st/glsl_to_nir: disable io lowering and array splitting of fs inputs
authorTimothy Arceri <tarceri@itsqueeze.com>
Mon, 15 Jan 2018 00:48:16 +0000 (11:48 +1100)
committerTimothy Arceri <tarceri@itsqueeze.com>
Tue, 30 Jan 2018 22:14:08 +0000 (09:14 +1100)
We need this to be able to support the interpolateAt builtins in a
sane way. It also leads to the generation of more optimal code.

The lowering and splitting is made conditional on lower_all_io_to_temps
because vc4 and freedreno both expect these passes to be enabled and
niether support glsl 400 so don't need to deal with the interpolateAt
builtins.

We leave the other stages for now as to avoid regressions. Ideally we
could remove the stage checks and just set the nir options correctly
for each stage. However all gallium drivers currently just use return
the same nir compiler options for all stages, and it's probably more
trouble than its worth to change this.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/mesa/state_tracker/st_glsl_to_nir.cpp

index a3d447c5a410f20c63b7707257f3b428f5529d63..65931bfa33ba8171c47ec36aaa64e1922c1c1b24 100644 (file)
@@ -451,6 +451,8 @@ st_nir_get_mesa_program(struct gl_context *ctx,
                         struct gl_linked_shader *shader)
 {
    struct st_context *st = st_context(ctx);
+   const nir_shader_compiler_options *options =
+      ctx->Const.ShaderCompilerOptions[shader->Program->info.stage].NirOptions;
    struct gl_program *prog;
 
    validate_ir_tree(shader->ir);
@@ -480,12 +482,18 @@ st_nir_get_mesa_program(struct gl_context *ctx,
    set_st_program(prog, shader_program, nir);
    prog->nir = nir;
 
-   if (nir->info.stage != MESA_SHADER_TESS_CTRL &&
-       nir->info.stage != MESA_SHADER_TESS_EVAL) {
+   if (options->lower_all_io_to_temps ||
+       nir->info.stage == MESA_SHADER_VERTEX ||
+       nir->info.stage == MESA_SHADER_GEOMETRY) {
       NIR_PASS_V(nir, nir_lower_io_to_temporaries,
                  nir_shader_get_entrypoint(nir),
                  true, true);
+   } else if (nir->info.stage == MESA_SHADER_FRAGMENT) {
+      NIR_PASS_V(nir, nir_lower_io_to_temporaries,
+                 nir_shader_get_entrypoint(nir),
+                 true, false);
    }
+
    NIR_PASS_V(nir, nir_lower_global_vars_to_local);
    NIR_PASS_V(nir, nir_split_var_copies);
    NIR_PASS_V(nir, nir_lower_var_copies);
@@ -655,12 +663,18 @@ st_finalize_nir(struct st_context *st, struct gl_program *prog,
                 struct gl_shader_program *shader_program, nir_shader *nir)
 {
    struct pipe_screen *screen = st->pipe->screen;
+   const nir_shader_compiler_options *options =
+      st->ctx->Const.ShaderCompilerOptions[prog->info.stage].NirOptions;
 
    NIR_PASS_V(nir, nir_split_var_copies);
    NIR_PASS_V(nir, nir_lower_var_copies);
-   if (nir->info.stage != MESA_SHADER_TESS_CTRL &&
-       nir->info.stage != MESA_SHADER_TESS_EVAL)
+   if (options->lower_all_io_to_temps ||
+       nir->info.stage == MESA_SHADER_VERTEX ||
+       nir->info.stage == MESA_SHADER_GEOMETRY) {
       NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
+   } else if (nir->info.stage == MESA_SHADER_FRAGMENT) {
+      NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, true);
+   }
 
    if (nir->info.stage == MESA_SHADER_VERTEX) {
       /* Needs special handling so drvloc matches the vbo state: */