From e8f2adf8e3f381176703bf8bf4e927c8ce6bc891 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 20 Jun 2010 05:30:04 +0200 Subject: r300g: manually assign texture cache regions This should fix corrupted texturing on r3xx-r4xx. --- src/gallium/drivers/r300/r300_context.h | 3 +++ src/gallium/drivers/r300/r300_reg.h | 34 +++++++++++++++++++++++++++ src/gallium/drivers/r300/r300_state.c | 34 ++++++++++++++++++++++++++- src/gallium/drivers/r300/r300_state_derived.c | 3 +++ 4 files changed, 73 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 8e9742fe82f..224d5737753 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -174,6 +174,9 @@ struct r300_sampler_view { /* Copy of r300_texture::texture_format_state with format-specific bits * added. */ struct r300_texture_format_state format; + + /* The texture cache region for this texture. */ + uint32_t texcache_region; }; struct r300_texture_fb_state { diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 04eaa83f697..c783998c78d 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -1630,6 +1630,40 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_TX_FORMAT_GAMMA (1 << 21) # define R300_TX_FORMAT_YUV_TO_RGB (1 << 22) +# define R300_TX_CACHE(x) ((x) << 27) +# define R300_TX_CACHE_WHOLE 0 +/* reserved */ +# define R300_TX_CACHE_HALF_0 2 +# define R300_TX_CACHE_HALF_1 3 +# define R300_TX_CACHE_FOURTH_0 4 +# define R300_TX_CACHE_FOURTH_1 5 +# define R300_TX_CACHE_FOURTH_2 6 +# define R300_TX_CACHE_FOURTH_3 7 +# define R300_TX_CACHE_EIGHTH_0 8 +# define R300_TX_CACHE_EIGHTH_1 9 +# define R300_TX_CACHE_EIGHTH_2 10 +# define R300_TX_CACHE_EIGHTH_3 11 +# define R300_TX_CACHE_EIGHTH_4 12 +# define R300_TX_CACHE_EIGHTH_5 13 +# define R300_TX_CACHE_EIGHTH_6 14 +# define R300_TX_CACHE_EIGHTH_7 15 +# define R300_TX_CACHE_SIXTEENTH_0 16 +# define R300_TX_CACHE_SIXTEENTH_1 17 +# define R300_TX_CACHE_SIXTEENTH_2 18 +# define R300_TX_CACHE_SIXTEENTH_3 19 +# define R300_TX_CACHE_SIXTEENTH_4 20 +# define R300_TX_CACHE_SIXTEENTH_5 21 +# define R300_TX_CACHE_SIXTEENTH_6 22 +# define R300_TX_CACHE_SIXTEENTH_7 23 +# define R300_TX_CACHE_SIXTEENTH_8 24 +# define R300_TX_CACHE_SIXTEENTH_9 25 +# define R300_TX_CACHE_SIXTEENTH_10 26 +# define R300_TX_CACHE_SIXTEENTH_11 27 +# define R300_TX_CACHE_SIXTEENTH_12 28 +# define R300_TX_CACHE_SIXTEENTH_13 29 +# define R300_TX_CACHE_SIXTEENTH_14 30 +# define R300_TX_CACHE_SIXTEENTH_15 31 + #define R300_TX_FORMAT2_0 0x4500 /* obvious missing in gap */ # define R300_TX_PITCHMASK_SHIFT 0 # define R300_TX_PITCHMASK_MASK (2047 << 0) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 256184aac9e..9c5a2a05bd4 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1107,6 +1107,28 @@ static void r300_delete_sampler_state(struct pipe_context* pipe, void* state) FREE(state); } +static uint32_t r300_assign_texture_cache_region(unsigned index, unsigned num) +{ + /* This looks like a hack, but I believe it's suppose to work like + * that. To illustrate how this works, let's assume you have 5 textures. + * From docs, 5 and the successive numbers are: + * + * FOURTH_1 = 5 + * FOURTH_2 = 6 + * FOURTH_3 = 7 + * EIGHTH_0 = 8 + * EIGHTH_1 = 9 + * + * First 3 textures will get 3/4 of size of the cache, divived evenly + * between them. The last 1/4 of the cache must be divided between + * the last 2 textures, each will therefore get 1/8 of the cache. + * Why not just to use "5 + texture_index" ? + * + * This simple trick works for all "num" <= 16. + */ + return R300_TX_CACHE(num + index); +} + static void r300_set_fragment_sampler_views(struct pipe_context* pipe, unsigned count, struct pipe_sampler_view** views) @@ -1115,7 +1137,7 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe, struct r300_textures_state* state = (struct r300_textures_state*)r300->textures_state.state; struct r300_texture *texture; - unsigned i; + unsigned i, real_num_views = 0, view_index = 0; unsigned tex_units = r300->screen->caps.num_tex_units; boolean dirty_tex = FALSE; @@ -1123,6 +1145,12 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe, return; } + /* Calculate the real number of views. */ + for (i = 0; i < count; i++) { + if (views[i]) + real_num_views++; + } + for (i = 0; i < count; i++) { if (&state->sampler_views[i]->base != views[i]) { pipe_sampler_view_reference( @@ -1142,6 +1170,10 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe, if (texture->uses_pitch) { r300->fs_rc_constant_state.dirty = TRUE; } + + state->sampler_views[i]->texcache_region = + r300_assign_texture_cache_region(view_index, real_num_views); + view_index++; } } diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index b5f011b9b6f..1e5a2721651 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -554,6 +554,9 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) texstate->filter1 = sampler->filter1; texstate->border_color = sampler->border_color; + /* Assign a texture cache region. */ + texstate->format.format1 |= view->texcache_region; + /* If compare mode is disabled, the sampler view swizzles * are stored in the format. * Otherwise, swizzles must be applied after the compare mode -- cgit v1.2.3