diff options
Diffstat (limited to 'mesalib/src/mesa/main')
23 files changed, 325 insertions, 232 deletions
diff --git a/mesalib/src/mesa/main/APIspec.xml b/mesalib/src/mesa/main/APIspec.xml index 574480e28..a92bb437c 100644 --- a/mesalib/src/mesa/main/APIspec.xml +++ b/mesalib/src/mesa/main/APIspec.xml @@ -631,12 +631,6 @@ <desc name="pname"> <value name="GL_RGB_SCALE"/> <value name="GL_ALPHA_SCALE"/> - - <desc name="param" convert="true" error="GL_INVALID_VALUE"> - <value name="1.0"/> - <value name="2.0"/> - <value name="4.0"/> - </desc> </desc> <desc name="pname"> diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c index e67957d4d..1dc1c1b97 100644 --- a/mesalib/src/mesa/main/attrib.c +++ b/mesalib/src/mesa/main/attrib.c @@ -1279,30 +1279,6 @@ _mesa_PopAttrib(void) /** - * Helper for incrementing/decrementing vertex buffer object reference - * counts when pushing/popping the GL_CLIENT_VERTEX_ARRAY_BIT attribute group. - */ -static void -adjust_buffer_object_ref_counts(struct gl_array_object *arrayObj, GLint step) -{ - GLuint i; - - arrayObj->Vertex.BufferObj->RefCount += step; - arrayObj->Weight.BufferObj->RefCount += step; - arrayObj->Normal.BufferObj->RefCount += step; - arrayObj->Color.BufferObj->RefCount += step; - arrayObj->SecondaryColor.BufferObj->RefCount += step; - arrayObj->FogCoord.BufferObj->RefCount += step; - arrayObj->Index.BufferObj->RefCount += step; - arrayObj->EdgeFlag.BufferObj->RefCount += step; - for (i = 0; i < Elements(arrayObj->TexCoord); i++) - arrayObj->TexCoord[i].BufferObj->RefCount += step; - for (i = 0; i < Elements(arrayObj->VertexAttrib); i++) - arrayObj->VertexAttrib[i].BufferObj->RefCount += step; -} - - -/** * Copy gl_pixelstore_attrib from src to dst, updating buffer * object refcounts. */ @@ -1327,6 +1303,151 @@ copy_pixelstore(struct gl_context *ctx, #define GL_CLIENT_PACK_BIT (1<<20) #define GL_CLIENT_UNPACK_BIT (1<<21) +/** + * Copy gl_array_object from src to dest. + * 'dest' must be in an initialized state. + */ +static void +copy_array_object(struct gl_context *ctx, + struct gl_array_object *dest, + struct gl_array_object *src) +{ + GLuint i; + + /* skip Name */ + /* skip RefCount */ + + /* In theory must be the same anyway, but on recreate make sure it matches */ + dest->VBOonly = src->VBOonly; + + _mesa_copy_client_array(ctx, &dest->Vertex, &src->Vertex); + _mesa_copy_client_array(ctx, &dest->Weight, &src->Weight); + _mesa_copy_client_array(ctx, &dest->Normal, &src->Normal); + _mesa_copy_client_array(ctx, &dest->Color, &src->Color); + _mesa_copy_client_array(ctx, &dest->SecondaryColor, &src->SecondaryColor); + _mesa_copy_client_array(ctx, &dest->FogCoord, &src->FogCoord); + _mesa_copy_client_array(ctx, &dest->Index, &src->Index); + _mesa_copy_client_array(ctx, &dest->EdgeFlag, &src->EdgeFlag); +#if FEATURE_point_size_array + _mesa_copy_client_array(ctx, &dest->PointSize, &src->PointSize); +#endif + for (i = 0; i < Elements(src->TexCoord); i++) + _mesa_copy_client_array(ctx, &dest->TexCoord[i], &src->TexCoord[i]); + for (i = 0; i < Elements(src->VertexAttrib); i++) + _mesa_copy_client_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]); + + /* _Enabled must be the same than on push */ + dest->_Enabled = src->_Enabled; + dest->_MaxElement = src->_MaxElement; +} + +/** + * Copy gl_array_attrib from src to dest. + * 'dest' must be in an initialized state. + */ +static void +copy_array_attrib(struct gl_context *ctx, + struct gl_array_attrib *dest, + struct gl_array_attrib *src) +{ + /* skip ArrayObj */ + /* skip DefaultArrayObj, Objects */ + dest->ActiveTexture = src->ActiveTexture; + dest->LockFirst = src->LockFirst; + dest->LockCount = src->LockCount; + dest->PrimitiveRestart = src->PrimitiveRestart; + dest->RestartIndex = src->RestartIndex; + /* skip NewState */ + /* skip RebindArrays */ + + copy_array_object(ctx, dest->ArrayObj, src->ArrayObj); + + /* skip ArrayBufferObj */ + /* skip ElementArrayBufferObj */ +} + +/** + * Save the content of src to dest. + */ +static void +save_array_attrib(struct gl_context *ctx, + struct gl_array_attrib *dest, + struct gl_array_attrib *src) +{ + /* Set the Name, needed for restore, but do never overwrite. + * Needs to match value in the object hash. */ + dest->ArrayObj->Name = src->ArrayObj->Name; + /* And copy all of the rest. */ + copy_array_attrib(ctx, dest, src); + + /* Just reference them here */ + _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj, + src->ArrayBufferObj); + _mesa_reference_buffer_object(ctx, &dest->ElementArrayBufferObj, + src->ElementArrayBufferObj); +} + +/** + * Restore the content of src to dest. + */ +static void +restore_array_attrib(struct gl_context *ctx, + struct gl_array_attrib *dest, + struct gl_array_attrib *src) +{ + /* Restore or recreate the array object by its name ... */ + _mesa_BindVertexArrayAPPLE(src->ArrayObj->Name); + + /* ... and restore its content */ + copy_array_attrib(ctx, dest, src); + + /* Restore or recreate the buffer objects by the names ... */ + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + src->ArrayBufferObj->Name); + _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, + src->ElementArrayBufferObj->Name); + + /* Better safe than sorry?! */ + dest->RebindArrays = GL_TRUE; + + /* FIXME: Should some bits in ctx->Array->NewState also be set + * FIXME: here? It seems like it should be set to inclusive-or + * FIXME: of the old ArrayObj->_Enabled and the new _Enabled. + * ... just do it. + */ + dest->NewState |= src->ArrayObj->_Enabled | dest->ArrayObj->_Enabled; +} + +/** + * init/alloc the fields of 'attrib'. + * Needs to the init part matching free_array_attrib_data below. + */ +static void +init_array_attrib_data(struct gl_context *ctx, + struct gl_array_attrib *attrib) +{ + /* Get a non driver gl_array_object. */ + attrib->ArrayObj = CALLOC_STRUCT( gl_array_object ); + _mesa_initialize_array_object(ctx, attrib->ArrayObj, 0); +} + +/** + * Free/unreference the fields of 'attrib' but don't delete it (that's + * done later in the calling code). + * Needs to the cleanup part matching init_array_attrib_data above. + */ +static void +free_array_attrib_data(struct gl_context *ctx, + struct gl_array_attrib *attrib) +{ + /* We use a non driver array object, so don't just unref since we would + * end up using the drivers DeleteArrayObject function for deletion. */ + _mesa_delete_array_object(ctx, attrib->ArrayObj); + attrib->ArrayObj = 0; + _mesa_reference_buffer_object(ctx, &attrib->ArrayBufferObj, NULL); + _mesa_reference_buffer_object(ctx, &attrib->ElementArrayBufferObj, NULL); +} + void GLAPIENTRY _mesa_PushClientAttrib(GLbitfield mask) @@ -1360,26 +1481,10 @@ _mesa_PushClientAttrib(GLbitfield mask) if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { struct gl_array_attrib *attr; - struct gl_array_object *obj; - - attr = MALLOC_STRUCT( gl_array_attrib ); - obj = MALLOC_STRUCT( gl_array_object ); - -#if FEATURE_ARB_vertex_buffer_object - /* increment ref counts since we're copying pointers to these objects */ - ctx->Array.ArrayBufferObj->RefCount++; - ctx->Array.ElementArrayBufferObj->RefCount++; -#endif - - memcpy( attr, &ctx->Array, sizeof(struct gl_array_attrib) ); - memcpy( obj, ctx->Array.ArrayObj, sizeof(struct gl_array_object) ); - - attr->ArrayObj = obj; - + attr = CALLOC_STRUCT( gl_array_attrib ); + init_array_attrib_data(ctx, attr); + save_array_attrib(ctx, attr, &ctx->Array); save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr); - - /* bump reference counts on buffer objects */ - adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, 1); } ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head; @@ -1426,36 +1531,10 @@ _mesa_PopClientAttrib(void) ctx->NewState |= _NEW_PACKUNPACK; break; case GL_CLIENT_VERTEX_ARRAY_BIT: { - struct gl_array_attrib * data = + struct gl_array_attrib * attr = (struct gl_array_attrib *) node->data; - - adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, -1); - - ctx->Array.ActiveTexture = data->ActiveTexture; - if (data->LockCount != 0) - _mesa_LockArraysEXT(data->LockFirst, data->LockCount); - else if (ctx->Array.LockCount) - _mesa_UnlockArraysEXT(); - - _mesa_BindVertexArrayAPPLE( data->ArrayObj->Name ); - -#if FEATURE_ARB_vertex_buffer_object - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, - data->ArrayBufferObj->Name); - _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, - data->ElementArrayBufferObj->Name); -#endif - - memcpy( ctx->Array.ArrayObj, data->ArrayObj, - sizeof( struct gl_array_object ) ); - - FREE( data->ArrayObj ); - - /* FIXME: Should some bits in ctx->Array->NewState also be set - * FIXME: here? It seems like it should be set to inclusive-or - * FIXME: of the old ArrayObj->_Enabled and the new _Enabled. - */ - + restore_array_attrib(ctx, &ctx->Array, attr); + free_array_attrib_data(ctx, attr); ctx->NewState |= _NEW_ARRAY; break; } diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c index 67241eb1e..f2e8f568c 100644 --- a/mesalib/src/mesa/main/bufferobj.c +++ b/mesalib/src/mesa/main/bufferobj.c @@ -571,7 +571,7 @@ bind_buffer_object(struct gl_context *ctx, GLenum target, GLuint buffer) /* Get pointer to old buffer object (to be unbound) */ oldBufObj = *bindTarget; - if (oldBufObj && oldBufObj->Name == buffer) + if (oldBufObj && oldBufObj->Name == buffer && !oldBufObj->DeletePending) return; /* rebinding the same buffer object- no change */ /* @@ -773,6 +773,17 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids) /* The ID is immediately freed for re-use */ _mesa_HashRemove(ctx->Shared->BufferObjects, ids[i]); + /* Make sure we do not run into the classic ABA problem on bind. + * We don't want to allow re-binding a buffer object that's been + * "deleted" by glDeleteBuffers(). + * + * The explicit rebinding to the default object in the current context + * prevents the above in the current context, but another context + * sharing the same objects might suffer from this problem. + * The alternative would be to do the hash lookup in any case on bind + * which would introduce more runtime overhead than this. + */ + bufObj->DeletePending = GL_TRUE; _mesa_reference_buffer_object(ctx, &bufObj, NULL); } } diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h index 89d6cda91..921e30222 100644 --- a/mesalib/src/mesa/main/compiler.h +++ b/mesalib/src/mesa/main/compiler.h @@ -150,7 +150,7 @@ extern "C" { * inline a static function that we later use in an alias. - ajax */ #ifndef PUBLIC -# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# if (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define PUBLIC __attribute__((visibility("default"))) # define USED __attribute__((used)) # else diff --git a/mesalib/src/mesa/main/context.h b/mesalib/src/mesa/main/context.h index a4c7ba2c5..a9df0a866 100644 --- a/mesalib/src/mesa/main/context.h +++ b/mesalib/src/mesa/main/context.h @@ -233,7 +233,7 @@ do { \ * glBegin()/glEnd() pair, with return value. * * \param ctx GL context. - * \param retval value to return value in case the assertion fails. + * \param retval value to return in case the assertion fails. */ #define ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, retval) \ do { \ @@ -274,7 +274,7 @@ do { \ * glBegin()/glEnd() pair and flush the vertices, with return value. * * \param ctx GL context. - * \param retval value to return value in case the assertion fails. + * \param retval value to return in case the assertion fails. */ #define ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval) \ do { \ diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c index 625649e9d..d901bddf8 100644 --- a/mesalib/src/mesa/main/dlist.c +++ b/mesalib/src/mesa/main/dlist.c @@ -939,7 +939,9 @@ unpack_image(struct gl_context *ctx, GLuint dimensions, } return image; } + /* bad access! */ + _mesa_error(ctx, GL_INVALID_OPERATION, "invalid PBO access"); return NULL; } diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index f9da54e73..c56062ac6 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -2486,6 +2486,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, void GLAPIENTRY _mesa_GenerateMipmapEXT(GLenum target) { + struct gl_texture_image *srcImage; struct gl_texture_object *texObj; GLboolean error; @@ -2532,6 +2533,13 @@ _mesa_GenerateMipmapEXT(GLenum target) } _mesa_lock_texture(ctx, texObj); + + srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel); + if (!srcImage) { + _mesa_unlock_texture(ctx, texObj); + return; + } + if (target == GL_TEXTURE_CUBE_MAP) { GLuint face; for (face = 0; face < 6; face++) diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index 160a97c0c..b5500714b 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -1137,8 +1137,8 @@ load_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit ) ir_variable *rot_mat_0_var, *rot_mat_1_var; ir_dereference_variable *rot_mat_0, *rot_mat_1; - rot_mat_0_var = p->shader->symbols->get_variable("gl_MESABumpRotMatrix0"); - rot_mat_1_var = p->shader->symbols->get_variable("gl_MESABumpRotMatrix1"); + rot_mat_0_var = p->shader->symbols->get_variable("gl_BumpRotMatrix0MESA"); + rot_mat_1_var = p->shader->symbols->get_variable("gl_BumpRotMatrix1MESA"); rot_mat_0 = new(p->mem_ctx) ir_dereference_variable(rot_mat_0_var); rot_mat_1 = new(p->mem_ctx) ir_dereference_variable(rot_mat_1_var); @@ -1229,7 +1229,7 @@ emit_fog_instructions(struct texenv_fragment_program *p, temp = new(p->mem_ctx) ir_dereference_variable(fog_result); fragcolor = new(p->mem_ctx) ir_swizzle(temp, 0, 1, 2, 3, 3); - oparams = p->shader->symbols->get_variable("gl_MESAFogParamsOptimized"); + oparams = p->shader->symbols->get_variable("gl_FogParamsOptimizedMESA"); fogcoord = p->shader->symbols->get_variable("gl_FogFragCoord"); params = p->shader->symbols->get_variable("gl_Fog"); f = new(p->mem_ctx) ir_dereference_variable(fogcoord); @@ -1464,7 +1464,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key) validate_ir_tree(p.shader->ir); - while (do_common_optimization(p.shader->ir, false, 32)) + while (do_common_optimization(p.shader->ir, false, false, 32)) ; reparent_ir(p.shader->ir, p.shader->ir); diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c index 345a1c53e..2469e4265 100644 --- a/mesalib/src/mesa/main/imports.c +++ b/mesalib/src/mesa/main/imports.c @@ -514,7 +514,7 @@ _mesa_ffsll(int64_t val) #endif #if !defined(__GNUC__) ||\ - ((_GNUC__ == 3 && __GNUC_MINOR__ < 4) && __GNUC__ < 4) + ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */ /** * Return number of bits set in given GLuint. */ diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h index 20fa148fe..797f35742 100644 --- a/mesalib/src/mesa/main/imports.h +++ b/mesalib/src/mesa/main/imports.h @@ -453,7 +453,7 @@ static inline int32_t _mesa_next_pow_two_32(uint32_t x) { #if defined(__GNUC__) && \ - ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) + ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */ uint32_t y = (x != 1); return (1 + y) << ((__builtin_clz(x - y) ^ 31) ); #else @@ -472,7 +472,7 @@ static inline int64_t _mesa_next_pow_two_64(uint64_t x) { #if defined(__GNUC__) && \ - ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) + ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */ uint64_t y = (x != 1); if (sizeof(x) == sizeof(long)) return (1 + y) << ((__builtin_clzl(x - y) ^ 63)); @@ -499,7 +499,7 @@ static inline GLuint _mesa_logbase2(GLuint n) { #if defined(__GNUC__) && \ - ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) + ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */ return (31 - __builtin_clz(n | 1)); #else GLuint pos = 0; @@ -576,7 +576,7 @@ _mesa_init_sqrt_table(void); #define _mesa_ffs(i) ffs(i) #define _mesa_ffsll(i) ffsll(i) -#if ((_GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) +#if ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */ #define _mesa_bitcount(i) __builtin_popcount(i) #define _mesa_bitcount_64(i) __builtin_popcountll(i) #else diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 17c645a7e..411768641 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1261,11 +1261,6 @@ struct gl_texture_image GLuint Level; /**< Which mipmap level am I? */ /** Cube map face: index into gl_texture_object::Image[] array */ GLuint Face; - - GLuint RowStride; /**< Padded width in units of texels */ - GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to - each 2D slice in 'Data', in texels */ - GLvoid *Data; /**< Image data, accessed via FetchTexel() */ }; @@ -1535,6 +1530,7 @@ struct gl_buffer_object GLintptr Offset; /**< Mapped offset */ GLsizeiptr Length; /**< Mapped length */ /*@}*/ + GLboolean DeletePending; /**< true if buffer object is removed from the hash */ GLboolean Written; /**< Ever written to? (for debugging) */ GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ }; @@ -2736,6 +2732,20 @@ struct gl_constants /* GL_ARB_robustness */ GLenum ResetStrategy; + + /** + * Whether the implementation strips out and ignores texture borders. + * + * Many GPU hardware implementations don't support rendering with texture + * borders and mipmapped textures. (Note: not static border color, but the + * old 1-pixel border around each edge). Implementations then have to do + * slow fallbacks to be correct, or just ignore the border and be fast but + * wrong. Setting the flag stripts the border off of TexImage calls, + * providing "fast but wrong" at significantly reduced driver complexity. + * + * Texture borders are deprecated in GL 3.0. + **/ + GLboolean StripTextureBorder; }; diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c index 092e541c5..ecdeaf5dc 100644 --- a/mesalib/src/mesa/main/pack.c +++ b/mesalib/src/mesa/main/pack.c @@ -3717,6 +3717,7 @@ _mesa_unpack_color_span_ubyte(struct gl_context *ctx, if (!indexes) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + free(rgba); return; } diff --git a/mesalib/src/mesa/main/pixelstore.c b/mesalib/src/mesa/main/pixelstore.c index d957950ed..81474491d 100644 --- a/mesalib/src/mesa/main/pixelstore.c +++ b/mesalib/src/mesa/main/pixelstore.c @@ -214,7 +214,7 @@ _mesa_PixelStorei( GLenum pname, GLint param ) void GLAPIENTRY _mesa_PixelStoref( GLenum pname, GLfloat param ) { - _mesa_PixelStorei( pname, (GLint) param ); + _mesa_PixelStorei( pname, IROUND(param) ); } diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c index 98ca733c0..80fd03b91 100644 --- a/mesalib/src/mesa/main/state.c +++ b/mesalib/src/mesa/main/state.c @@ -461,7 +461,7 @@ static void update_twoside(struct gl_context *ctx) { if (ctx->Shader.CurrentVertexProgram || - ctx->VertexProgram.Current) { + ctx->VertexProgram._Enabled) { ctx->VertexProgram._TwoSideEnabled = ctx->VertexProgram.TwoSideEnabled; } else { ctx->VertexProgram._TwoSideEnabled = (ctx->Light.Enabled && diff --git a/mesalib/src/mesa/main/texcompress.c b/mesalib/src/mesa/main/texcompress.c index 03e05d5ef..0458b9b68 100644 --- a/mesalib/src/mesa/main/texcompress.c +++ b/mesalib/src/mesa/main/texcompress.c @@ -461,8 +461,8 @@ _mesa_decompress_image(gl_format format, GLuint width, GLuint height, /* setup dummy texture image info */ memset(&texImage, 0, sizeof(texImage)); - texImage.Base.Data = (void *) src; - texImage.Base.RowStride = srcRowStride; + texImage.Data = (void *) src; + texImage.RowStride = srcRowStride; switch (format) { /* DXT formats */ diff --git a/mesalib/src/mesa/main/texcompress_fxt1.c b/mesalib/src/mesa/main/texcompress_fxt1.c index 41630a47c..d5c73e3b4 100644 --- a/mesalib/src/mesa/main/texcompress_fxt1.c +++ b/mesalib/src/mesa/main/texcompress_fxt1.c @@ -177,7 +177,7 @@ _mesa_fetch_texel_2d_f_rgba_fxt1( const struct swrast_texture_image *texImage, /* just sample as GLubyte and convert to float here */ GLubyte rgba[4]; (void) k; - fxt1_decode_1(texImage->Base.Data, texImage->Base.RowStride, i, j, rgba); + fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, rgba); texel[RCOMP] = UBYTE_TO_FLOAT(rgba[RCOMP]); texel[GCOMP] = UBYTE_TO_FLOAT(rgba[GCOMP]); texel[BCOMP] = UBYTE_TO_FLOAT(rgba[BCOMP]); @@ -192,7 +192,7 @@ _mesa_fetch_texel_2d_f_rgb_fxt1( const struct swrast_texture_image *texImage, /* just sample as GLubyte and convert to float here */ GLubyte rgba[4]; (void) k; - fxt1_decode_1(texImage->Base.Data, texImage->Base.RowStride, i, j, rgba); + fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, rgba); texel[RCOMP] = UBYTE_TO_FLOAT(rgba[RCOMP]); texel[GCOMP] = UBYTE_TO_FLOAT(rgba[GCOMP]); texel[BCOMP] = UBYTE_TO_FLOAT(rgba[BCOMP]); diff --git a/mesalib/src/mesa/main/texcompress_rgtc.c b/mesalib/src/mesa/main/texcompress_rgtc.c index b03cd28b8..3586fc39d 100644 --- a/mesalib/src/mesa/main/texcompress_rgtc.c +++ b/mesalib/src/mesa/main/texcompress_rgtc.c @@ -325,7 +325,7 @@ _mesa_fetch_texel_2d_f_red_rgtc1(const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel) { GLubyte red; - unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data), + unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data, i, j, &red, 1); texel[RCOMP] = UBYTE_TO_FLOAT(red); texel[GCOMP] = 0.0; @@ -338,7 +338,7 @@ _mesa_fetch_texel_2d_f_signed_red_rgtc1(const struct swrast_texture_image *texIm GLint i, GLint j, GLint k, GLfloat *texel) { GLbyte red; - signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data), + signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data), i, j, &red, 1); texel[RCOMP] = BYTE_TO_FLOAT_TEX(red); texel[GCOMP] = 0.0; @@ -351,9 +351,9 @@ _mesa_fetch_texel_2d_f_rg_rgtc2(const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel) { GLubyte red, green; - unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data), + unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data, i, j, &red, 2); - unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data) + 8, + unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data + 8, i, j, &green, 2); texel[RCOMP] = UBYTE_TO_FLOAT(red); texel[GCOMP] = UBYTE_TO_FLOAT(green); @@ -366,9 +366,9 @@ _mesa_fetch_texel_2d_f_signed_rg_rgtc2(const struct swrast_texture_image *texIma GLint i, GLint j, GLint k, GLfloat *texel) { GLbyte red, green; - signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data), + signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data), i, j, &red, 2); - signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data) + 8, + signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data) + 8, i, j, &green, 2); texel[RCOMP] = BYTE_TO_FLOAT_TEX(red); texel[GCOMP] = BYTE_TO_FLOAT_TEX(green); @@ -381,7 +381,7 @@ _mesa_fetch_texel_2d_f_l_latc1(const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel) { GLubyte red; - unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data), + unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data, i, j, &red, 1); texel[RCOMP] = texel[GCOMP] = @@ -394,7 +394,7 @@ _mesa_fetch_texel_2d_f_signed_l_latc1(const struct swrast_texture_image *texImag GLint i, GLint j, GLint k, GLfloat *texel) { GLbyte red; - signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data), + signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data), i, j, &red, 1); texel[RCOMP] = texel[GCOMP] = @@ -407,9 +407,9 @@ _mesa_fetch_texel_2d_f_la_latc2(const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel) { GLubyte red, green; - unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data), + unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data, i, j, &red, 2); - unsigned_fetch_texel_rgtc(texImage->Base.RowStride, (GLubyte *)(texImage->Base.Data) + 8, + unsigned_fetch_texel_rgtc(texImage->RowStride, texImage->Data + 8, i, j, &green, 2); texel[RCOMP] = texel[GCOMP] = @@ -422,9 +422,9 @@ _mesa_fetch_texel_2d_f_signed_la_latc2(const struct swrast_texture_image *texIma GLint i, GLint j, GLint k, GLfloat *texel) { GLbyte red, green; - signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data), + signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data), i, j, &red, 2); - signed_fetch_texel_rgtc(texImage->Base.RowStride, (GLbyte *)(texImage->Base.Data) + 8, + signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data) + 8, i, j, &green, 2); texel[RCOMP] = texel[GCOMP] = diff --git a/mesalib/src/mesa/main/texcompress_s3tc.c b/mesalib/src/mesa/main/texcompress_s3tc.c index 29386a37d..11c7db4ef 100644 --- a/mesalib/src/mesa/main/texcompress_s3tc.c +++ b/mesalib/src/mesa/main/texcompress_s3tc.c @@ -402,8 +402,8 @@ fetch_texel_2d_rgb_dxt1( const struct swrast_texture_image *texImage, { (void) k; if (fetch_ext_rgb_dxt1) { - fetch_ext_rgb_dxt1(texImage->Base.RowStride, - (GLubyte *)(texImage)->Base.Data, i, j, texel); + fetch_ext_rgb_dxt1(texImage->RowStride, + texImage->Data, i, j, texel); } else _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgb_dxt1"); @@ -430,8 +430,8 @@ fetch_texel_2d_rgba_dxt1( const struct swrast_texture_image *texImage, { (void) k; if (fetch_ext_rgba_dxt1) { - fetch_ext_rgba_dxt1(texImage->Base.RowStride, - (GLubyte *)(texImage)->Base.Data, i, j, texel); + fetch_ext_rgba_dxt1(texImage->RowStride, + texImage->Data, i, j, texel); } else _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt1\n"); @@ -458,9 +458,8 @@ fetch_texel_2d_rgba_dxt3( const struct swrast_texture_image *texImage, { (void) k; if (fetch_ext_rgba_dxt3) { - fetch_ext_rgba_dxt3(texImage->Base.RowStride, - (GLubyte *)(texImage)->Base.Data, - i, j, texel); + fetch_ext_rgba_dxt3(texImage->RowStride, + texImage->Data, i, j, texel); } else _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt3\n"); @@ -487,9 +486,8 @@ fetch_texel_2d_rgba_dxt5( const struct swrast_texture_image *texImage, { (void) k; if (fetch_ext_rgba_dxt5) { - fetch_ext_rgba_dxt5(texImage->Base.RowStride, - (GLubyte *)(texImage)->Base.Data, - i, j, texel); + fetch_ext_rgba_dxt5(texImage->RowStride, + texImage->Data, i, j, texel); } else _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt5\n"); diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c index 7f262d6d8..aebe38ee0 100644 --- a/mesalib/src/mesa/main/texformat.c +++ b/mesalib/src/mesa/main/texformat.c @@ -34,6 +34,7 @@ #include "context.h" +#include "enums.h" #include "mfeatures.h" #include "mtypes.h" #include "texcompress.h" @@ -897,7 +898,8 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, } } - _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()"); + _mesa_problem(ctx, "unexpected format %s in _mesa_choose_tex_format()", + _mesa_lookup_enum_by_nr(internalFormat)); return MESA_FORMAT_NONE; } diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 2d06f84bf..acf7187fd 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -58,27 +58,6 @@ /** - * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE - * elsewhere. - */ -void * -_mesa_alloc_texmemory(GLsizei bytes) -{ - return _mesa_align_malloc(bytes, 512); -} - - -/** - * Free texture memory allocated with _mesa_alloc_texmemory() - */ -void -_mesa_free_texmemory(void *m) -{ - _mesa_align_free(m); -} - - -/** * Return the simple base format for a given internal texture format. * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA. * @@ -599,29 +578,6 @@ _mesa_new_texture_image( struct gl_context *ctx ) /** - * Free texture image data. - * This function is a fallback called via ctx->Driver.FreeTextureImageBuffer(). - * - * \param texImage texture image. - * - * Free the texture image data if it's not marked as client data. - */ -void -_mesa_free_texture_image_data(struct gl_context *ctx, - struct gl_texture_image *texImage) -{ - (void) ctx; - - if (texImage->Data) { - /* free the old texture data */ - _mesa_free_texmemory(texImage->Data); - } - - texImage->Data = NULL; -} - - -/** * Free a gl_texture_image and associated data. * This function is a fallback called via ctx->Driver.DeleteTextureImage(). * @@ -638,11 +594,6 @@ _mesa_delete_texture_image(struct gl_context *ctx, */ ASSERT(ctx->Driver.FreeTextureImageBuffer); ctx->Driver.FreeTextureImageBuffer( ctx, texImage ); - - ASSERT(texImage->Data == NULL); - if (texImage->ImageOffsets) - free(texImage->ImageOffsets); - free(texImage); } @@ -1084,18 +1035,12 @@ clear_teximage_fields(struct gl_texture_image *img) img->Width = 0; img->Height = 0; img->Depth = 0; - img->RowStride = 0; - if (img->ImageOffsets) { - free(img->ImageOffsets); - img->ImageOffsets = NULL; - } img->Width2 = 0; img->Height2 = 0; img->Depth2 = 0; img->WidthLog2 = 0; img->HeightLog2 = 0; img->DepthLog2 = 0; - img->Data = NULL; img->TexFormat = MESA_FORMAT_NONE; } @@ -1123,8 +1068,6 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target, GLint border, GLenum internalFormat, gl_format format) { - GLint i; - ASSERT(img); ASSERT(width >= 0); ASSERT(height >= 0); @@ -1161,19 +1104,6 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target, img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); - /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */ - img->RowStride = width; - /* Allocate the ImageOffsets array and initialize to typical values. - * We allocate the array for 1D/2D textures too in order to avoid special- - * case code in the texstore routines. - */ - if (img->ImageOffsets) - free(img->ImageOffsets); - img->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint)); - for (i = 0; i < depth; i++) { - img->ImageOffsets[i] = i * width * height; - } - img->TexFormat = format; } @@ -2316,6 +2246,45 @@ _mesa_choose_texture_format(struct gl_context *ctx, return f; } +/** + * Adjust pixel unpack params and image dimensions to strip off the + * texture border. + * + * Gallium and intel don't support texture borders. They've seldem been used + * and seldom been implemented correctly anyway. + * + * \param unpackNew returns the new pixel unpack parameters + */ +static void +strip_texture_border(GLint *border, + GLint *width, GLint *height, GLint *depth, + const struct gl_pixelstore_attrib *unpack, + struct gl_pixelstore_attrib *unpackNew) +{ + assert(*border > 0); /* sanity check */ + + *unpackNew = *unpack; + + if (unpackNew->RowLength == 0) + unpackNew->RowLength = *width; + + if (depth && unpackNew->ImageHeight == 0) + unpackNew->ImageHeight = *height; + + unpackNew->SkipPixels += *border; + if (height) + unpackNew->SkipRows += *border; + if (depth) + unpackNew->SkipImages += *border; + + assert(*width >= 3); + *width = *width - 2 * *border; + if (height && *height >= 3) + *height = *height - 2 * *border; + if (depth && *depth >= 3) + *depth = *depth - 2 * *border; + *border = 0; +} /** * Common code to implement all the glTexImage1D/2D/3D functions. @@ -2328,6 +2297,8 @@ teximage(struct gl_context *ctx, GLuint dims, const GLvoid *pixels) { GLboolean error; + struct gl_pixelstore_attrib unpack_no_border; + const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); @@ -2392,6 +2363,16 @@ teximage(struct gl_context *ctx, GLuint dims, return; /* error was recorded */ } + /* Allow a hardware driver to just strip out the border, to provide + * reliable but slightly incorrect hardware rendering instead of + * rarely-tested software fallback rendering. + */ + if (border && ctx->Const.StripTextureBorder) { + strip_texture_border(&border, &width, &height, &depth, unpack, + &unpack_no_border); + unpack = &unpack_no_border; + } + if (ctx->NewState & _NEW_PIXEL) _mesa_update_state(ctx); @@ -2409,7 +2390,6 @@ teximage(struct gl_context *ctx, GLuint dims, ctx->Driver.FreeTextureImageBuffer(ctx, texImage); - ASSERT(texImage->Data == NULL); texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, internalFormat, format, type); @@ -2425,19 +2405,19 @@ teximage(struct gl_context *ctx, GLuint dims, case 1: ctx->Driver.TexImage1D(ctx, target, level, internalFormat, width, border, format, - type, pixels, &ctx->Unpack, texObj, + type, pixels, unpack, texObj, texImage); break; case 2: ctx->Driver.TexImage2D(ctx, target, level, internalFormat, width, height, border, format, - type, pixels, &ctx->Unpack, texObj, + type, pixels, unpack, texObj, texImage); break; case 3: ctx->Driver.TexImage3D(ctx, target, level, internalFormat, width, height, depth, border, format, - type, pixels, &ctx->Unpack, texObj, + type, pixels, unpack, texObj, texImage); break; default: @@ -2548,7 +2528,6 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) } else { ctx->Driver.FreeTextureImageBuffer(ctx, texImage); - ASSERT(texImage->Data == NULL); ctx->Driver.EGLImageTargetTexture2D(ctx, target, texObj, texImage, image); @@ -2734,6 +2713,16 @@ copyteximage(struct gl_context *ctx, GLuint dims, texObj = _mesa_get_current_tex_object(ctx, target); + if (border && ctx->Const.StripTextureBorder) { + x += border; + width -= border * 2; + if (dims == 2) { + y += border; + height -= border * 2; + } + border = 0; + } + _mesa_lock_texture(ctx, texObj); { texImage = _mesa_get_tex_image(ctx, texObj, target, level); @@ -3370,7 +3359,6 @@ compressedteximage(struct gl_context *ctx, GLuint dims, gl_format texFormat; ctx->Driver.FreeTextureImageBuffer(ctx, texImage); - ASSERT(texImage->Data == NULL); texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, internalFormat, GL_NONE, diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index 6ce0fe92c..fd315bea3 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -36,13 +36,6 @@ #include "formats.h" -extern void * -_mesa_alloc_texmemory(GLsizei bytes); - -extern void -_mesa_free_texmemory(void *m); - - /** \name Internal functions */ /*@{*/ @@ -62,10 +55,6 @@ extern void _mesa_delete_texture_image( struct gl_context *ctx, struct gl_texture_image *teximage ); -extern void -_mesa_free_texture_image_data( struct gl_context *ctx, - struct gl_texture_image *texImage ); - extern void _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target, diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index 1b90cca9b..4d9942ba8 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -543,12 +543,13 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, width /= 2; } if (i >= minLevel && i <= maxLevel) { - if (!t->Image[0][i]) { - incomplete(t, "1D Image[0][i] == NULL"); + const struct gl_texture_image *img = t->Image[0][i]; + if (!img) { + incomplete(t, "1D Image[%d] is missing", i); return; } - if (t->Image[0][i]->Width2 != width ) { - incomplete(t, "1D Image[0][i] bad width"); + if (img->Width2 != width ) { + incomplete(t, "1D Image[%d] bad width %u", i, img->Width2); return; } } @@ -570,16 +571,17 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, height /= 2; } if (i >= minLevel && i <= maxLevel) { - if (!t->Image[0][i]) { - incomplete(t, "2D Image[0][i] == NULL"); + const struct gl_texture_image *img = t->Image[0][i]; + if (!img) { + incomplete(t, "2D Image[%d of %d] is missing", i, maxLevel); return; } - if (t->Image[0][i]->Width2 != width) { - incomplete(t, "2D Image[0][i] bad width"); + if (img->Width2 != width) { + incomplete(t, "2D Image[%d] bad width %u", i, img->Width2); return; } - if (t->Image[0][i]->Height2 != height) { - incomplete(t, "2D Image[0][i] bad height"); + if (img->Height2 != height) { + incomplete(t, "2D Image[i] bad height %u", i, img->Height2); return; } if (width==1 && height==1) { @@ -604,24 +606,25 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, depth /= 2; } if (i >= minLevel && i <= maxLevel) { - if (!t->Image[0][i]) { - incomplete(t, "3D Image[0][i] == NULL"); + const struct gl_texture_image *img = t->Image[0][i]; + if (!img) { + incomplete(t, "3D Image[%d] is missing", i); return; } - if (t->Image[0][i]->_BaseFormat == GL_DEPTH_COMPONENT) { + if (img->_BaseFormat == GL_DEPTH_COMPONENT) { incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex"); return; } - if (t->Image[0][i]->Width2 != width) { - incomplete(t, "3D Image[0][i] bad width"); + if (img->Width2 != width) { + incomplete(t, "3D Image[%d] bad width %u", i, img->Width2); return; } - if (t->Image[0][i]->Height2 != height) { - incomplete(t, "3D Image[0][i] bad height"); + if (img->Height2 != height) { + incomplete(t, "3D Image[%d] bad height %u", i, img->Height2); return; } - if (t->Image[0][i]->Depth2 != depth) { - incomplete(t, "3D Image[0][i] bad depth"); + if (img->Depth2 != depth) { + incomplete(t, "3D Image[%d] bad depth %u", i, img->Depth2); return; } } diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index cc9fbc020..05c1964d6 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -4499,6 +4499,9 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level, (void) border; + if (width == 0) + return; + /* allocate storage for texture data */ if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat, width, 1, 1)) { @@ -4560,6 +4563,9 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level, (void) border; + if (width == 0 || height == 0) + return; + /* allocate storage for texture data */ if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat, width, height, 1)) { @@ -4651,6 +4657,9 @@ _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level, (void) border; + if (width == 0 || height == 0 || depth == 0) + return; + /* allocate storage for texture data */ if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat, width, height, depth)) { @@ -4906,7 +4915,6 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx, ASSERT(texImage->Width > 0); ASSERT(texImage->Height > 0); ASSERT(texImage->Depth == 1); - ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */ /* allocate storage for texture data */ if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat, |