|
@@ -52,6 +52,7 @@ struct evergreen_cs_track {
|
|
u32 cb_color_view[12];
|
|
u32 cb_color_view[12];
|
|
u32 cb_color_pitch[12];
|
|
u32 cb_color_pitch[12];
|
|
u32 cb_color_slice[12];
|
|
u32 cb_color_slice[12];
|
|
|
|
+ u32 cb_color_slice_idx[12];
|
|
u32 cb_color_attrib[12];
|
|
u32 cb_color_attrib[12];
|
|
u32 cb_color_cmask_slice[8];/* unused */
|
|
u32 cb_color_cmask_slice[8];/* unused */
|
|
u32 cb_color_fmask_slice[8];/* unused */
|
|
u32 cb_color_fmask_slice[8];/* unused */
|
|
@@ -127,12 +128,14 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track)
|
|
track->cb_color_info[i] = 0;
|
|
track->cb_color_info[i] = 0;
|
|
track->cb_color_view[i] = 0xFFFFFFFF;
|
|
track->cb_color_view[i] = 0xFFFFFFFF;
|
|
track->cb_color_pitch[i] = 0;
|
|
track->cb_color_pitch[i] = 0;
|
|
- track->cb_color_slice[i] = 0;
|
|
|
|
|
|
+ track->cb_color_slice[i] = 0xfffffff;
|
|
|
|
+ track->cb_color_slice_idx[i] = 0;
|
|
}
|
|
}
|
|
track->cb_target_mask = 0xFFFFFFFF;
|
|
track->cb_target_mask = 0xFFFFFFFF;
|
|
track->cb_shader_mask = 0xFFFFFFFF;
|
|
track->cb_shader_mask = 0xFFFFFFFF;
|
|
track->cb_dirty = true;
|
|
track->cb_dirty = true;
|
|
|
|
|
|
|
|
+ track->db_depth_slice = 0xffffffff;
|
|
track->db_depth_view = 0xFFFFC000;
|
|
track->db_depth_view = 0xFFFFC000;
|
|
track->db_depth_size = 0xFFFFFFFF;
|
|
track->db_depth_size = 0xFFFFFFFF;
|
|
track->db_depth_control = 0xFFFFFFFF;
|
|
track->db_depth_control = 0xFFFFFFFF;
|
|
@@ -250,10 +253,9 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p,
|
|
{
|
|
{
|
|
struct evergreen_cs_track *track = p->track;
|
|
struct evergreen_cs_track *track = p->track;
|
|
unsigned palign, halign, tileb, slice_pt;
|
|
unsigned palign, halign, tileb, slice_pt;
|
|
|
|
+ unsigned mtile_pr, mtile_ps, mtileb;
|
|
|
|
|
|
tileb = 64 * surf->bpe * surf->nsamples;
|
|
tileb = 64 * surf->bpe * surf->nsamples;
|
|
- palign = track->group_size / (8 * surf->bpe * surf->nsamples);
|
|
|
|
- palign = MAX(8, palign);
|
|
|
|
slice_pt = 1;
|
|
slice_pt = 1;
|
|
if (tileb > surf->tsplit) {
|
|
if (tileb > surf->tsplit) {
|
|
slice_pt = tileb / surf->tsplit;
|
|
slice_pt = tileb / surf->tsplit;
|
|
@@ -262,7 +264,10 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p,
|
|
/* macro tile width & height */
|
|
/* macro tile width & height */
|
|
palign = (8 * surf->bankw * track->npipes) * surf->mtilea;
|
|
palign = (8 * surf->bankw * track->npipes) * surf->mtilea;
|
|
halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea;
|
|
halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea;
|
|
- surf->layer_size = surf->nbx * surf->nby * surf->bpe * slice_pt;
|
|
|
|
|
|
+ mtileb = (palign / 8) * (halign / 8) * tileb;;
|
|
|
|
+ mtile_pr = surf->nbx / palign;
|
|
|
|
+ mtile_ps = (mtile_pr * surf->nby) / halign;
|
|
|
|
+ surf->layer_size = mtile_ps * mtileb * slice_pt;
|
|
surf->base_align = (palign / 8) * (halign / 8) * tileb;
|
|
surf->base_align = (palign / 8) * (halign / 8) * tileb;
|
|
surf->palign = palign;
|
|
surf->palign = palign;
|
|
surf->halign = halign;
|
|
surf->halign = halign;
|
|
@@ -434,6 +439,39 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
|
|
|
|
|
|
offset += surf.layer_size * mslice;
|
|
offset += surf.layer_size * mslice;
|
|
if (offset > radeon_bo_size(track->cb_color_bo[id])) {
|
|
if (offset > radeon_bo_size(track->cb_color_bo[id])) {
|
|
|
|
+ /* old ddx are broken they allocate bo with w*h*bpp but
|
|
|
|
+ * program slice with ALIGN(h, 8), catch this and patch
|
|
|
|
+ * command stream.
|
|
|
|
+ */
|
|
|
|
+ if (!surf.mode) {
|
|
|
|
+ volatile u32 *ib = p->ib.ptr;
|
|
|
|
+ unsigned long tmp, nby, bsize, size, min = 0;
|
|
|
|
+
|
|
|
|
+ /* find the height the ddx wants */
|
|
|
|
+ if (surf.nby > 8) {
|
|
|
|
+ min = surf.nby - 8;
|
|
|
|
+ }
|
|
|
|
+ bsize = radeon_bo_size(track->cb_color_bo[id]);
|
|
|
|
+ tmp = track->cb_color_bo_offset[id] << 8;
|
|
|
|
+ for (nby = surf.nby; nby > min; nby--) {
|
|
|
|
+ size = nby * surf.nbx * surf.bpe * surf.nsamples;
|
|
|
|
+ if ((tmp + size * mslice) <= bsize) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (nby > min) {
|
|
|
|
+ surf.nby = nby;
|
|
|
|
+ slice = ((nby * surf.nbx) / 64) - 1;
|
|
|
|
+ if (!evergreen_surface_check(p, &surf, "cb")) {
|
|
|
|
+ /* check if this one works */
|
|
|
|
+ tmp += surf.layer_size * mslice;
|
|
|
|
+ if (tmp <= bsize) {
|
|
|
|
+ ib[track->cb_color_slice_idx[id]] = slice;
|
|
|
|
+ goto old_ddx_ok;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
|
|
dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
|
|
"offset %d, max layer %d, bo size %ld, slice %d)\n",
|
|
"offset %d, max layer %d, bo size %ld, slice %d)\n",
|
|
__func__, __LINE__, id, surf.layer_size,
|
|
__func__, __LINE__, id, surf.layer_size,
|
|
@@ -446,6 +484,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
|
|
surf.tsplit, surf.mtilea);
|
|
surf.tsplit, surf.mtilea);
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
+old_ddx_ok:
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1532,6 +1571,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
|
case CB_COLOR7_SLICE:
|
|
case CB_COLOR7_SLICE:
|
|
tmp = (reg - CB_COLOR0_SLICE) / 0x3c;
|
|
tmp = (reg - CB_COLOR0_SLICE) / 0x3c;
|
|
track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
|
|
track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
|
|
|
|
+ track->cb_color_slice_idx[tmp] = idx;
|
|
track->cb_dirty = true;
|
|
track->cb_dirty = true;
|
|
break;
|
|
break;
|
|
case CB_COLOR8_SLICE:
|
|
case CB_COLOR8_SLICE:
|
|
@@ -1540,6 +1580,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
|
case CB_COLOR11_SLICE:
|
|
case CB_COLOR11_SLICE:
|
|
tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8;
|
|
tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8;
|
|
track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
|
|
track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
|
|
|
|
+ track->cb_color_slice_idx[tmp] = idx;
|
|
track->cb_dirty = true;
|
|
track->cb_dirty = true;
|
|
break;
|
|
break;
|
|
case CB_COLOR0_ATTRIB:
|
|
case CB_COLOR0_ATTRIB:
|