Descriptorize SwapChain.

This also makes SwapChain support WebGPU-style error handling.

BUG=dawn:8

Change-Id: I5a142ae58600445f0f44f6dbe419cb7c3cdc9464
Reviewed-on: https://dawn-review.googlesource.com/c/4660
Reviewed-by: Yunchao He <yunchao.he@intel.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2019-02-15 11:15:58 +00:00 committed by Commit Bot service account
parent c8b067d2df
commit 7be2a71f2b
27 changed files with 212 additions and 111 deletions

View File

@ -475,8 +475,11 @@
] ]
}, },
{ {
"name": "create swap chain builder", "name": "create swap chain",
"returns": "swap chain builder" "returns": "swap chain",
"args": [
{"name": "descriptor", "type": "swap chain descriptor", "annotation": "const*"}
]
}, },
{ {
"name": "create texture", "name": "create texture",
@ -957,19 +960,11 @@
} }
] ]
}, },
"swap chain builder": { "swap chain descriptor": {
"category": "object", "category": "structure",
"methods": [ "extensible": true,
{ "members": [
"name": "get result", {"name": "implementation", "type": "uint64_t"}
"returns": "swap chain"
},
{
"name": "set implementation",
"args": [
{"name": "implementation", "type": "uint64_t"}
]
}
] ]
}, },
"texture": { "texture": {

View File

@ -29,11 +29,10 @@ void init() {
queue = dawnDeviceCreateQueue(device); queue = dawnDeviceCreateQueue(device);
{ {
dawnSwapChainBuilder builder = dawnDeviceCreateSwapChainBuilder(device); dawnSwapChainDescriptor descriptor;
uint64_t swapchainImpl = GetSwapChainImplementation(); descriptor.nextInChain = nullptr;
dawnSwapChainBuilderSetImplementation(builder, swapchainImpl); descriptor.implementation = GetSwapChainImplementation();
swapchain = dawnSwapChainBuilderGetResult(builder); swapchain = dawnDeviceCreateSwapChain(device, &descriptor);
dawnSwapChainBuilderRelease(builder);
} }
swapChainFormat = static_cast<dawnTextureFormat>(GetPreferredSwapChainTextureFormat()); swapChainFormat = static_cast<dawnTextureFormat>(GetPreferredSwapChainTextureFormat());
dawnSwapChainConfigure(swapchain, swapChainFormat, DAWN_TEXTURE_USAGE_BIT_OUTPUT_ATTACHMENT, 640, dawnSwapChainConfigure(swapchain, swapChainFormat, DAWN_TEXTURE_USAGE_BIT_OUTPUT_ATTACHMENT, 640,

View File

@ -150,9 +150,9 @@ dawn::TextureFormat GetPreferredSwapChainTextureFormat() {
} }
dawn::SwapChain GetSwapChain(const dawn::Device &device) { dawn::SwapChain GetSwapChain(const dawn::Device &device) {
return device.CreateSwapChainBuilder() dawn::SwapChainDescriptor swapChainDesc;
.SetImplementation(GetSwapChainImplementation()) swapChainDesc.implementation = GetSwapChainImplementation();
.GetResult(); return device.CreateSwapChain(&swapChainDesc);
} }
dawn::TextureView CreateDefaultDepthStencilView(const dawn::Device& device) { dawn::TextureView CreateDefaultDepthStencilView(const dawn::Device& device) {

View File

@ -220,8 +220,14 @@ namespace dawn_native {
return result; return result;
} }
SwapChainBuilder* DeviceBase::CreateSwapChainBuilder() { SwapChainBase* DeviceBase::CreateSwapChain(const SwapChainDescriptor* descriptor) {
return new SwapChainBuilder(this); SwapChainBase* result = nullptr;
if (ConsumedError(CreateSwapChainInternal(&result, descriptor))) {
return SwapChainBase::MakeError(this);
}
return result;
} }
TextureBase* DeviceBase::CreateTexture(const TextureDescriptor* descriptor) { TextureBase* DeviceBase::CreateTexture(const TextureDescriptor* descriptor) {
TextureBase* result = nullptr; TextureBase* result = nullptr;
@ -337,6 +343,13 @@ namespace dawn_native {
return {}; return {};
} }
MaybeError DeviceBase::CreateSwapChainInternal(SwapChainBase** result,
const SwapChainDescriptor* descriptor) {
DAWN_TRY(ValidateSwapChainDescriptor(this, descriptor));
DAWN_TRY_ASSIGN(*result, CreateSwapChainImpl(descriptor));
return {};
}
MaybeError DeviceBase::CreateTextureInternal(TextureBase** result, MaybeError DeviceBase::CreateTextureInternal(TextureBase** result,
const TextureDescriptor* descriptor) { const TextureDescriptor* descriptor) {
DAWN_TRY(ValidateTextureDescriptor(this, descriptor)); DAWN_TRY(ValidateTextureDescriptor(this, descriptor));

View File

@ -62,7 +62,6 @@ namespace dawn_native {
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0; virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
virtual RenderPassDescriptorBase* CreateRenderPassDescriptor( virtual RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) = 0; RenderPassDescriptorBuilder* builder) = 0;
virtual SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) = 0;
virtual Serial GetCompletedCommandSerial() const = 0; virtual Serial GetCompletedCommandSerial() const = 0;
virtual Serial GetLastSubmittedCommandSerial() const = 0; virtual Serial GetLastSubmittedCommandSerial() const = 0;
@ -101,7 +100,7 @@ namespace dawn_native {
RenderPipelineBase* CreateRenderPipeline(const RenderPipelineDescriptor* descriptor); RenderPipelineBase* CreateRenderPipeline(const RenderPipelineDescriptor* descriptor);
SamplerBase* CreateSampler(const SamplerDescriptor* descriptor); SamplerBase* CreateSampler(const SamplerDescriptor* descriptor);
ShaderModuleBase* CreateShaderModule(const ShaderModuleDescriptor* descriptor); ShaderModuleBase* CreateShaderModule(const ShaderModuleDescriptor* descriptor);
SwapChainBuilder* CreateSwapChainBuilder(); SwapChainBase* CreateSwapChain(const SwapChainDescriptor* descriptor);
TextureBase* CreateTexture(const TextureDescriptor* descriptor); TextureBase* CreateTexture(const TextureDescriptor* descriptor);
TextureViewBase* CreateTextureView(TextureBase* texture, TextureViewBase* CreateTextureView(TextureBase* texture,
const TextureViewDescriptor* descriptor); const TextureViewDescriptor* descriptor);
@ -141,6 +140,8 @@ namespace dawn_native {
const SamplerDescriptor* descriptor) = 0; const SamplerDescriptor* descriptor) = 0;
virtual ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( virtual ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) = 0; const ShaderModuleDescriptor* descriptor) = 0;
virtual ResultOrError<SwapChainBase*> CreateSwapChainImpl(
const SwapChainDescriptor* descriptor) = 0;
virtual ResultOrError<TextureBase*> CreateTextureImpl( virtual ResultOrError<TextureBase*> CreateTextureImpl(
const TextureDescriptor* descriptor) = 0; const TextureDescriptor* descriptor) = 0;
virtual ResultOrError<TextureViewBase*> CreateTextureViewImpl( virtual ResultOrError<TextureViewBase*> CreateTextureViewImpl(
@ -163,6 +164,8 @@ namespace dawn_native {
MaybeError CreateSamplerInternal(SamplerBase** result, const SamplerDescriptor* descriptor); MaybeError CreateSamplerInternal(SamplerBase** result, const SamplerDescriptor* descriptor);
MaybeError CreateShaderModuleInternal(ShaderModuleBase** result, MaybeError CreateShaderModuleInternal(ShaderModuleBase** result,
const ShaderModuleDescriptor* descriptor); const ShaderModuleDescriptor* descriptor);
MaybeError CreateSwapChainInternal(SwapChainBase** result,
const SwapChainDescriptor* descriptor);
MaybeError CreateTextureInternal(TextureBase** result, const TextureDescriptor* descriptor); MaybeError CreateTextureInternal(TextureBase** result, const TextureDescriptor* descriptor);
MaybeError CreateTextureViewInternal(TextureViewBase** result, MaybeError CreateTextureViewInternal(TextureViewBase** result,
TextureBase* texture, TextureBase* texture,

View File

@ -16,28 +16,79 @@
#include "dawn_native/Device.h" #include "dawn_native/Device.h"
#include "dawn_native/Texture.h" #include "dawn_native/Texture.h"
#include "dawn_native/ValidationUtils_autogen.h"
namespace dawn_native { namespace dawn_native {
namespace {
class ErrorSwapChain : public SwapChainBase {
public:
ErrorSwapChain(DeviceBase* device) : SwapChainBase(device, ObjectBase::kError) {
}
private:
TextureBase* GetNextTextureImpl(const TextureDescriptor*) override {
UNREACHABLE();
}
void OnBeforePresent(TextureBase* texture) override {
UNREACHABLE();
}
};
} // anonymous namespace
MaybeError ValidateSwapChainDescriptor(const DeviceBase* device,
const SwapChainDescriptor* descriptor) {
if (descriptor->implementation == 0) {
return DAWN_VALIDATION_ERROR("Null implementation for the swapchain");
}
dawnSwapChainImplementation* impl =
reinterpret_cast<dawnSwapChainImplementation*>(descriptor->implementation);
if (!impl->Init || !impl->Destroy || !impl->Configure || !impl->GetNextTexture ||
!impl->Present) {
return DAWN_VALIDATION_ERROR("Implementation is incomplete");
}
return {};
}
// SwapChain // SwapChain
SwapChainBase::SwapChainBase(SwapChainBuilder* builder) SwapChainBase::SwapChainBase(DeviceBase* device, const SwapChainDescriptor* descriptor)
: ObjectBase(builder->GetDevice()), mImplementation(builder->mImplementation) { : ObjectBase(device),
mImplementation(
*reinterpret_cast<dawnSwapChainImplementation*>(descriptor->implementation)) {
}
SwapChainBase::SwapChainBase(DeviceBase* device, ObjectBase::ErrorTag tag)
: ObjectBase(device, tag) {
} }
SwapChainBase::~SwapChainBase() { SwapChainBase::~SwapChainBase() {
const auto& im = GetImplementation(); if (!IsError()) {
im.Destroy(im.userData); const auto& im = GetImplementation();
im.Destroy(im.userData);
}
}
// static
SwapChainBase* SwapChainBase::MakeError(DeviceBase* device) {
return new ErrorSwapChain(device);
} }
void SwapChainBase::Configure(dawn::TextureFormat format, void SwapChainBase::Configure(dawn::TextureFormat format,
dawn::TextureUsageBit allowedUsage, dawn::TextureUsageBit allowedUsage,
uint32_t width, uint32_t width,
uint32_t height) { uint32_t height) {
if (width == 0 || height == 0) { if (GetDevice()->ConsumedError(ValidateConfigure(format, allowedUsage, width, height))) {
GetDevice()->HandleError("Swap chain cannot be configured to zero size");
return; return;
} }
ASSERT(!IsError());
allowedUsage |= dawn::TextureUsageBit::Present; allowedUsage |= dawn::TextureUsageBit::Present;
mFormat = format; mFormat = format;
@ -49,11 +100,10 @@ namespace dawn_native {
} }
TextureBase* SwapChainBase::GetNextTexture() { TextureBase* SwapChainBase::GetNextTexture() {
if (mWidth == 0) { if (GetDevice()->ConsumedError(ValidateGetNextTexture())) {
// If width is 0, it implies swap chain has never been configured return TextureBase::MakeError(GetDevice());
GetDevice()->HandleError("Swap chain needs to be configured before GetNextTexture");
return nullptr;
} }
ASSERT(!IsError());
TextureDescriptor descriptor; TextureDescriptor descriptor;
descriptor.dimension = dawn::TextureDimension::e2D; descriptor.dimension = dawn::TextureDimension::e2D;
@ -72,11 +122,10 @@ namespace dawn_native {
} }
void SwapChainBase::Present(TextureBase* texture) { void SwapChainBase::Present(TextureBase* texture) {
// This also checks that the texture is valid since mLastNextTexture is always valid. if (GetDevice()->ConsumedError(ValidatePresent(texture))) {
if (texture != mLastNextTexture) {
GetDevice()->HandleError("Tried to present something other than the last NextTexture");
return; return;
} }
ASSERT(!IsError());
OnBeforePresent(texture); OnBeforePresent(texture);
@ -84,37 +133,48 @@ namespace dawn_native {
} }
const dawnSwapChainImplementation& SwapChainBase::GetImplementation() { const dawnSwapChainImplementation& SwapChainBase::GetImplementation() {
ASSERT(!IsError());
return mImplementation; return mImplementation;
} }
// SwapChain Builder MaybeError SwapChainBase::ValidateConfigure(dawn::TextureFormat format,
dawn::TextureUsageBit allowedUsage,
uint32_t width,
uint32_t height) const {
DAWN_TRY(GetDevice()->ValidateObject(this));
SwapChainBuilder::SwapChainBuilder(DeviceBase* device) : Builder(device) { DAWN_TRY(ValidateTextureUsageBit(allowedUsage));
} DAWN_TRY(ValidateTextureFormat(format));
SwapChainBase* SwapChainBuilder::GetResultImpl() { if (width == 0 || height == 0) {
if (!mImplementation.Init) { return DAWN_VALIDATION_ERROR("Swap chain cannot be configured to zero size");
HandleError("Implementation not set");
return nullptr;
}
return GetDevice()->CreateSwapChain(this);
}
void SwapChainBuilder::SetImplementation(uint64_t implementation) {
if (!implementation) {
HandleError("Implementation pointer is invalid");
return;
} }
dawnSwapChainImplementation& impl = return {};
*reinterpret_cast<dawnSwapChainImplementation*>(implementation); }
if (!impl.Init || !impl.Destroy || !impl.Configure || !impl.GetNextTexture || MaybeError SwapChainBase::ValidateGetNextTexture() const {
!impl.Present) { DAWN_TRY(GetDevice()->ValidateObject(this));
HandleError("Implementation is incomplete");
return; if (mWidth == 0) {
// If width is 0, it implies swap chain has never been configured
return DAWN_VALIDATION_ERROR("Swap chain needs to be configured before GetNextTexture");
} }
mImplementation = impl; return {};
} }
MaybeError SwapChainBase::ValidatePresent(TextureBase* texture) const {
DAWN_TRY(GetDevice()->ValidateObject(this));
DAWN_TRY(GetDevice()->ValidateObject(texture));
// This also checks that the texture is valid since mLastNextTexture is always valid.
if (texture != mLastNextTexture) {
return DAWN_VALIDATION_ERROR(
"Tried to present something other than the last NextTexture");
}
return {};
}
} // namespace dawn_native } // namespace dawn_native

View File

@ -16,6 +16,7 @@
#define DAWNNATIVE_SWAPCHAIN_H_ #define DAWNNATIVE_SWAPCHAIN_H_
#include "dawn_native/Builder.h" #include "dawn_native/Builder.h"
#include "dawn_native/Error.h"
#include "dawn_native/Forward.h" #include "dawn_native/Forward.h"
#include "dawn_native/ObjectBase.h" #include "dawn_native/ObjectBase.h"
@ -24,11 +25,16 @@
namespace dawn_native { namespace dawn_native {
MaybeError ValidateSwapChainDescriptor(const DeviceBase* device,
const SwapChainDescriptor* descriptor);
class SwapChainBase : public ObjectBase { class SwapChainBase : public ObjectBase {
public: public:
SwapChainBase(SwapChainBuilder* builder); SwapChainBase(DeviceBase* device, const SwapChainDescriptor* descriptor);
~SwapChainBase(); ~SwapChainBase();
static SwapChainBase* MakeError(DeviceBase* device);
// Dawn API // Dawn API
void Configure(dawn::TextureFormat format, void Configure(dawn::TextureFormat format,
dawn::TextureUsageBit allowedUsage, dawn::TextureUsageBit allowedUsage,
@ -38,11 +44,20 @@ namespace dawn_native {
void Present(TextureBase* texture); void Present(TextureBase* texture);
protected: protected:
SwapChainBase(DeviceBase* device, ObjectBase::ErrorTag tag);
const dawnSwapChainImplementation& GetImplementation(); const dawnSwapChainImplementation& GetImplementation();
virtual TextureBase* GetNextTextureImpl(const TextureDescriptor*) = 0; virtual TextureBase* GetNextTextureImpl(const TextureDescriptor*) = 0;
virtual void OnBeforePresent(TextureBase* texture) = 0; virtual void OnBeforePresent(TextureBase* texture) = 0;
private: private:
MaybeError ValidateConfigure(dawn::TextureFormat format,
dawn::TextureUsageBit allowedUsage,
uint32_t width,
uint32_t height) const;
MaybeError ValidateGetNextTexture() const;
MaybeError ValidatePresent(TextureBase* texture) const;
dawnSwapChainImplementation mImplementation = {}; dawnSwapChainImplementation mImplementation = {};
dawn::TextureFormat mFormat = {}; dawn::TextureFormat mFormat = {};
dawn::TextureUsageBit mAllowedUsage; dawn::TextureUsageBit mAllowedUsage;
@ -51,20 +66,6 @@ namespace dawn_native {
TextureBase* mLastNextTexture = nullptr; TextureBase* mLastNextTexture = nullptr;
}; };
class SwapChainBuilder : public Builder<SwapChainBase> {
public:
SwapChainBuilder(DeviceBase* device);
// Dawn API
SwapChainBase* GetResultImpl() override;
void SetImplementation(uint64_t implementation);
private:
friend class SwapChainBase;
dawnSwapChainImplementation mImplementation = {};
};
} // namespace dawn_native } // namespace dawn_native
#endif // DAWNNATIVE_SWAPCHAIN_H_ #endif // DAWNNATIVE_SWAPCHAIN_H_

View File

@ -231,8 +231,9 @@ namespace dawn_native { namespace d3d12 {
const ShaderModuleDescriptor* descriptor) { const ShaderModuleDescriptor* descriptor) {
return new ShaderModule(this, descriptor); return new ShaderModule(this, descriptor);
} }
SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) { ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl(
return new SwapChain(builder); const SwapChainDescriptor* descriptor) {
return new SwapChain(this, descriptor);
} }
ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) { ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) {
return new Texture(this, descriptor); return new Texture(this, descriptor);

View File

@ -44,7 +44,6 @@ namespace dawn_native { namespace d3d12 {
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor( RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override; RenderPassDescriptorBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
Serial GetCompletedCommandSerial() const final override; Serial GetCompletedCommandSerial() const final override;
Serial GetLastSubmittedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override;
@ -96,6 +95,8 @@ namespace dawn_native { namespace d3d12 {
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override; const ShaderModuleDescriptor* descriptor) override;
ResultOrError<SwapChainBase*> CreateSwapChainImpl(
const SwapChainDescriptor* descriptor) override;
ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override; ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override;
ResultOrError<TextureViewBase*> CreateTextureViewImpl( ResultOrError<TextureViewBase*> CreateTextureViewImpl(
TextureBase* texture, TextureBase* texture,

View File

@ -21,7 +21,8 @@
namespace dawn_native { namespace d3d12 { namespace dawn_native { namespace d3d12 {
SwapChain::SwapChain(SwapChainBuilder* builder) : SwapChainBase(builder) { SwapChain::SwapChain(Device* device, const SwapChainDescriptor* descriptor)
: SwapChainBase(device, descriptor) {
const auto& im = GetImplementation(); const auto& im = GetImplementation();
dawnWSIContextD3D12 wsiContext = {}; dawnWSIContextD3D12 wsiContext = {};
wsiContext.device = reinterpret_cast<dawnDevice>(GetDevice()); wsiContext.device = reinterpret_cast<dawnDevice>(GetDevice());

View File

@ -19,9 +19,11 @@
namespace dawn_native { namespace d3d12 { namespace dawn_native { namespace d3d12 {
class Device;
class SwapChain : public SwapChainBase { class SwapChain : public SwapChainBase {
public: public:
SwapChain(SwapChainBuilder* builder); SwapChain(Device* device, const SwapChainDescriptor* descriptor);
~SwapChain(); ~SwapChain();
protected: protected:

View File

@ -41,7 +41,6 @@ namespace dawn_native { namespace metal {
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor( RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override; RenderPassDescriptorBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
Serial GetCompletedCommandSerial() const final override; Serial GetCompletedCommandSerial() const final override;
Serial GetLastSubmittedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override;
@ -79,6 +78,8 @@ namespace dawn_native { namespace metal {
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override; const ShaderModuleDescriptor* descriptor) override;
ResultOrError<SwapChainBase*> CreateSwapChainImpl(
const SwapChainDescriptor* descriptor) override;
ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override; ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override;
ResultOrError<TextureViewBase*> CreateTextureViewImpl( ResultOrError<TextureViewBase*> CreateTextureViewImpl(
TextureBase* texture, TextureBase* texture,

View File

@ -110,8 +110,9 @@ namespace dawn_native { namespace metal {
const ShaderModuleDescriptor* descriptor) { const ShaderModuleDescriptor* descriptor) {
return new ShaderModule(this, descriptor); return new ShaderModule(this, descriptor);
} }
SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) { ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl(
return new SwapChain(builder); const SwapChainDescriptor* descriptor) {
return new SwapChain(this, descriptor);
} }
ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) { ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) {
return new Texture(this, descriptor); return new Texture(this, descriptor);

View File

@ -23,7 +23,7 @@ namespace dawn_native { namespace metal {
class SwapChain : public SwapChainBase { class SwapChain : public SwapChainBase {
public: public:
SwapChain(SwapChainBuilder* builder); SwapChain(Device* device, const SwapChainDescriptor* descriptor);
~SwapChain(); ~SwapChain();
protected: protected:

View File

@ -21,7 +21,8 @@
namespace dawn_native { namespace metal { namespace dawn_native { namespace metal {
SwapChain::SwapChain(SwapChainBuilder* builder) : SwapChainBase(builder) { SwapChain::SwapChain(Device* device, const SwapChainDescriptor* descriptor)
: SwapChainBase(device, descriptor) {
const auto& im = GetImplementation(); const auto& im = GetImplementation();
dawnWSIContextMetal wsiContext = {}; dawnWSIContextMetal wsiContext = {};
wsiContext.device = ToBackend(GetDevice())->GetMTLDevice(); wsiContext.device = ToBackend(GetDevice())->GetMTLDevice();

View File

@ -112,8 +112,9 @@ namespace dawn_native { namespace null {
return module; return module;
} }
SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) { ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl(
return new SwapChain(builder); const SwapChainDescriptor* descriptor) {
return new SwapChain(this, descriptor);
} }
ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) { ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) {
return new Texture(this, descriptor); return new Texture(this, descriptor);
@ -253,7 +254,8 @@ namespace dawn_native { namespace null {
// SwapChain // SwapChain
SwapChain::SwapChain(SwapChainBuilder* builder) : SwapChainBase(builder) { SwapChain::SwapChain(Device* device, const SwapChainDescriptor* descriptor)
: SwapChainBase(device, descriptor) {
const auto& im = GetImplementation(); const auto& im = GetImplementation();
im.Init(im.userData, nullptr); im.Init(im.userData, nullptr);
} }

View File

@ -94,7 +94,6 @@ namespace dawn_native { namespace null {
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor( RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override; RenderPassDescriptorBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
Serial GetCompletedCommandSerial() const final override; Serial GetCompletedCommandSerial() const final override;
Serial GetLastSubmittedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override;
@ -127,6 +126,8 @@ namespace dawn_native { namespace null {
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override; const ShaderModuleDescriptor* descriptor) override;
ResultOrError<SwapChainBase*> CreateSwapChainImpl(
const SwapChainDescriptor* descriptor) override;
ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override; ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override;
ResultOrError<TextureViewBase*> CreateTextureViewImpl( ResultOrError<TextureViewBase*> CreateTextureViewImpl(
TextureBase* texture, TextureBase* texture,
@ -176,7 +177,7 @@ namespace dawn_native { namespace null {
class SwapChain : public SwapChainBase { class SwapChain : public SwapChainBase {
public: public:
SwapChain(SwapChainBuilder* builder); SwapChain(Device* device, const SwapChainDescriptor* descriptor);
~SwapChain(); ~SwapChain();
protected: protected:

View File

@ -90,8 +90,9 @@ namespace dawn_native { namespace opengl {
const ShaderModuleDescriptor* descriptor) { const ShaderModuleDescriptor* descriptor) {
return new ShaderModule(this, descriptor); return new ShaderModule(this, descriptor);
} }
SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) { ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl(
return new SwapChain(builder); const SwapChainDescriptor* descriptor) {
return new SwapChain(this, descriptor);
} }
ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) { ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) {
return new Texture(this, descriptor); return new Texture(this, descriptor);

View File

@ -44,7 +44,6 @@ namespace dawn_native { namespace opengl {
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor( RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override; RenderPassDescriptorBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
Serial GetCompletedCommandSerial() const final override; Serial GetCompletedCommandSerial() const final override;
Serial GetLastSubmittedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override;
@ -74,6 +73,8 @@ namespace dawn_native { namespace opengl {
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override; const ShaderModuleDescriptor* descriptor) override;
ResultOrError<SwapChainBase*> CreateSwapChainImpl(
const SwapChainDescriptor* descriptor) override;
ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override; ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override;
ResultOrError<TextureViewBase*> CreateTextureViewImpl( ResultOrError<TextureViewBase*> CreateTextureViewImpl(
TextureBase* texture, TextureBase* texture,

View File

@ -14,7 +14,7 @@
#include "dawn_native/opengl/SwapChainGL.h" #include "dawn_native/opengl/SwapChainGL.h"
#include "dawn_native/Device.h" #include "dawn_native/opengl/DeviceGL.h"
#include "dawn_native/opengl/Forward.h" #include "dawn_native/opengl/Forward.h"
#include "dawn_native/opengl/TextureGL.h" #include "dawn_native/opengl/TextureGL.h"
@ -22,7 +22,8 @@
namespace dawn_native { namespace opengl { namespace dawn_native { namespace opengl {
SwapChain::SwapChain(SwapChainBuilder* builder) : SwapChainBase(builder) { SwapChain::SwapChain(Device* device, const SwapChainDescriptor* descriptor)
: SwapChainBase(device, descriptor) {
const auto& im = GetImplementation(); const auto& im = GetImplementation();
im.Init(im.userData, nullptr); im.Init(im.userData, nullptr);
} }

View File

@ -25,7 +25,7 @@ namespace dawn_native { namespace opengl {
class SwapChain : public SwapChainBase { class SwapChain : public SwapChainBase {
public: public:
SwapChain(SwapChainBuilder* builder); SwapChain(Device* device, const SwapChainDescriptor* descriptor);
~SwapChain(); ~SwapChain();
protected: protected:

View File

@ -179,13 +179,13 @@ namespace dawn_native { namespace vulkan {
const ShaderModuleDescriptor* descriptor) { const ShaderModuleDescriptor* descriptor) {
return new ShaderModule(this, descriptor); return new ShaderModule(this, descriptor);
} }
SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) { ResultOrError<SwapChainBase*> Device::CreateSwapChainImpl(
return new SwapChain(builder); const SwapChainDescriptor* descriptor) {
return new SwapChain(this, descriptor);
} }
ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) { ResultOrError<TextureBase*> Device::CreateTextureImpl(const TextureDescriptor* descriptor) {
return new Texture(this, descriptor); return new Texture(this, descriptor);
} }
ResultOrError<TextureViewBase*> Device::CreateTextureViewImpl( ResultOrError<TextureViewBase*> Device::CreateTextureViewImpl(
TextureBase* texture, TextureBase* texture,
const TextureViewDescriptor* descriptor) { const TextureViewDescriptor* descriptor) {

View File

@ -68,7 +68,6 @@ namespace dawn_native { namespace vulkan {
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor( RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override; RenderPassDescriptorBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
Serial GetCompletedCommandSerial() const final override; Serial GetCompletedCommandSerial() const final override;
Serial GetLastSubmittedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override;
@ -99,6 +98,8 @@ namespace dawn_native { namespace vulkan {
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override; const ShaderModuleDescriptor* descriptor) override;
ResultOrError<SwapChainBase*> CreateSwapChainImpl(
const SwapChainDescriptor* descriptor) override;
ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override; ResultOrError<TextureBase*> CreateTextureImpl(const TextureDescriptor* descriptor) override;
ResultOrError<TextureViewBase*> CreateTextureViewImpl( ResultOrError<TextureViewBase*> CreateTextureViewImpl(
TextureBase* texture, TextureBase* texture,

View File

@ -19,7 +19,8 @@
namespace dawn_native { namespace vulkan { namespace dawn_native { namespace vulkan {
SwapChain::SwapChain(SwapChainBuilder* builder) : SwapChainBase(builder) { SwapChain::SwapChain(Device* device, const SwapChainDescriptor* descriptor)
: SwapChainBase(device, descriptor) {
const auto& im = GetImplementation(); const auto& im = GetImplementation();
dawnWSIContextVulkan wsiContext = {}; dawnWSIContextVulkan wsiContext = {};
im.Init(im.userData, &wsiContext); im.Init(im.userData, &wsiContext);

View File

@ -21,9 +21,11 @@
namespace dawn_native { namespace vulkan { namespace dawn_native { namespace vulkan {
class Device;
class SwapChain : public SwapChainBase { class SwapChain : public SwapChainBase {
public: public:
SwapChain(SwapChainBuilder* builder); SwapChain(Device* device, const SwapChainDescriptor* descriptor);
~SwapChain(); ~SwapChain();
protected: protected:

View File

@ -35,14 +35,26 @@ class DevNull : public dawn_wire::CommandSerializer {
std::vector<char> buf; std::vector<char> buf;
}; };
void SkipSwapChainBuilderSetImplementation(dawnSwapChainBuilder builder, uint64_t) { static dawnProcDeviceCreateSwapChain originalDeviceCreateSwapChain = nullptr;
dawnSwapChain ErrorDeviceCreateSwapChain(dawnDevice device, const dawnSwapChainDescriptor*) {
dawnSwapChainDescriptor desc;
desc.nextInChain = nullptr;
// A 0 implementation will trigger a swapchain creation error.
desc.implementation = 0;
return originalDeviceCreateSwapChain(device, &desc);
} }
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
dawnProcTable procs = dawn_native::GetProcs(); dawnProcTable procs = dawn_native::GetProcs();
// SwapChainSetImplementation receives a pointer, skip calls to it as they would be intercepted
// in embedders or dawn_wire too. // Swapchains receive a pointer to an implementation. The fuzzer will pass garbage in so we
procs.swapChainBuilderSetImplementation = SkipSwapChainBuilderSetImplementation; // intercept calls to create swapchains and make sure they always return error swapchains.
// This is ok for fuzzing because embedders of dawn_wire would always define their own
// swapchain handling.
originalDeviceCreateSwapChain = procs.deviceCreateSwapChain;
procs.deviceCreateSwapChain = ErrorDeviceCreateSwapChain;
dawnSetProcs(&procs); dawnSetProcs(&procs);
// Create an instance and find the null adapter to create a device with. // Create an instance and find the null adapter to create a device with.

View File

@ -235,9 +235,9 @@ void DawnTest::SetUp() {
// The swapchain isn't used by tests but is useful when debugging with graphics debuggers that // The swapchain isn't used by tests but is useful when debugging with graphics debuggers that
// capture at frame boundaries. // capture at frame boundaries.
swapchain = device.CreateSwapChainBuilder() dawn::SwapChainDescriptor swapChainDesc;
.SetImplementation(mBinding->GetSwapChainImplementation()) swapChainDesc.implementation = mBinding->GetSwapChainImplementation();
.GetResult(); swapchain = device.CreateSwapChain(&swapChainDesc);
swapchain.Configure( swapchain.Configure(
static_cast<dawn::TextureFormat>(mBinding->GetPreferredSwapChainTextureFormat()), static_cast<dawn::TextureFormat>(mBinding->GetPreferredSwapChainTextureFormat()),
dawn::TextureUsageBit::OutputAttachment, 400, 400); dawn::TextureUsageBit::OutputAttachment, 400, 400);