[Mesa-dev] [PATCH] radeonsi: Fix blending using destination alpha factor but non-alpha destination
Michel Dänzer
michel at daenzer.net
Mon Feb 18 10:14:34 PST 2013
From: Michel Dänzer <michel.daenzer at amd.com>
11 more little piglits.
NOTE: This is a candidate for the 9.1 branch.
Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
Any ideas why this seems necessary with radeonsi but not with r600g?
src/gallium/drivers/radeonsi/si_state.c | 116 +++++++++++++++++---------------
src/gallium/drivers/radeonsi/si_state.h | 3 +-
2 files changed, 61 insertions(+), 58 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index d20e3ff..144a29d 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -36,33 +36,6 @@
#include "si_state.h"
#include "sid.h"
-/*
- * inferred framebuffer and blender state
- */
-static void si_update_fb_blend_state(struct r600_context *rctx)
-{
- struct si_pm4_state *pm4;
- struct si_state_blend *blend = rctx->queued.named.blend;
- uint32_t mask;
-
- if (blend == NULL)
- return;
-
- pm4 = CALLOC_STRUCT(si_pm4_state);
- if (pm4 == NULL)
- return;
-
- mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1;
- mask &= blend->cb_target_mask;
- si_pm4_set_reg(pm4, R_028238_CB_TARGET_MASK, mask);
-
- si_pm4_set_state(rctx, fb_blend, pm4);
-}
-
-/*
- * Blender functions
- */
-
static uint32_t si_translate_blend_function(int blend_func)
{
switch (blend_func) {
@@ -84,7 +57,7 @@ static uint32_t si_translate_blend_function(int blend_func)
return 0;
}
-static uint32_t si_translate_blend_factor(int blend_fact)
+static uint32_t si_translate_blend_factor(int blend_fact, bool dst_alpha)
{
switch (blend_fact) {
case PIPE_BLENDFACTOR_ONE:
@@ -94,7 +67,7 @@ static uint32_t si_translate_blend_factor(int blend_fact)
case PIPE_BLENDFACTOR_SRC_ALPHA:
return V_028780_BLEND_SRC_ALPHA;
case PIPE_BLENDFACTOR_DST_ALPHA:
- return V_028780_BLEND_DST_ALPHA;
+ return dst_alpha ? V_028780_BLEND_DST_ALPHA : V_028780_BLEND_ONE;
case PIPE_BLENDFACTOR_DST_COLOR:
return V_028780_BLEND_DST_COLOR;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
@@ -110,7 +83,7 @@ static uint32_t si_translate_blend_factor(int blend_fact)
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
return V_028780_BLEND_ONE_MINUS_SRC_ALPHA;
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- return V_028780_BLEND_ONE_MINUS_DST_ALPHA;
+ return dst_alpha ? V_028780_BLEND_ONE_MINUS_DST_ALPHA : V_028780_BLEND_ZERO;
case PIPE_BLENDFACTOR_INV_DST_COLOR:
return V_028780_BLEND_ONE_MINUS_DST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
@@ -133,30 +106,25 @@ static uint32_t si_translate_blend_factor(int blend_fact)
return 0;
}
-static void *si_create_blend_state(struct pipe_context *ctx,
- const struct pipe_blend_state *state)
+/*
+ * inferred framebuffer and blender state
+ */
+static void si_update_fb_blend_state(struct r600_context *rctx)
{
- struct si_state_blend *blend = CALLOC_STRUCT(si_state_blend);
- struct si_pm4_state *pm4 = &blend->pm4;
-
- uint32_t color_control;
+ struct si_pm4_state *pm4;
+ struct si_state_blend *blend = rctx->queued.named.blend;
+ const struct pipe_blend_state *state;
+ uint32_t mask = 0;
if (blend == NULL)
- return NULL;
-
- color_control = S_028808_MODE(V_028808_CB_NORMAL);
- if (state->logicop_enable) {
- color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
- } else {
- color_control |= S_028808_ROP3(0xcc);
- }
- si_pm4_set_reg(pm4, R_028808_CB_COLOR_CONTROL, color_control);
+ return;
- si_pm4_set_reg(pm4, R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, ~0);
- si_pm4_set_reg(pm4, R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1, ~0);
+ pm4 = CALLOC_STRUCT(si_pm4_state);
+ if (pm4 == NULL)
+ return;
- blend->cb_target_mask = 0;
- for (int i = 0; i < 8; i++) {
+ state = &blend->state;
+ for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) {
/* state->rt entries > 0 only written if independent blending */
const int j = state->independent_blend_enable ? i : 0;
@@ -166,31 +134,67 @@ static void *si_create_blend_state(struct pipe_context *ctx,
unsigned eqA = state->rt[j].alpha_func;
unsigned srcA = state->rt[j].alpha_src_factor;
unsigned dstA = state->rt[j].alpha_dst_factor;
-
+ const struct util_format_description *desc;
unsigned blend_cntl = 0;
+ bool dst_alpha;
- /* we pretend 8 buffer are used, CB_SHADER_MASK will disable unused one */
- blend->cb_target_mask |= state->rt[j].colormask << (4 * i);
+ mask |= state->rt[j].colormask << (4 * i);
if (!state->rt[j].blend_enable) {
si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl);
continue;
}
+ desc = util_format_description(rctx->framebuffer.cbufs[i]->format);
+ dst_alpha = desc->swizzle[3] != PIPE_SWIZZLE_ONE;
+
blend_cntl |= S_028780_ENABLE(1);
blend_cntl |= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB));
- blend_cntl |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(srcRGB));
- blend_cntl |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(dstRGB));
+ blend_cntl |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(srcRGB, dst_alpha));
+ blend_cntl |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(dstRGB, dst_alpha));
if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
blend_cntl |= S_028780_SEPARATE_ALPHA_BLEND(1);
blend_cntl |= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA));
- blend_cntl |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(srcA));
- blend_cntl |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA));
+ blend_cntl |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(srcA, dst_alpha));
+ blend_cntl |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA, dst_alpha));
}
si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl);
}
+ si_pm4_set_reg(pm4, R_028238_CB_TARGET_MASK, mask);
+
+ si_pm4_set_state(rctx, fb_blend, pm4);
+}
+
+/*
+ * Blender functions
+ */
+
+static void *si_create_blend_state(struct pipe_context *ctx,
+ const struct pipe_blend_state *state)
+{
+ struct si_state_blend *blend = CALLOC_STRUCT(si_state_blend);
+ struct si_pm4_state *pm4 = &blend->pm4;
+
+ uint32_t color_control;
+
+ if (blend == NULL)
+ return NULL;
+
+ color_control = S_028808_MODE(V_028808_CB_NORMAL);
+ if (state->logicop_enable) {
+ color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
+ } else {
+ color_control |= S_028808_ROP3(0xcc);
+ }
+ si_pm4_set_reg(pm4, R_028808_CB_COLOR_CONTROL, color_control);
+
+ si_pm4_set_reg(pm4, R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, ~0);
+ si_pm4_set_reg(pm4, R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1, ~0);
+
+ memcpy(&blend->state, state, sizeof(blend->state));
+
return blend;
}
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index c49b029..6bf8fef 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -31,8 +31,7 @@
struct si_state_blend {
struct si_pm4_state pm4;
- uint32_t cb_target_mask;
- uint32_t cb_color_control;
+ struct pipe_blend_state state;
};
struct si_state_viewport {
--
1.8.1.3
More information about the mesa-dev
mailing list