[Static samplers] Pivot to having StaticSamplerBindingLayout
This CL moves static samplers away from being specified via a chained
struct on SamplerLayoutBinding to a chained struct on
BindGroupLayoutEntry, similarly to ExternalTextureBindingLayout. This
organization avoids redundantly specifying the sampler type and makes
the conceptual relationships more clear: a SamplerLayoutBinding is for
a sampler supplied dynamically, whereas the StaticSamplerBindingLayout
is for samplers supplied statically.
As a bonus, this new code organization directly points the way to a
couple next steps that need to happen:
* Incorporation of validation of the number of static samplers
* Populating BindingInfo with the static sampler's sampler object
This CL leaves TODOs for those next steps.
Bug: dawn:2463
Change-Id: I9974b5678051ea38ebab57e801affc474d13938b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/181042
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Colin Blundell <blundell@chromium.org>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 64491b3..9edf18c 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -375,10 +375,10 @@
{"name": "type", "type": "sampler binding type", "default": "undefined"}
]
},
- "static sampler": {
+ "static sampler binding layout": {
"category": "structure",
"chained": "in",
- "chain roots": ["sampler binding layout"],
+ "chain roots": ["bind group layout entry"],
"tags": ["dawn"],
"members": [
{"name": "sampler", "type": "sampler"}
@@ -3689,7 +3689,7 @@
{"value": 1212, "name": "shared fence MTL shared event descriptor", "tags": ["dawn", "native"]},
{"value": 1213, "name": "shared fence MTL shared event export info", "tags": ["dawn", "native"]},
{"value": 1214, "name": "shared buffer memory D3D12 resource descriptor", "tags": ["dawn", "native"]},
- {"value": 1215, "name": "static sampler", "tags": ["dawn"]}
+ {"value": 1215, "name": "static sampler binding layout", "tags": ["dawn"]}
]
},
"texture": {
diff --git a/src/dawn/native/BindGroupLayoutInternal.cpp b/src/dawn/native/BindGroupLayoutInternal.cpp
index 46fc853..0755617 100644
--- a/src/dawn/native/BindGroupLayoutInternal.cpp
+++ b/src/dawn/native/BindGroupLayoutInternal.cpp
@@ -45,7 +45,6 @@
#include "dawn/native/ObjectContentHasher.h"
#include "dawn/native/ObjectType_autogen.h"
#include "dawn/native/PerStage.h"
-#include "dawn/native/PhysicalDevice.h"
#include "dawn/native/Sampler.h"
#include "dawn/native/ValidationUtils_autogen.h"
@@ -122,21 +121,6 @@
if (entry->sampler.type != wgpu::SamplerBindingType::Undefined) {
bindingMemberCount++;
DAWN_TRY(ValidateSamplerBindingType(entry->sampler.type));
-
- UnpackedPtr<SamplerBindingLayout> samplerLayout;
- DAWN_TRY_ASSIGN(samplerLayout, ValidateAndUnpack(&entry->sampler));
-
- auto staticSampler = samplerLayout.Get<StaticSampler>();
- if (staticSampler) {
- DAWN_INVALID_IF(!device->HasFeature(Feature::StaticSamplers),
- "Static samplers used without the %s feature enabled.",
- device->GetPhysicalDevice()
- ->GetInstance()
- ->GetFeatureInfo(ToAPI(Feature::StaticSamplers))
- ->name);
-
- DAWN_TRY(device->ValidateObject(staticSampler->sampler));
- }
}
if (entry->texture.sampleType != wgpu::TextureSampleType::Undefined) {
@@ -201,6 +185,16 @@
}
}
+ if (auto* staticSamplerBindingLayout = entry.Get<StaticSamplerBindingLayout>()) {
+ bindingMemberCount++;
+
+ DAWN_INVALID_IF(!device->HasFeature(Feature::StaticSamplers),
+ "Static samplers used without the %s feature enabled.",
+ wgpu::FeatureName::StaticSamplers);
+
+ DAWN_TRY(device->ValidateObject(staticSamplerBindingLayout->sampler));
+ }
+
if (auto* externalTextureBindingLayout = entry.Get<ExternalTextureBindingLayout>()) {
bindingMemberCount++;
}
@@ -410,6 +404,8 @@
bindingLayout.viewDimension = wgpu::TextureViewDimension::e2D;
}
bindingInfo.bindingLayout = bindingLayout;
+ } else if (auto* staticSamplerBindingLayout = binding.Get<StaticSamplerBindingLayout>()) {
+ // TODO(crbug.com/dawn/2463): Populate BindingInfo for this entry.
} else {
DAWN_UNREACHABLE();
}
diff --git a/src/dawn/native/BindingInfo.cpp b/src/dawn/native/BindingInfo.cpp
index ae8f3e6..879104e 100644
--- a/src/dawn/native/BindingInfo.cpp
+++ b/src/dawn/native/BindingInfo.cpp
@@ -86,10 +86,10 @@
perStageBindingCountMember = &PerStageBindingCounts::sampledTextureCount;
} else if (entry->storageTexture.access != wgpu::StorageTextureAccess::Undefined) {
perStageBindingCountMember = &PerStageBindingCounts::storageTextureCount;
- } else {
- if (auto* externalTextureBindingLayout = entry.Get<ExternalTextureBindingLayout>()) {
- perStageBindingCountMember = &PerStageBindingCounts::externalTextureCount;
- }
+ } else if (auto* externalTextureBindingLayout = entry.Get<ExternalTextureBindingLayout>()) {
+ perStageBindingCountMember = &PerStageBindingCounts::externalTextureCount;
+ } else if (auto* staticSamplerBindingLayout = entry.Get<StaticSamplerBindingLayout>()) {
+ perStageBindingCountMember = &PerStageBindingCounts::staticSamplerCount;
}
DAWN_ASSERT(perStageBindingCountMember != nullptr);
@@ -115,6 +115,7 @@
bindingCounts->perStage[stage].uniformBufferCount += rhs.perStage[stage].uniformBufferCount;
bindingCounts->perStage[stage].externalTextureCount +=
rhs.perStage[stage].externalTextureCount;
+ bindingCounts->perStage[stage].staticSamplerCount += rhs.perStage[stage].staticSamplerCount;
}
}
@@ -164,12 +165,14 @@
bindingCounts.perStage[stage].externalTextureCount, stage,
limits.v1.maxSampledTexturesPerShaderStage);
+ // TODO(crbug.com/dawn/2463): Account for static samplers here.
DAWN_INVALID_IF(
bindingCounts.perStage[stage].samplerCount > limits.v1.maxSamplersPerShaderStage,
"The number of samplers (%u) in the %s stage exceeds the maximum per-stage limit "
"(%u).",
bindingCounts.perStage[stage].samplerCount, stage, limits.v1.maxSamplersPerShaderStage);
+ // TODO(crbug.com/dawn/2463): Account for static samplers here.
DAWN_INVALID_IF(
bindingCounts.perStage[stage].samplerCount +
(bindingCounts.perStage[stage].externalTextureCount *
diff --git a/src/dawn/native/BindingInfo.h b/src/dawn/native/BindingInfo.h
index 16970f6..1eba544 100644
--- a/src/dawn/native/BindingInfo.h
+++ b/src/dawn/native/BindingInfo.h
@@ -83,6 +83,7 @@
uint32_t storageTextureCount;
uint32_t uniformBufferCount;
uint32_t externalTextureCount;
+ uint32_t staticSamplerCount;
};
struct BindingCounts {
diff --git a/src/dawn/tests/unittests/validation/BindGroupValidationTests.cpp b/src/dawn/tests/unittests/validation/BindGroupValidationTests.cpp
index 64e01f3..c856614 100644
--- a/src/dawn/tests/unittests/validation/BindGroupValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/BindGroupValidationTests.cpp
@@ -1753,31 +1753,14 @@
});
}
-// Tests that chaining an arbitrary struct onto a sampler binding layout raises
-// an error.
-TEST_F(BindGroupLayoutValidationTest, SamplerBindingLayoutInvalidChainedStruct) {
- wgpu::BindGroupLayoutEntry binding = {};
- binding.binding = 0;
- binding.sampler.type = wgpu::SamplerBindingType::Filtering;
- wgpu::ExternalTextureBindingLayout invalidChainedStruct = {};
- binding.sampler.nextInChain = &invalidChainedStruct;
-
- wgpu::BindGroupLayoutDescriptor desc = {};
- desc.entryCount = 1;
- desc.entries = &binding;
-
- ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
-}
-
// Tests that creating a bind group layout with a valid static sampler raises an error
// if the required feature is not enabled.
TEST_F(BindGroupLayoutValidationTest, StaticSamplerNotSupportedWithoutFeatureEnabled) {
wgpu::BindGroupLayoutEntry binding = {};
binding.binding = 0;
- binding.sampler.type = wgpu::SamplerBindingType::Filtering;
- wgpu::StaticSampler staticSampler = {};
- staticSampler.sampler = device.CreateSampler();
- binding.sampler.nextInChain = &staticSampler;
+ wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
+ staticSamplerBinding.sampler = device.CreateSampler();
+ binding.nextInChain = &staticSamplerBinding;
wgpu::BindGroupLayoutDescriptor desc = {};
desc.entryCount = 1;
@@ -1801,10 +1784,9 @@
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest, StaticSamplerSupportedWhenFeatureEnabled) {
wgpu::BindGroupLayoutEntry binding = {};
binding.binding = 0;
- binding.sampler.type = wgpu::SamplerBindingType::Filtering;
- wgpu::StaticSampler staticSampler = {};
- staticSampler.sampler = device.CreateSampler();
- binding.sampler.nextInChain = &staticSampler;
+ wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
+ staticSamplerBinding.sampler = device.CreateSampler();
+ binding.nextInChain = &staticSamplerBinding;
wgpu::BindGroupLayoutDescriptor desc = {};
desc.entryCount = 1;
@@ -1818,8 +1800,7 @@
TEST_F(BindGroupLayoutWithStaticSamplersValidationTest, StaticSamplerWithInvalidSamplerObject) {
wgpu::BindGroupLayoutEntry binding = {};
binding.binding = 0;
- binding.sampler.type = wgpu::SamplerBindingType::Filtering;
- wgpu::StaticSampler staticSampler = {};
+ wgpu::StaticSamplerBindingLayout staticSamplerBinding = {};
wgpu::SamplerDescriptor samplerDesc;
samplerDesc.minFilter = static_cast<wgpu::FilterMode>(0xFFFFFFFF);
@@ -1827,8 +1808,8 @@
wgpu::Sampler errorSampler;
ASSERT_DEVICE_ERROR(errorSampler = device.CreateSampler(&samplerDesc));
- staticSampler.sampler = errorSampler;
- binding.sampler.nextInChain = &staticSampler;
+ staticSamplerBinding.sampler = errorSampler;
+ binding.nextInChain = &staticSamplerBinding;
wgpu::BindGroupLayoutDescriptor desc = {};
desc.entryCount = 1;