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.
This commit is contained in:
Dave Airlie 2011-01-29 21:25:37 +10:00
parent d171ae086b
commit 42b5f68198
3 changed files with 79 additions and 20 deletions

View 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]);
}

View File

@ -930,6 +930,9 @@
#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

View 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);