diff options
author | Christian König <[email protected]> | 2012-07-17 14:12:46 +0200 |
---|---|---|
committer | Christian König <[email protected]> | 2012-07-24 12:29:29 +0200 |
commit | 63636ae52aefc275115d1f3daac4e75285583485 (patch) | |
tree | 124ef1f0b00b84b18b55b55943eeb02a3225b296 /src/gallium | |
parent | bf7302a6e1f3aed4518498e90e8261a2b1f6afd7 (diff) |
radeonsi: move blender to new state handling
Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/radeonsi/evergreen_hw_context.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/evergreen_state.c | 152 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/r600_blit.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/r600_state_common.c | 27 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/radeonsi_pipe.h | 10 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 158 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.h | 9 |
7 files changed, 178 insertions, 191 deletions
diff --git a/src/gallium/drivers/radeonsi/evergreen_hw_context.c b/src/gallium/drivers/radeonsi/evergreen_hw_context.c index 4cf6a9e5253..68d53d47104 100644 --- a/src/gallium/drivers/radeonsi/evergreen_hw_context.c +++ b/src/gallium/drivers/radeonsi/evergreen_hw_context.c @@ -184,21 +184,12 @@ static const struct r600_reg si_context_reg_list[] = { {R_02870C_SPI_SHADER_POS_FORMAT, 0}, {R_028710_SPI_SHADER_Z_FORMAT, 0}, {R_028714_SPI_SHADER_COL_FORMAT, 0}, - {R_028780_CB_BLEND0_CONTROL, 0}, - {R_028784_CB_BLEND1_CONTROL, 0}, - {R_028788_CB_BLEND2_CONTROL, 0}, - {R_02878C_CB_BLEND3_CONTROL, 0}, - {R_028790_CB_BLEND4_CONTROL, 0}, - {R_028794_CB_BLEND5_CONTROL, 0}, - {R_028798_CB_BLEND6_CONTROL, 0}, - {R_02879C_CB_BLEND7_CONTROL, 0}, {R_0287D4_PA_CL_POINT_X_RAD, 0}, {R_0287D8_PA_CL_POINT_Y_RAD, 0}, {R_0287DC_PA_CL_POINT_SIZE, 0}, {R_0287E0_PA_CL_POINT_CULL_RAD, 0}, {R_028800_DB_DEPTH_CONTROL, 0}, {R_028804_DB_EQAA, 0}, - {R_028808_CB_COLOR_CONTROL, 0}, {R_02880C_DB_SHADER_CONTROL, 0}, {R_028810_PA_CL_CLIP_CNTL, 0}, {R_028814_PA_SU_SC_MODE_CNTL, 0}, @@ -284,8 +275,6 @@ static const struct r600_reg si_context_reg_list[] = { {R_028C2C_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1, 0}, {R_028C30_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2, 0}, {R_028C34_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3, 0}, - {R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, 0}, - {R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1, 0}, {GROUP_FORCE_NEW_BLOCK, 0}, {R_028C60_CB_COLOR0_BASE, REG_FLAG_NEED_BO}, {R_028C64_CB_COLOR0_PITCH, 0}, diff --git a/src/gallium/drivers/radeonsi/evergreen_state.c b/src/gallium/drivers/radeonsi/evergreen_state.c index 9c45719c750..62f138a1404 100644 --- a/src/gallium/drivers/radeonsi/evergreen_state.c +++ b/src/gallium/drivers/radeonsi/evergreen_state.c @@ -45,76 +45,7 @@ #include "sid.h" #include "r600_resource.h" #include "radeonsi_pipe.h" - -static uint32_t si_translate_blend_function(int blend_func) -{ - switch (blend_func) { - case PIPE_BLEND_ADD: - return V_028780_COMB_DST_PLUS_SRC; - case PIPE_BLEND_SUBTRACT: - return V_028780_COMB_SRC_MINUS_DST; - case PIPE_BLEND_REVERSE_SUBTRACT: - return V_028780_COMB_DST_MINUS_SRC; - case PIPE_BLEND_MIN: - return V_028780_COMB_MIN_DST_SRC; - case PIPE_BLEND_MAX: - return V_028780_COMB_MAX_DST_SRC; - default: - R600_ERR("Unknown blend function %d\n", blend_func); - assert(0); - break; - } - return 0; -} - -static uint32_t si_translate_blend_factor(int blend_fact) -{ - switch (blend_fact) { - case PIPE_BLENDFACTOR_ONE: - return V_028780_BLEND_ONE; - case PIPE_BLENDFACTOR_SRC_COLOR: - return V_028780_BLEND_SRC_COLOR; - case PIPE_BLENDFACTOR_SRC_ALPHA: - return V_028780_BLEND_SRC_ALPHA; - case PIPE_BLENDFACTOR_DST_ALPHA: - return V_028780_BLEND_DST_ALPHA; - case PIPE_BLENDFACTOR_DST_COLOR: - return V_028780_BLEND_DST_COLOR; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - return V_028780_BLEND_SRC_ALPHA_SATURATE; - case PIPE_BLENDFACTOR_CONST_COLOR: - return V_028780_BLEND_CONSTANT_COLOR; - case PIPE_BLENDFACTOR_CONST_ALPHA: - return V_028780_BLEND_CONSTANT_ALPHA; - case PIPE_BLENDFACTOR_ZERO: - return V_028780_BLEND_ZERO; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - return V_028780_BLEND_ONE_MINUS_SRC_COLOR; - 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; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - return V_028780_BLEND_ONE_MINUS_DST_COLOR; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - return V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR; - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - return V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA; - case PIPE_BLENDFACTOR_SRC1_COLOR: - return V_028780_BLEND_SRC1_COLOR; - case PIPE_BLENDFACTOR_SRC1_ALPHA: - return V_028780_BLEND_SRC1_ALPHA; - case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - return V_028780_BLEND_INV_SRC1_COLOR; - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: - return V_028780_BLEND_INV_SRC1_ALPHA; - default: - R600_ERR("Bad blend factor %d not supported!\n", blend_fact); - assert(0); - break; - } - return 0; -} +#include "si_state.h" #if 0 static uint32_t r600_translate_stencil_op(int s_op) @@ -852,83 +783,6 @@ static void evergreen_set_blend_color(struct pipe_context *ctx, r600_context_pipe_state_set(rctx, rstate); } -static void *evergreen_create_blend_state(struct pipe_context *ctx, - const struct pipe_blend_state *state) -{ - struct r600_context *rctx = (struct r600_context *)ctx; - struct r600_pipe_blend *blend = CALLOC_STRUCT(r600_pipe_blend); - struct r600_pipe_state *rstate; - uint32_t color_control, target_mask; - /* FIXME there is more then 8 framebuffer */ - unsigned blend_cntl[8]; - - if (blend == NULL) { - return NULL; - } - - rstate = &blend->rstate; - - rstate->id = R600_PIPE_STATE_BLEND; - - target_mask = 0; - 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); - } - /* we pretend 8 buffer are used, CB_SHADER_MASK will disable unused one */ - if (state->independent_blend_enable) { - for (int i = 0; i < 8; i++) { - target_mask |= (state->rt[i].colormask << (4 * i)); - } - } else { - for (int i = 0; i < 8; i++) { - target_mask |= (state->rt[0].colormask << (4 * i)); - } - } - blend->cb_target_mask = target_mask; - - r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL, - color_control, NULL, 0); - - r600_pipe_state_add_reg(rstate, R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, ~0, NULL, 0); - r600_pipe_state_add_reg(rstate, R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1, ~0, NULL, 0); - - for (int i = 0; i < 8; i++) { - /* state->rt entries > 0 only written if independent blending */ - const int j = state->independent_blend_enable ? i : 0; - - unsigned eqRGB = state->rt[j].rgb_func; - unsigned srcRGB = state->rt[j].rgb_src_factor; - unsigned dstRGB = state->rt[j].rgb_dst_factor; - unsigned eqA = state->rt[j].alpha_func; - unsigned srcA = state->rt[j].alpha_src_factor; - unsigned dstA = state->rt[j].alpha_dst_factor; - - blend_cntl[i] = 0; - if (!state->rt[j].blend_enable) - continue; - - blend_cntl[i] |= S_028780_ENABLE(1); - blend_cntl[i] |= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB)); - blend_cntl[i] |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(srcRGB)); - blend_cntl[i] |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(dstRGB)); - - if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { - blend_cntl[i] |= S_028780_SEPARATE_ALPHA_BLEND(1); - blend_cntl[i] |= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA)); - blend_cntl[i] |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(srcA)); - blend_cntl[i] |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA)); - } - } - for (int i = 0; i < 8; i++) { - r600_pipe_state_add_reg(rstate, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl[i], NULL, 0); - } - - return rstate; -} - static void *evergreen_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { @@ -1880,7 +1734,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, void cayman_init_state_functions(struct r600_context *rctx) { - rctx->context.create_blend_state = evergreen_create_blend_state; + si_init_state_functions(rctx); rctx->context.create_depth_stencil_alpha_state = evergreen_create_dsa_state; rctx->context.create_fs_state = si_create_shader_state; rctx->context.create_rasterizer_state = evergreen_create_rs_state; @@ -1888,7 +1742,6 @@ void cayman_init_state_functions(struct r600_context *rctx) rctx->context.create_sampler_view = evergreen_create_sampler_view; rctx->context.create_vertex_elements_state = si_create_vertex_elements; rctx->context.create_vs_state = si_create_shader_state; - rctx->context.bind_blend_state = r600_bind_blend_state; rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; rctx->context.bind_fragment_sampler_states = evergreen_bind_ps_sampler; rctx->context.bind_fs_state = r600_bind_ps_shader; @@ -1896,7 +1749,6 @@ void cayman_init_state_functions(struct r600_context *rctx) rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements; rctx->context.bind_vertex_sampler_states = evergreen_bind_vs_sampler; rctx->context.bind_vs_state = r600_bind_vs_shader; - rctx->context.delete_blend_state = r600_delete_state; rctx->context.delete_depth_stencil_alpha_state = r600_delete_state; rctx->context.delete_fs_state = r600_delete_ps_shader; rctx->context.delete_rasterizer_state = r600_delete_rs_state; diff --git a/src/gallium/drivers/radeonsi/r600_blit.c b/src/gallium/drivers/radeonsi/r600_blit.c index 1681b48b6f5..3b476bcee09 100644 --- a/src/gallium/drivers/radeonsi/r600_blit.c +++ b/src/gallium/drivers/radeonsi/r600_blit.c @@ -47,7 +47,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op r600_context_queries_suspend(rctx); - util_blitter_save_blend(rctx->blitter, rctx->states[R600_PIPE_STATE_BLEND]); + util_blitter_save_blend(rctx->blitter, rctx->queued.named.blend); util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->states[R600_PIPE_STATE_DSA]); if (rctx->states[R600_PIPE_STATE_STENCIL_REF]) { util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref); diff --git a/src/gallium/drivers/radeonsi/r600_state_common.c b/src/gallium/drivers/radeonsi/r600_state_common.c index 18ba7a8e2b6..dd3382fb34d 100644 --- a/src/gallium/drivers/radeonsi/r600_state_common.c +++ b/src/gallium/drivers/radeonsi/r600_state_common.c @@ -33,6 +33,7 @@ #include "r600_hw_context_priv.h" #include "radeonsi_pipe.h" #include "sid.h" +#include "si_state.h" static void r600_emit_surface_sync(struct r600_context *rctx, struct r600_atom *atom) { @@ -119,22 +120,6 @@ static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim) } /* common state between evergreen and r600 */ -void r600_bind_blend_state(struct pipe_context *ctx, void *state) -{ - struct r600_context *rctx = (struct r600_context *)ctx; - struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state; - struct r600_pipe_state *rstate; - - if (state == NULL) - return; - rstate = &blend->rstate; - rctx->states[rstate->id] = rstate; - rctx->cb_target_mask = blend->cb_target_mask; - rctx->cb_color_control = blend->cb_color_control; - - r600_context_pipe_state_set(rctx, rstate); -} - static void r600_set_stencil_ref(struct pipe_context *ctx, const struct r600_stencil_ref *state) { @@ -685,6 +670,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) unsigned prim, mask, ls_mask = 0; struct r600_block *dirty_block = NULL, *next_block = NULL; struct r600_atom *state = NULL, *next_state = NULL; + struct si_state_blend *blend; int i; if ((!info.count && (info.indexed || !info.count_from_stream_output)) || @@ -696,6 +682,11 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) if (!rctx->ps_shader || !rctx->vs_shader) return; + /* only temporary */ + if (!rctx->queued.named.blend) + return; + blend = rctx->queued.named.blend; + si_update_derived_state(rctx); r600_vertex_buffer_update(rctx); @@ -745,7 +736,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) rctx->vgt.id = R600_PIPE_STATE_VGT; rctx->vgt.nregs = 0; r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, NULL, 0); - r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, NULL, 0); + r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, blend->cb_target_mask & mask, NULL, 0); r600_pipe_state_add_reg(&rctx->vgt, R_028400_VGT_MAX_VTX_INDX, ~0, NULL, 0); r600_pipe_state_add_reg(&rctx->vgt, R_028404_VGT_MIN_VTX_INDX, 0, NULL, 0); r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, info.index_bias, NULL, 0); @@ -763,7 +754,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) rctx->vgt.nregs = 0; r600_pipe_state_mod_reg(&rctx->vgt, prim); - r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_target_mask & mask); + r600_pipe_state_mod_reg(&rctx->vgt, blend->cb_target_mask & mask); r600_pipe_state_mod_reg(&rctx->vgt, ~0); r600_pipe_state_mod_reg(&rctx->vgt, 0); r600_pipe_state_mod_reg(&rctx->vgt, info.index_bias); diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h index 733afd9b4f0..df1b45b2f9e 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h @@ -75,7 +75,6 @@ struct r600_atom_surface_sync { }; enum r600_pipe_state_id { - R600_PIPE_STATE_BLEND = 0, R600_PIPE_STATE_BLEND_COLOR, R600_PIPE_STATE_CONFIG, R600_PIPE_STATE_SEAMLESS_CUBEMAP, @@ -139,12 +138,6 @@ struct r600_pipe_rasterizer { float offset_scale; }; -struct r600_pipe_blend { - struct r600_pipe_state rstate; - unsigned cb_target_mask; - unsigned cb_color_control; -}; - struct r600_pipe_dsa { struct r600_pipe_state rstate; unsigned alpha_ref; @@ -243,8 +236,6 @@ struct r600_context { struct r600_pipe_state *states[R600_PIPE_NSTATES]; struct r600_vertex_element *vertex_elements; struct pipe_framebuffer_state framebuffer; - unsigned cb_target_mask; - unsigned cb_color_control; unsigned pa_sc_line_stipple; unsigned pa_su_sc_mode_cntl; unsigned pa_cl_clip_cntl; @@ -420,7 +411,6 @@ void *si_create_vertex_elements(struct pipe_context *ctx, unsigned count, const struct pipe_vertex_element *elements); void r600_delete_vertex_element(struct pipe_context *ctx, void *state); -void r600_bind_blend_state(struct pipe_context *ctx, void *state); void r600_bind_dsa_state(struct pipe_context *ctx, void *state); void r600_bind_rs_state(struct pipe_context *ctx, void *state); void r600_delete_rs_state(struct pipe_context *ctx, void *state); diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 843403b6deb..8373f423685 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -22,7 +22,163 @@ * * Authors: * Christian König <[email protected]> - * */ +#include "util/u_memory.h" +#include "radeonsi_pipe.h" #include "si_state.h" +#include "sid.h" + +/* + * Blender functions + */ + +static uint32_t si_translate_blend_function(int blend_func) +{ + switch (blend_func) { + case PIPE_BLEND_ADD: + return V_028780_COMB_DST_PLUS_SRC; + case PIPE_BLEND_SUBTRACT: + return V_028780_COMB_SRC_MINUS_DST; + case PIPE_BLEND_REVERSE_SUBTRACT: + return V_028780_COMB_DST_MINUS_SRC; + case PIPE_BLEND_MIN: + return V_028780_COMB_MIN_DST_SRC; + case PIPE_BLEND_MAX: + return V_028780_COMB_MAX_DST_SRC; + default: + R600_ERR("Unknown blend function %d\n", blend_func); + assert(0); + break; + } + return 0; +} + +static uint32_t si_translate_blend_factor(int blend_fact) +{ + switch (blend_fact) { + case PIPE_BLENDFACTOR_ONE: + return V_028780_BLEND_ONE; + case PIPE_BLENDFACTOR_SRC_COLOR: + return V_028780_BLEND_SRC_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA: + return V_028780_BLEND_SRC_ALPHA; + case PIPE_BLENDFACTOR_DST_ALPHA: + return V_028780_BLEND_DST_ALPHA; + case PIPE_BLENDFACTOR_DST_COLOR: + return V_028780_BLEND_DST_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + return V_028780_BLEND_SRC_ALPHA_SATURATE; + case PIPE_BLENDFACTOR_CONST_COLOR: + return V_028780_BLEND_CONSTANT_COLOR; + case PIPE_BLENDFACTOR_CONST_ALPHA: + return V_028780_BLEND_CONSTANT_ALPHA; + case PIPE_BLENDFACTOR_ZERO: + return V_028780_BLEND_ZERO; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + return V_028780_BLEND_ONE_MINUS_SRC_COLOR; + 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; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + return V_028780_BLEND_ONE_MINUS_DST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + return V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + return V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA; + case PIPE_BLENDFACTOR_SRC1_COLOR: + return V_028780_BLEND_SRC1_COLOR; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + return V_028780_BLEND_SRC1_ALPHA; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + return V_028780_BLEND_INV_SRC1_COLOR; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + return V_028780_BLEND_INV_SRC1_ALPHA; + default: + R600_ERR("Bad blend factor %d not supported!\n", blend_fact); + assert(0); + break; + } + return 0; +} + +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); + + blend->cb_target_mask = 0; + for (int i = 0; i < 8; i++) { + /* state->rt entries > 0 only written if independent blending */ + const int j = state->independent_blend_enable ? i : 0; + + unsigned eqRGB = state->rt[j].rgb_func; + unsigned srcRGB = state->rt[j].rgb_src_factor; + unsigned dstRGB = state->rt[j].rgb_dst_factor; + unsigned eqA = state->rt[j].alpha_func; + unsigned srcA = state->rt[j].alpha_src_factor; + unsigned dstA = state->rt[j].alpha_dst_factor; + + unsigned blend_cntl = 0; + + /* we pretend 8 buffer are used, CB_SHADER_MASK will disable unused one */ + blend->cb_target_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; + } + + 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)); + + 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)); + } + si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl); + } + + return blend; +} + +static void si_bind_blend_state(struct pipe_context *ctx, void *state) +{ + struct r600_context *rctx = (struct r600_context *)ctx; + si_pm4_bind_state(rctx, blend, (struct si_state_blend *)state); +} + +static void si_delete_blend_state(struct pipe_context *ctx, void *state) +{ + struct r600_context *rctx = (struct r600_context *)ctx; + si_pm4_delete_state(rctx, blend, (struct si_state_blend *)state); +} + +void si_init_state_functions(struct r600_context *rctx) +{ + rctx->context.create_blend_state = si_create_blend_state; + rctx->context.bind_blend_state = si_bind_blend_state; + rctx->context.delete_blend_state = si_delete_blend_state; +} diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 697c8721359..ed880d6c916 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -29,8 +29,15 @@ #include "radeonsi_pm4.h" +struct si_state_blend { + struct si_pm4_state pm4; + uint32_t cb_target_mask; + uint32_t cb_color_control; +}; + union si_state { struct { + struct si_state_blend *blend; } named; struct si_pm4_state *array[0]; }; @@ -62,4 +69,6 @@ union si_state { } \ } while(0); +void si_init_state_functions(struct r600_context *rctx); + #endif |