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": 6, "name": "texture compression ETC2"},
|
||||||
{"value": 7, "name": "texture compression ASTC"},
|
{"value": 7, "name": "texture compression ASTC"},
|
||||||
{"value": 8, "name": "indirect first instance"},
|
{"value": 8, "name": "indirect first instance"},
|
||||||
|
{"value": 9, "name": "shader f16"},
|
||||||
{"value": 1001, "name": "dawn shader float 16", "tags": ["dawn"]},
|
{"value": 1001, "name": "dawn shader float 16", "tags": ["dawn"]},
|
||||||
{"value": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
|
{"value": 1002, "name": "dawn internal usages", "tags": ["dawn"]},
|
||||||
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
|
{"value": 1003, "name": "dawn multi planar formats", "tags": ["dawn"]},
|
||||||
|
|
|
@ -61,7 +61,15 @@ struct ToggleInfo {
|
||||||
// A struct to record the information of a feature. A feature is a GPU feature that is not
|
// 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
|
// required to be supported by all Dawn backends and can only be used when it is enabled on the
|
||||||
// creation of device.
|
// 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.
|
// 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
|
// 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/Constants.h"
|
||||||
#include "dawn/common/GPUInfo.h"
|
#include "dawn/common/GPUInfo.h"
|
||||||
|
#include "dawn/native/ChainUtils_autogen.h"
|
||||||
#include "dawn/native/Device.h"
|
#include "dawn/native/Device.h"
|
||||||
#include "dawn/native/Instance.h"
|
#include "dawn/native/Instance.h"
|
||||||
#include "dawn/native/ValidationUtils_autogen.h"
|
#include "dawn/native/ValidationUtils_autogen.h"
|
||||||
|
@ -189,15 +190,40 @@ bool AdapterBase::GetLimits(SupportedLimits* limits) const {
|
||||||
return true;
|
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(
|
ResultOrError<Ref<DeviceBase>> AdapterBase::CreateDeviceInternal(
|
||||||
const DeviceDescriptor* descriptor) {
|
const DeviceDescriptor* descriptor) {
|
||||||
ASSERT(descriptor != nullptr);
|
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) {
|
for (uint32_t i = 0; i < descriptor->requiredFeaturesCount; ++i) {
|
||||||
wgpu::FeatureName f = descriptor->requiredFeatures[i];
|
wgpu::FeatureName feature = descriptor->requiredFeatures[i];
|
||||||
DAWN_TRY(ValidateFeatureName(f));
|
DAWN_TRY(ValidateFeatureSupportedWithToggles(feature, userProvidedToggles));
|
||||||
DAWN_INVALID_IF(!mSupportedFeatures.IsEnabled(f), "Requested feature %s is not supported.",
|
|
||||||
f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor->requiredLimits != nullptr) {
|
if (descriptor->requiredLimits != nullptr) {
|
||||||
|
@ -208,7 +234,7 @@ ResultOrError<Ref<DeviceBase>> AdapterBase::CreateDeviceInternal(
|
||||||
DAWN_INVALID_IF(descriptor->requiredLimits->nextInChain != nullptr,
|
DAWN_INVALID_IF(descriptor->requiredLimits->nextInChain != nullptr,
|
||||||
"nextInChain is not nullptr.");
|
"nextInChain is not nullptr.");
|
||||||
}
|
}
|
||||||
return CreateDeviceImpl(descriptor);
|
return CreateDeviceImpl(descriptor, userProvidedToggles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdapterBase::SetUseTieredLimits(bool useTieredLimits) {
|
void AdapterBase::SetUseTieredLimits(bool useTieredLimits) {
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "dawn/native/Error.h"
|
#include "dawn/native/Error.h"
|
||||||
#include "dawn/native/Features.h"
|
#include "dawn/native/Features.h"
|
||||||
#include "dawn/native/Limits.h"
|
#include "dawn/native/Limits.h"
|
||||||
|
#include "dawn/native/Toggles.h"
|
||||||
#include "dawn/native/dawn_platform.h"
|
#include "dawn/native/dawn_platform.h"
|
||||||
|
|
||||||
namespace dawn::native {
|
namespace dawn::native {
|
||||||
|
@ -72,14 +73,24 @@ class AdapterBase : public RefCounted {
|
||||||
std::string mName;
|
std::string mName;
|
||||||
wgpu::AdapterType mAdapterType = wgpu::AdapterType::Unknown;
|
wgpu::AdapterType mAdapterType = wgpu::AdapterType::Unknown;
|
||||||
std::string mDriverDescription;
|
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;
|
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:
|
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;
|
virtual MaybeError InitializeImpl() = 0;
|
||||||
|
|
||||||
// Check base WebGPU features and discover supported featurees.
|
// Check base WebGPU features and discover supported features.
|
||||||
virtual MaybeError InitializeSupportedFeaturesImpl() = 0;
|
virtual MaybeError InitializeSupportedFeaturesImpl() = 0;
|
||||||
|
|
||||||
// Check base WebGPU limits and populate supported limits.
|
// Check base WebGPU limits and populate supported limits.
|
||||||
|
@ -87,6 +98,10 @@ class AdapterBase : public RefCounted {
|
||||||
|
|
||||||
virtual void InitializeVendorArchitectureImpl();
|
virtual void InitializeVendorArchitectureImpl();
|
||||||
|
|
||||||
|
virtual MaybeError ValidateFeatureSupportedWithTogglesImpl(
|
||||||
|
wgpu::FeatureName feature,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles) = 0;
|
||||||
|
|
||||||
ResultOrError<Ref<DeviceBase>> CreateDeviceInternal(const DeviceDescriptor* descriptor);
|
ResultOrError<Ref<DeviceBase>> CreateDeviceInternal(const DeviceDescriptor* descriptor);
|
||||||
|
|
||||||
virtual MaybeError ResetInternalDeviceForTestingImpl();
|
virtual MaybeError ResetInternalDeviceForTestingImpl();
|
||||||
|
|
|
@ -364,7 +364,7 @@ MaybeError ValidateCopyTextureForBrowser(DeviceBase* device,
|
||||||
source->texture->GetSampleCount(), destination->texture->GetSampleCount());
|
source->texture->GetSampleCount(), destination->texture->GetSampleCount());
|
||||||
|
|
||||||
DAWN_INVALID_IF(
|
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.");
|
"The internalUsage is true while the dawn-internal-usages feature is not enabled.");
|
||||||
UsageValidationMode mode =
|
UsageValidationMode mode =
|
||||||
options->internalUsage ? UsageValidationMode::Internal : UsageValidationMode::Default;
|
options->internalUsage ? UsageValidationMode::Internal : UsageValidationMode::Default;
|
||||||
|
|
|
@ -170,20 +170,19 @@ ResultOrError<Ref<PipelineLayoutBase>> ValidateLayoutAndGetRenderPipelineDescrip
|
||||||
|
|
||||||
// DeviceBase
|
// DeviceBase
|
||||||
|
|
||||||
DeviceBase::DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor)
|
DeviceBase::DeviceBase(AdapterBase* adapter,
|
||||||
: mAdapter(adapter), mNextPipelineCompatibilityToken(1) {
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles)
|
||||||
|
: mAdapter(adapter),
|
||||||
|
mEnabledToggles(userProvidedToggles.providedTogglesEnabled),
|
||||||
|
mOverridenToggles(userProvidedToggles.togglesIsProvided),
|
||||||
|
mNextPipelineCompatibilityToken(1) {
|
||||||
mAdapter->GetInstance()->IncrementDeviceCountForTesting();
|
mAdapter->GetInstance()->IncrementDeviceCountForTesting();
|
||||||
ASSERT(descriptor != nullptr);
|
ASSERT(descriptor != nullptr);
|
||||||
|
|
||||||
AdapterProperties adapterProperties;
|
AdapterProperties adapterProperties;
|
||||||
adapter->APIGetProperties(&adapterProperties);
|
adapter->APIGetProperties(&adapterProperties);
|
||||||
|
|
||||||
const DawnTogglesDeviceDescriptor* togglesDesc = nullptr;
|
|
||||||
FindInChain(descriptor->nextInChain, &togglesDesc);
|
|
||||||
if (togglesDesc != nullptr) {
|
|
||||||
ApplyToggleOverrides(togglesDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetDefaultToggles();
|
SetDefaultToggles();
|
||||||
ApplyFeatures(descriptor);
|
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);
|
return mEnabledFeatures.IsEnabled(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::SetWGSLExtensionAllowList() {
|
void DeviceBase::SetWGSLExtensionAllowList() {
|
||||||
// Set the WGSL extensions allow list based on device's enabled features and other
|
// Set the WGSL extensions allow list based on device's enabled features and other
|
||||||
// propority. For example:
|
// propority.
|
||||||
// mWGSLExtensionAllowList.insert("InternalExtensionForTesting");
|
if (mEnabledFeatures.IsEnabled(Feature::ChromiumExperimentalDp4a)) {
|
||||||
if (IsFeatureEnabled(Feature::ChromiumExperimentalDp4a)) {
|
|
||||||
mWGSLExtensionAllowList.insert("chromium_experimental_dp4a");
|
mWGSLExtensionAllowList.insert("chromium_experimental_dp4a");
|
||||||
}
|
}
|
||||||
|
if (mEnabledFeatures.IsEnabled(Feature::ShaderF16)) {
|
||||||
|
mWGSLExtensionAllowList.insert("f16");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WGSLExtensionSet DeviceBase::GetWGSLExtensionAllowList() const {
|
WGSLExtensionSet DeviceBase::GetWGSLExtensionAllowList() const {
|
||||||
|
@ -1800,27 +1801,6 @@ void DeviceBase::SetDefaultToggles() {
|
||||||
SetToggle(Toggle::DisallowUnsafeAPIs, true);
|
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() {
|
void DeviceBase::FlushCallbackTaskQueue() {
|
||||||
if (!mCallbackTaskManager->IsEmpty()) {
|
if (!mCallbackTaskManager->IsEmpty()) {
|
||||||
// If a user calls Queue::Submit inside the callback, then the device will be ticked,
|
// 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 {
|
class DeviceBase : public RefCountedWithExternalCount {
|
||||||
public:
|
public:
|
||||||
DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor);
|
DeviceBase(AdapterBase* adapter,
|
||||||
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles);
|
||||||
~DeviceBase() override;
|
~DeviceBase() override;
|
||||||
|
|
||||||
// Handles the error, causing a device loss if applicable. Almost always when a device loss
|
// 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();
|
QueueBase* APIGetQueue();
|
||||||
|
|
||||||
bool APIGetLimits(SupportedLimits* limits) const;
|
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;
|
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;
|
size_t APIEnumerateFeatures(wgpu::FeatureName* features) const;
|
||||||
void APIInjectError(wgpu::ErrorType type, const char* message);
|
void APIInjectError(wgpu::ErrorType type, const char* message);
|
||||||
bool APITick();
|
bool APITick();
|
||||||
|
@ -381,9 +379,7 @@ class DeviceBase : public RefCountedWithExternalCount {
|
||||||
virtual bool ShouldDuplicateParametersForDrawIndirect(
|
virtual bool ShouldDuplicateParametersForDrawIndirect(
|
||||||
const RenderPipelineBase* renderPipelineBase) const;
|
const RenderPipelineBase* renderPipelineBase) const;
|
||||||
|
|
||||||
// TODO(crbug.com/dawn/1434): Make this function non-overridable when we support requesting
|
bool HasFeature(Feature feature) const;
|
||||||
// Adapter with toggles.
|
|
||||||
virtual bool IsFeatureEnabled(Feature feature) const;
|
|
||||||
|
|
||||||
const CombinedLimits& GetLimits() const;
|
const CombinedLimits& GetLimits() const;
|
||||||
|
|
||||||
|
@ -482,7 +478,6 @@ class DeviceBase : public RefCountedWithExternalCount {
|
||||||
WGPUCreateRenderPipelineAsyncCallback callback,
|
WGPUCreateRenderPipelineAsyncCallback callback,
|
||||||
void* userdata);
|
void* userdata);
|
||||||
|
|
||||||
void ApplyToggleOverrides(const DawnTogglesDeviceDescriptor* togglesDescriptor);
|
|
||||||
void ApplyFeatures(const DeviceDescriptor* deviceDescriptor);
|
void ApplyFeatures(const DeviceDescriptor* deviceDescriptor);
|
||||||
|
|
||||||
void SetDefaultToggles();
|
void SetDefaultToggles();
|
||||||
|
|
|
@ -34,58 +34,64 @@ using FeatureEnumAndInfoList =
|
||||||
static constexpr FeatureEnumAndInfoList kFeatureNameAndInfoList = {{
|
static constexpr FeatureEnumAndInfoList kFeatureNameAndInfoList = {{
|
||||||
{Feature::TextureCompressionBC,
|
{Feature::TextureCompressionBC,
|
||||||
{"texture-compression-bc", "Support Block Compressed (BC) texture formats",
|
{"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,
|
{Feature::TextureCompressionETC2,
|
||||||
{"texture-compression-etc2",
|
{"texture-compression-etc2",
|
||||||
"Support Ericsson Texture Compressed (ETC2/EAC) texture "
|
"Support Ericsson Texture Compressed (ETC2/EAC) texture "
|
||||||
"formats",
|
"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,
|
{Feature::TextureCompressionASTC,
|
||||||
{"texture-compression-astc",
|
{"texture-compression-astc",
|
||||||
"Support Adaptable Scalable Texture Compressed (ASTC) "
|
"Support Adaptable Scalable Texture Compressed (ASTC) "
|
||||||
"texture formats",
|
"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::ShaderFloat16,
|
|
||||||
{"shader-float16",
|
|
||||||
"Support 16bit float arithmetic and declarations in uniform and storage buffers",
|
|
||||||
"https://bugs.chromium.org/p/dawn/issues/detail?id=426"}},
|
|
||||||
{Feature::PipelineStatisticsQuery,
|
{Feature::PipelineStatisticsQuery,
|
||||||
{"pipeline-statistics-query", "Support Pipeline Statistics Query",
|
{"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,
|
{Feature::TimestampQuery,
|
||||||
{"timestamp-query", "Support Timestamp Query",
|
{"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,
|
{Feature::DepthClipControl,
|
||||||
{"depth-clip-control", "Disable depth clipping of primitives to the clip volume",
|
{"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,
|
{Feature::Depth32FloatStencil8,
|
||||||
{"depth32float-stencil8", "Support depth32float-stencil8 texture format",
|
{"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,
|
{Feature::ChromiumExperimentalDp4a,
|
||||||
{"chromium-experimental-dp4a", "Support experimental DP4a instructions in WGSL",
|
{"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,
|
{Feature::IndirectFirstInstance,
|
||||||
{"indirect-first-instance", "Support non-zero first instance values on indirect draw calls",
|
{"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,
|
{Feature::DawnInternalUsages,
|
||||||
{"dawn-internal-usages",
|
{"dawn-internal-usages",
|
||||||
"Add internal usages to resources to affect how the texture is allocated, but not "
|
"Add internal usages to resources to affect how the texture is allocated, but not "
|
||||||
"frontend validation. Other internal commands may access this usage.",
|
"frontend validation. Other internal commands may access this usage.",
|
||||||
"https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/"
|
"https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/"
|
||||||
"dawn_internal_usages.md"}},
|
"dawn_internal_usages.md",
|
||||||
|
FeatureInfo::FeatureState::Stable}},
|
||||||
{Feature::MultiPlanarFormats,
|
{Feature::MultiPlanarFormats,
|
||||||
{"multiplanar-formats", "Import and use multi-planar texture formats with per plane views",
|
{"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,
|
{Feature::DawnNative,
|
||||||
{"dawn-native", "WebGPU is running on top of dawn_native.",
|
{"dawn-native", "WebGPU is running on top of dawn_native.",
|
||||||
"https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/"
|
"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) {
|
Feature FromAPIFeature(wgpu::FeatureName feature) {
|
||||||
switch (feature) {
|
switch (feature) {
|
||||||
case wgpu::FeatureName::Undefined:
|
case wgpu::FeatureName::Undefined:
|
||||||
return Feature::InvalidEnum;
|
return Feature::InvalidEnum;
|
||||||
|
case wgpu::FeatureName::DawnShaderFloat16:
|
||||||
|
// Deprecated.
|
||||||
|
return Feature::InvalidEnum;
|
||||||
|
|
||||||
case wgpu::FeatureName::TimestampQuery:
|
case wgpu::FeatureName::TimestampQuery:
|
||||||
return Feature::TimestampQuery;
|
return Feature::TimestampQuery;
|
||||||
|
@ -103,8 +109,6 @@ Feature FromAPIFeature(wgpu::FeatureName feature) {
|
||||||
return Feature::Depth32FloatStencil8;
|
return Feature::Depth32FloatStencil8;
|
||||||
case wgpu::FeatureName::IndirectFirstInstance:
|
case wgpu::FeatureName::IndirectFirstInstance:
|
||||||
return Feature::IndirectFirstInstance;
|
return Feature::IndirectFirstInstance;
|
||||||
case wgpu::FeatureName::DawnShaderFloat16:
|
|
||||||
return Feature::ShaderFloat16;
|
|
||||||
case wgpu::FeatureName::DawnInternalUsages:
|
case wgpu::FeatureName::DawnInternalUsages:
|
||||||
return Feature::DawnInternalUsages;
|
return Feature::DawnInternalUsages;
|
||||||
case wgpu::FeatureName::DawnMultiPlanarFormats:
|
case wgpu::FeatureName::DawnMultiPlanarFormats:
|
||||||
|
@ -113,6 +117,8 @@ Feature FromAPIFeature(wgpu::FeatureName feature) {
|
||||||
return Feature::DawnNative;
|
return Feature::DawnNative;
|
||||||
case wgpu::FeatureName::ChromiumExperimentalDp4a:
|
case wgpu::FeatureName::ChromiumExperimentalDp4a:
|
||||||
return Feature::ChromiumExperimentalDp4a;
|
return Feature::ChromiumExperimentalDp4a;
|
||||||
|
case wgpu::FeatureName::ShaderF16:
|
||||||
|
return Feature::ShaderF16;
|
||||||
}
|
}
|
||||||
return Feature::InvalidEnum;
|
return Feature::InvalidEnum;
|
||||||
}
|
}
|
||||||
|
@ -135,8 +141,6 @@ wgpu::FeatureName ToAPIFeature(Feature feature) {
|
||||||
return wgpu::FeatureName::Depth32FloatStencil8;
|
return wgpu::FeatureName::Depth32FloatStencil8;
|
||||||
case Feature::IndirectFirstInstance:
|
case Feature::IndirectFirstInstance:
|
||||||
return wgpu::FeatureName::IndirectFirstInstance;
|
return wgpu::FeatureName::IndirectFirstInstance;
|
||||||
case Feature::ShaderFloat16:
|
|
||||||
return wgpu::FeatureName::DawnShaderFloat16;
|
|
||||||
case Feature::DawnInternalUsages:
|
case Feature::DawnInternalUsages:
|
||||||
return wgpu::FeatureName::DawnInternalUsages;
|
return wgpu::FeatureName::DawnInternalUsages;
|
||||||
case Feature::MultiPlanarFormats:
|
case Feature::MultiPlanarFormats:
|
||||||
|
@ -145,6 +149,8 @@ wgpu::FeatureName ToAPIFeature(Feature feature) {
|
||||||
return wgpu::FeatureName::DawnNative;
|
return wgpu::FeatureName::DawnNative;
|
||||||
case Feature::ChromiumExperimentalDp4a:
|
case Feature::ChromiumExperimentalDp4a:
|
||||||
return wgpu::FeatureName::ChromiumExperimentalDp4a;
|
return wgpu::FeatureName::ChromiumExperimentalDp4a;
|
||||||
|
case Feature::ShaderF16:
|
||||||
|
return wgpu::FeatureName::ShaderF16;
|
||||||
|
|
||||||
case Feature::EnumCount:
|
case Feature::EnumCount:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -30,13 +30,13 @@ enum class Feature {
|
||||||
TextureCompressionBC,
|
TextureCompressionBC,
|
||||||
TextureCompressionETC2,
|
TextureCompressionETC2,
|
||||||
TextureCompressionASTC,
|
TextureCompressionASTC,
|
||||||
ShaderFloat16,
|
|
||||||
PipelineStatisticsQuery,
|
PipelineStatisticsQuery,
|
||||||
TimestampQuery,
|
TimestampQuery,
|
||||||
DepthClipControl,
|
DepthClipControl,
|
||||||
Depth32FloatStencil8,
|
Depth32FloatStencil8,
|
||||||
ChromiumExperimentalDp4a,
|
ChromiumExperimentalDp4a,
|
||||||
IndirectFirstInstance,
|
IndirectFirstInstance,
|
||||||
|
ShaderF16,
|
||||||
|
|
||||||
// Dawn-specific
|
// Dawn-specific
|
||||||
DawnInternalUsages,
|
DawnInternalUsages,
|
||||||
|
|
|
@ -389,12 +389,12 @@ FormatTable BuildFormatTable(const DeviceBase* device) {
|
||||||
AddMultiAspectFormat(wgpu::TextureFormat::Depth24PlusStencil8,
|
AddMultiAspectFormat(wgpu::TextureFormat::Depth24PlusStencil8,
|
||||||
Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Stencil8, true, true, true, 2);
|
Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Stencil8, true, true, true, 2);
|
||||||
AddDepthFormat(wgpu::TextureFormat::Depth32Float, 4, true);
|
AddDepthFormat(wgpu::TextureFormat::Depth32Float, 4, true);
|
||||||
bool isD32S8Supported = device->IsFeatureEnabled(Feature::Depth32FloatStencil8);
|
bool isD32S8Supported = device->HasFeature(Feature::Depth32FloatStencil8);
|
||||||
AddMultiAspectFormat(wgpu::TextureFormat::Depth32FloatStencil8,
|
AddMultiAspectFormat(wgpu::TextureFormat::Depth32FloatStencil8,
|
||||||
Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Stencil8, true, isD32S8Supported, true, 2);
|
Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Stencil8, true, isD32S8Supported, true, 2);
|
||||||
|
|
||||||
// BC compressed formats
|
// 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::BC1RGBAUnorm, 8, 4, 4, isBCFormatSupported, 4);
|
||||||
AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnormSrgb, 8, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC1RGBAUnorm);
|
AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnormSrgb, 8, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC1RGBAUnorm);
|
||||||
AddCompressedFormat(wgpu::TextureFormat::BC4RSnorm, 8, 4, 4, isBCFormatSupported, 1);
|
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);
|
AddCompressedFormat(wgpu::TextureFormat::BC7RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC7RGBAUnorm);
|
||||||
|
|
||||||
// ETC2/EAC compressed formats
|
// 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::ETC2RGB8Unorm, 8, 4, 4, isETC2FormatSupported, 3);
|
||||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8UnormSrgb, 8, 4, 4, isETC2FormatSupported, 3, wgpu::TextureFormat::ETC2RGB8Unorm);
|
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8UnormSrgb, 8, 4, 4, isETC2FormatSupported, 3, wgpu::TextureFormat::ETC2RGB8Unorm);
|
||||||
AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1Unorm, 8, 4, 4, isETC2FormatSupported, 4);
|
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);
|
AddCompressedFormat(wgpu::TextureFormat::EACRG11Snorm, 16, 4, 4, isETC2FormatSupported, 2);
|
||||||
|
|
||||||
// ASTC compressed formats
|
// 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::ASTC4x4Unorm, 16, 4, 4, isASTCFormatSupported, 4);
|
||||||
AddCompressedFormat(wgpu::TextureFormat::ASTC4x4UnormSrgb, 16, 4, 4, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC4x4Unorm);
|
AddCompressedFormat(wgpu::TextureFormat::ASTC4x4UnormSrgb, 16, 4, 4, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC4x4Unorm);
|
||||||
AddCompressedFormat(wgpu::TextureFormat::ASTC5x4Unorm, 16, 5, 4, isASTCFormatSupported, 4);
|
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);
|
AddCompressedFormat(wgpu::TextureFormat::ASTC12x12UnormSrgb, 16, 12, 12, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC12x12Unorm);
|
||||||
|
|
||||||
// multi-planar formats
|
// 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,
|
AddMultiAspectFormat(wgpu::TextureFormat::R8BG8Biplanar420Unorm, Aspect::Plane0 | Aspect::Plane1,
|
||||||
wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm, false, isMultiPlanarFormatSupported, false, 3);
|
wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm, false, isMultiPlanarFormatSupported, false, 3);
|
||||||
|
|
||||||
|
|
|
@ -338,7 +338,7 @@ MaybeError EncodeIndirectDrawValidationCommands(DeviceBase* device,
|
||||||
if (device->IsValidationEnabled()) {
|
if (device->IsValidationEnabled()) {
|
||||||
newPass.flags |= kValidationEnabled;
|
newPass.flags |= kValidationEnabled;
|
||||||
}
|
}
|
||||||
if (device->IsFeatureEnabled(Feature::IndirectFirstInstance)) {
|
if (device->HasFeature(Feature::IndirectFirstInstance)) {
|
||||||
newPass.flags |= kIndirectFirstInstanceEnabled;
|
newPass.flags |= kIndirectFirstInstanceEnabled;
|
||||||
}
|
}
|
||||||
passes.push_back(std::move(newPass));
|
passes.push_back(std::move(newPass));
|
||||||
|
|
|
@ -60,7 +60,7 @@ MaybeError ValidateQuerySetDescriptor(DeviceBase* device, const QuerySetDescript
|
||||||
"fully implemented");
|
"fully implemented");
|
||||||
|
|
||||||
DAWN_INVALID_IF(
|
DAWN_INVALID_IF(
|
||||||
!device->IsFeatureEnabled(Feature::PipelineStatisticsQuery),
|
!device->HasFeature(Feature::PipelineStatisticsQuery),
|
||||||
"Pipeline statistics query set created without the feature being enabled.");
|
"Pipeline statistics query set created without the feature being enabled.");
|
||||||
|
|
||||||
DAWN_INVALID_IF(descriptor->pipelineStatisticsCount == 0,
|
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 "
|
"Timestamp queries are disallowed because they may expose precise "
|
||||||
"timing information.");
|
"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.");
|
"Timestamp query set created without the feature being enabled.");
|
||||||
|
|
||||||
DAWN_INVALID_IF(descriptor->pipelineStatisticsCount != 0,
|
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));
|
DAWN_TRY(ValidateSingleSType(descriptor->nextInChain, wgpu::SType::PrimitiveDepthClipControl));
|
||||||
const PrimitiveDepthClipControl* depthClipControl = nullptr;
|
const PrimitiveDepthClipControl* depthClipControl = nullptr;
|
||||||
FindInChain(descriptor->nextInChain, &depthClipControl);
|
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);
|
"%s is not supported", wgpu::FeatureName::DepthClipControl);
|
||||||
DAWN_TRY(ValidatePrimitiveTopology(descriptor->topology));
|
DAWN_TRY(ValidatePrimitiveTopology(descriptor->topology));
|
||||||
DAWN_TRY(ValidateIndexFormat(descriptor->stripIndexFormat));
|
DAWN_TRY(ValidateIndexFormat(descriptor->stripIndexFormat));
|
||||||
|
|
|
@ -339,7 +339,7 @@ MaybeError ValidateTextureDescriptor(const DeviceBase* device,
|
||||||
FindInChain(descriptor->nextInChain, &internalUsageDesc);
|
FindInChain(descriptor->nextInChain, &internalUsageDesc);
|
||||||
|
|
||||||
DAWN_INVALID_IF(
|
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");
|
"The internalUsageDesc is not empty while the dawn-internal-usages feature is not enabled");
|
||||||
|
|
||||||
const Format* format;
|
const Format* format;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "dawn/common/Assert.h"
|
#include "dawn/common/Assert.h"
|
||||||
#include "dawn/common/BitSetIterator.h"
|
#include "dawn/common/BitSetIterator.h"
|
||||||
#include "dawn/native/Toggles.h"
|
#include "dawn/native/Toggles.h"
|
||||||
|
#include "dawn/native/dawn_platform.h"
|
||||||
|
|
||||||
namespace dawn::native {
|
namespace dawn::native {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -334,6 +335,81 @@ std::vector<const char*> TogglesSet::GetContainedToggleNames() const {
|
||||||
return togglesNameInUse;
|
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) {
|
const char* ToggleEnumToName(Toggle toggle) {
|
||||||
ASSERT(toggle != Toggle::InvalidEnum);
|
ASSERT(toggle != Toggle::InvalidEnum);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
namespace dawn::native {
|
namespace dawn::native {
|
||||||
|
|
||||||
|
struct DawnTogglesDeviceDescriptor;
|
||||||
|
|
||||||
enum class Toggle {
|
enum class Toggle {
|
||||||
EmulateStoreAndMSAAResolve,
|
EmulateStoreAndMSAAResolve,
|
||||||
NonzeroClearResourcesOnCreationForTesting,
|
NonzeroClearResourcesOnCreationForTesting,
|
||||||
|
@ -92,6 +94,27 @@ struct TogglesSet {
|
||||||
std::vector<const char*> GetContainedToggleNames() const;
|
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);
|
const char* ToggleEnumToName(Toggle toggle);
|
||||||
|
|
||||||
class TogglesInfo {
|
class TogglesInfo {
|
||||||
|
|
|
@ -147,6 +147,9 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
||||||
dxcVersion >= MakeDXCVersion(kLeastMajorVersionForDP4a, kLeastMinorVersionForDP4a)) {
|
dxcVersion >= MakeDXCVersion(kLeastMajorVersionForDP4a, kLeastMinorVersionForDP4a)) {
|
||||||
mSupportedFeatures.EnableFeature(Feature::ChromiumExperimentalDp4a);
|
mSupportedFeatures.EnableFeature(Feature::ChromiumExperimentalDp4a);
|
||||||
}
|
}
|
||||||
|
if (mDeviceInfo.supportsShaderF16) {
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::ShaderF16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -312,6 +315,20 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
|
||||||
return {};
|
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() {
|
MaybeError Adapter::InitializeDebugLayerFilters() {
|
||||||
if (!GetInstance()->IsBackendValidationEnabled()) {
|
if (!GetInstance()->IsBackendValidationEnabled()) {
|
||||||
return {};
|
return {};
|
||||||
|
@ -418,8 +435,10 @@ void Adapter::CleanUpDebugLayerFilters() {
|
||||||
infoQueue->PopStorageFilter();
|
infoQueue->PopStorageFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(
|
||||||
return Device::Create(this, descriptor);
|
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
|
// 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;
|
const gpu_info::D3DDriverVersion& GetDriverVersion() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(const DeviceDescriptor* descriptor) override;
|
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
|
||||||
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles) override;
|
||||||
MaybeError ResetInternalDeviceForTestingImpl() override;
|
MaybeError ResetInternalDeviceForTestingImpl() override;
|
||||||
|
|
||||||
bool AreTimestampQueriesSupported() const;
|
bool AreTimestampQueriesSupported() const;
|
||||||
|
@ -49,6 +51,10 @@ class Adapter : public AdapterBase {
|
||||||
MaybeError InitializeSupportedFeaturesImpl() override;
|
MaybeError InitializeSupportedFeaturesImpl() override;
|
||||||
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override;
|
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override;
|
||||||
|
|
||||||
|
MaybeError ValidateFeatureSupportedWithTogglesImpl(
|
||||||
|
wgpu::FeatureName feature,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles) override;
|
||||||
|
|
||||||
MaybeError InitializeDebugLayerFilters();
|
MaybeError InitializeDebugLayerFilters();
|
||||||
void CleanUpDebugLayerFilters();
|
void CleanUpDebugLayerFilters();
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ ResultOrError<D3D12DeviceInfo> GatherDeviceInfo(const Adapter& adapter) {
|
||||||
info.shaderProfiles[SingleShaderStage::Fragment] = L"p" + profileSuffix;
|
info.shaderProfiles[SingleShaderStage::Fragment] = L"p" + profileSuffix;
|
||||||
info.shaderProfiles[SingleShaderStage::Compute] = L"c" + profileSuffix;
|
info.shaderProfiles[SingleShaderStage::Compute] = L"c" + profileSuffix;
|
||||||
|
|
||||||
info.supportsShaderFloat16 =
|
info.supportsShaderF16 =
|
||||||
driverShaderModel >= D3D_SHADER_MODEL_6_2 && featureOptions4.Native16BitShaderOpsSupported;
|
driverShaderModel >= D3D_SHADER_MODEL_6_2 && featureOptions4.Native16BitShaderOpsSupported;
|
||||||
|
|
||||||
info.supportsDP4a = driverShaderModel >= D3D_SHADER_MODEL_6_4;
|
info.supportsDP4a = driverShaderModel >= D3D_SHADER_MODEL_6_4;
|
||||||
|
|
|
@ -27,7 +27,7 @@ struct D3D12DeviceInfo {
|
||||||
bool isUMA;
|
bool isUMA;
|
||||||
uint32_t resourceHeapTier;
|
uint32_t resourceHeapTier;
|
||||||
bool supportsRenderPass;
|
bool supportsRenderPass;
|
||||||
bool supportsShaderFloat16;
|
bool supportsShaderF16;
|
||||||
// shaderModel indicates the maximum supported shader model, for example, the value 62
|
// 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.
|
// indicates that current driver supports the maximum shader model is shader model 6.2.
|
||||||
uint32_t shaderModel;
|
uint32_t shaderModel;
|
||||||
|
|
|
@ -63,8 +63,10 @@ static constexpr uint64_t kZeroBufferSize = 1024 * 1024 * 4; // 4 Mb
|
||||||
static constexpr uint64_t kMaxDebugMessagesToPrint = 5;
|
static constexpr uint64_t kMaxDebugMessagesToPrint = 5;
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter, const DeviceDescriptor* descriptor) {
|
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter,
|
||||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor));
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles) {
|
||||||
|
Ref<Device> device = AcquireRef(new Device(adapter, descriptor, userProvidedToggles));
|
||||||
DAWN_TRY(device->Initialize(descriptor));
|
DAWN_TRY(device->Initialize(descriptor));
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +86,7 @@ MaybeError Device::Initialize(const DeviceDescriptor* descriptor) {
|
||||||
CheckHRESULT(mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)),
|
CheckHRESULT(mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)),
|
||||||
"D3D12 create command queue"));
|
"D3D12 create command queue"));
|
||||||
|
|
||||||
if (IsFeatureEnabled(Feature::TimestampQuery) &&
|
if (HasFeature(Feature::TimestampQuery) &&
|
||||||
!IsToggleEnabled(Toggle::DisableTimestampQueryConversion)) {
|
!IsToggleEnabled(Toggle::DisableTimestampQueryConversion)) {
|
||||||
// Get GPU timestamp counter frequency (in ticks/second). This fails if the specified
|
// 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
|
// command queue doesn't support timestamps. D3D12_COMMAND_LIST_TYPE_DIRECT queues
|
||||||
|
@ -876,17 +878,6 @@ bool Device::ShouldDuplicateNumWorkgroupsForDispatchIndirect(
|
||||||
return ToBackend(computePipeline)->UsesNumWorkgroups();
|
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() {
|
void Device::SetLabelImpl() {
|
||||||
SetDebugName(this, mD3d12Device.Get(), "Dawn_Device", GetLabel());
|
SetDebugName(this, mD3d12Device.Get(), "Dawn_Device", GetLabel());
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,9 @@ class StagingDescriptorAllocator;
|
||||||
// Definition of backend types
|
// Definition of backend types
|
||||||
class Device final : public DeviceBase {
|
class Device final : public DeviceBase {
|
||||||
public:
|
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;
|
~Device() override;
|
||||||
|
|
||||||
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
||||||
|
@ -160,8 +162,6 @@ class Device final : public DeviceBase {
|
||||||
bool ShouldDuplicateParametersForDrawIndirect(
|
bool ShouldDuplicateParametersForDrawIndirect(
|
||||||
const RenderPipelineBase* renderPipelineBase) const override;
|
const RenderPipelineBase* renderPipelineBase) const override;
|
||||||
|
|
||||||
bool IsFeatureEnabled(Feature feature) const override;
|
|
||||||
|
|
||||||
uint64_t GetBufferCopyOffsetAlignmentForDepthStencil() const override;
|
uint64_t GetBufferCopyOffsetAlignmentForDepthStencil() const override;
|
||||||
|
|
||||||
// Dawn APIs
|
// Dawn APIs
|
||||||
|
|
|
@ -97,7 +97,7 @@ enum class Compiler { FXC, DXC };
|
||||||
X(bool, dumpShaders)
|
X(bool, dumpShaders)
|
||||||
|
|
||||||
#define D3D_BYTECODE_COMPILATION_REQUEST_MEMBERS(X) \
|
#define D3D_BYTECODE_COMPILATION_REQUEST_MEMBERS(X) \
|
||||||
X(bool, hasShaderFloat16Feature) \
|
X(bool, hasShaderF16Feature) \
|
||||||
X(uint32_t, compileFlags) \
|
X(uint32_t, compileFlags) \
|
||||||
X(Compiler, compiler) \
|
X(Compiler, compiler) \
|
||||||
X(uint64_t, compilerVersion) \
|
X(uint64_t, compilerVersion) \
|
||||||
|
@ -186,8 +186,7 @@ ResultOrError<ComPtr<IDxcBlob>> CompileShaderDXC(const D3DBytecodeCompilationReq
|
||||||
std::wstring entryPointW;
|
std::wstring entryPointW;
|
||||||
DAWN_TRY_ASSIGN(entryPointW, ConvertStringToWstring(entryPointName));
|
DAWN_TRY_ASSIGN(entryPointW, ConvertStringToWstring(entryPointName));
|
||||||
|
|
||||||
std::vector<const wchar_t*> arguments =
|
std::vector<const wchar_t*> arguments = GetDXCArguments(r.compileFlags, r.hasShaderF16Feature);
|
||||||
GetDXCArguments(r.compileFlags, r.hasShaderFloat16Feature);
|
|
||||||
|
|
||||||
ComPtr<IDxcOperationResult> result;
|
ComPtr<IDxcOperationResult> result;
|
||||||
DAWN_TRY(CheckHRESULT(r.dxcCompiler->Compile(sourceBlob.Get(), nullptr, entryPointW.c_str(),
|
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.disableWorkgroupInit = device->IsToggleEnabled(Toggle::DisableWorkgroupInit);
|
||||||
req.hlsl.dumpShaders = device->IsToggleEnabled(Toggle::DumpShaders);
|
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;
|
req.bytecode.compileFlags = compileFlags;
|
||||||
|
|
||||||
if (device->IsToggleEnabled(Toggle::UseDXC)) {
|
if (device->IsToggleEnabled(Toggle::UseDXC)) {
|
||||||
|
|
|
@ -299,8 +299,10 @@ class Adapter : public AdapterBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(const DeviceDescriptor* descriptor) override {
|
ResultOrError<Ref<DeviceBase>> CreateDeviceImpl(
|
||||||
return Device::Create(this, mDevice, descriptor);
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles) override {
|
||||||
|
return Device::Create(this, mDevice, descriptor, userProvidedToggles);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError InitializeImpl() override { return {}; }
|
MaybeError InitializeImpl() override { return {}; }
|
||||||
|
@ -378,6 +380,8 @@ class Adapter : public AdapterBase {
|
||||||
|
|
||||||
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
||||||
|
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::ShaderF16);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,6 +624,12 @@ class Adapter : public AdapterBase {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeError ValidateFeatureSupportedWithTogglesImpl(
|
||||||
|
wgpu::FeatureName feature,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles) override {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
NSPRef<id<MTLDevice>> mDevice;
|
NSPRef<id<MTLDevice>> mDevice;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,8 @@ class Device final : public DeviceBase {
|
||||||
public:
|
public:
|
||||||
static ResultOrError<Ref<Device>> Create(AdapterBase* adapter,
|
static ResultOrError<Ref<Device>> Create(AdapterBase* adapter,
|
||||||
NSPRef<id<MTLDevice>> mtlDevice,
|
NSPRef<id<MTLDevice>> mtlDevice,
|
||||||
const DeviceDescriptor* descriptor);
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles);
|
||||||
~Device() override;
|
~Device() override;
|
||||||
|
|
||||||
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
||||||
|
@ -74,7 +75,8 @@ class Device final : public DeviceBase {
|
||||||
private:
|
private:
|
||||||
Device(AdapterBase* adapter,
|
Device(AdapterBase* adapter,
|
||||||
NSPRef<id<MTLDevice>> mtlDevice,
|
NSPRef<id<MTLDevice>> mtlDevice,
|
||||||
const DeviceDescriptor* descriptor);
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles);
|
||||||
|
|
||||||
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
|
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
|
||||||
const BindGroupDescriptor* descriptor) override;
|
const BindGroupDescriptor* descriptor) override;
|
||||||
|
|
|
@ -107,16 +107,21 @@ void API_AVAILABLE(macos(10.15), ios(14)) UpdateTimestampPeriod(id<MTLDevice> de
|
||||||
// static
|
// static
|
||||||
ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
|
ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
|
||||||
NSPRef<id<MTLDevice>> mtlDevice,
|
NSPRef<id<MTLDevice>> mtlDevice,
|
||||||
const DeviceDescriptor* descriptor) {
|
const DeviceDescriptor* descriptor,
|
||||||
Ref<Device> device = AcquireRef(new Device(adapter, std::move(mtlDevice), descriptor));
|
const TripleStateTogglesSet& userProvidedToggles) {
|
||||||
|
Ref<Device> device =
|
||||||
|
AcquireRef(new Device(adapter, std::move(mtlDevice), descriptor, userProvidedToggles));
|
||||||
DAWN_TRY(device->Initialize(descriptor));
|
DAWN_TRY(device->Initialize(descriptor));
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::Device(AdapterBase* adapter,
|
Device::Device(AdapterBase* adapter,
|
||||||
NSPRef<id<MTLDevice>> mtlDevice,
|
NSPRef<id<MTLDevice>> mtlDevice,
|
||||||
const DeviceDescriptor* descriptor)
|
const DeviceDescriptor* descriptor,
|
||||||
: DeviceBase(adapter, descriptor), mMtlDevice(std::move(mtlDevice)), mCompletedSerial(0) {}
|
const TripleStateTogglesSet& userProvidedToggles)
|
||||||
|
: DeviceBase(adapter, descriptor, userProvidedToggles),
|
||||||
|
mMtlDevice(std::move(mtlDevice)),
|
||||||
|
mCompletedSerial(0) {}
|
||||||
|
|
||||||
Device::~Device() {
|
Device::~Device() {
|
||||||
Destroy();
|
Destroy();
|
||||||
|
@ -132,7 +137,7 @@ MaybeError Device::Initialize(const DeviceDescriptor* descriptor) {
|
||||||
|
|
||||||
DAWN_TRY(mCommandContext.PrepareNextCommandBuffer(*mCommandQueue));
|
DAWN_TRY(mCommandContext.PrepareNextCommandBuffer(*mCommandQueue));
|
||||||
|
|
||||||
if (IsFeatureEnabled(Feature::TimestampQuery) &&
|
if (HasFeature(Feature::TimestampQuery) &&
|
||||||
!IsToggleEnabled(Toggle::DisableTimestampQueryConversion)) {
|
!IsToggleEnabled(Toggle::DisableTimestampQueryConversion)) {
|
||||||
// Make a best guess of timestamp period based on device vendor info, and converge it to
|
// Make a best guess of timestamp period based on device vendor info, and converge it to
|
||||||
// an accurate value by the following calculations.
|
// an accurate value by the following calculations.
|
||||||
|
@ -322,7 +327,7 @@ MaybeError Device::TickImpl() {
|
||||||
DAWN_TRY(SubmitPendingCommandBuffer());
|
DAWN_TRY(SubmitPendingCommandBuffer());
|
||||||
|
|
||||||
// Just run timestamp period calculation when timestamp feature is enabled.
|
// 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, *)) {
|
if (@available(macos 10.15, iOS 14.0, *)) {
|
||||||
UpdateTimestampPeriod(GetMTLDevice(), mKalmanInfo.get(), &mCpuTimestamp, &mGpuTimestamp,
|
UpdateTimestampPeriod(GetMTLDevice(), mKalmanInfo.get(), &mCpuTimestamp, &mGpuTimestamp,
|
||||||
&mTimestampPeriod);
|
&mTimestampPeriod);
|
||||||
|
|
|
@ -65,8 +65,16 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(
|
||||||
return Device::Create(this, descriptor);
|
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 {
|
class Backend : public BackendConnection {
|
||||||
|
@ -103,8 +111,10 @@ struct CopyFromStagingToBufferOperation : PendingOperation {
|
||||||
// Device
|
// Device
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter, const DeviceDescriptor* descriptor) {
|
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter,
|
||||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor));
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles) {
|
||||||
|
Ref<Device> device = AcquireRef(new Device(adapter, descriptor, userProvidedToggles));
|
||||||
DAWN_TRY(device->Initialize(descriptor));
|
DAWN_TRY(device->Initialize(descriptor));
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,9 @@ struct PendingOperation {
|
||||||
|
|
||||||
class Device final : public DeviceBase {
|
class Device final : public DeviceBase {
|
||||||
public:
|
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;
|
~Device() override;
|
||||||
|
|
||||||
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
||||||
|
@ -182,7 +184,13 @@ class Adapter : public AdapterBase {
|
||||||
MaybeError InitializeSupportedFeaturesImpl() override;
|
MaybeError InitializeSupportedFeaturesImpl() override;
|
||||||
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) 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,
|
// Helper class so |BindGroup| can allocate memory for its binding data,
|
||||||
|
|
|
@ -141,6 +141,11 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
||||||
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShaderF16
|
||||||
|
if (mFunctions.IsGLExtensionSupported("GL_AMD_gpu_shader_half_float")) {
|
||||||
|
mSupportedFeatures.EnableFeature(Feature::ShaderF16);
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,12 +154,20 @@ MaybeError Adapter::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(
|
||||||
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles) {
|
||||||
EGLenum api =
|
EGLenum api =
|
||||||
GetBackendType() == wgpu::BackendType::OpenGL ? EGL_OPENGL_API : EGL_OPENGL_ES_API;
|
GetBackendType() == wgpu::BackendType::OpenGL ? EGL_OPENGL_API : EGL_OPENGL_ES_API;
|
||||||
std::unique_ptr<Device::Context> context;
|
std::unique_ptr<Device::Context> context;
|
||||||
DAWN_TRY_ASSIGN(context, ContextEGL::Create(mEGLFunctions, api));
|
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
|
} // namespace dawn::native::opengl
|
||||||
|
|
|
@ -36,7 +36,13 @@ class Adapter : public AdapterBase {
|
||||||
MaybeError InitializeImpl() override;
|
MaybeError InitializeImpl() override;
|
||||||
MaybeError InitializeSupportedFeaturesImpl() override;
|
MaybeError InitializeSupportedFeaturesImpl() override;
|
||||||
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) 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;
|
OpenGLFunctions mFunctions;
|
||||||
EGLFunctions mEGLFunctions;
|
EGLFunctions mEGLFunctions;
|
||||||
|
|
|
@ -108,8 +108,10 @@ namespace dawn::native::opengl {
|
||||||
ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
|
ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
|
||||||
const DeviceDescriptor* descriptor,
|
const DeviceDescriptor* descriptor,
|
||||||
const OpenGLFunctions& functions,
|
const OpenGLFunctions& functions,
|
||||||
std::unique_ptr<Context> context) {
|
std::unique_ptr<Context> context,
|
||||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor, functions, std::move(context)));
|
const TripleStateTogglesSet& userProvidedToggles) {
|
||||||
|
Ref<Device> device = AcquireRef(
|
||||||
|
new Device(adapter, descriptor, functions, std::move(context), userProvidedToggles));
|
||||||
DAWN_TRY(device->Initialize(descriptor));
|
DAWN_TRY(device->Initialize(descriptor));
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
@ -117,8 +119,11 @@ ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
|
||||||
Device::Device(AdapterBase* adapter,
|
Device::Device(AdapterBase* adapter,
|
||||||
const DeviceDescriptor* descriptor,
|
const DeviceDescriptor* descriptor,
|
||||||
const OpenGLFunctions& functions,
|
const OpenGLFunctions& functions,
|
||||||
std::unique_ptr<Context> context)
|
std::unique_ptr<Context> context,
|
||||||
: DeviceBase(adapter, descriptor), mGL(functions), mContext(std::move(context)) {}
|
const TripleStateTogglesSet& userProvidedToggles)
|
||||||
|
: DeviceBase(adapter, descriptor, userProvidedToggles),
|
||||||
|
mGL(functions),
|
||||||
|
mContext(std::move(context)) {}
|
||||||
|
|
||||||
Device::~Device() {
|
Device::~Device() {
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
|
@ -43,7 +43,8 @@ class Device final : public DeviceBase {
|
||||||
static ResultOrError<Ref<Device>> Create(AdapterBase* adapter,
|
static ResultOrError<Ref<Device>> Create(AdapterBase* adapter,
|
||||||
const DeviceDescriptor* descriptor,
|
const DeviceDescriptor* descriptor,
|
||||||
const OpenGLFunctions& functions,
|
const OpenGLFunctions& functions,
|
||||||
std::unique_ptr<Context> context);
|
std::unique_ptr<Context> context,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles);
|
||||||
~Device() override;
|
~Device() override;
|
||||||
|
|
||||||
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
||||||
|
@ -93,7 +94,8 @@ class Device final : public DeviceBase {
|
||||||
Device(AdapterBase* adapter,
|
Device(AdapterBase* adapter,
|
||||||
const DeviceDescriptor* descriptor,
|
const DeviceDescriptor* descriptor,
|
||||||
const OpenGLFunctions& functions,
|
const OpenGLFunctions& functions,
|
||||||
std::unique_ptr<Context> context);
|
std::unique_ptr<Context> context,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles);
|
||||||
|
|
||||||
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
|
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
|
||||||
const BindGroupDescriptor* descriptor) override;
|
const BindGroupDescriptor* descriptor) override;
|
||||||
|
|
|
@ -159,6 +159,15 @@ MaybeError Adapter::InitializeSupportedFeaturesImpl() {
|
||||||
mSupportedFeatures.EnableFeature(Feature::IndirectFirstInstance);
|
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) &&
|
if (mDeviceInfo.HasExt(DeviceExt::ShaderIntegerDotProduct) &&
|
||||||
mDeviceInfo.shaderIntegerDotProductProperties
|
mDeviceInfo.shaderIntegerDotProductProperties
|
||||||
.integerDotProduct4x8BitPackedSignedAccelerated == VK_TRUE &&
|
.integerDotProduct4x8BitPackedSignedAccelerated == VK_TRUE &&
|
||||||
|
@ -354,8 +363,16 @@ bool Adapter::SupportsExternalImages() const {
|
||||||
mVulkanInstance->GetFunctions());
|
mVulkanInstance->GetFunctions());
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
|
ResultOrError<Ref<DeviceBase>> Adapter::CreateDeviceImpl(
|
||||||
return Device::Create(this, descriptor);
|
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
|
} // namespace dawn::native::vulkan
|
||||||
|
|
|
@ -46,7 +46,13 @@ class Adapter : public AdapterBase {
|
||||||
MaybeError InitializeSupportedFeaturesImpl() override;
|
MaybeError InitializeSupportedFeaturesImpl() override;
|
||||||
MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) 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;
|
VkPhysicalDevice mPhysicalDevice;
|
||||||
Ref<VulkanInstance> mVulkanInstance;
|
Ref<VulkanInstance> mVulkanInstance;
|
||||||
|
|
|
@ -78,14 +78,19 @@ class ScopedSignalSemaphore : public NonMovable {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter, const DeviceDescriptor* descriptor) {
|
ResultOrError<Ref<Device>> Device::Create(Adapter* adapter,
|
||||||
Ref<Device> device = AcquireRef(new Device(adapter, descriptor));
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles) {
|
||||||
|
Ref<Device> device = AcquireRef(new Device(adapter, descriptor, userProvidedToggles));
|
||||||
DAWN_TRY(device->Initialize(descriptor));
|
DAWN_TRY(device->Initialize(descriptor));
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::Device(Adapter* adapter, const DeviceDescriptor* descriptor)
|
Device::Device(Adapter* adapter,
|
||||||
: DeviceBase(adapter, descriptor), mDebugPrefix(GetNextDeviceDebugPrefix()) {
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles)
|
||||||
|
: DeviceBase(adapter, descriptor, userProvidedToggles),
|
||||||
|
mDebugPrefix(GetNextDeviceDebugPrefix()) {
|
||||||
InitTogglesFromDriver();
|
InitTogglesFromDriver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,29 +454,29 @@ ResultOrError<VulkanDeviceKnobs> Device::CreateDevice(VkPhysicalDevice physicalD
|
||||||
usedKnobs.features.samplerAnisotropy = VK_TRUE;
|
usedKnobs.features.samplerAnisotropy = VK_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsFeatureEnabled(Feature::TextureCompressionBC)) {
|
if (HasFeature(Feature::TextureCompressionBC)) {
|
||||||
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.textureCompressionBC == VK_TRUE);
|
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.textureCompressionBC == VK_TRUE);
|
||||||
usedKnobs.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);
|
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.textureCompressionETC2 == VK_TRUE);
|
||||||
usedKnobs.features.textureCompressionETC2 = VK_TRUE;
|
usedKnobs.features.textureCompressionETC2 = VK_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsFeatureEnabled(Feature::TextureCompressionASTC)) {
|
if (HasFeature(Feature::TextureCompressionASTC)) {
|
||||||
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.textureCompressionASTC_LDR ==
|
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.textureCompressionASTC_LDR ==
|
||||||
VK_TRUE);
|
VK_TRUE);
|
||||||
usedKnobs.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 ==
|
ASSERT(ToBackend(GetAdapter())->GetDeviceInfo().features.pipelineStatisticsQuery ==
|
||||||
VK_TRUE);
|
VK_TRUE);
|
||||||
usedKnobs.features.pipelineStatisticsQuery = VK_TRUE;
|
usedKnobs.features.pipelineStatisticsQuery = VK_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsFeatureEnabled(Feature::DepthClipControl)) {
|
if (HasFeature(Feature::DepthClipControl)) {
|
||||||
const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
|
const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
|
||||||
ASSERT(deviceInfo.HasExt(DeviceExt::DepthClipEnable) &&
|
ASSERT(deviceInfo.HasExt(DeviceExt::DepthClipEnable) &&
|
||||||
deviceInfo.depthClipEnableFeatures.depthClipEnable == VK_TRUE);
|
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);
|
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();
|
const VulkanDeviceInfo& deviceInfo = ToBackend(GetAdapter())->GetDeviceInfo();
|
||||||
ASSERT(deviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) &&
|
ASSERT(deviceInfo.HasExt(DeviceExt::ShaderFloat16Int8) &&
|
||||||
deviceInfo.shaderFloat16Int8Features.shaderFloat16 == VK_TRUE &&
|
deviceInfo.shaderFloat16Int8Features.shaderFloat16 == VK_TRUE &&
|
||||||
deviceInfo.HasExt(DeviceExt::_16BitStorage) &&
|
deviceInfo.HasExt(DeviceExt::_16BitStorage) &&
|
||||||
deviceInfo._16BitStorageFeatures.storageBuffer16BitAccess == VK_TRUE &&
|
deviceInfo._16BitStorageFeatures.storageBuffer16BitAccess == VK_TRUE &&
|
||||||
|
deviceInfo._16BitStorageFeatures.storageInputOutput16 == VK_TRUE &&
|
||||||
deviceInfo._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE);
|
deviceInfo._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess == VK_TRUE);
|
||||||
|
|
||||||
usedKnobs.shaderFloat16Int8Features.shaderFloat16 = VK_TRUE;
|
usedKnobs.shaderFloat16Int8Features.shaderFloat16 = VK_TRUE;
|
||||||
usedKnobs._16BitStorageFeatures.storageBuffer16BitAccess = VK_TRUE;
|
usedKnobs._16BitStorageFeatures.storageBuffer16BitAccess = VK_TRUE;
|
||||||
|
usedKnobs._16BitStorageFeatures.storageInputOutput16 = VK_TRUE;
|
||||||
usedKnobs._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE;
|
usedKnobs._16BitStorageFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE;
|
||||||
|
|
||||||
featuresChain.Add(&usedKnobs.shaderFloat16Int8Features,
|
featuresChain.Add(&usedKnobs.shaderFloat16Int8Features,
|
||||||
|
|
|
@ -43,7 +43,9 @@ class ResourceMemoryAllocator;
|
||||||
|
|
||||||
class Device final : public DeviceBase {
|
class Device final : public DeviceBase {
|
||||||
public:
|
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;
|
~Device() override;
|
||||||
|
|
||||||
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
MaybeError Initialize(const DeviceDescriptor* descriptor);
|
||||||
|
@ -113,7 +115,9 @@ class Device final : public DeviceBase {
|
||||||
const char* GetDebugPrefix() { return mDebugPrefix.c_str(); }
|
const char* GetDebugPrefix() { return mDebugPrefix.c_str(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Device(Adapter* adapter, const DeviceDescriptor* descriptor);
|
Device(Adapter* adapter,
|
||||||
|
const DeviceDescriptor* descriptor,
|
||||||
|
const TripleStateTogglesSet& userProvidedToggles);
|
||||||
|
|
||||||
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
|
ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
|
||||||
const BindGroupDescriptor* descriptor) override;
|
const BindGroupDescriptor* descriptor) override;
|
||||||
|
|
|
@ -436,7 +436,7 @@ MaybeError RenderPipeline::Initialize() {
|
||||||
PNextChainBuilder rasterizationChain(&rasterization);
|
PNextChainBuilder rasterizationChain(&rasterization);
|
||||||
VkPipelineRasterizationDepthClipStateCreateInfoEXT depthClipState;
|
VkPipelineRasterizationDepthClipStateCreateInfoEXT depthClipState;
|
||||||
if (HasUnclippedDepth()) {
|
if (HasUnclippedDepth()) {
|
||||||
ASSERT(device->IsFeatureEnabled(Feature::DepthClipControl));
|
ASSERT(device->HasFeature(Feature::DepthClipControl));
|
||||||
depthClipState.pNext = nullptr;
|
depthClipState.pNext = nullptr;
|
||||||
depthClipState.depthClipEnable = VK_FALSE;
|
depthClipState.depthClipEnable = VK_FALSE;
|
||||||
depthClipState.flags = 0;
|
depthClipState.flags = 0;
|
||||||
|
|
|
@ -488,7 +488,7 @@ source_set("end2end_tests_sources") {
|
||||||
"end2end/SamplerFilterAnisotropicTests.cpp",
|
"end2end/SamplerFilterAnisotropicTests.cpp",
|
||||||
"end2end/SamplerTests.cpp",
|
"end2end/SamplerTests.cpp",
|
||||||
"end2end/ScissorTests.cpp",
|
"end2end/ScissorTests.cpp",
|
||||||
"end2end/ShaderFloat16Tests.cpp",
|
"end2end/ShaderF16Tests.cpp",
|
||||||
"end2end/ShaderTests.cpp",
|
"end2end/ShaderTests.cpp",
|
||||||
"end2end/ShaderValidationTests.cpp",
|
"end2end/ShaderValidationTests.cpp",
|
||||||
"end2end/StorageTextureTests.cpp",
|
"end2end/StorageTextureTests.cpp",
|
||||||
|
|
|
@ -31,7 +31,18 @@ class ExperimentalDP4aTests : public DawnTestWithParams<ExperimentalDP4aTestsPar
|
||||||
return {};
|
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};
|
return {wgpu::FeatureName::ChromiumExperimentalDp4a};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,9 +50,11 @@ class ExperimentalDP4aTests : public DawnTestWithParams<ExperimentalDP4aTestsPar
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsDP4aSupportedOnAdapter() const { return mIsDP4aSupportedOnAdapter; }
|
bool IsDP4aSupportedOnAdapter() const { return mIsDP4aSupportedOnAdapter; }
|
||||||
|
bool UseDxcEnabledOrNonD3D12() const { return mUseDxcEnabledOrNonD3D12; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mIsDP4aSupportedOnAdapter = false;
|
bool mIsDP4aSupportedOnAdapter = false;
|
||||||
|
bool mUseDxcEnabledOrNonD3D12 = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) {
|
TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) {
|
||||||
|
@ -67,12 +80,25 @@ TEST_P(ExperimentalDP4aTests, BasicDP4aFeaturesTest) {
|
||||||
buf.data4 = dot4U8Packed(a, c);
|
buf.data4 = dot4U8Packed(a, c);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
if (!GetParam().mRequestDP4aExtension || !IsDP4aSupportedOnAdapter() ||
|
const bool shouldDP4AFeatureSupportedByDevice =
|
||||||
(IsD3D12() && !HasToggleEnabled("use_dxc"))) {
|
// 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));
|
ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, computeShader));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
utils::CreateShaderModule(device, computeShader);
|
||||||
|
|
||||||
wgpu::BufferDescriptor bufferDesc;
|
wgpu::BufferDescriptor bufferDesc;
|
||||||
bufferDesc.size = 4 * sizeof(uint32_t);
|
bufferDesc.size = 4 * sizeof(uint32_t);
|
||||||
bufferDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc;
|
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);
|
EXPECT_BUFFER_U32_RANGE_EQ(expected, bufferOut, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DawnTestBase::CreateDeviceImpl always disable disallow_unsafe_apis toggle.
|
||||||
DAWN_INSTANTIATE_TEST_P(ExperimentalDP4aTests,
|
DAWN_INSTANTIATE_TEST_P(ExperimentalDP4aTests,
|
||||||
{D3D12Backend(), D3D12Backend({"use_dxc"}), VulkanBackend()},
|
{
|
||||||
|
D3D12Backend(),
|
||||||
|
D3D12Backend({"use_dxc"}, {}),
|
||||||
|
VulkanBackend(),
|
||||||
|
},
|
||||||
{true, false});
|
{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.requiredFeatures = &featureName;
|
||||||
deviceDescriptor.requiredFeaturesCount = 1;
|
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(
|
dawn::native::DeviceBase* deviceBase = dawn::native::FromAPI(
|
||||||
adapter.CreateDevice(reinterpret_cast<const WGPUDeviceDescriptor*>(&deviceDescriptor)));
|
adapter.CreateDevice(reinterpret_cast<const WGPUDeviceDescriptor*>(&deviceDescriptor)));
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "dawn/dawn_proc.h"
|
#include "dawn/dawn_proc.h"
|
||||||
#include "dawn/native/DawnNative.h"
|
#include "dawn/native/DawnNative.h"
|
||||||
|
@ -90,6 +91,42 @@ 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_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) {
|
TEST_F(DeviceCreationTest, CreateDeviceWithCacheSuccess) {
|
||||||
// Default device descriptor should have the same cache key as a device descriptor with a
|
// Default device descriptor should have the same cache key as a device descriptor with a
|
||||||
// default cache descriptor.
|
// default cache descriptor.
|
||||||
|
|
|
@ -23,6 +23,7 @@ bool IsFeatureSupported(WGPUFeatureName feature) {
|
||||||
case WGPUFeatureName_Undefined:
|
case WGPUFeatureName_Undefined:
|
||||||
case WGPUFeatureName_Force32:
|
case WGPUFeatureName_Force32:
|
||||||
case WGPUFeatureName_DawnNative:
|
case WGPUFeatureName_DawnNative:
|
||||||
|
case WGPUFeatureName_DawnShaderFloat16: // Deprecated
|
||||||
return false;
|
return false;
|
||||||
case WGPUFeatureName_Depth32FloatStencil8:
|
case WGPUFeatureName_Depth32FloatStencil8:
|
||||||
case WGPUFeatureName_TimestampQuery:
|
case WGPUFeatureName_TimestampQuery:
|
||||||
|
@ -32,10 +33,10 @@ bool IsFeatureSupported(WGPUFeatureName feature) {
|
||||||
case WGPUFeatureName_TextureCompressionASTC:
|
case WGPUFeatureName_TextureCompressionASTC:
|
||||||
case WGPUFeatureName_IndirectFirstInstance:
|
case WGPUFeatureName_IndirectFirstInstance:
|
||||||
case WGPUFeatureName_DepthClipControl:
|
case WGPUFeatureName_DepthClipControl:
|
||||||
case WGPUFeatureName_DawnShaderFloat16:
|
|
||||||
case WGPUFeatureName_DawnInternalUsages:
|
case WGPUFeatureName_DawnInternalUsages:
|
||||||
case WGPUFeatureName_DawnMultiPlanarFormats:
|
case WGPUFeatureName_DawnMultiPlanarFormats:
|
||||||
case WGPUFeatureName_ChromiumExperimentalDp4a:
|
case WGPUFeatureName_ChromiumExperimentalDp4a:
|
||||||
|
case WGPUFeatureName_ShaderF16:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue