From a05589ea0b7b760e0473af6c7ab5d796520f5948 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Wed, 16 Oct 2013 12:04:19 -0700 Subject: [PATCH] i965/gs: Add the ability to compile a DUAL_INSTANCED geometry shader. Not yet enabled. Reviewed-by: Eric Anholt --- src/mesa/drivers/dri/i965/brw_context.h | 6 +++++ .../drivers/dri/i965/brw_vec4_gs_visitor.cpp | 25 ++++++++++++++----- .../drivers/dri/i965/brw_vec4_gs_visitor.h | 3 ++- src/mesa/drivers/dri/i965/gen7_gs_state.c | 4 ++- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 39f45c64f87..4bff63ed01a 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -641,6 +641,12 @@ struct brw_gs_prog_data unsigned control_data_format; bool include_primitive_id; + + /** + * True if the thread should be dispatched in DUAL_INSTANCE mode, false if + * it should be dispatched in DUAL_OBJECT mode. + */ + bool dual_instanced_dispatch; }; /** Number of texture sampler units */ 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 a44f5930029..8af7a3cf6de 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp @@ -57,7 +57,8 @@ vec4_gs_visitor::make_reg_for_system_value(ir_variable *ir) int -vec4_gs_visitor::setup_varying_inputs(int payload_reg, int *attribute_map) +vec4_gs_visitor::setup_varying_inputs(int payload_reg, int *attribute_map, + int attributes_per_reg) { /* For geometry shaders there are N copies of the input attributes, where N * is the number of input vertices. attribute_map[BRW_VARYING_SLOT_COUNT * @@ -75,11 +76,14 @@ vec4_gs_visitor::setup_varying_inputs(int payload_reg, int *attribute_map) int varying = c->input_vue_map.slot_to_varying[slot]; for (unsigned vertex = 0; vertex < num_input_vertices; vertex++) { attribute_map[BRW_VARYING_SLOT_COUNT * vertex + varying] = - payload_reg + input_array_stride * vertex + slot; + attributes_per_reg * payload_reg + input_array_stride * vertex + + slot; } } - return payload_reg + input_array_stride * num_input_vertices; + int regs_used = ALIGN(input_array_stride * num_input_vertices, + attributes_per_reg) / attributes_per_reg; + return payload_reg + regs_used; } @@ -88,6 +92,11 @@ vec4_gs_visitor::setup_payload() { int attribute_map[BRW_VARYING_SLOT_COUNT * MAX_GS_INPUT_VERTICES]; + /* If we are in dual instanced mode, then attributes are going to be + * interleaved, so one register contains two attribute slots. + */ + int attributes_per_reg = c->prog_data.dual_instanced_dispatch ? 2 : 1; + /* If a geometry shader tries to read from an input that wasn't written by * the vertex shader, that produces undefined results, but it shouldn't * crash anything. So initialize attribute_map to zeros--that ensures that @@ -105,13 +114,14 @@ vec4_gs_visitor::setup_payload() /* If the shader uses gl_PrimitiveIDIn, that goes in r1. */ if (c->prog_data.include_primitive_id) - attribute_map[VARYING_SLOT_PRIMITIVE_ID] = reg++; + attribute_map[VARYING_SLOT_PRIMITIVE_ID] = attributes_per_reg * reg++; reg = setup_uniforms(reg); - reg = setup_varying_inputs(reg, attribute_map); + reg = setup_varying_inputs(reg, attribute_map, attributes_per_reg); - lower_attributes_to_hw_regs(attribute_map, false /* interleaved */); + lower_attributes_to_hw_regs(attribute_map, + c->prog_data.dual_instanced_dispatch); this->first_non_payload_grf = reg; } @@ -534,6 +544,9 @@ brw_gs_emit(struct brw_context *brw, printf("\n\n"); } + /* Assume the geometry shader will use DUAL_OBJECT dispatch for now. */ + c->prog_data.dual_instanced_dispatch = false; + vec4_gs_visitor v(brw, c, prog, shader, mem_ctx, false /* no_spills */); if (!v.run()) { prog->LinkStatus = false; diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h index 39d20bb7cb8..68756f74904 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h +++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h @@ -97,7 +97,8 @@ protected: virtual void visit(ir_end_primitive *); private: - int setup_varying_inputs(int payload_reg, int *attribute_map); + int setup_varying_inputs(int payload_reg, int *attribute_map, + int attributes_per_reg); void emit_control_data_bits(); src_reg vertex_count; diff --git a/src/mesa/drivers/dri/i965/gen7_gs_state.c b/src/mesa/drivers/dri/i965/gen7_gs_state.c index c272b7d8b57..2602200eb68 100644 --- a/src/mesa/drivers/dri/i965/gen7_gs_state.c +++ b/src/mesa/drivers/dri/i965/gen7_gs_state.c @@ -136,7 +136,9 @@ upload_gs_state(struct brw_context *brw) ((brw->max_gs_threads - 1) << max_threads_shift) | (brw->gs.prog_data->control_data_header_size_hwords << GEN7_GS_CONTROL_DATA_HEADER_SIZE_SHIFT) | - GEN7_GS_DISPATCH_MODE_DUAL_OBJECT | + (brw->gs.prog_data->dual_instanced_dispatch ? + GEN7_GS_DISPATCH_MODE_DUAL_INSTANCE : + GEN7_GS_DISPATCH_MODE_DUAL_OBJECT) | GEN6_GS_STATISTICS_ENABLE | (brw->gs.prog_data->include_primitive_id ? GEN7_GS_INCLUDE_PRIMITIVE_ID : 0) | -- 2.30.2