summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2013-10-16 12:27:37 -0700
committerPaul Berry <stereotype441@gmail.com>2013-10-24 22:00:53 -0700
commit3c2feb1969db110523093740ace594b5c9d75a25 (patch)
tree62f4cca4bf8c4889ec9cf01d540a41cd998032ac /src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
parent03ac2c7223f7645e30028bf59b4c9cf0f5734fc0 (diff)
downloadexternal_mesa3d-3c2feb1969db110523093740ace594b5c9d75a25.zip
external_mesa3d-3c2feb1969db110523093740ace594b5c9d75a25.tar.gz
external_mesa3d-3c2feb1969db110523093740ace594b5c9d75a25.tar.bz2
i965/gs: If a DUAL_OBJECT gs would spill, fall back to DUAL_INSTANCED.
This is similar to what we do for 16-wide vs 8-wide fragment shaders. First we try compiling the geometry shader in DUAL_OBJECT mode. If we can't do that without spilling, we fall back on DUAL_INSTANCED mode, which should require less spilling (since it uses an interleaved layout of payload registers). In an ideal world we'd fall back to SINGLE mode, which would allow us to interleave general-purpose registers too (resulting in even less likelihood of spilling). But at the moment, the vec4 generator and visitor classes don't have the infrastructure to interleave general purpose registers, so DUAL_INSTANCED is the best we can do. As a side benefit this paves the way for implementing instanced geometry shaders (which are incompatible with DUAL_OBJECT mode). Since most geometry shaders used in piglit testing are small, DUAL_INSTANCED mode won't get exercised very much in a normal piglit run. To force DUAL_INSTANCED mode to be used for all geometry shaders, set INTEL_DEBUG=nodualobj. Reviewed-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp')
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp30
1 files changed, 28 insertions, 2 deletions
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 b135f61..adbb1cf 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
@@ -550,8 +550,34 @@ 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;
+ /* Compile the geometry shader in DUAL_OBJECT dispatch mode, if we can do
+ * so without spilling.
+ */
+ if (likely(!(INTEL_DEBUG & DEBUG_NO_DUAL_OBJECT_GS))) {
+ c->prog_data.dual_instanced_dispatch = false;
+
+ vec4_gs_visitor v(brw, c, prog, shader, mem_ctx, true /* no_spills */);
+ if (v.run()) {
+ vec4_generator g(brw, prog, &c->gp->program.Base, &c->prog_data.base,
+ mem_ctx, INTEL_DEBUG & DEBUG_GS);
+ const unsigned *generated =
+ g.generate_assembly(&v.instructions, final_assembly_size);
+
+ return generated;
+ }
+ }
+
+ /* Either we failed to compile in DUAL_OBJECT mode (probably because it
+ * would have required spilling) or DUAL_OBJECT mode is disabled. So fall
+ * back to DUAL_INSTANCED mode, which consumes fewer registers.
+ *
+ * FIXME: In an ideal world we'd fall back to SINGLE mode, which would
+ * allow us to interleave general purpose registers (resulting in even less
+ * likelihood of spilling). But at the moment, the vec4 generator and
+ * visitor classes don't have the infrastructure to interleave general
+ * purpose registers, so DUAL_INSTANCED is the best we can do.
+ */
+ c->prog_data.dual_instanced_dispatch = true;
vec4_gs_visitor v(brw, c, prog, shader, mem_ctx, false /* no_spills */);
if (!v.run()) {