r600g: implement alpha-to-one
authorMarek Olšák <maraeo@gmail.com>
Fri, 3 Aug 2012 23:50:10 +0000 (01:50 +0200)
committerMarek Olšák <maraeo@gmail.com>
Wed, 15 Aug 2012 17:20:57 +0000 (19:20 +0200)
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c

index 6e338ae23f6783169ba895cd524b3855d6620e43..98e0338f648a7d8bf6a9bafbc800331cb365f39e 100644 (file)
@@ -743,6 +743,7 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx,
                r600_pipe_state_add_reg(rstate, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl[i]);
        }
 
+       blend->alpha_to_one = state->alpha_to_one;
        return rstate;
 }
 
@@ -836,6 +837,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
                S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
                S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip) |
                S_028810_DX_LINEAR_ATTR_CLIP_ENA(1);
+       rs->multisample_enable = state->multisample;
 
        /* offset */
        rs->offset_units = state->offset_units;
@@ -1472,6 +1474,8 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
        /* build states */
        rctx->export_16bpc = true;
        rctx->nr_cbufs = state->nr_cbufs;
+       rctx->cb0_is_integer = state->nr_cbufs &&
+                              util_format_is_pure_integer(state->cbufs[0]->format);
 
        for (i = 0; i < state->nr_cbufs; i++) {
                surf = (struct r600_surface*)state->cbufs[i];
index 04641838e0bf9eed80246ce43ee7c0ab090dc9e0..926f6eb05dc6260e04a36f56077dc62453f63716 100644 (file)
@@ -180,6 +180,7 @@ struct r600_pipe_rasterizer {
        float                           offset_units;
        float                           offset_scale;
        bool                            scissor_enable;
+       bool                            multisample_enable;
 };
 
 struct r600_pipe_blend {
@@ -187,6 +188,7 @@ struct r600_pipe_blend {
        unsigned                        cb_target_mask;
        unsigned                        cb_color_control;
        bool                            dual_src_blend;
+       bool                            alpha_to_one;
 };
 
 struct r600_pipe_dsa {
@@ -347,6 +349,9 @@ struct r600_context {
        boolean                         flatshade;
        boolean                         export_16bpc;
        unsigned                        nr_cbufs;
+       bool                            alpha_to_one;
+       bool                            multisample_enable;
+       bool                            cb0_is_integer;
 
        struct u_upload_mgr             *uploader;
        struct util_slab_mempool        pool_transfers;
index 3c0fbc8bdcc5e3d72347627c72a14ed7565c3e73..e4818a082124459f54f3eca4febd97d9d1567c7b 100644 (file)
@@ -1572,6 +1572,7 @@ static int r600_shader_from_tgsi(struct r600_context * rctx, struct r600_pipe_sh
                                        j--;
                                        continue;
                                }
+                               output[j].swizzle_w = rctx->alpha_to_one && rctx->multisample_enable && !rctx->cb0_is_integer ? 5 : 3;
                                output[j].array_base = next_pixel_base++;
                                output[j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
                                shader->nr_ps_color_exports++;
@@ -1584,7 +1585,7 @@ static int r600_shader_from_tgsi(struct r600_context * rctx, struct r600_pipe_sh
                                                output[j].swizzle_x = 0;
                                                output[j].swizzle_y = 1;
                                                output[j].swizzle_z = 2;
-                                               output[j].swizzle_w = 3;
+                                               output[j].swizzle_w = rctx->alpha_to_one && rctx->multisample_enable && !rctx->cb0_is_integer ? 5 : 3;
                                                output[j].burst_count = 1;
                                                output[j].barrier = 1;
                                                output[j].array_base = next_pixel_base++;
index c1061ddbe0c8dfd46bceaf812fef32f3f1fc8656..831630a83b1b02dccc97b5d753ea51ce25c9314e 100644 (file)
@@ -753,6 +753,8 @@ static void *r600_create_blend_state(struct pipe_context *ctx,
                if (i == 0)
                        r600_pipe_state_add_reg(rstate, R_028804_CB_BLEND_CONTROL, bc);
        }
+
+       blend->alpha_to_one = state->alpha_to_one;
        return rstate;
 }
 
@@ -846,6 +848,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
                S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
                S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip) |
                S_028810_DX_LINEAR_ATTR_CLIP_ENA(1);
+       rs->multisample_enable = state->multisample;
 
        /* offset */
        rs->offset_units = state->offset_units;
@@ -1398,6 +1401,8 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
        /* build states */
        rctx->export_16bpc = true;
        rctx->nr_cbufs = state->nr_cbufs;
+       rctx->cb0_is_integer = state->nr_cbufs &&
+                              util_format_is_pure_integer(state->cbufs[0]->format);
 
        for (i = 0; i < state->nr_cbufs; i++) {
                surf = (struct r600_surface*)state->cbufs[i];
index 4a75c144d8ad91805b4a80916aea1f072d235b0d..97a7c7ea2c73c062dfdb790a8d8571b32fa0f13e 100644 (file)
@@ -177,6 +177,7 @@ void r600_bind_blend_state(struct pipe_context *ctx, void *state)
        rstate = &blend->rstate;
        rctx->states[rstate->id] = rstate;
        rctx->dual_src_blend = blend->dual_src_blend;
+       rctx->alpha_to_one = blend->alpha_to_one;
        r600_context_pipe_state_set(rctx, rstate);
 
        if (rctx->cb_misc_state.blend_colormask != blend->cb_target_mask) {
@@ -320,6 +321,7 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
        rctx->two_side = rs->two_side;
        rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple;
        rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl;
+       rctx->multisample_enable = rs->multisample_enable;
 
        rctx->rasterizer = rs;
 
@@ -636,7 +638,8 @@ static INLINE unsigned r600_shader_selector_key(struct pipe_context * ctx,
 
        if (sel->type == PIPE_SHADER_FRAGMENT) {
                key = rctx->two_side |
-                               MIN2(sel->nr_ps_max_color_exports, rctx->nr_cbufs + rctx->dual_src_blend) << 1;
+                     ((rctx->alpha_to_one && rctx->multisample_enable && !rctx->cb0_is_integer) << 1) |
+                     (MIN2(sel->nr_ps_max_color_exports, rctx->nr_cbufs + rctx->dual_src_blend) << 2);
        } else
                key = 0;