/**
* Helper function to determine if a texture object is mutable (in terms
- * of GL_ARB_texture_storage).
+ * of GL_ARB_texture_storage/GL_ARB_bindless_texture).
*/
static GLboolean
mutable_tex_object(struct gl_context *ctx, GLenum target)
if (!texObj)
return GL_FALSE;
+ if (texObj->HandleAllocated) {
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*,
+ * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other
+ * functions defined in terms of these, if the texture object to be
+ * modified is referenced by one or more texture or image handles."
+ */
+ return GL_FALSE;
+ }
+
return !texObj->Immutable;
}
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, const char *caller)
{
+ assert(texObj);
+
struct gl_texture_image *texImage;
/* Check that the source buffer is complete */
return GL_TRUE;
}
- /* Get dest image pointers */
- if (!texObj) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", caller);
- return GL_TRUE;
- }
-
texImage = _mesa_select_tex_image(texObj, target, level);
if (!texImage) {
/* destination image does not exist */
* \param type the user's image type (only used if !compressed)
* \param imageSize only used for glCompressedTexImage1D/2D/3D calls.
*/
-static void
+static ALWAYS_INLINE void
teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type,
- GLsizei imageSize, const GLvoid *pixels)
+ GLsizei imageSize, const GLvoid *pixels, bool no_error)
{
const char *func = compressed ? "glCompressedTexImage" : "glTexImage";
struct gl_pixelstore_attrib unpack_no_border;
const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
struct gl_texture_object *texObj;
mesa_format texFormat;
- GLboolean dimensionsOK, sizeOK;
+ bool dimensionsOK = true, sizeOK = true;
FLUSH_VERTICES(ctx, 0);
internalFormat = override_internal_format(internalFormat, width, height);
- /* target error checking */
- if (!legal_teximage_target(ctx, dims, target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)",
- func, dims, _mesa_enum_to_string(target));
- return;
- }
-
- /* general error checking */
- if (compressed) {
- if (compressed_texture_error_check(ctx, dims, target, level,
- internalFormat,
- width, height, depth,
- border, imageSize, pixels))
- return;
- }
- else {
- if (texture_error_check(ctx, dims, target, level, internalFormat,
- format, type, width, height, depth, border,
- pixels))
+ if (!no_error) {
+ /* target error checking */
+ if (!legal_teximage_target(ctx, dims, target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)",
+ func, dims, _mesa_enum_to_string(target));
return;
+ }
+
+ /* general error checking */
+ if (compressed) {
+ if (compressed_texture_error_check(ctx, dims, target, level,
+ internalFormat,
+ width, height, depth,
+ border, imageSize, pixels))
+ return;
+ } else {
+ if (texture_error_check(ctx, dims, target, level, internalFormat,
+ format, type, width, height, depth, border,
+ pixels))
+ return;
+ }
}
/* Here we convert a cpal compressed image into a regular glTexImage2D
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);
+ if (!no_error) {
+ /* 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, proxy_target(target),
- 0, level, texFormat, 1,
- width, height, depth);
+ /* check that the texture won't take too much memory, etc */
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, proxy_target(target),
+ 0, level, texFormat, 1,
+ width, height, depth);
+ }
if (_mesa_is_proxy_texture(target)) {
/* Proxy texture: just clear or set state depending on error checking */
}
}
+/* This is a wrapper around teximage() so that we can force the KHR_no_error
+ * logic to be inlined without inlining the function into all the callers.
+ */
+static void
+teximage_err(struct gl_context *ctx, GLboolean compressed, GLuint dims,
+ GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ GLsizei imageSize, const GLvoid *pixels)
+{
+ teximage(ctx, compressed, dims, target, level, internalFormat, width, height,
+ depth, border, format, type, imageSize, pixels, false);
+}
+
+
+static void
+teximage_no_error(struct gl_context *ctx, GLboolean compressed, GLuint dims,
+ GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ GLsizei imageSize, const GLvoid *pixels)
+{
+ teximage(ctx, compressed, dims, target, level, internalFormat, width, height,
+ depth, border, format, type, imageSize, pixels, true);
+}
/*
GLenum type, const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- teximage(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1,
- border, format, type, 0, pixels);
+ teximage_err(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1,
+ border, format, type, 0, pixels);
}
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- teximage(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1,
- border, format, type, 0, pixels);
+ teximage_err(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1,
+ border, format, type, 0, pixels);
}
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- teximage(ctx, GL_FALSE, 3, target, level, internalFormat,
- width, height, depth,
- border, format, type, 0, pixels);
+ teximage_err(ctx, GL_FALSE, 3, target, level, internalFormat,
+ width, height, depth, border, format, type, 0, pixels);
}
}
+void GLAPIENTRY
+_mesa_TexImage1D_no_error(GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLint border, GLenum format,
+ GLenum type, const GLvoid *pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ teximage_no_error(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1,
+ 1, border, format, type, 0, pixels);
+}
+
+
+void GLAPIENTRY
+_mesa_TexImage2D_no_error(GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ teximage_no_error(ctx, GL_FALSE, 2, target, level, internalFormat, width,
+ height, 1, border, format, type, 0, pixels);
+}
+
+
+void GLAPIENTRY
+_mesa_TexImage3D_no_error(GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ teximage_no_error(ctx, GL_FALSE, 3, target, level, internalFormat,
+ width, height, depth, border, format, type, 0, pixels);
+}
+
+
void GLAPIENTRY
_mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
{
* Helper that implements the glTexSubImage1/2/3D()
* and glTextureSubImage1/2/3D() functions.
*/
-void
-_mesa_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, GLenum type, const GLvoid *pixels,
- bool dsa)
+static void
+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, GLenum type, const GLvoid *pixels,
+ bool dsa)
{
FLUSH_VERTICES(ctx, 0);
check_gen_mipmap(ctx, target, texObj, level);
- /* NOTE: Don't signal _NEW_TEXTURE since we've only changed
+ /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed
* the texel data, not the texture format, size, etc.
*/
}
* Must split this out this way because of GL_TEXTURE_CUBE_MAP.
*/
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,
- const char *callerName)
+texsubimage_err(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,
+ const char *callerName)
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
_mesa_enum_to_string(format),
_mesa_enum_to_string(type), pixels);
- _mesa_texture_sub_image(ctx, dims, texObj, texImage, target, level,
- xoffset, yoffset, zoffset, width, height, depth,
- format, type, pixels, false);
+ texture_sub_image(ctx, dims, texObj, texImage, target, level,
+ xoffset, yoffset, zoffset, width, height, depth,
+ format, type, pixels, false);
+}
+
+
+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)
+{
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ texImage = _mesa_select_tex_image(texObj, target, level);
+
+ texture_sub_image(ctx, dims, texObj, texImage, target, level,
+ xoffset, yoffset, zoffset, width, height, depth,
+ format, type, pixels, false);
}
_mesa_enum_to_string(type), pixels);
/* Get the texture object by Name. */
- texObj = _mesa_lookup_texture(ctx, texture);
- if (!texObj) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureSubImage%uD(texture)",
- dims);
+ texObj = _mesa_lookup_texture_err(ctx, texture, callerName);
+ if (!texObj)
return;
- }
/* check target (proxies not allowed) */
if (!legal_texsubimage_target(ctx, dims, texObj->Target, true)) {
texImage = texObj->Image[i][level];
assert(texImage);
- _mesa_texture_sub_image(ctx, 3, texObj, texImage, texObj->Target,
- level, xoffset, yoffset, 0,
- width, height, 1, format,
- type, pixels, true);
+ texture_sub_image(ctx, 3, texObj, texImage, texObj->Target,
+ level, xoffset, yoffset, 0,
+ width, height, 1, format,
+ type, pixels, true);
pixels = (GLubyte *) pixels + imageStride;
}
}
texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
assert(texImage);
- _mesa_texture_sub_image(ctx, dims, texObj, texImage, texObj->Target,
- level, xoffset, yoffset, zoffset,
- width, height, depth, format,
- type, pixels, true);
+ texture_sub_image(ctx, dims, texObj, texImage, texObj->Target,
+ level, xoffset, yoffset, zoffset,
+ width, height, depth, format,
+ type, pixels, true);
}
}
+void GLAPIENTRY
+_mesa_TexSubImage1D_no_error(GLenum target, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ texsubimage(ctx, 1, target, level,
+ xoffset, 0, 0,
+ width, 1, 1,
+ format, type, pixels);
+}
+
+
void GLAPIENTRY
_mesa_TexSubImage1D( GLenum target, GLint level,
GLint xoffset, GLsizei width,
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- texsubimage(ctx, 1, target, level,
- xoffset, 0, 0,
- width, 1, 1,
- format, type, pixels, "glTexSubImage1D");
+ texsubimage_err(ctx, 1, target, level,
+ xoffset, 0, 0,
+ width, 1, 1,
+ format, type, pixels, "glTexSubImage1D");
+}
+
+
+void GLAPIENTRY
+_mesa_TexSubImage2D_no_error(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ texsubimage(ctx, 2, target, level,
+ xoffset, yoffset, 0,
+ width, height, 1,
+ format, type, pixels);
}
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- texsubimage(ctx, 2, target, level,
- xoffset, yoffset, 0,
- width, height, 1,
- format, type, pixels, "glTexSubImage2D");
+ texsubimage_err(ctx, 2, target, level,
+ xoffset, yoffset, 0,
+ width, height, 1,
+ format, type, pixels, "glTexSubImage2D");
}
+void GLAPIENTRY
+_mesa_TexSubImage3D_no_error(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ const GLvoid *pixels)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ texsubimage(ctx, 3, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, pixels);
+}
+
void GLAPIENTRY
_mesa_TexSubImage3D( GLenum target, GLint level,
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- texsubimage(ctx, 3, target, level,
- xoffset, yoffset, zoffset,
- width, height, depth,
- format, type, pixels, "glTexSubImage3D");
+ texsubimage_err(ctx, 3, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, pixels, "glTexSubImage3D");
}
void GLAPIENTRY
return true;
}
+
/**
- * Implement the glCopyTexImage1/2D() functions.
+ * Implementation for glCopyTex(ture)SubImage1/2/3D() functions.
*/
static void
+copy_texture_sub_image(struct gl_context *ctx, GLuint dims,
+ struct gl_texture_object *texObj,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ struct gl_texture_image *texImage;
+
+ _mesa_lock_texture(ctx, texObj);
+
+ texImage = _mesa_select_tex_image(texObj, target, level);
+
+ /* If we have a border, offset=-1 is legal. Bias by border width. */
+ switch (dims) {
+ case 3:
+ if (target != GL_TEXTURE_2D_ARRAY)
+ zoffset += texImage->Border;
+ /* fall-through */
+ case 2:
+ if (target != GL_TEXTURE_1D_ARRAY)
+ yoffset += texImage->Border;
+ /* fall-through */
+ case 1:
+ xoffset += texImage->Border;
+ }
+
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ struct gl_renderbuffer *srcRb =
+ get_copy_tex_image_source(ctx, texImage->TexFormat);
+
+ copytexsubimage_by_slice(ctx, texImage, dims, xoffset, yoffset, zoffset,
+ srcRb, x, y, width, height);
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed
+ * the texel data, not the texture format, size, etc.
+ */
+ }
+
+ _mesa_unlock_texture(ctx, texObj);
+}
+
+
+static void
+copy_texture_sub_image_err(struct gl_context *ctx, GLuint dims,
+ struct gl_texture_object *texObj,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ const char *caller)
+{
+ FLUSH_VERTICES(ctx, 0);
+
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "%s %s %d %d %d %d %d %d %d %d\n", caller,
+ _mesa_enum_to_string(target),
+ level, xoffset, yoffset, zoffset, x, y, width, height);
+
+ if (ctx->NewState & NEW_COPY_TEX_STATE)
+ _mesa_update_state(ctx);
+
+ if (copytexsubimage_error_check(ctx, dims, texObj, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, caller)) {
+ return;
+ }
+
+ copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset,
+ zoffset, x, y, width, height);
+}
+
+
+static void
+copy_texture_sub_image_no_error(struct gl_context *ctx, GLuint dims,
+ struct gl_texture_object *texObj,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ FLUSH_VERTICES(ctx, 0);
+
+ if (ctx->NewState & NEW_COPY_TEX_STATE)
+ _mesa_update_state(ctx);
+
+ copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset,
+ zoffset, x, y, width, height);
+}
+
+
+/**
+ * Implement the glCopyTexImage1/2D() functions.
+ */
+static ALWAYS_INLINE void
copyteximage(struct gl_context *ctx, GLuint dims,
GLenum target, GLint level, GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
+ GLint x, GLint y, GLsizei width, GLsizei height, GLint border,
+ bool no_error)
{
- struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- const GLuint face = _mesa_tex_target_to_face(target);
+ struct gl_texture_object *texObj;
mesa_format texFormat;
- struct gl_renderbuffer *rb;
FLUSH_VERTICES(ctx, 0);
if (ctx->NewState & NEW_COPY_TEX_STATE)
_mesa_update_state(ctx);
- if (copytexture_error_check(ctx, dims, target, level, internalFormat,
- width, height, border))
- return;
+ if (!no_error) {
+ if (copytexture_error_check(ctx, dims, target, level, internalFormat,
+ 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;
+ 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);
if (texImage && can_avoid_reallocation(texImage, internalFormat, texFormat,
x, y, width, height, border)) {
_mesa_unlock_texture(ctx, texObj);
- _mesa_copy_texture_sub_image(ctx, dims, texObj, target, level,
- 0, 0, 0, x, y, width, height,
- "CopyTexImage");
+ if (no_error) {
+ copy_texture_sub_image_no_error(ctx, dims, texObj, target, level, 0,
+ 0, 0, x, y, width, height);
+ } else {
+ copy_texture_sub_image_err(ctx, dims, texObj, target, level, 0, 0,
+ 0, x, y, width, height,"CopyTexImage");
+ }
return;
}
}
_mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_LOW, "glCopyTexImage "
"can't avoid reallocating texture storage\n");
- rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
+ if (!no_error && _mesa_is_gles3(ctx)) {
+ struct gl_renderbuffer *rb =
+ _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
- if (_mesa_is_gles3(ctx)) {
if (_mesa_is_enum_format_unsized(internalFormat)) {
/* Conversion from GL_RGB10_A2 source buffer format is not allowed in
* OpenGL ES 3.0. Khronos bug# 9807.
}
else {
GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0;
+ const GLuint face = _mesa_tex_target_to_face(target);
/* Free old texture image */
ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
}
+static void
+copyteximage_err(struct gl_context *ctx, GLuint dims, GLenum target,
+ GLint level, GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border)
+{
+ copyteximage(ctx, dims, target, level, internalFormat, x, y, width, height,
+ border, false);
+}
+
+static void
+copyteximage_no_error(struct gl_context *ctx, GLuint dims, GLenum target,
+ GLint level, GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border)
+{
+ copyteximage(ctx, dims, target, level, internalFormat, x, y, width, height,
+ border, true);
+}
+
void GLAPIENTRY
_mesa_CopyTexImage1D( GLenum target, GLint level,
GLsizei width, GLint border )
{
GET_CURRENT_CONTEXT(ctx);
- copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border);
+ copyteximage_err(ctx, 1, target, level, internalFormat, x, y, width, 1,
+ border);
}
GLint border )
{
GET_CURRENT_CONTEXT(ctx);
- copyteximage(ctx, 2, target, level, internalFormat,
- x, y, width, height, border);
+ copyteximage_err(ctx, 2, target, level, internalFormat,
+ x, y, width, height, border);
}
-/**
- * Implementation for glCopyTex(ture)SubImage1/2/3D() functions.
- */
-void
-_mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims,
- struct gl_texture_object *texObj,
- GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- const char *caller)
+
+void GLAPIENTRY
+_mesa_CopyTexImage1D_no_error(GLenum target, GLint level, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLint border)
{
- struct gl_texture_image *texImage;
+ GET_CURRENT_CONTEXT(ctx);
+ copyteximage_no_error(ctx, 1, target, level, internalFormat, x, y, width, 1,
+ border);
+}
- FLUSH_VERTICES(ctx, 0);
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "%s %s %d %d %d %d %d %d %d %d\n", caller,
- _mesa_enum_to_string(target),
- level, xoffset, yoffset, zoffset, x, y, width, height);
+void GLAPIENTRY
+_mesa_CopyTexImage2D_no_error(GLenum target, GLint level, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ copyteximage_no_error(ctx, 2, target, level, internalFormat,
+ x, y, width, height, border);
+}
- if (ctx->NewState & NEW_COPY_TEX_STATE)
- _mesa_update_state(ctx);
- if (copytexsubimage_error_check(ctx, dims, texObj, target, level,
- xoffset, yoffset, zoffset,
- width, height, caller)) {
- return;
- }
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(texObj, target, level);
-
- /* If we have a border, offset=-1 is legal. Bias by border width. */
- switch (dims) {
- case 3:
- if (target != GL_TEXTURE_2D_ARRAY)
- zoffset += texImage->Border;
- /* fall-through */
- case 2:
- if (target != GL_TEXTURE_1D_ARRAY)
- yoffset += texImage->Border;
- /* fall-through */
- case 1:
- xoffset += texImage->Border;
- }
-
- if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
- &width, &height)) {
- struct gl_renderbuffer *srcRb =
- get_copy_tex_image_source(ctx, texImage->TexFormat);
-
- copytexsubimage_by_slice(ctx, texImage, dims,
- xoffset, yoffset, zoffset,
- srcRb, x, y, width, height);
-
- check_gen_mipmap(ctx, target, texObj, level);
-
- /* NOTE: Don't signal _NEW_TEXTURE since we've only changed
- * the texel data, not the texture format, size, etc.
- */
- }
- }
- _mesa_unlock_texture(ctx, texObj);
-}
-
-void GLAPIENTRY
-_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, "%s(invalid target %s)", self,
- _mesa_enum_to_string(target));
+void GLAPIENTRY
+_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, "%s(invalid target %s)", self,
+ _mesa_enum_to_string(target));
return;
}
if (!texObj)
return;
- _mesa_copy_texture_sub_image(ctx, 1, texObj, target, level, xoffset, 0, 0,
- x, y, width, 1, self);
+ copy_texture_sub_image_err(ctx, 1, texObj, target, level, xoffset, 0, 0,
+ x, y, width, 1, self);
}
-
-
void GLAPIENTRY
_mesa_CopyTexSubImage2D( GLenum target, GLint level,
GLint xoffset, GLint yoffset,
if (!texObj)
return;
- _mesa_copy_texture_sub_image(ctx, 2, texObj, target, level,
- xoffset, yoffset, 0,
- x, y, width, height, self);
+ copy_texture_sub_image_err(ctx, 2, texObj, target, level, xoffset, yoffset,
+ 0, x, y, width, height, self);
}
if (!texObj)
return;
- _mesa_copy_texture_sub_image(ctx, 3, texObj, target, level,
- xoffset, yoffset, zoffset,
- x, y, width, height, self);
+ copy_texture_sub_image_err(ctx, 3, texObj, target, level, xoffset, yoffset,
+ zoffset, x, y, width, height, self);
}
void GLAPIENTRY
return;
}
- _mesa_copy_texture_sub_image(ctx, 1, texObj, texObj->Target, level,
- xoffset, 0, 0, x, y, width, 1, self);
+ copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0,
+ 0, x, y, width, 1, self);
}
void GLAPIENTRY
return;
}
- _mesa_copy_texture_sub_image(ctx, 2, texObj, texObj->Target, level,
- xoffset, yoffset, 0,
- x, y, width, height, self);
+ copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset,
+ yoffset, 0, x, y, width, height, self);
}
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);
+ copy_texture_sub_image_err(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);
+ copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset,
+ yoffset, zoffset, x, y, width, height, self);
+}
+
+
+void GLAPIENTRY
+_mesa_CopyTexSubImage1D_no_error(GLenum target, GLint level, GLint xoffset,
+ GLint x, GLint y, GLsizei width)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target);
+ copy_texture_sub_image_no_error(ctx, 1, texObj, target, level, xoffset, 0, 0,
+ x, y, width, 1);
+}
+
+void GLAPIENTRY
+_mesa_CopyTexSubImage2D_no_error(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLint x, GLint y, GLsizei width,
+ GLsizei height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target);
+ copy_texture_sub_image_no_error(ctx, 2, texObj, target, level, xoffset,
+ yoffset, 0, x, y, width, height);
+}
+
+void GLAPIENTRY
+_mesa_CopyTexSubImage3D_no_error(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLint x, GLint y,
+ GLsizei width, GLsizei height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target);
+ copy_texture_sub_image_no_error(ctx, 3, texObj, target, level, xoffset,
+ yoffset, zoffset, x, y, width, height);
+}
+
+void GLAPIENTRY
+_mesa_CopyTextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset,
+ GLint x, GLint y, GLsizei width)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture);
+ copy_texture_sub_image_no_error(ctx, 1, texObj, texObj->Target, level,
+ xoffset, 0, 0, x, y, width, 1);
+}
+
+void GLAPIENTRY
+_mesa_CopyTextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset,
+ GLint yoffset, GLint x, GLint y,
+ GLsizei width, GLsizei height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture);
+ copy_texture_sub_image_no_error(ctx, 2, texObj, texObj->Target, level,
+ xoffset, yoffset, 0, x, y, width, height);
+}
+
+void GLAPIENTRY
+_mesa_CopyTextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLint x,
+ GLint y, GLsizei width, GLsizei height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture);
+ if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ /* Act like CopyTexSubImage2D */
+ copy_texture_sub_image_no_error(ctx, 2, texObj,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset,
+ level, xoffset, yoffset, 0, x, y, width,
+ height);
+ }
+ else
+ copy_texture_sub_image_no_error(ctx, 3, texObj, texObj->Target, level,
+ xoffset, yoffset, zoffset, x, y, width,
+ height);
}
+
static bool
check_clear_tex_image(struct gl_context *ctx,
const char *function,
{
struct gl_texture_object *texObj;
- if (texture == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(zero texture)", function);
- return NULL;
- }
-
- texObj = _mesa_lookup_texture(ctx, texture);
-
- if (texObj == NULL) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", function);
+ texObj = _mesa_lookup_texture_err(ctx, texture, function);
+ if (!texObj)
return NULL;
- }
if (texObj->Target == 0) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(unbound tex)", function);
const GLvoid *data)
{
GET_CURRENT_CONTEXT(ctx);
- teximage(ctx, GL_TRUE, 1, target, level, internalFormat,
- width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data);
+ teximage_err(ctx, GL_TRUE, 1, target, level, internalFormat,
+ width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data);
}
const GLvoid *data)
{
GET_CURRENT_CONTEXT(ctx);
- teximage(ctx, GL_TRUE, 2, target, level, internalFormat,
- width, height, 1, border, GL_NONE, GL_NONE, imageSize, data);
+ teximage_err(ctx, GL_TRUE, 2, target, level, internalFormat,
+ width, height, 1, border, GL_NONE, GL_NONE, imageSize, data);
}
GLsizei imageSize, const GLvoid *data)
{
GET_CURRENT_CONTEXT(ctx);
- teximage(ctx, GL_TRUE, 3, target, level, internalFormat,
- width, height, depth, border, GL_NONE, GL_NONE, imageSize, data);
+ teximage_err(ctx, GL_TRUE, 3, target, level, internalFormat, width, height,
+ depth, border, GL_NONE, GL_NONE, imageSize, data);
+}
+
+
+void GLAPIENTRY
+_mesa_CompressedTexImage1D_no_error(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLint border, GLsizei imageSize,
+ const GLvoid *data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ teximage_no_error(ctx, GL_TRUE, 1, target, level, internalFormat, width, 1,
+ 1, border, GL_NONE, GL_NONE, imageSize, data);
+}
+
+
+void GLAPIENTRY
+_mesa_CompressedTexImage2D_no_error(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLint border,
+ GLsizei imageSize, const GLvoid *data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ teximage_no_error(ctx, GL_TRUE, 2, target, level, internalFormat, width,
+ height, 1, border, GL_NONE, GL_NONE, imageSize, data);
+}
+
+
+void GLAPIENTRY
+_mesa_CompressedTexImage3D_no_error(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize, const GLvoid *data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ teximage_no_error(ctx, GL_TRUE, 3, target, level, internalFormat, width,
+ height, depth, border, GL_NONE, GL_NONE, imageSize, data);
}
* Common helper for glCompressedTexSubImage1/2/3D() and
* glCompressedTextureSubImage1/2/3D().
*/
-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)
+static void
+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)
{
FLUSH_VERTICES(ctx, 0);
check_gen_mipmap(ctx, target, texObj, level);
- /* NOTE: Don't signal _NEW_TEXTURE since we've only changed
+ /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed
* the texel data, not the texture format, size, etc.
*/
}
}
-void GLAPIENTRY
-_mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset,
- GLsizei width, GLenum format,
- GLsizei imageSize, const GLvoid *data)
+static ALWAYS_INLINE void
+compressed_tex_sub_image(unsigned dim, GLenum target, GLuint texture,
+ GLint level, GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width, GLsizei height,
+ GLsizei depth, GLenum format, GLsizei imageSize,
+ const GLvoid *data, bool dsa, bool no_error,
+ const char *caller)
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
- if (compressed_subtexture_target_check(ctx, target, 1, format, false,
- "glCompressedTexSubImage1D")) {
- return;
+ if (dsa) {
+ if (no_error) {
+ texObj = _mesa_lookup_texture(ctx, texture);
+ } else {
+ texObj = _mesa_lookup_texture_err(ctx, texture, caller);
+ if (!texObj)
+ return;
+ }
+
+ target = texObj->Target;
}
- texObj = _mesa_get_current_tex_object(ctx, target);
- if (!texObj)
+ if (!no_error &&
+ compressed_subtexture_target_check(ctx, target, dim, format, dsa,
+ caller)) {
return;
+ }
+
+ if (!dsa) {
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ if (!no_error && !texObj)
+ return;
+ }
- if (compressed_subtexture_error_check(ctx, 1, texObj, target,
- level, xoffset, 0, 0,
- width, 1, 1,
- format, imageSize, data,
- "glCompressedTexSubImage1D")) {
+ if (!no_error &&
+ compressed_subtexture_error_check(ctx, dim, texObj, target, level,
+ xoffset, yoffset, zoffset, width,
+ height, depth, format,
+ imageSize, data, caller)) {
return;
}
- texImage = _mesa_select_tex_image(texObj, target, level);
- assert(texImage);
+ /* Must handle special case GL_TEXTURE_CUBE_MAP. */
+ if (dim == 3 && dsa && texObj->Target == GL_TEXTURE_CUBE_MAP) {
+ const char *pixels = data;
+ 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 (!no_error && !_mesa_cube_level_complete(texObj, level)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedTextureSubImage3D(cube map incomplete)");
+ return;
+ }
- _mesa_compressed_texture_sub_image(ctx, 1, texObj, texImage, target, level,
- xoffset, 0, 0, width, 1, 1,
- format, imageSize, data);
+ /* Copy in each face. */
+ for (int i = 0; i < 6; ++i) {
+ texImage = texObj->Image[i][level];
+ assert(texImage);
+
+ 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, target, level);
+ assert(texImage);
+
+ compressed_texture_sub_image(ctx, dim, texObj, texImage, target, level,
+ xoffset, yoffset, zoffset, width, height,
+ depth, format, imageSize, data);
+ }
}
+
void GLAPIENTRY
-_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset,
- GLsizei width, GLenum format,
- GLsizei imageSize, const GLvoid *data)
+_mesa_CompressedTexSubImage1D_no_error(GLenum target, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data)
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
+ compressed_tex_sub_image(1, target, 0, level, xoffset, 0, 0, width,
+ 1, 1, format, imageSize, data, false, true,
+ "glCompressedTexSubImage1D");
+}
- GET_CURRENT_CONTEXT(ctx);
- texObj = _mesa_lookup_texture_err(ctx, texture,
- "glCompressedTextureSubImage1D");
- if (!texObj)
- return;
+void GLAPIENTRY
+_mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset,
+ GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *data)
+{
+ compressed_tex_sub_image(1, target, 0, level, xoffset, 0, 0, width, 1, 1,
+ format, imageSize, data, false, false,
+ "glCompressedTexSubImage1D");
+}
- if (compressed_subtexture_target_check(ctx, texObj->Target, 1, format, true,
- "glCompressedTextureSubImage1D")) {
- return;
- }
- if (compressed_subtexture_error_check(ctx, 1, texObj, texObj->Target,
- level, xoffset, 0, 0,
- width, 1, 1,
- format, imageSize, data,
- "glCompressedTextureSubImage1D")) {
- return;
- }
+void GLAPIENTRY
+_mesa_CompressedTextureSubImage1D_no_error(GLuint texture, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data)
+{
+ compressed_tex_sub_image(1, 0, texture, level, xoffset, 0, 0, width, 1, 1,
+ format, imageSize, data, true, true,
+ "glCompressedTextureSubImage1D");
+}
- 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);
+void GLAPIENTRY
+_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset,
+ GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *data)
+{
+ compressed_tex_sub_image(1, 0, texture, level, xoffset, 0, 0, width, 1, 1,
+ format, imageSize, data, true, false,
+ "glCompressedTextureSubImage1D");
+}
+
+void GLAPIENTRY
+_mesa_CompressedTexSubImage2D_no_error(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data)
+{
+ compressed_tex_sub_image(2, target, 0, level, xoffset, yoffset, 0, width,
+ height, 1, format, imageSize, data, false, true,
+ "glCompressedTexSubImage2D");
}
GLenum format, 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, 2, format, false,
- "glCompressedTexSubImage2D")) {
- return;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
- if (!texObj)
- return;
-
- if (compressed_subtexture_error_check(ctx, 2, texObj, target,
- level, xoffset, yoffset, 0,
- width, height, 1,
- format, imageSize, data,
- "glCompressedTexSubImage2D")) {
- return;
- }
+ compressed_tex_sub_image(2, target, 0, level, xoffset, yoffset, 0, width,
+ height, 1, format, imageSize, data, false, false,
+ "glCompressedTexSubImage2D");
+}
- 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);
+void GLAPIENTRY
+_mesa_CompressedTextureSubImage2D_no_error(GLuint texture, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data)
+{
+ compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0, width,
+ height, 1, format, imageSize, data, true, true,
+ "glCompressedTextureSubImage2D");
}
+
void GLAPIENTRY
_mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset,
GLint yoffset,
GLenum format, 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,
- "glCompressedTextureSubImage2D");
- if (!texObj)
- return;
-
- if (compressed_subtexture_target_check(ctx, texObj->Target, 2, format, true,
- "glCompressedTextureSubImage2D")) {
- return;
- }
-
- 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);
+ compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0, width,
+ height, 1, format, imageSize, data, true, false,
+ "glCompressedTextureSubImage2D");
+}
- _mesa_compressed_texture_sub_image(ctx, 2, texObj, texImage,
- texObj->Target, level,
- xoffset, yoffset, 0, width, height, 1,
- format, imageSize, data);
+void GLAPIENTRY
+_mesa_CompressedTexSubImage3D_no_error(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data)
+{
+ compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, imageSize, data,
+ false, true, "glCompressedTexSubImage3D");
}
void GLAPIENTRY
GLsizei height, GLsizei depth, GLenum format,
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,
- "glCompressedTexSubImage3D")) {
- return;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
- if (!texObj)
- return;
-
- 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);
+ compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, imageSize, data,
+ false, false, "glCompressedTexSubImage3D");
+}
- _mesa_compressed_texture_sub_image(ctx, 3, texObj, texImage, target, level,
- xoffset, yoffset, zoffset,
- width, height, depth,
- format, imageSize, data);
+void GLAPIENTRY
+_mesa_CompressedTextureSubImage3D_no_error(GLuint texture, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data)
+{
+ compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, imageSize, data,
+ true, true, "glCompressedTextureSubImage3D");
}
void GLAPIENTRY
GLenum format, 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,
- "glCompressedTextureSubImage3D");
- if (!texObj)
- return;
-
- if (compressed_subtexture_target_check(ctx, texObj->Target, 3, format, true,
- "glCompressedTextureSubImage3D")) {
- return;
- }
-
- 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);
- }
+ compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, imageSize, data,
+ true, false, "glCompressedTextureSubImage3D");
}
static mesa_format
return;
}
+ if (texObj->HandleAllocated) {
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*,
+ * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other
+ * functions defined in terms of these, if the texture object to be
+ * modified is referenced by one or more texture or image handles."
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable texture)", caller);
+ return;
+ }
+
format = _mesa_validate_texbuffer_format(ctx, internalFormat);
if (format == MESA_FORMAT_NONE) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat %s)",