Austin Eng 02fbf168e0 Add validation, storage, and querying of limits
Adds a way to store the limits on the Adapter and the
Device. For now, adapter limits are always the default
limits, and device limits are stored but not used.

This CL also adds usage of an ErrorObjectIdResolver and
Provider in the WGPUDeviceProperties serialization and
deserialization helpers. Serializing/deserializing this
struct should never have objects.

Bug: dawn:685
Change-Id: I1479b4407b0f9ec9f9b2bff62cad7caa693c99d7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/63983
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
2021-09-13 18:49:09 +00:00

235 lines
7.8 KiB
C++

//* Copyright 2017 The Dawn Authors
//*
//* Licensed under the Apache License, Version 2.0 (the "License");
//* you may not use this file except in compliance with the License.
//* You may obtain a copy of the License at
//*
//* http://www.apache.org/licenses/LICENSE-2.0
//*
//* Unless required by applicable law or agreed to in writing, software
//* distributed under the License is distributed on an "AS IS" BASIS,
//* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//* See the License for the specific language governing permissions and
//* limitations under the License.
#ifndef WEBGPU_CPP_H_
#define WEBGPU_CPP_H_
#include "dawn/webgpu.h"
#include "dawn/EnumClassBitmasks.h"
namespace wgpu {
static constexpr uint64_t kWholeSize = WGPU_WHOLE_SIZE;
// TODO(crbug.com/520): Remove kStrideUndefined in favor of kCopyStrideUndefined.
static constexpr uint32_t kStrideUndefined = WGPU_STRIDE_UNDEFINED;
static constexpr uint32_t kCopyStrideUndefined = WGPU_COPY_STRIDE_UNDEFINED;
static constexpr uint32_t kLimitU32Undefined = WGPU_LIMIT_U32_UNDEFINED;
static constexpr uint64_t kLimitU64Undefined = WGPU_LIMIT_U64_UNDEFINED;
{% for type in by_category["enum"] %}
enum class {{as_cppType(type.name)}} : uint32_t {
{% for value in type.values %}
{{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}},
{% endfor %}
};
{% endfor %}
{% for type in by_category["bitmask"] %}
enum class {{as_cppType(type.name)}} : uint32_t {
{% for value in type.values %}
{{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}},
{% endfor %}
};
{% endfor %}
{% for type in by_category["bitmask"] %}
template<>
struct IsDawnBitmask<{{as_cppType(type.name)}}> {
static constexpr bool enable = true;
};
{% endfor %}
using Proc = WGPUProc;
{% for type in by_category["callback"] %}
using {{as_cppType(type.name)}} = {{as_cType(type.name)}};
{% endfor %}
{% for type in by_category["object"] %}
class {{as_cppType(type.name)}};
{% endfor %}
{% for type in by_category["structure"] %}
struct {{as_cppType(type.name)}};
{% endfor %}
{% for typeDef in by_category["typedef"] %}
// {{as_cppType(typeDef.name)}} is deprecated.
// Use {{as_cppType(typeDef.type.name)}} instead.
using {{as_cppType(typeDef.name)}} = {{as_cppType(typeDef.type.name)}};
{% endfor %}
template<typename Derived, typename CType>
class ObjectBase {
public:
ObjectBase() = default;
ObjectBase(CType handle): mHandle(handle) {
if (mHandle) Derived::WGPUReference(mHandle);
}
~ObjectBase() {
if (mHandle) Derived::WGPURelease(mHandle);
}
ObjectBase(ObjectBase const& other)
: ObjectBase(other.Get()) {
}
Derived& operator=(ObjectBase const& other) {
if (&other != this) {
if (mHandle) Derived::WGPURelease(mHandle);
mHandle = other.mHandle;
if (mHandle) Derived::WGPUReference(mHandle);
}
return static_cast<Derived&>(*this);
}
ObjectBase(ObjectBase&& other) {
mHandle = other.mHandle;
other.mHandle = 0;
}
Derived& operator=(ObjectBase&& other) {
if (&other != this) {
if (mHandle) Derived::WGPURelease(mHandle);
mHandle = other.mHandle;
other.mHandle = 0;
}
return static_cast<Derived&>(*this);
}
ObjectBase(std::nullptr_t) {}
Derived& operator=(std::nullptr_t) {
if (mHandle != nullptr) {
Derived::WGPURelease(mHandle);
mHandle = nullptr;
}
return static_cast<Derived&>(*this);
}
bool operator==(std::nullptr_t) const {
return mHandle == nullptr;
}
bool operator!=(std::nullptr_t) const {
return mHandle != nullptr;
}
explicit operator bool() const {
return mHandle != nullptr;
}
CType Get() const {
return mHandle;
}
CType Release() {
CType result = mHandle;
mHandle = 0;
return result;
}
static Derived Acquire(CType handle) {
Derived result;
result.mHandle = handle;
return result;
}
protected:
CType mHandle = nullptr;
};
{% macro render_cpp_default_value(member, is_struct=True) -%}
{%- if member.annotation in ["*", "const*", "const*const*"] and member.optional -%}
{{" "}}= nullptr
{%- elif member.type.category == "object" and member.optional and is_struct -%}
{{" "}}= nullptr
{%- elif member.type.category in ["enum", "bitmask"] and member.default_value != None -%}
{{" "}}= {{as_cppType(member.type.name)}}::{{as_cppEnum(Name(member.default_value))}}
{%- elif member.type.category == "native" and member.default_value != None -%}
{{" "}}= {{member.default_value}}
{%- else -%}
{{assert(member.default_value == None)}}
{%- endif -%}
{%- endmacro %}
{% macro render_cpp_method_declaration(type, method) %}
{% set CppType = as_cppType(type.name) %}
{{as_cppType(method.return_type.name)}} {{method.name.CamelCase()}}(
{%- for arg in method.arguments -%}
{%- if not loop.first %}, {% endif -%}
{%- if arg.type.category == "object" and arg.annotation == "value" -%}
{{as_cppType(arg.type.name)}} const& {{as_varName(arg.name)}}
{%- else -%}
{{as_annotated_cppType(arg)}}
{%- endif -%}
{{render_cpp_default_value(arg, False)}}
{%- endfor -%}
) const
{%- endmacro %}
{% for type in by_category["object"] %}
{% set CppType = as_cppType(type.name) %}
{% set CType = as_cType(type.name) %}
class {{CppType}} : public ObjectBase<{{CppType}}, {{CType}}> {
public:
using ObjectBase::ObjectBase;
using ObjectBase::operator=;
{% for method in type.methods %}
{{render_cpp_method_declaration(type, method)}};
{% endfor %}
private:
friend ObjectBase<{{CppType}}, {{CType}}>;
static void WGPUReference({{CType}} handle);
static void WGPURelease({{CType}} handle);
};
{% endfor %}
Instance CreateInstance(InstanceDescriptor const * descriptor = nullptr);
Proc GetProcAddress(Device const& device, const char* procName);
struct ChainedStruct {
ChainedStruct const * nextInChain = nullptr;
SType sType = SType::Invalid;
};
{% for type in by_category["structure"] %}
{% if type.chained %}
struct {{as_cppType(type.name)}} : ChainedStruct {
{{as_cppType(type.name)}}() {
sType = SType::{{type.name.CamelCase()}};
}
{% else %}
struct {{as_cppType(type.name)}} {
{% endif %}
{% if type.extensible %}
ChainedStruct const * nextInChain = nullptr;
{% endif %}
{% for member in type.members %}
{% set member_declaration = as_annotated_cppType(member) + render_cpp_default_value(member) %}
{% if type.chained and loop.first %}
//* Align the first member to ChainedStruct to match the C struct layout.
alignas(ChainedStruct) {{member_declaration}};
{% else %}
{{member_declaration}};
{% endif %}
{% endfor %}
};
{% endfor %}
} // namespace wgpu
#endif // WEBGPU_CPP_H_