Commit a9af883e by Ben Clayton

WSI: Very basic XCB surface implementation.

Much like XlibSurfaceKHR, doesn't cope with any formats aside from 24-bit RGB. Bug: b/124265819 Bug: b/139412276 Bug: b/139491466 Change-Id: I1146f6ff672a9016be04e6b4d595de40fa03346f Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/35149 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com>
parent 2198b0fe
......@@ -71,6 +71,13 @@ if(CCACHE_FOUND)
endif(CCACHE_FOUND)
###########################################################
# Host libraries
###########################################################
find_library(X11 X11)
find_library(XCB xcb)
###########################################################
# Options
###########################################################
......@@ -1808,12 +1815,22 @@ elseif(LINUX)
${OPENGL_COMPILER_DIR}/ossource_posix.cpp
)
list(APPEND VULKAN_LIST
${SOURCE_DIR}/WSI/libX11.cpp
${SOURCE_DIR}/WSI/libX11.hpp
${SOURCE_DIR}/WSI/XlibSurfaceKHR.cpp
${SOURCE_DIR}/WSI/XlibSurfaceKHR.hpp
)
if(X11)
list(APPEND VULKAN_LIST
${SOURCE_DIR}/WSI/XlibSurfaceKHR.cpp
${SOURCE_DIR}/WSI/XlibSurfaceKHR.hpp
${SOURCE_DIR}/WSI/libX11.cpp
${SOURCE_DIR}/WSI/libX11.hpp
)
endif(X11)
if(XCB)
list(APPEND VULKAN_LIST
${SOURCE_DIR}/WSI/XcbSurfaceKHR.cpp
${SOURCE_DIR}/WSI/XcbSurfaceKHR.hpp
)
endif(XCB)
elseif(APPLE)
list(APPEND SWIFTSHADER_LIST
${SOURCE_DIR}/Main/FrameBufferOSX.mm
......@@ -1948,7 +1965,9 @@ if(BUILD_EGL)
PREFIX ""
)
if(LINUX)
set_property(TARGET libEGL APPEND PROPERTY COMPILE_DEFINITIONS "USE_X11=1")
if(X11)
set_property(TARGET libEGL APPEND PROPERTY COMPILE_DEFINITIONS "USE_X11=1")
endif(X11)
endif()
if (ANDROID)
set_target_properties(libEGL PROPERTIES SUFFIX "_swiftshader.so")
......@@ -2033,8 +2052,14 @@ if(BUILD_VULKAN)
set_property(TARGET libvk_swiftshader APPEND
PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_WIN32_KHR")
elseif(LINUX)
set_property(TARGET libvk_swiftshader APPEND
PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_XLIB_KHR")
if(X11)
set_property(TARGET libvk_swiftshader APPEND
PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_XLIB_KHR")
endif(X11)
if(XCB)
set_property(TARGET libvk_swiftshader APPEND
PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_XCB_KHR")
endif(XCB)
elseif(APPLE)
set_property(TARGET libvk_swiftshader APPEND
PROPERTY COMPILE_DEFINITIONS "VK_USE_PLATFORM_MACOS_MVK")
......@@ -2090,7 +2115,7 @@ if(BUILD_SAMPLES)
COMPILE_OPTIONS "${SWIFTSHADER_COMPILE_OPTIONS}"
COMPILE_DEFINITIONS "GL_GLEXT_PROTOTYPES"
)
target_link_libraries(OGLES2HelloAPI dl X11 libEGL libGLESv2) # Explicitly link our "lib*" targets, not the platform provided "EGL" and "GLESv2"
target_link_libraries(OGLES2HelloAPI dl ${X11} libEGL libGLESv2) # Explicitly link our "lib*" targets, not the platform provided "EGL" and "GLESv2"
elseif(APPLE)
add_executable(OGLES2HelloAPI MACOSX_BUNDLE
${HELLO2_DIR}/OGLES2HelloAPI_OSX.mm
......
......@@ -89,6 +89,11 @@ static const std::unordered_map<std::string, PFN_vkVoidFunction> instanceFunctio
MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceSurfacePresentModesKHR),
MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDevicePresentRectanglesKHR),
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
// VK_KHR_Xcb_surface
MAKE_VULKAN_INSTANCE_ENTRY(vkCreateXcbSurfaceKHR),
MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceXcbPresentationSupportKHR),
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
// VK_KHR_xlib_surface
MAKE_VULKAN_INSTANCE_ENTRY(vkCreateXlibSurfaceKHR),
......
......@@ -46,6 +46,10 @@
#include "WSI/MacOSSurfaceMVK.h"
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
#include "WSI/XcbSurfaceKHR.hpp"
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
#include "WSI/XlibSurfaceKHR.hpp"
#endif
......@@ -166,6 +170,9 @@ static const VkExtensionProperties instanceExtensionProperties[] =
#ifndef __ANDROID__
{ VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION },
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
{ VK_KHR_XCB_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_SPEC_VERSION },
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
{ VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_SPEC_VERSION },
#endif
......@@ -2657,6 +2664,24 @@ VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport(VkDevice device, cons
vk::Cast(device)->getDescriptorSetLayoutSupport(pCreateInfo, pSupport);
}
#ifdef VK_USE_PLATFORM_XCB_KHR
VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
{
TRACE("(VkInstance instance = %p, VkXcbSurfaceCreateInfoKHR* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
instance, pCreateInfo, pAllocator, pSurface);
return vk::XcbSurfaceKHR::Create(pAllocator, pCreateInfo, pSurface);
}
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id)
{
TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t queueFamilyIndex = %d, xcb_connection_t* connection = %p, xcb_visualid_t visual_id = %d)",
physicalDevice, int(queueFamilyIndex), connection, int(visual_id));
return VK_TRUE;
}
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
{
......
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "XcbSurfaceKHR.hpp"
#include "Vulkan/VkDeviceMemory.hpp"
#include "Vulkan/VkImage.hpp"
#include "System/SharedLibrary.hpp"
#include <memory>
namespace
{
template <typename FPTR>
void getFuncAddress(void *lib, const char *name, FPTR *out)
{
*out = reinterpret_cast<FPTR>(getProcAddress(lib, name));
}
struct LibXcbExports
{
LibXcbExports(void *lib)
{
getFuncAddress(lib, "xcb_create_gc", &xcb_create_gc);
getFuncAddress(lib, "xcb_flush", &xcb_flush);
getFuncAddress(lib, "xcb_free_gc", &xcb_free_gc);
getFuncAddress(lib, "xcb_generate_id", &xcb_generate_id);
getFuncAddress(lib, "xcb_get_geometry", &xcb_get_geometry);
getFuncAddress(lib, "xcb_get_geometry_reply", &xcb_get_geometry_reply);
getFuncAddress(lib, "xcb_put_image", &xcb_put_image);
}
xcb_void_cookie_t (*xcb_create_gc)(xcb_connection_t *c, xcb_gcontext_t cid, xcb_drawable_t drawable, uint32_t value_mask, const void *value_list);
int (*xcb_flush)(xcb_connection_t *c);
xcb_void_cookie_t (*xcb_free_gc)(xcb_connection_t *c, xcb_gcontext_t gc);
uint32_t (*xcb_generate_id)(xcb_connection_t *c);
xcb_get_geometry_cookie_t (*xcb_get_geometry)(xcb_connection_t *c, xcb_drawable_t drawable);
xcb_get_geometry_reply_t* (*xcb_get_geometry_reply)(xcb_connection_t *c, xcb_get_geometry_cookie_t cookie, xcb_generic_error_t **e);
xcb_void_cookie_t (*xcb_put_image)(xcb_connection_t *c, uint8_t format, xcb_drawable_t drawable, xcb_gcontext_t gc, uint16_t width,uint16_t height, int16_t dst_x, int16_t dst_y, uint8_t left_pad, uint8_t depth, uint32_t data_len, const uint8_t* data);
};
class LibXcb
{
public:
operator bool()
{
return loadExports();
}
LibXcbExports *operator->()
{
return loadExports();
}
private:
LibXcbExports *loadExports()
{
static auto exports = []
{
if (getProcAddress(RTLD_DEFAULT, "xcb_create_gc"))
{
return std::unique_ptr<LibXcbExports>(new LibXcbExports(RTLD_DEFAULT));
}
if (auto lib = loadLibrary("libXcb.so"))
{
return std::unique_ptr<LibXcbExports>(new LibXcbExports(lib));
}
return std::unique_ptr<LibXcbExports>();
}();
return exports.get();
}
};
LibXcb libXcb;
} // anonymous namespace
namespace vk {
XcbSurfaceKHR::XcbSurfaceKHR(const VkXcbSurfaceCreateInfoKHR *pCreateInfo, void *mem) :
connection(pCreateInfo->connection),
window(pCreateInfo->window)
{
}
void XcbSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
{
}
size_t XcbSurfaceKHR::ComputeRequiredAllocationSize(const VkXcbSurfaceCreateInfoKHR *pCreateInfo)
{
return 0;
}
void XcbSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
{
SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
auto geom = libXcb->xcb_get_geometry_reply(connection, libXcb->xcb_get_geometry(connection, window), nullptr);
VkExtent2D extent = {static_cast<uint32_t>(geom->width), static_cast<uint32_t>(geom->height)};
free(geom);
pSurfaceCapabilities->currentExtent = extent;
pSurfaceCapabilities->minImageExtent = extent;
pSurfaceCapabilities->maxImageExtent = extent;
}
void XcbSurfaceKHR::attachImage(PresentImage* image)
{
auto gc = libXcb->xcb_generate_id(connection);
uint32_t values[2] = {0, 0xffffffff};
libXcb->xcb_create_gc(connection, gc, window, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, values);
graphicsContexts[image] = gc;
}
void XcbSurfaceKHR::detachImage(PresentImage* image)
{
auto it = graphicsContexts.find(image);
if(it != graphicsContexts.end())
{
libXcb->xcb_free_gc(connection, it->second);
graphicsContexts.erase(image);
}
}
void XcbSurfaceKHR::present(PresentImage* image)
{
auto it = graphicsContexts.find(image);
if(it != graphicsContexts.end())
{
// TODO: Convert image if not RGB888.
VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
int stride = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
auto buffer = reinterpret_cast<uint8_t*>(image->getImageMemory()->getOffsetPointer(0));
size_t bufferSize = extent.height * stride;
constexpr int depth = 24; // TODO: Actually use window display depth.
libXcb->xcb_put_image(
connection,
XCB_IMAGE_FORMAT_Z_PIXMAP,
window,
it->second,
extent.width,
extent.height,
0, 0, // dst x, y
0, // left_pad
depth,
bufferSize, // data_len
buffer // data
);
libXcb->xcb_flush(connection);
}
}
}
\ No newline at end of file
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SWIFTSHADER_XCBSURFACEKHR_HPP
#define SWIFTSHADER_XCBSURFACEKHR_HPP
#include "Vulkan/VkObject.hpp"
#include "VkSurfaceKHR.hpp"
#include <xcb/xcb.h>
#include "vulkan/vulkan_xcb.h"
#include <unordered_map>
namespace vk {
class XcbSurfaceKHR : public SurfaceKHR, public ObjectBase<XcbSurfaceKHR, VkSurfaceKHR> {
public:
XcbSurfaceKHR(const VkXcbSurfaceCreateInfoKHR *pCreateInfo, void *mem);
void destroySurface(const VkAllocationCallbacks *pAllocator) override;
static size_t ComputeRequiredAllocationSize(const VkXcbSurfaceCreateInfoKHR *pCreateInfo);
void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
virtual void attachImage(PresentImage* image) override;
virtual void detachImage(PresentImage* image) override;
void present(PresentImage* image) override;
private:
xcb_connection_t* connection;
xcb_window_t window;
std::unordered_map<PresentImage*, uint32_t> graphicsContexts;
};
}
#endif //SWIFTSHADER_XCBSURFACEKHR_HPP
......@@ -17,8 +17,6 @@
#include "Vulkan/VkDeviceMemory.hpp"
#include "Vulkan/VkImage.hpp"
#include <string.h>
namespace vk {
XlibSurfaceKHR::XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem) :
......
......@@ -20,7 +20,7 @@
#include "VkSurfaceKHR.hpp"
#include "vulkan/vulkan_xlib.h"
#include <map>
#include <unordered_map>
namespace vk {
......@@ -43,7 +43,7 @@ private:
const Window window;
GC gc;
Visual *visual = nullptr;
std::map<PresentImage*, XImage*> imageMap;
std::unordered_map<PresentImage*, XImage*> imageMap;
};
}
......
......@@ -18,30 +18,40 @@
#define Bool int
namespace {
template <typename FPTR>
void getFuncAddress(void *lib, const char *name, FPTR *out)
{
*out = reinterpret_cast<FPTR>(getProcAddress(lib, name));
}
} // anonymous namespace
LibX11exports::LibX11exports(void *libX11, void *libXext)
{
XOpenDisplay = (Display *(*)(char*))getProcAddress(libX11, "XOpenDisplay");
XGetWindowAttributes = (Status (*)(Display*, Window, XWindowAttributes*))getProcAddress(libX11, "XGetWindowAttributes");
XDefaultScreenOfDisplay = (Screen *(*)(Display*))getProcAddress(libX11, "XDefaultScreenOfDisplay");
XWidthOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XWidthOfScreen");
XHeightOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XHeightOfScreen");
XPlanesOfScreen = (int (*)(Screen*))getProcAddress(libX11, "XPlanesOfScreen");
XDefaultGC = (GC (*)(Display*, int))getProcAddress(libX11, "XDefaultGC");
XDefaultDepth = (int (*)(Display*, int))getProcAddress(libX11, "XDefaultDepth");
XMatchVisualInfo = (Status (*)(Display*, int, int, int, XVisualInfo*))getProcAddress(libX11, "XMatchVisualInfo");
XDefaultVisual = (Visual *(*)(Display*, int screen_number))getProcAddress(libX11, "XDefaultVisual");
XSetErrorHandler = (int (*(*)(int (*)(Display*, XErrorEvent*)))(Display*, XErrorEvent*))getProcAddress(libX11, "XSetErrorHandler");
XSync = (int (*)(Display*, Bool))getProcAddress(libX11, "XSync");
XCreateImage = (XImage *(*)(Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int))getProcAddress(libX11, "XCreateImage");
XCloseDisplay = (int (*)(Display*))getProcAddress(libX11, "XCloseDisplay");
XPutImage = (int (*)(Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int))getProcAddress(libX11, "XPutImage");
XDrawString = (int (*)(Display*, Drawable, GC, int, int, char*, int))getProcAddress(libX11, "XDrawString");
getFuncAddress(libX11, "XOpenDisplay", &XOpenDisplay);
getFuncAddress(libX11, "XGetWindowAttributes", &XGetWindowAttributes);
getFuncAddress(libX11, "XDefaultScreenOfDisplay", &XDefaultScreenOfDisplay);
getFuncAddress(libX11, "XWidthOfScreen", &XWidthOfScreen);
getFuncAddress(libX11, "XHeightOfScreen", &XHeightOfScreen);
getFuncAddress(libX11, "XPlanesOfScreen", &XPlanesOfScreen);
getFuncAddress(libX11, "XDefaultGC", &XDefaultGC);
getFuncAddress(libX11, "XDefaultDepth", &XDefaultDepth);
getFuncAddress(libX11, "XMatchVisualInfo", &XMatchVisualInfo);
getFuncAddress(libX11, "XDefaultVisual", &XDefaultVisual);
getFuncAddress(libX11, "XSetErrorHandler", &XSetErrorHandler);
getFuncAddress(libX11, "XSync", &XSync);
getFuncAddress(libX11, "XCreateImage", &XCreateImage);
getFuncAddress(libX11, "XCloseDisplay", &XCloseDisplay);
getFuncAddress(libX11, "XPutImage", &XPutImage);
getFuncAddress(libX11, "XDrawString", &XDrawString);
XShmQueryExtension = (Bool (*)(Display*))getProcAddress(libXext, "XShmQueryExtension");
XShmCreateImage = (XImage *(*)(Display*, Visual*, unsigned int, int, char*, XShmSegmentInfo*, unsigned int, unsigned int))getProcAddress(libXext, "XShmCreateImage");
XShmAttach = (Bool (*)(Display*, XShmSegmentInfo*))getProcAddress(libXext, "XShmAttach");
XShmDetach = (Bool (*)(Display*, XShmSegmentInfo*))getProcAddress(libXext, "XShmDetach");
XShmPutImage = (int (*)(Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int, bool))getProcAddress(libXext, "XShmPutImage");
getFuncAddress(libXext, "XShmQueryExtension", &XShmQueryExtension);
getFuncAddress(libXext, "XShmCreateImage", &XShmCreateImage);
getFuncAddress(libXext, "XShmAttach", &XShmAttach);
getFuncAddress(libXext, "XShmDetach", &XShmDetach);
getFuncAddress(libXext, "XShmPutImage", &XShmPutImage);
}
LibX11exports *LibX11::operator->()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment