diff --git a/.gitignore b/.gitignore
index 544de56..eb6bf92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,4 @@ mesa-20100720.tar.bz2
/MesaLib-8.0.1.tar.bz2
/MesaLib-8.0.2.tar.bz2
/MesaLib-8.0.3.tar.bz2
+/MesaLib-8.0.4.tar.bz2
diff --git a/mesa-8.0.1-git.patch b/mesa-8.0.1-git.patch
deleted file mode 100644
index 62a320a..0000000
--- a/mesa-8.0.1-git.patch
+++ /dev/null
@@ -1,265 +0,0 @@
-diff --git a/docs/relnotes-8.0.1.html b/docs/relnotes-8.0.1.html
-index 8c8cd3f..29a314c 100644
---- a/docs/relnotes-8.0.1.html
-+++ b/docs/relnotes-8.0.1.html
-@@ -28,7 +28,9 @@ for DRI hardware acceleration.
-
-
MD5 checksums
-
--tdb
-+4855c2d93bd2ebd43f384bdcc92c9a27 MesaLib-8.0.1.tar.gz
-+24eeebf66971809d8f40775a379b36c9 MesaLib-8.0.1.tar.bz2
-+54e745d14dac5717f7f65b4e2d5c1df2 MesaLib-8.0.1.zip
-
-
- New features
-diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c
-index 0461c81..7afcf14 100644
---- a/src/gallium/auxiliary/rtasm/rtasm_cpu.c
-+++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c
-@@ -25,43 +25,43 @@
- *
- **************************************************************************/
-
-+#include "pipe/p_config.h"
-+#include "rtasm_cpu.h"
-+
-+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
-
- #include "util/u_debug.h"
--#include "rtasm_cpu.h"
-+#include "util/u_cpu_detect.h"
-
-+DEBUG_GET_ONCE_BOOL_OPTION(nosse, "GALLIUM_NOSSE", FALSE);
-
--#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
--static boolean rtasm_sse_enabled(void)
-+static struct util_cpu_caps *get_cpu_caps(void)
- {
-- static boolean firsttime = 1;
-- static boolean enabled;
--
-- /* This gets called quite often at the moment:
-- */
-- if (firsttime) {
-- enabled = !debug_get_bool_option("GALLIUM_NOSSE", FALSE);
-- firsttime = FALSE;
-- }
-- return enabled;
-+ util_cpu_detect();
-+ return &util_cpu_caps;
- }
--#endif
-
- int rtasm_cpu_has_sse(void)
- {
-- /* FIXME: actually detect this at run-time */
--#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
-- return rtasm_sse_enabled();
--#else
-- return 0;
--#endif
-+ return !debug_get_option_nosse() && get_cpu_caps()->has_sse;
- }
-
- int rtasm_cpu_has_sse2(void)
- {
-- /* FIXME: actually detect this at run-time */
--#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
-- return rtasm_sse_enabled();
-+ return !debug_get_option_nosse() && get_cpu_caps()->has_sse2;
-+}
-+
-+
- #else
-+
-+int rtasm_cpu_has_sse(void)
-+{
- return 0;
--#endif
- }
-+
-+int rtasm_cpu_has_sse2(void)
-+{
-+ return 0;
-+}
-+
-+#endif
-diff --git a/src/gallium/drivers/r300/compiler/radeon_program_alu.c b/src/gallium/drivers/r300/compiler/radeon_program_alu.c
-index dd1dfb3..c48f936 100644
---- a/src/gallium/drivers/r300/compiler/radeon_program_alu.c
-+++ b/src/gallium/drivers/r300/compiler/radeon_program_alu.c
-@@ -1165,35 +1165,79 @@ int radeonTransformDeriv(struct radeon_compiler* c,
- }
-
- /**
-+ * IF Temp[0].x -> IF Temp[0].x
-+ * ... -> ...
-+ * KILP -> KIL -abs(Temp[0].x)
-+ * ... -> ...
-+ * ENDIF -> ENDIF
-+ *
-+ * === OR ===
-+ *
- * IF Temp[0].x -\
- * KILP - > KIL -abs(Temp[0].x)
- * ENDIF -/
- *
-- * This needs to be done in its own pass, because it modifies the instructions
-- * before and after KILP.
-+ * === OR ===
-+ *
-+ * IF Temp[0].x -> IF Temp[0].x
-+ * ... -> ...
-+ * ELSE -> ELSE
-+ * ... -> ...
-+ * KILP -> KIL -abs(Temp[0].x)
-+ * ... -> ...
-+ * ENDIF -> ENDIF
-+ *
-+ * === OR ===
-+ *
-+ * KILP -> KIL -none.1111
-+ *
-+ * This needs to be done in its own pass, because it might modify the
-+ * instructions before and after KILP.
- */
- void rc_transform_KILP(struct radeon_compiler * c, void *user)
- {
- struct rc_instruction * inst;
- for (inst = c->Program.Instructions.Next;
- inst != &c->Program.Instructions; inst = inst->Next) {
-+ struct rc_instruction * if_inst;
-+ unsigned in_if = 0;
-
- if (inst->U.I.Opcode != RC_OPCODE_KILP)
- continue;
-
-+ for (if_inst = inst->Prev; if_inst != &c->Program.Instructions;
-+ if_inst = if_inst->Prev) {
-+
-+ if (if_inst->U.I.Opcode == RC_OPCODE_IF) {
-+ in_if = 1;
-+ break;
-+ }
-+ }
-+
- inst->U.I.Opcode = RC_OPCODE_KIL;
-
-- if (inst->Prev->U.I.Opcode != RC_OPCODE_IF
-- || inst->Next->U.I.Opcode != RC_OPCODE_ENDIF) {
-+ if (!in_if) {
- inst->U.I.SrcReg[0] = negate(builtin_one);
- } else {
--
-+ /* This should work even if the KILP is inside the ELSE
-+ * block, because -0.0 is considered negative. */
- inst->U.I.SrcReg[0] =
-- negate(absolute(inst->Prev->U.I.SrcReg[0]));
-- /* Remove IF */
-- rc_remove_instruction(inst->Prev);
-- /* Remove ENDIF */
-- rc_remove_instruction(inst->Next);
-+ negate(absolute(if_inst->U.I.SrcReg[0]));
-+
-+ if (inst->Prev->U.I.Opcode != RC_OPCODE_IF
-+ && inst->Next->U.I.Opcode != RC_OPCODE_ENDIF) {
-+
-+ /* Optimize the special case:
-+ * IF Temp[0].x
-+ * KILP
-+ * ENDIF
-+ */
-+
-+ /* Remove IF */
-+ rc_remove_instruction(inst->Prev);
-+ /* Remove ENDIF */
-+ rc_remove_instruction(inst->Next);
-+ }
- }
- }
- }
-diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
-index 82a3ff2..e22deb4 100644
---- a/src/gallium/drivers/svga/svga_screen.c
-+++ b/src/gallium/drivers/svga/svga_screen.c
-@@ -235,7 +235,7 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en
- case PIPE_SHADER_CAP_MAX_TEMPS:
- if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, &result))
- return 32;
-- return result.u;
-+ return MIN2(result.u, SVGA3D_TEMPREG_MAX);
- case PIPE_SHADER_CAP_MAX_ADDRS:
- case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
- /*
-@@ -286,7 +286,7 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en
- case PIPE_SHADER_CAP_MAX_TEMPS:
- if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, &result))
- return 32;
-- return result.u;
-+ return MIN2(result.u, SVGA3D_TEMPREG_MAX);
- case PIPE_SHADER_CAP_MAX_ADDRS:
- return 1;
- case PIPE_SHADER_CAP_MAX_PREDS:
-diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
-index 3347157..b2581da 100644
---- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
-+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
-@@ -2188,7 +2188,7 @@ void brw_fb_WRITE(struct brw_compile *p,
- msg_type,
- msg_length,
- header_present,
-- 1, /* last render target write */
-+ eot, /* last render target write */
- response_length,
- eot,
- 0 /* send_commit_msg */);
-diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
-index a2959a8..4b27e06 100644
---- a/src/mesa/main/bufferobj.c
-+++ b/src/mesa/main/bufferobj.c
-@@ -1159,17 +1159,17 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
- *params = _mesa_bufferobj_mapped(bufObj);
- return;
- case GL_BUFFER_ACCESS_FLAGS:
-- if (ctx->VersionMajor < 3)
-+ if (!ctx->Extensions.ARB_map_buffer_range)
- goto invalid_pname;
- *params = bufObj->AccessFlags;
- return;
- case GL_BUFFER_MAP_OFFSET:
-- if (ctx->VersionMajor < 3)
-+ if (!ctx->Extensions.ARB_map_buffer_range)
- goto invalid_pname;
- *params = (GLint) bufObj->Offset;
- return;
- case GL_BUFFER_MAP_LENGTH:
-- if (ctx->VersionMajor < 3)
-+ if (!ctx->Extensions.ARB_map_buffer_range)
- goto invalid_pname;
- *params = (GLint) bufObj->Length;
- return;
-@@ -1210,7 +1210,7 @@ _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
- *params = simplified_access_mode(bufObj->AccessFlags);
- return;
- case GL_BUFFER_ACCESS_FLAGS:
-- if (ctx->VersionMajor < 3)
-+ if (!ctx->Extensions.ARB_map_buffer_range)
- goto invalid_pname;
- *params = bufObj->AccessFlags;
- return;
-@@ -1218,12 +1218,12 @@ _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
- *params = _mesa_bufferobj_mapped(bufObj);
- return;
- case GL_BUFFER_MAP_OFFSET:
-- if (ctx->VersionMajor < 3)
-+ if (!ctx->Extensions.ARB_map_buffer_range)
- goto invalid_pname;
- *params = bufObj->Offset;
- return;
- case GL_BUFFER_MAP_LENGTH:
-- if (ctx->VersionMajor < 3)
-+ if (!ctx->Extensions.ARB_map_buffer_range)
- goto invalid_pname;
- *params = bufObj->Length;
- return;
diff --git a/mesa-8.0.3-git.patch b/mesa-8.0.3-git.patch
deleted file mode 100644
index 3a6ae23..0000000
--- a/mesa-8.0.3-git.patch
+++ /dev/null
@@ -1,901 +0,0 @@
-git diff-tree -p mesa-8.0.3..d715d3f4a82463a00a64d534747d80792508b97f
-
-diff --git a/docs/relnotes-8.0.3.html b/docs/relnotes-8.0.3.html
-index 4e81da4..dd27bef 100644
---- a/docs/relnotes-8.0.3.html
-+++ b/docs/relnotes-8.0.3.html
-@@ -28,7 +28,9 @@ for DRI hardware acceleration.
-
- MD5 checksums
-
--TBD.
-+b7210a6d6e4584bd852ab29294ce717e MesaLib-8.0.3.tar.gz
-+cc5ee15e306b8c15da6a478923797171 MesaLib-8.0.3.tar.bz2
-+32773634a0f7e70a680505a81426eccf MesaLib-8.0.3.zip
-
-
- New features
-diff --git a/docs/relnotes.html b/docs/relnotes.html
-index 23337cf..1bc889a 100644
---- a/docs/relnotes.html
-+++ b/docs/relnotes.html
-@@ -13,6 +13,7 @@ The release notes summarize what's new or changed in each Mesa release.
-
-
-
-+- 8.0.3 release notes
-
- 8.0.2 release notes
-
- 8.0.1 release notes
-
- 8.0 release notes
-diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
-index 080e03d..c098c05 100644
---- a/src/gallium/auxiliary/draw/draw_pt.c
-+++ b/src/gallium/auxiliary/draw/draw_pt.c
-@@ -329,25 +329,28 @@ draw_pt_arrays_restart(struct draw_context *draw,
-
- if (draw->pt.user.elts) {
- /* indexed prims (draw_elements) */
-+ const char *elts =
-+ (const char *) draw->pt.user.elts + draw->pt.index_buffer.offset;
-+
- cur_start = start;
- cur_count = 0;
-
- switch (draw->pt.user.eltSize) {
- case 1:
- {
-- const ubyte *elt_ub = (const ubyte *) draw->pt.user.elts;
-+ const ubyte *elt_ub = (const ubyte *) elts;
- PRIM_RESTART_LOOP(elt_ub);
- }
- break;
- case 2:
- {
-- const ushort *elt_us = (const ushort *) draw->pt.user.elts;
-+ const ushort *elt_us = (const ushort *) elts;
- PRIM_RESTART_LOOP(elt_us);
- }
- break;
- case 4:
- {
-- const uint *elt_ui = (const uint *) draw->pt.user.elts;
-+ const uint *elt_ui = (const uint *) elts;
- PRIM_RESTART_LOOP(elt_ui);
- }
- break;
-diff --git a/src/gallium/drivers/nv50/nv50_pc_emit.c b/src/gallium/drivers/nv50/nv50_pc_emit.c
-index 2b177c6..30079ba 100644
---- a/src/gallium/drivers/nv50/nv50_pc_emit.c
-+++ b/src/gallium/drivers/nv50/nv50_pc_emit.c
-@@ -865,8 +865,10 @@ emit_flop(struct nv_pc *pc, struct nv_instruction *i)
- assert(SFILE(i, 0) == NV_FILE_GPR);
-
- if (!i->is_long) {
-+ assert(i->opcode == NV_OP_RCP);
- emit_form_MUL(pc, i);
-- assert(i->opcode == NV_OP_RCP && !src0->mod);
-+ if (src0->mod & NV_MOD_NEG) pc->emit[0] |= 0x00400000;
-+ if (src0->mod & NV_MOD_ABS) pc->emit[0] |= 0x00008000;
- return;
- }
-
-diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c
-index 2f9379b..942c0ee 100644
---- a/src/gallium/drivers/svga/svga_surface.c
-+++ b/src/gallium/drivers/svga/svga_surface.c
-@@ -320,6 +320,11 @@ svga_mark_surface_dirty(struct pipe_surface *surf)
- else {
- /* this will happen later in svga_propagate_surface */
- }
-+
-+ /* Increment the view_age and texture age for this surface's slice
-+ * so that any sampler views into the texture are re-validated too.
-+ */
-+ tex->view_age[surf->u.tex.first_layer] = ++(tex->age);
- }
- }
-
-diff --git a/src/gallium/state_trackers/vega/vg_translate.c b/src/gallium/state_trackers/vega/vg_translate.c
-index 06cc003..7b3df27 100644
---- a/src/gallium/state_trackers/vega/vg_translate.c
-+++ b/src/gallium/state_trackers/vega/vg_translate.c
-@@ -526,8 +526,8 @@ void _vega_unpack_float_span_rgba(struct vg_context *ctx,
- src += offset;
- for (i = 0; i < n; ++i) {
- VGfloat clr[4];
-- clr[0] = ((*src >> 10) & 31)/31.;
-- clr[1] = ((*src >> 5) & 95)/95.;
-+ clr[0] = ((*src >> 11) & 31)/31.;
-+ clr[1] = ((*src >> 5) & 63)/63.;
- clr[2] = ((*src >> 0) & 31)/31.;
- clr[3] = 1.f;
-
-diff --git a/src/mesa/drivers/dri/i965/brw_eu.c b/src/mesa/drivers/dri/i965/brw_eu.c
-index 2b0593a..75a4205 100644
---- a/src/mesa/drivers/dri/i965/brw_eu.c
-+++ b/src/mesa/drivers/dri/i965/brw_eu.c
-@@ -47,13 +47,13 @@ brw_swap_cmod(uint32_t cmod)
- case BRW_CONDITIONAL_NZ:
- return cmod;
- case BRW_CONDITIONAL_G:
-- return BRW_CONDITIONAL_LE;
-- case BRW_CONDITIONAL_GE:
- return BRW_CONDITIONAL_L;
-+ case BRW_CONDITIONAL_GE:
-+ return BRW_CONDITIONAL_LE;
- case BRW_CONDITIONAL_L:
-- return BRW_CONDITIONAL_GE;
-- case BRW_CONDITIONAL_LE:
- return BRW_CONDITIONAL_G;
-+ case BRW_CONDITIONAL_LE:
-+ return BRW_CONDITIONAL_GE;
- default:
- return ~0;
- }
-diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
-index de4820b..32da289 100644
---- a/src/mesa/main/bufferobj.c
-+++ b/src/mesa/main/bufferobj.c
-@@ -524,7 +524,7 @@ _mesa_copy_buffer_subdata(struct gl_context *ctx,
- GLintptr readOffset, GLintptr writeOffset,
- GLsizeiptr size)
- {
-- void *srcPtr, *dstPtr;
-+ GLubyte *srcPtr, *dstPtr;
-
- /* the buffers should not be mapped */
- assert(!_mesa_bufferobj_mapped(src));
-@@ -1311,6 +1311,12 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
- return;
- }
-
-+ if (size < 0) {
-+ _mesa_error(ctx, GL_INVALID_VALUE,
-+ "glCopyBufferSubData(writeOffset = %d)", (int) size);
-+ return;
-+ }
-+
- if (readOffset + size > src->Size) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyBuffserSubData(readOffset + size = %d)",
-diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
-index b5b10aa..64f592a 100644
---- a/src/mesa/main/fbobject.c
-+++ b/src/mesa/main/fbobject.c
-@@ -1245,7 +1245,8 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
- case GL_RGBA8I_EXT:
- case GL_RGBA16I_EXT:
- case GL_RGBA32I_EXT:
-- return ctx->Extensions.EXT_texture_integer ? GL_RGBA : 0;
-+ return ctx->VersionMajor >= 3 ||
-+ ctx->Extensions.EXT_texture_integer ? GL_RGBA : 0;
-
- case GL_RGB8UI_EXT:
- case GL_RGB16UI_EXT:
-@@ -1253,7 +1254,8 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
- case GL_RGB8I_EXT:
- case GL_RGB16I_EXT:
- case GL_RGB32I_EXT:
-- return ctx->Extensions.EXT_texture_integer ? GL_RGB : 0;
-+ return ctx->VersionMajor >= 3 ||
-+ ctx->Extensions.EXT_texture_integer ? GL_RGB : 0;
-
- case GL_R8UI:
- case GL_R8I:
-@@ -1261,8 +1263,9 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
- case GL_R16I:
- case GL_R32UI:
- case GL_R32I:
-- return ctx->Extensions.ARB_texture_rg &&
-- ctx->Extensions.EXT_texture_integer ? GL_RED : 0;
-+ return ctx->VersionMajor >= 3 ||
-+ (ctx->Extensions.ARB_texture_rg &&
-+ ctx->Extensions.EXT_texture_integer) ? GL_RED : 0;
-
- case GL_RG8UI:
- case GL_RG8I:
-@@ -1270,8 +1273,9 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
- case GL_RG16I:
- case GL_RG32UI:
- case GL_RG32I:
-- return ctx->Extensions.ARB_texture_rg &&
-- ctx->Extensions.EXT_texture_integer ? GL_RG : 0;
-+ return ctx->VersionMajor >= 3 ||
-+ (ctx->Extensions.ARB_texture_rg &&
-+ ctx->Extensions.EXT_texture_integer) ? GL_RG : 0;
-
- case GL_INTENSITY8I_EXT:
- case GL_INTENSITY8UI_EXT:
-diff --git a/src/mesa/main/format_unpack.c b/src/mesa/main/format_unpack.c
-index a484979..fece8d9 100644
---- a/src/mesa/main/format_unpack.c
-+++ b/src/mesa/main/format_unpack.c
-@@ -2922,7 +2922,7 @@ unpack_uint_z_Z32_FLOAT(const void *src, GLuint *dst, GLuint n)
- const float *s = (const float *)src;
- GLuint i;
- for (i = 0; i < n; i++) {
-- dst[i] = FLOAT_TO_UINT(IROUND(CLAMP((s[i]), 0.0F, 1.0F)));
-+ dst[i] = FLOAT_TO_UINT(CLAMP(s[i], 0.0F, 1.0F));
- }
- }
-
-@@ -2938,7 +2938,7 @@ unpack_uint_z_Z32_FLOAT_X24S8(const void *src, GLuint *dst, GLuint n)
- GLuint i;
-
- for (i = 0; i < n; i++) {
-- dst[i] = FLOAT_TO_UINT(IROUND(CLAMP((s[i].z), 0.0F, 1.0F)));
-+ dst[i] = FLOAT_TO_UINT(CLAMP(s[i].z, 0.0F, 1.0F));
- }
- }
-
-diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
-index 8b65cf0..b6c2645 100644
---- a/src/mesa/main/image.c
-+++ b/src/mesa/main/image.c
-@@ -356,18 +356,92 @@ _mesa_bytes_per_pixel( GLenum format, GLenum type )
-
-
- /**
-- * Test for a legal pixel format and type.
-+ * Do error checking of format/type combinations for glReadPixels,
-+ * glDrawPixels and glTex[Sub]Image. Note that depending on the format
-+ * and type values, we may either generate GL_INVALID_OPERATION or
-+ * GL_INVALID_ENUM.
- *
- * \param format pixel format.
- * \param type pixel type.
- *
-- * \return GL_TRUE if the given pixel format and type are legal, or GL_FALSE
-- * otherwise.
-+ * \return GL_INVALID_ENUM, GL_INVALID_OPERATION or GL_NO_ERROR
- */
--GLboolean
--_mesa_is_legal_format_and_type(const struct gl_context *ctx,
-- GLenum format, GLenum type)
-+GLenum
-+_mesa_error_check_format_and_type(const struct gl_context *ctx,
-+ GLenum format, GLenum type)
- {
-+ /* special type-based checks (see glReadPixels, glDrawPixels error lists) */
-+ switch (type) {
-+ case GL_BITMAP:
-+ if (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX) {
-+ return GL_INVALID_ENUM;
-+ }
-+ break;
-+
-+ case GL_UNSIGNED_BYTE_3_3_2:
-+ case GL_UNSIGNED_BYTE_2_3_3_REV:
-+ case GL_UNSIGNED_SHORT_5_6_5:
-+ case GL_UNSIGNED_SHORT_5_6_5_REV:
-+ if (format == GL_RGB) {
-+ break; /* OK */
-+ }
-+ if (format == GL_RGB_INTEGER_EXT &&
-+ ctx->Extensions.ARB_texture_rgb10_a2ui) {
-+ break; /* OK */
-+ }
-+ return GL_INVALID_OPERATION;
-+
-+ case GL_UNSIGNED_SHORT_4_4_4_4:
-+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
-+ case GL_UNSIGNED_SHORT_5_5_5_1:
-+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
-+ case GL_UNSIGNED_INT_8_8_8_8:
-+ case GL_UNSIGNED_INT_8_8_8_8_REV:
-+ case GL_UNSIGNED_INT_10_10_10_2:
-+ case GL_UNSIGNED_INT_2_10_10_10_REV:
-+ if (format == GL_RGBA ||
-+ format == GL_BGRA ||
-+ format == GL_ABGR_EXT) {
-+ break; /* OK */
-+ }
-+ if ((format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT) &&
-+ ctx->Extensions.ARB_texture_rgb10_a2ui) {
-+ break; /* OK */
-+ }
-+ return GL_INVALID_OPERATION;
-+
-+ case GL_UNSIGNED_INT_24_8:
-+ if (!ctx->Extensions.EXT_packed_depth_stencil) {
-+ return GL_INVALID_ENUM;
-+ }
-+ if (format != GL_DEPTH_STENCIL) {
-+ return GL_INVALID_OPERATION;
-+ }
-+ return GL_NO_ERROR;
-+
-+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
-+ if (!ctx->Extensions.ARB_depth_buffer_float) {
-+ return GL_INVALID_ENUM;
-+ }
-+ if (format != GL_DEPTH_STENCIL) {
-+ return GL_INVALID_OPERATION;
-+ }
-+ return GL_NO_ERROR;
-+
-+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
-+ if (!ctx->Extensions.EXT_packed_float) {
-+ return GL_INVALID_ENUM;
-+ }
-+ if (format != GL_RGB) {
-+ return GL_INVALID_OPERATION;
-+ }
-+ return GL_NO_ERROR;
-+
-+ default:
-+ ; /* fall-through */
-+ }
-+
-+ /* now, for each format, check the type for compatibility */
- switch (format) {
- case GL_COLOR_INDEX:
- case GL_STENCIL_INDEX:
-@@ -380,12 +454,14 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
-- return GL_TRUE;
-- case GL_HALF_FLOAT_ARB:
-- return ctx->Extensions.ARB_half_float_pixel;
-+ return GL_NO_ERROR;
-+ case GL_HALF_FLOAT:
-+ return ctx->Extensions.ARB_half_float_pixel
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-+
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
-@@ -404,16 +480,17 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
-- return GL_TRUE;
-- case GL_HALF_FLOAT_ARB:
-- return ctx->Extensions.ARB_half_float_pixel;
-+ return GL_NO_ERROR;
-+ case GL_HALF_FLOAT:
-+ return ctx->Extensions.ARB_half_float_pixel
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-+
- case GL_RG:
- if (!ctx->Extensions.ARB_texture_rg)
-- return GL_FALSE;
--
-+ return GL_INVALID_ENUM;
- switch (type) {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
-@@ -422,12 +499,14 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
-- return GL_TRUE;
-- case GL_HALF_FLOAT_ARB:
-- return ctx->Extensions.ARB_half_float_pixel;
-+ return GL_NO_ERROR;
-+ case GL_HALF_FLOAT:
-+ return ctx->Extensions.ARB_half_float_pixel
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-+
- case GL_RGB:
- switch (type) {
- case GL_BYTE:
-@@ -441,16 +520,20 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
-- return GL_TRUE;
-- case GL_HALF_FLOAT_ARB:
-- return ctx->Extensions.ARB_half_float_pixel;
-+ return GL_NO_ERROR;
-+ case GL_HALF_FLOAT:
-+ return ctx->Extensions.ARB_half_float_pixel
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- case GL_UNSIGNED_INT_5_9_9_9_REV:
-- return ctx->Extensions.EXT_texture_shared_exponent;
-+ return ctx->Extensions.EXT_texture_shared_exponent
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- case GL_UNSIGNED_INT_10F_11F_11F_REV:
-- return ctx->Extensions.EXT_packed_float;
-+ return ctx->Extensions.EXT_packed_float
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-+
- case GL_BGR:
- switch (type) {
- /* NOTE: no packed types are supported with BGR. That's
-@@ -463,12 +546,14 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
-- return GL_TRUE;
-- case GL_HALF_FLOAT_ARB:
-- return ctx->Extensions.ARB_half_float_pixel;
-+ return GL_NO_ERROR;
-+ case GL_HALF_FLOAT:
-+ return ctx->Extensions.ARB_half_float_pixel
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-+
- case GL_RGBA:
- case GL_BGRA:
- case GL_ABGR_EXT:
-@@ -488,28 +573,37 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
-- return GL_TRUE;
-- case GL_HALF_FLOAT_ARB:
-- return ctx->Extensions.ARB_half_float_pixel;
-+ return GL_NO_ERROR;
-+ case GL_HALF_FLOAT:
-+ return ctx->Extensions.ARB_half_float_pixel
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-+
- case GL_YCBCR_MESA:
-+ if (!ctx->Extensions.MESA_ycbcr_texture)
-+ return GL_INVALID_ENUM;
- if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
- type == GL_UNSIGNED_SHORT_8_8_REV_MESA)
-- return GL_TRUE;
-+ return GL_NO_ERROR;
- else
-- return GL_FALSE;
-+ return GL_INVALID_OPERATION;
-+
- case GL_DEPTH_STENCIL_EXT:
-- if ((ctx->Extensions.EXT_packed_depth_stencil &&
-- type == GL_UNSIGNED_INT_24_8_EXT) ||
-- (ctx->Extensions.ARB_depth_buffer_float &&
-- type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV))
-- return GL_TRUE;
-+ if (ctx->Extensions.EXT_packed_depth_stencil &&
-+ type == GL_UNSIGNED_INT_24_8)
-+ return GL_NO_ERROR;
-+ else if (ctx->Extensions.ARB_depth_buffer_float &&
-+ type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
-+ return GL_NO_ERROR;
- else
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
-+
- case GL_DUDV_ATI:
- case GL_DU8DV8_ATI:
-+ if (!ctx->Extensions.ATI_envmap_bumpmap)
-+ return GL_INVALID_ENUM;
- switch (type) {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
-@@ -518,9 +612,9 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
-- return GL_TRUE;
-+ return GL_NO_ERROR;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-
- /* integer-valued formats */
-@@ -536,9 +630,11 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_UNSIGNED_INT:
-- return ctx->Extensions.EXT_texture_integer;
-+ return (ctx->VersionMajor >= 3 ||
-+ ctx->Extensions.EXT_texture_integer)
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-
- case GL_RGB_INTEGER_EXT:
-@@ -549,14 +645,17 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_UNSIGNED_INT:
-- return ctx->Extensions.EXT_texture_integer;
-+ return (ctx->VersionMajor >= 3 ||
-+ ctx->Extensions.EXT_texture_integer)
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
-- return ctx->Extensions.ARB_texture_rgb10_a2ui;
-+ return ctx->Extensions.ARB_texture_rgb10_a2ui
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-
- case GL_BGR_INTEGER_EXT:
-@@ -568,9 +667,11 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_INT:
- case GL_UNSIGNED_INT:
- /* NOTE: no packed formats w/ BGR format */
-- return ctx->Extensions.EXT_texture_integer;
-+ return (ctx->VersionMajor >= 3 ||
-+ ctx->Extensions.EXT_texture_integer)
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-
- case GL_RGBA_INTEGER_EXT:
-@@ -582,7 +683,9 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_UNSIGNED_INT:
-- return ctx->Extensions.EXT_texture_integer;
-+ return (ctx->VersionMajor >= 3 ||
-+ ctx->Extensions.EXT_texture_integer)
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
-@@ -591,9 +694,10 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
-- return ctx->Extensions.ARB_texture_rgb10_a2ui;
-+ return ctx->Extensions.ARB_texture_rgb10_a2ui
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-
- case GL_LUMINANCE_INTEGER_EXT:
-@@ -605,15 +709,16 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx,
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_UNSIGNED_INT:
-- return ctx->Extensions.EXT_texture_integer;
-+ return ctx->Extensions.EXT_texture_integer
-+ ? GL_NO_ERROR : GL_INVALID_ENUM;
- default:
-- return GL_FALSE;
-+ return GL_INVALID_ENUM;
- }
-
- default:
-- ; /* fall-through */
-+ return GL_INVALID_ENUM;
- }
-- return GL_FALSE;
-+ return GL_NO_ERROR;
- }
-
-
-diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h
-index e4961ed..f1ed883 100644
---- a/src/mesa/main/image.h
-+++ b/src/mesa/main/image.h
-@@ -53,9 +53,9 @@ _mesa_components_in_format( GLenum format );
- extern GLint
- _mesa_bytes_per_pixel( GLenum format, GLenum type );
-
--extern GLboolean
--_mesa_is_legal_format_and_type(const struct gl_context *ctx,
-- GLenum format, GLenum type);
-+extern GLenum
-+_mesa_error_check_format_and_type(const struct gl_context *ctx,
-+ GLenum format, GLenum type);
-
- extern GLboolean
- _mesa_is_color_format(GLenum format);
-diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
-index 6c041fa..d0947d6 100644
---- a/src/mesa/main/readpix.c
-+++ b/src/mesa/main/readpix.c
-@@ -650,6 +650,7 @@ _mesa_error_check_format_type(struct gl_context *ctx, GLenum format,
- {
- const char *readDraw = drawing ? "Draw" : "Read";
- const GLboolean reading = !drawing;
-+ GLenum err;
-
- /* state validation should have already been done */
- ASSERT(ctx->NewState == 0x0);
-@@ -671,9 +672,9 @@ _mesa_error_check_format_type(struct gl_context *ctx, GLenum format,
- }
-
- /* basic combinations test */
-- if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
-- _mesa_error(ctx, GL_INVALID_ENUM,
-- "gl%sPixels(format or type)", readDraw);
-+ err = _mesa_error_check_format_and_type(ctx, format, type);
-+ if (err != GL_NO_ERROR) {
-+ _mesa_error(ctx, err, "gl%sPixels(format or type)", readDraw);
- return GL_TRUE;
- }
-
-@@ -777,7 +778,7 @@ _mesa_error_check_format_type(struct gl_context *ctx, GLenum format,
- }
- break;
- default:
-- /* this should have been caught in _mesa_is_legal_format_type() */
-+ /* this should have been caught in _mesa_error_check_format_type() */
- _mesa_problem(ctx, "unexpected format in _mesa_%sPixels", readDraw);
- return GL_TRUE;
- }
-diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
-index 259eb90..5fdc2ab 100644
---- a/src/mesa/main/texformat.c
-+++ b/src/mesa/main/texformat.c
-@@ -706,6 +706,12 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
- RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_INT32);
- RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT32);
- break;
-+ }
-+ }
-+
-+ if (ctx->VersionMajor >= 3 ||
-+ ctx->Extensions.EXT_texture_integer) {
-+ switch (internalFormat) {
- case GL_RGB8UI_EXT:
- RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UINT8);
- RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8);
-@@ -822,7 +828,9 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
- }
- }
-
-- if (ctx->Extensions.ARB_texture_rg && ctx->Extensions.EXT_texture_integer) {
-+ if (ctx->VersionMajor >= 3 ||
-+ (ctx->Extensions.ARB_texture_rg &&
-+ ctx->Extensions.EXT_texture_integer)) {
- switch (internalFormat) {
- case GL_R8UI:
- RETURN_IF_SUPPORTED(MESA_FORMAT_R_UINT8);
-diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
-index 76ac5a2..254199b 100644
---- a/src/mesa/main/texgetimage.c
-+++ b/src/mesa/main/texgetimage.c
-@@ -691,7 +691,7 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
- struct gl_texture_image *texImage;
- const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
- const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
-- GLenum baseFormat;
-+ GLenum baseFormat, err;
-
- if (maxLevels == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target=0x%x)", target);
-@@ -734,6 +734,12 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
- if (!ctx->Extensions.ATI_envmap_bumpmap
- && _mesa_is_dudv_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
-+ return;
-+ }
-+
-+ err = _mesa_error_check_format_and_type(ctx, format, type);
-+ if (err != GL_NO_ERROR) {
-+ _mesa_error(ctx, err, "glGetTexImage(format/type)");
- return GL_TRUE;
- }
-
-@@ -744,14 +750,6 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
- return GL_TRUE;
- }
-
-- if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
-- /* GL_INVALID_OPERATION is generated by a format/type
-- * mismatch (see the 1.2 spec page 94, sec 3.6.4.)
-- */
-- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(target)");
-- return GL_TRUE;
-- }
--
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- /* non-existant texture image */
-diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
-index c347f59..077c196 100644
---- a/src/mesa/main/teximage.c
-+++ b/src/mesa/main/teximage.c
-@@ -323,7 +323,8 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
- }
- #endif /* FEATURE_EXT_texture_sRGB */
-
-- if (ctx->Extensions.EXT_texture_integer) {
-+ if (ctx->VersionMajor >= 3 ||
-+ ctx->Extensions.EXT_texture_integer) {
- switch (internalFormat) {
- case GL_RGBA8UI_EXT:
- case GL_RGBA16UI_EXT:
-@@ -340,6 +341,11 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
- case GL_RGB16I_EXT:
- case GL_RGB32I_EXT:
- return GL_RGB;
-+ }
-+ }
-+
-+ if (ctx->Extensions.EXT_texture_integer) {
-+ switch (internalFormat) {
- case GL_ALPHA8UI_EXT:
- case GL_ALPHA16UI_EXT:
- case GL_ALPHA32UI_EXT:
-@@ -391,7 +397,7 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
- case GL_R16UI:
- case GL_R32I:
- case GL_R32UI:
-- if (!ctx->Extensions.EXT_texture_integer)
-+ if (ctx->VersionMajor < 3 && !ctx->Extensions.EXT_texture_integer)
- break;
- /* FALLTHROUGH */
- case GL_R8:
-@@ -416,7 +422,7 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
- case GL_RG16UI:
- case GL_RG32I:
- case GL_RG32UI:
-- if (!ctx->Extensions.EXT_texture_integer)
-+ if (ctx->VersionMajor < 3 && !ctx->Extensions.EXT_texture_integer)
- break;
- /* FALLTHROUGH */
- case GL_RG:
-@@ -1578,6 +1584,7 @@ texture_error_check( struct gl_context *ctx,
- const GLboolean isProxy = target == proxyTarget;
- GLboolean sizeOK = GL_TRUE;
- GLboolean colorFormat;
-+ GLenum err;
-
- /* Even though there are no color-index textures, we still have to support
- * uploading color-index data and remapping it to RGB via the
-@@ -1646,16 +1653,10 @@ texture_error_check( struct gl_context *ctx,
- }
-
- /* Check incoming image format and type */
-- if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
-- /* Normally, GL_INVALID_OPERATION is generated by a format/type
-- * mismatch (see the 1.2 spec page 94, sec 3.6.4.). But with the
-- * GL_EXT_texture_integer extension, some combinations should generate
-- * GL_INVALID_ENUM instead (grr!).
-- */
-+ err = _mesa_error_check_format_and_type(ctx, format, type);
-+ if (err != GL_NO_ERROR) {
- if (!isProxy) {
-- GLenum error = _mesa_is_integer_format(format)
-- ? GL_INVALID_ENUM : GL_INVALID_OPERATION;
-- _mesa_error(ctx, error,
-+ _mesa_error(ctx, err,
- "glTexImage%dD(incompatible format 0x%x, type 0x%x)",
- dimensions, format, type);
- }
-@@ -1754,7 +1755,7 @@ texture_error_check( struct gl_context *ctx,
- }
-
- /* additional checks for integer textures */
-- if (ctx->Extensions.EXT_texture_integer &&
-+ if ((ctx->VersionMajor >= 3 || ctx->Extensions.EXT_texture_integer) &&
- (_mesa_is_integer_format(format) !=
- _mesa_is_integer_format(internalFormat))) {
- if (!isProxy) {
-@@ -1805,6 +1806,8 @@ subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
- GLint width, GLint height, GLint depth,
- GLenum format, GLenum type )
- {
-+ GLenum err;
-+
- /* Basic level check */
- if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
-@@ -1828,13 +1831,9 @@ subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
- return GL_TRUE;
- }
-
-- if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
-- /* As with the glTexImage2D check above, the error code here
-- * depends on texture integer.
-- */
-- GLenum error = _mesa_is_integer_format(format)
-- ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
-- _mesa_error(ctx, error,
-+ err = _mesa_error_check_format_and_type(ctx, format, type);
-+ if (err != GL_NO_ERROR) {
-+ _mesa_error(ctx, err,
- "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)",
- dimensions, format, type);
- return GL_TRUE;
-diff --git a/src/mesa/main/version.c b/src/mesa/main/version.c
-index 38ae1ce..fc6e17c 100644
---- a/src/mesa/main/version.c
-+++ b/src/mesa/main/version.c
-@@ -140,7 +140,6 @@ compute_version(struct gl_context *ctx)
- ctx->Extensions.EXT_framebuffer_sRGB &&
- ctx->Extensions.EXT_packed_float &&
- ctx->Extensions.EXT_texture_array &&
-- ctx->Extensions.EXT_texture_integer &&
- ctx->Extensions.EXT_texture_shared_exponent &&
- ctx->Extensions.EXT_transform_feedback &&
- ctx->Extensions.NV_conditional_render);
-diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
-index 04d451b..d4992a7 100644
---- a/src/mesa/state_tracker/st_cb_drawpixels.c
-+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
-@@ -215,7 +215,7 @@ st_make_drawpix_z_stencil_program(struct st_context *st,
- if (!p)
- return NULL;
-
-- p->NumInstructions = write_depth ? 2 : 1;
-+ p->NumInstructions = write_depth ? 3 : 1;
- p->NumInstructions += write_stencil ? 1 : 0;
-
- p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
-@@ -236,6 +236,13 @@ st_make_drawpix_z_stencil_program(struct st_context *st,
- p->Instructions[ic].TexSrcUnit = 0;
- p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
- ic++;
-+ /* MOV result.color, fragment.color; */
-+ p->Instructions[ic].Opcode = OPCODE_MOV;
-+ p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
-+ p->Instructions[ic].DstReg.Index = FRAG_RESULT_COLOR;
-+ p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
-+ p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_COL0;
-+ ic++;
- }
-
- if (write_stencil) {
-@@ -258,8 +265,10 @@ st_make_drawpix_z_stencil_program(struct st_context *st,
-
- p->InputsRead = FRAG_BIT_TEX0 | FRAG_BIT_COL0;
- p->OutputsWritten = 0;
-- if (write_depth)
-+ if (write_depth) {
- p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_DEPTH);
-+ p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_COLOR);
-+ }
- if (write_stencil)
- p->OutputsWritten |= BITFIELD64_BIT(FRAG_RESULT_STENCIL);
-
-diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
-index ad4f23c..88c5ad7 100644
---- a/src/mesa/state_tracker/st_cb_texture.c
-+++ b/src/mesa/state_tracker/st_cb_texture.c
-@@ -406,6 +406,8 @@ guess_and_alloc_texture(struct st_context *st,
- ptLayers,
- bindings);
-
-+ stObj->lastLevel = lastLevel;
-+
- DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
-
- return stObj->pt != NULL;
-diff --git a/tests/glx/Makefile.am b/tests/glx/Makefile.am
-index cdebf5d..5f55a5b 100644
---- a/tests/glx/Makefile.am
-+++ b/tests/glx/Makefile.am
-@@ -1,6 +1,6 @@
--AM_CFLAGS = -I$(top_builddir)/src/glx -I$(top_builddir)/src/mapi \
-+AM_CFLAGS = -I$(top_builddir)/src/glx -I$(top_builddir)/src/mapi -I$(top_builddir)/include \
- $(X11_CFLAGS) $(GTEST_CFLAGS)
--AM_CXXFLAGS = -I$(top_builddir)/src/glx -I$(top_builddir)/src/mapi \
-+AM_CXXFLAGS = -I$(top_builddir)/src/glx -I$(top_builddir)/src/mapi -I$(top_builddir)/include \
- $(X11_CFLAGS) $(GTEST_CFLAGS)
-
- if HAVE_GTEST
diff --git a/mesa-8.0.4-git.patch b/mesa-8.0.4-git.patch
new file mode 100644
index 0000000..0a56d6f
--- /dev/null
+++ b/mesa-8.0.4-git.patch
@@ -0,0 +1,1447 @@
+diff --git a/bin/shortlog_mesa.sh b/bin/shortlog_mesa.sh
+new file mode 100755
+index 0000000..b20c52f
+--- /dev/null
++++ b/bin/shortlog_mesa.sh
+@@ -0,0 +1,23 @@
++#!/bin/bash
++
++# This script is used to generate the list of changes that
++# appears in the release notes files, with HTML formatting.
++
++
++typeset -i in_log=0
++
++git shortlog $* | while read l
++do
++ if [ $in_log -eq 0 ]; then
++ echo '
'$l'
'
++ echo ''
++ in_log=1
++ elif echo "$l" | egrep -q '^$' ; then
++ echo '
'
++ echo
++ in_log=0
++ else
++ mesg=$(echo $l | sed 's/ (cherry picked from commit [0-9a-f]\+)//;s/\&/&/g;s/\</g;s/>/\>/g')
++ echo ' - '${mesg}'
'
++ fi
++done
+diff --git a/docs/relnotes-8.0.4.html b/docs/relnotes-8.0.4.html
+index d5792aa..529140a 100644
+--- a/docs/relnotes-8.0.4.html
++++ b/docs/relnotes-8.0.4.html
+@@ -1,16 +1,13 @@
+-
+-
++
++
+
+-Mesa Release Notes
+-
+-
++
++ Mesa Release Notes
++
+
++
+
+-
+-
+-
+-
+-Mesa 8.0.4 Release Notes / July 10, 2012
++Mesa 8.0.4 Release Notes / July 10, 2012
+
+
+ Mesa 8.0.4 is a bug fix release which fixes bugs found since the 8.0.2 release.
+@@ -28,7 +25,9 @@ for DRI hardware acceleration.
+
+
MD5 checksums
+
+-TBD
++02b96082d2f1ad72e7385f4022afafb9 MesaLib-8.0.4.tar.gz
++d546f988adfdf986cff45b1efa2d8a46 MesaLib-8.0.4.tar.bz2
++1f0fdabe6e8019d4de6c16e20e74d163 MesaLib-8.0.4.zip
+
+
+ New features
+@@ -68,18 +67,18 @@ TBD
+ git log mesa-8.0.3..mesa-8.0.4
+
+
+-Andreas Betz (1):
++
Andreas Betz (1):
+
+ - vega: fix 565 color unpacking bug
+-
++
+
+-Antoine Labour (2):
++
Antoine Labour (2):
+
+ - meta: Cleanup the resources we allocate.
+ - mesa: Free uniforms correclty.
+-
++
+
+-Brian Paul (22):
++
Brian Paul (22):
+
+ - docs: add link to 8.0.3 release notes
+ - mesa: fix Z32_FLOAT -> uint conversion functions
+@@ -103,39 +102,39 @@ TBD
+ - st/mesa: fix mipmap image size computation w.r.t. texture arrays
+ - draw: fix missing immediates bug in polygon stipple code
+ - st/mesa: fix max_offset computation for base vertex
+-
++
+
+-Christoph Bumiller (1):
++
Christoph Bumiller (1):
+
+ - nv50: handle NEG,ABS modifiers for short RCP encoding
+-
++
+
+-Dylan Noblesmith (1):
++
Dylan Noblesmith (1):
+
+ - mesa: require GL_MAX_SAMPLES >= 4 for GL 3.0
+-
++
+
+-Eric Anholt (1):
++
Eric Anholt (1):
+
+ - i965/vs: Fix texelFetchOffset()
+-
++
+
+-Ian Romanick (5):
++
Ian Romanick (5):
+
+ - docs: Add 8.0.3 release md5sums
+ - glx/tests: Fix off-by-one error in allocating extension string buffer
+ - glsl: Remove spurious printf messages
+ - glsl: Fix pi/2 constant in acos built-in function
+ - mesa: Bump version number to 8.0.4
+-
++
+
+-José Fonseca (2):
++
José Fonseca (2):
+
+ - mesa: Avoid void acinclude.m4 Android.common.mk Android.mk autogen.sh bin common.py configs configure.ac docs doxygen include Makefile scons SConstruct src tests arithmetic.
+ - draw: Ensure that prepare is always run after LLVM garbagge collection.
+-
++
+
+-Kenneth Graunke (15):
++
Kenneth Graunke (15):
+
+ - mesa: Check for a negative "size" parameter in glCopyBufferSubData().
+ - i965: Fix brw_swap_cmod() for LE/GE comparisons.
+@@ -152,51 +151,51 @@ TBD
+ - i965/fs: Fix user-defined FS outputs with less than four components.
+ - glsl: Hook up loop_variable_state destructor to plug a memory leak.
+ - glsl: Don't trust loop analysis in the presence of function calls.
+-
++
+
+-Kurt Roeckx (1):
++
Kurt Roeckx (1):
+
+ - i830: Fix crash for GL_STENCIL_TEST in i830Enable()
+-
++
+
+-Lukas Rössler (1):
++
Lukas Rössler (1):
+
+ - glu: fix two Clang warnings
+-
++
+
+-Marek Olšák (2):
++
Marek Olšák (2):
+
+ - mesa: allow exposing GL3 without EXT_texture_integer
+ - st/mesa: don't do srgb->linear conversion in decompress_with_blit
+-
++
+
+-Paul Seidler (1):
++
Paul Seidler (1):
+
+ - tests: include mesa headers
+-
++
+
+-Stéphane Marchesin (3):
++
Stéphane Marchesin (3):
+
+ - glx: Handle a null reply in QueryVersion.
+ - i915g: Don't invert signalled/unsignalled fences
+ - i915g: Don't avoid flushing when we have a pending fence.
+-
++
+
+-Thomas Gstädtner (1):
++
Thomas Gstädtner (1):
+
+ - gallium/targets: pass ldflags parameter to MKLIB
+-
++
+
+-Vadim Girlin (2):
++
Vadim Girlin (2):
+
+ - st/mesa: set stObj->lastLevel in guess_and_alloc_texture
+ - r600g: check gpr count limit
+-
++
+
+-Vinson Lee (1):
++
Vinson Lee (1):
+
+ - st/mesa: Fix uninitialized members in glsl_to_tgsi_visitor constructor.
+-
++
+
+
+
+diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
+index 1998941..1d99539 100644
+--- a/src/egl/drivers/dri2/platform_android.c
++++ b/src/egl/drivers/dri2/platform_android.c
+@@ -498,6 +498,14 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
+ for (j = 0; dri2_dpy->driver_configs[j]; j++) {
+ const EGLint surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
+ struct dri2_egl_config *dri2_conf;
++ unsigned int double_buffered = 0;
++
++ dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[j],
++ __DRI_ATTRIB_DOUBLE_BUFFER, &double_buffered);
++
++ /* support only double buffered configs */
++ if (!double_buffered)
++ continue;
+
+ dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[j],
+ count + 1, visuals[i].size, surface_type, NULL,
+@@ -523,17 +531,6 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
+ /* there is no front buffer so no OpenGL */
+ dri2_conf->base.RenderableType &= ~EGL_OPENGL_BIT;
+ dri2_conf->base.Conformant &= ~EGL_OPENGL_BIT;
+-
+- /*
+- * We want to make sure GL_DRAW_BUFFER for windows or pbuffers is always
+- * GL_BACK. For EGL configs that do not have a double DRI config, clear
+- * the surface type.
+- *
+- * This is just to be on the safe side. dri2_add_config never sets
+- * EGL_WINDOW_BIT or EGL_PBUFFER_BIT for such configs.
+- */
+- if (!dri2_conf->dri_double_config)
+- dri2_conf->base.SurfaceType = 0;
+ }
+
+ return (count != 0);
+diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
+index c0108fc..ae9c3b2 100644
+--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
++++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
+@@ -455,7 +455,7 @@ ximage_display_copy_to_pixmap(struct native_display *ndpy,
+ if (src->bind & PIPE_BIND_DISPLAY_TARGET) {
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
+- const struct ximage_config *xconf;
++ const struct ximage_config *xconf = NULL;
+ struct xlib_drawable xdraw;
+ int i;
+
+diff --git a/src/mesa/drivers/dri/common/xmlconfig.c b/src/mesa/drivers/dri/common/xmlconfig.c
+index 6d1d5ec..039e98a 100644
+--- a/src/mesa/drivers/dri/common/xmlconfig.c
++++ b/src/mesa/drivers/dri/common/xmlconfig.c
+@@ -86,7 +86,7 @@ static const char *__getProgramName () {
+ #endif
+
+ #if !defined(GET_PROGRAM_NAME)
+-# if defined(__OpenBSD__) || defined(NetBSD) || defined(__UCLIBC__)
++# if defined(__OpenBSD__) || defined(NetBSD) || defined(__UCLIBC__) || defined(ANDROID)
+ /* This is a hack. It's said to work on OpenBSD, NetBSD and GNU.
+ * Rogelio M.Serrano Jr. reported it's also working with UCLIBC. It's
+ * used as a last resort, if there is no documented facility available. */
+diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c
+index 669fea8..647ba62 100644
+--- a/src/mesa/drivers/dri/i915/i830_state.c
++++ b/src/mesa/drivers/dri/i915/i830_state.c
+@@ -30,6 +30,7 @@
+ #include "main/context.h"
+ #include "main/macros.h"
+ #include "main/enums.h"
++#include "main/fbobject.h"
+ #include "main/dd.h"
+ #include "main/state.h"
+
+@@ -545,7 +546,7 @@ i830Scissor(struct gl_context * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+
+ DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h);
+
+- if (ctx->DrawBuffer->Name == 0) {
++ if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+ x1 = x;
+ y1 = ctx->DrawBuffer->Height - (y + h);
+ x2 = x + w - 1;
+diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
+index 94c7327..3ab75a9 100644
+--- a/src/mesa/drivers/dri/i915/i915_state.c
++++ b/src/mesa/drivers/dri/i915/i915_state.c
+@@ -30,6 +30,7 @@
+ #include "main/context.h"
+ #include "main/macros.h"
+ #include "main/enums.h"
++#include "main/fbobject.h"
+ #include "main/dd.h"
+ #include "main/state.h"
+ #include "tnl/tnl.h"
+@@ -400,7 +401,7 @@ intelCalcViewport(struct gl_context * ctx)
+ {
+ struct intel_context *intel = intel_context(ctx);
+
+- if (ctx->DrawBuffer->Name == 0) {
++ if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+ _math_matrix_viewport(&intel->ViewportMatrix,
+ ctx->Viewport.X,
+ ctx->DrawBuffer->Height - ctx->Viewport.Y,
+@@ -518,7 +519,7 @@ i915Scissor(struct gl_context * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+
+ DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h);
+
+- if (ctx->DrawBuffer->Name == 0) {
++ if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+ x1 = x;
+ y1 = ctx->DrawBuffer->Height - (y + h);
+ x2 = x + w - 1;
+@@ -577,7 +578,7 @@ i915CullFaceFrontFace(struct gl_context * ctx, GLenum unused)
+ else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
+ mode = S4_CULLMODE_CW;
+
+- if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0)
++ if (ctx->DrawBuffer && _mesa_is_user_fbo(ctx->DrawBuffer))
+ mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);
+ if (ctx->Polygon.CullFaceMode == GL_FRONT)
+ mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);
+diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
+index a66ccc7..78bc6f9 100644
+--- a/src/mesa/drivers/dri/i965/brw_context.c
++++ b/src/mesa/drivers/dri/i965/brw_context.c
+@@ -240,7 +240,7 @@ brwCreateContext(int api,
+ /* WM maximum threads is number of EUs times number of threads per EU. */
+ if (intel->gen >= 7) {
+ if (intel->gt == 1) {
+- brw->max_wm_threads = 86;
++ brw->max_wm_threads = 48;
+ brw->max_vs_threads = 36;
+ brw->max_gs_threads = 36;
+ brw->urb.size = 128;
+diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
+index 20b57bd..f213ca2 100644
+--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
++++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
+@@ -35,6 +35,7 @@ extern "C" {
+ #include "main/macros.h"
+ #include "main/shaderobj.h"
+ #include "main/uniforms.h"
++#include "main/fbobject.h"
+ #include "program/prog_parameter.h"
+ #include "program/prog_print.h"
+ #include "program/register_allocate.h"
+@@ -1595,6 +1596,9 @@ fs_visitor::compute_to_mrf()
+ }
+ }
+
++ if (progress)
++ live_intervals_valid = false;
++
+ return progress;
+ }
+
+@@ -1671,6 +1675,9 @@ fs_visitor::remove_duplicate_mrf_writes()
+ }
+ }
+
++ if (progress)
++ live_intervals_valid = false;
++
+ return progress;
+ }
+
+@@ -1883,6 +1890,7 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
+ struct gl_fragment_program *fp = (struct gl_fragment_program *)
+ prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
+ struct brw_fragment_program *bfp = brw_fragment_program(fp);
++ bool program_uses_dfdy = fp->UsesDFdy;
+
+ memset(&key, 0, sizeof(key));
+
+@@ -1921,7 +1929,10 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
+
+ if (fp->Base.InputsRead & FRAG_BIT_WPOS) {
+ key.drawable_height = ctx->DrawBuffer->Height;
+- key.render_to_fbo = ctx->DrawBuffer->Name != 0;
++ }
++
++ if ((fp->Base.InputsRead & FRAG_BIT_WPOS) || program_uses_dfdy) {
++ key.render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
+ }
+
+ key.nr_color_regions = 1;
+diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
+index d43a782..f557138 100644
+--- a/src/mesa/drivers/dri/i965/brw_fs.h
++++ b/src/mesa/drivers/dri/i965/brw_fs.h
+@@ -410,6 +410,7 @@ public:
+
+ this->frag_depth = NULL;
+ memset(this->outputs, 0, sizeof(this->outputs));
++ memset(this->output_components, 0, sizeof(this->output_components));
+ this->first_non_payload_grf = 0;
+ this->max_grf = intel->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF;
+
+@@ -542,7 +543,8 @@ public:
+ struct brw_reg src);
+ void generate_discard(fs_inst *inst);
+ void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src);
+- void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src);
++ void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src,
++ bool negate_value);
+ void generate_spill(fs_inst *inst, struct brw_reg src);
+ void generate_unspill(fs_inst *inst, struct brw_reg dst);
+ void generate_pull_constant_load(fs_inst *inst, struct brw_reg dst);
+diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+index cc70904..e7871a0 100644
+--- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
++++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+@@ -475,8 +475,13 @@ fs_visitor::generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
+ brw_ADD(p, dst, src0, negate(src1));
+ }
+
++/* The negate_value boolean is used to negate the derivative computation for
++ * FBOs, since they place the origin at the upper left instead of the lower
++ * left.
++ */
+ void
+-fs_visitor::generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
++fs_visitor::generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src,
++ bool negate_value)
+ {
+ struct brw_reg src0 = brw_reg(src.file, src.nr, 0,
+ BRW_REGISTER_TYPE_F,
+@@ -490,7 +495,10 @@ fs_visitor::generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
+ BRW_WIDTH_4,
+ BRW_HORIZONTAL_STRIDE_0,
+ BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
+- brw_ADD(p, dst, src0, negate(src1));
++ if (negate_value)
++ brw_ADD(p, dst, src1, negate(src0));
++ else
++ brw_ADD(p, dst, src0, negate(src1));
+ }
+
+ void
+@@ -913,7 +921,11 @@ fs_visitor::generate_code()
+ generate_ddx(inst, dst, src[0]);
+ break;
+ case FS_OPCODE_DDY:
+- generate_ddy(inst, dst, src[0]);
++ /* Make sure fp->UsesDFdy flag got set (otherwise there's no
++ * guarantee that c->key.render_to_fbo is set).
++ */
++ assert(fp->UsesDFdy);
++ generate_ddy(inst, dst, src[0], c->key.render_to_fbo);
+ break;
+
+ case FS_OPCODE_SPILL:
+diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
+index 07462d3..d2c9246 100644
+--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
++++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
+@@ -40,6 +40,8 @@
+ #include "brw_state.h"
+ #include "brw_defines.h"
+
++#include "main/fbobject.h"
++
+ /* Constant single cliprect for framebuffer object or DRI2 drawing */
+ static void upload_drawing_rect(struct brw_context *brw)
+ {
+@@ -376,6 +378,24 @@ static void emit_depthbuffer(struct brw_context *brw)
+ assert(intel->gen < 6 || region->tiling == I915_TILING_Y);
+ assert(!hiz_region || region->tiling == I915_TILING_Y);
+
++ /* According to the Sandy Bridge PRM, volume 2 part 1, pp326-327
++ * (3DSTATE_DEPTH_BUFFER dw5), in the documentation for "Depth
++ * Coordinate Offset X/Y":
++ *
++ * "The 3 LSBs of both offsets must be zero to ensure correct
++ * alignment"
++ *
++ * We have no guarantee that tile_x and tile_y are correctly aligned,
++ * since they are determined by the mipmap layout, which is only aligned
++ * to multiples of 4.
++ *
++ * So, to avoid hanging the GPU, just smash the low order 3 bits of
++ * tile_x and tile_y to 0. This is a temporary workaround until we come
++ * up with a better solution.
++ */
++ tile_x &= ~7;
++ tile_y &= ~7;
++
+ BEGIN_BATCH(len);
+ OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (len - 2));
+ OUT_BATCH(((region->pitch * region->cpp) - 1) |
+@@ -506,7 +526,7 @@ static void upload_polygon_stipple(struct brw_context *brw)
+ * to a FBO (i.e. any named frame buffer object), we *don't*
+ * need to invert - we already match the layout.
+ */
+- if (ctx->DrawBuffer->Name == 0) {
++ if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+ for (i = 0; i < 32; i++)
+ OUT_BATCH(ctx->PolygonStipple[31 - i]); /* invert */
+ }
+@@ -549,15 +569,13 @@ static void upload_polygon_stipple_offset(struct brw_context *brw)
+
+ /* _NEW_BUFFERS
+ *
+- * If we're drawing to a system window (ctx->DrawBuffer->Name == 0),
+- * we have to invert the Y axis in order to match the OpenGL
+- * pixel coordinate system, and our offset must be matched
+- * to the window position. If we're drawing to a FBO
+- * (ctx->DrawBuffer->Name != 0), then our native pixel coordinate
+- * system works just fine, and there's no window system to
+- * worry about.
++ * If we're drawing to a system window we have to invert the Y axis
++ * in order to match the OpenGL pixel coordinate system, and our
++ * offset must be matched to the window position. If we're drawing
++ * to a user-created FBO then our native pixel coordinate system
++ * works just fine, and there's no window system to worry about.
+ */
+- if (brw->intel.ctx.DrawBuffer->Name == 0)
++ if (_mesa_is_winsys_fbo(brw->intel.ctx.DrawBuffer))
+ OUT_BATCH((32 - (ctx->DrawBuffer->Height & 31)) & 31);
+ else
+ OUT_BATCH(0);
+diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c
+index ccef3e83..4c605dd 100644
+--- a/src/mesa/drivers/dri/i965/brw_sf.c
++++ b/src/mesa/drivers/dri/i965/brw_sf.c
+@@ -32,7 +32,9 @@
+
+ #include "main/glheader.h"
+ #include "main/macros.h"
++#include "main/mtypes.h"
+ #include "main/enums.h"
++#include "main/fbobject.h"
+
+ #include "intel_batchbuffer.h"
+
+@@ -136,7 +138,7 @@ brw_upload_sf_prog(struct brw_context *brw)
+ struct gl_context *ctx = &brw->intel.ctx;
+ struct brw_sf_prog_key key;
+ /* _NEW_BUFFERS */
+- bool render_to_fbo = ctx->DrawBuffer->Name != 0;
++ bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
+
+ memset(&key, 0, sizeof(key));
+
+diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
+index d7e7aa1..7c29ba2 100644
+--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
++++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
+@@ -31,10 +31,12 @@
+
+
+
++#include "main/mtypes.h"
++#include "main/macros.h"
++#include "main/fbobject.h"
+ #include "brw_context.h"
+ #include "brw_state.h"
+ #include "brw_defines.h"
+-#include "main/macros.h"
+ #include "brw_sf.h"
+
+ static void upload_sf_vp(struct brw_context *brw)
+@@ -44,7 +46,7 @@ static void upload_sf_vp(struct brw_context *brw)
+ const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
+ struct brw_sf_viewport *sfv;
+ GLfloat y_scale, y_bias;
+- const bool render_to_fbo = (ctx->DrawBuffer->Name != 0);
++ const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+
+ sfv = brw_state_batch(brw, AUB_TRACE_SF_VP_STATE,
+@@ -142,7 +144,7 @@ static void upload_sf_unit( struct brw_context *brw )
+ struct brw_sf_unit_state *sf;
+ drm_intel_bo *bo = intel->batch.bo;
+ int chipset_max_threads;
+- bool render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
++ bool render_to_fbo = _mesa_is_user_fbo(brw->intel.ctx.DrawBuffer);
+
+ sf = brw_state_batch(brw, AUB_TRACE_SF_STATE,
+ sizeof(*sf), 64, &brw->sf.state_offset);
+diff --git a/src/mesa/drivers/dri/i965/brw_vs_constval.c b/src/mesa/drivers/dri/i965/brw_vs_constval.c
+index 5b26c7a..3d53843 100644
+--- a/src/mesa/drivers/dri/i965/brw_vs_constval.c
++++ b/src/mesa/drivers/dri/i965/brw_vs_constval.c
+@@ -143,14 +143,12 @@ static void calc_sizes( struct tracker *t )
+ /* Examine vertex program output sizes to set the size_masks[] info
+ * which describes the fragment program input sizes.
+ */
+- for (vertRes = VERT_RESULT_TEX0; vertRes < VERT_RESULT_MAX; vertRes++) {
++ for (vertRes = 0; vertRes < VERT_RESULT_MAX; vertRes++) {
+
+ /* map vertex program output index to fragment program input index */
+ GLint fragAttrib = _mesa_vert_result_to_frag_attrib(vertRes);
+ if (fragAttrib < 0)
+ continue;
+- assert(fragAttrib >= FRAG_ATTRIB_TEX0);
+- assert(fragAttrib <= FRAG_ATTRIB_MAX);
+
+ switch (get_output_size(t, vertRes)) {
+ case 4: t->size_masks[4-1] |= 1 << fragAttrib;
+diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
+index 7dee20b..86bc182 100644
+--- a/src/mesa/drivers/dri/i965/brw_wm.c
++++ b/src/mesa/drivers/dri/i965/brw_wm.c
+@@ -33,6 +33,7 @@
+ #include "brw_wm.h"
+ #include "brw_state.h"
+ #include "main/formats.h"
++#include "main/fbobject.h"
+ #include "main/samplerobj.h"
+ #include "program/prog_parameter.h"
+
+@@ -416,6 +417,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
+ GLuint lookup = 0;
+ GLuint line_aa;
+ GLuint i;
++ bool program_uses_dfdy = fp->program.UsesDFdy;
+
+ memset(key, 0, sizeof(*key));
+
+@@ -515,7 +517,10 @@ static void brw_wm_populate_key( struct brw_context *brw,
+ */
+ if (fp->program.Base.InputsRead & FRAG_BIT_WPOS) {
+ key->drawable_height = ctx->DrawBuffer->Height;
+- key->render_to_fbo = ctx->DrawBuffer->Name != 0;
++ }
++
++ if ((fp->program.Base.InputsRead & FRAG_BIT_WPOS) || program_uses_dfdy) {
++ key->render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
+ }
+
+ /* _NEW_BUFFERS */
+diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
+index 8f1cb8c..2cde2a0 100644
+--- a/src/mesa/drivers/dri/i965/brw_wm.h
++++ b/src/mesa/drivers/dri/i965/brw_wm.h
+@@ -346,7 +346,8 @@ void emit_ddxy(struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ bool is_ddx,
+- const struct brw_reg *arg0);
++ const struct brw_reg *arg0,
++ bool negate_value);
+ void emit_delta_xy(struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
+index 270e321..f98d2f7 100644
+--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
++++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
+@@ -457,12 +457,16 @@ void emit_frontfacing(struct brw_compile *p,
+ * between each other. We could probably do it like ddx and swizzle the right
+ * order later, but bail for now and just produce
+ * ((ss0.tl - ss0.bl)x4 (ss1.tl - ss1.bl)x4)
++ *
++ * The negate_value boolean is used to negate the d/dy computation for FBOs,
++ * since they place the origin at the upper left instead of the lower left.
+ */
+ void emit_ddxy(struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ bool is_ddx,
+- const struct brw_reg *arg0)
++ const struct brw_reg *arg0,
++ bool negate_value)
+ {
+ int i;
+ struct brw_reg src0, src1;
+@@ -498,7 +502,10 @@ void emit_ddxy(struct brw_compile *p,
+ BRW_HORIZONTAL_STRIDE_0,
+ BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
+ }
+- brw_ADD(p, dst[i], src0, negate(src1));
++ if (negate_value)
++ brw_ADD(p, dst[i], src1, negate(src0));
++ else
++ brw_ADD(p, dst[i], src0, negate(src1));
+ }
+ }
+ if (mask & SATURATE)
+@@ -1739,11 +1746,15 @@ void brw_wm_emit( struct brw_wm_compile *c )
+ break;
+
+ case OPCODE_DDX:
+- emit_ddxy(p, dst, dst_flags, true, args[0]);
++ emit_ddxy(p, dst, dst_flags, true, args[0], false);
+ break;
+
+ case OPCODE_DDY:
+- emit_ddxy(p, dst, dst_flags, false, args[0]);
++ /* Make sure fp->program.UsesDFdy flag got set (otherwise there's no
++ * guarantee that c->key.render_to_fbo is set).
++ */
++ assert(c->fp->program.UsesDFdy);
++ emit_ddxy(p, dst, dst_flags, false, args[0], c->key.render_to_fbo);
+ break;
+
+ case OPCODE_DP2:
+diff --git a/src/mesa/drivers/dri/i965/gen6_hiz.c b/src/mesa/drivers/dri/i965/gen6_hiz.c
+index a86c147..92cf1d4 100644
+--- a/src/mesa/drivers/dri/i965/gen6_hiz.c
++++ b/src/mesa/drivers/dri/i965/gen6_hiz.c
+@@ -489,6 +489,24 @@ gen6_hiz_exec(struct intel_context *intel,
+ offset = intel_renderbuffer_tile_offsets(&rb, &tile_x, &tile_y);
+ }
+
++ /* According to the Sandy Bridge PRM, volume 2 part 1, pp326-327
++ * (3DSTATE_DEPTH_BUFFER dw5), in the documentation for "Depth
++ * Coordinate Offset X/Y":
++ *
++ * "The 3 LSBs of both offsets must be zero to ensure correct
++ * alignment"
++ *
++ * We have no guarantee that tile_x and tile_y are correctly aligned,
++ * since they are determined by the mipmap layout, which is only aligned
++ * to multiples of 4.
++ *
++ * So, to avoid hanging the GPU, just smash the low order 3 bits of
++ * tile_x and tile_y to 0. This is a temporary workaround until we come
++ * up with a better solution.
++ */
++ tile_x &= ~7;
++ tile_y &= ~7;
++
+ uint32_t format;
+ switch (mt->format) {
+ case MESA_FORMAT_Z16: format = BRW_DEPTHFORMAT_D16_UNORM; break;
+diff --git a/src/mesa/drivers/dri/i965/gen6_scissor_state.c b/src/mesa/drivers/dri/i965/gen6_scissor_state.c
+index feeca28..4c7f81c 100644
+--- a/src/mesa/drivers/dri/i965/gen6_scissor_state.c
++++ b/src/mesa/drivers/dri/i965/gen6_scissor_state.c
+@@ -29,13 +29,14 @@
+ #include "brw_state.h"
+ #include "brw_defines.h"
+ #include "intel_batchbuffer.h"
++#include "main/fbobject.h"
+
+ static void
+ gen6_upload_scissor_state(struct brw_context *brw)
+ {
+ struct intel_context *intel = &brw->intel;
+ struct gl_context *ctx = &intel->ctx;
+- const bool render_to_fbo = (ctx->DrawBuffer->Name != 0);
++ const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
+ struct gen6_scissor_rect *scissor;
+ uint32_t scissor_state_offset;
+
+diff --git a/src/mesa/drivers/dri/i965/gen6_sf_state.c b/src/mesa/drivers/dri/i965/gen6_sf_state.c
+index 07b8e6d..d099b45 100644
+--- a/src/mesa/drivers/dri/i965/gen6_sf_state.c
++++ b/src/mesa/drivers/dri/i965/gen6_sf_state.c
+@@ -30,6 +30,7 @@
+ #include "brw_defines.h"
+ #include "brw_util.h"
+ #include "main/macros.h"
++#include "main/fbobject.h"
+ #include "intel_batchbuffer.h"
+
+ /**
+@@ -123,7 +124,7 @@ upload_sf_state(struct brw_context *brw)
+ uint32_t dw1, dw2, dw3, dw4, dw16, dw17;
+ int i;
+ /* _NEW_BUFFER */
+- bool render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
++ bool render_to_fbo = _mesa_is_user_fbo(brw->intel.ctx.DrawBuffer);
+ int attr = 0, input_index = 0;
+ int urb_entry_read_offset = 1;
+ float point_size;
+diff --git a/src/mesa/drivers/dri/i965/gen6_viewport_state.c b/src/mesa/drivers/dri/i965/gen6_viewport_state.c
+index 9ff2bd9..f787ac7 100644
+--- a/src/mesa/drivers/dri/i965/gen6_viewport_state.c
++++ b/src/mesa/drivers/dri/i965/gen6_viewport_state.c
+@@ -29,6 +29,7 @@
+ #include "brw_state.h"
+ #include "brw_defines.h"
+ #include "intel_batchbuffer.h"
++#include "main/fbobject.h"
+
+ /* The clip VP defines the guardband region where expensive clipping is skipped
+ * and fragments are allowed to be generated and clipped out cheaply by the SF.
+@@ -70,7 +71,7 @@ gen6_upload_sf_vp(struct brw_context *brw)
+ const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
+ struct brw_sf_viewport *sfv;
+ GLfloat y_scale, y_bias;
+- const bool render_to_fbo = (ctx->DrawBuffer->Name != 0);
++ const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+
+ sfv = brw_state_batch(brw, AUB_TRACE_SF_VP_STATE,
+diff --git a/src/mesa/drivers/dri/i965/gen7_clip_state.c b/src/mesa/drivers/dri/i965/gen7_clip_state.c
+index c32cd98..2e4daf9 100644
+--- a/src/mesa/drivers/dri/i965/gen7_clip_state.c
++++ b/src/mesa/drivers/dri/i965/gen7_clip_state.c
+@@ -26,6 +26,7 @@
+ #include "brw_defines.h"
+ #include "brw_util.h"
+ #include "intel_batchbuffer.h"
++#include "main/fbobject.h"
+
+ static void
+ upload_clip_state(struct brw_context *brw)
+@@ -40,7 +41,7 @@ upload_clip_state(struct brw_context *brw)
+ const struct gl_fragment_program *fprog = brw->fragment_program;
+
+ /* _NEW_BUFFERS */
+- bool render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
++ bool render_to_fbo = _mesa_is_user_fbo(brw->intel.ctx.DrawBuffer);
+
+ if (brw_fprog_uses_noperspective(fprog)) {
+ nonperspective_barycentric_enable_flag =
+diff --git a/src/mesa/drivers/dri/i965/gen7_hiz.c b/src/mesa/drivers/dri/i965/gen7_hiz.c
+index 34e51ab..962079e 100644
+--- a/src/mesa/drivers/dri/i965/gen7_hiz.c
++++ b/src/mesa/drivers/dri/i965/gen7_hiz.c
+@@ -349,6 +349,24 @@ gen7_hiz_exec(struct intel_context *intel,
+ offset = intel_renderbuffer_tile_offsets(&rb, &tile_x, &tile_y);
+ }
+
++ /* According to the Sandy Bridge PRM, volume 2 part 1, pp326-327
++ * (3DSTATE_DEPTH_BUFFER dw5), in the documentation for "Depth
++ * Coordinate Offset X/Y":
++ *
++ * "The 3 LSBs of both offsets must be zero to ensure correct
++ * alignment"
++ *
++ * We have no guarantee that tile_x and tile_y are correctly aligned,
++ * since they are determined by the mipmap layout, which is only aligned
++ * to multiples of 4.
++ *
++ * So, to avoid hanging the GPU, just smash the low order 3 bits of
++ * tile_x and tile_y to 0. This is a temporary workaround until we come
++ * up with a better solution.
++ */
++ tile_x &= ~7;
++ tile_y &= ~7;
++
+ intel_emit_depth_stall_flushes(intel);
+
+ BEGIN_BATCH(7);
+diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c
+index d0ce542..870702f 100644
+--- a/src/mesa/drivers/dri/i965/gen7_misc_state.c
++++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c
+@@ -93,6 +93,24 @@ static void emit_depthbuffer(struct brw_context *brw)
+
+ offset = intel_renderbuffer_tile_offsets(drb, &tile_x, &tile_y);
+
++ /* According to the Sandy Bridge PRM, volume 2 part 1, pp326-327
++ * (3DSTATE_DEPTH_BUFFER dw5), in the documentation for "Depth
++ * Coordinate Offset X/Y":
++ *
++ * "The 3 LSBs of both offsets must be zero to ensure correct
++ * alignment"
++ *
++ * We have no guarantee that tile_x and tile_y are correctly aligned,
++ * since they are determined by the mipmap layout, which is only aligned
++ * to multiples of 4.
++ *
++ * So, to avoid hanging the GPU, just smash the low order 3 bits of
++ * tile_x and tile_y to 0. This is a temporary workaround until we come
++ * up with a better solution.
++ */
++ tile_x &= ~7;
++ tile_y &= ~7;
++
+ assert(region->tiling == I915_TILING_Y);
+
+ /* _NEW_DEPTH, _NEW_STENCIL */
+diff --git a/src/mesa/drivers/dri/i965/gen7_sf_state.c b/src/mesa/drivers/dri/i965/gen7_sf_state.c
+index b215af2..e86829a 100644
+--- a/src/mesa/drivers/dri/i965/gen7_sf_state.c
++++ b/src/mesa/drivers/dri/i965/gen7_sf_state.c
+@@ -26,6 +26,7 @@
+ #include "brw_defines.h"
+ #include "brw_util.h"
+ #include "main/macros.h"
++#include "main/fbobject.h"
+ #include "intel_batchbuffer.h"
+
+ static void
+@@ -49,7 +50,7 @@ upload_sbe_state(struct brw_context *brw)
+ bool userclip_active = (ctx->Transform.ClipPlanesEnabled != 0);
+ uint16_t attr_overrides[FRAG_ATTRIB_MAX];
+ /* _NEW_BUFFERS */
+- bool render_to_fbo = ctx->DrawBuffer->Name != 0;
++ bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
+ uint32_t point_sprite_origin;
+
+ brw_compute_vue_map(&vue_map, intel, userclip_active, vs_outputs_written);
+@@ -163,7 +164,7 @@ upload_sf_state(struct brw_context *brw)
+ uint32_t dw1, dw2, dw3;
+ float point_size;
+ /* _NEW_BUFFERS */
+- bool render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
++ bool render_to_fbo = _mesa_is_user_fbo(brw->intel.ctx.DrawBuffer);
+
+ dw1 = GEN6_SF_STATISTICS_ENABLE |
+ GEN6_SF_VIEWPORT_TRANSFORM_ENABLE;
+diff --git a/src/mesa/drivers/dri/i965/gen7_viewport_state.c b/src/mesa/drivers/dri/i965/gen7_viewport_state.c
+index d0b89d5..2bcf338 100644
+--- a/src/mesa/drivers/dri/i965/gen7_viewport_state.c
++++ b/src/mesa/drivers/dri/i965/gen7_viewport_state.c
+@@ -25,6 +25,7 @@
+ #include "brw_state.h"
+ #include "brw_defines.h"
+ #include "intel_batchbuffer.h"
++#include "main/fbobject.h"
+
+ static void
+ gen7_upload_sf_clip_viewport(struct brw_context *brw)
+@@ -33,7 +34,7 @@ gen7_upload_sf_clip_viewport(struct brw_context *brw)
+ struct gl_context *ctx = &intel->ctx;
+ const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
+ GLfloat y_scale, y_bias;
+- const bool render_to_fbo = (ctx->DrawBuffer->Name != 0);
++ const bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+ struct gen7_sf_clip_viewport *vp;
+
+diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
+index 9809f79..2b02763 100644
+--- a/src/mesa/drivers/dri/intel/intel_buffers.c
++++ b/src/mesa/drivers/dri/intel/intel_buffers.c
+@@ -30,6 +30,7 @@
+ #include "intel_fbo.h"
+ #include "intel_mipmap_tree.h"
+
++#include "main/fbobject.h"
+ #include "main/framebuffer.h"
+ #include "main/renderbuffer.h"
+
+@@ -82,7 +83,7 @@ intel_check_front_buffer_rendering(struct intel_context *intel)
+ static void
+ intelDrawBuffer(struct gl_context * ctx, GLenum mode)
+ {
+- if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
++ if (ctx->DrawBuffer && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+ struct intel_context *const intel = intel_context(ctx);
+ const bool was_front_buffer_rendering =
+ intel->is_front_buffer_rendering;
+@@ -105,7 +106,7 @@ intelDrawBuffer(struct gl_context * ctx, GLenum mode)
+ static void
+ intelReadBuffer(struct gl_context * ctx, GLenum mode)
+ {
+- if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
++ if (ctx->DrawBuffer && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+ struct intel_context *const intel = intel_context(ctx);
+ const bool was_front_buffer_reading =
+ intel->is_front_buffer_reading;
+diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
+index faf81ee..a9e663c 100644
+--- a/src/mesa/drivers/dri/intel/intel_context.c
++++ b/src/mesa/drivers/dri/intel/intel_context.c
+@@ -206,7 +206,7 @@ intel_flush_front(struct gl_context *ctx)
+ __DRIcontext *driContext = intel->driContext;
+ __DRIscreen *const screen = intel->intelScreen->driScrnPriv;
+
+- if ((ctx->DrawBuffer->Name == 0) && intel->front_buffer_dirty) {
++ if (_mesa_is_winsys_fbo(ctx->DrawBuffer) && intel->front_buffer_dirty) {
+ if (screen->dri2.loader &&
+ (screen->dri2.loader->base.version >= 2)
+ && (screen->dri2.loader->flushFrontBuffer != NULL) &&
+@@ -445,7 +445,7 @@ intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+ if (intel->saved_viewport)
+ intel->saved_viewport(ctx, x, y, w, h);
+
+- if (ctx->DrawBuffer->Name == 0) {
++ if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+ dri2InvalidateDrawable(driContext->driDrawablePriv);
+ dri2InvalidateDrawable(driContext->driReadablePriv);
+ }
+diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c
+index 34fed3d..ab4e581 100644
+--- a/src/mesa/drivers/dri/intel/intel_pixel_read.c
++++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c
+@@ -29,6 +29,7 @@
+ #include "main/enums.h"
+ #include "main/mtypes.h"
+ #include "main/macros.h"
++#include "main/fbobject.h"
+ #include "main/image.h"
+ #include "main/bufferobj.h"
+ #include "main/readpix.h"
+@@ -116,7 +117,7 @@ do_blit_readpixels(struct gl_context * ctx,
+ return false;
+ }
+ else {
+- if (ctx->ReadBuffer->Name == 0)
++ if (_mesa_is_winsys_fbo(ctx->ReadBuffer))
+ rowLength = -rowLength;
+ }
+
+@@ -145,7 +146,7 @@ do_blit_readpixels(struct gl_context * ctx,
+ all ? INTEL_WRITE_FULL :
+ INTEL_WRITE_PART);
+
+- if (ctx->ReadBuffer->Name == 0)
++ if (_mesa_is_winsys_fbo(ctx->ReadBuffer))
+ y = ctx->ReadBuffer->Height - (y + height);
+
+ if (!intelEmitCopyBlit(intel,
+diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
+index adea0f5..a6b5309 100644
+--- a/src/mesa/main/buffers.c
++++ b/src/mesa/main/buffers.c
+@@ -35,6 +35,7 @@
+ #include "colormac.h"
+ #include "context.h"
+ #include "enums.h"
++#include "fbobject.h"
+ #include "mtypes.h"
+
+
+@@ -55,7 +56,7 @@ supported_buffer_bitmask(const struct gl_context *ctx, const struct gl_framebuff
+ {
+ GLbitfield mask = 0x0;
+
+- if (fb->Name > 0) {
++ if (_mesa_is_user_fbo(fb)) {
+ /* A user-created renderbuffer */
+ GLuint i;
+ ASSERT(ctx->Extensions.EXT_framebuffer_object);
+@@ -354,7 +355,7 @@ updated_drawbuffers(struct gl_context *ctx)
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+
+ /* Flag the FBO as requiring validation. */
+- if (fb->Name != 0) {
++ if (_mesa_is_user_fbo(fb)) {
+ fb->_Status = 0;
+ }
+ }
+@@ -448,7 +449,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
+ fb->ColorDrawBuffer[buf] = GL_NONE;
+ }
+
+- if (fb->Name == 0) {
++ if (_mesa_is_winsys_fbo(fb)) {
+ /* also set context drawbuffer state */
+ for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
+ if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) {
+@@ -472,7 +473,7 @@ _mesa_update_draw_buffers(struct gl_context *ctx)
+ GLuint i;
+
+ /* should be a window system FBO */
+- assert(ctx->DrawBuffer->Name == 0);
++ assert(_mesa_is_winsys_fbo(ctx->DrawBuffer));
+
+ for (i = 0; i < ctx->Const.MaxDrawBuffers; i++)
+ buffers[i] = ctx->Color.DrawBuffer[i];
+@@ -493,7 +494,7 @@ _mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex)
+ {
+ struct gl_framebuffer *fb = ctx->ReadBuffer;
+
+- if (fb->Name == 0) {
++ if (_mesa_is_winsys_fbo(fb)) {
+ /* Only update the per-context READ_BUFFER state if we're bound to
+ * a window-system framebuffer.
+ */
+@@ -529,7 +530,7 @@ _mesa_ReadBuffer(GLenum buffer)
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
+
+- if (fb->Name > 0 && buffer == GL_NONE) {
++ if (_mesa_is_user_fbo(fb) && buffer == GL_NONE) {
+ /* This is legal for user-created framebuffer objects */
+ srcBuffer = -1;
+ }
+diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
+index b7b1e44..f9d4435 100644
+--- a/src/mesa/main/extensions.c
++++ b/src/mesa/main/extensions.c
+@@ -916,7 +916,7 @@ _mesa_get_extension_count(struct gl_context *ctx)
+
+ base = (GLboolean *) &ctx->Extensions;
+ for (i = extension_table; i->name != 0; ++i) {
+- if (base[i->offset]) {
++ if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
+ ctx->Extensions.Count++;
+ }
+ }
+@@ -939,10 +939,11 @@ _mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
+ base = (GLboolean*) &ctx->Extensions;
+ n = 0;
+ for (i = extension_table; i->name != 0; ++i) {
+- if (n == index && base[i->offset]) {
+- return (GLubyte*) i->name;
+- } else if (base[i->offset]) {
+- ++n;
++ if (base[i->offset] & (i->api_set & (1 << ctx->API))) {
++ if (n == index)
++ return (const GLubyte*) i->name;
++ else
++ ++n;
+ }
+ }
+
+diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
+index 64f592a..68da579 100644
+--- a/src/mesa/main/fbobject.c
++++ b/src/mesa/main/fbobject.c
+@@ -79,26 +79,6 @@ static struct gl_renderbuffer DummyRenderbuffer;
+ static struct gl_framebuffer IncompleteFramebuffer;
+
+
+-/**
+- * Is the given FBO a user-created FBO?
+- */
+-static inline GLboolean
+-is_user_fbo(const struct gl_framebuffer *fb)
+-{
+- return fb->Name != 0;
+-}
+-
+-
+-/**
+- * Is the given FBO a window system FBO (like an X window)?
+- */
+-static inline GLboolean
+-is_winsys_fbo(const struct gl_framebuffer *fb)
+-{
+- return fb->Name == 0;
+-}
+-
+-
+ static void
+ delete_dummy_renderbuffer(struct gl_renderbuffer *rb)
+ {
+@@ -214,7 +194,7 @@ _mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
+ {
+ GLuint i;
+
+- assert(is_user_fbo(fb));
++ assert(_mesa_is_user_fbo(fb));
+
+ switch (attachment) {
+ case GL_COLOR_ATTACHMENT0_EXT:
+@@ -265,7 +245,7 @@ static struct gl_renderbuffer_attachment *
+ _mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
+ GLenum attachment)
+ {
+- assert(is_winsys_fbo(fb));
++ assert(_mesa_is_winsys_fbo(fb));
+
+ switch (attachment) {
+ case GL_FRONT_LEFT:
+@@ -711,7 +691,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
+ GLint i;
+ GLuint j;
+
+- assert(is_user_fbo(fb));
++ assert(_mesa_is_user_fbo(fb));
+
+ numImages = 0;
+ fb->Width = 0;
+@@ -1009,10 +989,10 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
+ _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+ }
+
+- if (is_user_fbo(ctx->DrawBuffer)) {
++ if (_mesa_is_user_fbo(ctx->DrawBuffer)) {
+ detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
+ }
+- if (is_user_fbo(ctx->ReadBuffer)
++ if (_mesa_is_user_fbo(ctx->ReadBuffer)
+ && ctx->ReadBuffer != ctx->DrawBuffer) {
+ detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
+ }
+@@ -1322,7 +1302,7 @@ invalidate_rb(GLuint key, void *data, void *userData)
+ struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData;
+
+ /* If this is a user-created FBO */
+- if (is_user_fbo(fb)) {
++ if (_mesa_is_user_fbo(fb)) {
+ GLuint i;
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = fb->Attachment + i;
+@@ -1614,7 +1594,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
+ GLuint i;
+ ASSERT(ctx->Driver.RenderTexture);
+
+- if (is_winsys_fbo(fb))
++ if (_mesa_is_winsys_fbo(fb))
+ return; /* can't render to texture with winsys framebuffers */
+
+ for (i = 0; i < BUFFER_COUNT; i++) {
+@@ -1634,7 +1614,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
+ static void
+ check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
+ {
+- if (is_winsys_fbo(fb))
++ if (_mesa_is_winsys_fbo(fb))
+ return; /* can't render to texture with winsys framebuffers */
+
+ if (ctx->Driver.FinishRenderTexture) {
+@@ -1887,7 +1867,7 @@ _mesa_CheckFramebufferStatusEXT(GLenum target)
+ return 0;
+ }
+
+- if (is_winsys_fbo(buffer)) {
++ if (_mesa_is_winsys_fbo(buffer)) {
+ /* The window system / default framebuffer is always complete */
+ return GL_FRAMEBUFFER_COMPLETE_EXT;
+ }
+@@ -1950,7 +1930,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
+ }
+
+ /* check framebuffer binding */
+- if (is_winsys_fbo(fb)) {
++ if (_mesa_is_winsys_fbo(fb)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTexture%sEXT", caller);
+ return;
+@@ -2211,7 +2191,7 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
+ return;
+ }
+
+- if (is_winsys_fbo(fb)) {
++ if (_mesa_is_winsys_fbo(fb)) {
+ /* Can't attach new renderbuffers to a window system framebuffer */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
+ return;
+@@ -2292,7 +2272,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
+ return;
+ }
+
+- if (is_winsys_fbo(buffer)) {
++ if (_mesa_is_winsys_fbo(buffer)) {
+ /* Page 126 (page 136 of the PDF) of the OpenGL ES 2.0.25 spec
+ * says:
+ *
+@@ -2339,7 +2319,8 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
+
+ switch (pname) {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
+- *params = is_winsys_fbo(buffer) ? GL_FRAMEBUFFER_DEFAULT : att->Type;
++ *params = _mesa_is_winsys_fbo(buffer)
++ ? GL_FRAMEBUFFER_DEFAULT : att->Type;
+ return;
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
+ if (att->Type == GL_RENDERBUFFER_EXT) {
+diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h
+index 0a70a43..3aee842 100644
+--- a/src/mesa/main/fbobject.h
++++ b/src/mesa/main/fbobject.h
+@@ -32,6 +32,28 @@
+ struct gl_context;
+ struct gl_texture_object;
+
++
++/**
++ * Is the given FBO a user-created FBO?
++ */
++static inline GLboolean
++_mesa_is_user_fbo(const struct gl_framebuffer *fb)
++{
++ return fb->Name != 0;
++}
++
++
++/**
++ * Is the given FBO a window system FBO (like an X window)?
++ */
++static inline GLboolean
++_mesa_is_winsys_fbo(const struct gl_framebuffer *fb)
++{
++ return fb->Name == 0;
++}
++
++
++
+ extern void
+ _mesa_init_fbobjects(struct gl_context *ctx);
+
+diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
+index d11b167..d566249 100644
+--- a/src/mesa/main/formats.c
++++ b/src/mesa/main/formats.c
+@@ -1860,8 +1860,7 @@ _mesa_format_image_size(gl_format format, GLsizei width,
+ const GLuint wblocks = (width + bw - 1) / bw;
+ const GLuint hblocks = (height + bh - 1) / bh;
+ const GLuint sz = wblocks * hblocks * info->BytesPerBlock;
+- assert(depth == 1);
+- return sz;
++ return sz * depth;
+ }
+ else {
+ /* non-compressed */
+@@ -1887,8 +1886,7 @@ _mesa_format_image_size64(gl_format format, GLsizei width,
+ const uint64_t wblocks = (width + bw - 1) / bw;
+ const uint64_t hblocks = (height + bh - 1) / bh;
+ const uint64_t sz = wblocks * hblocks * info->BytesPerBlock;
+- assert(depth == 1);
+- return sz;
++ return sz * depth;
+ }
+ else {
+ /* non-compressed */
+diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
+index 730de62..10cfaf5 100644
+--- a/src/mesa/main/framebuffer.c
++++ b/src/mesa/main/framebuffer.c
+@@ -281,8 +281,8 @@ _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
+ * and return early.
+ */
+
+- /* For window system framebuffers, Name is zero */
+- assert(fb->Name == 0);
++ /* Can only resize win-sys framebuffer objects */
++ assert(_mesa_is_winsys_fbo(fb));
+
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
+@@ -408,7 +408,7 @@ update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
+ GLuint i;
+
+ /* user-created framebuffers only */
+- assert(fb->Name);
++ assert(_mesa_is_user_fbo(fb));
+
+ for (i = 0; i < BUFFER_COUNT; i++) {
+ struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
+@@ -687,7 +687,7 @@ update_color_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb)
+ static void
+ update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
+ {
+- if (fb->Name == 0) {
++ if (_mesa_is_winsys_fbo(fb)) {
+ /* This is a window-system framebuffer */
+ /* Need to update the FB's GL_DRAW_BUFFER state to match the
+ * context state (GL_READ_BUFFER too).
+diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
+index b86aeb6..cc6e9bd 100644
+--- a/src/mesa/main/mtypes.h
++++ b/src/mesa/main/mtypes.h
+@@ -1974,6 +1974,7 @@ struct gl_fragment_program
+ {
+ struct gl_program Base; /**< base class */
+ GLboolean UsesKill; /**< shader uses KIL instruction */
++ GLboolean UsesDFdy; /**< shader uses DDY instruction */
+ GLboolean OriginUpperLeft;
+ GLboolean PixelCenterInteger;
+ enum gl_frag_depth_layout FragDepthLayout;
+diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c
+index 4b0ee79..f3f9283 100644
+--- a/src/mesa/main/pack.c
++++ b/src/mesa/main/pack.c
+@@ -4900,7 +4900,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
+ else {
+ /* need to use double precision to prevent overflow problems */
+ for (i = 0; i < n; i++) {
+- GLdouble z = depthValues[i] * (GLfloat) depthMax;
++ GLdouble z = depthValues[i] * (GLdouble) depthMax;
+ if (z >= (GLdouble) 0xffffffff)
+ zValues[i] = 0xffffffff;
+ else
+diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
+index d139386..1bb09bf 100644
+--- a/src/mesa/main/renderbuffer.c
++++ b/src/mesa/main/renderbuffer.c
+@@ -104,7 +104,7 @@ _mesa_add_renderbuffer(struct gl_framebuffer *fb,
+ fb->Attachment[bufferName].Renderbuffer == NULL);
+
+ /* winsys vs. user-created buffer cross check */
+- if (fb->Name) {
++ if (_mesa_is_user_fbo(fb)) {
+ assert(rb->Name);
+ }
+ else {
+diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
+index 077c196..4c1acac 100644
+--- a/src/mesa/main/teximage.c
++++ b/src/mesa/main/teximage.c
+@@ -1984,7 +1984,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
+ }
+
+ /* Check that the source buffer is complete */
+- if (ctx->ReadBuffer->Name) {
++ if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
+ if (ctx->ReadBuffer->_Status == 0) {
+ _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
+ }
+@@ -2109,7 +2109,7 @@ copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
+ GLenum target, GLint level)
+ {
+ /* Check that the source buffer is complete */
+- if (ctx->ReadBuffer->Name) {
++ if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
+ if (ctx->ReadBuffer->_Status == 0) {
+ _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
+ }
+@@ -2301,7 +2301,7 @@ check_rtt_cb(GLuint key, void *data, void *userData)
+ const GLuint level = info->level, face = info->face;
+
+ /* If this is a user-created FBO */
+- if (fb->Name) {
++ if (_mesa_is_user_fbo(fb)) {
+ GLuint i;
+ /* check if any of the FBO's attachments point to 'texObj' */
+ for (i = 0; i < BUFFER_COUNT; i++) {
+diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
+index dc6e309..1b61d3a 100644
+--- a/src/mesa/main/texobj.c
++++ b/src/mesa/main/texobj.c
+@@ -893,7 +893,7 @@ unbind_texobj_from_fbo(struct gl_context *ctx,
+
+ for (i = 0; i < n; i++) {
+ struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer;
+- if (fb->Name) {
++ if (_mesa_is_user_fbo(fb)) {
+ GLuint j;
+ for (j = 0; j < BUFFER_COUNT; j++) {
+ if (fb->Attachment[j].Type == GL_TEXTURE &&
+diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c
+index 582cbcc..3ad8377 100644
+--- a/src/mesa/program/program.c
++++ b/src/mesa/program/program.c
+@@ -551,6 +551,7 @@ _mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog)
+ = (const struct gl_fragment_program *) prog;
+ struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone;
+ fpc->UsesKill = fp->UsesKill;
++ fpc->UsesDFdy = fp->UsesDFdy;
+ fpc->OriginUpperLeft = fp->OriginUpperLeft;
+ fpc->PixelCenterInteger = fp->PixelCenterInteger;
+ }
+@@ -772,6 +773,7 @@ _mesa_combine_programs(struct gl_context *ctx,
+ newFprog = (struct gl_fragment_program *) newProg;
+
+ newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
++ newFprog->UsesDFdy = fprogA->UsesDFdy || fprogB->UsesDFdy;
+
+ /* We'll do a search and replace for instances
+ * of progB_colorFile/progB_colorIndex below...
diff --git a/mesa.spec b/mesa.spec
index 21abf4c..6f9e6df 100644
--- a/mesa.spec
+++ b/mesa.spec
@@ -35,8 +35,8 @@
Summary: Mesa graphics libraries
Name: mesa
-Version: 8.0.3
-Release: 3%{?dist}
+Version: 8.0.4
+Release: 1%{?dist}
License: MIT
Group: System Environment/Libraries
URL: http://www.mesa3d.org
@@ -54,7 +54,7 @@ Patch9: mesa-8.0-llvmpipe-shmget.patch
Patch12: mesa-8.0.1-fix-16bpp.patch
Patch13: mesa-8.0-nouveau-vieux-nvfx-lowmem.patch
Patch14: mesa-8.0-nouveau-vieux-finish.patch
-Patch15: mesa-8.0.3-git.patch
+Patch15: mesa-8.0.4-git.patch
BuildRequires: pkgconfig autoconf automake libtool
%if %{with_hardware}
@@ -570,6 +570,9 @@ rm -rf $RPM_BUILD_ROOT
%endif
%changelog
+* Wed Sep 19 2012 Dave Airlie 8.0.4-1
+- rebase to 8.0.4 release + 8.0 branch fixes
+
* Mon Jun 25 2012 Adam Jackson 8.0.3-3
- mesa-8.0.3-git.patch: Sync with 8.0 branch.
diff --git a/sources b/sources
index 865fbbe..bf5f679 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
6ae05158e678f4594343f32c2ca50515 gl-manpages-1.0.1.tar.bz2
-cc5ee15e306b8c15da6a478923797171 MesaLib-8.0.3.tar.bz2
+d546f988adfdf986cff45b1efa2d8a46 MesaLib-8.0.4.tar.bz2