mesa: move _mesa_Get[Compressed]TexImage() to texgetimage.c

All the glGetTexImage code is in one file now.
This commit is contained in:
Brian Paul
2009-08-13 09:38:39 -06:00
parent b9f67df6e7
commit ba2a55ccd6
5 changed files with 275 additions and 242 deletions

View File

@@ -107,6 +107,7 @@
#include "state.h"
#include "stencil.h"
#include "texenv.h"
#include "texgetimage.h"
#include "teximage.h"
#if FEATURE_texgen
#include "texgen.h"

View File

@@ -36,6 +36,7 @@
#include "texcompress.h"
#include "texformat.h"
#include "texgetimage.h"
#include "teximage.h"
@@ -105,6 +106,18 @@ type_with_negative_values(GLenum type)
}
/**
* Return pointer to current texture unit.
* This the texture unit set by glActiveTexture(), not glClientActiveTexture().
*/
static INLINE struct gl_texture_unit *
get_current_tex_unit(GLcontext *ctx)
{
ASSERT(ctx->Texture.CurrentUnit < Elements(ctx->Texture.Unit));
return &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
}
/**
* This is the software fallback for Driver.GetTexImage().
* All error checking will have been done before this routine is called.
@@ -355,3 +368,222 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
ctx->Pack.BufferObj);
}
}
/**
* Do error checking for a glGetTexImage() call.
* \return GL_TRUE if any error, GL_FALSE if no errors.
*/
static GLboolean
getteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
GLenum format, GLenum type, GLvoid *pixels )
{
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
if (level < 0 || level >= maxLevels) {
_mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
return GL_TRUE;
}
if (_mesa_sizeof_packed_type(type) <= 0) {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
return GL_TRUE;
}
if (_mesa_components_in_format(format) <= 0 ||
format == GL_STENCIL_INDEX) {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
return GL_TRUE;
}
if (!ctx->Extensions.EXT_paletted_texture && _mesa_is_index_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.ARB_depth_texture && _mesa_is_depth_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.MESA_ycbcr_texture && _mesa_is_ycbcr_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.EXT_packed_depth_stencil
&& _mesa_is_depthstencil_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.ATI_envmap_bumpmap
&& _mesa_is_dudv_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
texUnit = get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
if (!texObj || _mesa_is_proxy_texture(target)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
return GL_TRUE;
}
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
if (!texImage) {
/* out of memory */
return GL_TRUE;
}
/* Make sure the requested image format is compatible with the
* texture's format. Note that a color index texture can be converted
* to RGBA so that combo is allowed.
*/
if (_mesa_is_color_format(format)
&& !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
&& !_mesa_is_index_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (_mesa_is_index_format(format)
&& !_mesa_is_index_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (_mesa_is_depth_format(format)
&& !_mesa_is_depth_format(texImage->TexFormat->BaseFormat)
&& !_mesa_is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (_mesa_is_ycbcr_format(format)
&& !_mesa_is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (_mesa_is_depthstencil_format(format)
&& !_mesa_is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (_mesa_is_dudv_format(format)
&& !_mesa_is_dudv_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* packing texture image into a PBO */
const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
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 GL_TRUE;
}
}
return GL_FALSE;
}
/**
* Get texture image. Called by glGetTexImage.
*
* \param target texture target.
* \param level image level.
* \param format pixel data format for returned image.
* \param type pixel data type for returned image.
* \param pixels returned pixel data.
*/
void GLAPIENTRY
_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
GLenum type, GLvoid *pixels )
{
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (getteximage_error_check(ctx, target, level, format, type, pixels)) {
return;
}
texUnit = get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
struct gl_texture_image *texImage =
_mesa_select_tex_image(ctx, texObj, target, level);
/* typically, this will call _mesa_get_teximage() */
ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
texObj, texImage);
}
_mesa_unlock_texture(ctx, texObj);
}
void GLAPIENTRY
_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
{
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLint maxLevels;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
texUnit = get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
if (!texObj) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
return;
}
maxLevels = _mesa_max_texture_levels(ctx, target);
ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
if (level < 0 || level >= maxLevels) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
return;
}
if (_mesa_is_proxy_texture(target)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
return;
}
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
if (texImage) {
if (texImage->IsCompressed) {
/* this typically calls _mesa_get_compressed_teximage() */
ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
texObj, texImage);
}
else {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetCompressedTexImageARB");
}
}
else {
/* probably invalid mipmap level */
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetCompressedTexImageARB(level)");
}
}
_mesa_unlock_texture(ctx, texObj);
}

View File

@@ -43,4 +43,13 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
extern void GLAPIENTRY
_mesa_GetTexImage( GLenum target, GLint level,
GLenum format, GLenum type, GLvoid *pixels );
extern void GLAPIENTRY
_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);
#endif /* TEXGETIMAGE_H */

View File

@@ -537,8 +537,8 @@ _mesa_is_color_format(GLenum format)
/**
* Test if the given image format is a color index format.
*/
static GLboolean
is_index_format(GLenum format)
GLboolean
_mesa_is_index_format(GLenum format)
{
switch (format) {
case GL_COLOR_INDEX:
@@ -558,8 +558,8 @@ is_index_format(GLenum format)
/**
* Test if the given image format is a depth component format.
*/
static GLboolean
is_depth_format(GLenum format)
GLboolean
_mesa_is_depth_format(GLenum format)
{
switch (format) {
case GL_DEPTH_COMPONENT16:
@@ -576,8 +576,8 @@ is_depth_format(GLenum format)
/**
* Test if the given image format is a YCbCr format.
*/
static GLboolean
is_ycbcr_format(GLenum format)
GLboolean
_mesa_is_ycbcr_format(GLenum format)
{
switch (format) {
case GL_YCBCR_MESA:
@@ -591,8 +591,8 @@ is_ycbcr_format(GLenum format)
/**
* Test if the given image format is a Depth/Stencil format.
*/
static GLboolean
is_depthstencil_format(GLenum format)
GLboolean
_mesa_is_depthstencil_format(GLenum format)
{
switch (format) {
case GL_DEPTH24_STENCIL8_EXT:
@@ -606,8 +606,8 @@ is_depthstencil_format(GLenum format)
/**
* Test if the given image format is a dudv format.
*/
static GLboolean
is_dudv_format(GLenum format)
GLboolean
_mesa_is_dudv_format(GLenum format)
{
switch (format) {
case GL_DUDV_ATI:
@@ -1549,13 +1549,13 @@ texture_error_check( GLcontext *ctx, GLenum target,
/* make sure internal format and format basically agree */
colorFormat = _mesa_is_color_format(format);
indexFormat = is_index_format(format);
indexFormat = _mesa_is_index_format(format);
if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
(is_index_format(internalFormat) && !indexFormat) ||
(is_depth_format(internalFormat) != is_depth_format(format)) ||
(is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) ||
(is_depthstencil_format(internalFormat) != is_depthstencil_format(format)) ||
(is_dudv_format(internalFormat) != is_dudv_format(format))) {
(_mesa_is_index_format(internalFormat) && !indexFormat) ||
(_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
(_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
(_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
(_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
if (!isProxy)
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
@@ -1990,7 +1990,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
}
else if (is_depth_format(internalFormat)) {
else if (_mesa_is_depth_format(internalFormat)) {
/* make sure we have depth/stencil buffers */
if (!ctx->ReadBuffer->_DepthBuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -1998,7 +1998,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
}
else if (is_depthstencil_format(internalFormat)) {
else if (_mesa_is_depthstencil_format(internalFormat)) {
/* make sure we have depth/stencil buffers */
if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -2223,170 +2223,6 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
}
/**
* Do error checking for a glGetTexImage() call.
* \return GL_TRUE if any error, GL_FALSE if no errors.
*/
static GLboolean
getteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
GLenum format, GLenum type, GLvoid *pixels )
{
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
if (level < 0 || level >= maxLevels) {
_mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
return GL_TRUE;
}
if (_mesa_sizeof_packed_type(type) <= 0) {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
return GL_TRUE;
}
if (_mesa_components_in_format(format) <= 0 ||
format == GL_STENCIL_INDEX) {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
return GL_TRUE;
}
if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.MESA_ycbcr_texture && is_ycbcr_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.EXT_packed_depth_stencil
&& is_depthstencil_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.ATI_envmap_bumpmap
&& is_dudv_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
texUnit = get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
if (!texObj || _mesa_is_proxy_texture(target)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
return GL_TRUE;
}
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
if (!texImage) {
/* out of memory */
return GL_TRUE;
}
/* Make sure the requested image format is compatible with the
* texture's format. Note that a color index texture can be converted
* to RGBA so that combo is allowed.
*/
if (_mesa_is_color_format(format)
&& !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
&& !is_index_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (is_index_format(format)
&& !is_index_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (is_depth_format(format)
&& !is_depth_format(texImage->TexFormat->BaseFormat)
&& !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (is_ycbcr_format(format)
&& !is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (is_depthstencil_format(format)
&& !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (is_dudv_format(format)
&& !is_dudv_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* packing texture image into a PBO */
const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
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 GL_TRUE;
}
}
return GL_FALSE;
}
/**
* Get texture image. Called by glGetTexImage.
*
* \param target texture target.
* \param level image level.
* \param format pixel data format for returned image.
* \param type pixel data type for returned image.
* \param pixels returned pixel data.
*/
void GLAPIENTRY
_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
GLenum type, GLvoid *pixels )
{
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (getteximage_error_check(ctx, target, level, format, type, pixels)) {
return;
}
texUnit = get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
struct gl_texture_image *texImage =
_mesa_select_tex_image(ctx, texObj, target, level);
/* typically, this will call _mesa_get_teximage() */
ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
texObj, texImage);
}
_mesa_unlock_texture(ctx, texObj);
}
/** Callback info for walking over FBO hash table */
struct cb_info
{
@@ -3947,55 +3783,3 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
}
void GLAPIENTRY
_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
{
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLint maxLevels;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
texUnit = get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
if (!texObj) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
return;
}
maxLevels = _mesa_max_texture_levels(ctx, target);
ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
if (level < 0 || level >= maxLevels) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
return;
}
if (_mesa_is_proxy_texture(target)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
return;
}
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
if (texImage) {
if (texImage->IsCompressed) {
/* this typically calls _mesa_get_compressed_teximage() */
ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
texObj, texImage);
}
else {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetCompressedTexImageARB");
}
}
else {
/* probably invalid mipmap level */
_mesa_error(ctx, GL_INVALID_VALUE,
"glGetCompressedTexImageARB(level)");
}
}
_mesa_unlock_texture(ctx, texObj);
}

View File

@@ -118,6 +118,21 @@ _mesa_tex_target_to_face(GLenum target);
extern GLboolean
_mesa_is_color_format(GLenum format);
extern GLboolean
_mesa_is_index_format(GLenum format);
extern GLboolean
_mesa_is_depth_format(GLenum format);
extern GLboolean
_mesa_is_ycbcr_format(GLenum format);
extern GLboolean
_mesa_is_depthstencil_format(GLenum format);
extern GLboolean
_mesa_is_dudv_format(GLenum format);
/**
* Lock a texture for updating. See also _mesa_lock_context_textures().
@@ -167,11 +182,6 @@ _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
const GLvoid *pixels );
extern void GLAPIENTRY
_mesa_GetTexImage( GLenum target, GLint level,
GLenum format, GLenum type, GLvoid *pixels );
extern void GLAPIENTRY
_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
GLsizei width,
@@ -264,9 +274,6 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
GLsizei height, GLsizei depth, GLenum format,
GLsizei imageSize, const GLvoid *data);
extern void GLAPIENTRY
_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);
/*@}*/
#endif