summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/teximage.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/teximage.c')
-rw-r--r--src/mesa/main/teximage.c2101
1 files changed, 857 insertions, 1244 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index b65a2de046e..1e8626c7346 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -40,6 +40,7 @@
#include "image.h"
#include "imports.h"
#include "macros.h"
+#include "mfeatures.h"
#include "state.h"
#include "texcompress.h"
#include "texfetch.h"
@@ -340,11 +341,11 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
return GL_RGBA;
case GL_SLUMINANCE_ALPHA_EXT:
case GL_SLUMINANCE8_ALPHA8_EXT:
- case GL_COMPRESSED_SLUMINANCE_EXT:
case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
return GL_LUMINANCE_ALPHA;
case GL_SLUMINANCE_EXT:
case GL_SLUMINANCE8_EXT:
+ case GL_COMPRESSED_SLUMINANCE_EXT:
return GL_LUMINANCE;
default:
; /* fallthrough */
@@ -596,7 +597,8 @@ _mesa_free_texture_image_data(struct gl_context *ctx,
* Free the texture image structure and the associated image data.
*/
void
-_mesa_delete_texture_image( struct gl_context *ctx, struct gl_texture_image *texImage )
+_mesa_delete_texture_image(struct gl_context *ctx,
+ struct gl_texture_image *texImage)
{
/* Free texImage->Data and/or any other driver-specific texture
* image storage.
@@ -635,7 +637,49 @@ _mesa_is_proxy_texture(GLenum target)
/**
- * Get the texture object that corresponds to the target of the given texture unit.
+ * Return the proxy target which corresponds to the given texture target
+ */
+static GLenum
+get_proxy_target(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_PROXY_TEXTURE_1D:
+ return GL_PROXY_TEXTURE_1D;
+ case GL_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_2D:
+ return GL_PROXY_TEXTURE_2D;
+ case GL_TEXTURE_3D:
+ case GL_PROXY_TEXTURE_3D:
+ return GL_PROXY_TEXTURE_3D;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ return GL_PROXY_TEXTURE_CUBE_MAP_ARB;
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ return GL_PROXY_TEXTURE_RECTANGLE_NV;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
+ return GL_PROXY_TEXTURE_1D_ARRAY_EXT;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+ return GL_PROXY_TEXTURE_2D_ARRAY_EXT;
+ default:
+ _mesa_problem(NULL, "unexpected target in get_proxy_target()");
+ return 0;
+ }
+}
+
+
+/**
+ * Get the texture object that corresponds to the target of the given
+ * texture unit.
*
* \param ctx GL context.
* \param texUnit texture unit.
@@ -646,7 +690,8 @@ _mesa_is_proxy_texture(GLenum target)
* \sa gl_texture_unit.
*/
struct gl_texture_object *
-_mesa_select_tex_object(struct gl_context *ctx, const struct gl_texture_unit *texUnit,
+_mesa_select_tex_object(struct gl_context *ctx,
+ const struct gl_texture_unit *texUnit,
GLenum target)
{
switch (target) {
@@ -723,7 +768,8 @@ _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target)
* \return pointer to the texture image structure, or NULL on failure.
*/
struct gl_texture_image *
-_mesa_select_tex_image(struct gl_context *ctx, const struct gl_texture_object *texObj,
+_mesa_select_tex_image(struct gl_context *ctx,
+ const struct gl_texture_object *texObj,
GLenum target, GLint level)
{
const GLuint face = _mesa_tex_target_to_face(target);
@@ -883,6 +929,45 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
}
+/**
+ * Return number of dimensions per mipmap level for the given texture target.
+ */
+static GLint
+get_texture_dimensions(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_PROXY_TEXTURE_1D:
+ return 1;
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_PROXY_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_RECTANGLE:
+ case GL_PROXY_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ case GL_TEXTURE_1D_ARRAY:
+ case GL_PROXY_TEXTURE_1D_ARRAY:
+ return 2;
+ case GL_TEXTURE_3D:
+ case GL_PROXY_TEXTURE_3D:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_PROXY_TEXTURE_2D_ARRAY:
+ return 3;
+ default:
+ _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()",
+ target);
+ return 2;
+ }
+}
+
+
+
#if 000 /* not used anymore */
/*
@@ -988,6 +1073,7 @@ clear_teximage_fields(struct gl_texture_image *img)
* \param depth image depth.
* \param border image border.
* \param internalFormat internal format.
+ * \param format the actual hardware format (one of MESA_FORMAT_*)
*
* Fills in the fields of \p img with the given information.
* Note: width, height and depth include the border.
@@ -996,9 +1082,10 @@ void
_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
struct gl_texture_image *img,
GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum internalFormat)
+ GLint border, GLenum internalFormat,
+ gl_format format)
{
- GLint i;
+ GLint i, dims;
ASSERT(img);
ASSERT(width >= 0);
@@ -1069,8 +1156,11 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
img->DepthScale = (GLfloat) img->Depth;
}
- img->FetchTexelc = NULL;
- img->FetchTexelf = NULL;
+ img->TexFormat = format;
+
+ dims = get_texture_dimensions(target);
+
+ _mesa_set_fetch_functions(img, dims);
}
@@ -1084,7 +1174,8 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
* fields are cleared so that its parent object will test incomplete.
*/
void
-_mesa_clear_texture_image(struct gl_context *ctx, struct gl_texture_image *texImage)
+_mesa_clear_texture_image(struct gl_context *ctx,
+ struct gl_texture_image *texImage)
{
ctx->Driver.FreeTexImageData(ctx, texImage);
clear_teximage_fields(texImage);
@@ -1129,94 +1220,110 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
switch (target) {
case GL_PROXY_TEXTURE_1D:
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
- if (width < 2 * border || width > 2 + maxSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- width >0 && !_mesa_is_pow_two(width - 2 * border)) ||
- level >= ctx->Const.MaxTextureLevels) {
- /* bad width or level */
+ if (width < 2 * border || width > 2 + maxSize)
return GL_FALSE;
+ if (level >= ctx->Const.MaxTextureLevels)
+ return GL_FALSE;
+ if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+ if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+ return GL_FALSE;
}
return GL_TRUE;
+
case GL_PROXY_TEXTURE_2D:
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
- if (width < 2 * border || width > 2 + maxSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
- height < 2 * border || height > 2 + maxSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
- level >= ctx->Const.MaxTextureLevels) {
- /* bad width or height or level */
+ if (width < 2 * border || width > 2 + maxSize)
return GL_FALSE;
+ if (height < 2 * border || height > 2 + maxSize)
+ return GL_FALSE;
+ if (level >= ctx->Const.MaxTextureLevels)
+ return GL_FALSE;
+ if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+ if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+ return GL_FALSE;
+ if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
+ return GL_FALSE;
}
return GL_TRUE;
+
case GL_PROXY_TEXTURE_3D:
maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
- if (width < 2 * border || width > 2 + maxSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
- height < 2 * border || height > 2 + maxSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
- depth < 2 * border || depth > 2 + maxSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) ||
- level >= ctx->Const.Max3DTextureLevels) {
- /* bad width or height or depth or level */
+ if (width < 2 * border || width > 2 + maxSize)
+ return GL_FALSE;
+ if (height < 2 * border || height > 2 + maxSize)
+ return GL_FALSE;
+ if (depth < 2 * border || depth > 2 + maxSize)
+ return GL_FALSE;
+ if (level >= ctx->Const.Max3DTextureLevels)
return GL_FALSE;
+ if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+ if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+ return GL_FALSE;
+ if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
+ return GL_FALSE;
+ if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border))
+ return GL_FALSE;
}
return GL_TRUE;
+
case GL_PROXY_TEXTURE_RECTANGLE_NV:
- if (width < 0 || width > ctx->Const.MaxTextureRectSize ||
- height < 0 || height > ctx->Const.MaxTextureRectSize ||
- level != 0) {
- /* bad width or height or level */
+ maxSize = ctx->Const.MaxTextureRectSize;
+ if (width < 0 || width > maxSize)
+ return GL_FALSE;
+ if (height < 0 || height > maxSize)
+ return GL_FALSE;
+ if (level != 0)
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 ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
- height < 2 * border || height > 2 + maxSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
- level >= ctx->Const.MaxCubeTextureLevels) {
- /* bad width or height */
+ if (width < 2 * border || width > 2 + maxSize)
+ return GL_FALSE;
+ if (height < 2 * border || height > 2 + maxSize)
+ return GL_FALSE;
+ if (level >= ctx->Const.MaxCubeTextureLevels)
return GL_FALSE;
+ if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+ if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+ return GL_FALSE;
+ if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
+ return GL_FALSE;
}
return GL_TRUE;
+
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
- if (width < 2 * border || width > 2 + maxSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
- level >= ctx->Const.MaxTextureLevels) {
- /* bad width or level */
+ if (width < 2 * border || width > 2 + maxSize)
return GL_FALSE;
- }
-
- if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) {
+ if (height < 1 || height > ctx->Const.MaxArrayTextureLayers)
+ return GL_FALSE;
+ if (level >= ctx->Const.MaxTextureLevels)
return GL_FALSE;
+ if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+ if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+ return GL_FALSE;
}
return GL_TRUE;
+
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
- if (width < 2 * border || width > 2 + maxSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
- height < 2 * border || height > 2 + maxSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two &&
- height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
- level >= ctx->Const.MaxTextureLevels) {
- /* bad width or height or level */
+ if (width < 2 * border || width > 2 + maxSize)
return GL_FALSE;
- }
- if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) {
+ if (height < 2 * border || height > 2 + maxSize)
+ return GL_FALSE;
+ if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers)
return GL_FALSE;
+ if (level >= ctx->Const.MaxTextureLevels)
+ return GL_FALSE;
+ if (!ctx->Extensions.ARB_texture_non_power_of_two) {
+ if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
+ return GL_FALSE;
+ if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
+ return GL_FALSE;
}
return GL_TRUE;
+
default:
_mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
return GL_FALSE;
@@ -1225,15 +1332,37 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
/**
- * Helper function to determine whether a target supports compressed textures
+ * 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
-target_can_be_compressed(struct gl_context *ctx, GLenum target)
+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 and specific compression
+ * format are supported.
+ */
+static GLboolean
+target_can_be_compressed(const struct gl_context *ctx, GLenum target,
+ GLenum intFormat)
+{
+ (void) intFormat; /* not used yet */
+
switch (target) {
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
- return GL_TRUE;
+ return GL_TRUE; /* true for any compressed format so far */
case GL_PROXY_TEXTURE_CUBE_MAP:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
@@ -1252,15 +1381,118 @@ target_can_be_compressed(struct gl_context *ctx, GLenum target)
/**
+ * Check if the given texture target value is legal for a
+ * glTexImage1/2/3D call.
+ */
+static GLboolean
+legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
+{
+ switch (dims) {
+ case 1:
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_PROXY_TEXTURE_1D:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+ case 2:
+ switch (target) {
+ case GL_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_2D:
+ return GL_TRUE;
+ case GL_PROXY_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ return ctx->Extensions.ARB_texture_cube_map;
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ return ctx->Extensions.NV_texture_rectangle;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
+ return ctx->Extensions.MESA_texture_array;
+ default:
+ return GL_FALSE;
+ }
+ case 3:
+ switch (target) {
+ case GL_TEXTURE_3D:
+ case GL_PROXY_TEXTURE_3D:
+ return GL_TRUE;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+ return ctx->Extensions.MESA_texture_array;
+ default:
+ return GL_FALSE;
+ }
+ default:
+ _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims);
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Check if the given texture target value is legal for a
+ * glTexSubImage, glCopyTexSubImage or glCopyTexImage call.
+ * The difference compared to legal_teximage_target() above is that
+ * proxy targets are not supported.
+ */
+static GLboolean
+legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
+{
+ switch (dims) {
+ case 1:
+ return target == GL_TEXTURE_1D;
+ case 2:
+ switch (target) {
+ case GL_TEXTURE_2D:
+ return GL_TRUE;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ return ctx->Extensions.ARB_texture_cube_map;
+ case GL_TEXTURE_RECTANGLE_NV:
+ return ctx->Extensions.NV_texture_rectangle;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ return ctx->Extensions.MESA_texture_array;
+ default:
+ return GL_FALSE;
+ }
+ case 3:
+ switch (target) {
+ case GL_TEXTURE_3D:
+ return GL_TRUE;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ return ctx->Extensions.MESA_texture_array;
+ default:
+ return GL_FALSE;
+ }
+ default:
+ _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()",
+ dims);
+ return GL_FALSE;
+ }
+}
+
+
+/**
* Test the glTexImage[123]D() parameters for errors.
*
* \param ctx GL context.
+ * \param dimensions texture image dimensions (must be 1, 2 or 3).
* \param target texture target given by the user.
* \param level image level given by the user.
* \param internalFormat internal format given by the user.
* \param format pixel data format given by the user.
* \param type pixel data type given by the user.
- * \param dimensions texture image dimensions (must be 1, 2 or 3).
* \param width image width given by the user.
* \param height image height given by the user.
* \param depth image depth given by the user.
@@ -1269,21 +1501,21 @@ target_can_be_compressed(struct gl_context *ctx, GLenum target)
* \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
*
* Verifies each of the parameters against the constants specified in
- * __struct gl_contextRec::Const and the supported extensions, and according to the
- * OpenGL specification.
+ * __struct gl_contextRec::Const and the supported extensions, and according
+ * to the OpenGL specification.
*/
static GLboolean
-texture_error_check( struct gl_context *ctx, GLenum target,
+texture_error_check( struct gl_context *ctx,
+ GLuint dimensions, GLenum target,
GLint level, GLint internalFormat,
GLenum format, GLenum type,
- GLuint dimensions,
GLint width, GLint height,
GLint depth, GLint border )
{
- const GLboolean isProxy = _mesa_is_proxy_texture(target);
+ const GLenum proxyTarget = get_proxy_target(target);
+ const GLboolean isProxy = target == proxyTarget;
GLboolean sizeOK = GL_TRUE;
GLboolean colorFormat, indexFormat;
- GLenum proxy_target;
/* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
@@ -1313,71 +1545,16 @@ texture_error_check( struct gl_context *ctx, GLenum target,
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) {
- proxy_target = GL_PROXY_TEXTURE_1D;
- height = 1;
- depth = 1;
- }
- else {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
- return GL_TRUE;
- }
- }
- else if (dimensions == 2) {
- depth = 1;
- if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) {
- proxy_target = GL_PROXY_TEXTURE_2D;
- }
- 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;
- }
- proxy_target = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
- sizeOK = (width == height);
- }
- 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;
- }
- proxy_target = GL_PROXY_TEXTURE_RECTANGLE_NV;
- }
- else if (target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
- target == GL_TEXTURE_1D_ARRAY_EXT) {
- proxy_target = GL_PROXY_TEXTURE_1D_ARRAY_EXT;
- }
- 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) {
- proxy_target = GL_PROXY_TEXTURE_3D;
- }
- else if (target == GL_PROXY_TEXTURE_2D_ARRAY_EXT ||
- target == GL_TEXTURE_2D_ARRAY_EXT) {
- proxy_target = GL_PROXY_TEXTURE_2D_ARRAY_EXT;
- }
- 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;
+ /* Do this simple check before calling the TestProxyTexImage() function */
+ if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
+ sizeOK = (width == height);
}
- sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxy_target, level,
+ /*
+ * Use the proxy texture driver hook to see if the size/level/etc are
+ * legal.
+ */
+ sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
internalFormat, format,
type, width, height,
depth, border);
@@ -1482,9 +1659,10 @@ texture_error_check( struct gl_context *ctx, GLenum target,
/* additional checks for compressed textures */
if (_mesa_is_compressed_format(ctx, internalFormat)) {
- if (!target_can_be_compressed(ctx, target) && !isProxy) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glTexImage%dD(target)", dimensions);
+ if (!target_can_be_compressed(ctx, target, internalFormat)) {
+ if (!isProxy)
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glTexImage%dD(target)", dimensions);
return GL_TRUE;
}
if (border != 0) {
@@ -1532,8 +1710,8 @@ texture_error_check( struct gl_context *ctx, GLenum target,
* \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
*
* Verifies each of the parameters against the constants specified in
- * __struct gl_contextRec::Const and the supported extensions, and according to the
- * OpenGL specification.
+ * __struct gl_contextRec::Const and the supported extensions, and according
+ * to the OpenGL specification.
*/
static GLboolean
subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
@@ -1542,61 +1720,13 @@ subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
GLint width, GLint height, GLint depth,
GLenum format, GLenum type )
{
- /* Check target */
- if (dimensions == 1) {
- if (target != GL_TEXTURE_1D) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
- return GL_TRUE;
- }
- }
- else if (dimensions == 2) {
- 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, "glTexSubImage2D(target)" );
- return GL_TRUE;
- }
- }
- else if (target == GL_TEXTURE_RECTANGLE_NV) {
- if (!ctx->Extensions.NV_texture_rectangle) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
- return GL_TRUE;
- }
- }
- else if (target == GL_TEXTURE_1D_ARRAY_EXT) {
- if (!ctx->Extensions.MESA_texture_array) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
- return GL_TRUE;
- }
- }
- else if (target != GL_TEXTURE_2D) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
- return GL_TRUE;
- }
- }
- else if (dimensions == 3) {
- if (target == GL_TEXTURE_2D_ARRAY_EXT) {
- if (!ctx->Extensions.MESA_texture_array) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
- return GL_TRUE;
- }
- }
- else if (target != GL_TEXTURE_3D) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
- return GL_TRUE;
- }
- }
- else {
- _mesa_problem( ctx, "invalid dims in texture_error_check" );
- return GL_TRUE;
- }
-
/* Basic level check */
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
_mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
return GL_TRUE;
}
+ /* Check for negative sizes */
if (width < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glTexSubImage%dD(width=%d)", dimensions, width);
@@ -1683,13 +1813,6 @@ subtexture_error_check2( struct gl_context *ctx, GLuint dimensions,
if (_mesa_is_format_compressed(destTex->TexFormat)) {
GLuint bw, bh;
- if (!target_can_be_compressed(ctx, target)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glTexSubImage%dD(target=%s)", dimensions,
- _mesa_lookup_enum_by_nr(target));
- return GL_TRUE;
- }
-
/* do tests which depend on compression block size */
_mesa_get_format_block_size(destTex->TexFormat, &bw, &bh);
@@ -1732,18 +1855,26 @@ subtexture_error_check2( struct gl_context *ctx, GLuint dimensions,
* \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
*
* Verifies each of the parameters against the constants specified in
- * __struct gl_contextRec::Const and the supported extensions, and according to the
- * OpenGL specification.
+ * __struct gl_contextRec::Const and the supported extensions, and according
+ * to the OpenGL specification.
*/
static GLboolean
copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
GLenum target, GLint level, GLint internalFormat,
GLint width, GLint height, GLint border )
{
- GLenum type;
+ const GLenum proxyTarget = get_proxy_target(target);
+ const GLenum type = GL_FLOAT;
GLboolean sizeOK;
GLint format;
+ /* check target */
+ if (!legal_texsubimage_target(ctx, dimensions, target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
+ dimensions, _mesa_lookup_enum_by_nr(target));
+ return GL_TRUE;
+ }
+
/* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
_mesa_error(ctx, GL_INVALID_VALUE,
@@ -1781,75 +1912,14 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
return GL_TRUE;
}
- /* NOTE: the format and type aren't really significant for
- * TestProxyTexImage(). Only the internalformat really matters.
- */
- type = GL_FLOAT;
+ /* Do size, level checking */
+ sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB)
+ ? (width == height) : 1;
- /* Check target and call ctx->Driver.TestProxyTexImage() to check the
- * level, width, height and depth.
- */
- if (dimensions == 1) {
- 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)" );
- return GL_TRUE;
- }
- }
- else if (dimensions == 2) {
- if (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_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, "glCopyTexImage2D(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_TEXTURE_RECTANGLE_NV) {
- if (!ctx->Extensions.NV_texture_rectangle) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
- 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_1D_ARRAY_EXT) {
- if (!ctx->Extensions.MESA_texture_array) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)");
- return GL_TRUE;
- }
- sizeOK = ctx->Driver.TestProxyTexImage(ctx,
- GL_PROXY_TEXTURE_1D_ARRAY_EXT,
- level, internalFormat,
- format, type,
- width, height, 1, border);
- }
- else {
- _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
- return GL_TRUE;
- }
- }
- else {
- _mesa_problem(ctx, "invalid dimensions in copytexture_error_check");
- return GL_TRUE;
- }
+ sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
+ internalFormat, format,
+ type, width, height,
+ 1, border);
if (!sizeOK) {
if (dimensions == 1) {
@@ -1865,7 +1935,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
}
if (_mesa_is_compressed_format(ctx, internalFormat)) {
- if (!target_can_be_compressed(ctx, target)) {
+ if (!target_can_be_compressed(ctx, target, internalFormat)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyTexImage%dD(target)", dimensions);
return GL_TRUE;
@@ -1924,45 +1994,11 @@ copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
}
}
- /* Check target */
- if (dimensions == 1) {
- if (target != GL_TEXTURE_1D) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
- return GL_TRUE;
- }
- }
- else if (dimensions == 2) {
- 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, "glCopyTexSubImage2D(target)" );
- return GL_TRUE;
- }
- }
- else if (target == GL_TEXTURE_RECTANGLE_NV) {
- if (!ctx->Extensions.NV_texture_rectangle) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
- return GL_TRUE;
- }
- }
- else if (target == GL_TEXTURE_1D_ARRAY_EXT) {
- if (!ctx->Extensions.MESA_texture_array) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
- return GL_TRUE;
- }
- }
- else if (target != GL_TEXTURE_2D) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
- return GL_TRUE;
- }
- }
- else if (dimensions == 3) {
- if (((target != GL_TEXTURE_2D_ARRAY_EXT) ||
- (!ctx->Extensions.MESA_texture_array))
- && (target != GL_TEXTURE_3D)) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" );
- return GL_TRUE;
- }
+ /* check target (proxies not allowed) */
+ if (!legal_texsubimage_target(ctx, dimensions, target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)",
+ dimensions, _mesa_lookup_enum_by_nr(target));
+ return GL_TRUE;
}
/* Check level */
@@ -2051,11 +2087,6 @@ copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions,
}
if (_mesa_is_format_compressed(teximage->TexFormat)) {
- if (!target_can_be_compressed(ctx, target)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glCopyTexSubImage%dD(target)", dimensions);
- return GL_TRUE;
- }
/* offset must be multiple of 4 */
if ((xoffset & 3) || (yoffset & 3)) {
_mesa_error(ctx, GL_INVALID_VALUE,
@@ -2107,9 +2138,9 @@ copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions,
/* If copying into an integer texture, the source buffer must also be
* integer-valued.
*/
- if (_mesa_is_format_integer(teximage->TexFormat)) {
+ if (_mesa_is_format_integer_color(teximage->TexFormat)) {
struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
- if (!_mesa_is_format_integer(rb->Format)) {
+ if (!_mesa_is_format_integer_color(rb->Format)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyTexSubImage%dD(source buffer is not integer format)",
dimensions);
@@ -2257,13 +2288,14 @@ override_internal_format(GLenum internalFormat, GLint width, GLint height)
* for efficient texture memory layout/allocation. In particular, this
* comes up during automatic mipmap generation.
*/
-void
+gl_format
_mesa_choose_texture_format(struct gl_context *ctx,
struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
GLenum target, GLint level,
GLenum internalFormat, GLenum format, GLenum type)
{
+ gl_format f;
+
/* see if we've already chosen a format for the previous level */
if (level > 0) {
struct gl_texture_image *prevImage =
@@ -2275,102 +2307,60 @@ _mesa_choose_texture_format(struct gl_context *ctx,
prevImage->Width > 0 &&
prevImage->InternalFormat == internalFormat) {
/* use the same format */
- texImage->TexFormat = prevImage->TexFormat;
- return;
+ ASSERT(prevImage->TexFormat != MESA_FORMAT_NONE);
+ return prevImage->TexFormat;
}
}
/* choose format from scratch */
- texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
- format, type);
- ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+ f = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+ ASSERT(f != MESA_FORMAT_NONE);
+ return f;
}
-
-/*
- * Called from the API. Note that width includes the border.
+/**
+ * Common code to implement all the glTexImage1D/2D/3D functions.
*/
-void GLAPIENTRY
-_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
- GLsizei width, GLint border, GLenum format,
- GLenum type, const GLvoid *pixels )
+static void
+teximage(struct gl_context *ctx, GLuint dims,
+ GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels)
{
- GET_CURRENT_CONTEXT(ctx);
+ GLboolean error;
+
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glTexImage1D %s %d %s %d %d %s %s %p\n",
+ _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
+ dims,
_mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat), width, border,
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height, depth, border,
_mesa_lookup_enum_by_nr(format),
_mesa_lookup_enum_by_nr(type), pixels);
- internalFormat = override_internal_format(internalFormat, width, 1);
-
- if (target == GL_TEXTURE_1D) {
- /* non-proxy target */
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- const GLuint face = _mesa_tex_target_to_face(target);
-
- if (texture_error_check(ctx, target, level, internalFormat,
- format, type, 1, width, 1, 1, border)) {
- return; /* error was recorded */
- }
-
- if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
- _mesa_update_state(ctx);
-
- texObj = _mesa_get_current_tex_object(ctx, target);
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_get_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
- }
- else {
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
-
- ASSERT(texImage->Data == NULL);
-
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, 1, 1,
- border, internalFormat);
-
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, format, type);
-
- /* Give the texture to the driver. <pixels> may be null. */
- ASSERT(ctx->Driver.TexImage1D);
- ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
- width, border, format, type, pixels,
- &ctx->Unpack, texObj, texImage);
-
- ASSERT(texImage->TexFormat);
+ internalFormat = override_internal_format(internalFormat, width, height);
- _mesa_set_fetch_functions(texImage, 1);
+ /* target error checking */
+ if (!legal_teximage_target(ctx, dims, target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)",
+ dims, _mesa_lookup_enum_by_nr(target));
+ return;
+ }
- check_gen_mipmap(ctx, target, texObj, level);
+ /* general error checking */
+ error = texture_error_check(ctx, dims, target, level, internalFormat,
+ format, type, width, height, depth, border);
- update_fbo_texture(ctx, texObj, face, level);
+ if (_mesa_is_proxy_texture(target)) {
+ /* Proxy texture: just clear or set state depending on error checking */
+ struct gl_texture_image *texImage =
+ _mesa_get_proxy_tex_image(ctx, target, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- }
- _mesa_unlock_texture(ctx, texObj);
- }
- else if (target == GL_PROXY_TEXTURE_1D) {
- /* Proxy texture: check for errors and update proxy state */
- struct gl_texture_image *texImage;
- texImage = _mesa_get_proxy_tex_image(ctx, target, level);
- if (texture_error_check(ctx, target, level, internalFormat,
- format, type, 1, width, 1, 1, border)) {
+ if (error) {
/* when error, clear all proxy texture image parameters */
if (texImage)
clear_teximage_fields(texImage);
@@ -2379,54 +2369,28 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
/* no error, set the tex image parameters */
struct gl_texture_object *texObj =
_mesa_get_current_tex_object(ctx, target);
- ASSERT(texImage);
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, 1, 1,
- border, internalFormat);
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, format, type);
+ gl_format 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);
+ }
+ else if (texImage) {
+ clear_teximage_fields(texImage);
+ }
}
}
else {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
- return;
- }
-}
-
-
-void GLAPIENTRY
-_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
- GLsizei width, GLsizei height, GLint border,
- GLenum format, GLenum type,
- const GLvoid *pixels )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glTexImage2D %s %d %s %d %d %d %s %s %p\n",
- _mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat), width, height,
- border, _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type), pixels);
-
- internalFormat = override_internal_format(internalFormat, width, height);
-
- if (target == GL_TEXTURE_2D ||
- (ctx->Extensions.ARB_texture_cube_map &&
- target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
- target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) ||
- (ctx->Extensions.NV_texture_rectangle &&
- target == GL_TEXTURE_RECTANGLE_NV) ||
- (ctx->Extensions.MESA_texture_array &&
- target == GL_TEXTURE_1D_ARRAY_EXT)) {
/* non-proxy target */
+ const GLuint face = _mesa_tex_target_to_face(target);
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- const GLuint face = _mesa_tex_target_to_face(target);
- if (texture_error_check(ctx, target, level, internalFormat,
- format, type, 2, width, height, 1, border)) {
+ if (error) {
return; /* error was recorded */
}
@@ -2434,78 +2398,97 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
_mesa_update_state(ctx);
texObj = _mesa_get_current_tex_object(ctx, target);
+
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+
if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
}
else {
+ gl_format texFormat;
+
if (texImage->Data) {
ctx->Driver.FreeTexImageData( ctx, texImage );
}
ASSERT(texImage->Data == NULL);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, height, 1,
- border, internalFormat);
-
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, format, type);
-
- /* Give the texture to the driver. <pixels> may be null. */
- ASSERT(ctx->Driver.TexImage2D);
- ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
- width, height, border, format, type,
- pixels, &ctx->Unpack, texObj, texImage);
-
- ASSERT(texImage->TexFormat);
-
- _mesa_set_fetch_functions(texImage, 2);
+ 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);
+
+ /* Give the texture to the driver. <pixels> may be null. */
+ ASSERT(ctx->Driver.TexImage3D);
+ switch (dims) {
+ case 1:
+ ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
+ width, border, format,
+ type, pixels, &ctx->Unpack, texObj,
+ texImage);
+ break;
+ case 2:
+ ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
+ width, height, border, format,
+ type, pixels, &ctx->Unpack, texObj,
+ texImage);
+ break;
+ case 3:
+ ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
+ width, height, depth, border, format,
+ type, pixels, &ctx->Unpack, texObj,
+ texImage);
+ break;
+ default:
+ _mesa_problem(ctx, "invalid dims=%u in teximage()", dims);
+ }
- check_gen_mipmap(ctx, target, texObj, level);
+ check_gen_mipmap(ctx, target, texObj, level);
- update_fbo_texture(ctx, texObj, face, level);
+ update_fbo_texture(ctx, texObj, face, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
+ }
}
}
_mesa_unlock_texture(ctx, texObj);
}
- else if (target == GL_PROXY_TEXTURE_2D ||
- (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
- ctx->Extensions.ARB_texture_cube_map) ||
- (target == GL_PROXY_TEXTURE_RECTANGLE_NV &&
- ctx->Extensions.NV_texture_rectangle) ||
- (ctx->Extensions.MESA_texture_array &&
- target == GL_PROXY_TEXTURE_1D_ARRAY_EXT)) {
- /* Proxy texture: check for errors and update proxy state */
- struct gl_texture_image *texImage;
- texImage = _mesa_get_proxy_tex_image(ctx, target, level);
- if (texture_error_check(ctx, target, level, internalFormat,
- format, type, 2, width, height, 1, border)) {
- /* when error, clear all proxy texture image parameters */
- if (texImage)
- clear_teximage_fields(texImage);
- }
- else {
- /* no error, set the tex image parameters */
- struct gl_texture_object *texObj =
- _mesa_get_current_tex_object(ctx, target);
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, height, 1,
- border, internalFormat);
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, format, type);
- }
- }
- else {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
- return;
- }
+}
+
+
+/*
+ * Called from the API. Note that width includes the border.
+ */
+void GLAPIENTRY
+_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLint border, GLenum format,
+ GLenum type, const GLvoid *pixels )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
+ border, format, type, pixels);
+}
+
+
+void GLAPIENTRY
+_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type,
+ const GLvoid *pixels )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ teximage(ctx, 2, target, level, internalFormat, width, height, 1,
+ border, format, type, pixels);
}
@@ -2520,101 +2503,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
const GLvoid *pixels )
{
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glTexImage3D %s %d %s %d %d %d %d %s %s %p\n",
- _mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat), width, height,
- depth, border, _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type), pixels);
-
- internalFormat = override_internal_format(internalFormat, width, height);
-
- if (target == GL_TEXTURE_3D ||
- (ctx->Extensions.MESA_texture_array &&
- target == GL_TEXTURE_2D_ARRAY_EXT)) {
- /* non-proxy target */
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- const GLuint face = _mesa_tex_target_to_face(target);
-
- if (texture_error_check(ctx, target, level, (GLint) internalFormat,
- format, type, 3, width, height, depth, border)) {
- return; /* error was recorded */
- }
-
- if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
- _mesa_update_state(ctx);
-
- texObj = _mesa_get_current_tex_object(ctx, target);
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_get_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
- }
- else {
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
-
- ASSERT(texImage->Data == NULL);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, height, depth,
- border, internalFormat);
-
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, format, type);
-
- /* 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);
-
- ASSERT(texImage->TexFormat);
-
- _mesa_set_fetch_functions(texImage, 3);
-
- check_gen_mipmap(ctx, target, texObj, level);
-
- update_fbo_texture(ctx, texObj, face, level);
-
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- }
- _mesa_unlock_texture(ctx, texObj);
- }
- else if (target == GL_PROXY_TEXTURE_3D ||
- (ctx->Extensions.MESA_texture_array &&
- target == GL_PROXY_TEXTURE_2D_ARRAY_EXT)) {
- /* Proxy texture: check for errors and update proxy state */
- struct gl_texture_image *texImage;
- texImage = _mesa_get_proxy_tex_image(ctx, target, level);
- if (texture_error_check(ctx, target, level, internalFormat,
- format, type, 3, width, height, depth, border)) {
- /* when error, clear all proxy texture image parameters */
- if (texImage)
- clear_teximage_fields(texImage);
- }
- else {
- /* no error, set the tex image parameters */
- struct gl_texture_object *texObj =
- _mesa_get_current_tex_object(ctx, target);
- _mesa_init_teximage_fields(ctx, target, texImage, width, height,
- depth, border, internalFormat);
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, format, type);
- }
- }
- else {
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
- return;
- }
+ teximage(ctx, 3, target, level, internalFormat, width, height, depth,
+ border, format, type, pixels);
}
@@ -2677,51 +2567,92 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
#endif
-void GLAPIENTRY
-_mesa_TexSubImage1D( GLenum target, GLint level,
- GLint xoffset, GLsizei width,
- GLenum format, GLenum type,
- const GLvoid *pixels )
+
+/**
+ * Implement all the glTexSubImage1/2/3D() functions.
+ */
+static void
+texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels )
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- GET_CURRENT_CONTEXT(ctx);
+
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glTexSubImage1D %s %d %d %d %s %s %p\n",
+ _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
+ dims,
_mesa_lookup_enum_by_nr(target), level,
- xoffset, width, _mesa_lookup_enum_by_nr(format),
+ xoffset, yoffset, zoffset, width, height, depth,
+ _mesa_lookup_enum_by_nr(format),
_mesa_lookup_enum_by_nr(type), pixels);
+ /* check target (proxies not allowed) */
+ if (!legal_texsubimage_target(ctx, dims, target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
+ dims, _mesa_lookup_enum_by_nr(target));
+ return;
+ }
+
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
- width, 1, 1, format, type)) {
+ if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type)) {
return; /* error was detected */
}
-
texObj = _mesa_get_current_tex_object(ctx, target);
- assert(texObj);
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0,
- width, 1, 1, format, type, texImage)) {
+ if (subtexture_error_check2(ctx, dims, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, texImage)) {
/* error was recorded */
}
- else if (width > 0) {
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
+ else if (width > 0 && height > 0 && height > 0) {
+ /* If we have a border, offset=-1 is legal. Bias by border width. */
+ switch (dims) {
+ case 3:
+ zoffset += texImage->Border;
+ /* fall-through */
+ case 2:
+ yoffset += texImage->Border;
+ /* fall-through */
+ case 1:
+ xoffset += texImage->Border;
+ }
- ASSERT(ctx->Driver.TexSubImage1D);
- ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width,
- format, type, pixels, &ctx->Unpack,
- texObj, texImage);
+ switch (dims) {
+ case 1:
+ ctx->Driver.TexSubImage1D(ctx, target, level,
+ xoffset, width,
+ format, type, pixels,
+ &ctx->Unpack, texObj, texImage );
+ break;
+ case 2:
+ ctx->Driver.TexSubImage2D(ctx, target, level,
+ xoffset, yoffset, width, height,
+ format, type, pixels,
+ &ctx->Unpack, texObj, texImage );
+ break;
+ case 3:
+ ctx->Driver.TexSubImage3D(ctx, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, pixels,
+ &ctx->Unpack, texObj, texImage );
+ break;
+ default:
+ _mesa_problem(ctx, "unexpected dims in subteximage()");
+ }
check_gen_mipmap(ctx, target, texObj, level);
@@ -2733,58 +2664,31 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
void GLAPIENTRY
+_mesa_TexSubImage1D( GLenum target, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ texsubimage(ctx, 1, target, level,
+ xoffset, 0, 0,
+ width, 1, 1,
+ format, type, pixels);
+}
+
+
+void GLAPIENTRY
_mesa_TexSubImage2D( GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const GLvoid *pixels )
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glTexSubImage2D %s %d %d %d %d %d %s %s %p\n",
- _mesa_lookup_enum_by_nr(target), level,
- xoffset, yoffset, width, height,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type), pixels);
-
- if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
- _mesa_update_state(ctx);
-
- if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
- width, height, 1, format, type)) {
- return; /* error was detected */
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
- if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
- width, height, 1, format, type, texImage)) {
- /* error was recorded */
- }
- else if (width > 0 && height >= 0) {
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
-
- ASSERT(ctx->Driver.TexSubImage2D);
- ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
- width, height, format, type, pixels,
- &ctx->Unpack, texObj, texImage);
-
- check_gen_mipmap(ctx, target, texObj, level);
-
- ctx->NewState |= _NEW_TEXTURE;
- }
- }
- _mesa_unlock_texture(ctx, texObj);
+ texsubimage(ctx, 2, target, level,
+ xoffset, yoffset, 0,
+ width, height, 1,
+ format, type, pixels);
}
@@ -2796,84 +2700,41 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
GLenum format, GLenum type,
const GLvoid *pixels )
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glTexSubImage3D %s %d %d %d %d %d %d %d %s %s %p\n",
- _mesa_lookup_enum_by_nr(target), level,
- xoffset, yoffset, zoffset, width, height, depth,
- _mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type), pixels);
-
- if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
- _mesa_update_state(ctx);
-
- if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
- width, height, depth, format, type)) {
- return; /* error was detected */
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
- if (subtexture_error_check2(ctx, 3, target, level,
- xoffset, yoffset, zoffset,
- width, height, depth,
- format, type, texImage)) {
- /* error was recorded */
- }
- else if (width > 0 && height > 0 && height > 0) {
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
- zoffset += texImage->Border;
-
- ASSERT(ctx->Driver.TexSubImage3D);
- ctx->Driver.TexSubImage3D(ctx, target, level,
- xoffset, yoffset, zoffset,
- width, height, depth,
- format, type, pixels,
- &ctx->Unpack, texObj, texImage );
-
- check_gen_mipmap(ctx, target, texObj, level);
-
- ctx->NewState |= _NEW_TEXTURE;
- }
- }
- _mesa_unlock_texture(ctx, texObj);
+ texsubimage(ctx, 3, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, pixels);
}
-void GLAPIENTRY
-_mesa_CopyTexImage1D( GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y,
- GLsizei width, GLint border )
+/**
+ * Implement the glCopyTexImage1/2D() functions.
+ */
+static void
+copyteximage(struct gl_context *ctx, GLuint dims,
+ GLenum target, GLint level, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
const GLuint face = _mesa_tex_target_to_face(target);
- GET_CURRENT_CONTEXT(ctx);
+
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glCopyTexImage1D %s %d %s %d %d %d %d\n",
+ _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
+ dims,
_mesa_lookup_enum_by_nr(target), level,
_mesa_lookup_enum_by_nr(internalFormat),
- x, y, width, border);
+ x, y, width, height, border);
if (ctx->NewState & NEW_COPY_TEX_STATE)
_mesa_update_state(ctx);
- if (copytexture_error_check(ctx, 1, target, level, internalFormat,
- width, 1, border))
+ if (copytexture_error_check(ctx, dims, target, level, internalFormat,
+ width, height, border))
return;
texObj = _mesa_get_current_tex_object(ctx, target);
@@ -2881,38 +2742,46 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+
if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
}
else {
+ gl_format texFormat;
+
if (texImage->Data) {
ctx->Driver.FreeTexImageData( ctx, texImage );
}
ASSERT(texImage->Data == NULL);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
- border, internalFormat);
+ texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
+ internalFormat, GL_NONE,
+ GL_NONE);
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, GL_NONE, GL_NONE);
-
- ASSERT(ctx->Driver.CopyTexImage1D);
- ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
- x, y, width, border);
-
- ASSERT(texImage->TexFormat);
+ if (legal_texture_size(ctx, texFormat, width, height, 1)) {
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
+ border, internalFormat, texFormat);
- _mesa_set_fetch_functions(texImage, 1);
+ ASSERT(ctx->Driver.CopyTexImage2D);
+ if (dims == 1)
+ ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
+ x, y, width, border);
+ else
+ ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
+ x, y, width, height, border);
- check_gen_mipmap(ctx, target, texObj, level);
+ check_gen_mipmap(ctx, target, texObj, level);
- update_fbo_texture(ctx, texObj, face, level);
+ update_fbo_texture(ctx, texObj, face, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
+ }
}
}
_mesa_unlock_texture(ctx, texObj);
@@ -2921,95 +2790,52 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
void GLAPIENTRY
-_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border )
+_mesa_CopyTexImage1D( GLenum target, GLint level,
+ GLenum internalFormat,
+ GLint x, GLint y,
+ GLsizei width, GLint border )
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- const GLuint face = _mesa_tex_target_to_face(target);
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glCopyTexImage2D %s %d %s %d %d %d %d %d\n",
- _mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat),
- x, y, width, height, border);
-
- if (ctx->NewState & NEW_COPY_TEX_STATE)
- _mesa_update_state(ctx);
-
- if (copytexture_error_check(ctx, 2, target, level, internalFormat,
- width, height, border))
- return;
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_get_tex_image(ctx, texObj, target, level);
-
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
- }
- else {
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
-
- ASSERT(texImage->Data == NULL);
-
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, height, 1,
- border, internalFormat);
-
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, GL_NONE, GL_NONE);
-
- ASSERT(ctx->Driver.CopyTexImage2D);
- ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
- x, y, width, height, border);
-
- ASSERT(texImage->TexFormat);
-
- _mesa_set_fetch_functions(texImage, 2);
+ copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border);
+}
- check_gen_mipmap(ctx, target, texObj, level);
- update_fbo_texture(ctx, texObj, face, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- }
- _mesa_unlock_texture(ctx, texObj);
+void GLAPIENTRY
+_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ copyteximage(ctx, 2, target, level, internalFormat,
+ x, y, width, height, border);
}
-void GLAPIENTRY
-_mesa_CopyTexSubImage1D( GLenum target, GLint level,
- GLint xoffset, GLint x, GLint y, GLsizei width )
+
+/**
+ * Implementation for glCopyTexSubImage1/2/3D() functions.
+ */
+static void
+copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height)
{
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- GLint yoffset = 0;
- GLsizei height = 1;
- GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glCopyTexSubImage1D %s %d %d %d %d %d\n",
+ _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n",
+ dims,
_mesa_lookup_enum_by_nr(target),
- level, xoffset, x, y, width);
+ level, xoffset, yoffset, zoffset, x, y, width, height);
if (ctx->NewState & NEW_COPY_TEX_STATE)
_mesa_update_state(ctx);
- if (copytexsubimage_error_check1(ctx, 1, target, level))
+ if (copytexsubimage_error_check1(ctx, dims, target, level))
return;
texObj = _mesa_get_current_tex_object(ctx, target);
@@ -3018,19 +2844,43 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (copytexsubimage_error_check2(ctx, 1, target, level,
- xoffset, 0, 0, width, 1, texImage)) {
- /* error was recorded */
+ if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset,
+ zoffset, width, height, texImage)) {
+ /* error was recored */
}
else {
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
+ /* If we have a border, offset=-1 is legal. Bias by border width. */
+ switch (dims) {
+ case 3:
+ zoffset += texImage->Border;
+ /* fall-through */
+ case 2:
+ yoffset += texImage->Border;
+ /* fall-through */
+ case 1:
+ xoffset += texImage->Border;
+ }
if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
&width, &height)) {
- ASSERT(ctx->Driver.CopyTexSubImage1D);
- ctx->Driver.CopyTexSubImage1D(ctx, target, level,
- xoffset, x, y, width);
+ switch (dims) {
+ case 1:
+ ctx->Driver.CopyTexSubImage1D(ctx, target, level,
+ xoffset, x, y, width);
+ break;
+ case 2:
+ ctx->Driver.CopyTexSubImage2D(ctx, target, level,
+ xoffset, yoffset,
+ x, y, width, height);
+ break;
+ case 3:
+ ctx->Driver.CopyTexSubImage3D(ctx, target, level,
+ xoffset, yoffset, zoffset,
+ x, y, width, height);
+ break;
+ default:
+ _mesa_problem(ctx, "bad dims in copytexsubimage()");
+ }
check_gen_mipmap(ctx, target, texObj, level);
@@ -3042,57 +2892,24 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
}
+void GLAPIENTRY
+_mesa_CopyTexSubImage1D( GLenum target, GLint level,
+ GLint xoffset, GLint x, GLint y, GLsizei width )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1);
+}
+
+
void GLAPIENTRY
_mesa_CopyTexSubImage2D( GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height )
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glCopyTexSubImage2D %s %d %d %d %d %d %d %d\n",
- _mesa_lookup_enum_by_nr(target),
- level, xoffset, yoffset, x, y, width, height);
-
- if (ctx->NewState & NEW_COPY_TEX_STATE)
- _mesa_update_state(ctx);
-
- if (copytexsubimage_error_check1(ctx, 2, target, level))
- return;
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
- if (copytexsubimage_error_check2(ctx, 2, target, level,
- xoffset, yoffset, 0,
- width, height, texImage)) {
- /* error was recorded */
- }
- else {
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
-
- if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
- &width, &height)) {
- ASSERT(ctx->Driver.CopyTexSubImage2D);
- ctx->Driver.CopyTexSubImage2D(ctx, target, level, xoffset, yoffset,
- x, y, width, height);
-
- check_gen_mipmap(ctx, target, texObj, level);
-
- ctx->NewState |= _NEW_TEXTURE;
- }
- }
- }
- _mesa_unlock_texture(ctx, texObj);
+ copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y,
+ width, height);
}
@@ -3102,52 +2919,9 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height )
{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glCopyTexSubImage3D %s %d %d %d %d %d %d %d %d\n",
- _mesa_lookup_enum_by_nr(target),
- level, xoffset, yoffset, zoffset, x, y, width, height);
-
- if (ctx->NewState & NEW_COPY_TEX_STATE)
- _mesa_update_state(ctx);
-
- if (copytexsubimage_error_check1(ctx, 3, target, level))
- return;
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
- if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset,
- zoffset, width, height, texImage)) {
- /* error was recored */
- }
- else {
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
- zoffset += texImage->Border;
-
- if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
- &width, &height)) {
- ASSERT(ctx->Driver.CopyTexSubImage3D);
- ctx->Driver.CopyTexSubImage3D(ctx, target, level,
- xoffset, yoffset, zoffset,
- x, y, width, height);
-
- check_gen_mipmap(ctx, target, texObj, level);
-
- ctx->NewState |= _NEW_TEXTURE;
- }
- }
- }
- _mesa_unlock_texture(ctx, texObj);
+ copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
+ x, y, width, height);
}
@@ -3192,45 +2966,18 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
GLsizei height, GLsizei depth, GLint border,
GLsizei imageSize)
{
- GLint expectedSize, maxLevels = 0, maxTextureSize;
+ const GLenum proxyTarget = get_proxy_target(target);
+ const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
+ GLint expectedSize;
- if (dimensions == 1) {
- /* 1D compressed textures not allowed */
- return GL_INVALID_ENUM;
- }
- else if (dimensions == 2) {
- if (target == GL_PROXY_TEXTURE_2D) {
- maxLevels = ctx->Const.MaxTextureLevels;
- }
- else if (target == GL_TEXTURE_2D) {
- maxLevels = ctx->Const.MaxTextureLevels;
- }
- else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
- if (!ctx->Extensions.ARB_texture_cube_map)
- return GL_INVALID_ENUM; /*target*/
- 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)
- return GL_INVALID_ENUM; /*target*/
- maxLevels = ctx->Const.MaxCubeTextureLevels;
- }
- else {
- return GL_INVALID_ENUM; /*target*/
- }
- }
- else if (dimensions == 3) {
- /* 3D compressed textures not allowed */
- return GL_INVALID_ENUM;
- }
- else {
- assert(0);
+ /* check level */
+ if (level < 0 || level >= maxLevels)
+ return GL_INVALID_VALUE;
+
+ if (!target_can_be_compressed(ctx, target, internalFormat)) {
return GL_INVALID_ENUM;
}
- maxTextureSize = 1 << (maxLevels - 1);
-
/* This will detect any invalid internalFormat value */
if (!_mesa_is_compressed_format(ctx, internalFormat))
return GL_INVALID_ENUM;
@@ -3239,47 +2986,51 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
if (_mesa_base_tex_format(ctx, internalFormat) < 0)
return GL_INVALID_ENUM;
+ /* No compressed formats support borders at this time */
if (border != 0)
return GL_INVALID_VALUE;
- /*
- * XXX We should probably use the proxy texture error check function here.
- */
- if (width < 1 || width > maxTextureSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(width)))
- return GL_INVALID_VALUE;
-
- if ((height < 1 || height > maxTextureSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(height)))
- && dimensions > 1)
- return GL_INVALID_VALUE;
-
- if ((depth < 1 || depth > maxTextureSize ||
- (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(depth)))
- && dimensions > 2)
- return GL_INVALID_VALUE;
-
/* For cube map, width must equal height */
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height)
return GL_INVALID_VALUE;
- if (level < 0 || level >= maxLevels)
- return GL_INVALID_VALUE;
+ /* check image size against compression block size */
+ {
+ gl_format texFormat =
+ ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+ GL_NONE, GL_NONE);
+ GLuint bw, bh;
- expectedSize = compressed_tex_size(width, height, depth, internalFormat);
- if (expectedSize != imageSize)
- return GL_INVALID_VALUE;
+ _mesa_get_format_block_size(texFormat, &bw, &bh);
+ if ((width > bw && width % bw > 0) ||
+ (height > bh && height % bh > 0)) {
+ /*
+ * Per GL_ARB_texture_compression: GL_INVALID_OPERATION is
+ * generated [...] if any parameter combinations are not
+ * supported by the specific compressed internal format.
+ */
+ return GL_INVALID_OPERATION;
+ }
+ }
-#if FEATURE_EXT_texture_sRGB
- if ((internalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT ||
- internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT ||
- internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT ||
- internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT)
- && border != 0) {
+ /* check image sizes */
+ if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
+ internalFormat, GL_NONE, GL_NONE,
+ width, height, depth, border)) {
+ /* See error comment above */
return GL_INVALID_OPERATION;
}
-#endif
+
+ /* check image size in bytes */
+ expectedSize = compressed_tex_size(width, height, depth, internalFormat);
+ if (expectedSize != imageSize) {
+ /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...]
+ * if <imageSize> is not consistent with the format, dimensions, and
+ * contents of the specified image.
+ */
+ return GL_INVALID_VALUE;
+ }
return GL_NO_ERROR;
}
@@ -3421,156 +3172,101 @@ compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
}
-
-void GLAPIENTRY
-_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
- GLenum internalFormat, GLsizei width,
- GLint border, GLsizei imageSize,
- const GLvoid *data)
+/**
+ * Implementation of the glCompressedTexImage1/2/3D() functions.
+ */
+static void
+compressedteximage(struct gl_context *ctx, GLuint dims,
+ GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize, const GLvoid *data)
{
- GET_CURRENT_CONTEXT(ctx);
+ GLenum error;
+
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glCompressedTexImage1DARB %s %d %s %d %d %d %p\n",
+ _mesa_debug(ctx,
+ "glCompressedTexImage%uDARB %s %d %s %d %d %d %d %d %p\n",
+ dims,
_mesa_lookup_enum_by_nr(target), level,
_mesa_lookup_enum_by_nr(internalFormat),
- width, border, imageSize, data);
-
- if (target == GL_TEXTURE_1D) {
- /* non-proxy target */
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GLenum error = compressed_texture_error_check(ctx, 1, target, level,
- internalFormat, width, 1, 1, border, imageSize);
- if (error) {
- _mesa_error(ctx, error, "glCompressedTexImage1D");
- return;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_get_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
- }
- else {
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
- ASSERT(texImage->Data == NULL);
-
- _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
- border, internalFormat);
-
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, GL_NONE, GL_NONE);
+ width, height, depth, border, imageSize, data);
- ASSERT(ctx->Driver.CompressedTexImage1D);
- ctx->Driver.CompressedTexImage1D(ctx, target, level,
- internalFormat, width, border,
- imageSize, data,
- texObj, texImage);
+ /* check target */
+ if (!legal_teximage_target(ctx, dims, target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target=%s)",
+ dims, _mesa_lookup_enum_by_nr(target));
+ return;
+ }
- _mesa_set_fetch_functions(texImage, 1);
+ error = compressed_texture_error_check(ctx, dims, target, level,
+ internalFormat, width, height, depth,
+ border, imageSize);
- check_gen_mipmap(ctx, target, texObj, level);
+#if FEATURE_ES
+ /* XXX this is kind of a hack */
+ if (error) {
+ _mesa_error(ctx, error, "glTexImage2D");
+ return;
+ }
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
+ if (dims == 2) {
+ switch (internalFormat) {
+ case GL_PALETTE4_RGB8_OES:
+ case GL_PALETTE4_RGBA8_OES:
+ case GL_PALETTE4_R5_G6_B5_OES:
+ case GL_PALETTE4_RGBA4_OES:
+ case GL_PALETTE4_RGB5_A1_OES:
+ case GL_PALETTE8_RGB8_OES:
+ case GL_PALETTE8_RGBA8_OES:
+ case GL_PALETTE8_R5_G6_B5_OES:
+ case GL_PALETTE8_RGBA4_OES:
+ case GL_PALETTE8_RGB5_A1_OES:
+ _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
+ width, height, imageSize, data);
+ return;
}
- _mesa_unlock_texture(ctx, texObj);
}
- else if (target == GL_PROXY_TEXTURE_1D) {
- /* Proxy texture: check for errors and update proxy state */
- GLenum error = compressed_texture_error_check(ctx, 1, target, level,
- internalFormat, width, 1, 1, border, imageSize);
+#endif
+
+ if (_mesa_is_proxy_texture(target)) {
+ /* Proxy texture: just check for errors and update proxy state */
+ struct gl_texture_image *texImage;
+
if (!error) {
- ASSERT(ctx->Driver.TestProxyTexImage);
- error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
- internalFormat, GL_NONE, GL_NONE,
- width, 1, 1, border);
+ struct gl_texture_object *texObj =
+ _mesa_get_current_tex_object(ctx, target);
+ gl_format texFormat =
+ _mesa_choose_texture_format(ctx, texObj, target, level,
+ internalFormat, GL_NONE, GL_NONE);
+ if (!legal_texture_size(ctx, texFormat, width, height, depth)) {
+ error = GL_OUT_OF_MEMORY;
+ }
}
- 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)
+
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texImage) {
+ if (error) {
+ /* if error, clear all proxy texture image parameters */
clear_teximage_fields(texImage);
- }
- else {
- /* store the teximage parameters */
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
- border, internalFormat);
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, GL_NONE, GL_NONE);
- }
- _mesa_unlock_texture(ctx, texObj);
+ }
+ else {
+ /* no error: store the teximage parameters */
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height,
+ depth, border, internalFormat,
+ MESA_FORMAT_NONE);
+ }
}
}
else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1D(target)");
- return;
- }
-}
-
-void GLAPIENTRY
-_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
- GLenum internalFormat, GLsizei width,
- GLsizei height, GLint border, GLsizei imageSize,
- const GLvoid *data)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glCompressedTexImage2DARB %s %d %s %d %d %d %d %p\n",
- _mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat),
- width, height, border, imageSize, data);
-
-#if FEATURE_ES
- switch (internalFormat) {
- case GL_PALETTE4_RGB8_OES:
- case GL_PALETTE4_RGBA8_OES:
- case GL_PALETTE4_R5_G6_B5_OES:
- case GL_PALETTE4_RGBA4_OES:
- case GL_PALETTE4_RGB5_A1_OES:
- case GL_PALETTE8_RGB8_OES:
- case GL_PALETTE8_RGBA8_OES:
- case GL_PALETTE8_R5_G6_B5_OES:
- case GL_PALETTE8_RGBA4_OES:
- case GL_PALETTE8_RGB5_A1_OES:
- _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
- width, height, imageSize, data);
- return;
- }
-#endif
-
- if (target == GL_TEXTURE_2D ||
- (ctx->Extensions.ARB_texture_cube_map &&
- target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
- target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
/* non-proxy target */
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- GLenum error = compressed_texture_error_check(ctx, 2, target, level,
- internalFormat, width, height, 1, border, imageSize);
if (error) {
- _mesa_error(ctx, error, "glCompressedTexImage2D");
+ _mesa_error(ctx, error, "glCompressedTexImage%uD", dims);
return;
}
@@ -3580,186 +3276,105 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
{
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glCompressedTexImage%uD", dims);
}
else {
+ gl_format texFormat;
+
if (texImage->Data) {
ctx->Driver.FreeTexImageData( ctx, texImage );
}
ASSERT(texImage->Data == NULL);
- _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
- border, internalFormat);
-
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, GL_NONE, GL_NONE);
-
- ASSERT(ctx->Driver.CompressedTexImage2D);
- ctx->Driver.CompressedTexImage2D(ctx, target, level,
- internalFormat, width, height,
- border, imageSize, data,
- texObj, texImage);
-
- _mesa_set_fetch_functions(texImage, 2);
+ 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);
+
+ switch (dims) {
+ case 1:
+ ASSERT(ctx->Driver.CompressedTexImage1D);
+ ctx->Driver.CompressedTexImage1D(ctx, target, level,
+ internalFormat,
+ width,
+ border, imageSize, data,
+ texObj, texImage);
+ break;
+ case 2:
+ ASSERT(ctx->Driver.CompressedTexImage2D);
+ ctx->Driver.CompressedTexImage2D(ctx, target, level,
+ internalFormat,
+ width, height,
+ border, imageSize, data,
+ texObj, texImage);
+ break;
+ case 3:
+ ASSERT(ctx->Driver.CompressedTexImage3D);
+ ctx->Driver.CompressedTexImage3D(ctx, target, level,
+ internalFormat,
+ width, height, depth,
+ border, imageSize, data,
+ texObj, texImage);
+ break;
+ default:
+ _mesa_problem(ctx, "bad dims in compressedteximage");
+ }
- check_gen_mipmap(ctx, target, texObj, level);
+ check_gen_mipmap(ctx, target, texObj, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glCompressedTexImage%uD", dims);
+ }
}
}
_mesa_unlock_texture(ctx, texObj);
}
- else if (target == GL_PROXY_TEXTURE_2D ||
- (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB &&
- ctx->Extensions.ARB_texture_cube_map)) {
- /* Proxy texture: check for errors and update proxy state */
- GLenum error = compressed_texture_error_check(ctx, 2, target, level,
- internalFormat, width, height, 1, border, imageSize);
- if (!error) {
- ASSERT(ctx->Driver.TestProxyTexImage);
- error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
- internalFormat, GL_NONE, GL_NONE,
- width, height, 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)
- clear_teximage_fields(texImage);
- }
- else {
- /* store the teximage parameters */
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
- border, internalFormat);
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, GL_NONE, GL_NONE);
- }
- _mesa_unlock_texture(ctx, texObj);
- }
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(target)");
- return;
- }
}
void GLAPIENTRY
-_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
+_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
GLenum internalFormat, GLsizei width,
- GLsizei height, GLsizei depth, GLint border,
- GLsizei imageSize, const GLvoid *data)
+ GLint border, GLsizei imageSize,
+ const GLvoid *data)
{
GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
- _mesa_debug(ctx, "glCompressedTexImage3DARB %s %d %s %d %d %d %d %d %p\n",
- _mesa_lookup_enum_by_nr(target), level,
- _mesa_lookup_enum_by_nr(internalFormat),
- width, height, depth, border, imageSize, data);
-
- if (target == GL_TEXTURE_3D) {
- /* non-proxy target */
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GLenum error = compressed_texture_error_check(ctx, 3, target, level,
- internalFormat, width, height, depth, border, imageSize);
- if (error) {
- _mesa_error(ctx, error, "glCompressedTexImage3D");
- return;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_get_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
- }
- else {
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
- ASSERT(texImage->Data == NULL);
-
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, height, depth,
- border, internalFormat);
-
- /* Choose actual texture format */
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, GL_NONE, GL_NONE);
+ compressedteximage(ctx, 1, target, level, internalFormat,
+ width, 1, 1, border, imageSize, data);
+}
- ASSERT(ctx->Driver.CompressedTexImage3D);
- ctx->Driver.CompressedTexImage3D(ctx, target, level,
- internalFormat,
- width, height, depth,
- border, imageSize, data,
- texObj, texImage);
- _mesa_set_fetch_functions(texImage, 3);
+void GLAPIENTRY
+_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLint border, GLsizei imageSize,
+ const GLvoid *data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ compressedteximage(ctx, 2, target, level, internalFormat,
+ width, height, 1, border, imageSize, data);
+}
- check_gen_mipmap(ctx, target, texObj, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- }
- _mesa_unlock_texture(ctx, texObj);
- }
- else if (target == GL_PROXY_TEXTURE_3D) {
- /* Proxy texture: check for errors and update proxy state */
- GLenum error = compressed_texture_error_check(ctx, 3, target, level,
- internalFormat, width, height, depth, border, imageSize);
- if (!error) {
- ASSERT(ctx->Driver.TestProxyTexImage);
- error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
- internalFormat, GL_NONE, GL_NONE,
- 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)
- clear_teximage_fields(texImage);
- }
- else {
- /* store the teximage parameters */
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- _mesa_init_teximage_fields(ctx, target, texImage, width, height,
- depth, border, internalFormat);
- _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
- internalFormat, GL_NONE, GL_NONE);
- }
- _mesa_unlock_texture(ctx, texObj);
- }
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3D(target)");
- return;
- }
+void GLAPIENTRY
+_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize, const GLvoid *data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ compressedteximage(ctx, 3, target, level, internalFormat,
+ width, height, depth, border, imageSize, data);
}
@@ -3869,5 +3484,3 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset,
width, height, depth, format, imageSize, data);
}
-
-