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 <lokokung@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2022-04-13 15:33:06 +00:00 committed by Dawn LUCI CQ
parent 2517d99f35
commit 147da21856
10 changed files with 61 additions and 57 deletions

View File

@ -53,9 +53,7 @@ void init() {
device = CreateCppDawnDevice(); device = CreateCppDawnDevice();
queue = device.GetQueue(); queue = device.GetQueue();
swapchain = GetSwapChain(device); swapchain = GetSwapChain();
swapchain.Configure(GetPreferredSwapChainTextureFormat(), wgpu::TextureUsage::RenderAttachment,
640, 480);
wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"( wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
struct Constants { struct Constants {

View File

@ -28,14 +28,8 @@ WGPUTextureFormat swapChainFormat;
void init() { void init() {
device = CreateCppDawnDevice().Release(); device = CreateCppDawnDevice().Release();
queue = wgpuDeviceGetQueue(device); queue = wgpuDeviceGetQueue(device);
swapchain = GetSwapChain().Release();
{
WGPUSwapChainDescriptor descriptor = {};
descriptor.implementation = GetSwapChainImplementation();
swapchain = wgpuDeviceCreateSwapChain(device, nullptr, &descriptor);
}
swapChainFormat = static_cast<WGPUTextureFormat>(GetPreferredSwapChainTextureFormat()); swapChainFormat = static_cast<WGPUTextureFormat>(GetPreferredSwapChainTextureFormat());
wgpuSwapChainConfigure(swapchain, swapChainFormat, WGPUTextureUsage_RenderAttachment, 640, 480);
const char* vs = R"( const char* vs = R"(
@stage(vertex) fn main( @stage(vertex) fn main(

View File

@ -296,9 +296,7 @@ void init() {
device = CreateCppDawnDevice(); device = CreateCppDawnDevice();
queue = device.GetQueue(); queue = device.GetQueue();
swapchain = GetSwapChain(device); swapchain = GetSwapChain();
swapchain.Configure(GetPreferredSwapChainTextureFormat(), wgpu::TextureUsage::RenderAttachment,
640, 480);
initBuffers(); initBuffers();
initRender(); initRender();

View File

@ -89,9 +89,7 @@ void init() {
device = CreateCppDawnDevice(); device = CreateCppDawnDevice();
queue = device.GetQueue(); queue = device.GetQueue();
swapchain = GetSwapChain(device); swapchain = GetSwapChain();
swapchain.Configure(GetPreferredSwapChainTextureFormat(), wgpu::TextureUsage::RenderAttachment,
640, 480);
initBuffers(); initBuffers();
initTextures(); initTextures();

View File

@ -22,7 +22,6 @@
#include "dawn/dawn_proc.h" #include "dawn/dawn_proc.h"
#include "dawn/dawn_wsi.h" #include "dawn/dawn_wsi.h"
#include "dawn/native/DawnNative.h" #include "dawn/native/DawnNative.h"
#include "dawn/utils/BackendBinding.h"
#include "dawn/utils/GLFWUtils.h" #include "dawn/utils/GLFWUtils.h"
#include "dawn/utils/TerribleCommandBuffer.h" #include "dawn/utils/TerribleCommandBuffer.h"
#include "dawn/wire/WireClient.h" #include "dawn/wire/WireClient.h"
@ -81,7 +80,7 @@ static wgpu::BackendType backendType = wgpu::BackendType::OpenGL;
static CmdBufType cmdBufType = CmdBufType::Terrible; static CmdBufType cmdBufType = CmdBufType::Terrible;
static std::unique_ptr<dawn::native::Instance> instance; static std::unique_ptr<dawn::native::Instance> instance;
static utils::BackendBinding* binding = nullptr; static wgpu::SwapChain swapChain;
static GLFWwindow* window = nullptr; static GLFWwindow* window = nullptr;
@ -110,7 +109,7 @@ wgpu::Device CreateCppDawnDevice() {
} }
instance = std::make_unique<dawn::native::Instance>(); instance = std::make_unique<dawn::native::Instance>();
utils::DiscoverAdapter(instance.get(), window, backendType); instance->DiscoverDefaultAdapters();
// Get an adapter for the backend to use, and create the device. // Get an adapter for the backend to use, and create the device.
dawn::native::Adapter backendAdapter; dawn::native::Adapter backendAdapter;
@ -129,12 +128,23 @@ wgpu::Device CreateCppDawnDevice() {
WGPUDevice backendDevice = backendAdapter.CreateDevice(); WGPUDevice backendDevice = backendAdapter.CreateDevice();
DawnProcTable backendProcs = dawn::native::GetProcs(); DawnProcTable backendProcs = dawn::native::GetProcs();
binding = utils::CreateBinding(backendType, window, backendDevice); // Create the swapchain
if (binding == nullptr) { auto surfaceChainedDesc = utils::SetupWindowAndGetSurfaceDescriptor(window);
return wgpu::Device(); WGPUSurfaceDescriptor surfaceDesc;
} surfaceDesc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(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<WGPUTextureFormat>(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; WGPUDevice cDevice = nullptr;
DawnProcTable procs; DawnProcTable procs;
@ -142,6 +152,7 @@ wgpu::Device CreateCppDawnDevice() {
case CmdBufType::None: case CmdBufType::None:
procs = backendProcs; procs = backendProcs;
cDevice = backendDevice; cDevice = backendDevice;
swapChain = wgpu::SwapChain::Acquire(backendSwapChain);
break; break;
case CmdBufType::Terrible: { case CmdBufType::Terrible: {
@ -165,8 +176,13 @@ wgpu::Device CreateCppDawnDevice() {
auto deviceReservation = wireClient->ReserveDevice(); auto deviceReservation = wireClient->ReserveDevice();
wireServer->InjectDevice(backendDevice, deviceReservation.id, wireServer->InjectDevice(backendDevice, deviceReservation.id,
deviceReservation.generation); deviceReservation.generation);
cDevice = deviceReservation.device; 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; } break;
} }
@ -175,19 +191,13 @@ wgpu::Device CreateCppDawnDevice() {
return wgpu::Device::Acquire(cDevice); return wgpu::Device::Acquire(cDevice);
} }
uint64_t GetSwapChainImplementation() {
return binding->GetSwapChainImplementation();
}
wgpu::TextureFormat GetPreferredSwapChainTextureFormat() { wgpu::TextureFormat GetPreferredSwapChainTextureFormat() {
DoFlush(); // TODO(dawn:1362): Return the adapter's preferred format when implemented.
return static_cast<wgpu::TextureFormat>(binding->GetPreferredSwapChainTextureFormat()); return wgpu::TextureFormat::BGRA8Unorm;
} }
wgpu::SwapChain GetSwapChain(const wgpu::Device& device) { wgpu::SwapChain GetSwapChain() {
wgpu::SwapChainDescriptor swapChainDesc; return swapChain;
swapChainDesc.implementation = GetSwapChainImplementation();
return device.CreateSwapChain(nullptr, &swapChainDesc);
} }
wgpu::TextureView CreateDefaultDepthStencilView(const wgpu::Device& device) { wgpu::TextureView CreateDefaultDepthStencilView(const wgpu::Device& device) {
@ -257,6 +267,16 @@ bool InitSample(int argc, const char** argv) {
return false; 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; return true;
} }

View File

@ -26,9 +26,8 @@ struct GLFWwindow;
struct GLFWwindow* GetGLFWWindow(); struct GLFWwindow* GetGLFWWindow();
wgpu::Device CreateCppDawnDevice(); wgpu::Device CreateCppDawnDevice();
uint64_t GetSwapChainImplementation();
wgpu::TextureFormat GetPreferredSwapChainTextureFormat(); wgpu::TextureFormat GetPreferredSwapChainTextureFormat();
wgpu::SwapChain GetSwapChain(const wgpu::Device& device); wgpu::SwapChain GetSwapChain();
wgpu::TextureView CreateDefaultDepthStencilView(const wgpu::Device& device); wgpu::TextureView CreateDefaultDepthStencilView(const wgpu::Device& device);
#endif // SRC_DAWN_SAMPLES_SAMPLEUTILS_H_ #endif // SRC_DAWN_SAMPLES_SAMPLEUTILS_H_

View File

@ -85,7 +85,7 @@ class WindowSurfaceInstanceTests : public testing::Test {
TEST_F(WindowSurfaceInstanceTests, ControlCase) { TEST_F(WindowSurfaceInstanceTests, ControlCase) {
GLFWwindow* window = CreateWindow(); GLFWwindow* window = CreateWindow();
std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor = std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); utils::SetupWindowAndGetSurfaceDescriptor(window);
wgpu::SurfaceDescriptor descriptor; wgpu::SurfaceDescriptor descriptor;
descriptor.nextInChain = chainedDescriptor.get(); descriptor.nextInChain = chainedDescriptor.get();
@ -127,9 +127,9 @@ TEST_F(WindowSurfaceInstanceTests, HTMLCanvasDescriptor) {
TEST_F(WindowSurfaceInstanceTests, TwoChainedDescriptors) { TEST_F(WindowSurfaceInstanceTests, TwoChainedDescriptors) {
GLFWwindow* window = CreateWindow(); GLFWwindow* window = CreateWindow();
std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor1 = std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor1 =
utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); utils::SetupWindowAndGetSurfaceDescriptor(window);
std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor2 = std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor2 =
utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); utils::SetupWindowAndGetSurfaceDescriptor(window);
wgpu::SurfaceDescriptor descriptor; wgpu::SurfaceDescriptor descriptor;
descriptor.nextInChain = chainedDescriptor1.get(); descriptor.nextInChain = chainedDescriptor1.get();
@ -144,7 +144,7 @@ TEST_F(WindowSurfaceInstanceTests, TwoChainedDescriptors) {
TEST_F(WindowSurfaceInstanceTests, CorrectSTypeHWND) { TEST_F(WindowSurfaceInstanceTests, CorrectSTypeHWND) {
GLFWwindow* window = CreateWindow(); GLFWwindow* window = CreateWindow();
std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor = std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); utils::SetupWindowAndGetSurfaceDescriptor(window);
ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromWindowsHWND); ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromWindowsHWND);
} }
@ -180,7 +180,7 @@ TEST_F(WindowSurfaceInstanceTests, HWNDSurfacesAreInvalid) {
TEST_F(WindowSurfaceInstanceTests, CorrectSTypeXlib) { TEST_F(WindowSurfaceInstanceTests, CorrectSTypeXlib) {
GLFWwindow* window = CreateWindow(); GLFWwindow* window = CreateWindow();
std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor = std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); utils::SetupWindowAndGetSurfaceDescriptor(window);
ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromXlibWindow); ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromXlibWindow);
} }
@ -220,7 +220,7 @@ TEST_F(WindowSurfaceInstanceTests, XlibSurfacesAreInvalid) {
TEST_F(WindowSurfaceInstanceTests, CorrectSTypeMetal) { TEST_F(WindowSurfaceInstanceTests, CorrectSTypeMetal) {
GLFWwindow* window = CreateWindow(); GLFWwindow* window = CreateWindow();
std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor = std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
utils::SetupWindowAndGetSurfaceDescriptorForTesting(window); utils::SetupWindowAndGetSurfaceDescriptor(window);
ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromMetalLayer); ASSERT_EQ(chainedDescriptor->sType, wgpu::SType::SurfaceDescriptorFromMetalLayer);
} }

View File

@ -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<wgpu::ChainedStruct> chainedDescriptor = std::unique_ptr<wgpu::ChainedStruct> chainedDescriptor =
SetupWindowAndGetSurfaceDescriptorForTesting(window); SetupWindowAndGetSurfaceDescriptor(window);
wgpu::SurfaceDescriptor descriptor; wgpu::SurfaceDescriptor descriptor;
descriptor.nextInChain = chainedDescriptor.get(); descriptor.nextInChain = chainedDescriptor.get();
@ -60,8 +60,7 @@ namespace utils {
} }
#if defined(DAWN_PLATFORM_WINDOWS) #if defined(DAWN_PLATFORM_WINDOWS)
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorForTesting( std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) {
GLFWwindow* window) {
std::unique_ptr<wgpu::SurfaceDescriptorFromWindowsHWND> desc = std::unique_ptr<wgpu::SurfaceDescriptorFromWindowsHWND> desc =
std::make_unique<wgpu::SurfaceDescriptorFromWindowsHWND>(); std::make_unique<wgpu::SurfaceDescriptorFromWindowsHWND>();
desc->hwnd = glfwGetWin32Window(window); desc->hwnd = glfwGetWin32Window(window);
@ -69,8 +68,7 @@ namespace utils {
return std::move(desc); return std::move(desc);
} }
#elif defined(DAWN_USE_X11) #elif defined(DAWN_USE_X11)
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorForTesting( std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) {
GLFWwindow* window) {
std::unique_ptr<wgpu::SurfaceDescriptorFromXlibWindow> desc = std::unique_ptr<wgpu::SurfaceDescriptorFromXlibWindow> desc =
std::make_unique<wgpu::SurfaceDescriptorFromXlibWindow>(); std::make_unique<wgpu::SurfaceDescriptorFromXlibWindow>();
desc->display = glfwGetX11Display(); desc->display = glfwGetX11Display();
@ -78,9 +76,9 @@ namespace utils {
return std::move(desc); return std::move(desc);
} }
#elif defined(DAWN_ENABLE_BACKEND_METAL) #elif defined(DAWN_ENABLE_BACKEND_METAL)
// SetupWindowAndGetSurfaceDescriptorForTesting defined in GLFWUtils_metal.mm // SetupWindowAndGetSurfaceDescriptor defined in GLFWUtils_metal.mm
#else #else
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorForTesting(GLFWwindow*) { std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow*) {
return nullptr; return nullptr;
} }
#endif #endif

View File

@ -30,12 +30,12 @@ namespace utils {
// Does the necessary setup on the GLFWwindow to allow creating a wgpu::Surface with it and // 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. // calls `instance.CreateSurface` with the correct descriptor for this window.
// Returns a null wgpu::Surface on failure. // 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 // Use for testing only. Does everything that CreateSurfaceForWindow does except the call to
// CreateSurface so the descriptor can be modified for testing. // CreateSurface. Useful to be able to modify the descriptor for testing, or when trying to
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorForTesting( // avoid using the global proc table.
GLFWwindow* window); std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window);
} // namespace utils } // namespace utils

View File

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