i965: Remove unused variable 'options'
[mesa.git] / src / mesa / drivers / dri / i965 / brw_link.cpp
index 3bb04fa6effc1ca105fc65c93d74ddb66e1e8dc5..da38ec2516a7439ab30b8f881449b7537d45a64d 100644 (file)
@@ -22,9 +22,7 @@
  */
 
 #include "brw_context.h"
-#include "brw_shader.h"
-#include "brw_fs.h"
-#include "brw_nir.h"
+#include "compiler/brw_nir.h"
 #include "brw_program.h"
 #include "compiler/glsl/ir.h"
 #include "compiler/glsl/ir_optimization.h"
@@ -43,17 +41,17 @@ static bool
 brw_shader_precompile(struct gl_context *ctx,
                       struct gl_shader_program *sh_prog)
 {
-   struct gl_shader *vs = sh_prog->_LinkedShaders[MESA_SHADER_VERTEX];
-   struct gl_shader *tcs = sh_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL];
-   struct gl_shader *tes = sh_prog->_LinkedShaders[MESA_SHADER_TESS_EVAL];
-   struct gl_shader *gs = sh_prog->_LinkedShaders[MESA_SHADER_GEOMETRY];
-   struct gl_shader *fs = sh_prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
-   struct gl_shader *cs = sh_prog->_LinkedShaders[MESA_SHADER_COMPUTE];
-
-   if (fs && !brw_fs_precompile(ctx, sh_prog, fs->Program))
+   struct gl_linked_shader *vs = sh_prog->_LinkedShaders[MESA_SHADER_VERTEX];
+   struct gl_linked_shader *tcs = sh_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL];
+   struct gl_linked_shader *tes = sh_prog->_LinkedShaders[MESA_SHADER_TESS_EVAL];
+   struct gl_linked_shader *gs = sh_prog->_LinkedShaders[MESA_SHADER_GEOMETRY];
+   struct gl_linked_shader *fs = sh_prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
+   struct gl_linked_shader *cs = sh_prog->_LinkedShaders[MESA_SHADER_COMPUTE];
+
+   if (fs && !brw_fs_precompile(ctx, fs->Program))
       return false;
 
-   if (gs && !brw_gs_precompile(ctx, sh_prog, gs->Program))
+   if (gs && !brw_gs_precompile(ctx, gs->Program))
       return false;
 
    if (tes && !brw_tes_precompile(ctx, sh_prog, tes->Program))
@@ -62,10 +60,10 @@ brw_shader_precompile(struct gl_context *ctx,
    if (tcs && !brw_tcs_precompile(ctx, sh_prog, tcs->Program))
       return false;
 
-   if (vs && !brw_vs_precompile(ctx, sh_prog, vs->Program))
+   if (vs && !brw_vs_precompile(ctx, vs->Program))
       return false;
 
-   if (cs && !brw_cs_precompile(ctx, sh_prog, cs->Program))
+   if (cs && !brw_cs_precompile(ctx, cs->Program))
       return false;
 
    return true;
@@ -73,7 +71,6 @@ brw_shader_precompile(struct gl_context *ctx,
 
 static void
 brw_lower_packing_builtins(struct brw_context *brw,
-                           gl_shader_stage shader_type,
                            exec_list *ir)
 {
    /* Gens < 7 don't have instructions to convert to or from half-precision,
@@ -86,85 +83,52 @@ brw_lower_packing_builtins(struct brw_context *brw,
 }
 
 static void
-process_glsl_ir(gl_shader_stage stage,
-                struct brw_context *brw,
+process_glsl_ir(struct brw_context *brw,
                 struct gl_shader_program *shader_prog,
-                struct gl_shader *shader)
+                struct gl_linked_shader *shader)
 {
    struct gl_context *ctx = &brw->ctx;
-   const struct brw_compiler *compiler = brw->intelScreen->compiler;
-   const struct gl_shader_compiler_options *options =
-      &ctx->Const.ShaderCompilerOptions[shader->Stage];
 
    /* Temporary memory context for any new IR. */
    void *mem_ctx = ralloc_context(NULL);
 
    ralloc_adopt(mem_ctx, shader->ir);
 
+   lower_blend_equation_advanced(shader);
+
    /* lower_packing_builtins() inserts arithmetic instructions, so it
     * must precede lower_instructions().
     */
-   brw_lower_packing_builtins(brw, shader->Stage, shader->ir);
+   brw_lower_packing_builtins(brw, shader->ir);
    do_mat_op_to_vec(shader->ir);
-   lower_instructions(shader->ir,
-                      DIV_TO_MUL_RCP |
-                      SUB_TO_ADD_NEG |
-                      EXP_TO_EXP2 |
-                      LOG_TO_LOG2 |
-                      DFREXP_DLDEXP_TO_ARITH |
-                      CARRY_TO_ARITH |
-                      BORROW_TO_ARITH);
+
+   unsigned instructions_to_lower = (DIV_TO_MUL_RCP |
+                                     SUB_TO_ADD_NEG |
+                                     EXP_TO_EXP2 |
+                                     LOG_TO_LOG2 |
+                                     DFREXP_DLDEXP_TO_ARITH);
+   if (brw->gen < 7) {
+      instructions_to_lower |= BIT_COUNT_TO_MATH |
+                               EXTRACT_TO_SHIFTS |
+                               INSERT_TO_SHIFTS |
+                               REVERSE_TO_SHIFTS;
+   }
+
+   lower_instructions(shader->ir, instructions_to_lower);
 
    /* Pre-gen6 HW can only nest if-statements 16 deep.  Beyond this,
     * if-statements need to be flattened.
     */
    if (brw->gen < 6)
-      lower_if_to_cond_assign(shader->ir, 16);
+      lower_if_to_cond_assign(shader->Stage, shader->ir, 16);
 
    do_lower_texture_projection(shader->ir);
-   brw_lower_texture_gradients(brw, shader->ir);
    do_vec_index_to_cond_assign(shader->ir);
    lower_vector_insert(shader->ir, true);
    lower_offset_arrays(shader->ir);
-   brw_do_lower_unnormalized_offset(shader->ir);
    lower_noise(shader->ir);
    lower_quadop_vector(shader->ir, false);
 
-   bool lowered_variable_indexing =
-      lower_variable_index_to_cond_assign((gl_shader_stage)stage,
-                                          shader->ir,
-                                          options->EmitNoIndirectInput,
-                                          options->EmitNoIndirectOutput,
-                                          options->EmitNoIndirectTemp,
-                                          options->EmitNoIndirectUniform);
-
-   if (unlikely(brw->perf_debug && lowered_variable_indexing)) {
-      perf_debug("Unsupported form of variable indexing in %s; falling "
-                 "back to very inefficient code generation\n",
-                 _mesa_shader_stage_to_abbrev(shader->Stage));
-   }
-
-   bool progress;
-   do {
-      progress = false;
-
-      if (compiler->scalar_stage[shader->Stage]) {
-         if (shader->Stage == MESA_SHADER_VERTEX ||
-             shader->Stage == MESA_SHADER_FRAGMENT)
-            brw_do_channel_expressions(shader->ir);
-         brw_do_vector_splitting(shader->ir);
-      }
-
-      progress = do_lower_jumps(shader->ir, true, true,
-                                true, /* main return */
-                                false, /* continue */
-                                false /* loops */
-                                ) || progress;
-
-      progress = do_common_optimization(shader->ir, true, true,
-                                        options, ctx->Const.NativeIntegers) || progress;
-   } while (progress);
-
    validate_ir_tree(shader->ir);
 
    /* Now that we've finished altering the linked IR, reparent any live IR back
@@ -176,51 +140,78 @@ process_glsl_ir(gl_shader_stage stage,
 
    if (ctx->_Shader->Flags & GLSL_DUMP) {
       fprintf(stderr, "\n");
-      fprintf(stderr, "GLSL IR for linked %s program %d:\n",
-              _mesa_shader_stage_to_string(shader->Stage),
-              shader_prog->Name);
-      _mesa_print_ir(stderr, shader->ir, NULL);
+      if (shader->ir) {
+         fprintf(stderr, "GLSL IR for linked %s program %d:\n",
+                 _mesa_shader_stage_to_string(shader->Stage),
+                 shader_prog->Name);
+         _mesa_print_ir(stderr, shader->ir, NULL);
+      } else {
+         fprintf(stderr, "No GLSL IR for linked %s program %d (shader may be "
+                 "from cache)\n", _mesa_shader_stage_to_string(shader->Stage),
+                 shader_prog->Name);
+      }
       fprintf(stderr, "\n");
    }
 }
 
-extern "C" struct gl_shader *
-brw_new_shader(struct gl_context *ctx, GLuint name, gl_shader_stage stage)
+static void
+unify_interfaces(struct shader_info **infos)
 {
-   struct brw_shader *shader;
+   struct shader_info *prev_info = NULL;
 
-   shader = rzalloc(NULL, struct brw_shader);
-   if (shader) {
-      shader->base.Stage = stage;
-      shader->base.Name = name;
-      _mesa_init_shader(ctx, &shader->base);
-   }
+   for (unsigned i = MESA_SHADER_VERTEX; i < MESA_SHADER_FRAGMENT; i++) {
+      if (!infos[i])
+         continue;
+
+      if (prev_info) {
+         prev_info->outputs_written |= infos[i]->inputs_read &
+            ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER);
+         infos[i]->inputs_read |= prev_info->outputs_written &
+            ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER);
 
-   return &shader->base;
+         prev_info->patch_outputs_written |= infos[i]->patch_inputs_read;
+         infos[i]->patch_inputs_read |= prev_info->patch_outputs_written;
+      }
+      prev_info = infos[i];
+   }
 }
 
 extern "C" GLboolean
 brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
 {
    struct brw_context *brw = brw_context(ctx);
-   const struct brw_compiler *compiler = brw->intelScreen->compiler;
+   const struct brw_compiler *compiler = brw->screen->compiler;
    unsigned int stage;
+   struct shader_info *infos[MESA_SHADER_STAGES] = { 0, };
 
    for (stage = 0; stage < ARRAY_SIZE(shProg->_LinkedShaders); stage++) {
-      struct gl_shader *shader = shProg->_LinkedShaders[stage];
+      struct gl_linked_shader *shader = shProg->_LinkedShaders[stage];
       if (!shader)
          continue;
 
-      struct gl_program *prog =
-         ctx->Driver.NewProgram(ctx, _mesa_shader_stage_to_program(stage),
-                                shader->Name);
-      if (!prog)
-        return false;
+      struct gl_program *prog = shader->Program;
       prog->Parameters = _mesa_new_parameter_list();
 
-      _mesa_copy_linked_program_data((gl_shader_stage) stage, shProg, prog);
+      process_glsl_ir(brw, shProg, shader);
+
+      _mesa_copy_linked_program_data(shProg, shader);
+
+      prog->ShadowSamplers = shader->shadow_samplers;
+      _mesa_update_shader_textures_used(shProg, prog);
+
+      bool debug_enabled =
+         (INTEL_DEBUG & intel_debug_flag_for_shader_stage(shader->Stage));
+
+      if (debug_enabled && shader->ir) {
+         fprintf(stderr, "GLSL IR for native %s shader %d:\n",
+                 _mesa_shader_stage_to_string(shader->Stage), shProg->Name);
+         _mesa_print_ir(stderr, shader->ir, NULL);
+         fprintf(stderr, "\n\n");
+      }
 
-      process_glsl_ir((gl_shader_stage) stage, brw, shProg, shader);
+      prog->nir = brw_create_nir(brw, shProg, prog, (gl_shader_stage) stage,
+                                 compiler->scalar_stage[stage]);
+      infos[stage] = prog->nir->info;
 
       /* Make a pass over the IR to add state references for any built-in
        * uniforms that are used.  This has to be done now (during linking).
@@ -229,38 +220,27 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
        * too late.  At that point, the values for the built-in uniforms won't
        * get sent to the shader.
        */
-      foreach_in_list(ir_instruction, node, shader->ir) {
-         ir_variable *var = node->as_variable();
-
-         if ((var == NULL) || (var->data.mode != ir_var_uniform)
-             || (strncmp(var->name, "gl_", 3) != 0))
-            continue;
-
-         const ir_state_slot *const slots = var->get_state_slots();
-         assert(slots != NULL);
-
-         for (unsigned int i = 0; i < var->get_num_state_slots(); i++) {
-            _mesa_add_state_reference(prog->Parameters,
-                                      (gl_state_index *) slots[i].tokens);
+      nir_foreach_variable(var, &prog->nir->uniforms) {
+         if (strncmp(var->name, "gl_", 3) == 0) {
+            const nir_state_slot *const slots = var->state_slots;
+            assert(var->state_slots != NULL);
+
+            for (unsigned int i = 0; i < var->num_state_slots; i++) {
+               _mesa_add_state_reference(prog->Parameters,
+                                         (gl_state_index *)slots[i].tokens);
+            }
          }
       }
-
-      do_set_program_inouts(shader->ir, prog, shader->Stage);
-
-      prog->SamplersUsed = shader->active_samplers;
-      prog->ShadowSamplers = shader->shadow_samplers;
-      _mesa_update_shader_textures_used(shProg, prog);
-
-      _mesa_reference_program(ctx, &shader->Program, prog);
-
-      brw_add_texrect_params(prog);
-
-      prog->nir = brw_create_nir(brw, shProg, prog, (gl_shader_stage) stage,
-                                 compiler->scalar_stage[stage]);
-
-      _mesa_reference_program(ctx, &prog, NULL);
    }
 
+   /* The linker tries to dead code eliminate unused varying components,
+    * and make sure interfaces match.  But it isn't able to do so in all
+    * cases.  So, explicitly make the interfaces match by OR'ing together
+    * the inputs_read/outputs_written bitfields of adjacent stages.
+    */
+   if (!shProg->SeparateShader)
+      unify_interfaces(infos);
+
    if ((ctx->_Shader->Flags & GLSL_DUMP) && shProg->Name != 0) {
       for (unsigned i = 0; i < shProg->NumShaders; i++) {
          const struct gl_shader *sh = shProg->Shaders[i];
@@ -279,5 +259,16 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
       return false;
 
    build_program_resource_list(ctx, shProg);
+
+   for (stage = 0; stage < ARRAY_SIZE(shProg->_LinkedShaders); stage++) {
+      struct gl_linked_shader *shader = shProg->_LinkedShaders[stage];
+      if (!shader)
+         continue;
+
+      /* The GLSL IR won't be needed anymore. */
+      ralloc_free(shader->ir);
+      shader->ir = NULL;
+   }
+
    return true;
 }