On Wed, Oct 20, 2010 at 11:55 PM, Dave Airlie <airlied@xxxxxxxxx> wrote: > From: Dave Airlie <airlied@xxxxxxxxxx> > > The CS checker had some incorrect alignment requirements for 2D surfaces, > this made rendering to mipmap levels that were 2D broken. > > Also the CB height was being worked out from the BO size, this doesn't work > at all when rendering mipmap levels, instead we work out what height userspace > wanted from slice max and use that to check it fits inside the BO, however > the DDX send the wrong slice max for an unaligned buffer so we have to workaround > for that even though its a userspace bug. > > Signed-off-by: Dave Airlie <airlied@xxxxxxxxxx> This looks good. Signed-off-by: Alex Deucher <alexdeucher@xxxxxxxxx> > --- > drivers/gpu/drm/radeon/r600_cs.c | 29 ++++++++++++++++++++--------- > drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- > 2 files changed, 22 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c > index 820c121..8c82e43 100644 > --- a/drivers/gpu/drm/radeon/r600_cs.c > +++ b/drivers/gpu/drm/radeon/r600_cs.c > @@ -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 %d 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 %d 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); > @@ -1139,7 +1150,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); > diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c > index f29a269..f9e2286 100644 > --- a/drivers/gpu/drm/radeon/radeon_drv.c > +++ b/drivers/gpu/drm/radeon/radeon_drv.c > @@ -47,9 +47,10 @@ > * - 2.4.0 - add crtc id query > * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen > * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) > + * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change) > */ > #define KMS_DRIVER_MAJOR 2 > -#define KMS_DRIVER_MINOR 6 > +#define KMS_DRIVER_MINOR 7 > #define KMS_DRIVER_PATCHLEVEL 0 > int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); > int radeon_driver_unload_kms(struct drm_device *dev); > -- > 1.7.2.3 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel