[Mesa-dev] [PATCH] i965/msaa: Add sample-alpha-to-coverage support for multiple render targets

Anuj Phogat anuj.phogat at gmail.com
Thu Aug 2 16:35:41 PDT 2012


Render Target Write message should include source zero alpha value when
sample-alpha-to-coverage is enabled for an FBO with  multiple render targets.
Source zero alpha value is used as fragment coverage for all the render
targets.

This patch makes piglit tests draw-buffers-alpha-to-coverage and
alpha-to-coverage-no-draw-buffer-zero to pass on Sandybridge. No
regressions are observed with piglit all.tests.

Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
---
 src/mesa/drivers/dri/i965/brw_fs_emit.cpp    |   12 +++++++++
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp |   33 ++++++++++++++++++++++----
 src/mesa/drivers/dri/i965/brw_wm.c           |    2 +
 src/mesa/drivers/dri/i965/brw_wm.h           |    1 +
 4 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
index dc5f3e1..c039cab 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
@@ -59,6 +59,18 @@ fs_visitor::generate_fb_write(fs_inst *inst)
 		 retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
 	 brw_set_compression_control(p, BRW_COMPRESSION_NONE);
 
+         if (inst->target > 0 &&
+	     c->key.nr_color_regions > 1 &&
+	     c->key.sample_alpha_to_coverage) {
+            /* Set "Source0 Alpha Present to RenderTarget" bit in message
+             * header.
+             */
+            brw_OR(p,
+		   vec1(retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD)),
+		   vec1(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD)),
+		   brw_imm_ud(0x1 << 11));
+         }
+
 	 if (inst->target > 0) {
 	    /* Set the render target index for choosing BLEND_STATE. */
 	    brw_MOV(p, retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE,
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index fefe2c7..7fc28ac 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1930,14 +1930,24 @@ fs_visitor::emit_color_write(int target, int index, int first_color_mrf)
 {
    int reg_width = c->dispatch_width / 8;
    fs_inst *inst;
-   fs_reg color = outputs[target];
+   fs_reg color;
+   bool src0_alpha_to_render_target = target > 0 &&
+				      c->key.nr_color_regions > 1 &&
+				      c->key.sample_alpha_to_coverage;
+
+   color = (src0_alpha_to_render_target && !index) ?
+	    outputs[0] :
+	    outputs[target];
    fs_reg mrf;
 
    /* If there's no color data to be written, skip it. */
    if (color.file == BAD_FILE)
       return;
 
-   color.reg_offset += index;
+   if (src0_alpha_to_render_target)
+      color.reg_offset += !index ? 3 : index - 1;
+   else
+      color.reg_offset += index;
 
    if (c->dispatch_width == 8 || intel->gen >= 6) {
       /* SIMD8 write looks like:
@@ -2007,6 +2017,7 @@ fs_visitor::emit_fb_writes()
 {
    this->current_annotation = "FB write header";
    bool header_present = true;
+   unsigned output_components;
    /* We can potentially have a message length of up to 15, so we have to set
     * base_mrf to either 0 or 1 in order to fit in m0..m15.
     */
@@ -2014,6 +2025,7 @@ fs_visitor::emit_fb_writes()
    int nr = base_mrf;
    int reg_width = c->dispatch_width / 8;
    bool do_dual_src = this->dual_src_output.file != BAD_FILE;
+   bool src0_alpha_to_render_target = false;
 
    if (c->dispatch_width == 16 && do_dual_src) {
       fail("GL_ARB_blend_func_extended not yet supported in 16-wide.");
@@ -2035,6 +2047,8 @@ fs_visitor::emit_fb_writes()
    }
 
    if (header_present) {
+      src0_alpha_to_render_target =  c->key.nr_color_regions > 1 &&
+				     c->key.sample_alpha_to_coverage;
       /* m2, m3 header */
       nr += 2;
    }
@@ -2051,6 +2065,8 @@ fs_visitor::emit_fb_writes()
    nr += 4 * reg_width;
    if (do_dual_src)
       nr += 4;
+   if (src0_alpha_to_render_target)
+      nr += reg_width;
 
    if (c->source_depth_to_render_target) {
       if (intel->gen == 6 && c->dispatch_width == 16) {
@@ -2122,10 +2138,17 @@ fs_visitor::emit_fb_writes()
       this->current_annotation = ralloc_asprintf(this->mem_ctx,
 						 "FB write target %d",
 						 target);
-      for (unsigned i = 0; i < this->output_components[target]; i++)
-	 emit_color_write(target, i, color_mrf);
+      /* If src0_alpha_to_render_target is true, include source zero alpha
+       * data in RenderTargetWrite message for targets > 0.
+       */
+      output_components = (target && src0_alpha_to_render_target) ?
+			  (this->output_components[target] + 1) :
+			  this->output_components[target];
 
-      fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
+      for (unsigned i = 0; i < output_components; i++)
+         emit_color_write(target, i, color_mrf);
+
+      fs_inst *inst  = emit(FS_OPCODE_FB_WRITE);
       inst->target = target;
       inst->base_mrf = base_mrf;
       inst->mlen = nr - base_mrf;
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 5ab0547..210b078 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -546,6 +546,8 @@ static void brw_wm_populate_key( struct brw_context *brw,
    /* _NEW_BUFFERS */
    key->nr_color_regions = ctx->DrawBuffer->_NumColorDrawBuffers;
 
+   key->sample_alpha_to_coverage = ctx->Multisample.SampleAlphaToCoverage;
+
    /* CACHE_NEW_VS_PROG */
    key->vp_outputs_written = brw->vs.prog_data->outputs_written;
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index b976a60..4c2f7d9 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -64,6 +64,7 @@ struct brw_wm_prog_key {
    GLuint stats_wm:1;
    GLuint flat_shade:1;
    GLuint nr_color_regions:5;
+   GLuint sample_alpha_to_coverage:1;
    GLuint render_to_fbo:1;
    GLuint clamp_fragment_color:1;
    GLuint line_aa:2;
-- 
1.7.7.6



More information about the mesa-dev mailing list