SDL: Fixed slow startup time when using the direct3d12 renderer

From 548b382fd98dbaa4129a1a29ac1957251473a0c3 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 4 Feb 2024 12:08:55 -0800
Subject: [PATCH] Fixed slow startup time when using the direct3d12 renderer

On some systems creating the entire set of available pipeline states is very time consuming. We'll only use a few of them in any given program, so we'll just create them on demand.

Fixes https://github.com/libsdl-org/SDL/issues/7634
---
 src/render/direct3d12/SDL_render_d3d12.c | 55 +++++++++++++-----------
 1 file changed, 30 insertions(+), 25 deletions(-)

diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c
index 2ce0eb68382e..afd25c9cdfae 100644
--- a/src/render/direct3d12/SDL_render_d3d12.c
+++ b/src/render/direct3d12/SDL_render_d3d12.c
@@ -749,7 +749,7 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer)
     ID3D12Device *d3dDevice = NULL;
     HRESULT result = S_OK;
     UINT creationFlags = 0;
-    int i, j, k, l;
+    int i;
     SDL_bool createDebug;
 
     D3D12_COMMAND_QUEUE_DESC queueDesc;
@@ -757,21 +757,6 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer)
     D3D12_SAMPLER_DESC samplerDesc;
     ID3D12DescriptorHeap *rootDescriptorHeaps[2];
 
-    const SDL_BlendMode defaultBlendModes[] = {
-        SDL_BLENDMODE_NONE,
-        SDL_BLENDMODE_BLEND,
-        SDL_BLENDMODE_ADD,
-        SDL_BLENDMODE_MOD,
-        SDL_BLENDMODE_MUL
-    };
-    const DXGI_FORMAT defaultRTVFormats[] = {
-        DXGI_FORMAT_R16G16B16A16_FLOAT,
-        DXGI_FORMAT_R10G10B10A2_UNORM,
-        DXGI_FORMAT_B8G8R8A8_UNORM,
-        DXGI_FORMAT_B8G8R8X8_UNORM,
-        DXGI_FORMAT_R8_UNORM
-    };
-
     /* See if we need debug interfaces */
     createDebug = SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D11_DEBUG, SDL_FALSE);
 
@@ -1056,20 +1041,40 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer)
         }
     }
 
-    /* Create all the default pipeline state objects
-       (will add everything except custom blend states) */
-    for (i = 0; i < NUM_SHADERS; ++i) {
-        for (j = 0; j < SDL_arraysize(defaultBlendModes); ++j) {
-            for (k = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; k < D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH; ++k) {
-                for (l = 0; l < SDL_arraysize(defaultRTVFormats); ++l) {
-                    if (!D3D12_CreatePipelineState(renderer, (D3D12_Shader)i, defaultBlendModes[j], (D3D12_PRIMITIVE_TOPOLOGY_TYPE)k, defaultRTVFormats[l])) {
-                        /* D3D12_CreatePipelineState will set the SDL error, if it fails */
-                        goto done;
+#if 0 /* Actually, don't do this, it causes a huge startup time on some systems */
+    {
+        const SDL_BlendMode defaultBlendModes[] = {
+            SDL_BLENDMODE_NONE,
+            SDL_BLENDMODE_BLEND,
+            SDL_BLENDMODE_ADD,
+            SDL_BLENDMODE_MOD,
+            SDL_BLENDMODE_MUL
+        };
+        const DXGI_FORMAT defaultRTVFormats[] = {
+            DXGI_FORMAT_R16G16B16A16_FLOAT,
+            DXGI_FORMAT_R10G10B10A2_UNORM,
+            DXGI_FORMAT_B8G8R8A8_UNORM,
+            DXGI_FORMAT_B8G8R8X8_UNORM,
+            DXGI_FORMAT_R8_UNORM
+        };
+        int i, j, k, l;
+
+        /* Create all the default pipeline state objects
+           (will add everything except custom blend states) */
+        for (i = 0; i < NUM_SHADERS; ++i) {
+            for (j = 0; j < SDL_arraysize(defaultBlendModes); ++j) {
+                for (k = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; k < D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH; ++k) {
+                    for (l = 0; l < SDL_arraysize(defaultRTVFormats); ++l) {
+                        if (!D3D12_CreatePipelineState(renderer, (D3D12_Shader)i, defaultBlendModes[j], (D3D12_PRIMITIVE_TOPOLOGY_TYPE)k, defaultRTVFormats[l])) {
+                            /* D3D12_CreatePipelineState will set the SDL error, if it fails */
+                            goto done;
+                        }
                     }
                 }
             }
         }
     }
+#endif /* 0 */
 
     /* Create default vertex buffers  */
     for (i = 0; i < SDL_D3D12_NUM_VERTEX_BUFFERS; ++i) {