Added fallback _mesa_get_[compressed]_teximage() routines to texstore.ctags/unichrome-last-xinerama
@@ -79,6 +79,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) | |||
driver->TexSubImage1D = _mesa_store_texsubimage1d; | |||
driver->TexSubImage2D = _mesa_store_texsubimage2d; | |||
driver->TexSubImage3D = _mesa_store_texsubimage3d; | |||
driver->GetTexImage = _mesa_get_teximage; | |||
driver->CopyTexImage1D = _swrast_copy_teximage1d; | |||
driver->CopyTexImage2D = _swrast_copy_teximage2d; | |||
driver->CopyTexSubImage1D = _swrast_copy_texsubimage1d; | |||
@@ -91,6 +92,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) | |||
driver->CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; | |||
driver->CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; | |||
driver->CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; | |||
driver->GetCompressedTexImage = _mesa_get_compressed_teximage; | |||
driver->CompressedTextureSize = _mesa_compressed_texture_size; | |||
driver->BindTexture = NULL; | |||
driver->NewTextureObject = _mesa_new_texture_object; |
@@ -157,10 +157,9 @@ struct dd_function_table { | |||
* This function must respect all rasterization state, glPixelTransfer(), | |||
* glPixelZoom(), etc. | |||
*/ | |||
void (*CopyPixels)( GLcontext *ctx, | |||
GLint srcx, GLint srcy, | |||
GLsizei width, GLsizei height, | |||
GLint dstx, GLint dsty, GLenum type ); | |||
void (*CopyPixels)( GLcontext *ctx, GLint srcx, GLint srcy, | |||
GLsizei width, GLsizei height, | |||
GLint dstx, GLint dsty, GLenum type ); | |||
/** | |||
* This is called by glBitmap(). | |||
@@ -297,6 +296,14 @@ struct dd_function_table { | |||
struct gl_texture_object *texObj, | |||
struct gl_texture_image *texImage ); | |||
/** | |||
* Called by glGetTexImage(). | |||
*/ | |||
void (*GetTexImage)( GLcontext *ctx, GLenum target, GLint level, | |||
GLenum format, GLenum type, GLvoid *pixels, | |||
const struct gl_texture_object *texObj, | |||
const struct gl_texture_image *texImage ); | |||
/** | |||
* Called by glCopyTexImage1D(). | |||
* | |||
@@ -454,6 +461,15 @@ struct dd_function_table { | |||
struct gl_texture_object *texObj, | |||
struct gl_texture_image *texImage); | |||
/** | |||
* Called by glGetCompressedTexImage. | |||
*/ | |||
void (*GetCompressedTexImage)(GLcontext *ctx, GLenum target, GLint level, | |||
GLvoid *img, | |||
const struct gl_texture_object *texObj, | |||
const struct gl_texture_image *texImage); | |||
/** | |||
* Called to query number of bytes of storage needed to store the | |||
* specified compressed texture. |
@@ -1902,7 +1902,6 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, | |||
const struct gl_texture_object *texObj; | |||
const struct gl_texture_image *texImage; | |||
GLint maxLevels = 0; | |||
GLuint dimensions; | |||
GET_CURRENT_CONTEXT(ctx); | |||
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); | |||
@@ -1979,127 +1978,9 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, | |||
return; | |||
} | |||
dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; | |||
/* XXX - someday the rest of this function should be moved into a | |||
* fallback routine called via ctx->Driver.GetTexImage() | |||
*/ | |||
if (ctx->Pack.BufferObj->Name) { | |||
/* pack texture image into a PBO */ | |||
GLubyte *buf; | |||
if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width, | |||
texImage->Height, texImage->Depth, | |||
format, type, pixels)) { | |||
_mesa_error(ctx, GL_INVALID_OPERATION, | |||
"glGetTexImage(invalid PBO access)"); | |||
return; | |||
} | |||
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, | |||
GL_WRITE_ONLY_ARB, | |||
ctx->Pack.BufferObj); | |||
if (!buf) { | |||
/* buffer is already mapped - that's an error */ | |||
_mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)"); | |||
return; | |||
} | |||
pixels = ADD_POINTERS(buf, pixels); | |||
} | |||
else if (!pixels) { | |||
/* not an error */ | |||
return; | |||
} | |||
/* | |||
* XXX Move this code into a new driver fall-back function | |||
*/ | |||
{ | |||
const GLint width = texImage->Width; | |||
const GLint height = texImage->Height; | |||
const GLint depth = texImage->Depth; | |||
GLint img, row; | |||
for (img = 0; img < depth; img++) { | |||
for (row = 0; row < height; row++) { | |||
/* compute destination address in client memory */ | |||
GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels, | |||
width, height, format, type, | |||
img, row, 0); | |||
assert(dest); | |||
if (format == GL_COLOR_INDEX) { | |||
GLuint indexRow[MAX_WIDTH]; | |||
GLint col; | |||
/* Can't use FetchTexel here because that returns RGBA */ | |||
if (texImage->TexFormat->IndexBits == 8) { | |||
const GLubyte *src = (const GLubyte *) texImage->Data; | |||
for (col = 0; col < width; col++) { | |||
indexRow[col] = src[texImage->Width * | |||
(img * texImage->Height + row) + col]; | |||
} | |||
} | |||
else if (texImage->TexFormat->IndexBits == 16) { | |||
const GLushort *src = (const GLushort *) texImage->Data; | |||
for (col = 0; col < width; col++) { | |||
indexRow[col] = src[texImage->Width * | |||
(img * texImage->Height + row) + col]; | |||
} | |||
} | |||
else { | |||
_mesa_problem(ctx, | |||
"Color index problem in _mesa_GetTexImage"); | |||
} | |||
_mesa_pack_index_span(ctx, width, type, dest, | |||
indexRow, &ctx->Pack, | |||
0 /* no image transfer */); | |||
} | |||
else if (format == GL_DEPTH_COMPONENT) { | |||
GLfloat depthRow[MAX_WIDTH]; | |||
GLint col; | |||
for (col = 0; col < width; col++) { | |||
(*texImage->FetchTexelf)(texImage, col, row, img, | |||
depthRow + col); | |||
} | |||
_mesa_pack_depth_span(ctx, width, dest, type, | |||
depthRow, &ctx->Pack); | |||
} | |||
else if (format == GL_YCBCR_MESA) { | |||
/* No pixel transfer */ | |||
const GLint rowstride = texImage->RowStride; | |||
MEMCPY(dest, | |||
(const GLushort *) texImage->Data + row * rowstride, | |||
width * sizeof(GLushort)); | |||
/* check for byte swapping */ | |||
if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR | |||
&& type == GL_UNSIGNED_SHORT_8_8_REV_MESA) || | |||
(texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV | |||
&& type == GL_UNSIGNED_SHORT_8_8_MESA)) { | |||
if (!ctx->Pack.SwapBytes) | |||
_mesa_swap2((GLushort *) dest, width); | |||
} | |||
else if (ctx->Pack.SwapBytes) { | |||
_mesa_swap2((GLushort *) dest, width); | |||
} | |||
} | |||
else { | |||
/* general case: convert row to RGBA format */ | |||
GLfloat rgba[MAX_WIDTH][4]; | |||
GLint col; | |||
for (col = 0; col < width; col++) { | |||
(*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]); | |||
} | |||
_mesa_pack_rgba_span_float(ctx, width, | |||
(const GLfloat (*)[4]) rgba, | |||
format, type, dest, &ctx->Pack, | |||
0 /* no image transfer */); | |||
} /* format */ | |||
} /* row */ | |||
} /* img */ | |||
} | |||
if (ctx->Pack.BufferObj->Name) { | |||
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, | |||
ctx->Pack.BufferObj); | |||
} | |||
/* typically, this will call _mesa_get_teximage() */ | |||
ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels, | |||
texObj, texImage); | |||
} | |||
@@ -3394,40 +3275,6 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) | |||
return; | |||
} | |||
/* XXX - someday the rest of this function should be moved into a | |||
* fallback routine called via ctx->Driver.GetCompressedTexImage() | |||
*/ | |||
if (ctx->Pack.BufferObj->Name) { | |||
/* pack texture image into a PBO */ | |||
GLubyte *buf; | |||
if ((const GLubyte *) img + texImage->CompressedSize > | |||
(const GLubyte *) ctx->Pack.BufferObj->Size) { | |||
_mesa_error(ctx, GL_INVALID_OPERATION, | |||
"glGetCompressedTexImage(invalid PBO access)"); | |||
return; | |||
} | |||
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, | |||
GL_WRITE_ONLY_ARB, | |||
ctx->Pack.BufferObj); | |||
if (!buf) { | |||
/* buffer is already mapped - that's an error */ | |||
_mesa_error(ctx, GL_INVALID_OPERATION, | |||
"glGetCompressedTexImage(PBO is mapped)"); | |||
return; | |||
} | |||
img = ADD_POINTERS(buf, img); | |||
} | |||
else if (!img) { | |||
/* not an error */ | |||
return; | |||
} | |||
/* just memcpy, no pixelstore or pixel transfer */ | |||
MEMCPY(img, texImage->Data, texImage->CompressedSize); | |||
if (ctx->Pack.BufferObj->Name) { | |||
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, | |||
ctx->Pack.BufferObj); | |||
} | |||
/* this typically calls _mesa_get_compressed_teximage() */ | |||
ctx->Driver.GetCompressedTexImage(ctx, target, level, img, texObj,texImage); | |||
} |
@@ -3597,3 +3597,177 @@ _mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight, | |||
} | |||
} | |||
} | |||
/** | |||
* This is the software fallback for Driver.GetTexImage(). | |||
* All error checking will have been done before this routine is called. | |||
*/ | |||
void | |||
_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, | |||
GLenum format, GLenum type, GLvoid *pixels, | |||
const struct gl_texture_object *texObj, | |||
const struct gl_texture_image *texImage) | |||
{ | |||
GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; | |||
if (ctx->Pack.BufferObj->Name) { | |||
/* pack texture image into a PBO */ | |||
GLubyte *buf; | |||
if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width, | |||
texImage->Height, texImage->Depth, | |||
format, type, pixels)) { | |||
_mesa_error(ctx, GL_INVALID_OPERATION, | |||
"glGetTexImage(invalid PBO access)"); | |||
return; | |||
} | |||
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, | |||
GL_WRITE_ONLY_ARB, | |||
ctx->Pack.BufferObj); | |||
if (!buf) { | |||
/* buffer is already mapped - that's an error */ | |||
_mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)"); | |||
return; | |||
} | |||
pixels = ADD_POINTERS(buf, pixels); | |||
} | |||
else if (!pixels) { | |||
/* not an error */ | |||
return; | |||
} | |||
{ | |||
const GLint width = texImage->Width; | |||
const GLint height = texImage->Height; | |||
const GLint depth = texImage->Depth; | |||
GLint img, row; | |||
for (img = 0; img < depth; img++) { | |||
for (row = 0; row < height; row++) { | |||
/* compute destination address in client memory */ | |||
GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels, | |||
width, height, format, type, | |||
img, row, 0); | |||
assert(dest); | |||
if (format == GL_COLOR_INDEX) { | |||
GLuint indexRow[MAX_WIDTH]; | |||
GLint col; | |||
/* Can't use FetchTexel here because that returns RGBA */ | |||
if (texImage->TexFormat->IndexBits == 8) { | |||
const GLubyte *src = (const GLubyte *) texImage->Data; | |||
for (col = 0; col < width; col++) { | |||
indexRow[col] = src[texImage->Width * | |||
(img * texImage->Height + row) + col]; | |||
} | |||
} | |||
else if (texImage->TexFormat->IndexBits == 16) { | |||
const GLushort *src = (const GLushort *) texImage->Data; | |||
for (col = 0; col < width; col++) { | |||
indexRow[col] = src[texImage->Width * | |||
(img * texImage->Height + row) + col]; | |||
} | |||
} | |||
else { | |||
_mesa_problem(ctx, | |||
"Color index problem in _mesa_GetTexImage"); | |||
} | |||
_mesa_pack_index_span(ctx, width, type, dest, | |||
indexRow, &ctx->Pack, | |||
0 /* no image transfer */); | |||
} | |||
else if (format == GL_DEPTH_COMPONENT) { | |||
GLfloat depthRow[MAX_WIDTH]; | |||
GLint col; | |||
for (col = 0; col < width; col++) { | |||
(*texImage->FetchTexelf)(texImage, col, row, img, | |||
depthRow + col); | |||
} | |||
_mesa_pack_depth_span(ctx, width, dest, type, | |||
depthRow, &ctx->Pack); | |||
} | |||
else if (format == GL_YCBCR_MESA) { | |||
/* No pixel transfer */ | |||
const GLint rowstride = texImage->RowStride; | |||
MEMCPY(dest, | |||
(const GLushort *) texImage->Data + row * rowstride, | |||
width * sizeof(GLushort)); | |||
/* check for byte swapping */ | |||
if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR | |||
&& type == GL_UNSIGNED_SHORT_8_8_REV_MESA) || | |||
(texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV | |||
&& type == GL_UNSIGNED_SHORT_8_8_MESA)) { | |||
if (!ctx->Pack.SwapBytes) | |||
_mesa_swap2((GLushort *) dest, width); | |||
} | |||
else if (ctx->Pack.SwapBytes) { | |||
_mesa_swap2((GLushort *) dest, width); | |||
} | |||
} | |||
else { | |||
/* general case: convert row to RGBA format */ | |||
GLfloat rgba[MAX_WIDTH][4]; | |||
GLint col; | |||
for (col = 0; col < width; col++) { | |||
(*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]); | |||
} | |||
_mesa_pack_rgba_span_float(ctx, width, | |||
(const GLfloat (*)[4]) rgba, | |||
format, type, dest, &ctx->Pack, | |||
0 /* no image transfer */); | |||
} /* format */ | |||
} /* row */ | |||
} /* img */ | |||
} | |||
if (ctx->Pack.BufferObj->Name) { | |||
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, | |||
ctx->Pack.BufferObj); | |||
} | |||
} | |||
/** | |||
* This is the software fallback for Driver.GetCompressedTexImage(). | |||
* All error checking will have been done before this routine is called. | |||
*/ | |||
void | |||
_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level, | |||
GLvoid *img, | |||
const struct gl_texture_object *texObj, | |||
const struct gl_texture_image *texImage) | |||
{ | |||
if (ctx->Pack.BufferObj->Name) { | |||
/* pack texture image into a PBO */ | |||
GLubyte *buf; | |||
if ((const GLubyte *) img + texImage->CompressedSize > | |||
(const GLubyte *) ctx->Pack.BufferObj->Size) { | |||
_mesa_error(ctx, GL_INVALID_OPERATION, | |||
"glGetCompressedTexImage(invalid PBO access)"); | |||
return; | |||
} | |||
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, | |||
GL_WRITE_ONLY_ARB, | |||
ctx->Pack.BufferObj); | |||
if (!buf) { | |||
/* buffer is already mapped - that's an error */ | |||
_mesa_error(ctx, GL_INVALID_OPERATION, | |||
"glGetCompressedTexImage(PBO is mapped)"); | |||
return; | |||
} | |||
img = ADD_POINTERS(buf, img); | |||
} | |||
else if (!img) { | |||
/* not an error */ | |||
return; | |||
} | |||
/* just memcpy, no pixelstore or pixel transfer */ | |||
MEMCPY(img, texImage->Data, texImage->CompressedSize); | |||
if (ctx->Pack.BufferObj->Name) { | |||
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, | |||
ctx->Pack.BufferObj); | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
/* | |||
* Mesa 3-D graphics library | |||
* Version: 6.1 | |||
* Version: 6.3 | |||
* | |||
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved. | |||
* | |||
@@ -213,17 +213,32 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, | |||
extern void | |||
_mesa_rescale_teximage2d (GLuint bytesPerPixel, | |||
GLuint srcStrideInPixels, | |||
GLuint dstRowStride, | |||
GLint srcWidth, GLint srcHeight, | |||
GLint dstWidth, GLint dstHeight, | |||
const GLvoid *srcImage, GLvoid *dstImage); | |||
_mesa_rescale_teximage2d(GLuint bytesPerPixel, | |||
GLuint srcStrideInPixels, | |||
GLuint dstRowStride, | |||
GLint srcWidth, GLint srcHeight, | |||
GLint dstWidth, GLint dstHeight, | |||
const GLvoid *srcImage, GLvoid *dstImage); | |||
extern void | |||
_mesa_upscale_teximage2d( GLsizei inWidth, GLsizei inHeight, | |||
GLsizei outWidth, GLsizei outHeight, | |||
GLint comps, const GLchan *src, GLint srcRowStride, | |||
GLchan *dest ); | |||
_mesa_upscale_teximage2d(GLsizei inWidth, GLsizei inHeight, | |||
GLsizei outWidth, GLsizei outHeight, | |||
GLint comps, const GLchan *src, GLint srcRowStride, | |||
GLchan *dest); | |||
extern void | |||
_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, | |||
GLenum format, GLenum type, GLvoid *pixels, | |||
const struct gl_texture_object *texObj, | |||
const struct gl_texture_image *texImage); | |||
extern void | |||
_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level, | |||
GLvoid *img, | |||
const struct gl_texture_object *texObj, | |||
const struct gl_texture_image *texImage); | |||
#endif |