Commit 4a80ba25 by Tim Van Patten Committed by Commit Bot

Vulkan: Ignore VK_INCOMPLETE from vkGetPipelineCacheData

From vkGetPipelineCacheData(3) Manual Page: If pDataSize is less than the maximum size that can be retrieved by the pipeline cache, at most pDataSize bytes will be written to pData, and vkGetPipelineCacheData will return VK_INCOMPLETE. Any data written to pData is valid and can be provided as the pInitialData member of the VkPipelineCacheCreateInfo structure passed to vkCreatePipelineCache. Bug: angleproject:3988 Test: CQ, CtsOpenGLTestCases Change-Id: I34589ee3c9e27839a9cd0168b4a2186f4cbb255e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1854680 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: 's avatarTobin Ehlis <tobine@google.com>
parent 68591eff
......@@ -1485,6 +1485,14 @@ angle::Result RendererVk::getPipelineLayout(
pipelineLayoutOut);
}
angle::Result RendererVk::getPipelineCacheSize(DisplayVk *displayVk, size_t *pipelineCacheSizeOut)
{
VkResult result = mPipelineCache.getCacheData(mDevice, pipelineCacheSizeOut, nullptr);
ANGLE_VK_TRY(displayVk, result);
return angle::Result::Continue;
}
angle::Result RendererVk::syncPipelineCacheVk(DisplayVk *displayVk)
{
// TODO: Synchronize access to the pipeline/blob caches?
......@@ -1502,33 +1510,41 @@ angle::Result RendererVk::syncPipelineCacheVk(DisplayVk *displayVk)
mPipelineCacheVkUpdateTimeout = kPipelineCacheVkUpdatePeriod;
// Get the size of the cache.
size_t pipelineCacheSize = 0;
VkResult result = mPipelineCache.getCacheData(mDevice, &pipelineCacheSize, nullptr);
if (result != VK_INCOMPLETE)
{
ANGLE_VK_TRY(displayVk, result);
}
ANGLE_TRY(getPipelineCacheSize(displayVk, &pipelineCacheSize));
angle::MemoryBuffer *pipelineCacheData = nullptr;
ANGLE_VK_CHECK_ALLOC(displayVk,
displayVk->getScratchBuffer(pipelineCacheSize, &pipelineCacheData));
size_t originalPipelineCacheSize = pipelineCacheSize;
result = mPipelineCache.getCacheData(mDevice, &pipelineCacheSize, pipelineCacheData->data());
// Note: currently we don't accept incomplete as we don't expect it (the full size of cache
// was determined just above), so receiving it hints at an implementation bug we would want
// to know about early.
ASSERT(result != VK_INCOMPLETE);
VkResult result =
mPipelineCache.getCacheData(mDevice, &pipelineCacheSize, pipelineCacheData->data());
// We don't need all of the cache data, so just make sure we at least got the header
// Vulkan Spec 9.6. Pipeline Cache
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/chap9.html#pipelines-cache
// If pDataSize is less than what is necessary to store this header, nothing will be written to
// pData and zero will be written to pDataSize.
// Any data written to pData is valid and can be provided as the pInitialData member of the
// VkPipelineCacheCreateInfo structure passed to vkCreatePipelineCache.
if (ANGLE_UNLIKELY(result == VK_INCOMPLETE) || (pipelineCacheSize == 0))
{
size_t intermediatePipelineCacheSize = pipelineCacheSize;
ANGLE_TRY(getPipelineCacheSize(displayVk, &pipelineCacheSize));
ERR() << "Pipeline cache size changed: old = " << originalPipelineCacheSize
<< ", intermediate = " << intermediatePipelineCacheSize
<< ", current = " << pipelineCacheData;
}
// TODO(http://anglebug.com/3988) Ignore VK_INCOMPLETE to reduce test flakiness
ANGLE_VK_TRY(displayVk, result);
// If vkGetPipelineCacheData ends up writing fewer bytes than requested, zero out the rest of
// the buffer to avoid leaking garbage memory.
ASSERT(pipelineCacheSize <= originalPipelineCacheSize);
if (pipelineCacheSize < originalPipelineCacheSize)
ASSERT(pipelineCacheSize <= pipelineCacheData->size());
if (pipelineCacheSize < pipelineCacheData->size())
{
memset(pipelineCacheData->data() + pipelineCacheSize, 0,
originalPipelineCacheSize - pipelineCacheSize);
pipelineCacheData->size() - pipelineCacheSize);
}
displayVk->getBlobCache()->putApplication(mPipelineCacheVkBlobKey, *pipelineCacheData);
......
......@@ -127,6 +127,7 @@ class RendererVk : angle::NonCopyable
const vk::DescriptorSetLayoutPointerArray &descriptorSetLayouts,
vk::BindingPointer<vk::PipelineLayout> *pipelineLayoutOut);
angle::Result getPipelineCacheSize(DisplayVk *displayVk, size_t *pipelineCacheSizeOut);
angle::Result syncPipelineCacheVk(DisplayVk *displayVk);
// Issues a new serial for linked shader modules. Used in the pipeline cache.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment