Add support for SurfaceDescriptorFromWaylandSurface

Bug: dawn:1246
Change-Id: I0af28e1820ad8da2121a00bdef7202695d23bbf7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/75422
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2022-06-01 09:30:50 +00:00 committed by Dawn LUCI CQ
parent 691c5fc4e6
commit 2e22d9285c
11 changed files with 133 additions and 23 deletions

View File

@ -82,6 +82,7 @@ set(ENABLE_METAL OFF)
set(ENABLE_OPENGLES OFF)
set(ENABLE_DESKTOP_GL OFF)
set(ENABLE_VULKAN OFF)
set(USE_WAYLAND OFF)
set(USE_X11 OFF)
set(BUILD_SAMPLES OFF)
if (WIN32)
@ -124,6 +125,7 @@ option_if_not_defined(DAWN_ENABLE_DESKTOP_GL "Enable compilation of the OpenGL b
option_if_not_defined(DAWN_ENABLE_OPENGLES "Enable compilation of the OpenGL ES backend" ${ENABLE_OPENGLES})
option_if_not_defined(DAWN_ENABLE_VULKAN "Enable compilation of the Vulkan backend" ${ENABLE_VULKAN})
option_if_not_defined(DAWN_ALWAYS_ASSERT "Enable assertions on all build types" OFF)
option_if_not_defined(DAWN_USE_WAYLAND "Enable support for Wayland surface" ${USE_WAYLAND})
option_if_not_defined(DAWN_USE_X11 "Enable support for X11 surface" ${USE_X11})
option_if_not_defined(DAWN_BUILD_SAMPLES "Enables building Dawn's samples" ${BUILD_SAMPLES})
@ -232,6 +234,9 @@ endif()
if (DAWN_ENABLE_VULKAN)
target_compile_definitions(dawn_internal_config INTERFACE "DAWN_ENABLE_BACKEND_VULKAN")
endif()
if (DAWN_USE_WAYLAND)
target_compile_definitions(dawn_internal_config INTERFACE "DAWN_USE_WAYLAND")
endif()
if (DAWN_USE_X11)
target_compile_definitions(dawn_internal_config INTERFACE "DAWN_USE_X11")
endif()

View File

@ -19,10 +19,12 @@ if (build_with_chromium) {
import("//build/config/sanitizers/sanitizers.gni")
dawn_use_x11 = ozone_platform_x11
dawn_use_wayland = false
} else {
declare_args() {
# Whether Dawn should enable X11 support.
dawn_use_x11 = is_linux && !is_chromeos
dawn_use_wayland = false
}
}

View File

@ -80,6 +80,9 @@ config("internal_config") {
defines += [ "DAWN_ENABLE_BACKEND_VULKAN" ]
}
if (dawn_use_wayland) {
defines += [ "DAWN_USE_WAYLAND" ]
}
if (dawn_use_x11) {
defines += [ "DAWN_USE_X11" ]
}

View File

@ -153,6 +153,12 @@ HandleType* AsVkArray(detail::VkHandle<Tag, HandleType>* handle) {
#include "dawn/common/xlib_with_undefs.h"
#endif // defined(DAWN_USE_X11)
#if defined(DAWN_USE_WAYLAND)
#ifndef VK_USE_PLATFORM_WAYLAND_KHR
#define VK_USE_PLATFORM_WAYLAND_KHR
#endif
#endif // defined(DAWN_USE_WAYLAND)
#if defined(DAWN_ENABLE_BACKEND_METAL)
#ifndef VK_USE_PLATFORM_METAL_EXT
#define VK_USE_PLATFORM_METAL_EXT

View File

@ -41,6 +41,9 @@ absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConv
case Surface::Type::MetalLayer:
s->Append("MetalLayer");
break;
case Surface::Type::WaylandSurface:
s->Append("WaylandSurface");
break;
case Surface::Type::WindowsHWND:
s->Append("WindowsHWND");
break;
@ -128,6 +131,18 @@ MaybeError ValidateSurfaceDescriptor(const InstanceBase* instance,
}
#endif // defined(DAWN_PLATFORM_WINDOWS)
#if defined(DAWN_USE_WAYLAND)
const SurfaceDescriptorFromWaylandSurface* waylandDesc = nullptr;
FindInChain(descriptor->nextInChain, &waylandDesc);
if (waylandDesc) {
// Unfortunately we can't check the validity of wayland objects. Only that they
// aren't nullptr.
DAWN_INVALID_IF(waylandDesc->display == nullptr, "Wayland display is nullptr.");
DAWN_INVALID_IF(waylandDesc->surface == nullptr, "Wayland surface is nullptr.");
return {};
}
#endif // defined(DAWN_USE_X11)
#if defined(DAWN_USE_X11)
const SurfaceDescriptorFromXlibWindow* xDesc = nullptr;
FindInChain(descriptor->nextInChain, &xDesc);
@ -165,6 +180,7 @@ Surface::Surface(InstanceBase* instance, const SurfaceDescriptor* descriptor)
const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr;
const SurfaceDescriptorFromWindowsCoreWindow* coreWindowDesc = nullptr;
const SurfaceDescriptorFromWindowsSwapChainPanel* swapChainPanelDesc = nullptr;
const SurfaceDescriptorFromWaylandSurface* waylandDesc = nullptr;
const SurfaceDescriptorFromXlibWindow* xDesc = nullptr;
FindInChain(descriptor->nextInChain, &androidDesc);
FindInChain(descriptor->nextInChain, &metalDesc);
@ -178,6 +194,10 @@ Surface::Surface(InstanceBase* instance, const SurfaceDescriptor* descriptor)
} else if (androidDesc) {
mType = Type::AndroidWindow;
mAndroidNativeWindow = androidDesc->window;
} else if (waylandDesc) {
mType = Type::WaylandSurface;
mWaylandDisplay = waylandDesc->display;
mWaylandSurface = waylandDesc->surface;
} else if (hwndDesc) {
mType = Type::WindowsHWND;
mHInstance = hwndDesc->hinstance;
@ -239,6 +259,16 @@ void* Surface::GetMetalLayer() const {
return mMetalLayer;
}
void* Surface::GetWaylandDisplay() const {
ASSERT(mType == Type::WaylandSurface);
return mWaylandDisplay;
}
void* Surface::GetWaylandSurface() const {
ASSERT(mType == Type::WaylandSurface);
return mWaylandSurface;
}
void* Surface::GetHInstance() const {
ASSERT(!IsError());
ASSERT(mType == Type::WindowsHWND);

View File

@ -55,6 +55,7 @@ class Surface final : public ErrorMonad {
enum class Type {
AndroidWindow,
MetalLayer,
WaylandSurface,
WindowsHWND,
WindowsCoreWindow,
WindowsSwapChainPanel,
@ -69,6 +70,10 @@ class Surface final : public ErrorMonad {
// Valid to call if the type is Android
void* GetAndroidNativeWindow() const;
// Valid to call if the type is WaylandSurface
void* GetWaylandDisplay() const;
void* GetWaylandSurface() const;
// Valid to call if the type is WindowsHWND
void* GetHInstance() const;
void* GetHWND() const;
@ -99,6 +104,10 @@ class Surface final : public ErrorMonad {
// ANativeWindow
void* mAndroidNativeWindow = nullptr;
// Wayland
void* mWaylandDisplay = nullptr;
void* mWaylandSurface = nullptr;
// WindowsHwnd
void* mHInstance = nullptr;
void* mHWND = nullptr;

View File

@ -158,6 +158,26 @@ ResultOrError<VkSurfaceKHR> CreateVulkanSurface(Adapter* adapter, Surface* surfa
#endif // defined(DAWN_PLATFORM_ANDROID)
#if defined(DAWN_USE_WAYLAND)
case Surface::Type::WaylandSurface: {
if (info.HasExt(InstanceExt::XlibSurface)) {
VkWaylandSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.display = static_cast<struct wl_display*>(surface->GetWaylandDisplay());
createInfo.surface = static_cast<struct wl_surface*>(surface->GetWaylandSurface());
VkSurfaceKHR vkSurface = VK_NULL_HANDLE;
DAWN_TRY(CheckVkSuccess(
fn.CreateWaylandSurfaceKHR(instance, &createInfo, nullptr, &*vkSurface),
"CreateWaylandSurface"));
return vkSurface;
}
break;
}
#endif // defined(DAWN_USE_WAYLAND)
#if defined(DAWN_USE_X11)
case Surface::Type::XlibWindow: {
if (info.HasExt(InstanceExt::XlibSurface)) {

View File

@ -188,6 +188,13 @@ MaybeError VulkanFunctions::LoadInstanceProcs(VkInstance instance,
}
#endif // defined(DAWN_ENABLE_BACKEND_METAL)
#if defined(DAWN_USE_WAYLAND)
if (globalInfo.HasExt(InstanceExt::WaylandSurface)) {
GET_INSTANCE_PROC(CreateWaylandSurfaceKHR);
GET_INSTANCE_PROC(GetPhysicalDeviceWaylandPresentationSupportKHR);
}
#endif // defined(DAWN_USE_WAYLAND)
#if defined(DAWN_PLATFORM_WINDOWS)
if (globalInfo.HasExt(InstanceExt::Win32Surface)) {
GET_INSTANCE_PROC(CreateWin32SurfaceKHR);

View File

@ -149,6 +149,13 @@ struct VulkanFunctions {
VkFn<PFN_vkCreateMetalSurfaceEXT> CreateMetalSurfaceEXT = nullptr;
#endif // defined(DAWN_ENABLE_BACKEND_METAL)
#if defined(DAWN_USE_WAYLAND)
// KHR_wayland_surface
PFN_vkCreateWaylandSurfaceKHR CreateWaylandSurfaceKHR = nullptr;
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
GetPhysicalDeviceWaylandPresentationSupportKHR = nullptr;
#endif // defined(DAWN_USE_WAYLAND)
#if defined(DAWN_PLATFORM_WINDOWS)
// KHR_win32_surface
VkFn<PFN_vkCreateWin32SurfaceKHR> CreateWin32SurfaceKHR = nullptr;

View File

@ -21,9 +21,13 @@
#if defined(DAWN_PLATFORM_WINDOWS)
#define GLFW_EXPOSE_NATIVE_WIN32
#elif defined(DAWN_USE_X11)
#endif
#if defined(DAWN_USE_X11)
#define GLFW_EXPOSE_NATIVE_X11
#endif
#if defined(DAWN_USE_WAYLAND)
#define GLFW_EXPOSE_NATIVE_WAYLAND
#endif
#include "GLFW/glfw3native.h"
namespace utils {
@ -59,28 +63,45 @@ wgpu::Surface CreateSurfaceForWindow(const wgpu::Instance& instance, GLFWwindow*
return surface;
}
#if defined(DAWN_PLATFORM_WINDOWS)
// SetupWindowAndGetSurfaceDescriptorCocoa defined in GLFWUtils_metal.mm
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorCocoa(GLFWwindow* window);
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) {
switch (glfwGetPlatform()) {
#if defined(DAWN_PLATFORM_WINDOWS)
case GLFW_PLATFORM_WIN32: {
std::unique_ptr<wgpu::SurfaceDescriptorFromWindowsHWND> desc =
std::make_unique<wgpu::SurfaceDescriptorFromWindowsHWND>();
desc->hwnd = glfwGetWin32Window(window);
desc->hinstance = GetModuleHandle(nullptr);
return std::move(desc);
}
#elif defined(DAWN_USE_X11)
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) {
}
#endif
#if defined(DAWN_ENABLE_BACKEND_METAL)
case GLFW_PLATFORM_COCOA:
return SetupWindowAndGetSurfaceDescriptorCocoa(window);
#endif
#if defined(DAWN_USE_WAYLAND)
case GLFW_PLATFORM_WAYLAND: {
std::unique_ptr<wgpu::SurfaceDescriptorFromWaylandSurface> desc =
std::make_unique<wgpu::SurfaceDescriptorFromWaylandSurface>();
desc->display = glfwGetWaylandDisplay();
desc->surface = glfwGetWaylandWindow(window);
return std::move(desc);
}
#endif
#if defined(DAWN_USE_X11)
case GLFW_PLATFORM_X11: {
std::unique_ptr<wgpu::SurfaceDescriptorFromXlibWindow> desc =
std::make_unique<wgpu::SurfaceDescriptorFromXlibWindow>();
desc->display = glfwGetX11Display();
desc->window = glfwGetX11Window(window);
return std::move(desc);
}
#elif defined(DAWN_ENABLE_BACKEND_METAL)
// SetupWindowAndGetSurfaceDescriptor defined in GLFWUtils_metal.mm
#else
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow*) {
return nullptr;
}
}
#endif
default:
return nullptr;
}
}
} // namespace utils

View File

@ -28,7 +28,7 @@
namespace utils {
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) {
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorCocoa(GLFWwindow* window) {
if (@available(macOS 10.11, *)) {
NSWindow* nsWindow = glfwGetCocoaWindow(window);
NSView* view = [nsWindow contentView];