summary refs log tree commit diff
path: root/pkgs/development/libraries/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/development/libraries/mesa')
-rw-r--r--pkgs/development/libraries/mesa/default.nix138
-rw-r--r--pkgs/development/libraries/mesa/dricore-gallium.patch216
-rw-r--r--pkgs/development/libraries/mesa/fix-rounding.patch357
-rw-r--r--pkgs/development/libraries/mesa/mips_wmb.patch16
-rw-r--r--pkgs/development/libraries/mesa/static-gallium.patch71
5 files changed, 764 insertions, 34 deletions
diff --git a/pkgs/development/libraries/mesa/default.nix b/pkgs/development/libraries/mesa/default.nix
index d3f7afbd308..de130d465c2 100644
--- a/pkgs/development/libraries/mesa/default.nix
+++ b/pkgs/development/libraries/mesa/default.nix
@@ -1,41 +1,143 @@
-{ stdenv, fetchurl, flex, bison, pkgconfig, libdrm, file, expat, makedepend
-, libXxf86vm, libXfixes, libXdamage, glproto, dri2proto, libX11, libxcb, libXext
-, libXt, udev, enableTextureFloats ? false
-, python, libxml2Python }:
+{ stdenv, fetchurl, pkgconfig, intltool, flex, bison, autoconf, automake, libtool
+, python, libxml2Python, file, expat, makedepend
+, libdrm, xorg, wayland, udev, llvm, libffi
+, libvdpau
+, enableTextureFloats ? false # Texture floats are patented, see docs/patents.txt
+, enableR600LlvmCompiler ? false # we would need currently unreleased LLVM or patches
+, enableExtraFeatures ? false # add ~15 MB to mesa_drivers
+}:
 
 if ! stdenv.lib.lists.elem stdenv.system stdenv.lib.platforms.mesaPlatforms then
   throw "unsupported platform for Mesa"
 else
 
-let version = "8.0.4"; in
+/** Packaging design:
+  - The basic mesa ($out) contains headers and libraries (GLU is in mesa_glu now).
+    This or the mesa attribute (which also contains GLU) are small (~ 2.2 MB, mostly headers)
+    and are designed to be the buildInput of other packages.
+  - DRI and EGL drivers are compiled into $drivers output,
+    which is bigger (~13 MB) and depends on LLVM (~40 MB).
+    These should be searched at runtime in /run/current-system/sw/lib/*
+    and so are kind-of impure (given by NixOS).
+    (I suppose on non-NixOS one would create the appropriate symlinks from there.)
+*/
 
+let
+  version = "9.1.3";
+  driverLink = "/run/opengl-driver" + stdenv.lib.optionalString stdenv.isi686 "-32";
+in
 stdenv.mkDerivation {
-  name = "mesa-${version}";
+  name = "mesa-noglu-${version}";
 
   src = fetchurl {
     url = "ftp://ftp.freedesktop.org/pub/mesa/${version}/MesaLib-${version}.tar.bz2";
-    md5 = "d546f988adfdf986cff45b1efa2d8a46";
+    sha256="0rnpaambxv5cd6kbfyvv4b8x2rw1xj13a67xbkzmndfh08iaqpcd";
   };
 
-  patches =
-    stdenv.lib.optional (stdenv.system == "mips64el-linux") ./mips_wmb.patch;
-
   prePatch = "patchShebangs .";
 
-  configureFlags =
-      " --enable-gles1 --enable-gles2 --enable-gallium-egl"
-    + " --with-gallium-drivers=i915,nouveau,r600,svga,swrast"
-    # Texture floats are patented, see docs/patents.txt
-    + stdenv.lib.optionalString enableTextureFloats " --enable-texture-float";
+  patches = [
+    ./static-gallium.patch
+    ./dricore-gallium.patch
+    ./fix-rounding.patch
+  ];
+
+  # Change the search path for EGL drivers from $drivers/* to driverLink
+  postPatch = ''
+    sed '/D_EGL_DRIVER_SEARCH_DIR=/s,EGL_DRIVER_INSTALL_DIR,${driverLink}/lib/egl,' \
+      -i src/egl/main/Makefile.am
+  '';
+
+  outputs = ["out" "drivers"];
+
+  preConfigure = "./autogen.sh";
+
+  configureFlags = with stdenv.lib; [
+    "--with-dri-driverdir=$(drivers)/lib/dri"
+    "--with-egl-driver-dir=$(drivers)/lib/egl"
+    "--with-dri-searchpath=${driverLink}/lib/dri"
+
+    "--enable-dri"
+    "--enable-glx-tls"
+    "--enable-shared-glapi" "--enable-shared-gallium"
+    "--enable-driglx-direct" # seems enabled anyway
+    "--enable-gallium-llvm" "--with-llvm-shared-libs"
+    "--enable-xa" # used in vmware driver
 
-  buildInputs = [ expat libdrm libXxf86vm libXfixes libXdamage glproto dri2proto
-    libxml2Python libX11 libXext libxcb libXt udev ];
+    "--with-dri-drivers=i965,r200,radeon"
+    "--with-gallium-drivers=i915,nouveau,r300,r600,svga,swrast" # radeonsi complains about R600 missing in LLVM
+    "--with-egl-platforms=x11,wayland,drm" "--enable-gbm" "--enable-shared-glapi"
+  ]
+    ++ optional enableR600LlvmCompiler "--enable-r600-llvm-compiler" # complains about R600 missing in LLVM
+    ++ optional enableTextureFloats "--enable-texture-float"
+    ++ optionals enableExtraFeatures [
+      "--enable-gles1" "--enable-gles2"
+      "--enable-osmesa"
+      "--enable-openvg" "--enable-gallium-egl" # not needed for EGL in Gallium, but OpenVG might be useful
+      #"--enable-xvmc" # tests segfault with 9.1.{1,2,3}
+      "--enable-vdpau"
+      #"--enable-opencl" # ToDo: opencl seems to need libclc for clover
+    ];
 
   nativeBuildInputs = [ pkgconfig python makedepend file flex bison ];
 
+  propagatedBuildInputs = with xorg; [ libXdamage libXxf86vm ]
+  ++
+  stdenv.lib.optionals stdenv.isLinux [libdrm]
+  ;
+  buildInputs = with xorg; [
+    autoconf automake libtool intltool expat libxml2Python llvm
+    libXfixes glproto dri2proto libX11 libXext libxcb libXt
+    libffi wayland
+  ] ++ stdenv.lib.optionals enableExtraFeatures [ /*libXvMC*/ libvdpau ]
+  ++ stdenv.lib.optional stdenv.isLinux [udev]
+  ;
+
   enableParallelBuilding = true;
+  doCheck = true;
+
+  # move gallium-related stuff to $drivers, so $out doesn't depend on LLVM
+  # ToDo: probably not all .la files are completely fixed, but it shouldn't matter
+  postInstall = with stdenv.lib; ''
+    mv -t "$drivers/lib/" \
+  '' + optionalString enableExtraFeatures ''
+      `#$out/lib/libXvMC*` \
+      $out/lib/vdpau \
+      $out/lib/libOSMesa* \
+      $out/lib/gbm $out/lib/libgbm* \
+      $out/lib/gallium-pipe \
+  '' + ''
+      $out/lib/libdricore* \
+      $out/lib/libgallium* \
+      $out/lib/libxatracker*
+
+  '' + /* now fix references in .la files */ ''
+    sed "/^libdir=/s,$out,$drivers," -i \
+  '' + optionalString enableExtraFeatures ''
+      `#$drivers/lib/libXvMC*.la` \
+      $drivers/lib/vdpau/*.la \
+      $drivers/lib/libOSMesa*.la \
+      $drivers/lib/gallium-pipe/*.la \
+  '' + ''
+      $drivers/lib/libgallium.la \
+      $drivers/lib/libdricore*.la
+
+    sed "s,$out\(/lib/\(libdricore[0-9\.]*\|libgallium\).la\),$drivers\1,g" \
+      -i $drivers/lib/*.la $drivers/lib/*/*.la
+
+  '' + /* work around bug #529, but maybe $drivers should also be patchelf-ed */ ''
+    find $drivers/ -type f -executable -print0 | xargs -0 strip -S || true
+
+  '' + /* add RPATH so the drivers can find the moved libgallium and libdricore9 */ ''
+    for lib in $drivers/lib/*.so* $drivers/lib/*/*.so*; do
+      if [[ ! -L "$lib" ]]; then
+        patchelf --set-rpath "$(patchelf --print-rpath $lib):$drivers/lib" "$lib"
+      fi
+    done
+  '';
+  #ToDo: @vcunat isn't sure if drirc will be found when in $out/etc/, but it doesn't seem important ATM
 
-  passthru = { inherit libdrm; };
+  passthru = { inherit libdrm; inherit version; };
 
   meta = {
     description = "An open source implementation of OpenGL";
diff --git a/pkgs/development/libraries/mesa/dricore-gallium.patch b/pkgs/development/libraries/mesa/dricore-gallium.patch
new file mode 100644
index 00000000000..9a8b6768277
--- /dev/null
+++ b/pkgs/development/libraries/mesa/dricore-gallium.patch
@@ -0,0 +1,216 @@
+commit 5208f187c7dade2c33385a56c1a5f1c3cedc8377 (HEAD, nix-patches)
+Author: Vladimír Čunát <vcunat@gmail.com>
+Date:   Mon May 13 11:34:59 2013 +0200
+
+    118-dricore-gallium.patch
+
+diff --git a/configure.ac b/configure.ac
+index be89843..08f6761 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -928,6 +928,8 @@ AC_SUBST([GLESv2_LIB_DEPS])
+ AC_SUBST([GLESv2_PC_LIB_PRIV])
+ 
+ DRI_LIB_DEPS="\$(top_builddir)/src/mesa/libdricore/libdricore${VERSION}.la"
++MESAGALLIUM_LIBS="${DRI_LIB_DEPS}"
++AC_SUBST([MESAGALLIUM_LIBS], ${MESAGALLIUM_LIBS})
+ 
+ AC_SUBST([HAVE_XF86VIDMODE])
+ 
+diff --git a/src/gallium/auxiliary/Makefile.am b/src/gallium/auxiliary/Makefile.am
+index 3cdec83..53ff69b 100644
+--- a/src/gallium/auxiliary/Makefile.am
++++ b/src/gallium/auxiliary/Makefile.am
+@@ -34,14 +34,14 @@ if LLVM_NEEDS_FNORTTI
+ 
+ AM_CXXFLAGS += -fno-rtti
+ 
+-libgallium_la_LIBADD = $(LLVM_LIBS)
+-
+ endif
+ 
+ libgallium_la_SOURCES += \
+ 	$(GALLIVM_SOURCES) \
+ 	$(GALLIVM_CPP_SOURCES)
+ 
++libgallium_la_LIBADD = ../../mesa/libdricore/libmesagallium.la $(LLVM_LIBS) $(GALLIUM_DRI_LIB_DEPS)
++
+ endif
+ 
+ indices/u_indices_gen.c: $(srcdir)/indices/u_indices_gen.py
+diff --git a/src/gallium/targets/dri-i915/Makefile.am b/src/gallium/targets/dri-i915/Makefile.am
+index f4f9030..e9b9462 100644
+--- a/src/gallium/targets/dri-i915/Makefile.am
++++ b/src/gallium/targets/dri-i915/Makefile.am
+@@ -49,7 +49,7 @@ i915_dri_la_SOURCES = \
+ i915_dri_la_LDFLAGS = -module -avoid-version -shared -no-undefined
+ 
+ i915_dri_la_LIBADD = \
+-	$(top_builddir)/src/mesa/libmesagallium.la \
++	@MESAGALLIUM_LIBS@ \
+ 	$(top_builddir)/src/gallium/auxiliary/libgallium.la \
+ 	$(top_builddir)/src/gallium/state_trackers/dri/drm/libdridrm.la \
+ 	$(top_builddir)/src/gallium/winsys/i915/drm/libi915drm.la \
+diff --git a/src/gallium/targets/dri-nouveau/Makefile.am b/src/gallium/targets/dri-nouveau/Makefile.am
+index 69ccf32..fef4c63 100644
+--- a/src/gallium/targets/dri-nouveau/Makefile.am
++++ b/src/gallium/targets/dri-nouveau/Makefile.am
+@@ -48,7 +48,7 @@ nouveau_dri_la_SOURCES = \
+ nouveau_dri_la_LDFLAGS = -module -avoid-version -shared -no-undefined
+ 
+ nouveau_dri_la_LIBADD = \
+-	$(top_builddir)/src/mesa/libmesagallium.la \
++	@MESAGALLIUM_LIBS@ \
+ 	$(top_builddir)/src/gallium/auxiliary/libgallium.la \
+ 	$(top_builddir)/src/gallium/state_trackers/dri/drm/libdridrm.la \
+ 	$(top_builddir)/src/gallium/winsys/nouveau/drm/libnouveaudrm.la \
+diff --git a/src/gallium/targets/dri-r300/Makefile.am b/src/gallium/targets/dri-r300/Makefile.am
+index 8c0215d..6beb536 100644
+--- a/src/gallium/targets/dri-r300/Makefile.am
++++ b/src/gallium/targets/dri-r300/Makefile.am
+@@ -49,7 +49,7 @@ r300_dri_la_SOURCES = \
+ r300_dri_la_LDFLAGS = -module -avoid-version -shared -no-undefined
+ 
+ r300_dri_la_LIBADD = \
+-	$(top_builddir)/src/mesa/libmesagallium.la \
++	@MESAGALLIUM_LIBS@ \
+ 	$(top_builddir)/src/gallium/auxiliary/libgallium.la \
+ 	$(top_builddir)/src/gallium/state_trackers/dri/drm/libdridrm.la \
+ 	$(top_builddir)/src/gallium/winsys/radeon/drm/libradeonwinsys.la \
+diff --git a/src/gallium/targets/dri-r600/Makefile.am b/src/gallium/targets/dri-r600/Makefile.am
+index 2b3524b..d40fb89 100644
+--- a/src/gallium/targets/dri-r600/Makefile.am
++++ b/src/gallium/targets/dri-r600/Makefile.am
+@@ -48,7 +48,7 @@ r600_dri_la_SOURCES = \
+ r600_dri_la_LDFLAGS = -module -avoid-version -shared -no-undefined
+ 
+ r600_dri_la_LIBADD = \
+-	$(top_builddir)/src/mesa/libmesagallium.la \
++	@MESAGALLIUM_LIBS@ \
+ 	$(top_builddir)/src/gallium/auxiliary/libgallium.la \
+ 	$(top_builddir)/src/gallium/drivers/r600/libr600.la \
+ 	$(top_builddir)/src/gallium/state_trackers/dri/drm/libdridrm.la \
+diff --git a/src/gallium/targets/dri-radeonsi/Makefile.am b/src/gallium/targets/dri-radeonsi/Makefile.am
+index f7d87a6..87ab2aa 100644
+--- a/src/gallium/targets/dri-radeonsi/Makefile.am
++++ b/src/gallium/targets/dri-radeonsi/Makefile.am
+@@ -49,7 +49,7 @@ radeonsi_dri_la_SOURCES = \
+ radeonsi_dri_la_LDFLAGS = -module -avoid-version -shared -no-undefined
+ 
+ radeonsi_dri_la_LIBADD = \
+-	$(top_builddir)/src/mesa/libmesagallium.la \
++	@MESAGALLIUM_LIBS@ \
+ 	$(top_builddir)/src/gallium/auxiliary/libgallium.la \
+ 	$(top_builddir)/src/gallium/drivers/radeonsi/libradeonsi.la \
+ 	$(top_builddir)/src/gallium/state_trackers/dri/drm/libdridrm.la \
+diff --git a/src/gallium/targets/dri-swrast/Makefile.am b/src/gallium/targets/dri-swrast/Makefile.am
+index 1104379..72d2401 100644
+--- a/src/gallium/targets/dri-swrast/Makefile.am
++++ b/src/gallium/targets/dri-swrast/Makefile.am
+@@ -49,7 +49,7 @@ swrast_dri_la_SOURCES = \
+ swrast_dri_la_LDFLAGS = -module -avoid-version -shared -no-undefined
+ 
+ swrast_dri_la_LIBADD = \
+-	$(top_builddir)/src/mesa/libmesagallium.la \
++	@MESAGALLIUM_LIBS@ \
+ 	$(top_builddir)/src/gallium/auxiliary/libgallium.la \
+ 	$(top_builddir)/src/gallium/state_trackers/dri/sw/libdrisw.la \
+ 	$(top_builddir)/src/gallium/winsys/sw/dri/libswdri.la \
+diff --git a/src/gallium/targets/dri-vmwgfx/Makefile.am b/src/gallium/targets/dri-vmwgfx/Makefile.am
+index ca7df65..4384976 100644
+--- a/src/gallium/targets/dri-vmwgfx/Makefile.am
++++ b/src/gallium/targets/dri-vmwgfx/Makefile.am
+@@ -48,7 +48,7 @@ vmwgfx_dri_la_SOURCES = \
+ vmwgfx_dri_la_LDFLAGS = -module -avoid-version -shared -no-undefined
+ 
+ vmwgfx_dri_la_LIBADD = \
+-	$(top_builddir)/src/mesa/libmesagallium.la \
++	@MESAGALLIUM_LIBS@ \
+ 	$(top_builddir)/src/gallium/auxiliary/libgallium.la \
+ 	$(top_builddir)/src/gallium/state_trackers/dri/drm/libdridrm.la \
+ 	$(top_builddir)/src/gallium/winsys/svga/drm/libsvgadrm.la \
+diff --git a/src/gallium/targets/egl-static/Makefile.am b/src/gallium/targets/egl-static/Makefile.am
+index 5c40ae8..6922ab2 100644
+--- a/src/gallium/targets/egl-static/Makefile.am
++++ b/src/gallium/targets/egl-static/Makefile.am
+@@ -104,7 +104,7 @@ AM_CPPFLAGS += \
+ 	$(API_DEFINES)
+ 
+ egl_gallium_la_LIBADD += \
+-	$(top_builddir)/src/mesa/libmesagallium.la
++	@MESAGALLIUM_LIBS@
+ # make st/mesa built-in when there is a single glapi provider
+ if HAVE_SHARED_GLAPI
+ egl_gallium_la_LIBADD += \
+diff --git a/src/mesa/Makefile.am b/src/mesa/Makefile.am
+index 41483dd..0045a673 100644
+--- a/src/mesa/Makefile.am
++++ b/src/mesa/Makefile.am
+@@ -75,9 +75,6 @@ noinst_LTLIBRARIES += libmesa.la
+ else
+ check_LTLIBRARIES = libmesa.la
+ endif
+-if HAVE_GALLIUM
+-noinst_LTLIBRARIES += libmesagallium.la
+-endif
+ 
+ SRCDIR = $(top_srcdir)/src/mesa/
+ BUILDDIR = $(top_builddir)/src/mesa/
+@@ -119,15 +116,6 @@ libmesa_la_LIBADD = \
+         $()
+ libmesa_la_LDFLAGS =
+ 
+-libmesagallium_la_SOURCES = \
+-	$(MESA_GALLIUM_FILES) \
+-        $(MESA_ASM_FILES_FOR_ARCH)
+-
+-libmesagallium_la_LIBADD = \
+-        $(top_builddir)/src/glsl/libglsl.la \
+-        $(top_builddir)/src/mesa/program/libprogram.la \
+-        $()
+-
+ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = gl.pc
+ 
+diff --git a/src/mesa/libdricore/Makefile.am b/src/mesa/libdricore/Makefile.am
+index 753548e..8761418 100644
+--- a/src/mesa/libdricore/Makefile.am
++++ b/src/mesa/libdricore/Makefile.am
+@@ -42,6 +42,7 @@ libdricore@VERSION@_la_SOURCES = \
+ libdricore@VERSION@_la_LDFLAGS = -version-number 1:0
+ libdricore@VERSION@_la_LIBADD = \
+         ../program/libdricore_program.la \
++        $(top_builddir)/src/mapi/shared-glapi/libglapi.la
+         $()
+ 
+ if HAVE_X86_ASM
+@@ -65,8 +66,10 @@ AM_CPPFLAGS += \
+         -I$(top_srcdir)/src/mesa/sparc
+ endif
+ 
++lib_LTLIBRARIES =
++
+ if HAVE_DRI
+-lib_LTLIBRARIES = libdricore@VERSION@.la
++lib_LTLIBRARIES += libdricore@VERSION@.la
+ 
+ # Provide compatibility with scripts for the old Mesa build system for
+ # a while by putting a link to the driver into /lib of the build tree.
+@@ -76,6 +79,17 @@ all-local: libdricore@VERSION@.la
+ 	ln -sf libdricore@VERSION@.so.1 $(top_builddir)/$(LIB_DIR)/libdricore@VERSION@.so
+ endif
+ 
++libmesagallium_la_SOURCES = \
++	$(STATETRACKER_FILES)
++libmesagallium_la_CFLAGS = @LLVM_CFLAGS@
++libmesagallium_la_CXXFLAGS = @LLVM_CXXFLAGS@
++libmesagallium_la_LIBADD = libdricore@VERSION@.la $(LLVM_LIBS)
++
++if HAVE_GALLIUM
++noinst_LTLIBRARIES = libmesagallium.la
++endif
++
++
+ CLEANFILES = \
+ 	$(top_builddir)/$(LIB_DIR)/libdricore@VERSION@.so.1 \
+ 	$(top_builddir)/$(LIB_DIR)/libdricore@VERSION@.so
diff --git a/pkgs/development/libraries/mesa/fix-rounding.patch b/pkgs/development/libraries/mesa/fix-rounding.patch
new file mode 100644
index 00000000000..f81760a6708
--- /dev/null
+++ b/pkgs/development/libraries/mesa/fix-rounding.patch
@@ -0,0 +1,357 @@
+From c25ae5d27b114e23d5734f846002df1a05759658 Mon Sep 17 00:00:00 2001
+From: Roland Scheidegger <sroland@vmware.com>
+Date: Thu, 31 Jan 2013 19:27:49 +0000
+Subject: gallivm: fix issues with trunc/round/floor/ceil with no arch rounding
+
+The emulation of these if there's no rounding instruction available
+is a bit more complicated than what the code did.
+In particular, doing fp-to-int/int-to-fp will not work if the exponent
+is large enough (and with NaNs, Infs). Hence such values need to be filtered
+out and the original value returned in this case (which fortunately should
+always be exact). This comes at the expense of performance (if your cpu
+doesn't support rounding instructions).
+Furthermore, floor/ifloor/ceil/iceil were affected by precision issues for
+values near negative (for floor) or positive (for ceil) zero, fix that as well
+(fixing this issue might not actually be slower except for ceil/iceil if the
+type is not signed which is probably rare - note iceil has no callers left
+in any case).
+
+Also add some new rounding test values in lp_test_arit to actually test
+for that stuff (which previously would have failed without sse41).
+
+This fixes https://bugs.freedesktop.org/show_bug.cgi?id=59701.
+---
+diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+index b4e9f23..ec05026 100644
+--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
++++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+@@ -1590,12 +1590,37 @@ lp_build_trunc(struct lp_build_context *bld,
+       return lp_build_round_arch(bld, a, LP_BUILD_ROUND_TRUNCATE);
+    }
+    else {
+-      LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
+-      LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->gallivm, type);
+-      LLVMValueRef res;
+-      res = LLVMBuildFPToSI(builder, a, int_vec_type, "");
+-      res = LLVMBuildSIToFP(builder, res, vec_type, "");
+-      return res;
++      const struct lp_type type = bld->type;
++      struct lp_type inttype;
++      struct lp_build_context intbld;
++      LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 2^24);
++      LLVMValueRef trunc, res, anosign, mask;
++      LLVMTypeRef int_vec_type = bld->int_vec_type;
++      LLVMTypeRef vec_type = bld->vec_type;
++
++      assert(type.width == 32); /* might want to handle doubles at some point */
++
++      inttype = type;
++      inttype.floating = 0;
++      lp_build_context_init(&intbld, bld->gallivm, inttype);
++
++      /* round by truncation */
++      trunc = LLVMBuildFPToSI(builder, a, int_vec_type, "");
++      res = LLVMBuildSIToFP(builder, trunc, vec_type, "floor.trunc");
++
++      /* mask out sign bit */
++      anosign = lp_build_abs(bld, a);
++      /*
++       * mask out all values if anosign > 2^24
++       * This should work both for large ints (all rounding is no-op for them
++       * because such floats are always exact) as well as special cases like
++       * NaNs, Infs (taking advantage of the fact they use max exponent).
++       * (2^24 is arbitrary anything between 2^24 and 2^31 should work.)
++       */
++      anosign = LLVMBuildBitCast(builder, anosign, int_vec_type, "");
++      cmpval = LLVMBuildBitCast(builder, cmpval, int_vec_type, "");
++      mask = lp_build_cmp(&intbld, PIPE_FUNC_GREATER, anosign, cmpval);
++      return lp_build_select(bld, mask, a, res);
+    }
+ }
+ 
+@@ -1620,11 +1645,36 @@ lp_build_round(struct lp_build_context *bld,
+       return lp_build_round_arch(bld, a, LP_BUILD_ROUND_NEAREST);
+    }
+    else {
+-      LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
+-      LLVMValueRef res;
++      const struct lp_type type = bld->type;
++      struct lp_type inttype;
++      struct lp_build_context intbld;
++      LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 2^24);
++      LLVMValueRef res, anosign, mask;
++      LLVMTypeRef int_vec_type = bld->int_vec_type;
++      LLVMTypeRef vec_type = bld->vec_type;
++
++      assert(type.width == 32); /* might want to handle doubles at some point */
++
++      inttype = type;
++      inttype.floating = 0;
++      lp_build_context_init(&intbld, bld->gallivm, inttype);
++
+       res = lp_build_iround(bld, a);
+       res = LLVMBuildSIToFP(builder, res, vec_type, "");
+-      return res;
++
++      /* mask out sign bit */
++      anosign = lp_build_abs(bld, a);
++      /*
++       * mask out all values if anosign > 2^24
++       * This should work both for large ints (all rounding is no-op for them
++       * because such floats are always exact) as well as special cases like
++       * NaNs, Infs (taking advantage of the fact they use max exponent).
++       * (2^24 is arbitrary anything between 2^24 and 2^31 should work.)
++       */
++      anosign = LLVMBuildBitCast(builder, anosign, int_vec_type, "");
++      cmpval = LLVMBuildBitCast(builder, cmpval, int_vec_type, "");
++      mask = lp_build_cmp(&intbld, PIPE_FUNC_GREATER, anosign, cmpval);
++      return lp_build_select(bld, mask, a, res);
+    }
+ }
+ 
+@@ -1648,11 +1698,52 @@ lp_build_floor(struct lp_build_context *bld,
+       return lp_build_round_arch(bld, a, LP_BUILD_ROUND_FLOOR);
+    }
+    else {
+-      LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
+-      LLVMValueRef res;
+-      res = lp_build_ifloor(bld, a);
+-      res = LLVMBuildSIToFP(builder, res, vec_type, "");
+-      return res;
++      const struct lp_type type = bld->type;
++      struct lp_type inttype;
++      struct lp_build_context intbld;
++      LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 2^24);
++      LLVMValueRef trunc, res, anosign, mask;
++      LLVMTypeRef int_vec_type = bld->int_vec_type;
++      LLVMTypeRef vec_type = bld->vec_type;
++
++      assert(type.width == 32); /* might want to handle doubles at some point */
++
++      inttype = type;
++      inttype.floating = 0;
++      lp_build_context_init(&intbld, bld->gallivm, inttype);
++
++      /* round by truncation */
++      trunc = LLVMBuildFPToSI(builder, a, int_vec_type, "");
++      res = LLVMBuildSIToFP(builder, trunc, vec_type, "floor.trunc");
++
++      if (type.sign) {
++         LLVMValueRef tmp;
++
++         /*
++          * fix values if rounding is wrong (for non-special cases)
++          * - this is the case if trunc > a
++          */
++         mask = lp_build_cmp(bld, PIPE_FUNC_GREATER, res, a);
++         /* tmp = trunc > a ? 1.0 : 0.0 */
++         tmp = LLVMBuildBitCast(builder, bld->one, int_vec_type, "");
++         tmp = lp_build_and(&intbld, mask, tmp);
++         tmp = LLVMBuildBitCast(builder, tmp, vec_type, "");
++         res = lp_build_sub(bld, res, tmp);
++      }
++
++      /* mask out sign bit */
++      anosign = lp_build_abs(bld, a);
++      /*
++       * mask out all values if anosign > 2^24
++       * This should work both for large ints (all rounding is no-op for them
++       * because such floats are always exact) as well as special cases like
++       * NaNs, Infs (taking advantage of the fact they use max exponent).
++       * (2^24 is arbitrary anything between 2^24 and 2^31 should work.)
++       */
++      anosign = LLVMBuildBitCast(builder, anosign, int_vec_type, "");
++      cmpval = LLVMBuildBitCast(builder, cmpval, int_vec_type, "");
++      mask = lp_build_cmp(&intbld, PIPE_FUNC_GREATER, anosign, cmpval);
++      return lp_build_select(bld, mask, a, res);
+    }
+ }
+ 
+@@ -1676,11 +1767,48 @@ lp_build_ceil(struct lp_build_context *bld,
+       return lp_build_round_arch(bld, a, LP_BUILD_ROUND_CEIL);
+    }
+    else {
+-      LLVMTypeRef vec_type = lp_build_vec_type(bld->gallivm, type);
+-      LLVMValueRef res;
+-      res = lp_build_iceil(bld, a);
+-      res = LLVMBuildSIToFP(builder, res, vec_type, "");
+-      return res;
++      const struct lp_type type = bld->type;
++      struct lp_type inttype;
++      struct lp_build_context intbld;
++      LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 2^24);
++      LLVMValueRef trunc, res, anosign, mask, tmp;
++      LLVMTypeRef int_vec_type = bld->int_vec_type;
++      LLVMTypeRef vec_type = bld->vec_type;
++
++      assert(type.width == 32); /* might want to handle doubles at some point */
++
++      inttype = type;
++      inttype.floating = 0;
++      lp_build_context_init(&intbld, bld->gallivm, inttype);
++
++      /* round by truncation */
++      trunc = LLVMBuildFPToSI(builder, a, int_vec_type, "");
++      trunc = LLVMBuildSIToFP(builder, trunc, vec_type, "ceil.trunc");
++
++      /*
++       * fix values if rounding is wrong (for non-special cases)
++       * - this is the case if trunc < a
++       */
++      mask = lp_build_cmp(bld, PIPE_FUNC_LESS, trunc, a);
++      /* tmp = trunc < a ? 1.0 : 0.0 */
++      tmp = LLVMBuildBitCast(builder, bld->one, int_vec_type, "");
++      tmp = lp_build_and(&intbld, mask, tmp);
++      tmp = LLVMBuildBitCast(builder, tmp, vec_type, "");
++      res = lp_build_add(bld, trunc, tmp);
++
++      /* mask out sign bit */
++      anosign = lp_build_abs(bld, a);
++      /*
++       * mask out all values if anosign > 2^24
++       * This should work both for large ints (all rounding is no-op for them
++       * because such floats are always exact) as well as special cases like
++       * NaNs, Infs (taking advantage of the fact they use max exponent).
++       * (2^24 is arbitrary anything between 2^24 and 2^31 should work.)
++       */
++      anosign = LLVMBuildBitCast(builder, anosign, int_vec_type, "");
++      cmpval = LLVMBuildBitCast(builder, cmpval, int_vec_type, "");
++      mask = lp_build_cmp(&intbld, PIPE_FUNC_GREATER, anosign, cmpval);
++      return lp_build_select(bld, mask, a, res);
+    }
+ }
+ 
+@@ -1826,32 +1954,30 @@ lp_build_ifloor(struct lp_build_context *bld,
+          res = lp_build_round_arch(bld, a, LP_BUILD_ROUND_FLOOR);
+       }
+       else {
+-         /* Take the sign bit and add it to 1 constant */
+-         LLVMTypeRef vec_type = bld->vec_type;
+-         unsigned mantissa = lp_mantissa(type);
+-         LLVMValueRef mask = lp_build_const_int_vec(bld->gallivm, type,
+-                                  (unsigned long long)1 << (type.width - 1));
+-         LLVMValueRef sign;
+-         LLVMValueRef offset;
++         struct lp_type inttype;
++         struct lp_build_context intbld;
++         LLVMValueRef trunc, itrunc, mask;
+ 
+-         /* sign = a < 0 ? ~0 : 0 */
+-         sign = LLVMBuildBitCast(builder, a, int_vec_type, "");
+-         sign = LLVMBuildAnd(builder, sign, mask, "");
+-         sign = LLVMBuildAShr(builder, sign,
+-                              lp_build_const_int_vec(bld->gallivm, type,
+-                                                     type.width - 1),
+-                              "ifloor.sign");
++         assert(type.floating);
++         assert(lp_check_value(type, a));
+ 
+-         /* offset = -0.99999(9)f */
+-         offset = lp_build_const_vec(bld->gallivm, type,
+-                                     -(double)(((unsigned long long)1 << mantissa) - 10)/((unsigned long long)1 << mantissa));
+-         offset = LLVMConstBitCast(offset, int_vec_type);
++         inttype = type;
++         inttype.floating = 0;
++         lp_build_context_init(&intbld, bld->gallivm, inttype);
+ 
+-         /* offset = a < 0 ? offset : 0.0f */
+-         offset = LLVMBuildAnd(builder, offset, sign, "");
+-         offset = LLVMBuildBitCast(builder, offset, vec_type, "ifloor.offset");
++         /* round by truncation */
++         itrunc = LLVMBuildFPToSI(builder, a, int_vec_type, "");
++         trunc = LLVMBuildSIToFP(builder, itrunc, bld->vec_type, "ifloor.trunc");
+ 
+-         res = LLVMBuildFAdd(builder, res, offset, "ifloor.res");
++         /*
++          * fix values if rounding is wrong (for non-special cases)
++          * - this is the case if trunc > a
++          * The results of doing this with NaNs, very large values etc.
++          * are undefined but this seems to be the case anyway.
++          */
++         mask = lp_build_cmp(bld, PIPE_FUNC_GREATER, trunc, a);
++         /* cheapie minus one with mask since the mask is minus one / zero */
++         return lp_build_add(&intbld, itrunc, mask);
+       }
+    }
+ 
+@@ -1883,35 +2009,30 @@ lp_build_iceil(struct lp_build_context *bld,
+       res = lp_build_round_arch(bld, a, LP_BUILD_ROUND_CEIL);
+    }
+    else {
+-      LLVMTypeRef vec_type = bld->vec_type;
+-      unsigned mantissa = lp_mantissa(type);
+-      LLVMValueRef offset;
++      struct lp_type inttype;
++      struct lp_build_context intbld;
++      LLVMValueRef trunc, itrunc, mask;
+ 
+-      /* offset = 0.99999(9)f */
+-      offset = lp_build_const_vec(bld->gallivm, type,
+-                                  (double)(((unsigned long long)1 << mantissa) - 10)/((unsigned long long)1 << mantissa));
++      assert(type.floating);
++      assert(lp_check_value(type, a));
+ 
+-      if (type.sign) {
+-         LLVMValueRef mask = lp_build_const_int_vec(bld->gallivm, type,
+-                                (unsigned long long)1 << (type.width - 1));
+-         LLVMValueRef sign;
++      inttype = type;
++      inttype.floating = 0;
++      lp_build_context_init(&intbld, bld->gallivm, inttype);
+ 
+-         /* sign = a < 0 ? 0 : ~0 */
+-         sign = LLVMBuildBitCast(builder, a, int_vec_type, "");
+-         sign = LLVMBuildAnd(builder, sign, mask, "");
+-         sign = LLVMBuildAShr(builder, sign,
+-                              lp_build_const_int_vec(bld->gallivm, type,
+-                                                     type.width - 1),
+-                              "iceil.sign");
+-         sign = LLVMBuildNot(builder, sign, "iceil.not");
+-
+-         /* offset = a < 0 ? 0.0 : offset */
+-         offset = LLVMConstBitCast(offset, int_vec_type);
+-         offset = LLVMBuildAnd(builder, offset, sign, "");
+-         offset = LLVMBuildBitCast(builder, offset, vec_type, "iceil.offset");
+-      }
++      /* round by truncation */
++      itrunc = LLVMBuildFPToSI(builder, a, int_vec_type, "");
++      trunc = LLVMBuildSIToFP(builder, itrunc, bld->vec_type, "iceil.trunc");
+ 
+-      res = LLVMBuildFAdd(builder, a, offset, "iceil.res");
++      /*
++       * fix values if rounding is wrong (for non-special cases)
++       * - this is the case if trunc < a
++       * The results of doing this with NaNs, very large values etc.
++       * are undefined but this seems to be the case anyway.
++       */
++      mask = lp_build_cmp(bld, PIPE_FUNC_LESS, trunc, a);
++      /* cheapie plus one with mask since the mask is minus one / zero */
++      return lp_build_sub(&intbld, itrunc, mask);
+    }
+ 
+    /* round to nearest (toward zero) */
+diff --git a/src/gallium/drivers/llvmpipe/lp_test_arit.c b/src/gallium/drivers/llvmpipe/lp_test_arit.c
+index 99928b8..f14e4b3 100644
+--- a/src/gallium/drivers/llvmpipe/lp_test_arit.c
++++ b/src/gallium/drivers/llvmpipe/lp_test_arit.c
+@@ -207,6 +207,18 @@ const float round_values[] = {
+       -10.0, -1, 0.0, 12.0,
+       -1.49, -0.25, 1.25, 2.51,
+       -0.99, -0.01, 0.01, 0.99,
++      1.401298464324817e-45f, // smallest denormal
++      -1.401298464324817e-45f,
++      1.62981451e-08f,
++      -1.62981451e-08f,
++      1.62981451e15f, // large number not representable as 32bit int
++      -1.62981451e15f,
++      FLT_EPSILON,
++      -FLT_EPSILON,
++      1.0f - 0.5f*FLT_EPSILON,
++      -1.0f + FLT_EPSILON,
++      FLT_MAX,
++      -FLT_MAX
+ };
+ 
+ static float fractf(float x)
+--
+cgit v0.9.0.2-2-gbebe
diff --git a/pkgs/development/libraries/mesa/mips_wmb.patch b/pkgs/development/libraries/mesa/mips_wmb.patch
deleted file mode 100644
index 1ffa1bdd8df..00000000000
--- a/pkgs/development/libraries/mesa/mips_wmb.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-rixed told me (viric) it's the patch to apply for mesa.
-I adapted his patch for mesa 7.5 to this 7.10
-
-diff --git a/src/mesa/drivers/dri/sis/sis_context.h b/src/mesa/drivers/dri/sis/sis_context.h
-index a82a659..d8d8d9a 100644
---- a/src/mesa/drivers/dri/sis/sis_context.h
-+++ b/src/mesa/drivers/dri/sis/sis_context.h
-@@ -404,6 +404,8 @@ struct sis_context
- #define MMIO_WMB()	__asm __volatile("" : : : "memory")
- #elif defined(__ia64__)
- #define MMIO_WMB()	__asm __volatile("mf" : : : "memory")
-+#elif defined(__mips__)
-+#define MMIO_WMB()     __asm __volatile("" : : : "memory")
- #else
- #error platform needs WMB
- #endif
diff --git a/pkgs/development/libraries/mesa/static-gallium.patch b/pkgs/development/libraries/mesa/static-gallium.patch
new file mode 100644
index 00000000000..755682d9f1e
--- /dev/null
+++ b/pkgs/development/libraries/mesa/static-gallium.patch
@@ -0,0 +1,71 @@
+commit 2c910b6f186616cac8134e2a2cbe239c8351ed99
+Author: Vladimír Čunát <vcunat@gmail.com>
+Date:   Mon May 13 11:34:34 2013 +0200
+
+    117-static-gallium.patch
+    
+    Conflicts (moving of VISIBILITY_ confused the merge):
+    	src/gallium/auxiliary/Makefile.am
+
+diff --git a/configure.ac b/configure.ac
+index b9fcb0b..be89843 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -747,6 +747,19 @@ if test "x$enable_shared_glapi" = xyes; then
+ fi
+ AM_CONDITIONAL(HAVE_SHARED_GLAPI, test "x$enable_shared_glapi" = xyes)
+ 
++AC_ARG_ENABLE([shared-gallium],
++    [AS_HELP_STRING([--enable-shared-gallium],
++        [Enable shared gallium core @<:@default=yes@:>@])],
++    [enable_shared_gallium="$enableval"],
++    [enable_shared_gallium=yes])
++
++SHARED_GALLIUM="0"
++if test "x$enable_shared_gallium" = xyes; then
++    SHARED_GALLIUM="1"
++fi
++AC_SUBST([SHARED_GALLIUM])
++AM_CONDITIONAL(HAVE_SHARED_GALLIUM, test $SHARED_GALLIUM = 1)
++
+ dnl
+ dnl Driver specific build directories
+ dnl
+diff --git a/src/gallium/auxiliary/Makefile.am b/src/gallium/auxiliary/Makefile.am
+index f14279b..3cdec83 100644
+--- a/src/gallium/auxiliary/Makefile.am
++++ b/src/gallium/auxiliary/Makefile.am
+@@ -3,14 +3,19 @@ AUTOMAKE_OPTIONS = subdir-objects
+ include Makefile.sources
+ include $(top_srcdir)/src/gallium/Automake.inc
+ 
+-noinst_LTLIBRARIES = libgallium.la
+-
+ AM_CFLAGS = \
+ 	-I$(top_srcdir)/src/gallium/auxiliary/util \
+-	$(GALLIUM_CFLAGS) \
+-	$(VISIBILITY_CFLAGS)
++	$(GALLIUM_CFLAGS)
+ 
+-AM_CXXFLAGS = $(VISIBILITY_CXXFLAGS)
++AM_CXXFLAGS =
++
++if HAVE_SHARED_GALLIUM
++lib_LTLIBRARIES = libgallium.la
++else
++noinst_LTLIBRARIES = libgallium.la
++AM_CFLAGS += $(VISIBILITY_CFLAGS)
++AM_CXXFLAGS += $(VISIBILITY_CXXFLAGS)
++endif
+ 
+ libgallium_la_SOURCES = \
+ 	$(C_SOURCES) \
+@@ -29,6 +34,8 @@ if LLVM_NEEDS_FNORTTI
+ 
+ AM_CXXFLAGS += -fno-rtti
+ 
++libgallium_la_LIBADD = $(LLVM_LIBS)
++
+ endif
+ 
+ libgallium_la_SOURCES += \