diff options
author | Marek Olšák <maraeo@gmail.com> | 2011-03-04 16:39:51 +0100 |
---|---|---|
committer | Marek Olšák <maraeo@gmail.com> | 2011-03-04 17:47:56 +0100 |
commit | 910bac63dfc5c6d9bf7162388c951784eba534f6 (patch) | |
tree | 17093a72704672158ee61f9bd07f31dab15b6030 /src | |
parent | 4a4f6a390160d8c535e0a7ae96a203a99971f3c0 (diff) |
r300g: implement blending for some of non-RGBA8 formats
Blending is now fully supported with:
- R8_UNORM
- R8G8_UNORM
- B8G8R8A8_UNORM
- R16G16B16A16_FLOAT (r500-only)
Blending is partially supported (DST_ALPHA not working) with:
- L8A8_UNORM
- I8_UNORM
- B5G5R5A1_UNORM
- B10G10R10A2_UNORM
The other formats can't do blending.
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 58 |
2 files changed, 52 insertions, 7 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 6f2aab69ab1..b0a67e01225 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -70,6 +70,7 @@ struct r300_blend_state { }; struct r300_blend_color_state { + struct pipe_blend_color state; uint32_t cb[3]; }; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index b810f4081c8..64fd7136b30 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -24,6 +24,7 @@ #include "draw/draw_context.h" #include "util/u_framebuffer.h" +#include "util/u_half.h" #include "util/u_math.h" #include "util/u_mm.h" #include "util/u_memory.h" @@ -395,22 +396,64 @@ static void r300_set_blend_color(struct pipe_context* pipe, const struct pipe_blend_color* color) { struct r300_context* r300 = r300_context(pipe); - struct r300_blend_color_state* state = + struct pipe_framebuffer_state *fb = r300->fb_state.state; + struct r300_blend_color_state *state = (struct r300_blend_color_state*)r300->blend_color_state.state; + struct pipe_blend_color c; + enum pipe_format format = fb->nr_cbufs ? fb->cbufs[0]->format : 0; CB_LOCALS; + state->state = *color; /* Save it, so that we can reuse it in set_fb_state */ + c = *color; + + /* The blend color is dependent on the colorbuffer format. */ + if (fb->nr_cbufs) { + switch (format) { + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_I8_UNORM: + c.color[1] = c.color[0]; + break; + + case PIPE_FORMAT_A8_UNORM: + c.color[1] = c.color[3]; + break; + + case PIPE_FORMAT_R8G8_UNORM: + c.color[2] = c.color[1]; + break; + + case PIPE_FORMAT_L8A8_UNORM: + c.color[2] = c.color[3]; + break; + + default:; + } + } + if (r300->screen->caps.is_r500) { - /* XXX if FP16 blending is enabled, we should use the FP16 format */ BEGIN_CB(state->cb, 3); OUT_CB_REG_SEQ(R500_RB3D_CONSTANT_COLOR_AR, 2); - OUT_CB(float_to_fixed10(color->color[0]) | - (float_to_fixed10(color->color[3]) << 16)); - OUT_CB(float_to_fixed10(color->color[2]) | - (float_to_fixed10(color->color[1]) << 16)); + + switch (format) { + case PIPE_FORMAT_R16G16B16A16_FLOAT: + OUT_CB(util_float_to_half(c.color[2]) | + (util_float_to_half(c.color[3]) << 16)); + OUT_CB(util_float_to_half(c.color[0]) | + (util_float_to_half(c.color[1]) << 16)); + break; + + default: + OUT_CB(float_to_fixed10(c.color[0]) | + (float_to_fixed10(c.color[3]) << 16)); + OUT_CB(float_to_fixed10(c.color[2]) | + (float_to_fixed10(c.color[1]) << 16)); + } + END_CB; } else { union util_color uc; - util_pack_color(color->color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); + util_pack_color(c.color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); BEGIN_CB(state->cb, 2); OUT_CB_REG(R300_RB3D_BLEND_COLOR, uc.ui); @@ -686,6 +729,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, /* What is marked as dirty depends on the enum r300_fb_state_change. */ if (change == R300_CHANGED_FB_STATE) { r300_mark_atom_dirty(r300, &r300->aa_state); + r300_set_blend_color(&r300->context, r300->blend_color_state.state); } if (change == R300_CHANGED_FB_STATE || |