diff options
author | Marek Olšák <maraeo@gmail.com> | 2011-03-13 11:54:29 +0100 |
---|---|---|
committer | Marek Olšák <maraeo@gmail.com> | 2011-03-14 10:09:34 +0100 |
commit | 23ccab39cd6b89efd8be238c3061e7ddb3697a55 (patch) | |
tree | 0f52c6797d54600c155f6b4e3f77557a7f5642f3 | |
parent | 340e15c79b9c973d8dcefb55e2adf3ac813d1fec (diff) |
r300g: clamp after blending for fixed-point formats only
-rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 5 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 42 |
3 files changed, 36 insertions, 14 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 1624708710..e395f41290 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -67,7 +67,8 @@ struct r300_aa_state { struct r300_blend_state { struct pipe_blend_state state; - uint32_t cb[8]; + uint32_t cb_clamp[8]; + uint32_t cb_noclamp[8]; uint32_t cb_no_readwrite[8]; }; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index b28be9367f..e17a907e77 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -45,7 +45,10 @@ void r300_emit_blend_state(struct r300_context* r300, CS_LOCALS(r300); if (fb->nr_cbufs) { - WRITE_CS_TABLE(blend->cb, size); + if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) + WRITE_CS_TABLE(blend->cb_noclamp, size); + else + WRITE_CS_TABLE(blend->cb_clamp, size); } else { WRITE_CS_TABLE(blend->cb_no_readwrite, size); } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index f0830e13f0..d449265b66 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -188,11 +188,12 @@ static void* r300_create_blend_state(struct pipe_context* pipe, struct r300_screen* r300screen = r300_screen(pipe->screen); struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); uint32_t blend_control = 0; /* R300_RB3D_CBLEND: 0x4e04 */ + uint32_t blend_control_noclamp = 0; /* R300_RB3D_CBLEND: 0x4e04 */ uint32_t alpha_blend_control = 0; /* R300_RB3D_ABLEND: 0x4e08 */ + uint32_t alpha_blend_control_noclamp = 0; /* R300_RB3D_ABLEND: 0x4e08 */ uint32_t color_channel_mask = 0; /* R300_RB3D_COLOR_CHANNEL_MASK: 0x4e0c */ uint32_t rop = 0; /* R300_RB3D_ROPCNTL: 0x4e18 */ uint32_t dither = 0; /* R300_RB3D_DITHER_CTL: 0x4e50 */ - boolean clamp = TRUE; CB_LOCALS; blend->state = *state; @@ -209,10 +210,14 @@ static void* r300_create_blend_state(struct pipe_context* pipe, /* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha, * this is just the crappy D3D naming */ - blend_control = R300_ALPHA_BLEND_ENABLE | - r300_translate_blend_function(eqRGB, clamp) | + blend_control = blend_control_noclamp = + R300_ALPHA_BLEND_ENABLE | ( r300_translate_blend_factor(srcRGB) << R300_SRC_BLEND_SHIFT) | ( r300_translate_blend_factor(dstRGB) << R300_DST_BLEND_SHIFT); + blend_control |= + r300_translate_blend_function(eqRGB, TRUE); + blend_control_noclamp |= + r300_translate_blend_function(eqRGB, FALSE); /* Optimization: some operations do not require the destination color. * @@ -234,6 +239,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe, srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE) { /* Enable reading from the colorbuffer. */ blend_control |= R300_READ_ENABLE; + blend_control_noclamp |= R300_READ_ENABLE; if (r300screen->caps.is_r500) { /* Optimization: Depending on incoming pixels, we can @@ -271,8 +277,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe, * * Equations other than ADD are rarely used and therefore won't be * optimized. */ - if (clamp && - (eqRGB == PIPE_BLEND_ADD || eqRGB == PIPE_BLEND_REVERSE_SUBTRACT) && + if ((eqRGB == PIPE_BLEND_ADD || eqRGB == PIPE_BLEND_REVERSE_SUBTRACT) && (eqA == PIPE_BLEND_ADD || eqA == PIPE_BLEND_REVERSE_SUBTRACT)) { /* ADD: X+Y * REVERSE_SUBTRACT: Y-X @@ -310,10 +315,14 @@ static void* r300_create_blend_state(struct pipe_context* pipe, /* separate alpha */ if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { blend_control |= R300_SEPARATE_ALPHA_ENABLE; - alpha_blend_control = - r300_translate_blend_function(eqA, clamp) | + blend_control_noclamp |= R300_SEPARATE_ALPHA_ENABLE; + alpha_blend_control = alpha_blend_control_noclamp = (r300_translate_blend_factor(srcA) << R300_SRC_BLEND_SHIFT) | (r300_translate_blend_factor(dstA) << R300_DST_BLEND_SHIFT); + alpha_blend_control |= + r300_translate_blend_function(eqA, TRUE); + alpha_blend_control_noclamp |= + r300_translate_blend_function(eqA, FALSE); } } @@ -350,7 +359,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe, */ /* Build a command buffer. */ - BEGIN_CB(blend->cb, 8); + BEGIN_CB(blend->cb_clamp, 8); OUT_CB_REG(R300_RB3D_ROPCNTL, rop); OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3); OUT_CB(blend_control); @@ -359,6 +368,16 @@ static void* r300_create_blend_state(struct pipe_context* pipe, OUT_CB_REG(R300_RB3D_DITHER_CTL, dither); END_CB; + /* Build a command buffer. */ + BEGIN_CB(blend->cb_noclamp, 8); + OUT_CB_REG(R300_RB3D_ROPCNTL, rop); + OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3); + OUT_CB(blend_control_noclamp); + OUT_CB(alpha_blend_control_noclamp); + OUT_CB(color_channel_mask); + OUT_CB_REG(R300_RB3D_DITHER_CTL, dither); + END_CB; + /* The same as above, but with no colorbuffer reads and writes. */ BEGIN_CB(blend->cb_no_readwrite, 8); OUT_CB_REG(R300_RB3D_ROPCNTL, rop); @@ -842,10 +861,9 @@ r300_set_framebuffer_state(struct pipe_context* pipe, } } - /* If nr_cbufs is changed from zero to non-zero or vice versa... */ - if (!!old_state->nr_cbufs != !!state->nr_cbufs) { - r300_mark_atom_dirty(r300, &r300->blend_state); - } + /* Need to reset clamping or colormask. */ + r300_mark_atom_dirty(r300, &r300->blend_state); + /* If zsbuf is set from NULL to non-NULL or vice versa.. */ if (!!old_state->zsbuf != !!state->zsbuf) { r300_mark_atom_dirty(r300, &r300->dsa_state); |