From: Marek Olšák Date: Fri, 3 Aug 2012 23:50:10 +0000 (+0200) Subject: r600g: implement alpha-to-one X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=26cb887ea213be2445e0fd64364d9264ed4fbfd2;p=mesa.git r600g: implement alpha-to-one --- diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 6e338ae23f6..98e0338f648 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -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]; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 04641838e0b..926f6eb05dc 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -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; diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 3c0fbc8bdcc..e4818a08212 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -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++; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index c1061ddbe0c..831630a83b1 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -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]; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 4a75c144d8a..97a7c7ea2c7 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -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;