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)
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]);
unsigned color_info;
unsigned format, swap, ntype;
unsigned offset;
+ unsigned tile_type;
const struct util_format_description *desc;
struct r600_bo *bo[3];
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,
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]);
}
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;
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;
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);