mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-05 09:26:25 +00:00
GPU Vulkan: Fix render pass race (#12587)
This commit is contained in:
@@ -1175,6 +1175,7 @@ struct VulkanRenderer
|
|||||||
SDL_Mutex *submitLock;
|
SDL_Mutex *submitLock;
|
||||||
SDL_Mutex *acquireCommandBufferLock;
|
SDL_Mutex *acquireCommandBufferLock;
|
||||||
SDL_Mutex *acquireUniformBufferLock;
|
SDL_Mutex *acquireUniformBufferLock;
|
||||||
|
SDL_Mutex *renderPassFetchLock;
|
||||||
SDL_Mutex *framebufferFetchLock;
|
SDL_Mutex *framebufferFetchLock;
|
||||||
SDL_Mutex *windowLock;
|
SDL_Mutex *windowLock;
|
||||||
|
|
||||||
@@ -4889,6 +4890,7 @@ static void VULKAN_DestroyDevice(
|
|||||||
SDL_DestroyMutex(renderer->submitLock);
|
SDL_DestroyMutex(renderer->submitLock);
|
||||||
SDL_DestroyMutex(renderer->acquireCommandBufferLock);
|
SDL_DestroyMutex(renderer->acquireCommandBufferLock);
|
||||||
SDL_DestroyMutex(renderer->acquireUniformBufferLock);
|
SDL_DestroyMutex(renderer->acquireUniformBufferLock);
|
||||||
|
SDL_DestroyMutex(renderer->renderPassFetchLock);
|
||||||
SDL_DestroyMutex(renderer->framebufferFetchLock);
|
SDL_DestroyMutex(renderer->framebufferFetchLock);
|
||||||
SDL_DestroyMutex(renderer->windowLock);
|
SDL_DestroyMutex(renderer->windowLock);
|
||||||
|
|
||||||
@@ -7034,12 +7036,15 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass(
|
|||||||
key.depthStencilTargetDescription.stencilStoreOp = depthStencilTargetInfo->stencil_store_op;
|
key.depthStencilTargetDescription.stencilStoreOp = depthStencilTargetInfo->stencil_store_op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_LockMutex(renderer->renderPassFetchLock);
|
||||||
|
|
||||||
bool result = SDL_FindInHashTable(
|
bool result = SDL_FindInHashTable(
|
||||||
renderer->renderPassHashTable,
|
renderer->renderPassHashTable,
|
||||||
(const void *)&key,
|
(const void *)&key,
|
||||||
(const void **)&renderPassWrapper);
|
(const void **)&renderPassWrapper);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
|
SDL_UnlockMutex(renderer->renderPassFetchLock);
|
||||||
return renderPassWrapper->handle;
|
return renderPassWrapper->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7050,6 +7055,7 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass(
|
|||||||
depthStencilTargetInfo);
|
depthStencilTargetInfo);
|
||||||
|
|
||||||
if (renderPassHandle == VK_NULL_HANDLE) {
|
if (renderPassHandle == VK_NULL_HANDLE) {
|
||||||
|
SDL_UnlockMutex(renderer->renderPassFetchLock);
|
||||||
return VK_NULL_HANDLE;
|
return VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7065,6 +7071,8 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass(
|
|||||||
(const void *)allocedKey,
|
(const void *)allocedKey,
|
||||||
(const void *)renderPassWrapper, true);
|
(const void *)renderPassWrapper, true);
|
||||||
|
|
||||||
|
SDL_UnlockMutex(renderer->renderPassFetchLock);
|
||||||
|
|
||||||
return renderPassHandle;
|
return renderPassHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7133,9 +7141,8 @@ static VulkanFramebuffer *VULKAN_INTERNAL_FetchFramebuffer(
|
|||||||
(const void *)&key,
|
(const void *)&key,
|
||||||
(const void **)&vulkanFramebuffer);
|
(const void **)&vulkanFramebuffer);
|
||||||
|
|
||||||
SDL_UnlockMutex(renderer->framebufferFetchLock);
|
|
||||||
|
|
||||||
if (findResult) {
|
if (findResult) {
|
||||||
|
SDL_UnlockMutex(renderer->framebufferFetchLock);
|
||||||
return vulkanFramebuffer;
|
return vulkanFramebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7203,19 +7210,18 @@ static VulkanFramebuffer *VULKAN_INTERNAL_FetchFramebuffer(
|
|||||||
FramebufferHashTableKey *allocedKey = SDL_malloc(sizeof(FramebufferHashTableKey));
|
FramebufferHashTableKey *allocedKey = SDL_malloc(sizeof(FramebufferHashTableKey));
|
||||||
SDL_memcpy(allocedKey, &key, sizeof(FramebufferHashTableKey));
|
SDL_memcpy(allocedKey, &key, sizeof(FramebufferHashTableKey));
|
||||||
|
|
||||||
SDL_LockMutex(renderer->framebufferFetchLock);
|
|
||||||
|
|
||||||
SDL_InsertIntoHashTable(
|
SDL_InsertIntoHashTable(
|
||||||
renderer->framebufferHashTable,
|
renderer->framebufferHashTable,
|
||||||
(const void *)allocedKey,
|
(const void *)allocedKey,
|
||||||
(const void *)vulkanFramebuffer, true);
|
(const void *)vulkanFramebuffer, true);
|
||||||
|
|
||||||
SDL_UnlockMutex(renderer->framebufferFetchLock);
|
|
||||||
} else {
|
} else {
|
||||||
SDL_free(vulkanFramebuffer);
|
SDL_free(vulkanFramebuffer);
|
||||||
|
SDL_UnlockMutex(renderer->framebufferFetchLock);
|
||||||
CHECK_VULKAN_ERROR_AND_RETURN(result, vkCreateFramebuffer, NULL);
|
CHECK_VULKAN_ERROR_AND_RETURN(result, vkCreateFramebuffer, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_UnlockMutex(renderer->framebufferFetchLock);
|
||||||
return vulkanFramebuffer;
|
return vulkanFramebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11607,6 +11613,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
|||||||
renderer->submitLock = SDL_CreateMutex();
|
renderer->submitLock = SDL_CreateMutex();
|
||||||
renderer->acquireCommandBufferLock = SDL_CreateMutex();
|
renderer->acquireCommandBufferLock = SDL_CreateMutex();
|
||||||
renderer->acquireUniformBufferLock = SDL_CreateMutex();
|
renderer->acquireUniformBufferLock = SDL_CreateMutex();
|
||||||
|
renderer->renderPassFetchLock = SDL_CreateMutex();
|
||||||
renderer->framebufferFetchLock = SDL_CreateMutex();
|
renderer->framebufferFetchLock = SDL_CreateMutex();
|
||||||
renderer->windowLock = SDL_CreateMutex();
|
renderer->windowLock = SDL_CreateMutex();
|
||||||
|
|
||||||
@@ -11668,7 +11675,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
|||||||
|
|
||||||
renderer->renderPassHashTable = SDL_CreateHashTable(
|
renderer->renderPassHashTable = SDL_CreateHashTable(
|
||||||
0, // !!! FIXME: a real guess here, for a _minimum_ if not a maximum, could be useful.
|
0, // !!! FIXME: a real guess here, for a _minimum_ if not a maximum, could be useful.
|
||||||
true, // thread-safe
|
false, // manually synchronized due to timing
|
||||||
VULKAN_INTERNAL_RenderPassHashFunction,
|
VULKAN_INTERNAL_RenderPassHashFunction,
|
||||||
VULKAN_INTERNAL_RenderPassHashKeyMatch,
|
VULKAN_INTERNAL_RenderPassHashKeyMatch,
|
||||||
VULKAN_INTERNAL_RenderPassHashDestroy,
|
VULKAN_INTERNAL_RenderPassHashDestroy,
|
||||||
|
Reference in New Issue
Block a user