[Mesa-dev] [PATCH v4 8/9] i965: support gl_InvocationID for gen7
Anuj Phogat
anuj.phogat at gmail.com
Wed Feb 12 18:40:17 PST 2014
On Thu, Feb 6, 2014 at 6:28 PM, Jordan Justen <jordan.l.justen at intel.com> wrote:
> 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 <jordan.l.justen at intel.com>
> Acked-by: Paul Berry <stereotype441 at gmail.com>
> ---
> 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 +
> src/mesa/drivers/dri/i965/brw_vec4_generator.cpp | 20 ++++++++++++++++++++
> src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp | 16 +++++++++++++---
> 5 files changed, 48 insertions(+), 3 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
> index 75d09fc..199a699 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 6cc2595..5e3005a 100644
> --- a/src/mesa/drivers/dri/i965/brw_shader.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
> @@ -525,6 +525,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 e17b5cd..182a1e1 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4.h
> +++ b/src/mesa/drivers/dri/i965/brw_vec4.h
> @@ -616,6 +616,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 94d1e79..a48d829 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
> @@ -639,6 +639,22 @@ 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_all }
But the instruction generated here uses WE_normal:
shr(8) g5<1>UD g0<1,4,0>UD 0x0000001bUD {
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)
> {
> @@ -1218,6 +1234,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 40743cc..360703b 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;
> }
>
>
> --
> 1.9.rc1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list