drm/radeon: allow CMASK and FMASK in the CS checker on r600-r700
MSAA is impossible without them. Signed-off-by: Marek Olšák <maraeo@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Jerome Glisse <jglisse@redhat.com>
This commit is contained in:
committed by
Alex Deucher
parent
48c0ac9911
commit
c116cc9496
@ -47,13 +47,17 @@ struct r600_cs_track {
|
||||
u32 npipes;
|
||||
/* value we track */
|
||||
u32 sq_config;
|
||||
u32 log_nsamples;
|
||||
u32 nsamples;
|
||||
u32 cb_color_base_last[8];
|
||||
struct radeon_bo *cb_color_bo[8];
|
||||
u64 cb_color_bo_mc[8];
|
||||
u32 cb_color_bo_offset[8];
|
||||
struct radeon_bo *cb_color_frag_bo[8]; /* unused */
|
||||
struct radeon_bo *cb_color_tile_bo[8]; /* unused */
|
||||
u64 cb_color_bo_offset[8];
|
||||
struct radeon_bo *cb_color_frag_bo[8];
|
||||
u64 cb_color_frag_offset[8];
|
||||
struct radeon_bo *cb_color_tile_bo[8];
|
||||
u64 cb_color_tile_offset[8];
|
||||
u32 cb_color_mask[8];
|
||||
u32 cb_color_info[8];
|
||||
u32 cb_color_view[8];
|
||||
u32 cb_color_size_idx[8]; /* unused */
|
||||
@ -349,10 +353,6 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
||||
unsigned array_mode;
|
||||
u32 format;
|
||||
|
||||
if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
|
||||
dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
|
||||
format = G_0280A0_FORMAT(track->cb_color_info[i]);
|
||||
if (!r600_fmt_is_valid_color(format)) {
|
||||
@ -441,7 +441,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
||||
* broken userspace.
|
||||
*/
|
||||
} else {
|
||||
dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n",
|
||||
dev_warn(p->dev, "%s offset[%d] %d %llu %d %lu too big (%d %d) (%d %d %d)\n",
|
||||
__func__, i, array_mode,
|
||||
track->cb_color_bo_offset[i], tmp,
|
||||
radeon_bo_size(track->cb_color_bo[i]),
|
||||
@ -458,6 +458,51 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
||||
tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) |
|
||||
S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
|
||||
ib[track->cb_color_size_idx[i]] = tmp;
|
||||
|
||||
/* FMASK/CMASK */
|
||||
switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
|
||||
case V_0280A0_TILE_DISABLE:
|
||||
break;
|
||||
case V_0280A0_FRAG_ENABLE:
|
||||
if (track->nsamples > 1) {
|
||||
uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]);
|
||||
/* the tile size is 8x8, but the size is in units of bits.
|
||||
* for bytes, do just * 8. */
|
||||
uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1);
|
||||
|
||||
if (bytes + track->cb_color_frag_offset[i] >
|
||||
radeon_bo_size(track->cb_color_frag_bo[i])) {
|
||||
dev_warn(p->dev, "%s FMASK_TILE_MAX too large "
|
||||
"(tile_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n",
|
||||
__func__, tile_max, bytes,
|
||||
track->cb_color_frag_offset[i],
|
||||
radeon_bo_size(track->cb_color_frag_bo[i]));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
case V_0280A0_CLEAR_ENABLE:
|
||||
{
|
||||
uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]);
|
||||
/* One block = 128x128 pixels, one 8x8 tile has 4 bits..
|
||||
* (128*128) / (8*8) / 2 = 128 bytes per block. */
|
||||
uint32_t bytes = (block_max + 1) * 128;
|
||||
|
||||
if (bytes + track->cb_color_tile_offset[i] >
|
||||
radeon_bo_size(track->cb_color_tile_bo[i])) {
|
||||
dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large "
|
||||
"(block_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n",
|
||||
__func__, block_max, bytes,
|
||||
track->cb_color_tile_offset[i],
|
||||
radeon_bo_size(track->cb_color_tile_bo[i]));
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dev_warn(p->dev, "%s invalid tile mode\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1231,6 +1276,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
||||
break;
|
||||
case R_028C04_PA_SC_AA_CONFIG:
|
||||
tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx));
|
||||
track->log_nsamples = tmp;
|
||||
track->nsamples = 1 << tmp;
|
||||
track->cb_dirty = true;
|
||||
break;
|
||||
@ -1312,16 +1358,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
||||
dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
ib[idx] = track->cb_color_base_last[tmp];
|
||||
track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp];
|
||||
track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp];
|
||||
ib[idx] = track->cb_color_base_last[tmp];
|
||||
} else {
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
track->cb_color_frag_bo[tmp] = reloc->robj;
|
||||
track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8;
|
||||
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
}
|
||||
if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
|
||||
track->cb_dirty = true;
|
||||
}
|
||||
break;
|
||||
case R_0280C0_CB_COLOR0_TILE:
|
||||
@ -1338,16 +1389,35 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
||||
dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
ib[idx] = track->cb_color_base_last[tmp];
|
||||
track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp];
|
||||
track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp];
|
||||
ib[idx] = track->cb_color_base_last[tmp];
|
||||
} else {
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
track->cb_color_tile_bo[tmp] = reloc->robj;
|
||||
track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8;
|
||||
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
}
|
||||
if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
|
||||
track->cb_dirty = true;
|
||||
}
|
||||
break;
|
||||
case R_028100_CB_COLOR0_MASK:
|
||||
case R_028104_CB_COLOR1_MASK:
|
||||
case R_028108_CB_COLOR2_MASK:
|
||||
case R_02810C_CB_COLOR3_MASK:
|
||||
case R_028110_CB_COLOR4_MASK:
|
||||
case R_028114_CB_COLOR5_MASK:
|
||||
case R_028118_CB_COLOR6_MASK:
|
||||
case R_02811C_CB_COLOR7_MASK:
|
||||
tmp = (reg - R_028100_CB_COLOR0_MASK) / 4;
|
||||
track->cb_color_mask[tmp] = ib[idx];
|
||||
if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
|
||||
track->cb_dirty = true;
|
||||
}
|
||||
break;
|
||||
case CB_COLOR0_BASE:
|
||||
|
Reference in New Issue
Block a user