radeonsi: record information about all written and read varyings
authorMarek Olšák <marek.olsak@amd.com>
Mon, 14 Nov 2016 06:56:57 +0000 (07:56 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 21 Nov 2016 20:44:35 +0000 (21:44 +0100)
It's just tgsi_shader_info with DEFAULT_VAL varyings removed.

Tested-by: Edmondo Tommasina <edmondo.tommasina@gmail.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_shader.h
src/gallium/drivers/radeonsi/si_state_shaders.c

index 8b5645930841e82dfa1cc39d428a725a07b0a43a..2b4322443319ba7ed6ba7b2f6275981302a978cb 100644 (file)
@@ -141,6 +141,28 @@ unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index)
        }
 }
 
+unsigned si_shader_io_get_unique_index2(unsigned name, unsigned index)
+{
+       switch (name) {
+       case TGSI_SEMANTIC_FOG:
+               return 0;
+       case TGSI_SEMANTIC_LAYER:
+               return 1;
+       case TGSI_SEMANTIC_VIEWPORT_INDEX:
+               return 2;
+       case TGSI_SEMANTIC_PRIMID:
+               return 3;
+       case TGSI_SEMANTIC_COLOR: /* these alias */
+       case TGSI_SEMANTIC_BCOLOR:
+               return 4 + index;
+       case TGSI_SEMANTIC_TEXCOORD:
+               return 6 + index;
+       default:
+               assert(!"invalid semantic name");
+               return 0;
+       }
+}
+
 /**
  * Get the value of a shader input parameter and extract a bitfield.
  */
index 4cbd1c24742c2fe7ddb7ea0085ea32089f564599..fc9c9131be8b0893a028cfa3d09b634959456272 100644 (file)
@@ -295,9 +295,12 @@ struct si_shader_selector {
        /* CS parameters */
        unsigned local_size;
 
-       /* masks of "get_unique_index" bits */
-       uint64_t        outputs_written;
-       uint32_t        patch_outputs_written;
+       uint64_t        outputs_written;        /* "get_unique_index" bits */
+       uint32_t        patch_outputs_written;  /* "get_unique_index" bits */
+       uint32_t        outputs_written2;       /* "get_unique_index2" bits */
+
+       uint64_t        inputs_read;            /* "get_unique_index" bits */
+       uint32_t        inputs_read2;           /* "get_unique_index2" bits */
 };
 
 /* Valid shader configurations:
@@ -539,6 +542,7 @@ int si_compile_llvm(struct si_screen *sscreen,
                    const char *name);
 void si_shader_destroy(struct si_shader *shader);
 unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index);
+unsigned si_shader_io_get_unique_index2(unsigned name, unsigned index);
 int si_shader_binary_upload(struct si_screen *sscreen, struct si_shader *shader);
 void si_shader_dump(struct si_screen *sscreen, struct si_shader *shader,
                    struct pipe_debug_callback *debug, unsigned processor,
index d10084dfe4e7f57c8c972ea929e78bb999a113e5..e4d8747c6fe1846f08d8231640a1088f6a08d73a 100644 (file)
@@ -1296,6 +1296,51 @@ void si_init_shader_selector_async(void *job, int thread_index)
                }
 
                sel->main_shader_part = shader;
+
+               /* Unset "outputs_written" flags for outputs converted to
+                * DEFAULT_VAL, so that later inter-shader optimizations don't
+                * try to eliminate outputs that don't exist in the final
+                * shader.
+                *
+                * This is only done if non-monolithic shaders are enabled.
+                */
+               if ((sel->type == PIPE_SHADER_VERTEX ||
+                    sel->type == PIPE_SHADER_TESS_EVAL) &&
+                   !shader->key.as_ls &&
+                   !shader->key.as_es) {
+                       unsigned i;
+
+                       for (i = 0; i < sel->info.num_outputs; i++) {
+                               unsigned offset = shader->info.vs_output_param_offset[i];
+
+                               if (offset <= EXP_PARAM_OFFSET_31)
+                                       continue;
+
+                               unsigned name = sel->info.output_semantic_name[i];
+                               unsigned index = sel->info.output_semantic_index[i];
+                               unsigned id;
+
+                               switch (name) {
+                               case TGSI_SEMANTIC_GENERIC:
+                                       /* don't process indices the function can't handle */
+                                       if (index >= 60)
+                                               break;
+                                       /* fall through */
+                               case TGSI_SEMANTIC_CLIPDIST:
+                                       id = si_shader_io_get_unique_index(name, index);
+                                       sel->outputs_written &= ~(1ull << id);
+                                       break;
+                               case TGSI_SEMANTIC_POSITION: /* ignore these */
+                               case TGSI_SEMANTIC_PSIZE:
+                               case TGSI_SEMANTIC_CLIPVERTEX:
+                               case TGSI_SEMANTIC_EDGEFLAG:
+                                       break;
+                               default:
+                                       id = si_shader_io_get_unique_index2(name, index);
+                                       sel->outputs_written2 &= ~(1u << id);
+                               }
+                       }
+               }
        }
 
        /* Pre-compilation. */
@@ -1437,12 +1482,36 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
                                sel->outputs_written |=
                                        1llu << si_shader_io_get_unique_index(name, index);
                                break;
+                       case TGSI_SEMANTIC_CLIPVERTEX: /* ignore these */
+                       case TGSI_SEMANTIC_EDGEFLAG:
+                               break;
+                       default:
+                               sel->outputs_written2 |=
+                                       1u << si_shader_io_get_unique_index2(name, index);
                        }
                }
                sel->esgs_itemsize = util_last_bit64(sel->outputs_written) * 16;
                break;
 
        case PIPE_SHADER_FRAGMENT:
+               for (i = 0; i < sel->info.num_inputs; i++) {
+                       unsigned name = sel->info.input_semantic_name[i];
+                       unsigned index = sel->info.input_semantic_index[i];
+
+                       switch (name) {
+                       case TGSI_SEMANTIC_CLIPDIST:
+                       case TGSI_SEMANTIC_GENERIC:
+                               sel->inputs_read |=
+                                       1llu << si_shader_io_get_unique_index(name, index);
+                               break;
+                       case TGSI_SEMANTIC_PCOORD: /* ignore this */
+                               break;
+                       default:
+                               sel->inputs_read2 |=
+                                       1u << si_shader_io_get_unique_index2(name, index);
+                       }
+               }
+
                for (i = 0; i < 8; i++)
                        if (sel->info.colors_written & (1 << i))
                                sel->colors_written_4bit |= 0xf << (4 * i);