From 008338bc4e2d9cc5931b9968d019619c09392389 Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Sat, 25 Jan 2014 12:55:24 -0800 Subject: [PATCH] i965: support gl_InvocationID for gen7 v2: * Make gl_InvocationID a system value v3: * Properly shift from R0.1 into DST.4 by adding GS_OPCODE_GET_INSTANCE_ID Signed-off-by: Jordan Justen Acked-by: Paul Berry Reviewed-by: Anuj Phogat --- src/mesa/drivers/dri/i965/brw_defines.h | 12 +++++++++++ src/mesa/drivers/dri/i965/brw_shader.cpp | 2 ++ src/mesa/drivers/dri/i965/brw_vec4.h | 1 + .../drivers/dri/i965/brw_vec4_generator.cpp | 21 +++++++++++++++++++ .../drivers/dri/i965/brw_vec4_gs_visitor.cpp | 16 +++++++++++--- 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 1cbbe67b6c3..1b573448c06 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -902,6 +902,13 @@ enum opcode { * form the final channel mask. */ GS_OPCODE_SET_CHANNEL_MASKS, + + /** + * Get the "Instance ID" fields from the payload. + * + * - dst is the GRF for gl_InvocationID. + */ + GS_OPCODE_GET_INSTANCE_ID, }; enum brw_urb_write_flags { @@ -1538,6 +1545,11 @@ enum brw_message_target { # define BRW_GS_EDGE_INDICATOR_0 (1 << 8) # define BRW_GS_EDGE_INDICATOR_1 (1 << 9) +/* GS Thread Payload + */ +/* R0 */ +# define GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT 27 + /* 3DSTATE_GS "Output Vertex Size" has an effective maximum of 62. It's * counted in multiples of 16 bytes. */ diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index d3a75607846..08ceca1571a 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -527,6 +527,8 @@ brw_instruction_name(enum opcode op) return "prepare_channel_masks"; case GS_OPCODE_SET_CHANNEL_MASKS: return "set_channel_masks"; + case GS_OPCODE_GET_INSTANCE_ID: + return "get_instance_id"; default: /* Yes, this leaks. It's in debug code, it should never occur, and if diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index 1e0d8824f17..6bd8b80cf2f 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -675,6 +675,7 @@ private: void generate_gs_set_dword_2_immed(struct brw_reg dst, struct brw_reg src); void generate_gs_prepare_channel_masks(struct brw_reg dst); void generate_gs_set_channel_masks(struct brw_reg dst, struct brw_reg src); + void generate_gs_get_instance_id(struct brw_reg dst); void generate_oword_dual_block_offsets(struct brw_reg m1, struct brw_reg index); void generate_scratch_write(vec4_instruction *inst, diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp index e0c59bac3d7..d3d593941b2 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp @@ -631,6 +631,23 @@ vec4_generator::generate_gs_set_channel_masks(struct brw_reg dst, brw_pop_insn_state(p); } +void +vec4_generator::generate_gs_get_instance_id(struct brw_reg dst) +{ + /* We want to right shift R0.0 & R0.1 by GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT + * and store into dst.0 & dst.4. So generate the instruction: + * + * shr(8) dst<1> R0<1,4,0> GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT { align1 WE_normal 1Q } + */ + brw_push_insn_state(p); + brw_set_access_mode(p, BRW_ALIGN_1); + dst = retype(dst, BRW_REGISTER_TYPE_UD); + struct brw_reg r0(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD)); + brw_SHR(p, dst, stride(r0, 1, 4, 0), + brw_imm_ud(GEN7_GS_PAYLOAD_INSTANCE_ID_SHIFT)); + brw_pop_insn_state(p); +} + void vec4_generator::generate_oword_dual_block_offsets(struct brw_reg m1, struct brw_reg index) @@ -1211,6 +1228,10 @@ vec4_generator::generate_vec4_instruction(vec4_instruction *instruction, generate_gs_set_channel_masks(dst, src[0]); break; + case GS_OPCODE_GET_INSTANCE_ID: + generate_gs_get_instance_id(dst); + break; + case SHADER_OPCODE_SHADER_TIME_ADD: brw_shader_time_add(p, src[0], prog_data->base.binding_table.shader_time_start); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp index d57c6197c20..1d00796be36 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp @@ -51,9 +51,19 @@ vec4_gs_visitor::vec4_gs_visitor(struct brw_context *brw, dst_reg * vec4_gs_visitor::make_reg_for_system_value(ir_variable *ir) { - /* Geometry shaders don't use any system values. */ - assert(!"Unreached"); - return NULL; + dst_reg *reg = new(mem_ctx) dst_reg(this, ir->type); + + switch (ir->data.location) { + case SYSTEM_VALUE_INVOCATION_ID: + this->current_annotation = "initialize gl_InvocationID"; + emit(GS_OPCODE_GET_INSTANCE_ID, *reg); + break; + default: + assert(!"not reached"); + break; + } + + return reg; } -- 2.30.2