diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_state_derived.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_state_derived.c | 126 |
1 files changed, 33 insertions, 93 deletions
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 9c8e907fdf..292b20a7f4 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -99,78 +99,22 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300) gen_count++; } - /* XXX magic */ assert(gen_count <= 8); } -/* Update the PSC tables. */ -/* XXX move this function into r300_state.c after TCL-bypass gets removed - * XXX because this one is dependent only on vertex elements. */ -static void r300_vertex_psc(struct r300_context* r300) -{ - struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_vertex_stream_state *vformat = - (struct r300_vertex_stream_state*)r300->vertex_stream_state.state; - uint16_t type, swizzle; - enum pipe_format format; - unsigned i; - int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - int* stream_tab; - - memset(vformat, 0, sizeof(struct r300_vertex_stream_state)); - - stream_tab = identity; - - /* Vertex shaders have no semantics on their inputs, - * so PSC should just route stuff based on the vertex elements, - * and not on attrib information. */ - DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements" - " in psc\n", - vs->info.num_inputs, - r300->vertex_element_count); - - for (i = 0; i < r300->vertex_element_count; i++) { - format = r300->vertex_element[i].src_format; - - type = r300_translate_vertex_data_type(format) | - (stream_tab[i] << R300_DST_VEC_LOC_SHIFT); - swizzle = r300_translate_vertex_data_swizzle(format); - - if (i & 1) { - vformat->vap_prog_stream_cntl[i >> 1] |= type << 16; - vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; - } else { - vformat->vap_prog_stream_cntl[i >> 1] |= type; - vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; - } - } - - assert(i <= 15); - - /* Set the last vector in the PSC. */ - if (i) { - i -= 1; - } - vformat->vap_prog_stream_cntl[i >> 1] |= - (R300_LAST_VEC << (i & 1 ? 16 : 0)); - - vformat->count = (i >> 1) + 1; - r300->vertex_stream_state.size = (1 + vformat->count) * 2; -} - /* Update the PSC tables for SW TCL, using Draw. */ -static void r300_swtcl_vertex_psc(struct r300_context* r300) +static void r300_swtcl_vertex_psc(struct r300_context *r300) { + struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state; struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_vertex_stream_state *vformat = - (struct r300_vertex_stream_state*)r300->vertex_stream_state.state; struct vertex_info* vinfo = &r300->vertex_info; uint16_t type, swizzle; enum pipe_format format; unsigned i, attrib_count; int* vs_output_tab = vs->stream_loc_notcl; - memset(vformat, 0, sizeof(struct r300_vertex_stream_state)); + /* XXX hax */ + memset(vstream, 0, sizeof(struct r300_vertex_stream_state)); /* For each Draw attribute, route it to the fragment shader according * to the vs_output_tab. */ @@ -181,9 +125,7 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300) " vs_output_tab %d\n", vinfo->attrib[i].src_index, vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, vs_output_tab[i]); - } - for (i = 0; i < attrib_count; i++) { /* Make sure we have a proper destination for our attribute. */ assert(vs_output_tab[i] != -1); @@ -199,11 +141,11 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300) /* Add the attribute to the PSC table. */ if (i & 1) { - vformat->vap_prog_stream_cntl[i >> 1] |= type << 16; - vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; + vstream->vap_prog_stream_cntl[i >> 1] |= type << 16; + vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; } else { - vformat->vap_prog_stream_cntl[i >> 1] |= type; - vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; + vstream->vap_prog_stream_cntl[i >> 1] |= type; + vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; } } @@ -211,11 +153,12 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300) if (i) { i -= 1; } - vformat->vap_prog_stream_cntl[i >> 1] |= + vstream->vap_prog_stream_cntl[i >> 1] |= (R300_LAST_VEC << (i & 1 ? 16 : 0)); - vformat->count = (i >> 1) + 1; - r300->vertex_stream_state.size = (1 + vformat->count) * 2; + vstream->count = (i >> 1) + 1; + r300->vertex_stream_state.dirty = TRUE; + r300->vertex_stream_state.size = (1 + vstream->count) * 2; } static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr, @@ -322,7 +265,7 @@ static void r300_update_rs_block(struct r300_context* r300, boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED || vs_outputs->bcolor[1] != ATTR_UNUSED; - if (r300_screen(r300->context.screen)->caps->is_r500) { + if (r300->screen->caps.is_r500) { rX00_rs_col = r500_rs_col; rX00_rs_col_write = r500_rs_col_write; rX00_rs_tex = r500_rs_tex; @@ -432,23 +375,8 @@ static void r300_update_rs_block(struct r300_context* r300, static void r300_update_derived_shader_state(struct r300_context* r300) { struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_screen* r300screen = r300_screen(r300->context.screen); - struct r300_vap_output_state *vap_out = - (struct r300_vap_output_state*)r300->vap_output_state.state; - - /* XXX Mmm, delicious hax */ - memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); - memcpy(vap_out, vs->hwfmt, sizeof(uint)*4); r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs); - - if (r300screen->caps->has_tcl) { - r300_vertex_psc(r300); - } else { - r300_draw_emit_all_attribs(r300); - draw_compute_vertex_size(&r300->vertex_info); - r300_swtcl_vertex_psc(r300); - } } static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa) @@ -528,20 +456,25 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) (struct r300_textures_state*)r300->textures_state.state; struct r300_texture_sampler_state *texstate; struct r300_sampler_state *sampler; + struct pipe_sampler_view *view; struct r300_texture *tex; unsigned min_level, max_level, i, size; unsigned count = MIN2(state->texture_count, state->sampler_count); state->tx_enable = 0; + state->count = 0; size = 2; for (i = 0; i < count; i++) { - if (state->textures[i] && state->sampler_states[i]) { + if (state->fragment_sampler_views[i] && state->sampler_states[i]) { state->tx_enable |= 1 << i; - tex = state->textures[i]; + view = state->fragment_sampler_views[i]; + tex = (struct r300_texture *)view->texture; sampler = state->sampler_states[i]; + assert(view->format == tex->tex.format); + texstate = &state->regs[i]; memcpy(texstate->format, &tex->state, sizeof(uint32_t)*3); texstate->filter[0] = sampler->filter0; @@ -556,15 +489,17 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) texstate->filter[0] |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); } - if (tex->is_npot) { + if (tex->uses_pitch) { /* NPOT textures don't support mip filter, unfortunately. * This prevents incorrect rendering. */ texstate->filter[0] &= ~R300_TX_MIN_FILTER_MIP_MASK; } else { /* determine min/max levels */ /* the MAX_MIP level is the largest (finest) one */ - max_level = MIN2(sampler->max_lod, tex->tex.last_level); - min_level = MIN2(sampler->min_lod, max_level); + max_level = MIN3(sampler->max_lod + view->first_level, + tex->tex.last_level, view->last_level); + min_level = MIN2(sampler->min_lod + view->first_level, + max_level); texstate->format[0] |= R300_TX_NUM_LEVELS(max_level); texstate->filter[0] |= R300_TX_MAX_MIP_LEVEL(min_level); } @@ -581,9 +516,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) void r300_update_derived_state(struct r300_context* r300) { - if (r300->rs_block_state.dirty || - r300->vertex_stream_state.dirty || /* XXX put updating this state out of this file */ - r300->rs_state.dirty) { /* XXX and remove this one (tcl_bypass dependency) */ + if (r300->rs_block_state.dirty) { r300_update_derived_shader_state(r300); } @@ -591,5 +524,12 @@ void r300_update_derived_state(struct r300_context* r300) r300_merge_textures_and_samplers(r300); } + if (r300->draw) { + memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); + r300_draw_emit_all_attribs(r300); + draw_compute_vertex_size(&r300->vertex_info); + r300_swtcl_vertex_psc(r300); + } + r300_update_ztop(r300); } |