summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@tungstengraphics.com>2008-02-23 11:01:36 +0100
committerRoland Scheidegger <sroland@tungstengraphics.com>2008-02-23 11:01:36 +0100
commitd6098db1409e8ee45052920d3acdd3b6f2cb80aa (patch)
tree9d4c47ab59ffdb5cd84f6b32c2e45baae6ecc82b
parent20d0e539160fcbdd65ecbe188ac1ce2800af1b5c (diff)
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.
-rw-r--r--shared-core/radeon_state.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c
index 6f2e05b3..70651d7f 100644
--- a/shared-core/radeon_state.c
+++ b/shared-core/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();