Implement upstream RequestDevice, add native-only CreateDevice
This CL implements RequestDevice and also has changes for
Dawn to internally use wgpu::FeatureName enums, instead of
strings. Some of the string handling is kept for now to
support the deprecated creation path. GetFeatureInfo is added
to the instance to get a name and description of the feature,
for reporting in about://gpu.
Dawn device toggles are now passed in an extension struct off
of the device descriptor. This is only supported in dawn_native,
and not dawn_wire, for now, since dawn_wire doesn't have a way
to serialize lists of null-terminated const char*.
To enable the client to check whether the toggle descriptor is
supported, a `dawn-native` feature is added which is supported
all the time with dawn_native, but not supported with dawn_wire.
Feature `dawn-native` also enables a synchronous version of
CreateDevice for convenience.
Bug: dawn:160
Change-Id: Ifc195e7ea808c6c319021528ef4b36bd65583bff
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/72020
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/dawn.json b/dawn.json
index a575dcb..6e9882b 100644
--- a/dawn.json
+++ b/dawn.json
@@ -113,6 +113,14 @@
{"name": "callback", "type": "request device callback"},
{"name": "userdata", "type": "void", "annotation": "*"}
]
+ },
+ {
+ "name": "create device",
+ "tags": ["dawn"],
+ "returns": "device",
+ "args": [
+ {"name": "descriptor", "type": "device descriptor", "annotation": "const*", "optional": "true"}
+ ]
}
]
},
@@ -148,6 +156,17 @@
{"name": "required limits", "type": "required limits", "annotation": "const*", "optional": true}
]
},
+ "dawn toggles device descriptor": {
+ "tags": ["dawn", "native"],
+ "category": "structure",
+ "chained": "in",
+ "members": [
+ {"name": "force enabled toggles count", "type": "uint32_t", "default": 0},
+ {"name": "force enabled toggles", "type": "char", "annotation": "const*const*", "length": "force enabled toggles count"},
+ {"name": "force disabled toggles count", "type": "uint32_t", "default": 0},
+ {"name": "force disabled toggles", "type": "char", "annotation": "const*const*", "length": "force disabled toggles count"}
+ ]
+ },
"address mode": {
"category": "enum",
"values": [
@@ -1164,6 +1183,7 @@
{"name": "depth32 float stencil8", "type": "bool", "default": "false"},
{"name": "invalid feature", "type": "bool", "default": "false"},
{"name": "dawn internal usages", "type": "bool", "default": "false"},
+ {"name": "dawn native", "type": "bool", "default": "false"},
{"name": "limits", "type": "supported limits"}
]
},
@@ -1313,7 +1333,8 @@
{"value": 1000, "name": "depth clamping", "tags": ["emscripten", "dawn"]},
{"value": 1001, "name": "dawn shader float 16", "tags": ["dawn"]},
{"value": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
- {"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]}
+ {"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
+ {"value": 1004, "name": "dawn native", "tags": ["dawn", "native"]}
]
},
"filter mode": {
@@ -2347,7 +2368,8 @@
{"value": 10, "name": "external texture binding layout", "tags": ["dawn"]},
{"value": 11, "name": "surface descriptor from windows swap chain panel", "tags": ["dawn"]},
{"value": 1000, "name": "dawn texture internal usage descriptor", "tags": ["dawn"]},
- {"value": 1001, "name": "primitive depth clamping state", "tags": ["dawn", "emscripten"]}
+ {"value": 1001, "name": "primitive depth clamping state", "tags": ["dawn", "emscripten"]},
+ {"value": 1002, "name": "dawn toggles device descriptor", "tags": ["dawn", "native"]}
]
},
"texture": {
diff --git a/dawn_wire.json b/dawn_wire.json
index 497a0eb..869f74b 100644
--- a/dawn_wire.json
+++ b/dawn_wire.json
@@ -179,6 +179,7 @@
"SurfaceDescriptorFromWindowsSwapChainPanel"
],
"client_side_commands": [
+ "AdapterCreateDevice",
"AdapterGetProperties",
"AdapterGetLimits",
"AdapterHasFeature",
diff --git a/docs/features/dawn_native.md b/docs/features/dawn_native.md
new file mode 100644
index 0000000..c1e212d
--- /dev/null
+++ b/docs/features/dawn_native.md
@@ -0,0 +1,13 @@
+# Dawn Native
+
+The `dawn-native` feature enables additional functionality that is supported only
+when the WebGPU implementation is `dawn_native`.
+
+Additional functionality:
+ - `wgpu::DawnTogglesDeviceDescriptor` may be chained on `wgpu::DeviceDescriptor` on device creation to enable Dawn-specific toggles on the device.
+
+ - Synchronous `adapter.CreateDevice(const wgpu::DeviceDescriptor*)` may be called.
+
+Notes:
+ - Enabling this feature in the `wgpu::DeviceDescriptor` does nothing, but
+its presence in the Adapter's set of supported features means that the additional functionality is supported.
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index 5c17d77..fa8a1ee 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -405,8 +405,10 @@
return result
-def parse_json(json, enabled_tags):
- is_enabled = lambda json_data: item_is_enabled(enabled_tags, json_data)
+def parse_json(json, enabled_tags, disabled_tags=None):
+ is_enabled = lambda json_data: item_is_enabled(
+ enabled_tags, json_data) and not item_is_disabled(
+ disabled_tags, json_data)
category_to_parser = {
'bitmask': BitmaskType,
'enum': EnumType,
@@ -426,7 +428,7 @@
by_category[name] = []
for (name, json_data) in json.items():
- if name[0] == '_' or not item_is_enabled(enabled_tags, json_data):
+ if name[0] == '_' or not is_enabled(json_data):
continue
category = json_data['category']
parsed = category_to_parser[category](is_enabled, name, json_data)
@@ -464,12 +466,14 @@
'types': types,
'by_category': by_category,
'enabled_tags': enabled_tags,
+ 'disabled_tags': disabled_tags,
}
return {
'metadata': Metadata(json['_metadata']),
'types': types,
'by_category': by_category,
'enabled_tags': enabled_tags,
+ 'disabled_tags': disabled_tags,
'c_methods': lambda typ: c_methods(api_params, typ),
'c_methods_sorted_by_name': get_c_methods_sorted_by_name(api_params),
}
@@ -617,6 +621,8 @@
return typ + ' * ' + name
elif arg.annotation == 'const*':
return typ + ' const * ' + name
+ elif arg.annotation == 'const*const*':
+ return 'const ' + typ + '* const * ' + name
else:
assert False
@@ -632,6 +638,14 @@
return any(tag in enabled_tags for tag in tags)
+def item_is_disabled(disabled_tags, json_data):
+ if disabled_tags is None: return False
+ tags = json_data.get('tags')
+ if tags is None: return False
+
+ return any(tag in disabled_tags for tag in tags)
+
+
def as_cppEnum(value_name):
assert not value_name.native
if value_name.concatcase()[0].isdigit():
@@ -672,6 +686,7 @@
Method(Name('release'), params['types']['void'], [],
{'tags': ['dawn', 'emscripten']}),
] if item_is_enabled(params['enabled_tags'], x.json_data)
+ and not item_is_disabled(params['disabled_tags'], x.json_data)
]
@@ -925,10 +940,14 @@
frontend_params))
if 'dawn_wire' in targets:
- additional_params = compute_wire_params(params_dawn, wire_json)
+ params_dawn_wire = parse_json(loaded_json,
+ enabled_tags=['dawn', 'deprecated'],
+ disabled_tags=['native'])
+ additional_params = compute_wire_params(params_dawn_wire,
+ wire_json)
wire_params = [
- RENDER_PARAMS_BASE, params_dawn, {
+ RENDER_PARAMS_BASE, params_dawn_wire, {
'as_wireType': lambda type : as_wireType(metadata, type),
'as_annotated_wireType': \
lambda arg: annotated(as_wireType(metadata, arg.type), arg),
diff --git a/generator/templates/dawn_wire/WireCmd.cpp b/generator/templates/dawn_wire/WireCmd.cpp
index 7bc148f..e473192 100644
--- a/generator/templates/dawn_wire/WireCmd.cpp
+++ b/generator/templates/dawn_wire/WireCmd.cpp
@@ -179,6 +179,7 @@
{% endif %}
{
{% if member.annotation != "value" %}
+ {{ assert(member.annotation != "const*const*") }}
auto memberLength = {{member_length(member, "record.")}};
result += memberLength * {{member_transfer_sizeof(member)}};
//* Structures might contain more pointers so we need to add their extra size as well.
@@ -258,6 +259,7 @@
//* Allocate space and write the non-value arguments in it.
{% for member in members if member.annotation != "value" and member.length != "strlen" and not member.skip_serialize %}
+ {{ assert(member.annotation != "const*const*") }}
{% set memberName = as_varName(member.name) %}
{% if member.type.category != "object" and member.optional %}
@@ -367,6 +369,7 @@
//* Get extra buffer data, and copy pointed to values in extra allocated space.
{% for member in members if member.annotation != "value" and member.length != "strlen" %}
+ {{ assert(member.annotation != "const*const*") }}
{% set memberName = as_varName(member.name) %}
{% if member.type.category != "object" and member.optional %}
diff --git a/src/dawn_native/Adapter.cpp b/src/dawn_native/Adapter.cpp
index 7ef85c1..a30c553 100644
--- a/src/dawn_native/Adapter.cpp
+++ b/src/dawn_native/Adapter.cpp
@@ -15,12 +15,15 @@
#include "dawn_native/Adapter.h"
#include "common/Constants.h"
+#include "dawn_native/Device.h"
#include "dawn_native/Instance.h"
+#include "dawn_native/ValidationUtils_autogen.h"
namespace dawn_native {
AdapterBase::AdapterBase(InstanceBase* instance, wgpu::BackendType backend)
: mInstance(instance), mBackend(backend) {
+ mSupportedFeatures.EnableFeature(Feature::DawnNative);
mSupportedFeatures.EnableFeature(Feature::DawnInternalUsages);
}
@@ -90,10 +93,36 @@
return mSupportedFeatures.EnumerateFeatures(features);
}
+ DeviceBase* AdapterBase::APICreateDevice(const DeviceDescriptor* descriptor) {
+ DeviceDescriptor defaultDesc = {};
+ if (descriptor == nullptr) {
+ descriptor = &defaultDesc;
+ }
+ auto result = CreateDeviceInternal(descriptor);
+ if (result.IsError()) {
+ mInstance->ConsumedError(result.AcquireError());
+ return nullptr;
+ }
+ return result.AcquireSuccess().Detach();
+ }
+
void AdapterBase::APIRequestDevice(const DeviceDescriptor* descriptor,
WGPURequestDeviceCallback callback,
void* userdata) {
- callback(WGPURequestDeviceStatus_Error, nullptr, "Not implemented", userdata);
+ auto result = CreateDeviceInternal(descriptor);
+
+ if (result.IsError()) {
+ std::unique_ptr<ErrorData> errorData = result.AcquireError();
+ callback(WGPURequestDeviceStatus_Error, nullptr,
+ errorData->GetFormattedMessage().c_str(), userdata);
+ return;
+ }
+
+ Ref<DeviceBase> device = result.AcquireSuccess();
+
+ WGPURequestDeviceStatus status =
+ device == nullptr ? WGPURequestDeviceStatus_Unknown : WGPURequestDeviceStatus_Success;
+ callback(status, ToAPI(device.Detach()), nullptr, userdata);
}
wgpu::BackendType AdapterBase::GetBackendType() const {
@@ -120,14 +149,10 @@
return mSupportedFeatures;
}
- bool AdapterBase::SupportsAllRequestedFeatures(
- const std::vector<const char*>& requestedFeatures) const {
- for (const char* featureStr : requestedFeatures) {
- Feature featureEnum = mInstance->FeatureNameToEnum(featureStr);
- if (featureEnum == Feature::InvalidEnum) {
- return false;
- }
- if (!mSupportedFeatures.IsEnabled(featureEnum)) {
+ bool AdapterBase::SupportsAllRequiredFeatures(
+ const ityp::span<size_t, const wgpu::FeatureName>& features) const {
+ for (wgpu::FeatureName f : features) {
+ if (!mSupportedFeatures.IsEnabled(f)) {
return false;
}
}
@@ -163,57 +188,27 @@
return true;
}
- DeviceBase* AdapterBase::CreateDevice(const DawnDeviceDescriptor* descriptor) {
- DeviceBase* result = nullptr;
+ ResultOrError<Ref<DeviceBase>> AdapterBase::CreateDeviceInternal(
+ const DeviceDescriptor* descriptor) {
+ ASSERT(descriptor != nullptr);
- if (mInstance->ConsumedError(CreateDeviceInternal(&result, descriptor))) {
- return nullptr;
+ for (uint32_t i = 0; i < descriptor->requiredFeaturesCount; ++i) {
+ wgpu::FeatureName f = descriptor->requiredFeatures[i];
+ DAWN_TRY(ValidateFeatureName(f));
+ DAWN_INVALID_IF(!mSupportedFeatures.IsEnabled(f),
+ "Requested feature %s is not supported.", f);
}
- return result;
- }
-
- void AdapterBase::RequestDevice(const DawnDeviceDescriptor* descriptor,
- WGPURequestDeviceCallback callback,
- void* userdata) {
- DeviceBase* device = nullptr;
- MaybeError err = CreateDeviceInternal(&device, descriptor);
-
- if (err.IsError()) {
- std::unique_ptr<ErrorData> errorData = err.AcquireError();
- callback(WGPURequestDeviceStatus_Error, ToAPI(device),
- errorData->GetFormattedMessage().c_str(), userdata);
- return;
- }
- WGPURequestDeviceStatus status =
- device == nullptr ? WGPURequestDeviceStatus_Unknown : WGPURequestDeviceStatus_Success;
- callback(status, ToAPI(device), nullptr, userdata);
- }
-
- MaybeError AdapterBase::CreateDeviceInternal(DeviceBase** result,
- const DawnDeviceDescriptor* descriptor) {
- if (descriptor != nullptr) {
- for (const char* featureStr : descriptor->requiredFeatures) {
- Feature featureEnum = mInstance->FeatureNameToEnum(featureStr);
- DAWN_INVALID_IF(featureEnum == Feature::InvalidEnum,
- "Requested feature %s is unknown.", featureStr);
- DAWN_INVALID_IF(!mSupportedFeatures.IsEnabled(featureEnum),
- "Requested feature %s is disabled.", featureStr);
- }
- }
-
- if (descriptor != nullptr && descriptor->requiredLimits != nullptr) {
+ if (descriptor->requiredLimits != nullptr) {
DAWN_TRY_CONTEXT(
ValidateLimits(mUseTieredLimits ? ApplyLimitTiers(mLimits.v1) : mLimits.v1,
- FromAPI(descriptor->requiredLimits)->limits),
+ descriptor->requiredLimits->limits),
"validating required limits");
DAWN_INVALID_IF(descriptor->requiredLimits->nextInChain != nullptr,
"nextInChain is not nullptr.");
}
-
- DAWN_TRY_ASSIGN(*result, CreateDeviceImpl(descriptor));
- return {};
+ return CreateDeviceImpl(descriptor);
}
void AdapterBase::SetUseTieredLimits(bool useTieredLimits) {
diff --git a/src/dawn_native/Adapter.h b/src/dawn_native/Adapter.h
index a8a5fdb..b8dc2d7 100644
--- a/src/dawn_native/Adapter.h
+++ b/src/dawn_native/Adapter.h
@@ -18,6 +18,7 @@
#include "dawn_native/DawnNative.h"
#include "common/RefCounted.h"
+#include "common/ityp_span.h"
#include "dawn_native/Error.h"
#include "dawn_native/Features.h"
#include "dawn_native/Limits.h"
@@ -44,6 +45,7 @@
void APIRequestDevice(const DeviceDescriptor* descriptor,
WGPURequestDeviceCallback callback,
void* userdata);
+ DeviceBase* APICreateDevice(const DeviceDescriptor* descriptor = nullptr);
wgpu::BackendType GetBackendType() const;
wgpu::AdapterType GetAdapterType() const;
@@ -51,16 +53,11 @@
const PCIInfo& GetPCIInfo() const;
InstanceBase* GetInstance() const;
- DeviceBase* CreateDevice(const DawnDeviceDescriptor* descriptor = nullptr);
-
- void RequestDevice(const DawnDeviceDescriptor* descriptor,
- WGPURequestDeviceCallback callback,
- void* userdata);
-
void ResetInternalDeviceForTesting();
FeaturesSet GetSupportedFeatures() const;
- bool SupportsAllRequestedFeatures(const std::vector<const char*>& requestedFeatures) const;
+ bool SupportsAllRequiredFeatures(
+ const ityp::span<size_t, const wgpu::FeatureName>& features) const;
WGPUDeviceProperties GetAdapterProperties() const;
bool GetLimits(SupportedLimits* limits) const;
@@ -76,8 +73,8 @@
FeaturesSet mSupportedFeatures;
private:
- virtual ResultOrError<DeviceBase*> CreateDeviceImpl(
- const DawnDeviceDescriptor* descriptor) = 0;
+ virtual ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
+ const DeviceDescriptor* descriptor) = 0;
virtual MaybeError InitializeImpl() = 0;
@@ -87,8 +84,7 @@
// Check base WebGPU limits and populate supported limits.
virtual MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) = 0;
- MaybeError CreateDeviceInternal(DeviceBase** result,
- const DawnDeviceDescriptor* descriptor);
+ ResultOrError<Ref<DeviceBase>> CreateDeviceInternal(const DeviceDescriptor* descriptor);
virtual MaybeError ResetInternalDeviceForTestingImpl();
InstanceBase* mInstance = nullptr;
diff --git a/src/dawn_native/DawnNative.cpp b/src/dawn_native/DawnNative.cpp
index c10fe00..86a6bb4 100644
--- a/src/dawn_native/DawnNative.cpp
+++ b/src/dawn_native/DawnNative.cpp
@@ -14,6 +14,7 @@
#include "dawn_native/DawnNative.h"
+#include "common/Log.h"
#include "dawn_native/BindGroupLayout.h"
#include "dawn_native/Buffer.h"
#include "dawn_native/Device.h"
@@ -25,6 +26,41 @@
namespace dawn_native {
+ namespace {
+ struct ComboDeprecatedDawnDeviceDescriptor : DeviceDescriptor {
+ ComboDeprecatedDawnDeviceDescriptor(const DawnDeviceDescriptor* deviceDescriptor) {
+ dawn::WarningLog() << "DawnDeviceDescriptor is deprecated. Please use "
+ "WGPUDeviceDescriptor instead.";
+
+ DeviceDescriptor* desc = this;
+
+ if (deviceDescriptor != nullptr) {
+ desc->nextInChain = &mTogglesDesc;
+ mTogglesDesc.forceEnabledToggles = deviceDescriptor->forceEnabledToggles.data();
+ mTogglesDesc.forceEnabledTogglesCount =
+ deviceDescriptor->forceEnabledToggles.size();
+ mTogglesDesc.forceDisabledToggles =
+ deviceDescriptor->forceDisabledToggles.data();
+ mTogglesDesc.forceDisabledTogglesCount =
+ deviceDescriptor->forceDisabledToggles.size();
+
+ desc->requiredLimits =
+ reinterpret_cast<const RequiredLimits*>(deviceDescriptor->requiredLimits);
+
+ FeaturesInfo featuresInfo;
+ for (const char* featureStr : deviceDescriptor->requiredFeatures) {
+ mRequiredFeatures.push_back(featuresInfo.FeatureNameToAPIEnum(featureStr));
+ }
+ desc->requiredFeatures = mRequiredFeatures.data();
+ desc->requiredFeaturesCount = mRequiredFeatures.size();
+ }
+ }
+
+ DawnTogglesDeviceDescriptor mTogglesDesc = {};
+ std::vector<wgpu::FeatureName> mRequiredFeatures = {};
+ };
+ } // namespace
+
const DawnProcTable& GetProcsAutogen();
const DawnProcTable& GetProcs() {
@@ -98,6 +134,10 @@
return mImpl->GetPCIInfo();
}
+ WGPUAdapter Adapter::Get() const {
+ return ToAPI(mImpl);
+ }
+
std::vector<const char*> Adapter::GetSupportedFeatures() const {
FeaturesSet supportedFeaturesSet = mImpl->GetSupportedFeatures();
return supportedFeaturesSet.GetEnabledFeatureNames();
@@ -124,13 +164,19 @@
}
WGPUDevice Adapter::CreateDevice(const DawnDeviceDescriptor* deviceDescriptor) {
- return ToAPI(mImpl->CreateDevice(deviceDescriptor));
+ ComboDeprecatedDawnDeviceDescriptor desc(deviceDescriptor);
+ return ToAPI(mImpl->APICreateDevice(&desc));
+ }
+
+ WGPUDevice Adapter::CreateDevice(const WGPUDeviceDescriptor* deviceDescriptor) {
+ return ToAPI(mImpl->APICreateDevice(FromAPI(deviceDescriptor)));
}
void Adapter::RequestDevice(const DawnDeviceDescriptor* descriptor,
WGPURequestDeviceCallback callback,
void* userdata) {
- mImpl->RequestDevice(descriptor, callback, userdata);
+ ComboDeprecatedDawnDeviceDescriptor desc(descriptor);
+ mImpl->APIRequestDevice(&desc, callback, userdata);
}
void Adapter::ResetInternalDeviceForTesting() {
@@ -176,6 +222,10 @@
return mImpl->GetToggleInfo(toggleName);
}
+ const FeatureInfo* Instance::GetFeatureInfo(WGPUFeatureName feature) {
+ return mImpl->GetFeatureInfo(static_cast<wgpu::FeatureName>(feature));
+ }
+
void Instance::EnableBackendValidation(bool enableBackendValidation) {
if (enableBackendValidation) {
mImpl->SetBackendValidationLevel(BackendValidationLevel::Full);
diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp
index 127b29f..90af4cf 100644
--- a/src/dawn_native/Device.cpp
+++ b/src/dawn_native/Device.cpp
@@ -21,6 +21,7 @@
#include "dawn_native/BindGroup.h"
#include "dawn_native/BindGroupLayout.h"
#include "dawn_native/Buffer.h"
+#include "dawn_native/ChainUtils_autogen.h"
#include "dawn_native/CommandBuffer.h"
#include "dawn_native/CommandEncoder.h"
#include "dawn_native/CompilationMessages.h"
@@ -172,15 +173,19 @@
// DeviceBase
- DeviceBase::DeviceBase(AdapterBase* adapter, const DawnDeviceDescriptor* descriptor)
+ DeviceBase::DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor)
: mInstance(adapter->GetInstance()), mAdapter(adapter), mNextPipelineCompatibilityToken(1) {
- if (descriptor != nullptr) {
- ApplyToggleOverrides(descriptor);
- ApplyFeatures(descriptor);
- }
+ ASSERT(descriptor != nullptr);
- if (descriptor != nullptr && descriptor->requiredLimits != nullptr) {
- mLimits.v1 = ReifyDefaultLimits(FromAPI(descriptor->requiredLimits)->limits);
+ const DawnTogglesDeviceDescriptor* togglesDesc = nullptr;
+ FindInChain(descriptor->nextInChain, &togglesDesc);
+ if (togglesDesc != nullptr) {
+ ApplyToggleOverrides(togglesDesc);
+ }
+ ApplyFeatures(descriptor);
+
+ if (descriptor->requiredLimits != nullptr) {
+ mLimits.v1 = ReifyDefaultLimits(descriptor->requiredLimits->limits);
} else {
GetDefaultLimits(&mLimits.v1);
}
@@ -1140,16 +1145,14 @@
return result.Detach();
}
- void DeviceBase::ApplyFeatures(const DawnDeviceDescriptor* deviceDescriptor) {
+ void DeviceBase::ApplyFeatures(const DeviceDescriptor* deviceDescriptor) {
ASSERT(deviceDescriptor);
- ASSERT(GetAdapter()->SupportsAllRequestedFeatures(deviceDescriptor->requiredFeatures));
+ ASSERT(GetAdapter()->SupportsAllRequiredFeatures(
+ {deviceDescriptor->requiredFeatures, deviceDescriptor->requiredFeaturesCount}));
- mEnabledFeatures = GetAdapter()->GetInstance()->FeatureNamesToFeaturesSet(
- deviceDescriptor->requiredFeatures);
- }
-
- std::vector<const char*> DeviceBase::GetEnabledFeatures() const {
- return mEnabledFeatures.GetEnabledFeatureNames();
+ for (uint32_t i = 0; i < deviceDescriptor->requiredFeaturesCount; ++i) {
+ mEnabledFeatures.EnableFeature(deviceDescriptor->requiredFeatures[i]);
+ }
}
bool DeviceBase::IsFeatureEnabled(Feature feature) const {
@@ -1600,18 +1603,20 @@
SetToggle(Toggle::DisallowUnsafeAPIs, true);
}
- void DeviceBase::ApplyToggleOverrides(const DawnDeviceDescriptor* deviceDescriptor) {
- ASSERT(deviceDescriptor);
+ void DeviceBase::ApplyToggleOverrides(const DawnTogglesDeviceDescriptor* togglesDescriptor) {
+ ASSERT(togglesDescriptor != nullptr);
- for (const char* toggleName : deviceDescriptor->forceEnabledToggles) {
- Toggle toggle = GetAdapter()->GetInstance()->ToggleNameToEnum(toggleName);
+ for (uint32_t i = 0; i < togglesDescriptor->forceEnabledTogglesCount; ++i) {
+ Toggle toggle = GetAdapter()->GetInstance()->ToggleNameToEnum(
+ togglesDescriptor->forceEnabledToggles[i]);
if (toggle != Toggle::InvalidEnum) {
mEnabledToggles.Set(toggle, true);
mOverridenToggles.Set(toggle, true);
}
}
- for (const char* toggleName : deviceDescriptor->forceDisabledToggles) {
- Toggle toggle = GetAdapter()->GetInstance()->ToggleNameToEnum(toggleName);
+ for (uint32_t i = 0; i < togglesDescriptor->forceDisabledTogglesCount; ++i) {
+ Toggle toggle = GetAdapter()->GetInstance()->ToggleNameToEnum(
+ togglesDescriptor->forceDisabledToggles[i]);
if (toggle != Toggle::InvalidEnum) {
mEnabledToggles.Set(toggle, false);
mOverridenToggles.Set(toggle, true);
diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h
index 298d0b4..1925478 100644
--- a/src/dawn_native/Device.h
+++ b/src/dawn_native/Device.h
@@ -56,7 +56,7 @@
class DeviceBase : public RefCounted {
public:
- DeviceBase(AdapterBase* adapter, const DawnDeviceDescriptor* descriptor);
+ DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor);
virtual ~DeviceBase();
void HandleError(InternalErrorType type, const char* message);
@@ -312,7 +312,6 @@
void TrackObject(ApiObjectBase* object);
std::mutex* GetObjectListMutex(ObjectType type);
- std::vector<const char*> GetEnabledFeatures() const;
std::vector<const char*> GetTogglesUsed() const;
bool IsFeatureEnabled(Feature feature) const;
bool IsToggleEnabled(Toggle toggle) const;
@@ -442,8 +441,8 @@
WGPUCreateRenderPipelineAsyncCallback callback,
void* userdata);
- void ApplyToggleOverrides(const DawnDeviceDescriptor* deviceDescriptor);
- void ApplyFeatures(const DawnDeviceDescriptor* deviceDescriptor);
+ void ApplyToggleOverrides(const DawnTogglesDeviceDescriptor* togglesDescriptor);
+ void ApplyFeatures(const DeviceDescriptor* deviceDescriptor);
void SetDefaultToggles();
diff --git a/src/dawn_native/Features.cpp b/src/dawn_native/Features.cpp
index 037d8f4..913706c 100644
--- a/src/dawn_native/Features.cpp
+++ b/src/dawn_native/Features.cpp
@@ -83,7 +83,12 @@
{"multiplanar-formats",
"Import and use multi-planar texture formats with per plane views",
"https://bugs.chromium.org/p/dawn/issues/detail?id=551"},
- &WGPUDeviceProperties::multiPlanarFormats}}};
+ &WGPUDeviceProperties::multiPlanarFormats},
+ {Feature::DawnNative,
+ {"dawn-native", "WebGPU is running on top of dawn_native.",
+ "https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/features/"
+ "dawn_native.md"},
+ &WGPUDeviceProperties::dawnNative}}};
Feature FromAPIFeature(wgpu::FeatureName feature) {
switch (feature) {
@@ -112,6 +117,8 @@
return Feature::DawnInternalUsages;
case wgpu::FeatureName::DawnMultiPlanarFormats:
return Feature::MultiPlanarFormats;
+ case wgpu::FeatureName::DawnNative:
+ return Feature::DawnNative;
case wgpu::FeatureName::IndirectFirstInstance:
return Feature::InvalidEnum;
@@ -143,6 +150,8 @@
return wgpu::FeatureName::DawnInternalUsages;
case Feature::MultiPlanarFormats:
return wgpu::FeatureName::DawnMultiPlanarFormats;
+ case Feature::DawnNative:
+ return wgpu::FeatureName::DawnNative;
case Feature::EnumCount:
UNREACHABLE();
@@ -157,6 +166,10 @@
featuresBitSet.set(featureIndex);
}
+ void FeaturesSet::EnableFeature(wgpu::FeatureName feature) {
+ EnableFeature(FromAPIFeature(feature));
+ }
+
bool FeaturesSet::IsEnabled(Feature feature) const {
ASSERT(feature != Feature::InvalidEnum);
const size_t featureIndex = static_cast<size_t>(feature);
@@ -184,8 +197,13 @@
uint32_t index = 0;
for (uint32_t i : IterateBitSet(featuresBitSet)) {
- const char* featureName = FeatureEnumToName(static_cast<Feature>(i));
- enabledFeatureNames[index] = featureName;
+ Feature feature = static_cast<Feature>(i);
+ ASSERT(feature != Feature::InvalidEnum);
+
+ const FeatureEnumAndInfo& featureNameAndInfo = kFeatureNameAndInfoList[i];
+ ASSERT(featureNameAndInfo.feature == feature);
+
+ enabledFeatureNames[index] = featureNameAndInfo.info.name;
++index;
}
return enabledFeatureNames;
@@ -199,13 +217,9 @@
}
}
- const char* FeatureEnumToName(Feature feature) {
+ wgpu::FeatureName FeatureEnumToAPIFeature(Feature feature) {
ASSERT(feature != Feature::InvalidEnum);
-
- const FeatureEnumAndInfo& featureNameAndInfo =
- kFeatureNameAndInfoList[static_cast<size_t>(feature)];
- ASSERT(featureNameAndInfo.feature == feature);
- return featureNameAndInfo.info.name;
+ return ToAPIFeature(feature);
}
FeaturesInfo::FeaturesInfo() {
@@ -216,14 +230,12 @@
}
}
- const FeatureInfo* FeaturesInfo::GetFeatureInfo(const char* featureName) const {
- ASSERT(featureName);
-
- const auto& iter = mFeatureNameToEnumMap.find(featureName);
- if (iter != mFeatureNameToEnumMap.cend()) {
- return &kFeatureNameAndInfoList[static_cast<size_t>(iter->second)].info;
+ const FeatureInfo* FeaturesInfo::GetFeatureInfo(wgpu::FeatureName feature) const {
+ Feature f = FromAPIFeature(feature);
+ if (f == Feature::InvalidEnum) {
+ return nullptr;
}
- return nullptr;
+ return &kFeatureNameAndInfoList[static_cast<size_t>(f)].info;
}
Feature FeaturesInfo::FeatureNameToEnum(const char* featureName) const {
@@ -253,16 +265,13 @@
return Feature::InvalidEnum;
}
- FeaturesSet FeaturesInfo::FeatureNamesToFeaturesSet(
- const std::vector<const char*>& requiredFeatures) const {
- FeaturesSet featuresSet;
-
- for (const char* featureName : requiredFeatures) {
- Feature featureEnum = FeatureNameToEnum(featureName);
- ASSERT(featureEnum != Feature::InvalidEnum);
- featuresSet.EnableFeature(featureEnum);
+ wgpu::FeatureName FeaturesInfo::FeatureNameToAPIEnum(const char* featureName) const {
+ Feature f = FeatureNameToEnum(featureName);
+ if (f != Feature::InvalidEnum) {
+ return ToAPIFeature(f);
}
- return featuresSet;
+ // Pass something invalid.
+ return static_cast<wgpu::FeatureName>(-1);
}
} // namespace dawn_native
diff --git a/src/dawn_native/Features.h b/src/dawn_native/Features.h
index 6dd2afc..07a1e6d 100644
--- a/src/dawn_native/Features.h
+++ b/src/dawn_native/Features.h
@@ -39,6 +39,7 @@
// Dawn-specific
DawnInternalUsages,
MultiPlanarFormats,
+ DawnNative,
EnumCount,
InvalidEnum = EnumCount,
@@ -51,6 +52,7 @@
std::bitset<static_cast<size_t>(Feature::EnumCount)> featuresBitSet;
void EnableFeature(Feature feature);
+ void EnableFeature(wgpu::FeatureName feature);
bool IsEnabled(Feature feature) const;
bool IsEnabled(wgpu::FeatureName feature) const;
// Returns |count|, the number of features. Writes out all |count| values if |features| is
@@ -60,7 +62,7 @@
void InitializeDeviceProperties(WGPUDeviceProperties* properties) const;
};
- const char* FeatureEnumToName(Feature feature);
+ wgpu::FeatureName FeatureEnumToAPIFeature(Feature feature);
class FeaturesInfo {
public:
@@ -68,10 +70,9 @@
// Used to query the details of an feature. Return nullptr if featureName is not a valid
// name of an feature supported in Dawn
- const FeatureInfo* GetFeatureInfo(const char* featureName) const;
+ const FeatureInfo* GetFeatureInfo(wgpu::FeatureName feature) const;
Feature FeatureNameToEnum(const char* featureName) const;
- FeaturesSet FeatureNamesToFeaturesSet(
- const std::vector<const char*>& requiredFeatures) const;
+ wgpu::FeatureName FeatureNameToAPIEnum(const char* featureName) const;
private:
std::unordered_map<std::string, Feature> mFeatureNameToEnumMap;
diff --git a/src/dawn_native/Instance.cpp b/src/dawn_native/Instance.cpp
index d8e107f..39648f3 100644
--- a/src/dawn_native/Instance.cpp
+++ b/src/dawn_native/Instance.cpp
@@ -142,17 +142,8 @@
return mTogglesInfo.ToggleNameToEnum(toggleName);
}
- const FeatureInfo* InstanceBase::GetFeatureInfo(const char* featureName) {
- return mFeaturesInfo.GetFeatureInfo(featureName);
- }
-
- Feature InstanceBase::FeatureNameToEnum(const char* featureName) {
- return mFeaturesInfo.FeatureNameToEnum(featureName);
- }
-
- FeaturesSet InstanceBase::FeatureNamesToFeaturesSet(
- const std::vector<const char*>& requiredFeatures) {
- return mFeaturesInfo.FeatureNamesToFeaturesSet(requiredFeatures);
+ const FeatureInfo* InstanceBase::GetFeatureInfo(wgpu::FeatureName feature) {
+ return mFeaturesInfo.GetFeatureInfo(feature);
}
const std::vector<std::unique_ptr<AdapterBase>>& InstanceBase::GetAdapters() const {
diff --git a/src/dawn_native/Instance.h b/src/dawn_native/Instance.h
index a36255a..488a30e 100644
--- a/src/dawn_native/Instance.h
+++ b/src/dawn_native/Instance.h
@@ -64,9 +64,7 @@
// Used to query the details of an feature. Return nullptr if featureName is not a valid
// name of an feature supported in Dawn.
- const FeatureInfo* GetFeatureInfo(const char* featureName);
- Feature FeatureNameToEnum(const char* featureName);
- FeaturesSet FeatureNamesToFeaturesSet(const std::vector<const char*>& requiredFeatures);
+ const FeatureInfo* GetFeatureInfo(wgpu::FeatureName feature);
bool IsBackendValidationEnabled() const;
void SetBackendValidationLevel(BackendValidationLevel level);
diff --git a/src/dawn_native/d3d12/AdapterD3D12.cpp b/src/dawn_native/d3d12/AdapterD3D12.cpp
index ca845f3..6e40c7a 100644
--- a/src/dawn_native/d3d12/AdapterD3D12.cpp
+++ b/src/dawn_native/d3d12/AdapterD3D12.cpp
@@ -394,7 +394,7 @@
infoQueue->PopStorageFilter();
}
- ResultOrError<DeviceBase*> Adapter::CreateDeviceImpl(const DawnDeviceDescriptor* descriptor) {
+ ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
return Device::Create(this, descriptor);
}
diff --git a/src/dawn_native/d3d12/AdapterD3D12.h b/src/dawn_native/d3d12/AdapterD3D12.h
index 4f40447..4bb5a02 100644
--- a/src/dawn_native/d3d12/AdapterD3D12.h
+++ b/src/dawn_native/d3d12/AdapterD3D12.h
@@ -40,8 +40,8 @@
const gpu_info::D3DDriverVersion& GetDriverVersion() const;
private:
- ResultOrError<DeviceBase*> CreateDeviceImpl(
- const DawnDeviceDescriptor* descriptor) override;
+ ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
+ const DeviceDescriptor* descriptor) override;
MaybeError ResetInternalDeviceForTestingImpl() override;
bool AreTimestampQueriesSupported() const;
diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp
index 2104789..94697e2 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn_native/d3d12/DeviceD3D12.cpp
@@ -56,11 +56,11 @@
static constexpr uint64_t kMaxDebugMessagesToPrint = 5;
// static
- ResultOrError<Device*> Device::Create(Adapter* adapter,
- const DawnDeviceDescriptor* descriptor) {
+ ResultOrError<Ref<Device>> Device::Create(Adapter* adapter,
+ const DeviceDescriptor* descriptor) {
Ref<Device> device = AcquireRef(new Device(adapter, descriptor));
DAWN_TRY(device->Initialize());
- return device.Detach();
+ return device;
}
MaybeError Device::Initialize() {
diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h
index e6b7234..6036e41 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.h
+++ b/src/dawn_native/d3d12/DeviceD3D12.h
@@ -41,8 +41,8 @@
// Definition of backend types
class Device final : public DeviceBase {
public:
- static ResultOrError<Device*> Create(Adapter* adapter,
- const DawnDeviceDescriptor* descriptor);
+ static ResultOrError<Ref<Device>> Create(Adapter* adapter,
+ const DeviceDescriptor* descriptor);
~Device() override;
MaybeError Initialize();
diff --git a/src/dawn_native/metal/BackendMTL.mm b/src/dawn_native/metal/BackendMTL.mm
index 632aa8a..8b0194b 100644
--- a/src/dawn_native/metal/BackendMTL.mm
+++ b/src/dawn_native/metal/BackendMTL.mm
@@ -277,8 +277,8 @@
}
private:
- ResultOrError<DeviceBase*> CreateDeviceImpl(
- const DawnDeviceDescriptor* descriptor) override {
+ ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
+ const DeviceDescriptor* descriptor) override {
return Device::Create(this, mDevice, descriptor);
}
diff --git a/src/dawn_native/metal/DeviceMTL.h b/src/dawn_native/metal/DeviceMTL.h
index 6f5153b..14c179f 100644
--- a/src/dawn_native/metal/DeviceMTL.h
+++ b/src/dawn_native/metal/DeviceMTL.h
@@ -38,9 +38,9 @@
class Device final : public DeviceBase {
public:
- static ResultOrError<Device*> Create(AdapterBase* adapter,
- NSPRef<id<MTLDevice>> mtlDevice,
- const DawnDeviceDescriptor* descriptor);
+ static ResultOrError<Ref<Device>> Create(AdapterBase* adapter,
+ NSPRef<id<MTLDevice>> mtlDevice,
+ const DeviceDescriptor* descriptor);
~Device() override;
MaybeError Initialize();
@@ -77,7 +77,7 @@
private:
Device(AdapterBase* adapter,
NSPRef<id<MTLDevice>> mtlDevice,
- const DawnDeviceDescriptor* descriptor);
+ const DeviceDescriptor* descriptor);
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
const BindGroupDescriptor* descriptor) override;
diff --git a/src/dawn_native/metal/DeviceMTL.mm b/src/dawn_native/metal/DeviceMTL.mm
index c79cff4..f02d096 100644
--- a/src/dawn_native/metal/DeviceMTL.mm
+++ b/src/dawn_native/metal/DeviceMTL.mm
@@ -106,17 +106,17 @@
} // namespace
// static
- ResultOrError<Device*> Device::Create(AdapterBase* adapter,
- NSPRef<id<MTLDevice>> mtlDevice,
- const DawnDeviceDescriptor* descriptor) {
+ ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
+ NSPRef<id<MTLDevice>> mtlDevice,
+ const DeviceDescriptor* descriptor) {
Ref<Device> device = AcquireRef(new Device(adapter, std::move(mtlDevice), descriptor));
DAWN_TRY(device->Initialize());
- return device.Detach();
+ return device;
}
Device::Device(AdapterBase* adapter,
NSPRef<id<MTLDevice>> mtlDevice,
- const DawnDeviceDescriptor* descriptor)
+ const DeviceDescriptor* descriptor)
: DeviceBase(adapter, descriptor), mMtlDevice(std::move(mtlDevice)), mCompletedSerial(0) {
}
diff --git a/src/dawn_native/null/DeviceNull.cpp b/src/dawn_native/null/DeviceNull.cpp
index b7146b9..58a783c 100644
--- a/src/dawn_native/null/DeviceNull.cpp
+++ b/src/dawn_native/null/DeviceNull.cpp
@@ -38,8 +38,11 @@
}
// Used for the tests that intend to use an adapter without all features enabled.
- void Adapter::SetSupportedFeatures(const std::vector<const char*>& requiredFeatures) {
- mSupportedFeatures = GetInstance()->FeatureNamesToFeaturesSet(requiredFeatures);
+ void Adapter::SetSupportedFeatures(const std::vector<wgpu::FeatureName>& requiredFeatures) {
+ mSupportedFeatures = {};
+ for (wgpu::FeatureName f : requiredFeatures) {
+ mSupportedFeatures.EnableFeature(f);
+ }
}
MaybeError Adapter::InitializeImpl() {
@@ -57,7 +60,7 @@
return {};
}
- ResultOrError<DeviceBase*> Adapter::CreateDeviceImpl(const DawnDeviceDescriptor* descriptor) {
+ ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
return Device::Create(this, descriptor);
}
@@ -95,11 +98,11 @@
// Device
// static
- ResultOrError<Device*> Device::Create(Adapter* adapter,
- const DawnDeviceDescriptor* descriptor) {
+ ResultOrError<Ref<Device>> Device::Create(Adapter* adapter,
+ const DeviceDescriptor* descriptor) {
Ref<Device> device = AcquireRef(new Device(adapter, descriptor));
DAWN_TRY(device->Initialize());
- return device.Detach();
+ return device;
}
Device::~Device() {
diff --git a/src/dawn_native/null/DeviceNull.h b/src/dawn_native/null/DeviceNull.h
index 380295b..ef2adfb 100644
--- a/src/dawn_native/null/DeviceNull.h
+++ b/src/dawn_native/null/DeviceNull.h
@@ -86,8 +86,8 @@
class Device final : public DeviceBase {
public:
- static ResultOrError<Device*> Create(Adapter* adapter,
- const DawnDeviceDescriptor* descriptor);
+ static ResultOrError<Ref<Device>> Create(Adapter* adapter,
+ const DeviceDescriptor* descriptor);
~Device() override;
MaybeError Initialize();
@@ -175,15 +175,15 @@
bool SupportsExternalImages() const override;
// Used for the tests that intend to use an adapter without all features enabled.
- void SetSupportedFeatures(const std::vector<const char*>& requiredFeatures);
+ void SetSupportedFeatures(const std::vector<wgpu::FeatureName>& requiredFeatures);
private:
MaybeError InitializeImpl() override;
MaybeError InitializeSupportedFeaturesImpl() override;
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override;
- ResultOrError<DeviceBase*> CreateDeviceImpl(
- const DawnDeviceDescriptor* descriptor) override;
+ ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
+ const DeviceDescriptor* descriptor) override;
};
// Helper class so |BindGroup| can allocate memory for its binding data,
diff --git a/src/dawn_native/opengl/BackendGL.cpp b/src/dawn_native/opengl/BackendGL.cpp
index 3c57200..611d258 100644
--- a/src/dawn_native/opengl/BackendGL.cpp
+++ b/src/dawn_native/opengl/BackendGL.cpp
@@ -254,8 +254,8 @@
return {};
}
- ResultOrError<DeviceBase*> CreateDeviceImpl(
- const DawnDeviceDescriptor* descriptor) override {
+ ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
+ const DeviceDescriptor* descriptor) override {
// There is no limit on the number of devices created from this adapter because they can
// all share the same backing OpenGL context.
return Device::Create(this, descriptor, mFunctions);
diff --git a/src/dawn_native/opengl/DeviceGL.cpp b/src/dawn_native/opengl/DeviceGL.cpp
index 89bd9f8..0240e06 100644
--- a/src/dawn_native/opengl/DeviceGL.cpp
+++ b/src/dawn_native/opengl/DeviceGL.cpp
@@ -35,16 +35,16 @@
namespace dawn_native { namespace opengl {
// static
- ResultOrError<Device*> Device::Create(AdapterBase* adapter,
- const DawnDeviceDescriptor* descriptor,
- const OpenGLFunctions& functions) {
+ ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
+ const DeviceDescriptor* descriptor,
+ const OpenGLFunctions& functions) {
Ref<Device> device = AcquireRef(new Device(adapter, descriptor, functions));
DAWN_TRY(device->Initialize());
- return device.Detach();
+ return device;
}
Device::Device(AdapterBase* adapter,
- const DawnDeviceDescriptor* descriptor,
+ const DeviceDescriptor* descriptor,
const OpenGLFunctions& functions)
: DeviceBase(adapter, descriptor), gl(functions) {
}
diff --git a/src/dawn_native/opengl/DeviceGL.h b/src/dawn_native/opengl/DeviceGL.h
index f131706..1bd8f31 100644
--- a/src/dawn_native/opengl/DeviceGL.h
+++ b/src/dawn_native/opengl/DeviceGL.h
@@ -37,9 +37,9 @@
class Device final : public DeviceBase {
public:
- static ResultOrError<Device*> Create(AdapterBase* adapter,
- const DawnDeviceDescriptor* descriptor,
- const OpenGLFunctions& functions);
+ static ResultOrError<Ref<Device>> Create(AdapterBase* adapter,
+ const DeviceDescriptor* descriptor,
+ const OpenGLFunctions& functions);
~Device() override;
MaybeError Initialize();
@@ -81,7 +81,7 @@
private:
Device(AdapterBase* adapter,
- const DawnDeviceDescriptor* descriptor,
+ const DeviceDescriptor* descriptor,
const OpenGLFunctions& functions);
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
diff --git a/src/dawn_native/vulkan/AdapterVk.cpp b/src/dawn_native/vulkan/AdapterVk.cpp
index 816efff..4f8b1c9 100644
--- a/src/dawn_native/vulkan/AdapterVk.cpp
+++ b/src/dawn_native/vulkan/AdapterVk.cpp
@@ -338,7 +338,7 @@
mVulkanInstance->GetFunctions());
}
- ResultOrError<DeviceBase*> Adapter::CreateDeviceImpl(const DawnDeviceDescriptor* descriptor) {
+ ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
return Device::Create(this, descriptor);
}
diff --git a/src/dawn_native/vulkan/AdapterVk.h b/src/dawn_native/vulkan/AdapterVk.h
index 7e9257c..6d93a07 100644
--- a/src/dawn_native/vulkan/AdapterVk.h
+++ b/src/dawn_native/vulkan/AdapterVk.h
@@ -46,8 +46,8 @@
MaybeError InitializeSupportedFeaturesImpl() override;
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override;
- ResultOrError<DeviceBase*> CreateDeviceImpl(
- const DawnDeviceDescriptor* descriptor) override;
+ ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
+ const DeviceDescriptor* descriptor) override;
VkPhysicalDevice mPhysicalDevice;
Ref<VulkanInstance> mVulkanInstance;
diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp
index de7c8d4..2c2c48b 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -45,14 +45,14 @@
namespace dawn_native { namespace vulkan {
// static
- ResultOrError<Device*> Device::Create(Adapter* adapter,
- const DawnDeviceDescriptor* descriptor) {
+ ResultOrError<Ref<Device>> Device::Create(Adapter* adapter,
+ const DeviceDescriptor* descriptor) {
Ref<Device> device = AcquireRef(new Device(adapter, descriptor));
DAWN_TRY(device->Initialize());
- return device.Detach();
+ return device;
}
- Device::Device(Adapter* adapter, const DawnDeviceDescriptor* descriptor)
+ Device::Device(Adapter* adapter, const DeviceDescriptor* descriptor)
: DeviceBase(adapter, descriptor) {
InitTogglesFromDriver();
}
diff --git a/src/dawn_native/vulkan/DeviceVk.h b/src/dawn_native/vulkan/DeviceVk.h
index 1c697a8..00f32c7 100644
--- a/src/dawn_native/vulkan/DeviceVk.h
+++ b/src/dawn_native/vulkan/DeviceVk.h
@@ -43,8 +43,8 @@
class Device final : public DeviceBase {
public:
- static ResultOrError<Device*> Create(Adapter* adapter,
- const DawnDeviceDescriptor* descriptor);
+ static ResultOrError<Ref<Device>> Create(Adapter* adapter,
+ const DeviceDescriptor* descriptor);
~Device() override;
MaybeError Initialize();
@@ -106,7 +106,7 @@
float GetTimestampPeriodInNS() const override;
private:
- Device(Adapter* adapter, const DawnDeviceDescriptor* descriptor);
+ Device(Adapter* adapter, const DeviceDescriptor* descriptor);
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
const BindGroupDescriptor* descriptor) override;
diff --git a/src/dawn_wire/SupportedFeatures.cpp b/src/dawn_wire/SupportedFeatures.cpp
index a1d4006..41c3a4a 100644
--- a/src/dawn_wire/SupportedFeatures.cpp
+++ b/src/dawn_wire/SupportedFeatures.cpp
@@ -22,6 +22,7 @@
switch (feature) {
case WGPUFeatureName_Undefined:
case WGPUFeatureName_Force32:
+ case WGPUFeatureName_DawnNative:
return false;
case WGPUFeatureName_Depth24UnormStencil8:
case WGPUFeatureName_Depth32FloatStencil8:
diff --git a/src/dawn_wire/client/Adapter.cpp b/src/dawn_wire/client/Adapter.cpp
index fd5daf7..db9986f 100644
--- a/src/dawn_wire/client/Adapter.cpp
+++ b/src/dawn_wire/client/Adapter.cpp
@@ -14,6 +14,7 @@
#include "dawn_wire/client/Adapter.h"
+#include "common/Log.h"
#include "dawn_wire/client/Client.h"
namespace dawn_wire { namespace client {
@@ -124,4 +125,9 @@
return true;
}
+ WGPUDevice Adapter::CreateDevice(const WGPUDeviceDescriptor*) {
+ dawn::ErrorLog() << "adapter.CreateDevice not supported with dawn_wire.";
+ return nullptr;
+ }
+
}} // namespace dawn_wire::client
diff --git a/src/dawn_wire/client/Adapter.h b/src/dawn_wire/client/Adapter.h
index e6f77dc..26c8222 100644
--- a/src/dawn_wire/client/Adapter.h
+++ b/src/dawn_wire/client/Adapter.h
@@ -50,6 +50,9 @@
uint32_t featuresCount,
const WGPUFeatureName* features);
+ // Unimplementable. Only availale in dawn_native.
+ WGPUDevice CreateDevice(const WGPUDeviceDescriptor*);
+
private:
LimitsAndFeatures mLimitsAndFeatures;
WGPUAdapterProperties mProperties;
diff --git a/src/include/dawn_native/DawnNative.h b/src/include/dawn_native/DawnNative.h
index a73f4f2..fb2bd78 100644
--- a/src/include/dawn_native/DawnNative.h
+++ b/src/include/dawn_native/DawnNative.h
@@ -121,15 +121,17 @@
explicit operator bool() const;
- // Create a device on this adapter, note that the interface will change to include at least
- // a device descriptor and a pointer to backend specific options.
- // On an error, nullptr is returned.
- WGPUDevice CreateDevice(const DawnDeviceDescriptor* deviceDescriptor = nullptr);
+ // Create a device on this adapter. On an error, nullptr is returned.
+ WGPUDevice CreateDevice(const DawnDeviceDescriptor* deviceDescriptor);
+ WGPUDevice CreateDevice(const WGPUDeviceDescriptor* deviceDescriptor = nullptr);
void RequestDevice(const DawnDeviceDescriptor* descriptor,
WGPURequestDeviceCallback callback,
void* userdata);
+ // Returns the underlying WGPUAdapter object.
+ WGPUAdapter Get() const;
+
// Reset the backend device object for testing purposes.
void ResetInternalDeviceForTesting();
@@ -173,6 +175,7 @@
std::vector<Adapter> GetAdapters() const;
const ToggleInfo* GetToggleInfo(const char* toggleName);
+ const FeatureInfo* GetFeatureInfo(WGPUFeatureName feature);
// Enables backend validation layers
void EnableBackendValidation(bool enableBackendValidation);
diff --git a/src/tests/BUILD.gn b/src/tests/BUILD.gn
index 4eb64a3..6141875 100644
--- a/src/tests/BUILD.gn
+++ b/src/tests/BUILD.gn
@@ -227,6 +227,7 @@
"unittests/TypedIntegerTests.cpp",
"unittests/native/CommandBufferEncodingTests.cpp",
"unittests/native/DestroyObjectTests.cpp",
+ "unittests/native/DeviceCreationTests.cpp",
"unittests/validation/BindGroupValidationTests.cpp",
"unittests/validation/BufferValidationTests.cpp",
"unittests/validation/CommandBufferValidationTests.cpp",
diff --git a/src/tests/unittests/FeatureTests.cpp b/src/tests/unittests/FeatureTests.cpp
index 729dca6..4e1e797 100644
--- a/src/tests/unittests/FeatureTests.cpp
+++ b/src/tests/unittests/FeatureTests.cpp
@@ -26,10 +26,10 @@
mAdapterBase(mInstanceBase.Get()) {
}
- std::vector<const char*> GetAllFeatureNames() {
- std::vector<const char*> allFeatureNames(kTotalFeaturesCount);
+ std::vector<wgpu::FeatureName> GetAllFeatureNames() {
+ std::vector<wgpu::FeatureName> allFeatureNames(kTotalFeaturesCount);
for (size_t i = 0; i < kTotalFeaturesCount; ++i) {
- allFeatureNames[i] = FeatureEnumToName(static_cast<dawn_native::Feature>(i));
+ allFeatureNames[i] = FeatureEnumToAPIFeature(static_cast<dawn_native::Feature>(i));
}
return allFeatureNames;
}
@@ -45,20 +45,23 @@
// Test the creation of a device will fail if the requested feature is not supported on the
// Adapter.
TEST_F(FeatureTests, AdapterWithRequiredFeatureDisabled) {
- const std::vector<const char*> kAllFeatureNames = GetAllFeatureNames();
+ const std::vector<wgpu::FeatureName> kAllFeatureNames = GetAllFeatureNames();
for (size_t i = 0; i < kTotalFeaturesCount; ++i) {
dawn_native::Feature notSupportedFeature = static_cast<dawn_native::Feature>(i);
- std::vector<const char*> featureNamesWithoutOne = kAllFeatureNames;
+ std::vector<wgpu::FeatureName> featureNamesWithoutOne = kAllFeatureNames;
featureNamesWithoutOne.erase(featureNamesWithoutOne.begin() + i);
mAdapterBase.SetSupportedFeatures(featureNamesWithoutOne);
dawn_native::Adapter adapterWithoutFeature(&mAdapterBase);
- dawn_native::DawnDeviceDescriptor deviceDescriptor;
- const char* featureName = FeatureEnumToName(notSupportedFeature);
- deviceDescriptor.requiredFeatures = std::vector<const char*>(1, featureName);
- WGPUDevice deviceWithFeature = adapterWithoutFeature.CreateDevice(&deviceDescriptor);
+ wgpu::DeviceDescriptor deviceDescriptor;
+ wgpu::FeatureName featureName = FeatureEnumToAPIFeature(notSupportedFeature);
+ deviceDescriptor.requiredFeatures = &featureName;
+ deviceDescriptor.requiredFeaturesCount = 1;
+
+ WGPUDevice deviceWithFeature = adapterWithoutFeature.CreateDevice(
+ reinterpret_cast<const WGPUDeviceDescriptor*>(&deviceDescriptor));
ASSERT_EQ(nullptr, deviceWithFeature);
}
}
@@ -68,14 +71,18 @@
dawn_native::Adapter adapter(&mAdapterBase);
for (size_t i = 0; i < kTotalFeaturesCount; ++i) {
dawn_native::Feature feature = static_cast<dawn_native::Feature>(i);
- const char* featureName = FeatureEnumToName(feature);
+ wgpu::FeatureName featureName = FeatureEnumToAPIFeature(feature);
- dawn_native::DawnDeviceDescriptor deviceDescriptor;
- deviceDescriptor.requiredFeatures = {featureName};
- dawn_native::DeviceBase* deviceBase =
- dawn_native::FromAPI(adapter.CreateDevice(&deviceDescriptor));
- std::vector<const char*> enabledFeatures = deviceBase->GetEnabledFeatures();
- ASSERT_EQ(1u, enabledFeatures.size());
- ASSERT_EQ(0, std::strcmp(featureName, enabledFeatures[0]));
+ wgpu::DeviceDescriptor deviceDescriptor;
+ deviceDescriptor.requiredFeatures = &featureName;
+ deviceDescriptor.requiredFeaturesCount = 1;
+
+ dawn_native::DeviceBase* deviceBase = dawn_native::FromAPI(
+ adapter.CreateDevice(reinterpret_cast<const WGPUDeviceDescriptor*>(&deviceDescriptor)));
+
+ ASSERT_EQ(1u, deviceBase->APIEnumerateFeatures(nullptr));
+ wgpu::FeatureName enabledFeature;
+ deviceBase->APIEnumerateFeatures(&enabledFeature);
+ EXPECT_EQ(enabledFeature, featureName);
}
}
diff --git a/src/tests/unittests/GetProcAddressTests.cpp b/src/tests/unittests/GetProcAddressTests.cpp
index 8f90efc..e2c6afd 100644
--- a/src/tests/unittests/GetProcAddressTests.cpp
+++ b/src/tests/unittests/GetProcAddressTests.cpp
@@ -59,7 +59,7 @@
switch (GetParam()) {
case DawnFlavor::Native: {
mDevice = wgpu::Device::Acquire(
- reinterpret_cast<WGPUDevice>(mNativeAdapter.CreateDevice(nullptr)));
+ reinterpret_cast<WGPUDevice>(mNativeAdapter.APICreateDevice()));
mProcs = dawn_native::GetProcs();
break;
}
diff --git a/src/tests/unittests/PerThreadProcTests.cpp b/src/tests/unittests/PerThreadProcTests.cpp
index 38ce981..6151a6c 100644
--- a/src/tests/unittests/PerThreadProcTests.cpp
+++ b/src/tests/unittests/PerThreadProcTests.cpp
@@ -57,10 +57,10 @@
// Note: Acquire doesn't call reference or release.
wgpu::Device deviceA =
- wgpu::Device::Acquire(reinterpret_cast<WGPUDevice>(mNativeAdapter.CreateDevice(nullptr)));
+ wgpu::Device::Acquire(reinterpret_cast<WGPUDevice>(mNativeAdapter.APICreateDevice()));
wgpu::Device deviceB =
- wgpu::Device::Acquire(reinterpret_cast<WGPUDevice>(mNativeAdapter.CreateDevice(nullptr)));
+ wgpu::Device::Acquire(reinterpret_cast<WGPUDevice>(mNativeAdapter.APICreateDevice()));
std::thread threadA([&]() {
DawnProcTable procs = dawn_native::GetProcs();
diff --git a/src/tests/unittests/native/DeviceCreationTests.cpp b/src/tests/unittests/native/DeviceCreationTests.cpp
new file mode 100644
index 0000000..6402286
--- /dev/null
+++ b/src/tests/unittests/native/DeviceCreationTests.cpp
@@ -0,0 +1,115 @@
+// Copyright 2021 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.
+
+#include "dawn/dawn_proc.h"
+#include "dawn_native/DawnNative.h"
+#include "tests/MockCallback.h"
+#include "utils/SystemUtils.h"
+#include "utils/WGPUHelpers.h"
+
+#include <gtest/gtest.h>
+
+namespace {
+
+ using namespace testing;
+
+ class DeviceCreationTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ dawnProcSetProcs(&dawn_native::GetProcs());
+
+ instance = std::make_unique<dawn_native::Instance>();
+ instance->DiscoverDefaultAdapters();
+ for (dawn_native::Adapter& nativeAdapter : instance->GetAdapters()) {
+ wgpu::AdapterProperties properties;
+ nativeAdapter.GetProperties(&properties);
+
+ if (properties.backendType == wgpu::BackendType::Null) {
+ adapter = wgpu::Adapter(nativeAdapter.Get());
+ break;
+ }
+ }
+ ASSERT_NE(adapter, nullptr);
+ }
+
+ void TearDown() override {
+ adapter = nullptr;
+ instance = nullptr;
+ dawnProcSetProcs(nullptr);
+ }
+
+ std::unique_ptr<dawn_native::Instance> instance;
+ wgpu::Adapter adapter;
+ };
+
+ // Test successful call to CreateDevice with no descriptor
+ TEST_F(DeviceCreationTest, CreateDeviceNoDescriptorSuccess) {
+ wgpu::Device device = adapter.CreateDevice();
+ EXPECT_NE(device, nullptr);
+ }
+
+ // Test successful call to CreateDevice with descriptor.
+ TEST_F(DeviceCreationTest, CreateDeviceSuccess) {
+ wgpu::DeviceDescriptor desc = {};
+ wgpu::Device device = adapter.CreateDevice(&desc);
+ EXPECT_NE(device, nullptr);
+ }
+
+ // Test successful call to CreateDevice with toggle descriptor.
+ TEST_F(DeviceCreationTest, CreateDeviceWithTogglesSuccess) {
+ wgpu::DeviceDescriptor desc = {};
+ wgpu::DawnTogglesDeviceDescriptor togglesDesc = {};
+ desc.nextInChain = &togglesDesc;
+
+ const char* toggle = "skip_validation";
+ togglesDesc.forceEnabledToggles = &toggle;
+ togglesDesc.forceEnabledTogglesCount = 1;
+
+ wgpu::Device device = adapter.CreateDevice(&desc);
+ EXPECT_NE(device, nullptr);
+
+ auto toggles = dawn_native::GetTogglesUsed(device.Get());
+ EXPECT_THAT(toggles, testing::Contains(testing::StrEq(toggle)));
+ }
+
+ // Test successful call to RequestDevice with descriptor
+ TEST_F(DeviceCreationTest, RequestDeviceSuccess) {
+ WGPUDevice cDevice;
+ {
+ MockCallback<WGPURequestDeviceCallback> cb;
+ EXPECT_CALL(cb, Call(WGPURequestDeviceStatus_Success, NotNull(), nullptr, this))
+ .WillOnce(SaveArg<1>(&cDevice));
+
+ wgpu::DeviceDescriptor desc = {};
+ adapter.RequestDevice(&desc, cb.Callback(), cb.MakeUserdata(this));
+ }
+
+ wgpu::Device device = wgpu::Device::Acquire(cDevice);
+ EXPECT_NE(device, nullptr);
+ }
+
+ // Test failing call to RequestDevice with invalid feature
+ TEST_F(DeviceCreationTest, RequestDeviceFailure) {
+ MockCallback<WGPURequestDeviceCallback> cb;
+ EXPECT_CALL(cb, Call(WGPURequestDeviceStatus_Error, nullptr, NotNull(), this)).Times(1);
+
+ wgpu::DeviceDescriptor desc = {};
+ wgpu::FeatureName invalidFeature = static_cast<wgpu::FeatureName>(WGPUFeatureName_Force32);
+ desc.requiredFeatures = &invalidFeature;
+ desc.requiredFeaturesCount = 1;
+
+ adapter.RequestDevice(&desc, cb.Callback(), cb.MakeUserdata(this));
+ }
+
+} // anonymous namespace
diff --git a/src/tests/white_box/VulkanImageWrappingTestsDmaBuf.cpp b/src/tests/white_box/VulkanImageWrappingTestsDmaBuf.cpp
index f1f3c27..830d5fd 100644
--- a/src/tests/white_box/VulkanImageWrappingTestsDmaBuf.cpp
+++ b/src/tests/white_box/VulkanImageWrappingTestsDmaBuf.cpp
@@ -312,17 +312,21 @@
// Create another device based on the original
backendAdapter = dawn_native::vulkan::ToBackend(deviceVk->GetAdapter());
- deviceDescriptor.forceEnabledToggles = GetParam().forceEnabledWorkarounds;
- deviceDescriptor.forceDisabledToggles = GetParam().forceDisabledWorkarounds;
+ deviceDescriptor.nextInChain = &togglesDesc;
+ togglesDesc.forceEnabledToggles = GetParam().forceEnabledWorkarounds.data();
+ togglesDesc.forceEnabledTogglesCount = GetParam().forceEnabledWorkarounds.size();
+ togglesDesc.forceDisabledToggles = GetParam().forceDisabledWorkarounds.data();
+ togglesDesc.forceDisabledTogglesCount = GetParam().forceDisabledWorkarounds.size();
secondDeviceVk =
- dawn_native::vulkan::ToBackend(backendAdapter->CreateDevice(&deviceDescriptor));
+ dawn_native::vulkan::ToBackend(backendAdapter->APICreateDevice(&deviceDescriptor));
secondDevice = wgpu::Device::Acquire(dawn_native::ToAPI(secondDeviceVk));
}
protected:
dawn_native::vulkan::Adapter* backendAdapter;
- dawn_native::DawnDeviceDescriptor deviceDescriptor;
+ dawn_native::DeviceDescriptor deviceDescriptor;
+ dawn_native::DawnTogglesDeviceDescriptor togglesDesc;
wgpu::Device secondDevice;
dawn_native::vulkan::Device* secondDeviceVk;
@@ -691,7 +695,7 @@
// device 2 = |secondDevice|
// Create device 3
dawn_native::vulkan::Device* thirdDeviceVk =
- dawn_native::vulkan::ToBackend(backendAdapter->CreateDevice(&deviceDescriptor));
+ dawn_native::vulkan::ToBackend(backendAdapter->APICreateDevice(&deviceDescriptor));
wgpu::Device thirdDevice = wgpu::Device::Acquire(dawn_native::ToAPI(thirdDeviceVk));
// Make queue for device 2 and 3
diff --git a/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp b/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp
index 196c1b0..74c551a 100644
--- a/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp
+++ b/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp
@@ -383,11 +383,14 @@
// Create another device based on the original
backendAdapter = dawn_native::vulkan::ToBackend(deviceVk->GetAdapter());
- deviceDescriptor.forceEnabledToggles = GetParam().forceEnabledWorkarounds;
- deviceDescriptor.forceDisabledToggles = GetParam().forceDisabledWorkarounds;
+ deviceDescriptor.nextInChain = &togglesDesc;
+ togglesDesc.forceEnabledToggles = GetParam().forceEnabledWorkarounds.data();
+ togglesDesc.forceEnabledTogglesCount = GetParam().forceEnabledWorkarounds.size();
+ togglesDesc.forceDisabledToggles = GetParam().forceDisabledWorkarounds.data();
+ togglesDesc.forceDisabledTogglesCount = GetParam().forceDisabledWorkarounds.size();
secondDeviceVk =
- dawn_native::vulkan::ToBackend(backendAdapter->CreateDevice(&deviceDescriptor));
+ dawn_native::vulkan::ToBackend(backendAdapter->APICreateDevice(&deviceDescriptor));
secondDevice = wgpu::Device::Acquire(dawn_native::ToAPI(secondDeviceVk));
CreateBindExportImage(deviceVk, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, &defaultImage,
@@ -418,7 +421,8 @@
dawn_native::vulkan::Device* secondDeviceVk;
dawn_native::vulkan::Adapter* backendAdapter;
- dawn_native::DawnDeviceDescriptor deviceDescriptor;
+ dawn_native::DeviceDescriptor deviceDescriptor;
+ dawn_native::DawnTogglesDeviceDescriptor togglesDesc;
wgpu::TextureDescriptor defaultDescriptor;
VkImage defaultImage;
@@ -797,7 +801,7 @@
// device 2 = |secondDevice|
// Create device 3
dawn_native::vulkan::Device* thirdDeviceVk =
- dawn_native::vulkan::ToBackend(backendAdapter->CreateDevice(&deviceDescriptor));
+ dawn_native::vulkan::ToBackend(backendAdapter->APICreateDevice(&deviceDescriptor));
wgpu::Device thirdDevice = wgpu::Device::Acquire(dawn_native::ToAPI(thirdDeviceVk));
// Make queue for device 2 and 3