From: Dave Airlie Date: Mon, 2 Aug 2010 04:42:29 +0000 (+1000) Subject: r600g: add initial blend state. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7bcd39ce50b7b710bb8561c430f345ebe91ab9a3;p=mesa.git r600g: add initial blend state. migrates cb_cntl to be regenerated --- diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c index fc8aa1b866d..8b191914f5f 100644 --- a/src/gallium/drivers/r600/r600_context.c +++ b/src/gallium/drivers/r600/r600_context.c @@ -331,20 +331,6 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) return NULL; } - rctx->hw_states.cb_cntl = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL); - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F; - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x0000000F; - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_COLOR_CONTROL] = 0x00CC0000; - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000; - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000; - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000; - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000; - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000; - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF; - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF; - rctx->hw_states.cb_cntl->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF; - radeon_state_pm4(rctx->hw_states.cb_cntl); - r600_init_config(rctx); rctx->ctx = radeon_ctx(rscreen->rw); diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h index 97c8a46bb05..a1ee9577bae 100644 --- a/src/gallium/drivers/r600/r600_context.h +++ b/src/gallium/drivers/r600/r600_context.h @@ -158,6 +158,7 @@ struct r600_context { struct r600_vertex_element *vertex_elements; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_index_buffer index_buffer; + struct pipe_blend_color blend_color; }; #if 0 diff --git a/src/gallium/drivers/r600/r600_reg.h b/src/gallium/drivers/r600/r600_reg.h new file mode 100644 index 00000000000..2600875d5c1 --- /dev/null +++ b/src/gallium/drivers/r600/r600_reg.h @@ -0,0 +1,72 @@ +#ifndef R600_REG_H +#define R600_REG_H + +/* for regs which haven't been generated yet */ + +#define R600_BLEND_ZERO 0 +#define R600_BLEND_ONE 1 +#define R600_BLEND_SRC_COLOR 2 +#define R600_BLEND_ONE_MINUS_SRC_COLOR 3 +#define R600_BLEND_SRC_ALPHA 4 +#define R600_BLEND_ONE_MINUS_SRC_ALPHA 5 +#define R600_BLEND_DST_ALPHA 6 +#define R600_BLEND_ONE_MINUS_DST_ALPHA 7 +#define R600_BLEND_DST_COLOR 8 +#define R600_BLEND_ONE_MINUS_DST_COLOR 9 +#define R600_BLEND_SRC_ALPHA_SATURATE 10 +#define R600_BLEND_BOTH_SRC_ALPHA 11 +#define R600_BLEND_BOTH_INV_SRC_ALPHA 12 +#define R600_BLEND_CONST_COLOR 13 +#define R600_BLEND_ONE_MINUS_CONST_COLOR 14 +#define R600_BLEND_SRC1_COLOR 15 +#define R600_BLEND_INV_SRC1_COLOR 16 +#define R600_BLEND_SRC1_ALPHA 17 +#define R600_BLEND_INV_SRC1_ALPHA 18 +#define R600_BLEND_CONST_ALPHA 19 +#define R600_BLEND_ONE_MINUS_CONST_ALPHA 20 + +#define R600_BLEND_FCN_ADD 0 +#define R600_BLEND_FCN_SUBTRACT 1 +#define R600_BLEND_FCN_MIN 2 +#define R600_BLEND_FCN_MAX 3 +#define R600_BLEND_FCN_RSUB 4 + +#define CB_BLEND_COLOR_SRCBLEND_SHIFT 0 +#define CB_BLEND_COLOR_COMB_FCN_SHIFT 5 +#define CB_BLEND_COLOR_DESTBLEND_SHIFT 8 +#define CB_BLEND_ALPHA_SRCBLEND_SHIFT 16 +#define CB_BLEND_ALPHA_COMB_FCN_SHIFT 21 +#define CB_BLEND_ALPHA_DESTBLEND_SHIFT 24 +#define CB_BLEND_SEPARATE_ALPHA_BLEND (1 << 29) + +#define SX_ALPHA_TEST_FUNC_SHIFT (0) +#define SX_ALPHA_TEST_ENABLE (1 << 3) + +#define R600_ZS_KEEP 0 +#define R600_ZS_ZERO 1 +#define R600_ZS_REPLACE 2 +#define R600_ZS_INCR 3 +#define R600_ZS_DECR 4 +#define R600_ZS_INVERT 5 +#define R600_ZS_INCR_WRAP 6 +#define R600_ZS_DECR_WRAP 7 + +#define R600_STENCILREF_SHIFT 0 +#define R600_STENCILMASK_SHIFT 8 +#define R600_STENCILWRITEMASK_SHIFT 16 + +#define PA_SU_PS_WIDTH_SHIFT 16 + +#define PA_SU_CULL_FRONT (1 << 0) +#define PA_SU_CULL_BACK (1 << 1) +#define PA_SU_FACE_CCW (0 << 2) +#define PA_SU_FACE_CW (1 << 2) + +#define PA_SU_POLYMODE_FRONT_SHIFT 5 +#define PA_SU_POLYMODE_BACK_SHIFT 5 +#define POLYGON_MODE_POINT 0 +#define POLYGON_MODE_LINE 1 +#define POLYGON_MODE_TRI 2 + + +#endif diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index b27d9d55575..56304cc69fb 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -32,6 +32,8 @@ #include "r600_context.h" #include "r600_resource.h" #include "r600d.h" +#include "r600_reg.h" +#include "r600_state_inlines.h" static void *r600_create_blend_state(struct pipe_context *ctx, const struct pipe_blend_state *state) @@ -259,6 +261,9 @@ static void r600_delete_state(struct pipe_context *ctx, void *state) static void r600_set_blend_color(struct pipe_context *ctx, const struct pipe_blend_color *color) { + struct r600_context *rctx = r600_context(ctx); + + rctx->blend_color = *color; } static void r600_set_clip_state(struct pipe_context *ctx, @@ -604,15 +609,17 @@ static struct radeon_state *r600_blend(struct r600_context *rctx) { struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; + const struct pipe_blend_state *state = &rctx->blend->state.blend; + int i; rstate = radeon_state(rscreen->rw, R600_BLEND_TYPE, R600_BLEND); if (rstate == NULL) return NULL; - rstate->states[R600_BLEND__CB_BLEND_RED] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND_GREEN] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND_BLUE] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND_ALPHA] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND0_CONTROL] = 0x00010001; + rstate->states[R600_BLEND__CB_BLEND_RED] = fui(rctx->blend_color.color[0]); + rstate->states[R600_BLEND__CB_BLEND_GREEN] = fui(rctx->blend_color.color[1]); + rstate->states[R600_BLEND__CB_BLEND_BLUE] = fui(rctx->blend_color.color[2]); + rstate->states[R600_BLEND__CB_BLEND_ALPHA] = fui(rctx->blend_color.color[3]); + rstate->states[R600_BLEND__CB_BLEND0_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND1_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND2_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND3_CONTROL] = 0x00000000; @@ -621,6 +628,37 @@ static struct radeon_state *r600_blend(struct r600_context *rctx) rstate->states[R600_BLEND__CB_BLEND6_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND7_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND_CONTROL] = 0x00000000; + + for (i = 0; i < 8; i++) { + + unsigned eqRGB = state->rt[i].rgb_func; + unsigned srcRGB = state->rt[i].rgb_src_factor; + unsigned dstRGB = state->rt[i].rgb_dst_factor; + + unsigned eqA = state->rt[i].alpha_func; + unsigned srcA = state->rt[i].alpha_src_factor; + unsigned dstA = state->rt[i].alpha_dst_factor; + uint32_t bc = 0; + + if (!state->rt[i].blend_enable) + continue; + + bc |= r600_translate_blend_function(eqRGB) << CB_BLEND_COLOR_COMB_FCN_SHIFT; + bc |= r600_translate_blend_factor(srcRGB) << CB_BLEND_COLOR_SRCBLEND_SHIFT; + bc |= r600_translate_blend_factor(dstRGB) << CB_BLEND_COLOR_DESTBLEND_SHIFT; + + if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { + bc |= CB_BLEND_SEPARATE_ALPHA_BLEND; + bc |= r600_translate_blend_function(eqA) << CB_BLEND_ALPHA_COMB_FCN_SHIFT; + bc |= r600_translate_blend_factor(srcA) << CB_BLEND_ALPHA_SRCBLEND_SHIFT; + bc |= r600_translate_blend_factor(dstA) << CB_BLEND_ALPHA_DESTBLEND_SHIFT; + } + + rstate->states[R600_BLEND__CB_BLEND0_CONTROL + i] = bc; + if (i == 0) + rstate->states[R600_BLEND__CB_BLEND_CONTROL] = bc; + } + if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); return NULL; @@ -1084,6 +1122,49 @@ static struct radeon_state *r600_resource(struct r600_context *rctx, return rstate; } +static struct radeon_state *r600_cb_cntl(struct r600_context *rctx) +{ + struct r600_screen *rscreen = rctx->screen; + struct radeon_state *rstate; + const struct pipe_blend_state *pbs = &rctx->blend->state.blend; + uint32_t color_control, target_mask; + int i; + + target_mask = 0; + color_control = 0; + + if (pbs->logicop_enable) { + color_control |= (pbs->logicop_func) << 16; + } else + color_control |= (0xcc << 16); + + target_mask |= (pbs->rt[0].colormask); + for (i = 0; i < 8; i++) { + if (pbs->rt[i].blend_enable) { + color_control |= (1 << (8 + i)); + target_mask |= (pbs->rt[0].colormask << (4 * i)); + } else if (i == 0) + target_mask |= 0xf; + } + rstate = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL); + rstate->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F; + rstate->states[R600_CB_CNTL__CB_TARGET_MASK] = target_mask; + rstate->states[R600_CB_CNTL__CB_COLOR_CONTROL] = color_control; + rstate->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000; + rstate->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000; + rstate->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000; + rstate->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000; + rstate->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000; + rstate->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF; + rstate->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF; + rstate->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF; + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; +} + int r600_context_hw_states(struct r600_context *rctx) { unsigned i; @@ -1093,7 +1174,7 @@ int r600_context_hw_states(struct r600_context *rctx) * doesn't */ //radeon_state_decref(rctx->hw_states.config); - //radeon_state_decref(rctx->hw_states.cb_cntl); + radeon_state_decref(rctx->hw_states.cb_cntl); radeon_state_decref(rctx->hw_states.db); radeon_state_decref(rctx->hw_states.rasterizer); radeon_state_decref(rctx->hw_states.scissor); @@ -1120,6 +1201,8 @@ int r600_context_hw_states(struct r600_context *rctx) rctx->hw_states.viewport = r600_viewport(rctx); rctx->hw_states.cb0 = r600_cb0(rctx); rctx->hw_states.db = r600_db(rctx); + rctx->hw_states.cb_cntl = r600_cb_cntl(rctx); + for (i = 0; i < rctx->ps_nsampler; i++) { if (rctx->ps_sampler[i]) { rctx->hw_states.ps_sampler[i] = r600_sampler(rctx, diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h new file mode 100644 index 00000000000..42bab52b3fa --- /dev/null +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -0,0 +1,100 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R600_STATE_INLINES_H +#define R600_STATE_INLINES_H + +#include "r600_reg.h" + +static INLINE uint32_t r600_translate_blend_function(int blend_func) +{ + switch (blend_func) { + case PIPE_BLEND_ADD: + return R600_BLEND_FCN_ADD; + case PIPE_BLEND_SUBTRACT: + return R600_BLEND_FCN_SUBTRACT; + case PIPE_BLEND_REVERSE_SUBTRACT: + return R600_BLEND_FCN_RSUB; + case PIPE_BLEND_MIN: + return R600_BLEND_FCN_MIN; + case PIPE_BLEND_MAX: + return R600_BLEND_FCN_MAX; + default: + fprintf(stderr, "r600: Unknown blend function %d\n", blend_func); + assert(0); + break; + } + return 0; +} + +static INLINE uint32_t r600_translate_blend_factor(int blend_fact) +{ + switch (blend_fact) { + case PIPE_BLENDFACTOR_ONE: + return R600_BLEND_ZERO; + case PIPE_BLENDFACTOR_SRC_COLOR: + return R600_BLEND_SRC_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA: + return R600_BLEND_SRC_ALPHA; + case PIPE_BLENDFACTOR_DST_ALPHA: + return R600_BLEND_DST_ALPHA; + case PIPE_BLENDFACTOR_DST_COLOR: + return R600_BLEND_DST_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + return R600_BLEND_SRC_ALPHA_SATURATE; + case PIPE_BLENDFACTOR_CONST_COLOR: + return R600_BLEND_CONST_COLOR; + case PIPE_BLENDFACTOR_CONST_ALPHA: + return R600_BLEND_CONST_ALPHA; + case PIPE_BLENDFACTOR_ZERO: + return R600_BLEND_ZERO; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + return R600_BLEND_ONE_MINUS_SRC_COLOR; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + return R600_BLEND_ONE_MINUS_SRC_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + return R600_BLEND_ONE_MINUS_DST_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + return R600_BLEND_ONE_MINUS_DST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + return R600_BLEND_ONE_MINUS_CONST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + return R600_BLEND_ONE_MINUS_CONST_ALPHA; + + case PIPE_BLENDFACTOR_SRC1_COLOR: + return R600_BLEND_SRC1_COLOR; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + return R600_BLEND_SRC1_ALPHA; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + return R600_BLEND_INV_SRC1_COLOR; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + return R600_BLEND_INV_SRC1_ALPHA; + default: + fprintf(stderr, "r600: Implementation error: " + "Bad blend factor %d not supported!\n", blend_fact); + assert(0); + break; + } + return 0; +} + +#endif