nir: Add a flag to lower_io to force "sample" interpolation
[mesa.git] / src / mesa / drivers / dri / i965 / brw_tcs.c
index 5a514ef21e917552385ba1936007f65d223292ff..44629ad34655313dccba41b75d073670715e7298 100644 (file)
@@ -153,6 +153,8 @@ brw_tcs_debug_recompile(struct brw_context *brw,
                       key->patch_outputs_written);
    found |= key_debug(brw, "TES primitive mode", old_key->tes_primitive_mode,
                       key->tes_primitive_mode);
+   found |= key_debug(brw, "quads and equal_spacing workaround",
+                      old_key->quads_workaround, key->quads_workaround);
    found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
 
    if (!found) {
@@ -168,7 +170,7 @@ brw_codegen_tcs_prog(struct brw_context *brw,
 {
    struct gl_context *ctx = &brw->ctx;
    const struct brw_compiler *compiler = brw->intelScreen->compiler;
-   const struct brw_device_info *devinfo = compiler->devinfo;
+   const struct gen_device_info *devinfo = compiler->devinfo;
    struct brw_stage_state *stage_state = &brw->tcs.base;
    nir_shader *nir;
    struct brw_tcs_prog_data prog_data;
@@ -197,7 +199,7 @@ brw_codegen_tcs_prog(struct brw_context *brw,
     * padding around uniform values below vec4 size, so the worst case is that
     * every uniform is a float which gets padded to the size of a vec4.
     */
-   struct gl_shader *tcs = shader_prog ?
+   struct gl_linked_shader *tcs = shader_prog ?
       shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL] : NULL;
    int param_count = nir->num_uniforms / 4;
 
@@ -225,19 +227,24 @@ brw_codegen_tcs_prog(struct brw_context *brw,
        */
       const float **param = (const float **) prog_data.base.base.param;
       static float zero = 0.0f;
-      for (int i = 0; i < 4; i++) {
-         param[7 - i] = &ctx->TessCtrlProgram.patch_default_outer_level[i];
-      }
+      for (int i = 0; i < 8; i++)
+         param[i] = &zero;
 
       if (key->tes_primitive_mode == GL_QUADS) {
+         for (int i = 0; i < 4; i++)
+            param[7 - i] = &ctx->TessCtrlProgram.patch_default_outer_level[i];
+
          param[3] = &ctx->TessCtrlProgram.patch_default_inner_level[0];
          param[2] = &ctx->TessCtrlProgram.patch_default_inner_level[1];
-         param[1] = &zero;
-         param[0] = &zero;
       } else if (key->tes_primitive_mode == GL_TRIANGLES) {
+         for (int i = 0; i < 3; i++)
+            param[7 - i] = &ctx->TessCtrlProgram.patch_default_outer_level[i];
+
          param[4] = &ctx->TessCtrlProgram.patch_default_inner_level[0];
-         for (int i = 0; i < 4; i++)
-            param[i] = &zero;
+      } else {
+         assert(key->tes_primitive_mode == GL_ISOLINES);
+         param[7] = &ctx->TessCtrlProgram.patch_default_outer_level[1];
+         param[6] = &ctx->TessCtrlProgram.patch_default_outer_level[0];
       }
    }
 
@@ -289,11 +296,9 @@ brw_codegen_tcs_prog(struct brw_context *brw,
    }
 
    /* Scratch space is used for register spilling */
-   if (prog_data.base.base.total_scratch) {
-      brw_get_scratch_bo(brw, &stage_state->scratch_bo,
-                        prog_data.base.base.total_scratch *
-                         brw->max_hs_threads);
-   }
+   brw_alloc_stage_scratch(brw, stage_state,
+                           prog_data.base.base.total_scratch,
+                           brw->max_hs_threads);
 
    brw_upload_cache(&brw->cache, BRW_CACHE_TCS_PROG,
                     key, sizeof(*key),
@@ -334,7 +339,8 @@ brw_upload_tcs_prog(struct brw_context *brw,
 
    memset(&key, 0, sizeof(key));
 
-   key.input_vertices = ctx->TessCtrlProgram.patch_vertices;
+   if (brw->gen < 8 || !tcp)
+      key.input_vertices = ctx->TessCtrlProgram.patch_vertices;
    key.outputs_written = per_vertex_slots;
    key.patch_outputs_written = per_patch_slots;
 
@@ -342,13 +348,15 @@ brw_upload_tcs_prog(struct brw_context *brw,
     * based on the domain the DS is expecting to tessellate.
     */
    key.tes_primitive_mode = tep->program.PrimitiveMode;
+   key.quads_workaround = brw->gen < 9 &&
+                          tep->program.PrimitiveMode == GL_QUADS &&
+                          tep->program.Spacing == GL_EQUAL;
 
    if (tcp) {
       key.program_string_id = tcp->id;
 
       /* _NEW_TEXTURE */
-      brw_populate_sampler_prog_key_data(ctx, prog, stage_state->sampler_count,
-                                         &key.tex);
+      brw_populate_sampler_prog_key_data(ctx, prog, &key.tex);
    } else {
       key.outputs_written = tep->program.Base.InputsRead;
    }
@@ -379,6 +387,8 @@ brw_tcs_precompile(struct gl_context *ctx,
 
    struct gl_tess_ctrl_program *tcp = (struct gl_tess_ctrl_program *)prog;
    struct brw_tess_ctrl_program *btcp = brw_tess_ctrl_program(tcp);
+   const struct gl_linked_shader *tes =
+      shader_prog->_LinkedShaders[MESA_SHADER_TESS_EVAL];
 
    memset(&key, 0, sizeof(key));
 
@@ -386,11 +396,19 @@ brw_tcs_precompile(struct gl_context *ctx,
    brw_setup_tex_for_precompile(brw, &key.tex, prog);
 
    /* Guess that the input and output patches have the same dimensionality. */
-   key.input_vertices = shader_prog->TessCtrl.VerticesOut;
+   if (brw->gen < 8) {
+      key.input_vertices = shader_prog->
+         _LinkedShaders[MESA_SHADER_TESS_CTRL]->info.TessCtrl.VerticesOut;
+   }
 
-   key.tes_primitive_mode =
-      shader_prog->_LinkedShaders[MESA_SHADER_TESS_EVAL] ?
-      shader_prog->TessEval.PrimitiveMode : GL_TRIANGLES;
+   if (tes) {
+      key.tes_primitive_mode = tes->info.TessEval.PrimitiveMode;
+      key.quads_workaround = brw->gen < 9 &&
+                             tes->info.TessEval.PrimitiveMode == GL_QUADS &&
+                             tes->info.TessEval.Spacing == GL_EQUAL;
+   } else {
+      key.tes_primitive_mode = GL_TRIANGLES;
+   }
 
    key.outputs_written = prog->OutputsWritten;
    key.patch_outputs_written = prog->PatchOutputsWritten;