Commit a681d126 by Nicolas Caramelli

Add Wayland support for Vulkan WSI

Bug: b/161736397 Change-Id: Ia795a1dcf201cc33027f520c0af8d5839d873af9 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/46768Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Caramelli <caramelli.devel@gmail.com>
parent 3b2cd31c
...@@ -86,6 +86,9 @@ endif() ...@@ -86,6 +86,9 @@ endif()
find_library(X11 X11) find_library(X11 X11)
find_library(XCB xcb) find_library(XCB xcb)
if(SWIFTSHADER_BUILD_WSI_WAYLAND)
find_library(WAYLAND wayland-client)
endif(SWIFTSHADER_BUILD_WSI_WAYLAND)
########################################################### ###########################################################
# Options # Options
...@@ -112,6 +115,7 @@ option_if_not_defined(SWIFTSHADER_BUILD_EGL "Build the EGL library" TRUE) ...@@ -112,6 +115,7 @@ option_if_not_defined(SWIFTSHADER_BUILD_EGL "Build the EGL library" TRUE)
option_if_not_defined(SWIFTSHADER_BUILD_GLESv2 "Build the OpenGL ES 2 library" TRUE) option_if_not_defined(SWIFTSHADER_BUILD_GLESv2 "Build the OpenGL ES 2 library" TRUE)
option_if_not_defined(SWIFTSHADER_BUILD_GLES_CM "Build the OpenGL ES 1.1 library" TRUE) option_if_not_defined(SWIFTSHADER_BUILD_GLES_CM "Build the OpenGL ES 1.1 library" TRUE)
option_if_not_defined(SWIFTSHADER_BUILD_VULKAN "Build the Vulkan library" TRUE) option_if_not_defined(SWIFTSHADER_BUILD_VULKAN "Build the Vulkan library" TRUE)
option_if_not_defined(SWIFTSHADER_BUILD_WSI_WAYLAND "Build the Wayland WSI support" FALSE)
option_if_not_defined(SWIFTSHADER_BUILD_PVR "Build the PowerVR examples" TRUE) option_if_not_defined(SWIFTSHADER_BUILD_PVR "Build the PowerVR examples" TRUE)
option_if_not_defined(SWIFTSHADER_GET_PVR "Check out the PowerVR submodule" FALSE) option_if_not_defined(SWIFTSHADER_GET_PVR "Check out the PowerVR submodule" FALSE)
...@@ -627,6 +631,9 @@ if(WIN32) ...@@ -627,6 +631,9 @@ if(WIN32)
set(OS_LIBS odbc32 odbccp32 WS2_32 dxguid) set(OS_LIBS odbc32 odbccp32 WS2_32 dxguid)
elseif(LINUX) elseif(LINUX)
set(OS_LIBS dl pthread) set(OS_LIBS dl pthread)
if(SWIFTSHADER_BUILD_WSI_WAYLAND)
list(APPEND OS_LIBS "${WAYLAND}")
endif(SWIFTSHADER_BUILD_WSI_WAYLAND)
elseif(FUCHSIA) elseif(FUCHSIA)
set(OS_LIBS zircon) set(OS_LIBS zircon)
elseif(APPLE) elseif(APPLE)
...@@ -707,6 +714,11 @@ if(SWIFTSHADER_BUILD_VULKAN) ...@@ -707,6 +714,11 @@ if(SWIFTSHADER_BUILD_VULKAN)
if(XCB) if(XCB)
target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_XCB_KHR") target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_XCB_KHR")
endif() endif()
if(SWIFTSHADER_BUILD_WSI_WAYLAND)
if(WAYLAND)
target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_WAYLAND_KHR")
endif()
endif(SWIFTSHADER_BUILD_WSI_WAYLAND)
elseif(APPLE) elseif(APPLE)
target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_MACOS_MVK") target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_MACOS_MVK")
elseif(FUCHSIA) elseif(FUCHSIA)
......
...@@ -114,6 +114,11 @@ static const std::unordered_map<std::string, PFN_vkVoidFunction> instanceFunctio ...@@ -114,6 +114,11 @@ static const std::unordered_map<std::string, PFN_vkVoidFunction> instanceFunctio
MAKE_VULKAN_INSTANCE_ENTRY(vkCreateXlibSurfaceKHR), MAKE_VULKAN_INSTANCE_ENTRY(vkCreateXlibSurfaceKHR),
MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceXlibPresentationSupportKHR), MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceXlibPresentationSupportKHR),
#endif #endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
// VK_KHR_wayland_surface
MAKE_VULKAN_INSTANCE_ENTRY(vkCreateWaylandSurfaceKHR),
MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceWaylandPresentationSupportKHR),
#endif
#ifdef VK_USE_PLATFORM_MACOS_MVK #ifdef VK_USE_PLATFORM_MACOS_MVK
// VK_MVK_macos_surface // VK_MVK_macos_surface
MAKE_VULKAN_INSTANCE_ENTRY(vkCreateMacOSSurfaceMVK), MAKE_VULKAN_INSTANCE_ENTRY(vkCreateMacOSSurfaceMVK),
......
...@@ -57,6 +57,10 @@ ...@@ -57,6 +57,10 @@
# include "WSI/XlibSurfaceKHR.hpp" # include "WSI/XlibSurfaceKHR.hpp"
#endif #endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
# include "WSI/WaylandSurfaceKHR.hpp"
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR #ifdef VK_USE_PLATFORM_WIN32_KHR
# include "WSI/Win32SurfaceKHR.hpp" # include "WSI/Win32SurfaceKHR.hpp"
#endif #endif
...@@ -314,6 +318,9 @@ static const VkExtensionProperties instanceExtensionProperties[] = { ...@@ -314,6 +318,9 @@ static const VkExtensionProperties instanceExtensionProperties[] = {
#ifdef VK_USE_PLATFORM_XLIB_KHR #ifdef VK_USE_PLATFORM_XLIB_KHR
{ VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_SPEC_VERSION }, { VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_SPEC_VERSION },
#endif #endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
{ VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_SPEC_VERSION },
#endif
#ifdef VK_USE_PLATFORM_MACOS_MVK #ifdef VK_USE_PLATFORM_MACOS_MVK
{ VK_MVK_MACOS_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_SPEC_VERSION }, { VK_MVK_MACOS_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_SPEC_VERSION },
#endif #endif
...@@ -3488,6 +3495,24 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkP ...@@ -3488,6 +3495,24 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkP
} }
#endif #endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)
{
TRACE("(VkInstance instance = %p, VkWaylandSurfaceCreateInfoKHR* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
instance, pCreateInfo, pAllocator, pSurface);
return vk::WaylandSurfaceKHR::Create(pAllocator, pCreateInfo, pSurface);
}
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display *display)
{
TRACE("(VkPhysicalDevice physicalDevice = %p, uint32_t queueFamilyIndex = %d, struct wl_display* display = %p)",
physicalDevice, int(queueFamilyIndex), display);
return VK_TRUE;
}
#endif
#ifdef VK_USE_PLATFORM_MACOS_MVK #ifdef VK_USE_PLATFORM_MACOS_MVK
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)
{ {
......
...@@ -46,6 +46,12 @@ elseif(LINUX) ...@@ -46,6 +46,12 @@ elseif(LINUX)
) )
endif() endif()
if(WAYLAND)
list(APPEND WSI_SRC_FILES
WaylandSurfaceKHR.cpp
WaylandSurfaceKHR.hpp
)
endif()
elseif(APPLE) elseif(APPLE)
list(APPEND WSI_SRC_FILES list(APPEND WSI_SRC_FILES
MetalSurface.mm MetalSurface.mm
......
// Copyright 2020 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.
#include "WaylandSurfaceKHR.hpp"
#include "Vulkan/VkDeviceMemory.hpp"
#include "Vulkan/VkImage.hpp"
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
namespace vk {
static void wl_registry_handle_global(void *data, struct wl_registry *registry, unsigned int name, const char *interface, unsigned int version)
{
struct wl_shm **pshm = (struct wl_shm **)data;
if(!strcmp(interface, "wl_shm"))
{
*pshm = static_cast<struct wl_shm*>(wl_registry_bind(registry, name, &wl_shm_interface, 1));
}
}
static void wl_registry_handle_global_remove(void *data, struct wl_registry *registry, unsigned int name)
{
}
static const struct wl_registry_listener wl_registry_listener = { wl_registry_handle_global, wl_registry_handle_global_remove };
WaylandSurfaceKHR::WaylandSurfaceKHR(const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, void *mem)
: display(pCreateInfo->display)
, surface(pCreateInfo->surface)
{
struct wl_registry *registry = wl_display_get_registry(display);
wl_registry_add_listener(registry, &wl_registry_listener, &shm);
wl_display_dispatch(display);
}
void WaylandSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
{
}
size_t WaylandSurfaceKHR::ComputeRequiredAllocationSize(const VkWaylandSurfaceCreateInfoKHR *pCreateInfo)
{
return 0;
}
void WaylandSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
{
SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
pSurfaceCapabilities->currentExtent = { 0xFFFFFFFF, 0xFFFFFFFF };
pSurfaceCapabilities->minImageExtent = { 1, 1 };
pSurfaceCapabilities->maxImageExtent = { 0xFFFFFFFF, 0xFFFFFFFF };
}
void WaylandSurfaceKHR::attachImage(PresentImage *image)
{
WaylandImage *wlImage = new WaylandImage;
char path[] = "/tmp/XXXXXX";
int fd = mkstemp(path);
VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
int stride = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
ftruncate(fd, extent.height * stride);
struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, extent.height * stride);
wlImage->buffer = wl_shm_pool_create_buffer(pool, 0, extent.width, extent.height, stride, WL_SHM_FORMAT_XRGB8888);
wlImage->data = static_cast<uint8_t *>(mmap(NULL, extent.height * stride, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
wl_shm_pool_destroy(pool);
close(fd);
imageMap[image] = wlImage;
}
void WaylandSurfaceKHR::detachImage(PresentImage *image)
{
auto it = imageMap.find(image);
if(it != imageMap.end())
{
WaylandImage *wlImage = it->second;
VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
int stride = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
munmap(wlImage->data, extent.height * stride);
wl_buffer_destroy(wlImage->buffer);
delete wlImage;
imageMap.erase(image);
}
}
VkResult WaylandSurfaceKHR::present(PresentImage *image)
{
auto it = imageMap.find(image);
if(it != imageMap.end())
{
WaylandImage *wlImage = it->second;
VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
int bufferRowPitch = image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
image->getImage()->copyTo(reinterpret_cast<uint8_t *>(wlImage->data), bufferRowPitch);
wl_surface_attach(surface, wlImage->buffer, 0, 0);
wl_surface_damage(surface, 0, 0, extent.width, extent.height);
wl_surface_commit(surface);
wl_display_roundtrip(display);
wl_display_sync(display);
}
return VK_SUCCESS;
}
} // namespace vk
// Copyright 2020 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_WAYLANDSURFACEKHR_HPP
#define SWIFTSHADER_WAYLANDSURFACEKHR_HPP
#include "VkSurfaceKHR.hpp"
#include "Vulkan/VkObject.hpp"
#include <vulkan/vulkan_wayland.h>
#include <wayland-client.h>
#include <unordered_map>
namespace vk {
struct WaylandImage
{
struct wl_buffer *buffer;
uint8_t *data;
};
class WaylandSurfaceKHR : public SurfaceKHR, public ObjectBase<WaylandSurfaceKHR, VkSurfaceKHR>
{
public:
WaylandSurfaceKHR(const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, void *mem);
void destroySurface(const VkAllocationCallbacks *pAllocator) override;
static size_t ComputeRequiredAllocationSize(const VkWaylandSurfaceCreateInfoKHR *pCreateInfo);
void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
virtual void attachImage(PresentImage *image) override;
virtual void detachImage(PresentImage *image) override;
VkResult present(PresentImage *image) override;
private:
struct wl_display *display;
struct wl_surface *surface;
struct wl_shm *shm;
std::unordered_map<PresentImage *, WaylandImage *> imageMap;
};
} // namespace vk
#endif //SWIFTSHADER_WAYLANDSURFACEKHR_HPP
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