Save all binding layouts in an std::variant in BindingInfo
This patch uses std::variant to represent 4 possible member types in
BindingInfo (BufferBindingLayout, SamplerBindingLayout,
TextureBindingLayout, StorageTextureBindingLayout) as logically
at any time only one of them can be used.
Bug: dawn:527
Change-Id: If83d8fa282a0d4092051ef54a97369d70a3fb531
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/172460
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/BindGroup.cpp b/src/dawn/native/BindGroup.cpp
index 510019c..4e2a217 100644
--- a/src/dawn/native/BindGroup.cpp
+++ b/src/dawn/native/BindGroup.cpp
@@ -28,6 +28,7 @@
#include "dawn/native/BindGroup.h"
#include "dawn/common/Assert.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/common/Math.h"
#include "dawn/common/ityp_bitset.h"
#include "dawn/native/BindGroupLayout.h"
@@ -50,7 +51,7 @@
MaybeError ValidateBufferBinding(const DeviceBase* device,
const BindGroupEntry& entry,
- const BindingInfo& bindingInfo) {
+ const BufferBindingLayout& layout) {
DAWN_INVALID_IF(entry.buffer == nullptr, "Binding entry buffer not set.");
DAWN_INVALID_IF(entry.sampler != nullptr || entry.textureView != nullptr,
@@ -60,8 +61,6 @@
DAWN_TRY(device->ValidateObject(entry.buffer));
- DAWN_ASSERT(bindingInfo.bindingType == BindingInfoType::Buffer);
-
uint64_t bufferSize = entry.buffer->GetSize();
// Handle wgpu::WholeSize, avoiding overflows.
@@ -87,7 +86,7 @@
wgpu::BufferUsage requiredUsage;
uint64_t maxBindingSize;
uint64_t requiredBindingAlignment;
- switch (bindingInfo.buffer.type) {
+ switch (layout.type) {
case wgpu::BufferBindingType::Uniform:
requiredUsage = wgpu::BufferUsage::Uniform;
maxBindingSize = device->GetLimits().v1.maxUniformBufferBindingSize;
@@ -101,7 +100,7 @@
DAWN_INVALID_IF(
bindingSize % 4 != 0,
"Binding size (%u) of %s isn't a multiple of 4 when binding type is (%s).",
- bindingSize, entry.buffer, bindingInfo.buffer.type);
+ bindingSize, entry.buffer, layout.type);
break;
case kInternalStorageBufferBinding:
requiredUsage = kInternalStorageBuffer;
@@ -114,15 +113,15 @@
DAWN_INVALID_IF(!IsAligned(entry.offset, requiredBindingAlignment),
"Offset (%u) of %s does not satisfy the minimum %s alignment (%u).",
- entry.offset, entry.buffer, bindingInfo.buffer.type, requiredBindingAlignment);
+ entry.offset, entry.buffer, layout.type, requiredBindingAlignment);
DAWN_INVALID_IF(!(entry.buffer->GetUsage() & requiredUsage),
"Binding usage (%s) of %s doesn't match expected usage (%s).",
entry.buffer->GetUsageExternalOnly(), entry.buffer, requiredUsage);
- DAWN_INVALID_IF(bindingSize < bindingInfo.buffer.minBindingSize,
+ DAWN_INVALID_IF(bindingSize < layout.minBindingSize,
"Binding size (%u) of %s is smaller than the minimum binding size (%u).",
- bindingSize, entry.buffer, bindingInfo.buffer.minBindingSize);
+ bindingSize, entry.buffer, layout.minBindingSize);
DAWN_INVALID_IF(bindingSize > maxBindingSize,
"Binding size (%u) of %s is larger than the maximum binding size (%u).",
@@ -131,10 +130,7 @@
return {};
}
-MaybeError ValidateTextureBinding(DeviceBase* device,
- const BindGroupEntry& entry,
- const BindingInfo& bindingInfo,
- UsageValidationMode mode) {
+MaybeError ValidateTextureBindGroupEntry(DeviceBase* device, const BindGroupEntry& entry) {
DAWN_INVALID_IF(entry.textureView == nullptr, "Binding entry textureView not set.");
DAWN_INVALID_IF(entry.sampler != nullptr || entry.buffer != nullptr,
@@ -142,84 +138,94 @@
DAWN_INVALID_IF(entry.nextInChain != nullptr, "nextInChain must be nullptr.");
+ TextureViewBase* view = entry.textureView;
DAWN_TRY(device->ValidateObject(entry.textureView));
+ Aspect aspect = view->GetAspects();
+ DAWN_INVALID_IF(!HasOneBit(aspect), "Multiple aspects (%s) selected in %s.", aspect, view);
+
+ return {};
+}
+
+MaybeError ValidateSampledTextureBinding(DeviceBase* device,
+ const BindGroupEntry& entry,
+ const TextureBindingLayout& layout,
+ UsageValidationMode mode) {
+ DAWN_TRY(ValidateTextureBindGroupEntry(device, entry));
+
TextureViewBase* view = entry.textureView;
Aspect aspect = view->GetAspects();
DAWN_INVALID_IF(!HasOneBit(aspect), "Multiple aspects (%s) selected in %s.", aspect, view);
TextureBase* texture = view->GetTexture();
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Texture: {
- SampleTypeBit supportedTypes =
- texture->GetFormat().GetAspectInfo(aspect).supportedSampleTypes;
- DAWN_TRY(ValidateCanUseAs(texture, wgpu::TextureUsage::TextureBinding, mode));
- DAWN_INVALID_IF(texture->IsMultisampledTexture() != bindingInfo.texture.multisampled,
- "Sample count (%u) of %s doesn't match expectation (multisampled: %d).",
- texture->GetSampleCount(), texture, bindingInfo.texture.multisampled);
+ SampleTypeBit supportedTypes = texture->GetFormat().GetAspectInfo(aspect).supportedSampleTypes;
+ DAWN_TRY(ValidateCanUseAs(texture, wgpu::TextureUsage::TextureBinding, mode));
- SampleTypeBit requiredType;
- if (bindingInfo.texture.sampleType == kInternalResolveAttachmentSampleType) {
- // If the binding's sample type is kInternalResolveAttachmentSampleType,
- // then the supported types must contain float.
- requiredType = SampleTypeBit::UnfilterableFloat;
- } else {
- requiredType = SampleTypeToSampleTypeBit(bindingInfo.texture.sampleType);
- }
+ DAWN_INVALID_IF(texture->IsMultisampledTexture() != layout.multisampled,
+ "Sample count (%u) of %s doesn't match expectation (multisampled: %d).",
+ texture->GetSampleCount(), texture, layout.multisampled);
- DAWN_INVALID_IF(
- !(supportedTypes & requiredType),
- "None of the supported sample types (%s) of %s match the expected sample "
- "types (%s).",
- supportedTypes, texture, requiredType);
-
- DAWN_INVALID_IF(entry.textureView->GetDimension() != bindingInfo.texture.viewDimension,
- "Dimension (%s) of %s doesn't match the expected dimension (%s).",
- entry.textureView->GetDimension(), entry.textureView,
- bindingInfo.texture.viewDimension);
-
- DAWN_INVALID_IF(device->IsCompatibilityMode() &&
- entry.textureView->GetDimension() !=
- texture->GetCompatibilityTextureBindingViewDimension(),
- "Dimension (%s) of %s must match textureBindingViewDimension (%s) of "
- "%s in compatibility mode.",
- entry.textureView->GetDimension(), entry.textureView,
- texture->GetCompatibilityTextureBindingViewDimension(), texture);
- break;
- }
- case BindingInfoType::StorageTexture: {
- DAWN_TRY(ValidateCanUseAs(texture, wgpu::TextureUsage::StorageBinding, mode));
-
- DAWN_ASSERT(!texture->IsMultisampledTexture());
-
- DAWN_INVALID_IF(texture->GetFormat().format != bindingInfo.storageTexture.format,
- "Format (%s) of %s expected to be (%s).", texture->GetFormat().format,
- texture, bindingInfo.storageTexture.format);
-
- DAWN_INVALID_IF(
- entry.textureView->GetDimension() != bindingInfo.storageTexture.viewDimension,
- "Dimension (%s) of %s doesn't match the expected dimension (%s).",
- entry.textureView->GetDimension(), entry.textureView,
- bindingInfo.storageTexture.viewDimension);
-
- DAWN_INVALID_IF(entry.textureView->GetLevelCount() != 1,
- "mipLevelCount (%u) of %s expected to be 1.",
- entry.textureView->GetLevelCount(), entry.textureView);
- break;
- }
- default:
- DAWN_UNREACHABLE();
- break;
+ SampleTypeBit requiredType;
+ if (layout.sampleType == kInternalResolveAttachmentSampleType) {
+ // If the binding's sample type is kInternalResolveAttachmentSampleType,
+ // then the supported types must contain float.
+ requiredType = SampleTypeBit::UnfilterableFloat;
+ } else {
+ requiredType = SampleTypeToSampleTypeBit(layout.sampleType);
}
+ DAWN_INVALID_IF(!(supportedTypes & requiredType),
+ "None of the supported sample types (%s) of %s match the expected sample "
+ "types (%s).",
+ supportedTypes, texture, requiredType);
+
+ DAWN_INVALID_IF(entry.textureView->GetDimension() != layout.viewDimension,
+ "Dimension (%s) of %s doesn't match the expected dimension (%s).",
+ entry.textureView->GetDimension(), entry.textureView, layout.viewDimension);
+
+ DAWN_INVALID_IF(
+ device->IsCompatibilityMode() && entry.textureView->GetDimension() !=
+ texture->GetCompatibilityTextureBindingViewDimension(),
+ "Dimension (%s) of %s must match textureBindingViewDimension (%s) of "
+ "%s in compatibility mode.",
+ entry.textureView->GetDimension(), entry.textureView,
+ texture->GetCompatibilityTextureBindingViewDimension(), texture);
+
+ return {};
+}
+
+MaybeError ValidateStorageTextureBinding(DeviceBase* device,
+ const BindGroupEntry& entry,
+ const StorageTextureBindingLayout& layout,
+ UsageValidationMode mode) {
+ DAWN_TRY(ValidateTextureBindGroupEntry(device, entry));
+
+ TextureViewBase* view = entry.textureView;
+ TextureBase* texture = view->GetTexture();
+
+ DAWN_TRY(ValidateCanUseAs(texture, wgpu::TextureUsage::StorageBinding, mode));
+
+ DAWN_ASSERT(!texture->IsMultisampledTexture());
+
+ DAWN_INVALID_IF(texture->GetFormat().format != layout.format,
+ "Format (%s) of %s expected to be (%s).", texture->GetFormat().format, texture,
+ layout.format);
+
+ DAWN_INVALID_IF(view->GetDimension() != layout.viewDimension,
+ "Dimension (%s) of %s doesn't match the expected dimension (%s).",
+ view->GetDimension(), entry.textureView, layout.viewDimension);
+
+ DAWN_INVALID_IF(view->GetLevelCount() != 1, "mipLevelCount (%u) of %s expected to be 1.",
+ view->GetLevelCount(), view);
+
return {};
}
MaybeError ValidateSamplerBinding(const DeviceBase* device,
const BindGroupEntry& entry,
- const BindingInfo& bindingInfo) {
+ const SamplerBindingLayout& layout) {
DAWN_INVALID_IF(entry.sampler == nullptr, "Binding entry sampler not set.");
DAWN_INVALID_IF(entry.textureView != nullptr || entry.buffer != nullptr,
@@ -229,9 +235,7 @@
DAWN_TRY(device->ValidateObject(entry.sampler));
- DAWN_ASSERT(bindingInfo.bindingType == BindingInfoType::Sampler);
-
- switch (bindingInfo.sampler.type) {
+ switch (layout.type) {
case wgpu::SamplerBindingType::NonFiltering:
DAWN_INVALID_IF(entry.sampler->IsFiltering(),
"Filtering sampler %s is incompatible with non-filtering sampler "
@@ -283,7 +287,9 @@
void ForEachUnverifiedBufferBindingIndexImpl(const BindGroupLayoutInternalBase* bgl, F&& f) {
uint32_t packedIndex = 0;
for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBufferCount(); ++bindingIndex) {
- if (bgl->GetBindingInfo(bindingIndex).buffer.minBindingSize == 0) {
+ const auto* bufferLayout =
+ std::get_if<BufferBindingLayout>(&bgl->GetBindingInfo(bindingIndex).bindingLayout);
+ if (bufferLayout == nullptr || bufferLayout->minBindingSize == 0) {
f(bindingIndex, packedIndex++);
}
}
@@ -353,31 +359,37 @@
const BindingInfo& bindingInfo = layout->GetBindingInfo(bindingIndex);
// Perform binding-type specific validation.
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer:
+ DAWN_TRY(MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout& layout) -> MaybeError {
// TODO(dawn:1485): Validate buffer binding with usage validation mode.
- DAWN_TRY_CONTEXT(ValidateBufferBinding(device, entry, bindingInfo),
+ DAWN_TRY_CONTEXT(ValidateBufferBinding(device, entry, layout),
"validating entries[%u] as a Buffer."
"\nExpected entry layout: %s",
- i, bindingInfo);
- break;
- case BindingInfoType::Texture:
- case BindingInfoType::StorageTexture:
- DAWN_TRY_CONTEXT(ValidateTextureBinding(device, entry, bindingInfo, mode),
- "validating entries[%u] as a Texture."
+ i, layout);
+ return {};
+ },
+ [&](const TextureBindingLayout& layout) -> MaybeError {
+ DAWN_TRY_CONTEXT(ValidateSampledTextureBinding(device, entry, layout, mode),
+ "validating entries[%u] as a Sampled Texture."
"\nExpected entry layout: %s",
- i, bindingInfo);
- break;
- case BindingInfoType::Sampler:
- DAWN_TRY_CONTEXT(ValidateSamplerBinding(device, entry, bindingInfo),
+ i, layout);
+ return {};
+ },
+ [&](const StorageTextureBindingLayout& layout) -> MaybeError {
+ DAWN_TRY_CONTEXT(ValidateStorageTextureBinding(device, entry, layout, mode),
+ "validating entries[%u] as a Storage Texture."
+ "\nExpected entry layout: %s",
+ i, layout);
+ return {};
+ },
+ [&](const SamplerBindingLayout& layout) -> MaybeError {
+ DAWN_TRY_CONTEXT(ValidateSamplerBinding(device, entry, layout),
"validating entries[%u] as a Sampler."
"\nExpected entry layout: %s",
- i, bindingInfo);
- break;
- case BindingInfoType::ExternalTexture:
- DAWN_UNREACHABLE();
- break;
- }
+ i, layout);
+ return {};
+ }));
}
// This should always be true because
@@ -545,7 +557,8 @@
DAWN_ASSERT(!IsError());
const BindGroupLayoutInternalBase* layout = GetLayout();
DAWN_ASSERT(bindingIndex < layout->GetBindingCount());
- DAWN_ASSERT(layout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::Buffer);
+ DAWN_ASSERT(std::holds_alternative<BufferBindingLayout>(
+ layout->GetBindingInfo(bindingIndex).bindingLayout));
BufferBase* buffer = static_cast<BufferBase*>(mBindingData.bindings[bindingIndex].Get());
return {buffer, mBindingData.bufferData[bindingIndex].offset,
mBindingData.bufferData[bindingIndex].size};
@@ -555,7 +568,8 @@
DAWN_ASSERT(!IsError());
const BindGroupLayoutInternalBase* layout = GetLayout();
DAWN_ASSERT(bindingIndex < layout->GetBindingCount());
- DAWN_ASSERT(layout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::Sampler);
+ DAWN_ASSERT(std::holds_alternative<SamplerBindingLayout>(
+ layout->GetBindingInfo(bindingIndex).bindingLayout));
return static_cast<SamplerBase*>(mBindingData.bindings[bindingIndex].Get());
}
@@ -563,9 +577,10 @@
DAWN_ASSERT(!IsError());
const BindGroupLayoutInternalBase* layout = GetLayout();
DAWN_ASSERT(bindingIndex < layout->GetBindingCount());
- DAWN_ASSERT(layout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::Texture ||
- layout->GetBindingInfo(bindingIndex).bindingType ==
- BindingInfoType::StorageTexture);
+ DAWN_ASSERT(std::holds_alternative<TextureBindingLayout>(
+ layout->GetBindingInfo(bindingIndex).bindingLayout) ||
+ std::holds_alternative<StorageTextureBindingLayout>(
+ layout->GetBindingInfo(bindingIndex).bindingLayout));
return static_cast<TextureViewBase*>(mBindingData.bindings[bindingIndex].Get());
}
diff --git a/src/dawn/native/BindGroupLayoutInternal.cpp b/src/dawn/native/BindGroupLayoutInternal.cpp
index b609fc4..33808da 100644
--- a/src/dawn/native/BindGroupLayoutInternal.cpp
+++ b/src/dawn/native/BindGroupLayoutInternal.cpp
@@ -37,6 +37,7 @@
#include "dawn/common/BitSetIterator.h"
#include "dawn/common/Enumerator.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/ChainUtils.h"
#include "dawn/native/Device.h"
#include "dawn/native/ObjectBase.h"
@@ -351,29 +352,35 @@
namespace {
bool operator!=(const BindingInfo& a, const BindingInfo& b) {
- if (a.visibility != b.visibility || a.bindingType != b.bindingType) {
+ if (a.visibility != b.visibility || a.bindingLayout.index() != b.bindingLayout.index()) {
return true;
}
- switch (a.bindingType) {
- case BindingInfoType::Buffer:
- return a.buffer.type != b.buffer.type ||
- a.buffer.hasDynamicOffset != b.buffer.hasDynamicOffset ||
- a.buffer.minBindingSize != b.buffer.minBindingSize;
- case BindingInfoType::Sampler:
- return a.sampler.type != b.sampler.type;
- case BindingInfoType::Texture:
- return a.texture.sampleType != b.texture.sampleType ||
- a.texture.viewDimension != b.texture.viewDimension ||
- a.texture.multisampled != b.texture.multisampled;
- case BindingInfoType::StorageTexture:
- return a.storageTexture.access != b.storageTexture.access ||
- a.storageTexture.viewDimension != b.storageTexture.viewDimension ||
- a.storageTexture.format != b.storageTexture.format;
- case BindingInfoType::ExternalTexture:
- return false;
- }
- DAWN_UNREACHABLE();
+ return MatchVariant(
+ a.bindingLayout,
+ [&](const BufferBindingLayout& layoutA) -> bool {
+ const BufferBindingLayout& layoutB = std::get<BufferBindingLayout>(b.bindingLayout);
+ return layoutA.type != layoutB.type ||
+ layoutA.hasDynamicOffset != layoutB.hasDynamicOffset ||
+ layoutA.minBindingSize != layoutB.minBindingSize;
+ },
+ [&](const SamplerBindingLayout& layoutA) -> bool {
+ const SamplerBindingLayout& layoutB = std::get<SamplerBindingLayout>(b.bindingLayout);
+ return layoutA.type != layoutB.type;
+ },
+ [&](const TextureBindingLayout& layoutA) -> bool {
+ const TextureBindingLayout& layoutB = std::get<TextureBindingLayout>(b.bindingLayout);
+ return layoutA.sampleType != layoutB.sampleType ||
+ layoutA.viewDimension != layoutB.viewDimension ||
+ layoutA.multisampled != layoutB.multisampled;
+ },
+ [&](const StorageTextureBindingLayout& layoutA) -> bool {
+ const StorageTextureBindingLayout& layoutB =
+ std::get<StorageTextureBindingLayout>(b.bindingLayout);
+ return layoutA.access != layoutB.access ||
+ layoutA.viewDimension != layoutB.viewDimension ||
+ layoutA.format != layoutB.format;
+ });
}
bool IsBufferBinding(const UnpackedPtr<BindGroupLayoutEntry>& binding) {
@@ -393,29 +400,24 @@
bindingInfo.visibility = binding->visibility;
if (binding->buffer.type != wgpu::BufferBindingType::Undefined) {
- bindingInfo.bindingType = BindingInfoType::Buffer;
- bindingInfo.buffer = binding->buffer;
+ bindingInfo.bindingLayout = binding->buffer;
} else if (binding->sampler.type != wgpu::SamplerBindingType::Undefined) {
- bindingInfo.bindingType = BindingInfoType::Sampler;
- bindingInfo.sampler = binding->sampler;
+ bindingInfo.bindingLayout = binding->sampler;
} else if (binding->texture.sampleType != wgpu::TextureSampleType::Undefined) {
- bindingInfo.bindingType = BindingInfoType::Texture;
- bindingInfo.texture = binding->texture.WithTrivialFrontendDefaults();
-
+ TextureBindingLayout bindingLayout = binding->texture.WithTrivialFrontendDefaults();
if (binding->texture.viewDimension == wgpu::TextureViewDimension::Undefined) {
- bindingInfo.texture.viewDimension = wgpu::TextureViewDimension::e2D;
+ bindingLayout.viewDimension = wgpu::TextureViewDimension::e2D;
}
+ bindingInfo.bindingLayout = bindingLayout;
} else if (binding->storageTexture.access != wgpu::StorageTextureAccess::Undefined) {
- bindingInfo.bindingType = BindingInfoType::StorageTexture;
- bindingInfo.storageTexture = binding->storageTexture.WithTrivialFrontendDefaults();
-
+ StorageTextureBindingLayout bindingLayout =
+ binding->storageTexture.WithTrivialFrontendDefaults();
if (binding->storageTexture.viewDimension == wgpu::TextureViewDimension::Undefined) {
- bindingInfo.storageTexture.viewDimension = wgpu::TextureViewDimension::e2D;
+ bindingLayout.viewDimension = wgpu::TextureViewDimension::e2D;
}
+ bindingInfo.bindingLayout = bindingLayout;
} else {
- if (auto* externalTextureBindingLayout = binding.Get<ExternalTextureBindingLayout>()) {
- bindingInfo.bindingType = BindingInfoType::ExternalTexture;
- }
+ DAWN_UNREACHABLE();
}
return bindingInfo;
@@ -459,48 +461,61 @@
BindingInfo bInfo = CreateBindGroupLayoutInfo(b);
// Sort by type.
- if (aInfo.bindingType != bInfo.bindingType) {
- return aInfo.bindingType < bInfo.bindingType;
+ if (aInfo.bindingLayout.index() != bInfo.bindingLayout.index()) {
+ return GetBindingInfoType(aInfo) < GetBindingInfoType(bInfo);
}
if (a->visibility != b->visibility) {
return a->visibility < b->visibility;
}
- switch (aInfo.bindingType) {
- case BindingInfoType::Buffer:
- if (aInfo.buffer.minBindingSize != bInfo.buffer.minBindingSize) {
- return aInfo.buffer.minBindingSize < bInfo.buffer.minBindingSize;
+ switch (GetBindingInfoType(aInfo)) {
+ case BindingInfoType::Buffer: {
+ const auto& aLayout = std::get<BufferBindingLayout>(aInfo.bindingLayout);
+ const auto& bLayout = std::get<BufferBindingLayout>(bInfo.bindingLayout);
+ if (aLayout.minBindingSize != bLayout.minBindingSize) {
+ return aLayout.minBindingSize < bLayout.minBindingSize;
}
break;
- case BindingInfoType::Sampler:
- if (aInfo.sampler.type != bInfo.sampler.type) {
- return aInfo.sampler.type < bInfo.sampler.type;
+ }
+ case BindingInfoType::Sampler: {
+ const auto& aLayout = std::get<SamplerBindingLayout>(aInfo.bindingLayout);
+ const auto& bLayout = std::get<SamplerBindingLayout>(bInfo.bindingLayout);
+ if (aLayout.type != bLayout.type) {
+ return aLayout.type < bLayout.type;
}
break;
- case BindingInfoType::Texture:
- if (aInfo.texture.multisampled != bInfo.texture.multisampled) {
- return aInfo.texture.multisampled < bInfo.texture.multisampled;
+ }
+ case BindingInfoType::Texture: {
+ const auto& aLayout = std::get<TextureBindingLayout>(aInfo.bindingLayout);
+ const auto& bLayout = std::get<TextureBindingLayout>(bInfo.bindingLayout);
+ if (aLayout.multisampled != bLayout.multisampled) {
+ return aLayout.multisampled < bLayout.multisampled;
}
- if (aInfo.texture.viewDimension != bInfo.texture.viewDimension) {
- return aInfo.texture.viewDimension < bInfo.texture.viewDimension;
+ if (aLayout.viewDimension != bLayout.viewDimension) {
+ return aLayout.viewDimension < bLayout.viewDimension;
}
- if (aInfo.texture.sampleType != bInfo.texture.sampleType) {
- return aInfo.texture.sampleType < bInfo.texture.sampleType;
+ if (aLayout.sampleType != bLayout.sampleType) {
+ return aLayout.sampleType < bLayout.sampleType;
}
break;
- case BindingInfoType::StorageTexture:
- if (aInfo.storageTexture.access != bInfo.storageTexture.access) {
- return aInfo.storageTexture.access < bInfo.storageTexture.access;
+ }
+ case BindingInfoType::StorageTexture: {
+ const auto& aLayout = std::get<StorageTextureBindingLayout>(aInfo.bindingLayout);
+ const auto& bLayout = std::get<StorageTextureBindingLayout>(bInfo.bindingLayout);
+ if (aLayout.access != bLayout.access) {
+ return aLayout.access < bLayout.access;
}
- if (aInfo.storageTexture.viewDimension != bInfo.storageTexture.viewDimension) {
- return aInfo.storageTexture.viewDimension < bInfo.storageTexture.viewDimension;
+ if (aLayout.viewDimension != bLayout.viewDimension) {
+ return aLayout.viewDimension < bLayout.viewDimension;
}
- if (aInfo.storageTexture.format != bInfo.storageTexture.format) {
- return aInfo.storageTexture.format < bInfo.storageTexture.format;
+ if (aLayout.format != bLayout.format) {
+ return aLayout.format < bLayout.format;
}
break;
+ }
case BindingInfoType::ExternalTexture:
+ DAWN_UNREACHABLE();
break;
}
return a->binding < b->binding;
@@ -512,7 +527,7 @@
BindingIndex lastBufferIndex{0};
BindingIndex firstNonBufferIndex = std::numeric_limits<BindingIndex>::max();
for (auto [i, binding] : Enumerate(bindings)) {
- if (binding.bindingType == BindingInfoType::Buffer) {
+ if (std::holds_alternative<BufferBindingLayout>(binding.bindingLayout)) {
lastBufferIndex = std::max(i, lastBufferIndex);
} else {
firstNonBufferIndex = std::min(i, firstNonBufferIndex);
@@ -609,11 +624,25 @@
recorder.Record(id, index);
const BindingInfo& info = mBindingInfo[index];
- recorder.Record(info.buffer.hasDynamicOffset, info.visibility, info.bindingType,
- info.buffer.type, info.buffer.minBindingSize, info.sampler.type,
- info.texture.sampleType, info.texture.viewDimension,
- info.texture.multisampled, info.storageTexture.access,
- info.storageTexture.format, info.storageTexture.viewDimension);
+ recorder.Record(info.visibility);
+
+ MatchVariant(
+ info.bindingLayout,
+ [&](const BufferBindingLayout& layout) {
+ recorder.Record(BindingInfoType::Buffer, layout.hasDynamicOffset, layout.type,
+ layout.minBindingSize);
+ },
+ [&](const SamplerBindingLayout& layout) {
+ recorder.Record(BindingInfoType::Sampler, layout.type);
+ },
+ [&](const TextureBindingLayout& layout) {
+ recorder.Record(BindingInfoType::Texture, layout.sampleType, layout.viewDimension,
+ layout.multisampled);
+ },
+ [&](const StorageTextureBindingLayout& layout) {
+ recorder.Record(BindingInfoType::StorageTexture, layout.access, layout.format,
+ layout.viewDimension);
+ });
}
return recorder.GetContentHash();
@@ -705,7 +734,7 @@
bool BindGroupLayoutInternalBase::IsStorageBufferBinding(BindingIndex bindingIndex) const {
DAWN_ASSERT(bindingIndex < GetBufferCount());
- switch (GetBindingInfo(bindingIndex).buffer.type) {
+ switch (std::get<BufferBindingLayout>(GetBindingInfo(bindingIndex).bindingLayout).type) {
case wgpu::BufferBindingType::Uniform:
return false;
case kInternalStorageBufferBinding:
diff --git a/src/dawn/native/BindingInfo.cpp b/src/dawn/native/BindingInfo.cpp
index 220b3fe..ae8f3e6 100644
--- a/src/dawn/native/BindingInfo.cpp
+++ b/src/dawn/native/BindingInfo.cpp
@@ -27,11 +27,23 @@
#include "dawn/native/BindingInfo.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/ChainUtils.h"
#include "dawn/native/Limits.h"
namespace dawn::native {
+BindingInfoType GetBindingInfoType(const BindingInfo& info) {
+ return MatchVariant(
+ info.bindingLayout,
+ [](const BufferBindingLayout&) -> BindingInfoType { return BindingInfoType::Buffer; },
+ [](const SamplerBindingLayout&) -> BindingInfoType { return BindingInfoType::Sampler; },
+ [](const TextureBindingLayout&) -> BindingInfoType { return BindingInfoType::Texture; },
+ [](const StorageTextureBindingLayout&) -> BindingInfoType {
+ return BindingInfoType::StorageTexture;
+ });
+}
+
void IncrementBindingCounts(BindingCounts* bindingCounts,
const UnpackedPtr<BindGroupLayoutEntry>& entry) {
bindingCounts->totalCount += 1;
diff --git a/src/dawn/native/BindingInfo.h b/src/dawn/native/BindingInfo.h
index d21f22e..16970f6 100644
--- a/src/dawn/native/BindingInfo.h
+++ b/src/dawn/native/BindingInfo.h
@@ -29,6 +29,7 @@
#define SRC_DAWN_NATIVE_BINDINGINFO_H_
#include <cstdint>
+#include <variant>
#include <vector>
#include "dawn/common/Constants.h"
@@ -61,15 +62,15 @@
BindingNumber binding;
wgpu::ShaderStage visibility;
- BindingInfoType bindingType;
-
- // TODO(dawn:527): These four values could be made into a union.
- BufferBindingLayout buffer;
- SamplerBindingLayout sampler;
- TextureBindingLayout texture;
- StorageTextureBindingLayout storageTexture;
+ std::variant<BufferBindingLayout,
+ SamplerBindingLayout,
+ TextureBindingLayout,
+ StorageTextureBindingLayout>
+ bindingLayout;
};
+BindingInfoType GetBindingInfoType(const BindingInfo& bindingInfo);
+
struct BindingSlot {
BindGroupIndex group;
BindingNumber binding;
diff --git a/src/dawn/native/CommandBufferStateTracker.cpp b/src/dawn/native/CommandBufferStateTracker.cpp
index 2a24eed..c02fe7a 100644
--- a/src/dawn/native/CommandBufferStateTracker.cpp
+++ b/src/dawn/native/CommandBufferStateTracker.cpp
@@ -124,11 +124,12 @@
for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBufferCount(); ++bindingIndex) {
const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
// Buffer bindings are sorted to have smallest of bindingIndex.
- DAWN_ASSERT(bindingInfo.bindingType == BindingInfoType::Buffer);
+ const BufferBindingLayout& layout =
+ std::get<BufferBindingLayout>(bindingInfo.bindingLayout);
// BindGroup validation already guarantees the buffer usage includes
// wgpu::BufferUsage::Storage
- if (bindingInfo.buffer.type != wgpu::BufferBindingType::Storage) {
+ if (layout.type != wgpu::BufferBindingType::Storage) {
continue;
}
@@ -141,7 +142,7 @@
uint64_t adjustedOffset = bufferBinding.offset;
// Apply dynamic offset if any.
- if (bindingInfo.buffer.hasDynamicOffset) {
+ if (layout.hasDynamicOffset) {
// SetBindGroup validation already guarantees offsets and sizes don't overflow.
adjustedOffset += dynamicOffsets[groupIndex][static_cast<uint32_t>(bindingIndex)];
}
@@ -162,11 +163,13 @@
bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
- if (bindingInfo.bindingType != BindingInfoType::StorageTexture) {
+ const auto* layout =
+ std::get_if<StorageTextureBindingLayout>(&bindingInfo.bindingLayout);
+ if (layout == nullptr) {
continue;
}
- switch (bindingInfo.storageTexture.access) {
+ switch (layout->access) {
case wgpu::StorageTextureAccess::WriteOnly:
case wgpu::StorageTextureAccess::ReadWrite:
break;
@@ -359,8 +362,8 @@
for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
- if (bindingInfo.bindingType != BindingInfoType::Texture &&
- bindingInfo.bindingType != BindingInfoType::StorageTexture) {
+ if (!std::holds_alternative<TextureBindingLayout>(bindingInfo.bindingLayout) &&
+ !std::holds_alternative<StorageTextureBindingLayout>(bindingInfo.bindingLayout)) {
continue;
}
@@ -672,11 +675,12 @@
mBindgroups[i]->GetUnverifiedBufferSizes()[packedIndex.value()];
uint64_t minBufferSize = (*mMinBufferSizes)[i][packedIndex.value()];
+ const auto& layout = std::get<BufferBindingLayout>(bindingInfo.bindingLayout);
return DAWN_VALIDATION_ERROR(
"%s bound with size %u at group %u, binding %u is too small. The pipeline (%s) "
"requires a buffer binding which is at least %u bytes.%s",
buffer, bufferSize, i, bindingNumber, mLastPipeline, minBufferSize,
- (bindingInfo.buffer.type == wgpu::BufferBindingType::Uniform
+ (layout.type == wgpu::BufferBindingType::Uniform
? " This binding is a uniform buffer binding. It is padded to a multiple "
"of 16 bytes, and as a result may be larger than the associated data in "
"the shader source."
diff --git a/src/dawn/native/PassResourceUsageTracker.cpp b/src/dawn/native/PassResourceUsageTracker.cpp
index b75e695..8a9e8e4 100644
--- a/src/dawn/native/PassResourceUsageTracker.cpp
+++ b/src/dawn/native/PassResourceUsageTracker.cpp
@@ -29,6 +29,7 @@
#include <utility>
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/BindGroup.h"
#include "dawn/native/Buffer.h"
#include "dawn/native/EnumMaskIterator.h"
@@ -108,10 +109,11 @@
++bindingIndex) {
const BindingInfo& bindingInfo = group->GetLayout()->GetBindingInfo(bindingIndex);
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer: {
+ MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout& layout) {
BufferBase* buffer = group->GetBindingAsBufferBinding(bindingIndex).buffer;
- switch (bindingInfo.buffer.type) {
+ switch (layout.type) {
case wgpu::BufferBindingType::Uniform:
BufferUsedAs(buffer, wgpu::BufferUsage::Uniform, bindingInfo.visibility);
break;
@@ -127,12 +129,10 @@
case wgpu::BufferBindingType::Undefined:
DAWN_UNREACHABLE();
}
- break;
- }
-
- case BindingInfoType::Texture: {
+ },
+ [&](const TextureBindingLayout& layout) {
TextureViewBase* view = group->GetBindingAsTextureView(bindingIndex);
- switch (bindingInfo.texture.sampleType) {
+ switch (layout.sampleType) {
case kInternalResolveAttachmentSampleType:
TextureViewUsedAs(view, kResolveAttachmentLoadingUsage,
bindingInfo.visibility);
@@ -142,12 +142,10 @@
bindingInfo.visibility);
break;
}
- break;
- }
-
- case BindingInfoType::StorageTexture: {
+ },
+ [&](const StorageTextureBindingLayout& layout) {
TextureViewBase* view = group->GetBindingAsTextureView(bindingIndex);
- switch (bindingInfo.storageTexture.access) {
+ switch (layout.access) {
case wgpu::StorageTextureAccess::WriteOnly:
TextureViewUsedAs(view, kWriteOnlyStorageTexture, bindingInfo.visibility);
break;
@@ -161,16 +159,8 @@
case wgpu::StorageTextureAccess::Undefined:
DAWN_UNREACHABLE();
}
- break;
- }
-
- case BindingInfoType::ExternalTexture:
- DAWN_UNREACHABLE();
- break;
-
- case BindingInfoType::Sampler:
- break;
- }
+ },
+ [&](const SamplerBindingLayout&) {});
}
for (const Ref<ExternalTextureBase>& externalTexture : group->GetBoundExternalTextures()) {
@@ -222,24 +212,20 @@
for (BindingIndex index{0}; index < group->GetLayout()->GetBindingCount(); ++index) {
const BindingInfo& bindingInfo = group->GetLayout()->GetBindingInfo(index);
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer: {
+ MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout&) {
mUsage.referencedBuffers.insert(group->GetBindingAsBufferBinding(index).buffer);
- break;
- }
-
- case BindingInfoType::Texture:
- case BindingInfoType::StorageTexture: {
+ },
+ [&](const TextureBindingLayout&) {
mUsage.referencedTextures.insert(
group->GetBindingAsTextureView(index)->GetTexture());
- break;
- }
-
- case BindingInfoType::ExternalTexture:
- DAWN_UNREACHABLE();
- case BindingInfoType::Sampler:
- break;
- }
+ },
+ [&](const StorageTextureBindingLayout&) {
+ mUsage.referencedTextures.insert(
+ group->GetBindingAsTextureView(index)->GetTexture());
+ },
+ [](const SamplerBindingLayout&) {});
}
for (const Ref<ExternalTextureBase>& externalTexture : group->GetBoundExternalTextures()) {
diff --git a/src/dawn/native/ProgrammableEncoder.cpp b/src/dawn/native/ProgrammableEncoder.cpp
index 4d577d2..036b231 100644
--- a/src/dawn/native/ProgrammableEncoder.cpp
+++ b/src/dawn/native/ProgrammableEncoder.cpp
@@ -149,12 +149,12 @@
const BindingInfo& bindingInfo = layout->GetBindingInfo(i);
// BGL creation sorts bindings such that the dynamic buffer bindings are first.
- // DAWN_ASSERT that this true.
- DAWN_ASSERT(bindingInfo.bindingType == BindingInfoType::Buffer);
- DAWN_ASSERT(bindingInfo.buffer.hasDynamicOffset);
+ const BufferBindingLayout& bindingLayout =
+ std::get<BufferBindingLayout>(bindingInfo.bindingLayout);
+ DAWN_ASSERT(bindingLayout.hasDynamicOffset);
uint64_t requiredAlignment;
- switch (bindingInfo.buffer.type) {
+ switch (bindingLayout.type) {
case wgpu::BufferBindingType::Uniform:
requiredAlignment = GetDevice()->GetLimits().v1.minUniformBufferOffsetAlignment;
break;
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 1898b61..b55ea40 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -383,7 +383,9 @@
for (BindingIndex bindingIndex{0}; bindingIndex < layout->GetBufferCount(); ++bindingIndex) {
const BindingInfo& bindingInfo = layout->GetBindingInfo(bindingIndex);
- if (bindingInfo.buffer.minBindingSize != 0) {
+ const auto* bufferBindingLayout =
+ std::get_if<BufferBindingLayout>(&bindingInfo.bindingLayout);
+ if (bufferBindingLayout == nullptr || bufferBindingLayout->minBindingSize > 0) {
// Skip bindings that have minimum buffer size set in the layout
continue;
}
@@ -411,20 +413,20 @@
}
bool IsShaderCompatibleWithPipelineLayoutOnStorageTextureAccess(
- const BindingInfo& bindingInfo,
- const StorageTextureBindingInfo& bindingLayout) {
- return bindingInfo.storageTexture.access == bindingLayout.access ||
- (bindingInfo.storageTexture.access == wgpu::StorageTextureAccess::ReadWrite &&
- bindingLayout.access == wgpu::StorageTextureAccess::WriteOnly);
+ const StorageTextureBindingLayout& pipelineBindingLayout,
+ const StorageTextureBindingInfo& shaderBindingInfo) {
+ return pipelineBindingLayout.access == shaderBindingInfo.access ||
+ (pipelineBindingLayout.access == wgpu::StorageTextureAccess::ReadWrite &&
+ shaderBindingInfo.access == wgpu::StorageTextureAccess::WriteOnly);
}
BindingInfoType GetShaderBindingType(const ShaderBindingInfo& shaderInfo) {
return MatchVariant(
- shaderInfo.bindingInfo, [&](const BufferBindingInfo&) { return BindingInfoType::Buffer; },
- [&](const StorageTextureBindingInfo&) { return BindingInfoType::StorageTexture; },
- [&](const SampledTextureBindingInfo&) { return BindingInfoType::Texture; },
- [&](const SamplerBindingInfo&) { return BindingInfoType::Sampler; },
- [&](const ExternalTextureBindingInfo&) { return BindingInfoType::ExternalTexture; });
+ shaderInfo.bindingInfo, [](const BufferBindingInfo&) { return BindingInfoType::Buffer; },
+ [](const SamplerBindingInfo&) { return BindingInfoType::Sampler; },
+ [](const SampledTextureBindingInfo&) { return BindingInfoType::Texture; },
+ [](const StorageTextureBindingInfo&) { return BindingInfoType::StorageTexture; },
+ [](const ExternalTextureBindingInfo&) { return BindingInfoType::ExternalTexture; });
}
MaybeError ValidateCompatibilityOfSingleBindingWithLayout(const DeviceBase* device,
@@ -460,10 +462,11 @@
BindingIndex bindingIndex(bindingIt->second);
const BindingInfo& layoutInfo = layout->GetBindingInfo(bindingIndex);
+ BindingInfoType bindingLayoutType = GetBindingInfoType(layoutInfo);
BindingInfoType shaderBindingType = GetShaderBindingType(shaderInfo);
- DAWN_INVALID_IF(layoutInfo.bindingType != shaderBindingType,
+ DAWN_INVALID_IF(bindingLayoutType != shaderBindingType,
"Binding type in the shader (%s) doesn't match the type in the layout (%s).",
- shaderBindingType, layoutInfo.bindingType);
+ shaderBindingType, bindingLayoutType);
ExternalTextureBindingExpansionMap expansions = layout->GetExternalTextureBindingExpansionMap();
DAWN_INVALID_IF(expansions.find(bindingNumber) != expansions.end(),
@@ -477,21 +480,23 @@
return MatchVariant(
shaderInfo.bindingInfo,
[&](const SampledTextureBindingInfo& bindingInfo) -> MaybeError {
+ const TextureBindingLayout& bindingLayout =
+ std::get<TextureBindingLayout>(layoutInfo.bindingLayout);
DAWN_INVALID_IF(
- layoutInfo.texture.multisampled != bindingInfo.multisampled,
+ bindingLayout.multisampled != bindingInfo.multisampled,
"Binding multisampled flag (%u) doesn't match the layout's multisampled "
"flag (%u)",
- layoutInfo.texture.multisampled, bindingInfo.multisampled);
+ bindingLayout.multisampled, bindingInfo.multisampled);
// TODO(dawn:563): Provide info about the sample types.
SampleTypeBit requiredType;
- if (layoutInfo.texture.sampleType == kInternalResolveAttachmentSampleType) {
+ if (bindingLayout.sampleType == kInternalResolveAttachmentSampleType) {
// If the layout's texture's sample type is
// kInternalResolveAttachmentSampleType, then the shader's compatible sample
// types must contain float.
requiredType = SampleTypeBit::UnfilterableFloat;
} else {
- requiredType = SampleTypeToSampleTypeBit(layoutInfo.texture.sampleType);
+ requiredType = SampleTypeToSampleTypeBit(bindingLayout.sampleType);
}
DAWN_INVALID_IF(!(bindingInfo.compatibleSampleTypes & requiredType),
@@ -499,68 +504,72 @@
"sample type of the layout.");
DAWN_INVALID_IF(
- layoutInfo.texture.viewDimension != bindingInfo.viewDimension,
+ bindingLayout.viewDimension != bindingInfo.viewDimension,
"The shader's binding dimension (%s) doesn't match the shader's binding "
"dimension (%s).",
- layoutInfo.texture.viewDimension, bindingInfo.viewDimension);
+ bindingLayout.viewDimension, bindingInfo.viewDimension);
return {};
},
[&](const StorageTextureBindingInfo& bindingInfo) -> MaybeError {
- DAWN_ASSERT(layoutInfo.storageTexture.format != wgpu::TextureFormat::Undefined);
+ const StorageTextureBindingLayout& bindingLayout =
+ std::get<StorageTextureBindingLayout>(layoutInfo.bindingLayout);
+ DAWN_ASSERT(bindingLayout.format != wgpu::TextureFormat::Undefined);
DAWN_ASSERT(bindingInfo.format != wgpu::TextureFormat::Undefined);
DAWN_INVALID_IF(!IsShaderCompatibleWithPipelineLayoutOnStorageTextureAccess(
- layoutInfo, bindingInfo),
+ bindingLayout, bindingInfo),
"The layout's binding access (%s) isn't compatible with the shader's "
"binding access (%s).",
- layoutInfo.storageTexture.access, bindingInfo.access);
+ bindingLayout.access, bindingInfo.access);
- DAWN_INVALID_IF(layoutInfo.storageTexture.format != bindingInfo.format,
+ DAWN_INVALID_IF(bindingLayout.format != bindingInfo.format,
"The layout's binding format (%s) doesn't match the shader's binding "
"format (%s).",
- layoutInfo.storageTexture.format, bindingInfo.format);
+ bindingLayout.format, bindingInfo.format);
- DAWN_INVALID_IF(layoutInfo.storageTexture.viewDimension != bindingInfo.viewDimension,
+ DAWN_INVALID_IF(bindingLayout.viewDimension != bindingInfo.viewDimension,
"The layout's binding dimension (%s) doesn't match the "
"shader's binding dimension (%s).",
- layoutInfo.storageTexture.viewDimension, bindingInfo.viewDimension);
+ bindingLayout.viewDimension, bindingInfo.viewDimension);
return {};
},
[&](const BufferBindingInfo& bindingInfo) -> MaybeError {
+ const BufferBindingLayout& bindingLayout =
+ std::get<BufferBindingLayout>(layoutInfo.bindingLayout);
// Binding mismatch between shader and bind group is invalid. For example, a
// writable binding in the shader with a readonly storage buffer in the bind
// group layout is invalid. For internal usage with internal shaders, a storage
// binding in the shader with an internal storage buffer in the bind group
// layout is also valid.
- bool validBindingConversion =
- (layoutInfo.buffer.type == kInternalStorageBufferBinding &&
- bindingInfo.type == wgpu::BufferBindingType::Storage);
+ bool validBindingConversion = (bindingLayout.type == kInternalStorageBufferBinding &&
+ bindingInfo.type == wgpu::BufferBindingType::Storage);
DAWN_INVALID_IF(
- layoutInfo.buffer.type != bindingInfo.type && !validBindingConversion,
+ bindingLayout.type != bindingInfo.type && !validBindingConversion,
"The buffer type in the shader (%s) is not compatible with the type in the "
"layout (%s).",
- bindingInfo.type, layoutInfo.buffer.type);
+ bindingInfo.type, bindingLayout.type);
- DAWN_INVALID_IF(layoutInfo.buffer.minBindingSize != 0 &&
- bindingInfo.minBindingSize > layoutInfo.buffer.minBindingSize,
+ DAWN_INVALID_IF(bindingLayout.minBindingSize != 0 &&
+ bindingInfo.minBindingSize > bindingLayout.minBindingSize,
"The shader uses more bytes of the buffer (%u) than the layout's "
"minBindingSize (%u).",
- bindingInfo.minBindingSize, layoutInfo.buffer.minBindingSize);
+ bindingInfo.minBindingSize, bindingLayout.minBindingSize);
return {};
},
[&](const SamplerBindingInfo& bindingInfo) -> MaybeError {
+ const SamplerBindingLayout& bindingLayout =
+ std::get<SamplerBindingLayout>(layoutInfo.bindingLayout);
DAWN_INVALID_IF(
- (layoutInfo.sampler.type == wgpu::SamplerBindingType::Comparison) !=
+ (bindingLayout.type == wgpu::SamplerBindingType::Comparison) !=
bindingInfo.isComparison,
"The sampler type in the shader (comparison: %u) doesn't match the type in "
"the layout (comparison: %u).",
bindingInfo.isComparison,
- layoutInfo.sampler.type == wgpu::SamplerBindingType::Comparison);
+ bindingLayout.type == wgpu::SamplerBindingType::Comparison);
return {};
},
-
- [&](const ExternalTextureBindingInfo&) -> MaybeError {
+ [](const ExternalTextureBindingInfo&) -> MaybeError {
DAWN_UNREACHABLE();
return {};
});
@@ -1153,21 +1162,17 @@
layout->GetBindGroupLayout(pair.sampler.group);
const BindingInfo& samplerInfo =
samplerBGL->GetBindingInfo(samplerBGL->GetBindingIndex(pair.sampler.binding));
- if (samplerInfo.sampler.type != wgpu::SamplerBindingType::Filtering) {
+ const SamplerBindingLayout& samplerLayout =
+ std::get<SamplerBindingLayout>(samplerInfo.bindingLayout);
+ if (samplerLayout.type != wgpu::SamplerBindingType::Filtering) {
continue;
}
const BindGroupLayoutInternalBase* textureBGL =
layout->GetBindGroupLayout(pair.texture.group);
const BindingInfo& textureInfo =
textureBGL->GetBindingInfo(textureBGL->GetBindingIndex(pair.texture.binding));
-
- DAWN_ASSERT(textureInfo.bindingType != BindingInfoType::Buffer &&
- textureInfo.bindingType != BindingInfoType::Sampler &&
- textureInfo.bindingType != BindingInfoType::StorageTexture);
-
- if (textureInfo.bindingType != BindingInfoType::Texture) {
- continue;
- }
+ const TextureBindingLayout& sampledTextureBindingLayout =
+ std::get<TextureBindingLayout>(textureInfo.bindingLayout);
// Uint/Sint can't be statically used with a sampler, so they any
// texture bindings reflected must be float or depth textures. If
@@ -1175,12 +1180,12 @@
// specifies a uint/sint texture binding,
// |ValidateCompatibilityWithBindGroupLayout| will fail since the
// sampleType does not match.
- DAWN_ASSERT(textureInfo.texture.sampleType != wgpu::TextureSampleType::Undefined &&
- textureInfo.texture.sampleType != wgpu::TextureSampleType::Uint &&
- textureInfo.texture.sampleType != wgpu::TextureSampleType::Sint);
+ DAWN_ASSERT(sampledTextureBindingLayout.sampleType != wgpu::TextureSampleType::Undefined &&
+ sampledTextureBindingLayout.sampleType != wgpu::TextureSampleType::Uint &&
+ sampledTextureBindingLayout.sampleType != wgpu::TextureSampleType::Sint);
DAWN_INVALID_IF(
- textureInfo.texture.sampleType == wgpu::TextureSampleType::UnfilterableFloat,
+ sampledTextureBindingLayout.sampleType == wgpu::TextureSampleType::UnfilterableFloat,
"Texture binding (group:%u, binding:%u) is %s but used statically with a sampler "
"(group:%u, binding:%u) that's %s",
pair.texture.group, pair.texture.binding, wgpu::TextureSampleType::UnfilterableFloat,
diff --git a/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp b/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
index 27323c1..df0c29f 100644
--- a/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
+++ b/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
@@ -31,6 +31,7 @@
#include <vector>
#include "dawn/common/Assert.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/Format.h"
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d11/BindGroupD3D11.h"
@@ -172,16 +173,17 @@
++bindingIndex) {
const BindingInfo& bindingInfo = group->GetLayout()->GetBindingInfo(bindingIndex);
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer: {
+ DAWN_TRY(MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout& layout) -> MaybeError {
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
auto offset = binding.offset;
- if (bindingInfo.buffer.hasDynamicOffset) {
+ if (layout.hasDynamicOffset) {
// Dynamic buffers are packed at the front of BindingIndices.
offset += dynamicOffsets[bindingIndex];
}
- switch (bindingInfo.buffer.type) {
+ switch (layout.type) {
case wgpu::BufferBindingType::Storage:
case kInternalStorageBufferBinding: {
DAWN_ASSERT(IsSubset(
@@ -202,11 +204,10 @@
break;
}
}
- break;
- }
-
- case BindingInfoType::StorageTexture: {
- switch (bindingInfo.storageTexture.access) {
+ return {};
+ },
+ [&](const StorageTextureBindingLayout& layout) -> MaybeError {
+ switch (layout.access) {
case wgpu::StorageTextureAccess::WriteOnly:
case wgpu::StorageTextureAccess::ReadWrite: {
ComPtr<ID3D11UnorderedAccessView> d3d11UAV;
@@ -224,14 +225,10 @@
DAWN_UNREACHABLE();
break;
}
- break;
- }
- case BindingInfoType::Texture:
- case BindingInfoType::ExternalTexture:
- case BindingInfoType::Sampler: {
- break;
- }
- }
+ return {};
+ },
+ [](const TextureBindingLayout&) -> MaybeError { return {}; },
+ [](const SamplerBindingLayout&) -> MaybeError { return {}; }));
}
}
@@ -288,16 +285,17 @@
const uint32_t bindingSlot = indices[bindingIndex];
const auto bindingVisibility = bindingInfo.visibility & mVisibleStages;
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer: {
+ DAWN_TRY(MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout& layout) -> MaybeError {
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
auto offset = binding.offset;
- if (bindingInfo.buffer.hasDynamicOffset) {
+ if (layout.hasDynamicOffset) {
// Dynamic buffers are packed at the front of BindingIndices.
offset += dynamicOffsets[bindingIndex];
}
- switch (bindingInfo.buffer.type) {
+ switch (layout.type) {
case wgpu::BufferBindingType::Uniform: {
ToBackend(binding.buffer)->EnsureConstantBufferIsUpdated(mCommandContext);
ID3D11Buffer* d3d11Buffer =
@@ -366,10 +364,9 @@
case wgpu::BufferBindingType::Undefined:
DAWN_UNREACHABLE();
}
- break;
- }
-
- case BindingInfoType::Sampler: {
+ return {};
+ },
+ [&](const SamplerBindingLayout&) -> MaybeError {
Sampler* sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
ID3D11SamplerState* d3d11SamplerState = sampler->GetD3D11SamplerState();
if (bindingVisibility & wgpu::ShaderStage::Vertex) {
@@ -381,10 +378,9 @@
if (bindingVisibility & wgpu::ShaderStage::Compute) {
deviceContext->CSSetSamplers(bindingSlot, 1, &d3d11SamplerState);
}
- break;
- }
-
- case BindingInfoType::Texture: {
+ return {};
+ },
+ [&](const TextureBindingLayout&) -> MaybeError {
TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
ComPtr<ID3D11ShaderResourceView> srv;
// For sampling from stencil, we have to use an internal mirror 'R8Uint' texture.
@@ -403,12 +399,11 @@
if (bindingVisibility & wgpu::ShaderStage::Compute) {
deviceContext->CSSetShaderResources(bindingSlot, 1, srv.GetAddressOf());
}
- break;
- }
-
- case BindingInfoType::StorageTexture: {
+ return {};
+ },
+ [&](const StorageTextureBindingLayout& layout) -> MaybeError {
TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
- switch (bindingInfo.storageTexture.access) {
+ switch (layout.access) {
case wgpu::StorageTextureAccess::WriteOnly:
case wgpu::StorageTextureAccess::ReadWrite: {
ID3D11UnorderedAccessView* d3d11UAV = nullptr;
@@ -436,13 +431,8 @@
default:
DAWN_UNREACHABLE();
}
- break;
- }
-
- case BindingInfoType::ExternalTexture: {
- return DAWN_UNIMPLEMENTED_ERROR("External textures are not supported");
- }
- }
+ return {};
+ }));
}
return {};
}
@@ -459,9 +449,10 @@
const uint32_t bindingSlot = indices[bindingIndex];
const auto bindingVisibility = bindingInfo.visibility & mVisibleStages;
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer: {
- switch (bindingInfo.buffer.type) {
+ MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout& layout) {
+ switch (layout.type) {
case wgpu::BufferBindingType::Uniform: {
ID3D11Buffer* nullBuffer = nullptr;
if (bindingVisibility & wgpu::ShaderStage::Vertex) {
@@ -511,10 +502,8 @@
case wgpu::BufferBindingType::Undefined:
DAWN_UNREACHABLE();
}
- break;
- }
-
- case BindingInfoType::Sampler: {
+ },
+ [&](const SamplerBindingLayout&) {
ID3D11SamplerState* nullSampler = nullptr;
if (bindingVisibility & wgpu::ShaderStage::Vertex) {
deviceContext->VSSetSamplers(bindingSlot, 1, &nullSampler);
@@ -525,10 +514,8 @@
if (bindingVisibility & wgpu::ShaderStage::Compute) {
deviceContext->CSSetSamplers(bindingSlot, 1, &nullSampler);
}
- break;
- }
-
- case BindingInfoType::Texture: {
+ },
+ [&](const TextureBindingLayout&) {
ID3D11ShaderResourceView* nullSRV = nullptr;
if (bindingVisibility & wgpu::ShaderStage::Vertex) {
deviceContext->VSSetShaderResources(bindingSlot, 1, &nullSRV);
@@ -539,11 +526,9 @@
if (bindingVisibility & wgpu::ShaderStage::Compute) {
deviceContext->CSSetShaderResources(bindingSlot, 1, &nullSRV);
}
- break;
- }
-
- case BindingInfoType::StorageTexture: {
- switch (bindingInfo.storageTexture.access) {
+ },
+ [&](const StorageTextureBindingLayout& layout) {
+ switch (layout.access) {
case wgpu::StorageTextureAccess::WriteOnly:
case wgpu::StorageTextureAccess::ReadWrite: {
ID3D11UnorderedAccessView* nullUAV = nullptr;
@@ -574,14 +559,7 @@
default:
DAWN_UNREACHABLE();
}
- break;
- }
-
- case BindingInfoType::ExternalTexture: {
- DAWN_UNREACHABLE();
- break;
- }
- }
+ });
}
}
diff --git a/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp b/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
index 84534c6..b0915be 100644
--- a/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
+++ b/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
@@ -28,6 +28,7 @@
#include "dawn/native/d3d11/PipelineLayoutD3D11.h"
#include "dawn/common/BitSetIterator.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/BindGroupLayoutInternal.h"
#include "dawn/native/d3d11/DeviceD3D11.h"
@@ -61,9 +62,10 @@
for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer:
- switch (bindingInfo.buffer.type) {
+ MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout& layout) {
+ switch (layout.type) {
case wgpu::BufferBindingType::Uniform:
mIndexInfo[group][bindingIndex] = constantBufferIndex++;
break;
@@ -78,19 +80,15 @@
case wgpu::BufferBindingType::Undefined:
DAWN_UNREACHABLE();
}
- break;
-
- case BindingInfoType::Sampler:
+ },
+ [&](const SamplerBindingLayout&) {
mIndexInfo[group][bindingIndex] = samplerIndex++;
- break;
-
- case BindingInfoType::Texture:
- case BindingInfoType::ExternalTexture:
+ },
+ [&](const TextureBindingLayout&) {
mIndexInfo[group][bindingIndex] = shaderResourceViewIndex++;
- break;
-
- case BindingInfoType::StorageTexture:
- switch (bindingInfo.storageTexture.access) {
+ },
+ [&](const StorageTextureBindingLayout& layout) {
+ switch (layout.access) {
case wgpu::StorageTextureAccess::ReadWrite:
case wgpu::StorageTextureAccess::WriteOnly:
mIndexInfo[group][bindingIndex] = --unorderedAccessViewIndex;
@@ -102,8 +100,7 @@
case wgpu::StorageTextureAccess::Undefined:
DAWN_UNREACHABLE();
}
- break;
- }
+ });
}
}
mUnusedUAVBindingCount = unorderedAccessViewIndex;
diff --git a/src/dawn/native/d3d12/BindGroupD3D12.cpp b/src/dawn/native/d3d12/BindGroupD3D12.cpp
index 7b27cbd..7298e6b 100644
--- a/src/dawn/native/d3d12/BindGroupD3D12.cpp
+++ b/src/dawn/native/d3d12/BindGroupD3D12.cpp
@@ -30,6 +30,7 @@
#include <utility>
#include "dawn/common/BitSetIterator.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/ExternalTexture.h"
#include "dawn/native/Queue.h"
#include "dawn/native/d3d12/BindGroupLayoutD3D12.h"
@@ -71,8 +72,9 @@
// Increment size does not need to be stored and is only used to get a handle
// local to the allocation with OffsetFrom().
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer: {
+ MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout& layout) {
BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
ID3D12Resource* resource = ToBackend(binding.buffer)->GetD3D12Resource();
@@ -80,10 +82,10 @@
// The Buffer was destroyed. Skip creating buffer views since there is no
// resource. This bind group won't be used as it is an error to submit a
// command buffer that references destroyed resources.
- continue;
+ return;
}
- switch (bindingInfo.buffer.type) {
+ switch (layout.type) {
case wgpu::BufferBindingType::Uniform: {
D3D12_CONSTANT_BUFFER_VIEW_DESC desc;
desc.SizeInBytes =
@@ -141,11 +143,8 @@
case wgpu::BufferBindingType::Undefined:
DAWN_UNREACHABLE();
}
-
- break;
- }
-
- case BindingInfoType::Texture: {
+ },
+ [&](const TextureBindingLayout&) {
auto* view = ToBackend(GetBindingAsTextureView(bindingIndex));
auto& srv = view->GetSRVDescriptor();
@@ -154,17 +153,15 @@
// The Texture was destroyed. Skip creating the SRV since there is no
// resource. This bind group won't be used as it is an error to submit a
// command buffer that references destroyed resources.
- continue;
+ return;
}
d3d12Device->CreateShaderResourceView(
resource, &srv,
viewAllocation.OffsetFrom(viewSizeIncrement,
descriptorHeapOffsets[bindingIndex]));
- break;
- }
-
- case BindingInfoType::StorageTexture: {
+ },
+ [&](const StorageTextureBindingLayout& layout) {
TextureView* view = ToBackend(GetBindingAsTextureView(bindingIndex));
ID3D12Resource* resource = ToBackend(view->GetTexture())->GetD3D12Resource();
@@ -172,10 +169,10 @@
// The Texture was destroyed. Skip creating the SRV/UAV since there is no
// resource. This bind group won't be used as it is an error to submit a
// command buffer that references destroyed resources.
- continue;
+ return;
}
- switch (bindingInfo.storageTexture.access) {
+ switch (layout.access) {
case wgpu::StorageTextureAccess::WriteOnly:
case wgpu::StorageTextureAccess::ReadWrite: {
D3D12_UNORDERED_ACCESS_VIEW_DESC uav = view->GetUAVDescriptor();
@@ -196,19 +193,9 @@
case wgpu::StorageTextureAccess::Undefined:
DAWN_UNREACHABLE();
}
-
- break;
- }
-
- case BindingInfoType::ExternalTexture: {
- DAWN_UNREACHABLE();
- }
-
- case BindingInfoType::Sampler: {
- // No-op as samplers will be later initialized by CreateSamplers().
- break;
- }
- }
+ },
+ // No-op as samplers will be later initialized by CreateSamplers().
+ [](const SamplerBindingLayout&) {});
}
// Loop through the dynamic storage buffers and build a flat map from the index of the
diff --git a/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp b/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
index af67683..ed02fde 100644
--- a/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
+++ b/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
@@ -30,6 +30,7 @@
#include <utility>
#include "dawn/common/BitSetIterator.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
#include "dawn/native/d3d12/SamplerHeapCacheD3D12.h"
#include "dawn/native/d3d12/StagingDescriptorAllocatorD3D12.h"
@@ -37,9 +38,10 @@
namespace dawn::native::d3d12 {
namespace {
D3D12_DESCRIPTOR_RANGE_TYPE WGPUBindingInfoToDescriptorRangeType(const BindingInfo& bindingInfo) {
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer:
- switch (bindingInfo.buffer.type) {
+ return MatchVariant(
+ bindingInfo.bindingLayout,
+ [](const BufferBindingLayout& layout) -> D3D12_DESCRIPTOR_RANGE_TYPE {
+ switch (layout.type) {
case wgpu::BufferBindingType::Uniform:
return D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
case wgpu::BufferBindingType::Storage:
@@ -50,16 +52,15 @@
case wgpu::BufferBindingType::Undefined:
DAWN_UNREACHABLE();
}
-
- case BindingInfoType::Sampler:
+ },
+ [](const SamplerBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
return D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
-
- case BindingInfoType::Texture:
- case BindingInfoType::ExternalTexture:
+ },
+ [](const TextureBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
return D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
-
- case BindingInfoType::StorageTexture:
- switch (bindingInfo.storageTexture.access) {
+ },
+ [](const StorageTextureBindingLayout& layout) -> D3D12_DESCRIPTOR_RANGE_TYPE {
+ switch (layout.access) {
case wgpu::StorageTextureAccess::WriteOnly:
case wgpu::StorageTextureAccess::ReadWrite:
return D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
@@ -68,7 +69,7 @@
case wgpu::StorageTextureAccess::Undefined:
DAWN_UNREACHABLE();
}
- }
+ });
}
} // anonymous namespace
@@ -97,7 +98,8 @@
if (bindingIndex < GetDynamicBufferCount()) {
continue;
}
- DAWN_ASSERT(!bindingInfo.buffer.hasDynamicOffset);
+ DAWN_ASSERT(!std::holds_alternative<BufferBindingLayout>(bindingInfo.bindingLayout) ||
+ !std::get<BufferBindingLayout>(bindingInfo.bindingLayout).hasDynamicOffset);
mDescriptorHeapOffsets[bindingIndex] =
descriptorRangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER
@@ -116,36 +118,32 @@
// the descriptor table is set on a command list (during recording), and the descriptors
// cannot be changed until the command list has finished executing for the last time, so we
// don't need to set DESCRIPTORS_VOLATILE for any binding types.
- switch (bindingInfo.bindingType) {
- // Sampler descriptor ranges don't support DATA_* flags at all since samplers do not
- // point to data.
- case BindingInfoType::Sampler:
- range.Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
- break;
+ range.Flags = MatchVariant(
+ bindingInfo.bindingLayout,
+ [](const SamplerBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
+ // Sampler descriptor ranges don't support DATA_* flags at all since samplers do not
+ // point to data.
+ return D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
+ },
+ [](const BufferBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
+ // In Dawn it's allowed to do state transitions on the buffers or textures after
+ // binding
+ // them on the current command list, which indicates a change to its data (or
+ // possibly resource metadata), so we cannot bind them as DATA_STATIC. We cannot
+ // bind them as DATA_STATIC_WHILE_SET_AT_EXECUTE either because it is required to be
+ // rebound to the command list before the next (this) Draw/Dispatch call, while
+ // currently we may not rebind these resources if the current bind group is not
+ // changed.
+ return D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS |
+ D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE;
+ },
+ [](const TextureBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
+ return D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE;
+ },
+ [](const StorageTextureBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
+ return D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE;
+ });
- // In Dawn it's allowed to do state transitions on the buffers or textures after binding
- // them on the current command list, which indicates a change to its data (or possibly
- // resource metadata), so we cannot bind them as DATA_STATIC.
- // We cannot bind them as DATA_STATIC_WHILE_SET_AT_EXECUTE either because it is required
- // to be rebound to the command list before the next (this) Draw/Dispatch call, while
- // currently we may not rebind these resources if the current bind group is not changed.
- case BindingInfoType::Buffer:
- range.Flags =
- D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS |
- D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE;
- break;
- case BindingInfoType::Texture:
- case BindingInfoType::StorageTexture:
- range.Flags = D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE;
- break;
-
- // ExternalTexture bindings are decayed in the frontend and backends shouldn't need to
- // handle them.
- case BindingInfoType::ExternalTexture:
- default:
- DAWN_UNREACHABLE();
- break;
- }
std::vector<D3D12_DESCRIPTOR_RANGE1>& descriptorRanges =
descriptorRangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER ? mSamplerDescriptorRanges
: mCbvUavSrvDescriptorRanges;
diff --git a/src/dawn/native/d3d12/CommandBufferD3D12.cpp b/src/dawn/native/d3d12/CommandBufferD3D12.cpp
index 0842470..90b329c 100644
--- a/src/dawn/native/d3d12/CommandBufferD3D12.cpp
+++ b/src/dawn/native/d3d12/CommandBufferD3D12.cpp
@@ -524,8 +524,7 @@
D3D12_GPU_VIRTUAL_ADDRESS bufferLocation =
ToBackend(binding.buffer)->GetVA() + offset;
- DAWN_ASSERT(bindingInfo.bindingType == BindingInfoType::Buffer);
- switch (bindingInfo.buffer.type) {
+ switch (std::get<BufferBindingLayout>(bindingInfo.bindingLayout).type) {
case wgpu::BufferBindingType::Uniform:
if (mInCompute) {
commandList->SetComputeRootConstantBufferView(parameterIndex,
diff --git a/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp b/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
index c56e294..7aa0cff 100644
--- a/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
+++ b/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
@@ -249,7 +249,8 @@
mDynamicRootParameterIndices[group][dynamicBindingIndex] = rootParameters.size();
// Set parameter types according to bind group layout descriptor.
- rootParameter.ParameterType = RootParameterType(bindingInfo.buffer.type);
+ rootParameter.ParameterType =
+ RootParameterType(std::get<BufferBindingLayout>(bindingInfo.bindingLayout).type);
// Set visibilities according to bind group layout descriptor.
rootParameter.ShaderVisibility = ShaderVisibilityType(bindingInfo.visibility);
@@ -424,7 +425,9 @@
uint32_t PipelineLayout::GetDynamicRootParameterIndex(BindGroupIndex group,
BindingIndex bindingIndex) const {
DAWN_ASSERT(group < kMaxBindGroupsTyped);
- DAWN_ASSERT(GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).buffer.hasDynamicOffset);
+ DAWN_ASSERT(std::get<BufferBindingLayout>(
+ GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).bindingLayout)
+ .hasDynamicOffset);
DAWN_ASSERT(GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).visibility !=
wgpu::ShaderStage::None);
return mDynamicRootParameterIndices[group][bindingIndex];
diff --git a/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp b/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp
index 0351bbc..da7d4e2 100644
--- a/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp
+++ b/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp
@@ -120,7 +120,7 @@
for (BindingIndex bindingIndex = bgl->GetDynamicBufferCount();
bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
- if (bindingInfo.bindingType == BindingInfoType::Sampler) {
+ if (std::holds_alternative<SamplerBindingLayout>(bindingInfo.bindingLayout)) {
samplers.push_back(ToBackend(group->GetBindingAsSampler(bindingIndex)));
}
}
diff --git a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
index 6bf7ba7..431efd2 100644
--- a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
+++ b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
@@ -211,15 +211,17 @@
continue;
}
+ const auto& bindingLayout =
+ std::get<BufferBindingLayout>(bgl->GetBindingInfo(bindingIndex).bindingLayout);
+
// Declaring a read-only storage buffer in HLSL but specifying a storage
// buffer in the BGL produces the wrong output. Force read-only storage
// buffer bindings to be treated as UAV instead of SRV. Internal storage
// buffer is a storage buffer used in the internal pipeline.
const bool forceStorageBufferAsUAV =
(bufferBindingInfo->type == wgpu::BufferBindingType::ReadOnlyStorage &&
- (bgl->GetBindingInfo(bindingIndex).buffer.type ==
- wgpu::BufferBindingType::Storage ||
- bgl->GetBindingInfo(bindingIndex).buffer.type == kInternalStorageBufferBinding));
+ (bindingLayout.type == wgpu::BufferBindingType::Storage ||
+ bindingLayout.type == kInternalStorageBufferBinding));
if (forceStorageBufferAsUAV) {
accessControls.emplace(srcBindingPoint, tint::core::Access::kReadWrite);
}
@@ -250,7 +252,7 @@
// }
if ((bufferBindingInfo->type == wgpu::BufferBindingType::Storage ||
bufferBindingInfo->type == wgpu::BufferBindingType::ReadOnlyStorage) &&
- !bgl->GetBindingInfo(bindingIndex).buffer.hasDynamicOffset) {
+ !bindingLayout.hasDynamicOffset) {
req.hlsl.tintOptions.binding_points_ignored_in_robustness_transform.emplace_back(
srcBindingPoint);
}
diff --git a/src/dawn/native/metal/CommandBufferMTL.mm b/src/dawn/native/metal/CommandBufferMTL.mm
index d4da77f..ce703a7 100644
--- a/src/dawn/native/metal/CommandBufferMTL.mm
+++ b/src/dawn/native/metal/CommandBufferMTL.mm
@@ -27,6 +27,7 @@
#include "dawn/native/metal/CommandBufferMTL.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/BindGroupTracker.h"
#include "dawn/native/CommandEncoder.h"
#include "dawn/native/Commands.h"
@@ -570,8 +571,9 @@
SingleShaderStage::Compute)[index][bindingIndex];
}
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer: {
+ MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout& layout) {
const BufferBinding& binding = group->GetBindingAsBufferBinding(bindingIndex);
ToBackend(binding.buffer)->TrackUsage();
const id<MTLBuffer> buffer = ToBackend(binding.buffer)->GetMTLBuffer();
@@ -579,7 +581,7 @@
// TODO(crbug.com/dawn/854): Record bound buffer status to use
// setBufferOffset to achieve better performance.
- if (bindingInfo.buffer.hasDynamicOffset) {
+ if (layout.hasDynamicOffset) {
// Dynamic buffers are packed at the front of BindingIndices.
offset += dynamicOffsets[bindingIndex];
}
@@ -606,11 +608,8 @@
offsets:&offset
withRange:NSMakeRange(computeIndex, 1)];
}
-
- break;
- }
-
- case BindingInfoType::Sampler: {
+ },
+ [&](const SamplerBindingLayout&) {
auto sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
if (hasVertStage) {
[render setVertexSamplerState:sampler->GetMTLSamplerState()
@@ -624,11 +623,8 @@
[compute setSamplerState:sampler->GetMTLSamplerState()
atIndex:computeIndex];
}
- break;
- }
-
- case BindingInfoType::Texture:
- case BindingInfoType::StorageTexture: {
+ },
+ [&](const TextureBindingLayout&) {
auto textureView = ToBackend(group->GetBindingAsTextureView(bindingIndex));
if (hasVertStage) {
[render setVertexTexture:textureView->GetMTLTexture() atIndex:vertIndex];
@@ -639,12 +635,19 @@
if (hasComputeStage) {
[compute setTexture:textureView->GetMTLTexture() atIndex:computeIndex];
}
- break;
- }
-
- case BindingInfoType::ExternalTexture:
- DAWN_UNREACHABLE();
- }
+ },
+ [&](const StorageTextureBindingLayout&) {
+ auto textureView = ToBackend(group->GetBindingAsTextureView(bindingIndex));
+ if (hasVertStage) {
+ [render setVertexTexture:textureView->GetMTLTexture() atIndex:vertIndex];
+ }
+ if (hasFragStage) {
+ [render setFragmentTexture:textureView->GetMTLTexture() atIndex:fragIndex];
+ }
+ if (hasComputeStage) {
+ [compute setTexture:textureView->GetMTLTexture() atIndex:computeIndex];
+ }
+ });
}
}
diff --git a/src/dawn/native/metal/PipelineLayoutMTL.mm b/src/dawn/native/metal/PipelineLayoutMTL.mm
index ab78922..6bfc9dd 100644
--- a/src/dawn/native/metal/PipelineLayoutMTL.mm
+++ b/src/dawn/native/metal/PipelineLayoutMTL.mm
@@ -28,6 +28,7 @@
#include "dawn/native/metal/PipelineLayoutMTL.h"
#include "dawn/common/BitSetIterator.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/BindGroupLayoutInternal.h"
#include "dawn/native/metal/DeviceMTL.h"
@@ -60,24 +61,24 @@
continue;
}
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer:
+ MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout&) {
mIndexInfo[stage][group][bindingIndex] = bufferIndex;
bufferIndex++;
- break;
-
- case BindingInfoType::Sampler:
+ },
+ [&](const SamplerBindingLayout&) {
mIndexInfo[stage][group][bindingIndex] = samplerIndex;
samplerIndex++;
- break;
-
- case BindingInfoType::Texture:
- case BindingInfoType::StorageTexture:
- case BindingInfoType::ExternalTexture:
+ },
+ [&](const TextureBindingLayout&) {
mIndexInfo[stage][group][bindingIndex] = textureIndex;
textureIndex++;
- break;
- }
+ },
+ [&](const StorageTextureBindingLayout&) {
+ mIndexInfo[stage][group][bindingIndex] = textureIndex;
+ textureIndex++;
+ });
}
}
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index 578c13b..d4aa7aa 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -32,6 +32,7 @@
#include <utility>
#include <vector>
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/BindGroup.h"
#include "dawn/native/BindGroupTracker.h"
#include "dawn/native/CommandEncoder.h"
@@ -269,7 +270,7 @@
++bindingIndex) {
const BindingInfo& bindingInfo = group->GetLayout()->GetBindingInfo(bindingIndex);
- if (bindingInfo.bindingType == BindingInfoType::Texture) {
+ if (std::holds_alternative<TextureBindingLayout>(bindingInfo.bindingLayout)) {
TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
view->CopyIfNeeded();
}
@@ -278,21 +279,21 @@
for (BindingIndex bindingIndex{0}; bindingIndex < group->GetLayout()->GetBindingCount();
++bindingIndex) {
const BindingInfo& bindingInfo = group->GetLayout()->GetBindingInfo(bindingIndex);
-
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer: {
+ MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout& layout) {
BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
GLuint buffer = ToBackend(binding.buffer)->GetHandle();
GLuint index = indices[bindingIndex];
GLuint offset = binding.offset;
- if (bindingInfo.buffer.hasDynamicOffset) {
+ if (layout.hasDynamicOffset) {
// Dynamic buffers are packed at the front of BindingIndices.
offset += dynamicOffsets[bindingIndex];
}
GLenum target;
- switch (bindingInfo.buffer.type) {
+ switch (layout.type) {
case wgpu::BufferBindingType::Uniform:
target = GL_UNIFORM_BUFFER;
break;
@@ -306,10 +307,8 @@
}
gl.BindBufferRange(target, index, buffer, offset, binding.size);
- break;
- }
-
- case BindingInfoType::Sampler: {
+ },
+ [&](const SamplerBindingLayout&) {
Sampler* sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
GLuint samplerIndex = indices[bindingIndex];
@@ -323,10 +322,8 @@
gl.BindSampler(unit.unit, sampler->GetNonFilteringHandle());
}
}
- break;
- }
-
- case BindingInfoType::Texture: {
+ },
+ [&](const TextureBindingLayout&) {
TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
GLuint handle = view->GetHandle();
GLenum target = view->GetGLTarget();
@@ -365,18 +362,15 @@
// Some texture builtin function data needs emulation to update into the
// internal uniform buffer.
UpdateTextureBuiltinsUniformData(gl, view, groupIndex, bindingIndex);
-
- break;
- }
-
- case BindingInfoType::StorageTexture: {
+ },
+ [&](const StorageTextureBindingLayout& layout) {
TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
Texture* texture = ToBackend(view->GetTexture());
GLuint handle = texture->GetHandle();
GLuint imageIndex = indices[bindingIndex];
GLenum access;
- switch (bindingInfo.storageTexture.access) {
+ switch (layout.access) {
case wgpu::StorageTextureAccess::WriteOnly:
access = GL_WRITE_ONLY;
break;
@@ -405,13 +399,7 @@
view->GetBaseArrayLayer(), access,
texture->GetGLFormat().internalFormat);
texture->Touch();
- break;
- }
-
- case BindingInfoType::ExternalTexture:
- DAWN_UNREACHABLE();
- break;
- }
+ });
}
}
diff --git a/src/dawn/native/opengl/PipelineGL.cpp b/src/dawn/native/opengl/PipelineGL.cpp
index f59c41e..6c5d12b 100644
--- a/src/dawn/native/opengl/PipelineGL.cpp
+++ b/src/dawn/native/opengl/PipelineGL.cpp
@@ -147,7 +147,8 @@
GLuint textureIndex = indices[combined.textureLocation.group][bindingIndex];
mUnitsForTextures[textureIndex].push_back(textureUnit);
- shouldUseFiltering = bgl->GetBindingInfo(bindingIndex).texture.sampleType ==
+ const auto& bindingLayout = bgl->GetBindingInfo(bindingIndex).bindingLayout;
+ shouldUseFiltering = std::get<TextureBindingLayout>(bindingLayout).sampleType ==
wgpu::TextureSampleType::Float;
}
{
diff --git a/src/dawn/native/opengl/PipelineLayoutGL.cpp b/src/dawn/native/opengl/PipelineLayoutGL.cpp
index 57bcf00..4b44aa6 100644
--- a/src/dawn/native/opengl/PipelineLayoutGL.cpp
+++ b/src/dawn/native/opengl/PipelineLayoutGL.cpp
@@ -28,6 +28,7 @@
#include "dawn/native/opengl/PipelineLayoutGL.h"
#include "dawn/common/BitSetIterator.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/BindGroupLayoutInternal.h"
#include "dawn/native/opengl/DeviceGL.h"
@@ -48,9 +49,10 @@
for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer:
- switch (bindingInfo.buffer.type) {
+ MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout& layout) {
+ switch (layout.type) {
case wgpu::BufferBindingType::Uniform:
mIndexInfo[group][bindingIndex] = uboIndex;
uboIndex++;
@@ -64,24 +66,19 @@
case wgpu::BufferBindingType::Undefined:
DAWN_UNREACHABLE();
}
- break;
-
- case BindingInfoType::Sampler:
+ },
+ [&](const SamplerBindingLayout&) {
mIndexInfo[group][bindingIndex] = samplerIndex;
samplerIndex++;
- break;
-
- case BindingInfoType::Texture:
- case BindingInfoType::ExternalTexture:
+ },
+ [&](const TextureBindingLayout&) {
mIndexInfo[group][bindingIndex] = sampledTextureIndex;
sampledTextureIndex++;
- break;
-
- case BindingInfoType::StorageTexture:
+ },
+ [&](const StorageTextureBindingLayout&) {
mIndexInfo[group][bindingIndex] = storageTextureIndex;
storageTextureIndex++;
- break;
- }
+ });
}
}
diff --git a/src/dawn/native/vulkan/BindGroupLayoutVk.cpp b/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
index 0a79620..3f78a37 100644
--- a/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
+++ b/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
@@ -31,6 +31,7 @@
#include "absl/container/flat_hash_map.h"
#include "dawn/common/BitSetIterator.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/common/ityp_vector.h"
#include "dawn/native/CacheKey.h"
#include "dawn/native/vulkan/DescriptorSetAllocator.h"
@@ -62,33 +63,30 @@
} // anonymous namespace
VkDescriptorType VulkanDescriptorType(const BindingInfo& bindingInfo) {
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer:
- switch (bindingInfo.buffer.type) {
+ return MatchVariant(
+ bindingInfo.bindingLayout,
+ [](const BufferBindingLayout& layout) -> VkDescriptorType {
+ switch (layout.type) {
case wgpu::BufferBindingType::Uniform:
- if (bindingInfo.buffer.hasDynamicOffset) {
+ if (layout.hasDynamicOffset) {
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
}
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case wgpu::BufferBindingType::Storage:
case kInternalStorageBufferBinding:
case wgpu::BufferBindingType::ReadOnlyStorage:
- if (bindingInfo.buffer.hasDynamicOffset) {
+ if (layout.hasDynamicOffset) {
return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
}
return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
case wgpu::BufferBindingType::Undefined:
DAWN_UNREACHABLE();
+ return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
}
- case BindingInfoType::Sampler:
- return VK_DESCRIPTOR_TYPE_SAMPLER;
- case BindingInfoType::Texture:
- case BindingInfoType::ExternalTexture:
- return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
- case BindingInfoType::StorageTexture:
- return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
- }
- DAWN_UNREACHABLE();
+ },
+ [](const SamplerBindingLayout&) { return VK_DESCRIPTOR_TYPE_SAMPLER; },
+ [](const TextureBindingLayout&) { return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; },
+ [](const StorageTextureBindingLayout&) { return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; });
}
// static
diff --git a/src/dawn/native/vulkan/BindGroupVk.cpp b/src/dawn/native/vulkan/BindGroupVk.cpp
index c619e88..fa40523 100644
--- a/src/dawn/native/vulkan/BindGroupVk.cpp
+++ b/src/dawn/native/vulkan/BindGroupVk.cpp
@@ -28,6 +28,7 @@
#include "dawn/native/vulkan/BindGroupVk.h"
#include "dawn/common/BitSetIterator.h"
+#include "dawn/common/MatchVariant.h"
#include "dawn/common/ityp_stack_vec.h"
#include "dawn/native/ExternalTexture.h"
#include "dawn/native/vulkan/BindGroupLayoutVk.h"
@@ -63,7 +64,10 @@
bindingCount);
uint32_t numWrites = 0;
- for (const auto [_, bindingIndex] : GetLayout()->GetBindingMap()) {
+ for (const auto& bindingItem : GetLayout()->GetBindingMap()) {
+ // We cannot use structured binding here because lambda expressions can only capture
+ // variables, while structured binding doesn't introduce variables.
+ BindingIndex bindingIndex = bindingItem.second;
const BindingInfo& bindingInfo = GetLayout()->GetBindingInfo(bindingIndex);
auto& write = writes[numWrites];
@@ -75,8 +79,9 @@
write.descriptorCount = 1;
write.descriptorType = VulkanDescriptorType(bindingInfo);
- switch (bindingInfo.bindingType) {
- case BindingInfoType::Buffer: {
+ bool isValidDescriptorSet = MatchVariant(
+ bindingInfo.bindingLayout,
+ [&](const BufferBindingLayout&) -> bool {
BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
VkBuffer handle = ToBackend(binding.buffer)->GetHandle();
@@ -85,23 +90,21 @@
// a Vulkan Validation Layers error. This bind group won't be used as it
// is an error to submit a command buffer that references destroyed
// resources.
- continue;
+ return false;
}
writeBufferInfo[numWrites].buffer = handle;
writeBufferInfo[numWrites].offset = binding.offset;
writeBufferInfo[numWrites].range = binding.size;
write.pBufferInfo = &writeBufferInfo[numWrites];
- break;
- }
-
- case BindingInfoType::Sampler: {
+ return true;
+ },
+ [&](const SamplerBindingLayout&) -> bool {
Sampler* sampler = ToBackend(GetBindingAsSampler(bindingIndex));
writeImageInfo[numWrites].sampler = sampler->GetHandle();
write.pImageInfo = &writeImageInfo[numWrites];
- break;
- }
-
- case BindingInfoType::Texture: {
+ return true;
+ },
+ [&](const TextureBindingLayout&) -> bool {
TextureView* view = ToBackend(GetBindingAsTextureView(bindingIndex));
VkImageView handle = view->GetHandle();
@@ -111,17 +114,16 @@
// a Vulkan Validation Layers error. This bind group won't be used as it
// is an error to submit a command buffer that references destroyed
// resources.
- continue;
+ return false;
}
writeImageInfo[numWrites].imageView = handle;
writeImageInfo[numWrites].imageLayout = VulkanImageLayout(
view->GetTexture()->GetFormat(), wgpu::TextureUsage::TextureBinding);
write.pImageInfo = &writeImageInfo[numWrites];
- break;
- }
-
- case BindingInfoType::StorageTexture: {
+ return true;
+ },
+ [&](const StorageTextureBindingLayout&) -> bool {
TextureView* view = ToBackend(GetBindingAsTextureView(bindingIndex));
VkImageView handle = VK_NULL_HANDLE;
@@ -136,21 +138,18 @@
// a Vulkan Validation Layers error. This bind group won't be used as it
// is an error to submit a command buffer that references destroyed
// resources.
- continue;
+ return false;
}
writeImageInfo[numWrites].imageView = handle;
writeImageInfo[numWrites].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
write.pImageInfo = &writeImageInfo[numWrites];
- break;
- }
+ return true;
+ });
- case BindingInfoType::ExternalTexture:
- DAWN_UNREACHABLE();
- break;
+ if (isValidDescriptorSet) {
+ numWrites++;
}
-
- numWrites++;
}
// TODO(crbug.com/dawn/855): Batch these updates
diff --git a/src/dawn/native/webgpu_absl_format.cpp b/src/dawn/native/webgpu_absl_format.cpp
index 68f5cf1..95e2cc3 100644
--- a/src/dawn/native/webgpu_absl_format.cpp
+++ b/src/dawn/native/webgpu_absl_format.cpp
@@ -30,6 +30,7 @@
#include <string>
#include <vector>
+#include "dawn/common/MatchVariant.h"
#include "dawn/native/AttachmentState.h"
#include "dawn/native/BindingInfo.h"
#include "dawn/native/Device.h"
@@ -115,26 +116,24 @@
absl::FormatSink* s) {
static const auto* const fmt =
new absl::ParsedFormat<'u', 's', 's', 's'>("{ binding: %u, visibility: %s, %s: %s }");
- switch (value.bindingType) {
- case BindingInfoType::Buffer:
+ MatchVariant(
+ value.bindingLayout,
+ [&](const BufferBindingLayout& layout) {
s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
- value.bindingType, value.buffer));
- break;
- case BindingInfoType::Sampler:
+ BindingInfoType::Buffer, layout));
+ },
+ [&](const SamplerBindingLayout& layout) {
s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
- value.bindingType, value.sampler));
- break;
- case BindingInfoType::Texture:
+ BindingInfoType::Sampler, layout));
+ },
+ [&](const TextureBindingLayout& layout) {
s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
- value.bindingType, value.texture));
- break;
- case BindingInfoType::StorageTexture:
+ BindingInfoType::Texture, layout));
+ },
+ [&](const StorageTextureBindingLayout& layout) {
s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
- value.bindingType, value.storageTexture));
- break;
- case BindingInfoType::ExternalTexture:
- break;
- }
+ BindingInfoType::StorageTexture, layout));
+ });
return {true};
}