summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2011-03-04 16:39:51 +0100
committerMarek Olšák <[email protected]>2011-03-04 17:47:56 +0100
commit910bac63dfc5c6d9bf7162388c951784eba534f6 (patch)
tree17093a72704672158ee61f9bd07f31dab15b6030 /src
parent4a4f6a390160d8c535e0a7ae96a203a99971f3c0 (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.h1
-rw-r--r--src/gallium/drivers/r300/r300_state.c58
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 ||