nv30: import new driver for GeForce FX/6/7 chipsets, and Quadro variants
authorBen Skeggs <bskeggs@redhat.com>
Wed, 11 Jan 2012 11:42:07 +0000 (12:42 +0100)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 13 Apr 2012 16:56:34 +0000 (02:56 +1000)
The primary motivation for this rewrite was to have a maintainable driver
going forward, as nvfx was quite horrible in a lot of ways.

The driver is heavily based on the design of the nv50/nvc0 3d drivers we
already have, and uses the same common buffer/fence code.  It also passes
a HEAP more piglit tests than nvfx did, supports a couple more features,
and a few more to come still probably.

The CPU footprint of this driver is far far less than nvfx, and translates
into far greater framerates in a lot of applications (unless you're using
a CPU that's way way newer than the GPUs of these generations....)

Basically, we once again have a maintained driver for these chipsets \o/

Feel free to report bugs now!

45 files changed:
configure.ac
src/gallium/drivers/nouveau/nouveau_buffer.c
src/gallium/drivers/nouveau/nouveau_context.h
src/gallium/drivers/nouveau/nouveau_winsys.h
src/gallium/drivers/nv30/Android.mk [new file with mode: 0644]
src/gallium/drivers/nv30/Makefile [new file with mode: 0644]
src/gallium/drivers/nv30/Makefile.sources [new file with mode: 0644]
src/gallium/drivers/nv30/SConscript [new file with mode: 0644]
src/gallium/drivers/nv30/nv01_2d.xml.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv30-40_3d.xml.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_clear.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_context.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_context.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_draw.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_format.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_format.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_fragprog.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_fragtex.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_miptree.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_push.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_query.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_resource.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_resource.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_screen.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_screen.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_state.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_state.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_state_validate.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_texture.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_transfer.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_transfer.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_vbo.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_vertprog.c [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_vertprog.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv30_winsys.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv40_vertprog.h [new file with mode: 0644]
src/gallium/drivers/nv30/nv40_verttex.c [new file with mode: 0644]
src/gallium/drivers/nv30/nvfx_fragprog.c [new file with mode: 0644]
src/gallium/drivers/nv30/nvfx_shader.h [new file with mode: 0644]
src/gallium/drivers/nv30/nvfx_vertprog.c [new file with mode: 0644]
src/gallium/drivers/nv50/nv50_context.c
src/gallium/targets/dri-nouveau/Makefile
src/gallium/targets/vdpau-nouveau/Makefile
src/gallium/targets/xorg-nouveau/Makefile
src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c

index c9be8c7..df65ae5 100644 (file)
@@ -1917,7 +1917,7 @@ if test "x$with_gallium_drivers" != x; then
             ;;
         xnouveau)
             PKG_CHECK_MODULES([NOUVEAU], [libdrm_nouveau >= $LIBDRM_NOUVEAU_REQUIRED])
-            GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nv50 nvc0"
+            GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nv30 nv50 nvc0"
             gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau" "" "xvmc-nouveau" "vdpau-nouveau"
             ;;
         xswrast)
index 653acaa..d2d0113 100644 (file)
@@ -135,7 +135,7 @@ nouveau_buffer_upload(struct nouveau_context *nv, struct nv04_resource *buf,
    struct nouveau_bo *bounce = NULL;
    uint32_t offset;
 
-   if (size <= 192) {
+   if (size <= 192 && (nv->push_data || nv->push_cb)) {
       if (buf->base.bind & PIPE_BIND_CONSTANT_BUFFER)
          nv->push_cb(nv, buf->bo, buf->domain, buf->offset, buf->base.width0,
                      start, size / 4, (const uint32_t *)(buf->data + start));
index 4e6085f..79efd08 100644 (file)
@@ -3,12 +3,11 @@
 
 #include "pipe/p_context.h"
 
-struct nouveau_pushbuf;
-
 struct nouveau_context {
    struct pipe_context pipe;
    struct nouveau_screen *screen;
 
+   struct nouveau_client *client;
    struct nouveau_pushbuf *pushbuf;
 
    boolean vbo_dirty;
index 9fb865e..faaa524 100644 (file)
@@ -75,6 +75,9 @@ nouveau_screen_transfer_flags(unsigned pipe)
 }
 
 extern struct pipe_screen *
+nv30_screen_create(struct nouveau_device *);
+
+extern struct pipe_screen *
 nv50_screen_create(struct nouveau_device *);
 
 extern struct pipe_screen *
diff --git a/src/gallium/drivers/nv30/Android.mk b/src/gallium/drivers/nv30/Android.mk
new file mode 100644 (file)
index 0000000..fec076c
--- /dev/null
@@ -0,0 +1,37 @@
+# Mesa 3-D graphics library
+#
+# Copyright (C) 2011 Chia-I Wu <olvaffe@gmail.com>
+# Copyright (C) 2011 LunarG Inc.
+#
+# 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
+# THE AUTHORS OR COPYRIGHT HOLDERS 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# get C_SOURCES and CPP_SOURCES
+include $(LOCAL_PATH)/Makefile.sources
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(C_SOURCES) $(CPP_SOURCES)
+LOCAL_C_INCLUDES := $(DRM_TOP)
+
+LOCAL_MODULE := libmesa_pipe_nv30
+
+include $(GALLIUM_COMMON_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile
new file mode 100644 (file)
index 0000000..94d1a77
--- /dev/null
@@ -0,0 +1,15 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = nv30
+
+include Makefile.sources
+
+LIBRARY_INCLUDES = \
+       $(LIBDRM_CFLAGS)
+
+include ../../Makefile.template
+# DO NOT DELETE
+
+# FIXME: Remove when this driver is converted to automake.
+all: default
diff --git a/src/gallium/drivers/nv30/Makefile.sources b/src/gallium/drivers/nv30/Makefile.sources
new file mode 100644 (file)
index 0000000..f3d8ad5
--- /dev/null
@@ -0,0 +1,20 @@
+C_SOURCES := nv30_screen.c \
+             nv30_context.c \
+             nv30_format.c \
+             nv30_resource.c \
+             nv30_transfer.c \
+             nv30_miptree.c \
+             nv30_state.c \
+             nv30_state_validate.c \
+             nv30_texture.c \
+             nv30_fragtex.c \
+             nv40_verttex.c \
+             nv30_fragprog.c \
+             nv30_vertprog.c \
+             nv30_clear.c \
+             nv30_vbo.c \
+             nv30_push.c \
+             nv30_draw.c \
+             nv30_query.c \
+             nvfx_vertprog.c \
+             nvfx_fragprog.c
diff --git a/src/gallium/drivers/nv30/SConscript b/src/gallium/drivers/nv30/SConscript
new file mode 100644 (file)
index 0000000..3c2ff03
--- /dev/null
@@ -0,0 +1,11 @@
+Import('*')
+
+env = env.Clone()
+
+nv30 = env.ConvenienceLibrary(
+    target = 'nv30',
+    source = env.ParseSourceList('Makefile.sources',
+        ['C_SOURCES', 'CPP_SOURCES'])
+    )
+
+Export('nv30')
diff --git a/src/gallium/drivers/nv30/nv01_2d.xml.h b/src/gallium/drivers/nv30/nv01_2d.xml.h
new file mode 100644 (file)
index 0000000..afae00c
--- /dev/null
@@ -0,0 +1,1416 @@
+#ifndef _HOME_SKEGGSB_GIT_ENVYTOOLS_RNNDB_NV01_2D_XML
+#define _HOME_SKEGGSB_GIT_ENVYTOOLS_RNNDB_NV01_2D_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/skeggsb/git/envytools/rnndb/nv_objects.xml      (    794 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/copyright.xml       (   6452 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv_m2mf.xml         (   2696 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv_object.xml       (  12672 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nvchipsets.xml      (   3617 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv_defs.xml         (   4437 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv50_defs.xml       (   5468 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nvc0_m2mf.xml       (   2687 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv01_2d.xml         (  32584 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv04_dvd.xml        (   3000 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv03_3d.xml         (   5209 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv04_3d.xml         (  17759 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv_3ddefs.xml       (  16394 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv10_3d.xml         (  18437 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv20_3d.xml         (  21107 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv30-40_3d.xml      (  31987 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv50_2d.xml         (  11113 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv50_3d.xml         (  65233 bytes, from 2011-11-30 05:49:35)
+- /home/skeggsb/git/envytools/rnndb/nv50_compute.xml    (  14012 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nv84_crypt.xml      (   2071 bytes, from 2011-11-30 05:49:35)
+- /home/skeggsb/git/envytools/rnndb/nv31_mpeg.xml       (   2269 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/nvc0_3d.xml         (  52547 bytes, from 2011-11-30 05:49:35)
+- /home/skeggsb/git/envytools/rnndb/nvc0_compute.xml    (  10865 bytes, from 2011-10-22 08:01:09)
+- /home/skeggsb/git/envytools/rnndb/blob_nvc0_pcopy.xml (   4516 bytes, from 2011-10-22 08:01:09)
+
+Copyright (C) 2006-2011 by the following authors:
+- Artur Huillet <arthur.huillet@free.fr> (ahuillet)
+- Ben Skeggs (darktama, darktama_)
+- B. R. <koala_br@users.sourceforge.net> (koala_br)
+- Carlos Martin <carlosmn@users.sf.net> (carlosmn)
+- Christoph Bumiller <e0425955@student.tuwien.ac.at> (calim, chrisbmr)
+- Dawid Gajownik <gajownik@users.sf.net> (gajownik)
+- Dmitry Baryshkov
+- Dmitry Eremin-Solenikov <lumag@users.sf.net> (lumag)
+- EdB <edb_@users.sf.net> (edb_)
+- Erik Waling <erikwailing@users.sf.net> (erikwaling)
+- Francisco Jerez <currojerez@riseup.net> (curro)
+- imirkin <imirkin@users.sf.net> (imirkin)
+- jb17bsome <jb17bsome@bellsouth.net> (jb17bsome)
+- Jeremy Kolb <kjeremy@users.sf.net> (kjeremy)
+- Laurent Carlier <lordheavym@gmail.com> (lordheavy)
+- Luca Barbieri <luca@luca-barbieri.com> (lb, lb1)
+- Maarten Maathuis <madman2003@gmail.com> (stillunknown)
+- Marcin KoÅ›cielnicki <koriakin@0x04.net> (mwk, koriakin)
+- Mark Carey <mark.carey@gmail.com> (careym)
+- Matthieu Castet <matthieu.castet@parrot.com> (mat-c)
+- nvidiaman <nvidiaman@users.sf.net> (nvidiaman)
+- Patrice Mandin <patmandin@gmail.com> (pmandin, pmdata)
+- Pekka Paalanen <pq@iki.fi> (pq, ppaalanen)
+- Peter Popov <ironpeter@users.sf.net> (ironpeter)
+- Richard Hughes <hughsient@users.sf.net> (hughsient)
+- Rudi Cilibrasi <cilibrar@users.sf.net> (cilibrar)
+- Serge Martin
+- Simon Raffeiner
+- Stephane Loeuillet <leroutier@users.sf.net> (leroutier)
+- Stephane Marchesin <stephane.marchesin@gmail.com> (marcheu)
+- sturmflut <sturmflut@users.sf.net> (sturmflut)
+- Sylvain Munaut <tnt@246tNt.com>
+- Victor Stinner <victor.stinner@haypocalc.com> (haypo)
+- Wladmir van der Laan <laanwj@gmail.com> (miathan6)
+- Younes Manton <younes.m@gmail.com> (ymanton)
+
+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 (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 NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+*/
+
+
+
+#define NV01_BETA_DMA_NOTIFY                                   0x00000180
+
+#define NV01_BETA_BETA_1D31                                    0x00000300
+
+
+#define NV04_BETA4_DMA_NOTIFY                                  0x00000180
+
+#define NV04_BETA4_BETA_FACTOR                                 0x00000300
+
+
+#define NV01_CHROMA_DMA_NOTIFY                                 0x00000180
+
+#define NV01_CHROMA_COLOR_FORMAT                               0x00000300
+#define NV01_CHROMA_COLOR_FORMAT_A16R5G6B5                     0x00000001
+#define NV01_CHROMA_COLOR_FORMAT_X16A1R5G5B5                   0x00000002
+#define NV01_CHROMA_COLOR_FORMAT_A8R8G8B8                      0x00000003
+
+#define NV01_CHROMA_COLOR                                      0x00000304
+
+
+#define NV01_PATTERN_DMA_NOTIFY                                        0x00000180
+
+#define NV01_PATTERN_COLOR_FORMAT                              0x00000300
+#define NV01_PATTERN_COLOR_FORMAT_A16R5G6B5                    0x00000001
+#define NV01_PATTERN_COLOR_FORMAT_X16A1R5G5B5                  0x00000002
+#define NV01_PATTERN_COLOR_FORMAT_A8R8G8B8                     0x00000003
+
+#define NV01_PATTERN_MONOCHROME_FORMAT                         0x00000304
+#define NV01_PATTERN_MONOCHROME_FORMAT_CGA6                    0x00000001
+#define NV01_PATTERN_MONOCHROME_FORMAT_LE                      0x00000002
+
+#define NV01_PATTERN_MONOCHROME_SHAPE                          0x00000308
+#define NV01_PATTERN_MONOCHROME_SHAPE_8X8                      0x00000000
+#define NV01_PATTERN_MONOCHROME_SHAPE_64X1                     0x00000001
+#define NV01_PATTERN_MONOCHROME_SHAPE_1X64                     0x00000002
+
+#define NV04_PATTERN_PATTERN_SELECT                            0x0000030c
+#define NV04_PATTERN_PATTERN_SELECT_MONO                       0x00000001
+#define NV04_PATTERN_PATTERN_SELECT_COLOR                      0x00000002
+
+#define NV01_PATTERN_MONOCHROME_COLOR(i0)                     (0x00000310 + 0x4*(i0))
+#define NV01_PATTERN_MONOCHROME_COLOR__ESIZE                   0x00000004
+#define NV01_PATTERN_MONOCHROME_COLOR__LEN                     0x00000002
+
+#define NV01_PATTERN_MONOCHROME_PATTERN(i0)                   (0x00000318 + 0x4*(i0))
+#define NV01_PATTERN_MONOCHROME_PATTERN__ESIZE                 0x00000004
+#define NV01_PATTERN_MONOCHROME_PATTERN__LEN                   0x00000002
+
+#define NV04_PATTERN_PATTERN_Y8(i0)                           (0x00000400 + 0x4*(i0))
+#define NV04_PATTERN_PATTERN_Y8__ESIZE                         0x00000004
+#define NV04_PATTERN_PATTERN_Y8__LEN                           0x00000010
+#define NV04_PATTERN_PATTERN_Y8_Y0__MASK                       0x000000ff
+#define NV04_PATTERN_PATTERN_Y8_Y0__SHIFT                      0
+#define NV04_PATTERN_PATTERN_Y8_Y1__MASK                       0x0000ff00
+#define NV04_PATTERN_PATTERN_Y8_Y1__SHIFT                      8
+#define NV04_PATTERN_PATTERN_Y8_Y2__MASK                       0x00ff0000
+#define NV04_PATTERN_PATTERN_Y8_Y2__SHIFT                      16
+#define NV04_PATTERN_PATTERN_Y8_Y3__MASK                       0xff000000
+#define NV04_PATTERN_PATTERN_Y8_Y3__SHIFT                      24
+
+#define NV04_PATTERN_PATTERN_R5G6B5(i0)                               (0x00000500 + 0x4*(i0))
+#define NV04_PATTERN_PATTERN_R5G6B5__ESIZE                     0x00000004
+#define NV04_PATTERN_PATTERN_R5G6B5__LEN                       0x00000020
+#define NV04_PATTERN_PATTERN_R5G6B5_B0__MASK                   0x0000001f
+#define NV04_PATTERN_PATTERN_R5G6B5_B0__SHIFT                  0
+#define NV04_PATTERN_PATTERN_R5G6B5_G0__MASK                   0x000007e0
+#define NV04_PATTERN_PATTERN_R5G6B5_G0__SHIFT                  5
+#define NV04_PATTERN_PATTERN_R5G6B5_R0__MASK                   0x0000f800
+#define NV04_PATTERN_PATTERN_R5G6B5_R0__SHIFT                  11
+#define NV04_PATTERN_PATTERN_R5G6B5_B1__MASK                   0x001f0000
+#define NV04_PATTERN_PATTERN_R5G6B5_B1__SHIFT                  16
+#define NV04_PATTERN_PATTERN_R5G6B5_G1__MASK                   0x07e00000
+#define NV04_PATTERN_PATTERN_R5G6B5_G1__SHIFT                  21
+#define NV04_PATTERN_PATTERN_R5G6B5_R1__MASK                   0xf8000000
+#define NV04_PATTERN_PATTERN_R5G6B5_R1__SHIFT                  27
+
+#define NV04_PATTERN_PATTERN_X1R5G5B5(i0)                     (0x00000600 + 0x4*(i0))
+#define NV04_PATTERN_PATTERN_X1R5G5B5__ESIZE                   0x00000004
+#define NV04_PATTERN_PATTERN_X1R5G5B5__LEN                     0x00000020
+#define NV04_PATTERN_PATTERN_X1R5G5B5_B0__MASK                 0x0000001f
+#define NV04_PATTERN_PATTERN_X1R5G5B5_B0__SHIFT                        0
+#define NV04_PATTERN_PATTERN_X1R5G5B5_G0__MASK                 0x000003e0
+#define NV04_PATTERN_PATTERN_X1R5G5B5_G0__SHIFT                        5
+#define NV04_PATTERN_PATTERN_X1R5G5B5_R0__MASK                 0x00007c00
+#define NV04_PATTERN_PATTERN_X1R5G5B5_R0__SHIFT                        10
+#define NV04_PATTERN_PATTERN_X1R5G5B5_B1__MASK                 0x001f0000
+#define NV04_PATTERN_PATTERN_X1R5G5B5_B1__SHIFT                        16
+#define NV04_PATTERN_PATTERN_X1R5G5B5_G1__MASK                 0x03e00000
+#define NV04_PATTERN_PATTERN_X1R5G5B5_G1__SHIFT                        21
+#define NV04_PATTERN_PATTERN_X1R5G5B5_R1__MASK                 0x7c000000
+#define NV04_PATTERN_PATTERN_X1R5G5B5_R1__SHIFT                        26
+
+#define NV04_PATTERN_PATTERN_X8R8G8B8(i0)                     (0x00000700 + 0x4*(i0))
+#define NV04_PATTERN_PATTERN_X8R8G8B8__ESIZE                   0x00000004
+#define NV04_PATTERN_PATTERN_X8R8G8B8__LEN                     0x00000040
+#define NV04_PATTERN_PATTERN_X8R8G8B8_B__MASK                  0x000000ff
+#define NV04_PATTERN_PATTERN_X8R8G8B8_B__SHIFT                 0
+#define NV04_PATTERN_PATTERN_X8R8G8B8_G__MASK                  0x0000ff00
+#define NV04_PATTERN_PATTERN_X8R8G8B8_G__SHIFT                 8
+#define NV04_PATTERN_PATTERN_X8R8G8B8_R__MASK                  0x00ff0000
+#define NV04_PATTERN_PATTERN_X8R8G8B8_R__SHIFT                 16
+
+
+#define NV01_CLIP_DMA_NOTIFY                                   0x00000180
+
+#define NV01_CLIP_POINT                                                0x00000300
+#define NV01_CLIP_POINT_X__MASK                                        0x0000ffff
+#define NV01_CLIP_POINT_X__SHIFT                               0
+#define NV01_CLIP_POINT_Y__MASK                                        0xffff0000
+#define NV01_CLIP_POINT_Y__SHIFT                               16
+
+#define NV01_CLIP_SIZE                                         0x00000304
+#define NV01_CLIP_SIZE_W__MASK                                 0x0000ffff
+#define NV01_CLIP_SIZE_W__SHIFT                                        0
+#define NV01_CLIP_SIZE_H__MASK                                 0xffff0000
+#define NV01_CLIP_SIZE_H__SHIFT                                        16
+
+
+#define NV01_ROP_DMA_NOTIFY                                    0x00000180
+
+#define NV01_ROP_ROP                                           0x00000300
+
+
+#define NV04_SURFACE_2D_DMA_NOTIFY                             0x00000180
+
+#define NV04_SURFACE_2D_DMA_IMAGE_SOURCE                       0x00000184
+
+#define NV04_SURFACE_2D_DMA_IMAGE_DESTIN                       0x00000188
+
+
+#define NV50_SURFACE_2D_SRC_LINEAR                             0x00000200
+
+#define NV50_SURFACE_2D_SRC_TILE_MODE                          0x00000204
+
+#define NV50_SURFACE_2D_SRC_WIDTH                              0x00000208
+
+#define NV50_SURFACE_2D_SRC_HEIGHT                             0x0000020c
+
+#define NV50_SURFACE_2D_UNK0210                                        0x00000210
+
+#define NV50_SURFACE_2D_UNK0214                                        0x00000214
+
+#define NV50_SURFACE_2D_DST_LINEAR                             0x00000218
+
+#define NV50_SURFACE_2D_DST_TILE_MODE                          0x0000021c
+
+#define NV50_SURFACE_2D_DST_WIDTH                              0x00000220
+
+#define NV50_SURFACE_2D_DST_HEIGHT                             0x00000224
+
+#define NV50_SURFACE_2D_UNK0228                                        0x00000228
+
+#define NV50_SURFACE_2D_UNK022C                                        0x0000022c
+
+#define NV50_SURFACE_2D_OFFSET_SOURCE_HIGH                     0x00000230
+
+#define NV50_SURFACE_2D_OFFSET_DESTIN_HIGH                     0x00000234
+
+#define NV04_SURFACE_2D_FORMAT                                 0x00000300
+#define NV04_SURFACE_2D_FORMAT_Y8                              0x00000001
+#define NV04_SURFACE_2D_FORMAT_X1R5G5B5_Z1R5G5B5               0x00000002
+#define NV04_SURFACE_2D_FORMAT_X1R5G5B5_X1R5G5B5               0x00000003
+#define NV04_SURFACE_2D_FORMAT_R5G6B5                          0x00000004
+#define NV04_SURFACE_2D_FORMAT_Y16                             0x00000005
+#define NV04_SURFACE_2D_FORMAT_X8R8G8B8_Z8R8G8B8               0x00000006
+#define NV04_SURFACE_2D_FORMAT_X8R8G8B8_X8R8G8B8               0x00000007
+#define NV04_SURFACE_2D_FORMAT_X1A7R8G8B8_Z1A7R8G8B8           0x00000008
+#define NV04_SURFACE_2D_FORMAT_X1A7R8G8B8_X1A7R8G8B8           0x00000009
+#define NV04_SURFACE_2D_FORMAT_A8R8G8B8                                0x0000000a
+#define NV04_SURFACE_2D_FORMAT_Y32                             0x0000000b
+
+#define NV04_SURFACE_2D_PITCH                                  0x00000304
+#define NV04_SURFACE_2D_PITCH_SOURCE__MASK                     0x0000ffff
+#define NV04_SURFACE_2D_PITCH_SOURCE__SHIFT                    0
+#define NV04_SURFACE_2D_PITCH_DESTIN__MASK                     0xffff0000
+#define NV04_SURFACE_2D_PITCH_DESTIN__SHIFT                    16
+
+#define NV04_SURFACE_2D_OFFSET_SOURCE                          0x00000308
+
+#define NV04_SURFACE_2D_OFFSET_DESTIN                          0x0000030c
+
+
+#define NV04_SURFACE_SWZ_DMA_NOTIFY                            0x00000180
+
+#define NV04_SURFACE_SWZ_DMA_IMAGE                             0x00000184
+
+#define NV04_SURFACE_SWZ_FORMAT                                        0x00000300
+#define NV04_SURFACE_SWZ_FORMAT_COLOR__MASK                    0x000000ff
+#define NV04_SURFACE_SWZ_FORMAT_COLOR__SHIFT                   0
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_Y8                       0x00000001
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_X1R5G5B5_Z1R5G5B5                0x00000002
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_X1R5G5B5_X1R5G5B5                0x00000003
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_R5G6B5                   0x00000004
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_Y16                      0x00000005
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_X8R8G8B8_Z8R8G8B8                0x00000006
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_X8R8G8B8_X8R8G8B8                0x00000007
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_X1A7R8G8B8_Z1A7R8G8B8    0x00000008
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_X1A7R8G8B8_X1A7R8G8B8    0x00000009
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_A8R8G8B8                 0x0000000a
+#define NV04_SURFACE_SWZ_FORMAT_COLOR_Y32                      0x0000000b
+#define NV04_SURFACE_SWZ_FORMAT_BASE_SIZE_U__MASK              0x00ff0000
+#define NV04_SURFACE_SWZ_FORMAT_BASE_SIZE_U__SHIFT             16
+#define NV04_SURFACE_SWZ_FORMAT_BASE_SIZE_V__MASK              0xff000000
+#define NV04_SURFACE_SWZ_FORMAT_BASE_SIZE_V__SHIFT             24
+
+#define NV04_SURFACE_SWZ_OFFSET                                        0x00000304
+
+
+#define NV01_POINT_PATCH                                       0x0000010c
+
+#define NV01_POINT_DMA_NOTIFY                                  0x00000180
+
+#define NV01_POINT_CLIP                                                0x00000184
+
+#define NV01_POINT_PATTERN                                     0x00000188
+
+#define NV01_POINT_ROP                                         0x0000018c
+
+#define NV01_POINT_BETA                                                0x00000190
+
+#define NV01_POINT_SURFACE_DST                                 0x00000194
+
+#define NV01_POINT_OPERATION                                   0x000002fc
+#define NV01_POINT_OPERATION_SRCCOPY_AND                       0x00000000
+#define NV01_POINT_OPERATION_ROP_AND                           0x00000001
+#define NV01_POINT_OPERATION_BLEND_AND                         0x00000002
+#define NV01_POINT_OPERATION_SRCCOPY                           0x00000003
+#define NV01_POINT_OPERATION_SRCCOPY_PREMULT                   0x00000004
+#define NV01_POINT_OPERATION_BLEND_PREMULT                     0x00000005
+
+#define NV01_POINT_COLOR_FORMAT                                        0x00000300
+#define NV01_POINT_COLOR_FORMAT_X16A8Y8                                0x00000001
+#define NV01_POINT_COLOR_FORMAT_X24Y8                          0x00000002
+#define NV01_POINT_COLOR_FORMAT_X16A1R5G5B5                    0x00000003
+#define NV01_POINT_COLOR_FORMAT_X17R5G5B5                      0x00000004
+#define NV01_POINT_COLOR_FORMAT_A8R8G8B8                       0x00000005
+#define NV01_POINT_COLOR_FORMAT_X8R8G8B8                       0x00000006
+#define NV01_POINT_COLOR_FORMAT_A16Y16                         0x00000007
+#define NV01_POINT_COLOR_FORMAT_X16Y16                         0x00000008
+
+#define NV01_POINT_COLOR                                       0x00000304
+
+#define NV01_POINT_POINT(i0)                                  (0x00000400 + 0x4*(i0))
+#define NV01_POINT_POINT__ESIZE                                        0x00000004
+#define NV01_POINT_POINT__LEN                                  0x00000020
+#define NV01_POINT_POINT_X__MASK                               0x0000ffff
+#define NV01_POINT_POINT_X__SHIFT                              0
+#define NV01_POINT_POINT_Y__MASK                               0xffff0000
+#define NV01_POINT_POINT_Y__SHIFT                              16
+
+#define NV01_POINT_POINT32_X(i0)                              (0x00000480 + 0x8*(i0))
+#define NV01_POINT_POINT32_X__ESIZE                            0x00000008
+#define NV01_POINT_POINT32_X__LEN                              0x00000010
+
+#define NV01_POINT_POINT32_Y(i0)                              (0x00000484 + 0x8*(i0))
+#define NV01_POINT_POINT32_Y__ESIZE                            0x00000008
+#define NV01_POINT_POINT32_Y__LEN                              0x00000010
+
+#define NV01_POINT_CPOINT_COLOR(i0)                           (0x00000500 + 0x8*(i0))
+#define NV01_POINT_CPOINT_COLOR__ESIZE                         0x00000008
+#define NV01_POINT_CPOINT_COLOR__LEN                           0x00000010
+
+#define NV01_POINT_CPOINT_POINT(i0)                           (0x00000504 + 0x8*(i0))
+#define NV01_POINT_CPOINT_POINT__ESIZE                         0x00000008
+#define NV01_POINT_CPOINT_POINT__LEN                           0x00000010
+#define NV01_POINT_CPOINT_POINT_X__MASK                                0x0000ffff
+#define NV01_POINT_CPOINT_POINT_X__SHIFT                       0
+#define NV01_POINT_CPOINT_POINT_Y__MASK                                0xffff0000
+#define NV01_POINT_CPOINT_POINT_Y__SHIFT                       16
+
+
+#define NV01_LINE_PATCH                                                0x0000010c
+
+#define NV01_LINE_DMA_NOTIFY                                   0x00000180
+
+#define NV01_LINE_CLIP                                         0x00000184
+
+#define NV01_LINE_PATTERN                                      0x00000188
+
+#define NV04_LIN_PATTERN                                       0x00000188
+
+#define NV01_LINE_ROP                                          0x0000018c
+
+#define NV01_LINE_BETA                                         0x00000190
+
+#define NV01_LINE_SURFACE_DST                                  0x00000194
+
+
+#define NV04_LIN_BETA4                                         0x00000194
+
+#define NV04_LIN_SURFACE                                       0x00000198
+
+#define NV01_LINE_OPERATION                                    0x000002fc
+#define NV01_LINE_OPERATION_SRCCOPY_AND                                0x00000000
+#define NV01_LINE_OPERATION_ROP_AND                            0x00000001
+#define NV01_LINE_OPERATION_BLEND_AND                          0x00000002
+#define NV01_LINE_OPERATION_SRCCOPY                            0x00000003
+#define NV01_LINE_OPERATION_SRCCOPY_PREMULT                    0x00000004
+#define NV01_LINE_OPERATION_BLEND_PREMULT                      0x00000005
+
+#define NV01_LINE_COLOR_FORMAT                                 0x00000300
+#define NV01_LINE_COLOR_FORMAT_A16R5G6B5                       0x00000001
+#define NV01_LINE_COLOR_FORMAT_X16A1R5G5B5                     0x00000002
+#define NV01_LINE_COLOR_FORMAT_A8R8G8B8                                0x00000003
+
+#define NV01_LINE_COLOR                                                0x00000304
+
+#define NV01_LINE_LINE_POINT0(i0)                             (0x00000400 + 0x8*(i0))
+#define NV01_LINE_LINE_POINT0__ESIZE                           0x00000008
+#define NV01_LINE_LINE_POINT0__LEN                             0x00000010
+#define NV01_LINE_LINE_POINT0_X__MASK                          0x0000ffff
+#define NV01_LINE_LINE_POINT0_X__SHIFT                         0
+#define NV01_LINE_LINE_POINT0_Y__MASK                          0xffff0000
+#define NV01_LINE_LINE_POINT0_Y__SHIFT                         16
+
+#define NV01_LINE_LINE_POINT1(i0)                             (0x00000404 + 0x8*(i0))
+#define NV01_LINE_LINE_POINT1__ESIZE                           0x00000008
+#define NV01_LINE_LINE_POINT1__LEN                             0x00000010
+#define NV01_LINE_LINE_POINT1_X__MASK                          0x0000ffff
+#define NV01_LINE_LINE_POINT1_X__SHIFT                         0
+#define NV01_LINE_LINE_POINT1_Y__MASK                          0xffff0000
+#define NV01_LINE_LINE_POINT1_Y__SHIFT                         16
+
+#define NV01_LINE_LINE32_POINT0_X(i0)                         (0x00000480 + 0x10*(i0))
+#define NV01_LINE_LINE32_POINT0_X__ESIZE                       0x00000010
+#define NV01_LINE_LINE32_POINT0_X__LEN                         0x00000008
+
+#define NV01_LINE_LINE32_POINT0_Y(i0)                         (0x00000484 + 0x10*(i0))
+#define NV01_LINE_LINE32_POINT0_Y__ESIZE                       0x00000010
+#define NV01_LINE_LINE32_POINT0_Y__LEN                         0x00000008
+
+#define NV01_LINE_LINE32_POINT1_X(i0)                         (0x00000488 + 0x10*(i0))
+#define NV01_LINE_LINE32_POINT1_X__ESIZE                       0x00000010
+#define NV01_LINE_LINE32_POINT1_X__LEN                         0x00000008
+
+#define NV01_LINE_LINE32_POINT1_Y(i0)                         (0x0000048c + 0x10*(i0))
+#define NV01_LINE_LINE32_POINT1_Y__ESIZE                       0x00000010
+#define NV01_LINE_LINE32_POINT1_Y__LEN                         0x00000008
+
+#define NV01_LINE_POLYLINE(i0)                                (0x00000500 + 0x4*(i0))
+#define NV01_LINE_POLYLINE__ESIZE                              0x00000004
+#define NV01_LINE_POLYLINE__LEN                                        0x00000020
+#define NV01_LINE_POLYLINE_X__MASK                             0x0000ffff
+#define NV01_LINE_POLYLINE_X__SHIFT                            0
+#define NV01_LINE_POLYLINE_Y__MASK                             0xffff0000
+#define NV01_LINE_POLYLINE_Y__SHIFT                            16
+
+#define NV01_LINE_POLYLINE32_POINT_X(i0)                      (0x00000580 + 0x8*(i0))
+#define NV01_LINE_POLYLINE32_POINT_X__ESIZE                    0x00000008
+#define NV01_LINE_POLYLINE32_POINT_X__LEN                      0x00000010
+
+#define NV01_LINE_POLYLINE32_POINT_Y(i0)                      (0x00000584 + 0x8*(i0))
+#define NV01_LINE_POLYLINE32_POINT_Y__ESIZE                    0x00000008
+#define NV01_LINE_POLYLINE32_POINT_Y__LEN                      0x00000010
+
+#define NV01_LINE_CPOLYLINE_COLOR(i0)                         (0x00000600 + 0x8*(i0))
+#define NV01_LINE_CPOLYLINE_COLOR__ESIZE                       0x00000008
+#define NV01_LINE_CPOLYLINE_COLOR__LEN                         0x00000010
+
+#define NV01_LINE_CPOLYLINE_POINT(i0)                         (0x00000604 + 0x8*(i0))
+#define NV01_LINE_CPOLYLINE_POINT__ESIZE                       0x00000008
+#define NV01_LINE_CPOLYLINE_POINT__LEN                         0x00000010
+#define NV01_LINE_CPOLYLINE_POINT_X__MASK                      0x0000ffff
+#define NV01_LINE_CPOLYLINE_POINT_X__SHIFT                     0
+#define NV01_LINE_CPOLYLINE_POINT_Y__MASK                      0xffff0000
+#define NV01_LINE_CPOLYLINE_POINT_Y__SHIFT                     16
+
+
+#define NV01_TRI_PATCH                                         0x0000010c
+
+#define NV01_TRI_DMA_NOTIFY                                    0x00000180
+
+#define NV01_TRI_CLIP                                          0x00000184
+
+#define NV01_TRI_PATTERN                                       0x00000188
+
+#define NV04_TRI_PATTERN                                       0x00000188
+
+#define NV01_TRI_ROP                                           0x0000018c
+
+#define NV01_TRI_BETA                                          0x00000190
+
+#define NV01_TRI_SURFACE_DST                                   0x00000194
+
+
+#define NV04_TRI_BETA4                                         0x00000194
+
+#define NV04_TRI_SURFACE                                       0x00000198
+
+#define NV01_TRI_OPERATION                                     0x000002fc
+#define NV01_TRI_OPERATION_SRCCOPY_AND                         0x00000000
+#define NV01_TRI_OPERATION_ROP_AND                             0x00000001
+#define NV01_TRI_OPERATION_BLEND_AND                           0x00000002
+#define NV01_TRI_OPERATION_SRCCOPY                             0x00000003
+#define NV01_TRI_OPERATION_SRCCOPY_PREMULT                     0x00000004
+#define NV01_TRI_OPERATION_BLEND_PREMULT                       0x00000005
+
+#define NV01_TRI_COLOR_FORMAT                                  0x00000300
+#define NV01_TRI_COLOR_FORMAT_A16R5G6B5                                0x00000001
+#define NV01_TRI_COLOR_FORMAT_X16A1R5G5B5                      0x00000002
+#define NV01_TRI_COLOR_FORMAT_A8R8G8B8                         0x00000003
+
+#define NV01_TRI_COLOR                                         0x00000304
+
+#define NV01_TRI_TRIANGLE_POINT0                               0x00000310
+#define NV01_TRI_TRIANGLE_POINT0_X__MASK                       0x0000ffff
+#define NV01_TRI_TRIANGLE_POINT0_X__SHIFT                      0
+#define NV01_TRI_TRIANGLE_POINT0_Y__MASK                       0xffff0000
+#define NV01_TRI_TRIANGLE_POINT0_Y__SHIFT                      16
+
+#define NV01_TRI_TRIANGLE_POINT1                               0x00000314
+#define NV01_TRI_TRIANGLE_POINT1_X__MASK                       0x0000ffff
+#define NV01_TRI_TRIANGLE_POINT1_X__SHIFT                      0
+#define NV01_TRI_TRIANGLE_POINT1_Y__MASK                       0xffff0000
+#define NV01_TRI_TRIANGLE_POINT1_Y__SHIFT                      16
+
+#define NV01_TRI_TRIANGLE_POINT2                               0x00000318
+#define NV01_TRI_TRIANGLE_POINT2_X__MASK                       0x0000ffff
+#define NV01_TRI_TRIANGLE_POINT2_X__SHIFT                      0
+#define NV01_TRI_TRIANGLE_POINT2_Y__MASK                       0xffff0000
+#define NV01_TRI_TRIANGLE_POINT2_Y__SHIFT                      16
+
+#define NV01_TRI_TRIANGLE32_POINT0_X                           0x00000320
+
+#define NV01_TRI_TRIANGLE32_POINT0_Y                           0x00000324
+
+#define NV01_TRI_TRIANGLE32_POINT1_X                           0x00000328
+
+#define NV01_TRI_TRIANGLE32_POINT1_Y                           0x0000032c
+
+#define NV01_TRI_TRIANGLE32_POINT2_X                           0x00000330
+
+#define NV01_TRI_TRIANGLE32_POINT2_Y                           0x00000334
+
+#define NV01_TRI_TRIMESH(i0)                                  (0x00000400 + 0x4*(i0))
+#define NV01_TRI_TRIMESH__ESIZE                                        0x00000004
+#define NV01_TRI_TRIMESH__LEN                                  0x00000020
+#define NV01_TRI_TRIMESH_X__MASK                               0x0000ffff
+#define NV01_TRI_TRIMESH_X__SHIFT                              0
+#define NV01_TRI_TRIMESH_Y__MASK                               0xffff0000
+#define NV01_TRI_TRIMESH_Y__SHIFT                              16
+
+#define NV01_TRI_TRIMESH32_POINT_X(i0)                        (0x00000480 + 0x8*(i0))
+#define NV01_TRI_TRIMESH32_POINT_X__ESIZE                      0x00000008
+#define NV01_TRI_TRIMESH32_POINT_X__LEN                                0x00000010
+
+#define NV01_TRI_TRIMESH32_POINT_Y(i0)                        (0x00000484 + 0x8*(i0))
+#define NV01_TRI_TRIMESH32_POINT_Y__ESIZE                      0x00000008
+#define NV01_TRI_TRIMESH32_POINT_Y__LEN                                0x00000010
+
+#define NV01_TRI_CTRIANGLE_COLOR(i0)                          (0x00000500 + 0x10*(i0))
+#define NV01_TRI_CTRIANGLE_COLOR__ESIZE                                0x00000010
+#define NV01_TRI_CTRIANGLE_COLOR__LEN                          0x00000008
+
+#define NV01_TRI_CTRIANGLE_POINT0(i0)                         (0x00000504 + 0x10*(i0))
+#define NV01_TRI_CTRIANGLE_POINT0__ESIZE                       0x00000010
+#define NV01_TRI_CTRIANGLE_POINT0__LEN                         0x00000008
+#define NV01_TRI_CTRIANGLE_POINT0_X__MASK                      0x0000ffff
+#define NV01_TRI_CTRIANGLE_POINT0_X__SHIFT                     0
+#define NV01_TRI_CTRIANGLE_POINT0_Y__MASK                      0xffff0000
+#define NV01_TRI_CTRIANGLE_POINT0_Y__SHIFT                     16
+
+#define NV01_TRI_CTRIANGLE_POINT1(i0)                         (0x00000508 + 0x10*(i0))
+#define NV01_TRI_CTRIANGLE_POINT1__ESIZE                       0x00000010
+#define NV01_TRI_CTRIANGLE_POINT1__LEN                         0x00000008
+#define NV01_TRI_CTRIANGLE_POINT1_X__MASK                      0x0000ffff
+#define NV01_TRI_CTRIANGLE_POINT1_X__SHIFT                     0
+#define NV01_TRI_CTRIANGLE_POINT1_Y__MASK                      0xffff0000
+#define NV01_TRI_CTRIANGLE_POINT1_Y__SHIFT                     16
+
+#define NV01_TRI_CTRIANGLE_POINT2(i0)                         (0x0000050c + 0x10*(i0))
+#define NV01_TRI_CTRIANGLE_POINT2__ESIZE                       0x00000010
+#define NV01_TRI_CTRIANGLE_POINT2__LEN                         0x00000008
+#define NV01_TRI_CTRIANGLE_POINT2_X__MASK                      0x0000ffff
+#define NV01_TRI_CTRIANGLE_POINT2_X__SHIFT                     0
+#define NV01_TRI_CTRIANGLE_POINT2_Y__MASK                      0xffff0000
+#define NV01_TRI_CTRIANGLE_POINT2_Y__SHIFT                     16
+
+#define NV01_TRI_CTRIMESH_COLOR(i0)                           (0x00000580 + 0x8*(i0))
+#define NV01_TRI_CTRIMESH_COLOR__ESIZE                         0x00000008
+#define NV01_TRI_CTRIMESH_COLOR__LEN                           0x00000010
+
+#define NV01_TRI_CTRIMESH_POINT(i0)                           (0x00000584 + 0x8*(i0))
+#define NV01_TRI_CTRIMESH_POINT__ESIZE                         0x00000008
+#define NV01_TRI_CTRIMESH_POINT__LEN                           0x00000010
+#define NV01_TRI_CTRIMESH_POINT_X__MASK                                0x0000ffff
+#define NV01_TRI_CTRIMESH_POINT_X__SHIFT                       0
+#define NV01_TRI_CTRIMESH_POINT_Y__MASK                                0xffff0000
+#define NV01_TRI_CTRIMESH_POINT_Y__SHIFT                       16
+
+
+#define NV01_RECT_PATCH                                                0x0000010c
+
+#define NV01_RECT_DMA_NOTIFY                                   0x00000180
+
+#define NV01_RECT_CLIP                                         0x00000184
+
+#define NV01_RECT_PATTERN                                      0x00000188
+
+#define NV04_RECT_PATTERN                                      0x00000188
+
+#define NV01_RECT_ROP                                          0x0000018c
+
+#define NV01_RECT_BETA                                         0x00000190
+
+#define NV01_RECT_SURFACE_DST                                  0x00000194
+
+
+#define NV04_RECT_BETA4                                                0x00000194
+
+#define NV04_RECT_SURFACE                                      0x00000198
+
+#define NV01_RECT_OPERATION                                    0x000002fc
+#define NV01_RECT_OPERATION_SRCCOPY_AND                                0x00000000
+#define NV01_RECT_OPERATION_ROP_AND                            0x00000001
+#define NV01_RECT_OPERATION_BLEND_AND                          0x00000002
+#define NV01_RECT_OPERATION_SRCCOPY                            0x00000003
+#define NV01_RECT_OPERATION_SRCCOPY_PREMULT                    0x00000004
+#define NV01_RECT_OPERATION_BLEND_PREMULT                      0x00000005
+
+#define NV01_RECT_COLOR_FORMAT                                 0x00000300
+#define NV01_RECT_COLOR_FORMAT_A16R5G6B5                       0x00000001
+#define NV01_RECT_COLOR_FORMAT_X16A1R5G5B5                     0x00000002
+#define NV01_RECT_COLOR_FORMAT_A8R8G8B8                                0x00000003
+
+#define NV01_RECT_COLOR                                                0x00000304
+
+#define NV01_RECT_RECTANGLE_POINT(i0)                         (0x00000400 + 0x8*(i0))
+#define NV01_RECT_RECTANGLE_POINT__ESIZE                       0x00000008
+#define NV01_RECT_RECTANGLE_POINT__LEN                         0x00000010
+#define NV01_RECT_RECTANGLE_POINT_X__MASK                      0x0000ffff
+#define NV01_RECT_RECTANGLE_POINT_X__SHIFT                     0
+#define NV01_RECT_RECTANGLE_POINT_Y__MASK                      0xffff0000
+#define NV01_RECT_RECTANGLE_POINT_Y__SHIFT                     16
+
+#define NV01_RECT_RECTANGLE_SIZE(i0)                          (0x00000404 + 0x8*(i0))
+#define NV01_RECT_RECTANGLE_SIZE__ESIZE                                0x00000008
+#define NV01_RECT_RECTANGLE_SIZE__LEN                          0x00000010
+#define NV01_RECT_RECTANGLE_SIZE_W__MASK                       0x0000ffff
+#define NV01_RECT_RECTANGLE_SIZE_W__SHIFT                      0
+#define NV01_RECT_RECTANGLE_SIZE_H__MASK                       0xffff0000
+#define NV01_RECT_RECTANGLE_SIZE_H__SHIFT                      16
+
+
+#define NV01_BLIT_PATCH                                                0x0000010c
+
+
+#define NV15_BLIT_WAIT_FOR_IDLE                                        0x00000108
+
+#define NV15_BLIT_FLIP_SET_READ                                        0x00000120
+
+#define NV15_BLIT_FLIP_SET_WRITE                               0x00000124
+
+#define NV15_BLIT_FLIP_MAX                                     0x00000128
+
+#define NV15_BLIT_FLIP_INCR_WRITE                              0x0000012c
+
+#define NV15_BLIT_FLIP_WAIT                                    0x00000130
+
+#define NV15_BLIT_FLIP_CRTC_INCR_READ                          0x00000134
+
+#define NV01_BLIT_DMA_NOTIFY                                   0x00000180
+
+#define NV01_BLIT_COLOR_KEY                                    0x00000184
+
+#define NV04_BLIT_COLOR_KEY                                    0x00000184
+
+#define NV01_BLIT_CLIP                                         0x00000188
+
+#define NV01_BLIT_PATTERN                                      0x0000018c
+
+#define NV04_BLIT_PATTERN                                      0x0000018c
+
+#define NV01_BLIT_ROP                                          0x00000190
+
+#define NV01_BLIT_BETA                                         0x00000194
+
+
+#define NV01_BLIT_SURFACE_SRC                                  0x00000198
+
+#define NV01_BLIT_SURFACE_DST                                  0x0000019c
+
+
+#define NV04_BLIT_BETA4                                                0x00000198
+
+#define NV04_BLIT_SURFACES                                     0x0000019c
+
+#define NV01_BLIT_OPERATION                                    0x000002fc
+#define NV01_BLIT_OPERATION_SRCCOPY_AND                                0x00000000
+#define NV01_BLIT_OPERATION_ROP_AND                            0x00000001
+#define NV01_BLIT_OPERATION_BLEND_AND                          0x00000002
+#define NV01_BLIT_OPERATION_SRCCOPY                            0x00000003
+#define NV01_BLIT_OPERATION_SRCCOPY_PREMULT                    0x00000004
+#define NV01_BLIT_OPERATION_BLEND_PREMULT                      0x00000005
+
+#define NV01_BLIT_POINT_IN                                     0x00000300
+#define NV01_BLIT_POINT_IN_X__MASK                             0x0000ffff
+#define NV01_BLIT_POINT_IN_X__SHIFT                            0
+#define NV01_BLIT_POINT_IN_Y__MASK                             0xffff0000
+#define NV01_BLIT_POINT_IN_Y__SHIFT                            16
+
+#define NV01_BLIT_POINT_OUT                                    0x00000304
+#define NV01_BLIT_POINT_OUT_X__MASK                            0x0000ffff
+#define NV01_BLIT_POINT_OUT_X__SHIFT                           0
+#define NV01_BLIT_POINT_OUT_Y__MASK                            0xffff0000
+#define NV01_BLIT_POINT_OUT_Y__SHIFT                           16
+
+#define NV01_BLIT_SIZE                                         0x00000308
+#define NV01_BLIT_SIZE_W__MASK                                 0x0000ffff
+#define NV01_BLIT_SIZE_W__SHIFT                                        0
+#define NV01_BLIT_SIZE_H__MASK                                 0xffff0000
+#define NV01_BLIT_SIZE_H__SHIFT                                        16
+
+
+#define NV04_INDEX_PATCH                                       0x0000010c
+
+#define NV04_INDEX_DMA_NOTIFY                                  0x00000180
+
+#define NV04_INDEX_DMA_LUT                                     0x00000184
+
+#define NV04_INDEX_COLOR_KEY                                   0x00000188
+
+#define NV04_INDEX_CLIP                                                0x0000018c
+
+#define NV04_INDEX_PATTERN                                     0x00000190
+
+#define NV04_INDEX_ROP                                         0x00000194
+
+#define NV04_INDEX_BETA                                                0x00000198
+
+#define NV04_INDEX_BETA4                                       0x0000019c
+
+#define NV04_INDEX_SURFACE                                     0x000001a0
+
+#define NV05_INDEX_SURFACE                                     0x000001a0
+
+#define NV05_INDEX_COLOR_CONVERSION                            0x000003e0
+
+#define NV04_INDEX_OPERATION                                   0x000003e4
+
+#define NV04_INDEX_COLOR_FORMAT                                        0x000003e8
+
+#define NV04_INDEX_INDEX_FORMAT                                        0x000003ec
+
+#define NV04_INDEX_LUT_OFFSET                                  0x000003f0
+
+#define NV04_INDEX_POINT                                       0x000003f4
+
+#define NV04_INDEX_SIZE_OUT                                    0x000003f8
+
+#define NV04_INDEX_SIZE_IN                                     0x000003fc
+
+#define NV04_INDEX_COLOR(i0)                                  (0x00000400 + 0x4*(i0))
+#define NV04_INDEX_COLOR__ESIZE                                        0x00000004
+#define NV04_INDEX_COLOR__LEN                                  0x00000700
+
+
+#define NV10_IFC_WAIT_FOR_IDLE                                 0x00000108
+
+#define NV01_IFC_PATCH                                         0x0000010c
+
+#define NV01_IFC_DMA_NOTIFY                                    0x00000180
+
+#define NV01_IFC_COLOR_KEY                                     0x00000184
+
+#define NV04_IFC_COLOR_KEY                                     0x00000184
+
+#define NV01_IFC_CLIP                                          0x00000188
+
+#define NV01_IFC_PATTERN                                       0x0000018c
+
+#define NV04_IFC_PATTERN                                       0x0000018c
+
+#define NV01_IFC_ROP                                           0x00000190
+
+#define NV01_IFC_BETA                                          0x00000194
+
+
+#define NV01_IFC_SURFACE_DST                                   0x00000198
+
+
+#define NV04_IFC_BETA4                                         0x00000198
+
+#define NV04_IFC_SURFACE                                       0x0000019c
+
+#define NV05_IFC_COLOR_CONVERSION                              0x000002f8
+
+#define NV01_IFC_OPERATION                                     0x000002fc
+#define NV01_IFC_OPERATION_SRCCOPY_AND                         0x00000000
+#define NV01_IFC_OPERATION_ROP_AND                             0x00000001
+#define NV01_IFC_OPERATION_BLEND_AND                           0x00000002
+#define NV01_IFC_OPERATION_SRCCOPY                             0x00000003
+#define NV01_IFC_OPERATION_SRCCOPY_PREMULT                     0x00000004
+#define NV01_IFC_OPERATION_BLEND_PREMULT                       0x00000005
+
+#define NV01_IFC_COLOR_FORMAT                                  0x00000300
+#define NV01_IFC_COLOR_FORMAT_R5G6G5                           0x00000001
+#define NV01_IFC_COLOR_FORMAT_A1R5G5B5                         0x00000002
+#define NV01_IFC_COLOR_FORMAT_X1R5G5B5                         0x00000003
+#define NV01_IFC_COLOR_FORMAT_A8R8G8B8                         0x00000004
+#define NV01_IFC_COLOR_FORMAT_X8R8G8B8                         0x00000005
+
+#define NV01_IFC_POINT                                         0x00000304
+#define NV01_IFC_POINT_X__MASK                                 0x0000ffff
+#define NV01_IFC_POINT_X__SHIFT                                        0
+#define NV01_IFC_POINT_Y__MASK                                 0xffff0000
+#define NV01_IFC_POINT_Y__SHIFT                                        16
+
+#define NV01_IFC_SIZE_OUT                                      0x00000308
+#define NV01_IFC_SIZE_OUT_W__MASK                              0x0000ffff
+#define NV01_IFC_SIZE_OUT_W__SHIFT                             0
+#define NV01_IFC_SIZE_OUT_H__MASK                              0xffff0000
+#define NV01_IFC_SIZE_OUT_H__SHIFT                             16
+
+#define NV01_IFC_SIZE_IN                                       0x0000030c
+#define NV01_IFC_SIZE_IN_W__MASK                               0x0000ffff
+#define NV01_IFC_SIZE_IN_W__SHIFT                              0
+#define NV01_IFC_SIZE_IN_H__MASK                               0xffff0000
+#define NV01_IFC_SIZE_IN_H__SHIFT                              16
+
+#define NV01_IFC_COLOR(i0)                                    (0x00000400 + 0x4*(i0))
+#define NV01_IFC_COLOR__ESIZE                                  0x00000004
+#define NV01_IFC_COLOR__LEN                                    0x00000020
+
+#define NV04_IFC_COLOR(i0)                                    (0x00000400 + 0x4*(i0))
+#define NV04_IFC_COLOR__ESIZE                                  0x00000004
+#define NV04_IFC_COLOR__LEN                                    0x00000700
+
+
+#define NV03_SIFC_PATCH                                                0x0000010c
+
+#define NV03_SIFC_DMA_NOTIFY                                   0x00000180
+
+#define NV03_SIFC_COLOR_KEY                                    0x00000184
+
+#define NV04_SIFC_COLOR_KEY                                    0x00000184
+
+#define NV03_SIFC_PATTERN                                      0x00000188
+
+#define NV04_SIFC_PATTERN                                      0x00000188
+
+#define NV03_SIFC_ROP                                          0x0000018c
+
+#define NV03_SIFC_BETA                                         0x00000190
+
+
+#define NV03_SIFC_SURFACE_DST                                  0x00000194
+
+
+#define NV04_SIFC_BETA4                                                0x00000194
+
+#define NV04_SIFC_SURFACE                                      0x00000198
+
+#define NV05_SIFC_COLOR_CONVERSION                             0x000002f8
+
+#define NV03_SIFC_OPERATION                                    0x000002fc
+
+#define NV03_SIFC_COLOR_FORMAT                                 0x00000300
+
+#define NV03_SIFC_SIZE_IN                                      0x00000304
+#define NV03_SIFC_SIZE_IN_W__MASK                              0x0000ffff
+#define NV03_SIFC_SIZE_IN_W__SHIFT                             0
+#define NV03_SIFC_SIZE_IN_H__MASK                              0xffff0000
+#define NV03_SIFC_SIZE_IN_H__SHIFT                             16
+
+#define NV03_SIFC_DX_DU                                                0x00000308
+
+#define NV03_SIFC_DY_DV                                                0x0000030c
+
+#define NV03_SIFC_CLIP_POINT                                   0x00000310
+#define NV03_SIFC_CLIP_POINT_X__MASK                           0x0000ffff
+#define NV03_SIFC_CLIP_POINT_X__SHIFT                          0
+#define NV03_SIFC_CLIP_POINT_Y__MASK                           0xffff0000
+#define NV03_SIFC_CLIP_POINT_Y__SHIFT                          16
+
+#define NV03_SIFC_CLIP_SIZE                                    0x00000314
+#define NV03_SIFC_CLIP_SIZE_W__MASK                            0x0000ffff
+#define NV03_SIFC_CLIP_SIZE_W__SHIFT                           0
+#define NV03_SIFC_CLIP_SIZE_H__MASK                            0xffff0000
+#define NV03_SIFC_CLIP_SIZE_H__SHIFT                           16
+
+#define NV03_SIFC_POINT12D4                                    0x00000318
+#define NV03_SIFC_POINT12D4_X__MASK                            0x0000ffff
+#define NV03_SIFC_POINT12D4_X__SHIFT                           0
+#define NV03_SIFC_POINT12D4_Y__MASK                            0xffff0000
+#define NV03_SIFC_POINT12D4_Y__SHIFT                           16
+
+#define NV03_SIFC_COLOR(i0)                                   (0x00000400 + 0x4*(i0))
+#define NV03_SIFC_COLOR__ESIZE                                 0x00000004
+#define NV03_SIFC_COLOR__LEN                                   0x00000700
+
+
+#define NV10_SIFM_WAIT_FOR_IDLE                                        0x00000108
+
+#define NV03_SIFM_DMA_NOTIFY                                   0x00000180
+
+#define NV03_SIFM_DMA_IMAGE                                    0x00000184
+
+#define NV03_SIFM_PATTERN                                      0x00000188
+
+#define NV04_SIFM_PATTERN                                      0x00000188
+
+#define NV03_SIFM_ROP                                          0x0000018c
+
+#define NV03_SIFM_BETA                                         0x00000190
+
+
+#define NV03_SIFM_SURFACE_DST                                  0x00000194
+
+
+#define NV04_SIFM_BETA4                                                0x00000194
+
+#define NV04_SIFM_SURFACE                                      0x00000198
+
+#define NV05_SIFM_SURFACE                                      0x00000198
+
+#define NV05_SIFM_COLOR_CONVERSION                             0x000002fc
+#define NV05_SIFM_COLOR_CONVERSION_DITHER                      0x00000000
+#define NV05_SIFM_COLOR_CONVERSION_TRUNCATE                    0x00000001
+#define NV05_SIFM_COLOR_CONVERSION_SUBTR_TRUNCATE              0x00000002
+
+#define NV03_SIFM_COLOR_FORMAT                                 0x00000300
+#define NV03_SIFM_COLOR_FORMAT_A1R5G5B5                                0x00000001
+#define NV03_SIFM_COLOR_FORMAT_X1R5G5B5                                0x00000002
+#define NV03_SIFM_COLOR_FORMAT_A8R8G8B8                                0x00000003
+#define NV03_SIFM_COLOR_FORMAT_X8R8G8B8                                0x00000004
+#define NV03_SIFM_COLOR_FORMAT_V8YB8U8YA8                      0x00000005
+#define NV03_SIFM_COLOR_FORMAT_YB8V8YA8U8                      0x00000006
+#define NV03_SIFM_COLOR_FORMAT_R5G6B5                          0x00000007
+#define NV03_SIFM_COLOR_FORMAT_Y8                              0x00000008
+#define NV03_SIFM_COLOR_FORMAT_AY8                             0x00000009
+
+#define NV03_SIFM_OPERATION                                    0x00000304
+#define NV03_SIFM_OPERATION_SRCCOPY_AND                                0x00000000
+#define NV03_SIFM_OPERATION_ROP_AND                            0x00000001
+#define NV03_SIFM_OPERATION_BLEND_AND                          0x00000002
+#define NV03_SIFM_OPERATION_SRCCOPY                            0x00000003
+#define NV03_SIFM_OPERATION_SRCCOPY_PREMULT                    0x00000004
+#define NV03_SIFM_OPERATION_BLEND_PREMULT                      0x00000005
+
+#define NV03_SIFM_CLIP_POINT                                   0x00000308
+#define NV03_SIFM_CLIP_POINT_X__MASK                           0x0000ffff
+#define NV03_SIFM_CLIP_POINT_X__SHIFT                          0
+#define NV03_SIFM_CLIP_POINT_Y__MASK                           0xffff0000
+#define NV03_SIFM_CLIP_POINT_Y__SHIFT                          16
+
+#define NV03_SIFM_CLIP_SIZE                                    0x0000030c
+#define NV03_SIFM_CLIP_SIZE_W__MASK                            0x0000ffff
+#define NV03_SIFM_CLIP_SIZE_W__SHIFT                           0
+#define NV03_SIFM_CLIP_SIZE_H__MASK                            0xffff0000
+#define NV03_SIFM_CLIP_SIZE_H__SHIFT                           16
+
+#define NV03_SIFM_OUT_POINT                                    0x00000310
+#define NV03_SIFM_OUT_POINT_X__MASK                            0x0000ffff
+#define NV03_SIFM_OUT_POINT_X__SHIFT                           0
+#define NV03_SIFM_OUT_POINT_Y__MASK                            0xffff0000
+#define NV03_SIFM_OUT_POINT_Y__SHIFT                           16
+
+#define NV03_SIFM_OUT_SIZE                                     0x00000314
+#define NV03_SIFM_OUT_SIZE_W__MASK                             0x0000ffff
+#define NV03_SIFM_OUT_SIZE_W__SHIFT                            0
+#define NV03_SIFM_OUT_SIZE_H__MASK                             0xffff0000
+#define NV03_SIFM_OUT_SIZE_H__SHIFT                            16
+
+#define NV03_SIFM_DU_DX                                                0x00000318
+
+#define NV03_SIFM_DV_DY                                                0x0000031c
+
+#define NV03_SIFM_SIZE                                         0x00000400
+#define NV03_SIFM_SIZE_W__MASK                                 0x0000ffff
+#define NV03_SIFM_SIZE_W__SHIFT                                        0
+#define NV03_SIFM_SIZE_H__MASK                                 0xffff0000
+#define NV03_SIFM_SIZE_H__SHIFT                                        16
+
+#define NV03_SIFM_FORMAT                                       0x00000404
+#define NV03_SIFM_FORMAT_PITCH__MASK                           0x0000ffff
+#define NV03_SIFM_FORMAT_PITCH__SHIFT                          0
+#define NV03_SIFM_FORMAT_ORIGIN__MASK                          0x00ff0000
+#define NV03_SIFM_FORMAT_ORIGIN__SHIFT                         16
+#define NV03_SIFM_FORMAT_ORIGIN_CENTER                         0x00010000
+#define NV03_SIFM_FORMAT_ORIGIN_CORNER                         0x00020000
+#define NV03_SIFM_FORMAT_FILTER__MASK                          0xff000000
+#define NV03_SIFM_FORMAT_FILTER__SHIFT                         24
+#define NV03_SIFM_FORMAT_FILTER_POINT_SAMPLE                   0x00000000
+#define NV03_SIFM_FORMAT_FILTER_BILINEAR                       0x01000000
+
+#define NV03_SIFM_OFFSET                                       0x00000408
+
+#define NV03_SIFM_POINT                                                0x0000040c
+#define NV03_SIFM_POINT_U__MASK                                        0x0000ffff
+#define NV03_SIFM_POINT_U__SHIFT                               0
+#define NV03_SIFM_POINT_V__MASK                                        0xffff0000
+#define NV03_SIFM_POINT_V__SHIFT                               16
+
+
+#define NV50_SIFM_OFFSET_HIGH                                  0x00000410
+
+#define NV50_SIFM_SRC_LINEAR                                   0x00000414
+
+#define NV50_SIFM_SRC_TILE_MODE                                        0x00000418
+
+
+#define NV03_GDI_DMA_NOTIFY                                    0x00000180
+
+#define NV03_GDI_PATTERN                                       0x00000184
+
+#define NV03_GDI_ROP                                           0x00000188
+
+#define NV03_GDI_BETA                                          0x0000019c
+
+#define NV03_GDI_SURFACE_DST                                   0x00000190
+
+#define NV03_GDI_OPERATION                                     0x000002fc
+
+#define NV03_GDI_COLOR_FORMAT                                  0x00000300
+
+#define NV03_GDI_MONOCHROME_FORMAT                             0x00000304
+
+#define NV03_GDI_COLOR1_A                                      0x000003fc
+
+#define NV03_GDI_UNCLIPPED_RECTANGLE_POINT(i0)                (0x00000400 + 0x8*(i0))
+#define NV03_GDI_UNCLIPPED_RECTANGLE_POINT__ESIZE              0x00000008
+#define NV03_GDI_UNCLIPPED_RECTANGLE_POINT__LEN                        0x00000040
+#define NV03_GDI_UNCLIPPED_RECTANGLE_POINT_Y__MASK             0x0000ffff
+#define NV03_GDI_UNCLIPPED_RECTANGLE_POINT_Y__SHIFT            0
+#define NV03_GDI_UNCLIPPED_RECTANGLE_POINT_X__MASK             0xffff0000
+#define NV03_GDI_UNCLIPPED_RECTANGLE_POINT_X__SHIFT            16
+
+#define NV03_GDI_UNCLIPPED_RECTANGLE_SIZE(i0)                 (0x00000404 + 0x8*(i0))
+#define NV03_GDI_UNCLIPPED_RECTANGLE_SIZE__ESIZE               0x00000008
+#define NV03_GDI_UNCLIPPED_RECTANGLE_SIZE__LEN                 0x00000040
+#define NV03_GDI_UNCLIPPED_RECTANGLE_SIZE_H__MASK              0x0000ffff
+#define NV03_GDI_UNCLIPPED_RECTANGLE_SIZE_H__SHIFT             0
+#define NV03_GDI_UNCLIPPED_RECTANGLE_SIZE_W__MASK              0xffff0000
+#define NV03_GDI_UNCLIPPED_RECTANGLE_SIZE_W__SHIFT             16
+
+#define NV03_GDI_CLIP_POINT0_B                                 0x000007f4
+#define NV03_GDI_CLIP_POINT0_B_L__MASK                         0x0000ffff
+#define NV03_GDI_CLIP_POINT0_B_L__SHIFT                                0
+#define NV03_GDI_CLIP_POINT0_B_T__MASK                         0xffff0000
+#define NV03_GDI_CLIP_POINT0_B_T__SHIFT                                16
+
+#define NV03_GDI_CLIP_POINT1_B                                 0x000007f8
+#define NV03_GDI_CLIP_POINT1_B_R__MASK                         0x0000ffff
+#define NV03_GDI_CLIP_POINT1_B_R__SHIFT                                0
+#define NV03_GDI_CLIP_POINT1_B_B__MASK                         0xffff0000
+#define NV03_GDI_CLIP_POINT1_B_B__SHIFT                                16
+
+#define NV03_GDI_COLOR1_B                                      0x000007fc
+
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_0(i0)                (0x00000800 + 0x8*(i0))
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_0__ESIZE              0x00000008
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_0__LEN                        0x00000040
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_0_L__MASK             0x0000ffff
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_0_L__SHIFT            0
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_0_T__MASK             0xffff0000
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_0_T__SHIFT            16
+
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_1(i0)                (0x00000804 + 0x8*(i0))
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_1__ESIZE              0x00000008
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_1__LEN                        0x00000040
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_1_R__MASK             0x0000ffff
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_1_R__SHIFT            0
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_1_B__MASK             0xffff0000
+#define NV03_GDI_CLIPPED_RECTANGLE_POINT_1_B__SHIFT            16
+
+#define NV03_GDI_CLIP_C_POINT0                                 0x00000bec
+#define NV03_GDI_CLIP_C_POINT0_L__MASK                         0x0000ffff
+#define NV03_GDI_CLIP_C_POINT0_L__SHIFT                                0
+#define NV03_GDI_CLIP_C_POINT0_T__MASK                         0xffff0000
+#define NV03_GDI_CLIP_C_POINT0_T__SHIFT                                16
+
+#define NV03_GDI_CLIP_C_POINT1                                 0x00000bf0
+#define NV03_GDI_CLIP_C_POINT1_R__MASK                         0x0000ffff
+#define NV03_GDI_CLIP_C_POINT1_R__SHIFT                                0
+#define NV03_GDI_CLIP_C_POINT1_B__MASK                         0xffff0000
+#define NV03_GDI_CLIP_C_POINT1_B__SHIFT                                16
+
+#define NV03_GDI_COLOR1_C                                      0x00000bf4
+
+#define NV03_GDI_SIZE_C                                                0x00000bf8
+#define NV03_GDI_SIZE_C_W__MASK                                        0x0000ffff
+#define NV03_GDI_SIZE_C_W__SHIFT                               0
+#define NV03_GDI_SIZE_C_H__MASK                                        0xffff0000
+#define NV03_GDI_SIZE_C_H__SHIFT                               16
+
+#define NV03_GDI_POINT_C                                       0x00000bfc
+#define NV03_GDI_POINT_C_X__MASK                               0x0000ffff
+#define NV03_GDI_POINT_C_X__SHIFT                              0
+#define NV03_GDI_POINT_C_Y__MASK                               0xffff0000
+#define NV03_GDI_POINT_C_Y__SHIFT                              16
+
+#define NV03_GDI_MONOCHROME_COLOR1_C(i0)                      (0x00000c00 + 0x4*(i0))
+#define NV03_GDI_MONOCHROME_COLOR1_C__ESIZE                    0x00000004
+#define NV03_GDI_MONOCHROME_COLOR1_C__LEN                      0x00000080
+
+#define NV03_GDI_CLIP_D_POINT0                                 0x00000fe8
+#define NV03_GDI_CLIP_D_POINT0_L__MASK                         0x0000ffff
+#define NV03_GDI_CLIP_D_POINT0_L__SHIFT                                0
+#define NV03_GDI_CLIP_D_POINT0_T__MASK                         0xffff0000
+#define NV03_GDI_CLIP_D_POINT0_T__SHIFT                                16
+
+#define NV03_GDI_CLIP_D_POINT1                                 0x00000fec
+#define NV03_GDI_CLIP_D_POINT1_R__MASK                         0x0000ffff
+#define NV03_GDI_CLIP_D_POINT1_R__SHIFT                                0
+#define NV03_GDI_CLIP_D_POINT1_B__MASK                         0xffff0000
+#define NV03_GDI_CLIP_D_POINT1_B__SHIFT                                16
+
+#define NV03_GDI_COLOR1_D                                      0x00000ff0
+
+#define NV03_GDI_SIZE_IN_D                                     0x00000ff4
+#define NV03_GDI_SIZE_IN_D_W__MASK                             0x0000ffff
+#define NV03_GDI_SIZE_IN_D_W__SHIFT                            0
+#define NV03_GDI_SIZE_IN_D_H__MASK                             0xffff0000
+#define NV03_GDI_SIZE_IN_D_H__SHIFT                            16
+
+#define NV03_GDI_SIZE_OUT_D                                    0x00000ff8
+#define NV03_GDI_SIZE_OUT_D_W__MASK                            0x0000ffff
+#define NV03_GDI_SIZE_OUT_D_W__SHIFT                           0
+#define NV03_GDI_SIZE_OUT_D_H__MASK                            0xffff0000
+#define NV03_GDI_SIZE_OUT_D_H__SHIFT                           16
+
+#define NV03_GDI_POINT_D                                       0x00000ffc
+#define NV03_GDI_POINT_D_X__MASK                               0x0000ffff
+#define NV03_GDI_POINT_D_X__SHIFT                              0
+#define NV03_GDI_POINT_D_Y__MASK                               0xffff0000
+#define NV03_GDI_POINT_D_Y__SHIFT                              16
+
+#define NV03_GDI_MONOCHROME_COLOR1_D(i0)                      (0x00001000 + 0x4*(i0))
+#define NV03_GDI_MONOCHROME_COLOR1_D__ESIZE                    0x00000004
+#define NV03_GDI_MONOCHROME_COLOR1_D__LEN                      0x00000080
+
+#define NV03_GDI_CLIP_E_POINT0                                 0x000013e4
+#define NV03_GDI_CLIP_E_POINT0_L__MASK                         0x0000ffff
+#define NV03_GDI_CLIP_E_POINT0_L__SHIFT                                0
+#define NV03_GDI_CLIP_E_POINT0_T__MASK                         0xffff0000
+#define NV03_GDI_CLIP_E_POINT0_T__SHIFT                                16
+
+#define NV03_GDI_CLIP_E_POINT1                                 0x000013e8
+#define NV03_GDI_CLIP_E_POINT1_R__MASK                         0x0000ffff
+#define NV03_GDI_CLIP_E_POINT1_R__SHIFT                                0
+#define NV03_GDI_CLIP_E_POINT1_B__MASK                         0xffff0000
+#define NV03_GDI_CLIP_E_POINT1_B__SHIFT                                16
+
+#define NV03_GDI_COLOR0_E                                      0x000013ec
+
+#define NV03_GDI_COLOR1_E                                      0x000013f0
+
+#define NV03_GDI_SIZE_IN_E                                     0x000013f4
+#define NV03_GDI_SIZE_IN_E_W__MASK                             0x0000ffff
+#define NV03_GDI_SIZE_IN_E_W__SHIFT                            0
+#define NV03_GDI_SIZE_IN_E_H__MASK                             0xffff0000
+#define NV03_GDI_SIZE_IN_E_H__SHIFT                            16
+
+#define NV03_GDI_SIZE_OUT_E                                    0x000013f8
+#define NV03_GDI_SIZE_OUT_E_W__MASK                            0x0000ffff
+#define NV03_GDI_SIZE_OUT_E_W__SHIFT                           0
+#define NV03_GDI_SIZE_OUT_E_H__MASK                            0xffff0000
+#define NV03_GDI_SIZE_OUT_E_H__SHIFT                           16
+
+#define NV03_GDI_POINT_E                                       0x000013fc
+#define NV03_GDI_POINT_E_X__MASK                               0x0000ffff
+#define NV03_GDI_POINT_E_X__SHIFT                              0
+#define NV03_GDI_POINT_E_Y__MASK                               0xffff0000
+#define NV03_GDI_POINT_E_Y__SHIFT                              16
+
+#define NV03_GDI_MONOCHROME_COLOR01_E(i0)                     (0x00001400 + 0x4*(i0))
+#define NV03_GDI_MONOCHROME_COLOR01_E__ESIZE                   0x00000004
+#define NV03_GDI_MONOCHROME_COLOR01_E__LEN                     0x00000080
+
+
+#define NV04_GDI_PATCH                                         0x0000010c
+
+#define NV04_GDI_DMA_NOTIFY                                    0x00000180
+
+#define NV04_GDI_DMA_FONTS                                     0x00000184
+
+#define NV04_GDI_PATTERN                                       0x00000188
+
+#define NV04_GDI_ROP                                           0x0000018c
+
+#define NV04_GDI_BETA                                          0x00000190
+
+#define NV04_GDI_BETA4                                         0x00000194
+
+#define NV04_GDI_SURFACE                                       0x00000198
+
+#define NV04_GDI_OPERATION                                     0x000002fc
+#define NV04_GDI_OPERATION_SRCCOPY_AND                         0x00000000
+#define NV04_GDI_OPERATION_ROP_AND                             0x00000001
+#define NV04_GDI_OPERATION_BLEND_AND                           0x00000002
+#define NV04_GDI_OPERATION_SRCCOPY                             0x00000003
+#define NV04_GDI_OPERATION_SRCCOPY_PREMULT                     0x00000004
+#define NV04_GDI_OPERATION_BLEND_PREMULT                       0x00000005
+
+#define NV04_GDI_COLOR_FORMAT                                  0x00000300
+#define NV04_GDI_COLOR_FORMAT_A16R5G6B5                                0x00000001
+#define NV04_GDI_COLOR_FORMAT_X16A1R5G5B5                      0x00000002
+#define NV04_GDI_COLOR_FORMAT_A8R8G8B8                         0x00000003
+
+#define NV04_GDI_MONOCHROME_FORMAT                             0x00000304
+#define NV04_GDI_MONOCHROME_FORMAT_CGA6                                0x00000001
+#define NV04_GDI_MONOCHROME_FORMAT_LE                          0x00000002
+
+#define NV04_GDI_COLOR1_A                                      0x000003fc
+
+#define NV04_GDI_UNCLIPPED_RECTANGLE_POINT(i0)                (0x00000400 + 0x8*(i0))
+#define NV04_GDI_UNCLIPPED_RECTANGLE_POINT__ESIZE              0x00000008
+#define NV04_GDI_UNCLIPPED_RECTANGLE_POINT__LEN                        0x00000020
+#define NV04_GDI_UNCLIPPED_RECTANGLE_POINT_Y__MASK             0x0000ffff
+#define NV04_GDI_UNCLIPPED_RECTANGLE_POINT_Y__SHIFT            0
+#define NV04_GDI_UNCLIPPED_RECTANGLE_POINT_X__MASK             0xffff0000
+#define NV04_GDI_UNCLIPPED_RECTANGLE_POINT_X__SHIFT            16
+
+#define NV04_GDI_UNCLIPPED_RECTANGLE_SIZE(i0)                 (0x00000404 + 0x8*(i0))
+#define NV04_GDI_UNCLIPPED_RECTANGLE_SIZE__ESIZE               0x00000008
+#define NV04_GDI_UNCLIPPED_RECTANGLE_SIZE__LEN                 0x00000020
+#define NV04_GDI_UNCLIPPED_RECTANGLE_SIZE_H__MASK              0x0000ffff
+#define NV04_GDI_UNCLIPPED_RECTANGLE_SIZE_H__SHIFT             0
+#define NV04_GDI_UNCLIPPED_RECTANGLE_SIZE_W__MASK              0xffff0000
+#define NV04_GDI_UNCLIPPED_RECTANGLE_SIZE_W__SHIFT             16
+
+#define NV04_GDI_CLIP_B_POINT0                                 0x000005f4
+#define NV04_GDI_CLIP_B_POINT0_L__MASK                         0x0000ffff
+#define NV04_GDI_CLIP_B_POINT0_L__SHIFT                                0
+#define NV04_GDI_CLIP_B_POINT0_T__MASK                         0xffff0000
+#define NV04_GDI_CLIP_B_POINT0_T__SHIFT                                16
+
+#define NV04_GDI_CLIP_B_POINT1                                 0x000005f8
+#define NV04_GDI_CLIP_B_POINT1_R__MASK                         0x0000ffff
+#define NV04_GDI_CLIP_B_POINT1_R__SHIFT                                0
+#define NV04_GDI_CLIP_B_POINT1_B__MASK                         0xffff0000
+#define NV04_GDI_CLIP_B_POINT1_B__SHIFT                                16
+
+#define NV04_GDI_COLOR1_B                                      0x000005fc
+
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_0(i0)                (0x00000600 + 0x8*(i0))
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_0__ESIZE              0x00000008
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_0__LEN                        0x00000020
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_0_L__MASK             0x0000ffff
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_0_L__SHIFT            0
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_0_T__MASK             0xffff0000
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_0_T__SHIFT            16
+
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_1(i0)                (0x00000604 + 0x8*(i0))
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_1__ESIZE              0x00000008
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_1__LEN                        0x00000020
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_1_R__MASK             0x0000ffff
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_1_R__SHIFT            0
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_1_B__MASK             0xffff0000
+#define NV04_GDI_CLIPPED_RECTANGLE_POINT_1_B__SHIFT            16
+
+#define NV04_GDI_CLIP_C_POINT0                                 0x000007ec
+#define NV04_GDI_CLIP_C_POINT0_L__MASK                         0x0000ffff
+#define NV04_GDI_CLIP_C_POINT0_L__SHIFT                                0
+#define NV04_GDI_CLIP_C_POINT0_T__MASK                         0xffff0000
+#define NV04_GDI_CLIP_C_POINT0_T__SHIFT                                16
+
+#define NV04_GDI_CLIP_C_POINT1                                 0x000007f0
+#define NV04_GDI_CLIP_C_POINT1_R__MASK                         0x0000ffff
+#define NV04_GDI_CLIP_C_POINT1_R__SHIFT                                0
+#define NV04_GDI_CLIP_C_POINT1_B__MASK                         0xffff0000
+#define NV04_GDI_CLIP_C_POINT1_B__SHIFT                                16
+
+#define NV04_GDI_COLOR1_C                                      0x000007f4
+
+#define NV04_GDI_SIZE_C                                                0x000007f8
+#define NV04_GDI_SIZE_C_W__MASK                                        0x0000ffff
+#define NV04_GDI_SIZE_C_W__SHIFT                               0
+#define NV04_GDI_SIZE_C_H__MASK                                        0xffff0000
+#define NV04_GDI_SIZE_C_H__SHIFT                               16
+
+#define NV04_GDI_POINT_C                                       0x000007fc
+#define NV04_GDI_POINT_C_X__MASK                               0x0000ffff
+#define NV04_GDI_POINT_C_X__SHIFT                              0
+#define NV04_GDI_POINT_C_Y__MASK                               0xffff0000
+#define NV04_GDI_POINT_C_Y__SHIFT                              16
+
+#define NV04_GDI_MONOCHROME_COLOR1_C(i0)                      (0x00000800 + 0x4*(i0))
+#define NV04_GDI_MONOCHROME_COLOR1_C__ESIZE                    0x00000004
+#define NV04_GDI_MONOCHROME_COLOR1_C__LEN                      0x00000080
+
+#define NV04_GDI_CLIP_E_POINT0                                 0x00000be4
+#define NV04_GDI_CLIP_E_POINT0_L__MASK                         0x0000ffff
+#define NV04_GDI_CLIP_E_POINT0_L__SHIFT                                0
+#define NV04_GDI_CLIP_E_POINT0_T__MASK                         0xffff0000
+#define NV04_GDI_CLIP_E_POINT0_T__SHIFT                                16
+
+#define NV04_GDI_CLIP_E_POINT1                                 0x00000be8
+#define NV04_GDI_CLIP_E_POINT1_R__MASK                         0x0000ffff
+#define NV04_GDI_CLIP_E_POINT1_R__SHIFT                                0
+#define NV04_GDI_CLIP_E_POINT1_B__MASK                         0xffff0000
+#define NV04_GDI_CLIP_E_POINT1_B__SHIFT                                16
+
+#define NV04_GDI_COLOR0_E                                      0x00000bec
+
+#define NV04_GDI_COLOR1_E                                      0x00000bf0
+
+#define NV04_GDI_SIZE_IN_E                                     0x00000bf4
+#define NV04_GDI_SIZE_IN_E_W__MASK                             0x0000ffff
+#define NV04_GDI_SIZE_IN_E_W__SHIFT                            0
+#define NV04_GDI_SIZE_IN_E_H__MASK                             0xffff0000
+#define NV04_GDI_SIZE_IN_E_H__SHIFT                            16
+
+#define NV04_GDI_SIZE_OUT_E                                    0x00000bf8
+#define NV04_GDI_SIZE_OUT_E_W__MASK                            0x0000ffff
+#define NV04_GDI_SIZE_OUT_E_W__SHIFT                           0
+#define NV04_GDI_SIZE_OUT_E_H__MASK                            0xffff0000
+#define NV04_GDI_SIZE_OUT_E_H__SHIFT                           16
+
+#define NV04_GDI_POINT_E                                       0x00000bfc
+#define NV04_GDI_POINT_E_X__MASK                               0x0000ffff
+#define NV04_GDI_POINT_E_X__SHIFT                              0
+#define NV04_GDI_POINT_E_Y__MASK                               0xffff0000
+#define NV04_GDI_POINT_E_Y__SHIFT                              16
+
+#define NV04_GDI_MONOCHROME_COLOR01_E(i0)                     (0x00000c00 + 0x4*(i0))
+#define NV04_GDI_MONOCHROME_COLOR01_E__ESIZE                   0x00000004
+#define NV04_GDI_MONOCHROME_COLOR01_E__LEN                     0x00000080
+
+#define NV04_GDI_FONT_F                                                0x00000ff0
+#define NV04_GDI_FONT_F_OFFSET__MASK                           0x0fffffff
+#define NV04_GDI_FONT_F_OFFSET__SHIFT                          0
+#define NV04_GDI_FONT_F_PITCH__MASK                            0xf0000000
+#define NV04_GDI_FONT_F_PITCH__SHIFT                           28
+
+#define NV04_GDI_CLIP_F_POINT0                                 0x00000ff4
+#define NV04_GDI_CLIP_F_POINT0_L__MASK                         0x0000ffff
+#define NV04_GDI_CLIP_F_POINT0_L__SHIFT                                0
+#define NV04_GDI_CLIP_F_POINT0_T__MASK                         0xffff0000
+#define NV04_GDI_CLIP_F_POINT0_T__SHIFT                                16
+
+#define NV04_GDI_CLIP_F_POINT1                                 0x00000ff8
+#define NV04_GDI_CLIP_F_POINT1_R__MASK                         0x0000ffff
+#define NV04_GDI_CLIP_F_POINT1_R__SHIFT                                0
+#define NV04_GDI_CLIP_F_POINT1_B__MASK                         0xffff0000
+#define NV04_GDI_CLIP_F_POINT1_B__SHIFT                                16
+
+#define NV04_GDI_COLOR1_F                                      0x00000ffc
+
+#define NV04_GDI_CHARACTER_COLOR1_F(i0)                               (0x00001000 + 0x4*(i0))
+#define NV04_GDI_CHARACTER_COLOR1_F__ESIZE                     0x00000004
+#define NV04_GDI_CHARACTER_COLOR1_F__LEN                       0x00000100
+#define NV04_GDI_CHARACTER_COLOR1_F_INDEX__MASK                        0x000000ff
+#define NV04_GDI_CHARACTER_COLOR1_F_INDEX__SHIFT               0
+#define NV04_GDI_CHARACTER_COLOR1_F_X__MASK                    0x000fff00
+#define NV04_GDI_CHARACTER_COLOR1_F_X__SHIFT                   8
+#define NV04_GDI_CHARACTER_COLOR1_F_Y__MASK                    0xfff00000
+#define NV04_GDI_CHARACTER_COLOR1_F_Y__SHIFT                   20
+
+#define NV04_GDI_FONT_G                                                0x000017f0
+#define NV04_GDI_FONT_G_OFFSET__MASK                           0x0fffffff
+#define NV04_GDI_FONT_G_OFFSET__SHIFT                          0
+#define NV04_GDI_FONT_G_PITCH__MASK                            0xf0000000
+#define NV04_GDI_FONT_G_PITCH__SHIFT                           28
+
+#define NV04_GDI_CLIP_G_POINT0                                 0x000017f4
+#define NV04_GDI_CLIP_G_POINT0_L__MASK                         0x0000ffff
+#define NV04_GDI_CLIP_G_POINT0_L__SHIFT                                0
+#define NV04_GDI_CLIP_G_POINT0_T__MASK                         0xffff0000
+#define NV04_GDI_CLIP_G_POINT0_T__SHIFT                                16
+
+#define NV04_GDI_CLIP_G_POINT1                                 0x000017f8
+#define NV04_GDI_CLIP_G_POINT1_R__MASK                         0x0000ffff
+#define NV04_GDI_CLIP_G_POINT1_R__SHIFT                                0
+#define NV04_GDI_CLIP_G_POINT1_B__MASK                         0xffff0000
+#define NV04_GDI_CLIP_G_POINT1_B__SHIFT                                16
+
+#define NV04_GDI_COLOR1_G                                      0x000017fc
+
+#define NV04_GDI_CHARACTER_COLOR1_G_POINT(i0)                 (0x00001800 + 0x8*(i0))
+#define NV04_GDI_CHARACTER_COLOR1_G_POINT__ESIZE               0x00000008
+#define NV04_GDI_CHARACTER_COLOR1_G_POINT__LEN                 0x00000100
+#define NV04_GDI_CHARACTER_COLOR1_G_POINT_X__MASK              0x0000ffff
+#define NV04_GDI_CHARACTER_COLOR1_G_POINT_X__SHIFT             0
+#define NV04_GDI_CHARACTER_COLOR1_G_POINT_Y__MASK              0xffff0000
+#define NV04_GDI_CHARACTER_COLOR1_G_POINT_Y__SHIFT             16
+
+#define NV04_GDI_CHARACTER_COLOR1_G_INDEX(i0)                 (0x00001804 + 0x8*(i0))
+#define NV04_GDI_CHARACTER_COLOR1_G_INDEX__ESIZE               0x00000008
+#define NV04_GDI_CHARACTER_COLOR1_G_INDEX__LEN                 0x00000100
+
+
+#define NV10_TEXUPLOAD_WAIT_FOR_IDLE                           0x00000108
+
+#define NV10_TEXUPLOAD_DMA_NOTIFY                              0x00000180
+
+#define NV10_TEXUPLOAD_SURFACE                                 0x00000184
+
+#define NV10_TEXUPLOAD_COLOR_FORMAT                            0x00000300
+
+#define NV10_TEXUPLOAD_POINT                                   0x00000304
+#define NV10_TEXUPLOAD_POINT_X__MASK                           0x0000ffff
+#define NV10_TEXUPLOAD_POINT_X__SHIFT                          0
+#define NV10_TEXUPLOAD_POINT_Y__MASK                           0xffff0000
+#define NV10_TEXUPLOAD_POINT_Y__SHIFT                          16
+
+#define NV10_TEXUPLOAD_SIZE                                    0x00000308
+#define NV10_TEXUPLOAD_SIZE_W__MASK                            0x0000ffff
+#define NV10_TEXUPLOAD_SIZE_W__SHIFT                           0
+#define NV10_TEXUPLOAD_SIZE_H__MASK                            0xffff0000
+#define NV10_TEXUPLOAD_SIZE_H__SHIFT                           16
+
+#define NV10_TEXUPLOAD_CLIP_HORIZONTAL                         0x0000030c
+#define NV10_TEXUPLOAD_CLIP_HORIZONTAL_X__MASK                 0x0000ffff
+#define NV10_TEXUPLOAD_CLIP_HORIZONTAL_X__SHIFT                        0
+#define NV10_TEXUPLOAD_CLIP_HORIZONTAL_W__MASK                 0xffff0000
+#define NV10_TEXUPLOAD_CLIP_HORIZONTAL_W__SHIFT                        16
+
+#define NV10_TEXUPLOAD_CLIP_VERTICAL                           0x00000310
+#define NV10_TEXUPLOAD_CLIP_VERTICAL_Y__MASK                   0x0000ffff
+#define NV10_TEXUPLOAD_CLIP_VERTICAL_Y__SHIFT                  0
+#define NV10_TEXUPLOAD_CLIP_VERTICAL_H__MASK                   0xffff0000
+#define NV10_TEXUPLOAD_CLIP_VERTICAL_H__SHIFT                  16
+
+#define NV10_TEXUPLOAD_COLOR(i0)                              (0x00000400 + 0x4*(i0))
+#define NV10_TEXUPLOAD_COLOR__ESIZE                            0x00000004
+#define NV10_TEXUPLOAD_COLOR__LEN                              0x00000700
+
+
+#endif /* _HOME_SKEGGSB_GIT_ENVYTOOLS_RNNDB_NV01_2D_XML */
diff --git a/src/gallium/drivers/nv30/nv30-40_3d.xml.h b/src/gallium/drivers/nv30/nv30-40_3d.xml.h
new file mode 100644 (file)
index 0000000..447f4b3
--- /dev/null
@@ -0,0 +1,2045 @@
+#ifndef _HOME_SKEGGSB_GIT_ENVYTOOLS_RNNDB_NV30_40_3D_XML
+#define _HOME_SKEGGSB_GIT_ENVYTOOLS_RNNDB_NV30_40_3D_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/skeggsb/git/envytools/rnndb/nv30-40_3d.xml (  32450 bytes, from 2012-02-10 02:41:48)
+- /home/skeggsb/git/envytools/rnndb/copyright.xml  (   6452 bytes, from 2011-06-30 00:27:55)
+- /home/skeggsb/git/envytools/rnndb/nv_3ddefs.xml  (  16394 bytes, from 2011-06-30 00:27:55)
+- /home/skeggsb/git/envytools/rnndb/nv_defs.xml    (   4437 bytes, from 2011-06-30 00:27:55)
+- /home/skeggsb/git/envytools/rnndb/nv_object.xml  (  12672 bytes, from 2011-07-13 22:28:24)
+- /home/skeggsb/git/envytools/rnndb/nvchipsets.xml (   3617 bytes, from 2011-07-17 23:19:55)
+- /home/skeggsb/git/envytools/rnndb/nv50_defs.xml  (   5468 bytes, from 2011-07-08 05:22:51)
+
+Copyright (C) 2006-2012 by the following authors:
+- Artur Huillet <arthur.huillet@free.fr> (ahuillet)
+- Ben Skeggs (darktama, darktama_)
+- B. R. <koala_br@users.sourceforge.net> (koala_br)
+- Carlos Martin <carlosmn@users.sf.net> (carlosmn)
+- Christoph Bumiller <e0425955@student.tuwien.ac.at> (calim, chrisbmr)
+- Dawid Gajownik <gajownik@users.sf.net> (gajownik)
+- Dmitry Baryshkov
+- Dmitry Eremin-Solenikov <lumag@users.sf.net> (lumag)
+- EdB <edb_@users.sf.net> (edb_)
+- Erik Waling <erikwailing@users.sf.net> (erikwaling)
+- Francisco Jerez <currojerez@riseup.net> (curro)
+- imirkin <imirkin@users.sf.net> (imirkin)
+- jb17bsome <jb17bsome@bellsouth.net> (jb17bsome)
+- Jeremy Kolb <kjeremy@users.sf.net> (kjeremy)
+- Laurent Carlier <lordheavym@gmail.com> (lordheavy)
+- Luca Barbieri <luca@luca-barbieri.com> (lb, lb1)
+- Maarten Maathuis <madman2003@gmail.com> (stillunknown)
+- Marcin KoÅ›cielnicki <koriakin@0x04.net> (mwk, koriakin)
+- Mark Carey <mark.carey@gmail.com> (careym)
+- Matthieu Castet <matthieu.castet@parrot.com> (mat-c)
+- nvidiaman <nvidiaman@users.sf.net> (nvidiaman)
+- Patrice Mandin <patmandin@gmail.com> (pmandin, pmdata)
+- Pekka Paalanen <pq@iki.fi> (pq, ppaalanen)
+- Peter Popov <ironpeter@users.sf.net> (ironpeter)
+- Richard Hughes <hughsient@users.sf.net> (hughsient)
+- Rudi Cilibrasi <cilibrar@users.sf.net> (cilibrar)
+- Serge Martin
+- Simon Raffeiner
+- Stephane Loeuillet <leroutier@users.sf.net> (leroutier)
+- Stephane Marchesin <stephane.marchesin@gmail.com> (marcheu)
+- sturmflut <sturmflut@users.sf.net> (sturmflut)
+- Sylvain Munaut <tnt@246tNt.com>
+- Victor Stinner <victor.stinner@haypocalc.com> (haypo)
+- Wladmir van der Laan <laanwj@gmail.com> (miathan6)
+- Younes Manton <younes.m@gmail.com> (ymanton)
+
+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 (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 NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+*/
+
+
+
+#define NV30_3D_FLIP_SET_READ                                  0x00000120
+
+#define NV30_3D_FLIP_SET_WRITE                                 0x00000124
+
+#define NV30_3D_FLIP_MAX                                       0x00000128
+
+#define NV30_3D_FLIP_INCR_WRITE                                        0x0000012c
+
+#define NV30_3D_FLIP_WAIT                                      0x00000130
+
+#define NV30_3D_DMA_NOTIFY                                     0x00000180
+
+#define NV30_3D_DMA_TEXTURE0                                   0x00000184
+
+#define NV30_3D_DMA_TEXTURE1                                   0x00000188
+
+#define NV30_3D_DMA_COLOR1                                     0x0000018c
+
+#define NV30_3D_DMA_UNK190                                     0x00000190
+
+#define NV30_3D_DMA_COLOR0                                     0x00000194
+
+#define NV30_3D_DMA_ZETA                                       0x00000198
+
+#define NV30_3D_DMA_VTXBUF0                                    0x0000019c
+
+#define NV30_3D_DMA_VTXBUF1                                    0x000001a0
+
+#define NV30_3D_DMA_FENCE                                      0x000001a4
+
+#define NV30_3D_DMA_QUERY                                      0x000001a8
+
+#define NV30_3D_DMA_UNK1AC                                     0x000001ac
+
+#define NV30_3D_DMA_UNK1B0                                     0x000001b0
+
+#define NV40_3D_DMA_COLOR2                                     0x000001b4
+
+#define NV40_3D_DMA_COLOR3                                     0x000001b8
+
+#define NV30_3D_RT_HORIZ                                       0x00000200
+#define NV30_3D_RT_HORIZ_X__MASK                               0x0000ffff
+#define NV30_3D_RT_HORIZ_X__SHIFT                              0
+#define NV30_3D_RT_HORIZ_W__MASK                               0xffff0000
+#define NV30_3D_RT_HORIZ_W__SHIFT                              16
+
+#define NV30_3D_RT_VERT                                                0x00000204
+#define NV30_3D_RT_VERT_Y__MASK                                        0x0000ffff
+#define NV30_3D_RT_VERT_Y__SHIFT                               0
+#define NV30_3D_RT_VERT_H__MASK                                        0xffff0000
+#define NV30_3D_RT_VERT_H__SHIFT                               16
+
+#define NV30_3D_RT_FORMAT                                      0x00000208
+#define NV30_3D_RT_FORMAT_COLOR__MASK                          0x0000001f
+#define NV30_3D_RT_FORMAT_COLOR__SHIFT                         0
+#define NV30_3D_RT_FORMAT_COLOR_R5G6B5                         0x00000003
+#define NV30_3D_RT_FORMAT_COLOR_X8R8G8B8                       0x00000005
+#define NV30_3D_RT_FORMAT_COLOR_A8R8G8B8                       0x00000008
+#define NV30_3D_RT_FORMAT_COLOR_B8                             0x00000009
+#define NV30_3D_RT_FORMAT_COLOR_A16B16G16R16_FLOAT             0x0000000b
+#define NV30_3D_RT_FORMAT_COLOR_A32B32G32R32_FLOAT             0x0000000c
+#define NV30_3D_RT_FORMAT_COLOR_R32_FLOAT                      0x0000000d
+#define NV30_3D_RT_FORMAT_COLOR_UNK0D                          0x0000000d
+#define NV30_3D_RT_FORMAT_COLOR_X8B8G8R8                       0x0000000f
+#define NV30_3D_RT_FORMAT_COLOR_A8B8G8R8                       0x00000010
+#define NV30_3D_RT_FORMAT_ZETA__MASK                           0x000000e0
+#define NV30_3D_RT_FORMAT_ZETA__SHIFT                          5
+#define NV30_3D_RT_FORMAT_ZETA_Z16                             0x00000020
+#define NV30_3D_RT_FORMAT_ZETA_Z24S8                           0x00000040
+#define NV30_3D_RT_FORMAT_TYPE__MASK                           0x00000f00
+#define NV30_3D_RT_FORMAT_TYPE__SHIFT                          8
+#define NV30_3D_RT_FORMAT_TYPE_LINEAR                          0x00000100
+#define NV30_3D_RT_FORMAT_TYPE_SWIZZLED                                0x00000200
+#define NV30_3D_RT_FORMAT_LOG2_WIDTH__MASK                     0x00ff0000
+#define NV30_3D_RT_FORMAT_LOG2_WIDTH__SHIFT                    16
+#define NV30_3D_RT_FORMAT_LOG2_HEIGHT__MASK                    0xff000000
+#define NV30_3D_RT_FORMAT_LOG2_HEIGHT__SHIFT                   24
+
+#define NV30_3D_COLOR0_PITCH                                   0x0000020c
+#define NV30_3D_COLOR0_PITCH_COLOR0__MASK                      0x0000ffff
+#define NV30_3D_COLOR0_PITCH_COLOR0__SHIFT                     0
+#define NV30_3D_COLOR0_PITCH_ZETA__MASK                                0xffff0000
+#define NV30_3D_COLOR0_PITCH_ZETA__SHIFT                       16
+
+#define NV40_3D_COLOR0_PITCH                                   0x0000020c
+
+#define NV30_3D_COLOR0_OFFSET                                  0x00000210
+
+#define NV30_3D_ZETA_OFFSET                                    0x00000214
+
+#define NV30_3D_COLOR1_OFFSET                                  0x00000218
+
+#define NV30_3D_COLOR1_PITCH                                   0x0000021c
+
+#define NV30_3D_RT_ENABLE                                      0x00000220
+#define NV30_3D_RT_ENABLE_COLOR0                               0x00000001
+#define NV30_3D_RT_ENABLE_COLOR1                               0x00000002
+#define NV40_3D_RT_ENABLE_COLOR2                               0x00000004
+#define NV40_3D_RT_ENABLE_COLOR3                               0x00000008
+#define NV30_3D_RT_ENABLE_MRT                                  0x00000010
+
+#define NV40_3D_ZETA_PITCH                                     0x0000022c
+
+#define NV30_3D_HIERZ_PITCH                                    0x0000022c
+
+#define NV30_3D_HIERZ_OFFSET                                   0x00000230
+
+#define NV30_3D_TEX_UNITS_ENABLE                               0x0000023c
+#define NV30_3D_TEX_UNITS_ENABLE_TX0                           0x00000001
+#define NV30_3D_TEX_UNITS_ENABLE_TX1                           0x00000002
+#define NV30_3D_TEX_UNITS_ENABLE_TX2                           0x00000004
+#define NV30_3D_TEX_UNITS_ENABLE_TX3                           0x00000008
+#define NV30_3D_TEX_UNITS_ENABLE_TX4                           0x00000010
+#define NV30_3D_TEX_UNITS_ENABLE_TX5                           0x00000020
+#define NV30_3D_TEX_UNITS_ENABLE_TX6                           0x00000040
+#define NV30_3D_TEX_UNITS_ENABLE_TX7                           0x00000080
+
+#define NV30_3D_TEX_MATRIX_ENABLE(i0)                         (0x00000240 + 0x4*(i0))
+#define NV30_3D_TEX_MATRIX_ENABLE__ESIZE                       0x00000004
+#define NV30_3D_TEX_MATRIX_ENABLE__LEN                         0x00000008
+
+#define NV40_3D_COLOR2_PITCH                                   0x00000280
+
+#define NV40_3D_COLOR3_PITCH                                   0x00000284
+
+#define NV40_3D_COLOR2_OFFSET                                  0x00000288
+
+#define NV40_3D_COLOR3_OFFSET                                  0x0000028c
+
+#define NV30_3D_VIEWPORT_TX_ORIGIN                             0x000002b8
+#define NV30_3D_VIEWPORT_TX_ORIGIN_X__MASK                     0x0000ffff
+#define NV30_3D_VIEWPORT_TX_ORIGIN_X__SHIFT                    0
+#define NV30_3D_VIEWPORT_TX_ORIGIN_Y__MASK                     0xffff0000
+#define NV30_3D_VIEWPORT_TX_ORIGIN_Y__SHIFT                    16
+
+#define NV30_3D_VIEWPORT_CLIP_MODE                             0x000002bc
+
+#define NV30_3D_VIEWPORT_CLIP_HORIZ(i0)                               (0x000002c0 + 0x8*(i0))
+#define NV30_3D_VIEWPORT_CLIP_HORIZ__ESIZE                     0x00000008
+#define NV30_3D_VIEWPORT_CLIP_HORIZ__LEN                       0x00000008
+#define NV30_3D_VIEWPORT_CLIP_HORIZ_L__MASK                    0x0000ffff
+#define NV30_3D_VIEWPORT_CLIP_HORIZ_L__SHIFT                   0
+#define NV30_3D_VIEWPORT_CLIP_HORIZ_R__MASK                    0xffff0000
+#define NV30_3D_VIEWPORT_CLIP_HORIZ_R__SHIFT                   16
+
+#define NV30_3D_VIEWPORT_CLIP_VERT(i0)                        (0x000002c4 + 0x8*(i0))
+#define NV30_3D_VIEWPORT_CLIP_VERT__ESIZE                      0x00000008
+#define NV30_3D_VIEWPORT_CLIP_VERT__LEN                                0x00000008
+#define NV30_3D_VIEWPORT_CLIP_VERT_T__MASK                     0x0000ffff
+#define NV30_3D_VIEWPORT_CLIP_VERT_T__SHIFT                    0
+#define NV30_3D_VIEWPORT_CLIP_VERT_D__MASK                     0xffff0000
+#define NV30_3D_VIEWPORT_CLIP_VERT_D__SHIFT                    16
+
+#define NV30_3D_DITHER_ENABLE                                  0x00000300
+
+#define NV30_3D_ALPHA_FUNC_ENABLE                              0x00000304
+
+#define NV30_3D_ALPHA_FUNC_FUNC                                        0x00000308
+#define NV30_3D_ALPHA_FUNC_FUNC_NEVER                          0x00000200
+#define NV30_3D_ALPHA_FUNC_FUNC_LESS                           0x00000201
+#define NV30_3D_ALPHA_FUNC_FUNC_EQUAL                          0x00000202
+#define NV30_3D_ALPHA_FUNC_FUNC_LEQUAL                         0x00000203
+#define NV30_3D_ALPHA_FUNC_FUNC_GREATER                                0x00000204
+#define NV30_3D_ALPHA_FUNC_FUNC_NOTEQUAL                       0x00000205
+#define NV30_3D_ALPHA_FUNC_FUNC_GEQUAL                         0x00000206
+#define NV30_3D_ALPHA_FUNC_FUNC_ALWAYS                         0x00000207
+
+#define NV30_3D_ALPHA_FUNC_REF                                 0x0000030c
+
+#define NV30_3D_BLEND_FUNC_ENABLE                              0x00000310
+
+#define NV30_3D_BLEND_FUNC_SRC                                 0x00000314
+#define NV30_3D_BLEND_FUNC_SRC_RGB__MASK                       0x0000ffff
+#define NV30_3D_BLEND_FUNC_SRC_RGB__SHIFT                      0
+#define NV30_3D_BLEND_FUNC_SRC_RGB_ZERO                                0x00000000
+#define NV30_3D_BLEND_FUNC_SRC_RGB_ONE                         0x00000001
+#define NV30_3D_BLEND_FUNC_SRC_RGB_SRC_COLOR                   0x00000300
+#define NV30_3D_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_COLOR         0x00000301
+#define NV30_3D_BLEND_FUNC_SRC_RGB_SRC_ALPHA                   0x00000302
+#define NV30_3D_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_ALPHA         0x00000303
+#define NV30_3D_BLEND_FUNC_SRC_RGB_DST_ALPHA                   0x00000304
+#define NV30_3D_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_ALPHA         0x00000305
+#define NV30_3D_BLEND_FUNC_SRC_RGB_DST_COLOR                   0x00000306
+#define NV30_3D_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_COLOR         0x00000307
+#define NV30_3D_BLEND_FUNC_SRC_RGB_SRC_ALPHA_SATURATE          0x00000308
+#define NV30_3D_BLEND_FUNC_SRC_RGB_CONSTANT_COLOR              0x00008001
+#define NV30_3D_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_COLOR    0x00008002
+#define NV30_3D_BLEND_FUNC_SRC_RGB_CONSTANT_ALPHA              0x00008003
+#define NV30_3D_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_ALPHA    0x00008004
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA__MASK                     0xffff0000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA__SHIFT                    16
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_ZERO                      0x00000000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_ONE                       0x00010000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_SRC_COLOR                 0x03000000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_COLOR       0x03010000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA                 0x03020000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_ALPHA       0x03030000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_DST_ALPHA                 0x03040000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_ALPHA       0x03050000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_DST_COLOR                 0x03060000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_COLOR       0x03070000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA_SATURATE                0x03080000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_CONSTANT_COLOR            0x80010000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_COLOR  0x80020000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_CONSTANT_ALPHA            0x80030000
+#define NV30_3D_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_ALPHA  0x80040000
+
+#define NV30_3D_BLEND_FUNC_DST                                 0x00000318
+#define NV30_3D_BLEND_FUNC_DST_RGB__MASK                       0x0000ffff
+#define NV30_3D_BLEND_FUNC_DST_RGB__SHIFT                      0
+#define NV30_3D_BLEND_FUNC_DST_RGB_ZERO                                0x00000000
+#define NV30_3D_BLEND_FUNC_DST_RGB_ONE                         0x00000001
+#define NV30_3D_BLEND_FUNC_DST_RGB_SRC_COLOR                   0x00000300
+#define NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_COLOR         0x00000301
+#define NV30_3D_BLEND_FUNC_DST_RGB_SRC_ALPHA                   0x00000302
+#define NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA         0x00000303
+#define NV30_3D_BLEND_FUNC_DST_RGB_DST_ALPHA                   0x00000304
+#define NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_ALPHA         0x00000305
+#define NV30_3D_BLEND_FUNC_DST_RGB_DST_COLOR                   0x00000306
+#define NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_COLOR         0x00000307
+#define NV30_3D_BLEND_FUNC_DST_RGB_SRC_ALPHA_SATURATE          0x00000308
+#define NV30_3D_BLEND_FUNC_DST_RGB_CONSTANT_COLOR              0x00008001
+#define NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_COLOR    0x00008002
+#define NV30_3D_BLEND_FUNC_DST_RGB_CONSTANT_ALPHA              0x00008003
+#define NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_ALPHA    0x00008004
+#define NV30_3D_BLEND_FUNC_DST_ALPHA__MASK                     0xffff0000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA__SHIFT                    16
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_ZERO                      0x00000000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_ONE                       0x00010000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_SRC_COLOR                 0x03000000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_COLOR       0x03010000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_SRC_ALPHA                 0x03020000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_ALPHA       0x03030000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_DST_ALPHA                 0x03040000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_ALPHA       0x03050000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_DST_COLOR                 0x03060000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_COLOR       0x03070000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_SRC_ALPHA_SATURATE                0x03080000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_CONSTANT_COLOR            0x80010000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_COLOR  0x80020000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_CONSTANT_ALPHA            0x80030000
+#define NV30_3D_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_ALPHA  0x80040000
+
+#define NV30_3D_BLEND_COLOR                                    0x0000031c
+#define NV30_3D_BLEND_COLOR_B__MASK                            0x000000ff
+#define NV30_3D_BLEND_COLOR_B__SHIFT                           0
+#define NV30_3D_BLEND_COLOR_G__MASK                            0x0000ff00
+#define NV30_3D_BLEND_COLOR_G__SHIFT                           8
+#define NV30_3D_BLEND_COLOR_R__MASK                            0x00ff0000
+#define NV30_3D_BLEND_COLOR_R__SHIFT                           16
+#define NV30_3D_BLEND_COLOR_A__MASK                            0xff000000
+#define NV30_3D_BLEND_COLOR_A__SHIFT                           24
+
+#define NV30_3D_BLEND_EQUATION                                 0x00000320
+#define NV30_3D_BLEND_EQUATION_FUNC_ADD                                0x00008006
+#define NV30_3D_BLEND_EQUATION_MIN                             0x00008007
+#define NV30_3D_BLEND_EQUATION_MAX                             0x00008008
+#define NV30_3D_BLEND_EQUATION_FUNC_SUBTRACT                   0x0000800a
+#define NV30_3D_BLEND_EQUATION_FUNC_REVERSE_SUBTRACT           0x0000800b
+
+#define NV40_3D_BLEND_EQUATION                                 0x00000320
+#define NV40_3D_BLEND_EQUATION_RGB__MASK                       0x0000ffff
+#define NV40_3D_BLEND_EQUATION_RGB__SHIFT                      0
+#define NV40_3D_BLEND_EQUATION_RGB_FUNC_ADD                    0x00008006
+#define NV40_3D_BLEND_EQUATION_RGB_MIN                         0x00008007
+#define NV40_3D_BLEND_EQUATION_RGB_MAX                         0x00008008
+#define NV40_3D_BLEND_EQUATION_RGB_FUNC_SUBTRACT               0x0000800a
+#define NV40_3D_BLEND_EQUATION_RGB_FUNC_REVERSE_SUBTRACT       0x0000800b
+#define NV40_3D_BLEND_EQUATION_ALPHA__MASK                     0xffff0000
+#define NV40_3D_BLEND_EQUATION_ALPHA__SHIFT                    16
+#define NV40_3D_BLEND_EQUATION_ALPHA_FUNC_ADD                  0x80060000
+#define NV40_3D_BLEND_EQUATION_ALPHA_MIN                       0x80070000
+#define NV40_3D_BLEND_EQUATION_ALPHA_MAX                       0x80080000
+#define NV40_3D_BLEND_EQUATION_ALPHA_FUNC_SUBTRACT             0x800a0000
+#define NV40_3D_BLEND_EQUATION_ALPHA_FUNC_REVERSE_SUBTRACT     0x800b0000
+
+#define NV30_3D_COLOR_MASK                                     0x00000324
+#define NV30_3D_COLOR_MASK_B                                   0x000000ff
+#define NV30_3D_COLOR_MASK_G                                   0x0000ff00
+#define NV30_3D_COLOR_MASK_R                                   0x00ff0000
+#define NV30_3D_COLOR_MASK_A                                   0xff000000
+
+#define NV30_3D_STENCIL(i0)                                   (0x00000328 + 0x20*(i0))
+#define NV30_3D_STENCIL__ESIZE                                 0x00000020
+#define NV30_3D_STENCIL__LEN                                   0x00000002
+
+#define NV30_3D_STENCIL_ENABLE(i0)                            (0x00000328 + 0x20*(i0))
+
+#define NV30_3D_STENCIL_MASK(i0)                              (0x0000032c + 0x20*(i0))
+
+#define NV30_3D_STENCIL_FUNC_FUNC(i0)                         (0x00000330 + 0x20*(i0))
+#define NV30_3D_STENCIL_FUNC_FUNC_NEVER                                0x00000200
+#define NV30_3D_STENCIL_FUNC_FUNC_LESS                         0x00000201
+#define NV30_3D_STENCIL_FUNC_FUNC_EQUAL                                0x00000202
+#define NV30_3D_STENCIL_FUNC_FUNC_LEQUAL                       0x00000203
+#define NV30_3D_STENCIL_FUNC_FUNC_GREATER                      0x00000204
+#define NV30_3D_STENCIL_FUNC_FUNC_NOTEQUAL                     0x00000205
+#define NV30_3D_STENCIL_FUNC_FUNC_GEQUAL                       0x00000206
+#define NV30_3D_STENCIL_FUNC_FUNC_ALWAYS                       0x00000207
+
+#define NV30_3D_STENCIL_FUNC_REF(i0)                          (0x00000334 + 0x20*(i0))
+
+#define NV30_3D_STENCIL_FUNC_MASK(i0)                         (0x00000338 + 0x20*(i0))
+
+#define NV30_3D_STENCIL_OP_FAIL(i0)                           (0x0000033c + 0x20*(i0))
+#define NV30_3D_STENCIL_OP_FAIL_ZERO                           0x00000000
+#define NV30_3D_STENCIL_OP_FAIL_INVERT                         0x0000150a
+#define NV30_3D_STENCIL_OP_FAIL_KEEP                           0x00001e00
+#define NV30_3D_STENCIL_OP_FAIL_REPLACE                                0x00001e01
+#define NV30_3D_STENCIL_OP_FAIL_INCR                           0x00001e02
+#define NV30_3D_STENCIL_OP_FAIL_DECR                           0x00001e03
+#define NV30_3D_STENCIL_OP_FAIL_INCR_WRAP                      0x00008507
+#define NV30_3D_STENCIL_OP_FAIL_DECR_WRAP                      0x00008508
+
+#define NV30_3D_STENCIL_OP_ZFAIL(i0)                          (0x00000340 + 0x20*(i0))
+#define NV30_3D_STENCIL_OP_ZFAIL_ZERO                          0x00000000
+#define NV30_3D_STENCIL_OP_ZFAIL_INVERT                                0x0000150a
+#define NV30_3D_STENCIL_OP_ZFAIL_KEEP                          0x00001e00
+#define NV30_3D_STENCIL_OP_ZFAIL_REPLACE                       0x00001e01
+#define NV30_3D_STENCIL_OP_ZFAIL_INCR                          0x00001e02
+#define NV30_3D_STENCIL_OP_ZFAIL_DECR                          0x00001e03
+#define NV30_3D_STENCIL_OP_ZFAIL_INCR_WRAP                     0x00008507
+#define NV30_3D_STENCIL_OP_ZFAIL_DECR_WRAP                     0x00008508
+
+#define NV30_3D_STENCIL_OP_ZPASS(i0)                          (0x00000344 + 0x20*(i0))
+#define NV30_3D_STENCIL_OP_ZPASS_ZERO                          0x00000000
+#define NV30_3D_STENCIL_OP_ZPASS_INVERT                                0x0000150a
+#define NV30_3D_STENCIL_OP_ZPASS_KEEP                          0x00001e00
+#define NV30_3D_STENCIL_OP_ZPASS_REPLACE                       0x00001e01
+#define NV30_3D_STENCIL_OP_ZPASS_INCR                          0x00001e02
+#define NV30_3D_STENCIL_OP_ZPASS_DECR                          0x00001e03
+#define NV30_3D_STENCIL_OP_ZPASS_INCR_WRAP                     0x00008507
+#define NV30_3D_STENCIL_OP_ZPASS_DECR_WRAP                     0x00008508
+
+#define NV30_3D_SHADE_MODEL                                    0x00000368
+#define NV30_3D_SHADE_MODEL_FLAT                               0x00001d00
+#define NV30_3D_SHADE_MODEL_SMOOTH                             0x00001d01
+
+#define NV30_3D_FOG_ENABLE                                     0x0000036c
+
+#define NV30_3D_FOG_COLOR                                      0x00000370
+#define NV30_3D_FOG_COLOR_R__MASK                              0x000000ff
+#define NV30_3D_FOG_COLOR_R__SHIFT                             0
+#define NV30_3D_FOG_COLOR_G__MASK                              0x0000ff00
+#define NV30_3D_FOG_COLOR_G__SHIFT                             8
+#define NV30_3D_FOG_COLOR_B__MASK                              0x00ff0000
+#define NV30_3D_FOG_COLOR_B__SHIFT                             16
+#define NV30_3D_FOG_COLOR_A__MASK                              0xff000000
+#define NV30_3D_FOG_COLOR_A__SHIFT                             24
+
+#define NV40_3D_MRT_COLOR_MASK                                 0x00000370
+#define NV40_3D_MRT_COLOR_MASK_BUFFER1_A                       0x00000010
+#define NV40_3D_MRT_COLOR_MASK_BUFFER1_R                       0x00000020
+#define NV40_3D_MRT_COLOR_MASK_BUFFER1_G                       0x00000040
+#define NV40_3D_MRT_COLOR_MASK_BUFFER1_B                       0x00000080
+#define NV40_3D_MRT_COLOR_MASK_BUFFER2_A                       0x00000100
+#define NV40_3D_MRT_COLOR_MASK_BUFFER2_R                       0x00000200
+#define NV40_3D_MRT_COLOR_MASK_BUFFER2_G                       0x00000400
+#define NV40_3D_MRT_COLOR_MASK_BUFFER2_B                       0x00000800
+#define NV40_3D_MRT_COLOR_MASK_BUFFER3_A                       0x00001000
+#define NV40_3D_MRT_COLOR_MASK_BUFFER3_R                       0x00002000
+#define NV40_3D_MRT_COLOR_MASK_BUFFER3_G                       0x00004000
+#define NV40_3D_MRT_COLOR_MASK_BUFFER3_B                       0x00008000
+
+#define NV30_3D_COLOR_LOGIC_OP_ENABLE                          0x00000374
+
+#define NV30_3D_COLOR_LOGIC_OP_OP                              0x00000378
+#define NV30_3D_COLOR_LOGIC_OP_OP_CLEAR                                0x00001500
+#define NV30_3D_COLOR_LOGIC_OP_OP_AND                          0x00001501
+#define NV30_3D_COLOR_LOGIC_OP_OP_AND_REVERSE                  0x00001502
+#define NV30_3D_COLOR_LOGIC_OP_OP_COPY                         0x00001503
+#define NV30_3D_COLOR_LOGIC_OP_OP_AND_INVERTED                 0x00001504
+#define NV30_3D_COLOR_LOGIC_OP_OP_NOOP                         0x00001505
+#define NV30_3D_COLOR_LOGIC_OP_OP_XOR                          0x00001506
+#define NV30_3D_COLOR_LOGIC_OP_OP_OR                           0x00001507
+#define NV30_3D_COLOR_LOGIC_OP_OP_NOR                          0x00001508
+#define NV30_3D_COLOR_LOGIC_OP_OP_EQUIV                                0x00001509
+#define NV30_3D_COLOR_LOGIC_OP_OP_INVERT                       0x0000150a
+#define NV30_3D_COLOR_LOGIC_OP_OP_OR_REVERSE                   0x0000150b
+#define NV30_3D_COLOR_LOGIC_OP_OP_COPY_INVERTED                        0x0000150c
+#define NV30_3D_COLOR_LOGIC_OP_OP_OR_INVERTED                  0x0000150d
+#define NV30_3D_COLOR_LOGIC_OP_OP_NAND                         0x0000150e
+#define NV30_3D_COLOR_LOGIC_OP_OP_SET                          0x0000150f
+
+#define NV30_3D_NORMALIZE_ENABLE                               0x0000037c
+
+#define NV35_3D_DEPTH_BOUNDS_TEST_ENABLE                       0x00000380
+
+#define NV35_3D_DEPTH_BOUNDS_TEST_ZMIN                         0x00000384
+
+#define NV35_3D_DEPTH_BOUNDS_TEST_ZMAX                         0x00000388
+
+#define NV30_3D_COLOR_MATERIAL                                 0x00000390
+#define NV30_3D_COLOR_MATERIAL_FRONT_EMISSION_ENABLE           0x00000001
+#define NV30_3D_COLOR_MATERIAL_FRONT_AMBIENT_ENABLE            0x00000004
+#define NV30_3D_COLOR_MATERIAL_FRONT_DIFFUSE_ENABLE            0x00000010
+#define NV30_3D_COLOR_MATERIAL_FRONT_SPECULAR_ENABLE           0x00000040
+#define NV30_3D_COLOR_MATERIAL_BACK_EMISSION_ENABLE            0x00000100
+#define NV30_3D_COLOR_MATERIAL_BACK_AMBIENT_ENABLE             0x00000400
+#define NV30_3D_COLOR_MATERIAL_BACK_DIFFUSE_ENABLE             0x00001000
+#define NV30_3D_COLOR_MATERIAL_BACK_SPECULAR_ENABLE            0x00004000
+
+#define NV30_3D_DEPTH_RANGE_NEAR                               0x00000394
+
+#define NV30_3D_DEPTH_RANGE_FAR                                        0x00000398
+
+#define NV30_3D_COLOR_MATERIAL_FRONT                           0x000003a0
+
+
+#define NV30_3D_COLOR_MATERIAL_FRONT_R                         0x000003a0
+
+#define NV30_3D_COLOR_MATERIAL_FRONT_G                         0x000003a4
+
+#define NV30_3D_COLOR_MATERIAL_FRONT_B                         0x000003a8
+
+#define NV30_3D_COLOR_MATERIAL_FRONT_A                         0x000003ac
+
+#define NV40_3D_MIPMAP_ROUNDING                                        0x000003b0
+#define NV40_3D_MIPMAP_ROUNDING_MODE__MASK                     0x00100000
+#define NV40_3D_MIPMAP_ROUNDING_MODE__SHIFT                    20
+#define NV40_3D_MIPMAP_ROUNDING_MODE_UP                                0x00000000
+#define NV40_3D_MIPMAP_ROUNDING_MODE_DOWN                      0x00100000
+
+#define NV30_3D_LINE_WIDTH                                     0x000003b8
+
+#define NV30_3D_LINE_SMOOTH_ENABLE                             0x000003bc
+
+
+
+#define NV30_3D_TEX_GEN_MODE(i0, i1)                          (0x00000400 + 0x10*(i0) + 0x4*(i1))
+#define NV30_3D_TEX_GEN_MODE__ESIZE                            0x00000004
+#define NV30_3D_TEX_GEN_MODE__LEN                              0x00000004
+#define NV30_3D_TEX_GEN_MODE_FALSE                             0x00000000
+#define NV30_3D_TEX_GEN_MODE_EYE_LINEAR                                0x00002400
+#define NV30_3D_TEX_GEN_MODE_OBJECT_LINEAR                     0x00002401
+#define NV30_3D_TEX_GEN_MODE_SPHERE_MAP                                0x00002402
+#define NV30_3D_TEX_GEN_MODE_NORMAL_MAP                                0x00008511
+#define NV30_3D_TEX_GEN_MODE_REFLECTION_MAP                    0x00008512
+
+#define NV30_3D_MODELVIEW_MATRIX(i0)                          (0x00000480 + 0x4*(i0))
+#define NV30_3D_MODELVIEW_MATRIX__ESIZE                                0x00000004
+#define NV30_3D_MODELVIEW_MATRIX__LEN                          0x00000010
+
+#define NV30_3D_INVERSE_MODELVIEW_MATRIX(i0)                  (0x00000580 + 0x4*(i0))
+#define NV30_3D_INVERSE_MODELVIEW_MATRIX__ESIZE                        0x00000004
+#define NV30_3D_INVERSE_MODELVIEW_MATRIX__LEN                  0x0000000c
+
+#define NV30_3D_PROJECTION_MATRIX(i0)                         (0x00000680 + 0x4*(i0))
+#define NV30_3D_PROJECTION_MATRIX__ESIZE                       0x00000004
+#define NV30_3D_PROJECTION_MATRIX__LEN                         0x00000010
+
+
+#define NV30_3D_TEX_MATRIX(i0, i1)                            (0x000006c0 + 0x40*(i0) + 0x4*(i1))
+#define NV30_3D_TEX_MATRIX__ESIZE                              0x00000004
+#define NV30_3D_TEX_MATRIX__LEN                                        0x00000010
+
+#define NV30_3D_SCISSOR_HORIZ                                  0x000008c0
+#define NV30_3D_SCISSOR_HORIZ_X__MASK                          0x0000ffff
+#define NV30_3D_SCISSOR_HORIZ_X__SHIFT                         0
+#define NV30_3D_SCISSOR_HORIZ_W__MASK                          0xffff0000
+#define NV30_3D_SCISSOR_HORIZ_W__SHIFT                         16
+
+#define NV30_3D_SCISSOR_VERT                                   0x000008c4
+#define NV30_3D_SCISSOR_VERT_Y__MASK                           0x0000ffff
+#define NV30_3D_SCISSOR_VERT_Y__SHIFT                          0
+#define NV30_3D_SCISSOR_VERT_H__MASK                           0xffff0000
+#define NV30_3D_SCISSOR_VERT_H__SHIFT                          16
+
+#define NV30_3D_FOG_COORD_DIST                                 0x000008c8
+
+#define NV30_3D_FOG_MODE                                       0x000008cc
+
+#define NV30_3D_FOG_EQUATION_CONSTANT                          0x000008d0
+
+#define NV30_3D_FOG_EQUATION_LINEAR                            0x000008d4
+
+#define NV30_3D_FOG_EQUATION_QUADRATIC                         0x000008d8
+
+#define NV30_3D_FP_ACTIVE_PROGRAM                              0x000008e4
+#define NV30_3D_FP_ACTIVE_PROGRAM_DMA0                         0x00000001
+#define NV30_3D_FP_ACTIVE_PROGRAM_DMA1                         0x00000002
+#define NV30_3D_FP_ACTIVE_PROGRAM_OFFSET__MASK                 0xfffffffc
+#define NV30_3D_FP_ACTIVE_PROGRAM_OFFSET__SHIFT                        2
+
+
+#define NV30_3D_RC_COLOR0                                      0x000008ec
+#define NV30_3D_RC_COLOR0_B__MASK                              0x000000ff
+#define NV30_3D_RC_COLOR0_B__SHIFT                             0
+#define NV30_3D_RC_COLOR0_G__MASK                              0x0000ff00
+#define NV30_3D_RC_COLOR0_G__SHIFT                             8
+#define NV30_3D_RC_COLOR0_R__MASK                              0x00ff0000
+#define NV30_3D_RC_COLOR0_R__SHIFT                             16
+#define NV30_3D_RC_COLOR0_A__MASK                              0xff000000
+#define NV30_3D_RC_COLOR0_A__SHIFT                             24
+
+#define NV30_3D_RC_COLOR1                                      0x000008f0
+#define NV30_3D_RC_COLOR1_B__MASK                              0x000000ff
+#define NV30_3D_RC_COLOR1_B__SHIFT                             0
+#define NV30_3D_RC_COLOR1_G__MASK                              0x0000ff00
+#define NV30_3D_RC_COLOR1_G__SHIFT                             8
+#define NV30_3D_RC_COLOR1_R__MASK                              0x00ff0000
+#define NV30_3D_RC_COLOR1_R__SHIFT                             16
+#define NV30_3D_RC_COLOR1_A__MASK                              0xff000000
+#define NV30_3D_RC_COLOR1_A__SHIFT                             24
+
+#define NV30_3D_RC_FINAL0                                      0x000008f4
+#define NV30_3D_RC_FINAL0_D_INPUT__MASK                                0x0000000f
+#define NV30_3D_RC_FINAL0_D_INPUT__SHIFT                       0
+#define NV30_3D_RC_FINAL0_D_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_FINAL0_D_INPUT_CONSTANT_COLOR0              0x00000001
+#define NV30_3D_RC_FINAL0_D_INPUT_CONSTANT_COLOR1              0x00000002
+#define NV30_3D_RC_FINAL0_D_INPUT_FOG                          0x00000003
+#define NV30_3D_RC_FINAL0_D_INPUT_PRIMARY_COLOR                        0x00000004
+#define NV30_3D_RC_FINAL0_D_INPUT_SECONDARY_COLOR              0x00000005
+#define NV30_3D_RC_FINAL0_D_INPUT_TEXTURE0                     0x00000008
+#define NV30_3D_RC_FINAL0_D_INPUT_TEXTURE1                     0x00000009
+#define NV30_3D_RC_FINAL0_D_INPUT_TEXTURE2                     0x0000000a
+#define NV30_3D_RC_FINAL0_D_INPUT_TEXTURE3                     0x0000000b
+#define NV30_3D_RC_FINAL0_D_INPUT_SPARE0                       0x0000000c
+#define NV30_3D_RC_FINAL0_D_INPUT_SPARE1                       0x0000000d
+#define NV30_3D_RC_FINAL0_D_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x0000000e
+#define NV30_3D_RC_FINAL0_D_INPUT_E_TIMES_F                    0x0000000f
+#define NV30_3D_RC_FINAL0_D_COMPONENT_USAGE__MASK              0x00000010
+#define NV30_3D_RC_FINAL0_D_COMPONENT_USAGE__SHIFT             4
+#define NV30_3D_RC_FINAL0_D_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_FINAL0_D_COMPONENT_USAGE_ALPHA              0x00000010
+#define NV30_3D_RC_FINAL0_D_MAPPING__MASK                      0x000000e0
+#define NV30_3D_RC_FINAL0_D_MAPPING__SHIFT                     5
+#define NV30_3D_RC_FINAL0_D_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_FINAL0_D_MAPPING_UNSIGNED_INVERT            0x00000020
+#define NV30_3D_RC_FINAL0_D_MAPPING_EXPAND_NORMAL              0x00000040
+#define NV30_3D_RC_FINAL0_D_MAPPING_EXPAND_NEGATE              0x00000060
+#define NV30_3D_RC_FINAL0_D_MAPPING_HALF_BIAS_NORMAL           0x00000080
+#define NV30_3D_RC_FINAL0_D_MAPPING_HALF_BIAS_NEGATE           0x000000a0
+#define NV30_3D_RC_FINAL0_D_MAPPING_SIGNED_IDENTITY            0x000000c0
+#define NV30_3D_RC_FINAL0_D_MAPPING_SIGNED_NEGATE              0x000000e0
+#define NV30_3D_RC_FINAL0_C_INPUT__MASK                                0x00000f00
+#define NV30_3D_RC_FINAL0_C_INPUT__SHIFT                       8
+#define NV30_3D_RC_FINAL0_C_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_FINAL0_C_INPUT_CONSTANT_COLOR0              0x00000100
+#define NV30_3D_RC_FINAL0_C_INPUT_CONSTANT_COLOR1              0x00000200
+#define NV30_3D_RC_FINAL0_C_INPUT_FOG                          0x00000300
+#define NV30_3D_RC_FINAL0_C_INPUT_PRIMARY_COLOR                        0x00000400
+#define NV30_3D_RC_FINAL0_C_INPUT_SECONDARY_COLOR              0x00000500
+#define NV30_3D_RC_FINAL0_C_INPUT_TEXTURE0                     0x00000800
+#define NV30_3D_RC_FINAL0_C_INPUT_TEXTURE1                     0x00000900
+#define NV30_3D_RC_FINAL0_C_INPUT_TEXTURE2                     0x00000a00
+#define NV30_3D_RC_FINAL0_C_INPUT_TEXTURE3                     0x00000b00
+#define NV30_3D_RC_FINAL0_C_INPUT_SPARE0                       0x00000c00
+#define NV30_3D_RC_FINAL0_C_INPUT_SPARE1                       0x00000d00
+#define NV30_3D_RC_FINAL0_C_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x00000e00
+#define NV30_3D_RC_FINAL0_C_INPUT_E_TIMES_F                    0x00000f00
+#define NV30_3D_RC_FINAL0_C_COMPONENT_USAGE__MASK              0x00001000
+#define NV30_3D_RC_FINAL0_C_COMPONENT_USAGE__SHIFT             12
+#define NV30_3D_RC_FINAL0_C_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_FINAL0_C_COMPONENT_USAGE_ALPHA              0x00001000
+#define NV30_3D_RC_FINAL0_C_MAPPING__MASK                      0x0000e000
+#define NV30_3D_RC_FINAL0_C_MAPPING__SHIFT                     13
+#define NV30_3D_RC_FINAL0_C_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_FINAL0_C_MAPPING_UNSIGNED_INVERT            0x00002000
+#define NV30_3D_RC_FINAL0_C_MAPPING_EXPAND_NORMAL              0x00004000
+#define NV30_3D_RC_FINAL0_C_MAPPING_EXPAND_NEGATE              0x00006000
+#define NV30_3D_RC_FINAL0_C_MAPPING_HALF_BIAS_NORMAL           0x00008000
+#define NV30_3D_RC_FINAL0_C_MAPPING_HALF_BIAS_NEGATE           0x0000a000
+#define NV30_3D_RC_FINAL0_C_MAPPING_SIGNED_IDENTITY            0x0000c000
+#define NV30_3D_RC_FINAL0_C_MAPPING_SIGNED_NEGATE              0x0000e000
+#define NV30_3D_RC_FINAL0_B_INPUT__MASK                                0x000f0000
+#define NV30_3D_RC_FINAL0_B_INPUT__SHIFT                       16
+#define NV30_3D_RC_FINAL0_B_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_FINAL0_B_INPUT_CONSTANT_COLOR0              0x00010000
+#define NV30_3D_RC_FINAL0_B_INPUT_CONSTANT_COLOR1              0x00020000
+#define NV30_3D_RC_FINAL0_B_INPUT_FOG                          0x00030000
+#define NV30_3D_RC_FINAL0_B_INPUT_PRIMARY_COLOR                        0x00040000
+#define NV30_3D_RC_FINAL0_B_INPUT_SECONDARY_COLOR              0x00050000
+#define NV30_3D_RC_FINAL0_B_INPUT_TEXTURE0                     0x00080000
+#define NV30_3D_RC_FINAL0_B_INPUT_TEXTURE1                     0x00090000
+#define NV30_3D_RC_FINAL0_B_INPUT_TEXTURE2                     0x000a0000
+#define NV30_3D_RC_FINAL0_B_INPUT_TEXTURE3                     0x000b0000
+#define NV30_3D_RC_FINAL0_B_INPUT_SPARE0                       0x000c0000
+#define NV30_3D_RC_FINAL0_B_INPUT_SPARE1                       0x000d0000
+#define NV30_3D_RC_FINAL0_B_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x000e0000
+#define NV30_3D_RC_FINAL0_B_INPUT_E_TIMES_F                    0x000f0000
+#define NV30_3D_RC_FINAL0_B_COMPONENT_USAGE__MASK              0x00100000
+#define NV30_3D_RC_FINAL0_B_COMPONENT_USAGE__SHIFT             20
+#define NV30_3D_RC_FINAL0_B_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_FINAL0_B_COMPONENT_USAGE_ALPHA              0x00100000
+#define NV30_3D_RC_FINAL0_B_MAPPING__MASK                      0x00e00000
+#define NV30_3D_RC_FINAL0_B_MAPPING__SHIFT                     21
+#define NV30_3D_RC_FINAL0_B_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_FINAL0_B_MAPPING_UNSIGNED_INVERT            0x00200000
+#define NV30_3D_RC_FINAL0_B_MAPPING_EXPAND_NORMAL              0x00400000
+#define NV30_3D_RC_FINAL0_B_MAPPING_EXPAND_NEGATE              0x00600000
+#define NV30_3D_RC_FINAL0_B_MAPPING_HALF_BIAS_NORMAL           0x00800000
+#define NV30_3D_RC_FINAL0_B_MAPPING_HALF_BIAS_NEGATE           0x00a00000
+#define NV30_3D_RC_FINAL0_B_MAPPING_SIGNED_IDENTITY            0x00c00000
+#define NV30_3D_RC_FINAL0_B_MAPPING_SIGNED_NEGATE              0x00e00000
+#define NV30_3D_RC_FINAL0_A_INPUT__MASK                                0x0f000000
+#define NV30_3D_RC_FINAL0_A_INPUT__SHIFT                       24
+#define NV30_3D_RC_FINAL0_A_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_FINAL0_A_INPUT_CONSTANT_COLOR0              0x01000000
+#define NV30_3D_RC_FINAL0_A_INPUT_CONSTANT_COLOR1              0x02000000
+#define NV30_3D_RC_FINAL0_A_INPUT_FOG                          0x03000000
+#define NV30_3D_RC_FINAL0_A_INPUT_PRIMARY_COLOR                        0x04000000
+#define NV30_3D_RC_FINAL0_A_INPUT_SECONDARY_COLOR              0x05000000
+#define NV30_3D_RC_FINAL0_A_INPUT_TEXTURE0                     0x08000000
+#define NV30_3D_RC_FINAL0_A_INPUT_TEXTURE1                     0x09000000
+#define NV30_3D_RC_FINAL0_A_INPUT_TEXTURE2                     0x0a000000
+#define NV30_3D_RC_FINAL0_A_INPUT_TEXTURE3                     0x0b000000
+#define NV30_3D_RC_FINAL0_A_INPUT_SPARE0                       0x0c000000
+#define NV30_3D_RC_FINAL0_A_INPUT_SPARE1                       0x0d000000
+#define NV30_3D_RC_FINAL0_A_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x0e000000
+#define NV30_3D_RC_FINAL0_A_INPUT_E_TIMES_F                    0x0f000000
+#define NV30_3D_RC_FINAL0_A_COMPONENT_USAGE__MASK              0x10000000
+#define NV30_3D_RC_FINAL0_A_COMPONENT_USAGE__SHIFT             28
+#define NV30_3D_RC_FINAL0_A_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_FINAL0_A_COMPONENT_USAGE_ALPHA              0x10000000
+#define NV30_3D_RC_FINAL0_A_MAPPING__MASK                      0xe0000000
+#define NV30_3D_RC_FINAL0_A_MAPPING__SHIFT                     29
+#define NV30_3D_RC_FINAL0_A_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_FINAL0_A_MAPPING_UNSIGNED_INVERT            0x20000000
+#define NV30_3D_RC_FINAL0_A_MAPPING_EXPAND_NORMAL              0x40000000
+#define NV30_3D_RC_FINAL0_A_MAPPING_EXPAND_NEGATE              0x60000000
+#define NV30_3D_RC_FINAL0_A_MAPPING_HALF_BIAS_NORMAL           0x80000000
+#define NV30_3D_RC_FINAL0_A_MAPPING_HALF_BIAS_NEGATE           0xa0000000
+#define NV30_3D_RC_FINAL0_A_MAPPING_SIGNED_IDENTITY            0xc0000000
+#define NV30_3D_RC_FINAL0_A_MAPPING_SIGNED_NEGATE              0xe0000000
+
+#define NV30_3D_RC_FINAL1                                      0x000008f8
+#define NV30_3D_RC_FINAL1_COLOR_SUM_CLAMP                      0x00000080
+#define NV30_3D_RC_FINAL1_G_INPUT__MASK                                0x00000f00
+#define NV30_3D_RC_FINAL1_G_INPUT__SHIFT                       8
+#define NV30_3D_RC_FINAL1_G_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_FINAL1_G_INPUT_CONSTANT_COLOR0              0x00000100
+#define NV30_3D_RC_FINAL1_G_INPUT_CONSTANT_COLOR1              0x00000200
+#define NV30_3D_RC_FINAL1_G_INPUT_FOG                          0x00000300
+#define NV30_3D_RC_FINAL1_G_INPUT_PRIMARY_COLOR                        0x00000400
+#define NV30_3D_RC_FINAL1_G_INPUT_SECONDARY_COLOR              0x00000500
+#define NV30_3D_RC_FINAL1_G_INPUT_TEXTURE0                     0x00000800
+#define NV30_3D_RC_FINAL1_G_INPUT_TEXTURE1                     0x00000900
+#define NV30_3D_RC_FINAL1_G_INPUT_TEXTURE2                     0x00000a00
+#define NV30_3D_RC_FINAL1_G_INPUT_TEXTURE3                     0x00000b00
+#define NV30_3D_RC_FINAL1_G_INPUT_SPARE0                       0x00000c00
+#define NV30_3D_RC_FINAL1_G_INPUT_SPARE1                       0x00000d00
+#define NV30_3D_RC_FINAL1_G_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x00000e00
+#define NV30_3D_RC_FINAL1_G_INPUT_E_TIMES_F                    0x00000f00
+#define NV30_3D_RC_FINAL1_G_COMPONENT_USAGE__MASK              0x00001000
+#define NV30_3D_RC_FINAL1_G_COMPONENT_USAGE__SHIFT             12
+#define NV30_3D_RC_FINAL1_G_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_FINAL1_G_COMPONENT_USAGE_ALPHA              0x00001000
+#define NV30_3D_RC_FINAL1_G_MAPPING__MASK                      0x0000e000
+#define NV30_3D_RC_FINAL1_G_MAPPING__SHIFT                     13
+#define NV30_3D_RC_FINAL1_G_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_FINAL1_G_MAPPING_UNSIGNED_INVERT            0x00002000
+#define NV30_3D_RC_FINAL1_G_MAPPING_EXPAND_NORMAL              0x00004000
+#define NV30_3D_RC_FINAL1_G_MAPPING_EXPAND_NEGATE              0x00006000
+#define NV30_3D_RC_FINAL1_G_MAPPING_HALF_BIAS_NORMAL           0x00008000
+#define NV30_3D_RC_FINAL1_G_MAPPING_HALF_BIAS_NEGATE           0x0000a000
+#define NV30_3D_RC_FINAL1_G_MAPPING_SIGNED_IDENTITY            0x0000c000
+#define NV30_3D_RC_FINAL1_G_MAPPING_SIGNED_NEGATE              0x0000e000
+#define NV30_3D_RC_FINAL1_F_INPUT__MASK                                0x000f0000
+#define NV30_3D_RC_FINAL1_F_INPUT__SHIFT                       16
+#define NV30_3D_RC_FINAL1_F_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_FINAL1_F_INPUT_CONSTANT_COLOR0              0x00010000
+#define NV30_3D_RC_FINAL1_F_INPUT_CONSTANT_COLOR1              0x00020000
+#define NV30_3D_RC_FINAL1_F_INPUT_FOG                          0x00030000
+#define NV30_3D_RC_FINAL1_F_INPUT_PRIMARY_COLOR                        0x00040000
+#define NV30_3D_RC_FINAL1_F_INPUT_SECONDARY_COLOR              0x00050000
+#define NV30_3D_RC_FINAL1_F_INPUT_TEXTURE0                     0x00080000
+#define NV30_3D_RC_FINAL1_F_INPUT_TEXTURE1                     0x00090000
+#define NV30_3D_RC_FINAL1_F_INPUT_TEXTURE2                     0x000a0000
+#define NV30_3D_RC_FINAL1_F_INPUT_TEXTURE3                     0x000b0000
+#define NV30_3D_RC_FINAL1_F_INPUT_SPARE0                       0x000c0000
+#define NV30_3D_RC_FINAL1_F_INPUT_SPARE1                       0x000d0000
+#define NV30_3D_RC_FINAL1_F_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x000e0000
+#define NV30_3D_RC_FINAL1_F_INPUT_E_TIMES_F                    0x000f0000
+#define NV30_3D_RC_FINAL1_F_COMPONENT_USAGE__MASK              0x00100000
+#define NV30_3D_RC_FINAL1_F_COMPONENT_USAGE__SHIFT             20
+#define NV30_3D_RC_FINAL1_F_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_FINAL1_F_COMPONENT_USAGE_ALPHA              0x00100000
+#define NV30_3D_RC_FINAL1_F_MAPPING__MASK                      0x00e00000
+#define NV30_3D_RC_FINAL1_F_MAPPING__SHIFT                     21
+#define NV30_3D_RC_FINAL1_F_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_FINAL1_F_MAPPING_UNSIGNED_INVERT            0x00200000
+#define NV30_3D_RC_FINAL1_F_MAPPING_EXPAND_NORMAL              0x00400000
+#define NV30_3D_RC_FINAL1_F_MAPPING_EXPAND_NEGATE              0x00600000
+#define NV30_3D_RC_FINAL1_F_MAPPING_HALF_BIAS_NORMAL           0x00800000
+#define NV30_3D_RC_FINAL1_F_MAPPING_HALF_BIAS_NEGATE           0x00a00000
+#define NV30_3D_RC_FINAL1_F_MAPPING_SIGNED_IDENTITY            0x00c00000
+#define NV30_3D_RC_FINAL1_F_MAPPING_SIGNED_NEGATE              0x00e00000
+#define NV30_3D_RC_FINAL1_E_INPUT__MASK                                0x0f000000
+#define NV30_3D_RC_FINAL1_E_INPUT__SHIFT                       24
+#define NV30_3D_RC_FINAL1_E_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_FINAL1_E_INPUT_CONSTANT_COLOR0              0x01000000
+#define NV30_3D_RC_FINAL1_E_INPUT_CONSTANT_COLOR1              0x02000000
+#define NV30_3D_RC_FINAL1_E_INPUT_FOG                          0x03000000
+#define NV30_3D_RC_FINAL1_E_INPUT_PRIMARY_COLOR                        0x04000000
+#define NV30_3D_RC_FINAL1_E_INPUT_SECONDARY_COLOR              0x05000000
+#define NV30_3D_RC_FINAL1_E_INPUT_TEXTURE0                     0x08000000
+#define NV30_3D_RC_FINAL1_E_INPUT_TEXTURE1                     0x09000000
+#define NV30_3D_RC_FINAL1_E_INPUT_TEXTURE2                     0x0a000000
+#define NV30_3D_RC_FINAL1_E_INPUT_TEXTURE3                     0x0b000000
+#define NV30_3D_RC_FINAL1_E_INPUT_SPARE0                       0x0c000000
+#define NV30_3D_RC_FINAL1_E_INPUT_SPARE1                       0x0d000000
+#define NV30_3D_RC_FINAL1_E_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x0e000000
+#define NV30_3D_RC_FINAL1_E_INPUT_E_TIMES_F                    0x0f000000
+#define NV30_3D_RC_FINAL1_E_COMPONENT_USAGE__MASK              0x10000000
+#define NV30_3D_RC_FINAL1_E_COMPONENT_USAGE__SHIFT             28
+#define NV30_3D_RC_FINAL1_E_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_FINAL1_E_COMPONENT_USAGE_ALPHA              0x10000000
+#define NV30_3D_RC_FINAL1_E_MAPPING__MASK                      0xe0000000
+#define NV30_3D_RC_FINAL1_E_MAPPING__SHIFT                     29
+#define NV30_3D_RC_FINAL1_E_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_FINAL1_E_MAPPING_UNSIGNED_INVERT            0x20000000
+#define NV30_3D_RC_FINAL1_E_MAPPING_EXPAND_NORMAL              0x40000000
+#define NV30_3D_RC_FINAL1_E_MAPPING_EXPAND_NEGATE              0x60000000
+#define NV30_3D_RC_FINAL1_E_MAPPING_HALF_BIAS_NORMAL           0x80000000
+#define NV30_3D_RC_FINAL1_E_MAPPING_HALF_BIAS_NEGATE           0xa0000000
+#define NV30_3D_RC_FINAL1_E_MAPPING_SIGNED_IDENTITY            0xc0000000
+#define NV30_3D_RC_FINAL1_E_MAPPING_SIGNED_NEGATE              0xe0000000
+
+#define NV30_3D_RC_ENABLE                                      0x000008fc
+#define NV30_3D_RC_ENABLE_NUM_COMBINERS__MASK                  0x0000000f
+#define NV30_3D_RC_ENABLE_NUM_COMBINERS__SHIFT                 0
+#define NV30_3D_RC_ENABLE_STAGE_CONSTANT_COLOR0                        0x0000f000
+#define NV30_3D_RC_ENABLE_STAGE_CONSTANT_COLOR1                        0x000f0000
+
+
+#define NV30_3D_RC_IN_ALPHA(i0)                                       (0x00000900 + 0x20*(i0))
+#define NV30_3D_RC_IN_ALPHA_D_INPUT__MASK                      0x0000000f
+#define NV30_3D_RC_IN_ALPHA_D_INPUT__SHIFT                     0
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_ZERO                       0x00000000
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_CONSTANT_COLOR0            0x00000001
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_CONSTANT_COLOR1            0x00000002
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_FOG                                0x00000003
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_PRIMARY_COLOR              0x00000004
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_SECONDARY_COLOR            0x00000005
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_TEXTURE0                   0x00000008
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_TEXTURE1                   0x00000009
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_TEXTURE2                   0x0000000a
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_TEXTURE3                   0x0000000b
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_SPARE0                     0x0000000c
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_SPARE1                     0x0000000d
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_SPARE0_PLUS_SECONDARY_COLOR        0x0000000e
+#define NV30_3D_RC_IN_ALPHA_D_INPUT_E_TIMES_F                  0x0000000f
+#define NV30_3D_RC_IN_ALPHA_D_COMPONENT_USAGE__MASK            0x00000010
+#define NV30_3D_RC_IN_ALPHA_D_COMPONENT_USAGE__SHIFT           4
+#define NV30_3D_RC_IN_ALPHA_D_COMPONENT_USAGE_BLUE             0x00000000
+#define NV30_3D_RC_IN_ALPHA_D_COMPONENT_USAGE_ALPHA            0x00000010
+#define NV30_3D_RC_IN_ALPHA_D_MAPPING__MASK                    0x000000e0
+#define NV30_3D_RC_IN_ALPHA_D_MAPPING__SHIFT                   5
+#define NV30_3D_RC_IN_ALPHA_D_MAPPING_UNSIGNED_IDENTITY                0x00000000
+#define NV30_3D_RC_IN_ALPHA_D_MAPPING_UNSIGNED_INVERT          0x00000020
+#define NV30_3D_RC_IN_ALPHA_D_MAPPING_EXPAND_NORMAL            0x00000040
+#define NV30_3D_RC_IN_ALPHA_D_MAPPING_EXPAND_NEGATE            0x00000060
+#define NV30_3D_RC_IN_ALPHA_D_MAPPING_HALF_BIAS_NORMAL         0x00000080
+#define NV30_3D_RC_IN_ALPHA_D_MAPPING_HALF_BIAS_NEGATE         0x000000a0
+#define NV30_3D_RC_IN_ALPHA_D_MAPPING_SIGNED_IDENTITY          0x000000c0
+#define NV30_3D_RC_IN_ALPHA_D_MAPPING_SIGNED_NEGATE            0x000000e0
+#define NV30_3D_RC_IN_ALPHA_C_INPUT__MASK                      0x00000f00
+#define NV30_3D_RC_IN_ALPHA_C_INPUT__SHIFT                     8
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_ZERO                       0x00000000
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_CONSTANT_COLOR0            0x00000100
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_CONSTANT_COLOR1            0x00000200
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_FOG                                0x00000300
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_PRIMARY_COLOR              0x00000400
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_SECONDARY_COLOR            0x00000500
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_TEXTURE0                   0x00000800
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_TEXTURE1                   0x00000900
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_TEXTURE2                   0x00000a00
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_TEXTURE3                   0x00000b00
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_SPARE0                     0x00000c00
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_SPARE1                     0x00000d00
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_SPARE0_PLUS_SECONDARY_COLOR        0x00000e00
+#define NV30_3D_RC_IN_ALPHA_C_INPUT_E_TIMES_F                  0x00000f00
+#define NV30_3D_RC_IN_ALPHA_C_COMPONENT_USAGE__MASK            0x00001000
+#define NV30_3D_RC_IN_ALPHA_C_COMPONENT_USAGE__SHIFT           12
+#define NV30_3D_RC_IN_ALPHA_C_COMPONENT_USAGE_BLUE             0x00000000
+#define NV30_3D_RC_IN_ALPHA_C_COMPONENT_USAGE_ALPHA            0x00001000
+#define NV30_3D_RC_IN_ALPHA_C_MAPPING__MASK                    0x0000e000
+#define NV30_3D_RC_IN_ALPHA_C_MAPPING__SHIFT                   13
+#define NV30_3D_RC_IN_ALPHA_C_MAPPING_UNSIGNED_IDENTITY                0x00000000
+#define NV30_3D_RC_IN_ALPHA_C_MAPPING_UNSIGNED_INVERT          0x00002000
+#define NV30_3D_RC_IN_ALPHA_C_MAPPING_EXPAND_NORMAL            0x00004000
+#define NV30_3D_RC_IN_ALPHA_C_MAPPING_EXPAND_NEGATE            0x00006000
+#define NV30_3D_RC_IN_ALPHA_C_MAPPING_HALF_BIAS_NORMAL         0x00008000
+#define NV30_3D_RC_IN_ALPHA_C_MAPPING_HALF_BIAS_NEGATE         0x0000a000
+#define NV30_3D_RC_IN_ALPHA_C_MAPPING_SIGNED_IDENTITY          0x0000c000
+#define NV30_3D_RC_IN_ALPHA_C_MAPPING_SIGNED_NEGATE            0x0000e000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT__MASK                      0x000f0000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT__SHIFT                     16
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_ZERO                       0x00000000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_CONSTANT_COLOR0            0x00010000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_CONSTANT_COLOR1            0x00020000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_FOG                                0x00030000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_PRIMARY_COLOR              0x00040000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_SECONDARY_COLOR            0x00050000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_TEXTURE0                   0x00080000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_TEXTURE1                   0x00090000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_TEXTURE2                   0x000a0000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_TEXTURE3                   0x000b0000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_SPARE0                     0x000c0000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_SPARE1                     0x000d0000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_SPARE0_PLUS_SECONDARY_COLOR        0x000e0000
+#define NV30_3D_RC_IN_ALPHA_B_INPUT_E_TIMES_F                  0x000f0000
+#define NV30_3D_RC_IN_ALPHA_B_COMPONENT_USAGE__MASK            0x00100000
+#define NV30_3D_RC_IN_ALPHA_B_COMPONENT_USAGE__SHIFT           20
+#define NV30_3D_RC_IN_ALPHA_B_COMPONENT_USAGE_BLUE             0x00000000
+#define NV30_3D_RC_IN_ALPHA_B_COMPONENT_USAGE_ALPHA            0x00100000
+#define NV30_3D_RC_IN_ALPHA_B_MAPPING__MASK                    0x00e00000
+#define NV30_3D_RC_IN_ALPHA_B_MAPPING__SHIFT                   21
+#define NV30_3D_RC_IN_ALPHA_B_MAPPING_UNSIGNED_IDENTITY                0x00000000
+#define NV30_3D_RC_IN_ALPHA_B_MAPPING_UNSIGNED_INVERT          0x00200000
+#define NV30_3D_RC_IN_ALPHA_B_MAPPING_EXPAND_NORMAL            0x00400000
+#define NV30_3D_RC_IN_ALPHA_B_MAPPING_EXPAND_NEGATE            0x00600000
+#define NV30_3D_RC_IN_ALPHA_B_MAPPING_HALF_BIAS_NORMAL         0x00800000
+#define NV30_3D_RC_IN_ALPHA_B_MAPPING_HALF_BIAS_NEGATE         0x00a00000
+#define NV30_3D_RC_IN_ALPHA_B_MAPPING_SIGNED_IDENTITY          0x00c00000
+#define NV30_3D_RC_IN_ALPHA_B_MAPPING_SIGNED_NEGATE            0x00e00000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT__MASK                      0x0f000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT__SHIFT                     24
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_ZERO                       0x00000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_CONSTANT_COLOR0            0x01000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_CONSTANT_COLOR1            0x02000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_FOG                                0x03000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_PRIMARY_COLOR              0x04000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_SECONDARY_COLOR            0x05000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_TEXTURE0                   0x08000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_TEXTURE1                   0x09000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_TEXTURE2                   0x0a000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_TEXTURE3                   0x0b000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_SPARE0                     0x0c000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_SPARE1                     0x0d000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_SPARE0_PLUS_SECONDARY_COLOR        0x0e000000
+#define NV30_3D_RC_IN_ALPHA_A_INPUT_E_TIMES_F                  0x0f000000
+#define NV30_3D_RC_IN_ALPHA_A_COMPONENT_USAGE__MASK            0x10000000
+#define NV30_3D_RC_IN_ALPHA_A_COMPONENT_USAGE__SHIFT           28
+#define NV30_3D_RC_IN_ALPHA_A_COMPONENT_USAGE_BLUE             0x00000000
+#define NV30_3D_RC_IN_ALPHA_A_COMPONENT_USAGE_ALPHA            0x10000000
+#define NV30_3D_RC_IN_ALPHA_A_MAPPING__MASK                    0xe0000000
+#define NV30_3D_RC_IN_ALPHA_A_MAPPING__SHIFT                   29
+#define NV30_3D_RC_IN_ALPHA_A_MAPPING_UNSIGNED_IDENTITY                0x00000000
+#define NV30_3D_RC_IN_ALPHA_A_MAPPING_UNSIGNED_INVERT          0x20000000
+#define NV30_3D_RC_IN_ALPHA_A_MAPPING_EXPAND_NORMAL            0x40000000
+#define NV30_3D_RC_IN_ALPHA_A_MAPPING_EXPAND_NEGATE            0x60000000
+#define NV30_3D_RC_IN_ALPHA_A_MAPPING_HALF_BIAS_NORMAL         0x80000000
+#define NV30_3D_RC_IN_ALPHA_A_MAPPING_HALF_BIAS_NEGATE         0xa0000000
+#define NV30_3D_RC_IN_ALPHA_A_MAPPING_SIGNED_IDENTITY          0xc0000000
+#define NV30_3D_RC_IN_ALPHA_A_MAPPING_SIGNED_NEGATE            0xe0000000
+
+#define NV30_3D_RC_IN_RGB(i0)                                 (0x00000904 + 0x20*(i0))
+#define NV30_3D_RC_IN_RGB_D_INPUT__MASK                                0x0000000f
+#define NV30_3D_RC_IN_RGB_D_INPUT__SHIFT                       0
+#define NV30_3D_RC_IN_RGB_D_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_IN_RGB_D_INPUT_CONSTANT_COLOR0              0x00000001
+#define NV30_3D_RC_IN_RGB_D_INPUT_CONSTANT_COLOR1              0x00000002
+#define NV30_3D_RC_IN_RGB_D_INPUT_FOG                          0x00000003
+#define NV30_3D_RC_IN_RGB_D_INPUT_PRIMARY_COLOR                        0x00000004
+#define NV30_3D_RC_IN_RGB_D_INPUT_SECONDARY_COLOR              0x00000005
+#define NV30_3D_RC_IN_RGB_D_INPUT_TEXTURE0                     0x00000008
+#define NV30_3D_RC_IN_RGB_D_INPUT_TEXTURE1                     0x00000009
+#define NV30_3D_RC_IN_RGB_D_INPUT_TEXTURE2                     0x0000000a
+#define NV30_3D_RC_IN_RGB_D_INPUT_TEXTURE3                     0x0000000b
+#define NV30_3D_RC_IN_RGB_D_INPUT_SPARE0                       0x0000000c
+#define NV30_3D_RC_IN_RGB_D_INPUT_SPARE1                       0x0000000d
+#define NV30_3D_RC_IN_RGB_D_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x0000000e
+#define NV30_3D_RC_IN_RGB_D_INPUT_E_TIMES_F                    0x0000000f
+#define NV30_3D_RC_IN_RGB_D_COMPONENT_USAGE__MASK              0x00000010
+#define NV30_3D_RC_IN_RGB_D_COMPONENT_USAGE__SHIFT             4
+#define NV30_3D_RC_IN_RGB_D_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_IN_RGB_D_COMPONENT_USAGE_ALPHA              0x00000010
+#define NV30_3D_RC_IN_RGB_D_MAPPING__MASK                      0x000000e0
+#define NV30_3D_RC_IN_RGB_D_MAPPING__SHIFT                     5
+#define NV30_3D_RC_IN_RGB_D_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_IN_RGB_D_MAPPING_UNSIGNED_INVERT            0x00000020
+#define NV30_3D_RC_IN_RGB_D_MAPPING_EXPAND_NORMAL              0x00000040
+#define NV30_3D_RC_IN_RGB_D_MAPPING_EXPAND_NEGATE              0x00000060
+#define NV30_3D_RC_IN_RGB_D_MAPPING_HALF_BIAS_NORMAL           0x00000080
+#define NV30_3D_RC_IN_RGB_D_MAPPING_HALF_BIAS_NEGATE           0x000000a0
+#define NV30_3D_RC_IN_RGB_D_MAPPING_SIGNED_IDENTITY            0x000000c0
+#define NV30_3D_RC_IN_RGB_D_MAPPING_SIGNED_NEGATE              0x000000e0
+#define NV30_3D_RC_IN_RGB_C_INPUT__MASK                                0x00000f00
+#define NV30_3D_RC_IN_RGB_C_INPUT__SHIFT                       8
+#define NV30_3D_RC_IN_RGB_C_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_IN_RGB_C_INPUT_CONSTANT_COLOR0              0x00000100
+#define NV30_3D_RC_IN_RGB_C_INPUT_CONSTANT_COLOR1              0x00000200
+#define NV30_3D_RC_IN_RGB_C_INPUT_FOG                          0x00000300
+#define NV30_3D_RC_IN_RGB_C_INPUT_PRIMARY_COLOR                        0x00000400
+#define NV30_3D_RC_IN_RGB_C_INPUT_SECONDARY_COLOR              0x00000500
+#define NV30_3D_RC_IN_RGB_C_INPUT_TEXTURE0                     0x00000800
+#define NV30_3D_RC_IN_RGB_C_INPUT_TEXTURE1                     0x00000900
+#define NV30_3D_RC_IN_RGB_C_INPUT_TEXTURE2                     0x00000a00
+#define NV30_3D_RC_IN_RGB_C_INPUT_TEXTURE3                     0x00000b00
+#define NV30_3D_RC_IN_RGB_C_INPUT_SPARE0                       0x00000c00
+#define NV30_3D_RC_IN_RGB_C_INPUT_SPARE1                       0x00000d00
+#define NV30_3D_RC_IN_RGB_C_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x00000e00
+#define NV30_3D_RC_IN_RGB_C_INPUT_E_TIMES_F                    0x00000f00
+#define NV30_3D_RC_IN_RGB_C_COMPONENT_USAGE__MASK              0x00001000
+#define NV30_3D_RC_IN_RGB_C_COMPONENT_USAGE__SHIFT             12
+#define NV30_3D_RC_IN_RGB_C_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_IN_RGB_C_COMPONENT_USAGE_ALPHA              0x00001000
+#define NV30_3D_RC_IN_RGB_C_MAPPING__MASK                      0x0000e000
+#define NV30_3D_RC_IN_RGB_C_MAPPING__SHIFT                     13
+#define NV30_3D_RC_IN_RGB_C_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_IN_RGB_C_MAPPING_UNSIGNED_INVERT            0x00002000
+#define NV30_3D_RC_IN_RGB_C_MAPPING_EXPAND_NORMAL              0x00004000
+#define NV30_3D_RC_IN_RGB_C_MAPPING_EXPAND_NEGATE              0x00006000
+#define NV30_3D_RC_IN_RGB_C_MAPPING_HALF_BIAS_NORMAL           0x00008000
+#define NV30_3D_RC_IN_RGB_C_MAPPING_HALF_BIAS_NEGATE           0x0000a000
+#define NV30_3D_RC_IN_RGB_C_MAPPING_SIGNED_IDENTITY            0x0000c000
+#define NV30_3D_RC_IN_RGB_C_MAPPING_SIGNED_NEGATE              0x0000e000
+#define NV30_3D_RC_IN_RGB_B_INPUT__MASK                                0x000f0000
+#define NV30_3D_RC_IN_RGB_B_INPUT__SHIFT                       16
+#define NV30_3D_RC_IN_RGB_B_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_IN_RGB_B_INPUT_CONSTANT_COLOR0              0x00010000
+#define NV30_3D_RC_IN_RGB_B_INPUT_CONSTANT_COLOR1              0x00020000
+#define NV30_3D_RC_IN_RGB_B_INPUT_FOG                          0x00030000
+#define NV30_3D_RC_IN_RGB_B_INPUT_PRIMARY_COLOR                        0x00040000
+#define NV30_3D_RC_IN_RGB_B_INPUT_SECONDARY_COLOR              0x00050000
+#define NV30_3D_RC_IN_RGB_B_INPUT_TEXTURE0                     0x00080000
+#define NV30_3D_RC_IN_RGB_B_INPUT_TEXTURE1                     0x00090000
+#define NV30_3D_RC_IN_RGB_B_INPUT_TEXTURE2                     0x000a0000
+#define NV30_3D_RC_IN_RGB_B_INPUT_TEXTURE3                     0x000b0000
+#define NV30_3D_RC_IN_RGB_B_INPUT_SPARE0                       0x000c0000
+#define NV30_3D_RC_IN_RGB_B_INPUT_SPARE1                       0x000d0000
+#define NV30_3D_RC_IN_RGB_B_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x000e0000
+#define NV30_3D_RC_IN_RGB_B_INPUT_E_TIMES_F                    0x000f0000
+#define NV30_3D_RC_IN_RGB_B_COMPONENT_USAGE__MASK              0x00100000
+#define NV30_3D_RC_IN_RGB_B_COMPONENT_USAGE__SHIFT             20
+#define NV30_3D_RC_IN_RGB_B_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_IN_RGB_B_COMPONENT_USAGE_ALPHA              0x00100000
+#define NV30_3D_RC_IN_RGB_B_MAPPING__MASK                      0x00e00000
+#define NV30_3D_RC_IN_RGB_B_MAPPING__SHIFT                     21
+#define NV30_3D_RC_IN_RGB_B_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_IN_RGB_B_MAPPING_UNSIGNED_INVERT            0x00200000
+#define NV30_3D_RC_IN_RGB_B_MAPPING_EXPAND_NORMAL              0x00400000
+#define NV30_3D_RC_IN_RGB_B_MAPPING_EXPAND_NEGATE              0x00600000
+#define NV30_3D_RC_IN_RGB_B_MAPPING_HALF_BIAS_NORMAL           0x00800000
+#define NV30_3D_RC_IN_RGB_B_MAPPING_HALF_BIAS_NEGATE           0x00a00000
+#define NV30_3D_RC_IN_RGB_B_MAPPING_SIGNED_IDENTITY            0x00c00000
+#define NV30_3D_RC_IN_RGB_B_MAPPING_SIGNED_NEGATE              0x00e00000
+#define NV30_3D_RC_IN_RGB_A_INPUT__MASK                                0x0f000000
+#define NV30_3D_RC_IN_RGB_A_INPUT__SHIFT                       24
+#define NV30_3D_RC_IN_RGB_A_INPUT_ZERO                         0x00000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_CONSTANT_COLOR0              0x01000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_CONSTANT_COLOR1              0x02000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_FOG                          0x03000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_PRIMARY_COLOR                        0x04000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_SECONDARY_COLOR              0x05000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_TEXTURE0                     0x08000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_TEXTURE1                     0x09000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_TEXTURE2                     0x0a000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_TEXTURE3                     0x0b000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_SPARE0                       0x0c000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_SPARE1                       0x0d000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_SPARE0_PLUS_SECONDARY_COLOR  0x0e000000
+#define NV30_3D_RC_IN_RGB_A_INPUT_E_TIMES_F                    0x0f000000
+#define NV30_3D_RC_IN_RGB_A_COMPONENT_USAGE__MASK              0x10000000
+#define NV30_3D_RC_IN_RGB_A_COMPONENT_USAGE__SHIFT             28
+#define NV30_3D_RC_IN_RGB_A_COMPONENT_USAGE_RGB                        0x00000000
+#define NV30_3D_RC_IN_RGB_A_COMPONENT_USAGE_ALPHA              0x10000000
+#define NV30_3D_RC_IN_RGB_A_MAPPING__MASK                      0xe0000000
+#define NV30_3D_RC_IN_RGB_A_MAPPING__SHIFT                     29
+#define NV30_3D_RC_IN_RGB_A_MAPPING_UNSIGNED_IDENTITY          0x00000000
+#define NV30_3D_RC_IN_RGB_A_MAPPING_UNSIGNED_INVERT            0x20000000
+#define NV30_3D_RC_IN_RGB_A_MAPPING_EXPAND_NORMAL              0x40000000
+#define NV30_3D_RC_IN_RGB_A_MAPPING_EXPAND_NEGATE              0x60000000
+#define NV30_3D_RC_IN_RGB_A_MAPPING_HALF_BIAS_NORMAL           0x80000000
+#define NV30_3D_RC_IN_RGB_A_MAPPING_HALF_BIAS_NEGATE           0xa0000000
+#define NV30_3D_RC_IN_RGB_A_MAPPING_SIGNED_IDENTITY            0xc0000000
+#define NV30_3D_RC_IN_RGB_A_MAPPING_SIGNED_NEGATE              0xe0000000
+
+#define NV30_3D_RC_CONSTANT_COLOR0(i0)                        (0x00000908 + 0x20*(i0))
+#define NV30_3D_RC_CONSTANT_COLOR0_B__MASK                     0x000000ff
+#define NV30_3D_RC_CONSTANT_COLOR0_B__SHIFT                    0
+#define NV30_3D_RC_CONSTANT_COLOR0_G__MASK                     0x0000ff00
+#define NV30_3D_RC_CONSTANT_COLOR0_G__SHIFT                    8
+#define NV30_3D_RC_CONSTANT_COLOR0_R__MASK                     0x00ff0000
+#define NV30_3D_RC_CONSTANT_COLOR0_R__SHIFT                    16
+#define NV30_3D_RC_CONSTANT_COLOR0_A__MASK                     0xff000000
+#define NV30_3D_RC_CONSTANT_COLOR0_A__SHIFT                    24
+
+#define NV30_3D_RC_CONSTANT_COLOR1(i0)                        (0x0000090c + 0x20*(i0))
+#define NV30_3D_RC_CONSTANT_COLOR1_B__MASK                     0x000000ff
+#define NV30_3D_RC_CONSTANT_COLOR1_B__SHIFT                    0
+#define NV30_3D_RC_CONSTANT_COLOR1_G__MASK                     0x0000ff00
+#define NV30_3D_RC_CONSTANT_COLOR1_G__SHIFT                    8
+#define NV30_3D_RC_CONSTANT_COLOR1_R__MASK                     0x00ff0000
+#define NV30_3D_RC_CONSTANT_COLOR1_R__SHIFT                    16
+#define NV30_3D_RC_CONSTANT_COLOR1_A__MASK                     0xff000000
+#define NV30_3D_RC_CONSTANT_COLOR1_A__SHIFT                    24
+
+#define NV30_3D_RC_OUT_ALPHA(i0)                              (0x00000910 + 0x20*(i0))
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT__MASK                   0x0000000f
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT__SHIFT                  0
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_ZERO                    0x00000000
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_CONSTANT_COLOR0         0x00000001
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_CONSTANT_COLOR1         0x00000002
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_FOG                     0x00000003
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_PRIMARY_COLOR           0x00000004
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_SECONDARY_COLOR         0x00000005
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_TEXTURE0                        0x00000008
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_TEXTURE1                        0x00000009
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_TEXTURE2                        0x0000000a
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_TEXTURE3                        0x0000000b
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_SPARE0                  0x0000000c
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_SPARE1                  0x0000000d
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR     0x0000000e
+#define NV30_3D_RC_OUT_ALPHA_CD_OUTPUT_E_TIMES_F               0x0000000f
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT__MASK                   0x000000f0
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT__SHIFT                  4
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_ZERO                    0x00000000
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_CONSTANT_COLOR0         0x00000010
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_CONSTANT_COLOR1         0x00000020
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_FOG                     0x00000030
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_PRIMARY_COLOR           0x00000040
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_SECONDARY_COLOR         0x00000050
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_TEXTURE0                        0x00000080
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_TEXTURE1                        0x00000090
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_TEXTURE2                        0x000000a0
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_TEXTURE3                        0x000000b0
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_SPARE0                  0x000000c0
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_SPARE1                  0x000000d0
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR     0x000000e0
+#define NV30_3D_RC_OUT_ALPHA_AB_OUTPUT_E_TIMES_F               0x000000f0
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT__MASK                  0x00000f00
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT__SHIFT                 8
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_ZERO                   0x00000000
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_CONSTANT_COLOR0                0x00000100
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_CONSTANT_COLOR1                0x00000200
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_FOG                    0x00000300
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_PRIMARY_COLOR          0x00000400
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_SECONDARY_COLOR                0x00000500
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_TEXTURE0               0x00000800
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_TEXTURE1               0x00000900
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_TEXTURE2               0x00000a00
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_TEXTURE3               0x00000b00
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_SPARE0                 0x00000c00
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_SPARE1                 0x00000d00
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR    0x00000e00
+#define NV30_3D_RC_OUT_ALPHA_SUM_OUTPUT_E_TIMES_F              0x00000f00
+#define NV30_3D_RC_OUT_ALPHA_CD_DOT_PRODUCT                    0x00001000
+#define NV30_3D_RC_OUT_ALPHA_AB_DOT_PRODUCT                    0x00002000
+#define NV30_3D_RC_OUT_ALPHA_MUX_SUM                           0x00004000
+#define NV30_3D_RC_OUT_ALPHA_BIAS__MASK                                0x00008000
+#define NV30_3D_RC_OUT_ALPHA_BIAS__SHIFT                       15
+#define NV30_3D_RC_OUT_ALPHA_BIAS_NONE                         0x00000000
+#define NV30_3D_RC_OUT_ALPHA_BIAS_BIAS_BY_NEGATIVE_ONE_HALF    0x00008000
+#define NV30_3D_RC_OUT_ALPHA_SCALE__MASK                       0x00030000
+#define NV30_3D_RC_OUT_ALPHA_SCALE__SHIFT                      16
+#define NV30_3D_RC_OUT_ALPHA_SCALE_NONE                                0x00000000
+#define NV30_3D_RC_OUT_ALPHA_SCALE_SCALE_BY_TWO                        0x00010000
+#define NV30_3D_RC_OUT_ALPHA_SCALE_SCALE_BY_FOUR               0x00020000
+#define NV30_3D_RC_OUT_ALPHA_SCALE_SCALE_BY_ONE_HALF           0x00030000
+
+#define NV30_3D_RC_OUT_RGB(i0)                                (0x00000914 + 0x20*(i0))
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT__MASK                     0x0000000f
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT__SHIFT                    0
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_ZERO                      0x00000000
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_CONSTANT_COLOR0           0x00000001
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_CONSTANT_COLOR1           0x00000002
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_FOG                       0x00000003
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_PRIMARY_COLOR             0x00000004
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_SECONDARY_COLOR           0x00000005
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_TEXTURE0                  0x00000008
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_TEXTURE1                  0x00000009
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_TEXTURE2                  0x0000000a
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_TEXTURE3                  0x0000000b
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_SPARE0                    0x0000000c
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_SPARE1                    0x0000000d
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR       0x0000000e
+#define NV30_3D_RC_OUT_RGB_CD_OUTPUT_E_TIMES_F                 0x0000000f
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT__MASK                     0x000000f0
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT__SHIFT                    4
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_ZERO                      0x00000000
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_CONSTANT_COLOR0           0x00000010
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_CONSTANT_COLOR1           0x00000020
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_FOG                       0x00000030
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_PRIMARY_COLOR             0x00000040
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_SECONDARY_COLOR           0x00000050
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_TEXTURE0                  0x00000080
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_TEXTURE1                  0x00000090
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_TEXTURE2                  0x000000a0
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_TEXTURE3                  0x000000b0
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_SPARE0                    0x000000c0
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_SPARE1                    0x000000d0
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR       0x000000e0
+#define NV30_3D_RC_OUT_RGB_AB_OUTPUT_E_TIMES_F                 0x000000f0
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT__MASK                    0x00000f00
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT__SHIFT                   8
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_ZERO                     0x00000000
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_CONSTANT_COLOR0          0x00000100
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_CONSTANT_COLOR1          0x00000200
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_FOG                      0x00000300
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_PRIMARY_COLOR            0x00000400
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_SECONDARY_COLOR          0x00000500
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_TEXTURE0                 0x00000800
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_TEXTURE1                 0x00000900
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_TEXTURE2                 0x00000a00
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_TEXTURE3                 0x00000b00
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_SPARE0                   0x00000c00
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_SPARE1                   0x00000d00
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR      0x00000e00
+#define NV30_3D_RC_OUT_RGB_SUM_OUTPUT_E_TIMES_F                        0x00000f00
+#define NV30_3D_RC_OUT_RGB_CD_DOT_PRODUCT                      0x00001000
+#define NV30_3D_RC_OUT_RGB_AB_DOT_PRODUCT                      0x00002000
+#define NV30_3D_RC_OUT_RGB_MUX_SUM                             0x00004000
+#define NV30_3D_RC_OUT_RGB_BIAS__MASK                          0x00008000
+#define NV30_3D_RC_OUT_RGB_BIAS__SHIFT                         15
+#define NV30_3D_RC_OUT_RGB_BIAS_NONE                           0x00000000
+#define NV30_3D_RC_OUT_RGB_BIAS_BIAS_BY_NEGATIVE_ONE_HALF      0x00008000
+#define NV30_3D_RC_OUT_RGB_SCALE__MASK                         0x00030000
+#define NV30_3D_RC_OUT_RGB_SCALE__SHIFT                                16
+#define NV30_3D_RC_OUT_RGB_SCALE_NONE                          0x00000000
+#define NV30_3D_RC_OUT_RGB_SCALE_SCALE_BY_TWO                  0x00010000
+#define NV30_3D_RC_OUT_RGB_SCALE_SCALE_BY_FOUR                 0x00020000
+#define NV30_3D_RC_OUT_RGB_SCALE_SCALE_BY_ONE_HALF             0x00030000
+
+#define NV30_3D_VIEWPORT_HORIZ                                 0x00000a00
+#define NV30_3D_VIEWPORT_HORIZ_X__MASK                         0x0000ffff
+#define NV30_3D_VIEWPORT_HORIZ_X__SHIFT                                0
+#define NV30_3D_VIEWPORT_HORIZ_W__MASK                         0xffff0000
+#define NV30_3D_VIEWPORT_HORIZ_W__SHIFT                                16
+
+#define NV30_3D_VIEWPORT_VERT                                  0x00000a04
+#define NV30_3D_VIEWPORT_VERT_Y__MASK                          0x0000ffff
+#define NV30_3D_VIEWPORT_VERT_Y__SHIFT                         0
+#define NV30_3D_VIEWPORT_VERT_H__MASK                          0xffff0000
+#define NV30_3D_VIEWPORT_VERT_H__SHIFT                         16
+
+#define NV30_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION   0x00000a10
+
+
+#define NV30_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x00000a10
+
+#define NV30_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x00000a14
+
+#define NV30_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x00000a18
+
+#define NV30_3D_VIEWPORT_TRANSLATE                             0x00000a20
+
+
+#define NV30_3D_VIEWPORT_TRANSLATE_X                           0x00000a20
+
+#define NV30_3D_VIEWPORT_TRANSLATE_Y                           0x00000a24
+
+#define NV30_3D_VIEWPORT_TRANSLATE_Z                           0x00000a28
+
+#define NV30_3D_VIEWPORT_TRANSLATE_W                           0x00000a2c
+
+#define NV30_3D_VIEWPORT_SCALE                                 0x00000a30
+
+
+#define NV30_3D_VIEWPORT_SCALE_X                               0x00000a30
+
+#define NV30_3D_VIEWPORT_SCALE_Y                               0x00000a34
+
+#define NV30_3D_VIEWPORT_SCALE_Z                               0x00000a38
+
+#define NV30_3D_VIEWPORT_SCALE_W                               0x00000a3c
+
+#define NV30_3D_POLYGON_OFFSET_POINT_ENABLE                    0x00000a60
+
+#define NV30_3D_POLYGON_OFFSET_LINE_ENABLE                     0x00000a64
+
+#define NV30_3D_POLYGON_OFFSET_FILL_ENABLE                     0x00000a68
+
+#define NV30_3D_DEPTH_FUNC                                     0x00000a6c
+#define NV30_3D_DEPTH_FUNC_NEVER                               0x00000200
+#define NV30_3D_DEPTH_FUNC_LESS                                        0x00000201
+#define NV30_3D_DEPTH_FUNC_EQUAL                               0x00000202
+#define NV30_3D_DEPTH_FUNC_LEQUAL                              0x00000203
+#define NV30_3D_DEPTH_FUNC_GREATER                             0x00000204
+#define NV30_3D_DEPTH_FUNC_NOTEQUAL                            0x00000205
+#define NV30_3D_DEPTH_FUNC_GEQUAL                              0x00000206
+#define NV30_3D_DEPTH_FUNC_ALWAYS                              0x00000207
+
+#define NV30_3D_DEPTH_WRITE_ENABLE                             0x00000a70
+
+#define NV30_3D_DEPTH_TEST_ENABLE                              0x00000a74
+
+#define NV30_3D_POLYGON_OFFSET_FACTOR                          0x00000a78
+
+#define NV30_3D_POLYGON_OFFSET_UNITS                           0x00000a7c
+
+#define NV30_3D_VTX_ATTR_3I_XY(i0)                            (0x00000a80 + 0x8*(i0))
+#define NV30_3D_VTX_ATTR_3I_XY__ESIZE                          0x00000008
+#define NV30_3D_VTX_ATTR_3I_XY__LEN                            0x00000010
+#define NV30_3D_VTX_ATTR_3I_XY_X__MASK                         0x0000ffff
+#define NV30_3D_VTX_ATTR_3I_XY_X__SHIFT                                0
+#define NV30_3D_VTX_ATTR_3I_XY_Y__MASK                         0xffff0000
+#define NV30_3D_VTX_ATTR_3I_XY_Y__SHIFT                                16
+
+#define NV30_3D_VTX_ATTR_3I_Z(i0)                             (0x00000a84 + 0x8*(i0))
+#define NV30_3D_VTX_ATTR_3I_Z__ESIZE                           0x00000008
+#define NV30_3D_VTX_ATTR_3I_Z__LEN                             0x00000010
+#define NV30_3D_VTX_ATTR_3I_Z_Z__MASK                          0x0000ffff
+#define NV30_3D_VTX_ATTR_3I_Z_Z__SHIFT                         0
+
+#define NV30_3D_TEX_FILTER_OPTIMIZATION(i0)                   (0x00000b00 + 0x4*(i0))
+#define NV30_3D_TEX_FILTER_OPTIMIZATION__ESIZE                 0x00000004
+#define NV30_3D_TEX_FILTER_OPTIMIZATION__LEN                   0x00000004
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_TRILINEAR__MASK                0x0000001f
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_TRILINEAR__SHIFT       0
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_TRILINEAR_OFF          0x00000000
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_TRILINEAR_HIGH_QUALITY 0x00000004
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_TRILINEAR_QUALITY      0x00000006
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_TRILINEAR_PERFORMANCE  0x00000008
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_TRILINEAR_HIGH_PERFORMANCE     0x00000018
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_ANISO_SAMPLE__MASK     0x000001c0
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_ANISO_SAMPLE__SHIFT    6
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_ANISO_SAMPLE_OFF       0x00000000
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_ANISO_SAMPLE_HIGH_QUALITY      0x000000c0
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_ANISO_SAMPLE_QUALITY   0x000001c0
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_ANISO_SAMPLE_PERFORMANCE       0x00000140
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_UNKNOWN__MASK          0x00007c00
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_UNKNOWN__SHIFT         10
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_UNKNOWN_OFF            0x00000000
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_UNKNOWN_PARTIAL                0x00002c00
+#define NV40_3D_TEX_FILTER_OPTIMIZATION_UNKNOWN_FULL           0x00007c00
+
+#define NV40_3D_UNK0B40(i0)                                   (0x00000b40 + 0x4*(i0))
+#define NV40_3D_UNK0B40__ESIZE                                 0x00000004
+#define NV40_3D_UNK0B40__LEN                                   0x00000008
+
+#define NV30_3D_VP_UPLOAD_INST(i0)                            (0x00000b80 + 0x4*(i0))
+#define NV30_3D_VP_UPLOAD_INST__ESIZE                          0x00000004
+#define NV30_3D_VP_UPLOAD_INST__LEN                            0x00000004
+
+
+#define NV30_3D_TEX_CLIP_PLANE(i0)                            (0x00000e00 + 0x10*(i0))
+
+
+#define NV30_3D_TEX_CLIP_PLANE_X(i0)                          (0x00000e00 + 0x10*(i0))
+
+#define NV30_3D_TEX_CLIP_PLANE_Y(i0)                          (0x00000e04 + 0x10*(i0))
+
+#define NV30_3D_TEX_CLIP_PLANE_Z(i0)                          (0x00000e08 + 0x10*(i0))
+
+#define NV30_3D_TEX_CLIP_PLANE_W(i0)                          (0x00000e0c + 0x10*(i0))
+
+#define NV30_3D_LIGHT                                          0x00001000
+
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT(i0)          (0x00001000 + 0x40*(i0))
+
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(i0)        (0x00001000 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(i0)        (0x00001004 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(i0)        (0x00001008 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE(i0)          (0x0000100c + 0x40*(i0))
+
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(i0)        (0x0000100c + 0x40*(i0))
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(i0)        (0x00001010 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(i0)        (0x00001014 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR(i0)         (0x00001018 + 0x40*(i0))
+
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(i0)               (0x00001018 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(i0)               (0x0000101c + 0x40*(i0))
+
+#define NV30_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(i0)               (0x00001020 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_UNK24(i0)                                       (0x00001024 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_HALF_VECTOR(i0)                         (0x00001028 + 0x40*(i0))
+
+
+#define NV30_3D_LIGHT_HALF_VECTOR_X(i0)                               (0x00001028 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_HALF_VECTOR_Y(i0)                               (0x0000102c + 0x40*(i0))
+
+#define NV30_3D_LIGHT_HALF_VECTOR_Z(i0)                               (0x00001030 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_DIRECTION(i0)                           (0x00001034 + 0x40*(i0))
+
+
+#define NV30_3D_LIGHT_DIRECTION_X(i0)                         (0x00001034 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_DIRECTION_Y(i0)                         (0x00001038 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_DIRECTION_Z(i0)                         (0x0000103c + 0x40*(i0))
+
+
+#define NV30_3D_LIGHT_SPOT_CUTOFF_A(i0)                               (0x00001200 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_SPOT_CUTOFF_B(i0)                               (0x00001204 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_SPOT_CUTOFF_C(i0)                               (0x00001208 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_SPOT_DIR(i0)                            (0x0000120c + 0x40*(i0))
+
+
+#define NV30_3D_LIGHT_SPOT_DIR_X(i0)                          (0x0000120c + 0x40*(i0))
+
+#define NV30_3D_LIGHT_SPOT_DIR_Y(i0)                          (0x00001210 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_SPOT_DIR_Z(i0)                          (0x00001214 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_SPOT_CUTOFF_D(i0)                               (0x00001218 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_POSITION(i0)                            (0x0000121c + 0x40*(i0))
+
+
+#define NV30_3D_LIGHT_POSITION_X(i0)                          (0x0000121c + 0x40*(i0))
+
+#define NV30_3D_LIGHT_POSITION_Y(i0)                          (0x00001220 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_POSITION_Z(i0)                          (0x00001224 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_ATTENUATION(i0)                         (0x00001228 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_ATTENUATION_CONSTANT(i0)                (0x00001228 + 0x40*(i0))
+
+#define NV30_3D_LIGHT_ATTENUATION_LINEAR(i0)                  (0x0000122c + 0x40*(i0))
+
+#define NV30_3D_LIGHT_ATTENUATION_QUADRATIC(i0)                       (0x00001230 + 0x40*(i0))
+
+#define NV30_3D_FRONT_MATERIAL_SHININESS(i0)                  (0x00001400 + 0x4*(i0))
+#define NV30_3D_FRONT_MATERIAL_SHININESS__ESIZE                        0x00000004
+#define NV30_3D_FRONT_MATERIAL_SHININESS__LEN                  0x00000006
+
+#define NV30_3D_ENABLED_LIGHTS                                 0x00001420
+
+#define NV30_3D_VERTEX_TWO_SIDE_ENABLE                         0x0000142c
+
+#define NV30_3D_FP_REG_CONTROL                                 0x00001450
+#define NV30_3D_FP_REG_CONTROL_UNK0__MASK                      0x0000ffff
+#define NV30_3D_FP_REG_CONTROL_UNK0__SHIFT                     0
+#define NV30_3D_FP_REG_CONTROL_UNK1__MASK                      0xffff0000
+#define NV30_3D_FP_REG_CONTROL_UNK1__SHIFT                     16
+
+#define NV30_3D_FLATSHADE_FIRST                                        0x00001454
+
+#define NV30_3D_EDGEFLAG                                       0x0000145c
+#define NV30_3D_EDGEFLAG_ENABLE                                        0x00000001
+
+#define NV30_3D_VP_CLIP_PLANES_ENABLE                          0x00001478
+#define NV30_3D_VP_CLIP_PLANES_ENABLE_PLANE0                   0x00000002
+#define NV30_3D_VP_CLIP_PLANES_ENABLE_PLANE1                   0x00000020
+#define NV30_3D_VP_CLIP_PLANES_ENABLE_PLANE2                   0x00000200
+#define NV30_3D_VP_CLIP_PLANES_ENABLE_PLANE3                   0x00002000
+#define NV30_3D_VP_CLIP_PLANES_ENABLE_PLANE4                   0x00020000
+#define NV30_3D_VP_CLIP_PLANES_ENABLE_PLANE5                   0x00200000
+
+#define NV30_3D_POLYGON_STIPPLE_ENABLE                         0x0000147c
+
+#define NV30_3D_POLYGON_STIPPLE_PATTERN(i0)                   (0x00001480 + 0x4*(i0))
+#define NV30_3D_POLYGON_STIPPLE_PATTERN__ESIZE                 0x00000004
+#define NV30_3D_POLYGON_STIPPLE_PATTERN__LEN                   0x00000020
+
+#define NV30_3D_VTX_ATTR_3F(i0)                                       (0x00001500 + 0x10*(i0))
+#define NV30_3D_VTX_ATTR_3F__ESIZE                             0x00000010
+#define NV30_3D_VTX_ATTR_3F__LEN                               0x00000010
+
+
+#define NV30_3D_VTX_ATTR_3F_X(i0)                             (0x00001500 + 0x10*(i0))
+
+#define NV30_3D_VTX_ATTR_3F_Y(i0)                             (0x00001504 + 0x10*(i0))
+
+#define NV30_3D_VTX_ATTR_3F_Z(i0)                             (0x00001508 + 0x10*(i0))
+
+
+#define NV30_3D_VP_CLIP_PLANE(i0, i1)                         (0x00001600 + 0x10*(i0) + 0x4*(i1))
+#define NV30_3D_VP_CLIP_PLANE__ESIZE                           0x00000004
+#define NV30_3D_VP_CLIP_PLANE__LEN                             0x00000004
+
+#define NV30_3D_VTXBUF(i0)                                    (0x00001680 + 0x4*(i0))
+#define NV30_3D_VTXBUF__ESIZE                                  0x00000004
+#define NV30_3D_VTXBUF__LEN                                    0x00000010
+#define NV30_3D_VTXBUF_OFFSET__MASK                            0x0fffffff
+#define NV30_3D_VTXBUF_OFFSET__SHIFT                           0
+#define NV30_3D_VTXBUF_DMA1                                    0x80000000
+
+#define NV40_3D_VTX_CACHE_INVALIDATE                           0x00001714
+
+#define NV30_3D_VTXFMT(i0)                                    (0x00001740 + 0x4*(i0))
+#define NV30_3D_VTXFMT__ESIZE                                  0x00000004
+#define NV30_3D_VTXFMT__LEN                                    0x00000010
+#define NV30_3D_VTXFMT_TYPE__MASK                              0x0000000f
+#define NV30_3D_VTXFMT_TYPE__SHIFT                             0
+#define NV30_3D_VTXFMT_TYPE_B8G8R8A8_UNORM                     0x00000000
+#define NV30_3D_VTXFMT_TYPE_V16_SNORM                          0x00000001
+#define NV30_3D_VTXFMT_TYPE_V32_FLOAT                          0x00000002
+#define NV30_3D_VTXFMT_TYPE_V16_FLOAT                          0x00000003
+#define NV30_3D_VTXFMT_TYPE_U8_UNORM                           0x00000004
+#define NV30_3D_VTXFMT_TYPE_V16_SSCALED                                0x00000005
+#define NV30_3D_VTXFMT_TYPE_U8_USCALED                         0x00000007
+#define NV30_3D_VTXFMT_SIZE__MASK                              0x000000f0
+#define NV30_3D_VTXFMT_SIZE__SHIFT                             4
+#define NV30_3D_VTXFMT_STRIDE__MASK                            0x0000ff00
+#define NV30_3D_VTXFMT_STRIDE__SHIFT                           8
+
+#define NV30_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION    0x000017a0
+
+
+#define NV30_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R  0x000017a0
+
+#define NV30_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G  0x000017a4
+
+#define NV30_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B  0x000017a8
+
+#define NV30_3D_COLOR_MATERIAL_BACK                            0x000017b0
+
+
+#define NV30_3D_COLOR_MATERIAL_BACK_R                          0x000017b0
+
+#define NV30_3D_COLOR_MATERIAL_BACK_G                          0x000017b4
+
+#define NV30_3D_COLOR_MATERIAL_BACK_B                          0x000017b8
+
+#define NV30_3D_COLOR_MATERIAL_BACK_A                          0x000017bc
+
+#define NV30_3D_QUERY_RESET                                    0x000017c8
+
+#define NV30_3D_QUERY_ENABLE                                   0x000017cc
+
+#define NV30_3D_QUERY_GET                                      0x00001800
+#define NV30_3D_QUERY_GET_OFFSET__MASK                         0x00ffffff
+#define NV30_3D_QUERY_GET_OFFSET__SHIFT                                0
+#define NV30_3D_QUERY_GET_UNK24__MASK                          0xff000000
+#define NV30_3D_QUERY_GET_UNK24__SHIFT                         24
+
+#define NV30_3D_VERTEX_BEGIN_END                               0x00001808
+#define NV30_3D_VERTEX_BEGIN_END_STOP                          0x00000000
+#define NV30_3D_VERTEX_BEGIN_END_POINTS                                0x00000001
+#define NV30_3D_VERTEX_BEGIN_END_LINES                         0x00000002
+#define NV30_3D_VERTEX_BEGIN_END_LINE_LOOP                     0x00000003
+#define NV30_3D_VERTEX_BEGIN_END_LINE_STRIP                    0x00000004
+#define NV30_3D_VERTEX_BEGIN_END_TRIANGLES                     0x00000005
+#define NV30_3D_VERTEX_BEGIN_END_TRIANGLE_STRIP                        0x00000006
+#define NV30_3D_VERTEX_BEGIN_END_TRIANGLE_FAN                  0x00000007
+#define NV30_3D_VERTEX_BEGIN_END_QUADS                         0x00000008
+#define NV30_3D_VERTEX_BEGIN_END_QUAD_STRIP                    0x00000009
+#define NV30_3D_VERTEX_BEGIN_END_POLYGON                       0x0000000a
+
+#define NV30_3D_VB_ELEMENT_U16                                 0x0000180c
+#define NV30_3D_VB_ELEMENT_U16_0__MASK                         0x0000ffff
+#define NV30_3D_VB_ELEMENT_U16_0__SHIFT                                0
+#define NV30_3D_VB_ELEMENT_U16_1__MASK                         0xffff0000
+#define NV30_3D_VB_ELEMENT_U16_1__SHIFT                                16
+
+#define NV30_3D_VB_ELEMENT_U32                                 0x00001810
+
+#define NV30_3D_VB_VERTEX_BATCH                                        0x00001814
+#define NV30_3D_VB_VERTEX_BATCH_OFFSET__MASK                   0x00ffffff
+#define NV30_3D_VB_VERTEX_BATCH_OFFSET__SHIFT                  0
+#define NV30_3D_VB_VERTEX_BATCH_COUNT__MASK                    0xff000000
+#define NV30_3D_VB_VERTEX_BATCH_COUNT__SHIFT                   24
+
+#define NV30_3D_VERTEX_DATA                                    0x00001818
+
+#define NV30_3D_IDXBUF_OFFSET                                  0x0000181c
+
+#define NV30_3D_IDXBUF_FORMAT                                  0x00001820
+#define NV30_3D_IDXBUF_FORMAT_DMA1                             0x00000001
+#define NV30_3D_IDXBUF_FORMAT_TYPE__MASK                       0x000000f0
+#define NV30_3D_IDXBUF_FORMAT_TYPE__SHIFT                      4
+#define NV30_3D_IDXBUF_FORMAT_TYPE_U32                         0x00000000
+#define NV30_3D_IDXBUF_FORMAT_TYPE_U16                         0x00000010
+
+#define NV30_3D_VB_INDEX_BATCH                                 0x00001824
+#define NV30_3D_VB_INDEX_BATCH_START__MASK                     0x00ffffff
+#define NV30_3D_VB_INDEX_BATCH_START__SHIFT                    0
+#define NV30_3D_VB_INDEX_BATCH_COUNT__MASK                     0xff000000
+#define NV30_3D_VB_INDEX_BATCH_COUNT__SHIFT                    24
+
+#define NV30_3D_POLYGON_MODE_FRONT                             0x00001828
+#define NV30_3D_POLYGON_MODE_FRONT_POINT                       0x00001b00
+#define NV30_3D_POLYGON_MODE_FRONT_LINE                                0x00001b01
+#define NV30_3D_POLYGON_MODE_FRONT_FILL                                0x00001b02
+
+#define NV30_3D_POLYGON_MODE_BACK                              0x0000182c
+#define NV30_3D_POLYGON_MODE_BACK_POINT                                0x00001b00
+#define NV30_3D_POLYGON_MODE_BACK_LINE                         0x00001b01
+#define NV30_3D_POLYGON_MODE_BACK_FILL                         0x00001b02
+
+#define NV30_3D_CULL_FACE                                      0x00001830
+#define NV30_3D_CULL_FACE_FRONT                                        0x00000404
+#define NV30_3D_CULL_FACE_BACK                                 0x00000405
+#define NV30_3D_CULL_FACE_FRONT_AND_BACK                       0x00000408
+
+#define NV30_3D_FRONT_FACE                                     0x00001834
+#define NV30_3D_FRONT_FACE_CW                                  0x00000900
+#define NV30_3D_FRONT_FACE_CCW                                 0x00000901
+
+#define NV30_3D_POLYGON_SMOOTH_ENABLE                          0x00001838
+
+#define NV30_3D_CULL_FACE_ENABLE                               0x0000183c
+
+#define NV30_3D_TEX_PALETTE_OFFSET(i0)                        (0x00001840 + 0x4*(i0))
+#define NV30_3D_TEX_PALETTE_OFFSET__ESIZE                      0x00000004
+#define NV30_3D_TEX_PALETTE_OFFSET__LEN                                0x00000008
+
+#define NV40_3D_TEX_SIZE1(i0)                                 (0x00001840 + 0x4*(i0))
+#define NV40_3D_TEX_SIZE1__ESIZE                               0x00000004
+#define NV40_3D_TEX_SIZE1__LEN                                 0x00000008
+#define NV40_3D_TEX_SIZE1_DEPTH__MASK                          0xfff00000
+#define NV40_3D_TEX_SIZE1_DEPTH__SHIFT                         20
+#define NV40_3D_TEX_SIZE1_PITCH__MASK                          0x0000ffff
+#define NV40_3D_TEX_SIZE1_PITCH__SHIFT                         0
+
+#define NV30_3D_VTX_ATTR_2F(i0)                                       (0x00001880 + 0x8*(i0))
+#define NV30_3D_VTX_ATTR_2F__ESIZE                             0x00000008
+#define NV30_3D_VTX_ATTR_2F__LEN                               0x00000010
+
+
+#define NV30_3D_VTX_ATTR_2F_X(i0)                             (0x00001880 + 0x8*(i0))
+
+#define NV30_3D_VTX_ATTR_2F_Y(i0)                             (0x00001884 + 0x8*(i0))
+
+#define NV30_3D_VTX_ATTR_2I(i0)                                       (0x00001900 + 0x4*(i0))
+#define NV30_3D_VTX_ATTR_2I__ESIZE                             0x00000004
+#define NV30_3D_VTX_ATTR_2I__LEN                               0x00000010
+#define NV30_3D_VTX_ATTR_2I_X__MASK                            0x0000ffff
+#define NV30_3D_VTX_ATTR_2I_X__SHIFT                           0
+#define NV30_3D_VTX_ATTR_2I_Y__MASK                            0xffff0000
+#define NV30_3D_VTX_ATTR_2I_Y__SHIFT                           16
+
+#define NV30_3D_VTX_ATTR_4UB(i0)                              (0x00001940 + 0x4*(i0))
+#define NV30_3D_VTX_ATTR_4UB__ESIZE                            0x00000004
+#define NV30_3D_VTX_ATTR_4UB__LEN                              0x00000010
+#define NV30_3D_VTX_ATTR_4UB_X__MASK                           0x000000ff
+#define NV30_3D_VTX_ATTR_4UB_X__SHIFT                          0
+#define NV30_3D_VTX_ATTR_4UB_Y__MASK                           0x0000ff00
+#define NV30_3D_VTX_ATTR_4UB_Y__SHIFT                          8
+#define NV30_3D_VTX_ATTR_4UB_Z__MASK                           0x00ff0000
+#define NV30_3D_VTX_ATTR_4UB_Z__SHIFT                          16
+#define NV30_3D_VTX_ATTR_4UB_W__MASK                           0xff000000
+#define NV30_3D_VTX_ATTR_4UB_W__SHIFT                          24
+
+#define NV30_3D_VTX_ATTR_4I(i0)                                       (0x00001980 + 0x8*(i0))
+#define NV30_3D_VTX_ATTR_4I__ESIZE                             0x00000008
+#define NV30_3D_VTX_ATTR_4I__LEN                               0x00000010
+
+#define NV30_3D_VTX_ATTR_4I_XY(i0)                            (0x00001980 + 0x8*(i0))
+#define NV30_3D_VTX_ATTR_4I_XY_X__MASK                         0x0000ffff
+#define NV30_3D_VTX_ATTR_4I_XY_X__SHIFT                                0
+#define NV30_3D_VTX_ATTR_4I_XY_Y__MASK                         0xffff0000
+#define NV30_3D_VTX_ATTR_4I_XY_Y__SHIFT                                16
+
+#define NV30_3D_VTX_ATTR_4I_ZW(i0)                            (0x00001984 + 0x8*(i0))
+#define NV30_3D_VTX_ATTR_4I_ZW_Z__MASK                         0x0000ffff
+#define NV30_3D_VTX_ATTR_4I_ZW_Z__SHIFT                                0
+#define NV30_3D_VTX_ATTR_4I_ZW_W__MASK                         0xffff0000
+#define NV30_3D_VTX_ATTR_4I_ZW_W__SHIFT                                16
+
+#define NV30_3D_TEX_OFFSET(i0)                                (0x00001a00 + 0x20*(i0))
+#define NV30_3D_TEX_OFFSET__ESIZE                              0x00000020
+#define NV30_3D_TEX_OFFSET__LEN                                        0x00000008
+
+#define NV30_3D_TEX_FORMAT(i0)                                (0x00001a04 + 0x20*(i0))
+#define NV30_3D_TEX_FORMAT__ESIZE                              0x00000020
+#define NV30_3D_TEX_FORMAT__LEN                                        0x00000008
+#define NV30_3D_TEX_FORMAT_DMA0                                        0x00000001
+#define NV30_3D_TEX_FORMAT_DMA1                                        0x00000002
+#define NV30_3D_TEX_FORMAT_CUBIC                               0x00000004
+#define NV30_3D_TEX_FORMAT_NO_BORDER                           0x00000008
+#define NV30_3D_TEX_FORMAT_DIMS__MASK                          0x000000f0
+#define NV30_3D_TEX_FORMAT_DIMS__SHIFT                         4
+#define NV30_3D_TEX_FORMAT_DIMS_1D                             0x00000010
+#define NV30_3D_TEX_FORMAT_DIMS_2D                             0x00000020
+#define NV30_3D_TEX_FORMAT_DIMS_3D                             0x00000030
+#define NV30_3D_TEX_FORMAT_FORMAT__MASK                                0x0000ff00
+#define NV30_3D_TEX_FORMAT_FORMAT__SHIFT                       8
+#define NV30_3D_TEX_FORMAT_FORMAT_L8                           0x00000000
+#define NV30_3D_TEX_FORMAT_FORMAT_I8                           0x00000100
+#define NV30_3D_TEX_FORMAT_FORMAT_A1R5G5B5                     0x00000200
+#define NV30_3D_TEX_FORMAT_FORMAT_A4R4G4B4                     0x00000400
+#define NV30_3D_TEX_FORMAT_FORMAT_R5G6B5                       0x00000500
+#define NV30_3D_TEX_FORMAT_FORMAT_A8R8G8B8                     0x00000600
+#define NV30_3D_TEX_FORMAT_FORMAT_X8R8G8B8                     0x00000700
+#define NV30_3D_TEX_FORMAT_FORMAT_INDEX8                       0x00000b00
+#define NV30_3D_TEX_FORMAT_FORMAT_DXT1                         0x00000c00
+#define NV30_3D_TEX_FORMAT_FORMAT_DXT3                         0x00000e00
+#define NV30_3D_TEX_FORMAT_FORMAT_DXT5                         0x00000f00
+#define NV30_3D_TEX_FORMAT_FORMAT_A1R5G5B5_RECT                        0x00001000
+#define NV30_3D_TEX_FORMAT_FORMAT_R5G6B5_RECT                  0x00001100
+#define NV30_3D_TEX_FORMAT_FORMAT_A8R8G8B8_RECT                        0x00001200
+#define NV30_3D_TEX_FORMAT_FORMAT_L8_RECT                      0x00001300
+#define NV30_3D_TEX_FORMAT_FORMAT_DSDT8_RECT                   0x00001700
+#define NV30_3D_TEX_FORMAT_FORMAT_A8L8                         0x00001a00
+#define NV30_3D_TEX_FORMAT_FORMAT_I8_RECT                      0x00001b00
+#define NV30_3D_TEX_FORMAT_FORMAT_A4R4G4B4_RECT                        0x00001d00
+#define NV30_3D_TEX_FORMAT_FORMAT_R8G8B8_RECT                  0x00001e00
+#define NV30_3D_TEX_FORMAT_FORMAT_A8L8_RECT                    0x00002000
+#define NV30_3D_TEX_FORMAT_FORMAT_Z24                          0x00002a00
+#define NV30_3D_TEX_FORMAT_FORMAT_Z24_RECT                     0x00002b00
+#define NV30_3D_TEX_FORMAT_FORMAT_Z16                          0x00002c00
+#define NV30_3D_TEX_FORMAT_FORMAT_Z16_RECT                     0x00002d00
+#define NV30_3D_TEX_FORMAT_FORMAT_DSDT8                                0x00002800
+#define NV30_3D_TEX_FORMAT_FORMAT_HILO16                       0x00003300
+#define NV30_3D_TEX_FORMAT_FORMAT_HILO16_RECT                  0x00003600
+#define NV30_3D_TEX_FORMAT_FORMAT_HILO8                                0x00004400
+#define NV30_3D_TEX_FORMAT_FORMAT_SIGNED_HILO8                 0x00004500
+#define NV30_3D_TEX_FORMAT_FORMAT_HILO8_RECT                   0x00004600
+#define NV30_3D_TEX_FORMAT_FORMAT_SIGNED_HILO8_RECT            0x00004700
+#define NV30_3D_TEX_FORMAT_FORMAT_A16                          0x00003200
+#define NV30_3D_TEX_FORMAT_FORMAT_A16_RECT                     0x00003500
+#define NV30_3D_TEX_FORMAT_FORMAT_UNK3F                                0x00003f00
+#define NV30_3D_TEX_FORMAT_FORMAT_FLOAT_RGBA16_NV              0x00004a00
+#define NV30_3D_TEX_FORMAT_FORMAT_FLOAT_RGBA32_NV              0x00004b00
+#define NV30_3D_TEX_FORMAT_FORMAT_FLOAT_R32_NV                 0x00004c00
+#define NV40_3D_TEX_FORMAT_FORMAT__MASK                                0x00001f00
+#define NV40_3D_TEX_FORMAT_FORMAT__SHIFT                       8
+#define NV40_3D_TEX_FORMAT_FORMAT_L8                           0x00000100
+#define NV40_3D_TEX_FORMAT_FORMAT_A1R5G5B5                     0x00000200
+#define NV40_3D_TEX_FORMAT_FORMAT_A4R4G4B4                     0x00000300
+#define NV40_3D_TEX_FORMAT_FORMAT_R5G6B5                       0x00000400
+#define NV40_3D_TEX_FORMAT_FORMAT_A8R8G8B8                     0x00000500
+#define NV40_3D_TEX_FORMAT_FORMAT_DXT1                         0x00000600
+#define NV40_3D_TEX_FORMAT_FORMAT_DXT3                         0x00000700
+#define NV40_3D_TEX_FORMAT_FORMAT_DXT5                         0x00000800
+#define NV40_3D_TEX_FORMAT_FORMAT_A8L8                         0x00000b00
+#define NV40_3D_TEX_FORMAT_FORMAT_Z24                          0x00001000
+#define NV40_3D_TEX_FORMAT_FORMAT_Z16                          0x00001200
+#define NV40_3D_TEX_FORMAT_FORMAT_A16                          0x00001400
+#define NV40_3D_TEX_FORMAT_FORMAT_A16L16                       0x00001500
+#define NV40_3D_TEX_FORMAT_FORMAT_HILO8                                0x00001800
+#define NV40_3D_TEX_FORMAT_FORMAT_RGBA16F                      0x00001a00
+#define NV40_3D_TEX_FORMAT_FORMAT_RGBA32F                      0x00001b00
+#define NV40_3D_TEX_FORMAT_LINEAR                              0x00002000
+#define NV40_3D_TEX_FORMAT_RECT                                        0x00004000
+#define NV40_3D_TEX_FORMAT_MIPMAP_COUNT__MASK                  0x000f0000
+#define NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT                 16
+#define NV30_3D_TEX_FORMAT_MIPMAP                              0x00080000
+#define NV30_3D_TEX_FORMAT_BASE_SIZE_U__MASK                   0x00f00000
+#define NV30_3D_TEX_FORMAT_BASE_SIZE_U__SHIFT                  20
+#define NV30_3D_TEX_FORMAT_BASE_SIZE_V__MASK                   0x0f000000
+#define NV30_3D_TEX_FORMAT_BASE_SIZE_V__SHIFT                  24
+#define NV30_3D_TEX_FORMAT_BASE_SIZE_W__MASK                   0xf0000000
+#define NV30_3D_TEX_FORMAT_BASE_SIZE_W__SHIFT                  28
+
+#define NV30_3D_TEX_WRAP(i0)                                  (0x00001a08 + 0x20*(i0))
+#define NV30_3D_TEX_WRAP__ESIZE                                        0x00000020
+#define NV30_3D_TEX_WRAP__LEN                                  0x00000008
+#define NV30_3D_TEX_WRAP_S__MASK                               0x000000ff
+#define NV30_3D_TEX_WRAP_S__SHIFT                              0
+#define NV30_3D_TEX_WRAP_S_REPEAT                              0x00000001
+#define NV30_3D_TEX_WRAP_S_MIRRORED_REPEAT                     0x00000002
+#define NV30_3D_TEX_WRAP_S_CLAMP_TO_EDGE                       0x00000003
+#define NV30_3D_TEX_WRAP_S_CLAMP_TO_BORDER                     0x00000004
+#define NV30_3D_TEX_WRAP_S_CLAMP                               0x00000005
+#define NV40_3D_TEX_WRAP_S_MIRROR_CLAMP_TO_EDGE                        0x00000006
+#define NV40_3D_TEX_WRAP_S_MIRROR_CLAMP_TO_BORDER              0x00000007
+#define NV40_3D_TEX_WRAP_S_MIRROR_CLAMP                                0x00000008
+#define NV40_3D_TEX_WRAP_ANISO_MIP_FILTER_OPTIMIZATION__MASK   0x00000070
+#define NV40_3D_TEX_WRAP_ANISO_MIP_FILTER_OPTIMIZATION__SHIFT  4
+#define NV40_3D_TEX_WRAP_ANISO_MIP_FILTER_OPTIMIZATION_OFF     0x00000000
+#define NV40_3D_TEX_WRAP_ANISO_MIP_FILTER_OPTIMIZATION_QUALITY 0x00000020
+#define NV40_3D_TEX_WRAP_ANISO_MIP_FILTER_OPTIMIZATION_PERFORMANCE     0x00000030
+#define NV40_3D_TEX_WRAP_ANISO_MIP_FILTER_OPTIMIZATION_HIGH_PERFORMANCE        0x00000070
+#define NV30_3D_TEX_WRAP_T__MASK                               0x00000f00
+#define NV30_3D_TEX_WRAP_T__SHIFT                              8
+#define NV30_3D_TEX_WRAP_T_REPEAT                              0x00000100
+#define NV30_3D_TEX_WRAP_T_MIRRORED_REPEAT                     0x00000200
+#define NV30_3D_TEX_WRAP_T_CLAMP_TO_EDGE                       0x00000300
+#define NV30_3D_TEX_WRAP_T_CLAMP_TO_BORDER                     0x00000400
+#define NV30_3D_TEX_WRAP_T_CLAMP                               0x00000500
+#define NV40_3D_TEX_WRAP_T_MIRROR_CLAMP_TO_EDGE                        0x00000600
+#define NV40_3D_TEX_WRAP_T_MIRROR_CLAMP_TO_BORDER              0x00000700
+#define NV40_3D_TEX_WRAP_T_MIRROR_CLAMP                                0x00000800
+#define NV30_3D_TEX_WRAP_EXPAND_NORMAL                         0x0000f000
+#define NV30_3D_TEX_WRAP_R__MASK                               0x000f0000
+#define NV30_3D_TEX_WRAP_R__SHIFT                              16
+#define NV30_3D_TEX_WRAP_R_REPEAT                              0x00010000
+#define NV30_3D_TEX_WRAP_R_MIRRORED_REPEAT                     0x00020000
+#define NV30_3D_TEX_WRAP_R_CLAMP_TO_EDGE                       0x00030000
+#define NV30_3D_TEX_WRAP_R_CLAMP_TO_BORDER                     0x00040000
+#define NV30_3D_TEX_WRAP_R_CLAMP                               0x00050000
+#define NV40_3D_TEX_WRAP_R_MIRROR_CLAMP_TO_EDGE                        0x00060000
+#define NV40_3D_TEX_WRAP_R_MIRROR_CLAMP_TO_BORDER              0x00070000
+#define NV40_3D_TEX_WRAP_R_MIRROR_CLAMP                                0x00080000
+#define NV40_3D_TEX_WRAP_GAMMA_DECREASE_FILTER__MASK           0x00f00000
+#define NV40_3D_TEX_WRAP_GAMMA_DECREASE_FILTER__SHIFT          20
+#define NV40_3D_TEX_WRAP_GAMMA_DECREASE_FILTER_NONE            0x00000000
+#define NV40_3D_TEX_WRAP_GAMMA_DECREASE_FILTER_RED             0x00100000
+#define NV40_3D_TEX_WRAP_GAMMA_DECREASE_FILTER_GREEN           0x00200000
+#define NV40_3D_TEX_WRAP_GAMMA_DECREASE_FILTER_BLUE            0x00400000
+#define NV40_3D_TEX_WRAP_GAMMA_DECREASE_FILTER_ALL             0x00f00000
+#define NV30_3D_TEX_WRAP_RCOMP__MASK                           0xf0000000
+#define NV30_3D_TEX_WRAP_RCOMP__SHIFT                          28
+#define NV30_3D_TEX_WRAP_RCOMP_NEVER                           0x00000000
+#define NV30_3D_TEX_WRAP_RCOMP_GREATER                         0x10000000
+#define NV30_3D_TEX_WRAP_RCOMP_EQUAL                           0x20000000
+#define NV30_3D_TEX_WRAP_RCOMP_GEQUAL                          0x30000000
+#define NV30_3D_TEX_WRAP_RCOMP_LESS                            0x40000000
+#define NV30_3D_TEX_WRAP_RCOMP_NOTEQUAL                                0x50000000
+#define NV30_3D_TEX_WRAP_RCOMP_LEQUAL                          0x60000000
+#define NV30_3D_TEX_WRAP_RCOMP_ALWAYS                          0x70000000
+
+#define NV30_3D_TEX_ENABLE(i0)                                (0x00001a0c + 0x20*(i0))
+#define NV30_3D_TEX_ENABLE__ESIZE                              0x00000020
+#define NV30_3D_TEX_ENABLE__LEN                                        0x00000008
+#define NV30_3D_TEX_ENABLE_ANISO__MASK                         0x00000030
+#define NV30_3D_TEX_ENABLE_ANISO__SHIFT                                4
+#define NV30_3D_TEX_ENABLE_ANISO_NONE                          0x00000000
+#define NV30_3D_TEX_ENABLE_ANISO_2X                            0x00000010
+#define NV30_3D_TEX_ENABLE_ANISO_4X                            0x00000020
+#define NV30_3D_TEX_ENABLE_ANISO_8X                            0x00000030
+#define NV40_3D_TEX_ENABLE_ANISO__MASK                         0x000000f0
+#define NV40_3D_TEX_ENABLE_ANISO__SHIFT                                4
+#define NV40_3D_TEX_ENABLE_ANISO_NONE                          0x00000000
+#define NV40_3D_TEX_ENABLE_ANISO_2X                            0x00000010
+#define NV40_3D_TEX_ENABLE_ANISO_4X                            0x00000020
+#define NV40_3D_TEX_ENABLE_ANISO_6X                            0x00000030
+#define NV40_3D_TEX_ENABLE_ANISO_8X                            0x00000040
+#define NV40_3D_TEX_ENABLE_ANISO_10X                           0x00000050
+#define NV40_3D_TEX_ENABLE_ANISO_12X                           0x00000060
+#define NV40_3D_TEX_ENABLE_ANISO_16X                           0x00000070
+#define NV30_3D_TEX_ENABLE_MIPMAP_MAX_LOD__MASK                        0x0003c000
+#define NV30_3D_TEX_ENABLE_MIPMAP_MAX_LOD__SHIFT               14
+#define NV40_3D_TEX_ENABLE_MIPMAP_MAX_LOD__MASK                        0x00038000
+#define NV40_3D_TEX_ENABLE_MIPMAP_MAX_LOD__SHIFT               15
+#define NV30_3D_TEX_ENABLE_MIPMAP_MIN_LOD__MASK                        0x3c000000
+#define NV30_3D_TEX_ENABLE_MIPMAP_MIN_LOD__SHIFT               26
+#define NV40_3D_TEX_ENABLE_MIPMAP_MIN_LOD__MASK                        0x38000000
+#define NV40_3D_TEX_ENABLE_MIPMAP_MIN_LOD__SHIFT               27
+#define NV30_3D_TEX_ENABLE_ENABLE                              0x40000000
+#define NV40_3D_TEX_ENABLE_ENABLE                              0x80000000
+
+#define NV30_3D_TEX_SWIZZLE(i0)                                       (0x00001a10 + 0x20*(i0))
+#define NV30_3D_TEX_SWIZZLE__ESIZE                             0x00000020
+#define NV30_3D_TEX_SWIZZLE__LEN                               0x00000008
+#define NV30_3D_TEX_SWIZZLE_S1_W__MASK                         0x00000003
+#define NV30_3D_TEX_SWIZZLE_S1_W__SHIFT                                0
+#define NV30_3D_TEX_SWIZZLE_S1_W_W                             0x00000000
+#define NV30_3D_TEX_SWIZZLE_S1_W_Z                             0x00000001
+#define NV30_3D_TEX_SWIZZLE_S1_W_Y                             0x00000002
+#define NV30_3D_TEX_SWIZZLE_S1_W_X                             0x00000003
+#define NV30_3D_TEX_SWIZZLE_S1_Z__MASK                         0x0000000c
+#define NV30_3D_TEX_SWIZZLE_S1_Z__SHIFT                                2
+#define NV30_3D_TEX_SWIZZLE_S1_Z_W                             0x00000000
+#define NV30_3D_TEX_SWIZZLE_S1_Z_Z                             0x00000004
+#define NV30_3D_TEX_SWIZZLE_S1_Z_Y                             0x00000008
+#define NV30_3D_TEX_SWIZZLE_S1_Z_X                             0x0000000c
+#define NV30_3D_TEX_SWIZZLE_S1_Y__MASK                         0x00000030
+#define NV30_3D_TEX_SWIZZLE_S1_Y__SHIFT                                4
+#define NV30_3D_TEX_SWIZZLE_S1_Y_W                             0x00000000
+#define NV30_3D_TEX_SWIZZLE_S1_Y_Z                             0x00000010
+#define NV30_3D_TEX_SWIZZLE_S1_Y_Y                             0x00000020
+#define NV30_3D_TEX_SWIZZLE_S1_Y_X                             0x00000030
+#define NV30_3D_TEX_SWIZZLE_S1_X__MASK                         0x000000c0
+#define NV30_3D_TEX_SWIZZLE_S1_X__SHIFT                                6
+#define NV30_3D_TEX_SWIZZLE_S1_X_W                             0x00000000
+#define NV30_3D_TEX_SWIZZLE_S1_X_Z                             0x00000040
+#define NV30_3D_TEX_SWIZZLE_S1_X_Y                             0x00000080
+#define NV30_3D_TEX_SWIZZLE_S1_X_X                             0x000000c0
+#define NV30_3D_TEX_SWIZZLE_S0_W__MASK                         0x00000300
+#define NV30_3D_TEX_SWIZZLE_S0_W__SHIFT                                8
+#define NV30_3D_TEX_SWIZZLE_S0_W_ZERO                          0x00000000
+#define NV30_3D_TEX_SWIZZLE_S0_W_ONE                           0x00000100
+#define NV30_3D_TEX_SWIZZLE_S0_W_S1                            0x00000200
+#define NV30_3D_TEX_SWIZZLE_S0_Z__MASK                         0x00000c00
+#define NV30_3D_TEX_SWIZZLE_S0_Z__SHIFT                                10
+#define NV30_3D_TEX_SWIZZLE_S0_Z_ZERO                          0x00000000
+#define NV30_3D_TEX_SWIZZLE_S0_Z_ONE                           0x00000400
+#define NV30_3D_TEX_SWIZZLE_S0_Z_S1                            0x00000800
+#define NV30_3D_TEX_SWIZZLE_S0_Y__MASK                         0x00003000
+#define NV30_3D_TEX_SWIZZLE_S0_Y__SHIFT                                12
+#define NV30_3D_TEX_SWIZZLE_S0_Y_ZERO                          0x00000000
+#define NV30_3D_TEX_SWIZZLE_S0_Y_ONE                           0x00001000
+#define NV30_3D_TEX_SWIZZLE_S0_Y_S1                            0x00002000
+#define NV30_3D_TEX_SWIZZLE_S0_X__MASK                         0x0000c000
+#define NV30_3D_TEX_SWIZZLE_S0_X__SHIFT                                14
+#define NV30_3D_TEX_SWIZZLE_S0_X_ZERO                          0x00000000
+#define NV30_3D_TEX_SWIZZLE_S0_X_ONE                           0x00004000
+#define NV30_3D_TEX_SWIZZLE_S0_X_S1                            0x00008000
+#define NV30_3D_TEX_SWIZZLE_RECT_PITCH__MASK                   0xffff0000
+#define NV30_3D_TEX_SWIZZLE_RECT_PITCH__SHIFT                  16
+
+#define NV30_3D_TEX_FILTER(i0)                                (0x00001a14 + 0x20*(i0))
+#define NV30_3D_TEX_FILTER__ESIZE                              0x00000020
+#define NV30_3D_TEX_FILTER__LEN                                        0x00000008
+#define NV30_3D_TEX_FILTER_LOD_BIAS__MASK                      0x00000f00
+#define NV30_3D_TEX_FILTER_LOD_BIAS__SHIFT                     8
+#define NV30_3D_TEX_FILTER_MIN__MASK                           0x000f0000
+#define NV30_3D_TEX_FILTER_MIN__SHIFT                          16
+#define NV30_3D_TEX_FILTER_MIN_NEAREST                         0x00010000
+#define NV30_3D_TEX_FILTER_MIN_LINEAR                          0x00020000
+#define NV30_3D_TEX_FILTER_MIN_NEAREST_MIPMAP_NEAREST          0x00030000
+#define NV30_3D_TEX_FILTER_MIN_LINEAR_MIPMAP_NEAREST           0x00040000
+#define NV30_3D_TEX_FILTER_MIN_NEAREST_MIPMAP_LINEAR           0x00050000
+#define NV30_3D_TEX_FILTER_MIN_LINEAR_MIPMAP_LINEAR            0x00060000
+#define NV30_3D_TEX_FILTER_MAG__MASK                           0x0f000000
+#define NV30_3D_TEX_FILTER_MAG__SHIFT                          24
+#define NV30_3D_TEX_FILTER_MAG_NEAREST                         0x01000000
+#define NV30_3D_TEX_FILTER_MAG_LINEAR                          0x02000000
+#define NV30_3D_TEX_FILTER_SIGNED_BLUE                         0x10000000
+#define NV30_3D_TEX_FILTER_SIGNED_GREEN                                0x20000000
+#define NV30_3D_TEX_FILTER_SIGNED_RED                          0x40000000
+#define NV30_3D_TEX_FILTER_SIGNED_ALPHA                                0x80000000
+
+#define NV30_3D_TEX_NPOT_SIZE(i0)                             (0x00001a18 + 0x20*(i0))
+#define NV30_3D_TEX_NPOT_SIZE__ESIZE                           0x00000020
+#define NV30_3D_TEX_NPOT_SIZE__LEN                             0x00000008
+#define NV30_3D_TEX_NPOT_SIZE_H__MASK                          0x0000ffff
+#define NV30_3D_TEX_NPOT_SIZE_H__SHIFT                         0
+#define NV30_3D_TEX_NPOT_SIZE_W__MASK                          0xffff0000
+#define NV30_3D_TEX_NPOT_SIZE_W__SHIFT                         16
+
+#define NV30_3D_TEX_BORDER_COLOR(i0)                          (0x00001a1c + 0x20*(i0))
+#define NV30_3D_TEX_BORDER_COLOR__ESIZE                                0x00000020
+#define NV30_3D_TEX_BORDER_COLOR__LEN                          0x00000008
+#define NV30_3D_TEX_BORDER_COLOR_B__MASK                       0x000000ff
+#define NV30_3D_TEX_BORDER_COLOR_B__SHIFT                      0
+#define NV30_3D_TEX_BORDER_COLOR_G__MASK                       0x0000ff00
+#define NV30_3D_TEX_BORDER_COLOR_G__SHIFT                      8
+#define NV30_3D_TEX_BORDER_COLOR_R__MASK                       0x00ff0000
+#define NV30_3D_TEX_BORDER_COLOR_R__SHIFT                      16
+#define NV30_3D_TEX_BORDER_COLOR_A__MASK                       0xff000000
+#define NV30_3D_TEX_BORDER_COLOR_A__SHIFT                      24
+
+#define NV30_3D_VTX_ATTR_4F(i0)                                       (0x00001c00 + 0x10*(i0))
+#define NV30_3D_VTX_ATTR_4F__ESIZE                             0x00000010
+#define NV30_3D_VTX_ATTR_4F__LEN                               0x00000010
+
+
+#define NV30_3D_VTX_ATTR_4F_X(i0)                             (0x00001c00 + 0x10*(i0))
+
+#define NV30_3D_VTX_ATTR_4F_Y(i0)                             (0x00001c04 + 0x10*(i0))
+
+#define NV30_3D_VTX_ATTR_4F_Z(i0)                             (0x00001c08 + 0x10*(i0))
+
+#define NV30_3D_VTX_ATTR_4F_W(i0)                             (0x00001c0c + 0x10*(i0))
+
+#define NV30_3D_FP_CONTROL                                     0x00001d60
+#define NV30_3D_FP_CONTROL_USED_REGS_MINUS1_DIV2__MASK         0x0000000f
+#define NV30_3D_FP_CONTROL_USED_REGS_MINUS1_DIV2__SHIFT                0
+#define NV30_3D_FP_CONTROL_USES_KIL                            0x00000080
+#define NV40_3D_FP_CONTROL_KIL                                 0x00000080
+#define NV40_3D_FP_CONTROL_TEMP_COUNT__MASK                    0xff000000
+#define NV40_3D_FP_CONTROL_TEMP_COUNT__SHIFT                   24
+
+#define NV30_3D_FENCE_OFFSET                                   0x00001d6c
+
+#define NV30_3D_FENCE_VALUE                                    0x00001d70
+
+#define NV30_3D_DEPTH_CONTROL                                  0x00001d78
+#define NV30_3D_DEPTH_CONTROL_CLAMP                            0x000000f0
+
+#define NV30_3D_MULTISAMPLE_CONTROL                            0x00001d7c
+#define NV30_3D_MULTISAMPLE_CONTROL_ENABLE                     0x00000001
+#define NV30_3D_MULTISAMPLE_CONTROL_SAMPLE_ALPHA_TO_COVERAGE   0x00000010
+#define NV30_3D_MULTISAMPLE_CONTROL_SAMPLE_ALPHA_TO_ONE                0x00000100
+#define NV30_3D_MULTISAMPLE_CONTROL_SAMPLE_COVERAGE__MASK      0xffff0000
+#define NV30_3D_MULTISAMPLE_CONTROL_SAMPLE_COVERAGE__SHIFT     16
+
+#define NV30_3D_COORD_CONVENTIONS                              0x00001d88
+#define NV30_3D_COORD_CONVENTIONS_HEIGHT__MASK                 0x00000fff
+#define NV30_3D_COORD_CONVENTIONS_HEIGHT__SHIFT                        0
+#define NV30_3D_COORD_CONVENTIONS_ORIGIN__MASK                 0x00001000
+#define NV30_3D_COORD_CONVENTIONS_ORIGIN__SHIFT                        12
+#define NV30_3D_COORD_CONVENTIONS_ORIGIN_NORMAL                        0x00000000
+#define NV30_3D_COORD_CONVENTIONS_ORIGIN_INVERTED              0x00001000
+#define NV30_3D_COORD_CONVENTIONS_CENTER__MASK                 0x00010000
+#define NV30_3D_COORD_CONVENTIONS_CENTER__SHIFT                        16
+#define NV30_3D_COORD_CONVENTIONS_CENTER_HALF_INTEGER          0x00000000
+#define NV30_3D_COORD_CONVENTIONS_CENTER_INTEGER               0x00010000
+
+#define NV30_3D_CLEAR_DEPTH_VALUE                              0x00001d8c
+
+#define NV30_3D_CLEAR_COLOR_VALUE                              0x00001d90
+#define NV30_3D_CLEAR_COLOR_VALUE_B__MASK                      0x000000ff
+#define NV30_3D_CLEAR_COLOR_VALUE_B__SHIFT                     0
+#define NV30_3D_CLEAR_COLOR_VALUE_G__MASK                      0x0000ff00
+#define NV30_3D_CLEAR_COLOR_VALUE_G__SHIFT                     8
+#define NV30_3D_CLEAR_COLOR_VALUE_R__MASK                      0x00ff0000
+#define NV30_3D_CLEAR_COLOR_VALUE_R__SHIFT                     16
+#define NV30_3D_CLEAR_COLOR_VALUE_A__MASK                      0xff000000
+#define NV30_3D_CLEAR_COLOR_VALUE_A__SHIFT                     24
+
+#define NV30_3D_CLEAR_BUFFERS                                  0x00001d94
+#define NV30_3D_CLEAR_BUFFERS_DEPTH                            0x00000001
+#define NV30_3D_CLEAR_BUFFERS_STENCIL                          0x00000002
+#define NV30_3D_CLEAR_BUFFERS_COLOR_R                          0x00000010
+#define NV30_3D_CLEAR_BUFFERS_COLOR_G                          0x00000020
+#define NV30_3D_CLEAR_BUFFERS_COLOR_B                          0x00000040
+#define NV30_3D_CLEAR_BUFFERS_COLOR_A                          0x00000080
+
+#define NV30_3D_PRIMITIVE_RESTART_ENABLE                       0x00001dac
+
+#define NV30_3D_PRIMITIVE_RESTART_INDEX                                0x00001db0
+
+#define NV30_3D_LINE_STIPPLE_ENABLE                            0x00001db4
+
+#define NV30_3D_LINE_STIPPLE_PATTERN                           0x00001db8
+#define NV30_3D_LINE_STIPPLE_PATTERN_FACTOR__MASK              0x0000ffff
+#define NV30_3D_LINE_STIPPLE_PATTERN_FACTOR__SHIFT             0
+#define NV30_3D_LINE_STIPPLE_PATTERN_PATTERN__MASK             0xffff0000
+#define NV30_3D_LINE_STIPPLE_PATTERN_PATTERN__SHIFT            16
+
+#define NV30_3D_BACK_MATERIAL_SHININESS(i0)                   (0x00001e20 + 0x4*(i0))
+#define NV30_3D_BACK_MATERIAL_SHININESS__ESIZE                 0x00000004
+#define NV30_3D_BACK_MATERIAL_SHININESS__LEN                   0x00000006
+
+#define NV30_3D_VTX_ATTR_1F(i0)                                       (0x00001e40 + 0x4*(i0))
+#define NV30_3D_VTX_ATTR_1F__ESIZE                             0x00000004
+#define NV30_3D_VTX_ATTR_1F__LEN                               0x00000010
+
+#define NV30_3D_ENGINE                                         0x00001e94
+#define NV30_3D_ENGINE_FP                                      0x00000001
+#define NV30_3D_ENGINE_VP                                      0x00000002
+#define NV30_3D_ENGINE_FIXED                                   0x00000004
+
+#define NV30_3D_VP_UPLOAD_FROM_ID                              0x00001e9c
+
+#define NV30_3D_VP_START_FROM_ID                               0x00001ea0
+
+#define NV30_3D_POINT_PARAMETERS(i0)                          (0x00001ec0 + 0x4*(i0))
+#define NV30_3D_POINT_PARAMETERS__ESIZE                                0x00000004
+#define NV30_3D_POINT_PARAMETERS__LEN                          0x00000008
+
+#define NV30_3D_POINT_SIZE                                     0x00001ee0
+
+#define NV30_3D_POINT_PARAMETERS_ENABLE                                0x00001ee4
+
+#define NV30_3D_POINT_SPRITE                                   0x00001ee8
+#define NV30_3D_POINT_SPRITE_ENABLE                            0x00000001
+#define NV30_3D_POINT_SPRITE_R_MODE__MASK                      0x00000006
+#define NV30_3D_POINT_SPRITE_R_MODE__SHIFT                     1
+#define NV30_3D_POINT_SPRITE_R_MODE_ZERO                       0x00000000
+#define NV30_3D_POINT_SPRITE_R_MODE_R                          0x00000002
+#define NV30_3D_POINT_SPRITE_R_MODE_S                          0x00000004
+#define NV30_3D_POINT_SPRITE_COORD_REPLACE_0                   0x00000100
+#define NV30_3D_POINT_SPRITE_COORD_REPLACE_1                   0x00000200
+#define NV30_3D_POINT_SPRITE_COORD_REPLACE_2                   0x00000400
+#define NV30_3D_POINT_SPRITE_COORD_REPLACE_3                   0x00000800
+#define NV30_3D_POINT_SPRITE_COORD_REPLACE_4                   0x00001000
+#define NV30_3D_POINT_SPRITE_COORD_REPLACE_5                   0x00002000
+#define NV30_3D_POINT_SPRITE_COORD_REPLACE_6                   0x00004000
+#define NV30_3D_POINT_SPRITE_COORD_REPLACE_7                   0x00008000
+
+#define NV30_3D_VP_UPLOAD_CONST_ID                             0x00001efc
+
+#define NV30_3D_VP_UPLOAD_CONST(i0)                           (0x00001f00 + 0x10*(i0))
+#define NV30_3D_VP_UPLOAD_CONST__ESIZE                         0x00000010
+#define NV30_3D_VP_UPLOAD_CONST__LEN                           0x00000004
+
+
+#define NV30_3D_VP_UPLOAD_CONST_X(i0)                         (0x00001f00 + 0x10*(i0))
+
+#define NV30_3D_VP_UPLOAD_CONST_Y(i0)                         (0x00001f04 + 0x10*(i0))
+
+#define NV30_3D_VP_UPLOAD_CONST_Z(i0)                         (0x00001f08 + 0x10*(i0))
+
+#define NV30_3D_VP_UPLOAD_CONST_W(i0)                         (0x00001f0c + 0x10*(i0))
+
+#define NV30_3D_UNK1F80(i0)                                   (0x00001f80 + 0x4*(i0))
+#define NV30_3D_UNK1F80__ESIZE                                 0x00000004
+#define NV30_3D_UNK1F80__LEN                                   0x00000010
+
+#define NV40_3D_TEX_CACHE_CTL                                  0x00001fd8
+
+#define NV40_3D_VP_ATTRIB_EN                                   0x00001ff0
+
+#define NV40_3D_VP_RESULT_EN                                   0x00001ff4
+
+
+#endif /* _HOME_SKEGGSB_GIT_ENVYTOOLS_RNNDB_NV30_40_3D_XML */
diff --git a/src/gallium/drivers/nv30/nv30_clear.c b/src/gallium/drivers/nv30/nv30_clear.c
new file mode 100644 (file)
index 0000000..c11e9e0
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "pipe/p_defines.h"
+#include "util/u_pack_color.h"
+
+#include "nouveau/nouveau_gldefs.h"
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_format.h"
+
+static INLINE uint32_t
+pack_rgba(enum pipe_format format, const float *rgba)
+{
+   union util_color uc;
+   util_pack_color(rgba, format, &uc);
+   return uc.ui;
+}
+
+static INLINE uint32_t
+pack_zeta(enum pipe_format format, double depth, unsigned stencil)
+{
+   uint32_t zuint = (uint32_t)(depth * 4294967295.0);
+   if (format != PIPE_FORMAT_Z16_UNORM)
+      return (zuint & 0xffffff00) | (stencil & 0xff);
+   return zuint >> 16;
+}
+
+static void
+nv30_clear(struct pipe_context *pipe, unsigned buffers,
+           const union pipe_color_union *color, double depth, unsigned stencil)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct pipe_framebuffer_state *fb = &nv30->framebuffer;
+   uint32_t colr = 0, zeta = 0, mode = 0;
+
+   if (!nv30_state_validate(nv30, TRUE))
+      return;
+
+   if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
+      colr  = pack_rgba(fb->cbufs[0]->format, color->f);
+      mode |= NV30_3D_CLEAR_BUFFERS_COLOR_R |
+              NV30_3D_CLEAR_BUFFERS_COLOR_G |
+              NV30_3D_CLEAR_BUFFERS_COLOR_B |
+              NV30_3D_CLEAR_BUFFERS_COLOR_A;
+   }
+
+   if (fb->zsbuf) {
+      zeta = pack_zeta(fb->zsbuf->format, depth, stencil);
+      if (buffers & PIPE_CLEAR_DEPTH)
+         mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;
+      if (buffers & PIPE_CLEAR_STENCIL)
+         mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;
+   }
+
+   /*XXX: wtf? fixes clears sometimes not clearing on nv3x... */
+   if (nv30->screen->eng3d->oclass < NV40_3D_CLASS) {
+      BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);
+      PUSH_DATA (push, zeta);
+      PUSH_DATA (push, colr);
+      PUSH_DATA (push, mode);
+   }
+
+   BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);
+   PUSH_DATA (push, zeta);
+   PUSH_DATA (push, colr);
+   PUSH_DATA (push, mode);
+
+   nv30_state_release(nv30);
+}
+
+static void
+nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
+                         const union pipe_color_union *color,
+                         unsigned x, unsigned y, unsigned w, unsigned h)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nv30_surface *sf = nv30_surface(ps);
+   struct nv30_miptree *mt = nv30_miptree(ps->texture);
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nouveau_object *eng3d = nv30->screen->eng3d;
+   struct nouveau_pushbuf_refn refn;
+   uint32_t rt_format;
+
+   rt_format = nv30_format(pipe->screen, ps->format)->hw;
+   if (util_format_get_blocksize(ps->format) == 4)
+      rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
+   else
+      rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;
+
+   if (nv30_miptree(ps->texture)->swizzled) {
+      rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
+      rt_format |= util_logbase2(sf->width) << 16;
+      rt_format |= util_logbase2(sf->height) << 24;
+   } else {
+      rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
+   }
+
+   refn.bo = mt->base.bo;
+   refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
+   if (nouveau_pushbuf_space(push, 16, 1, 0) ||
+       nouveau_pushbuf_refn (push, &refn, 1))
+      return;
+
+   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
+   PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);
+   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
+   PUSH_DATA (push, sf->width << 16);
+   PUSH_DATA (push, sf->height << 16);
+   PUSH_DATA (push, rt_format);
+   BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 2);
+   if (eng3d->oclass < NV40_3D_CLASS)
+      PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
+   else
+      PUSH_DATA (push, sf->pitch);
+   PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
+   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
+   PUSH_DATA (push, (w << 16) | x);
+   PUSH_DATA (push, (h << 16) | y);
+
+   BEGIN_NV04(push, NV30_3D(CLEAR_COLOR_VALUE), 2);
+   PUSH_DATA (push, pack_rgba(ps->format, color->f));
+   PUSH_DATA (push, NV30_3D_CLEAR_BUFFERS_COLOR_R |
+                    NV30_3D_CLEAR_BUFFERS_COLOR_G |
+                    NV30_3D_CLEAR_BUFFERS_COLOR_B |
+                    NV30_3D_CLEAR_BUFFERS_COLOR_A);
+
+   nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
+}
+
+static void
+nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,
+                         unsigned buffers, double depth, unsigned stencil,
+                         unsigned x, unsigned y, unsigned w, unsigned h)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nv30_surface *sf = nv30_surface(ps);
+   struct nv30_miptree *mt = nv30_miptree(ps->texture);
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nouveau_object *eng3d = nv30->screen->eng3d;
+   struct nouveau_pushbuf_refn refn;
+   uint32_t rt_format, mode = 0;
+
+   rt_format = nv30_format(pipe->screen, ps->format)->hw;
+   if (util_format_get_blocksize(ps->format) == 4)
+      rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;
+   else
+      rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;
+
+   if (nv30_miptree(ps->texture)->swizzled) {
+      rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
+      rt_format |= util_logbase2(sf->width) << 16;
+      rt_format |= util_logbase2(sf->height) << 24;
+   } else {
+      rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
+   }
+
+   if (buffers & PIPE_CLEAR_DEPTH)
+      mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;
+   if (buffers & PIPE_CLEAR_STENCIL)
+      mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;
+
+   refn.bo = mt->base.bo;
+   refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
+   if (nouveau_pushbuf_space(push, 32, 1, 0) ||
+       nouveau_pushbuf_refn (push, &refn, 1))
+      return;
+
+   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
+   PUSH_DATA (push, sf->width << 16);
+   PUSH_DATA (push, sf->height << 16);
+   PUSH_DATA (push, rt_format);
+   if (eng3d->oclass < NV40_3D_CLASS) {
+      BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 1);
+      PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
+   } else {
+      BEGIN_NV04(push, NV40_3D(ZETA_PITCH), 1);
+      PUSH_DATA (push, sf->pitch);
+   }
+   BEGIN_NV04(push, NV30_3D(ZETA_OFFSET), 1);
+   PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
+   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
+   PUSH_DATA (push, (w << 16) | x);
+   PUSH_DATA (push, (h << 16) | y);
+
+   BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 1);
+   PUSH_DATA (push, pack_zeta(ps->format, depth, stencil));
+   BEGIN_NV04(push, NV30_3D(CLEAR_BUFFERS), 1);
+   PUSH_DATA (push, mode);
+
+   nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
+}
+
+void
+nv30_clear_init(struct pipe_context *pipe)
+{
+   pipe->clear = nv30_clear;
+   pipe->clear_render_target = nv30_clear_render_target;
+   pipe->clear_depth_stencil = nv30_clear_depth_stencil;
+}
diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c
new file mode 100644 (file)
index 0000000..258ea72
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "draw/draw_context.h"
+
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+
+#include "nouveau/nouveau_fence.h"
+#include "nv30_context.h"
+#include "nv30_transfer.h"
+#include "nv30_state.h"
+
+static void
+nv30_context_kick_notify(struct nouveau_pushbuf *push)
+{
+   struct nouveau_screen *screen;
+   struct nv30_context *nv30;
+
+   if (!push->user_priv)
+      return;
+   nv30 = container_of(push->user_priv, nv30, bufctx);
+   screen = &nv30->screen->base;
+
+   nouveau_fence_next(screen);
+   nouveau_fence_update(screen, TRUE);
+
+   if (push->bufctx) {
+      struct nouveau_bufref *bref;
+      LIST_FOR_EACH_ENTRY(bref, &push->bufctx->current, thead) {
+         struct nv04_resource *res = bref->priv;
+         if (res && res->mm) {
+            nouveau_fence_ref(screen->fence.current, &res->fence);
+
+            if (bref->flags & NOUVEAU_BO_RD)
+               res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
+
+            if (bref->flags & NOUVEAU_BO_WR) {
+               nouveau_fence_ref(screen->fence.current, &res->fence_wr);
+               res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
+            }
+         }
+      }
+   }
+}
+
+static void
+nv30_context_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+   if (fence)
+      nouveau_fence_ref(nv30->screen->base.fence.current,
+                        (struct nouveau_fence **)fence);
+
+   PUSH_KICK(push);
+}
+
+static void
+nv30_context_destroy(struct pipe_context *pipe)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+
+   if (nv30->draw)
+      draw_destroy(nv30->draw);
+
+   nouveau_bufctx_del(&nv30->bufctx);
+
+   if (nv30->screen->cur_ctx == nv30)
+      nv30->screen->cur_ctx = NULL;
+
+   FREE(nv30);
+}
+
+#define FAIL_CONTEXT_INIT(str, err)                   \
+   do {                                               \
+      NOUVEAU_ERR(str, err);                          \
+      nv30_context_destroy(pipe);                     \
+      return NULL;                                    \
+   } while(0)
+
+struct pipe_context *
+nv30_context_create(struct pipe_screen *pscreen, void *priv)
+{
+   struct nv30_screen *screen = nv30_screen(pscreen);
+   struct nv30_context *nv30 = CALLOC_STRUCT(nv30_context);
+   struct nouveau_pushbuf *push;
+   struct pipe_context *pipe;
+   int ret;
+
+   if (!nv30)
+      return NULL;
+
+   nv30->screen = screen;
+   nv30->base.screen = &screen->base;
+   nv30->base.copy_data = nv30_transfer_copy_data;
+
+   pipe = &nv30->base.pipe;
+   pipe->screen = pscreen;
+   pipe->priv = priv;
+   pipe->destroy = nv30_context_destroy;
+   pipe->flush = nv30_context_flush;
+
+   /*XXX: *cough* per-context client */
+   nv30->base.client = screen->base.client;
+
+   /*XXX: *cough* per-context pushbufs */
+   push = screen->base.pushbuf;
+   nv30->base.pushbuf = push;
+   nv30->base.pushbuf->user_priv = push->user_priv; /* hack at validate time */
+   nv30->base.pushbuf->rsvd_kick = 16; /* hack in screen before first space */
+   nv30->base.pushbuf->kick_notify = nv30_context_kick_notify;
+
+   ret = nouveau_bufctx_new(nv30->base.client, 64, &nv30->bufctx);
+   if (ret) {
+      nv30_context_destroy(pipe);
+      return NULL;
+   }
+
+   /*XXX: make configurable with performance vs quality, these defaults
+    *     match the binary driver's defaults
+    */
+   if (screen->eng3d->oclass < NV40_3D_CLASS)
+      nv30->config.filter = 0x00000004;
+   else
+      nv30->config.filter = 0x00002dc4;
+
+   nv30->config.aniso = NV40_3D_TEX_WRAP_ANISO_MIP_FILTER_OPTIMIZATION_OFF;
+
+   if (debug_get_bool_option("NV30_SWTNL", FALSE))
+      nv30->draw_flags |= NV30_NEW_SWTNL;
+
+   /*XXX: nvfx... */
+   nv30->is_nv4x = (screen->eng3d->oclass >= NV40_3D_CLASS) ? ~0 : 0;
+   nv30->use_nv4x = (screen->eng3d->oclass >= NV40_3D_CLASS) ? ~0 : 0;
+   nv30->render_mode = HW;
+
+   nv30_vbo_init(pipe);
+   nv30_query_init(pipe);
+   nv30_state_init(pipe);
+   nv30_resource_init(pipe);
+   nv30_clear_init(pipe);
+   nv30_fragprog_init(pipe);
+   nv30_vertprog_init(pipe);
+   nv30_texture_init(pipe);
+   nv30_fragtex_init(pipe);
+   nv40_verttex_init(pipe);
+   nv30_draw_init(pipe);
+
+   return pipe;
+}
diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h
new file mode 100644 (file)
index 0000000..0a6f97f
--- /dev/null
@@ -0,0 +1,231 @@
+#ifndef __NV30_CONTEXT_H__
+#define __NV30_CONTEXT_H__
+
+#include "pipe/p_format.h"
+
+#include "nv30_screen.h"
+#include "nv30_state.h"
+
+#include "nouveau/nouveau_context.h"
+
+#define BUFCTX_FB          0
+#define BUFCTX_VTXTMP      1
+#define BUFCTX_VTXBUF      2
+#define BUFCTX_IDXBUF      3
+#define BUFCTX_VERTTEX(n) (4 + (n))
+#define BUFCTX_FRAGPROG    8
+#define BUFCTX_FRAGTEX(n) (9 + (n))
+
+#define NV30_NEW_BLEND        (1 << 0)
+#define NV30_NEW_RASTERIZER   (1 << 1)
+#define NV30_NEW_ZSA          (1 << 2)
+#define NV30_NEW_VERTPROG     (1 << 3)
+#define NV30_NEW_VERTCONST    (1 << 4)
+#define NV30_NEW_FRAGPROG     (1 << 5)
+#define NV30_NEW_FRAGCONST    (1 << 6)
+#define NV30_NEW_BLEND_COLOUR (1 << 7)
+#define NV30_NEW_STENCIL_REF  (1 << 8)
+#define NV30_NEW_CLIP         (1 << 9)
+#define NV30_NEW_SAMPLE_MASK  (1 << 10)
+#define NV30_NEW_FRAMEBUFFER  (1 << 11)
+#define NV30_NEW_STIPPLE      (1 << 12)
+#define NV30_NEW_SCISSOR      (1 << 13)
+#define NV30_NEW_VIEWPORT     (1 << 14)
+#define NV30_NEW_ARRAYS       (1 << 15)
+#define NV30_NEW_VERTEX       (1 << 16)
+#define NV30_NEW_CONSTBUF     (1 << 17)
+#define NV30_NEW_FRAGTEX      (1 << 18)
+#define NV30_NEW_VERTTEX      (1 << 19)
+#define NV30_NEW_SWTNL        (1 << 31)
+#define NV30_NEW_ALL          0x000fffff
+
+struct nv30_context {
+   struct nouveau_context base;
+   struct nv30_screen *screen;
+
+   struct nouveau_bufctx *bufctx;
+
+   struct {
+      unsigned rt_enable;
+      unsigned scissor_off;
+      unsigned num_vtxelts;
+      boolean  prim_restart;
+      struct nv30_fragprog *fragprog;
+   } state;
+
+   uint32_t dirty;
+
+   struct draw_context *draw;
+   uint32_t draw_flags;
+   uint32_t draw_dirty;
+
+   struct nv30_blend_stateobj *blend;
+   struct nv30_rasterizer_stateobj *rast;
+   struct nv30_zsa_stateobj *zsa;
+   struct nv30_vertex_stateobj *vertex;
+
+   struct {
+      unsigned filter;
+      unsigned aniso;
+   } config;
+
+   struct {
+      struct nv30_vertprog *program;
+
+      struct pipe_resource *constbuf;
+      unsigned constbuf_nr;
+
+      struct pipe_sampler_view *textures[PIPE_MAX_SAMPLERS];
+      unsigned num_textures;
+      struct nv30_sampler_state *samplers[PIPE_MAX_SAMPLERS];
+      unsigned num_samplers;
+      unsigned dirty_samplers;
+   } vertprog;
+
+   struct {
+      struct nv30_fragprog *program;
+
+      struct pipe_resource *constbuf;
+      unsigned constbuf_nr;
+
+      struct pipe_sampler_view *textures[PIPE_MAX_SAMPLERS];
+      unsigned num_textures;
+      struct nv30_sampler_state *samplers[PIPE_MAX_SAMPLERS];
+      unsigned num_samplers;
+      unsigned dirty_samplers;
+   } fragprog;
+
+   struct pipe_framebuffer_state framebuffer;
+   struct pipe_blend_color blend_colour;
+   struct pipe_stencil_ref stencil_ref;
+   struct pipe_poly_stipple stipple;
+   struct pipe_scissor_state scissor;
+   struct pipe_viewport_state viewport;
+   struct pipe_clip_state clip;
+
+   unsigned sample_mask;
+
+   struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
+   unsigned num_vtxbufs;
+   struct pipe_index_buffer idxbuf;
+   uint32_t vbo_fifo;
+   uint32_t vbo_user;
+   unsigned vbo_min_index;
+   unsigned vbo_max_index;
+   boolean  vbo_push_hint;
+
+   struct nouveau_heap  *blit_vp;
+   struct pipe_resource *blit_fp;
+
+   /*XXX: nvfx state, DO NOT USE EVER OUTSIDE "STOLEN" NVFX code */
+   unsigned is_nv4x;
+   unsigned use_nv4x;
+   bool hw_pointsprite_control;
+   enum {
+      HW,
+   } render_mode;
+};
+
+static INLINE struct nv30_context *
+nv30_context(struct pipe_context *pipe)
+{
+   return (struct nv30_context *)pipe;
+}
+
+struct pipe_context *
+nv30_context_create(struct pipe_screen *pscreen, void *priv);
+
+void
+nv30_vbo_init(struct pipe_context *pipe);
+
+void
+nv30_vbo_validate(struct nv30_context *nv30);
+
+void
+nv30_query_init(struct pipe_context *pipe);
+
+void
+nv30_state_init(struct pipe_context *pipe);
+
+void
+nv30_clear_init(struct pipe_context *pipe);
+
+void
+nv30_vertprog_init(struct pipe_context *pipe);
+
+void
+nv30_vertprog_validate(struct nv30_context *nv30);
+
+void
+nv30_fragprog_init(struct pipe_context *pipe);
+
+void
+nv30_fragprog_validate(struct nv30_context *nv30);
+
+void
+nv30_texture_init(struct pipe_context *pipe);
+
+void
+nv30_texture_validate(struct nv30_context *nv30);
+
+void
+nv30_fragtex_init(struct pipe_context *pipe);
+
+void
+nv30_fragtex_validate(struct nv30_context *nv30);
+
+void
+nv40_verttex_init(struct pipe_context *pipe);
+
+void
+nv40_verttex_validate(struct nv30_context *nv30);
+
+void
+nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info);
+
+void
+nv30_draw_init(struct pipe_context *pipe);
+
+void
+nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info);
+
+boolean
+nv30_state_validate(struct nv30_context *nv30, boolean hwtnl);
+
+void
+nv30_state_release(struct nv30_context *nv30);
+
+//XXX: needed to make it build, clean this up!
+void
+_nvfx_fragprog_translate(struct nv30_context *nvfx, struct nv30_fragprog *fp,
+         boolean emulate_sprite_flipping);
+
+boolean
+_nvfx_vertprog_translate(struct nv30_context *nv30, struct nv30_vertprog *vp);
+
+#ifdef NV30_3D_VERTEX_BEGIN_END
+#define NV30_PRIM_GL_CASE(n) \
+   case PIPE_PRIM_##n: return NV30_3D_VERTEX_BEGIN_END_##n
+
+static INLINE unsigned
+nv30_prim_gl(unsigned prim)
+{
+   switch (prim) {
+   NV30_PRIM_GL_CASE(POINTS);
+   NV30_PRIM_GL_CASE(LINES);
+   NV30_PRIM_GL_CASE(LINE_LOOP);
+   NV30_PRIM_GL_CASE(LINE_STRIP);
+   NV30_PRIM_GL_CASE(TRIANGLES);
+   NV30_PRIM_GL_CASE(TRIANGLE_STRIP);
+   NV30_PRIM_GL_CASE(TRIANGLE_FAN);
+   NV30_PRIM_GL_CASE(QUADS);
+   NV30_PRIM_GL_CASE(QUAD_STRIP);
+   NV30_PRIM_GL_CASE(POLYGON);
+   default:
+      return NV30_3D_VERTEX_BEGIN_END_POINTS;
+      break;
+   }
+}
+#endif
+
+#endif
diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c
new file mode 100644 (file)
index 0000000..61e3246
--- /dev/null
@@ -0,0 +1,496 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "draw/draw_context.h"
+#include "draw/draw_vertex.h"
+#include "draw/draw_pipe.h"
+#include "draw/draw_vbuf.h"
+#include "draw/draw_private.h"
+
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_format.h"
+
+struct nv30_render {
+   struct vbuf_render base;
+   struct nv30_context *nv30;
+
+   struct pipe_transfer *transfer;
+   struct pipe_resource *buffer;
+   unsigned offset;
+   unsigned length;
+
+   struct vertex_info vertex_info;
+
+   struct nouveau_heap *vertprog;
+   uint32_t vtxprog[16][4];
+   uint32_t vtxfmt[16];
+   uint32_t vtxptr[16];
+   uint32_t prim;
+};
+
+static INLINE struct nv30_render *
+nv30_render(struct vbuf_render *render)
+{
+   return (struct nv30_render *)render;
+}
+
+static const struct vertex_info *
+nv30_render_get_vertex_info(struct vbuf_render *render)
+{
+   return &nv30_render(render)->vertex_info;
+}
+
+static boolean
+nv30_render_allocate_vertices(struct vbuf_render *render,
+                              ushort vertex_size, ushort nr_vertices)
+{
+   struct nv30_render *r = nv30_render(render);
+   struct nv30_context *nv30 = r->nv30;
+
+   r->length = vertex_size * nr_vertices;
+
+   if (r->offset + r->length >= render->max_vertex_buffer_bytes) {
+      pipe_resource_reference(&r->buffer, NULL);
+      r->buffer = pipe_buffer_create(&nv30->screen->base.base,
+                                     PIPE_BIND_VERTEX_BUFFER, 0,
+                                     render->max_vertex_buffer_bytes);
+      if (!r->buffer)
+         return FALSE;
+
+      r->offset = 0;
+   }
+
+   return TRUE;
+}
+
+static void *
+nv30_render_map_vertices(struct vbuf_render *render)
+{
+   struct nv30_render *r = nv30_render(render);
+   char *map = pipe_buffer_map(&r->nv30->base.pipe, r->buffer,
+                               PIPE_TRANSFER_WRITE |
+                               PIPE_TRANSFER_UNSYNCHRONIZED, &r->transfer);
+   return map + r->offset;
+}
+
+static void
+nv30_render_unmap_vertices(struct vbuf_render *render,
+                           ushort min_index, ushort max_index)
+{
+   struct nv30_render *r = nv30_render(render);
+   pipe_buffer_unmap(&r->nv30->base.pipe, r->transfer);
+}
+
+static void
+nv30_render_set_primitive(struct vbuf_render *render, unsigned prim)
+{
+   struct nv30_render *r = nv30_render(render);
+
+   r->prim = nv30_prim_gl(prim);
+}
+
+static void
+nv30_render_draw_elements(struct vbuf_render *render,
+                          const ushort *indices, uint count)
+{
+   struct nv30_render *r = nv30_render(render);
+   struct nv30_context *nv30 = r->nv30;
+   struct nouveau_pushbuf *push = nv30->screen->base.pushbuf;
+   unsigned i;
+
+   BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
+   for (i = 0; i < r->vertex_info.num_attribs; i++) {
+      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
+                       nv04_resource(r->buffer), r->offset + r->vtxptr[i],
+                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0);
+   }
+
+   if (!nv30_state_validate(nv30, FALSE))
+      return;
+
+   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+   PUSH_DATA (push, r->prim);
+
+   if (count & 1) {
+      BEGIN_NV04(push, NV30_3D(VB_ELEMENT_U32), 1);
+      PUSH_DATA (push, *indices++);
+   }
+
+   count >>= 1;
+   while (count) {
+      unsigned npush = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
+      count -= npush;
+
+      BEGIN_NI04(push, NV30_3D(VB_ELEMENT_U16), npush);
+      while (npush--) {
+         PUSH_DATA(push, (indices[1] << 16) | indices[0]);
+         indices += 2;
+      }
+   }
+
+   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
+   PUSH_RESET(push, BUFCTX_VTXTMP);
+}
+
+static void
+nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
+{
+   struct nv30_render *r = nv30_render(render);
+   struct nv30_context *nv30 = r->nv30;
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   unsigned fn = nr >> 8, pn = nr & 0xff;
+   unsigned ps = fn + (pn ? 1 : 0);
+   unsigned i;
+
+   BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
+   for (i = 0; i < r->vertex_info.num_attribs; i++) {
+      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
+                       nv04_resource(r->buffer), r->offset + r->vtxptr[i],
+                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0);
+   }
+
+   if (!nv30_state_validate(nv30, FALSE))
+      return;
+
+   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+   PUSH_DATA (push, r->prim);
+
+   BEGIN_NI04(push, NV30_3D(VB_VERTEX_BATCH), ps);
+   while (fn--) {
+      PUSH_DATA (push, 0xff000000 | start);
+      start += 256;
+   }
+
+   if (pn)
+      PUSH_DATA (push, ((pn - 1) << 24) | start);
+
+   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
+   PUSH_RESET(push, BUFCTX_VTXTMP);
+}
+
+static void
+nv30_render_release_vertices(struct vbuf_render *render)
+{
+   struct nv30_render *r = nv30_render(render);
+   r->offset += r->length;
+}
+
+static const struct {
+   unsigned emit;
+   unsigned interp;
+   unsigned vp30;
+   unsigned vp40;
+   unsigned ow40;
+} vroute [] = {
+   [TGSI_SEMANTIC_POSITION] = { EMIT_4F, INTERP_PERSPECTIVE, 0, 0, 0x00000000 },
+   [TGSI_SEMANTIC_COLOR   ] = { EMIT_4F, INTERP_LINEAR     , 3, 1, 0x00000001 },
+   [TGSI_SEMANTIC_BCOLOR  ] = { EMIT_4F, INTERP_LINEAR     , 1, 3, 0x00000004 },
+   [TGSI_SEMANTIC_FOG     ] = { EMIT_4F, INTERP_PERSPECTIVE, 5, 5, 0x00000010 },
+   [TGSI_SEMANTIC_PSIZE   ] = { EMIT_1F_PSIZE, INTERP_POS  , 6, 6, 0x00000020 },
+   [TGSI_SEMANTIC_GENERIC ] = { EMIT_4F, INTERP_PERSPECTIVE, 8, 7, 0x00004000 }
+};
+
+static boolean
+vroute_add(struct nv30_render *r, uint attrib, uint sem, uint *idx)
+{
+   struct pipe_screen *pscreen = &r->nv30->screen->base.base;
+   struct nv30_fragprog *fp = r->nv30->fragprog.program;
+   struct vertex_info *vinfo = &r->vertex_info;
+   enum pipe_format format;
+   uint emit = EMIT_OMIT;
+   uint result = *idx;
+
+   if (sem == TGSI_SEMANTIC_GENERIC && result >= 8) {
+      for (result = 0; result < 8; result++) {
+         if (fp->texcoord[result] == *idx) {
+            emit = vroute[sem].emit;
+            break;
+         }
+      }
+   } else {
+      emit = vroute[sem].emit;
+   }
+
+   if (emit == EMIT_OMIT)
+      return FALSE;
+
+   draw_emit_vertex_attr(vinfo, emit, vroute[sem].interp, attrib);
+   format = draw_translate_vinfo_format(emit);
+
+   r->vtxfmt[attrib] = nv30_vtxfmt(pscreen, format)->hw;
+   r->vtxptr[attrib] = vinfo->size | NV30_3D_VTXBUF_DMA1;
+   vinfo->size += draw_translate_vinfo_size(emit);
+
+   if (nv30_screen(pscreen)->eng3d->oclass < NV40_3D_CLASS) {
+      r->vtxprog[attrib][0] = 0x001f38d8;
+      r->vtxprog[attrib][1] = 0x0080001b | (attrib << 9);
+      r->vtxprog[attrib][2] = 0x0836106c;
+      r->vtxprog[attrib][3] = 0x2000f800 | (result + vroute[sem].vp30) << 2;
+   } else {
+      r->vtxprog[attrib][0] = 0x401f9c6c;
+      r->vtxprog[attrib][1] = 0x0040000d | (attrib << 8);
+      r->vtxprog[attrib][2] = 0x8106c083;
+      r->vtxprog[attrib][3] = 0x6041ff80 | (result + vroute[sem].vp40) << 2;
+   }
+
+   *idx = vroute[sem].ow40 << result;
+   return TRUE;
+}
+
+static boolean
+nv30_render_validate(struct nv30_context *nv30)
+{
+   struct nv30_render *r = nv30_render(nv30->draw->render);
+   struct nv30_rasterizer_stateobj *rast = nv30->rast;
+   struct pipe_screen *pscreen = &nv30->screen->base.base;
+   struct nouveau_pushbuf *push = nv30->screen->base.pushbuf;
+   struct nouveau_object *eng3d = nv30->screen->eng3d;
+   struct nv30_vertprog *vp = nv30->vertprog.program;
+   struct vertex_info *vinfo = &r->vertex_info;
+   unsigned vp_attribs = 0;
+   unsigned vp_results = 0;
+   unsigned attrib = 0;
+   unsigned pntc;
+   int i;
+
+   if (!r->vertprog) {
+      struct nouveau_heap *heap = nv30_screen(pscreen)->vp_exec_heap;
+      if (nouveau_heap_alloc(heap, 16, &r->vertprog, &r->vertprog)) {
+         while (heap->next && heap->size < 16) {
+            struct nouveau_heap **evict = heap->next->priv;
+            nouveau_heap_free(evict);
+         }
+
+         if (nouveau_heap_alloc(heap, 16, &r->vertprog, &r->vertprog))
+            return FALSE;
+      }
+   }
+
+   vinfo->num_attribs = 0;
+   vinfo->size = 0;
+
+   /* setup routing for all necessary vp outputs */
+   for (i = 0; i < vp->info.num_outputs && attrib < 16; i++) {
+      uint semantic = vp->info.output_semantic_name[i];
+      uint index = vp->info.output_semantic_index[i];
+      if (vroute_add(r, attrib, semantic, &index)) {
+         vp_attribs |= (1 << attrib++);
+         vp_results |= index;
+      }
+   }
+
+   /* setup routing for replaced point coords not written by vp */
+   if (rast && rast->pipe.point_quad_rasterization)
+      pntc = rast->pipe.sprite_coord_enable & 0x000002ff;
+   else
+      pntc = 0;
+
+   while (pntc && attrib < 16) {
+      uint index = ffs(pntc) - 1; pntc &= ~(1 << index);
+      if (vroute_add(r, attrib, TGSI_SEMANTIC_GENERIC, &index)) {
+         vp_attribs |= (1 << attrib++);
+         vp_results |= index;
+      }
+   }
+
+   /* modify vertex format for correct stride, and stub out unused ones */
+   BEGIN_NV04(push, NV30_3D(VP_UPLOAD_FROM_ID), 1);
+   PUSH_DATA (push, r->vertprog->start);
+   r->vtxprog[attrib - 1][3] |= 1;
+   for (i = 0; i < attrib; i++) {
+      BEGIN_NV04(push, NV30_3D(VP_UPLOAD_INST(0)), 4);
+      PUSH_DATAp(push, r->vtxprog[i], 4);
+      r->vtxfmt[i] |= vinfo->size << 8;
+   }
+   for (; i < 16; i++)
+      r->vtxfmt[i]  = NV30_3D_VTXFMT_TYPE_V32_FLOAT;
+
+   BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8);
+   PUSH_DATAf(push, 0.0);
+   PUSH_DATAf(push, 0.0);
+   PUSH_DATAf(push, 0.0);
+   PUSH_DATAf(push, 0.0);
+   PUSH_DATAf(push, 1.0);
+   PUSH_DATAf(push, 1.0);
+   PUSH_DATAf(push, 1.0);
+   PUSH_DATAf(push, 1.0);
+   BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2);
+   PUSH_DATAf(push, 0.0);
+   PUSH_DATAf(push, 1.0);
+
+   BEGIN_NV04(push, NV30_3D(VTXFMT(0)), 16);
+   PUSH_DATAp(push, r->vtxfmt, 16);
+
+   BEGIN_NV04(push, NV30_3D(VP_START_FROM_ID), 1);
+   PUSH_DATA (push, r->vertprog->start);
+   BEGIN_NV04(push, NV30_3D(ENGINE), 1);
+   PUSH_DATA (push, 0x00000103);
+   if (eng3d->oclass >= NV40_3D_CLASS) {
+      BEGIN_NV04(push, NV40_3D(VP_ATTRIB_EN), 2);
+      PUSH_DATA (push, vp_attribs);
+      PUSH_DATA (push, vp_results);
+   }
+
+   vinfo->size /= 4;
+   return TRUE;
+}
+
+void
+nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct draw_context *draw = nv30->draw;
+   struct pipe_transfer *transfer[PIPE_MAX_ATTRIBS];
+   struct pipe_transfer *transferi = NULL;
+   int i;
+
+   nv30_render_validate(nv30);
+
+   if (nv30->draw_dirty & NV30_NEW_VIEWPORT)
+      draw_set_viewport_state(draw, &nv30->viewport);
+   if (nv30->draw_dirty & NV30_NEW_RASTERIZER)
+      draw_set_rasterizer_state(draw, &nv30->rast->pipe, NULL);
+   if (nv30->draw_dirty & NV30_NEW_CLIP)
+      draw_set_clip_state(draw, &nv30->clip);
+   if (nv30->draw_dirty & NV30_NEW_ARRAYS) {
+      draw_set_vertex_buffers(draw, nv30->num_vtxbufs, nv30->vtxbuf);
+      draw_set_vertex_elements(draw, nv30->vertex->num_elements, nv30->vertex->pipe);
+   }
+   if (nv30->draw_dirty & NV30_NEW_FRAGPROG) {
+      struct nv30_fragprog *fp = nv30->fragprog.program;
+      if (!fp->draw)
+         fp->draw = draw_create_fragment_shader(draw, &fp->pipe);
+      draw_bind_fragment_shader(draw, fp->draw);
+   }
+   if (nv30->draw_dirty & NV30_NEW_VERTPROG) {
+      struct nv30_vertprog *vp = nv30->vertprog.program;
+      if (!vp->draw)
+         vp->draw = draw_create_vertex_shader(draw, &vp->pipe);
+      draw_bind_vertex_shader(draw, vp->draw);
+   }
+   if (nv30->draw_dirty & NV30_NEW_VERTCONST) {
+      if (nv30->vertprog.constbuf) {
+         void *map = nv04_resource(nv30->vertprog.constbuf)->data;
+         draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
+                                         map, nv30->vertprog.constbuf_nr);
+      }
+   }
+
+   for (i = 0; i < nv30->num_vtxbufs; i++) {
+      void *map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer,
+                                  PIPE_TRANSFER_UNSYNCHRONIZED |
+                                  PIPE_TRANSFER_READ, &transfer[i]);
+      draw_set_mapped_vertex_buffer(draw, i, map);
+   }
+
+   if (info->indexed) {
+      void *map = pipe_buffer_map(pipe, nv30->idxbuf.buffer,
+                                  PIPE_TRANSFER_UNSYNCHRONIZED |
+                                  PIPE_TRANSFER_READ, &transferi);
+      draw_set_index_buffer(draw, &nv30->idxbuf);
+      draw_set_mapped_index_buffer(draw, map);
+   } else {
+      draw_set_mapped_index_buffer(draw, NULL);
+   }
+
+   draw_vbo(draw, info);
+   draw_flush(draw);
+
+   if (info->indexed)
+      pipe_buffer_unmap(pipe, transferi);
+   for (i = 0; i < nv30->num_vtxbufs; i++)
+      pipe_buffer_unmap(pipe, transfer[i]);
+
+   nv30->draw_dirty = 0;
+   nv30_state_release(nv30);
+}
+
+static void
+nv30_render_destroy(struct vbuf_render *render)
+{
+   FREE(render);
+}
+
+static struct vbuf_render *
+nv30_render_create(struct nv30_context *nv30)
+{
+   struct nv30_render *r = CALLOC_STRUCT(nv30_render);
+   if (!r)
+      return NULL;
+
+   r->nv30 = nv30;
+   r->offset = 1 * 1024 * 1024;
+
+   r->base.max_indices = 16 * 1024;
+   r->base.max_vertex_buffer_bytes = r->offset;
+
+   r->base.get_vertex_info = nv30_render_get_vertex_info;
+   r->base.allocate_vertices = nv30_render_allocate_vertices;
+   r->base.map_vertices = nv30_render_map_vertices;
+   r->base.unmap_vertices = nv30_render_unmap_vertices;
+   r->base.set_primitive = nv30_render_set_primitive;
+   r->base.draw_elements = nv30_render_draw_elements;
+   r->base.draw_arrays = nv30_render_draw_arrays;
+   r->base.release_vertices = nv30_render_release_vertices;
+   r->base.destroy = nv30_render_destroy;
+   return &r->base;
+}
+
+void
+nv30_draw_init(struct pipe_context *pipe)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct vbuf_render *render;
+   struct draw_context *draw;
+   struct draw_stage *stage;
+
+   draw = draw_create(pipe);
+   if (!draw)
+      return;
+
+   render = nv30_render_create(nv30);
+   if (!render) {
+      draw_destroy(draw);
+      return;
+   }
+
+   stage = draw_vbuf_stage(draw, render);
+   if (!stage) {
+      render->destroy(render);
+      draw_destroy(draw);
+      return;
+   }
+
+   draw_set_render(draw, render);
+   draw_set_rasterize_stage(draw, stage);
+   draw_wide_line_threshold(draw, 10000000.f);
+   draw_wide_point_threshold(draw, 10000000.f);
+   draw_wide_point_sprites(draw, TRUE);
+   nv30->draw = draw;
+}
diff --git a/src/gallium/drivers/nv30/nv30_format.c b/src/gallium/drivers/nv30/nv30_format.c
new file mode 100644 (file)
index 0000000..b210c2c
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_format.h"
+
+#define NV30_3D_RT_FORMAT_COLOR_X1R5G5B5 2
+
+#define NV30_3D_TEX_FORMAT_FORMAT_A16L16 NV30_3D_TEX_FORMAT_FORMAT_HILO16
+#define NV30_3D_TEX_FORMAT_FORMAT_A16L16_RECT NV30_3D_TEX_FORMAT_FORMAT_HILO16_RECT
+#define NV30_3D_TEX_FORMAT_FORMAT_RGBA16F 0x00004a00
+#define NV30_3D_TEX_FORMAT_FORMAT_RGBA16F_RECT NV30_3D_TEX_FORMAT_FORMAT_RGBA16F
+#define NV30_3D_TEX_FORMAT_FORMAT_RGBA32F 0x00004b00
+#define NV30_3D_TEX_FORMAT_FORMAT_RGBA32F_RECT NV30_3D_TEX_FORMAT_FORMAT_RGBA32F
+#define NV30_3D_TEX_FORMAT_FORMAT_R32F 0x00004c00
+#define NV30_3D_TEX_FORMAT_FORMAT_R32F_RECT NV30_3D_TEX_FORMAT_FORMAT_R32F
+#define NV30_3D_TEX_FORMAT_FORMAT_DXT1_RECT NV30_3D_TEX_FORMAT_FORMAT_DXT1
+#define NV30_3D_TEX_FORMAT_FORMAT_DXT3_RECT NV30_3D_TEX_FORMAT_FORMAT_DXT3
+#define NV30_3D_TEX_FORMAT_FORMAT_DXT5_RECT NV30_3D_TEX_FORMAT_FORMAT_DXT5
+#define NV30_3D_TEX_FORMAT_FORMAT_RG16F 0xdeadcafe
+#define NV30_3D_TEX_FORMAT_FORMAT_RG16F_RECT 0xdeadcafe
+
+#define NV40_3D_TEX_FORMAT_FORMAT_R32F 0x00001c00
+#define NV40_3D_TEX_FORMAT_FORMAT_RG16F 0x00001f00
+
+#define ____ 0
+#define S___ PIPE_BIND_SAMPLER_VIEW
+#define _R__ PIPE_BIND_RENDER_TARGET
+#define _B__ PIPE_BIND_RENDER_TARGET | PIPE_BIND_BLENDABLE
+#define _Z__ PIPE_BIND_DEPTH_STENCIL
+#define __V_ PIPE_BIND_VERTEX_BUFFER
+#define SR__ (S___ | _R__)
+#define SB__ (S___ | _B__)
+#define SZ__ (S___ | _Z__)
+#define S_V_ (S___ | __V_)
+#define SRV_ (SR__ | __V_)
+#define SBV_ (SB__ | __V_)
+
+#define _(a,b) [PIPE_FORMAT_##a] = {                                           \
+   .bindings = (b),                                                            \
+}
+const struct nv30_format_info
+nv30_format_info_table[PIPE_FORMAT_COUNT] = {
+   _(L8_UNORM            , S___),
+   _(L8_SNORM            , S___),
+   _(L8_SRGB             , S___),
+   _(I8_UNORM            , S___),
+   _(I8_SNORM            , S___),
+   _(A8_UNORM            , S___),
+   _(A8_SNORM            , S___),
+   _(R8_UNORM            , S_V_),
+   _(R8_SNORM            , S___),
+   _(B5G5R5X1_UNORM      , SB__),
+   _(B5G5R5A1_UNORM      , S___),
+   _(B4G4R4X4_UNORM      , S___),
+   _(B4G4R4A4_UNORM      , S___),
+   _(B5G6R5_UNORM        , SB__),
+   _(B8G8R8X8_UNORM      , SB__),
+   _(B8G8R8X8_SRGB       , S___),
+   _(B8G8R8A8_UNORM      , SB__),
+   _(B8G8R8A8_SRGB       , S___),
+   _(R8G8B8A8_UNORM      , __V_),
+   _(R8G8B8A8_SNORM      , S___),
+   _(DXT1_RGB            , S___),
+   _(DXT1_SRGB           , S___),
+   _(DXT1_RGBA           , S___),
+   _(DXT1_SRGBA          , S___),
+   _(DXT3_RGBA           , S___),
+   _(DXT3_SRGBA          , S___),
+   _(DXT5_RGBA           , S___),
+   _(DXT5_SRGBA          , S___),
+   _(L8A8_UNORM          , S___),
+   _(L8A8_SRGB           , S___),
+   _(R8G8_UNORM          , S_V_),
+   _(R8G8_SNORM          , S___),
+   _(R8G8B8_UNORM        , __V_),
+   _(Z16_UNORM           , SZ__),
+   _(X8Z24_UNORM         , SZ__),
+   _(S8_UINT_Z24_UNORM   , SZ__),
+   _(L16_UNORM           , S___),
+   _(L16_SNORM           , S___),
+   _(I16_UNORM           , S___),
+   _(I16_SNORM           , S___),
+   _(A16_UNORM           , S___),
+   _(A16_SNORM           , S___),
+   _(R16_UNORM           , S___),
+   _(R16_SNORM           , S_V_),
+   _(R16G16_SNORM        , __V_),
+   _(R16G16B16_SNORM     , __V_),
+   _(R16G16B16A16_SNORM  , __V_),
+   _(R8_USCALED          , __V_),
+   _(R8G8_USCALED        , __V_),
+   _(R8G8B8_USCALED      , __V_),
+   _(R8G8B8A8_USCALED    , __V_),
+   _(R16_FLOAT           , __V_),
+   _(R16G16_FLOAT        , __V_), //S_V_),
+   _(R16G16B16_FLOAT     , __V_),
+   _(R16G16B16A16_FLOAT  , __V_), //SBV_),
+   _(R16_SSCALED         , __V_),
+   _(R16G16_SSCALED      , __V_),
+   _(R16G16B16_SSCALED   , __V_),
+   _(R16G16B16A16_SSCALED, __V_),
+   _(R32_FLOAT           , __V_), //SRV_),
+   _(R32G32_FLOAT        , __V_),
+   _(R32G32B32_FLOAT     , __V_),
+   _(R32G32B32A32_FLOAT  , __V_), //SRV_),
+};
+#undef _
+#undef ____
+
+#define R_(a,b) [PIPE_FORMAT_##a] = {                                          \
+   .hw = NV30_3D_RT_FORMAT_COLOR_##b,                                          \
+}
+#define Z_(a,b) [PIPE_FORMAT_##a] = {                                          \
+   .hw = NV30_3D_RT_FORMAT_ZETA_##b,                                           \
+}
+const struct nv30_format
+nv30_format_table[PIPE_FORMAT_COUNT] = {
+   R_(B5G5R5X1_UNORM    , X1R5G5B5          ),
+   R_(B5G6R5_UNORM      , R5G6B5            ),
+   R_(B8G8R8X8_UNORM    , X8R8G8B8          ),
+   R_(B8G8R8A8_UNORM    , A8R8G8B8          ),
+   Z_(Z16_UNORM         , Z16               ),
+   Z_(X8Z24_UNORM       , Z24S8             ),
+   Z_(S8_UINT_Z24_UNORM , Z24S8             ),
+   R_(R16G16B16A16_FLOAT, A16B16G16R16_FLOAT),
+   R_(R32G32B32A32_FLOAT, A32B32G32R32_FLOAT),
+   R_(R32_FLOAT         , R32_FLOAT         ),
+};
+
+#define _(a,b,c) [PIPE_FORMAT_##a] = {                                         \
+   .hw = NV30_3D_VTXFMT_TYPE_##b | ((c) << NV30_3D_VTXFMT_SIZE__SHIFT)         \
+}
+const struct nv30_vtxfmt
+nv30_vtxfmt_table[PIPE_FORMAT_COUNT] = {
+   _(R8_UNORM            , U8_UNORM   , 1),
+   _(R8G8_UNORM          , U8_UNORM   , 2),
+   _(R8G8B8_UNORM        , U8_UNORM   , 3),
+   _(R8G8B8A8_UNORM      , U8_UNORM   , 4),
+   _(R8_USCALED          , U8_USCALED , 1),
+   _(R8G8_USCALED        , U8_USCALED , 2),
+   _(R8G8B8_USCALED      , U8_USCALED , 3),
+   _(R8G8B8A8_USCALED    , U8_USCALED , 4),
+   _(R16_SNORM           , V16_SNORM  , 1),
+   _(R16G16_SNORM        , V16_SNORM  , 2),
+   _(R16G16B16_SNORM     , V16_SNORM  , 3),
+   _(R16G16B16A16_SNORM  , V16_SNORM  , 4),
+   _(R16_SSCALED         , V16_SSCALED, 1),
+   _(R16G16_SSCALED      , V16_SSCALED, 2),
+   _(R16G16B16_SSCALED   , V16_SSCALED, 3),
+   _(R16G16B16A16_SSCALED, V16_SSCALED, 4),
+   _(R16_FLOAT           , V16_FLOAT  , 1),
+   _(R16G16_FLOAT        , V16_FLOAT  , 2),
+   _(R16G16B16_FLOAT     , V16_FLOAT  , 3),
+   _(R16G16B16A16_FLOAT  , V16_FLOAT  , 4),
+   _(R32_FLOAT           , V32_FLOAT  , 1),
+   _(R32G32_FLOAT        , V32_FLOAT  , 2),
+   _(R32G32B32_FLOAT     , V32_FLOAT  , 3),
+   _(R32G32B32A32_FLOAT  , V32_FLOAT  , 4),
+};
+#undef _
+
+#define SWZ_OUT_0 0
+#define SWZ_OUT_1 1
+#define SWZ_OUT_C 2
+
+#define SWZ_SRC_0 3
+#define SWZ_SRC_1 2
+#define SWZ_SRC_2 1
+#define SWZ_SRC_3 0
+#define SWZ_SRC_x 0
+
+#define NONE 0x00000000
+#define SRGB 0x00700000
+
+#define ____ 0x00000000
+#define SSSS 0xf0000000
+
+#define _(a,b,c,d,e,f,g,h,i,j,k,l,m) [PIPE_FORMAT_##a] = {                     \
+   .nv30 = NV30_3D_TEX_FORMAT_FORMAT_##b,                                      \
+   .nv30_rect = NV30_3D_TEX_FORMAT_FORMAT_##b##_RECT,                          \
+   .nv40 = NV40_3D_TEX_FORMAT_FORMAT_##b,                                      \
+   .swz[0] = { SWZ_OUT_##d, SWZ_SRC_##h },                                     \
+   .swz[1] = { SWZ_OUT_##e, SWZ_SRC_##i },                                     \
+   .swz[2] = { SWZ_OUT_##f, SWZ_SRC_##j },                                     \
+   .swz[3] = { SWZ_OUT_##g, SWZ_SRC_##k },                                     \
+   .swz[4] = { SWZ_OUT_0, SWZ_SRC_x },                                         \
+   .swz[5] = { SWZ_OUT_1, SWZ_SRC_x },                                         \
+   .swizzle = (c) * 0x00010000,                                                \
+   .wrap =  (l),                                                               \
+   .filter = (m),                                                              \
+}
+const struct nv30_texfmt
+nv30_texfmt_table[PIPE_FORMAT_COUNT] = {
+   _(L8_UNORM          , L8      , 0, C, C, C, 1, 0, 0, 0, x, NONE, ____),
+   _(L8_SNORM          , L8      , 0, C, C, C, 1, 0, 0, 0, x, NONE, SSSS),
+   _(L8_SRGB           , L8      , 0, C, C, C, 1, 0, 0, 0, x, SRGB, ____),
+   _(I8_UNORM          , L8      , 0, C, C, C, C, 0, 0, 0, 0, NONE, ____),
+   _(I8_SNORM          , L8      , 0, C, C, C, C, 0, 0, 0, 0, NONE, SSSS),
+   _(A8_UNORM          , L8      , 0, 0, 0, 0, C, x, x, x, 0, NONE, ____),
+   _(A8_SNORM          , L8      , 0, 0, 0, 0, C, x, x, x, 0, NONE, SSSS),
+   _(R8_UNORM          , L8      , 0, C, 0, 0, 1, 0, x, x, x, NONE, ____),
+   _(R8_SNORM          , L8      , 0, C, 0, 0, 1, 0, x, x, x, NONE, SSSS),
+   _(B5G5R5X1_UNORM    , A1R5G5B5, 0, C, C, C, 1, 2, 1, 0, x, NONE, ____),
+   _(B5G5R5A1_UNORM    , A1R5G5B5, 0, C, C, C, C, 2, 1, 0, 3, NONE, ____),
+   _(B4G4R4X4_UNORM    , A4R4G4B4, 0, C, C, C, 1, 2, 1, 0, x, NONE, ____),
+   _(B4G4R4A4_UNORM    , A4R4G4B4, 0, C, C, C, C, 2, 1, 0, 3, NONE, ____),
+   _(B5G6R5_UNORM      , R5G6B5  , 0, C, C, C, 1, 2, 1, 0, x, NONE, ____),
+   _(B8G8R8X8_UNORM    , A8R8G8B8, 0, C, C, C, 1, 2, 1, 0, x, NONE, ____),
+   _(B8G8R8X8_SRGB     , A8R8G8B8, 0, C, C, C, 1, 2, 1, 0, x, SRGB, ____),
+   _(B8G8R8A8_UNORM    , A8R8G8B8, 0, C, C, C, C, 2, 1, 0, 3, NONE, ____),
+   _(B8G8R8A8_SRGB     , A8R8G8B8, 0, C, C, C, C, 2, 1, 0, 3, SRGB, ____),
+   _(R8G8B8A8_SNORM    , A8R8G8B8, 0, C, C, C, C, 0, 1, 2, 3, NONE, SSSS),
+   _(DXT1_RGB          , DXT1    , 0, C, C, C, 1, 2, 1, 0, x, NONE, ____),
+   _(DXT1_SRGB         , DXT1    , 0, C, C, C, 1, 2, 1, 0, x, SRGB, ____),
+   _(DXT1_RGBA         , DXT1    , 0, C, C, C, C, 2, 1, 0, 3, NONE, ____),
+   _(DXT1_SRGBA        , DXT1    , 0, C, C, C, C, 2, 1, 0, 3, SRGB, ____),
+   _(DXT3_RGBA         , DXT3    , 0, C, C, C, C, 2, 1, 0, 3, NONE, ____),
+   _(DXT3_SRGBA        , DXT3    , 0, C, C, C, C, 2, 1, 0, 3, SRGB, ____),
+   _(DXT5_RGBA         , DXT5    , 0, C, C, C, C, 2, 1, 0, 3, NONE, ____),
+   _(DXT5_SRGBA        , DXT5    , 0, C, C, C, C, 2, 1, 0, 3, SRGB, ____),
+   _(L8A8_UNORM        , A8L8    , 0, C, C, C, C, 0, 0, 0, 3, NONE, ____),
+   _(L8A8_SRGB         , A8L8    , 0, C, C, C, C, 0, 0, 0, 3, SRGB, ____),
+   _(R8G8_UNORM        , A8L8    , 0, C, C, 0, 1, 0, 3, x, x, NONE, ____),
+   _(R8G8_SNORM        , A8L8    , 0, C, C, 0, 1, 0, 3, x, x, NONE, SSSS),
+   _(Z16_UNORM         , Z16     , 0, C, C, C, 1, 3, 3, 3, x, NONE, ____),
+   _(X8Z24_UNORM       , Z24     , 0, C, C, C, 1, 3, 3, 3, x, NONE, ____),
+   _(S8_UINT_Z24_UNORM , Z24     , 0, C, C, C, 1, 3, 3, 3, x, NONE, ____),
+   _(L16_UNORM         , A16     , 0, C, C, C, 1, 1, 1, 1, 1, NONE, ____),
+   _(L16_SNORM         , A16     , 0, C, C, C, 1, 1, 1, 1, 1, NONE, SSSS),
+   _(I16_UNORM         , A16     , 0, C, C, C, C, 1, 1, 1, 1, NONE, ____),
+   _(I16_SNORM         , A16     , 0, C, C, C, C, 1, 1, 1, 1, NONE, SSSS),
+   _(A16_UNORM         , A16     , 0, 0, 0, 0, C, 1, 1, 1, 1, NONE, ____),
+   _(A16_SNORM         , A16     , 0, 0, 0, 0, C, 1, 1, 1, 1, NONE, SSSS),
+   _(R16_UNORM         , A16     , 0, C, 0, 0, 1, 1, 1, 1, 1, NONE, ____),
+   _(R16_SNORM         , A16     , 0, C, 0, 0, 1, 1, 1, 1, 1, NONE, SSSS),
+   _(R16G16_FLOAT      , RG16F   , 0, C, C, 0, 1, 2, 1, 0, 3, NONE, ____),
+   _(R16G16B16A16_FLOAT, RGBA16F , 0, C, C, C, C, 2, 1, 0, 3, NONE, ____),
+   _(R32_FLOAT         , R32F    , 0, C, 0, 0, 1, 2, 1, 0, 3, NONE, ____),
+   _(R32G32B32A32_FLOAT, RGBA32F , 0, C, C, C, C, 2, 1, 0, 3, NONE, ____),
+};
+#undef _
diff --git a/src/gallium/drivers/nv30/nv30_format.h b/src/gallium/drivers/nv30/nv30_format.h
new file mode 100644 (file)
index 0000000..8bf4a37
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef __NV30_FORMAT_H__
+#define __NV30_FORMAT_H__
+
+struct nv30_format_info {
+   unsigned bindings;
+};
+
+struct nv30_format {
+   unsigned hw;
+};
+
+struct nv30_vtxfmt {
+   unsigned hw;
+};
+
+struct nv30_texfmt {
+   unsigned nv30;
+   unsigned nv30_rect;
+   unsigned nv40;
+   struct {
+      unsigned src;
+      unsigned cmp;
+   } swz[6];
+   unsigned swizzle;
+   unsigned filter;
+   unsigned wrap;
+};
+
+extern const struct nv30_format_info nv30_format_info_table[];
+static INLINE const struct nv30_format_info *
+nv30_format_info(struct pipe_screen *pscreen, enum pipe_format format)
+{
+   return &nv30_format_info_table[format];
+}
+
+extern const struct nv30_format nv30_format_table[];
+static INLINE const struct nv30_format *
+nv30_format(struct pipe_screen *pscreen, enum pipe_format format)
+{
+   return &nv30_format_table[format];
+}
+
+extern const struct nv30_vtxfmt nv30_vtxfmt_table[];
+static INLINE const struct nv30_vtxfmt *
+nv30_vtxfmt(struct pipe_screen *pscreen, enum pipe_format format)
+{
+   return &nv30_vtxfmt_table[format];
+}
+
+extern const struct nv30_texfmt nv30_texfmt_table[];
+static INLINE const struct nv30_texfmt *
+nv30_texfmt(struct pipe_screen *pscreen, enum pipe_format format)
+{
+   return &nv30_texfmt_table[format];
+}
+
+#endif
diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c
new file mode 100644 (file)
index 0000000..865c828
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "tgsi/tgsi_parse.h"
+
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nvfx_shader.h"
+
+static void
+nv30_fragprog_upload(struct nv30_context *nv30)
+{
+   struct nouveau_context *nv = &nv30->base;
+   struct nv30_fragprog *fp = nv30->fragprog.program;
+   struct pipe_context *pipe = &nv30->base.pipe;
+   struct pipe_transfer *transfer;
+   uint32_t *map;
+   int i; (void)i;
+
+   if (unlikely(!fp->buffer)) {
+      fp->buffer = pipe_buffer_create(pipe->screen, 0, 0, fp->insn_len * 4);
+   }
+
+   map = pipe_buffer_map(pipe, fp->buffer, PIPE_TRANSFER_WRITE, &transfer);
+#ifndef PIPE_ARCH_BIG_ENDIAN
+   memcpy(map, fp->insn, fp->insn_len * 4);
+#else
+   for (i = 0; i < fp->insn_len; i++)
+      *map++ = (fp->insn[i] >> 16) | (fp->insn[i] << 16);
+#endif
+   pipe_buffer_unmap(pipe, transfer);
+
+   if (nv04_resource(fp->buffer)->domain != NOUVEAU_BO_VRAM)
+      nouveau_buffer_migrate(nv, nv04_resource(fp->buffer), NOUVEAU_BO_VRAM);
+}
+
+void
+nv30_fragprog_validate(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nouveau_object *eng3d = nv30->screen->eng3d;
+   struct nv30_fragprog *fp = nv30->fragprog.program;
+   boolean upload = FALSE;
+   int i;
+
+   if (!fp->translated) {
+      _nvfx_fragprog_translate(nv30, fp, FALSE);
+      if (!fp->translated)
+         return;
+
+      upload = TRUE;
+   }
+
+   /* update constants, also needs to be done on every fp switch as we
+    * have no idea whether the constbuf changed in the meantime
+    */
+   if (nv30->fragprog.constbuf) {
+      struct pipe_resource *constbuf = nv30->fragprog.constbuf;
+      uint32_t *cbuf = (uint32_t *)nv04_resource(constbuf)->data;
+
+      for (i = 0; i < fp->nr_consts; i++) {
+         unsigned off = fp->consts[i].offset;
+         unsigned idx = fp->consts[i].index * 4;
+
+         if (!memcmp(&fp->insn[off], &cbuf[idx], 4 * 4))
+            continue;
+         memcpy(&fp->insn[off], &cbuf[idx], 4 * 4);
+         upload = TRUE;
+      }
+   }
+
+   if (upload)
+      nv30_fragprog_upload(nv30);
+
+   /* FP_ACTIVE_PROGRAM needs to be done again even if only the consts
+    * were updated.  TEX_CACHE_CTL magic is not enough to convince the
+    * GPU that it should re-read the fragprog from VRAM... sigh.
+    */
+   if (nv30->state.fragprog != fp || upload) {
+      struct nv04_resource *r = nv04_resource(fp->buffer);
+
+      if (!PUSH_SPACE(push, 8))
+         return;
+      PUSH_RESET(push, BUFCTX_FRAGPROG);
+
+      BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1);
+      PUSH_RESRC(push, NV30_3D(FP_ACTIVE_PROGRAM), BUFCTX_FRAGPROG, r, 0,
+                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD | NOUVEAU_BO_OR,
+                       NV30_3D_FP_ACTIVE_PROGRAM_DMA0,
+                       NV30_3D_FP_ACTIVE_PROGRAM_DMA1);
+      BEGIN_NV04(push, NV30_3D(FP_CONTROL), 1);
+      PUSH_DATA (push, fp->fp_control);
+      if (eng3d->oclass < NV40_3D_CLASS) {
+         BEGIN_NV04(push, NV30_3D(FP_REG_CONTROL), 1);
+         PUSH_DATA (push, 0x00010004);
+         BEGIN_NV04(push, NV30_3D(TEX_UNITS_ENABLE), 1);
+         PUSH_DATA (push, fp->samplers);
+      } else {
+         BEGIN_NV04(push, SUBC_3D(0x0b40), 1);
+         PUSH_DATA (push, 0x00000000);
+      }
+
+      nv30->state.fragprog = fp;
+   }
+}
+
+static void *
+nv30_fp_state_create(struct pipe_context *pipe,
+                     const struct pipe_shader_state *cso)
+{
+   struct nv30_fragprog *fp = CALLOC_STRUCT(nv30_fragprog);
+   if (!fp)
+      return NULL;
+
+   fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+   tgsi_scan_shader(fp->pipe.tokens, &fp->info);
+   return fp;
+}
+
+static void
+nv30_fp_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+   struct nv30_fragprog *fp = hwcso;
+
+   pipe_resource_reference(&fp->buffer, NULL);
+
+   FREE((void *)fp->pipe.tokens);
+   FREE(fp->insn);
+   FREE(fp);
+}
+
+static void
+nv30_fp_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+
+   nv30->fragprog.program = hwcso;
+   nv30->dirty |= NV30_NEW_FRAGPROG;
+}
+
+void
+nv30_fragprog_init(struct pipe_context *pipe)
+{
+   pipe->create_fs_state = nv30_fp_state_create;
+   pipe->bind_fs_state = nv30_fp_state_bind;
+   pipe->delete_fs_state = nv30_fp_state_delete;
+}
diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c
new file mode 100644 (file)
index 0000000..723628b
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "util/u_inlines.h"
+
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_format.h"
+
+void
+nv30_fragtex_validate(struct nv30_context *nv30)
+{
+   struct pipe_screen *pscreen = &nv30->screen->base.base;
+   struct nouveau_object *eng3d = nv30->screen->eng3d;
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   unsigned dirty = nv30->fragprog.dirty_samplers;
+
+   while (dirty) {
+      unsigned unit = ffs(dirty) - 1;
+      struct nv30_sampler_view *sv = (void *)nv30->fragprog.textures[unit];
+      struct nv30_sampler_state *ss = nv30->fragprog.samplers[unit];
+
+      PUSH_RESET(push, BUFCTX_FRAGTEX(unit));
+
+      if (ss && sv) {
+         const struct nv30_texfmt *fmt = nv30_texfmt(pscreen, sv->pipe.format);
+         struct pipe_resource *pt = sv->pipe.texture;
+         struct nv30_miptree *mt = nv30_miptree(pt);
+         unsigned min_lod, max_lod;
+         u32 filter = sv->filt | (ss->filt & sv->filt_mask);
+         u32 format = sv->fmt | ss->fmt;
+         u32 enable = ss->en;
+
+         /* handle base_level when not using a mip filter, min/max level
+          * is unfortunately ignored by the hardware otherwise
+          */
+         if (ss->pipe.min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
+            if (sv->base_lod)
+               filter += 0x00020000; /* N/L -> NMN/LMN */
+            max_lod = sv->base_lod;
+            min_lod = sv->base_lod;
+         } else {
+            max_lod = MIN2(ss->max_lod + sv->base_lod, sv->high_lod);
+            min_lod = MIN2(ss->min_lod + sv->base_lod, max_lod);
+         }
+
+         if (eng3d->oclass >= NV40_3D_CLASS) {
+            /* this is a tad stupid of the hardware, but there's no non-rcomp
+             * z16/z24 texture formats to be had, we have to suffer and lose
+             * some precision to handle this case.
+             */
+            if (ss->pipe.compare_mode != PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+               if (fmt->nv40 == NV40_3D_TEX_FORMAT_FORMAT_Z16)
+                  format |= NV40_3D_TEX_FORMAT_FORMAT_A8L8;
+               else
+               if (fmt->nv40 == NV40_3D_TEX_FORMAT_FORMAT_Z24)
+                  format |= NV40_3D_TEX_FORMAT_FORMAT_A16L16;
+               else
+                  format |= fmt->nv40;
+            } else {
+               format |= fmt->nv40;
+            }
+
+            enable |= (min_lod << 19) | (max_lod << 7);
+            enable |= NV40_3D_TEX_ENABLE_ENABLE;
+
+            BEGIN_NV04(push, NV40_3D(TEX_SIZE1(unit)), 1);
+            PUSH_DATA (push, sv->npot_size1);
+         } else {
+            /* this is a tad stupid of the hardware, but there's no non-rcomp
+             * z16/z24 texture formats to be had, we have to suffer and lose
+             * some precision to handle this case.
+             */
+            if (ss->pipe.compare_mode != PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+               if (fmt->nv30 == NV30_3D_TEX_FORMAT_FORMAT_Z16) {
+                  if (ss->pipe.normalized_coords)
+                     format |= NV30_3D_TEX_FORMAT_FORMAT_A8L8;
+                  else
+                     format |= NV30_3D_TEX_FORMAT_FORMAT_A8L8_RECT;
+               } else
+               if (fmt->nv30 == NV30_3D_TEX_FORMAT_FORMAT_Z24) {
+                  if (ss->pipe.normalized_coords)
+                     format |= NV30_3D_TEX_FORMAT_FORMAT_HILO16;
+                  else
+                     format |= NV30_3D_TEX_FORMAT_FORMAT_HILO16_RECT;
+               } else {
+                  if (ss->pipe.normalized_coords)
+                     format |= fmt->nv30;
+                  else
+                     format |= fmt->nv30_rect;
+               }
+            } else {
+               if (ss->pipe.normalized_coords)
+                  format |= fmt->nv30;
+               else
+                  format |= fmt->nv30_rect;
+            }
+
+            enable |= NV30_3D_TEX_ENABLE_ENABLE;
+            enable |= (min_lod << 18) | (max_lod << 6);
+         }
+
+         BEGIN_NV04(push, NV30_3D(TEX_OFFSET(unit)), 8);
+         PUSH_MTHDl(push, NV30_3D(TEX_OFFSET(unit)), BUFCTX_FRAGTEX(unit),
+                          mt->base.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+         PUSH_MTHDs(push, NV30_3D(TEX_FORMAT(unit)), BUFCTX_FRAGTEX(unit),
+                          mt->base.bo, format, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD,
+                          NV30_3D_TEX_FORMAT_DMA0,
+                          NV30_3D_TEX_FORMAT_DMA1);
+         PUSH_DATA (push, sv->wrap | (ss->wrap & sv->wrap_mask));
+         PUSH_DATA (push, enable);
+         PUSH_DATA (push, sv->swz);
+         PUSH_DATA (push, filter);
+         PUSH_DATA (push, sv->npot_size0);
+         PUSH_DATA (push, ss->bcol);
+         BEGIN_NV04(push, NV30_3D(TEX_FILTER_OPTIMIZATION(unit)), 1);
+         PUSH_DATA (push, nv30->config.filter);
+      } else {
+         BEGIN_NV04(push, NV30_3D(TEX_ENABLE(unit)), 1);
+         PUSH_DATA (push, 0);
+      }
+
+      dirty &= ~(1 << unit);
+   }
+
+   nv30->fragprog.dirty_samplers = 0;
+}
+
+static void
+nv30_fragtex_sampler_states_bind(struct pipe_context *pipe,
+                                 unsigned nr, void **hwcso)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   unsigned i;
+
+   for (i = 0; i < nr; i++) {
+      nv30->fragprog.samplers[i] = hwcso[i];
+      nv30->fragprog.dirty_samplers |= (1 << i);
+   }
+
+   for (; i < nv30->fragprog.num_samplers; i++) {
+      nv30->fragprog.samplers[i] = NULL;
+      nv30->fragprog.dirty_samplers |= (1 << i);
+   }
+
+   nv30->fragprog.num_samplers = nr;
+   nv30->dirty |= NV30_NEW_FRAGTEX;
+}
+
+
+static void
+nv30_fragtex_set_sampler_views(struct pipe_context *pipe, unsigned nr,
+                               struct pipe_sampler_view **views)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   unsigned i;
+
+   for (i = 0; i < nr; i++) {
+      nouveau_bufctx_reset(nv30->bufctx, BUFCTX_FRAGTEX(i));
+      pipe_sampler_view_reference(&nv30->fragprog.textures[i], views[i]);
+      nv30->fragprog.dirty_samplers |= (1 << i);
+   }
+
+   for (; i < nv30->fragprog.num_textures; i++) {
+      nouveau_bufctx_reset(nv30->bufctx, BUFCTX_FRAGTEX(i));
+      pipe_sampler_view_reference(&nv30->fragprog.textures[i], NULL);
+      nv30->fragprog.dirty_samplers |= (1 << i);
+   }
+
+   nv30->fragprog.num_textures = nr;
+   nv30->dirty |= NV30_NEW_FRAGTEX;
+}
+
+void
+nv30_fragtex_init(struct pipe_context *pipe)
+{
+   pipe->bind_fragment_sampler_states = nv30_fragtex_sampler_states_bind;
+   pipe->set_fragment_sampler_views = nv30_fragtex_set_sampler_views;
+}
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
new file mode 100644 (file)
index 0000000..7e67729
--- /dev/null
@@ -0,0 +1,442 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+#include "util/u_surface.h"
+
+#include "nouveau/nv_m2mf.xml.h"
+#include "nv30_screen.h"
+#include "nv30_context.h"
+#include "nv30_resource.h"
+#include "nv30_transfer.h"
+
+static INLINE unsigned
+layer_offset(struct pipe_resource *pt, unsigned level, unsigned layer)
+{
+   struct nv30_miptree *mt = nv30_miptree(pt);
+   struct nv30_miptree_level *lvl = &mt->level[level];
+
+   if (pt->target == PIPE_TEXTURE_CUBE)
+      return (layer * mt->layer_size) + lvl->offset;
+
+   return lvl->offset + (layer * lvl->zslice_size);
+}
+
+static boolean
+nv30_miptree_get_handle(struct pipe_screen *pscreen,
+                        struct pipe_resource *pt,
+                        struct winsys_handle *handle)
+{
+   struct nv30_miptree *mt = nv30_miptree(pt);
+   unsigned stride;
+
+   if (!mt || !mt->base.bo)
+      return FALSE;
+
+   stride = util_format_get_stride(mt->base.base.format,
+                                   mt->base.base.width0);
+
+   return nouveau_screen_bo_get_handle(pscreen, mt->base.bo, stride, handle);
+}
+
+static void
+nv30_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
+{
+   struct nv30_miptree *mt = nv30_miptree(pt);
+
+   nouveau_bo_ref(NULL, &mt->base.bo);
+   FREE(mt);
+}
+
+struct nv30_transfer {
+   struct pipe_transfer base;
+   struct nv30_rect img;
+   struct nv30_rect tmp;
+   unsigned nblocksx;
+   unsigned nblocksy;
+};
+
+static INLINE struct nv30_transfer *
+nv30_transfer(struct pipe_transfer *ptx)
+{
+   return (struct nv30_transfer *)ptx;
+}
+
+static INLINE void
+define_rect(struct pipe_resource *pt, unsigned level, unsigned z,
+            unsigned x, unsigned y, unsigned w, unsigned h,
+            struct nv30_rect *rect)
+{
+   struct nv30_miptree *mt = nv30_miptree(pt);
+   struct nv30_miptree_level *lvl = &mt->level[level];
+
+   rect->w = u_minify(pt->width0, level) << mt->ms_x;
+   rect->w = util_format_get_nblocksx(pt->format, rect->w);
+   rect->h = u_minify(pt->height0, level) << mt->ms_y;
+   rect->h = util_format_get_nblocksy(pt->format, rect->h);
+   rect->d = 1;
+   rect->z = 0;
+   if (mt->swizzled) {
+      if (pt->target == PIPE_TEXTURE_3D) {
+         rect->d = u_minify(pt->depth0, level);
+         rect->z = z; z = 0;
+      }
+      rect->pitch = 0;
+   } else {
+      rect->pitch = lvl->pitch;
+   }
+
+   rect->bo     = mt->base.bo;
+   rect->domain = NOUVEAU_BO_VRAM;
+   rect->offset = layer_offset(pt, level, z);
+   rect->cpp    = util_format_get_blocksize(pt->format);
+
+   rect->x0     = util_format_get_nblocksx(pt->format, x) << mt->ms_x;
+   rect->y0     = util_format_get_nblocksy(pt->format, y) << mt->ms_y;
+   rect->x1     = rect->x0 + (w << mt->ms_x);
+   rect->y1     = rect->y0 + (h << mt->ms_y);
+}
+
+void
+nv30_resource_copy_region(struct pipe_context *pipe,
+                          struct pipe_resource *dstres, unsigned dst_level,
+                          unsigned dstx, unsigned dsty, unsigned dstz,
+                          struct pipe_resource *srcres, unsigned src_level,
+                          const struct pipe_box *src_box)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nv30_rect src, dst;
+
+   if (dstres->target == PIPE_BUFFER && srcres->target == PIPE_BUFFER) {
+      util_resource_copy_region(pipe, dstres, dst_level, dstx, dsty, dstz,
+                                      srcres, src_level, src_box);
+      return;
+   }
+
+   define_rect(srcres, src_level, src_box->z, src_box->x, src_box->y,
+                       src_box->width, src_box->height, &src);
+   define_rect(dstres, dst_level, dstz, dstx, dsty,
+                       src_box->width, src_box->height, &dst);
+
+   nv30_transfer_rect(nv30, NEAREST, &src, &dst);
+}
+
+void
+nv30_resource_resolve(struct pipe_context *pipe,
+                      const struct pipe_resolve_info *info)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nv30_rect src, dst;
+
+   define_rect(info->src.res, 0, 0, info->src.x0, info->src.y0,
+               info->src.x1 - info->src.x0, info->src.y1 - info->src.y0, &src);
+   define_rect(info->dst.res, info->dst.level, 0, info->dst.x0, info->dst.y0,
+               info->dst.x1 - info->dst.x0, info->dst.y1 - info->dst.y0, &dst);
+
+   nv30_transfer_rect(nv30, BILINEAR, &src, &dst);
+}
+
+static struct pipe_transfer *
+nv30_miptree_transfer_new(struct pipe_context *pipe, struct pipe_resource *pt,
+                          unsigned level, unsigned usage,
+                          const struct pipe_box *box)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nouveau_device *dev = nv30->screen->base.device;
+   struct nv30_transfer *tx;
+   int ret;
+
+   tx = CALLOC_STRUCT(nv30_transfer);
+   if (!tx)
+      return NULL;
+   pipe_resource_reference(&tx->base.resource, pt);
+   tx->base.level = level;
+   tx->base.usage = usage;
+   tx->base.box = *box;
+   tx->base.stride = util_format_get_nblocksx(pt->format, box->width) *
+                     util_format_get_blocksize(pt->format);
+   tx->base.layer_stride = util_format_get_nblocksy(pt->format, box->height) *
+                           tx->base.stride;
+
+   tx->nblocksx = util_format_get_nblocksx(pt->format, box->width);
+   tx->nblocksy = util_format_get_nblocksy(pt->format, box->height);
+
+   define_rect(pt, level, box->z, box->x, box->y,
+                   tx->nblocksx, tx->nblocksy, &tx->img);
+
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
+                        tx->base.layer_stride, NULL, &tx->tmp.bo);
+   if (ret) {
+      pipe_resource_reference(&tx->base.resource, NULL);
+      FREE(tx);
+      return NULL;
+   }
+
+   tx->tmp.domain = NOUVEAU_BO_GART;
+   tx->tmp.offset = 0;
+   tx->tmp.pitch  = tx->base.stride;
+   tx->tmp.cpp    = tx->img.cpp;
+   tx->tmp.w      = tx->nblocksx;
+   tx->tmp.h      = tx->nblocksy;
+   tx->tmp.d      = 1;
+   tx->tmp.x0     = 0;
+   tx->tmp.y0     = 0;
+   tx->tmp.x1     = tx->tmp.w;
+   tx->tmp.y1     = tx->tmp.h;
+   tx->tmp.z      = 0;
+
+   if (usage & PIPE_TRANSFER_READ)
+      nv30_transfer_rect(nv30, NEAREST, &tx->img, &tx->tmp);
+
+   return &tx->base;
+}
+
+static void
+nv30_miptree_transfer_del(struct pipe_context *pipe, struct pipe_transfer *ptx)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nv30_transfer *tx = nv30_transfer(ptx);
+
+   if (ptx->usage & PIPE_TRANSFER_WRITE)
+      nv30_transfer_rect(nv30, NEAREST, &tx->tmp, &tx->img);
+
+   nouveau_bo_ref(NULL, &tx->tmp.bo);
+   pipe_resource_reference(&ptx->resource, NULL);
+   FREE(tx);
+}
+
+static void *
+nv30_miptree_transfer_map(struct pipe_context *pipe, struct pipe_transfer *ptx)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nv30_transfer *tx = nv30_transfer(ptx);
+   unsigned access = 0;
+   int ret;
+
+   if (tx->tmp.bo->map)
+      return tx->tmp.bo->map;
+
+   if (ptx->usage & PIPE_TRANSFER_READ)
+      access |= NOUVEAU_BO_RD;
+   if (ptx->usage & PIPE_TRANSFER_WRITE)
+      access |= NOUVEAU_BO_WR;
+
+   ret = nouveau_bo_map(tx->tmp.bo, access, nv30->base.client);
+   if (ret)
+      return NULL;
+   return tx->tmp.bo->map;
+}
+
+static void
+nv30_miptree_transfer_unmap(struct pipe_context *pipe,
+                            struct pipe_transfer *ptx)
+{
+}
+
+const struct u_resource_vtbl nv30_miptree_vtbl = {
+   nv30_miptree_get_handle,
+   nv30_miptree_destroy,
+   nv30_miptree_transfer_new,
+   nv30_miptree_transfer_del,
+   nv30_miptree_transfer_map,
+   u_default_transfer_flush_region,
+   nv30_miptree_transfer_unmap,
+   u_default_transfer_inline_write
+};
+
+struct pipe_resource *
+nv30_miptree_create(struct pipe_screen *pscreen,
+                    const struct pipe_resource *tmpl)
+{
+   struct nouveau_device *dev = nouveau_screen(pscreen)->device;
+   struct nv30_miptree *mt = CALLOC_STRUCT(nv30_miptree);
+   struct pipe_resource *pt = &mt->base.base;
+   unsigned blocksz, size;
+   unsigned w, h, d, l;
+   int ret;
+
+   switch (tmpl->nr_samples) {
+   case 4:
+      mt->ms_mode = 0x00004000;
+      mt->ms_x = 1;
+      mt->ms_y = 1;
+      break;
+   case 2:
+      mt->ms_mode = 0x00003000;
+      mt->ms_x = 1;
+      mt->ms_y = 0;
+      break;
+   default:
+      mt->ms_mode = 0x00000000;
+      mt->ms_x = 0;
+      mt->ms_y = 0;
+      break;
+   }
+
+   mt->base.vtbl = &nv30_miptree_vtbl;
+   *pt = *tmpl;
+   pipe_reference_init(&pt->reference, 1);
+   pt->screen = pscreen;
+
+   w = pt->width0 << mt->ms_x;
+   h = pt->height0 << mt->ms_y;
+   d = (pt->target == PIPE_TEXTURE_3D) ? pt->depth0 : 1;
+   blocksz = util_format_get_blocksize(pt->format);
+
+   if ((pt->target == PIPE_TEXTURE_RECT) ||
+       !util_is_power_of_two(pt->width0) ||
+       !util_is_power_of_two(pt->height0) ||
+       !util_is_power_of_two(pt->depth0) ||
+       util_format_is_compressed(pt->format) ||
+       util_format_is_float(pt->format) || mt->ms_mode) {
+      mt->uniform_pitch = util_format_get_nblocksx(pt->format, w) * blocksz;
+      mt->uniform_pitch = align(mt->uniform_pitch, 64);
+   }
+
+   if (!mt->uniform_pitch)
+      mt->swizzled = TRUE;
+
+   size = 0;
+   for (l = 0; l <= pt->last_level; l++) {
+      struct nv30_miptree_level *lvl = &mt->level[l];
+      unsigned nbx = util_format_get_nblocksx(pt->format, w);
+      unsigned nby = util_format_get_nblocksx(pt->format, h);
+
+      lvl->offset = size;
+      lvl->pitch  = mt->uniform_pitch;
+      if (!lvl->pitch)
+         lvl->pitch = nbx * blocksz;
+
+      lvl->zslice_size = lvl->pitch * nby;
+      size += lvl->zslice_size * d;
+
+      w = u_minify(w, 1);
+      h = u_minify(h, 1);
+      d = u_minify(d, 1);
+   }
+
+   mt->layer_size = size;
+   if (pt->target == PIPE_TEXTURE_CUBE) {
+      if (!mt->uniform_pitch)
+         mt->layer_size = align(mt->layer_size, 128);
+      size = mt->layer_size * 6;
+   }
+
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 256, size, NULL, &mt->base.bo);
+   if (ret) {
+      FREE(mt);
+      return NULL;
+   }
+
+   mt->base.domain = NOUVEAU_BO_VRAM;
+   return &mt->base.base;
+}
+
+struct pipe_resource *
+nv30_miptree_from_handle(struct pipe_screen *pscreen,
+                         const struct pipe_resource *tmpl,
+                         struct winsys_handle *handle)
+{
+   struct nv30_miptree *mt;
+   unsigned stride;
+
+   /* only supports 2D, non-mipmapped textures for the moment */
+   if ((tmpl->target != PIPE_TEXTURE_2D &&
+        tmpl->target != PIPE_TEXTURE_RECT) ||
+       tmpl->last_level != 0 ||
+       tmpl->depth0 != 1 ||
+       tmpl->array_size > 1)
+      return NULL;
+
+   mt = CALLOC_STRUCT(nv30_miptree);
+   if (!mt)
+      return NULL;
+
+   mt->base.bo = nouveau_screen_bo_from_handle(pscreen, handle, &stride);
+   if (mt->base.bo == NULL) {
+      FREE(mt);
+      return NULL;
+   }
+
+   mt->base.base = *tmpl;
+   mt->base.vtbl = &nv30_miptree_vtbl;
+   pipe_reference_init(&mt->base.base.reference, 1);
+   mt->base.base.screen = pscreen;
+   mt->uniform_pitch = stride;
+   mt->level[0].pitch = mt->uniform_pitch;
+   mt->level[0].offset = 0;
+
+   /* no need to adjust bo reference count */
+   return &mt->base.base;
+}
+
+struct pipe_surface *
+nv30_miptree_surface_new(struct pipe_context *pipe,
+                         struct pipe_resource *pt,
+                         const struct pipe_surface *tmpl)
+{
+   struct nv30_miptree *mt = nv30_miptree(pt); /* guaranteed */
+   struct nv30_surface *ns;
+   struct pipe_surface *ps;
+   struct nv30_miptree_level *lvl = &mt->level[tmpl->u.tex.level];
+
+   ns = CALLOC_STRUCT(nv30_surface);
+   if (!ns)
+      return NULL;
+   ps = &ns->base;
+
+   pipe_reference_init(&ps->reference, 1);
+   pipe_resource_reference(&ps->texture, pt);
+   ps->context = pipe;
+   ps->format = tmpl->format;
+   ps->usage = tmpl->usage;
+   ps->u.tex.level = tmpl->u.tex.level;
+   ps->u.tex.first_layer = tmpl->u.tex.first_layer;
+   ps->u.tex.last_layer = tmpl->u.tex.last_layer;
+
+   ns->width = u_minify(pt->width0, ps->u.tex.level);
+   ns->height = u_minify(pt->height0, ps->u.tex.level);
+   ns->depth = ps->u.tex.last_layer - ps->u.tex.first_layer + 1;
+   ns->offset = layer_offset(pt, ps->u.tex.level, ps->u.tex.first_layer);
+   if (mt->swizzled)
+      ns->pitch = 4096; /* random, just something the hw won't reject.. */
+   else
+      ns->pitch = lvl->pitch;
+
+   /* comment says there are going to be removed, but they're used by the st */
+   ps->width = ns->width;
+   ps->height = ns->height;
+   return ps;
+}
+
+void
+nv30_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps)
+{
+   struct nv30_surface *ns = nv30_surface(ps);
+
+   pipe_resource_reference(&ps->texture, NULL);
+   FREE(ns);
+}
diff --git a/src/gallium/drivers/nv30/nv30_push.c b/src/gallium/drivers/nv30/nv30_push.c
new file mode 100644 (file)
index 0000000..16575ee
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "translate/translate.h"
+
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_resource.h"
+
+struct push_context {
+   struct nouveau_pushbuf *push;
+
+   void *idxbuf;
+
+   float edgeflag;
+   int edgeflag_attr;
+
+   uint32_t vertex_words;
+   uint32_t packet_vertex_limit;
+
+   struct translate *translate;
+
+   boolean primitive_restart;
+   uint32_t prim;
+   uint32_t restart_index;
+};
+
+static INLINE unsigned
+prim_restart_search_i08(uint8_t *elts, unsigned push, uint8_t index)
+{
+   unsigned i;
+   for (i = 0; i < push; ++i)
+      if (elts[i] == index)
+         break;
+   return i;
+}
+
+static INLINE unsigned
+prim_restart_search_i16(uint16_t *elts, unsigned push, uint16_t index)
+{
+   unsigned i;
+   for (i = 0; i < push; ++i)
+      if (elts[i] == index)
+         break;
+   return i;
+}
+
+static INLINE unsigned
+prim_restart_search_i32(uint32_t *elts, unsigned push, uint32_t index)
+{
+   unsigned i;
+   for (i = 0; i < push; ++i)
+      if (elts[i] == index)
+         break;
+   return i;
+}
+
+static void
+emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
+{
+   uint8_t *elts = (uint8_t *)ctx->idxbuf + start;
+
+   while (count) {
+      unsigned push = MIN2(count, ctx->packet_vertex_limit);
+      unsigned size, nr;
+
+      nr = push;
+      if (ctx->primitive_restart)
+         nr = prim_restart_search_i08(elts, push, ctx->restart_index);
+
+      size = ctx->vertex_words * nr;
+
+      BEGIN_NI04(ctx->push, NV30_3D(VERTEX_DATA), size);
+
+      ctx->translate->run_elts8(ctx->translate, elts, nr, 0, ctx->push->cur);
+
+      ctx->push->cur += size;
+      count -= nr;
+      elts += nr;
+
+      if (nr != push) {
+         BEGIN_NV04(ctx->push, NV30_3D(VB_ELEMENT_U32), 1);
+         PUSH_DATA (ctx->push, ctx->restart_index);
+         count--;
+         elts++;
+      }
+   }
+}
+
+static void
+emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
+{
+   uint16_t *elts = (uint16_t *)ctx->idxbuf + start;
+
+   while (count) {
+      unsigned push = MIN2(count, ctx->packet_vertex_limit);
+      unsigned size, nr;
+
+      nr = push;
+      if (ctx->primitive_restart)
+         nr = prim_restart_search_i16(elts, push, ctx->restart_index);
+
+      size = ctx->vertex_words * nr;
+
+      BEGIN_NI04(ctx->push, NV30_3D(VERTEX_DATA), size);
+
+      ctx->translate->run_elts16(ctx->translate, elts, nr, 0, ctx->push->cur);
+
+      ctx->push->cur += size;
+      count -= nr;
+      elts += nr;
+
+      if (nr != push) {
+         BEGIN_NV04(ctx->push, NV30_3D(VB_ELEMENT_U32), 1);
+         PUSH_DATA (ctx->push, ctx->restart_index);
+         count--;
+         elts++;
+      }
+   }
+}
+
+static void
+emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
+{
+   uint32_t *elts = (uint32_t *)ctx->idxbuf + start;
+
+   while (count) {
+      unsigned push = MIN2(count, ctx->packet_vertex_limit);
+      unsigned size, nr;
+
+      nr = push;
+      if (ctx->primitive_restart)
+         nr = prim_restart_search_i32(elts, push, ctx->restart_index);
+
+      size = ctx->vertex_words * nr;
+
+      BEGIN_NI04(ctx->push, NV30_3D(VERTEX_DATA), size);
+
+      ctx->translate->run_elts(ctx->translate, elts, nr, 0, ctx->push->cur);
+
+      ctx->push->cur += size;
+      count -= nr;
+      elts += nr;
+
+      if (nr != push) {
+         BEGIN_NV04(ctx->push, NV30_3D(VB_ELEMENT_U32), 1);
+         PUSH_DATA (ctx->push, ctx->restart_index);
+         count--;
+         elts++;
+      }
+   }
+}
+
+static void
+emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
+{
+   while (count) {
+      unsigned push = MIN2(count, ctx->packet_vertex_limit);
+      unsigned size = ctx->vertex_words * push;
+
+      BEGIN_NI04(ctx->push, NV30_3D(VERTEX_DATA), size);
+
+      ctx->translate->run(ctx->translate, start, push, 0, ctx->push->cur);
+      ctx->push->cur += size;
+      count -= push;
+      start += push;
+   }
+}
+
+void
+nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info)
+{
+   struct push_context ctx;
+   unsigned i, index_size;
+   boolean apply_bias = info->indexed && info->index_bias;
+
+   ctx.push = nv30->base.pushbuf;
+   ctx.translate = nv30->vertex->translate;
+   ctx.packet_vertex_limit = nv30->vertex->vtx_per_packet_max;
+   ctx.vertex_words = nv30->vertex->vtx_size;
+
+   for (i = 0; i < nv30->num_vtxbufs; ++i) {
+      uint8_t *data;
+      struct pipe_vertex_buffer *vb = &nv30->vtxbuf[i];
+      struct nv04_resource *res = nv04_resource(vb->buffer);
+
+      data = nouveau_resource_map_offset(&nv30->base, res,
+                                         vb->buffer_offset, NOUVEAU_BO_RD);
+
+      if (apply_bias)
+         data += info->index_bias * vb->stride;
+
+      ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0);
+   }
+
+   if (info->indexed) {
+      ctx.idxbuf = nouveau_resource_map_offset(&nv30->base,
+                                               nv04_resource(nv30->idxbuf.buffer),
+                                               nv30->idxbuf.offset, NOUVEAU_BO_RD);
+      if (!ctx.idxbuf) {
+         nv30_state_release(nv30);
+         return;
+      }
+      index_size = nv30->idxbuf.index_size;
+      ctx.primitive_restart = info->primitive_restart;
+      ctx.restart_index = info->restart_index;
+   } else {
+      ctx.idxbuf = NULL;
+      index_size = 0;
+      ctx.primitive_restart = FALSE;
+      ctx.restart_index = 0;
+   }
+
+   if (nv30->screen->eng3d->oclass >= NV40_3D_CLASS) {
+      BEGIN_NV04(ctx.push, NV40_3D(PRIM_RESTART_ENABLE), 2);
+      PUSH_DATA (ctx.push, info->primitive_restart);
+      PUSH_DATA (ctx.push, info->restart_index);
+      nv30->state.prim_restart = info->primitive_restart;
+   }
+
+   ctx.prim = nv30_prim_gl(info->mode);
+
+   PUSH_RESET(ctx.push, BUFCTX_IDXBUF);
+   BEGIN_NV04(ctx.push, NV30_3D(VERTEX_BEGIN_END), 1);
+   PUSH_DATA (ctx.push, ctx.prim);
+   switch (index_size) {
+   case 0:
+      emit_vertices_seq(&ctx, info->start, info->count);
+      break;
+   case 1:
+      emit_vertices_i08(&ctx, info->start, info->count);
+      break;
+   case 2:
+      emit_vertices_i16(&ctx, info->start, info->count);
+      break;
+   case 4:
+      emit_vertices_i32(&ctx, info->start, info->count);
+      break;
+   default:
+      assert(0);
+      break;
+   }
+   BEGIN_NV04(ctx.push, NV30_3D(VERTEX_BEGIN_END), 1);
+   PUSH_DATA (ctx.push, NV30_3D_VERTEX_BEGIN_END_STOP);
+
+   if (info->indexed)
+      nouveau_resource_unmap(nv04_resource(nv30->idxbuf.buffer));
+
+   for (i = 0; i < nv30->num_vtxbufs; ++i)
+      nouveau_resource_unmap(nv04_resource(nv30->vtxbuf[i].buffer));
+
+   nv30_state_release(nv30);
+}
diff --git a/src/gallium/drivers/nv30/nv30_query.c b/src/gallium/drivers/nv30/nv30_query.c
new file mode 100644 (file)
index 0000000..fb4be31
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_screen.h"
+#include "nv30_context.h"
+
+#define LIST_FIRST_ENTRY(__type, __item, __field) \
+   LIST_ENTRY(__type, (__item)->next, __field)
+
+struct nv30_query_object {
+   struct list_head list;
+   struct nouveau_heap *hw;
+};
+
+static volatile void *
+nv30_ntfy(struct nv30_screen *screen, struct nv30_query_object *qo)
+{
+   struct nv04_notify *query = screen->query->data;
+   struct nouveau_bo *notify = screen->notify;
+   volatile void *ntfy = NULL;
+
+   if (qo && qo->hw)
+      ntfy = (char *)notify->map + query->offset + qo->hw->start;
+
+   return ntfy;
+}
+
+static void
+nv30_query_object_del(struct nv30_screen *screen, struct nv30_query_object **po)
+{
+   struct nv30_query_object *qo = *po; *po = NULL;
+   if (qo) {
+      volatile uint32_t *ntfy = nv30_ntfy(screen, qo);
+      while (ntfy[3] & 0xff000000) {
+      }
+      nouveau_heap_free(&qo->hw);
+      LIST_DEL(&qo->list);
+      FREE(qo);
+   }
+}
+
+static struct nv30_query_object *
+nv30_query_object_new(struct nv30_screen *screen)
+{
+   struct nv30_query_object *oq, *qo = CALLOC_STRUCT(nv30_query_object);
+   volatile uint32_t *ntfy;
+
+   if (!qo)
+      return NULL;
+
+   /* allocate a new hw query object, if no hw objects left we need to
+    * spin waiting for one to become free
+    */
+   while (nouveau_heap_alloc(screen->query_heap, 32, NULL, &qo->hw)) {
+      oq = LIST_FIRST_ENTRY(struct nv30_query_object, &screen->queries, list);
+      nv30_query_object_del(screen, &oq);
+   }
+
+   LIST_ADDTAIL(&qo->list, &screen->queries);
+
+   ntfy = nv30_ntfy(screen, qo);
+   ntfy[0] = 0x00000000;
+   ntfy[1] = 0x00000000;
+   ntfy[2] = 0x00000000;
+   ntfy[3] = 0x01000000;
+   return qo;
+}
+
+struct nv30_query {
+   struct nv30_query_object *qo[2];
+   unsigned type;
+   uint32_t report;
+   uint32_t enable;
+   uint64_t result;
+};
+
+static INLINE struct nv30_query *
+nv30_query(struct pipe_query *pipe)
+{
+   return (struct nv30_query *)pipe;
+}
+
+static struct pipe_query *
+nv30_query_create(struct pipe_context *pipe, unsigned type)
+{
+   struct nv30_query *q = CALLOC_STRUCT(nv30_query);
+   if (!q)
+      return NULL;
+
+   q->type = type;
+
+   switch (q->type) {
+   case PIPE_QUERY_TIME_ELAPSED:
+      q->enable = 0x0000;
+      q->report = 1;
+      break;
+   case PIPE_QUERY_OCCLUSION_COUNTER:
+      q->enable = NV30_3D_QUERY_ENABLE;
+      q->report = 1;
+      break;
+   case NV30_QUERY_ZCULL_0:
+   case NV30_QUERY_ZCULL_1:
+   case NV30_QUERY_ZCULL_2:
+   case NV30_QUERY_ZCULL_3:
+      q->enable = 0x1804;
+      q->report = 2 + (q->type - NV30_QUERY_ZCULL_0);
+      break;
+   default:
+      FREE(q);
+      return NULL;
+   }
+
+   return (struct pipe_query *)q;
+}
+
+static void
+nv30_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
+{
+   FREE(pq);
+}
+
+static void
+nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nv30_query *q = nv30_query(pq);
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+   switch (q->type) {
+   case PIPE_QUERY_TIME_ELAPSED:
+      q->qo[0] = nv30_query_object_new(nv30->screen);
+      if (q->qo[0]) {
+         BEGIN_NV04(push, NV30_3D(QUERY_GET), 1);
+         PUSH_DATA (push, (q->report << 24) | q->qo[0]->hw->start);
+      }
+      break;
+   default:
+      BEGIN_NV04(push, NV30_3D(QUERY_RESET), 1);
+      PUSH_DATA (push, q->report);
+      break;
+   }
+
+   if (q->enable) {
+      BEGIN_NV04(push, SUBC_3D(q->enable), 1);
+      PUSH_DATA (push, 1);
+   }
+}
+
+static void
+nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nv30_screen *screen = nv30->screen;
+   struct nv30_query *q = nv30_query(pq);
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+   q->qo[1] = nv30_query_object_new(screen);
+   if (q->qo[1]) {
+      BEGIN_NV04(push, NV30_3D(QUERY_GET), 1);
+      PUSH_DATA (push, (q->report << 24) | q->qo[1]->hw->start);
+   }
+
+   if (q->enable) {
+      BEGIN_NV04(push, SUBC_3D(q->enable), 1);
+      PUSH_DATA (push, 0);
+   }
+   PUSH_KICK (push);
+}
+
+static boolean
+nv30_query_result(struct pipe_context *pipe, struct pipe_query *pq,
+                  boolean wait, void *result)
+{
+   struct nv30_screen *screen = nv30_screen(pipe->screen);
+   struct nv30_query *q = nv30_query(pq);
+   volatile uint32_t *ntfy0 = nv30_ntfy(screen, q->qo[0]);
+   volatile uint32_t *ntfy1 = nv30_ntfy(screen, q->qo[1]);
+   uint64_t *res64 = result;
+
+   if (ntfy1) {
+      while (ntfy1[3] & 0xff000000) {
+         if (!wait)
+            return FALSE;
+      }
+
+      switch (q->type) {
+      case PIPE_QUERY_TIME_ELAPSED:
+         q->result = *(uint64_t *)&ntfy1[0] - *(uint64_t *)&ntfy0[0];
+         break;
+      default:
+         q->result = ntfy1[2];
+         break;
+      }
+
+      nv30_query_object_del(screen, &q->qo[0]);
+      nv30_query_object_del(screen, &q->qo[1]);
+   }
+
+   *res64 = q->result;
+   return TRUE;
+}
+
+static void
+nv40_query_render_condition(struct pipe_context *pipe,
+                            struct pipe_query *pq, uint mode)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nv30_query *q = nv30_query(pq);
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+   if (!pq) {
+      BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
+      PUSH_DATA (push, 0x01000000);
+      return;
+   }
+
+   if (mode == PIPE_RENDER_COND_WAIT ||
+       mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
+      BEGIN_NV04(push, SUBC_3D(0x0110), 1);
+      PUSH_DATA (push, 0);
+   }
+
+   BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
+   PUSH_DATA (push, 0x02000000 | q->qo[1]->hw->start);
+}
+
+void
+nv30_query_init(struct pipe_context *pipe)
+{
+   struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d;
+
+   pipe->create_query = nv30_query_create;
+   pipe->destroy_query = nv30_query_destroy;
+   pipe->begin_query = nv30_query_begin;
+   pipe->end_query = nv30_query_end;
+   pipe->get_query_result = nv30_query_result;
+   if (eng3d->oclass >= NV40_3D_CLASS)
+      pipe->render_condition = nv40_query_render_condition;
+}
diff --git a/src/gallium/drivers/nv30/nv30_resource.c b/src/gallium/drivers/nv30/nv30_resource.c
new file mode 100644 (file)
index 0000000..6bcee4d
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+
+#include "nv30_screen.h"
+#include "nv30_context.h"
+#include "nv30_resource.h"
+#include "nv30_transfer.h"
+
+static struct pipe_resource *
+nv30_resource_create(struct pipe_screen *pscreen,
+                     const struct pipe_resource *tmpl)
+{
+   switch (tmpl->target) {
+   case PIPE_BUFFER:
+      return nouveau_buffer_create(pscreen, tmpl);
+   default:
+      return nv30_miptree_create(pscreen, tmpl);
+   }
+}
+
+static struct pipe_resource *
+nv30_resource_from_handle(struct pipe_screen *pscreen,
+                          const struct pipe_resource *tmpl,
+                          struct winsys_handle *handle)
+{
+   if (tmpl->target == PIPE_BUFFER)
+      return NULL;
+   else
+      return nv30_miptree_from_handle(pscreen, tmpl, handle);
+}
+
+void
+nv30_resource_screen_init(struct pipe_screen *pscreen)
+{
+   pscreen->resource_create = nv30_resource_create;
+   pscreen->resource_from_handle = nv30_resource_from_handle;
+   pscreen->resource_get_handle = u_resource_get_handle_vtbl;
+   pscreen->resource_destroy = u_resource_destroy_vtbl;
+   pscreen->user_buffer_create = nouveau_user_buffer_create;
+}
+
+void
+nv30_resource_init(struct pipe_context *pipe)
+{
+   pipe->get_transfer = u_get_transfer_vtbl;
+   pipe->transfer_map = u_transfer_map_vtbl;
+   pipe->transfer_flush_region = u_transfer_flush_region_vtbl;
+   pipe->transfer_unmap = u_transfer_unmap_vtbl;
+   pipe->transfer_destroy = u_transfer_destroy_vtbl;
+   pipe->transfer_inline_write = u_transfer_inline_write_vtbl;
+   pipe->create_surface = nv30_miptree_surface_new;
+   pipe->surface_destroy = nv30_miptree_surface_del;
+   pipe->resource_copy_region = nv30_resource_copy_region;
+   pipe->resource_resolve = nv30_resource_resolve;
+}
diff --git a/src/gallium/drivers/nv30/nv30_resource.h b/src/gallium/drivers/nv30/nv30_resource.h
new file mode 100644 (file)
index 0000000..6f5d1a8
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef __NV30_RESOURCE_H__
+#define __NV30_RESOURCE_H__
+
+#include "nouveau/nouveau_buffer.h"
+
+void nv30_resource_screen_init(struct pipe_screen *);
+void nv30_resource_init(struct pipe_context *);
+
+struct nv30_surface {
+   struct pipe_surface base;
+   uint32_t offset;
+   uint32_t pitch;
+   uint32_t width;
+   uint16_t height;
+   uint16_t depth;
+};
+
+static INLINE struct nv30_surface *
+nv30_surface(struct pipe_surface *ps)
+{
+   return (struct nv30_surface *)ps;
+}
+
+struct nv30_miptree_level {
+   uint32_t offset;
+   uint32_t pitch;
+   uint32_t zslice_size;
+};
+
+struct nv30_miptree {
+   struct nv04_resource base;
+   struct nv30_miptree_level level[13];
+   uint32_t uniform_pitch;
+   uint32_t layer_size;
+   boolean swizzled;
+   unsigned ms_mode;
+   unsigned ms_x:1;
+   unsigned ms_y:1;
+};
+
+static INLINE struct nv30_miptree *
+nv30_miptree(struct pipe_resource *pt)
+{
+   return (struct nv30_miptree *)pt;
+}
+
+struct pipe_resource *
+nv30_miptree_create(struct pipe_screen *, const struct pipe_resource *);
+
+struct pipe_resource *
+nv30_miptree_from_handle(struct pipe_screen *, const struct pipe_resource *,
+                         struct winsys_handle *);
+
+struct pipe_surface *
+nv30_miptree_surface_new(struct pipe_context *, struct pipe_resource *,
+                         const struct pipe_surface *);
+
+void
+nv30_miptree_surface_del(struct pipe_context *, struct pipe_surface *);
+
+void
+nv30_resource_copy_region(struct pipe_context *pipe,
+                          struct pipe_resource *dst, unsigned dst_level,
+                          unsigned dstx, unsigned dsty, unsigned dstz,
+                          struct pipe_resource *src, unsigned src_level,
+                          const struct pipe_box *src_box);
+
+void
+nv30_resource_resolve(struct pipe_context *, const struct pipe_resolve_info *);
+
+#endif
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
new file mode 100644 (file)
index 0000000..fa51407
--- /dev/null
@@ -0,0 +1,565 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "util/u_format_s3tc.h"
+
+#include "nouveau/nv_object.xml.h"
+#include "nouveau/nv_m2mf.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv01_2d.xml.h"
+
+#include "nouveau/nouveau_fence.h"
+#include "nv30_screen.h"
+#include "nv30_context.h"
+#include "nv30_resource.h"
+#include "nv30_format.h"
+
+#define RANKINE_0397_CHIPSET 0x00000003
+#define RANKINE_0497_CHIPSET 0x000001e0
+#define RANKINE_0697_CHIPSET 0x00000010
+#define CURIE_4097_CHIPSET   0x00000baf
+#define CURIE_4497_CHIPSET   0x00005450
+#define CURIE_4497_CHIPSET6X 0x00000088
+
+static int
+nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
+{
+   struct nv30_screen *screen = nv30_screen(pscreen);
+   struct nouveau_object *eng3d = screen->eng3d;
+
+   switch (param) {
+   /* non-boolean capabilities */
+   case PIPE_CAP_MAX_RENDER_TARGETS:
+      return (eng3d->oclass >= NV40_3D_CLASS) ? 4 : 1;
+   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+      return 13;
+   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+      return 10;
+   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+      return 13;
+   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+      return 16;
+   case PIPE_CAP_GLSL_FEATURE_LEVEL:
+      return 120;
+   /* supported capabilities */
+   case PIPE_CAP_TWO_SIDED_STENCIL:
+   case PIPE_CAP_ANISOTROPIC_FILTER:
+   case PIPE_CAP_POINT_SPRITE:
+   case PIPE_CAP_SCALED_RESOLVE:
+   case PIPE_CAP_OCCLUSION_QUERY:
+   case PIPE_CAP_TIMER_QUERY:
+   case PIPE_CAP_TEXTURE_SHADOW_MAP:
+   case PIPE_CAP_TEXTURE_SWIZZLE:
+   case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+   case PIPE_CAP_DEPTH_CLIP_DISABLE:
+   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+      return 1;
+   /* nv4x capabilities */
+   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+   case PIPE_CAP_NPOT_TEXTURES:
+   case PIPE_CAP_CONDITIONAL_RENDER:
+   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
+   case PIPE_CAP_PRIMITIVE_RESTART:
+      return (eng3d->oclass >= NV40_3D_CLASS) ? 1 : 0;
+   /* unsupported */
+   case PIPE_CAP_DUAL_SOURCE_BLEND:
+   case PIPE_CAP_SM3:
+   case PIPE_CAP_INDEP_BLEND_ENABLE:
+   case PIPE_CAP_INDEP_BLEND_FUNC:
+   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
+   case PIPE_CAP_SHADER_STENCIL_EXPORT:
+   case PIPE_CAP_TGSI_INSTANCEID:
+   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: /* XXX: yes? */
+   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
+   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
+   case PIPE_CAP_MIN_TEXEL_OFFSET:
+   case PIPE_CAP_MAX_TEXEL_OFFSET:
+   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
+   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
+   case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
+   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
+   case PIPE_CAP_TEXTURE_BARRIER:
+   case PIPE_CAP_SEAMLESS_CUBE_MAP:
+   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
+   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
+   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
+      return 0;
+   default:
+      debug_printf("unknown param %d\n", param);
+      return 0;
+   }
+}
+
+static float
+nv30_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
+{
+   struct nv30_screen *screen = nv30_screen(pscreen);
+   struct nouveau_object *eng3d = screen->eng3d;
+
+   switch (param) {
+   case PIPE_CAPF_MAX_LINE_WIDTH:
+   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
+      return 10.0;
+   case PIPE_CAPF_MAX_POINT_WIDTH:
+   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
+      return 64.0;
+   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
+      return (eng3d->oclass >= NV40_3D_CLASS) ? 16.0 : 8.0;
+   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
+      return 15.0;
+   default:
+      debug_printf("unknown paramf %d\n", param);
+      return 0;
+   }
+}
+
+static int
+nv30_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
+                             enum pipe_shader_cap param)
+{
+   struct nv30_screen *screen = nv30_screen(pscreen);
+   struct nouveau_object *eng3d = screen->eng3d;
+
+   switch (shader) {
+   case PIPE_SHADER_VERTEX:
+      switch (param) {
+      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+         return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 256;
+      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+         return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 0;
+      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+         return 0;
+      case PIPE_SHADER_CAP_MAX_INPUTS:
+         return 16;
+      case PIPE_SHADER_CAP_MAX_CONSTS:
+         return (eng3d->oclass >= NV40_3D_CLASS) ? (468 - 6): (256 - 6);
+      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+         return 1;
+      case PIPE_SHADER_CAP_MAX_TEMPS:
+         return (eng3d->oclass >= NV40_3D_CLASS) ? 32 : 13;
+      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
+         return 0;
+      case PIPE_SHADER_CAP_MAX_ADDRS:
+         return 2;
+      case PIPE_SHADER_CAP_MAX_PREDS:
+      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
+      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
+      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
+      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
+      case PIPE_SHADER_CAP_SUBROUTINES:
+      case PIPE_SHADER_CAP_INTEGERS:
+         return 0;
+      default:
+         debug_printf("unknown vertex shader param %d\n", param);
+         return 0;
+      }
+      break;
+   case PIPE_SHADER_FRAGMENT:
+      switch (param) {
+      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+         return 4096;
+      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+         return 0;
+      case PIPE_SHADER_CAP_MAX_INPUTS:
+         return (eng3d->oclass >= NV40_3D_CLASS) ? 12 : 10;
+      case PIPE_SHADER_CAP_MAX_CONSTS:
+         return (eng3d->oclass >= NV40_3D_CLASS) ? 224 : 32;
+      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+         return 1;
+      case PIPE_SHADER_CAP_MAX_TEMPS:
+         return 32;
+      case PIPE_SHADER_CAP_MAX_ADDRS:
+         return (eng3d->oclass >= NV40_3D_CLASS) ? 1 : 0;
+      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
+         return 16;
+      case PIPE_SHADER_CAP_MAX_PREDS:
+      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
+      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
+      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
+      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
+      case PIPE_SHADER_CAP_SUBROUTINES:
+         return 0;
+      default:
+         debug_printf("unknown fragment shader param %d\n", param);
+         return 0;
+      }
+      break;
+   default:
+      return 0;
+   }
+}
+
+static boolean
+nv30_screen_is_format_supported(struct pipe_screen *pscreen,
+                                enum pipe_format format,
+                                enum pipe_texture_target target,
+                                unsigned sample_count,
+                                unsigned bindings)
+{
+   if (!(0x00000017 & (1 << sample_count)))
+      return FALSE;
+
+   if (!util_format_s3tc_enabled) {
+      switch (format) {
+      case PIPE_FORMAT_DXT1_RGB:
+      case PIPE_FORMAT_DXT1_RGBA:
+      case PIPE_FORMAT_DXT3_RGBA:
+      case PIPE_FORMAT_DXT5_RGBA:
+         return FALSE;
+      default:
+         break;
+      }
+   }
+
+   /* transfers & shared are always supported */
+   bindings &= ~(PIPE_BIND_TRANSFER_READ |
+                 PIPE_BIND_TRANSFER_WRITE |
+                 PIPE_BIND_SHARED);
+
+   return (nv30_format_info(pscreen, format)->bindings & bindings) == bindings;
+}
+
+static void
+nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence)
+{
+   struct nv30_screen *screen = nv30_screen(pscreen);
+   struct nouveau_pushbuf *push = screen->base.pushbuf;
+
+   *sequence = ++screen->base.fence.sequence;
+
+   BEGIN_NV04(push, NV30_3D(FENCE_OFFSET), 2);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, *sequence);
+}
+
+static uint32_t
+nv30_screen_fence_update(struct pipe_screen *pscreen)
+{
+   struct nv30_screen *screen = nv30_screen(pscreen);
+   struct nv04_notify *fence = screen->fence->data;
+   return *(uint32_t *)((char *)screen->notify->map + fence->offset);
+}
+
+static void
+nv30_screen_destroy(struct pipe_screen *pscreen)
+{
+   struct nv30_screen *screen = nv30_screen(pscreen);
+
+   if (screen->base.fence.current &&
+       screen->base.fence.current->state >= NOUVEAU_FENCE_STATE_EMITTED) {
+      nouveau_fence_wait(screen->base.fence.current);
+      nouveau_fence_ref (NULL, &screen->base.fence.current);
+   }
+
+   nouveau_object_del(&screen->query);
+   nouveau_object_del(&screen->fence);
+   nouveau_object_del(&screen->ntfy);
+
+   nouveau_object_del(&screen->sifm);
+   nouveau_object_del(&screen->swzsurf);
+   nouveau_object_del(&screen->surf2d);
+   nouveau_object_del(&screen->m2mf);
+   nouveau_object_del(&screen->eng3d);
+   nouveau_object_del(&screen->null);
+
+   nouveau_screen_fini(&screen->base);
+   FREE(screen);
+}
+
+#define FAIL_SCREEN_INIT(str, err)                    \
+   do {                                               \
+      NOUVEAU_ERR(str, err);                          \
+      nv30_screen_destroy(pscreen);                   \
+      return NULL;                                    \
+   } while(0)
+
+struct pipe_screen *
+nv30_screen_create(struct nouveau_device *dev)
+{
+   struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen);
+   struct pipe_screen *pscreen;
+   struct nouveau_pushbuf *push;
+   struct nv04_fifo *fifo;
+   unsigned oclass = 0;
+   int ret, i;
+
+   if (!screen)
+      return NULL;
+
+   switch (dev->chipset & 0xf0) {
+   case 0x30:
+      if (RANKINE_0397_CHIPSET & (1 << (dev->chipset & 0x0f)))
+         oclass = NV30_3D_CLASS;
+      else
+      if (RANKINE_0697_CHIPSET & (1 << (dev->chipset & 0x0f)))
+         oclass = NV34_3D_CLASS;
+      else
+      if (RANKINE_0497_CHIPSET & (1 << (dev->chipset & 0x0f)))
+         oclass = NV35_3D_CLASS;
+      break;
+   case 0x40:
+      if (CURIE_4097_CHIPSET & (1 << (dev->chipset & 0x0f)))
+         oclass = NV40_3D_CLASS;
+      else
+      if (CURIE_4497_CHIPSET & (1 << (dev->chipset & 0x0f)))
+         oclass = NV44_3D_CLASS;
+      break;
+   case 0x60:
+      if (CURIE_4497_CHIPSET6X & (1 << (dev->chipset & 0x0f)))
+         oclass = NV44_3D_CLASS;
+      break;
+   default:
+      break;
+   }
+
+   if (!oclass) {
+      NOUVEAU_ERR("unknown 3d class for 0x%02x\n", dev->chipset);
+      return NULL;
+   }
+
+   pscreen = &screen->base.base;
+   pscreen->destroy = nv30_screen_destroy;
+   pscreen->get_param = nv30_screen_get_param;
+   pscreen->get_paramf = nv30_screen_get_paramf;
+   pscreen->get_shader_param = nv30_screen_get_shader_param;
+   pscreen->context_create = nv30_context_create;
+   pscreen->is_format_supported = nv30_screen_is_format_supported;
+   nv30_resource_screen_init(pscreen);
+
+   screen->base.fence.emit = nv30_screen_fence_emit;
+   screen->base.fence.update = nv30_screen_fence_update;
+   screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER;
+   if (oclass != NV40_3D_CLASS)
+      screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER;
+
+   ret = nouveau_screen_init(&screen->base, dev);
+   if (ret)
+      FAIL_SCREEN_INIT("nv30_screen_init failed: %d\n", ret);
+
+   fifo = screen->base.channel->data;
+   push = screen->base.pushbuf;
+   push->rsvd_kick = 16;
+
+   ret = nouveau_object_new(screen->base.channel, 0x00000000, NV01_NULL_CLASS,
+                            NULL, 0, &screen->null);
+   if (ret)
+      FAIL_SCREEN_INIT("error allocating null object: %d\n", ret);
+
+   /* DMA_FENCE refuses to accept DMA objects with "adjust" filled in,
+    * this means that the address pointed at by the DMA object must
+    * be 4KiB aligned, which means this object needs to be the first
+    * one allocated on the channel.
+    */
+   ret = nouveau_object_new(screen->base.channel, 0xbeef1e00,
+                            NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
+                            .length = 32 }, sizeof(struct nv04_notify),
+                            &screen->fence);
+   if (ret)
+      FAIL_SCREEN_INIT("error allocating fence notifier: %d\n", ret);
+
+   /* DMA_NOTIFY object, we don't actually use this but M2MF fails without */
+   ret = nouveau_object_new(screen->base.channel, 0xbeef0301,
+                            NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
+                            .length = 32 }, sizeof(struct nv04_notify),
+                            &screen->ntfy);
+   if (ret)
+      FAIL_SCREEN_INIT("error allocating sync notifier: %d\n", ret);
+
+   /* DMA_QUERY, used to implement occlusion queries, we attempt to allocate
+    * the remainder of the "notifier block" assigned by the kernel for
+    * use as query objects
+    */
+   ret = nouveau_object_new(screen->base.channel, 0xbeef0351,
+                            NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
+                            .length = 4096 - 128 }, sizeof(struct nv04_notify),
+                            &screen->query);
+   if (ret)
+      FAIL_SCREEN_INIT("error allocating query notifier: %d\n", ret);
+
+   ret = nouveau_heap_init(&screen->query_heap, 0, 4096 - 128);
+   if (ret)
+      FAIL_SCREEN_INIT("error creating query heap: %d\n", ret);
+
+   LIST_INITHEAD(&screen->queries);
+
+   /* Vertex program resources (code/data), currently 6 of the constant
+    * slots are reserved to implement user clipping planes
+    */
+   if (oclass < NV40_3D_CLASS) {
+      nouveau_heap_init(&screen->vp_exec_heap, 0, 256);
+      nouveau_heap_init(&screen->vp_data_heap, 6, 256 - 6);
+   } else {
+      nouveau_heap_init(&screen->vp_exec_heap, 0, 512);
+      nouveau_heap_init(&screen->vp_data_heap, 6, 468 - 6);
+   }
+
+   ret = nouveau_bo_wrap(screen->base.device, fifo->notify, &screen->notify);
+   if (ret == 0)
+      nouveau_bo_map(screen->notify, 0, screen->base.client);
+   if (ret)
+      FAIL_SCREEN_INIT("error mapping notifier memory: %d\n", ret);
+
+   ret = nouveau_object_new(screen->base.channel, 0xbeef3097, oclass,
+                            NULL, 0, &screen->eng3d);
+   if (ret)
+      FAIL_SCREEN_INIT("error allocating 3d object: %d\n", ret);
+
+   BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
+   PUSH_DATA (push, screen->eng3d->handle);
+   BEGIN_NV04(push, NV30_3D(DMA_NOTIFY), 13);
+   PUSH_DATA (push, screen->ntfy->handle);
+   PUSH_DATA (push, fifo->vram);     /* TEXTURE0 */
+   PUSH_DATA (push, fifo->gart);     /* TEXTURE1 */
+   PUSH_DATA (push, fifo->vram);     /* COLOR1 */
+   PUSH_DATA (push, screen->null->handle);  /* UNK190 */
+   PUSH_DATA (push, fifo->vram);     /* COLOR0 */
+   PUSH_DATA (push, fifo->vram);     /* ZETA */
+   PUSH_DATA (push, fifo->vram);     /* VTXBUF0 */
+   PUSH_DATA (push, fifo->gart);     /* VTXBUF1 */
+   PUSH_DATA (push, screen->fence->handle);  /* FENCE */
+   PUSH_DATA (push, screen->query->handle);  /* QUERY - intr 0x80 if nullobj */
+   PUSH_DATA (push, screen->null->handle);  /* UNK1AC */
+   PUSH_DATA (push, screen->null->handle);  /* UNK1B0 */
+   BEGIN_NV04(push, NV30_3D(VIEWPORT_CLIP_MODE), 1);
+   PUSH_DATA (push, 0);
+   if (screen->eng3d->oclass < NV40_3D_CLASS) {
+      BEGIN_NV04(push, SUBC_3D(0x03b0), 1);
+      PUSH_DATA (push, 0x00100000);
+      BEGIN_NV04(push, SUBC_3D(0x1d80), 1);
+      PUSH_DATA (push, 3);
+
+      BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
+      PUSH_DATA (push, 0);
+      BEGIN_NV04(push, SUBC_3D(0x17e0), 3);
+      PUSH_DATA (push, fui(0.0));
+      PUSH_DATA (push, fui(0.0));
+      PUSH_DATA (push, fui(1.0));
+      BEGIN_NV04(push, SUBC_3D(0x1f80), 16);
+      for (i = 0; i < 16; i++)
+         PUSH_DATA (push, (i == 8) ? 0x0000ffff : 0);
+
+      BEGIN_NV04(push, NV30_3D(RC_ENABLE), 1);
+      PUSH_DATA (push, 0);
+   } else {
+      BEGIN_NV04(push, NV40_3D(DMA_COLOR2), 2);
+      PUSH_DATA (push, fifo->vram);
+      PUSH_DATA (push, fifo->vram);  /* COLOR3 */
+
+      BEGIN_NV04(push, SUBC_3D(0x1450), 1);
+      PUSH_DATA (push, 0x00000004);
+
+      BEGIN_NV04(push, SUBC_3D(0x1ea4), 3); /* ZCULL */
+      PUSH_DATA (push, 0x00000010);
+      PUSH_DATA (push, 0x01000100);
+      PUSH_DATA (push, 0xff800006);
+
+      /* vtxprog output routing */
+      BEGIN_NV04(push, SUBC_3D(0x1fc4), 1);
+      PUSH_DATA (push, 0x06144321);
+      BEGIN_NV04(push, SUBC_3D(0x1fc8), 2);
+      PUSH_DATA (push, 0xedcba987);
+      PUSH_DATA (push, 0x0000006f);
+      BEGIN_NV04(push, SUBC_3D(0x1fd0), 1);
+      PUSH_DATA (push, 0x00171615);
+      BEGIN_NV04(push, SUBC_3D(0x1fd4), 1);
+      PUSH_DATA (push, 0x001b1a19);
+
+      BEGIN_NV04(push, SUBC_3D(0x1ef8), 1);
+      PUSH_DATA (push, 0x0020ffff);
+      BEGIN_NV04(push, SUBC_3D(0x1d64), 1);
+      PUSH_DATA (push, 0x01d300d4);
+
+      BEGIN_NV04(push, NV40_3D(MIPMAP_ROUNDING), 1);
+      PUSH_DATA (push, NV40_3D_MIPMAP_ROUNDING_MODE_DOWN);
+   }
+
+   ret = nouveau_object_new(screen->base.channel, 0xbeef3901, NV03_M2MF_CLASS,
+                            NULL, 0, &screen->m2mf);
+   if (ret)
+      FAIL_SCREEN_INIT("error allocating m2mf object: %d\n", ret);
+
+   BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1);
+   PUSH_DATA (push, screen->m2mf->handle);
+   BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1);
+   PUSH_DATA (push, screen->ntfy->handle);
+
+   ret = nouveau_object_new(screen->base.channel, 0xbeef6201,
+                            NV10_SURFACE_2D_CLASS, NULL, 0, &screen->surf2d);
+   if (ret)
+      FAIL_SCREEN_INIT("error allocating surf2d object: %d\n", ret);
+
+   BEGIN_NV04(push, NV01_SUBC(SF2D, OBJECT), 1);
+   PUSH_DATA (push, screen->surf2d->handle);
+   BEGIN_NV04(push, NV04_SF2D(DMA_NOTIFY), 1);
+   PUSH_DATA (push, screen->ntfy->handle);
+
+   if (dev->chipset < 0x40)
+      oclass = NV30_SURFACE_SWZ_CLASS;
+   else
+      oclass = NV40_SURFACE_SWZ_CLASS;
+
+   ret = nouveau_object_new(screen->base.channel, 0xbeef5201, oclass,
+                            NULL, 0, &screen->swzsurf);
+   if (ret)
+      FAIL_SCREEN_INIT("error allocating swizzled surface object: %d\n", ret);
+
+   BEGIN_NV04(push, NV01_SUBC(SSWZ, OBJECT), 1);
+   PUSH_DATA (push, screen->swzsurf->handle);
+   BEGIN_NV04(push, NV04_SSWZ(DMA_NOTIFY), 1);
+   PUSH_DATA (push, screen->ntfy->handle);
+
+   if (dev->chipset < 0x40)
+      oclass = NV30_SIFM_CLASS;
+   else
+      oclass = NV40_SIFM_CLASS;
+
+   ret = nouveau_object_new(screen->base.channel, 0xbeef7701, oclass,
+                            NULL, 0, &screen->sifm);
+   if (ret)
+      FAIL_SCREEN_INIT("error allocating scaled image object: %d\n", ret);
+
+   BEGIN_NV04(push, NV01_SUBC(SIFM, OBJECT), 1);
+   PUSH_DATA (push, screen->sifm->handle);
+   BEGIN_NV04(push, NV03_SIFM(DMA_NOTIFY), 1);
+   PUSH_DATA (push, screen->ntfy->handle);
+   BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1);
+   PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_TRUNCATE);
+
+   nouveau_pushbuf_kick(push, push->channel);
+
+   nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
+   return pscreen;
+}
diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h
new file mode 100644 (file)
index 0000000..2ee087e
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef __NV30_SCREEN_H__
+#define __NV30_SCREEN_H__
+
+#include <stdio.h>
+
+#define NOUVEAU_ERR(fmt, args...) \
+   fprintf(stderr, "%s:%d -  "fmt, __FUNCTION__, __LINE__, ##args);
+
+#include "util/u_double_list.h"
+
+#include "nouveau/nouveau_screen.h"
+#include "nouveau/nouveau_fence.h"
+#include "nouveau/nouveau_heap.h"
+#include "nv30_winsys.h"
+#include "nv30_resource.h"
+
+struct nv30_context;
+
+struct nv30_screen {
+   struct nouveau_screen base;
+
+   struct nv30_context *cur_ctx;
+
+   struct nouveau_bo *notify;
+
+   struct nouveau_object *ntfy;
+   struct nouveau_object *fence;
+
+   struct nouveau_object *query;
+   struct nouveau_heap *query_heap;
+   struct list_head queries;
+
+   struct nouveau_object *null;
+   struct nouveau_object *eng3d;
+   struct nouveau_object *m2mf;
+   struct nouveau_object *surf2d;
+   struct nouveau_object *swzsurf;
+   struct nouveau_object *sifm;
+
+   /*XXX: nvfx state */
+   struct nouveau_heap *vp_exec_heap;
+   struct nouveau_heap *vp_data_heap;
+};
+
+static INLINE struct nv30_screen *
+nv30_screen(struct pipe_screen *pscreen)
+{
+   return (struct nv30_screen *)pscreen;
+}
+
+#endif
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
new file mode 100644 (file)
index 0000000..64a8f33
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "util/u_inlines.h"
+
+#include "nouveau/nouveau_gldefs.h"
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_winsys.h"
+
+#define NV40_3D_MRT_BLEND_ENABLE 0x0000036c
+
+static void *
+nv30_blend_state_create(struct pipe_context *pipe,
+                        const struct pipe_blend_state *cso)
+{
+   struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d;
+   struct nv30_blend_stateobj *so;
+   uint32_t blend[2], cmask[2];
+   int i;
+
+   so = CALLOC_STRUCT(nv30_blend_stateobj);
+   if (!so)
+      return NULL;
+   so->pipe = *cso;
+
+   if (cso->logicop_enable) {
+      SB_MTHD30(so, COLOR_LOGIC_OP_ENABLE, 2);
+      SB_DATA  (so, 1);
+      SB_DATA  (so, nvgl_logicop_func(cso->logicop_func));
+   } else {
+      SB_MTHD30(so, COLOR_LOGIC_OP_ENABLE, 1);
+      SB_DATA  (so, 0);
+   }
+
+   SB_MTHD30(so, DITHER_ENABLE, 1);
+   SB_DATA  (so, cso->dither);
+
+   blend[0] = cso->rt[0].blend_enable;
+   cmask[0] = !!(cso->rt[0].colormask & PIPE_MASK_A) << 24 |
+              !!(cso->rt[0].colormask & PIPE_MASK_R) << 16 |
+              !!(cso->rt[0].colormask & PIPE_MASK_G) <<  8 |
+              !!(cso->rt[0].colormask & PIPE_MASK_B);
+   if (cso->independent_blend_enable) {
+      blend[1] = 0;
+      cmask[1] = 0;
+      for (i = 1; i < 4; i++) {
+         blend[1] |= cso->rt[i].blend_enable << i;
+         cmask[1] |= !!(cso->rt[i].colormask & PIPE_MASK_A) << (0 + (i * 4)) |
+                     !!(cso->rt[i].colormask & PIPE_MASK_R) << (1 + (i * 4)) |
+                     !!(cso->rt[i].colormask & PIPE_MASK_G) << (2 + (i * 4)) |
+                     !!(cso->rt[i].colormask & PIPE_MASK_B) << (3 + (i * 4));
+      }
+   } else {
+      blend[1]  = 0x0000000e *   (blend[0] & 0x00000001);
+      cmask[1]  = 0x00001110 * !!(cmask[0] & 0x01000000);
+      cmask[1] |= 0x00002220 * !!(cmask[0] & 0x00010000);
+      cmask[1] |= 0x00004440 * !!(cmask[0] & 0x00000100);
+      cmask[1] |= 0x00008880 * !!(cmask[0] & 0x00000001);
+   }
+
+   if (eng3d->oclass >= NV40_3D_CLASS) {
+      SB_MTHD40(so, MRT_BLEND_ENABLE, 2);
+      SB_DATA  (so, blend[1]);
+      SB_DATA  (so, cmask[1]);
+   }
+
+   if (blend[0] || blend[1]) {
+      SB_MTHD30(so, BLEND_FUNC_ENABLE, 3);
+      SB_DATA  (so, blend[0]);
+      SB_DATA  (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) |
+                     nvgl_blend_func(cso->rt[0].rgb_src_factor));
+      SB_DATA  (so, (nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16) |
+                     nvgl_blend_func(cso->rt[0].rgb_dst_factor));
+      if (eng3d->oclass < NV40_3D_CLASS) {
+         SB_MTHD30(so, BLEND_EQUATION, 1);
+         SB_DATA  (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
+      } else {
+         SB_MTHD40(so, BLEND_EQUATION, 1);
+         SB_DATA  (so, (nvgl_blend_eqn(cso->rt[0].alpha_func) << 16) |
+                        nvgl_blend_eqn(cso->rt[0].rgb_func));
+      }
+   } else {
+      SB_MTHD30(so, BLEND_FUNC_ENABLE, 1);
+      SB_DATA  (so, blend[0]);
+   }
+
+   SB_MTHD30(so, COLOR_MASK, 1);
+   SB_DATA  (so, cmask[0]);
+   return so;
+}
+
+static void
+nv30_blend_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+
+   nv30->blend = hwcso;
+   nv30->dirty |= NV30_NEW_BLEND;
+}
+
+static void
+nv30_blend_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+   FREE(hwcso);
+}
+
+static void *
+nv30_rasterizer_state_create(struct pipe_context *pipe,
+                             const struct pipe_rasterizer_state *cso)
+{
+   struct nv30_rasterizer_stateobj *so;
+
+   so = CALLOC_STRUCT(nv30_rasterizer_stateobj);
+   if (!so)
+      return NULL;
+   so->pipe = *cso;
+
+   SB_MTHD30(so, SHADE_MODEL, 1);
+   SB_DATA  (so, cso->flatshade ? NV30_3D_SHADE_MODEL_FLAT :
+                                  NV30_3D_SHADE_MODEL_SMOOTH);
+
+   SB_MTHD30(so, POLYGON_MODE_FRONT, 6);
+   SB_DATA  (so, nvgl_polygon_mode(cso->fill_front));
+   SB_DATA  (so, nvgl_polygon_mode(cso->fill_back));
+   if (cso->cull_face == PIPE_FACE_FRONT_AND_BACK)
+      SB_DATA  (so, NV30_3D_CULL_FACE_FRONT_AND_BACK);
+   else
+   if (cso->cull_face == PIPE_FACE_FRONT)
+      SB_DATA  (so, NV30_3D_CULL_FACE_FRONT);
+   else
+      SB_DATA  (so, NV30_3D_CULL_FACE_BACK);
+   SB_DATA  (so, cso->front_ccw ? NV30_3D_FRONT_FACE_CCW :
+                                  NV30_3D_FRONT_FACE_CW);
+   SB_DATA  (so, cso->poly_smooth);
+   SB_DATA  (so, cso->cull_face != PIPE_FACE_NONE);
+
+   SB_MTHD30(so, POLYGON_OFFSET_POINT_ENABLE, 3);
+   SB_DATA  (so, cso->offset_point);
+   SB_DATA  (so, cso->offset_line);
+   SB_DATA  (so, cso->offset_tri);
+   if (cso->offset_point || cso->offset_line || cso->offset_tri) {
+      SB_MTHD30(so, POLYGON_OFFSET_FACTOR, 2);
+      SB_DATA  (so, fui(cso->offset_scale));
+      SB_DATA  (so, fui(cso->offset_units * 2.0));
+   }
+
+   SB_MTHD30(so, LINE_WIDTH, 2);
+   SB_DATA  (so, (unsigned char)(cso->line_width * 8.0) & 0xff);
+   SB_DATA  (so, cso->line_smooth);
+   SB_MTHD30(so, LINE_STIPPLE_ENABLE, 2);
+   SB_DATA  (so, cso->line_stipple_enable);
+   SB_DATA  (so, (cso->line_stipple_pattern << 16) |
+                  cso->line_stipple_factor);
+
+   SB_MTHD30(so, VERTEX_TWO_SIDE_ENABLE, 1);
+   SB_DATA  (so, cso->light_twoside);
+   SB_MTHD30(so, POLYGON_STIPPLE_ENABLE, 1);
+   SB_DATA  (so, cso->poly_stipple_enable);
+   SB_MTHD30(so, POINT_SIZE, 1);
+   SB_DATA  (so, fui(cso->point_size));
+   SB_MTHD30(so, FLATSHADE_FIRST, 1);
+   SB_DATA  (so, cso->flatshade_first);
+
+   SB_MTHD30(so, DEPTH_CONTROL, 1);
+   SB_DATA  (so, cso->depth_clip ? 0x00000001 : 0x00000010);
+   return so;
+}
+
+static void
+nv30_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+
+   nv30->rast = hwcso;
+   nv30->dirty |= NV30_NEW_RASTERIZER;
+}
+
+static void
+nv30_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+   FREE(hwcso);
+}
+
+static void *
+nv30_zsa_state_create(struct pipe_context *pipe,
+                      const struct pipe_depth_stencil_alpha_state *cso)
+{
+   struct nv30_zsa_stateobj *so;
+
+   so = CALLOC_STRUCT(nv30_zsa_stateobj);
+   if (!so)
+      return NULL;
+   so->pipe = *cso;
+
+   SB_MTHD30(so, DEPTH_FUNC, 3);
+   SB_DATA  (so, nvgl_comparison_op(cso->depth.func));
+   SB_DATA  (so, cso->depth.writemask);
+   SB_DATA  (so, cso->depth.enabled);
+
+   if (cso->stencil[0].enabled) {
+      SB_MTHD30(so, STENCIL_ENABLE(0), 3);
+      SB_DATA  (so, 1);
+      SB_DATA  (so, cso->stencil[0].writemask);
+      SB_DATA  (so, nvgl_comparison_op(cso->stencil[0].func));
+      SB_MTHD30(so, STENCIL_FUNC_MASK(0), 4);
+      SB_DATA  (so, cso->stencil[0].valuemask);
+      SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
+      SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
+      SB_DATA  (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
+   } else {
+      SB_MTHD30(so, STENCIL_ENABLE(0), 2);
+      SB_DATA  (so, 0);
+      SB_DATA  (so, 0x000000ff);
+   }
+
+   if (cso->stencil[1].enabled) {
+      SB_MTHD30(so, STENCIL_ENABLE(1), 3);
+      SB_DATA  (so, 1);
+      SB_DATA  (so, cso->stencil[1].writemask);
+      SB_DATA  (so, nvgl_comparison_op(cso->stencil[1].func));
+      SB_MTHD30(so, STENCIL_FUNC_MASK(1), 4);
+      SB_DATA  (so, cso->stencil[1].valuemask);
+      SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
+      SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
+      SB_DATA  (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
+   } else {
+      SB_MTHD30(so, STENCIL_ENABLE(1), 1);
+      SB_DATA  (so, 0);
+   }
+
+   SB_MTHD30(so, ALPHA_FUNC_ENABLE, 3);
+   SB_DATA  (so, cso->alpha.enabled ? 1 : 0);
+   SB_DATA  (so, nvgl_comparison_op(cso->alpha.func));
+   SB_DATA  (so, float_to_ubyte(cso->alpha.ref_value));
+
+   return so;
+}
+
+static void
+nv30_zsa_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+
+   nv30->zsa = hwcso;
+   nv30->dirty |= NV30_NEW_ZSA;
+}
+
+static void
+nv30_zsa_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+   FREE(hwcso);
+}
+
+static void
+nv30_set_blend_color(struct pipe_context *pipe,
+                     const struct pipe_blend_color *bcol)
+{
+    struct nv30_context *nv30 = nv30_context(pipe);
+
+    nv30->blend_colour = *bcol;
+    nv30->dirty |= NV30_NEW_BLEND_COLOUR;
+}
+
+static void
+nv30_set_stencil_ref(struct pipe_context *pipe,
+                     const struct pipe_stencil_ref *sr)
+{
+    struct nv30_context *nv30 = nv30_context(pipe);
+
+    nv30->stencil_ref = *sr;
+    nv30->dirty |= NV30_NEW_STENCIL_REF;
+}
+
+static void
+nv30_set_clip_state(struct pipe_context *pipe,
+                    const struct pipe_clip_state *clip)
+{
+    struct nv30_context *nv30 = nv30_context(pipe);
+
+    memcpy(nv30->clip.ucp, clip->ucp, sizeof(clip->ucp));
+
+    nv30->dirty |= NV30_NEW_CLIP;
+}
+
+static void
+nv30_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
+{
+    struct nv30_context *nv30 = nv30_context(pipe);
+
+    nv30->sample_mask = sample_mask;
+    nv30->dirty |= NV30_NEW_SAMPLE_MASK;
+}
+
+static void
+nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
+                         struct pipe_resource *buf)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   unsigned size;
+
+   size = 0;
+   if (buf)
+      size = buf->width0 / (4 * sizeof(float));
+
+   if (shader == PIPE_SHADER_VERTEX) {
+      pipe_resource_reference(&nv30->vertprog.constbuf, buf);
+      nv30->vertprog.constbuf_nr = size;
+      nv30->dirty |= NV30_NEW_VERTCONST;
+   } else
+   if (shader == PIPE_SHADER_FRAGMENT) {
+      pipe_resource_reference(&nv30->fragprog.constbuf, buf);
+      nv30->fragprog.constbuf_nr = size;
+      nv30->dirty |= NV30_NEW_FRAGCONST;
+   }
+}
+
+static void
+nv30_set_framebuffer_state(struct pipe_context *pipe,
+                           const struct pipe_framebuffer_state *fb)
+{
+    struct nv30_context *nv30 = nv30_context(pipe);
+
+    nouveau_bufctx_reset(nv30->bufctx, BUFCTX_FB);
+
+    nv30->framebuffer = *fb;
+    nv30->dirty |= NV30_NEW_FRAMEBUFFER;
+}
+
+static void
+nv30_set_polygon_stipple(struct pipe_context *pipe,
+                         const struct pipe_poly_stipple *stipple)
+{
+    struct nv30_context *nv30 = nv30_context(pipe);
+
+    nv30->stipple = *stipple;
+    nv30->dirty |= NV30_NEW_STIPPLE;
+}
+
+static void
+nv30_set_scissor_state(struct pipe_context *pipe,
+                       const struct pipe_scissor_state *scissor)
+{
+    struct nv30_context *nv30 = nv30_context(pipe);
+
+    nv30->scissor = *scissor;
+    nv30->dirty |= NV30_NEW_SCISSOR;
+}
+
+static void
+nv30_set_viewport_state(struct pipe_context *pipe,
+                        const struct pipe_viewport_state *vpt)
+{
+    struct nv30_context *nv30 = nv30_context(pipe);
+
+    nv30->viewport = *vpt;
+    nv30->dirty |= NV30_NEW_VIEWPORT;
+}
+
+static void
+nv30_set_vertex_buffers(struct pipe_context *pipe,
+                        unsigned count,
+                        const struct pipe_vertex_buffer *vb)
+{
+    struct nv30_context *nv30 = nv30_context(pipe);
+    unsigned i;
+
+    nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VTXBUF);
+
+    for (i = 0; i < count; ++i)
+       pipe_resource_reference(&nv30->vtxbuf[i].buffer, vb[i].buffer);
+    for (; i < nv30->num_vtxbufs; ++i)
+       pipe_resource_reference(&nv30->vtxbuf[i].buffer, NULL);
+
+    memcpy(nv30->vtxbuf, vb, sizeof(*vb) * count);
+    nv30->num_vtxbufs = count;
+
+    nv30->dirty |= NV30_NEW_ARRAYS;
+}
+
+static void
+nv30_set_index_buffer(struct pipe_context *pipe,
+                      const struct pipe_index_buffer *ib)
+{
+    struct nv30_context *nv30 = nv30_context(pipe);
+
+    if (ib) {
+       pipe_resource_reference(&nv30->idxbuf.buffer, ib->buffer);
+       memcpy(&nv30->idxbuf, ib, sizeof(nv30->idxbuf));
+    } else {
+       pipe_resource_reference(&nv30->idxbuf.buffer, NULL);
+    }
+}
+
+void
+nv30_state_init(struct pipe_context *pipe)
+{
+   pipe->create_blend_state = nv30_blend_state_create;
+   pipe->bind_blend_state = nv30_blend_state_bind;
+   pipe->delete_blend_state = nv30_blend_state_delete;
+
+   pipe->create_rasterizer_state = nv30_rasterizer_state_create;
+   pipe->bind_rasterizer_state = nv30_rasterizer_state_bind;
+   pipe->delete_rasterizer_state = nv30_rasterizer_state_delete;
+
+   pipe->create_depth_stencil_alpha_state = nv30_zsa_state_create;
+   pipe->bind_depth_stencil_alpha_state = nv30_zsa_state_bind;
+   pipe->delete_depth_stencil_alpha_state = nv30_zsa_state_delete;
+
+   pipe->set_blend_color = nv30_set_blend_color;
+   pipe->set_stencil_ref = nv30_set_stencil_ref;
+   pipe->set_clip_state = nv30_set_clip_state;
+   pipe->set_sample_mask = nv30_set_sample_mask;
+   pipe->set_constant_buffer = nv30_set_constant_buffer;
+   pipe->set_framebuffer_state = nv30_set_framebuffer_state;
+   pipe->set_polygon_stipple = nv30_set_polygon_stipple;
+   pipe->set_scissor_state = nv30_set_scissor_state;
+   pipe->set_viewport_state = nv30_set_viewport_state;
+
+   pipe->set_vertex_buffers = nv30_set_vertex_buffers;
+   pipe->set_index_buffer = nv30_set_index_buffer;
+
+   pipe->redefine_user_buffer = u_default_redefine_user_buffer;
+}
diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h
new file mode 100644 (file)
index 0000000..a219bf2
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef __NV30_STATE_H__
+#define __NV30_STATE_H__
+
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_scan.h"
+#include "util/u_dynarray.h"
+
+#define NV30_QUERY_ZCULL_0 (PIPE_QUERY_TYPES + 0)
+#define NV30_QUERY_ZCULL_1 (PIPE_QUERY_TYPES + 1)
+#define NV30_QUERY_ZCULL_2 (PIPE_QUERY_TYPES + 2)
+#define NV30_QUERY_ZCULL_3 (PIPE_QUERY_TYPES + 3)
+
+#define SB_DATA(so, u)        (so)->data[(so)->size++] = (u)
+#define SB_MTHD30(so, mthd, size)                                          \
+   SB_DATA((so), ((size) << 18) | (7 << 13) | NV30_3D_##mthd)
+#define SB_MTHD40(so, mthd, size)                                          \
+   SB_DATA((so), ((size) << 18) | (7 << 13) | NV40_3D_##mthd)
+
+struct nv30_blend_stateobj {
+   struct pipe_blend_state pipe;
+   unsigned data[16];
+   unsigned size;
+};
+
+struct nv30_rasterizer_stateobj {
+   struct pipe_rasterizer_state pipe;
+   unsigned data[32];
+   unsigned size;
+};
+
+struct nv30_zsa_stateobj {
+   struct pipe_depth_stencil_alpha_state pipe;
+   unsigned data[32];
+   unsigned size;
+};
+
+struct nv30_sampler_state {
+   struct pipe_sampler_state pipe;
+   unsigned fmt;
+   unsigned wrap;
+   unsigned en;
+   unsigned filt;
+   unsigned bcol;
+   /* 4.8 */
+   unsigned min_lod;
+   unsigned max_lod;
+};
+
+struct nv30_sampler_view {
+   struct pipe_sampler_view pipe;
+   unsigned fmt;
+   unsigned swz;
+   unsigned filt;
+   unsigned filt_mask;
+   unsigned wrap;
+   unsigned wrap_mask;
+   unsigned npot_size0;
+   unsigned npot_size1;
+   /* 4.8 */
+   unsigned base_lod;
+   unsigned high_lod;
+};
+
+struct nv30_shader_reloc {
+   unsigned location;
+   unsigned target;
+};
+
+struct nv30_vertprog_exec {
+   uint32_t data[4];
+};
+
+struct nv30_vertprog_data {
+   int index; /* immediates == -1 */
+   float value[4];
+};
+
+struct nv30_vertprog {
+   struct pipe_shader_state pipe;
+   struct tgsi_shader_info info;
+
+   struct draw_vertex_shader *draw;
+   boolean translated;
+   unsigned enabled_ucps;
+   uint16_t texcoord[10];
+
+   struct util_dynarray branch_relocs;
+   struct nv30_vertprog_exec *insns;
+   unsigned nr_insns;
+
+   struct util_dynarray const_relocs;
+   struct nv30_vertprog_data *consts;
+   unsigned nr_consts;
+
+   struct nouveau_heap *exec;
+   struct nouveau_heap *data;
+   uint32_t ir;
+   uint32_t or;
+   void *nvfx;
+};
+
+struct nv30_fragprog_data {
+   unsigned offset;
+   unsigned index;
+};
+
+struct nv30_fragprog {
+   struct pipe_shader_state pipe;
+   struct tgsi_shader_info info;
+
+   struct draw_fragment_shader *draw;
+   boolean translated;
+
+   uint32_t *insn;
+   unsigned insn_len;
+
+   uint16_t texcoord[10];
+   struct nv30_fragprog_data *consts;
+   unsigned nr_consts;
+
+   struct pipe_resource *buffer;
+   uint32_t vp_or; /* appended to VP_RESULT_EN */
+   uint32_t fp_control;
+   uint32_t point_sprite_control;
+   uint32_t coord_conventions;
+   uint32_t samplers;
+   uint32_t rt_enable;
+};
+
+struct nv30_vertex_element {
+   unsigned state;
+};
+
+struct nv30_vertex_stateobj {
+   struct pipe_vertex_element pipe[PIPE_MAX_ATTRIBS];
+   struct translate *translate;
+   bool need_conversion;
+   unsigned num_elements;
+   unsigned vtx_size;
+   unsigned vtx_per_packet_max;
+   struct nv30_vertex_element element[];
+};
+
+#endif
diff --git a/src/gallium/drivers/nv30/nv30_state_validate.c b/src/gallium/drivers/nv30/nv30_state_validate.c
new file mode 100644 (file)
index 0000000..df0170b
--- /dev/null
@@ -0,0 +1,535 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_half.h"
+
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_format.h"
+
+static void
+nv30_validate_fb(struct nv30_context *nv30)
+{
+   struct pipe_screen *pscreen = &nv30->screen->base.base;
+   struct pipe_framebuffer_state *fb = &nv30->framebuffer;
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nouveau_object *eng3d = nv30->screen->eng3d;
+   uint32_t rt_format;
+   int h = fb->height;
+   int w = fb->width;
+   int x = 0;
+   int y = 0;
+
+   nv30->state.rt_enable = (NV30_3D_RT_ENABLE_COLOR0 << fb->nr_cbufs) - 1;
+   if (nv30->state.rt_enable > 1)
+      nv30->state.rt_enable |= NV30_3D_RT_ENABLE_MRT;
+
+   rt_format = 0;
+   if (fb->nr_cbufs > 0) {
+      struct nv30_miptree *mt = nv30_miptree(fb->cbufs[0]->texture);
+      rt_format |= nv30_format(pscreen, fb->cbufs[0]->format)->hw;
+      rt_format |= mt->ms_mode;
+      if (mt->swizzled)
+         rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
+      else
+         rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
+   } else {
+      if (fb->zsbuf && util_format_get_blocksize(fb->zsbuf->format) > 2)
+         rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;
+      else
+         rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;
+   }
+
+   if (fb->zsbuf) {
+      rt_format |= nv30_format(pscreen, fb->zsbuf->format)->hw;
+      if (nv30_miptree(fb->zsbuf->texture)->swizzled)
+         rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
+      else
+         rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
+   } else {
+      if (fb->nr_cbufs && util_format_get_blocksize(fb->cbufs[0]->format) > 2)
+         rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
+      else
+         rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;
+   }
+
+   /* hardware rounds down render target offset to 64 bytes, but surfaces
+    * with a size of 2x2 pixel (16bpp) or 1x1 pixel (32bpp) have an
+    * unaligned start aaddress.  For these two important square formats
+    * we can hack around this limitation by adjusting the viewport origin
+    */
+   if (nv30->state.rt_enable) {
+      int off = nv30_surface(fb->cbufs[0])->offset & 63;
+      if (off) {
+         x += off / (util_format_get_blocksize(fb->cbufs[0]->format) * 2);
+         w  = 16;
+         h  = 2;
+      }
+   }
+
+   if (rt_format & NV30_3D_RT_FORMAT_TYPE_SWIZZLED) {
+      rt_format |= util_logbase2(w) << 16;
+      rt_format |= util_logbase2(h) << 24;
+   }
+
+   if (!PUSH_SPACE(push, 64))
+      return;
+   PUSH_RESET(push, BUFCTX_FB);
+
+   BEGIN_NV04(push, SUBC_3D(0x1da4), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
+   PUSH_DATA (push, w << 16);
+   PUSH_DATA (push, h << 16);
+   PUSH_DATA (push, rt_format);
+   BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2);
+   PUSH_DATA (push, w << 16);
+   PUSH_DATA (push, h << 16);
+   BEGIN_NV04(push, NV30_3D(VIEWPORT_TX_ORIGIN), 1);
+   PUSH_DATA (push, (y << 16) | x);
+
+   if ((nv30->state.rt_enable & NV30_3D_RT_ENABLE_COLOR0) || fb->zsbuf) {
+      struct nv30_surface *rsf = nv30_surface(fb->cbufs[0]);
+      struct nv30_surface *zsf = nv30_surface(fb->zsbuf);
+      struct nouveau_bo *rbo, *zbo;
+
+      if (!rsf)      rsf = zsf;
+      else if (!zsf) zsf = rsf;
+      rbo = nv30_miptree(rsf->base.texture)->base.bo;
+      zbo = nv30_miptree(zsf->base.texture)->base.bo;
+
+      if (eng3d->oclass >= NV40_3D_CLASS) {
+         BEGIN_NV04(push, NV40_3D(ZETA_PITCH), 1);
+         PUSH_DATA (push, zsf->pitch);
+         BEGIN_NV04(push, NV40_3D(COLOR0_PITCH), 3);
+         PUSH_DATA (push, rsf->pitch);
+      } else {
+         BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 3);
+         PUSH_DATA (push, (zsf->pitch << 16) | rsf->pitch);
+      }
+      PUSH_MTHDl(push, NV30_3D(COLOR0_OFFSET), BUFCTX_FB, rbo, rsf->offset & ~63,
+                       NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+      PUSH_MTHDl(push, NV30_3D(ZETA_OFFSET), BUFCTX_FB, zbo, zsf->offset & ~63,
+                       NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+   }
+
+   if (nv30->state.rt_enable & NV30_3D_RT_ENABLE_COLOR1) {
+      struct nv30_surface *sf = nv30_surface(fb->cbufs[1]);
+      struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo;
+
+      BEGIN_NV04(push, NV30_3D(COLOR1_OFFSET), 2);
+      PUSH_MTHDl(push, NV30_3D(COLOR1_OFFSET), BUFCTX_FB, bo, sf->offset,
+                       NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+      PUSH_DATA (push, sf->pitch);
+   }
+
+   if (nv30->state.rt_enable & NV40_3D_RT_ENABLE_COLOR2) {
+      struct nv30_surface *sf = nv30_surface(fb->cbufs[2]);
+      struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo;
+
+      BEGIN_NV04(push, NV40_3D(COLOR2_OFFSET), 1);
+      PUSH_MTHDl(push, NV40_3D(COLOR2_OFFSET), BUFCTX_FB, bo, sf->offset,
+                       NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+      BEGIN_NV04(push, NV40_3D(COLOR2_PITCH), 1);
+      PUSH_DATA (push, sf->pitch);
+   }
+
+   if (nv30->state.rt_enable & NV40_3D_RT_ENABLE_COLOR3) {
+      struct nv30_surface *sf = nv30_surface(fb->cbufs[3]);
+      struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo;
+
+      BEGIN_NV04(push, NV40_3D(COLOR3_OFFSET), 1);
+      PUSH_MTHDl(push, NV40_3D(COLOR3_OFFSET), BUFCTX_FB, bo, sf->offset,
+                       NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+      BEGIN_NV04(push, NV40_3D(COLOR3_PITCH), 1);
+      PUSH_DATA (push, sf->pitch);
+   }
+}
+
+static void
+nv30_validate_blend_colour(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   float *rgba = nv30->blend_colour.color;
+
+   if (nv30->framebuffer.nr_cbufs) {
+      switch (nv30->framebuffer.cbufs[0]->format) {
+      case PIPE_FORMAT_R16G16B16A16_FLOAT:
+      case PIPE_FORMAT_R32G32B32A32_FLOAT:
+         BEGIN_NV04(push, NV30_3D(BLEND_COLOR), 1);
+         PUSH_DATA (push, (util_float_to_half(rgba[0]) <<  0) |
+                          (util_float_to_half(rgba[1]) << 16));
+         BEGIN_NV04(push, SUBC_3D(0x037c), 1);
+         PUSH_DATA (push, (util_float_to_half(rgba[2]) <<  0) |
+                          (util_float_to_half(rgba[3]) << 16));
+         break;
+      default:
+         break;
+      }
+   }
+
+   BEGIN_NV04(push, NV30_3D(BLEND_COLOR), 1);
+   PUSH_DATA (push, (float_to_ubyte(rgba[3]) << 24) |
+                    (float_to_ubyte(rgba[0]) << 16) |
+                    (float_to_ubyte(rgba[1]) <<  8) |
+                    (float_to_ubyte(rgba[2]) <<  0));
+}
+
+static void
+nv30_validate_stencil_ref(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+   BEGIN_NV04(push, NV30_3D(STENCIL_FUNC_REF(0)), 1);
+   PUSH_DATA (push, nv30->stencil_ref.ref_value[0]);
+   BEGIN_NV04(push, NV30_3D(STENCIL_FUNC_REF(1)), 1);
+   PUSH_DATA (push, nv30->stencil_ref.ref_value[1]);
+}
+
+static void
+nv30_validate_stipple(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+   BEGIN_NV04(push, NV30_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
+   PUSH_DATAp(push, nv30->stipple.stipple, 32);
+}
+
+static void
+nv30_validate_scissor(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct pipe_scissor_state *s = &nv30->scissor;
+
+   if (!(nv30->dirty & NV30_NEW_SCISSOR) &&
+       nv30->rast->pipe.scissor != nv30->state.scissor_off)
+      return;
+   nv30->state.scissor_off = !nv30->rast->pipe.scissor;
+
+   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
+   if (nv30->rast->pipe.scissor) {
+      PUSH_DATA (push, ((s->maxx - s->minx) << 16) | s->minx);
+      PUSH_DATA (push, ((s->maxy - s->miny) << 16) | s->miny);
+   } else {
+      PUSH_DATA (push, 0x10000000);
+      PUSH_DATA (push, 0x10000000);
+   }
+}
+
+static void
+nv30_validate_viewport(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct pipe_viewport_state *vp = &nv30->viewport;
+
+   BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8);
+   PUSH_DATAf(push, vp->translate[0]);
+   PUSH_DATAf(push, vp->translate[1]);
+   PUSH_DATAf(push, vp->translate[2]);
+   PUSH_DATAf(push, vp->translate[3]);
+   PUSH_DATAf(push, vp->scale[0]);
+   PUSH_DATAf(push, vp->scale[1]);
+   PUSH_DATAf(push, vp->scale[2]);
+   PUSH_DATAf(push, vp->scale[3]);
+   BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2);
+   PUSH_DATAf(push, vp->translate[2] - fabsf(vp->scale[2]));
+   PUSH_DATAf(push, vp->translate[2] + fabsf(vp->scale[2]));
+}
+
+static void
+nv30_validate_clip(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   unsigned i;
+   uint32_t clpd_enable = 0;
+
+   for (i = 0; i < 6; i++) {
+      if (nv30->rast->pipe.clip_plane_enable & (1 << i)) {
+         if (nv30->dirty & NV30_NEW_CLIP) {
+            BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 5);
+            PUSH_DATA (push, i);
+            PUSH_DATAp(push, nv30->clip.ucp[i], 4);
+         }
+
+         clpd_enable |= 1 << (1 + 4*i);
+      }
+   }
+
+   BEGIN_NV04(push, NV30_3D(VP_CLIP_PLANES_ENABLE), 1);
+   PUSH_DATA (push, clpd_enable);
+}
+
+static void
+nv30_validate_blend(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+   PUSH_SPACE(push, nv30->blend->size);
+   PUSH_DATAp(push, nv30->blend->data, nv30->blend->size);
+}
+
+static void
+nv30_validate_zsa(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+   PUSH_SPACE(push, nv30->zsa->size);
+   PUSH_DATAp(push, nv30->zsa->data, nv30->zsa->size);
+}
+
+static void
+nv30_validate_rasterizer(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+   PUSH_SPACE(push, nv30->rast->size);
+   PUSH_DATAp(push, nv30->rast->data, nv30->rast->size);
+}
+
+static void
+nv30_validate_multisample(struct nv30_context *nv30)
+{
+   struct pipe_rasterizer_state *rasterizer = &nv30->rast->pipe;
+   struct pipe_blend_state *blend = &nv30->blend->pipe;
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   uint32_t ctrl = nv30->sample_mask << 16;
+
+   if (blend->alpha_to_one)
+      ctrl |= 0x00000100;
+   if (blend->alpha_to_coverage)
+      ctrl |= 0x00000010;
+   if (rasterizer->multisample)
+      ctrl |= 0x00000001;
+
+   BEGIN_NV04(push, NV30_3D(MULTISAMPLE_CONTROL), 1);
+   PUSH_DATA (push, ctrl);
+}
+
+static void
+nv30_validate_fragment(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nv30_fragprog *fp = nv30->fragprog.program;
+
+   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
+   PUSH_DATA (push, nv30->state.rt_enable & ~fp->rt_enable);
+   BEGIN_NV04(push, NV30_3D(COORD_CONVENTIONS), 1);
+   PUSH_DATA (push, fp->coord_conventions | nv30->framebuffer.height);
+}
+
+static void
+nv30_validate_point_coord(struct nv30_context *nv30)
+{
+   struct pipe_rasterizer_state *rasterizer = &nv30->rast->pipe;
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nv30_fragprog *fp = nv30->fragprog.program;
+   uint32_t hw = 0x00000000;
+
+   if (rasterizer) {
+      hw |= (nv30->rast->pipe.sprite_coord_enable & 0xff) << 8;
+      if (fp)
+         hw |= fp->point_sprite_control;
+
+      if (rasterizer->sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT) {
+         if (hw)
+            nv30->draw_flags |= NV30_NEW_RASTERIZER;
+      } else
+      if (rasterizer->point_quad_rasterization) {
+         hw |= NV30_3D_POINT_SPRITE_ENABLE;
+      }
+   }
+
+   BEGIN_NV04(push, NV30_3D(POINT_SPRITE), 1);
+   PUSH_DATA (push, hw);
+}
+
+struct state_validate {
+   void (*func)(struct nv30_context *);
+   uint32_t mask;
+};
+
+static struct state_validate hwtnl_validate_list[] = {
+    { nv30_validate_fb,            NV30_NEW_FRAMEBUFFER },
+    { nv30_validate_blend,         NV30_NEW_BLEND },
+    { nv30_validate_zsa,           NV30_NEW_ZSA },
+    { nv30_validate_rasterizer,    NV30_NEW_RASTERIZER },
+    { nv30_validate_multisample,   NV30_NEW_SAMPLE_MASK | NV30_NEW_BLEND |
+                                   NV30_NEW_RASTERIZER },
+    { nv30_validate_blend_colour,  NV30_NEW_BLEND_COLOUR |
+                                   NV30_NEW_FRAMEBUFFER },
+    { nv30_validate_stencil_ref,   NV30_NEW_STENCIL_REF },
+    { nv30_validate_stipple,       NV30_NEW_STIPPLE },
+    { nv30_validate_scissor,       NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER },
+    { nv30_validate_viewport,      NV30_NEW_VIEWPORT },
+    { nv30_validate_clip,          NV30_NEW_CLIP },
+    { nv30_fragprog_validate,      NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST },
+    { nv30_vertprog_validate,      NV30_NEW_VERTPROG | NV30_NEW_VERTCONST |
+                                   NV30_NEW_FRAGPROG | NV30_NEW_RASTERIZER },
+    { nv30_validate_fragment,      NV30_NEW_FRAMEBUFFER | NV30_NEW_FRAGPROG },
+    { nv30_validate_point_coord,   NV30_NEW_RASTERIZER | NV30_NEW_FRAGPROG },
+    { nv30_fragtex_validate,       NV30_NEW_FRAGTEX },
+    { nv40_verttex_validate,       NV30_NEW_VERTTEX },
+    { nv30_vbo_validate,           NV30_NEW_VERTEX | NV30_NEW_ARRAYS },
+    {}
+};
+
+#define NV30_SWTNL_MASK (NV30_NEW_VIEWPORT |  \
+                         NV30_NEW_CLIP |      \
+                         NV30_NEW_VERTPROG |  \
+                         NV30_NEW_VERTCONST | \
+                         NV30_NEW_VERTTEX |   \
+                         NV30_NEW_VERTEX |    \
+                         NV30_NEW_ARRAYS)
+
+static struct state_validate swtnl_validate_list[] = {
+    { nv30_validate_fb,            NV30_NEW_FRAMEBUFFER },
+    { nv30_validate_blend,         NV30_NEW_BLEND },
+    { nv30_validate_zsa,           NV30_NEW_ZSA },
+    { nv30_validate_rasterizer,    NV30_NEW_RASTERIZER },
+    { nv30_validate_multisample,   NV30_NEW_SAMPLE_MASK | NV30_NEW_BLEND |
+                                   NV30_NEW_RASTERIZER },
+    { nv30_validate_blend_colour,  NV30_NEW_BLEND_COLOUR |
+                                   NV30_NEW_FRAMEBUFFER },
+    { nv30_validate_stencil_ref,   NV30_NEW_STENCIL_REF },
+    { nv30_validate_stipple,       NV30_NEW_STIPPLE },
+    { nv30_validate_scissor,       NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER },
+    { nv30_fragprog_validate,      NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST },
+    { nv30_validate_fragment,      NV30_NEW_FRAMEBUFFER | NV30_NEW_FRAGPROG },
+    { nv30_fragtex_validate,       NV30_NEW_FRAGTEX },
+    {}
+};
+
+static void
+nv30_state_context_switch(struct nv30_context *nv30)
+{
+   struct nv30_context *prev = nv30->screen->cur_ctx;
+
+   if (prev)
+      nv30->state = prev->state;
+   nv30->dirty = NV30_NEW_ALL;
+
+   if (!nv30->vertex)
+      nv30->dirty &= ~(NV30_NEW_VERTEX | NV30_NEW_ARRAYS);
+
+   if (!nv30->vertprog.program)
+      nv30->dirty &= ~NV30_NEW_VERTPROG;
+   if (!nv30->fragprog.program)
+      nv30->dirty &= ~NV30_NEW_FRAGPROG;
+
+   if (!nv30->blend)
+      nv30->dirty &= ~NV30_NEW_BLEND;
+   if (!nv30->rast)
+      nv30->dirty &= ~NV30_NEW_RASTERIZER;
+   if (!nv30->zsa)
+      nv30->dirty &= ~NV30_NEW_ZSA;
+
+   nv30->screen->cur_ctx = nv30;
+   nv30->base.pushbuf->user_priv = &nv30->bufctx;
+}
+
+boolean
+nv30_state_validate(struct nv30_context *nv30, boolean hwtnl)
+{
+   struct nouveau_screen *screen = &nv30->screen->base;
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nouveau_bufctx *bctx = nv30->bufctx;
+   struct nouveau_bufref *bref;
+   struct state_validate *validate;
+
+   if (nv30->screen->cur_ctx != nv30)
+      nv30_state_context_switch(nv30);
+
+   if (hwtnl) {
+      nv30->draw_dirty |= nv30->dirty;
+      if (nv30->draw_flags) {
+         nv30->draw_flags &= ~nv30->dirty;
+         if (!nv30->draw_flags)
+            nv30->dirty |= NV30_SWTNL_MASK;
+      }
+   }
+
+   if (!nv30->draw_flags)
+      validate = hwtnl_validate_list;
+   else
+      validate = swtnl_validate_list;
+
+   if (nv30->dirty) {
+      while (validate->func) {
+         if (nv30->dirty & validate->mask)
+            validate->func(nv30);
+         validate++;
+      }
+
+      nv30->dirty = 0;
+   }
+
+   nouveau_pushbuf_bufctx(push, bctx);
+   if (nouveau_pushbuf_validate(push)) {
+      nouveau_pushbuf_bufctx(push, NULL);
+      return FALSE;
+   }
+
+   /*XXX*/
+   BEGIN_NV04(push, NV30_3D(VTX_CACHE_INVALIDATE_1710), 1);
+   PUSH_DATA (push, 0);
+   if (nv30->screen->eng3d->oclass >= NV40_3D_CLASS) {
+      BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
+      PUSH_DATA (push, 2);
+      BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
+      PUSH_DATA (push, 1);
+      BEGIN_NV04(push, NV30_3D(R1718), 1);
+      PUSH_DATA (push, 0);
+      BEGIN_NV04(push, NV30_3D(R1718), 1);
+      PUSH_DATA (push, 0);
+      BEGIN_NV04(push, NV30_3D(R1718), 1);
+      PUSH_DATA (push, 0);
+   }
+
+   LIST_FOR_EACH_ENTRY(bref, &bctx->current, thead) {
+      struct nv04_resource *res = bref->priv;
+      if (res && res->mm) {
+         nouveau_fence_ref(screen->fence.current, &res->fence);
+
+         if (bref->flags & NOUVEAU_BO_RD)
+            res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
+
+         if (bref->flags & NOUVEAU_BO_WR) {
+            nouveau_fence_ref(screen->fence.current, &res->fence_wr);
+            res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
+         }
+      }
+   }
+
+   return TRUE;
+}
+
+void
+nv30_state_release(struct nv30_context *nv30)
+{
+   nouveau_pushbuf_bufctx(nv30->base.pushbuf, NULL);
+}
diff --git a/src/gallium/drivers/nv30/nv30_texture.c b/src/gallium/drivers/nv30/nv30_texture.c
new file mode 100644 (file)
index 0000000..fb9ee07
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_format.h"
+
+#define NV30_3D_TEX_WRAP_S_MIRROR_REPEAT NV30_3D_TEX_WRAP_S_MIRRORED_REPEAT
+#define NV30_WRAP(n) \
+   case PIPE_TEX_WRAP_##n: ret = NV30_3D_TEX_WRAP_S_##n; break
+#define NV40_WRAP(n) \
+   case PIPE_TEX_WRAP_##n: ret = NV40_3D_TEX_WRAP_S_##n; break
+
+static INLINE unsigned
+wrap_mode(unsigned pipe)
+{
+   unsigned ret = NV30_3D_TEX_WRAP_S_REPEAT;
+
+   switch (pipe) {
+   NV30_WRAP(REPEAT);
+   NV30_WRAP(MIRROR_REPEAT);
+   NV30_WRAP(CLAMP_TO_EDGE);
+   NV30_WRAP(CLAMP_TO_BORDER);
+   NV30_WRAP(CLAMP);
+   NV40_WRAP(MIRROR_CLAMP_TO_EDGE);
+   NV40_WRAP(MIRROR_CLAMP_TO_BORDER);
+   NV40_WRAP(MIRROR_CLAMP);
+   default:
+      break;
+   }
+
+   return ret >> NV30_3D_TEX_WRAP_S__SHIFT;
+}
+
+static INLINE unsigned
+filter_mode(const struct pipe_sampler_state *cso)
+{
+   unsigned filter;
+
+   switch (cso->mag_img_filter) {
+   case PIPE_TEX_FILTER_LINEAR:
+      filter = NV30_3D_TEX_FILTER_MAG_LINEAR;
+      break;
+   default:
+      filter = NV30_3D_TEX_FILTER_MAG_NEAREST;
+      break;
+   }
+
+   switch (cso->min_img_filter) {
+   case PIPE_TEX_FILTER_LINEAR:
+      switch (cso->min_mip_filter) {
+      case PIPE_TEX_MIPFILTER_NEAREST:
+         filter |= NV30_3D_TEX_FILTER_MIN_LINEAR_MIPMAP_NEAREST;
+         break;
+      case PIPE_TEX_MIPFILTER_LINEAR:
+         filter |= NV30_3D_TEX_FILTER_MIN_LINEAR_MIPMAP_LINEAR;
+         break;
+      default:
+         filter |= NV30_3D_TEX_FILTER_MIN_LINEAR;
+         break;
+      }
+      break;
+   default:
+      switch (cso->min_mip_filter) {
+      case PIPE_TEX_MIPFILTER_NEAREST:
+         filter |= NV30_3D_TEX_FILTER_MIN_NEAREST_MIPMAP_NEAREST;
+         break;
+      case PIPE_TEX_MIPFILTER_LINEAR:
+         filter |= NV30_3D_TEX_FILTER_MIN_NEAREST_MIPMAP_LINEAR;
+         break;
+      default:
+         filter |= NV30_3D_TEX_FILTER_MIN_NEAREST;
+         break;
+      }
+      break;
+   }
+
+   return filter;
+}
+
+static INLINE unsigned
+compare_mode(const struct pipe_sampler_state *cso)
+{
+   if (cso->compare_mode != PIPE_TEX_COMPARE_R_TO_TEXTURE)
+      return 0;
+
+   switch (cso->compare_func) {
+   case PIPE_FUNC_NEVER   : return NV30_3D_TEX_WRAP_RCOMP_NEVER;
+   case PIPE_FUNC_GREATER : return NV30_3D_TEX_WRAP_RCOMP_GREATER;
+   case PIPE_FUNC_EQUAL   : return NV30_3D_TEX_WRAP_RCOMP_EQUAL;
+   case PIPE_FUNC_GEQUAL  : return NV30_3D_TEX_WRAP_RCOMP_GEQUAL;
+   case PIPE_FUNC_LESS    : return NV30_3D_TEX_WRAP_RCOMP_LESS;
+   case PIPE_FUNC_NOTEQUAL: return NV30_3D_TEX_WRAP_RCOMP_NOTEQUAL;
+   case PIPE_FUNC_LEQUAL  : return NV30_3D_TEX_WRAP_RCOMP_LEQUAL;
+   case PIPE_FUNC_ALWAYS  : return NV30_3D_TEX_WRAP_RCOMP_ALWAYS;
+   default:
+      return 0;
+   }
+}
+
+static void *
+nv30_sampler_state_create(struct pipe_context *pipe,
+                          const struct pipe_sampler_state *cso)
+{
+   struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d;
+   struct nv30_sampler_state *so;
+   const float max_lod = 15.0 + (255.0 / 256.0);
+
+   so = MALLOC_STRUCT(nv30_sampler_state);
+   if (!so)
+      return NULL;
+
+   so->pipe  = *cso;
+   so->fmt   = 0;
+   so->wrap  = (wrap_mode(cso->wrap_s) << NV30_3D_TEX_WRAP_S__SHIFT) |
+               (wrap_mode(cso->wrap_t) << NV30_3D_TEX_WRAP_T__SHIFT) |
+               (wrap_mode(cso->wrap_r) << NV30_3D_TEX_WRAP_R__SHIFT);
+   so->en    = 0;
+   so->wrap |= compare_mode(cso);
+   so->filt  = filter_mode(cso) | 0x00002000;
+   so->bcol  = (float_to_ubyte(cso->border_color.f[3]) << 24) |
+               (float_to_ubyte(cso->border_color.f[0]) << 16) |
+               (float_to_ubyte(cso->border_color.f[1]) <<  8) |
+               (float_to_ubyte(cso->border_color.f[2]) <<  0);
+
+   if (eng3d->oclass >= NV40_3D_CLASS) {
+      unsigned aniso = cso->max_anisotropy;
+
+      if (!cso->normalized_coords)
+         so->fmt |= NV40_3D_TEX_FORMAT_RECT;
+
+      if (aniso > 1) {
+         if      (aniso >= 16) so->en |= NV40_3D_TEX_ENABLE_ANISO_16X;
+         else if (aniso >= 12) so->en |= NV40_3D_TEX_ENABLE_ANISO_12X;
+         else if (aniso >= 10) so->en |= NV40_3D_TEX_ENABLE_ANISO_10X;
+         else if (aniso >=  8) so->en |= NV40_3D_TEX_ENABLE_ANISO_8X;
+         else if (aniso >=  6) so->en |= NV40_3D_TEX_ENABLE_ANISO_6X;
+         else if (aniso >=  4) so->en |= NV40_3D_TEX_ENABLE_ANISO_4X;
+         else                  so->en |= NV40_3D_TEX_ENABLE_ANISO_2X;
+
+         so->wrap |= nv30_context(pipe)->config.aniso;
+      }
+   } else {
+      so->en |= NV30_3D_TEX_ENABLE_ENABLE;
+
+      if      (cso->max_anisotropy >= 8) so->en |= NV30_3D_TEX_ENABLE_ANISO_8X;
+      else if (cso->max_anisotropy >= 4) so->en |= NV30_3D_TEX_ENABLE_ANISO_4X;
+      else if (cso->max_anisotropy >= 2) so->en |= NV30_3D_TEX_ENABLE_ANISO_2X;
+   }
+
+   so->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
+   so->max_lod = (int)(CLAMP(cso->max_lod, 0.0, max_lod) * 256.0);
+   so->min_lod = (int)(CLAMP(cso->min_lod, 0.0, max_lod) * 256.0);
+   return so;
+}
+
+static void
+nv30_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+   FREE(hwcso);
+}
+
+static INLINE uint32_t
+swizzle(const struct nv30_texfmt *fmt, unsigned cmp, unsigned swz)
+{
+   uint32_t data = fmt->swz[swz].src << 8;
+   if (swz <= PIPE_SWIZZLE_ALPHA)
+      data |= fmt->swz[swz].cmp;
+   else
+      data |= fmt->swz[cmp].cmp;
+   return data;
+}
+
+static struct pipe_sampler_view *
+nv30_sampler_view_create(struct pipe_context *pipe, struct pipe_resource *pt,
+                         const struct pipe_sampler_view *tmpl)
+{
+   const struct nv30_texfmt *fmt = nv30_texfmt(pipe->screen, tmpl->format);
+   struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d;
+   struct nv30_miptree *mt = nv30_miptree(pt);
+   struct nv30_sampler_view *so;
+
+   so = MALLOC_STRUCT(nv30_sampler_view);
+   if (!so)
+      return NULL;
+   so->pipe = *tmpl;
+   so->pipe.reference.count = 1;
+   so->pipe.texture = NULL;
+   so->pipe.context = pipe;
+   pipe_resource_reference(&so->pipe.texture, pt);
+
+   so->fmt = NV30_3D_TEX_FORMAT_NO_BORDER;
+   switch (pt->target) {
+   case PIPE_TEXTURE_1D:
+      so->fmt |= NV30_3D_TEX_FORMAT_DIMS_1D;
+      break;
+   case PIPE_TEXTURE_CUBE:
+      so->fmt |= NV30_3D_TEX_FORMAT_CUBIC;
+   case PIPE_TEXTURE_2D:
+   case PIPE_TEXTURE_RECT:
+      so->fmt |= NV30_3D_TEX_FORMAT_DIMS_2D;
+      break;
+   case PIPE_TEXTURE_3D:
+      so->fmt |= NV30_3D_TEX_FORMAT_DIMS_3D;
+      break;
+   default:
+      assert(0);
+      so->fmt |= NV30_3D_TEX_FORMAT_DIMS_1D;
+      break;
+   }
+
+   so->filt = fmt->filter;
+   so->wrap = fmt->wrap;
+   so->swz  = fmt->swizzle;
+   so->swz |= swizzle(fmt, 3, tmpl->swizzle_a);
+   so->swz |= swizzle(fmt, 0, tmpl->swizzle_r) << 2;
+   so->swz |= swizzle(fmt, 1, tmpl->swizzle_g) << 4;
+   so->swz |= swizzle(fmt, 2, tmpl->swizzle_b) << 6;
+
+   /* apparently, we need to ignore the t coordinate for 1D textures to
+    * fix piglit tex1d-2dborder
+    */
+   so->wrap_mask = ~0;
+   if (pt->target == PIPE_TEXTURE_1D) {
+      so->wrap_mask &= ~NV30_3D_TEX_WRAP_T__MASK;
+      so->wrap      |=  NV30_3D_TEX_WRAP_T_REPEAT;
+   }
+
+   /* yet more hardware suckage, can't filter 32-bit float formats */
+   switch (tmpl->format) {
+   case PIPE_FORMAT_R32_FLOAT:
+   case PIPE_FORMAT_R32G32B32A32_FLOAT:
+      so->filt_mask = ~(NV30_3D_TEX_FILTER_MIN__MASK |
+                        NV30_3D_TEX_FILTER_MAG__MASK);
+      so->filt     |= NV30_3D_TEX_FILTER_MIN_NEAREST |
+                      NV30_3D_TEX_FILTER_MAG_NEAREST;
+      break;
+   default:
+      so->filt_mask = ~0;
+      break;
+   }
+
+   so->npot_size0 = (pt->width0 << 16) | pt->height0;
+   if (eng3d->oclass >= NV40_3D_CLASS) {
+      so->npot_size1 = (pt->depth0 << 20) | mt->uniform_pitch;
+      if (!mt->swizzled)
+         so->fmt |= NV40_3D_TEX_FORMAT_LINEAR;
+      so->fmt |= 0x00008000;
+      so->fmt |= (pt->last_level + 1) << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT;
+   } else {
+      so->swz |= mt->uniform_pitch << NV30_3D_TEX_SWIZZLE_RECT_PITCH__SHIFT;
+      if (pt->last_level)
+         so->fmt |= NV30_3D_TEX_FORMAT_MIPMAP;
+      so->fmt |= util_logbase2(pt->width0)  << 20;
+      so->fmt |= util_logbase2(pt->height0) << 24;
+      so->fmt |= util_logbase2(pt->depth0)  << 28;
+      so->fmt |= 0x00010000;
+   }
+
+   so->base_lod = so->pipe.u.tex.first_level << 8;
+   so->high_lod = MIN2(pt->last_level, so->pipe.u.tex.last_level) << 8;
+   return &so->pipe;
+}
+
+static void
+nv30_sampler_view_destroy(struct pipe_context *pipe,
+                          struct pipe_sampler_view *view)
+{
+   pipe_resource_reference(&view->texture, NULL);
+   FREE(view);
+}
+
+void
+nv30_texture_init(struct pipe_context *pipe)
+{
+   pipe->create_sampler_state = nv30_sampler_state_create;
+   pipe->delete_sampler_state = nv30_sampler_state_delete;
+   pipe->create_sampler_view = nv30_sampler_view_create;
+   pipe->sampler_view_destroy = nv30_sampler_view_destroy;
+}
diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c
new file mode 100644 (file)
index 0000000..8e70883
--- /dev/null
@@ -0,0 +1,755 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#define XFER_ARGS                                                              \
+   struct nv30_context *nv30, enum nv30_transfer_filter filter,                \
+   struct nv30_rect *src, struct nv30_rect *dst
+
+#include "util/u_math.h"
+
+#include "nouveau/nv_object.xml.h"
+#include "nouveau/nv_m2mf.xml.h"
+#include "nv01_2d.xml.h"
+#include "nv30-40_3d.xml.h"
+
+#include "nv30_context.h"
+#include "nv30_transfer.h"
+
+/* Various helper functions to transfer different types of data in a number
+ * of different ways.
+ */
+
+static INLINE boolean
+nv30_transfer_scaled(struct nv30_rect *src, struct nv30_rect *dst)
+{
+   if (src->x1 - src->x0 != dst->x1 - dst->x0)
+      return TRUE;
+   if (src->y1 - src->y0 != dst->y1 - dst->y0)
+      return TRUE;
+   return FALSE;
+}
+
+static INLINE boolean
+nv30_transfer_blit(XFER_ARGS)
+{
+   if (nv30->screen->eng3d->oclass < NV40_3D_CLASS)
+      return FALSE;
+   if (dst->offset & 63 || dst->pitch & 63 || dst->d > 1)
+      return FALSE;
+   if (dst->w < 2 || dst->h < 2)
+      return FALSE;
+   if (dst->cpp > 4 || (dst->cpp == 1 && !dst->pitch))
+      return FALSE;
+   if (src->cpp > 4)
+      return FALSE;
+   return TRUE;
+}
+
+static INLINE struct nouveau_heap *
+nv30_transfer_rect_vertprog(struct nv30_context *nv30)
+{
+   struct nouveau_heap *heap = nv30->screen->vp_exec_heap;
+   struct nouveau_heap *vp;
+
+   vp = nv30->blit_vp;
+   if (!vp) {
+      if (nouveau_heap_alloc(heap, 2, &nv30->blit_vp, &nv30->blit_vp)) {
+         while (heap->next && heap->size < 2) {
+            struct nouveau_heap **evict = heap->next->priv;
+            nouveau_heap_free(evict);
+         }
+
+         if (nouveau_heap_alloc(heap, 2, &nv30->blit_vp, &nv30->blit_vp))
+            return NULL;
+      }
+
+      vp = nv30->blit_vp;
+      if (vp) {
+         struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_FROM_ID), 1);
+         PUSH_DATA (push, vp->start);
+         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_INST(0)), 4);
+         PUSH_DATA (push, 0x401f9c6c); /* mov o[hpos], a[0]; */
+         PUSH_DATA (push, 0x0040000d);
+         PUSH_DATA (push, 0x8106c083);
+         PUSH_DATA (push, 0x6041ff80);
+         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_INST(0)), 4);
+         PUSH_DATA (push, 0x401f9c6c); /* mov o[tex0], a[8]; end; */
+         PUSH_DATA (push, 0x0040080d);
+         PUSH_DATA (push, 0x8106c083);
+         PUSH_DATA (push, 0x6041ff9d);
+      }
+   }
+
+   return vp;
+}
+
+
+static INLINE struct nv04_resource *
+nv30_transfer_rect_fragprog(struct nv30_context *nv30)
+{
+   struct nv04_resource *fp = nv04_resource(nv30->blit_fp);
+   struct pipe_context *pipe = &nv30->base.pipe;
+
+   if (!fp) {
+      nv30->blit_fp = pipe_buffer_create(pipe->screen, 0, 0, 12 * 4);
+      if (nv30->blit_fp) {
+         struct pipe_transfer *transfer;
+         u32 *map = pipe_buffer_map(pipe, nv30->blit_fp,
+                                    PIPE_TRANSFER_WRITE, &transfer);
+         if (map) {
+            map[0] = 0x17009e00; /* texr r0, i[tex0], texture[0]; end; */
+            map[1] = 0x1c9dc801;
+            map[2] = 0x0001c800;
+            map[3] = 0x3fe1c800;
+            map[4] = 0x01401e81; /* end; */
+            map[5] = 0x1c9dc800;
+            map[6] = 0x0001c800;
+            map[7] = 0x0001c800;
+            pipe_buffer_unmap(pipe, transfer);
+         }
+
+         fp = nv04_resource(nv30->blit_fp);
+         nouveau_buffer_migrate(&nv30->base, fp, NOUVEAU_BO_VRAM);
+      }
+   }
+
+   return fp;
+}
+
+static void
+nv30_transfer_rect_blit(XFER_ARGS)
+{
+   struct nv04_resource *fp = nv30_transfer_rect_fragprog(nv30);
+   struct nouveau_heap *vp = nv30_transfer_rect_vertprog(nv30);
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nouveau_pushbuf_refn refs[] = {
+      { fp->bo, fp->domain | NOUVEAU_BO_RD },
+      { src->bo, src->domain | NOUVEAU_BO_RD },
+      { dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR },
+   };
+   u32 texfmt, texswz;
+   u32 format, stride;
+
+   if (nouveau_pushbuf_space(push, 512, 8, 0) ||
+       nouveau_pushbuf_refn (push, refs, sizeof(refs) / sizeof(refs[0])))
+      return;
+
+   /* various switches depending on cpp of the transfer */
+   switch (dst->cpp) {
+   case 4:
+      format = NV30_3D_RT_FORMAT_COLOR_A8R8G8B8 |
+               NV30_3D_RT_FORMAT_ZETA_Z24S8;
+      texfmt = NV40_3D_TEX_FORMAT_FORMAT_A8R8G8B8;
+      texswz = 0x0000aae4;
+      break;
+   case 2:
+      format = NV30_3D_RT_FORMAT_COLOR_R5G6B5 |
+               NV30_3D_RT_FORMAT_ZETA_Z16;
+      texfmt = NV40_3D_TEX_FORMAT_FORMAT_R5G6B5;
+      texswz = 0x0000a9e4;
+      break;
+   case 1:
+      format = NV30_3D_RT_FORMAT_COLOR_B8 |
+               NV30_3D_RT_FORMAT_ZETA_Z16;
+      texfmt = NV40_3D_TEX_FORMAT_FORMAT_L8;
+      texswz = 0x0000aaff;
+      break;
+   default:
+      assert(0);
+      return;
+   }
+
+   /* render target */
+   if (!dst->pitch) {
+      format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
+      format |= util_logbase2(dst->w) << 16;
+      format |= util_logbase2(dst->h) << 24;
+      stride  = 64;
+   } else {
+      format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
+      stride  = dst->pitch;
+   }
+
+   BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2);
+   PUSH_DATA (push, dst->w << 16);
+   PUSH_DATA (push, dst->h << 16);
+   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 5);
+   PUSH_DATA (push, dst->w << 16);
+   PUSH_DATA (push, dst->h << 16);
+   PUSH_DATA (push, format);
+   PUSH_DATA (push, stride);
+   PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
+   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
+   PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);
+
+   nv30->dirty |= NV30_NEW_FRAMEBUFFER;
+
+   /* viewport state */
+   BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8);
+   PUSH_DATAf(push, 0.0);
+   PUSH_DATAf(push, 0.0);
+   PUSH_DATAf(push, 0.0);
+   PUSH_DATAf(push, 0.0);
+   PUSH_DATAf(push, 1.0);
+   PUSH_DATAf(push, 1.0);
+   PUSH_DATAf(push, 1.0);
+   PUSH_DATAf(push, 1.0);
+   BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2);
+   PUSH_DATAf(push, 0.0);
+   PUSH_DATAf(push, 1.0);
+
+   nv30->dirty |= NV30_NEW_VIEWPORT;
+
+   /* blend state */
+   BEGIN_NV04(push, NV30_3D(COLOR_LOGIC_OP_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV30_3D(DITHER_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV30_3D(COLOR_MASK), 1);
+   PUSH_DATA (push, 0x01010101);
+
+   nv30->dirty |= NV30_NEW_BLEND;
+
+   /* depth-stencil-alpha state */
+   BEGIN_NV04(push, NV30_3D(DEPTH_WRITE_ENABLE), 2);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(0)), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(1)), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV30_3D(ALPHA_FUNC_ENABLE), 1);
+   PUSH_DATA (push, 0);
+
+   nv30->dirty |= NV30_NEW_ZSA;
+
+   /* rasterizer state */
+   BEGIN_NV04(push, NV30_3D(SHADE_MODEL), 1);
+   PUSH_DATA (push, NV30_3D_SHADE_MODEL_FLAT);
+   BEGIN_NV04(push, NV30_3D(CULL_FACE_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV30_3D(POLYGON_MODE_FRONT), 2);
+   PUSH_DATA (push, NV30_3D_POLYGON_MODE_FRONT_FILL);
+   PUSH_DATA (push, NV30_3D_POLYGON_MODE_BACK_FILL);
+   BEGIN_NV04(push, NV30_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV30_3D(POLYGON_STIPPLE_ENABLE), 1);
+   PUSH_DATA (push, 0);
+
+   nv30->state.scissor_off = 0;
+   nv30->dirty |= NV30_NEW_RASTERIZER;
+
+   /* vertex program */
+   BEGIN_NV04(push, NV30_3D(VP_START_FROM_ID), 1);
+   PUSH_DATA (push, vp->start);
+   BEGIN_NV04(push, NV40_3D(VP_ATTRIB_EN), 2);
+   PUSH_DATA (push, 0x00000101); /* attrib: 0, 8 */
+   PUSH_DATA (push, 0x00004000); /* result: hpos, tex0 */
+   BEGIN_NV04(push, NV30_3D(ENGINE), 1);
+   PUSH_DATA (push, 0x00000103);
+   BEGIN_NV04(push, NV30_3D(VP_CLIP_PLANES_ENABLE), 1);
+   PUSH_DATA (push, 0x00000000);
+
+   nv30->dirty |= NV30_NEW_VERTPROG;
+   nv30->dirty |= NV30_NEW_CLIP;
+
+   /* fragment program */
+   BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1);
+   PUSH_RELOC(push, fp->bo, fp->offset, fp->domain |
+                    NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
+                    NV30_3D_FP_ACTIVE_PROGRAM_DMA0,
+                    NV30_3D_FP_ACTIVE_PROGRAM_DMA1);
+   BEGIN_NV04(push, NV30_3D(FP_CONTROL), 1);
+   PUSH_DATA (push, 0x02000000);
+
+   nv30->state.fragprog = NULL;
+   nv30->dirty |= NV30_NEW_FRAGPROG;
+
+   /* texture */
+   texfmt |= 1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT;
+   texfmt |= NV30_3D_TEX_FORMAT_NO_BORDER;
+   texfmt |= NV40_3D_TEX_FORMAT_RECT;
+   texfmt |= 0x00008000;
+   if (src->d < 2)
+      texfmt |= NV30_3D_TEX_FORMAT_DIMS_2D;
+   else
+      texfmt |= NV30_3D_TEX_FORMAT_DIMS_3D;
+   if (src->pitch)
+      texfmt |= NV40_3D_TEX_FORMAT_LINEAR;
+
+   BEGIN_NV04(push, NV30_3D(TEX_OFFSET(0)), 8);
+   PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0);
+   PUSH_RELOC(push, src->bo, texfmt, NOUVEAU_BO_OR,
+                    NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1);
+   PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP_TO_EDGE |
+                    NV30_3D_TEX_WRAP_T_CLAMP_TO_EDGE |
+                    NV30_3D_TEX_WRAP_R_CLAMP_TO_EDGE);
+   PUSH_DATA (push, NV40_3D_TEX_ENABLE_ENABLE);
+   PUSH_DATA (push, texswz);
+   switch (filter) {
+   case BILINEAR:
+      PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_LINEAR |
+                       NV30_3D_TEX_FILTER_MAG_LINEAR | 0x00002000);
+      break;
+   default:
+      PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_NEAREST |
+                       NV30_3D_TEX_FILTER_MAG_NEAREST | 0x00002000);
+      break;
+   }
+   PUSH_DATA (push, (src->w << 16) | src->h);
+   PUSH_DATA (push, 0x00000000);
+   BEGIN_NV04(push, NV40_3D(TEX_SIZE1(0)), 1);
+   PUSH_DATA (push, 0x00100000 | src->pitch);
+   BEGIN_NV04(push, SUBC_3D(0x0b40), 1);
+   PUSH_DATA (push, src->d < 2 ? 0x00000001 : 0x00000000);
+   BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
+   PUSH_DATA (push, 1);
+
+   nv30->fragprog.dirty_samplers |= 1;
+   nv30->dirty |= NV30_NEW_FRAGTEX;
+
+   /* blit! */
+   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
+   PUSH_DATA (push, (dst->x1 - dst->x0) << 16 | dst->x0);
+   PUSH_DATA (push, (dst->y1 - dst->y0) << 16 | dst->y0);
+   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_QUADS);
+   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
+   PUSH_DATAf(push, src->x0);
+   PUSH_DATAf(push, src->y0);
+   PUSH_DATAf(push, src->z);
+   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
+   PUSH_DATA (push, (dst->y0 << 16) | dst->x0);
+   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
+   PUSH_DATAf(push, src->x1);
+   PUSH_DATAf(push, src->y0);
+   PUSH_DATAf(push, src->z);
+   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
+   PUSH_DATA (push, (dst->y0 << 16) | dst->x1);
+   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
+   PUSH_DATAf(push, src->x1);
+   PUSH_DATAf(push, src->y1);
+   PUSH_DATAf(push, src->z);
+   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
+   PUSH_DATA (push, (dst->y1 << 16) | dst->x1);
+   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
+   PUSH_DATAf(push, src->x0);
+   PUSH_DATAf(push, src->y1);
+   PUSH_DATAf(push, src->z);
+   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
+   PUSH_DATA (push, (dst->y1 << 16) | dst->x0);
+   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
+}
+
+static boolean
+nv30_transfer_sifm(XFER_ARGS)
+{
+   if (!src->pitch || (src->w | src->h) > 1024 || src->w < 2 || src->h < 2)
+      return FALSE;
+
+   if (src->d > 1 || dst->d > 1)
+      return FALSE;
+
+   if (dst->offset & 63)
+      return FALSE;
+
+   if (!dst->pitch) {
+      if ((dst->w | dst->h) > 2048 || dst->w < 2 || dst->h < 2)
+         return FALSE;
+   } else {
+      if (dst->domain != NOUVEAU_BO_VRAM)
+         return FALSE;
+      if (dst->pitch & 63)
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+static void
+nv30_transfer_rect_sifm(XFER_ARGS)
+
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nouveau_pushbuf_refn refs[] = {
+      { src->bo, src->domain | NOUVEAU_BO_RD },
+      { dst->bo, dst->domain | NOUVEAU_BO_WR },
+   };
+   struct nv04_fifo *fifo = push->channel->data;
+   unsigned si_fmt, si_arg;
+   unsigned ss_fmt;
+
+   switch (dst->cpp) {
+   case 4: ss_fmt = NV04_SURFACE_SWZ_FORMAT_COLOR_A8R8G8B8; break;
+   case 2: ss_fmt = NV04_SURFACE_SWZ_FORMAT_COLOR_R5G6B5; break;
+   default:
+      ss_fmt = NV04_SURFACE_SWZ_FORMAT_COLOR_Y8;
+      break;
+   }
+
+   switch (src->cpp) {
+   case 4: si_fmt = NV03_SIFM_COLOR_FORMAT_A8R8G8B8; break;
+   case 2: si_fmt = NV03_SIFM_COLOR_FORMAT_R5G6B5; break;
+   default:
+      si_fmt = NV03_SIFM_COLOR_FORMAT_AY8;
+      break;
+   }
+
+   if (filter == NEAREST) {
+      si_arg  = NV03_SIFM_FORMAT_ORIGIN_CENTER;
+      si_arg |= NV03_SIFM_FORMAT_FILTER_POINT_SAMPLE;
+   } else {
+      si_arg  = NV03_SIFM_FORMAT_ORIGIN_CORNER;
+      si_arg |= NV03_SIFM_FORMAT_FILTER_BILINEAR;
+   }
+
+   if (nouveau_pushbuf_space(push, 32, 6, 0) ||
+       nouveau_pushbuf_refn (push, refs, 2))
+      return;
+
+   if (dst->pitch) {
+      BEGIN_NV04(push, NV04_SF2D(DMA_IMAGE_SOURCE), 2);
+      PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
+      PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
+      BEGIN_NV04(push, NV04_SF2D(FORMAT), 4);
+      PUSH_DATA (push, ss_fmt);
+      PUSH_DATA (push, dst->pitch << 16 | dst->pitch);
+      PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
+      PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
+      BEGIN_NV04(push, NV05_SIFM(SURFACE), 1);
+      PUSH_DATA (push, nv30->screen->surf2d->handle);
+   } else {
+      BEGIN_NV04(push, NV04_SSWZ(DMA_IMAGE), 1);
+      PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
+      BEGIN_NV04(push, NV04_SSWZ(FORMAT), 2);
+      PUSH_DATA (push, ss_fmt | (util_logbase2(dst->w) << 16) |
+                                (util_logbase2(dst->h) << 24));
+      PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
+      BEGIN_NV04(push, NV05_SIFM(SURFACE), 1);
+      PUSH_DATA (push, nv30->screen->swzsurf->handle);
+   }
+
+   BEGIN_NV04(push, NV03_SIFM(DMA_IMAGE), 1);
+   PUSH_RELOC(push, src->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
+   BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 8);
+   PUSH_DATA (push, si_fmt);
+   PUSH_DATA (push, NV03_SIFM_OPERATION_SRCCOPY);
+   PUSH_DATA (push, (           dst->y0  << 16) |            dst->x0);
+   PUSH_DATA (push, ((dst->y1 - dst->y0) << 16) | (dst->x1 - dst->x0));
+   PUSH_DATA (push, (           dst->y0  << 16) |            dst->x0);
+   PUSH_DATA (push, ((dst->y1 - dst->y0) << 16) | (dst->x1 - dst->x0));
+   PUSH_DATA (push, ((src->x1 - src->x0) << 20) / (dst->x1 - dst->x0));
+   PUSH_DATA (push, ((src->y1 - src->y0) << 20) / (dst->y1 - dst->y0));
+   BEGIN_NV04(push, NV03_SIFM(SIZE), 4);
+   PUSH_DATA (push, align((src->y1 - src->y0), 2) << 16 |
+                    align((src->x1 - src->x0), 2));
+   PUSH_DATA (push, src->pitch | si_arg);
+   PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0);
+   PUSH_DATA (push, (src->y0 << 16) | src->x0);
+}
+
+/* The NOP+OFFSET_OUT stuff after each M2MF transfer *is* actually required
+ * to prevent some odd things from happening, easily reproducible by
+ * attempting to do conditional rendering that has a M2MF transfer done
+ * some time before it.  0x1e98 will fail with a DMA_W_PROTECTION (assuming
+ * that name is still accurate on nv4x) error.
+ */
+
+static boolean
+nv30_transfer_m2mf(XFER_ARGS)
+{
+   if (!src->pitch || !dst->pitch)
+      return FALSE;
+   if (nv30_transfer_scaled(src, dst))
+      return FALSE;
+   return TRUE;
+}
+
+static void
+nv30_transfer_rect_m2mf(XFER_ARGS)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nouveau_pushbuf_refn refs[] = {
+      { src->bo, src->domain | NOUVEAU_BO_RD },
+      { dst->bo, dst->domain | NOUVEAU_BO_WR },
+   };
+   struct nv04_fifo *fifo = push->channel->data;
+   unsigned src_offset = src->offset;
+   unsigned dst_offset = dst->offset;
+   unsigned w = dst->x1 - dst->x0;
+   unsigned h = dst->y1 - dst->y0;
+
+   src_offset += (src->y0 * src->pitch) + (src->x0 * src->cpp);
+   dst_offset += (dst->y0 * dst->pitch) + (dst->x0 * dst->cpp);
+
+   BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2);
+   PUSH_DATA (push, (src->domain == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart);
+   PUSH_DATA (push, (dst->domain == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart);
+
+   while (h) {
+      unsigned lines = (h > 2047) ? 2047 : h;
+
+      if (nouveau_pushbuf_space(push, 13, 2, 0) ||
+          nouveau_pushbuf_refn (push, refs, 2))
+         return;
+
+      BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
+      PUSH_RELOC(push, src->bo, src_offset, NOUVEAU_BO_LOW, 0, 0);
+      PUSH_RELOC(push, dst->bo, dst_offset, NOUVEAU_BO_LOW, 0, 0);
+      PUSH_DATA (push, src->pitch);
+      PUSH_DATA (push, dst->pitch);
+      PUSH_DATA (push, w * src->cpp);
+      PUSH_DATA (push, lines);
+      PUSH_DATA (push, NV03_M2MF_FORMAT_INPUT_INC_1 |
+                       NV03_M2MF_FORMAT_OUTPUT_INC_1);
+      PUSH_DATA (push, 0x00000000);
+      BEGIN_NV04(push, NV04_GRAPH(M2MF, NOP), 1);
+      PUSH_DATA (push, 0x00000000);
+      BEGIN_NV04(push, NV03_M2MF(OFFSET_OUT), 1);
+      PUSH_DATA (push, 0x00000000);
+
+      h -= lines;
+      src_offset += src->pitch * lines;
+      dst_offset += dst->pitch * lines;
+   }
+}
+
+static boolean
+nv30_transfer_cpu(XFER_ARGS)
+{
+   if (nv30_transfer_scaled(src, dst))
+      return FALSE;
+   return TRUE;
+}
+
+static char *
+linear_ptr(struct nv30_rect *rect, char *base, int x, int y, int z)
+{
+   return base + (y * rect->pitch) + (x * rect->cpp);
+}
+
+static INLINE unsigned
+swizzle2d(unsigned v, unsigned s)
+{
+   v = (v | (v << 8)) & 0x00ff00ff;
+   v = (v | (v << 4)) & 0x0f0f0f0f;
+   v = (v | (v << 2)) & 0x33333333;
+   v = (v | (v << 1)) & 0x55555555;
+   return v << s;
+}
+
+static char *
+swizzle2d_ptr(struct nv30_rect *rect, char *base, int x, int y, int z)
+{
+   unsigned k = util_logbase2(MIN2(rect->w, rect->h));
+   unsigned km = (1 << k) - 1;
+   unsigned nx = rect->w >> k;
+   unsigned tx = x >> k;
+   unsigned ty = y >> k;
+   unsigned m;
+
+   m  = swizzle2d(x & km, 0);
+   m |= swizzle2d(y & km, 1);
+   m += ((ty * nx) + tx) << k << k;
+
+   return base + (m * rect->cpp);
+}
+
+static char *
+swizzle3d_ptr(struct nv30_rect *rect, char *base, int x, int y, int z)
+{
+   unsigned w = rect->w >> 1;
+   unsigned h = rect->h >> 1;
+   unsigned d = rect->d >> 1;
+   unsigned i = 0, o;
+   unsigned v = 0;
+
+   do {
+      o = i;
+      if (w) {
+         v |= (x & 1) << i++;
+         x >>= 1;
+         w >>= 1;
+      }
+      if (h) {
+         v |= (y & 1) << i++;
+         y >>= 1;
+         h >>= 1;
+      }
+      if (d) {
+         v |= (z & 1) << i++;
+         z >>= 1;
+         d >>= 1;
+      }
+   } while(o != i);
+
+   return base + (v * rect->cpp);
+}
+
+typedef char *(*get_ptr_t)(struct nv30_rect *, char *, int, int, int);
+
+static INLINE get_ptr_t
+get_ptr(struct nv30_rect *rect)
+{
+   if (rect->pitch)
+      return linear_ptr;
+
+   if (rect->d <= 1)
+      return swizzle2d_ptr;
+
+   return swizzle3d_ptr;
+}
+
+static void
+nv30_transfer_rect_cpu(XFER_ARGS)
+{
+   get_ptr_t sp = get_ptr(src);
+   get_ptr_t dp = get_ptr(dst);
+   char *srcmap, *dstmap;
+   int x, y;
+
+   nouveau_bo_map(src->bo, NOUVEAU_BO_RD, nv30->base.client);
+   nouveau_bo_map(dst->bo, NOUVEAU_BO_WR, nv30->base.client);
+   srcmap = src->bo->map + src->offset;
+   dstmap = dst->bo->map + dst->offset;
+
+   for (y = 0; y < (dst->y1 - dst->y0); y++) {
+      for (x = 0; x < (dst->x1 - dst->x0); x++) {
+         memcpy(dp(dst, dstmap, dst->x0 + x, dst->y0 + y, dst->z),
+                sp(src, srcmap, src->x0 + x, src->y0 + y, src->z), dst->cpp);
+      }
+   }
+}
+
+void
+nv30_transfer_rect(struct nv30_context *nv30, enum nv30_transfer_filter filter,
+                   struct nv30_rect *src, struct nv30_rect *dst)
+{
+   static const struct {
+      char *name;
+      boolean (*possible)(XFER_ARGS);
+      void (*execute)(XFER_ARGS);
+   } *method, methods[] = {
+      { "m2mf", nv30_transfer_m2mf, nv30_transfer_rect_m2mf },
+      { "sifm", nv30_transfer_sifm, nv30_transfer_rect_sifm },
+      { "blit", nv30_transfer_blit, nv30_transfer_rect_blit },
+      { "rect", nv30_transfer_cpu, nv30_transfer_rect_cpu },
+      {}
+   };
+
+   method = methods - 1;
+   while ((++method)->possible) {
+      if (method->possible(nv30, filter, src, dst)) {
+         method->execute(nv30, filter, src, dst);
+         return;
+      }
+   }
+
+   assert(0);
+}
+
+void
+nv30_transfer_push_data(struct nouveau_context *nv,
+                        struct nouveau_bo *bo, unsigned offset, unsigned domain,
+                        unsigned size, void *data)
+{
+   /* use ifc, or scratch + copy_data? */
+   fprintf(stderr, "nv30: push_data not implemented\n");
+}
+
+void
+nv30_transfer_copy_data(struct nouveau_context *nv,
+                        struct nouveau_bo *dst, unsigned d_off, unsigned d_dom,
+                        struct nouveau_bo *src, unsigned s_off, unsigned s_dom,
+                        unsigned size)
+{
+   struct nv04_fifo *fifo = nv->screen->channel->data;
+   struct nouveau_pushbuf_refn refs[] = {
+      { src, s_dom | NOUVEAU_BO_RD },
+      { dst, d_dom | NOUVEAU_BO_WR },
+   };
+   struct nouveau_pushbuf *push = nv->pushbuf;
+   unsigned pages, lines;
+
+   pages = size >> 12;
+   size -= (pages << 12);
+
+   BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2);
+   PUSH_DATA (push, (s_dom == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart);
+   PUSH_DATA (push, (d_dom == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart);
+
+   while (pages) {
+      lines  = (pages > 2047) ? 2047 : pages;
+      pages -= lines;
+
+      if (nouveau_pushbuf_space(push, 13, 2, 0) ||
+          nouveau_pushbuf_refn (push, refs, 2))
+         return;
+
+      BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
+      PUSH_RELOC(push, src, s_off, NOUVEAU_BO_LOW, 0, 0);
+      PUSH_RELOC(push, dst, d_off, NOUVEAU_BO_LOW, 0, 0);
+      PUSH_DATA (push, 4096);
+      PUSH_DATA (push, 4096);
+      PUSH_DATA (push, 4096);
+      PUSH_DATA (push, lines);
+      PUSH_DATA (push, NV03_M2MF_FORMAT_INPUT_INC_1 |
+                       NV03_M2MF_FORMAT_OUTPUT_INC_1);
+      PUSH_DATA (push, 0x00000000);
+      BEGIN_NV04(push, NV04_GRAPH(M2MF, NOP), 1);
+      PUSH_DATA (push, 0x00000000);
+      BEGIN_NV04(push, NV03_M2MF(OFFSET_OUT), 1);
+      PUSH_DATA (push, 0x00000000);
+
+      s_off += (lines << 12);
+      d_off += (lines << 12);
+   }
+
+   if (size) {
+      if (nouveau_pushbuf_space(push, 13, 2, 0) ||
+          nouveau_pushbuf_refn (push, refs, 2))
+         return;
+
+      BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
+      PUSH_RELOC(push, src, s_off, NOUVEAU_BO_LOW, 0, 0);
+      PUSH_RELOC(push, dst, d_off, NOUVEAU_BO_LOW, 0, 0);
+      PUSH_DATA (push, size);
+      PUSH_DATA (push, size);
+      PUSH_DATA (push, size);
+      PUSH_DATA (push, 1);
+      PUSH_DATA (push, NV03_M2MF_FORMAT_INPUT_INC_1 |
+                       NV03_M2MF_FORMAT_OUTPUT_INC_1);
+      PUSH_DATA (push, 0x00000000);
+      BEGIN_NV04(push, NV04_GRAPH(M2MF, NOP), 1);
+      PUSH_DATA (push, 0x00000000);
+      BEGIN_NV04(push, NV03_M2MF(OFFSET_OUT), 1);
+      PUSH_DATA (push, 0x00000000);
+   }
+}
diff --git a/src/gallium/drivers/nv30/nv30_transfer.h b/src/gallium/drivers/nv30/nv30_transfer.h
new file mode 100644 (file)
index 0000000..3fa6cd0
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __NV30_TRANSFER_H__
+#define __NV30_TRANSFER_H__
+
+struct nv30_rect {
+   struct nouveau_bo *bo;
+   unsigned offset;
+   unsigned domain;
+   unsigned pitch;
+   unsigned cpp;
+   unsigned w;
+   unsigned h;
+   unsigned d;
+   unsigned z;
+   unsigned x0;
+   unsigned x1;
+   unsigned y0;
+   unsigned y1;
+};
+
+enum nv30_transfer_filter {
+   NEAREST = 0,
+   BILINEAR
+};
+
+void
+nv30_transfer_rect(struct nv30_context *, enum nv30_transfer_filter filter,
+                   struct nv30_rect *, struct nv30_rect *);
+
+void
+nv30_transfer_push_data(struct nouveau_context *,
+                        struct nouveau_bo *, unsigned offset, unsigned domain,
+                        unsigned size, void *data);
+
+void
+nv30_transfer_copy_data(struct nouveau_context *,
+                        struct nouveau_bo *, unsigned dstoff, unsigned dstdom,
+                        struct nouveau_bo *, unsigned srcoff, unsigned srcdom,
+                        unsigned size);
+
+#endif
diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c
new file mode 100644 (file)
index 0000000..43914f7
--- /dev/null
@@ -0,0 +1,620 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+#include "translate/translate.h"
+
+#include "nouveau/nouveau_fence.h"
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_format.h"
+
+static void
+nv30_emit_vtxattr(struct nv30_context *nv30, struct pipe_vertex_buffer *vb,
+                  struct pipe_vertex_element *ve, unsigned attr)
+{
+   const unsigned nc = util_format_get_nr_components(ve->src_format);
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nv04_resource *res = nv04_resource(vb->buffer);
+   const void *data;
+   float v[4];
+
+   data = nouveau_resource_map_offset(&nv30->base, res, vb->buffer_offset +
+                                      ve->src_offset, NOUVEAU_BO_RD);
+
+   util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1);
+
+   switch (nc) {
+   case 4:
+      BEGIN_NV04(push, NV30_3D(VTX_ATTR_4F(attr)), 4);
+      PUSH_DATAf(push, v[0]);
+      PUSH_DATAf(push, v[1]);
+      PUSH_DATAf(push, v[2]);
+      PUSH_DATAf(push, v[3]);
+      break;
+   case 3:
+      BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(attr)), 3);
+      PUSH_DATAf(push, v[0]);
+      PUSH_DATAf(push, v[1]);
+      PUSH_DATAf(push, v[2]);
+      break;
+   case 2:
+      BEGIN_NV04(push, NV30_3D(VTX_ATTR_2F(attr)), 2);
+      PUSH_DATAf(push, v[0]);
+      PUSH_DATAf(push, v[1]);
+      break;
+   case 1:
+      BEGIN_NV04(push, NV30_3D(VTX_ATTR_1F(attr)), 1);
+      PUSH_DATAf(push, v[0]);
+      break;
+   default:
+      assert(0);
+      break;
+   }
+}
+
+static INLINE void
+nv30_vbuf_range(struct nv30_context *nv30, int vbi,
+                uint32_t *base, uint32_t *size)
+{
+   assert(nv30->vbo_max_index != ~0);
+   *base = nv30->vbo_min_index * nv30->vtxbuf[vbi].stride;
+   *size = (nv30->vbo_max_index -
+            nv30->vbo_min_index + 1) * nv30->vtxbuf[vbi].stride;
+}
+
+static void
+nv30_prevalidate_vbufs(struct nv30_context *nv30)
+{
+   struct pipe_vertex_buffer *vb;
+   struct nv04_resource *buf;
+   int i;
+   uint32_t base, size;
+
+   nv30->vbo_fifo = nv30->vbo_user = 0;
+
+   for (i = 0; i < nv30->num_vtxbufs; i++) {
+      vb = &nv30->vtxbuf[i];
+      if (!vb->stride)
+         continue;
+      buf = nv04_resource(vb->buffer);
+
+      /* NOTE: user buffers with temporary storage count as mapped by GPU */
+      if (!nouveau_resource_mapped_by_gpu(vb->buffer)) {
+         if (nv30->vbo_push_hint) {
+            nv30->vbo_fifo = ~0;
+            continue;
+         } else {
+            if (buf->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY) {
+               nv30->vbo_user |= 1 << i;
+               assert(vb->stride > vb->buffer_offset);
+               nv30_vbuf_range(nv30, i, &base, &size);
+               nouveau_user_buffer_upload(&nv30->base, buf, base, size);
+            } else {
+               nouveau_buffer_migrate(&nv30->base, buf, NOUVEAU_BO_GART);
+            }
+            nv30->base.vbo_dirty = TRUE;
+         }
+      }
+   }
+}
+
+static void
+nv30_update_user_vbufs(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   uint32_t base, offset, size;
+   int i;
+   uint32_t written = 0;
+
+   for (i = 0; i < nv30->vertex->num_elements; i++) {
+      struct pipe_vertex_element *ve = &nv30->vertex->pipe[i];
+      const int b = ve->vertex_buffer_index;
+      struct pipe_vertex_buffer *vb = &nv30->vtxbuf[b];
+      struct nv04_resource *buf = nv04_resource(vb->buffer);
+
+      if (!(nv30->vbo_user & (1 << b)))
+         continue;
+
+      if (!vb->stride) {
+         nv30_emit_vtxattr(nv30, vb, ve, i);
+         continue;
+      }
+      nv30_vbuf_range(nv30, b, &base, &size);
+
+      if (!(written & (1 << b))) {
+         written |= 1 << b;
+         nouveau_user_buffer_upload(&nv30->base, buf, base, size);
+      }
+
+      offset = vb->buffer_offset + ve->src_offset;
+
+      BEGIN_NV04(push, NV30_3D(VTXBUF(i)), 1);
+      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP, buf, offset,
+                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD,
+                       0, NV30_3D_VTXBUF_DMA1);
+   }
+   nv30->base.vbo_dirty = TRUE;
+}
+
+static INLINE void
+nv30_release_user_vbufs(struct nv30_context *nv30)
+{
+   uint32_t vbo_user = nv30->vbo_user;
+
+   while (vbo_user) {
+      int i = ffs(vbo_user) - 1;
+      vbo_user &= ~(1 << i);
+
+      nouveau_buffer_release_gpu_storage(nv04_resource(nv30->vtxbuf[i].buffer));
+   }
+
+   nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VTXTMP);
+}
+
+void
+nv30_vbo_validate(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nv30_vertex_stateobj *vertex = nv30->vertex;
+   struct pipe_vertex_element *ve;
+   struct pipe_vertex_buffer *vb;
+   unsigned i, redefine;
+
+   nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VTXBUF);
+   if (!nv30->vertex || nv30->draw_flags)
+      return;
+
+   if (unlikely(vertex->need_conversion)) {
+      nv30->vbo_fifo = ~0;
+      nv30->vbo_user = 0;
+   } else {
+      nv30_prevalidate_vbufs(nv30);
+   }
+
+   if (!PUSH_SPACE(push, 128))
+      return;
+
+   redefine = MAX2(vertex->num_elements, nv30->state.num_vtxelts);
+   BEGIN_NV04(push, NV30_3D(VTXFMT(0)), redefine);
+
+   for (i = 0; i < vertex->num_elements; i++) {
+      ve = &vertex->pipe[i];
+      vb = &nv30->vtxbuf[ve->vertex_buffer_index];
+
+      if (likely(vb->stride) || nv30->vbo_fifo)
+         PUSH_DATA (push, (vb->stride << 8) | vertex->element[i].state);
+      else
+         PUSH_DATA (push, NV30_3D_VTXFMT_TYPE_V32_FLOAT);
+   }
+
+   for (; i < nv30->state.num_vtxelts; i++) {
+      PUSH_DATA (push, NV30_3D_VTXFMT_TYPE_V32_FLOAT);
+   }
+
+   for (i = 0; i < vertex->num_elements; i++) {
+      struct nv04_resource *res;
+      unsigned offset;
+      boolean user;
+
+      ve = &vertex->pipe[i];
+      vb = &nv30->vtxbuf[ve->vertex_buffer_index];
+      user = (nv30->vbo_user & (1 << ve->vertex_buffer_index));
+
+      res = nv04_resource(vb->buffer);
+
+      if (nv30->vbo_fifo || unlikely(vb->stride == 0)) {
+         if (!nv30->vbo_fifo)
+            nv30_emit_vtxattr(nv30, vb, ve, i);
+         continue;
+      }
+
+      offset = ve->src_offset + vb->buffer_offset;
+
+      BEGIN_NV04(push, NV30_3D(VTXBUF(i)), 1);
+      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), user ? BUFCTX_VTXTMP : BUFCTX_VTXBUF,
+                       res, offset, NOUVEAU_BO_LOW | NOUVEAU_BO_RD,
+                       0, NV30_3D_VTXBUF_DMA1);
+   }
+
+   nv30->state.num_vtxelts = vertex->num_elements;
+}
+
+static void *
+nv30_vertex_state_create(struct pipe_context *pipe, unsigned num_elements,
+                         const struct pipe_vertex_element *elements)
+{
+    struct nv30_vertex_stateobj *so;
+    struct translate_key transkey;
+    unsigned i;
+
+    assert(num_elements);
+
+    so = MALLOC(sizeof(*so) + sizeof(*so->element) * num_elements);
+    if (!so)
+        return NULL;
+    memcpy(so->pipe, elements, sizeof(*elements) * num_elements);
+    so->num_elements = num_elements;
+    so->need_conversion = FALSE;
+
+    transkey.nr_elements = 0;
+    transkey.output_stride = 0;
+
+    for (i = 0; i < num_elements; i++) {
+        const struct pipe_vertex_element *ve = &elements[i];
+        const unsigned vbi = ve->vertex_buffer_index;
+        enum pipe_format fmt = ve->src_format;
+
+        so->element[i].state = nv30_vtxfmt(pipe->screen, fmt)->hw;
+        if (!so->element[i].state) {
+            switch (util_format_get_nr_components(fmt)) {
+            case 1: fmt = PIPE_FORMAT_R32_FLOAT; break;
+            case 2: fmt = PIPE_FORMAT_R32G32_FLOAT; break;
+            case 3: fmt = PIPE_FORMAT_R32G32B32_FLOAT; break;
+            case 4: fmt = PIPE_FORMAT_R32G32B32A32_FLOAT; break;
+            default:
+                assert(0);
+                return NULL;
+            }
+            so->element[i].state = nv30_vtxfmt(pipe->screen, fmt)->hw;
+            so->need_conversion = TRUE;
+        }
+
+        if (1) {
+            unsigned j = transkey.nr_elements++;
+
+            transkey.element[j].type = TRANSLATE_ELEMENT_NORMAL;
+            transkey.element[j].input_format = ve->src_format;
+            transkey.element[j].input_buffer = vbi;
+            transkey.element[j].input_offset = ve->src_offset;
+            transkey.element[j].instance_divisor = ve->instance_divisor;
+
+            transkey.element[j].output_format = fmt;
+            transkey.element[j].output_offset = transkey.output_stride;
+            transkey.output_stride += (util_format_get_stride(fmt, 1) + 3) & ~3;
+        }
+    }
+
+    so->translate = translate_create(&transkey);
+    so->vtx_size = transkey.output_stride / 4;
+    so->vtx_per_packet_max = NV04_PFIFO_MAX_PACKET_LEN / MAX2(so->vtx_size, 1);
+    return so;
+}
+
+static void
+nv30_vertex_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+   struct nv30_vertex_stateobj *so = hwcso;
+
+   if (so->translate)
+      so->translate->release(so->translate);
+   FREE(hwcso);
+}
+
+static void
+nv30_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+
+   nv30->vertex = hwcso;
+   nv30->dirty |= NV30_NEW_VERTEX;
+}
+
+static void
+nv30_draw_arrays(struct nv30_context *nv30,
+                 unsigned mode, unsigned start, unsigned count,
+                 unsigned instance_count)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   unsigned prim;
+
+   prim = nv30_prim_gl(mode);
+
+   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+   PUSH_DATA (push, prim);
+   while (count) {
+      const unsigned mpush = 2047 * 256;
+      unsigned npush  = (count > mpush) ? mpush : count;
+      unsigned wpush  = ((npush + 255) & ~255) >> 8;
+
+      count -= npush;
+
+      BEGIN_NI04(push, NV30_3D(VB_VERTEX_BATCH), wpush);
+      while (npush >= 256) {
+         PUSH_DATA (push, 0xff000000 | start);
+         start += 256;
+         npush -= 256;
+      }
+
+      if (npush)
+         PUSH_DATA (push, ((npush - 1) << 24) | start);
+   }
+   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
+}
+
+static void
+nv30_draw_elements_inline_u08(struct nouveau_pushbuf *push, uint8_t *map,
+                              unsigned start, unsigned count)
+{
+   map += start;
+
+   if (count & 1) {
+      BEGIN_NV04(push, NV30_3D(VB_ELEMENT_U32), 1);
+      PUSH_DATA (push, *map++);
+   }
+
+   count >>= 1;
+   while (count) {
+      unsigned npush = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
+      count -= npush;
+
+      BEGIN_NI04(push, NV30_3D(VB_ELEMENT_U16), npush);
+      while (npush--) {
+         PUSH_DATA (push, (map[1] << 16) | map[0]);
+         map += 2;
+      }
+   }
+
+}
+
+static void
+nv30_draw_elements_inline_u16(struct nouveau_pushbuf *push, uint16_t *map,
+                              unsigned start, unsigned count)
+{
+   map += start;
+
+   if (count & 1) {
+      BEGIN_NV04(push, NV30_3D(VB_ELEMENT_U32), 1);
+      PUSH_DATA (push, *map++);
+   }
+
+   count >>= 1;
+   while (count) {
+      unsigned npush = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
+      count -= npush;
+
+      BEGIN_NI04(push, NV30_3D(VB_ELEMENT_U16), npush);
+      while (npush--) {
+         PUSH_DATA (push, (map[1] << 16) | map[0]);
+         map += 2;
+      }
+   }
+}
+
+static void
+nv30_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map,
+                              unsigned start, unsigned count)
+{
+   map += start;
+
+   while (count) {
+      const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
+
+      BEGIN_NI04(push, NV30_3D(VB_ELEMENT_U32), nr);
+      PUSH_DATAp(push, map, nr);
+
+      map += nr;
+      count -= nr;
+   }
+}
+
+static void
+nv30_draw_elements_inline_u32_short(struct nouveau_pushbuf *push, uint32_t *map,
+                                    unsigned start, unsigned count)
+{
+   map += start;
+
+   if (count & 1) {
+      BEGIN_NV04(push, NV30_3D(VB_ELEMENT_U32), 1);
+      PUSH_DATA (push, *map++);
+   }
+
+   count >>= 1;
+   while (count) {
+      unsigned npush = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);;
+      count -= npush;
+
+      BEGIN_NI04(push, NV30_3D(VB_ELEMENT_U16), npush);
+      while (npush--) {
+         PUSH_DATA (push, (map[1] << 16) | map[0]);
+         map += 2;
+      }
+   }
+}
+
+static void
+nv30_draw_elements(struct nv30_context *nv30, boolean shorten,
+                   unsigned mode, unsigned start, unsigned count,
+                   unsigned instance_count, int32_t index_bias)
+{
+   const unsigned index_size = nv30->idxbuf.index_size;
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nouveau_object *eng3d = nv30->screen->eng3d;
+   unsigned prim = nv30_prim_gl(mode);
+   void *data;
+
+#if 0 /*XXX*/
+   if (index_bias != nv30->state.index_bias) {
+      BEGIN_NV04(push, NV30_3D(VB_ELEMENT_BASE), 1);
+      PUSH_DATA (push, index_bias);
+      nv30->state.index_bias = index_bias;
+   }
+#endif
+
+   if (eng3d->oclass == NV40_3D_CLASS && index_size > 1 &&
+       nouveau_resource_mapped_by_gpu(nv30->idxbuf.buffer)) {
+      struct nv04_resource *res = nv04_resource(nv30->idxbuf.buffer);
+      unsigned offset = nv30->idxbuf.offset;
+
+      BEGIN_NV04(push, NV30_3D(IDXBUF_OFFSET), 2);
+      PUSH_RESRC(push, NV30_3D(IDXBUF_OFFSET), BUFCTX_IDXBUF, res, offset,
+                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0);
+      PUSH_MTHD (push, NV30_3D(IDXBUF_FORMAT), BUFCTX_IDXBUF, res->bo,
+                       (index_size == 2) ? 0x00000010 : 0x00000000,
+                       res->domain | NOUVEAU_BO_RD,
+                       0, NV30_3D_IDXBUF_FORMAT_DMA1);
+      BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+      PUSH_DATA (push, prim);
+      while (count) {
+         const unsigned mpush = 2047 * 256;
+         unsigned npush  = (count > mpush) ? mpush : count;
+         unsigned wpush  = ((npush + 255) & ~255) >> 8;
+
+         count -= npush;
+
+         BEGIN_NI04(push, NV30_3D(VB_INDEX_BATCH), wpush);
+         while (npush >= 256) {
+            PUSH_DATA (push, 0xff000000 | start);
+            start += 256;
+            npush -= 256;
+         }
+
+         if (npush)
+            PUSH_DATA (push, ((npush - 1) << 24) | start);
+      }
+      BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+      PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
+      PUSH_RESET(push, BUFCTX_IDXBUF);
+   } else {
+      data = nouveau_resource_map_offset(&nv30->base,
+                                         nv04_resource(nv30->idxbuf.buffer),
+                                         nv30->idxbuf.offset, NOUVEAU_BO_RD);
+      if (!data)
+         return;
+
+      BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+      PUSH_DATA (push, prim);
+      switch (index_size) {
+      case 1:
+         nv30_draw_elements_inline_u08(push, data, start, count);
+         break;
+      case 2:
+         nv30_draw_elements_inline_u16(push, data, start, count);
+         break;
+      case 4:
+         if (shorten)
+            nv30_draw_elements_inline_u32_short(push, data, start, count);
+         else
+            nv30_draw_elements_inline_u32(push, data, start, count);
+         break;
+      default:
+         assert(0);
+         return;
+      }
+      BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+      PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
+   }
+}
+
+static void
+nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
+   /* For picking only a few vertices from a large user buffer, push is better,
+    * if index count is larger and we expect repeated vertices, suggest upload.
+    */
+   nv30->vbo_push_hint = /* the 64 is heuristic */
+      !(info->indexed &&
+        ((info->max_index - info->min_index + 64) < info->count));
+
+   nv30->vbo_min_index = info->min_index;
+   nv30->vbo_max_index = info->max_index;
+
+   if (nv30->vbo_push_hint != !!nv30->vbo_fifo)
+      nv30->dirty |= NV30_NEW_ARRAYS;
+
+   push->user_priv = &nv30->bufctx;
+   if (nv30->vbo_user && !(nv30->dirty & (NV30_NEW_VERTEX | NV30_NEW_ARRAYS)))
+      nv30_update_user_vbufs(nv30);
+
+   nv30_state_validate(nv30, TRUE);
+   if (nv30->draw_flags) {
+      nv30_render_vbo(pipe, info);
+      return;
+   } else
+   if (nv30->vbo_fifo) {
+      nv30_push_vbo(nv30, info);
+      return;
+   }
+
+   if (nv30->base.vbo_dirty) {
+      BEGIN_NV04(push, NV30_3D(VTX_CACHE_INVALIDATE_1710), 1);
+      PUSH_DATA (push, 0);
+      nv30->base.vbo_dirty = FALSE;
+   }
+
+   if (!info->indexed) {
+      nv30_draw_arrays(nv30,
+                       info->mode, info->start, info->count,
+                       info->instance_count);
+   } else {
+      boolean shorten = info->max_index <= 65535;
+
+      assert(nv30->idxbuf.buffer);
+
+      if (info->primitive_restart != nv30->state.prim_restart) {
+         if (info->primitive_restart) {
+            BEGIN_NV04(push, NV40_3D(PRIM_RESTART_ENABLE), 2);
+            PUSH_DATA (push, 1);
+            PUSH_DATA (push, info->restart_index);
+
+            if (info->restart_index > 65535)
+               shorten = FALSE;
+         } else {
+            BEGIN_NV04(push, NV40_3D(PRIM_RESTART_ENABLE), 1);
+            PUSH_DATA (push, 0);
+         }
+         nv30->state.prim_restart = info->primitive_restart;
+      } else
+      if (info->primitive_restart) {
+         BEGIN_NV04(push, NV40_3D(PRIM_RESTART_INDEX), 1);
+         PUSH_DATA (push, info->restart_index);
+
+         if (info->restart_index > 65535)
+            shorten = FALSE;
+      }
+
+      nv30_draw_elements(nv30, shorten,
+                         info->mode, info->start, info->count,
+                         info->instance_count, info->index_bias);
+   }
+
+   nv30_state_release(nv30);
+   nv30_release_user_vbufs(nv30);
+}
+
+void
+nv30_vbo_init(struct pipe_context *pipe)
+{
+   pipe->create_vertex_elements_state = nv30_vertex_state_create;
+   pipe->delete_vertex_elements_state = nv30_vertex_state_delete;
+   pipe->bind_vertex_elements_state = nv30_vertex_state_bind;
+   pipe->draw_vbo = nv30_draw_vbo;
+}
diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c
new file mode 100644 (file)
index 0000000..9b5ba35
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "util/u_dynarray.h"
+#include "tgsi/tgsi_parse.h"
+
+#include "nouveau/nv_object.xml.h"
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_state.h"
+
+static void
+nv30_vertprog_destroy(struct nv30_vertprog *vp)
+{
+   util_dynarray_fini(&vp->branch_relocs);
+   nouveau_heap_free(&vp->exec);
+   FREE(vp->insns);
+   vp->insns = NULL;
+   vp->nr_insns = 0;
+
+   util_dynarray_fini(&vp->const_relocs);
+   nouveau_heap_free(&vp->data);
+   FREE(vp->consts);
+   vp->consts = NULL;
+   vp->nr_consts = 0;
+
+   vp->translated = FALSE;
+}
+
+void
+nv30_vertprog_validate(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   struct nouveau_object *eng3d = nv30->screen->eng3d;
+   struct nv30_vertprog *vp = nv30->vertprog.program;
+   struct nv30_fragprog *fp = nv30->fragprog.program;
+   boolean upload_code = FALSE;
+   boolean upload_data = FALSE;
+   unsigned i;
+
+   if (nv30->dirty & NV30_NEW_FRAGPROG) {
+      if (memcmp(vp->texcoord, fp->texcoord, sizeof(vp->texcoord))) {
+         if (vp->translated)
+            nv30_vertprog_destroy(vp);
+         memcpy(vp->texcoord, fp->texcoord, sizeof(vp->texcoord));
+      }
+   }
+
+   if (nv30->rast && nv30->rast->pipe.clip_plane_enable != vp->enabled_ucps) {
+      vp->enabled_ucps = nv30->rast->pipe.clip_plane_enable;
+      if (vp->translated)
+         nv30_vertprog_destroy(vp);
+   }
+
+   if (!vp->translated) {
+      vp->translated = _nvfx_vertprog_translate(nv30, vp);
+      if (!vp->translated) {
+         nv30->draw_flags |= NV30_NEW_VERTPROG;
+         return;
+      }
+      nv30->dirty |= NV30_NEW_VERTPROG;
+   }
+
+   if (!vp->exec) {
+      struct nouveau_heap *heap = nv30->screen->vp_exec_heap;
+      struct nv30_shader_reloc *reloc = vp->branch_relocs.data;
+      unsigned nr_reloc = vp->branch_relocs.size / sizeof(*reloc);
+      uint32_t *inst, target;
+
+      if (nouveau_heap_alloc(heap, vp->nr_insns, &vp->exec, &vp->exec)) {
+         while (heap->next && heap->size < vp->nr_insns) {
+            struct nouveau_heap **evict = heap->next->priv;
+            nouveau_heap_free(evict);
+         }
+
+         if (nouveau_heap_alloc(heap, vp->nr_insns, &vp->exec, &vp->exec)) {
+            nv30->draw_flags |= NV30_NEW_VERTPROG;
+            return;
+         }
+      }
+
+      if (eng3d->oclass < NV40_3D_CLASS) {
+         while (nr_reloc--) {
+            inst     = vp->insns[reloc->location].data;
+            target   = vp->exec->start + reloc->target;
+
+            inst[2] &= ~0x000007fc;
+            inst[2] |= target << 2;
+            reloc++;
+         }
+      } else {
+         while (nr_reloc--) {
+            inst     = vp->insns[reloc->location].data;
+            target   = vp->exec->start + reloc->target;
+
+            inst[2] &= ~0x0000003f;
+            inst[2] |= target >> 3;
+            inst[3] &= ~0xe0000000;
+            inst[3] |= target << 29;
+            reloc++;
+         }
+      }
+
+      upload_code = TRUE;
+   }
+
+   if (vp->nr_consts && !vp->data) {
+      struct nouveau_heap *heap = nv30->screen->vp_data_heap;
+      struct nv30_shader_reloc *reloc = vp->const_relocs.data;
+      unsigned nr_reloc = vp->const_relocs.size / sizeof(*reloc);
+      uint32_t *inst, target;
+
+      if (nouveau_heap_alloc(heap, vp->nr_consts, vp, &vp->data)) {
+         while (heap->next && heap->size < vp->nr_consts) {
+            struct nv30_vertprog *evp = heap->next->priv;
+            nouveau_heap_free(&evp->data);
+         }
+
+         if (nouveau_heap_alloc(heap, vp->nr_consts, vp, &vp->data)) {
+            nv30->draw_flags |= NV30_NEW_VERTPROG;
+            return;
+         }
+      }
+
+      if (eng3d->oclass < NV40_3D_CLASS) {
+         while (nr_reloc--) {
+            inst     = vp->insns[reloc->location].data;
+            target   = vp->data->start + reloc->target;
+
+            inst[1] &= ~0x0003fc000;
+            inst[1] |= target << 14;
+            reloc++;
+         }
+      } else {
+         while (nr_reloc--) {
+            inst     = vp->insns[reloc->location].data;
+            target   = vp->data->start + reloc->target;
+
+            inst[1] &= ~0x0001ff000;
+            inst[1] |= target << 12;
+            reloc++;
+         }
+      }
+
+      upload_code = TRUE;
+      upload_data = TRUE;
+   }
+
+   if (vp->nr_consts) {
+      struct nv04_resource *res = nv04_resource(nv30->vertprog.constbuf);
+
+      for (i = 0; i < vp->nr_consts; i++) {
+         struct nv30_vertprog_data *data = &vp->consts[i];
+
+         if (data->index < 0) {
+            if (!upload_data)
+               continue;
+         } else {
+            float *constbuf = (float *)res->data;
+            if (!upload_data &&
+                !memcmp(data->value, &constbuf[data->index * 4], 16))
+               continue;
+            memcpy(data->value, &constbuf[data->index * 4], 16);
+         }
+
+         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 5);
+         PUSH_DATA (push, vp->data->start + i);
+         PUSH_DATAp(push, data->value, 4);
+      }
+   }
+
+   if (upload_code) {
+      BEGIN_NV04(push, NV30_3D(VP_UPLOAD_FROM_ID), 1);
+      PUSH_DATA (push, vp->exec->start);
+      for (i = 0; i < vp->nr_insns; i++) {
+         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_INST(0)), 4);
+         PUSH_DATAp(push, vp->insns[i].data, 4);
+      }
+   }
+
+   if (nv30->dirty & (NV30_NEW_VERTPROG | NV30_NEW_FRAGPROG)) {
+      BEGIN_NV04(push, NV30_3D(VP_START_FROM_ID), 1);
+      PUSH_DATA (push, vp->exec->start);
+      if (eng3d->oclass < NV40_3D_CLASS) {
+         BEGIN_NV04(push, NV30_3D(ENGINE), 1);
+         PUSH_DATA (push, 0x00000013); /* vp instead of ff, somehow */
+      } else {
+         BEGIN_NV04(push, NV40_3D(VP_ATTRIB_EN), 2);
+         PUSH_DATA (push, vp->ir);
+         PUSH_DATA (push, vp->or | fp->vp_or);
+         BEGIN_NV04(push, NV30_3D(ENGINE), 1);
+         PUSH_DATA (push, 0x00000011);
+      }
+   }
+}
+
+static void *
+nv30_vp_state_create(struct pipe_context *pipe,
+                     const struct pipe_shader_state *cso)
+{
+   struct nv30_vertprog *vp = CALLOC_STRUCT(nv30_vertprog);
+   if (!vp)
+      return NULL;
+
+   vp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+   tgsi_scan_shader(vp->pipe.tokens, &vp->info);
+   return vp;
+}
+
+static void
+nv30_vp_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+   struct nv30_vertprog *vp = hwcso;
+
+   if (vp->translated)
+      nv30_vertprog_destroy(vp);
+   FREE((void *)vp->pipe.tokens);
+   FREE(vp);
+}
+
+static void
+nv30_vp_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+
+   nv30->vertprog.program = hwcso;
+   nv30->dirty |= NV30_NEW_VERTPROG;
+}
+
+void
+nv30_vertprog_init(struct pipe_context *pipe)
+{
+   pipe->create_vs_state = nv30_vp_state_create;
+   pipe->bind_vs_state = nv30_vp_state_bind;
+   pipe->delete_vs_state = nv30_vp_state_delete;
+}
diff --git a/src/gallium/drivers/nv30/nv30_vertprog.h b/src/gallium/drivers/nv30/nv30_vertprog.h
new file mode 100644 (file)
index 0000000..e8c16b0
--- /dev/null
@@ -0,0 +1,176 @@
+#ifndef __NV30_SHADER_H__
+#define __NV30_SHADER_H__
+
+/* Vertex programs instruction set
+ *
+ * 128bit opcodes, split into 4 32-bit ones for ease of use.
+ *
+ * Non-native instructions
+ *   ABS - MOV + NV40_VP_INST0_DEST_ABS
+ *   POW - EX2 + MUL + LG2
+ *   SUB - ADD, second source negated
+ *   SWZ - MOV
+ *   XPD -
+ *
+ * Register access
+ *   - Only one INPUT can be accessed per-instruction (move extras into TEMPs)
+ *   - Only one CONST can be accessed per-instruction (move extras into TEMPs)
+ *
+ * Relative Addressing
+ *   According to the value returned for
+ *   MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
+ *
+ *   there are only two address registers available.  The destination in the
+ *   ARL instruction is set to TEMP <n> (The temp isn't actually written).
+ *
+ *   When using vanilla ARB_v_p, the proprietary driver will squish both the
+ *   available ADDRESS regs into the first hardware reg in the X and Y
+ *   components.
+ *
+ *   To use an address reg as an index into consts, the CONST_SRC is set to
+ *   (const_base + offset) and INDEX_CONST is set.
+ *
+ *   To access the second address reg use ADDR_REG_SELECT_1. A particular
+ *   component of the address regs is selected with ADDR_SWZ.
+ *
+ *   Only one address register can be accessed per instruction.
+ *
+ * Conditional execution (see NV_vertex_program{2,3} for details) Conditional
+ * execution of an instruction is enabled by setting COND_TEST_ENABLE, and
+ * selecting the condition which will allow the test to pass with
+ * COND_{FL,LT,...}.  It is possible to swizzle the values in the condition
+ * register, which allows for testing against an individual component.
+ *
+ * Branching:
+ *
+ *   The BRA/CAL instructions seem to follow a slightly different opcode
+ *   layout.  The destination instruction ID (IADDR) overlaps a source field.
+ *   Instruction ID's seem to be numbered based on the UPLOAD_FROM_ID FIFO
+ *   command, and is incremented automatically on each UPLOAD_INST FIFO
+ *   command.
+ *
+ *   Conditional branching is achieved by using the condition tests described
+ *   above.  There doesn't appear to be dedicated looping instructions, but
+ *   this can be done using a temp reg + conditional branching.
+ *
+ *   Subroutines may be uploaded before the main program itself, but the first
+ *   executed instruction is determined by the PROGRAM_START_ID FIFO command.
+ *
+ */
+
+/* DWORD 0 */
+
+/* guess that this is the same as nv40 */
+#define NV30_VP_INST_INDEX_INPUT                                        (1 << 27)
+
+#define NV30_VP_INST_ADDR_REG_SELECT_1        (1 << 24)
+#define NV30_VP_INST_SRC2_ABS           (1 << 23) /* guess */
+#define NV30_VP_INST_SRC1_ABS           (1 << 22) /* guess */
+#define NV30_VP_INST_SRC0_ABS           (1 << 21) /* guess */
+#define NV30_VP_INST_VEC_RESULT         (1 << 20)
+#define NV30_VP_INST_DEST_TEMP_ID_SHIFT        16
+#define NV30_VP_INST_DEST_TEMP_ID_MASK        (0x0F << 16)
+#define NV30_VP_INST_COND_UPDATE_ENABLE        (1<<15)
+#define NV30_VP_INST_VEC_DEST_TEMP_MASK      (0x1F << 16)
+#define NV30_VP_INST_COND_TEST_ENABLE        (1<<14)
+#define NV30_VP_INST_COND_SHIFT          11
+#define NV30_VP_INST_COND_MASK          (0x07 << 11)
+#define NV30_VP_INST_COND_SWZ_X_SHIFT        9
+#define NV30_VP_INST_COND_SWZ_X_MASK        (0x03 <<  9)
+#define NV30_VP_INST_COND_SWZ_Y_SHIFT        7
+#define NV30_VP_INST_COND_SWZ_Y_MASK        (0x03 <<  7)
+#define NV30_VP_INST_COND_SWZ_Z_SHIFT        5
+#define NV30_VP_INST_COND_SWZ_Z_MASK        (0x03 <<  5)
+#define NV30_VP_INST_COND_SWZ_W_SHIFT        3
+#define NV30_VP_INST_COND_SWZ_W_MASK        (0x03 <<  3)
+#define NV30_VP_INST_COND_SWZ_ALL_SHIFT        3
+#define NV30_VP_INST_COND_SWZ_ALL_MASK        (0xFF <<  3)
+#define NV30_VP_INST_ADDR_SWZ_SHIFT        1
+#define NV30_VP_INST_ADDR_SWZ_MASK        (0x03 <<  1)
+#define NV30_VP_INST_SCA_OPCODEH_SHIFT        0
+#define NV30_VP_INST_SCA_OPCODEH_MASK        (0x01 <<  0)
+
+/* DWORD 1 */
+#define NV30_VP_INST_SCA_OPCODEL_SHIFT        28
+#define NV30_VP_INST_SCA_OPCODEL_MASK        (0x0F << 28)
+#define NV30_VP_INST_VEC_OPCODE_SHIFT        23
+#define NV30_VP_INST_VEC_OPCODE_MASK        (0x1F << 23)
+#define NV30_VP_INST_CONST_SRC_SHIFT        14
+#define NV30_VP_INST_CONST_SRC_MASK        (0xFF << 14)
+#define NV30_VP_INST_INPUT_SRC_SHIFT        9    /*NV20*/
+#define NV30_VP_INST_INPUT_SRC_MASK        (0x0F <<  9)  /*NV20*/
+#define NV30_VP_INST_SRC0H_SHIFT        0    /*NV20*/
+#define NV30_VP_INST_SRC0H_MASK          (0x1FF << 0)  /*NV20*/
+
+/* Please note: the IADDR fields overlap other fields because they are used
+ * only for branch instructions.  See Branching: label above
+ *
+ * DWORD 2
+ */
+#define NV30_VP_INST_SRC0L_SHIFT        26    /*NV20*/
+#define NV30_VP_INST_SRC0L_MASK         (0x3F  <<26)  /* NV30_VP_SRC0_LOW_MASK << 26 */
+#define NV30_VP_INST_SRC1_SHIFT         11    /*NV20*/
+#define NV30_VP_INST_SRC1_MASK          (0x7FFF<<11)  /*NV20*/
+#define NV30_VP_INST_SRC2H_SHIFT        0    /*NV20*/
+#define NV30_VP_INST_SRC2H_MASK          (0x7FF << 0)  /* NV30_VP_SRC2_HIGH_MASK >> 4*/
+#define NV30_VP_INST_IADDR_SHIFT        2
+#define NV30_VP_INST_IADDR_MASK          (0x1FF <<  2)   /* NV30_VP_SRC2_LOW_MASK << 28 */
+
+/* DWORD 3 */
+#define NV30_VP_INST_SRC2L_SHIFT        28    /*NV20*/
+#define NV30_VP_INST_SRC2L_MASK          (0x0F  <<28)  /*NV20*/
+#define NV30_VP_INST_STEMP_WRITEMASK_SHIFT      24
+#define NV30_VP_INST_STEMP_WRITEMASK_MASK      (0x0F << 24)
+#define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT      20
+#define NV30_VP_INST_VTEMP_WRITEMASK_MASK      (0x0F << 20)
+#define NV30_VP_INST_SDEST_WRITEMASK_SHIFT      16
+#define NV30_VP_INST_SDEST_WRITEMASK_MASK      (0x0F << 16)
+#define NV30_VP_INST_VDEST_WRITEMASK_SHIFT      12    /*NV20*/
+#define NV30_VP_INST_VDEST_WRITEMASK_MASK      (0x0F << 12)  /*NV20*/
+#define NV30_VP_INST_DEST_SHIFT        2
+#define NV30_VP_INST_DEST_MASK        (0x1F <<  2)
+#  define NV30_VP_INST_DEST_POS  0
+#  define NV30_VP_INST_DEST_BFC0  1
+#  define NV30_VP_INST_DEST_BFC1  2
+#  define NV30_VP_INST_DEST_COL0  3
+#  define NV30_VP_INST_DEST_COL1  4
+#  define NV30_VP_INST_DEST_FOGC  5
+#  define NV30_VP_INST_DEST_PSZ   6
+#  define NV30_VP_INST_DEST_TC(n)  (8+(n))
+#  define NV30_VP_INST_DEST_CLP(n) (17 + (n))
+
+/* guess that this is the same as nv40 */
+#define NV30_VP_INST_INDEX_CONST                                        (1 << 1)
+
+/* Useful to split the source selection regs into their pieces */
+#define NV30_VP_SRC0_HIGH_SHIFT                                                6
+#define NV30_VP_SRC0_HIGH_MASK                                        0x00007FC0
+#define NV30_VP_SRC0_LOW_MASK                                         0x0000003F
+#define NV30_VP_SRC2_HIGH_SHIFT                                                4
+#define NV30_VP_SRC2_HIGH_MASK                                        0x00007FF0
+#define NV30_VP_SRC2_LOW_MASK                                         0x0000000F
+
+
+/* Source-register definition - matches NV20 exactly */
+#define NV30_VP_SRC_NEGATE          (1<<14)
+#define NV30_VP_SRC_SWZ_X_SHIFT        12
+#define NV30_VP_SRC_REG_SWZ_X_MASK        (0x03  <<12)
+#define NV30_VP_SRC_SWZ_Y_SHIFT        10
+#define NV30_VP_SRC_REG_SWZ_Y_MASK        (0x03  <<10)
+#define NV30_VP_SRC_SWZ_Z_SHIFT        8
+#define NV30_VP_SRC_REG_SWZ_Z_MASK        (0x03  << 8)
+#define NV30_VP_SRC_SWZ_W_SHIFT        6
+#define NV30_VP_SRC_REG_SWZ_W_MASK        (0x03  << 6)
+#define NV30_VP_SRC_REG_SWZ_ALL_SHIFT        6
+#define NV30_VP_SRC_REG_SWZ_ALL_MASK        (0xFF  << 6)
+#define NV30_VP_SRC_TEMP_SRC_SHIFT        2
+#define NV30_VP_SRC_REG_TEMP_ID_MASK        (0x0F  << 0)
+#define NV30_VP_SRC_REG_TYPE_SHIFT        0
+#define NV30_VP_SRC_REG_TYPE_MASK        (0x03  << 0)
+#define NV30_VP_SRC_REG_TYPE_TEMP  1
+#define NV30_VP_SRC_REG_TYPE_INPUT  2
+#define NV30_VP_SRC_REG_TYPE_CONST  3 /* guess */
+
+#include "nvfx_shader.h"
+
+#endif
diff --git a/src/gallium/drivers/nv30/nv30_winsys.h b/src/gallium/drivers/nv30/nv30_winsys.h
new file mode 100644 (file)
index 0000000..1db634e
--- /dev/null
@@ -0,0 +1,158 @@
+#ifndef __NV30_WINSYS_H__
+#define __NV30_WINSYS_H__
+
+#include <string.h>
+#include "nouveau/nouveau_winsys.h"
+#include "nouveau/nouveau_buffer.h"
+
+/*XXX: rnn */
+#define NV40_3D_VTXTEX_OFFSET(i) (0x0900 + ((i) * 0x20)) // 401e80
+#define NV40_3D_VTXTEX_FORMAT(i) (0x0904 + ((i) * 0x20)) // 401e90
+#define NV40_3D_VTXTEX_WRAP(i)   (0x0908 + ((i) * 0x20)) // 401ea0
+#define NV40_3D_VTXTEX_ENABLE(i) (0x090c + ((i) * 0x20)) // 401eb0
+#define NV40_3D_VTXTEX_SWZ(i)    (0x0910 + ((i) * 0x20)) // 401ec0
+#define NV40_3D_VTXTEX_FILTER(i) (0x0914 + ((i) * 0x20)) // 401ed0
+#define NV40_3D_VTXTEX_SIZE(i)   (0x0918 + ((i) * 0x20)) // 401ee0
+#define NV40_3D_VTXTEX_BCOL(i)   (0x091c + ((i) * 0x20)) // 401ef0
+#define NV30_3D_VTX_CACHE_INVALIDATE_1710 0x1710
+#define NV30_3D_R1718 0x1718
+#define NV40_3D_PRIM_RESTART_ENABLE 0x1dac
+#define NV40_3D_PRIM_RESTART_INDEX  0x1db0
+
+static INLINE void
+PUSH_RELOC(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t offset,
+      uint32_t flags, uint32_t vor, uint32_t tor)
+{
+   nouveau_pushbuf_reloc(push, bo, offset, flags, vor, tor);
+}
+
+static INLINE struct nouveau_bufctx *
+bufctx(struct nouveau_pushbuf *push)
+{
+   struct nouveau_bufctx **pctx = push->user_priv;
+   return *pctx;
+}
+
+static INLINE void
+PUSH_RESET(struct nouveau_pushbuf *push, int bin)
+{
+   nouveau_bufctx_reset(bufctx(push), bin);
+}
+
+static INLINE void
+PUSH_REFN(struct nouveau_pushbuf *push, int bin,
+     struct nouveau_bo *bo, uint32_t access)
+{
+   nouveau_bufctx_refn(bufctx(push), bin, bo, access);
+}
+
+static INLINE void
+PUSH_MTHDl(struct nouveau_pushbuf *push, int subc, int mthd, int bin,
+      struct nouveau_bo *bo, uint32_t offset, uint32_t access)
+{
+   nouveau_bufctx_mthd(bufctx(push), bin, (1 << 18) | (subc << 13) | mthd,
+                       bo, offset, access | NOUVEAU_BO_LOW, 0, 0)->priv = NULL;
+   PUSH_DATA(push, bo->offset + offset);
+}
+
+static INLINE void
+PUSH_MTHDo(struct nouveau_pushbuf *push, int subc, int mthd, int bin,
+      struct nouveau_bo *bo, uint32_t access, uint32_t vor, uint32_t tor)
+{
+   nouveau_bufctx_mthd(bufctx(push), bin, (1 << 18) | (subc << 13) | mthd,
+                       bo, 0, access | NOUVEAU_BO_OR, vor, tor)->priv = NULL;
+   if (bo->flags & NOUVEAU_BO_VRAM)
+      PUSH_DATA(push, vor);
+   else
+      PUSH_DATA(push, tor);
+}
+
+static INLINE void
+PUSH_MTHDs(struct nouveau_pushbuf *push, int subc, int mthd, int bin,
+      struct nouveau_bo *bo, uint32_t data, uint32_t access,
+      uint32_t vor, uint32_t tor)
+{
+   nouveau_bufctx_mthd(bufctx(push), bin, (1 << 18) | (subc << 13) | mthd,
+                       bo, data, access | NOUVEAU_BO_OR, vor, tor)->priv = NULL;
+   if (bo->flags & NOUVEAU_BO_VRAM)
+      PUSH_DATA(push, data | vor);
+   else
+      PUSH_DATA(push, data | tor);
+}
+
+static INLINE struct nouveau_bufref *
+PUSH_MTHD(struct nouveau_pushbuf *push, int subc, int mthd, int bin,
+     struct nouveau_bo *bo, uint32_t data, uint32_t access,
+     uint32_t vor, uint32_t tor)
+{
+   struct nouveau_bufref *bref =
+   nouveau_bufctx_mthd(bufctx(push), bin, (1 << 18) | (subc << 13) | mthd,
+                       bo, data, access | NOUVEAU_BO_OR, vor, tor);
+   if (access & NOUVEAU_BO_LOW)
+      data += bo->offset;
+   if (bo->flags & NOUVEAU_BO_VRAM)
+      data |= vor;
+   else
+      data |= tor;
+   PUSH_DATA(push, data);
+   bref->priv = NULL;
+   return bref;
+}
+
+static INLINE void
+PUSH_RESRC(struct nouveau_pushbuf *push, int subc, int mthd, int bin,
+           struct nv04_resource *r, uint32_t data, uint32_t access,
+           uint32_t vor, uint32_t tor)
+{
+   PUSH_MTHD(push, subc, mthd, bin, r->bo, r->offset + data,
+             r->domain | access, vor, tor)->priv = r;
+}
+
+static INLINE void
+BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, int size)
+{
+   PUSH_SPACE(push, size + 1);
+   PUSH_DATA (push, 0x00000000 | (size << 18) | (subc << 13) | mthd);
+}
+
+static INLINE void
+BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, int size)
+{
+   PUSH_SPACE(push, size + 1);
+   PUSH_DATA (push, 0x40000000 | (size << 18) | (subc << 13) | mthd);
+}
+
+/* subchannel assignment
+ *
+ * 0: <1.0.0 - used by kernel for m2mf
+ *     1.0.0 - used by kernel for nvsw
+ *
+ * 1: <1.0.0 - used by kernel for nvsw
+ *     1.0.0 - free for userspace
+ *
+ * 2-7: free for userspace on all kernel versions
+ */
+
+#define SUBC_M2MF(mthd)  2, (mthd)
+#define NV03_M2MF(mthd)  SUBC_M2MF(NV03_M2MF_##mthd)
+
+#define SUBC_SF2D(mthd)  3, (mthd)
+#define NV04_SF2D(mthd)  SUBC_SF2D(NV04_SURFACE_2D_##mthd)
+
+#define SUBC_SSWZ(mthd)  4, (mthd)
+#define NV04_SSWZ(mthd)  SUBC_SSWZ(NV04_SURFACE_SWZ_##mthd)
+
+#define SUBC_SIFM(mthd)  5, (mthd)
+#define NV03_SIFM(mthd)  SUBC_SIFM(NV03_SIFM_##mthd)
+#define NV05_SIFM(mthd)  SUBC_SIFM(NV05_SIFM_##mthd)
+
+#define SUBC_3D(mthd)    7, (mthd)
+#define NV30_3D(mthd)    SUBC_3D(NV30_3D_##mthd)
+#define NV40_3D(mthd)    SUBC_3D(NV40_3D_##mthd)
+
+#define NV01_SUBC(subc, mthd) SUBC_##subc((NV01_SUBCHAN_##mthd))
+#define NV11_SUBC(subc, mthd) SUBC_##subc((NV11_SUBCHAN_##mthd))
+
+#define NV04_GRAPH(subc, mthd) SUBC_##subc((NV04_GRAPH_##mthd))
+
+#endif
diff --git a/src/gallium/drivers/nv30/nv40_vertprog.h b/src/gallium/drivers/nv30/nv40_vertprog.h
new file mode 100644 (file)
index 0000000..c1f2208
--- /dev/null
@@ -0,0 +1,178 @@
+#ifndef __NV40_SHADER_H__
+#define __NV40_SHADER_H__
+
+/* Vertex programs instruction set
+ *
+ * The NV40 instruction set is very similar to NV30.  Most fields are in
+ * a slightly different position in the instruction however.
+ *
+ * Merged instructions
+ *     In some cases it is possible to put two instructions into one opcode
+ *     slot.  The rules for when this is OK is not entirely clear to me yet.
+ *
+ *     There are separate writemasks and dest temp register fields for each
+ *     grouping of instructions.  There is however only one field with the
+ *     ID of a result register.  Writing to temp/result regs is selected by
+ *     setting VEC_RESULT/SCA_RESULT.
+ *
+ * Temporary registers
+ *     The source/dest temp register fields have been extended by 1 bit, to
+ *     give a total of 32 temporary registers.
+ *
+ * Relative Addressing
+ *     NV40 can use an address register to index into vertex attribute regs.
+ *     This is done by putting the offset value into INPUT_SRC and setting
+ *     the INDEX_INPUT flag.
+ *
+ * Conditional execution (see NV_vertex_program{2,3} for details)
+ *     There is a second condition code register on NV40, it's use is enabled
+ *     by setting the COND_REG_SELECT_1 flag.
+ *
+ * Texture lookup
+ *     TODO
+ */
+
+/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */
+#define NV40_VP_INST_VEC_RESULT                                        (1 << 30)
+/* uncertain.. */
+#define NV40_VP_INST_COND_UPDATE_ENABLE                        ((1 << 14)|1<<29)
+/* use address reg as index into attribs */
+#define NV40_VP_INST_INDEX_INPUT                                       (1 << 27)
+#define NV40_VP_INST_SATURATE                                          (1 << 26)
+#define NV40_VP_INST_COND_REG_SELECT_1                                 (1 << 25)
+#define NV40_VP_INST_ADDR_REG_SELECT_1                                 (1 << 24)
+#define NV40_VP_INST_SRC2_ABS                                          (1 << 23)
+#define NV40_VP_INST_SRC1_ABS                                          (1 << 22)
+#define NV40_VP_INST_SRC0_ABS                                          (1 << 21)
+#define NV40_VP_INST_VEC_DEST_TEMP_SHIFT                                      15
+#define NV40_VP_INST_VEC_DEST_TEMP_MASK                             (0x3F << 15)
+#define NV40_VP_INST_COND_TEST_ENABLE                                  (1 << 13)
+#define NV40_VP_INST_COND_SHIFT                                               10
+#define NV40_VP_INST_COND_MASK                                       (0x7 << 10)
+#define NV40_VP_INST_COND_SWZ_X_SHIFT                                          8
+#define NV40_VP_INST_COND_SWZ_X_MASK                                    (3 << 8)
+#define NV40_VP_INST_COND_SWZ_Y_SHIFT                                          6
+#define NV40_VP_INST_COND_SWZ_Y_MASK                                    (3 << 6)
+#define NV40_VP_INST_COND_SWZ_Z_SHIFT                                          4
+#define NV40_VP_INST_COND_SWZ_Z_MASK                                    (3 << 4)
+#define NV40_VP_INST_COND_SWZ_W_SHIFT                                          2
+#define NV40_VP_INST_COND_SWZ_W_MASK                                    (3 << 2)
+#define NV40_VP_INST_COND_SWZ_ALL_SHIFT                                        2
+#define NV40_VP_INST_COND_SWZ_ALL_MASK                               (0xFF << 2)
+#define NV40_VP_INST_ADDR_SWZ_SHIFT                                            0
+#define NV40_VP_INST_ADDR_SWZ_MASK                                   (0x03 << 0)
+#define NV40_VP_INST0_KNOWN ( \
+                NV40_VP_INST_INDEX_INPUT | \
+                NV40_VP_INST_COND_REG_SELECT_1 | \
+                NV40_VP_INST_ADDR_REG_SELECT_1 | \
+                NV40_VP_INST_SRC2_ABS | \
+                NV40_VP_INST_SRC1_ABS | \
+                NV40_VP_INST_SRC0_ABS | \
+                NV40_VP_INST_VEC_DEST_TEMP_MASK | \
+                NV40_VP_INST_COND_TEST_ENABLE | \
+                NV40_VP_INST_COND_MASK | \
+                NV40_VP_INST_COND_SWZ_ALL_MASK | \
+                NV40_VP_INST_ADDR_SWZ_MASK)
+
+/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */
+#define NV40_VP_INST_VEC_OPCODE_SHIFT                                         22
+#define NV40_VP_INST_VEC_OPCODE_MASK                                (0x1F << 22)
+#define NV40_VP_INST_SCA_OPCODE_SHIFT                                         27
+#define NV40_VP_INST_SCA_OPCODE_MASK                                (0x1F << 27)
+#define NV40_VP_INST_CONST_SRC_SHIFT                                          12
+#define NV40_VP_INST_CONST_SRC_MASK                                 (0xFF << 12)
+#define NV40_VP_INST_INPUT_SRC_SHIFT                                           8
+#define NV40_VP_INST_INPUT_SRC_MASK                                  (0x0F << 8)
+#define NV40_VP_INST_SRC0H_SHIFT                                               0
+#define NV40_VP_INST_SRC0H_MASK                                      (0xFF << 0)
+#define NV40_VP_INST1_KNOWN ( \
+                NV40_VP_INST_VEC_OPCODE_MASK | \
+                NV40_VP_INST_SCA_OPCODE_MASK | \
+                NV40_VP_INST_CONST_SRC_MASK  | \
+                NV40_VP_INST_INPUT_SRC_MASK  | \
+                NV40_VP_INST_SRC0H_MASK \
+                )
+
+/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */
+#define NV40_VP_INST_SRC0L_SHIFT                                              23
+#define NV40_VP_INST_SRC0L_MASK                                    (0x1FF << 23)
+#define NV40_VP_INST_SRC1_SHIFT                                                6
+#define NV40_VP_INST_SRC1_MASK                                    (0x1FFFF << 6)
+#define NV40_VP_INST_SRC2H_SHIFT                                               0
+#define NV40_VP_INST_SRC2H_MASK                                      (0x3F << 0)
+#define NV40_VP_INST_IADDRH_SHIFT                                              0
+#define NV40_VP_INST_IADDRH_MASK                                     (0x3F << 0)
+
+/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */
+#define NV40_VP_INST_IADDRL_SHIFT                                             29
+#define NV40_VP_INST_IADDRL_MASK                                       (7 << 29)
+#define NV40_VP_INST_SRC2L_SHIFT                                              21
+#define NV40_VP_INST_SRC2L_MASK                                    (0x7FF << 21)
+#define NV40_VP_INST_SCA_WRITEMASK_SHIFT                                      17
+#define NV40_VP_INST_SCA_WRITEMASK_MASK                              (0xF << 17)
+#    define NV40_VP_INST_SCA_WRITEMASK_X                               (1 << 20)
+#    define NV40_VP_INST_SCA_WRITEMASK_Y                               (1 << 19)
+#    define NV40_VP_INST_SCA_WRITEMASK_Z                               (1 << 18)
+#    define NV40_VP_INST_SCA_WRITEMASK_W                               (1 << 17)
+#define NV40_VP_INST_VEC_WRITEMASK_SHIFT                                      13
+#define NV40_VP_INST_VEC_WRITEMASK_MASK                              (0xF << 13)
+#    define NV40_VP_INST_VEC_WRITEMASK_X                               (1 << 16)
+#    define NV40_VP_INST_VEC_WRITEMASK_Y                               (1 << 15)
+#    define NV40_VP_INST_VEC_WRITEMASK_Z                               (1 << 14)
+#    define NV40_VP_INST_VEC_WRITEMASK_W                               (1 << 13)
+#define NV40_VP_INST_SCA_RESULT                                        (1 << 12)
+#define NV40_VP_INST_SCA_DEST_TEMP_SHIFT                                       7
+#define NV40_VP_INST_SCA_DEST_TEMP_MASK                              (0x1F << 7)
+#define NV40_VP_INST_DEST_SHIFT                                                2
+#define NV40_VP_INST_DEST_MASK                                         (31 << 2)
+#    define NV40_VP_INST_DEST_POS                                              0
+#    define NV40_VP_INST_DEST_COL0                                             1
+#    define NV40_VP_INST_DEST_COL1                                             2
+#    define NV40_VP_INST_DEST_BFC0                                             3
+#    define NV40_VP_INST_DEST_BFC1                                             4
+#    define NV40_VP_INST_DEST_FOGC                                             5
+#    define NV40_VP_INST_DEST_PSZ                                              6
+#    define NV40_VP_INST_DEST_TC0                                              7
+#    define NV40_VP_INST_DEST_TC(n)                                        (7+n)
+#    define NV40_VP_INST_DEST_TEMP                                          0x1F
+#define NV40_VP_INST_INDEX_CONST                                        (1 << 1)
+#define NV40_VP_INST3_KNOWN ( \
+                NV40_VP_INST_SRC2L_MASK |\
+                NV40_VP_INST_SCA_WRITEMASK_MASK |\
+                NV40_VP_INST_VEC_WRITEMASK_MASK |\
+                NV40_VP_INST_SCA_DEST_TEMP_MASK |\
+                NV40_VP_INST_DEST_MASK |\
+                NV40_VP_INST_INDEX_CONST)
+
+/* Useful to split the source selection regs into their pieces */
+#define NV40_VP_SRC0_HIGH_SHIFT                                                9
+#define NV40_VP_SRC0_HIGH_MASK                                        0x0001FE00
+#define NV40_VP_SRC0_LOW_MASK                                         0x000001FF
+#define NV40_VP_SRC2_HIGH_SHIFT                                               11
+#define NV40_VP_SRC2_HIGH_MASK                                        0x0001F800
+#define NV40_VP_SRC2_LOW_MASK                                         0x000007FF
+
+/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */
+#define NV40_VP_SRC_NEGATE                                             (1 << 16)
+#define NV40_VP_SRC_SWZ_X_SHIFT                                               14
+#define NV40_VP_SRC_SWZ_X_MASK                                         (3 << 14)
+#define NV40_VP_SRC_SWZ_Y_SHIFT                                               12
+#define NV40_VP_SRC_SWZ_Y_MASK                                         (3 << 12)
+#define NV40_VP_SRC_SWZ_Z_SHIFT                                               10
+#define NV40_VP_SRC_SWZ_Z_MASK                                         (3 << 10)
+#define NV40_VP_SRC_SWZ_W_SHIFT                                                8
+#define NV40_VP_SRC_SWZ_W_MASK                                          (3 << 8)
+#define NV40_VP_SRC_SWZ_ALL_SHIFT                                              8
+#define NV40_VP_SRC_SWZ_ALL_MASK                                     (0xFF << 8)
+#define NV40_VP_SRC_TEMP_SRC_SHIFT                                             2
+#define NV40_VP_SRC_TEMP_SRC_MASK                                    (0x1F << 2)
+#define NV40_VP_SRC_REG_TYPE_SHIFT                                             0
+#define NV40_VP_SRC_REG_TYPE_MASK                                       (3 << 0)
+#    define NV40_VP_SRC_REG_TYPE_UNK0                                          0
+#    define NV40_VP_SRC_REG_TYPE_TEMP                                          1
+#    define NV40_VP_SRC_REG_TYPE_INPUT                                         2
+#    define NV40_VP_SRC_REG_TYPE_CONST                                         3
+
+#include "nvfx_shader.h"
+
+#endif
diff --git a/src/gallium/drivers/nv30/nv40_verttex.c b/src/gallium/drivers/nv30/nv40_verttex.c
new file mode 100644 (file)
index 0000000..06fcc6f
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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
+ * THE AUTHORS 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.
+ *
+ * Authors: Ben Skeggs
+ *
+ */
+
+#include "util/u_inlines.h"
+#include "nv30_context.h"
+
+void
+nv40_verttex_validate(struct nv30_context *nv30)
+{
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
+   unsigned dirty = nv30->vertprog.dirty_samplers;
+
+   while (dirty) {
+      unsigned unit = ffs(dirty) - 1;
+      struct nv30_sampler_view *sv = (void *)nv30->fragprog.textures[unit];
+      struct nv30_sampler_state *ss = nv30->fragprog.samplers[unit];
+
+      if (ss && sv) {
+      } else {
+         BEGIN_NV04(push, NV40_3D(VTXTEX_ENABLE(unit)), 1);
+         PUSH_DATA (push, 0);
+      }
+   }
+
+   nv30->vertprog.dirty_samplers = 0;
+}
+
+static void
+nv40_verttex_sampler_states_bind(struct pipe_context *pipe,
+                                 unsigned nr, void **hwcso)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   unsigned i;
+
+   for (i = 0; i < nr; i++) {
+      nv30->vertprog.samplers[i] = hwcso[i];
+      nv30->vertprog.dirty_samplers |= (1 << i);
+   }
+
+   for (; i < nv30->vertprog.num_samplers; i++) {
+      nv30->vertprog.samplers[i] = NULL;
+      nv30->vertprog.dirty_samplers |= (1 << i);
+   }
+
+   nv30->vertprog.num_samplers = nr;
+   nv30->dirty |= NV30_NEW_VERTTEX;
+}
+
+
+static void
+nv40_verttex_set_sampler_views(struct pipe_context *pipe, unsigned nr,
+                               struct pipe_sampler_view **views)
+{
+   struct nv30_context *nv30 = nv30_context(pipe);
+   unsigned i;
+
+   for (i = 0; i < nr; i++) {
+      nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VERTTEX(i));
+      pipe_sampler_view_reference(&nv30->vertprog.textures[i], views[i]);
+      nv30->vertprog.dirty_samplers |= (1 << i);
+   }
+
+   for (; i < nv30->vertprog.num_textures; i++) {
+      nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VERTTEX(i));
+      pipe_sampler_view_reference(&nv30->vertprog.textures[i], NULL);
+      nv30->vertprog.dirty_samplers |= (1 << i);
+   }
+
+   nv30->vertprog.num_textures = nr;
+   nv30->dirty |= NV30_NEW_VERTTEX;
+}
+
+void
+nv40_verttex_init(struct pipe_context *pipe)
+{
+   pipe->bind_vertex_sampler_states = nv40_verttex_sampler_states_bind;
+   pipe->set_vertex_sampler_views = nv40_verttex_set_sampler_views;
+}
diff --git a/src/gallium/drivers/nv30/nvfx_fragprog.c b/src/gallium/drivers/nv30/nvfx_fragprog.c
new file mode 100644 (file)
index 0000000..e562b45
--- /dev/null
@@ -0,0 +1,1241 @@
+#include <float.h>
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+#include "util/u_linkage.h"
+#include "util/u_inlines.h"
+#include "util/u_debug.h"
+
+#include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_util.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_ureg.h"
+
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nvfx_shader.h"
+
+struct nvfx_fpc {
+   struct nv30_fragprog *fp;
+
+   unsigned max_temps;
+   unsigned long long r_temps;
+   unsigned long long r_temps_discard;
+   struct nvfx_reg r_result[PIPE_MAX_SHADER_OUTPUTS];
+   struct nvfx_reg r_input[PIPE_MAX_SHADER_INPUTS];
+   struct nvfx_reg *r_temp;
+
+   int num_regs;
+
+   unsigned inst_offset;
+   unsigned have_const;
+
+   struct util_dynarray imm_data;
+
+   struct nvfx_reg* r_imm;
+   unsigned nr_imm;
+
+   struct util_dynarray if_stack;
+   //struct util_dynarray loop_stack;
+   struct util_dynarray label_relocs;
+};
+
+static INLINE struct nvfx_reg
+temp(struct nvfx_fpc *fpc)
+{
+   int idx = __builtin_ctzll(~fpc->r_temps);
+
+   if (idx >= fpc->max_temps) {
+      NOUVEAU_ERR("out of temps!!\n");
+      assert(0);
+      return nvfx_reg(NVFXSR_TEMP, 0);
+   }
+
+   fpc->r_temps |= (1ULL << idx);
+   fpc->r_temps_discard |= (1ULL << idx);
+   return nvfx_reg(NVFXSR_TEMP, idx);
+}
+
+static INLINE void
+release_temps(struct nvfx_fpc *fpc)
+{
+   fpc->r_temps &= ~fpc->r_temps_discard;
+   fpc->r_temps_discard = 0ULL;
+}
+
+static inline struct nvfx_reg
+nvfx_fp_imm(struct nvfx_fpc *fpc, float a, float b, float c, float d)
+{
+   float v[4] = {a, b, c, d};
+   int idx = fpc->imm_data.size >> 4;
+
+   memcpy(util_dynarray_grow(&fpc->imm_data, sizeof(float) * 4), v, 4 * sizeof(float));
+   return nvfx_reg(NVFXSR_IMM, idx);
+}
+
+static void
+grow_insns(struct nvfx_fpc *fpc, int size)
+{
+   struct nv30_fragprog *fp = fpc->fp;
+
+   fp->insn_len += size;
+   fp->insn = realloc(fp->insn, sizeof(uint32_t) * fp->insn_len);
+}
+
+static void
+emit_src(struct nvfx_fpc *fpc, int pos, struct nvfx_src src)
+{
+   struct nv30_fragprog *fp = fpc->fp;
+   uint32_t *hw = &fp->insn[fpc->inst_offset];
+   uint32_t sr = 0;
+
+   switch (src.reg.type) {
+   case NVFXSR_INPUT:
+      sr |= (NVFX_FP_REG_TYPE_INPUT << NVFX_FP_REG_TYPE_SHIFT);
+      hw[0] |= (src.reg.index << NVFX_FP_OP_INPUT_SRC_SHIFT);
+      break;
+   case NVFXSR_OUTPUT:
+      sr |= NVFX_FP_REG_SRC_HALF;
+      /* fall-through */
+   case NVFXSR_TEMP:
+      sr |= (NVFX_FP_REG_TYPE_TEMP << NVFX_FP_REG_TYPE_SHIFT);
+      sr |= (src.reg.index << NVFX_FP_REG_SRC_SHIFT);
+      break;
+   case NVFXSR_IMM:
+      if (!fpc->have_const) {
+         grow_insns(fpc, 4);
+         hw = &fp->insn[fpc->inst_offset];
+         fpc->have_const = 1;
+      }
+
+      memcpy(&fp->insn[fpc->inst_offset + 4],
+            (float*)fpc->imm_data.data + src.reg.index * 4,
+            sizeof(uint32_t) * 4);
+
+      sr |= (NVFX_FP_REG_TYPE_CONST << NVFX_FP_REG_TYPE_SHIFT);
+      break;
+   case NVFXSR_CONST:
+      if (!fpc->have_const) {
+         grow_insns(fpc, 4);
+         hw = &fp->insn[fpc->inst_offset];
+         fpc->have_const = 1;
+      }
+
+      {
+         struct nv30_fragprog_data *fpd;
+
+         fp->consts = realloc(fp->consts, ++fp->nr_consts *
+                    sizeof(*fpd));
+         fpd = &fp->consts[fp->nr_consts - 1];
+         fpd->offset = fpc->inst_offset + 4;
+         fpd->index = src.reg.index;
+         memset(&fp->insn[fpd->offset], 0, sizeof(uint32_t) * 4);
+      }
+
+      sr |= (NVFX_FP_REG_TYPE_CONST << NVFX_FP_REG_TYPE_SHIFT);
+      break;
+   case NVFXSR_NONE:
+      sr |= (NVFX_FP_REG_TYPE_INPUT << NVFX_FP_REG_TYPE_SHIFT);
+      break;
+   default:
+      assert(0);
+   }
+
+   if (src.negate)
+      sr |= NVFX_FP_REG_NEGATE;
+
+   if (src.abs)
+      hw[1] |= (1 << (29 + pos));
+
+   sr |= ((src.swz[0] << NVFX_FP_REG_SWZ_X_SHIFT) |
+          (src.swz[1] << NVFX_FP_REG_SWZ_Y_SHIFT) |
+          (src.swz[2] << NVFX_FP_REG_SWZ_Z_SHIFT) |
+          (src.swz[3] << NVFX_FP_REG_SWZ_W_SHIFT));
+
+   hw[pos + 1] |= sr;
+}
+
+static void
+emit_dst(struct nvfx_fpc *fpc, struct nvfx_reg dst)
+{
+   struct nv30_fragprog *fp = fpc->fp;
+   uint32_t *hw = &fp->insn[fpc->inst_offset];
+
+   switch (dst.type) {
+   case NVFXSR_OUTPUT:
+      if (dst.index == 1)
+         fp->fp_control |= 0x0000000e;
+      else {
+         hw[0] |= NVFX_FP_OP_OUT_REG_HALF;
+         dst.index <<= 1;
+      }
+      /* fall-through */
+   case NVFXSR_TEMP:
+      if (fpc->num_regs < (dst.index + 1))
+         fpc->num_regs = dst.index + 1;
+      break;
+   case NVFXSR_NONE:
+      hw[0] |= (1 << 30);
+      break;
+   default:
+      assert(0);
+   }
+
+   hw[0] |= (dst.index << NVFX_FP_OP_OUT_REG_SHIFT);
+}
+
+static void
+nvfx_fp_emit(struct nvfx_fpc *fpc, struct nvfx_insn insn)
+{
+   struct nv30_fragprog *fp = fpc->fp;
+   uint32_t *hw;
+
+   fpc->inst_offset = fp->insn_len;
+   fpc->have_const = 0;
+   grow_insns(fpc, 4);
+   hw = &fp->insn[fpc->inst_offset];
+   memset(hw, 0, sizeof(uint32_t) * 4);
+
+   if (insn.op == NVFX_FP_OP_OPCODE_KIL)
+      fp->fp_control |= NV30_3D_FP_CONTROL_USES_KIL;
+   hw[0] |= (insn.op << NVFX_FP_OP_OPCODE_SHIFT);
+   hw[0] |= (insn.mask << NVFX_FP_OP_OUTMASK_SHIFT);
+   hw[2] |= (insn.scale << NVFX_FP_OP_DST_SCALE_SHIFT);
+
+   if (insn.sat)
+      hw[0] |= NVFX_FP_OP_OUT_SAT;
+
+   if (insn.cc_update)
+      hw[0] |= NVFX_FP_OP_COND_WRITE_ENABLE;
+   hw[1] |= (insn.cc_test << NVFX_FP_OP_COND_SHIFT);
+   hw[1] |= ((insn.cc_swz[0] << NVFX_FP_OP_COND_SWZ_X_SHIFT) |
+        (insn.cc_swz[1] << NVFX_FP_OP_COND_SWZ_Y_SHIFT) |
+        (insn.cc_swz[2] << NVFX_FP_OP_COND_SWZ_Z_SHIFT) |
+        (insn.cc_swz[3] << NVFX_FP_OP_COND_SWZ_W_SHIFT));
+
+   if(insn.unit >= 0)
+   {
+      hw[0] |= (insn.unit << NVFX_FP_OP_TEX_UNIT_SHIFT);
+      fp->samplers |= (1 << insn.unit);
+   }
+
+   emit_dst(fpc, insn.dst);
+   emit_src(fpc, 0, insn.src[0]);
+   emit_src(fpc, 1, insn.src[1]);
+   emit_src(fpc, 2, insn.src[2]);
+}
+
+#define arith(s,o,d,m,s0,s1,s2) \
+       nvfx_insn((s), NVFX_FP_OP_OPCODE_##o, -1, \
+                       (d), (m), (s0), (s1), (s2))
+
+#define tex(s,o,u,d,m,s0,s1,s2) \
+   nvfx_insn((s), NVFX_FP_OP_OPCODE_##o, (u), \
+                   (d), (m), (s0), none, none)
+
+/* IF src.x != 0, as TGSI specifies */
+static void
+nv40_fp_if(struct nvfx_fpc *fpc, struct nvfx_src src)
+{
+   const struct nvfx_src none = nvfx_src(nvfx_reg(NVFXSR_NONE, 0));
+   struct nvfx_insn insn = arith(0, MOV, none.reg, NVFX_FP_MASK_X, src, none, none);
+   uint32_t *hw;
+   insn.cc_update = 1;
+   nvfx_fp_emit(fpc, insn);
+
+   fpc->inst_offset = fpc->fp->insn_len;
+   grow_insns(fpc, 4);
+   hw = &fpc->fp->insn[fpc->inst_offset];
+   /* I really wonder why fp16 precision is used. Presumably the hardware ignores it? */
+   hw[0] = (NV40_FP_OP_BRA_OPCODE_IF << NVFX_FP_OP_OPCODE_SHIFT) |
+      NV40_FP_OP_OUT_NONE |
+      (NVFX_FP_PRECISION_FP16 << NVFX_FP_OP_PRECISION_SHIFT);
+   /* Use .xxxx swizzle so that we check only src[0].x*/
+   hw[1] = (0 << NVFX_FP_OP_COND_SWZ_X_SHIFT) |
+         (0 << NVFX_FP_OP_COND_SWZ_Y_SHIFT) |
+         (0 << NVFX_FP_OP_COND_SWZ_Z_SHIFT) |
+         (0 << NVFX_FP_OP_COND_SWZ_W_SHIFT) |
+         (NVFX_FP_OP_COND_NE << NVFX_FP_OP_COND_SHIFT);
+   hw[2] = 0; /* | NV40_FP_OP_OPCODE_IS_BRANCH | else_offset */
+   hw[3] = 0; /* | endif_offset */
+   util_dynarray_append(&fpc->if_stack, unsigned, fpc->inst_offset);
+}
+
+/* IF src.x != 0, as TGSI specifies */
+static void
+nv40_fp_cal(struct nvfx_fpc *fpc, unsigned target)
+{
+        struct nvfx_relocation reloc;
+        uint32_t *hw;
+        fpc->inst_offset = fpc->fp->insn_len;
+        grow_insns(fpc, 4);
+        hw = &fpc->fp->insn[fpc->inst_offset];
+        /* I really wonder why fp16 precision is used. Presumably the hardware ignores it? */
+        hw[0] = (NV40_FP_OP_BRA_OPCODE_CAL << NVFX_FP_OP_OPCODE_SHIFT);
+        /* Use .xxxx swizzle so that we check only src[0].x*/
+        hw[1] = (NVFX_SWZ_IDENTITY << NVFX_FP_OP_COND_SWZ_ALL_SHIFT) |
+                        (NVFX_FP_OP_COND_TR << NVFX_FP_OP_COND_SHIFT);
+        hw[2] = NV40_FP_OP_OPCODE_IS_BRANCH; /* | call_offset */
+        hw[3] = 0;
+        reloc.target = target;
+        reloc.location = fpc->inst_offset + 2;
+        util_dynarray_append(&fpc->label_relocs, struct nvfx_relocation, reloc);
+}
+
+static void
+nv40_fp_ret(struct nvfx_fpc *fpc)
+{
+   uint32_t *hw;
+   fpc->inst_offset = fpc->fp->insn_len;
+   grow_insns(fpc, 4);
+   hw = &fpc->fp->insn[fpc->inst_offset];
+   /* I really wonder why fp16 precision is used. Presumably the hardware ignores it? */
+   hw[0] = (NV40_FP_OP_BRA_OPCODE_RET << NVFX_FP_OP_OPCODE_SHIFT);
+   /* Use .xxxx swizzle so that we check only src[0].x*/
+   hw[1] = (NVFX_SWZ_IDENTITY << NVFX_FP_OP_COND_SWZ_ALL_SHIFT) |
+         (NVFX_FP_OP_COND_TR << NVFX_FP_OP_COND_SHIFT);
+   hw[2] = NV40_FP_OP_OPCODE_IS_BRANCH; /* | call_offset */
+   hw[3] = 0;
+}
+
+static void
+nv40_fp_rep(struct nvfx_fpc *fpc, unsigned count, unsigned target)
+{
+        struct nvfx_relocation reloc;
+        uint32_t *hw;
+        fpc->inst_offset = fpc->fp->insn_len;
+        grow_insns(fpc, 4);
+        hw = &fpc->fp->insn[fpc->inst_offset];
+        /* I really wonder why fp16 precision is used. Presumably the hardware ignores it? */
+        hw[0] = (NV40_FP_OP_BRA_OPCODE_REP << NVFX_FP_OP_OPCODE_SHIFT) |
+                        NV40_FP_OP_OUT_NONE |
+                        (NVFX_FP_PRECISION_FP16 << NVFX_FP_OP_PRECISION_SHIFT);
+        /* Use .xxxx swizzle so that we check only src[0].x*/
+        hw[1] = (NVFX_SWZ_IDENTITY << NVFX_FP_OP_COND_SWZ_ALL_SHIFT) |
+                        (NVFX_FP_OP_COND_TR << NVFX_FP_OP_COND_SHIFT);
+        hw[2] = NV40_FP_OP_OPCODE_IS_BRANCH |
+                        (count << NV40_FP_OP_REP_COUNT1_SHIFT) |
+                        (count << NV40_FP_OP_REP_COUNT2_SHIFT) |
+                        (count << NV40_FP_OP_REP_COUNT3_SHIFT);
+        hw[3] = 0; /* | end_offset */
+        reloc.target = target;
+        reloc.location = fpc->inst_offset + 3;
+        util_dynarray_append(&fpc->label_relocs, struct nvfx_relocation, reloc);
+        //util_dynarray_append(&fpc->loop_stack, unsigned, target);
+}
+
+/* warning: this only works forward, and probably only if not inside any IF */
+static void
+nv40_fp_bra(struct nvfx_fpc *fpc, unsigned target)
+{
+        struct nvfx_relocation reloc;
+        uint32_t *hw;
+        fpc->inst_offset = fpc->fp->insn_len;
+        grow_insns(fpc, 4);
+        hw = &fpc->fp->insn[fpc->inst_offset];
+        /* I really wonder why fp16 precision is used. Presumably the hardware ignores it? */
+        hw[0] = (NV40_FP_OP_BRA_OPCODE_IF << NVFX_FP_OP_OPCODE_SHIFT) |
+                NV40_FP_OP_OUT_NONE |
+                (NVFX_FP_PRECISION_FP16 << NVFX_FP_OP_PRECISION_SHIFT);
+        /* Use .xxxx swizzle so that we check only src[0].x*/
+        hw[1] = (NVFX_SWZ_IDENTITY << NVFX_FP_OP_COND_SWZ_X_SHIFT) |
+                        (NVFX_FP_OP_COND_FL << NVFX_FP_OP_COND_SHIFT);
+        hw[2] = NV40_FP_OP_OPCODE_IS_BRANCH; /* | else_offset */
+        hw[3] = 0; /* | endif_offset */
+        reloc.target = target;
+        reloc.location = fpc->inst_offset + 2;
+        util_dynarray_append(&fpc->label_relocs, struct nvfx_relocation, reloc);
+        reloc.target = target;
+        reloc.location = fpc->inst_offset + 3;
+        util_dynarray_append(&fpc->label_relocs, struct nvfx_relocation, reloc);
+}
+
+static void
+nv40_fp_brk(struct nvfx_fpc *fpc)
+{
+   uint32_t *hw;
+   fpc->inst_offset = fpc->fp->insn_len;
+   grow_insns(fpc, 4);
+   hw = &fpc->fp->insn[fpc->inst_offset];
+   /* I really wonder why fp16 precision is used. Presumably the hardware ignores it? */
+   hw[0] = (NV40_FP_OP_BRA_OPCODE_BRK << NVFX_FP_OP_OPCODE_SHIFT) |
+      NV40_FP_OP_OUT_NONE;
+   /* Use .xxxx swizzle so that we check only src[0].x*/
+   hw[1] = (NVFX_SWZ_IDENTITY << NVFX_FP_OP_COND_SWZ_X_SHIFT) |
+         (NVFX_FP_OP_COND_TR << NVFX_FP_OP_COND_SHIFT);
+   hw[2] = NV40_FP_OP_OPCODE_IS_BRANCH;
+   hw[3] = 0;
+}
+
+static INLINE struct nvfx_src
+tgsi_src(struct nvfx_fpc *fpc, const struct tgsi_full_src_register *fsrc)
+{
+   struct nvfx_src src;
+
+   switch (fsrc->Register.File) {
+   case TGSI_FILE_INPUT:
+      src.reg = fpc->r_input[fsrc->Register.Index];
+      break;
+   case TGSI_FILE_CONSTANT:
+      src.reg = nvfx_reg(NVFXSR_CONST, fsrc->Register.Index);
+      break;
+   case TGSI_FILE_IMMEDIATE:
+      assert(fsrc->Register.Index < fpc->nr_imm);
+      src.reg = fpc->r_imm[fsrc->Register.Index];
+      break;
+   case TGSI_FILE_TEMPORARY:
+      src.reg = fpc->r_temp[fsrc->Register.Index];
+      break;
+   /* NV40 fragprog result regs are just temps, so this is simple */
+   case TGSI_FILE_OUTPUT:
+      src.reg = fpc->r_result[fsrc->Register.Index];
+      break;
+   default:
+      NOUVEAU_ERR("bad src file\n");
+      src.reg.index = 0;
+      src.reg.type = 0;
+      break;
+   }
+
+   src.abs = fsrc->Register.Absolute;
+   src.negate = fsrc->Register.Negate;
+   src.swz[0] = fsrc->Register.SwizzleX;
+   src.swz[1] = fsrc->Register.SwizzleY;
+   src.swz[2] = fsrc->Register.SwizzleZ;
+   src.swz[3] = fsrc->Register.SwizzleW;
+   src.indirect = 0;
+   src.indirect_reg = 0;
+   src.indirect_swz = 0;
+   return src;
+}
+
+static INLINE struct nvfx_reg
+tgsi_dst(struct nvfx_fpc *fpc, const struct tgsi_full_dst_register *fdst) {
+   switch (fdst->Register.File) {
+   case TGSI_FILE_OUTPUT:
+      return fpc->r_result[fdst->Register.Index];
+   case TGSI_FILE_TEMPORARY:
+      return fpc->r_temp[fdst->Register.Index];
+   case TGSI_FILE_NULL:
+      return nvfx_reg(NVFXSR_NONE, 0);
+   default:
+      NOUVEAU_ERR("bad dst file %d\n", fdst->Register.File);
+      return nvfx_reg(NVFXSR_NONE, 0);
+   }
+}
+
+static INLINE int
+tgsi_mask(uint tgsi)
+{
+   int mask = 0;
+
+   if (tgsi & TGSI_WRITEMASK_X) mask |= NVFX_FP_MASK_X;
+   if (tgsi & TGSI_WRITEMASK_Y) mask |= NVFX_FP_MASK_Y;
+   if (tgsi & TGSI_WRITEMASK_Z) mask |= NVFX_FP_MASK_Z;
+   if (tgsi & TGSI_WRITEMASK_W) mask |= NVFX_FP_MASK_W;
+   return mask;
+}
+
+static boolean
+nvfx_fragprog_parse_instruction(struct nv30_context* nvfx, struct nvfx_fpc *fpc,
+            const struct tgsi_full_instruction *finst)
+{
+   const struct nvfx_src none = nvfx_src(nvfx_reg(NVFXSR_NONE, 0));
+   struct nvfx_insn insn;
+   struct nvfx_src src[3], tmp;
+   struct nvfx_reg dst;
+   int mask, sat, unit = 0;
+   int ai = -1, ci = -1, ii = -1;
+   int i;
+
+   if (finst->Instruction.Opcode == TGSI_OPCODE_END)
+      return TRUE;
+
+   for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
+      const struct tgsi_full_src_register *fsrc;
+
+      fsrc = &finst->Src[i];
+      if (fsrc->Register.File == TGSI_FILE_TEMPORARY) {
+         src[i] = tgsi_src(fpc, fsrc);
+      }
+   }
+
+   for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
+      const struct tgsi_full_src_register *fsrc;
+
+      fsrc = &finst->Src[i];
+
+      switch (fsrc->Register.File) {
+      case TGSI_FILE_INPUT:
+         if(fpc->fp->info.input_semantic_name[fsrc->Register.Index] == TGSI_SEMANTIC_FOG && (0
+               || fsrc->Register.SwizzleX == PIPE_SWIZZLE_ALPHA
+               || fsrc->Register.SwizzleY == PIPE_SWIZZLE_ALPHA
+               || fsrc->Register.SwizzleZ == PIPE_SWIZZLE_ALPHA
+               || fsrc->Register.SwizzleW == PIPE_SWIZZLE_ALPHA
+               )) {
+            /* hardware puts 0 in fogcoord.w, but GL/Gallium want 1 there */
+            struct nvfx_src addend = nvfx_src(nvfx_fp_imm(fpc, 0, 0, 0, 1));
+            addend.swz[0] = fsrc->Register.SwizzleX;
+            addend.swz[1] = fsrc->Register.SwizzleY;
+            addend.swz[2] = fsrc->Register.SwizzleZ;
+            addend.swz[3] = fsrc->Register.SwizzleW;
+            src[i] = nvfx_src(temp(fpc));
+            nvfx_fp_emit(fpc, arith(0, ADD, src[i].reg, NVFX_FP_MASK_ALL, tgsi_src(fpc, fsrc), addend, none));
+         } else if (ai == -1 || ai == fsrc->Register.Index) {
+            ai = fsrc->Register.Index;
+            src[i] = tgsi_src(fpc, fsrc);
+         } else {
+            src[i] = nvfx_src(temp(fpc));
+            nvfx_fp_emit(fpc, arith(0, MOV, src[i].reg, NVFX_FP_MASK_ALL, tgsi_src(fpc, fsrc), none, none));
+         }
+         break;
+      case TGSI_FILE_CONSTANT:
+         if ((ci == -1 && ii == -1) ||
+             ci == fsrc->Register.Index) {
+            ci = fsrc->Register.Index;
+            src[i] = tgsi_src(fpc, fsrc);
+         } else {
+            src[i] = nvfx_src(temp(fpc));
+            nvfx_fp_emit(fpc, arith(0, MOV, src[i].reg, NVFX_FP_MASK_ALL, tgsi_src(fpc, fsrc), none, none));
+         }
+         break;
+      case TGSI_FILE_IMMEDIATE:
+         if ((ci == -1 && ii == -1) ||
+             ii == fsrc->Register.Index) {
+            ii = fsrc->Register.Index;
+            src[i] = tgsi_src(fpc, fsrc);
+         } else {
+            src[i] = nvfx_src(temp(fpc));
+            nvfx_fp_emit(fpc, arith(0, MOV, src[i].reg, NVFX_FP_MASK_ALL, tgsi_src(fpc, fsrc), none, none));
+         }
+         break;
+      case TGSI_FILE_TEMPORARY:
+         /* handled above */
+         break;
+      case TGSI_FILE_SAMPLER:
+         unit = fsrc->Register.Index;
+         break;
+      case TGSI_FILE_OUTPUT:
+         break;
+      default:
+         NOUVEAU_ERR("bad src file\n");
+         return FALSE;
+      }
+   }
+
+   dst  = tgsi_dst(fpc, &finst->Dst[0]);
+   mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
+   sat  = (finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE);
+
+   switch (finst->Instruction.Opcode) {
+   case TGSI_OPCODE_ABS:
+      nvfx_fp_emit(fpc, arith(sat, MOV, dst, mask, abs(src[0]), none, none));
+      break;
+   case TGSI_OPCODE_ADD:
+      nvfx_fp_emit(fpc, arith(sat, ADD, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_CMP:
+      insn = arith(0, MOV, none.reg, mask, src[0], none, none);
+      insn.cc_update = 1;
+      nvfx_fp_emit(fpc, insn);
+
+      insn = arith(sat, MOV, dst, mask, src[2], none, none);
+      insn.cc_test = NVFX_COND_GE;
+      nvfx_fp_emit(fpc, insn);
+
+      insn = arith(sat, MOV, dst, mask, src[1], none, none);
+      insn.cc_test = NVFX_COND_LT;
+      nvfx_fp_emit(fpc, insn);
+      break;
+   case TGSI_OPCODE_COS:
+      nvfx_fp_emit(fpc, arith(sat, COS, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_DDX:
+      if (mask & (NVFX_FP_MASK_Z | NVFX_FP_MASK_W)) {
+         tmp = nvfx_src(temp(fpc));
+         nvfx_fp_emit(fpc, arith(sat, DDX, tmp.reg, NVFX_FP_MASK_X | NVFX_FP_MASK_Y, swz(src[0], Z, W, Z, W), none, none));
+         nvfx_fp_emit(fpc, arith(0, MOV, tmp.reg, NVFX_FP_MASK_Z | NVFX_FP_MASK_W, swz(tmp, X, Y, X, Y), none, none));
+         nvfx_fp_emit(fpc, arith(sat, DDX, tmp.reg, NVFX_FP_MASK_X | NVFX_FP_MASK_Y, src[0], none, none));
+         nvfx_fp_emit(fpc, arith(0, MOV, dst, mask, tmp, none, none));
+      } else {
+         nvfx_fp_emit(fpc, arith(sat, DDX, dst, mask, src[0], none, none));
+      }
+      break;
+   case TGSI_OPCODE_DDY:
+      if (mask & (NVFX_FP_MASK_Z | NVFX_FP_MASK_W)) {
+         tmp = nvfx_src(temp(fpc));
+         nvfx_fp_emit(fpc, arith(sat, DDY, tmp.reg, NVFX_FP_MASK_X | NVFX_FP_MASK_Y, swz(src[0], Z, W, Z, W), none, none));
+         nvfx_fp_emit(fpc, arith(0, MOV, tmp.reg, NVFX_FP_MASK_Z | NVFX_FP_MASK_W, swz(tmp, X, Y, X, Y), none, none));
+         nvfx_fp_emit(fpc, arith(sat, DDY, tmp.reg, NVFX_FP_MASK_X | NVFX_FP_MASK_Y, src[0], none, none));
+         nvfx_fp_emit(fpc, arith(0, MOV, dst, mask, tmp, none, none));
+      } else {
+         nvfx_fp_emit(fpc, arith(sat, DDY, dst, mask, src[0], none, none));
+      }
+      break;
+   case TGSI_OPCODE_DP2:
+      tmp = nvfx_src(temp(fpc));
+      nvfx_fp_emit(fpc, arith(0, MUL, tmp.reg, NVFX_FP_MASK_X | NVFX_FP_MASK_Y, src[0], src[1], none));
+      nvfx_fp_emit(fpc, arith(0, ADD, dst, mask, swz(tmp, X, X, X, X), swz(tmp, Y, Y, Y, Y), none));
+      break;
+   case TGSI_OPCODE_DP3:
+      nvfx_fp_emit(fpc, arith(sat, DP3, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_DP4:
+      nvfx_fp_emit(fpc, arith(sat, DP4, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_DPH:
+      tmp = nvfx_src(temp(fpc));
+      nvfx_fp_emit(fpc, arith(0, DP3, tmp.reg, NVFX_FP_MASK_X, src[0], src[1], none));
+      nvfx_fp_emit(fpc, arith(sat, ADD, dst, mask, swz(tmp, X, X, X, X), swz(src[1], W, W, W, W), none));
+      break;
+   case TGSI_OPCODE_DST:
+      nvfx_fp_emit(fpc, arith(sat, DST, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_EX2:
+      nvfx_fp_emit(fpc, arith(sat, EX2, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_FLR:
+      nvfx_fp_emit(fpc, arith(sat, FLR, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_FRC:
+      nvfx_fp_emit(fpc, arith(sat, FRC, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_KILP:
+      nvfx_fp_emit(fpc, arith(0, KIL, none.reg, 0, none, none, none));
+      break;
+   case TGSI_OPCODE_KIL:
+      insn = arith(0, MOV, none.reg, NVFX_FP_MASK_ALL, src[0], none, none);
+      insn.cc_update = 1;
+      nvfx_fp_emit(fpc, insn);
+
+      insn = arith(0, KIL, none.reg, 0, none, none, none);
+      insn.cc_test = NVFX_COND_LT;
+      nvfx_fp_emit(fpc, insn);
+      break;
+   case TGSI_OPCODE_LG2:
+      nvfx_fp_emit(fpc, arith(sat, LG2, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_LIT:
+      if(!nvfx->is_nv4x)
+         nvfx_fp_emit(fpc, arith(sat, LIT_NV30, dst, mask, src[0], src[1], src[2]));
+      else {
+         /* we use FLT_MIN, so that log2 never gives -infinity, and thus multiplication by
+          * specular 0 always gives 0, so that ex2 gives 1, to satisfy the 0^0 = 1 requirement
+          *
+          * NOTE: if we start using half precision, we might need an fp16 FLT_MIN here instead
+          */
+         struct nvfx_src maxs = nvfx_src(nvfx_fp_imm(fpc, 0, FLT_MIN, 0, 0));
+         tmp = nvfx_src(temp(fpc));
+         if (ci>= 0 || ii >= 0) {
+            nvfx_fp_emit(fpc, arith(0, MOV, tmp.reg, NVFX_FP_MASK_X | NVFX_FP_MASK_Y, maxs, none, none));
+            maxs = tmp;
+         }
+         nvfx_fp_emit(fpc, arith(0, MAX, tmp.reg, NVFX_FP_MASK_Y | NVFX_FP_MASK_W, swz(src[0], X, X, X, Y), swz(maxs, X, X, Y, Y), none));
+         nvfx_fp_emit(fpc, arith(0, LG2, tmp.reg, NVFX_FP_MASK_W, swz(tmp, W, W, W, W), none, none));
+         nvfx_fp_emit(fpc, arith(0, MUL, tmp.reg, NVFX_FP_MASK_W, swz(tmp, W, W, W, W), swz(src[0], W, W, W, W), none));
+         nvfx_fp_emit(fpc, arith(sat, LITEX2_NV40, dst, mask, swz(tmp, Y, Y, W, W), none, none));
+      }
+      break;
+   case TGSI_OPCODE_LRP:
+      if(!nvfx->is_nv4x)
+         nvfx_fp_emit(fpc, arith(sat, LRP_NV30, dst, mask, src[0], src[1], src[2]));
+      else {
+         tmp = nvfx_src(temp(fpc));
+         nvfx_fp_emit(fpc, arith(0, MAD, tmp.reg, mask, neg(src[0]), src[2], src[2]));
+         nvfx_fp_emit(fpc, arith(sat, MAD, dst, mask, src[0], src[1], tmp));
+      }
+      break;
+   case TGSI_OPCODE_MAD:
+      nvfx_fp_emit(fpc, arith(sat, MAD, dst, mask, src[0], src[1], src[2]));
+      break;
+   case TGSI_OPCODE_MAX:
+      nvfx_fp_emit(fpc, arith(sat, MAX, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_MIN:
+      nvfx_fp_emit(fpc, arith(sat, MIN, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_MOV:
+      nvfx_fp_emit(fpc, arith(sat, MOV, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_MUL:
+      nvfx_fp_emit(fpc, arith(sat, MUL, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_NOP:
+      break;
+   case TGSI_OPCODE_POW:
+      if(!nvfx->is_nv4x)
+         nvfx_fp_emit(fpc, arith(sat, POW_NV30, dst, mask, src[0], src[1], none));
+      else {
+         tmp = nvfx_src(temp(fpc));
+         nvfx_fp_emit(fpc, arith(0, LG2, tmp.reg, NVFX_FP_MASK_X, swz(src[0], X, X, X, X), none, none));
+         nvfx_fp_emit(fpc, arith(0, MUL, tmp.reg, NVFX_FP_MASK_X, swz(tmp, X, X, X, X), swz(src[1], X, X, X, X), none));
+         nvfx_fp_emit(fpc, arith(sat, EX2, dst, mask, swz(tmp, X, X, X, X), none, none));
+      }
+      break;
+   case TGSI_OPCODE_RCP:
+      nvfx_fp_emit(fpc, arith(sat, RCP, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_RFL:
+      if(!nvfx->is_nv4x)
+         nvfx_fp_emit(fpc, arith(0, RFL_NV30, dst, mask, src[0], src[1], none));
+      else {
+         tmp = nvfx_src(temp(fpc));
+         nvfx_fp_emit(fpc, arith(0, DP3, tmp.reg, NVFX_FP_MASK_X, src[0], src[0], none));
+         nvfx_fp_emit(fpc, arith(0, DP3, tmp.reg, NVFX_FP_MASK_Y, src[0], src[1], none));
+         insn = arith(0, DIV, tmp.reg, NVFX_FP_MASK_Z, swz(tmp, Y, Y, Y, Y), swz(tmp, X, X, X, X), none);
+         insn.scale = NVFX_FP_OP_DST_SCALE_2X;
+         nvfx_fp_emit(fpc, insn);
+         nvfx_fp_emit(fpc, arith(sat, MAD, dst, mask, swz(tmp, Z, Z, Z, Z), src[0], neg(src[1])));
+      }
+      break;
+   case TGSI_OPCODE_RSQ:
+      if(!nvfx->is_nv4x)
+         nvfx_fp_emit(fpc, arith(sat, RSQ_NV30, dst, mask, abs(swz(src[0], X, X, X, X)), none, none));
+      else {
+         tmp = nvfx_src(temp(fpc));
+         insn = arith(0, LG2, tmp.reg, NVFX_FP_MASK_X, abs(swz(src[0], X, X, X, X)), none, none);
+         insn.scale = NVFX_FP_OP_DST_SCALE_INV_2X;
+         nvfx_fp_emit(fpc, insn);
+         nvfx_fp_emit(fpc, arith(sat, EX2, dst, mask, neg(swz(tmp, X, X, X, X)), none, none));
+      }
+      break;
+   case TGSI_OPCODE_SCS:
+      /* avoid overwriting the source */
+      if(src[0].swz[NVFX_SWZ_X] != NVFX_SWZ_X)
+      {
+         if (mask & NVFX_FP_MASK_X)
+            nvfx_fp_emit(fpc, arith(sat, COS, dst, NVFX_FP_MASK_X, swz(src[0], X, X, X, X), none, none));
+         if (mask & NVFX_FP_MASK_Y)
+            nvfx_fp_emit(fpc, arith(sat, SIN, dst, NVFX_FP_MASK_Y, swz(src[0], X, X, X, X), none, none));
+      }
+      else
+      {
+         if (mask & NVFX_FP_MASK_Y)
+            nvfx_fp_emit(fpc, arith(sat, SIN, dst, NVFX_FP_MASK_Y, swz(src[0], X, X, X, X), none, none));
+         if (mask & NVFX_FP_MASK_X)
+            nvfx_fp_emit(fpc, arith(sat, COS, dst, NVFX_FP_MASK_X, swz(src[0], X, X, X, X), none, none));
+      }
+      break;
+   case TGSI_OPCODE_SEQ:
+      nvfx_fp_emit(fpc, arith(sat, SEQ, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SFL:
+      nvfx_fp_emit(fpc, arith(sat, SFL, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SGE:
+      nvfx_fp_emit(fpc, arith(sat, SGE, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SGT:
+      nvfx_fp_emit(fpc, arith(sat, SGT, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SIN:
+      nvfx_fp_emit(fpc, arith(sat, SIN, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_SLE:
+      nvfx_fp_emit(fpc, arith(sat, SLE, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SLT:
+      nvfx_fp_emit(fpc, arith(sat, SLT, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SNE:
+      nvfx_fp_emit(fpc, arith(sat, SNE, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SSG:
+   {
+      struct nvfx_src minones = swz(nvfx_src(nvfx_fp_imm(fpc, -1, -1, -1, -1)), X, X, X, X);
+
+      insn = arith(sat, MOV, dst, mask, src[0], none, none);
+      insn.cc_update = 1;
+      nvfx_fp_emit(fpc, insn);
+
+      insn = arith(0, STR, dst, mask, none, none, none);
+      insn.cc_test = NVFX_COND_GT;
+      nvfx_fp_emit(fpc, insn);
+
+      if(!sat) {
+         insn = arith(0, MOV, dst, mask, minones, none, none);
+         insn.cc_test = NVFX_COND_LT;
+         nvfx_fp_emit(fpc, insn);
+      }
+      break;
+   }
+   case TGSI_OPCODE_STR:
+      nvfx_fp_emit(fpc, arith(sat, STR, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SUB:
+      nvfx_fp_emit(fpc, arith(sat, ADD, dst, mask, src[0], neg(src[1]), none));
+      break;
+   case TGSI_OPCODE_TEX:
+      nvfx_fp_emit(fpc, tex(sat, TEX, unit, dst, mask, src[0], none, none));
+      break;
+        case TGSI_OPCODE_TRUNC:
+                tmp = nvfx_src(temp(fpc));
+                insn = arith(0, MOV, none.reg, mask, src[0], none, none);
+                insn.cc_update = 1;
+                nvfx_fp_emit(fpc, insn);
+
+                nvfx_fp_emit(fpc, arith(0, FLR, tmp.reg, mask, abs(src[0]), none, none));
+                nvfx_fp_emit(fpc, arith(sat, MOV, dst, mask, tmp, none, none));
+
+                insn = arith(sat, MOV, dst, mask, neg(tmp), none, none);
+                insn.cc_test = NVFX_COND_LT;
+                nvfx_fp_emit(fpc, insn);
+                break;
+        case TGSI_OPCODE_TXB:
+                nvfx_fp_emit(fpc, tex(sat, TXB, unit, dst, mask, src[0], none, none));
+                break;
+        case TGSI_OPCODE_TXL:
+                if(nvfx->is_nv4x)
+                        nvfx_fp_emit(fpc, tex(sat, TXL_NV40, unit, dst, mask, src[0], none, none));
+                else /* unsupported on nv30, use TEX and hope they like it */
+                        nvfx_fp_emit(fpc, tex(sat, TEX, unit, dst, mask, src[0], none, none));
+                break;
+        case TGSI_OPCODE_TXP:
+                nvfx_fp_emit(fpc, tex(sat, TXP, unit, dst, mask, src[0], none, none));
+                break;
+   case TGSI_OPCODE_XPD:
+      tmp = nvfx_src(temp(fpc));
+      nvfx_fp_emit(fpc, arith(0, MUL, tmp.reg, mask, swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none));
+      nvfx_fp_emit(fpc, arith(sat, MAD, dst, (mask & ~NVFX_FP_MASK_W), swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y), neg(tmp)));
+      break;
+
+   case TGSI_OPCODE_IF:
+      // MOVRC0 R31 (TR0.xyzw), R<src>:
+      // IF (NE.xxxx) ELSE <else> END <end>
+      if(!nvfx->use_nv4x)
+         goto nv3x_cflow;
+      nv40_fp_if(fpc, src[0]);
+      break;
+
+   case TGSI_OPCODE_ELSE:
+   {
+      uint32_t *hw;
+      if(!nvfx->use_nv4x)
+         goto nv3x_cflow;
+      assert(util_dynarray_contains(&fpc->if_stack, unsigned));
+      hw = &fpc->fp->insn[util_dynarray_top(&fpc->if_stack, unsigned)];
+      hw[2] = NV40_FP_OP_OPCODE_IS_BRANCH | fpc->fp->insn_len;
+      break;
+   }
+
+   case TGSI_OPCODE_ENDIF:
+   {
+      uint32_t *hw;
+      if(!nvfx->use_nv4x)
+         goto nv3x_cflow;
+      assert(util_dynarray_contains(&fpc->if_stack, unsigned));
+      hw = &fpc->fp->insn[util_dynarray_pop(&fpc->if_stack, unsigned)];
+      if(!hw[2])
+         hw[2] = NV40_FP_OP_OPCODE_IS_BRANCH | fpc->fp->insn_len;
+      hw[3] = fpc->fp->insn_len;
+      break;
+   }
+
+   case TGSI_OPCODE_BRA:
+      /* This can in limited cases be implemented with an IF with the else and endif labels pointing to the target */
+      /* no state tracker uses this, so don't implement this for now */
+      assert(0);
+      nv40_fp_bra(fpc, finst->Label.Label);
+      break;
+
+   case TGSI_OPCODE_BGNSUB:
+   case TGSI_OPCODE_ENDSUB:
+      /* nothing to do here */
+      break;
+
+   case TGSI_OPCODE_CAL:
+      if(!nvfx->use_nv4x)
+         goto nv3x_cflow;
+      nv40_fp_cal(fpc, finst->Label.Label);
+      break;
+
+   case TGSI_OPCODE_RET:
+      if(!nvfx->use_nv4x)
+         goto nv3x_cflow;
+      nv40_fp_ret(fpc);
+      break;
+
+   case TGSI_OPCODE_BGNLOOP:
+      if(!nvfx->use_nv4x)
+         goto nv3x_cflow;
+      /* TODO: we should support using two nested REPs to allow a > 255 iteration count */
+      nv40_fp_rep(fpc, 255, finst->Label.Label);
+      break;
+
+   case TGSI_OPCODE_ENDLOOP:
+      break;
+
+   case TGSI_OPCODE_BRK:
+      if(!nvfx->use_nv4x)
+         goto nv3x_cflow;
+      nv40_fp_brk(fpc);
+      break;
+
+   case TGSI_OPCODE_CONT:
+   {
+      static int warned = 0;
+      if(!warned) {
+         NOUVEAU_ERR("Sorry, the continue keyword is not implemented: ignoring it.\n");
+         warned = 1;
+      }
+      break;
+   }
+
+        default:
+      NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode);
+      return FALSE;
+   }
+
+out:
+   release_temps(fpc);
+   return TRUE;
+nv3x_cflow:
+   {
+      static int warned = 0;
+      if(!warned) {
+         NOUVEAU_ERR(
+               "Sorry, control flow instructions are not supported in hardware on nv3x: ignoring them\n"
+               "If rendering is incorrect, try to disable GLSL support in the application.\n");
+         warned = 1;
+      }
+   }
+   goto out;
+}
+
+static boolean
+nvfx_fragprog_parse_decl_input(struct nv30_context *nvfx, struct nvfx_fpc *fpc,
+                               const struct tgsi_full_declaration *fdec)
+{
+   unsigned idx = fdec->Range.First;
+   unsigned hw;
+
+   switch (fdec->Semantic.Name) {
+   case TGSI_SEMANTIC_POSITION:
+      hw = NVFX_FP_OP_INPUT_SRC_POSITION;
+      break;
+   case TGSI_SEMANTIC_COLOR:
+      hw = NVFX_FP_OP_INPUT_SRC_COL0 + fdec->Semantic.Index;
+      break;
+   case TGSI_SEMANTIC_FOG:
+      hw = NVFX_FP_OP_INPUT_SRC_FOGC;
+      break;
+   case TGSI_SEMANTIC_FACE:
+      hw = NV40_FP_OP_INPUT_SRC_FACING;
+      break;
+   case TGSI_SEMANTIC_GENERIC:
+      if (fdec->Semantic.Index >= 8)
+         return TRUE;
+
+      fpc->fp->texcoord[fdec->Semantic.Index] = fdec->Semantic.Index;
+      fpc->fp->vp_or |= (0x00004000 << fdec->Semantic.Index);
+      hw = NVFX_FP_OP_INPUT_SRC_TC(fdec->Semantic.Index);
+      break;
+   default:
+      assert(0);
+      return FALSE;
+   }
+
+   fpc->r_input[idx] = nvfx_reg(NVFXSR_INPUT, hw);
+   return TRUE;
+}
+
+static boolean
+nvfx_fragprog_assign_generic(struct nv30_context *nvfx, struct nvfx_fpc *fpc,
+                             const struct tgsi_full_declaration *fdec)
+{
+   unsigned num_texcoords = nvfx->use_nv4x ? 10 : 8;
+   unsigned idx = fdec->Range.First;
+   unsigned hw;
+
+   switch (fdec->Semantic.Name) {
+   case TGSI_SEMANTIC_GENERIC:
+      if (fdec->Semantic.Index >= 8) {
+         for (hw = 0; hw < num_texcoords; hw++) {
+            if (fpc->fp->texcoord[hw] == 0xffff) {
+               fpc->fp->texcoord[hw] = fdec->Semantic.Index;
+               if (hw <= 7) fpc->fp->vp_or |= (0x00004000 << hw);
+               else         fpc->fp->vp_or |= (0x00001000 << (hw - 8));
+               if (fdec->Semantic.Index == 9)
+                  fpc->fp->point_sprite_control |= (0x00000100 << hw);
+               hw = NVFX_FP_OP_INPUT_SRC_TC(hw);
+               fpc->r_input[idx] = nvfx_reg(NVFXSR_INPUT, hw);
+               return TRUE;
+            }
+         }
+         return FALSE;
+      }
+      return TRUE;
+   default:
+      return TRUE;
+   }
+}
+
+static boolean
+nvfx_fragprog_parse_decl_output(struct nv30_context* nvfx, struct nvfx_fpc *fpc,
+            const struct tgsi_full_declaration *fdec)
+{
+   unsigned idx = fdec->Range.First;
+   unsigned hw;
+
+   switch (fdec->Semantic.Name) {
+   case TGSI_SEMANTIC_POSITION:
+      hw = 1;
+      break;
+   case TGSI_SEMANTIC_COLOR:
+      hw = ~0;
+      switch (fdec->Semantic.Index) {
+      case 0: hw = 0; break;
+      case 1: hw = 2; break;
+      case 2: hw = 3; break;
+      case 3: hw = 4; break;
+      }
+      if(hw > ((nvfx->use_nv4x) ? 4 : 2)) {
+         NOUVEAU_ERR("bad rcol index\n");
+         return FALSE;
+      }
+      break;
+   default:
+      NOUVEAU_ERR("bad output semantic\n");
+      return FALSE;
+   }
+
+   fpc->r_result[idx] = nvfx_reg(NVFXSR_OUTPUT, hw);
+   fpc->r_temps |= (1ULL << hw);
+   return TRUE;
+}
+
+static boolean
+nvfx_fragprog_prepare(struct nv30_context* nvfx, struct nvfx_fpc *fpc)
+{
+   struct tgsi_parse_context p;
+   int high_temp = -1, i;
+
+   fpc->r_imm = CALLOC(fpc->fp->info.immediate_count, sizeof(struct nvfx_reg));
+
+   tgsi_parse_init(&p, fpc->fp->pipe.tokens);
+   while (!tgsi_parse_end_of_tokens(&p)) {
+      const union tgsi_full_token *tok = &p.FullToken;
+
+      tgsi_parse_token(&p);
+      switch(tok->Token.Type) {
+      case TGSI_TOKEN_TYPE_DECLARATION:
+      {
+         const struct tgsi_full_declaration *fdec;
+         fdec = &p.FullToken.FullDeclaration;
+         switch (fdec->Declaration.File) {
+         case TGSI_FILE_INPUT:
+            if (!nvfx_fragprog_parse_decl_input(nvfx, fpc, fdec))
+               goto out_err;
+            break;
+         case TGSI_FILE_OUTPUT:
+            if (!nvfx_fragprog_parse_decl_output(nvfx, fpc, fdec))
+               goto out_err;
+            break;
+         case TGSI_FILE_TEMPORARY:
+            if (fdec->Range.Last > high_temp) {
+               high_temp =
+                  fdec->Range.Last;
+            }
+            break;
+         default:
+            break;
+         }
+      }
+         break;
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+      {
+         struct tgsi_full_immediate *imm;
+
+         imm = &p.FullToken.FullImmediate;
+         assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
+         assert(fpc->nr_imm < fpc->fp->info.immediate_count);
+
+         fpc->r_imm[fpc->nr_imm++] = nvfx_fp_imm(fpc, imm->u[0].Float, imm->u[1].Float, imm->u[2].Float, imm->u[3].Float);
+         break;
+      }
+      default:
+         break;
+      }
+   }
+   tgsi_parse_free(&p);
+
+   tgsi_parse_init(&p, fpc->fp->pipe.tokens);
+   while (!tgsi_parse_end_of_tokens(&p)) {
+      const struct tgsi_full_declaration *fdec;
+      tgsi_parse_token(&p);
+      switch(p.FullToken.Token.Type) {
+      case TGSI_TOKEN_TYPE_DECLARATION:
+         fdec = &p.FullToken.FullDeclaration;
+         switch (fdec->Declaration.File) {
+         case TGSI_FILE_INPUT:
+            if (!nvfx_fragprog_assign_generic(nvfx, fpc, fdec))
+               goto out_err;
+            break;
+         default:
+            break;
+         }
+         break;
+      default:
+         break;
+      }
+   }
+   tgsi_parse_free(&p);
+
+   if (++high_temp) {
+      fpc->r_temp = CALLOC(high_temp, sizeof(struct nvfx_reg));
+      for (i = 0; i < high_temp; i++)
+         fpc->r_temp[i] = temp(fpc);
+      fpc->r_temps_discard = 0ULL;
+   }
+
+   return TRUE;
+
+out_err:
+   if (fpc->r_temp) {
+      FREE(fpc->r_temp);
+      fpc->r_temp = NULL;
+   }
+   tgsi_parse_free(&p);
+   return FALSE;
+}
+
+DEBUG_GET_ONCE_BOOL_OPTION(nvfx_dump_fp, "NVFX_DUMP_FP", FALSE)
+
+void
+_nvfx_fragprog_translate(struct nv30_context *nvfx, struct nv30_fragprog *fp,
+         boolean emulate_sprite_flipping)
+{
+   struct tgsi_parse_context parse;
+   struct nvfx_fpc *fpc = NULL;
+   struct util_dynarray insns;
+
+   fp->translated = FALSE;
+   fp->point_sprite_control = 0;
+   fp->vp_or = 0;
+
+   fpc = CALLOC_STRUCT(nvfx_fpc);
+   if (!fpc)
+      goto out_err;
+
+   fpc->max_temps = nvfx->use_nv4x ? 48 : 32;
+   fpc->fp = fp;
+   fpc->num_regs = 2;
+   memset(fp->texcoord, 0xff, sizeof(fp->texcoord));
+
+   for (unsigned i = 0; i < fp->info.num_properties; ++i) {
+      switch (fp->info.properties[i].name) {
+      case TGSI_PROPERTY_FS_COORD_ORIGIN:
+         if (fp->info.properties[i].data[0])
+            fp->coord_conventions |= NV30_3D_COORD_CONVENTIONS_ORIGIN_INVERTED;
+         break;
+      case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
+         if (fp->info.properties[i].data[0])
+            fp->coord_conventions |= NV30_3D_COORD_CONVENTIONS_CENTER_INTEGER;
+         break;
+      case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
+         if (fp->info.properties[i].data[0])
+            fp->rt_enable |= NV30_3D_RT_ENABLE_MRT;
+         break;
+      default:
+         break;
+      }
+   }
+
+   if (!nvfx_fragprog_prepare(nvfx, fpc))
+      goto out_err;
+
+   tgsi_parse_init(&parse, fp->pipe.tokens);
+   util_dynarray_init(&insns);
+
+   while (!tgsi_parse_end_of_tokens(&parse)) {
+      tgsi_parse_token(&parse);
+
+      switch (parse.FullToken.Token.Type) {
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+      {
+         const struct tgsi_full_instruction *finst;
+
+         util_dynarray_append(&insns, unsigned, fp->insn_len);
+         finst = &parse.FullToken.FullInstruction;
+         if (!nvfx_fragprog_parse_instruction(nvfx, fpc, finst))
+            goto out_err;
+      }
+         break;
+      default:
+         break;
+      }
+   }
+   util_dynarray_append(&insns, unsigned, fp->insn_len);
+
+   for(unsigned i = 0; i < fpc->label_relocs.size; i += sizeof(struct nvfx_relocation))
+   {
+      struct nvfx_relocation* label_reloc = (struct nvfx_relocation*)((char*)fpc->label_relocs.data + i);
+      fp->insn[label_reloc->location] |= ((unsigned*)insns.data)[label_reloc->target];
+   }
+   util_dynarray_fini(&insns);
+
+   if(!nvfx->is_nv4x)
+      fp->fp_control |= (fpc->num_regs-1)/2;
+   else
+      fp->fp_control |= fpc->num_regs << NV40_3D_FP_CONTROL_TEMP_COUNT__SHIFT;
+
+   /* Terminate final instruction */
+   if(fp->insn)
+      fp->insn[fpc->inst_offset] |= 0x00000001;
+
+   /* Append NOP + END instruction for branches to the end of the program */
+   fpc->inst_offset = fp->insn_len;
+   grow_insns(fpc, 4);
+   fp->insn[fpc->inst_offset + 0] = 0x00000001;
+   fp->insn[fpc->inst_offset + 1] = 0x00000000;
+   fp->insn[fpc->inst_offset + 2] = 0x00000000;
+   fp->insn[fpc->inst_offset + 3] = 0x00000000;
+
+   if(debug_get_option_nvfx_dump_fp())
+   {
+      debug_printf("\n");
+      tgsi_dump(fp->pipe.tokens, 0);
+
+      debug_printf("\n%s fragment program:\n", nvfx->is_nv4x ? "nv4x" : "nv3x");
+      for (unsigned i = 0; i < fp->insn_len; i += 4)
+         debug_printf("%3u: %08x %08x %08x %08x\n", i >> 2, fp->insn[i], fp->insn[i + 1], fp->insn[i + 2], fp->insn[i + 3]);
+      debug_printf("\n");
+   }
+
+   fp->translated = TRUE;
+
+out:
+   tgsi_parse_free(&parse);
+   if(fpc)
+   {
+      if (fpc->r_temp)
+         FREE(fpc->r_temp);
+      util_dynarray_fini(&fpc->if_stack);
+      util_dynarray_fini(&fpc->label_relocs);
+      util_dynarray_fini(&fpc->imm_data);
+      //util_dynarray_fini(&fpc->loop_stack);
+      FREE(fpc);
+   }
+
+   return;
+
+out_err:
+   _debug_printf("Error: failed to compile this fragment program:\n");
+   tgsi_dump(fp->pipe.tokens, 0);
+   goto out;
+}
+
+static inline void
+nvfx_fp_memcpy(void* dst, const void* src, size_t len)
+{
+#ifndef PIPE_ARCH_BIG_ENDIAN
+   memcpy(dst, src, len);
+#else
+   size_t i;
+   for(i = 0; i < len; i += 4) {
+      uint32_t v = *(uint32_t*)((char*)src + i);
+      *(uint32_t*)((char*)dst + i) = (v >> 16) | (v << 16);
+   }
+#endif
+}
diff --git a/src/gallium/drivers/nv30/nvfx_shader.h b/src/gallium/drivers/nv30/nvfx_shader.h
new file mode 100644 (file)
index 0000000..e343bf0
--- /dev/null
@@ -0,0 +1,525 @@
+#ifndef __NVFX_SHADER_H__
+#define __NVFX_SHADER_H__
+
+#include <stdint.h>
+
+#include "pipe/p_compiler.h"
+
+#define NVFX_SWZ_IDENTITY ((3 << 6) | (2 << 4) | (1 << 2) | (0 << 0))
+
+/* this will resolve to either the NV30 or the NV40 version
+ * depending on the current hardware */
+/* unusual, but very fast and compact method */
+#define NVFX_VP(c) ((NV30_VP_##c) + (nv30->is_nv4x & ((NV40_VP_##c) - (NV30_VP_##c))))
+
+#define NVFX_VP_INST_SLOT_VEC 0
+#define NVFX_VP_INST_SLOT_SCA 1
+
+#define NVFX_VP_INST_IN_POS  0    /* These seem to match the bindings specified in */
+#define NVFX_VP_INST_IN_WEIGHT  1    /* the ARB_v_p spec (2.14.3.1) */
+#define NVFX_VP_INST_IN_NORMAL  2
+#define NVFX_VP_INST_IN_COL0  3    /* Should probably confirm them all though */
+#define NVFX_VP_INST_IN_COL1  4
+#define NVFX_VP_INST_IN_FOGC  5
+#define NVFX_VP_INST_IN_TC0  8
+#define NVFX_VP_INST_IN_TC(n)  (8+n)
+
+#define NVFX_VP_INST_SCA_OP_NOP 0x00
+#define NVFX_VP_INST_SCA_OP_MOV 0x01
+#define NVFX_VP_INST_SCA_OP_RCP 0x02
+#define NVFX_VP_INST_SCA_OP_RCC 0x03
+#define NVFX_VP_INST_SCA_OP_RSQ 0x04
+#define NVFX_VP_INST_SCA_OP_EXP 0x05
+#define NVFX_VP_INST_SCA_OP_LOG 0x06
+#define NVFX_VP_INST_SCA_OP_LIT 0x07
+#define NVFX_VP_INST_SCA_OP_BRA 0x09
+#define NVFX_VP_INST_SCA_OP_CAL 0x0B
+#define NVFX_VP_INST_SCA_OP_RET 0x0C
+#define NVFX_VP_INST_SCA_OP_LG2 0x0D
+#define NVFX_VP_INST_SCA_OP_EX2 0x0E
+#define NVFX_VP_INST_SCA_OP_SIN 0x0F
+#define NVFX_VP_INST_SCA_OP_COS 0x10
+
+#define NV40_VP_INST_SCA_OP_PUSHA 0x13
+#define NV40_VP_INST_SCA_OP_POPA 0x14
+
+#define NVFX_VP_INST_VEC_OP_NOP 0x00
+#define NVFX_VP_INST_VEC_OP_MOV 0x01
+#define NVFX_VP_INST_VEC_OP_MUL 0x02
+#define NVFX_VP_INST_VEC_OP_ADD 0x03
+#define NVFX_VP_INST_VEC_OP_MAD 0x04
+#define NVFX_VP_INST_VEC_OP_DP3 0x05
+#define NVFX_VP_INST_VEC_OP_DPH 0x06
+#define NVFX_VP_INST_VEC_OP_DP4 0x07
+#define NVFX_VP_INST_VEC_OP_DST 0x08
+#define NVFX_VP_INST_VEC_OP_MIN 0x09
+#define NVFX_VP_INST_VEC_OP_MAX 0x0A
+#define NVFX_VP_INST_VEC_OP_SLT 0x0B
+#define NVFX_VP_INST_VEC_OP_SGE 0x0C
+#define NVFX_VP_INST_VEC_OP_ARL 0x0D
+#define NVFX_VP_INST_VEC_OP_FRC 0x0E
+#define NVFX_VP_INST_VEC_OP_FLR 0x0F
+#define NVFX_VP_INST_VEC_OP_SEQ 0x10
+#define NVFX_VP_INST_VEC_OP_SFL 0x11
+#define NVFX_VP_INST_VEC_OP_SGT 0x12
+#define NVFX_VP_INST_VEC_OP_SLE 0x13
+#define NVFX_VP_INST_VEC_OP_SNE 0x14
+#define NVFX_VP_INST_VEC_OP_STR 0x15
+#define NVFX_VP_INST_VEC_OP_SSG 0x16
+#define NVFX_VP_INST_VEC_OP_ARR 0x17
+#define NVFX_VP_INST_VEC_OP_ARA 0x18
+
+#define NV40_VP_INST_VEC_OP_TXL 0x19
+
+/* DWORD 3 */
+#define NVFX_VP_INST_LAST                           (1 << 0)
+
+/*
+ * Each fragment program opcode appears to be comprised of 4 32-bit values.
+ *
+ * 0: OPDEST
+ *     0: program end
+ *     1-6: destination register
+ *     7: destination register is fp16?? (use for outputs)
+ *     8: set condition code
+ *     9: writemask x
+ *     10: writemask y
+ *     11: writemask z
+ *     12: writemask w
+ *     13-16: source attribute register number (e.g. COL0)
+ *     17-20: texture unit number
+ *     21: expand value on texture operation (x -> 2x - 1)
+ *     22-23: precision 0 = fp32, 1 = fp16, 2 = s1.10 fixed, 3 = s0.8 fixed (nv40-only))
+ *     24-29: opcode
+ *     30: no destination
+ *     31: saturate
+ * 1 - SRC0
+ *     0-17: see common source fields
+ *     18: execute if condition code less
+ *     19: execute if condition code equal
+ *     20: execute if condition code greater
+ *     21-22: condition code swizzle x source component
+ *     23-24: condition code swizzle y source component
+ *     25-26: condition code swizzle z source component
+ *     27-28: condition code swizzle w source component
+ *     29: source 0 absolute
+ *     30: always 0 in renouveau tests
+ *     31: always 0 in renouveau tests
+ * 2 - SRC1
+ *     0-17: see common source fields
+ *     18: source 1 absolute
+ *     19-20: input precision 0 = fp32, 1 = fp16, 2 = s1.10 fixed, 3 = ???
+ *     21-27: always 0 in renouveau tests
+ *     28-30: scale (0 = 1x, 1 = 2x, 2 = 4x, 3 = 8x, 4 = ???, 5, = 1/2, 6 = 1/4, 7 = 1/8)
+ *     31: opcode is branch
+ * 3 - SRC2
+ *     0-17: see common source fields
+ *     18: source 2 absolute
+ *     19-29: address register displacement
+ *     30: use index register
+ *     31: disable perspective-correct interpolation?
+ *
+* Common fields of 0, 1, 2 - SRC
+ *     0-1: source register type (0 = temp, 1 = input, 2 = immediate, 3 = ???)
+ *     2-7: source temp register index
+ *     8: source register is fp16??
+ *     9-10: source swizzle x source component
+ *     11-12: source swizzle y source component
+ *     13-14: source swizzle z source component
+ *     15-16: source swizzle w source component
+ *     17: negate
+
+ * There appears to be no special difference between result regs and temp regs.
+ *     result.color == R0.xyzw
+ *     result.depth == R1.z
+ * When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0
+ * otherwise it is set to 1.
+ *
+ * Constants are inserted directly after the instruction that uses them.
+ *
+ * It appears that it's not possible to use two input registers in one
+ * instruction as the input sourcing is done in the instruction dword
+ * and not the source selection dwords.  As such instructions such as:
+ *
+ *     ADD result.color, fragment.color, fragment.texcoord[0];
+ *
+ * must be split into two MOV's and then an ADD (nvidia does this) but
+ * I'm not sure why it's not just one MOV and then source the second input
+ * in the ADD instruction..
+ *
+ * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
+ * negation requires multiplication with a const.
+ *
+ * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE
+ * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO
+ * is implemented simply by not writing to the relevant components of the destination.
+ *
+ * Conditional execution
+ *   TODO
+ *
+ * Non-native instructions:
+ *   LIT
+ *   LRP - MAD+MAD
+ *   SUB - ADD, negate second source
+ *   RSQ - LG2 + EX2
+ *   POW - LG2 + MUL + EX2
+ *   SCS - COS + SIN
+ *   XPD
+ *
+ * NV40 Looping
+ *   Loops appear to be fairly expensive on NV40 at least, the proprietary
+ *   driver goes to a lot of effort to avoid using the native looping
+ *   instructions.  If the total number of *executed* instructions between
+ *   REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop.
+ *   The maximum loop count is 255.
+ *
+ */
+
+//== Opcode / Destination selection ==
+#define NVFX_FP_OP_PROGRAM_END          (1 << 0)
+#define NVFX_FP_OP_OUT_REG_SHIFT        1
+#define NV30_FP_OP_OUT_REG_MASK          (31 << 1)  /* uncertain */
+#define NV40_FP_OP_OUT_REG_MASK          (63 << 1)
+/* Needs to be set when writing outputs to get expected result.. */
+#define NVFX_FP_OP_OUT_REG_HALF          (1 << 7)
+#define NVFX_FP_OP_COND_WRITE_ENABLE        (1 << 8)
+#define NVFX_FP_OP_OUTMASK_SHIFT        9
+#define NVFX_FP_OP_OUTMASK_MASK          (0xF << 9)
+#  define NVFX_FP_OP_OUT_X  (1<<9)
+#  define NVFX_FP_OP_OUT_Y  (1<<10)
+#  define NVFX_FP_OP_OUT_Z  (1<<11)
+#  define NVFX_FP_OP_OUT_W  (1<<12)
+/* Uncertain about these, especially the input_src values.. it's possible that
+ * they can be dynamically changed.
+ */
+#define NVFX_FP_OP_INPUT_SRC_SHIFT        13
+#define NVFX_FP_OP_INPUT_SRC_MASK        (15 << 13)
+#  define NVFX_FP_OP_INPUT_SRC_POSITION  0x0
+#  define NVFX_FP_OP_INPUT_SRC_COL0  0x1
+#  define NVFX_FP_OP_INPUT_SRC_COL1  0x2
+#  define NVFX_FP_OP_INPUT_SRC_FOGC  0x3
+#  define NVFX_FP_OP_INPUT_SRC_TC0    0x4
+#  define NVFX_FP_OP_INPUT_SRC_TC(n)  (0x4 + n)
+#  define NV40_FP_OP_INPUT_SRC_FACING  0xE
+#define NVFX_FP_OP_TEX_UNIT_SHIFT        17
+#define NVFX_FP_OP_TEX_UNIT_MASK        (0xF << 17) /* guess */
+#define NVFX_FP_OP_PRECISION_SHIFT        22
+#define NVFX_FP_OP_PRECISION_MASK        (3 << 22)
+#   define NVFX_FP_PRECISION_FP32  0
+#   define NVFX_FP_PRECISION_FP16  1
+#   define NVFX_FP_PRECISION_FX12  2
+#define NVFX_FP_OP_OPCODE_SHIFT          24
+#define NVFX_FP_OP_OPCODE_MASK          (0x3F << 24)
+/* NV30/NV40 fragment program opcodes */
+#define NVFX_FP_OP_OPCODE_NOP 0x00
+#define NVFX_FP_OP_OPCODE_MOV 0x01
+#define NVFX_FP_OP_OPCODE_MUL 0x02
+#define NVFX_FP_OP_OPCODE_ADD 0x03
+#define NVFX_FP_OP_OPCODE_MAD 0x04
+#define NVFX_FP_OP_OPCODE_DP3 0x05
+#define NVFX_FP_OP_OPCODE_DP4 0x06
+#define NVFX_FP_OP_OPCODE_DST 0x07
+#define NVFX_FP_OP_OPCODE_MIN 0x08
+#define NVFX_FP_OP_OPCODE_MAX 0x09
+#define NVFX_FP_OP_OPCODE_SLT 0x0A
+#define NVFX_FP_OP_OPCODE_SGE 0x0B
+#define NVFX_FP_OP_OPCODE_SLE 0x0C
+#define NVFX_FP_OP_OPCODE_SGT 0x0D
+#define NVFX_FP_OP_OPCODE_SNE 0x0E
+#define NVFX_FP_OP_OPCODE_SEQ 0x0F
+#define NVFX_FP_OP_OPCODE_FRC 0x10
+#define NVFX_FP_OP_OPCODE_FLR 0x11
+#define NVFX_FP_OP_OPCODE_KIL 0x12
+#define NVFX_FP_OP_OPCODE_PK4B 0x13
+#define NVFX_FP_OP_OPCODE_UP4B 0x14
+#define NVFX_FP_OP_OPCODE_DDX 0x15 /* can only write XY */
+#define NVFX_FP_OP_OPCODE_DDY 0x16 /* can only write XY */
+#define NVFX_FP_OP_OPCODE_TEX 0x17
+#define NVFX_FP_OP_OPCODE_TXP 0x18
+#define NVFX_FP_OP_OPCODE_TXD 0x19
+#define NVFX_FP_OP_OPCODE_RCP 0x1A
+#define NVFX_FP_OP_OPCODE_EX2 0x1C
+#define NVFX_FP_OP_OPCODE_LG2 0x1D
+#define NVFX_FP_OP_OPCODE_STR 0x20
+#define NVFX_FP_OP_OPCODE_SFL 0x21
+#define NVFX_FP_OP_OPCODE_COS 0x22
+#define NVFX_FP_OP_OPCODE_SIN 0x23
+#define NVFX_FP_OP_OPCODE_PK2H 0x24
+#define NVFX_FP_OP_OPCODE_UP2H 0x25
+#define NVFX_FP_OP_OPCODE_PK4UB 0x27
+#define NVFX_FP_OP_OPCODE_UP4UB 0x28
+#define NVFX_FP_OP_OPCODE_PK2US 0x29
+#define NVFX_FP_OP_OPCODE_UP2US 0x2A
+#define NVFX_FP_OP_OPCODE_DP2A 0x2E
+#define NVFX_FP_OP_OPCODE_TXB 0x31
+#define NVFX_FP_OP_OPCODE_DIV 0x3A
+
+/* NV30 only fragment program opcodes */
+#define NVFX_FP_OP_OPCODE_RSQ_NV30 0x1B
+#define NVFX_FP_OP_OPCODE_LIT_NV30 0x1E
+#define NVFX_FP_OP_OPCODE_LRP_NV30 0x1F
+#define NVFX_FP_OP_OPCODE_POW_NV30 0x26
+#define NVFX_FP_OP_OPCODE_RFL_NV30 0x36
+
+/* NV40 only fragment program opcodes */
+#define NVFX_FP_OP_OPCODE_TXL_NV40 0x2F
+#define NVFX_FP_OP_OPCODE_LITEX2_NV40 0x3C
+
+/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/
+#define NV40_FP_OP_BRA_OPCODE_BRK                                    0x0
+#define NV40_FP_OP_BRA_OPCODE_CAL                                    0x1
+#define NV40_FP_OP_BRA_OPCODE_IF                                     0x2
+#define NV40_FP_OP_BRA_OPCODE_LOOP                                   0x3
+#define NV40_FP_OP_BRA_OPCODE_REP                                    0x4
+#define NV40_FP_OP_BRA_OPCODE_RET                                    0x5
+
+#define NV40_FP_OP_OUT_NONE         (1 << 30)
+#define NVFX_FP_OP_OUT_SAT          (1 << 31)
+
+/* high order bits of SRC0 */
+#define NVFX_FP_OP_SRC0_ABS          (1 << 29)
+#define NVFX_FP_OP_COND_SWZ_W_SHIFT        27
+#define NVFX_FP_OP_COND_SWZ_W_MASK        (3 << 27)
+#define NVFX_FP_OP_COND_SWZ_Z_SHIFT        25
+#define NVFX_FP_OP_COND_SWZ_Z_MASK        (3 << 25)
+#define NVFX_FP_OP_COND_SWZ_Y_SHIFT        23
+#define NVFX_FP_OP_COND_SWZ_Y_MASK        (3 << 23)
+#define NVFX_FP_OP_COND_SWZ_X_SHIFT        21
+#define NVFX_FP_OP_COND_SWZ_X_MASK        (3 << 21)
+#define NVFX_FP_OP_COND_SWZ_ALL_SHIFT        21
+#define NVFX_FP_OP_COND_SWZ_ALL_MASK        (0xFF << 21)
+#define NVFX_FP_OP_COND_SHIFT          18
+#define NVFX_FP_OP_COND_MASK          (0x07 << 18)
+#  define NVFX_FP_OP_COND_FL  0
+#  define NVFX_FP_OP_COND_LT  1
+#  define NVFX_FP_OP_COND_EQ  2
+#  define NVFX_FP_OP_COND_LE  3
+#  define NVFX_FP_OP_COND_GT  4
+#  define NVFX_FP_OP_COND_NE  5
+#  define NVFX_FP_OP_COND_GE  6
+#  define NVFX_FP_OP_COND_TR  7
+
+/* high order bits of SRC1 */
+#define NV40_FP_OP_OPCODE_IS_BRANCH                                      (1<<31)
+#define NVFX_FP_OP_DST_SCALE_SHIFT        28
+#define NVFX_FP_OP_DST_SCALE_MASK        (3 << 28)
+#define NVFX_FP_OP_DST_SCALE_1X                                                0
+#define NVFX_FP_OP_DST_SCALE_2X                                                1
+#define NVFX_FP_OP_DST_SCALE_4X                                                2
+#define NVFX_FP_OP_DST_SCALE_8X                                                3
+#define NVFX_FP_OP_DST_SCALE_INV_2X                                            5
+#define NVFX_FP_OP_DST_SCALE_INV_4X                                            6
+#define NVFX_FP_OP_DST_SCALE_INV_8X                                            7
+#define NVFX_FP_OP_SRC1_ABS          (1 << 18)
+
+/* SRC1 LOOP */
+#define NV40_FP_OP_LOOP_INCR_SHIFT                                            19
+#define NV40_FP_OP_LOOP_INCR_MASK                                   (0xFF << 19)
+#define NV40_FP_OP_LOOP_INDEX_SHIFT                                           10
+#define NV40_FP_OP_LOOP_INDEX_MASK                                  (0xFF << 10)
+#define NV40_FP_OP_LOOP_COUNT_SHIFT                                            2
+#define NV40_FP_OP_LOOP_COUNT_MASK                                   (0xFF << 2)
+
+/* SRC1 IF: absolute offset in dwords */
+#define NV40_FP_OP_ELSE_OFFSET_SHIFT                                           0
+#define NV40_FP_OP_ELSE_OFFSET_MASK                             (0x7FFFFFFF << 0)
+
+/* SRC1 CAL */
+#define NV40_FP_OP_SUB_OFFSET_SHIFT                                                 0
+#define NV40_FP_OP_SUB_OFFSET_MASK                                   (0x7FFFFFFF << 0)
+
+/* SRC1 REP
+ *   I have no idea why there are 3 count values here..  but they
+ *   have always been filled with the same value in my tests so
+ *   far..
+ */
+#define NV40_FP_OP_REP_COUNT1_SHIFT                                            2
+#define NV40_FP_OP_REP_COUNT1_MASK                                   (0xFF << 2)
+#define NV40_FP_OP_REP_COUNT2_SHIFT                                           10
+#define NV40_FP_OP_REP_COUNT2_MASK                                  (0xFF << 10)
+#define NV40_FP_OP_REP_COUNT3_SHIFT                                           19
+#define NV40_FP_OP_REP_COUNT3_MASK                                  (0xFF << 19)
+
+/* SRC2 REP/IF: absolute offset in dwords */
+#define NV40_FP_OP_END_OFFSET_SHIFT                                            0
+#define NV40_FP_OP_END_OFFSET_MASK                              (0x7FFFFFFF << 0)
+
+/* high order bits of SRC2 */
+#define NVFX_FP_OP_INDEX_INPUT          (1 << 30)
+#define NV40_FP_OP_ADDR_INDEX_SHIFT        19
+#define NV40_FP_OP_ADDR_INDEX_MASK        (0xF << 19)
+
+//== Register selection ==
+#define NVFX_FP_REG_TYPE_SHIFT           0
+#define NVFX_FP_REG_TYPE_MASK           (3 << 0)
+#  define NVFX_FP_REG_TYPE_TEMP   0
+#  define NVFX_FP_REG_TYPE_INPUT  1
+#  define NVFX_FP_REG_TYPE_CONST  2
+#define NVFX_FP_REG_SRC_SHIFT            2
+#define NV30_FP_REG_SRC_MASK              (31 << 2)
+#define NV40_FP_REG_SRC_MASK              (63 << 2)
+#define NVFX_FP_REG_SRC_HALF            (1 << 8)
+#define NVFX_FP_REG_SWZ_ALL_SHIFT        9
+#define NVFX_FP_REG_SWZ_ALL_MASK        (255 << 9)
+#define NVFX_FP_REG_SWZ_X_SHIFT          9
+#define NVFX_FP_REG_SWZ_X_MASK          (3 << 9)
+#define NVFX_FP_REG_SWZ_Y_SHIFT          11
+#define NVFX_FP_REG_SWZ_Y_MASK          (3 << 11)
+#define NVFX_FP_REG_SWZ_Z_SHIFT          13
+#define NVFX_FP_REG_SWZ_Z_MASK          (3 << 13)
+#define NVFX_FP_REG_SWZ_W_SHIFT          15
+#define NVFX_FP_REG_SWZ_W_MASK          (3 << 15)
+#  define NVFX_FP_SWIZZLE_X  0
+#  define NVFX_FP_SWIZZLE_Y  1
+#  define NVFX_FP_SWIZZLE_Z  2
+#  define NVFX_FP_SWIZZLE_W  3
+#define NVFX_FP_REG_NEGATE          (1 << 17)
+
+#define NVFXSR_NONE    0
+#define NVFXSR_OUTPUT  1
+#define NVFXSR_INPUT   2
+#define NVFXSR_TEMP    3
+#define NVFXSR_CONST   5
+#define NVFXSR_IMM     6
+
+#define NVFX_COND_FL  0
+#define NVFX_COND_LT  1
+#define NVFX_COND_EQ  2
+#define NVFX_COND_LE  3
+#define NVFX_COND_GT  4
+#define NVFX_COND_NE  5
+#define NVFX_COND_GE  6
+#define NVFX_COND_TR  7
+
+/* Yes, this are ordered differently... */
+
+#define NVFX_VP_MASK_X 8
+#define NVFX_VP_MASK_Y 4
+#define NVFX_VP_MASK_Z 2
+#define NVFX_VP_MASK_W 1
+#define NVFX_VP_MASK_ALL 0xf
+
+#define NVFX_FP_MASK_X 1
+#define NVFX_FP_MASK_Y 2
+#define NVFX_FP_MASK_Z 4
+#define NVFX_FP_MASK_W 8
+#define NVFX_FP_MASK_ALL 0xf
+
+#define NVFX_SWZ_X 0
+#define NVFX_SWZ_Y 1
+#define NVFX_SWZ_Z 2
+#define NVFX_SWZ_W 3
+
+#define swz(s,x,y,z,w) nvfx_src_swz((s), NVFX_SWZ_##x, NVFX_SWZ_##y, NVFX_SWZ_##z, NVFX_SWZ_##w)
+#define neg(s) nvfx_src_neg((s))
+#define abs(s) nvfx_src_abs((s))
+
+struct nvfx_reg {
+       int8_t type;
+       uint32_t index;
+};
+
+struct nvfx_src {
+       struct nvfx_reg reg;
+
+       uint8_t indirect : 1;
+       uint8_t indirect_reg : 1;
+       uint8_t indirect_swz : 2;
+       uint8_t negate : 1;
+       uint8_t abs : 1;
+       uint8_t swz[4];
+};
+
+struct nvfx_insn
+{
+       uint8_t op;
+       char scale;
+       int8_t unit;
+       uint8_t mask;
+       uint8_t cc_swz[4];
+
+       uint8_t sat : 1;
+       uint8_t cc_update : 1;
+       uint8_t cc_update_reg : 1;
+       uint8_t cc_test : 3;
+       uint8_t cc_test_reg : 1;
+
+       struct nvfx_reg dst;
+       struct nvfx_src src[3];
+};
+
+static INLINE struct nvfx_insn
+nvfx_insn(boolean sat, unsigned op, int unit, struct nvfx_reg dst, unsigned mask, struct nvfx_src s0, struct nvfx_src s1, struct nvfx_src s2)
+{
+       struct nvfx_insn insn = {
+               .op = op,
+               .scale = 0,
+               .unit = unit,
+               .sat = sat,
+               .mask = mask,
+               .cc_update = 0,
+               .cc_update_reg = 0,
+               .cc_test = NVFX_COND_TR,
+               .cc_test_reg = 0,
+               .cc_swz = { 0, 1, 2, 3 },
+               .dst = dst,
+               .src = {s0, s1, s2}
+       };
+       return insn;
+}
+
+static INLINE struct nvfx_reg
+nvfx_reg(int type, int index)
+{
+       struct nvfx_reg temp = {
+               .type = type,
+               .index = index,
+       };
+       return temp;
+}
+
+static INLINE struct nvfx_src
+nvfx_src(struct nvfx_reg reg)
+{
+       struct nvfx_src temp = {
+               .reg = reg,
+               .abs = 0,
+               .negate = 0,
+               .swz = { 0, 1, 2, 3 },
+               .indirect = 0,
+       };
+       return temp;
+}
+
+static INLINE struct nvfx_src
+nvfx_src_swz(struct nvfx_src src, int x, int y, int z, int w)
+{
+       struct nvfx_src dst = src;
+
+       dst.swz[NVFX_SWZ_X] = src.swz[x];
+       dst.swz[NVFX_SWZ_Y] = src.swz[y];
+       dst.swz[NVFX_SWZ_Z] = src.swz[z];
+       dst.swz[NVFX_SWZ_W] = src.swz[w];
+       return dst;
+}
+
+static INLINE struct nvfx_src
+nvfx_src_neg(struct nvfx_src src)
+{
+       src.negate = !src.negate;
+       return src;
+}
+
+static INLINE struct nvfx_src
+nvfx_src_abs(struct nvfx_src src)
+{
+       src.abs = 1;
+       return src;
+}
+
+struct nvfx_relocation {
+        unsigned location;
+        unsigned target;
+};
+
+#endif
diff --git a/src/gallium/drivers/nv30/nvfx_vertprog.c b/src/gallium/drivers/nv30/nvfx_vertprog.c
new file mode 100644 (file)
index 0000000..d7eb9fb
--- /dev/null
@@ -0,0 +1,1116 @@
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+#include "util/u_linkage.h"
+#include "util/u_debug.h"
+
+#include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_util.h"
+#include "tgsi/tgsi_ureg.h"
+
+#include "draw/draw_context.h"
+
+#include "nv30-40_3d.xml.h"
+#include "nv30_context.h"
+#include "nv30_resource.h"
+
+/* TODO (at least...):
+ *  1. Indexed consts  + ARL
+ *  3. NV_vp11, NV_vp2, NV_vp3 features
+ *       - extra arith opcodes
+ *       - branching
+ *       - texture sampling
+ *       - indexed attribs
+ *       - indexed results
+ *  4. bugs
+ */
+
+#include "nv30_vertprog.h"
+#include "nv40_vertprog.h"
+
+struct nvfx_loop_entry {
+   unsigned brk_target;
+   unsigned cont_target;
+};
+
+struct nvfx_vpc {
+   struct nv30_context* nv30;
+   struct pipe_shader_state pipe;
+   struct nv30_vertprog *vp;
+   struct tgsi_shader_info* info;
+
+   struct nv30_vertprog_exec *vpi;
+
+   unsigned r_temps;
+   unsigned r_temps_discard;
+   struct nvfx_reg r_result[PIPE_MAX_SHADER_OUTPUTS];
+   struct nvfx_reg *r_address;
+   struct nvfx_reg *r_temp;
+   struct nvfx_reg *r_const;
+   struct nvfx_reg r_0_1;
+
+   struct nvfx_reg *imm;
+   unsigned nr_imm;
+
+   int hpos_idx;
+   int cvtx_idx;
+
+   struct util_dynarray label_relocs;
+   struct util_dynarray loop_stack;
+};
+
+static struct nvfx_reg
+temp(struct nvfx_vpc *vpc)
+{
+   int idx = ffs(~vpc->r_temps) - 1;
+
+   if (idx < 0) {
+      NOUVEAU_ERR("out of temps!!\n");
+      assert(0);
+      return nvfx_reg(NVFXSR_TEMP, 0);
+   }
+
+   vpc->r_temps |= (1 << idx);
+   vpc->r_temps_discard |= (1 << idx);
+   return nvfx_reg(NVFXSR_TEMP, idx);
+}
+
+static inline void
+release_temps(struct nvfx_vpc *vpc)
+{
+   vpc->r_temps &= ~vpc->r_temps_discard;
+   vpc->r_temps_discard = 0;
+}
+
+static struct nvfx_reg
+constant(struct nvfx_vpc *vpc, int pipe, float x, float y, float z, float w)
+{
+   struct nv30_vertprog *vp = vpc->vp;
+   struct nv30_vertprog_data *vpd;
+   int idx;
+
+   if (pipe >= 0) {
+      for (idx = 0; idx < vp->nr_consts; idx++) {
+         if (vp->consts[idx].index == pipe)
+            return nvfx_reg(NVFXSR_CONST, idx);
+      }
+   }
+
+   idx = vp->nr_consts++;
+   vp->consts = realloc(vp->consts, sizeof(*vpd) * vp->nr_consts);
+   vpd = &vp->consts[idx];
+
+   vpd->index = pipe;
+   vpd->value[0] = x;
+   vpd->value[1] = y;
+   vpd->value[2] = z;
+   vpd->value[3] = w;
+   return nvfx_reg(NVFXSR_CONST, idx);
+}
+
+#define arith(s,t,o,d,m,s0,s1,s2) \
+   nvfx_insn((s), (NVFX_VP_INST_SLOT_##t << 7) | NVFX_VP_INST_##t##_OP_##o, -1, (d), (m), (s0), (s1), (s2))
+
+static void
+emit_src(struct nv30_context *nv30, struct nvfx_vpc *vpc, uint32_t *hw,
+         int pos, struct nvfx_src src)
+{
+   struct nv30_vertprog *vp = vpc->vp;
+   uint32_t sr = 0;
+   struct nvfx_relocation reloc;
+
+   switch (src.reg.type) {
+   case NVFXSR_TEMP:
+      sr |= (NVFX_VP(SRC_REG_TYPE_TEMP) << NVFX_VP(SRC_REG_TYPE_SHIFT));
+      sr |= (src.reg.index << NVFX_VP(SRC_TEMP_SRC_SHIFT));
+      break;
+   case NVFXSR_INPUT:
+      sr |= (NVFX_VP(SRC_REG_TYPE_INPUT) <<
+             NVFX_VP(SRC_REG_TYPE_SHIFT));
+      vp->ir |= (1 << src.reg.index);
+      hw[1] |= (src.reg.index << NVFX_VP(INST_INPUT_SRC_SHIFT));
+      break;
+   case NVFXSR_CONST:
+      sr |= (NVFX_VP(SRC_REG_TYPE_CONST) <<
+             NVFX_VP(SRC_REG_TYPE_SHIFT));
+      if (src.reg.index < 512) {
+         reloc.location = vp->nr_insns - 1;
+         reloc.target = src.reg.index;
+         util_dynarray_append(&vp->const_relocs, struct nvfx_relocation, reloc);
+      } else {
+         hw[1] |= (src.reg.index - 512) << NVFX_VP(INST_CONST_SRC_SHIFT);
+      }
+      break;
+   case NVFXSR_NONE:
+      sr |= (NVFX_VP(SRC_REG_TYPE_INPUT) <<
+             NVFX_VP(SRC_REG_TYPE_SHIFT));
+      break;
+   default:
+      assert(0);
+   }
+
+   if (src.negate)
+      sr |= NVFX_VP(SRC_NEGATE);
+
+   if (src.abs)
+      hw[0] |= (1 << (21 + pos));
+
+   sr |= ((src.swz[0] << NVFX_VP(SRC_SWZ_X_SHIFT)) |
+          (src.swz[1] << NVFX_VP(SRC_SWZ_Y_SHIFT)) |
+          (src.swz[2] << NVFX_VP(SRC_SWZ_Z_SHIFT)) |
+          (src.swz[3] << NVFX_VP(SRC_SWZ_W_SHIFT)));
+
+   if(src.indirect) {
+      if(src.reg.type == NVFXSR_CONST)
+         hw[3] |= NVFX_VP(INST_INDEX_CONST);
+      else if(src.reg.type == NVFXSR_INPUT)
+         hw[0] |= NVFX_VP(INST_INDEX_INPUT);
+      else
+         assert(0);
+      if(src.indirect_reg)
+         hw[0] |= NVFX_VP(INST_ADDR_REG_SELECT_1);
+      hw[0] |= src.indirect_swz << NVFX_VP(INST_ADDR_SWZ_SHIFT);
+   }
+
+   switch (pos) {
+   case 0:
+      hw[1] |= ((sr & NVFX_VP(SRC0_HIGH_MASK)) >>
+           NVFX_VP(SRC0_HIGH_SHIFT)) << NVFX_VP(INST_SRC0H_SHIFT);
+      hw[2] |= (sr & NVFX_VP(SRC0_LOW_MASK)) <<
+           NVFX_VP(INST_SRC0L_SHIFT);
+      break;
+   case 1:
+      hw[2] |= sr << NVFX_VP(INST_SRC1_SHIFT);
+      break;
+   case 2:
+      hw[2] |= ((sr & NVFX_VP(SRC2_HIGH_MASK)) >>
+           NVFX_VP(SRC2_HIGH_SHIFT)) << NVFX_VP(INST_SRC2H_SHIFT);
+      hw[3] |= (sr & NVFX_VP(SRC2_LOW_MASK)) <<
+           NVFX_VP(INST_SRC2L_SHIFT);
+      break;
+   default:
+      assert(0);
+   }
+}
+
+static void
+emit_dst(struct nv30_context *nv30, struct nvfx_vpc *vpc, uint32_t *hw,
+         int slot, struct nvfx_reg dst)
+{
+   struct nv30_vertprog *vp = vpc->vp;
+
+   switch (dst.type) {
+   case NVFXSR_NONE:
+      if(!nv30->is_nv4x)
+         hw[0] |= NV30_VP_INST_DEST_TEMP_ID_MASK;
+      else {
+         hw[3] |= NV40_VP_INST_DEST_MASK;
+         if (slot == 0)
+            hw[0] |= NV40_VP_INST_VEC_DEST_TEMP_MASK;
+         else
+            hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK;
+      }
+      break;
+   case NVFXSR_TEMP:
+      if(!nv30->is_nv4x)
+         hw[0] |= (dst.index << NV30_VP_INST_DEST_TEMP_ID_SHIFT);
+      else {
+         hw[3] |= NV40_VP_INST_DEST_MASK;
+         if (slot == 0)
+            hw[0] |= (dst.index << NV40_VP_INST_VEC_DEST_TEMP_SHIFT);
+         else
+            hw[3] |= (dst.index << NV40_VP_INST_SCA_DEST_TEMP_SHIFT);
+      }
+      break;
+   case NVFXSR_OUTPUT:
+      /* TODO: this may be wrong because on nv30 COL0 and BFC0 are swapped */
+      if(nv30->is_nv4x) {
+         switch (dst.index) {
+         case NV30_VP_INST_DEST_CLP(0):
+            dst.index = NVFX_VP(INST_DEST_FOGC);
+            vp->or   |= (1 << 6);
+            break;
+         case NV30_VP_INST_DEST_CLP(1):
+            dst.index = NVFX_VP(INST_DEST_FOGC);
+            vp->or   |= (1 << 7);
+            break;
+         case NV30_VP_INST_DEST_CLP(2):
+            dst.index = NVFX_VP(INST_DEST_FOGC);
+            vp->or   |= (1 << 8);
+            break;
+         case NV30_VP_INST_DEST_CLP(3):
+            dst.index = NVFX_VP(INST_DEST_PSZ);
+            vp->or   |= (1 << 9);
+            break;
+         case NV30_VP_INST_DEST_CLP(4):
+            dst.index = NVFX_VP(INST_DEST_PSZ);
+            vp->or   |= (1 << 10);
+            break;
+         case NV30_VP_INST_DEST_CLP(5):
+            dst.index = NVFX_VP(INST_DEST_PSZ);
+            vp->or   |= (1 << 11);
+            break;
+         case NV40_VP_INST_DEST_COL0: vp->or |= (1 << 0); break;
+         case NV40_VP_INST_DEST_COL1: vp->or |= (1 << 1); break;
+         case NV40_VP_INST_DEST_BFC0: vp->or |= (1 << 2); break;
+         case NV40_VP_INST_DEST_BFC1: vp->or |= (1 << 3); break;
+         case NV40_VP_INST_DEST_FOGC: vp->or |= (1 << 4); break;
+         case NV40_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break;
+         }
+      }
+
+      if(!nv30->is_nv4x) {
+         hw[3] |= (dst.index << NV30_VP_INST_DEST_SHIFT);
+         hw[0] |= NV30_VP_INST_VEC_DEST_TEMP_MASK;
+
+         /*XXX: no way this is entirely correct, someone needs to
+          *     figure out what exactly it is.
+          */
+         hw[3] |= 0x800;
+      } else {
+         hw[3] |= (dst.index << NV40_VP_INST_DEST_SHIFT);
+         if (slot == 0) {
+            hw[0] |= NV40_VP_INST_VEC_RESULT;
+            hw[0] |= NV40_VP_INST_VEC_DEST_TEMP_MASK;
+         } else {
+            hw[3] |= NV40_VP_INST_SCA_RESULT;
+            hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK;
+         }
+      }
+      break;
+   default:
+      assert(0);
+   }
+}
+
+static void
+nvfx_vp_emit(struct nvfx_vpc *vpc, struct nvfx_insn insn)
+{
+   struct nv30_context *nv30 = vpc->nv30;
+   struct nv30_vertprog *vp = vpc->vp;
+   unsigned slot = insn.op >> 7;
+   unsigned op = insn.op & 0x7f;
+   uint32_t *hw;
+
+   vp->insns = realloc(vp->insns, ++vp->nr_insns * sizeof(*vpc->vpi));
+   vpc->vpi = &vp->insns[vp->nr_insns - 1];
+   memset(vpc->vpi, 0, sizeof(*vpc->vpi));
+
+   hw = vpc->vpi->data;
+
+   if (insn.cc_test != NVFX_COND_TR)
+      hw[0] |= NVFX_VP(INST_COND_TEST_ENABLE);
+   hw[0] |= (insn.cc_test << NVFX_VP(INST_COND_SHIFT));
+   hw[0] |= ((insn.cc_swz[0] << NVFX_VP(INST_COND_SWZ_X_SHIFT)) |
+             (insn.cc_swz[1] << NVFX_VP(INST_COND_SWZ_Y_SHIFT)) |
+             (insn.cc_swz[2] << NVFX_VP(INST_COND_SWZ_Z_SHIFT)) |
+             (insn.cc_swz[3] << NVFX_VP(INST_COND_SWZ_W_SHIFT)));
+   if(insn.cc_update)
+      hw[0] |= NVFX_VP(INST_COND_UPDATE_ENABLE);
+
+   if(insn.sat) {
+      assert(nv30->use_nv4x);
+      if(nv30->use_nv4x)
+         hw[0] |= NV40_VP_INST_SATURATE;
+   }
+
+   if(!nv30->is_nv4x) {
+      if(slot == 0)
+         hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT);
+      else {
+         hw[0] |= ((op >> 4) << NV30_VP_INST_SCA_OPCODEH_SHIFT);
+         hw[1] |= ((op & 0xf) << NV30_VP_INST_SCA_OPCODEL_SHIFT);
+      }
+//      hw[3] |= NVFX_VP(INST_SCA_DEST_TEMP_MASK);
+//      hw[3] |= (mask << NVFX_VP(INST_VEC_WRITEMASK_SHIFT));
+
+      if (insn.dst.type == NVFXSR_OUTPUT) {
+         if (slot)
+            hw[3] |= (insn.mask << NV30_VP_INST_SDEST_WRITEMASK_SHIFT);
+         else
+            hw[3] |= (insn.mask << NV30_VP_INST_VDEST_WRITEMASK_SHIFT);
+      } else {
+         if (slot)
+            hw[3] |= (insn.mask << NV30_VP_INST_STEMP_WRITEMASK_SHIFT);
+         else
+            hw[3] |= (insn.mask << NV30_VP_INST_VTEMP_WRITEMASK_SHIFT);
+      }
+    } else {
+      if (slot == 0) {
+         hw[1] |= (op << NV40_VP_INST_VEC_OPCODE_SHIFT);
+         hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK;
+         hw[3] |= (insn.mask << NV40_VP_INST_VEC_WRITEMASK_SHIFT);
+       } else {
+         hw[1] |= (op << NV40_VP_INST_SCA_OPCODE_SHIFT);
+         hw[0] |= NV40_VP_INST_VEC_DEST_TEMP_MASK ;
+         hw[3] |= (insn.mask << NV40_VP_INST_SCA_WRITEMASK_SHIFT);
+      }
+   }
+
+   emit_dst(nv30, vpc, hw, slot, insn.dst);
+   emit_src(nv30, vpc, hw, 0, insn.src[0]);
+   emit_src(nv30, vpc, hw, 1, insn.src[1]);
+   emit_src(nv30, vpc, hw, 2, insn.src[2]);
+
+//   if(insn.src[0].indirect || op == NVFX_VP_INST_VEC_OP_ARL)
+//      hw[3] |= NV40_VP_INST_SCA_RESULT;
+}
+
+static inline struct nvfx_src
+tgsi_src(struct nvfx_vpc *vpc, const struct tgsi_full_src_register *fsrc) {
+   struct nvfx_src src;
+
+   switch (fsrc->Register.File) {
+   case TGSI_FILE_INPUT:
+      src.reg = nvfx_reg(NVFXSR_INPUT, fsrc->Register.Index);
+      break;
+   case TGSI_FILE_CONSTANT:
+      src.reg = vpc->r_const[fsrc->Register.Index];
+      break;
+   case TGSI_FILE_IMMEDIATE:
+      src.reg = vpc->imm[fsrc->Register.Index];
+      break;
+   case TGSI_FILE_TEMPORARY:
+      src.reg = vpc->r_temp[fsrc->Register.Index];
+      break;
+   default:
+      NOUVEAU_ERR("bad src file\n");
+      src.reg.index = 0;
+      src.reg.type = -1;
+      break;
+   }
+
+   src.abs = fsrc->Register.Absolute;
+   src.negate = fsrc->Register.Negate;
+   src.swz[0] = fsrc->Register.SwizzleX;
+   src.swz[1] = fsrc->Register.SwizzleY;
+   src.swz[2] = fsrc->Register.SwizzleZ;
+   src.swz[3] = fsrc->Register.SwizzleW;
+   src.indirect = 0;
+   src.indirect_reg = 0;
+   src.indirect_swz = 0;
+
+   if(fsrc->Register.Indirect) {
+      if(fsrc->Indirect.File == TGSI_FILE_ADDRESS &&
+         (fsrc->Register.File == TGSI_FILE_CONSTANT ||
+          fsrc->Register.File == TGSI_FILE_INPUT)) {
+         src.indirect = 1;
+         src.indirect_reg = fsrc->Indirect.Index;
+         src.indirect_swz = fsrc->Indirect.SwizzleX;
+      } else {
+         src.reg.index = 0;
+         src.reg.type = -1;
+      }
+   }
+
+   return src;
+}
+
+static INLINE struct nvfx_reg
+tgsi_dst(struct nvfx_vpc *vpc, const struct tgsi_full_dst_register *fdst) {
+   struct nvfx_reg dst;
+
+   switch (fdst->Register.File) {
+   case TGSI_FILE_NULL:
+      dst = nvfx_reg(NVFXSR_NONE, 0);
+      break;
+   case TGSI_FILE_OUTPUT:
+      dst = vpc->r_result[fdst->Register.Index];
+      break;
+   case TGSI_FILE_TEMPORARY:
+      dst = vpc->r_temp[fdst->Register.Index];
+      break;
+   case TGSI_FILE_ADDRESS:
+      dst = vpc->r_address[fdst->Register.Index];
+      break;
+   default:
+      NOUVEAU_ERR("bad dst file %i\n", fdst->Register.File);
+      dst.index = 0;
+      dst.type = 0;
+      break;
+   }
+
+   return dst;
+}
+
+static inline int
+tgsi_mask(uint tgsi)
+{
+   int mask = 0;
+
+   if (tgsi & TGSI_WRITEMASK_X) mask |= NVFX_VP_MASK_X;
+   if (tgsi & TGSI_WRITEMASK_Y) mask |= NVFX_VP_MASK_Y;
+   if (tgsi & TGSI_WRITEMASK_Z) mask |= NVFX_VP_MASK_Z;
+   if (tgsi & TGSI_WRITEMASK_W) mask |= NVFX_VP_MASK_W;
+   return mask;
+}
+
+static boolean
+nvfx_vertprog_parse_instruction(struct nv30_context *nv30, struct nvfx_vpc *vpc,
+            unsigned idx, const struct tgsi_full_instruction *finst)
+{
+   struct nvfx_src src[3], tmp;
+   struct nvfx_reg dst;
+   struct nvfx_reg final_dst;
+   struct nvfx_src none = nvfx_src(nvfx_reg(NVFXSR_NONE, 0));
+   struct nvfx_insn insn;
+   struct nvfx_relocation reloc;
+   struct nvfx_loop_entry loop;
+   boolean sat = FALSE;
+   int mask;
+   int ai = -1, ci = -1, ii = -1;
+   int i;
+   unsigned sub_depth = 0;
+
+   for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
+      const struct tgsi_full_src_register *fsrc;
+
+      fsrc = &finst->Src[i];
+      if (fsrc->Register.File == TGSI_FILE_TEMPORARY) {
+         src[i] = tgsi_src(vpc, fsrc);
+      }
+   }
+
+   for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
+      const struct tgsi_full_src_register *fsrc;
+
+      fsrc = &finst->Src[i];
+
+      switch (fsrc->Register.File) {
+      case TGSI_FILE_INPUT:
+         if (ai == -1 || ai == fsrc->Register.Index) {
+            ai = fsrc->Register.Index;
+            src[i] = tgsi_src(vpc, fsrc);
+         } else {
+            src[i] = nvfx_src(temp(vpc));
+            nvfx_vp_emit(vpc, arith(0, VEC, MOV, src[i].reg, NVFX_VP_MASK_ALL,
+                         tgsi_src(vpc, fsrc), none, none));
+         }
+         break;
+      case TGSI_FILE_CONSTANT:
+         if ((ci == -1 && ii == -1) ||
+             ci == fsrc->Register.Index) {
+            ci = fsrc->Register.Index;
+            src[i] = tgsi_src(vpc, fsrc);
+         } else {
+            src[i] = nvfx_src(temp(vpc));
+            nvfx_vp_emit(vpc, arith(0, VEC, MOV, src[i].reg, NVFX_VP_MASK_ALL,
+                         tgsi_src(vpc, fsrc), none, none));
+         }
+         break;
+      case TGSI_FILE_IMMEDIATE:
+         if ((ci == -1 && ii == -1) ||
+             ii == fsrc->Register.Index) {
+            ii = fsrc->Register.Index;
+            src[i] = tgsi_src(vpc, fsrc);
+         } else {
+            src[i] = nvfx_src(temp(vpc));
+            nvfx_vp_emit(vpc, arith(0, VEC, MOV, src[i].reg, NVFX_VP_MASK_ALL,
+                         tgsi_src(vpc, fsrc), none, none));
+         }
+         break;
+      case TGSI_FILE_TEMPORARY:
+         /* handled above */
+         break;
+      default:
+         NOUVEAU_ERR("bad src file\n");
+         return FALSE;
+      }
+   }
+
+   for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
+      if(src[i].reg.type < 0)
+         return FALSE;
+   }
+
+   if(finst->Dst[0].Register.File == TGSI_FILE_ADDRESS &&
+      finst->Instruction.Opcode != TGSI_OPCODE_ARL)
+      return FALSE;
+
+   final_dst = dst  = tgsi_dst(vpc, &finst->Dst[0]);
+   mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
+   if(finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) {
+      assert(finst->Instruction.Opcode != TGSI_OPCODE_ARL);
+      if (nv30->use_nv4x)
+         sat = TRUE;
+      else
+      if(dst.type != NVFXSR_TEMP)
+         dst = temp(vpc);
+   }
+
+   switch (finst->Instruction.Opcode) {
+   case TGSI_OPCODE_ABS:
+      nvfx_vp_emit(vpc, arith(sat, VEC, MOV, dst, mask, abs(src[0]), none, none));
+      break;
+   case TGSI_OPCODE_ADD:
+      nvfx_vp_emit(vpc, arith(sat, VEC, ADD, dst, mask, src[0], none, src[1]));
+      break;
+   case TGSI_OPCODE_ARL:
+      nvfx_vp_emit(vpc, arith(0, VEC, ARL, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_CMP:
+      insn = arith(0, VEC, MOV, none.reg, mask, src[0], none, none);
+      insn.cc_update = 1;
+      nvfx_vp_emit(vpc, insn);
+
+      insn = arith(sat, VEC, MOV, dst, mask, src[2], none, none);
+      insn.cc_test = NVFX_COND_GE;
+      nvfx_vp_emit(vpc, insn);
+
+      insn = arith(sat, VEC, MOV, dst, mask, src[1], none, none);
+      insn.cc_test = NVFX_COND_LT;
+      nvfx_vp_emit(vpc, insn);
+      break;
+   case TGSI_OPCODE_COS:
+      nvfx_vp_emit(vpc, arith(sat, SCA, COS, dst, mask, none, none, src[0]));
+      break;
+   case TGSI_OPCODE_DP2:
+      tmp = nvfx_src(temp(vpc));
+      nvfx_vp_emit(vpc, arith(0, VEC, MUL, tmp.reg, NVFX_VP_MASK_X | NVFX_VP_MASK_Y, src[0], src[1], none));
+      nvfx_vp_emit(vpc, arith(sat, VEC, ADD, dst, mask, swz(tmp, X, X, X, X), none, swz(tmp, Y, Y, Y, Y)));
+      break;
+   case TGSI_OPCODE_DP3:
+      nvfx_vp_emit(vpc, arith(sat, VEC, DP3, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_DP4:
+      nvfx_vp_emit(vpc, arith(sat, VEC, DP4, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_DPH:
+      nvfx_vp_emit(vpc, arith(sat, VEC, DPH, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_DST:
+      nvfx_vp_emit(vpc, arith(sat, VEC, DST, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_EX2:
+      nvfx_vp_emit(vpc, arith(sat, SCA, EX2, dst, mask, none, none, src[0]));
+      break;
+   case TGSI_OPCODE_EXP:
+      nvfx_vp_emit(vpc, arith(sat, SCA, EXP, dst, mask, none, none, src[0]));
+      break;
+   case TGSI_OPCODE_FLR:
+      nvfx_vp_emit(vpc, arith(sat, VEC, FLR, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_FRC:
+      nvfx_vp_emit(vpc, arith(sat, VEC, FRC, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_LG2:
+      nvfx_vp_emit(vpc, arith(sat, SCA, LG2, dst, mask, none, none, src[0]));
+      break;
+   case TGSI_OPCODE_LIT:
+      nvfx_vp_emit(vpc, arith(sat, SCA, LIT, dst, mask, none, none, src[0]));
+      break;
+   case TGSI_OPCODE_LOG:
+      nvfx_vp_emit(vpc, arith(sat, SCA, LOG, dst, mask, none, none, src[0]));
+      break;
+   case TGSI_OPCODE_LRP:
+      tmp = nvfx_src(temp(vpc));
+      nvfx_vp_emit(vpc, arith(0, VEC, MAD, tmp.reg, mask, neg(src[0]), src[2], src[2]));
+      nvfx_vp_emit(vpc, arith(sat, VEC, MAD, dst, mask, src[0], src[1], tmp));
+      break;
+   case TGSI_OPCODE_MAD:
+      nvfx_vp_emit(vpc, arith(sat, VEC, MAD, dst, mask, src[0], src[1], src[2]));
+      break;
+   case TGSI_OPCODE_MAX:
+      nvfx_vp_emit(vpc, arith(sat, VEC, MAX, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_MIN:
+      nvfx_vp_emit(vpc, arith(sat, VEC, MIN, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_MOV:
+      nvfx_vp_emit(vpc, arith(sat, VEC, MOV, dst, mask, src[0], none, none));
+      break;
+   case TGSI_OPCODE_MUL:
+      nvfx_vp_emit(vpc, arith(sat, VEC, MUL, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_NOP:
+      break;
+   case TGSI_OPCODE_POW:
+      tmp = nvfx_src(temp(vpc));
+      nvfx_vp_emit(vpc, arith(0, SCA, LG2, tmp.reg, NVFX_VP_MASK_X, none, none, swz(src[0], X, X, X, X)));
+      nvfx_vp_emit(vpc, arith(0, VEC, MUL, tmp.reg, NVFX_VP_MASK_X, swz(tmp, X, X, X, X), swz(src[1], X, X, X, X), none));
+      nvfx_vp_emit(vpc, arith(sat, SCA, EX2, dst, mask, none, none, swz(tmp, X, X, X, X)));
+      break;
+   case TGSI_OPCODE_RCP:
+      nvfx_vp_emit(vpc, arith(sat, SCA, RCP, dst, mask, none, none, src[0]));
+      break;
+   case TGSI_OPCODE_RSQ:
+      nvfx_vp_emit(vpc, arith(sat, SCA, RSQ, dst, mask, none, none, abs(src[0])));
+      break;
+   case TGSI_OPCODE_SEQ:
+      nvfx_vp_emit(vpc, arith(sat, VEC, SEQ, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SFL:
+      nvfx_vp_emit(vpc, arith(sat, VEC, SFL, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SGE:
+      nvfx_vp_emit(vpc, arith(sat, VEC, SGE, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SGT:
+      nvfx_vp_emit(vpc, arith(sat, VEC, SGT, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SIN:
+      nvfx_vp_emit(vpc, arith(sat, SCA, SIN, dst, mask, none, none, src[0]));
+      break;
+   case TGSI_OPCODE_SLE:
+      nvfx_vp_emit(vpc, arith(sat, VEC, SLE, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SLT:
+      nvfx_vp_emit(vpc, arith(sat, VEC, SLT, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SNE:
+      nvfx_vp_emit(vpc, arith(sat, VEC, SNE, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SSG:
+      nvfx_vp_emit(vpc, arith(sat, VEC, SSG, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_STR:
+      nvfx_vp_emit(vpc, arith(sat, VEC, STR, dst, mask, src[0], src[1], none));
+      break;
+   case TGSI_OPCODE_SUB:
+      nvfx_vp_emit(vpc, arith(sat, VEC, ADD, dst, mask, src[0], none, neg(src[1])));
+      break;
+   case TGSI_OPCODE_TRUNC:
+      tmp = nvfx_src(temp(vpc));
+      insn = arith(0, VEC, MOV, none.reg, mask, src[0], none, none);
+      insn.cc_update = 1;
+      nvfx_vp_emit(vpc, insn);
+
+      nvfx_vp_emit(vpc, arith(0, VEC, FLR, tmp.reg, mask, abs(src[0]), none, none));
+      nvfx_vp_emit(vpc, arith(sat, VEC, MOV, dst, mask, tmp, none, none));
+
+      insn = arith(sat, VEC, MOV, dst, mask, neg(tmp), none, none);
+      insn.cc_test = NVFX_COND_LT;
+      nvfx_vp_emit(vpc, insn);
+      break;
+   case TGSI_OPCODE_XPD:
+      tmp = nvfx_src(temp(vpc));
+      nvfx_vp_emit(vpc, arith(0, VEC, MUL, tmp.reg, mask, swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none));
+      nvfx_vp_emit(vpc, arith(sat, VEC, MAD, dst, (mask & ~NVFX_VP_MASK_W), swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y), neg(tmp)));
+      break;
+   case TGSI_OPCODE_IF:
+      insn = arith(0, VEC, MOV, none.reg, NVFX_VP_MASK_X, src[0], none, none);
+      insn.cc_update = 1;
+      nvfx_vp_emit(vpc, insn);
+
+      reloc.location = vpc->vp->nr_insns;
+      reloc.target = finst->Label.Label + 1;
+      util_dynarray_append(&vpc->label_relocs, struct nvfx_relocation, reloc);
+
+      insn = arith(0, SCA, BRA, none.reg, 0, none, none, none);
+      insn.cc_test = NVFX_COND_EQ;
+      insn.cc_swz[0] = insn.cc_swz[1] = insn.cc_swz[2] = insn.cc_swz[3] = 0;
+      nvfx_vp_emit(vpc, insn);
+      break;
+   case TGSI_OPCODE_ELSE:
+   case TGSI_OPCODE_BRA:
+   case TGSI_OPCODE_CAL:
+      reloc.location = vpc->vp->nr_insns;
+      reloc.target = finst->Label.Label;
+      util_dynarray_append(&vpc->label_relocs, struct nvfx_relocation, reloc);
+
+      if(finst->Instruction.Opcode == TGSI_OPCODE_CAL)
+         insn = arith(0, SCA, CAL, none.reg, 0, none, none, none);
+      else
+         insn = arith(0, SCA, BRA, none.reg, 0, none, none, none);
+      nvfx_vp_emit(vpc, insn);
+      break;
+   case TGSI_OPCODE_RET:
+      if(sub_depth || !vpc->vp->enabled_ucps) {
+         tmp = none;
+         tmp.swz[0] = tmp.swz[1] = tmp.swz[2] = tmp.swz[3] = 0;
+         nvfx_vp_emit(vpc, arith(0, SCA, RET, none.reg, 0, none, none, tmp));
+      } else {
+         reloc.location = vpc->vp->nr_insns;
+         reloc.target = vpc->info->num_instructions;
+         util_dynarray_append(&vpc->label_relocs, struct nvfx_relocation, reloc);
+         nvfx_vp_emit(vpc, arith(0, SCA, BRA, none.reg, 0, none, none, none));
+      }
+      break;
+   case TGSI_OPCODE_BGNSUB:
+      ++sub_depth;
+      break;
+   case TGSI_OPCODE_ENDSUB:
+      --sub_depth;
+      break;
+   case TGSI_OPCODE_ENDIF:
+      /* nothing to do here */
+      break;
+   case TGSI_OPCODE_BGNLOOP:
+      loop.cont_target = idx;
+      loop.brk_target = finst->Label.Label + 1;
+      util_dynarray_append(&vpc->loop_stack, struct nvfx_loop_entry, loop);
+      break;
+   case TGSI_OPCODE_ENDLOOP:
+      loop = util_dynarray_pop(&vpc->loop_stack, struct nvfx_loop_entry);
+
+      reloc.location = vpc->vp->nr_insns;
+      reloc.target = loop.cont_target;
+      util_dynarray_append(&vpc->label_relocs, struct nvfx_relocation, reloc);
+
+      nvfx_vp_emit(vpc, arith(0, SCA, BRA, none.reg, 0, none, none, none));
+      break;
+   case TGSI_OPCODE_CONT:
+      loop = util_dynarray_top(&vpc->loop_stack, struct nvfx_loop_entry);
+
+      reloc.location = vpc->vp->nr_insns;
+      reloc.target = loop.cont_target;
+      util_dynarray_append(&vpc->label_relocs, struct nvfx_relocation, reloc);
+
+      nvfx_vp_emit(vpc, arith(0, SCA, BRA, none.reg, 0, none, none, none));
+      break;
+   case TGSI_OPCODE_BRK:
+      loop = util_dynarray_top(&vpc->loop_stack, struct nvfx_loop_entry);
+
+      reloc.location = vpc->vp->nr_insns;
+      reloc.target = loop.brk_target;
+      util_dynarray_append(&vpc->label_relocs, struct nvfx_relocation, reloc);
+
+      nvfx_vp_emit(vpc, arith(0, SCA, BRA, none.reg, 0, none, none, none));
+      break;
+   case TGSI_OPCODE_END:
+      assert(!sub_depth);
+      if(vpc->vp->enabled_ucps) {
+         if(idx != (vpc->info->num_instructions - 1)) {
+            reloc.location = vpc->vp->nr_insns;
+            reloc.target = vpc->info->num_instructions;
+            util_dynarray_append(&vpc->label_relocs, struct nvfx_relocation, reloc);
+            nvfx_vp_emit(vpc, arith(0, SCA, BRA, none.reg, 0, none, none, none));
+         }
+      } else {
+         if(vpc->vp->nr_insns)
+            vpc->vp->insns[vpc->vp->nr_insns - 1].data[3] |= NVFX_VP_INST_LAST;
+         nvfx_vp_emit(vpc, arith(0, VEC, NOP, none.reg, 0, none, none, none));
+         vpc->vp->insns[vpc->vp->nr_insns - 1].data[3] |= NVFX_VP_INST_LAST;
+      }
+      break;
+   default:
+      NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode);
+      return FALSE;
+   }
+
+   if(finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE && !nv30->use_nv4x) {
+      if (!vpc->r_0_1.type)
+         vpc->r_0_1 = constant(vpc, -1, 0, 1, 0, 0);
+      nvfx_vp_emit(vpc, arith(0, VEC, MAX, dst, mask, nvfx_src(dst), swz(nvfx_src(vpc->r_0_1), X, X, X, X), none));
+      nvfx_vp_emit(vpc, arith(0, VEC, MIN, final_dst, mask, nvfx_src(dst), swz(nvfx_src(vpc->r_0_1), Y, Y, Y, Y), none));
+   }
+
+   release_temps(vpc);
+   return TRUE;
+}
+
+static boolean
+nvfx_vertprog_parse_decl_output(struct nv30_context *nv30, struct nvfx_vpc *vpc,
+                                const struct tgsi_full_declaration *fdec)
+{
+   unsigned num_texcoords = nv30->is_nv4x ? 10 : 8;
+   unsigned idx = fdec->Range.First;
+   int hw = 0, i;
+
+   switch (fdec->Semantic.Name) {
+   case TGSI_SEMANTIC_POSITION:
+      hw = NVFX_VP(INST_DEST_POS);
+      vpc->hpos_idx = idx;
+      break;
+   case TGSI_SEMANTIC_CLIPVERTEX:
+      vpc->r_result[idx] = temp(vpc);
+      vpc->r_temps_discard = 0;
+      vpc->cvtx_idx = idx;
+      return TRUE;
+   case TGSI_SEMANTIC_COLOR:
+      if (fdec->Semantic.Index == 0) {
+         hw = NVFX_VP(INST_DEST_COL0);
+      } else
+      if (fdec->Semantic.Index == 1) {
+         hw = NVFX_VP(INST_DEST_COL1);
+      } else {
+         NOUVEAU_ERR("bad colour semantic index\n");
+         return FALSE;
+      }
+      break;
+   case TGSI_SEMANTIC_BCOLOR:
+      if (fdec->Semantic.Index == 0) {
+         hw = NVFX_VP(INST_DEST_BFC0);
+      } else
+      if (fdec->Semantic.Index == 1) {
+         hw = NVFX_VP(INST_DEST_BFC1);
+      } else {
+         NOUVEAU_ERR("bad bcolour semantic index\n");
+         return FALSE;
+      }
+      break;
+   case TGSI_SEMANTIC_FOG:
+      hw = NVFX_VP(INST_DEST_FOGC);
+      break;
+   case TGSI_SEMANTIC_PSIZE:
+      hw = NVFX_VP(INST_DEST_PSZ);
+      break;
+   case TGSI_SEMANTIC_GENERIC:
+      for (i = 0; i < num_texcoords; i++) {
+         if (vpc->vp->texcoord[i] == fdec->Semantic.Index) {
+            hw = NVFX_VP(INST_DEST_TC(i));
+            break;
+         }
+      }
+
+      if (i == num_texcoords) {
+         vpc->r_result[idx] = nvfx_reg(NVFXSR_NONE, 0);
+         return TRUE;
+      }
+      break;
+   case TGSI_SEMANTIC_EDGEFLAG:
+      /* not really an error just a fallback */
+      NOUVEAU_ERR("cannot handle edgeflag output\n");
+      return FALSE;
+   default:
+      NOUVEAU_ERR("bad output semantic\n");
+      return FALSE;
+   }
+
+   vpc->r_result[idx] = nvfx_reg(NVFXSR_OUTPUT, hw);
+   return TRUE;
+}
+
+static boolean
+nvfx_vertprog_prepare(struct nv30_context *nv30, struct nvfx_vpc *vpc)
+{
+   struct tgsi_parse_context p;
+   int high_const = -1, high_temp = -1, high_addr = -1, nr_imm = 0, i;
+
+   tgsi_parse_init(&p, vpc->pipe.tokens);
+   while (!tgsi_parse_end_of_tokens(&p)) {
+      const union tgsi_full_token *tok = &p.FullToken;
+
+      tgsi_parse_token(&p);
+      switch(tok->Token.Type) {
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+         nr_imm++;
+         break;
+      case TGSI_TOKEN_TYPE_DECLARATION:
+      {
+         const struct tgsi_full_declaration *fdec;
+
+         fdec = &p.FullToken.FullDeclaration;
+         switch (fdec->Declaration.File) {
+         case TGSI_FILE_TEMPORARY:
+            if (fdec->Range.Last > high_temp) {
+               high_temp =
+                  fdec->Range.Last;
+            }
+            break;
+         case TGSI_FILE_ADDRESS:
+            if (fdec->Range.Last > high_addr) {
+               high_addr =
+                  fdec->Range.Last;
+            }
+            break;
+         case TGSI_FILE_CONSTANT:
+            if (fdec->Range.Last > high_const) {
+               high_const =
+                     fdec->Range.Last;
+            }
+            break;
+         case TGSI_FILE_OUTPUT:
+            if (!nvfx_vertprog_parse_decl_output(nv30, vpc, fdec))
+               return FALSE;
+            break;
+         default:
+            break;
+         }
+      }
+         break;
+      default:
+         break;
+      }
+   }
+   tgsi_parse_free(&p);
+
+   if (nr_imm) {
+      vpc->imm = CALLOC(nr_imm, sizeof(struct nvfx_reg));
+      assert(vpc->imm);
+   }
+
+   if (++high_temp) {
+      vpc->r_temp = CALLOC(high_temp, sizeof(struct nvfx_reg));
+      for (i = 0; i < high_temp; i++)
+         vpc->r_temp[i] = temp(vpc);
+   }
+
+   if (++high_addr) {
+      vpc->r_address = CALLOC(high_addr, sizeof(struct nvfx_reg));
+      for (i = 0; i < high_addr; i++)
+         vpc->r_address[i] = nvfx_reg(NVFXSR_TEMP, i);
+   }
+
+   if(++high_const) {
+      vpc->r_const = CALLOC(high_const, sizeof(struct nvfx_reg));
+      for (i = 0; i < high_const; i++)
+         vpc->r_const[i] = constant(vpc, i, 0, 0, 0, 0);
+   }
+
+   vpc->r_temps_discard = 0;
+   return TRUE;
+}
+
+DEBUG_GET_ONCE_BOOL_OPTION(nvfx_dump_vp, "NVFX_DUMP_VP", FALSE)
+
+boolean
+_nvfx_vertprog_translate(struct nv30_context *nv30, struct nv30_vertprog *vp)
+{
+   struct tgsi_parse_context parse;
+   struct nvfx_vpc *vpc = NULL;
+   struct nvfx_src none = nvfx_src(nvfx_reg(NVFXSR_NONE, 0));
+   struct util_dynarray insns;
+   int i, ucps;
+
+   vp->translated = FALSE;
+   vp->nr_insns = 0;
+   vp->nr_consts = 0;
+
+   vpc = CALLOC_STRUCT(nvfx_vpc);
+   if (!vpc)
+      return FALSE;
+   vpc->nv30 = nv30;
+   vpc->vp   = vp;
+   vpc->pipe = vp->pipe;
+   vpc->info = &vp->info;
+   vpc->cvtx_idx = -1;
+
+   if (!nvfx_vertprog_prepare(nv30, vpc)) {
+      FREE(vpc);
+      return FALSE;
+   }
+
+   /* Redirect post-transform vertex position to a temp if user clip
+    * planes are enabled.  We need to append code to the vtxprog
+    * to handle clip planes later.
+    */
+   if (vp->enabled_ucps && vpc->cvtx_idx < 0)  {
+      vpc->r_result[vpc->hpos_idx] = temp(vpc);
+      vpc->r_temps_discard = 0;
+      vpc->cvtx_idx = vpc->hpos_idx;
+   }
+
+   util_dynarray_init(&insns);
+
+   tgsi_parse_init(&parse, vp->pipe.tokens);
+   while (!tgsi_parse_end_of_tokens(&parse)) {
+      tgsi_parse_token(&parse);
+
+      switch (parse.FullToken.Token.Type) {
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+      {
+         const struct tgsi_full_immediate *imm;
+
+         imm = &parse.FullToken.FullImmediate;
+         assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
+         assert(imm->Immediate.NrTokens == 4 + 1);
+         vpc->imm[vpc->nr_imm++] =
+            constant(vpc, -1,
+                imm->u[0].Float,
+                imm->u[1].Float,
+                imm->u[2].Float,
+                imm->u[3].Float);
+      }
+         break;
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+      {
+         const struct tgsi_full_instruction *finst;
+         unsigned idx = insns.size >> 2;
+         util_dynarray_append(&insns, unsigned, vp->nr_insns);
+         finst = &parse.FullToken.FullInstruction;
+         if (!nvfx_vertprog_parse_instruction(nv30, vpc, idx, finst))
+            goto out;
+      }
+         break;
+      default:
+         break;
+      }
+   }
+
+   util_dynarray_append(&insns, unsigned, vp->nr_insns);
+
+   for(unsigned i = 0; i < vpc->label_relocs.size; i += sizeof(struct nvfx_relocation))
+   {
+      struct nvfx_relocation* label_reloc = (struct nvfx_relocation*)((char*)vpc->label_relocs.data + i);
+      struct nvfx_relocation hw_reloc;
+
+      hw_reloc.location = label_reloc->location;
+      hw_reloc.target = ((unsigned*)insns.data)[label_reloc->target];
+
+      //debug_printf("hw %u -> tgsi %u = hw %u\n", hw_reloc.location, label_reloc->target, hw_reloc.target);
+
+      util_dynarray_append(&vp->branch_relocs, struct nvfx_relocation, hw_reloc);
+   }
+   util_dynarray_fini(&insns);
+   util_dynarray_trim(&vp->branch_relocs);
+
+   /* XXX: what if we add a RET before?!  make sure we jump here...*/
+
+   /* Write out HPOS if it was redirected to a temp earlier */
+   if (vpc->r_result[vpc->hpos_idx].type != NVFXSR_OUTPUT) {
+      struct nvfx_reg hpos = nvfx_reg(NVFXSR_OUTPUT,
+                  NVFX_VP(INST_DEST_POS));
+      struct nvfx_src htmp = nvfx_src(vpc->r_result[vpc->hpos_idx]);
+
+      nvfx_vp_emit(vpc, arith(0, VEC, MOV, hpos, NVFX_VP_MASK_ALL, htmp, none, none));
+   }
+
+   /* Insert code to handle user clip planes */
+   ucps = vp->enabled_ucps;
+   while (ucps) {
+      int i = ffs(ucps) - 1; ucps &= ~(1 << i);
+      struct nvfx_reg cdst = nvfx_reg(NVFXSR_OUTPUT, NV30_VP_INST_DEST_CLP(i));
+      struct nvfx_src ceqn = nvfx_src(nvfx_reg(NVFXSR_CONST, 512 + i));
+      struct nvfx_src htmp = nvfx_src(vpc->r_result[vpc->cvtx_idx]);
+      unsigned mask;
+
+      if(nv30->is_nv4x)
+      {
+         switch (i) {
+         case 0: case 3: mask = NVFX_VP_MASK_Y; break;
+         case 1: case 4: mask = NVFX_VP_MASK_Z; break;
+         case 2: case 5: mask = NVFX_VP_MASK_W; break;
+         default:
+            NOUVEAU_ERR("invalid clip dist #%d\n", i);
+            goto out;
+         }
+      }
+      else
+         mask = NVFX_VP_MASK_X;
+
+      nvfx_vp_emit(vpc, arith(0, VEC, DP4, cdst, mask, htmp, ceqn, none));
+   }
+
+   if (vpc->vp->nr_insns)
+      vpc->vp->insns[vpc->vp->nr_insns - 1].data[3] |= NVFX_VP_INST_LAST;
+
+   if(debug_get_option_nvfx_dump_vp())
+   {
+      debug_printf("\n");
+      tgsi_dump(vpc->pipe.tokens, 0);
+
+      debug_printf("\n%s vertex program:\n", nv30->is_nv4x ? "nv4x" : "nv3x");
+      for (i = 0; i < vp->nr_insns; i++)
+         debug_printf("%3u: %08x %08x %08x %08x\n", i, vp->insns[i].data[0], vp->insns[i].data[1], vp->insns[i].data[2], vp->insns[i].data[3]);
+      debug_printf("\n");
+   }
+
+   vp->translated = TRUE;
+
+out:
+   tgsi_parse_free(&parse);
+   if(vpc) {
+      util_dynarray_fini(&vpc->label_relocs);
+      util_dynarray_fini(&vpc->loop_stack);
+      FREE(vpc->r_temp);
+      FREE(vpc->r_address);
+      FREE(vpc->r_const);
+      FREE(vpc->imm);
+      FREE(vpc);
+   }
+
+   return vp->translated;
+}
index 88eb4bb..98f8c4d 100644 (file)
@@ -27,8 +27,6 @@
 #include "nv50_screen.h"
 #include "nv50_resource.h"
 
-#include "nouveau/nouveau_reloc.h"
-
 static void
 nv50_flush(struct pipe_context *pipe,
            struct pipe_fence_handle **fence)
index 03279aa..c3c2778 100644 (file)
@@ -8,6 +8,7 @@ PIPE_DRIVERS = \
        $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
        $(TOP)/src/gallium/drivers/trace/libtrace.a \
        $(TOP)/src/gallium/drivers/rbug/librbug.a \
+       $(TOP)/src/gallium/drivers/nv30/libnv30.a \
        $(TOP)/src/gallium/drivers/nv50/libnv50.a \
        $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \
        $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
index b5be875..bb971c6 100644 (file)
@@ -7,6 +7,7 @@ DRIVER_INCLUDES = $(shell $(PKG_CONFIG) libdrm --cflags-only-I)
 
 PIPE_DRIVERS = \
        $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+       $(TOP)/src/gallium/drivers/nv30/libnv30.a \
        $(TOP)/src/gallium/drivers/nv50/libnv50.a \
        $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \
        $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
index f833411..8e704c6 100644 (file)
@@ -13,6 +13,7 @@ DRIVER_DEFINES = \
 DRIVER_PIPES = \
        $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
        $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+       $(TOP)/src/gallium/drivers/nv30/libnv30.a \
        $(TOP)/src/gallium/drivers/nv50/libnv50.a \
        $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \
        $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
index 017e92e..91d51c0 100644 (file)
@@ -21,13 +21,11 @@ nouveau_drm_screen_create(int fd)
                return NULL;
 
        switch (dev->chipset & 0xf0) {
-#if 0
        case 0x30:
        case 0x40:
        case 0x60:
                init = nv30_screen_create;
                break;
-#endif
        case 0x50:
        case 0x80:
        case 0x90: