r300g: manually assign texture cache regions
authorMarek Olšák <maraeo@gmail.com>
Sun, 20 Jun 2010 03:30:04 +0000 (05:30 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sun, 20 Jun 2010 03:30:04 +0000 (05:30 +0200)
This should fix corrupted texturing on r3xx-r4xx.

src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_reg.h
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_derived.c

index 8e9742fe82f22524f0f9e65298d344a6b7ac853b..224d5737753be35bf12292c3c4c94cca9896b396 100644 (file)
@@ -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 {
index 04eaa83f69736b12f2dbb3b0d5716a2fb9203ec1..c783998c78dc447eca73c86028a50d9625692cbf 100644 (file)
@@ -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)
index 256184aac9e95fc062cae5eb5408491f576ced0f..9c5a2a05bd4ee3d55a0df3b2dff87b2f743dce60 100644 (file)
@@ -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++;
         }
     }
 
index b5f011b9b6f79082adcf2ef4ce5b88d7b7c8d085..1e5a2721651cc847b90cc7e286f298f65794412b 100644 (file)
@@ -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