frontend/nine: Fix shader multi-use crash
authorAxel Davy <davyaxel0@gmail.com>
Sat, 30 Jul 2022 08:09:05 +0000 (10:09 +0200)
committerAxel Davy <davyaxel0@gmail.com>
Fri, 12 Aug 2022 19:53:11 +0000 (21:53 +0200)
Due to the driver live shader cache, it's possible
two different d3d9 shaders get the same cso.

As it's disallowed to destroy a shader cso being
bound, nine checks for this scenario. However it
was not taking into account the cso might be from
a different shader.

cc: mesa-stable

Signed-off-by: Axel Davy <davyaxel0@gmail.com>
Acked-by: David Heidelberg <david.heidelberg@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18021>

src/gallium/frontends/nine/pixelshader9.c
src/gallium/frontends/nine/vertexshader9.c

index 4b2b2b7..c5fe93c 100644 (file)
@@ -117,8 +117,13 @@ NinePixelShader9_dtor( struct NinePixelShader9 *This )
 
         do {
             if (var->cso) {
-                if (This->base.device->context.cso_shader.ps == var->cso)
+                if (This->base.device->context.cso_shader.ps == var->cso) {
+                    /* unbind because it is illegal to delete something bound */
                     pipe->bind_fs_state(pipe, NULL);
+                    /* This will rebind cso_shader.ps in case somehow actually
+                     * an identical shader with same cso is bound */
+                    This->base.device->context.commit |= NINE_STATE_COMMIT_PS;
+                }
                 pipe->delete_fs_state(pipe, var->cso);
                 FREE(var->const_ranges);
             }
@@ -126,8 +131,10 @@ NinePixelShader9_dtor( struct NinePixelShader9 *This )
         } while (var);
 
         if (This->ff_cso) {
-            if (This->ff_cso == This->base.device->context.cso_shader.ps)
+            if (This->ff_cso == This->base.device->context.cso_shader.ps) {
                 pipe->bind_fs_state(pipe, NULL);
+                This->base.device->context.commit |= NINE_STATE_COMMIT_PS;
+            }
             pipe->delete_fs_state(pipe, This->ff_cso);
         }
     }
index d88cfd5..c2b7036 100644 (file)
@@ -134,8 +134,13 @@ NineVertexShader9_dtor( struct NineVertexShader9 *This )
 
         do {
             if (var->cso) {
-                if (This->base.device->context.cso_shader.vs == var->cso)
+                if (This->base.device->context.cso_shader.vs == var->cso) {
+                    /* unbind because it is illegal to delete something bound */
                     pipe->bind_vs_state(pipe, NULL);
+                    /* This will rebind cso_shader.vs in case somehow actually
+                     * an identical shader with same cso is bound */
+                    This->base.device->context.commit |= NINE_STATE_COMMIT_VS;
+                }
                 pipe->delete_vs_state(pipe, var->cso);
                 FREE(var->const_ranges);
             }
@@ -150,8 +155,10 @@ NineVertexShader9_dtor( struct NineVertexShader9 *This )
         }
 
         if (This->ff_cso) {
-            if (This->ff_cso == This->base.device->context.cso_shader.vs)
+            if (This->ff_cso == This->base.device->context.cso_shader.vs) {
                 pipe->bind_vs_state(pipe, NULL);
+                This->base.device->context.commit |= NINE_STATE_COMMIT_VS;
+            }
             pipe->delete_vs_state(pipe, This->ff_cso);
         }
     }