nir: Use a system value for gl_PrimitiveIDIn.
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>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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 */
|
||||
/*@}*/
|
||||
|
@@ -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]);
|
||||
|
Reference in New Issue
Block a user