summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_state.c')
-rw-r--r--src/gallium/drivers/r300/r300_state.c105
1 files changed, 73 insertions, 32 deletions
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index d1eced61db..edf7114bbb 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -151,9 +151,10 @@ static void r300_set_blend_color(struct pipe_context* pipe,
const struct pipe_blend_color* color)
{
struct r300_context* r300 = r300_context(pipe);
+ union util_color uc;
- util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM,
- &r300->blend_color_state->blend_color);
+ util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc);
+ r300->blend_color_state->blend_color = uc.ui;
/* XXX if FP16 blending is enabled, we should use the FP16 format */
r300->blend_color_state->blend_color_red_alpha =
@@ -289,11 +290,37 @@ static void r300_set_edgeflags(struct pipe_context* pipe,
/* XXX and even worse, I have no idea WTF the bitfield is */
}
+static void r300_set_scissor_regs(const struct pipe_scissor_state* state,
+ struct r300_scissor_regs *scissor,
+ boolean is_r500)
+{
+ if (is_r500) {
+ scissor->top_left =
+ (state->minx << R300_SCISSORS_X_SHIFT) |
+ (state->miny << R300_SCISSORS_Y_SHIFT);
+ scissor->bottom_right =
+ ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) |
+ ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT);
+ } else {
+ /* Offset of 1440 in non-R500 chipsets. */
+ scissor->top_left =
+ ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) |
+ ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT);
+ scissor->bottom_right =
+ (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
+ (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
+ }
+
+ scissor->empty_area = state->minx >= state->maxx ||
+ state->miny >= state->maxy;
+}
+
static void
r300_set_framebuffer_state(struct pipe_context* pipe,
const struct pipe_framebuffer_state* state)
{
struct r300_context* r300 = r300_context(pipe);
+ struct pipe_scissor_state scissor;
if (r300->draw) {
draw_flush(r300->draw);
@@ -301,6 +328,16 @@ static void
r300->framebuffer_state = *state;
+ scissor.minx = scissor.miny = 0;
+ scissor.maxx = state->width;
+ scissor.maxy = state->height;
+ r300_set_scissor_regs(&scissor, &r300->scissor_state->framebuffer,
+ r300_screen(r300->context.screen)->caps->is_r500);
+
+ /* Don't rely on the order of states being set for the first time. */
+ if (!r300->rs_state || !r300->rs_state->rs.scissor) {
+ r300->dirty_state |= R300_NEW_SCISSOR;
+ }
r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
}
@@ -382,8 +419,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
if (state->bypass_vs_clip_and_viewport ||
!r300_screen(pipe->screen)->caps->has_tcl) {
rs->vap_control_status |= R300_VAP_TCL_BYPASS;
- } else {
- rs->rs.bypass_vs_clip_and_viewport = TRUE;
}
rs->point_size = pack_float_16_6x(state->point_size) |
@@ -513,6 +548,7 @@ static void*
struct r300_context* r300 = r300_context(pipe);
struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
int lod_bias;
+ union util_color uc;
sampler->filter0 |=
(r300_translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) |
@@ -523,14 +559,19 @@ static void*
state->mag_img_filter,
state->min_mip_filter);
+ /* Unfortunately, r300-r500 don't support floating-point mipmap lods. */
+ /* We must pass these to the emit function to clamp them properly. */
+ sampler->min_lod = MAX2((unsigned)state->min_lod, 0);
+ sampler->max_lod = MAX2((unsigned)ceilf(state->max_lod), 0);
+
lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1);
sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT;
sampler->filter1 |= r300_anisotropy(state->max_anisotropy);
- util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM,
- &sampler->border_color);
+ util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc);
+ sampler->border_color = uc.ui;
/* R500-specific fixups and optimizations */
if (r300_screen(r300->context.screen)->caps->is_r500) {
@@ -561,6 +602,12 @@ static void r300_bind_sampler_states(struct pipe_context* pipe,
r300->sampler_count = count;
}
+static void r300_lacks_vertex_textures(struct pipe_context* pipe,
+ unsigned count,
+ void** states)
+{
+}
+
static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)
{
FREE(state);
@@ -571,6 +618,7 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
struct pipe_texture** texture)
{
struct r300_context* r300 = r300_context(pipe);
+ boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
int i;
/* XXX magic num */
@@ -585,6 +633,13 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
texture[i]);
r300->dirty_state |= (R300_NEW_TEXTURE << i);
+
+ /* R300-specific - set the texrect factor in a fragment shader */
+ if (!is_r500 && r300->textures[i]->is_npot) {
+ /* XXX It would be nice to re-emit just 1 constant,
+ * XXX not all of them */
+ r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ }
}
}
@@ -604,24 +659,13 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
- if (r300_screen(r300->context.screen)->caps->is_r500) {
- r300->scissor_state->scissor_top_left =
- (state->minx << R300_SCISSORS_X_SHIFT) |
- (state->miny << R300_SCISSORS_Y_SHIFT);
- r300->scissor_state->scissor_bottom_right =
- ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) |
- ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT);
- } else {
- /* Offset of 1440 in non-R500 chipsets. */
- r300->scissor_state->scissor_top_left =
- ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) |
- ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT);
- r300->scissor_state->scissor_bottom_right =
- (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
- (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
- }
+ r300_set_scissor_regs(state, &r300->scissor_state->scissor,
+ r300_screen(r300->context.screen)->caps->is_r500);
- r300->dirty_state |= R300_NEW_SCISSOR;
+ /* Don't rely on the order of states being set for the first time. */
+ if (!r300->rs_state || r300->rs_state->rs.scissor) {
+ r300->dirty_state |= R300_NEW_SCISSOR;
+ }
}
static void r300_set_viewport_state(struct pipe_context* pipe,
@@ -674,6 +718,8 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
draw_flush(r300->draw);
draw_set_vertex_buffers(r300->draw, count, buffers);
}
+
+ r300->dirty_state |= R300_NEW_VERTEX_FORMAT;
}
static void r300_set_vertex_elements(struct pipe_context* pipe,
@@ -706,9 +752,6 @@ static void* r300_create_vs_state(struct pipe_context* pipe,
tgsi_scan_shader(shader->tokens, &vs->info);
- /* Appease Draw. */
- vs->draw = draw_create_vertex_shader(r300->draw, shader);
-
return (void*)vs;
} else {
return draw_create_vertex_shader(r300->draw, shader);
@@ -719,8 +762,6 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
- draw_flush(r300->draw);
-
if (r300_screen(pipe->screen)->caps->has_tcl) {
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
@@ -731,10 +772,10 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
r300_translate_vertex_shader(r300, vs);
}
- draw_bind_vertex_shader(r300->draw, vs->draw);
r300->vs = vs;
r300->dirty_state |= R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS;
} else {
+ draw_flush(r300->draw);
draw_bind_vertex_shader(r300->draw,
(struct draw_vertex_shader*)shader);
}
@@ -748,7 +789,6 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
rc_constants_destroy(&vs->code.constants);
- draw_delete_vertex_shader(r300->draw, vs->draw);
FREE((void*)vs->state.tokens);
FREE(shader);
} else {
@@ -813,10 +853,11 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.delete_rasterizer_state = r300_delete_rs_state;
r300->context.create_sampler_state = r300_create_sampler_state;
- r300->context.bind_sampler_states = r300_bind_sampler_states;
+ r300->context.bind_fragment_sampler_states = r300_bind_sampler_states;
+ r300->context.bind_vertex_sampler_states = r300_lacks_vertex_textures;
r300->context.delete_sampler_state = r300_delete_sampler_state;
- r300->context.set_sampler_textures = r300_set_sampler_textures;
+ r300->context.set_fragment_sampler_textures = r300_set_sampler_textures;
r300->context.set_scissor_state = r300_set_scissor_state;