mesa: raise max texture sizes to 16K
This allows 16K x 16K 2D textures, for example, but we don't want to allow that for 3D textures. The new gl_constants::MaxTextureMBytes field is used to prevent allocating too large of texture image. This allows a 16K x 32 x 32 3D texture, for example, but prevents 16K^3. Drivers can override this limit. The default is currently 1GB. Apps should use the proxy texture mechanism to determine the actual max texture size.
This commit is contained in:
parent
23390e2f5c
commit
4b08f35487
|
@ -97,17 +97,20 @@
|
|||
/** Max texture palette / color table size */
|
||||
#define MAX_COLOR_TABLE_SIZE 256
|
||||
|
||||
/** Max memory to allow for a single texture image (in megabytes) */
|
||||
#define MAX_TEXTURE_MBYTES 1024
|
||||
|
||||
/** Number of 1D/2D texture mipmap levels */
|
||||
#define MAX_TEXTURE_LEVELS 13
|
||||
#define MAX_TEXTURE_LEVELS 15
|
||||
|
||||
/** Number of 3D texture mipmap levels */
|
||||
#define MAX_3D_TEXTURE_LEVELS 9
|
||||
#define MAX_3D_TEXTURE_LEVELS 15
|
||||
|
||||
/** Number of cube texture mipmap levels - GL_ARB_texture_cube_map */
|
||||
#define MAX_CUBE_TEXTURE_LEVELS 13
|
||||
#define MAX_CUBE_TEXTURE_LEVELS 15
|
||||
|
||||
/** Maximum rectangular texture size - GL_NV_texture_rectangle */
|
||||
#define MAX_TEXTURE_RECT_SIZE 4096
|
||||
#define MAX_TEXTURE_RECT_SIZE 16384
|
||||
|
||||
/** Maximum number of layers in a 1D or 2D array texture - GL_MESA_texture_array */
|
||||
#define MAX_ARRAY_TEXTURE_LAYERS 64
|
||||
|
@ -140,11 +143,11 @@
|
|||
*/
|
||||
|
||||
#ifndef MAX_WIDTH
|
||||
# define MAX_WIDTH 4096
|
||||
# define MAX_WIDTH 16384
|
||||
#endif
|
||||
/** Maximum viewport/image height */
|
||||
#ifndef MAX_HEIGHT
|
||||
# define MAX_HEIGHT 4096
|
||||
# define MAX_HEIGHT 16384
|
||||
#endif
|
||||
|
||||
/** Maxmimum size for CVA. May be overridden by the drivers. */
|
||||
|
@ -168,7 +171,7 @@
|
|||
#define MAX_TEXTURE_MAX_ANISOTROPY 16.0
|
||||
|
||||
/** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */
|
||||
#define MAX_TEXTURE_LOD_BIAS 12.0
|
||||
#define MAX_TEXTURE_LOD_BIAS 14.0
|
||||
|
||||
/** For any program target/extension */
|
||||
/*@{*/
|
||||
|
|
|
@ -535,6 +535,7 @@ _mesa_init_constants(struct gl_context *ctx)
|
|||
assert(ctx);
|
||||
|
||||
/* Constants, may be overriden (usually only reduced) by device drivers */
|
||||
ctx->Const.MaxTextureMbytes = MAX_TEXTURE_MBYTES;
|
||||
ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
|
||||
ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
|
||||
ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
|
||||
|
|
|
@ -2567,6 +2567,7 @@ struct gl_program_constants
|
|||
*/
|
||||
struct gl_constants
|
||||
{
|
||||
GLint MaxTextureMbytes; /**< Max memory per image, in MB */
|
||||
GLint MaxTextureLevels; /**< Max mipmap levels. */
|
||||
GLint Max3DTextureLevels; /**< Max mipmap levels for 3D textures */
|
||||
GLint MaxCubeTextureLevels; /**< Max mipmap levels for cube textures */
|
||||
|
|
|
@ -1273,6 +1273,24 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the memory used by the texture would exceed the driver's limit.
|
||||
* This lets us support a max 3D texture size of 8K (for example) but
|
||||
* prevents allocating a full 8K x 8K x 8K texture.
|
||||
* XXX this could be rolled into the proxy texture size test (above) but
|
||||
* we don't have the actual texture internal format at that point.
|
||||
*/
|
||||
static GLboolean
|
||||
legal_texture_size(struct gl_context *ctx, gl_format format,
|
||||
GLint width, GLint height, GLint depth)
|
||||
{
|
||||
uint64_t bytes = _mesa_format_image_size64(format, width, height, depth);
|
||||
uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */
|
||||
return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to determine whether a target supports compressed textures
|
||||
*/
|
||||
|
@ -2392,6 +2410,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
|
|||
internalFormat, format,
|
||||
type);
|
||||
|
||||
if (legal_texture_size(ctx, texFormat, width, 1, 1)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage,
|
||||
width, 1, 1,
|
||||
border, internalFormat,
|
||||
|
@ -2411,6 +2430,10 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
|
|||
texObj->_Complete = GL_FALSE;
|
||||
ctx->NewState |= _NEW_TEXTURE;
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
|
||||
}
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
|
@ -2432,9 +2455,14 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
|
|||
level,
|
||||
internalFormat,
|
||||
format, type);
|
||||
if (legal_texture_size(ctx, texFormat, width, 1, 1)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
|
||||
border, internalFormat, texFormat);
|
||||
}
|
||||
else if (texImage) {
|
||||
clear_teximage_fields(texImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
|
||||
|
@ -2502,8 +2530,10 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
|
|||
internalFormat, format,
|
||||
type);
|
||||
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
|
||||
border, internalFormat, texFormat);
|
||||
if (legal_texture_size(ctx, texFormat, width, height, 1)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width,
|
||||
height, 1, border, internalFormat,
|
||||
texFormat);
|
||||
|
||||
/* Give the texture to the driver. <pixels> may be null. */
|
||||
ASSERT(ctx->Driver.TexImage2D);
|
||||
|
@ -2519,6 +2549,10 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
|
|||
texObj->_Complete = GL_FALSE;
|
||||
ctx->NewState |= _NEW_TEXTURE;
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
|
||||
}
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
|
@ -2546,9 +2580,14 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
|
|||
target, level,
|
||||
internalFormat,
|
||||
format, type);
|
||||
if (legal_texture_size(ctx, texFormat, width, 1, 1)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
|
||||
border, internalFormat, texFormat);
|
||||
}
|
||||
else if (texImage) {
|
||||
clear_teximage_fields(texImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
|
||||
|
@ -2613,6 +2652,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
|
|||
texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
|
||||
internalFormat, format,
|
||||
type);
|
||||
|
||||
if (legal_texture_size(ctx, texFormat, width, height, depth)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage,
|
||||
width, height, depth,
|
||||
border, internalFormat, texFormat);
|
||||
|
@ -2620,8 +2661,9 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
|
|||
/* Give the texture to the driver. <pixels> may be null. */
|
||||
ASSERT(ctx->Driver.TexImage3D);
|
||||
ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
|
||||
width, height, depth, border, format, type,
|
||||
pixels, &ctx->Unpack, texObj, texImage);
|
||||
width, height, depth, border, format,
|
||||
type, pixels, &ctx->Unpack, texObj,
|
||||
texImage);
|
||||
|
||||
check_gen_mipmap(ctx, target, texObj, level);
|
||||
|
||||
|
@ -2631,6 +2673,10 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
|
|||
texObj->_Complete = GL_FALSE;
|
||||
ctx->NewState |= _NEW_TEXTURE;
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
|
||||
}
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
|
@ -2654,8 +2700,14 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
|
|||
target, level,
|
||||
internalFormat,
|
||||
format, type);
|
||||
if (legal_texture_size(ctx, texFormat, width, height, depth)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, height,
|
||||
depth, border, internalFormat, texFormat);
|
||||
depth, border, internalFormat,
|
||||
texFormat);
|
||||
}
|
||||
else if (texImage) {
|
||||
clear_teximage_fields(texImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -2944,6 +2996,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
|
|||
internalFormat, GL_NONE,
|
||||
GL_NONE);
|
||||
|
||||
if (legal_texture_size(ctx, texFormat, width, 1, 1)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
|
||||
border, internalFormat, texFormat);
|
||||
|
||||
|
@ -2959,6 +3012,10 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
|
|||
texObj->_Complete = GL_FALSE;
|
||||
ctx->NewState |= _NEW_TEXTURE;
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
|
||||
}
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
|
@ -3011,6 +3068,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
|
|||
internalFormat, GL_NONE,
|
||||
GL_NONE);
|
||||
|
||||
if (legal_texture_size(ctx, texFormat, width, height, 1)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
|
||||
border, internalFormat, texFormat);
|
||||
|
||||
|
@ -3026,6 +3084,10 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
|
|||
texObj->_Complete = GL_FALSE;
|
||||
ctx->NewState |= _NEW_TEXTURE;
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
|
||||
}
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
|
@ -3510,6 +3572,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
|
|||
internalFormat, GL_NONE,
|
||||
GL_NONE);
|
||||
|
||||
if (legal_texture_size(ctx, texFormat, width, 1, 1)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
|
||||
border, internalFormat, texFormat);
|
||||
|
||||
|
@ -3525,6 +3588,10 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
|
|||
texObj->_Complete = GL_FALSE;
|
||||
ctx->NewState |= _NEW_TEXTURE;
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
|
||||
}
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
|
@ -3559,9 +3626,14 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
|
|||
texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
|
||||
internalFormat, GL_NONE,
|
||||
GL_NONE);
|
||||
if (legal_texture_size(ctx, texFormat, width, 1, 1)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
|
||||
border, internalFormat, texFormat);
|
||||
}
|
||||
else if (texImage) {
|
||||
clear_teximage_fields(texImage);
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
}
|
||||
|
@ -3639,8 +3711,10 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
|
|||
internalFormat, GL_NONE,
|
||||
GL_NONE);
|
||||
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
|
||||
border, internalFormat, texFormat);
|
||||
if (legal_texture_size(ctx, texFormat, width, 1, 1)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width,
|
||||
height, 1, border, internalFormat,
|
||||
texFormat);
|
||||
|
||||
ASSERT(ctx->Driver.CompressedTexImage2D);
|
||||
ctx->Driver.CompressedTexImage2D(ctx, target, level,
|
||||
|
@ -3654,6 +3728,10 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
|
|||
texObj->_Complete = GL_FALSE;
|
||||
ctx->NewState |= _NEW_TEXTURE;
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
|
||||
}
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
|
@ -3690,8 +3768,14 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
|
|||
texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
|
||||
internalFormat, GL_NONE,
|
||||
GL_NONE);
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
|
||||
border, internalFormat, texFormat);
|
||||
if (legal_texture_size(ctx, texFormat, width, height, 1)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width,
|
||||
height, 1, border, internalFormat,
|
||||
texFormat);
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
|
@ -3749,6 +3833,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
|
|||
internalFormat, GL_NONE,
|
||||
GL_NONE);
|
||||
|
||||
if (legal_texture_size(ctx, texFormat, width, height, depth)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage,
|
||||
width, height, depth,
|
||||
border, internalFormat, texFormat);
|
||||
|
@ -3766,6 +3851,10 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
|
|||
texObj->_Complete = GL_FALSE;
|
||||
ctx->NewState |= _NEW_TEXTURE;
|
||||
}
|
||||
else {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
|
||||
}
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
|
@ -3800,10 +3889,15 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
|
|||
texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
|
||||
internalFormat, GL_NONE,
|
||||
GL_NONE);
|
||||
if (legal_texture_size(ctx, texFormat, width, height, depth)) {
|
||||
_mesa_init_teximage_fields(ctx, target, texImage, width, height,
|
||||
depth, border, internalFormat,
|
||||
texFormat);
|
||||
}
|
||||
else if (texImage) {
|
||||
clear_teximage_fields(texImage);
|
||||
}
|
||||
}
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue