aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main/teximage.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main/teximage.c')
-rw-r--r--mesalib/src/mesa/main/teximage.c415
1 files changed, 180 insertions, 235 deletions
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index da8fbcd32..83e79a5a3 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -1209,44 +1209,22 @@ _mesa_clear_texture_image(struct gl_context *ctx,
/**
- * This is the fallback for Driver.TestProxyTexImage(). Test the texture
- * level, width, height and depth against the ctx->Const limits for textures.
- *
- * A hardware driver might override this function if, for example, the
- * max 3D texture size is 512x512x64 (i.e. not a cube).
- *
- * Note that width, height, depth == 0 is not an error. However, a
- * texture with zero width/height/depth will be considered "incomplete"
- * and texturing will effectively be disabled.
- *
- * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
- * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
- * GL_PROXY_TEXTURE_CUBE_MAP_ARB.
- * \param level as passed to glTexImage
- * \param internalFormat as passed to glTexImage
- * \param format as passed to glTexImage
- * \param type as passed to glTexImage
- * \param width as passed to glTexImage
- * \param height as passed to glTexImage
- * \param depth as passed to glTexImage
- * \param border as passed to glTexImage
- * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
+ * Check the width, height, depth and border of a texture image are legal.
+ * Used by all the glTexImage, glCompressedTexImage and glCopyTexImage
+ * functions.
+ * The target and level parameters will have already been validated.
+ * \return GL_TRUE if size is OK, GL_FALSE otherwise.
*/
GLboolean
-_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
- GLint internalFormat, GLenum format, GLenum type,
- GLint width, GLint height, GLint depth, GLint border)
+_mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
+ GLint level, GLint width, GLint height,
+ GLint depth, GLint border)
{
GLint maxSize;
- (void) internalFormat;
- (void) format;
- (void) type;
-
switch (target) {
+ case GL_TEXTURE_1D:
case GL_PROXY_TEXTURE_1D:
- if (level >= ctx->Const.MaxTextureLevels)
- return GL_FALSE;
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); /* level zero size */
maxSize >>= level; /* level size */
if (width < 2 * border || width > 2 * border + maxSize)
@@ -1257,9 +1235,8 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
}
return GL_TRUE;
+ case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
- if (level >= ctx->Const.MaxTextureLevels)
- return GL_FALSE;
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
maxSize >>= level;
if (width < 2 * border || width > 2 * border + maxSize)
@@ -1274,9 +1251,8 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
}
return GL_TRUE;
+ case GL_TEXTURE_3D:
case GL_PROXY_TEXTURE_3D:
- if (level >= ctx->Const.Max3DTextureLevels)
- return GL_FALSE;
maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
maxSize >>= level;
if (width < 2 * border || width > 2 * border + maxSize)
@@ -1295,6 +1271,7 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
}
return GL_TRUE;
+ case GL_TEXTURE_RECTANGLE_NV:
case GL_PROXY_TEXTURE_RECTANGLE_NV:
if (level != 0)
return GL_FALSE;
@@ -1305,9 +1282,13 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
return GL_FALSE;
return GL_TRUE;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
- if (level >= ctx->Const.MaxCubeTextureLevels)
- return GL_FALSE;
maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
maxSize >>= level;
if (width < 2 * border || width > 2 * border + maxSize)
@@ -1322,9 +1303,8 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
}
return GL_TRUE;
+ case GL_TEXTURE_1D_ARRAY_EXT:
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
- if (level >= ctx->Const.MaxTextureLevels)
- return GL_FALSE;
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
maxSize >>= level;
if (width < 2 * border || width > 2 * border + maxSize)
@@ -1337,9 +1317,8 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
}
return GL_TRUE;
+ case GL_TEXTURE_2D_ARRAY_EXT:
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
- if (level >= ctx->Const.MaxTextureLevels)
- return GL_FALSE;
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
maxSize >>= level;
if (width < 2 * border || width > 2 * border + maxSize)
@@ -1357,25 +1336,43 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
return GL_TRUE;
default:
- _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
+ _mesa_problem(ctx, "Invalid target in _mesa_legal_texture_dimensions()");
return GL_FALSE;
}
}
/**
- * Check if the memory used by the texture would exceed the driver's limit.
- * This lets us support a max 3D texture size of 8K (for example) but
- * prevents allocating a full 8K x 8K x 8K texture.
- * XXX this could be rolled into the proxy texture size test (above) but
- * we don't have the actual texture internal format at that point.
+ * This is the fallback for Driver.TestProxyTexImage() for doing device-
+ * specific texture image size checks.
+ *
+ * A hardware driver might override this function if, for example, the
+ * max 3D texture size is 512x512x64 (i.e. not a cube).
+ *
+ * Note that width, height, depth == 0 is not an error. However, a
+ * texture with zero width/height/depth will be considered "incomplete"
+ * and texturing will effectively be disabled.
+ *
+ * \param target any texture target/type
+ * \param level as passed to glTexImage
+ * \param format the MESA_FORMAT_x for the tex image
+ * \param width as passed to glTexImage
+ * \param height as passed to glTexImage
+ * \param depth as passed to glTexImage
+ * \param border as passed to glTexImage
+ * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
*/
-static GLboolean
-legal_texture_size(struct gl_context *ctx, gl_format format,
- GLint width, GLint height, GLint depth)
+GLboolean
+_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
+ gl_format format,
+ GLint width, GLint height, GLint depth, GLint border)
{
+ /* We just check if the image size is less than MaxTextureMbytes.
+ * Some drivers may do more specific checks.
+ */
uint64_t bytes = _mesa_format_image_size64(format, width, height, depth);
uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */
+ mbytes *= _mesa_num_tex_faces(target);
return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
}
@@ -1664,19 +1661,11 @@ get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh)
/**
- * Special value returned by error some texture error checking functions when
- * an error is detected and the proxy texture image's width/height/depth/format
- * fields should be zeroed-out.
- */
-#define PROXY_ERROR 2
-
-
-/**
* Test the glTexImage[123]D() parameters for errors.
*
* \param ctx GL context.
* \param dimensions texture image dimensions (must be 1, 2 or 3).
- * \param target texture target given by the user.
+ * \param target texture target given by the user (already validated).
* \param level image level given by the user.
* \param internalFormat internal format given by the user.
* \param format pixel data format given by the user.
@@ -1686,14 +1675,17 @@ get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh)
* \param depth image depth given by the user.
* \param border image border given by the user.
*
- * \return PROXY_ERROR if there's an error that should zero-out the proxy image,
- * GL_TRUE if a regular GL error is found, or GL_FALSE if no error,
+ * \return GL_TRUE if a error is found, GL_FALSE otherwise
*
* Verifies each of the parameters against the constants specified in
* __struct gl_contextRec::Const and the supported extensions, and according
* to the OpenGL specification.
+ * Note that we don't fully error-check the width, height, depth values
+ * here. That's done in _mesa_legal_texture_dimensions() which is used
+ * by several other GL entrypoints. Plus, texture dims have a special
+ * interaction with proxy textures.
*/
-static GLenum
+static GLboolean
texture_error_check( struct gl_context *ctx,
GLuint dimensions, GLenum target,
GLint level, GLint internalFormat,
@@ -1701,9 +1693,6 @@ texture_error_check( struct gl_context *ctx,
GLint width, GLint height,
GLint depth, GLint border )
{
- const GLenum proxyTarget = _mesa_get_proxy_target(target);
- const GLboolean isProxy = target == proxyTarget;
- GLboolean sizeOK = GL_TRUE;
GLboolean colorFormat;
GLenum err;
@@ -1720,8 +1709,8 @@ texture_error_check( struct gl_context *ctx,
* zero-out behaviour is only used in cases related to memory allocation.
*/
- /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
- if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+ /* level check */
+ if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTexImage%dD(level=%d)", dimensions, level);
return GL_TRUE;
@@ -1769,30 +1758,11 @@ texture_error_check( struct gl_context *ctx,
}
}
- /* Do this simple check before calling the TestProxyTexImage() function */
- if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
- sizeOK = (width == height);
- }
-
- /*
- * Use the proxy texture driver hook to see if the size/level/etc are
- * legal.
- */
- sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
- internalFormat, format,
- type, width, height,
- depth, border);
- if (!sizeOK) {
- if (isProxy) {
- /* No GL error is recorded, but we need to zero-out the image dims */
- return PROXY_ERROR;
- }
- else {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
- dimensions, level, width, height, depth);
- return GL_TRUE;
- }
+ if ((target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
+ _mesa_is_cube_face(target)) && width != height) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage2D(cube width != height)");
+ return GL_TRUE;
}
/* Check internalFormat */
@@ -1921,8 +1891,9 @@ texture_error_check( struct gl_context *ctx,
/**
* Error checking for glCompressedTexImage[123]D().
- * \param reason returns reason for error, if any
- * \return error code or GL_NO_ERROR or PROXY_ERROR.
+ * Note that the width, height and depth values are not fully error checked
+ * here.
+ * \return GL_TRUE if a error is found, GL_FALSE otherwise
*/
static GLenum
compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
@@ -1931,7 +1902,6 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
GLsizei height, GLsizei depth, GLint border,
GLsizei imageSize)
{
- const GLenum proxyTarget = _mesa_get_proxy_target(target);
const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
GLint expectedSize;
GLenum choose_format;
@@ -2033,13 +2003,15 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
}
/* For cube map, width must equal height */
- if (_mesa_is_cube_face(target) && width != height) {
+ if ((target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
+ _mesa_is_cube_face(target)) && width != height) {
reason = "width != height";
error = GL_INVALID_VALUE;
goto error;
}
/* check image size against compression block size */
+ /* XXX possibly move this into the _mesa_legal_texture_dimensions() func */
{
gl_format texFormat =
ctx->Driver.ChooseTextureFormat(ctx, target, proxy_format,
@@ -2060,20 +2032,6 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
}
}
- /* check image sizes */
- if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
- proxy_format, choose_format,
- choose_type,
- width, height, depth, border)) {
- /* See error comment above */
- if (target == proxyTarget) {
- return PROXY_ERROR;
- }
- reason = "invalid width, height or format";
- error = GL_INVALID_OPERATION;
- goto error;
- }
-
/* check image size in bytes */
if (expectedSize != imageSize) {
/* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...]
@@ -2091,11 +2049,11 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
goto error;
}
- return GL_NO_ERROR;
+ return GL_FALSE;
error:
_mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", dimensions, reason);
- return error;
+ return GL_TRUE;
}
@@ -2105,7 +2063,7 @@ error:
*
* \param ctx GL context.
* \param dimensions texture image dimensions (must be 1, 2 or 3).
- * \param target texture target given by the user.
+ * \param target texture target given by the user (already validated)
* \param level image level given by the user.
* \param xoffset sub-image x offset given by the user.
* \param yoffset sub-image y offset given by the user.
@@ -2131,8 +2089,8 @@ subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
{
GLenum err;
- /* Basic level check */
- if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+ /* level check */
+ if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
return GL_TRUE;
}
@@ -2306,9 +2264,6 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
GLenum target, GLint level, GLint internalFormat,
GLint width, GLint height, GLint border )
{
- const GLenum proxyTarget = _mesa_get_proxy_target(target);
- const GLenum type = GL_FLOAT;
- GLboolean sizeOK;
GLint baseFormat;
/* check target */
@@ -2318,8 +2273,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
return GL_TRUE;
}
- /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
- if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+ /* level check */
+ if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyTexImage%dD(level=%d)", dimensions, level);
return GL_TRUE;
@@ -2403,25 +2358,10 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
}
}
- /* Do size, level checking */
- sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB)
- ? (width == height) : 1;
-
- sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
- internalFormat, baseFormat,
- type, width, height,
- 1, border);
-
- if (!sizeOK) {
- if (dimensions == 1) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexImage1D(width=%d)", width);
- }
- else {
- ASSERT(dimensions == 2);
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexImage2D(width=%d, height=%d)", width, height);
- }
+ if ((target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
+ _mesa_is_cube_face(target)) && width != height) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage2D(cube width != height)");
return GL_TRUE;
}
@@ -2497,7 +2437,7 @@ copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
}
/* Check level */
- if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+ if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyTexSubImage%dD(level=%d)", dimensions, level);
return GL_TRUE;
@@ -2901,9 +2841,11 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
GLsizei imageSize, const GLvoid *pixels)
{
const char *func = compressed ? "glCompressedTexImage" : "glTexImage";
- GLenum error;
struct gl_pixelstore_attrib unpack_no_border;
const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
+ struct gl_texture_object *texObj;
+ gl_format texFormat;
+ GLboolean dimensionsOK, sizeOK;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -2937,22 +2879,23 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
/* general error checking */
if (compressed) {
- error = compressed_texture_error_check(ctx, dims, target, level,
- internalFormat,
- width, height, depth,
- border, imageSize);
+ if (compressed_texture_error_check(ctx, dims, target, level,
+ internalFormat,
+ width, height, depth,
+ border, imageSize))
+ return;
}
else {
- error = texture_error_check(ctx, dims, target, level, internalFormat,
- format, type, width, height, depth, border);
+ if (texture_error_check(ctx, dims, target, level, internalFormat,
+ format, type, width, height, depth, border))
+ return;
}
-#if FEATURE_ES
/* Here we convert a cpal compressed image into a regular glTexImage2D
* call by decompressing the texture. If we really want to support cpal
* textures in any driver this would have to be changed.
*/
- if (compressed && !error && dims == 2) {
+ if (ctx->API == API_OPENGLES && compressed && dims == 2) {
switch (internalFormat) {
case GL_PALETTE4_RGB8_OES:
case GL_PALETTE4_RGBA8_OES:
@@ -2969,50 +2912,55 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
return;
}
}
-#endif
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ assert(texObj);
+
+ texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
+ internalFormat, format, type);
+ assert(texFormat != MESA_FORMAT_NONE);
+
+ /* check that width, height, depth are legal for the mipmap level */
+ dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, level, width,
+ height, depth, border);
+
+ /* check that the texture won't take too much memory, etc */
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, _mesa_get_proxy_target(target),
+ level, texFormat,
+ width, height, depth, border);
if (_mesa_is_proxy_texture(target)) {
/* Proxy texture: just clear or set state depending on error checking */
struct gl_texture_image *texImage =
get_proxy_tex_image(ctx, target, level);
- gl_format texFormat = MESA_FORMAT_NONE;
- if (!error) {
- /* No parameter errors. Choose a texture format and see if we
- * can really allocate the texture.
- */
- struct gl_texture_object *texObj =
- _mesa_get_current_tex_object(ctx, target);
- texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
- internalFormat, format, type);
- if (!legal_texture_size(ctx, texFormat, width, height, depth)) {
- error = PROXY_ERROR;
- }
- }
+ if (!texImage)
+ return; /* GL_OUT_OF_MEMORY already recorded */
- if (error == PROXY_ERROR) {
- /* image too large, etc. Clear all proxy texture image parameters. */
- if (texImage)
- clear_teximage_fields(texImage);
- }
- else if (error == GL_FALSE) {
- /* no error: store the teximage parameters */
- if (texImage)
- _mesa_init_teximage_fields(ctx, texImage, width, height, depth,
- border, internalFormat, texFormat);
+ if (dimensionsOK && sizeOK) {
+ _mesa_init_teximage_fields(ctx, texImage, width, height, depth,
+ border, internalFormat, texFormat);
}
else {
- /* other, regular error (was already recorded) */
+ clear_teximage_fields(texImage);
}
}
else {
/* non-proxy target */
const GLuint face = _mesa_tex_target_to_face(target);
- struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- if (error) {
- return; /* error was recorded */
+ if (!dimensionsOK) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%uD(invalid width or height or depth)",
+ dims);
+ return;
+ }
+
+ if (!sizeOK) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glTexImage%uD(image too large)", dims);
+ return;
}
/* Allow a hardware driver to just strip out the border, to provide
@@ -3029,8 +2977,6 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
if (ctx->NewState & _NEW_PIXEL)
_mesa_update_state(ctx);
- texObj = _mesa_get_current_tex_object(ctx, target);
-
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
@@ -3039,38 +2985,27 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
_mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
}
else {
- gl_format texFormat;
-
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
- texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
- internalFormat, format,
- type);
-
- if (legal_texture_size(ctx, texFormat, width, height, depth)) {
- _mesa_init_teximage_fields(ctx, texImage,
- width, height, depth,
- border, internalFormat, texFormat);
-
- /* Give the texture to the driver. <pixels> may be null. */
- if (compressed) {
- ctx->Driver.CompressedTexImage(ctx, dims, texImage,
- imageSize, pixels);
- }
- else {
- ctx->Driver.TexImage(ctx, dims, texImage, format,
- type, pixels, unpack);
- }
-
- check_gen_mipmap(ctx, target, texObj, level);
-
- _mesa_update_fbo_texture(ctx, texObj, face, level);
+ _mesa_init_teximage_fields(ctx, texImage,
+ width, height, depth,
+ border, internalFormat, texFormat);
- _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
+ /* Give the texture to the driver. <pixels> may be null. */
+ if (compressed) {
+ ctx->Driver.CompressedTexImage(ctx, dims, texImage,
+ imageSize, pixels);
}
else {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
+ ctx->Driver.TexImage(ctx, dims, texImage, format,
+ type, pixels, unpack);
}
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
+
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
}
}
_mesa_unlock_texture(ctx, texObj);
@@ -3078,6 +3013,7 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
}
+
/*
* Called from the API. Note that width includes the border.
*/
@@ -3343,6 +3279,7 @@ copyteximage(struct gl_context *ctx, GLuint dims,
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
const GLuint face = _mesa_tex_target_to_face(target);
+ gl_format texFormat;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -3360,7 +3297,27 @@ copyteximage(struct gl_context *ctx, GLuint dims,
width, height, border))
return;
+ if (!_mesa_legal_texture_dimensions(ctx, target, level, width, height,
+ 1, border)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%uD(invalid width or height)", dims);
+ return;
+ }
+
texObj = _mesa_get_current_tex_object(ctx, target);
+ assert(texObj);
+
+ texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
+ internalFormat, GL_NONE, GL_NONE);
+ assert(texFormat != MESA_FORMAT_NONE);
+
+ if (!ctx->Driver.TestProxyTexImage(ctx, _mesa_get_proxy_target(target),
+ level, texFormat,
+ width, height, 1, border)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glCopyTexImage%uD(image too large)", dims);
+ return;
+ }
if (border && ctx->Const.StripTextureBorder) {
x += border;
@@ -3380,45 +3337,33 @@ copyteximage(struct gl_context *ctx, GLuint dims,
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
}
else {
- /* choose actual hw format */
- gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
- target, level,
- internalFormat,
- GL_NONE, GL_NONE);
-
- if (legal_texture_size(ctx, texFormat, width, height, 1)) {
- GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0;
+ GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0;
- /* Free old texture image */
- ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
+ /* Free old texture image */
+ ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
- _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
- border, internalFormat, texFormat);
+ _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
+ border, internalFormat, texFormat);
- /* Allocate texture memory (no pixel data yet) */
- ctx->Driver.TexImage(ctx, dims, texImage,
- GL_NONE, GL_NONE,
- NULL, &ctx->Unpack);
+ /* Allocate texture memory (no pixel data yet) */
+ ctx->Driver.TexImage(ctx, dims, texImage,
+ GL_NONE, GL_NONE,
+ NULL, &ctx->Unpack);
- if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
- &width, &height)) {
- struct gl_renderbuffer *srcRb =
- get_copy_tex_image_source(ctx, texImage->TexFormat);
+ if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
+ &width, &height)) {
+ struct gl_renderbuffer *srcRb =
+ get_copy_tex_image_source(ctx, texImage->TexFormat);
- ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ,
- srcRb, srcX, srcY, width, height);
- }
+ ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ,
+ srcRb, srcX, srcY, width, height);
+ }
- check_gen_mipmap(ctx, target, texObj, level);
+ check_gen_mipmap(ctx, target, texObj, level);
- _mesa_update_fbo_texture(ctx, texObj, face, level);
+ _mesa_update_fbo_texture(ctx, texObj, face, level);
- _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
- }
- else {
- /* probably too large of image */
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
- }
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
}
}
_mesa_unlock_texture(ctx, texObj);