summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@tungstengraphics.com>2008-06-19 11:36:04 +1000
committerDave Airlie <airlied@redhat.com>2008-06-19 11:36:04 +1000
commit9156cf09f56150ed89f77eaa4c386a07789776a0 (patch)
tree39088281aa78ab6e3188dcd789e35ff726a056c0 /drivers/char
parentc0beb2a723d69934a53f51a9d664c5b1dbbf634b (diff)
drm/radeon: fix texture uploads with large 3d textures (bug 13980)
Texture uploads could hit the blitter coordinate limit, adjust the texture offset when uploading the pieces. Make sure to check the end address of the upload too. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/drm/radeon_state.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index eee13571240..11c146b4921 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -1662,7 +1662,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
u32 height;
int i;
u32 texpitch, microtile;
- u32 offset;
+ u32 offset, byte_offset;
RING_LOCALS;
if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) {
@@ -1727,6 +1727,13 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
} else
microtile = 0;
+ /* this might fail for zero-sized uploads - are those illegal? */
+ if (!radeon_check_offset(dev_priv, tex->offset + image->height *
+ blit_width - 1)) {
+ DRM_ERROR("Invalid final destination offset\n");
+ return -EINVAL;
+ }
+
DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width);
do {
@@ -1840,6 +1847,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
}
#undef RADEON_COPY_MT
+ byte_offset = (image->y & ~2047) * blit_width;
buf->file_priv = file_priv;
buf->used = size;
offset = dev_priv->gart_buffers_offset + buf->offset;
@@ -1854,9 +1862,9 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
RADEON_DP_SRC_SOURCE_MEMORY |
RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
OUT_RING((spitch << 22) | (offset >> 10));
- OUT_RING((texpitch << 22) | (tex->offset >> 10));
+ OUT_RING((texpitch << 22) | ((tex->offset >> 10) + (byte_offset >> 10)));
OUT_RING(0);
- OUT_RING((image->x << 16) | image->y);
+ OUT_RING((image->x << 16) | (image->y % 2048));
OUT_RING((image->width << 16) | height);
RADEON_WAIT_UNTIL_2D_IDLE();
ADVANCE_RING();