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++;
 			}
 		}
 	}