r600g: get tiling info from kernel
authorDave Airlie <airlied@redhat.com>
Fri, 8 Oct 2010 01:56:43 +0000 (11:56 +1000)
committerDave Airlie <airlied@redhat.com>
Sun, 17 Oct 2010 23:25:22 +0000 (09:25 +1000)
src/gallium/drivers/r600/r600.h
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/winsys/r600/drm/r600.c
src/gallium/winsys/r600/drm/r600_drm.c
src/gallium/winsys/r600/drm/r600_priv.h

index 24e25cec0db56314d24726e2c180c77cf6f43cfc..15ee0011061fa078073170916799cf8fb9870d3b 100644 (file)
@@ -99,8 +99,15 @@ enum chip_class {
        EVERGREEN,
 };
 
+struct r600_tiling_info {
+       unsigned num_channels;
+       unsigned num_banks;
+       unsigned group_bytes;
+};
+
 enum radeon_family r600_get_family(struct radeon *rw);
 enum chip_class r600_get_family_class(struct radeon *radeon);
+struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon);
 
 /* r600_bo.c */
 struct r600_bo;
index 8eb979932361dea45e6c862aa2f2a222c15338bc..dd8fa4fcd770c8c8d070a7cb96c220b97ef98268 100644 (file)
@@ -443,5 +443,7 @@ struct pipe_screen *r600_screen_create(struct radeon *radeon)
        r600_init_screen_texture_functions(&rscreen->screen);
        r600_init_screen_resource_functions(&rscreen->screen);
 
+       rscreen->tiling_info = r600_get_tiling_info(radeon);
+
        return &rscreen->screen;
 }
index 47a1b3070e9d58fe033edf1095c78d5c9195b826..35548329e469c4d6e77a3b193e8e8f8632497d63 100644 (file)
@@ -58,6 +58,7 @@ enum r600_pipe_state_id {
 struct r600_screen {
        struct pipe_screen              screen;
        struct radeon                   *radeon;
+       struct r600_tiling_info         *tiling_info;
 };
 
 struct r600_pipe_sampler_view {
index 496547ca99431ac9a1e0726007c623f3f56ce169..0a4d2e791db60eebf2179d977688a7e576a6b473 100644 (file)
@@ -40,6 +40,11 @@ enum chip_class r600_get_family_class(struct radeon *radeon)
        return radeon->chip_class;
 }
 
+struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon)
+{
+       return &radeon->tiling_info;
+}
+
 static int r600_get_device(struct radeon *r600)
 {
        struct drm_radeon_info info;
index 4916843fd6d31a1a5d7380cfe5956cde56503a58..c9de95ffc027fea1bfb1f945db79f5defa05b7d2 100644 (file)
@@ -37,6 +37,9 @@
 #include "xf86drm.h"
 #include "radeon_drm.h"
 
+#ifndef RADEON_INFO_TILING_CONFIG
+#define RADEON_INFO_TILING_CONFIG 0x6
+#endif
 static int radeon_get_device(struct radeon *radeon)
 {
        struct drm_radeon_info info;
@@ -50,6 +53,61 @@ static int radeon_get_device(struct radeon *radeon)
        return r;
 }
 
+static int radeon_drm_get_tiling(struct radeon *radeon)
+{
+       struct drm_radeon_info info;
+       int r;
+       uint32_t tiling_config;
+
+       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 r;
+
+       switch ((tiling_config & 0xe) >> 1) {
+       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;
+       }
+
+       switch ((tiling_config & 0x30) >> 4) {
+       case 0:
+               radeon->tiling_info.num_banks = 4;
+               break;
+       case 1:
+               radeon->tiling_info.num_banks = 8;
+               break;
+       default:
+               return -EINVAL;
+
+       }
+       switch ((tiling_config & 0xc0) >> 6) {
+       case 0:
+               radeon->tiling_info.group_bytes = 256;
+               break;
+       case 1:
+               radeon->tiling_info.group_bytes = 512;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
 struct radeon *radeon_new(int fd, unsigned device)
 {
        struct radeon *radeon;
@@ -157,6 +215,10 @@ 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;
+       }
        radeon->kman = radeon_bo_pbmgr_create(radeon);
        if (!radeon->kman)
                return NULL;
index e3868d3cb9a5b6840bc045345ed629daf3d8fbfb..08e243b00d077e525c1df0e737a70ce5b9c14fce 100644 (file)
@@ -42,6 +42,7 @@ struct radeon {
        enum chip_class                 chip_class;
        struct pb_manager *kman; /* kernel bo manager */
        struct pb_manager *cman; /* cached bo manager */
+       struct r600_tiling_info tiling_info;
 };
 
 struct radeon *r600_new(int fd, unsigned device);