summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2013-10-16 12:04:19 -0700
committerPaul Berry <[email protected]>2013-10-24 22:00:46 -0700
commita05589ea0b7b760e0473af6c7ab5d796520f5948 (patch)
tree5469999caa9a54d0b7dd29b959e2828b6dda2dde
parent34cba13ef822faebbb1f10f1400f87fa9bf70d60 (diff)
i965/gs: Add the ability to compile a DUAL_INSTANCED geometry shader.
Not yet enabled. Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h6
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp25
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.h3
-rw-r--r--src/mesa/drivers/dri/i965/gen7_gs_state.c4
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) |