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>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b6733f5..287b903 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -82,6 +82,7 @@
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_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 @@
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()
diff --git a/scripts/dawn_features.gni b/scripts/dawn_features.gni
index 234791c..57227de 100644
--- a/scripts/dawn_features.gni
+++ b/scripts/dawn_features.gni
@@ -19,10 +19,12 @@
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
}
}
diff --git a/src/dawn/common/BUILD.gn b/src/dawn/common/BUILD.gn
index 3ff8bde..a9ecded 100644
--- a/src/dawn/common/BUILD.gn
+++ b/src/dawn/common/BUILD.gn
@@ -80,6 +80,9 @@
defines += [ "DAWN_ENABLE_BACKEND_VULKAN" ]
}
+ if (dawn_use_wayland) {
+ defines += [ "DAWN_USE_WAYLAND" ]
+ }
if (dawn_use_x11) {
defines += [ "DAWN_USE_X11" ]
}
diff --git a/src/dawn/common/vulkan_platform.h b/src/dawn/common/vulkan_platform.h
index c4bff86..848ee75 100644
--- a/src/dawn/common/vulkan_platform.h
+++ b/src/dawn/common/vulkan_platform.h
@@ -153,6 +153,12 @@
#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
diff --git a/src/dawn/native/Surface.cpp b/src/dawn/native/Surface.cpp
index e93aa73..c340ccf 100644
--- a/src/dawn/native/Surface.cpp
+++ b/src/dawn/native/Surface.cpp
@@ -41,6 +41,9 @@
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 @@
}
#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 @@
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 @@
} 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 @@
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);
diff --git a/src/dawn/native/Surface.h b/src/dawn/native/Surface.h
index f01d96d..865d33b 100644
--- a/src/dawn/native/Surface.h
+++ b/src/dawn/native/Surface.h
@@ -55,6 +55,7 @@
enum class Type {
AndroidWindow,
MetalLayer,
+ WaylandSurface,
WindowsHWND,
WindowsCoreWindow,
WindowsSwapChainPanel,
@@ -69,6 +70,10 @@
// 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 @@
// ANativeWindow
void* mAndroidNativeWindow = nullptr;
+ // Wayland
+ void* mWaylandDisplay = nullptr;
+ void* mWaylandSurface = nullptr;
+
// WindowsHwnd
void* mHInstance = nullptr;
void* mHWND = nullptr;
diff --git a/src/dawn/native/vulkan/SwapChainVk.cpp b/src/dawn/native/vulkan/SwapChainVk.cpp
index 63de95e..9f35655 100644
--- a/src/dawn/native/vulkan/SwapChainVk.cpp
+++ b/src/dawn/native/vulkan/SwapChainVk.cpp
@@ -158,6 +158,26 @@
#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)) {
diff --git a/src/dawn/native/vulkan/VulkanFunctions.cpp b/src/dawn/native/vulkan/VulkanFunctions.cpp
index 3734dac..1b629e6 100644
--- a/src/dawn/native/vulkan/VulkanFunctions.cpp
+++ b/src/dawn/native/vulkan/VulkanFunctions.cpp
@@ -188,6 +188,13 @@
}
#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);
diff --git a/src/dawn/native/vulkan/VulkanFunctions.h b/src/dawn/native/vulkan/VulkanFunctions.h
index 66732b8..0e26114 100644
--- a/src/dawn/native/vulkan/VulkanFunctions.h
+++ b/src/dawn/native/vulkan/VulkanFunctions.h
@@ -149,6 +149,13 @@
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;
diff --git a/src/dawn/utils/GLFWUtils.cpp b/src/dawn/utils/GLFWUtils.cpp
index 5a1b4ba..b5c4a16 100644
--- a/src/dawn/utils/GLFWUtils.cpp
+++ b/src/dawn/utils/GLFWUtils.cpp
@@ -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 @@
return surface;
}
+// 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)
-std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) {
- 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) {
- 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;
-}
+ 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);
+ }
#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);
+ }
+#endif
+ default:
+ return nullptr;
+ }
+}
} // namespace utils
diff --git a/src/dawn/utils/GLFWUtils_metal.mm b/src/dawn/utils/GLFWUtils_metal.mm
index 0762a3d..d07eeca 100644
--- a/src/dawn/utils/GLFWUtils_metal.mm
+++ b/src/dawn/utils/GLFWUtils_metal.mm
@@ -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];