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.
This commit is contained in:
Corentin Wallez 2018-07-16 17:40:08 +02:00 committed by Corentin Wallez
parent 629c11baad
commit 52f2383bb8
3 changed files with 78 additions and 40 deletions

View File

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

View File

@ -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<PipelineLayoutBase*> 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<QueueBase*> 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<SamplerBase*> 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

View File

@ -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<SamplerBase*> 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;