i965: Implement gl_PatchVerticesIn by baking it into brw_tcs_prog_key.
authorKenneth Graunke <kenneth@whitecape.org>
Thu, 26 Nov 2015 07:35:29 +0000 (23:35 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 22 Dec 2015 10:12:05 +0000 (02:12 -0800)
The hardware provides us no decent way of getting at the number of input
vertices in the patch topology from the tessellation control shader.
It's actually very surprising - normally this sort of information would
be available in the thread payload.

For the precompile, we guess that the number of vertices will be the
same for both the input and output patches.  This usually seems to be
the case.

On Gen8+, we could pass in an extra push constant containing this value.
We may be able to do that on Haswell too.  It's quite a bit trickier on
Ivybridge, however.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/mesa/drivers/dri/i965/brw_compiler.h
src/mesa/drivers/dri/i965/brw_tcs.c
src/mesa/drivers/dri/i965/brw_vec4_tcs.cpp

index e6bae8e902ff40b16cb3b747690f9dbdcd88fe20..59084e62035f88deeab6f112cc9fd0f5b7ba3a02 100644 (file)
@@ -198,6 +198,8 @@ struct brw_tcs_prog_key
 
    GLenum tes_primitive_mode;
 
+   unsigned input_vertices;
+
    struct brw_sampler_prog_key_data tex;
 };
 
index b33a16d17102d0d4d7dece626cc69724f3c5d06f..b5eb4cdde5ec3d767f9a4ac1f54ea30fed4ca7d7 100644 (file)
@@ -65,6 +65,8 @@ brw_tcs_debug_recompile(struct brw_context *brw,
       return;
    }
 
+   found |= key_debug(brw, "input vertices", old_key->input_vertices,
+                      key->input_vertices);
    found |= key_debug(brw, "TES primitive mode", old_key->tes_primitive_mode,
                       key->tes_primitive_mode);
    found |= brw_debug_recompile_sampler_key(brw, &old_key->tex, &key->tex);
@@ -188,6 +190,7 @@ brw_upload_tcs_prog(struct brw_context *brw)
 
    if (!brw_state_dirty(brw,
                         _NEW_TEXTURE,
+                        BRW_NEW_PATCH_PRIMITIVE |
                         BRW_NEW_TESS_CTRL_PROGRAM |
                         BRW_NEW_TESS_EVAL_PROGRAM))
       return;
@@ -207,6 +210,8 @@ brw_upload_tcs_prog(struct brw_context *brw)
 
    key.program_string_id = tcp->id;
 
+   key.input_vertices = ctx->TessCtrlProgram.patch_vertices;
+
    /* _NEW_TEXTURE */
    brw_populate_sampler_prog_key_data(ctx, prog, stage_state->sampler_count,
                                       &key.tex);
@@ -251,6 +256,9 @@ brw_tcs_precompile(struct gl_context *ctx,
    key.program_string_id = btcp->id;
    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;
+
    key.tes_primitive_mode = GL_TRIANGLES;
 
    success = brw_codegen_tcs_prog(brw, shader_prog, btcp, &key);
index 22224d1186be4df4b21f07d199f673a2e6082dba..bd985598f6584559b27e86bb2769661e7eac6ad1 100644 (file)
@@ -257,7 +257,8 @@ vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
            get_nir_dest(instr->dest, BRW_REGISTER_TYPE_UD));
       break;
    case nir_intrinsic_load_patch_vertices_in:
-      unreachable("XXX: gl_PatchVerticesIn not implemented yet.");
+      emit(MOV(get_nir_dest(instr->dest, BRW_REGISTER_TYPE_D),
+               brw_imm_d(key->input_vertices)));
       break;
    case nir_intrinsic_load_per_vertex_input: {
       src_reg indirect_offset = get_indirect_offset(instr);