dawn: Refactor device creation and add shader-f16 feature
This CL modifies the way adapter creating devices, adds `shader-f16` feature, and deprecates the `dawn-shader-float16` feature which is no longer used. Details: 1. Parse the toggles chained with device descriptor in `adapter::CreateDeviceInternal`, which are then used to validate features requirement within `CreateDeviceInternal` and passed to device constructor as initializer. 2. When creating device, validate features requirement in `CreateDeviceInternal` with toggles known, make sure to fail the device creation if a required feature is not supported by adapter or is guarded by certain toggles which were not enabled/disabled. Feature ShaderF16 and ChromiumExperimentalDp4a are validated in this way. Unittest is added to check creating devices with toggles-guarded features required. 3. Add `shader-f16` feature, which allow `using f16;` in WGSL code. End-to-end tests are added to test a trival f16 WGSL shader could be used if and only if the device has `shader-f16` feature. 4. Deprecate the `dawn-shader-float16` feature, which will be completely removed after cleaning up Blink code. Bug: dawn:1510 Change-Id: I6cb2dcbe1ee584fdd6131c62df1ee850b881dbd2 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/100802 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com> Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
f9eeed6106
commit
7ca82ac4d0
|
@ -1384,6 +1384,7 @@
|
|||
{"value": 6, "name": "texture compression ETC2"},
|
||||
{"value": 7, "name": "texture compression ASTC"},
|
||||
{"value": 8, "name": "indirect first instance"},
|
||||
{"value": 9, "name": "shader f16"},
|
||||
{"value": 1001, "name": "dawn shader float 16", "tags": ["dawn"]},
|
||||
{"value": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
|
||||
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
|
||||
|
|
|
@ -61,7 +61,15 @@ struct ToggleInfo {
|
|||
// A struct to record the information of a feature. A feature is a GPU feature that is not
|
||||
// required to be supported by all Dawn backends and can only be used when it is enabled on the
|
||||
// creation of device.
|
||||
using FeatureInfo = ToggleInfo;
|
||||
struct FeatureInfo {
|
||||
const char* name;
|
||||
const char* description;
|
||||
const char* url;
|
||||
// The enum of feature state, could be stable or experimental. Using an experimental feature
|
||||
// requires DisallowUnsafeAPIs toggle being disabled.
|
||||
enum class FeatureState { Stable = 0, Experimental };
|
||||
FeatureState featureState;
|
||||
};
|
||||
|
||||
// An adapter is an object that represent on possibility of creating devices in the system.
|
||||
// Most of the time it will represent a combination of a physical GPU and an API. Not that the
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "dawn/common/Constants.h"
|
||||
#include "dawn/common/GPUInfo.h"
|
||||
#include "dawn/native/ChainUtils_autogen.h"
|
||||
#include "dawn/native/Device.h"
|
||||
#include "dawn/native/Instance.h"
|
||||
#include "dawn/native/ValidationUtils_autogen.h"
|
||||
|
@ -189,15 +190,40 @@ bool AdapterBase::GetLimits(SupportedLimits* limits) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
MaybeError AdapterBase::ValidateFeatureSupportedWithToggles(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
DAWN_TRY(ValidateFeatureName(feature));
|
||||
DAWN_INVALID_IF(!mSupportedFeatures.IsEnabled(feature),
|
||||
"Requested feature %s is not supported.", feature);
|
||||
|
||||
const FeatureInfo* featureInfo = GetInstance()->GetFeatureInfo(feature);
|
||||
// Experimental features are guarded by toggle DisallowUnsafeAPIs.
|
||||
if (featureInfo->featureState == FeatureInfo::FeatureState::Experimental) {
|
||||
DAWN_INVALID_IF(!userProvidedToggles.IsDisabled(Toggle::DisallowUnsafeAPIs),
|
||||
"Feature %s is guarded by toggle disallow_unsafe_apis.", featureInfo->name);
|
||||
}
|
||||
|
||||
// Do backend-specific validation.
|
||||
return ValidateFeatureSupportedWithTogglesImpl(feature, userProvidedToggles);
|
||||
}
|
||||
|
||||
ResultOrError<Ref<DeviceBase>> AdapterBase::CreateDeviceInternal(
|
||||
const DeviceDescriptor* descriptor) {
|
||||
ASSERT(descriptor != nullptr);
|
||||
|
||||
// Check overriden toggles before creating device, as some device features may be guarded by
|
||||
// toggles, and requiring such features without using corresponding toggles should fails the
|
||||
// device creating.
|
||||
const DawnTogglesDeviceDescriptor* togglesDesc = nullptr;
|
||||
FindInChain(descriptor->nextInChain, &togglesDesc);
|
||||
TripleStateTogglesSet userProvidedToggles =
|
||||
TripleStateTogglesSet::CreateFromTogglesDeviceDescriptor(togglesDesc);
|
||||
|
||||
// Validate all required features are supported by the adapter and suitable under given toggles.
|
||||
for (uint32_t i = 0; i < descriptor->requiredFeaturesCount; ++i) {
|
||||
wgpu::FeatureName f = descriptor->requiredFeatures[i];
|
||||
DAWN_TRY(ValidateFeatureName(f));
|
||||
DAWN_INVALID_IF(!mSupportedFeatures.IsEnabled(f), "Requested feature %s is not supported.",
|
||||
f);
|
||||
wgpu::FeatureName feature = descriptor->requiredFeatures[i];
|
||||
DAWN_TRY(ValidateFeatureSupportedWithToggles(feature, userProvidedToggles));
|
||||
}
|
||||
|
||||
if (descriptor->requiredLimits != nullptr) {
|
||||
|
@ -208,7 +234,7 @@ ResultOrError<Ref<DeviceBase>> AdapterBase::CreateDeviceInternal(
|
|||
DAWN_INVALID_IF(descriptor->requiredLimits->nextInChain != nullptr,
|
||||
"nextInChain is not nullptr.");
|
||||
}
|
||||
return CreateDeviceImpl(descriptor);
|
||||
return CreateDeviceImpl(descriptor, userProvidedToggles);
|
||||
}
|
||||
|
||||
void AdapterBase::SetUseTieredLimits(bool useTieredLimits) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "dawn/native/Error.h"
|
||||
#include "dawn/native/Features.h"
|
||||
#include "dawn/native/Limits.h"
|
||||
#include "dawn/native/Toggles.h"
|
||||
#include "dawn/native/dawn_platform.h"
|
||||
|
||||
namespace dawn::native {
|
||||
|
@ -72,14 +73,24 @@ class AdapterBase : public RefCounted {
|
|||
std::string mName;
|
||||
wgpu::AdapterType mAdapterType = wgpu::AdapterType::Unknown;
|
||||
std::string mDriverDescription;
|
||||
|
||||
// Features set that CAN be supported by devices of this adapter. Some features in this set may
|
||||
// be guarded by toggles, and creating a device with these features required may result in a
|
||||
// validation error if proper toggles are not enabled/disabled.
|
||||
FeaturesSet mSupportedFeatures;
|
||||
// Check if a feature os supported by this adapter AND suitable with given toggles.
|
||||
MaybeError ValidateFeatureSupportedWithToggles(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles);
|
||||
|
||||
private:
|
||||
virtual ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(const DeviceDescriptor* descriptor) = 0;
|
||||
virtual ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) = 0;
|
||||
|
||||
virtual MaybeError InitializeImpl() = 0;
|
||||
|
||||
// Check base WebGPU features and discover supported featurees.
|
||||
// Check base WebGPU features and discover supported features.
|
||||
virtual MaybeError InitializeSupportedFeaturesImpl() = 0;
|
||||
|
||||
// Check base WebGPU limits and populate supported limits.
|
||||
|
@ -87,6 +98,10 @@ class AdapterBase : public RefCounted {
|
|||
|
||||
virtual void InitializeVendorArchitectureImpl();
|
||||
|
||||
virtual MaybeError ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) = 0;
|
||||
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceInternal(const DeviceDescriptor* descriptor);
|
||||
|
||||
virtual MaybeError ResetInternalDeviceForTestingImpl();
|
||||
|
|
|
@ -364,7 +364,7 @@ MaybeError ValidateCopyTextureForBrowser(DeviceBase* device,
|
|||
source->texture->GetSampleCount(), destination->texture->GetSampleCount());
|
||||
|
||||
DAWN_INVALID_IF(
|
||||
options->internalUsage && !device->IsFeatureEnabled(Feature::DawnInternalUsages),
|
||||
options->internalUsage && !device->HasFeature(Feature::DawnInternalUsages),
|
||||
"The internalUsage is true while the dawn-internal-usages feature is not enabled.");
|
||||
UsageValidationMode mode =
|
||||
options->internalUsage ? UsageValidationMode::Internal : UsageValidationMode::Default;
|
||||
|
|
|
@ -170,20 +170,19 @@ ResultOrError<Ref<PipelineLayoutBase>> ValidateLayoutAndGetRenderPipelineDescrip
|
|||
|
||||
// DeviceBase
|
||||
|
||||
DeviceBase::DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor)
|
||||
: mAdapter(adapter), mNextPipelineCompatibilityToken(1) {
|
||||
DeviceBase::DeviceBase(AdapterBase* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles)
|
||||
: mAdapter(adapter),
|
||||
mEnabledToggles(userProvidedToggles.providedTogglesEnabled),
|
||||
mOverridenToggles(userProvidedToggles.togglesIsProvided),
|
||||
mNextPipelineCompatibilityToken(1) {
|
||||
mAdapter->GetInstance()->IncrementDeviceCountForTesting();
|
||||
ASSERT(descriptor != nullptr);
|
||||
|
||||
AdapterProperties adapterProperties;
|
||||
adapter->APIGetProperties(&adapterProperties);
|
||||
|
||||
const DawnTogglesDeviceDescriptor* togglesDesc = nullptr;
|
||||
FindInChain(descriptor->nextInChain, &togglesDesc);
|
||||
if (togglesDesc != nullptr) {
|
||||
ApplyToggleOverrides(togglesDesc);
|
||||
}
|
||||
|
||||
SetDefaultToggles();
|
||||
ApplyFeatures(descriptor);
|
||||
|
||||
|
@ -1323,17 +1322,19 @@ void DeviceBase::ApplyFeatures(const DeviceDescriptor* deviceDescriptor) {
|
|||
}
|
||||
}
|
||||
|
||||
bool DeviceBase::IsFeatureEnabled(Feature feature) const {
|
||||
bool DeviceBase::HasFeature(Feature feature) const {
|
||||
return mEnabledFeatures.IsEnabled(feature);
|
||||
}
|
||||
|
||||
void DeviceBase::SetWGSLExtensionAllowList() {
|
||||
// Set the WGSL extensions allow list based on device's enabled features and other
|
||||
// propority. For example:
|
||||
// mWGSLExtensionAllowList.insert("InternalExtensionForTesting");
|
||||
if (IsFeatureEnabled(Feature::ChromiumExperimentalDp4a)) {
|
||||
// propority.
|
||||
if (mEnabledFeatures.IsEnabled(Feature::ChromiumExperimentalDp4a)) {
|
||||
mWGSLExtensionAllowList.insert("chromium_experimental_dp4a");
|
||||
}
|
||||
if (mEnabledFeatures.IsEnabled(Feature::ShaderF16)) {
|
||||
mWGSLExtensionAllowList.insert("f16");
|
||||
}
|
||||
}
|
||||
|
||||
WGSLExtensionSet DeviceBase::GetWGSLExtensionAllowList() const {
|
||||
|
@ -1800,27 +1801,6 @@ void DeviceBase::SetDefaultToggles() {
|
|||
SetToggle(Toggle::DisallowUnsafeAPIs, true);
|
||||
}
|
||||
|
||||
void DeviceBase::ApplyToggleOverrides(const DawnTogglesDeviceDescriptor* togglesDescriptor) {
|
||||
ASSERT(togglesDescriptor != nullptr);
|
||||
|
||||
for (uint32_t i = 0; i < togglesDescriptor->forceEnabledTogglesCount; ++i) {
|
||||
Toggle toggle = GetAdapter()->GetInstance()->ToggleNameToEnum(
|
||||
togglesDescriptor->forceEnabledToggles[i]);
|
||||
if (toggle != Toggle::InvalidEnum) {
|
||||
mEnabledToggles.Set(toggle, true);
|
||||
mOverridenToggles.Set(toggle, true);
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < togglesDescriptor->forceDisabledTogglesCount; ++i) {
|
||||
Toggle toggle = GetAdapter()->GetInstance()->ToggleNameToEnum(
|
||||
togglesDescriptor->forceDisabledToggles[i]);
|
||||
if (toggle != Toggle::InvalidEnum) {
|
||||
mEnabledToggles.Set(toggle, false);
|
||||
mOverridenToggles.Set(toggle, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceBase::FlushCallbackTaskQueue() {
|
||||
if (!mCallbackTaskManager->IsEmpty()) {
|
||||
// If a user calls Queue::Submit inside the callback, then the device will be ticked,
|
||||
|
|
|
@ -62,7 +62,9 @@ using WGSLExtensionSet = std::unordered_set<std::string>;
|
|||
|
||||
class DeviceBase : public RefCountedWithExternalCount {
|
||||
public:
|
||||
DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor);
|
||||
DeviceBase(AdapterBase* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles);
|
||||
~DeviceBase() override;
|
||||
|
||||
// Handles the error, causing a device loss if applicable. Almost always when a device loss
|
||||
|
@ -279,11 +281,7 @@ class DeviceBase : public RefCountedWithExternalCount {
|
|||
QueueBase* APIGetQueue();
|
||||
|
||||
bool APIGetLimits(SupportedLimits* limits) const;
|
||||
// Note that we should not use this function to query the features which can only be enabled
|
||||
// behind toggles (use IsFeatureEnabled() instead).
|
||||
bool APIHasFeature(wgpu::FeatureName feature) const;
|
||||
// Note that we should not use this function to query the features which can only be enabled
|
||||
// behind toggles (use IsFeatureEnabled() instead).
|
||||
size_t APIEnumerateFeatures(wgpu::FeatureName* features) const;
|
||||
void APIInjectError(wgpu::ErrorType type, const char* message);
|
||||
bool APITick();
|
||||
|
@ -381,9 +379,7 @@ class DeviceBase : public RefCountedWithExternalCount {
|
|||
virtual bool ShouldDuplicateParametersForDrawIndirect(
|
||||
const RenderPipelineBase* renderPipelineBase) const;
|
||||
|
||||
// TODO(crbug.com/dawn/1434): Make this function non-overridable when we support requesting
|
||||
// Adapter with toggles.
|
||||
virtual bool IsFeatureEnabled(Feature feature) const;
|
||||
bool HasFeature(Feature feature) const;
|
||||
|
||||
const CombinedLimits& GetLimits() const;
|
||||
|
||||
|
@ -482,7 +478,6 @@ class DeviceBase : public RefCountedWithExternalCount {
|
|||
WGPUCreateRenderPipelineAsyncCallback callback,
|
||||
void* userdata);
|
||||
|
||||
void ApplyToggleOverrides(const DawnTogglesDeviceDescriptor* togglesDescriptor);
|
||||
void ApplyFeatures(const DeviceDescriptor* deviceDescriptor);
|
||||
|
||||
void SetDefaultToggles();
|
||||
|
|
|
@ -34,58 +34,64 @@ using FeatureEnumAndInfoList =
|
|||
static constexpr FeatureEnumAndInfoList kFeatureNameAndInfoList = {{
|
||||
{Feature::TextureCompressionBC,
|
||||
{"texture-compression-bc", "Support Block Compressed (BC) texture formats",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=42"}},
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=42", FeatureInfo::FeatureState::Stable}},
|
||||
{Feature::TextureCompressionETC2,
|
||||
{"texture-compression-etc2",
|
||||
"Support Ericsson Texture Compressed (ETC2/EAC) texture "
|
||||
"formats",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=955"}},
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=955", FeatureInfo::FeatureState::Stable}},
|
||||
{Feature::TextureCompressionASTC,
|
||||
{"texture-compression-astc",
|
||||
"Support Adaptable Scalable Texture Compressed (ASTC) "
|
||||
"texture formats",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=955"}},
|
||||
{Feature::ShaderFloat16,
|
||||
{"shader-float16",
|
||||
"Support 16bit float arithmetic and declarations in uniform and storage buffers",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=426"}},
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=955", FeatureInfo::FeatureState::Stable}},
|
||||
{Feature::PipelineStatisticsQuery,
|
||||
{"pipeline-statistics-query", "Support Pipeline Statistics Query",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=434"}},
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=434", FeatureInfo::FeatureState::Stable}},
|
||||
{Feature::TimestampQuery,
|
||||
{"timestamp-query", "Support Timestamp Query",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=434"}},
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=434", FeatureInfo::FeatureState::Stable}},
|
||||
{Feature::DepthClipControl,
|
||||
{"depth-clip-control", "Disable depth clipping of primitives to the clip volume",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=1178"}},
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=1178", FeatureInfo::FeatureState::Stable}},
|
||||
{Feature::Depth32FloatStencil8,
|
||||
{"depth32float-stencil8", "Support depth32float-stencil8 texture format",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=690"}},
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=690", FeatureInfo::FeatureState::Stable}},
|
||||
{Feature::ChromiumExperimentalDp4a,
|
||||
{"chromium-experimental-dp4a", "Support experimental DP4a instructions in WGSL",
|
||||
"https://bugs.chromium.org/p/tint/issues/detail?id=1497"}},
|
||||
"https://bugs.chromium.org/p/tint/issues/detail?id=1497",
|
||||
FeatureInfo::FeatureState::Experimental}},
|
||||
{Feature::IndirectFirstInstance,
|
||||
{"indirect-first-instance", "Support non-zero first instance values on indirect draw calls",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=1197"}},
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=1197", FeatureInfo::FeatureState::Stable}},
|
||||
{Feature::ShaderF16,
|
||||
{"shader-f16", "Supports the \"enable f16;\" directive in WGSL",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=1510",
|
||||
FeatureInfo::FeatureState::Experimental}},
|
||||
{Feature::DawnInternalUsages,
|
||||
{"dawn-internal-usages",
|
||||
"Add internal usages to resources to affect how the texture is allocated, but not "
|
||||
"frontend validation. Other internal commands may access this usage.",
|
||||
"https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/"
|
||||
"dawn_internal_usages.md"}},
|
||||
"dawn_internal_usages.md",
|
||||
FeatureInfo::FeatureState::Stable}},
|
||||
{Feature::MultiPlanarFormats,
|
||||
{"multiplanar-formats", "Import and use multi-planar texture formats with per plane views",
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=551"}},
|
||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=551", FeatureInfo::FeatureState::Stable}},
|
||||
{Feature::DawnNative,
|
||||
{"dawn-native", "WebGPU is running on top of dawn_native.",
|
||||
"https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/"
|
||||
"dawn_native.md"}},
|
||||
"dawn_native.md",
|
||||
FeatureInfo::FeatureState::Stable}},
|
||||
}};
|
||||
|
||||
Feature FromAPIFeature(wgpu::FeatureName feature) {
|
||||
switch (feature) {
|
||||
case wgpu::FeatureName::Undefined:
|
||||
return Feature::InvalidEnum;
|
||||
case wgpu::FeatureName::DawnShaderFloat16:
|
||||
// Deprecated.
|
||||
return Feature::InvalidEnum;
|
||||
|
||||
case wgpu::FeatureName::TimestampQuery:
|
||||
return Feature::TimestampQuery;
|
||||
|
@ -103,8 +109,6 @@ Feature FromAPIFeature(wgpu::FeatureName feature) {
|
|||
return Feature::Depth32FloatStencil8;
|
||||
case wgpu::FeatureName::IndirectFirstInstance:
|
||||
return Feature::IndirectFirstInstance;
|
||||
case wgpu::FeatureName::DawnShaderFloat16:
|
||||
return Feature::ShaderFloat16;
|
||||
case wgpu::FeatureName::DawnInternalUsages:
|
||||
return Feature::DawnInternalUsages;
|
||||
case wgpu::FeatureName::DawnMultiPlanarFormats:
|
||||
|
@ -113,6 +117,8 @@ Feature FromAPIFeature(wgpu::FeatureName feature) {
|
|||
return Feature::DawnNative;
|
||||
case wgpu::FeatureName::ChromiumExperimentalDp4a:
|
||||
return Feature::ChromiumExperimentalDp4a;
|
||||
case wgpu::FeatureName::ShaderF16:
|
||||
return Feature::ShaderF16;
|
||||
}
|
||||
return Feature::InvalidEnum;
|
||||
}
|
||||
|
@ -135,8 +141,6 @@ wgpu::FeatureName ToAPIFeature(Feature feature) {
|
|||
return wgpu::FeatureName::Depth32FloatStencil8;
|
||||
case Feature::IndirectFirstInstance:
|
||||
return wgpu::FeatureName::IndirectFirstInstance;
|
||||
case Feature::ShaderFloat16:
|
||||
return wgpu::FeatureName::DawnShaderFloat16;
|
||||
case Feature::DawnInternalUsages:
|
||||
return wgpu::FeatureName::DawnInternalUsages;
|
||||
case Feature::MultiPlanarFormats:
|
||||
|
@ -145,6 +149,8 @@ wgpu::FeatureName ToAPIFeature(Feature feature) {
|
|||
return wgpu::FeatureName::DawnNative;
|
||||
case Feature::ChromiumExperimentalDp4a:
|
||||
return wgpu::FeatureName::ChromiumExperimentalDp4a;
|
||||
case Feature::ShaderF16:
|
||||
return wgpu::FeatureName::ShaderF16;
|
||||
|
||||
case Feature::EnumCount:
|
||||
break;
|
||||
|
|
|
@ -30,13 +30,13 @@ enum class Feature {
|
|||
TextureCompressionBC,
|
||||
TextureCompressionETC2,
|
||||
TextureCompressionASTC,
|
||||
ShaderFloat16,
|
||||
PipelineStatisticsQuery,
|
||||
TimestampQuery,
|
||||
DepthClipControl,
|
||||
Depth32FloatStencil8,
|
||||
ChromiumExperimentalDp4a,
|
||||
IndirectFirstInstance,
|
||||
ShaderF16,
|
||||
|
||||
// Dawn-specific
|
||||
DawnInternalUsages,
|
||||
|
|
|
@ -389,12 +389,12 @@ FormatTable BuildFormatTable(const DeviceBase* device) {
|
|||
AddMultiAspectFormat(wgpu::TextureFormat::Depth24PlusStencil8,
|
||||
Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Stencil8, true, true, true, 2);
|
||||
AddDepthFormat(wgpu::TextureFormat::Depth32Float, 4, true);
|
||||
bool isD32S8Supported = device->IsFeatureEnabled(Feature::Depth32FloatStencil8);
|
||||
bool isD32S8Supported = device->HasFeature(Feature::Depth32FloatStencil8);
|
||||
AddMultiAspectFormat(wgpu::TextureFormat::Depth32FloatStencil8,
|
||||
Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Stencil8, true, isD32S8Supported, true, 2);
|
||||
|
||||
// BC compressed formats
|
||||
bool isBCFormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionBC);
|
||||
bool isBCFormatSupported = device->HasFeature(Feature::TextureCompressionBC);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnorm, 8, 4, 4, isBCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnormSrgb, 8, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC1RGBAUnorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::BC4RSnorm, 8, 4, 4, isBCFormatSupported, 1);
|
||||
|
@ -411,7 +411,7 @@ FormatTable BuildFormatTable(const DeviceBase* device) {
|
|||
AddCompressedFormat(wgpu::TextureFormat::BC7RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC7RGBAUnorm);
|
||||
|
||||
// ETC2/EAC compressed formats
|
||||
bool isETC2FormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionETC2);
|
||||
bool isETC2FormatSupported = device->HasFeature(Feature::TextureCompressionETC2);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8Unorm, 8, 4, 4, isETC2FormatSupported, 3);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8UnormSrgb, 8, 4, 4, isETC2FormatSupported, 3, wgpu::TextureFormat::ETC2RGB8Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1Unorm, 8, 4, 4, isETC2FormatSupported, 4);
|
||||
|
@ -424,7 +424,7 @@ FormatTable BuildFormatTable(const DeviceBase* device) {
|
|||
AddCompressedFormat(wgpu::TextureFormat::EACRG11Snorm, 16, 4, 4, isETC2FormatSupported, 2);
|
||||
|
||||
// ASTC compressed formats
|
||||
bool isASTCFormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionASTC);
|
||||
bool isASTCFormatSupported = device->HasFeature(Feature::TextureCompressionASTC);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC4x4Unorm, 16, 4, 4, isASTCFormatSupported, 4);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC4x4UnormSrgb, 16, 4, 4, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC4x4Unorm);
|
||||
AddCompressedFormat(wgpu::TextureFormat::ASTC5x4Unorm, 16, 5, 4, isASTCFormatSupported, 4);
|
||||
|
@ -455,7 +455,7 @@ FormatTable BuildFormatTable(const DeviceBase* device) {
|
|||
AddCompressedFormat(wgpu::TextureFormat::ASTC12x12UnormSrgb, 16, 12, 12, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC12x12Unorm);
|
||||
|
||||
// multi-planar formats
|
||||
const bool isMultiPlanarFormatSupported = device->IsFeatureEnabled(Feature::MultiPlanarFormats);
|
||||
const bool isMultiPlanarFormatSupported = device->HasFeature(Feature::MultiPlanarFormats);
|
||||
AddMultiAspectFormat(wgpu::TextureFormat::R8BG8Biplanar420Unorm, Aspect::Plane0 | Aspect::Plane1,
|
||||
wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm, false, isMultiPlanarFormatSupported, false, 3);
|
||||
|
||||
|
|
|
@ -338,7 +338,7 @@ MaybeError EncodeIndirectDrawValidationCommands(DeviceBase* device,
|
|||
if (device->IsValidationEnabled()) {
|
||||
newPass.flags |= kValidationEnabled;
|
||||
}
|
||||
if (device->IsFeatureEnabled(Feature::IndirectFirstInstance)) {
|
||||
if (device->HasFeature(Feature::IndirectFirstInstance)) {
|
||||
newPass.flags |= kIndirectFirstInstanceEnabled;
|
||||
}
|
||||
passes.push_back(std::move(newPass));
|
||||
|
|
|
@ -60,7 +60,7 @@ MaybeError ValidateQuerySetDescriptor(DeviceBase* device, const QuerySetDescript
|
|||
"fully implemented");
|
||||
|
||||
DAWN_INVALID_IF(
|
||||
!device->IsFeatureEnabled(Feature::PipelineStatisticsQuery),
|
||||
!device->HasFeature(Feature::PipelineStatisticsQuery),
|
||||
"Pipeline statistics query set created without the feature being enabled.");
|
||||
|
||||
DAWN_INVALID_IF(descriptor->pipelineStatisticsCount == 0,
|
||||
|
@ -82,7 +82,7 @@ MaybeError ValidateQuerySetDescriptor(DeviceBase* device, const QuerySetDescript
|
|||
"Timestamp queries are disallowed because they may expose precise "
|
||||
"timing information.");
|
||||
|
||||
DAWN_INVALID_IF(!device->IsFeatureEnabled(Feature::TimestampQuery),
|
||||
DAWN_INVALID_IF(!device->HasFeature(Feature::TimestampQuery),
|
||||
"Timestamp query set created without the feature being enabled.");
|
||||
|
||||
DAWN_INVALID_IF(descriptor->pipelineStatisticsCount != 0,
|
||||
|
|
|
@ -156,7 +156,7 @@ MaybeError ValidatePrimitiveState(const DeviceBase* device, const PrimitiveState
|
|||
DAWN_TRY(ValidateSingleSType(descriptor->nextInChain, wgpu::SType::PrimitiveDepthClipControl));
|
||||
const PrimitiveDepthClipControl* depthClipControl = nullptr;
|
||||
FindInChain(descriptor->nextInChain, &depthClipControl);
|
||||
DAWN_INVALID_IF(depthClipControl && !device->IsFeatureEnabled(Feature::DepthClipControl),
|
||||
DAWN_INVALID_IF(depthClipControl && !device->HasFeature(Feature::DepthClipControl),
|
||||
"%s is not supported", wgpu::FeatureName::DepthClipControl);
|
||||
DAWN_TRY(ValidatePrimitiveTopology(descriptor->topology));
|
||||
DAWN_TRY(ValidateIndexFormat(descriptor->stripIndexFormat));
|
||||
|
|
|
@ -339,7 +339,7 @@ MaybeError ValidateTextureDescriptor(const DeviceBase* device,
|
|||
FindInChain(descriptor->nextInChain, &internalUsageDesc);
|
||||
|
||||
DAWN_INVALID_IF(
|
||||
internalUsageDesc != nullptr && !device->IsFeatureEnabled(Feature::DawnInternalUsages),
|
||||
internalUsageDesc != nullptr && !device->HasFeature(Feature::DawnInternalUsages),
|
||||
"The internalUsageDesc is not empty while the dawn-internal-usages feature is not enabled");
|
||||
|
||||
const Format* format;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "dawn/common/Assert.h"
|
||||
#include "dawn/common/BitSetIterator.h"
|
||||
#include "dawn/native/Toggles.h"
|
||||
#include "dawn/native/dawn_platform.h"
|
||||
|
||||
namespace dawn::native {
|
||||
namespace {
|
||||
|
@ -334,6 +335,81 @@ std::vector<const char*> TogglesSet::GetContainedToggleNames() const {
|
|||
return togglesNameInUse;
|
||||
}
|
||||
|
||||
TripleStateTogglesSet TripleStateTogglesSet::CreateFromTogglesDeviceDescriptor(
|
||||
const DawnTogglesDeviceDescriptor* togglesDesc) {
|
||||
TripleStateTogglesSet userToggles;
|
||||
if (togglesDesc != nullptr) {
|
||||
TogglesInfo togglesInfo;
|
||||
for (uint32_t i = 0; i < togglesDesc->forceEnabledTogglesCount; ++i) {
|
||||
Toggle toggle = togglesInfo.ToggleNameToEnum(togglesDesc->forceEnabledToggles[i]);
|
||||
if (toggle != Toggle::InvalidEnum) {
|
||||
userToggles.togglesIsProvided.Set(toggle, true);
|
||||
userToggles.providedTogglesEnabled.Set(toggle, true);
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < togglesDesc->forceDisabledTogglesCount; ++i) {
|
||||
Toggle toggle = togglesInfo.ToggleNameToEnum(togglesDesc->forceDisabledToggles[i]);
|
||||
if (toggle != Toggle::InvalidEnum) {
|
||||
userToggles.togglesIsProvided.Set(toggle, true);
|
||||
userToggles.providedTogglesEnabled.Set(toggle, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return userToggles;
|
||||
}
|
||||
|
||||
void TripleStateTogglesSet::Set(Toggle toggle, bool enabled) {
|
||||
ASSERT(toggle != Toggle::InvalidEnum);
|
||||
togglesIsProvided.Set(toggle, true);
|
||||
providedTogglesEnabled.Set(toggle, enabled);
|
||||
}
|
||||
|
||||
bool TripleStateTogglesSet::IsProvided(Toggle toggle) const {
|
||||
return togglesIsProvided.Has(toggle);
|
||||
}
|
||||
// Return true if the toggle is provided in enable list, and false otherwise.
|
||||
bool TripleStateTogglesSet::IsEnabled(Toggle toggle) const {
|
||||
return togglesIsProvided.Has(toggle) && providedTogglesEnabled.Has(toggle);
|
||||
}
|
||||
// Return true if the toggle is provided in disable list, and false otherwise.
|
||||
bool TripleStateTogglesSet::IsDisabled(Toggle toggle) const {
|
||||
return togglesIsProvided.Has(toggle) && !providedTogglesEnabled.Has(toggle);
|
||||
}
|
||||
|
||||
std::vector<const char*> TripleStateTogglesSet::GetEnabledToggleNames() const {
|
||||
std::vector<const char*> enabledTogglesName(providedTogglesEnabled.toggleBitset.count());
|
||||
|
||||
uint32_t index = 0;
|
||||
for (uint32_t i : IterateBitSet(providedTogglesEnabled.toggleBitset)) {
|
||||
const Toggle& toggle = static_cast<Toggle>(i);
|
||||
// All enabled toggles must be provided.
|
||||
ASSERT(togglesIsProvided.Has(toggle));
|
||||
const char* toggleName = ToggleEnumToName(toggle);
|
||||
enabledTogglesName[index] = toggleName;
|
||||
++index;
|
||||
}
|
||||
|
||||
return enabledTogglesName;
|
||||
}
|
||||
|
||||
std::vector<const char*> TripleStateTogglesSet::GetDisabledToggleNames() const {
|
||||
std::vector<const char*> enabledTogglesName(togglesIsProvided.toggleBitset.count() -
|
||||
providedTogglesEnabled.toggleBitset.count());
|
||||
|
||||
uint32_t index = 0;
|
||||
for (uint32_t i : IterateBitSet(togglesIsProvided.toggleBitset)) {
|
||||
const Toggle& toggle = static_cast<Toggle>(i);
|
||||
// Disabled toggles are those provided but not enabled.
|
||||
if (!providedTogglesEnabled.Has(toggle)) {
|
||||
const char* toggleName = ToggleEnumToName(toggle);
|
||||
enabledTogglesName[index] = toggleName;
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
return enabledTogglesName;
|
||||
}
|
||||
|
||||
const char* ToggleEnumToName(Toggle toggle) {
|
||||
ASSERT(toggle != Toggle::InvalidEnum);
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
namespace dawn::native {
|
||||
|
||||
struct DawnTogglesDeviceDescriptor;
|
||||
|
||||
enum class Toggle {
|
||||
EmulateStoreAndMSAAResolve,
|
||||
NonzeroClearResourcesOnCreationForTesting,
|
||||
|
@ -92,6 +94,27 @@ struct TogglesSet {
|
|||
std::vector<const char*> GetContainedToggleNames() const;
|
||||
};
|
||||
|
||||
// TripleStateTogglesSet track each toggle with three posible states, i.e. "Not provided" (default),
|
||||
// "Provided as enabled", and "Provided as disabled". This struct can be used to record the
|
||||
// user-provided toggles, where some toggles are explicitly enabled or disabled while the other
|
||||
// toggles are left as default.
|
||||
struct TripleStateTogglesSet {
|
||||
TogglesSet togglesIsProvided;
|
||||
TogglesSet providedTogglesEnabled;
|
||||
|
||||
static TripleStateTogglesSet CreateFromTogglesDeviceDescriptor(
|
||||
const DawnTogglesDeviceDescriptor* togglesDesc);
|
||||
// Provide a single toggle with given state.
|
||||
void Set(Toggle toggle, bool enabled);
|
||||
bool IsProvided(Toggle toggle) const;
|
||||
// Return true if the toggle is provided in enable list, and false otherwise.
|
||||
bool IsEnabled(Toggle toggle) const;
|
||||
// Return true if the toggle is provided in disable list, and false otherwise.
|
||||
bool IsDisabled(Toggle toggle) const;
|
||||
std::vector<const char*> GetEnabledToggleNames() const;
|
||||
std::vector<const char*> GetDisabledToggleNames() const;
|
||||
};
|
||||
|
||||
const char* ToggleEnumToName(Toggle toggle);
|
||||
|
||||
class TogglesInfo {
|
||||
|
|
|
@ -147,6 +147,9 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
|||
dxcVersion >= MakeDXCVersion(kLeastMajorVersionForDP4a, kLeastMinorVersionForDP4a)) {
|
||||
mSupportedFeatures.EnableFeature(Feature::ChromiumExperimentalDp4a);
|
||||
}
|
||||
if (mDeviceInfo.supportsShaderF16) {
|
||||
mSupportedFeatures.EnableFeature(Feature::ShaderF16);
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -312,6 +315,20 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
|
|||
return {};
|
||||
}
|
||||
|
||||
MaybeError Adapter::ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
// shader-f16 feature and chromium-experimental-dp4a feature require DXC for D3D12.
|
||||
if (feature == wgpu::FeatureName::ShaderF16 ||
|
||||
feature == wgpu::FeatureName::ChromiumExperimentalDp4a) {
|
||||
DAWN_INVALID_IF(!(userProvidedToggles.IsEnabled(Toggle::UseDXC) &&
|
||||
mBackend->GetFunctions()->IsDXCAvailable()),
|
||||
"Feature %s requires DXC for D3D12.",
|
||||
GetInstance()->GetFeatureInfo(feature)->name);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError Adapter::InitializeDebugLayerFilters() {
|
||||
if (!GetInstance()->IsBackendValidationEnabled()) {
|
||||
return {};
|
||||
|
@ -418,8 +435,10 @@ void Adapter::CleanUpDebugLayerFilters() {
|
|||
infoQueue->PopStorageFilter();
|
||||
}
|
||||
|
||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
||||
return Device::Create(this, descriptor);
|
||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
return Device::Create(this, descriptor, userProvidedToggles);
|
||||
}
|
||||
|
||||
// Resets the backend device and creates a new one. If any D3D12 objects belonging to the
|
||||
|
|
|
@ -40,7 +40,9 @@ class Adapter : public AdapterBase {
|
|||
const gpu_info::D3DDriverVersion& GetDriverVersion() const;
|
||||
|
||||
private:
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(const DeviceDescriptor* descriptor) override;
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) override;
|
||||
MaybeError ResetInternalDeviceForTestingImpl() override;
|
||||
|
||||
bool AreTimestampQueriesSupported() const;
|
||||
|
@ -49,6 +51,10 @@ class Adapter : public AdapterBase {
|
|||
MaybeError InitializeSupportedFeaturesImpl() override;
|
||||
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override;
|
||||
|
||||
MaybeError ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) override;
|
||||
|
||||
MaybeError InitializeDebugLayerFilters();
|
||||
void CleanUpDebugLayerFilters();
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ ResultOrError<D3D12DeviceInfo> GatherDeviceInfo(const Adapter& adapter) {
|
|||
info.shaderProfiles[SingleShaderStage::Fragment] = L"p" + profileSuffix;
|
||||
info.shaderProfiles[SingleShaderStage::Compute] = L"c" + profileSuffix;
|
||||
|
||||
info.supportsShaderFloat16 =
|
||||
info.supportsShaderF16 =
|
||||
driverShaderModel >= D3D_SHADER_MODEL_6_2 && featureOptions4.Native16BitShaderOpsSupported;
|
||||
|
||||
info.supportsDP4a = driverShaderModel >= D3D_SHADER_MODEL_6_4;
|
||||
|
|
|
@ -27,7 +27,7 @@ struct D3D12DeviceInfo {
|
|||
bool isUMA;
|
||||
uint32_t resourceHeapTier;
|
||||
bool supportsRenderPass;
|
||||
bool supportsShaderFloat16;
|
||||
bool supportsShaderF16;
|
||||
// shaderModel indicates the maximum supported shader model, for example, the value 62
|
||||
// indicates that current driver supports the maximum shader model is shader model 6.2.
|
||||
uint32_t shaderModel;
|
||||
|
|
|
@ -63,8 +63,10 @@ static constexpr uint64_t kZeroBufferSize = 1024 * 1024 * 4; // 4 Mb
|
|||
static constexpr uint64_t kMaxDebugMessagesToPrint = 5;
|
||||
|
||||
// static
|
||||
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter, const DeviceDescriptor* descriptor) {
|
||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor));
|
||||
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor, userProvidedToggles));
|
||||
DAWN_TRY(device->Initialize(descriptor));
|
||||
return device;
|
||||
}
|
||||
|
@ -84,7 +86,7 @@ MaybeError Device::Initialize(const DeviceDescriptor* descriptor) {
|
|||
CheckHRESULT(mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)),
|
||||
"D3D12 create command queue"));
|
||||
|
||||
if (IsFeatureEnabled(Feature::TimestampQuery) &&
|
||||
if (HasFeature(Feature::TimestampQuery) &&
|
||||
!IsToggleEnabled(Toggle::DisableTimestampQueryConversion)) {
|
||||
// Get GPU timestamp counter frequency (in ticks/second). This fails if the specified
|
||||
// command queue doesn't support timestamps. D3D12_COMMAND_LIST_TYPE_DIRECT queues
|
||||
|
@ -876,17 +878,6 @@ bool Device::ShouldDuplicateNumWorkgroupsForDispatchIndirect(
|
|||
return ToBackend(computePipeline)->UsesNumWorkgroups();
|
||||
}
|
||||
|
||||
bool Device::IsFeatureEnabled(Feature feature) const {
|
||||
// Currently we can only use DXC to compile HLSL shaders using float16, and
|
||||
// ChromiumExperimentalDp4a is an experimental feature which can only be enabled with toggle
|
||||
// "use_dxc".
|
||||
if ((feature == Feature::ChromiumExperimentalDp4a || feature == Feature::ShaderFloat16) &&
|
||||
!IsToggleEnabled(Toggle::UseDXC)) {
|
||||
return false;
|
||||
}
|
||||
return DeviceBase::IsFeatureEnabled(feature);
|
||||
}
|
||||
|
||||
void Device::SetLabelImpl() {
|
||||
SetDebugName(this, mD3d12Device.Get(), "Dawn_Device", GetLabel());
|
||||
}
|
||||
|
|
|
@ -46,7 +46,9 @@ class StagingDescriptorAllocator;
|
|||
// Definition of backend types
|
||||
class Device final : public DeviceBase {
|
||||
public:
|
||||
static ResultOrError<Ref<Device>> Create(Adapter* adapter, const DeviceDescriptor* descriptor);
|
||||
static ResultOrError<Ref<Device>> Create(Adapter* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles);
|
||||
~Device() override;
|
||||
|
||||
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
||||
|
@ -160,8 +162,6 @@ class Device final : public DeviceBase {
|
|||
bool ShouldDuplicateParametersForDrawIndirect(
|
||||
const RenderPipelineBase* renderPipelineBase) const override;
|
||||
|
||||
bool IsFeatureEnabled(Feature feature) const override;
|
||||
|
||||
uint64_t GetBufferCopyOffsetAlignmentForDepthStencil() const override;
|
||||
|
||||
// Dawn APIs
|
||||
|
|
|
@ -97,7 +97,7 @@ enum class Compiler { FXC, DXC };
|
|||
X(bool, dumpShaders)
|
||||
|
||||
#define D3D_BYTECODE_COMPILATION_REQUEST_MEMBERS(X) \
|
||||
X(bool, hasShaderFloat16Feature) \
|
||||
X(bool, hasShaderF16Feature) \
|
||||
X(uint32_t, compileFlags) \
|
||||
X(Compiler, compiler) \
|
||||
X(uint64_t, compilerVersion) \
|
||||
|
@ -186,8 +186,7 @@ ResultOrError<ComPtr<IDxcBlob>> CompileShaderDXC(const D3DBytecodeCompilationReq
|
|||
std::wstring entryPointW;
|
||||
DAWN_TRY_ASSIGN(entryPointW, ConvertStringToWstring(entryPointName));
|
||||
|
||||
std::vector<const wchar_t*> arguments =
|
||||
GetDXCArguments(r.compileFlags, r.hasShaderFloat16Feature);
|
||||
std::vector<const wchar_t*> arguments = GetDXCArguments(r.compileFlags, r.hasShaderF16Feature);
|
||||
|
||||
ComPtr<IDxcOperationResult> result;
|
||||
DAWN_TRY(CheckHRESULT(r.dxcCompiler->Compile(sourceBlob.Get(), nullptr, entryPointW.c_str(),
|
||||
|
@ -475,7 +474,7 @@ ResultOrError<CompiledShader> ShaderModule::Compile(const ProgrammableStage& pro
|
|||
req.hlsl.disableWorkgroupInit = device->IsToggleEnabled(Toggle::DisableWorkgroupInit);
|
||||
req.hlsl.dumpShaders = device->IsToggleEnabled(Toggle::DumpShaders);
|
||||
|
||||
req.bytecode.hasShaderFloat16Feature = device->IsFeatureEnabled(Feature::ShaderFloat16);
|
||||
req.bytecode.hasShaderF16Feature = device->HasFeature(Feature::ShaderF16);
|
||||
req.bytecode.compileFlags = compileFlags;
|
||||
|
||||
if (device->IsToggleEnabled(Toggle::UseDXC)) {
|
||||
|
|
|
@ -299,8 +299,10 @@ class Adapter : public AdapterBase {
|
|||
}
|
||||
|
||||
private:
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(const DeviceDescriptor* descriptor) override {
|
||||
return Device::Create(this, mDevice, descriptor);
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) override {
|
||||
return Device::Create(this, mDevice, descriptor, userProvidedToggles);
|
||||
}
|
||||
|
||||
MaybeError InitializeImpl() override { return {}; }
|
||||
|
@ -378,6 +380,8 @@ class Adapter : public AdapterBase {
|
|||
|
||||
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
||||
|
||||
mSupportedFeatures.EnableFeature(Feature::ShaderF16);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -620,6 +624,12 @@ class Adapter : public AdapterBase {
|
|||
return {};
|
||||
}
|
||||
|
||||
MaybeError ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) override {
|
||||
return {};
|
||||
}
|
||||
|
||||
NSPRef<id<MTLDevice>> mDevice;
|
||||
};
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ class Device final : public DeviceBase {
|
|||
public:
|
||||
static ResultOrError<Ref<Device>> Create(AdapterBase* adapter,
|
||||
NSPRef<id<MTLDevice>> mtlDevice,
|
||||
const DeviceDescriptor* descriptor);
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles);
|
||||
~Device() override;
|
||||
|
||||
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
||||
|
@ -74,7 +75,8 @@ class Device final : public DeviceBase {
|
|||
private:
|
||||
Device(AdapterBase* adapter,
|
||||
NSPRef<id<MTLDevice>> mtlDevice,
|
||||
const DeviceDescriptor* descriptor);
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles);
|
||||
|
||||
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
|
||||
const BindGroupDescriptor* descriptor) override;
|
||||
|
|
|
@ -107,16 +107,21 @@ void API_AVAILABLE(macos(10.15), ios(14)) UpdateTimestampPeriod(id<MTLDevice> de
|
|||
// static
|
||||
ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
|
||||
NSPRef<id<MTLDevice>> mtlDevice,
|
||||
const DeviceDescriptor* descriptor) {
|
||||
Ref<Device> device = AcquireRef(new Device(adapter, std::move(mtlDevice), descriptor));
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
Ref<Device> device =
|
||||
AcquireRef(new Device(adapter, std::move(mtlDevice), descriptor, userProvidedToggles));
|
||||
DAWN_TRY(device->Initialize(descriptor));
|
||||
return device;
|
||||
}
|
||||
|
||||
Device::Device(AdapterBase* adapter,
|
||||
NSPRef<id<MTLDevice>> mtlDevice,
|
||||
const DeviceDescriptor* descriptor)
|
||||
: DeviceBase(adapter, descriptor), mMtlDevice(std::move(mtlDevice)), mCompletedSerial(0) {}
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles)
|
||||
: DeviceBase(adapter, descriptor, userProvidedToggles),
|
||||
mMtlDevice(std::move(mtlDevice)),
|
||||
mCompletedSerial(0) {}
|
||||
|
||||
Device::~Device() {
|
||||
Destroy();
|
||||
|
@ -132,7 +137,7 @@ MaybeError Device::Initialize(const DeviceDescriptor* descriptor) {
|
|||
|
||||
DAWN_TRY(mCommandContext.PrepareNextCommandBuffer(*mCommandQueue));
|
||||
|
||||
if (IsFeatureEnabled(Feature::TimestampQuery) &&
|
||||
if (HasFeature(Feature::TimestampQuery) &&
|
||||
!IsToggleEnabled(Toggle::DisableTimestampQueryConversion)) {
|
||||
// Make a best guess of timestamp period based on device vendor info, and converge it to
|
||||
// an accurate value by the following calculations.
|
||||
|
@ -322,7 +327,7 @@ MaybeError Device::TickImpl() {
|
|||
DAWN_TRY(SubmitPendingCommandBuffer());
|
||||
|
||||
// Just run timestamp period calculation when timestamp feature is enabled.
|
||||
if (IsFeatureEnabled(Feature::TimestampQuery)) {
|
||||
if (HasFeature(Feature::TimestampQuery)) {
|
||||
if (@available(macos 10.15, iOS 14.0, *)) {
|
||||
UpdateTimestampPeriod(GetMTLDevice(), mKalmanInfo.get(), &mCpuTimestamp, &mGpuTimestamp,
|
||||
&mTimestampPeriod);
|
||||
|
|
|
@ -65,8 +65,16 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
|
|||
return {};
|
||||
}
|
||||
|
||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
||||
return Device::Create(this, descriptor);
|
||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
return Device::Create(this, descriptor, userProvidedToggles);
|
||||
}
|
||||
|
||||
MaybeError Adapter::ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
return {};
|
||||
}
|
||||
|
||||
class Backend : public BackendConnection {
|
||||
|
@ -103,8 +111,10 @@ struct CopyFromStagingToBufferOperation : PendingOperation {
|
|||
// Device
|
||||
|
||||
// static
|
||||
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter, const DeviceDescriptor* descriptor) {
|
||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor));
|
||||
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor, userProvidedToggles));
|
||||
DAWN_TRY(device->Initialize(descriptor));
|
||||
return device;
|
||||
}
|
||||
|
|
|
@ -89,7 +89,9 @@ struct PendingOperation {
|
|||
|
||||
class Device final : public DeviceBase {
|
||||
public:
|
||||
static ResultOrError<Ref<Device>> Create(Adapter* adapter, const DeviceDescriptor* descriptor);
|
||||
static ResultOrError<Ref<Device>> Create(Adapter* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles);
|
||||
~Device() override;
|
||||
|
||||
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
||||
|
@ -182,7 +184,13 @@ class Adapter : public AdapterBase {
|
|||
MaybeError InitializeSupportedFeaturesImpl() override;
|
||||
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override;
|
||||
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(const DeviceDescriptor* descriptor) override;
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) override;
|
||||
|
||||
MaybeError ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) override;
|
||||
};
|
||||
|
||||
// Helper class so |BindGroup| can allocate memory for its binding data,
|
||||
|
|
|
@ -141,6 +141,11 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
|||
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
||||
}
|
||||
|
||||
// ShaderF16
|
||||
if (mFunctions.IsGLExtensionSupported("GL_AMD_gpu_shader_half_float")) {
|
||||
mSupportedFeatures.EnableFeature(Feature::ShaderF16);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -149,12 +154,20 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
|
|||
return {};
|
||||
}
|
||||
|
||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
EGLenum api =
|
||||
GetBackendType() == wgpu::BackendType::OpenGL ? EGL_OPENGL_API : EGL_OPENGL_ES_API;
|
||||
std::unique_ptr<Device::Context> context;
|
||||
DAWN_TRY_ASSIGN(context, ContextEGL::Create(mEGLFunctions, api));
|
||||
return Device::Create(this, descriptor, mFunctions, std::move(context));
|
||||
return Device::Create(this, descriptor, mFunctions, std::move(context), userProvidedToggles);
|
||||
}
|
||||
|
||||
MaybeError Adapter::ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace dawn::native::opengl
|
||||
|
|
|
@ -36,7 +36,13 @@ class Adapter : public AdapterBase {
|
|||
MaybeError InitializeImpl() override;
|
||||
MaybeError InitializeSupportedFeaturesImpl() override;
|
||||
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override;
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(const DeviceDescriptor* descriptor) override;
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) override;
|
||||
|
||||
MaybeError ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) override;
|
||||
|
||||
OpenGLFunctions mFunctions;
|
||||
EGLFunctions mEGLFunctions;
|
||||
|
|
|
@ -108,8 +108,10 @@ namespace dawn::native::opengl {
|
|||
ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const OpenGLFunctions& functions,
|
||||
std::unique_ptr<Context> context) {
|
||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor, functions, std::move(context)));
|
||||
std::unique_ptr<Context> context,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
Ref<Device> device = AcquireRef(
|
||||
new Device(adapter, descriptor, functions, std::move(context), userProvidedToggles));
|
||||
DAWN_TRY(device->Initialize(descriptor));
|
||||
return device;
|
||||
}
|
||||
|
@ -117,8 +119,11 @@ ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
|
|||
Device::Device(AdapterBase* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const OpenGLFunctions& functions,
|
||||
std::unique_ptr<Context> context)
|
||||
: DeviceBase(adapter, descriptor), mGL(functions), mContext(std::move(context)) {}
|
||||
std::unique_ptr<Context> context,
|
||||
const TripleStateTogglesSet& userProvidedToggles)
|
||||
: DeviceBase(adapter, descriptor, userProvidedToggles),
|
||||
mGL(functions),
|
||||
mContext(std::move(context)) {}
|
||||
|
||||
Device::~Device() {
|
||||
Destroy();
|
||||
|
|
|
@ -43,7 +43,8 @@ class Device final : public DeviceBase {
|
|||
static ResultOrError<Ref<Device>> Create(AdapterBase* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const OpenGLFunctions& functions,
|
||||
std::unique_ptr<Context> context);
|
||||
std::unique_ptr<Context> context,
|
||||
const TripleStateTogglesSet& userProvidedToggles);
|
||||
~Device() override;
|
||||
|
||||
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
||||
|
@ -93,7 +94,8 @@ class Device final : public DeviceBase {
|
|||
Device(AdapterBase* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const OpenGLFunctions& functions,
|
||||
std::unique_ptr<Context> context);
|
||||
std::unique_ptr<Context> context,
|
||||
const TripleStateTogglesSet& userProvidedToggles);
|
||||
|
||||
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
|
||||
const BindGroupDescriptor* descriptor) override;
|
||||
|
|
|
@ -159,6 +159,15 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
|||
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
||||
}
|
||||
|
||||
if (mDeviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) &&
|
||||
mDeviceInfo.HasExt(DeviceExt::_16BitStorage) &&
|
||||
mDeviceInfo.shaderFloat16Int8Features.shaderFloat16 == VK_TRUE &&
|
||||
mDeviceInfo._16BitStorageFeatures.storageBuffer16BitAccess == VK_TRUE &&
|
||||
mDeviceInfo._16BitStorageFeatures.storageInputOutput16 == VK_TRUE &&
|
||||
mDeviceInfo._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE) {
|
||||
mSupportedFeatures.EnableFeature(Feature::ShaderF16);
|
||||
}
|
||||
|
||||
if (mDeviceInfo.HasExt(DeviceExt::ShaderIntegerDotProduct) &&
|
||||
mDeviceInfo.shaderIntegerDotProductProperties
|
||||
.integerDotProduct4x8BitPackedSignedAccelerated == VK_TRUE &&
|
||||
|
@ -354,8 +363,16 @@ bool Adapter::SupportsExternalImages() const {
|
|||
mVulkanInstance->GetFunctions());
|
||||
}
|
||||
|
||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
||||
return Device::Create(this, descriptor);
|
||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
return Device::Create(this, descriptor, userProvidedToggles);
|
||||
}
|
||||
|
||||
MaybeError Adapter::ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace dawn::native::vulkan
|
||||
|
|
|
@ -46,7 +46,13 @@ class Adapter : public AdapterBase {
|
|||
MaybeError InitializeSupportedFeaturesImpl() override;
|
||||
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override;
|
||||
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(const DeviceDescriptor* descriptor) override;
|
||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) override;
|
||||
|
||||
MaybeError ValidateFeatureSupportedWithTogglesImpl(
|
||||
wgpu::FeatureName feature,
|
||||
const TripleStateTogglesSet& userProvidedToggles) override;
|
||||
|
||||
VkPhysicalDevice mPhysicalDevice;
|
||||
Ref<VulkanInstance> mVulkanInstance;
|
||||
|
|
|
@ -78,14 +78,19 @@ class ScopedSignalSemaphore : public NonMovable {
|
|||
} // namespace
|
||||
|
||||
// static
|
||||
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter, const DeviceDescriptor* descriptor) {
|
||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor));
|
||||
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles) {
|
||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor, userProvidedToggles));
|
||||
DAWN_TRY(device->Initialize(descriptor));
|
||||
return device;
|
||||
}
|
||||
|
||||
Device::Device(Adapter* adapter, const DeviceDescriptor* descriptor)
|
||||
: DeviceBase(adapter, descriptor), mDebugPrefix(GetNextDeviceDebugPrefix()) {
|
||||
Device::Device(Adapter* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles)
|
||||
: DeviceBase(adapter, descriptor, userProvidedToggles),
|
||||
mDebugPrefix(GetNextDeviceDebugPrefix()) {
|
||||
InitTogglesFromDriver();
|
||||
}
|
||||
|
||||
|
@ -449,29 +454,29 @@ ResultOrError<VulkanDeviceKnobs> Device::CreateDevice(VkPhysicalDevice physicalD
|
|||
usedKnobs.features.samplerAnisotropy = VK_TRUE;
|
||||
}
|
||||
|
||||
if (IsFeatureEnabled(Feature::TextureCompressionBC)) {
|
||||
if (HasFeature(Feature::TextureCompressionBC)) {
|
||||
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.textureCompressionBC == VK_TRUE);
|
||||
usedKnobs.features.textureCompressionBC = VK_TRUE;
|
||||
}
|
||||
|
||||
if (IsFeatureEnabled(Feature::TextureCompressionETC2)) {
|
||||
if (HasFeature(Feature::TextureCompressionETC2)) {
|
||||
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.textureCompressionETC2 == VK_TRUE);
|
||||
usedKnobs.features.textureCompressionETC2 = VK_TRUE;
|
||||
}
|
||||
|
||||
if (IsFeatureEnabled(Feature::TextureCompressionASTC)) {
|
||||
if (HasFeature(Feature::TextureCompressionASTC)) {
|
||||
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.textureCompressionASTC_LDR ==
|
||||
VK_TRUE);
|
||||
usedKnobs.features.textureCompressionASTC_LDR = VK_TRUE;
|
||||
}
|
||||
|
||||
if (IsFeatureEnabled(Feature::PipelineStatisticsQuery)) {
|
||||
if (HasFeature(Feature::PipelineStatisticsQuery)) {
|
||||
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.pipelineStatisticsQuery ==
|
||||
VK_TRUE);
|
||||
usedKnobs.features.pipelineStatisticsQuery = VK_TRUE;
|
||||
}
|
||||
|
||||
if (IsFeatureEnabled(Feature::DepthClipControl)) {
|
||||
if (HasFeature(Feature::DepthClipControl)) {
|
||||
const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
|
||||
ASSERT(deviceInfo.HasExt(DeviceExt::DepthClipEnable) &&
|
||||
deviceInfo.depthClipEnableFeatures.depthClipEnable == VK_TRUE);
|
||||
|
@ -481,16 +486,20 @@ ResultOrError<VulkanDeviceKnobs> Device::CreateDevice(VkPhysicalDevice physicalD
|
|||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT);
|
||||
}
|
||||
|
||||
if (IsFeatureEnabled(Feature::ShaderFloat16)) {
|
||||
// TODO(dawn:1510, tint:1473): After implementing a transform to handle the pipeline input /
|
||||
// output if necessary, relax the requirement of storageInputOutput16.
|
||||
if (HasFeature(Feature::ShaderF16)) {
|
||||
const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
|
||||
ASSERT(deviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) &&
|
||||
deviceInfo.shaderFloat16Int8Features.shaderFloat16 == VK_TRUE &&
|
||||
deviceInfo.HasExt(DeviceExt::_16BitStorage) &&
|
||||
deviceInfo._16BitStorageFeatures.storageBuffer16BitAccess == VK_TRUE &&
|
||||
deviceInfo._16BitStorageFeatures.storageInputOutput16 == VK_TRUE &&
|
||||
deviceInfo._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE);
|
||||
|
||||
usedKnobs.shaderFloat16Int8Features.shaderFloat16 = VK_TRUE;
|
||||
usedKnobs._16BitStorageFeatures.storageBuffer16BitAccess = VK_TRUE;
|
||||
usedKnobs._16BitStorageFeatures.storageInputOutput16 = VK_TRUE;
|
||||
usedKnobs._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE;
|
||||
|
||||
featuresChain.Add(&usedKnobs.shaderFloat16Int8Features,
|
||||
|
|
|
@ -43,7 +43,9 @@ class ResourceMemoryAllocator;
|
|||
|
||||
class Device final : public DeviceBase {
|
||||
public:
|
||||
static ResultOrError<Ref<Device>> Create(Adapter* adapter, const DeviceDescriptor* descriptor);
|
||||
static ResultOrError<Ref<Device>> Create(Adapter* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles);
|
||||
~Device() override;
|
||||
|
||||
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
||||
|
@ -113,7 +115,9 @@ class Device final : public DeviceBase {
|
|||
const char* GetDebugPrefix() { return mDebugPrefix.c_str(); }
|
||||
|
||||
private:
|
||||
Device(Adapter* adapter, const DeviceDescriptor* descriptor);
|
||||
Device(Adapter* adapter,
|
||||
const DeviceDescriptor* descriptor,
|
||||
const TripleStateTogglesSet& userProvidedToggles);
|
||||
|
||||
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
|
||||
const BindGroupDescriptor* descriptor) override;
|
||||
|
|
|
@ -436,7 +436,7 @@ MaybeError RenderPipeline::Initialize() {
|
|||
PNextChainBuilder rasterizationChain(&rasterization);
|
||||
VkPipelineRasterizationDepthClipStateCreateInfoEXT depthClipState;
|
||||
if (HasUnclippedDepth()) {
|
||||
ASSERT(device->IsFeatureEnabled(Feature::DepthClipControl));
|
||||
ASSERT(device->HasFeature(Feature::DepthClipControl));
|
||||
depthClipState.pNext = nullptr;
|
||||
depthClipState.depthClipEnable = VK_FALSE;
|
||||
depthClipState.flags = 0;
|
||||
|
|
|
@ -488,7 +488,7 @@ source_set("end2end_tests_sources") {
|
|||
"end2end/SamplerFilterAnisotropicTests.cpp",
|
||||
"end2end/SamplerTests.cpp",
|
||||
"end2end/ScissorTests.cpp",
|
||||
"end2end/ShaderFloat16Tests.cpp",
|
||||
"end2end/ShaderF16Tests.cpp",
|
||||
"end2end/ShaderTests.cpp",
|
||||
"end2end/ShaderValidationTests.cpp",
|
||||
"end2end/StorageTextureTests.cpp",
|
||||
|
|
|
@ -31,7 +31,18 @@ class ExperimentalDP4aTests : public DawnTestWithParams<ExperimentalDP4aTestsPar
|
|||
return {};
|
||||
}
|
||||
|
||||
if (GetParam().mRequestDP4aExtension) {
|
||||
if (!IsD3D12()) {
|
||||
mUseDxcEnabledOrNonD3D12 = true;
|
||||
} else {
|
||||
for (auto* enabledToggle : GetParam().forceEnabledWorkarounds) {
|
||||
if (strncmp(enabledToggle, "use_dxc", 7) == 0) {
|
||||
mUseDxcEnabledOrNonD3D12 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetParam().mRequestDP4aExtension && mUseDxcEnabledOrNonD3D12) {
|
||||
return {wgpu::FeatureName::ChromiumExperimentalDp4a};
|
||||
}
|
||||
|
||||
|
@ -39,9 +50,11 @@ class ExperimentalDP4aTests : public DawnTestWithParams<ExperimentalDP4aTestsPar
|
|||
}
|
||||
|
||||
bool IsDP4aSupportedOnAdapter() const { return mIsDP4aSupportedOnAdapter; }
|
||||
bool UseDxcEnabledOrNonD3D12() const { return mUseDxcEnabledOrNonD3D12; }
|
||||
|
||||
private:
|
||||
bool mIsDP4aSupportedOnAdapter = false;
|
||||
bool mUseDxcEnabledOrNonD3D12 = false;
|
||||
};
|
||||
|
||||
TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) {
|
||||
|
@ -67,12 +80,25 @@ TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) {
|
|||
buf.data4 = dot4U8Packed(a, c);
|
||||
}
|
||||
)";
|
||||
if (!GetParam().mRequestDP4aExtension || !IsDP4aSupportedOnAdapter() ||
|
||||
(IsD3D12() && !HasToggleEnabled("use_dxc"))) {
|
||||
const bool shouldDP4AFeatureSupportedByDevice =
|
||||
// Required when creating device
|
||||
GetParam().mRequestDP4aExtension &&
|
||||
// Adapter support the feature
|
||||
IsDP4aSupportedOnAdapter() &&
|
||||
// Proper toggle, disallow_unsafe_apis and use_dxc if d3d12
|
||||
// Note that "disallow_unsafe_apis" is always disabled in DawnTestBase::CreateDeviceImpl.
|
||||
!HasToggleEnabled("disallow_unsafe_apis") && UseDxcEnabledOrNonD3D12();
|
||||
const bool deviceSupportDP4AFeature =
|
||||
device.HasFeature(wgpu::FeatureName::ChromiumExperimentalDp4a);
|
||||
EXPECT_EQ(deviceSupportDP4AFeature, shouldDP4AFeatureSupportedByDevice);
|
||||
|
||||
if (!deviceSupportDP4AFeature) {
|
||||
ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, computeShader));
|
||||
return;
|
||||
}
|
||||
|
||||
utils::CreateShaderModule(device, computeShader);
|
||||
|
||||
wgpu::BufferDescriptor bufferDesc;
|
||||
bufferDesc.size = 4 * sizeof(uint32_t);
|
||||
bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
|
||||
|
@ -101,6 +127,11 @@ TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) {
|
|||
EXPECT_BUFFER_U32_RANGE_EQ(expected, bufferOut, 0, 4);
|
||||
}
|
||||
|
||||
// DawnTestBase::CreateDeviceImpl always disable disallow_unsafe_apis toggle.
|
||||
DAWN_INSTANTIATE_TEST_P(ExperimentalDP4aTests,
|
||||
{D3D12Backend(), D3D12Backend({"use_dxc"}), VulkanBackend()},
|
||||
{
|
||||
D3D12Backend(),
|
||||
D3D12Backend({"use_dxc"}, {}),
|
||||
VulkanBackend(),
|
||||
},
|
||||
{true, false});
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
// Copyright 2022 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 <vector>
|
||||
|
||||
#include "dawn/tests/DawnTest.h"
|
||||
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "dawn/utils/WGPUHelpers.h"
|
||||
|
||||
namespace {
|
||||
using RequireShaderF16Feature = bool;
|
||||
DAWN_TEST_PARAM_STRUCT(ShaderF16TestsParams, RequireShaderF16Feature);
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
class ShaderF16Tests : public DawnTestWithParams<ShaderF16TestsParams> {
|
||||
protected:
|
||||
std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
|
||||
mIsShaderF16SupportedOnAdapter = SupportsFeatures({wgpu::FeatureName::ShaderF16});
|
||||
if (!mIsShaderF16SupportedOnAdapter) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!IsD3D12()) {
|
||||
mUseDxcEnabledOrNonD3D12 = true;
|
||||
} else {
|
||||
for (auto* enabledToggle : GetParam().forceEnabledWorkarounds) {
|
||||
if (strncmp(enabledToggle, "use_dxc", 7) == 0) {
|
||||
mUseDxcEnabledOrNonD3D12 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetParam().mRequireShaderF16Feature && mUseDxcEnabledOrNonD3D12) {
|
||||
return {wgpu::FeatureName::ShaderF16};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool IsShaderF16SupportedOnAdapter() const { return mIsShaderF16SupportedOnAdapter; }
|
||||
bool UseDxcEnabledOrNonD3D12() const { return mUseDxcEnabledOrNonD3D12; }
|
||||
|
||||
private:
|
||||
bool mIsShaderF16SupportedOnAdapter = false;
|
||||
bool mUseDxcEnabledOrNonD3D12 = false;
|
||||
};
|
||||
|
||||
TEST_P(ShaderF16Tests, BasicShaderF16FeaturesTest) {
|
||||
const char* computeShader = R"(
|
||||
enable f16;
|
||||
|
||||
struct Buf {
|
||||
v : f32,
|
||||
}
|
||||
@group(0) @binding(0) var<storage, read_write> buf : Buf;
|
||||
|
||||
@compute @workgroup_size(1)
|
||||
fn CSMain() {
|
||||
let a : f16 = f16(buf.v) + 1.0h;
|
||||
buf.v = f32(a);
|
||||
}
|
||||
)";
|
||||
|
||||
const bool shouldShaderF16FeatureSupportedByDevice =
|
||||
// Required when creating device
|
||||
GetParam().mRequireShaderF16Feature &&
|
||||
// Adapter support the feature
|
||||
IsShaderF16SupportedOnAdapter() &&
|
||||
// Proper toggle, disallow_unsafe_apis and use_dxc if d3d12
|
||||
// Note that "disallow_unsafe_apis" is always disabled in DawnTestBase::CreateDeviceImpl.
|
||||
!HasToggleEnabled("disallow_unsafe_apis") && UseDxcEnabledOrNonD3D12();
|
||||
const bool deviceSupportShaderF16Feature = device.HasFeature(wgpu::FeatureName::ShaderF16);
|
||||
EXPECT_EQ(deviceSupportShaderF16Feature, shouldShaderF16FeatureSupportedByDevice);
|
||||
|
||||
if (!deviceSupportShaderF16Feature) {
|
||||
ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, computeShader));
|
||||
return;
|
||||
}
|
||||
|
||||
wgpu::BufferDescriptor bufferDesc;
|
||||
bufferDesc.size = 4u;
|
||||
bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
|
||||
wgpu::Buffer bufferOut = device.CreateBuffer(&bufferDesc);
|
||||
|
||||
wgpu::ComputePipelineDescriptor csDesc;
|
||||
csDesc.compute.module = utils::CreateShaderModule(device, computeShader);
|
||||
csDesc.compute.entryPoint = "CSMain";
|
||||
wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);
|
||||
|
||||
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
|
||||
{
|
||||
{0, bufferOut},
|
||||
});
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.SetPipeline(pipeline);
|
||||
pass.SetBindGroup(0, bindGroup);
|
||||
pass.DispatchWorkgroups(1);
|
||||
pass.End();
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
|
||||
uint32_t expected[] = {0x3f800000}; // 1.0f
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(expected, bufferOut, 0, 1);
|
||||
}
|
||||
|
||||
// DawnTestBase::CreateDeviceImpl always disable disallow_unsafe_apis toggle.
|
||||
DAWN_INSTANTIATE_TEST_P(ShaderF16Tests,
|
||||
{
|
||||
D3D12Backend(),
|
||||
D3D12Backend({"use_dxc"}),
|
||||
VulkanBackend(),
|
||||
MetalBackend(),
|
||||
OpenGLBackend(),
|
||||
OpenGLESBackend(),
|
||||
},
|
||||
{true, false});
|
|
@ -1,178 +0,0 @@
|
|||
// Copyright 2020 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 <vector>
|
||||
|
||||
#include "dawn/common/Math.h"
|
||||
#include "dawn/tests/DawnTest.h"
|
||||
#include "dawn/utils/WGPUHelpers.h"
|
||||
|
||||
class ShaderFloat16Tests : public DawnTest {
|
||||
protected:
|
||||
std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
|
||||
mIsShaderFloat16Supported = SupportsFeatures({wgpu::FeatureName::DawnShaderFloat16});
|
||||
if (!mIsShaderFloat16Supported) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {wgpu::FeatureName::DawnShaderFloat16};
|
||||
}
|
||||
|
||||
bool IsShaderFloat16Supported() const { return mIsShaderFloat16Supported; }
|
||||
|
||||
bool mIsShaderFloat16Supported = false;
|
||||
};
|
||||
|
||||
// Test basic 16bit float arithmetic and 16bit storage features.
|
||||
// TODO(crbug.com/tint/404): Implement float16 in Tint.
|
||||
TEST_P(ShaderFloat16Tests, DISABLED_Basic16BitFloatFeaturesTest) {
|
||||
DAWN_TEST_UNSUPPORTED_IF(!IsShaderFloat16Supported());
|
||||
DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsIntel()); // Flaky crashes. crbug.com/dawn/586
|
||||
|
||||
uint16_t uniformData[] = {Float32ToFloat16(1.23), Float32ToFloat16(0.0)}; // 0.0 is a padding.
|
||||
wgpu::Buffer uniformBuffer = utils::CreateBufferFromData(
|
||||
device, &uniformData, sizeof(uniformData), wgpu::BufferUsage::Uniform);
|
||||
|
||||
uint16_t bufferInData[] = {Float32ToFloat16(2.34), Float32ToFloat16(0.0)}; // 0.0 is a padding.
|
||||
wgpu::Buffer bufferIn = utils::CreateBufferFromData(device, &bufferInData, sizeof(bufferInData),
|
||||
wgpu::BufferUsage::Storage);
|
||||
|
||||
wgpu::BufferDescriptor bufferDesc;
|
||||
bufferDesc.size = 2 * sizeof(uint16_t);
|
||||
bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
|
||||
wgpu::Buffer bufferOut = device.CreateBuffer(&bufferDesc);
|
||||
|
||||
// SPIR-V ASM produced by glslang for the following fragment shader:
|
||||
//
|
||||
// #version 450
|
||||
// #extension GL_AMD_gpu_shader_half_float : require
|
||||
//
|
||||
// struct S {
|
||||
// float16_t f;
|
||||
// float16_t padding;
|
||||
// };
|
||||
// layout(std140, set = 0, binding = 0) uniform uniformBuf { S c; };
|
||||
// layout(std140, set = 0, binding = 1) readonly buffer bufA { S a; };
|
||||
// layout(std140, set = 0, binding = 2) buffer bufB { S b; };
|
||||
//
|
||||
// void main() {
|
||||
// b.f = a.f + c.f;
|
||||
// }
|
||||
|
||||
wgpu::ShaderModule module = utils::CreateShaderModuleFromASM(device, R"(
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 10
|
||||
; Bound: 26
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpCapability Float16
|
||||
OpCapability StorageBuffer16BitAccess
|
||||
OpCapability UniformAndStorageBuffer16BitAccess
|
||||
OpExtension "SPV_KHR_16bit_storage"
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpSource GLSL 450
|
||||
OpSourceExtension "GL_AMD_gpu_shader_half_float"
|
||||
OpName %main "main"
|
||||
OpName %S "S"
|
||||
OpMemberName %S 0 "f"
|
||||
OpMemberName %S 1 "padding"
|
||||
OpName %bufB "bufB"
|
||||
OpMemberName %bufB 0 "b"
|
||||
OpName %_ ""
|
||||
OpName %bufA "bufA"
|
||||
OpMemberName %bufA 0 "a"
|
||||
OpName %__0 ""
|
||||
OpName %uniformBuf "uniformBuf"
|
||||
OpMemberName %uniformBuf 0 "c"
|
||||
OpName %__1 ""
|
||||
OpMemberDecorate %S 0 Offset 0
|
||||
OpMemberDecorate %S 1 Offset 2
|
||||
OpMemberDecorate %bufB 0 Offset 0
|
||||
OpDecorate %bufB BufferBlock
|
||||
OpDecorate %_ DescriptorSet 0
|
||||
OpDecorate %_ Binding 2
|
||||
OpMemberDecorate %bufA 0 NonWritable
|
||||
OpMemberDecorate %bufA 0 Offset 0
|
||||
OpDecorate %bufA BufferBlock
|
||||
OpDecorate %__0 DescriptorSet 0
|
||||
OpDecorate %__0 Binding 1
|
||||
OpMemberDecorate %uniformBuf 0 Offset 0
|
||||
OpDecorate %uniformBuf Block
|
||||
OpDecorate %__1 DescriptorSet 0
|
||||
OpDecorate %__1 Binding 0
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%half = OpTypeFloat 16
|
||||
%S = OpTypeStruct %half %half
|
||||
%bufB = OpTypeStruct %S
|
||||
%_ptr_Uniform_bufB = OpTypePointer Uniform %bufB
|
||||
%_ = OpVariable %_ptr_Uniform_bufB Uniform
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%bufA = OpTypeStruct %S
|
||||
%_ptr_Uniform_bufA = OpTypePointer Uniform %bufA
|
||||
%__0 = OpVariable %_ptr_Uniform_bufA Uniform
|
||||
%_ptr_Uniform_half = OpTypePointer Uniform %half
|
||||
%uniformBuf = OpTypeStruct %S
|
||||
%_ptr_Uniform_uniformBuf = OpTypePointer Uniform %uniformBuf
|
||||
%__1 = OpVariable %_ptr_Uniform_uniformBuf Uniform
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%17 = OpAccessChain %_ptr_Uniform_half %__0 %int_0 %int_0
|
||||
%18 = OpLoad %half %17
|
||||
%22 = OpAccessChain %_ptr_Uniform_half %__1 %int_0 %int_0
|
||||
%23 = OpLoad %half %22
|
||||
%24 = OpFAdd %half %18 %23
|
||||
%25 = OpAccessChain %_ptr_Uniform_half %_ %int_0 %int_0
|
||||
OpStore %25 %24
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)");
|
||||
|
||||
wgpu::ComputePipelineDescriptor csDesc;
|
||||
csDesc.compute.module = module;
|
||||
csDesc.compute.entryPoint = "main";
|
||||
wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);
|
||||
|
||||
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
|
||||
{
|
||||
{0, uniformBuffer, 0, sizeof(uniformData)},
|
||||
{1, bufferIn, 0, sizeof(bufferInData)},
|
||||
{2, bufferOut},
|
||||
});
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
||||
pass.SetPipeline(pipeline);
|
||||
pass.SetBindGroup(0, bindGroup);
|
||||
pass.DispatchWorkgroups(1);
|
||||
pass.End();
|
||||
wgpu::CommandBuffer commands = encoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
|
||||
uint16_t expected[] = {Float32ToFloat16(3.57), Float32ToFloat16(0.0)}; // 0.0 is a padding.
|
||||
|
||||
EXPECT_BUFFER_U16_RANGE_EQ(expected, bufferOut, 0, 2);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(ShaderFloat16Tests,
|
||||
D3D12Backend(),
|
||||
MetalBackend(),
|
||||
OpenGLBackend(),
|
||||
OpenGLESBackend(),
|
||||
VulkanBackend());
|
|
@ -77,6 +77,14 @@ TEST_F(FeatureTests, GetEnabledFeatures) {
|
|||
deviceDescriptor.requiredFeatures = &featureName;
|
||||
deviceDescriptor.requiredFeaturesCount = 1;
|
||||
|
||||
// Some features may require DisallowUnsafeApis toggle disabled, otherwise CreateDevice may
|
||||
// failed.
|
||||
const char* const disableToggles[] = {"disallow_unsafe_apis"};
|
||||
wgpu::DawnTogglesDeviceDescriptor toggleDesc;
|
||||
toggleDesc.forceDisabledToggles = disableToggles;
|
||||
toggleDesc.forceDisabledTogglesCount = 1;
|
||||
deviceDescriptor.nextInChain = &toggleDesc;
|
||||
|
||||
dawn::native::DeviceBase* deviceBase = dawn::native::FromAPI(
|
||||
adapter.CreateDevice(reinterpret_cast<const WGPUDeviceDescriptor*>(&deviceDescriptor)));
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "dawn/dawn_proc.h"
|
||||
#include "dawn/native/DawnNative.h"
|
||||
|
@ -90,6 +91,42 @@ TEST_F(DeviceCreationTest, CreateDeviceWithTogglesSuccess) {
|
|||
EXPECT_THAT(toggles, Contains(StrEq(toggle)));
|
||||
}
|
||||
|
||||
// Test features guarded by toggles are validated when creating devices.
|
||||
TEST_F(DeviceCreationTest, CreateDeviceRequiringFeaturesGuardedByToggle) {
|
||||
std::vector<wgpu::FeatureName> featuresGuardedByToggle = {
|
||||
wgpu::FeatureName::ShaderF16, wgpu::FeatureName::ChromiumExperimentalDp4a};
|
||||
|
||||
for (auto feature : featuresGuardedByToggle) {
|
||||
wgpu::DeviceDescriptor deviceDescriptor;
|
||||
deviceDescriptor.requiredFeatures = &feature;
|
||||
deviceDescriptor.requiredFeaturesCount = 1;
|
||||
|
||||
// Test creating device without toggle would fail.
|
||||
{
|
||||
wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
|
||||
EXPECT_EQ(device, nullptr);
|
||||
}
|
||||
|
||||
// Test creating device without DisallowUnsafeApis toggle disabled.
|
||||
{
|
||||
const char* const disableToggles[] = {"disallow_unsafe_apis"};
|
||||
wgpu::DawnTogglesDeviceDescriptor toggleDesc;
|
||||
toggleDesc.forceDisabledToggles = disableToggles;
|
||||
toggleDesc.forceDisabledTogglesCount = 1;
|
||||
deviceDescriptor.nextInChain = &toggleDesc;
|
||||
|
||||
wgpu::Device device = adapter.CreateDevice(&deviceDescriptor);
|
||||
EXPECT_NE(device, nullptr);
|
||||
|
||||
ASSERT_EQ(1u, device.EnumerateFeatures(nullptr));
|
||||
wgpu::FeatureName enabledFeature;
|
||||
device.EnumerateFeatures(&enabledFeature);
|
||||
EXPECT_EQ(enabledFeature, feature);
|
||||
device.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DeviceCreationTest, CreateDeviceWithCacheSuccess) {
|
||||
// Default device descriptor should have the same cache key as a device descriptor with a
|
||||
// default cache descriptor.
|
||||
|
|
|
@ -23,6 +23,7 @@ bool IsFeatureSupported(WGPUFeatureName feature) {
|
|||
case WGPUFeatureName_Undefined:
|
||||
case WGPUFeatureName_Force32:
|
||||
case WGPUFeatureName_DawnNative:
|
||||
case WGPUFeatureName_DawnShaderFloat16: // Deprecated
|
||||
return false;
|
||||
case WGPUFeatureName_Depth32FloatStencil8:
|
||||
case WGPUFeatureName_TimestampQuery:
|
||||
|
@ -32,10 +33,10 @@ bool IsFeatureSupported(WGPUFeatureName feature) {
|
|||
case WGPUFeatureName_TextureCompressionASTC:
|
||||
case WGPUFeatureName_IndirectFirstInstance:
|
||||
case WGPUFeatureName_DepthClipControl:
|
||||
case WGPUFeatureName_DawnShaderFloat16:
|
||||
case WGPUFeatureName_DawnInternalUsages:
|
||||
case WGPUFeatureName_DawnMultiPlanarFormats:
|
||||
case WGPUFeatureName_ChromiumExperimentalDp4a:
|
||||
case WGPUFeatureName_ShaderF16:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue