Mesa (master): i965/fs: Don' t issue FB writes for bound but unwritten color targets.

Kenneth Graunke kwg at kemper.freedesktop.org
Mon Mar 9 23:10:05 UTC 2015


Module: Mesa
Branch: master
Commit: e95969cd9548033250ba12f2adf11740319b41e7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e95969cd9548033250ba12f2adf11740319b41e7

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Thu Feb 26 17:45:49 2015 -0800

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 at whitecape.org>
Reviewed-by: Jason Ekstrand <jason.ekstrand at intel.com>
Cc: mesa-stable at lists.freedesktop.org

---

 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp |   12 +++++++++---
 1 file 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 5222387..7859fef 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -3668,7 +3668,7 @@ fs_visitor::emit_fb_writes()
    brw_wm_prog_data *prog_data = (brw_wm_prog_data*) this->prog_data;
    brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
 
-   fs_inst *inst;
+   fs_inst *inst = NULL;
    if (do_dual_src) {
       this->current_annotation = ralloc_asprintf(this->mem_ctx,
 						 "FB dual-source write");
@@ -3700,8 +3700,12 @@ fs_visitor::emit_fb_writes()
       }
 
       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);
@@ -3714,7 +3718,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.




More information about the mesa-commit mailing list