From 147da21856613bce4baade89a27d5b551a96c162 Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Wed, 13 Apr 2022 15:33:06 +0000 Subject: [PATCH] Change Dawn samples to use surface-based swapchains. This helps people looking at samples on how to use Dawn from getting confused when implementation-based swapchains break (because they were just made to be good enough N years ago). Fixed: dawn:1361 Change-Id: Ia989fca4d0455fb8e0ff754056a3d60eb2958b04 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/86531 Reviewed-by: Loko Kung Commit-Queue: Corentin Wallez --- src/dawn/samples/Animometer.cpp | 4 +- src/dawn/samples/CHelloTriangle.cpp | 8 +-- src/dawn/samples/ComputeBoids.cpp | 4 +- src/dawn/samples/CppHelloTriangle.cpp | 4 +- src/dawn/samples/SampleUtils.cpp | 58 +++++++++++++------ src/dawn/samples/SampleUtils.h | 3 +- src/dawn/tests/end2end/WindowSurfaceTests.cpp | 12 ++-- src/dawn/utils/GLFWUtils.cpp | 14 ++--- src/dawn/utils/GLFWUtils.h | 8 +-- src/dawn/utils/GLFWUtils_metal.mm | 3 +- 10 files changed, 61 insertions(+), 57 deletions(-) diff --git a/src/dawn/samples/Animometer.cpp b/src/dawn/samples/Animometer.cpp index 2c4f027308..273cbce4fe 100644 --- a/src/dawn/samples/Animometer.cpp +++ b/src/dawn/samples/Animometer.cpp @@ -53,9 +53,7 @@ void init() { device = CreateCppDawnDevice(); queue = device.GetQueue(); - swapchain = GetSwapChain(device); - swapchain.Configure(GetPreferredSwapChainTextureFormat(), wgpu::TextureUsage::RenderAttachment, - 640, 480); + swapchain = GetSwapChain(); wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"( struct Constants { diff --git a/src/dawn/samples/CHelloTriangle.cpp b/src/dawn/samples/CHelloTriangle.cpp index 8f634473c5..ed1507e4bb 100644 --- a/src/dawn/samples/CHelloTriangle.cpp +++ b/src/dawn/samples/CHelloTriangle.cpp @@ -28,14 +28,8 @@ WGPUTextureFormat swapChainFormat; void init() { device = CreateCppDawnDevice().Release(); queue = wgpuDeviceGetQueue(device); - - { - WGPUSwapChainDescriptor descriptor = {}; - descriptor.implementation = GetSwapChainImplementation(); - swapchain = wgpuDeviceCreateSwapChain(device, nullptr, &descriptor); - } + swapchain = GetSwapChain().Release(); swapChainFormat = static_cast(GetPreferredSwapChainTextureFormat()); - wgpuSwapChainConfigure(swapchain, swapChainFormat, WGPUTextureUsage_RenderAttachment, 640, 480); const char* vs = R"( @stage(vertex) fn main( diff --git a/src/dawn/samples/ComputeBoids.cpp b/src/dawn/samples/ComputeBoids.cpp index cbe7d3f14e..d91b4a4bd8 100644 --- a/src/dawn/samples/ComputeBoids.cpp +++ b/src/dawn/samples/ComputeBoids.cpp @@ -296,9 +296,7 @@ void init() { device = CreateCppDawnDevice(); queue = device.GetQueue(); - swapchain = GetSwapChain(device); - swapchain.Configure(GetPreferredSwapChainTextureFormat(), wgpu::TextureUsage::RenderAttachment, - 640, 480); + swapchain = GetSwapChain(); initBuffers(); initRender(); diff --git a/src/dawn/samples/CppHelloTriangle.cpp b/src/dawn/samples/CppHelloTriangle.cpp index c6a61046a1..3c3ba51ace 100644 --- a/src/dawn/samples/CppHelloTriangle.cpp +++ b/src/dawn/samples/CppHelloTriangle.cpp @@ -89,9 +89,7 @@ void init() { device = CreateCppDawnDevice(); queue = device.GetQueue(); - swapchain = GetSwapChain(device); - swapchain.Configure(GetPreferredSwapChainTextureFormat(), wgpu::TextureUsage::RenderAttachment, - 640, 480); + swapchain = GetSwapChain(); initBuffers(); initTextures(); diff --git a/src/dawn/samples/SampleUtils.cpp b/src/dawn/samples/SampleUtils.cpp index 4e7ef520fc..bce64bc308 100644 --- a/src/dawn/samples/SampleUtils.cpp +++ b/src/dawn/samples/SampleUtils.cpp @@ -22,7 +22,6 @@ #include "dawn/dawn_proc.h" #include "dawn/dawn_wsi.h" #include "dawn/native/DawnNative.h" -#include "dawn/utils/BackendBinding.h" #include "dawn/utils/GLFWUtils.h" #include "dawn/utils/TerribleCommandBuffer.h" #include "dawn/wire/WireClient.h" @@ -81,7 +80,7 @@ static wgpu::BackendType backendType = wgpu::BackendType::OpenGL; static CmdBufType cmdBufType = CmdBufType::Terrible; static std::unique_ptr instance; -static utils::BackendBinding* binding = nullptr; +static wgpu::SwapChain swapChain; static GLFWwindow* window = nullptr; @@ -110,7 +109,7 @@ wgpu::Device CreateCppDawnDevice() { } instance = std::make_unique(); - utils::DiscoverAdapter(instance.get(), window, backendType); + instance->DiscoverDefaultAdapters(); // Get an adapter for the backend to use, and create the device. dawn::native::Adapter backendAdapter; @@ -129,12 +128,23 @@ wgpu::Device CreateCppDawnDevice() { WGPUDevice backendDevice = backendAdapter.CreateDevice(); DawnProcTable backendProcs = dawn::native::GetProcs(); - binding = utils::CreateBinding(backendType, window, backendDevice); - if (binding == nullptr) { - return wgpu::Device(); - } + // Create the swapchain + auto surfaceChainedDesc = utils::SetupWindowAndGetSurfaceDescriptor(window); + WGPUSurfaceDescriptor surfaceDesc; + surfaceDesc.nextInChain = reinterpret_cast(surfaceChainedDesc.get()); + WGPUSurface surface = backendProcs.instanceCreateSurface(instance->Get(), &surfaceDesc); - // Choose whether to use the backend procs and devices directly, or set up the wire. + WGPUSwapChainDescriptor swapChainDesc; + swapChainDesc.usage = WGPUTextureUsage_RenderAttachment; + swapChainDesc.format = static_cast(GetPreferredSwapChainTextureFormat()); + swapChainDesc.width = 640; + swapChainDesc.height = 480; + swapChainDesc.presentMode = WGPUPresentMode_Mailbox; + swapChainDesc.implementation = 0; + WGPUSwapChain backendSwapChain = + backendProcs.deviceCreateSwapChain(backendDevice, surface, &swapChainDesc); + + // Choose whether to use the backend procs and devices/swapchains directly, or set up the wire. WGPUDevice cDevice = nullptr; DawnProcTable procs; @@ -142,6 +152,7 @@ wgpu::Device CreateCppDawnDevice() { case CmdBufType::None: procs = backendProcs; cDevice = backendDevice; + swapChain = wgpu::SwapChain::Acquire(backendSwapChain); break; case CmdBufType::Terrible: { @@ -165,8 +176,13 @@ wgpu::Device CreateCppDawnDevice() { auto deviceReservation = wireClient->ReserveDevice(); wireServer->InjectDevice(backendDevice, deviceReservation.id, deviceReservation.generation); - cDevice = deviceReservation.device; + + auto swapChainReservation = wireClient->ReserveSwapChain(cDevice); + wireServer->InjectSwapChain(backendSwapChain, swapChainReservation.id, + swapChainReservation.generation, deviceReservation.id, + deviceReservation.generation); + swapChain = wgpu::SwapChain::Acquire(swapChainReservation.swapchain); } break; } @@ -175,19 +191,13 @@ wgpu::Device CreateCppDawnDevice() { return wgpu::Device::Acquire(cDevice); } -uint64_t GetSwapChainImplementation() { - return binding->GetSwapChainImplementation(); -} - wgpu::TextureFormat GetPreferredSwapChainTextureFormat() { - DoFlush(); - return static_cast(binding->GetPreferredSwapChainTextureFormat()); + // TODO(dawn:1362): Return the adapter's preferred format when implemented. + return wgpu::TextureFormat::BGRA8Unorm; } -wgpu::SwapChain GetSwapChain(const wgpu::Device& device) { - wgpu::SwapChainDescriptor swapChainDesc; - swapChainDesc.implementation = GetSwapChainImplementation(); - return device.CreateSwapChain(nullptr, &swapChainDesc); +wgpu::SwapChain GetSwapChain() { + return swapChain; } wgpu::TextureView CreateDefaultDepthStencilView(const wgpu::Device& device) { @@ -257,6 +267,16 @@ bool InitSample(int argc, const char** argv) { return false; } } + + // TODO(dawn:810): Reenable once the OpenGL(ES) backend is able to create its own context such + // that it can use surface-based swapchains. + if (backendType == wgpu::BackendType::OpenGL || backendType == wgpu::BackendType::OpenGLES) { + fprintf(stderr, + "The OpenGL(ES) backend is temporarily not supported for samples. See " + "https://crbug.com/dawn/810"); + return false; + } + return true; } diff --git a/src/dawn/samples/SampleUtils.h b/src/dawn/samples/SampleUtils.h index 1555d52f28..d7f6d172e9 100644 --- a/src/dawn/samples/SampleUtils.h +++ b/src/dawn/samples/SampleUtils.h @@ -26,9 +26,8 @@ struct GLFWwindow; struct GLFWwindow* GetGLFWWindow(); wgpu::Device CreateCppDawnDevice(); -uint64_t GetSwapChainImplementation(); wgpu::TextureFormat GetPreferredSwapChainTextureFormat(); -wgpu::SwapChain GetSwapChain(const wgpu::Device& device); +wgpu::SwapChain GetSwapChain(); wgpu::TextureView CreateDefaultDepthStencilView(const wgpu::Device& device); #endif // SRC_DAWN_SAMPLES_SAMPLEUTILS_H_ diff --git a/src/dawn/tests/end2end/WindowSurfaceTests.cpp b/src/dawn/tests/end2end/WindowSurfaceTests.cpp index 1974f3c750..89978f2dc6 100644 --- a/src/dawn/tests/end2end/WindowSurfaceTests.cpp +++ b/src/dawn/tests/end2end/WindowSurfaceTests.cpp @@ -85,7 +85,7 @@ class WindowSurfaceInstanceTests : public testing::Test { TEST_F(WindowSurfaceInstanceTests, ControlCase) { GLFWwindow* window = CreateWindow(); std::unique_ptr chainedDescriptor = - utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); + utils::SetupWindowAndGetSurfaceDescriptor(window); wgpu::SurfaceDescriptor descriptor; descriptor.nextInChain = chainedDescriptor.get(); @@ -127,9 +127,9 @@ TEST_F(WindowSurfaceInstanceTests, HTMLCanvasDescriptor) { TEST_F(WindowSurfaceInstanceTests, TwoChainedDescriptors) { GLFWwindow* window = CreateWindow(); std::unique_ptr chainedDescriptor1 = - utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); + utils::SetupWindowAndGetSurfaceDescriptor(window); std::unique_ptr chainedDescriptor2 = - utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); + utils::SetupWindowAndGetSurfaceDescriptor(window); wgpu::SurfaceDescriptor descriptor; descriptor.nextInChain = chainedDescriptor1.get(); @@ -144,7 +144,7 @@ TEST_F(WindowSurfaceInstanceTests, TwoChainedDescriptors) { TEST_F(WindowSurfaceInstanceTests, CorrectSTypeHWND) { GLFWwindow* window = CreateWindow(); std::unique_ptr chainedDescriptor = - utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); + utils::SetupWindowAndGetSurfaceDescriptor(window); ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromWindowsHWND); } @@ -180,7 +180,7 @@ TEST_F(WindowSurfaceInstanceTests, HWNDSurfacesAreInvalid) { TEST_F(WindowSurfaceInstanceTests, CorrectSTypeXlib) { GLFWwindow* window = CreateWindow(); std::unique_ptr chainedDescriptor = - utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); + utils::SetupWindowAndGetSurfaceDescriptor(window); ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromXlibWindow); } @@ -220,7 +220,7 @@ TEST_F(WindowSurfaceInstanceTests, XlibSurfacesAreInvalid) { TEST_F(WindowSurfaceInstanceTests, CorrectSTypeMetal) { GLFWwindow* window = CreateWindow(); std::unique_ptr chainedDescriptor = - utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); + utils::SetupWindowAndGetSurfaceDescriptor(window); ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromMetalLayer); } diff --git a/src/dawn/utils/GLFWUtils.cpp b/src/dawn/utils/GLFWUtils.cpp index de77ccd462..d8c162c463 100644 --- a/src/dawn/utils/GLFWUtils.cpp +++ b/src/dawn/utils/GLFWUtils.cpp @@ -48,9 +48,9 @@ namespace utils { } } - wgpu::Surface CreateSurfaceForWindow(wgpu::Instance instance, GLFWwindow* window) { + wgpu::Surface CreateSurfaceForWindow(const wgpu::Instance& instance, GLFWwindow* window) { std::unique_ptr chainedDescriptor = - SetupWindowAndGetSurfaceDescriptorForTesting(window); + SetupWindowAndGetSurfaceDescriptor(window); wgpu::SurfaceDescriptor descriptor; descriptor.nextInChain = chainedDescriptor.get(); @@ -60,8 +60,7 @@ namespace utils { } #if defined(DAWN_PLATFORM_WINDOWS) - std::unique_ptr SetupWindowAndGetSurfaceDescriptorForTesting( - GLFWwindow* window) { + std::unique_ptr SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) { std::unique_ptr desc = std::make_unique(); desc->hwnd = glfwGetWin32Window(window); @@ -69,8 +68,7 @@ namespace utils { return std::move(desc); } #elif defined(DAWN_USE_X11) - std::unique_ptr SetupWindowAndGetSurfaceDescriptorForTesting( - GLFWwindow* window) { + std::unique_ptr SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) { std::unique_ptr desc = std::make_unique(); desc->display = glfwGetX11Display(); @@ -78,9 +76,9 @@ namespace utils { return std::move(desc); } #elif defined(DAWN_ENABLE_BACKEND_METAL) - // SetupWindowAndGetSurfaceDescriptorForTesting defined in GLFWUtils_metal.mm + // SetupWindowAndGetSurfaceDescriptor defined in GLFWUtils_metal.mm #else - std::unique_ptr SetupWindowAndGetSurfaceDescriptorForTesting(GLFWwindow*) { + std::unique_ptr SetupWindowAndGetSurfaceDescriptor(GLFWwindow*) { return nullptr; } #endif diff --git a/src/dawn/utils/GLFWUtils.h b/src/dawn/utils/GLFWUtils.h index 7df9f75d63..11ec67304a 100644 --- a/src/dawn/utils/GLFWUtils.h +++ b/src/dawn/utils/GLFWUtils.h @@ -30,12 +30,12 @@ namespace utils { // Does the necessary setup on the GLFWwindow to allow creating a wgpu::Surface with it and // calls `instance.CreateSurface` with the correct descriptor for this window. // Returns a null wgpu::Surface on failure. - wgpu::Surface CreateSurfaceForWindow(wgpu::Instance instance, GLFWwindow* window); + wgpu::Surface CreateSurfaceForWindow(const wgpu::Instance& instance, GLFWwindow* window); // Use for testing only. Does everything that CreateSurfaceForWindow does except the call to - // CreateSurface so the descriptor can be modified for testing. - std::unique_ptr SetupWindowAndGetSurfaceDescriptorForTesting( - GLFWwindow* window); + // CreateSurface. Useful to be able to modify the descriptor for testing, or when trying to + // avoid using the global proc table. + std::unique_ptr SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window); } // namespace utils diff --git a/src/dawn/utils/GLFWUtils_metal.mm b/src/dawn/utils/GLFWUtils_metal.mm index b574002ce4..324988764c 100644 --- a/src/dawn/utils/GLFWUtils_metal.mm +++ b/src/dawn/utils/GLFWUtils_metal.mm @@ -28,8 +28,7 @@ namespace utils { - std::unique_ptr SetupWindowAndGetSurfaceDescriptorForTesting( - GLFWwindow* window) { + std::unique_ptr SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) { if (@available(macOS 10.11, *)) { NSWindow* nsWindow = glfwGetCocoaWindow(window); NSView* view = [nsWindow contentView];