summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@fedoraproject.org>2008-05-10 05:25:47 +0000
committerDave Airlie <airlied@fedoraproject.org>2008-05-10 05:25:47 +0000
commitdf3a038c7ab6b913d89a324a58e407d108bf4e78 (patch)
treebffd368be8ceee81fbd1e1f6cd467fa52326d988
parent75c2c8ea2b573a42724e51b79627b9a1b9b52649 (diff)
downloadmesa-df3a038c7ab6b913d89a324a58e407d108bf4e78.tar.gz
mesa-df3a038c7ab6b913d89a324a58e407d108bf4e78.tar.xz
mesa-df3a038c7ab6b913d89a324a58e407d108bf4e78.zip
- Bring in a bunch of fixes from upstream, missing rs690 pci id,mesa-7_1-0_31_fc9
- DRI2 + modeset + 965 + compiz + alt-tab fixed.
-rw-r--r--mesa-7.1-bag-of-fixes.patch2054
-rw-r--r--mesa-7.1-f9-intel-and-radeon-fixes.patch784
-rw-r--r--mesa-7.1-fix-965-googleearth.patch38
-rw-r--r--mesa.spec10
4 files changed, 2060 insertions, 826 deletions
diff --git a/mesa-7.1-bag-of-fixes.patch b/mesa-7.1-bag-of-fixes.patch
new file mode 100644
index 0000000..f1caf69
--- /dev/null
+++ b/mesa-7.1-bag-of-fixes.patch
@@ -0,0 +1,2054 @@
+commit 81c4e373bd687983ced6cb632b8c9bd599c1ecd0
+Author: Dave Airlie <airlied@panoply-rh.(none)>
+Date: Tue May 6 18:52:47 2008 +1000
+
+ i965: fix googleearth in classic mode.
+
+ In classic mode googleearth triggered a case where vbos weren't getting accounted properly.
+ (cherry picked from commit 17adf04e5c1da72a51815f3fdb9de2f3a8149c1a)
+
+commit fbb82e911658b29b3961370e497011f9dd4b281f
+Author: Dave Airlie <airlied@redhat.com>
+Date: Fri May 9 13:51:37 2008 +1000
+
+ intel: use new mipmap generation hooks in driver.
+ (cherry picked from commit 0dbd5c864047ad2ad3d459493c9e82be57427f83)
+
+commit 9436f301bb06dabde75059b7e15d69ae37af2984
+Author: Dave Airlie <airlied@linux.ie>
+Date: Fri May 9 13:41:02 2008 +1000
+
+ swrast/dri: switch over users of generate_mipmap to new interface
+ (cherry picked from commit 86bd98c6aa0d1a8533699af911c7c40c549b3965)
+
+commit 69fef7f46a3285ca1786ba7e384eae3119dc3753
+Author: Brian <brian.paul@tungstengraphics.com>
+Date: Fri Feb 8 14:45:58 2008 -0700
+
+ Remove unused texunit parameter to ctx->Driver.GenerateMipmap()
+ (cherry picked from commit c3395f4473c8fdf75d04c0dd72e687bc8d8127a7)
+ (cherry picked from commit d4e1d85dba8ec4a37f68a284b5a2be15b4f2987a)
+
+commit b2f4ad6b373b44fed2cfa6e7528480df46af315c
+Author: Dave Airlie <airlied@linux.ie>
+Date: Fri May 9 13:33:06 2008 +1000
+
+ Added ctx->Driver.GenerateMipmap() driver hook
+ (cherry picked from commit 4c2f3dbca940f289e67248682b84a3516d5a3031)
+
+ Conflicts:
+
+ src/mesa/drivers/common/driverfuncs.c
+ (cherry picked from commit a638676473bd7bf2d47275ed2fd708e5b9d47e0b)
+
+commit 0fdb3fde63561e95c00482a660604ddd7c3d655d
+Author: Kristian Høgsberg <krh@redhat.com>
+Date: Thu May 8 19:48:32 2008 -0400
+
+ Add RS690M PCI ID.
+ (cherry picked from commit 990e010394a2685c1daeaef61cf4f7e2a0ba419e)
+
+commit ab134426b1645a536684ffe1294f1029b4954d00
+Author: Brian Paul <brian.paul@tungstengraphics.com>
+Date: Thu May 8 10:59:31 2008 -0600
+
+ disable debug printfs
+ (cherry picked from commit b4e75d6c41b2561ca86321fb775ca774c8af44eb)
+
+commit 2407499bc013e53d4c0936bed0622bdc758677b3
+Author: Brian Paul <brian.paul@tungstengraphics.com>
+Date: Thu May 8 08:39:30 2008 -0600
+
+ disable GL_DEPTH_TEST before glDrawPixels in case window has unrequested depth buffer
+ (cherry picked from commit 45668806567c0f31479c8bf9b1a85930cac70c5d)
+
+commit 9146fffba3e68d642c5712ec0bc414c3ac0e4d5a
+Author: Brian Paul <brian.paul@tungstengraphics.com>
+Date: Thu May 8 08:36:49 2008 -0600
+
+ call glutDestroyWindow()
+ (cherry picked from commit 6a3fac871104c5cf3cd1c6a7767ba66d10446475)
+
+commit e073db2739497c03674c006f1dab61a64755cb14
+Author: Brian Paul <brian.paul@tungstengraphics.com>
+Date: Wed May 7 18:51:44 2008 -0600
+
+ fix refcounting bugs in tnl/tex program caches
+ (cherry picked from commit 5b5c9315275752add1215dba0f86d5f5068d856b)
+
+commit 2f56de178297cb08e26b0e1c70d7beb1e0d4f841
+Author: Brian <brian.paul@tungstengraphics.com>
+Date: Tue May 6 23:08:51 2008 -0600
+
+ implement full reference counting for vertex/fragment programs
+
+ Use _mesa_reference_vert/fragprog() wherever we assign program pointers.
+ Fixes a memory corruption bug found with glean/api2 test.
+ (cherry picked from commit df43fb661b2030d9b833a42dd47b8d7bf58d73aa)
+
+commit 329f8ccddd4309aade2a53b633b32ac6c5e50f27
+Author: Xiang, Haihao <haihao.xiang@intel.com>
+Date: Thu May 8 11:52:57 2008 +0800
+
+ mesa: Call RENDER_FINISH on the zero pixel case.
+ (cherry picked from commit 9508293e0186ded3be212a377b1fe39d68070da7)
+
+commit fc35fb99411fc1bac92a7da9d90a16f28602623f
+Author: Dave Airlie <airlied@linux.ie>
+Date: Mon May 5 23:49:50 2008 +1000
+
+ r300: fix swtcl texrect path properly.
+
+ We really need to update the shader state so the texrect parameters work.
+
+ This should fix compiz looking crappy on rs480 and rs690
+ (cherry picked from commit 66a5562ce2906fbf5b96d1cee18f9a31a78c4360)
+ (cherry picked from commit a7016949f27f7612ffba7a4d0c5e6280cb3e66ba)
+
+commit 5344028569e7c5fa7349685923c9ecc319c86fc6
+Author: Dave Airlie <airlied@linux.ie>
+Date: Sat May 3 21:31:22 2008 +1000
+
+ r300: add R300_NO_TCL to allow testing of non-tcl on tcl cards
+ (cherry picked from commit 026ef8111a94f6449dfa5e5cc0ae91fca4e68c0c)
+ (cherry picked from commit 2f0a75f0040b0de339c78448844a7b18ab995c46)
+
+commit f232d553352fa8ace512564f371f623da4c08485
+Author: Markus Amsler <markus.amsler@oribi.org>
+Date: Fri May 2 01:58:18 2008 +0000
+
+ r300: Set correct VAP_CNTL per vertex program.
+ (cherry picked from commit acb47dee69a165f242d88f9eac60fc5646e33410)
+
+commit 135c59946a341e93f5e2a8f61a658d8c49ce2395
+Author: Brian Paul <brian.paul@tungstengraphics.com>
+Date: Thu May 1 14:59:34 2008 -0600
+
+ fix conversion of GLfloat display list IDs
+
+ Use floor() to convert to int (per Mark Kildard and the SI).
+ Also, change translate_id() to return a signed integer since we may be
+ offsetting from GL_LIST_BASE.
+ (cherry picked from commit 6e19f82c37191dabcdd882d0edac98a2ca9c11e4)
+
+commit d8dc7982bc38a1e28a123d5f63736bb8deea134c
+Author: Brian Paul <brian.paul@tungstengraphics.com>
+Date: Wed Apr 30 16:05:01 2008 -0600
+
+ Add support for GL_REPLACE_EXT texture env mode.
+
+ GL_REPLACE_EXT comes from the ancient GL_EXT_texture extension. Found an old demo that
+ actually uses it.
+ The values of the GL_REPLACE and GL_REPLACE_EXT tokens is different, unfortunately.
+ (cherry picked from commit 5f0fa82f68e3f4f7086ed6cf5616ef94820e19ee)
+
+commit 736cb42b9f6dc60ad83858bb6e244f5e9a0df3ef
+Author: Xiang, Haihao <haihao.xiang@intel.com>
+Date: Wed Apr 30 16:27:52 2008 +0800
+
+ intel: test cpp to ensure mipmap tree matches texture image.
+ (cherry picked from commit d12fa3511da23d8285f3ea1a51a1f328cdbb1462)
+
+commit 1bae58ce0dab2bc69b4467cae8cdc8a007c446ac
+Author: Brian Paul <brian.paul@tungstengraphics.com>
+Date: Tue Apr 29 15:02:46 2008 -0600
+
+ disable GL_TEXTURE_1D at end of frame to fix failed assertion
+ (cherry picked from commit aef4ca647d1d8275b1586a92485ea6c5bc8e950c)
+
+commit 2ec4728f9175e2184a2af009d7d2be1f191d35d9
+Author: Brian Paul <brian.paul@tungstengraphics.com>
+Date: Fri Apr 25 09:46:43 2008 -0600
+
+ mesa: adjust glBitmap coords by a small epsilon
+
+ Fixes problem with bitmaps jumping around by one pixel depending on window
+ size. The rasterpos is often X.9999 instead of X+1.
+ Run progs/redbook/drawf and resize window to check.
+
+ Cherry picked from gallium-0.1 branch
+ (cherry picked from commit 4e0e02ae684c0286599309ae166cfc716db940d7)
+
+commit 28b887a05543e67d0e40eb17502fcf590145022a
+Author: Ove Kaaven <ovek@arcticnet.no>
+Date: Tue Apr 29 22:14:05 2008 +0200
+
+ r200: fix state submission issue causing bogus textures (bug 15730)
+ (cherry picked from commit 4f474c7d1e1e6807af0f3db55f641fbd66be2e90)
+
+commit 52a964a87f5155bad582b2b48ff8ba8ca9669a69
+Author: Michel Dänzer <michel@tungstengraphics.com>
+Date: Tue Apr 29 18:43:28 2008 +0200
+
+ Change default of driconf "allow_large_textures" to announce hardware limits.
+
+ The previous default these days served mostly to cause artifical problems with
+ GLX compositing managers like compiz (see e.g.
+ http://bugs.freedesktop.org/show_bug.cgi?id=10501).
+ (cherry picked from commit acba9c1771d653126fd6f604cb80c050b9e8ffb3)
+
+commit 98b53ad38218a4392f0dc070fd425f9cc61fdfa7
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Apr 25 16:07:12 2008 -0700
+
+ [i965] short immediate values must be replicated to both halves of the dword
+
+ The 32-bit immediate value in the i965 instruction word must contain two
+ copies of any 16-bit constants. brw_imm_uw and brw_imm_w just needed to
+ copy the value into both halves of the immediate value instruction field.
+ (cherry picked from commit ca73488f48e3ee278f0185bb7dcc03d7bdedb62d)
+
+commit 5b77d659ef8d57b74b7ff2a8d1126808d9ee1de2
+Author: Pierre Beyssac <mesa-bugzilla@fasterix.frmug.org>
+Date: Thu Apr 24 16:29:34 2008 -0600
+
+ enable GL_EXT_multi_draw_arrays (see bug 15670)
+ (cherry picked from commit fddb0f6e4fa67f3d6940e10519560941b59f5a5e)
+
+commit 36de683cfa560c20ae7a068ed3906ccafc399b91
+Author: Xiang, Haihao <haihao.xiang@intel.com>
+Date: Tue Apr 22 16:25:23 2008 +0800
+
+ i965: fix DEPTH_TEXTURE_MODE (bug #14220)
+ (cherry picked from commit 6e620162a1b235ade227368b87fa993e844d7077)
+
+commit 7786e8a122717c1f68e943994ed99fda697f29dc
+Author: Zou Nan hai <nanhai.zou@intel.com>
+Date: Tue Apr 22 15:50:40 2008 +0800
+
+ [i965] This is to fix random crash in some maps of Ut2004 demo.
+ e.g. bridge of fate.
+ If vs output is big, driver may fall back to use 8 urb entries for vs,
+ unfortunally, for some unknown reason, if vs is working at 4x2 mode,
+ 8 entries is not enough, may lead to gpu hang.
+ (cherry picked from commit c9c64a100d5d0661fd672af040a68bd4e7292940)
+
+commit b557beb6572e5662a21375b6aa9e25df4fa4dc34
+Author: Xiang, Haihao <haihao.xiang@intel.com>
+Date: Tue Apr 22 11:11:42 2008 +0800
+
+ i965: save the offset of target buffer after last execution, not relocatee buffer.
+ (cherry picked from commit f61e51ee98a2f43ad61e98353eae2cd8dc8a272f)
+
+commit 96aff7d90e5404bb8b023fcae676c2de78829eb3
+Author: Xiang, Haihao <haihao.xiang@intel.com>
+Date: Mon Apr 21 17:34:00 2008 +0800
+
+ intel: fix an assertion failure. fix bug #15575
+ (cherry picked from commit 7c2a3fced8bbf0915ee4160c23b1752917c1e69d)
+
+commit e82b0a1a63d6438328d0821d271bbf9946e7a96c
+Author: Xiang, Haihao <haihao.xiang@intel.com>
+Date: Mon Apr 21 14:02:50 2008 +0800
+
+ i965: clear the PRESUMED_OFFSET flag from bo_req.hint, not bo_req.flags. fix #15574
+ (cherry picked from commit 33107357a1226b9218fac410a7502a981aac5cc5)
+
+commit 6c33450bfdb38592ea77dd2ff65d522b47bcaa41
+Author: Dave Airlie <airlied@panoply-rh.(none)>
+Date: Fri Apr 18 15:37:54 2008 +1000
+
+ i965: fixup depth buffer check
+ (cherry picked from commit 27e06a52342b94b4fb1d60a57c3bdaa2b30607cf)
+diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c
+index c2d40bd..b6bdbe4 100644
+--- a/progs/demos/shadowtex.c
++++ b/progs/demos/shadowtex.c
+@@ -658,6 +658,7 @@ Display(void)
+ glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ }
+
++ glDisable(GL_TEXTURE_1D);
+ glDisable(GL_TEXTURE_2D);
+ }
+
+diff --git a/progs/tests/fbotest2.c b/progs/tests/fbotest2.c
+index 18f2897..5283c7e 100644
+--- a/progs/tests/fbotest2.c
++++ b/progs/tests/fbotest2.c
+@@ -68,6 +68,7 @@ Display( void )
+
+ /* draw to window */
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
++ glDisable(GL_DEPTH_TEST); /* in case window has depth buffer */
+ glWindowPos2iARB(0, 0);
+ glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+diff --git a/progs/trivial/tri.c b/progs/trivial/tri.c
+index 58a650b..d4a7f08 100644
+--- a/progs/trivial/tri.c
++++ b/progs/trivial/tri.c
+@@ -33,6 +33,7 @@
+
+
+ GLenum doubleBuffer;
++int win;
+
+ static void Init(void)
+ {
+@@ -59,7 +60,8 @@ static void Key(unsigned char key, int x, int y)
+
+ switch (key) {
+ case 27:
+- exit(1);
++ glutDestroyWindow(win);
++ exit(0);
+ default:
+ return;
+ }
+@@ -122,7 +124,8 @@ int main(int argc, char **argv)
+ type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+ glutInitDisplayMode(type);
+
+- if (glutCreateWindow("First Tri") == GL_FALSE) {
++ win = glutCreateWindow("First Tri");
++ if (!win) {
+ exit(1);
+ }
+
+diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
+index 03fbab6..7fe1162 100644
+--- a/src/mesa/drivers/common/driverfuncs.c
++++ b/src/mesa/drivers/common/driverfuncs.c
+@@ -29,6 +29,7 @@
+ #include "buffers.h"
+ #include "context.h"
+ #include "framebuffer.h"
++#include "mipmap.h"
+ #include "queryobj.h"
+ #include "renderbuffer.h"
+ #include "texcompress.h"
+@@ -98,6 +99,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
+ driver->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+ driver->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+ driver->CopyTexSubImage3D = _swrast_copy_texsubimage3d;
++ driver->GenerateMipmap = _mesa_generate_mipmap;
+ driver->TestProxyTexImage = _mesa_test_proxy_teximage;
+ driver->CompressedTexImage1D = _mesa_store_compressed_teximage1d;
+ driver->CompressedTexImage2D = _mesa_store_compressed_teximage2d;
+diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
+index aa985d6..2d99238 100644
+--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
++++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
+@@ -404,6 +404,7 @@ int brw_prepare_vertices( struct brw_context *brw,
+ */
+ copy_array_to_vbo_array(brw, upload[0], interleave);
+
++ ret |= dri_bufmgr_check_aperture_space(upload[0]->bo);
+ for (i = 1; i < nr_uploads; i++) {
+ /* Then, just point upload[i] at upload[0]'s buffer. */
+ upload[i]->stride = interleave;
+@@ -416,13 +417,13 @@ int brw_prepare_vertices( struct brw_context *brw,
+ else {
+ /* Upload non-interleaved arrays */
+ for (i = 0; i < nr_uploads; i++) {
+- copy_array_to_vbo_array(brw, upload[i], upload[i]->element_size);
++ copy_array_to_vbo_array(brw, upload[i], upload[i]->element_size);
++ if (upload[i]->bo) {
++ ret |= dri_bufmgr_check_aperture_space(upload[i]->bo);
++ }
+ }
+ }
+
+- if (brw->vb.upload.bo) {
+- ret |= dri_bufmgr_check_aperture_space(brw->vb.upload.bo);
+- }
+
+ if (ret)
+ return 1;
+diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
+index 25f1f89..c138d15 100644
+--- a/src/mesa/drivers/dri/i965/brw_eu.h
++++ b/src/mesa/drivers/dri/i965/brw_eu.h
+@@ -335,14 +335,14 @@ static __inline struct brw_reg brw_imm_ud( GLuint ud )
+ static __inline struct brw_reg brw_imm_uw( GLushort uw )
+ {
+ struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
+- imm.dw1.ud = uw;
++ imm.dw1.ud = uw | (uw << 16);
+ return imm;
+ }
+
+ static __inline struct brw_reg brw_imm_w( GLshort w )
+ {
+ struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
+- imm.dw1.d = w;
++ imm.dw1.d = w | (w << 16);
+ return imm;
+ }
+
+diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
+index ec0bd6b..26ec797 100644
+--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
++++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
+@@ -183,7 +183,7 @@ static int prepare_depthbuffer(struct brw_context *brw)
+ {
+ struct intel_region *region = brw->state.depth_region;
+
+- if (region->buffer)
++ if (!region || !region->buffer)
+ return 0;
+ return dri_bufmgr_check_aperture_space(region->buffer);
+ }
+diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c
+index 4b03838..c423dbe 100644
+--- a/src/mesa/drivers/dri/i965/brw_urb.c
++++ b/src/mesa/drivers/dri/i965/brw_urb.c
+@@ -52,7 +52,7 @@ static const struct {
+ GLuint min_entry_size;
+ GLuint max_entry_size;
+ } limits[CS+1] = {
+- { 8, 32, 1, 5 }, /* vs */
++ { 16, 32, 1, 5 }, /* vs */
+ { 4, 8, 1, 5 }, /* gs */
+ { 6, 8, 1, 5 }, /* clp */
+ { 1, 8, 1, 12 }, /* sf */
+diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
+index a02f70a..4cda559 100644
+--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
++++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
+@@ -724,9 +724,6 @@ static void emit_tex( struct brw_wm_compile *c,
+ responseLength,
+ msgLength,
+ 0);
+-
+- if (shadow)
+- brw_MOV(p, dst[3], brw_imm_f(1.0));
+ }
+
+
+diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+index eff4555..0d91391 100644
+--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
++++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+@@ -69,7 +69,7 @@ static GLuint translate_tex_target( GLenum target )
+ }
+
+
+-static GLuint translate_tex_format( GLuint mesa_format )
++static GLuint translate_tex_format( GLuint mesa_format, GLenum depth_mode )
+ {
+ switch( mesa_format ) {
+ case MESA_FORMAT_L8:
+@@ -114,7 +114,12 @@ static GLuint translate_tex_format( GLuint mesa_format )
+ return BRW_SURFACEFORMAT_FXT1;
+
+ case MESA_FORMAT_Z16:
+- return BRW_SURFACEFORMAT_I16_UNORM;
++ if (depth_mode == GL_INTENSITY)
++ return BRW_SURFACEFORMAT_I16_UNORM;
++ else if (depth_mode == GL_ALPHA)
++ return BRW_SURFACEFORMAT_A16_UNORM;
++ else
++ return BRW_SURFACEFORMAT_L16_UNORM;
+
+ case MESA_FORMAT_RGB_DXT1:
+ return BRW_SURFACEFORMAT_DXT1_RGB;
+@@ -143,7 +148,7 @@ static GLuint translate_tex_format( GLuint mesa_format )
+ }
+
+ struct brw_wm_surface_key {
+- GLenum target;
++ GLenum target, depthmode;
+ dri_bo *bo;
+ GLint format;
+ GLint first_level, last_level;
+@@ -163,7 +168,7 @@ brw_create_texture_surface( struct brw_context *brw,
+
+ surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+ surf.ss0.surface_type = translate_tex_target(key->target);
+- surf.ss0.surface_format = translate_tex_format(key->format);
++ surf.ss0.surface_format = translate_tex_format(key->format, key->depthmode);
+
+ /* This is ok for all textures with channel width 8bit or less:
+ */
+@@ -219,6 +224,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
+
+ memset(&key, 0, sizeof(key));
+ key.target = tObj->Target;
++ key.depthmode = tObj->DepthMode;
+ key.format = firstImage->TexFormat->MesaFormat;
+ key.bo = intelObj->mt->region->buffer;
+ key.first_level = intelObj->firstLevel;
+diff --git a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c
+index 6828425..545913f 100644
+--- a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c
++++ b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c
+@@ -889,7 +889,7 @@ dri_ttm_bo_process_reloc(dri_bo *bo)
+ struct intel_validate_entry *entry =
+ &bufmgr_ttm->validate_array[target_buf_ttm->validate_index];
+
+- entry->bo_arg.d.req.bo_req.flags &= ~DRM_BO_HINT_PRESUMED_OFFSET;
++ entry->bo_arg.d.req.bo_req.hint &= ~DRM_BO_HINT_PRESUMED_OFFSET;
+ }
+ }
+ }
+@@ -993,7 +993,7 @@ dri_ttm_bo_post_submit(dri_bo *bo)
+ /* Continue walking the tree depth-first. */
+ dri_ttm_bo_post_submit(r->target_buf);
+
+- r->last_target_offset = bo->offset;
++ r->last_target_offset = r->target_buf->offset;
+ }
+ }
+
+diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+index 55503f4..9205627 100644
+--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
++++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+@@ -272,6 +272,11 @@ intel_miptree_match_image(struct intel_mipmap_tree *mt,
+ image->IsCompressed != mt->compressed)
+ return GL_FALSE;
+
++ if (!image->IsCompressed &&
++ !mt->compressed &&
++ image->TexFormat->TexelBytes != mt->cpp)
++ return GL_FALSE;
++
+ /* Test image dimensions against the base level image adjusted for
+ * minification. This will also catch images not present in the
+ * tree, changed targets, etc.
+diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
+index 5aeb2a1..52e062e 100644
+--- a/src/mesa/drivers/dri/intel/intel_screen.c
++++ b/src/mesa/drivers/dri/intel/intel_screen.c
+@@ -68,7 +68,7 @@ PUBLIC const char __driConfigOptions[] =
+ DRI_CONF_SECTION_END
+ DRI_CONF_SECTION_QUALITY
+ DRI_CONF_FORCE_S3TC_ENABLE(false)
+- DRI_CONF_ALLOW_LARGE_TEXTURES(1)
++ DRI_CONF_ALLOW_LARGE_TEXTURES(2)
+ DRI_CONF_SECTION_END
+ DRI_CONF_SECTION_DEBUG
+ DRI_CONF_NO_RAST(false)
+diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c
+index 329af0d..f1d6a6d 100644
+--- a/src/mesa/drivers/dri/intel/intel_tex.c
++++ b/src/mesa/drivers/dri/intel/intel_tex.c
+@@ -172,14 +172,13 @@ timed_memcpy(void *dest, const void *src, size_t n)
+ */
+ void
+ intel_generate_mipmap(GLcontext *ctx, GLenum target,
+- const struct gl_texture_unit *texUnit,
+ struct gl_texture_object *texObj)
+ {
+ struct intel_texture_object *intelObj = intel_texture_object(texObj);
+ GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
+ int face, i;
+
+- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
++ _mesa_generate_mipmap(ctx, target, texObj);
+
+ /* Update the level information in our private data in the new images, since
+ * it didn't get set as part of a normal TexImage path.
+@@ -198,6 +197,15 @@ intel_generate_mipmap(GLcontext *ctx, GLenum target,
+ }
+ }
+
++static void intelGenerateMipmap(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj)
++{
++ struct intel_context *intel = intel_context(ctx);
++ struct intel_texture_object *intelObj = intel_texture_object(texObj);
++
++ intel_tex_map_images(intel, intelObj);
++ intel_generate_mipmap(ctx, target, texObj);
++ intel_tex_unmap_images(intel, intelObj);
++}
+
+ void
+ intelInitTextureFuncs(struct dd_function_table *functions)
+@@ -221,6 +229,7 @@ intelInitTextureFuncs(struct dd_function_table *functions)
+ functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+ #endif
+ functions->GetTexImage = intelGetTexImage;
++ functions->GenerateMipmap = intelGenerateMipmap;
+
+ /* compressed texture functions */
+ functions->CompressedTexImage2D = intelCompressedTexImage2D;
+diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h
+index 3a87137..60ab820 100644
+--- a/src/mesa/drivers/dri/intel/intel_tex.h
++++ b/src/mesa/drivers/dri/intel/intel_tex.h
+@@ -151,7 +151,6 @@ void intel_tex_unmap_images(struct intel_context *intel,
+ int intel_compressed_num_bytes(GLuint mesaFormat);
+
+ void intel_generate_mipmap(GLcontext *ctx, GLenum target,
+- const struct gl_texture_unit *texUnit,
+ struct gl_texture_object *texObj);
+
+ #endif
+diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
+index 7facc46..1add7c6 100644
+--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
++++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
+@@ -161,9 +161,7 @@ do_copy_texsubimage(struct intel_context *intel,
+
+ /* GL_SGIS_generate_mipmap */
+ if (intelImage->level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- intel_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ intel_generate_mipmap(ctx, target, texObj);
+ }
+
+ return GL_TRUE;
+diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
+index a56a395..95ddbd5 100644
+--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
++++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
+@@ -348,8 +348,10 @@ intelTexImage(GLcontext * ctx,
+ postConvWidth = 32 / texelBytes;
+ texImage->RowStride = postConvWidth;
+ }
+-
+- assert(texImage->RowStride == postConvWidth);
++
++ if (!intelImage->mt) {
++ assert(texImage->RowStride == postConvWidth);
++ }
+ }
+
+ /* Release the reference to a potentially orphaned buffer.
+@@ -520,9 +522,7 @@ intelTexImage(GLcontext * ctx,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- intel_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ intel_generate_mipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, unpack);
+diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
+index 688e387..9ba494b 100644
+--- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c
++++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
+@@ -102,9 +102,7 @@ intelTexSubimage(GLcontext * ctx,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- intel_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ intel_generate_mipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
+index 20c1107..c567349 100644
+--- a/src/mesa/drivers/dri/r200/r200_context.c
++++ b/src/mesa/drivers/dri/r200/r200_context.c
+@@ -69,6 +69,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ #define need_GL_ATI_fragment_shader
+ #define need_GL_EXT_blend_minmax
+ #define need_GL_EXT_fog_coord
++#define need_GL_EXT_multi_draw_arrays
+ #define need_GL_EXT_secondary_color
+ #define need_GL_EXT_blend_equation_separate
+ #define need_GL_EXT_blend_func_separate
+@@ -132,6 +133,7 @@ const struct dri_extension card_extensions[] =
+ { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
+ { "GL_EXT_blend_subtract", NULL },
+ { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
++ { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
+ { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
+ { "GL_EXT_stencil_wrap", NULL },
+ { "GL_EXT_texture_edge_clamp", NULL },
+diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c
+index 05ff595..4edf304 100644
+--- a/src/mesa/drivers/dri/r200/r200_texstate.c
++++ b/src/mesa/drivers/dri/r200/r200_texstate.c
+@@ -1815,6 +1815,12 @@ void r200UpdateTextureState( GLcontext *ctx )
+ GLboolean ok;
+ GLuint dbg;
+
++ /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or
++ rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since
++ we use these to determine if we want to emit the corresponding state
++ atoms. */
++ R200_NEWPRIM( rmesa );
++
+ if (ctx->ATIFragmentShader._Enabled) {
+ GLuint i;
+ for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
+diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
+index d2ed310..c56a762 100644
+--- a/src/mesa/drivers/dri/r300/r300_context.c
++++ b/src/mesa/drivers/dri/r300/r300_context.c
+@@ -84,6 +84,7 @@ int hw_tcl_on = 1;
+ #define need_GL_ARB_vertex_program
+ #define need_GL_EXT_blend_minmax
+ //#define need_GL_EXT_fog_coord
++#define need_GL_EXT_multi_draw_arrays
+ #define need_GL_EXT_secondary_color
+ #define need_GL_EXT_blend_equation_separate
+ #define need_GL_EXT_blend_func_separate
+@@ -112,6 +113,7 @@ const struct dri_extension card_extensions[] = {
+ {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
+ {"GL_EXT_blend_subtract", NULL},
+ // {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
++ {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
+ {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions},
+ {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
+ {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
+diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
+index 1b40588..baa7418 100644
+--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
++++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
+@@ -316,6 +316,14 @@ static void r300EmitClearState(GLcontext * ctx)
+ e32(FP_SELA(0, NO, W, FP_TMP(0), 0, 0));
+
+ if (has_tcl) {
++ R300_STATECHANGE(rmesa, vap_cntl);
++ reg_start(R300_VAP_CNTL, 0);
++
++ e32((10 << R300_VAP_CNTL__PVS_NUM_SLOTS__SHIFT) |
++ (6 << R300_VAP_CNTL__PVS_NUM_CNTRLS__SHIFT) |
++ (4 << R300_VAP_CNTL__PVS_NUM_FPUS__SHIFT) |
++ (12 << R300_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
++
+ R300_STATECHANGE(r300, pvs);
+ reg_start(R300_VAP_PVS_CNTL_1, 2);
+
+diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
+index 2200cec..d2a8175 100644
+--- a/src/mesa/drivers/dri/r300/r300_reg.h
++++ b/src/mesa/drivers/dri/r300/r300_reg.h
+@@ -67,9 +67,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ /*
+ * Vertex Array Processing (VAP) Control
+- * Stolen from r200 code from Christoph Brill (It's a guess!)
+ */
+ #define R300_VAP_CNTL 0x2080
++# define R300_VAP_CNTL__PVS_NUM_SLOTS__SHIFT 0
++# define R300_VAP_CNTL__PVS_NUM_CNTRLS__SHIFT 4
++# define R300_VAP_CNTL__PVS_NUM_FPUS__SHIFT 8
++# define R300_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 18
++# define R500_VAP_CNTL__VAP_NO_RENDER (1<<17)
++# define R300_VAP_CNTL__DX_CLIP_SPACE_DEF (1<<22)
++# define R500_VAP_CNTL__TCL_STATE_OPTIMIZATION (1<<23)
+
+ /* This register is written directly and also starts data section
+ * in many 3d CP_PACKET3's
+diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
+index e11b5af..aa0de4e 100644
+--- a/src/mesa/drivers/dri/r300/r300_state.c
++++ b/src/mesa/drivers/dri/r300/r300_state.c
+@@ -1648,10 +1648,51 @@ static inline void r300SetupVertexProgramFragment(r300ContextPtr r300, int dest,
+ }
+ }
+
++/* FIXME: move near the MIN2 define. */
++#define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
++
++/* FIXME: need to add a structure for per-card/chipset values; they are
++ * currently hard-coded. */
++static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count,
++ GLuint output_count, GLuint temp_count)
++{
++ int cmd_reserved = 0;
++ int cmd_written = 0;
++ drm_radeon_cmd_header_t *cmd = NULL;
++
++ int vtx_mem_size = 72; /* FIXME: R3XX vs R5XX */
++
++ /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
++ * See r500 docs 6.5.2 */
++ reg_start(R300_VAP_PVS_WAITIDLE, 0);
++ e32(0x00000000);
++
++ /* avoid division by zero */
++ if (input_count == 0)
++ input_count = 1;
++ if (output_count == 0)
++ output_count = 1;
++ if (temp_count == 0)
++ temp_count = 1;
++
++ int pvs_num_slots =
++ MIN3(10, vtx_mem_size / input_count, vtx_mem_size / output_count);
++ int pvs_num_cntrls = MIN2(6, vtx_mem_size / temp_count);
++
++ R300_STATECHANGE(rmesa, vap_cntl);
++ rmesa->hw.vap_cntl.cmd[1] =
++ (pvs_num_slots << R300_VAP_CNTL__PVS_NUM_SLOTS__SHIFT) |
++ (pvs_num_cntrls << R300_VAP_CNTL__PVS_NUM_CNTRLS__SHIFT) |
++ (4 << R300_VAP_CNTL__PVS_NUM_FPUS__SHIFT) |
++ (12 << R300_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT) |
++ R500_VAP_CNTL__TCL_STATE_OPTIMIZATION;
++}
++
+ static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
+ {
+ struct r300_vertex_shader_state *prog = &(rmesa->state.vertex_shader);
+ GLuint o_reg = 0;
++ GLuint i_reg = 0;
+ int i;
+ int inst_count = 0;
+ int param_count = 0;
+@@ -1664,6 +1705,7 @@ static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
+ prog->program.body.i[program_end + 2] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+ prog->program.body.i[program_end + 3] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+ program_end += 4;
++ i_reg++;
+ }
+ }
+
+@@ -1673,6 +1715,8 @@ static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
+ &(prog->program));
+ inst_count = (prog->program.length / 4) - 1;
+
++ r300VapCntl(rmesa, i_reg, o_reg, 0);
++
+ R300_STATECHANGE(rmesa, pvs);
+ rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
+ (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
+@@ -1686,6 +1730,15 @@ static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
+ (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT);
+ }
+
++static int r300BitCount(int x)
++{
++ x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U);
++ x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U);
++ x = (x >> 16) + (x & 0xffff);
++ x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f);
++ return (x >> 8) + (x & 0x00ff);
++}
++
+ static void r300SetupRealVertexProgram(r300ContextPtr rmesa)
+ {
+ GLcontext *ctx = rmesa->radeon.glCtx;
+@@ -1707,6 +1760,10 @@ static void r300SetupRealVertexProgram(r300ContextPtr rmesa)
+ r300SetupVertexProgramFragment(rmesa, R300_PVS_UPLOAD_PROGRAM, &(prog->program));
+ inst_count = (prog->program.length / 4) - 1;
+
++ r300VapCntl(rmesa, r300BitCount(prog->key.InputsRead),
++ r300BitCount(prog->key.OutputsWritten),
++ prog->num_temporaries);
++
+ R300_STATECHANGE(rmesa, pvs);
+ rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
+ (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
+@@ -1740,13 +1797,6 @@ static void r300SetupVertexProgram(r300ContextPtr rmesa)
+ r300SetupDefaultVertexProgram(rmesa);
+ }
+
+-
+- /* FIXME: This is done for vertex shader fragments, but also needs to be
+- * done for vap_pvs, so I leave it as a reminder. */
+-#if 0
+- reg_start(R300_VAP_PVS_WAITIDLE, 0);
+- e32(0x00000000);
+-#endif
+ }
+
+ /**
+@@ -1848,11 +1898,6 @@ static void r300ResetHwState(r300ContextPtr r300)
+ r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
+ r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
+
+- if (!has_tcl)
+- r300->hw.vap_cntl.cmd[1] = 0x0014045a;
+- else
+- r300->hw.vap_cntl.cmd[1] = 0x0030045A; //0x0030065a /* Dangerous */
+-
+ r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
+ | R300_VPORT_X_OFFSET_ENA
+ | R300_VPORT_Y_SCALE_ENA
+@@ -2084,10 +2129,11 @@ void r300UpdateShaders(r300ContextPtr rmesa)
+ hw_tcl_on = future_hw_tcl_on = 0;
+ r300ResetHwState(rmesa);
+
++ r300UpdateStateParameters(ctx, _NEW_PROGRAM);
+ return;
+ }
+- r300UpdateStateParameters(ctx, _NEW_PROGRAM);
+ }
++ r300UpdateStateParameters(ctx, _NEW_PROGRAM);
+ }
+
+ static void r300SetupPixelShader(r300ContextPtr rmesa)
+diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c
+index a732bdb..1452ed5 100644
+--- a/src/mesa/drivers/dri/r300/r300_swtcl.c
++++ b/src/mesa/drivers/dri/r300/r300_swtcl.c
+@@ -591,6 +591,7 @@ static void r300RenderStart(GLcontext *ctx)
+ r300ChooseRenderState(ctx);
+ r300SetVertexFormat(ctx);
+
++ r300UpdateShaders(rmesa);
+ r300UpdateShaderStates(rmesa);
+
+ r300EmitCacheFlush(rmesa);
+diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
+index 27d233c..f92fdd4 100644
+--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
++++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
+@@ -90,7 +90,7 @@ DRI_CONF_BEGIN
+ DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
+ DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
+ DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
+- DRI_CONF_ALLOW_LARGE_TEXTURES(1)
++ DRI_CONF_ALLOW_LARGE_TEXTURES(2)
+ DRI_CONF_SECTION_END
+ DRI_CONF_SECTION_DEBUG
+ DRI_CONF_NO_RAST(false)
+@@ -117,7 +117,7 @@ DRI_CONF_BEGIN
+ DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
+ DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
+ DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
+- DRI_CONF_ALLOW_LARGE_TEXTURES(1)
++ DRI_CONF_ALLOW_LARGE_TEXTURES(2)
+ DRI_CONF_TEXTURE_BLEND_QUALITY(1.0,"0.0:1.0")
+ DRI_CONF_SECTION_END
+ DRI_CONF_SECTION_DEBUG
+@@ -682,6 +682,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
+ break;
+
+ case PCI_CHIP_RS690_791E:
++ case PCI_CHIP_RS690_791F:
+ screen->chip_family = CHIP_FAMILY_RS690;
+ fprintf(stderr, "Warning, RS690 detected, 3D support is incomplete.\n");
+ break;
+@@ -697,6 +698,9 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
+ return NULL;
+ }
+
++ if (getenv("R300_NO_TCL"))
++ screen->chip_flags &= ~RADEON_CHIPSET_TCL;
++
+ if (screen->chip_family <= CHIP_FAMILY_RS200)
+ screen->chip_flags |= RADEON_CLASS_R100;
+ else if (screen->chip_family <= CHIP_FAMILY_RV280)
+diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c
+index 0261a3f..15f15a8 100644
+--- a/src/mesa/drivers/dri/unichrome/via_tex.c
++++ b/src/mesa/drivers/dri/unichrome/via_tex.c
+@@ -820,9 +820,7 @@ static void viaTexImage(GLcontext *ctx,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ _mesa_generate_mipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
+index d94876e..417a49f 100644
+--- a/src/mesa/main/context.c
++++ b/src/mesa/main/context.c
+@@ -150,8 +150,6 @@ int MESA_DEBUG_FLAGS = 0;
+ /* ubyte -> float conversion */
+ GLfloat _mesa_ubyte_to_float_color_tab[256];
+
+-static void
+-free_shared_state( GLcontext *ctx, struct gl_shared_state *ss );
+
+
+ /**
+@@ -421,12 +419,14 @@ alloc_shared_state( GLcontext *ctx )
+ #endif
+
+ #if FEATURE_ARB_vertex_program
+- ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
++ ss->DefaultVertexProgram = (struct gl_vertex_program *)
++ ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
+ if (!ss->DefaultVertexProgram)
+ goto cleanup;
+ #endif
+ #if FEATURE_ARB_fragment_program
+- ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
++ ss->DefaultFragmentProgram = (struct gl_fragment_program *)
++ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+ if (!ss->DefaultFragmentProgram)
+ goto cleanup;
+ #endif
+@@ -503,12 +503,10 @@ cleanup:
+ _mesa_DeleteHashTable(ss->Programs);
+ #endif
+ #if FEATURE_ARB_vertex_program
+- if (ss->DefaultVertexProgram)
+- ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
++ _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
+ #endif
+ #if FEATURE_ARB_fragment_program
+- if (ss->DefaultFragmentProgram)
+- ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
++ _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
+ #endif
+ #if FEATURE_ATI_fragment_shader
+ if (ss->DefaultFragmentShader)
+@@ -715,10 +713,10 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
+ _mesa_DeleteHashTable(ss->Programs);
+ #endif
+ #if FEATURE_ARB_vertex_program
+- ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
++ _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
+ #endif
+ #if FEATURE_ARB_fragment_program
+- ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
++ _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
+ #endif
+
+ #if FEATURE_ATI_fragment_shader
+@@ -1252,6 +1250,14 @@ _mesa_free_context_data( GLcontext *ctx )
+ _mesa_unreference_framebuffer(&ctx->DrawBuffer);
+ _mesa_unreference_framebuffer(&ctx->ReadBuffer);
+
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
++
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
++
+ _mesa_free_attrib_data(ctx);
+ _mesa_free_lighting_data( ctx );
+ _mesa_free_eval_data( ctx );
+diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
+index ce33905..e3ded41 100644
+--- a/src/mesa/main/dd.h
++++ b/src/mesa/main/dd.h
+@@ -328,6 +328,12 @@ struct dd_function_table {
+ GLsizei width, GLsizei height );
+
+ /**
++ * Called by glGenerateMipmap() or when GL_GENERATE_MIPMAP_SGIS is enabled.
++ */
++ void (*GenerateMipmap)(GLcontext *ctx, GLenum target,
++ struct gl_texture_object *texObj);
++
++ /**
+ * Called by glTexImage[123]D when user specifies a proxy texture
+ * target.
+ *
+diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
+index 8d10d8a..23ede7b 100644
+--- a/src/mesa/main/dlist.c
++++ b/src/mesa/main/dlist.c
+@@ -611,9 +611,9 @@ destroy_list(GLcontext *ctx, GLuint list)
+
+
+ /*
+- * Translate the nth element of list from type to GLuint.
++ * Translate the nth element of list from <type> to GLint.
+ */
+-static GLuint
++static GLint
+ translate_id(GLsizei n, GLenum type, const GLvoid * list)
+ {
+ GLbyte *bptr;
+@@ -627,37 +627,40 @@ translate_id(GLsizei n, GLenum type, const GLvoid * list)
+ switch (type) {
+ case GL_BYTE:
+ bptr = (GLbyte *) list;
+- return (GLuint) *(bptr + n);
++ return (GLint) bptr[n];
+ case GL_UNSIGNED_BYTE:
+ ubptr = (GLubyte *) list;
+- return (GLuint) *(ubptr + n);
++ return (GLint) ubptr[n];
+ case GL_SHORT:
+ sptr = (GLshort *) list;
+- return (GLuint) *(sptr + n);
++ return (GLint) sptr[n];
+ case GL_UNSIGNED_SHORT:
+ usptr = (GLushort *) list;
+- return (GLuint) *(usptr + n);
++ return (GLint) usptr[n];
+ case GL_INT:
+ iptr = (GLint *) list;
+- return (GLuint) *(iptr + n);
++ return iptr[n];
+ case GL_UNSIGNED_INT:
+ uiptr = (GLuint *) list;
+- return (GLuint) *(uiptr + n);
++ return (GLint) uiptr[n];
+ case GL_FLOAT:
+ fptr = (GLfloat *) list;
+- return (GLuint) *(fptr + n);
++ return (GLint) FLOORF(fptr[n]);
+ case GL_2_BYTES:
+ ubptr = ((GLubyte *) list) + 2 * n;
+- return (GLuint) *ubptr * 256 + (GLuint) * (ubptr + 1);
++ return (GLint) ubptr[0] * 256
++ + (GLint) ubptr[1];
+ case GL_3_BYTES:
+ ubptr = ((GLubyte *) list) + 3 * n;
+- return (GLuint) * ubptr * 65536
+- + (GLuint) *(ubptr + 1) * 256 + (GLuint) * (ubptr + 2);
++ return (GLint) ubptr[0] * 65536
++ + (GLint) ubptr[1] * 256
++ + (GLint) ubptr[2];
+ case GL_4_BYTES:
+ ubptr = ((GLubyte *) list) + 4 * n;
+- return (GLuint) *ubptr * 16777216
+- + (GLuint) *(ubptr + 1) * 65536
+- + (GLuint) *(ubptr + 2) * 256 + (GLuint) * (ubptr + 3);
++ return (GLint) ubptr[0] * 16777216
++ + (GLint) ubptr[1] * 65536
++ + (GLint) ubptr[2] * 256
++ + (GLint) ubptr[3];
+ default:
+ return 0;
+ }
+@@ -992,10 +995,10 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
+ }
+
+ for (i = 0; i < n; i++) {
+- GLuint list = translate_id(i, type, lists);
++ GLint list = translate_id(i, type, lists);
+ Node *n = ALLOC_INSTRUCTION(ctx, OPCODE_CALL_LIST_OFFSET, 2);
+ if (n) {
+- n[1].ui = list;
++ n[1].i = list;
+ n[2].b = typeErrorFlag;
+ }
+ }
+@@ -5774,7 +5777,8 @@ execute_list(GLcontext *ctx, GLuint list)
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)");
+ }
+ else if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
+- execute_list(ctx, ctx->List.ListBase + n[1].ui);
++ GLuint list = (GLuint) (ctx->List.ListBase + n[1].i);
++ execute_list(ctx, list);
+ }
+ break;
+ case OPCODE_CLEAR:
+@@ -6822,7 +6826,6 @@ void GLAPIENTRY
+ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
+ {
+ GET_CURRENT_CONTEXT(ctx);
+- GLuint list;
+ GLint i;
+ GLboolean save_compile_flag;
+
+@@ -6854,8 +6857,8 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
+ ctx->CompileFlag = GL_FALSE;
+
+ for (i = 0; i < n; i++) {
+- list = translate_id(i, type, lists);
+- execute_list(ctx, ctx->List.ListBase + list);
++ GLuint list = (GLuint) (ctx->List.ListBase + translate_id(i, type, lists));
++ execute_list(ctx, list);
+ }
+
+ ctx->CompileFlag = save_compile_flag;
+diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
+index 4f28766..fde9338 100644
+--- a/src/mesa/main/drawpix.c
++++ b/src/mesa/main/drawpix.c
+@@ -374,8 +374,9 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
+
+ if (ctx->RenderMode == GL_RENDER) {
+ /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
+- GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
+- GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
++ const GLfloat epsilon = 0.0001;
++ GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig);
++ GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig);
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack from PBO */
+diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
+index 9b60c73..8e9948c 100644
+--- a/src/mesa/main/fbobject.c
++++ b/src/mesa/main/fbobject.c
+@@ -1544,7 +1544,7 @@ _mesa_GenerateMipmapEXT(GLenum target)
+
+ /* XXX this might not handle cube maps correctly */
+ _mesa_lock_texture(ctx, texObj);
+- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ _mesa_unlock_texture(ctx, texObj);
+ }
+
+diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
+index 44357fb..8ca912b 100644
+--- a/src/mesa/main/mipmap.c
++++ b/src/mesa/main/mipmap.c
+@@ -934,7 +934,6 @@ make_2d_stack_mipmap(const struct gl_texture_format *format, GLint border,
+ */
+ void
+ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
+- const struct gl_texture_unit *texUnit,
+ struct gl_texture_object *texObj)
+ {
+ const struct gl_texture_image *srcImage;
+diff --git a/src/mesa/main/mipmap.h b/src/mesa/main/mipmap.h
+index df78603..46e1690 100644
+--- a/src/mesa/main/mipmap.h
++++ b/src/mesa/main/mipmap.h
+@@ -30,7 +30,6 @@
+
+ extern void
+ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
+- const struct gl_texture_unit *texUnit,
+ struct gl_texture_object *texObj);
+
+
+diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
+index c8718a7..001240a 100644
+--- a/src/mesa/main/mtypes.h
++++ b/src/mesa/main/mtypes.h
+@@ -1544,19 +1544,17 @@ struct gl_texture_unit
+ /*@}*/
+ };
+
+-struct texenvprog_cache_item {
+- GLuint hash;
+- void *key;
+- struct gl_fragment_program *data;
+- struct texenvprog_cache_item *next;
+-};
+
+-struct texenvprog_cache {
++struct texenvprog_cache_item;
++
++struct texenvprog_cache
++{
+ struct texenvprog_cache_item **items;
+ GLuint size, n_items;
+ GLcontext *ctx;
+ };
+
++
+ /**
+ * Texture attribute group (GL_TEXTURE_BIT).
+ */
+@@ -2185,10 +2183,10 @@ struct gl_shared_state
+ /*@{*/
+ struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
+ #if FEATURE_ARB_vertex_program
+- struct gl_program *DefaultVertexProgram;
++ struct gl_vertex_program *DefaultVertexProgram;
+ #endif
+ #if FEATURE_ARB_fragment_program
+- struct gl_program *DefaultFragmentProgram;
++ struct gl_fragment_program *DefaultFragmentProgram;
+ #endif
+ /*@}*/
+
+diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
+index 5ff67b6..1c73c5c 100644
+--- a/src/mesa/main/state.c
++++ b/src/mesa/main/state.c
+@@ -978,50 +978,60 @@ update_program(GLcontext *ctx)
+ * 3. Programs derived from fixed-function state.
+ */
+
+- ctx->FragmentProgram._Current = NULL;
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
+
+ if (shProg && shProg->LinkStatus) {
+ /* Use shader programs */
+ /* XXX this isn't quite right, since we may have either a vertex
+ * _or_ fragment shader (not always both).
+ */
+- ctx->VertexProgram._Current = shProg->VertexProgram;
+- ctx->FragmentProgram._Current = shProg->FragmentProgram;
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
++ shProg->VertexProgram);
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
++ shProg->FragmentProgram);
+ }
+ else {
+ if (ctx->VertexProgram._Enabled) {
+ /* use user-defined vertex program */
+- ctx->VertexProgram._Current = ctx->VertexProgram.Current;
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
++ ctx->VertexProgram.Current);
+ }
+ else if (ctx->VertexProgram._MaintainTnlProgram) {
+ /* Use vertex program generated from fixed-function state.
+ * The _Current pointer will get set in
+ * _tnl_UpdateFixedFunctionProgram() later if appropriate.
+ */
+- ctx->VertexProgram._Current = NULL;
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
+ }
+ else {
+ /* no vertex program */
+- ctx->VertexProgram._Current = NULL;
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
+ }
+
+ if (ctx->FragmentProgram._Enabled) {
+ /* use user-defined vertex program */
+- ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
++ ctx->FragmentProgram.Current);
+ }
+ else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
+ /* Use fragment program generated from fixed-function state.
+ * The _Current pointer will get set in _mesa_UpdateTexEnvProgram()
+ * later if appropriate.
+ */
+- ctx->FragmentProgram._Current = NULL;
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
+ }
+ else {
+ /* no fragment program */
+- ctx->FragmentProgram._Current = NULL;
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
+ }
+ }
+
++ if (ctx->VertexProgram._Current)
++ assert(ctx->VertexProgram._Current->Base.Parameters);
++ if (ctx->FragmentProgram._Current)
++ assert(ctx->FragmentProgram._Current->Base.Parameters);
++
++
+ ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
+ if (ctx->FragmentProgram._MaintainTexEnvProgram &&
+ !ctx->FragmentProgram._Enabled) {
+diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
+index fb68bf0..68a4db9 100644
+--- a/src/mesa/main/texenvprogram.c
++++ b/src/mesa/main/texenvprogram.c
+@@ -28,12 +28,23 @@
+ #include "glheader.h"
+ #include "macros.h"
+ #include "enums.h"
++#include "shader/program.h"
+ #include "shader/prog_parameter.h"
+ #include "shader/prog_instruction.h"
+ #include "shader/prog_print.h"
+ #include "shader/prog_statevars.h"
+ #include "texenvprogram.h"
+
++
++struct texenvprog_cache_item
++{
++ GLuint hash;
++ void *key;
++ struct gl_fragment_program *data;
++ struct texenvprog_cache_item *next;
++};
++
++
+ /**
+ * This MAX is probably a bit generous, but that's OK. There can be
+ * up to four instructions per texture unit (TEX + 3 for combine),
+@@ -1133,7 +1144,7 @@ search_cache(const struct texenvprog_cache *cache,
+
+ for (c = cache->items[hash % cache->size]; c; c = c->next) {
+ if (c->hash == hash && memcmp(c->key, key, keysize) == 0)
+- return (struct gl_fragment_program *) c->data;
++ return c->data;
+ }
+
+ return NULL;
+@@ -1161,7 +1172,7 @@ static void rehash( struct texenvprog_cache *cache )
+ cache->size = size;
+ }
+
+-static void clear_cache( struct texenvprog_cache *cache )
++static void clear_cache(GLcontext *ctx, struct texenvprog_cache *cache)
+ {
+ struct texenvprog_cache_item *c, *next;
+ GLuint i;
+@@ -1170,8 +1181,7 @@ static void clear_cache( struct texenvprog_cache *cache )
+ for (c = cache->items[i]; c; c = next) {
+ next = c->next;
+ _mesa_free(c->key);
+- cache->ctx->Driver.DeleteProgram(cache->ctx,
+- (struct gl_program *) c->data);
++ _mesa_reference_fragprog(ctx, &c->data, NULL);
+ _mesa_free(c);
+ }
+ cache->items[i] = NULL;
+@@ -1182,25 +1192,25 @@ static void clear_cache( struct texenvprog_cache *cache )
+ }
+
+
+-static void cache_item( struct texenvprog_cache *cache,
++static void cache_item( GLcontext *ctx,
++ struct texenvprog_cache *cache,
+ GLuint hash,
+ const struct state_key *key,
+- void *data )
++ struct gl_fragment_program *prog)
+ {
+- struct texenvprog_cache_item *c
+- = (struct texenvprog_cache_item *) MALLOC(sizeof(*c));
++ struct texenvprog_cache_item *c = CALLOC_STRUCT(texenvprog_cache_item);
+ c->hash = hash;
+
+ c->key = _mesa_malloc(sizeof(*key));
+ memcpy(c->key, key, sizeof(*key));
+
+- c->data = (struct gl_fragment_program *) data;
++ _mesa_reference_fragprog(ctx, &c->data, prog);
+
+ if (cache->n_items > cache->size * 1.5) {
+ if (cache->size < 1000)
+ rehash(cache);
+ else
+- clear_cache(cache);
++ clear_cache(ctx, cache);
+ }
+
+ cache->n_items++;
+@@ -1243,32 +1253,29 @@ _mesa_UpdateTexEnvProgram( GLcontext *ctx )
+ /* If a conventional fragment program/shader isn't in effect... */
+ if (!ctx->FragmentProgram._Enabled &&
+ (!ctx->Shader.CurrentProgram || !ctx->Shader.CurrentProgram->FragmentProgram)) {
++ struct gl_fragment_program *newProg;
++
+ make_state_key(ctx, &key);
+ hash = hash_key(&key);
+
+- ctx->FragmentProgram._Current =
+- ctx->FragmentProgram._TexEnvProgram =
+- search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
++ newProg = search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
++
++ if (!newProg) {
++ /* create new tex env program */
+
+- if (!ctx->FragmentProgram._TexEnvProgram) {
+ if (0)
+ _mesa_printf("Building new texenv proggy for key %x\n", hash);
+
+- /* create new tex env program */
+- ctx->FragmentProgram._Current =
+- ctx->FragmentProgram._TexEnvProgram =
+- (struct gl_fragment_program *)
++ newProg = (struct gl_fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+
+- create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram);
++ create_new_program(ctx, &key, newProg);
+
+- cache_item(&ctx->Texture.env_fp_cache, hash, &key,
+- ctx->FragmentProgram._TexEnvProgram);
+- }
+- else {
+- if (0)
+- _mesa_printf("Found existing texenv program for key %x\n", hash);
++ cache_item(ctx, &ctx->Texture.env_fp_cache, hash, &key, newProg);
+ }
++
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, newProg);
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, newProg);
+ }
+ else {
+ /* _Current pointer has been updated in update_program */
+@@ -1298,6 +1305,6 @@ void _mesa_TexEnvProgramCacheInit( GLcontext *ctx )
+
+ void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx )
+ {
+- clear_cache(&ctx->Texture.env_fp_cache);
++ clear_cache(ctx, &ctx->Texture.env_fp_cache);
+ _mesa_free(ctx->Texture.env_fp_cache.items);
+ }
+diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
+index 288b334..626c264 100644
+--- a/src/mesa/main/texstate.c
++++ b/src/mesa/main/texstate.c
+@@ -213,6 +213,9 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state,
+ return;
+ }
+
++ if (mode == GL_REPLACE_EXT)
++ mode = GL_REPLACE;
++
+ switch (mode) {
+ case GL_REPLACE:
+ case GL_MODULATE:
+@@ -315,7 +318,9 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ {
+- const GLenum mode = (GLenum) (GLint) *param;
++ GLenum mode = (GLenum) (GLint) *param;
++ if (mode == GL_REPLACE_EXT)
++ mode = GL_REPLACE;
+ if (texUnit->EnvMode == mode)
+ return;
+ if (mode == GL_MODULATE ||
+diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
+index 90edca8..5363e9e 100644
+--- a/src/mesa/main/texstore.c
++++ b/src/mesa/main/texstore.c
+@@ -2918,9 +2918,7 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+@@ -3004,9 +3002,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+@@ -3080,9 +3076,7 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+@@ -3128,9 +3122,7 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+@@ -3183,9 +3175,7 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+@@ -3238,9 +3228,7 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+@@ -3314,9 +3302,7 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
+@@ -3426,9 +3412,7 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target,
+- &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+- texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
+diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
+index d2c9183..787013b 100644
+--- a/src/mesa/shader/program.c
++++ b/src/mesa/shader/program.c
+@@ -59,9 +59,9 @@ _mesa_init_program(GLcontext *ctx)
+ ctx->VertexProgram.Enabled = GL_FALSE;
+ ctx->VertexProgram.PointSizeEnabled = GL_FALSE;
+ ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
+- ctx->VertexProgram.Current = (struct gl_vertex_program *) ctx->Shared->DefaultVertexProgram;
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
++ ctx->Shared->DefaultVertexProgram);
+ assert(ctx->VertexProgram.Current);
+- ctx->VertexProgram.Current->Base.RefCount++;
+ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
+ ctx->VertexProgram.TrackMatrix[i] = GL_NONE;
+ ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV;
+@@ -70,7 +70,8 @@ _mesa_init_program(GLcontext *ctx)
+
+ #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
+ ctx->FragmentProgram.Enabled = GL_FALSE;
+- ctx->FragmentProgram.Current = (struct gl_fragment_program *) ctx->Shared->DefaultFragmentProgram;
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
++ ctx->Shared->DefaultFragmentProgram);
+ assert(ctx->FragmentProgram.Current);
+ ctx->FragmentProgram.Current->Base.RefCount++;
+ #endif
+@@ -92,18 +93,10 @@ void
+ _mesa_free_program_data(GLcontext *ctx)
+ {
+ #if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
+- if (ctx->VertexProgram.Current) {
+- ctx->VertexProgram.Current->Base.RefCount--;
+- if (ctx->VertexProgram.Current->Base.RefCount <= 0)
+- ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base));
+- }
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
+ #endif
+ #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
+- if (ctx->FragmentProgram.Current) {
+- ctx->FragmentProgram.Current->Base.RefCount--;
+- if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
+- ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
+- }
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
+ #endif
+ /* XXX probably move this stuff */
+ #if FEATURE_ATI_fragment_shader
+@@ -311,7 +304,7 @@ void
+ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
+ {
+ (void) ctx;
+- ASSERT(prog);
++ ASSERT(prog); assert(prog->RefCount==0);
+
+ if (prog == &_mesa_DummyProgram)
+ return;
+@@ -367,6 +360,59 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id)
+
+
+ /**
++ * Reference counting for vertex/fragment programs
++ */
++void
++_mesa_reference_program(GLcontext *ctx,
++ struct gl_program **ptr,
++ struct gl_program *prog)
++{
++ assert(ptr);
++ if (*ptr && prog) {
++ /* sanity check */
++ ASSERT((*ptr)->Target == prog->Target);
++ }
++ if (*ptr == prog) {
++ return; /* no change */
++ }
++ if (*ptr) {
++ GLboolean deleteFlag;
++
++ /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/
++#if 0
++ printf("Program %p %u 0x%x Refcount-- to %d\n",
++ *ptr, (*ptr)->Id, (*ptr)->Target, (*ptr)->RefCount - 1);
++#endif
++ ASSERT((*ptr)->RefCount > 0);
++ (*ptr)->RefCount--;
++
++ deleteFlag = ((*ptr)->RefCount == 0);
++ /*_glthread_UNLOCK_MUTEX((*ptr)->Mutex);*/
++
++ if (deleteFlag) {
++ ASSERT(ctx);
++ ctx->Driver.DeleteProgram(ctx, *ptr);
++ }
++
++ *ptr = NULL;
++ }
++
++ assert(!*ptr);
++ if (prog) {
++ /*_glthread_LOCK_MUTEX(prog->Mutex);*/
++ prog->RefCount++;
++#if 0
++ printf("Program %p %u 0x%x Refcount++ to %d\n",
++ prog, prog->Id, prog->Target, prog->RefCount);
++#endif
++ /*_glthread_UNLOCK_MUTEX(prog->Mutex);*/
++ }
++
++ *ptr = prog;
++}
++
++
++/**
+ * Return a copy of a program.
+ * XXX Problem here if the program object is actually OO-derivation
+ * made by a device driver.
+@@ -381,8 +427,9 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
+ return NULL;
+
+ assert(clone->Target == prog->Target);
++ assert(clone->RefCount == 1);
++
+ clone->String = (GLubyte *) _mesa_strdup((char *) prog->String);
+- clone->RefCount = 1;
+ clone->Format = prog->Format;
+ clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
+ if (!clone->Instructions) {
+@@ -514,9 +561,9 @@ _mesa_BindProgram(GLenum target, GLuint id)
+ /* Bind a default program */
+ newProg = NULL;
+ if (target == GL_VERTEX_PROGRAM_ARB) /* == GL_VERTEX_PROGRAM_NV */
+- newProg = ctx->Shared->DefaultVertexProgram;
++ newProg = &ctx->Shared->DefaultVertexProgram->Base;
+ else
+- newProg = ctx->Shared->DefaultFragmentProgram;
++ newProg = &ctx->Shared->DefaultFragmentProgram->Base;
+ }
+ else {
+ /* Bind a user program */
+@@ -544,26 +591,16 @@ _mesa_BindProgram(GLenum target, GLuint id)
+ return;
+ }
+
+- /* unbind/delete oldProg */
+- if (curProg->Id != 0) {
+- /* decrement refcount on previously bound fragment program */
+- curProg->RefCount--;
+- /* and delete if refcount goes below one */
+- if (curProg->RefCount <= 0) {
+- /* the program ID was already removed from the hash table */
+- ctx->Driver.DeleteProgram(ctx, curProg);
+- }
+- }
+-
+ /* bind newProg */
+ if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */
+- ctx->VertexProgram.Current = (struct gl_vertex_program *) newProg;
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
++ (struct gl_vertex_program *) newProg);
+ }
+ else if (target == GL_FRAGMENT_PROGRAM_NV ||
+ target == GL_FRAGMENT_PROGRAM_ARB) {
+- ctx->FragmentProgram.Current = (struct gl_fragment_program *) newProg;
++ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
++ (struct gl_fragment_program *) newProg);
+ }
+- newProg->RefCount++;
+
+ /* Never null pointers */
+ ASSERT(ctx->VertexProgram.Current);
+@@ -621,10 +658,7 @@ _mesa_DeletePrograms(GLsizei n, const GLuint *ids)
+ }
+ /* The ID is immediately available for re-use now */
+ _mesa_HashRemove(ctx->Shared->Programs, ids[i]);
+- prog->RefCount--;
+- if (prog->RefCount <= 0) {
+- ctx->Driver.DeleteProgram(ctx, prog);
+- }
++ _mesa_reference_program(ctx, &prog, NULL);
+ }
+ }
+ }
+diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h
+index ea2c8c3..9a6883e 100644
+--- a/src/mesa/shader/program.h
++++ b/src/mesa/shader/program.h
+@@ -86,6 +86,28 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog);
+ extern struct gl_program *
+ _mesa_lookup_program(GLcontext *ctx, GLuint id);
+
++extern void
++_mesa_reference_program(GLcontext *ctx,
++ struct gl_program **ptr,
++ struct gl_program *prog);
++
++static INLINE void
++_mesa_reference_vertprog(GLcontext *ctx,
++ struct gl_vertex_program **ptr,
++ struct gl_vertex_program *prog)
++{
++ _mesa_reference_program(ctx, (struct gl_program **) ptr,
++ (struct gl_program *) prog);
++}
++
++static INLINE void
++_mesa_reference_fragprog(GLcontext *ctx,
++ struct gl_fragment_program **ptr,
++ struct gl_fragment_program *prog)
++{
++ _mesa_reference_program(ctx, (struct gl_program **) ptr,
++ (struct gl_program *) prog);
++}
+
+ extern struct gl_program *
+ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog);
+diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
+index 01a237c..684d62d 100644
+--- a/src/mesa/shader/shader_api.c
++++ b/src/mesa/shader/shader_api.c
+@@ -79,8 +79,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx,
+ /* to prevent a double-free in the next call */
+ shProg->VertexProgram->Base.Parameters = NULL;
+ }
+- ctx->Driver.DeleteProgram(ctx, &shProg->VertexProgram->Base);
+- shProg->VertexProgram = NULL;
++ _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
+ }
+
+ if (shProg->FragmentProgram) {
+@@ -88,8 +87,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx,
+ /* to prevent a double-free in the next call */
+ shProg->FragmentProgram->Base.Parameters = NULL;
+ }
+- ctx->Driver.DeleteProgram(ctx, &shProg->FragmentProgram->Base);
+- shProg->FragmentProgram = NULL;
++ _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
+ }
+
+ if (shProg->Uniforms) {
+@@ -1098,6 +1096,8 @@ _mesa_link_program(GLcontext *ctx, GLuint program)
+ return;
+ }
+
++ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
++
+ _slang_link(ctx, program, shProg);
+ }
+
+diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
+index c8457fc..72fe999 100644
+--- a/src/mesa/shader/slang/slang_link.c
++++ b/src/mesa/shader/slang/slang_link.c
+@@ -516,19 +516,19 @@ _slang_link(GLcontext *ctx,
+ * changing src/dst registers after merging the uniforms and varying vars.
+ */
+ if (vertProg) {
+- shProg->VertexProgram
+- = vertex_program(_mesa_clone_program(ctx, &vertProg->Base));
++ _mesa_reference_vertprog(ctx, &shProg->VertexProgram,
++ vertex_program(_mesa_clone_program(ctx, &vertProg->Base)));
+ }
+ else {
+- shProg->VertexProgram = NULL;
++ _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
+ }
+
+ if (fragProg) {
+- shProg->FragmentProgram
+- = fragment_program(_mesa_clone_program(ctx, &fragProg->Base));
++ _mesa_reference_fragprog(ctx, &shProg->FragmentProgram,
++ fragment_program(_mesa_clone_program(ctx, &fragProg->Base)));
+ }
+ else {
+- shProg->FragmentProgram = NULL;
++ _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
+ }
+
+ if (shProg->VertexProgram)
+@@ -545,10 +545,12 @@ _slang_link(GLcontext *ctx,
+ if (shProg->VertexProgram) {
+ _mesa_free_parameter_list(shProg->VertexProgram->Base.Parameters);
+ shProg->VertexProgram->Base.Parameters = shProg->Uniforms;
++ assert(shProg->Uniforms);
+ }
+ if (shProg->FragmentProgram) {
+ _mesa_free_parameter_list(shProg->FragmentProgram->Base.Parameters);
+ shProg->FragmentProgram->Base.Parameters = shProg->Uniforms;
++ assert(shProg->Uniforms);
+ }
+
+ if (shProg->VertexProgram) {
+diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
+index 81f5caa..730798c 100644
+--- a/src/mesa/swrast/s_drawpix.c
++++ b/src/mesa/swrast/s_drawpix.c
+@@ -840,8 +840,10 @@ _swrast_DrawPixels( GLcontext *ctx,
+ _swrast_validate_derived( ctx );
+
+ pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+- if (!pixels)
++ if (!pixels) {
++ RENDER_FINISH(swrast,ctx);
+ return;
++ }
+
+ switch (format) {
+ case GL_STENCIL_INDEX:
+diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c
+index 3f49b40..547d5b9 100644
+--- a/src/mesa/swrast/s_texstore.c
++++ b/src/mesa/swrast/s_texstore.c
+@@ -305,7 +305,7 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+ }
+
+@@ -381,7 +381,7 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+ }
+
+@@ -450,7 +450,7 @@ _swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+ }
+
+@@ -526,7 +526,7 @@ _swrast_copy_texsubimage2d( GLcontext *ctx,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+ }
+
+@@ -599,6 +599,6 @@ _swrast_copy_texsubimage3d( GLcontext *ctx,
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
++ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+ }
+diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
+index baf283e..1ac508f 100644
+--- a/src/mesa/tnl/t_context.h
++++ b/src/mesa/tnl/t_context.h
+@@ -388,7 +388,7 @@ struct tnl_clipspace
+ struct tnl_cache_item {
+ GLuint hash;
+ void *key;
+- void *data;
++ struct gl_vertex_program *prog;
+ struct tnl_cache_item *next;
+ };
+
+diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c
+index a7fd815..2b1eefe 100644
+--- a/src/mesa/tnl/t_vp_build.c
++++ b/src/mesa/tnl/t_vp_build.c
+@@ -1464,21 +1464,22 @@ create_new_program( const struct state_key *key,
+ build_tnl_program( &p );
+ }
+
+-static void *search_cache( struct tnl_cache *cache,
+- GLuint hash,
+- const void *key,
+- GLuint keysize)
++
++static struct gl_vertex_program *
++search_cache(struct tnl_cache *cache, GLuint hash,
++ const void *key, GLuint keysize)
+ {
+ struct tnl_cache_item *c;
+
+ for (c = cache->items[hash % cache->size]; c; c = c->next) {
+ if (c->hash == hash && _mesa_memcmp(c->key, key, keysize) == 0)
+- return c->data;
++ return c->prog;
+ }
+
+ return NULL;
+ }
+
++
+ static void rehash( struct tnl_cache *cache )
+ {
+ struct tnl_cache_item **items;
+@@ -1501,15 +1502,16 @@ static void rehash( struct tnl_cache *cache )
+ cache->size = size;
+ }
+
+-static void cache_item( struct tnl_cache *cache,
++static void cache_item( GLcontext *ctx,
++ struct tnl_cache *cache,
+ GLuint hash,
+ void *key,
+- void *data )
++ struct gl_vertex_program *prog )
+ {
+- struct tnl_cache_item *c = (struct tnl_cache_item*) _mesa_malloc(sizeof(*c));
++ struct tnl_cache_item *c = CALLOC_STRUCT(tnl_cache_item);
+ c->hash = hash;
+ c->key = key;
+- c->data = data;
++ _mesa_reference_vertprog(ctx, &c->prog, prog);
+
+ if (++cache->n_items > cache->size * 1.5)
+ rehash(cache);
+@@ -1540,6 +1542,8 @@ void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
+
+ if (!ctx->VertexProgram._Current ||
+ ctx->VertexProgram._Current == ctx->VertexProgram._TnlProgram) {
++ struct gl_vertex_program *newProg;
++
+ /* Grab all the relevent state and put it in a single structure:
+ */
+ key = make_state_key(ctx);
+@@ -1547,33 +1551,31 @@ void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
+
+ /* Look for an already-prepared program for this state:
+ */
+- ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *)
+- search_cache( tnl->vp_cache, hash, key, sizeof(*key) );
++ newProg = search_cache( tnl->vp_cache, hash, key, sizeof(*key));
+
+ /* OK, we'll have to build a new one:
+ */
+- if (!ctx->VertexProgram._TnlProgram) {
++ if (!newProg) {
++
+ if (0)
+ _mesa_printf("Build new TNL program\n");
+
+- ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *)
++ newProg = (struct gl_vertex_program *)
+ ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
+
+- create_new_program( key, ctx->VertexProgram._TnlProgram,
+- ctx->Const.VertexProgram.MaxTemps );
++ create_new_program( key, newProg, ctx->Const.VertexProgram.MaxTemps );
+
+ if (ctx->Driver.ProgramStringNotify)
+ ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB,
+- &ctx->VertexProgram._TnlProgram->Base );
++ &newProg->Base );
+
+- cache_item(tnl->vp_cache, hash, key, ctx->VertexProgram._TnlProgram );
+- }
+- else {
+- FREE(key);
+- if (0)
+- _mesa_printf("Found existing TNL program for key %x\n", hash);
++ cache_item(ctx, tnl->vp_cache, hash, key, newProg);
++
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, newProg);
+ }
+- ctx->VertexProgram._Current = ctx->VertexProgram._TnlProgram;
++
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, newProg);
++ _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, newProg);
+ }
+
+ /* Tell the driver about the change. Could define a new target for
+@@ -1606,7 +1608,7 @@ void _tnl_ProgramCacheDestroy( GLcontext *ctx )
+ for (c = tnl->vp_cache->items[i]; c; c = next) {
+ next = c->next;
+ FREE(c->key);
+- FREE(c->data);
++ _mesa_reference_vertprog(ctx, &c->prog, NULL);
+ FREE(c);
+ }
+
diff --git a/mesa-7.1-f9-intel-and-radeon-fixes.patch b/mesa-7.1-f9-intel-and-radeon-fixes.patch
deleted file mode 100644
index 901670f..0000000
--- a/mesa-7.1-f9-intel-and-radeon-fixes.patch
+++ /dev/null
@@ -1,784 +0,0 @@
-commit fc35fb99411fc1bac92a7da9d90a16f28602623f
-Author: Dave Airlie <airlied@linux.ie>
-Date: Mon May 5 23:49:50 2008 +1000
-
- r300: fix swtcl texrect path properly.
-
- We really need to update the shader state so the texrect parameters work.
-
- This should fix compiz looking crappy on rs480 and rs690
- (cherry picked from commit 66a5562ce2906fbf5b96d1cee18f9a31a78c4360)
- (cherry picked from commit a7016949f27f7612ffba7a4d0c5e6280cb3e66ba)
-
-commit 5344028569e7c5fa7349685923c9ecc319c86fc6
-Author: Dave Airlie <airlied@linux.ie>
-Date: Sat May 3 21:31:22 2008 +1000
-
- r300: add R300_NO_TCL to allow testing of non-tcl on tcl cards
- (cherry picked from commit 026ef8111a94f6449dfa5e5cc0ae91fca4e68c0c)
- (cherry picked from commit 2f0a75f0040b0de339c78448844a7b18ab995c46)
-
-commit f232d553352fa8ace512564f371f623da4c08485
-Author: Markus Amsler <markus.amsler@oribi.org>
-Date: Fri May 2 01:58:18 2008 +0000
-
- r300: Set correct VAP_CNTL per vertex program.
- (cherry picked from commit acb47dee69a165f242d88f9eac60fc5646e33410)
-
-commit 135c59946a341e93f5e2a8f61a658d8c49ce2395
-Author: Brian Paul <brian.paul@tungstengraphics.com>
-Date: Thu May 1 14:59:34 2008 -0600
-
- fix conversion of GLfloat display list IDs
-
- Use floor() to convert to int (per Mark Kildard and the SI).
- Also, change translate_id() to return a signed integer since we may be
- offsetting from GL_LIST_BASE.
- (cherry picked from commit 6e19f82c37191dabcdd882d0edac98a2ca9c11e4)
-
-commit d8dc7982bc38a1e28a123d5f63736bb8deea134c
-Author: Brian Paul <brian.paul@tungstengraphics.com>
-Date: Wed Apr 30 16:05:01 2008 -0600
-
- Add support for GL_REPLACE_EXT texture env mode.
-
- GL_REPLACE_EXT comes from the ancient GL_EXT_texture extension. Found an old demo that
- actually uses it.
- The values of the GL_REPLACE and GL_REPLACE_EXT tokens is different, unfortunately.
- (cherry picked from commit 5f0fa82f68e3f4f7086ed6cf5616ef94820e19ee)
-
-commit 736cb42b9f6dc60ad83858bb6e244f5e9a0df3ef
-Author: Xiang, Haihao <haihao.xiang@intel.com>
-Date: Wed Apr 30 16:27:52 2008 +0800
-
- intel: test cpp to ensure mipmap tree matches texture image.
- (cherry picked from commit d12fa3511da23d8285f3ea1a51a1f328cdbb1462)
-
-commit 1bae58ce0dab2bc69b4467cae8cdc8a007c446ac
-Author: Brian Paul <brian.paul@tungstengraphics.com>
-Date: Tue Apr 29 15:02:46 2008 -0600
-
- disable GL_TEXTURE_1D at end of frame to fix failed assertion
- (cherry picked from commit aef4ca647d1d8275b1586a92485ea6c5bc8e950c)
-
-commit 2ec4728f9175e2184a2af009d7d2be1f191d35d9
-Author: Brian Paul <brian.paul@tungstengraphics.com>
-Date: Fri Apr 25 09:46:43 2008 -0600
-
- mesa: adjust glBitmap coords by a small epsilon
-
- Fixes problem with bitmaps jumping around by one pixel depending on window
- size. The rasterpos is often X.9999 instead of X+1.
- Run progs/redbook/drawf and resize window to check.
-
- Cherry picked from gallium-0.1 branch
- (cherry picked from commit 4e0e02ae684c0286599309ae166cfc716db940d7)
-
-commit 28b887a05543e67d0e40eb17502fcf590145022a
-Author: Ove Kaaven <ovek@arcticnet.no>
-Date: Tue Apr 29 22:14:05 2008 +0200
-
- r200: fix state submission issue causing bogus textures (bug 15730)
- (cherry picked from commit 4f474c7d1e1e6807af0f3db55f641fbd66be2e90)
-
-commit 52a964a87f5155bad582b2b48ff8ba8ca9669a69
-Author: Michel Dänzer <michel@tungstengraphics.com>
-Date: Tue Apr 29 18:43:28 2008 +0200
-
- Change default of driconf "allow_large_textures" to announce hardware limits.
-
- The previous default these days served mostly to cause artifical problems with
- GLX compositing managers like compiz (see e.g.
- http://bugs.freedesktop.org/show_bug.cgi?id=10501).
- (cherry picked from commit acba9c1771d653126fd6f604cb80c050b9e8ffb3)
-
-commit 98b53ad38218a4392f0dc070fd425f9cc61fdfa7
-Author: Keith Packard <keithp@keithp.com>
-Date: Fri Apr 25 16:07:12 2008 -0700
-
- [i965] short immediate values must be replicated to both halves of the dword
-
- The 32-bit immediate value in the i965 instruction word must contain two
- copies of any 16-bit constants. brw_imm_uw and brw_imm_w just needed to
- copy the value into both halves of the immediate value instruction field.
- (cherry picked from commit ca73488f48e3ee278f0185bb7dcc03d7bdedb62d)
-
-commit 5b77d659ef8d57b74b7ff2a8d1126808d9ee1de2
-Author: Pierre Beyssac <mesa-bugzilla@fasterix.frmug.org>
-Date: Thu Apr 24 16:29:34 2008 -0600
-
- enable GL_EXT_multi_draw_arrays (see bug 15670)
- (cherry picked from commit fddb0f6e4fa67f3d6940e10519560941b59f5a5e)
-
-commit 36de683cfa560c20ae7a068ed3906ccafc399b91
-Author: Xiang, Haihao <haihao.xiang@intel.com>
-Date: Tue Apr 22 16:25:23 2008 +0800
-
- i965: fix DEPTH_TEXTURE_MODE (bug #14220)
- (cherry picked from commit 6e620162a1b235ade227368b87fa993e844d7077)
-
-commit 7786e8a122717c1f68e943994ed99fda697f29dc
-Author: Zou Nan hai <nanhai.zou@intel.com>
-Date: Tue Apr 22 15:50:40 2008 +0800
-
- [i965] This is to fix random crash in some maps of Ut2004 demo.
- e.g. bridge of fate.
- If vs output is big, driver may fall back to use 8 urb entries for vs,
- unfortunally, for some unknown reason, if vs is working at 4x2 mode,
- 8 entries is not enough, may lead to gpu hang.
- (cherry picked from commit c9c64a100d5d0661fd672af040a68bd4e7292940)
-
-commit b557beb6572e5662a21375b6aa9e25df4fa4dc34
-Author: Xiang, Haihao <haihao.xiang@intel.com>
-Date: Tue Apr 22 11:11:42 2008 +0800
-
- i965: save the offset of target buffer after last execution, not relocatee buffer.
- (cherry picked from commit f61e51ee98a2f43ad61e98353eae2cd8dc8a272f)
-
-commit 96aff7d90e5404bb8b023fcae676c2de78829eb3
-Author: Xiang, Haihao <haihao.xiang@intel.com>
-Date: Mon Apr 21 17:34:00 2008 +0800
-
- intel: fix an assertion failure. fix bug #15575
- (cherry picked from commit 7c2a3fced8bbf0915ee4160c23b1752917c1e69d)
-
-commit e82b0a1a63d6438328d0821d271bbf9946e7a96c
-Author: Xiang, Haihao <haihao.xiang@intel.com>
-Date: Mon Apr 21 14:02:50 2008 +0800
-
- i965: clear the PRESUMED_OFFSET flag from bo_req.hint, not bo_req.flags. fix #15574
- (cherry picked from commit 33107357a1226b9218fac410a7502a981aac5cc5)
-
-commit 6c33450bfdb38592ea77dd2ff65d522b47bcaa41
-Author: Dave Airlie <airlied@panoply-rh.(none)>
-Date: Fri Apr 18 15:37:54 2008 +1000
-
- i965: fixup depth buffer check
- (cherry picked from commit 27e06a52342b94b4fb1d60a57c3bdaa2b30607cf)
-diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c
-index c2d40bd..b6bdbe4 100644
---- a/progs/demos/shadowtex.c
-+++ b/progs/demos/shadowtex.c
-@@ -658,6 +658,7 @@ Display(void)
- glDisable(GL_FRAGMENT_PROGRAM_ARB);
- }
-
-+ glDisable(GL_TEXTURE_1D);
- glDisable(GL_TEXTURE_2D);
- }
-
-diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
-index 25f1f89..c138d15 100644
---- a/src/mesa/drivers/dri/i965/brw_eu.h
-+++ b/src/mesa/drivers/dri/i965/brw_eu.h
-@@ -335,14 +335,14 @@ static __inline struct brw_reg brw_imm_ud( GLuint ud )
- static __inline struct brw_reg brw_imm_uw( GLushort uw )
- {
- struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
-- imm.dw1.ud = uw;
-+ imm.dw1.ud = uw | (uw << 16);
- return imm;
- }
-
- static __inline struct brw_reg brw_imm_w( GLshort w )
- {
- struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
-- imm.dw1.d = w;
-+ imm.dw1.d = w | (w << 16);
- return imm;
- }
-
-diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
-index ec0bd6b..26ec797 100644
---- a/src/mesa/drivers/dri/i965/brw_misc_state.c
-+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
-@@ -183,7 +183,7 @@ static int prepare_depthbuffer(struct brw_context *brw)
- {
- struct intel_region *region = brw->state.depth_region;
-
-- if (region->buffer)
-+ if (!region || !region->buffer)
- return 0;
- return dri_bufmgr_check_aperture_space(region->buffer);
- }
-diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c
-index 4b03838..c423dbe 100644
---- a/src/mesa/drivers/dri/i965/brw_urb.c
-+++ b/src/mesa/drivers/dri/i965/brw_urb.c
-@@ -52,7 +52,7 @@ static const struct {
- GLuint min_entry_size;
- GLuint max_entry_size;
- } limits[CS+1] = {
-- { 8, 32, 1, 5 }, /* vs */
-+ { 16, 32, 1, 5 }, /* vs */
- { 4, 8, 1, 5 }, /* gs */
- { 6, 8, 1, 5 }, /* clp */
- { 1, 8, 1, 12 }, /* sf */
-diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
-index a02f70a..4cda559 100644
---- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
-+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
-@@ -724,9 +724,6 @@ static void emit_tex( struct brw_wm_compile *c,
- responseLength,
- msgLength,
- 0);
--
-- if (shadow)
-- brw_MOV(p, dst[3], brw_imm_f(1.0));
- }
-
-
-diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
-index eff4555..0d91391 100644
---- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
-+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
-@@ -69,7 +69,7 @@ static GLuint translate_tex_target( GLenum target )
- }
-
-
--static GLuint translate_tex_format( GLuint mesa_format )
-+static GLuint translate_tex_format( GLuint mesa_format, GLenum depth_mode )
- {
- switch( mesa_format ) {
- case MESA_FORMAT_L8:
-@@ -114,7 +114,12 @@ static GLuint translate_tex_format( GLuint mesa_format )
- return BRW_SURFACEFORMAT_FXT1;
-
- case MESA_FORMAT_Z16:
-- return BRW_SURFACEFORMAT_I16_UNORM;
-+ if (depth_mode == GL_INTENSITY)
-+ return BRW_SURFACEFORMAT_I16_UNORM;
-+ else if (depth_mode == GL_ALPHA)
-+ return BRW_SURFACEFORMAT_A16_UNORM;
-+ else
-+ return BRW_SURFACEFORMAT_L16_UNORM;
-
- case MESA_FORMAT_RGB_DXT1:
- return BRW_SURFACEFORMAT_DXT1_RGB;
-@@ -143,7 +148,7 @@ static GLuint translate_tex_format( GLuint mesa_format )
- }
-
- struct brw_wm_surface_key {
-- GLenum target;
-+ GLenum target, depthmode;
- dri_bo *bo;
- GLint format;
- GLint first_level, last_level;
-@@ -163,7 +168,7 @@ brw_create_texture_surface( struct brw_context *brw,
-
- surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
- surf.ss0.surface_type = translate_tex_target(key->target);
-- surf.ss0.surface_format = translate_tex_format(key->format);
-+ surf.ss0.surface_format = translate_tex_format(key->format, key->depthmode);
-
- /* This is ok for all textures with channel width 8bit or less:
- */
-@@ -219,6 +224,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
-
- memset(&key, 0, sizeof(key));
- key.target = tObj->Target;
-+ key.depthmode = tObj->DepthMode;
- key.format = firstImage->TexFormat->MesaFormat;
- key.bo = intelObj->mt->region->buffer;
- key.first_level = intelObj->firstLevel;
-diff --git a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c
-index 6828425..545913f 100644
---- a/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c
-+++ b/src/mesa/drivers/dri/intel/intel_bufmgr_ttm.c
-@@ -889,7 +889,7 @@ dri_ttm_bo_process_reloc(dri_bo *bo)
- struct intel_validate_entry *entry =
- &bufmgr_ttm->validate_array[target_buf_ttm->validate_index];
-
-- entry->bo_arg.d.req.bo_req.flags &= ~DRM_BO_HINT_PRESUMED_OFFSET;
-+ entry->bo_arg.d.req.bo_req.hint &= ~DRM_BO_HINT_PRESUMED_OFFSET;
- }
- }
- }
-@@ -993,7 +993,7 @@ dri_ttm_bo_post_submit(dri_bo *bo)
- /* Continue walking the tree depth-first. */
- dri_ttm_bo_post_submit(r->target_buf);
-
-- r->last_target_offset = bo->offset;
-+ r->last_target_offset = r->target_buf->offset;
- }
- }
-
-diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
-index 55503f4..9205627 100644
---- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
-+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
-@@ -272,6 +272,11 @@ intel_miptree_match_image(struct intel_mipmap_tree *mt,
- image->IsCompressed != mt->compressed)
- return GL_FALSE;
-
-+ if (!image->IsCompressed &&
-+ !mt->compressed &&
-+ image->TexFormat->TexelBytes != mt->cpp)
-+ return GL_FALSE;
-+
- /* Test image dimensions against the base level image adjusted for
- * minification. This will also catch images not present in the
- * tree, changed targets, etc.
-diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
-index 5aeb2a1..52e062e 100644
---- a/src/mesa/drivers/dri/intel/intel_screen.c
-+++ b/src/mesa/drivers/dri/intel/intel_screen.c
-@@ -68,7 +68,7 @@ PUBLIC const char __driConfigOptions[] =
- DRI_CONF_SECTION_END
- DRI_CONF_SECTION_QUALITY
- DRI_CONF_FORCE_S3TC_ENABLE(false)
-- DRI_CONF_ALLOW_LARGE_TEXTURES(1)
-+ DRI_CONF_ALLOW_LARGE_TEXTURES(2)
- DRI_CONF_SECTION_END
- DRI_CONF_SECTION_DEBUG
- DRI_CONF_NO_RAST(false)
-diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
-index a56a395..bcb6583 100644
---- a/src/mesa/drivers/dri/intel/intel_tex_image.c
-+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
-@@ -348,8 +348,10 @@ intelTexImage(GLcontext * ctx,
- postConvWidth = 32 / texelBytes;
- texImage->RowStride = postConvWidth;
- }
--
-- assert(texImage->RowStride == postConvWidth);
-+
-+ if (!intelImage->mt) {
-+ assert(texImage->RowStride == postConvWidth);
-+ }
- }
-
- /* Release the reference to a potentially orphaned buffer.
-diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
-index 20c1107..c567349 100644
---- a/src/mesa/drivers/dri/r200/r200_context.c
-+++ b/src/mesa/drivers/dri/r200/r200_context.c
-@@ -69,6 +69,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- #define need_GL_ATI_fragment_shader
- #define need_GL_EXT_blend_minmax
- #define need_GL_EXT_fog_coord
-+#define need_GL_EXT_multi_draw_arrays
- #define need_GL_EXT_secondary_color
- #define need_GL_EXT_blend_equation_separate
- #define need_GL_EXT_blend_func_separate
-@@ -132,6 +133,7 @@ const struct dri_extension card_extensions[] =
- { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
- { "GL_EXT_blend_subtract", NULL },
- { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
-+ { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
- { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
- { "GL_EXT_stencil_wrap", NULL },
- { "GL_EXT_texture_edge_clamp", NULL },
-diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c
-index 05ff595..4edf304 100644
---- a/src/mesa/drivers/dri/r200/r200_texstate.c
-+++ b/src/mesa/drivers/dri/r200/r200_texstate.c
-@@ -1815,6 +1815,12 @@ void r200UpdateTextureState( GLcontext *ctx )
- GLboolean ok;
- GLuint dbg;
-
-+ /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or
-+ rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since
-+ we use these to determine if we want to emit the corresponding state
-+ atoms. */
-+ R200_NEWPRIM( rmesa );
-+
- if (ctx->ATIFragmentShader._Enabled) {
- GLuint i;
- for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
-diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
-index d2ed310..c56a762 100644
---- a/src/mesa/drivers/dri/r300/r300_context.c
-+++ b/src/mesa/drivers/dri/r300/r300_context.c
-@@ -84,6 +84,7 @@ int hw_tcl_on = 1;
- #define need_GL_ARB_vertex_program
- #define need_GL_EXT_blend_minmax
- //#define need_GL_EXT_fog_coord
-+#define need_GL_EXT_multi_draw_arrays
- #define need_GL_EXT_secondary_color
- #define need_GL_EXT_blend_equation_separate
- #define need_GL_EXT_blend_func_separate
-@@ -112,6 +113,7 @@ const struct dri_extension card_extensions[] = {
- {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
- {"GL_EXT_blend_subtract", NULL},
- // {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
-+ {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
- {"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions},
- {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
- {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
-diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
-index 1b40588..baa7418 100644
---- a/src/mesa/drivers/dri/r300/r300_ioctl.c
-+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
-@@ -316,6 +316,14 @@ static void r300EmitClearState(GLcontext * ctx)
- e32(FP_SELA(0, NO, W, FP_TMP(0), 0, 0));
-
- if (has_tcl) {
-+ R300_STATECHANGE(rmesa, vap_cntl);
-+ reg_start(R300_VAP_CNTL, 0);
-+
-+ e32((10 << R300_VAP_CNTL__PVS_NUM_SLOTS__SHIFT) |
-+ (6 << R300_VAP_CNTL__PVS_NUM_CNTRLS__SHIFT) |
-+ (4 << R300_VAP_CNTL__PVS_NUM_FPUS__SHIFT) |
-+ (12 << R300_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
-+
- R300_STATECHANGE(r300, pvs);
- reg_start(R300_VAP_PVS_CNTL_1, 2);
-
-diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
-index 2200cec..d2a8175 100644
---- a/src/mesa/drivers/dri/r300/r300_reg.h
-+++ b/src/mesa/drivers/dri/r300/r300_reg.h
-@@ -67,9 +67,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- /*
- * Vertex Array Processing (VAP) Control
-- * Stolen from r200 code from Christoph Brill (It's a guess!)
- */
- #define R300_VAP_CNTL 0x2080
-+# define R300_VAP_CNTL__PVS_NUM_SLOTS__SHIFT 0
-+# define R300_VAP_CNTL__PVS_NUM_CNTRLS__SHIFT 4
-+# define R300_VAP_CNTL__PVS_NUM_FPUS__SHIFT 8
-+# define R300_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 18
-+# define R500_VAP_CNTL__VAP_NO_RENDER (1<<17)
-+# define R300_VAP_CNTL__DX_CLIP_SPACE_DEF (1<<22)
-+# define R500_VAP_CNTL__TCL_STATE_OPTIMIZATION (1<<23)
-
- /* This register is written directly and also starts data section
- * in many 3d CP_PACKET3's
-diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
-index e11b5af..aa0de4e 100644
---- a/src/mesa/drivers/dri/r300/r300_state.c
-+++ b/src/mesa/drivers/dri/r300/r300_state.c
-@@ -1648,10 +1648,51 @@ static inline void r300SetupVertexProgramFragment(r300ContextPtr r300, int dest,
- }
- }
-
-+/* FIXME: move near the MIN2 define. */
-+#define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
-+
-+/* FIXME: need to add a structure for per-card/chipset values; they are
-+ * currently hard-coded. */
-+static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count,
-+ GLuint output_count, GLuint temp_count)
-+{
-+ int cmd_reserved = 0;
-+ int cmd_written = 0;
-+ drm_radeon_cmd_header_t *cmd = NULL;
-+
-+ int vtx_mem_size = 72; /* FIXME: R3XX vs R5XX */
-+
-+ /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
-+ * See r500 docs 6.5.2 */
-+ reg_start(R300_VAP_PVS_WAITIDLE, 0);
-+ e32(0x00000000);
-+
-+ /* avoid division by zero */
-+ if (input_count == 0)
-+ input_count = 1;
-+ if (output_count == 0)
-+ output_count = 1;
-+ if (temp_count == 0)
-+ temp_count = 1;
-+
-+ int pvs_num_slots =
-+ MIN3(10, vtx_mem_size / input_count, vtx_mem_size / output_count);
-+ int pvs_num_cntrls = MIN2(6, vtx_mem_size / temp_count);
-+
-+ R300_STATECHANGE(rmesa, vap_cntl);
-+ rmesa->hw.vap_cntl.cmd[1] =
-+ (pvs_num_slots << R300_VAP_CNTL__PVS_NUM_SLOTS__SHIFT) |
-+ (pvs_num_cntrls << R300_VAP_CNTL__PVS_NUM_CNTRLS__SHIFT) |
-+ (4 << R300_VAP_CNTL__PVS_NUM_FPUS__SHIFT) |
-+ (12 << R300_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT) |
-+ R500_VAP_CNTL__TCL_STATE_OPTIMIZATION;
-+}
-+
- static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
- {
- struct r300_vertex_shader_state *prog = &(rmesa->state.vertex_shader);
- GLuint o_reg = 0;
-+ GLuint i_reg = 0;
- int i;
- int inst_count = 0;
- int param_count = 0;
-@@ -1664,6 +1705,7 @@ static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
- prog->program.body.i[program_end + 2] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
- prog->program.body.i[program_end + 3] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
- program_end += 4;
-+ i_reg++;
- }
- }
-
-@@ -1673,6 +1715,8 @@ static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
- &(prog->program));
- inst_count = (prog->program.length / 4) - 1;
-
-+ r300VapCntl(rmesa, i_reg, o_reg, 0);
-+
- R300_STATECHANGE(rmesa, pvs);
- rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
- (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
-@@ -1686,6 +1730,15 @@ static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
- (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT);
- }
-
-+static int r300BitCount(int x)
-+{
-+ x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U);
-+ x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U);
-+ x = (x >> 16) + (x & 0xffff);
-+ x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f);
-+ return (x >> 8) + (x & 0x00ff);
-+}
-+
- static void r300SetupRealVertexProgram(r300ContextPtr rmesa)
- {
- GLcontext *ctx = rmesa->radeon.glCtx;
-@@ -1707,6 +1760,10 @@ static void r300SetupRealVertexProgram(r300ContextPtr rmesa)
- r300SetupVertexProgramFragment(rmesa, R300_PVS_UPLOAD_PROGRAM, &(prog->program));
- inst_count = (prog->program.length / 4) - 1;
-
-+ r300VapCntl(rmesa, r300BitCount(prog->key.InputsRead),
-+ r300BitCount(prog->key.OutputsWritten),
-+ prog->num_temporaries);
-+
- R300_STATECHANGE(rmesa, pvs);
- rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
- (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
-@@ -1740,13 +1797,6 @@ static void r300SetupVertexProgram(r300ContextPtr rmesa)
- r300SetupDefaultVertexProgram(rmesa);
- }
-
--
-- /* FIXME: This is done for vertex shader fragments, but also needs to be
-- * done for vap_pvs, so I leave it as a reminder. */
--#if 0
-- reg_start(R300_VAP_PVS_WAITIDLE, 0);
-- e32(0x00000000);
--#endif
- }
-
- /**
-@@ -1848,11 +1898,6 @@ static void r300ResetHwState(r300ContextPtr r300)
- r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
- r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
-
-- if (!has_tcl)
-- r300->hw.vap_cntl.cmd[1] = 0x0014045a;
-- else
-- r300->hw.vap_cntl.cmd[1] = 0x0030045A; //0x0030065a /* Dangerous */
--
- r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
- | R300_VPORT_X_OFFSET_ENA
- | R300_VPORT_Y_SCALE_ENA
-@@ -2084,10 +2129,11 @@ void r300UpdateShaders(r300ContextPtr rmesa)
- hw_tcl_on = future_hw_tcl_on = 0;
- r300ResetHwState(rmesa);
-
-+ r300UpdateStateParameters(ctx, _NEW_PROGRAM);
- return;
- }
-- r300UpdateStateParameters(ctx, _NEW_PROGRAM);
- }
-+ r300UpdateStateParameters(ctx, _NEW_PROGRAM);
- }
-
- static void r300SetupPixelShader(r300ContextPtr rmesa)
-diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c
-index a732bdb..1452ed5 100644
---- a/src/mesa/drivers/dri/r300/r300_swtcl.c
-+++ b/src/mesa/drivers/dri/r300/r300_swtcl.c
-@@ -591,6 +591,7 @@ static void r300RenderStart(GLcontext *ctx)
- r300ChooseRenderState(ctx);
- r300SetVertexFormat(ctx);
-
-+ r300UpdateShaders(rmesa);
- r300UpdateShaderStates(rmesa);
-
- r300EmitCacheFlush(rmesa);
-diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
-index 27d233c..5cf7f89 100644
---- a/src/mesa/drivers/dri/radeon/radeon_screen.c
-+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
-@@ -90,7 +90,7 @@ DRI_CONF_BEGIN
- DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
- DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
- DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
-- DRI_CONF_ALLOW_LARGE_TEXTURES(1)
-+ DRI_CONF_ALLOW_LARGE_TEXTURES(2)
- DRI_CONF_SECTION_END
- DRI_CONF_SECTION_DEBUG
- DRI_CONF_NO_RAST(false)
-@@ -117,7 +117,7 @@ DRI_CONF_BEGIN
- DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
- DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
- DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
-- DRI_CONF_ALLOW_LARGE_TEXTURES(1)
-+ DRI_CONF_ALLOW_LARGE_TEXTURES(2)
- DRI_CONF_TEXTURE_BLEND_QUALITY(1.0,"0.0:1.0")
- DRI_CONF_SECTION_END
- DRI_CONF_SECTION_DEBUG
-@@ -697,6 +697,9 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
- return NULL;
- }
-
-+ if (getenv("R300_NO_TCL"))
-+ screen->chip_flags &= ~RADEON_CHIPSET_TCL;
-+
- if (screen->chip_family <= CHIP_FAMILY_RS200)
- screen->chip_flags |= RADEON_CLASS_R100;
- else if (screen->chip_family <= CHIP_FAMILY_RV280)
-diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
-index 8d10d8a..23ede7b 100644
---- a/src/mesa/main/dlist.c
-+++ b/src/mesa/main/dlist.c
-@@ -611,9 +611,9 @@ destroy_list(GLcontext *ctx, GLuint list)
-
-
- /*
-- * Translate the nth element of list from type to GLuint.
-+ * Translate the nth element of list from <type> to GLint.
- */
--static GLuint
-+static GLint
- translate_id(GLsizei n, GLenum type, const GLvoid * list)
- {
- GLbyte *bptr;
-@@ -627,37 +627,40 @@ translate_id(GLsizei n, GLenum type, const GLvoid * list)
- switch (type) {
- case GL_BYTE:
- bptr = (GLbyte *) list;
-- return (GLuint) *(bptr + n);
-+ return (GLint) bptr[n];
- case GL_UNSIGNED_BYTE:
- ubptr = (GLubyte *) list;
-- return (GLuint) *(ubptr + n);
-+ return (GLint) ubptr[n];
- case GL_SHORT:
- sptr = (GLshort *) list;
-- return (GLuint) *(sptr + n);
-+ return (GLint) sptr[n];
- case GL_UNSIGNED_SHORT:
- usptr = (GLushort *) list;
-- return (GLuint) *(usptr + n);
-+ return (GLint) usptr[n];
- case GL_INT:
- iptr = (GLint *) list;
-- return (GLuint) *(iptr + n);
-+ return iptr[n];
- case GL_UNSIGNED_INT:
- uiptr = (GLuint *) list;
-- return (GLuint) *(uiptr + n);
-+ return (GLint) uiptr[n];
- case GL_FLOAT:
- fptr = (GLfloat *) list;
-- return (GLuint) *(fptr + n);
-+ return (GLint) FLOORF(fptr[n]);
- case GL_2_BYTES:
- ubptr = ((GLubyte *) list) + 2 * n;
-- return (GLuint) *ubptr * 256 + (GLuint) * (ubptr + 1);
-+ return (GLint) ubptr[0] * 256
-+ + (GLint) ubptr[1];
- case GL_3_BYTES:
- ubptr = ((GLubyte *) list) + 3 * n;
-- return (GLuint) * ubptr * 65536
-- + (GLuint) *(ubptr + 1) * 256 + (GLuint) * (ubptr + 2);
-+ return (GLint) ubptr[0] * 65536
-+ + (GLint) ubptr[1] * 256
-+ + (GLint) ubptr[2];
- case GL_4_BYTES:
- ubptr = ((GLubyte *) list) + 4 * n;
-- return (GLuint) *ubptr * 16777216
-- + (GLuint) *(ubptr + 1) * 65536
-- + (GLuint) *(ubptr + 2) * 256 + (GLuint) * (ubptr + 3);
-+ return (GLint) ubptr[0] * 16777216
-+ + (GLint) ubptr[1] * 65536
-+ + (GLint) ubptr[2] * 256
-+ + (GLint) ubptr[3];
- default:
- return 0;
- }
-@@ -992,10 +995,10 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
- }
-
- for (i = 0; i < n; i++) {
-- GLuint list = translate_id(i, type, lists);
-+ GLint list = translate_id(i, type, lists);
- Node *n = ALLOC_INSTRUCTION(ctx, OPCODE_CALL_LIST_OFFSET, 2);
- if (n) {
-- n[1].ui = list;
-+ n[1].i = list;
- n[2].b = typeErrorFlag;
- }
- }
-@@ -5774,7 +5777,8 @@ execute_list(GLcontext *ctx, GLuint list)
- _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)");
- }
- else if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
-- execute_list(ctx, ctx->List.ListBase + n[1].ui);
-+ GLuint list = (GLuint) (ctx->List.ListBase + n[1].i);
-+ execute_list(ctx, list);
- }
- break;
- case OPCODE_CLEAR:
-@@ -6822,7 +6826,6 @@ void GLAPIENTRY
- _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
- {
- GET_CURRENT_CONTEXT(ctx);
-- GLuint list;
- GLint i;
- GLboolean save_compile_flag;
-
-@@ -6854,8 +6857,8 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
- ctx->CompileFlag = GL_FALSE;
-
- for (i = 0; i < n; i++) {
-- list = translate_id(i, type, lists);
-- execute_list(ctx, ctx->List.ListBase + list);
-+ GLuint list = (GLuint) (ctx->List.ListBase + translate_id(i, type, lists));
-+ execute_list(ctx, list);
- }
-
- ctx->CompileFlag = save_compile_flag;
-diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
-index 4f28766..fde9338 100644
---- a/src/mesa/main/drawpix.c
-+++ b/src/mesa/main/drawpix.c
-@@ -374,8 +374,9 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
-
- if (ctx->RenderMode == GL_RENDER) {
- /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
-- GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
-- GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
-+ const GLfloat epsilon = 0.0001;
-+ GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig);
-+ GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig);
-
- if (ctx->Unpack.BufferObj->Name) {
- /* unpack from PBO */
-diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
-index 288b334..626c264 100644
---- a/src/mesa/main/texstate.c
-+++ b/src/mesa/main/texstate.c
-@@ -213,6 +213,9 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state,
- return;
- }
-
-+ if (mode == GL_REPLACE_EXT)
-+ mode = GL_REPLACE;
-+
- switch (mode) {
- case GL_REPLACE:
- case GL_MODULATE:
-@@ -315,7 +318,9 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
- switch (pname) {
- case GL_TEXTURE_ENV_MODE:
- {
-- const GLenum mode = (GLenum) (GLint) *param;
-+ GLenum mode = (GLenum) (GLint) *param;
-+ if (mode == GL_REPLACE_EXT)
-+ mode = GL_REPLACE;
- if (texUnit->EnvMode == mode)
- return;
- if (mode == GL_MODULATE ||
diff --git a/mesa-7.1-fix-965-googleearth.patch b/mesa-7.1-fix-965-googleearth.patch
deleted file mode 100644
index a081d11..0000000
--- a/mesa-7.1-fix-965-googleearth.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-commit 17adf04e5c1da72a51815f3fdb9de2f3a8149c1a
-Author: Dave Airlie <airlied@panoply-rh.(none)>
-Date: Tue May 6 18:52:47 2008 +1000
-
- i965: fix googleearth in classic mode.
-
- In classic mode googleearth triggered a case where vbos weren't getting accounted properly.
-
-diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
-index aa985d6..2d99238 100644
---- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
-+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
-@@ -404,6 +404,7 @@ int brw_prepare_vertices( struct brw_context *brw,
- */
- copy_array_to_vbo_array(brw, upload[0], interleave);
-
-+ ret |= dri_bufmgr_check_aperture_space(upload[0]->bo);
- for (i = 1; i < nr_uploads; i++) {
- /* Then, just point upload[i] at upload[0]'s buffer. */
- upload[i]->stride = interleave;
-@@ -416,13 +417,13 @@ int brw_prepare_vertices( struct brw_context *brw,
- else {
- /* Upload non-interleaved arrays */
- for (i = 0; i < nr_uploads; i++) {
-- copy_array_to_vbo_array(brw, upload[i], upload[i]->element_size);
-+ copy_array_to_vbo_array(brw, upload[i], upload[i]->element_size);
-+ if (upload[i]->bo) {
-+ ret |= dri_bufmgr_check_aperture_space(upload[i]->bo);
-+ }
- }
- }
-
-- if (brw->vb.upload.bo) {
-- ret |= dri_bufmgr_check_aperture_space(brw->vb.upload.bo);
-- }
-
- if (ret)
- return 1;
diff --git a/mesa.spec b/mesa.spec
index 5a14652..10b530f 100644
--- a/mesa.spec
+++ b/mesa.spec
@@ -15,7 +15,7 @@
Summary: Mesa graphics libraries
Name: mesa
Version: 7.1
-Release: 0.30%{?dist}
+Release: 0.31%{?dist}
License: MIT
Group: System Environment/Libraries
URL: http://www.mesa3d.org
@@ -38,8 +38,7 @@ Patch7: mesa-7.1-link-shared.patch
# lets only build drivers on sparc that are remotely useful
Patch8: mesa-7.1-sparc.patch
-Patch10: mesa-7.1-f9-intel-and-radeon-fixes.patch
-Patch11: mesa-7.1-fix-965-googleearth.patch
+Patch10: mesa-7.1-bag-of-fixes.patch
Patch12: mesa-7.1-disable-intel-classic-warn.patch
BuildRequires: pkgconfig autoconf automake
@@ -170,7 +169,6 @@ This package provides some demo applications for testing Mesa.
%patch7 -p1 -b .dricore
%patch8 -p1
%patch10 -p1 -b .misc-fixes
-%patch11 -p1 -b .965-googleearth
%patch12 -p1 -b .intel-nowarn
# WARNING: The following files are copyright "Mark J. Kilgard" under the GLUT
@@ -420,6 +418,10 @@ rm -rf $RPM_BUILD_ROOT
%{_libdir}/mesa-demos-data
%changelog
+* Sat May 10 2008 Dave Airlie <airlied@redhat.com> 7.1-0.31
+- Bring in a bunch of fixes from upstream, missing rs690 pci id,
+- DRI2 + modeset + 965 + compiz + alt-tab fixed.
+
* Wed May 07 2008 Dave Airlie <airlied@redhat.com> 7.1-0.30
- fix googleearth on Intel 965 (#443930)
- disable classic warning to avoid people reporting it.