aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2012-03-23 10:05:55 +0100
committermarha <marha@users.sourceforge.net>2012-03-23 10:05:55 +0100
commit0f834b91a4768673833ab4917e87d86c237bb1a6 (patch)
tree363489504ed4b2d360259b8de4c9e392918e5d02 /mesalib/src/mesa/main
parentfc72edebf875378459368c5383d9023730cbca54 (diff)
downloadvcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.tar.gz
vcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.tar.bz2
vcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.zip
libX11 xserver fontconfig mesa pixman xkbcomp xkeyboard-config git update
23 Mar 2012
Diffstat (limited to 'mesalib/src/mesa/main')
-rw-r--r--mesalib/src/mesa/main/api_validate.c73
-rw-r--r--mesalib/src/mesa/main/api_validate.h2
-rw-r--r--mesalib/src/mesa/main/dlist.c10
-rw-r--r--mesalib/src/mesa/main/getstring.c2
-rw-r--r--mesalib/src/mesa/main/mtypes.h4
-rw-r--r--mesalib/src/mesa/main/samplerobj.c9
-rw-r--r--mesalib/src/mesa/main/samplerobj.h21
-rw-r--r--mesalib/src/mesa/main/teximage.c17
-rw-r--r--mesalib/src/mesa/main/texobj.c334
-rw-r--r--mesalib/src/mesa/main/texobj.h21
-rw-r--r--mesalib/src/mesa/main/texparam.c10
-rw-r--r--mesalib/src/mesa/main/texstate.c7
-rw-r--r--mesalib/src/mesa/main/transformfeedback.c27
-rw-r--r--mesalib/src/mesa/main/transformfeedback.h3
-rw-r--r--mesalib/src/mesa/main/uniform_query.cpp16
-rw-r--r--mesalib/src/mesa/main/uniforms.c2
16 files changed, 279 insertions, 279 deletions
diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c
index 4e94f47e3..02495a15a 100644
--- a/mesalib/src/mesa/main/api_validate.c
+++ b/mesalib/src/mesa/main/api_validate.c
@@ -29,6 +29,7 @@
#include "imports.h"
#include "mfeatures.h"
#include "mtypes.h"
+#include "enums.h"
#include "vbo/vbo.h"
@@ -204,18 +205,60 @@ check_index_bounds(struct gl_context *ctx, GLsizei count, GLenum type,
* are supported.
*/
GLboolean
-_mesa_valid_prim_mode(const struct gl_context *ctx, GLenum mode)
+_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
{
if (ctx->Extensions.ARB_geometry_shader4 &&
mode > GL_TRIANGLE_STRIP_ADJACENCY_ARB) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode);
return GL_FALSE;
}
else if (mode > GL_POLYGON) {
- return GL_FALSE;
- }
- else {
- return GL_TRUE;
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode);
+ return GL_FALSE;
+ }
+
+ /* From the GL_EXT_transform_feedback spec:
+ *
+ * "The error INVALID_OPERATION is generated if Begin, or any command
+ * that performs an explicit Begin, is called when:
+ *
+ * * a geometry shader is not active and <mode> does not match the
+ * allowed begin modes for the current transform feedback state as
+ * given by table X.1.
+ *
+ * * a geometry shader is active and the output primitive type of the
+ * geometry shader does not match the allowed begin modes for the
+ * current transform feedback state as given by table X.1.
+ *
+ */
+ if (ctx->TransformFeedback.CurrentObject->Active &&
+ !ctx->TransformFeedback.CurrentObject->Paused) {
+ GLboolean pass = GL_TRUE;
+
+ switch (mode) {
+ case GL_POINTS:
+ pass = ctx->TransformFeedback.Mode == GL_POINTS;
+ break;
+ case GL_LINES:
+ case GL_LINE_STRIP:
+ case GL_LINE_LOOP:
+ pass = ctx->TransformFeedback.Mode == GL_LINES;
+ break;
+ default:
+ pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
+ break;
+ }
+ if (!pass) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(mode=%s vs transform feedback %s)",
+ name,
+ _mesa_lookup_prim_by_nr(mode),
+ _mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode));
+ return GL_FALSE;
+ }
}
+
+ return GL_TRUE;
}
@@ -237,8 +280,7 @@ _mesa_validate_DrawElements(struct gl_context *ctx,
return GL_FALSE;
}
- if (!_mesa_valid_prim_mode(ctx, mode)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(mode)" );
+ if (!_mesa_valid_prim_mode(ctx, mode, "glDrawElements")) {
return GL_FALSE;
}
@@ -294,8 +336,7 @@ _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode,
return GL_FALSE;
}
- if (!_mesa_valid_prim_mode(ctx, mode)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(mode)" );
+ if (!_mesa_valid_prim_mode(ctx, mode, "glDrawRangeElements")) {
return GL_FALSE;
}
@@ -353,8 +394,7 @@ _mesa_validate_DrawArrays(struct gl_context *ctx,
return GL_FALSE;
}
- if (!_mesa_valid_prim_mode(ctx, mode)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
+ if (!_mesa_valid_prim_mode(ctx, mode, "glDrawArrays")) {
return GL_FALSE;
}
@@ -389,9 +429,7 @@ _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint fi
return GL_FALSE;
}
- if (!_mesa_valid_prim_mode(ctx, mode)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glDrawArraysInstanced(mode=0x%x)", mode);
+ if (!_mesa_valid_prim_mode(ctx, mode, "glDrawArraysInstanced")) {
return GL_FALSE;
}
@@ -429,9 +467,7 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
return GL_FALSE;
}
- if (!_mesa_valid_prim_mode(ctx, mode)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glDrawElementsInstanced(mode = 0x%x)", mode);
+ if (!_mesa_valid_prim_mode(ctx, mode, "glDrawElementsInstanced")) {
return GL_FALSE;
}
@@ -485,8 +521,7 @@ _mesa_validate_DrawTransformFeedback(struct gl_context *ctx,
{
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- if (!_mesa_valid_prim_mode(ctx, mode)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glDrawTransformFeedback(mode)");
+ if (!_mesa_valid_prim_mode(ctx, mode, "glDrawTransformFeedback")) {
return GL_FALSE;
}
diff --git a/mesalib/src/mesa/main/api_validate.h b/mesalib/src/mesa/main/api_validate.h
index f4948424c..d92fd433f 100644
--- a/mesalib/src/mesa/main/api_validate.h
+++ b/mesalib/src/mesa/main/api_validate.h
@@ -43,7 +43,7 @@ _mesa_max_buffer_index(struct gl_context *ctx, GLuint count, GLenum type,
extern GLboolean
-_mesa_valid_prim_mode(const struct gl_context *ctx, GLenum mode);
+_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name);
extern GLboolean
diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c
index 420ddcc0c..f113573d8 100644
--- a/mesalib/src/mesa/main/dlist.c
+++ b/mesalib/src/mesa/main/dlist.c
@@ -5767,10 +5767,16 @@ save_Begin(GLenum mode)
Node *n;
GLboolean error = GL_FALSE;
- if (!_mesa_valid_prim_mode(ctx, mode)) {
- _mesa_compile_error(ctx, GL_INVALID_ENUM, "glBegin(mode)");
+ if (mode > GL_POLYGON) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBegin(mode=%x)", mode);
error = GL_TRUE;
}
+ if (ctx->ExecuteFlag) {
+ if (!_mesa_valid_prim_mode(ctx, mode, "glBegin")) {
+ error = GL_TRUE;
+ }
+ }
+
else if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN) {
/* Typically the first begin. This may raise an error on
* playback, depending on whether CallList is issued from inside
diff --git a/mesalib/src/mesa/main/getstring.c b/mesalib/src/mesa/main/getstring.c
index 90e028055..2f445aaf9 100644
--- a/mesalib/src/mesa/main/getstring.c
+++ b/mesalib/src/mesa/main/getstring.c
@@ -53,6 +53,8 @@ shading_language_version(struct gl_context *ctx)
return (const GLubyte *) "1.20";
case 130:
return (const GLubyte *) "1.30";
+ case 140:
+ return (const GLubyte *) "1.40";
default:
_mesa_problem(ctx,
"Invalid GLSL version in shading_language_version()");
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index f76096a49..a3827d48d 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1316,7 +1316,9 @@ struct gl_texture_object
GLenum Swizzle[4]; /**< GL_EXT_texture_swizzle */
GLuint _Swizzle; /**< same as Swizzle, but SWIZZLE_* format */
GLboolean GenerateMipmap; /**< GL_SGIS_generate_mipmap */
- GLboolean _Complete; /**< Is texture object complete? */
+ GLboolean _BaseComplete; /**< Is the base texture level valid? */
+ GLboolean _MipmapComplete; /**< Is the whole mipmap valid? */
+ GLboolean _IsIntegerFormat; /**< Does the texture store integer values? */
GLboolean _RenderToTexture; /**< Any rendering to this texture? */
GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
GLboolean Immutable; /**< GL_ARB_texture_storage */
diff --git a/mesalib/src/mesa/main/samplerobj.c b/mesalib/src/mesa/main/samplerobj.c
index 7cf0654ad..5d1b2adbb 100644
--- a/mesalib/src/mesa/main/samplerobj.c
+++ b/mesalib/src/mesa/main/samplerobj.c
@@ -55,12 +55,11 @@ _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name)
* Handle reference counting.
*/
void
-_mesa_reference_sampler_object(struct gl_context *ctx,
- struct gl_sampler_object **ptr,
- struct gl_sampler_object *samp)
+_mesa_reference_sampler_object_(struct gl_context *ctx,
+ struct gl_sampler_object **ptr,
+ struct gl_sampler_object *samp)
{
- if (*ptr == samp)
- return;
+ assert(*ptr != samp); /* The inline wrapper should prevent no-op calls */
if (*ptr) {
/* Unreference the old sampler */
diff --git a/mesalib/src/mesa/main/samplerobj.h b/mesalib/src/mesa/main/samplerobj.h
index fe7d5a7d3..0bfda4351 100644
--- a/mesalib/src/mesa/main/samplerobj.h
+++ b/mesalib/src/mesa/main/samplerobj.h
@@ -37,10 +37,29 @@ _mesa_get_samplerobj(struct gl_context *ctx, GLuint unit)
return &ctx->Texture.Unit[unit]._Current->Sampler;
}
+
+/** Does the given filter state do mipmap filtering? */
+static inline GLboolean
+_mesa_is_mipmap_filter(const struct gl_sampler_object *samp)
+{
+ return samp->MinFilter != GL_NEAREST && samp->MinFilter != GL_LINEAR;
+}
+
+
extern void
+_mesa_reference_sampler_object_(struct gl_context *ctx,
+ struct gl_sampler_object **ptr,
+ struct gl_sampler_object *samp);
+
+static inline void
_mesa_reference_sampler_object(struct gl_context *ctx,
struct gl_sampler_object **ptr,
- struct gl_sampler_object *samp);
+ struct gl_sampler_object *samp)
+{
+ if (*ptr != samp)
+ _mesa_reference_sampler_object_(ctx, ptr, samp);
+}
+
extern void
_mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name);
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index cf0a0cb2a..c54118212 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -43,6 +43,7 @@
#include "state.h"
#include "texcompress.h"
#include "teximage.h"
+#include "texobj.h"
#include "texstate.h"
#include "texpal.h"
#include "mtypes.h"
@@ -2602,9 +2603,7 @@ teximage(struct gl_context *ctx, GLuint dims,
_mesa_update_fbo_texture(ctx, texObj, face, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
@@ -2702,9 +2701,7 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
ctx->Driver.EGLImageTargetTexture2D(ctx, target,
texObj, texImage, image);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
}
_mesa_unlock_texture(ctx, texObj);
@@ -2965,9 +2962,7 @@ copyteximage(struct gl_context *ctx, GLuint dims,
_mesa_update_fbo_texture(ctx, texObj, face, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
}
else {
/* probably too large of image */
@@ -3598,9 +3593,7 @@ compressedteximage(struct gl_context *ctx, GLuint dims,
check_gen_mipmap(ctx, target, texObj, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY,
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index 590594826..cfaac64bf 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -262,7 +262,8 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
dest->_MaxLevel = src->_MaxLevel;
dest->_MaxLambda = src->_MaxLambda;
dest->GenerateMipmap = src->GenerateMipmap;
- dest->_Complete = src->_Complete;
+ dest->_BaseComplete = src->_BaseComplete;
+ dest->_MipmapComplete = src->_MipmapComplete;
COPY_4V(dest->Swizzle, src->Swizzle);
dest->_Swizzle = src->_Swizzle;
@@ -386,14 +387,26 @@ _mesa_reference_texobj_(struct gl_texture_object **ptr,
}
+enum base_mipmap { BASE, MIPMAP };
+
/**
- * Mark a texture object as incomplete.
+ * Mark a texture object as incomplete. There are actually three kinds of
+ * (in)completeness:
+ * 1. "base incomplete": the base level of the texture is invalid so no
+ * texturing is possible.
+ * 2. "mipmap incomplete": a non-base level of the texture is invalid so
+ * mipmap filtering isn't possible, but non-mipmap filtering is.
+ * 3. "texture incompleteness": some combination of texture state and
+ * sampler state renders the texture incomplete.
+ *
* \param t texture object
+ * \param bm either BASE or MIPMAP to indicate what's incomplete
* \param fmt... string describing why it's incomplete (for debugging).
*/
static void
-incomplete(struct gl_texture_object *t, const char *fmt, ...)
+incomplete(struct gl_texture_object *t, enum base_mipmap bm,
+ const char *fmt, ...)
{
#if 0
va_list args;
@@ -405,7 +418,9 @@ incomplete(struct gl_texture_object *t, const char *fmt, ...)
printf("Texture Obj %d incomplete because: %s\n", t->Name, s);
#endif
- t->_Complete = GL_FALSE;
+ if (bm == BASE)
+ t->_BaseComplete = GL_FALSE;
+ t->_MipmapComplete = GL_FALSE;
}
@@ -426,79 +441,94 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
struct gl_texture_object *t )
{
const GLint baseLevel = t->BaseLevel;
+ const struct gl_texture_image *baseImage;
GLint maxLog2 = 0, maxLevels = 0;
- t->_Complete = GL_TRUE; /* be optimistic */
+ /* We'll set these to FALSE if tests fail below */
+ t->_BaseComplete = GL_TRUE;
+ t->_MipmapComplete = GL_TRUE;
/* Detect cases where the application set the base level to an invalid
* value.
*/
if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) {
- incomplete(t, "base level = %d is invalid", baseLevel);
+ incomplete(t, BASE, "base level = %d is invalid", baseLevel);
+ return;
+ }
+
+ if (t->MaxLevel < baseLevel) {
+ incomplete(t, BASE, "MAX_LEVEL (%d) < BASE_LEVEL (%d)",
+ t->MaxLevel, baseLevel);
return;
}
+ baseImage = t->Image[0][baseLevel];
+
/* Always need the base level image */
- if (!t->Image[0][baseLevel]) {
- incomplete(t, "Image[baseLevel=%d] == NULL", baseLevel);
+ if (!baseImage) {
+ incomplete(t, BASE, "Image[baseLevel=%d] == NULL", baseLevel);
return;
}
/* Check width/height/depth for zero */
- if (t->Image[0][baseLevel]->Width == 0 ||
- t->Image[0][baseLevel]->Height == 0 ||
- t->Image[0][baseLevel]->Depth == 0) {
- incomplete(t, "texture width = 0");
+ if (baseImage->Width == 0 ||
+ baseImage->Height == 0 ||
+ baseImage->Depth == 0) {
+ incomplete(t, BASE, "texture width or height or depth = 0");
return;
}
- /* Compute _MaxLevel */
- if ((t->Target == GL_TEXTURE_1D) ||
- (t->Target == GL_TEXTURE_1D_ARRAY_EXT)) {
- maxLog2 = t->Image[0][baseLevel]->WidthLog2;
- maxLevels = ctx->Const.MaxTextureLevels;
+ /* Check if the texture values are integer */
+ {
+ GLenum datatype = _mesa_get_format_datatype(baseImage->TexFormat);
+ t->_IsIntegerFormat = datatype == GL_INT || datatype == GL_UNSIGNED_INT;
}
- else if ((t->Target == GL_TEXTURE_2D) ||
- (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) {
- maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,
- t->Image[0][baseLevel]->HeightLog2);
+
+ /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the
+ * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state).
+ */
+ switch (t->Target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ maxLog2 = baseImage->WidthLog2;
maxLevels = ctx->Const.MaxTextureLevels;
- }
- else if (t->Target == GL_TEXTURE_3D) {
- GLint max = MAX2(t->Image[0][baseLevel]->WidthLog2,
- t->Image[0][baseLevel]->HeightLog2);
- maxLog2 = MAX2(max, (GLint)(t->Image[0][baseLevel]->DepthLog2));
+ break;
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ maxLog2 = MAX2(baseImage->WidthLog2,
+ baseImage->HeightLog2);
+ maxLevels = ctx->Const.MaxTextureLevels;
+ break;
+ case GL_TEXTURE_3D:
+ maxLog2 = MAX3(baseImage->WidthLog2,
+ baseImage->HeightLog2,
+ baseImage->DepthLog2);
maxLevels = ctx->Const.Max3DTextureLevels;
- }
- else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
- maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,
- t->Image[0][baseLevel]->HeightLog2);
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ maxLog2 = MAX2(baseImage->WidthLog2,
+ baseImage->HeightLog2);
maxLevels = ctx->Const.MaxCubeTextureLevels;
- }
- else if (t->Target == GL_TEXTURE_RECTANGLE_NV ||
- t->Target == GL_TEXTURE_EXTERNAL_OES) {
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_TEXTURE_BUFFER:
+ case GL_TEXTURE_EXTERNAL_OES:
maxLog2 = 0; /* not applicable */
maxLevels = 1; /* no mipmapping */
- }
- else {
+ break;
+ default:
_mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness");
return;
}
ASSERT(maxLevels > 0);
- if (t->MaxLevel < t->BaseLevel) {
- incomplete(t, "MAX_LEVEL (%d) < BASE_LEVEL (%d)",
- t->MaxLevel, t->BaseLevel);
- return;
- }
-
- t->_MaxLevel = baseLevel + maxLog2;
+ t->_MaxLevel = baseLevel + maxLog2; /* 'p' in the GL spec */
t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel);
- t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1);
+ t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1); /* 'q' in the GL spec */
/* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */
- t->_MaxLambda = (GLfloat) (t->_MaxLevel - t->BaseLevel);
+ t->_MaxLambda = (GLfloat) (t->_MaxLevel - baseLevel);
if (t->Immutable) {
/* This texture object was created with glTexStorage1/2/3D() so we
@@ -510,193 +540,103 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
}
if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
- /* make sure that all six cube map level 0 images are the same size */
- const GLuint w = t->Image[0][baseLevel]->Width2;
- const GLuint h = t->Image[0][baseLevel]->Height2;
+ /* Make sure that all six cube map level 0 images are the same size.
+ * Note: we know that the image's width==height (we enforce that
+ * at glTexImage time) so we only need to test the width here.
+ */
GLuint face;
+ assert(baseImage->Width2 == baseImage->Height);
for (face = 1; face < 6; face++) {
+ assert(t->Image[face][baseLevel]->Width2 ==
+ t->Image[face][baseLevel]->Height2);
if (t->Image[face][baseLevel] == NULL ||
- t->Image[face][baseLevel]->Width2 != w ||
- t->Image[face][baseLevel]->Height2 != h) {
- incomplete(t, "Cube face missing or mismatched size");
+ t->Image[face][baseLevel]->Width2 != baseImage->Width2) {
+ incomplete(t, BASE, "Cube face missing or mismatched size");
return;
}
}
}
- /* extra checking for mipmaps */
- if (t->Sampler.MinFilter != GL_NEAREST && t->Sampler.MinFilter != GL_LINEAR) {
- /*
- * Mipmapping: determine if we have a complete set of mipmaps
- */
+ /*
+ * Do mipmap consistency checking.
+ * Note: we don't care about the current texture sampler state here.
+ * To determine texture completeness we'll either look at _BaseComplete
+ * or _MipmapComplete depending on the current minification filter mode.
+ */
+ {
GLint i;
- GLint minLevel = baseLevel;
- GLint maxLevel = t->_MaxLevel;
+ const GLint minLevel = baseLevel;
+ const GLint maxLevel = t->_MaxLevel;
+ GLuint width, height, depth, face, numFaces = 1;
if (minLevel > maxLevel) {
- incomplete(t, "minLevel > maxLevel");
+ incomplete(t, BASE, "minLevel > maxLevel");
return;
}
- /* Test dimension-independent attributes */
- for (i = minLevel; i <= maxLevel; i++) {
- if (t->Image[0][i]) {
- if (t->Image[0][i]->TexFormat != t->Image[0][baseLevel]->TexFormat) {
- incomplete(t, "Format[i] != Format[baseLevel]");
- return;
- }
- if (t->Image[0][i]->Border != t->Image[0][baseLevel]->Border) {
- incomplete(t, "Border[i] != Border[baseLevel]");
- return;
- }
- }
- }
+ /* Get the base image's dimensions */
+ width = baseImage->Width2;
+ height = baseImage->Height2;
+ depth = baseImage->Depth2;
- /* Test things which depend on number of texture image dimensions */
- if ((t->Target == GL_TEXTURE_1D) ||
- (t->Target == GL_TEXTURE_1D_ARRAY_EXT)) {
- /* Test 1-D mipmaps */
- GLuint width = t->Image[0][baseLevel]->Width2;
- for (i = baseLevel + 1; i < maxLevels; i++) {
- if (width > 1) {
- width /= 2;
- }
- if (i >= minLevel && i <= maxLevel) {
- const struct gl_texture_image *img = t->Image[0][i];
- if (!img) {
- incomplete(t, "1D Image[%d] is missing", i);
- return;
- }
- if (img->Width2 != width ) {
- incomplete(t, "1D Image[%d] bad width %u", i, img->Width2);
- return;
- }
- }
- if (width == 1) {
- return; /* found smallest needed mipmap, all done! */
- }
+ /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL textures */
+ for (i = baseLevel + 1; i < maxLevels; i++) {
+ /* Compute the expected size of image at level[i] */
+ if (width > 1) {
+ width /= 2;
}
- }
- else if ((t->Target == GL_TEXTURE_2D) ||
- (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) {
- /* Test 2-D mipmaps */
- GLuint width = t->Image[0][baseLevel]->Width2;
- GLuint height = t->Image[0][baseLevel]->Height2;
- for (i = baseLevel + 1; i < maxLevels; i++) {
- if (width > 1) {
- width /= 2;
- }
- if (height > 1) {
- height /= 2;
- }
+ if (height > 1 && t->Target != GL_TEXTURE_1D_ARRAY) {
+ height /= 2;
+ }
+ if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY) {
+ depth /= 2;
+ }
+
+ /* loop over cube faces (or single face otherwise) */
+ for (face = 0; face < numFaces; face++) {
if (i >= minLevel && i <= maxLevel) {
- const struct gl_texture_image *img = t->Image[0][i];
+ const struct gl_texture_image *img = t->Image[face][i];
+
if (!img) {
- incomplete(t, "2D Image[%d of %d] is missing", i, maxLevel);
+ incomplete(t, MIPMAP, "TexImage[%d] is missing", i);
return;
}
- if (img->Width2 != width) {
- incomplete(t, "2D Image[%d] bad width %u", i, img->Width2);
- return;
- }
- if (img->Height2 != height) {
- incomplete(t, "2D Image[i] bad height %u", i, img->Height2);
- return;
- }
- if (width==1 && height==1) {
- return; /* found smallest needed mipmap, all done! */
- }
- }
- }
- }
- else if (t->Target == GL_TEXTURE_3D) {
- /* Test 3-D mipmaps */
- GLuint width = t->Image[0][baseLevel]->Width2;
- GLuint height = t->Image[0][baseLevel]->Height2;
- GLuint depth = t->Image[0][baseLevel]->Depth2;
- for (i = baseLevel + 1; i < maxLevels; i++) {
- if (width > 1) {
- width /= 2;
- }
- if (height > 1) {
- height /= 2;
- }
- if (depth > 1) {
- depth /= 2;
- }
- if (i >= minLevel && i <= maxLevel) {
- const struct gl_texture_image *img = t->Image[0][i];
- if (!img) {
- incomplete(t, "3D Image[%d] is missing", i);
+ if (img->TexFormat != baseImage->TexFormat) {
+ incomplete(t, MIPMAP, "Format[i] != Format[baseLevel]");
return;
}
- if (img->_BaseFormat == GL_DEPTH_COMPONENT) {
- incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
+ if (img->Border != baseImage->Border) {
+ incomplete(t, MIPMAP, "Border[i] != Border[baseLevel]");
return;
}
if (img->Width2 != width) {
- incomplete(t, "3D Image[%d] bad width %u", i, img->Width2);
+ incomplete(t, MIPMAP, "TexImage[%d] bad width %u", i, img->Width2);
return;
}
if (img->Height2 != height) {
- incomplete(t, "3D Image[%d] bad height %u", i, img->Height2);
+ incomplete(t, MIPMAP, "TexImage[%d] bad height %u", i, img->Height2);
return;
}
if (img->Depth2 != depth) {
- incomplete(t, "3D Image[%d] bad depth %u", i, img->Depth2);
+ incomplete(t, MIPMAP, "TexImage[%d] bad depth %u", i, img->Depth2);
return;
}
- }
- if (width == 1 && height == 1 && depth == 1) {
- return; /* found smallest needed mipmap, all done! */
- }
- }
- }
- else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
- /* make sure 6 cube faces are consistant */
- GLuint width = t->Image[0][baseLevel]->Width2;
- GLuint height = t->Image[0][baseLevel]->Height2;
- for (i = baseLevel + 1; i < maxLevels; i++) {
- if (width > 1) {
- width /= 2;
- }
- if (height > 1) {
- height /= 2;
- }
- if (i >= minLevel && i <= maxLevel) {
- GLuint face;
- for (face = 0; face < 6; face++) {
- /* check that we have images defined */
- if (!t->Image[face][i]) {
- incomplete(t, "CubeMap Image[n][i] == NULL");
- return;
- }
- /* Don't support GL_DEPTH_COMPONENT for cube maps */
- if (ctx->VersionMajor < 3 && !ctx->Extensions.EXT_gpu_shader4) {
- if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
- incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
- return;
- }
- }
- /* check that all six images have same size */
- if (t->Image[face][i]->Width2 != width ||
- t->Image[face][i]->Height2 != height) {
- incomplete(t, "CubeMap Image[n][i] bad size");
+
+ /* Extra checks for cube textures */
+ if (face > 0) {
+ /* check that cube faces are the same size */
+ if (img->Width2 != t->Image[0][i]->Width2 ||
+ img->Height2 != t->Image[0][i]->Height2) {
+ incomplete(t, MIPMAP, "CubeMap Image[n][i] bad size");
return;
}
- }
- }
- if (width == 1 && height == 1) {
- return; /* found smallest needed mipmap, all done! */
+ }
}
}
- }
- else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
- /* XXX special checking? */
- }
- else {
- /* Target = ??? */
- _mesa_problem(ctx, "Bug in gl_test_texture_object_completeness\n");
+
+ if (width == 1 && height == 1 && depth == 1) {
+ return; /* found smallest needed mipmap, all done! */
+ }
}
}
}
@@ -752,7 +692,8 @@ void
_mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj,
GLboolean invalidate_state)
{
- texObj->_Complete = GL_FALSE;
+ texObj->_BaseComplete = GL_FALSE;
+ texObj->_MipmapComplete = GL_FALSE;
if (invalidate_state)
ctx->NewState |= _NEW_TEXTURE;
}
@@ -875,7 +816,8 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
}
_mesa_test_texobj_completeness(ctx, texObj);
- assert(texObj->_Complete);
+ assert(texObj->_BaseComplete);
+ assert(texObj->_MipmapComplete);
ctx->Shared->FallbackTex[tex] = texObj;
}
diff --git a/mesalib/src/mesa/main/texobj.h b/mesalib/src/mesa/main/texobj.h
index 03dfbe304..c020b9013 100644
--- a/mesalib/src/mesa/main/texobj.h
+++ b/mesalib/src/mesa/main/texobj.h
@@ -35,6 +35,7 @@
#include "compiler.h"
#include "glheader.h"
#include "mtypes.h"
+#include "samplerobj.h"
/**
@@ -77,6 +78,26 @@ _mesa_reference_texobj(struct gl_texture_object **ptr,
}
+/** Is the texture "complete" with respect to the given sampler state? */
+static inline GLboolean
+_mesa_is_texture_complete(const struct gl_texture_object *texObj,
+ const struct gl_sampler_object *sampler)
+{
+ if (texObj->_IsIntegerFormat &&
+ (sampler->MagFilter != GL_NEAREST ||
+ (sampler->MinFilter != GL_NEAREST &&
+ sampler->MinFilter != GL_NEAREST_MIPMAP_NEAREST))) {
+ /* If the format is integer, only nearest filtering is allowed */
+ return GL_FALSE;
+ }
+
+ if (_mesa_is_mipmap_filter(sampler))
+ return texObj->_MipmapComplete;
+ else
+ return texObj->_BaseComplete;
+}
+
+
extern void
_mesa_test_texobj_completeness( const struct gl_context *ctx,
struct gl_texture_object *obj );
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index 9a2ec518f..9abc503e3 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -41,6 +41,7 @@
#include "main/mtypes.h"
#include "main/state.h"
#include "main/texcompress.h"
+#include "main/texobj.h"
#include "main/texparam.h"
#include "main/teximage.h"
#include "main/texstate.h"
@@ -211,8 +212,7 @@ flush(struct gl_context *ctx)
/**
* This is called just prior to changing any texture object state which
- * can effect texture completeness (texture base level, max level,
- * minification filter).
+ * can effect texture completeness (texture base level, max level).
* Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
* state flag and then mark the texture object as 'incomplete' so that any
* per-texture derived state gets recomputed.
@@ -221,7 +221,7 @@ static inline void
incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
{
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- texObj->_Complete = GL_FALSE;
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
}
@@ -241,7 +241,7 @@ set_tex_parameteri(struct gl_context *ctx,
switch (params[0]) {
case GL_NEAREST:
case GL_LINEAR:
- incomplete(ctx, texObj);
+ flush(ctx);
texObj->Sampler.MinFilter = params[0];
return GL_TRUE;
case GL_NEAREST_MIPMAP_NEAREST:
@@ -250,7 +250,7 @@ set_tex_parameteri(struct gl_context *ctx,
case GL_LINEAR_MIPMAP_LINEAR:
if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
texObj->Target != GL_TEXTURE_EXTERNAL_OES) {
- incomplete(ctx, texObj);
+ flush(ctx);
texObj->Sampler.MinFilter = params[0];
return GL_TRUE;
}
diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c
index 187ec9c36..ee778ffd0 100644
--- a/mesalib/src/mesa/main/texstate.c
+++ b/mesalib/src/mesa/main/texstate.c
@@ -569,10 +569,13 @@ update_texture_state( struct gl_context *ctx )
for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
if (enabledTargets & (1 << texIndex)) {
struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
- if (!texObj->_Complete) {
+ struct gl_sampler_object *sampler = texUnit->Sampler ?
+ texUnit->Sampler : &texObj->Sampler;
+
+ if (!_mesa_is_texture_complete(texObj, sampler)) {
_mesa_test_texobj_completeness(ctx, texObj);
}
- if (texObj->_Complete) {
+ if (_mesa_is_texture_complete(texObj, sampler)) {
texUnit->_ReallyEnabled = 1 << texIndex;
_mesa_reference_texobj(&texUnit->_Current, texObj);
break;
diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c
index c2114c227..f2c1435d9 100644
--- a/mesalib/src/mesa/main/transformfeedback.c
+++ b/mesalib/src/mesa/main/transformfeedback.c
@@ -89,33 +89,6 @@ reference_transform_feedback_object(struct gl_transform_feedback_object **ptr,
/**
- * Check if the given primitive mode (as in glBegin(mode)) is compatible
- * with the current transform feedback mode (if it's enabled).
- * This is to be called from glBegin(), glDrawArrays(), glDrawElements(), etc.
- *
- * \return GL_TRUE if the mode is OK, GL_FALSE otherwise.
- */
-GLboolean
-_mesa_validate_primitive_mode(struct gl_context *ctx, GLenum mode)
-{
- if (ctx->TransformFeedback.CurrentObject->Active &&
- !ctx->TransformFeedback.CurrentObject->Paused) {
- switch (mode) {
- case GL_POINTS:
- return ctx->TransformFeedback.Mode == GL_POINTS;
- case GL_LINES:
- case GL_LINE_STRIP:
- case GL_LINE_LOOP:
- return ctx->TransformFeedback.Mode == GL_LINES;
- default:
- return ctx->TransformFeedback.Mode == GL_TRIANGLES;
- }
- }
- return GL_TRUE;
-}
-
-
-/**
* Check that all the buffer objects currently bound for transform
* feedback actually exist. Raise a GL_INVALID_OPERATION error if
* any buffers are missing.
diff --git a/mesalib/src/mesa/main/transformfeedback.h b/mesalib/src/mesa/main/transformfeedback.h
index 8a6672d58..7d63de017 100644
--- a/mesalib/src/mesa/main/transformfeedback.h
+++ b/mesalib/src/mesa/main/transformfeedback.h
@@ -42,9 +42,6 @@ _mesa_free_transform_feedback(struct gl_context *ctx);
#if FEATURE_EXT_transform_feedback
extern GLboolean
-_mesa_validate_primitive_mode(struct gl_context *ctx, GLenum mode);
-
-extern GLboolean
_mesa_validate_transform_feedback_buffers(struct gl_context *ctx);
diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp
index 869f7d373..991df7896 100644
--- a/mesalib/src/mesa/main/uniform_query.cpp
+++ b/mesalib/src/mesa/main/uniform_query.cpp
@@ -203,10 +203,18 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
const union gl_constant_value *const src =
&uni->storage[offset * elements];
- unsigned bytes = sizeof(uni->storage[0]) * elements;
- if (bytes > (unsigned) bufSize) {
- elements = bufSize / sizeof(uni->storage[0]);
- bytes = bufSize;
+ assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
+ returnType == GLSL_TYPE_UINT);
+ /* The three (currently) supported types all have the same size,
+ * which is of course the same as their union. That'll change
+ * with glGetUniformdv()...
+ */
+ unsigned bytes = sizeof(src[0]) * elements;
+ if (bufSize < 0 || bytes > (unsigned) bufSize) {
+ _mesa_error( ctx, GL_INVALID_OPERATION,
+ "glGetnUniform*vARB(out of bounds: bufSize is %d,"
+ " but %u bytes are required)", bufSize, bytes );
+ return;
}
/* If the return type and the uniform's native type are "compatible,"
diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c
index e0214a88a..be1e1728d 100644
--- a/mesalib/src/mesa/main/uniforms.c
+++ b/mesalib/src/mesa/main/uniforms.c
@@ -479,7 +479,7 @@ _mesa_GetnUniformdvARB(GLhandleARB program, GLint location,
(void) params;
/*
- _mesa_get_uniform(ctx, program, location, bufSize, GL_DOUBLE, params);
+ _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_DOUBLE, params);
*/
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB"
"(GL_ARB_gpu_shader_fp64 not implemented)");