Implement maxBindingsPerBindGroup limit

Bug: dawn:1523
Change-Id: Ifcf83f6836a5d7ed447080ccb033e4163970432e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/100706
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Brandon Jones <bajones@chromium.org>
This commit is contained in:
Brandon Jones 2022-08-31 17:01:58 +00:00 committed by Dawn LUCI CQ
parent 1862e83510
commit 4d67a883b6
9 changed files with 24 additions and 24 deletions

View File

@ -1250,6 +1250,7 @@
{"name": "max texture dimension 3D", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
{"name": "max texture array layers", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
{"name": "max bind groups", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
{"name": "max bindings per bind group", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
{"name": "max dynamic uniform buffers per pipeline layout", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
{"name": "max dynamic storage buffers per pipeline layout", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
{"name": "max sampled textures per shader stage", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},

View File

@ -18,6 +18,7 @@
#include <cstdint>
static constexpr uint32_t kMaxBindGroups = 4u;
static constexpr uint32_t kMaxBindingsPerBindGroup = 640u;
static constexpr uint8_t kMaxVertexAttributes = 16u;
static constexpr uint8_t kMaxVertexBuffers = 8u;
static constexpr uint32_t kMaxVertexBufferArrayStride = 2048u;
@ -62,7 +63,4 @@ static constexpr uint8_t kSampledTexturesPerExternalTexture = 4u;
static constexpr uint8_t kSamplersPerExternalTexture = 1u;
static constexpr uint8_t kUniformsPerExternalTexture = 1u;
// A spec defined constant but that doesn't have a name.
static constexpr uint32_t kMaxBindingNumber = 65535;
#endif // SRC_DAWN_COMMON_CONSTANTS_H_

View File

@ -183,8 +183,8 @@ std::vector<BindGroupLayoutEntry> ExtractAndExpandBglEntries(
std::vector<BindGroupLayoutEntry> expandedOutput;
// When new bgl entries are created, we use binding numbers larger than
// kMaxBindingNumber to ensure there are no collisions.
uint32_t nextOpenBindingNumberForNewEntry = kMaxBindingNumber + 1;
// kMaxBindingsPerBindGroup to ensure there are no collisions.
uint32_t nextOpenBindingNumberForNewEntry = kMaxBindingsPerBindGroup;
for (uint32_t i = 0; i < descriptor->entryCount; i++) {
const BindGroupLayoutEntry& entry = descriptor->entries[i];
const ExternalTextureBindingLayout* externalTextureBindingLayout = nullptr;
@ -250,9 +250,9 @@ MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase* device,
const BindGroupLayoutEntry& entry = descriptor->entries[i];
BindingNumber bindingNumber = BindingNumber(entry.binding);
DAWN_INVALID_IF(bindingNumber > kMaxBindingNumberTyped,
"Binding number (%u) exceeds the maximum binding number (%u).",
uint32_t(bindingNumber), uint32_t(kMaxBindingNumberTyped));
DAWN_INVALID_IF(bindingNumber >= kMaxBindingsPerBindGroupTyped,
"Binding number (%u) exceeds the maxBindingsPerBindGroup limit (%u).",
uint32_t(bindingNumber), kMaxBindingsPerBindGroup);
DAWN_INVALID_IF(bindingsSet.count(bindingNumber) != 0,
"On entries[%u]: binding index (%u) was specified by a previous entry.", i,
entry.binding);

View File

@ -23,7 +23,7 @@
namespace dawn::native {
// Binding numbers in the shader and BindGroup/BindGroupLayoutDescriptors
using BindingNumber = TypedInteger<struct BindingNumberT, uint32_t>;
constexpr BindingNumber kMaxBindingNumberTyped = BindingNumber(kMaxBindingNumber);
constexpr BindingNumber kMaxBindingsPerBindGroupTyped = BindingNumber(kMaxBindingsPerBindGroup);
// Binding numbers get mapped to a packed range of indices
using BindingIndex = TypedInteger<struct BindingIndexT, uint32_t>;

View File

@ -37,6 +37,7 @@
X(Maximum, maxTextureDimension3D, 2048, 2048) \
X(Maximum, maxTextureArrayLayers, 256, 256) \
X(Maximum, maxBindGroups, 4, 4) \
X(Maximum, maxBindingsPerBindGroup, 640, 640) \
X(Maximum, maxDynamicUniformBuffersPerPipelineLayout, 8, 8) \
X(Maximum, maxDynamicStorageBuffersPerPipelineLayout, 4, 4) \
X(Maximum, maxSampledTexturesPerShaderStage, 16, 16) \

View File

@ -792,9 +792,9 @@ ResultOrError<std::unique_ptr<EntryPointMetadata>> ReflectEntryPointUsingTint(
"The entry-point uses a binding with a group decoration (%u) "
"that exceeds the maximum (%u).",
resource.bind_group, kMaxBindGroups) ||
DelayedInvalidIf(bindingNumber > kMaxBindingNumberTyped,
"Binding number (%u) exceeds the maximum binding number (%u).",
uint32_t(bindingNumber), uint32_t(kMaxBindingNumberTyped))) {
DelayedInvalidIf(bindingNumber >= kMaxBindingsPerBindGroupTyped,
"Binding number (%u) exceeds the maxBindingsPerBindGroup limit (%u).",
uint32_t(bindingNumber), kMaxBindingsPerBindGroup)) {
continue;
}

View File

@ -1254,7 +1254,7 @@ TEST_P(BindGroupTests, ArbitraryBindingNumbers) {
color : vec4<f32>
}
@group(0) @binding(953) var <uniform> ubo1 : Ubo;
@group(0) @binding(553) var <uniform> ubo1 : Ubo;
@group(0) @binding(47) var <uniform> ubo2 : Ubo;
@group(0) @binding(111) var <uniform> ubo3 : Ubo;
@ -1295,7 +1295,7 @@ TEST_P(BindGroupTests, ArbitraryBindingNumbers) {
};
utils::BindingInitializationHelper bindings[] = {
{953, color1, 0, 4 * sizeof(float)}, //
{553, color1, 0, 4 * sizeof(float)}, //
{47, color2, 0, 4 * sizeof(float)}, //
{111, color3, 0, 4 * sizeof(float)}, //
};

View File

@ -1017,14 +1017,14 @@ TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutStorageBindingsInVertexShad
// Tests setting that bind group layout bindings numbers may be very large.
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutEntryMax) {
// Check that up to kMaxBindingNumber is valid.
utils::MakeBindGroupLayout(
device, {{kMaxBindingNumber, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform}});
// Check that up to kMaxBindingsPerBindGroup-1 is valid.
utils::MakeBindGroupLayout(device, {{kMaxBindingsPerBindGroup - 1, wgpu::ShaderStage::Vertex,
wgpu::BufferBindingType::Uniform}});
// But after is an error.
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
device,
{{kMaxBindingNumber + 1, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform}}));
{{kMaxBindingsPerBindGroup, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform}}));
}
// This test verifies that the BindGroupLayout bindings are correctly validated, even if the

View File

@ -550,25 +550,25 @@ struct Buf {
})"));
}
// Test that @binding must be less then kMaxBindingNumber
// Test that @binding must be less then kMaxBindingsPerBindGroup
TEST_F(ShaderModuleValidationTest, MaxBindingNumber) {
static_assert(kMaxBindingNumber == 65535);
static_assert(kMaxBindingsPerBindGroup == 640);
wgpu::ComputePipelineDescriptor desc;
desc.compute.entryPoint = "main";
// kMaxBindingNumber is valid.
// kMaxBindingsPerBindGroup-1 is valid.
desc.compute.module = utils::CreateShaderModule(device, R"(
@group(0) @binding(65535) var s : sampler;
@group(0) @binding(639) var s : sampler;
@compute @workgroup_size(1) fn main() {
_ = s;
}
)");
device.CreateComputePipeline(&desc);
// kMaxBindingNumber + 1 is an error
// kMaxBindingsPerBindGroup is an error
desc.compute.module = utils::CreateShaderModule(device, R"(
@group(0) @binding(65536) var s : sampler;
@group(0) @binding(640) var s : sampler;
@compute @workgroup_size(1) fn main() {
_ = s;
}