r600g: start looking at evergreen tiling.
authorDave Airlie <airlied@redhat.com>
Sat, 29 Jan 2011 11:25:37 +0000 (21:25 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 1 Feb 2011 00:36:57 +0000 (10:36 +1000)
this just adds the ioctl interface and sets the tile type
and array mode in the correct place.

This seems to bring eg 1D tiling to the same level, and issues
as on r600. No idea how to address 2D yet.

src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/evergreend.h
src/gallium/winsys/r600/drm/r600_drm.c

index 5a923db3dfb413fc0dcd9b82423e7c87d4ef20e5..8c4f0f9aad6267ce36fcfa8d51c487b0d0833bd8 100644 (file)
@@ -351,7 +351,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
        struct r600_resource *rbuffer;
        unsigned format;
        uint32_t word4 = 0, yuv_format = 0, pitch = 0;
-       unsigned char swizzle[4];
+       unsigned char swizzle[4], array_mode = 0, tile_type = 0;
        struct r600_bo *bo[2];
 
        if (resource == NULL)
@@ -390,15 +390,21 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
        bo[1] = rbuffer->bo;
 
        pitch = align(tmp->pitch_in_pixels[0], 8);
+       if (tmp->tiled) {
+               array_mode = tmp->array_mode[0];
+               tile_type = tmp->tile_type;
+       }
 
        /* FIXME properly handle first level != 0 */
        r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0,
                                S_030000_DIM(r600_tex_dim(texture->target)) |
                                S_030000_PITCH((pitch / 8) - 1) |
+                               S_030000_NON_DISP_TILING_ORDER(tile_type) |
                                S_030000_TEX_WIDTH(texture->width0 - 1), 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1,
                                S_030004_TEX_HEIGHT(texture->height0 - 1) |
-                               S_030004_TEX_DEPTH(texture->depth0 - 1),
+                               S_030004_TEX_DEPTH(texture->depth0 - 1) |
+                               S_030004_ARRAY_MODE(array_mode),
                                0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2,
                                (tmp->offset[0] + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]);
@@ -635,6 +641,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
        unsigned color_info;
        unsigned format, swap, ntype;
        unsigned offset;
+       unsigned tile_type;
        const struct util_format_description *desc;
        struct r600_bo *bo[3];
 
@@ -659,11 +666,17 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
        swap = r600_translate_colorswap(rtex->resource.base.b.format);
        color_info = S_028C70_FORMAT(format) |
                S_028C70_COMP_SWAP(swap) |
+               S_028C70_ARRAY_MODE(rtex->array_mode[level]) |
                S_028C70_BLEND_CLAMP(1) |
                S_028C70_NUMBER_TYPE(ntype);
        if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
                color_info |= S_028C70_SOURCE_FORMAT(1);
 
+       if (rtex->tiled) {
+               tile_type = rtex->tile_type;
+       } else /* workaround for linear buffers */
+               tile_type = 1;
+
        /* FIXME handle enabling of CB beyond BASE8 which has different offset */
        r600_pipe_state_add_reg(rstate,
                                R_028C60_CB_COLOR0_BASE + cb * 0x3C,
@@ -687,7 +700,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
                                0x00000000, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate,
                                R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C,
-                               S_028C74_NON_DISP_TILING_ORDER(1),
+                               S_028C74_NON_DISP_TILING_ORDER(tile_type),
                                0xFFFFFFFF, bo[0]);
 }
 
index f7f0085b6a7ca4e37c4be5fc972c391c603840bf..dec32b504ee7212f970bc4991bc5bc6ee274d39f 100644 (file)
 #define     V_030000_SQ_TEX_DIM_2D_ARRAY               0x00000005
 #define     V_030000_SQ_TEX_DIM_2D_MSAA                0x00000006
 #define     V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA          0x00000007
+#define   S_030000_NON_DISP_TILING_ORDER(x)            (((x) & 0x1) << 5)
+#define   G_030000_NON_DISP_TILING_ORDER(x)            (((x) >> 5) & 0x1)
+#define   C_030000_NON_DISP_TILING_ORDER               0xFFFFFFDF
 #define   S_030000_PITCH(x)                            (((x) & 0xFFF) << 6)
 #define   G_030000_PITCH(x)                            (((x) >> 6) & 0xFFF)
 #define   C_030000_PITCH                               0xFFFC003F
index 3c7e9aa4490d1381de617fb2e49fcdbf14a25377..096c178aa382f0d05f07b77b1a1d11136566cf7d 100644 (file)
@@ -78,20 +78,8 @@ static int radeon_get_device(struct radeon *radeon)
        return r;
 }
 
-static int radeon_drm_get_tiling(struct radeon *radeon)
+static int r600_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
 {
-       struct drm_radeon_info info;
-       int r;
-       uint32_t tiling_config = 0;
-
-       info.request = RADEON_INFO_TILING_CONFIG;
-       info.value = (uintptr_t)&tiling_config;
-       r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
-                               sizeof(struct drm_radeon_info));
-
-       if (r)
-               return 0;
-
        switch ((tiling_config & 0xe) >> 1) {
        case 0:
                radeon->tiling_info.num_channels = 1;
@@ -133,6 +121,62 @@ static int radeon_drm_get_tiling(struct radeon *radeon)
        return 0;
 }
 
+static int eg_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
+{
+       switch (tiling_config & 0xf) {
+       case 0:
+               radeon->tiling_info.num_channels = 1;
+               break;
+       case 1:
+               radeon->tiling_info.num_channels = 2;
+               break;
+       case 2:
+               radeon->tiling_info.num_channels = 4;
+               break;
+       case 3:
+               radeon->tiling_info.num_channels = 8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       radeon->tiling_info.num_banks = (tiling_config & 0xf0) >> 4;
+
+       switch ((tiling_config & 0xf00) >> 8) {
+       case 0:
+               radeon->tiling_info.group_bytes = 256;
+               break;
+       case 1:
+               radeon->tiling_info.group_bytes = 512;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int radeon_drm_get_tiling(struct radeon *radeon)
+{
+       struct drm_radeon_info info;
+       int r;
+       uint32_t tiling_config = 0;
+
+       info.request = RADEON_INFO_TILING_CONFIG;
+       info.value = (uintptr_t)&tiling_config;
+       r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
+                               sizeof(struct drm_radeon_info));
+
+       if (r)
+               return 0;
+
+       if (radeon->chip_class == R600 || radeon->chip_class == R700) {
+               r = r600_interpret_tiling(radeon, tiling_config);
+       } else {
+               r = eg_interpret_tiling(radeon, tiling_config);
+       }
+       return r;
+}
+
 static int radeon_get_clock_crystal_freq(struct radeon *radeon)
 {
        struct drm_radeon_info info;
@@ -228,10 +272,9 @@ static struct radeon *radeon_new(int fd, unsigned device)
                break;
        }
 
-       if (radeon->chip_class == R600 || radeon->chip_class == R700) {
-               if (radeon_drm_get_tiling(radeon))
-                       return NULL;
-       }
+       if (radeon_drm_get_tiling(radeon))
+               return NULL;
+
        /* get the GPU counter frequency, failure is non fatal */
        radeon_get_clock_crystal_freq(radeon);