Dawn: Promote DisallowUnsafeAPIs as instance toggle
This CL add Instance and Adapter toggle stage, and promote DisallowUnsafeAPIs as an instance toggle, and can be required using DawnTogglesDescriptor chained in instance descriptor when creating instance. The instance's toggles state will get inherited to adapters and devices it create. Related tests are implemented and updated. Toggles inheritance can be overriden if not forced, so requiring DisallowUnsafeAPIs when creating device is still available and working like before. Note that currently we don't have toggle of adapter stage, and can not require toggles when creating adapter, until follow up CLs implement it. Currently the toggles state of a adapter is simply inherited from instance. Bug: dawn:1495 Change-Id: I6bf7aa0f950a99451afcc2cab5322c924b7d9520 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/122021 Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com> Reviewed-by: Austin Eng <enga@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
e5ca66806f
commit
c2657b21d5
|
@ -174,7 +174,7 @@
|
||||||
"tags": ["dawn", "native"],
|
"tags": ["dawn", "native"],
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"chained": "in",
|
"chained": "in",
|
||||||
"chain roots": ["device descriptor"],
|
"chain roots": ["instance descriptor", "device descriptor"],
|
||||||
"members": [
|
"members": [
|
||||||
{"name": "enabled toggles count", "type": "uint32_t", "default": 0},
|
{"name": "enabled toggles count", "type": "uint32_t", "default": 0},
|
||||||
{"name": "enabled toggles", "type": "char", "annotation": "const*const*", "length": "enabled toggles count"},
|
{"name": "enabled toggles", "type": "char", "annotation": "const*const*", "length": "enabled toggles count"},
|
||||||
|
|
|
@ -51,9 +51,7 @@ struct DAWN_NATIVE_EXPORT DawnDeviceDescriptor {
|
||||||
|
|
||||||
// Each toggle is assigned with a TogglesStage, indicating the validation and earliest usage
|
// Each toggle is assigned with a TogglesStage, indicating the validation and earliest usage
|
||||||
// time of the toggle.
|
// time of the toggle.
|
||||||
// TODO(dawn:1495): Currently all toggles are device toggles, i.e. of Device toggle stage. Add
|
enum class ToggleStage { Instance, Adapter, Device };
|
||||||
// instance and adapter stages after instance and adapter toggles implemented.
|
|
||||||
enum class ToggleStage { Device };
|
|
||||||
|
|
||||||
// A struct to record the information of a toggle. A toggle is a code path in Dawn device that
|
// A struct to record the information of a toggle. A toggle is a code path in Dawn device that
|
||||||
// can be manually configured to run or not outside Dawn, including workarounds, special
|
// can be manually configured to run or not outside Dawn, including workarounds, special
|
||||||
|
|
|
@ -27,10 +27,11 @@
|
||||||
|
|
||||||
namespace dawn::native {
|
namespace dawn::native {
|
||||||
|
|
||||||
AdapterBase::AdapterBase(InstanceBase* instance, wgpu::BackendType backend)
|
AdapterBase::AdapterBase(InstanceBase* instance,
|
||||||
: mInstance(instance), mBackend(backend) {
|
wgpu::BackendType backend,
|
||||||
mSupportedFeatures.EnableFeature(Feature::DawnNative);
|
const TogglesState& adapterToggles)
|
||||||
mSupportedFeatures.EnableFeature(Feature::DawnInternalUsages);
|
: mInstance(instance), mBackend(backend), mTogglesState(adapterToggles) {
|
||||||
|
ASSERT(adapterToggles.GetStage() == ToggleStage::Adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdapterBase::~AdapterBase() = default;
|
AdapterBase::~AdapterBase() = default;
|
||||||
|
@ -39,6 +40,8 @@ MaybeError AdapterBase::Initialize() {
|
||||||
DAWN_TRY_CONTEXT(InitializeImpl(), "initializing adapter (backend=%s)", mBackend);
|
DAWN_TRY_CONTEXT(InitializeImpl(), "initializing adapter (backend=%s)", mBackend);
|
||||||
InitializeVendorArchitectureImpl();
|
InitializeVendorArchitectureImpl();
|
||||||
|
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::DawnNative);
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::DawnInternalUsages);
|
||||||
InitializeSupportedFeaturesImpl();
|
InitializeSupportedFeaturesImpl();
|
||||||
|
|
||||||
DAWN_TRY_CONTEXT(
|
DAWN_TRY_CONTEXT(
|
||||||
|
@ -206,6 +209,10 @@ bool AdapterBase::GetLimits(SupportedLimits* limits) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TogglesState& AdapterBase::GetTogglesState() const {
|
||||||
|
return mTogglesState;
|
||||||
|
}
|
||||||
|
|
||||||
MaybeError AdapterBase::ValidateFeatureSupportedWithDeviceToggles(
|
MaybeError AdapterBase::ValidateFeatureSupportedWithDeviceToggles(
|
||||||
wgpu::FeatureName feature,
|
wgpu::FeatureName feature,
|
||||||
const TogglesState& deviceTogglesState) {
|
const TogglesState& deviceTogglesState) {
|
||||||
|
@ -229,8 +236,8 @@ ResultOrError<Ref<DeviceBase>> AdapterBase::CreateDeviceInternal(
|
||||||
const DeviceDescriptor* descriptor) {
|
const DeviceDescriptor* descriptor) {
|
||||||
ASSERT(descriptor != nullptr);
|
ASSERT(descriptor != nullptr);
|
||||||
|
|
||||||
// Create device toggles state from required toggles descriptor.
|
// Create device toggles state from required toggles descriptor and inherited adapter toggles
|
||||||
// TODO(dawn:1495): After implementing adapter toggles, also inherite adapter toggles state.
|
// state.
|
||||||
const DawnTogglesDescriptor* deviceTogglesDesc = nullptr;
|
const DawnTogglesDescriptor* deviceTogglesDesc = nullptr;
|
||||||
FindInChain(descriptor->nextInChain, &deviceTogglesDesc);
|
FindInChain(descriptor->nextInChain, &deviceTogglesDesc);
|
||||||
|
|
||||||
|
@ -261,21 +268,21 @@ ResultOrError<Ref<DeviceBase>> AdapterBase::CreateDeviceInternal(
|
||||||
deviceTogglesDesc = &convertedDeviceTogglesDesc;
|
deviceTogglesDesc = &convertedDeviceTogglesDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create device toggles state from user-given toggles descriptor, and set up forced and default
|
// Create device toggles state.
|
||||||
// toggles.
|
|
||||||
// TODO(dawn:1495): After implementing adapter toggles, device toggles state should also inherit
|
|
||||||
// from adapter toggles state.
|
|
||||||
TogglesState deviceToggles =
|
TogglesState deviceToggles =
|
||||||
TogglesState::CreateFromTogglesDescriptor(deviceTogglesDesc, ToggleStage::Device);
|
TogglesState::CreateFromTogglesDescriptor(deviceTogglesDesc, ToggleStage::Device);
|
||||||
|
deviceToggles.InheritFrom(mTogglesState);
|
||||||
// Default toggles for all backend
|
// Default toggles for all backend
|
||||||
deviceToggles.Default(Toggle::LazyClearResourceOnFirstUse, true);
|
deviceToggles.Default(Toggle::LazyClearResourceOnFirstUse, true);
|
||||||
deviceToggles.Default(Toggle::DisallowUnsafeAPIs, true);
|
|
||||||
// Backend-specific forced and default device toggles
|
// Backend-specific forced and default device toggles
|
||||||
SetupBackendDeviceToggles(&deviceToggles);
|
SetupBackendDeviceToggles(&deviceToggles);
|
||||||
|
|
||||||
// Validate all required features are supported by the adapter and suitable under given toggles.
|
// Validate all required features are supported by the adapter and suitable under given toggles.
|
||||||
// TODO(dawn:1495): After implementing adapter toggles, validate supported features using
|
// Note that certain toggles in device toggles state may be overriden by user and different from
|
||||||
// adapter toggles instead of device toggles.
|
// the adapter toggles state.
|
||||||
|
// TODO(dawn:1495): After implementing adapter toggles, decide whether we should validate
|
||||||
|
// supported features using adapter toggles or device toggles.
|
||||||
for (uint32_t i = 0; i < descriptor->requiredFeaturesCount; ++i) {
|
for (uint32_t i = 0; i < descriptor->requiredFeaturesCount; ++i) {
|
||||||
wgpu::FeatureName feature = descriptor->requiredFeatures[i];
|
wgpu::FeatureName feature = descriptor->requiredFeatures[i];
|
||||||
DAWN_TRY(ValidateFeatureSupportedWithDeviceToggles(feature, deviceToggles));
|
DAWN_TRY(ValidateFeatureSupportedWithDeviceToggles(feature, deviceToggles));
|
||||||
|
|
|
@ -34,7 +34,9 @@ class DeviceBase;
|
||||||
|
|
||||||
class AdapterBase : public RefCounted {
|
class AdapterBase : public RefCounted {
|
||||||
public:
|
public:
|
||||||
AdapterBase(InstanceBase* instance, wgpu::BackendType backend);
|
AdapterBase(InstanceBase* instance,
|
||||||
|
wgpu::BackendType backend,
|
||||||
|
const TogglesState& adapterToggles);
|
||||||
~AdapterBase() override;
|
~AdapterBase() override;
|
||||||
|
|
||||||
MaybeError Initialize();
|
MaybeError Initialize();
|
||||||
|
@ -65,6 +67,9 @@ class AdapterBase : public RefCounted {
|
||||||
|
|
||||||
void SetUseTieredLimits(bool useTieredLimits);
|
void SetUseTieredLimits(bool useTieredLimits);
|
||||||
|
|
||||||
|
// Get the actual toggles state of the adapter.
|
||||||
|
const TogglesState& GetTogglesState() const;
|
||||||
|
|
||||||
virtual bool SupportsExternalImages() const = 0;
|
virtual bool SupportsExternalImages() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -113,6 +118,10 @@ class AdapterBase : public RefCounted {
|
||||||
virtual MaybeError ResetInternalDeviceForTestingImpl();
|
virtual MaybeError ResetInternalDeviceForTestingImpl();
|
||||||
Ref<InstanceBase> mInstance;
|
Ref<InstanceBase> mInstance;
|
||||||
wgpu::BackendType mBackend;
|
wgpu::BackendType mBackend;
|
||||||
|
|
||||||
|
// Adapter toggles state, currently only inherited from instance toggles state.
|
||||||
|
TogglesState mTogglesState;
|
||||||
|
|
||||||
CombinedLimits mLimits;
|
CombinedLimits mLimits;
|
||||||
bool mUseTieredLimits = false;
|
bool mUseTieredLimits = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "dawn/native/BackendConnection.h"
|
#include "dawn/native/BackendConnection.h"
|
||||||
|
#include "dawn/native/Instance.h"
|
||||||
|
|
||||||
namespace dawn::native {
|
namespace dawn::native {
|
||||||
|
|
||||||
|
@ -28,7 +29,8 @@ InstanceBase* BackendConnection::GetInstance() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<std::vector<Ref<AdapterBase>>> BackendConnection::DiscoverAdapters(
|
ResultOrError<std::vector<Ref<AdapterBase>>> BackendConnection::DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* options) {
|
const AdapterDiscoveryOptionsBase* options,
|
||||||
|
const TogglesState& adapterToggles) {
|
||||||
return DAWN_VALIDATION_ERROR("DiscoverAdapters not implemented for this backend.");
|
return DAWN_VALIDATION_ERROR("DiscoverAdapters not implemented for this backend.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "dawn/native/Adapter.h"
|
#include "dawn/native/Adapter.h"
|
||||||
#include "dawn/native/DawnNative.h"
|
#include "dawn/native/DawnNative.h"
|
||||||
|
#include "dawn/native/Toggles.h"
|
||||||
|
|
||||||
namespace dawn::native {
|
namespace dawn::native {
|
||||||
|
|
||||||
|
@ -35,11 +36,13 @@ class BackendConnection {
|
||||||
|
|
||||||
// Returns all the adapters for the system that can be created by the backend, without extra
|
// Returns all the adapters for the system that can be created by the backend, without extra
|
||||||
// options (such as debug adapters, custom driver libraries, etc.)
|
// options (such as debug adapters, custom driver libraries, etc.)
|
||||||
virtual std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() = 0;
|
virtual std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters(
|
||||||
|
const TogglesState& adapterToggles) = 0;
|
||||||
|
|
||||||
// Returns new adapters created with the backend-specific options.
|
// Returns new adapters created with the backend-specific options.
|
||||||
virtual ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
virtual ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* options);
|
const AdapterDiscoveryOptionsBase* options,
|
||||||
|
const TogglesState& adapterToggles);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InstanceBase* mInstance = nullptr;
|
InstanceBase* mInstance = nullptr;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "dawn/native/ChainUtils_autogen.h"
|
#include "dawn/native/ChainUtils_autogen.h"
|
||||||
#include "dawn/native/ErrorData.h"
|
#include "dawn/native/ErrorData.h"
|
||||||
#include "dawn/native/Surface.h"
|
#include "dawn/native/Surface.h"
|
||||||
|
#include "dawn/native/Toggles.h"
|
||||||
#include "dawn/native/ValidationUtils_autogen.h"
|
#include "dawn/native/ValidationUtils_autogen.h"
|
||||||
#include "dawn/platform/DawnPlatform.h"
|
#include "dawn/platform/DawnPlatform.h"
|
||||||
|
|
||||||
|
@ -110,18 +111,30 @@ InstanceBase* APICreateInstance(const InstanceDescriptor* descriptor) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Ref<InstanceBase> InstanceBase::Create(const InstanceDescriptor* descriptor) {
|
Ref<InstanceBase> InstanceBase::Create(const InstanceDescriptor* descriptor) {
|
||||||
Ref<InstanceBase> instance = AcquireRef(new InstanceBase);
|
|
||||||
static constexpr InstanceDescriptor kDefaultDesc = {};
|
static constexpr InstanceDescriptor kDefaultDesc = {};
|
||||||
if (descriptor == nullptr) {
|
if (descriptor == nullptr) {
|
||||||
descriptor = &kDefaultDesc;
|
descriptor = &kDefaultDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DawnTogglesDescriptor* instanceTogglesDesc = nullptr;
|
||||||
|
FindInChain(descriptor->nextInChain, &instanceTogglesDesc);
|
||||||
|
|
||||||
|
// Set up the instance toggle state from toggles descriptor
|
||||||
|
TogglesState instanceToggles =
|
||||||
|
TogglesState::CreateFromTogglesDescriptor(instanceTogglesDesc, ToggleStage::Instance);
|
||||||
|
// By default enable the DisallowUnsafeAPIs instance toggle, it will be inherited to adapters
|
||||||
|
// and devices created by this instance if not overriden.
|
||||||
|
// TODO(dawn:1685): Rename DisallowUnsafeAPIs to AllowUnsafeAPIs, and change relating logic.
|
||||||
|
instanceToggles.Default(Toggle::DisallowUnsafeAPIs, true);
|
||||||
|
|
||||||
|
Ref<InstanceBase> instance = AcquireRef(new InstanceBase(instanceToggles));
|
||||||
if (instance->ConsumedError(instance->Initialize(descriptor))) {
|
if (instance->ConsumedError(instance->Initialize(descriptor))) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceBase::InstanceBase() = default;
|
InstanceBase::InstanceBase(const TogglesState& instanceToggles) : mToggles(instanceToggles) {}
|
||||||
|
|
||||||
InstanceBase::~InstanceBase() = default;
|
InstanceBase::~InstanceBase() = default;
|
||||||
|
|
||||||
|
@ -138,7 +151,9 @@ void InstanceBase::WillDropLastExternalRef() {
|
||||||
|
|
||||||
// TODO(crbug.com/dawn/832): make the platform an initialization parameter of the instance.
|
// TODO(crbug.com/dawn/832): make the platform an initialization parameter of the instance.
|
||||||
MaybeError InstanceBase::Initialize(const InstanceDescriptor* descriptor) {
|
MaybeError InstanceBase::Initialize(const InstanceDescriptor* descriptor) {
|
||||||
DAWN_TRY(ValidateSingleSType(descriptor->nextInChain, wgpu::SType::DawnInstanceDescriptor));
|
DAWN_TRY(ValidateSTypes(descriptor->nextInChain, {{wgpu::SType::DawnInstanceDescriptor},
|
||||||
|
{wgpu::SType::DawnTogglesDescriptor}}));
|
||||||
|
|
||||||
const DawnInstanceDescriptor* dawnDesc = nullptr;
|
const DawnInstanceDescriptor* dawnDesc = nullptr;
|
||||||
FindInChain(descriptor->nextInChain, &dawnDesc);
|
FindInChain(descriptor->nextInChain, &dawnDesc);
|
||||||
if (dawnDesc != nullptr) {
|
if (dawnDesc != nullptr) {
|
||||||
|
@ -280,7 +295,14 @@ void InstanceBase::DiscoverDefaultAdapters() {
|
||||||
|
|
||||||
// Query and merge all default adapters for all backends
|
// Query and merge all default adapters for all backends
|
||||||
for (std::unique_ptr<BackendConnection>& backend : mBackends) {
|
for (std::unique_ptr<BackendConnection>& backend : mBackends) {
|
||||||
std::vector<Ref<AdapterBase>> backendAdapters = backend->DiscoverDefaultAdapters();
|
// Set up toggles state for default adapters, currently adapter don't have a toggles
|
||||||
|
// descriptor so just inherit from instance toggles.
|
||||||
|
// TODO(dawn:1495): Handle the adapter toggles descriptor after implemented.
|
||||||
|
TogglesState adapterToggles = TogglesState(ToggleStage::Adapter);
|
||||||
|
adapterToggles.InheritFrom(mToggles);
|
||||||
|
|
||||||
|
std::vector<Ref<AdapterBase>> backendAdapters =
|
||||||
|
backend->DiscoverDefaultAdapters(adapterToggles);
|
||||||
|
|
||||||
for (Ref<AdapterBase>& adapter : backendAdapters) {
|
for (Ref<AdapterBase>& adapter : backendAdapters) {
|
||||||
ASSERT(adapter->GetBackendType() == backend->GetType());
|
ASSERT(adapter->GetBackendType() == backend->GetType());
|
||||||
|
@ -306,6 +328,10 @@ bool InstanceBase::DiscoverAdapters(const AdapterDiscoveryOptionsBase* options)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TogglesState& InstanceBase::GetTogglesState() const {
|
||||||
|
return mToggles;
|
||||||
|
}
|
||||||
|
|
||||||
const ToggleInfo* InstanceBase::GetToggleInfo(const char* toggleName) {
|
const ToggleInfo* InstanceBase::GetToggleInfo(const char* toggleName) {
|
||||||
return mTogglesInfo.GetToggleInfo(toggleName);
|
return mTogglesInfo.GetToggleInfo(toggleName);
|
||||||
}
|
}
|
||||||
|
@ -397,8 +423,14 @@ MaybeError InstanceBase::DiscoverAdaptersInternal(const AdapterDiscoveryOptionsB
|
||||||
}
|
}
|
||||||
foundBackend = true;
|
foundBackend = true;
|
||||||
|
|
||||||
|
// Set up toggles state for default adapters, currently adapter don't have a toggles
|
||||||
|
// descriptor so just inherit from instance toggles.
|
||||||
|
// TODO(dawn:1495): Handle the adapter toggles descriptor after implemented.
|
||||||
|
TogglesState adapterToggles = TogglesState(ToggleStage::Adapter);
|
||||||
|
adapterToggles.InheritFrom(mToggles);
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> newAdapters;
|
std::vector<Ref<AdapterBase>> newAdapters;
|
||||||
DAWN_TRY_ASSIGN(newAdapters, backend->DiscoverAdapters(options));
|
DAWN_TRY_ASSIGN(newAdapters, backend->DiscoverAdapters(options, adapterToggles));
|
||||||
|
|
||||||
for (Ref<AdapterBase>& adapter : newAdapters) {
|
for (Ref<AdapterBase>& adapter : newAdapters) {
|
||||||
ASSERT(adapter->GetBackendType() == backend->GetType());
|
ASSERT(adapter->GetBackendType() == backend->GetType());
|
||||||
|
|
|
@ -72,6 +72,8 @@ class InstanceBase final : public RefCountedWithExternalCount {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TogglesState& GetTogglesState() const;
|
||||||
|
|
||||||
// Used to query the details of a toggle. Return nullptr if toggleName is not a valid name
|
// Used to query the details of a toggle. Return nullptr if toggleName is not a valid name
|
||||||
// of a toggle supported in Dawn.
|
// of a toggle supported in Dawn.
|
||||||
const ToggleInfo* GetToggleInfo(const char* toggleName);
|
const ToggleInfo* GetToggleInfo(const char* toggleName);
|
||||||
|
@ -113,7 +115,7 @@ class InstanceBase final : public RefCountedWithExternalCount {
|
||||||
Surface* APICreateSurface(const SurfaceDescriptor* descriptor);
|
Surface* APICreateSurface(const SurfaceDescriptor* descriptor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InstanceBase();
|
explicit InstanceBase(const TogglesState& instanceToggles);
|
||||||
~InstanceBase() override;
|
~InstanceBase() override;
|
||||||
|
|
||||||
void WillDropLastExternalRef() override;
|
void WillDropLastExternalRef() override;
|
||||||
|
@ -150,6 +152,8 @@ class InstanceBase final : public RefCountedWithExternalCount {
|
||||||
std::vector<std::unique_ptr<BackendConnection>> mBackends;
|
std::vector<std::unique_ptr<BackendConnection>> mBackends;
|
||||||
std::vector<Ref<AdapterBase>> mAdapters;
|
std::vector<Ref<AdapterBase>> mAdapters;
|
||||||
|
|
||||||
|
TogglesState mToggles;
|
||||||
|
|
||||||
FeaturesInfo mFeaturesInfo;
|
FeaturesInfo mFeaturesInfo;
|
||||||
TogglesInfo mTogglesInfo;
|
TogglesInfo mTogglesInfo;
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ static constexpr ToggleEnumAndInfoList kToggleNameAndInfoList = {{
|
||||||
{"disallow_unsafe_apis",
|
{"disallow_unsafe_apis",
|
||||||
"Produces validation errors on API entry points or parameter combinations that aren't "
|
"Produces validation errors on API entry points or parameter combinations that aren't "
|
||||||
"considered secure yet.",
|
"considered secure yet.",
|
||||||
"http://crbug.com/1138528", ToggleStage::Device}},
|
"http://crbug.com/1138528", ToggleStage::Instance}},
|
||||||
{Toggle::FlushBeforeClientWaitSync,
|
{Toggle::FlushBeforeClientWaitSync,
|
||||||
{"flush_before_client_wait_sync",
|
{"flush_before_client_wait_sync",
|
||||||
"Call glFlush before glClientWaitSync to work around bugs in the latter",
|
"Call glFlush before glClientWaitSync to work around bugs in the latter",
|
||||||
|
@ -447,7 +447,9 @@ TogglesState TogglesState::CreateFromTogglesDescriptor(const DawnTogglesDescript
|
||||||
Toggle toggle = togglesInfo.ToggleNameToEnum(togglesDesc->enabledToggles[i]);
|
Toggle toggle = togglesInfo.ToggleNameToEnum(togglesDesc->enabledToggles[i]);
|
||||||
if (toggle != Toggle::InvalidEnum) {
|
if (toggle != Toggle::InvalidEnum) {
|
||||||
const ToggleInfo* toggleInfo = togglesInfo.GetToggleInfo(toggle);
|
const ToggleInfo* toggleInfo = togglesInfo.GetToggleInfo(toggle);
|
||||||
if (toggleInfo->stage == requiredStage) {
|
// Accept the required toggles of current and earlier stage to allow override
|
||||||
|
// inheritance.
|
||||||
|
if (toggleInfo->stage <= requiredStage) {
|
||||||
togglesState.mTogglesSet.Set(toggle, true);
|
togglesState.mTogglesSet.Set(toggle, true);
|
||||||
togglesState.mEnabledToggles.Set(toggle, true);
|
togglesState.mEnabledToggles.Set(toggle, true);
|
||||||
}
|
}
|
||||||
|
@ -457,7 +459,9 @@ TogglesState TogglesState::CreateFromTogglesDescriptor(const DawnTogglesDescript
|
||||||
Toggle toggle = togglesInfo.ToggleNameToEnum(togglesDesc->disabledToggles[i]);
|
Toggle toggle = togglesInfo.ToggleNameToEnum(togglesDesc->disabledToggles[i]);
|
||||||
if (toggle != Toggle::InvalidEnum) {
|
if (toggle != Toggle::InvalidEnum) {
|
||||||
const ToggleInfo* toggleInfo = togglesInfo.GetToggleInfo(toggle);
|
const ToggleInfo* toggleInfo = togglesInfo.GetToggleInfo(toggle);
|
||||||
if (toggleInfo->stage == requiredStage) {
|
// Accept the required toggles of current and earlier stage to allow override
|
||||||
|
// inheritance.
|
||||||
|
if (toggleInfo->stage <= requiredStage) {
|
||||||
togglesState.mTogglesSet.Set(toggle, true);
|
togglesState.mTogglesSet.Set(toggle, true);
|
||||||
togglesState.mEnabledToggles.Set(toggle, false);
|
togglesState.mEnabledToggles.Set(toggle, false);
|
||||||
}
|
}
|
||||||
|
@ -467,6 +471,30 @@ TogglesState TogglesState::CreateFromTogglesDescriptor(const DawnTogglesDescript
|
||||||
return togglesState;
|
return togglesState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TogglesState& TogglesState::InheritFrom(const TogglesState& inheritedToggles) {
|
||||||
|
ASSERT(inheritedToggles.GetStage() < mStage);
|
||||||
|
|
||||||
|
// Do inheritance. All toggles that are force-set in the inherited toggles states would
|
||||||
|
// be force-set in the result toggles state, and all toggles that are set in the inherited
|
||||||
|
// toggles states and not required in current toggles state would be set in the result toggles
|
||||||
|
// state.
|
||||||
|
for (uint32_t i : inheritedToggles.mTogglesSet.Iterate()) {
|
||||||
|
const Toggle& toggle = static_cast<Toggle>(i);
|
||||||
|
ASSERT(TogglesInfo::GetToggleInfo(toggle)->stage < mStage);
|
||||||
|
bool isEnabled = inheritedToggles.mEnabledToggles.Has(toggle);
|
||||||
|
bool isForced = inheritedToggles.mForcedToggles.Has(toggle);
|
||||||
|
// Only inherit a toggle if it is not set by user requirement or is forced in earlier stage.
|
||||||
|
// In this way we allow user requirement override the inheritance if not forced.
|
||||||
|
if (!mTogglesSet.Has(toggle) || isForced) {
|
||||||
|
mTogglesSet.Set(toggle, true);
|
||||||
|
mEnabledToggles.Set(toggle, isEnabled);
|
||||||
|
mForcedToggles.Set(toggle, isForced);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// Set a toggle to given state, if the toggle has not been already set. Do nothing otherwise.
|
// Set a toggle to given state, if the toggle has not been already set. Do nothing otherwise.
|
||||||
void TogglesState::Default(Toggle toggle, bool enabled) {
|
void TogglesState::Default(Toggle toggle, bool enabled) {
|
||||||
ASSERT(toggle != Toggle::InvalidEnum);
|
ASSERT(toggle != Toggle::InvalidEnum);
|
||||||
|
@ -492,6 +520,15 @@ void TogglesState::ForceSet(Toggle toggle, bool enabled) {
|
||||||
mForcedToggles.Set(toggle, true);
|
mForcedToggles.Set(toggle, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TogglesState& TogglesState::SetForTesting(Toggle toggle, bool enabled, bool forced) {
|
||||||
|
ASSERT(toggle != Toggle::InvalidEnum);
|
||||||
|
mTogglesSet.Set(toggle, true);
|
||||||
|
mEnabledToggles.Set(toggle, enabled);
|
||||||
|
mForcedToggles.Set(toggle, forced);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool TogglesState::IsSet(Toggle toggle) const {
|
bool TogglesState::IsSet(Toggle toggle) const {
|
||||||
// Ensure that the toggle never used earlier than its stage.
|
// Ensure that the toggle never used earlier than its stage.
|
||||||
ASSERT(TogglesInfo::GetToggleInfo(toggle)->stage <= mStage);
|
ASSERT(TogglesInfo::GetToggleInfo(toggle)->stage <= mStage);
|
||||||
|
|
|
@ -127,17 +127,25 @@ class TogglesState {
|
||||||
// Create an empty toggles state of given stage
|
// Create an empty toggles state of given stage
|
||||||
explicit TogglesState(ToggleStage stage);
|
explicit TogglesState(ToggleStage stage);
|
||||||
|
|
||||||
// Create a RequiredTogglesSet from a DawnTogglesDescriptor, only considering toggles of
|
// Create a TogglesState from a DawnTogglesDescriptor, only considering toggles of
|
||||||
// required toggle stage.
|
// required toggle stage.
|
||||||
static TogglesState CreateFromTogglesDescriptor(const DawnTogglesDescriptor* togglesDesc,
|
static TogglesState CreateFromTogglesDescriptor(const DawnTogglesDescriptor* togglesDesc,
|
||||||
ToggleStage requiredStage);
|
ToggleStage requiredStage);
|
||||||
|
|
||||||
|
// Inherit from a given toggles state of earlier stage, only inherit the forced and the
|
||||||
|
// unrequired toggles to allow overriding. Return *this to allow method chaining manner.
|
||||||
|
TogglesState& InheritFrom(const TogglesState& inheritedToggles);
|
||||||
|
|
||||||
// Set a toggle of the same stage of toggles state stage if and only if it is not already set.
|
// Set a toggle of the same stage of toggles state stage if and only if it is not already set.
|
||||||
void Default(Toggle toggle, bool enabled);
|
void Default(Toggle toggle, bool enabled);
|
||||||
// Force set a toggle of same stage of toggles state stage. A force-set toggle will get
|
// Force set a toggle of same stage of toggles state stage. A force-set toggle will get
|
||||||
// inherited to all later stage as forced.
|
// inherited to all later stage as forced.
|
||||||
void ForceSet(Toggle toggle, bool enabled);
|
void ForceSet(Toggle toggle, bool enabled);
|
||||||
|
|
||||||
|
// Set a toggle of any stage for testing propose. Return *this to allow method chaining
|
||||||
|
// manner.
|
||||||
|
TogglesState& SetForTesting(Toggle toggle, bool enabled, bool forced);
|
||||||
|
|
||||||
// Return whether the toggle is set or not. Force-set is always treated as set.
|
// Return whether the toggle is set or not. Force-set is always treated as set.
|
||||||
bool IsSet(Toggle toggle) const;
|
bool IsSet(Toggle toggle) const;
|
||||||
// Return true if and only if the toggle is set to true.
|
// Return true if and only if the toggle is set to true.
|
||||||
|
|
|
@ -28,8 +28,10 @@
|
||||||
|
|
||||||
namespace dawn::native::d3d12 {
|
namespace dawn::native::d3d12 {
|
||||||
|
|
||||||
Adapter::Adapter(Backend* backend, ComPtr<IDXGIAdapter3> hardwareAdapter)
|
Adapter::Adapter(Backend* backend,
|
||||||
: AdapterBase(backend->GetInstance(), wgpu::BackendType::D3D12),
|
ComPtr<IDXGIAdapter3> hardwareAdapter,
|
||||||
|
const TogglesState& adapterToggles)
|
||||||
|
: AdapterBase(backend->GetInstance(), wgpu::BackendType::D3D12, adapterToggles),
|
||||||
mHardwareAdapter(hardwareAdapter),
|
mHardwareAdapter(hardwareAdapter),
|
||||||
mBackend(backend) {}
|
mBackend(backend) {}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,9 @@ class Backend;
|
||||||
|
|
||||||
class Adapter : public AdapterBase {
|
class Adapter : public AdapterBase {
|
||||||
public:
|
public:
|
||||||
Adapter(Backend* backend, ComPtr<IDXGIAdapter3> hardwareAdapter);
|
Adapter(Backend* backend,
|
||||||
|
ComPtr<IDXGIAdapter3> hardwareAdapter,
|
||||||
|
const TogglesState& adapterToggles);
|
||||||
~Adapter() override;
|
~Adapter() override;
|
||||||
|
|
||||||
// AdapterBase Implementation
|
// AdapterBase Implementation
|
||||||
|
|
|
@ -69,10 +69,12 @@ ResultOrError<ComPtr<IDXGIFactory4>> CreateFactory(const PlatformFunctions* func
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<Ref<AdapterBase>> CreateAdapterFromIDXGIAdapter(Backend* backend,
|
ResultOrError<Ref<AdapterBase>> CreateAdapterFromIDXGIAdapter(Backend* backend,
|
||||||
ComPtr<IDXGIAdapter> dxgiAdapter) {
|
ComPtr<IDXGIAdapter> dxgiAdapter,
|
||||||
|
const TogglesState& adapterToggles) {
|
||||||
ComPtr<IDXGIAdapter3> dxgiAdapter3;
|
ComPtr<IDXGIAdapter3> dxgiAdapter3;
|
||||||
DAWN_TRY(CheckHRESULT(dxgiAdapter.As(&dxgiAdapter3), "DXGIAdapter retrieval"));
|
DAWN_TRY(CheckHRESULT(dxgiAdapter.As(&dxgiAdapter3), "DXGIAdapter retrieval"));
|
||||||
Ref<Adapter> adapter = AcquireRef(new Adapter(backend, std::move(dxgiAdapter3)));
|
Ref<Adapter> adapter =
|
||||||
|
AcquireRef(new Adapter(backend, std::move(dxgiAdapter3), adapterToggles));
|
||||||
DAWN_TRY(adapter->Initialize());
|
DAWN_TRY(adapter->Initialize());
|
||||||
|
|
||||||
return {std::move(adapter)};
|
return {std::move(adapter)};
|
||||||
|
@ -271,9 +273,9 @@ const PlatformFunctions* Backend::GetFunctions() const {
|
||||||
return mFunctions.get();
|
return mFunctions.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters(const TogglesState& adapterToggles) {
|
||||||
AdapterDiscoveryOptions options;
|
AdapterDiscoveryOptions options;
|
||||||
auto result = DiscoverAdapters(&options);
|
auto result = DiscoverAdapters(&options, adapterToggles);
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
GetInstance()->ConsumedError(result.AcquireError());
|
GetInstance()->ConsumedError(result.AcquireError());
|
||||||
return {};
|
return {};
|
||||||
|
@ -282,7 +284,8 @@ std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* optionsBase) {
|
const AdapterDiscoveryOptionsBase* optionsBase,
|
||||||
|
const TogglesState& adapterToggles) {
|
||||||
ASSERT(optionsBase->backendType == WGPUBackendType_D3D12);
|
ASSERT(optionsBase->backendType == WGPUBackendType_D3D12);
|
||||||
const AdapterDiscoveryOptions* options =
|
const AdapterDiscoveryOptions* options =
|
||||||
static_cast<const AdapterDiscoveryOptions*>(optionsBase);
|
static_cast<const AdapterDiscoveryOptions*>(optionsBase);
|
||||||
|
@ -291,7 +294,8 @@ ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||||
if (options->dxgiAdapter != nullptr) {
|
if (options->dxgiAdapter != nullptr) {
|
||||||
// |dxgiAdapter| was provided. Discover just that adapter.
|
// |dxgiAdapter| was provided. Discover just that adapter.
|
||||||
Ref<AdapterBase> adapter;
|
Ref<AdapterBase> adapter;
|
||||||
DAWN_TRY_ASSIGN(adapter, CreateAdapterFromIDXGIAdapter(this, options->dxgiAdapter));
|
DAWN_TRY_ASSIGN(adapter,
|
||||||
|
CreateAdapterFromIDXGIAdapter(this, options->dxgiAdapter, adapterToggles));
|
||||||
adapters.push_back(std::move(adapter));
|
adapters.push_back(std::move(adapter));
|
||||||
return std::move(adapters);
|
return std::move(adapters);
|
||||||
}
|
}
|
||||||
|
@ -304,7 +308,8 @@ ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(dxgiAdapter != nullptr);
|
ASSERT(dxgiAdapter != nullptr);
|
||||||
ResultOrError<Ref<AdapterBase>> adapter = CreateAdapterFromIDXGIAdapter(this, dxgiAdapter);
|
ResultOrError<Ref<AdapterBase>> adapter =
|
||||||
|
CreateAdapterFromIDXGIAdapter(this, dxgiAdapter, adapterToggles);
|
||||||
if (adapter.IsError()) {
|
if (adapter.IsError()) {
|
||||||
GetInstance()->ConsumedError(adapter.AcquireError());
|
GetInstance()->ConsumedError(adapter.AcquireError());
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -75,9 +75,11 @@ class Backend : public BackendConnection {
|
||||||
|
|
||||||
const PlatformFunctions* GetFunctions() const;
|
const PlatformFunctions* GetFunctions() const;
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() override;
|
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters(
|
||||||
|
const TogglesState& adapterToggles) override;
|
||||||
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* optionsBase) override;
|
const AdapterDiscoveryOptionsBase* optionsBase,
|
||||||
|
const TogglesState& adapterToggles) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Acquiring DXC version information and store the result in mDxcVersionInfo. This function
|
// Acquiring DXC version information and store the result in mDxcVersionInfo. This function
|
||||||
|
|
|
@ -26,9 +26,11 @@ class Backend : public BackendConnection {
|
||||||
explicit Backend(InstanceBase* instance);
|
explicit Backend(InstanceBase* instance);
|
||||||
~Backend() override;
|
~Backend() override;
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() override;
|
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters(
|
||||||
|
const TogglesState& adapterToggles) override;
|
||||||
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* optionsBase) override;
|
const AdapterDiscoveryOptionsBase* optionsBase,
|
||||||
|
const TogglesState& adapterToggles) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dawn::native::metal
|
} // namespace dawn::native::metal
|
||||||
|
|
|
@ -255,8 +255,8 @@ DAWN_NOINLINE bool IsGPUCounterSupported(id<MTLDevice> device,
|
||||||
|
|
||||||
class Adapter : public AdapterBase {
|
class Adapter : public AdapterBase {
|
||||||
public:
|
public:
|
||||||
Adapter(InstanceBase* instance, id<MTLDevice> device)
|
Adapter(InstanceBase* instance, id<MTLDevice> device, const TogglesState& requiredAdapterToggle)
|
||||||
: AdapterBase(instance, wgpu::BackendType::Metal), mDevice(device) {
|
: AdapterBase(instance, wgpu::BackendType::Metal, requiredAdapterToggle), mDevice(device) {
|
||||||
mName = std::string([[*mDevice name] UTF8String]);
|
mName = std::string([[*mDevice name] UTF8String]);
|
||||||
|
|
||||||
PCIIDs ids;
|
PCIIDs ids;
|
||||||
|
@ -774,9 +774,9 @@ Backend::Backend(InstanceBase* instance) : BackendConnection(instance, wgpu::Bac
|
||||||
|
|
||||||
Backend::~Backend() = default;
|
Backend::~Backend() = default;
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters(const TogglesState& adapterToggles) {
|
||||||
AdapterDiscoveryOptions options;
|
AdapterDiscoveryOptions options;
|
||||||
auto result = DiscoverAdapters(&options);
|
auto result = DiscoverAdapters(&options, adapterToggles);
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
GetInstance()->ConsumedError(result.AcquireError());
|
GetInstance()->ConsumedError(result.AcquireError());
|
||||||
return {};
|
return {};
|
||||||
|
@ -785,7 +785,8 @@ std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* optionsBase) {
|
const AdapterDiscoveryOptionsBase* optionsBase,
|
||||||
|
const TogglesState& adapterToggles) {
|
||||||
ASSERT(optionsBase->backendType == WGPUBackendType_Metal);
|
ASSERT(optionsBase->backendType == WGPUBackendType_Metal);
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> adapters;
|
std::vector<Ref<AdapterBase>> adapters;
|
||||||
|
@ -793,7 +794,7 @@ ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||||
NSRef<NSArray<id<MTLDevice>>> devices = AcquireNSRef(MTLCopyAllDevices());
|
NSRef<NSArray<id<MTLDevice>>> devices = AcquireNSRef(MTLCopyAllDevices());
|
||||||
|
|
||||||
for (id<MTLDevice> device in devices.Get()) {
|
for (id<MTLDevice> device in devices.Get()) {
|
||||||
Ref<Adapter> adapter = AcquireRef(new Adapter(GetInstance(), device));
|
Ref<Adapter> adapter = AcquireRef(new Adapter(GetInstance(), device, adapterToggles));
|
||||||
if (!GetInstance()->ConsumedError(adapter->Initialize())) {
|
if (!GetInstance()->ConsumedError(adapter->Initialize())) {
|
||||||
adapters.push_back(std::move(adapter));
|
adapters.push_back(std::move(adapter));
|
||||||
}
|
}
|
||||||
|
@ -802,7 +803,8 @@ ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||||
|
|
||||||
// iOS only has a single device so MTLCopyAllDevices doesn't exist there.
|
// iOS only has a single device so MTLCopyAllDevices doesn't exist there.
|
||||||
#if defined(DAWN_PLATFORM_IOS)
|
#if defined(DAWN_PLATFORM_IOS)
|
||||||
Ref<Adapter> adapter = AcquireRef(new Adapter(GetInstance(), MTLCreateSystemDefaultDevice()));
|
Ref<Adapter> adapter =
|
||||||
|
AcquireRef(new Adapter(GetInstance(), MTLCreateSystemDefaultDevice(), adapterToggles));
|
||||||
if (!GetInstance()->ConsumedError(adapter->Initialize())) {
|
if (!GetInstance()->ConsumedError(adapter->Initialize())) {
|
||||||
adapters.push_back(std::move(adapter));
|
adapters.push_back(std::move(adapter));
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,12 @@ namespace dawn::native::null {
|
||||||
|
|
||||||
// Implementation of pre-Device objects: the null adapter, null backend connection and Connect()
|
// Implementation of pre-Device objects: the null adapter, null backend connection and Connect()
|
||||||
|
|
||||||
Adapter::Adapter(InstanceBase* instance) : AdapterBase(instance, wgpu::BackendType::Null) {
|
Adapter::Adapter(InstanceBase* instance)
|
||||||
|
: Adapter(instance,
|
||||||
|
TogglesState(ToggleStage::Adapter).InheritFrom(instance->GetTogglesState())) {}
|
||||||
|
|
||||||
|
Adapter::Adapter(InstanceBase* instance, const TogglesState& adapterToggles)
|
||||||
|
: AdapterBase(instance, wgpu::BackendType::Null, adapterToggles) {
|
||||||
mVendorId = 0;
|
mVendorId = 0;
|
||||||
mDeviceId = 0;
|
mDeviceId = 0;
|
||||||
mName = "Null backend";
|
mName = "Null backend";
|
||||||
|
@ -85,11 +90,12 @@ class Backend : public BackendConnection {
|
||||||
explicit Backend(InstanceBase* instance)
|
explicit Backend(InstanceBase* instance)
|
||||||
: BackendConnection(instance, wgpu::BackendType::Null) {}
|
: BackendConnection(instance, wgpu::BackendType::Null) {}
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() override {
|
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters(
|
||||||
|
const TogglesState& adapterToggles) override {
|
||||||
// There is always a single Null adapter because it is purely CPU based and doesn't
|
// There is always a single Null adapter because it is purely CPU based and doesn't
|
||||||
// depend on the system.
|
// depend on the system.
|
||||||
std::vector<Ref<AdapterBase>> adapters;
|
std::vector<Ref<AdapterBase>> adapters;
|
||||||
Ref<Adapter> adapter = AcquireRef(new Adapter(GetInstance()));
|
Ref<Adapter> adapter = AcquireRef(new Adapter(GetInstance(), adapterToggles));
|
||||||
adapters.push_back(std::move(adapter));
|
adapters.push_back(std::move(adapter));
|
||||||
return adapters;
|
return adapters;
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,10 @@ class Device final : public DeviceBase {
|
||||||
|
|
||||||
class Adapter : public AdapterBase {
|
class Adapter : public AdapterBase {
|
||||||
public:
|
public:
|
||||||
|
// Create null adapter without providing toggles state for testing, only inherit instance's
|
||||||
|
// toggles state
|
||||||
explicit Adapter(InstanceBase* instance);
|
explicit Adapter(InstanceBase* instance);
|
||||||
|
Adapter(InstanceBase* instance, const TogglesState& adapterToggles);
|
||||||
~Adapter() override;
|
~Adapter() override;
|
||||||
|
|
||||||
// AdapterBase Implementation
|
// AdapterBase Implementation
|
||||||
|
|
|
@ -53,8 +53,10 @@ uint32_t GetVendorIdFromVendors(const char* vendor) {
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
Adapter::Adapter(InstanceBase* instance, wgpu::BackendType backendType)
|
Adapter::Adapter(InstanceBase* instance,
|
||||||
: AdapterBase(instance, backendType) {}
|
wgpu::BackendType backendType,
|
||||||
|
const TogglesState& adapterToggle)
|
||||||
|
: AdapterBase(instance, backendType, adapterToggle) {}
|
||||||
|
|
||||||
MaybeError Adapter::InitializeGLFunctions(void* (*getProc)(const char*)) {
|
MaybeError Adapter::InitializeGLFunctions(void* (*getProc)(const char*)) {
|
||||||
// Use getProc to populate the dispatch table
|
// Use getProc to populate the dispatch table
|
||||||
|
|
|
@ -23,7 +23,9 @@ namespace dawn::native::opengl {
|
||||||
|
|
||||||
class Adapter : public AdapterBase {
|
class Adapter : public AdapterBase {
|
||||||
public:
|
public:
|
||||||
Adapter(InstanceBase* instance, wgpu::BackendType backendType);
|
Adapter(InstanceBase* instance,
|
||||||
|
wgpu::BackendType backendType,
|
||||||
|
const TogglesState& adapterToggle);
|
||||||
|
|
||||||
MaybeError InitializeGLFunctions(void* (*getProc)(const char*));
|
MaybeError InitializeGLFunctions(void* (*getProc)(const char*));
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace dawn::native::opengl {
|
||||||
Backend::Backend(InstanceBase* instance, wgpu::BackendType backendType)
|
Backend::Backend(InstanceBase* instance, wgpu::BackendType backendType)
|
||||||
: BackendConnection(instance, backendType) {}
|
: BackendConnection(instance, backendType) {}
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters(const TogglesState& adapterToggles) {
|
||||||
std::vector<Ref<AdapterBase>> adapters;
|
std::vector<Ref<AdapterBase>> adapters;
|
||||||
#if DAWN_PLATFORM_IS(WINDOWS)
|
#if DAWN_PLATFORM_IS(WINDOWS)
|
||||||
const char* eglLib = "libEGL.dll";
|
const char* eglLib = "libEGL.dll";
|
||||||
|
@ -69,7 +69,7 @@ std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||||
|
|
||||||
context->MakeCurrent();
|
context->MakeCurrent();
|
||||||
|
|
||||||
auto result = DiscoverAdapters(&options);
|
auto result = DiscoverAdapters(&options, adapterToggles);
|
||||||
|
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
GetInstance()->ConsumedError(result.AcquireError());
|
GetInstance()->ConsumedError(result.AcquireError());
|
||||||
|
@ -84,7 +84,8 @@ std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* optionsBase) {
|
const AdapterDiscoveryOptionsBase* optionsBase,
|
||||||
|
const TogglesState& adapterToggles) {
|
||||||
// TODO(cwallez@chromium.org): For now only create a single OpenGL adapter because don't
|
// TODO(cwallez@chromium.org): For now only create a single OpenGL adapter because don't
|
||||||
// know how to handle MakeCurrent.
|
// know how to handle MakeCurrent.
|
||||||
DAWN_INVALID_IF(mCreatedAdapter, "The OpenGL backend can only create a single adapter.");
|
DAWN_INVALID_IF(mCreatedAdapter, "The OpenGL backend can only create a single adapter.");
|
||||||
|
@ -95,8 +96,8 @@ ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||||
|
|
||||||
DAWN_INVALID_IF(options->getProc == nullptr, "AdapterDiscoveryOptions::getProc must be set");
|
DAWN_INVALID_IF(options->getProc == nullptr, "AdapterDiscoveryOptions::getProc must be set");
|
||||||
|
|
||||||
Ref<Adapter> adapter = AcquireRef(
|
Ref<Adapter> adapter = AcquireRef(new Adapter(
|
||||||
new Adapter(GetInstance(), static_cast<wgpu::BackendType>(optionsBase->backendType)));
|
GetInstance(), static_cast<wgpu::BackendType>(optionsBase->backendType), adapterToggles));
|
||||||
DAWN_TRY(adapter->InitializeGLFunctions(options->getProc));
|
DAWN_TRY(adapter->InitializeGLFunctions(options->getProc));
|
||||||
DAWN_TRY(adapter->Initialize());
|
DAWN_TRY(adapter->Initialize());
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,11 @@ class Backend : public BackendConnection {
|
||||||
public:
|
public:
|
||||||
Backend(InstanceBase* instance, wgpu::BackendType backendType);
|
Backend(InstanceBase* instance, wgpu::BackendType backendType);
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() override;
|
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters(
|
||||||
|
const TogglesState& adapterToggles) override;
|
||||||
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* options) override;
|
const AdapterDiscoveryOptionsBase* option,
|
||||||
|
const TogglesState& adapterToggless) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mCreatedAdapter = false;
|
bool mCreatedAdapter = false;
|
||||||
|
|
|
@ -58,8 +58,9 @@ gpu_info::DriverVersion DecodeVulkanDriverVersion(uint32_t vendorID, uint32_t ve
|
||||||
|
|
||||||
Adapter::Adapter(InstanceBase* instance,
|
Adapter::Adapter(InstanceBase* instance,
|
||||||
VulkanInstance* vulkanInstance,
|
VulkanInstance* vulkanInstance,
|
||||||
VkPhysicalDevice physicalDevice)
|
VkPhysicalDevice physicalDevice,
|
||||||
: AdapterBase(instance, wgpu::BackendType::Vulkan),
|
const TogglesState& adapterToggles)
|
||||||
|
: AdapterBase(instance, wgpu::BackendType::Vulkan, adapterToggles),
|
||||||
mPhysicalDevice(physicalDevice),
|
mPhysicalDevice(physicalDevice),
|
||||||
mVulkanInstance(vulkanInstance) {}
|
mVulkanInstance(vulkanInstance) {}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,8 @@ class Adapter : public AdapterBase {
|
||||||
public:
|
public:
|
||||||
Adapter(InstanceBase* instance,
|
Adapter(InstanceBase* instance,
|
||||||
VulkanInstance* vulkanInstance,
|
VulkanInstance* vulkanInstance,
|
||||||
VkPhysicalDevice physicalDevice);
|
VkPhysicalDevice physicalDevice,
|
||||||
|
const TogglesState& adapterToggles);
|
||||||
~Adapter() override;
|
~Adapter() override;
|
||||||
|
|
||||||
// AdapterBase Implementation
|
// AdapterBase Implementation
|
||||||
|
|
|
@ -457,9 +457,9 @@ Backend::Backend(InstanceBase* instance) : BackendConnection(instance, wgpu::Bac
|
||||||
|
|
||||||
Backend::~Backend() = default;
|
Backend::~Backend() = default;
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters(const TogglesState& adapterToggles) {
|
||||||
AdapterDiscoveryOptions options;
|
AdapterDiscoveryOptions options;
|
||||||
auto result = DiscoverAdapters(&options);
|
auto result = DiscoverAdapters(&options, adapterToggles);
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
GetInstance()->ConsumedError(result.AcquireError());
|
GetInstance()->ConsumedError(result.AcquireError());
|
||||||
return {};
|
return {};
|
||||||
|
@ -468,7 +468,8 @@ std::vector<Ref<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* optionsBase) {
|
const AdapterDiscoveryOptionsBase* optionsBase,
|
||||||
|
const TogglesState& adapterToggles) {
|
||||||
ASSERT(optionsBase->backendType == WGPUBackendType_Vulkan);
|
ASSERT(optionsBase->backendType == WGPUBackendType_Vulkan);
|
||||||
|
|
||||||
const AdapterDiscoveryOptions* options =
|
const AdapterDiscoveryOptions* options =
|
||||||
|
@ -497,8 +498,8 @@ ResultOrError<std::vector<Ref<AdapterBase>>> Backend::DiscoverAdapters(
|
||||||
const std::vector<VkPhysicalDevice>& physicalDevices =
|
const std::vector<VkPhysicalDevice>& physicalDevices =
|
||||||
mVulkanInstances[icd]->GetPhysicalDevices();
|
mVulkanInstances[icd]->GetPhysicalDevices();
|
||||||
for (uint32_t i = 0; i < physicalDevices.size(); ++i) {
|
for (uint32_t i = 0; i < physicalDevices.size(); ++i) {
|
||||||
Ref<Adapter> adapter =
|
Ref<Adapter> adapter = AcquireRef(new Adapter(instance, mVulkanInstances[icd].Get(),
|
||||||
AcquireRef(new Adapter(instance, mVulkanInstances[icd].Get(), physicalDevices[i]));
|
physicalDevices[i], adapterToggles));
|
||||||
if (instance->ConsumedError(adapter->Initialize())) {
|
if (instance->ConsumedError(adapter->Initialize())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,9 +91,11 @@ class Backend : public BackendConnection {
|
||||||
|
|
||||||
MaybeError Initialize();
|
MaybeError Initialize();
|
||||||
|
|
||||||
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters() override;
|
std::vector<Ref<AdapterBase>> DiscoverDefaultAdapters(
|
||||||
|
const TogglesState& adapterToggles) override;
|
||||||
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
ResultOrError<std::vector<Ref<AdapterBase>>> DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* optionsBase) override;
|
const AdapterDiscoveryOptionsBase* optionsBase,
|
||||||
|
const TogglesState& adapterToggles) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ityp::array<ICD, Ref<VulkanInstance>, 2> mVulkanInstances = {};
|
ityp::array<ICD, Ref<VulkanInstance>, 2> mVulkanInstances = {};
|
||||||
|
|
|
@ -309,6 +309,7 @@ dawn_test("dawn_unittests") {
|
||||||
"unittests/SubresourceStorageTests.cpp",
|
"unittests/SubresourceStorageTests.cpp",
|
||||||
"unittests/SystemUtilsTests.cpp",
|
"unittests/SystemUtilsTests.cpp",
|
||||||
"unittests/ToBackendTests.cpp",
|
"unittests/ToBackendTests.cpp",
|
||||||
|
"unittests/ToggleTests.cpp",
|
||||||
"unittests/TypedIntegerTests.cpp",
|
"unittests/TypedIntegerTests.cpp",
|
||||||
"unittests/UnicodeTests.cpp",
|
"unittests/UnicodeTests.cpp",
|
||||||
"unittests/native/AllowedErrorTests.cpp",
|
"unittests/native/AllowedErrorTests.cpp",
|
||||||
|
|
|
@ -45,7 +45,19 @@ DawnNativeTest::~DawnNativeTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DawnNativeTest::SetUp() {
|
void DawnNativeTest::SetUp() {
|
||||||
instance = std::make_unique<dawn::native::Instance>();
|
// Create an instance with toggle DisallowUnsafeApis disabled, which would be inherited to
|
||||||
|
// adapter and device toggles and allow us to test unsafe apis (including experimental
|
||||||
|
// features).
|
||||||
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
||||||
|
WGPUDawnTogglesDescriptor instanceToggles = {};
|
||||||
|
instanceToggles.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
||||||
|
instanceToggles.disabledTogglesCount = 1;
|
||||||
|
instanceToggles.disabledToggles = &disallowUnsafeApisToggle;
|
||||||
|
|
||||||
|
WGPUInstanceDescriptor instanceDesc = {};
|
||||||
|
instanceDesc.nextInChain = &instanceToggles.chain;
|
||||||
|
|
||||||
|
instance = std::make_unique<dawn::native::Instance>(&instanceDesc);
|
||||||
instance->EnableAdapterBlocklist(false);
|
instance->EnableAdapterBlocklist(false);
|
||||||
platform = CreateTestPlatform();
|
platform = CreateTestPlatform();
|
||||||
dawn::native::FromAPI(instance->Get())->SetPlatformForTesting(platform.get());
|
dawn::native::FromAPI(instance->Get())->SetPlatformForTesting(platform.get());
|
||||||
|
@ -78,16 +90,7 @@ std::unique_ptr<dawn::platform::Platform> DawnNativeTest::CreateTestPlatform() {
|
||||||
}
|
}
|
||||||
|
|
||||||
WGPUDevice DawnNativeTest::CreateTestDevice() {
|
WGPUDevice DawnNativeTest::CreateTestDevice() {
|
||||||
// Disabled disallowing unsafe APIs so we can test them.
|
return adapter.CreateDevice();
|
||||||
wgpu::DeviceDescriptor deviceDescriptor = {};
|
|
||||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc = {};
|
|
||||||
deviceDescriptor.nextInChain = &deviceTogglesDesc;
|
|
||||||
|
|
||||||
const char* toggle = "disallow_unsafe_apis";
|
|
||||||
deviceTogglesDesc.disabledToggles = &toggle;
|
|
||||||
deviceTogglesDesc.disabledTogglesCount = 1;
|
|
||||||
|
|
||||||
return adapter.CreateDevice(&deviceDescriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -73,6 +73,56 @@ void printBuffer(testing::AssertionResult& result, const T* buffer, const size_t
|
||||||
result << std::endl;
|
result << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A helper class to create DawnTogglesDescriptor from test params
|
||||||
|
struct ParamTogglesHelper {
|
||||||
|
std::vector<const char*> enabledToggles;
|
||||||
|
std::vector<const char*> disabledToggles;
|
||||||
|
wgpu::DawnTogglesDescriptor togglesDesc;
|
||||||
|
|
||||||
|
// Create toggles descriptor for a given stage from test param and global test env
|
||||||
|
ParamTogglesHelper(const AdapterTestParam& testParam, dawn::native::ToggleStage requiredStage) {
|
||||||
|
for (const char* requireEnabledWorkaround : testParam.forceEnabledWorkarounds) {
|
||||||
|
const dawn::native::ToggleInfo* info =
|
||||||
|
gTestEnv->GetInstance()->GetToggleInfo(requireEnabledWorkaround);
|
||||||
|
ASSERT(info != nullptr);
|
||||||
|
if (info->stage == requiredStage) {
|
||||||
|
enabledToggles.push_back(requireEnabledWorkaround);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const char* requireDisabledWorkaround : testParam.forceDisabledWorkarounds) {
|
||||||
|
const dawn::native::ToggleInfo* info =
|
||||||
|
gTestEnv->GetInstance()->GetToggleInfo(requireDisabledWorkaround);
|
||||||
|
ASSERT(info != nullptr);
|
||||||
|
if (info->stage == requiredStage) {
|
||||||
|
disabledToggles.push_back(requireDisabledWorkaround);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const std::string& toggle : gTestEnv->GetEnabledToggles()) {
|
||||||
|
const dawn::native::ToggleInfo* info =
|
||||||
|
gTestEnv->GetInstance()->GetToggleInfo(toggle.c_str());
|
||||||
|
ASSERT(info != nullptr);
|
||||||
|
if (info->stage == requiredStage) {
|
||||||
|
enabledToggles.push_back(info->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const std::string& toggle : gTestEnv->GetDisabledToggles()) {
|
||||||
|
const dawn::native::ToggleInfo* info =
|
||||||
|
gTestEnv->GetInstance()->GetToggleInfo(toggle.c_str());
|
||||||
|
ASSERT(info != nullptr);
|
||||||
|
if (info->stage == requiredStage) {
|
||||||
|
disabledToggles.push_back(info->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
togglesDesc = {};
|
||||||
|
togglesDesc.enabledToggles = enabledToggles.data();
|
||||||
|
togglesDesc.enabledTogglesCount = enabledToggles.size();
|
||||||
|
togglesDesc.disabledToggles = disabledToggles.data();
|
||||||
|
togglesDesc.disabledTogglesCount = disabledToggles.size();
|
||||||
|
}
|
||||||
|
};
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
DawnTestBase::PrintToStringParamName::PrintToStringParamName(const char* test) : mTest(test) {}
|
DawnTestBase::PrintToStringParamName::PrintToStringParamName(const char* test) : mTest(test) {}
|
||||||
|
@ -307,7 +357,19 @@ void DawnTestEnvironment::ParseArgs(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<dawn::native::Instance> DawnTestEnvironment::CreateInstanceAndDiscoverAdapters() {
|
std::unique_ptr<dawn::native::Instance> DawnTestEnvironment::CreateInstanceAndDiscoverAdapters() {
|
||||||
auto instance = std::make_unique<dawn::native::Instance>();
|
// Create an instance with toggle DisallowUnsafeApis disabled, which would be inherited to
|
||||||
|
// adapter and device toggles and allow us to test unsafe apis (including experimental
|
||||||
|
// features).
|
||||||
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
||||||
|
WGPUDawnTogglesDescriptor instanceToggles = {};
|
||||||
|
instanceToggles.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
||||||
|
instanceToggles.disabledTogglesCount = 1;
|
||||||
|
instanceToggles.disabledToggles = &disallowUnsafeApisToggle;
|
||||||
|
|
||||||
|
WGPUInstanceDescriptor instanceDesc = {};
|
||||||
|
instanceDesc.nextInChain = &instanceToggles.chain;
|
||||||
|
|
||||||
|
auto instance = std::make_unique<dawn::native::Instance>(&instanceDesc);
|
||||||
instance->EnableBeginCaptureOnStartup(mBeginCaptureOnStartup);
|
instance->EnableBeginCaptureOnStartup(mBeginCaptureOnStartup);
|
||||||
instance->SetBackendValidationLevel(mBackendValidationLevel);
|
instance->SetBackendValidationLevel(mBackendValidationLevel);
|
||||||
instance->EnableAdapterBlocklist(false);
|
instance->EnableAdapterBlocklist(false);
|
||||||
|
@ -577,8 +639,9 @@ DawnTestBase::DawnTestBase(const AdapterTestParam& param) : mParam(param) {
|
||||||
gCurrentTest = this;
|
gCurrentTest = this;
|
||||||
|
|
||||||
DawnProcTable procs = dawn::native::GetProcs();
|
DawnProcTable procs = dawn::native::GetProcs();
|
||||||
// Override procs to provide harness-specific behavior to always select the null adapter,
|
// Override procs to provide harness-specific behavior to always select the adapter required in
|
||||||
// and to allow fixture-specific overriding of the test device with CreateDeviceImpl.
|
// testing parameter, and to allow fixture-specific overriding of the test device with
|
||||||
|
// CreateDeviceImpl.
|
||||||
procs.instanceRequestAdapter = [](WGPUInstance instance, const WGPURequestAdapterOptions*,
|
procs.instanceRequestAdapter = [](WGPUInstance instance, const WGPURequestAdapterOptions*,
|
||||||
WGPURequestAdapterCallback callback, void* userdata) {
|
WGPURequestAdapterCallback callback, void* userdata) {
|
||||||
ASSERT(gCurrentTest);
|
ASSERT(gCurrentTest);
|
||||||
|
@ -872,55 +935,26 @@ bool DawnTestBase::SupportsFeatures(const std::vector<wgpu::FeatureName>& featur
|
||||||
|
|
||||||
WGPUDevice DawnTestBase::CreateDeviceImpl(std::string isolationKey) {
|
WGPUDevice DawnTestBase::CreateDeviceImpl(std::string isolationKey) {
|
||||||
// Create the device from the adapter
|
// Create the device from the adapter
|
||||||
for (const char* forceEnabledWorkaround : mParam.forceEnabledWorkarounds) {
|
|
||||||
ASSERT(gTestEnv->GetInstance()->GetToggleInfo(forceEnabledWorkaround) != nullptr);
|
|
||||||
}
|
|
||||||
for (const char* forceDisabledWorkaround : mParam.forceDisabledWorkarounds) {
|
|
||||||
ASSERT(gTestEnv->GetInstance()->GetToggleInfo(forceDisabledWorkaround) != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const char*> forceEnabledToggles = mParam.forceEnabledWorkarounds;
|
|
||||||
std::vector<const char*> forceDisabledToggles = mParam.forceDisabledWorkarounds;
|
|
||||||
|
|
||||||
std::vector<wgpu::FeatureName> requiredFeatures = GetRequiredFeatures();
|
std::vector<wgpu::FeatureName> requiredFeatures = GetRequiredFeatures();
|
||||||
|
|
||||||
wgpu::SupportedLimits supportedLimits;
|
wgpu::SupportedLimits supportedLimits;
|
||||||
mBackendAdapter.GetLimits(reinterpret_cast<WGPUSupportedLimits*>(&supportedLimits));
|
mBackendAdapter.GetLimits(reinterpret_cast<WGPUSupportedLimits*>(&supportedLimits));
|
||||||
wgpu::RequiredLimits requiredLimits = GetRequiredLimits(supportedLimits);
|
wgpu::RequiredLimits requiredLimits = GetRequiredLimits(supportedLimits);
|
||||||
|
|
||||||
// Disabled disallowing unsafe APIs so we can test them.
|
|
||||||
forceDisabledToggles.push_back("disallow_unsafe_apis");
|
|
||||||
|
|
||||||
for (const std::string& toggle : gTestEnv->GetEnabledToggles()) {
|
|
||||||
const dawn::native::ToggleInfo* info =
|
|
||||||
gTestEnv->GetInstance()->GetToggleInfo(toggle.c_str());
|
|
||||||
ASSERT(info != nullptr);
|
|
||||||
forceEnabledToggles.push_back(info->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const std::string& toggle : gTestEnv->GetDisabledToggles()) {
|
|
||||||
const dawn::native::ToggleInfo* info =
|
|
||||||
gTestEnv->GetInstance()->GetToggleInfo(toggle.c_str());
|
|
||||||
ASSERT(info != nullptr);
|
|
||||||
forceDisabledToggles.push_back(info->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
wgpu::DeviceDescriptor deviceDescriptor = {};
|
wgpu::DeviceDescriptor deviceDescriptor = {};
|
||||||
deviceDescriptor.requiredLimits = &requiredLimits;
|
deviceDescriptor.requiredLimits = &requiredLimits;
|
||||||
deviceDescriptor.requiredFeatures = requiredFeatures.data();
|
deviceDescriptor.requiredFeatures = requiredFeatures.data();
|
||||||
deviceDescriptor.requiredFeaturesCount = requiredFeatures.size();
|
deviceDescriptor.requiredFeaturesCount = requiredFeatures.size();
|
||||||
|
|
||||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc = {};
|
|
||||||
deviceDescriptor.nextInChain = &deviceTogglesDesc;
|
|
||||||
deviceTogglesDesc.enabledToggles = forceEnabledToggles.data();
|
|
||||||
deviceTogglesDesc.enabledTogglesCount = forceEnabledToggles.size();
|
|
||||||
deviceTogglesDesc.disabledToggles = forceDisabledToggles.data();
|
|
||||||
deviceTogglesDesc.disabledTogglesCount = forceDisabledToggles.size();
|
|
||||||
|
|
||||||
wgpu::DawnCacheDeviceDescriptor cacheDesc = {};
|
wgpu::DawnCacheDeviceDescriptor cacheDesc = {};
|
||||||
deviceTogglesDesc.nextInChain = &cacheDesc;
|
deviceDescriptor.nextInChain = &cacheDesc;
|
||||||
cacheDesc.isolationKey = isolationKey.c_str();
|
cacheDesc.isolationKey = isolationKey.c_str();
|
||||||
|
|
||||||
|
// Note that DisallowUnsafeApis is disabled when creating testing instance and would be
|
||||||
|
// inherited to all adapters' toggles set.
|
||||||
|
ParamTogglesHelper deviceTogglesHelper(mParam, dawn::native::ToggleStage::Device);
|
||||||
|
cacheDesc.nextInChain = &deviceTogglesHelper.togglesDesc;
|
||||||
|
|
||||||
return mBackendAdapter.CreateDevice(&deviceDescriptor);
|
return mBackendAdapter.CreateDevice(&deviceDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,7 +965,9 @@ wgpu::Device DawnTestBase::CreateDevice(std::string isolationKey) {
|
||||||
// to CreateDeviceImpl.
|
// to CreateDeviceImpl.
|
||||||
mNextIsolationKeyQueue.push(std::move(isolationKey));
|
mNextIsolationKeyQueue.push(std::move(isolationKey));
|
||||||
|
|
||||||
// This descriptor doesn't matter since device selection is overriden by CreateDeviceImpl.
|
// RequestDevice is overriden by CreateDeviceImpl and device descriptor is ignored by it. Give
|
||||||
|
// an empty descriptor.
|
||||||
|
// TODO(dawn:1684): Replace empty DeviceDescriptor with nullptr after Dawn wire support it.
|
||||||
wgpu::DeviceDescriptor deviceDesc = {};
|
wgpu::DeviceDescriptor deviceDesc = {};
|
||||||
mAdapter.RequestDevice(
|
mAdapter.RequestDevice(
|
||||||
&deviceDesc,
|
&deviceDesc,
|
||||||
|
@ -988,7 +1024,9 @@ void DawnTestBase::SetUp() {
|
||||||
"_" + ::testing::UnitTest::GetInstance()->current_test_info()->name();
|
"_" + ::testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||||
mWireHelper->BeginWireTrace(traceName.c_str());
|
mWireHelper->BeginWireTrace(traceName.c_str());
|
||||||
|
|
||||||
// These options are unused since adapter selection is overriden to use the test params
|
// RequestAdapter is overriden to ignore RequestAdapterOptions, but dawn_wire requires a valid
|
||||||
|
// pointer, so give a empty option.
|
||||||
|
// TODO(dawn:1684): Replace empty RequestAdapterOptions with nullptr after Dawn wire support it.
|
||||||
wgpu::RequestAdapterOptions options = {};
|
wgpu::RequestAdapterOptions options = {};
|
||||||
mInstance.RequestAdapter(
|
mInstance.RequestAdapter(
|
||||||
&options,
|
&options,
|
||||||
|
|
|
@ -86,7 +86,8 @@ TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) {
|
||||||
// Adapter support the feature
|
// Adapter support the feature
|
||||||
IsDP4aSupportedOnAdapter() &&
|
IsDP4aSupportedOnAdapter() &&
|
||||||
// Proper toggle, disallow_unsafe_apis and use_dxc if d3d12
|
// Proper toggle, disallow_unsafe_apis and use_dxc if d3d12
|
||||||
// Note that "disallow_unsafe_apis" is always disabled in DawnTestBase::CreateDeviceImpl.
|
// Note that "disallow_unsafe_apis" is always disabled in
|
||||||
|
// DawnTestEnvironment::CreateInstanceAndDiscoverAdapters.
|
||||||
!HasToggleEnabled("disallow_unsafe_apis") && UseDxcEnabledOrNonD3D12();
|
!HasToggleEnabled("disallow_unsafe_apis") && UseDxcEnabledOrNonD3D12();
|
||||||
const bool deviceSupportDP4AFeature =
|
const bool deviceSupportDP4AFeature =
|
||||||
device.HasFeature(wgpu::FeatureName::ChromiumExperimentalDp4a);
|
device.HasFeature(wgpu::FeatureName::ChromiumExperimentalDp4a);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "dawn/native/Features.h"
|
#include "dawn/native/Features.h"
|
||||||
#include "dawn/native/Instance.h"
|
#include "dawn/native/Instance.h"
|
||||||
|
#include "dawn/native/Toggles.h"
|
||||||
#include "dawn/native/null/DeviceNull.h"
|
#include "dawn/native/null/DeviceNull.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
@ -24,7 +25,11 @@ class FeatureTests : public testing::Test {
|
||||||
FeatureTests()
|
FeatureTests()
|
||||||
: testing::Test(),
|
: testing::Test(),
|
||||||
mInstanceBase(dawn::native::InstanceBase::Create()),
|
mInstanceBase(dawn::native::InstanceBase::Create()),
|
||||||
mAdapterBase(mInstanceBase.Get()) {}
|
mAdapterBase(mInstanceBase.Get()),
|
||||||
|
mUnsafeAdapterBase(
|
||||||
|
mInstanceBase.Get(),
|
||||||
|
dawn::native::TogglesState(dawn::native::ToggleStage::Adapter)
|
||||||
|
.SetForTesting(dawn::native::Toggle::DisallowUnsafeAPIs, false, false)) {}
|
||||||
|
|
||||||
std::vector<wgpu::FeatureName> GetAllFeatureNames() {
|
std::vector<wgpu::FeatureName> GetAllFeatureNames() {
|
||||||
std::vector<wgpu::FeatureName> allFeatureNames(kTotalFeaturesCount);
|
std::vector<wgpu::FeatureName> allFeatureNames(kTotalFeaturesCount);
|
||||||
|
@ -38,8 +43,13 @@ class FeatureTests : public testing::Test {
|
||||||
static_cast<size_t>(dawn::native::Feature::EnumCount);
|
static_cast<size_t>(dawn::native::Feature::EnumCount);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// By default DisallowUnsafeAPIs is enabled in this instance.
|
||||||
Ref<dawn::native::InstanceBase> mInstanceBase;
|
Ref<dawn::native::InstanceBase> mInstanceBase;
|
||||||
|
// The adapter that inherit toggles states from the instance, also have DisallowUnsafeAPIs
|
||||||
|
// enabled.
|
||||||
dawn::native::null::Adapter mAdapterBase;
|
dawn::native::null::Adapter mAdapterBase;
|
||||||
|
// The adapter that override DisallowUnsafeAPIs to disabled in toggles state.
|
||||||
|
dawn::native::null::Adapter mUnsafeAdapterBase;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test the creation of a device will fail if the requested feature is not supported on the
|
// Test the creation of a device will fail if the requested feature is not supported on the
|
||||||
|
@ -52,14 +62,11 @@ TEST_F(FeatureTests, AdapterWithRequiredFeatureDisabled) {
|
||||||
std::vector<wgpu::FeatureName> featureNamesWithoutOne = kAllFeatureNames;
|
std::vector<wgpu::FeatureName> featureNamesWithoutOne = kAllFeatureNames;
|
||||||
featureNamesWithoutOne.erase(featureNamesWithoutOne.begin() + i);
|
featureNamesWithoutOne.erase(featureNamesWithoutOne.begin() + i);
|
||||||
|
|
||||||
mAdapterBase.SetSupportedFeatures(featureNamesWithoutOne);
|
// Test that the adapter with unsafe apis disallowed validate features as expected.
|
||||||
dawn::native::Adapter adapterWithoutFeature(&mAdapterBase);
|
|
||||||
|
|
||||||
// Test that creating device with and without DisallowUnsafeApis toggle disabled will both
|
|
||||||
// failed.
|
|
||||||
|
|
||||||
// Without disabling DisallowUnsafeApis toggle
|
|
||||||
{
|
{
|
||||||
|
mAdapterBase.SetSupportedFeatures(featureNamesWithoutOne);
|
||||||
|
dawn::native::Adapter adapterWithoutFeature(&mAdapterBase);
|
||||||
|
|
||||||
wgpu::DeviceDescriptor deviceDescriptor;
|
wgpu::DeviceDescriptor deviceDescriptor;
|
||||||
wgpu::FeatureName featureName = FeatureEnumToAPIFeature(notSupportedFeature);
|
wgpu::FeatureName featureName = FeatureEnumToAPIFeature(notSupportedFeature);
|
||||||
deviceDescriptor.requiredFeatures = &featureName;
|
deviceDescriptor.requiredFeatures = &featureName;
|
||||||
|
@ -70,48 +77,46 @@ TEST_F(FeatureTests, AdapterWithRequiredFeatureDisabled) {
|
||||||
ASSERT_EQ(nullptr, deviceWithFeature);
|
ASSERT_EQ(nullptr, deviceWithFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disabling DisallowUnsafeApis toggle
|
// Test that the adapter with unsafe apis allowed validate features as expected.
|
||||||
{
|
{
|
||||||
wgpu::DeviceDescriptor unsafeDeviceDescriptor;
|
mUnsafeAdapterBase.SetSupportedFeatures(featureNamesWithoutOne);
|
||||||
wgpu::FeatureName featureName = FeatureEnumToAPIFeature(notSupportedFeature);
|
dawn::native::Adapter adapterWithoutFeature(&mUnsafeAdapterBase);
|
||||||
unsafeDeviceDescriptor.requiredFeatures = &featureName;
|
|
||||||
unsafeDeviceDescriptor.requiredFeaturesCount = 1;
|
|
||||||
|
|
||||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
wgpu::DeviceDescriptor deviceDescriptor;
|
||||||
unsafeDeviceDescriptor.nextInChain = &deviceTogglesDesc;
|
wgpu::FeatureName featureName = FeatureEnumToAPIFeature(notSupportedFeature);
|
||||||
const char* toggle = "disallow_unsafe_apis";
|
deviceDescriptor.requiredFeatures = &featureName;
|
||||||
deviceTogglesDesc.disabledToggles = &toggle;
|
deviceDescriptor.requiredFeaturesCount = 1;
|
||||||
deviceTogglesDesc.disabledTogglesCount = 1;
|
|
||||||
|
|
||||||
WGPUDevice deviceWithFeature = adapterWithoutFeature.CreateDevice(
|
WGPUDevice deviceWithFeature = adapterWithoutFeature.CreateDevice(
|
||||||
reinterpret_cast<const WGPUDeviceDescriptor*>(&unsafeDeviceDescriptor));
|
reinterpret_cast<const WGPUDeviceDescriptor*>(&deviceDescriptor));
|
||||||
ASSERT_EQ(nullptr, deviceWithFeature);
|
ASSERT_EQ(nullptr, deviceWithFeature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test creating device requiring a supported feature can succeed (with DisallowUnsafeApis guarded
|
// Test creating device requiring a supported feature can succeed (with DisallowUnsafeApis adapter
|
||||||
// for experimental features), and Device.GetEnabledFeatures() can return the names of the enabled
|
// toggle disabled for experimental features), and Device.GetEnabledFeatures() can return the names
|
||||||
// features correctly.
|
// of the enabled features correctly.
|
||||||
TEST_F(FeatureTests, RequireAndGetEnabledFeatures) {
|
TEST_F(FeatureTests, RequireAndGetEnabledFeatures) {
|
||||||
dawn::native::Adapter adapter(&mAdapterBase);
|
dawn::native::Adapter adapter(&mAdapterBase);
|
||||||
|
dawn::native::Adapter unsafeAdapter(&mUnsafeAdapterBase);
|
||||||
dawn::native::FeaturesInfo featuresInfo;
|
dawn::native::FeaturesInfo featuresInfo;
|
||||||
|
|
||||||
for (size_t i = 0; i < kTotalFeaturesCount; ++i) {
|
for (size_t i = 0; i < kTotalFeaturesCount; ++i) {
|
||||||
dawn::native::Feature feature = static_cast<dawn::native::Feature>(i);
|
dawn::native::Feature feature = static_cast<dawn::native::Feature>(i);
|
||||||
wgpu::FeatureName featureName = FeatureEnumToAPIFeature(feature);
|
wgpu::FeatureName featureName = FeatureEnumToAPIFeature(feature);
|
||||||
|
|
||||||
// Test with DisallowUnsafeApis not disabled.
|
wgpu::DeviceDescriptor deviceDescriptor;
|
||||||
{
|
deviceDescriptor.requiredFeatures = &featureName;
|
||||||
wgpu::DeviceDescriptor deviceDescriptor;
|
deviceDescriptor.requiredFeaturesCount = 1;
|
||||||
deviceDescriptor.requiredFeatures = &featureName;
|
|
||||||
deviceDescriptor.requiredFeaturesCount = 1;
|
|
||||||
|
|
||||||
|
// Test with the adapter with DisallowUnsafeApis adapter toggles not disabled.
|
||||||
|
{
|
||||||
dawn::native::DeviceBase* deviceBase = dawn::native::FromAPI(adapter.CreateDevice(
|
dawn::native::DeviceBase* deviceBase = dawn::native::FromAPI(adapter.CreateDevice(
|
||||||
reinterpret_cast<const WGPUDeviceDescriptor*>(&deviceDescriptor)));
|
reinterpret_cast<const WGPUDeviceDescriptor*>(&deviceDescriptor)));
|
||||||
|
|
||||||
// Device creation should fail if requiring experimental features without disabling
|
// Creating a device with experimental feature requires the adapter disables
|
||||||
// DisallowUnsafeApis
|
// DisallowUnsafeApis, otherwise a validation error.
|
||||||
if (featuresInfo.GetFeatureInfo(featureName)->featureState ==
|
if (featuresInfo.GetFeatureInfo(featureName)->featureState ==
|
||||||
dawn::native::FeatureInfo::FeatureState::Experimental) {
|
dawn::native::FeatureInfo::FeatureState::Experimental) {
|
||||||
ASSERT_EQ(nullptr, deviceBase);
|
ASSERT_EQ(nullptr, deviceBase);
|
||||||
|
@ -126,20 +131,11 @@ TEST_F(FeatureTests, RequireAndGetEnabledFeatures) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test with DisallowUnsafeApis disabled, creating device should always succeed.
|
// Test with the adapter with DisallowUnsafeApis toggles disabled, creating device should
|
||||||
|
// always succeed.
|
||||||
{
|
{
|
||||||
wgpu::DeviceDescriptor unsafeDeviceDescriptor;
|
dawn::native::DeviceBase* deviceBase = dawn::native::FromAPI(unsafeAdapter.CreateDevice(
|
||||||
unsafeDeviceDescriptor.requiredFeatures = &featureName;
|
reinterpret_cast<const WGPUDeviceDescriptor*>(&deviceDescriptor)));
|
||||||
unsafeDeviceDescriptor.requiredFeaturesCount = 1;
|
|
||||||
|
|
||||||
const char* const disableToggles[] = {"disallow_unsafe_apis"};
|
|
||||||
wgpu::DawnTogglesDescriptor toggleDesc;
|
|
||||||
toggleDesc.disabledToggles = disableToggles;
|
|
||||||
toggleDesc.disabledTogglesCount = 1;
|
|
||||||
unsafeDeviceDescriptor.nextInChain = &toggleDesc;
|
|
||||||
|
|
||||||
dawn::native::DeviceBase* deviceBase = dawn::native::FromAPI(adapter.CreateDevice(
|
|
||||||
reinterpret_cast<const WGPUDeviceDescriptor*>(&unsafeDeviceDescriptor)));
|
|
||||||
|
|
||||||
ASSERT_NE(nullptr, deviceBase);
|
ASSERT_NE(nullptr, deviceBase);
|
||||||
ASSERT_EQ(1u, deviceBase->APIEnumerateFeatures(nullptr));
|
ASSERT_EQ(1u, deviceBase->APIEnumerateFeatures(nullptr));
|
||||||
|
|
|
@ -0,0 +1,202 @@
|
||||||
|
// Copyright 2023 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 <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "dawn/dawn_proc.h"
|
||||||
|
#include "dawn/native/Adapter.h"
|
||||||
|
#include "dawn/native/DawnNative.h"
|
||||||
|
#include "dawn/native/Device.h"
|
||||||
|
#include "dawn/native/Instance.h"
|
||||||
|
#include "dawn/native/Toggles.h"
|
||||||
|
#include "dawn/native/dawn_platform.h"
|
||||||
|
#include "dawn/tests/MockCallback.h"
|
||||||
|
#include "dawn/utils/SystemUtils.h"
|
||||||
|
#include "dawn/utils/WGPUHelpers.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using testing::Contains;
|
||||||
|
using testing::MockCallback;
|
||||||
|
using testing::NotNull;
|
||||||
|
using testing::SaveArg;
|
||||||
|
using testing::StrEq;
|
||||||
|
|
||||||
|
class InstanceToggleTest : public testing::Test {
|
||||||
|
protected:
|
||||||
|
void SetUp() override { dawnProcSetProcs(&dawn::native::GetProcs()); }
|
||||||
|
|
||||||
|
void TearDown() override { dawnProcSetProcs(nullptr); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test that instance toggles are set by requirement or default as expected.
|
||||||
|
TEST_F(InstanceToggleTest, InstanceTogglesSet) {
|
||||||
|
auto validateInstanceToggles = [](const dawn::native::Instance* nativeInstance,
|
||||||
|
std::initializer_list<const char*> enableToggles,
|
||||||
|
std::initializer_list<const char*> disableToggles) {
|
||||||
|
const dawn::native::InstanceBase* instance = dawn::native::FromAPI(nativeInstance->Get());
|
||||||
|
const dawn::native::TogglesState& instanceTogglesState = instance->GetTogglesState();
|
||||||
|
std::vector<const char*> enabledToggles = instanceTogglesState.GetEnabledToggleNames();
|
||||||
|
std::vector<const char*> disabledToggles = instanceTogglesState.GetDisabledToggleNames();
|
||||||
|
EXPECT_EQ(disabledToggles.size(), disableToggles.size());
|
||||||
|
EXPECT_EQ(enabledToggles.size(), enableToggles.size());
|
||||||
|
for (auto* enableToggle : enableToggles) {
|
||||||
|
EXPECT_THAT(enabledToggles, Contains(StrEq(enableToggle)));
|
||||||
|
}
|
||||||
|
for (auto* disableToggle : disableToggles) {
|
||||||
|
EXPECT_THAT(disabledToggles, Contains(StrEq(disableToggle)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create instance with no toggles descriptor
|
||||||
|
{
|
||||||
|
std::unique_ptr<dawn::native::Instance> instance;
|
||||||
|
|
||||||
|
// Create an instance with default toggles, where DisallowUnsafeApis is enabled.
|
||||||
|
instance = std::make_unique<dawn::native::Instance>();
|
||||||
|
validateInstanceToggles(instance.get(), {"disallow_unsafe_apis"}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create instance with empty toggles descriptor
|
||||||
|
{
|
||||||
|
std::unique_ptr<dawn::native::Instance> instance;
|
||||||
|
|
||||||
|
// Make an instance descriptor chaining an empty toggles descriptor
|
||||||
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
||||||
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
||||||
|
|
||||||
|
WGPUInstanceDescriptor instanceDesc = {};
|
||||||
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
||||||
|
|
||||||
|
// Create an instance with default toggles, where DisallowUnsafeApis is enabled.
|
||||||
|
instance = std::make_unique<dawn::native::Instance>(&instanceDesc);
|
||||||
|
validateInstanceToggles(instance.get(), {"disallow_unsafe_apis"}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create instance with DisallowUnsafeAPIs explicitly enabled in toggles descriptor
|
||||||
|
{
|
||||||
|
std::unique_ptr<dawn::native::Instance> instance;
|
||||||
|
|
||||||
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
||||||
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
||||||
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
||||||
|
instanceTogglesDesc.enabledTogglesCount = 1;
|
||||||
|
instanceTogglesDesc.enabledToggles = &disallowUnsafeApisToggle;
|
||||||
|
|
||||||
|
WGPUInstanceDescriptor instanceDesc = {};
|
||||||
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
||||||
|
|
||||||
|
// Create an instance with DisallowUnsafeApis explicitly enabled.
|
||||||
|
instance = std::make_unique<dawn::native::Instance>(&instanceDesc);
|
||||||
|
validateInstanceToggles(instance.get(), {disallowUnsafeApisToggle}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create instance with DisallowUnsafeAPIs explicitly disabled in toggles descriptor
|
||||||
|
{
|
||||||
|
std::unique_ptr<dawn::native::Instance> instance;
|
||||||
|
|
||||||
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
||||||
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
||||||
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
||||||
|
instanceTogglesDesc.disabledTogglesCount = 1;
|
||||||
|
instanceTogglesDesc.disabledToggles = &disallowUnsafeApisToggle;
|
||||||
|
|
||||||
|
WGPUInstanceDescriptor instanceDesc = {};
|
||||||
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
||||||
|
|
||||||
|
// Create an instance with DisallowUnsafeApis explicitly disabled.
|
||||||
|
instance = std::make_unique<dawn::native::Instance>(&instanceDesc);
|
||||||
|
validateInstanceToggles(instance.get(), {}, {disallowUnsafeApisToggle});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that instance toggles are inherited to the adapters and devices it creates.
|
||||||
|
TEST_F(InstanceToggleTest, InstanceTogglesInheritToAdapterAndDevice) {
|
||||||
|
auto validateInstanceTogglesInheritedToAdapter = [&](dawn::native::Instance* nativeInstance) {
|
||||||
|
dawn::native::InstanceBase* instance = dawn::native::FromAPI(nativeInstance->Get());
|
||||||
|
const dawn::native::TogglesState& instanceTogglesState = instance->GetTogglesState();
|
||||||
|
|
||||||
|
// Discover adapters with default toggles.
|
||||||
|
instance->DiscoverDefaultAdapters();
|
||||||
|
|
||||||
|
// Get the adapter created by instance with default toggles.
|
||||||
|
dawn::native::AdapterBase* nullAdapter = nullptr;
|
||||||
|
for (auto& adapter : instance->GetAdapters()) {
|
||||||
|
if (adapter->GetBackendType() == wgpu::BackendType::Null) {
|
||||||
|
nullAdapter = adapter.Get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT_NE(nullAdapter, nullptr);
|
||||||
|
auto& adapterTogglesState = nullAdapter->GetTogglesState();
|
||||||
|
|
||||||
|
// Creater a default device.
|
||||||
|
dawn::native::DeviceBase* nullDevice = nullAdapter->APICreateDevice();
|
||||||
|
|
||||||
|
// Check instance toggles are inherited by adapter and device.
|
||||||
|
dawn::native::TogglesInfo togglesInfo;
|
||||||
|
static_assert(std::is_same_v<std::underlying_type_t<dawn::native::Toggle>, int>);
|
||||||
|
for (int i = 0; i < static_cast<int>(dawn::native::Toggle::EnumCount); i++) {
|
||||||
|
dawn::native::Toggle toggle = static_cast<dawn::native::Toggle>(i);
|
||||||
|
if (togglesInfo.GetToggleInfo(toggle)->stage != dawn::native::ToggleStage::Instance) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(instanceTogglesState.IsSet(toggle), adapterTogglesState.IsSet(toggle));
|
||||||
|
EXPECT_EQ(instanceTogglesState.IsEnabled(toggle),
|
||||||
|
adapterTogglesState.IsEnabled(toggle));
|
||||||
|
EXPECT_EQ(instanceTogglesState.IsEnabled(toggle), nullDevice->IsToggleEnabled(toggle));
|
||||||
|
}
|
||||||
|
|
||||||
|
nullDevice->Release();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create instance with DisallowUnsafeAPIs explicitly enabled in toggles descriptor
|
||||||
|
{
|
||||||
|
std::unique_ptr<dawn::native::Instance> instance;
|
||||||
|
|
||||||
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
||||||
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
||||||
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
||||||
|
instanceTogglesDesc.enabledTogglesCount = 1;
|
||||||
|
instanceTogglesDesc.enabledToggles = &disallowUnsafeApisToggle;
|
||||||
|
|
||||||
|
WGPUInstanceDescriptor instanceDesc = {};
|
||||||
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
||||||
|
|
||||||
|
// Create an instance with DisallowUnsafeApis explicitly enabled.
|
||||||
|
instance = std::make_unique<dawn::native::Instance>(&instanceDesc);
|
||||||
|
validateInstanceTogglesInheritedToAdapter(instance.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create instance with DisallowUnsafeAPIs explicitly disabled in toggles descriptor
|
||||||
|
{
|
||||||
|
std::unique_ptr<dawn::native::Instance> instance;
|
||||||
|
|
||||||
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
||||||
|
WGPUDawnTogglesDescriptor instanceTogglesDesc = {};
|
||||||
|
instanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
||||||
|
instanceTogglesDesc.disabledTogglesCount = 1;
|
||||||
|
instanceTogglesDesc.disabledToggles = &disallowUnsafeApisToggle;
|
||||||
|
|
||||||
|
WGPUInstanceDescriptor instanceDesc = {};
|
||||||
|
instanceDesc.nextInChain = &instanceTogglesDesc.chain;
|
||||||
|
|
||||||
|
// Create an instance with DisallowUnsafeApis explicitly enabled.
|
||||||
|
instance = std::make_unique<dawn::native::Instance>(&instanceDesc);
|
||||||
|
validateInstanceTogglesInheritedToAdapter(instance.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // anonymous namespace
|
|
@ -16,8 +16,10 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "dawn/dawn_proc.h"
|
#include "dawn/dawn_proc.h"
|
||||||
|
#include "dawn/native/Adapter.h"
|
||||||
#include "dawn/native/DawnNative.h"
|
#include "dawn/native/DawnNative.h"
|
||||||
#include "dawn/native/Device.h"
|
#include "dawn/native/Device.h"
|
||||||
|
#include "dawn/native/Toggles.h"
|
||||||
#include "dawn/native/dawn_platform.h"
|
#include "dawn/native/dawn_platform.h"
|
||||||
#include "dawn/tests/MockCallback.h"
|
#include "dawn/tests/MockCallback.h"
|
||||||
#include "dawn/utils/SystemUtils.h"
|
#include "dawn/utils/SystemUtils.h"
|
||||||
|
@ -37,7 +39,20 @@ class DeviceCreationTest : public testing::Test {
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
dawnProcSetProcs(&dawn::native::GetProcs());
|
dawnProcSetProcs(&dawn::native::GetProcs());
|
||||||
|
|
||||||
instance = std::make_unique<dawn::native::Instance>();
|
WGPUInstanceDescriptor safeInstanceDesc = {};
|
||||||
|
|
||||||
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
||||||
|
WGPUDawnTogglesDescriptor unsafeInstanceTogglesDesc = {};
|
||||||
|
unsafeInstanceTogglesDesc.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
||||||
|
unsafeInstanceTogglesDesc.disabledTogglesCount = 1;
|
||||||
|
unsafeInstanceTogglesDesc.disabledToggles = &disallowUnsafeApisToggle;
|
||||||
|
|
||||||
|
WGPUInstanceDescriptor unsafeInstanceDesc = {};
|
||||||
|
unsafeInstanceDesc.nextInChain = &unsafeInstanceTogglesDesc.chain;
|
||||||
|
|
||||||
|
// Create an instance with default toggles, where DisallowUnsafeApis is enabled, and create
|
||||||
|
// an adapter from it.
|
||||||
|
instance = std::make_unique<dawn::native::Instance>(&safeInstanceDesc);
|
||||||
instance->DiscoverDefaultAdapters();
|
instance->DiscoverDefaultAdapters();
|
||||||
for (dawn::native::Adapter& nativeAdapter : instance->GetAdapters()) {
|
for (dawn::native::Adapter& nativeAdapter : instance->GetAdapters()) {
|
||||||
wgpu::AdapterProperties properties;
|
wgpu::AdapterProperties properties;
|
||||||
|
@ -48,17 +63,41 @@ class DeviceCreationTest : public testing::Test {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create an instance with toggle DisallowUnsafeApis disabled, and create an unsafe adapter
|
||||||
|
// from it.
|
||||||
|
unsafeInstance = std::make_unique<dawn::native::Instance>(&unsafeInstanceDesc);
|
||||||
|
unsafeInstance->DiscoverDefaultAdapters();
|
||||||
|
for (dawn::native::Adapter& nativeAdapter : unsafeInstance->GetAdapters()) {
|
||||||
|
wgpu::AdapterProperties properties;
|
||||||
|
nativeAdapter.GetProperties(&properties);
|
||||||
|
|
||||||
|
if (properties.backendType == wgpu::BackendType::Null) {
|
||||||
|
unsafeAdapter = wgpu::Adapter(nativeAdapter.Get());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT_NE(adapter, nullptr);
|
ASSERT_NE(adapter, nullptr);
|
||||||
|
ASSERT_NE(unsafeAdapter, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TearDown() override {
|
void TearDown() override {
|
||||||
adapter = nullptr;
|
adapter = nullptr;
|
||||||
|
unsafeAdapter = nullptr;
|
||||||
instance = nullptr;
|
instance = nullptr;
|
||||||
|
unsafeInstance = nullptr;
|
||||||
dawnProcSetProcs(nullptr);
|
dawnProcSetProcs(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr size_t kTotalFeaturesCount =
|
||||||
|
static_cast<size_t>(dawn::native::Feature::EnumCount);
|
||||||
|
|
||||||
std::unique_ptr<dawn::native::Instance> instance;
|
std::unique_ptr<dawn::native::Instance> instance;
|
||||||
|
std::unique_ptr<dawn::native::Instance> unsafeInstance;
|
||||||
wgpu::Adapter adapter;
|
wgpu::Adapter adapter;
|
||||||
|
wgpu::Adapter unsafeAdapter;
|
||||||
|
dawn::native::FeaturesInfo featuresInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test successful call to CreateDevice with no descriptor
|
// Test successful call to CreateDevice with no descriptor
|
||||||
|
@ -91,23 +130,53 @@ TEST_F(DeviceCreationTest, CreateDeviceWithTogglesSuccess) {
|
||||||
EXPECT_THAT(toggles, Contains(StrEq(toggle)));
|
EXPECT_THAT(toggles, Contains(StrEq(toggle)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test features guarded by toggles are validated when creating devices.
|
// Test experimental features are guarded by DisallowUnsafeApis adapter toggle, it is inherited from
|
||||||
TEST_F(DeviceCreationTest, CreateDeviceRequiringFeaturesGuardedByToggle) {
|
// instance but can be overriden by device toggles.
|
||||||
std::vector<wgpu::FeatureName> featuresGuardedByToggle = {
|
TEST_F(DeviceCreationTest, CreateDeviceRequiringExperimentalFeatures) {
|
||||||
wgpu::FeatureName::ShaderF16, wgpu::FeatureName::ChromiumExperimentalDp4a};
|
// Ensure that DisallowUnsafeApis adapter toggle is enabled on safe adapter.
|
||||||
|
auto safeAdapterBase = dawn::native::FromAPI(adapter.Get());
|
||||||
|
ASSERT_TRUE(
|
||||||
|
safeAdapterBase->GetTogglesState().IsEnabled(dawn::native::Toggle::DisallowUnsafeAPIs));
|
||||||
|
// Ensure that DisallowUnsafeApis adapter toggle is disabled on unsafe adapter.
|
||||||
|
auto unsafeAdapterBase = dawn::native::FromAPI(unsafeAdapter.Get());
|
||||||
|
ASSERT_FALSE(
|
||||||
|
unsafeAdapterBase->GetTogglesState().IsEnabled(dawn::native::Toggle::DisallowUnsafeAPIs));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < kTotalFeaturesCount; i++) {
|
||||||
|
dawn::native::Feature feature = static_cast<dawn::native::Feature>(i);
|
||||||
|
wgpu::FeatureName featureName = dawn::native::FeatureEnumToAPIFeature(feature);
|
||||||
|
|
||||||
|
// Only test experimental features.
|
||||||
|
if (featuresInfo.GetFeatureInfo(featureName)->featureState ==
|
||||||
|
dawn::native::FeatureInfo::FeatureState::Stable) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto feature : featuresGuardedByToggle) {
|
|
||||||
wgpu::DeviceDescriptor deviceDescriptor;
|
wgpu::DeviceDescriptor deviceDescriptor;
|
||||||
deviceDescriptor.requiredFeatures = &feature;
|
deviceDescriptor.requiredFeatures = &featureName;
|
||||||
deviceDescriptor.requiredFeaturesCount = 1;
|
deviceDescriptor.requiredFeaturesCount = 1;
|
||||||
|
|
||||||
// Test creating device without toggle would fail.
|
// Test creating device on the adapter with DisallowUnsafeApis toggle enabled would fail.
|
||||||
{
|
{
|
||||||
wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
|
wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
|
||||||
EXPECT_EQ(device, nullptr);
|
EXPECT_EQ(device, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test creating device without DisallowUnsafeApis toggle disabled.
|
// Test creating device on the adapter with DisallowUnsafeApis toggle disabled would
|
||||||
|
// succeed.
|
||||||
|
{
|
||||||
|
// unsafeAdapter has DisallowUnsafeApis adapter toggle disabled.
|
||||||
|
wgpu::Device device = unsafeAdapter.CreateDevice(&deviceDescriptor);
|
||||||
|
EXPECT_NE(device, nullptr);
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, device.EnumerateFeatures(nullptr));
|
||||||
|
wgpu::FeatureName enabledFeature;
|
||||||
|
device.EnumerateFeatures(&enabledFeature);
|
||||||
|
EXPECT_EQ(enabledFeature, featureName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test creating device with DisallowUnsafeApis disabled in device toggle descriptor will
|
||||||
|
// success on both adapter, as device toggles will override the inherited adapter toggles.
|
||||||
{
|
{
|
||||||
const char* const disableToggles[] = {"disallow_unsafe_apis"};
|
const char* const disableToggles[] = {"disallow_unsafe_apis"};
|
||||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
||||||
|
@ -115,14 +184,49 @@ TEST_F(DeviceCreationTest, CreateDeviceRequiringFeaturesGuardedByToggle) {
|
||||||
deviceTogglesDesc.disabledTogglesCount = 1;
|
deviceTogglesDesc.disabledTogglesCount = 1;
|
||||||
deviceDescriptor.nextInChain = &deviceTogglesDesc;
|
deviceDescriptor.nextInChain = &deviceTogglesDesc;
|
||||||
|
|
||||||
wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
|
// Test on adapter with DisallowUnsafeApis enabled.
|
||||||
EXPECT_NE(device, nullptr);
|
{
|
||||||
|
wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
|
||||||
|
EXPECT_NE(device, nullptr);
|
||||||
|
|
||||||
ASSERT_EQ(1u, device.EnumerateFeatures(nullptr));
|
ASSERT_EQ(1u, device.EnumerateFeatures(nullptr));
|
||||||
wgpu::FeatureName enabledFeature;
|
wgpu::FeatureName enabledFeature;
|
||||||
device.EnumerateFeatures(&enabledFeature);
|
device.EnumerateFeatures(&enabledFeature);
|
||||||
EXPECT_EQ(enabledFeature, feature);
|
EXPECT_EQ(enabledFeature, featureName);
|
||||||
device.Release();
|
}
|
||||||
|
|
||||||
|
// Test on adapter with DisallowUnsafeApis disabled.
|
||||||
|
{
|
||||||
|
wgpu::Device device = unsafeAdapter.CreateDevice(&deviceDescriptor);
|
||||||
|
EXPECT_NE(device, nullptr);
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, device.EnumerateFeatures(nullptr));
|
||||||
|
wgpu::FeatureName enabledFeature;
|
||||||
|
device.EnumerateFeatures(&enabledFeature);
|
||||||
|
EXPECT_EQ(enabledFeature, featureName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test creating device with DisallowUnsafeApis enabled in device toggle descriptor will
|
||||||
|
// fail on both adapter, as device toggles will override the inherited adapter toggles.
|
||||||
|
{
|
||||||
|
const char* const enableToggles[] = {"disallow_unsafe_apis"};
|
||||||
|
wgpu::DawnTogglesDescriptor deviceToggleDesc;
|
||||||
|
deviceToggleDesc.enabledToggles = enableToggles;
|
||||||
|
deviceToggleDesc.enabledTogglesCount = 1;
|
||||||
|
deviceDescriptor.nextInChain = &deviceToggleDesc;
|
||||||
|
|
||||||
|
// Test on adapter with DisallowUnsafeApis enabled.
|
||||||
|
{
|
||||||
|
wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
|
||||||
|
EXPECT_EQ(device, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test on adapter with DisallowUnsafeApis disabled.
|
||||||
|
{
|
||||||
|
wgpu::Device device = unsafeAdapter.CreateDevice(&deviceDescriptor);
|
||||||
|
EXPECT_EQ(device, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,12 +279,6 @@ class TimestampQueryValidationTest : public QuerySetValidationTest {
|
||||||
descriptor.requiredFeatures = requiredFeatures;
|
descriptor.requiredFeatures = requiredFeatures;
|
||||||
descriptor.requiredFeaturesCount = 1;
|
descriptor.requiredFeaturesCount = 1;
|
||||||
|
|
||||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
|
||||||
descriptor.nextInChain = &deviceTogglesDesc;
|
|
||||||
const char* disabledToggles[1] = {"disallow_unsafe_apis"};
|
|
||||||
deviceTogglesDesc.disabledToggles = disabledToggles;
|
|
||||||
deviceTogglesDesc.disabledTogglesCount = 1;
|
|
||||||
|
|
||||||
return dawnAdapter.CreateDevice(&descriptor);
|
return dawnAdapter.CreateDevice(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,12 +576,6 @@ class TimestampQueryInsidePassesValidationTest : public QuerySetValidationTest {
|
||||||
descriptor.requiredFeatures = requiredFeatures;
|
descriptor.requiredFeatures = requiredFeatures;
|
||||||
descriptor.requiredFeaturesCount = 2;
|
descriptor.requiredFeaturesCount = 2;
|
||||||
|
|
||||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
|
||||||
descriptor.nextInChain = &deviceTogglesDesc;
|
|
||||||
const char* disabledToggles[1] = {"disallow_unsafe_apis"};
|
|
||||||
deviceTogglesDesc.disabledToggles = disabledToggles;
|
|
||||||
deviceTogglesDesc.disabledTogglesCount = 1;
|
|
||||||
|
|
||||||
return dawnAdapter.CreateDevice(&descriptor);
|
return dawnAdapter.CreateDevice(&descriptor);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -722,19 +710,14 @@ TEST_F(TimestampQueryInsidePassesValidationTest, WriteTimestampOnRenderPassEncod
|
||||||
class PipelineStatisticsQueryValidationTest : public QuerySetValidationTest {
|
class PipelineStatisticsQueryValidationTest : public QuerySetValidationTest {
|
||||||
protected:
|
protected:
|
||||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||||
|
// Create a device with pipeline statistic query feature required. Note that Pipeline
|
||||||
|
// statistic query is an unsafe API, while DisallowUnsafeApis instance toggle is disabled
|
||||||
|
// when ValidationTest creating testing instance, so we can test it.
|
||||||
wgpu::DeviceDescriptor descriptor;
|
wgpu::DeviceDescriptor descriptor;
|
||||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::PipelineStatisticsQuery};
|
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::PipelineStatisticsQuery};
|
||||||
descriptor.requiredFeatures = requiredFeatures;
|
descriptor.requiredFeatures = requiredFeatures;
|
||||||
descriptor.requiredFeaturesCount = 1;
|
descriptor.requiredFeaturesCount = 1;
|
||||||
|
|
||||||
// TODO(crbug.com/1177506): Pipeline statistic query is an unsafe API, disable disallowing
|
|
||||||
// unsafe APIs to test it.
|
|
||||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
|
||||||
descriptor.nextInChain = &deviceTogglesDesc;
|
|
||||||
const char* disabledToggles[1] = {"disallow_unsafe_apis"};
|
|
||||||
deviceTogglesDesc.disabledToggles = disabledToggles;
|
|
||||||
deviceTogglesDesc.disabledTogglesCount = 1;
|
|
||||||
|
|
||||||
return dawnAdapter.CreateDevice(&descriptor);
|
return dawnAdapter.CreateDevice(&descriptor);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,22 +26,11 @@
|
||||||
class RenderPipelineValidationTest : public ValidationTest {
|
class RenderPipelineValidationTest : public ValidationTest {
|
||||||
protected:
|
protected:
|
||||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||||
// Disabled disallowing unsafe APIs so we can test ShaderF16 feature.
|
|
||||||
const char* disabledToggle[] = {"disallow_unsafe_apis"};
|
|
||||||
|
|
||||||
wgpu::DeviceDescriptor descriptor;
|
wgpu::DeviceDescriptor descriptor;
|
||||||
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::ShaderF16};
|
wgpu::FeatureName requiredFeatures[1] = {wgpu::FeatureName::ShaderF16};
|
||||||
descriptor.requiredFeatures = requiredFeatures;
|
descriptor.requiredFeatures = requiredFeatures;
|
||||||
descriptor.requiredFeaturesCount = 1;
|
descriptor.requiredFeaturesCount = 1;
|
||||||
|
|
||||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
|
||||||
descriptor.nextInChain = &deviceTogglesDesc;
|
|
||||||
|
|
||||||
deviceTogglesDesc.enabledToggles = nullptr;
|
|
||||||
deviceTogglesDesc.enabledTogglesCount = 0;
|
|
||||||
deviceTogglesDesc.disabledToggles = disabledToggle;
|
|
||||||
deviceTogglesDesc.disabledTogglesCount = 1;
|
|
||||||
|
|
||||||
return dawnAdapter.CreateDevice(&descriptor);
|
return dawnAdapter.CreateDevice(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -729,14 +729,6 @@ class CompressedTextureFormatsValidationTests : public TextureValidationTest {
|
||||||
descriptor.requiredFeatures = requiredFeatures;
|
descriptor.requiredFeatures = requiredFeatures;
|
||||||
descriptor.requiredFeaturesCount = 3;
|
descriptor.requiredFeaturesCount = 3;
|
||||||
|
|
||||||
// TODO(dawn:814): Remove when 1D texture support is complete.
|
|
||||||
const char* kDisallowUnsafeApis = "disallow_unsafe_apis";
|
|
||||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
|
||||||
deviceTogglesDesc.disabledToggles = &kDisallowUnsafeApis;
|
|
||||||
deviceTogglesDesc.disabledTogglesCount = 1;
|
|
||||||
|
|
||||||
descriptor.nextInChain = &deviceTogglesDesc;
|
|
||||||
|
|
||||||
return dawnAdapter.CreateDevice(&descriptor);
|
return dawnAdapter.CreateDevice(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,11 @@ using testing::HasSubstr;
|
||||||
|
|
||||||
class UnsafeAPIValidationTest : public ValidationTest {
|
class UnsafeAPIValidationTest : public ValidationTest {
|
||||||
protected:
|
protected:
|
||||||
|
// UnsafeAPIValidationTest create the device with toggle DisallowUnsafeApis explicitly enabled,
|
||||||
|
// which overrides the inheritance.
|
||||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||||
|
// Enable the DisallowUnsafeAPIs toggles in device toggles descriptor to override the
|
||||||
|
// inheritance and create a device disallowing unsafe apis.
|
||||||
wgpu::DeviceDescriptor descriptor;
|
wgpu::DeviceDescriptor descriptor;
|
||||||
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
||||||
descriptor.nextInChain = &deviceTogglesDesc;
|
descriptor.nextInChain = &deviceTogglesDesc;
|
||||||
|
|
|
@ -84,11 +84,14 @@ ValidationTest::ValidationTest() {
|
||||||
gCurrentTest = this;
|
gCurrentTest = this;
|
||||||
|
|
||||||
DawnProcTable procs = dawn::native::GetProcs();
|
DawnProcTable procs = dawn::native::GetProcs();
|
||||||
// Override procs to provide harness-specific behavior to always select the null adapter,
|
|
||||||
// and to allow fixture-specific overriding of the test device with CreateTestDevice.
|
// Override procs to provide harness-specific behavior to always select the null adapter, with
|
||||||
|
// adapter toggles inherited from instance toggles state. WGPURequestAdapterOptions is ignored
|
||||||
|
// here.
|
||||||
procs.instanceRequestAdapter = [](WGPUInstance instance, const WGPURequestAdapterOptions*,
|
procs.instanceRequestAdapter = [](WGPUInstance instance, const WGPURequestAdapterOptions*,
|
||||||
WGPURequestAdapterCallback callback, void* userdata) {
|
WGPURequestAdapterCallback callback, void* userdata) {
|
||||||
ASSERT(gCurrentTest);
|
ASSERT(gCurrentTest);
|
||||||
|
|
||||||
std::vector<dawn::native::Adapter> adapters = gCurrentTest->mDawnInstance->GetAdapters();
|
std::vector<dawn::native::Adapter> adapters = gCurrentTest->mDawnInstance->GetAdapters();
|
||||||
// Validation tests run against the null backend, find the corresponding adapter
|
// Validation tests run against the null backend, find the corresponding adapter
|
||||||
for (auto& adapter : adapters) {
|
for (auto& adapter : adapters) {
|
||||||
|
@ -121,7 +124,21 @@ ValidationTest::ValidationTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValidationTest::SetUp() {
|
void ValidationTest::SetUp() {
|
||||||
mDawnInstance = std::make_unique<dawn::native::Instance>();
|
// Create an instance with toggle DisallowUnsafeApis disabled, which would be inherited to
|
||||||
|
// adapter and device toggles and allow us to test unsafe apis (including experimental
|
||||||
|
// features). To test device of DisallowUnsafeApis enabled, require it in device toggles
|
||||||
|
// descriptor to override the inheritance.
|
||||||
|
const char* disallowUnsafeApisToggle = "disallow_unsafe_apis";
|
||||||
|
WGPUDawnTogglesDescriptor instanceToggles = {};
|
||||||
|
instanceToggles.chain.sType = WGPUSType::WGPUSType_DawnTogglesDescriptor;
|
||||||
|
instanceToggles.disabledTogglesCount = 1;
|
||||||
|
instanceToggles.disabledToggles = &disallowUnsafeApisToggle;
|
||||||
|
|
||||||
|
WGPUInstanceDescriptor instanceDesc = {};
|
||||||
|
instanceDesc.nextInChain = &instanceToggles.chain;
|
||||||
|
|
||||||
|
mDawnInstance = std::make_unique<dawn::native::Instance>(&instanceDesc);
|
||||||
|
|
||||||
mDawnInstance->DiscoverDefaultAdapters();
|
mDawnInstance->DiscoverDefaultAdapters();
|
||||||
mInstance = mWireHelper->RegisterInstance(mDawnInstance->Get());
|
mInstance = mWireHelper->RegisterInstance(mDawnInstance->Get());
|
||||||
|
|
||||||
|
@ -130,7 +147,8 @@ void ValidationTest::SetUp() {
|
||||||
"_" + ::testing::UnitTest::GetInstance()->current_test_info()->name();
|
"_" + ::testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||||
mWireHelper->BeginWireTrace(traceName.c_str());
|
mWireHelper->BeginWireTrace(traceName.c_str());
|
||||||
|
|
||||||
// These options are unused since validation tests always select the null adapter
|
// RequestAdapter is overriden to ignore RequestAdapterOptions and always select the null
|
||||||
|
// adapter.
|
||||||
wgpu::RequestAdapterOptions options = {};
|
wgpu::RequestAdapterOptions options = {};
|
||||||
mInstance.RequestAdapter(
|
mInstance.RequestAdapter(
|
||||||
&options,
|
&options,
|
||||||
|
@ -263,9 +281,8 @@ dawn::native::Adapter& ValidationTest::GetBackendAdapter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
WGPUDevice ValidationTest::CreateTestDevice(dawn::native::Adapter dawnAdapter) {
|
WGPUDevice ValidationTest::CreateTestDevice(dawn::native::Adapter dawnAdapter) {
|
||||||
// Disabled disallowing unsafe APIs so we can test them.
|
|
||||||
std::vector<const char*> enabledToggles;
|
std::vector<const char*> enabledToggles;
|
||||||
std::vector<const char*> disabledToggles = {"disallow_unsafe_apis"};
|
std::vector<const char*> disabledToggles;
|
||||||
|
|
||||||
for (const std::string& toggle : gToggleParser->GetEnabledToggles()) {
|
for (const std::string& toggle : gToggleParser->GetEnabledToggles()) {
|
||||||
enabledToggles.push_back(toggle.c_str());
|
enabledToggles.push_back(toggle.c_str());
|
||||||
|
|
Loading…
Reference in New Issue