summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2016-06-26 00:39:19 -0700
committerKenneth Graunke <[email protected]>2016-06-27 16:36:51 -0700
commit7e7e501acf3ea609e3e2e8bb4091a5a20ae3adc2 (patch)
treec910996798423d2abbd44e7afbea5c7726fbf972
parenta36a73a7b8a058c037cb0307b57ac97292953c58 (diff)
i965: Make emit_urb_writes() not produce an EOT message for GS.
emit_urb_writes() contains code to emit an EOT write with no actual data when there are no output varyings. This makes sense for the VS and TES stages, where it's called once at the end of the program. However, in the geometry shader stage, emit_urb_writes() is called once for every EmitVertex(). We explicitly emit a URB write with EOT set at the end of the shader, separately from this path. So we'd better not terminate the thread. This could get us into trouble for shaders which do EmitVertex() with no varyings followed by SSBO/image/atomic writes. It also caused us to emit multiple sends with EOT set, which apparently confuses the register allocator into not using g112-g127 for all but the first one. This caused EU validation failures in OglGSCloth shaders in shader-db. (The actual application was fine, but shader-db thinks there are no outputs because it doesn't understand transform feedback.) Cc: [email protected] Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Iago Toral Quiroga <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 3a49794c9cf..17eba8deb22 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -594,6 +594,13 @@ fs_visitor::emit_urb_writes(const fs_reg &gs_vertex_count)
* "The write data payload can be between 1 and 8 message phases long."
*/
if (vue_map->slots_valid == 0) {
+ /* For GS, just turn EmitVertex() into a no-op. We don't want it to
+ * end the thread, and emit_gs_thread_end() already emits a SEND with
+ * EOT at the end of the program for us.
+ */
+ if (stage == MESA_SHADER_GEOMETRY)
+ return;
+
fs_reg payload = fs_reg(VGRF, alloc.allocate(2), BRW_REGISTER_TYPE_UD);
bld.exec_all().MOV(payload, urb_handle);