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.pho...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev