Skip to content

Commit

Permalink
[WebGPU] CTS validation/createPipelineLayout test is failing
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=266390
<radar://119645609>

Reviewed by Dan Glastonbury.

Add passing expectations and validate pipeline creation.

* LayoutTests/http/tests/webgpu/webgpu/api/validation/createPipelineLayout-expected.txt:
* Source/WebGPU/WebGPU/BindGroupLayout.h:
(WebGPU::BindGroupLayout::create):
* Source/WebGPU/WebGPU/BindGroupLayout.mm:
(WebGPU::Device::createBindGroupLayout):
(WebGPU::BindGroupLayout::BindGroupLayout):
(WebGPU::BindGroupLayout::dynamicUniformBuffers const):
(WebGPU::BindGroupLayout::dynamicStorageBuffers const):
* Source/WebGPU/WebGPU/PipelineLayout.mm:
(WebGPU::Device::createPipelineLayout):

Canonical link: https://commits.webkit.org/272070@main
  • Loading branch information
mwyrzykowski committed Dec 14, 2023
1 parent 9941ce5 commit 2382ddd
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
(Populate me when we're ready to investigate this test)

PASS :number_of_dynamic_buffers_exceeds_the_maximum_value:
PASS :number_of_bind_group_layouts_exceeds_the_maximum_value:
PASS :bind_group_layouts,device_mismatch:

10 changes: 7 additions & 3 deletions Source/WebGPU/WebGPU/BindGroupLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ class BindGroupLayout : public WGPUBindGroupLayoutImpl, public RefCounted<BindGr
using StageMapValue = BindingAccess;
using StageMapTable = HashMap<uint64_t, StageMapValue, DefaultHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>;

static Ref<BindGroupLayout> create(StageMapTable&& stageMapTable, id<MTLArgumentEncoder> vertexArgumentEncoder, id<MTLArgumentEncoder> fragmentArgumentEncoder, id<MTLArgumentEncoder> computeArgumentEncoder, EntriesContainer&& entries, size_t sizeOfVertexDynamicOffsets, size_t sizeOfFragmentDynamicOffsets, size_t sizeOfComputeDynamicOffsets, bool isAutoGenerated, ShaderStageArray<uint32_t>&& uniformBuffersPerStage, ShaderStageArray<uint32_t>&& storageBuffersPerStage, ShaderStageArray<uint32_t>&& samplersPerStage, ShaderStageArray<uint32_t>&& texturesPerStage, ShaderStageArray<uint32_t>&& storageTexturesPerStage, const Device& device)
static Ref<BindGroupLayout> create(StageMapTable&& stageMapTable, id<MTLArgumentEncoder> vertexArgumentEncoder, id<MTLArgumentEncoder> fragmentArgumentEncoder, id<MTLArgumentEncoder> computeArgumentEncoder, EntriesContainer&& entries, size_t sizeOfVertexDynamicOffsets, size_t sizeOfFragmentDynamicOffsets, size_t sizeOfComputeDynamicOffsets, bool isAutoGenerated, ShaderStageArray<uint32_t>&& uniformBuffersPerStage, ShaderStageArray<uint32_t>&& storageBuffersPerStage, ShaderStageArray<uint32_t>&& samplersPerStage, ShaderStageArray<uint32_t>&& texturesPerStage, ShaderStageArray<uint32_t>&& storageTexturesPerStage, uint32_t dynamicUniformBuffers, uint32_t dynamicStorageBuffers, const Device& device)
{
return adoptRef(*new BindGroupLayout(WTFMove(stageMapTable), vertexArgumentEncoder, fragmentArgumentEncoder, computeArgumentEncoder, WTFMove(entries), sizeOfVertexDynamicOffsets, sizeOfFragmentDynamicOffsets, sizeOfComputeDynamicOffsets, isAutoGenerated, WTFMove(uniformBuffersPerStage), WTFMove(storageBuffersPerStage), WTFMove(samplersPerStage), WTFMove(texturesPerStage), WTFMove(storageTexturesPerStage), device));
return adoptRef(*new BindGroupLayout(WTFMove(stageMapTable), vertexArgumentEncoder, fragmentArgumentEncoder, computeArgumentEncoder, WTFMove(entries), sizeOfVertexDynamicOffsets, sizeOfFragmentDynamicOffsets, sizeOfComputeDynamicOffsets, isAutoGenerated, WTFMove(uniformBuffersPerStage), WTFMove(storageBuffersPerStage), WTFMove(samplersPerStage), WTFMove(texturesPerStage), WTFMove(storageTexturesPerStage), dynamicUniformBuffers, dynamicStorageBuffers, device));
}
static Ref<BindGroupLayout> createInvalid(const Device& device)
{
Expand Down Expand Up @@ -122,9 +122,11 @@ class BindGroupLayout : public WGPUBindGroupLayoutImpl, public RefCounted<BindGr
uint32_t samplersPerStage(ShaderStage) const;
uint32_t texturesPerStage(ShaderStage) const;
uint32_t storageTexturesPerStage(ShaderStage) const;
uint32_t dynamicUniformBuffers() const;
uint32_t dynamicStorageBuffers() const;

private:
BindGroupLayout(StageMapTable&&, id<MTLArgumentEncoder>, id<MTLArgumentEncoder>, id<MTLArgumentEncoder>, EntriesContainer&&, size_t sizeOfVertexDynamicOffsets, size_t sizeOfFragmentDynamicOffsets, size_t sizeOfComputeDynamicOffsets, bool isAutoGenerated, ShaderStageArray<uint32_t>&& uniformBuffersPerStage, ShaderStageArray<uint32_t>&& storageBuffersPerStage, ShaderStageArray<uint32_t>&& samplersPerStage, ShaderStageArray<uint32_t>&& texturesPerStage, ShaderStageArray<uint32_t>&& storageTexturesPerStage, const Device&);
BindGroupLayout(StageMapTable&&, id<MTLArgumentEncoder>, id<MTLArgumentEncoder>, id<MTLArgumentEncoder>, EntriesContainer&&, size_t sizeOfVertexDynamicOffsets, size_t sizeOfFragmentDynamicOffsets, size_t sizeOfComputeDynamicOffsets, bool isAutoGenerated, ShaderStageArray<uint32_t>&& uniformBuffersPerStage, ShaderStageArray<uint32_t>&& storageBuffersPerStage, ShaderStageArray<uint32_t>&& samplersPerStage, ShaderStageArray<uint32_t>&& texturesPerStage, ShaderStageArray<uint32_t>&& storageTexturesPerStage, uint32_t dynamicUniformBuffers, uint32_t dynamicStorageBuffers, const Device&);
explicit BindGroupLayout(const Device&);

const StageMapTable m_indicesForBinding;
Expand All @@ -145,6 +147,8 @@ class BindGroupLayout : public WGPUBindGroupLayoutImpl, public RefCounted<BindGr
ShaderStageArray<uint32_t> m_samplersPerStage;
ShaderStageArray<uint32_t> m_texturesPerStage;
ShaderStageArray<uint32_t> m_storageTexturesPerStage;
uint32_t m_dynamicUniformBuffers { 0 };
uint32_t m_dynamicStorageBuffers { 0 };
};

} // namespace WebGPU
16 changes: 14 additions & 2 deletions Source/WebGPU/WebGPU/BindGroupLayout.mm
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,10 @@ static bool containsStage(WGPUShaderStageFlags stageBitfield, auto stage)
return BindGroupLayout::createInvalid(*this);
}

return BindGroupLayout::create(WTFMove(indicesForBinding), argumentEncoders[0], argumentEncoders[1], argumentEncoders[2], WTFMove(bindGroupLayoutEntries), sizeOfDynamicOffsets[0], sizeOfDynamicOffsets[1], sizeOfDynamicOffsets[2], isAutoGenerated, WTFMove(uniformBuffersPerStage), WTFMove(storageBuffersPerStage), WTFMove(samplersPerStage), WTFMove(texturesPerStage), WTFMove(storageTexturesPerStage), *this);
return BindGroupLayout::create(WTFMove(indicesForBinding), argumentEncoders[0], argumentEncoders[1], argumentEncoders[2], WTFMove(bindGroupLayoutEntries), sizeOfDynamicOffsets[0], sizeOfDynamicOffsets[1], sizeOfDynamicOffsets[2], isAutoGenerated, WTFMove(uniformBuffersPerStage), WTFMove(storageBuffersPerStage), WTFMove(samplersPerStage), WTFMove(texturesPerStage), WTFMove(storageTexturesPerStage), dynamicUniformBuffers, dynamicStorageBuffers, *this);
}

BindGroupLayout::BindGroupLayout(StageMapTable&& indicesForBinding, id<MTLArgumentEncoder> vertexArgumentEncoder, id<MTLArgumentEncoder> fragmentArgumentEncoder, id<MTLArgumentEncoder> computeArgumentEncoder, BindGroupLayout::EntriesContainer&& bindGroupLayoutEntries, size_t sizeOfVertexDynamicOffsets, size_t sizeOfFragmentDynamicOffsets, size_t sizeOfComputeDynamicOffsets, bool isAutoGenerated, ShaderStageArray<uint32_t>&& uniformBuffersPerStage, ShaderStageArray<uint32_t>&& storageBuffersPerStage, ShaderStageArray<uint32_t>&& samplersPerStage, ShaderStageArray<uint32_t>&& texturesPerStage, ShaderStageArray<uint32_t>&& storageTexturesPerStage, const Device& device)
BindGroupLayout::BindGroupLayout(StageMapTable&& indicesForBinding, id<MTLArgumentEncoder> vertexArgumentEncoder, id<MTLArgumentEncoder> fragmentArgumentEncoder, id<MTLArgumentEncoder> computeArgumentEncoder, BindGroupLayout::EntriesContainer&& bindGroupLayoutEntries, size_t sizeOfVertexDynamicOffsets, size_t sizeOfFragmentDynamicOffsets, size_t sizeOfComputeDynamicOffsets, bool isAutoGenerated, ShaderStageArray<uint32_t>&& uniformBuffersPerStage, ShaderStageArray<uint32_t>&& storageBuffersPerStage, ShaderStageArray<uint32_t>&& samplersPerStage, ShaderStageArray<uint32_t>&& texturesPerStage, ShaderStageArray<uint32_t>&& storageTexturesPerStage, uint32_t dynamicUniformBuffers, uint32_t dynamicStorageBuffers, const Device& device)
: m_indicesForBinding(WTFMove(indicesForBinding))
, m_vertexArgumentEncoder(vertexArgumentEncoder)
, m_fragmentArgumentEncoder(fragmentArgumentEncoder)
Expand All @@ -413,6 +413,8 @@ static bool containsStage(WGPUShaderStageFlags stageBitfield, auto stage)
, m_samplersPerStage(WTFMove(samplersPerStage))
, m_texturesPerStage(WTFMove(texturesPerStage))
, m_storageTexturesPerStage(WTFMove(storageTexturesPerStage))
, m_dynamicUniformBuffers(dynamicUniformBuffers)
, m_dynamicStorageBuffers(dynamicStorageBuffers)
{
}

Expand Down Expand Up @@ -517,6 +519,16 @@ static bool containsStage(WGPUShaderStageFlags stageBitfield, auto stage)
return m_isAutoGenerated;
}

uint32_t BindGroupLayout::dynamicUniformBuffers() const
{
return m_dynamicUniformBuffers;
}

uint32_t BindGroupLayout::dynamicStorageBuffers() const
{
return m_dynamicStorageBuffers;
}

} // namespace WebGPU

#pragma mark WGPU Stubs
Expand Down
25 changes: 24 additions & 1 deletion Source/WebGPU/WebGPU/PipelineLayout.mm
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,23 @@

std::optional<Vector<Ref<BindGroupLayout>>> optionalBindGroupLayouts = std::nullopt;
if (descriptor.bindGroupLayouts) {
auto& deviceLimits = limits();
if (descriptor.bindGroupLayoutCount > deviceLimits.maxBindGroups) {
generateAValidationError("Too many bind groups"_s);
return PipelineLayout::createInvalid(*this);
}
Vector<Ref<BindGroupLayout>> bindGroupLayouts(descriptor.bindGroupLayoutCount, [&](size_t i) {
auto* bindGroupLayout = descriptor.bindGroupLayouts[i];
return Ref<BindGroupLayout> { WebGPU::fromAPI(bindGroupLayout) };
});
auto& deviceLimits = limits();
ShaderStage stages[] = { ShaderStage::Vertex, ShaderStage::Fragment, ShaderStage::Compute };
for (ShaderStage shaderStage : stages) {
uint32_t uniformBufferCount = 0, storageBufferCount = 0, samplerCount = 0, textureCount = 0, storageTextureCount = 0;
for (auto& bindGroupLayout : bindGroupLayouts) {
if (this != &bindGroupLayout->device()) {
generateAValidationError("Device mismatch"_s);
return PipelineLayout::createInvalid(*this);
}
uniformBufferCount += bindGroupLayout->uniformBuffersPerStage(shaderStage);
storageBufferCount += bindGroupLayout->storageBuffersPerStage(shaderStage);
samplerCount += bindGroupLayout->samplersPerStage(shaderStage);
Expand All @@ -59,6 +67,21 @@
}
}
}

uint32_t dynamicUniformBuffers = 0, dynamicStorageBuffers = 0;
for (auto& bindGroupLayout : bindGroupLayouts) {
dynamicUniformBuffers += bindGroupLayout->dynamicUniformBuffers();
dynamicStorageBuffers += bindGroupLayout->dynamicStorageBuffers();
}
if (dynamicUniformBuffers > deviceLimits.maxDynamicUniformBuffersPerPipelineLayout) {
generateAValidationError("Too many dynamic uniform buffers"_s);
return PipelineLayout::createInvalid(*this);
}
if (dynamicStorageBuffers > deviceLimits.maxDynamicStorageBuffersPerPipelineLayout) {
generateAValidationError("Too many dynamic storage buffers"_s);
return PipelineLayout::createInvalid(*this);
}

optionalBindGroupLayouts = WTFMove(bindGroupLayouts);
}

Expand Down

0 comments on commit 2382ddd

Please sign in to comment.