r600g: fix buffer alignment
authorAlex Deucher <alexdeucher@gmail.com>
Thu, 18 Nov 2010 02:30:09 +0000 (21:30 -0500)
committerAlex Deucher <alexdeucher@gmail.com>
Thu, 18 Nov 2010 02:33:40 +0000 (21:33 -0500)
This should fix the remaining buffer alignment issues in r600g.

src/gallium/drivers/r600/r600_texture.c
src/gallium/winsys/r600/drm/r600_drm.c

index e719f7fb9836ac09b81e931fbd96b9926ae2ca7e..8ecd434a43ac87e8e9388a09de1450cded8f32b3 100644 (file)
@@ -109,11 +109,11 @@ static unsigned r600_get_pixel_alignment(struct pipe_screen *screen,
        case V_038000_ARRAY_2D_TILED_THIN1:
                p_align = MAX2(rscreen->tiling_info->num_banks,
                               (((rscreen->tiling_info->group_bytes / 8 / pixsize)) *
-                               rscreen->tiling_info->num_banks));
+                               rscreen->tiling_info->num_banks)) * 8;
                break;
-       case 0:
+       case V_038000_ARRAY_LINEAR_GENERAL:
        default:
-               p_align = 64;
+               p_align = rscreen->tiling_info->group_bytes / pixsize;
                break;
        }
        return p_align;
@@ -139,6 +139,29 @@ static unsigned r600_get_height_alignment(struct pipe_screen *screen,
        return h_align;
 }
 
+static unsigned r600_get_base_alignment(struct pipe_screen *screen,
+                                       enum pipe_format format,
+                                       unsigned array_mode)
+{
+       struct r600_screen* rscreen = (struct r600_screen *)screen;
+       unsigned pixsize = util_format_get_blocksize(format);
+       int p_align = r600_get_pixel_alignment(screen, format, array_mode);
+       int h_align = r600_get_height_alignment(screen, array_mode);
+       int b_align;
+
+       switch (array_mode) {
+       case V_038000_ARRAY_2D_TILED_THIN1:
+               b_align = MAX2(rscreen->tiling_info->num_banks * rscreen->tiling_info->num_channels * 8 * 8 * pixsize,
+                              p_align * pixsize * h_align);
+               break;
+       case V_038000_ARRAY_1D_TILED_THIN1:
+       default:
+               b_align = rscreen->tiling_info->group_bytes;
+               break;
+       }
+       return b_align;
+}
+
 static unsigned mip_minify(unsigned size, unsigned level)
 {
        unsigned val;
@@ -152,11 +175,12 @@ static unsigned r600_texture_get_stride(struct pipe_screen *screen,
                                        struct r600_resource_texture *rtex,
                                        unsigned level)
 {
+       struct r600_screen* rscreen = (struct r600_screen *)screen;
        struct pipe_resource *ptex = &rtex->resource.base.b;
        struct radeon *radeon = (struct radeon *)screen->winsys;
        enum chip_class chipc = r600_get_family_class(radeon);
        unsigned width, stride, tile_width;
-       
+
        if (rtex->pitch_override)
                return rtex->pitch_override;
 
@@ -167,11 +191,6 @@ static unsigned r600_texture_get_stride(struct pipe_screen *screen,
                width = align(width, tile_width);
        }
        stride = util_format_get_stride(ptex->format, width);
-       if (chipc == EVERGREEN)
-               stride = align(stride, 512);
-
-        if (ptex->bind & PIPE_BIND_RENDER_TARGET)
-               stride = align(stride, 512);
 
        return stride;
 }
@@ -257,6 +276,9 @@ static void r600_setup_miptree(struct pipe_screen *screen,
                }
                else
                        size = layer_size * u_minify(ptex->depth0, i);
+               /* align base image and start of miptree */
+               if ((i == 0) || (i == 1))
+                       offset = align(offset, r600_get_base_alignment(screen, ptex->format, array_mode));
                rtex->offset[i] = offset;
                rtex->layer_size[i] = layer_size;
                rtex->pitch_in_bytes[i] = pitch;
@@ -297,7 +319,10 @@ r600_texture_create_object(struct pipe_screen *screen,
        resource->size = rtex->size;
 
        if (!resource->bo) {
-               resource->bo = r600_bo(radeon, rtex->size, 4096, base->bind, base->usage);
+               struct pipe_resource *ptex = &rtex->resource.base.b;
+               int base_align = r600_get_base_alignment(screen, ptex->format, array_mode);
+
+               resource->bo = r600_bo(radeon, rtex->size, base_align, base->bind, base->usage);
                if (!resource->bo) {
                        FREE(rtex);
                        return NULL;
index 60c2f51fac03f1226e8d4acf6e4a03123f50f9ed..6742993ef3e9ae3190b45e251c132c18bb6136a9 100644 (file)
@@ -195,12 +195,16 @@ struct radeon *radeon_new(int fd, unsigned device)
        case CHIP_RS780:
        case CHIP_RS880:
                radeon->chip_class = R600;
+               /* set default group bytes, overridden by tiling info ioctl */
+               radeon->tiling_info.group_bytes = 256;
                break;
        case CHIP_RV770:
        case CHIP_RV730:
        case CHIP_RV710:
        case CHIP_RV740:
                radeon->chip_class = R700;
+               /* set default group bytes, overridden by tiling info ioctl */
+               radeon->tiling_info.group_bytes = 256;
                break;
        case CHIP_CEDAR:
        case CHIP_REDWOOD:
@@ -208,6 +212,8 @@ struct radeon *radeon_new(int fd, unsigned device)
        case CHIP_CYPRESS:
        case CHIP_HEMLOCK:
                radeon->chip_class = EVERGREEN;
+               /* set default group bytes, overridden by tiling info ioctl */
+               radeon->tiling_info.group_bytes = 512;
                break;
        default:
                fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",