Skip to content

Commit 06bf8d1

Browse files
whrvtslouken
authored andcommitted
gpu_vulkan: Set texture container before transitioning to default barrier state.
Avoids a null dereference of currentRegion->vulkanTexture->container in DefragmentMemory: } else if (!currentRegion->isBuffer && !currentRegion->vulkanTexture->markedForDestroy) { ... &currentRegion->vulkanTexture->container->header.info ... (among others) by not "VULKAN_Submit"ting (and thus adding it to the defrag pool) before setting the container. Although rare (defrag almost never ran), this crash happened in a real-world application.
1 parent 1296270 commit 06bf8d1

File tree

1 file changed

+18
-19
lines changed

1 file changed

+18
-19
lines changed

src/gpu/vulkan/SDL_gpu_vulkan.c

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,7 @@ struct VulkanRenderer
12691269

12701270
static bool VULKAN_INTERNAL_DefragmentMemory(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer);
12711271
static bool VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer);
1272+
static void VULKAN_ReleaseTexture(SDL_GPURenderer *driverData, SDL_GPUTexture *texture);
12721273
static void VULKAN_ReleaseWindow(SDL_GPURenderer *driverData, SDL_Window *window);
12731274
static bool VULKAN_Wait(SDL_GPURenderer *driverData);
12741275
static bool VULKAN_WaitForFences(SDL_GPURenderer *driverData, bool waitAll, SDL_GPUFence *const *fences, Uint32 numFences);
@@ -5654,7 +5655,6 @@ static void VULKAN_PopDebugGroup(
56545655

56555656
static VulkanTexture *VULKAN_INTERNAL_CreateTexture(
56565657
VulkanRenderer *renderer,
5657-
bool transitionToDefaultLayout,
56585658
const SDL_GPUTextureCreateInfo *createinfo)
56595659
{
56605660
VkResult vulkanResult;
@@ -5882,21 +5882,6 @@ static VulkanTexture *VULKAN_INTERNAL_CreateTexture(
58825882
&nameInfo);
58835883
}
58845884

5885-
if (transitionToDefaultLayout) {
5886-
// Let's transition to the default barrier state, because for some reason Vulkan doesn't let us do that with initialLayout.
5887-
VulkanCommandBuffer *barrierCommandBuffer = (VulkanCommandBuffer *)VULKAN_AcquireCommandBuffer((SDL_GPURenderer *)renderer);
5888-
VULKAN_INTERNAL_TextureTransitionToDefaultUsage(
5889-
renderer,
5890-
barrierCommandBuffer,
5891-
VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED,
5892-
texture);
5893-
VULKAN_INTERNAL_TrackTexture(barrierCommandBuffer, texture);
5894-
if (!VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer)) {
5895-
VULKAN_INTERNAL_DestroyTexture(renderer, texture);
5896-
return NULL;
5897-
}
5898-
}
5899-
59005885
return texture;
59015886
}
59025887

@@ -5963,7 +5948,6 @@ static void VULKAN_INTERNAL_CycleActiveTexture(
59635948
// No texture is available, generate a new one.
59645949
texture = VULKAN_INTERNAL_CreateTexture(
59655950
renderer,
5966-
false,
59675951
&container->header.info);
59685952

59695953
VULKAN_INTERNAL_TextureTransitionToDefaultUsage(
@@ -6865,7 +6849,6 @@ static SDL_GPUTexture *VULKAN_CreateTexture(
68656849

68666850
texture = VULKAN_INTERNAL_CreateTexture(
68676851
renderer,
6868-
true,
68696852
createinfo);
68706853

68716854
if (texture == NULL) {
@@ -6897,6 +6880,23 @@ static SDL_GPUTexture *VULKAN_CreateTexture(
68976880
texture->container = container;
68986881
texture->containerIndex = 0;
68996882

6883+
// Let's transition to the default barrier state, because for some reason Vulkan doesn't let us do that with initialLayout.
6884+
// Only do this after "container" is set, so the texture
6885+
// is fully initialized before any Submit that could trigger defrag.
6886+
{
6887+
VulkanCommandBuffer *barrierCommandBuffer = (VulkanCommandBuffer *)VULKAN_AcquireCommandBuffer((SDL_GPURenderer *)renderer);
6888+
VULKAN_INTERNAL_TextureTransitionToDefaultUsage(
6889+
renderer,
6890+
barrierCommandBuffer,
6891+
VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED,
6892+
texture);
6893+
VULKAN_INTERNAL_TrackTexture(barrierCommandBuffer, texture);
6894+
if (!VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer)) {
6895+
VULKAN_ReleaseTexture((SDL_GPURenderer *)renderer, (SDL_GPUTexture *)container);
6896+
return NULL;
6897+
}
6898+
}
6899+
69006900
return (SDL_GPUTexture *)container;
69016901
}
69026902

@@ -10950,7 +10950,6 @@ static bool VULKAN_INTERNAL_DefragmentMemory(
1095010950
} else if (!currentRegion->isBuffer && !currentRegion->vulkanTexture->markedForDestroy) {
1095110951
VulkanTexture *newTexture = VULKAN_INTERNAL_CreateTexture(
1095210952
renderer,
10953-
false,
1095410953
&currentRegion->vulkanTexture->container->header.info);
1095510954

1095610955
if (newTexture == NULL) {

0 commit comments

Comments
 (0)