Fix DescriptorUpdateTemplate::updateDescriptorSet
The logic did not handle desciptor arrays, or the descriptor overflow case.
Bug: b/123244275
Tests: *with_template*
Change-Id: Idf3f70848136865d1d76dc4f2f41b4c35d9230db
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28388
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Vulkan/VkDescriptorSetLayout.cpp b/src/Vulkan/VkDescriptorSetLayout.cpp
index 7a5dcca..80a0bec 100644
--- a/src/Vulkan/VkDescriptorSetLayout.cpp
+++ b/src/Vulkan/VkDescriptorSetLayout.cpp
@@ -220,8 +220,8 @@
VkDescriptorSetLayoutBinding const & DescriptorSetLayout::getBindingLayout(uint32_t binding) const
{
- ASSERT(binding < bindingCount);
- return bindings[binding];
+ uint32_t index = getBindingIndex(binding);
+ return bindings[index];
}
uint8_t* DescriptorSetLayout::getOffsetPointer(DescriptorSet *descriptorSet, uint32_t binding, uint32_t arrayElement, uint32_t count, size_t* typeSize) const
diff --git a/src/Vulkan/VkDescriptorSetLayout.hpp b/src/Vulkan/VkDescriptorSetLayout.hpp
index b086626..70ff227 100644
--- a/src/Vulkan/VkDescriptorSetLayout.hpp
+++ b/src/Vulkan/VkDescriptorSetLayout.hpp
@@ -62,8 +62,7 @@
// VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
bool isBindingDynamic(uint32_t binding) const;
- // Returns the VkDescriptorSetLayoutBinding for the binding with the given
- // index.
+ // Returns the VkDescriptorSetLayoutBinding for the given binding.
VkDescriptorSetLayoutBinding const & getBindingLayout(uint32_t binding) const;
uint8_t* getOffsetPointer(DescriptorSet *descriptorSet, uint32_t binding, uint32_t arrayElement, uint32_t count, size_t* typeSize) const;
diff --git a/src/Vulkan/VkDescriptorUpdateTemplate.cpp b/src/Vulkan/VkDescriptorUpdateTemplate.cpp
index 1b72419..2a1400f 100644
--- a/src/Vulkan/VkDescriptorUpdateTemplate.cpp
+++ b/src/Vulkan/VkDescriptorUpdateTemplate.cpp
@@ -41,13 +41,33 @@
for(uint32_t i = 0; i < descriptorUpdateEntryCount; i++)
{
- for(uint32_t j = 0; j < descriptorUpdateEntries[i].descriptorCount; j++)
+ auto const &entry = descriptorUpdateEntries[i];
+ auto binding = entry.dstBinding;
+ auto arrayElement = entry.dstArrayElement;
+ for (uint32_t descriptorIndex = 0; descriptorIndex < entry.descriptorCount; descriptorIndex++)
{
- const char *memToRead = (const char *)pData + descriptorUpdateEntries[i].offset + j * descriptorUpdateEntries[i].stride;
+ while (arrayElement == descriptorSetLayout->getBindingLayout(binding).descriptorCount)
+ {
+ // If descriptorCount is greater than the number of remaining
+ // array elements in the destination binding, those affect
+ // consecutive bindings in a manner similar to
+ // VkWriteDescriptorSet.
+ // If a binding has a descriptorCount of zero, it is skipped.
+ arrayElement = 0;
+ binding++;
+ }
+
+ uint8_t *memToRead = (uint8_t *)pData + entry.offset + descriptorIndex * entry.stride;
size_t typeSize = 0;
uint8_t* memToWrite = descriptorSetLayout->getOffsetPointer(
- descriptorSet, descriptorUpdateEntries[i].dstBinding, descriptorUpdateEntries[i].dstArrayElement, 1, &typeSize);
+ descriptorSet,
+ binding,
+ arrayElement,
+ 1, // count
+ &typeSize);
memcpy(memToWrite, memToRead, typeSize);
+
+ arrayElement++;
}
}
}