summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/r600
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-01-29 21:25:37 +1000
committerDave Airlie <airlied@redhat.com>2011-02-01 10:36:57 +1000
commit42b5f6819881e4885ff73a17635eb7d2d341563d (patch)
tree92a8371a3e5edcd36d15ed7b4e1dde209dd87b43 /src/gallium/winsys/r600
parentd171ae086bae37279251a1d6f32e16e333cfc154 (diff)
r600g: start looking at evergreen tiling.
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.
Diffstat (limited to 'src/gallium/winsys/r600')
-rw-r--r--src/gallium/winsys/r600/drm/r600_drm.c77
1 files changed, 60 insertions, 17 deletions
diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c
index 3c7e9aa449..096c178aa3 100644
--- a/src/gallium/winsys/r600/drm/r600_drm.c
+++ b/src/gallium/winsys/r600/drm/r600_drm.c
@@ -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);