Commit 322220a0 by Tim Van Patten Committed by Commit Bot

Vulkan: Ignore VK_INCOMPLETE from vkGetPipelineCacheData

When getting the data store from a pipeline cache, we do the following sequence: 1.) Query the amount of data to get. 2.) Create a buffer to hold that data. 3.) Request that amount of pipeline cache data. This typically works without errors, but we have seen cases where the amount of pipeline cache data changes between steps (1) and (3). This leads to the driver returning VK_INCOMPLETE because we requested a different amount of data than the driver currently has (either too much or too little). However, getting at least the pipeline cache header is all that's required, so this isn't necessarily an error: From the Vulkan spec: > 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. This change will update ANGLE to ignore VK_INCOMPLETE, rather than treating it as an error. Bug: angleproject:3988 Test: Android dEQP-GLES2.* Change-Id: I6518d7cb00c26ae403b58aafa86a600fa7a8504a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1900009Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Tim Van Patten <timvp@google.com>
parent 6072d056
...@@ -1556,12 +1556,20 @@ angle::Result RendererVk::syncPipelineCacheVk(DisplayVk *displayVk) ...@@ -1556,12 +1556,20 @@ angle::Result RendererVk::syncPipelineCacheVk(DisplayVk *displayVk)
size_t pipelineCacheSize = 0; size_t pipelineCacheSize = 0;
ANGLE_TRY(getPipelineCacheSize(displayVk, &pipelineCacheSize)); ANGLE_TRY(getPipelineCacheSize(displayVk, &pipelineCacheSize));
// Make sure we will receive enough data to hold the pipeline cache header
// Table 7. Layout for pipeline cache header version VK_PIPELINE_CACHE_HEADER_VERSION_ONE
const size_t kPipelineCacheHeaderSize = 16 + VK_UUID_SIZE;
if (pipelineCacheSize < kPipelineCacheHeaderSize)
{
// No pipeline cache data to read, so return
return angle::Result::Continue;
}
angle::MemoryBuffer *pipelineCacheData = nullptr; angle::MemoryBuffer *pipelineCacheData = nullptr;
ANGLE_VK_CHECK_ALLOC(displayVk, ANGLE_VK_CHECK_ALLOC(displayVk,
displayVk->getScratchBuffer(pipelineCacheSize, &pipelineCacheData)); displayVk->getScratchBuffer(pipelineCacheSize, &pipelineCacheData));
size_t originalPipelineCacheSize = pipelineCacheSize; size_t oldPipelineCacheSize = pipelineCacheSize;
VkResult result = VkResult result =
mPipelineCache.getCacheData(mDevice, &pipelineCacheSize, pipelineCacheData->data()); 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 // We don't need all of the cache data, so just make sure we at least got the header
...@@ -1571,16 +1579,20 @@ angle::Result RendererVk::syncPipelineCacheVk(DisplayVk *displayVk) ...@@ -1571,16 +1579,20 @@ angle::Result RendererVk::syncPipelineCacheVk(DisplayVk *displayVk)
// pData and zero will be written to pDataSize. // 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 // Any data written to pData is valid and can be provided as the pInitialData member of the
// VkPipelineCacheCreateInfo structure passed to vkCreatePipelineCache. // VkPipelineCacheCreateInfo structure passed to vkCreatePipelineCache.
if (ANGLE_UNLIKELY(result == VK_INCOMPLETE) || (pipelineCacheSize == 0)) if (ANGLE_UNLIKELY(pipelineCacheSize < kPipelineCacheHeaderSize))
{ {
size_t intermediatePipelineCacheSize = pipelineCacheSize; WARN() << "Not enough pipeline cache data read.";
ANGLE_TRY(getPipelineCacheSize(displayVk, &pipelineCacheSize)); return angle::Result::Continue;
ERR() << "Pipeline cache size changed: old = " << originalPipelineCacheSize }
<< ", intermediate = " << intermediatePipelineCacheSize else if (ANGLE_UNLIKELY(result == VK_INCOMPLETE))
<< ", current = " << pipelineCacheData; {
WARN() << "Received VK_INCOMPLETE: Old: " << oldPipelineCacheSize
<< ", New: " << pipelineCacheSize;
}
else
{
ANGLE_VK_TRY(displayVk, result);
} }
// 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 // If vkGetPipelineCacheData ends up writing fewer bytes than requested, zero out the rest of
// the buffer to avoid leaking garbage memory. // the buffer to avoid leaking garbage memory.
......
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