r300: Add blend color.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Sat, 17 Jan 2009 10:25:52 +0000 (02:25 -0800)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Mon, 2 Feb 2009 07:30:23 +0000 (23:30 -0800)
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_state.c

index 6dfc9ed6246f52d439bca5d1d3e7421cf6031b1e..b072179f5be8ab011b4672f13870c7fda7403038 100644 (file)
@@ -27,6 +27,7 @@ static void r300_destroy_context(struct pipe_context* context) {
 
     draw_destroy(r300->draw);
 
+    FREE(r300->blend_color_state);
     FREE(r300->scissor_state);
     FREE(r300);
 }
@@ -48,6 +49,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
 
     r300->draw = draw_create();
 
+    r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);
     r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);
 
     r300_init_surface_functions(r300);
index ea057bcab77eb4d7f90dc1b8c03717927f988717..4cbbf96fb1146342bfd3b49a0e2d1adaa2548fb4 100644 (file)
@@ -36,6 +36,14 @@ struct r300_blend_state {
     uint32_t dither;              /* R300_RB3D_DITHER_CTL: 0x4e50 */
 };
 
+struct r300_blend_color_state {
+    /* RV515 and earlier */
+    uint32_t blend_color;            /* R300_RB3D_BLEND_COLOR: 0x4e10 */
+    /* R520 and newer */
+    uint32_t blend_color_red_alpha;  /* R500_RB3D_CONSTANT_COLOR_AR: 0x4ef8 */
+    uint32_t blend_color_green_blue; /* R500_RB3D_CONSTANT_COLOR_GB: 0x4efc */
+};
+
 struct r300_dsa_state {
     uint32_t alpha_function;    /* R300_FG_ALPHA_FUNC: 0x4bd4 */
     uint32_t alpha_reference;   /* R500_FG_ALPHA_VALUE: 0x4be0 */
@@ -60,10 +68,11 @@ struct r300_scissor_state {
     uint32_t scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
 };
 
-#define R300_NEW_BLEND    0x1
-#define R300_NEW_DSA      0x2
-#define R300_NEW_RS       0x4
-#define R300_NEW_SCISSOR  0x8
+#define R300_NEW_BLEND          0x01
+#define R300_NEW_BLEND_COLOR    0x02
+#define R300_NEW_DSA            0x04
+#define R300_NEW_RS             0x08
+#define R300_NEW_SCISSOR        0x10
 
 struct r300_context {
     /* Parent class */
@@ -77,6 +86,8 @@ struct r300_context {
     /* Various CSO state objects. */
     /* Blend state. */
     struct r300_blend_state* blend_state;
+    /* Blend color state. */
+    struct r300_blend_color_state* blend_color_state;
     /* Depth, stencil, and alpha state. */
     struct r300_dsa_state* dsa_state;
     /* Rasterizer state. */
index 7668b14c637ac55121352016a4363411cce73b91..4392078e74c31ff50ab16025852ee1177c26b73b 100644 (file)
@@ -165,6 +165,33 @@ static void r300_delete_blend_state(struct pipe_context* pipe,
     FREE(state);
 }
 
+/* Set blend color.
+ * Setup both R300 and R500 registers, figure out later which one to write. */
+static void r300_set_blend_color(struct pipe_context* pipe,
+                                 const struct pipe_blend_color* color)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    uint32_t r, g, b, a;
+    ubyte ur, ug, ub, ua;
+
+    r = util_iround(color->color[0] * 1023.0f);
+    g = util_iround(color->color[1] * 1023.0f);
+    b = util_iround(color->color[2] * 1023.0f);
+    a = util_iround(color->color[3] * 1023.0f);
+
+    ur = float_to_ubyte(color->color[0]);
+    ug = float_to_ubyte(color->color[1]);
+    ub = float_to_ubyte(color->color[2]);
+    ua = float_to_ubyte(color->color[3]);
+
+    r300->blend_color_state->blend_color = (a << 24) | (r << 16) | (g << 8) | b;
+
+    r300->blend_color_state->blend_color_red_alpha = ur | (ua << 16);
+    r300->blend_color_state->blend_color_green_blue = ub | (ug << 16);
+
+    r300->dirty_state |= R300_NEW_BLEND_COLOR;
+}
+
 static uint32_t translate_depth_stencil_function(int zs_func) {
     switch (zs_func) {
         case PIPE_FUNC_NEVER:
@@ -474,6 +501,8 @@ void r300_init_state_functions(struct r300_context* r300) {
     r300->context.bind_blend_state = r300_bind_blend_state;
     r300->context.delete_blend_state = r300_delete_blend_state;
 
+    r300->context.set_blend_color = r300_set_blend_color;
+
     r300->context.create_rasterizer_state = r300_create_rs_state;
     r300->context.bind_rasterizer_state = r300_bind_rs_state;
     r300->context.delete_rasterizer_state = r300_delete_rs_state;