summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2016-12-14 03:29:29 -0800
committerKenneth Graunke <[email protected]>2017-01-05 01:54:52 -0800
commit480d6c1653713dcae617ac523b2ca5deee01c845 (patch)
tree050a22bc656fbff0720d9dba1ea36e10fb4c91ca /src/mesa
parent8dc92a56134580dc47e48a046aff347776aaac34 (diff)
i965: Fix last slot calculations
If the VUE map has slots at the end which the shader does not write, then we'd "flush" (constructing an URB write) on the last output it actually wrote. Then, we'd construct another SEND with EOT, but with no actual payload data. That's not legal. For example, SSO programs have clip distance slots allocated no matter what, but the shader may not write them. If it doesn't write any user defined varyings, then the clip distance slots will be the last ones. Found while debugging dEQP-VK.tessellation.shader_input_output.gl_position_vs_to_tcs_to_tes Cc: [email protected] Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 14415bd5c7a..3775e6c4a09 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -672,6 +672,17 @@ fs_visitor::emit_urb_writes(const fs_reg &gs_vertex_count)
length = 0;
urb_offset = starting_urb_offset;
flush = false;
+
+ /* SSO shaders can have VUE slots allocated which are never actually
+ * written to, so ignore them when looking for the last (written) slot.
+ */
+ int last_slot = vue_map->num_slots - 1;
+ while (last_slot > 0 &&
+ (vue_map->slot_to_varying[last_slot] == BRW_VARYING_SLOT_PAD ||
+ outputs[vue_map->slot_to_varying[last_slot]].file == BAD_FILE)) {
+ last_slot--;
+ }
+
for (slot = 0; slot < vue_map->num_slots; slot++) {
int varying = vue_map->slot_to_varying[slot];
switch (varying) {
@@ -757,8 +768,7 @@ fs_visitor::emit_urb_writes(const fs_reg &gs_vertex_count)
* the last slot or if we need to flush (see BAD_FILE varying case
* above), emit a URB write send now to flush out the data.
*/
- int last = slot == vue_map->num_slots - 1;
- if (length == 8 || last)
+ if (length == 8 || slot == last_slot)
flush = true;
if (flush) {
fs_reg *payload_sources =
@@ -777,7 +787,7 @@ fs_visitor::emit_urb_writes(const fs_reg &gs_vertex_count)
header_size);
fs_inst *inst = abld.emit(opcode, reg_undef, payload);
- inst->eot = last && stage != MESA_SHADER_GEOMETRY;
+ inst->eot = slot == last_slot && stage != MESA_SHADER_GEOMETRY;
inst->mlen = length + header_size;
inst->offset = urb_offset;
urb_offset = starting_urb_offset + slot + 1;