Descriptor Update Template implementation
Basic implementation of descriptor update template.
Only supports VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET template type.
Bug b/123244275
Change-Id: Iaf7c1e52bee6d2683a2f34bd2f780396aa953442
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26568
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Vulkan/VkDescriptorSetLayout.hpp b/src/Vulkan/VkDescriptorSetLayout.hpp
index d332c28..3905a16 100644
--- a/src/Vulkan/VkDescriptorSetLayout.hpp
+++ b/src/Vulkan/VkDescriptorSetLayout.hpp
@@ -36,10 +36,10 @@
void initialize(VkDescriptorSet descriptorSet);
size_t getSize() const;
size_t getBindingOffset(uint32_t binding) const;
+ uint8_t* getOffsetPointer(VkDescriptorSet descriptorSet, uint32_t binding, uint32_t arrayElement, uint32_t count, size_t* typeSize) const;
private:
uint32_t getBindingIndex(uint32_t binding) const;
- uint8_t* getOffsetPointer(VkDescriptorSet descriptorSet, uint32_t binding, uint32_t arrayElement, uint32_t count, size_t* typeSize) const;
static const uint8_t* GetInputData(const VkWriteDescriptorSet& descriptorWrites);
VkDescriptorSetLayoutCreateFlags flags;
diff --git a/src/Vulkan/VkDescriptorUpdateTemplate.cpp b/src/Vulkan/VkDescriptorUpdateTemplate.cpp
new file mode 100644
index 0000000..903f5f2
--- /dev/null
+++ b/src/Vulkan/VkDescriptorUpdateTemplate.cpp
@@ -0,0 +1,51 @@
+// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "VkDescriptorUpdateTemplate.hpp"
+#include "VkDescriptorSetLayout.hpp"
+#include <cstring>
+
+namespace vk
+{
+ DescriptorUpdateTemplate::DescriptorUpdateTemplate(const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, void* mem) :
+ descriptorUpdateEntryCount(pCreateInfo->descriptorUpdateEntryCount),
+ descriptorUpdateEntries(reinterpret_cast<VkDescriptorUpdateTemplateEntry*>(mem)),
+ descriptorSetLayout(Cast(pCreateInfo->descriptorSetLayout))
+ {
+ for(uint32_t i = 0; i < descriptorUpdateEntryCount; i++)
+ {
+ descriptorUpdateEntries[i] = pCreateInfo->pDescriptorUpdateEntries[i];
+ }
+ }
+
+ size_t DescriptorUpdateTemplate::ComputeRequiredAllocationSize(const VkDescriptorUpdateTemplateCreateInfo* info)
+ {
+ return info->descriptorUpdateEntryCount * sizeof(VkDescriptorUpdateTemplateEntry);
+ }
+
+ void DescriptorUpdateTemplate::updateDescriptorSet(VkDescriptorSet descriptorSet, const void* pData)
+ {
+ for(uint32_t i = 0; i < descriptorUpdateEntryCount; i++)
+ {
+ for(uint32_t j = 0; j < descriptorUpdateEntries[i].descriptorCount; j++)
+ {
+ const char *memToRead = (const char *)pData + descriptorUpdateEntries[i].offset + j * descriptorUpdateEntries[i].stride;
+ size_t typeSize = 0;
+ uint8_t* memToWrite = descriptorSetLayout->getOffsetPointer(
+ descriptorSet, descriptorUpdateEntries[i].dstBinding, descriptorUpdateEntries[i].dstArrayElement, 1, &typeSize);
+ memcpy(memToWrite, memToRead, typeSize);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Vulkan/VkDescriptorUpdateTemplate.hpp b/src/Vulkan/VkDescriptorUpdateTemplate.hpp
new file mode 100644
index 0000000..cb75f22
--- /dev/null
+++ b/src/Vulkan/VkDescriptorUpdateTemplate.hpp
@@ -0,0 +1,47 @@
+// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef VK_DESCRIPTOR_UPDATE_TEMPLATE_HPP_
+#define VK_DESCRIPTOR_UPDATE_TEMPLATE_HPP_
+
+#include "VkObject.hpp"
+
+namespace vk
+{
+ class DescriptorSetLayout;
+
+ class DescriptorUpdateTemplate : public Object<DescriptorUpdateTemplate, VkDescriptorUpdateTemplate>
+ {
+ public:
+ DescriptorUpdateTemplate(const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, void* mem);
+ ~DescriptorUpdateTemplate() = delete;
+
+ static size_t ComputeRequiredAllocationSize(const VkDescriptorUpdateTemplateCreateInfo* info);
+
+ void updateDescriptorSet(VkDescriptorSet descriptorSet, const void* pData);
+
+ private:
+ uint32_t descriptorUpdateEntryCount = 0;
+ VkDescriptorUpdateTemplateEntry* descriptorUpdateEntries = nullptr;
+ DescriptorSetLayout* descriptorSetLayout = nullptr;
+ };
+
+ static inline DescriptorUpdateTemplate* Cast(VkDescriptorUpdateTemplate object)
+ {
+ return reinterpret_cast<DescriptorUpdateTemplate*>(object);
+ }
+
+} // namespace vk
+
+#endif // VK_DESCRIPTOR_UPDATE_TEMPLATE_HPP_
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 5b2f735..26ac1d8 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -20,6 +20,7 @@
#include "VkDebug.hpp"
#include "VkDescriptorPool.hpp"
#include "VkDescriptorSetLayout.hpp"
+#include "VkDescriptorUpdateTemplate.hpp"
#include "VkDestroy.h"
#include "VkDevice.hpp"
#include "VkDeviceMemory.hpp"
@@ -2032,21 +2033,31 @@
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplate(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate)
{
- TRACE("()");
- UNIMPLEMENTED();
- return VK_SUCCESS;
+ TRACE("(VkDevice device = 0x%X, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate = 0x%X)",
+ device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
+
+ if(pCreateInfo->pNext || pCreateInfo->flags || (pCreateInfo->templateType != VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET))
+ {
+ UNIMPLEMENTED();
+ }
+
+ return vk::DescriptorUpdateTemplate::Create(pAllocator, pCreateInfo, pDescriptorUpdateTemplate);
}
VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplate(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator)
{
- TRACE("()");
- UNIMPLEMENTED();
+ TRACE("(VkDevice device = 0x%X, VkDescriptorUpdateTemplate descriptorUpdateTemplate = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
+ device, descriptorUpdateTemplate, pAllocator);
+
+ vk::destroy(descriptorUpdateTemplate, pAllocator);
}
VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData)
{
- TRACE("()");
- UNIMPLEMENTED();
+ TRACE("(VkDevice device = 0x%X, VkDescriptorSet descriptorSet = 0x%X, VkDescriptorUpdateTemplate descriptorUpdateTemplate = 0x%X, const void* pData = 0x%X)",
+ device, descriptorSet, descriptorUpdateTemplate, pData);
+
+ vk::Cast(descriptorUpdateTemplate)->updateDescriptorSet(descriptorSet, pData);
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties)
diff --git a/src/Vulkan/vulkan.vcxproj b/src/Vulkan/vulkan.vcxproj
index 65dad9e..0328234 100644
--- a/src/Vulkan/vulkan.vcxproj
+++ b/src/Vulkan/vulkan.vcxproj
@@ -106,6 +106,7 @@
<ClCompile Include="VkDebug.cpp" />
<ClCompile Include="VkDescriptorPool.cpp" />
<ClCompile Include="VkDescriptorSetLayout.cpp" />
+ <ClCompile Include="VkDescriptorUpdateTemplate.cpp" />
<ClCompile Include="VkDevice.cpp" />
<ClCompile Include="VkDeviceMemory.cpp" />
<ClCompile Include="VkFramebuffer.cpp" />
@@ -202,6 +203,7 @@
<ClInclude Include="VkDebug.hpp" />
<ClInclude Include="VkDescriptorPool.hpp" />
<ClInclude Include="VkDescriptorSetLayout.hpp" />
+ <ClInclude Include="VkDescriptorUpdateTemplate.hpp" />
<ClInclude Include="VkDestroy.h" />
<ClInclude Include="VkDevice.hpp" />
<ClInclude Include="VkDeviceMemory.hpp" />
diff --git a/src/Vulkan/vulkan.vcxproj.filters b/src/Vulkan/vulkan.vcxproj.filters
index 522de29..06eef79 100644
--- a/src/Vulkan/vulkan.vcxproj.filters
+++ b/src/Vulkan/vulkan.vcxproj.filters
@@ -210,6 +210,9 @@
<ClCompile Include="VkDescriptorSetLayout.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
+ <ClCompile Include="VkDescriptorUpdateTemplate.cpp">
+ <Filter>Source Files\Vulkan</Filter>
+ </ClCompile>
<ClCompile Include="VkDevice.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
@@ -290,6 +293,9 @@
<ClInclude Include="VkDescriptorSetLayout.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
+ <ClInclude Include="VkDescriptorUpdateTemplate.hpp">
+ <Filter>Header Files\Vulkan</Filter>
+ </ClInclude>
<ClInclude Include="VkDevice.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>