diff options
Diffstat (limited to 'mesalib/src/mesa')
43 files changed, 853 insertions, 390 deletions
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c index d2c74b91d..75d25253e 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c @@ -52,6 +52,7 @@ #include "main/texstate.h" #include "swrast_priv.h" +#include "swrast/s_context.h" /** @@ -67,6 +68,7 @@ static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + struct swrast_texture_image *swImage; uint32_t internalFormat; gl_format texFormat; @@ -77,6 +79,7 @@ static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base); texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target); texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0); + swImage = swrast_texture_image(texImage); _mesa_lock_texture(&dri_ctx->Base, texObj); @@ -90,7 +93,7 @@ static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, _mesa_init_teximage_fields(&dri_ctx->Base, target, texImage, w, h, 1, 0, internalFormat, texFormat); - sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)texImage->Data, + sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)swImage->Data, dPriv->loaderPrivate); _mesa_unlock_texture(&dri_ctx->Base, texObj); 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 431eafd38..4c77397d9 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..3e449b03e 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -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..719dff3af 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? */ }; 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 904aa457e..ed7eae4f4 100644 --- a/mesalib/src/mesa/main/texcompress_s3tc.c +++ b/mesalib/src/mesa/main/texcompress_s3tc.c @@ -398,8 +398,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"); @@ -426,8 +426,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"); @@ -454,9 +454,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"); @@ -483,9 +482,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..798201a60 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; } @@ -2409,7 +2339,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); @@ -2548,7 +2477,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); @@ -3370,7 +3298,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..cd9249630 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -4906,7 +4906,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, diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index fecab50f7..bdbb6b938 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -40,6 +40,7 @@ #include "../glsl/program.h" #include "ir_optimization.h" #include "ast.h" +#include "linker.h" #include "main/mtypes.h" #include "main/shaderobj.h" @@ -2587,13 +2588,35 @@ check_resources(const struct gl_context *ctx, } } +class add_uniform_to_shader : public uniform_field_visitor { +public: + add_uniform_to_shader(struct gl_shader_program *shader_program, + struct gl_program_parameter_list *params) + : shader_program(shader_program), params(params), next_sampler(0) + { + /* empty */ + } -static int -add_uniform_to_shader(ir_variable *var, - struct gl_program_parameter_list *params, - unsigned int &next_sampler) + int process(ir_variable *var) + { + this->idx = -1; + this->uniform_field_visitor::process(var); + + return this->idx; + } + +private: + virtual void visit_field(const glsl_type *type, const char *name); + + struct gl_shader_program *shader_program; + struct gl_program_parameter_list *params; + int next_sampler; + int idx; +}; + +void +add_uniform_to_shader::visit_field(const glsl_type *type, const char *name) { - const glsl_type *type = var->type; unsigned int size; if (type->is_vector() || type->is_scalar()) { @@ -2610,10 +2633,9 @@ add_uniform_to_shader(ir_variable *var, file = PROGRAM_UNIFORM; } - int index = _mesa_lookup_parameter_index(params, -1, var->name); + int index = _mesa_lookup_parameter_index(params, -1, name); if (index < 0) { - index = _mesa_add_parameter(params, file, - var->name, size, type->gl_type, + index = _mesa_add_parameter(params, file, name, size, type->gl_type, NULL, NULL, 0x0); /* Sampler uniform values are stored in prog->SamplerUnits, @@ -2622,11 +2644,15 @@ add_uniform_to_shader(ir_variable *var, */ if (file == PROGRAM_SAMPLER) { for (unsigned int j = 0; j < size / 4; j++) - params->ParameterValues[index + j][0].f = next_sampler++; + params->ParameterValues[index + j][0].f = this->next_sampler++; } } - return index; + /* The first part of the uniform that's processed determines the base + * location of the whole uniform (for structures). + */ + if (this->idx < 0) + this->idx = index; } /** @@ -2644,7 +2670,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program struct gl_program_parameter_list *params) { - unsigned int next_sampler = 0; + add_uniform_to_shader add(shader_program, params); foreach_list(node, sh->ir) { ir_variable *var = ((ir_instruction *) node)->as_variable(); @@ -2653,7 +2679,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program || (strncmp(var->name, "gl_", 3) == 0)) continue; - int loc = add_uniform_to_shader(var, params, next_sampler); + int loc = add.process(var); /* The location chosen in the Parameters list here (returned from * _mesa_add_parameter) has to match what the linker chose. @@ -3212,7 +3238,9 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; - progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress; + progress = do_common_optimization(ir, true, true, + options->MaxUnrollIterations) + || progress; progress = lower_quadop_vector(ir, true) || progress; @@ -3321,7 +3349,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader) /* Do some optimization at compile time to reduce shader IR size * and reduce later work if the same shader is linked multiple times */ - while (do_common_optimization(shader->ir, false, 32)) + while (do_common_optimization(shader->ir, false, false, 32)) ; validate_ir_tree(shader->ir); diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index 0a3220221..c60780989 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -75,6 +75,7 @@ struct st_context struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */ struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */ struct draw_stage *rastpos_stage; /**< For glRasterPos */ + GLboolean sw_primitive_restart; /* On old libGL's for linux we need to invalidate the drawables diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index 574802084..ff3008a5f 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -353,9 +353,26 @@ setup_interleaved_attribs(struct gl_context *ctx, struct pipe_context *pipe = st->pipe; GLuint attr; const GLubyte *low_addr = NULL; - - /* Find the lowest address of the arrays we're drawing */ + GLboolean usingVBO; /* all arrays in a VBO? */ + struct gl_buffer_object *bufobj; + GLuint user_buffer_size = 0; + GLuint vertex_size = 0; /* bytes per vertex, in bytes */ + GLsizei stride; + + /* Find the lowest address of the arrays we're drawing, + * Init bufobj and stride. + */ if (vpv->num_inputs) { + const GLuint mesaAttr0 = vp->index_to_input[0]; + const struct gl_client_array *array = arrays[mesaAttr0]; + + /* Since we're doing interleaved arrays, we know there'll be at most + * one buffer object and the stride will be the same for all arrays. + * Grab them now. + */ + bufobj = array->BufferObj; + stride = array->StrideB; + low_addr = arrays[vp->index_to_input[0]]->Ptr; for (attr = 1; attr < vpv->num_inputs; attr++) { @@ -363,44 +380,24 @@ setup_interleaved_attribs(struct gl_context *ctx, low_addr = MIN2(low_addr, start); } } + else { + /* not sure we'll ever have zero inputs, but play it safe */ + bufobj = NULL; + stride = 0; + low_addr = 0; + } + + /* are the arrays in user space? */ + usingVBO = bufobj && _mesa_is_bufferobj(bufobj); for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; const struct gl_client_array *array = arrays[mesaAttr]; - struct gl_buffer_object *bufobj = array->BufferObj; - struct st_buffer_object *stobj = st_buffer_object(bufobj); unsigned src_offset = (unsigned) (array->Ptr - low_addr); GLuint element_size = array->_ElementSize; - GLsizei stride = array->StrideB; assert(element_size == array->Size * _mesa_sizeof_type(array->Type)); - if (attr == 0) { - if (bufobj && _mesa_is_bufferobj(bufobj)) { - vbuffer->buffer = NULL; - pipe_resource_reference(&vbuffer->buffer, stobj->buffer); - vbuffer->buffer_offset = pointer_to_offset(low_addr); - } - else { - uint divisor = array->InstanceDivisor; - uint last_index = divisor ? num_instances / divisor : max_index; - uint bytes = src_offset + stride * last_index + element_size; - - vbuffer->buffer = pipe_user_buffer_create(pipe->screen, - (void*) low_addr, - bytes, - PIPE_BIND_VERTEX_BUFFER); - vbuffer->buffer_offset = 0; - - /* Track user vertex buffers. */ - pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer); - st->user_attrib[0].element_size = element_size; - st->user_attrib[0].stride = stride; - st->num_user_attribs = 1; - } - vbuffer->stride = stride; /* in bytes */ - } - velements[attr].src_offset = src_offset; velements[attr].instance_divisor = array->InstanceDivisor; velements[attr].vertex_buffer_index = 0; @@ -409,6 +406,54 @@ setup_interleaved_attribs(struct gl_context *ctx, array->Format, array->Normalized); assert(velements[attr].src_format); + + if (!usingVBO) { + /* how many bytes referenced by this attribute array? */ + uint divisor = array->InstanceDivisor; + uint last_index = divisor ? num_instances / divisor : max_index; + uint bytes = src_offset + stride * last_index + element_size; + + user_buffer_size = MAX2(user_buffer_size, bytes); + + /* update vertex size */ + vertex_size = MAX2(vertex_size, src_offset + element_size); + } + } + + /* + * Return the vbuffer info and setup user-space attrib info, if needed. + */ + if (vpv->num_inputs == 0) { + /* just defensive coding here */ + vbuffer->buffer = NULL; + vbuffer->buffer_offset = 0; + vbuffer->stride = 0; + st->num_user_attribs = 0; + } + else if (usingVBO) { + /* all interleaved arrays in a VBO */ + struct st_buffer_object *stobj = st_buffer_object(bufobj); + + vbuffer->buffer = NULL; + pipe_resource_reference(&vbuffer->buffer, stobj->buffer); + vbuffer->buffer_offset = pointer_to_offset(low_addr); + vbuffer->stride = stride; + st->num_user_attribs = 0; + } + else { + /* all interleaved arrays in user memory */ + vbuffer->buffer = pipe_user_buffer_create(pipe->screen, + (void*) low_addr, + user_buffer_size, + PIPE_BIND_VERTEX_BUFFER); + vbuffer->buffer_offset = 0; + vbuffer->stride = stride; + + /* Track user vertex buffers. */ + pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer); + st->user_attrib[0].element_size = vertex_size; + st->user_attrib[0].stride = stride; + st->num_user_attribs = 1; } } @@ -582,6 +627,127 @@ check_uniforms(struct gl_context *ctx) } } +/** Helper code for primitive restart fallback */ +#define DO_DRAW(pipe, cur_start, cur_count) \ + do { \ + info.start = cur_start; \ + info.count = cur_count; \ + if (u_trim_pipe_prim(info.mode, &info.count)) { \ + if (transfer) \ + pipe_buffer_unmap(pipe, transfer); \ + pipe->draw_vbo(pipe, &info); \ + if (transfer) { \ + ptr = pipe_buffer_map(pipe, ibuffer->buffer, PIPE_TRANSFER_READ, &transfer); \ + assert(ptr != NULL); \ + ptr = ADD_POINTERS(ptr, ibuffer->offset); \ + } \ + } \ + } while(0) + +/** More helper code for primitive restart fallback */ +#define PRIM_RESTART_LOOP(elements) \ + do { \ + for (i = start; i < end; i++) { \ + if (elements[i] == info.restart_index) { \ + if (cur_count > 0) { \ + /* draw elts up to prev pos */ \ + DO_DRAW(pipe, cur_start, cur_count); \ + } \ + /* begin new prim at next elt */ \ + cur_start = i + 1; \ + cur_count = 0; \ + } \ + else { \ + cur_count++; \ + } \ + } \ + if (cur_count > 0) { \ + DO_DRAW(pipe, cur_start, cur_count); \ + } \ + } while (0) + +static void +handle_fallback_primitive_restart(struct pipe_context *pipe, + const struct _mesa_index_buffer *ib, + struct pipe_index_buffer *ibuffer, + struct pipe_draw_info *orig_info) +{ + const unsigned start = orig_info->start; + const unsigned count = orig_info->count; + const unsigned end = start + count; + struct pipe_draw_info info = *orig_info; + struct pipe_transfer *transfer = NULL; + unsigned instance, i, cur_start, cur_count; + const void *ptr; + + info.primitive_restart = FALSE; + + if (!info.indexed) { + /* Splitting the draw arrays call is handled by the VBO module */ + if (u_trim_pipe_prim(info.mode, &info.count)) + pipe->draw_vbo(pipe, &info); + + return; + } + + /* info.indexed == TRUE */ + assert(ibuffer); + assert(ibuffer->buffer); + + if (ib) { + struct gl_buffer_object *bufobj = ib->obj; + if (bufobj && bufobj->Name) { + ptr = NULL; + } + else { + ptr = ib->ptr; + } + } else { + ptr = NULL; + } + + if (!ptr) + ptr = pipe_buffer_map(pipe, ibuffer->buffer, PIPE_TRANSFER_READ, &transfer); + + if (!ptr) + return; + ptr = ADD_POINTERS(ptr, ibuffer->offset); + + /* Need to loop over instances as well to preserve draw order */ + for (instance = 0; instance < orig_info->instance_count; instance++) { + info.start_instance = instance + orig_info->start_instance; + info.instance_count = 1; + cur_start = start; + cur_count = 0; + + switch (ibuffer->index_size) { + case 1: + { + const ubyte *elt_ub = (const ubyte *)ptr; + PRIM_RESTART_LOOP(elt_ub); + } + break; + case 2: + { + const ushort *elt_us = (const ushort *)ptr; + PRIM_RESTART_LOOP(elt_us); + } + break; + case 4: + { + const uint *elt_ui = (const uint *)ptr; + PRIM_RESTART_LOOP(elt_ui); + } + break; + default: + assert(0 && "bad index_size in handle_fallback_primitive_restart()"); + } + } + + if (transfer) + pipe_buffer_unmap(pipe, transfer); +} + /** * Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to @@ -794,7 +960,22 @@ st_draw_vbo(struct gl_context *ctx, info.max_index = info.start + info.count - 1; } - if (u_trim_pipe_prim(info.mode, &info.count)) + if (info.primitive_restart) { + /* + * Handle primitive restart for drivers that doesn't support it. + * + * The VBO module handles restart inside of draw_arrays for us, + * but we should still remove the primitive_restart flag on the + * info struct, the fallback function does this for us. Just + * remove the flag for all drivers in this case as well. + */ + if (st->sw_primitive_restart || !info.indexed) + handle_fallback_primitive_restart(pipe, ib, &ibuffer, &info); + else + /* don't trim, restarts might be inside index list */ + pipe->draw_vbo(pipe, &info); + } + else if (u_trim_pipe_prim(info.mode, &info.count)) pipe->draw_vbo(pipe, &info); } diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index a1f029089..37f36de93 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -555,8 +555,9 @@ void st_init_extensions(struct st_context *st) #endif } - if (screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) { - ctx->Extensions.NV_primitive_restart = GL_TRUE; + ctx->Extensions.NV_primitive_restart = GL_TRUE; + if (!screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) { + st->sw_primitive_restart = GL_TRUE; } if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) { diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 18e8a1db4..145bd7dcd 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -4322,37 +4322,15 @@ compile_tgsi_instruction(struct st_translate *t, } /** - * Emit the TGSI instructions to adjust the WPOS pixel center convention - * Basically, add (adjX, adjY) to the fragment position. - */ -static void -emit_adjusted_wpos(struct st_translate *t, - const struct gl_program *program, - float adjX, float adjY) -{ - struct ureg_program *ureg = t->ureg; - struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg); - struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; - - /* Note that we bias X and Y and pass Z and W through unchanged. - * The shader might also use gl_FragCoord.w and .z. - */ - ureg_ADD(ureg, wpos_temp, wpos_input, - ureg_imm4f(ureg, adjX, adjY, 0.0f, 0.0f)); - - t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); -} - - -/** - * Emit the TGSI instructions for inverting the WPOS y coordinate. + * Emit the TGSI instructions for inverting and adjusting WPOS. * This code is unavoidable because it also depends on whether * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM). */ static void -emit_wpos_inversion(struct st_translate *t, - const struct gl_program *program, - bool invert) +emit_wpos_adjustment( struct st_translate *t, + const struct gl_program *program, + boolean invert, + GLfloat adjX, GLfloat adjY[2]) { struct ureg_program *ureg = t->ureg; @@ -4371,35 +4349,55 @@ emit_wpos_inversion(struct st_translate *t, unsigned wposTransConst = _mesa_add_state_reference(program->Parameters, wposTransformState); - struct ureg_src wpostrans = ureg_DECL_constant(ureg, wposTransConst); - struct ureg_dst wpos_temp; + struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst ); + struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg ); struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; - /* MOV wpos_temp, input[wpos] - */ - if (wpos_input.File == TGSI_FILE_TEMPORARY) - wpos_temp = ureg_dst(wpos_input); - else { - wpos_temp = ureg_DECL_temporary(ureg); - ureg_MOV(ureg, wpos_temp, wpos_input); + /* First, apply the coordinate shift: */ + if (adjX || adjY[0] || adjY[1]) { + if (adjY[0] != adjY[1]) { + /* Adjust the y coordinate by adjY[1] or adjY[0] respectively + * depending on whether inversion is actually going to be applied + * or not, which is determined by testing against the inversion + * state variable used below, which will be either +1 or -1. + */ + struct ureg_dst adj_temp = ureg_DECL_temporary(ureg); + + ureg_CMP(ureg, adj_temp, + ureg_scalar(wpostrans, invert ? 2 : 0), + ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f), + ureg_imm4f(ureg, adjX, adjY[1], 0.0f, 0.0f)); + ureg_ADD(ureg, wpos_temp, wpos_input, ureg_src(adj_temp)); + } else { + ureg_ADD(ureg, wpos_temp, wpos_input, + ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f)); + } + wpos_input = ureg_src(wpos_temp); + } else { + /* MOV wpos_temp, input[wpos] + */ + ureg_MOV( ureg, wpos_temp, wpos_input ); } + /* Now the conditional y flip: STATE_FB_WPOS_Y_TRANSFORM.xy/zw will be + * inversion/identity, or the other way around if we're drawing to an FBO. + */ if (invert) { /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy */ - ureg_MAD(ureg, - ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y), - wpos_input, - ureg_scalar(wpostrans, 0), - ureg_scalar(wpostrans, 1)); + ureg_MAD( ureg, + ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), + wpos_input, + ureg_scalar(wpostrans, 0), + ureg_scalar(wpostrans, 1)); } else { /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww */ - ureg_MAD(ureg, - ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y), - wpos_input, - ureg_scalar(wpostrans, 2), - ureg_scalar(wpostrans, 3)); + ureg_MAD( ureg, + ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), + wpos_input, + ureg_scalar(wpostrans, 2), + ureg_scalar(wpostrans, 3)); } /* Use wpos_temp as position input from here on: @@ -4420,8 +4418,37 @@ emit_wpos(struct st_context *st, const struct gl_fragment_program *fp = (const struct gl_fragment_program *) program; struct pipe_screen *pscreen = st->pipe->screen; + GLfloat adjX = 0.0f; + GLfloat adjY[2] = { 0.0f, 0.0f }; boolean invert = FALSE; + /* Query the pixel center conventions supported by the pipe driver and set + * adjX, adjY to help out if it cannot handle the requested one internally. + * + * The bias of the y-coordinate depends on whether y-inversion takes place + * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are + * drawing to an FBO (causes additional inversion), and whether the the pipe + * driver origin and the requested origin differ (the latter condition is + * stored in the 'invert' variable). + * + * For height = 100 (i = integer, h = half-integer, l = lower, u = upper): + * + * center shift only: + * i -> h: +0.5 + * h -> i: -0.5 + * + * inversion only: + * l,i -> u,i: ( 0.0 + 1.0) * -1 + 100 = 99 + * l,h -> u,h: ( 0.5 + 0.0) * -1 + 100 = 99.5 + * u,i -> l,i: (99.0 + 1.0) * -1 + 100 = 0 + * u,h -> l,h: (99.5 + 0.0) * -1 + 100 = 0.5 + * + * inversion and center shift: + * l,i -> u,h: ( 0.0 + 0.5) * -1 + 100 = 99.5 + * l,h -> u,i: ( 0.5 + 0.5) * -1 + 100 = 99 + * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5 + * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0 + */ if (fp->OriginUpperLeft) { /* Fragment shader wants origin in upper-left */ if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { @@ -4449,12 +4476,17 @@ emit_wpos(struct st_context *st, if (fp->PixelCenterInteger) { /* Fragment shader wants pixel center integer */ - if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { /* the driver supports pixel center integer */ + adjY[1] = 1.0f; ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); - else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) + } + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { /* the driver supports pixel center half integer, need to bias X,Y */ - emit_adjusted_wpos(t, program, 0.5f, invert ? 0.5f : -0.5f); + adjX = -0.5f; + adjY[0] = -0.5f; + adjY[1] = 0.5f; + } else assert(0); } @@ -4465,8 +4497,8 @@ emit_wpos(struct st_context *st, } else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { /* the driver supports pixel center integer, need to bias X,Y */ + adjX = adjY[0] = adjY[1] = 0.5f; ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); - emit_adjusted_wpos(t, program, 0.5f, invert ? -0.5f : 0.5f); } else assert(0); @@ -4474,7 +4506,7 @@ emit_wpos(struct st_context *st, /* we invert after adjustment so that we avoid the MOV to temporary, * and reuse the adjustment ADD instead */ - emit_wpos_inversion(t, program, invert); + emit_wpos_adjustment(t, program, invert, adjX, adjY); } /** @@ -5026,7 +5058,9 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; - progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress; + progress = do_common_optimization(ir, true, true, + options->MaxUnrollIterations) + || progress; progress = lower_quadop_vector(ir, false) || progress; diff --git a/mesalib/src/mesa/swrast/s_context.c b/mesalib/src/mesa/swrast/s_context.c index 5287671d7..9112cf30d 100644 --- a/mesalib/src/mesa/swrast/s_context.c +++ b/mesalib/src/mesa/swrast/s_context.c @@ -747,6 +747,12 @@ _swrast_CreateContext( struct gl_context *ctx ) swrast->AllowVertexFog = GL_TRUE; swrast->AllowPixelFog = GL_TRUE; + swrast->Driver.SpanRenderStart = _swrast_span_render_start; + swrast->Driver.SpanRenderFinish = _swrast_span_render_finish; + + ctx->Driver.MapTexture = _swrast_map_texture; + ctx->Driver.UnmapTexture = _swrast_unmap_texture; + /* Optimized Accum buffer */ swrast->_IntegerAccumMode = GL_FALSE; swrast->_IntegerAccumScaler = 0.0; @@ -837,6 +843,24 @@ _swrast_render_primitive( struct gl_context *ctx, GLenum prim ) } +/** called via swrast->Driver.SpanRenderStart() */ +void +_swrast_span_render_start(struct gl_context *ctx) +{ + _swrast_map_textures(ctx); + _swrast_map_renderbuffers(ctx); +} + + +/** called via swrast->Driver.SpanRenderFinish() */ +void +_swrast_span_render_finish(struct gl_context *ctx) +{ + _swrast_unmap_textures(ctx); + _swrast_unmap_renderbuffers(ctx); +} + + void _swrast_render_start( struct gl_context *ctx ) { diff --git a/mesalib/src/mesa/swrast/s_context.h b/mesalib/src/mesa/swrast/s_context.h index ec8451eb8..d3ba37819 100644 --- a/mesalib/src/mesa/swrast/s_context.h +++ b/mesalib/src/mesa/swrast/s_context.h @@ -138,20 +138,17 @@ struct swrast_texture_image /** used for mipmap LOD computation */ GLfloat WidthScale, HeightScale, DepthScale; -#if 0 - GLubyte *Data; /**< The actual texture data in malloc'd memory */ + /** These fields only valid when texture memory is mapped */ + GLint RowStride; /**< Padded width in units of texels */ + GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to + each 2D slice in 'Data', in texels */ + GLubyte *Data; /**< Image data, accessed via FetchTexel() */ - GLint TexelSize; /**< bytes per texel block */ -#endif + /** Malloc'd texture memory */ + GLubyte *Buffer; FetchTexelFunc FetchTexel; StoreTexelFunc Store; - -#if 0 - /** These fields only valid when texture memory is mapped */ - GLubyte **SliceMaps; /**< points to OneMap or a malloc'd array */ - GLint RowStride; /**< bytes per row of blocks */ -#endif }; @@ -339,6 +336,31 @@ swrast_render_finish(struct gl_context *ctx) } +extern void +_swrast_span_render_start(struct gl_context *ctx); + +extern void +_swrast_span_render_finish(struct gl_context *ctx); + +extern void +_swrast_map_textures(struct gl_context *ctx); + +extern void +_swrast_unmap_textures(struct gl_context *ctx); + +extern void +_swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj); + +extern void +_swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj); + + +extern void +_swrast_map_renderbuffers(struct gl_context *ctx); + +extern void +_swrast_unmap_renderbuffers(struct gl_context *ctx); + /** * Size of an RGBA pixel, in bytes, for given datatype. diff --git a/mesalib/src/mesa/swrast/s_fragprog.c b/mesalib/src/mesa/swrast/s_fragprog.c index 7f205a200..1caa0ebc2 100644 --- a/mesalib/src/mesa/swrast/s_fragprog.c +++ b/mesalib/src/mesa/swrast/s_fragprog.c @@ -237,7 +237,8 @@ run_program(struct gl_context *ctx, SWspan *span, GLuint start, GLuint end) else if (depth >= 1.0) span->array->z[i] = ctx->DrawBuffer->_DepthMax; else - span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF); + span->array->z[i] = + (GLuint) (depth * ctx->DrawBuffer->_DepthMaxF + 0.5F); } } else { diff --git a/mesalib/src/mesa/swrast/s_span.c b/mesalib/src/mesa/swrast/s_span.c index e517c9ae1..4124e444e 100644 --- a/mesalib/src/mesa/swrast/s_span.c +++ b/mesalib/src/mesa/swrast/s_span.c @@ -1251,7 +1251,10 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span) 4 * span->end * sizeof(GLchan)); } - ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB || + ASSERT(rb->_BaseFormat == GL_RGBA || + rb->_BaseFormat == GL_RGB || + rb->_BaseFormat == GL_RED || + rb->_BaseFormat == GL_RG || rb->_BaseFormat == GL_ALPHA); if (ctx->Color.ColorLogicOpEnabled) { diff --git a/mesalib/src/mesa/swrast/s_texcombine.c b/mesalib/src/mesa/swrast/s_texcombine.c index c67c356c1..a7cbb4424 100644 --- a/mesalib/src/mesa/swrast/s_texcombine.c +++ b/mesalib/src/mesa/swrast/s_texcombine.c @@ -108,6 +108,7 @@ texture_combine( struct gl_context *ctx, GLuint unit, GLuint n, i--; } _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); + free(rgba); return; } } diff --git a/mesalib/src/mesa/swrast/s_texfetch_tmp.h b/mesalib/src/mesa/swrast/s_texfetch_tmp.h index c63b2043c..8b7e930f9 100644 --- a/mesalib/src/mesa/swrast/s_texfetch_tmp.h +++ b/mesalib/src/mesa/swrast/s_texfetch_tmp.h @@ -43,7 +43,7 @@ #if DIM == 1 #define TEXEL_ADDR( type, image, i, j, k, size ) \ - ((void) (j), (void) (k), ((type *)(image)->Base.Data + (i) * (size))) + ((void) (j), (void) (k), ((type *)(image)->Data + (i) * (size))) #define FETCH(x) fetch_texel_1d_##x @@ -51,15 +51,15 @@ #define TEXEL_ADDR( type, image, i, j, k, size ) \ ((void) (k), \ - ((type *)(image)->Base.Data + ((image)->Base.RowStride * (j) + (i)) * (size))) + ((type *)(image)->Data + ((image)->RowStride * (j) + (i)) * (size))) #define FETCH(x) fetch_texel_2d_##x #elif DIM == 3 #define TEXEL_ADDR( type, image, i, j, k, size ) \ - ((type *)(image)->Base.Data + ((image)->Base.ImageOffsets[k] \ - + (image)->Base.RowStride * (j) + (i)) * (size)) + ((type *)(image)->Data + ((image)->ImageOffsets[k] \ + + (image)->RowStride * (j) + (i)) * (size)) #define FETCH(x) fetch_texel_3d_##x diff --git a/mesalib/src/mesa/swrast/s_texfilter.c b/mesalib/src/mesa/swrast/s_texfilter.c index f8b0fa1aa..9de5c0276 100644 --- a/mesalib/src/mesa/swrast/s_texfilter.c +++ b/mesalib/src/mesa/swrast/s_texfilter.c @@ -1375,7 +1375,7 @@ opt_sample_rgb_2d(struct gl_context *ctx, GLint i = IFLOOR(texcoords[k][0] * width) & colMask; GLint j = IFLOOR(texcoords[k][1] * height) & rowMask; GLint pos = (j << shift) | i; - GLubyte *texel = ((GLubyte *) img->Data) + 3*pos; + GLubyte *texel = swImg->Data + 3 * pos; rgba[k][RCOMP] = UBYTE_TO_FLOAT(texel[2]); rgba[k][GCOMP] = UBYTE_TO_FLOAT(texel[1]); rgba[k][BCOMP] = UBYTE_TO_FLOAT(texel[0]); @@ -1419,7 +1419,7 @@ opt_sample_rgba_2d(struct gl_context *ctx, const GLint col = IFLOOR(texcoords[i][0] * width) & colMask; const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask; const GLint pos = (row << shift) | col; - const GLuint texel = *((GLuint *) img->Data + pos); + const GLuint texel = *((GLuint *) swImg->Data + pos); rgba[i][RCOMP] = UBYTE_TO_FLOAT( (texel >> 24) ); rgba[i][GCOMP] = UBYTE_TO_FLOAT( (texel >> 16) & 0xff ); rgba[i][BCOMP] = UBYTE_TO_FLOAT( (texel >> 8) & 0xff ); @@ -1442,7 +1442,7 @@ sample_lambda_2d(struct gl_context *ctx, const GLboolean repeatNoBorderPOT = (tObj->Sampler.WrapS == GL_REPEAT) && (tObj->Sampler.WrapT == GL_REPEAT) - && (tImg->Border == 0 && (tImg->Width == tImg->RowStride)) + && (tImg->Border == 0 && (tImg->Width == swImg->RowStride)) && swImg->_IsPowerOfTwo; ASSERT(lambda != NULL); diff --git a/mesalib/src/mesa/swrast/s_texrender.c b/mesalib/src/mesa/swrast/s_texrender.c index 47e458e1c..e2b921512 100644 --- a/mesalib/src/mesa/swrast/s_texrender.c +++ b/mesalib/src/mesa/swrast/s_texrender.c @@ -31,6 +31,15 @@ struct texture_renderbuffer }; +/** cast wrapper */ +static inline struct texture_renderbuffer * +texture_renderbuffer(struct gl_renderbuffer *rb) +{ + return (struct texture_renderbuffer *) rb; +} + + + /** * Get row of values from the renderbuffer that wraps a texture image. */ @@ -38,8 +47,7 @@ static void texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, GLint x, GLint y, void *values) { - const struct texture_renderbuffer *trb - = (const struct texture_renderbuffer *) rb; + struct texture_renderbuffer *trb = texture_renderbuffer(rb); const GLint z = trb->Zoffset; GLuint i; @@ -107,8 +115,7 @@ static void texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, const GLint x[], const GLint y[], void *values) { - const struct texture_renderbuffer *trb - = (const struct texture_renderbuffer *) rb; + struct texture_renderbuffer *trb = texture_renderbuffer(rb); const GLint z = trb->Zoffset; GLuint i; @@ -174,8 +181,7 @@ static void texture_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, GLint x, GLint y, const void *values, const GLubyte *mask) { - const struct texture_renderbuffer *trb - = (const struct texture_renderbuffer *) rb; + struct texture_renderbuffer *trb = texture_renderbuffer(rb); const GLint z = trb->Zoffset; GLuint i; @@ -236,8 +242,7 @@ static void texture_put_row_rgb(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, GLint x, GLint y, const void *values, const GLubyte *mask) { - const struct texture_renderbuffer *trb - = (const struct texture_renderbuffer *) rb; + struct texture_renderbuffer *trb = texture_renderbuffer(rb); const GLint z = trb->Zoffset; GLuint i; @@ -296,8 +301,7 @@ static void texture_put_mono_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, GLint x, GLint y, const void *value, const GLubyte *mask) { - const struct texture_renderbuffer *trb - = (const struct texture_renderbuffer *) rb; + struct texture_renderbuffer *trb = texture_renderbuffer(rb); const GLint z = trb->Zoffset; GLuint i; @@ -356,8 +360,7 @@ texture_put_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co const GLint x[], const GLint y[], const void *values, const GLubyte *mask) { - const struct texture_renderbuffer *trb - = (const struct texture_renderbuffer *) rb; + struct texture_renderbuffer *trb = texture_renderbuffer(rb); const GLint z = trb->Zoffset; GLuint i; @@ -415,8 +418,7 @@ texture_put_mono_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, const GLint x[], const GLint y[], const void *value, const GLubyte *mask) { - const struct texture_renderbuffer *trb - = (const struct texture_renderbuffer *) rb; + struct texture_renderbuffer *trb = texture_renderbuffer(rb); const GLint z = trb->Zoffset; GLuint i; @@ -610,7 +612,6 @@ update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att) trb->Base.DataType = CHAN_TYPE; trb->Base._BaseFormat = GL_RGBA; } - trb->Base.Data = trb->TexImage->Base.Data; } diff --git a/mesalib/src/mesa/swrast/s_texture.c b/mesalib/src/mesa/swrast/s_texture.c index 36b429cfa..fb1edb318 100644 --- a/mesalib/src/mesa/swrast/s_texture.c +++ b/mesalib/src/mesa/swrast/s_texture.c @@ -69,14 +69,32 @@ _swrast_alloc_texture_image_buffer(struct gl_context *ctx, { struct swrast_texture_image *swImg = swrast_texture_image(texImage); GLuint bytes = _mesa_format_image_size(format, width, height, depth); + GLuint i; /* This _should_ be true (revisit if these ever fail) */ assert(texImage->Width == width); assert(texImage->Height == height); assert(texImage->Depth == depth); - assert(!texImage->Data); - texImage->Data = _mesa_align_malloc(bytes, 512); + assert(!swImg->Buffer); + swImg->Buffer = _mesa_align_malloc(bytes, 512); + if (!swImg->Buffer) + return GL_FALSE; + + /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */ + swImg->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. + */ + swImg->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint)); + if (!swImg->ImageOffsets) + return GL_FALSE; + + for (i = 0; i < depth; i++) { + swImg->ImageOffsets[i] = i * width * height; + } if ((width == 1 || _mesa_is_pow_two(texImage->Width2)) && (height == 1 || _mesa_is_pow_two(texImage->Height2)) && @@ -98,7 +116,7 @@ _swrast_alloc_texture_image_buffer(struct gl_context *ctx, swImg->DepthScale = (GLfloat) texImage->Depth; } - return texImage->Data != NULL; + return GL_TRUE; } @@ -109,11 +127,16 @@ void _swrast_free_texture_image_buffer(struct gl_context *ctx, struct gl_texture_image *texImage) { - if (texImage->Data) { - _mesa_align_free(texImage->Data); + struct swrast_texture_image *swImage = swrast_texture_image(texImage); + if (swImage->Buffer) { + _mesa_align_free(swImage->Buffer); + swImage->Buffer = NULL; } - texImage->Data = NULL; + if (swImage->ImageOffsets) { + free(swImage->ImageOffsets); + swImage->ImageOffsets = NULL; + } } @@ -155,6 +178,7 @@ _swrast_map_teximage(struct gl_context *ctx, GLubyte **mapOut, GLint *rowStrideOut) { + struct swrast_texture_image *swImage = swrast_texture_image(texImage); GLubyte *map; GLint stride, texelSize; GLuint bw, bh; @@ -165,9 +189,9 @@ _swrast_map_teximage(struct gl_context *ctx, stride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); - assert(texImage->Data); + assert(swImage->Buffer); - map = texImage->Data; + map = swImage->Buffer; if (texImage->TexObject->Target == GL_TEXTURE_3D || texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY) { @@ -200,3 +224,138 @@ _swrast_unmap_teximage(struct gl_context *ctx, { /* nop */ } + + +void +_swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj) +{ + const GLuint faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1; + GLuint face, level; + + for (face = 0; face < faces; face++) { + for (level = texObj->BaseLevel; level < MAX_TEXTURE_LEVELS; level++) { + struct gl_texture_image *texImage = texObj->Image[face][level]; + if (texImage) { + struct swrast_texture_image *swImage = + swrast_texture_image(texImage); + + /* XXX we'll eventually call _swrast_map_teximage() here */ + swImage->Data = swImage->Buffer; + assert(swImage->Buffer); + } + } + } +} + + +void +_swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj) +{ + const GLuint faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1; + GLuint face, level; + + for (face = 0; face < faces; face++) { + for (level = texObj->BaseLevel; level < MAX_TEXTURE_LEVELS; level++) { + struct gl_texture_image *texImage = texObj->Image[face][level]; + if (texImage) { + struct swrast_texture_image *swImage + = swrast_texture_image(texImage); + + /* XXX we'll eventually call _swrast_unmap_teximage() here */ + swImage->Data = NULL; + } + } + } +} + + +/** + * Map all textures for reading prior to software rendering. + */ +void +_swrast_map_textures(struct gl_context *ctx) +{ + GLbitfield enabledUnits = ctx->Texture._EnabledUnits; + + /* loop over enabled texture units */ + while (enabledUnits) { + GLuint unit = _mesa_ffs(enabledUnits) - 1; + struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; + + _swrast_map_texture(ctx, texObj); + + enabledUnits &= ~(1 << unit); + } +} + + +/** + * Unmap all textures for reading prior to software rendering. + */ +void +_swrast_unmap_textures(struct gl_context *ctx) +{ + GLbitfield enabledUnits = ctx->Texture._EnabledUnits; + + /* loop over enabled texture units */ + while (enabledUnits) { + GLuint unit = _mesa_ffs(enabledUnits) - 1; + struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; + + _swrast_unmap_texture(ctx, texObj); + + enabledUnits &= ~(1 << unit); + } +} + + +/** + * Map or unmap any textures that we may be rendering to as renderbuffers. + */ +static void +map_unmap_renderbuffers(struct gl_context *ctx, + struct gl_framebuffer *fb, + GLboolean map) +{ + GLuint i; + + for (i = 0; i < Elements(fb->Attachment); i++) { + struct gl_texture_object *texObj = fb->Attachment[i].Texture; + if (texObj) { + const GLuint level = fb->Attachment[i].TextureLevel; + const GLuint face = fb->Attachment[i].CubeMapFace; + struct gl_texture_image *texImage = texObj->Image[face][level]; + if (texImage) { + struct swrast_texture_image *swImage + = swrast_texture_image(texImage); + + if (map) { + /* XXX we'll eventually call _swrast_map_teximage() here */ + swImage->Data = swImage->Buffer; + } + else { + /* XXX we'll eventually call _swrast_unmap_teximage() here */ + swImage->Data = NULL; + } + } + } + } +} + + +void +_swrast_map_renderbuffers(struct gl_context *ctx) +{ + map_unmap_renderbuffers(ctx, ctx->DrawBuffer, GL_TRUE); + if (ctx->ReadBuffer != ctx->DrawBuffer) + map_unmap_renderbuffers(ctx, ctx->ReadBuffer, GL_TRUE); +} + + +void +_swrast_unmap_renderbuffers(struct gl_context *ctx) +{ + map_unmap_renderbuffers(ctx, ctx->DrawBuffer, GL_FALSE); + if (ctx->ReadBuffer != ctx->DrawBuffer) + map_unmap_renderbuffers(ctx, ctx->ReadBuffer, GL_FALSE); +} diff --git a/mesalib/src/mesa/swrast/s_triangle.c b/mesalib/src/mesa/swrast/s_triangle.c index 839c4fd08..b4f8e7479 100644 --- a/mesalib/src/mesa/swrast/s_triangle.c +++ b/mesalib/src/mesa/swrast/s_triangle.c @@ -127,10 +127,12 @@ _swrast_culltriangle( struct gl_context *ctx, ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const struct gl_texture_image *texImg = \ obj->Image[0][obj->BaseLevel]; \ + const struct swrast_texture_image *swImg = \ + swrast_texture_image_const(texImg); \ const GLfloat twidth = (GLfloat) texImg->Width; \ const GLfloat theight = (GLfloat) texImg->Height; \ const GLint twidth_log2 = texImg->WidthLog2; \ - const GLubyte *texture = (const GLubyte *) texImg->Data; \ + const GLubyte *texture = (const GLubyte *) swImg->Data; \ const GLint smask = texImg->Width - 1; \ const GLint tmask = texImg->Height - 1; \ ASSERT(texImg->TexFormat == MESA_FORMAT_RGB888); \ @@ -181,10 +183,12 @@ _swrast_culltriangle( struct gl_context *ctx, ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const struct gl_texture_image *texImg = \ obj->Image[0][obj->BaseLevel]; \ + const struct swrast_texture_image *swImg = \ + swrast_texture_image_const(texImg); \ const GLfloat twidth = (GLfloat) texImg->Width; \ const GLfloat theight = (GLfloat) texImg->Height; \ const GLint twidth_log2 = texImg->WidthLog2; \ - const GLubyte *texture = (const GLubyte *) texImg->Data; \ + const GLubyte *texture = (const GLubyte *) swImg->Data; \ const GLint smask = texImg->Width - 1; \ const GLint tmask = texImg->Height - 1; \ ASSERT(texImg->TexFormat == MESA_FORMAT_RGB888); \ @@ -533,9 +537,11 @@ affine_span(struct gl_context *ctx, SWspan *span, ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const struct gl_texture_image *texImg = \ obj->Image[0][obj->BaseLevel]; \ + const struct swrast_texture_image *swImg = \ + swrast_texture_image_const(texImg); \ const GLfloat twidth = (GLfloat) texImg->Width; \ const GLfloat theight = (GLfloat) texImg->Height; \ - info.texture = (const GLchan *) texImg->Data; \ + info.texture = (const GLchan *) swImg->Data; \ info.twidth_log2 = texImg->WidthLog2; \ info.smask = texImg->Width - 1; \ info.tmask = texImg->Height - 1; \ @@ -800,7 +806,9 @@ fast_persp_span(struct gl_context *ctx, SWspan *span, ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const struct gl_texture_image *texImg = \ obj->Image[0][obj->BaseLevel]; \ - info.texture = (const GLchan *) texImg->Data; \ + const struct swrast_texture_image *swImg = \ + swrast_texture_image_const(texImg); \ + info.texture = (const GLchan *) swImg->Data; \ info.twidth_log2 = texImg->WidthLog2; \ info.smask = texImg->Width - 1; \ info.tmask = texImg->Height - 1; \ @@ -1062,7 +1070,7 @@ _swrast_choose_triangle( struct gl_context *ctx ) && texObj2D->_Swizzle == SWIZZLE_NOOP && swImg->_IsPowerOfTwo && texImg->Border == 0 - && texImg->Width == texImg->RowStride + && texImg->Width == swImg->RowStride && (format == MESA_FORMAT_RGB888 || format == MESA_FORMAT_RGBA8888) && minFilter == magFilter && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR diff --git a/mesalib/src/mesa/tnl/t_vb_program.c b/mesalib/src/mesa/tnl/t_vb_program.c index 367dfd5bb..836e8e8fa 100644 --- a/mesalib/src/mesa/tnl/t_vb_program.c +++ b/mesalib/src/mesa/tnl/t_vb_program.c @@ -68,6 +68,8 @@ struct vp_stage_data { GLubyte *clipmask; /**< clip flags */ GLubyte ormask, andmask; /**< for clipping */ + GLboolean vertex_textures; + struct gl_program_machine machine; }; diff --git a/mesalib/src/mesa/vbo/vbo_exec.h b/mesalib/src/mesa/vbo/vbo_exec.h index 9a1b5a127..0b72579a8 100644 --- a/mesalib/src/mesa/vbo/vbo_exec.h +++ b/mesalib/src/mesa/vbo/vbo_exec.h @@ -78,9 +78,6 @@ struct vbo_exec_copied_vtx { }; -typedef void (*vbo_attrfv_func)( const GLfloat * ); - - struct vbo_exec_context { struct gl_context *ctx; @@ -113,8 +110,6 @@ struct vbo_exec_context * values are squashed down to the 32 attributes passed to the * vertex program below: */ - enum vp_mode program_mode; - GLuint enabled_flags; const struct gl_client_array *inputs[VERT_ATTRIB_MAX]; } vtx; @@ -126,10 +121,6 @@ struct vbo_exec_context } eval; struct { - enum vp_mode program_mode; - GLuint enabled_flags; - GLuint array_obj; - /* These just mirror the current arrayobj (todo: make arrayobj * look like this and remove the mirror): */ diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c index 4e4f2c947..7023380a1 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_array.c +++ b/mesalib/src/mesa/vbo/vbo_exec_array.c @@ -422,8 +422,6 @@ bind_array_obj(struct gl_context *ctx) assert(i < Elements(exec->array.generic_array)); exec->array.generic_array[i] = &arrayObj->VertexAttrib[i]; } - - exec->array.array_obj = arrayObj->Name; } @@ -444,10 +442,7 @@ recalculate_input_bindings(struct gl_context *ctx) GLbitfield const_inputs = 0x0; GLuint i; - exec->array.program_mode = get_program_mode(ctx); - exec->array.enabled_flags = ctx->Array.ArrayObj->_Enabled; - - switch (exec->array.program_mode) { + switch (get_program_mode(ctx)) { case VP_NONE: /* When no vertex program is active (or the vertex program is generated * from fixed-function state). We put the material values into the diff --git a/mesalib/src/mesa/vbo/vbo_save.h b/mesalib/src/mesa/vbo/vbo_save.h index a064090cf..a85a7cbf6 100644 --- a/mesalib/src/mesa/vbo/vbo_save.h +++ b/mesalib/src/mesa/vbo/vbo_save.h @@ -146,7 +146,6 @@ struct vbo_save_context { GLuint vert_count; GLuint max_vert; GLboolean dangling_attr_ref; - GLboolean have_materials; GLuint opcode_vertex_list; |