[Mesa-dev] [PATCH] etnaviv: calculate load balancing value at link time

Christian Gmeiner christian.gmeiner at gmail.com
Thu May 9 11:09:45 UTC 2019


Move the calculation out of the compiler.

Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
---
 .../drivers/etnaviv/etnaviv_compiler.c        | 28 ----------------
 .../drivers/etnaviv/etnaviv_compiler.h        |  1 -
 src/gallium/drivers/etnaviv/etnaviv_shader.c  | 32 +++++++++++++++++--
 3 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.c b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
index ceca5b8af99..4bb4f325b7a 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_compiler.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
@@ -2192,33 +2192,6 @@ fill_in_vs_outputs(struct etna_shader_variant *sobj, struct etna_compile *c)
 
    /* build two-level index for linking */
    build_output_index(sobj);
-
-   /* fill in "mystery meat" load balancing value. This value determines how
-    * work is scheduled between VS and PS
-    * in the unified shader architecture. More precisely, it is determined from
-    * the number of VS outputs, as well as chip-specific
-    * vertex output buffer size, vertex cache size, and the number of shader
-    * cores.
-    *
-    * XXX this is a conservative estimate, the "optimal" value is only known for
-    * sure at link time because some
-    * outputs may be unused and thus unmapped. Then again, in the general use
-    * case with GLSL the vertex and fragment
-    * shaders are linked already before submitting to Gallium, thus all outputs
-    * are used.
-    */
-   int half_out = (c->file[TGSI_FILE_OUTPUT].reg_size + 1) / 2;
-   assert(half_out);
-
-   uint32_t b = ((20480 / (c->specs->vertex_output_buffer_size -
-                           2 * half_out * c->specs->vertex_cache_size)) +
-                 9) /
-                10;
-   uint32_t a = (b + 256 / (c->specs->shader_core_count * half_out)) / 2;
-   sobj->vs_load_balancing = VIVS_VS_LOAD_BALANCING_A(MIN2(a, 255)) |
-                             VIVS_VS_LOAD_BALANCING_B(MIN2(b, 255)) |
-                             VIVS_VS_LOAD_BALANCING_C(0x3f) |
-                             VIVS_VS_LOAD_BALANCING_D(0x0f);
 }
 
 static bool
@@ -2513,7 +2486,6 @@ etna_dump_shader(const struct etna_shader_variant *shader)
    if (shader->processor == PIPE_SHADER_VERTEX) {
       printf("  vs_pos_out_reg=%i\n", shader->vs_pos_out_reg);
       printf("  vs_pointsize_out_reg=%i\n", shader->vs_pointsize_out_reg);
-      printf("  vs_load_balancing=0x%08x\n", shader->vs_load_balancing);
    } else {
       printf("  ps_color_out_reg=%i\n", shader->ps_color_out_reg);
       printf("  ps_depth_out_reg=%i\n", shader->ps_depth_out_reg);
diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.h b/src/gallium/drivers/etnaviv/etnaviv_compiler.h
index 48b1b218750..985d8310850 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_compiler.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.h
@@ -85,7 +85,6 @@ struct etna_shader_variant {
    /* special outputs (vs only) */
    int vs_pos_out_reg; /* VS position output */
    int vs_pointsize_out_reg; /* VS point size output */
-   uint32_t vs_load_balancing;
 
    /* special outputs (ps only) */
    int ps_color_out_reg; /* color output register */
diff --git a/src/gallium/drivers/etnaviv/etnaviv_shader.c b/src/gallium/drivers/etnaviv/etnaviv_shader.c
index d2d736bdee5..03ba94ff5fa 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_shader.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_shader.c
@@ -53,6 +53,31 @@ static bool etna_icache_upload_shader(struct etna_context *ctx, struct etna_shad
    return true;
 }
 
+static uint32_t
+etna_calculate_load_balance(const struct etna_specs *specs, unsigned num_regs)
+{
+   /* fill in "mystery meat" load balancing value. This value determines how
+    * work is scheduled between VS and PS
+    * in the unified shader architecture. More precisely, it is determined from
+    * the number of VS outputs, as well as chip-specific
+    * vertex output buffer size, vertex cache size, and the number of shader
+    * cores.
+    */
+   unsigned half_out = (num_regs + 1) / 2;
+   assert(half_out);
+
+   uint32_t b = ((20480 / (specs->vertex_output_buffer_size -
+                           2 * half_out * specs->vertex_cache_size)) +
+                 9) /
+                10;
+   uint32_t a = (b + 256 / (specs->shader_core_count * half_out)) / 2;
+
+   return VIVS_VS_LOAD_BALANCING_A(MIN2(a, 255)) |
+          VIVS_VS_LOAD_BALANCING_B(MIN2(b, 255)) |
+          VIVS_VS_LOAD_BALANCING_C(0x3f) |
+          VIVS_VS_LOAD_BALANCING_D(0x0f);
+}
+
 /* Link vs and fs together: fill in shader_state from vs and fs
  * as this function is called every time a new fs or vs is bound, the goal is to
  * do little processing as possible here, and to precompute as much as possible in
@@ -139,9 +164,12 @@ etna_link_shaders(struct etna_context *ctx, struct compiled_shader_state *cs,
       cs->VS_OUTPUT_COUNT_PSIZE = cs->VS_OUTPUT_COUNT;
    }
 
-   cs->VS_LOAD_BALANCING = vs->vs_load_balancing;
-   cs->VS_START_PC = 0;
+   unsigned num_regs = vs->outfile.num_reg;
+   num_regs += COND(vs->vs_pos_out_reg != -1, 1);
+   num_regs += COND(vs->vs_pointsize_out_reg != -1, 1);
+   cs->VS_LOAD_BALANCING = etna_calculate_load_balance(&ctx->specs, num_regs);
 
+   cs->VS_START_PC = 0;
    cs->PS_END_PC = fs->code_size / 4;
    cs->PS_OUTPUT_REG = fs->ps_color_out_reg;
    cs->PS_INPUT_COUNT =
-- 
2.21.0



More information about the mesa-dev mailing list