aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main/teximage.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2015-03-22 13:30:59 +0100
committermarha <marha@users.sourceforge.net>2015-03-22 13:30:59 +0100
commit82c8df11062f72a7d467e26cedbbd8b322ff7a70 (patch)
tree7e7a3e408d09d3e50ff0d2f9befeb5b7ab5617a5 /mesalib/src/mesa/main/teximage.c
parent8574eba804031f6b19713f0b02952280730bf62e (diff)
downloadvcxsrv-82c8df11062f72a7d467e26cedbbd8b322ff7a70.tar.gz
vcxsrv-82c8df11062f72a7d467e26cedbbd8b322ff7a70.tar.bz2
vcxsrv-82c8df11062f72a7d467e26cedbbd8b322ff7a70.zip
randrproto fontconfig libX11 libXdmcp libxcb mesa xkbcomp xserver git update 22 Mar 2015
xserver commit 0a78b599b34cc8b5fe6fe82f90e90234e8ab7a56 libxcb commit a90be9955d2c5a635f791d44db1154633b9d3322 libX11 commit 5a499ca7b064bf7e6a4fcc169f22862dce0c60c5 libXdmcp commit 0c09444d276fbf46a0e8b427a4f6a325d0625742 xkbcomp commit fc3e6ddb2c8e922ea80f2dc5cbc1df2102e30d99 randrproto commit b1ba68df8a5fc113a387123ec2f312195e28e47f fontconfig commit 69ff6b6e260584e383c38b1b7034ddcbb23d214f mesa commit 397b491173f0d2df4deb44d21c170bf16840d507
Diffstat (limited to 'mesalib/src/mesa/main/teximage.c')
-rw-r--r--mesalib/src/mesa/main/teximage.c681
1 files changed, 447 insertions, 234 deletions
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 611d664b6..8d9d7cfc1 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -53,6 +53,7 @@
#include "mtypes.h"
#include "glformats.h"
#include "texstore.h"
+#include "pbo.h"
/**
@@ -1619,32 +1620,30 @@ error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims,
/* Check size */
if (subWidth < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "%s%dD(width=%d)", func, dims, subWidth);
+ "%s(width=%d)", func, subWidth);
return GL_TRUE;
}
if (dims > 1 && subHeight < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "%s%dD(height=%d)", func, dims, subHeight);
+ "%s(height=%d)", func, subHeight);
return GL_TRUE;
}
if (dims > 2 && subDepth < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "%s%dD(depth=%d)", func, dims, subDepth);
+ "%s(depth=%d)", func, subDepth);
return GL_TRUE;
}
/* check xoffset and width */
if (xoffset < - (GLint) destImage->Border) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(xoffset)",
- func, dims);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset)", func);
return GL_TRUE;
}
if (xoffset + subWidth > (GLint) destImage->Width) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(xoffset+width)",
- func, dims);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset+width)", func);
return GL_TRUE;
}
@@ -1652,13 +1651,11 @@ error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims,
if (dims > 1) {
GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destImage->Border;
if (yoffset < -yBorder) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(yoffset)",
- func, dims);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset)", func);
return GL_TRUE;
}
if (yoffset + subHeight > (GLint) destImage->Height) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(yoffset+height)",
- func, dims);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset+height)", func);
return GL_TRUE;
}
}
@@ -1671,7 +1668,7 @@ error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims,
0 : destImage->Border;
if (zoffset < -zBorder) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset)", func);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset)", func);
return GL_TRUE;
}
@@ -1679,7 +1676,7 @@ error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims,
if (target == GL_TEXTURE_CUBE_MAP)
depth = 6;
if (zoffset + subDepth > depth) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset+depth)", func);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset+depth)", func);
return GL_TRUE;
}
}
@@ -1697,8 +1694,8 @@ error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims,
/* offset must be multiple of block size */
if ((xoffset % bw != 0) || (yoffset % bh != 0)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "%s%dD(xoffset = %d, yoffset = %d)",
- func, dims, xoffset, yoffset);
+ "%s(xoffset = %d, yoffset = %d)",
+ func, xoffset, yoffset);
return GL_TRUE;
}
@@ -1710,14 +1707,14 @@ error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims,
if ((subWidth % bw != 0) &&
(xoffset + subWidth != (GLint) destImage->Width)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "%s%dD(width = %d)", func, dims, subWidth);
+ "%s(width = %d)", func, subWidth);
return GL_TRUE;
}
if ((subHeight % bh != 0) &&
(yoffset + subHeight != (GLint) destImage->Height)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "%s%dD(height = %d)", func, dims, subHeight);
+ "%s(height = %d)", func, subHeight);
return GL_TRUE;
}
}
@@ -2113,7 +2110,8 @@ texture_error_check( struct gl_context *ctx,
GLint level, GLint internalFormat,
GLenum format, GLenum type,
GLint width, GLint height,
- GLint depth, GLint border )
+ GLint depth, GLint border,
+ const GLvoid *pixels )
{
GLenum err;
@@ -2198,6 +2196,13 @@ texture_error_check( struct gl_context *ctx,
return GL_TRUE;
}
+ /* validate the bound PBO, if any */
+ if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack,
+ width, height, depth, format, type,
+ INT_MAX, pixels, "glTexImage")) {
+ return GL_TRUE;
+ }
+
/* make sure internal format and format basically agree */
if (!texture_formats_agree(internalFormat, format)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -2294,7 +2299,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
GLenum target, GLint level,
GLenum internalFormat, GLsizei width,
GLsizei height, GLsizei depth, GLint border,
- GLsizei imageSize)
+ GLsizei imageSize, const GLvoid *data)
{
const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
GLint expectedSize;
@@ -2322,6 +2327,13 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
return GL_TRUE;
}
+ /* validate the bound PBO, if any */
+ if (!_mesa_validate_pbo_source_compressed(ctx, dimensions, &ctx->Unpack,
+ imageSize, data,
+ "glCompressedTexImage")) {
+ return GL_TRUE;
+ }
+
switch (internalFormat) {
case GL_PALETTE4_RGB8_OES:
case GL_PALETTE4_RGBA8_OES:
@@ -2454,30 +2466,28 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
- GLenum format, GLenum type, bool dsa)
+ GLenum format, GLenum type, const GLvoid *pixels,
+ bool dsa, const char *callerName)
{
struct gl_texture_image *texImage;
GLenum err;
- const char* suffix = dsa ? "ture" : "";
if (!texObj) {
/* must be out of memory */
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sSubImage%dD()",
- suffix, dimensions);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", callerName);
return GL_TRUE;
}
/* check target (proxies not allowed) */
if (!legal_texsubimage_target(ctx, dimensions, target, dsa)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sSubImage%uD(target=%s)",
- suffix, dimensions, _mesa_lookup_enum_by_nr(target));
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%s)",
+ callerName, _mesa_lookup_enum_by_nr(target));
return GL_TRUE;
}
/* level check */
if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sSubImage%uD(level=%d)",
- suffix, dimensions, level);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level);
return GL_TRUE;
}
@@ -2489,9 +2499,8 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
err = _mesa_es_error_check_format_and_type(format, type, dimensions);
if (err != GL_NO_ERROR) {
- _mesa_error(ctx, err,
- "glTex%sSubImage%dD(format = %s, type = %s)",
- suffix, dimensions, _mesa_lookup_enum_by_nr(format),
+ _mesa_error(ctx, err, "%s(format = %s, type = %s)",
+ callerName, _mesa_lookup_enum_by_nr(format),
_mesa_lookup_enum_by_nr(type));
return GL_TRUE;
}
@@ -2500,34 +2509,37 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
err = _mesa_error_check_format_and_type(ctx, format, type);
if (err != GL_NO_ERROR) {
_mesa_error(ctx, err,
- "glTex%sSubImage%dD(incompatible format = %s, type = %s)",
- suffix, dimensions, _mesa_lookup_enum_by_nr(format),
+ "%s(incompatible format = %s, type = %s)",
+ callerName, _mesa_lookup_enum_by_nr(format),
_mesa_lookup_enum_by_nr(type));
return GL_TRUE;
}
+ /* validate the bound PBO, if any */
+ if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack,
+ width, height, depth, format, type,
+ INT_MAX, pixels, callerName)) {
+ return GL_TRUE;
+ }
+
texImage = _mesa_select_tex_image(texObj, target, level);
if (!texImage) {
/* non-existant texture level */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTex%sSubImage%dD(invalid texture image)", suffix,
- dimensions);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture image)",
+ callerName);
return GL_TRUE;
}
if (error_check_subtexture_dimensions(ctx, dimensions,
texImage, xoffset, yoffset, zoffset,
- width, height, depth,
- dsa ? "glTextureSubImage" :
- "glTexSubImage")) {
+ width, height, depth, callerName)) {
return GL_TRUE;
}
if (_mesa_is_format_compressed(texImage->TexFormat)) {
if (compressedteximage_only_format(ctx, texImage->InternalFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glTex%sSubImage%dD(no compression for format)",
- suffix, dimensions);
+ "%s(no compression for format)", callerName);
return GL_TRUE;
}
}
@@ -2537,8 +2549,7 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
if (_mesa_is_format_integer_color(texImage->TexFormat) !=
_mesa_is_enum_format_integer(format)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glTex%sSubImage%dD(integer/non-integer format mismatch)",
- suffix, dimensions);
+ "%s(integer/non-integer format mismatch)", callerName);
return GL_TRUE;
}
}
@@ -2815,10 +2826,9 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
const struct gl_texture_object *texObj,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
- GLint width, GLint height, bool dsa)
+ GLint width, GLint height, const char *caller)
{
struct gl_texture_image *texImage;
- const char *suffix = dsa ? "ture" : "";
/* Check that the source buffer is complete */
if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
@@ -2827,31 +2837,26 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
}
if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
_mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glCopyTex%sSubImage%dD(invalid readbuffer)",
- suffix, dimensions);
+ "%s(invalid readbuffer)", caller);
return GL_TRUE;
}
if (ctx->ReadBuffer->Visual.samples > 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTex%sSubImage%dD(multisample FBO)", suffix,
- dimensions);
+ "%s(multisample FBO)", caller);
return GL_TRUE;
}
}
/* Check level */
if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTex%sSubImage%dD(level=%d)", suffix,
- dimensions, level);
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", caller, level);
return GL_TRUE;
}
/* Get dest image pointers */
if (!texObj) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTex%sSubImage%dD()",
- suffix, dimensions);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", caller);
return GL_TRUE;
}
@@ -2859,37 +2864,33 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
if (!texImage) {
/* destination image does not exist */
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTex%sSubImage%dD(invalid texture image)",
- suffix, dimensions);
+ "%s(invalid texture image)", caller);
return GL_TRUE;
}
if (error_check_subtexture_dimensions(ctx, dimensions, texImage,
xoffset, yoffset, zoffset,
- width, height, 1, dsa ?
- "glCompressedTextureSubImage" :
- "glCompressedTexSubImage")) {
+ width, height, 1, caller)) {
return GL_TRUE;
}
if (_mesa_is_format_compressed(texImage->TexFormat)) {
if (compressedteximage_only_format(ctx, texImage->InternalFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTex%sSubImage%dD(no compression for format)",
- suffix, dimensions);
+ "%s(no compression for format)", caller);
return GL_TRUE;
}
}
if (texImage->InternalFormat == GL_YCBCR_MESA) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTex%sSubImage2D", suffix);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", caller);
return GL_TRUE;
}
if (!_mesa_source_buffer_exists(ctx, texImage->_BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTex%sSubImage%dD(missing readbuffer, format=0x%x)",
- suffix, dimensions, texImage->_BaseFormat);
+ "%s(missing readbuffer, format=0x%x)", caller,
+ texImage->_BaseFormat);
return GL_TRUE;
}
@@ -2907,8 +2908,7 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
if (_mesa_is_format_integer_color(rb->Format) !=
_mesa_is_format_integer_color(texImage->TexFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTex%sSubImage%dD(integer vs non-integer)",
- suffix, dimensions);
+ "%s(integer vs non-integer)", caller);
return GL_TRUE;
}
}
@@ -3218,12 +3218,13 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
if (compressed_texture_error_check(ctx, dims, target, level,
internalFormat,
width, height, depth,
- border, imageSize))
+ border, imageSize, pixels))
return;
}
else {
if (texture_error_check(ctx, dims, target, level, internalFormat,
- format, type, width, height, depth, border))
+ format, type, width, height, depth, border,
+ pixels))
return;
}
@@ -3562,7 +3563,8 @@ static void
texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const GLvoid *pixels)
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const char *callerName)
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
@@ -3573,7 +3575,8 @@ texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
if (texsubimage_error_check(ctx, dims, texObj, target, level,
xoffset, yoffset, zoffset,
- width, height, depth, format, type, false)) {
+ width, height, depth, format, type,
+ pixels, false, callerName)) {
return; /* error was detected */
}
@@ -3603,7 +3606,8 @@ texturesubimage(struct gl_context *ctx, GLuint dims,
GLuint texture, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const GLvoid *pixels)
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const char *callerName)
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
@@ -3627,7 +3631,8 @@ texturesubimage(struct gl_context *ctx, GLuint dims,
if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level,
xoffset, yoffset, zoffset,
- width, height, depth, format, type, true)) {
+ width, height, depth, format, type,
+ pixels, true, callerName)) {
return; /* error was detected */
}
@@ -3636,20 +3641,6 @@ texturesubimage(struct gl_context *ctx, GLuint dims,
if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
GLint rowStride;
- /* Error checking */
- if (texObj->NumLayers < 6) {
- /* Not enough image planes for a cube map. The spec does not say
- * what should happen in this case because the user has always
- * specified each cube face separately (using
- * GL_TEXTURE_CUBE_MAP_POSITIVE_X+i) in previous GL versions.
- * This is addressed in Khronos Bug 13223.
- */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTextureSubImage%uD(insufficient cube map storage)",
- dims);
- return;
- }
-
/*
* What do we do if the user created a texture with the following code
* and then called this function with its handle?
@@ -3691,6 +3682,8 @@ texturesubimage(struct gl_context *ctx, GLuint dims,
/* Copy in each face. */
for (i = 0; i < 6; ++i) {
texImage = texObj->Image[i][level];
+ assert(texImage);
+
_mesa_texture_sub_image(ctx, 3, texObj, texImage, texObj->Target,
level, xoffset, yoffset, zoffset,
width, height, 1, format,
@@ -3700,8 +3693,7 @@ texturesubimage(struct gl_context *ctx, GLuint dims,
}
else {
texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
- if (!texImage)
- return;
+ assert(texImage);
_mesa_texture_sub_image(ctx, dims, texObj, texImage, texObj->Target,
level, xoffset, yoffset, zoffset,
@@ -3721,7 +3713,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
texsubimage(ctx, 1, target, level,
xoffset, 0, 0,
width, 1, 1,
- format, type, pixels);
+ format, type, pixels, "glTexSubImage1D");
}
@@ -3736,7 +3728,7 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
texsubimage(ctx, 2, target, level,
xoffset, yoffset, 0,
width, height, 1,
- format, type, pixels);
+ format, type, pixels, "glTexSubImage2D");
}
@@ -3752,7 +3744,7 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
texsubimage(ctx, 3, target, level,
xoffset, yoffset, zoffset,
width, height, depth,
- format, type, pixels);
+ format, type, pixels, "glTexSubImage3D");
}
void GLAPIENTRY
@@ -3765,7 +3757,7 @@ _mesa_TextureSubImage1D(GLuint texture, GLint level,
texturesubimage(ctx, 1, texture, level,
xoffset, 0, 0,
width, 1, 1,
- format, type, pixels);
+ format, type, pixels, "glTextureSubImage1D");
}
@@ -3780,7 +3772,7 @@ _mesa_TextureSubImage2D(GLuint texture, GLint level,
texturesubimage(ctx, 2, texture, level,
xoffset, yoffset, 0,
width, height, 1,
- format, type, pixels);
+ format, type, pixels, "glTextureSubImage2D");
}
@@ -3795,7 +3787,7 @@ _mesa_TextureSubImage3D(GLuint texture, GLint level,
texturesubimage(ctx, 3, texture, level,
xoffset, yoffset, zoffset,
width, height, depth,
- format, type, pixels);
+ format, type, pixels, "glTextureSubImage3D");
}
@@ -4040,15 +4032,14 @@ _mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y,
GLsizei width, GLsizei height,
- bool dsa)
+ const char *caller)
{
struct gl_texture_image *texImage;
FLUSH_VERTICES(ctx, 0);
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glCopyTex%sSubImage%uD %s %d %d %d %d %d %d %d %d\n",
- dsa ? "ture" : "", dims,
+ _mesa_debug(ctx, "%s %s %d %d %d %d %d %d %d %d\n", caller,
_mesa_lookup_enum_by_nr(target),
level, xoffset, yoffset, zoffset, x, y, width, height);
@@ -4057,7 +4048,7 @@ _mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims,
if (copytexsubimage_error_check(ctx, dims, texObj, target, level,
xoffset, yoffset, zoffset,
- width, height, dsa)) {
+ width, height, caller)) {
return;
}
@@ -4103,14 +4094,14 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
GLint xoffset, GLint x, GLint y, GLsizei width )
{
struct gl_texture_object* texObj;
+ const char *self = "glCopyTexSubImage1D";
GET_CURRENT_CONTEXT(ctx);
/* Check target (proxies not allowed). Target must be checked prior to
* calling _mesa_get_current_tex_object.
*/
if (!legal_texsubimage_target(ctx, 1, target, false)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glCopyTexSubImage1D(invalid target %s)",
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
_mesa_lookup_enum_by_nr(target));
return;
}
@@ -4120,7 +4111,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
return;
_mesa_copy_texture_sub_image(ctx, 1, texObj, target, level, xoffset, 0, 0,
- x, y, width, 1, false);
+ x, y, width, 1, self);
}
@@ -4131,14 +4122,14 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
GLint x, GLint y, GLsizei width, GLsizei height )
{
struct gl_texture_object* texObj;
+ const char *self = "glCopyTexSubImage2D";
GET_CURRENT_CONTEXT(ctx);
/* Check target (proxies not allowed). Target must be checked prior to
* calling _mesa_get_current_tex_object.
*/
if (!legal_texsubimage_target(ctx, 2, target, false)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glCopyTexSubImage2D(invalid target %s)",
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
_mesa_lookup_enum_by_nr(target));
return;
}
@@ -4149,7 +4140,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
_mesa_copy_texture_sub_image(ctx, 2, texObj, target, level,
xoffset, yoffset, 0,
- x, y, width, height, false);
+ x, y, width, height, self);
}
@@ -4160,14 +4151,14 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
GLint x, GLint y, GLsizei width, GLsizei height )
{
struct gl_texture_object* texObj;
+ const char *self = "glCopyTexSubImage3D";
GET_CURRENT_CONTEXT(ctx);
/* Check target (proxies not allowed). Target must be checked prior to
* calling _mesa_get_current_tex_object.
*/
if (!legal_texsubimage_target(ctx, 3, target, false)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glCopyTexSubImage3D(invalid target %s)",
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
_mesa_lookup_enum_by_nr(target));
return;
}
@@ -4178,7 +4169,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
_mesa_copy_texture_sub_image(ctx, 3, texObj, target, level,
xoffset, yoffset, zoffset,
- x, y, width, height, false);
+ x, y, width, height, self);
}
void GLAPIENTRY
@@ -4186,22 +4177,22 @@ _mesa_CopyTextureSubImage1D(GLuint texture, GLint level,
GLint xoffset, GLint x, GLint y, GLsizei width)
{
struct gl_texture_object* texObj;
+ const char *self = "glCopyTextureSubImage1D";
GET_CURRENT_CONTEXT(ctx);
- texObj = _mesa_lookup_texture_err(ctx, texture, "glCopyTextureSubImage1D");
+ texObj = _mesa_lookup_texture_err(ctx, texture, self);
if (!texObj)
return;
/* Check target (proxies not allowed). */
if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glCopyTextureSubImage1D(invalid target %s)",
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
_mesa_lookup_enum_by_nr(texObj->Target));
return;
}
_mesa_copy_texture_sub_image(ctx, 1, texObj, texObj->Target, level,
- xoffset, 0, 0, x, y, width, 1, true);
+ xoffset, 0, 0, x, y, width, 1, self);
}
void GLAPIENTRY
@@ -4210,23 +4201,23 @@ _mesa_CopyTextureSubImage2D(GLuint texture, GLint level,
GLint x, GLint y, GLsizei width, GLsizei height)
{
struct gl_texture_object* texObj;
+ const char *self = "glCopyTextureSubImage2D";
GET_CURRENT_CONTEXT(ctx);
- texObj = _mesa_lookup_texture_err(ctx, texture, "glCopyTextureSubImage2D");
+ texObj = _mesa_lookup_texture_err(ctx, texture, self);
if (!texObj)
return;
/* Check target (proxies not allowed). */
if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glCopyTextureSubImage2D(invalid target %s)",
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
_mesa_lookup_enum_by_nr(texObj->Target));
return;
}
_mesa_copy_texture_sub_image(ctx, 2, texObj, texObj->Target, level,
xoffset, yoffset, 0,
- x, y, width, height, true);
+ x, y, width, height, self);
}
@@ -4237,23 +4228,31 @@ _mesa_CopyTextureSubImage3D(GLuint texture, GLint level,
GLint x, GLint y, GLsizei width, GLsizei height)
{
struct gl_texture_object* texObj;
+ const char *self = "glCopyTextureSubImage3D";
GET_CURRENT_CONTEXT(ctx);
- texObj = _mesa_lookup_texture_err(ctx, texture, "glCopyTextureSubImage3D");
+ texObj = _mesa_lookup_texture_err(ctx, texture, self);
if (!texObj)
return;
/* Check target (proxies not allowed). */
if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glCopyTextureSubImage3D(invalid target %s)",
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
_mesa_lookup_enum_by_nr(texObj->Target));
return;
}
- _mesa_copy_texture_sub_image(ctx, 3, texObj, texObj->Target, level,
- xoffset, yoffset, zoffset,
- x, y, width, height, true);
+ if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ /* Act like CopyTexSubImage2D */
+ _mesa_copy_texture_sub_image(ctx, 2, texObj,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset,
+ level, xoffset, yoffset, 0,
+ x, y, width, height, self);
+ }
+ else
+ _mesa_copy_texture_sub_image(ctx, 3, texObj, texObj->Target, level,
+ xoffset, yoffset, zoffset,
+ x, y, width, height, self);
}
static bool
@@ -4636,68 +4635,72 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, bool dsa)
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data, const char *callerName)
{
struct gl_texture_image *texImage;
GLint expectedSize;
- const char *suffix = dsa ? "ture" : "";
/* this will catch any invalid compressed format token */
if (!_mesa_is_compressed_format(ctx, format)) {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glCompressedTex%sSubImage%uD(format)", suffix, dims);
+ "%s(format)", callerName);
return GL_TRUE;
}
if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glCompressedTex%sSubImage%uD(level=%d)",
- suffix, dims, level);
+ "%s(level=%d)",
+ callerName, level);
+ return GL_TRUE;
+ }
+
+ /* validate the bound PBO, if any */
+ if (!_mesa_validate_pbo_source_compressed(ctx, dims, &ctx->Unpack,
+ imageSize, data, callerName)) {
return GL_TRUE;
}
/* Check for invalid pixel storage modes */
if (!_mesa_compressed_pixel_storage_error_check(ctx, dims,
- &ctx->Unpack,
- dsa ? "glCompressedTextureSubImage" :
- "glCompressedTexSubImage")) {
+ &ctx->Unpack, callerName)) {
return GL_TRUE;
}
expectedSize = compressed_tex_size(width, height, depth, format);
if (expectedSize != imageSize) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glCompressedTex%sSubImage%uD(size=%d)",
- suffix, dims, imageSize);
+ "%s(size=%d)",
+ callerName, imageSize);
return GL_TRUE;
}
texImage = _mesa_select_tex_image(texObj, target, level);
if (!texImage) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCompressedTex%sSubImage%uD(invalid texture image)",
- suffix, dims);
+ "%s(invalid texture image)",
+ callerName);
return GL_TRUE;
}
if ((GLint) format != texImage->InternalFormat) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCompressedTex%sSubImage%uD(format=0x%x)",
- suffix, dims, format);
+ "%s(format=0x%x)",
+ callerName, format);
return GL_TRUE;
}
if (compressedteximage_only_format(ctx, format)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCompressedTex%sSubImage%uD(format=0x%x cannot be updated)",
- suffix, dims, format);
+ "%s(format=0x%x cannot be updated)",
+ callerName, format);
return GL_TRUE;
}
if (error_check_subtexture_dimensions(ctx, dims,
texImage, xoffset, yoffset, zoffset,
width, height, depth,
- "glCompressedTexSubImage")) {
+ callerName)) {
return GL_TRUE;
}
@@ -4748,30 +4751,19 @@ _mesa_CompressedTexImage3D(GLenum target, GLint level,
void
_mesa_compressed_texture_sub_image(struct gl_context *ctx, GLuint dims,
struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint zoffset,
GLsizei width, GLsizei height,
GLsizei depth,
GLenum format, GLsizei imageSize,
- const GLvoid *data, bool dsa)
+ const GLvoid *data)
{
- struct gl_texture_image *texImage;
-
- if (compressed_subtexture_error_check(ctx, dims, texObj, target,
- level, xoffset, yoffset, zoffset,
- width, height, depth,
- format, imageSize, dsa)) {
- return;
- }
-
FLUSH_VERTICES(ctx, 0);
_mesa_lock_texture(ctx, texObj);
{
- texImage = _mesa_select_tex_image(texObj, target, level);
- assert(texImage);
-
if (width > 0 && height > 0 && depth > 0) {
ctx->Driver.CompressedTexSubImage(ctx, dims, texImage,
xoffset, yoffset, zoffset,
@@ -4795,6 +4787,8 @@ _mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset,
GLsizei imageSize, const GLvoid *data)
{
struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+
GET_CURRENT_CONTEXT(ctx);
if (compressed_subtexture_target_check(ctx, target, 1, format, false,
@@ -4806,9 +4800,20 @@ _mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset,
if (!texObj)
return;
- _mesa_compressed_texture_sub_image(ctx, 1, texObj, target, level,
+ if (compressed_subtexture_error_check(ctx, 1, texObj, target,
+ level, xoffset, 0, 0,
+ width, 1, 1,
+ format, imageSize, data,
+ "glCompressedTexSubImage1D")) {
+ return;
+ }
+
+ texImage = _mesa_select_tex_image(texObj, target, level);
+ assert(texImage);
+
+ _mesa_compressed_texture_sub_image(ctx, 1, texObj, texImage, target, level,
xoffset, 0, 0, width, 1, 1,
- format, imageSize, data, false);
+ format, imageSize, data);
}
void GLAPIENTRY
@@ -4817,6 +4822,8 @@ _mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset,
GLsizei imageSize, const GLvoid *data)
{
struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+
GET_CURRENT_CONTEXT(ctx);
texObj = _mesa_lookup_texture_err(ctx, texture,
@@ -4830,9 +4837,21 @@ _mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset,
return;
}
- _mesa_compressed_texture_sub_image(ctx, 1, texObj, texObj->Target, level,
+ if (compressed_subtexture_error_check(ctx, 1, texObj, texObj->Target,
+ level, xoffset, 0, 0,
+ width, 1, 1,
+ format, imageSize, data,
+ "glCompressedTextureSubImage1D")) {
+ return;
+ }
+
+ texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
+ assert(texImage);
+
+ _mesa_compressed_texture_sub_image(ctx, 1, texObj, texImage,
+ texObj->Target, level,
xoffset, 0, 0, width, 1, 1,
- format, imageSize, data, true);
+ format, imageSize, data);
}
@@ -4843,6 +4862,8 @@ _mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
const GLvoid *data)
{
struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+
GET_CURRENT_CONTEXT(ctx);
if (compressed_subtexture_target_check(ctx, target, 2, format, false,
@@ -4854,9 +4875,21 @@ _mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
if (!texObj)
return;
- _mesa_compressed_texture_sub_image(ctx, 2, texObj, target, level,
+ if (compressed_subtexture_error_check(ctx, 2, texObj, target,
+ level, xoffset, yoffset, 0,
+ width, height, 1,
+ format, imageSize, data,
+ "glCompressedTexSubImage2D")) {
+ return;
+ }
+
+
+ texImage = _mesa_select_tex_image(texObj, target, level);
+ assert(texImage);
+
+ _mesa_compressed_texture_sub_image(ctx, 2, texObj, texImage, target, level,
xoffset, yoffset, 0, width, height, 1,
- format, imageSize, data, false);
+ format, imageSize, data);
}
void GLAPIENTRY
@@ -4867,6 +4900,8 @@ _mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset,
const GLvoid *data)
{
struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+
GET_CURRENT_CONTEXT(ctx);
texObj = _mesa_lookup_texture_err(ctx, texture,
@@ -4880,9 +4915,21 @@ _mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset,
return;
}
- _mesa_compressed_texture_sub_image(ctx, 2, texObj, texObj->Target, level,
+ if (compressed_subtexture_error_check(ctx, 2, texObj, texObj->Target,
+ level, xoffset, yoffset, 0,
+ width, height, 1,
+ format, imageSize, data,
+ "glCompressedTextureSubImage2D")) {
+ return;
+ }
+
+ texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
+ assert(texImage);
+
+ _mesa_compressed_texture_sub_image(ctx, 2, texObj, texImage,
+ texObj->Target, level,
xoffset, yoffset, 0, width, height, 1,
- format, imageSize, data, true);
+ format, imageSize, data);
}
void GLAPIENTRY
@@ -4892,6 +4939,8 @@ _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,
GLsizei imageSize, const GLvoid *data)
{
struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+
GET_CURRENT_CONTEXT(ctx);
if (compressed_subtexture_target_check(ctx, target, 3, format, false,
@@ -4903,10 +4952,22 @@ _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,
if (!texObj)
return;
- _mesa_compressed_texture_sub_image(ctx, 3, texObj, target, level,
+ if (compressed_subtexture_error_check(ctx, 3, texObj, target,
+ level, xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, imageSize, data,
+ "glCompressedTexSubImage3D")) {
+ return;
+ }
+
+
+ texImage = _mesa_select_tex_image(texObj, target, level);
+ assert(texImage);
+
+ _mesa_compressed_texture_sub_image(ctx, 3, texObj, texImage, target, level,
xoffset, yoffset, zoffset,
width, height, depth,
- format, imageSize, data, false);
+ format, imageSize, data);
}
void GLAPIENTRY
@@ -4917,6 +4978,8 @@ _mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset,
const GLvoid *data)
{
struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+
GET_CURRENT_CONTEXT(ctx);
texObj = _mesa_lookup_texture_err(ctx, texture,
@@ -4930,10 +4993,60 @@ _mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset,
return;
}
- _mesa_compressed_texture_sub_image(ctx, 3, texObj, texObj->Target, level,
- xoffset, yoffset, zoffset,
- width, height, depth,
- format, imageSize, data, true);
+ if (compressed_subtexture_error_check(ctx, 3, texObj, texObj->Target,
+ level, xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, imageSize, data,
+ "glCompressedTextureSubImage3D")) {
+ return;
+ }
+
+ /* Must handle special case GL_TEXTURE_CUBE_MAP. */
+ if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ const char *pixels = data;
+ int i;
+ GLint image_stride;
+
+ /* Make sure the texture object is a proper cube.
+ * (See texturesubimage in teximage.c for details on why this check is
+ * performed.)
+ */
+ if (!_mesa_cube_level_complete(texObj, level)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedTextureSubImage3D(cube map incomplete)");
+ return;
+ }
+
+ /* Copy in each face. */
+ for (i = 0; i < 6; ++i) {
+ texImage = texObj->Image[i][level];
+ assert(texImage);
+
+ _mesa_compressed_texture_sub_image(ctx, 3, texObj, texImage,
+ texObj->Target, level,
+ xoffset, yoffset, zoffset,
+ width, height, 1,
+ format, imageSize, pixels);
+
+ /* Compressed images don't have a client format */
+ image_stride = _mesa_format_image_size(texImage->TexFormat,
+ texImage->Width,
+ texImage->Height, 1);
+
+ pixels += image_stride;
+ imageSize -= image_stride;
+ }
+ }
+ else {
+ texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
+ assert(texImage);
+
+ _mesa_compressed_texture_sub_image(ctx, 3, texObj, texImage,
+ texObj->Target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, imageSize, data);
+ }
}
static mesa_format
@@ -5152,24 +5265,34 @@ _mesa_validate_texbuffer_format(const struct gl_context *ctx,
void
_mesa_texture_buffer_range(struct gl_context *ctx,
- struct gl_texture_object *texObj, GLenum target,
+ struct gl_texture_object *texObj,
GLenum internalFormat,
struct gl_buffer_object *bufObj,
- GLintptr offset, GLsizeiptr size, bool range,
- bool dsa)
+ GLintptr offset, GLsizeiptr size,
+ const char *caller)
{
mesa_format format;
- FLUSH_VERTICES(ctx, 0);
+ /* NOTE: ARB_texture_buffer_object has interactions with
+ * the compatibility profile that are not implemented.
+ */
+ if (!(ctx->API == API_OPENGL_CORE &&
+ ctx->Extensions.ARB_texture_buffer_object)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(ARB_texture_buffer_object is not"
+ " implemented for the compatibility profile)", caller);
+ return;
+ }
format = _mesa_validate_texbuffer_format(ctx, internalFormat);
if (format == MESA_FORMAT_NONE) {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glTex%sBuffer%s(internalFormat 0x%x)", dsa ? "ture" : "",
- range ? "Range" : "", internalFormat);
+ "%s(internalFormat 0x%x)", caller, internalFormat);
return;
}
+ FLUSH_VERTICES(ctx, 0);
+
_mesa_lock_texture(ctx, texObj);
{
_mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj);
@@ -5188,6 +5311,75 @@ _mesa_texture_buffer_range(struct gl_context *ctx,
}
+/**
+ * Make sure the texture buffer target is GL_TEXTURE_BUFFER.
+ * Return true if it is, and return false if it is not
+ * (and throw INVALID ENUM as dictated in the OpenGL 4.5
+ * core spec, 02.02.2015, PDF page 245).
+ */
+static bool
+check_texture_buffer_target(struct gl_context *ctx, GLenum target,
+ const char *caller)
+{
+ if (target != GL_TEXTURE_BUFFER_ARB) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(texture target is not GL_TEXTURE_BUFFER)", caller);
+ return false;
+ }
+ else
+ return true;
+}
+
+/**
+ * Check for errors related to the texture buffer range.
+ * Return false if errors are found, true if none are found.
+ */
+static bool
+check_texture_buffer_range(struct gl_context *ctx,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset, GLsizeiptr size,
+ const char *caller)
+{
+ /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
+ * Textures (PDF page 245):
+ * "An INVALID_VALUE error is generated if offset is negative, if
+ * size is less than or equal to zero, or if offset + size is greater
+ * than the value of BUFFER_SIZE for the buffer bound to target."
+ */
+ if (offset < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d < 0)", caller,
+ (int) offset);
+ return false;
+ }
+
+ if (size <= 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d <= 0)", caller,
+ (int) size);
+ return false;
+ }
+
+ if (offset + size > bufObj->Size) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(offset=%d + size=%d > buffer_size=%d)", caller,
+ (int) offset, (int) size, (int) bufObj->Size);
+ return false;
+ }
+
+ /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
+ * Textures (PDF page 245):
+ * "An INVALID_VALUE error is generated if offset is not an integer
+ * multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT."
+ */
+ if (offset % ctx->Const.TextureBufferOffsetAlignment) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(invalid offset alignment)", caller);
+ return false;
+ }
+
+ return true;
+}
+
+
/** GL_ARB_texture_buffer_object */
void GLAPIENTRY
_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
@@ -5197,33 +5389,25 @@ _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
GET_CURRENT_CONTEXT(ctx);
- /* Need to catch this before it gets to _mesa_get_current_tex_object */
- if (target != GL_TEXTURE_BUFFER_ARB) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)");
- return;
- }
-
- /* NOTE: ARB_texture_buffer_object has interactions with
- * the compatibility profile that are not implemented.
+ /* Need to catch a bad target before it gets to
+ * _mesa_get_current_tex_object.
*/
- if (!(ctx->API == API_OPENGL_CORE &&
- ctx->Extensions.ARB_texture_buffer_object)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer");
+ if (!check_texture_buffer_target(ctx, target, "glTexBuffer"))
return;
- }
- bufObj = _mesa_lookup_bufferobj(ctx, buffer);
- if (!bufObj && buffer) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer(buffer %u)", buffer);
- return;
- }
+ if (buffer) {
+ bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBuffer");
+ if (!bufObj)
+ return;
+ } else
+ bufObj = NULL;
texObj = _mesa_get_current_tex_object(ctx, target);
if (!texObj)
return;
- _mesa_texture_buffer_range(ctx, texObj, target, internalFormat, bufObj, 0,
- buffer ? -1 : 0, false, false);
+ _mesa_texture_buffer_range(ctx, texObj, internalFormat, bufObj, 0,
+ buffer ? -1 : 0, "glTexBuffer");
}
@@ -5237,46 +5421,41 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
GET_CURRENT_CONTEXT(ctx);
- /* Need to catch this before it gets to _mesa_get_current_tex_object */
- if (target != GL_TEXTURE_BUFFER_ARB) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexBufferRange(target)");
- return;
- }
-
- if (!(ctx->API == API_OPENGL_CORE &&
- ctx->Extensions.ARB_texture_buffer_range)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBufferRange");
+ /* Need to catch a bad target before it gets to
+ * _mesa_get_current_tex_object.
+ */
+ if (!check_texture_buffer_target(ctx, target, "glTexBufferRange"))
return;
- }
- bufObj = _mesa_lookup_bufferobj(ctx, buffer);
- if (bufObj) {
- if (offset < 0 ||
- size <= 0 ||
- (offset + size) > bufObj->Size) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTexBufferRange");
+ if (buffer) {
+ bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBufferRange");
+ if (!bufObj)
return;
- }
- if (offset % ctx->Const.TextureBufferOffsetAlignment) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexBufferRange(invalid offset alignment)");
+
+ if (!check_texture_buffer_range(ctx, bufObj, offset, size,
+ "glTexBufferRange"))
return;
- }
- } else if (buffer) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBufferRange(buffer %u)",
- buffer);
- return;
+
} else {
+
+ /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
+ * Textures (PDF page 254):
+ * "If buffer is zero, then any buffer object attached to the buffer
+ * texture is detached, the values offset and size are ignored and
+ * the state for offset and size for the buffer texture are reset to
+ * zero."
+ */
offset = 0;
size = 0;
+ bufObj = NULL;
}
texObj = _mesa_get_current_tex_object(ctx, target);
if (!texObj)
return;
- _mesa_texture_buffer_range(ctx, texObj, target, internalFormat, bufObj,
- offset, size, true, false);
+ _mesa_texture_buffer_range(ctx, texObj, internalFormat, bufObj,
+ offset, size, "glTexBufferRange");
}
void GLAPIENTRY
@@ -5287,35 +5466,69 @@ _mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer)
GET_CURRENT_CONTEXT(ctx);
- /* NOTE: ARB_texture_buffer_object has interactions with
- * the compatibility profile that are not implemented.
- */
- if (!(ctx->API == API_OPENGL_CORE &&
- ctx->Extensions.ARB_texture_buffer_object)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureBuffer");
+ if (buffer) {
+ bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer");
+ if (!bufObj)
+ return;
+ } else
+ bufObj = NULL;
+
+ /* Get the texture object by Name. */
+ texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBuffer");
+ if (!texObj)
return;
- }
- bufObj = _mesa_lookup_bufferobj(ctx, buffer);
- if (!bufObj && buffer) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureBuffer(buffer %u)",
- buffer);
+ if (!check_texture_buffer_target(ctx, texObj->Target, "glTextureBuffer"))
return;
+
+ _mesa_texture_buffer_range(ctx, texObj, internalFormat,
+ bufObj, 0, buffer ? -1 : 0, "glTextureBuffer");
+}
+
+void GLAPIENTRY
+_mesa_TextureBufferRange(GLuint texture, GLenum internalFormat, GLuint buffer,
+ GLintptr offset, GLsizeiptr size)
+{
+ struct gl_texture_object *texObj;
+ struct gl_buffer_object *bufObj;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (buffer) {
+ bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
+ "glTextureBufferRange");
+ if (!bufObj)
+ return;
+
+ if (!check_texture_buffer_range(ctx, bufObj, offset, size,
+ "glTextureBufferRange"))
+ return;
+
+ } else {
+
+ /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
+ * Textures (PDF page 254):
+ * "If buffer is zero, then any buffer object attached to the buffer
+ * texture is detached, the values offset and size are ignored and
+ * the state for offset and size for the buffer texture are reset to
+ * zero."
+ */
+ offset = 0;
+ size = 0;
+ bufObj = NULL;
}
/* Get the texture object by Name. */
- texObj = _mesa_lookup_texture_err(ctx, texture,
- "glTextureBuffer(texture)");
+ texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBufferRange");
if (!texObj)
return;
- if (texObj->Target != GL_TEXTURE_BUFFER_ARB) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTextureBuffer(target)");
+ if (!check_texture_buffer_target(ctx, texObj->Target,
+ "glTextureBufferRange"))
return;
- }
- _mesa_texture_buffer_range(ctx, texObj, texObj->Target, internalFormat,
- bufObj, 0, buffer ? -1 : 0, false, true);
+ _mesa_texture_buffer_range(ctx, texObj, internalFormat,
+ bufObj, offset, size, "glTextureBufferRange");
}
static GLboolean