Use Error in Sampler and autogenerated validation functions

This commit is contained in:
Corentin Wallez 2018-05-28 14:26:40 -04:00 committed by Corentin Wallez
parent 1fda980fa6
commit 50e0986e0e
6 changed files with 40 additions and 17 deletions

View File

@ -17,6 +17,7 @@
#include "common/Assert.h" #include "common/Assert.h"
#include "backend/ErrorData.h"
#include "backend/ValidationUtils_autogen.h" #include "backend/ValidationUtils_autogen.h"
#include "backend/{{namespace}}/GeneratedCodeIncludes.h" #include "backend/{{namespace}}/GeneratedCodeIncludes.h"
@ -82,10 +83,15 @@ namespace {{namespace}} {
bool error = false; bool error = false;
{% for arg in method.arguments %} {% for arg in method.arguments %}
{% set cppType = as_cppType(arg.type.name) %} {% set cppType = as_cppType(arg.type.name) %}
{% set argName = as_varName(arg.name) %}
{% if arg.type.category in ["enum", "bitmask"] %} {% if arg.type.category in ["enum", "bitmask"] %}
if (!IsValid{{cppType}}(static_cast<nxt::{{cppType}}>({{as_varName(arg.name)}}))) error = true; MaybeError {{argName}}Valid = Validate{{cppType}}(static_cast<nxt::{{cppType}}>({{argName}}));
if ({{argName}}Valid.IsError()) {
delete {{argName}}Valid.AcquireError();
error = true;
}
{% else %} {% else %}
(void) {{as_varName(arg.name)}}; (void) {{argName}};
{% endif %} {% endif %}
if (error) { if (error) {
{% if type.is_builder %} {% if type.is_builder %}

View File

@ -17,22 +17,25 @@
namespace backend { namespace backend {
{% for type in by_category["enum"] %} {% for type in by_category["enum"] %}
bool IsValid{{type.name.CamelCase()}}(nxt::{{as_cppType(type.name)}} value) { MaybeError Validate{{type.name.CamelCase()}}(nxt::{{as_cppType(type.name)}} value) {
switch (value) { switch (value) {
{% for value in type.values %} {% for value in type.values %}
case nxt::{{as_cppType(type.name)}}::{{as_cppEnum(value.name)}}: case nxt::{{as_cppType(type.name)}}::{{as_cppEnum(value.name)}}:
return true; return {};
{% endfor %} {% endfor %}
default: default:
return false; NXT_RETURN_ERROR("Invalid value for {{as_cType(type.name)}}");
} }
} }
{% endfor %} {% endfor %}
{% for type in by_category["bitmask"] %} {% for type in by_category["bitmask"] %}
bool IsValid{{type.name.CamelCase()}}(nxt::{{as_cppType(type.name)}} value) { MaybeError Validate{{type.name.CamelCase()}}(nxt::{{as_cppType(type.name)}} value) {
return (value & static_cast<nxt::{{as_cppType(type.name)}}>(~{{type.full_mask}})) == 0; if ((value & static_cast<nxt::{{as_cppType(type.name)}}>(~{{type.full_mask}})) == 0) {
return {};
}
NXT_RETURN_ERROR("Invalid value for {{as_cType(type.name)}}");
} }
{% endfor %} {% endfor %}

View File

@ -17,11 +17,13 @@
#include "nxt/nxtcpp.h" #include "nxt/nxtcpp.h"
#include "backend/Error.h"
namespace backend { namespace backend {
// Helper functions to check the value of enums and bitmasks // Helper functions to check the value of enums and bitmasks
{% for type in by_category["enum"] + by_category["bitmask"] %} {% for type in by_category["enum"] + by_category["bitmask"] %}
bool IsValid{{type.name.CamelCase()}}(nxt::{{as_cppType(type.name)}} value); MaybeError Validate{{type.name.CamelCase()}}(nxt::{{as_cppType(type.name)}} value);
{% endfor %} {% endfor %}
} // namespace backend } // namespace backend

View File

@ -21,6 +21,7 @@
#include "backend/CommandBuffer.h" #include "backend/CommandBuffer.h"
#include "backend/ComputePipeline.h" #include "backend/ComputePipeline.h"
#include "backend/DepthStencilState.h" #include "backend/DepthStencilState.h"
#include "backend/ErrorData.h"
#include "backend/InputState.h" #include "backend/InputState.h"
#include "backend/PipelineLayout.h" #include "backend/PipelineLayout.h"
#include "backend/Queue.h" #include "backend/Queue.h"
@ -131,9 +132,13 @@ namespace backend {
return new RenderPipelineBuilder(this); return new RenderPipelineBuilder(this);
} }
SamplerBase* DeviceBase::CreateSampler(const nxt::SamplerDescriptor* descriptor) { SamplerBase* DeviceBase::CreateSampler(const nxt::SamplerDescriptor* descriptor) {
if (!ValidateSamplerDescriptor(this, descriptor)) { MaybeError validation = ValidateSamplerDescriptor(this, descriptor);
if (validation.IsError()) {
// TODO(cwallez@chromium.org): Implement the WebGPU error handling mechanism.
delete validation.AcquireError();
return nullptr; return nullptr;
} }
return CreateSamplerImpl(descriptor); return CreateSamplerImpl(descriptor);
} }
ShaderModuleBuilder* DeviceBase::CreateShaderModuleBuilder() { ShaderModuleBuilder* DeviceBase::CreateShaderModuleBuilder() {

View File

@ -19,13 +19,18 @@
namespace backend { namespace backend {
bool ValidateSamplerDescriptor(DeviceBase*, const nxt::SamplerDescriptor* descriptor) { MaybeError ValidateSamplerDescriptor(DeviceBase*, const nxt::SamplerDescriptor* descriptor) {
return descriptor->nextInChain == nullptr && IsValidFilterMode(descriptor->magFilter) && NXT_TRY(ValidateFilterMode(descriptor->minFilter));
IsValidFilterMode(descriptor->minFilter) && NXT_TRY(ValidateFilterMode(descriptor->magFilter));
IsValidFilterMode(descriptor->mipmapFilter) && NXT_TRY(ValidateFilterMode(descriptor->mipmapFilter));
IsValidAddressMode(descriptor->addressModeU) && NXT_TRY(ValidateAddressMode(descriptor->addressModeU));
IsValidAddressMode(descriptor->addressModeV) && NXT_TRY(ValidateAddressMode(descriptor->addressModeV));
IsValidAddressMode(descriptor->addressModeW); NXT_TRY(ValidateAddressMode(descriptor->addressModeW));
if (descriptor->nextInChain != nullptr) {
NXT_RETURN_ERROR("nextInChain must be nullptr");
}
return {};
} }
// SamplerBase // SamplerBase

View File

@ -15,6 +15,7 @@
#ifndef BACKEND_SAMPLER_H_ #ifndef BACKEND_SAMPLER_H_
#define BACKEND_SAMPLER_H_ #define BACKEND_SAMPLER_H_
#include "backend/Error.h"
#include "backend/RefCounted.h" #include "backend/RefCounted.h"
#include "nxt/nxtcpp.h" #include "nxt/nxtcpp.h"
@ -23,7 +24,8 @@ namespace backend {
class DeviceBase; class DeviceBase;
bool ValidateSamplerDescriptor(DeviceBase* device, const nxt::SamplerDescriptor* descriptor); MaybeError ValidateSamplerDescriptor(DeviceBase* device,
const nxt::SamplerDescriptor* descriptor);
class SamplerBase : public RefCounted { class SamplerBase : public RefCounted {
public: public: