diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_state.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 108 |
1 files changed, 76 insertions, 32 deletions
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 7505353953..8bcd6c5060 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,7 +328,18 @@ 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; + r300->dirty_state |= R300_NEW_BLEND; } /* Create fragment shader state. */ @@ -317,6 +355,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe, fs->state.tokens = tgsi_dup_tokens(shader->tokens); tgsi_scan_shader(shader->tokens, &fs->info); + r300_shader_read_fs_inputs(&fs->info, &fs->inputs); return (void*)fs; } @@ -330,11 +369,10 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) if (fs == NULL) { r300->fs = NULL; return; - } else if (!fs->translated) { - r300_translate_fragment_shader(r300, fs); } r300->fs = fs; + r300_pick_fragment_shader(r300); r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; } @@ -343,7 +381,14 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) static void r300_delete_fs_state(struct pipe_context* pipe, void* shader) { struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; - rc_constants_destroy(&fs->code.constants); + struct r300_fragment_shader_code *tmp, *ptr = fs->first; + + while (ptr) { + tmp = ptr; + ptr = ptr->next; + rc_constants_destroy(&tmp->code.constants); + FREE(tmp); + } FREE((void*)fs->state.tokens); FREE(shader); } @@ -382,8 +427,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) | @@ -474,10 +517,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe, rs->color_control = R300_SHADE_MODEL_SMOOTH; } - if (!state->flatshade_first) { - rs->color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST; - } - return (void*)rs; } @@ -513,6 +552,9 @@ 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->state = *state; sampler->filter0 |= (r300_translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) | @@ -534,8 +576,8 @@ static void* 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) { @@ -564,6 +606,20 @@ static void r300_bind_sampler_states(struct pipe_context* pipe, } r300->sampler_count = count; + + /* Pick a fragment shader based on the texture compare state. */ + if (r300->fs && (r300->dirty_state & R300_ANY_NEW_SAMPLERS)) { + if (r300_pick_fragment_shader(r300)) { + r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | + R300_NEW_FRAGMENT_SHADER_CONSTANTS; + } + } +} + +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) @@ -584,8 +640,6 @@ static void r300_set_sampler_textures(struct pipe_context* pipe, return; } - r300->context.flush(&r300->context, 0, NULL); - for (i = 0; i < count; i++) { if (r300->textures[i] != (struct r300_texture*)texture[i]) { pipe_texture_reference((struct pipe_texture**)&r300->textures[i], @@ -617,24 +671,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, @@ -823,6 +866,7 @@ void r300_init_state_functions(struct r300_context* r300) r300->context.create_sampler_state = r300_create_sampler_state; 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_fragment_sampler_textures = r300_set_sampler_textures; |