X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fteximage.c;h=5e13025ed1ba2df730eb40fa7e28a361129634ed;hb=1ebe4305fd0e4b4f023eb50ca0b8229bdd7c1a5e;hp=a0397472057ad7e96e156b4e2f8c9f920648991a;hpb=3034c4c7251bca68e68fbc1e71ec5ee7c7ae0d30;p=mesa.git diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index a0397472057..5e13025ed1b 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -3783,19 +3783,35 @@ copy_texture_sub_image_err(struct gl_context *ctx, GLuint dims, } +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); @@ -3809,15 +3825,17 @@ copyteximage(struct gl_context *ctx, GLuint dims, 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); @@ -3835,8 +3853,13 @@ copyteximage(struct gl_context *ctx, GLuint dims, 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; } } @@ -3844,9 +3867,10 @@ copyteximage(struct gl_context *ctx, GLuint dims, _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. @@ -3906,6 +3930,7 @@ copyteximage(struct gl_context *ctx, GLuint dims, } 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); @@ -3939,6 +3964,24 @@ copyteximage(struct gl_context *ctx, GLuint dims, } +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, @@ -3947,7 +3990,8 @@ _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); } @@ -3958,11 +4002,31 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 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, @@ -4124,6 +4188,87 @@ _mesa_CopyTextureSubImage3D(GLuint texture, 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, @@ -4216,6 +4361,15 @@ get_tex_obj_for_clear(struct gl_context *ctx, 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, @@ -4224,7 +4378,7 @@ get_tex_images_for_clear(struct gl_context *ctx, 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); @@ -4232,28 +4386,23 @@ get_tex_images_for_clear(struct gl_context *ctx, } 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 @@ -4285,6 +4434,7 @@ _mesa_ClearTexSubImage( GLuint texture, GLint level, minDepth = -(int) texImages[0]->Border; maxDepth = texImages[0]->Depth; } else { + assert(numImages == MAX_FACES); minDepth = 0; maxDepth = numImages; } @@ -4314,7 +4464,9 @@ _mesa_ClearTexSubImage( GLuint texture, GLint level, 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]))