PipelineCache basic operations support
After this cl, pipeline caches remain unused at pipeline creation
time, but some basic functionalities of the pipeline cache itself
have been added:
- Initial data is copied at pipeline cache creation time
- PipelineCache objects must store a header at the beginning of the
cache
- Providing a bad size to vkGetPipelineCacheData will now return
VK_INCOMPLETE
Also fixed a few tracing strings in libVulkan.cpp.
Bug b/123588002
Change-Id: Icc0aadbe6a60bf3d2b9d3a43132d26671f60c728
Tests: dEQP-VK.pipeline.cache.*
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28430
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Vulkan/VkPipelineCache.cpp b/src/Vulkan/VkPipelineCache.cpp
new file mode 100644
index 0000000..e0890f1
--- /dev/null
+++ b/src/Vulkan/VkPipelineCache.cpp
@@ -0,0 +1,79 @@
+// Copyright 2019 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 "VkPipelineCache.hpp"
+#include <cstring>
+
+namespace vk
+{
+
+PipelineCache::PipelineCache(const VkPipelineCacheCreateInfo* pCreateInfo, void* mem) :
+ dataSize(ComputeRequiredAllocationSize(pCreateInfo)), data(reinterpret_cast<uint8_t*>(mem))
+{
+ CacheHeader* header = reinterpret_cast<CacheHeader*>(mem);
+ header->headerLength = sizeof(CacheHeader);
+ header->headerVersion = VK_PIPELINE_CACHE_HEADER_VERSION_ONE;
+ header->vendorID = VENDOR_ID;
+ header->deviceID = DEVICE_ID;
+ memcpy(header->pipelineCacheUUID, SWIFTSHADER_UUID, VK_UUID_SIZE);
+
+ if(pCreateInfo->pInitialData && (pCreateInfo->initialDataSize > 0))
+ {
+ memcpy(data + sizeof(CacheHeader), pCreateInfo->pInitialData, pCreateInfo->initialDataSize);
+ }
+}
+
+void PipelineCache::destroy(const VkAllocationCallbacks* pAllocator)
+{
+ vk::deallocate(data, pAllocator);
+}
+
+size_t PipelineCache::ComputeRequiredAllocationSize(const VkPipelineCacheCreateInfo* pCreateInfo)
+{
+ return pCreateInfo->initialDataSize + sizeof(CacheHeader);
+}
+
+VkResult PipelineCache::getData(size_t* pDataSize, void* pData)
+{
+ if(!pData)
+ {
+ *pDataSize = dataSize;
+ return VK_SUCCESS;
+ }
+
+ if(*pDataSize != dataSize)
+ {
+ *pDataSize = 0;
+ return VK_INCOMPLETE;
+ }
+
+ if(*pDataSize > 0)
+ {
+ memcpy(pData, data, *pDataSize);
+ }
+
+ return VK_SUCCESS;
+}
+
+VkResult PipelineCache::merge(uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches)
+{
+ for(uint32_t i = 0; i < srcCacheCount; i++)
+ {
+ // TODO (b/123588002): merge pSrcCaches[i];
+ }
+
+ return VK_SUCCESS;
+}
+
+} // namespace vk
diff --git a/src/Vulkan/VkPipelineCache.hpp b/src/Vulkan/VkPipelineCache.hpp
index 6218394..927c7a2 100644
--- a/src/Vulkan/VkPipelineCache.hpp
+++ b/src/Vulkan/VkPipelineCache.hpp
@@ -23,18 +23,27 @@
class PipelineCache : public Object<PipelineCache, VkPipelineCache>
{
public:
- PipelineCache(const VkPipelineCacheCreateInfo* pCreateInfo, void* mem)
- {
- }
-
+ PipelineCache(const VkPipelineCacheCreateInfo* pCreateInfo, void* mem);
~PipelineCache() = delete;
+ void destroy(const VkAllocationCallbacks* pAllocator);
- static size_t ComputeRequiredAllocationSize(const VkPipelineCacheCreateInfo* pCreateInfo)
- {
- return 0;
- }
+ static size_t ComputeRequiredAllocationSize(const VkPipelineCacheCreateInfo* pCreateInfo);
+
+ VkResult getData(size_t* pDataSize, void* pData);
+ VkResult merge(uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches);
private:
+ struct CacheHeader
+ {
+ uint32_t headerLength;
+ uint32_t headerVersion;
+ uint32_t vendorID;
+ uint32_t deviceID;
+ uint8_t pipelineCacheUUID[VK_UUID_SIZE];
+ };
+
+ size_t dataSize = 0;
+ uint8_t* data = nullptr;
};
static inline PipelineCache* Cast(VkPipelineCache object)
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 10d0048..c5b9939 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -676,8 +676,8 @@
VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
{
- TRACE("(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements)",
- device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
+ TRACE("(VkDevice device = 0x%X, VkImage image = 0x%X, uint32_t* pSparseMemoryRequirementCount = 0x%X, VkSparseImageMemoryRequirements* pSparseMemoryRequirements = 0x%X)",
+ device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
// The 'sparseBinding' feature is not supported, so images can not be created with the VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT flag.
// "If the image was not created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then pSparseMemoryRequirementCount will be set to zero and pSparseMemoryRequirements will not be written to."
@@ -686,7 +686,7 @@
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties)
{
- TRACE("(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties)",
+ TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkFormat format = %d, VkImageType type = %d, VkSampleCountFlagBits samples = %d, VkImageUsageFlags usage = %d, VkImageTiling tiling = %d, uint32_t* pPropertyCount = 0x%X, VkSparseImageFormatProperties* pProperties = 0x%X)",
physicalDevice, format, type, samples, usage, tiling, pPropertyCount, pProperties);
// We do not support sparse images.
@@ -873,8 +873,8 @@
VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView)
{
- TRACE("(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView)",
- device, pCreateInfo, pAllocator, pView);
+ TRACE("(VkDevice device = 0x%X, const VkBufferViewCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkBufferView* pView = 0x%X)",
+ device, pCreateInfo, pAllocator, pView);
if(pCreateInfo->pNext || pCreateInfo->flags)
{
@@ -886,8 +886,8 @@
VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator)
{
- TRACE("(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator)",
- device, bufferView, pAllocator);
+ TRACE("(VkDevice device = 0x%X, VkBufferView bufferView = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
+ device, bufferView, pAllocator);
vk::destroy(bufferView, pAllocator);
}
@@ -921,8 +921,8 @@
VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout)
{
- TRACE("(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout)",
- device, image, pSubresource, pLayout);
+ TRACE("(VkDevice device = 0x%X, VkImage image = 0x%X, const VkImageSubresource* pSubresource = 0x%X, VkSubresourceLayout* pLayout = 0x%X)",
+ device, image, pSubresource, pLayout);
vk::Cast(image)->getSubresourceLayout(pSubresource, pLayout);
}
@@ -1003,8 +1003,8 @@
VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache)
{
- TRACE("(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache)",
- device, pCreateInfo, pAllocator, pPipelineCache);
+ TRACE("(VkDevice device = 0x%X, const VkPipelineCacheCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkPipelineCache* pPipelineCache = 0x%X)",
+ device, pCreateInfo, pAllocator, pPipelineCache);
if(pCreateInfo->pNext || pCreateInfo->flags)
{
@@ -1016,24 +1016,26 @@
VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator)
{
- TRACE("(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator)",
- device, pipelineCache, pAllocator);
+ TRACE("(VkDevice device = 0x%X, VkPipelineCache pipelineCache = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
+ device, pipelineCache, pAllocator);
vk::destroy(pipelineCache, pAllocator);
}
VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData)
{
- TRACE("()");
- UNIMPLEMENTED("vkGetPipelineCacheData");
- return VK_SUCCESS;
+ TRACE("(VkDevice device = 0x%X, VkPipelineCache pipelineCache = 0x%X, size_t* pDataSize = 0x%X, void* pData = 0x%X)",
+ device, pipelineCache, pDataSize, pData);
+
+ return vk::Cast(pipelineCache)->getData(pDataSize, pData);
}
VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches)
{
- TRACE("()");
- UNIMPLEMENTED("vkMergePipelineCaches");
- return VK_SUCCESS;
+ TRACE("(VkDevice device = 0x%X, VkPipelineCache dstCache = 0x%X, uint32_t srcCacheCount = %d, const VkPipelineCache* pSrcCaches = 0x%X)",
+ device, dstCache, srcCacheCount, pSrcCaches);
+
+ return vk::Cast(dstCache)->merge(srcCacheCount, pSrcCaches);
}
VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
@@ -2251,8 +2253,8 @@
VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport)
{
- TRACE("(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport)",
- device, pCreateInfo, pSupport);
+ TRACE("(VkDevice device = 0x%X, const VkDescriptorSetLayoutCreateInfo* pCreateInfo = 0x%X, VkDescriptorSetLayoutSupport* pSupport = 0x%X)",
+ device, pCreateInfo, pSupport);
vk::Cast(device)->getDescriptorSetLayoutSupport(pCreateInfo, pSupport);
}
diff --git a/src/Vulkan/vulkan.vcxproj b/src/Vulkan/vulkan.vcxproj
index c60dd20..f8e95ad 100644
--- a/src/Vulkan/vulkan.vcxproj
+++ b/src/Vulkan/vulkan.vcxproj
@@ -125,6 +125,7 @@
<ClCompile Include="VkMemory.cpp" />
<ClCompile Include="VkPhysicalDevice.cpp" />
<ClCompile Include="VkPipeline.cpp" />
+ <ClCompile Include="VkPipelineCache.cpp" />
<ClCompile Include="VkPipelineLayout.cpp" />
<ClCompile Include="VkPromotedExtensions.cpp" />
<ClCompile Include="VkQueryPool.cpp" />
diff --git a/src/Vulkan/vulkan.vcxproj.filters b/src/Vulkan/vulkan.vcxproj.filters
index aaa9bf6..3b95e02 100644
--- a/src/Vulkan/vulkan.vcxproj.filters
+++ b/src/Vulkan/vulkan.vcxproj.filters
@@ -225,6 +225,9 @@
<ClCompile Include="VkPipeline.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
+ <ClCompile Include="VkPipelineCache.cpp">
+ <Filter>Source Files\Vulkan</Filter>
+ </ClCompile>
<ClCompile Include="VkPipelineLayout.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>