gallium/swr: fix tessellation state save/restore
authorJan Zielinski <jan.zielinski@intel.com>
Tue, 28 Jan 2020 11:09:11 +0000 (12:09 +0100)
committerJan Zielinski <jan.zielinski@intel.com>
Tue, 28 Jan 2020 12:55:47 +0000 (13:55 +0100)
Tessellation state should be saved with TCS/TES state
when binding new state and restored if old state
is set again.

Reviewed-by: Krzysztof Raszkowski <krzysztof.raszkowski@intel.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3596>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3596>

src/gallium/drivers/swr/swr_context.h
src/gallium/drivers/swr/swr_state.cpp
src/gallium/drivers/swr/swr_state.h

index 0fafe1449e7eb9a18bc84a888d159273a765cd46..9a19720478a3ffb0026839d439f5844fab1bda06 100644 (file)
@@ -56,8 +56,9 @@
 #define SWR_BLOCK_CLIENT_DRAW ( 1 << 18) // Indicates client draw will block
 #define SWR_NEW_TCS (1 << 19)
 #define SWR_NEW_TES (1 << 20)
-#define SWR_NEW_TCSCONSTANTS (1 << 21)
-#define SWR_NEW_TESCONSTANTS (1 << 22)
+#define SWR_NEW_TS (1 << 21)
+#define SWR_NEW_TCSCONSTANTS (1 << 22)
+#define SWR_NEW_TESCONSTANTS (1 << 23)
 
 namespace std
 {
index ea6d09ffb5f030fe528e224f32860766ef4f207e..34e36a8025a0688e6b7a2e03b92020ca64402c93 100644 (file)
@@ -485,6 +485,7 @@ swr_bind_tcs_state(struct pipe_context *pipe, void *tcs)
 
    ctx->tcs = (swr_tess_control_shader *)tcs;
    ctx->dirty |= SWR_NEW_TCS;
+   ctx->dirty |= SWR_NEW_TS;
 }
 
 static void
@@ -519,8 +520,15 @@ swr_bind_tes_state(struct pipe_context *pipe, void *tes)
    if (ctx->tes == tes)
       return;
 
+   // Save current tessellator state first
+   if (ctx->tes != nullptr) {
+      ctx->tes->ts_state = ctx->tsState;
+   }
+
    ctx->tes = (swr_tess_evaluation_shader *)tes;
+
    ctx->dirty |= SWR_NEW_TES;
+   ctx->dirty |= SWR_NEW_TS;
 }
 
 static void
@@ -1544,6 +1552,19 @@ swr_update_derived(struct pipe_context *pipe,
       }
    }
 
+   // We may need to restore tessellation state
+   // This restored state may be however overwritten
+   // during shader compilation
+   if (ctx->dirty & SWR_NEW_TS) {
+      if (ctx->tes != nullptr) {
+         ctx->tsState = ctx->tes->ts_state;
+         ctx->api.pfnSwrSetTsState(ctx->swrContext, &ctx->tsState);
+      } else {
+         SWR_TS_STATE state = { 0 };
+         ctx->api.pfnSwrSetTsState(ctx->swrContext, &state);
+      }
+   }
+
    // Tessellation Evaluation Shader
    // Compile TES first, because TCS is optional
    if (ctx->dirty & (SWR_NEW_GS |
@@ -1582,16 +1603,13 @@ swr_update_derived(struct pipe_context *pipe,
                                      ctx->swrDC.texturesTES);
          }
 
+         // Update tessellation state in case it's been updated
          ctx->api.pfnSwrSetTsState(ctx->swrContext, &ctx->tsState);
-
       } else {
-         SWR_TS_STATE state = { 0 };
-         ctx->api.pfnSwrSetTsState(ctx->swrContext, &state);
          ctx->api.pfnSwrSetDsFunc(ctx->swrContext, NULL);
       }
    }
 
-
    /* Tessellation Control Shader */
    if (ctx->dirty & (SWR_NEW_GS |
                      SWR_NEW_VS |
@@ -1631,11 +1649,9 @@ swr_update_derived(struct pipe_context *pipe,
                                      ctx->swrDC.texturesTCS);
          }
 
+         // Update tessellation state in case it's been updated
          ctx->api.pfnSwrSetTsState(ctx->swrContext, &ctx->tsState);
-
       } else {
-         SWR_TS_STATE state = { 0 };
-         ctx->api.pfnSwrSetTsState(ctx->swrContext, &state);
          ctx->api.pfnSwrSetHsFunc(ctx->swrContext, NULL);
       }
    }
index 09463241b965c6384d9d269a472fe03a5701157f..128b85a892b3f3ab01089e38bca892577f16fa28 100644 (file)
@@ -92,6 +92,7 @@ struct swr_tess_control_shader {
 struct swr_tess_evaluation_shader {
    struct pipe_shader_state pipe;
    struct lp_tgsi_info info;
+   SWR_TS_STATE ts_state;
 
    std::unordered_map<swr_jit_tes_key, std::unique_ptr<VariantTES>> map;
 };