Rework gl[Copy]Tex[Sub]Image() error checking so that all level, width, height
and depth checks are done via ctx->Driver.TestProxyTexImage(). This allows more flexiblity, like supporting larger, non-cubic 3D textures.
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
/* $Id: osmesa.c,v 1.103 2003/04/01 17:28:55 brianp Exp $ */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
* Version: 5.1
|
* Version: 5.1
|
||||||
@@ -48,6 +46,7 @@
|
|||||||
#include "mtypes.h"
|
#include "mtypes.h"
|
||||||
#include "texformat.h"
|
#include "texformat.h"
|
||||||
#include "texobj.h"
|
#include "texobj.h"
|
||||||
|
#include "teximage.h"
|
||||||
#include "texstore.h"
|
#include "texstore.h"
|
||||||
#include "array_cache/acache.h"
|
#include "array_cache/acache.h"
|
||||||
#include "swrast/swrast.h"
|
#include "swrast/swrast.h"
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
/* $Id: xm_dd.c,v 1.47 2003/04/01 17:28:11 brianp Exp $ */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
* Version: 5.1
|
* Version: 5.1
|
||||||
@@ -36,6 +34,7 @@
|
|||||||
#include "mtypes.h"
|
#include "mtypes.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "texobj.h"
|
#include "texobj.h"
|
||||||
|
#include "teximage.h"
|
||||||
#include "texstore.h"
|
#include "texstore.h"
|
||||||
#include "texformat.h"
|
#include "texformat.h"
|
||||||
#include "xmesaP.h"
|
#include "xmesaP.h"
|
||||||
@@ -924,6 +923,39 @@ void xmesa_update_state( GLcontext *ctx, GLuint new_state )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called via ctx->Driver.TestProxyTeximage(). Normally, we'd just use
|
||||||
|
* the _mesa_test_proxy_teximage() fallback function, but we're going to
|
||||||
|
* special-case the 3D texture case to allow textures up to 512x512x32
|
||||||
|
* texels.
|
||||||
|
*/
|
||||||
|
static GLboolean
|
||||||
|
test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint internalFormat, GLenum format, GLenum type,
|
||||||
|
GLint width, GLint height, GLint depth, GLint border)
|
||||||
|
{
|
||||||
|
if (target == GL_PROXY_TEXTURE_3D) {
|
||||||
|
/* special case for 3D textures */
|
||||||
|
if (width * height * depth > 512 * 512 * 64 ||
|
||||||
|
width < 2 * border || _mesa_bitcount(width - 2 * border) != 1 ||
|
||||||
|
height < 2 * border || _mesa_bitcount(height - 2 * border) != 1 ||
|
||||||
|
depth < 2 * border || _mesa_bitcount(depth - 2 * border) != 1) {
|
||||||
|
/* Bad size, or too many texels */
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* use the fallback routine for 1D, 2D, cube and rect targets */
|
||||||
|
return _mesa_test_proxy_teximage(ctx, target, level, internalFormat,
|
||||||
|
format, type, width, height, depth,
|
||||||
|
border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Setup pointers and other driver state that is constant for the life
|
/* Setup pointers and other driver state that is constant for the life
|
||||||
* of a context.
|
* of a context.
|
||||||
*/
|
*/
|
||||||
@@ -957,7 +989,7 @@ void xmesa_init_pointers( GLcontext *ctx )
|
|||||||
ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
|
ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
|
||||||
ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
|
ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
|
||||||
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
|
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
|
||||||
ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
|
ctx->Driver.TestProxyTexImage = test_proxy_teximage;
|
||||||
|
|
||||||
ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
|
ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
|
||||||
ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
|
ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
/* $Id: config.h,v 1.45 2003/03/29 17:01:03 brianp Exp $ */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
* Version: 5.1
|
* Version: 5.1
|
||||||
@@ -107,7 +105,7 @@
|
|||||||
#define MAX_TEXTURE_LEVELS 12
|
#define MAX_TEXTURE_LEVELS 12
|
||||||
|
|
||||||
/* Number of 3D texture mipmap levels */
|
/* Number of 3D texture mipmap levels */
|
||||||
#define MAX_3D_TEXTURE_LEVELS 8
|
#define MAX_3D_TEXTURE_LEVELS 9
|
||||||
|
|
||||||
/* Number of cube texture mipmap levels - GL_ARB_texture_cube_map */
|
/* Number of cube texture mipmap levels - GL_ARB_texture_cube_map */
|
||||||
#define MAX_CUBE_TEXTURE_LEVELS 12
|
#define MAX_CUBE_TEXTURE_LEVELS 12
|
||||||
|
@@ -785,7 +785,7 @@ make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Reset the fields of a gl_texture_image struct to zero.
|
* Reset the fields of a gl_texture_image struct to zero.
|
||||||
* This is called when a proxy texture test fails, we set all the
|
* This is called when a proxy texture test fails, we set all the
|
||||||
* image members (except DriverData) to zero.
|
* image members (except DriverData) to zero.
|
||||||
@@ -871,12 +871,103 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the fallback for Driver.TestProxyTexImage(). Test the texture
|
||||||
|
* level, width, height and depth against the ctx->Const limits for textures.
|
||||||
|
*
|
||||||
|
* A hardware driver might override this function if, for example, the
|
||||||
|
* max 3D texture size is 512x512x64 (i.e. not a cube).
|
||||||
|
*
|
||||||
|
* \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
|
||||||
|
* GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
|
||||||
|
* GL_PROXY_TEXTURE_CUBE_MAP_ARB.
|
||||||
|
* \param level as passed to glTexImage
|
||||||
|
* \param internalFormat as passed to glTexImage
|
||||||
|
* \param format as passed to glTexImage
|
||||||
|
* \param type as passed to glTexImage
|
||||||
|
* \param width as passed to glTexImage
|
||||||
|
* \param height as passed to glTexImage
|
||||||
|
* \param depth as passed to glTexImage
|
||||||
|
* \param border as passed to glTexImage
|
||||||
|
* \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
|
||||||
|
*/
|
||||||
|
GLboolean
|
||||||
|
_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint internalFormat, GLenum format, GLenum type,
|
||||||
|
GLint width, GLint height, GLint depth, GLint border)
|
||||||
|
{
|
||||||
|
GLint maxSize;
|
||||||
|
|
||||||
/*
|
(void) internalFormat;
|
||||||
|
(void) format;
|
||||||
|
(void) type;
|
||||||
|
|
||||||
|
switch (target) {
|
||||||
|
case GL_PROXY_TEXTURE_1D:
|
||||||
|
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
|
||||||
|
if (width < 2 * border || width > 2 + maxSize ||
|
||||||
|
_mesa_bitcount(width - 2 * border) != 1 ||
|
||||||
|
level >= ctx->Const.MaxTextureLevels) {
|
||||||
|
/* bad width or level */
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
return GL_TRUE;
|
||||||
|
case GL_PROXY_TEXTURE_2D:
|
||||||
|
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
|
||||||
|
if (width < 2 * border || width > 2 + maxSize ||
|
||||||
|
_mesa_bitcount(width - 2 * border) != 1 ||
|
||||||
|
height < 2 * border || height > 2 + maxSize ||
|
||||||
|
_mesa_bitcount(height - 2 * border) != 1 ||
|
||||||
|
level >= ctx->Const.MaxTextureLevels) {
|
||||||
|
/* bad width or height or level */
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
return GL_TRUE;
|
||||||
|
case GL_PROXY_TEXTURE_3D:
|
||||||
|
maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
|
||||||
|
if (width < 2 * border || width > 2 + maxSize ||
|
||||||
|
_mesa_bitcount(width - 2 * border) != 1 ||
|
||||||
|
height < 2 * border || height > 2 + maxSize ||
|
||||||
|
_mesa_bitcount(height - 2 * border) != 1 ||
|
||||||
|
depth < 2 * border || depth > 2 + maxSize ||
|
||||||
|
_mesa_bitcount(depth - 2 * border) != 1 ||
|
||||||
|
level >= ctx->Const.Max3DTextureLevels) {
|
||||||
|
/* bad width or height or depth or level */
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
return GL_TRUE;
|
||||||
|
case GL_PROXY_TEXTURE_RECTANGLE_NV:
|
||||||
|
if (width < 1 || width > ctx->Const.MaxTextureRectSize ||
|
||||||
|
height < 1 || height > ctx->Const.MaxTextureRectSize ||
|
||||||
|
level != 0) {
|
||||||
|
/* bad width or height or level */
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
return GL_TRUE;
|
||||||
|
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
|
||||||
|
maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
|
||||||
|
if (width < 2 * border || width > 2 + maxSize ||
|
||||||
|
_mesa_bitcount(width - 2 * border) != 1 ||
|
||||||
|
height < 2 * border || height > 2 + maxSize ||
|
||||||
|
_mesa_bitcount(height - 2 * border) != 1 ||
|
||||||
|
level >= ctx->Const.MaxCubeTextureLevels) {
|
||||||
|
/* bad width or height */
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
return GL_TRUE;
|
||||||
|
default:
|
||||||
|
_mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
* Test glTexImage[123]D() parameters for errors.
|
* Test glTexImage[123]D() parameters for errors.
|
||||||
* Input:
|
* This function calls the ctx->Driver.TestProxyTexImage() function to
|
||||||
* dimensions - must be 1 or 2 or 3
|
* check the level and size.
|
||||||
* Return: GL_TRUE = an error was detected, GL_FALSE = no errors
|
* \param dimensions must be 1 or 2 or 3
|
||||||
|
* \return GL_TRUE if an error was detected or GL_FALSE if no errors
|
||||||
*/
|
*/
|
||||||
static GLboolean
|
static GLboolean
|
||||||
texture_error_check( GLcontext *ctx, GLenum target,
|
texture_error_check( GLcontext *ctx, GLenum target,
|
||||||
@@ -886,180 +977,11 @@ texture_error_check( GLcontext *ctx, GLenum target,
|
|||||||
GLint width, GLint height,
|
GLint width, GLint height,
|
||||||
GLint depth, GLint border )
|
GLint depth, GLint border )
|
||||||
{
|
{
|
||||||
GLboolean isProxy;
|
const GLboolean isProxy = is_proxy_target(target);
|
||||||
GLint maxLevels = 0, maxTextureSize;
|
GLboolean sizeOK;
|
||||||
|
|
||||||
if (dimensions == 1) {
|
/* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
|
||||||
if (target == GL_PROXY_TEXTURE_1D) {
|
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
|
||||||
isProxy = GL_TRUE;
|
|
||||||
}
|
|
||||||
else if (target == GL_TEXTURE_1D) {
|
|
||||||
isProxy = GL_FALSE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
maxLevels = ctx->Const.MaxTextureLevels;
|
|
||||||
}
|
|
||||||
else if (dimensions == 2) {
|
|
||||||
if (target == GL_PROXY_TEXTURE_2D) {
|
|
||||||
isProxy = GL_TRUE;
|
|
||||||
maxLevels = ctx->Const.MaxTextureLevels;
|
|
||||||
}
|
|
||||||
else if (target == GL_TEXTURE_2D) {
|
|
||||||
isProxy = GL_FALSE;
|
|
||||||
maxLevels = ctx->Const.MaxTextureLevels;
|
|
||||||
}
|
|
||||||
else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
|
|
||||||
if (!ctx->Extensions.ARB_texture_cube_map) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
isProxy = GL_TRUE;
|
|
||||||
maxLevels = ctx->Const.MaxCubeTextureLevels;
|
|
||||||
}
|
|
||||||
else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
|
||||||
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
|
|
||||||
if (!ctx->Extensions.ARB_texture_cube_map) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
isProxy = GL_FALSE;
|
|
||||||
maxLevels = ctx->Const.MaxCubeTextureLevels;
|
|
||||||
}
|
|
||||||
else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
|
|
||||||
if (!ctx->Extensions.NV_texture_rectangle) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
isProxy = GL_TRUE;
|
|
||||||
maxLevels = 1;
|
|
||||||
}
|
|
||||||
else if (target == GL_TEXTURE_RECTANGLE_NV) {
|
|
||||||
if (!ctx->Extensions.NV_texture_rectangle) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
isProxy = GL_FALSE;
|
|
||||||
maxLevels = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (dimensions == 3) {
|
|
||||||
if (target == GL_PROXY_TEXTURE_3D) {
|
|
||||||
isProxy = GL_TRUE;
|
|
||||||
}
|
|
||||||
else if (target == GL_TEXTURE_3D) {
|
|
||||||
isProxy = GL_FALSE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
maxLevels = ctx->Const.Max3DTextureLevels;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_mesa_problem( ctx, "bad dims in texture_error_check" );
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(maxLevels > 0);
|
|
||||||
maxTextureSize = 1 << (maxLevels - 1);
|
|
||||||
|
|
||||||
/* Border */
|
|
||||||
if (border != 0 && border != 1) {
|
|
||||||
if (!isProxy) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glTexImage%dD(border=%d)", dimensions, border);
|
|
||||||
}
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
if ((target == GL_TEXTURE_RECTANGLE_NV ||
|
|
||||||
target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0) {
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Width */
|
|
||||||
if (target == GL_TEXTURE_RECTANGLE_NV ||
|
|
||||||
target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
|
|
||||||
if (width < 1 || width > ctx->Const.MaxTextureRectSize) {
|
|
||||||
if (!isProxy) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glTexImage%dD(width=%d)", dimensions, width);
|
|
||||||
}
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (width < 2 * border || width > 2 + maxTextureSize
|
|
||||||
|| logbase2( width - 2 * border ) < 0) {
|
|
||||||
if (!isProxy) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glTexImage%dD(width=%d)", dimensions, width);
|
|
||||||
}
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Height */
|
|
||||||
if (target == GL_TEXTURE_RECTANGLE_NV ||
|
|
||||||
target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
|
|
||||||
if (height < 1 || height > ctx->Const.MaxTextureRectSize) {
|
|
||||||
if (!isProxy) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glTexImage%dD(height=%d)", dimensions, height);
|
|
||||||
}
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (dimensions >= 2) {
|
|
||||||
if (height < 2 * border || height > 2 + maxTextureSize
|
|
||||||
|| logbase2( height - 2 * border ) < 0) {
|
|
||||||
if (!isProxy) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glTexImage%dD(height=%d)", dimensions, height);
|
|
||||||
}
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For cube map, width must equal height */
|
|
||||||
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
|
||||||
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
|
|
||||||
if (width != height) {
|
|
||||||
if (!isProxy) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)");
|
|
||||||
}
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Depth */
|
|
||||||
if (dimensions >= 3) {
|
|
||||||
if (depth < 2 * border || depth > 2 + maxTextureSize
|
|
||||||
|| logbase2( depth - 2 * border ) < 0) {
|
|
||||||
if (!isProxy) {
|
|
||||||
_mesa_error( ctx, GL_INVALID_VALUE,
|
|
||||||
"glTexImage3D(depth=%d)", depth );
|
|
||||||
}
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Level */
|
|
||||||
if (target == GL_TEXTURE_RECTANGLE_NV ||
|
|
||||||
target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
|
|
||||||
if (level != 0) {
|
|
||||||
if (!isProxy) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glTexImage2D(level=%d)", level);
|
|
||||||
}
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (level < 0 || level >= maxLevels) {
|
|
||||||
if (!isProxy) {
|
if (!isProxy) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
"glTexImage%dD(level=%d)", dimensions, level);
|
"glTexImage%dD(level=%d)", dimensions, level);
|
||||||
@@ -1067,15 +989,95 @@ texture_error_check( GLcontext *ctx, GLenum target,
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For cube map, width must equal height */
|
/* Check border */
|
||||||
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
if (border < 0 || border > 1 ||
|
||||||
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
|
((target == GL_TEXTURE_RECTANGLE_NV ||
|
||||||
if (width != height) {
|
target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)");
|
if (!isProxy) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
|
"glTexImage%dD(border=%d)", dimensions, border);
|
||||||
|
}
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check target and call ctx->Driver.TestProxyTexImage() to check the
|
||||||
|
* level, width, height and depth.
|
||||||
|
*/
|
||||||
|
if (dimensions == 1) {
|
||||||
|
if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) {
|
||||||
|
sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D,
|
||||||
|
level, internalFormat,
|
||||||
|
format, type,
|
||||||
|
width, 1, 1, border);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (dimensions == 2) {
|
||||||
|
if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) {
|
||||||
|
sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D,
|
||||||
|
level, internalFormat,
|
||||||
|
format, type,
|
||||||
|
width, height, 1, border);
|
||||||
|
}
|
||||||
|
else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
|
||||||
|
(target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
||||||
|
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
|
||||||
|
if (!ctx->Extensions.ARB_texture_cube_map) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
sizeOK = (width == height) &&
|
||||||
|
ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB,
|
||||||
|
level, internalFormat, format, type,
|
||||||
|
width, height, 1, border);
|
||||||
|
}
|
||||||
|
else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
|
||||||
|
target == GL_TEXTURE_RECTANGLE_NV) {
|
||||||
|
if (!ctx->Extensions.NV_texture_rectangle) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
sizeOK = ctx->Driver.TestProxyTexImage(ctx,
|
||||||
|
GL_PROXY_TEXTURE_RECTANGLE_NV,
|
||||||
|
level, internalFormat,
|
||||||
|
format, type,
|
||||||
|
width, height, 1, border);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dimensions == 3) {
|
||||||
|
if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) {
|
||||||
|
sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_3D,
|
||||||
|
level, internalFormat,
|
||||||
|
format, type,
|
||||||
|
width, height, depth, border);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_mesa_problem( ctx, "bad dims in texture_error_check" );
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sizeOK) {
|
||||||
|
if (!isProxy) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
|
"glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
|
||||||
|
dimensions, level, width, height, depth);
|
||||||
|
}
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check internalFormat */
|
||||||
if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
|
if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
|
||||||
if (!isProxy) {
|
if (!isProxy) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
@@ -1085,6 +1087,7 @@ texture_error_check( GLcontext *ctx, GLenum target,
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check incoming image format and type */
|
||||||
if (!_mesa_is_legal_format_and_type(format, type)) {
|
if (!_mesa_is_legal_format_and_type(format, type)) {
|
||||||
/* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
|
/* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
|
||||||
* is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
|
* is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
|
||||||
@@ -1176,52 +1179,47 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
|
|||||||
{
|
{
|
||||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||||
struct gl_texture_image *destTex;
|
struct gl_texture_image *destTex;
|
||||||
GLint maxLevels = 0;
|
|
||||||
|
|
||||||
|
/* Check target */
|
||||||
if (dimensions == 1) {
|
if (dimensions == 1) {
|
||||||
if (target == GL_TEXTURE_1D) {
|
if (target != GL_TEXTURE_1D) {
|
||||||
maxLevels = ctx->Const.MaxTextureLevels;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dimensions == 2) {
|
else if (dimensions == 2) {
|
||||||
if (ctx->Extensions.ARB_texture_cube_map &&
|
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
||||||
target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
|
||||||
target <=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
|
target <=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
|
||||||
maxLevels = ctx->Const.MaxCubeTextureLevels;
|
if (!ctx->Extensions.ARB_texture_cube_map) {
|
||||||
|
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (ctx->Extensions.NV_texture_rectangle &&
|
else if (ctx->Extensions.NV_texture_rectangle &&
|
||||||
target == GL_TEXTURE_RECTANGLE_NV) {
|
target == GL_TEXTURE_RECTANGLE_NV) {
|
||||||
maxLevels = 1;
|
if (!ctx->Extensions.NV_texture_rectangle) {
|
||||||
|
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (target == GL_TEXTURE_2D) {
|
else if (target != GL_TEXTURE_2D) {
|
||||||
maxLevels = ctx->Const.MaxTextureLevels;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dimensions == 3) {
|
else if (dimensions == 3) {
|
||||||
if (target == GL_TEXTURE_3D) {
|
if (target != GL_TEXTURE_3D) {
|
||||||
maxLevels = ctx->Const.Max3DTextureLevels;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_mesa_problem( ctx, "bad dims in texture_error_check" );
|
_mesa_problem( ctx, "invalid dims in texture_error_check" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(maxLevels > 0);
|
/* Basic level check */
|
||||||
|
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
|
||||||
if (level < 0 || level >= maxLevels) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
|
_mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
@@ -1237,32 +1235,38 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
if (depth < 0 && dimensions > 2) {
|
if (depth < 0 && dimensions > 2) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(depth=%d)", dimensions, depth);
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
|
"glTexSubImage%dD(depth=%d)", dimensions, depth);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
destTex = _mesa_select_tex_image(ctx, texUnit, target, level);
|
destTex = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||||
|
|
||||||
if (!destTex) {
|
if (!destTex) {
|
||||||
_mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage2D");
|
/* undefined image level */
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xoffset < -((GLint)destTex->Border)) {
|
if (xoffset < -((GLint)destTex->Border)) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset)");
|
_mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
|
||||||
|
dimensions);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
|
if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset+width)");
|
_mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
|
||||||
|
dimensions);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
if (dimensions > 1) {
|
if (dimensions > 1) {
|
||||||
if (yoffset < -((GLint)destTex->Border)) {
|
if (yoffset < -((GLint)destTex->Border)) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset)");
|
_mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
|
||||||
|
dimensions);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
|
if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset+height)");
|
_mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
|
||||||
|
dimensions);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1336,82 +1340,93 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
|
|||||||
GLenum target, GLint level, GLint internalFormat,
|
GLenum target, GLint level, GLint internalFormat,
|
||||||
GLint width, GLint height, GLint border )
|
GLint width, GLint height, GLint border )
|
||||||
{
|
{
|
||||||
GLint maxLevels = 0, maxTextureSize;
|
GLenum format, type;
|
||||||
|
GLboolean sizeOK;
|
||||||
|
|
||||||
|
/* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
|
||||||
|
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
|
"glCopyTexImage%dD(level=%d)", dimensions, level);
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check border */
|
||||||
|
if (border < 0 || border > 1 ||
|
||||||
|
((target == GL_TEXTURE_RECTANGLE_NV ||
|
||||||
|
target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The format and type aren't really significant here, but we need to pass
|
||||||
|
* something to TestProxyTexImage().
|
||||||
|
*/
|
||||||
|
format = _mesa_base_tex_format(ctx, internalFormat);
|
||||||
|
type = GL_FLOAT;
|
||||||
|
|
||||||
|
/* Check target and call ctx->Driver.TestProxyTexImage() to check the
|
||||||
|
* level, width, height and depth.
|
||||||
|
*/
|
||||||
if (dimensions == 1) {
|
if (dimensions == 1) {
|
||||||
if (target != GL_TEXTURE_1D) {
|
if (target == GL_TEXTURE_1D) {
|
||||||
|
sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D,
|
||||||
|
level, internalFormat,
|
||||||
|
format, type,
|
||||||
|
width, 1, 1, border);
|
||||||
|
}
|
||||||
|
else {
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
maxLevels = ctx->Const.MaxTextureLevels;
|
|
||||||
}
|
}
|
||||||
else if (dimensions == 2) {
|
else if (dimensions == 2) {
|
||||||
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
if (target == GL_TEXTURE_2D) {
|
||||||
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
|
sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D,
|
||||||
|
level, internalFormat,
|
||||||
|
format, type,
|
||||||
|
width, height, 1, border);
|
||||||
|
}
|
||||||
|
else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
||||||
|
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
|
||||||
if (!ctx->Extensions.ARB_texture_cube_map) {
|
if (!ctx->Extensions.ARB_texture_cube_map) {
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
sizeOK = (width == height) &&
|
||||||
|
ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB,
|
||||||
|
level, internalFormat, format, type,
|
||||||
|
width, height, 1, border);
|
||||||
}
|
}
|
||||||
else if (target == GL_TEXTURE_RECTANGLE_NV) {
|
else if (target == GL_TEXTURE_RECTANGLE_NV) {
|
||||||
if (!ctx->Extensions.NV_texture_rectangle) {
|
if (!ctx->Extensions.NV_texture_rectangle) {
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
sizeOK = ctx->Driver.TestProxyTexImage(ctx,
|
||||||
|
GL_PROXY_TEXTURE_RECTANGLE_NV,
|
||||||
|
level, internalFormat,
|
||||||
|
format, type,
|
||||||
|
width, height, 1, border);
|
||||||
}
|
}
|
||||||
else if (target != GL_TEXTURE_2D) {
|
else {
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
if (target == GL_TEXTURE_2D)
|
|
||||||
maxLevels = ctx->Const.MaxTextureLevels;
|
|
||||||
else if (target == GL_TEXTURE_RECTANGLE_NV)
|
|
||||||
maxLevels = 1;
|
|
||||||
else
|
|
||||||
maxLevels = ctx->Const.MaxCubeTextureLevels;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
ASSERT(maxLevels > 0);
|
_mesa_problem(ctx, "invalid dimensions in copytexture_error_check");
|
||||||
maxTextureSize = 1 << (maxLevels - 1);
|
|
||||||
|
|
||||||
/* Border */
|
|
||||||
if (border != 0 && border != 1) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glCopyTexImage%dD(border)", dimensions);
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Width */
|
if (!sizeOK) {
|
||||||
if (width < 2 * border || width > 2 + maxTextureSize
|
if (dimensions == 1) {
|
||||||
|| logbase2( width - 2 * border ) < 0) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glCopyTexImage%dD(width=%d)", dimensions, width);
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Height */
|
|
||||||
if (dimensions >= 2) {
|
|
||||||
if (height < 2 * border || height > 2 + maxTextureSize
|
|
||||||
|| logbase2( height - 2 * border ) < 0) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
"glCopyTexImage%dD(height=%d)", dimensions, height);
|
"glCopyTexImage1D(width=%d)", width);
|
||||||
return GL_TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
ASSERT(dimensions == 2);
|
||||||
/* For cube map, width must equal height */
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
"glCopyTexImage2D(width=%d, height=%d)", width, height);
|
||||||
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
|
|
||||||
if (width != height) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width != height)");
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Level */
|
|
||||||
if (level < 0 || level >= maxLevels) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glCopyTexImage%dD(level=%d)", dimensions, level);
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1447,14 +1462,13 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
|
|||||||
{
|
{
|
||||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||||
struct gl_texture_image *teximage;
|
struct gl_texture_image *teximage;
|
||||||
GLint maxLevels = 0;
|
|
||||||
|
|
||||||
|
/* Check target */
|
||||||
if (dimensions == 1) {
|
if (dimensions == 1) {
|
||||||
if (target != GL_TEXTURE_1D) {
|
if (target != GL_TEXTURE_1D) {
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
maxLevels = ctx->Const.MaxTextureLevels;
|
|
||||||
}
|
}
|
||||||
else if (dimensions == 2) {
|
else if (dimensions == 2) {
|
||||||
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
|
||||||
@@ -1474,29 +1488,22 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
|
|||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
if (target == GL_TEXTURE_2D)
|
|
||||||
maxLevels = ctx->Const.MaxTextureLevels;
|
|
||||||
else if (target == GL_TEXTURE_RECTANGLE_NV)
|
|
||||||
maxLevels = 1;
|
|
||||||
else
|
|
||||||
maxLevels = ctx->Const.MaxCubeTextureLevels;
|
|
||||||
}
|
}
|
||||||
else if (dimensions == 3) {
|
else if (dimensions == 3) {
|
||||||
if (target != GL_TEXTURE_3D) {
|
if (target != GL_TEXTURE_3D) {
|
||||||
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" );
|
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" );
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
maxLevels = ctx->Const.Max3DTextureLevels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(maxLevels > 0);
|
/* Check level */
|
||||||
|
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
|
||||||
if (level < 0 || level >= maxLevels) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
"glCopyTexSubImage%dD(level=%d)", dimensions, level);
|
"glCopyTexSubImage%dD(level=%d)", dimensions, level);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check size */
|
||||||
if (width < 0) {
|
if (width < 0) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
"glCopyTexSubImage%dD(width=%d)", dimensions, width);
|
"glCopyTexSubImage%dD(width=%d)", dimensions, width);
|
||||||
@@ -1792,30 +1799,22 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
|
|||||||
}
|
}
|
||||||
else if (target == GL_PROXY_TEXTURE_1D) {
|
else if (target == GL_PROXY_TEXTURE_1D) {
|
||||||
/* Proxy texture: check for errors and update proxy state */
|
/* Proxy texture: check for errors and update proxy state */
|
||||||
GLboolean error = texture_error_check(ctx, target, level, internalFormat,
|
struct gl_texture_image *texImage;
|
||||||
format, type, 1, postConvWidth, 1, 1, border);
|
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
||||||
if (!error) {
|
if (texture_error_check(ctx, target, level, internalFormat,
|
||||||
ASSERT(ctx->Driver.TestProxyTexImage);
|
format, type, 1, postConvWidth, 1, 1, border)) {
|
||||||
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
|
/* when error, clear all proxy texture image parameters */
|
||||||
internalFormat, format, type,
|
|
||||||
postConvWidth, 1, 1, border);
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
/* if error, clear all proxy texture image parameters */
|
|
||||||
struct gl_texture_image *texImage;
|
|
||||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
|
||||||
if (texImage)
|
if (texImage)
|
||||||
clear_teximage_fields(texImage);
|
clear_teximage_fields(texImage);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* no error, set the tex image parameters */
|
/* no error, set the tex image parameters */
|
||||||
struct gl_texture_unit *texUnit;
|
ASSERT(texImage);
|
||||||
struct gl_texture_image *texImage;
|
|
||||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
|
||||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
|
||||||
_mesa_init_teximage_fields(ctx, target, texImage,
|
_mesa_init_teximage_fields(ctx, target, texImage,
|
||||||
postConvWidth, 1, 1,
|
postConvWidth, 1, 1,
|
||||||
border, internalFormat);
|
border, internalFormat);
|
||||||
|
texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
|
||||||
|
internalFormat, format, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1901,30 +1900,22 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
|
|||||||
(target == GL_PROXY_TEXTURE_RECTANGLE_NV &&
|
(target == GL_PROXY_TEXTURE_RECTANGLE_NV &&
|
||||||
ctx->Extensions.NV_texture_rectangle)) {
|
ctx->Extensions.NV_texture_rectangle)) {
|
||||||
/* Proxy texture: check for errors and update proxy state */
|
/* Proxy texture: check for errors and update proxy state */
|
||||||
GLboolean error = texture_error_check(ctx, target, level, internalFormat,
|
struct gl_texture_image *texImage;
|
||||||
format, type, 2, postConvWidth, postConvHeight, 1, border);
|
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
||||||
if (!error) {
|
if (texture_error_check(ctx, target, level, internalFormat,
|
||||||
ASSERT(ctx->Driver.TestProxyTexImage);
|
format, type, 2, postConvWidth, postConvHeight,
|
||||||
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
|
1, border)) {
|
||||||
internalFormat, format, type,
|
/* when error, clear all proxy texture image parameters */
|
||||||
postConvWidth, postConvHeight, 1, border);
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
/* if error, clear all proxy texture image parameters */
|
|
||||||
struct gl_texture_image *texImage;
|
|
||||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
|
||||||
if (texImage)
|
if (texImage)
|
||||||
clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
|
clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* no error, set the tex image parameters */
|
/* no error, set the tex image parameters */
|
||||||
struct gl_texture_unit *texUnit;
|
|
||||||
struct gl_texture_image *texImage;
|
|
||||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
|
||||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
|
||||||
_mesa_init_teximage_fields(ctx, target, texImage,
|
_mesa_init_teximage_fields(ctx, target, texImage,
|
||||||
postConvWidth, postConvHeight, 1,
|
postConvWidth, postConvHeight, 1,
|
||||||
border, internalFormat);
|
border, internalFormat);
|
||||||
|
texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
|
||||||
|
internalFormat, format, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1996,29 +1987,20 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
|
|||||||
}
|
}
|
||||||
else if (target == GL_PROXY_TEXTURE_3D) {
|
else if (target == GL_PROXY_TEXTURE_3D) {
|
||||||
/* Proxy texture: check for errors and update proxy state */
|
/* Proxy texture: check for errors and update proxy state */
|
||||||
GLboolean error = texture_error_check(ctx, target, level, internalFormat,
|
struct gl_texture_image *texImage;
|
||||||
format, type, 3, width, height, depth, border);
|
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
||||||
if (!error) {
|
if (texture_error_check(ctx, target, level, internalFormat,
|
||||||
ASSERT(ctx->Driver.TestProxyTexImage);
|
format, type, 3, width, height, depth, border)) {
|
||||||
error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
|
/* when error, clear all proxy texture image parameters */
|
||||||
internalFormat, format, type,
|
|
||||||
width, height, depth, border);
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
/* if error, clear all proxy texture image parameters */
|
|
||||||
struct gl_texture_image *texImage;
|
|
||||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
|
||||||
if (texImage)
|
if (texImage)
|
||||||
clear_teximage_fields(texImage);
|
clear_teximage_fields(texImage);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* no error, set the tex image parameters */
|
/* no error, set the tex image parameters */
|
||||||
struct gl_texture_unit *texUnit;
|
|
||||||
struct gl_texture_image *texImage;
|
|
||||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
|
||||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
|
||||||
_mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
|
_mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
|
||||||
border, internalFormat);
|
border, internalFormat);
|
||||||
|
texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
|
||||||
|
internalFormat, format, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
/* $Id: teximage.h,v 1.23 2003/04/01 16:41:54 brianp Exp $ */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
* Version: 3.5
|
* Version: 5.1
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
|
* Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -83,6 +81,11 @@ extern GLint
|
|||||||
_mesa_max_texture_levels(GLcontext *ctx, GLenum target);
|
_mesa_max_texture_levels(GLcontext *ctx, GLenum target);
|
||||||
|
|
||||||
|
|
||||||
|
extern GLboolean
|
||||||
|
_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint internalFormat, GLenum format, GLenum type,
|
||||||
|
GLint width, GLint height, GLint depth, GLint border);
|
||||||
|
|
||||||
/*** API entry point functions ***/
|
/*** API entry point functions ***/
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
/* $Id: texstore.c,v 1.55 2003/04/01 16:41:55 brianp Exp $ */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
* Version: 5.1
|
* Version: 5.1
|
||||||
@@ -1264,40 +1262,6 @@ _mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the fallback for Driver.TestProxyTexImage().
|
|
||||||
*/
|
|
||||||
GLboolean
|
|
||||||
_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
|
|
||||||
GLint internalFormat, GLenum format, GLenum type,
|
|
||||||
GLint width, GLint height, GLint depth, GLint border)
|
|
||||||
{
|
|
||||||
struct gl_texture_image *texImage;
|
|
||||||
|
|
||||||
(void) format;
|
|
||||||
(void) type;
|
|
||||||
|
|
||||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
|
||||||
|
|
||||||
/* We always pass.
|
|
||||||
* The core Mesa code will have already tested the image size, etc.
|
|
||||||
* If a driver has more stringent texture limits to enforce it will
|
|
||||||
* have to override this function.
|
|
||||||
*/
|
|
||||||
/* choose the texture format */
|
|
||||||
assert(ctx->Driver.ChooseTextureFormat);
|
|
||||||
texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
|
|
||||||
internalFormat, format, type);
|
|
||||||
assert(texImage->TexFormat);
|
|
||||||
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Average together two rows of a source image to produce a single new
|
* Average together two rows of a source image to produce a single new
|
||||||
* row in the dest image. It's legal for the two source rows to point
|
* row in the dest image. It's legal for the two source rows to point
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
/* $Id: texstore.h,v 1.11 2002/09/27 02:45:38 brianp Exp $ */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
* Version: 4.1
|
* Version: 5.1
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
|
* Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -165,12 +163,6 @@ _mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
|
|||||||
struct gl_texture_image *texImage);
|
struct gl_texture_image *texImage);
|
||||||
|
|
||||||
|
|
||||||
extern GLboolean
|
|
||||||
_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
|
|
||||||
GLint internalFormat, GLenum format, GLenum type,
|
|
||||||
GLint width, GLint height, GLint depth, GLint border);
|
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
|
_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
|
||||||
const struct gl_texture_unit *texUnit,
|
const struct gl_texture_unit *texUnit,
|
||||||
|
Reference in New Issue
Block a user