summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2015-02-26 17:45:49 -0800
committerEmil Velikov <emil.l.velikov@gmail.com>2015-03-11 18:35:39 +0000
commitfbd06fe65c0fe57f0dea96c87d9f0eb5abc72bb7 (patch)
tree055ab899d79e783c8462ffda469662addbac81bf
parentc232d765affc06cc6e81ddee07656919e7f17aa5 (diff)
i965/fs: Don't issue FB writes for bound but unwritten color targets.
We used to loop over all color attachments, and emit FB writes for each one, even if the shader didn't write to a corresponding output variable. Those color attachments would be filled with garbage (undefined values). Football Manager binds a framebuffer with 4 color attachments, but draws to it using a shader that only writes to gl_FragData[0..2]. This meant that color attachment 3 would be filled with garbage, resulting in rendering artifacts. Now we skip writing to it, fixing rendering. Writes to gl_FragColor initialize outputs[0..nr_color_regions-1] to GRFs, while writes to gl_FragData[i] initialize outputs[i]. Thanks to Jason Ekstrand for tracking this down. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=86747 Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com> Cc: mesa-stable@lists.freedesktop.org (cherry picked from commit e95969cd9548033250ba12f2adf11740319b41e7) Conflicts: src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp12
1 files changed, 9 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 0e4b814e73c..80488926d02 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -3520,7 +3520,7 @@ fs_visitor::emit_fb_writes()
do_dual_src = false;
}
- fs_inst *inst;
+ fs_inst *inst = NULL;
if (do_dual_src) {
this->current_annotation = ralloc_asprintf(this->mem_ctx,
"FB dual-source write");
@@ -3528,8 +3528,12 @@ fs_visitor::emit_fb_writes()
reg_undef, 4);
inst->target = 0;
prog_data->dual_src_blend = true;
- } else if (key->nr_color_regions > 0) {
+ } else {
for (int target = 0; target < key->nr_color_regions; target++) {
+ /* Skip over outputs that weren't written. */
+ if (this->outputs[target].file == BAD_FILE)
+ continue;
+
this->current_annotation = ralloc_asprintf(this->mem_ctx,
"FB write target %d",
target);
@@ -3542,7 +3546,9 @@ fs_visitor::emit_fb_writes()
this->output_components[target]);
inst->target = target;
}
- } else {
+ }
+
+ if (inst == NULL) {
/* Even if there's no color buffers enabled, we still need to send
* alpha out the pipeline to our null renderbuffer to support
* alpha-testing, alpha-to-coverage, and so on.