aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/main/image.c31
-rw-r--r--src/mesa/main/image.h6
-rw-r--r--src/mesa/main/teximage.c30
3 files changed, 60 insertions, 7 deletions
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index ba46cdc1b17..ae3c82b8101 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -4625,6 +4625,37 @@ _mesa_clip_readpixels(const GLcontext *ctx,
/**
+ * Do clipping for a glCopyTexSubImage call.
+ * The framebuffer source region might extend outside the framebuffer
+ * bounds. Clip the source region against the framebuffer bounds and
+ * adjust the texture/dest position and size accordingly.
+ *
+ * \return GL_FALSE if region is totally clipped, GL_TRUE otherwise.
+ */
+GLboolean
+_mesa_clip_copytexsubimage(const GLcontext *ctx,
+ GLint *destX, GLint *destY,
+ GLint *srcX, GLint *srcY,
+ GLsizei *width, GLsizei *height)
+{
+ const struct gl_framebuffer *fb = ctx->ReadBuffer;
+ const GLint srcX0 = *srcX, srcY0 = *srcY;
+
+ if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax,
+ srcX, srcY, width, height)) {
+ *destX = *destX + *srcX - srcX0;
+ *destY = *destY + *srcY - srcY0;
+
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+
+
+/**
* Clip the rectangle defined by (x, y, width, height) against the bounds
* specified by [xmin, xmax) and [ymin, ymax).
* \return GL_FALSE if rect is totally clipped, GL_TRUE otherwise.
diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h
index 2a16989fa7e..c379d5fa7d1 100644
--- a/src/mesa/main/image.h
+++ b/src/mesa/main/image.h
@@ -225,6 +225,12 @@ _mesa_clip_readpixels(const GLcontext *ctx,
struct gl_pixelstore_attrib *pack);
extern GLboolean
+_mesa_clip_copytexsubimage(const GLcontext *ctx,
+ GLint *destX, GLint *destY,
+ GLint *srcX, GLint *srcY,
+ GLsizei *width, GLsizei *height);
+
+extern GLboolean
_mesa_clip_to_region(GLint xmin, GLint ymin,
GLint xmax, GLint ymax,
GLint *x, GLint *y,
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 3420d8e2baf..09ec0d45533 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -3024,6 +3024,9 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLsizei postConvWidth = width;
+ GLint yoffset = 0;
+ GLsizei height = 1;
+
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -3053,8 +3056,13 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
/* If we have a border, xoffset=-1 is legal. Bias by border width */
xoffset += texImage->Border;
- ASSERT(ctx->Driver.CopyTexSubImage1D);
- (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width);
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage1D);
+ ctx->Driver.CopyTexSubImage1D(ctx, target, level,
+ xoffset, x, y, width);
+ }
+
ctx->NewState |= _NEW_TEXTURE;
}
out:
@@ -3099,10 +3107,14 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
/* If we have a border, xoffset=-1 is legal. Bias by border width */
xoffset += texImage->Border;
yoffset += texImage->Border;
-
- ASSERT(ctx->Driver.CopyTexSubImage2D);
- (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level,
+
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage2D);
+ ctx->Driver.CopyTexSubImage2D(ctx, target, level,
xoffset, yoffset, x, y, width, height);
+ }
+
ctx->NewState |= _NEW_TEXTURE;
}
out:
@@ -3150,10 +3162,14 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
yoffset += texImage->Border;
zoffset += texImage->Border;
- ASSERT(ctx->Driver.CopyTexSubImage3D);
- (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level,
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage3D);
+ ctx->Driver.CopyTexSubImage3D(ctx, target, level,
xoffset, yoffset, zoffset,
x, y, width, height);
+ }
+
ctx->NewState |= _NEW_TEXTURE;
}
out: