nir: Use a system value for gl_PrimitiveIDIn.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 23 Sep 2015 22:40:33 +0000 (15:40 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 29 Sep 2015 21:19:32 +0000 (14:19 -0700)
At least on Intel hardware, gl_PrimitiveIDIn comes in as a special part
of the payload rather than a normal input.  This is typically what we
use system values for.  Dave and Ilia also agree that a system value
would be nicer.

At some point, we should change it at the GLSL IR level as well.  But
that requires changing most of the drivers.  For now, let's at least
make NIR do the right thing, which is easy.

v2: Add a comment about not creating a temporary (suggested by Iago).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
src/glsl/nir/glsl_to_nir.cpp
src/glsl/nir/nir.c
src/glsl/nir/nir_intrinsics.h
src/glsl/shader_enums.h
src/mesa/drivers/dri/i965/brw_vec4_gs_nir.cpp

index f03a107a9015ca59fb9c9223c83df31236b3f916..c0b26340f0d32e54ef7d4b26e51846a0748dab30 100644 (file)
@@ -271,6 +271,11 @@ nir_visitor::visit(ir_variable *ir)
          /* For whatever reason, GLSL IR makes gl_FrontFacing an input */
          var->data.location = SYSTEM_VALUE_FRONT_FACE;
          var->data.mode = nir_var_system_value;
+      } else if (shader->stage == MESA_SHADER_GEOMETRY &&
+                 ir->data.location == VARYING_SLOT_PRIMITIVE_ID) {
+         /* For whatever reason, GLSL IR makes gl_PrimitiveIDIn an input */
+         var->data.location = SYSTEM_VALUE_PRIMITIVE_ID;
+         var->data.mode = nir_var_system_value;
       } else {
          var->data.mode = nir_var_shader_in;
       }
index 57fd959c9313b58687bc148b58dae4f29b7e3995..fe10b380ef09548276ff6fe2796a58e8f018de08 100644 (file)
@@ -1489,10 +1489,11 @@ nir_intrinsic_from_system_value(gl_system_value val)
       return nir_intrinsic_load_work_group_id;
    case SYSTEM_VALUE_NUM_WORK_GROUPS:
       return nir_intrinsic_load_num_work_groups;
+   case SYSTEM_VALUE_PRIMITIVE_ID:
+      return nir_intrinsic_load_primitive_id;
    /* FINISHME: Add tessellation intrinsics.
    case SYSTEM_VALUE_TESS_COORD:
    case SYSTEM_VALUE_VERTICES_IN:
-   case SYSTEM_VALUE_PRIMITIVE_ID:
    case SYSTEM_VALUE_TESS_LEVEL_OUTER:
    case SYSTEM_VALUE_TESS_LEVEL_INNER:
     */
@@ -1529,6 +1530,8 @@ nir_system_value_from_intrinsic(nir_intrinsic_op intrin)
       return SYSTEM_VALUE_NUM_WORK_GROUPS;
    case nir_intrinsic_load_work_group_id:
       return SYSTEM_VALUE_WORK_GROUP_ID;
+   case nir_intrinsic_load_primitive_id:
+      return SYSTEM_VALUE_PRIMITIVE_ID;
    /* FINISHME: Add tessellation intrinsics.
       return SYSTEM_VALUE_TESS_COORD;
       return SYSTEM_VALUE_VERTICES_IN;
index 649312fec51e6652065c3540a4d1ac7e0f7ae449..ac4c2ba0eb271151575591603cd44b88efcd63c6 100644 (file)
@@ -194,6 +194,7 @@ SYSTEM_VALUE(instance_id, 1, 0)
 SYSTEM_VALUE(sample_id, 1, 0)
 SYSTEM_VALUE(sample_pos, 2, 0)
 SYSTEM_VALUE(sample_mask_in, 1, 0)
+SYSTEM_VALUE(primitive_id, 1, 0)
 SYSTEM_VALUE(invocation_id, 1, 0)
 SYSTEM_VALUE(local_invocation_id, 3, 0)
 SYSTEM_VALUE(work_group_id, 3, 0)
index 99acc640496010e9c6dd1c6b2a4dbb0a1c20aace..2a5d2c5bfa75199c13718c317c2b77020dd87919 100644 (file)
@@ -399,7 +399,7 @@ typedef enum
    /*@{*/
    SYSTEM_VALUE_TESS_COORD,
    SYSTEM_VALUE_VERTICES_IN,    /**< Tessellation vertices in input patch */
-   SYSTEM_VALUE_PRIMITIVE_ID,   /**< (currently not used by GS) */
+   SYSTEM_VALUE_PRIMITIVE_ID,
    SYSTEM_VALUE_TESS_LEVEL_OUTER, /**< TES input */
    SYSTEM_VALUE_TESS_LEVEL_INNER, /**< TES input */
    /*@}*/
index 4f4e1e12fabf0e8897fd0d579ddee5cc7b2f3408..64a90e5ddff2da95c3faaf96570e0bb9c58478c3 100644 (file)
@@ -72,6 +72,10 @@ vec4_gs_visitor::nir_setup_system_value_intrinsic(nir_intrinsic_instr *instr)
    dst_reg *reg;
 
    switch (instr->intrinsic) {
+   case nir_intrinsic_load_primitive_id:
+      /* We'll just read g1 directly; don't create a temporary. */
+      break;
+
    case nir_intrinsic_load_invocation_id:
       reg = &this->nir_system_values[SYSTEM_VALUE_INVOCATION_ID];
       if (reg->file == BAD_FILE)
@@ -111,6 +115,12 @@ vec4_gs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
          retype(get_nir_src(instr->src[0], 1), BRW_REGISTER_TYPE_UD);
       break;
 
+   case nir_intrinsic_load_primitive_id:
+      assert(c->prog_data.include_primitive_id);
+      dest = get_nir_dest(instr->dest, BRW_REGISTER_TYPE_D);
+      emit(MOV(dest, retype(brw_vec4_grf(1, 0), BRW_REGISTER_TYPE_D)));
+      break;
+
    case nir_intrinsic_load_invocation_id: {
       src_reg invocation_id =
          src_reg(nir_system_values[SYSTEM_VALUE_INVOCATION_ID]);