[Xquartz-changes] mesa: Branch 'master' - 60 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Mon Jun 20 16:56:29 PDT 2011


Rebased ref, commits from common ancestor:
commit 4fbdde889ce5875243c588e4c7c9f4b775d0d7a5
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Fri Jun 17 12:24:55 2011 -0700

    glx: Bind to our context before __glXSetCurrentContext
    
    We want to bind to our context before calling __glXSetCurrentContext or
    messing with the gc rect in order to properly handle error conditions.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c
index 0f39ee5..6f048ae 100644
--- a/src/glx/glxcurrent.c
+++ b/src/glx/glxcurrent.c
@@ -212,7 +212,6 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
 {
    struct glx_context *gc = (struct glx_context *) gc_user;
    struct glx_context *oldGC = __glXGetCurrentContext();
-   int ret = Success;
 
    /* XXX: If this is left out, then libGL ends up not having this
     * symbol, and drivers using it fail to load.  Compare the
@@ -259,15 +258,28 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
    }
 
    if (gc) {
+      /* Attempt to bind the context.  We do this before mucking with
+       * gc and __glXSetCurrentContext to properly handle our state in
+       * case of an error.
+       *
+       * If an error occurs, set the Null context since we've already
+       * blown away our old context.  The caller is responsible for
+       * figuring out how to handle setting a valid context.
+       */
+      if (gc->vtable->bind(gc, oldGC, draw, read) != Success) {
+         __glXSetCurrentContextNull();
+         __glXUnlock();
+         __glXGenerateError(dpy, None, GLXBadContext, X_GLXMakeContextCurrent);
+         return GL_FALSE;
+      }
+
       if (gc->thread_refcount == 0)
          gc->currentDpy = dpy;
-      __glXSetCurrentContext(gc);
-      ret = gc->vtable->bind(gc, oldGC, draw, read);
-      if (gc->thread_refcount == 0) {
          gc->currentDrawable = draw;
          gc->currentReadable = read;
       }
       gc->thread_refcount++;
+      __glXSetCurrentContext(gc);
    } else {
       __glXSetCurrentContextNull();
    }
@@ -281,11 +293,6 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
 
    __glXUnlock();
 
-   if (ret) {
-      __glXGenerateError(dpy, None, ret, X_GLXMakeContextCurrent);
-      return GL_FALSE;
-   }
-
    return GL_TRUE;
 }
 
commit 517614141be2a1f392a4ea87c1077911ccadf35f
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Fri Jun 17 12:28:05 2011 -0700

    glx: Destroy the old context only after the new one has been bound
    
    This fixes a regression introduced by 49d7e48b33264d94e30af6129c281b6acafa9427
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c
index 9eb7d5a..0f39ee5 100644
--- a/src/glx/glxcurrent.c
+++ b/src/glx/glxcurrent.c
@@ -255,13 +255,6 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
       if (--oldGC->thread_refcount == 0) {
 	 oldGC->vtable->unbind(oldGC, gc);
 	 oldGC->currentDpy = 0;
-
-	 if (oldGC->xid == None && oldGC != gc) {
-	    /* We are switching away from a context that was
-	     * previously destroyed, so we need to free the memory
-	     * for the old handle. */
-	    oldGC->vtable->destroy(oldGC);
-	 }
       }
    }
 
@@ -279,6 +272,13 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
       __glXSetCurrentContextNull();
    }
 
+   if (oldGC->thread_refcount == 0 && oldGC != &dummyContext && oldGC->xid == None) {
+      /* We are switching away from a context that was
+       * previously destroyed, so we need to free the memory
+       * for the old handle. */
+      oldGC->vtable->destroy(oldGC);
+   }
+
    __glXUnlock();
 
    if (ret) {
commit 559e4f8ebcb186b491d7d687ac43f22a62448fc1
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Wed Jun 15 00:27:55 2011 -0700

    glx: Allow a context-specific fallback for glXGetProcAddress
    
    In applegl, GLX advertises the same extensions provided by OpenGL.framework
    even if such extensions are not provided by glapi.  This allows a client
    to get access to such API.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/src/glx/applegl_glx.c b/src/glx/applegl_glx.c
index 4bf4672..8766c88 100644
--- a/src/glx/applegl_glx.c
+++ b/src/glx/applegl_glx.c
@@ -34,10 +34,12 @@
 #if defined(GLX_USE_APPLEGL)
 
 #include <stdbool.h>
+#include <dlfcn.h>
 
 #include "glxclient.h"
 #include "apple_glx_context.h"
 #include "apple_glx.h"
+#include "apple_cgl.h"
 #include "glx_error.h"
 
 static void
@@ -82,6 +84,12 @@ applegl_wait_x(struct glx_context *gc)
    apple_glx_waitx(dpy, gc->driContext);
 }
 
+static void *
+applegl_get_proc_address(const char *symbol)
+{
+   return dlsym(apple_cgl_get_dl_handle(), symbol);
+}
+
 static const struct glx_context_vtable applegl_context_vtable = {
    applegl_destroy_context,
    applegl_bind_context,
@@ -91,6 +99,7 @@ static const struct glx_context_vtable applegl_context_vtable = {
    DRI_glXUseXFont,
    NULL, /* bind_tex_image, */
    NULL, /* release_tex_image, */
+   applegl_get_proc_address,
 };
 
 struct glx_context *
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index e7c18ff..80e4da3 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -767,6 +767,7 @@ static const struct glx_context_vtable dri2_context_vtable = {
    DRI_glXUseXFont,
    dri2_bind_tex_image,
    dri2_release_tex_image,
+   NULL, /* get_proc_address */
 };
 
 static void
diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c
index d59784c..6f3b2b8 100644
--- a/src/glx/dri_glx.c
+++ b/src/glx/dri_glx.c
@@ -558,6 +558,7 @@ static const struct glx_context_vtable dri_context_vtable = {
    DRI_glXUseXFont,
    NULL,
    NULL,
+   NULL, /* get_proc_address */
 };
 
 static struct glx_context *
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
index 0075695..07d4955 100644
--- a/src/glx/drisw_glx.c
+++ b/src/glx/drisw_glx.c
@@ -296,6 +296,7 @@ static const struct glx_context_vtable drisw_context_vtable = {
    DRI_glXUseXFont,
    NULL,
    NULL,
+   NULL, /* get_proc_address */
 };
 
 static struct glx_context *
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index 88a6edd..0641528 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -224,7 +224,7 @@ struct glx_context_vtable {
 			  GLXDrawable drawable,
 			  int buffer, const int *attrib_list);
    void (*release_tex_image)(Display * dpy, GLXDrawable drawable, int buffer);
-   
+   void * (*get_proc_address)(const char *symbol);
 };
 
 extern void
diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index cd8bc97..e6816ea 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -2521,6 +2521,12 @@ _X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void)
 #endif
       if (!f)
          f = (gl_function) _glapi_get_proc_address((const char *) procName);
+      if (!f) {
+         struct glx_context *gc = __glXGetCurrentContext();
+      
+         if (gc != NULL && gc->vtable->get_proc_address != NULL)
+            f = gc->vtable->get_proc_address((const char *) procName);
+      }
    }
    return f;
 }
diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c
index b4f16c7..7b542dd 100644
--- a/src/glx/indirect_glx.c
+++ b/src/glx/indirect_glx.c
@@ -335,6 +335,7 @@ static const struct glx_context_vtable indirect_context_vtable = {
    indirect_use_x_font,
    indirect_bind_tex_image,
    indirect_release_tex_image,
+   NULL, /* get_proc_address */
 };
 
 /**
commit fbd7448977efd49afba322cbb0853e9981ec2d2d
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Wed Jun 15 17:30:56 2011 -0700

    glapi: Update specs to correctly list FramebufferTextureLayerARB as an alias of FramebufferTextureLayerEXT
    
    FramebufferTextureLayer is an alias of FramebufferTextureLayerEXT, so
    FramebufferTextureLayerARB needs to be listed as an alias of
    FramebufferTextureLayerEXT rather than FramebufferTextureLayer.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/src/mapi/glapi/gen/ARB_geometry_shader4.xml b/src/mapi/glapi/gen/ARB_geometry_shader4.xml
index ca9a101..d9e540f 100644
--- a/src/mapi/glapi/gen/ARB_geometry_shader4.xml
+++ b/src/mapi/glapi/gen/ARB_geometry_shader4.xml
@@ -38,7 +38,7 @@
         <param name="texture" type="GLuint"/>
         <param name="level" type="GLint"/>
     </function>
-    <function name="FramebufferTextureLayerARB" alias="FramebufferTextureLayer">
+    <function name="FramebufferTextureLayerARB" alias="FramebufferTextureLayerEXT">
         <param name="target" type="GLenum"/>
         <param name="attachment" type="GLenum"/>
         <param name="texture" type="GLuint"/>
commit de77324d8f14951e4dc17f570e49451a0cd33121
Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Thu Jun 9 13:31:32 2011 -0700

    linker: Reject shaders that use too many varyings
    
    Previously it was up to the driver or later code generator to reject
    these shaders.  It turns out that nobody did this.
    
    This will need changes to support geometry shaders.
    
    NOTE: This is a candidate for the stable branches.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=37743
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 255edc6..b6479e7 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1405,8 +1405,9 @@ demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode)
 }
 
 
-void
-assign_varying_locations(struct gl_shader_program *prog,
+bool
+assign_varying_locations(struct gl_context *ctx,
+			 struct gl_shader_program *prog,
 			 gl_shader *producer, gl_shader *consumer)
 {
    /* FINISHME: Set dynamically when geometry shader support is added. */
@@ -1462,6 +1463,8 @@ assign_varying_locations(struct gl_shader_program *prog,
       }
    }
 
+   unsigned varying_vectors = 0;
+
    foreach_list(node, consumer->ir) {
       ir_variable *const var = ((ir_instruction *) node)->as_variable();
 
@@ -1492,8 +1495,32 @@ assign_varying_locations(struct gl_shader_program *prog,
 	  * value is written by the previous stage.
 	  */
 	 var->mode = ir_var_auto;
+      } else {
+	 /* The packing rules are used for vertex shader inputs are also used
+	  * for fragment shader inputs.
+	  */
+	 varying_vectors += count_attribute_slots(var->type);
       }
    }
+
+   if (ctx->API == API_OPENGLES2 || prog->Version == 100) {
+      if (varying_vectors > ctx->Const.MaxVarying) {
+	 linker_error_printf(prog, "shader uses too many varying vectors "
+			     "(%u > %u)\n",
+			     varying_vectors, ctx->Const.MaxVarying);
+	 return false;
+      }
+   } else {
+      const unsigned float_components = varying_vectors * 4;
+      if (float_components > ctx->Const.MaxVarying * 4) {
+	 linker_error_printf(prog, "shader uses too many varying components "
+			     "(%u > %u)\n",
+			     float_components, ctx->Const.MaxVarying * 4);
+	 return false;
+      }
+   }
+
+   return true;
 }
 
 
@@ -1666,9 +1693,13 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       if (prog->_LinkedShaders[i] == NULL)
 	 continue;
 
-      assign_varying_locations(prog,
-			       prog->_LinkedShaders[prev],
-			       prog->_LinkedShaders[i]);
+      if (!assign_varying_locations(ctx, prog,
+				    prog->_LinkedShaders[prev],
+				    prog->_LinkedShaders[i])) {
+	 prog->LinkStatus = false;
+	 goto done;
+      }
+
       prev = i;
    }
 
commit 4e5c51a05e70c215b284a38fc35850b485bbee8d
Author: Dan Nicholson <dbn.lists at gmail.com>
Date:   Thu Jun 16 16:32:42 2011 -0700

    glw: Mark all extern symbols GLAPI to regain default visibility (#31294)
    
    Since switching to hidden visibility on gcc, GLw apps were failing to
    link. Use the GLAPI definition to use default visibility where necessary.
    
    $ nm lib/libGLw.so | grep DrawingArea
    0000000000004020 T GLwCreateMDrawingArea
    0000000000003430 T GLwDrawingAreaMakeCurrent
    0000000000003410 T GLwDrawingAreaSwapBuffers
    0000000000204c60 D glwDrawingAreaClassRec
    0000000000204d48 D glwDrawingAreaWidgetClass
    00000000002053c0 D glwMDrawingAreaClassRec
    00000000002054e0 D glwMDrawingAreaWidgetClass
    
    Signed-off-by: Dan Nicholson <dbn.lists at gmail.com>
    Tested-by: justin <jlec at gentoo.org>

diff --git a/src/glw/GLwDrawA.h b/src/glw/GLwDrawA.h
index cd631b4..b9711c2 100644
--- a/src/glw/GLwDrawA.h
+++ b/src/glw/GLwDrawA.h
@@ -136,7 +136,7 @@
 typedef struct _GLwMDrawingAreaClassRec	*GLwMDrawingAreaWidgetClass;
 typedef struct _GLwMDrawingAreaRec	*GLwMDrawingAreaWidget;
 
-extern WidgetClass glwMDrawingAreaWidgetClass;
+GLAPI WidgetClass glwMDrawingAreaWidgetClass;
 
 
 #else 
@@ -144,7 +144,7 @@ extern WidgetClass glwMDrawingAreaWidgetClass;
 typedef struct _GLwDrawingAreaClassRec	*GLwDrawingAreaWidgetClass;
 typedef struct _GLwDrawingAreaRec	*GLwDrawingAreaWidget;
 
-extern WidgetClass glwDrawingAreaWidgetClass;
+GLAPI WidgetClass glwDrawingAreaWidgetClass;
 
 
 #endif
@@ -177,8 +177,8 @@ extern "C" {
 #endif
 
 /* front ends to glXMakeCurrent and glXSwapBuffers */
-extern void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx);
-extern void GLwDrawingAreaSwapBuffers(Widget w);
+GLAPI void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx);
+GLAPI void GLwDrawingAreaSwapBuffers(Widget w);
 
 #ifdef __GLX_MOTIF
 #ifdef _NO_PROTO
diff --git a/src/glw/GLwDrawAP.h b/src/glw/GLwDrawAP.h
index f121701..4ff21b4 100644
--- a/src/glw/GLwDrawAP.h
+++ b/src/glw/GLwDrawAP.h
@@ -59,7 +59,7 @@ typedef struct _GLwMDrawingAreaClassRec {
   } GLwMDrawingAreaClassRec;
 
 
-extern GLwMDrawingAreaClassRec glwMDrawingAreaClassRec;
+GLAPI GLwMDrawingAreaClassRec glwMDrawingAreaClassRec;
 
 
 /* XT */
@@ -70,7 +70,7 @@ typedef struct _GLwDrawingAreaClassRec {
   GLwDrawingAreaClassPart     glwDrawingArea_class;
   } GLwDrawingAreaClassRec;
 
-extern GLwDrawingAreaClassRec glwDrawingAreaClassRec;
+GLAPI GLwDrawingAreaClassRec glwDrawingAreaClassRec;
 
 
 #endif 
commit f6e5230b2614cc91e4c849c07781b2230878d274
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jun 17 18:44:26 2011 -0700

    i965/gen6: Apply documented workaround for nonpipelined state packets.
    
    Fixes a 100% reproducible GPU hang in topogun-1.06-orc-84k.trace.
    
    Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index b0f95dd..c235696 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -219,6 +219,12 @@ static void emit_depthbuffer(struct brw_context *brw)
    struct intel_region *hiz_region = depth_irb ? depth_irb->hiz_region : NULL;
    unsigned int len;
 
+   /* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both
+    * non-pipelined state that will need the PIPE_CONTROL workaround.
+    */
+   if (intel->gen == 6)
+      intel_emit_post_sync_nonzero_flush(intel);
+
    /*
     * If either depth or stencil buffer has packed depth/stencil format,
     * then don't use separate stencil. Emit only a depth buffer.
@@ -408,6 +414,9 @@ static void emit_depthbuffer(struct brw_context *brw)
     *     when HiZ is enabled and the DEPTH_BUFFER_STATE changes.
     */
    if (intel->gen >= 6 || hiz_region) {
+      if (intel->gen == 6)
+	 intel_emit_post_sync_nonzero_flush(intel);
+
       BEGIN_BATCH(2);
       OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 | (2 - 2));
       OUT_BATCH(0);
@@ -523,6 +532,9 @@ static void upload_aa_line_parameters(struct brw_context *brw)
    if (!ctx->Line.SmoothFlag || !brw->has_aa_line_parameters)
       return;
 
+   if (intel->gen == 6)
+      intel_emit_post_sync_nonzero_flush(intel);
+
    OUT_BATCH(_3DSTATE_AA_LINE_PARAMETERS << 16 | (3 - 2));
    /* use legacy aa line coverage computation */
    OUT_BATCH(0);
@@ -553,6 +565,9 @@ static void upload_line_stipple(struct brw_context *brw)
    if (!ctx->Line.StippleFlag)
       return;
 
+   if (intel->gen == 6)
+      intel_emit_post_sync_nonzero_flush(intel);
+
    BEGIN_BATCH(3);
    OUT_BATCH(_3DSTATE_LINE_STIPPLE_PATTERN << 16 | (3 - 2));
    OUT_BATCH(ctx->Line.StipplePattern);
@@ -580,6 +595,10 @@ static void upload_invarient_state( struct brw_context *brw )
 {
    struct intel_context *intel = &brw->intel;
 
+   /* 3DSTATE_SIP, 3DSTATE_MULTISAMPLE, etc. are nonpipelined. */
+   if (intel->gen == 6)
+      intel_emit_post_sync_nonzero_flush(intel);
+
    {
       /* 0x61040000  Pipeline Select */
       /*     PipelineSelect            : 0 */
@@ -643,6 +662,7 @@ static void upload_invarient_state( struct brw_context *brw )
       sip.header.length = 0;
       sip.bits0.pad = 0;
       sip.bits0.system_instruction_pointer = 0;
+
       BRW_BATCH_STRUCT(brw, &sip);
    }
 
@@ -683,6 +703,9 @@ static void upload_state_base_address( struct brw_context *brw )
    struct intel_context *intel = &brw->intel;
 
    if (intel->gen >= 6) {
+      if (intel->gen == 6)
+	 intel_emit_post_sync_nonzero_flush(intel);
+
        BEGIN_BATCH(10);
        OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (10 - 2));
        /* General state base address: stateless DP read/write requests */
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 77563ae..7353829 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -293,7 +293,27 @@ emit:
    item->header = intel->batch.emit;
 }
 
-static void
+/**
+ * Emits a PIPE_CONTROL with a non-zero post-sync operation, for
+ * implementing two workarounds on gen6.  From section 1.4.7.1
+ * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1:
+ *
+ * [DevSNB-C+{W/A}] Before any depth stall flush (including those
+ * produced by non-pipelined state commands), software needs to first
+ * send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
+ * 0.
+ *
+ * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable
+ * =1, a PIPE_CONTROL with any non-zero post-sync-op is required.
+ *
+ * XXX: There is also a workaround that would appear to apply to this
+ * workaround, but it doesn't appear to be necessary so far:
+ *
+ * Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
+ * BEFORE the pipe-control with a post-sync op and no write-cache
+ * flushes.
+ */
+void
 intel_emit_post_sync_nonzero_flush(struct intel_context *intel)
 {
    if (!intel->batch.need_workaround_flush)
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
index 3ed88d0..fb4134d 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
@@ -39,6 +39,7 @@ GLboolean intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel,
 					      uint32_t write_domain,
 					      uint32_t offset);
 void intel_batchbuffer_emit_mi_flush(struct intel_context *intel);
+void intel_emit_post_sync_nonzero_flush(struct intel_context *intel);
 
 static INLINE uint32_t float_as_int(float f)
 {
commit 0ab7d6f437f2f7a1b2d84f30497f3c2013b52791
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jun 17 18:24:56 2011 -0700

    i965/gen6: Limit the workaround flush to once per primitive.
    
    We're about to call this function in a bunch of state emits, so let's
    not spam the hardware with flushes too hard.

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index d6a99ab..6368218 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -240,6 +240,8 @@ GLboolean brwCreateContext( int api,
 
    brw->emit_state_always = 0;
 
+   intel->batch.need_workaround_flush = true;
+
    ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
    ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
 
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 6144f0a..350fc51 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -177,6 +177,8 @@ static void brw_emit_prim(struct brw_context *brw,
    OUT_BATCH(base_vertex_location);
    ADVANCE_BATCH();
 
+   intel->batch.need_workaround_flush = true;
+
    if (intel->always_flush_cache) {
       intel_batchbuffer_emit_mi_flush(intel);
    }
diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c
index 0f73148..8612e74 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -118,6 +118,11 @@ static void brw_new_batch( struct intel_context *intel )
     */
    brw->state.dirty.brw |= BRW_NEW_CONTEXT | BRW_NEW_BATCH;
 
+   /* Assume that the last command before the start of our batch was a
+    * primitive, for safety.
+    */
+   intel->batch.need_workaround_flush = true;
+
    brw->vb.nr_current_buffers = 0;
 
    /* Mark that the current program cache BO has been used by the GPU.
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 9e8f8b5..77563ae 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -296,6 +296,9 @@ emit:
 static void
 intel_emit_post_sync_nonzero_flush(struct intel_context *intel)
 {
+   if (!intel->batch.need_workaround_flush)
+      return;
+
    BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_PIPE_CONTROL);
    OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
@@ -303,6 +306,8 @@ intel_emit_post_sync_nonzero_flush(struct intel_context *intel)
 	     I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT, 0);
    OUT_BATCH(0); /* write data */
    ADVANCE_BATCH();
+
+   intel->batch.need_workaround_flush = false;
 }
 
 /* Emit a pipelined flush to either flush render and texture cache for
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index 751af45..148fb0c 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -183,6 +183,8 @@ struct intel_context
       drm_intel_bo *last_bo;
       /** BO for post-sync nonzero writes for gen6 workaround. */
       drm_intel_bo *workaround_bo;
+      bool need_workaround_flush;
+
       struct cached_batch_item *cached_items;
 
       uint16_t emit, total;
commit dfada714f8db3deea2fea3583c3c166a78db1117
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jun 17 18:20:36 2011 -0700

    i965/gen6: Use an BO instead of writing to address 0 for PIPE_CONTROL W/A.
    
    This was spectacularly unsafe.  On my system, address 0 happens to be
    the hardware status page for the render ring, and the first quadword
    of that happens to contain nothing we ever look at, but I sure didn't
    look forward to having to debug some day when, for example, the kernel
    happened to bind the ringbuffer before binding the hwsp.

diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 250102e..9e8f8b5 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -53,6 +53,22 @@ static void clear_cache( struct intel_context *intel )
 }
 
 void
+intel_batchbuffer_init(struct intel_context *intel)
+{
+   intel_batchbuffer_reset(intel);
+
+   if (intel->gen == 6) {
+      /* We can't just use brw_state_batch to get a chunk of space for
+       * the gen6 workaround because it involves actually writing to
+       * the buffer, and the kernel doesn't let us write to the batch.
+       */
+      intel->batch.workaround_bo = drm_intel_bo_alloc(intel->bufmgr,
+						      "gen6 workaround",
+						      4096, 4096);
+   }
+}
+
+void
 intel_batchbuffer_reset(struct intel_context *intel)
 {
    if (intel->batch.last_bo != NULL) {
@@ -76,6 +92,7 @@ intel_batchbuffer_free(struct intel_context *intel)
 {
    drm_intel_bo_unreference(intel->batch.last_bo);
    drm_intel_bo_unreference(intel->batch.bo);
+   drm_intel_bo_unreference(intel->batch.workaround_bo);
    clear_cache(intel);
 }
 
@@ -282,7 +299,8 @@ intel_emit_post_sync_nonzero_flush(struct intel_context *intel)
    BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_PIPE_CONTROL);
    OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
-   OUT_BATCH(0); /* write address */
+   OUT_RELOC(intel->batch.workaround_bo,
+	     I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT, 0);
    OUT_BATCH(0); /* write data */
    ADVANCE_BATCH();
 }
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
index a0a5c98..3ed88d0 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
@@ -9,6 +9,7 @@
 
 #define BATCH_RESERVED 16
 
+void intel_batchbuffer_init(struct intel_context *intel);
 void intel_batchbuffer_reset(struct intel_context *intel);
 void intel_batchbuffer_free(struct intel_context *intel);
 
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 0c2ba41..820688e 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -854,7 +854,7 @@ intelInitContext(struct intel_context *intel,
    if (INTEL_DEBUG & DEBUG_BUFMGR)
       dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE);
 
-   intel_batchbuffer_reset(intel);
+   intel_batchbuffer_init(intel);
 
    intel_fbo_init(intel);
 
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index 80dee4e..751af45 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -181,7 +181,8 @@ struct intel_context
       drm_intel_bo *bo;
       /** Last BO submitted to the hardware.  Used for glFinish(). */
       drm_intel_bo *last_bo;
-
+      /** BO for post-sync nonzero writes for gen6 workaround. */
+      drm_intel_bo *workaround_bo;
       struct cached_batch_item *cached_items;
 
       uint16_t emit, total;
commit 8f9e8d79c8c180e4254d01c688969d6d45386891
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jun 17 18:13:02 2011 -0700

    i965/gen6: Factor the PIPE_CONTROL workaround to a separate function.
    
    We're need this workaorund a lot more than we're currently doing, so
    let's reuse it.

diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 77edc3a..250102e 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -276,6 +276,17 @@ emit:
    item->header = intel->batch.emit;
 }
 
+static void
+intel_emit_post_sync_nonzero_flush(struct intel_context *intel)
+{
+   BEGIN_BATCH(4);
+   OUT_BATCH(_3DSTATE_PIPE_CONTROL);
+   OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
+   OUT_BATCH(0); /* write address */
+   OUT_BATCH(0); /* write data */
+   ADVANCE_BATCH();
+}
+
 /* Emit a pipelined flush to either flush render and texture cache for
  * reading from a FBO-drawn texture, or flush so that frontbuffer
  * render appears on the screen in DRI1.
@@ -294,15 +305,17 @@ intel_batchbuffer_emit_mi_flush(struct intel_context *intel)
 	 OUT_BATCH(0);
 	 ADVANCE_BATCH();
       } else {
-	 BEGIN_BATCH(8);
-	 /* XXX workaround: issue any post sync != 0 before write
-	  * cache flush = 1
-	  */
-	 OUT_BATCH(_3DSTATE_PIPE_CONTROL);
-	 OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
-	 OUT_BATCH(0); /* write address */
-	 OUT_BATCH(0); /* write data */
+	 if (intel->gen == 6) {
+	    /* Hardware workaround: SNB B-Spec says:
+	     *
+	     * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache
+	     * Flush Enable =1, a PIPE_CONTROL with any non-zero
+	     * post-sync-op is required.
+	     */
+	    intel_emit_post_sync_nonzero_flush(intel);
+	 }
 
+	 BEGIN_BATCH(4);
 	 OUT_BATCH(_3DSTATE_PIPE_CONTROL);
 	 OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
 		   PIPE_CONTROL_WRITE_FLUSH |
commit 911768700ed63c937bfcc75ec9afcfd1aa66f690
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jun 15 17:48:56 2011 -0700

    i965/gen6: Remove state flagging on BRW_NEW_CURBE_OFFSETS.
    
    That flag was leftover from gen4, where brw_curbe.c is choosing ranges
    of the CURBE space for constants to live in, and the unit state tells
    where to load them from.  That's not the case on gen6 -- we don't set
    this flag (since constants aren't in the URB), nor do we have any
    state like that to upload.

diff --git a/src/mesa/drivers/dri/i965/gen6_gs_state.c b/src/mesa/drivers/dri/i965/gen6_gs_state.c
index e73e782..d29f029 100644
--- a/src/mesa/drivers/dri/i965/gen6_gs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_gs_state.c
@@ -65,8 +65,7 @@ upload_gs_state(struct brw_context *brw)
 const struct brw_tracked_state gen6_gs_state = {
    .dirty = {
       .mesa  = _NEW_TRANSFORM,
-      .brw   = (BRW_NEW_CURBE_OFFSETS |
-		BRW_NEW_URB_FENCE |
+      .brw   = (BRW_NEW_URB_FENCE |
 		BRW_NEW_CONTEXT),
       .cache = CACHE_NEW_GS_PROG
    },
diff --git a/src/mesa/drivers/dri/i965/gen6_vs_state.c b/src/mesa/drivers/dri/i965/gen6_vs_state.c
index fd46da0..022e23e 100644
--- a/src/mesa/drivers/dri/i965/gen6_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_vs_state.c
@@ -165,8 +165,7 @@ upload_vs_state(struct brw_context *brw)
 const struct brw_tracked_state gen6_vs_state = {
    .dirty = {
       .mesa  = _NEW_TRANSFORM | _NEW_PROGRAM_CONSTANTS,
-      .brw   = (BRW_NEW_CURBE_OFFSETS |
-                BRW_NEW_NR_VS_SURFACES |
+      .brw   = (BRW_NEW_NR_VS_SURFACES |
 		BRW_NEW_URB_FENCE |
 		BRW_NEW_CONTEXT |
 		BRW_NEW_VERTEX_PROGRAM |
diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index 038087e..9ef6133 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -209,8 +209,7 @@ const struct brw_tracked_state gen6_wm_state = {
 		_NEW_BUFFERS |
 		_NEW_PROGRAM_CONSTANTS |
 		_NEW_POLYGON),
-      .brw   = (BRW_NEW_CURBE_OFFSETS |
-		BRW_NEW_FRAGMENT_PROGRAM |
+      .brw   = (BRW_NEW_FRAGMENT_PROGRAM |
                 BRW_NEW_NR_WM_SURFACES |
 		BRW_NEW_URB_FENCE |
 		BRW_NEW_BATCH),
commit c860f48f11b83334128c8e557a64036b8071a90b
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jun 15 17:47:54 2011 -0700

    i965/gen4: Remove old VS unit state key structure.
    
    We're streaming VS state out now, not caching it.

diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c
index 185020c..d5010a2 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_state.c
@@ -36,18 +36,6 @@
 #include "brw_defines.h"
 #include "main/macros.h"
 
-struct brw_vs_unit_key {
-   unsigned int total_grf;
-   unsigned int urb_entry_read_length;
-   unsigned int curb_entry_read_length;
-
-   unsigned int curbe_offset;
-
-   unsigned int nr_urb_entries, urb_size;
-
-   unsigned int nr_surfaces;
-};
-
 static void
 brw_prepare_vs_unit(struct brw_context *brw)
 {
commit 7d4d6082403bef750375cbff5cbb709e1fd30715
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jun 15 17:38:54 2011 -0700

    i965/gen6: Add missing state flag for VS push constants.
    
    It was already annotated up above and everything.

diff --git a/src/mesa/drivers/dri/i965/gen6_vs_state.c b/src/mesa/drivers/dri/i965/gen6_vs_state.c
index 7838a91..fd46da0 100644
--- a/src/mesa/drivers/dri/i965/gen6_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_vs_state.c
@@ -110,7 +110,7 @@ const struct brw_tracked_state gen6_vs_constants = {
       .mesa  = _NEW_TRANSFORM | _NEW_PROGRAM_CONSTANTS,
       .brw   = (BRW_NEW_BATCH |
 		BRW_NEW_VERTEX_PROGRAM),
-      .cache = 0,
+      .cache = CACHE_NEW_VS_PROG,
    },
    .prepare = gen6_prepare_vs_push_constants,
 };
commit b46dc45ceef3deb17ba2b0b4300eeb93e9cf7833
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jun 15 17:35:49 2011 -0700

    i965/gen6+: Correct gratuitous dependency on NEW_POLYGONSTIPPLE.
    
    That flag is for the contents of the stipple, not the enable flag.

diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index 62e0600..038087e 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -99,7 +99,7 @@ upload_wm_state(struct brw_context *brw)
       brw_fragment_program_const(brw->fragment_program);
    uint32_t dw2, dw4, dw5, dw6;
 
-   /* CACHE_NEW_WM_PROG */
+    /* CACHE_NEW_WM_PROG */
    if (brw->wm.prog_data->nr_params == 0) {
       /* Disable the push constant buffers. */
       BEGIN_BATCH(5);
@@ -159,7 +159,7 @@ upload_wm_state(struct brw_context *brw)
    if (ctx->Line.StippleFlag)
       dw5 |= GEN6_WM_LINE_STIPPLE_ENABLE;
 
-   /* _NEW_POLYGONSTIPPLE */
+   /* _NEW_POLYGON */
    if (ctx->Polygon.StippleFlag)
       dw5 |= GEN6_WM_POLYGON_STIPPLE_ENABLE;
 
@@ -204,8 +204,11 @@ upload_wm_state(struct brw_context *brw)
 
 const struct brw_tracked_state gen6_wm_state = {
    .dirty = {
-      .mesa  = (_NEW_LINE | _NEW_POLYGONSTIPPLE | _NEW_COLOR | _NEW_BUFFERS |
-		_NEW_PROGRAM_CONSTANTS | _NEW_POLYGON),
+      .mesa  = (_NEW_LINE |
+		_NEW_COLOR |
+		_NEW_BUFFERS |
+		_NEW_PROGRAM_CONSTANTS |
+		_NEW_POLYGON),
       .brw   = (BRW_NEW_CURBE_OFFSETS |
 		BRW_NEW_FRAGMENT_PROGRAM |
                 BRW_NEW_NR_WM_SURFACES |
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_state.c b/src/mesa/drivers/dri/i965/gen7_wm_state.c
index 239f661..17f7535 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_state.c
@@ -105,7 +105,7 @@ upload_wm_state(struct brw_context *brw)
    if (ctx->Line.StippleFlag)
       dw1 |= GEN7_WM_LINE_STIPPLE_ENABLE;
 
-   /* _NEW_POLYGONSTIPPLE */
+   /* _NEW_POLYGON */
    if (ctx->Polygon.StippleFlag)
       dw1 |= GEN7_WM_POLYGON_STIPPLE_ENABLE;
 
@@ -240,7 +240,9 @@ upload_ps_state(struct brw_context *brw)
 
 const struct brw_tracked_state gen7_ps_state = {
    .dirty = {
-      .mesa  = (_NEW_LINE | _NEW_POLYGON | _NEW_POLYGONSTIPPLE |
+      .mesa  = (_NEW_LINE |
+		_NEW_POLYGON |
+		_NEW_POLYGONSTIPPLE |
 		_NEW_PROGRAM_CONSTANTS),
       .brw   = (BRW_NEW_CURBE_OFFSETS |
 		BRW_NEW_FRAGMENT_PROGRAM |
commit 416a698b3c727c6db9902ac20053da73bb4b59c2
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jun 15 17:32:07 2011 -0700

    i965/gen6+: Add a missing state flag for WM constants.

diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index 024a1d8..62e0600 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -39,6 +39,7 @@ gen6_prepare_wm_push_constants(struct brw_context *brw)
 {
    struct intel_context *intel = &brw->intel;
    struct gl_context *ctx = &intel->ctx;
+   /* BRW_NEW_FRAGMENT_PROGRAM */
    const struct brw_fragment_program *fp =
       brw_fragment_program_const(brw->fragment_program);
 
@@ -48,6 +49,7 @@ gen6_prepare_wm_push_constants(struct brw_context *brw)
    /* XXX: Should this happen somewhere before to get our state flag set? */
    _mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
 
+   /* CACHE_NEW_VS_PROG */
    if (brw->wm.prog_data->nr_params != 0) {
       float *constants;
       unsigned int i;
@@ -83,7 +85,7 @@ const struct brw_tracked_state gen6_wm_constants = {
       .mesa  = _NEW_PROGRAM_CONSTANTS,
       .brw   = (BRW_NEW_BATCH |
 		BRW_NEW_FRAGMENT_PROGRAM),
-      .cache = 0,
+      .cache = CACHE_NEW_VS_PROG,
    },
    .prepare = gen6_prepare_wm_push_constants,
 };
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_state.c b/src/mesa/drivers/dri/i965/gen7_wm_state.c
index ac6ba2f..239f661 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_state.c
@@ -36,6 +36,7 @@ gen7_prepare_wm_constants(struct brw_context *brw)
 {
    struct intel_context *intel = &brw->intel;
    struct gl_context *ctx = &intel->ctx;
+   /* BRW_NEW_FRAGMENT_PROGRAM */
    const struct brw_fragment_program *fp =
       brw_fragment_program_const(brw->fragment_program);
 
@@ -45,7 +46,7 @@ gen7_prepare_wm_constants(struct brw_context *brw)
    /* XXX: Should this happen somewhere before to get our state flag set? */
    _mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
 
-   /* BRW_NEW_FRAGMENT_PROGRAM */
+   /* CACHE_NEW_WM_PROG */
    if (brw->wm.prog_data->nr_params != 0) {
       float *constants;
       unsigned int i;
@@ -80,7 +81,7 @@ const struct brw_tracked_state gen7_wm_constants = {
    .dirty = {
       .mesa  = _NEW_PROGRAM_CONSTANTS,
       .brw   = (BRW_NEW_BATCH | BRW_NEW_FRAGMENT_PROGRAM),
-      .cache = 0,
+      .cache = CACHE_NEW_WM_PROG,
    },
    .prepare = gen7_prepare_wm_constants,
 };
commit 16a04e019dcb0f1d50ceab5c8c2eafb56fa60853
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Mon Jun 20 11:05:26 2011 -0400

    wayland: Pass use_invalidate extension to driver

diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index dd9eb94..1d300c2 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -84,7 +84,7 @@ struct dri2_egl_display
 
    __DRIdri2LoaderExtension    dri2_loader_extension;
    __DRIswrastLoaderExtension  swrast_loader_extension;
-   const __DRIextension     *extensions[3];
+   const __DRIextension     *extensions[4];
 
 #ifdef HAVE_X11_PLATFORM
    xcb_connection_t         *conn;
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index e786780..9ea9c7c 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -720,7 +720,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
       
    dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
    dri2_dpy->extensions[1] = &image_lookup_extension.base;
-   dri2_dpy->extensions[2] = NULL;
+   dri2_dpy->extensions[2] = &use_invalidate.base;
+   dri2_dpy->extensions[3] = NULL;
 
    if (!dri2_create_screen(disp))
       goto cleanup_driver;
commit 80636ff2da374ca417db5afaaa0ab0cc5de9272d
Author: Benjamin Franzke <benjaminfranzke at googlemail.com>
Date:   Sun Jun 19 23:48:39 2011 +0200

    egl_dri2/x11: Check availability of the dri2 extension
    
    Do this before query versions, or xcb will shutdown
    and the connection can not be used for swrast.

diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index 8bff294..4e00c95 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -479,10 +479,19 @@ dri2_connect(struct dri2_egl_display *dri2_dpy)
    xcb_generic_error_t *error;
    xcb_screen_iterator_t s;
    char *driver_name, *device_name;
+   const xcb_query_extension_reply_t *extension;
 
    xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_xfixes_id);
    xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri2_id);
 
+   extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_xfixes_id);
+   if (!(extension && extension->present))
+      return EGL_FALSE;
+
+   extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_dri2_id);
+   if (!(extension && extension->present))
+      return EGL_FALSE;
+
    xfixes_query_cookie = xcb_xfixes_query_version(dri2_dpy->conn,
 						  XCB_XFIXES_MAJOR_VERSION,
 						  XCB_XFIXES_MINOR_VERSION);
commit 8eea050f5aed6ad8aeb64105c0e2581f0fd0b10a
Author: Chia-I Wu <olv at lunarg.com>
Date:   Mon Jun 20 11:14:56 2011 +0900

    docs: update EGL for changed configure options

diff --git a/docs/egl.html b/docs/egl.html
index fb15086..5b75007 100644
--- a/docs/egl.html
+++ b/docs/egl.html
@@ -29,12 +29,14 @@ directly dispatched to the drivers.</p>
 the driver for your hardware.  For example</p>
 
 <pre>
-  $ ./configure --enable-gles2 --enable-openvg --enable-gallium-nouveau
+  $ ./configure --enable-gles1 --enable-gles2 \
+                --with-dri-drivers=... \
+                --with-gallium-drivers=...
 </pre>
 
-<p>The main library and OpenGL is enabled by default.  The first option above
-enables <a href="opengles.html">OpenGL ES 2.x</a>.  The second option enables
-<a href="openvg.html">OpenVG</a>.</p>
+<p>The main library and OpenGL is enabled by default.  The first two options
+above enables <a href="opengles.html">OpenGL ES 1.x and 2.x</a>.  The last two
+options enables the listed classic and and Gallium drivers respectively.</p>
 
 </li>
 
@@ -42,8 +44,8 @@ enables <a href="opengles.html">OpenGL ES 2.x</a>.  The second option enables
 </ol>
 
 <p>In the given example, it will build and install <code>libEGL</code>,
-<code>libGL</code>, <code>libGLESv1_CM</code>, <code>libGLESv2</code>,
-<code>libOpenVG</code>, and one or more EGL drivers.</p>
+<code>libGL</code>, <code>libGLESv1_CM</code>, <code>libGLESv2</code>, and one
+or more EGL drivers.</p>
 
 <h3>Configure Options</h3>
 
@@ -65,6 +67,12 @@ drivers will be installed to <code>${libdir}/egl</code>.</p>
 
 </li>
 
+<li><code>--enable-gallium-egl</code>
+
+<p>Enable the optional <code>egl_gallium</code> driver.</p>
+
+</li>
+
 <li><code>--with-egl-platforms</code>
 
 <p>List the platforms (window systems) to support.  Its argument is a comma
@@ -88,15 +96,17 @@ internal library that supports multiple APIs.</p>
 
 </li>
 
-<li><code>--enable-openvg</code>
+<li><code>--enable-shared-glapi</code>
 
-<p>OpenVG must be explicitly enabled by this option.</p>
+<p>By default, <code>libGL</code> has its own copy of <code>libglapi</code>.
+This options makes <code>libGL</code> use the shared <code>libglapi</code>.  This
+is required if applications mix OpenGL and OpenGL ES.</p>
 
 </li>
 
-<li><code>--enable-gallium-egl</code>
+<li><code>--enable-openvg</code>
 
-<p>Explicitly enable or disable <code>egl_gallium</code>.</p>
+<p>OpenVG must be explicitly enabled by this option.</p>
 
 </li>
 
@@ -220,8 +230,7 @@ distribution.</p>
 <p>Generally, <code>egl_dri2</code> is preferred over <code>egl_gallium</code>
 when the system already has DRI drivers.  As <code>egl_gallium</code> is loaded
 before <code>egl_dri2</code> when both are available, <code>egl_gallium</code>
-may either be disabled with <code>--disable-gallium-egl</code> or packaged
-separately.</p>
+is disabled by default.</p>
 
 <h2>Developers</h2>
 
@@ -307,17 +316,5 @@ not be called with the sample display at the same time.  If a driver has access
 to an <code>EGLDisplay</code> without going through the EGL APIs, the driver
 should as well lock the display before using it.
 
-<h3>TODOs</h3>
-
-<ul>
-<li>Pass the conformance tests</li>
-<li>Mixed use of OpenGL, OpenGL ES 1.1, and OpenGL ES 2.0 is supported.  But
-which one of <code>libGL.so</code>, <code>libGLESv1_CM.so</code>, and
-<code>libGLESv2.so</code> should an application link to?  Bad things may happen
-when, say, an application is linked to <code>libGLESv2.so</code> and
-<code>libcairo</code>, which is linked to <code>libGL.so</code> instead.</li>
-
-</ul>
-
 </body>
 </html>
diff --git a/docs/opengles.html b/docs/opengles.html
index 742182e..0fee488 100644
--- a/docs/opengles.html
+++ b/docs/opengles.html
@@ -34,27 +34,10 @@ EGL drivers for your hardware.</p>
 
 <h2>Run the Demos</h2>
 
-<p>There are some demos in <code>progs/egl/</code>.  You can use them to test
-your build.  For example,</p>
-
-<pre>
-  $ cd progs/egl/eglut
-  $ make
-  $ cd ../opengles1
-  $ make
-  $ ./torus_x11
-</pre>
+<p>There are some demos in <code>mesa/demos</code> repository.</p>
 
 <h2>Developers</h2>
 
-<h3>Internal Libraries</h3>
-
-<table border="1" style="text-align: center;">
-	<tr><td>Library Name</td><td>Used By</td><td>Enabled</td><td>OpenGL</td><td>OpenGL ES 1.x</td><td>OpenGL ES 2.x</td></tr>
-	<tr><td><code>libmesa.a</td><td>Classic DRI drivers</td><td>y</td><td>y</td><td>--enable-gles1</td><td>--enable-gles2</td></tr>
-	<tr><td><code>libmesagallium.a</td><td>Gallium EGL and DRI drivers</td><td>y</td><td>y</td><td>--enable-gles1</td><td>--enable-gles2</td></tr>
-</table>
-
 <h3>Dispatch Table</h3>
 
 <p>OpenGL ES has an additional indirection when dispatching fucntions</p>
diff --git a/docs/openvg.html b/docs/openvg.html
index eff8c58..81e50b6 100644
--- a/docs/openvg.html
+++ b/docs/openvg.html
@@ -11,7 +11,7 @@
 <H1>OpenVG State Tracker</H1>
 
 <p>
-The current version of the OpenVG state tracker implements OpenVG 1.0.
+The current version of the OpenVG state tracker implements OpenVG 1.1.
 </p>
 <p>
 More informations about OpenVG can be found at
@@ -26,9 +26,9 @@ Please refer to <a href="egl.html">Mesa EGL</a> for more information about EGL.
 
 <h2>Building the library</h2>
 <ol>
-<li>Run <code>configure</code> with <code>--enable-openvg</code>.  If you do
-not need OpenGL, you can add <code>--disable-opengl</code> to save the
-compilation time.</li>
+<li>Run <code>configure</code> with <code>--enable-openvg</code> and
+<code>--enable-gallium-egl</code>.  If you do not need OpenGL, you can add
+<code>--disable-opengl</code> to save the compilation time.</li>
 
 <li>Build and install Mesa as usual.</li>
 </ol>
@@ -36,7 +36,7 @@ compilation time.</li>
 <h3>Sample build</h3>
 A sample build looks as follows:
 <pre>
-  $ ./configure --disable-opengl --enable-openvg
+  $ ./configure --disable-opengl --enable-openvg --enable-gallium-egl
   $ make
   $ make install
 </pre>
commit 66c71d150aed5fbecd49cb028332fdcc2c1feb70
Author: Chia-I Wu <olv at lunarg.com>
Date:   Mon Jun 20 08:05:04 2011 +0900

    configure.ac: remove deprecated EGL options

diff --git a/configure.ac b/configure.ac
index 70da9ee..c9dd8a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -523,11 +523,6 @@ AC_ARG_ENABLE([gles2],
         [enable support for OpenGL ES 2.x API @<:@default=no@:>@])],
     [enable_gles2="$enableval"],
     [enable_gles2=no])
-AC_ARG_ENABLE([gles-overlay],
-    [AS_HELP_STRING([--enable-gles-overlay],
-        [DEPRECATED.  Same as --enable-gles1 and --enable-gles2])],
-    [enable_gles1="$enableval"; enable_gles2="$enableval"],
-    [])
 AC_ARG_ENABLE([openvg],
     [AS_HELP_STRING([--enable-openvg],
         [enable support for OpenVG API @<:@default=no@:>@])],
@@ -1560,10 +1555,6 @@ AC_ARG_WITH([egl-platforms],
         "x11,drm" @<:@default=auto@:>@])],
     [with_egl_platforms="$withval"],
     [with_egl_platforms=yes])
-AC_ARG_WITH([egl-displays],
-    [AS_HELP_STRING([--with-egl-displays@<:@=DIRS...@:>@],
-        [DEPRECATED.  Use --with-egl-platforms instead])],
-    [with_egl_platforms="$withval"])
 
 EGL_PLATFORMS=""
 WAYLAND_EGL_LIB_DEPS=""
commit c772d4e6f34f6f55a730fb17aaee7a3b0554db3e
Author: Marcin Slusarz <marcin.slusarz at gmail.com>
Date:   Mon May 16 21:50:29 2011 +0200

    xorg/nouveau: rename to nouveau2
    
    Signed-off-by: Marek Olšák <maraeo at gmail.com>

diff --git a/src/gallium/targets/xorg-nouveau/Makefile b/src/gallium/targets/xorg-nouveau/Makefile
index 5a2cdb1..16ac954 100644
--- a/src/gallium/targets/xorg-nouveau/Makefile
+++ b/src/gallium/targets/xorg-nouveau/Makefile
@@ -1,7 +1,7 @@
 TOP = ../../../..
 include $(TOP)/configs/current
 
-LIBNAME = modesetting_drv.so
+LIBNAME = nouveau2_drv.so
 
 C_SOURCES = \
 	nouveau_target.c \
diff --git a/src/gallium/targets/xorg-nouveau/nouveau_xorg.c b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c
index f0d6492..a25254a 100644
--- a/src/gallium/targets/xorg-nouveau/nouveau_xorg.c
+++ b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c
@@ -54,7 +54,7 @@ static PciChipsets nouveau_xorg_pci_devices[] = {
 };
 
 static XF86ModuleVersionInfo nouveau_xorg_version = {
-    "modesetting",
+    "nouveau2",
     MODULEVENDORSTRING,
     MODINFOSTRING1,
     MODINFOSTRING2,
@@ -70,9 +70,9 @@ static XF86ModuleVersionInfo nouveau_xorg_version = {
  * Xorg driver exported structures
  */
 
-_X_EXPORT DriverRec modesetting = {
+_X_EXPORT DriverRec nouveau2 = {
     1,
-    "modesetting",
+    "nouveau2",
     nouveau_xorg_identify,
     NULL,
     xorg_tracker_available_options,
@@ -85,7 +85,7 @@ _X_EXPORT DriverRec modesetting = {
 
 static MODULESETUPPROTO(nouveau_xorg_setup);
 
-_X_EXPORT XF86ModuleData modesettingModuleData = {
+_X_EXPORT XF86ModuleData nouveau2ModuleData = {
     &nouveau_xorg_version,
     nouveau_xorg_setup,
     NULL
@@ -104,7 +104,7 @@ nouveau_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
      */
     if (!setupDone) {
 	setupDone = 1;
-	xf86AddDriver(&modesetting, module, HaveDriverFuncs);
+	xf86AddDriver(&nouveau2, module, HaveDriverFuncs);
 
 	/*
 	 * The return value must be non-NULL on success even though there
@@ -121,7 +121,7 @@ nouveau_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
 static void
 nouveau_xorg_identify(int flags)
 {
-    xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers",
+    xf86PrintChipsets("nouveau2", "Driver for Modesetting Kernel Drivers",
 		      nouveau_xorg_chipsets);
 }
 
@@ -137,7 +137,7 @@ nouveau_xorg_pci_probe(DriverPtr driver,
     if (scrn != NULL) {
 	scrn->driverVersion = 1;
 	scrn->driverName = "nouveau";
-	scrn->name = "modesetting";
+	scrn->name = "nouveau2";
 	scrn->Probe = NULL;
 
 	entity = xf86GetEntityInfo(entity_num);
commit a97b40a886944a6aeb214e52028ff0e430b71dca
Author: Marcin Slusarz <marcin.slusarz at gmail.com>
Date:   Sun Jun 5 21:05:24 2011 +0200

    st/xorg: initialize drm_mode.type
    
    it's uninitialized, but used by kernel (drm_mode_setcrtc -> drm_mode_set_crtcinfo)
    
    Signed-off-by: Marek Olšák <maraeo at gmail.com>

diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 0499ed1..22e61cf 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -122,6 +122,7 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
     drm_mode.hskew = mode->HSkew;
     drm_mode.vscan = mode->VScan;
     drm_mode.vrefresh = mode->VRefresh;
+    drm_mode.type = 0;
     if (!mode->name)
 	xf86SetModeDefaultName(mode);
     strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN - 1);
commit 21c0556b61708878ce25879c994bba2f914115a6
Author: Marcin Slusarz <marcin.slusarz at gmail.com>
Date:   Sun Jun 5 21:04:49 2011 +0200

    st/xorg: add GALLIUM_AUXILIARIES to target dependencies
    
    Without it changes to GALLIUM_AUXILIARIES don't induce target rebuild
    
    Signed-off-by: Marek Olšák <maraeo at gmail.com>

diff --git a/src/gallium/targets/Makefile.xorg b/src/gallium/targets/Makefile.xorg
index 47040bb..6fad710 100644
--- a/src/gallium/targets/Makefile.xorg
+++ b/src/gallium/targets/Makefile.xorg
@@ -41,7 +41,7 @@ endif
 
 default: depend $(TOP)/$(LIB_DIR)/gallium $(LIBNAME) $(LIBNAME_STAGING)
 
-$(LIBNAME): $(OBJECTS) Makefile ../Makefile.xorg $(LIBS) $(DRIVER_PIPES)
+$(LIBNAME): $(OBJECTS) Makefile ../Makefile.xorg $(LIBS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES)
 	$(MKLIB) -linker '$(CC)' -noprefix -o $@ $(LDFLAGS) $(OBJECTS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $(DRIVER_LINKS)
 
 depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) $(GENERATED_SOURCES)
commit 2f6a9687cf83aea10225f4ec91206c500bc3df89
Author: Marcin Slusarz <marcin.slusarz at gmail.com>
Date:   Mon May 9 00:35:10 2011 +0200

    gallium/nouveau: remove unused nouveau_screen_bo_user

diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 401155b..223e768 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -81,20 +81,6 @@ nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
 	return bo;
 }
 
-struct nouveau_bo *
-nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes)
-{
-	struct nouveau_device *dev = nouveau_screen(pscreen)->device;
-	struct nouveau_bo *bo = NULL;
-	int ret;
-
-	ret = nouveau_bo_user(dev, ptr, bytes, &bo);
-	if (ret)
-		return NULL;
-
-	return bo;
-}
-
 void *
 nouveau_screen_bo_map(struct pipe_screen *pscreen,
 		      struct nouveau_bo *bo,
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index 186ada3..d910809 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -47,8 +47,6 @@ nouveau_screen(struct pipe_screen *pscreen)
 struct nouveau_bo *
 nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
 		      unsigned usage, unsigned bind, unsigned size);
-struct nouveau_bo *
-nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes);
 void *
 nouveau_screen_bo_map(struct pipe_screen *pscreen,
 		      struct nouveau_bo *pb,
commit fe20edf959c4ec565ef29f2556e03ce36e0c259f
Author: Marcin Slusarz <marcin.slusarz at gmail.com>
Date:   Mon May 16 21:52:47 2011 +0200

    st/xorg: fix crash triggered by rendercheck -t composite -f a8r8g8b8 -o Src, Saturate
    
    samplers[0] may remain uninititialized if src picture/pixmap is null

diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index b5dacd2..f696b72 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -355,7 +355,7 @@ bind_samplers(struct exa_context *exa, int op,
               struct exa_pixmap_priv *pMask,
               struct exa_pixmap_priv *pDst)
 {
-   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
+   struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS] = {0};
    struct pipe_sampler_state src_sampler, mask_sampler;
    struct pipe_sampler_view view_templ;
    struct pipe_sampler_view *src_view;
commit 54d1b718b897742bf424f61f911e4ca8bbffa689
Author: Marcin Slusarz <marcin.slusarz at gmail.com>
Date:   Mon May 16 21:52:05 2011 +0200

    st/xorg: fix crash triggered by rendercheck -t blend -f a8r8g8b8 -o Clear

diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index d4dc84a..b5dacd2 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -237,7 +237,7 @@ picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, bool
    boolean swizzle = FALSE;
    unsigned ret = 0;
 
-   if (pSrc->picture_format == pSrcPicture->format) {
+   if (pSrc && pSrc->picture_format == pSrcPicture->format) {
       if (pSrc->picture_format == PICT_a8) {
          if (mask)
             return FS_MASK_LUMINANCE;
@@ -252,7 +252,7 @@ picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, bool
       return 0;
    }
 
-   if (pSrc->picture_format != PICT_a8r8g8b8) {
+   if (pSrc && pSrc->picture_format != PICT_a8r8g8b8) {
       assert(!"can not handle formats");
       return 0;
    }
commit badf0335ef70223204fbae3e8fdef718cdb3ad19
Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Jun 19 23:41:02 2011 +0200

    r600g: implement seamless_cube_map on r600-r700
    
    st/mesa guarantees that all bound sampler states have the same value
    in seamless_cube_map.

diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 16fe6c5..a0d145d 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -376,6 +376,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
 	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
 	case PIPE_CAP_SM3:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP:
 		return 1;
 
 	/* Supported except the original R600. */
@@ -385,7 +386,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 		return family == CHIP_R600 ? 0 : 1;
 
 	/* Supported on Evergreen. */
-	case PIPE_CAP_SEAMLESS_CUBE_MAP:
 	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
 		return family >= CHIP_CEDAR ? 1 : 0;
 
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 84a45be..9941bbf 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -50,6 +50,7 @@ enum r600_pipe_state_id {
 	R600_PIPE_STATE_BLEND = 0,
 	R600_PIPE_STATE_BLEND_COLOR,
 	R600_PIPE_STATE_CONFIG,
+	R600_PIPE_STATE_SEAMLESS_CUBEMAP,
 	R600_PIPE_STATE_CLIP,
 	R600_PIPE_STATE_SCISSOR,
 	R600_PIPE_STATE_VIEWPORT,
@@ -126,6 +127,11 @@ struct r600_pipe_shader {
 	struct r600_vertex_element	vertex_elements;
 };
 
+struct r600_pipe_sampler_state {
+	struct r600_pipe_state		rstate;
+	boolean seamless_cube_map;
+};
+
 /* needed for blitter save */
 #define NUM_TEX_UNITS 16
 
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 4ce1740..91da7c5 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -369,14 +369,17 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
 static void *r600_create_sampler_state(struct pipe_context *ctx,
 					const struct pipe_sampler_state *state)
 {
-	struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
+	struct r600_pipe_sampler_state *ss = CALLOC_STRUCT(r600_pipe_sampler_state);
+	struct r600_pipe_state *rstate;
 	union util_color uc;
 	unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 4 : 0;
 
-	if (rstate == NULL) {
+	if (ss == NULL) {
 		return NULL;
 	}
 
+	ss->seamless_cube_map = state->seamless_cube_map;
+	rstate = &ss->rstate;
 	rstate->id = R600_PIPE_STATE_SAMPLER;
 	util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
 	r600_pipe_state_add_reg_noblock(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0,
@@ -559,27 +562,57 @@ static void r600_set_ps_sampler_view(struct pipe_context *ctx, unsigned count,
 	rctx->ps_samplers.n_views = count;
 }
 
+static void r600_set_seamless_cubemap(struct r600_pipe_context *rctx, boolean enable)
+{
+	struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
+	if (rstate == NULL)
+		return;
+
+	rstate->id = R600_PIPE_STATE_SEAMLESS_CUBEMAP;
+	r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX,
+				(enable ? 0 : S_009508_DISABLE_CUBE_WRAP(1)),
+				1, NULL);
+
+	free(rctx->states[R600_PIPE_STATE_SEAMLESS_CUBEMAP]);
+	rctx->states[R600_PIPE_STATE_SEAMLESS_CUBEMAP] = rstate;
+	r600_context_pipe_state_set(&rctx->ctx, rstate);
+}
+
 static void r600_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void **states)
 {
 	struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
-	struct r600_pipe_state **rstates = (struct r600_pipe_state **)states;
+	struct r600_pipe_sampler_state **sstates = (struct r600_pipe_sampler_state **)states;
+	int seamless = -1;
 
 	memcpy(rctx->ps_samplers.samplers, states, sizeof(void*) * count);
 	rctx->ps_samplers.n_samplers = count;
 
 	for (int i = 0; i < count; i++) {
-		r600_context_pipe_state_set_ps_sampler(&rctx->ctx, rstates[i], i);
+		r600_context_pipe_state_set_ps_sampler(&rctx->ctx, &sstates[i]->rstate, i);
+
+		if (sstates[i])
+			seamless = sstates[i]->seamless_cube_map;
 	}
+
+	if (seamless != -1)
+		r600_set_seamless_cubemap(rctx, seamless);
 }
 
 static void r600_bind_vs_sampler(struct pipe_context *ctx, unsigned count, void **states)
 {
 	struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
-	struct r600_pipe_state **rstates = (struct r600_pipe_state **)states;
+	struct r600_pipe_sampler_state **sstates = (struct r600_pipe_sampler_state **)states;
+	int seamless = -1;
 
 	for (int i = 0; i < count; i++) {
-		r600_context_pipe_state_set_vs_sampler(&rctx->ctx, rstates[i], i);
+		r600_context_pipe_state_set_vs_sampler(&rctx->ctx, &sstates[i]->rstate, i);
+
+		if (sstates[i])
+			seamless = sstates[i]->seamless_cube_map;
 	}
+
+	if (seamless != -1)
+		r600_set_seamless_cubemap(rctx, seamless);
 }
 
 static void r600_set_clip_state(struct pipe_context *ctx,
commit 9bcce02f47f721bfb8917fd5639756fb3456aab5
Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Jun 19 23:28:33 2011 +0200

    r600g: remove some magic numbers

diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index d927e4a..4ce1740 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1290,14 +1290,22 @@ void r600_init_config(struct r600_pipe_context *rctx)
 
 	if (family >= CHIP_RV770) {
 		r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x00004000, 0xFFFFFFFF, NULL);
-		r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, 0x07000002, 0xFFFFFFFF, NULL);
+		r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX,
+					S_009508_DISABLE_CUBE_ANISO(1) |
+					S_009508_SYNC_GRADIENT(1) |
+					S_009508_SYNC_WALKER(1) |
+					S_009508_SYNC_ALIGNER(1), 0xFFFFFFFF, NULL);
 		r600_pipe_state_add_reg(rstate, R_009830_DB_DEBUG, 0x00000000, 0xFFFFFFFF, NULL);
 		r600_pipe_state_add_reg(rstate, R_009838_DB_WATERMARKS, 0x00420204, 0xFFFFFFFF, NULL);
 		r600_pipe_state_add_reg(rstate, R_0286C8_SPI_THREAD_GROUPING, 0x00000000, 0xFFFFFFFF, NULL);
 		r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL, 0x00514002, 0xFFFFFFFF, NULL);
 	} else {
 		r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x00000000, 0xFFFFFFFF, NULL);
-		r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, 0x07000003, 0xFFFFFFFF, NULL);
+		r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX,
+					S_009508_DISABLE_CUBE_ANISO(1) |
+					S_009508_SYNC_GRADIENT(1) |
+					S_009508_SYNC_WALKER(1) |
+					S_009508_SYNC_ALIGNER(1), 0xFFFFFFFF, NULL);
 		r600_pipe_state_add_reg(rstate, R_009830_DB_DEBUG, 0x82000000, 0xFFFFFFFF, NULL);
 		r600_pipe_state_add_reg(rstate, R_009838_DB_WATERMARKS, 0x01020204, 0xFFFFFFFF, NULL);
 		r600_pipe_state_add_reg(rstate, R_0286C8_SPI_THREAD_GROUPING, 0x00000001, 0xFFFFFFFF, NULL);
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
index 6373572..f6eec24 100644
--- a/src/gallium/drivers/r600/r600d.h
+++ b/src/gallium/drivers/r600/r600d.h
@@ -2556,6 +2556,9 @@
 #define   S_009508_DISABLE_CUBE_WRAP(x)                (((x) & 0x1) << 0)
 #define   G_009508_DISABLE_CUBE_WRAP(x)                (((x) >> 0) & 0x1)
 #define   C_009508_DISABLE_CUBE_WRAP                   0xFFFFFFFE
+#define   S_009508_DISABLE_CUBE_ANISO(x)               (((x) & 0x1) << 1)
+#define   G_009508_DISABLE_CUBE_ANISO(x)               (((x) >> 1) & 0x1)
+#define   C_009508_DISABLE_CUBE_ANISO                  (~(1 << 1))
 #define   S_009508_SYNC_GRADIENT(x)                    (((x) & 0x1) << 24)
 #define   G_009508_SYNC_GRADIENT(x)                    (((x) >> 24) & 0x1)
 #define   C_009508_SYNC_GRADIENT                       0xFEFFFFFF
commit 1251e1df0f5d4bc81c80c4c2d61c0a5f9b8b759a
Author: Marek Olšák <maraeo at gmail.com>
Date:   Sat Jun 18 20:33:55 2011 +0200

    configure.ac: add back --enable-gallium-egl

diff --git a/configure.ac b/configure.ac
index 871b16e..70da9ee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -548,6 +548,13 @@ AC_ARG_ENABLE([egl],
         [disable EGL library @<:@default=enabled@:>@])],
     [enable_egl="$enableval"],
     [enable_egl=yes])
+AC_ARG_ENABLE([gallium_egl],
+    [AS_HELP_STRING([--enable-gallium-egl],
+        [enable optional EGL state tracker (not required
+         for EGL support in Gallium with OpenGL and OpenGL ES)
+         @<:@default=disable@:>@])],
+    [enable_gallium_egl="$enableval"],
+    [enable_gallium_egl=no])
 
 # Option for Gallium drivers
 GALLIUM_DRIVERS_DEFAULT="r300,r600,swrast"
@@ -1210,9 +1217,6 @@ if test "x$enable_egl" = xyes; then
     SRC_DIRS="$SRC_DIRS egl"
     EGL_LIB_DEPS="$DLOPEN_LIBS $SELINUX_LIBS -lpthread"
     EGL_DRIVERS_DIRS=""
-    GALLIUM_STATE_TRACKERS_DIRS="egl $GALLIUM_STATE_TRACKERS_DIRS"
-    GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl"
-    HAVE_ST_EGL="yes"
 
     if test "$enable_static" != yes; then
         # build egl_glx when libGL is built
@@ -1246,6 +1250,22 @@ AC_SUBST([EGL_LIB_DEPS])
 AC_SUBST([EGL_DRIVERS_DIRS])
 
 dnl
+dnl EGL Gallium configuration
+dnl
+if test "x$enable_gallium_egl" = xyes; then
+    if test "x$with_gallium_drivers" = x; then
+        AC_MSG_ERROR([cannot enable egl_gallium without Gallium])
+    fi
+    if test "x$enable_egl" = xno; then
+        AC_MSG_ERROR([cannot enable egl_gallium without EGL])
+    fi
+
+    GALLIUM_STATE_TRACKERS_DIRS="egl $GALLIUM_STATE_TRACKERS_DIRS"
+    GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl"
+    HAVE_ST_EGL="yes"
+fi
+
+dnl
 dnl X.Org DDX configuration
 dnl
 if test "x$enable_xorg" = xyes; then
@@ -1271,6 +1291,9 @@ if test "x$enable_openvg" = xyes; then
     if test "x$with_gallium_drivers" = x; then
         AC_MSG_ERROR([cannot enable OpenVG without Gallium])
     fi
+    if test "x$enable_gallium_egl" = xno; then
+        AC_MSG_ERROR([cannot enable OpenVG without egl_gallium])
+    fi
 
     EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(VG_LIB)'
     VG_LIB_DEPS="$VG_LIB_DEPS $SELINUX_LIBS -lpthread"
@@ -1787,7 +1810,7 @@ if test "$enable_egl" = yes; then
         egl_drivers="$egl_drivers builtin:egl_$d"
     done
 
-    if test "$enable_gallium" = yes -a "$HAVE_ST_EGL" = yes; then
+    if test "x$HAVE_ST_EGL" = xyes; then
         echo "        EGL drivers:    ${egl_drivers} egl_gallium"
         echo "        EGL Gallium STs:$EGL_CLIENT_APIS"
     else
commit 9ba2907f2ed893da3da1345647e34a597dd6ed07
Author: Cyril Brulebois <kibi at debian.org>
Date:   Wed Jun 15 15:50:02 2011 +0200

    configure.ac: Avoid running llvm-config when it hadn't been checked for.
    
    If --disable-gallium is passed, llvm-config isn't checked for, so mark
    it explicitly as absent, through LLVM_CONFIG=no.
    
    Passing --disable-gallium would result in:
    | ../configure: line 9739: --version: command not found
    | ../configure: line 9740: --cppflags: command not found
    | ../configure: line 9741: --libs: command not found
    | ../configure: line 9743: --ldflags: command not found
    
    With this commit, one gets that instead:
    | configure: error: LLVM is required to build Gallium R300 on x86 and x86_64
    
    Signed-off-by: Cyril Brulebois <kibi at debian.org>

diff --git a/configure.ac b/configure.ac
index b2a0f66..871b16e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1511,6 +1511,8 @@ dnl
 if test "x$with_gallium_drivers" != x; then
     SRC_DIRS="$SRC_DIRS gallium gallium/winsys gallium/targets"
     AC_PATH_PROG([LLVM_CONFIG], [llvm-config], [no])
+else
+    LLVM_CONFIG=no
 fi
 
 AC_SUBST([LLVM_CFLAGS])
commit 0c7c5b68766a0d1d4da870fab0bcfd79fed1ed56
Author: Marek Olšák <maraeo at gmail.com>
Date:   Tue Jun 14 08:31:11 2011 +0200

    configure.ac: build r600g by default
    
    Reviewed-by: Alex Deucher <alexdeucher at gmail.com>

diff --git a/configure.ac b/configure.ac
index 804b8a7..b2a0f66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -550,13 +550,13 @@ AC_ARG_ENABLE([egl],
     [enable_egl=yes])
 
 # Option for Gallium drivers
-GALLIUM_DRIVERS_DEFAULT="r300,swrast"
+GALLIUM_DRIVERS_DEFAULT="r300,r600,swrast"
 
 AC_ARG_WITH([gallium-drivers],
     [AS_HELP_STRING([--with-gallium-drivers@<:@=DIRS...@:>@],
         [comma delimited Gallium drivers list, e.g.
         "i915,i965,nouveau,r300,r600,svga,swrast"
-        @<:@default=r300,swrast@:>@])],
+        @<:@default=r300,r600,swrast@:>@])],
     [with_gallium_drivers="$withval"],
     [with_gallium_drivers="$GALLIUM_DRIVERS_DEFAULT"])
 
commit 58b6a19ea4a48abe6307cca74b4d24752a0aeb57
Author: Marek Olšák <maraeo at gmail.com>
Date:   Tue Jun 14 07:46:59 2011 +0200

    configure.ac: add option --with-gallium-drivers=DIRS
    
    This removes all the --enable-gallium-$driver options and --disable-gallium.
    
    Gallium can be disabled by --with-gallium-drivers= (without parameters).
    
    Default is:
    --with-gallium-drivers=r300,swrast
    
    Reviewed-by: Alex Deucher <alexdeucher at gmail.com>

diff --git a/configure.ac b/configure.ac
index 5d045f0..804b8a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -549,12 +549,16 @@ AC_ARG_ENABLE([egl],
     [enable_egl="$enableval"],
     [enable_egl=yes])
 
-# Option for Gallium
-AC_ARG_ENABLE([gallium],
-    [AS_HELP_STRING([--disable-gallium],
-        [build gallium @<:@default=enabled@:>@])],
-    [enable_gallium="$enableval"],
-    [enable_gallium=yes])
+# Option for Gallium drivers
+GALLIUM_DRIVERS_DEFAULT="r300,swrast"
+
+AC_ARG_WITH([gallium-drivers],
+    [AS_HELP_STRING([--with-gallium-drivers@<:@=DIRS...@:>@],
+        [comma delimited Gallium drivers list, e.g.
+        "i915,i965,nouveau,r300,r600,svga,swrast"
+        @<:@default=r300,swrast@:>@])],
+    [with_gallium_drivers="$withval"],
+    [with_gallium_drivers="$GALLIUM_DRIVERS_DEFAULT"])
 
 if test "x$enable_opengl" = xno -a \
         "x$enable_gles1" = xno -a \
@@ -1264,7 +1268,7 @@ if test "x$enable_openvg" = xyes; then
     if test "x$enable_egl" = xno; then
         AC_MSG_ERROR([cannot enable OpenVG without EGL])
     fi
-    if test "x$enable_gallium" = xno; then
+    if test "x$with_gallium_drivers" = x; then
         AC_MSG_ERROR([cannot enable OpenVG without Gallium])
     fi
 
@@ -1280,6 +1284,10 @@ dnl D3D1X configuration
 dnl
 
 if test "x$enable_d3d1x" = xyes; then
+    if test "x$with_gallium_drivers" = x; then
+        AC_MSG_ERROR([cannot enable D3D1X without Gallium])
+    fi
+
     GALLIUM_STATE_TRACKERS_DIRS="d3d1x $GALLIUM_STATE_TRACKERS_DIRS"
     HAVE_ST_D3D1X=yes
 fi
@@ -1500,7 +1508,7 @@ AC_SUBST([PROGRAM_DIRS])
 dnl
 dnl Gallium configuration
 dnl
-if test "x$enable_gallium" = xyes; then
+if test "x$with_gallium_drivers" != x; then
     SRC_DIRS="$SRC_DIRS gallium gallium/winsys gallium/targets"
     AC_PATH_PROG([LLVM_CONFIG], [llvm-config], [no])
 fi
@@ -1615,6 +1623,9 @@ AC_ARG_ENABLE([gallium-llvm],
         [build gallium LLVM support @<:@default=enabled on x86/x86_64@:>@])],
     [enable_gallium_llvm="$enableval"],
     [enable_gallium_llvm=auto])
+if test "x$with_gallium_drivers" = x; then
+    enable_gallium_llvm=no
+fi
 if test "x$enable_gallium_llvm" = xauto; then
     case "$host_cpu" in
     i*86|x86_64) enable_gallium_llvm=yes;;
@@ -1660,108 +1671,46 @@ gallium_require_llvm() {
     fi
 }
 
-
-dnl
-dnl Gallium SVGA configuration
-dnl
-AC_ARG_ENABLE([gallium-svga],
-    [AS_HELP_STRING([--enable-gallium-svga],
-        [build gallium SVGA @<:@default=disabled@:>@])],
-    [enable_gallium_svga="$enableval"],
-    [enable_gallium_svga=auto])
-if test "x$enable_gallium_svga" = xyes; then
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga"
-    gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx"
-elif test "x$enable_gallium_svga" = xauto; then
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga"
-fi
-
-dnl
-dnl Gallium i915 configuration
-dnl
-AC_ARG_ENABLE([gallium-i915],
-    [AS_HELP_STRING([--enable-gallium-i915],
-        [build gallium i915 @<:@default=disabled@:>@])],
-    [enable_gallium_i915="$enableval"],
-    [enable_gallium_i915=auto])
-if test "x$enable_gallium_i915" = xyes; then
-    GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw"
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915"
-    gallium_check_st "i915/drm" "dri-i915" "xorg-i915"
-elif test "x$enable_gallium_i915" = xauto; then
+dnl Gallium drivers
+if test "x$with_gallium_drivers" != x; then
+    # This is for compile-testing
+    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915 i965 r300 svga"
     GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw"
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915"
-fi
-
-dnl
-dnl Gallium i965 configuration
-dnl
-AC_ARG_ENABLE([gallium-i965],
-    [AS_HELP_STRING([--enable-gallium-i965],
-        [build gallium i965 @<:@default=disabled@:>@])],
-    [enable_gallium_i965="$enableval"],
-    [enable_gallium_i965=auto])
-if test "x$enable_gallium_i965" = xyes; then
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i965"
-    gallium_check_st "i965/drm" "dri-i965" "xorg-i965"
-elif test "x$enable_gallium_i965" = xauto; then
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i965"
-fi
-
-dnl
-dnl Gallium Radeon r300g configuration
-dnl
-AC_ARG_ENABLE([gallium-r300],
-    [AS_HELP_STRING([--disable-gallium-r300],
-        [build R300 driver @<:@default=enabled@:>@])],
-    [enable_gallium_r300="$enableval"],
-    [enable_gallium_r300=yes])
-
-if test "x$enable_gallium_r300" = xyes && test "x$mesa_driver" = xdri; then
-    gallium_require_llvm "Gallium R300"
-
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300"
-    gallium_check_st "radeon/drm" "dri-r300" "xorg-r300"
-fi
 
-dnl
-dnl Gallium Radeon r600g configuration
-dnl
-AC_ARG_ENABLE([gallium-r600],
-    [AS_HELP_STRING([--enable-gallium-r600],
-        [build gallium r600 @<:@default=disabled@:>@])],
-    [enable_gallium_r600="$enableval"],
-    [enable_gallium_r600=auto])
-if test "x$enable_gallium_r600" = xyes; then
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r600"
-    gallium_check_st "r600/drm" "dri-r600"
-fi
-
-dnl
-dnl Gallium Nouveau configuration
-dnl
-AC_ARG_ENABLE([gallium-nouveau],
-    [AS_HELP_STRING([--enable-gallium-nouveau],
-        [build gallium nouveau @<:@default=disabled@:>@])],
-    [enable_gallium_nouveau="$enableval"],
-    [enable_gallium_nouveau=no])
-if test "x$enable_gallium_nouveau" = xyes; then
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50 nvc0"
-    gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau"
-fi
-
-dnl
-dnl Gallium swrast configuration
-dnl
-AC_ARG_ENABLE([gallium-swrast],
-    [AS_HELP_STRING([--enable-gallium-swrast],
-        [build gallium swrast @<:@default=auto@:>@])],
-    [enable_gallium_swrast="$enableval"],
-    [enable_gallium_swrast=auto])
-if test "x$enable_gallium_swrast" = xyes || test "x$enable_gallium_swrast" = xauto; then
-    if test "x$HAVE_ST_DRI" = xyes; then
-        GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS dri-swrast"
-    fi
+    gallium_drivers=`IFS=', '; echo $with_gallium_drivers`
+    for driver in $gallium_drivers; do
+        case "x$driver" in
+        xsvga)
+            gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx"
+            ;;
+        xi915)
+            gallium_check_st "i915/drm" "dri-i915" "xorg-i915"
+            ;;
+        xi965)
+            gallium_check_st "i965/drm" "dri-i965" "xorg-i965"
+            ;;
+        xr300)
+            gallium_require_llvm "Gallium R300"
+            gallium_check_st "radeon/drm" "dri-r300" "xorg-r300"
+            ;;
+        xr600)
+            GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r600"
+            gallium_check_st "r600/drm" "dri-r600"
+            ;;
+        xnouveau)
+            GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50 nvc0"
+            gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau"
+            ;;
+        xswrast)
+            if test "x$HAVE_ST_DRI" = xyes; then
+                GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS dri-swrast"
+            fi
+            ;;
+        *)
+            AC_MSG_ERROR([Unknown Gallium driver: $driver])
+            ;;
+        esac
+    done
 fi
 
 dnl prepend CORE_DIRS to SRC_DIRS
commit 440d71db7853fa81821b36a99e360fb72dbdccab
Author: Marek Olšák <maraeo at gmail.com>
Date:   Tue Jun 14 05:38:58 2011 +0200

    configure.ac: remove --with-state-trackers
    
    There is an obvious redundancy:
    
    --with-driver=dri VS --with-state-trackers=dri
    --with-driver=xlib VS --with-state-trackers=glx
    --enable-openvg VS --with-state-trackers=vega
    --enable-egl VS --with-state-trackers=egl
    
    This patch adds two new options for the remaining state trackers:
    --enable-xorg
    --enable-d3d1x
    
    Reviewed-by: Alex Deucher <alexdeucher at gmail.com>

diff --git a/configure.ac b/configure.ac
index 90171fa..5d045f0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -507,7 +507,7 @@ if test "x$enable_selinux" = "xyes"; then
     DEFINES="$DEFINES -DMESA_SELINUX"
 fi
 
-dnl Determine which APIs to support
+dnl Options for APIs
 AC_ARG_ENABLE([opengl],
     [AS_HELP_STRING([--disable-opengl],
         [disable support for standard OpenGL API @<:@default=no@:>@])],
@@ -528,27 +528,40 @@ AC_ARG_ENABLE([gles-overlay],
         [DEPRECATED.  Same as --enable-gles1 and --enable-gles2])],
     [enable_gles1="$enableval"; enable_gles2="$enableval"],
     [])
-
 AC_ARG_ENABLE([openvg],
     [AS_HELP_STRING([--enable-openvg],
         [enable support for OpenVG API @<:@default=no@:>@])],
     [enable_openvg="$enableval"],
     [enable_openvg=no])
+AC_ARG_ENABLE([xorg],
+    [AS_HELP_STRING([--enable-xorg],
+        [enable support for X.Org DDX API @<:@default=no@:>@])],
+    [enable_xorg="$enableval"],
+    [enable_xorg=no])
+AC_ARG_ENABLE([d3d1x],
+    [AS_HELP_STRING([--enable-d3d1x],
+        [enable support for Direct3D 10 & 11 low-level API @<:@default=no@:>@])],
+    [enable_d3d1x="$enableval"],
+    [enable_d3d1x=no])
+AC_ARG_ENABLE([egl],
+    [AS_HELP_STRING([--disable-egl],
+        [disable EGL library @<:@default=enabled@:>@])],
+    [enable_egl="$enableval"],
+    [enable_egl=yes])
 
-dnl smooth the transition; should be removed eventually
-if test "x$enable_openvg" = xno; then
-    case "x$with_state_trackers" in
-    x*vega*)
-        AC_MSG_WARN([vega state tracker is enabled without --enable-openvg])
-        enable_openvg=yes
-        ;;
-    esac
-fi
+# Option for Gallium
+AC_ARG_ENABLE([gallium],
+    [AS_HELP_STRING([--disable-gallium],
+        [build gallium @<:@default=enabled@:>@])],
+    [enable_gallium="$enableval"],
+    [enable_gallium=yes])
 
 if test "x$enable_opengl" = xno -a \
         "x$enable_gles1" = xno -a \
         "x$enable_gles2" = xno -a \
-        "x$enable_openvg" = xno; then
+        "x$enable_openvg" = xno -a \
+        "x$enable_xorg" = xno -a \
+        "x$enable_d3d1x" = xno; then
     AC_MSG_ERROR([at least one API should be enabled])
 fi
 
@@ -657,11 +670,6 @@ if test "x$enable_gles2" = xyes; then
     CORE_DIRS="$CORE_DIRS mapi/es2api"
 fi
 
-# build vgapi if OpenVG is enabled
-if test "x$enable_openvg" = xyes; then
-    CORE_DIRS="$CORE_DIRS mapi/vgapi"
-fi
-
 # build glsl and mesa if OpenGL or OpenGL ES is enabled
 case "x$enable_opengl$enable_gles1$enable_gles2" in
 x*yes*)
@@ -674,11 +682,14 @@ xlib)
     DRIVER_DIRS="x11"
     GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib"
     GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS libgl-xlib"
+    GALLIUM_STATE_TRACKERS_DIRS="glx $GALLIUM_STATE_TRACKERS_DIRS"
     ;;
 dri)
     SRC_DIRS="$SRC_DIRS glx"
     DRIVER_DIRS="dri"
     GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib sw/dri"
+    GALLIUM_STATE_TRACKERS_DIRS="dri $GALLIUM_STATE_TRACKERS_DIRS"
+    HAVE_ST_DRI="yes"
     ;;
 osmesa)
     DRIVER_DIRS="osmesa"
@@ -1184,24 +1195,19 @@ AC_SUBST([OSMESA_PC_LIB_PRIV])
 dnl
 dnl EGL configuration
 dnl
-AC_ARG_ENABLE([egl],
-    [AS_HELP_STRING([--disable-egl],
-        [disable EGL library @<:@default=enabled@:>@])],
-    [enable_egl="$enableval"],
-    [enable_egl=yes])
+EGL_CLIENT_APIS=""
+
 if test "x$enable_egl" = xno; then
     if test "x$mesa_driver" = xno; then
         AC_MSG_ERROR([cannot disable EGL when there is no mesa driver])
     fi
-    if test "x$enable_openvg" = xyes; then
-        AC_MSG_ERROR([cannot enable OpenVG without EGL])
-    fi
 fi
 if test "x$enable_egl" = xyes; then
     SRC_DIRS="$SRC_DIRS egl"
     EGL_LIB_DEPS="$DLOPEN_LIBS $SELINUX_LIBS -lpthread"
     EGL_DRIVERS_DIRS=""
-    GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl"
+    GALLIUM_STATE_TRACKERS_DIRS="egl $GALLIUM_STATE_TRACKERS_DIRS"
+    GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl"
     HAVE_ST_EGL="yes"
 
     if test "$enable_static" != yes; then
@@ -1236,6 +1242,49 @@ AC_SUBST([EGL_LIB_DEPS])
 AC_SUBST([EGL_DRIVERS_DIRS])
 
 dnl
+dnl X.Org DDX configuration
+dnl
+if test "x$enable_xorg" = xyes; then
+    PKG_CHECK_MODULES([XORG], [xorg-server >= 1.6.0])
+    PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED])
+    PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED])
+    PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
+        HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
+        HAVE_XEXTPROTO_71="no")
+    GALLIUM_STATE_TRACKERS_DIRS="xorg $GALLIUM_STATE_TRACKERS_DIRS"
+    HAVE_ST_XORG=yes
+fi
+
+dnl
+dnl OpenVG configuration
+dnl
+VG_LIB_DEPS=""
+
+if test "x$enable_openvg" = xyes; then
+    if test "x$enable_egl" = xno; then
+        AC_MSG_ERROR([cannot enable OpenVG without EGL])
+    fi
+    if test "x$enable_gallium" = xno; then
+        AC_MSG_ERROR([cannot enable OpenVG without Gallium])
+    fi
+
+    EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(VG_LIB)'
+    VG_LIB_DEPS="$VG_LIB_DEPS $SELINUX_LIBS -lpthread"
+    CORE_DIRS="$CORE_DIRS mapi/vgapi"
+    GALLIUM_STATE_TRACKERS_DIRS="vega $GALLIUM_STATE_TRACKERS_DIRS"
+    HAVE_ST_VEGA=yes
+fi
+
+dnl
+dnl D3D1X configuration
+dnl
+
+if test "x$enable_d3d1x" = xyes; then
+    GALLIUM_STATE_TRACKERS_DIRS="d3d1x $GALLIUM_STATE_TRACKERS_DIRS"
+    HAVE_ST_D3D1X=yes
+fi
+
+dnl
 dnl GLU configuration
 dnl
 AC_ARG_ENABLE([glu],
@@ -1451,14 +1500,6 @@ AC_SUBST([PROGRAM_DIRS])
 dnl
 dnl Gallium configuration
 dnl
-AC_ARG_ENABLE([gallium],
-    [AS_HELP_STRING([--disable-gallium],
-        [build gallium @<:@default=enabled@:>@])],
-    [enable_gallium="$enableval"],
-    [enable_gallium=yes])
-if test "x$enable_gallium" = xno -a "x$enable_openvg" = xyes; then
-    AC_MSG_ERROR([cannot enable OpenVG without Gallium])
-fi
 if test "x$enable_gallium" = xyes; then
     SRC_DIRS="$SRC_DIRS gallium gallium/winsys gallium/targets"
     AC_PATH_PROG([LLVM_CONFIG], [llvm-config], [no])
@@ -1469,125 +1510,17 @@ AC_SUBST([LLVM_LIBS])
 AC_SUBST([LLVM_LDFLAGS])
 AC_SUBST([LLVM_VERSION])
 
-dnl
-dnl Gallium state trackers configuration
-dnl
 
-AC_ARG_WITH([state-trackers],
-    [AS_HELP_STRING([--with-state-trackers@<:@=DIRS...@:>@],
-        [comma delimited state_trackers list, e.g.
-        "egl,glx" @<:@default=auto@:>@])],
-    [with_state_trackers="$withval"],
-    [with_state_trackers=yes])
-
-case "$with_state_trackers" in
-no)
-    GALLIUM_STATE_TRACKERS_DIRS=""
-    ;;
-yes)
-    # look at what else is built
-    case "$mesa_driver" in
-    xlib)
-        GALLIUM_STATE_TRACKERS_DIRS=glx
-        ;;
-    dri)
-        GALLIUM_STATE_TRACKERS_DIRS="dri"
-        HAVE_ST_DRI="yes"
-        # Have only tested st/xorg on 1.6.0 servers
-        PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0 libdrm >= $LIBDRM_XORG_REQUIRED libkms >= $LIBKMS_XORG_REQUIRED],
-            HAVE_ST_XORG="yes"; GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xorg",
-            HAVE_ST_XORG="no")
-        ;;
-    esac
-
-    if test "x$enable_egl" = xyes; then
-        if test "$enable_openvg" = yes; then
-            GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS vega"
-            st_egl="yes"
-        fi
-    fi
-    ;;
-*)
-    # verify the requested state tracker exist
-    state_trackers=""
-    _state_trackers=`IFS=', '; echo $with_state_trackers`
-    for tracker in $_state_trackers; do
-        case "$tracker" in
-        dri)
-            if test "x$mesa_driver" != xdri; then
-                AC_MSG_ERROR([cannot build dri state tracker without mesa driver set to dri])
-            fi
-            HAVE_ST_DRI="yes"
-            ;;
-        egl)
-            if test "x$enable_egl" != xyes; then
-                AC_MSG_ERROR([cannot build egl state tracker without EGL library])
-            fi
-            HAVE_ST_EGL="yes"
-            ;;
-        xorg)
-            PKG_CHECK_MODULES([XORG], [xorg-server >= 1.6.0])
-            PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED])
-            PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED])
-            HAVE_ST_XORG="yes"
-            ;;
-        vega)
-            if test "x$enable_openvg" != xyes; then
-                AC_MSG_ERROR([cannot build vega state tracker without --enable-openvg])
-            fi
-            have_st_vega="yes"
-            ;;
-        esac
-
-	if test -n "$tracker"; then
-            test -d "$srcdir/src/gallium/state_trackers/$tracker" || \
-                AC_MSG_ERROR([state tracker '$tracker' doesn't exist])
-            if test -n "$state_trackers"; then
-                state_trackers="$state_trackers $tracker"
-            else
-                state_trackers="$tracker"
-            fi
-        fi
-    done
-    GALLIUM_STATE_TRACKERS_DIRS="$state_trackers"
-
-    # append --enable-openvg/--enable-gallium-egl to --with-state-trackers
-    if test "x$have_st_vega" != xyes -a "x$enable_openvg" = xyes; then
-        AC_MSG_ERROR([--with-state-trackers specified but vega is missing])
-    fi
-    if test "x$HAVE_ST_EGL" != xyes; then
-        AC_MSG_ERROR([--with-state-trackers specified but egl is missing])
-    fi
-    ;;
-esac
-
-
-EGL_CLIENT_APIS=""
-VG_LIB_DEPS=""
 
 case "x$enable_opengl$enable_gles1$enable_gles2" in
 x*yes*)
     EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(GL_LIB)'
     ;;
 esac
-if test "x$enable_openvg" = xyes; then
-    EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(VG_LIB)'
-    VG_LIB_DEPS="$VG_LIB_DEPS $SELINUX_LIBS -lpthread"
-fi
 
 AC_SUBST([VG_LIB_DEPS])
 AC_SUBST([EGL_CLIENT_APIS])
 
-if test "x$HAVE_ST_EGL" = xyes; then
-	GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl"
-fi
-
-if test "x$HAVE_ST_XORG" = xyes; then
-    PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
-        HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
-        HAVE_XEXTPROTO_71="no")
-fi
-
 AC_ARG_WITH([egl-platforms],
     [AS_HELP_STRING([--with-egl-platforms@<:@=DIRS...@:>@],
         [comma delimited native platforms libEGL supports, e.g.
commit ad50abbac9b166b0fd10b3cf3c24eec32b366f6b
Author: Marek Olšák <maraeo at gmail.com>
Date:   Tue Jun 14 05:14:27 2011 +0200

    configure.ac: remove redundant option --enable-gallium-egl
    
    We already have --enable-gallium, --enable-egl, and --with-state-trackers=egl.
    
    Reviewed-by: Alex Deucher <alexdeucher at gmail.com>

diff --git a/configure.ac b/configure.ac
index 69513c1..90171fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1201,6 +1201,9 @@ if test "x$enable_egl" = xyes; then
     SRC_DIRS="$SRC_DIRS egl"
     EGL_LIB_DEPS="$DLOPEN_LIBS $SELINUX_LIBS -lpthread"
     EGL_DRIVERS_DIRS=""
+    GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl"
+    HAVE_ST_EGL="yes"
+
     if test "$enable_static" != yes; then
         # build egl_glx when libGL is built
         if test "$mesa_driver" = xlib -o "$mesa_driver" = dri; then
@@ -1470,26 +1473,6 @@ dnl
 dnl Gallium state trackers configuration
 dnl
 
-AC_ARG_ENABLE([gallium-egl],
-    [AS_HELP_STRING([--enable-gallium-egl],
-        [enable gallium EGL state tracker @<:@default=auto@:>@])],
-    [enable_gallium_egl="$enableval"],
-    [enable_gallium_egl=auto])
-if test "x$enable_gallium_egl" = xauto; then
-    case "$mesa_driver" in
-    dri|no)
-        enable_gallium_egl=$enable_egl
-        ;;
-    *)
-        enable_gallium_egl=$enable_openvg
-        ;;
-    esac
-fi
-case "x$enable_egl$enable_gallium_egl" in
-xnoyes)
-    AC_MSG_ERROR([cannot build Gallium EGL state tracker without EGL])
-esac
-
 AC_ARG_WITH([state-trackers],
     [AS_HELP_STRING([--with-state-trackers@<:@=DIRS...@:>@],
         [comma delimited state_trackers list, e.g.
@@ -1522,11 +1505,6 @@ yes)
             GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS vega"
             st_egl="yes"
         fi
-
-        if test "$enable_gallium_egl" = yes; then
-            GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl"
-            HAVE_ST_EGL="yes"
-        fi
     fi
     ;;
 *)
@@ -1577,7 +1555,7 @@ yes)
     if test "x$have_st_vega" != xyes -a "x$enable_openvg" = xyes; then
         AC_MSG_ERROR([--with-state-trackers specified but vega is missing])
     fi
-    if test "x$HAVE_ST_EGL" != xyes -a "x$enable_gallium_egl" = xyes; then
+    if test "x$HAVE_ST_EGL" != xyes; then
         AC_MSG_ERROR([--with-state-trackers specified but egl is missing])
     fi
     ;;
commit d1f66a9424d087f81d0040aafde033bd5cb1ca72
Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Jun 19 21:02:42 2011 +0200

    u_vbuf_mgr: make u_vbuf_mgr_draw_begin return flags in a bitmask

diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c
index fdfa9fc..374fc33 100644
--- a/src/gallium/auxiliary/util/u_vbuf_mgr.c
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c
@@ -152,9 +152,9 @@ void u_vbuf_mgr_destroy(struct u_vbuf_mgr *mgrb)
 }
 
 
-static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
-                                   int min_index, int max_index,
-                                   boolean *upload_flushed)
+static enum u_vbuf_return_flags
+u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
+                       int min_index, int max_index)
 {
    struct translate_key key;
    struct translate_element *te;
@@ -166,6 +166,7 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
    struct pipe_resource *out_buffer = NULL;
    unsigned i, num_verts, out_offset;
    struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
+   boolean upload_flushed = FALSE;
 
    memset(&key, 0, sizeof(key));
    memset(tr_elem_index, 0xff, sizeof(tr_elem_index));
@@ -248,7 +249,7 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
    u_upload_alloc(mgr->b.uploader,
                   key.output_stride * min_index,
                   key.output_stride * num_verts,
-                  &out_offset, &out_buffer, upload_flushed,
+                  &out_offset, &out_buffer, &upload_flushed,
                   (void**)&out_map);
 
    out_offset -= key.output_stride * min_index;
@@ -308,6 +309,8 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
    }
 
    pipe_resource_reference(&out_buffer, NULL);
+
+   return upload_flushed ? U_VBUF_UPLOAD_FLUSHED : 0;
 }
 
 static void u_vbuf_translate_end(struct u_vbuf_mgr_priv *mgr)
@@ -510,14 +513,15 @@ void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgrb,
    mgr->b.nr_real_vertex_buffers = count;
 }
 
-static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
-                                  int min_index, int max_index,
-                                  unsigned instance_count,
-                                  boolean *upload_flushed)
+static enum u_vbuf_return_flags
+u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
+                      int min_index, int max_index,
+                      unsigned instance_count)
 {
    unsigned i, nr = mgr->ve->count;
    unsigned count = max_index + 1 - min_index;
    boolean uploaded[PIPE_MAX_ATTRIBS] = {0};
+   enum u_vbuf_return_flags retval = 0;
 
    for (i = 0; i < nr; i++) {
       unsigned index = mgr->ve->ve[i].vertex_buffer_index;
@@ -556,11 +560,14 @@ static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
          vb->buffer_offset -= first;
 
          uploaded[index] = TRUE;
-         *upload_flushed = *upload_flushed || flushed;
+         if (flushed)
+            retval |= U_VBUF_UPLOAD_FLUSHED;
       } else {
          assert(mgr->b.real_vertex_buffer[index]);
       }
    }
+
+   return retval;
 }
 
 static void u_vbuf_mgr_compute_max_index(struct u_vbuf_mgr_priv *mgr)
@@ -602,14 +609,13 @@ static void u_vbuf_mgr_compute_max_index(struct u_vbuf_mgr_priv *mgr)
    }
 }
 
-void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
-                           const struct pipe_draw_info *info,
-                           boolean *buffers_updated,
-                           boolean *uploader_flushed)
+enum u_vbuf_return_flags
+u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
+                      const struct pipe_draw_info *info)
 {
    struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
-   boolean bufs_updated = FALSE, upload_flushed = FALSE;
    int min_index, max_index;
+   enum u_vbuf_return_flags retval = 0;
 
    u_vbuf_mgr_compute_max_index(mgr);
 
@@ -622,27 +628,20 @@ void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
 
    /* Translate vertices with non-native layouts or formats. */
    if (mgr->incompatible_vb_layout || mgr->ve->incompatible_layout) {
-      u_vbuf_translate_begin(mgr, min_index, max_index, &upload_flushed);
+      retval |= u_vbuf_translate_begin(mgr, min_index, max_index);
 
       if (mgr->fallback_ve) {
-         bufs_updated = TRUE;
+         retval |= U_VBUF_BUFFERS_UPDATED;
       }
    }
 
    /* Upload user buffers. */
    if (mgr->any_user_vbs) {
-      u_vbuf_upload_buffers(mgr, min_index, max_index, info->instance_count,
-                            &upload_flushed);
-      bufs_updated = TRUE;
-   }
-
-   /* Set the return values. */
-   if (buffers_updated) {
-      *buffers_updated = bufs_updated;
-   }
-   if (uploader_flushed) {
-      *uploader_flushed = upload_flushed;
+      retval |= u_vbuf_upload_buffers(mgr, min_index, max_index,
+                                      info->instance_count);
+      retval |= U_VBUF_BUFFERS_UPDATED;
    }
+   return retval;
 }
 
 void u_vbuf_mgr_draw_end(struct u_vbuf_mgr *mgrb)
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.h b/src/gallium/auxiliary/util/u_vbuf_mgr.h
index 9380dce..4e63724 100644
--- a/src/gallium/auxiliary/util/u_vbuf_mgr.h
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.h
@@ -78,6 +78,11 @@ enum u_fetch_alignment {
    U_VERTEX_FETCH_DWORD_ALIGNED
 };
 
+enum u_vbuf_return_flags {
+   U_VBUF_BUFFERS_UPDATED = 1,
+   U_VBUF_UPLOAD_FLUSHED = 2
+};
+
 
 struct u_vbuf_mgr *
 u_vbuf_mgr_create(struct pipe_context *pipe,
@@ -105,10 +110,9 @@ void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgr,
                                    unsigned count,
                                    const struct pipe_vertex_buffer *bufs);
 
-void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgr,
-                           const struct pipe_draw_info *info,
-                           boolean *buffers_updated,
-                           boolean *uploader_flushed);
+enum u_vbuf_return_flags
+u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgr,
+                      const struct pipe_draw_info *info);
 
 void u_vbuf_mgr_draw_end(struct u_vbuf_mgr *mgr);
 
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 7cf0aba..b31141a 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -768,7 +768,6 @@ static void r300_draw_vbo(struct pipe_context* pipe,
 {
     struct r300_context* r300 = r300_context(pipe);
     struct pipe_draw_info info = *dinfo;
-    boolean buffers_updated, uploader_flushed;
 
     info.indexed = info.indexed && r300->index_buffer.buffer;
 
@@ -780,9 +779,7 @@ static void r300_draw_vbo(struct pipe_context* pipe,
     r300_update_derived_state(r300);
 
     /* Start the vbuf manager and update buffers if needed. */
-    u_vbuf_mgr_draw_begin(r300->vbuf_mgr, &info,
-                          &buffers_updated, &uploader_flushed);
-    if (buffers_updated) {
+    if (u_vbuf_mgr_draw_begin(r300->vbuf_mgr, &info) & U_VBUF_BUFFERS_UPDATED) {
         r300->vertex_arrays_dirty = TRUE;
     }
 
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 5f9f398..816508a 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -543,7 +543,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
 		if (rctx->have_depth_fb || rctx->have_depth_texture)
 			r600_flush_depth_textures(rctx);
 	}
-	u_vbuf_mgr_draw_begin(rctx->vbuf_mgr, info, NULL, NULL);
+	u_vbuf_mgr_draw_begin(rctx->vbuf_mgr, info);
 	r600_vertex_buffer_update(rctx);
 
 	draw.info = *info;
commit 8623c68aec95e0883308051068b3496a85e8b9ea
Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Jun 19 19:42:22 2011 +0200

    r600g: fix warning: assignment discards qualifiers from pointer target type

diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index e858ea2..6171d28 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -294,7 +294,8 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
 {
 	struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src;
 	struct texture_orig_info orig_info[2];
-	struct pipe_box sbox, *psbox;
+	struct pipe_box sbox;
+	const struct pipe_box *psbox;
 	boolean restore_orig[2];
 
 	/* Fallback for buffers. */
commit 0d58723cde31703f13f2e8e0747cde30b9e5d6de
Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Jun 19 19:38:48 2011 +0200

    u_vbuf_mgr: fix uploading if format size is greater than stride

diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c
index 0414952..fdfa9fc 100644
--- a/src/gallium/auxiliary/util/u_vbuf_mgr.c
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c
@@ -537,6 +537,11 @@ static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
          } else if (vb->stride) {
             first = vb->stride * min_index;
             size = vb->stride * count;
+
+            /* Unusual case when stride is smaller than the format size.
+             * XXX This won't work with interleaved arrays. */
+            if (mgr->ve->native_format_size[i] > vb->stride)
+               size += mgr->ve->native_format_size[i] - vb->stride;
          } else {
             first = 0;
             size = mgr->ve->native_format_size[i];
commit dd3b812962a8720aca0a80bf6ea35f70319d3ca1
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Fri Jun 10 15:17:37 2011 -0700

    i965: Enable extension GL_ARB_shader_texture_lod.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=36987
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/docs/relnotes-7.11.html b/docs/relnotes-7.11.html
index aaeabc2..c81ac9f 100644
--- a/docs/relnotes-7.11.html
+++ b/docs/relnotes-7.11.html
@@ -45,7 +45,7 @@ tbd
 <li>GL_ARB_robustness (all drivers)
 <li>GL_ARB_sampler_objects (gallium drivers)
 <li>GL_ARB_seamless_cube_map (gallium r600)
-<li>GL_ARB_shader_texture_lod (gallium drivers)
+<li>GL_ARB_shader_texture_lod (gallium drivers, i965)
 <li>GL_ARB_sync (gallium drivers only, intel support was in 7.6)
 <li>GL_ARB_texture_compression_rgtc (gallium drivers, swrast, i965)
 <li>GL_ARB_texture_float (gallium, i965)
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 3fd987a..64c996c 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -172,6 +172,7 @@ static const struct dri_extension brw_extensions[] = {
    { "GL_ARB_occlusion_query",            GL_ARB_occlusion_query_functions },
    { "GL_ARB_point_sprite", 		  NULL },
    { "GL_ARB_seamless_cube_map",          NULL },
+   { "GL_ARB_shader_texture_lod",         NULL },
    { "GL_ARB_shadow",                     NULL },
 #ifdef TEXTURE_FLOAT_ENABLED
    { "GL_ARB_texture_float",              NULL },
commit 6430df37736d71dd2bd6f1fe447d39f0b68cb567
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Fri Jun 10 14:48:46 2011 -0700

    i965/fs: Add support for TXD with shadow comparisons.
    
    Our hardware doesn't have a sample_d_c message, so we have to do a
    regular sample_d and emit instructions to manually perform the
    comparison.
    
    This requires a state dependent recompile whenever the sampler's compare
    mode or function change.  This adds the per-sampler comparison functions
    to brw_wm_prog_key, but only sets them when the sampler's compare mode
    is GL_COMPARE_R_TO_TEXTURE (i.e. only for shadow sampling).
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 1cd6739..b5ea943 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1686,6 +1686,9 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
    key.clamp_fragment_color = true;
 
    for (int i = 0; i < BRW_MAX_TEX_UNIT; i++) {
+      if (fp->Base.ShadowSamplers & (1 << i))
+	 key.compare_funcs[i] = GL_LESS;
+
       /* FINISHME: depth compares might use (0,0,0,W) for example */
       key.tex_swizzles[i] = SWIZZLE_XYZW;
    }
diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
index 1c522cb..1d89b8f 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
@@ -273,7 +273,7 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
 	 }
 	 break;
       case FS_OPCODE_TXD:
-	 assert(!inst->shadow_compare);
+	 /* There is no sample_d_c message; comparisons are done manually */
 	 msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS;
 	 break;
       }
@@ -312,7 +312,7 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
 	 }
 	 break;
       case FS_OPCODE_TXD:
-	 assert(!inst->shadow_compare); // not supported yet
+	 /* There is no sample_d_c message; comparisons are done manually */
 	 assert(inst->mlen == 7 || inst->mlen == 10);
 	 msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS;
 	 break;
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 35bda58..6116b10 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -549,7 +549,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
    /* g0 header. */
    mlen = 1;
 
-   if (ir->shadow_comparitor) {
+   if (ir->shadow_comparitor && ir->op != ir_txd) {
       for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
 	 fs_inst *inst = emit(BRW_OPCODE_MOV,
 			      fs_reg(MRF, base_mrf + mlen + i), coordinate);
@@ -744,7 +744,7 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
    }
    mlen += ir->coordinate->type->vector_elements * reg_width;
 
-   if (ir->shadow_comparitor) {
+   if (ir->shadow_comparitor && ir->op != ir_txd) {
       mlen = MAX2(mlen, header_present + 4 * reg_width);
 
       this->result = reg_undef;
@@ -841,7 +841,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       base_mrf--;
    }
 
-   if (ir->shadow_comparitor) {
+   if (ir->shadow_comparitor && ir->op != ir_txd) {
       ir->shadow_comparitor->accept(this);
       emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
       mlen += reg_width;
@@ -937,6 +937,19 @@ fs_visitor::visit(ir_texture *ir)
    int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base);
    sampler = fp->Base.SamplerUnits[sampler];
 
+   /* Our hardware doesn't have a sample_d_c message, so shadow compares
+    * for textureGrad/TXD need to be emulated with instructions.
+    */
+   bool hw_compare_supported = ir->op != ir_txd;
+   if (ir->shadow_comparitor && !hw_compare_supported) {
+      assert(c->key.compare_funcs[sampler] != GL_NONE);
+      /* No need to even sample for GL_ALWAYS or GL_NEVER...bail early */
+      if (c->key.compare_funcs[sampler] == GL_ALWAYS)
+	 return swizzle_result(ir, fs_reg(1.0f), sampler);
+      else if (c->key.compare_funcs[sampler] == GL_NEVER)
+	 return swizzle_result(ir, fs_reg(0.0f), sampler);
+   }
+
    this->result = reg_undef;
    ir->coordinate->accept(this);
    fs_reg coordinate = this->result;
@@ -1045,8 +1058,47 @@ fs_visitor::visit(ir_texture *ir)
 
    inst->sampler = sampler;
 
-   if (ir->shadow_comparitor)
-      inst->shadow_compare = true;
+   if (ir->shadow_comparitor) {
+      if (hw_compare_supported) {
+	 inst->shadow_compare = true;
+      } else {
+	 ir->shadow_comparitor->accept(this);
+	 fs_reg ref = this->result;
+
+	 fs_reg value = dst;
+	 dst = fs_reg(this, glsl_type::vec4_type);
+
+	 /* FINISHME: This needs to be done pre-filtering. */
+
+	 uint32_t conditional = 0;
+	 switch (c->key.compare_funcs[sampler]) {
+	 /* GL_ALWAYS and GL_NEVER were handled at the top of the function */
+	 case GL_LESS:     conditional = BRW_CONDITIONAL_L;   break;
+	 case GL_GREATER:  conditional = BRW_CONDITIONAL_G;   break;
+	 case GL_LEQUAL:   conditional = BRW_CONDITIONAL_LE;  break;
+	 case GL_GEQUAL:   conditional = BRW_CONDITIONAL_GE;  break;
+	 case GL_EQUAL:    conditional = BRW_CONDITIONAL_EQ;  break;
+	 case GL_NOTEQUAL: conditional = BRW_CONDITIONAL_NEQ; break;
+	 default: assert(!"Should not get here: bad shadow compare function");
+	 }
+
+	 /* Use conditional moves to load 0 or 1 as the result */
+	 this->current_annotation = "manual shadow comparison";
+	 for (int i = 0; i < 4; i++) {
+	    inst = emit(BRW_OPCODE_MOV, dst, fs_reg(0.0f));
+
+	    inst = emit(BRW_OPCODE_CMP, reg_null_f, ref, value);
+	    inst->conditional_mod = conditional;
+
+	    inst = emit(BRW_OPCODE_MOV, dst, fs_reg(1.0f));
+	    inst->predicated = true;
+
+	    dst.reg_offset++;
+	    value.reg_offset++;
+	 }
+	 dst.reg_offset = 0;
+      }
+   }
 
    swizzle_result(ir, dst, sampler);
 }
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index f1c9985..b0dfdd5 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -388,6 +388,8 @@ static void brw_wm_populate_key( struct brw_context *brw,
 	  * all 4 channels.
 	  */
 	 if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
+	    key->compare_funcs[i] = sampler->CompareFunc;
+
 	    if (sampler->DepthMode == GL_ALPHA) {
 	       swizzles[0] = SWIZZLE_ZERO;
 	       swizzles[1] = SWIZZLE_ZERO;
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index e244b55..29082c1 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -68,6 +68,18 @@ struct brw_wm_prog_key {
    GLuint clamp_fragment_color:1;
    GLuint line_aa:2;
 
+   /**
+    * Per-sampler comparison functions:
+    *
+    * If comparison mode is GL_COMPARE_R_TO_TEXTURE, then this is set to one
+    * of GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL,
+    * GL_GEQUAL, or GL_ALWAYS.  Otherwise (comparison mode is GL_NONE), this
+    * field is irrelevant so it's left as GL_NONE (0).
+    *
+    * While this is a GLenum, all possible values fit in 16-bits.
+    */
+   uint16_t compare_funcs[BRW_MAX_TEX_UNIT];
+
    GLbitfield proj_attrib_mask; /**< one bit per fragment program attribute */
    GLuint yuvtex_mask:16;
    GLuint yuvtex_swap_mask:16;	/* UV swaped */
commit 01fa9addf447120e994415ad8fc8246ac234ec27
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Fri Jun 10 14:45:24 2011 -0700

    i965/fs: Refactor texture result swizzling into a helper function.
    
    The next patch will add a few additional uses.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 7570dda..2bf850e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -441,6 +441,8 @@ public:
    void visit(ir_function *ir);
    void visit(ir_function_signature *ir);
 
+   void swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler);
+
    fs_inst *emit(fs_inst inst);
 
    fs_inst *emit(int opcode)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index ac24375..35bda58 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -1045,20 +1045,30 @@ fs_visitor::visit(ir_texture *ir)
 
    inst->sampler = sampler;
 
-   this->result = dst;
-
    if (ir->shadow_comparitor)
       inst->shadow_compare = true;
 
+   swizzle_result(ir, dst, sampler);
+}
+
+/**
+ * Swizzle the result of a texture result.  This is necessary for
+ * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons.
+ */
+void
+fs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler)
+{
+   this->result = orig_val;
+
    if (ir->type == glsl_type::float_type) {
       /* Ignore DEPTH_TEXTURE_MODE swizzling. */
       assert(ir->sampler->type->sampler_shadow);
-   } else if (c->key.tex_swizzles[inst->sampler] != SWIZZLE_NOOP) {
-      fs_reg swizzle_dst = fs_reg(this, glsl_type::vec4_type);
+   } else if (c->key.tex_swizzles[sampler] != SWIZZLE_NOOP) {
+      fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type);
 
       for (int i = 0; i < 4; i++) {
-	 int swiz = GET_SWZ(c->key.tex_swizzles[inst->sampler], i);
-	 fs_reg l = swizzle_dst;
+	 int swiz = GET_SWZ(c->key.tex_swizzles[sampler], i);
+	 fs_reg l = swizzled_result;
 	 l.reg_offset += i;
 
 	 if (swiz == SWIZZLE_ZERO) {
@@ -1066,12 +1076,12 @@ fs_visitor::visit(ir_texture *ir)
 	 } else if (swiz == SWIZZLE_ONE) {
 	    emit(BRW_OPCODE_MOV, l, fs_reg(1.0f));
 	 } else {
-	    fs_reg r = dst;
-	    r.reg_offset += GET_SWZ(c->key.tex_swizzles[inst->sampler], i);
+	    fs_reg r = orig_val;
+	    r.reg_offset += GET_SWZ(c->key.tex_swizzles[sampler], i);
 	    emit(BRW_OPCODE_MOV, l, r);
 	 }
       }
-      this->result = swizzle_dst;
+      this->result = swizzled_result;
    }
 }
 
commit f1622cfe9c0f37a9b452be1297f187cba8c46e6a
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Fri Jun 10 14:49:36 2011 -0700

    i965/fs: Move sampler fetch to the top of the ir_texture visit function.
    
    This makes it available earlier, which will soon be necessary.
    (Separating code motion from actual changes.)
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index a5479e1..ac24375 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -932,9 +932,11 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
 void
 fs_visitor::visit(ir_texture *ir)
 {
-   int sampler;
    fs_inst *inst = NULL;
 
+   int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base);
+   sampler = fp->Base.SamplerUnits[sampler];
+
    this->result = reg_undef;
    ir->coordinate->accept(this);
    fs_reg coordinate = this->result;
@@ -973,11 +975,6 @@ fs_visitor::visit(ir_texture *ir)
    /* Should be lowered by do_lower_texture_projection */
    assert(!ir->projector);
 
-   sampler = _mesa_get_sampler_uniform_value(ir->sampler,
-					     prog,
-					     &fp->Base);
-   sampler = fp->Base.SamplerUnits[sampler];
-
    /* The 965 requires the EU to do the normalization of GL rectangle
     * texture coordinates.  We use the program parameter state
     * tracking to get the scaling factor.
commit 6c947cfd1973c3791d54f1406c973357b4a9621a
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Wed Jun 8 16:05:34 2011 -0700

    i965/fs: Add support for non-shadow textureGrad (TXD) on gen4.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
index 844b89b..1c522cb 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
@@ -312,7 +312,9 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
 	 }
 	 break;
       case FS_OPCODE_TXD:
-	 assert(!"TXD isn't supported on gen4 yet.");
+	 assert(!inst->shadow_compare); // not supported yet
+	 assert(inst->mlen == 7 || inst->mlen == 10);
+	 msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS;
 	 break;
       }
    }
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 638eaa4..a5479e1 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -595,7 +595,42 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
       mlen += 3;
    } else if (ir->op == ir_txd) {
-      assert(!"TXD isn't supported on gen4 yet.");
+      ir->lod_info.grad.dPdx->accept(this);
+      fs_reg dPdx = this->result;
+
+      ir->lod_info.grad.dPdy->accept(this);
+      fs_reg dPdy = this->result;
+
+      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
+	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate);
+	 coordinate.reg_offset++;
+      }
+      /* the slots for u and v are always present, but r is optional */
+      mlen += MAX2(ir->coordinate->type->vector_elements, 2);
+
+      /*  P   = u, v, r
+       * dPdx = dudx, dvdx, drdx
+       * dPdy = dudy, dvdy, drdy
+       *
+       * 2-arg: dudx   dvdx   dudy   dvdy
+       *        dPdx.x dPdx.y dPdy.x dPdy.y
+       *        m4     m5     m6     m7
+       *
+       * 3-arg: dudx   dvdx   drdx   dudy   dvdy   drdy
+       *        dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z
+       *        m5     m6     m7     m8     m9     m10
+       */
+      for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
+	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
+	 dPdx.reg_offset++;
+	 mlen++;
+      }
+
+      for (int i = 0; i < ir->lod_info.grad.dPdy->type->vector_elements; i++) {
+	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
+	 dPdy.reg_offset++;
+	 mlen++;
+      }
    } else {
       /* Oh joy.  gen4 doesn't have SIMD8 non-shadow-compare bias/lod
        * instructions.  We'll need to do SIMD16 here.
commit 2f4a4b943f1cad9bbbb8f66c34dca506503ba5bb
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Wed Jun 8 16:06:49 2011 -0700

    i965/fs: Add support for non-shadow textureGrad (TXD) on gen5/6.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 7255946..638eaa4 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -742,7 +742,37 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
 
       inst = emit(FS_OPCODE_TXL, dst);
       break;
-   case ir_txd:
+   case ir_txd: {
+      ir->lod_info.grad.dPdx->accept(this);
+      fs_reg dPdx = this->result;
+
+      ir->lod_info.grad.dPdy->accept(this);
+      fs_reg dPdy = this->result;
+
+      mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */
+
+      /**
+       *  P   =  u,    v,    r
+       * dPdx = dudx, dvdx, drdx
+       * dPdy = dudy, dvdy, drdy
+       *
+       * Load up these values:
+       * - dudx   dudy   dvdx   dvdy   drdx   drdy
+       * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z
+       */
+      for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
+	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
+	 dPdx.reg_offset++;
+	 mlen += reg_width;
+
+	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
+	 dPdy.reg_offset++;
+	 mlen += reg_width;
+      }
+
+      inst = emit(FS_OPCODE_TXD, dst);
+      break;
+   }
    case ir_txf:
       assert(!"GLSL 1.30 features unsupported");
       break;
commit 3fa910fff9f72d1adf33f0f4dea3d790a9ce04ab
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Wed Jun 8 16:08:07 2011 -0700

    i965/fs: Add support for non-shadow textureGrad (TXD) on Ivybridge.
    
    This is somewhat ugly, but I couldn't think of a nicer way to handle the
    interleaved coordinate/derivative parameter loading.
    
    Ironlake and Sandybridge will still hit an assertion in visit().
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
index 6b7c434..844b89b 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
@@ -273,7 +273,8 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
 	 }
 	 break;
       case FS_OPCODE_TXD:
-	 assert(!"TXD isn't supported on gen5+ yet.");
+	 assert(!inst->shadow_compare);
+	 msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS;
 	 break;
       }
    } else {
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index b485787..7255946 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -796,20 +796,52 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
       emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
       mlen += reg_width;
       break;
-   case ir_txd:
+   case ir_txd: {
+      if (c->dispatch_width == 16)
+	 fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode.");
+
+      ir->lod_info.grad.dPdx->accept(this);
+      fs_reg dPdx = this->result;
+
+      ir->lod_info.grad.dPdy->accept(this);
+      fs_reg dPdy = this->result;
+
+      /* Load dPdx and the coordinate together:
+       * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z
+       */
+      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
+	 fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
+			      coordinate);
+	 if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
+	    inst->saturate = true;
+	 coordinate.reg_offset++;
+	 mlen += reg_width;
+
+	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
+	 dPdx.reg_offset++;
+	 mlen += reg_width;
+
+	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
+	 dPdy.reg_offset++;
+	 mlen += reg_width;
+      }
+      break;
+   }
    case ir_txf:
       assert(!"GLSL 1.30 features unsupported");
       break;
    }
 
-   /* Set up the coordinate */
-   for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
-      fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
-			   coordinate);
-      if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
-	 inst->saturate = true;
-      coordinate.reg_offset++;
-      mlen += reg_width;
+   /* Set up the coordinate (except for TXD where it was done earlier) */
+   if (ir->op != ir_txd) {
+      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
+	 fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
+			      coordinate);
+	 if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
+	    inst->saturate = true;
+	 coordinate.reg_offset++;
+	 mlen += reg_width;
+      }
    }
 
    /* Generate the SEND */
commit ad9481e12813d5f1dec95ce123927e132fa935fb
Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Fri Jun 10 16:00:03 2011 -0700

    i965/fs: Check for compilation failure and bail before optimizing.
    
    Prior to this patch, it would attempt to optimize and allocate registers
    for the program even if it failed to compile.  This seems wasteful.
    
    More importantly, the "message length > 11" failure seems to choke the
    instruction scheduler, making it somehow use an undefined value and
    segmentation fault.
    
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 8580c78..1cd6739 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1533,6 +1533,8 @@ fs_visitor::run()
 	 this->result = reg_undef;
 	 ir->accept(this);
       }
+      if (failed)
+	 return false;
 
       emit_fb_writes();
 
commit c173541d9769d41a85cc899bc49699a3587df4bf
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Apr 27 13:33:10 2011 -0700

    i965: Use state streaming on programs, and state base address on gen5+.
    
    There will be a little bit of thrashing of the program cache BO as the
    cache warms up, but once the application is in steady state, this
    reduces relocations on gen5 and later.
    
    On my T420 laptop, cairogl firefox-talos-gfx performance improves 2.6%
    +/- 1.3% (n=6).  No statistically significant performance difference
    on nexuiz (n=5).

diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index c7d428b..d82206b 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -146,15 +146,12 @@ static void compile_clip_prog( struct brw_context *brw,
       printf("\n");
    }
 
-   /* Upload
-    */
-   drm_intel_bo_unreference(brw->clip.prog_bo);
-   brw->clip.prog_bo = brw_upload_cache(&brw->cache,
-					BRW_CLIP_PROG,
-					&c.key, sizeof(c.key),
-					program, program_size,
-					&c.prog_data, sizeof(c.prog_data),
-					&brw->clip.prog_data);
+   brw_upload_cache(&brw->cache,
+		    BRW_CLIP_PROG,
+		    &c.key, sizeof(c.key),
+		    program, program_size,
+		    &c.prog_data, sizeof(c.prog_data),
+		    &brw->clip.prog_offset, &brw->clip.prog_data);
    ralloc_free(mem_ctx);
 }
 
@@ -271,12 +268,11 @@ static void upload_clip_prog(struct brw_context *brw)
       }
    }
 
-   drm_intel_bo_unreference(brw->clip.prog_bo);
-   brw->clip.prog_bo = brw_search_cache(&brw->cache, BRW_CLIP_PROG,
-					&key, sizeof(key),
-					&brw->clip.prog_data);
-   if (brw->clip.prog_bo == NULL)
+   if (!brw_search_cache(&brw->cache, BRW_CLIP_PROG,
+			 &key, sizeof(key),
+			 &brw->clip.prog_offset, &brw->clip.prog_data)) {
       compile_clip_prog( brw, &key );
+   }
 }
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c
index 6015c8c..b9efbb7 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_state.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_state.c
@@ -43,11 +43,15 @@ brw_prepare_clip_unit(struct brw_context *brw)
    clip = brw_state_batch(brw, sizeof(*clip), 32, &brw->clip.state_offset);
    memset(clip, 0, sizeof(*clip));
 
-   /* CACHE_NEW_CLIP_PROG */
+   /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_CLIP_PROG */
    clip->thread0.grf_reg_count = (ALIGN(brw->clip.prog_data->total_grf, 16) /
 				 16 - 1);
-   /* reloc */
-   clip->thread0.kernel_start_pointer = brw->clip.prog_bo->offset >> 6;
+   clip->thread0.kernel_start_pointer =
+      brw_program_reloc(brw,
+			brw->clip.state_offset +
+			offsetof(struct brw_clip_unit_state, thread0),
+			brw->clip.prog_offset +
+			(clip->thread0.grf_reg_count << 1)) >> 6;
 
    clip->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
    clip->thread1.single_program_flow = 1;
@@ -110,14 +114,6 @@ brw_prepare_clip_unit(struct brw_context *brw)
    clip->viewport_ymin = -1;
    clip->viewport_ymax = 1;
 
-   /* Emit clip program relocation */
-   assert(brw->clip.prog_bo);
-   drm_intel_bo_emit_reloc(intel->batch.bo,
-			   (brw->clip.state_offset +
-			    offsetof(struct brw_clip_unit_state, thread0)),
-			   brw->clip.prog_bo, clip->thread0.grf_reg_count << 1,
-			   I915_GEM_DOMAIN_INSTRUCTION, 0);
-
    brw->state.dirty.cache |= CACHE_NEW_CLIP_UNIT;
 }
 
@@ -125,6 +121,7 @@ const struct brw_tracked_state brw_clip_unit = {
    .dirty = {
       .mesa  = _NEW_TRANSFORM,
       .brw   = (BRW_NEW_BATCH |
+		BRW_NEW_PROGRAM_CACHE |
 		BRW_NEW_CURBE_OFFSETS |
 		BRW_NEW_URB_FENCE),
       .cache = CACHE_NEW_CLIP_PROG
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 621b6f8..16b71f6 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -142,7 +142,8 @@ enum brw_state_id {
    BRW_STATE_NR_VS_SURFACES,
    BRW_STATE_INDEX_BUFFER,
    BRW_STATE_VS_CONSTBUF,
-   BRW_STATE_WM_CONSTBUF
+   BRW_STATE_WM_CONSTBUF,
+   BRW_STATE_PROGRAM_CACHE,
 };
 
 #define BRW_NEW_URB_FENCE               (1 << BRW_STATE_URB_FENCE)
@@ -172,6 +173,7 @@ enum brw_state_id {
 #define BRW_NEW_INDEX_BUFFER           (1 << BRW_STATE_INDEX_BUFFER)
 #define BRW_NEW_VS_CONSTBUF            (1 << BRW_STATE_VS_CONSTBUF)
 #define BRW_NEW_WM_CONSTBUF            (1 << BRW_STATE_WM_CONSTBUF)
+#define BRW_NEW_PROGRAM_CACHE		(1 << BRW_STATE_PROGRAM_CACHE)
 
 struct brw_state_flags {
    /** State update flags signalled by mesa internals */
@@ -365,7 +367,8 @@ struct brw_cache_item {
    GLuint key_size;		/* for variable-sized keys */
    const void *key;
 
-   drm_intel_bo *bo;
+   uint32_t offset;
+   uint32_t size;
 
    struct brw_cache_item *next;
 };   
@@ -376,14 +379,11 @@ struct brw_cache {
    struct brw_context *brw;
 
    struct brw_cache_item **items;
+   drm_intel_bo *bo;
    GLuint size, n_items;
 
-   char *name[BRW_MAX_CACHE];
-
-   /* Record of the last BOs chosen for each cache_id.  Used to set
-    * brw->state.dirty.cache when a new cache item is chosen.
-    */
-   drm_intel_bo *last_bo[BRW_MAX_CACHE];
+   uint32_t next_offset;
+   bool bo_used_by_gpu;
 };
 
 
@@ -634,8 +634,9 @@ struct brw_context
       struct brw_vs_prog_data *prog_data;
       int8_t *constant_map; /* variable array following prog_data */
 
-      drm_intel_bo *prog_bo;
       drm_intel_bo *const_bo;
+      /** Offset in the program cache to the VS program */
+      uint32_t prog_offset;
       uint32_t state_offset;
 
       /** Binding table of pointers to surf_bo entries */
@@ -651,14 +652,16 @@ struct brw_context
       struct brw_gs_prog_data *prog_data;
 
       GLboolean prog_active;
+      /** Offset in the program cache to the CLIP program pre-gen6 */
+      uint32_t prog_offset;
       uint32_t state_offset;
-      drm_intel_bo *prog_bo;
    } gs;
 
    struct {
       struct brw_clip_prog_data *prog_data;
 
-      drm_intel_bo *prog_bo;
+      /** Offset in the program cache to the CLIP program pre-gen6 */
+      uint32_t prog_offset;
 
       /* Offset in the batch to the CLIP state on pre-gen6. */
       uint32_t state_offset;
@@ -673,7 +676,8 @@ struct brw_context
    struct {
       struct brw_sf_prog_data *prog_data;
 
-      drm_intel_bo *prog_bo;
+      /** Offset in the program cache to the CLIP program pre-gen6 */
+      uint32_t prog_offset;
       uint32_t state_offset;
       uint32_t vp_offset;
    } sf;
@@ -700,12 +704,14 @@ struct brw_context
       GLuint sampler_count;
       uint32_t sampler_offset;
 
+      /** Offset in the program cache to the WM program */
+      uint32_t prog_offset;
+
       /** Binding table of pointers to surf_bo entries */
       uint32_t bind_bo_offset;
       uint32_t surf_offset[BRW_WM_MAX_SURF];
       uint32_t state_offset; /* offset in batchbuffer to pre-gen6 WM state */
 
-      drm_intel_bo *prog_bo;
       drm_intel_bo *const_bo; /* pull constant buffer. */
       /**
        * This is offset in the batch to the push constants on gen6.
@@ -717,9 +723,6 @@ struct brw_context
 
 
    struct {
-      /* gen4 */
-      drm_intel_bo *prog_bo;
-
       uint32_t state_offset;
       uint32_t blend_state_offset;
       uint32_t depth_stencil_state_offset;
@@ -874,6 +877,26 @@ brw_register_blocks(int reg_count)
    return ALIGN(reg_count, 16) / 16 - 1;
 }
 
+static inline uint32_t
+brw_program_reloc(struct brw_context *brw, uint32_t state_offset,
+		  uint32_t prog_offset)
+{
+   struct intel_context *intel = &brw->intel;
+
+   if (intel->gen >= 5) {
+      /* Using state base address. */
+      return prog_offset;
+   }
+
+   drm_intel_bo_emit_reloc(intel->batch.bo,
+			   state_offset,
+			   brw->cache.bo,
+			   prog_offset,
+			   I915_GEM_DOMAIN_INSTRUCTION, 0);
+
+   return brw->cache.bo->offset + prog_offset;
+}
+
 GLboolean brw_do_cubemap_normalize(struct exec_list *instructions);
 
 #endif
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 7c73a8f..8580c78 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1697,14 +1697,12 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
 
    key.program_string_id = bfp->id;
 
-   drm_intel_bo *old_prog_bo = brw->wm.prog_bo;
+   uint32_t old_prog_offset = brw->wm.prog_offset;
    struct brw_wm_prog_data *old_prog_data = brw->wm.prog_data;
-   brw->wm.prog_bo = NULL;
 
    bool success = do_wm_prog(brw, prog, bfp, &key);
 
-   drm_intel_bo_unreference(brw->wm.prog_bo);
-   brw->wm.prog_bo = old_prog_bo;
+   brw->wm.prog_offset = old_prog_offset;
    brw->wm.prog_data = old_prog_data;
 
    return success;
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index 001cd62..3171e97 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -121,14 +121,11 @@ static void compile_gs_prog( struct brw_context *brw,
       printf("\n");
     }
 
-   /* Upload
-    */
-   drm_intel_bo_unreference(brw->gs.prog_bo);
-   brw->gs.prog_bo = brw_upload_cache(&brw->cache, BRW_GS_PROG,
-				      &c.key, sizeof(c.key),
-				      program, program_size,
-				      &c.prog_data, sizeof(c.prog_data),
-				      &brw->gs.prog_data);
+   brw_upload_cache(&brw->cache, BRW_GS_PROG,
+		    &c.key, sizeof(c.key),
+		    program, program_size,
+		    &c.prog_data, sizeof(c.prog_data),
+		    &brw->gs.prog_offset, &brw->gs.prog_data);
    ralloc_free(mem_ctx);
 }
 
@@ -189,15 +186,12 @@ static void prepare_gs_prog(struct brw_context *brw)
       brw->gs.prog_active = key.need_gs_prog;
    }
 
-   drm_intel_bo_unreference(brw->gs.prog_bo);
-   brw->gs.prog_bo = NULL;
-
    if (brw->gs.prog_active) {
-      brw->gs.prog_bo = brw_search_cache(&brw->cache, BRW_GS_PROG,
-					 &key, sizeof(key),
-					 &brw->gs.prog_data);
-      if (brw->gs.prog_bo == NULL)
+      if (!brw_search_cache(&brw->cache, BRW_GS_PROG,
+			    &key, sizeof(key),
+			    &brw->gs.prog_offset, &brw->gs.prog_data)) {
 	 compile_gs_prog( brw, &key );
+      }
    }
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c
index 542874b..bbfefcd 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_state.c
@@ -45,12 +45,17 @@ brw_prepare_gs_unit(struct brw_context *brw)
 
    memset(gs, 0, sizeof(*gs));
 
-   /* CACHE_NEW_GS_PROG */
+   /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_GS_PROG */
    if (brw->gs.prog_active) {
       gs->thread0.grf_reg_count = (ALIGN(brw->gs.prog_data->total_grf, 16) /
 				   16 - 1);
-      /* reloc */
-      gs->thread0.kernel_start_pointer = brw->gs.prog_bo->offset >> 6;
+
+      gs->thread0.kernel_start_pointer =
+	 brw_program_reloc(brw,
+			   brw->gs.state_offset +
+			   offsetof(struct brw_gs_unit_state, thread0),
+			   brw->gs.prog_offset +
+			   (gs->thread0.grf_reg_count << 1)) >> 6;
 
       gs->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
       gs->thread1.single_program_flow = 1;
@@ -69,13 +74,6 @@ brw_prepare_gs_unit(struct brw_context *brw)
 	 gs->thread4.max_threads = 1;
       else
 	 gs->thread4.max_threads = 0;
-
-      /* Emit GS program relocation */
-      drm_intel_bo_emit_reloc(intel->batch.bo,
-			      (brw->gs.state_offset +
-			       offsetof(struct brw_gs_unit_state, thread0)),
-			      brw->gs.prog_bo, gs->thread0.grf_reg_count << 1,
-			      I915_GEM_DOMAIN_INSTRUCTION, 0);
    }
 
    if (intel->gen == 5)
@@ -91,6 +89,7 @@ const struct brw_tracked_state brw_gs_unit = {
    .dirty = {
       .mesa  = 0,
       .brw   = (BRW_NEW_BATCH |
+		BRW_NEW_PROGRAM_CACHE |
 		BRW_NEW_CURBE_OFFSETS |
 		BRW_NEW_URB_FENCE),
       .cache = CACHE_NEW_GS_PROG
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 1f3b64f..b0f95dd 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -706,7 +706,9 @@ static void upload_state_base_address( struct brw_context *brw )
 				   I915_GEM_DOMAIN_INSTRUCTION), 0, 1);
 
        OUT_BATCH(1); /* Indirect object base address: MEDIA_OBJECT data */
-       OUT_BATCH(1); /* Instruction base address: shader kernels (incl. SIP) */
+       OUT_RELOC(brw->cache.bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
+		 1); /* Instruction base address: shader kernels (incl. SIP) */
+
        OUT_BATCH(1); /* General state upper bound */
        OUT_BATCH(1); /* Dynamic state upper bound */
        OUT_BATCH(1); /* Indirect object upper bound */
@@ -719,7 +721,8 @@ static void upload_state_base_address( struct brw_context *brw )
        OUT_RELOC(intel->batch.bo, I915_GEM_DOMAIN_SAMPLER, 0,
 		 1); /* Surface state base address */
        OUT_BATCH(1); /* Indirect object base address */
-       OUT_BATCH(1); /* Instruction base address */
+       OUT_RELOC(brw->cache.bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
+		 1); /* Instruction base address */
        OUT_BATCH(1); /* General state upper bound */
        OUT_BATCH(1); /* Indirect object upper bound */
        OUT_BATCH(1); /* Instruction access upper bound */
@@ -740,7 +743,8 @@ static void upload_state_base_address( struct brw_context *brw )
 const struct brw_tracked_state brw_state_base_address = {
    .dirty = {
       .mesa = 0,
-      .brw = BRW_NEW_BATCH,
+      .brw = (BRW_NEW_BATCH |
+	      BRW_NEW_PROGRAM_CACHE),
       .cache = 0,
    },
    .emit = upload_state_base_address
diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c
index c222777..fca30a7 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.c
+++ b/src/mesa/drivers/dri/i965/brw_sf.c
@@ -120,14 +120,11 @@ static void compile_sf_prog( struct brw_context *brw,
       printf("\n");
    }
 
-   /* Upload
-    */
-   drm_intel_bo_unreference(brw->sf.prog_bo);
-   brw->sf.prog_bo = brw_upload_cache(&brw->cache, BRW_SF_PROG,
-				      &c.key, sizeof(c.key),
-				      program, program_size,
-				      &c.prog_data, sizeof(c.prog_data),
-				      &brw->sf.prog_data);
+   brw_upload_cache(&brw->cache, BRW_SF_PROG,
+		    &c.key, sizeof(c.key),
+		    program, program_size,
+		    &c.prog_data, sizeof(c.prog_data),
+		    &brw->sf.prog_offset, &brw->sf.prog_data);
    ralloc_free(mem_ctx);
 }
 
@@ -191,12 +188,11 @@ static void upload_sf_prog(struct brw_context *brw)
       key.frontface_ccw = (ctx->Polygon.FrontFace == GL_CCW) ^ (ctx->DrawBuffer->Name != 0);
    }
 
-   drm_intel_bo_unreference(brw->sf.prog_bo);
-   brw->sf.prog_bo = brw_search_cache(&brw->cache, BRW_SF_PROG,
-				      &key, sizeof(key),
-				      &brw->sf.prog_data);
-   if (brw->sf.prog_bo == NULL)
+   if (!brw_search_cache(&brw->cache, BRW_SF_PROG,
+			 &key, sizeof(key),
+			 &brw->sf.prog_offset, &brw->sf.prog_data)) {
       compile_sf_prog( brw, &key );
+   }
 }
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index 78b22c4..eb3d103 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -133,9 +133,14 @@ static void upload_sf_unit( struct brw_context *brw )
 
    memset(sf, 0, sizeof(*sf));
 
-   /* CACHE_NEW_SF_PROG */
+   /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_SF_PROG */
    sf->thread0.grf_reg_count = ALIGN(brw->sf.prog_data->total_grf, 16) / 16 - 1;
-   sf->thread0.kernel_start_pointer = brw->sf.prog_bo->offset >> 6; /* reloc */
+   sf->thread0.kernel_start_pointer =
+      brw_program_reloc(brw,
+			brw->sf.state_offset +
+			offsetof(struct brw_sf_unit_state, thread0),
+			brw->sf.prog_offset +
+			(sf->thread0.grf_reg_count << 1)) >> 6;
 
    sf->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
 
@@ -282,11 +287,6 @@ static void upload_sf_unit( struct brw_context *brw )
    /* STATE_PREFETCH command description describes this state as being
     * something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain.
     */
-   /* Emit SF program relocation */
-   drm_intel_bo_emit_reloc(bo, (brw->sf.state_offset +
-				offsetof(struct brw_sf_unit_state, thread0)),
-			   brw->sf.prog_bo, sf->thread0.grf_reg_count << 1,
-			   I915_GEM_DOMAIN_INSTRUCTION, 0);
 
    /* Emit SF viewport relocation */
    drm_intel_bo_emit_reloc(bo, (brw->sf.state_offset +
@@ -308,6 +308,7 @@ const struct brw_tracked_state brw_sf_unit = {
 		_NEW_SCISSOR |
 		_NEW_BUFFERS),
       .brw   = (BRW_NEW_BATCH |
+		BRW_NEW_PROGRAM_CACHE |
 		BRW_NEW_URB_FENCE),
       .cache = (CACHE_NEW_SF_VP |
 		CACHE_NEW_SF_PROG)
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 544ef7d..b384651 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -145,21 +145,21 @@ void brw_clear_validated_bos(struct brw_context *brw);
  * brw_state_cache.c
  */
 
-drm_intel_bo *brw_upload_cache(struct brw_cache *cache,
-			       enum brw_cache_id cache_id,
-			       const void *key,
-			       GLuint key_sz,
-			       const void *data,
-			       GLuint data_sz,
-			       const void *aux,
-			       GLuint aux_sz,
-			       void *aux_return);
-
-drm_intel_bo *brw_search_cache( struct brw_cache *cache,
-			  enum brw_cache_id cache_id,
-			  const void *key,
-			  GLuint key_size,
-			  void *aux_return);
+void brw_upload_cache(struct brw_cache *cache,
+		      enum brw_cache_id cache_id,
+		      const void *key,
+		      GLuint key_sz,
+		      const void *data,
+		      GLuint data_sz,
+		      const void *aux,
+		      GLuint aux_sz,
+		      uint32_t *out_offset, void *out_aux);
+
+bool brw_search_cache(struct brw_cache *cache,
+		      enum brw_cache_id cache_id,
+		      const void *key,
+		      GLuint key_size,
+		      uint32_t *inout_offset, void *out_aux);
 void brw_state_cache_check_size( struct brw_context *brw );
 
 void brw_init_caches( struct brw_context *brw );
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index f13a41f..d13711b 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -45,6 +45,7 @@
  */
 
 #include "main/imports.h"
+#include "intel_batchbuffer.h"
 #include "brw_state.h"
 
 #define FILE_DEBUG_FLAG DEBUG_STATE
@@ -67,23 +68,6 @@ hash_key(struct brw_cache_item *item)
    return hash;
 }
 
-
-/**
- * Marks a new buffer as being chosen for the given cache id.
- */
-static void
-update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id,
-		  drm_intel_bo *bo)
-{
-   if (bo == cache->last_bo[cache_id])
-      return; /* no change */
-
-   drm_intel_bo_unreference(cache->last_bo[cache_id]);
-   cache->last_bo[cache_id] = bo;
-   drm_intel_bo_reference(cache->last_bo[cache_id]);
-   cache->brw->state.dirty.cache |= 1 << cache_id;
-}
-
 static int
 brw_cache_item_equals(const struct brw_cache_item *a,
 		      const struct brw_cache_item *b)
@@ -145,12 +129,13 @@ rehash(struct brw_cache *cache)
 /**
  * Returns the buffer object matching cache_id and key, or NULL.
  */
-drm_intel_bo *
+bool
 brw_search_cache(struct brw_cache *cache,
                  enum brw_cache_id cache_id,
                  const void *key, GLuint key_size,
-                 void *aux_return)
+                 uint32_t *inout_offset, void *out_aux)
 {
+   struct brw_context *brw = cache->brw;
    struct brw_cache_item *item;
    struct brw_cache_item lookup;
    GLuint hash;
@@ -164,19 +149,45 @@ brw_search_cache(struct brw_cache *cache,
    item = search_cache(cache, hash, &lookup);
 
    if (item == NULL)
-      return NULL;
+      return false;
 
-   if (aux_return)
-      *(void **)aux_return = (void *)((char *)item->key + item->key_size);
+   *(void **)out_aux = ((char *)item->key + item->key_size);
 
-   update_cache_last(cache, cache_id, item->bo);
+   if (item->offset != *inout_offset) {
+      brw->state.dirty.cache |= (1 << cache_id);
+      *inout_offset = item->offset;
+   }
 
-   drm_intel_bo_reference(item->bo);
-   return item->bo;
+   return true;
 }
 
+static void
+brw_cache_new_bo(struct brw_cache *cache, uint32_t new_size)
+{
+   struct brw_context *brw = cache->brw;
+   struct intel_context *intel = &brw->intel;
+   drm_intel_bo *new_bo;
+
+   new_bo = drm_intel_bo_alloc(intel->bufmgr, "program cache", new_size, 64);
 
-drm_intel_bo *
+   /* Copy any existing data that needs to be saved. */
+   if (cache->next_offset != 0) {
+      drm_intel_bo_map(cache->bo, false);
+      drm_intel_bo_subdata(new_bo, 0, cache->next_offset, cache->bo->virtual);
+      drm_intel_bo_unmap(cache->bo);
+   }
+
+   drm_intel_bo_unreference(cache->bo);
+   cache->bo = new_bo;
+   cache->bo_used_by_gpu = false;
+
+   /* Since we have a new BO in place, we need to signal the units
+    * that depend on it (state base address on gen5+, or unit state before).
+    */
+   brw->state.dirty.brw |= BRW_NEW_PROGRAM_CACHE;
+}
+
+void
 brw_upload_cache(struct brw_cache *cache,
 		 enum brw_cache_id cache_id,
 		 const void *key,
@@ -185,12 +196,12 @@ brw_upload_cache(struct brw_cache *cache,
 		 GLuint data_size,
 		 const void *aux,
 		 GLuint aux_size,
-		 void *aux_return)
+		 uint32_t *out_offset,
+		 void *out_aux)
 {
    struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item);
    GLuint hash;
    void *tmp;
-   drm_intel_bo *bo;
 
    item->cache_id = cache_id;
    item->key = key;
@@ -198,10 +209,28 @@ brw_upload_cache(struct brw_cache *cache,
    hash = hash_key(item);
    item->hash = hash;
 
-   /* Create the buffer object to contain the data */
-   bo = drm_intel_bo_alloc(cache->brw->intel.bufmgr,
-			   cache->name[cache_id], data_size, 1 << 6);
+   /* Allocate space in the cache BO for our new program. */
+   if (cache->next_offset + data_size > cache->bo->size) {
+      uint32_t new_size = cache->bo->size * 2;
+
+      while (cache->next_offset + data_size > new_size)
+	 new_size *= 2;
+
+      brw_cache_new_bo(cache, new_size);
+   }
+
+   /* If we would block on writing to an in-use program BO, just
+    * recreate it.
+    */
+   if (cache->bo_used_by_gpu) {
+      brw_cache_new_bo(cache, cache->bo->size);
+   }
+
+   item->offset = cache->next_offset;
+   item->size = data_size;
 
+   /* Programs are always 64-byte aligned, so set up the next one now */
+   cache->next_offset = ALIGN(item->offset + data_size, 64);
 
    /* Set up the memory containing the key and aux_data */
    tmp = malloc(key_size + aux_size);
@@ -211,9 +240,6 @@ brw_upload_cache(struct brw_cache *cache,
 
    item->key = tmp;
 
-   item->bo = bo;
-   drm_intel_bo_reference(bo);
-
    if (cache->n_items > cache->size * 1.5)
       rehash(cache);
 
@@ -222,34 +248,18 @@ brw_upload_cache(struct brw_cache *cache,
    cache->items[hash] = item;
    cache->n_items++;
 
-   if (aux_return) {
-      *(void **)aux_return = (void *)((char *)item->key + item->key_size);
-   }
-
-   DBG("upload %s: %d bytes to cache id %d\n",
-       cache->name[cache_id],
-       data_size, cache_id);
-
    /* Copy data to the buffer */
-   drm_intel_bo_subdata(bo, 0, data_size, data);
-
-   update_cache_last(cache, cache_id, bo);
+   drm_intel_bo_subdata(cache->bo, item->offset, data_size, data);
 
-   return bo;
-}
-
-static void
-brw_init_cache_id(struct brw_cache *cache,
-                  const char *name,
-                  enum brw_cache_id id)
-{
-   cache->name[id] = strdup(name);
+   *out_offset = item->offset;
+   *(void **)out_aux = (void *)((char *)item->key + item->key_size);
+   cache->brw->state.dirty.cache |= 1 << cache_id;
 }
 
-
 void
 brw_init_caches(struct brw_context *brw)
 {
+   struct intel_context *intel = &brw->intel;
    struct brw_cache *cache = &brw->cache;
 
    cache->brw = brw;
@@ -259,36 +269,15 @@ brw_init_caches(struct brw_context *brw)
    cache->items = (struct brw_cache_item **)
       calloc(1, cache->size * sizeof(struct brw_cache_item));
 
-   brw_init_cache_id(cache, "CC_VP", BRW_CC_VP);
-   brw_init_cache_id(cache, "CC_UNIT", BRW_CC_UNIT);
-   brw_init_cache_id(cache, "WM_PROG", BRW_WM_PROG);
-   brw_init_cache_id(cache, "SAMPLER", BRW_SAMPLER);
-   brw_init_cache_id(cache, "WM_UNIT", BRW_WM_UNIT);
-   brw_init_cache_id(cache, "SF_PROG", BRW_SF_PROG);
-   brw_init_cache_id(cache, "SF_VP", BRW_SF_VP);
-
-   brw_init_cache_id(cache, "SF_UNIT", BRW_SF_UNIT);
-
-   brw_init_cache_id(cache, "VS_UNIT", BRW_VS_UNIT);
-
-   brw_init_cache_id(cache, "VS_PROG", BRW_VS_PROG);
-
-   brw_init_cache_id(cache, "CLIP_UNIT", BRW_CLIP_UNIT);
-
-   brw_init_cache_id(cache, "CLIP_PROG", BRW_CLIP_PROG);
-   brw_init_cache_id(cache, "CLIP_VP", BRW_CLIP_VP);
-
-   brw_init_cache_id(cache, "GS_UNIT", BRW_GS_UNIT);
-
-   brw_init_cache_id(cache, "GS_PROG", BRW_GS_PROG);
-   brw_init_cache_id(cache, "BLEND_STATE", BRW_BLEND_STATE);
-   brw_init_cache_id(cache, "COLOR_CALC_STATE", BRW_COLOR_CALC_STATE);
-   brw_init_cache_id(cache, "DEPTH_STENCIL_STATE", BRW_DEPTH_STENCIL_STATE);
+   cache->bo = drm_intel_bo_alloc(intel->bufmgr,
+				  "program cache",
+				  4096, 64);
 }
 
 static void
 brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
 {
+   struct intel_context *intel = &brw->intel;
    struct brw_cache_item *c, *next;
    GLuint i;
 
@@ -297,7 +286,6 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
    for (i = 0; i < cache->size; i++) {
       for (c = cache->items[i]; c; c = next) {
 	 next = c->next;
-	 drm_intel_bo_unreference(c->bo);
 	 free((void *)c->key);
 	 free(c);
       }
@@ -306,9 +294,18 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
 
    cache->n_items = 0;
 
+   /* Start putting programs into the start of the BO again, since
+    * we'll never find the old results.
+    */
+   cache->next_offset = 0;
+
+   /* We need to make sure that the programs get regenerated, since
+    * any offsets leftover in brw_context will no longer be valid.
+    */
    brw->state.dirty.mesa |= ~0;
    brw->state.dirty.brw |= ~0;
    brw->state.dirty.cache |= ~0;
+   intel_batchbuffer_flush(intel);
 }
 
 void
@@ -325,15 +322,10 @@ brw_state_cache_check_size(struct brw_context *brw)
 static void
 brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache)
 {
-   GLuint i;
 
    DBG("%s\n", __FUNCTION__);
 
    brw_clear_cache(brw, cache);
-   for (i = 0; i < BRW_MAX_CACHE; i++) {
-      drm_intel_bo_unreference(cache->last_bo[i]);
-      free(cache->name[i]);
-   }
    free(cache->items);
    cache->items = NULL;
    cache->size = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_state_dump.c b/src/mesa/drivers/dri/i965/brw_state_dump.c
index ff06cb3..7a3a88f 100644
--- a/src/mesa/drivers/dri/i965/brw_state_dump.c
+++ b/src/mesa/drivers/dri/i965/brw_state_dump.c
@@ -459,21 +459,19 @@ static void dump_blend_state(struct brw_context *brw)
 
 }
 
-static void brw_debug_prog(const char *name, drm_intel_bo *prog)
+static void brw_debug_prog(struct brw_context *brw,
+			   const char *name, uint32_t prog_offset)
 {
    unsigned int i;
    uint32_t *data;
 
-   if (prog == NULL)
-      return;
-
-   drm_intel_bo_map(prog, GL_FALSE);
+   drm_intel_bo_map(brw->cache.bo, false);
 
-   data = prog->virtual;
+   data = brw->cache.bo->virtual + prog_offset;
 
-   for (i = 0; i < prog->size / 4 / 4; i++) {
+   for (i = 0; i < brw->cache.bo->size / 4 / 4; i++) {
       fprintf(stderr, "%8s: 0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
-	      name, (unsigned int)prog->offset + i * 4 * 4,
+	      name, (unsigned int)brw->cache.bo->offset + i * 4 * 4,
 	      data[i * 4], data[i * 4 + 1], data[i * 4 + 2], data[i * 4 + 3]);
       /* Stop at the end of the program.  It'd be nice to keep track of the actual
        * intended program size instead of guessing like this.
@@ -485,7 +483,7 @@ static void brw_debug_prog(const char *name, drm_intel_bo *prog)
 	 break;
    }
 
-   drm_intel_bo_unmap(prog);
+   drm_intel_bo_unmap(brw->cache.bo);
 }
 
 
@@ -518,17 +516,19 @@ void brw_debug_batch(struct intel_context *intel)
    if (intel->gen < 6)
        state_struct_out("VS", intel->batch.bo, brw->vs.state_offset,
 			sizeof(struct brw_vs_unit_state));
-   brw_debug_prog("VS prog", brw->vs.prog_bo);
+   brw_debug_prog(brw, "VS prog", brw->vs.prog_offset);
 
    if (intel->gen < 6)
        state_struct_out("GS", intel->batch.bo, brw->gs.state_offset,
 			sizeof(struct brw_gs_unit_state));
-   brw_debug_prog("GS prog", brw->gs.prog_bo);
+   if (brw->gs.prog_active) {
+      brw_debug_prog(brw, "GS prog", brw->gs.prog_offset);
+   }
 
    if (intel->gen < 6) {
       state_struct_out("SF", intel->batch.bo, brw->sf.state_offset,
 		       sizeof(struct brw_sf_unit_state));
-      brw_debug_prog("SF prog", brw->sf.prog_bo);
+      brw_debug_prog(brw, "SF prog", brw->sf.prog_offset);
    }
    if (intel->gen >= 7)
       dump_sf_clip_viewport_state(brw);
@@ -540,7 +540,7 @@ void brw_debug_batch(struct intel_context *intel)
    if (intel->gen < 6)
        state_struct_out("WM", intel->batch.bo, brw->wm.state_offset,
 			sizeof(struct brw_wm_unit_state));
-   brw_debug_prog("WM prog", brw->wm.prog_bo);
+   brw_debug_prog(brw, "WM prog", brw->wm.prog_offset);
 
    if (intel->gen >= 6) {
 	dump_cc_viewport_state(brw);
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 6a4c112..50ab490 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -47,11 +47,11 @@ static const struct brw_tracked_state *gen4_atoms[] =
    &brw_check_fallback,
 
    &brw_wm_input_sizes,
-   &brw_vs_prog,
-   &brw_gs_prog, 
-   &brw_clip_prog, 
-   &brw_sf_prog,
-   &brw_wm_prog,
+   &brw_vs_prog, /* must do before GS prog, state base address. */
+   &brw_gs_prog, /* must do before state base address */
+   &brw_clip_prog, /* must do before state base address */
+   &brw_sf_prog, /* must do before state base address */
+   &brw_wm_prog, /* must do before state base address */
 
    /* Once all the programs are done, we know how large urb entry
     * sizes need to be and can decide if we need to change the urb
@@ -110,9 +110,9 @@ static const struct brw_tracked_state *gen6_atoms[] =
    &brw_check_fallback,
 
    &brw_wm_input_sizes,
-   &brw_vs_prog,
-   &brw_gs_prog,
-   &brw_wm_prog,
+   &brw_vs_prog, /* must do before state base address */
+   &brw_gs_prog, /* must do before state base address */
+   &brw_wm_prog, /* must do before state base address */
 
    &gen6_clip_vp,
    &gen6_sf_vp,
@@ -365,6 +365,7 @@ static struct dirty_bit_map brw_bits[] = {
    DEFINE_BIT(BRW_NEW_PRIMITIVE),
    DEFINE_BIT(BRW_NEW_CONTEXT),
    DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS),
+   DEFINE_BIT(BRW_NEW_PROGRAM_CACHE),
    DEFINE_BIT(BRW_NEW_PSP),
    DEFINE_BIT(BRW_NEW_WM_SURFACES),
    DEFINE_BIT(BRW_NEW_INDICES),
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index 80d5e78..a9ad531 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -105,12 +105,11 @@ static void do_vs_prog( struct brw_context *brw,
    /* constant_map */
    aux_size += c.vp->program.Base.Parameters->NumParameters;
 
-   drm_intel_bo_unreference(brw->vs.prog_bo);
-   brw->vs.prog_bo = brw_upload_cache(&brw->cache, BRW_VS_PROG,
-				      &c.key, sizeof(c.key),
-				      program, program_size,
-				      &c.prog_data, aux_size,
-				      &brw->vs.prog_data);
+   brw_upload_cache(&brw->cache, BRW_VS_PROG,
+		    &c.key, sizeof(c.key),
+		    program, program_size,
+		    &c.prog_data, aux_size,
+		    &brw->vs.prog_offset, &brw->vs.prog_data);
    ralloc_free(mem_ctx);
 }
 
@@ -153,14 +152,11 @@ static void brw_upload_vs_prog(struct brw_context *brw)
       }
    }
 
-   /* Make an early check for the key.
-    */
-   drm_intel_bo_unreference(brw->vs.prog_bo);
-   brw->vs.prog_bo = brw_search_cache(&brw->cache, BRW_VS_PROG,
-				      &key, sizeof(key),
-				      &brw->vs.prog_data);
-   if (brw->vs.prog_bo == NULL)
+   if (!brw_search_cache(&brw->cache, BRW_VS_PROG,
+			 &key, sizeof(key),
+			 &brw->vs.prog_offset, &brw->vs.prog_data)) {
       do_vs_prog(brw, vp, &key);
+   }
    brw->vs.constant_map = ((int8_t *)brw->vs.prog_data +
 			   sizeof(*brw->vs.prog_data));
 }
diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c
index 1eee5b7..185020c 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_state.c
@@ -58,8 +58,14 @@ brw_prepare_vs_unit(struct brw_context *brw)
    vs = brw_state_batch(brw, sizeof(*vs), 32, &brw->vs.state_offset);
    memset(vs, 0, sizeof(*vs));
 
-   /* CACHE_NEW_VS_PROG */
-   vs->thread0.kernel_start_pointer = brw->vs.prog_bo->offset >> 6; /* reloc */
+   /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_VS_PROG */
+   vs->thread0.kernel_start_pointer =
+      brw_program_reloc(brw,
+			brw->vs.state_offset +
+			offsetof(struct brw_vs_unit_state, thread0),
+			brw->vs.prog_offset +
+			(vs->thread0.grf_reg_count << 1)) >> 6;
+
    vs->thread0.grf_reg_count = ALIGN(brw->vs.prog_data->total_grf, 16) / 16 - 1;
    vs->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
    /* Choosing multiple program flow means that we may get 2-vertex threads,
@@ -152,13 +158,6 @@ brw_prepare_vs_unit(struct brw_context *brw)
     */
    vs->vs6.vs_enable = 1;
 
-   /* Emit VS program relocation */
-   drm_intel_bo_emit_reloc(intel->batch.bo, (brw->vs.state_offset +
-					     offsetof(struct brw_vs_unit_state,
-						      thread0)),
-			   brw->vs.prog_bo, vs->thread0.grf_reg_count << 1,
-			   I915_GEM_DOMAIN_INSTRUCTION, 0);
-
    brw->state.dirty.cache |= CACHE_NEW_VS_UNIT;
 }
 
@@ -166,6 +165,7 @@ const struct brw_tracked_state brw_vs_unit = {
    .dirty = {
       .mesa  = _NEW_TRANSFORM,
       .brw   = (BRW_NEW_BATCH |
+		BRW_NEW_PROGRAM_CACHE |
 		BRW_NEW_CURBE_OFFSETS |
                 BRW_NEW_NR_VS_SURFACES |
 		BRW_NEW_URB_FENCE),
diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c
index 236c4d2..0f73148 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -69,14 +69,8 @@ static void brw_destroy_context( struct intel_context *intel )
    ralloc_free(brw->wm.compile_data);
 
    dri_bo_release(&brw->curbe.curbe_bo);
-   dri_bo_release(&brw->vs.prog_bo);
    dri_bo_release(&brw->vs.const_bo);
-   dri_bo_release(&brw->gs.prog_bo);
-   dri_bo_release(&brw->clip.prog_bo);
-   dri_bo_release(&brw->sf.prog_bo);
-   dri_bo_release(&brw->wm.prog_bo);
    dri_bo_release(&brw->wm.const_bo);
-   dri_bo_release(&brw->cc.prog_bo);
 
    free(brw->curbe.last_buf);
    free(brw->curbe.next_buf);
@@ -125,6 +119,12 @@ static void brw_new_batch( struct intel_context *intel )
    brw->state.dirty.brw |= BRW_NEW_CONTEXT | BRW_NEW_BATCH;
 
    brw->vb.nr_current_buffers = 0;
+
+   /* Mark that the current program cache BO has been used by the GPU.
+    * It will be reallocated if we need to put new programs in for the
+    * next batch.
+    */
+   brw->cache.bo_used_by_gpu = true;
 }
 
 static void brw_invalidate_state( struct intel_context *intel, GLuint new_state )
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 1aebd12..f1c9985 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -273,12 +273,11 @@ bool do_wm_prog(struct brw_context *brw,
     */
    program = brw_get_program(&c->func, &program_size);
 
-   drm_intel_bo_unreference(brw->wm.prog_bo);
-   brw->wm.prog_bo = brw_upload_cache(&brw->cache, BRW_WM_PROG,
-				      &c->key, sizeof(c->key),
-				      program, program_size,
-				      &c->prog_data, sizeof(c->prog_data),
-				      &brw->wm.prog_data);
+   brw_upload_cache(&brw->cache, BRW_WM_PROG,
+		    &c->key, sizeof(c->key),
+		    program, program_size,
+		    &c->prog_data, sizeof(c->prog_data),
+		    &brw->wm.prog_offset, &brw->wm.prog_data);
 
    return true;
 }
@@ -477,13 +476,9 @@ static void brw_prepare_wm_prog(struct brw_context *brw)
 
    brw_wm_populate_key(brw, &key);
 
-   /* Make an early check for the key.
-    */
-   drm_intel_bo_unreference(brw->wm.prog_bo);
-   brw->wm.prog_bo = brw_search_cache(&brw->cache, BRW_WM_PROG,
-				      &key, sizeof(key),
-				      &brw->wm.prog_data);
-   if (brw->wm.prog_bo == NULL) {
+   if (!brw_search_cache(&brw->cache, BRW_WM_PROG,
+			 &key, sizeof(key),
+			 &brw->wm.prog_offset, &brw->wm.prog_data)) {
       bool success = do_wm_prog(brw, ctx->Shader.CurrentFragmentProgram, fp,
 				&key);
       assert(success);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index ef98f81..506e2bd 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -90,13 +90,25 @@ brw_prepare_wm_unit(struct brw_context *brw)
 	     brw->wm.prog_data->first_curbe_grf_16);
    }
 
-   /* CACHE_NEW_WM_PROG */
+   /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_WM_PROG */
    wm->thread0.grf_reg_count = brw->wm.prog_data->reg_blocks;
    wm->wm9.grf_reg_count_2 = brw->wm.prog_data->reg_blocks_16;
-   wm->thread0.kernel_start_pointer = brw->wm.prog_bo->offset >> 6; /* reloc */
-   /* reloc */
-   wm->wm9.kernel_start_pointer_2 = (brw->wm.prog_bo->offset +
-				     brw->wm.prog_data->prog_offset_16) >> 6;
+
+   wm->thread0.kernel_start_pointer =
+      brw_program_reloc(brw,
+			brw->wm.state_offset +
+			offsetof(struct brw_wm_unit_state, thread0),
+			brw->wm.prog_offset +
+			(wm->thread0.grf_reg_count << 1)) >> 6;
+
+   wm->wm9.kernel_start_pointer_2 =
+      brw_program_reloc(brw,
+			brw->wm.state_offset +
+			offsetof(struct brw_wm_unit_state, wm9),
+			brw->wm.prog_offset +
+			brw->wm.prog_data->prog_offset_16 +
+			(wm->wm9.grf_reg_count_2 << 1)) >> 6;
+
    wm->thread1.depth_coef_urb_read_offset = 1;
    wm->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
 
@@ -214,23 +226,6 @@ brw_prepare_wm_unit(struct brw_context *brw)
    if (unlikely(INTEL_DEBUG & DEBUG_STATS) || intel->stats_wm)
       wm->wm4.stats_enable = 1;
 
-   /* Emit WM program relocation */
-   drm_intel_bo_emit_reloc(intel->batch.bo,
-			   brw->wm.state_offset +
-			   offsetof(struct brw_wm_unit_state, thread0),
-			   brw->wm.prog_bo, wm->thread0.grf_reg_count << 1,
-			   I915_GEM_DOMAIN_INSTRUCTION, 0);
-
-   if (brw->wm.prog_data->prog_offset_16) {
-      drm_intel_bo_emit_reloc(intel->batch.bo,
-			      brw->wm.state_offset +
-			      offsetof(struct brw_wm_unit_state, wm9),
-			      brw->wm.prog_bo,
-			      ((wm->wm9.grf_reg_count_2 << 1) +
-			       brw->wm.prog_data->prog_offset_16),
-			      I915_GEM_DOMAIN_INSTRUCTION, 0);
-   }
-
    /* Emit scratch space relocation */
    if (brw->wm.prog_data->total_scratch != 0) {
       drm_intel_bo_emit_reloc(intel->batch.bo,
@@ -265,6 +260,7 @@ const struct brw_tracked_state brw_wm_unit = {
 	       _NEW_BUFFERS),
 
       .brw = (BRW_NEW_BATCH |
+	      BRW_NEW_PROGRAM_CACHE |
 	      BRW_NEW_FRAGMENT_PROGRAM |
 	      BRW_NEW_CURBE_OFFSETS |
 	      BRW_NEW_NR_WM_SURFACES),
diff --git a/src/mesa/drivers/dri/i965/gen6_gs_state.c b/src/mesa/drivers/dri/i965/gen6_gs_state.c
index c1d0a73..e73e782 100644
--- a/src/mesa/drivers/dri/i965/gen6_gs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_gs_state.c
@@ -45,7 +45,7 @@ upload_gs_state(struct brw_context *brw)
    ADVANCE_BATCH();
 
    // GS should never be used on Gen6.  Disable it.
-   assert(brw->gs.prog_bo == NULL);
+   assert(!brw->gs.prog_active);
    BEGIN_BATCH(7);
    OUT_BATCH(_3DSTATE_GS << 16 | (7 - 2));
    OUT_BATCH(0); /* prog_bo */
diff --git a/src/mesa/drivers/dri/i965/gen6_urb.c b/src/mesa/drivers/dri/i965/gen6_urb.c
index 62645a6..b410511 100644
--- a/src/mesa/drivers/dri/i965/gen6_urb.c
+++ b/src/mesa/drivers/dri/i965/gen6_urb.c
@@ -64,7 +64,7 @@ upload_urb(struct brw_context *brw)
    assert(brw->urb.nr_vs_entries % 4 == 0);
    assert(brw->urb.nr_gs_entries % 4 == 0);
    /* GS requirement */
-   assert(!brw->gs.prog_bo || brw->urb.vs_size < 5);
+   assert(!brw->gs.prog_active || brw->urb.vs_size < 5);
 
    BEGIN_BATCH(3);
    OUT_BATCH(_3DSTATE_URB << 16 | (3 - 2));
diff --git a/src/mesa/drivers/dri/i965/gen6_vs_state.c b/src/mesa/drivers/dri/i965/gen6_vs_state.c
index b46368e..7838a91 100644
--- a/src/mesa/drivers/dri/i965/gen6_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_vs_state.c
@@ -147,7 +147,7 @@ upload_vs_state(struct brw_context *brw)
 
    BEGIN_BATCH(6);
    OUT_BATCH(_3DSTATE_VS << 16 | (6 - 2));
-   OUT_RELOC(brw->vs.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
+   OUT_BATCH(brw->vs.prog_offset);
    OUT_BATCH((0 << GEN6_VS_SAMPLER_COUNT_SHIFT) |
 	     GEN6_VS_FLOATING_POINT_MODE_ALT |
 	     (brw->vs.nr_surfaces << GEN6_VS_BINDING_TABLE_ENTRY_COUNT_SHIFT));
diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index 43e651d..024a1d8 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -183,7 +183,7 @@ upload_wm_state(struct brw_context *brw)
 
    BEGIN_BATCH(9);
    OUT_BATCH(_3DSTATE_WM << 16 | (9 - 2));
-   OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
+   OUT_BATCH(brw->wm.prog_offset);
    OUT_BATCH(dw2);
    if (brw->wm.prog_data->total_scratch) {
       OUT_RELOC(brw->wm.scratch_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
@@ -195,12 +195,8 @@ upload_wm_state(struct brw_context *brw)
    OUT_BATCH(dw5);
    OUT_BATCH(dw6);
    OUT_BATCH(0); /* kernel 1 pointer */
-   if (brw->wm.prog_data->prog_offset_16) {
-      OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
-		brw->wm.prog_data->prog_offset_16);
-   } else {
-      OUT_BATCH(0); /* kernel 2 pointer */
-   }
+   /* kernel 2 pointer */
+   OUT_BATCH(brw->wm.prog_offset + brw->wm.prog_data->prog_offset_16);
    ADVANCE_BATCH();
 }
 
diff --git a/src/mesa/drivers/dri/i965/gen7_disable.c b/src/mesa/drivers/dri/i965/gen7_disable.c
index 4e94617..a44d315 100644
--- a/src/mesa/drivers/dri/i965/gen7_disable.c
+++ b/src/mesa/drivers/dri/i965/gen7_disable.c
@@ -31,7 +31,7 @@ disable_stages(struct brw_context *brw)
 {
    struct intel_context *intel = &brw->intel;
 
-   assert(brw->gs.prog_bo == NULL);
+   assert(!brw->gs.prog_active);
 
    /* Disable the Geometry Shader (GS) Unit */
    BEGIN_BATCH(7);
diff --git a/src/mesa/drivers/dri/i965/gen7_urb.c b/src/mesa/drivers/dri/i965/gen7_urb.c
index 3a61469..b36d780 100644
--- a/src/mesa/drivers/dri/i965/gen7_urb.c
+++ b/src/mesa/drivers/dri/i965/gen7_urb.c
@@ -78,7 +78,7 @@ upload_urb(struct brw_context *brw)
    assert(brw->urb.nr_vs_entries % 8 == 0);
    assert(brw->urb.nr_gs_entries % 8 == 0);
    /* GS requirement */
-   assert(!brw->gs.prog_bo);
+   assert(brw->gs.prog_active);
 
    BEGIN_BATCH(2);
    OUT_BATCH(_3DSTATE_PUSH_CONSTANT_ALLOC_VS << 16 | (2 - 2));
diff --git a/src/mesa/drivers/dri/i965/gen7_vs_state.c b/src/mesa/drivers/dri/i965/gen7_vs_state.c
index ae7a1d6..0fad3d2 100644
--- a/src/mesa/drivers/dri/i965/gen7_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_vs_state.c
@@ -67,7 +67,7 @@ upload_vs_state(struct brw_context *brw)
 
    BEGIN_BATCH(6);
    OUT_BATCH(_3DSTATE_VS << 16 | (6 - 2));
-   OUT_RELOC(brw->vs.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
+   OUT_BATCH(brw->vs.prog_offset);
    OUT_BATCH((0 << GEN6_VS_SAMPLER_COUNT_SHIFT) |
 	     GEN6_VS_FLOATING_POINT_MODE_ALT |
 	     (brw->vs.nr_surfaces << GEN6_VS_BINDING_TABLE_ENTRY_COUNT_SHIFT));
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_state.c b/src/mesa/drivers/dri/i965/gen7_wm_state.c
index 6a64eb8..ac6ba2f 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_state.c
@@ -227,18 +227,13 @@ upload_ps_state(struct brw_context *brw)
 
    BEGIN_BATCH(8);
    OUT_BATCH(_3DSTATE_PS << 16 | (8 - 2));
-   OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
+   OUT_BATCH(brw->wm.prog_offset);
    OUT_BATCH(dw2);
    OUT_BATCH(0); /* scratch space base offset */
    OUT_BATCH(dw4);
    OUT_BATCH(dw5);
    OUT_BATCH(0); /* kernel 1 pointer */
-   if (brw->wm.prog_data->prog_offset_16) {
-      OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
-	        brw->wm.prog_data->prog_offset_16);
-   } else {
-      OUT_BATCH(0); /* kernel 2 pointer */
-   }
+   OUT_BATCH(brw->wm.prog_offset + brw->wm.prog_data->prog_offset_16);
    ADVANCE_BATCH();
 }
 
commit 962dab948609c97c1c01fde6a27e19307948d302
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jun 14 15:48:24 2011 -0700

    i965: Only flag the new-batch related state as dirty at new batch time.
    
    This was debug code from the initial import of the driver.  No
    statistically significant performance difference on cairo-gl or
    nexuiz (n=6).

diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c
index 69650e1..236c4d2 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -122,11 +122,7 @@ static void brw_new_batch( struct intel_context *intel )
     * This is probably not as severe as on 915, since almost all of our state
     * is just in referenced buffers.
     */
-   brw->state.dirty.brw |= BRW_NEW_CONTEXT;
-
-   brw->state.dirty.mesa |= ~0;
-   brw->state.dirty.brw |= ~0;
-   brw->state.dirty.cache |= ~0;
+   brw->state.dirty.brw |= BRW_NEW_CONTEXT | BRW_NEW_BATCH;
 
    brw->vb.nr_current_buffers = 0;
 }
commit 6f998b58bc61f2507cd53204d7567299379c42ca
Author: Eric Anholt <eric at anholt.net>
Date:   Sat Jun 18 15:59:00 2011 -0700

    mesa: Fix render-to-texture regression.
    
    Accidentally introduced in fc8c4a3a7b92a1134cd3a9312063abba9e14b0fe.
    Fixes fbo-drawbuffers-maxtargets and friends.

diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 07853e0..8cc3fd4 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -1556,7 +1556,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
    GLuint i;
    ASSERT(ctx->Driver.RenderTexture);
 
-   if (is_winsys_fbo(fb));
+   if (is_winsys_fbo(fb))
       return; /* can't render to texture with winsys framebuffers */
 
    for (i = 0; i < BUFFER_COUNT; i++) {
@@ -1576,7 +1576,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
 static void
 check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
 {
-   if (is_winsys_fbo(fb));
+   if (is_winsys_fbo(fb))
       return; /* can't render to texture with winsys framebuffers */
 
    if (ctx->Driver.FinishRenderTexture) {
commit 001e07144332203bb30993eed4181b0e411a18be
Author: Eric Anholt <eric at anholt.net>
Date:   Wed May 25 16:37:09 2011 -0700

    mesa: Flag _NEW_BUFFERS when unbinding an attachment on glDeleteTextures.
    
    The _ColorDrawBuffers[] wouldn't get updated despite us having updated
    what it depends on (Attachments[]->Renderbuffer).  Other callers of
    _mesa_remove_attachment are already flagging _NEW_BUFFERS for other
    reasons.  The specific bug report that led to this fix (and
    the fbo-finish-deleted testcase) was fixed by
    23b6f9606dc247488835745668b3686218612536, though.
    
    Reviewed-by: Brian Paul <brianp at vmware.com>

diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index fdf1281..565a3a2 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -879,6 +879,8 @@ unbind_texobj_from_fbo(struct gl_context *ctx,
          for (j = 0; j < BUFFER_COUNT; j++) {
             if (fb->Attachment[j].Type == GL_TEXTURE &&
                 fb->Attachment[j].Texture == texObj) {
+	       /* Vertices are already flushed by _mesa_DeleteTextures */
+	       ctx->NewState |= _NEW_BUFFERS;
                _mesa_remove_attachment(ctx, fb->Attachment + j);         
             }
          }
commit a5a36d9b158a317daa1cf10a6b6ed2bed6b22750
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jun 10 20:19:01 2011 -0700

    i965: Don't try to continue space before the start of a VBO.
    
    This loop is trying to see if all the buffers to be uploaded happen to
    be the same increment from the start of the 3DSTATE_VERTEX_BUFFERS
    currently loaded in the hardware.  However, we might be at a smaller
    offset than the previous set of VERTEX_BUFFERS, so we can't reuse
    because that packet made the first entry be its starting offset (you
    can't access outside the given bounds).
    
    Fixes piglit ARB_vertex_buffer_object/elements-negative-offset.

diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 13d3aa7..32a1d29 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -500,6 +500,8 @@ static void brw_prepare_vertices(struct brw_context *brw)
 	    break;
 
 	 d = brw->vb.buffers[i].offset - brw->vb.current_buffers[i].offset;
+	 if (d < 0)
+	    break;
 	 if (i == 0)
 	    delta = d / brw->vb.current_buffers[i].stride;
 	 if (delta * brw->vb.current_buffers[i].stride != d)
commit 5c2c60175d0e5da9b0e9688538b84dedf05107de
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Jun 10 15:07:59 2011 -0700

    i965: Add missing state flag for vertex elements on current VS program.
    
    Fixes a missing 3DSTATE_VERTEX_ELEMENTS on topogun.trace.

diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index c6e5395..13d3aa7 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -278,6 +278,7 @@ static void brw_prepare_vertices(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->intel.ctx;
    struct intel_context *intel = intel_context(ctx);
+   /* CACHE_NEW_VS_PROG */
    GLbitfield vs_inputs = brw->vs.prog_data->inputs_read;
    const unsigned char *ptr = NULL;
    GLuint interleaved = 0, total_size = 0;
@@ -646,7 +647,7 @@ const struct brw_tracked_state brw_vertices = {
    .dirty = {
       .mesa = 0,
       .brw = BRW_NEW_BATCH | BRW_NEW_VERTICES,
-      .cache = 0,
+      .cache = CACHE_NEW_VS_PROG,
    },
    .prepare = brw_prepare_vertices,
    .emit = brw_emit_vertices,
commit a4f4e24f0756f496cd5fa807ea70bcbee98a3134
Author: Marek Olšák <maraeo at gmail.com>
Date:   Sat Jun 18 18:58:57 2011 +0200

    r300g: rename AOS -> VARRAYS

diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index fe7fa17..7cf0aba 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -175,8 +175,8 @@ static void r300_split_index_bias(struct r300_context *r300, int index_bias,
 enum r300_prepare_flags {
     PREP_EMIT_STATES    = (1 << 0), /* call emit_dirty_state and friends? */
     PREP_VALIDATE_VBOS  = (1 << 1), /* validate VBOs? */
-    PREP_EMIT_AOS       = (1 << 2), /* call emit_vertex_arrays? */
-    PREP_EMIT_AOS_SWTCL = (1 << 3), /* call emit_vertex_arrays_swtcl? */
+    PREP_EMIT_VARRAYS       = (1 << 2), /* call emit_vertex_arrays? */
+    PREP_EMIT_VARRAYS_SWTCL = (1 << 3), /* call emit_vertex_arrays_swtcl? */
     PREP_INDEXED        = (1 << 4)  /* is this draw_elements? */
 };
 
@@ -194,8 +194,8 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300,
 {
     boolean flushed        = FALSE;
     boolean emit_states    = flags & PREP_EMIT_STATES;
-    boolean emit_vertex_arrays       = flags & PREP_EMIT_AOS;
-    boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL;
+    boolean emit_vertex_arrays       = flags & PREP_EMIT_VARRAYS;
+    boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_VARRAYS_SWTCL;
 
     /* Add dirty state, index offset, and AOS. */
     if (emit_states)
@@ -238,8 +238,8 @@ static boolean r300_emit_states(struct r300_context *r300,
                                 int index_bias, int instance_id)
 {
     boolean emit_states    = flags & PREP_EMIT_STATES;
-    boolean emit_vertex_arrays       = flags & PREP_EMIT_AOS;
-    boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL;
+    boolean emit_vertex_arrays       = flags & PREP_EMIT_VARRAYS;
+    boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_VARRAYS_SWTCL;
     boolean indexed        = flags & PREP_INDEXED;
     boolean validate_vbos  = flags & PREP_VALIDATE_VBOS;
 
@@ -541,7 +541,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
 
     /* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
     if (!r300_prepare_for_rendering(r300,
-            PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
+            PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
             PREP_INDEXED, NULL, 2+count_dwords, 0, info->index_bias, -1))
         return;
 
@@ -663,7 +663,7 @@ static void r300_draw_elements(struct r300_context *r300,
 
     /* 19 dwords for emit_draw_elements. Give up if the function fails. */
     if (!r300_prepare_for_rendering(r300,
-            PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
+            PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
             PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias,
             instance_id))
         goto done;
@@ -690,7 +690,7 @@ static void r300_draw_elements(struct r300_context *r300,
             /* 15 dwords for emit_draw_elements */
             if (count) {
                 if (!r300_prepare_for_rendering(r300,
-                        PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
+                        PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS | PREP_INDEXED,
                         indexBuffer, 19, buffer_offset, info->index_bias,
                         instance_id))
                     goto done;
@@ -716,7 +716,7 @@ static void r300_draw_arrays(struct r300_context *r300,
 
     /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
     if (!r300_prepare_for_rendering(r300,
-                                    PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
+                                    PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS,
                                     NULL, 9, start, 0, instance_id))
         return;
 
@@ -737,7 +737,7 @@ static void r300_draw_arrays(struct r300_context *r300,
             /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
             if (count) {
                 if (!r300_prepare_for_rendering(r300,
-                                                PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
+                                                PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS, NULL, 9,
                                                 start, 0, instance_id))
                     return;
             }
@@ -844,7 +844,7 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
     r300_update_derived_state(r300);
 
     r300_reserve_cs_dwords(r300,
-            PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL |
+            PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL |
             (indexed ? PREP_INDEXED : 0),
             indexed ? 256 : 6);
 
@@ -1026,12 +1026,12 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
 
     if (r300->draw_first_emitted) {
         if (!r300_prepare_for_rendering(r300,
-                PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL,
+                PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL,
                 NULL, dwords, 0, 0, -1))
             return;
     } else {
         if (!r300_emit_states(r300,
-                PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL,
+                PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL,
                 NULL, 0, 0, -1))
             return;
     }
@@ -1066,12 +1066,12 @@ static void r300_render_draw_elements(struct vbuf_render* render,
 
     if (r300->draw_first_emitted) {
         if (!r300_prepare_for_rendering(r300,
-                PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
+                PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED,
                 NULL, 256, 0, 0, -1))
             return;
     } else {
         if (!r300_emit_states(r300,
-                PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
+                PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED,
                 NULL, 0, 0, -1))
             return;
     }
@@ -1108,7 +1108,7 @@ static void r300_render_draw_elements(struct vbuf_render* render,
 
         if (count) {
             if (!r300_prepare_for_rendering(r300,
-                    PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
+                    PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED,
                     NULL, 256, 0, 0, -1))
                 return;
 
commit 7df7eaf8453bbc7bfd8d23b7808c92d30c62bf55
Author: Marek Olšák <maraeo at gmail.com>
Date:   Fri Jun 17 19:21:59 2011 +0200

    r300g: fix handling PREP_* options
    
    This should fix rendering >65532 vertices using draw_arrays on r300-r400.
    
    NOTE: This is a candidate for the 7.10 branch.

diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index d9399d7..fe7fa17 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -193,23 +193,22 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300,
                                       unsigned cs_dwords)
 {
     boolean flushed        = FALSE;
-    boolean first_draw     = flags & PREP_EMIT_STATES;
+    boolean emit_states    = flags & PREP_EMIT_STATES;
     boolean emit_vertex_arrays       = flags & PREP_EMIT_AOS;
     boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL;
 
     /* Add dirty state, index offset, and AOS. */
-    if (first_draw) {
+    if (emit_states)
         cs_dwords += r300_get_num_dirty_dwords(r300);
 
-        if (r300->screen->caps.is_r500)
-            cs_dwords += 2; /* emit_index_offset */
+    if (r300->screen->caps.is_r500)
+        cs_dwords += 2; /* emit_index_offset */
 
-        if (emit_vertex_arrays)
-            cs_dwords += 55; /* emit_vertex_arrays */
+    if (emit_vertex_arrays)
+        cs_dwords += 55; /* emit_vertex_arrays */
 
-        if (emit_vertex_arrays_swtcl)
-            cs_dwords += 7; /* emit_vertex_arrays_swtcl */
-    }
+    if (emit_vertex_arrays_swtcl)
+        cs_dwords += 7; /* emit_vertex_arrays_swtcl */
 
     cs_dwords += r300_get_num_cs_end_dwords(r300);
 
@@ -238,46 +237,48 @@ static boolean r300_emit_states(struct r300_context *r300,
                                 int buffer_offset,
                                 int index_bias, int instance_id)
 {
-    boolean first_draw     = flags & PREP_EMIT_STATES;
+    boolean emit_states    = flags & PREP_EMIT_STATES;
     boolean emit_vertex_arrays       = flags & PREP_EMIT_AOS;
     boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL;
     boolean indexed        = flags & PREP_INDEXED;
     boolean validate_vbos  = flags & PREP_VALIDATE_VBOS;
 
     /* Validate buffers and emit dirty state if needed. */
-    if (first_draw) {
+    if (emit_states || (emit_vertex_arrays && validate_vbos)) {
         if (!r300_emit_buffer_validate(r300, validate_vbos,
                                        index_buffer)) {
            fprintf(stderr, "r300: CS space validation failed. "
                    "(not enough memory?) Skipping rendering.\n");
            return FALSE;
         }
+    }
 
+    if (emit_states)
         r300_emit_dirty_state(r300);
-        if (r300->screen->caps.is_r500) {
-            if (r300->screen->caps.has_tcl)
-                r500_emit_index_bias(r300, index_bias);
-            else
-                r500_emit_index_bias(r300, 0);
-        }
 
-        if (emit_vertex_arrays &&
-            (r300->vertex_arrays_dirty ||
-             r300->vertex_arrays_indexed != indexed ||
-             r300->vertex_arrays_offset != buffer_offset ||
-             r300->vertex_arrays_instance_id != instance_id)) {
-            r300_emit_vertex_arrays(r300, buffer_offset, indexed, instance_id);
-
-            r300->vertex_arrays_dirty = FALSE;
-            r300->vertex_arrays_indexed = indexed;
-            r300->vertex_arrays_offset = buffer_offset;
-            r300->vertex_arrays_instance_id = instance_id;
-        }
+    if (r300->screen->caps.is_r500) {
+        if (r300->screen->caps.has_tcl)
+            r500_emit_index_bias(r300, index_bias);
+        else
+            r500_emit_index_bias(r300, 0);
+    }
 
-        if (emit_vertex_arrays_swtcl)
-            r300_emit_vertex_arrays_swtcl(r300, indexed);
+    if (emit_vertex_arrays &&
+        (r300->vertex_arrays_dirty ||
+         r300->vertex_arrays_indexed != indexed ||
+         r300->vertex_arrays_offset != buffer_offset ||
+         r300->vertex_arrays_instance_id != instance_id)) {
+        r300_emit_vertex_arrays(r300, buffer_offset, indexed, instance_id);
+
+        r300->vertex_arrays_dirty = FALSE;
+        r300->vertex_arrays_indexed = indexed;
+        r300->vertex_arrays_offset = buffer_offset;
+        r300->vertex_arrays_instance_id = instance_id;
     }
 
+    if (emit_vertex_arrays_swtcl)
+        r300_emit_vertex_arrays_swtcl(r300, indexed);
+
     return TRUE;
 }
 
commit 2fe39b46e73aea37152777fe11d489e0b1bc3f92
Author: Vadim Girlin <vadimgirlin at gmail.com>
Date:   Fri Jun 17 23:02:01 2011 +0400

    r600g: fix LIT to handle src==dst properly
    
    Current LIT implementation uses dst components for storing temp
    results, possibly overwriting still needed values (depends on the
    swizzles).
    This patch uses temp reg for one of such cases (found in etqw) and
    fixes "LIT R.z, R.xyzz".
    
    Tested on evergreen. Fixes some etqw-demo rendering glitches when
    "Lighting" is set to "High" in the settings.
    
    Signed-off-by: Vadim Girlin <vadimgirlin at gmail.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 0995dd5..0268108 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -1366,7 +1366,9 @@ static int tgsi_lit(struct r600_shader_ctx *ctx)
 			memset(&alu, 0, sizeof(struct r600_bc_alu));
 			alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED);
 			r600_bc_src(&alu.src[0], &ctx->src[0], 1);
-			tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst);
+			alu.dst.sel = ctx->temp_reg;
+			alu.dst.chan = 2;
+			alu.dst.write = 1;
 			alu.last = 1;
 			r = r600_bc_add_alu(ctx->bc, &alu);
 			if (r)
commit 8ab1c5328b12e8b075f62599a84672024aaf2982
Author: Vadim Girlin <vadimgirlin at gmail.com>
Date:   Fri Jun 17 23:02:00 2011 +0400

    r600g: fix RSQ to use abs value of operand on evergreen
    
    fixes https://bugs.freedesktop.org/show_bug.cgi?id=36917
    
    Signed-off-by: Vadim Girlin <vadimgirlin at gmail.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index b8a86b0..0995dd5 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -3266,7 +3266,7 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = {
 	{TGSI_OPCODE_MOV,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2},
 	{TGSI_OPCODE_LIT,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_lit},
 	{TGSI_OPCODE_RCP,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, tgsi_trans_srcx_replicate},
-	{TGSI_OPCODE_RSQ,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans_srcx_replicate},
+	{TGSI_OPCODE_RSQ,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_rsq},
 	{TGSI_OPCODE_EXP,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_exp},
 	{TGSI_OPCODE_LOG,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_log},
 	{TGSI_OPCODE_MUL,	0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2},
commit a916d4279a2c8daac832f77b84aff66f33b590a3
Author: Vadim Girlin <vadimgirlin at gmail.com>
Date:   Fri Jun 17 23:01:59 2011 +0400

    r600g: fix source box in r600_resource_copy_region
    
    Source box needs to be adjusted for blitting from compressed formats.
    
    fixes https://bugs.freedesktop.org/show_bug.cgi?id=35434
    
    Signed-off-by: Vadim Girlin <vadimgirlin at gmail.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index 043c875..e858ea2 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -294,6 +294,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
 {
 	struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src;
 	struct texture_orig_info orig_info[2];
+	struct pipe_box sbox, *psbox;
 	boolean restore_orig[2];
 
 	/* Fallback for buffers. */
@@ -311,7 +312,15 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
 	if (util_format_is_compressed(src->format)) {
 		r600_compressed_to_blittable(src, src_level, &orig_info[0]);
 		restore_orig[0] = TRUE;
-	}
+		sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x);
+		sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y);
+		sbox.z = src_box->z;
+		sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width);
+		sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height);
+		sbox.depth = src_box->depth;
+		psbox=&sbox;
+	} else
+		psbox=src_box;
 
 	if (util_format_is_compressed(dst->format)) {
 		r600_compressed_to_blittable(dst, dst_level, &orig_info[1]);
@@ -322,7 +331,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
 	}
 
 	r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
-			    src, src_level, src_box);
+			    src, src_level, psbox);
 
 	if (restore_orig[0])
 		r600_reset_blittable_to_compressed(src, src_level, &orig_info[0]);
commit 753660780a84187043d0dc4b0e0f449786862182
Author: Brian Paul <brianp at vmware.com>
Date:   Fri Jun 17 13:43:06 2011 -0600

    mesa: allow depth texture arrays
    
    The GL_EXT_texture_array spec allows this (Section 3.8.1).
    Fixes failing piglit fbo-depth-array test.
    
    NOTE: This is a candidate for the 7.10 branch.

diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 0827cb8..40398a8 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -1685,11 +1685,15 @@ texture_error_check( struct gl_context *ctx,
 
    /* additional checks for depth textures */
    if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
-      /* Only 1D, 2D and rectangular textures supported, not 3D or cubes */
+      /* Only 1D, 2D, rect and array textures supported, not 3D or cubes */
       if (target != GL_TEXTURE_1D &&
           target != GL_PROXY_TEXTURE_1D &&
           target != GL_TEXTURE_2D &&
           target != GL_PROXY_TEXTURE_2D &&
+          target != GL_TEXTURE_1D_ARRAY &&
+          target != GL_PROXY_TEXTURE_1D_ARRAY &&
+          target != GL_TEXTURE_2D_ARRAY &&
+          target != GL_PROXY_TEXTURE_2D_ARRAY &&
           target != GL_TEXTURE_RECTANGLE_ARB &&
           target != GL_PROXY_TEXTURE_RECTANGLE_ARB) {
          if (!isProxy)
commit da5c852d636dfeffeb792c78b882c80c91ab6a89
Author: Brian Paul <brianp at vmware.com>
Date:   Fri Jun 17 13:28:38 2011 -0600

    st/mesa: remove unneeded test for GL_TRUE

diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 99f486b..45e4766 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -1203,7 +1203,7 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
     * that in advance.  Specify potential render target flags now.
     */
    bindings = PIPE_BIND_SAMPLER_VIEW;
-   if (renderable == GL_TRUE) {
+   if (renderable) {
       if (_mesa_is_depth_or_stencil_format(internalFormat))
 	 bindings |= PIPE_BIND_DEPTH_STENCIL;
       else
commit 15750d89b9d3592032814faf7dd885c9dd6d686b
Author: Brian Paul <brianp at vmware.com>
Date:   Fri Jun 17 13:25:31 2011 -0600

    st/mesa: remove redundant _mesa_is_depth_format() call
    
    The _mesa_is_depth_or_stencil_format() call covers all depth
    format cases too.

diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index d11308d..99f486b 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -1204,8 +1204,7 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
     */
    bindings = PIPE_BIND_SAMPLER_VIEW;
    if (renderable == GL_TRUE) {
-      if (_mesa_is_depth_format(internalFormat) ||
-	  _mesa_is_depth_or_stencil_format(internalFormat))
+      if (_mesa_is_depth_or_stencil_format(internalFormat))
 	 bindings |= PIPE_BIND_DEPTH_STENCIL;
       else
 	 bindings |= PIPE_BIND_RENDER_TARGET;
commit 3ea6fdfdf1a6aed5c924cfe52aa0d543c6d58aa3
Author: Brian Paul <brianp at vmware.com>
Date:   Fri Jun 17 13:23:16 2011 -0600

    st/mesa: remove trailing whitespace in st_format.c

diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index bd17448..d11308d 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -1108,7 +1108,7 @@ static struct format_mapping format_map[] = {
  * Return first supported format from the given list.
  */
 static enum pipe_format
-find_supported_format(struct pipe_screen *screen, 
+find_supported_format(struct pipe_screen *screen,
                       const enum pipe_format formats[],
                       enum pipe_texture_target target,
                       unsigned sample_count,
@@ -1207,7 +1207,7 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
       if (_mesa_is_depth_format(internalFormat) ||
 	  _mesa_is_depth_or_stencil_format(internalFormat))
 	 bindings |= PIPE_BIND_DEPTH_STENCIL;
-      else 
+      else
 	 bindings |= PIPE_BIND_RENDER_TARGET;
    }
 
commit befaab8fa12eb4f628e21ffa75e523ac5eb7fbc2
Author: Brian Paul <brianp at vmware.com>
Date:   Fri Jun 17 13:22:43 2011 -0600

    st/mesa: move comment for ChooseTextureFormat() to right place

diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 3583571..bd17448 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -1188,9 +1188,6 @@ st_choose_renderbuffer_format(struct pipe_screen *screen,
 }
 
 
-/**
- * Called via ctx->Driver.chooseTextureFormat().
- */
 gl_format
 st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
 				  GLenum format, GLenum type, GLboolean renderable)
@@ -1231,6 +1228,10 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
    return st_pipe_format_to_mesa_format(pFormat);
 }
 
+
+/**
+ * Called via ctx->Driver.ChooseTextureFormat().
+ */
 gl_format
 st_ChooseTextureFormat(struct gl_context *ctx, GLint internalFormat,
                        GLenum format, GLenum type)


More information about the Xquartz-changes mailing list