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:
parent
1862e83510
commit
4d67a883b6
|
@ -1250,6 +1250,7 @@
|
||||||
{"name": "max texture dimension 3D", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"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 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 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 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 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"},
|
{"name": "max sampled textures per shader stage", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
static constexpr uint32_t kMaxBindGroups = 4u;
|
static constexpr uint32_t kMaxBindGroups = 4u;
|
||||||
|
static constexpr uint32_t kMaxBindingsPerBindGroup = 640u;
|
||||||
static constexpr uint8_t kMaxVertexAttributes = 16u;
|
static constexpr uint8_t kMaxVertexAttributes = 16u;
|
||||||
static constexpr uint8_t kMaxVertexBuffers = 8u;
|
static constexpr uint8_t kMaxVertexBuffers = 8u;
|
||||||
static constexpr uint32_t kMaxVertexBufferArrayStride = 2048u;
|
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 kSamplersPerExternalTexture = 1u;
|
||||||
static constexpr uint8_t kUniformsPerExternalTexture = 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_
|
#endif // SRC_DAWN_COMMON_CONSTANTS_H_
|
||||||
|
|
|
@ -183,8 +183,8 @@ std::vector<BindGroupLayoutEntry> ExtractAndExpandBglEntries(
|
||||||
std::vector<BindGroupLayoutEntry> expandedOutput;
|
std::vector<BindGroupLayoutEntry> expandedOutput;
|
||||||
|
|
||||||
// When new bgl entries are created, we use binding numbers larger than
|
// When new bgl entries are created, we use binding numbers larger than
|
||||||
// kMaxBindingNumber to ensure there are no collisions.
|
// kMaxBindingsPerBindGroup to ensure there are no collisions.
|
||||||
uint32_t nextOpenBindingNumberForNewEntry = kMaxBindingNumber + 1;
|
uint32_t nextOpenBindingNumberForNewEntry = kMaxBindingsPerBindGroup;
|
||||||
for (uint32_t i = 0; i < descriptor->entryCount; i++) {
|
for (uint32_t i = 0; i < descriptor->entryCount; i++) {
|
||||||
const BindGroupLayoutEntry& entry = descriptor->entries[i];
|
const BindGroupLayoutEntry& entry = descriptor->entries[i];
|
||||||
const ExternalTextureBindingLayout* externalTextureBindingLayout = nullptr;
|
const ExternalTextureBindingLayout* externalTextureBindingLayout = nullptr;
|
||||||
|
@ -250,9 +250,9 @@ MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase* device,
|
||||||
const BindGroupLayoutEntry& entry = descriptor->entries[i];
|
const BindGroupLayoutEntry& entry = descriptor->entries[i];
|
||||||
BindingNumber bindingNumber = BindingNumber(entry.binding);
|
BindingNumber bindingNumber = BindingNumber(entry.binding);
|
||||||
|
|
||||||
DAWN_INVALID_IF(bindingNumber > kMaxBindingNumberTyped,
|
DAWN_INVALID_IF(bindingNumber >= kMaxBindingsPerBindGroupTyped,
|
||||||
"Binding number (%u) exceeds the maximum binding number (%u).",
|
"Binding number (%u) exceeds the maxBindingsPerBindGroup limit (%u).",
|
||||||
uint32_t(bindingNumber), uint32_t(kMaxBindingNumberTyped));
|
uint32_t(bindingNumber), kMaxBindingsPerBindGroup);
|
||||||
DAWN_INVALID_IF(bindingsSet.count(bindingNumber) != 0,
|
DAWN_INVALID_IF(bindingsSet.count(bindingNumber) != 0,
|
||||||
"On entries[%u]: binding index (%u) was specified by a previous entry.", i,
|
"On entries[%u]: binding index (%u) was specified by a previous entry.", i,
|
||||||
entry.binding);
|
entry.binding);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
namespace dawn::native {
|
namespace dawn::native {
|
||||||
// Binding numbers in the shader and BindGroup/BindGroupLayoutDescriptors
|
// Binding numbers in the shader and BindGroup/BindGroupLayoutDescriptors
|
||||||
using BindingNumber = TypedInteger<struct BindingNumberT, uint32_t>;
|
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
|
// Binding numbers get mapped to a packed range of indices
|
||||||
using BindingIndex = TypedInteger<struct BindingIndexT, uint32_t>;
|
using BindingIndex = TypedInteger<struct BindingIndexT, uint32_t>;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
X(Maximum, maxTextureDimension3D, 2048, 2048) \
|
X(Maximum, maxTextureDimension3D, 2048, 2048) \
|
||||||
X(Maximum, maxTextureArrayLayers, 256, 256) \
|
X(Maximum, maxTextureArrayLayers, 256, 256) \
|
||||||
X(Maximum, maxBindGroups, 4, 4) \
|
X(Maximum, maxBindGroups, 4, 4) \
|
||||||
|
X(Maximum, maxBindingsPerBindGroup, 640, 640) \
|
||||||
X(Maximum, maxDynamicUniformBuffersPerPipelineLayout, 8, 8) \
|
X(Maximum, maxDynamicUniformBuffersPerPipelineLayout, 8, 8) \
|
||||||
X(Maximum, maxDynamicStorageBuffersPerPipelineLayout, 4, 4) \
|
X(Maximum, maxDynamicStorageBuffersPerPipelineLayout, 4, 4) \
|
||||||
X(Maximum, maxSampledTexturesPerShaderStage, 16, 16) \
|
X(Maximum, maxSampledTexturesPerShaderStage, 16, 16) \
|
||||||
|
|
|
@ -792,9 +792,9 @@ ResultOrError<std::unique_ptr<EntryPointMetadata>> ReflectEntryPointUsingTint(
|
||||||
"The entry-point uses a binding with a group decoration (%u) "
|
"The entry-point uses a binding with a group decoration (%u) "
|
||||||
"that exceeds the maximum (%u).",
|
"that exceeds the maximum (%u).",
|
||||||
resource.bind_group, kMaxBindGroups) ||
|
resource.bind_group, kMaxBindGroups) ||
|
||||||
DelayedInvalidIf(bindingNumber > kMaxBindingNumberTyped,
|
DelayedInvalidIf(bindingNumber >= kMaxBindingsPerBindGroupTyped,
|
||||||
"Binding number (%u) exceeds the maximum binding number (%u).",
|
"Binding number (%u) exceeds the maxBindingsPerBindGroup limit (%u).",
|
||||||
uint32_t(bindingNumber), uint32_t(kMaxBindingNumberTyped))) {
|
uint32_t(bindingNumber), kMaxBindingsPerBindGroup)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1254,7 +1254,7 @@ TEST_P(BindGroupTests, ArbitraryBindingNumbers) {
|
||||||
color : vec4<f32>
|
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(47) var <uniform> ubo2 : Ubo;
|
||||||
@group(0) @binding(111) var <uniform> ubo3 : Ubo;
|
@group(0) @binding(111) var <uniform> ubo3 : Ubo;
|
||||||
|
|
||||||
|
@ -1295,7 +1295,7 @@ TEST_P(BindGroupTests, ArbitraryBindingNumbers) {
|
||||||
};
|
};
|
||||||
|
|
||||||
utils::BindingInitializationHelper bindings[] = {
|
utils::BindingInitializationHelper bindings[] = {
|
||||||
{953, color1, 0, 4 * sizeof(float)}, //
|
{553, color1, 0, 4 * sizeof(float)}, //
|
||||||
{47, color2, 0, 4 * sizeof(float)}, //
|
{47, color2, 0, 4 * sizeof(float)}, //
|
||||||
{111, color3, 0, 4 * sizeof(float)}, //
|
{111, color3, 0, 4 * sizeof(float)}, //
|
||||||
};
|
};
|
||||||
|
|
|
@ -1017,14 +1017,14 @@ TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutStorageBindingsInVertexShad
|
||||||
|
|
||||||
// Tests setting that bind group layout bindings numbers may be very large.
|
// Tests setting that bind group layout bindings numbers may be very large.
|
||||||
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutEntryMax) {
|
TEST_F(BindGroupLayoutValidationTest, BindGroupLayoutEntryMax) {
|
||||||
// Check that up to kMaxBindingNumber is valid.
|
// Check that up to kMaxBindingsPerBindGroup-1 is valid.
|
||||||
utils::MakeBindGroupLayout(
|
utils::MakeBindGroupLayout(device, {{kMaxBindingsPerBindGroup - 1, wgpu::ShaderStage::Vertex,
|
||||||
device, {{kMaxBindingNumber, wgpu::ShaderStage::Vertex, wgpu::BufferBindingType::Uniform}});
|
wgpu::BufferBindingType::Uniform}});
|
||||||
|
|
||||||
// But after is an error.
|
// But after is an error.
|
||||||
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
|
||||||
device,
|
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
|
// This test verifies that the BindGroupLayout bindings are correctly validated, even if the
|
||||||
|
|
|
@ -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) {
|
TEST_F(ShaderModuleValidationTest, MaxBindingNumber) {
|
||||||
static_assert(kMaxBindingNumber == 65535);
|
static_assert(kMaxBindingsPerBindGroup == 640);
|
||||||
|
|
||||||
wgpu::ComputePipelineDescriptor desc;
|
wgpu::ComputePipelineDescriptor desc;
|
||||||
desc.compute.entryPoint = "main";
|
desc.compute.entryPoint = "main";
|
||||||
|
|
||||||
// kMaxBindingNumber is valid.
|
// kMaxBindingsPerBindGroup-1 is valid.
|
||||||
desc.compute.module = utils::CreateShaderModule(device, R"(
|
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() {
|
@compute @workgroup_size(1) fn main() {
|
||||||
_ = s;
|
_ = s;
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
device.CreateComputePipeline(&desc);
|
device.CreateComputePipeline(&desc);
|
||||||
|
|
||||||
// kMaxBindingNumber + 1 is an error
|
// kMaxBindingsPerBindGroup is an error
|
||||||
desc.compute.module = utils::CreateShaderModule(device, R"(
|
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() {
|
@compute @workgroup_size(1) fn main() {
|
||||||
_ = s;
|
_ = s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue