Bladeren bron

Only draw if state was set successfully in the Vulkan renderer

This can fail if there is drawing queued when the device is reset and all textures are freed. This also fixes a crash when that happens.
Sam Lantinga 1 week geleden
bovenliggende
commit
0cb26f9f6d
1 gewijzigde bestanden met toevoegingen van 36 en 17 verwijderingen
  1. 36 17
      src/render/vulkan/SDL_render_vulkan.c

+ 36 - 17
src/render/vulkan/SDL_render_vulkan.c

@@ -4424,8 +4424,12 @@ static bool VULKAN_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand
     int numSamplers = 0;
     int numSamplers = 0;
     VkSampler samplers[2];
     VkSampler samplers[2];
     VULKAN_PixelShaderConstants constants;
     VULKAN_PixelShaderConstants constants;
-    VkDescriptorSetLayout descriptorSetLayout = textureData->yuvPipeline ? textureData->yuvPipeline->descriptorSetLayoutYcbcr : rendererData->descriptorSetLayout;
-    VkPipelineLayout pipelineLayout = textureData->yuvPipeline ? textureData->yuvPipeline->pipelineLayoutYcbcr : rendererData->pipelineLayout;
+    VkDescriptorSetLayout descriptorSetLayout;
+    VkPipelineLayout pipelineLayout;
+
+    if (!textureData) {
+        return SDL_SetError("Texture is not currently available");
+    }
 
 
     VULKAN_SetupShaderConstants(renderer, cmd, texture, &constants);
     VULKAN_SetupShaderConstants(renderer, cmd, texture, &constants);
 
 
@@ -4494,6 +4498,13 @@ static bool VULKAN_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand
         samplers[numSamplers++] = samplers[0];
         samplers[numSamplers++] = samplers[0];
     }
     }
 
 
+    if (textureData->yuvPipeline) {
+        descriptorSetLayout = textureData->yuvPipeline->descriptorSetLayoutYcbcr;
+        pipelineLayout = textureData->yuvPipeline->pipelineLayoutYcbcr;
+    } else {
+        descriptorSetLayout = rendererData->descriptorSetLayout;
+        pipelineLayout = rendererData->pipelineLayout;
+    }
     return VULKAN_SetDrawState(renderer, cmd, pipelineLayout, descriptorSetLayout, &constants, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, numImageViews, imageViews, numSamplers, samplers, matrix, stateCache, textureData->yuv);
     return VULKAN_SetDrawState(renderer, cmd, pipelineLayout, descriptorSetLayout, &constants, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, numImageViews, imageViews, numSamplers, samplers, matrix, stateCache, textureData->yuv);
 }
 }
 
 
@@ -4611,15 +4622,17 @@ static bool VULKAN_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cm
             size_t line_start = 0;
             size_t line_start = 0;
             size_t line_end = line_start + count - 1;
             size_t line_end = line_start + count - 1;
             if (verts[line_start].pos[0] != verts[line_end].pos[0] || verts[line_start].pos[1] != verts[line_end].pos[1]) {
             if (verts[line_start].pos[0] != verts[line_end].pos[0] || verts[line_start].pos[1] != verts[line_end].pos[1]) {
-                VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, NULL, 0, NULL, NULL, &stateCache, false);
-                VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, start + line_end, 1);
-                have_point_draw_state = true;
+                if (VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, NULL, 0, NULL, NULL, &stateCache, false)) {
+                    VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, start + line_end, 1);
+                    have_point_draw_state = true;
+                }
             }
             }
 
 
             if (count > 2) {
             if (count > 2) {
                 // joined lines cannot be grouped
                 // joined lines cannot be grouped
-                VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 0, NULL, 0, NULL, NULL, &stateCache, false);
-                VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, start, count);
+                if (VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 0, NULL, 0, NULL, NULL, &stateCache, false)) {
+                    VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, start, count);
+                }
             } else {
             } else {
                 // let's group non joined lines
                 // let's group non joined lines
                 SDL_RenderCommand *finalcmd = cmd;
                 SDL_RenderCommand *finalcmd = cmd;
@@ -4648,17 +4661,19 @@ static bool VULKAN_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cm
                         line_end = line_start + nextcmd->data.draw.count - 1;
                         line_end = line_start + nextcmd->data.draw.count - 1;
                         if (verts[line_start].pos[0] != verts[line_end].pos[0] || verts[line_start].pos[1] != verts[line_end].pos[1]) {
                         if (verts[line_start].pos[0] != verts[line_end].pos[0] || verts[line_start].pos[1] != verts[line_end].pos[1]) {
                             if (!have_point_draw_state) {
                             if (!have_point_draw_state) {
-                                VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, NULL, 0, NULL, NULL, &stateCache, false);
-                                have_point_draw_state = true;
+                                have_point_draw_state = VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, NULL, 0, NULL, NULL, &stateCache, false);
+                            }
+                            if (have_point_draw_state) {
+                                VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, start + line_end, 1);
                             }
                             }
-                            VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, start + line_end, 1);
                         }
                         }
                         count += nextcmd->data.draw.count;
                         count += nextcmd->data.draw.count;
                     }
                     }
                 }
                 }
 
 
-                VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, 0, NULL, 0, NULL, NULL, &stateCache, false);
-                VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, start, count);
+                if (VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, 0, NULL, 0, NULL, NULL, &stateCache, false)) {
+                    VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, start, count);
+                }
 
 
                 cmd = finalcmd; // skip any copy commands we just combined in here.
                 cmd = finalcmd; // skip any copy commands we just combined in here.
             }
             }
@@ -4713,16 +4728,20 @@ static bool VULKAN_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cm
             }
             }
 
 
             if (thiscmdtype == SDL_RENDERCMD_GEOMETRY) {
             if (thiscmdtype == SDL_RENDERCMD_GEOMETRY) {
+                bool setState;
                 if (thistexture) {
                 if (thistexture) {
-                    VULKAN_SetCopyState(renderer, cmd, NULL, &stateCache);
+                    setState = VULKAN_SetCopyState(renderer, cmd, NULL, &stateCache);
                 } else {
                 } else {
-                    VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, NULL, 0, NULL, NULL, &stateCache, false);
+                    setState = VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, NULL, 0, NULL, NULL, &stateCache, false);
                 }
                 }
 
 
-                VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, start, count);
+                if (setState) {
+                    VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, start, count);
+                }
             } else {
             } else {
-                VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, NULL, 0, NULL, NULL, &stateCache, false);
-                VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, start, count);
+                if (VULKAN_SetDrawState(renderer, cmd, rendererData->pipelineLayout, rendererData->descriptorSetLayout, NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, NULL, 0, NULL, NULL, &stateCache, false)) {
+                    VULKAN_DrawPrimitives(renderer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, start, count);
+                }
             }
             }
             cmd = finalcmd; // skip any copy commands we just combined in here.
             cmd = finalcmd; // skip any copy commands we just combined in here.
             break;
             break;