---
 src/gallium/drivers/radeon/r600_texture.c | 84 +++++++++++++++++++++++++------
 1 file changed, 68 insertions(+), 16 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_texture.c 
b/src/gallium/drivers/radeon/r600_texture.c
index 70f21bd..c91fbce 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -457,12 +457,53 @@ void r600_texture_init_cmask(struct r600_common_screen 
*rscreen,
        }
 }
 
-static void r600_texture_allocate_htile(struct r600_common_screen *rscreen,
-                                       struct r600_texture *rtex)
+static unsigned si_texture_htile_alloc_size(struct r600_common_screen *rscreen,
+                                           struct r600_texture *rtex)
+{
+       unsigned num_pipes = rscreen->tiling_info.num_channels;
+
+       unsigned cl_width;
+       unsigned cl_height;
+       switch (num_pipes) {
+       case 2:
+               cl_width = 32;
+               cl_height = 32;
+               break;
+       case 4:
+               cl_width = 64;
+               cl_height = 32;
+               break;
+       case 8:
+               cl_width = 64;
+               cl_height = 64;
+               break;
+       case 16:
+               cl_width = 128;
+               cl_height = 64;
+               break;
+       default:
+               assert(0);
+               return 0;
+       }
+
+       unsigned width = align(rtex->surface.npix_x, cl_width * 8);
+       unsigned height = align(rtex->surface.npix_y, cl_height * 8);
+
+       unsigned slice_elements = (width * height) / (8 * 8);
+       unsigned slice_bytes = slice_elements * 4;
+
+       unsigned pipe_interleave_bytes = rscreen->tiling_info.group_bytes;
+       unsigned base_align = num_pipes * pipe_interleave_bytes;
+       unsigned size = rtex->surface.array_size * align(slice_bytes, 
base_align);
+
+       return size;
+}
+
+static unsigned r600_texture_htile_alloc_size(struct r600_common_screen 
*rscreen,
+                                             struct r600_texture *rtex)
 {
        unsigned sw = rtex->surface.level[0].nblk_x * rtex->surface.blk_w;
        unsigned sh = rtex->surface.level[0].nblk_y * rtex->surface.blk_h;
-       unsigned htile_size;
        unsigned npipes = rscreen->info.r600_num_tile_pipes;
 
        /* XXX also use it for other texture targets */
@@ -470,24 +511,39 @@ static void r600_texture_allocate_htile(struct 
r600_common_screen *rscreen,
            rtex->resource.b.b.target != PIPE_TEXTURE_2D ||
            rtex->surface.level[0].nblk_x < 32 ||
            rtex->surface.level[0].nblk_y < 32) {
-               return;
+               return 0;
        }
 
        /* this alignment and htile size only apply to linear htile buffer */
        sw = align(sw, 16 << 3);
        sh = align(sh, npipes << 3);
-       htile_size = (sw >> 3) * (sh >> 3) * 4;
+       unsigned htile_size = (sw >> 3) * (sh >> 3) * 4;
        /* must be aligned with 2K * npipes */
        htile_size = align(htile_size, (2 << 10) * npipes);
+       return htile_size;
+}
+
+static void r600_texture_allocate_htile(struct r600_common_screen *rscreen,
+                                       struct r600_texture *rtex)
+{
+       unsigned htile_size;
+       if (rscreen->chip_class >= SI) {
+               htile_size = si_texture_htile_alloc_size(rscreen, rtex);
+       } else {
+               htile_size = r600_texture_htile_alloc_size(rscreen, rtex);
+       }
+
+       if (!htile_size)
+               return;
 
        /* XXX don't allocate it separately */
-       rtex->htile_buffer = (struct 
r600_resource*)pipe_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
-                                                                      
PIPE_USAGE_STATIC, htile_size);
+       rtex->htile_buffer = (struct r600_resource*)
+                            pipe_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
+                                               PIPE_USAGE_STATIC, htile_size);
        if (rtex->htile_buffer == NULL) {
                /* this is not a fatal error as we can still keep rendering
-                * without htile buffer
-                */
-               R600_ERR("r600: failed to create bo for htile buffers\n");
+                * without htile buffer */
+               R600_ERR("Failed to create buffer object for htile buffer.\n");
        } else {
                r600_screen_clear_buffer(rscreen, &rtex->htile_buffer->b.b, 0, 
htile_size, 0);
        }
@@ -534,12 +590,8 @@ r600_texture_create_object(struct pipe_screen *screen,
                if (!(base->flags & (R600_RESOURCE_FLAG_TRANSFER |
                                     R600_RESOURCE_FLAG_FLUSHED_DEPTH)) &&
                    !(rscreen->debug_flags & DBG_NO_HYPERZ)) {
-                       if (rscreen->chip_class >= SI) {
-                               /* XXX implement Hyper-Z for SI.
-                                * Reuse the CMASK allocator, which is almost 
the same as HTILE. */
-                       } else {
-                               r600_texture_allocate_htile(rscreen, rtex);
-                       }
+
+                       r600_texture_allocate_htile(rscreen, rtex);
                }
        } else {
                if (base->nr_samples > 1) {
-- 
1.8.3.2

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to