[mesa/f19] rebase to Mesa 9.1.1 + fixes from git

Dave Airlie airlied at fedoraproject.org
Sat Apr 27 07:30:20 UTC 2013


commit 8a2a35f7ff928053cfc424f2155c67e0fac4308f
Author: Dave Airlie <airlied at gmail.com>
Date:   Sat Apr 27 17:29:43 2013 +1000

    rebase to Mesa 9.1.1 + fixes from git

 .gitignore                   |    1 +
 mesa-9.0-19-g895a587.patch   | 1889 -----------------------------------
 mesa-9.0.1-22-gd0a9ab2.patch | 1834 ----------------------------------
 mesa-9.1-53-gd0ccb5b.patch   | 1974 -------------------------------------
 mesa-9.1.1-53-g3cff41c.patch | 2242 ++++++++++++++++++++++++++++++++++++++++++
 mesa.spec                    |    9 +-
 sources                      |    2 +-
 7 files changed, 2250 insertions(+), 5701 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index b475cc4..78b25bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,3 +46,4 @@ mesa-20100720.tar.bz2
 /MesaLib-9.0.1.tar.bz2
 /mesa-20130213.tar.xz
 /MesaLib-9.1.tar.bz2
+/MesaLib-9.1.1.tar.bz2
diff --git a/mesa-9.1.1-53-g3cff41c.patch b/mesa-9.1.1-53-g3cff41c.patch
new file mode 100644
index 0000000..d6b302a
--- /dev/null
+++ b/mesa-9.1.1-53-g3cff41c.patch
@@ -0,0 +1,2242 @@
+diff --git a/configure.ac b/configure.ac
+index 4a98996..1c9d606 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -452,6 +452,9 @@ if test "x$enable_asm" = xyes; then
+         linux* | *freebsd* | dragonfly* | *netbsd*)
+             test "x$enable_64bit" = xyes && asm_arch=x86_64 || asm_arch=x86
+             ;;
++        gnu*)
++            asm_arch=x86
++            ;;
+         esac
+         ;;
+     x86_64)
+@@ -826,20 +829,6 @@ if test "x$enable_dri" = xyes; then
+     fi
+ fi
+ 
+-dnl Find out if X is available.
+-PKG_CHECK_MODULES([X11], [x11], [no_x=no], [no_x=yes])
+-
+-dnl Try to tell the user that the --x-* options are only used when
+-dnl pkg-config is not available. This must be right after AC_PATH_XTRA.
+-m4_divert_once([HELP_BEGIN],
+-[These options are only used when the X libraries cannot be found by the
+-pkg-config utility.])
+-
+-dnl We need X for xlib and dri, so bomb now if it's not found
+-if test "x$enable_glx" = xyes -a "x$no_x" = xyes; then
+-    AC_MSG_ERROR([X11 development libraries needed for GLX])
+-fi
+-
+ dnl Direct rendering or just indirect rendering
+ case "$host_os" in
+ gnu*)
+diff --git a/docs/relnotes-9.1.1.html b/docs/relnotes-9.1.1.html
+index 8921c8f..a73c974 100644
+--- a/docs/relnotes-9.1.1.html
++++ b/docs/relnotes-9.1.1.html
+@@ -30,6 +30,9 @@ because GL_ARB_compatibility is not supported.
+ 
+ <h2>MD5 checksums</h2>
+ <pre>
++6508d9882d8dce7106717f365632700c  MesaLib-9.1.1.tar.gz
++6ea2bdc3b7ecfb4257b39814b4182580  MesaLib-9.1.1.tar.bz2
++3434c0eb47849a08c53cd32833d10d13  MesaLib-9.1.1.zip
+ </pre>
+ 
+ <h2>New features</h2>
+diff --git a/include/c99_compat.h b/include/c99_compat.h
+new file mode 100644
+index 0000000..3a9f502
+--- /dev/null
++++ b/include/c99_compat.h
+@@ -0,0 +1,147 @@
++/**************************************************************************
++ *
++ * Copyright 2007-2013 VMware, Inc.
++ * All Rights Reserved.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sub license, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial portions
++ * of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
++ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
++ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
++ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ *
++ **************************************************************************/
++
++#ifndef _C99_COMPAT_H_
++#define _C99_COMPAT_H_
++
++
++/*
++ * MSVC hacks.
++ */
++#if defined(_MSC_VER)
++   /*
++    * Visual Studio 2012 will complain if we define the `inline` keyword, but
++    * actually it only supports the keyword on C++.
++    *
++    * We could skip this check by defining _ALLOW_KEYWORD_MACROS, but there is
++    * probably value in checking this for other keywords.  So simply include
++    * the checking before we define it below.
++    */
++#  if _MSC_VER >= 1700
++#    include <xkeycheck.h>
++#  endif
++
++   /*
++    * XXX: MSVC has a `__restrict` keyword, but it also has a
++    * `__declspec(restrict)` modifier, so it is impossible to define a
++    * `restrict` macro without interfering with the latter.  Furthermore the
++    * MSVC standard library uses __declspec(restrict) under the _CRTRESTRICT
++    * macro.  For now resolve this issue by redefining _CRTRESTRICT, but going
++    * forward we should probably should stop using restrict, especially
++    * considering that our code does not obbey strict aliasing rules any way.
++    */
++#  include <crtdefs.h>
++#  undef _CRTRESTRICT
++#  define _CRTRESTRICT
++#endif
++
++
++/*
++ * C99 inline keyword
++ */
++#ifndef inline
++#  ifdef __cplusplus
++     /* C++ supports inline keyword */
++#  elif defined(__GNUC__)
++#    define inline __inline__
++#  elif defined(_MSC_VER)
++#    define inline __inline
++#  elif defined(__ICL)
++#    define inline __inline
++#  elif defined(__INTEL_COMPILER)
++     /* Intel compiler supports inline keyword */
++#  elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
++#    define inline __inline
++#  elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
++     /* C99 supports inline keyword */
++#  elif (__STDC_VERSION__ >= 199901L)
++     /* C99 supports inline keyword */
++#  else
++#    define inline
++#  endif
++#endif
++
++
++/*
++ * C99 restrict keyword
++ *
++ * See also:
++ * - http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html
++ */
++#ifndef restrict
++#  if (__STDC_VERSION__ >= 199901L)
++     /* C99 */
++#  elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
++     /* C99 */
++#  elif defined(__GNUC__)
++#    define restrict __restrict__
++#  elif defined(_MSC_VER)
++#    define restrict __restrict
++#  else
++#    define restrict /* */
++#  endif
++#endif
++
++
++/*
++ * C99 __func__ macro
++ */
++#ifndef __func__
++#  if (__STDC_VERSION__ >= 199901L)
++     /* C99 */
++#  elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
++     /* C99 */
++#  elif defined(__GNUC__)
++#    if __GNUC__ >= 2
++#      define __func__ __FUNCTION__
++#    else
++#      define __func__ "<unknown>"
++#    endif
++#  elif defined(_MSC_VER)
++#    if _MSC_VER >= 1300
++#      define __func__ __FUNCTION__
++#    else
++#      define __func__ "<unknown>"
++#    endif
++#  else
++#    define __func__ "<unknown>"
++#  endif
++#endif
++
++
++/* Simple test case for debugging */
++#if 0
++static inline const char *
++test_c99_compat_h(const void * restrict a,
++                  const void * restrict b)
++{
++   return __func__;
++}
++#endif
++
++
++#endif /* _C99_COMPAT_H_ */
+diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h
+index 9823693..2499172 100644
+--- a/src/egl/main/eglcompiler.h
++++ b/src/egl/main/eglcompiler.h
+@@ -31,6 +31,9 @@
+ #define EGLCOMPILER_INCLUDED
+ 
+ 
++#include "c99_compat.h" /* inline, __func__, etc. */
++
++
+ /**
+  * Get standard integer types
+  */
+@@ -62,30 +65,7 @@
+ #endif
+ 
+ 
+-/**
+- * Function inlining
+- */
+-#ifndef inline
+-#  ifdef __cplusplus
+-     /* C++ supports inline keyword */
+-#  elif defined(__GNUC__)
+-#    define inline __inline__
+-#  elif defined(_MSC_VER)
+-#    define inline __inline
+-#  elif defined(__ICL)
+-#    define inline __inline
+-#  elif defined(__INTEL_COMPILER)
+-     /* Intel compiler supports inline keyword */
+-#  elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
+-#    define inline __inline
+-#  elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
+-     /* C99 supports inline keyword */
+-#  elif (__STDC_VERSION__ >= 199901L)
+-     /* C99 supports inline keyword */
+-#  else
+-#    define inline
+-#  endif
+-#endif
++/* XXX: Use standard `inline` keyword instead */
+ #ifndef INLINE
+ #  define INLINE inline
+ #endif
+@@ -104,21 +84,9 @@
+ #  endif
+ #endif
+ 
+-/**
+- * The __FUNCTION__ gcc variable is generally only used for debugging.
+- * If we're not using gcc, define __FUNCTION__ as a cpp symbol here.
+- * Don't define it if using a newer Windows compiler.
+- */
++/* XXX: Use standard `__func__` instead */
+ #ifndef __FUNCTION__
+-# if (!defined __GNUC__) && (!defined __xlC__) && \
+-      (!defined(_MSC_VER) || _MSC_VER < 1300)
+-#  if (__STDC_VERSION__ >= 199901L) /* C99 */ || \
+-    (defined(__SUNPRO_C) && defined(__C99FEATURES__))
+-#   define __FUNCTION__ __func__
+-#  else
+-#   define __FUNCTION__ "<unknown>"
+-#  endif
+-# endif
++#  define __FUNCTION__ __func__
+ #endif
+ 
+ #endif /* EGLCOMPILER_INCLUDED */
+diff --git a/src/gallium/auxiliary/Makefile.am b/src/gallium/auxiliary/Makefile.am
+index a4eee47..f14279b 100644
+--- a/src/gallium/auxiliary/Makefile.am
++++ b/src/gallium/auxiliary/Makefile.am
+@@ -7,7 +7,10 @@ noinst_LTLIBRARIES = libgallium.la
+ 
+ AM_CFLAGS = \
+ 	-I$(top_srcdir)/src/gallium/auxiliary/util \
+-	$(GALLIUM_CFLAGS)
++	$(GALLIUM_CFLAGS) \
++	$(VISIBILITY_CFLAGS)
++
++AM_CXXFLAGS = $(VISIBILITY_CXXFLAGS)
+ 
+ libgallium_la_SOURCES = \
+ 	$(C_SOURCES) \
+@@ -18,7 +21,7 @@ if HAVE_MESA_LLVM
+ AM_CFLAGS += \
+ 	$(LLVM_CFLAGS)
+ 
+-AM_CXXFLAGS = \
++AM_CXXFLAGS += \
+ 	$(GALLIUM_CFLAGS) \
+ 	$(LLVM_CXXFLAGS)
+ 
+diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
+index 4898849..5fb4a11 100644
+--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
++++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
+@@ -240,6 +240,7 @@ struct lp_exec_mask {
+    struct lp_build_context *bld;
+ 
+    boolean has_mask;
++   boolean ret_in_main;
+ 
+    LLVMTypeRef int_vec_type;
+ 
+diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+index 0621fb4..413a918 100644
+--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
++++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+@@ -73,6 +73,7 @@ static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context
+ 
+    mask->bld = bld;
+    mask->has_mask = FALSE;
++   mask->ret_in_main = FALSE;
+    mask->cond_stack_size = 0;
+    mask->loop_stack_size = 0;
+    mask->call_stack_size = 0;
+@@ -108,7 +109,7 @@ static void lp_exec_mask_update(struct lp_exec_mask *mask)
+    } else
+       mask->exec_mask = mask->cond_mask;
+ 
+-   if (mask->call_stack_size) {
++   if (mask->call_stack_size || mask->ret_in_main) {
+       mask->exec_mask = LLVMBuildAnd(builder,
+                                      mask->exec_mask,
+                                      mask->ret_mask,
+@@ -117,7 +118,8 @@ static void lp_exec_mask_update(struct lp_exec_mask *mask)
+ 
+    mask->has_mask = (mask->cond_stack_size > 0 ||
+                      mask->loop_stack_size > 0 ||
+-                     mask->call_stack_size > 0);
++                     mask->call_stack_size > 0 ||
++                     mask->ret_in_main);
+ }
+ 
+ static void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
+@@ -348,11 +350,23 @@ static void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
+    LLVMBuilderRef builder = mask->bld->gallivm->builder;
+    LLVMValueRef exec_mask;
+ 
+-   if (mask->call_stack_size == 0) {
++   if (mask->cond_stack_size == 0 &&
++       mask->loop_stack_size == 0 &&
++       mask->call_stack_size == 0) {
+       /* returning from main() */
+       *pc = -1;
+       return;
+    }
++
++   if (mask->call_stack_size == 0) {
++      /*
++       * This requires special handling since we need to ensure
++       * we don't drop the mask even if we have no call stack
++       * (e.g. after a ret in a if clause after the endif)
++       */
++      mask->ret_in_main = TRUE;
++   }
++
+    exec_mask = LLVMBuildNot(builder,
+                             mask->exec_mask,
+                             "ret");
+diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
+index 1267e79..dc3a5fb 100644
+--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
++++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
+@@ -1569,7 +1569,7 @@ tgsi_text_translate(
+    struct tgsi_token *tokens,
+    uint num_tokens )
+ {
+-   struct translate_ctx ctx;
++   struct translate_ctx ctx = {0};
+ 
+    ctx.text = text;
+    ctx.cur = text;
+diff --git a/src/gallium/drivers/Makefile.am b/src/gallium/drivers/Makefile.am
+index 25d9533..3477fee 100644
+--- a/src/gallium/drivers/Makefile.am
++++ b/src/gallium/drivers/Makefile.am
+@@ -1,6 +1,7 @@
+ AUTOMAKE_OPTIONS = subdir-objects
+ 
+ AM_CPPFLAGS = \
++	-I$(top_srcdir)/include \
+ 	-I$(top_srcdir)/src/gallium/include \
+ 	-I$(top_srcdir)/src/gallium/auxiliary \
+ 	-I$(top_srcdir)/src/gallium/drivers \
+diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
+index 328c0f7..e145391 100644
+--- a/src/gallium/drivers/llvmpipe/lp_scene.c
++++ b/src/gallium/drivers/llvmpipe/lp_scene.c
+@@ -64,6 +64,28 @@ lp_scene_create( struct pipe_context *pipe )
+ 
+    pipe_mutex_init(scene->mutex);
+ 
++#ifdef DEBUG
++   /* Do some scene limit sanity checks here */
++   {
++      size_t maxBins = TILES_X * TILES_Y;
++      size_t maxCommandBytes = sizeof(struct cmd_block) * maxBins;
++      size_t maxCommandPlusData = maxCommandBytes + DATA_BLOCK_SIZE;
++      /* We'll need at least one command block per bin.  Make sure that's
++       * less than the max allowed scene size.
++       */
++      assert(maxCommandBytes < LP_SCENE_MAX_SIZE);
++      /* We'll also need space for at least one other data block */
++      assert(maxCommandPlusData <= LP_SCENE_MAX_SIZE);
++
++      /* Ideally, the size of a cmd_block object will be a power of two
++       * in order to avoid wasting space when we allocation them from
++       * data blocks (which are power of two also).
++       */
++      assert(sizeof(struct cmd_block) ==
++             util_next_power_of_two(sizeof(struct cmd_block)));
++   }
++#endif
++
+    return scene;
+ }
+ 
+diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h
+index b1db61b..801829d 100644
+--- a/src/gallium/drivers/llvmpipe/lp_scene.h
++++ b/src/gallium/drivers/llvmpipe/lp_scene.h
+@@ -49,12 +49,18 @@ struct lp_rast_state;
+ #define TILES_Y (LP_MAX_HEIGHT / TILE_SIZE)
+ 
+ 
+-#define CMD_BLOCK_MAX 128
++/* Commands per command block (ideally so sizeof(cmd_block) is a power of
++ * two in size.)
++ */
++#define CMD_BLOCK_MAX 29
++
++/* Bytes per data block.
++ */
+ #define DATA_BLOCK_SIZE (64 * 1024)
+ 
+ /* Scene temporary storage is clamped to this size:
+  */
+-#define LP_SCENE_MAX_SIZE (4*1024*1024)
++#define LP_SCENE_MAX_SIZE (9*1024*1024)
+ 
+ /* The maximum amount of texture storage referenced by a scene is
+  * clamped ot this size:
+diff --git a/src/gallium/drivers/nv50/nv50_blit.h b/src/gallium/drivers/nv50/nv50_blit.h
+index d409f21..bdd6a63 100644
+--- a/src/gallium/drivers/nv50/nv50_blit.h
++++ b/src/gallium/drivers/nv50/nv50_blit.h
+@@ -180,4 +180,44 @@ nv50_blit_eng2d_get_mask(const struct pipe_blit_info *info)
+    return mask;
+ }
+ 
++#if NOUVEAU_DRIVER == 0xc0
++# define nv50_format_table nvc0_format_table
++#endif
++
++/* return TRUE for formats that can be converted among each other by NVC0_2D */
++static INLINE boolean
++nv50_2d_dst_format_faithful(enum pipe_format format)
++{
++   const uint64_t mask =
++       NV50_ENG2D_SUPPORTED_FORMATS &
++      ~NV50_ENG2D_NOCONVERT_FORMATS;
++   uint8_t id = nv50_format_table[format].rt;
++   return (id >= 0xc0) && (mask & (1ULL << (id - 0xc0)));
++}
++static INLINE boolean
++nv50_2d_src_format_faithful(enum pipe_format format)
++{
++   const uint64_t mask =
++      NV50_ENG2D_SUPPORTED_FORMATS &
++    ~(NV50_ENG2D_LUMINANCE_FORMATS | NV50_ENG2D_INTENSITY_FORMATS);
++   uint8_t id = nv50_format_table[format].rt;
++   return (id >= 0xc0) && (mask & (1ULL << (id - 0xc0)));
++}
++
++static INLINE boolean
++nv50_2d_format_supported(enum pipe_format format)
++{
++   uint8_t id = nv50_format_table[format].rt;
++   return (id >= 0xc0) &&
++      (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)));
++}
++
++static INLINE boolean
++nv50_2d_dst_format_ops_supported(enum pipe_format format)
++{
++   uint8_t id = nv50_format_table[format].rt;
++   return (id >= 0xc0) &&
++      (NV50_ENG2D_OPERATION_FORMATS & (1ULL << (id - 0xc0)));
++}
++
+ #endif /* __NV50_BLIT_H__ */
+diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
+index a95e96d..f5e7b36 100644
+--- a/src/gallium/drivers/nv50/nv50_state_validate.c
++++ b/src/gallium/drivers/nv50/nv50_state_validate.c
+@@ -9,6 +9,7 @@ nv50_validate_fb(struct nv50_context *nv50)
+    struct pipe_framebuffer_state *fb = &nv50->framebuffer;
+    unsigned i;
+    unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
++   uint32_t array_size = 0xffff, array_mode = 0;
+ 
+    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
+ 
+@@ -23,6 +24,13 @@ nv50_validate_fb(struct nv50_context *nv50)
+       struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
+       struct nouveau_bo *bo = mt->base.bo;
+ 
++      array_size = MIN2(array_size, sf->depth);
++      if (mt->layout_3d)
++         array_mode = NV50_3D_RT_ARRAY_MODE_MODE_3D; /* 1 << 16 */
++
++      /* can't mix 3D with ARRAY or have RTs of different depth/array_size */
++      assert(mt->layout_3d || !array_mode || array_size == 1);
++
+       BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(i)), 5);
+       PUSH_DATAh(push, bo->offset + sf->offset);
+       PUSH_DATA (push, bo->offset + sf->offset);
+@@ -34,7 +42,7 @@ nv50_validate_fb(struct nv50_context *nv50)
+          PUSH_DATA (push, sf->width);
+          PUSH_DATA (push, sf->height);
+          BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
+-         PUSH_DATA (push, sf->depth);
++         PUSH_DATA (push, array_mode | array_size);
+       } else {
+          PUSH_DATA (push, 0);
+          PUSH_DATA (push, 0);
+@@ -63,7 +71,7 @@ nv50_validate_fb(struct nv50_context *nv50)
+       struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
+       struct nv50_surface *sf = nv50_surface(fb->zsbuf);
+       struct nouveau_bo *bo = mt->base.bo;
+-      int unk = mt->base.base.target == PIPE_TEXTURE_2D;
++      int unk = mt->base.base.target == PIPE_TEXTURE_3D || sf->depth == 1;
+ 
+       BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
+       PUSH_DATAh(push, bo->offset + sf->offset);
+diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
+index 7a0470c..3a780f6 100644
+--- a/src/gallium/drivers/nv50/nv50_surface.c
++++ b/src/gallium/drivers/nv50/nv50_surface.c
+@@ -35,25 +35,22 @@
+ 
+ #include "nv50_context.h"
+ #include "nv50_resource.h"
+-#include "nv50_blit.h"
+ 
+ #include "nv50_defs.xml.h"
+ #include "nv50_texture.xml.h"
+ 
++/* these are used in nv50_blit.h */
+ #define NV50_ENG2D_SUPPORTED_FORMATS 0xff0843e080608409ULL
++#define NV50_ENG2D_NOCONVERT_FORMATS 0x0008402000000000ULL
++#define NV50_ENG2D_LUMINANCE_FORMATS 0x0008402000000000ULL
++#define NV50_ENG2D_INTENSITY_FORMATS 0x0000000000000000ULL
++#define NV50_ENG2D_OPERATION_FORMATS 0x060001c000608000ULL
+ 
+-/* return TRUE for formats that can be converted among each other by NV50_2D */
+-static INLINE boolean
+-nv50_2d_format_faithful(enum pipe_format format)
+-{
+-   uint8_t id = nv50_format_table[format].rt;
+-
+-   return (id >= 0xc0) &&
+-      (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)));
+-}
++#define NOUVEAU_DRIVER 0x50
++#include "nv50_blit.h"
+ 
+ static INLINE uint8_t
+-nv50_2d_format(enum pipe_format format)
++nv50_2d_format(enum pipe_format format, boolean dst, boolean dst_src_equal)
+ {
+    uint8_t id = nv50_format_table[format].rt;
+ 
+@@ -62,6 +59,7 @@ nv50_2d_format(enum pipe_format format)
+     */
+    if ((id >= 0xc0) && (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0))))
+       return id;
++   assert(dst_src_equal);
+ 
+    switch (util_format_get_blocksize(format)) {
+    case 1:
+@@ -78,7 +76,7 @@ nv50_2d_format(enum pipe_format format)
+ static int
+ nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst,
+                     struct nv50_miptree *mt, unsigned level, unsigned layer,
+-                    enum pipe_format pformat)
++                    enum pipe_format pformat, boolean dst_src_pformat_equal)
+ {
+    struct nouveau_bo *bo = mt->base.bo;
+    uint32_t width, height, depth;
+@@ -86,7 +84,7 @@ nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst,
+    uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
+    uint32_t offset = mt->level[level].offset;
+ 
+-   format = nv50_2d_format(pformat);
++   format = nv50_2d_format(pformat, dst, dst_src_pformat_equal);
+    if (!format) {
+       NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
+                   util_format_name(pformat));
+@@ -155,15 +153,16 @@ nv50_2d_texture_do_copy(struct nouveau_pushbuf *push,
+    const enum pipe_format dfmt = dst->base.base.format;
+    const enum pipe_format sfmt = src->base.base.format;
+    int ret;
++   boolean eqfmt = dfmt == sfmt;
+ 
+    if (!PUSH_SPACE(push, 2 * 16 + 32))
+       return PIPE_ERROR;
+ 
+-   ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz, dfmt);
++   ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz, dfmt, eqfmt);
+    if (ret)
+       return ret;
+ 
+-   ret = nv50_2d_texture_set(push, 0, src, src_level, sz, sfmt);
++   ret = nv50_2d_texture_set(push, 0, src, src_level, sz, sfmt, eqfmt);
+    if (ret)
+       return ret;
+ 
+@@ -243,8 +242,8 @@ nv50_resource_copy_region(struct pipe_context *pipe,
+    }
+ 
+    assert((src->format == dst->format) ||
+-          (nv50_2d_format_faithful(src->format) &&
+-           nv50_2d_format_faithful(dst->format)));
++          (nv50_2d_src_format_faithful(src->format) &&
++           nv50_2d_dst_format_faithful(dst->format)));
+ 
+    BCTX_REFN(nv50->bufctx, 2D, nv04_resource(src), RD);
+    BCTX_REFN(nv50->bufctx, 2D, nv04_resource(dst), WR);
+@@ -936,7 +935,7 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
+    nv50_blit_select_fp(blit, info);
+    nv50_blitctx_pre_blit(blit);
+ 
+-   nv50_blit_set_dst(blit, dst, info->dst.level,  0, info->dst.format);
++   nv50_blit_set_dst(blit, dst, info->dst.level, -1, info->dst.format);
+    nv50_blit_set_src(blit, src, info->src.level, -1, info->src.format,
+                      blit->filter);
+ 
+@@ -977,6 +976,8 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
+ 
+    BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
+    PUSH_DATA (push, 0);
++   BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
++   PUSH_DATA (push, 0x1);
+ 
+    /* Draw a large triangle in screen coordinates covering the whole
+     * render target, with scissors defining the destination region.
+@@ -1059,7 +1060,8 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
+    int64_t du_dx, dv_dy;
+    int i;
+    uint32_t mode;
+-   const uint32_t mask = nv50_blit_eng2d_get_mask(info);
++   uint32_t mask = nv50_blit_eng2d_get_mask(info);
++   boolean b;
+ 
+    mode = nv50_blit_get_filter(info) ?
+       NV50_2D_BLIT_CONTROL_FILTER_BILINEAR :
+@@ -1070,8 +1072,9 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
+    du_dx = ((int64_t)info->src.box.width << 32) / info->dst.box.width;
+    dv_dy = ((int64_t)info->src.box.height << 32) / info->dst.box.height;
+ 
+-   nv50_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format);
+-   nv50_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format);
++   b = info->dst.format == info->src.format;
++   nv50_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format, b);
++   nv50_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format, b);
+ 
+    if (info->scissor_enable) {
+       BEGIN_NV04(push, NV50_2D(CLIP_X), 5);
+@@ -1094,6 +1097,17 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
+       PUSH_DATA (push, 0xffffffff);
+       BEGIN_NV04(push, NV50_2D(OPERATION), 1);
+       PUSH_DATA (push, NV50_2D_OPERATION_ROP);
++   } else
++   if (info->src.format != info->dst.format) {
++      if (info->src.format == PIPE_FORMAT_R8_UNORM ||
++          info->src.format == PIPE_FORMAT_R16_UNORM ||
++          info->src.format == PIPE_FORMAT_R16_FLOAT ||
++          info->src.format == PIPE_FORMAT_R32_FLOAT) {
++         mask = 0xffff0000; /* also makes condition for OPERATION reset true */
++         BEGIN_NV04(push, NV50_2D(BETA4), 2);
++         PUSH_DATA (push, mask);
++         PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY_PREMULT);
++      }
+    }
+ 
+    if (src->ms_x > dst->ms_x || src->ms_y > dst->ms_y) {
+@@ -1224,10 +1238,25 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
+       debug_printf("blit: cannot filter array or cube textures in z direction");
+    }
+ 
+-   if (!eng3d && info->dst.format != info->src.format)
+-      if (!nv50_2d_format_faithful(info->dst.format) ||
+-          !nv50_2d_format_faithful(info->src.format))
++   if (!eng3d && info->dst.format != info->src.format) {
++      if (!nv50_2d_dst_format_faithful(info->dst.format) ||
++          !nv50_2d_src_format_faithful(info->src.format)) {
+          eng3d = TRUE;
++      } else
++      if (!nv50_2d_src_format_faithful(info->src.format)) {
++         if (!util_format_is_luminance(info->src.format)) {
++            if (util_format_is_intensity(info->src.format))
++               eng3d = TRUE;
++            else
++            if (!nv50_2d_dst_format_ops_supported(info->dst.format))
++               eng3d = TRUE;
++            else
++               eng3d = !nv50_2d_format_supported(info->src.format);
++         }
++      } else
++      if (util_format_is_luminance_alpha(info->src.format))
++         eng3d = TRUE;
++   }
+ 
+    if (info->src.resource->nr_samples == 8 &&
+        info->dst.resource->nr_samples <= 1)
+diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h
+index 1cf1f96..bd3de58 100644
+--- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h
++++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h
+@@ -1041,7 +1041,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ #define NVC0_3D_VIEWPORT_TRANSFORM_EN				0x0000192c
+ 
+ #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL				0x0000193c
+-#define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK0			0x00000001
++#define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_RANGE_0_1		0x00000001
+ #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1__MASK		0x00000006
+ #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1__SHIFT		1
+ #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK0			0x00000000
+diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
+index 281d740..66154a4 100644
+--- a/src/gallium/drivers/nvc0/nvc0_surface.c
++++ b/src/gallium/drivers/nvc0/nvc0_surface.c
+@@ -36,29 +36,32 @@
+ 
+ #include "nv50/nv50_defs.xml.h"
+ #include "nv50/nv50_texture.xml.h"
+-#include "nv50/nv50_blit.h"
+ 
+-#define NVC0_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL
++/* these are used in nv50_blit.h */
++#define NV50_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL
++#define NV50_ENG2D_NOCONVERT_FORMATS 0x009cc02000000000ULL
++#define NV50_ENG2D_LUMINANCE_FORMATS 0x001cc02000000000ULL
++#define NV50_ENG2D_INTENSITY_FORMATS 0x0080000000000000ULL
++#define NV50_ENG2D_OPERATION_FORMATS 0x060001c000638000ULL
+ 
+-/* return TRUE for formats that can be converted among each other by NVC0_2D */
+-static INLINE boolean
+-nvc0_2d_format_faithful(enum pipe_format format)
+-{
+-   uint8_t id = nvc0_format_table[format].rt;
+-
+-   return (id >= 0xc0) && (NVC0_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)));
+-}
++#define NOUVEAU_DRIVER 0xc0
++#include "nv50/nv50_blit.h"
+ 
+ static INLINE uint8_t
+-nvc0_2d_format(enum pipe_format format)
++nvc0_2d_format(enum pipe_format format, boolean dst, boolean dst_src_equal)
+ {
+    uint8_t id = nvc0_format_table[format].rt;
+ 
++   /* A8_UNORM is treated as I8_UNORM as far as the 2D engine is concerned. */
++   if (!dst && unlikely(format == PIPE_FORMAT_I8_UNORM) && !dst_src_equal)
++      return NV50_SURFACE_FORMAT_A8_UNORM;
++
+    /* Hardware values for color formats range from 0xc0 to 0xff,
+     * but the 2D engine doesn't support all of them.
+     */
+-   if (nvc0_2d_format_faithful(format))
++   if (nv50_2d_format_supported(format))
+       return id;
++   assert(dst_src_equal);
+ 
+    switch (util_format_get_blocksize(format)) {
+    case 1:
+@@ -72,6 +75,7 @@ nvc0_2d_format(enum pipe_format format)
+    case 16:
+       return NV50_SURFACE_FORMAT_RGBA32_FLOAT;
+    default:
++      assert(0);
+       return 0;
+    }
+ }
+@@ -79,7 +83,7 @@ nvc0_2d_format(enum pipe_format format)
+ static int
+ nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst,
+                     struct nv50_miptree *mt, unsigned level, unsigned layer,
+-                    enum pipe_format pformat)
++                    enum pipe_format pformat, boolean dst_src_pformat_equal)
+ {
+    struct nouveau_bo *bo = mt->base.bo;
+    uint32_t width, height, depth;
+@@ -87,7 +91,7 @@ nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst,
+    uint32_t mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT;
+    uint32_t offset = mt->level[level].offset;
+ 
+-   format = nvc0_2d_format(pformat);
++   format = nvc0_2d_format(pformat, dst, dst_src_pformat_equal);
+    if (!format) {
+       NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
+                   util_format_name(pformat));
+@@ -157,15 +161,16 @@ nvc0_2d_texture_do_copy(struct nouveau_pushbuf *push,
+    const enum pipe_format dfmt = dst->base.base.format;
+    const enum pipe_format sfmt = src->base.base.format;
+    int ret;
++   boolean eqfmt = dfmt == sfmt;
+ 
+    if (!PUSH_SPACE(push, 2 * 16 + 32))
+       return PIPE_ERROR;
+ 
+-   ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz, dfmt);
++   ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz, dfmt, eqfmt);
+    if (ret)
+       return ret;
+ 
+-   ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz, sfmt);
++   ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz, sfmt, eqfmt);
+    if (ret)
+       return ret;
+ 
+@@ -243,8 +248,8 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
+       return;
+    }
+ 
+-   assert(nvc0_2d_format_faithful(src->format));
+-   assert(nvc0_2d_format_faithful(dst->format));
++   assert(nv50_2d_dst_format_faithful(dst->format));
++   assert(nv50_2d_src_format_faithful(src->format));
+ 
+    BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD);
+    BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR);
+@@ -490,19 +495,19 @@ nvc0_blitter_make_vp(struct nvc0_blitter *blit)
+ {
+    static const uint32_t code_nvc0[] =
+    {
+-      0xfff01c66, 0x06000080, /* vfetch b128 { $r0 $r1 $r2 $r3 } a[0x80] */
+-      0xfff11c26, 0x06000090, /* vfetch b96 { $r4 $r5 $r6 } a[0x90]*/
+-      0x03f01c66, 0x0a7e0070, /* export b128 o[0x70] { $r0 $r1 $r2 $r3 } */
+-      0x13f01c26, 0x0a7e0080, /* export b96 o[0x80] { $r4 $r5 $r6 } */
++      0xfff11c26, 0x06000080, /* vfetch b64 $r4:$r5 a[0x80] */
++      0xfff01c46, 0x06000090, /* vfetch b96 $r0:$r1:$r2 a[0x90] */
++      0x13f01c26, 0x0a7e0070, /* export b64 o[0x70] $r4:$r5 */
++      0x03f01c46, 0x0a7e0080, /* export b96 o[0x80] $r0:$r1:$r2 */
+       0x00001de7, 0x80000000, /* exit */
+    };
+    static const uint32_t code_nve4[] =
+    {
+       0x00000007, 0x20000000, /* sched */
+-      0xfff01c66, 0x06000080, /* vfetch b128 { $r0 $r1 $r2 $r3 } a[0x80] */
+-      0xfff11c46, 0x06000090, /* vfetch b96 { $r4 $r5 $r6 } a[0x90]*/
+-      0x03f01c66, 0x0a7e0070, /* export b128 o[0x70] { $r0 $r1 $r2 $r3 } */
+-      0x13f01c46, 0x0a7e0080, /* export b96 o[0x80] { $r4 $r5 $r6 } */
++      0xfff11c26, 0x06000080, /* vfetch b64 $r4:$r5 a[0x80] */
++      0xfff01c46, 0x06000090, /* vfetch b96 $r0:$r1:$r2 a[0x90] */
++      0x13f01c26, 0x0a7e0070, /* export b64 o[0x70] $r4:$r5 */
++      0x03f01c46, 0x0a7e0080, /* export b96 o[0x80] $r0:$r1:$r2 */
+       0x00001de7, 0x80000000, /* exit */
+    };
+ 
+@@ -515,13 +520,13 @@ nvc0_blitter_make_vp(struct nvc0_blitter *blit)
+       blit->vp.code = (uint32_t *)code_nvc0; /* const_cast */
+       blit->vp.code_size = sizeof(code_nvc0);
+    }
+-   blit->vp.max_gpr = 7;
++   blit->vp.max_gpr = 6;
+    blit->vp.vp.edgeflag = PIPE_MAX_ATTRIBS;
+ 
+    blit->vp.hdr[0]  = 0x00020461; /* vertprog magic */
+    blit->vp.hdr[4]  = 0x000ff000; /* no outputs read */
+-   blit->vp.hdr[6]  = 0x0000003f; /* a[0x80], a[0x90] */
+-   blit->vp.hdr[13] = 0x0003f000; /* o[0x70], o[0x80] */
++   blit->vp.hdr[6]  = 0x00000073; /* a[0x80].xy, a[0x90].xyz */
++   blit->vp.hdr[13] = 0x00073000; /* o[0x70].xy, o[0x80].xyz */
+ }
+ 
+ static void
+@@ -820,7 +825,7 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+    nvc0_blit_select_fp(blit, info);
+    nvc0_blitctx_pre_blit(blit);
+ 
+-   nvc0_blit_set_dst(blit, dst, info->dst.level,  0, info->dst.format);
++   nvc0_blit_set_dst(blit, dst, info->dst.level, -1, info->dst.format);
+    nvc0_blit_set_src(blit, src, info->src.level, -1, info->src.format,
+                      blit->filter);
+ 
+@@ -859,6 +864,8 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+       z += 0.5f * dz;
+ 
+    IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0);
++   IMMED_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 0x2 |
++              NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_RANGE_0_1);
+    BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2);
+    PUSH_DATA (push, nvc0->framebuffer.width << 16);
+    PUSH_DATA (push, nvc0->framebuffer.height << 16);
+@@ -925,11 +932,14 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+    if (info->dst.box.z + info->dst.box.depth - 1)
+       IMMED_NVC0(push, NVC0_3D(LAYER), 0);
+ 
+-   /* re-enable normally constant state */
++   nvc0_blitctx_post_blit(blit);
+ 
+-   IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
++   /* restore viewport */
+ 
+-   nvc0_blitctx_post_blit(blit);
++   BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2);
++   PUSH_DATA (push, nvc0->framebuffer.width << 16);
++   PUSH_DATA (push, nvc0->framebuffer.height << 16);
++   IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
+ }
+ 
+ static void
+@@ -948,7 +958,8 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+    int64_t du_dx, dv_dy;
+    int i;
+    uint32_t mode;
+-   const uint32_t mask = nv50_blit_eng2d_get_mask(info);
++   uint32_t mask = nv50_blit_eng2d_get_mask(info);
++   boolean b;
+ 
+    mode = nv50_blit_get_filter(info) ?
+       NVC0_2D_BLIT_CONTROL_FILTER_BILINEAR :
+@@ -959,8 +970,9 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+    du_dx = ((int64_t)info->src.box.width << 32) / info->dst.box.width;
+    dv_dy = ((int64_t)info->src.box.height << 32) / info->dst.box.height;
+ 
+-   nvc0_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format);
+-   nvc0_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format);
++   b = info->dst.format == info->src.format;
++   nvc0_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format, b);
++   nvc0_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format, b);
+ 
+    if (info->scissor_enable) {
+       BEGIN_NVC0(push, NVC0_2D(CLIP_X), 5);
+@@ -981,6 +993,25 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+       PUSH_DATA (push, 0xffffffff);
+       PUSH_DATA (push, 0xffffffff);
+       IMMED_NVC0(push, NVC0_2D(OPERATION), NVC0_2D_OPERATION_ROP);
++   } else
++   if (info->src.format != info->dst.format) {
++      if (info->src.format == PIPE_FORMAT_R8_UNORM ||
++          info->src.format == PIPE_FORMAT_R8_SNORM ||
++          info->src.format == PIPE_FORMAT_R16_UNORM ||
++          info->src.format == PIPE_FORMAT_R16_SNORM ||
++          info->src.format == PIPE_FORMAT_R16_FLOAT ||
++          info->src.format == PIPE_FORMAT_R32_FLOAT) {
++         mask = 0xffff0000; /* also makes condition for OPERATION reset true */
++         BEGIN_NVC0(push, NVC0_2D(BETA4), 2);
++         PUSH_DATA (push, mask);
++         PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY_PREMULT);
++      } else
++      if (info->src.format == PIPE_FORMAT_A8_UNORM) {
++         mask = 0xff000000;
++         BEGIN_NVC0(push, NVC0_2D(BETA4), 2);
++         PUSH_DATA (push, mask);
++         PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY_PREMULT);
++      }
+    }
+ 
+    if (src->ms_x > dst->ms_x || src->ms_y > dst->ms_y) {
+@@ -1106,10 +1137,24 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
+       debug_printf("blit: cannot filter array or cube textures in z direction");
+    }
+ 
+-   if (!eng3d && info->dst.format != info->src.format)
+-      if (!nvc0_2d_format_faithful(info->dst.format) ||
+-          !nvc0_2d_format_faithful(info->src.format))
++   if (!eng3d && info->dst.format != info->src.format) {
++      if (!nv50_2d_dst_format_faithful(info->dst.format)) {
++         eng3d = TRUE;
++      } else
++      if (!nv50_2d_src_format_faithful(info->src.format)) {
++         if (!util_format_is_luminance(info->src.format)) {
++            if (util_format_is_intensity(info->src.format))
++               eng3d = info->src.format != PIPE_FORMAT_I8_UNORM;
++            else
++            if (!nv50_2d_dst_format_ops_supported(info->dst.format))
++               eng3d = TRUE;
++            else
++               eng3d = !nv50_2d_format_supported(info->src.format);
++         }
++      } else
++      if (util_format_is_luminance_alpha(info->src.format))
+          eng3d = TRUE;
++   }
+ 
+    if (info->src.resource->nr_samples == 8 &&
+        info->dst.resource->nr_samples <= 1)
+diff --git a/src/gallium/drivers/r300/compiler/radeon_optimize.c b/src/gallium/drivers/r300/compiler/radeon_optimize.c
+index 734c7f2..74afd6f 100644
+--- a/src/gallium/drivers/r300/compiler/radeon_optimize.c
++++ b/src/gallium/drivers/r300/compiler/radeon_optimize.c
+@@ -708,6 +708,7 @@ static int peephole_mul_omod(
+ 	struct rc_list * writer_list;
+ 	struct rc_variable * var;
+ 	struct peephole_mul_cb_data cb_data;
++	unsigned writemask_sum;
+ 
+ 	for (i = 0; i < 2; i++) {
+ 		unsigned int j;
+@@ -815,10 +816,11 @@ static int peephole_mul_omod(
+ 	}
+ 
+ 	/* Rewrite the instructions */
++	writemask_sum = rc_variable_writemask_sum(writer_list->Item);
+ 	for (var = writer_list->Item; var; var = var->Friend) {
+ 		struct rc_variable * writer = var;
+ 		unsigned conversion_swizzle = rc_make_conversion_swizzle(
+-					writer->Inst->U.I.DstReg.WriteMask,
++					writemask_sum,
+ 					inst_mul->U.I.DstReg.WriteMask);
+ 		writer->Inst->U.I.Omod = omod_op;
+ 		writer->Inst->U.I.DstReg.File = inst_mul->U.I.DstReg.File;
+diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
+index a7973a5..80b859f 100644
+--- a/src/gallium/drivers/r600/r600_pipe.c
++++ b/src/gallium/drivers/r600/r600_pipe.c
+@@ -1157,7 +1157,7 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
+ 	 * case were triggering lockup quickly such as :
+ 	 * piglit/bin/depthstencil-render-miplevels 1024 d=s=z24_s8
+ 	 */
+-	rscreen->use_hyperz = debug_get_bool_option("R600_HYPERZ", TRUE);
++	rscreen->use_hyperz = debug_get_bool_option("R600_HYPERZ", FALSE);
+ 	rscreen->use_hyperz = rscreen->info.drm_minor >= 26 ? rscreen->use_hyperz : FALSE;
+ 
+ 	rscreen->global_pool = compute_memory_pool_new(rscreen);
+diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c
+index 0335189..782ad26 100644
+--- a/src/gallium/drivers/r600/r600_query.c
++++ b/src/gallium/drivers/r600/r600_query.c
+@@ -186,10 +186,11 @@ static void r600_emit_query_end(struct r600_context *ctx, struct r600_query *que
+ 	case PIPE_QUERY_PRIMITIVES_GENERATED:
+ 	case PIPE_QUERY_SO_STATISTICS:
+ 	case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
++		va += query->buffer.results_end + query->result_size/2;
+ 		cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 2, 0);
+ 		cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_SAMPLE_STREAMOUTSTATS) | EVENT_INDEX(3);
+-		cs->buf[cs->cdw++] = query->buffer.results_end + query->result_size/2;
+-		cs->buf[cs->cdw++] = 0;
++		cs->buf[cs->cdw++] = va;
++		cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF;
+ 		break;
+ 	case PIPE_QUERY_TIME_ELAPSED:
+ 		va += query->buffer.results_end + query->result_size/2;
+diff --git a/src/gallium/drivers/radeon/Makefile.am b/src/gallium/drivers/radeon/Makefile.am
+index e6eb241..a3a7b74 100644
+--- a/src/gallium/drivers/radeon/Makefile.am
++++ b/src/gallium/drivers/radeon/Makefile.am
+@@ -1,11 +1,14 @@
+ include Makefile.sources
+ include $(top_srcdir)/src/gallium/Automake.inc
+ 
++LIBGALLIUM_LIBS=
++
+ if HAVE_GALLIUM_R600
+ if HAVE_GALLIUM_RADEONSI
+ lib_LTLIBRARIES = libllvmradeon at VERSION@.la
+ libllvmradeon at VERSION@_la_LDFLAGS = -Wl, -shared -avoid-version \
+ 	$(LLVM_LDFLAGS)
++LIBGALLIUM_LIBS += $(top_builddir)/src/gallium/auxiliary/libgallium.la
+ else
+ noinst_LTLIBRARIES = libllvmradeon at VERSION@.la
+ endif
+@@ -26,5 +29,6 @@ libllvmradeon at VERSION@_la_SOURCES = \
+ 	$(C_FILES)
+ 
+ libllvmradeon at VERSION@_la_LIBADD = \
++	$(LIBGALLIUM_LIBS) \
+ 	$(CLOCK_LIB) \
+ 	$(LLVM_LIBS)
+diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
+index 8c35625..93766a3 100644
+--- a/src/gallium/drivers/radeonsi/si_state_draw.c
++++ b/src/gallium/drivers/radeonsi/si_state_draw.c
+@@ -401,6 +401,11 @@ static void si_update_derived_state(struct r600_context *rctx)
+ 	}
+ 
+ 	if (si_pm4_state_changed(rctx, ps) || si_pm4_state_changed(rctx, vs)) {
++		/* XXX: Emitting the PS state even when only the VS changed
++		 * fixes random failures with piglit glsl-max-varyings.
++		 * Not sure why...
++		 */
++		rctx->emitted.named.ps = NULL;
+ 		si_update_spi_map(rctx);
+ 	}
+ }
+diff --git a/src/gallium/drivers/rbug/Makefile.am b/src/gallium/drivers/rbug/Makefile.am
+index 655bfe1..3c1a8b5 100644
+--- a/src/gallium/drivers/rbug/Makefile.am
++++ b/src/gallium/drivers/rbug/Makefile.am
+@@ -30,6 +30,7 @@ noinst_LTLIBRARIES = librbug.la
+ # preprocessor is determined by the ordering of the -I flags.
+ AM_CFLAGS = \
+ 	$(GALLIUM_CFLAGS) \
++	$(VISIBILITY_CFLAGS) \
+ 	-I$(top_srcdir)/src/gallium/drivers \
+ 	-I$(top_srcdir)/include
+ 
+diff --git a/src/gallium/drivers/svga/Makefile.am b/src/gallium/drivers/svga/Makefile.am
+index fdaa3c8..7eacd90 100644
+--- a/src/gallium/drivers/svga/Makefile.am
++++ b/src/gallium/drivers/svga/Makefile.am
+@@ -29,6 +29,8 @@ AM_CPPFLAGS = \
+ 	-I$(top_srcdir)/include \
+ 	$(GALLIUM_CFLAGS)
+ 
++AM_CFLAGS = $(VISIBILITY_CFLAGS)
++
+ #On some systems -std= must be added to CFLAGS to be the last -std=
+ CFLAGS += -std=gnu99
+ 
+diff --git a/src/gallium/drivers/trace/Makefile.am b/src/gallium/drivers/trace/Makefile.am
+index a9e1457..984ead4 100644
+--- a/src/gallium/drivers/trace/Makefile.am
++++ b/src/gallium/drivers/trace/Makefile.am
+@@ -1,7 +1,8 @@
+ include $(top_srcdir)/src/gallium/Automake.inc
+ 
+ AM_CFLAGS = \
+-	$(GALLIUM_CFLAGS)
++	$(GALLIUM_CFLAGS) \
++	$(VISIBILITY_CFLAGS)
+ 
+ noinst_LTLIBRARIES = libtrace.la
+ 
+diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
+index 5958333..a131969 100644
+--- a/src/gallium/include/pipe/p_compiler.h
++++ b/src/gallium/include/pipe/p_compiler.h
+@@ -29,6 +29,8 @@
+ #define P_COMPILER_H
+ 
+ 
++#include "c99_compat.h" /* inline, __func__, etc. */
++
+ #include "p_config.h"
+ 
+ #include <stdlib.h>
+@@ -90,28 +92,7 @@ typedef unsigned char boolean;
+ #endif
+ #endif
+ 
+-/* Function inlining */
+-#ifndef inline
+-#  ifdef __cplusplus
+-     /* C++ supports inline keyword */
+-#  elif defined(__GNUC__)
+-#    define inline __inline__
+-#  elif defined(_MSC_VER)
+-#    define inline __inline
+-#  elif defined(__ICL)
+-#    define inline __inline
+-#  elif defined(__INTEL_COMPILER)
+-     /* Intel compiler supports inline keyword */
+-#  elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
+-#    define inline __inline
+-#  elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
+-     /* C99 supports inline keyword */
+-#  elif (__STDC_VERSION__ >= 199901L)
+-     /* C99 supports inline keyword */
+-#  else
+-#    define inline
+-#  endif
+-#endif
++/* XXX: Use standard `inline` keyword instead */
+ #ifndef INLINE
+ #  define INLINE inline
+ #endif
+@@ -127,26 +108,6 @@ typedef unsigned char boolean;
+ #  endif
+ #endif
+ 
+-/*
+- * Define the C99 restrict keyword.
+- *
+- * See also:
+- * - http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html
+- */
+-#ifndef restrict
+-#  if (__STDC_VERSION__ >= 199901L)
+-     /* C99 */
+-#  elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
+-     /* C99 */
+-#  elif defined(__GNUC__)
+-#    define restrict __restrict__
+-#  elif defined(_MSC_VER)
+-#    define restrict __restrict
+-#  else
+-#    define restrict /* */
+-#  endif
+-#endif
+-
+ 
+ /* Function visibility */
+ #ifndef PUBLIC
+@@ -160,35 +121,10 @@ typedef unsigned char boolean;
+ #endif
+ 
+ 
+-/* The __FUNCTION__ gcc variable is generally only used for debugging.
+- * If we're not using gcc, define __FUNCTION__ as a cpp symbol here.
+- */
++/* XXX: Use standard `__func__` instead */
+ #ifndef __FUNCTION__
+-# if !defined(__GNUC__)
+-#  if (__STDC_VERSION__ >= 199901L) /* C99 */ || \
+-    (defined(__SUNPRO_C) && defined(__C99FEATURES__))
+-#   define __FUNCTION__ __func__
+-#  else
+-#   define __FUNCTION__ "<unknown>"
+-#  endif
+-# endif
+-# if defined(_MSC_VER) && _MSC_VER < 1300
+-#  define __FUNCTION__ "<unknown>"
+-# endif
++#  define __FUNCTION__ __func__
+ #endif
+-#ifndef __func__
+-#  if (__STDC_VERSION__ >= 199901L) || \
+-      (defined(__SUNPRO_C) && defined(__C99FEATURES__))
+-       /* __func__ is part of C99 */
+-#  elif defined(_MSC_VER)
+-#    if _MSC_VER >= 1300
+-#      define __func__ __FUNCTION__
+-#    else
+-#      define __func__ "<unknown>"
+-#    endif
+-#  endif
+-#endif
+-
+ 
+ 
+ /* This should match linux gcc cdecl semantics everywhere, so that we
+diff --git a/src/gallium/state_trackers/egl/Makefile.am b/src/gallium/state_trackers/egl/Makefile.am
+index e19e9a3..f78b36e 100644
+--- a/src/gallium/state_trackers/egl/Makefile.am
++++ b/src/gallium/state_trackers/egl/Makefile.am
+@@ -27,7 +27,7 @@ include $(top_srcdir)/src/gallium/Automake.inc
+ AM_CFLAGS = $(GALLIUM_CFLAGS)
+ AM_CPPFLAGS = \
+ 	-I$(top_srcdir)/src/egl/main \
+-	-I$(top_srcdir)/src/egl/wayland/wayland-drm/ \
++	-I$(top_builddir)/src/egl/wayland/wayland-drm/ \
+ 	-I$(top_srcdir)/include
+ 
+ noinst_LTLIBRARIES = libegl.la
+diff --git a/src/gallium/state_trackers/xa/Makefile.am b/src/gallium/state_trackers/xa/Makefile.am
+index 5b53ef9..57d55c4 100644
+--- a/src/gallium/state_trackers/xa/Makefile.am
++++ b/src/gallium/state_trackers/xa/Makefile.am
+@@ -24,7 +24,9 @@ include $(top_srcdir)/src/gallium/Automake.inc
+ 
+ AM_CFLAGS = \
+ 	-Wall -pedantic \
+-	$(GALLIUM_CFLAGS)
++	$(GALLIUM_CFLAGS) \
++	$(VISIBILITY_CFLAGS)
++
+ AM_CPPFLAGS = \
+ 	-I$(top_srcdir)/src/gallium/ \
+ 	-I$(top_srcdir)/src/gallium/winsys \
+diff --git a/src/gallium/winsys/svga/drm/Makefile.am b/src/gallium/winsys/svga/drm/Makefile.am
+index 53bbcc2..d7ada3c 100644
+--- a/src/gallium/winsys/svga/drm/Makefile.am
++++ b/src/gallium/winsys/svga/drm/Makefile.am
+@@ -31,6 +31,8 @@ AM_CPPFLAGS = \
+ 	$(GALLIUM_CFLAGS) \
+ 	$(LIBDRM_CFLAGS)
+ 
++AM_CFLAGS = $(VISIBILITY_CFLAGS)
++
+ #On some systems -std= must be added to CFLAGS to be the last -std=
+ CFLAGS += -std=gnu99 -D_FILE_OFFSET_BITS=64
+ 
+diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
+index 02d85b8..dee9709 100644
+--- a/src/glsl/glsl_types.cpp
++++ b/src/glsl/glsl_types.cpp
+@@ -446,6 +446,8 @@ const glsl_type *glsl_type::get_scalar_type() const
+       return int_type;
+    case GLSL_TYPE_FLOAT:
+       return float_type;
++   case GLSL_TYPE_BOOL:
++      return bool_type;
+    default:
+       /* Handle everything else */
+       return type;
+diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
+index d8cafd5..78ce13e 100644
+--- a/src/glsl/ir_validate.cpp
++++ b/src/glsl/ir_validate.cpp
+@@ -695,6 +695,11 @@ check_node_type(ir_instruction *ir, void *data)
+ void
+ validate_ir_tree(exec_list *instructions)
+ {
++   /* We shouldn't have any reason to validate IR in a release build,
++    * and it's half composed of assert()s anyway which wouldn't do
++    * anything.
++    */
++#ifdef DEBUG
+    ir_validate v;
+ 
+    v.run(instructions);
+@@ -704,4 +709,5 @@ validate_ir_tree(exec_list *instructions)
+ 
+       visit_tree(ir, check_node_type, NULL);
+    }
++#endif
+ }
+diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
+index 57e7a9a..cf0420c 100644
+--- a/src/glsl/linker.cpp
++++ b/src/glsl/linker.cpp
+@@ -1067,13 +1067,11 @@ link_intrastage_shaders(void *mem_ctx,
+ 
+    free(linking_shaders);
+ 
+-#ifdef DEBUG
+    /* At this point linked should contain all of the linked IR, so
+     * validate it to make sure nothing went wrong.
+     */
+    if (linked)
+       validate_ir_tree(linked->ir);
+-#endif
+ 
+    /* Make a pass over all variable declarations to ensure that arrays with
+     * unspecified sizes have a size specified.  The size is inferred from the
+diff --git a/src/glx/Makefile.am b/src/glx/Makefile.am
+index 4aa900a..f01709b 100644
+--- a/src/glx/Makefile.am
++++ b/src/glx/Makefile.am
+@@ -39,6 +39,7 @@ AM_CFLAGS = \
+ 	-I$(top_srcdir)/src/mapi/glapi \
+ 	-I$(top_builddir)/src/mapi \
+ 	-I$(top_builddir)/src/mapi/glapi \
++	$(VISIBILITY_CFLAGS) \
+ 	$(SHARED_GLAPI_CFLAGS) \
+ 	$(EXTRA_DEFINES_XF86VIDMODE) \
+ 	-D_REENTRANT \
+diff --git a/src/mapi/glapi/gen/gl_x86-64_asm.py b/src/mapi/glapi/gen/gl_x86-64_asm.py
+index a3548c2..19e0e15 100644
+--- a/src/mapi/glapi/gen/gl_x86-64_asm.py
++++ b/src/mapi/glapi/gen/gl_x86-64_asm.py
+@@ -181,19 +181,6 @@ class PrintGenericStubs(gl_XML.gl_print_base):
+ 
+     def printRealFooter(self):
+         print ''
+-        print '#if defined(GLX_USE_TLS) && defined(__linux__)'
+-        print '	.section ".note.ABI-tag", "a"'
+-        print '	.p2align 2'
+-        print '	.long	1f - 0f   /* name length */'
+-        print '	.long	3f - 2f   /* data length */'
+-        print '	.long	1         /* note length */'
+-        print '0:	.asciz "GNU"      /* vendor name */'
+-        print '1:	.p2align 2'
+-        print '2:	.long	0         /* note data: the ABI tag */'
+-        print '	.long	2,4,20    /* Minimum kernel version w/TLS */'
+-        print '3:	.p2align 2        /* pad out section */'
+-        print '#endif /* GLX_USE_TLS */'
+-        print ''
+         print '#if defined (__ELF__) && defined (__linux__)'
+         print '	.section .note.GNU-stack,"",%progbits'
+         print '#endif'
+diff --git a/src/mapi/glapi/gen/gl_x86_asm.py b/src/mapi/glapi/gen/gl_x86_asm.py
+index 8b0f6ee..919bbc0 100644
+--- a/src/mapi/glapi/gen/gl_x86_asm.py
++++ b/src/mapi/glapi/gen/gl_x86_asm.py
+@@ -189,19 +189,6 @@ class PrintGenericStubs(gl_XML.gl_print_base):
+         print '\t\tALIGNTEXT16'
+         print 'GLNAME(gl_dispatch_functions_end):'
+         print ''
+-        print '#if defined(GLX_USE_TLS) && defined(__linux__)'
+-        print '	.section ".note.ABI-tag", "a"'
+-        print '	.p2align 2'
+-        print '	.long	1f - 0f   /* name length */'
+-        print '	.long	3f - 2f   /* data length */'
+-        print '	.long	1         /* note length */'
+-        print '0:	.asciz "GNU"      /* vendor name */'
+-        print '1:	.p2align 2'
+-        print '2:	.long	0         /* note data: the ABI tag */'
+-        print '	.long	2,4,20    /* Minimum kernel version w/TLS */'
+-        print '3:	.p2align 2        /* pad out section */'
+-        print '#endif /* GLX_USE_TLS */'
+-        print ''
+         print '#if defined (__ELF__) && defined (__linux__)'
+         print '	.section .note.GNU-stack,"",%progbits'
+         print '#endif'
+diff --git a/src/mapi/mapi/entry_x86-64_tls.h b/src/mapi/mapi/entry_x86-64_tls.h
+index 72d4125..36cad00 100644
+--- a/src/mapi/mapi/entry_x86-64_tls.h
++++ b/src/mapi/mapi/entry_x86-64_tls.h
+@@ -28,19 +28,6 @@
+ 
+ #include "u_macros.h"
+ 
+-#ifdef __linux__
+-__asm__(".section .note.ABI-tag, \"a\"\n\t"
+-        ".p2align 2\n\t"
+-        ".long 1f - 0f\n\t"      /* name length */
+-        ".long 3f - 2f\n\t"      /* data length */
+-        ".long 1\n\t"            /* note length */
+-        "0: .asciz \"GNU\"\n\t"  /* vendor name */
+-        "1: .p2align 2\n\t"
+-        "2: .long 0\n\t"         /* note data: the ABI tag */
+-        ".long 2,4,20\n\t"       /* Minimum kernel version w/TLS */
+-        "3: .p2align 2\n\t");    /* pad out section */
+-#endif /* __linux__ */
+-
+ __asm__(".text\n"
+         ".balign 32\n"
+         "x86_64_entry_start:");
+diff --git a/src/mapi/mapi/entry_x86_tls.h b/src/mapi/mapi/entry_x86_tls.h
+index de91812..58d09ca 100644
+--- a/src/mapi/mapi/entry_x86_tls.h
++++ b/src/mapi/mapi/entry_x86_tls.h
+@@ -29,19 +29,6 @@
+ #include <string.h>
+ #include "u_macros.h"
+ 
+-#ifdef __linux__
+-__asm__(".section .note.ABI-tag, \"a\"\n\t"
+-        ".p2align 2\n\t"
+-        ".long 1f - 0f\n\t"      /* name length */
+-        ".long 3f - 2f\n\t"      /* data length */
+-        ".long 1\n\t"            /* note length */
+-        "0: .asciz \"GNU\"\n\t"  /* vendor name */
+-        "1: .p2align 2\n\t"
+-        "2: .long 0\n\t"         /* note data: the ABI tag */
+-        ".long 2,4,20\n\t"       /* Minimum kernel version w/TLS */
+-        "3: .p2align 2\n\t");    /* pad out section */
+-#endif /* __linux__ */
+-
+ __asm__(".text");
+ 
+ __asm__("x86_current_tls:\n\t"
+diff --git a/src/mapi/mapi/u_compiler.h b/src/mapi/mapi/u_compiler.h
+index 2b019ed..f376e97 100644
+--- a/src/mapi/mapi/u_compiler.h
++++ b/src/mapi/mapi/u_compiler.h
+@@ -1,28 +1,10 @@
+ #ifndef _U_COMPILER_H_
+ #define _U_COMPILER_H_
+ 
+-/* Function inlining */
+-#ifndef inline
+-#  ifdef __cplusplus
+-     /* C++ supports inline keyword */
+-#  elif defined(__GNUC__)
+-#    define inline __inline__
+-#  elif defined(_MSC_VER)
+-#    define inline __inline
+-#  elif defined(__ICL)
+-#    define inline __inline
+-#  elif defined(__INTEL_COMPILER)
+-     /* Intel compiler supports inline keyword */
+-#  elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
+-#    define inline __inline
+-#  elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
+-     /* C99 supports inline keyword */
+-#  elif (__STDC_VERSION__ >= 199901L)
+-     /* C99 supports inline keyword */
+-#  else
+-#    define inline
+-#  endif
+-#endif
++#include "c99_compat.h" /* inline, __func__, etc. */
++
++
++/* XXX: Use standard `inline` keyword instead */
+ #ifndef INLINE
+ #  define INLINE inline
+ #endif
+diff --git a/src/mesa/drivers/dri/i965/brw_clear.c b/src/mesa/drivers/dri/i965/brw_clear.c
+index 53d8e54..cde1a06 100644
+--- a/src/mesa/drivers/dri/i965/brw_clear.c
++++ b/src/mesa/drivers/dri/i965/brw_clear.c
+@@ -40,6 +40,8 @@
+ #include "intel_mipmap_tree.h"
+ #include "intel_regions.h"
+ 
++#include "brw_context.h"
++
+ #define FILE_DEBUG_FLAG DEBUG_BLIT
+ 
+ static const char *buffer_names[] = {
+@@ -219,7 +221,8 @@ brw_fast_clear_depth(struct gl_context *ctx)
+ static void
+ brw_clear(struct gl_context *ctx, GLbitfield mask)
+ {
+-   struct intel_context *intel = intel_context(ctx);
++   struct brw_context *brw = brw_context(ctx);
++   struct intel_context *intel = &brw->intel;
+ 
+    if (!_mesa_check_conditional_render(ctx))
+       return;
+@@ -229,6 +232,7 @@ brw_clear(struct gl_context *ctx, GLbitfield mask)
+    }
+ 
+    intel_prepare_render(intel);
++   brw_workaround_depthstencil_alignment(brw);
+ 
+    if (mask & BUFFER_BIT_DEPTH) {
+       if (brw_fast_clear_depth(ctx)) {
+diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
+index 79cc12f..4bcfb95 100644
+--- a/src/mesa/drivers/dri/i965/brw_defines.h
++++ b/src/mesa/drivers/dri/i965/brw_defines.h
+@@ -437,6 +437,7 @@
+ #define BRW_SURFACEFORMAT_B10G10R10A2_SSCALED            0x1B9
+ #define BRW_SURFACEFORMAT_B10G10R10A2_UINT               0x1BA
+ #define BRW_SURFACEFORMAT_B10G10R10A2_SINT               0x1BB
++#define BRW_SURFACEFORMAT_RAW                            0x1FF
+ #define BRW_SURFACE_FORMAT_SHIFT	18
+ #define BRW_SURFACE_FORMAT_MASK		INTEL_MASK(26, 18)
+ 
+@@ -857,6 +858,7 @@ enum brw_message_target {
+    GEN6_SFID_DATAPORT_CONSTANT_CACHE = 9,
+ 
+    GEN7_SFID_DATAPORT_DATA_CACHE     = 10,
++   HSW_SFID_DATAPORT_DATA_CACHE_1    = 12,
+ };
+ 
+ #define GEN7_MESSAGE_TARGET_DP_DATA_CACHE     10
+@@ -965,7 +967,44 @@ enum brw_message_target {
+ 
+ /* GEN7 */
+ #define GEN7_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE          10
++#define GEN7_DATAPORT_DC_OWORD_BLOCK_READ                           0
++#define GEN7_DATAPORT_DC_UNALIGNED_OWORD_BLOCK_READ                 1
++#define GEN7_DATAPORT_DC_OWORD_DUAL_BLOCK_READ                      2
+ #define GEN7_DATAPORT_DC_DWORD_SCATTERED_READ                       3
++#define GEN7_DATAPORT_DC_BYTE_SCATTERED_READ                        4
++#define GEN7_DATAPORT_DC_UNTYPED_SURFACE_READ                       5
++#define GEN7_DATAPORT_DC_UNTYPED_ATOMIC_OP                          6
++#define GEN7_DATAPORT_DC_MEMORY_FENCE                               7
++#define GEN7_DATAPORT_DC_OWORD_BLOCK_WRITE                          8
++#define GEN7_DATAPORT_DC_OWORD_DUAL_BLOCK_WRITE                     10
++#define GEN7_DATAPORT_DC_DWORD_SCATTERED_WRITE                      11
++#define GEN7_DATAPORT_DC_BYTE_SCATTERED_WRITE                       12
++#define GEN7_DATAPORT_DC_UNTYPED_SURFACE_WRITE                      13
++
++/* HSW */
++#define HSW_DATAPORT_DC_PORT0_OWORD_BLOCK_READ                      0
++#define HSW_DATAPORT_DC_PORT0_UNALIGNED_OWORD_BLOCK_READ            1
++#define HSW_DATAPORT_DC_PORT0_OWORD_DUAL_BLOCK_READ                 2
++#define HSW_DATAPORT_DC_PORT0_DWORD_SCATTERED_READ                  3
++#define HSW_DATAPORT_DC_PORT0_BYTE_SCATTERED_READ                   4
++#define HSW_DATAPORT_DC_PORT0_MEMORY_FENCE                          7
++#define HSW_DATAPORT_DC_PORT0_OWORD_BLOCK_WRITE                     8
++#define HSW_DATAPORT_DC_PORT0_OWORD_DUAL_BLOCK_WRITE                10
++#define HSW_DATAPORT_DC_PORT0_DWORD_SCATTERED_WRITE                 11
++#define HSW_DATAPORT_DC_PORT0_BYTE_SCATTERED_WRITE                  12
++
++#define HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ                  1
++#define HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP                     2
++#define HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2             3
++#define HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_READ                      4
++#define HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ                    5
++#define HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP                       6
++#define HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2               7
++#define HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE                 9
++#define HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_WRITE                     10
++#define HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP                     11
++#define HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2             12
++#define HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE                   13
+ 
+ /* dataport atomic operations. */
+ #define BRW_AOP_AND                   1
+diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
+index b34754a..40cae37 100644
+--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
++++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
+@@ -2539,15 +2539,22 @@ void brw_shader_time_add(struct brw_compile *p,
+    brw_set_src0(p, send, brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE,
+                                       base_mrf, 0));
+ 
++   uint32_t sfid, msg_type;
++   if (intel->is_haswell) {
++      sfid = HSW_SFID_DATAPORT_DATA_CACHE_1;
++      msg_type = HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP;
++   } else {
++      sfid = GEN7_SFID_DATAPORT_DATA_CACHE;
++      msg_type = GEN7_DATAPORT_DC_UNTYPED_ATOMIC_OP;
++   }
++
+    bool header_present = false;
+    bool eot = false;
+    uint32_t mlen = 2; /* offset, value */
+    uint32_t rlen = 0;
+-   brw_set_message_descriptor(p, send,
+-                              GEN7_SFID_DATAPORT_DATA_CACHE,
+-                              mlen, rlen, header_present, eot);
++   brw_set_message_descriptor(p, send, sfid, mlen, rlen, header_present, eot);
+ 
+-   send->bits3.ud |= 6 << 14; /* untyped atomic op */
++   send->bits3.ud |= msg_type << 14;
+    send->bits3.ud |= 0 << 13; /* no return data */
+    send->bits3.ud |= 1 << 12; /* SIMD8 mode */
+    send->bits3.ud |= BRW_AOP_ADD << 8;
+diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
+index f80219e..4924441 100644
+--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
++++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
+@@ -2295,7 +2295,8 @@ clear_deps_for_inst_src(fs_inst *inst, int dispatch_width, bool *deps,
+ void
+ fs_visitor::insert_gen4_pre_send_dependency_workarounds(fs_inst *inst)
+ {
+-   int write_len = inst->regs_written() * dispatch_width / 8;
++   int reg_size = dispatch_width / 8;
++   int write_len = inst->regs_written() * reg_size;
+    int first_write_grf = inst->dst.reg;
+    bool needs_dep[BRW_MAX_MRF];
+    assert(write_len < (int)sizeof(needs_dep) - 1);
+@@ -2334,14 +2335,19 @@ fs_visitor::insert_gen4_pre_send_dependency_workarounds(fs_inst *inst)
+        * instruction but a MOV that might have left us an outstanding
+        * dependency has more latency than a MOV.
+        */
+-      if (scan_inst->dst.file == GRF &&
+-          scan_inst->dst.reg >= first_write_grf &&
+-          scan_inst->dst.reg < first_write_grf + write_len &&
+-          needs_dep[scan_inst->dst.reg - first_write_grf]) {
+-         inst->insert_before(DEP_RESOLVE_MOV(scan_inst->dst.reg));
+-         needs_dep[scan_inst->dst.reg - first_write_grf] = false;
+-         if (scan_inst_16wide)
+-            needs_dep[scan_inst->dst.reg - first_write_grf + 1] = false;
++      if (scan_inst->dst.file == GRF) {
++         for (int i = 0; i < scan_inst->regs_written(); i++) {
++            int reg = scan_inst->dst.reg + i * reg_size;
++
++            if (reg >= first_write_grf &&
++                reg < first_write_grf + write_len &&
++                needs_dep[reg - first_write_grf]) {
++               inst->insert_before(DEP_RESOLVE_MOV(reg));
++               needs_dep[reg - first_write_grf] = false;
++               if (scan_inst_16wide)
++                  needs_dep[reg - first_write_grf + 1] = false;
++            }
++         }
+       }
+ 
+       /* Clear the flag for registers that actually got read (as expected). */
+@@ -2494,6 +2500,8 @@ fs_visitor::lower_uniform_pull_constant_loads()
+          inst->insert_before(setup2);
+          inst->opcode = FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD_GEN7;
+          inst->src[1] = payload;
++
++         this->live_intervals_valid = false;
+       } else {
+          /* Before register allocation, we didn't tell the scheduler about the
+           * MRF we use.  We know it's safe to use this MRF because nothing
+diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
+index db8f397..4c7991d 100644
+--- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
++++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
+@@ -190,6 +190,37 @@ fs_visitor::calculate_live_intervals()
+ 	    int reg = inst->src[i].reg;
+ 
+ 	    use[reg] = ip;
++
++            /* In most cases, a register can be written over safely by the
++             * same instruction that is its last use.  For a single
++             * instruction, the sources are dereferenced before writing of the
++             * destination starts (naturally).  This gets more complicated for
++             * simd16, because the instruction:
++             *
++             * mov(16)      g4<1>F      g4<8,8,1>F   g6<8,8,1>F
++             *
++             * is actually decoded in hardware as:
++             *
++             * mov(8)       g4<1>F      g4<8,8,1>F   g6<8,8,1>F
++             * mov(8)       g5<1>F      g5<8,8,1>F   g7<8,8,1>F
++             *
++             * Which is safe.  However, if we have uniform accesses
++             * happening, we get into trouble:
++             *
++             * mov(8)       g4<1>F      g4<0,1,0>F   g6<8,8,1>F
++             * mov(8)       g5<1>F      g4<0,1,0>F   g7<8,8,1>F
++             *
++             * Now our destination for the first instruction overwrote the
++             * second instruction's src0, and we get garbage for those 8
++             * pixels.  There's a similar issue for the pre-gen6
++             * pixel_x/pixel_y, which are registers of 16-bit values and thus
++             * would get stomped by the first decode as well.
++             */
++            if (dispatch_width == 16 && (inst->src[i].smear ||
++                                         (this->pixel_x.reg == reg ||
++                                          this->pixel_y.reg == reg))) {
++               use[reg]++;
++            }
+ 	 }
+       }
+ 
+@@ -264,28 +295,5 @@ fs_visitor::virtual_grf_interferes(int a, int b)
+    int start = MAX2(a_def, b_def);
+    int end = MIN2(a_use, b_use);
+ 
+-   /* If the register is used to store 16 values of less than float
+-    * size (only the case for pixel_[xy]), then we can't allocate
+-    * another dword-sized thing to that register that would be used in
+-    * the same instruction.  This is because when the GPU decodes (for
+-    * example):
+-    *
+-    * (declare (in ) vec4 gl_FragCoord at 0x97766a0)
+-    * add(16)         g6<1>F          g6<8,8,1>UW     0.5F { align1 compr };
+-    *
+-    * it's actually processed as:
+-    * add(8)         g6<1>F          g6<8,8,1>UW     0.5F { align1 };
+-    * add(8)         g7<1>F          g6.8<8,8,1>UW   0.5F { align1 sechalf };
+-    *
+-    * so our second half values in g6 got overwritten in the first
+-    * half.
+-    */
+-   if (dispatch_width == 16 && (this->pixel_x.reg == a ||
+-				this->pixel_x.reg == b ||
+-				this->pixel_y.reg == a ||
+-				this->pixel_y.reg == b)) {
+-      return start <= end;
+-   }
+-
+    return start < end;
+ }
+diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
+index ecc61c4..02ce57b 100644
+--- a/src/mesa/drivers/dri/i965/brw_state.h
++++ b/src/mesa/drivers/dri/i965/brw_state.h
+@@ -216,6 +216,8 @@ void gen7_set_surface_mcs_info(struct brw_context *brw,
+                                bool is_render_target);
+ void gen7_check_surface_setup(uint32_t *surf, bool is_render_target);
+ void gen7_init_vtable_surface_functions(struct brw_context *brw);
++void gen7_create_shader_time_surface(struct brw_context *brw,
++                                     uint32_t *out_offset);
+ 
+ /* brw_wm_sampler_state.c */
+ uint32_t translate_wrap_mode(GLenum wrap, bool using_nearest);
+diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+index 4da7eaa..2aefc0c 100644
+--- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
++++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+@@ -137,14 +137,11 @@ const struct brw_tracked_state brw_vs_ubo_surfaces = {
+ static void
+ brw_vs_upload_binding_table(struct brw_context *brw)
+ {
+-   struct intel_context *intel = &brw->intel;
+    uint32_t *bind;
+    int i;
+ 
+    if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
+-      intel->vtbl.create_constant_surface(brw, brw->shader_time.bo, 0,
+-                                          brw->shader_time.bo->size,
+-                                          &brw->vs.surf_offset[SURF_INDEX_VS_SHADER_TIME]);
++      gen7_create_shader_time_surface(brw, &brw->vs.surf_offset[SURF_INDEX_VS_SHADER_TIME]);
+ 
+       assert(brw->vs.prog_data->num_surfaces <= SURF_INDEX_VS_SHADER_TIME);
+       brw->vs.prog_data->num_surfaces = SURF_INDEX_VS_SHADER_TIME;
+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 6ec7d71..657a56f 100644
+--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
++++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+@@ -770,7 +770,8 @@ brw_get_texture_swizzle(const struct gl_context *ctx,
+    case GL_RED:
+    case GL_RG:
+    case GL_RGB:
+-      swizzles[3] = SWIZZLE_ONE;
++      if (_mesa_get_format_bits(img->TexFormat, GL_ALPHA_BITS) > 0)
++         swizzles[3] = SWIZZLE_ONE;
+       break;
+    }
+ 
+@@ -1468,14 +1469,11 @@ const struct brw_tracked_state brw_wm_ubo_surfaces = {
+ static void
+ brw_upload_wm_binding_table(struct brw_context *brw)
+ {
+-   struct intel_context *intel = &brw->intel;
+    uint32_t *bind;
+    int i;
+ 
+    if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
+-      intel->vtbl.create_constant_surface(brw, brw->shader_time.bo, 0,
+-                                          brw->shader_time.bo->size,
+-                                          &brw->wm.surf_offset[SURF_INDEX_WM_SHADER_TIME]);
++      gen7_create_shader_time_surface(brw, &brw->wm.surf_offset[SURF_INDEX_WM_SHADER_TIME]);
+    }
+ 
+    /* Might want to calculate nr_surfaces first, to avoid taking up so much
+diff --git a/src/mesa/drivers/dri/i965/gen6_cc.c b/src/mesa/drivers/dri/i965/gen6_cc.c
+index d32f636..7ac5d5f 100644
+--- a/src/mesa/drivers/dri/i965/gen6_cc.c
++++ b/src/mesa/drivers/dri/i965/gen6_cc.c
+@@ -126,7 +126,7 @@ gen6_upload_blend_state(struct brw_context *brw)
+           * not read the alpha channel, but will instead use the correct
+           * implicit value for alpha.
+           */
+-         if (!_mesa_base_format_has_channel(rb->_BaseFormat, GL_TEXTURE_ALPHA_TYPE))
++         if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat, GL_TEXTURE_ALPHA_TYPE))
+          {
+             srcRGB = brw_fix_xRGB_alpha(srcRGB);
+             srcA = brw_fix_xRGB_alpha(srcA);
+diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
+index 24f1b9c..2913fc6 100644
+--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
++++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
+@@ -413,6 +413,46 @@ gen7_create_constant_surface(struct brw_context *brw,
+    gen7_check_surface_setup(surf, false /* is_render_target */);
+ }
+ 
++/**
++ * Create a surface for shader time.
++ */
++void
++gen7_create_shader_time_surface(struct brw_context *brw, uint32_t *out_offset)
++{
++   struct intel_context *intel = &brw->intel;
++   const int w = brw->shader_time.bo->size - 1;
++
++   uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
++                                    8 * 4, 32, out_offset);
++   memset(surf, 0, 8 * 4);
++
++   surf[0] = BRW_SURFACE_BUFFER << BRW_SURFACE_TYPE_SHIFT |
++             BRW_SURFACEFORMAT_RAW << BRW_SURFACE_FORMAT_SHIFT |
++             BRW_SURFACE_RC_READ_WRITE;
++
++   surf[1] = brw->shader_time.bo->offset; /* reloc */
++
++   surf[2] = SET_FIELD(w & 0x7f, GEN7_SURFACE_WIDTH) |
++             SET_FIELD((w >> 7) & 0x1fff, GEN7_SURFACE_HEIGHT);
++   surf[3] = SET_FIELD((w >> 20) & 0x7f, BRW_SURFACE_DEPTH);
++
++   /* Unlike texture or renderbuffer surfaces, we only do untyped operations
++    * on the shader_time surface, so there's no need to set HSW channel
++    * overrides.
++    */
++
++   /* Emit relocation to surface contents.  Section 5.1.1 of the gen4
++    * bspec ("Data Cache") says that the data cache does not exist as
++    * a separate cache and is just the sampler cache.
++    */
++   drm_intel_bo_emit_reloc(intel->batch.bo,
++                           *out_offset + 4,
++                           brw->shader_time.bo, 0,
++                           I915_GEM_DOMAIN_SAMPLER, 0);
++
++   gen7_check_surface_setup(surf, false /* is_render_target */);
++}
++
+ static void
+ gen7_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit)
+ {
+diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
+index 5ec93f1..4173c0f 100644
+--- a/src/mesa/drivers/dri/intel/intel_screen.c
++++ b/src/mesa/drivers/dri/intel/intel_screen.c
+@@ -312,7 +312,7 @@ intel_create_image_from_name(__DRIscreen *screen,
+        cpp = _mesa_get_format_bytes(image->format);
+     image->region = intel_region_alloc_for_handle(intelScreen,
+ 						  cpp, width, height,
+-						  pitch, name, "image");
++						  pitch * cpp, name, "image");
+     if (image->region == NULL) {
+        free(image);
+        return NULL;
+diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
+index f56b3b2..6c119d5 100644
+--- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c
++++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
+@@ -69,7 +69,8 @@ nouveau_flush(struct gl_context *ctx)
+ 		__DRIdri2LoaderExtension *dri2 = screen->dri2.loader;
+ 		__DRIdrawable *drawable = nctx->dri_context->driDrawablePriv;
+ 
+-		dri2->flushFrontBuffer(drawable, drawable->loaderPrivate);
++		if (drawable && drawable->loaderPrivate)
++			dri2->flushFrontBuffer(drawable, drawable->loaderPrivate);
+ 	}
+ }
+ 
+diff --git a/src/mesa/drivers/dri/nouveau/nv10_context.c b/src/mesa/drivers/dri/nouveau/nv10_context.c
+index 7eda4e0..4ffc4ef 100644
+--- a/src/mesa/drivers/dri/nouveau/nv10_context.c
++++ b/src/mesa/drivers/dri/nouveau/nv10_context.c
+@@ -469,7 +469,7 @@ nv10_context_create(struct nouveau_screen *screen, const struct gl_config *visua
+ 		goto fail;
+ 
+ 	/* 3D engine. */
+-	if (context_chipset(ctx) >= 0x17)
++	if (context_chipset(ctx) >= 0x17 && context_chipset(ctx) != 0x1a)
+ 		celsius_class = NV17_3D_CLASS;
+ 	else if (context_chipset(ctx) >= 0x11)
+ 		celsius_class = NV15_3D_CLASS;
+diff --git a/src/mesa/drivers/osmesa/Makefile.am b/src/mesa/drivers/osmesa/Makefile.am
+index c4b178b..2503401 100644
+--- a/src/mesa/drivers/osmesa/Makefile.am
++++ b/src/mesa/drivers/osmesa/Makefile.am
+@@ -24,6 +24,7 @@
+ AM_CPPFLAGS = \
+ 	-I$(top_srcdir)/include \
+ 	-I$(top_srcdir)/src/mapi \
++	-I$(top_builddir)/src/mapi \
+ 	-I$(top_srcdir)/src/mesa/ \
+ 	$(DEFINES) \
+ 	$(API_DEFINES)
+diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h
+index b22b994..8b23665 100644
+--- a/src/mesa/main/compiler.h
++++ b/src/mesa/main/compiler.h
+@@ -48,6 +48,8 @@
+ #include <float.h>
+ #include <stdarg.h>
+ 
++#include "c99_compat.h" /* inline, __func__, etc. */
++
+ 
+ #ifdef __cplusplus
+ extern "C" {
+@@ -111,30 +113,7 @@ extern "C" {
+ 
+ 
+ 
+-/**
+- * Function inlining
+- */
+-#ifndef inline
+-#  ifdef __cplusplus
+-     /* C++ supports inline keyword */
+-#  elif defined(__GNUC__)
+-#    define inline __inline__
+-#  elif defined(_MSC_VER)
+-#    define inline __inline
+-#  elif defined(__ICL)
+-#    define inline __inline
+-#  elif defined(__INTEL_COMPILER)
+-     /* Intel compiler supports inline keyword */
+-#  elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
+-#    define inline __inline
+-#  elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
+-     /* C99 supports inline keyword */
+-#  elif (__STDC_VERSION__ >= 199901L)
+-     /* C99 supports inline keyword */
+-#  else
+-#    define inline
+-#  endif
+-#endif
++/* XXX: Use standard `inline` keyword instead */
+ #ifndef INLINE
+ #  define INLINE inline
+ #endif
+@@ -177,35 +156,10 @@ extern "C" {
+ #  endif
+ #endif
+ 
+-/**
+- * The __FUNCTION__ gcc variable is generally only used for debugging.
+- * If we're not using gcc, define __FUNCTION__ as a cpp symbol here.
+- * Don't define it if using a newer Windows compiler.
+- */
++/* XXX: Use standard `__func__` instead */
+ #ifndef __FUNCTION__
+-# if !defined(__GNUC__) && !defined(__xlC__) &&	\
+-      (!defined(_MSC_VER) || _MSC_VER < 1300)
+-#  if (__STDC_VERSION__ >= 199901L) /* C99 */ || \
+-    (defined(__SUNPRO_C) && defined(__C99FEATURES__))
+-#   define __FUNCTION__ __func__
+-#  else
+-#   define __FUNCTION__ "<unknown>"
+-#  endif
+-# endif
++#  define __FUNCTION__ __func__
+ #endif
+-#ifndef __func__
+-#  if (__STDC_VERSION__ >= 199901L) || \
+-      (defined(__SUNPRO_C) && defined(__C99FEATURES__))
+-       /* __func__ is part of C99 */
+-#  elif defined(_MSC_VER)
+-#    if _MSC_VER >= 1300
+-#      define __func__ __FUNCTION__
+-#    else
+-#      define __func__ "<unknown>"
+-#    endif
+-#  endif
+-#endif
+-
+ 
+ /**
+  * Either define MESA_BIG_ENDIAN or MESA_LITTLE_ENDIAN, and CPU_TO_LE32.
+@@ -353,8 +307,9 @@ static INLINE GLuint CPU_TO_LE32(GLuint x)
+  * USE_IEEE: Determine if we're using IEEE floating point
+  */
+ #if defined(__i386__) || defined(__386__) || defined(__sparc__) || \
+-    defined(__s390x__) || defined(__powerpc__) || \
++    defined(__s390__) || defined(__s390x__) || defined(__powerpc__) || \
+     defined(__x86_64__) || \
++    defined(__m68k__) || \
+     defined(ia64) || defined(__ia64__) || \
+     defined(__hppa__) || defined(hpux) || \
+     defined(__mips) || defined(_MIPS_ARCH) || \
+diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
+index 257f839..61c1151 100644
+--- a/src/mesa/main/fbobject.c
++++ b/src/mesa/main/fbobject.c
+@@ -3160,7 +3160,9 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+       }
+    }
+ 
+-   if (!mask) {
++   if (!mask ||
++       (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
++       (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
+       return;
+    }
+ 
+diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
+index 5f4e2fa..6fb2f5d 100644
+--- a/src/mesa/main/get.c
++++ b/src/mesa/main/get.c
+@@ -34,6 +34,7 @@
+ #include "state.h"
+ #include "texcompress.h"
+ #include "framebuffer.h"
++#include "samplerobj.h"
+ 
+ /* This is a table driven implemetation of the glGet*v() functions.
+  * The basic idea is that most getters just look up an int somewhere
+@@ -823,7 +824,16 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
+       {
+          struct gl_sampler_object *samp =
+             ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler;
+-         v->value_int = samp ? samp->Name : 0;
++
++         /*
++          * The sampler object may have been deleted on another context,
++          * so we try to lookup the sampler object before returning its Name.
++          */
++         if (samp && _mesa_lookup_samplerobj(ctx, samp->Name)) {
++            v->value_int = samp->Name;
++         } else {
++            v->value_int = 0;
++         }
+       }
+       break;
+    /* GL_ARB_uniform_buffer_object */
+diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
+index 9aab889..15c1c4d 100644
+--- a/src/mesa/main/get_hash_params.py
++++ b/src/mesa/main/get_hash_params.py
+@@ -412,7 +412,7 @@ descriptor=[
+   [ "DEPTH_SCALE", "CONTEXT_FLOAT(Pixel.DepthScale), NO_EXTRA" ],
+   [ "DOUBLEBUFFER", "BUFFER_INT(Visual.doubleBufferMode), NO_EXTRA" ],
+   [ "DRAW_BUFFER", "BUFFER_ENUM(ColorDrawBuffer[0]), NO_EXTRA" ],
+-  [ "EDGE_FLAG", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ],
++  [ "EDGE_FLAG", "LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_flush_current" ],
+   [ "FEEDBACK_BUFFER_SIZE", "CONTEXT_INT(Feedback.BufferSize), NO_EXTRA" ],
+   [ "FEEDBACK_BUFFER_TYPE", "CONTEXT_ENUM(Feedback.Type), NO_EXTRA" ],
+   [ "FOG_INDEX", "CONTEXT_FLOAT(Fog.Index), NO_EXTRA" ],
+diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
+index 3369623..8f906ae 100644
+--- a/src/mesa/main/mtypes.h
++++ b/src/mesa/main/mtypes.h
+@@ -1274,6 +1274,7 @@ struct gl_texture_object
+    GLfloat Priority;		/**< in [0,1] */
+    GLint BaseLevel;		/**< min mipmap level, OpenGL 1.2 */
+    GLint MaxLevel;		/**< max mipmap level, OpenGL 1.2 */
++   GLint ImmutableLevels;       /**< ES 3.0 / ARB_texture_view */
+    GLint _MaxLevel;		/**< actual max mipmap level (q in the spec) */
+    GLfloat _MaxLambda;		/**< = _MaxLevel - BaseLevel (q - b in spec) */
+    GLint CropRect[4];           /**< GL_OES_draw_texture */
+diff --git a/src/mesa/main/samplerobj.c b/src/mesa/main/samplerobj.c
+index 319a444..5cff329 100644
+--- a/src/mesa/main/samplerobj.c
++++ b/src/mesa/main/samplerobj.c
+@@ -40,7 +40,7 @@
+ #include "main/samplerobj.h"
+ 
+ 
+-static struct gl_sampler_object *
++struct gl_sampler_object *
+ _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name)
+ {
+    if (name == 0)
+@@ -206,9 +206,19 @@ _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers)
+ 
+    for (i = 0; i < count; i++) {
+       if (samplers[i]) {
++         GLuint j;
+          struct gl_sampler_object *sampObj =
+             _mesa_lookup_samplerobj(ctx, samplers[i]);
++   
+          if (sampObj) {
++            /* If the sampler is currently bound, unbind it. */
++            for (j = 0; j < ctx->Const.MaxCombinedTextureImageUnits; j++) {
++               if (ctx->Texture.Unit[j].Sampler == sampObj) {
++                  FLUSH_VERTICES(ctx, _NEW_TEXTURE);
++                  _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[j].Sampler, NULL);
++               }
++            }
++
+             /* The ID is immediately freed for re-use */
+             _mesa_HashRemove(ctx->Shared->SamplerObjects, samplers[i]);
+             /* But the object exists until its reference count goes to zero */
+diff --git a/src/mesa/main/samplerobj.h b/src/mesa/main/samplerobj.h
+index 3114257..69e3899 100644
+--- a/src/mesa/main/samplerobj.h
++++ b/src/mesa/main/samplerobj.h
+@@ -62,6 +62,8 @@ _mesa_reference_sampler_object(struct gl_context *ctx,
+       _mesa_reference_sampler_object_(ctx, ptr, samp);
+ }
+ 
++extern struct gl_sampler_object *
++_mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name);
+ 
+ extern struct gl_sampler_object *
+ _mesa_new_sampler_object(struct gl_context *ctx, GLuint name);
+diff --git a/src/mesa/main/tests/hash_table/Makefile.am b/src/mesa/main/tests/hash_table/Makefile.am
+index 272c63a..f63841d 100644
+--- a/src/mesa/main/tests/hash_table/Makefile.am
++++ b/src/mesa/main/tests/hash_table/Makefile.am
+@@ -19,6 +19,7 @@
+ #  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ 
+ AM_CPPFLAGS = \
++	-I$(top_srcdir)/include \
+ 	-I$(top_srcdir)/src/mesa/main \
+ 	$(API_DEFINES) $(DEFINES) $(INCLUDE_DIRS)
+ 
+diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
+index 7299a4b..74b09ef 100644
+--- a/src/mesa/main/texgetimage.c
++++ b/src/mesa/main/texgetimage.c
+@@ -518,6 +518,7 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
+    if (type_needs_clamping(type)) {
+       /* the returned image type can't have negative values */
+       if (dataType == GL_FLOAT ||
++          dataType == GL_HALF_FLOAT ||
+           dataType == GL_SIGNED_NORMALIZED ||
+           format == GL_LUMINANCE ||
+           format == GL_LUMINANCE_ALPHA) {
+diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
+index 1b9525b..1b91b89 100644
+--- a/src/mesa/main/teximage.c
++++ b/src/mesa/main/teximage.c
+@@ -1362,6 +1362,7 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
+          return GL_FALSE;
+       return GL_TRUE;
+ 
++   case GL_TEXTURE_CUBE_MAP:
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+@@ -3438,19 +3439,21 @@ copyteximage(struct gl_context *ctx, GLuint dims,
+          _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
+                                     border, internalFormat, texFormat);
+ 
+-         /* Allocate texture memory (no pixel data yet) */
+-         ctx->Driver.AllocTextureImageBuffer(ctx, texImage);
++         if (width && height) {
++            /* Allocate texture memory (no pixel data yet) */
++            ctx->Driver.AllocTextureImageBuffer(ctx, texImage);
+ 
+-         if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
+-                                        &width, &height)) {
+-            struct gl_renderbuffer *srcRb =
+-               get_copy_tex_image_source(ctx, texImage->TexFormat);
++            if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
++                                           &width, &height)) {
++               struct gl_renderbuffer *srcRb =
++                  get_copy_tex_image_source(ctx, texImage->TexFormat);
+ 
+-            ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ,
+-                                        srcRb, srcX, srcY, width, height);
+-         }
++               ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ,
++                                           srcRb, srcX, srcY, width, height);
++            }
+ 
+-         check_gen_mipmap(ctx, target, texObj, level);
++            check_gen_mipmap(ctx, target, texObj, level);
++         }
+ 
+          _mesa_update_fbo_texture(ctx, texObj, face, level);
+ 
+diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
+index 6f18ec6..dd67baa 100644
+--- a/src/mesa/main/texparam.c
++++ b/src/mesa/main/texparam.c
+@@ -1432,6 +1432,12 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
+          *params = (GLfloat) obj->Immutable;
+          break;
+ 
++      case GL_TEXTURE_IMMUTABLE_LEVELS:
++         if (!_mesa_is_gles3(ctx))
++            goto invalid_pname;
++         *params = (GLfloat) obj->ImmutableLevels;
++         break;
++
+       case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+          if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
+             goto invalid_pname;
+@@ -1609,6 +1615,12 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
+          *params = (GLint) obj->Immutable;
+          break;
+ 
++      case GL_TEXTURE_IMMUTABLE_LEVELS:
++         if (!_mesa_is_gles3(ctx))
++            goto invalid_pname;
++         *params = obj->ImmutableLevels;
++         break;
++
+       case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+          if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
+             goto invalid_pname;
+diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c
+index 00f19ba..675fd74 100644
+--- a/src/mesa/main/texstorage.c
++++ b/src/mesa/main/texstorage.c
+@@ -397,6 +397,7 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
+       }
+ 
+       texObj->Immutable = GL_TRUE;
++      texObj->ImmutableLevels = levels;
+    }
+ }
+ 
+diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
+index efb386e..f5b5c41 100644
+--- a/src/mesa/vbo/vbo_save_draw.c
++++ b/src/mesa/vbo/vbo_save_draw.c
+@@ -253,7 +253,7 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
+    struct vbo_save_context *save = &vbo_context(ctx)->save;
+    GLboolean remap_vertex_store = GL_FALSE;
+ 
+-   if (save->vertex_store->buffer) {
++   if (save->vertex_store && save->vertex_store->buffer) {
+       /* The vertex store is currently mapped but we're about to replay
+        * a display list.  This can happen when a nested display list is
+        * being build with GL_COMPILE_AND_EXECUTE.
diff --git a/mesa.spec b/mesa.spec
index cdf5126..7d9f01b 100644
--- a/mesa.spec
+++ b/mesa.spec
@@ -47,8 +47,8 @@
 
 Summary: Mesa graphics libraries
 Name: mesa
-Version: 9.1
-Release: 6%{?dist}
+Version: 9.1.1
+Release: 1%{?dist}
 License: MIT
 Group: System Environment/Libraries
 URL: http://www.mesa3d.org
@@ -64,7 +64,7 @@ Source3: make-git-snapshot.sh
 Source4: Mesa-MLAA-License-Clarification-Email.txt
 
 # git diff-tree -p mesa-9.1..origin/9.1 > `git describe origin/9.1`.patch
-Patch0: mesa-9.1-53-gd0ccb5b.patch
+Patch0: mesa-9.1.1-53-g3cff41c.patch
 
 Patch1: nv50-fix-build.patch
 Patch2: intel-revert-gl3.patch
@@ -592,6 +592,9 @@ rm -rf $RPM_BUILD_ROOT
 %endif
 
 %changelog
+* Sat Apr 27 2013 Dave Airlie <airlied at redhat.com> 9.1.1-1
+- rebase to Mesa 9.1.1 + fixes from git
+
 * Thu Apr 11 2013 Dave Airlie <airlied at redhat.com> 9.1-6
 - enable glx tls for glamor to work properly
 
diff --git a/sources b/sources
index 9dba37c..7ecd241 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-d3891e02215422e120271d976ff1947e  MesaLib-9.1.tar.bz2
+6ea2bdc3b7ecfb4257b39814b4182580  MesaLib-9.1.1.tar.bz2


More information about the scm-commits mailing list