}
+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 void
+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);
- copy_texture_sub_image_err(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);
}
+void GLAPIENTRY
+_mesa_CopyTexImage1D_no_error(GLenum target, GLint level, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLint border)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ copyteximage_no_error(ctx, 1, target, level, internalFormat, x, y, width, 1,
+ border);
+}
+
+
+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);
+}
+
void GLAPIENTRY
_mesa_CopyTexSubImage1D( GLenum target, GLint level,
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,
return texObj;
}
+
+/**
+ * For clearing cube textures, the zoffset and depth parameters indicate
+ * which cube map faces are to be cleared. This is the one case where we
+ * need to be concerned with multiple gl_texture_images. This function
+ * returns the array of texture images to clear for cube maps, or one
+ * texture image otherwise.
+ * \return number of texture images, 0 for error, 6 for cube, 1 otherwise.
+ */
static int
get_tex_images_for_clear(struct gl_context *ctx,
const char *function,
struct gl_texture_image **texImages)
{
GLenum target;
- int i;
+ int numFaces, i;
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);
}
if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
- for (i = 0; i < MAX_FACES; i++) {
- target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
-
- texImages[i] = _mesa_select_tex_image(texObj, target, level);
- if (texImages[i] == NULL) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(invalid level)", function);
- return 0;
- }
- }
-
- return MAX_FACES;
+ target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ numFaces = MAX_FACES;
+ }
+ else {
+ target = texObj->Target;
+ numFaces = 1;
}
- texImages[0] = _mesa_select_tex_image(texObj, texObj->Target, level);
-
- if (texImages[0] == NULL) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);
- return 0;
+ for (i = 0; i < numFaces; i++) {
+ texImages[i] = _mesa_select_tex_image(texObj, target + i, level);
+ if (texImages[i] == NULL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);
+ return 0;
+ }
}
- return 1;
+ return numFaces;
}
void GLAPIENTRY
minDepth = -(int) texImages[0]->Border;
maxDepth = texImages[0]->Depth;
} else {
+ assert(numImages == MAX_FACES);
minDepth = 0;
maxDepth = numImages;
}
data ? clearValue[0] : NULL);
}
} else {
+ /* loop over cube face images */
for (i = zoffset; i < zoffset + depth; i++) {
+ assert(i < MAX_FACES);
if (!check_clear_tex_image(ctx, "glClearTexSubImage",
texImages[i],
format, type, data, clearValue[i]))