From 52f2383bb85b1682c9041b8e19f78a79621316d9 Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Mon, 16 Jul 2018 17:40:08 +0200 Subject: [PATCH] DeviceBase: Add helper to consume errors This adds DeviceBase::ConsumedError which is a helper method intended to be the main place where Error.h errors are consumed. To test this mechanism, object creation using descriptors is changed to use ConsumedError, which finally gets their validation errors go somewhere. This mechanism isn't final though because we have yet to implement WebGPU error handling. --- src/backend/BindGroupLayout.cpp | 2 +- src/backend/Device.cpp | 98 ++++++++++++++++++++------------- src/backend/Device.h | 18 ++++++ 3 files changed, 78 insertions(+), 40 deletions(-) diff --git a/src/backend/BindGroupLayout.cpp b/src/backend/BindGroupLayout.cpp index a7df5dc270..fef29bb7fc 100644 --- a/src/backend/BindGroupLayout.cpp +++ b/src/backend/BindGroupLayout.cpp @@ -88,7 +88,7 @@ namespace backend { } BindGroupLayoutBase::~BindGroupLayoutBase() { - // Do not register the actual cached object if we are a blueprint + // Do not uncache the actual cached object if we are a blueprint if (!mIsBlueprint) { mDevice->UncacheBindGroupLayout(this); } diff --git a/src/backend/Device.cpp b/src/backend/Device.cpp index e81c38e289..5a01c4e4a7 100644 --- a/src/backend/Device.cpp +++ b/src/backend/Device.cpp @@ -93,25 +93,20 @@ namespace backend { mCaches->bindGroupLayouts.erase(obj); } + // Object creation API methods + BindGroupBuilder* DeviceBase::CreateBindGroupBuilder() { return new BindGroupBuilder(this); } BindGroupLayoutBase* DeviceBase::CreateBindGroupLayout( const nxt::BindGroupLayoutDescriptor* descriptor) { - MaybeError validation = ValidateBindGroupLayoutDescriptor(this, descriptor); - if (validation.IsError()) { - // TODO(cwallez@chromium.org): Implement the WebGPU error handling mechanism. - delete validation.AcquireError(); + BindGroupLayoutBase* result = nullptr; + + if (ConsumedError(CreateBindGroupLayoutInternal(&result, descriptor))) { return nullptr; } - auto maybeBindGroupLayout = GetOrCreateBindGroupLayout(descriptor); - if (maybeBindGroupLayout.IsError()) { - // TODO(cwallez@chromium.org): Implement the WebGPU error handling mechanism. - delete maybeBindGroupLayout.AcquireError(); - return nullptr; - } - return maybeBindGroupLayout.AcquireSuccess(); + return result; } BlendStateBuilder* DeviceBase::CreateBlendStateBuilder() { return new BlendStateBuilder(this); @@ -133,30 +128,22 @@ namespace backend { } PipelineLayoutBase* DeviceBase::CreatePipelineLayout( const nxt::PipelineLayoutDescriptor* descriptor) { - MaybeError validation = ValidatePipelineLayoutDescriptor(this, descriptor); - if (validation.IsError()) { - // TODO(cwallez@chromium.org): Implement the WebGPU error handling mechanism. - delete validation.AcquireError(); + PipelineLayoutBase* result = nullptr; + + if (ConsumedError(CreatePipelineLayoutInternal(&result, descriptor))) { return nullptr; } - ResultOrError maybePipelineLayout = - CreatePipelineLayoutImpl(descriptor); - if (maybePipelineLayout.IsError()) { - // TODO(cwallez@chromium.org): Implement the WebGPU error handling mechanism. - delete maybePipelineLayout.AcquireError(); - return nullptr; - } - return maybePipelineLayout.AcquireSuccess(); + return result; } QueueBase* DeviceBase::CreateQueue() { - ResultOrError maybeQueue = CreateQueueImpl(); - if (maybeQueue.IsError()) { - // TODO(cwallez@chromium.org): Implement the WebGPU error handling mechanism. - delete maybeQueue.AcquireError(); + QueueBase* result = nullptr; + + if (ConsumedError(CreateQueueInternal(&result))) { return nullptr; } - return maybeQueue.AcquireSuccess(); + + return result; } RenderPassDescriptorBuilder* DeviceBase::CreateRenderPassDescriptorBuilder() { return new RenderPassDescriptorBuilder(this); @@ -165,20 +152,13 @@ namespace backend { return new RenderPipelineBuilder(this); } SamplerBase* DeviceBase::CreateSampler(const nxt::SamplerDescriptor* descriptor) { - MaybeError validation = ValidateSamplerDescriptor(this, descriptor); - if (validation.IsError()) { - // TODO(cwallez@chromium.org): Implement the WebGPU error handling mechanism. - delete validation.AcquireError(); + SamplerBase* result = nullptr; + + if (ConsumedError(CreateSamplerInternal(&result, descriptor))) { return nullptr; } - ResultOrError maybeSampler = CreateSamplerImpl(descriptor); - if (maybeSampler.IsError()) { - // TODO(cwallez@chromium.org): Implement the WebGPU error handling mechanism. - delete maybeSampler.AcquireError(); - return nullptr; - } - return maybeSampler.AcquireSuccess(); + return result; } ShaderModuleBuilder* DeviceBase::CreateShaderModuleBuilder() { return new ShaderModuleBuilder(this); @@ -190,6 +170,8 @@ namespace backend { return new TextureBuilder(this); } + // Other Device API methods + void DeviceBase::Tick() { TickImpl(); } @@ -207,4 +189,42 @@ namespace backend { } } + // Implementation details of object creation + + MaybeError DeviceBase::CreateBindGroupLayoutInternal( + BindGroupLayoutBase** result, + const nxt::BindGroupLayoutDescriptor* descriptor) { + NXT_TRY(ValidateBindGroupLayoutDescriptor(this, descriptor)); + NXT_TRY_ASSIGN(*result, GetOrCreateBindGroupLayout(descriptor)); + return {}; + } + + MaybeError DeviceBase::CreatePipelineLayoutInternal( + PipelineLayoutBase** result, + const nxt::PipelineLayoutDescriptor* descriptor) { + NXT_TRY(ValidatePipelineLayoutDescriptor(this, descriptor)); + NXT_TRY_ASSIGN(*result, CreatePipelineLayoutImpl(descriptor)); + return {}; + } + + MaybeError DeviceBase::CreateQueueInternal(QueueBase** result) { + NXT_TRY_ASSIGN(*result, CreateQueueImpl()); + return {}; + } + + MaybeError DeviceBase::CreateSamplerInternal(SamplerBase** result, + const nxt::SamplerDescriptor* descriptor) { + NXT_TRY(ValidateSamplerDescriptor(this, descriptor)); + NXT_TRY_ASSIGN(*result, CreateSamplerImpl(descriptor)); + return {}; + } + + // Other implementation details + + void DeviceBase::ConsumeError(ErrorData* error) { + ASSERT(error != nullptr); + HandleError(error->GetMessage().c_str()); + delete error; + } + } // namespace backend diff --git a/src/backend/Device.h b/src/backend/Device.h index ec837505c2..bb1894ceb8 100644 --- a/src/backend/Device.h +++ b/src/backend/Device.h @@ -32,6 +32,14 @@ namespace backend { void HandleError(const char* message); + bool ConsumedError(MaybeError maybeError) { + if (NXT_UNLIKELY(maybeError.IsError())) { + ConsumeError(maybeError.AcquireError()); + return true; + } + return false; + } + // Used by autogenerated code, returns itself DeviceBase* GetDevice(); @@ -105,6 +113,16 @@ namespace backend { virtual ResultOrError CreateSamplerImpl( const nxt::SamplerDescriptor* descriptor) = 0; + MaybeError CreateBindGroupLayoutInternal(BindGroupLayoutBase** result, + const nxt::BindGroupLayoutDescriptor* descriptor); + MaybeError CreatePipelineLayoutInternal(PipelineLayoutBase** result, + const nxt::PipelineLayoutDescriptor* descriptor); + MaybeError CreateQueueInternal(QueueBase** result); + MaybeError CreateSamplerInternal(SamplerBase** result, + const nxt::SamplerDescriptor* descriptor); + + void ConsumeError(ErrorData* error); + // The object caches aren't exposed in the header as they would require a lot of // additional includes. struct Caches;