|
|
|
@@ -2677,119 +2677,6 @@ get_temp_image_type(struct gl_context *ctx, GLenum baseFormat) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Helper for _mesa_meta_CopyTexImage1/2D() functions. |
|
|
|
* Have to be careful with locking and meta state for pixel transfer. |
|
|
|
*/ |
|
|
|
static void |
|
|
|
copy_tex_image(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, |
|
|
|
GLenum internalFormat, GLint x, GLint y, |
|
|
|
GLsizei width, GLsizei height, GLint border) |
|
|
|
{ |
|
|
|
struct gl_texture_object *texObj; |
|
|
|
struct gl_texture_image *texImage; |
|
|
|
GLenum format, type; |
|
|
|
GLint bpp; |
|
|
|
void *buf; |
|
|
|
struct gl_renderbuffer *read_rb = ctx->ReadBuffer->_ColorReadBuffer; |
|
|
|
|
|
|
|
texObj = _mesa_get_current_tex_object(ctx, target); |
|
|
|
texImage = _mesa_get_tex_image(ctx, texObj, target, level); |
|
|
|
|
|
|
|
/* Choose format/type for temporary image buffer */ |
|
|
|
format = _mesa_base_tex_format(ctx, internalFormat); |
|
|
|
|
|
|
|
if (format == GL_LUMINANCE && |
|
|
|
_mesa_get_format_base_format(read_rb->Format) != GL_LUMINANCE) { |
|
|
|
/* The glReadPixels() path will convert RGB to luminance by |
|
|
|
* summing R+G+B. glCopyTexImage() is supposed to behave as |
|
|
|
* glCopyPixels, which doesn't do that change, and instead |
|
|
|
* leaves it up to glTexImage which converts RGB to luminance by |
|
|
|
* just taking the R channel. To avoid glReadPixels() trashing |
|
|
|
* our data, use RGBA for our temporary image. |
|
|
|
*/ |
|
|
|
format = GL_RGBA; |
|
|
|
} |
|
|
|
|
|
|
|
type = get_temp_image_type(ctx, format); |
|
|
|
bpp = _mesa_bytes_per_pixel(format, type); |
|
|
|
if (bpp <= 0) { |
|
|
|
_mesa_problem(ctx, "Bad bpp in meta copy_tex_image()"); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* Alloc image buffer (XXX could use a PBO) |
|
|
|
*/ |
|
|
|
buf = malloc(width * height * bpp); |
|
|
|
if (!buf) { |
|
|
|
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
_mesa_unlock_texture(ctx, texObj); /* need to unlock first */ |
|
|
|
|
|
|
|
/* |
|
|
|
* Read image from framebuffer (disable pixel transfer ops) |
|
|
|
*/ |
|
|
|
_mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER); |
|
|
|
ctx->Driver.ReadPixels(ctx, x, y, width, height, |
|
|
|
format, type, &ctx->Pack, buf); |
|
|
|
_mesa_meta_end(ctx); |
|
|
|
|
|
|
|
if (texImage->Data) { |
|
|
|
ctx->Driver.FreeTexImageData(ctx, texImage); |
|
|
|
} |
|
|
|
|
|
|
|
/* The texture's format was already chosen in _mesa_CopyTexImage() */ |
|
|
|
ASSERT(texImage->TexFormat != MESA_FORMAT_NONE); |
|
|
|
|
|
|
|
/* |
|
|
|
* Store texture data (with pixel transfer ops) |
|
|
|
*/ |
|
|
|
_mesa_meta_begin(ctx, META_PIXEL_STORE); |
|
|
|
|
|
|
|
_mesa_update_state(ctx); /* to update pixel transfer state */ |
|
|
|
|
|
|
|
if (target == GL_TEXTURE_1D) { |
|
|
|
ctx->Driver.TexImage1D(ctx, target, level, internalFormat, |
|
|
|
width, border, format, type, |
|
|
|
buf, &ctx->Unpack, texObj, texImage); |
|
|
|
} |
|
|
|
else { |
|
|
|
ctx->Driver.TexImage2D(ctx, target, level, internalFormat, |
|
|
|
width, height, border, format, type, |
|
|
|
buf, &ctx->Unpack, texObj, texImage); |
|
|
|
} |
|
|
|
_mesa_meta_end(ctx); |
|
|
|
|
|
|
|
_mesa_lock_texture(ctx, texObj); /* re-lock */ |
|
|
|
|
|
|
|
free(buf); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
_mesa_meta_CopyTexImage1D(struct gl_context *ctx, GLenum target, GLint level, |
|
|
|
GLenum internalFormat, GLint x, GLint y, |
|
|
|
GLsizei width, GLint border) |
|
|
|
{ |
|
|
|
copy_tex_image(ctx, 1, target, level, internalFormat, x, y, |
|
|
|
width, 1, border); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
_mesa_meta_CopyTexImage2D(struct gl_context *ctx, GLenum target, GLint level, |
|
|
|
GLenum internalFormat, GLint x, GLint y, |
|
|
|
GLsizei width, GLsizei height, GLint border) |
|
|
|
{ |
|
|
|
copy_tex_image(ctx, 2, target, level, internalFormat, x, y, |
|
|
|
width, height, border); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions. |
|
|
|
* Have to be careful with locking and meta state for pixel transfer. |