[dawn][native] Factor the logic to compute the tint::Bindings This option passed to Tint compilation is used to remap bindings from WGSL bind points, to whatever the backend needs to match how it sets BindGroups. The logic in all backends look extremely similar apart from how they map a (group, index) to a tint::BindPoint. The logic is extracted in a GenerateBindingRemapping helper function in TintUtils that takes a backend-specified functor for the mapping of a (group, index) to a tint::BindPoint. In the Vulkan backend, some leftover logic for static samplers is extracted from the generation of the tint::Bindings to modify it a posteriori. Bug: 447157265 Change-Id: Ib128c83e71a4ef1916fbe3e1c9475b5f1b680566 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/266375 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/src/dawn/native/TintUtils.h b/src/dawn/native/TintUtils.h index 2417f5d..41830fb 100644 --- a/src/dawn/native/TintUtils.h +++ b/src/dawn/native/TintUtils.h
@@ -32,8 +32,10 @@ #include <unordered_map> #include "dawn/common/NonCopyable.h" +#include "dawn/native/BindGroupLayoutInternal.h" #include "dawn/native/BindingInfo.h" #include "dawn/native/IntegerTypes.h" +#include "dawn/native/PipelineLayout.h" #include "dawn/native/ShaderModule.h" #include "dawn/native/stream/Stream.h" @@ -86,6 +88,96 @@ return {{BindGroupIndex(tintBindingPoint.group), BindingNumber(tintBindingPoint.binding)}}; } +// Helper function to generate the binding remapping information for Tint compilation. Each backend +// remaps the group + BindingIndex to a BindingPoint differently using the `BindingPointFor` +// function passed as argument. +template <typename F> +concept ConvertsBindingIndexToBindingPoint = requires(F f, BindGroupIndex group, BindingIndex i) { + { f(group, i) } -> std::same_as<tint::BindingPoint>; +}; +template <ConvertsBindingIndexToBindingPoint F> +tint::Bindings GenerateBindingRemapping(const PipelineLayoutBase* layout, + SingleShaderStage stage, + F&& BindingPointFor) { + tint::Bindings bindings; + + for (BindGroupIndex group : layout->GetBindGroupLayoutsMask()) { + const BindGroupLayoutInternalBase* bgl = layout->GetBindGroupLayout(group); + + for (const auto& [bindingNumber, apiBindingIndex] : bgl->GetBindingMap()) { + if (!(bgl->GetAPIBindingInfo(apiBindingIndex).visibility & StageBit(stage))) { + continue; + } + + tint::BindingPoint srcBindingPoint{ + .group = uint32_t(group), + .binding = uint32_t(bindingNumber), + }; + + MatchVariant( + bgl->GetAPIBindingInfo(apiBindingIndex).bindingLayout, + [&](const BufferBindingInfo& bindingInfo) { + tint::BindingPoint dstBindingPoint = + BindingPointFor(group, bgl->AsBindingIndex(apiBindingIndex)); + switch (bindingInfo.type) { + case wgpu::BufferBindingType::Uniform: + bindings.uniform.emplace(srcBindingPoint, dstBindingPoint); + break; + case kInternalStorageBufferBinding: + case wgpu::BufferBindingType::Storage: + case wgpu::BufferBindingType::ReadOnlyStorage: + case kInternalReadOnlyStorageBufferBinding: + bindings.storage.emplace(srcBindingPoint, dstBindingPoint); + break; + case wgpu::BufferBindingType::BindingNotUsed: + case wgpu::BufferBindingType::Undefined: + DAWN_UNREACHABLE(); + break; + } + }, + [&](const SamplerBindingInfo& bindingInfo) { + bindings.sampler.emplace( + srcBindingPoint, + BindingPointFor(group, bgl->AsBindingIndex(apiBindingIndex))); + }, + [&](const StaticSamplerBindingInfo& bindingInfo) { + bindings.sampler.emplace( + srcBindingPoint, + BindingPointFor(group, bgl->AsBindingIndex(apiBindingIndex))); + }, + [&](const TextureBindingInfo& bindingInfo) { + bindings.texture.emplace( + srcBindingPoint, + BindingPointFor(group, bgl->AsBindingIndex(apiBindingIndex))); + }, + [&](const StorageTextureBindingInfo& bindingInfo) { + bindings.storage_texture.emplace( + srcBindingPoint, + BindingPointFor(group, bgl->AsBindingIndex(apiBindingIndex))); + }, + [&](const InputAttachmentBindingInfo&) { + bindings.input_attachment.emplace( + srcBindingPoint, + BindingPointFor(group, bgl->AsBindingIndex(apiBindingIndex))); + }, + [](const TexelBufferBindingInfo& bindingInfo) { + // TODO(crbug/382544164): Prototype texel buffer feature + DAWN_UNREACHABLE(); + }, + [&](const ExternalTextureBindingInfo& bindingInfo) { + bindings.external_texture.emplace( + srcBindingPoint, + tint::ExternalTexture{ + .metadata = BindingPointFor(group, bindingInfo.metadata), + .plane0 = BindingPointFor(group, bindingInfo.plane0), + .plane1 = BindingPointFor(group, bindingInfo.plane1)}); + }); + } + } + + return bindings; +} + } // namespace dawn::native #endif // SRC_DAWN_NATIVE_TINTUTILS_H_
diff --git a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp index 80e138e..f0e7e5e 100644 --- a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp +++ b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
@@ -108,81 +108,15 @@ break; } - tint::Bindings bindings; - - for (BindGroupIndex group : layout->GetBindGroupLayoutsMask()) { - const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group)); - const auto& indices = layout->GetBindingTableIndexMap()[group]; - - for (const auto& [bindingNumber, apiBindingIndex] : bgl->GetBindingMap()) { - if (!(bgl->GetAPIBindingInfo(apiBindingIndex).visibility & StageBit(stage))) { - continue; - } - - tint::BindingPoint srcBindingPoint{ - .group = uint32_t(group), - .binding = uint32_t(bindingNumber), + tint::Bindings bindings = + GenerateBindingRemapping(layout, stage, [&](BindGroupIndex group, BindingIndex index) { + tint::BindingPoint dstBindingPoint = tint::BindingPoint{ + .group = 0, + .binding = layout->GetBindingTableIndexMap()[group][index][stage], }; - - auto ComputeDestinationBindingPoint = [&](BindingIndex bindingIndex) { - tint::BindingPoint dstBindingPoint{0u, indices[bindingIndex][stage]}; - DAWN_ASSERT(dstBindingPoint.binding != PipelineLayout::kInvalidSlot); - return dstBindingPoint; - }; - - MatchVariant( - bgl->GetAPIBindingInfo(apiBindingIndex).bindingLayout, - [&](const BufferBindingInfo& bindingInfo) { - tint::BindingPoint dstBindingPoint = - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex)); - switch (bindingInfo.type) { - case wgpu::BufferBindingType::Uniform: - bindings.uniform.emplace(srcBindingPoint, dstBindingPoint); - break; - case kInternalStorageBufferBinding: - case wgpu::BufferBindingType::Storage: - case wgpu::BufferBindingType::ReadOnlyStorage: - case kInternalReadOnlyStorageBufferBinding: - bindings.storage.emplace(srcBindingPoint, dstBindingPoint); - break; - case wgpu::BufferBindingType::BindingNotUsed: - case wgpu::BufferBindingType::Undefined: - DAWN_UNREACHABLE(); - break; - } - }, - [&](const SamplerBindingInfo& bindingInfo) { - bindings.sampler.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const TextureBindingInfo& bindingInfo) { - bindings.texture.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const StorageTextureBindingInfo& bindingInfo) { - bindings.storage_texture.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const TexelBufferBindingInfo& bindingInfo) { - // TODO(crbug/382544164): Prototype texel buffer feature - DAWN_UNREACHABLE(); - }, - [&](const ExternalTextureBindingInfo& bindingInfo) { - bindings.external_texture.emplace( - srcBindingPoint, - tint::ExternalTexture{ - .metadata = ComputeDestinationBindingPoint(bindingInfo.metadata), - .plane0 = ComputeDestinationBindingPoint(bindingInfo.plane0), - .plane1 = ComputeDestinationBindingPoint(bindingInfo.plane1)}); - }, - - [](const InputAttachmentBindingInfo&) { DAWN_UNREACHABLE(); }, - [](const StaticSamplerBindingInfo&) { DAWN_UNREACHABLE(); }); - } - } + DAWN_ASSERT(dstBindingPoint.binding != PipelineLayout::kInvalidSlot); + return dstBindingPoint; + }); req.hlsl.shaderModuleHash = GetHash(); req.hlsl.inputProgram = UnsafeUnserializedValue(UseTintProgram());
diff --git a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp index ef996e0..5cadddc 100644 --- a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp +++ b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
@@ -158,91 +158,23 @@ } } - using tint::BindingPoint; - tint::hlsl::writer::ArrayLengthFromUniformOptions arrayLengthFromUniform; arrayLengthFromUniform.ubo_binding = {layout->GetDynamicStorageBufferLengthsRegisterSpace(), layout->GetDynamicStorageBufferLengthsShaderRegister()}; - tint::Bindings bindings; - std::vector<BindingPoint> ignored_by_robustness; + tint::Bindings bindings = + GenerateBindingRemapping(layout, stage, [&](BindGroupIndex group, BindingIndex index) { + const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group)); + return tint::BindingPoint{ + .group = uint32_t(group), + .binding = bgl->GetShaderRegister(index), + }; + }); + std::vector<tint::BindingPoint> ignored_by_robustness; for (BindGroupIndex group : layout->GetBindGroupLayoutsMask()) { const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group)); - for (const auto& [bindingNumber, apiBindingIndex] : bgl->GetBindingMap()) { - tint::BindingPoint srcBindingPoint{ - .group = uint32_t(group), - .binding = uint32_t(bindingNumber), - }; - - // Remap the WGSL bindings to the register numbers computed in the - // d3d12::BindGroupLayout that packs them per register type. The group decoration stays - // the same as HLSL supports register spaces that are a similar concept of a second - // dimension of binding indices. - auto ComputeDestinationBindingPoint = [&](BindingIndex bindingIndex) { - return tint::BindingPoint{.group = uint32_t(group), - .binding = bgl->GetShaderRegister(bindingIndex)}; - }; - - MatchVariant( - bgl->GetAPIBindingInfo(apiBindingIndex).bindingLayout, - [&](const BufferBindingInfo& bindingInfo) { - tint::BindingPoint dstBindingPoint = - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex)); - switch (bindingInfo.type) { - case wgpu::BufferBindingType::Uniform: - bindings.uniform.emplace(srcBindingPoint, dstBindingPoint); - break; - case kInternalStorageBufferBinding: - case wgpu::BufferBindingType::Storage: - case wgpu::BufferBindingType::ReadOnlyStorage: - case kInternalReadOnlyStorageBufferBinding: - bindings.storage.emplace(srcBindingPoint, dstBindingPoint); - break; - case wgpu::BufferBindingType::BindingNotUsed: - case wgpu::BufferBindingType::Undefined: - DAWN_UNREACHABLE(); - break; - } - }, - - [&](const SamplerBindingInfo& bindingInfo) { - bindings.sampler.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const StaticSamplerBindingInfo& bindingInfo) { - bindings.sampler.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const TextureBindingInfo& bindingInfo) { - bindings.texture.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const StorageTextureBindingInfo& bindingInfo) { - bindings.storage_texture.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const TexelBufferBindingInfo& bindingInfo) { - // TODO(crbug/382544164): Prototype texel buffer feature - DAWN_UNREACHABLE(); - }, - [&](const ExternalTextureBindingInfo& bindingInfo) { - bindings.external_texture.emplace( - srcBindingPoint, - tint::ExternalTexture{ - .metadata = ComputeDestinationBindingPoint(bindingInfo.metadata), - .plane0 = ComputeDestinationBindingPoint(bindingInfo.plane0), - .plane1 = ComputeDestinationBindingPoint(bindingInfo.plane1)}); - }, - - [](const InputAttachmentBindingInfo&) { DAWN_UNREACHABLE(); }); - } - // On D3D12 backend all storage buffers without Dynamic Buffer Offset will always be bound // to root descriptor tables, where D3D12 runtime can guarantee that OOB-read will always // return 0 and OOB-write will always take no action, so we don't need to do robustness @@ -285,8 +217,8 @@ layout->GetDynamicStorageBufferLengthInfo()[group].bindingAndRegisterOffsets) { BindingNumber bindingNum = bindingAndRegisterOffset.binding; uint32_t registerOffset = bindingAndRegisterOffset.registerOffset; - BindingPoint bindingPoint{static_cast<uint32_t>(group), - static_cast<uint32_t>(bindingNum)}; + tint::BindingPoint bindingPoint{static_cast<uint32_t>(group), + static_cast<uint32_t>(bindingNum)}; arrayLengthFromUniform.bindpoint_to_size_index.emplace(bindingPoint, registerOffset); } }
diff --git a/src/dawn/native/metal/ShaderModuleMTL.mm b/src/dawn/native/metal/ShaderModuleMTL.mm index aa931b0..a29ca85 100644 --- a/src/dawn/native/metal/ShaderModuleMTL.mm +++ b/src/dawn/native/metal/ShaderModuleMTL.mm
@@ -122,88 +122,15 @@ namespace { -tint::Bindings GenerateBindingInfo(SingleShaderStage stage, - const PipelineLayout* layout, - const BindingInfoArray& moduleBindingInfo, - tint::msl::writer::ArrayLengthOptions& arrayLengthFromConstants, - bool useArgumentBuffers) { - tint::Bindings bindings; +tint::msl::writer::ArrayLengthOptions GenerateArrayLengthOptions(const PipelineLayout* layout, + SingleShaderStage stage) { + tint::msl::writer::ArrayLengthOptions arrayLength; + // Use the ShaderIndex as the indices for the buffer size lookups in the array length uniform + // transform. This is used to compute the size of variable length arrays in storage buffers. for (BindGroupIndex group : layout->GetBindGroupLayoutsMask()) { const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group)); - for (const auto& [bindingNumber, apiBindingIndex] : bgl->GetBindingMap()) { - tint::BindingPoint srcBindingPoint{ - .group = uint32_t(group), - .binding = uint32_t(bindingNumber), - }; - - auto& bindingIndexInfo = layout->GetBindingIndexInfo(stage)[group]; - - auto ComputeDestinationBindingPoint = [&](BindingIndex bindingIndex) { - uint32_t shaderIndex = bindingIndexInfo[bindingIndex]; - return tint::BindingPoint{ - .group = useArgumentBuffers ? uint32_t(group) : 0, - .binding = shaderIndex, - }; - }; - - MatchVariant( - bgl->GetAPIBindingInfo(apiBindingIndex).bindingLayout, - [&](const BufferBindingInfo& bindingInfo) { - tint::BindingPoint dstBindingPoint = - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex)); - switch (bindingInfo.type) { - case wgpu::BufferBindingType::Uniform: - bindings.uniform.emplace(srcBindingPoint, dstBindingPoint); - break; - case kInternalStorageBufferBinding: - case wgpu::BufferBindingType::Storage: - case wgpu::BufferBindingType::ReadOnlyStorage: - case kInternalReadOnlyStorageBufferBinding: - bindings.storage.emplace(srcBindingPoint, dstBindingPoint); - break; - case wgpu::BufferBindingType::BindingNotUsed: - case wgpu::BufferBindingType::Undefined: - DAWN_UNREACHABLE(); - break; - } - }, - [&](const SamplerBindingInfo& bindingInfo) { - bindings.sampler.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const TextureBindingInfo& bindingInfo) { - bindings.texture.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const StorageTextureBindingInfo& bindingInfo) { - bindings.storage_texture.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const TexelBufferBindingInfo& bindingInfo) { - // Metal does not support texel buffers. - // TODO(crbug/382544164): Prototype texel buffer feature - DAWN_UNREACHABLE(); - }, - [&](const ExternalTextureBindingInfo& bindingInfo) { - bindings.external_texture.emplace( - srcBindingPoint, - tint::ExternalTexture{ - .metadata = ComputeDestinationBindingPoint(bindingInfo.metadata), - .plane0 = ComputeDestinationBindingPoint(bindingInfo.plane0), - .plane1 = ComputeDestinationBindingPoint(bindingInfo.plane1)}); - }, - [](const StaticSamplerBindingInfo&) { DAWN_UNREACHABLE(); }, - [](const InputAttachmentBindingInfo&) { DAWN_UNREACHABLE(); }); - } - - // Use the ShaderIndex as the indices for the buffer size lookups in the array length - // uniform transform. This is used to compute the size of variable length arrays in storage - // buffers. for (BindingIndex index : bgl->GetBufferIndices()) { const auto& bindingInfo = bgl->GetBindingInfo(index); if (!(bindingInfo.visibility & StageBit(stage))) { @@ -216,7 +143,7 @@ case wgpu::BufferBindingType::Storage: case wgpu::BufferBindingType::ReadOnlyStorage: case kInternalReadOnlyStorageBufferBinding: - arrayLengthFromConstants.bindpoint_to_size_index.emplace( + arrayLength.bindpoint_to_size_index.emplace( tint::BindingPoint{uint32_t(group), uint32_t(bindingInfo.binding)}, layout->GetBindingIndexInfo(stage)[group][index]); break; @@ -230,7 +157,7 @@ } } } - return bindings; + return arrayLength; } std::unordered_map<uint32_t, tint::msl::writer::ArgumentBufferInfo> GenerateArgumentBufferInfo( @@ -297,12 +224,19 @@ std::ostringstream errorStream; errorStream << "Tint MSL failure:\n"; - tint::msl::writer::ArrayLengthOptions arrayLengthFromConstants; bool useArgumentBuffers = device->IsToggleEnabled(Toggle::MetalUseArgumentBuffers); - tint::Bindings bindings = GenerateBindingInfo(stage, layout, moduleBindingInfo, - arrayLengthFromConstants, useArgumentBuffers); + tint::Bindings bindings = + GenerateBindingRemapping(layout, stage, [&](BindGroupIndex group, BindingIndex index) { + return tint::BindingPoint{ + .group = useArgumentBuffers ? uint32_t(group) : 0, + .binding = layout->GetBindingIndexInfo(stage)[group][index], + }; + }); + + tint::msl::writer::ArrayLengthOptions arrayLengthFromConstants = + GenerateArrayLengthOptions(layout, stage); std::unordered_map<uint32_t, tint::msl::writer::ArgumentBufferInfo> argumentBufferInfo = GenerateArgumentBufferInfo(stage, layout, moduleBindingInfo, useArgumentBuffers);
diff --git a/src/dawn/native/opengl/ShaderModuleGL.cpp b/src/dawn/native/opengl/ShaderModuleGL.cpp index 4e3cd14..b1a07f2 100644 --- a/src/dawn/native/opengl/ShaderModuleGL.cpp +++ b/src/dawn/native/opengl/ShaderModuleGL.cpp
@@ -346,88 +346,6 @@ std::vector<tint::wgsl::Extension> internalExtensions) : ShaderModuleBase(device, descriptor, std::move(internalExtensions)) {} -tint::Bindings GenerateBindingInfo(SingleShaderStage stage, - const PipelineLayout* layout, - const BindingInfoArray& moduleBindingInfo, - GLSLCompilationRequest& req) { - tint::Bindings bindings; - - for (BindGroupIndex group : layout->GetBindGroupLayoutsMask()) { - const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group)); - const auto& bindingIndexInfo = layout->GetBindingIndexInfo()[group]; - - for (const auto& [bindingNumber, apiBindingIndex] : bgl->GetBindingMap()) { - tint::BindingPoint srcBindingPoint{ - .group = uint32_t(group), - .binding = uint32_t(bindingNumber), - }; - - auto ComputeDestinationBindingPoint = [&](BindingIndex bindingIndex) { - return tint::BindingPoint{ - .group = 0, - .binding = uint32_t(bindingIndexInfo[bindingIndex]), - }; - }; - - MatchVariant( - bgl->GetAPIBindingInfo(apiBindingIndex).bindingLayout, - [&](const BufferBindingInfo& bindingInfo) { - tint::BindingPoint dstBindingPoint = - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex)); - switch (bindingInfo.type) { - case wgpu::BufferBindingType::Uniform: - bindings.uniform.emplace(srcBindingPoint, dstBindingPoint); - break; - case kInternalStorageBufferBinding: - case wgpu::BufferBindingType::Storage: - case wgpu::BufferBindingType::ReadOnlyStorage: - case kInternalReadOnlyStorageBufferBinding: - bindings.storage.emplace(srcBindingPoint, dstBindingPoint); - break; - case wgpu::BufferBindingType::BindingNotUsed: - case wgpu::BufferBindingType::Undefined: - DAWN_UNREACHABLE(); - break; - } - }, - [&](const SamplerBindingInfo& bindingInfo) { - bindings.sampler.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const StaticSamplerBindingInfo& bindingInfo) { - bindings.sampler.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const TextureBindingInfo& bindingInfo) { - bindings.texture.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const StorageTextureBindingInfo& bindingInfo) { - bindings.storage_texture.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const TexelBufferBindingInfo& bindingInfo) { - // TODO(crbug/382544164): Prototype texel buffer feature - DAWN_UNREACHABLE(); - }, - [&](const ExternalTextureBindingInfo& bindingInfo) { - bindings.external_texture.emplace( - srcBindingPoint, - tint::ExternalTexture{ - .metadata = ComputeDestinationBindingPoint(bindingInfo.metadata), - .plane0 = ComputeDestinationBindingPoint(bindingInfo.plane0), - .plane1 = ComputeDestinationBindingPoint(bindingInfo.plane1)}); - }, - [](const InputAttachmentBindingInfo& bindingInfo) { DAWN_UNREACHABLE(); }); - } - } - return bindings; -} - ResultOrError<GLuint> ShaderModule::CompileShader( const OpenGLFunctions& gl, const ProgrammableStage& programmableStage, @@ -455,7 +373,13 @@ const EntryPointMetadata& entryPointMetaData = GetEntryPoint(programmableStage.entryPoint); const BindingInfoArray& moduleBindingInfo = entryPointMetaData.bindings; - auto bindings = GenerateBindingInfo(stage, layout, moduleBindingInfo, req); + tint::Bindings bindings = + GenerateBindingRemapping(layout, stage, [&](BindGroupIndex group, BindingIndex index) { + return tint::BindingPoint{ + .group = 0, + .binding = uint32_t(layout->GetBindingIndexInfo()[group][index]), + }; + }); // When textures are accessed without a sampler (e.g., textureLoad()), returned // CombinedSamplerInfo should use this sentinel value as sampler binding point.
diff --git a/src/dawn/native/vulkan/ShaderModuleVk.cpp b/src/dawn/native/vulkan/ShaderModuleVk.cpp index 468a630..1419999 100644 --- a/src/dawn/native/vulkan/ShaderModuleVk.cpp +++ b/src/dawn/native/vulkan/ShaderModuleVk.cpp
@@ -134,86 +134,29 @@ #if TINT_BUILD_SPV_WRITER // Creation of module and spirv is deferred to this point when using tint generator - tint::Bindings bindings; - std::unordered_set<tint::BindingPoint> statically_paired_texture_binding_points; + tint::Bindings bindings = + GenerateBindingRemapping(layout, stage, [&](BindGroupIndex group, BindingIndex index) { + return tint::BindingPoint{ + .group = uint32_t(group), + .binding = uint32_t(index), + }; + }); + // Post process the binding remapping to make statically paired texture point at the sampler + // binding point instead. + std::unordered_set<tint::BindingPoint> staticallyPairedTextureBindingPoints; for (BindGroupIndex group : layout->GetBindGroupLayoutsMask()) { const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group)); - for (const auto& [bindingNumber, apiBindingIndex] : bgl->GetBindingMap()) { - tint::BindingPoint srcBindingPoint{ - .group = uint32_t(group), - .binding = uint32_t(bindingNumber), - }; + for (BindingIndex index : bgl->GetSampledTextureIndices()) { + const auto& bindingInfo = bgl->GetBindingInfo(index); - auto ComputeDestinationBindingPoint = [&](BindingIndex bindingIndex) { - return tint::BindingPoint{.group = uint32_t(group), - .binding = uint32_t(bindingIndex)}; - }; - - MatchVariant( - bgl->GetAPIBindingInfo(apiBindingIndex).bindingLayout, - [&](const BufferBindingInfo& bindingInfo) { - tint::BindingPoint dstBindingPoint = - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex)); - switch (bindingInfo.type) { - case wgpu::BufferBindingType::Uniform: - bindings.uniform.emplace(srcBindingPoint, dstBindingPoint); - break; - case kInternalStorageBufferBinding: - case wgpu::BufferBindingType::Storage: - case wgpu::BufferBindingType::ReadOnlyStorage: - case kInternalReadOnlyStorageBufferBinding: - bindings.storage.emplace(srcBindingPoint, dstBindingPoint); - break; - case wgpu::BufferBindingType::BindingNotUsed: - case wgpu::BufferBindingType::Undefined: - DAWN_UNREACHABLE(); - break; - } - }, - [&](const SamplerBindingInfo& bindingInfo) { - bindings.sampler.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const StaticSamplerBindingInfo& bindingInfo) { - bindings.sampler.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const TextureBindingInfo& bindingInfo) { - tint::BindingPoint dstBindingPoint = - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex)); - if (auto samplerIndex = bgl->GetStaticSamplerIndexForTexture( - BindingIndex{dstBindingPoint.binding})) { - dstBindingPoint.binding = uint32_t(samplerIndex.value()); - statically_paired_texture_binding_points.insert(srcBindingPoint); - } - bindings.texture.emplace(srcBindingPoint, dstBindingPoint); - }, - [&](const StorageTextureBindingInfo& bindingInfo) { - bindings.storage_texture.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }, - [&](const TexelBufferBindingInfo& bindingInfo) { - // TODO(crbug/382544164): Prototype texel buffer feature - DAWN_UNREACHABLE(); - }, - [&](const ExternalTextureBindingInfo& bindingInfo) { - bindings.external_texture.emplace( - srcBindingPoint, - tint::ExternalTexture{ - .metadata = ComputeDestinationBindingPoint(bindingInfo.metadata), - .plane0 = ComputeDestinationBindingPoint(bindingInfo.plane0), - .plane1 = ComputeDestinationBindingPoint(bindingInfo.plane1)}); - }, - [&](const InputAttachmentBindingInfo& bindingInfo) { - bindings.input_attachment.emplace( - srcBindingPoint, - ComputeDestinationBindingPoint(bgl->AsBindingIndex(apiBindingIndex))); - }); + if (auto samplerIndex = bgl->GetStaticSamplerIndexForTexture(index)) { + tint::BindingPoint wgslBindingPoint = {.group = uint32_t(group), + .binding = uint32_t(bindingInfo.binding)}; + bindings.texture[wgslBindingPoint].binding = uint32_t(samplerIndex.value()); + staticallyPairedTextureBindingPoints.insert(wgslBindingPoint); + } } } @@ -266,7 +209,7 @@ req.tintOptions.strip_all_names = !GetDevice()->IsToggleEnabled(Toggle::DisableSymbolRenaming); req.tintOptions.statically_paired_texture_binding_points = - std::move(statically_paired_texture_binding_points); + std::move(staticallyPairedTextureBindingPoints); req.tintOptions.disable_robustness = !GetDevice()->IsRobustnessEnabled(); req.tintOptions.emit_vertex_point_size = emitPointSize;