diff options
Diffstat (limited to 'testing/mesa')
-rw-r--r-- | testing/mesa/LICENSE | 82 | ||||
-rw-r--r-- | testing/mesa/PKGBUILD | 342 | ||||
-rw-r--r-- | testing/mesa/gnome-shell-shader-fix.patch | 535 |
3 files changed, 959 insertions, 0 deletions
diff --git a/testing/mesa/LICENSE b/testing/mesa/LICENSE new file mode 100644 index 000000000..ae33d2709 --- /dev/null +++ b/testing/mesa/LICENSE @@ -0,0 +1,82 @@ +Disclaimer + +Mesa is a 3-D graphics library with an API which is very similar to +that of OpenGL* +To the extent that Mesa utilizes the OpenGL command syntax or state +machine, it is being used with authorization from Silicon Graphics, +Inc.(SGI). However, the author does not possess an OpenGL license +from SGI, and makes no claim that Mesa is in any way a compatible +replacement for OpenGL or associated with SGI. Those who want a +licensed implementation of OpenGL should contact a licensed +vendor. + +Please do not refer to the library as MesaGL (for legal +reasons). It's just Mesa or The Mesa 3-D graphics +library + +* OpenGL is a trademark of Silicon Graphics Incorporated. + +License / Copyright Information + +The Mesa distribution consists of several components. Different copyrights +and licenses apply to different components. For example, GLUT is copyrighted +by Mark Kilgard, some demo programs are copyrighted by SGI, some of the Mesa +device drivers are copyrighted by their authors. See below for a list of +Mesa's main components and the license for each. + +The core Mesa library is licensed according to the terms of the MIT license. +This allows integration with the XFree86, Xorg and DRI projects. + +The default Mesa license is as follows: + +Copyright (C) 1999-2007 Brian Paul 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, sublicense, +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 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 NONINFRINGEMENT. IN NO EVENT SHALL +BRIAN PAUL 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. + +Attention, Contributors + +When contributing to the Mesa project you must agree to the licensing terms +of the component to which you're contributing. +The following section lists the primary components of the Mesa distribution +and their respective licenses. + + +Mesa Component Licenses + +Component Location Primary Author License +---------------------------------------------------------------------------- +Main Mesa code src/mesa/ Brian Paul Mesa (MIT) + +Device drivers src/mesa/drivers/* See drivers See drivers + +Ext headers include/GL/glext.h SGI SGI Free B + include/GL/glxext.h + +GLUT src/glut/ Mark Kilgard Mark's copyright + +Mesa GLU library src/glu/mesa/ Brian Paul GNU-LGPL + +SGI GLU library src/glu/sgi/ SGI SGI Free B + +demo programs progs/demos/ various see source files + +X demos progs/xdemos/ Brian Paul see source files + +SGI demos progs/samples/ SGI SGI copyright + +RedBook demos progs/redbook/ SGI SGI copyright diff --git a/testing/mesa/PKGBUILD b/testing/mesa/PKGBUILD new file mode 100644 index 000000000..26997608b --- /dev/null +++ b/testing/mesa/PKGBUILD @@ -0,0 +1,342 @@ +# $Id: PKGBUILD 117470 2011-04-03 17:24:19Z ibiru $ +# Maintainer: Jan de Groot <jgc@archlinux.org> +# Maintainer: Andreas Radke <andyrtr@archlinux.org> + +pkgbase=mesa +pkgname=('mesa' 'libgl' 'libgles' 'libegl' 'ati-dri' 'intel-dri' 'unichrome-dri' 'mach64-dri' 'mga-dri' 'r128-dri' 'savage-dri' 'sis-dri' 'tdfx-dri' 'nouveau-dri') + +#_git=true +_git=false + +if [ "${_git}" = "true" ]; then + pkgver=7.10.0.git20110215 + else + pkgver=7.10.1 +fi +pkgrel=2 +arch=('i686' 'x86_64') +makedepends=('glproto>=1.4.12' 'pkgconfig' 'libdrm>=2.4.23' 'libxxf86vm>=1.1.0' 'libxdamage>=1.1.3' 'expat>=2.0.1' 'libx11>=1.3.5' 'libxt>=1.0.8' + 'gcc-libs>=4.5' 'dri2proto=2.3' 'python2' 'libxml2' 'imake') +url="http://mesa3d.sourceforge.net" +license=('custom') +source=(LICENSE) +if [ "${_git}" = "true" ]; then + # mesa git shot from 7.10 branch - see for state: http://cgit.freedesktop.org/mesa/mesa/commit/?h=7.10&id=cc1636b6db85604510f97f8a37d7fd0ecf453866 + source=(${source[@]} 'ftp://ftp.archlinux.org/other/mesa/mesa-cc1636b6db85604510f97f8a37d7fd0ecf453866.tar.bz2') + else + source=(${source[@]} "ftp://ftp.freedesktop.org/pub/mesa/${pkgver}/MesaLib-${pkgver}.tar.bz2" + gnome-shell-shader-fix.patch) +fi +md5sums=('5c65a0fe315dd347e09b1f2826a1df5a' + 'efe8da4d80c2a5d32a800770b8ce5dfa' + '3ec78f340f9387abd7a37b195e764cbf') + +build() { +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-* + autoreconf -vfi + else + cd "${srcdir}/Mesa-${pkgver}" +fi + +#backport from master to fix gnome-shell shader +#https://bugs.freedesktop.org/show_bug.cgi?id=35714 +patch -Np1 -i "${srcdir}/gnome-shell-shader-fix.patch" + +if [ "${_git}" = "true" ]; then + ./autogen.sh --prefix=/usr \ + --with-dri-driverdir=/usr/lib/xorg/modules/dri \ + --enable-gallium-radeon \ + --enable-gallium-r600 \ + --enable-gallium-nouveau \ + --enable-gallium-swrast \ + --enable-glx-tls \ + --with-driver=dri \ + --enable-xcb \ + --with-state-trackers=dri,glx \ + --disable-glut \ + --enable-gles1 \ + --enable-gles2 \ + --enable-egl \ + --disable-gallium-egl + else + ./configure --prefix=/usr \ + --with-dri-driverdir=/usr/lib/xorg/modules/dri \ + --enable-gallium-radeon \ + --enable-gallium-r600 \ + --enable-gallium-nouveau \ + --enable-gallium-swrast \ + --enable-glx-tls \ + --with-driver=dri \ + --enable-xcb \ + --with-state-trackers=dri,glx \ + --disable-glut \ + --enable-gles1 \ + --enable-gles2 \ + --enable-egl \ + --disable-gallium-egl +fi + + make +} + +package_libgl() { + depends=('libdrm>=2.4.22' 'libxxf86vm>=1.1.0' 'libxdamage>=1.1.3' 'expat>=2.0.1') + pkgdesc="Mesa 3-D graphics library and DRI software rasterizer" + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-* + else + cd "${srcdir}/Mesa-${pkgver}" +fi + install -m755 -d "${pkgdir}/usr/lib" + install -m755 -d "${pkgdir}/usr/lib/xorg/modules/extensions" + + bin/minstall lib/libGL.so* "${pkgdir}/usr/lib/" + + cd src/mesa/drivers/dri + #make -C swrast DESTDIR="${pkgdir}" install +if [ "${_git}" = "true" ]; then + make -C ${srcdir}/mesa-*/src/gallium/targets/dri-swrast DESTDIR="${pkgdir}" install + else + make -C ${srcdir}/Mesa-${pkgver}/src/gallium/targets/dri-swrast DESTDIR="${pkgdir}" install +fi + ln -s swrastg_dri.so "${pkgdir}/usr/lib/xorg/modules/dri/swrast_dri.so" + ln -s libglx.xorg "${pkgdir}/usr/lib/xorg/modules/extensions/libglx.so" + + install -m755 -d "${pkgdir}/usr/share/licenses/libgl" + install -m755 "${srcdir}/LICENSE" "${pkgdir}/usr/share/licenses/libgl/" +} + +package_libgles() { + depends=('libgl') + pkgdesc="Mesa GLES libraries and headers" + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-* + else + cd "${srcdir}/Mesa-${pkgver}" +fi + install -m755 -d "${pkgdir}/usr/lib" + install -m755 -d "${pkgdir}/usr/lib/pkgconfig" + install -m755 -d "${pkgdir}/usr/include" + install -m755 -d "${pkgdir}/usr/include/GLES" + install -m755 -d "${pkgdir}/usr/include/GLES2" + bin/minstall lib/libGLESv* "${pkgdir}/usr/lib/" + bin/minstall src/mapi/es1api/glesv1_cm.pc "${pkgdir}/usr/lib/pkgconfig/" + bin/minstall src/mapi/es2api/glesv2.pc "${pkgdir}/usr/lib/pkgconfig/" + bin/minstall include/GLES/* "${pkgdir}/usr/include/GLES/" + bin/minstall include/GLES2/* "${pkgdir}/usr/include/GLES2/" + bin/minstall include/GLES2/* "${pkgdir}/usr/include/GLES2/" + + install -m755 -d "${pkgdir}/usr/share/licenses/libgles" + install -m755 "${srcdir}/LICENSE" "${pkgdir}/usr/share/licenses/libgles/" +} + +package_libegl() { + depends=('libgl') + pkgdesc="Mesa libEGL libraries and headers" + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-* + else + cd "${srcdir}/Mesa-${pkgver}" +fi + install -m755 -d "${pkgdir}/usr/lib" + install -m755 -d "${pkgdir}/usr/lib/egl" + install -m755 -d "${pkgdir}/usr/lib/pkgconfig" + install -m755 -d "${pkgdir}/usr/include" + install -m755 -d "${pkgdir}/usr/include/" + install -m755 -d "${pkgdir}/usr/include/EGL" + install -m755 -d "${pkgdir}/usr/include/KHR" + install -m755 -d "${pkgdir}/usr/share" + install -m755 -d "${pkgdir}/usr/share/doc" + install -m755 -d "${pkgdir}/usr/share/doc/libegl" + bin/minstall lib/libEGL.so* "${pkgdir}/usr/lib/" + bin/minstall lib/egl/* "${pkgdir}/usr/lib/egl/" + bin/minstall src/egl/main/egl.pc "${pkgdir}/usr/lib/pkgconfig/" + bin/minstall include/EGL/* "${pkgdir}/usr/include/EGL/" + bin/minstall include/KHR/khrplatform.h "${pkgdir}/usr/include/KHR/" + bin/minstall docs/egl.html "${pkgdir}/usr/share/doc/libegl/" + + install -m755 -d "${pkgdir}/usr/share/licenses/libegl" + install -m755 "${srcdir}/LICENSE" "${pkgdir}/usr/share/licenses/libegl/" +} +package_mesa() { + depends=('libgl' 'libx11>=1.3.5' 'libxt>=1.0.8' 'gcc-libs>=4.5' 'dri2proto=2.3' 'libdrm>=2.4.22' 'glproto>=1.4.12') + optdepends=('opengl-man-pages: for the OpenGL API man pages') + pkgdesc="Mesa 3-D graphics libraries and include files" + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-* + else + cd "${srcdir}/Mesa-${pkgver}" +fi + make DESTDIR="${pkgdir}" install + + rm -f "${pkgdir}/usr/lib/libGL.so"* + rm -f "${pkgdir}/usr/lib/libGLESv"* + rm -f "${pkgdir}/usr/lib/libEGL"* + rm -rf "${pkgdir}/usr/lib/egl" + rm -f ${pkgdir}/usr/lib/pkgconfig/{glesv1_cm.pc,glesv2.pc,egl.pc} + rm -rf "${pkgdir}/usr/lib/xorg" + rm -f "${pkgdir}/usr/include/GL/glew.h" + rm -f "${pkgdir}/usr/include/GL/glxew.h" + rm -f "${pkgdir}/usr/include/GL/wglew.h" + rm -f "${pkgdir}/usr/include/GL/glut.h" + rm -rf ${pkgdir}/usr/include/{GLES,GLES2,EGL,KHR} + + install -m755 -d "${pkgdir}/usr/share/licenses/mesa" + install -m755 "${srcdir}/LICENSE" "${pkgdir}/usr/share/licenses/mesa/" +} + +package_ati-dri() { + depends=("libgl=${pkgver}") + pkgdesc="Mesa DRI + Gallium3D r300 drivers for AMD/ATI Radeon" + conflicts=('xf86-video-ati<6.9.0-6') + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-*/src/mesa/drivers/dri + else + cd "${srcdir}/Mesa-${pkgver}/src/mesa/drivers/dri" +fi + make -C radeon DESTDIR="${pkgdir}" install + make -C r200 DESTDIR="${pkgdir}" install + # classic mesa driver for R300 r300_dri.so + #make -C r300 DESTDIR="${pkgdir}" install <------- deprecated + # gallium3D driver for R300 r300_dri.so +if [ "${_git}" = "true" ]; then + make -C ${srcdir}/mesa-*/src/gallium/targets/dri-r300 DESTDIR="${pkgdir}" install + make -C ${srcdir}/mesa-*/src/gallium/targets/dri-r600 DESTDIR="${pkgdir}" install + else + make -C ${srcdir}/Mesa-${pkgver}/src/gallium/targets/dri-r300 DESTDIR="${pkgdir}" install + make -C ${srcdir}/Mesa-${pkgver}/src/gallium/targets/dri-r600 DESTDIR="${pkgdir}" install +fi + #make -C r600 DESTDIR="${pkgdir}" install +} + +package_intel-dri() { + depends=("libgl=${pkgver}") + pkgdesc="Mesa DRI drivers for Intel" + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-*/src/mesa/drivers/dri + else + cd "${srcdir}/Mesa-${pkgver}/src/mesa/drivers/dri" +fi + make -C i810 DESTDIR="${pkgdir}" install + make -C i915 DESTDIR="${pkgdir}" install + make -C i965 DESTDIR="${pkgdir}" install +} + +package_unichrome-dri() { + depends=("libgl=${pkgver}") + pkgdesc="Mesa DRI drivers for S3 Graphics/VIA Unichrome" + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-*/src/mesa/drivers/dri + else + cd "${srcdir}/Mesa-${pkgver}/src/mesa/drivers/dri" +fi + make -C unichrome DESTDIR="${pkgdir}" install +} + +package_mach64-dri() { + depends=("libgl=${pkgver}") + pkgdesc="Mesa DRI drivers for ATI Mach64" + conflicts=('xf86-video-mach64<6.8.2') + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-*/src/mesa/drivers/dri + else + cd "${srcdir}/Mesa-${pkgver}/src/mesa/drivers/dri" +fi + make -C mach64 DESTDIR="${pkgdir}" install +} + +package_mga-dri() { + depends=("libgl=${pkgver}") + pkgdesc="Mesa DRI drivers for Matrox" + conflicts=('xf86-video-mga<1.4.11') + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-*/src/mesa/drivers/dri + else + cd "${srcdir}/Mesa-${pkgver}/src/mesa/drivers/dri" +fi + make -C mga DESTDIR="${pkgdir}" install +} + +package_r128-dri() { + depends=("libgl=${pkgver}") + pkgdesc="Mesa DRI drivers for ATI Rage128" + conflicts=('xf86-video-r128<6.8.1') + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-*/src/mesa/drivers/dri + else + cd "${srcdir}/Mesa-${pkgver}/src/mesa/drivers/dri" +fi + make -C r128 DESTDIR="${pkgdir}" install +} + +package_savage-dri() { + depends=("libgl=${pkgver}") + pkgdesc="Mesa DRI drivers for S3 Sraphics/VIA Savage" + conflicts=('xf86-video-savage<2.3.1') + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-*/src/mesa/drivers/dri + else + cd "${srcdir}/Mesa-${pkgver}/src/mesa/drivers/dri" +fi + make -C savage DESTDIR="${pkgdir}" install +} + +package_sis-dri() { + depends=("libgl=${pkgver}") + pkgdesc="Mesa DRI drivers for SiS" + conflicts=('xf86-video-sis<0.10.2') + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-*/src/mesa/drivers/dri + else + cd "${srcdir}/Mesa-${pkgver}/src/mesa/drivers/dri" +fi + make -C sis DESTDIR="${pkgdir}" install +} + +package_tdfx-dri() { + depends=("libgl=${pkgver}") + pkgdesc="Mesa DRI drivers for 3dfx" + conflicts=('xf86-video-tdfx<1.4.3') + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-*/src/mesa/drivers/dri + else + cd "${srcdir}/Mesa-${pkgver}/src/mesa/drivers/dri" +fi + make -C tdfx DESTDIR="${pkgdir}" install +} + +package_nouveau-dri() { + depends=("libgl=${pkgver}") + pkgdesc="Mesa classic DRI + Gallium3D drivers for Nouveau" + +if [ "${_git}" = "true" ]; then + cd ${srcdir}/mesa-*/src/mesa/drivers/dri + else + cd "${srcdir}/Mesa-${pkgver}/src/mesa/drivers/dri" +fi + + # classic mesa driver for nv10 , nv20 nouveau_vieux_dri.so + make -C nouveau DESTDIR="${pkgdir}" install + + # gallium3D driver for nv30 - nv40 - nv50 nouveau_dri.so +if [ "${_git}" = "true" ]; then + make -C ${srcdir}/mesa-*/src/gallium/targets/dri-nouveau DESTDIR="${pkgdir}" install + else + make -C ${srcdir}/Mesa-${pkgver}/src/gallium/targets/dri-nouveau DESTDIR="${pkgdir}" install +fi +} + diff --git a/testing/mesa/gnome-shell-shader-fix.patch b/testing/mesa/gnome-shell-shader-fix.patch new file mode 100644 index 000000000..3b3f37591 --- /dev/null +++ b/testing/mesa/gnome-shell-shader-fix.patch @@ -0,0 +1,535 @@ +From 3f625689acd570e4f14cc2ebaa43a425d13954ff Mon Sep 17 00:00:00 2001 +From: Christoph Bumiller <e0425955@student.tuwien.ac.at> +Date: Thu, 31 Mar 2011 13:49:33 +0000 +Subject: nv50: copy regalloc fixes from nvc0 + +Should fix gnome-shell's fade shader. + +Unification of the shader backend which is supposed to remove the +code duplication is still WIP. +--- +diff --git a/src/gallium/drivers/nv50/nv50_pc.h b/src/gallium/drivers/nv50/nv50_pc.h +index e6f3815..a9a3248 100644 +--- a/src/gallium/drivers/nv50/nv50_pc.h ++++ b/src/gallium/drivers/nv50/nv50_pc.h +@@ -228,6 +228,8 @@ struct nv_ref { + ubyte flags; /* not used yet */ + }; + ++#define NV_REF_FLAG_REGALLOC_PRIV (1 << 0) ++ + struct nv_basic_block; + + struct nv_instruction { +@@ -263,6 +265,15 @@ struct nv_instruction { + ubyte quadop; + }; + ++static INLINE int ++nvi_vector_size(struct nv_instruction *nvi) ++{ ++ int i; ++ assert(nvi); ++ for (i = 0; i < 4 && nvi->def[i]; ++i); ++ return i; ++} ++ + #define CFG_EDGE_FORWARD 0 + #define CFG_EDGE_BACK 1 + #define CFG_EDGE_LOOP_ENTER 2 +diff --git a/src/gallium/drivers/nv50/nv50_pc_regalloc.c b/src/gallium/drivers/nv50/nv50_pc_regalloc.c +index 39ae366..657df2c 100644 +--- a/src/gallium/drivers/nv50/nv50_pc_regalloc.c ++++ b/src/gallium/drivers/nv50/nv50_pc_regalloc.c +@@ -32,14 +32,39 @@ + #include "util/u_simple_list.h" + + #define NUM_REGISTER_FILES 4 ++#define MAX_REGISTER_COUNT 256 + + struct register_set { + struct nv_pc *pc; + + uint32_t last[NUM_REGISTER_FILES]; +- uint32_t bits[NUM_REGISTER_FILES][8]; ++ uint32_t bits[NUM_REGISTER_FILES][(MAX_REGISTER_COUNT + 31) / 32]; + }; + ++/* using OR because a set bit means occupied/unavailable, aliasing is allowed */ ++static void ++intersect_register_sets(struct register_set *dst, ++ struct register_set *src1, struct register_set *src2) ++{ ++ int i, j; ++ ++ for (i = 0; i < NUM_REGISTER_FILES; ++i) { ++ for (j = 0; j < (MAX_REGISTER_COUNT + 31) / 32; ++j) ++ dst->bits[i][j] = src1->bits[i][j] | src2->bits[i][j]; ++ } ++} ++ ++static void ++mask_register_set(struct register_set *set, uint32_t mask, uint32_t umask) ++{ ++ int i, j; ++ ++ for (i = 0; i < NUM_REGISTER_FILES; ++i) { ++ for (j = 0; j < (MAX_REGISTER_COUNT + 31) / 32; ++j) ++ set->bits[i][j] = (set->bits[i][j] | mask) & umask; ++ } ++} ++ + struct nv_pc_pass { + struct nv_pc *pc; + +@@ -61,11 +86,15 @@ ranges_coalesce(struct nv_range *range) + } + } + ++/* @return: TRUE if @new_range can be freed (i.e. was not reused) */ + static boolean + add_range_ex(struct nv_value *val, int bgn, int end, struct nv_range *new_range) + { + struct nv_range *range, **nextp = &val->livei; + ++ if (bgn == end) /* [a, a) is invalid / empty */ ++ return TRUE; ++ + for (range = val->livei; range; range = range->next) { + if (end < range->bgn) + break; /* insert before */ +@@ -251,6 +280,8 @@ reg_occupy(struct register_set *set, struct nv_value *val) + id <<= s; + m = (1 << (1 << s)) - 1; + ++ assert(s >= 0); /* XXX: remove me */ ++ + set->bits[f][id / 32] |= m << (id % 32); + + if (set->pc->max_reg[f] < id) +@@ -286,15 +317,12 @@ join_allowed(struct nv_pc_pass *ctx, struct nv_value *a, struct nv_value *b) + if (a->join->reg.id == b->join->reg.id) + return TRUE; + +-#if 1 + /* either a or b or both have been assigned */ + + if (a->join->reg.id >= 0 && b->join->reg.id >= 0) + return FALSE; + else + if (b->join->reg.id >= 0) { +- if (a->join->reg.id >= 0) +- return FALSE; + val = a; + a = b; + b = val; +@@ -309,8 +337,6 @@ join_allowed(struct nv_pc_pass *ctx, struct nv_value *a, struct nv_value *b) + return FALSE; + } + return TRUE; +-#endif +- return FALSE; + } + + static INLINE void +@@ -336,14 +362,14 @@ do_join_values(struct nv_pc_pass *ctx, struct nv_value *a, struct nv_value *b) + assert(b->join == a->join); + } + +-static INLINE void ++static INLINE boolean + try_join_values(struct nv_pc_pass *ctx, struct nv_value *a, struct nv_value *b) + { + if (!join_allowed(ctx, a, b)) { + #ifdef NV50_RA_DEBUG_JOIN + debug_printf("cannot join %i to %i: not allowed\n", b->n, a->n); + #endif +- return; ++ return FALSE; + } + if (livei_have_overlap(a->join, b->join)) { + #ifdef NV50_RA_DEBUG_JOIN +@@ -351,10 +377,27 @@ try_join_values(struct nv_pc_pass *ctx, struct nv_value *a, struct nv_value *b) + livei_print(a); + livei_print(b); + #endif +- return; ++ return FALSE; + } + + do_join_values(ctx, a, b); ++ ++ return TRUE; ++} ++ ++static void ++join_values_nofail(struct nv_pc_pass *ctx, ++ struct nv_value *a, struct nv_value *b, boolean type_only) ++{ ++ if (type_only) { ++ assert(join_allowed(ctx, a, b)); ++ do_join_values(ctx, a, b); ++ } else { ++ boolean ok = try_join_values(ctx, a, b); ++ if (!ok) { ++ NOUVEAU_ERR("failed to coalesce values\n"); ++ } ++ } + } + + static INLINE boolean +@@ -369,20 +412,32 @@ need_new_else_block(struct nv_basic_block *b, struct nv_basic_block *p) + return (b->num_in > 1) && (n == 2); + } + ++/* Look for the @phi's operand whose definition reaches @b. */ + static int + phi_opnd_for_bb(struct nv_instruction *phi, struct nv_basic_block *b, + struct nv_basic_block *tb) + { ++ struct nv_ref *srci, *srcj; + int i, j; + +- for (j = -1, i = 0; i < 4 && phi->src[i]; ++i) { +- if (!nvbb_reachable_by(b, phi->src[i]->value->insn->bb, tb)) ++ for (j = -1, i = 0; i < 6 && phi->src[i]; ++i) { ++ srci = phi->src[i]; ++ /* if already replaced, check with original source first */ ++ if (srci->flags & NV_REF_FLAG_REGALLOC_PRIV) ++ srci = srci->value->insn->src[0]; ++ if (!nvbb_reachable_by(b, srci->value->insn->bb, NULL)) + continue; + /* NOTE: back-edges are ignored by the reachable-by check */ +- if (j < 0 || !nvbb_reachable_by(phi->src[j]->value->insn->bb, +- phi->src[i]->value->insn->bb, tb)) ++ if (j < 0 || !nvbb_reachable_by(srcj->value->insn->bb, ++ srci->value->insn->bb, NULL)) { + j = i; ++ srcj = srci; ++ } + } ++ if (j >= 0 && nvbb_reachable_by(b, phi->def[0]->insn->bb, NULL)) ++ if (!nvbb_reachable_by(srcj->value->insn->bb, ++ phi->def[0]->insn->bb, NULL)) ++ j = -1; + return j; + } + +@@ -429,16 +484,21 @@ pass_generate_phi_movs(struct nv_pc_pass *ctx, struct nv_basic_block *b) + ctx->pc->current_block = pn; + + for (i = b->phi; i && i->opcode == NV_OP_PHI; i = i->next) { +- if ((j = phi_opnd_for_bb(i, p, b)) < 0) +- continue; +- val = i->src[j]->value; +- +- if (i->src[j]->flags) { +- val = val->insn->src[0]->value; +- while (j < 4 && i->src[j]) +- ++j; +- assert(j < 4); ++ j = phi_opnd_for_bb(i, p, b); ++ ++ if (j < 0) { ++ val = i->def[0]; ++ } else { ++ val = i->src[j]->value; ++ if (i->src[j]->flags & NV_REF_FLAG_REGALLOC_PRIV) { ++ j = -1; ++ /* use original value, we already encountered & replaced it */ ++ val = val->insn->src[0]->value; ++ } + } ++ if (j < 0) /* need an additional source ? */ ++ for (j = 0; j < 5 && i->src[j] && i->src[j]->value != val; ++j); ++ assert(j < 5); + + ni = new_instruction(ctx->pc, NV_OP_MOV); + +@@ -452,7 +512,7 @@ pass_generate_phi_movs(struct nv_pc_pass *ctx, struct nv_basic_block *b) + + nv_reference(ctx->pc, &i->src[j], ni->def[0]); + +- i->src[j]->flags = 1; ++ i->src[j]->flags |= NV_REF_FLAG_REGALLOC_PRIV; + } + + if (pn != p && pn->exit) { +@@ -470,45 +530,50 @@ pass_generate_phi_movs(struct nv_pc_pass *ctx, struct nv_basic_block *b) + return 0; + } + ++#define JOIN_MASK_PHI (1 << 0) ++#define JOIN_MASK_SELECT (1 << 1) ++#define JOIN_MASK_MOV (1 << 2) ++#define JOIN_MASK_TEX (1 << 3) ++ + static int +-pass_join_values(struct nv_pc_pass *ctx, int iter) ++pass_join_values(struct nv_pc_pass *ctx, unsigned mask) + { + int c, n; + + for (n = 0; n < ctx->num_insns; ++n) { +- struct nv_instruction *i = ctx->insns[n]; ++ struct nv_instruction *nvi, *i = ctx->insns[n]; + + switch (i->opcode) { + case NV_OP_PHI: +- if (iter != 2) ++ if (!(mask & JOIN_MASK_PHI)) + break; +- for (c = 0; c < 4 && i->src[c]; ++c) +- try_join_values(ctx, i->def[0], i->src[c]->value); ++ for (c = 0; c < 5 && i->src[c]; ++c) ++ join_values_nofail(ctx, i->def[0], i->src[c]->value, FALSE); + break; + case NV_OP_MOV: +- if ((iter == 2) && i->src[0]->value->insn && +- !nv_is_vector_op(i->src[0]->value->join->insn->opcode)) ++ if (!(mask & JOIN_MASK_MOV)) ++ break; ++ nvi = i->src[0]->value->join->insn; ++ if (nvi && !nv_is_vector_op(nvi->opcode)) + try_join_values(ctx, i->def[0], i->src[0]->value); + break; + case NV_OP_SELECT: +- if (iter != 1) ++ if (!(mask & JOIN_MASK_SELECT)) + break; +- for (c = 0; c < 4 && i->src[c]; ++c) { +- assert(join_allowed(ctx, i->def[0], i->src[c]->value)); +- do_join_values(ctx, i->def[0], i->src[c]->value); +- } ++ for (c = 0; c < 5 && i->src[c]; ++c) ++ join_values_nofail(ctx, i->def[0], i->src[c]->value, TRUE); + break; + case NV_OP_TEX: + case NV_OP_TXB: + case NV_OP_TXL: + case NV_OP_TXQ: +- if (iter) ++ if (!(mask & JOIN_MASK_TEX)) + break; +- for (c = 0; c < 4; ++c) { +- if (!i->src[c]) +- break; +- do_join_values(ctx, i->def[c], i->src[c]->value); +- } ++ /* This should work without conflicts because we always generate ++ * extra MOVs for the sources of a TEX. ++ */ ++ for (c = 0; c < 4 && i->src[c]; ++c) ++ join_values_nofail(ctx, i->def[c], i->src[c]->value, TRUE); + break; + default: + break; +@@ -643,15 +708,15 @@ static void collect_live_values(struct nv_basic_block *b, const int n) + { + int i; + +- if (b->out[0]) { +- if (b->out[1]) { /* what to do about back-edges ? */ ++ if (b->out[0] && b->out_kind[0] != CFG_EDGE_FAKE) { ++ if (b->out[1] && b->out_kind[1] != CFG_EDGE_FAKE) { + for (i = 0; i < n; ++i) + b->live_set[i] = b->out[0]->live_set[i] | b->out[1]->live_set[i]; + } else { + memcpy(b->live_set, b->out[0]->live_set, n * sizeof(uint32_t)); + } + } else +- if (b->out[1]) { ++ if (b->out[1] && b->out_kind[1] != CFG_EDGE_FAKE) { + memcpy(b->live_set, b->out[1]->live_set, n * sizeof(uint32_t)); + } else { + memset(b->live_set, 0, n * sizeof(uint32_t)); +@@ -770,8 +835,8 @@ insert_ordered_tail(struct nv_value *list, struct nv_value *nval) + struct nv_value *elem; + + for (elem = list->prev; +- elem != list && elem->livei->bgn > nval->livei->bgn; +- elem = elem->prev); ++ elem != list && elem->livei->bgn > nval->livei->bgn; ++ elem = elem->prev); + /* now elem begins before or at the same time as val */ + + nval->prev = elem; +@@ -780,44 +845,49 @@ insert_ordered_tail(struct nv_value *list, struct nv_value *nval) + elem->next = nval; + } + +-static int +-pass_linear_scan(struct nv_pc_pass *ctx, int iter) ++static void ++collect_register_values(struct nv_pc_pass *ctx, struct nv_value *head, ++ boolean assigned_only) + { +- struct nv_instruction *i; +- struct register_set f, free; ++ struct nv_value *val; + int k, n; +- struct nv_value *cur, *val, *tmp[2]; +- struct nv_value active, inactive, handled, unhandled; + +- make_empty_list(&active); +- make_empty_list(&inactive); +- make_empty_list(&handled); +- make_empty_list(&unhandled); +- +- nv50_ctor_register_set(ctx->pc, &free); ++ make_empty_list(head); + +- /* joined values should have range = NULL and thus not be added; +- * also, fixed memory values won't be added because they're not +- * def'd, just used +- */ + for (n = 0; n < ctx->num_insns; ++n) { +- i = ctx->insns[n]; ++ struct nv_instruction *i = ctx->insns[n]; + ++ /* for joined values, only the representative will have livei != NULL */ + for (k = 0; k < 4; ++k) { + if (i->def[k] && i->def[k]->livei) +- insert_ordered_tail(&unhandled, i->def[k]); +- else +- if (0 && i->def[k]) +- debug_printf("skipping def'd value %i: no livei\n", i->def[k]->n); ++ if (!assigned_only || i->def[k]->reg.id >= 0) ++ insert_ordered_tail(head, i->def[k]); + } + if (i->flags_def && i->flags_def->livei) +- insert_ordered_tail(&unhandled, i->flags_def); ++ if (!assigned_only || i->flags_def->reg.id >= 0) ++ insert_ordered_tail(head, i->flags_def); + } + +- for (val = unhandled.next; val != unhandled.prev; val = val->next) { ++ for (val = head->next; val != head->prev; val = val->next) { + assert(val->join == val); + assert(val->livei->bgn <= val->next->livei->bgn); + } ++} ++ ++static int ++pass_linear_scan(struct nv_pc_pass *ctx, int iter) ++{ ++ struct register_set f, free; ++ struct nv_value *cur, *val, *tmp[2]; ++ struct nv_value active, inactive, handled, unhandled; ++ ++ make_empty_list(&active); ++ make_empty_list(&inactive); ++ make_empty_list(&handled); ++ ++ nv50_ctor_register_set(ctx->pc, &free); ++ ++ collect_register_values(ctx, &unhandled, FALSE); + + foreach_s(cur, tmp[0], &unhandled) { + remove_from_list(cur); +@@ -854,13 +924,7 @@ pass_linear_scan(struct nv_pc_pass *ctx, int iter) + reg_occupy(&f, val); + + if (cur->reg.id < 0) { +- boolean mem = FALSE; +- +- if (nv_is_vector_op(cur->insn->opcode)) +- mem = !reg_assign(&f, &cur->insn->def[0], 4); +- else +- if (iter) +- mem = !reg_assign(&f, &cur, 1); ++ boolean mem = !reg_assign(&f, &cur, 1); + + if (mem) { + NOUVEAU_ERR("out of registers\n"); +@@ -874,6 +938,67 @@ pass_linear_scan(struct nv_pc_pass *ctx, int iter) + return 0; + } + ++/* Allocate values defined by instructions such as TEX, which have to be ++ * assigned to consecutive registers. ++ * Linear scan doesn't really work here since the values can have different ++ * live intervals. ++ */ ++static int ++pass_allocate_constrained_values(struct nv_pc_pass *ctx) ++{ ++ struct nv_value regvals, *val; ++ struct nv_instruction *i; ++ struct nv_value *defs[4]; ++ struct register_set regs[4]; ++ int n, vsize, c; ++ uint32_t mask; ++ boolean mem; ++ ++ collect_register_values(ctx, ®vals, TRUE); ++ ++ for (n = 0; n < ctx->num_insns; ++n) { ++ i = ctx->insns[n]; ++ vsize = nvi_vector_size(i); ++ if (!(vsize > 1)) ++ continue; ++ assert(vsize <= 4); ++ for (c = 0; c < vsize; ++c) ++ defs[c] = i->def[c]->join; ++ ++ if (defs[0]->reg.id >= 0) { ++ for (c = 1; c < vsize; ++c) ++ assert(defs[c]->reg.id >= 0); ++ continue; ++ } ++ ++ for (c = 0; c < vsize; ++c) { ++ nv50_ctor_register_set(ctx->pc, ®s[c]); ++ ++ foreach(val, ®vals) { ++ if (val->reg.id >= 0 && livei_have_overlap(val, defs[c])) ++ reg_occupy(®s[c], val); ++ } ++ mask = 0x11111111; ++ if (vsize == 2) /* granularity is 2 and not 4 */ ++ mask |= 0x11111111 << 2; ++ mask_register_set(®s[c], 0, mask << c); ++ ++ if (defs[c]->livei) ++ insert_ordered_tail(®vals, defs[c]); ++ } ++ for (c = 1; c < vsize; ++c) ++ intersect_register_sets(®s[0], ®s[0], ®s[c]); ++ ++ mem = !reg_assign(®s[0], &defs[0], vsize); ++ ++ if (mem) { ++ NOUVEAU_ERR("out of registers\n"); ++ abort(); ++ } ++ } ++ return 0; ++} ++ + static int + nv_pc_pass1(struct nv_pc *pc, struct nv_basic_block *root) + { +@@ -923,16 +1048,16 @@ nv_pc_pass1(struct nv_pc *pc, struct nv_basic_block *root) + livei_print(&pc->values[i]); + #endif + +- ret = pass_join_values(ctx, 0); ++ ret = pass_join_values(ctx, JOIN_MASK_PHI); + if (ret) + goto out; +- ret = pass_linear_scan(ctx, 0); ++ ret = pass_join_values(ctx, JOIN_MASK_SELECT | JOIN_MASK_TEX); + if (ret) + goto out; +- ret = pass_join_values(ctx, 1); ++ ret = pass_join_values(ctx, JOIN_MASK_MOV); + if (ret) + goto out; +- ret = pass_join_values(ctx, 2); ++ ret = pass_allocate_constrained_values(ctx); + if (ret) + goto out; + ret = pass_linear_scan(ctx, 1); +-- +cgit v0.8.3-6-g21f6 |