|
@@ -170,6 +170,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
|
|
struct r600_cs_track *track = p->track;
|
|
|
u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align;
|
|
|
volatile u32 *ib = p->ib->ptr;
|
|
|
+ unsigned array_mode;
|
|
|
|
|
|
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");
|
|
@@ -185,12 +186,12 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
|
|
/* pitch is the number of 8x8 tiles per row */
|
|
|
pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1;
|
|
|
slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1;
|
|
|
- height = size / (pitch * 8 * bpe);
|
|
|
+ slice_tile_max *= 64;
|
|
|
+ height = slice_tile_max / (pitch * 8);
|
|
|
if (height > 8192)
|
|
|
height = 8192;
|
|
|
- if (height > 7)
|
|
|
- height &= ~0x7;
|
|
|
- switch (G_0280A0_ARRAY_MODE(track->cb_color_info[i])) {
|
|
|
+ array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]);
|
|
|
+ switch (array_mode) {
|
|
|
case V_0280A0_ARRAY_LINEAR_GENERAL:
|
|
|
/* technically height & 0x7 */
|
|
|
break;
|
|
@@ -222,7 +223,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
|
|
break;
|
|
|
case V_0280A0_ARRAY_2D_TILED_THIN1:
|
|
|
pitch_align = max((u32)track->nbanks,
|
|
|
- (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks));
|
|
|
+ (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)) / 8;
|
|
|
if (!IS_ALIGNED(pitch, pitch_align)) {
|
|
|
dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
|
|
|
__func__, __LINE__, pitch);
|
|
@@ -243,8 +244,18 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
|
|
/* check offset */
|
|
|
tmp = height * pitch * 8 * bpe;
|
|
|
if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
|
|
|
- dev_warn(p->dev, "%s offset[%d] %d too big\n", __func__, i, track->cb_color_bo_offset[i]);
|
|
|
- return -EINVAL;
|
|
|
+ if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
|
|
|
+ /* the initial DDX does bad things with the CB size occasionally */
|
|
|
+ /* it rounds up height too far for slice tile max but the BO is smaller */
|
|
|
+ tmp = (height - 7) * 8 * bpe;
|
|
|
+ if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
|
|
|
+ dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
}
|
|
|
if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) {
|
|
|
dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]);
|
|
@@ -361,7 +372,7 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
|
|
|
break;
|
|
|
case V_028010_ARRAY_2D_TILED_THIN1:
|
|
|
pitch_align = max((u32)track->nbanks,
|
|
|
- (u32)(((track->group_size / 8) / bpe) * track->nbanks));
|
|
|
+ (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8;
|
|
|
if (!IS_ALIGNED(pitch, pitch_align)) {
|
|
|
dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
|
|
|
__func__, __LINE__, pitch);
|
|
@@ -1138,7 +1149,7 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i
|
|
|
break;
|
|
|
case V_038000_ARRAY_2D_TILED_THIN1:
|
|
|
pitch_align = max((u32)track->nbanks,
|
|
|
- (u32)(((track->group_size / 8) / bpe) * track->nbanks));
|
|
|
+ (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8;
|
|
|
if (!IS_ALIGNED(pitch, pitch_align)) {
|
|
|
dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
|
|
|
__func__, __LINE__, pitch);
|