Added driver hooks for GetTexImage() and GetCompressedTexImage().

Added fallback _mesa_get_[compressed]_teximage() routines to texstore.c
This commit is contained in:
Brian Paul
2004-12-12 19:03:16 +00:00
parent 5aa1a111a4
commit 68d293b035
5 changed files with 227 additions and 173 deletions

View File

@@ -79,6 +79,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
driver->TexSubImage1D = _mesa_store_texsubimage1d; driver->TexSubImage1D = _mesa_store_texsubimage1d;
driver->TexSubImage2D = _mesa_store_texsubimage2d; driver->TexSubImage2D = _mesa_store_texsubimage2d;
driver->TexSubImage3D = _mesa_store_texsubimage3d; driver->TexSubImage3D = _mesa_store_texsubimage3d;
driver->GetTexImage = _mesa_get_teximage;
driver->CopyTexImage1D = _swrast_copy_teximage1d; driver->CopyTexImage1D = _swrast_copy_teximage1d;
driver->CopyTexImage2D = _swrast_copy_teximage2d; driver->CopyTexImage2D = _swrast_copy_teximage2d;
driver->CopyTexSubImage1D = _swrast_copy_texsubimage1d; 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->CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
driver->CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; driver->CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
driver->CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; driver->CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
driver->GetCompressedTexImage = _mesa_get_compressed_teximage;
driver->CompressedTextureSize = _mesa_compressed_texture_size; driver->CompressedTextureSize = _mesa_compressed_texture_size;
driver->BindTexture = NULL; driver->BindTexture = NULL;
driver->NewTextureObject = _mesa_new_texture_object; driver->NewTextureObject = _mesa_new_texture_object;

View File

@@ -157,8 +157,7 @@ struct dd_function_table {
* This function must respect all rasterization state, glPixelTransfer(), * This function must respect all rasterization state, glPixelTransfer(),
* glPixelZoom(), etc. * glPixelZoom(), etc.
*/ */
void (*CopyPixels)( GLcontext *ctx, void (*CopyPixels)( GLcontext *ctx, GLint srcx, GLint srcy,
GLint srcx, GLint srcy,
GLsizei width, GLsizei height, GLsizei width, GLsizei height,
GLint dstx, GLint dsty, GLenum type ); GLint dstx, GLint dsty, GLenum type );
@@ -297,6 +296,14 @@ struct dd_function_table {
struct gl_texture_object *texObj, struct gl_texture_object *texObj,
struct gl_texture_image *texImage ); 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(). * Called by glCopyTexImage1D().
* *
@@ -454,6 +461,15 @@ struct dd_function_table {
struct gl_texture_object *texObj, struct gl_texture_object *texObj,
struct gl_texture_image *texImage); 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 * Called to query number of bytes of storage needed to store the
* specified compressed texture. * specified compressed texture.

View File

@@ -1902,7 +1902,6 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
const struct gl_texture_object *texObj; const struct gl_texture_object *texObj;
const struct gl_texture_image *texImage; const struct gl_texture_image *texImage;
GLint maxLevels = 0; GLint maxLevels = 0;
GLuint dimensions;
GET_CURRENT_CONTEXT(ctx); GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -1979,127 +1978,9 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
return; return;
} }
dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; /* typically, this will call _mesa_get_teximage() */
ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
/* XXX - someday the rest of this function should be moved into a texObj, texImage);
* 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);
}
} }
@@ -3394,40 +3275,6 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
return; return;
} }
/* XXX - someday the rest of this function should be moved into a /* this typically calls _mesa_get_compressed_teximage() */
* fallback routine called via ctx->Driver.GetCompressedTexImage() ctx->Driver.GetCompressedTexImage(ctx, target, level, img, texObj,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);
}
} }

View File

@@ -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);
}
}

View File

@@ -1,6 +1,6 @@
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
* Version: 6.1 * Version: 6.3
* *
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved. * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
* *
@@ -213,7 +213,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
extern void extern void
_mesa_rescale_teximage2d (GLuint bytesPerPixel, _mesa_rescale_teximage2d(GLuint bytesPerPixel,
GLuint srcStrideInPixels, GLuint srcStrideInPixels,
GLuint dstRowStride, GLuint dstRowStride,
GLint srcWidth, GLint srcHeight, GLint srcWidth, GLint srcHeight,
@@ -221,9 +221,24 @@ _mesa_rescale_teximage2d (GLuint bytesPerPixel,
const GLvoid *srcImage, GLvoid *dstImage); const GLvoid *srcImage, GLvoid *dstImage);
extern void extern void
_mesa_upscale_teximage2d( GLsizei inWidth, GLsizei inHeight, _mesa_upscale_teximage2d(GLsizei inWidth, GLsizei inHeight,
GLsizei outWidth, GLsizei outHeight, GLsizei outWidth, GLsizei outHeight,
GLint comps, const GLchan *src, GLint srcRowStride, GLint comps, const GLchan *src, GLint srcRowStride,
GLchan *dest ); 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 #endif