summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/r300/r300_context.c2
-rw-r--r--src/gallium/drivers/r300/r300_context.h19
-rw-r--r--src/gallium/drivers/r300/r300_state.c29
3 files changed, 46 insertions, 4 deletions
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 6dfc9ed624..b072179f5b 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -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);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index ea057bcab7..4cbbf96fb1 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -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. */
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 7668b14c63..4392078e74 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -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;