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();
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 {

View File

@ -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<WGPUTextureFormat>(GetPreferredSwapChainTextureFormat());
wgpuSwapChainConfigure(swapchain, swapChainFormat, WGPUTextureUsage_RenderAttachment, 640, 480);
const char* vs = R"(
@stage(vertex) fn main(

View File

@ -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();

View File

@ -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();

View File

@ -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<dawn::native::Instance> 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<dawn::native::Instance>();
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<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;
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<wgpu::TextureFormat>(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;
}

View File

@ -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_

View File

@ -85,7 +85,7 @@ class WindowSurfaceInstanceTests : public testing::Test {
TEST_F(WindowSurfaceInstanceTests, ControlCase) {
GLFWwindow* window = CreateWindow();
std::unique_ptr<wgpu::ChainedStruct> 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<wgpu::ChainedStruct> chainedDescriptor1 =
utils::SetupWindowAndGetSurfaceDescriptorForTesting(window);
utils::SetupWindowAndGetSurfaceDescriptor(window);
std::unique_ptr<wgpu::ChainedStruct> 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<wgpu::ChainedStruct> 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<wgpu::ChainedStruct> 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<wgpu::ChainedStruct> chainedDescriptor =
utils::SetupWindowAndGetSurfaceDescriptorForTesting(window);
utils::SetupWindowAndGetSurfaceDescriptor(window);
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 =
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<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorForTesting(
GLFWwindow* window) {
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) {
std::unique_ptr<wgpu::SurfaceDescriptorFromWindowsHWND> desc =
std::make_unique<wgpu::SurfaceDescriptorFromWindowsHWND>();
desc->hwnd = glfwGetWin32Window(window);
@ -69,8 +68,7 @@ namespace utils {
return std::move(desc);
}
#elif defined(DAWN_USE_X11)
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorForTesting(
GLFWwindow* window) {
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window) {
std::unique_ptr<wgpu::SurfaceDescriptorFromXlibWindow> desc =
std::make_unique<wgpu::SurfaceDescriptorFromXlibWindow>();
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<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorForTesting(GLFWwindow*) {
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow*) {
return nullptr;
}
#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
// 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<wgpu::ChainedStruct> 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<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(GLFWwindow* window);
} // namespace utils

View File

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