ilo: clean up finalize_shader_states()
authorChia-I Wu <olvaffe@gmail.com>
Thu, 20 Jun 2013 04:57:42 +0000 (12:57 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Tue, 25 Jun 2013 04:10:34 +0000 (12:10 +0800)
Add ilo_shader_select_kernel() to replace the dependency table,
ilo_shader_variant_init(), and ilo_shader_state_use_variant().

With the changes, we no longer need to include ilo_shader_internal.h in
ilo_state.c.

src/gallium/drivers/ilo/ilo_shader.c
src/gallium/drivers/ilo/ilo_shader.h
src/gallium/drivers/ilo/ilo_state.c
src/gallium/drivers/ilo/shader/ilo_shader_internal.h

index 0f22ebb4dd815eb2005e4ef3547e97876c2fcbf3..4d63ec69098211f047488c9f363f555d49a09700 100644 (file)
@@ -29,6 +29,7 @@
 #include "intel_winsys.h"
 
 #include "shader/ilo_shader_internal.h"
+#include "ilo_state.h"
 #include "ilo_shader.h"
 
 struct ilo_shader_cache {
@@ -687,6 +688,10 @@ ilo_shader_create_vs(const struct ilo_dev_info *dev,
 
    shader = ilo_shader_state_create(precompile, PIPE_SHADER_VERTEX, state);
 
+   /* states used in ilo_shader_variant_init() */
+   shader->info.non_orthogonal_states = ILO_DIRTY_VERTEX_SAMPLER_VIEWS |
+                                        ILO_DIRTY_RASTERIZER;
+
    return shader;
 }
 
@@ -699,6 +704,11 @@ ilo_shader_create_gs(const struct ilo_dev_info *dev,
 
    shader = ilo_shader_state_create(precompile, PIPE_SHADER_GEOMETRY, state);
 
+   /* states used in ilo_shader_variant_init() */
+   shader->info.non_orthogonal_states = ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS |
+                                        ILO_DIRTY_VS |
+                                        ILO_DIRTY_RASTERIZER;
+
    return shader;
 }
 
@@ -711,6 +721,11 @@ ilo_shader_create_fs(const struct ilo_dev_info *dev,
 
    shader = ilo_shader_state_create(precompile, PIPE_SHADER_FRAGMENT, state);
 
+   /* states used in ilo_shader_variant_init() */
+   shader->info.non_orthogonal_states = ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS |
+                                        ILO_DIRTY_RASTERIZER |
+                                        ILO_DIRTY_FRAMEBUFFER;
+
    return shader;
 }
 
@@ -723,6 +738,8 @@ ilo_shader_create_cs(const struct ilo_dev_info *dev,
 
    shader = ilo_shader_state_create(precompile, PIPE_SHADER_COMPUTE, state);
 
+   shader->info.non_orthogonal_states = 0;
+
    return shader;
 }
 
@@ -740,3 +757,28 @@ ilo_shader_destroy(struct ilo_shader_state *shader)
    FREE((struct tgsi_token *) shader->info.tokens);
    FREE(shader);
 }
+
+/**
+ * Select a kernel for the given context.  This will compile a new kernel if
+ * none of the existing kernels work with the context.
+ *
+ * \param ilo the context
+ * \param dirty states of the context that are considered changed
+ * \return true if a different kernel is selected
+ */
+bool
+ilo_shader_select_kernel(struct ilo_shader_state *shader,
+                         const struct ilo_context *ilo,
+                         uint32_t dirty)
+{
+   const struct ilo_shader * const cur = shader->shader;
+   struct ilo_shader_variant variant;
+
+   if (!(shader->info.non_orthogonal_states & dirty))
+      return false;
+
+   ilo_shader_variant_init(&variant, &shader->info, ilo);
+   ilo_shader_state_use_variant(shader, &variant);
+
+   return (shader->shader != cur);
+}
index 5e457b91e11efc4ff96b474b278cdd233f6d53d7..4413c59e119632dba26c531c229499d14c019ec6 100644 (file)
@@ -77,4 +77,9 @@ ilo_shader_create_cs(const struct ilo_dev_info *dev,
 void
 ilo_shader_destroy(struct ilo_shader_state *shader);
 
+bool
+ilo_shader_select_kernel(struct ilo_shader_state *shader,
+                         const struct ilo_context *ilo,
+                         uint32_t dirty);
+
 #endif /* ILO_SHADER_H */
index 69fe383379314cff8d719ca77fca2bb2e67402d3..58894f288ffa8326fa8f6d8e65713a27bacf6b2e 100644 (file)
 #include "util/u_framebuffer.h"
 #include "util/u_helpers.h"
 
-#include "shader/ilo_shader_internal.h"
 #include "ilo_context.h"
 #include "ilo_resource.h"
 #include "ilo_shader.h"
 #include "ilo_state.h"
 
-/*
- * We simply remember the pipe states here and derive HW commands/states from
- * them later.  We could do better by deriving (some of the) HW
- * commands/states directly.
- */
-
 static void
 finalize_shader_states(struct ilo_context *ilo)
 {
-   /* this table is ugly and is a burden to maintain.. */
-   const struct {
-      struct ilo_shader_state *state;
-      struct ilo_shader *prev_shader;
-      uint32_t dirty;
-      uint32_t deps;
-   } sh[PIPE_SHADER_TYPES] = {
-      [PIPE_SHADER_VERTEX] = {
-         .state = ilo->vs,
-         .prev_shader = (ilo->vs) ? ilo->vs->shader : NULL,
-         .dirty = ILO_DIRTY_VS,
-         .deps = ILO_DIRTY_VERTEX_SAMPLER_VIEWS |
-                 ILO_DIRTY_RASTERIZER,
-      },
-      [PIPE_SHADER_FRAGMENT] = {
-         .state = ilo->fs,
-         .prev_shader = (ilo->fs) ? ilo->fs->shader : NULL,
-         .dirty = ILO_DIRTY_FS,
-         .deps = ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS |
-                 ILO_DIRTY_RASTERIZER |
-                 ILO_DIRTY_FRAMEBUFFER,
-      },
-      [PIPE_SHADER_GEOMETRY] = {
-         .state = ilo->gs,
-         .prev_shader = (ilo->gs) ? ilo->gs->shader : NULL,
-         .dirty = ILO_DIRTY_GS,
-         .deps = ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS |
-                 ILO_DIRTY_VS |
-                 ILO_DIRTY_RASTERIZER,
-      },
-      [PIPE_SHADER_COMPUTE] = {
-         .state = NULL,
-         .prev_shader = NULL,
-         .dirty = 0,
-         .deps = 0,
-      },
-   };
-   int i;
-
-   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
-      /* no state bound */
-      if (!sh[i].state)
-         continue;
+   unsigned type;
 
-      /* switch variant if the shader or the states it depends on changed */
-      if (ilo->dirty & (sh[i].dirty | sh[i].deps)) {
-         struct ilo_shader_variant variant;
+   for (type = 0; type < PIPE_SHADER_TYPES; type++) {
+      struct ilo_shader_state *shader;
+      uint32_t state;
 
-         ilo_shader_variant_init(&variant, &sh[i].state->info, ilo);
-         ilo_shader_state_use_variant(sh[i].state, &variant);
+      switch (type) {
+      case PIPE_SHADER_VERTEX:
+         shader = ilo->vs;
+         state = ILO_DIRTY_VS;
+         break;
+      case PIPE_SHADER_GEOMETRY:
+         shader = ilo->gs;
+         state = ILO_DIRTY_GS;
+         break;
+      case PIPE_SHADER_FRAGMENT:
+         shader = ilo->fs;
+         state = ILO_DIRTY_FS;
+         break;
+      default:
+         shader = NULL;
+         state = 0;
+         break;
       }
-   }
 
-   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
-      /* no state bound */
-      if (!sh[i].state)
+      if (!shader)
          continue;
 
-      /* mark the shader state dirty if new variant is selected */
-      if (sh[i].state->shader != sh[i].prev_shader)
-         ilo->dirty |= sh[i].dirty;
+      /* compile if the shader or the states it depends on changed */
+      if (ilo->dirty & state) {
+         ilo_shader_select_kernel(shader, ilo, ILO_DIRTY_ALL);
+      }
+      else if (ilo_shader_select_kernel(shader, ilo, ilo->dirty)) {
+         /* mark the state dirty if a new kernel is selected */
+         ilo->dirty |= state;
+      }
    }
 }
 
index a73b3393fe384a5263e636f8330e353b7c97c869..1723bd19ded437473e1f27c49b294991493adc50 100644 (file)
@@ -138,6 +138,8 @@ struct ilo_shader_info {
       unsigned req_input_mem;
    } compute;
 
+   uint32_t non_orthogonal_states;
+
    bool has_color_interp;
    bool has_pos;
    bool has_vertexid;