summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Justen <[email protected]>2014-01-25 12:55:24 -0800
committerJordan Justen <[email protected]>2014-02-20 10:33:09 -0800
commit008338bc4e2d9cc5931b9968d019619c09392389 (patch)
treeb98f9678650dae38536d0f3a7e06bbc7e060c773
parentd09901993539385c015c6389310c186cba9bb263 (diff)
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 <[email protected]> Acked-by: Paul Berry <[email protected]> Reviewed-by: Anuj Phogat <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h12
-rw-r--r--src/mesa/drivers/dri/i965/brw_shader.cpp2
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_generator.cpp21
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp16
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
@@ -632,6 +632,23 @@ vec4_generator::generate_gs_set_channel_masks(struct brw_reg dst,
}
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;
}