Skip to content

Commit 8df0436

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. (cherry picked from commit 06bf8d1)
1 parent 3b4cf41 commit 8df0436

1 file changed

Lines changed: 18 additions & 19 deletions

File tree

src/gpu/vulkan/SDL_gpu_vulkan.c

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

12221222
static bool VULKAN_INTERNAL_DefragmentMemory(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer);
12231223
static bool VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer);
1224+
static void VULKAN_ReleaseTexture(SDL_GPURenderer *driverData, SDL_GPUTexture *texture);
12241225
static void VULKAN_ReleaseWindow(SDL_GPURenderer *driverData, SDL_Window *window);
12251226
static bool VULKAN_Wait(SDL_GPURenderer *driverData);
12261227
static bool VULKAN_WaitForFences(SDL_GPURenderer *driverData, bool waitAll, SDL_GPUFence *const *fences, Uint32 numFences);
@@ -5605,7 +5606,6 @@ static void VULKAN_PopDebugGroup(
56055606

56065607
static VulkanTexture *VULKAN_INTERNAL_CreateTexture(
56075608
VulkanRenderer *renderer,
5608-
bool transitionToDefaultLayout,
56095609
const SDL_GPUTextureCreateInfo *createinfo)
56105610
{
56115611
VkResult vulkanResult;
@@ -5833,21 +5833,6 @@ static VulkanTexture *VULKAN_INTERNAL_CreateTexture(
58335833
&nameInfo);
58345834
}
58355835

5836-
if (transitionToDefaultLayout) {
5837-
// Let's transition to the default barrier state, because for some reason Vulkan doesn't let us do that with initialLayout.
5838-
VulkanCommandBuffer *barrierCommandBuffer = (VulkanCommandBuffer *)VULKAN_AcquireCommandBuffer((SDL_GPURenderer *)renderer);
5839-
VULKAN_INTERNAL_TextureTransitionToDefaultUsage(
5840-
renderer,
5841-
barrierCommandBuffer,
5842-
VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED,
5843-
texture);
5844-
VULKAN_INTERNAL_TrackTexture(barrierCommandBuffer, texture);
5845-
if (!VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer)) {
5846-
VULKAN_INTERNAL_DestroyTexture(renderer, texture);
5847-
return NULL;
5848-
}
5849-
}
5850-
58515836
return texture;
58525837
}
58535838

@@ -5914,7 +5899,6 @@ static void VULKAN_INTERNAL_CycleActiveTexture(
59145899
// No texture is available, generate a new one.
59155900
texture = VULKAN_INTERNAL_CreateTexture(
59165901
renderer,
5917-
false,
59185902
&container->header.info);
59195903

59205904
VULKAN_INTERNAL_TextureTransitionToDefaultUsage(
@@ -6816,7 +6800,6 @@ static SDL_GPUTexture *VULKAN_CreateTexture(
68166800

68176801
texture = VULKAN_INTERNAL_CreateTexture(
68186802
renderer,
6819-
true,
68206803
createinfo);
68216804

68226805
if (texture == NULL) {
@@ -6848,6 +6831,23 @@ static SDL_GPUTexture *VULKAN_CreateTexture(
68486831
texture->container = container;
68496832
texture->containerIndex = 0;
68506833

6834+
// Let's transition to the default barrier state, because for some reason Vulkan doesn't let us do that with initialLayout.
6835+
// Only do this after "container" is set, so the texture
6836+
// is fully initialized before any Submit that could trigger defrag.
6837+
{
6838+
VulkanCommandBuffer *barrierCommandBuffer = (VulkanCommandBuffer *)VULKAN_AcquireCommandBuffer((SDL_GPURenderer *)renderer);
6839+
VULKAN_INTERNAL_TextureTransitionToDefaultUsage(
6840+
renderer,
6841+
barrierCommandBuffer,
6842+
VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED,
6843+
texture);
6844+
VULKAN_INTERNAL_TrackTexture(barrierCommandBuffer, texture);
6845+
if (!VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer)) {
6846+
VULKAN_ReleaseTexture((SDL_GPURenderer *)renderer, (SDL_GPUTexture *)container);
6847+
return NULL;
6848+
}
6849+
}
6850+
68516851
return (SDL_GPUTexture *)container;
68526852
}
68536853

@@ -10901,7 +10901,6 @@ static bool VULKAN_INTERNAL_DefragmentMemory(
1090110901
} else if (!currentRegion->isBuffer && !currentRegion->vulkanTexture->markedForDestroy) {
1090210902
VulkanTexture *newTexture = VULKAN_INTERNAL_CreateTexture(
1090310903
renderer,
10904-
false,
1090510904
&currentRegion->vulkanTexture->container->header.info);
1090610905

1090710906
if (newTexture == NULL) {

0 commit comments

Comments
 (0)