diff options
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/r600/r600.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.c | 123 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_texture.c | 18 |
4 files changed, 133 insertions, 12 deletions
diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index f24146edcf1..600fae94b79 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -84,7 +84,6 @@ struct r600_tiling_info { 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); unsigned r600_get_clock_crystal_freq(struct radeon *radeon); unsigned r600_get_minor_version(struct radeon *radeon); unsigned r600_get_num_backends(struct radeon *radeon); 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, diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index c4952214364..7c7f0424a26 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -76,7 +76,8 @@ struct r600_screen { struct pipe_screen screen; struct radeon_winsys *ws; struct radeon *radeon; - struct r600_tiling_info *tiling_info; + struct radeon_info info; + struct r600_tiling_info tiling_info; struct util_slab_mempool pool_buffers; unsigned num_contexts; diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 425e269069f..4c7c7e57414 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -93,19 +93,19 @@ static unsigned r600_get_block_alignment(struct pipe_screen *screen, switch(array_mode) { case V_038000_ARRAY_1D_TILED_THIN1: p_align = MAX2(8, - ((rscreen->tiling_info->group_bytes / 8 / pixsize))); + ((rscreen->tiling_info.group_bytes / 8 / pixsize))); break; 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)) * 8; + p_align = MAX2(rscreen->tiling_info.num_banks, + (((rscreen->tiling_info.group_bytes / 8 / pixsize)) * + rscreen->tiling_info.num_banks)) * 8; break; case V_038000_ARRAY_LINEAR_ALIGNED: - p_align = MAX2(64, rscreen->tiling_info->group_bytes / pixsize); + p_align = MAX2(64, rscreen->tiling_info.group_bytes / pixsize); break; case V_038000_ARRAY_LINEAR_GENERAL: default: - p_align = rscreen->tiling_info->group_bytes / pixsize; + p_align = rscreen->tiling_info.group_bytes / pixsize; break; } return p_align; @@ -119,7 +119,7 @@ static unsigned r600_get_height_alignment(struct pipe_screen *screen, switch (array_mode) { case V_038000_ARRAY_2D_TILED_THIN1: - h_align = rscreen->tiling_info->num_channels * 8; + h_align = rscreen->tiling_info.num_channels * 8; break; case V_038000_ARRAY_1D_TILED_THIN1: case V_038000_ARRAY_LINEAR_ALIGNED: @@ -145,14 +145,14 @@ static unsigned r600_get_base_alignment(struct pipe_screen *screen, 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, + 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: case V_038000_ARRAY_LINEAR_ALIGNED: case V_038000_ARRAY_LINEAR_GENERAL: default: - b_align = rscreen->tiling_info->group_bytes; + b_align = rscreen->tiling_info.group_bytes; break; } return b_align; |