From 93da6e9f34226549b4eb8726383fb54c584a9e15 Mon Sep 17 00:00:00 2001 From: Axel Davy Date: Sat, 30 Jul 2022 10:09:05 +0200 Subject: [PATCH] frontend/nine: Fix shader multi-use crash 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 Acked-by: David Heidelberg Part-of: --- src/gallium/frontends/nine/pixelshader9.c | 11 +++++++++-- src/gallium/frontends/nine/vertexshader9.c | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/gallium/frontends/nine/pixelshader9.c b/src/gallium/frontends/nine/pixelshader9.c index 4b2b2b7..c5fe93c 100644 --- a/src/gallium/frontends/nine/pixelshader9.c +++ b/src/gallium/frontends/nine/pixelshader9.c @@ -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); } } diff --git a/src/gallium/frontends/nine/vertexshader9.c b/src/gallium/frontends/nine/vertexshader9.c index d88cfd5..c2b7036 100644 --- a/src/gallium/frontends/nine/vertexshader9.c +++ b/src/gallium/frontends/nine/vertexshader9.c @@ -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); } } -- 2.7.4