SDL: SDL_render: Call InvalidateCachedState to initialise some of driverdata values (eg '*_dirty' to 1).

From 7c71e72193348f19570fc77852aff2ddf510a84b Mon Sep 17 00:00:00 2001
From: Sylvain <[EMAIL REDACTED]>
Date: Fri, 1 Dec 2023 15:58:13 +0100
Subject: [PATCH] SDL_render: Call InvalidateCachedState to initialise some of
 driverdata values (eg '*_dirty' to 1). At the earliest place, immediatly
 after driverdata is set. (Doing it in SDL_render.c, after creation, would be
 too late, because there're renderers that already use/change those values in
 the CreateRender() function).

---
 src/render/direct3d/SDL_render_d3d.c     | 14 ++++----------
 src/render/direct3d11/SDL_render_d3d11.c |  1 +
 src/render/direct3d12/SDL_render_d3d12.c |  2 ++
 src/render/metal/SDL_render_metal.m      |  1 +
 src/render/opengl/SDL_render_gl.c        |  3 +--
 src/render/opengles2/SDL_render_gles2.c  |  2 +-
 src/render/ps2/SDL_render_ps2.c          |  1 +
 src/render/psp/SDL_render_psp.c          |  1 +
 src/render/software/SDL_render_sw.c      |  1 +
 src/render/vitagxm/SDL_render_vita_gxm.c |  1 +
 10 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c
index 744055bcb3d5..2ab49bd29f18 100644
--- a/src/render/direct3d/SDL_render_d3d.c
+++ b/src/render/direct3d/SDL_render_d3d.c
@@ -1511,12 +1511,9 @@ static int D3D_Reset(SDL_Renderer *renderer)
     IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget);
     D3D_InitRenderState(data);
     D3D_SetRenderTargetInternal(renderer, renderer->target);
-    data->drawstate.viewport_dirty = SDL_TRUE;
-    data->drawstate.cliprect_dirty = SDL_TRUE;
-    data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
-    data->drawstate.texture = NULL;
-    data->drawstate.shader = NULL;
-    data->drawstate.blend = SDL_BLENDMODE_INVALID;
+
+    D3D_InvalidateCachedState(renderer);
+
     IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX *)&d3dmatrix);
 
     /* Let the application know that render targets were reset */
@@ -1605,6 +1602,7 @@ SDL_Renderer *D3D_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_pro
     renderer->info = D3D_RenderDriver.info;
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
     renderer->driverdata = data;
+    D3D_InvalidateCachedState(renderer);
 
     SDL_GetWindowSizeInPixels(window, &w, &h);
     if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) {
@@ -1710,10 +1708,6 @@ SDL_Renderer *D3D_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_pro
         }
     }
 #endif
-    data->drawstate.viewport_dirty = SDL_TRUE;
-    data->drawstate.cliprect_dirty = SDL_TRUE;
-    data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
-    data->drawstate.blend = SDL_BLENDMODE_INVALID;
 
     SDL_SetProperty(SDL_GetRendererProperties(renderer), "SDL.renderer.d3d9.device", data->device);
 
diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c
index 9dfeb928b7eb..1c14a515079d 100644
--- a/src/render/direct3d11/SDL_render_d3d11.c
+++ b/src/render/direct3d11/SDL_render_d3d11.c
@@ -2472,6 +2472,7 @@ SDL_Renderer *D3D11_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_p
     renderer->info = D3D11_RenderDriver.info;
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
     renderer->driverdata = data;
+    D3D11_InvalidateCachedState(renderer);
 
 #if SDL_WINAPI_FAMILY_PHONE
     /* VSync is required in Windows Phone, at least for Win Phone 8.0 and 8.1.
diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c
index 91fdffbdec47..d1cafa5bf450 100644
--- a/src/render/direct3d12/SDL_render_d3d12.c
+++ b/src/render/direct3d12/SDL_render_d3d12.c
@@ -480,6 +480,7 @@ static void D3D12_ResetCommandList(D3D12_RenderData *data)
     data->cliprectDirty = SDL_TRUE;
     data->viewportDirty = SDL_TRUE;
     data->currentRenderTargetView.ptr = 0;
+    /* FIXME should we also clear currentSampler.ptr and currentRenderTargetView.ptr ? (and use D3D12_InvalidateCachedState() instead) */
 
     /* Release any upload buffers that were inflight */
     for (i = 0; i < data->currentUploadBuffer; ++i) {
@@ -3023,6 +3024,7 @@ SDL_Renderer *D3D12_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_p
     renderer->info = D3D12_RenderDriver.info;
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
     renderer->driverdata = data;
+    D3D12_InvalidateCachedState(renderer);
 
     if (SDL_GetBooleanProperty(create_props, "present_vsync", SDL_FALSE)) {
         renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m
index 4cb7577fb2cc..3d3e0586e38f 100644
--- a/src/render/metal/SDL_render_metal.m
+++ b/src/render/metal/SDL_render_metal.m
@@ -1796,6 +1796,7 @@ in case we want to use it later (recreating the renderer)
         }
 
         renderer->driverdata = (void *)CFBridgingRetain(data);
+        METAL_InvalidateCachedState(renderer);
         renderer->window = window;
 
         data.mtlview = view;
diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c
index 96ca76bd62a0..43c69602b66b 100644
--- a/src/render/opengl/SDL_render_gl.c
+++ b/src/render/opengl/SDL_render_gl.c
@@ -1832,6 +1832,7 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
     renderer->info = GL_RenderDriver.info;
     renderer->info.flags = 0; /* will set some flags below. */
     renderer->driverdata = data;
+    GL_InvalidateCachedState(renderer);
     renderer->window = window;
 
     data->context = SDL_GL_CreateContext(window);
@@ -2008,8 +2009,6 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
     /* This ended up causing video discrepancies between OpenGL and Direct3D */
     /* data->glEnable(GL_LINE_SMOOTH); */
 
-    data->drawstate.blend = SDL_BLENDMODE_INVALID;
-    data->drawstate.shader = SHADER_INVALID;
     data->drawstate.color = 0xFFFFFFFF;
     data->drawstate.clear_color = 0xFFFFFFFF;
 
diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c
index 1ea3afde8308..1173822efad7 100644
--- a/src/render/opengles2/SDL_render_gles2.c
+++ b/src/render/opengles2/SDL_render_gles2.c
@@ -2119,6 +2119,7 @@ static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
     renderer->info = GLES2_RenderDriver.info;
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
     renderer->driverdata = data;
+    GLES2_InvalidateCachedState(renderer);
     renderer->window = window;
 
     /* Create an OpenGL ES 2.0 context */
@@ -2255,7 +2256,6 @@ static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
 
     data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
 
-    data->drawstate.blend = SDL_BLENDMODE_INVALID;
     data->drawstate.clear_color = 0xFFFFFFFF;
     data->drawstate.projection[3][0] = -1.0f;
     data->drawstate.projection[3][3] = 1.0f;
diff --git a/src/render/ps2/SDL_render_ps2.c b/src/render/ps2/SDL_render_ps2.c
index b715a8586e78..dca67c364ee0 100644
--- a/src/render/ps2/SDL_render_ps2.c
+++ b/src/render/ps2/SDL_render_ps2.c
@@ -669,6 +669,7 @@ static SDL_Renderer *PS2_CreateRenderer(SDL_Window *window, SDL_PropertiesID cre
     renderer->info = PS2_RenderDriver.info;
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
     renderer->driverdata = data;
+    PS2_InvalidateCachedState(renderer);
     renderer->window = window;
 
     if (data->vsync) {
diff --git a/src/render/psp/SDL_render_psp.c b/src/render/psp/SDL_render_psp.c
index df70837204d6..6769238aee70 100644
--- a/src/render/psp/SDL_render_psp.c
+++ b/src/render/psp/SDL_render_psp.c
@@ -1338,6 +1338,7 @@ SDL_Renderer *PSP_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_pro
     renderer->info = PSP_RenderDriver.info;
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
     renderer->driverdata = data;
+    PSP_InvalidateCachedState(renderer);
     renderer->window = window;
 
     data->initialized = SDL_TRUE;
diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c
index efa30f312c3d..1ba010a2e336 100644
--- a/src/render/software/SDL_render_sw.c
+++ b/src/render/software/SDL_render_sw.c
@@ -1146,6 +1146,7 @@ SDL_Renderer *SW_CreateRendererForSurface(SDL_Surface *surface)
     renderer->DestroyRenderer = SW_DestroyRenderer;
     renderer->info = SW_RenderDriver.info;
     renderer->driverdata = data;
+    SW_InvalidateCachedState(renderer);
 
     SW_SelectBestFormats(renderer, surface->format->format);
 
diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c
index ade52281e92a..6b3831b65828 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm.c
+++ b/src/render/vitagxm/SDL_render_vita_gxm.c
@@ -255,6 +255,7 @@ SDL_Renderer *VITA_GXM_CreateRenderer(SDL_Window *window, SDL_PropertiesID creat
     renderer->info = VITA_GXM_RenderDriver.info;
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
     renderer->driverdata = data;
+    VITA_GXM_InvalidateCachedState(renderer);
     renderer->window = window;
 
     data->initialized = SDL_TRUE;