aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-10-27 08:37:52 +0200
committermarha <marha@users.sourceforge.net>2011-10-27 08:37:52 +0200
commit2a9be4af293f20fa33cc34fbc3b72e2235d91090 (patch)
treed41608bda1d56be1aa96857dee20e988b53760a3 /mesalib/src/mesa
parent9d53da0fbb9ae6df9a38ad40df4f53cd28287235 (diff)
parentd662d461634660f5c0f3998b5eb7d7ed3bd5a25f (diff)
downloadvcxsrv-2a9be4af293f20fa33cc34fbc3b72e2235d91090.tar.gz
vcxsrv-2a9be4af293f20fa33cc34fbc3b72e2235d91090.tar.bz2
vcxsrv-2a9be4af293f20fa33cc34fbc3b72e2235d91090.zip
Merge remote-tracking branch 'origin/released'
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/swrast.c5
-rw-r--r--mesalib/src/mesa/main/APIspec.xml6
-rw-r--r--mesalib/src/mesa/main/attrib.c223
-rw-r--r--mesalib/src/mesa/main/bufferobj.c13
-rw-r--r--mesalib/src/mesa/main/compiler.h2
-rw-r--r--mesalib/src/mesa/main/context.h4
-rw-r--r--mesalib/src/mesa/main/dlist.c2
-rw-r--r--mesalib/src/mesa/main/fbobject.c8
-rw-r--r--mesalib/src/mesa/main/ff_fragment_shader.cpp8
-rw-r--r--mesalib/src/mesa/main/imports.c2
-rw-r--r--mesalib/src/mesa/main/imports.h8
-rw-r--r--mesalib/src/mesa/main/mtypes.h20
-rw-r--r--mesalib/src/mesa/main/pack.c1
-rw-r--r--mesalib/src/mesa/main/pixelstore.c2
-rw-r--r--mesalib/src/mesa/main/state.c2
-rw-r--r--mesalib/src/mesa/main/texcompress.c4
-rw-r--r--mesalib/src/mesa/main/texcompress_fxt1.c4
-rw-r--r--mesalib/src/mesa/main/texcompress_rgtc.c24
-rw-r--r--mesalib/src/mesa/main/texcompress_s3tc.c18
-rw-r--r--mesalib/src/mesa/main/texformat.c4
-rw-r--r--mesalib/src/mesa/main/teximage.c140
-rw-r--r--mesalib/src/mesa/main/teximage.h11
-rw-r--r--mesalib/src/mesa/main/texobj.c41
-rw-r--r--mesalib/src/mesa/main/texstore.c10
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp56
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c58
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.c4
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.h1
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.c245
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c7
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp138
-rw-r--r--mesalib/src/mesa/swrast/s_context.c24
-rw-r--r--mesalib/src/mesa/swrast/s_context.h42
-rw-r--r--mesalib/src/mesa/swrast/s_fragprog.c3
-rw-r--r--mesalib/src/mesa/swrast/s_span.c5
-rw-r--r--mesalib/src/mesa/swrast/s_texcombine.c1
-rw-r--r--mesalib/src/mesa/swrast/s_texfetch_tmp.h8
-rw-r--r--mesalib/src/mesa/swrast/s_texfilter.c6
-rw-r--r--mesalib/src/mesa/swrast/s_texrender.c31
-rw-r--r--mesalib/src/mesa/swrast/s_texture.c175
-rw-r--r--mesalib/src/mesa/swrast/s_triangle.c18
-rw-r--r--mesalib/src/mesa/tnl/t_vb_program.c2
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec.h9
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c7
-rw-r--r--mesalib/src/mesa/vbo/vbo_save.h1
45 files changed, 952 insertions, 451 deletions
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
index 1bf39435b..b1abc502f 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
@@ -57,6 +57,7 @@
#include "main/texstate.h"
#include "swrast_priv.h"
+#include "swrast/s_context.h"
/**
@@ -72,6 +73,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;
@@ -82,6 +84,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);
@@ -95,7 +98,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 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,
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_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index 169e235ac..f82346bc6 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -543,45 +543,6 @@ st_AllocTextureImageBuffer(struct gl_context *ctx,
}
}
-
-/**
- * Adjust pixel unpack params and image dimensions to strip off the
- * texture border.
- * Gallium doesn'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;
-}
-
-
/**
* Do glTexImage1/2/3D().
*/
@@ -602,7 +563,6 @@ st_TexImage(struct gl_context * ctx,
struct st_texture_object *stObj = st_texture_object(texObj);
struct st_texture_image *stImage = st_texture_image(texImage);
GLuint dstRowStride = 0;
- struct gl_pixelstore_attrib unpackNB;
enum pipe_transfer_usage transfer_usage = 0;
GLubyte *dstMap;
@@ -627,21 +587,9 @@ st_TexImage(struct gl_context * ctx,
stObj->surface_based = GL_FALSE;
}
- /* gallium does not support texture borders, strip it off */
- if (border) {
- strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB);
- unpack = &unpackNB;
- texImage->Width = width;
- texImage->Height = height;
- texImage->Depth = depth;
- texImage->Border = 0;
- border = 0;
- }
- else {
- assert(texImage->Width == width);
- assert(texImage->Height == height);
- assert(texImage->Depth == depth);
- }
+ assert(texImage->Width == width);
+ assert(texImage->Height == height);
+ assert(texImage->Depth == depth);
stImage->base.Face = _mesa_tex_target_to_face(target);
stImage->base.Level = level;
diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c
index 6d4bc544d..a1817720d 100644
--- a/mesalib/src/mesa/state_tracker/st_context.c
+++ b/mesalib/src/mesa/state_tracker/st_context.c
@@ -144,6 +144,10 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
/* we want all vertex data to be placed in buffer objects */
vbo_use_buffer_objects(ctx);
+
+ /* make sure that no VBOs are left mapped when we're drawing. */
+ vbo_always_unmap_buffers(ctx);
+
/* Need these flags:
*/
st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
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..6b9ff6b72 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -222,6 +222,8 @@ void st_init_limits(struct st_context *st)
_mesa_override_glsl_version(st->ctx);
c->UniformBooleanTrue = ~0;
}
+
+ c->StripTextureBorder = GL_TRUE;
}
@@ -555,8 +557,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;