diff --git a/src/dawn_native/vulkan/BindGroupLayoutVk.cpp b/src/dawn_native/vulkan/BindGroupLayoutVk.cpp index c6ea3f9991..83f58381b9 100644 --- a/src/dawn_native/vulkan/BindGroupLayoutVk.cpp +++ b/src/dawn_native/vulkan/BindGroupLayoutVk.cpp @@ -50,8 +50,9 @@ namespace dawn_native { namespace vulkan { case dawn::BindingType::StorageBuffer: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; case dawn::BindingType::DynamicUniformBuffer: + return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; case dawn::BindingType::DynamicStorageBuffer: - UNREACHABLE(); + return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; default: UNREACHABLE(); } @@ -121,16 +122,15 @@ namespace dawn_native { namespace vulkan { auto ToDescriptorType = [](dawn::BindingType type) -> DescriptorType { switch (type) { case dawn::BindingType::UniformBuffer: + case dawn::BindingType::DynamicUniformBuffer: return UNIFORM_BUFFER; case dawn::BindingType::Sampler: return SAMPLER; case dawn::BindingType::SampledTexture: return SAMPLED_IMAGE; case dawn::BindingType::StorageBuffer: - return STORAGE_BUFFER; - case dawn::BindingType::DynamicUniformBuffer: case dawn::BindingType::DynamicStorageBuffer: - UNREACHABLE(); + return STORAGE_BUFFER; default: UNREACHABLE(); } diff --git a/src/dawn_native/vulkan/BindGroupVk.cpp b/src/dawn_native/vulkan/BindGroupVk.cpp index 1fb8a7ccbf..30d59698cc 100644 --- a/src/dawn_native/vulkan/BindGroupVk.cpp +++ b/src/dawn_native/vulkan/BindGroupVk.cpp @@ -81,7 +81,9 @@ namespace dawn_native { namespace vulkan { switch (layoutInfo.types[bindingIndex]) { case dawn::BindingType::UniformBuffer: - case dawn::BindingType::StorageBuffer: { + case dawn::BindingType::StorageBuffer: + case dawn::BindingType::DynamicUniformBuffer: + case dawn::BindingType::DynamicStorageBuffer: { BufferBinding binding = GetBindingAsBufferBinding(bindingIndex); writeBufferInfo[numWrites].buffer = ToBackend(binding.buffer)->GetHandle(); @@ -109,10 +111,6 @@ namespace dawn_native { namespace vulkan { write.pImageInfo = &writeImageInfo[numWrites]; } break; - case dawn::BindingType::DynamicUniformBuffer: - case dawn::BindingType::DynamicStorageBuffer: - UNREACHABLE(); - break; default: UNREACHABLE(); } diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp index 3c81af40ce..89fbbac4c0 100644 --- a/src/dawn_native/vulkan/CommandBufferVk.cpp +++ b/src/dawn_native/vulkan/CommandBufferVk.cpp @@ -105,9 +105,21 @@ namespace dawn_native { namespace vulkan { class DescriptorSetTracker { public: - void OnSetBindGroup(uint32_t index, VkDescriptorSet set) { + void OnSetBindGroup(uint32_t index, + VkDescriptorSet set, + uint32_t dynamicOffsetCount, + uint64_t* dynamicOffsets) { mDirtySets.set(index); mSets[index] = set; + mDynamicOffsetCounts[index] = dynamicOffsetCount; + if (dynamicOffsetCount > 0) { + // Vulkan backend use uint32_t as dynamic offsets type, it is not correct. + // Vulkan should use VkDeviceSize. Dawn vulkan backend has to handle this. + for (uint32_t i = 0; i < dynamicOffsetCount; ++i) { + ASSERT(dynamicOffsets[i] <= std::numeric_limits::max()); + mDynamicOffsets[index][i] = static_cast(dynamicOffsets[i]); + } + } } void OnPipelineLayoutChange(PipelineLayout* layout) { @@ -131,9 +143,11 @@ namespace dawn_native { namespace vulkan { void Flush(Device* device, VkCommandBuffer commands, VkPipelineBindPoint bindPoint) { for (uint32_t dirtyIndex : IterateBitSet(mDirtySets)) { - device->fn.CmdBindDescriptorSets(commands, bindPoint, - mCurrentLayout->GetHandle(), dirtyIndex, 1, - &mSets[dirtyIndex], 0, nullptr); + device->fn.CmdBindDescriptorSets( + commands, bindPoint, mCurrentLayout->GetHandle(), dirtyIndex, 1, + &mSets[dirtyIndex], mDynamicOffsetCounts[dirtyIndex], + mDynamicOffsetCounts[dirtyIndex] > 0 ? mDynamicOffsets[dirtyIndex].data() + : nullptr); } mDirtySets.reset(); } @@ -142,6 +156,8 @@ namespace dawn_native { namespace vulkan { PipelineLayout* mCurrentLayout = nullptr; std::array mSets; std::bitset mDirtySets; + std::array mDynamicOffsetCounts; + std::array, kMaxBindGroups> mDynamicOffsets; }; void RecordBeginRenderPass(VkCommandBuffer commands, @@ -414,8 +430,13 @@ namespace dawn_native { namespace vulkan { case Command::SetBindGroup: { SetBindGroupCmd* cmd = mCommands.NextCommand(); VkDescriptorSet set = ToBackend(cmd->group.Get())->GetHandle(); + uint64_t* dynamicOffsets = nullptr; + if (cmd->dynamicOffsetCount > 0) { + dynamicOffsets = mCommands.NextData(cmd->dynamicOffsetCount); + } - descriptorSets.OnSetBindGroup(cmd->index, set); + descriptorSets.OnSetBindGroup(cmd->index, set, cmd->dynamicOffsetCount, + dynamicOffsets); } break; case Command::SetComputePipeline: { @@ -552,8 +573,13 @@ namespace dawn_native { namespace vulkan { case Command::SetBindGroup: { SetBindGroupCmd* cmd = mCommands.NextCommand(); VkDescriptorSet set = ToBackend(cmd->group.Get())->GetHandle(); + uint64_t* dynamicOffsets = nullptr; + if (cmd->dynamicOffsetCount > 0) { + dynamicOffsets = mCommands.NextData(cmd->dynamicOffsetCount); + } - descriptorSets.OnSetBindGroup(cmd->index, set); + descriptorSets.OnSetBindGroup(cmd->index, set, cmd->dynamicOffsetCount, + dynamicOffsets); } break; case Command::SetBlendColor: { diff --git a/src/tests/end2end/DynamicBufferOffsetTests.cpp b/src/tests/end2end/DynamicBufferOffsetTests.cpp index ba12de1458..5916d04f61 100644 --- a/src/tests/end2end/DynamicBufferOffsetTests.cpp +++ b/src/tests/end2end/DynamicBufferOffsetTests.cpp @@ -56,7 +56,6 @@ class DynamicBufferOffsetTests : public DawnTest { } // Create objects to use as resources inside test bind groups. - const void* mappedData = nullptr; dawn::BindGroup mBindGroup; dawn::BindGroupLayout mBindGroupLayout; dawn::Buffer mUniformBuffer; @@ -212,4 +211,4 @@ TEST_P(DynamicBufferOffsetTests, SetDynamicOffestsComputePipeline) { kMinDynamicBufferOffsetAlignment, expectedData.size()); } -DAWN_INSTANTIATE_TEST(DynamicBufferOffsetTests, MetalBackend); +DAWN_INSTANTIATE_TEST(DynamicBufferOffsetTests, MetalBackend, VulkanBackend);