summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/r600_pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600/r600_pipe.c')
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c123
1 files changed, 122 insertions, 1 deletions
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index a3fc61822e7..7c8480772d2 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -589,18 +589,140 @@ static boolean r600_fence_finish(struct pipe_screen *pscreen,
return TRUE;
}
+static int r600_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config)
+{
+ switch ((tiling_config & 0xe) >> 1) {
+ case 0:
+ rscreen->tiling_info.num_channels = 1;
+ break;
+ case 1:
+ rscreen->tiling_info.num_channels = 2;
+ break;
+ case 2:
+ rscreen->tiling_info.num_channels = 4;
+ break;
+ case 3:
+ rscreen->tiling_info.num_channels = 8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch ((tiling_config & 0x30) >> 4) {
+ case 0:
+ rscreen->tiling_info.num_banks = 4;
+ break;
+ case 1:
+ rscreen->tiling_info.num_banks = 8;
+ break;
+ default:
+ return -EINVAL;
+
+ }
+ switch ((tiling_config & 0xc0) >> 6) {
+ case 0:
+ rscreen->tiling_info.group_bytes = 256;
+ break;
+ case 1:
+ rscreen->tiling_info.group_bytes = 512;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int evergreen_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config)
+{
+ switch (tiling_config & 0xf) {
+ case 0:
+ rscreen->tiling_info.num_channels = 1;
+ break;
+ case 1:
+ rscreen->tiling_info.num_channels = 2;
+ break;
+ case 2:
+ rscreen->tiling_info.num_channels = 4;
+ break;
+ case 3:
+ rscreen->tiling_info.num_channels = 8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch ((tiling_config & 0xf0) >> 4) {
+ case 0:
+ rscreen->tiling_info.num_banks = 4;
+ break;
+ case 1:
+ rscreen->tiling_info.num_banks = 8;
+ break;
+ case 2:
+ rscreen->tiling_info.num_banks = 16;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch ((tiling_config & 0xf00) >> 8) {
+ case 0:
+ rscreen->tiling_info.group_bytes = 256;
+ break;
+ case 1:
+ rscreen->tiling_info.group_bytes = 512;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int r600_init_tiling(struct r600_screen *rscreen)
+{
+ uint32_t tiling_config = rscreen->info.r600_tiling_config;
+
+ /* set default group bytes, overridden by tiling info ioctl */
+ if (r600_get_family_class(rscreen->radeon) <= R700) {
+ rscreen->tiling_info.group_bytes = 256;
+ } else {
+ rscreen->tiling_info.group_bytes = 512;
+ }
+
+ if (!tiling_config)
+ return 0;
+
+ if (r600_get_family_class(rscreen->radeon) <= R700) {
+ return r600_interpret_tiling(rscreen, tiling_config);
+ } else {
+ return evergreen_interpret_tiling(rscreen, tiling_config);
+ }
+}
+
struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
{
struct r600_screen *rscreen;
struct radeon *radeon = radeon_create(ws);
+ if (!radeon) {
+ return NULL;
+ }
rscreen = CALLOC_STRUCT(r600_screen);
if (rscreen == NULL) {
+ radeon_destroy(radeon);
return NULL;
}
rscreen->ws = ws;
rscreen->radeon = radeon;
+ ws->query_info(ws, &rscreen->info);
+
+ if (r600_init_tiling(rscreen)) {
+ radeon_destroy(radeon);
+ FREE(rscreen);
+ return NULL;
+ }
+
rscreen->screen.winsys = (struct pipe_winsys*)ws;
rscreen->screen.destroy = r600_destroy_screen;
rscreen->screen.get_name = r600_get_name;
@@ -621,7 +743,6 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
rscreen->screen.fence_finish = r600_fence_finish;
r600_init_screen_resource_functions(&rscreen->screen);
- rscreen->tiling_info = r600_get_tiling_info(radeon);
util_format_s3tc_init();
util_slab_create(&rscreen->pool_buffers,