radeonsi: implement GL_SAMPLE_ALPHA_TO_ONE
authorMarek Olšák <marek.olsak@amd.com>
Tue, 30 Jul 2013 20:29:29 +0000 (22:29 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Fri, 16 Aug 2013 23:48:25 +0000 (01:48 +0200)
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/radeonsi/radeonsi_pipe.h
src/gallium/drivers/radeonsi/radeonsi_shader.c
src/gallium/drivers/radeonsi/radeonsi_shader.h
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h

index fa6a53998807dcae99b237cb0154e96d61698fb3..b909323cdfdded89fd8f307d593d94dd8231dae7 100644 (file)
@@ -154,6 +154,7 @@ struct r600_context {
        struct si_vertex_element        *vertex_elements;
        struct pipe_framebuffer_state   framebuffer;
        unsigned                        fb_log_samples;
+       unsigned                        fb_cb0_is_integer;
        unsigned                        pa_sc_line_stipple;
        unsigned                        pa_su_sc_mode_cntl;
        /* for saving when using blitter */
index 6bf4b05ec878eb33f6eb529defb1d592f651132e..cbe10ccaa1f01a54126bf98da7ae0e0e794d8f67 100644 (file)
@@ -561,6 +561,17 @@ static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
        }
 }
 
+static void si_alpha_to_one(struct lp_build_tgsi_context *bld_base,
+                           unsigned index)
+{
+       struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
+
+       /* set alpha to one */
+       LLVMBuildStore(bld_base->base.gallivm->builder,
+                      bld_base->base.one,
+                      si_shader_ctx->radeon_bld.soa.outputs[index][3]);
+}
+
 static void si_llvm_emit_clipvertex(struct lp_build_tgsi_context * bld_base,
                                    LLVMValueRef (*pos)[9], unsigned index)
 {
@@ -707,6 +718,9 @@ handle_semantic:
                                        param_count++;
                                } else {
                                        target = V_008DFC_SQ_EXP_MRT + color_count;
+                                       if (si_shader_ctx->shader->key.ps.alpha_to_one) {
+                                               si_alpha_to_one(bld_base, index);
+                                       }
                                        if (color_count == 0 &&
                                            si_shader_ctx->shader->key.ps.alpha_func != PIPE_FUNC_ALWAYS)
                                                si_alpha_test(bld_base, index);
index 2d4468a2f37a3e5721fc356c6d36f0ac3d46200f..d12892b3b6ace7ece800940a8c2a55ed39926625 100644 (file)
@@ -124,6 +124,7 @@ union si_shader_key {
                unsigned        color_two_side:1;
                unsigned        alpha_func:3;
                unsigned        flatshade:1;
+               unsigned        alpha_to_one:1;
                float           alpha_ref;
        } ps;
        struct {
index ccd826e0ec6b86c1e77be127f41f1191cc0971b8..6e286e4792cd7f5633c05019796801a959dcb55a 100644 (file)
@@ -255,6 +255,8 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
        if (blend == NULL)
                return NULL;
 
+       blend->alpha_to_one = state->alpha_to_one;
+
        color_control = S_028808_MODE(mode);
        if (state->logicop_enable) {
                color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
@@ -520,6 +522,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
        }
 
        rs->two_side = state->light_twoside;
+       rs->multisample_enable = state->multisample;
        rs->clip_plane_enable = state->clip_plane_enable;
 
        polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
@@ -2247,6 +2250,8 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
 
        si_set_msaa_state(rctx, pm4, nr_samples);
        rctx->fb_log_samples = util_logbase2(nr_samples);
+       rctx->fb_cb0_is_integer = state->nr_cbufs &&
+                                 util_format_is_pure_integer(state->cbufs[0]->format);
 
        si_pm4_set_state(rctx, framebuffer, pm4);
        si_update_fb_rs_state(rctx);
@@ -2281,9 +2286,16 @@ static INLINE void si_shader_selector_key(struct pipe_context *ctx,
                if (sel->fs_write_all)
                        key->ps.nr_cbufs = rctx->framebuffer.nr_cbufs;
                key->ps.export_16bpc = rctx->export_16bpc;
+
                if (rctx->queued.named.rasterizer) {
                        key->ps.color_two_side = rctx->queued.named.rasterizer->two_side;
                        key->ps.flatshade = rctx->queued.named.rasterizer->flatshade;
+
+                       if (rctx->queued.named.blend) {
+                               key->ps.alpha_to_one = rctx->queued.named.blend->alpha_to_one &&
+                                                      rctx->queued.named.rasterizer->multisample_enable &&
+                                                      !rctx->fb_cb0_is_integer;
+                       }
                }
                if (rctx->queued.named.dsa) {
                        key->ps.alpha_func = rctx->queued.named.dsa->alpha_func;
index bc121048f2c93e507f2d4c11a334df9ef7f56ce1..fc9aa221959ec6a2ad43827149c13a9b808226a3 100644 (file)
@@ -40,7 +40,7 @@ struct si_atom {
 struct si_state_blend {
        struct si_pm4_state     pm4;
        uint32_t                cb_target_mask;
-       uint32_t                cb_color_control;
+       bool                    alpha_to_one;
 };
 
 struct si_state_viewport {
@@ -52,6 +52,7 @@ struct si_state_rasterizer {
        struct si_pm4_state     pm4;
        bool                    flatshade;
        bool                    two_side;
+       bool                    multisample_enable;
        unsigned                sprite_coord_enable;
        unsigned                pa_sc_line_stipple;
        unsigned                pa_su_sc_mode_cntl;