nv50: replace most of it with nvc0 driver ported to nv50
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Mon, 28 Feb 2011 11:41:09 +0000 (12:41 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Mon, 28 Feb 2011 11:41:09 +0000 (12:41 +0100)
We'll have to do some unification now to reduce code duplication.

41 files changed:
src/gallium/drivers/nv50/Makefile
src/gallium/drivers/nv50/SConscript
src/gallium/drivers/nv50/nv50_2d.xml.h [new file with mode: 0644]
src/gallium/drivers/nv50/nv50_3d.xml.h [new file with mode: 0644]
src/gallium/drivers/nv50/nv50_3ddefs.xml.h [new file with mode: 0644]
src/gallium/drivers/nv50/nv50_buffer.c
src/gallium/drivers/nv50/nv50_clear.c [deleted file]
src/gallium/drivers/nv50/nv50_context.c
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_defs.xml.h [new file with mode: 0644]
src/gallium/drivers/nv50/nv50_draw.c
src/gallium/drivers/nv50/nv50_fence.c [new file with mode: 0644]
src/gallium/drivers/nv50/nv50_fence.h [new file with mode: 0644]
src/gallium/drivers/nv50/nv50_formats.c
src/gallium/drivers/nv50/nv50_miptree.c
src/gallium/drivers/nv50/nv50_mm.c [new file with mode: 0644]
src/gallium/drivers/nv50/nv50_pc.c
src/gallium/drivers/nv50/nv50_pc.h
src/gallium/drivers/nv50/nv50_pc_optimize.c
src/gallium/drivers/nv50/nv50_program.c
src/gallium/drivers/nv50/nv50_program.h
src/gallium/drivers/nv50/nv50_push.c
src/gallium/drivers/nv50/nv50_query.c
src/gallium/drivers/nv50/nv50_reg.h [deleted file]
src/gallium/drivers/nv50/nv50_resource.c
src/gallium/drivers/nv50/nv50_resource.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_screen.h
src/gallium/drivers/nv50/nv50_shader_state.c
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/nv50/nv50_stateobj.h [new file with mode: 0644]
src/gallium/drivers/nv50/nv50_surface.c
src/gallium/drivers/nv50/nv50_tex.c
src/gallium/drivers/nv50/nv50_texture.h [deleted file]
src/gallium/drivers/nv50/nv50_texture.xml.h [new file with mode: 0644]
src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
src/gallium/drivers/nv50/nv50_transfer.c
src/gallium/drivers/nv50/nv50_transfer.h
src/gallium/drivers/nv50/nv50_vbo.c
src/gallium/drivers/nv50/nv50_winsys.h [new file with mode: 0644]

index b3535c0976eb36b86c6651210bbaca5d08832f84..d0a60c7ac13a3d51a982c6f459aa0cdabe15324d 100644 (file)
@@ -5,12 +5,10 @@ LIBNAME = nv50
 
 C_SOURCES = \
        nv50_buffer.c \
-       nv50_clear.c \
        nv50_context.c \
        nv50_draw.c \
        nv50_formats.c \
        nv50_miptree.c \
-       nv50_query.c \
        nv50_resource.c \
        nv50_screen.c \
        nv50_state.c \
@@ -19,7 +17,6 @@ C_SOURCES = \
        nv50_tex.c \
        nv50_transfer.c \
        nv50_vbo.c \
-       nv50_push.c \
        nv50_program.c \
        nv50_shader_state.c \
        nv50_pc.c \
@@ -27,7 +24,11 @@ C_SOURCES = \
        nv50_pc_emit.c \
        nv50_tgsi_to_nc.c \
        nv50_pc_optimize.c \
-       nv50_pc_regalloc.c
+       nv50_pc_regalloc.c \
+       nv50_push.c \
+       nv50_fence.c \
+       nv50_mm.c \
+       nv50_query.c
 
 LIBRARY_INCLUDES = \
        $(LIBDRM_CFLAGS)
index 8e7892a9ab69108ec63ffed5b534fb1508d3f542..84644515ede210466753409f471c3d1ef847584c 100644 (file)
@@ -6,12 +6,10 @@ nv50 = env.ConvenienceLibrary(
     target = 'nv50',
     source = [
         'nv50_buffer.c',
-        'nv50_clear.c',
         'nv50_context.c',
         'nv50_draw.c',
         'nv50_formats.c',
         'nv50_miptree.c',
-        'nv50_query.c',
         'nv50_resource.c',
         'nv50_screen.c',
         'nv50_state.c',
@@ -20,7 +18,6 @@ nv50 = env.ConvenienceLibrary(
         'nv50_tex.c',
         'nv50_transfer.c',
         'nv50_vbo.c',
-        'nv50_push.c',
         'nv50_program.c',
         'nv50_shader_state.c',
         'nv50_pc.c',
@@ -29,6 +26,11 @@ nv50 = env.ConvenienceLibrary(
         'nv50_tgsi_to_nc.c',
         'nv50_pc_optimize.c',
         'nv50_pc_regalloc.c',
+        'nv50_push.c',
+        'nv50_push2.c',
+        'nv50_fence.c',
+        'nv50_mm.c',
+        'nv50_query.c'
     ])
 
 Export('nv50')
diff --git a/src/gallium/drivers/nv50/nv50_2d.xml.h b/src/gallium/drivers/nv50/nv50_2d.xml.h
new file mode 100644 (file)
index 0000000..bc9bcf7
--- /dev/null
@@ -0,0 +1,393 @@
+#ifndef NV50_2D_XML
+#define NV50_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:
+- nv50_2d.xml    (   9799 bytes, from 2010-12-28 17:17:11)
+- copyright.xml  (   6452 bytes, from 2010-12-15 23:45:18)
+- nv_object.xml  (  11898 bytes, from 2010-12-28 17:17:11)
+- nvchipsets.xml (   3074 bytes, from 2010-12-15 23:45:18)
+- nv_defs.xml    (   4437 bytes, from 2010-12-15 23:45:18)
+- nv50_defs.xml  (   4487 bytes, from 2010-12-15 23:45:18)
+
+Copyright (C) 2006-2010 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 NV50_2D_DMA_NOTIFY                                     0x00000180
+
+#define NV50_2D_DMA_DST                                                0x00000184
+
+#define NV50_2D_DMA_SRC                                                0x00000188
+
+#define NV50_2D_DMA_COND                                       0x0000018c
+
+#define NV50_2D_DST_FORMAT                                     0x00000200
+
+#define NV50_2D_DST_LINEAR                                     0x00000204
+
+#define NV50_2D_DST_TILE_MODE                                  0x00000208
+
+#define NV50_2D_DST_DEPTH                                      0x0000020c
+
+#define NV50_2D_DST_LAYER                                      0x00000210
+
+#define NV50_2D_DST_PITCH                                      0x00000214
+
+#define NV50_2D_DST_WIDTH                                      0x00000218
+
+#define NV50_2D_DST_HEIGHT                                     0x0000021c
+
+#define NV50_2D_DST_ADDRESS_HIGH                               0x00000220
+
+#define NV50_2D_DST_ADDRESS_LOW                                        0x00000224
+
+#define NV50_2D_UNK228                                         0x00000228
+
+#define NV50_2D_SRC_FORMAT                                     0x00000230
+
+#define NV50_2D_SRC_LINEAR                                     0x00000234
+
+#define NV50_2D_SRC_TILE_MODE                                  0x00000238
+
+#define NV50_2D_SRC_DEPTH                                      0x0000023c
+
+#define NV50_2D_SRC_LAYER                                      0x00000240
+
+#define NV50_2D_SRC_PITCH                                      0x00000244
+#define NV50_2D_SRC_PITCH__MAX                                 0x00040000
+
+#define NV50_2D_SRC_WIDTH                                      0x00000248
+#define NV50_2D_SRC_WIDTH__MAX                                 0x00010000
+
+#define NV50_2D_SRC_HEIGHT                                     0x0000024c
+#define NV50_2D_SRC_HEIGHT__MAX                                        0x00010000
+
+#define NV50_2D_SRC_ADDRESS_HIGH                               0x00000250
+
+#define NV50_2D_SRC_ADDRESS_LOW                                        0x00000254
+
+#define NV50_2D_UNK258                                         0x00000258
+
+#define NV50_2D_UNK260                                         0x00000260
+
+#define NV50_2D_COND_ADDRESS_HIGH                              0x00000264
+
+#define NV50_2D_COND_ADDRESS_LOW                               0x00000268
+
+#define NV50_2D_COND_MODE                                      0x0000026c
+#define NV50_2D_COND_MODE_NEVER                                        0x00000000
+#define NV50_2D_COND_MODE_ALWAYS                               0x00000001
+#define NV50_2D_COND_MODE_RES_NON_ZERO                         0x00000002
+#define NV50_2D_COND_MODE_EQUAL                                        0x00000003
+#define NV50_2D_COND_MODE_NOT_EQUAL                            0x00000004
+
+#define NV50_2D_CLIP_X                                         0x00000280
+
+#define NV50_2D_CLIP_Y                                         0x00000284
+
+#define NV50_2D_CLIP_W                                         0x00000288
+
+#define NV50_2D_CLIP_H                                         0x0000028c
+
+#define NV50_2D_CLIP_ENABLE                                    0x00000290
+
+#define NV50_2D_COLOR_KEY_FORMAT                               0x00000294
+#define NV50_2D_COLOR_KEY_FORMAT_16BPP                         0x00000000
+#define NV50_2D_COLOR_KEY_FORMAT_15BPP                         0x00000001
+#define NV50_2D_COLOR_KEY_FORMAT_24BPP                         0x00000002
+#define NV50_2D_COLOR_KEY_FORMAT_30BPP                         0x00000003
+#define NV50_2D_COLOR_KEY_FORMAT_8BPP                          0x00000004
+#define NV50_2D_COLOR_KEY_FORMAT_16BPP2                                0x00000005
+#define NV50_2D_COLOR_KEY_FORMAT_32BPP                         0x00000006
+
+#define NV50_2D_COLOR_KEY                                      0x00000298
+
+#define NV50_2D_COLOR_KEY_ENABLE                               0x0000029c
+
+#define NV50_2D_ROP                                            0x000002a0
+
+#define NV50_2D_BETA1                                          0x000002a4
+
+#define NV50_2D_BETA4                                          0x000002a8
+
+#define NV50_2D_OPERATION                                      0x000002ac
+#define NV50_2D_OPERATION_SRCCOPY_AND                          0x00000000
+#define NV50_2D_OPERATION_ROP_AND                              0x00000001
+#define NV50_2D_OPERATION_BLEND_AND                            0x00000002
+#define NV50_2D_OPERATION_SRCCOPY                              0x00000003
+#define NV50_2D_OPERATION_UNK4                                 0x00000004
+#define NV50_2D_OPERATION_SRCCOPY_PREMULT                      0x00000005
+#define NV50_2D_OPERATION_BLEND_PREMULT                                0x00000006
+
+#define NV50_2D_UNK2B0                                         0x000002b0
+#define NV50_2D_UNK2B0_UNK0__MASK                              0x0000003f
+#define NV50_2D_UNK2B0_UNK0__SHIFT                             0
+#define NV50_2D_UNK2B0_UNK1__MASK                              0x00003f00
+#define NV50_2D_UNK2B0_UNK1__SHIFT                             8
+
+#define NV50_2D_PATTERN_SELECT                                 0x000002b4
+#define NV50_2D_PATTERN_SELECT_MONO_8X8                                0x00000000
+#define NV50_2D_PATTERN_SELECT_MONO_64X1                       0x00000001
+#define NV50_2D_PATTERN_SELECT_MONO_1X64                       0x00000002
+#define NV50_2D_PATTERN_SELECT_COLOR                           0x00000003
+
+#define NV50_2D_PATTERN_COLOR_FORMAT                           0x000002e8
+#define NV50_2D_PATTERN_COLOR_FORMAT_16BPP                     0x00000000
+#define NV50_2D_PATTERN_COLOR_FORMAT_15BPP                     0x00000001
+#define NV50_2D_PATTERN_COLOR_FORMAT_32BPP                     0x00000002
+#define NV50_2D_PATTERN_COLOR_FORMAT_8BPP                      0x00000003
+#define NV50_2D_PATTERN_COLOR_FORMAT_UNK4                      0x00000004
+#define NV50_2D_PATTERN_COLOR_FORMAT_UNK5                      0x00000005
+
+#define NV50_2D_PATTERN_MONO_FORMAT                            0x000002ec
+#define NV50_2D_PATTERN_MONO_FORMAT_CGA6                       0x00000000
+#define NV50_2D_PATTERN_MONO_FORMAT_LE                         0x00000001
+
+#define NV50_2D_PATTERN_COLOR(i0)                             (0x000002f0 + 0x4*(i0))
+#define NV50_2D_PATTERN_COLOR__ESIZE                           0x00000004
+#define NV50_2D_PATTERN_COLOR__LEN                             0x00000002
+
+#define NV50_2D_PATTERN_BITMAP(i0)                            (0x000002f8 + 0x4*(i0))
+#define NV50_2D_PATTERN_BITMAP__ESIZE                          0x00000004
+#define NV50_2D_PATTERN_BITMAP__LEN                            0x00000002
+
+#define NV50_2D_PATTERN_X8R8G8B8(i0)                          (0x00000300 + 0x4*(i0))
+#define NV50_2D_PATTERN_X8R8G8B8__ESIZE                                0x00000004
+#define NV50_2D_PATTERN_X8R8G8B8__LEN                          0x00000040
+#define NV50_2D_PATTERN_X8R8G8B8_B__MASK                       0x000000ff
+#define NV50_2D_PATTERN_X8R8G8B8_B__SHIFT                      0
+#define NV50_2D_PATTERN_X8R8G8B8_G__MASK                       0x0000ff00
+#define NV50_2D_PATTERN_X8R8G8B8_G__SHIFT                      8
+#define NV50_2D_PATTERN_X8R8G8B8_R__MASK                       0x00ff0000
+#define NV50_2D_PATTERN_X8R8G8B8_R__SHIFT                      16
+
+#define NV50_2D_PATTERN_R5G6B5(i0)                            (0x00000400 + 0x4*(i0))
+#define NV50_2D_PATTERN_R5G6B5__ESIZE                          0x00000004
+#define NV50_2D_PATTERN_R5G6B5__LEN                            0x00000020
+#define NV50_2D_PATTERN_R5G6B5_B0__MASK                                0x0000001f
+#define NV50_2D_PATTERN_R5G6B5_B0__SHIFT                       0
+#define NV50_2D_PATTERN_R5G6B5_G0__MASK                                0x000007e0
+#define NV50_2D_PATTERN_R5G6B5_G0__SHIFT                       5
+#define NV50_2D_PATTERN_R5G6B5_R0__MASK                                0x0000f800
+#define NV50_2D_PATTERN_R5G6B5_R0__SHIFT                       11
+#define NV50_2D_PATTERN_R5G6B5_B1__MASK                                0x001f0000
+#define NV50_2D_PATTERN_R5G6B5_B1__SHIFT                       16
+#define NV50_2D_PATTERN_R5G6B5_G1__MASK                                0x07e00000
+#define NV50_2D_PATTERN_R5G6B5_G1__SHIFT                       21
+#define NV50_2D_PATTERN_R5G6B5_R1__MASK                                0xf8000000
+#define NV50_2D_PATTERN_R5G6B5_R1__SHIFT                       27
+
+#define NV50_2D_PATTERN_X1R5G5B5(i0)                          (0x00000480 + 0x4*(i0))
+#define NV50_2D_PATTERN_X1R5G5B5__ESIZE                                0x00000004
+#define NV50_2D_PATTERN_X1R5G5B5__LEN                          0x00000020
+#define NV50_2D_PATTERN_X1R5G5B5_B0__MASK                      0x0000001f
+#define NV50_2D_PATTERN_X1R5G5B5_B0__SHIFT                     0
+#define NV50_2D_PATTERN_X1R5G5B5_G0__MASK                      0x000003e0
+#define NV50_2D_PATTERN_X1R5G5B5_G0__SHIFT                     5
+#define NV50_2D_PATTERN_X1R5G5B5_R0__MASK                      0x00007c00
+#define NV50_2D_PATTERN_X1R5G5B5_R0__SHIFT                     10
+#define NV50_2D_PATTERN_X1R5G5B5_B1__MASK                      0x001f0000
+#define NV50_2D_PATTERN_X1R5G5B5_B1__SHIFT                     16
+#define NV50_2D_PATTERN_X1R5G5B5_G1__MASK                      0x03e00000
+#define NV50_2D_PATTERN_X1R5G5B5_G1__SHIFT                     21
+#define NV50_2D_PATTERN_X1R5G5B5_R1__MASK                      0x7c000000
+#define NV50_2D_PATTERN_X1R5G5B5_R1__SHIFT                     26
+
+#define NV50_2D_PATTERN_Y8(i0)                                (0x00000500 + 0x4*(i0))
+#define NV50_2D_PATTERN_Y8__ESIZE                              0x00000004
+#define NV50_2D_PATTERN_Y8__LEN                                        0x00000010
+#define NV50_2D_PATTERN_Y8_Y0__MASK                            0x000000ff
+#define NV50_2D_PATTERN_Y8_Y0__SHIFT                           0
+#define NV50_2D_PATTERN_Y8_Y1__MASK                            0x0000ff00
+#define NV50_2D_PATTERN_Y8_Y1__SHIFT                           8
+#define NV50_2D_PATTERN_Y8_Y2__MASK                            0x00ff0000
+#define NV50_2D_PATTERN_Y8_Y2__SHIFT                           16
+#define NV50_2D_PATTERN_Y8_Y3__MASK                            0xff000000
+#define NV50_2D_PATTERN_Y8_Y3__SHIFT                           24
+
+#define NV50_2D_DRAW_SHAPE                                     0x00000580
+#define NV50_2D_DRAW_SHAPE_POINTS                              0x00000000
+#define NV50_2D_DRAW_SHAPE_LINES                               0x00000001
+#define NV50_2D_DRAW_SHAPE_LINE_STRIP                          0x00000002
+#define NV50_2D_DRAW_SHAPE_TRIANGLES                           0x00000003
+#define NV50_2D_DRAW_SHAPE_RECTANGLES                          0x00000004
+
+#define NV50_2D_DRAW_COLOR_FORMAT                              0x00000584
+
+#define NV50_2D_DRAW_COLOR                                     0x00000588
+
+#define NV50_2D_UNK58C                                         0x0000058c
+#define NV50_2D_UNK58C_0                                       0x00000001
+#define NV50_2D_UNK58C_1                                       0x00000010
+#define NV50_2D_UNK58C_2                                       0x00000100
+#define NV50_2D_UNK58C_3                                       0x00001000
+
+#define NV50_2D_DRAW_POINT16                                   0x000005e0
+#define NV50_2D_DRAW_POINT16_X__MASK                           0x0000ffff
+#define NV50_2D_DRAW_POINT16_X__SHIFT                          0
+#define NV50_2D_DRAW_POINT16_Y__MASK                           0xffff0000
+#define NV50_2D_DRAW_POINT16_Y__SHIFT                          16
+
+#define NV50_2D_DRAW_POINT32_X(i0)                            (0x00000600 + 0x8*(i0))
+#define NV50_2D_DRAW_POINT32_X__ESIZE                          0x00000008
+#define NV50_2D_DRAW_POINT32_X__LEN                            0x00000040
+
+#define NV50_2D_DRAW_POINT32_Y(i0)                            (0x00000604 + 0x8*(i0))
+#define NV50_2D_DRAW_POINT32_Y__ESIZE                          0x00000008
+#define NV50_2D_DRAW_POINT32_Y__LEN                            0x00000040
+
+#define NV50_2D_SIFC_BITMAP_ENABLE                             0x00000800
+
+#define NV50_2D_SIFC_FORMAT                                    0x00000804
+
+#define NV50_2D_SIFC_BITMAP_FORMAT                             0x00000808
+#define NV50_2D_SIFC_BITMAP_FORMAT_I1                          0x00000000
+#define NV50_2D_SIFC_BITMAP_FORMAT_I4                          0x00000001
+#define NV50_2D_SIFC_BITMAP_FORMAT_I8                          0x00000002
+
+#define NV50_2D_SIFC_BITMAP_LSB_FIRST                          0x0000080c
+
+#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE                     0x00000810
+#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_PACKED              0x00000000
+#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_BYTE          0x00000001
+#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_WORD          0x00000002
+
+#define NV50_2D_SIFC_BITMAP_COLOR_BIT0                         0x00000814
+
+#define NV50_2D_SIFC_BITMAP_COLOR_BIT1                         0x00000818
+
+#define NV50_2D_SIFC_BITMAP_WRITE_BIT0_ENABLE                  0x0000081c
+
+#define NV50_2D_SIFC_WIDTH                                     0x00000838
+
+#define NV50_2D_SIFC_HEIGHT                                    0x0000083c
+
+#define NV50_2D_SIFC_DX_DU_FRACT                               0x00000840
+
+#define NV50_2D_SIFC_DX_DU_INT                                 0x00000844
+
+#define NV50_2D_SIFC_DY_DV_FRACT                               0x00000848
+
+#define NV50_2D_SIFC_DY_DV_INT                                 0x0000084c
+
+#define NV50_2D_SIFC_DST_X_FRACT                               0x00000850
+
+#define NV50_2D_SIFC_DST_X_INT                                 0x00000854
+
+#define NV50_2D_SIFC_DST_Y_FRACT                               0x00000858
+
+#define NV50_2D_SIFC_DST_Y_INT                                 0x0000085c
+
+#define NV50_2D_SIFC_DATA                                      0x00000860
+
+#define NV50_2D_UNK0870                                                0x00000870
+
+#define NV50_2D_UNK0880                                                0x00000880
+
+#define NV50_2D_UNK0884                                                0x00000884
+
+#define NV50_2D_UNK0888                                                0x00000888
+
+#define NV50_2D_BLIT_CONTROL                                   0x0000088c
+#define NV50_2D_BLIT_CONTROL_ORIGIN__MASK                      0x00000001
+#define NV50_2D_BLIT_CONTROL_ORIGIN__SHIFT                     0
+#define NV50_2D_BLIT_CONTROL_ORIGIN_CENTER                     0x00000000
+#define NV50_2D_BLIT_CONTROL_ORIGIN_CORNER                     0x00000001
+#define NV50_2D_BLIT_CONTROL_FILTER__MASK                      0x00000010
+#define NV50_2D_BLIT_CONTROL_FILTER__SHIFT                     4
+#define NV50_2D_BLIT_CONTROL_FILTER_POINT_SAMPLE               0x00000000
+#define NV50_2D_BLIT_CONTROL_FILTER_BILINEAR                   0x00000010
+
+#define NV50_2D_BLIT_DST_X                                     0x000008b0
+
+#define NV50_2D_BLIT_DST_Y                                     0x000008b4
+
+#define NV50_2D_BLIT_DST_W                                     0x000008b8
+
+#define NV50_2D_BLIT_DST_H                                     0x000008bc
+
+#define NV50_2D_BLIT_DU_DX_FRACT                               0x000008c0
+
+#define NV50_2D_BLIT_DU_DX_INT                                 0x000008c4
+
+#define NV50_2D_BLIT_DV_DY_FRACT                               0x000008c8
+
+#define NV50_2D_BLIT_DV_DY_INT                                 0x000008cc
+
+#define NV50_2D_BLIT_SRC_X_FRACT                               0x000008d0
+
+#define NV50_2D_BLIT_SRC_X_INT                                 0x000008d4
+
+#define NV50_2D_BLIT_SRC_Y_FRACT                               0x000008d8
+
+#define NV50_2D_BLIT_SRC_Y_INT                                 0x000008dc
+
+#define NVC0_2D_FIRMWARE(i0)                                  (0x000008e0 + 0x4*(i0))
+#define NVC0_2D_FIRMWARE__ESIZE                                        0x00000004
+#define NVC0_2D_FIRMWARE__LEN                                  0x00000020
+
+
+#endif /* NV50_2D_XML */
diff --git a/src/gallium/drivers/nv50/nv50_3d.xml.h b/src/gallium/drivers/nv50/nv50_3d.xml.h
new file mode 100644 (file)
index 0000000..eb05bd4
--- /dev/null
@@ -0,0 +1,2084 @@
+#ifndef NV50_3D_XML
+#define NV50_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:
+- nv50_3d.xml    (  64479 bytes, from 2011-02-27 17:58:08)
+- copyright.xml  (   6452 bytes, from 2010-12-15 23:45:18)
+- nv_defs.xml    (   4437 bytes, from 2010-12-15 23:45:18)
+- nv50_defs.xml  (   4487 bytes, from 2010-12-15 23:45:18)
+- nv_3ddefs.xml  (  16394 bytes, from 2010-12-15 23:45:18)
+- nv_object.xml  (  12191 bytes, from 2011-02-27 17:58:08)
+- nvchipsets.xml (   3074 bytes, from 2011-02-27 17:58:08)
+
+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 NV50_3D_DMA_NOTIFY                                     0x00000180
+
+#define NV50_3D_DMA_ZETA                                       0x00000184
+
+#define NV50_3D_DMA_QUERY                                      0x00000188
+
+#define NV50_3D_DMA_VTXBUF                                     0x0000018c
+
+#define NV50_3D_DMA_LOCAL                                      0x00000190
+
+#define NV50_3D_DMA_STACK                                      0x00000194
+
+#define NV50_3D_DMA_CODE_CB                                    0x00000198
+
+#define NV50_3D_DMA_TSC                                                0x0000019c
+
+#define NV50_3D_DMA_TIC                                                0x000001a0
+
+#define NV50_3D_DMA_TEXTURE                                    0x000001a4
+
+#define NV50_3D_DMA_STRMOUT                                    0x000001a8
+
+#define NV50_3D_DMA_CLIPID                                     0x000001ac
+
+#define NV50_3D_DMA_COLOR(i0)                                 (0x000001c0 + 0x4*(i0))
+#define NV50_3D_DMA_COLOR__ESIZE                               0x00000004
+#define NV50_3D_DMA_COLOR__LEN                                 0x00000008
+
+#define NV50_3D_RT(i0)                                        (0x00000200 + 0x20*(i0))
+#define NV50_3D_RT__ESIZE                                      0x00000020
+#define NV50_3D_RT__LEN                                                0x00000008
+
+#define NV50_3D_RT_ADDRESS_HIGH(i0)                           (0x00000200 + 0x20*(i0))
+
+#define NV50_3D_RT_ADDRESS_LOW(i0)                            (0x00000204 + 0x20*(i0))
+
+#define NV50_3D_RT_FORMAT(i0)                                 (0x00000208 + 0x20*(i0))
+
+#define NV50_3D_RT_TILE_MODE(i0)                              (0x0000020c + 0x20*(i0))
+#define NV50_3D_RT_TILE_MODE_X__MASK                           0x0000000f
+#define NV50_3D_RT_TILE_MODE_X__SHIFT                          0
+#define NV50_3D_RT_TILE_MODE_Y__MASK                           0x000000f0
+#define NV50_3D_RT_TILE_MODE_Y__SHIFT                          4
+#define NV50_3D_RT_TILE_MODE_Z__MASK                           0x00000f00
+#define NV50_3D_RT_TILE_MODE_Z__SHIFT                          8
+
+#define NV50_3D_RT_LAYER_STRIDE(i0)                           (0x00000210 + 0x20*(i0))
+#define NV50_3D_RT_LAYER_STRIDE__SHR                           2
+
+#define NV50_3D_RT_UNK14(i0)                                  (0x00000214 + 0x20*(i0))
+
+#define NV50_3D_VTX_ATTR_1F(i0)                                       (0x00000300 + 0x4*(i0))
+#define NV50_3D_VTX_ATTR_1F__ESIZE                             0x00000004
+#define NV50_3D_VTX_ATTR_1F__LEN                               0x00000010
+
+#define NV50_3D_VTX_ATTR_2H(i0)                                       (0x00000340 + 0x4*(i0))
+#define NV50_3D_VTX_ATTR_2H__ESIZE                             0x00000004
+#define NV50_3D_VTX_ATTR_2H__LEN                               0x00000010
+#define NV50_3D_VTX_ATTR_2H_X__MASK                            0x0000ffff
+#define NV50_3D_VTX_ATTR_2H_X__SHIFT                           0
+#define NV50_3D_VTX_ATTR_2H_Y__MASK                            0xffff0000
+#define NV50_3D_VTX_ATTR_2H_Y__SHIFT                           16
+
+#define NV50_3D_VTX_ATTR_2F_X(i0)                             (0x00000380 + 0x8*(i0))
+#define NV50_3D_VTX_ATTR_2F_X__ESIZE                           0x00000008
+#define NV50_3D_VTX_ATTR_2F_X__LEN                             0x00000010
+
+#define NV50_3D_VTX_ATTR_2F_Y(i0)                             (0x00000384 + 0x8*(i0))
+#define NV50_3D_VTX_ATTR_2F_Y__ESIZE                           0x00000008
+#define NV50_3D_VTX_ATTR_2F_Y__LEN                             0x00000010
+
+#define NV50_3D_VTX_ATTR_3F_X(i0)                             (0x00000400 + 0x10*(i0))
+#define NV50_3D_VTX_ATTR_3F_X__ESIZE                           0x00000010
+#define NV50_3D_VTX_ATTR_3F_X__LEN                             0x00000010
+
+#define NV50_3D_VTX_ATTR_3F_Y(i0)                             (0x00000404 + 0x10*(i0))
+#define NV50_3D_VTX_ATTR_3F_Y__ESIZE                           0x00000010
+#define NV50_3D_VTX_ATTR_3F_Y__LEN                             0x00000010
+
+#define NV50_3D_VTX_ATTR_3F_Z(i0)                             (0x00000408 + 0x10*(i0))
+#define NV50_3D_VTX_ATTR_3F_Z__ESIZE                           0x00000010
+#define NV50_3D_VTX_ATTR_3F_Z__LEN                             0x00000010
+
+#define NV50_3D_VTX_ATTR_4F_X(i0)                             (0x00000500 + 0x10*(i0))
+#define NV50_3D_VTX_ATTR_4F_X__ESIZE                           0x00000010
+#define NV50_3D_VTX_ATTR_4F_X__LEN                             0x00000010
+
+#define NV50_3D_VTX_ATTR_4F_Y(i0)                             (0x00000504 + 0x10*(i0))
+#define NV50_3D_VTX_ATTR_4F_Y__ESIZE                           0x00000010
+#define NV50_3D_VTX_ATTR_4F_Y__LEN                             0x00000010
+
+#define NV50_3D_VTX_ATTR_4F_Z(i0)                             (0x00000508 + 0x10*(i0))
+#define NV50_3D_VTX_ATTR_4F_Z__ESIZE                           0x00000010
+#define NV50_3D_VTX_ATTR_4F_Z__LEN                             0x00000010
+
+#define NV50_3D_VTX_ATTR_4F_W(i0)                             (0x0000050c + 0x10*(i0))
+#define NV50_3D_VTX_ATTR_4F_W__ESIZE                           0x00000010
+#define NV50_3D_VTX_ATTR_4F_W__LEN                             0x00000010
+
+#define NV50_3D_VTX_ATTR_4H_0(i0)                             (0x00000600 + 0x8*(i0))
+#define NV50_3D_VTX_ATTR_4H_0__ESIZE                           0x00000008
+#define NV50_3D_VTX_ATTR_4H_0__LEN                             0x00000010
+#define NV50_3D_VTX_ATTR_4H_0_X__MASK                          0x0000ffff
+#define NV50_3D_VTX_ATTR_4H_0_X__SHIFT                         0
+#define NV50_3D_VTX_ATTR_4H_0_Y__MASK                          0xffff0000
+#define NV50_3D_VTX_ATTR_4H_0_Y__SHIFT                         16
+
+#define NV50_3D_VTX_ATTR_4H_1(i0)                             (0x00000604 + 0x8*(i0))
+#define NV50_3D_VTX_ATTR_4H_1__ESIZE                           0x00000008
+#define NV50_3D_VTX_ATTR_4H_1__LEN                             0x00000010
+#define NV50_3D_VTX_ATTR_4H_1_Z__MASK                          0x0000ffff
+#define NV50_3D_VTX_ATTR_4H_1_Z__SHIFT                         0
+#define NV50_3D_VTX_ATTR_4H_1_W__MASK                          0xffff0000
+#define NV50_3D_VTX_ATTR_4H_1_W__SHIFT                         16
+
+#define NV50_3D_VTX_ATTR_2I(i0)                                       (0x00000680 + 0x4*(i0))
+#define NV50_3D_VTX_ATTR_2I__ESIZE                             0x00000004
+#define NV50_3D_VTX_ATTR_2I__LEN                               0x00000010
+#define NV50_3D_VTX_ATTR_2I_X__MASK                            0x0000ffff
+#define NV50_3D_VTX_ATTR_2I_X__SHIFT                           0
+#define NV50_3D_VTX_ATTR_2I_Y__MASK                            0xffff0000
+#define NV50_3D_VTX_ATTR_2I_Y__SHIFT                           16
+
+#define NV50_3D_VTX_ATTR_2NI(i0)                              (0x000006c0 + 0x4*(i0))
+#define NV50_3D_VTX_ATTR_2NI__ESIZE                            0x00000004
+#define NV50_3D_VTX_ATTR_2NI__LEN                              0x00000010
+#define NV50_3D_VTX_ATTR_2NI_X__MASK                           0x0000ffff
+#define NV50_3D_VTX_ATTR_2NI_X__SHIFT                          0
+#define NV50_3D_VTX_ATTR_2NI_Y__MASK                           0xffff0000
+#define NV50_3D_VTX_ATTR_2NI_Y__SHIFT                          16
+
+#define NV50_3D_VTX_ATTR_4I_0(i0)                             (0x00000700 + 0x8*(i0))
+#define NV50_3D_VTX_ATTR_4I_0__ESIZE                           0x00000008
+#define NV50_3D_VTX_ATTR_4I_0__LEN                             0x00000010
+#define NV50_3D_VTX_ATTR_4I_0_X__MASK                          0x0000ffff
+#define NV50_3D_VTX_ATTR_4I_0_X__SHIFT                         0
+#define NV50_3D_VTX_ATTR_4I_0_Y__MASK                          0xffff0000
+#define NV50_3D_VTX_ATTR_4I_0_Y__SHIFT                         16
+
+#define NV50_3D_VTX_ATTR_4I_1(i0)                             (0x00000704 + 0x8*(i0))
+#define NV50_3D_VTX_ATTR_4I_1__ESIZE                           0x00000008
+#define NV50_3D_VTX_ATTR_4I_1__LEN                             0x00000010
+#define NV50_3D_VTX_ATTR_4I_1_Z__MASK                          0x0000ffff
+#define NV50_3D_VTX_ATTR_4I_1_Z__SHIFT                         0
+#define NV50_3D_VTX_ATTR_4I_1_W__MASK                          0xffff0000
+#define NV50_3D_VTX_ATTR_4I_1_W__SHIFT                         16
+
+#define NV50_3D_VTX_ATTR_4NI_0(i0)                            (0x00000780 + 0x8*(i0))
+#define NV50_3D_VTX_ATTR_4NI_0__ESIZE                          0x00000008
+#define NV50_3D_VTX_ATTR_4NI_0__LEN                            0x00000010
+#define NV50_3D_VTX_ATTR_4NI_0_X__MASK                         0x0000ffff
+#define NV50_3D_VTX_ATTR_4NI_0_X__SHIFT                                0
+#define NV50_3D_VTX_ATTR_4NI_0_Y__MASK                         0xffff0000
+#define NV50_3D_VTX_ATTR_4NI_0_Y__SHIFT                                16
+
+#define NV50_3D_VTX_ATTR_4NI_1(i0)                            (0x00000784 + 0x8*(i0))
+#define NV50_3D_VTX_ATTR_4NI_1__ESIZE                          0x00000008
+#define NV50_3D_VTX_ATTR_4NI_1__LEN                            0x00000010
+#define NV50_3D_VTX_ATTR_4NI_1_Z__MASK                         0x0000ffff
+#define NV50_3D_VTX_ATTR_4NI_1_Z__SHIFT                                0
+#define NV50_3D_VTX_ATTR_4NI_1_W__MASK                         0xffff0000
+#define NV50_3D_VTX_ATTR_4NI_1_W__SHIFT                                16
+
+#define NV50_3D_VTX_ATTR_4UB(i0)                              (0x00000800 + 0x4*(i0))
+#define NV50_3D_VTX_ATTR_4UB__ESIZE                            0x00000004
+#define NV50_3D_VTX_ATTR_4UB__LEN                              0x00000010
+#define NV50_3D_VTX_ATTR_4UB_X__MASK                           0x000000ff
+#define NV50_3D_VTX_ATTR_4UB_X__SHIFT                          0
+#define NV50_3D_VTX_ATTR_4UB_Y__MASK                           0x0000ff00
+#define NV50_3D_VTX_ATTR_4UB_Y__SHIFT                          8
+#define NV50_3D_VTX_ATTR_4UB_Z__MASK                           0x00ff0000
+#define NV50_3D_VTX_ATTR_4UB_Z__SHIFT                          16
+#define NV50_3D_VTX_ATTR_4UB_W__MASK                           0xff000000
+#define NV50_3D_VTX_ATTR_4UB_W__SHIFT                          24
+
+#define NV50_3D_VTX_ATTR_4B(i0)                                       (0x00000840 + 0x4*(i0))
+#define NV50_3D_VTX_ATTR_4B__ESIZE                             0x00000004
+#define NV50_3D_VTX_ATTR_4B__LEN                               0x00000010
+#define NV50_3D_VTX_ATTR_4B_X__MASK                            0x000000ff
+#define NV50_3D_VTX_ATTR_4B_X__SHIFT                           0
+#define NV50_3D_VTX_ATTR_4B_Y__MASK                            0x0000ff00
+#define NV50_3D_VTX_ATTR_4B_Y__SHIFT                           8
+#define NV50_3D_VTX_ATTR_4B_Z__MASK                            0x00ff0000
+#define NV50_3D_VTX_ATTR_4B_Z__SHIFT                           16
+#define NV50_3D_VTX_ATTR_4B_W__MASK                            0xff000000
+#define NV50_3D_VTX_ATTR_4B_W__SHIFT                           24
+
+#define NV50_3D_VTX_ATTR_4NUB(i0)                             (0x00000880 + 0x4*(i0))
+#define NV50_3D_VTX_ATTR_4NUB__ESIZE                           0x00000004
+#define NV50_3D_VTX_ATTR_4NUB__LEN                             0x00000010
+#define NV50_3D_VTX_ATTR_4NUB_X__MASK                          0x000000ff
+#define NV50_3D_VTX_ATTR_4NUB_X__SHIFT                         0
+#define NV50_3D_VTX_ATTR_4NUB_Y__MASK                          0x0000ff00
+#define NV50_3D_VTX_ATTR_4NUB_Y__SHIFT                         8
+#define NV50_3D_VTX_ATTR_4NUB_Z__MASK                          0x00ff0000
+#define NV50_3D_VTX_ATTR_4NUB_Z__SHIFT                         16
+#define NV50_3D_VTX_ATTR_4NUB_W__MASK                          0xff000000
+#define NV50_3D_VTX_ATTR_4NUB_W__SHIFT                         24
+
+#define NV50_3D_VTX_ATTR_4NB(i0)                              (0x000008c0 + 0x4*(i0))
+#define NV50_3D_VTX_ATTR_4NB__ESIZE                            0x00000004
+#define NV50_3D_VTX_ATTR_4NB__LEN                              0x00000010
+#define NV50_3D_VTX_ATTR_4NB_X__MASK                           0x000000ff
+#define NV50_3D_VTX_ATTR_4NB_X__SHIFT                          0
+#define NV50_3D_VTX_ATTR_4NB_Y__MASK                           0x0000ff00
+#define NV50_3D_VTX_ATTR_4NB_Y__SHIFT                          8
+#define NV50_3D_VTX_ATTR_4NB_Z__MASK                           0x00ff0000
+#define NV50_3D_VTX_ATTR_4NB_Z__SHIFT                          16
+#define NV50_3D_VTX_ATTR_4NB_W__MASK                           0xff000000
+#define NV50_3D_VTX_ATTR_4NB_W__SHIFT                          24
+
+#define NV50_3D_VERTEX_ARRAY_FETCH(i0)                        (0x00000900 + 0x10*(i0))
+#define NV50_3D_VERTEX_ARRAY_FETCH__ESIZE                      0x00000010
+#define NV50_3D_VERTEX_ARRAY_FETCH__LEN                                0x00000010
+#define NV50_3D_VERTEX_ARRAY_FETCH_STRIDE__MASK                        0x00000fff
+#define NV50_3D_VERTEX_ARRAY_FETCH_STRIDE__SHIFT               0
+#define NV50_3D_VERTEX_ARRAY_FETCH_ENABLE                      0x20000000
+
+#define NV50_3D_VERTEX_ARRAY_START_HIGH(i0)                   (0x00000904 + 0x10*(i0))
+#define NV50_3D_VERTEX_ARRAY_START_HIGH__ESIZE                 0x00000010
+#define NV50_3D_VERTEX_ARRAY_START_HIGH__LEN                   0x00000010
+
+#define NV50_3D_VERTEX_ARRAY_START_LOW(i0)                    (0x00000908 + 0x10*(i0))
+#define NV50_3D_VERTEX_ARRAY_START_LOW__ESIZE                  0x00000010
+#define NV50_3D_VERTEX_ARRAY_START_LOW__LEN                    0x00000010
+
+#define NV50_3D_VERTEX_ARRAY_DIVISOR(i0)                      (0x0000090c + 0x10*(i0))
+#define NV50_3D_VERTEX_ARRAY_DIVISOR__ESIZE                    0x00000010
+#define NV50_3D_VERTEX_ARRAY_DIVISOR__LEN                      0x00000010
+
+#define NV50_3D_VIEWPORT_SCALE_X(i0)                          (0x00000a00 + 0x20*(i0))
+#define NV50_3D_VIEWPORT_SCALE_X__ESIZE                                0x00000020
+#define NV50_3D_VIEWPORT_SCALE_X__LEN                          0x00000010
+
+#define NV50_3D_VIEWPORT_SCALE_Y(i0)                          (0x00000a04 + 0x20*(i0))
+#define NV50_3D_VIEWPORT_SCALE_Y__ESIZE                                0x00000020
+#define NV50_3D_VIEWPORT_SCALE_Y__LEN                          0x00000010
+
+#define NV50_3D_VIEWPORT_SCALE_Z(i0)                          (0x00000a08 + 0x20*(i0))
+#define NV50_3D_VIEWPORT_SCALE_Z__ESIZE                                0x00000020
+#define NV50_3D_VIEWPORT_SCALE_Z__LEN                          0x00000010
+
+#define NV50_3D_VIEWPORT_TRANSLATE_X(i0)                      (0x00000a0c + 0x20*(i0))
+#define NV50_3D_VIEWPORT_TRANSLATE_X__ESIZE                    0x00000020
+#define NV50_3D_VIEWPORT_TRANSLATE_X__LEN                      0x00000010
+
+#define NV50_3D_VIEWPORT_TRANSLATE_Y(i0)                      (0x00000a10 + 0x20*(i0))
+#define NV50_3D_VIEWPORT_TRANSLATE_Y__ESIZE                    0x00000020
+#define NV50_3D_VIEWPORT_TRANSLATE_Y__LEN                      0x00000010
+
+#define NV50_3D_VIEWPORT_TRANSLATE_Z(i0)                      (0x00000a14 + 0x20*(i0))
+#define NV50_3D_VIEWPORT_TRANSLATE_Z__ESIZE                    0x00000020
+#define NV50_3D_VIEWPORT_TRANSLATE_Z__LEN                      0x00000010
+
+#define NV50_3D_VIEWPORT_HORIZ(i0)                            (0x00000c00 + 0x10*(i0))
+#define NV50_3D_VIEWPORT_HORIZ__ESIZE                          0x00000010
+#define NV50_3D_VIEWPORT_HORIZ__LEN                            0x00000010
+#define NV50_3D_VIEWPORT_HORIZ_X__MASK                         0x0000ffff
+#define NV50_3D_VIEWPORT_HORIZ_X__SHIFT                                0
+#define NV50_3D_VIEWPORT_HORIZ_W__MASK                         0xffff0000
+#define NV50_3D_VIEWPORT_HORIZ_W__SHIFT                                16
+
+#define NV50_3D_VIEWPORT_VERT(i0)                             (0x00000c04 + 0x10*(i0))
+#define NV50_3D_VIEWPORT_VERT__ESIZE                           0x00000010
+#define NV50_3D_VIEWPORT_VERT__LEN                             0x00000010
+#define NV50_3D_VIEWPORT_VERT_Y__MASK                          0x0000ffff
+#define NV50_3D_VIEWPORT_VERT_Y__SHIFT                         0
+#define NV50_3D_VIEWPORT_VERT_H__MASK                          0xffff0000
+#define NV50_3D_VIEWPORT_VERT_H__SHIFT                         16
+
+#define NV50_3D_DEPTH_RANGE_NEAR(i0)                          (0x00000c08 + 0x10*(i0))
+#define NV50_3D_DEPTH_RANGE_NEAR__ESIZE                                0x00000010
+#define NV50_3D_DEPTH_RANGE_NEAR__LEN                          0x00000010
+
+#define NV50_3D_DEPTH_RANGE_FAR(i0)                           (0x00000c0c + 0x10*(i0))
+#define NV50_3D_DEPTH_RANGE_FAR__ESIZE                         0x00000010
+#define NV50_3D_DEPTH_RANGE_FAR__LEN                           0x00000010
+
+#define NV50_3D_CLIP_RECT_HORIZ(i0)                           (0x00000d00 + 0x8*(i0))
+#define NV50_3D_CLIP_RECT_HORIZ__ESIZE                         0x00000008
+#define NV50_3D_CLIP_RECT_HORIZ__LEN                           0x00000008
+#define NV50_3D_CLIP_RECT_HORIZ_MIN__MASK                      0x0000ffff
+#define NV50_3D_CLIP_RECT_HORIZ_MIN__SHIFT                     0
+#define NV50_3D_CLIP_RECT_HORIZ_MAX__MASK                      0xffff0000
+#define NV50_3D_CLIP_RECT_HORIZ_MAX__SHIFT                     16
+
+#define NV50_3D_CLIP_RECT_VERT(i0)                            (0x00000d04 + 0x8*(i0))
+#define NV50_3D_CLIP_RECT_VERT__ESIZE                          0x00000008
+#define NV50_3D_CLIP_RECT_VERT__LEN                            0x00000008
+#define NV50_3D_CLIP_RECT_VERT_MIN__MASK                       0x0000ffff
+#define NV50_3D_CLIP_RECT_VERT_MIN__SHIFT                      0
+#define NV50_3D_CLIP_RECT_VERT_MAX__MASK                       0xffff0000
+#define NV50_3D_CLIP_RECT_VERT_MAX__SHIFT                      16
+
+#define NV50_3D_CLIPID_REGION_HORIZ(i0)                               (0x00000d40 + 0x8*(i0))
+#define NV50_3D_CLIPID_REGION_HORIZ__ESIZE                     0x00000008
+#define NV50_3D_CLIPID_REGION_HORIZ__LEN                       0x00000004
+#define NV50_3D_CLIPID_REGION_HORIZ_X__MASK                    0x0000ffff
+#define NV50_3D_CLIPID_REGION_HORIZ_X__SHIFT                   0
+#define NV50_3D_CLIPID_REGION_HORIZ_W__MASK                    0xffff0000
+#define NV50_3D_CLIPID_REGION_HORIZ_W__SHIFT                   16
+
+#define NV50_3D_CLIPID_REGION_VERT(i0)                        (0x00000d44 + 0x8*(i0))
+#define NV50_3D_CLIPID_REGION_VERT__ESIZE                      0x00000008
+#define NV50_3D_CLIPID_REGION_VERT__LEN                                0x00000004
+#define NV50_3D_CLIPID_REGION_VERT_Y__MASK                     0x0000ffff
+#define NV50_3D_CLIPID_REGION_VERT_Y__SHIFT                    0
+#define NV50_3D_CLIPID_REGION_VERT_H__MASK                     0xffff0000
+#define NV50_3D_CLIPID_REGION_VERT_H__SHIFT                    16
+
+#define NV50_3D_UNK0D60                                                0x00000d60
+
+#define NV50_3D_UNK0D64                                                0x00000d64
+
+#define NV50_3D_COUNTER_ENABLE                                 0x00000d68
+#define NV50_3D_COUNTER_ENABLE_VFETCH_VERTICES                 0x00000001
+#define NV50_3D_COUNTER_ENABLE_VFETCH_PRIMITIVES               0x00000002
+#define NV50_3D_COUNTER_ENABLE_VP_LAUNCHES                     0x00000004
+#define NV50_3D_COUNTER_ENABLE_GP_LAUNCHES                     0x00000008
+#define NV50_3D_COUNTER_ENABLE_GP_PRIMITIVES_OUT               0x00000010
+#define NV50_3D_COUNTER_ENABLE_TRANSFORM_FEEDBACK              0x00000020
+#define NV50_3D_COUNTER_ENABLE_GENERATED_PRIMITIVES            0x00000040
+#define NV50_3D_COUNTER_ENABLE_RAST_PRIMITIVES_PRECLIP         0x00000080
+#define NV50_3D_COUNTER_ENABLE_RAST_PRIMITIVES_POSTCLIP                0x00000100
+#define NV50_3D_COUNTER_ENABLE_FP_PIXELS                       0x00000200
+#define NV84_3D_COUNTER_ENABLE_UNK0A                           0x00000400
+
+#define NV50_3D_UNK0D6C(i0)                                   (0x00000d6c + 0x4*(i0))
+#define NV50_3D_UNK0D6C__ESIZE                                 0x00000004
+#define NV50_3D_UNK0D6C__LEN                                   0x00000002
+#define NV50_3D_UNK0D6C_X__MASK                                        0x0000ffff
+#define NV50_3D_UNK0D6C_X__SHIFT                               0
+#define NV50_3D_UNK0D6C_Y__MASK                                        0xffff0000
+#define NV50_3D_UNK0D6C_Y__SHIFT                               16
+
+#define NV50_3D_VERTEX_BUFFER_FIRST                            0x00000d74
+
+#define NV50_3D_VERTEX_BUFFER_COUNT                            0x00000d78
+
+#define NV50_3D_UNK0D7C                                                0x00000d7c
+
+#define NV50_3D_CLEAR_COLOR(i0)                                       (0x00000d80 + 0x4*(i0))
+#define NV50_3D_CLEAR_COLOR__ESIZE                             0x00000004
+#define NV50_3D_CLEAR_COLOR__LEN                               0x00000004
+
+#define NV50_3D_CLEAR_DEPTH                                    0x00000d90
+
+#define NV50_3D_STACK_ADDRESS_HIGH                             0x00000d94
+
+#define NV50_3D_STACK_ADDRESS_LOW                              0x00000d98
+
+#define NV50_3D_STACK_SIZE_LOG                                 0x00000d9c
+
+#define NV50_3D_CLEAR_STENCIL                                  0x00000da0
+
+#define NV50_3D_STRMOUT_PARAMS_LATCH                           0x00000da4
+
+#define NV50_3D_STRMOUT_PRIMITIVE_LIMIT                                0x00000da8
+
+#define NV50_3D_POLYGON_MODE_FRONT                             0x00000dac
+#define NV50_3D_POLYGON_MODE_FRONT_POINT                       0x00001b00
+#define NV50_3D_POLYGON_MODE_FRONT_LINE                                0x00001b01
+#define NV50_3D_POLYGON_MODE_FRONT_FILL                                0x00001b02
+
+#define NV50_3D_POLYGON_MODE_BACK                              0x00000db0
+#define NV50_3D_POLYGON_MODE_BACK_POINT                                0x00001b00
+#define NV50_3D_POLYGON_MODE_BACK_LINE                         0x00001b01
+#define NV50_3D_POLYGON_MODE_BACK_FILL                         0x00001b02
+
+#define NV50_3D_POLYGON_SMOOTH_ENABLE                          0x00000db4
+
+#define NV50_3D_UNK0DB8                                                0x00000db8
+
+#define NV50_3D_ZCULL_UNK0DBC                                  0x00000dbc
+#define NV50_3D_ZCULL_UNK0DBC_UNK0                             0x00000001
+#define NV50_3D_ZCULL_UNK0DBC_UNK16__MASK                      0x00030000
+#define NV50_3D_ZCULL_UNK0DBC_UNK16__SHIFT                     16
+
+#define NV50_3D_POLYGON_OFFSET_POINT_ENABLE                    0x00000dc0
+
+#define NV50_3D_POLYGON_OFFSET_LINE_ENABLE                     0x00000dc4
+
+#define NV50_3D_POLYGON_OFFSET_FILL_ENABLE                     0x00000dc8
+
+#define NV50_3D_UNK0DCC                                                0x00000dcc
+
+#define NV50_3D_VTX_ATTR_MASK_UNK0DD0(i0)                     (0x00000dd0 + 0x4*(i0))
+#define NV50_3D_VTX_ATTR_MASK_UNK0DD0__ESIZE                   0x00000004
+#define NV50_3D_VTX_ATTR_MASK_UNK0DD0__LEN                     0x00000002
+
+#define NV50_3D_ZCULL_UNK0DD8                                  0x00000dd8
+#define NV50_3D_ZCULL_UNK0DD8_UNK0__MASK                       0x00000007
+#define NV50_3D_ZCULL_UNK0DD8_UNK0__SHIFT                      0
+#define NVA3_3D_ZCULL_UNK0DD8_UNK9                             0x00000200
+#define NV50_3D_ZCULL_UNK0DD8_UNK16__MASK                      0xffff0000
+#define NV50_3D_ZCULL_UNK0DD8_UNK16__SHIFT                     16
+
+#define NV50_3D_UNK0DDC                                                0x00000ddc
+
+#define NV50_3D_UNK0DE0                                                0x00000de0
+
+#define NV50_3D_WATCHDOG_TIMER                                 0x00000de4
+
+#define NV50_3D_UNK0DE8                                                0x00000de8
+
+#define NV50_3D_UNK0DEC                                                0x00000dec
+
+#define NV50_3D_UNK0DF0                                                0x00000df0
+#define NV50_3D_UNK0DF0_UNK0                                   0x00000001
+#define NV50_3D_UNK0DF0_UNK1__MASK                             0x00000ff0
+#define NV50_3D_UNK0DF0_UNK1__SHIFT                            4
+
+#define NV50_3D_UNK0DF4                                                0x00000df4
+
+#define NV50_3D_WINDOW_OFFSET_X                                        0x00000df8
+
+#define NV50_3D_WINDOW_OFFSET_Y                                        0x00000dfc
+
+#define NV50_3D_SCISSOR_ENABLE(i0)                            (0x00000e00 + 0x10*(i0))
+#define NV50_3D_SCISSOR_ENABLE__ESIZE                          0x00000010
+#define NV50_3D_SCISSOR_ENABLE__LEN                            0x00000010
+
+#define NV50_3D_SCISSOR_HORIZ(i0)                             (0x00000e04 + 0x10*(i0))
+#define NV50_3D_SCISSOR_HORIZ__ESIZE                           0x00000010
+#define NV50_3D_SCISSOR_HORIZ__LEN                             0x00000010
+#define NV50_3D_SCISSOR_HORIZ_MIN__MASK                                0x0000ffff
+#define NV50_3D_SCISSOR_HORIZ_MIN__SHIFT                       0
+#define NV50_3D_SCISSOR_HORIZ_MAX__MASK                                0xffff0000
+#define NV50_3D_SCISSOR_HORIZ_MAX__SHIFT                       16
+
+#define NV50_3D_SCISSOR_VERT(i0)                              (0x00000e08 + 0x10*(i0))
+#define NV50_3D_SCISSOR_VERT__ESIZE                            0x00000010
+#define NV50_3D_SCISSOR_VERT__LEN                              0x00000010
+#define NV50_3D_SCISSOR_VERT_MIN__MASK                         0x0000ffff
+#define NV50_3D_SCISSOR_VERT_MIN__SHIFT                                0
+#define NV50_3D_SCISSOR_VERT_MAX__MASK                         0xffff0000
+#define NV50_3D_SCISSOR_VERT_MAX__SHIFT                                16
+
+#define NV50_3D_CB_ADDR                                                0x00000f00
+#define NV50_3D_CB_ADDR_ID__MASK                               0x003fff00
+#define NV50_3D_CB_ADDR_ID__SHIFT                              8
+#define NV50_3D_CB_ADDR_BUFFER__MASK                           0x0000007f
+#define NV50_3D_CB_ADDR_BUFFER__SHIFT                          0
+
+#define NV50_3D_CB_DATA(i0)                                   (0x00000f04 + 0x4*(i0))
+#define NV50_3D_CB_DATA__ESIZE                                 0x00000004
+#define NV50_3D_CB_DATA__LEN                                   0x00000010
+
+#define NV50_3D_LOCAL_WARPS_LOG_ALLOC                          0x00000f44
+
+#define NV50_3D_LOCAL_WARPS_NO_CLAMP                           0x00000f48
+
+#define NV50_3D_STACK_WARPS_LOG_ALLOC                          0x00000f4c
+
+#define NV50_3D_STACK_WARPS_NO_CLAMP                           0x00000f50
+
+#define NV50_3D_STENCIL_BACK_FUNC_REF                          0x00000f54
+
+#define NV50_3D_STENCIL_BACK_MASK                              0x00000f58
+
+#define NV50_3D_STENCIL_BACK_FUNC_MASK                         0x00000f5c
+
+#define NV50_3D_UNK0F60(i0)                                   (0x00000f60 + 0x4*(i0))
+#define NV50_3D_UNK0F60__ESIZE                                 0x00000004
+#define NV50_3D_UNK0F60__LEN                                   0x00000004
+
+#define NV50_3D_GP_ADDRESS_HIGH                                        0x00000f70
+
+#define NV50_3D_GP_ADDRESS_LOW                                 0x00000f74
+
+#define NV50_3D_UNK0F78                                                0x00000f78
+
+#define NV50_3D_VP_ADDRESS_HIGH                                        0x00000f7c
+
+#define NV50_3D_VP_ADDRESS_LOW                                 0x00000f80
+
+#define NV50_3D_VERTEX_RUNOUT_ADDRESS_HIGH                     0x00000f84
+
+#define NV50_3D_VERTEX_RUNOUT_ADDRESS_LOW                      0x00000f88
+
+#define NV50_3D_UNK0F8C                                                0x00000f8c
+
+#define NV50_3D_UNK0F90                                                0x00000f90
+
+#define NV50_3D_UNK0F94                                                0x00000f94
+
+#define NV50_3D_UNK0F98                                                0x00000f98
+
+#define NV50_3D_DEPTH_BOUNDS(i0)                              (0x00000f9c + 0x4*(i0))
+#define NV50_3D_DEPTH_BOUNDS__ESIZE                            0x00000004
+#define NV50_3D_DEPTH_BOUNDS__LEN                              0x00000002
+
+#define NV50_3D_FP_ADDRESS_HIGH                                        0x00000fa4
+
+#define NV50_3D_FP_ADDRESS_LOW                                 0x00000fa8
+
+#define NV50_3D_UNK0FAC                                                0x00000fac
+#define NV50_3D_UNK0FAC_UNK0                                   0x00000001
+#define NVA0_3D_UNK0FAC_UNK2                                   0x00000002
+#define NV50_3D_UNK0FAC_UNK1__MASK                             0x000ffff0
+#define NV50_3D_UNK0FAC_UNK1__SHIFT                            4
+
+#define NV50_3D_UNK0FB0                                                0x00000fb0
+
+#define NV50_3D_UNK0FB4                                                0x00000fb4
+
+#define NV50_3D_UNK0FB8                                                0x00000fb8
+
+#define NV50_3D_MSAA_MASK(i0)                                 (0x00000fbc + 0x4*(i0))
+#define NV50_3D_MSAA_MASK__ESIZE                               0x00000004
+#define NV50_3D_MSAA_MASK__LEN                                 0x00000004
+
+#define NV50_3D_CLIPID_ADDRESS_HIGH                            0x00000fcc
+
+#define NV50_3D_CLIPID_ADDRESS_LOW                             0x00000fd0
+
+#define NV50_3D_MAP_SEMANTIC_5                                 0x00000fd4
+#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__MASK               0x000000ff
+#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__SHIFT              0
+
+#define NV50_3D_UNK0FD8                                                0x00000fd8
+#define NV50_3D_UNK0FD8_UNK0                                   0x00000001
+#define NV50_3D_UNK0FD8_UNK1                                   0x00000010
+
+#define NV50_3D_UNK0FDC                                                0x00000fdc
+
+#define NV50_3D_ZETA_ADDRESS_HIGH                              0x00000fe0
+
+#define NV50_3D_ZETA_ADDRESS_LOW                               0x00000fe4
+
+#define NV50_3D_ZETA_FORMAT                                    0x00000fe8
+
+#define NV50_3D_ZETA_TILE_MODE                                 0x00000fec
+
+#define NV50_3D_ZETA_LAYER_STRIDE                              0x00000ff0
+#define NV50_3D_ZETA_LAYER_STRIDE__SHR                         2
+
+#define NV50_3D_SCREEN_SCISSOR_HORIZ                           0x00000ff4
+#define NV50_3D_SCREEN_SCISSOR_HORIZ_W__MASK                   0xffff0000
+#define NV50_3D_SCREEN_SCISSOR_HORIZ_W__SHIFT                  16
+#define NV50_3D_SCREEN_SCISSOR_HORIZ_X__MASK                   0x0000ffff
+#define NV50_3D_SCREEN_SCISSOR_HORIZ_X__SHIFT                  0
+
+#define NV50_3D_SCREEN_SCISSOR_VERT                            0x00000ff8
+#define NV50_3D_SCREEN_SCISSOR_VERT_H__MASK                    0xffff0000
+#define NV50_3D_SCREEN_SCISSOR_VERT_H__SHIFT                   16
+#define NV50_3D_SCREEN_SCISSOR_VERT_Y__MASK                    0x0000ffff
+#define NV50_3D_SCREEN_SCISSOR_VERT_Y__SHIFT                   0
+
+#define NV50_3D_UNK0FFC                                                0x00000ffc
+
+#define NV50_3D_VERTEX_ARRAY_PER_INSTANCE(i0)                 (0x00001000 + 0x4*(i0))
+#define NV50_3D_VERTEX_ARRAY_PER_INSTANCE__ESIZE               0x00000004
+#define NV50_3D_VERTEX_ARRAY_PER_INSTANCE__LEN                 0x00000010
+
+#define NV50_3D_UNK1040(i0)                                   (0x00001040 + 0x4*(i0))
+#define NV50_3D_UNK1040__ESIZE                                 0x00000004
+#define NV50_3D_UNK1040__LEN                                   0x00000010
+
+#define NV50_3D_VERTEX_ARRAY_LIMIT_HIGH(i0)                   (0x00001080 + 0x8*(i0))
+#define NV50_3D_VERTEX_ARRAY_LIMIT_HIGH__ESIZE                 0x00000008
+#define NV50_3D_VERTEX_ARRAY_LIMIT_HIGH__LEN                   0x00000010
+
+#define NV50_3D_VERTEX_ARRAY_LIMIT_LOW(i0)                    (0x00001084 + 0x8*(i0))
+#define NV50_3D_VERTEX_ARRAY_LIMIT_LOW__ESIZE                  0x00000008
+#define NV50_3D_VERTEX_ARRAY_LIMIT_LOW__LEN                    0x00000010
+
+#define NV50_3D_UNK1100                                                0x00001100
+
+#define NV84_3D_UNK1104                                                0x00001104
+#define NV84_3D_UNK1104_0__MASK                                        0x0000ffff
+#define NV84_3D_UNK1104_0__SHIFT                               0
+#define NV84_3D_UNK1104_0__MAX                                 0x00002000
+#define NV84_3D_UNK1104_0__ALIGN                               0x00000040
+#define NV84_3D_UNK1104_1__MASK                                        0xffff0000
+#define NV84_3D_UNK1104_1__SHIFT                               16
+#define NV84_3D_UNK1104_1__MAX                                 0x00002000
+#define NV84_3D_UNK1104_1__ALIGN                               0x00000040
+
+#define NV84_3D_UNK1108                                                0x00001108
+#define NV84_3D_UNK1108_0                                      0x00000001
+#define NV84_3D_UNK1108_1                                      0x00000010
+
+#define NV84_3D_UNK110C                                                0x0000110c
+
+#define NV84_3D_UNK1110                                                0x00001110
+
+#define NV84_3D_WRCACHE_FLUSH                                  0x00001114
+
+#define NV84_3D_VERTEX_ID_BASE                                 0x00001118
+
+#define NV84_3D_PRIMITIVE_ID                                   0x0000111c
+
+#define NVA3_3D_VTX_ATTR_MASK_UNK0DD0_ALT(i0)                 (0x00001120 + 0x4*(i0))
+#define NVA3_3D_VTX_ATTR_MASK_UNK0DD0_ALT__ESIZE               0x00000004
+#define NVA3_3D_VTX_ATTR_MASK_UNK0DD0_ALT__LEN                 0x00000004
+
+#define NVA3_3D_VP_ATTR_EN_ALT(i0)                            (0x00001130 + 0x4*(i0))
+#define NVA3_3D_VP_ATTR_EN_ALT__ESIZE                          0x00000004
+#define NVA3_3D_VP_ATTR_EN_ALT__LEN                            0x00000004
+#define NVA3_3D_VP_ATTR_EN_ALT_7__MASK                         0xf0000000
+#define NVA3_3D_VP_ATTR_EN_ALT_7__SHIFT                                28
+#define NVA3_3D_VP_ATTR_EN_ALT_7_X                             0x10000000
+#define NVA3_3D_VP_ATTR_EN_ALT_7_Y                             0x20000000
+#define NVA3_3D_VP_ATTR_EN_ALT_7_Z                             0x40000000
+#define NVA3_3D_VP_ATTR_EN_ALT_7_W                             0x80000000
+#define NVA3_3D_VP_ATTR_EN_ALT_6__MASK                         0x0f000000
+#define NVA3_3D_VP_ATTR_EN_ALT_6__SHIFT                                24
+#define NVA3_3D_VP_ATTR_EN_ALT_6_X                             0x01000000
+#define NVA3_3D_VP_ATTR_EN_ALT_6_Y                             0x02000000
+#define NVA3_3D_VP_ATTR_EN_ALT_6_Z                             0x04000000
+#define NVA3_3D_VP_ATTR_EN_ALT_6_W                             0x08000000
+#define NVA3_3D_VP_ATTR_EN_ALT_5__MASK                         0x00f00000
+#define NVA3_3D_VP_ATTR_EN_ALT_5__SHIFT                                20
+#define NVA3_3D_VP_ATTR_EN_ALT_5_X                             0x00100000
+#define NVA3_3D_VP_ATTR_EN_ALT_5_Y                             0x00200000
+#define NVA3_3D_VP_ATTR_EN_ALT_5_Z                             0x00400000
+#define NVA3_3D_VP_ATTR_EN_ALT_5_W                             0x00800000
+#define NVA3_3D_VP_ATTR_EN_ALT_4__MASK                         0x000f0000
+#define NVA3_3D_VP_ATTR_EN_ALT_4__SHIFT                                16
+#define NVA3_3D_VP_ATTR_EN_ALT_4_X                             0x00010000
+#define NVA3_3D_VP_ATTR_EN_ALT_4_Y                             0x00020000
+#define NVA3_3D_VP_ATTR_EN_ALT_4_Z                             0x00040000
+#define NVA3_3D_VP_ATTR_EN_ALT_4_W                             0x00080000
+#define NVA3_3D_VP_ATTR_EN_ALT_3__MASK                         0x0000f000
+#define NVA3_3D_VP_ATTR_EN_ALT_3__SHIFT                                12
+#define NVA3_3D_VP_ATTR_EN_ALT_3_X                             0x00001000
+#define NVA3_3D_VP_ATTR_EN_ALT_3_Y                             0x00002000
+#define NVA3_3D_VP_ATTR_EN_ALT_3_Z                             0x00004000
+#define NVA3_3D_VP_ATTR_EN_ALT_3_W                             0x00008000
+#define NVA3_3D_VP_ATTR_EN_ALT_2__MASK                         0x00000f00
+#define NVA3_3D_VP_ATTR_EN_ALT_2__SHIFT                                8
+#define NVA3_3D_VP_ATTR_EN_ALT_2_X                             0x00000100
+#define NVA3_3D_VP_ATTR_EN_ALT_2_Y                             0x00000200
+#define NVA3_3D_VP_ATTR_EN_ALT_2_Z                             0x00000400
+#define NVA3_3D_VP_ATTR_EN_ALT_2_W                             0x00000800
+#define NVA3_3D_VP_ATTR_EN_ALT_1__MASK                         0x000000f0
+#define NVA3_3D_VP_ATTR_EN_ALT_1__SHIFT                                4
+#define NVA3_3D_VP_ATTR_EN_ALT_1_X                             0x00000010
+#define NVA3_3D_VP_ATTR_EN_ALT_1_Y                             0x00000020
+#define NVA3_3D_VP_ATTR_EN_ALT_1_Z                             0x00000040
+#define NVA3_3D_VP_ATTR_EN_ALT_1_W                             0x00000080
+#define NVA3_3D_VP_ATTR_EN_ALT_0__MASK                         0x0000000f
+#define NVA3_3D_VP_ATTR_EN_ALT_0__SHIFT                                0
+#define NVA3_3D_VP_ATTR_EN_ALT_0_X                             0x00000001
+#define NVA3_3D_VP_ATTR_EN_ALT_0_Y                             0x00000002
+#define NVA3_3D_VP_ATTR_EN_ALT_0_Z                             0x00000004
+#define NVA3_3D_VP_ATTR_EN_ALT_0_W                             0x00000008
+
+#define NVA3_3D_UNK1140                                                0x00001140
+
+#define NVA0_3D_UNK1144                                                0x00001144
+
+#define NVA0_3D_VTX_ATTR_DEFINE                                        0x0000114c
+#define NVA0_3D_VTX_ATTR_DEFINE_ATTR__MASK                     0x000000ff
+#define NVA0_3D_VTX_ATTR_DEFINE_ATTR__SHIFT                    0
+#define NVA0_3D_VTX_ATTR_DEFINE_COMP__MASK                     0x00000700
+#define NVA0_3D_VTX_ATTR_DEFINE_COMP__SHIFT                    8
+#define NVA0_3D_VTX_ATTR_DEFINE_COMP__MIN                      0x00000001
+#define NVA0_3D_VTX_ATTR_DEFINE_COMP__MAX                      0x00000004
+#define NVA0_3D_VTX_ATTR_DEFINE_SIZE__MASK                     0x00007000
+#define NVA0_3D_VTX_ATTR_DEFINE_SIZE__SHIFT                    12
+#define NVA0_3D_VTX_ATTR_DEFINE_SIZE_8                         0x00001000
+#define NVA0_3D_VTX_ATTR_DEFINE_SIZE_16                                0x00002000
+#define NVA0_3D_VTX_ATTR_DEFINE_SIZE_32                                0x00004000
+#define NVA0_3D_VTX_ATTR_DEFINE_TYPE__MASK                     0x00070000
+#define NVA0_3D_VTX_ATTR_DEFINE_TYPE__SHIFT                    16
+#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_SNORM                     0x00010000
+#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_UNORM                     0x00020000
+#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_SINT                      0x00030000
+#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_UINT                      0x00040000
+#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_USCALED                   0x00050000
+#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_SSCALED                   0x00060000
+#define NVA0_3D_VTX_ATTR_DEFINE_TYPE_FLOAT                     0x00070000
+
+#define NVA0_3D_VTX_ATTR_DATA(i0)                             (0x00001150 + 0x4*(i0))
+#define NVA0_3D_VTX_ATTR_DATA__ESIZE                           0x00000004
+#define NVA0_3D_VTX_ATTR_DATA__LEN                             0x00000004
+
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT(i0)                   (0x00001160 + 0x4*(i0))
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT__ESIZE                 0x00000004
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT__LEN                   0x00000020
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_BUFFER__MASK           0x0000001f
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_BUFFER__SHIFT          0
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_CONST                  0x00000040
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_OFFSET__MASK           0x001fff80
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_OFFSET__SHIFT          7
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT__MASK           0x07e00000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT__SHIFT          21
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_32_32_32_32     0x00200000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_32_32_32                0x00400000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_16_16_16_16     0x00600000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_32_32           0x00800000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_16_16_16                0x00a00000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_8_8_8_8         0x01400000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_16_16           0x01e00000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_32              0x02400000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_8_8_8           0x02600000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_8_8             0x03000000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_16              0x03600000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_8               0x03a00000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_FORMAT_2_10_10_10      0x06000000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE__MASK             0x38000000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE__SHIFT            27
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_SNORM             0x08000000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_UNORM             0x10000000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_SINT              0x18000000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_UINT              0x20000000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_USCALED           0x28000000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_SSCALED           0x30000000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_TYPE_FLOAT             0x38000000
+#define NVA3_3D_VERTEX_ARRAY_ATTRIB_ALT_BGRA                   0x80000000
+
+#define NV50_3D_RT_CONTROL                                     0x0000121c
+#define NV50_3D_RT_CONTROL_COUNT__MASK                         0x0000000f
+#define NV50_3D_RT_CONTROL_COUNT__SHIFT                                0
+#define NV50_3D_RT_CONTROL_MAP0__MASK                          0x00000070
+#define NV50_3D_RT_CONTROL_MAP0__SHIFT                         4
+#define NV50_3D_RT_CONTROL_MAP1__MASK                          0x00000380
+#define NV50_3D_RT_CONTROL_MAP1__SHIFT                         7
+#define NV50_3D_RT_CONTROL_MAP2__MASK                          0x00001c00
+#define NV50_3D_RT_CONTROL_MAP2__SHIFT                         10
+#define NV50_3D_RT_CONTROL_MAP3__MASK                          0x0000e000
+#define NV50_3D_RT_CONTROL_MAP3__SHIFT                         13
+#define NV50_3D_RT_CONTROL_MAP4__MASK                          0x00070000
+#define NV50_3D_RT_CONTROL_MAP4__SHIFT                         16
+#define NV50_3D_RT_CONTROL_MAP5__MASK                          0x00380000
+#define NV50_3D_RT_CONTROL_MAP5__SHIFT                         19
+#define NV50_3D_RT_CONTROL_MAP6__MASK                          0x01c00000
+#define NV50_3D_RT_CONTROL_MAP6__SHIFT                         22
+#define NV50_3D_RT_CONTROL_MAP7__MASK                          0x0e000000
+#define NV50_3D_RT_CONTROL_MAP7__SHIFT                         25
+
+#define NV50_3D_UNK1220                                                0x00001220
+
+#define NV50_3D_RT_ARRAY_MODE                                  0x00001224
+#define NV50_3D_RT_ARRAY_MODE_LAYERS__MASK                     0x0000ffff
+#define NV50_3D_RT_ARRAY_MODE_LAYERS__SHIFT                    0
+#define NV50_3D_RT_ARRAY_MODE_MODE__MASK                       0x00010000
+#define NV50_3D_RT_ARRAY_MODE_MODE__SHIFT                      16
+#define NV50_3D_RT_ARRAY_MODE_MODE_2D_ARRAY                    0x00000000
+#define NV50_3D_RT_ARRAY_MODE_MODE_3D                          0x00010000
+
+#define NV50_3D_ZETA_HORIZ                                     0x00001228
+
+#define NV50_3D_ZETA_VERT                                      0x0000122c
+
+#define NV50_3D_ZETA_ARRAY_MODE                                        0x00001230
+#define NV50_3D_ZETA_ARRAY_MODE_LAYERS__MASK                   0x0000ffff
+#define NV50_3D_ZETA_ARRAY_MODE_LAYERS__SHIFT                  0
+#define NV50_3D_ZETA_ARRAY_MODE_UNK                            0x00010000
+
+#define NV50_3D_LINKED_TSC                                     0x00001234
+
+#define NV50_3D_UNK1238                                                0x00001238
+
+#define NVA0_3D_DRAW_TFB_BYTES                                 0x0000123c
+
+#define NV50_3D_RT_HORIZ(i0)                                  (0x00001240 + 0x8*(i0))
+#define NV50_3D_RT_HORIZ__ESIZE                                        0x00000008
+#define NV50_3D_RT_HORIZ__LEN                                  0x00000008
+#define NV50_3D_RT_HORIZ_WIDTH__MASK                           0x0fffffff
+#define NV50_3D_RT_HORIZ_WIDTH__SHIFT                          0
+#define NV50_3D_RT_HORIZ_LINEAR                                        0x80000000
+
+#define NV50_3D_RT_VERT(i0)                                   (0x00001244 + 0x8*(i0))
+#define NV50_3D_RT_VERT__ESIZE                                 0x00000008
+#define NV50_3D_RT_VERT__LEN                                   0x00000008
+
+#define NV50_3D_CB_DEF_ADDRESS_HIGH                            0x00001280
+
+#define NV50_3D_CB_DEF_ADDRESS_LOW                             0x00001284
+
+#define NV50_3D_CB_DEF_SET                                     0x00001288
+#define NV50_3D_CB_DEF_SET_SIZE__MASK                          0x0000ffff
+#define NV50_3D_CB_DEF_SET_SIZE__SHIFT                         0
+#define NV50_3D_CB_DEF_SET_BUFFER__MASK                                0x007f0000
+#define NV50_3D_CB_DEF_SET_BUFFER__SHIFT                       16
+
+#define NV50_3D_UNK128C                                                0x0000128c
+#define NV50_3D_UNK128C_0__MASK                                        0x00000003
+#define NV50_3D_UNK128C_0__SHIFT                               0
+#define NV50_3D_UNK128C_1__MASK                                        0x00000030
+#define NV50_3D_UNK128C_1__SHIFT                               4
+#define NV50_3D_UNK128C_2__MASK                                        0x00000300
+#define NV50_3D_UNK128C_2__SHIFT                               8
+#define NV50_3D_UNK128C_3__MASK                                        0x00003000
+#define NV50_3D_UNK128C_3__SHIFT                               12
+
+#define NV50_3D_CALL_LIMIT_LOG                                 0x00001290
+#define NV50_3D_CALL_LIMIT_LOG_VP__MASK                                0x0000000f
+#define NV50_3D_CALL_LIMIT_LOG_VP__SHIFT                       0
+#define NV50_3D_CALL_LIMIT_LOG_GP__MASK                                0x000000f0
+#define NV50_3D_CALL_LIMIT_LOG_GP__SHIFT                       4
+#define NV50_3D_CALL_LIMIT_LOG_FP__MASK                                0x00000f00
+#define NV50_3D_CALL_LIMIT_LOG_FP__SHIFT                       8
+
+#define NV50_3D_STRMOUT_BUFFERS_CTRL                           0x00001294
+#define NV50_3D_STRMOUT_BUFFERS_CTRL_INTERLEAVED               0x00000001
+#define NVA0_3D_STRMOUT_BUFFERS_CTRL_LIMIT_MODE__MASK          0x00000002
+#define NVA0_3D_STRMOUT_BUFFERS_CTRL_LIMIT_MODE__SHIFT         1
+#define NVA0_3D_STRMOUT_BUFFERS_CTRL_LIMIT_MODE_PRIMITIVES     0x00000000
+#define NVA0_3D_STRMOUT_BUFFERS_CTRL_LIMIT_MODE_OFFSET         0x00000002
+#define NV50_3D_STRMOUT_BUFFERS_CTRL_SEPARATE__MASK            0x000000f0
+#define NV50_3D_STRMOUT_BUFFERS_CTRL_SEPARATE__SHIFT           4
+#define NV50_3D_STRMOUT_BUFFERS_CTRL_STRIDE__MASK              0x000fff00
+#define NV50_3D_STRMOUT_BUFFERS_CTRL_STRIDE__SHIFT             8
+#define NV50_3D_STRMOUT_BUFFERS_CTRL_STRIDE__MAX               0x00000800
+
+#define NV50_3D_FP_RESULT_COUNT                                        0x00001298
+
+#define NV50_3D_VTX_UNK129C                                    0x0000129c
+
+#define NV50_3D_UNK12A0                                                0x000012a0
+
+#define NV50_3D_UNK12A8                                                0x000012a8
+#define NV50_3D_UNK12A8_UNK1                                   0x00000001
+#define NV50_3D_UNK12A8_UNK2__MASK                             0x000ffff0
+#define NV50_3D_UNK12A8_UNK2__SHIFT                            4
+
+#define NV50_3D_UNK12AC                                                0x000012ac
+
+#define NV50_3D_UNK12B0                                                0x000012b0
+#define NV50_3D_UNK12B0_UNK0__MASK                             0x000000ff
+#define NV50_3D_UNK12B0_UNK0__SHIFT                            0
+#define NV50_3D_UNK12B0_UNK1__MASK                             0x0000ff00
+#define NV50_3D_UNK12B0_UNK1__SHIFT                            8
+#define NV50_3D_UNK12B0_UNK2__MASK                             0x00ff0000
+#define NV50_3D_UNK12B0_UNK2__SHIFT                            16
+#define NV50_3D_UNK12B0_UNK3__MASK                             0xff000000
+#define NV50_3D_UNK12B0_UNK3__SHIFT                            24
+#define NV50_3D_UNK12B0_UNK3__MAX                              0x00000080
+
+#define NV50_3D_UNK12B4                                                0x000012b4
+
+#define NV50_3D_UNK12B8                                                0x000012b8
+
+#define NV50_3D_DEPTH_TEST_ENABLE                              0x000012cc
+
+#define NV50_3D_D3D_FILL_MODE                                  0x000012d0
+#define NV50_3D_D3D_FILL_MODE_POINT                            0x00000001
+#define NV50_3D_D3D_FILL_MODE_WIREFRAME                                0x00000002
+#define NV50_3D_D3D_FILL_MODE_SOLID                            0x00000003
+
+#define NV50_3D_SHADE_MODEL                                    0x000012d4
+#define NV50_3D_SHADE_MODEL_FLAT                               0x00001d00
+#define NV50_3D_SHADE_MODEL_SMOOTH                             0x00001d01
+
+#define NV50_3D_LOCAL_ADDRESS_HIGH                             0x000012d8
+
+#define NV50_3D_LOCAL_ADDRESS_LOW                              0x000012dc
+
+#define NV50_3D_LOCAL_SIZE_LOG                                 0x000012e0
+
+#define NV50_3D_BLEND_INDEPENDENT                              0x000012e4
+
+#define NV50_3D_DEPTH_WRITE_ENABLE                             0x000012e8
+
+#define NV50_3D_ALPHA_TEST_ENABLE                              0x000012ec
+
+#define NV50_3D_PM_SET(i0)                                    (0x000012f0 + 0x4*(i0))
+#define NV50_3D_PM_SET__ESIZE                                  0x00000004
+#define NV50_3D_PM_SET__LEN                                    0x00000004
+
+#define NV50_3D_VB_ELEMENT_U8_SETUP                            0x00001300
+#define NV50_3D_VB_ELEMENT_U8_SETUP_OFFSET__MASK               0xc0000000
+#define NV50_3D_VB_ELEMENT_U8_SETUP_OFFSET__SHIFT              30
+#define NV50_3D_VB_ELEMENT_U8_SETUP_COUNT__MASK                        0x3fffffff
+#define NV50_3D_VB_ELEMENT_U8_SETUP_COUNT__SHIFT               0
+
+#define NV50_3D_VB_ELEMENT_U8                                  0x00001304
+#define NV50_3D_VB_ELEMENT_U8_I0__MASK                         0x000000ff
+#define NV50_3D_VB_ELEMENT_U8_I0__SHIFT                                0
+#define NV50_3D_VB_ELEMENT_U8_I1__MASK                         0x0000ff00
+#define NV50_3D_VB_ELEMENT_U8_I1__SHIFT                                8
+#define NV50_3D_VB_ELEMENT_U8_I2__MASK                         0x00ff0000
+#define NV50_3D_VB_ELEMENT_U8_I2__SHIFT                                16
+#define NV50_3D_VB_ELEMENT_U8_I3__MASK                         0xff000000
+#define NV50_3D_VB_ELEMENT_U8_I3__SHIFT                                24
+
+#define NV50_3D_D3D_CULL_MODE                                  0x00001308
+#define NV50_3D_D3D_CULL_MODE_NONE                             0x00000001
+#define NV50_3D_D3D_CULL_MODE_FRONT                            0x00000002
+#define NV50_3D_D3D_CULL_MODE_BACK                             0x00000003
+
+#define NV50_3D_DEPTH_TEST_FUNC                                        0x0000130c
+#define NV50_3D_DEPTH_TEST_FUNC_NEVER                          0x00000200
+#define NV50_3D_DEPTH_TEST_FUNC_LESS                           0x00000201
+#define NV50_3D_DEPTH_TEST_FUNC_EQUAL                          0x00000202
+#define NV50_3D_DEPTH_TEST_FUNC_LEQUAL                         0x00000203
+#define NV50_3D_DEPTH_TEST_FUNC_GREATER                                0x00000204
+#define NV50_3D_DEPTH_TEST_FUNC_NOTEQUAL                       0x00000205
+#define NV50_3D_DEPTH_TEST_FUNC_GEQUAL                         0x00000206
+#define NV50_3D_DEPTH_TEST_FUNC_ALWAYS                         0x00000207
+
+#define NV50_3D_ALPHA_TEST_REF                                 0x00001310
+
+#define NV50_3D_ALPHA_TEST_FUNC                                        0x00001314
+#define NV50_3D_ALPHA_TEST_FUNC_NEVER                          0x00000200
+#define NV50_3D_ALPHA_TEST_FUNC_LESS                           0x00000201
+#define NV50_3D_ALPHA_TEST_FUNC_EQUAL                          0x00000202
+#define NV50_3D_ALPHA_TEST_FUNC_LEQUAL                         0x00000203
+#define NV50_3D_ALPHA_TEST_FUNC_GREATER                                0x00000204
+#define NV50_3D_ALPHA_TEST_FUNC_NOTEQUAL                       0x00000205
+#define NV50_3D_ALPHA_TEST_FUNC_GEQUAL                         0x00000206
+#define NV50_3D_ALPHA_TEST_FUNC_ALWAYS                         0x00000207
+
+#define NVA0_3D_DRAW_TFB_STRIDE                                        0x00001318
+#define NVA0_3D_DRAW_TFB_STRIDE__MIN                           0x00000001
+#define NVA0_3D_DRAW_TFB_STRIDE__MAX                           0x00000fff
+
+#define NV50_3D_BLEND_COLOR(i0)                                       (0x0000131c + 0x4*(i0))
+#define NV50_3D_BLEND_COLOR__ESIZE                             0x00000004
+#define NV50_3D_BLEND_COLOR__LEN                               0x00000004
+
+#define NV50_3D_UNK132C                                                0x0000132c
+
+#define NV50_3D_TSC_FLUSH                                      0x00001330
+#define NV50_3D_TSC_FLUSH_SPECIFIC                             0x00000001
+#define NV50_3D_TSC_FLUSH_ENTRY__MASK                          0x03fffff0
+#define NV50_3D_TSC_FLUSH_ENTRY__SHIFT                         4
+
+#define NV50_3D_TIC_FLUSH                                      0x00001334
+#define NV50_3D_TIC_FLUSH_SPECIFIC                             0x00000001
+#define NV50_3D_TIC_FLUSH_ENTRY__MASK                          0x03fffff0
+#define NV50_3D_TIC_FLUSH_ENTRY__SHIFT                         4
+
+#define NV50_3D_TEX_CACHE_CTL                                  0x00001338
+#define NV50_3D_TEX_CACHE_CTL_UNK1__MASK                       0x00000030
+#define NV50_3D_TEX_CACHE_CTL_UNK1__SHIFT                      4
+
+#define NV50_3D_UNK133C                                                0x0000133c
+
+#define NV50_3D_BLEND_EQUATION_RGB                             0x00001340
+#define NV50_3D_BLEND_EQUATION_RGB_FUNC_ADD                    0x00008006
+#define NV50_3D_BLEND_EQUATION_RGB_MIN                         0x00008007
+#define NV50_3D_BLEND_EQUATION_RGB_MAX                         0x00008008
+#define NV50_3D_BLEND_EQUATION_RGB_FUNC_SUBTRACT               0x0000800a
+#define NV50_3D_BLEND_EQUATION_RGB_FUNC_REVERSE_SUBTRACT       0x0000800b
+
+#define NV50_3D_BLEND_FUNC_SRC_RGB                             0x00001344
+
+#define NV50_3D_BLEND_FUNC_DST_RGB                             0x00001348
+
+#define NV50_3D_BLEND_EQUATION_ALPHA                           0x0000134c
+#define NV50_3D_BLEND_EQUATION_ALPHA_FUNC_ADD                  0x00008006
+#define NV50_3D_BLEND_EQUATION_ALPHA_MIN                       0x00008007
+#define NV50_3D_BLEND_EQUATION_ALPHA_MAX                       0x00008008
+#define NV50_3D_BLEND_EQUATION_ALPHA_FUNC_SUBTRACT             0x0000800a
+#define NV50_3D_BLEND_EQUATION_ALPHA_FUNC_REVERSE_SUBTRACT     0x0000800b
+
+#define NV50_3D_BLEND_FUNC_SRC_ALPHA                           0x00001350
+
+#define NV50_3D_UNK1354                                                0x00001354
+
+#define NV50_3D_BLEND_FUNC_DST_ALPHA                           0x00001358
+
+#define NV50_3D_UNK135C                                                0x0000135c
+
+#define NV50_3D_BLEND_ENABLE(i0)                              (0x00001360 + 0x4*(i0))
+#define NV50_3D_BLEND_ENABLE__ESIZE                            0x00000004
+#define NV50_3D_BLEND_ENABLE__LEN                              0x00000008
+
+#define NV50_3D_STENCIL_ENABLE                                 0x00001380
+
+#define NV50_3D_STENCIL_FRONT_OP_FAIL                          0x00001384
+#define NV50_3D_STENCIL_FRONT_OP_FAIL_ZERO                     0x00000000
+#define NV50_3D_STENCIL_FRONT_OP_FAIL_INVERT                   0x0000150a
+#define NV50_3D_STENCIL_FRONT_OP_FAIL_KEEP                     0x00001e00
+#define NV50_3D_STENCIL_FRONT_OP_FAIL_REPLACE                  0x00001e01
+#define NV50_3D_STENCIL_FRONT_OP_FAIL_INCR                     0x00001e02
+#define NV50_3D_STENCIL_FRONT_OP_FAIL_DECR                     0x00001e03
+#define NV50_3D_STENCIL_FRONT_OP_FAIL_INCR_WRAP                        0x00008507
+#define NV50_3D_STENCIL_FRONT_OP_FAIL_DECR_WRAP                        0x00008508
+
+#define NV50_3D_STENCIL_FRONT_OP_ZFAIL                         0x00001388
+#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_ZERO                    0x00000000
+#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_INVERT                  0x0000150a
+#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_KEEP                    0x00001e00
+#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_REPLACE                 0x00001e01
+#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_INCR                    0x00001e02
+#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_DECR                    0x00001e03
+#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_INCR_WRAP               0x00008507
+#define NV50_3D_STENCIL_FRONT_OP_ZFAIL_DECR_WRAP               0x00008508
+
+#define NV50_3D_STENCIL_FRONT_OP_ZPASS                         0x0000138c
+#define NV50_3D_STENCIL_FRONT_OP_ZPASS_ZERO                    0x00000000
+#define NV50_3D_STENCIL_FRONT_OP_ZPASS_INVERT                  0x0000150a
+#define NV50_3D_STENCIL_FRONT_OP_ZPASS_KEEP                    0x00001e00
+#define NV50_3D_STENCIL_FRONT_OP_ZPASS_REPLACE                 0x00001e01
+#define NV50_3D_STENCIL_FRONT_OP_ZPASS_INCR                    0x00001e02
+#define NV50_3D_STENCIL_FRONT_OP_ZPASS_DECR                    0x00001e03
+#define NV50_3D_STENCIL_FRONT_OP_ZPASS_INCR_WRAP               0x00008507
+#define NV50_3D_STENCIL_FRONT_OP_ZPASS_DECR_WRAP               0x00008508
+
+#define NV50_3D_STENCIL_FRONT_FUNC_FUNC                                0x00001390
+#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_NEVER                  0x00000200
+#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_LESS                   0x00000201
+#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_EQUAL                  0x00000202
+#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_LEQUAL                 0x00000203
+#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_GREATER                        0x00000204
+#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_NOTEQUAL               0x00000205
+#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_GEQUAL                 0x00000206
+#define NV50_3D_STENCIL_FRONT_FUNC_FUNC_ALWAYS                 0x00000207
+
+#define NV50_3D_STENCIL_FRONT_FUNC_REF                         0x00001394
+
+#define NV50_3D_STENCIL_FRONT_MASK                             0x00001398
+
+#define NV50_3D_STENCIL_FRONT_FUNC_MASK                                0x0000139c
+
+#define NV50_3D_UNK13A0                                                0x000013a0
+
+#define NVA0_3D_DRAW_TFB_BASE                                  0x000013a4
+
+#define NV50_3D_FRAG_COLOR_CLAMP_EN                            0x000013a8
+#define NV50_3D_FRAG_COLOR_CLAMP_EN_0                          0x00000001
+#define NV50_3D_FRAG_COLOR_CLAMP_EN_1                          0x00000010
+#define NV50_3D_FRAG_COLOR_CLAMP_EN_2                          0x00000100
+#define NV50_3D_FRAG_COLOR_CLAMP_EN_3                          0x00001000
+#define NV50_3D_FRAG_COLOR_CLAMP_EN_4                          0x00010000
+#define NV50_3D_FRAG_COLOR_CLAMP_EN_5                          0x00100000
+#define NV50_3D_FRAG_COLOR_CLAMP_EN_6                          0x01000000
+#define NV50_3D_FRAG_COLOR_CLAMP_EN_7                          0x10000000
+
+#define NV50_3D_SCREEN_Y_CONTROL                               0x000013ac
+#define NV50_3D_SCREEN_Y_CONTROL_Y_NEGATE                      0x00000001
+#define NV50_3D_SCREEN_Y_CONTROL_TRIANGLE_RAST_FLIP            0x00000010
+
+#define NV50_3D_LINE_WIDTH                                     0x000013b0
+
+#define NV50_3D_TEX_LIMITS(i0)                                (0x000013b4 + 0x4*(i0))
+#define NV50_3D_TEX_LIMITS__ESIZE                              0x00000004
+#define NV50_3D_TEX_LIMITS__LEN                                        0x00000003
+#define NV50_3D_TEX_LIMITS_SAMPLERS_LOG2__MASK                 0x0000000f
+#define NV50_3D_TEX_LIMITS_SAMPLERS_LOG2__SHIFT                        0
+#define NV50_3D_TEX_LIMITS_SAMPLERS_LOG2__MIN                  0x00000000
+#define NV50_3D_TEX_LIMITS_SAMPLERS_LOG2__MAX                  0x00000004
+#define NV50_3D_TEX_LIMITS_TEXTURES_LOG2__MASK                 0x000000f0
+#define NV50_3D_TEX_LIMITS_TEXTURES_LOG2__SHIFT                        4
+#define NV50_3D_TEX_LIMITS_TEXTURES_LOG2__MIN                  0x00000000
+#define NV50_3D_TEX_LIMITS_TEXTURES_LOG2__MAX                  0x00000007
+
+#define NV50_3D_POINT_COORD_REPLACE_MAP(i0)                   (0x000013c0 + 0x4*(i0))
+#define NV50_3D_POINT_COORD_REPLACE_MAP__ESIZE                 0x00000004
+#define NV50_3D_POINT_COORD_REPLACE_MAP__LEN                   0x00000010
+
+#define NV50_3D_UNK1400_LANES                                  0x00001400
+
+#define NV50_3D_UNK1404                                                0x00001404
+
+#define NV50_3D_UNK1408                                                0x00001408
+
+#define NV50_3D_VP_START_ID                                    0x0000140c
+
+#define NV50_3D_GP_START_ID                                    0x00001410
+
+#define NV50_3D_FP_START_ID                                    0x00001414
+
+#define NVA3_3D_UNK1418                                                0x00001418
+
+#define NV50_3D_UNK141C                                                0x0000141c
+
+#define NV50_3D_GP_VERTEX_OUTPUT_COUNT                         0x00001420
+#define NV50_3D_GP_VERTEX_OUTPUT_COUNT__MIN                    0x00000001
+#define NV50_3D_GP_VERTEX_OUTPUT_COUNT__MAX                    0x00000400
+
+#define NV50_3D_VERTEX_ARRAY_FLUSH                             0x0000142c
+
+#define NV50_3D_UNK1430                                                0x00001430
+#define NV50_3D_UNK1430_UNK0                                   0x00000010
+#define NV50_3D_UNK1430_UNK1                                   0x00000100
+
+#define NV50_3D_VB_ELEMENT_BASE                                        0x00001434
+
+#define NV50_3D_VB_INSTANCE_BASE                               0x00001438
+
+#define NV50_3D_CLEAR_FLAGS                                    0x0000143c
+#define NV50_3D_CLEAR_FLAGS_STENCIL_MASK                       0x00000001
+#define NV50_3D_CLEAR_FLAGS_CLEAR_RECT__MASK                   0x00000010
+#define NV50_3D_CLEAR_FLAGS_CLEAR_RECT__SHIFT                  4
+#define NV50_3D_CLEAR_FLAGS_CLEAR_RECT_SCISSOR                 0x00000000
+#define NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT                        0x00000010
+
+#define NV50_3D_CODE_CB_FLUSH                                  0x00001440
+
+#define NV50_3D_BIND_TSC(i0)                                  (0x00001444 + 0x8*(i0))
+#define NV50_3D_BIND_TSC__ESIZE                                        0x00000008
+#define NV50_3D_BIND_TSC__LEN                                  0x00000003
+#define NV50_3D_BIND_TSC_VALID                                 0x00000001
+#define NV50_3D_BIND_TSC_SAMPLER__MASK                         0x000000f0
+#define NV50_3D_BIND_TSC_SAMPLER__SHIFT                                4
+#define NV50_3D_BIND_TSC_TSC__MASK                             0x001ff000
+#define NV50_3D_BIND_TSC_TSC__SHIFT                            12
+
+#define NV50_3D_BIND_TIC(i0)                                  (0x00001448 + 0x8*(i0))
+#define NV50_3D_BIND_TIC__ESIZE                                        0x00000008
+#define NV50_3D_BIND_TIC__LEN                                  0x00000003
+#define NV50_3D_BIND_TIC_VALID                                 0x00000001
+#define NV50_3D_BIND_TIC_TEXTURE__MASK                         0x000001fe
+#define NV50_3D_BIND_TIC_TEXTURE__SHIFT                                1
+#define NV50_3D_BIND_TIC_TIC__MASK                             0x7ffffe00
+#define NV50_3D_BIND_TIC_TIC__SHIFT                            9
+
+#define NV50_3D_BIND_TSC2(i0)                                 (0x00001468 + 0x8*(i0))
+#define NV50_3D_BIND_TSC2__ESIZE                               0x00000008
+#define NV50_3D_BIND_TSC2__LEN                                 0x00000003
+#define NV50_3D_BIND_TSC2_VALID                                        0x00000001
+#define NV50_3D_BIND_TSC2_SAMPLER__MASK                                0x000000f0
+#define NV50_3D_BIND_TSC2_SAMPLER__SHIFT                       4
+#define NV50_3D_BIND_TSC2_TSC__MASK                            0x001ff000
+#define NV50_3D_BIND_TSC2_TSC__SHIFT                           12
+
+#define NV50_3D_BIND_TIC2(i0)                                 (0x0000146c + 0x8*(i0))
+#define NV50_3D_BIND_TIC2__ESIZE                               0x00000008
+#define NV50_3D_BIND_TIC2__LEN                                 0x00000003
+#define NV50_3D_BIND_TIC2_VALID                                        0x00000001
+#define NV50_3D_BIND_TIC2_TEXTURE__MASK                                0x000001fe
+#define NV50_3D_BIND_TIC2_TEXTURE__SHIFT                       1
+#define NV50_3D_BIND_TIC2_TIC__MASK                            0x7ffffe00
+#define NV50_3D_BIND_TIC2_TIC__SHIFT                           9
+
+#define NV50_3D_STRMOUT_MAP(i0)                                       (0x00001480 + 0x4*(i0))
+#define NV50_3D_STRMOUT_MAP__ESIZE                             0x00000004
+#define NV50_3D_STRMOUT_MAP__LEN                               0x00000020
+
+#define NV50_3D_CLIPID_HEIGHT                                  0x00001504
+#define NV50_3D_CLIPID_HEIGHT__MAX                             0x00002000
+
+#define NV50_3D_CLIPID_FILL_RECT_HORIZ                         0x00001508
+#define NV50_3D_CLIPID_FILL_RECT_HORIZ_LOW__MASK               0x0000ffff
+#define NV50_3D_CLIPID_FILL_RECT_HORIZ_LOW__SHIFT              0
+#define NV50_3D_CLIPID_FILL_RECT_HORIZ_HIGH__MASK              0xffff0000
+#define NV50_3D_CLIPID_FILL_RECT_HORIZ_HIGH__SHIFT             16
+
+#define NV50_3D_CLIPID_FILL_RECT_VERT                          0x0000150c
+#define NV50_3D_CLIPID_FILL_RECT_VERT_LOW__MASK                        0x0000ffff
+#define NV50_3D_CLIPID_FILL_RECT_VERT_LOW__SHIFT               0
+#define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__MASK               0xffff0000
+#define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__SHIFT              16
+
+#define NV50_3D_VP_CLIP_DISTANCE_ENABLE                                0x00001510
+#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_0                      0x00000001
+#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_1                      0x00000002
+#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_2                      0x00000004
+#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_3                      0x00000008
+#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_4                      0x00000010
+#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_5                      0x00000020
+#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_6                      0x00000040
+#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_7                      0x00000080
+
+#define NV50_3D_SAMPLECNT_ENABLE                               0x00001514
+
+#define NV50_3D_POINT_SIZE                                     0x00001518
+
+#define NV50_3D_ZCULL_STATCTRS_ENABLE                          0x0000151c
+
+#define NV50_3D_POINT_SPRITE_ENABLE                            0x00001520
+
+#define NVA0_3D_UNK152C                                                0x0000152c
+#define NVA0_3D_UNK152C_UNK0                                   0x00000001
+#define NVA0_3D_UNK152C_UNK1                                   0x00000010
+#define NVA0_3D_UNK152C_UNK2                                   0x00000100
+#define NVA0_3D_UNK152C_UNK3__MASK                             0x000ff000
+#define NVA0_3D_UNK152C_UNK3__SHIFT                            12
+#define NVA0_3D_UNK152C_UNK3__MAX                              0x00000028
+
+#define NV50_3D_COUNTER_RESET                                  0x00001530
+#define NV50_3D_COUNTER_RESET_SAMPLECNT                                0x00000001
+#define NV50_3D_COUNTER_RESET_ZCULL_STATS                      0x00000002
+#define NVA0_3D_COUNTER_RESET_STRMOUT_VERTICES                 0x00000008
+#define NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK               0x00000010
+#define NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES             0x00000011
+#define NV50_3D_COUNTER_RESET_VFETCH_VERTICES                  0x00000012
+#define NV50_3D_COUNTER_RESET_VFETCH_PRIMITIVES                        0x00000013
+#define NV50_3D_COUNTER_RESET_VP_LAUNCHES                      0x00000015
+#define NV50_3D_COUNTER_RESET_GP_LAUNCHES                      0x0000001a
+#define NV50_3D_COUNTER_RESET_GP_PRIMITIVES_OUT                        0x0000001b
+#define NV50_3D_COUNTER_RESET_RAST_PRIMITIVES_PRECLIP          0x0000001c
+#define NV50_3D_COUNTER_RESET_RAST_PRIMITIVES_POSTCLIP         0x0000001d
+#define NV50_3D_COUNTER_RESET_FP_PIXELS                                0x0000001e
+
+#define NV50_3D_MULTISAMPLE_ENABLE                             0x00001534
+
+#define NV50_3D_ZETA_ENABLE                                    0x00001538
+
+#define NV50_3D_MULTISAMPLE_CTRL                               0x0000153c
+#define NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE             0x00000001
+#define NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE                  0x00000010
+
+#define NV50_3D_NOPERSPECTIVE_BITMAP(i0)                      (0x00001540 + 0x4*(i0))
+#define NV50_3D_NOPERSPECTIVE_BITMAP__ESIZE                    0x00000004
+#define NV50_3D_NOPERSPECTIVE_BITMAP__LEN                      0x00000004
+
+#define NV50_3D_COND_ADDRESS_HIGH                              0x00001550
+
+#define NV50_3D_COND_ADDRESS_LOW                               0x00001554
+
+#define NV50_3D_COND_MODE                                      0x00001558
+#define NV50_3D_COND_MODE_NEVER                                        0x00000000
+#define NV50_3D_COND_MODE_ALWAYS                               0x00000001
+#define NV50_3D_COND_MODE_RES_NON_ZERO                         0x00000002
+#define NV50_3D_COND_MODE_EQUAL                                        0x00000003
+#define NV50_3D_COND_MODE_NOT_EQUAL                            0x00000004
+
+#define NV50_3D_TSC_ADDRESS_HIGH                               0x0000155c
+
+#define NV50_3D_TSC_ADDRESS_LOW                                        0x00001560
+#define NV50_3D_TSC_ADDRESS_LOW__ALIGN                         0x00000020
+
+#define NV50_3D_TSC_LIMIT                                      0x00001564
+#define NV50_3D_TSC_LIMIT__MAX                                 0x00001fff
+
+#define NV50_3D_UNK1568                                                0x00001568
+
+#define NV50_3D_POLYGON_OFFSET_FACTOR                          0x0000156c
+
+#define NV50_3D_LINE_SMOOTH_ENABLE                             0x00001570
+
+#define NV50_3D_TIC_ADDRESS_HIGH                               0x00001574
+
+#define NV50_3D_TIC_ADDRESS_LOW                                        0x00001578
+
+#define NV50_3D_TIC_LIMIT                                      0x0000157c
+
+#define NV50_3D_PM_CONTROL(i0)                                (0x00001580 + 0x4*(i0))
+#define NV50_3D_PM_CONTROL__ESIZE                              0x00000004
+#define NV50_3D_PM_CONTROL__LEN                                        0x00000004
+#define NV50_3D_PM_CONTROL_UNK0                                        0x00000001
+#define NV50_3D_PM_CONTROL_UNK1__MASK                          0x00000070
+#define NV50_3D_PM_CONTROL_UNK1__SHIFT                         4
+#define NV50_3D_PM_CONTROL_UNK2__MASK                          0x00ffff00
+#define NV50_3D_PM_CONTROL_UNK2__SHIFT                         8
+#define NV50_3D_PM_CONTROL_UNK3__MASK                          0xff000000
+#define NV50_3D_PM_CONTROL_UNK3__SHIFT                         24
+
+#define NV50_3D_ZCULL_REGION                                   0x00001590
+
+#define NV50_3D_STENCIL_TWO_SIDE_ENABLE                                0x00001594
+
+#define NV50_3D_STENCIL_BACK_OP_FAIL                           0x00001598
+#define NV50_3D_STENCIL_BACK_OP_FAIL_ZERO                      0x00000000
+#define NV50_3D_STENCIL_BACK_OP_FAIL_INVERT                    0x0000150a
+#define NV50_3D_STENCIL_BACK_OP_FAIL_KEEP                      0x00001e00
+#define NV50_3D_STENCIL_BACK_OP_FAIL_REPLACE                   0x00001e01
+#define NV50_3D_STENCIL_BACK_OP_FAIL_INCR                      0x00001e02
+#define NV50_3D_STENCIL_BACK_OP_FAIL_DECR                      0x00001e03
+#define NV50_3D_STENCIL_BACK_OP_FAIL_INCR_WRAP                 0x00008507
+#define NV50_3D_STENCIL_BACK_OP_FAIL_DECR_WRAP                 0x00008508
+
+#define NV50_3D_STENCIL_BACK_OP_ZFAIL                          0x0000159c
+#define NV50_3D_STENCIL_BACK_OP_ZFAIL_ZERO                     0x00000000
+#define NV50_3D_STENCIL_BACK_OP_ZFAIL_INVERT                   0x0000150a
+#define NV50_3D_STENCIL_BACK_OP_ZFAIL_KEEP                     0x00001e00
+#define NV50_3D_STENCIL_BACK_OP_ZFAIL_REPLACE                  0x00001e01
+#define NV50_3D_STENCIL_BACK_OP_ZFAIL_INCR                     0x00001e02
+#define NV50_3D_STENCIL_BACK_OP_ZFAIL_DECR                     0x00001e03
+#define NV50_3D_STENCIL_BACK_OP_ZFAIL_INCR_WRAP                        0x00008507
+#define NV50_3D_STENCIL_BACK_OP_ZFAIL_DECR_WRAP                        0x00008508
+
+#define NV50_3D_STENCIL_BACK_OP_ZPASS                          0x000015a0
+#define NV50_3D_STENCIL_BACK_OP_ZPASS_ZERO                     0x00000000
+#define NV50_3D_STENCIL_BACK_OP_ZPASS_INVERT                   0x0000150a
+#define NV50_3D_STENCIL_BACK_OP_ZPASS_KEEP                     0x00001e00
+#define NV50_3D_STENCIL_BACK_OP_ZPASS_REPLACE                  0x00001e01
+#define NV50_3D_STENCIL_BACK_OP_ZPASS_INCR                     0x00001e02
+#define NV50_3D_STENCIL_BACK_OP_ZPASS_DECR                     0x00001e03
+#define NV50_3D_STENCIL_BACK_OP_ZPASS_INCR_WRAP                        0x00008507
+#define NV50_3D_STENCIL_BACK_OP_ZPASS_DECR_WRAP                        0x00008508
+
+#define NV50_3D_STENCIL_BACK_FUNC_FUNC                         0x000015a4
+#define NV50_3D_STENCIL_BACK_FUNC_FUNC_NEVER                   0x00000200
+#define NV50_3D_STENCIL_BACK_FUNC_FUNC_LESS                    0x00000201
+#define NV50_3D_STENCIL_BACK_FUNC_FUNC_EQUAL                   0x00000202
+#define NV50_3D_STENCIL_BACK_FUNC_FUNC_LEQUAL                  0x00000203
+#define NV50_3D_STENCIL_BACK_FUNC_FUNC_GREATER                 0x00000204
+#define NV50_3D_STENCIL_BACK_FUNC_FUNC_NOTEQUAL                        0x00000205
+#define NV50_3D_STENCIL_BACK_FUNC_FUNC_GEQUAL                  0x00000206
+#define NV50_3D_STENCIL_BACK_FUNC_FUNC_ALWAYS                  0x00000207
+
+#define NV50_3D_UNK15A8                                                0x000015a8
+#define NV50_3D_UNK15A8_UNK1__MASK                             0x00000007
+#define NV50_3D_UNK15A8_UNK1__SHIFT                            0
+#define NV50_3D_UNK15A8_UNK2__MASK                             0x00000070
+#define NV50_3D_UNK15A8_UNK2__SHIFT                            4
+
+#define NV50_3D_UNK15AC                                                0x000015ac
+
+#define NV50_3D_UNK15B0                                                0x000015b0
+#define NV50_3D_UNK15B0_0                                      0x00000001
+#define NV50_3D_UNK15B0_1                                      0x00000010
+#define NV50_3D_UNK15B0_2                                      0x00000100
+
+#define NV50_3D_CSAA_ENABLE                                    0x000015b4
+
+#define NV50_3D_FRAMEBUFFER_SRGB                               0x000015b8
+
+#define NV50_3D_POLYGON_OFFSET_UNITS                           0x000015bc
+
+#define NVA3_3D_UNK15C4                                                0x000015c4
+
+#define NVA3_3D_UNK15C8                                                0x000015c8
+
+#define NV50_3D_LAYER                                          0x000015cc
+#define NV50_3D_LAYER_IDX__MASK                                        0x0000ffff
+#define NV50_3D_LAYER_IDX__SHIFT                               0
+#define NV50_3D_LAYER_USE_GP                                   0x00010000
+
+#define NV50_3D_MULTISAMPLE_MODE                               0x000015d0
+#define NV50_3D_MULTISAMPLE_MODE_MS1                           0x00000000
+#define NV50_3D_MULTISAMPLE_MODE_MS2                           0x00000001
+#define NV50_3D_MULTISAMPLE_MODE_MS4                           0x00000002
+#define NV50_3D_MULTISAMPLE_MODE_MS8                           0x00000003
+#define NV50_3D_MULTISAMPLE_MODE_MS8_ALT                       0x00000004
+#define NV50_3D_MULTISAMPLE_MODE_MS2_ALT                       0x00000005
+#define NV50_3D_MULTISAMPLE_MODE_MS4_CS4                       0x00000008
+#define NV50_3D_MULTISAMPLE_MODE_MS4_CS12                      0x00000009
+#define NV50_3D_MULTISAMPLE_MODE_MS8_CS8                       0x0000000a
+
+#define NV50_3D_VERTEX_BEGIN_D3D                               0x000015d4
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE__MASK               0x0fffffff
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE__SHIFT              0
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_POINTS              0x00000001
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_LINES               0x00000002
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_LINE_STRIP          0x00000003
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_TRIANGLES           0x00000004
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_TRIANGLE_STRIP      0x00000005
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_LINES_ADJACENCY     0x0000000a
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_LINE_STRIP_ADJACENCY        0x0000000b
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_TRIANGLES_ADJACENCY 0x0000000c
+#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE_TRIANGLE_STRIP_ADJACENCY    0x0000000d
+#define NV50_3D_VERTEX_BEGIN_D3D_INSTANCE_NEXT                 0x10000000
+#define NV84_3D_VERTEX_BEGIN_D3D_PRIMITIVE_ID_CONT             0x20000000
+#define NVA0_3D_VERTEX_BEGIN_D3D_INSTANCE_CONT                 0x40000000
+
+#define NV50_3D_VERTEX_END_D3D                                 0x000015d8
+#define NV50_3D_VERTEX_END_D3D_UNK0                            0x00000001
+#define NVA0_3D_VERTEX_END_D3D_UNK1                            0x00000002
+
+#define NV50_3D_VERTEX_BEGIN_GL                                        0x000015dc
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE__MASK                        0x0fffffff
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE__SHIFT               0
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS               0x00000000
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_LINES                        0x00000001
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_LINE_LOOP            0x00000002
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_LINE_STRIP           0x00000003
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES            0x00000004
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLE_STRIP       0x00000005
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLE_FAN         0x00000006
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_QUADS                        0x00000007
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_QUAD_STRIP           0x00000008
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_POLYGON              0x00000009
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_LINES_ADJACENCY      0x0000000a
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_LINE_STRIP_ADJACENCY 0x0000000b
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES_ADJACENCY  0x0000000c
+#define NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLE_STRIP_ADJACENCY     0x0000000d
+#define NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT                  0x10000000
+#define NV84_3D_VERTEX_BEGIN_GL_PRIMITIVE_ID_CONT              0x20000000
+#define NVA0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT                  0x40000000
+
+#define NV50_3D_VERTEX_END_GL                                  0x000015e0
+#define NV50_3D_VERTEX_END_GL_UNK0                             0x00000001
+#define NVA0_3D_VERTEX_END_GL_UNK1                             0x00000002
+
+#define NV50_3D_EDGEFLAG_ENABLE                                        0x000015e4
+
+#define NV50_3D_VB_ELEMENT_U32                                 0x000015e8
+
+#define NV50_3D_VB_ELEMENT_U16_SETUP                           0x000015ec
+#define NV50_3D_VB_ELEMENT_U16_SETUP_OFFSET__MASK              0xc0000000
+#define NV50_3D_VB_ELEMENT_U16_SETUP_OFFSET__SHIFT             30
+#define NV50_3D_VB_ELEMENT_U16_SETUP_COUNT__MASK               0x3fffffff
+#define NV50_3D_VB_ELEMENT_U16_SETUP_COUNT__SHIFT              0
+
+#define NV50_3D_VB_ELEMENT_U16                                 0x000015f0
+#define NV50_3D_VB_ELEMENT_U16_I0__MASK                                0x0000ffff
+#define NV50_3D_VB_ELEMENT_U16_I0__SHIFT                       0
+#define NV50_3D_VB_ELEMENT_U16_I1__MASK                                0xffff0000
+#define NV50_3D_VB_ELEMENT_U16_I1__SHIFT                       16
+
+#define NV50_3D_VERTEX_BASE_HIGH                               0x000015f4
+
+#define NV50_3D_VERTEX_BASE_LOW                                        0x000015f8
+
+#define NV50_3D_VERTEX_DATA                                    0x00001640
+
+#define NV50_3D_PRIM_RESTART_ENABLE                            0x00001644
+
+#define NV50_3D_PRIM_RESTART_INDEX                             0x00001648
+
+#define NV50_3D_VP_GP_BUILTIN_ATTR_EN                          0x0000164c
+#define NV50_3D_VP_GP_BUILTIN_ATTR_EN_VERTEX_ID                        0x00000001
+#define NV50_3D_VP_GP_BUILTIN_ATTR_EN_INSTANCE_ID              0x00000010
+#define NV50_3D_VP_GP_BUILTIN_ATTR_EN_PRIMITIVE_ID             0x00000100
+#define NV50_3D_VP_GP_BUILTIN_ATTR_EN_UNK12                    0x00001000
+
+#define NV50_3D_VP_ATTR_EN(i0)                                (0x00001650 + 0x4*(i0))
+#define NV50_3D_VP_ATTR_EN__ESIZE                              0x00000004
+#define NV50_3D_VP_ATTR_EN__LEN                                        0x00000002
+#define NV50_3D_VP_ATTR_EN_7__MASK                             0xf0000000
+#define NV50_3D_VP_ATTR_EN_7__SHIFT                            28
+#define NV50_3D_VP_ATTR_EN_7_X                                 0x10000000
+#define NV50_3D_VP_ATTR_EN_7_Y                                 0x20000000
+#define NV50_3D_VP_ATTR_EN_7_Z                                 0x40000000
+#define NV50_3D_VP_ATTR_EN_7_W                                 0x80000000
+#define NV50_3D_VP_ATTR_EN_6__MASK                             0x0f000000
+#define NV50_3D_VP_ATTR_EN_6__SHIFT                            24
+#define NV50_3D_VP_ATTR_EN_6_X                                 0x01000000
+#define NV50_3D_VP_ATTR_EN_6_Y                                 0x02000000
+#define NV50_3D_VP_ATTR_EN_6_Z                                 0x04000000
+#define NV50_3D_VP_ATTR_EN_6_W                                 0x08000000
+#define NV50_3D_VP_ATTR_EN_5__MASK                             0x00f00000
+#define NV50_3D_VP_ATTR_EN_5__SHIFT                            20
+#define NV50_3D_VP_ATTR_EN_5_X                                 0x00100000
+#define NV50_3D_VP_ATTR_EN_5_Y                                 0x00200000
+#define NV50_3D_VP_ATTR_EN_5_Z                                 0x00400000
+#define NV50_3D_VP_ATTR_EN_5_W                                 0x00800000
+#define NV50_3D_VP_ATTR_EN_4__MASK                             0x000f0000
+#define NV50_3D_VP_ATTR_EN_4__SHIFT                            16
+#define NV50_3D_VP_ATTR_EN_4_X                                 0x00010000
+#define NV50_3D_VP_ATTR_EN_4_Y                                 0x00020000
+#define NV50_3D_VP_ATTR_EN_4_Z                                 0x00040000
+#define NV50_3D_VP_ATTR_EN_4_W                                 0x00080000
+#define NV50_3D_VP_ATTR_EN_3__MASK                             0x0000f000
+#define NV50_3D_VP_ATTR_EN_3__SHIFT                            12
+#define NV50_3D_VP_ATTR_EN_3_X                                 0x00001000
+#define NV50_3D_VP_ATTR_EN_3_Y                                 0x00002000
+#define NV50_3D_VP_ATTR_EN_3_Z                                 0x00004000
+#define NV50_3D_VP_ATTR_EN_3_W                                 0x00008000
+#define NV50_3D_VP_ATTR_EN_2__MASK                             0x00000f00
+#define NV50_3D_VP_ATTR_EN_2__SHIFT                            8
+#define NV50_3D_VP_ATTR_EN_2_X                                 0x00000100
+#define NV50_3D_VP_ATTR_EN_2_Y                                 0x00000200
+#define NV50_3D_VP_ATTR_EN_2_Z                                 0x00000400
+#define NV50_3D_VP_ATTR_EN_2_W                                 0x00000800
+#define NV50_3D_VP_ATTR_EN_1__MASK                             0x000000f0
+#define NV50_3D_VP_ATTR_EN_1__SHIFT                            4
+#define NV50_3D_VP_ATTR_EN_1_X                                 0x00000010
+#define NV50_3D_VP_ATTR_EN_1_Y                                 0x00000020
+#define NV50_3D_VP_ATTR_EN_1_Z                                 0x00000040
+#define NV50_3D_VP_ATTR_EN_1_W                                 0x00000080
+#define NV50_3D_VP_ATTR_EN_0__MASK                             0x0000000f
+#define NV50_3D_VP_ATTR_EN_0__SHIFT                            0
+#define NV50_3D_VP_ATTR_EN_0_X                                 0x00000001
+#define NV50_3D_VP_ATTR_EN_0_Y                                 0x00000002
+#define NV50_3D_VP_ATTR_EN_0_Z                                 0x00000004
+#define NV50_3D_VP_ATTR_EN_0_W                                 0x00000008
+
+#define NV50_3D_POINT_SMOOTH_ENABLE                            0x00001658
+
+#define NV50_3D_POINT_RASTER_RULES                             0x0000165c
+#define NV50_3D_POINT_RASTER_RULES_OGL                         0x00000000
+#define NV50_3D_POINT_RASTER_RULES_D3D                         0x00000001
+
+#define NV50_3D_POINT_SPRITE_CTRL                              0x00001660
+#define NV50_3D_POINT_SPRITE_CTRL_COORD_ORIGIN__MASK           0x00000010
+#define NV50_3D_POINT_SPRITE_CTRL_COORD_ORIGIN__SHIFT          4
+#define NV50_3D_POINT_SPRITE_CTRL_COORD_ORIGIN_LOWER_LEFT      0x00000000
+#define NV50_3D_POINT_SPRITE_CTRL_COORD_ORIGIN_UPPER_LEFT      0x00000010
+
+#define NVA0_3D_TEX_MISC                                       0x00001664
+#define NVA0_3D_TEX_MISC_UNK1                                  0x00000002
+#define NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP                     0x00000004
+
+#define NV50_3D_LINE_SMOOTH_BLUR                               0x00001668
+#define NV50_3D_LINE_SMOOTH_BLUR_LOW                           0x00000000
+#define NV50_3D_LINE_SMOOTH_BLUR_MEDIUM                                0x00000001
+#define NV50_3D_LINE_SMOOTH_BLUR_HIGH                          0x00000002
+
+#define NV50_3D_LINE_STIPPLE_ENABLE                            0x0000166c
+
+#define NV50_3D_COVERAGE_LUT(i0)                              (0x00001670 + 0x4*(i0))
+#define NV50_3D_COVERAGE_LUT__ESIZE                            0x00000004
+#define NV50_3D_COVERAGE_LUT__LEN                              0x00000004
+#define NV50_3D_COVERAGE_LUT_0__MASK                           0x000000ff
+#define NV50_3D_COVERAGE_LUT_0__SHIFT                          0
+#define NV50_3D_COVERAGE_LUT_1__MASK                           0x0000ff00
+#define NV50_3D_COVERAGE_LUT_1__SHIFT                          8
+#define NV50_3D_COVERAGE_LUT_2__MASK                           0x00ff0000
+#define NV50_3D_COVERAGE_LUT_2__SHIFT                          16
+#define NV50_3D_COVERAGE_LUT_3__MASK                           0xff000000
+#define NV50_3D_COVERAGE_LUT_3__SHIFT                          24
+
+#define NV50_3D_LINE_STIPPLE                                   0x00001680
+#define NV50_3D_LINE_STIPPLE_FACTOR_M1__MASK                   0x000000ff
+#define NV50_3D_LINE_STIPPLE_FACTOR_M1__SHIFT                  0
+#define NV50_3D_LINE_STIPPLE_PATTERN__MASK                     0x00ffff00
+#define NV50_3D_LINE_STIPPLE_PATTERN__SHIFT                    8
+
+#define NV50_3D_PROVOKING_VERTEX_LAST                          0x00001684
+
+#define NV50_3D_VERTEX_TWO_SIDE_ENABLE                         0x00001688
+
+#define NV50_3D_POLYGON_STIPPLE_ENABLE                         0x0000168c
+
+#define NV50_3D_UNK1690                                                0x00001690
+#define NV50_3D_UNK1690_ALWAYS_DERIV                           0x00000001
+#define NV50_3D_UNK1690_UNK16                                  0x00010000
+
+#define NV50_3D_SET_PROGRAM_CB                                 0x00001694
+#define NV50_3D_SET_PROGRAM_CB_PROGRAM__MASK                   0x000000f0
+#define NV50_3D_SET_PROGRAM_CB_PROGRAM__SHIFT                  4
+#define NV50_3D_SET_PROGRAM_CB_PROGRAM_VERTEX                  0x00000000
+#define NV50_3D_SET_PROGRAM_CB_PROGRAM_GEOMETRY                        0x00000020
+#define NV50_3D_SET_PROGRAM_CB_PROGRAM_FRAGMENT                        0x00000030
+#define NV50_3D_SET_PROGRAM_CB_INDEX__MASK                     0x00000f00
+#define NV50_3D_SET_PROGRAM_CB_INDEX__SHIFT                    8
+#define NV50_3D_SET_PROGRAM_CB_BUFFER__MASK                    0x0007f000
+#define NV50_3D_SET_PROGRAM_CB_BUFFER__SHIFT                   12
+#define NV50_3D_SET_PROGRAM_CB_VALID                           0x00000001
+
+#define NV50_3D_UNK1698                                                0x00001698
+#define NV50_3D_UNK1698_0                                      0x00000001
+#define NV50_3D_UNK1698_1                                      0x00000010
+#define NV50_3D_UNK1698_2                                      0x00000100
+
+#define NVA3_3D_SAMPLE_SHADING                                 0x0000169c
+#define NVA3_3D_SAMPLE_SHADING_MIN_SAMPLES__MASK               0x0000000f
+#define NVA3_3D_SAMPLE_SHADING_MIN_SAMPLES__SHIFT              0
+#define NVA3_3D_SAMPLE_SHADING_ENABLE                          0x00000010
+
+#define NVA3_3D_UNK16A0                                                0x000016a0
+
+#define NV50_3D_VP_RESULT_MAP_SIZE                             0x000016ac
+
+#define NV50_3D_VP_REG_ALLOC_TEMP                              0x000016b0
+
+#define NVA0_3D_UNK16B4                                                0x000016b4
+#define NVA0_3D_UNK16B4_UNK0                                   0x00000001
+#define NVA3_3D_UNK16B4_UNK1                                   0x00000002
+
+#define NV50_3D_VP_REG_ALLOC_RESULT                            0x000016b8
+
+#define NV50_3D_VP_RESULT_MAP(i0)                             (0x000016bc + 0x4*(i0))
+#define NV50_3D_VP_RESULT_MAP__ESIZE                           0x00000004
+#define NV50_3D_VP_RESULT_MAP__LEN                             0x00000011
+#define NV50_3D_VP_RESULT_MAP_0__MASK                          0x000000ff
+#define NV50_3D_VP_RESULT_MAP_0__SHIFT                         0
+#define NV50_3D_VP_RESULT_MAP_1__MASK                          0x0000ff00
+#define NV50_3D_VP_RESULT_MAP_1__SHIFT                         8
+#define NV50_3D_VP_RESULT_MAP_2__MASK                          0x00ff0000
+#define NV50_3D_VP_RESULT_MAP_2__SHIFT                         16
+#define NV50_3D_VP_RESULT_MAP_3__MASK                          0xff000000
+#define NV50_3D_VP_RESULT_MAP_3__SHIFT                         24
+
+#define NV50_3D_POLYGON_STIPPLE_PATTERN(i0)                   (0x00001700 + 0x4*(i0))
+#define NV50_3D_POLYGON_STIPPLE_PATTERN__ESIZE                 0x00000004
+#define NV50_3D_POLYGON_STIPPLE_PATTERN__LEN                   0x00000020
+
+#define NVA0_3D_STRMOUT_OFFSET(i0)                            (0x00001780 + 0x4*(i0))
+#define NVA0_3D_STRMOUT_OFFSET__ESIZE                          0x00000004
+#define NVA0_3D_STRMOUT_OFFSET__LEN                            0x00000004
+
+#define NV50_3D_GP_ENABLE                                      0x00001798
+
+#define NV50_3D_GP_REG_ALLOC_TEMP                              0x000017a0
+
+#define NV50_3D_GP_REG_ALLOC_RESULT                            0x000017a8
+
+#define NV50_3D_GP_RESULT_MAP_SIZE                             0x000017ac
+
+#define NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE                       0x000017b0
+#define NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE_POINTS                        0x00000001
+#define NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE_LINE_STRIP            0x00000002
+#define NV50_3D_GP_OUTPUT_PRIMITIVE_TYPE_TRIANGLE_STRIP                0x00000003
+
+#define NV50_3D_RASTERIZE_ENABLE                               0x000017b4
+
+#define NV50_3D_STRMOUT_ENABLE                                 0x000017b8
+
+#define NV50_3D_GP_RESULT_MAP(i0)                             (0x000017fc + 0x4*(i0))
+#define NV50_3D_GP_RESULT_MAP__ESIZE                           0x00000004
+#define NV50_3D_GP_RESULT_MAP__LEN                             0x00000021
+#define NV50_3D_GP_RESULT_MAP_0__MASK                          0x000000ff
+#define NV50_3D_GP_RESULT_MAP_0__SHIFT                         0
+#define NV50_3D_GP_RESULT_MAP_1__MASK                          0x0000ff00
+#define NV50_3D_GP_RESULT_MAP_1__SHIFT                         8
+#define NV50_3D_GP_RESULT_MAP_2__MASK                          0x00ff0000
+#define NV50_3D_GP_RESULT_MAP_2__SHIFT                         16
+#define NV50_3D_GP_RESULT_MAP_3__MASK                          0xff000000
+#define NV50_3D_GP_RESULT_MAP_3__SHIFT                         24
+
+#define NV50_3D_UNK187C                                                0x0000187c
+
+#define NVA3_3D_VERTEX_ARRAY_PER_INSTANCE_ALT(i0)             (0x00001880 + 0x4*(i0))
+#define NVA3_3D_VERTEX_ARRAY_PER_INSTANCE_ALT__ESIZE           0x00000004
+#define NVA3_3D_VERTEX_ARRAY_PER_INSTANCE_ALT__LEN             0x00000020
+
+#define NV50_3D_GP_VIEWPORT_ID_ENABLE                          0x00001900
+
+#define NV50_3D_MAP_SEMANTIC_0                                 0x00001904
+#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__MASK                   0x000000ff
+#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__SHIFT                  0
+#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__MASK                   0x0000ff00
+#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__SHIFT                  8
+#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__MASK                   0x00ff0000
+#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__SHIFT                  16
+#define NV50_3D_MAP_SEMANTIC_0_CLMP_EN                         0xff000000
+
+#define NV50_3D_MAP_SEMANTIC_1                                 0x00001908
+#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__MASK                        0x000000ff
+#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__SHIFT               0
+#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__MASK                  0x00000f00
+#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__SHIFT                 8
+
+#define NV50_3D_MAP_SEMANTIC_2                                 0x0000190c
+#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__MASK                  0x000000ff
+#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__SHIFT                 0
+
+#define NV50_3D_MAP_SEMANTIC_3                                 0x00001910
+#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK                   0x00000001
+#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__SHIFT                  0
+#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__MASK                   0x00000ff0
+#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__SHIFT                  4
+
+#define NV50_3D_MAP_SEMANTIC_4                                 0x00001914
+#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__MASK                   0x000000ff
+#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__SHIFT                  0
+
+#define NV50_3D_CULL_FACE_ENABLE                               0x00001918
+
+#define NV50_3D_FRONT_FACE                                     0x0000191c
+#define NV50_3D_FRONT_FACE_CW                                  0x00000900
+#define NV50_3D_FRONT_FACE_CCW                                 0x00000901
+
+#define NV50_3D_CULL_FACE                                      0x00001920
+#define NV50_3D_CULL_FACE_FRONT                                        0x00000404
+#define NV50_3D_CULL_FACE_BACK                                 0x00000405
+#define NV50_3D_CULL_FACE_FRONT_AND_BACK                       0x00000408
+
+#define NV50_3D_UNK1924                                                0x00001924
+
+#define NVA3_3D_FP_MULTISAMPLE                                 0x00001928
+#define NVA3_3D_FP_MULTISAMPLE_EXPORT_SAMPLE_MASK              0x00000001
+#define NVA3_3D_FP_MULTISAMPLE_FORCE_PER_SAMPLE                        0x00000002
+
+#define NV50_3D_VIEWPORT_TRANSFORM_EN                          0x0000192c
+
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL                          0x0000193c
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK0                     0x00000001
+#define NVA0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1                     0x00000002
+#define NVA0_3D_VIEW_VOLUME_CLIP_CTRL_UNK2                     0x00000004
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR         0x00000008
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR          0x00000010
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7                     0x00000080
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK10                    0x00000400
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK11                    0x00000800
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12__MASK              0x00003000
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12__SHIFT             12
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK0               0x00000000
+#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1               0x00001000
+#define NV84_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2               0x00002000
+
+#define NV50_3D_UNK1940                                                0x00001940
+#define NV50_3D_UNK1940_0                                      0x00000001
+#define NV50_3D_UNK1940_1                                      0x00000010
+#define NV50_3D_UNK1940_2                                      0x00000100
+#define NV50_3D_UNK1940_3                                      0x00001000
+#define NV50_3D_UNK1940_4                                      0x00010000
+#define NV50_3D_UNK1940_5                                      0x00100000
+#define NV50_3D_UNK1940_6                                      0x01000000
+#define NV50_3D_UNK1940_7                                      0x10000000
+
+#define NVA3_3D_UNK1944                                                0x00001944
+
+#define NV50_3D_CLIP_RECTS_EN                                  0x0000194c
+
+#define NV50_3D_CLIP_RECTS_MODE                                        0x00001950
+#define NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY                     0x00000000
+#define NV50_3D_CLIP_RECTS_MODE_OUTSIDE_ALL                    0x00000001
+#define NV50_3D_CLIP_RECTS_MODE_NEVER                          0x00000002
+
+#define NV50_3D_ZCULL_VALIDATE                                 0x00001954
+#define NV50_3D_ZCULL_VALIDATE_CLEAR_UNK0                      0x00000001
+#define NV50_3D_ZCULL_VALIDATE_CLEAR_UNK1                      0x00000010
+
+#define NV50_3D_ZCULL_INVALIDATE                               0x00001958
+
+#define NVA3_3D_UNK1960                                                0x00001960
+#define NVA3_3D_UNK1960_0                                      0x00000001
+#define NVA3_3D_UNK1960_1                                      0x00000010
+
+#define NV50_3D_UNK1968                                                0x00001968
+#define NV50_3D_UNK1968_0                                      0x00000001
+#define NV50_3D_UNK1968_1                                      0x00000010
+
+#define NV50_3D_FP_CTRL_UNK196C                                        0x0000196c
+#define NV50_3D_FP_CTRL_UNK196C_0                              0x00000001
+#define NV50_3D_FP_CTRL_UNK196C_1                              0x00000010
+
+#define NV50_3D_UNK1978                                                0x00001978
+
+#define NV50_3D_CLIPID_ENABLE                                  0x0000197c
+
+#define NV50_3D_CLIPID_WIDTH                                   0x00001980
+#define NV50_3D_CLIPID_WIDTH__MAX                              0x00002000
+#define NV50_3D_CLIPID_WIDTH__ALIGN                            0x00000040
+
+#define NV50_3D_CLIPID_ID                                      0x00001984
+
+#define NV50_3D_FP_INTERPOLANT_CTRL                            0x00001988
+#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK__MASK                        0xff000000
+#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK__SHIFT               24
+#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK_X                    0x01000000
+#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK_Y                    0x02000000
+#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK_Z                    0x04000000
+#define NV50_3D_FP_INTERPOLANT_CTRL_UMASK_W                    0x08000000
+#define NV50_3D_FP_INTERPOLANT_CTRL_COUNT_NONFLAT__MASK                0x00ff0000
+#define NV50_3D_FP_INTERPOLANT_CTRL_COUNT_NONFLAT__SHIFT       16
+#define NV50_3D_FP_INTERPOLANT_CTRL_OFFSET__MASK               0x0000ff00
+#define NV50_3D_FP_INTERPOLANT_CTRL_OFFSET__SHIFT              8
+#define NV50_3D_FP_INTERPOLANT_CTRL_COUNT__MASK                        0x000000ff
+#define NV50_3D_FP_INTERPOLANT_CTRL_COUNT__SHIFT               0
+
+#define NV50_3D_FP_REG_ALLOC_TEMP                              0x0000198c
+
+#define NV50_3D_REG_MODE                                       0x000019a0
+#define NV50_3D_REG_MODE_PACKED                                        0x00000001
+#define NV50_3D_REG_MODE_STRIPED                               0x00000002
+
+#define NV50_3D_FP_CONTROL                                     0x000019a8
+#define NV50_3D_FP_CONTROL_MULTIPLE_RESULTS                    0x00000001
+#define NV50_3D_FP_CONTROL_EXPORTS_Z                           0x00000100
+#define NV50_3D_FP_CONTROL_USES_KIL                            0x00100000
+
+#define NV50_3D_DEPTH_BOUNDS_EN                                        0x000019bc
+
+#define NV50_3D_UNK19C0                                                0x000019c0
+
+#define NV50_3D_LOGIC_OP_ENABLE                                        0x000019c4
+
+#define NV50_3D_LOGIC_OP                                       0x000019c8
+#define NV50_3D_LOGIC_OP_CLEAR                                 0x00001500
+#define NV50_3D_LOGIC_OP_AND                                   0x00001501
+#define NV50_3D_LOGIC_OP_AND_REVERSE                           0x00001502
+#define NV50_3D_LOGIC_OP_COPY                                  0x00001503
+#define NV50_3D_LOGIC_OP_AND_INVERTED                          0x00001504
+#define NV50_3D_LOGIC_OP_NOOP                                  0x00001505
+#define NV50_3D_LOGIC_OP_XOR                                   0x00001506
+#define NV50_3D_LOGIC_OP_OR                                    0x00001507
+#define NV50_3D_LOGIC_OP_NOR                                   0x00001508
+#define NV50_3D_LOGIC_OP_EQUIV                                 0x00001509
+#define NV50_3D_LOGIC_OP_INVERT                                        0x0000150a
+#define NV50_3D_LOGIC_OP_OR_REVERSE                            0x0000150b
+#define NV50_3D_LOGIC_OP_COPY_INVERTED                         0x0000150c
+#define NV50_3D_LOGIC_OP_OR_INVERTED                           0x0000150d
+#define NV50_3D_LOGIC_OP_NAND                                  0x0000150e
+#define NV50_3D_LOGIC_OP_SET                                   0x0000150f
+
+#define NV50_3D_ZETA_COMP_ENABLE                               0x000019cc
+
+#define NV50_3D_CLEAR_BUFFERS                                  0x000019d0
+#define NV50_3D_CLEAR_BUFFERS_Z                                        0x00000001
+#define NV50_3D_CLEAR_BUFFERS_S                                        0x00000002
+#define NV50_3D_CLEAR_BUFFERS_R                                        0x00000004
+#define NV50_3D_CLEAR_BUFFERS_G                                        0x00000008
+#define NV50_3D_CLEAR_BUFFERS_B                                        0x00000010
+#define NV50_3D_CLEAR_BUFFERS_A                                        0x00000020
+#define NV50_3D_CLEAR_BUFFERS_RT__MASK                         0x000003c0
+#define NV50_3D_CLEAR_BUFFERS_RT__SHIFT                                6
+#define NV50_3D_CLEAR_BUFFERS_LAYER__MASK                      0x001ffc00
+#define NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT                     10
+
+#define NV50_3D_CLIPID_FILL                                    0x000019d4
+
+#define NV50_3D_UNK19D8(i0)                                   (0x000019d8 + 0x4*(i0))
+#define NV50_3D_UNK19D8__ESIZE                                 0x00000004
+#define NV50_3D_UNK19D8__LEN                                   0x00000002
+
+#define NV50_3D_RT_COMP_ENABLE(i0)                            (0x000019e0 + 0x4*(i0))
+#define NV50_3D_RT_COMP_ENABLE__ESIZE                          0x00000004
+#define NV50_3D_RT_COMP_ENABLE__LEN                            0x00000008
+
+#define NV50_3D_COLOR_MASK(i0)                                (0x00001a00 + 0x4*(i0))
+#define NV50_3D_COLOR_MASK__ESIZE                              0x00000004
+#define NV50_3D_COLOR_MASK__LEN                                        0x00000008
+#define NV50_3D_COLOR_MASK_R                                   0x0000000f
+#define NV50_3D_COLOR_MASK_G                                   0x000000f0
+#define NV50_3D_COLOR_MASK_B                                   0x00000f00
+#define NV50_3D_COLOR_MASK_A                                   0x0000f000
+
+#define NV50_3D_UNK1A20                                                0x00001a20
+
+#define NV50_3D_DELAY                                          0x00001a24
+
+#define NV50_3D_UNK1A28                                                0x00001a28
+#define NV50_3D_UNK1A28_0__MASK                                        0x000000ff
+#define NV50_3D_UNK1A28_0__SHIFT                               0
+#define NV50_3D_UNK1A28_1                                      0x00000100
+
+#define NV50_3D_UNK1A2C                                                0x00001a2c
+
+#define NV50_3D_UNK1A30                                                0x00001a30
+
+#define NV50_3D_UNK1A34                                                0x00001a34
+
+#define NV50_3D_UNK1A38                                                0x00001a38
+
+#define NV50_3D_UNK1A3C                                                0x00001a3c
+
+#define NV50_3D_UNK1A40(i0)                                   (0x00001a40 + 0x4*(i0))
+#define NV50_3D_UNK1A40__ESIZE                                 0x00000004
+#define NV50_3D_UNK1A40__LEN                                   0x00000010
+#define NV50_3D_UNK1A40_0__MASK                                        0x00000007
+#define NV50_3D_UNK1A40_0__SHIFT                               0
+#define NV50_3D_UNK1A40_1__MASK                                        0x00000070
+#define NV50_3D_UNK1A40_1__SHIFT                               4
+#define NV50_3D_UNK1A40_2__MASK                                        0x00000700
+#define NV50_3D_UNK1A40_2__SHIFT                               8
+#define NV50_3D_UNK1A40_3__MASK                                        0x00007000
+#define NV50_3D_UNK1A40_3__SHIFT                               12
+#define NV50_3D_UNK1A40_4__MASK                                        0x00070000
+#define NV50_3D_UNK1A40_4__SHIFT                               16
+#define NV50_3D_UNK1A40_5__MASK                                        0x00700000
+#define NV50_3D_UNK1A40_5__SHIFT                               20
+#define NV50_3D_UNK1A40_6__MASK                                        0x07000000
+#define NV50_3D_UNK1A40_6__SHIFT                               24
+#define NV50_3D_UNK1A40_7__MASK                                        0x70000000
+#define NV50_3D_UNK1A40_7__SHIFT                               28
+
+#define NV50_3D_STRMOUT_ADDRESS_HIGH(i0)                      (0x00001a80 + 0x10*(i0))
+#define NV50_3D_STRMOUT_ADDRESS_HIGH__ESIZE                    0x00000010
+#define NV50_3D_STRMOUT_ADDRESS_HIGH__LEN                      0x00000004
+
+#define NV50_3D_STRMOUT_ADDRESS_LOW(i0)                               (0x00001a84 + 0x10*(i0))
+#define NV50_3D_STRMOUT_ADDRESS_LOW__ESIZE                     0x00000010
+#define NV50_3D_STRMOUT_ADDRESS_LOW__LEN                       0x00000004
+
+#define NV50_3D_STRMOUT_NUM_ATTRIBS(i0)                               (0x00001a88 + 0x10*(i0))
+#define NV50_3D_STRMOUT_NUM_ATTRIBS__ESIZE                     0x00000010
+#define NV50_3D_STRMOUT_NUM_ATTRIBS__LEN                       0x00000004
+#define NV50_3D_STRMOUT_NUM_ATTRIBS__MAX                       0x00000040
+
+#define NVA0_3D_STRMOUT_OFFSET_LIMIT(i0)                      (0x00001a8c + 0x10*(i0))
+#define NVA0_3D_STRMOUT_OFFSET_LIMIT__ESIZE                    0x00000010
+#define NVA0_3D_STRMOUT_OFFSET_LIMIT__LEN                      0x00000004
+
+#define NV50_3D_VERTEX_ARRAY_ATTRIB(i0)                               (0x00001ac0 + 0x4*(i0))
+#define NV50_3D_VERTEX_ARRAY_ATTRIB__ESIZE                     0x00000004
+#define NV50_3D_VERTEX_ARRAY_ATTRIB__LEN                       0x00000010
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_BUFFER__MASK               0x0000000f
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_BUFFER__SHIFT              0
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_CONST                      0x00000010
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_OFFSET__MASK               0x0007ffe0
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_OFFSET__SHIFT              5
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT__MASK               0x01f80000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT__SHIFT              19
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32_32         0x00080000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32            0x00100000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16_16         0x00180000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32_32               0x00200000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16            0x00280000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8_8             0x00500000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_16_16               0x00780000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32                  0x00900000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8               0x00980000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_8_8                 0x00c00000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_16                  0x00d80000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_8                   0x00e80000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_2_10_10_10          0x01800000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE__MASK                 0x7e000000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE__SHIFT                        25
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT                 0x7e000000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_UNORM                 0x24000000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_SNORM                 0x12000000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_USCALED               0x5a000000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED               0x6c000000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_UINT                  0x48000000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_SINT                  0x36000000
+#define NV50_3D_VERTEX_ARRAY_ATTRIB_BGRA                       0x80000000
+
+#define NV50_3D_QUERY_ADDRESS_HIGH                             0x00001b00
+
+#define NV50_3D_QUERY_ADDRESS_LOW                              0x00001b04
+
+#define NV50_3D_QUERY_SEQUENCE                                 0x00001b08
+
+#define NV50_3D_QUERY_GET                                      0x00001b0c
+#define NV50_3D_QUERY_GET_MODE__MASK                           0x00000003
+#define NV50_3D_QUERY_GET_MODE__SHIFT                          0
+#define NV50_3D_QUERY_GET_MODE_WRITE_UNK0                      0x00000000
+#define NV50_3D_QUERY_GET_MODE_SYNC                            0x00000001
+#define NV50_3D_QUERY_GET_MODE_WRITE_UNK2                      0x00000002
+#define NV50_3D_QUERY_GET_UNK4                                 0x00000010
+#define NVA0_3D_QUERY_GET_INDEX__MASK                          0x000000e0
+#define NVA0_3D_QUERY_GET_INDEX__SHIFT                         5
+#define NV50_3D_QUERY_GET_UNK8                                 0x00000100
+#define NV50_3D_QUERY_GET_UNIT__MASK                           0x0000f000
+#define NV50_3D_QUERY_GET_UNIT__SHIFT                          12
+#define NV50_3D_QUERY_GET_UNIT_UNK00                           0x00000000
+#define NV50_3D_QUERY_GET_UNIT_VFETCH                          0x00001000
+#define NV50_3D_QUERY_GET_UNIT_VP                              0x00002000
+#define NV50_3D_QUERY_GET_UNIT_RAST                            0x00004000
+#define NV50_3D_QUERY_GET_UNIT_STRMOUT                         0x00005000
+#define NV50_3D_QUERY_GET_UNIT_GP                              0x00006000
+#define NV50_3D_QUERY_GET_UNIT_ZCULL                           0x00007000
+#define NV50_3D_QUERY_GET_UNIT_TPROP                           0x0000a000
+#define NV50_3D_QUERY_GET_UNIT_UNK0C                           0x0000c000
+#define NV50_3D_QUERY_GET_UNIT_CROP                            0x0000f000
+#define NV50_3D_QUERY_GET_SYNC_COND__MASK                      0x00010000
+#define NV50_3D_QUERY_GET_SYNC_COND__SHIFT                     16
+#define NV50_3D_QUERY_GET_SYNC_COND_NEQUAL                     0x00000000
+#define NV50_3D_QUERY_GET_SYNC_COND_GREATER                    0x00010000
+#define NV50_3D_QUERY_GET_INTR                                 0x00100000
+#define NV50_3D_QUERY_GET_TYPE__MASK                           0x00800000
+#define NV50_3D_QUERY_GET_TYPE__SHIFT                          23
+#define NV50_3D_QUERY_GET_TYPE_QUERY                           0x00000000
+#define NV50_3D_QUERY_GET_TYPE_COUNTER                         0x00800000
+#define NV50_3D_QUERY_GET_QUERY_SELECT__MASK                   0x0f000000
+#define NV50_3D_QUERY_GET_QUERY_SELECT__SHIFT                  24
+#define NV50_3D_QUERY_GET_QUERY_SELECT_ZERO                    0x00000000
+#define NV50_3D_QUERY_GET_QUERY_SELECT_SAMPLECNT               0x01000000
+#define NV50_3D_QUERY_GET_QUERY_SELECT_STRMOUT_NO_OVERFLOW     0x02000000
+#define NVA0_3D_QUERY_GET_QUERY_SELECT_STRMOUT_DROPPED_PRIMITIVES      0x03000000
+#define NVA0_3D_QUERY_GET_QUERY_SELECT_STRMOUT_VERTICES                0x04000000
+#define NV50_3D_QUERY_GET_QUERY_SELECT_ZCULL_STAT_UNK0         0x05000000
+#define NV50_3D_QUERY_GET_QUERY_SELECT_ZCULL_STAT_UNK1         0x06000000
+#define NV50_3D_QUERY_GET_QUERY_SELECT_ZCULL_STAT_UNK2         0x07000000
+#define NV50_3D_QUERY_GET_QUERY_SELECT_ZCULL_STAT_UNK3         0x08000000
+#define NVA0_3D_QUERY_GET_QUERY_SELECT_RT_UNK14                        0x0c000000
+#define NVA0_3D_QUERY_GET_QUERY_SELECT_STRMOUT_OFFSET          0x0d000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT__MASK                 0x0f000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT__SHIFT                        24
+#define NV50_3D_QUERY_GET_COUNTER_SELECT_VFETCH_VERTICES       0x00000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT_VFETCH_PRIMITIVES     0x01000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT_VP_LAUNCHES           0x02000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT_GP_LAUNCHES           0x03000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT_GP_PRIMITIVES_OUT     0x04000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT_TRANSFORM_FEEDBACK    0x05000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT_GENERATED_PRIMITIVES  0x06000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT_RAST_PRIMITIVES_PRECLIP       0x07000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT_RAST_PRIMITIVES_POSTCLIP      0x08000000
+#define NV50_3D_QUERY_GET_COUNTER_SELECT_FP_PIXELS             0x09000000
+#define NV84_3D_QUERY_GET_COUNTER_SELECT_UNK0A                 0x0a000000
+#define NVA0_3D_QUERY_GET_COUNTER_SELECT_UNK0C                 0x0c000000
+#define NV50_3D_QUERY_GET_SHORT                                        0x10000000
+
+#define NVA3_3D_VP_RESULT_MAP_ALT(i0)                         (0x00001b3c + 0x4*(i0))
+#define NVA3_3D_VP_RESULT_MAP_ALT__ESIZE                       0x00000004
+#define NVA3_3D_VP_RESULT_MAP_ALT__LEN                         0x00000020
+#define NVA3_3D_VP_RESULT_MAP_ALT_0__MASK                      0x000000ff
+#define NVA3_3D_VP_RESULT_MAP_ALT_0__SHIFT                     0
+#define NVA3_3D_VP_RESULT_MAP_ALT_1__MASK                      0x0000ff00
+#define NVA3_3D_VP_RESULT_MAP_ALT_1__SHIFT                     8
+#define NVA3_3D_VP_RESULT_MAP_ALT_2__MASK                      0x00ff0000
+#define NVA3_3D_VP_RESULT_MAP_ALT_2__SHIFT                     16
+#define NVA3_3D_VP_RESULT_MAP_ALT_3__MASK                      0xff000000
+#define NVA3_3D_VP_RESULT_MAP_ALT_3__SHIFT                     24
+
+#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT(i0)                    (0x00001c00 + 0x10*(i0))
+#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT__ESIZE                  0x00000010
+#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT__LEN                    0x00000020
+#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT_STRIDE__MASK            0x00000fff
+#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT_STRIDE__SHIFT           0
+#define NVA3_3D_VERTEX_ARRAY_FETCH_ALT_ENABLE                  0x20000000
+
+#define NVA3_3D_VERTEX_ARRAY_START_HIGH_ALT(i0)                       (0x00001c04 + 0x10*(i0))
+#define NVA3_3D_VERTEX_ARRAY_START_HIGH_ALT__ESIZE             0x00000010
+#define NVA3_3D_VERTEX_ARRAY_START_HIGH_ALT__LEN               0x00000020
+
+#define NVA3_3D_VERTEX_ARRAY_START_LOW_ALT(i0)                (0x00001c08 + 0x10*(i0))
+#define NVA3_3D_VERTEX_ARRAY_START_LOW_ALT__ESIZE              0x00000010
+#define NVA3_3D_VERTEX_ARRAY_START_LOW_ALT__LEN                        0x00000020
+
+#define NVA3_3D_VERTEX_ARRAY_DIVISOR_ALT(i0)                  (0x00001c0c + 0x10*(i0))
+#define NVA3_3D_VERTEX_ARRAY_DIVISOR_ALT__ESIZE                        0x00000010
+#define NVA3_3D_VERTEX_ARRAY_DIVISOR_ALT__LEN                  0x00000020
+
+#define NVA3_3D_IBLEND(i0)                                    (0x00001e00 + 0x20*(i0))
+#define NVA3_3D_IBLEND__ESIZE                                  0x00000020
+#define NVA3_3D_IBLEND__LEN                                    0x00000008
+
+#define NVA3_3D_IBLEND_UNK00(i0)                              (0x00001e00 + 0x20*(i0))
+
+#define NVA3_3D_IBLEND_EQUATION_RGB(i0)                               (0x00001e04 + 0x20*(i0))
+#define NVA3_3D_IBLEND_EQUATION_RGB_FUNC_ADD                   0x00008006
+#define NVA3_3D_IBLEND_EQUATION_RGB_MIN                                0x00008007
+#define NVA3_3D_IBLEND_EQUATION_RGB_MAX                                0x00008008
+#define NVA3_3D_IBLEND_EQUATION_RGB_FUNC_SUBTRACT              0x0000800a
+#define NVA3_3D_IBLEND_EQUATION_RGB_FUNC_REVERSE_SUBTRACT      0x0000800b
+
+#define NVA3_3D_IBLEND_FUNC_SRC_RGB(i0)                               (0x00001e08 + 0x20*(i0))
+
+#define NVA3_3D_IBLEND_FUNC_DST_RGB(i0)                               (0x00001e0c + 0x20*(i0))
+
+#define NVA3_3D_IBLEND_EQUATION_ALPHA(i0)                     (0x00001e10 + 0x20*(i0))
+#define NVA3_3D_IBLEND_EQUATION_ALPHA_FUNC_ADD                 0x00008006
+#define NVA3_3D_IBLEND_EQUATION_ALPHA_MIN                      0x00008007
+#define NVA3_3D_IBLEND_EQUATION_ALPHA_MAX                      0x00008008
+#define NVA3_3D_IBLEND_EQUATION_ALPHA_FUNC_SUBTRACT            0x0000800a
+#define NVA3_3D_IBLEND_EQUATION_ALPHA_FUNC_REVERSE_SUBTRACT    0x0000800b
+
+#define NVA3_3D_IBLEND_FUNC_SRC_ALPHA(i0)                     (0x00001e14 + 0x20*(i0))
+
+#define NVA3_3D_IBLEND_FUNC_DST_ALPHA(i0)                     (0x00001e18 + 0x20*(i0))
+
+#define NVA3_3D_VERTEX_ARRAY_LIMIT_HIGH_ALT(i0)                       (0x00001f00 + 0x8*(i0))
+#define NVA3_3D_VERTEX_ARRAY_LIMIT_HIGH_ALT__ESIZE             0x00000008
+#define NVA3_3D_VERTEX_ARRAY_LIMIT_HIGH_ALT__LEN               0x00000020
+
+#define NVA3_3D_VERTEX_ARRAY_LIMIT_LOW_ALT(i0)                (0x00001f04 + 0x8*(i0))
+#define NVA3_3D_VERTEX_ARRAY_LIMIT_LOW_ALT__ESIZE              0x00000008
+#define NVA3_3D_VERTEX_ARRAY_LIMIT_LOW_ALT__LEN                        0x00000020
+
+
+#endif /* NV50_3D_XML */
diff --git a/src/gallium/drivers/nv50/nv50_3ddefs.xml.h b/src/gallium/drivers/nv50/nv50_3ddefs.xml.h
new file mode 100644 (file)
index 0000000..f26ac45
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef NV_3DDEFS_XML
+#define NV_3DDEFS_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:
+- nv50_3d.xml    (  26312 bytes, from 2010-10-08 10:10:01)
+- copyright.xml  (   6498 bytes, from 2010-10-03 13:18:37)
+- nv_defs.xml    (   4437 bytes, from 2010-07-06 07:43:58)
+- nv_3ddefs.xml  (  16397 bytes, from 2010-10-08 13:30:38)
+- nv_object.xml  (  11249 bytes, from 2010-10-07 15:31:28)
+- nvchipsets.xml (   2824 bytes, from 2010-07-07 13:41:20)
+- nv50_defs.xml  (   4482 bytes, from 2010-10-03 13:18:37)
+
+Copyright (C) 2006-2010 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, curro_, currojerez)
+- 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 NV50_3D_BLEND_FACTOR_ZERO                              0x00004000
+#define NV50_3D_BLEND_FACTOR_ONE                               0x00004001
+#define NV50_3D_BLEND_FACTOR_SRC_COLOR                         0x00004300
+#define NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC_COLOR               0x00004301
+#define NV50_3D_BLEND_FACTOR_SRC_ALPHA                         0x00004302
+#define NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA               0x00004303
+#define NV50_3D_BLEND_FACTOR_DST_ALPHA                         0x00004304
+#define NV50_3D_BLEND_FACTOR_ONE_MINUS_DST_ALPHA               0x00004305
+#define NV50_3D_BLEND_FACTOR_DST_COLOR                         0x00004306
+#define NV50_3D_BLEND_FACTOR_ONE_MINUS_DST_COLOR               0x00004307
+#define NV50_3D_BLEND_FACTOR_SRC_ALPHA_SATURATE                        0x00004308
+#define NV50_3D_BLEND_FACTOR_CONSTANT_COLOR                    0x0000c001
+#define NV50_3D_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR          0x0000c002
+#define NV50_3D_BLEND_FACTOR_CONSTANT_ALPHA                    0x0000c003
+#define NV50_3D_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA          0x0000c004
+#define NV50_3D_BLEND_FACTOR_SRC1_COLOR                                0x0000c900
+#define NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR              0x0000c901
+#define NV50_3D_BLEND_FACTOR_SRC1_ALPHA                                0x0000c902
+#define NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA              0x0000c903
+
+#endif /* NV_3DDEFS_XML */
index 45356f9f637c290f06f6707f472b7df99de2e916..5cb2e628e7a98f34cf0a8f9aa07500485de909db 100644 (file)
 #include "util/u_memory.h"
 #include "util/u_math.h"
 
+#define NOUVEAU_NVC0
 #include "nouveau/nouveau_screen.h"
 #include "nouveau/nouveau_winsys.h"
+#undef NOUVEAU_NVC0
+
+#include "nv50_context.h"
 #include "nv50_resource.h"
 
+struct nv50_transfer {
+   struct pipe_transfer base;
+};
 
+static INLINE struct nv50_transfer *
+nv50_transfer(struct pipe_transfer *transfer)
+{
+   return (struct nv50_transfer *)transfer;
+}
 
-static void nv50_buffer_destroy(struct pipe_screen *pscreen,
-                               struct pipe_resource *presource)
+static INLINE boolean
+nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf,
+                     unsigned domain)
 {
-       struct nv50_resource *buffer = nv50_resource(presource);
+   if (domain == NOUVEAU_BO_VRAM) {
+      buf->mm = nv50_mm_allocate(screen->mm_VRAM, buf->base.width0, &buf->bo,
+                                 &buf->offset);
+      if (!buf->bo)
+         return nv50_buffer_allocate(screen, buf, NOUVEAU_BO_GART);
+   } else
+   if (domain == NOUVEAU_BO_GART) {
+      buf->mm = nv50_mm_allocate(screen->mm_GART, buf->base.width0, &buf->bo,
+                                 &buf->offset);
+      if (!buf->bo)
+         return FALSE;
+   }
+   if (domain != NOUVEAU_BO_GART) {
+      if (!buf->data) {
+         buf->data = MALLOC(buf->base.width0);
+         if (!buf->data)
+            return FALSE;
+      }
+   }
+   buf->domain = domain;
+   return TRUE;
+}
 
-       nouveau_screen_bo_release(pscreen, buffer->bo);
-       FREE(buffer);
+static INLINE void
+release_allocation(struct nv50_mm_allocation **mm, struct nv50_fence *fence)
+{
+   if (fence && fence->state != NV50_FENCE_STATE_SIGNALLED) {
+      nv50_fence_sched_release(fence, *mm);
+   } else {
+      nv50_mm_free(*mm);
+   }
+   (*mm) = NULL;
 }
 
+INLINE void
+nv50_buffer_release_gpu_storage(struct nv50_resource *buf)
+{
+   nouveau_bo_ref(NULL, &buf->bo);
 
+   if (buf->mm)
+      release_allocation(&buf->mm, buf->fence);
 
+   buf->domain = 0;
+}
 
-/* Utility functions for transfer create/destroy are hooked in and
- * just record the arguments to those functions.
- */
-static void *
-nv50_buffer_transfer_map( struct pipe_context *pipe,
-                         struct pipe_transfer *transfer )
+static INLINE boolean
+nv50_buffer_reallocate(struct nv50_screen *screen, struct nv50_resource *buf,
+                       unsigned domain)
 {
-       struct nv50_resource *buffer = nv50_resource(transfer->resource);
-       uint8_t *map;
+   nv50_buffer_release_gpu_storage(buf);
 
-       map = nouveau_screen_bo_map_range( pipe->screen,
-                                          buffer->bo,
-                                          transfer->box.x,
-                                          transfer->box.width,
-                                          nouveau_screen_transfer_flags(transfer->usage) );
-       if (map == NULL)
-               return NULL;
-       
-       return map + transfer->box.x;
+   return nv50_buffer_allocate(screen, buf, domain);
 }
 
+static void
+nv50_buffer_destroy(struct pipe_screen *pscreen,
+                    struct pipe_resource *presource)
+{
+   struct nv50_resource *res = nv50_resource(presource);
+
+   nv50_buffer_release_gpu_storage(res);
 
+   if (res->data && !(res->status & NV50_BUFFER_STATUS_USER_MEMORY))
+      FREE(res->data);
 
-static void nv50_buffer_transfer_flush_region( struct pipe_context *pipe,
-                                              struct pipe_transfer *transfer,
-                                              const struct pipe_box *box)
+   FREE(res);
+}
+
+/* Maybe just migrate to GART right away if we actually need to do this. */
+boolean
+nv50_buffer_download(struct nv50_context *nv50, struct nv50_resource *buf,
+                     unsigned start, unsigned size)
 {
-       struct nv50_resource *buffer = nv50_resource(transfer->resource);
+   struct nv50_mm_allocation *mm;
+   struct nouveau_bo *bounce = NULL;
+   uint32_t offset;
+
+   assert(buf->domain == NOUVEAU_BO_VRAM);
+
+   mm = nv50_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset);
+   if (!bounce)
+      return FALSE;
 
-       nouveau_screen_bo_map_flush_range(pipe->screen,
-                                         buffer->bo,
-                                         transfer->box.x + box->x,
-                                         box->width);
+   nv50_m2mf_copy_linear(nv50, bounce, offset, NOUVEAU_BO_GART,
+                         buf->bo, buf->offset + start, NOUVEAU_BO_VRAM,
+                         size);
+
+   if (nouveau_bo_map_range(bounce, offset, size, NOUVEAU_BO_RD))
+      return FALSE;
+   memcpy(buf->data + start, bounce->map, size);
+   nouveau_bo_unmap(bounce);
+
+   buf->status &= ~NV50_BUFFER_STATUS_DIRTY;
+
+   nouveau_bo_ref(NULL, &bounce);
+   if (mm)
+      nv50_mm_free(mm);
+   return TRUE;
 }
 
-static void nv50_buffer_transfer_unmap( struct pipe_context *pipe,
-                                       struct pipe_transfer *transfer )
+static boolean
+nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf,
+                   unsigned start, unsigned size)
 {
-       struct nv50_resource *buffer = nv50_resource(transfer->resource);
+   struct nv50_mm_allocation *mm;
+   struct nouveau_bo *bounce = NULL;
+   uint32_t offset;
+
+   if (size <= 192) {
+      nv50_sifc_linear_u8(nv50, buf->bo, buf->domain, buf->offset + start,
+                          size, buf->data + start);
+      return TRUE;
+   }
+
+   mm = nv50_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset);
+   if (!bounce)
+      return FALSE;
+
+   nouveau_bo_map_range(bounce, offset, size,
+                        NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC);
+   memcpy(bounce->map, buf->data + start, size);
+   nouveau_bo_unmap(bounce);
+
+   nv50_m2mf_copy_linear(nv50, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM,
+                         bounce, offset, NOUVEAU_BO_GART, size);
+
+   nouveau_bo_ref(NULL, &bounce);
+   if (mm)
+      release_allocation(&mm, nv50->screen->fence.current);
+
+   if (start == 0 && size == buf->base.width0)
+      buf->status &= ~NV50_BUFFER_STATUS_DIRTY;
+   return TRUE;
+}
 
-       nouveau_screen_bo_unmap(pipe->screen, buffer->bo);
+static struct pipe_transfer *
+nv50_buffer_transfer_get(struct pipe_context *pipe,
+                         struct pipe_resource *resource,
+                         unsigned level,
+                         unsigned usage,
+                         const struct pipe_box *box)
+{
+   struct nv50_resource *buf = nv50_resource(resource);
+   struct nv50_transfer *xfr = CALLOC_STRUCT(nv50_transfer);
+   if (!xfr)
+      return NULL;
+
+   xfr->base.resource = resource;
+   xfr->base.box.x = box->x;
+   xfr->base.box.width = box->width;
+   xfr->base.usage = usage;
+
+   if (buf->domain == NOUVEAU_BO_VRAM) {
+      if (usage & PIPE_TRANSFER_READ) {
+         if (buf->status & NV50_BUFFER_STATUS_DIRTY)
+            nv50_buffer_download(nv50_context(pipe), buf, 0, buf->base.width0);
+      }
+   }
+
+   return &xfr->base;
 }
 
+static void
+nv50_buffer_transfer_destroy(struct pipe_context *pipe,
+                             struct pipe_transfer *transfer)
+{
+   struct nv50_resource *buf = nv50_resource(transfer->resource);
+   struct nv50_transfer *xfr = nv50_transfer(transfer);
+
+   if (xfr->base.usage & PIPE_TRANSFER_WRITE) {
+      /* writing is worse */
+      nv50_buffer_adjust_score(nv50_context(pipe), buf, -5000);
 
+      if (buf->domain == NOUVEAU_BO_VRAM) {
+         nv50_buffer_upload(nv50_context(pipe), buf,
+                            transfer->box.x, transfer->box.width);
+      }
 
+      if (buf->domain != 0 && (buf->base.bind & (PIPE_BIND_VERTEX_BUFFER |
+                                                 PIPE_BIND_INDEX_BUFFER)))
+         nv50_context(pipe)->vbo_dirty = TRUE;
+   }
 
-const struct u_resource_vtbl nv50_buffer_vtbl =
+   FREE(xfr);
+}
+
+static INLINE boolean
+nv50_buffer_sync(struct nv50_resource *buf, unsigned rw)
 {
-       u_default_resource_get_handle,      /* get_handle */
-       nv50_buffer_destroy,                /* resource_destroy */
-       NULL,                               /* is_resource_referenced */
-       u_default_get_transfer,             /* get_transfer */
-       u_default_transfer_destroy,         /* transfer_destroy */
-       nv50_buffer_transfer_map,           /* transfer_map */
-       nv50_buffer_transfer_flush_region,  /* transfer_flush_region */
-       nv50_buffer_transfer_unmap,         /* transfer_unmap */
-       u_default_transfer_inline_write     /* transfer_inline_write */
-};
+   if (rw == PIPE_TRANSFER_READ) {
+      if (!buf->fence_wr)
+         return TRUE;
+      if (!nv50_fence_wait(buf->fence_wr))
+         return FALSE;
+   } else {
+      if (!buf->fence)
+         return TRUE;
+      if (!nv50_fence_wait(buf->fence))
+         return FALSE;
+
+      nv50_fence_reference(&buf->fence, NULL);
+   }
+   nv50_fence_reference(&buf->fence_wr, NULL);
+
+   return TRUE;
+}
 
+static INLINE boolean
+nv50_buffer_busy(struct nv50_resource *buf, unsigned rw)
+{
+   if (rw == PIPE_TRANSFER_READ)
+      return (buf->fence_wr && !nv50_fence_signalled(buf->fence_wr));
+   else
+      return (buf->fence && !nv50_fence_signalled(buf->fence));
+}
 
+static void *
+nv50_buffer_transfer_map(struct pipe_context *pipe,
+                         struct pipe_transfer *transfer)
+{
+   struct nv50_transfer *xfr = nv50_transfer(transfer);
+   struct nv50_resource *buf = nv50_resource(transfer->resource);
+   struct nouveau_bo *bo = buf->bo;
+   uint8_t *map;
+   int ret;
+   uint32_t offset = xfr->base.box.x;
+   uint32_t flags;
+
+   nv50_buffer_adjust_score(nv50_context(pipe), buf, -250);
+
+   if (buf->domain != NOUVEAU_BO_GART)
+      return buf->data + offset;
+
+   if (buf->mm)
+      flags = NOUVEAU_BO_NOSYNC | NOUVEAU_BO_RDWR;
+   else
+      flags = nouveau_screen_transfer_flags(xfr->base.usage);
+
+   offset += buf->offset;
+
+   ret = nouveau_bo_map_range(buf->bo, offset, xfr->base.box.width, flags);
+   if (ret)
+      return NULL;
+   map = bo->map;
+
+   /* Unmap right now. Since multiple buffers can share a single nouveau_bo,
+    * not doing so might make future maps fail or trigger "reloc while mapped"
+    * errors. For now, mappings to userspace are guaranteed to be persistent.
+    */
+   nouveau_bo_unmap(bo);
+
+   if (buf->mm) {
+      if (xfr->base.usage & PIPE_TRANSFER_DONTBLOCK) {
+         if (nv50_buffer_busy(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE))
+            return NULL;
+      } else
+      if (!(xfr->base.usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
+         nv50_buffer_sync(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE);
+      }
+   }
+   return map;
+}
+
+
+
+static void
+nv50_buffer_transfer_flush_region(struct pipe_context *pipe,
+                                  struct pipe_transfer *transfer,
+                                  const struct pipe_box *box)
+{
+   struct nv50_resource *res = nv50_resource(transfer->resource);
+   struct nouveau_bo *bo = res->bo;
+   unsigned offset = res->offset + transfer->box.x + box->x;
+
+   /* not using non-snoop system memory yet, no need for cflush */
+   if (1)
+      return;
+
+   /* XXX: maybe need to upload for VRAM buffers here */
 
+   nouveau_screen_bo_map_flush_range(pipe->screen, bo, offset, box->width);
+}
+
+static void
+nv50_buffer_transfer_unmap(struct pipe_context *pipe,
+                           struct pipe_transfer *transfer)
+{
+   /* we've called nouveau_bo_unmap right after map */
+}
+
+const struct u_resource_vtbl nv50_buffer_vtbl =
+{
+   u_default_resource_get_handle,     /* get_handle */
+   nv50_buffer_destroy,               /* resource_destroy */
+   NULL,                              /* is_resource_referenced */
+   nv50_buffer_transfer_get,          /* get_transfer */
+   nv50_buffer_transfer_destroy,      /* transfer_destroy */
+   nv50_buffer_transfer_map,          /* transfer_map */
+   nv50_buffer_transfer_flush_region, /* transfer_flush_region */
+   nv50_buffer_transfer_unmap,        /* transfer_unmap */
+   u_default_transfer_inline_write    /* transfer_inline_write */
+};
 
 struct pipe_resource *
 nv50_buffer_create(struct pipe_screen *pscreen,
-                  const struct pipe_resource *template)
+                   const struct pipe_resource *templ)
 {
-       struct nv50_resource *buffer;
+   struct nv50_screen *screen = nv50_screen(pscreen);
+   struct nv50_resource *buffer;
+   boolean ret;
 
-       buffer = CALLOC_STRUCT(nv50_resource);
-       if (!buffer)
-               return NULL;
+   buffer = CALLOC_STRUCT(nv50_resource);
+   if (!buffer)
+      return NULL;
 
-       buffer->base = *template;
-       buffer->vtbl = &nv50_buffer_vtbl;
-       pipe_reference_init(&buffer->base.reference, 1);
-       buffer->base.screen = pscreen;
+   buffer->base = *templ;
+   buffer->vtbl = &nv50_buffer_vtbl;
+   pipe_reference_init(&buffer->base.reference, 1);
+   buffer->base.screen = pscreen;
 
-       buffer->bo = nouveau_screen_bo_new(pscreen,
-                                          16,
-                                          buffer->base.usage,
-                                          buffer->base.bind,
-                                          buffer->base.width0);
+   if (buffer->base.bind & PIPE_BIND_CONSTANT_BUFFER)
+      ret = nv50_buffer_allocate(screen, buffer, 0);
+   else
+      ret = nv50_buffer_allocate(screen, buffer, NOUVEAU_BO_GART);
 
-       if (buffer->bo == NULL)
-               goto fail;
+   if (ret == FALSE)
+      goto fail;
 
-       return &buffer->base;
+   return &buffer->base;
 
 fail:
-       FREE(buffer);
-       return NULL;
+   FREE(buffer);
+   return NULL;
 }
 
 
 struct pipe_resource *
 nv50_user_buffer_create(struct pipe_screen *pscreen,
-                       void *ptr,
-                       unsigned bytes,
-                       unsigned bind)
-{
-       struct nv50_resource *buffer;
-
-       buffer = CALLOC_STRUCT(nv50_resource);
-       if (!buffer)
-               return NULL;
-
-       pipe_reference_init(&buffer->base.reference, 1);
-       buffer->vtbl = &nv50_buffer_vtbl;
-       buffer->base.screen = pscreen;
-       buffer->base.format = PIPE_FORMAT_R8_UNORM;
-       buffer->base.usage = PIPE_USAGE_IMMUTABLE;
-       buffer->base.bind = bind;
-       buffer->base.width0 = bytes;
-       buffer->base.height0 = 1;
-       buffer->base.depth0 = 1;
-       buffer->base.array_size = 1;
-
-       buffer->bo = nouveau_screen_bo_user(pscreen, ptr, bytes);
-       if (!buffer->bo)
-               goto fail;
-       
-       return &buffer->base;
+                        void *ptr,
+                        unsigned bytes,
+                        unsigned bind)
+{
+   struct nv50_resource *buffer;
+
+   buffer = CALLOC_STRUCT(nv50_resource);
+   if (!buffer)
+      return NULL;
+
+   pipe_reference_init(&buffer->base.reference, 1);
+   buffer->vtbl = &nv50_buffer_vtbl;
+   buffer->base.screen = pscreen;
+   buffer->base.format = PIPE_FORMAT_R8_UNORM;
+   buffer->base.usage = PIPE_USAGE_IMMUTABLE;
+   buffer->base.bind = bind;
+   buffer->base.width0 = bytes;
+   buffer->base.height0 = 1;
+   buffer->base.depth0 = 1;
+
+   buffer->data = ptr;
+   buffer->status = NV50_BUFFER_STATUS_USER_MEMORY;
+
+   return &buffer->base;
+}
 
-fail:
-       FREE(buffer);
-       return NULL;
+/* Like download, but for GART buffers. Merge ? */
+static INLINE boolean
+nv50_buffer_data_fetch(struct nv50_resource *buf,
+                       struct nouveau_bo *bo, unsigned offset, unsigned size)
+{
+   if (!buf->data) {
+      buf->data = MALLOC(size);
+      if (!buf->data)
+         return FALSE;
+   }
+   if (nouveau_bo_map_range(bo, offset, size, NOUVEAU_BO_RD))
+      return FALSE;
+   memcpy(buf->data, bo->map, size);
+   nouveau_bo_unmap(bo);
+
+   return TRUE;
+}
+
+/* Migrate a linear buffer (vertex, index, constants) USER -> GART -> VRAM. */
+boolean
+nv50_buffer_migrate(struct nv50_context *nv50,
+                    struct nv50_resource *buf, const unsigned new_domain)
+{
+   struct nv50_screen *screen = nv50_screen(buf->base.screen);
+   struct nouveau_bo *bo;
+   const unsigned old_domain = buf->domain;
+   unsigned size = buf->base.width0;
+   unsigned offset;
+   int ret;
+
+   assert(new_domain != old_domain);
+
+   if (new_domain == NOUVEAU_BO_GART && old_domain == 0) {
+      if (!nv50_buffer_allocate(screen, buf, new_domain))
+         return FALSE;
+      ret = nouveau_bo_map_range(buf->bo, buf->offset, size, NOUVEAU_BO_WR |
+                                 NOUVEAU_BO_NOSYNC);
+      if (ret)
+         return ret;
+      memcpy(buf->bo->map, buf->data, size);
+      nouveau_bo_unmap(buf->bo);
+      FREE(buf->data);
+   } else
+   if (old_domain != 0 && new_domain != 0) {
+      struct nv50_mm_allocation *mm = buf->mm;
+
+      if (new_domain == NOUVEAU_BO_VRAM) {
+         /* keep a system memory copy of our data in case we hit a fallback */
+         if (!nv50_buffer_data_fetch(buf, buf->bo, buf->offset, size))
+            return FALSE;
+         debug_printf("migrating %u KiB to VRAM\n", size / 1024);
+      }
+
+      offset = buf->offset;
+      bo = buf->bo;
+      buf->bo = NULL;
+      buf->mm = NULL;
+      nv50_buffer_allocate(screen, buf, new_domain);
+
+      nv50_m2mf_copy_linear(nv50, buf->bo, buf->offset, new_domain,
+                            bo, offset, old_domain, buf->base.width0);
+
+      nouveau_bo_ref(NULL, &bo);
+      if (mm)
+         release_allocation(&mm, screen->fence.current);
+   } else
+   if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) {
+      if (!nv50_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM))
+         return FALSE;
+      if (!nv50_buffer_upload(nv50, buf, 0, buf->base.width0))
+         return FALSE;
+   } else
+      return FALSE;
+
+   assert(buf->domain == new_domain);
+   return TRUE;
 }
 
+/* Migrate data from glVertexAttribPointer(non-VBO) user buffers to GART.
+ * We'd like to only allocate @size bytes here, but then we'd have to rebase
+ * the vertex indices ...
+ */
+boolean
+nv50_user_buffer_upload(struct nv50_resource *buf, unsigned base, unsigned size)
+{
+   struct nv50_screen *screen = nv50_screen(buf->base.screen);
+   int ret;
+
+   assert(buf->status & NV50_BUFFER_STATUS_USER_MEMORY);
+
+   buf->base.width0 = base + size;
+   if (!nv50_buffer_reallocate(screen, buf, NOUVEAU_BO_GART))
+      return FALSE;
+
+   ret = nouveau_bo_map_range(buf->bo, buf->offset + base, size,
+                              NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC);
+   if (ret)
+      return FALSE;
+   memcpy(buf->bo->map, buf->data + base, size);
+   nouveau_bo_unmap(buf->bo);
+
+   return TRUE;
+}
diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c
deleted file mode 100644 (file)
index ee7cf28..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2008 Ben Skeggs
- *
- * 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.
- */
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-
-#include "nv50_context.h"
-
-void
-nv50_clear(struct pipe_context *pipe, unsigned buffers,
-          const float *rgba, double depth, unsigned stencil)
-{
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nouveau_channel *chan = nv50->screen->base.channel;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct pipe_framebuffer_state *fb = &nv50->framebuffer;
-       unsigned mode = 0, i;
-       const unsigned dirty = nv50->dirty;
-
-       /* don't need NEW_BLEND, NV50TCL_COLOR_MASK doesn't affect CLEAR_BUFFERS */
-       nv50->dirty &= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR;
-       if (!nv50_state_validate(nv50, 64))
-               return;
-
-       if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
-               BEGIN_RING(chan, tesla, NV50TCL_CLEAR_COLOR(0), 4);
-               OUT_RING  (chan, fui(rgba[0]));
-               OUT_RING  (chan, fui(rgba[1]));
-               OUT_RING  (chan, fui(rgba[2]));
-               OUT_RING  (chan, fui(rgba[3]));
-               mode |= 0x3c;
-       }
-
-       if (buffers & PIPE_CLEAR_DEPTH) {
-               BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1);
-               OUT_RING  (chan, fui(depth));
-               mode |= NV50TCL_CLEAR_BUFFERS_Z;
-       }
-       if (buffers & PIPE_CLEAR_STENCIL) {
-               BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1);
-               OUT_RING  (chan, stencil & 0xff);
-               mode |= NV50TCL_CLEAR_BUFFERS_S;
-       }
-
-       BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
-       OUT_RING  (chan, mode);
-
-       for (i = 1; i < fb->nr_cbufs; i++) {
-               BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
-               OUT_RING  (chan, (i << 6) | 0x3c);
-       }
-       nv50->dirty = dirty;
-}
-
index 4f9761617603bd1e9480fcd8378b0cf325b86454..bb6272a4a23da608b0325d5278ec598d9ffd1e28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Ben Skeggs
+ * Copyright 2010 Christoph Bumiller
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "nv50_screen.h"
 #include "nv50_resource.h"
 
+#include "nouveau/nouveau_reloc.h"
+
 static void
 nv50_flush(struct pipe_context *pipe, unsigned flags,
-          struct pipe_fence_handle **fence)
+           struct pipe_fence_handle **fence)
+{
+   struct nv50_context *nv50 = nv50_context(pipe);
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+
+   if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
+      BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1);
+      OUT_RING  (chan, 0);
+      BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
+      OUT_RING  (chan, 0x20);
+   }
+
+   if (fence)
+      nv50_fence_reference((struct nv50_fence **)fence,
+                           nv50->screen->fence.current);
+
+   if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME))
+      FIRE_RING(chan);
+}
+
+void
+nv50_default_flush_notify(struct nouveau_channel *chan)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nv50_context *nv50 = chan->user_private;
+
+   if (!nv50)
+      return;
 
-       if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
-               BEGIN_RING(chan, nv50->screen->tesla, 0x1338, 1);
-               OUT_RING  (chan, 0x20);
-       }
+   nv50_screen_fence_update(nv50->screen, TRUE);
 
-       if (flags & PIPE_FLUSH_FRAME)
-               FIRE_RING(chan);
+   nv50_screen_fence_next(nv50->screen);
 }
 
 static void
 nv50_destroy(struct pipe_context *pipe)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       int i;
-
-        for (i = 0; i < nv50->vtxbuf_nr; i++) {
-           pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
-        }
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       for (i = 0; i < 64; i++) {
-               if (!nv50->state.hw[i])
-                       continue;
-               so_ref(NULL, &nv50->state.hw[i]);
-       }
+   draw_destroy(nv50->draw);
 
-       draw_destroy(nv50->draw);
+   if (nv50->screen->cur_ctx == nv50) {
+      nv50->screen->base.channel->user_private = NULL;
+      nv50->screen->cur_ctx = NULL;
+   }
 
-       if (nv50->screen->cur_ctx == nv50)
-               nv50->screen->cur_ctx = NULL;
-
-       FREE(nv50);
+   FREE(nv50);
 }
 
-
 struct pipe_context *
 nv50_create(struct pipe_screen *pscreen, void *priv)
 {
-       struct pipe_winsys *pipe_winsys = pscreen->winsys;
-       struct nv50_screen *screen = nv50_screen(pscreen);
-       struct nv50_context *nv50;
+   struct pipe_winsys *pipe_winsys = pscreen->winsys;
+   struct nv50_screen *screen = nv50_screen(pscreen);
+   struct nv50_context *nv50;
+
+   nv50 = CALLOC_STRUCT(nv50_context);
+   if (!nv50)
+      return NULL;
+   nv50->screen = screen;
+
+   nv50->pipe.winsys = pipe_winsys;
+   nv50->pipe.screen = pscreen;
+   nv50->pipe.priv = priv;
+
+   nv50->pipe.destroy = nv50_destroy;
+
+   nv50->pipe.draw_vbo = nv50_draw_vbo;
+   nv50->pipe.clear = nv50_clear;
 
-       nv50 = CALLOC_STRUCT(nv50_context);
-       if (!nv50)
-               return NULL;
-       nv50->screen = screen;
+   nv50->pipe.flush = nv50_flush;
 
-       nv50->pipe.winsys = pipe_winsys;
-       nv50->pipe.screen = pscreen;
-       nv50->pipe.priv = priv;
+   screen->base.channel->user_private = nv50;
+   screen->base.channel->flush_notify = nv50_default_flush_notify;
 
-       nv50->pipe.destroy = nv50_destroy;
+   nv50_init_query_functions(nv50);
+   nv50_init_surface_functions(nv50);
+   nv50_init_state_functions(nv50);
+   nv50_init_resource_functions(&nv50->pipe);
 
-       nv50->pipe.draw_vbo = nv50_draw_vbo;
-       nv50->pipe.clear = nv50_clear;
+   nv50->draw = draw_create(&nv50->pipe);
+   assert(nv50->draw);
+   draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50));
 
-       nv50->pipe.flush = nv50_flush;
+   return &nv50->pipe;
+}
+
+struct resident {
+   struct nv50_resource *res;
+   uint32_t flags;
+};
+
+void
+nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx,
+                         struct nv50_resource *resource, uint32_t flags)
+{
+   struct resident rsd = { resource, flags };
+
+   if (!resource->bo)
+      return;
+
+   /* We don't need to reference the resource here, it will be referenced
+    * in the context/state, and bufctx will be reset when state changes.
+    */
+   util_dynarray_append(&nv50->residents[ctx], struct resident, rsd);
+}
+
+void
+nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx,
+                         struct nv50_resource *resource)
+{
+   struct resident *rsd, *top;
+   unsigned i;
+
+   for (i = 0; i < nv50->residents[ctx].size / sizeof(struct resident); ++i) {
+      rsd = util_dynarray_element(&nv50->residents[ctx], struct resident, i);
+
+      if (rsd->res == resource) {
+         top = util_dynarray_pop_ptr(&nv50->residents[ctx], struct resident);
+         if (rsd != top)
+            *rsd = *top;
+         break;
+      }
+   }
+}
+
+void
+nv50_bufctx_emit_relocs(struct nv50_context *nv50)
+{
+   struct resident *rsd;
+   struct util_dynarray *array;
+   unsigned ctx, i, n;
 
-       screen->base.channel->user_private = nv50;
+   for (ctx = 0; ctx < NV50_BUFCTX_COUNT; ++ctx) {
+      array = &nv50->residents[ctx];
 
-       nv50_init_surface_functions(nv50);
-       nv50_init_state_functions(nv50);
-       nv50_init_query_functions(nv50);
-       nv50_init_resource_functions(&nv50->pipe);
+      n = array->size / sizeof(struct resident);
+      MARK_RING(nv50->screen->base.channel, n, n);
+      for (i = 0; i < n; ++i) {
+         rsd = util_dynarray_element(array, struct resident, i);
 
-       nv50->draw = draw_create(&nv50->pipe);
-       assert(nv50->draw);
-       draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50));
+         nv50_resource_validate(rsd->res, rsd->flags);
+      }
+   }
 
-       return &nv50->pipe;
+   nv50_screen_make_buffers_resident(nv50->screen);
 }
index b2b0b72fe265e1e33b6e23999b7697cb9648d328..a6275d79587c7bfedcf760a96432b9616c38f887 100644 (file)
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
-#include "pipe/p_compiler.h"
 
 #include "util/u_memory.h"
 #include "util/u_math.h"
 #include "util/u_inlines.h"
+#include "util/u_dynarray.h"
 
 #include "draw/draw_vertex.h"
 
-#include "nouveau/nouveau_winsys.h"
-#include "nouveau/nouveau_gldefs.h"
-#include "nouveau/nouveau_stateobj.h"
-#include "nv50_reg.h"
-
+#include "nv50_winsys.h"
+#include "nv50_stateobj.h"
 #include "nv50_screen.h"
 #include "nv50_program.h"
+#include "nv50_resource.h"
 
-#define NOUVEAU_ERR(fmt, args...) \
-       fprintf(stderr, "%s:%d -  "fmt, __FUNCTION__, __LINE__, ##args);
-#define NOUVEAU_MSG(fmt, args...) \
-       fprintf(stderr, "nouveau: "fmt, ##args);
-
-#define nouveau_bo_tile_layout(nvbo) \
-       ((nvbo)->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)
-
-/* Constant buffer assignment */
-#define NV50_CB_PMISC          0
-#define NV50_CB_PVP            1
-#define NV50_CB_PFP            2
-#define NV50_CB_PGP            3
-#define NV50_CB_AUX            4
-
-#define NV50_NEW_BLEND         (1 << 0)
-#define NV50_NEW_ZSA           (1 << 1)
-#define NV50_NEW_BLEND_COLOUR  (1 << 2)
-#define NV50_NEW_STIPPLE       (1 << 3)
-#define NV50_NEW_SCISSOR       (1 << 4)
-#define NV50_NEW_VIEWPORT      (1 << 5)
-#define NV50_NEW_RASTERIZER    (1 << 6)
-#define NV50_NEW_FRAMEBUFFER   (1 << 7)
-#define NV50_NEW_VERTPROG      (1 << 8)
-#define NV50_NEW_VERTPROG_CB   (1 << 9)
-#define NV50_NEW_FRAGPROG      (1 << 10)
-#define NV50_NEW_FRAGPROG_CB   (1 << 11)
-#define NV50_NEW_GEOMPROG      (1 << 12)
-#define NV50_NEW_GEOMPROG_CB   (1 << 13)
-#define NV50_NEW_ARRAYS                (1 << 14)
-#define NV50_NEW_SAMPLER       (1 << 15)
-#define NV50_NEW_TEXTURE       (1 << 16)
-#define NV50_NEW_STENCIL_REF   (1 << 17)
-#define NV50_NEW_CLIP          (1 << 18)
-
-struct nv50_blend_stateobj {
-       struct pipe_blend_state pipe;
-       struct nouveau_stateobj *so;
-};
-
-struct nv50_zsa_stateobj {
-       struct pipe_depth_stencil_alpha_state pipe;
-       struct nouveau_stateobj *so;
-};
+#include "nouveau/nv_object.xml.h"
+#include "nouveau/nv_m2mf.xml.h"
+#include "nv50_3ddefs.xml.h"
+#include "nv50_3d.xml.h"
+#include "nv50_2d.xml.h"
 
-struct nv50_rasterizer_stateobj {
-       struct pipe_rasterizer_state pipe;
-       struct nouveau_stateobj *so;
-};
+#define NOUVEAU_ERR(fmt, args...) \
+   fprintf(stderr, "%s:%d -  "fmt, __FUNCTION__, __LINE__, ##args);
 
-struct nv50_sampler_stateobj {
-       boolean normalized;
-       unsigned tsc[8];
-};
+#ifdef NOUVEAU_DEBUG
+# define NOUVEAU_DBG(args...) printf(args);
+#else
+# define NOUVEAU_DBG(args...)
+#endif
 
-struct nv50_sampler_view {
-       struct pipe_sampler_view pipe;
-       uint32_t tic[8];
-};
+#define NV50_NEW_BLEND        (1 << 0)
+#define NV50_NEW_RASTERIZER   (1 << 1)
+#define NV50_NEW_ZSA          (1 << 2)
+#define NV50_NEW_VERTPROG     (1 << 3)
+#define NV50_NEW_GMTYPROG     (1 << 6)
+#define NV50_NEW_FRAGPROG     (1 << 7)
+#define NV50_NEW_BLEND_COLOUR (1 << 8)
+#define NV50_NEW_STENCIL_REF  (1 << 9)
+#define NV50_NEW_CLIP         (1 << 10)
+#define NV50_NEW_SAMPLE_MASK  (1 << 11)
+#define NV50_NEW_FRAMEBUFFER  (1 << 12)
+#define NV50_NEW_STIPPLE      (1 << 13)
+#define NV50_NEW_SCISSOR      (1 << 14)
+#define NV50_NEW_VIEWPORT     (1 << 15)
+#define NV50_NEW_ARRAYS       (1 << 16)
+#define NV50_NEW_VERTEX       (1 << 17)
+#define NV50_NEW_CONSTBUF     (1 << 18)
+#define NV50_NEW_TEXTURES     (1 << 19)
+#define NV50_NEW_SAMPLERS     (1 << 20)
+
+#define NV50_BUFCTX_CONSTANT 0
+#define NV50_BUFCTX_FRAME    1
+#define NV50_BUFCTX_VERTEX   2
+#define NV50_BUFCTX_TEXTURES 3
+#define NV50_BUFCTX_COUNT    4
+
+/* fixed constant buffer binding points - low indices for user's constbufs */
+#define NV50_CB_PVP 124
+#define NV50_CB_PGP 126
+#define NV50_CB_PFP 125
+#define NV50_CB_AUX 127
 
-struct nv50_vtxelt_stateobj {
-       struct pipe_vertex_element pipe[16];
-       unsigned num_elements;
-       uint32_t hw[16];
+struct nv50_context {
+   struct pipe_context pipe;
+
+   struct nv50_screen *screen;
+
+   struct util_dynarray residents[NV50_BUFCTX_COUNT];
+
+   uint32_t dirty;
+
+   struct {
+      uint32_t instance_elts; /* bitmask of per-instance elements */
+      uint32_t instance_base;
+      int32_t index_bias;
+      boolean prim_restart;
+      uint8_t num_vtxbufs;
+      uint8_t num_vtxelts;
+      uint8_t num_textures[3];
+      uint8_t num_samplers[3];
+      uint16_t scissor;
+   } state;
+
+   struct nv50_blend_stateobj *blend;
+   struct nv50_rasterizer_stateobj *rast;
+   struct nv50_zsa_stateobj *zsa;
+   struct nv50_vertex_stateobj *vertex;
+
+   struct nv50_program *vertprog;
+   struct nv50_program *gmtyprog;
+   struct nv50_program *fragprog;
+
+   struct pipe_resource *constbuf[3][16];
+   uint16_t constbuf_dirty[3];
+
+   struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
+   unsigned num_vtxbufs;
+   struct pipe_index_buffer idxbuf;
+   uint32_t vbo_fifo; /* bitmask of vertex elements to be pushed to FIFO */
+   uint32_t vbo_user; /* bitmask of vertex buffers pointing to user memory */
+   unsigned vbo_min_index; /* from pipe_draw_info, for vertex upload */
+   unsigned vbo_max_index;
+
+   struct pipe_sampler_view *textures[3][PIPE_MAX_SAMPLERS];
+   unsigned num_textures[3];
+   struct nv50_tsc_entry *samplers[3][PIPE_MAX_SAMPLERS];
+   unsigned num_samplers[3];
+
+   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;
+
+   boolean vbo_dirty;
+   boolean vbo_push_hint;
+
+   struct draw_context *draw;
 };
 
-static INLINE struct nv50_sampler_view *
-nv50_sampler_view(struct pipe_sampler_view *view)
-{
-       return (struct nv50_sampler_view *)view;
-}
-
-static INLINE unsigned
-get_tile_height(uint32_t tile_mode)
-{
-        return 1 << ((tile_mode & 0xf) + 2);
-}
-
-static INLINE unsigned
-get_tile_depth(uint32_t tile_mode)
+static INLINE struct nv50_context *
+nv50_context(struct pipe_context *pipe)
 {
-        return 1 << (tile_mode >> 4);
+   return (struct nv50_context *)pipe;
 }
 
-
 struct nv50_surface {
-       struct pipe_surface base;
-       unsigned offset;
+   struct pipe_surface base;
+   uint32_t offset;
+   uint32_t width;
+   uint16_t height;
+   uint16_t depth;
 };
 
 static INLINE struct nv50_surface *
-nv50_surface(struct pipe_surface *pt)
+nv50_surface(struct pipe_surface *ps)
 {
-       return (struct nv50_surface *)pt;
+   return (struct nv50_surface *)ps;
 }
 
-struct nv50_state {
-       struct nouveau_stateobj *hw[64];
-       uint64_t hw_dirty;
-
-       unsigned sampler_view_nr[3];
-       struct nouveau_stateobj *vtxbuf;
-       struct nouveau_stateobj *vtxattr;
-       unsigned vtxelt_nr;
-};
+/* nv50_context.c */
+struct pipe_context *nv50_create(struct pipe_screen *, void *);
 
-struct nv50_context {
-       struct pipe_context pipe;
-
-       struct nv50_screen *screen;
-
-       struct draw_context *draw;
-
-       struct nv50_state state;
-
-       unsigned dirty;
-       struct nv50_blend_stateobj *blend;
-       struct nv50_zsa_stateobj *zsa;
-       struct nv50_rasterizer_stateobj *rasterizer;
-       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_framebuffer_state framebuffer;
-       struct pipe_clip_state clip;
-       struct nv50_program *vertprog;
-       struct nv50_program *fragprog;
-       struct nv50_program *geomprog;
-       struct pipe_resource *constbuf[PIPE_SHADER_TYPES];
-       struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
-       unsigned vtxbuf_nr;
-       struct pipe_index_buffer idxbuf;
-       struct nv50_vtxelt_stateobj *vtxelt;
-       struct nv50_sampler_stateobj *sampler[3][PIPE_MAX_SAMPLERS];
-       unsigned sampler_nr[3];
-       struct pipe_sampler_view *sampler_views[3][PIPE_MAX_SAMPLERS];
-       unsigned sampler_view_nr[3];
-
-       unsigned vbo_fifo;
-       unsigned req_lmem;
-};
+void nv50_default_flush_notify(struct nouveau_channel *);
 
-static INLINE struct nv50_context *
-nv50_context(struct pipe_context *pipe)
+void nv50_bufctx_emit_relocs(struct nv50_context *);
+void nv50_bufctx_add_resident(struct nv50_context *, int ctx,
+                              struct nv50_resource *, uint32_t flags);
+void nv50_bufctx_del_resident(struct nv50_context *, int ctx,
+                              struct nv50_resource *);
+static INLINE void
+nv50_bufctx_reset(struct nv50_context *nv50, int ctx)
 {
-       return (struct nv50_context *)pipe;
+   util_dynarray_resize(&nv50->residents[ctx], 0);
 }
 
-extern void nv50_init_surface_functions(struct nv50_context *nv50);
-extern void nv50_init_state_functions(struct nv50_context *nv50);
-extern void nv50_init_query_functions(struct nv50_context *nv50);
-extern void nv50_init_transfer_functions(struct nv50_context *nv50);
-
-extern void nv50_screen_init_miptree_functions(struct pipe_screen *pscreen);
-
-extern int
-nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst,
-                    int dx, int dy, struct pipe_surface *src, int sx, int sy,
-                    int w, int h);
-
 /* nv50_draw.c */
-extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50);
+extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *);
 
-/* nv50_vbo.c */
-extern void nv50_draw_vbo(struct pipe_context *pipe,
-                          const struct pipe_draw_info *info);
-extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso);
-extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50);
+/* nv50_program.c */
+boolean nv50_program_translate(struct nv50_program *);
+void nv50_program_destroy(struct nv50_context *, struct nv50_program *);
 
-/* nv50_push.c */
-extern void
-nv50_push_elements_instanced(struct pipe_context *, struct pipe_resource *,
-                            unsigned idxsize, int idxbias,
-                             unsigned mode, unsigned start,
-                            unsigned count, unsigned i_start,
-                            unsigned i_count);
+/* nv50_query.c */
+void nv50_init_query_functions(struct nv50_context *);
 
-/* nv50_clear.c */
-extern void nv50_clear(struct pipe_context *pipe, unsigned buffers,
-                      const float *rgba, double depth, unsigned stencil);
+/* nv50_shader_state.c */
+void nv50_vertprog_validate(struct nv50_context *);
+void nv50_gmtyprog_validate(struct nv50_context *);
+void nv50_fragprog_validate(struct nv50_context *);
+void nv50_fp_linkage_validate(struct nv50_context *);
+void nv50_gp_linkage_validate(struct nv50_context *);
+void nv50_constbufs_validate(struct nv50_context *);
 
-/* nv50_program.c */
-extern struct nouveau_stateobj *
-nv50_vertprog_validate(struct nv50_context *nv50);
-extern struct nouveau_stateobj *
-nv50_fragprog_validate(struct nv50_context *nv50);
-extern struct nouveau_stateobj *
-nv50_geomprog_validate(struct nv50_context *nv50);
-extern struct nouveau_stateobj *
-nv50_fp_linkage_validate(struct nv50_context *nv50);
-extern struct nouveau_stateobj *
-nv50_gp_linkage_validate(struct nv50_context *nv50);
-extern void nv50_program_destroy(struct nv50_context *nv50,
-                                struct nv50_program *p);
+/* nv50_state.c */
+extern void nv50_init_state_functions(struct nv50_context *);
 
 /* nv50_state_validate.c */
-extern boolean nv50_state_validate(struct nv50_context *nv50, unsigned dwords);
+extern boolean nv50_state_validate(struct nv50_context *);
 
-extern void nv50_so_init_sifc(struct nv50_context *nv50,
-                             struct nouveau_stateobj *so,
-                             struct nouveau_bo *bo, unsigned reloc,
-                             unsigned offset, unsigned size);
+/* nv50_surface.c */
+extern void nv50_clear(struct pipe_context *, unsigned buffers,
+                       const float *rgba, double depth, unsigned stencil);
+extern void nv50_init_surface_functions(struct nv50_context *);
 
 /* nv50_tex.c */
-extern boolean nv50_tex_construct(struct nv50_sampler_view *view);
-extern void nv50_tex_relocs(struct nv50_context *);
-extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *);
+void nv50_validate_textures(struct nv50_context *);
+void nv50_validate_samplers(struct nv50_context *);
+
+struct pipe_sampler_view *
+nv50_create_sampler_view(struct pipe_context *,
+                         struct pipe_resource *,
+                         const struct pipe_sampler_view *);
+
+/* nv50_transfer.c */
+void
+nv50_sifc_linear_u8(struct nv50_context *nv50,
+                    struct nouveau_bo *dst, unsigned domain, int offset,
+                    unsigned size, void *data);
+void
+nv50_m2mf_copy_linear(struct nv50_context *nv50,
+                      struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
+                      struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
+                      unsigned size);
+
+/* nv50_vbo.c */
+void nv50_draw_vbo(struct pipe_context *, const struct pipe_draw_info *);
 
+void *
+nv50_vertex_state_create(struct pipe_context *pipe,
+                         unsigned num_elements,
+                         const struct pipe_vertex_element *elements);
+void
+nv50_vertex_state_delete(struct pipe_context *pipe, void *hwcso);
 
-/* nv50_context.c */
-struct pipe_context *
-nv50_create(struct pipe_screen *pscreen, void *priv);
+void nv50_vertex_arrays_validate(struct nv50_context *nv50);
 
-static INLINE unsigned
-nv50_prim(unsigned mode)
-{
-       switch (mode) {
-       case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS;
-       case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES;
-       case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP;
-       case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP;
-       case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES;
-       case PIPE_PRIM_TRIANGLE_STRIP:
-               return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP;
-       case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN;
-       case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS;
-       case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP;
-       case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON;
-       case PIPE_PRIM_LINES_ADJACENCY:
-               return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY;
-       case PIPE_PRIM_LINE_STRIP_ADJACENCY:
-               return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY;
-       case PIPE_PRIM_TRIANGLES_ADJACENCY:
-               return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY;
-       case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
-               return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY;
-       default:
-               break;
-       }
-
-       NOUVEAU_ERR("invalid primitive type %d\n", mode);
-       return NV50TCL_VERTEX_BEGIN_POINTS;
-}
+/* nv50_push.c */
+void nv50_push_vbo(struct nv50_context *, const struct pipe_draw_info *);
 
 #endif
diff --git a/src/gallium/drivers/nv50/nv50_defs.xml.h b/src/gallium/drivers/nv50/nv50_defs.xml.h
new file mode 100644 (file)
index 0000000..1bf2f80
--- /dev/null
@@ -0,0 +1,142 @@
+#ifndef NV50_DEFS_XML
+#define NV50_DEFS_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:
+- nv50_defs.xml (   4482 bytes, from 2010-10-03 13:18:37)
+- copyright.xml (   6498 bytes, from 2010-10-03 13:18:37)
+
+Copyright (C) 2006-2010 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, curro_, currojerez)
+- 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 NV50_SURFACE_FORMAT_R32G32B32A32_FLOAT                 0x000000c0
+#define NV50_SURFACE_FORMAT_R32G32B32A32_SINT                  0x000000c1
+#define NV50_SURFACE_FORMAT_R32G32B32A32_UINT                  0x000000c2
+#define NV50_SURFACE_FORMAT_R32G32B32X32_FLOAT                 0x000000c3
+#define NV50_SURFACE_FORMAT_R16G16B16A16_UNORM                 0x000000c6
+#define NV50_SURFACE_FORMAT_R16G16B16A16_SNORM                 0x000000c7
+#define NV50_SURFACE_FORMAT_R16G16B16A16_SINT                  0x000000c8
+#define NV50_SURFACE_FORMAT_R16G16B16A16_UINT                  0x000000c9
+#define NV50_SURFACE_FORMAT_R16G16B16A16_FLOAT                 0x000000ca
+#define NV50_SURFACE_FORMAT_R32G32_FLOAT                       0x000000cb
+#define NV50_SURFACE_FORMAT_R32G32_SINT                                0x000000cc
+#define NV50_SURFACE_FORMAT_R32G32_UINT                                0x000000cd
+#define NV50_SURFACE_FORMAT_R16G16B16X16_FLOAT                 0x000000ce
+#define NV50_SURFACE_FORMAT_A8R8G8B8_UNORM                     0x000000cf
+#define NV50_SURFACE_FORMAT_A8R8G8B8_SRGB                      0x000000d0
+#define NV50_SURFACE_FORMAT_A2B10G10R10_UNORM                  0x000000d1
+#define NV50_SURFACE_FORMAT_A2B10G10R10_UINT                   0x000000d2
+#define NV50_SURFACE_FORMAT_A8B8G8R8_UNORM                     0x000000d5
+#define NV50_SURFACE_FORMAT_A8B8G8R8_SRGB                      0x000000d6
+#define NV50_SURFACE_FORMAT_A8B8G8R8_SNORM                     0x000000d7
+#define NV50_SURFACE_FORMAT_A8B8G8R8_SINT                      0x000000d8
+#define NV50_SURFACE_FORMAT_A8B8G8R8_UINT                      0x000000d9
+#define NV50_SURFACE_FORMAT_R16G16_UNORM                       0x000000da
+#define NV50_SURFACE_FORMAT_R16G16_SNORM                       0x000000db
+#define NV50_SURFACE_FORMAT_R16G16_SINT                                0x000000dc
+#define NV50_SURFACE_FORMAT_R16G16_UINT                                0x000000dd
+#define NV50_SURFACE_FORMAT_R16G16_FLOAT                       0x000000de
+#define NV50_SURFACE_FORMAT_A2R10G10B10_UNORM                  0x000000df
+#define NV50_SURFACE_FORMAT_B10G11R11_FLOAT                    0x000000e0
+#define NV50_SURFACE_FORMAT_R32_FLOAT                          0x000000e5
+#define NV50_SURFACE_FORMAT_X8R8G8B8_UNORM                     0x000000e6
+#define NV50_SURFACE_FORMAT_X8R8G8B8_SRGB                      0x000000e7
+#define NV50_SURFACE_FORMAT_R5G6B5_UNORM                       0x000000e8
+#define NV50_SURFACE_FORMAT_A1R5G5B5_UNORM                     0x000000e9
+#define NV50_SURFACE_FORMAT_R8G8_UNORM                         0x000000ea
+#define NV50_SURFACE_FORMAT_R8G8_SNORM                         0x000000eb
+#define NV50_SURFACE_FORMAT_R8G8_SINT                          0x000000ec
+#define NV50_SURFACE_FORMAT_R8G8_UINT                          0x000000ed
+#define NV50_SURFACE_FORMAT_R16_UNORM                          0x000000ee
+#define NV50_SURFACE_FORMAT_R16_SNORM                          0x000000ef
+#define NV50_SURFACE_FORMAT_R16_SINT                           0x000000f0
+#define NV50_SURFACE_FORMAT_R16_UINT                           0x000000f1
+#define NV50_SURFACE_FORMAT_R16_FLOAT                          0x000000f2
+#define NV50_SURFACE_FORMAT_R8_UNORM                           0x000000f3
+#define NV50_SURFACE_FORMAT_R8_SNORM                           0x000000f4
+#define NV50_SURFACE_FORMAT_R8_SINT                            0x000000f5
+#define NV50_SURFACE_FORMAT_R8_UINT                            0x000000f6
+#define NV50_SURFACE_FORMAT_A8_UNORM                           0x000000f7
+#define NV50_SURFACE_FORMAT_X1R5G5B5_UNORM                     0x000000f8
+#define NV50_SURFACE_FORMAT_X8B8G8R8_UNORM                     0x000000f9
+#define NV50_SURFACE_FORMAT_X8B8G8R8_SRGB                      0x000000fa
+#define NV50_ZETA_FORMAT_Z32_FLOAT                             0x0000000a
+#define NV50_ZETA_FORMAT_Z16_UNORM                             0x00000013
+#define NV50_ZETA_FORMAT_Z24S8_UNORM                           0x00000014
+#define NV50_ZETA_FORMAT_X8Z24_UNORM                           0x00000015
+#define NV50_ZETA_FORMAT_S8Z24_UNORM                           0x00000016
+#define NV50_ZETA_FORMAT_UNK18                                 0x00000018
+#define NV50_ZETA_FORMAT_Z32_FLOAT_X24S8_UNORM                 0x00000019
+#define NV50_ZETA_FORMAT_UNK1D                                 0x0000001d
+#define NV50_ZETA_FORMAT_UNK1E                                 0x0000001e
+#define NV50_ZETA_FORMAT_UNK1F                                 0x0000001f
+#define NV50_QUERY__SIZE                                       0x00000010
+#define NV50_QUERY_COUNTER                                     0x00000000
+
+#define NV50_QUERY_RES                                         0x00000004
+
+#define NV50_QUERY_TIME                                                0x00000008
+
+
+#endif /* NV50_DEFS_XML */
index 2f6f607261e573e958544f893a5f3d434249e287..1d8598829c5ffd8762f734d4e8e173e6d46dda10 100644 (file)
 #include "nv50_context.h"
 
 struct nv50_render_stage {
-       struct draw_stage stage;
-       struct nv50_context *nv50;
+   struct draw_stage stage;
+   struct nv50_context *nv50;
 };
 
 static INLINE struct nv50_render_stage *
 nv50_render_stage(struct draw_stage *stage)
 {
-       return (struct nv50_render_stage *)stage;
+   return (struct nv50_render_stage *)stage;
 }
 
 static void
 nv50_render_point(struct draw_stage *stage, struct prim_header *prim)
 {
-       NOUVEAU_ERR("\n");
+   NOUVEAU_ERR("\n");
 }
 
 static void
 nv50_render_line(struct draw_stage *stage, struct prim_header *prim)
 {
-       NOUVEAU_ERR("\n");
+   NOUVEAU_ERR("\n");
 }
 
 static void
 nv50_render_tri(struct draw_stage *stage, struct prim_header *prim)
 {
-       NOUVEAU_ERR("\n");
+   NOUVEAU_ERR("\n");
 }
 
 static void
@@ -61,29 +61,28 @@ nv50_render_flush(struct draw_stage *stage, unsigned flags)
 static void
 nv50_render_reset_stipple_counter(struct draw_stage *stage)
 {
-       NOUVEAU_ERR("\n");
+   NOUVEAU_ERR("\n");
 }
 
 static void
 nv50_render_destroy(struct draw_stage *stage)
 {
-       FREE(stage);
+   FREE(stage);
 }
 
 struct draw_stage *
 nv50_draw_render_stage(struct nv50_context *nv50)
 {
-       struct nv50_render_stage *rs = CALLOC_STRUCT(nv50_render_stage);
+   struct nv50_render_stage *rs = CALLOC_STRUCT(nv50_render_stage);
 
-       rs->nv50 = nv50;
-       rs->stage.draw = nv50->draw;
-       rs->stage.destroy = nv50_render_destroy;
-       rs->stage.point = nv50_render_point;
-       rs->stage.line = nv50_render_line;
-       rs->stage.tri = nv50_render_tri;
-       rs->stage.flush = nv50_render_flush;
-       rs->stage.reset_stipple_counter = nv50_render_reset_stipple_counter;
+   rs->nv50 = nv50;
+   rs->stage.draw = nv50->draw;
+   rs->stage.destroy = nv50_render_destroy;
+   rs->stage.point = nv50_render_point;
+   rs->stage.line = nv50_render_line;
+   rs->stage.tri = nv50_render_tri;
+   rs->stage.flush = nv50_render_flush;
+   rs->stage.reset_stipple_counter = nv50_render_reset_stipple_counter;
 
-       return &rs->stage;
+   return &rs->stage;
 }
-
diff --git a/src/gallium/drivers/nv50/nv50_fence.c b/src/gallium/drivers/nv50/nv50_fence.c
new file mode 100644 (file)
index 0000000..936cf81
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2010 Christoph Bumiller
+ *
+ * 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.
+ */
+
+#include "nv50_fence.h"
+#include "nv50_context.h"
+#include "nv50_screen.h"
+
+#ifdef PIPE_OS_UNIX
+#include <sched.h>
+#endif
+
+boolean
+nv50_screen_fence_new(struct nv50_screen *screen, struct nv50_fence **fence,
+                      boolean emit)
+{
+   *fence = CALLOC_STRUCT(nv50_fence);
+   if (!*fence)
+      return FALSE;
+
+   (*fence)->screen = screen;
+   (*fence)->ref = 1;
+
+   if (emit)
+      nv50_fence_emit(*fence);
+
+   return TRUE;
+}
+
+void
+nv50_fence_emit(struct nv50_fence *fence)
+{
+   struct nv50_screen *screen = fence->screen;
+   struct nouveau_channel *chan = screen->base.channel;
+
+   fence->sequence = ++screen->fence.sequence;
+
+   assert(fence->state == NV50_FENCE_STATE_AVAILABLE);
+
+   MARK_RING (chan, 5, 2);
+   BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
+   OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
+   OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
+   OUT_RING  (chan, fence->sequence);
+   OUT_RING  (chan, 
+              NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
+              NV50_3D_QUERY_GET_UNK4 |
+              NV50_3D_QUERY_GET_UNIT_CROP |
+              NV50_3D_QUERY_GET_TYPE_QUERY |
+              NV50_3D_QUERY_GET_QUERY_SELECT_ZERO |
+              NV50_3D_QUERY_GET_SHORT);
+
+
+   ++fence->ref;
+
+   if (screen->fence.tail)
+      screen->fence.tail->next = fence;
+   else
+      screen->fence.head = fence;
+
+   screen->fence.tail = fence;
+
+   fence->state = NV50_FENCE_STATE_EMITTED;
+}
+
+static void
+nv50_fence_trigger_release_buffers(struct nv50_fence *fence);
+
+void
+nv50_fence_del(struct nv50_fence *fence)
+{
+   struct nv50_fence *it;
+   struct nv50_screen *screen = fence->screen;
+
+   if (fence->state == NV50_FENCE_STATE_EMITTED ||
+       fence->state == NV50_FENCE_STATE_FLUSHED) {
+      if (fence == screen->fence.head) {
+         screen->fence.head = fence->next;
+         if (!screen->fence.head)
+            screen->fence.tail = NULL;
+      } else {
+         for (it = screen->fence.head; it && it->next != fence; it = it->next);
+         it->next = fence->next;
+         if (screen->fence.tail == fence)
+            screen->fence.tail = it;
+      }
+   }
+
+   if (fence->buffers) {
+      debug_printf("WARNING: deleting fence with buffers "
+                   "still hooked to it !\n");
+      nv50_fence_trigger_release_buffers(fence);
+   }
+
+   FREE(fence);
+}
+
+static void
+nv50_fence_trigger_release_buffers(struct nv50_fence *fence)
+{
+   struct nv50_mm_allocation *alloc = fence->buffers;
+
+   while (alloc) {
+      struct nv50_mm_allocation *next = alloc->next;
+      nv50_mm_free(alloc);
+      alloc = next;
+   };
+   fence->buffers = NULL;
+}
+
+void
+nv50_screen_fence_update(struct nv50_screen *screen, boolean flushed)
+{
+   struct nv50_fence *fence;
+   struct nv50_fence *next = NULL;
+   uint32_t sequence = screen->fence.map[0];
+
+   if (screen->fence.sequence_ack == sequence)
+      return;
+   screen->fence.sequence_ack = sequence;
+
+   for (fence = screen->fence.head; fence; fence = next) {
+      next = fence->next;
+      sequence = fence->sequence;
+
+      fence->state = NV50_FENCE_STATE_SIGNALLED;
+
+      if (fence->buffers)
+         nv50_fence_trigger_release_buffers(fence);
+
+      nv50_fence_reference(&fence, NULL);
+
+      if (sequence == screen->fence.sequence_ack)
+         break;
+   }
+   screen->fence.head = next;
+   if (!next)
+      screen->fence.tail = NULL;
+
+   if (flushed) {
+      for (fence = next; fence; fence = fence->next)
+         fence->state = NV50_FENCE_STATE_FLUSHED;
+   }
+}
+
+#define NV50_FENCE_MAX_SPINS (1 << 31)
+
+boolean
+nv50_fence_signalled(struct nv50_fence *fence)
+{
+   struct nv50_screen *screen = fence->screen;
+
+   if (fence->state >= NV50_FENCE_STATE_EMITTED)
+      nv50_screen_fence_update(screen, FALSE);
+
+   return fence->state == NV50_FENCE_STATE_SIGNALLED;
+}
+
+boolean
+nv50_fence_wait(struct nv50_fence *fence)
+{
+   struct nv50_screen *screen = fence->screen;
+   uint32_t spins = 0;
+
+   if (fence->state < NV50_FENCE_STATE_EMITTED) {
+      nv50_fence_emit(fence);
+
+      if (fence == screen->fence.current)
+         nv50_screen_fence_new(screen, &screen->fence.current, FALSE);
+   }
+   if (fence->state < NV50_FENCE_STATE_FLUSHED)
+      FIRE_RING(screen->base.channel);
+
+   do {
+      nv50_screen_fence_update(screen, FALSE);
+
+      if (fence->state == NV50_FENCE_STATE_SIGNALLED)
+         return TRUE;
+      spins++;
+#ifdef PIPE_OS_UNIX
+      if (!(spins % 8)) /* donate a few cycles */
+         sched_yield();
+#endif
+   } while (spins < NV50_FENCE_MAX_SPINS);
+
+   debug_printf("Wait on fence %u (ack = %u, next = %u) timed out !\n",
+                fence->sequence,
+                screen->fence.sequence_ack, screen->fence.sequence);
+
+   return FALSE;
+}
+
+void
+nv50_screen_fence_next(struct nv50_screen *screen)
+{
+   nv50_fence_emit(screen->fence.current);
+   nv50_screen_fence_new(screen, &screen->fence.current, FALSE);
+}
diff --git a/src/gallium/drivers/nv50/nv50_fence.h b/src/gallium/drivers/nv50/nv50_fence.h
new file mode 100644 (file)
index 0000000..dd0b74e
--- /dev/null
@@ -0,0 +1,49 @@
+
+#ifndef __NV50_FENCE_H__
+#define __NV50_FENCE_H__
+
+#include "util/u_inlines.h"
+#include "util/u_double_list.h"
+
+#define NV50_FENCE_STATE_AVAILABLE 0
+#define NV50_FENCE_STATE_EMITTED   1
+#define NV50_FENCE_STATE_FLUSHED   2
+#define NV50_FENCE_STATE_SIGNALLED 3
+
+struct nv50_mm_allocation;
+
+struct nv50_fence {
+   struct nv50_fence *next;
+   struct nv50_screen *screen;
+   int state;
+   int ref;
+   uint32_t sequence;
+   struct nv50_mm_allocation *buffers;
+};
+
+void nv50_fence_emit(struct nv50_fence *);
+void nv50_fence_del(struct nv50_fence *);
+
+boolean nv50_fence_wait(struct nv50_fence *);
+boolean nv50_fence_signalled(struct nv50_fence *);
+
+static INLINE void
+nv50_fence_reference(struct nv50_fence **ref, struct nv50_fence *fence)
+{
+   if (*ref) {
+      if (--(*ref)->ref == 0)
+         nv50_fence_del(*ref);
+   }
+   if (fence)
+      ++fence->ref;
+
+   *ref = fence;
+}
+
+static INLINE struct nv50_fence *
+nv50_fence(struct pipe_fence_handle *fence)
+{
+   return (struct nv50_fence *)fence;
+}
+
+#endif // __NV50_FENCE_H__
index 428280945477b26c658df4e9841caf778e7d1968..194e826fa661b5e4f97352af9c74e594b245087b 100644 (file)
  */
 
 #include "nv50_screen.h"
-#include "nv50_texture.h"
-#include "nv50_reg.h"
+#include "nv50_texture.xml.h"
+#include "nv50_defs.xml.h"
+#include "nv50_3d.xml.h"
 #include "pipe/p_defines.h"
 
-#define A_(cr, cg, cb, ca, t0, t1, t2, t3, sz, r)          \
-   NV50TIC_0_0_MAPR_##cr | NV50TIC_0_0_TYPER_##t0 |         \
-   NV50TIC_0_0_MAPG_##cg | NV50TIC_0_0_TYPEG_##t1 |        \
-   NV50TIC_0_0_MAPB_##cb | NV50TIC_0_0_TYPEB_##t2 |        \
-   NV50TIC_0_0_MAPA_##ca | NV50TIC_0_0_TYPEA_##t3 |         \
-   NV50TIC_0_0_FMT_##sz,                                    \
-   NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_##sz |                \
-   NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_##t0 |                  \
-   (NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_##t0 << 3) | (r << 31)
-
-#define B_(cr, cg, cb, ca, t0, t1, t2, t3, sz, r)   \
-   NV50TIC_0_0_MAPR_##cr | NV50TIC_0_0_TYPER_##t0 | \
-   NV50TIC_0_0_MAPG_##cg | NV50TIC_0_0_TYPEG_##t1 | \
-   NV50TIC_0_0_MAPB_##cb | NV50TIC_0_0_TYPEB_##t2 | \
-   NV50TIC_0_0_MAPA_##ca | NV50TIC_0_0_TYPEA_##t3 | \
-   NV50TIC_0_0_FMT_##sz, 0
+#define A_(cr, cg, cb, ca, t0, t1, t2, t3, sz, r)    \
+   (NV50_TIC_MAP_##cr << NV50_TIC_0_MAPR__SHIFT) |   \
+   (NV50_TIC_TYPE_##t0 << NV50_TIC_0_TYPE0__SHIFT) | \
+   (NV50_TIC_MAP_##cg << NV50_TIC_0_MAPG__SHIFT) |   \
+   (NV50_TIC_TYPE_##t1 << NV50_TIC_0_TYPE1__SHIFT) | \
+   (NV50_TIC_MAP_##cb << NV50_TIC_0_MAPB__SHIFT) |   \
+   (NV50_TIC_TYPE_##t2 << NV50_TIC_0_TYPE2__SHIFT) | \
+   (NV50_TIC_MAP_##ca << NV50_TIC_0_MAPA__SHIFT) |   \
+   (NV50_TIC_TYPE_##t3 << NV50_TIC_0_TYPE3__SHIFT) | \
+   NV50_TIC_0_FMT_##sz,                              \
+   NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_##sz |         \
+   NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_##t0 | (r << 31)
+
+#define B_(cr, cg, cb, ca, t0, t1, t2, t3, sz, r)    \
+   (NV50_TIC_MAP_##cr << NV50_TIC_0_MAPR__SHIFT) |   \
+   (NV50_TIC_TYPE_##t0 << NV50_TIC_0_TYPE0__SHIFT) | \
+   (NV50_TIC_MAP_##cg << NV50_TIC_0_MAPG__SHIFT) |   \
+   (NV50_TIC_TYPE_##t1 << NV50_TIC_0_TYPE1__SHIFT) | \
+   (NV50_TIC_MAP_##cb << NV50_TIC_0_MAPB__SHIFT) |   \
+   (NV50_TIC_TYPE_##t2 << NV50_TIC_0_TYPE2__SHIFT) | \
+   (NV50_TIC_MAP_##ca << NV50_TIC_0_MAPA__SHIFT) |   \
+   (NV50_TIC_TYPE_##t3 << NV50_TIC_0_TYPE3__SHIFT) | \
+   NV50_TIC_0_FMT_##sz, 0
 
 #define VERTEX_BUFFER PIPE_BIND_VERTEX_BUFFER
 #define SAMPLER_VIEW  PIPE_BIND_SAMPLER_VIEW
 #define SCANOUT       PIPE_BIND_SCANOUT
 
 /* for vertex buffers: */
-#define NV50TIC_0_0_FMT_8_8_8 NV50TIC_0_0_FMT_8_8_8_8
-#define NV50TIC_0_0_FMT_16_16_16 NV50TIC_0_0_FMT_16_16_16_16
-#define NV50TIC_0_0_FMT_32_32_32 NV50TIC_0_0_FMT_32_32_32_32
-
-/* NOTE: using NV50_2D_DST_FORMAT for substitute formats used with 2D engine */
+#define NV50_TIC_0_FMT_8_8_8 NV50_TIC_0_FMT_8_8_8_8
+#define NV50_TIC_0_FMT_16_16_16 NV50_TIC_0_FMT_16_16_16_16
+#define NV50_TIC_0_FMT_32_32_32 NV50_TIC_0_FMT_32_32_32_32
 
 const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] =
 {
    /* COMMON FORMATS */
 
-   [PIPE_FORMAT_B8G8R8A8_UNORM] = { NV50TCL_RT_FORMAT_A8R8G8B8_UNORM,
+   [PIPE_FORMAT_B8G8R8A8_UNORM] = { NV50_SURFACE_FORMAT_A8R8G8B8_UNORM,
     A_(C2, C1, C0, C3, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 1),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET | SCANOUT },
 
-   [PIPE_FORMAT_B8G8R8X8_UNORM] = { NV50TCL_RT_FORMAT_X8R8G8B8_UNORM,
+   [PIPE_FORMAT_B8G8R8X8_UNORM] = { NV50_SURFACE_FORMAT_X8R8G8B8_UNORM,
     A_(C2, C1, C0, ONE, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 1),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET | SCANOUT },
 
-   [PIPE_FORMAT_B8G8R8A8_SRGB] = { NV50TCL_RT_FORMAT_A8R8G8B8_SRGB,
+   [PIPE_FORMAT_B8G8R8A8_SRGB] = { NV50_SURFACE_FORMAT_A8R8G8B8_SRGB,
     A_(C2, C1, C0, C3, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 1),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_B8G8R8X8_SRGB] = { NV50TCL_RT_FORMAT_X8R8G8B8_SRGB,
+   [PIPE_FORMAT_B8G8R8X8_SRGB] = { NV50_SURFACE_FORMAT_X8R8G8B8_SRGB,
     A_(C2, C1, C0, ONE, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 1),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_B5G6R5_UNORM] = { NV50TCL_RT_FORMAT_R5G6B5_UNORM,
+   [PIPE_FORMAT_B5G6R5_UNORM] = { NV50_SURFACE_FORMAT_R5G6B5_UNORM,
     B_(C2, C1, C0, ONE, UNORM, UNORM, UNORM, UNORM, 5_6_5, 1),
     SAMPLER_VIEW | RENDER_TARGET | SCANOUT },
 
-   [PIPE_FORMAT_B5G5R5A1_UNORM] = { NV50TCL_RT_FORMAT_A1R5G5B5_UNORM,
+   [PIPE_FORMAT_B5G5R5A1_UNORM] = { NV50_SURFACE_FORMAT_A1R5G5B5_UNORM,
     B_(C2, C1, C0, C3, UNORM, UNORM, UNORM, UNORM, 1_5_5_5, 1),
     SAMPLER_VIEW | RENDER_TARGET | SCANOUT },
 
-   [PIPE_FORMAT_B4G4R4A4_UNORM] = { NV50_2D_DST_FORMAT_R16_UNORM,
+   [PIPE_FORMAT_B4G4R4A4_UNORM] = { NV50_SURFACE_FORMAT_R16_UNORM,
     B_(C2, C1, C0, C3, UNORM, UNORM, UNORM, UNORM, 4_4_4_4, 1),
     SAMPLER_VIEW },
 
-   [PIPE_FORMAT_R10G10B10A2_UNORM] = { NV50TCL_RT_FORMAT_A2B10G10R10_UNORM,
+   [PIPE_FORMAT_R10G10B10A2_UNORM] = { NV50_SURFACE_FORMAT_A2B10G10R10_UNORM,
     A_(C0, C1, C2, C3, UNORM, UNORM, UNORM, UNORM, 2_10_10_10, 0),
     SAMPLER_VIEW | RENDER_TARGET | VERTEX_BUFFER | SCANOUT },
 
-   [PIPE_FORMAT_B10G10R10A2_UNORM] = { NV50TCL_RT_FORMAT_A2R10G10B10_UNORM,
+   [PIPE_FORMAT_B10G10R10A2_UNORM] = { NV50_SURFACE_FORMAT_A2R10G10B10_UNORM,
     A_(C2, C1, C0, C3, UNORM, UNORM, UNORM, UNORM, 2_10_10_10, 1),
     SAMPLER_VIEW | RENDER_TARGET | VERTEX_BUFFER },
 
    /* DEPTH/STENCIL FORMATS */
 
-   [PIPE_FORMAT_Z16_UNORM] = { NV50TCL_ZETA_FORMAT_Z16_UNORM,
-    B_(C0, C0, C0, ONE, UNORM, UINT, UINT, UINT, 16_DEPTH, 0),
+   [PIPE_FORMAT_Z16_UNORM] = { NV50_ZETA_FORMAT_Z16_UNORM,
+    B_(C0, C0, C0, ONE, UNORM, UINT, UINT, UINT, 16_ZETA, 0),
     SAMPLER_VIEW | DEPTH_STENCIL },
 
-   [PIPE_FORMAT_Z24_UNORM_S8_USCALED] = { NV50TCL_ZETA_FORMAT_S8Z24_UNORM,
+   [PIPE_FORMAT_Z24_UNORM_S8_USCALED] = { NV50_ZETA_FORMAT_S8Z24_UNORM,
     B_(C0, C0, C0, ONE, UNORM, UINT, UINT, UINT, 8_24, 0),
     SAMPLER_VIEW | DEPTH_STENCIL },
 
-   [PIPE_FORMAT_Z24X8_UNORM] = { NV50TCL_ZETA_FORMAT_X8Z24_UNORM,
+   [PIPE_FORMAT_Z24X8_UNORM] = { NV50_ZETA_FORMAT_X8Z24_UNORM,
     B_(C0, C0, C0, ONE, UNORM, UINT, UINT, UINT, 8_24, 0),
     SAMPLER_VIEW | DEPTH_STENCIL },
 
-   [PIPE_FORMAT_S8_USCALED_Z24_UNORM] = { NV50TCL_ZETA_FORMAT_S8Z24_UNORM,
+   [PIPE_FORMAT_S8_USCALED_Z24_UNORM] = { NV50_ZETA_FORMAT_Z24S8_UNORM,
     B_(C1, C1, C1, ONE, UINT, UNORM, UINT, UINT, 24_8, 0),
     SAMPLER_VIEW | DEPTH_STENCIL },
 
-   [PIPE_FORMAT_Z32_FLOAT] = { NV50TCL_ZETA_FORMAT_Z32_FLOAT,
-    B_(C0, C0, C0, ONE, FLOAT, UINT, UINT, UINT, 32_DEPTH, 0),
+   [PIPE_FORMAT_Z32_FLOAT] = { NV50_ZETA_FORMAT_Z32_FLOAT,
+    B_(C0, C0, C0, ONE, FLOAT, UINT, UINT, UINT, 32_ZETA, 0),
     SAMPLER_VIEW | DEPTH_STENCIL },
 
    [PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED] = {
-    NV50TCL_ZETA_FORMAT_Z32_FLOAT_X24S8_UNORM,
+    NV50_ZETA_FORMAT_Z32_FLOAT_X24S8_UNORM,
     B_(C0, C0, C0, ONE, FLOAT, UINT, UINT, UINT, 32_8, 0),
     SAMPLER_VIEW | DEPTH_STENCIL },
 
    /* LUMINANCE, ALPHA, INTENSITY */
 
-   [PIPE_FORMAT_L8_UNORM] = { NV50_2D_DST_FORMAT_R8_UNORM,
+   [PIPE_FORMAT_L8_UNORM] = { NV50_SURFACE_FORMAT_R8_UNORM,
     A_(C0, C0, C0, ONE, UNORM, UNORM, UNORM, UNORM, 8, 0),
     SAMPLER_VIEW },
 
-   [PIPE_FORMAT_L8_SRGB] = { NV50_2D_DST_FORMAT_R8_UNORM,
+   [PIPE_FORMAT_L8_SRGB] = { NV50_SURFACE_FORMAT_R8_UNORM,
     A_(C0, C0, C0, ONE, UNORM, UNORM, UNORM, UNORM, 8, 0),
     SAMPLER_VIEW },
 
-   [PIPE_FORMAT_I8_UNORM] = { NV50_2D_DST_FORMAT_R8_UNORM,
+   [PIPE_FORMAT_I8_UNORM] = { NV50_SURFACE_FORMAT_R8_UNORM,
     A_(C0, C0, C0, C0, UNORM, UNORM, UNORM, UNORM, 8, 0),
     SAMPLER_VIEW },
 
-   [PIPE_FORMAT_A8_UNORM] = { NV50TCL_RT_FORMAT_A8_UNORM,
+   [PIPE_FORMAT_A8_UNORM] = { NV50_SURFACE_FORMAT_A8_UNORM,
     A_(ZERO, ZERO, ZERO, C0, UNORM, UNORM, UNORM, UNORM, 8, 0),
     SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_L8A8_UNORM] = { NV50_2D_DST_FORMAT_R16_UNORM,
+   [PIPE_FORMAT_L8A8_UNORM] = { NV50_SURFACE_FORMAT_R16_UNORM,
     A_(C0, C0, C0, C1, UNORM, UNORM, UNORM, UNORM, 8_8, 0),
     SAMPLER_VIEW },
 
@@ -184,48 +190,48 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] =
 
    /* FLOAT 16 */
 
-   [PIPE_FORMAT_R16G16B16A16_FLOAT] = { NV50TCL_RT_FORMAT_R16G16B16A16_FLOAT,
+   [PIPE_FORMAT_R16G16B16A16_FLOAT] = { NV50_SURFACE_FORMAT_R16G16B16A16_FLOAT,
     A_(C0, C1, C2, C3, FLOAT, FLOAT, FLOAT, FLOAT, 16_16_16_16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R16G16B16_FLOAT] = { NV50TCL_RT_FORMAT_R16G16B16X16_FLOAT,
+   [PIPE_FORMAT_R16G16B16_FLOAT] = { NV50_SURFACE_FORMAT_R16G16B16X16_FLOAT,
     A_(C0, C1, C2, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 16_16_16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R16G16_FLOAT] = { NV50TCL_RT_FORMAT_R16G16_FLOAT,
+   [PIPE_FORMAT_R16G16_FLOAT] = { NV50_SURFACE_FORMAT_R16G16_FLOAT,
     A_(C0, C1, ZERO, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 16_16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R16_FLOAT] = { NV50TCL_RT_FORMAT_R16_FLOAT,
+   [PIPE_FORMAT_R16_FLOAT] = { NV50_SURFACE_FORMAT_R16_FLOAT,
     A_(C0, ZERO, ZERO, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
    /* FLOAT 32 */
 
-   [PIPE_FORMAT_R32G32B32A32_FLOAT] = { NV50TCL_RT_FORMAT_R32G32B32A32_FLOAT,
+   [PIPE_FORMAT_R32G32B32A32_FLOAT] = { NV50_SURFACE_FORMAT_R32G32B32A32_FLOAT,
     A_(C0, C1, C2, C3, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32_32, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R32G32B32_FLOAT] = { NV50TCL_RT_FORMAT_R32G32B32X32_FLOAT,
+   [PIPE_FORMAT_R32G32B32_FLOAT] = { NV50_SURFACE_FORMAT_R32G32B32X32_FLOAT,
     A_(C0, C1, C2, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R32G32_FLOAT] = { NV50TCL_RT_FORMAT_R32G32_FLOAT,
+   [PIPE_FORMAT_R32G32_FLOAT] = { NV50_SURFACE_FORMAT_R32G32_FLOAT,
     A_(C0, C1, ZERO, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 32_32, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R32_FLOAT] = { NV50TCL_RT_FORMAT_R32_FLOAT,
+   [PIPE_FORMAT_R32_FLOAT] = { NV50_SURFACE_FORMAT_R32_FLOAT,
     A_(C0, ZERO, ZERO, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 32, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
    /* ODD FORMATS */
 
-   [PIPE_FORMAT_R11G11B10_FLOAT] = { NV50TCL_RT_FORMAT_B10G11R11_FLOAT,
+   [PIPE_FORMAT_R11G11B10_FLOAT] = { NV50_SURFACE_FORMAT_B10G11R11_FLOAT,
     B_(C0, C1, C2, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 10_11_11, 0),
     SAMPLER_VIEW | RENDER_TARGET },
 
    [PIPE_FORMAT_R9G9B9E5_FLOAT] = { 0,
-    B_(C0, C1, C2, ONE, FLOAT, FLOAT, FLOAT, FLOAT, 5_9_9_9, 0),
+    B_(C0, C1, C2, ONE, FLOAT, FLOAT, FLOAT, FLOAT, E5_9_9_9, 0),
     SAMPLER_VIEW },
 
    /* SNORM 32 */
@@ -266,7 +272,7 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] =
 
    /* SNORM 16 */
 
-   [PIPE_FORMAT_R16G16B16A16_SNORM] = { NV50TCL_RT_FORMAT_R16G16B16A16_SNORM,
+   [PIPE_FORMAT_R16G16B16A16_SNORM] = { NV50_SURFACE_FORMAT_R16G16B16A16_SNORM,
     A_(C0, C1, C2, C3, SNORM, SNORM, SNORM, SNORM, 16_16_16_16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
@@ -274,17 +280,17 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] =
     A_(C0, C1, C2, ONE, SNORM, SNORM, SNORM, SNORM, 16_16_16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW },
 
-   [PIPE_FORMAT_R16G16_SNORM] = { NV50TCL_RT_FORMAT_R16G16_SNORM,
+   [PIPE_FORMAT_R16G16_SNORM] = { NV50_SURFACE_FORMAT_R16G16_SNORM,
     A_(C0, C1, C2, C3, SNORM, SNORM, SNORM, SNORM, 16_16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R16_SNORM] = { NV50TCL_RT_FORMAT_R16_SNORM,
+   [PIPE_FORMAT_R16_SNORM] = { NV50_SURFACE_FORMAT_R16_SNORM,
     A_(C0, ZERO, ZERO, ONE, SNORM, SNORM, SNORM, SNORM, 16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
    /* UNORM 16 */
 
-   [PIPE_FORMAT_R16G16B16A16_UNORM] = { NV50TCL_RT_FORMAT_R16G16B16A16_UNORM,
+   [PIPE_FORMAT_R16G16B16A16_UNORM] = { NV50_SURFACE_FORMAT_R16G16B16A16_UNORM,
     A_(C0, C1, C2, C3, UNORM, UNORM, UNORM, UNORM, 16_16_16_16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
@@ -292,17 +298,17 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] =
     A_(C0, C1, C2, ONE, UNORM, UNORM, UNORM, UNORM, 16_16_16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW },
 
-   [PIPE_FORMAT_R16G16_UNORM] = { NV50TCL_RT_FORMAT_R16G16_UNORM,
+   [PIPE_FORMAT_R16G16_UNORM] = { NV50_SURFACE_FORMAT_R16G16_UNORM,
     A_(C0, C1, C2, C3, UNORM, UNORM, UNORM, UNORM, 16_16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R16_UNORM] = { NV50TCL_RT_FORMAT_R16_UNORM,
+   [PIPE_FORMAT_R16_UNORM] = { NV50_SURFACE_FORMAT_R16_UNORM,
     A_(C0, ZERO, ZERO, ONE, UNORM, UNORM, UNORM, UNORM, 16, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
    /* SNORM 8 */
 
-   [PIPE_FORMAT_R8G8B8A8_SNORM] = { NV50TCL_RT_FORMAT_A8B8G8R8_SNORM,
+   [PIPE_FORMAT_R8G8B8A8_SNORM] = { NV50_SURFACE_FORMAT_A8B8G8R8_SNORM,
     A_(C0, C1, C2, C3, SNORM, SNORM, SNORM, SNORM, 8_8_8_8, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
@@ -310,37 +316,37 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] =
     A_(C0, C1, C2, ONE, SNORM, SNORM, SNORM, SNORM, 8_8_8, 0),
     VERTEX_BUFFER | SAMPLER_VIEW },
 
-   [PIPE_FORMAT_R8G8_SNORM] = { NV50TCL_RT_FORMAT_R8G8_SNORM,
+   [PIPE_FORMAT_R8G8_SNORM] = { NV50_SURFACE_FORMAT_R8G8_SNORM,
     A_(C0, C1, ZERO, ONE, SNORM, SNORM, SNORM, SNORM, 8_8, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R8_SNORM] = { NV50TCL_RT_FORMAT_R8_SNORM,
+   [PIPE_FORMAT_R8_SNORM] = { NV50_SURFACE_FORMAT_R8_SNORM,
     A_(C0, ZERO, ZERO, ONE, SNORM, SNORM, SNORM, SNORM, 8, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
    /* UNORM 8 */
 
-   [PIPE_FORMAT_R8G8B8A8_UNORM] = { NV50TCL_RT_FORMAT_A8B8G8R8_UNORM,
+   [PIPE_FORMAT_R8G8B8A8_UNORM] = { NV50_SURFACE_FORMAT_A8B8G8R8_UNORM,
     A_(C0, C1, C2, C3, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R8G8B8A8_SRGB] = { NV50TCL_RT_FORMAT_A8B8G8R8_SRGB,
+   [PIPE_FORMAT_R8G8B8A8_SRGB] = { NV50_SURFACE_FORMAT_A8B8G8R8_SRGB,
     A_(C0, C1, C2, C3, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 0),
     SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R8G8B8_UNORM] = { NV50TCL_RT_FORMAT_X8B8G8R8_UNORM,
+   [PIPE_FORMAT_R8G8B8_UNORM] = { NV50_SURFACE_FORMAT_X8B8G8R8_UNORM,
     A_(C0, C1, C2, ONE, UNORM, UNORM, UNORM, UNORM, 8_8_8, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R8G8B8_SRGB] = { NV50TCL_RT_FORMAT_X8B8G8R8_SRGB,
+   [PIPE_FORMAT_R8G8B8_SRGB] = { NV50_SURFACE_FORMAT_X8B8G8R8_SRGB,
     A_(C0, C1, C2, ONE, UNORM, UNORM, UNORM, UNORM, 8_8_8, 0),
     SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R8G8_UNORM] = { NV50TCL_RT_FORMAT_R8G8_UNORM,
+   [PIPE_FORMAT_R8G8_UNORM] = { NV50_SURFACE_FORMAT_R8G8_UNORM,
     A_(C0, C1, ZERO, ONE, UNORM, UNORM, UNORM, UNORM, 8_8, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
-   [PIPE_FORMAT_R8_UNORM] = { NV50TCL_RT_FORMAT_R8_UNORM,
+   [PIPE_FORMAT_R8_UNORM] = { NV50_SURFACE_FORMAT_R8_UNORM,
     A_(C0, ZERO, ZERO, ONE, UNORM, UNORM, UNORM, UNORM, 8, 0),
     VERTEX_BUFFER | SAMPLER_VIEW | RENDER_TARGET },
 
index 309b6503ca52e8a7010ba0626d984257a568336a..a7bd5bcbb6f2af7daa6771bcd233ba64f13088d2 100644 (file)
 #include "nv50_resource.h"
 #include "nv50_transfer.h"
 
-/* The restrictions in tile mode selection probably aren't necessary. */
 static INLINE uint32_t
-get_tile_mode(unsigned ny, unsigned d)
+get_tile_dims(unsigned nx, unsigned ny, unsigned nz)
 {
-       uint32_t tile_mode = 0x00;
-
-       if (ny > 32) tile_mode = 0x04; /* height 64 tiles */
-       else
-       if (ny > 16) tile_mode = 0x03; /* height 32 tiles */
-       else
-       if (ny >  8) tile_mode = 0x02; /* height 16 tiles */
-       else
-       if (ny >  4) tile_mode = 0x01; /* height 8 tiles */
-
-       if (d == 1)
-               return tile_mode;
-       else
-       if (tile_mode > 0x02)
-               tile_mode = 0x02;
-
-       if (d > 16 && tile_mode < 0x02)
-               return tile_mode | 0x50; /* depth 32 tiles */
-       if (d >  8) return tile_mode | 0x40; /* depth 16 tiles */
-       if (d >  4) return tile_mode | 0x30; /* depth 8 tiles */
-       if (d >  2) return tile_mode | 0x20; /* depth 4 tiles */
-
-       return tile_mode | 0x10;
+   uint32_t tile_mode = 0x00;
+
+   if (ny > 32) tile_mode = 0x04; /* height 128 tiles */
+   else
+   if (ny > 16) tile_mode = 0x03; /* height 64 tiles */
+   else
+   if (ny >  8) tile_mode = 0x02; /* height 32 tiles */
+   else
+   if (ny >  4) tile_mode = 0x01; /* height 16 tiles */
+
+   if (nz == 1)
+      return tile_mode;
+   else
+   if (tile_mode > 0x02)
+      tile_mode = 0x02;
+
+   if (nz > 16 && tile_mode < 0x02)
+      return tile_mode | 0x50; /* depth 32 tiles */
+   if (nz > 8) return tile_mode | 0x40; /* depth 16 tiles */
+   if (nz > 4) return tile_mode | 0x30; /* depth 8 tiles */
+   if (nz > 2) return tile_mode | 0x20; /* depth 4 tiles */
+
+   return tile_mode | 0x10;
 }
 
 static INLINE unsigned
-get_zslice_offset(unsigned tile_mode, unsigned z, unsigned pitch, unsigned nb_h)
+calc_zslice_offset(uint32_t tile_mode, unsigned z, unsigned pitch, unsigned nbh)
 {
-       unsigned tile_h = get_tile_height(tile_mode);
-       unsigned tile_d = get_tile_depth(tile_mode);
+   unsigned tile_h = NV50_TILE_HEIGHT(tile_mode);
+   unsigned tile_d_shift = NV50_TILE_DIM_SHIFT(tile_mode, 2);
+   unsigned tile_d = 1 << tile_d_shift;
 
-       /* pitch_2d == to next slice within this volume-tile */
-       /* pitch_3d == size (in bytes) of a volume-tile */
-       unsigned pitch_2d = tile_h * 64;
-       unsigned pitch_3d = tile_d * align(nb_h, tile_h) * pitch;
+   /* stride_2d == to next slice within this volume tile */
+   /* stride_3d == size (in bytes) of a volume tile */
+   unsigned stride_2d = tile_h * NV50_TILE_PITCH(tile_mode);
+   unsigned stride_3d = tile_d * align(nbh, tile_h) * pitch;
 
-       return (z % tile_d) * pitch_2d + (z / tile_d) * pitch_3d;
+   return (z & (tile_d - 1)) * stride_2d + (z >> tile_d_shift) * stride_3d;
 }
 
-
-
-
 static void
-nv50_miptree_destroy(struct pipe_screen *pscreen,
-                    struct pipe_resource *pt)
+nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
 {
-       struct nv50_miptree *mt = nv50_miptree(pt);
-       unsigned l;
+   struct nv50_miptree *mt = nv50_miptree(pt);
 
-       for (l = 0; l <= pt->last_level; ++l)
-               FREE(mt->level[l].image_offset);
+   nouveau_screen_bo_release(pscreen, mt->base.bo);
 
-       nouveau_screen_bo_release(pscreen, mt->base.bo);
-       FREE(mt);
+   FREE(mt);
 }
 
 static boolean
 nv50_miptree_get_handle(struct pipe_screen *pscreen,
-                       struct pipe_resource *pt,
-                       struct winsys_handle *whandle)
+                        struct pipe_resource *pt,
+                        struct winsys_handle *whandle)
 {
-       struct nv50_miptree *mt = nv50_miptree(pt);
-       unsigned stride;
+   struct nv50_miptree *mt = nv50_miptree(pt);
+   unsigned stride;
 
+   if (!mt || !mt->base.bo)
+      return FALSE;
 
-       if (!mt || !mt->base.bo)
-               return FALSE;
+   stride = util_format_get_stride(mt->base.base.format,
+                                   mt->base.base.width0);
 
-       stride = util_format_get_stride(mt->base.base.format,
-                                       mt->base.base.width0);
-
-       return nouveau_screen_bo_get_handle(pscreen,
-                                           mt->base.bo,
-                                           stride,
-                                           whandle);
+   return nouveau_screen_bo_get_handle(pscreen,
+                                       mt->base.bo,
+                                       stride,
+                                       whandle);
 }
 
-
 const struct u_resource_vtbl nv50_miptree_vtbl =
 {
-   nv50_miptree_get_handle,          /* get_handle */
-   nv50_miptree_destroy,             /* resource_destroy */
-   NULL,                             /* is_resource_referenced */
-   nv50_miptree_transfer_new,        /* get_transfer */
-   nv50_miptree_transfer_del,     /* transfer_destroy */
+   nv50_miptree_get_handle,         /* get_handle */
+   nv50_miptree_destroy,            /* resource_destroy */
+   NULL,                            /* is_resource_referenced */
+   nv50_miptree_transfer_new,       /* get_transfer */
+   nv50_miptree_transfer_del,       /* transfer_destroy */
    nv50_miptree_transfer_map,        /* transfer_map */
-   u_default_transfer_flush_region,   /* transfer_flush_region */
-   nv50_miptree_transfer_unmap,              /* transfer_unmap */
-   u_default_transfer_inline_write    /* transfer_inline_write */
+   u_default_transfer_flush_region, /* transfer_flush_region */
+   nv50_miptree_transfer_unmap,     /* transfer_unmap */
+   u_default_transfer_inline_write  /* transfer_inline_write */
 };
 
-
-
 struct pipe_resource *
-nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_resource *tmp)
+nv50_miptree_create(struct pipe_screen *pscreen,
+                    const struct pipe_resource *templ)
 {
-       struct nouveau_device *dev = nouveau_screen(pscreen)->device;
-       struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
-       struct pipe_resource *pt = &mt->base.base;
-       unsigned width = tmp->width0, height = tmp->height0;
-       unsigned depth = tmp->depth0, image_alignment;
-       uint32_t tile_flags;
-       int ret, i, l;
-
-       if (!mt)
-               return NULL;
-
-       *pt = *tmp;
-       mt->base.vtbl = &nv50_miptree_vtbl;
-       pipe_reference_init(&pt->reference, 1);
-       pt->screen = pscreen;
-
-       switch (pt->format) {
-       case PIPE_FORMAT_Z32_FLOAT:
-               tile_flags = 0x4800;
-               break;
-       case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
-               tile_flags = 0x1800;
-               break;
-       case PIPE_FORMAT_Z16_UNORM:
-               tile_flags = 0x6c00;
-               break;
-       case PIPE_FORMAT_Z24X8_UNORM:
-       case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
-               tile_flags = 0x2800;
-               break;
-       case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
-               tile_flags = 0xe000;
-               break;
-       case PIPE_FORMAT_R32G32B32A32_FLOAT:
-       case PIPE_FORMAT_R32G32B32_FLOAT:
-               tile_flags = 0x7400;
-               break;
-       default:
-               if ((pt->bind & PIPE_BIND_SCANOUT) &&
-                   util_format_get_blocksizebits(pt->format) == 32)
-                       tile_flags = 0x7a00;
-               else
-                       tile_flags = 0x7000;
-               break;
-       }
-
-       /* XXX: texture arrays */
-       mt->image_nr = (pt->target == PIPE_TEXTURE_CUBE) ? 6 : 1;
-
-       for (l = 0; l <= pt->last_level; l++) {
-               struct nv50_miptree_level *lvl = &mt->level[l];
-               unsigned nblocksy = util_format_get_nblocksy(pt->format, height);
-
-               lvl->image_offset = CALLOC(mt->image_nr, sizeof(int));
-               lvl->pitch = align(util_format_get_stride(pt->format, width), 64);
-               lvl->tile_mode = get_tile_mode(nblocksy, depth);
-
-               width = u_minify(width, 1);
-               height = u_minify(height, 1);
-               depth = u_minify(depth, 1);
-       }
-
-       image_alignment  = get_tile_height(mt->level[0].tile_mode) * 64;
-       image_alignment *= get_tile_depth(mt->level[0].tile_mode);
-
-       /* NOTE the distinction between arrays of mip-mapped 2D textures and
-        * mip-mapped 3D textures. We can't use image_nr == depth for 3D mip.
-        */
-       for (i = 0; i < mt->image_nr; i++) {
-               for (l = 0; l <= pt->last_level; l++) {
-                       struct nv50_miptree_level *lvl = &mt->level[l];
-                       int size;
-                       unsigned tile_h = get_tile_height(lvl->tile_mode);
-                       unsigned tile_d = get_tile_depth(lvl->tile_mode);
-
-                       size  = lvl->pitch;
-                       size *= align(util_format_get_nblocksy(pt->format, u_minify(pt->height0, l)), tile_h);
-                       size *= align(u_minify(pt->depth0, l), tile_d);
-
-                       lvl->image_offset[i] = mt->total_size;
-
-                       mt->total_size += size;
-               }
-               mt->total_size = align(mt->total_size, image_alignment);
-       }
-
-       ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, mt->total_size,
-                                 mt->level[0].tile_mode, tile_flags,
-                                 &mt->base.bo);
-       if (ret) {
-               for (l = 0; l <= pt->last_level; ++l)
-                       FREE(mt->level[l].image_offset);
-               FREE(mt);
-               return NULL;
-       }
-
-       return pt;
+   struct nouveau_device *dev = nouveau_screen(pscreen)->device;
+   struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
+   struct pipe_resource *pt = &mt->base.base;
+   int ret;
+   unsigned w, h, d, l, alloc_size;
+   uint32_t tile_flags;
+
+   if (!mt)
+      return NULL;
+
+   mt->base.vtbl = &nv50_miptree_vtbl;
+   *pt = *templ;
+   pipe_reference_init(&pt->reference, 1);
+   pt->screen = pscreen;
+
+   mt->layout_3d = pt->target == PIPE_TEXTURE_3D;
+
+   w = pt->width0;
+   h = pt->height0;
+   d = mt->layout_3d ? pt->depth0 : 1;
+
+   switch (pt->format) {
+   case PIPE_FORMAT_Z16_UNORM:
+      tile_flags = 0x6c00;
+      break;
+   case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+      tile_flags = 0x1800;
+      break;
+   case PIPE_FORMAT_Z24X8_UNORM:
+   case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+      tile_flags = 0x2800;
+      break;
+   case PIPE_FORMAT_R32G32B32A32_FLOAT:
+   case PIPE_FORMAT_R32G32B32_FLOAT:
+      tile_flags = 0x7400;
+      break;
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED:
+      tile_flags = 0x6000;
+      break;
+   case PIPE_FORMAT_R16G16B16A16_UNORM:
+      tile_flags = 0xe900; /* COMPRESSED */
+      break;
+   default:
+      if ((pt->bind & PIPE_BIND_SCANOUT) &&
+          util_format_get_blocksizebits(pt->format) == 32)
+         tile_flags = 0x7a00;
+      else
+         tile_flags = 0x7000;
+      break;
+   }
+
+   /* For 3D textures, a mipmap is spanned by all the layers, for array
+    * textures and cube maps, each layer contains its own mipmaps.
+    */
+   for (l = 0; l <= pt->last_level; ++l) {
+      struct nv50_miptree_level *lvl = &mt->level[l];
+      unsigned nbx = util_format_get_nblocksx(pt->format, w);
+      unsigned nby = util_format_get_nblocksy(pt->format, h);
+      unsigned blocksize = util_format_get_blocksize(pt->format);
+
+      lvl->offset = mt->total_size;
+      lvl->tile_mode = get_tile_dims(nbx, nby, d);
+      lvl->pitch = align(nbx * blocksize, NV50_TILE_PITCH(lvl->tile_mode));
+
+      mt->total_size += lvl->pitch *
+         align(nby, NV50_TILE_HEIGHT(lvl->tile_mode)) *
+         align(d, NV50_TILE_DEPTH(lvl->tile_mode));
+
+      w = u_minify(w, 1);
+      h = u_minify(h, 1);
+      d = u_minify(d, 1);
+   }
+
+   if (pt->array_size > 1) {
+      mt->layer_stride = align(mt->total_size,
+                               NV50_TILE_SIZE(mt->level[0].tile_mode));
+      mt->total_size = mt->layer_stride * pt->array_size;
+   }
+
+   alloc_size = mt->total_size;
+
+   ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, alloc_size,
+                             mt->level[0].tile_mode, tile_flags,
+                             &mt->base.bo);
+   if (ret) {
+      FREE(mt);
+      return NULL;
+   }
+   mt->base.domain = NOUVEAU_BO_VRAM;
+
+   return pt;
 }
 
-
 struct pipe_resource *
 nv50_miptree_from_handle(struct pipe_screen *pscreen,
-                        const struct pipe_resource *template,
-                        struct winsys_handle *whandle)
+                         const struct pipe_resource *templ,
+                         struct winsys_handle *whandle)
 {
-       struct nv50_miptree *mt;
-       unsigned stride;
-
-       /* Only supports 2D, non-mipmapped textures for the moment */
-       if ((template->target != PIPE_TEXTURE_2D &&
-             template->target != PIPE_TEXTURE_RECT) ||
-           template->last_level != 0 ||
-           template->depth0 != 1)
-               return NULL;
-
-       mt = CALLOC_STRUCT(nv50_miptree);
-       if (!mt)
-               return NULL;
-
-       mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride);
-       if (mt->base.bo == NULL) {
-               FREE(mt);
-               return NULL;
-       }
-
-
-       mt->base.base = *template;
-       mt->base.vtbl = &nv50_miptree_vtbl;
-       pipe_reference_init(&mt->base.base.reference, 1);
-       mt->base.base.screen = pscreen;
-       mt->image_nr = 1;
-       mt->level[0].pitch = stride;
-       mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
-       mt->level[0].tile_mode = mt->base.bo->tile_mode;
-
-       /* XXX: Need to adjust bo refcount??
-        */
-       /* nouveau_bo_ref(bo, &mt->base.bo); */
-       return &mt->base.base;
+   struct nv50_miptree *mt;
+   unsigned stride;
+
+   /* only supports 2D, non-mipmapped textures for the moment */
+   if ((templ->target != PIPE_TEXTURE_2D &&
+        templ->target != PIPE_TEXTURE_RECT) ||
+       templ->last_level != 0 ||
+       templ->depth0 != 1 ||
+       templ->array_size > 1)
+      return NULL;
+
+   mt = CALLOC_STRUCT(nv50_miptree);
+   if (!mt)
+      return NULL;
+
+   mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride);
+   if (mt->base.bo == NULL) {
+      FREE(mt);
+      return NULL;
+   }
+
+   mt->base.base = *templ;
+   mt->base.vtbl = &nv50_miptree_vtbl;
+   pipe_reference_init(&mt->base.base.reference, 1);
+   mt->base.base.screen = pscreen;
+   mt->level[0].pitch = stride;
+   mt->level[0].offset = 0;
+   mt->level[0].tile_mode = mt->base.bo->tile_mode;
+
+   /* no need to adjust bo reference count */
+   return &mt->base.base;
 }
 
 
-
-/* Surface functions
+/* Surface functions.
  */
 
 struct pipe_surface *
-nv50_miptree_surface_new(struct pipe_context *pipe, struct pipe_resource *pt,
-                        const struct pipe_surface *surf_tmpl)
+nv50_miptree_surface_new(struct pipe_context *pipe,
+                         struct pipe_resource *pt,
+                         const struct pipe_surface *templ)
 {
-       unsigned level = surf_tmpl->u.tex.level;
-       struct nv50_miptree *mt = nv50_miptree(pt);
-       struct nv50_miptree_level *lvl = &mt->level[level];
-       struct nv50_surface *ns;
-       unsigned img = 0, zslice = 0;
-
-       assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
-
-       /* XXX can't unify these here? */
-       if (pt->target == PIPE_TEXTURE_CUBE)
-               img = surf_tmpl->u.tex.first_layer;
-       else if (pt->target == PIPE_TEXTURE_3D)
-               zslice = surf_tmpl->u.tex.first_layer;
-
-       ns = CALLOC_STRUCT(nv50_surface);
-       if (!ns)
-               return NULL;
-       pipe_resource_reference(&ns->base.texture, pt);
-       ns->base.context = pipe;
-       ns->base.format = pt->format;
-       ns->base.width = u_minify(pt->width0, level);
-       ns->base.height = u_minify(pt->height0, level);
-       ns->base.usage = surf_tmpl->usage;
-       pipe_reference_init(&ns->base.reference, 1);
-       ns->base.u.tex.level = level;
-       ns->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
-       ns->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
-       ns->offset = lvl->image_offset[img];
-
-       if (pt->target == PIPE_TEXTURE_3D) {
-               unsigned nb_h = util_format_get_nblocksy(pt->format, ns->base.height);
-               ns->offset += get_zslice_offset(lvl->tile_mode, zslice,
-                                               lvl->pitch, nb_h);
-       }
-
-       return &ns->base;
+   struct nv50_miptree *mt = nv50_miptree(pt); /* guaranteed */
+   struct nv50_surface *ns;
+   struct pipe_surface *ps;
+   struct nv50_miptree_level *lvl = &mt->level[templ->u.tex.level];
+
+   ns = CALLOC_STRUCT(nv50_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 = templ->format;
+   ps->usage = templ->usage;
+   ps->u.tex.level = templ->u.tex.level;
+   ps->u.tex.first_layer = templ->u.tex.first_layer;
+   ps->u.tex.last_layer = templ->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 = lvl->offset;
+
+   /* comment says there are going to be removed, but they're used by the st */
+   ps->width = ns->width;
+   ps->height = ns->height;
+
+   if (mt->layout_3d) {
+      unsigned zslice = ps->u.tex.first_layer;
+
+      /* TODO: re-layout the texture to use only depth 1 tiles in this case: */
+      if (ns->depth > 1 && (zslice & (NV50_TILE_DEPTH(lvl->tile_mode) - 1)))
+         NOUVEAU_ERR("Creating unsupported 3D surface of slices [%u:%u].\n",
+                     zslice, ps->u.tex.last_layer);
+
+      ns->offset += calc_zslice_offset(lvl->tile_mode, zslice, lvl->pitch,
+                                       util_format_get_nblocksy(pt->format,
+                                                                ns->height));
+   } else {
+      ns->offset += mt->layer_stride * ps->u.tex.first_layer;
+   }
+
+   return ps;
 }
 
 void
-nv50_miptree_surface_del(struct pipe_context *pipe,
-                        struct pipe_surface *ps)
+nv50_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps)
 {
-       struct nv50_surface *s = nv50_surface(ps);
+   struct nv50_surface *s = nv50_surface(ps);
+
+   pipe_resource_reference(&ps->texture, NULL);
 
-       pipe_resource_reference(&s->base.texture, NULL);
-       FREE(s);
+   FREE(s);
 }
diff --git a/src/gallium/drivers/nv50/nv50_mm.c b/src/gallium/drivers/nv50/nv50_mm.c
new file mode 100644 (file)
index 0000000..f991d61
--- /dev/null
@@ -0,0 +1,277 @@
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_double_list.h"
+
+#include "nv50_screen.h"
+
+#define MM_MIN_ORDER 7
+#define MM_MAX_ORDER 20
+
+#define MM_NUM_BUCKETS (MM_MAX_ORDER - MM_MIN_ORDER + 1)
+
+#define MM_MIN_SIZE (1 << MM_MIN_ORDER)
+#define MM_MAX_SIZE (1 << MM_MAX_ORDER)
+
+struct mm_bucket {
+   struct list_head free;
+   struct list_head used;
+   struct list_head full;
+   int num_free;
+};
+
+struct nv50_mman {
+   struct nouveau_device *dev;
+   struct mm_bucket bucket[MM_NUM_BUCKETS];
+   uint32_t storage_type;
+   uint32_t domain;
+   uint64_t allocated;
+};
+
+struct mm_slab {
+   struct list_head head;
+   struct nouveau_bo *bo;
+   struct nv50_mman *cache;
+   int order;
+   int count;
+   int free;
+   uint32_t bits[0];
+};
+
+static int
+mm_slab_alloc(struct mm_slab *slab)
+{
+   int i, n, b;
+
+   if (slab->free == 0)
+      return -1;
+
+   for (i = 0; i < (slab->count + 31) / 32; ++i) {
+      b = ffs(slab->bits[i]) - 1;
+      if (b >= 0) {
+         n = i * 32 + b;
+         assert(n < slab->count);
+         slab->free--;
+         slab->bits[i] &= ~(1 << b);
+         return n;
+      }
+   }
+   return -1;
+}
+
+static INLINE void
+mm_slab_free(struct mm_slab *slab, int i)
+{
+   assert(i < slab->count);
+   slab->bits[i / 32] |= 1 << (i % 32);
+   slab->free++;
+   assert(slab->free <= slab->count);
+}
+
+static INLINE int
+mm_get_order(uint32_t size)
+{
+   int s = __builtin_clz(size) ^ 31;
+
+   if (size > (1 << s))
+      s += 1;
+   return s;
+}
+
+static struct mm_bucket *
+mm_bucket_by_order(struct nv50_mman *cache, int order)
+{
+   if (order > MM_MAX_ORDER)
+      return NULL;
+   return &cache->bucket[MAX2(order, MM_MIN_ORDER) - MM_MIN_ORDER];
+}
+
+static struct mm_bucket *
+mm_bucket_by_size(struct nv50_mman *cache, unsigned size)
+{
+   return mm_bucket_by_order(cache, mm_get_order(size));
+}
+
+/* size of bo allocation for slab with chunks of (1 << chunk_order) bytes */
+static INLINE uint32_t
+mm_default_slab_size(unsigned chunk_order)
+{
+   static const int8_t slab_order[MM_MAX_ORDER - MM_MIN_ORDER + 1] =
+   {
+      12, 12, 13, 14, 14, 17, 17, 17, 17, 19, 19, 20, 21, 22
+   };
+
+   assert(chunk_order <= MM_MAX_ORDER && chunk_order >= MM_MIN_ORDER);
+
+   return 1 << slab_order[chunk_order - MM_MIN_ORDER];
+}
+
+static int
+mm_slab_new(struct nv50_mman *cache, int chunk_order)
+{
+   struct mm_slab *slab;
+   int words, ret;
+   const uint32_t size = mm_default_slab_size(chunk_order);
+
+   words = ((size >> chunk_order) + 31) / 32;
+   assert(words);
+
+   slab = MALLOC(sizeof(struct mm_slab) + words * 4);
+   if (!slab)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   memset(&slab->bits[0], ~0, words * 4);
+
+   slab->bo = NULL;
+   ret = nouveau_bo_new_tile(cache->dev, cache->domain, 0, size,
+                             0, cache->storage_type, &slab->bo);
+   if (ret) {
+      FREE(slab);
+      return PIPE_ERROR_OUT_OF_MEMORY;
+   }
+
+   LIST_INITHEAD(&slab->head);
+
+   slab->cache = cache;
+   slab->order = chunk_order;
+   slab->count = slab->free = size >> chunk_order;
+
+   LIST_ADD(&slab->head, &mm_bucket_by_order(cache, chunk_order)->free);
+
+   cache->allocated += size;
+
+   debug_printf("MM: new slab, total memory = %lu KiB\n",
+                cache->allocated / 1024);
+
+   return PIPE_OK;
+}
+
+/* @return token to identify slab or NULL if we just allocated a new bo */
+struct nv50_mm_allocation *
+nv50_mm_allocate(struct nv50_mman *cache,
+                 uint32_t size, struct nouveau_bo **bo, uint32_t *offset)
+{
+   struct mm_bucket *bucket;
+   struct mm_slab *slab;
+   struct nv50_mm_allocation *alloc;
+   int ret;
+
+   bucket = mm_bucket_by_size(cache, size);
+   if (!bucket) {
+      ret = nouveau_bo_new_tile(cache->dev, cache->domain, 0, size,
+                                0, cache->storage_type, bo);
+      if (ret)
+         debug_printf("bo_new(%x, %x): %i\n", size, cache->storage_type, ret);
+
+      *offset = 0;
+      return NULL;
+   }
+
+   if (!LIST_IS_EMPTY(&bucket->used)) {
+      slab = LIST_ENTRY(struct mm_slab, bucket->used.next, head);
+   } else {
+      if (LIST_IS_EMPTY(&bucket->free)) {
+         mm_slab_new(cache, MAX2(mm_get_order(size), MM_MIN_ORDER));
+      }
+      slab = LIST_ENTRY(struct mm_slab, bucket->free.next, head);
+
+      LIST_DEL(&slab->head);
+      LIST_ADD(&slab->head, &bucket->used);
+   }
+
+   *offset = mm_slab_alloc(slab) << slab->order;
+
+   alloc = MALLOC_STRUCT(nv50_mm_allocation);
+   if (!alloc)
+      return NULL;
+
+   nouveau_bo_ref(slab->bo, bo);
+
+   if (slab->free == 0) {
+      LIST_DEL(&slab->head);
+      LIST_ADD(&slab->head, &bucket->full);
+   }
+
+   alloc->next = NULL;
+   alloc->offset = *offset;
+   alloc->priv = (void *)slab;
+
+   return alloc;
+}
+
+void
+nv50_mm_free(struct nv50_mm_allocation *alloc)
+{
+   struct mm_slab *slab = (struct mm_slab *)alloc->priv;
+   struct mm_bucket *bucket = mm_bucket_by_order(slab->cache, slab->order);
+
+   mm_slab_free(slab, alloc->offset >> slab->order);
+
+   if (slab->free == 1) {
+      LIST_DEL(&slab->head);
+
+      if (slab->count > 1)
+         LIST_ADDTAIL(&slab->head, &bucket->used);
+      else
+         LIST_ADDTAIL(&slab->head, &bucket->free);
+   }
+
+   FREE(alloc);
+}
+
+struct nv50_mman *
+nv50_mm_create(struct nouveau_device *dev, uint32_t domain,
+               uint32_t storage_type)
+{
+   struct nv50_mman *cache = MALLOC_STRUCT(nv50_mman);
+   int i;
+
+   if (!cache)
+      return NULL;
+
+   cache->dev = dev;
+   cache->domain = domain;
+   cache->storage_type = storage_type;
+   cache->allocated = 0;
+
+   for (i = 0; i < MM_NUM_BUCKETS; ++i) {
+      LIST_INITHEAD(&cache->bucket[i].free);
+      LIST_INITHEAD(&cache->bucket[i].used);
+      LIST_INITHEAD(&cache->bucket[i].full);
+   }
+
+   return cache;
+}
+
+static INLINE void
+nv50_mm_free_slabs(struct list_head *head)
+{
+   struct mm_slab *slab, *next;
+
+   LIST_FOR_EACH_ENTRY_SAFE(slab, next, head, head) {
+      LIST_DEL(&slab->head);
+      nouveau_bo_ref(NULL, &slab->bo);
+      FREE(slab);
+   }
+}
+
+void
+nv50_mm_destroy(struct nv50_mman *cache)
+{
+   int i;
+
+   if (!cache)
+      return;
+
+   for (i = 0; i < MM_NUM_BUCKETS; ++i) {
+      if (!LIST_IS_EMPTY(&cache->bucket[i].used) ||
+          !LIST_IS_EMPTY(&cache->bucket[i].full))
+         debug_printf("WARNING: destroying GPU memory cache "
+                      "with some buffers still in use\n");
+
+      nv50_mm_free_slabs(&cache->bucket[i].free);
+      nv50_mm_free_slabs(&cache->bucket[i].used);
+      nv50_mm_free_slabs(&cache->bucket[i].full);
+   }
+}
+
index c88e7ba742e68ce24516c12f3566a83b4830dc9f..82f1b84652760bd0a36e789f474bcd3a0934e9d6 100644 (file)
@@ -307,7 +307,10 @@ nv_pc_pass_in_order(struct nv_basic_block *root, nv_pc_pass_func f, void *priv)
             bb[p++] = b->out[j];
             break;
          case CFG_EDGE_LOOP_LEAVE:
-            bbb[pp++] = b->out[j];
+            if (!b->out[j]->priv) {
+               bbb[pp++] = b->out[j];
+               b->out[j]->priv = 1;
+            }
             break;
          default:
             assert(0);
index 2ead80430b0df49e8b82a23fa888c2a7aefdd3f3..e6f3815bafea7a152d631c416473f88a3907f217 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef __NV50_COMPILER_H__
 #define __NV50_COMPILER_H__
 
+#define NV50PC_DEBUG
+
 #ifdef NV50PC_DEBUG
 # define NV50_DBGMSG(args...) debug_printf(args)
 #else
index 679e5ea14856ffdaae8299e220c80657f6555de3..281ccf7ac611585e76ce54f328e0aac56fb971ca 100644 (file)
@@ -145,8 +145,9 @@ nv_pc_pass_pre_emission(void *priv, struct nv_basic_block *b)
    int j;
    uint size, n32 = 0;
 
+   /* find first non-empty block emitted before b */
    for (j = pc->num_blocks - 1; j >= 0 && !pc->bb_list[j]->bin_size; --j);
-   if (j >= 0) {
+   for (; j >= 0; --j) {
       in = pc->bb_list[j];
 
       /* check for no-op branches (BRA $PC+8) */
@@ -160,6 +161,9 @@ nv_pc_pass_pre_emission(void *priv, struct nv_basic_block *b)
          nv_nvi_delete(in->exit);
       }
       b->bin_pos = in->bin_pos + in->bin_size;
+
+      if (in->bin_size) /* no more no-op branches to b */
+         break;
    }
 
    pc->bb_list[pc->num_blocks++] = b;
index db681764910a2e536b46a018ba240775f9cf672f..1c1a4201b60d1dbfd62637f5324ef35f3cb9ab90 100644 (file)
@@ -411,11 +411,11 @@ nv50_fragprog_prepare(struct nv50_translation_info *ti)
 
    if (ti->scan.writes_z) {
       p->fp.flags[1] = 0x11;
-      p->fp.flags[0] |= NV50TCL_FP_CONTROL_EXPORTS_Z;
+      p->fp.flags[0] |= NV50_3D_FP_CONTROL_EXPORTS_Z;
    }
 
    if (ti->scan.uses_kill)
-      p->fp.flags[0] |= NV50TCL_FP_CONTROL_USES_KIL;
+      p->fp.flags[0] |= NV50_3D_FP_CONTROL_USES_KIL;
 
    /* FP inputs */
 
@@ -490,13 +490,13 @@ nv50_fragprog_prepare(struct nv50_translation_info *ti)
    if (n < m)
       nvary -= p->in[n].hw;
 
-   p->fp.interp |= nvary << NV50TCL_FP_INTERPOLANT_CTRL_COUNT_NONFLAT_SHIFT;
-   p->fp.interp |= nintp << NV50TCL_FP_INTERPOLANT_CTRL_COUNT_SHIFT;
+   p->fp.interp |= nvary << NV50_3D_FP_INTERPOLANT_CTRL_COUNT_NONFLAT__SHIFT;
+   p->fp.interp |= nintp << NV50_3D_FP_INTERPOLANT_CTRL_COUNT__SHIFT;
 
    /* FP outputs */
 
    if (p->out_nr > (1 + (ti->scan.writes_z ? 1 : 0)))
-      p->fp.flags[0] |= NV50TCL_FP_CONTROL_MULTIPLE_RESULTS;
+      p->fp.flags[0] |= NV50_3D_FP_CONTROL_MULTIPLE_RESULTS;
 
    depr = p->out_nr;
    for (i = 0; i < p->out_nr; ++i) {
@@ -608,7 +608,7 @@ nv50_prog_scan(struct nv50_translation_info *ti)
 }
 
 boolean
-nv50_program_tx(struct nv50_program *p)
+nv50_program_translate(struct nv50_program *p)
 {
    struct nv50_translation_info *ti;
    int ret;
@@ -646,9 +646,8 @@ out:
 void
 nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
 {
-   nouveau_bo_ref(NULL, &p->bo);
-
-   so_ref(NULL, &p->so);
+   if (p->res)
+      nouveau_resource_free(&p->res);
 
    if (p->code)
       FREE(p->code);
index 33c4c8ca6df6fe69349ada5e6105e7b5a8cd45c2..8f5b51757d82c1042dcafe45c4d2580d75b869b2 100644 (file)
@@ -47,12 +47,9 @@ struct nv50_program {
    boolean translated;
    boolean uses_lmem;
 
-   struct nouveau_bo *bo;
-   struct nouveau_stateobj *so;
-
    uint32_t *code;
    unsigned code_size;
-   unsigned code_start; /* offset inside bo */
+   unsigned code_base;
    uint32_t *immd;
    unsigned immd_size;
    unsigned parm_size; /* size limit of uniform buffer */
@@ -89,6 +86,8 @@ struct nv50_program {
    /* relocation records */
    void *fixups;
    unsigned num_fixups;
+
+   struct nouveau_resource *res;
 };
 
 #define NV50_INTERP_LINEAR   (1 << 0)
index 380f69406a27d8925d3be34e4fdda4bd89ac06b0..51ada6d749909c008130f41e7ea75ba680b8d777 100644 (file)
+
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "util/u_inlines.h"
 #include "util/u_format.h"
-#include "util/u_split_prim.h"
+#include "translate/translate.h"
 
 #include "nv50_context.h"
 #include "nv50_resource.h"
 
-struct push_context {
-   struct nv50_context *nv50;
+#include "nv50_3d.xml.h"
 
-   unsigned vtx_size;
+struct push_context {
+   struct nouveau_channel *chan;
 
    void *idxbuf;
-   int32_t idxbias;
-   unsigned idxsize;
 
    float edgeflag;
    int edgeflag_attr;
 
-   struct {
-      void *map;
-      unsigned stride;
-      unsigned divisor;
-      unsigned step;
-      void (*push)(struct nouveau_channel *, void *);
-   } attr[16];
-   unsigned attr_nr;
+   uint32_t vertex_words;
+   uint32_t packet_vertex_limit;
+
+   struct translate *translate;
+
+   boolean primitive_restart;
+   uint32_t prim;
+   uint32_t restart_index;
+   uint32_t instance_id;
 };
 
-static void
-emit_b32_1(struct nouveau_channel *chan, void *data)
+static INLINE unsigned
+prim_restart_search_i08(uint8_t *elts, unsigned push, uint8_t index)
 {
-   uint32_t *v = data;
-
-   OUT_RING(chan, v[0]);
+   unsigned i;
+   for (i = 0; i < push; ++i)
+      if (elts[i] == index)
+         break;
+   return i;
 }
 
-static void
-emit_b32_2(struct nouveau_channel *chan, void *data)
+static INLINE unsigned
+prim_restart_search_i16(uint16_t *elts, unsigned push, uint16_t index)
 {
-   uint32_t *v = data;
-
-   OUT_RING(chan, v[0]);
-   OUT_RING(chan, v[1]);
+   unsigned i;
+   for (i = 0; i < push; ++i)
+      if (elts[i] == index)
+         break;
+   return i;
 }
 
-static void
-emit_b32_3(struct nouveau_channel *chan, void *data)
+static INLINE unsigned
+prim_restart_search_i32(uint32_t *elts, unsigned push, uint32_t index)
 {
-   uint32_t *v = data;
-
-   OUT_RING(chan, v[0]);
-   OUT_RING(chan, v[1]);
-   OUT_RING(chan, v[2]);
+   unsigned i;
+   for (i = 0; i < push; ++i)
+      if (elts[i] == index)
+         break;
+   return i;
 }
 
 static void
-emit_b32_4(struct nouveau_channel *chan, void *data)
+emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
 {
-   uint32_t *v = data;
+   uint8_t *elts = (uint8_t *)ctx->idxbuf + start;
 
-   OUT_RING(chan, v[0]);
-   OUT_RING(chan, v[1]);
-   OUT_RING(chan, v[2]);
-   OUT_RING(chan, v[3]);
-}
+   while (count) {
+      unsigned push = MIN2(count, ctx->packet_vertex_limit);
+      unsigned size, nr;
 
-static void
-emit_b16_1(struct nouveau_channel *chan, void *data)
-{
-   uint16_t *v = data;
+      nr = push;
+      if (ctx->primitive_restart)
+         nr = prim_restart_search_i08(elts, push, ctx->restart_index);
 
-   OUT_RING(chan, v[0]);
-}
+      size = ctx->vertex_words * nr;
 
-static void
-emit_b16_3(struct nouveau_channel *chan, void *data)
-{
-   uint16_t *v = data;
+      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
 
-   OUT_RING(chan, (v[1] << 16) | v[0]);
-   OUT_RING(chan, v[2]);
-}
+      ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id,
+                                ctx->chan->cur);
 
-static void
-emit_b08_1(struct nouveau_channel *chan, void *data)
-{
-   uint8_t *v = data;
+      ctx->chan->cur += size;
+      count -= nr;
+      elts += nr;
 
-   OUT_RING(chan, v[0]);
+      if (nr != push) {
+         count--;
+         elts++;
+         BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
+         OUT_RING  (ctx->chan, 0);
+         OUT_RING  (ctx->chan, NVA0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
+                    (ctx->prim & ~NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
+      }
+   }
 }
 
 static void
-emit_b08_3(struct nouveau_channel *chan, void *data)
+emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
 {
-   uint8_t *v = data;
+   uint16_t *elts = (uint16_t *)ctx->idxbuf + start;
 
-   OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]);
-}
+   while (count) {
+      unsigned push = MIN2(count, ctx->packet_vertex_limit);
+      unsigned size, nr;
 
-static INLINE void
-emit_vertex(struct push_context *ctx, unsigned n)
-{
-   struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
-   struct nouveau_channel *chan = tesla->channel;
-   int i;
-
-   if (ctx->edgeflag_attr < 16) {
-      float *edgeflag = (float *)
-         ((uint8_t *)ctx->attr[ctx->edgeflag_attr].map +
-          ctx->attr[ctx->edgeflag_attr].stride * n);
-
-      if (*edgeflag != ctx->edgeflag) {
-         BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
-         OUT_RING  (chan, *edgeflag ? 1 : 0);
-         ctx->edgeflag = *edgeflag;
-      }
-   }
+      nr = push;
+      if (ctx->primitive_restart)
+         nr = prim_restart_search_i16(elts, push, ctx->restart_index);
 
-   BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, ctx->vtx_size);
-   for (i = 0; i < ctx->attr_nr; i++)
-      ctx->attr[i].push(chan,
-                       (uint8_t *)ctx->attr[i].map + ctx->attr[i].stride * n);
-}
+      size = ctx->vertex_words * nr;
 
-static void
-emit_edgeflag(void *priv, boolean enabled)
-{
-   struct push_context *ctx = priv;
-   struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
-   struct nouveau_channel *chan = tesla->channel;
+      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
 
-   BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
-   OUT_RING  (chan, enabled ? 1 : 0);
-}
+      ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id,
+                                 ctx->chan->cur);
 
-static void
-emit_elt08(void *priv, unsigned start, unsigned count)
-{
-   struct push_context *ctx = priv;
-   uint8_t *idxbuf = ctx->idxbuf;
+      ctx->chan->cur += size;
+      count -= nr;
+      elts += nr;
 
-   while (count--)
-      emit_vertex(ctx, idxbuf[start++]);
+      if (nr != push) {
+         count--;
+         elts++;
+         BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
+         OUT_RING  (ctx->chan, 0);
+         OUT_RING  (ctx->chan, NVA0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
+                    (ctx->prim & ~NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
+      }
+   }
 }
 
 static void
-emit_elt08_biased(void *priv, unsigned start, unsigned count)
+emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
 {
-   struct push_context *ctx = priv;
-   uint8_t *idxbuf = ctx->idxbuf;
+   uint32_t *elts = (uint32_t *)ctx->idxbuf + start;
 
-   while (count--)
-      emit_vertex(ctx, idxbuf[start++] + ctx->idxbias);
-}
+   while (count) {
+      unsigned push = MIN2(count, ctx->packet_vertex_limit);
+      unsigned size, nr;
 
-static void
-emit_elt16(void *priv, unsigned start, unsigned count)
-{
-   struct push_context *ctx = priv;
-   uint16_t *idxbuf = ctx->idxbuf;
+      nr = push;
+      if (ctx->primitive_restart)
+         nr = prim_restart_search_i32(elts, push, ctx->restart_index);
 
-   while (count--)
-      emit_vertex(ctx, idxbuf[start++]);
-}
+      size = ctx->vertex_words * nr;
 
-static void
-emit_elt16_biased(void *priv, unsigned start, unsigned count)
-{
-   struct push_context *ctx = priv;
-   uint16_t *idxbuf = ctx->idxbuf;
+      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
 
-   while (count--)
-      emit_vertex(ctx, idxbuf[start++] + ctx->idxbias);
-}
+      ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id,
+                               ctx->chan->cur);
 
-static void
-emit_elt32(void *priv, unsigned start, unsigned count)
-{
-   struct push_context *ctx = priv;
-   uint32_t *idxbuf = ctx->idxbuf;
+      ctx->chan->cur += size;
+      count -= nr;
+      elts += nr;
 
-   while (count--)
-      emit_vertex(ctx, idxbuf[start++]);
+      if (nr != push) {
+         count--;
+         elts++;
+         BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
+         OUT_RING  (ctx->chan, 0);
+         OUT_RING  (ctx->chan, NVA0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
+                    (ctx->prim & ~NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
+      }
+   }
 }
 
 static void
-emit_elt32_biased(void *priv, unsigned start, unsigned count)
+emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
 {
-   struct push_context *ctx = priv;
-   uint32_t *idxbuf = ctx->idxbuf;
+   while (count) {
+      unsigned push = MIN2(count, ctx->packet_vertex_limit);
+      unsigned size = ctx->vertex_words * push;
+
+      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
 
-   while (count--)
-      emit_vertex(ctx, idxbuf[start++] + ctx->idxbias);
+      ctx->translate->run(ctx->translate, start, push, ctx->instance_id,
+                          ctx->chan->cur);
+      ctx->chan->cur += size;
+      count -= push;
+      start += push;
+   }
 }
 
-static void
-emit_verts(void *priv, unsigned start, unsigned count)
+
+#define NV50_PRIM_GL_CASE(n) \
+   case PIPE_PRIM_##n: return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n
+
+static INLINE unsigned
+nv50_prim_gl(unsigned prim)
 {
-   while (count--)
-      emit_vertex(priv, start++);
+   switch (prim) {
+   NV50_PRIM_GL_CASE(POINTS);
+   NV50_PRIM_GL_CASE(LINES);
+   NV50_PRIM_GL_CASE(LINE_LOOP);
+   NV50_PRIM_GL_CASE(LINE_STRIP);
+   NV50_PRIM_GL_CASE(TRIANGLES);
+   NV50_PRIM_GL_CASE(TRIANGLE_STRIP);
+   NV50_PRIM_GL_CASE(TRIANGLE_FAN);
+   NV50_PRIM_GL_CASE(QUADS);
+   NV50_PRIM_GL_CASE(QUAD_STRIP);
+   NV50_PRIM_GL_CASE(POLYGON);
+   NV50_PRIM_GL_CASE(LINES_ADJACENCY);
+   NV50_PRIM_GL_CASE(LINE_STRIP_ADJACENCY);
+   NV50_PRIM_GL_CASE(TRIANGLES_ADJACENCY);
+   NV50_PRIM_GL_CASE(TRIANGLE_STRIP_ADJACENCY);
+   /*
+   NV50_PRIM_GL_CASE(PATCHES); */
+   default:
+      return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS;
+      break;
+   }
 }
 
 void
-nv50_push_elements_instanced(struct pipe_context *pipe,
-                             struct pipe_resource *idxbuf,
-                             unsigned idxsize, int idxbias,
-                             unsigned mode, unsigned start, unsigned count,
-                             unsigned i_start, unsigned i_count)
+nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
 {
-   struct nv50_context *nv50 = nv50_context(pipe);
-   struct nouveau_grobj *tesla = nv50->screen->tesla;
-   struct nouveau_channel *chan = tesla->channel;
    struct push_context ctx;
-   const unsigned p_overhead = 4 + /* begin/end */
-                               4; /* potential edgeflag enable/disable */
-   const unsigned v_overhead = 1 + /* VERTEX_DATA packet header */
-                               2; /* potential edgeflag modification */
-   struct util_split_prim s;
-   unsigned vtx_size;
-   boolean nzi = FALSE;
-   int i;
-
-   ctx.nv50 = nv50;
-   ctx.attr_nr = 0;
-   ctx.idxbuf = NULL;
-   ctx.vtx_size = 0;
-   ctx.edgeflag = 0.5f;
-   ctx.edgeflag_attr = nv50->vertprog->vp.edgeflag;
-
-   /* map vertex buffers, determine vertex size */
-   for (i = 0; i < nv50->vtxelt->num_elements; i++) {
-      struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
-      struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index];
-      struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo;
-      unsigned size, nr_components, n;
-
-      if (!(nv50->vbo_fifo & (1 << i)))
-         continue;
-      n = ctx.attr_nr++;
-
-      if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
-         assert(bo->map);
+   unsigned i, index_size;
+   unsigned inst = info->instance_count;
+   boolean apply_bias = info->indexed && info->index_bias;
+
+   ctx.chan = nv50->screen->base.channel;
+   ctx.translate = nv50->vertex->translate;
+   ctx.packet_vertex_limit = nv50->vertex->packet_vertex_limit;
+   ctx.vertex_words = nv50->vertex->vertex_size;
+
+   for (i = 0; i < nv50->num_vtxbufs; ++i) {
+      uint8_t *data;
+      struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i];
+      struct nv50_resource *res = nv50_resource(vb->buffer);
+
+      data = nv50_resource_map_offset(nv50, res,
+                                      vb->buffer_offset, NOUVEAU_BO_RD);
+
+      if (apply_bias && likely(!(nv50->vertex->instance_bufs & (1 << i))))
+         data += info->index_bias * vb->stride;
+
+      ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0);
+   }
+
+   if (info->indexed) {
+      ctx.idxbuf = nv50_resource_map_offset(nv50,
+                                            nv50_resource(nv50->idxbuf.buffer),
+                                            nv50->idxbuf.offset, NOUVEAU_BO_RD);
+      if (!ctx.idxbuf)
          return;
-      }
-      ctx.attr[n].map = (uint8_t *)bo->map + vb->buffer_offset + ve->src_offset;
-      nouveau_bo_unmap(bo);
-
-      ctx.attr[n].stride = vb->stride;
-      ctx.attr[n].divisor = ve->instance_divisor;
-      if (ctx.attr[n].divisor) {
-         ctx.attr[n].step = i_start % ve->instance_divisor;
-         ctx.attr[n].map = (uint8_t *)ctx.attr[n].map + i_start * vb->stride;
-      }
+      index_size = nv50->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;
+   }
+
+   ctx.instance_id = info->start_instance;
+   ctx.prim = nv50_prim_gl(info->mode);
 
-      size = util_format_get_component_bits(ve->src_format,
-                                            UTIL_FORMAT_COLORSPACE_RGB, 0);
-      nr_components = util_format_get_nr_components(ve->src_format);
-      switch (size) {
-      case 8:
-         switch (nr_components) {
-         case 1: ctx.attr[n].push = emit_b08_1; break;
-         case 2: ctx.attr[n].push = emit_b16_1; break;
-         case 3: ctx.attr[n].push = emit_b08_3; break;
-         case 4: ctx.attr[n].push = emit_b32_1; break;
-         }
-         ctx.vtx_size++;
+   while (inst--) {
+      BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1);
+      OUT_RING  (ctx.chan, ctx.prim);
+      switch (index_size) {
+      case 0:
+         emit_vertices_seq(&ctx, info->start, info->count);
          break;
-      case 16:
-         switch (nr_components) {
-         case 1: ctx.attr[n].push = emit_b16_1; break;
-         case 2: ctx.attr[n].push = emit_b32_1; break;
-         case 3: ctx.attr[n].push = emit_b16_3; break;
-         case 4: ctx.attr[n].push = emit_b32_2; break;
-         }
-         ctx.vtx_size += (nr_components + 1) >> 1;
+      case 1:
+         emit_vertices_i08(&ctx, info->start, info->count);
          break;
-      case 32:
-         switch (nr_components) {
-         case 1: ctx.attr[n].push = emit_b32_1; break;
-         case 2: ctx.attr[n].push = emit_b32_2; break;
-         case 3: ctx.attr[n].push = emit_b32_3; break;
-         case 4: ctx.attr[n].push = emit_b32_4; break;
-         }
-         ctx.vtx_size += nr_components;
+      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);
-         return;
+         break;
       }
-   }
-   vtx_size = ctx.vtx_size + v_overhead;
-
-   /* map index buffer, if present */
-   if (idxbuf) {
-      struct nouveau_bo *bo = nv50_resource(idxbuf)->bo;
+      BEGIN_RING(ctx.chan, RING_3D(VERTEX_END_GL), 1);
+      OUT_RING  (ctx.chan, 0);
 
-      if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
-         assert(bo->map);
-         return;
-      }
-      ctx.idxbuf = bo->map;
-      ctx.idxbias = idxbias;
-      ctx.idxsize = idxsize;
-      nouveau_bo_unmap(bo);
+      ctx.instance_id++;
+      ctx.prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
    }
 
-   s.priv = &ctx;
-   s.edge = emit_edgeflag;
-   if (idxbuf) {
-      if (idxsize == 1)
-         s.emit = idxbias ? emit_elt08_biased : emit_elt08;
-      else
-      if (idxsize == 2)
-         s.emit = idxbias ? emit_elt16_biased : emit_elt16;
-      else
-         s.emit = idxbias ? emit_elt32_biased : emit_elt32;
-   } else
-      s.emit = emit_verts;
-
-   /* per-instance loop */
-   BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
-   OUT_RING  (chan, NV50_CB_AUX | (24 << 8));
-   OUT_RING  (chan, i_start);
-   while (i_count--) {
-      unsigned max_verts;
-      boolean done;
-
-      for (i = 0; i < ctx.attr_nr; i++) {
-         if (!ctx.attr[i].divisor ||
-              ctx.attr[i].divisor != ++ctx.attr[i].step)
-            continue;
-         ctx.attr[i].step = 0;
-         ctx.attr[i].map = (uint8_t *)ctx.attr[i].map + ctx.attr[i].stride;
-      }
+   if (info->indexed)
+      nv50_resource_unmap(nv50_resource(nv50->idxbuf.buffer));
 
-      util_split_prim_init(&s, mode, start, count);
-      do {
-         if (AVAIL_RING(chan) < p_overhead + (6 * vtx_size)) {
-            FIRE_RING(chan);
-            if (!nv50_state_validate(nv50, p_overhead + (6 * vtx_size))) {
-               assert(0);
-               return;
-            }
-         }
-
-         max_verts  = AVAIL_RING(chan);
-         max_verts -= p_overhead;
-         max_verts /= vtx_size;
-
-         BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
-         OUT_RING  (chan, nv50_prim(s.mode) | (nzi ? (1 << 28) : 0));
-         done = util_split_prim_next(&s, max_verts);
-         BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
-         OUT_RING  (chan, 0);
-      } while (!done);
-
-      nzi = TRUE;
-   }
+   for (i = 0; i < nv50->num_vtxbufs; ++i)
+      nv50_resource_unmap(nv50_resource(nv50->vtxbuf[i].buffer));
 }
index f3418df83817b22a2d41762e99c6600e43d9ea60..e769aa18fe944a3032c38d90ee8eef1ed57bb15a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Ben Skeggs
+ * Copyright 2011 Nouveau Project
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * 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: Christoph Bumiller
  */
 
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-
 #include "nv50_context.h"
+#include "nouveau/nv_object.xml.h"
+
+/* XXX: Nested queries, and simultaneous queries on multiple gallium contexts
+ * (since we use only a single GPU channel per screen) will not work properly.
+ *
+ * The first is not that big of an issue because OpenGL does not allow nested
+ * queries anyway.
+ */
 
 struct nv50_query {
-       struct nouveau_bo *bo;
-       unsigned type;
-       boolean ready;
-       uint64_t result;
+   uint32_t *data;
+   uint32_t type;
+   uint32_t sequence;
+   struct nouveau_bo *bo;
+   uint32_t base;
+   uint32_t offset; /* base + i * 16 */
+   boolean ready;
+   boolean is64bit;
+   struct nv50_mm_allocation *mm;
 };
 
+#define NV50_QUERY_ALLOC_SPACE 128
+
 static INLINE struct nv50_query *
 nv50_query(struct pipe_query *pipe)
 {
-       return (struct nv50_query *)pipe;
+   return (struct nv50_query *)pipe;
+}
+
+static boolean
+nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
+{
+   struct nv50_screen *screen = nv50->screen;
+   int ret;
+
+   if (q->bo) {
+      nouveau_bo_ref(NULL, &q->bo);
+      if (q->mm) {
+         if (q->ready)
+            nv50_mm_free(q->mm);
+         else
+            nv50_fence_sched_release(screen->fence.current, q->mm);
+      }
+   }
+   if (size) {
+      q->mm = nv50_mm_allocate(screen->mm_GART, size, &q->bo, &q->base);
+      if (!q->bo)
+         return FALSE;
+      q->offset = q->base;
+
+      ret = nouveau_bo_map_range(q->bo, q->base, size, NOUVEAU_BO_RD |
+                                 NOUVEAU_BO_NOSYNC);
+      if (ret) {
+         nv50_query_allocate(nv50, q, 0);
+         return FALSE;
+      }
+      q->data = q->bo->map;
+      nouveau_bo_unmap(q->bo);
+   }
+   return TRUE;
+}
+
+static void
+nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
+{
+   nv50_query_allocate(nv50_context(pipe), nv50_query(pq), 0);
+   FREE(nv50_query(pq));
 }
 
 static struct pipe_query *
 nv50_query_create(struct pipe_context *pipe, unsigned type)
 {
-       struct nouveau_device *dev = nouveau_screen(pipe->screen)->device;
-       struct nv50_query *q = CALLOC_STRUCT(nv50_query);
-       int ret;
+   struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_query *q;
+
+   q = CALLOC_STRUCT(nv50_query);
+   if (!q)
+      return NULL;
 
-       assert (type == PIPE_QUERY_OCCLUSION_COUNTER);
-       q->type = type;
+   if (!nv50_query_allocate(nv50, q, NV50_QUERY_ALLOC_SPACE)) {
+      FREE(q);
+      return NULL;
+   }
 
-       ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 256,
-                            16, &q->bo);
-       if (ret) {
-               FREE(q);
-               return NULL;
-       }
+   q->is64bit = (type == PIPE_QUERY_PRIMITIVES_GENERATED ||
+                 type == PIPE_QUERY_PRIMITIVES_EMITTED ||
+                 type == PIPE_QUERY_SO_STATISTICS);
+   q->type = type;
 
-       return (struct pipe_query *)q;
+   if (q->type == PIPE_QUERY_OCCLUSION_COUNTER) {
+      q->offset -= 16;
+      q->data -= 16 / sizeof(*q->data); /* we advance before query_begin ! */
+   }
+
+   return (struct pipe_query *)q;
 }
 
 static void
-nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
+nv50_query_get(struct nouveau_channel *chan, struct nv50_query *q,
+               unsigned offset, uint32_t get)
 {
-       struct nv50_query *q = nv50_query(pq);
+   offset += q->offset;
 
-       if (q) {
-               nouveau_bo_ref(NULL, &q->bo);
-               FREE(q);
-       }
+   MARK_RING (chan, 5, 2);
+   BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
+   OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+   OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+   OUT_RING  (chan, q->sequence);
+   OUT_RING  (chan, get);
 }
 
 static void
 nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nouveau_channel *chan = nv50->screen->base.channel;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nv50_query *q = nv50_query(pq);
+   struct nv50_context *nv50 = nv50_context(pipe);
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nv50_query *q = nv50_query(pq);
+
+   /* For occlusion queries we have to change the storage, because a previous
+    * query might set the initial render conition to FALSE even *after* we re-
+    * initialized it to TRUE.
+    */
+   if (q->type == PIPE_QUERY_OCCLUSION_COUNTER) {
+      q->offset += 16;
+      q->data += 16 / sizeof(*q->data);
+      if (q->offset - q->base == NV50_QUERY_ALLOC_SPACE)
+         nv50_query_allocate(nv50, q, NV50_QUERY_ALLOC_SPACE);
 
-       BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_RESET, 1);
-       OUT_RING  (chan, 1);
-       BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_ENABLE, 1);
-       OUT_RING  (chan, 1);
+      /* XXX: can we do this with the GPU, and sync with respect to a previous
+       *  query ?
+       */
+      q->data[1] = 1; /* initial render condition = TRUE */
+   }
+   if (!q->is64bit)
+      q->data[0] = q->sequence++; /* the previously used one */
 
-       q->ready = FALSE;
+   switch (q->type) {
+   case PIPE_QUERY_OCCLUSION_COUNTER:
+      BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
+      OUT_RING  (chan, NV50_3D_COUNTER_RESET_SAMPLECNT);
+      BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
+      OUT_RING  (chan, 1);
+      break;
+   case PIPE_QUERY_PRIMITIVES_GENERATED: /* store before & after instead ? */
+      BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
+      OUT_RING  (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
+      break;
+   case PIPE_QUERY_PRIMITIVES_EMITTED:
+      BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
+      OUT_RING  (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
+      break;
+   case PIPE_QUERY_SO_STATISTICS:
+      BEGIN_RING_NI(chan, RING_3D(COUNTER_RESET), 2);
+      OUT_RING  (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
+      OUT_RING  (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
+      break;
+   case PIPE_QUERY_TIMESTAMP_DISJOINT:
+   case PIPE_QUERY_TIME_ELAPSED:
+      nv50_query_get(chan, q, 0x10, 0x00005002);
+      break;
+   default:
+      break;
+   }
+   q->ready = FALSE;
 }
 
 static void
 nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nouveau_channel *chan = nv50->screen->base.channel;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nv50_query *q = nv50_query(pq);
-
-       MARK_RING (chan, 5, 2); /* flush on lack of space or relocs */
-       BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4);
-       OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
-       OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
-       OUT_RING  (chan, 0x00000000);
-       OUT_RING  (chan, 0x0100f002);
-
-       BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_ENABLE, 1);
-       OUT_RING  (chan, 0);
+   struct nv50_context *nv50 = nv50_context(pipe);
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nv50_query *q = nv50_query(pq);
+
+   switch (q->type) {
+   case PIPE_QUERY_OCCLUSION_COUNTER:
+      nv50_query_get(chan, q, 0, 0x0100f002);
+      BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
+      OUT_RING  (chan, 0);
+      break;
+   case PIPE_QUERY_PRIMITIVES_GENERATED:
+      nv50_query_get(chan, q, 0, 0x06805002);
+      break;
+   case PIPE_QUERY_PRIMITIVES_EMITTED:
+      nv50_query_get(chan, q, 0, 0x05805002);
+      break;
+   case PIPE_QUERY_SO_STATISTICS:
+      nv50_query_get(chan, q, 0x00, 0x05805002);
+      nv50_query_get(chan, q, 0x10, 0x06805002);
+      break;
+   case PIPE_QUERY_TIMESTAMP_DISJOINT:
+   case PIPE_QUERY_TIME_ELAPSED:
+      nv50_query_get(chan, q, 0, 0x00005002);
+      break;
+   case PIPE_QUERY_GPU_FINISHED:
+      nv50_query_get(chan, q, 0, 0x1000f010);
+      break;
+   default:
+      assert(0);
+      break;
+   }
+}
+
+static INLINE boolean
+nv50_query_ready(struct nv50_query *q)
+{
+   return q->ready || (!q->is64bit && (q->data[0] == q->sequence));
+}
+
+static INLINE boolean
+nv50_query_wait(struct nv50_query *q)
+{
+   int ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD);
+   if (ret)
+      return FALSE;
+   nouveau_bo_unmap(q->bo);
+   return TRUE;
 }
 
 static boolean
 nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
-                 boolean wait, void *vresult)
+                  boolean wait, void *result)
 {
-       uint64_t *result = (uint64_t*)vresult;
-       struct nv50_query *q = nv50_query(pq);
-       int ret;
-
-       if (!q->ready) {
-               ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD |
-                                    (wait ? 0 : NOUVEAU_BO_NOWAIT));
-               if (ret)
-                       return false;
-               q->result = ((uint32_t *)q->bo->map)[1];
-               q->ready = TRUE;
-               nouveau_bo_unmap(q->bo);
-       }
-
-       *result = q->result;
-       return q->ready;
+   struct nv50_query *q = nv50_query(pq);
+   uint64_t *res64 = result;
+   boolean *res8 = result;
+   uint64_t *data64 = (uint64_t *)q->data;
+
+   if (q->type == PIPE_QUERY_GPU_FINISHED) {
+      res8[0] = nv50_query_ready(q);
+      return TRUE;
+   }
+
+   if (!q->ready) /* update ? */
+      q->ready = nv50_query_ready(q);
+   if (!q->ready) {
+      struct nouveau_channel *chan = nv50_context(pipe)->screen->base.channel;
+      if (!wait) {
+         if (nouveau_bo_pending(q->bo) & NOUVEAU_BO_WR) /* for daft apps */
+            FIRE_RING(chan);
+         return FALSE;
+      }
+      if (!nv50_query_wait(q))
+         return FALSE;
+   }
+   q->ready = TRUE;
+
+   switch (q->type) {
+   case PIPE_QUERY_OCCLUSION_COUNTER: /* u32 sequence, u32 count, u64 time */
+      res64[0] = q->data[1];
+      break;
+   case PIPE_QUERY_PRIMITIVES_GENERATED: /* u64 count, u64 time */
+   case PIPE_QUERY_PRIMITIVES_EMITTED: /* u64 count, u64 time */
+      res64[0] = data64[0];
+      break;
+   case PIPE_QUERY_SO_STATISTICS:
+      res64[0] = data64[0];
+      res64[1] = data64[1];
+      break;
+   case PIPE_QUERY_TIMESTAMP_DISJOINT: /* u32 sequence, u32 0, u64 time */
+      res64[0] = 1000000000;
+      res8[8] = (data64[0] == data64[2]) ? FALSE : TRUE;
+      break;
+   case PIPE_QUERY_TIME_ELAPSED:
+      res64[0] = data64[1] - data64[3];
+      break;
+   default:
+      return FALSE;
+   }
+
+   return TRUE;
 }
 
 static void
 nv50_render_condition(struct pipe_context *pipe,
-                     struct pipe_query *pq, uint mode)
+                      struct pipe_query *pq, uint mode)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nouveau_channel *chan = nv50->screen->base.channel;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nv50_query *q;
-
-       if (!pq) {
-               BEGIN_RING(chan, tesla, NV50TCL_COND_MODE, 1);
-               OUT_RING  (chan, NV50TCL_COND_MODE_ALWAYS);
-               return;
-       }
-       q = nv50_query(pq);
-
-       if (mode == PIPE_RENDER_COND_WAIT ||
-           mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
-               /* XXX: big fence, FIFO semaphore might be better */
-               BEGIN_RING(chan, tesla, 0x0110, 1);
-               OUT_RING  (chan, 0);
-       }
-
-       BEGIN_RING(chan, tesla, NV50TCL_COND_ADDRESS_HIGH, 3);
-       OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-       OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-       OUT_RING  (chan, NV50TCL_COND_MODE_RES);
+   struct nv50_context *nv50 = nv50_context(pipe);
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nv50_query *q;
+
+   if (!pq) {
+      BEGIN_RING(chan, RING_3D(COND_MODE), 1);
+      OUT_RING  (chan, NV50_3D_COND_MODE_ALWAYS);
+      return;
+   }
+   q = nv50_query(pq);
+
+   if (mode == PIPE_RENDER_COND_WAIT ||
+       mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
+      BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1);
+      OUT_RING  (chan, 0);
+   }
+
+   MARK_RING (chan, 4, 2);
+   BEGIN_RING(chan, RING_3D(COND_ADDRESS_HIGH), 3);
+   OUT_RELOCh(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+   OUT_RING  (chan, NV50_3D_COND_MODE_RES_NON_ZERO);
 }
 
 void
 nv50_init_query_functions(struct nv50_context *nv50)
 {
-       nv50->pipe.create_query = nv50_query_create;
-       nv50->pipe.destroy_query = nv50_query_destroy;
-       nv50->pipe.begin_query = nv50_query_begin;
-       nv50->pipe.end_query = nv50_query_end;
-       nv50->pipe.get_query_result = nv50_query_result;
-       nv50->pipe.render_condition = nv50_render_condition;
+   nv50->pipe.create_query = nv50_query_create;
+   nv50->pipe.destroy_query = nv50_query_destroy;
+   nv50->pipe.begin_query = nv50_query_begin;
+   nv50->pipe.end_query = nv50_query_end;
+   nv50->pipe.get_query_result = nv50_query_result;
+   nv50->pipe.render_condition = nv50_render_condition;
 }
diff --git a/src/gallium/drivers/nv50/nv50_reg.h b/src/gallium/drivers/nv50/nv50_reg.h
deleted file mode 100644 (file)
index 949838b..0000000
+++ /dev/null
@@ -1,1827 +0,0 @@
-/*************************************************************************
-
-   Autogenerated file, do not edit !
-
-   This file was generated by renouveau-gen from renouveau.xml, the
-   XML database of nvidia objects and methods. renouveau-gen and
-   renouveau.xml can be found in CVS module renouveau of sourceforge.net
-   project nouveau:
-
-cvs -z3 -d:pserver:anonymous@nouveau.cvs.sourceforge.net:/cvsroot/nouveau co -P renouveau
-
-**************************************************************************
-
-   Copyright (C) 2006-2008 :
-   Dmitry Baryshkov,
-   Laurent Carlier,
-   Matthieu Castet,
-   Dawid Gajownik,
-   Jeremy Kolb,
-   Stephane Loeuillet,
-   Patrice Mandin,
-   Stephane Marchesin,
-   Serge Martin,
-   Sylvain Munaut,
-   Simon Raffeiner,
-   Ben Skeggs,
-   Erik Waling,
-   koala_br,
-
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (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.
-
-*************************************************************************/
-
-
-#ifndef NOUVEAU_REG_H
-#define NOUVEAU_REG_H 1
-
-
-#define NV04_MEMORY_TO_MEMORY_FORMAT                                                   0x00000039
-
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_NOP                                              0x00000100
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_NOTIFY                                           0x00000104
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY                                       0x00000180
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN                                    0x00000184
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_OUT                                   0x00000188
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN                                                0x0000030c
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT                                       0x00000310
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_IN                                         0x00000314
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT                                                0x00000318
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN                                   0x0000031c
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_LINE_COUNT                                       0x00000320
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT                                           0x00000324
-#define   NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_INPUT_INC_SHIFT                          0
-#define   NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_INPUT_INC_MASK                           0x000000ff
-#define   NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_OUTPUT_INC_SHIFT                         8
-#define   NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_OUTPUT_INC_MASK                          0x0000ff00
-#define  NV04_MEMORY_TO_MEMORY_FORMAT_BUF_NOTIFY                                       0x00000328
-
-
-#define NV50_MEMORY_TO_MEMORY_FORMAT                                                   0x00005039
-
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_SERIALIZE                                                0x00000110
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN                                                0x00000200
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_MODE_IN                                   0x00000204
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_PITCH_IN                                  0x00000208
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_HEIGHT_IN                                 0x0000020c
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_DEPTH_IN                                  0x00000210
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_Z                             0x00000214
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN                               0x00000218
-#define   NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_X_SHIFT                      0
-#define   NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_X_MASK                       0x0000ffff
-#define   NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_Y_SHIFT                      16
-#define   NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_Y_MASK                       0xffff0000
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT                                       0x0000021c
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_MODE_OUT                                  0x00000220
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_PITCH_OUT                                 0x00000224
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_HEIGHT_OUT                                        0x00000228
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_DEPTH_OUT                                 0x0000022c
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_Z                            0x00000230
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT                              0x00000234
-#define   NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_X_SHIFT                     0
-#define   NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_X_MASK                      0x0000ffff
-#define   NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_Y_SHIFT                     16
-#define   NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_Y_MASK                      0xffff0000
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH                                   0x00000238
-#define  NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH                                  0x0000023c
-
-
-#define NV50_2D                                                                                0x0000502d
-
-#define  NV50_2D_NOP                                                                   0x00000100
-#define  NV50_2D_NOTIFY                                                                        0x00000104
-#define  NV50_2D_SERIALIZE                                                             0x00000110
-#define  NV50_2D_DMA_NOTIFY                                                            0x00000180
-#define  NV50_2D_DMA_DST                                                               0x00000184
-#define  NV50_2D_DMA_SRC                                                               0x00000188
-#define  NV50_2D_DMA_COND                                                              0x0000018c
-#define  NV50_2D_DST_FORMAT                                                            0x00000200
-#define   NV50_2D_DST_FORMAT_R32G32B32A32_FLOAT                                                0x000000c0
-#define   NV50_2D_DST_FORMAT_R32G32B32A32_SINT                                         0x000000c1
-#define   NV50_2D_DST_FORMAT_R32G32B32A32_UINT                                         0x000000c2
-#define   NV50_2D_DST_FORMAT_R32G32B32X32_FLOAT                                                0x000000c3
-#define   NV50_2D_DST_FORMAT_R16G16B16A16_UNORM                                                0x000000c6
-#define   NV50_2D_DST_FORMAT_R16G16B16A16_SNORM                                                0x000000c7
-#define   NV50_2D_DST_FORMAT_R16G16B16A16_SINT                                         0x000000c8
-#define   NV50_2D_DST_FORMAT_R16G16B16A16_UINT                                         0x000000c9
-#define   NV50_2D_DST_FORMAT_R16G16B16A16_FLOAT                                                0x000000ca
-#define   NV50_2D_DST_FORMAT_R32G32_FLOAT                                              0x000000cb
-#define   NV50_2D_DST_FORMAT_R32G32_SINT                                               0x000000cc
-#define   NV50_2D_DST_FORMAT_R32G32_UINT                                               0x000000cd
-#define   NV50_2D_DST_FORMAT_R16G16B16X16_FLOAT                                                0x000000ce
-#define   NV50_2D_DST_FORMAT_A8R8G8B8_UNORM                                            0x000000cf
-#define   NV50_2D_DST_FORMAT_A8R8G8B8_SRGB                                             0x000000d0
-#define   NV50_2D_DST_FORMAT_A2B10G10R10_UNORM                                         0x000000d1
-#define   NV50_2D_DST_FORMAT_A2B10G10R10_UINT                                          0x000000d2
-#define   NV50_2D_DST_FORMAT_A8B8G8R8_UNORM                                            0x000000d5
-#define   NV50_2D_DST_FORMAT_A8B8G8R8_SRGB                                             0x000000d6
-#define   NV50_2D_DST_FORMAT_A8B8G8R8_SNORM                                            0x000000d7
-#define   NV50_2D_DST_FORMAT_A8B8G8R8_SINT                                             0x000000d8
-#define   NV50_2D_DST_FORMAT_A8B8G8R8_UINT                                             0x000000d9
-#define   NV50_2D_DST_FORMAT_R16G16_UNORM                                              0x000000da
-#define   NV50_2D_DST_FORMAT_R16G16_SNORM                                              0x000000db
-#define   NV50_2D_DST_FORMAT_R16G16_SINT                                               0x000000dc
-#define   NV50_2D_DST_FORMAT_R16G16_UINT                                               0x000000dd
-#define   NV50_2D_DST_FORMAT_R16G16_FLOAT                                              0x000000de
-#define   NV50_2D_DST_FORMAT_A2R10G10B10_UNORM                                         0x000000df
-#define   NV50_2D_DST_FORMAT_B10G11R11_FLOAT                                           0x000000e0
-#define   NV50_2D_DST_FORMAT_R32_FLOAT                                                 0x000000e5
-#define   NV50_2D_DST_FORMAT_X8R8G8B8_UNORM                                            0x000000e6
-#define   NV50_2D_DST_FORMAT_X8R8G8B8_SRGB                                             0x000000e7
-#define   NV50_2D_DST_FORMAT_R5G6B5_UNORM                                              0x000000e8
-#define   NV50_2D_DST_FORMAT_A1R5G5B5_UNORM                                            0x000000e9
-#define   NV50_2D_DST_FORMAT_R8G8_UNORM                                                        0x000000ea
-#define   NV50_2D_DST_FORMAT_R8G8_SNORM                                                        0x000000eb
-#define   NV50_2D_DST_FORMAT_R8G8_SINT                                                 0x000000ec
-#define   NV50_2D_DST_FORMAT_R8G8_UINT                                                 0x000000ed
-#define   NV50_2D_DST_FORMAT_R16_UNORM                                                 0x000000ee
-#define   NV50_2D_DST_FORMAT_R16_SNORM                                                 0x000000ef
-#define   NV50_2D_DST_FORMAT_R16_SINT                                                  0x000000f0
-#define   NV50_2D_DST_FORMAT_R16_UINT                                                  0x000000f1
-#define   NV50_2D_DST_FORMAT_R16_FLOAT                                                 0x000000f2
-#define   NV50_2D_DST_FORMAT_R8_UNORM                                                  0x000000f3
-#define   NV50_2D_DST_FORMAT_R8_SNORM                                                  0x000000f4
-#define   NV50_2D_DST_FORMAT_R8_SINT                                                   0x000000f5
-#define   NV50_2D_DST_FORMAT_R8_UINT                                                   0x000000f6
-#define   NV50_2D_DST_FORMAT_A8_UNORM                                                  0x000000f7
-#define   NV50_2D_DST_FORMAT_X1R5G5B5_UNORM                                            0x000000f8
-#define   NV50_2D_DST_FORMAT_X8B8G8R8_UNORM                                            0x000000f9
-#define   NV50_2D_DST_FORMAT_X8B8G8R8_SRGB                                             0x000000fa
-#define  NV50_2D_DST_LINEAR                                                            0x00000204
-#define  NV50_2D_DST_TILE_MODE                                                         0x00000208
-#define  NV50_2D_DST_DEPTH                                                             0x0000020c
-#define  NV50_2D_DST_LAYER                                                             0x00000210
-#define  NV50_2D_DST_PITCH                                                             0x00000214
-#define  NV50_2D_DST_WIDTH                                                             0x00000218
-#define  NV50_2D_DST_HEIGHT                                                            0x0000021c
-#define  NV50_2D_DST_ADDRESS_HIGH                                                      0x00000220
-#define  NV50_2D_DST_ADDRESS_LOW                                                       0x00000224
-#define  NV50_2D_SRC_FORMAT                                                            0x00000230
-#define   NV50_2D_SRC_FORMAT_R32G32B32A32_FLOAT                                                0x000000c0
-#define   NV50_2D_SRC_FORMAT_R32G32B32A32_SINT                                         0x000000c1
-#define   NV50_2D_SRC_FORMAT_R32G32B32A32_UINT                                         0x000000c2
-#define   NV50_2D_SRC_FORMAT_R32G32B32X32_FLOAT                                                0x000000c3
-#define   NV50_2D_SRC_FORMAT_R16G16B16A16_UNORM                                                0x000000c6
-#define   NV50_2D_SRC_FORMAT_R16G16B16A16_SNORM                                                0x000000c7
-#define   NV50_2D_SRC_FORMAT_R16G16B16A16_SINT                                         0x000000c8
-#define   NV50_2D_SRC_FORMAT_R16G16B16A16_UINT                                         0x000000c9
-#define   NV50_2D_SRC_FORMAT_R16G16B16A16_FLOAT                                                0x000000ca
-#define   NV50_2D_SRC_FORMAT_R32G32_FLOAT                                              0x000000cb
-#define   NV50_2D_SRC_FORMAT_R32G32_SINT                                               0x000000cc
-#define   NV50_2D_SRC_FORMAT_R32G32_UINT                                               0x000000cd
-#define   NV50_2D_SRC_FORMAT_R16G16B16X16_FLOAT                                                0x000000ce
-#define   NV50_2D_SRC_FORMAT_A8R8G8B8_UNORM                                            0x000000cf
-#define   NV50_2D_SRC_FORMAT_A8R8G8B8_SRGB                                             0x000000d0
-#define   NV50_2D_SRC_FORMAT_A2B10G10R10_UNORM                                         0x000000d1
-#define   NV50_2D_SRC_FORMAT_A2B10G10R10_UINT                                          0x000000d2
-#define   NV50_2D_SRC_FORMAT_A8B8G8R8_UNORM                                            0x000000d5
-#define   NV50_2D_SRC_FORMAT_A8B8G8R8_SRGB                                             0x000000d6
-#define   NV50_2D_SRC_FORMAT_A8B8G8R8_SNORM                                            0x000000d7
-#define   NV50_2D_SRC_FORMAT_A8B8G8R8_SINT                                             0x000000d8
-#define   NV50_2D_SRC_FORMAT_A8B8G8R8_UINT                                             0x000000d9
-#define   NV50_2D_SRC_FORMAT_R16G16_UNORM                                              0x000000da
-#define   NV50_2D_SRC_FORMAT_R16G16_SNORM                                              0x000000db
-#define   NV50_2D_SRC_FORMAT_R16G16_SINT                                               0x000000dc
-#define   NV50_2D_SRC_FORMAT_R16G16_UINT                                               0x000000dd
-#define   NV50_2D_SRC_FORMAT_R16G16_FLOAT                                              0x000000de
-#define   NV50_2D_SRC_FORMAT_A2R10G10B10_UNORM                                         0x000000df
-#define   NV50_2D_SRC_FORMAT_B10G11R11_FLOAT                                           0x000000e0
-#define   NV50_2D_SRC_FORMAT_R32_FLOAT                                                 0x000000e5
-#define   NV50_2D_SRC_FORMAT_X8R8G8B8_UNORM                                            0x000000e6
-#define   NV50_2D_SRC_FORMAT_X8R8G8B8_SRGB                                             0x000000e7
-#define   NV50_2D_SRC_FORMAT_R5G6B5_UNORM                                              0x000000e8
-#define   NV50_2D_SRC_FORMAT_A1R5G5B5_UNORM                                            0x000000e9
-#define   NV50_2D_SRC_FORMAT_R8G8_UNORM                                                        0x000000ea
-#define   NV50_2D_SRC_FORMAT_R8G8_SNORM                                                        0x000000eb
-#define   NV50_2D_SRC_FORMAT_R8G8_SINT                                                 0x000000ec
-#define   NV50_2D_SRC_FORMAT_R8G8_UINT                                                 0x000000ed
-#define   NV50_2D_SRC_FORMAT_R16_UNORM                                                 0x000000ee
-#define   NV50_2D_SRC_FORMAT_R16_SNORM                                                 0x000000ef
-#define   NV50_2D_SRC_FORMAT_R16_SINT                                                  0x000000f0
-#define   NV50_2D_SRC_FORMAT_R16_UINT                                                  0x000000f1
-#define   NV50_2D_SRC_FORMAT_R16_FLOAT                                                 0x000000f2
-#define   NV50_2D_SRC_FORMAT_R8_UNORM                                                  0x000000f3
-#define   NV50_2D_SRC_FORMAT_R8_SNORM                                                  0x000000f4
-#define   NV50_2D_SRC_FORMAT_R8_SINT                                                   0x000000f5
-#define   NV50_2D_SRC_FORMAT_R8_UINT                                                   0x000000f6
-#define   NV50_2D_SRC_FORMAT_A8_UNORM                                                  0x000000f7
-#define   NV50_2D_SRC_FORMAT_X1R5G5B5_UNORM                                            0x000000f8
-#define   NV50_2D_SRC_FORMAT_X8B8G8R8_UNORM                                            0x000000f9
-#define   NV50_2D_SRC_FORMAT_X8B8G8R8_SRGB                                             0x000000fa
-#define  NV50_2D_SRC_LINEAR                                                            0x00000234
-#define  NV50_2D_SRC_TILE_MODE                                                         0x00000238
-#define  NV50_2D_SRC_DEPTH                                                             0x0000023c
-#define  NV50_2D_SRC_LAYER                                                             0x00000240
-#define  NV50_2D_SRC_PITCH                                                             0x00000244
-#define  NV50_2D_SRC_WIDTH                                                             0x00000248
-#define  NV50_2D_SRC_HEIGHT                                                            0x0000024c
-#define  NV50_2D_SRC_ADDRESS_HIGH                                                      0x00000250
-#define  NV50_2D_SRC_ADDRESS_LOW                                                       0x00000254
-#define  NV50_2D_COND_ADDRESS_HIGH                                                     0x00000264
-#define  NV50_2D_COND_ADDRESS_LOW                                                      0x00000268
-#define  NV50_2D_COND_MODE                                                             0x0000026c
-#define   NV50_2D_COND_MODE_NEVER                                                      0x00000000
-#define   NV50_2D_COND_MODE_ALWAYS                                                     0x00000001
-#define   NV50_2D_COND_MODE_RES                                                                0x00000002
-#define   NV50_2D_COND_MODE_NOT_RES_AND_NOT_ID                                         0x00000003
-#define   NV50_2D_COND_MODE_RES_OR_ID                                                  0x00000004
-#define  NV50_2D_CLIP_X                                                                        0x00000280
-#define  NV50_2D_CLIP_Y                                                                        0x00000284
-#define  NV50_2D_CLIP_W                                                                        0x00000288
-#define  NV50_2D_CLIP_H                                                                        0x0000028c
-#define  NV50_2D_CLIP_ENABLE                                                           0x00000290
-#define  NV50_2D_COLOR_KEY_FORMAT                                                      0x00000294
-#define   NV50_2D_COLOR_KEY_FORMAT_16BPP                                               0x00000000
-#define   NV50_2D_COLOR_KEY_FORMAT_15BPP                                               0x00000001
-#define   NV50_2D_COLOR_KEY_FORMAT_24BPP                                               0x00000002
-#define   NV50_2D_COLOR_KEY_FORMAT_30BPP                                               0x00000003
-#define   NV50_2D_COLOR_KEY_FORMAT_8BPP                                                        0x00000004
-#define   NV50_2D_COLOR_KEY_FORMAT_16BPP2                                              0x00000005
-#define   NV50_2D_COLOR_KEY_FORMAT_32BPP                                               0x00000006
-#define  NV50_2D_COLOR_KEY                                                             0x00000298
-#define  NV50_2D_COLOR_KEY_ENABLE                                                      0x0000029c
-#define  NV50_2D_ROP                                                                   0x000002a0
-#define  NV50_2D_OPERATION                                                             0x000002ac
-#define   NV50_2D_OPERATION_SRCCOPY_AND                                                        0x00000000
-#define   NV50_2D_OPERATION_ROP_AND                                                    0x00000001
-#define   NV50_2D_OPERATION_BLEND_AND                                                  0x00000002
-#define   NV50_2D_OPERATION_SRCCOPY                                                    0x00000003
-#define   NV50_2D_OPERATION_SRCCOPY_PREMULT                                            0x00000004
-#define   NV50_2D_OPERATION_BLEND_PREMULT                                              0x00000005
-#define  NV50_2D_PATTERN_FORMAT                                                                0x000002e8
-#define   NV50_2D_PATTERN_FORMAT_16BPP                                                 0x00000000
-#define   NV50_2D_PATTERN_FORMAT_15BPP                                                 0x00000001
-#define   NV50_2D_PATTERN_FORMAT_32BPP                                                 0x00000002
-#define   NV50_2D_PATTERN_FORMAT_8BPP                                                  0x00000003
-#define  NV50_2D_PATTERN_COLOR(x)                                                      (0x000002f0+((x)*4))
-#define  NV50_2D_PATTERN_COLOR__SIZE                                                   0x00000002
-#define  NV50_2D_PATTERN_BITMAP(x)                                                     (0x000002f8+((x)*4))
-#define  NV50_2D_PATTERN_BITMAP__SIZE                                                  0x00000002
-#define  NV50_2D_DRAW_SHAPE                                                            0x00000580
-#define   NV50_2D_DRAW_SHAPE_POINTS                                                    0x00000000
-#define   NV50_2D_DRAW_SHAPE_LINES                                                     0x00000001
-#define   NV50_2D_DRAW_SHAPE_LINE_STRIP                                                        0x00000002
-#define   NV50_2D_DRAW_SHAPE_TRIANGLES                                                 0x00000003
-#define   NV50_2D_DRAW_SHAPE_RECTANGLES                                                        0x00000004
-#define  NV50_2D_DRAW_COLOR_FORMAT                                                     0x00000584
-#define   NV50_2D_DRAW_COLOR_FORMAT_R32G32B32A32_FLOAT                                 0x000000c0
-#define   NV50_2D_DRAW_COLOR_FORMAT_R32G32B32A32_SINT                                  0x000000c1
-#define   NV50_2D_DRAW_COLOR_FORMAT_R32G32B32A32_UINT                                  0x000000c2
-#define   NV50_2D_DRAW_COLOR_FORMAT_R32G32B32X32_FLOAT                                 0x000000c3
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_UNORM                                 0x000000c6
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_SNORM                                 0x000000c7
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_SINT                                  0x000000c8
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_UINT                                  0x000000c9
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_FLOAT                                 0x000000ca
-#define   NV50_2D_DRAW_COLOR_FORMAT_R32G32_FLOAT                                       0x000000cb
-#define   NV50_2D_DRAW_COLOR_FORMAT_R32G32_SINT                                                0x000000cc
-#define   NV50_2D_DRAW_COLOR_FORMAT_R32G32_UINT                                                0x000000cd
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16B16X16_FLOAT                                 0x000000ce
-#define   NV50_2D_DRAW_COLOR_FORMAT_A8R8G8B8_UNORM                                     0x000000cf
-#define   NV50_2D_DRAW_COLOR_FORMAT_A8R8G8B8_SRGB                                      0x000000d0
-#define   NV50_2D_DRAW_COLOR_FORMAT_A2B10G10R10_UNORM                                  0x000000d1
-#define   NV50_2D_DRAW_COLOR_FORMAT_A2B10G10R10_UINT                                   0x000000d2
-#define   NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_UNORM                                     0x000000d5
-#define   NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_SRGB                                      0x000000d6
-#define   NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_SNORM                                     0x000000d7
-#define   NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_SINT                                      0x000000d8
-#define   NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_UINT                                      0x000000d9
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16_UNORM                                       0x000000da
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16_SNORM                                       0x000000db
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16_SINT                                                0x000000dc
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16_UINT                                                0x000000dd
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16G16_FLOAT                                       0x000000de
-#define   NV50_2D_DRAW_COLOR_FORMAT_A2R10G10B10_UNORM                                  0x000000df
-#define   NV50_2D_DRAW_COLOR_FORMAT_B10G11R11_FLOAT                                    0x000000e0
-#define   NV50_2D_DRAW_COLOR_FORMAT_R32_FLOAT                                          0x000000e5
-#define   NV50_2D_DRAW_COLOR_FORMAT_X8R8G8B8_UNORM                                     0x000000e6
-#define   NV50_2D_DRAW_COLOR_FORMAT_X8R8G8B8_SRGB                                      0x000000e7
-#define   NV50_2D_DRAW_COLOR_FORMAT_R5G6B5_UNORM                                       0x000000e8
-#define   NV50_2D_DRAW_COLOR_FORMAT_A1R5G5B5_UNORM                                     0x000000e9
-#define   NV50_2D_DRAW_COLOR_FORMAT_R8G8_UNORM                                         0x000000ea
-#define   NV50_2D_DRAW_COLOR_FORMAT_R8G8_SNORM                                         0x000000eb
-#define   NV50_2D_DRAW_COLOR_FORMAT_R8G8_SINT                                          0x000000ec
-#define   NV50_2D_DRAW_COLOR_FORMAT_R8G8_UINT                                          0x000000ed
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16_UNORM                                          0x000000ee
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16_SNORM                                          0x000000ef
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16_SINT                                           0x000000f0
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16_UINT                                           0x000000f1
-#define   NV50_2D_DRAW_COLOR_FORMAT_R16_FLOAT                                          0x000000f2
-#define   NV50_2D_DRAW_COLOR_FORMAT_R8_UNORM                                           0x000000f3
-#define   NV50_2D_DRAW_COLOR_FORMAT_R8_SNORM                                           0x000000f4
-#define   NV50_2D_DRAW_COLOR_FORMAT_R8_SINT                                            0x000000f5
-#define   NV50_2D_DRAW_COLOR_FORMAT_R8_UINT                                            0x000000f6
-#define   NV50_2D_DRAW_COLOR_FORMAT_A8_UNORM                                           0x000000f7
-#define   NV50_2D_DRAW_COLOR_FORMAT_X1R5G5B5_UNORM                                     0x000000f8
-#define   NV50_2D_DRAW_COLOR_FORMAT_X8B8G8R8_UNORM                                     0x000000f9
-#define   NV50_2D_DRAW_COLOR_FORMAT_X8B8G8R8_SRGB                                      0x000000fa
-#define  NV50_2D_DRAW_COLOR                                                            0x00000588
-#define  NV50_2D_DRAW_POINT16                                                          0x000005e0
-#define   NV50_2D_DRAW_POINT16_X_SHIFT                                                 0
-#define   NV50_2D_DRAW_POINT16_X_MASK                                                  0x0000ffff
-#define   NV50_2D_DRAW_POINT16_Y_SHIFT                                                 16
-#define   NV50_2D_DRAW_POINT16_Y_MASK                                                  0xffff0000
-#define  NV50_2D_DRAW_POINT32_X(x)                                                     (0x00000600+((x)*8))
-#define  NV50_2D_DRAW_POINT32_X__SIZE                                                  0x00000040
-#define  NV50_2D_DRAW_POINT32_Y(x)                                                     (0x00000604+((x)*8))
-#define  NV50_2D_DRAW_POINT32_Y__SIZE                                                  0x00000040
-#define  NV50_2D_SIFC_BITMAP_ENABLE                                                    0x00000800
-#define  NV50_2D_SIFC_FORMAT                                                           0x00000804
-#define   NV50_2D_SIFC_FORMAT_R32G32B32A32_FLOAT                                       0x000000c0
-#define   NV50_2D_SIFC_FORMAT_R32G32B32A32_SINT                                                0x000000c1
-#define   NV50_2D_SIFC_FORMAT_R32G32B32A32_UINT                                                0x000000c2
-#define   NV50_2D_SIFC_FORMAT_R32G32B32X32_FLOAT                                       0x000000c3
-#define   NV50_2D_SIFC_FORMAT_R16G16B16A16_UNORM                                       0x000000c6
-#define   NV50_2D_SIFC_FORMAT_R16G16B16A16_SNORM                                       0x000000c7
-#define   NV50_2D_SIFC_FORMAT_R16G16B16A16_SINT                                                0x000000c8
-#define   NV50_2D_SIFC_FORMAT_R16G16B16A16_UINT                                                0x000000c9
-#define   NV50_2D_SIFC_FORMAT_R16G16B16A16_FLOAT                                       0x000000ca
-#define   NV50_2D_SIFC_FORMAT_R32G32_FLOAT                                             0x000000cb
-#define   NV50_2D_SIFC_FORMAT_R32G32_SINT                                              0x000000cc
-#define   NV50_2D_SIFC_FORMAT_R32G32_UINT                                              0x000000cd
-#define   NV50_2D_SIFC_FORMAT_R16G16B16X16_FLOAT                                       0x000000ce
-#define   NV50_2D_SIFC_FORMAT_A8R8G8B8_UNORM                                           0x000000cf
-#define   NV50_2D_SIFC_FORMAT_A8R8G8B8_SRGB                                            0x000000d0
-#define   NV50_2D_SIFC_FORMAT_A2B10G10R10_UNORM                                                0x000000d1
-#define   NV50_2D_SIFC_FORMAT_A2B10G10R10_UINT                                         0x000000d2
-#define   NV50_2D_SIFC_FORMAT_A8B8G8R8_UNORM                                           0x000000d5
-#define   NV50_2D_SIFC_FORMAT_A8B8G8R8_SRGB                                            0x000000d6
-#define   NV50_2D_SIFC_FORMAT_A8B8G8R8_SNORM                                           0x000000d7
-#define   NV50_2D_SIFC_FORMAT_A8B8G8R8_SINT                                            0x000000d8
-#define   NV50_2D_SIFC_FORMAT_A8B8G8R8_UINT                                            0x000000d9
-#define   NV50_2D_SIFC_FORMAT_R16G16_UNORM                                             0x000000da
-#define   NV50_2D_SIFC_FORMAT_R16G16_SNORM                                             0x000000db
-#define   NV50_2D_SIFC_FORMAT_R16G16_SINT                                              0x000000dc
-#define   NV50_2D_SIFC_FORMAT_R16G16_UINT                                              0x000000dd
-#define   NV50_2D_SIFC_FORMAT_R16G16_FLOAT                                             0x000000de
-#define   NV50_2D_SIFC_FORMAT_A2R10G10B10_UNORM                                                0x000000df
-#define   NV50_2D_SIFC_FORMAT_B10G11R11_FLOAT                                          0x000000e0
-#define   NV50_2D_SIFC_FORMAT_R32_FLOAT                                                        0x000000e5
-#define   NV50_2D_SIFC_FORMAT_X8R8G8B8_UNORM                                           0x000000e6
-#define   NV50_2D_SIFC_FORMAT_X8R8G8B8_SRGB                                            0x000000e7
-#define   NV50_2D_SIFC_FORMAT_R5G6B5_UNORM                                             0x000000e8
-#define   NV50_2D_SIFC_FORMAT_A1R5G5B5_UNORM                                           0x000000e9
-#define   NV50_2D_SIFC_FORMAT_R8G8_UNORM                                               0x000000ea
-#define   NV50_2D_SIFC_FORMAT_R8G8_SNORM                                               0x000000eb
-#define   NV50_2D_SIFC_FORMAT_R8G8_SINT                                                        0x000000ec
-#define   NV50_2D_SIFC_FORMAT_R8G8_UINT                                                        0x000000ed
-#define   NV50_2D_SIFC_FORMAT_R16_UNORM                                                        0x000000ee
-#define   NV50_2D_SIFC_FORMAT_R16_SNORM                                                        0x000000ef
-#define   NV50_2D_SIFC_FORMAT_R16_SINT                                                 0x000000f0
-#define   NV50_2D_SIFC_FORMAT_R16_UINT                                                 0x000000f1
-#define   NV50_2D_SIFC_FORMAT_R16_FLOAT                                                        0x000000f2
-#define   NV50_2D_SIFC_FORMAT_R8_UNORM                                                 0x000000f3
-#define   NV50_2D_SIFC_FORMAT_R8_SNORM                                                 0x000000f4
-#define   NV50_2D_SIFC_FORMAT_R8_SINT                                                  0x000000f5
-#define   NV50_2D_SIFC_FORMAT_R8_UINT                                                  0x000000f6
-#define   NV50_2D_SIFC_FORMAT_A8_UNORM                                                 0x000000f7
-#define   NV50_2D_SIFC_FORMAT_X1R5G5B5_UNORM                                           0x000000f8
-#define   NV50_2D_SIFC_FORMAT_X8B8G8R8_UNORM                                           0x000000f9
-#define   NV50_2D_SIFC_FORMAT_X8B8G8R8_SRGB                                            0x000000fa
-#define  NV50_2D_SIFC_BITMAP_UNK808                                                    0x00000808
-#define  NV50_2D_SIFC_BITMAP_LSB_FIRST                                                 0x0000080c
-#define  NV50_2D_SIFC_BITMAP_LINE_PACK_MODE                                            0x00000810
-#define   NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_PACKED                                    0x00000000
-#define   NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_BYTE                                        0x00000001
-#define   NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_WORD                                        0x00000002
-#define  NV50_2D_SIFC_BITMAP_COLOR_BIT0                                                        0x00000814
-#define  NV50_2D_SIFC_BITMAP_COLOR_BIT1                                                        0x00000818
-#define  NV50_2D_SIFC_BITMAP_WRITE_BIT0_ENABLE                                         0x0000081c
-#define  NV50_2D_SIFC_WIDTH                                                            0x00000838
-#define  NV50_2D_SIFC_HEIGHT                                                           0x0000083c
-#define  NV50_2D_SIFC_DX_DU_FRACT                                                      0x00000840
-#define  NV50_2D_SIFC_DX_DU_INT                                                                0x00000844
-#define  NV50_2D_SIFC_DY_DV_FRACT                                                      0x00000848
-#define  NV50_2D_SIFC_DY_DV_INT                                                                0x0000084c
-#define  NV50_2D_SIFC_DST_X_FRACT                                                      0x00000850
-#define  NV50_2D_SIFC_DST_X_INT                                                                0x00000854
-#define  NV50_2D_SIFC_DST_Y_FRACT                                                      0x00000858
-#define  NV50_2D_SIFC_DST_Y_INT                                                                0x0000085c
-#define  NV50_2D_SIFC_DATA                                                             0x00000860
-#define  NV50_2D_BLIT_DST_X                                                            0x000008b0
-#define  NV50_2D_BLIT_DST_Y                                                            0x000008b4
-#define  NV50_2D_BLIT_DST_W                                                            0x000008b8
-#define  NV50_2D_BLIT_DST_H                                                            0x000008bc
-#define  NV50_2D_BLIT_DU_DX_FRACT                                                      0x000008c0
-#define  NV50_2D_BLIT_DU_DX_INT                                                                0x000008c4
-#define  NV50_2D_BLIT_DV_DY_FRACT                                                      0x000008c8
-#define  NV50_2D_BLIT_DV_DY_INT                                                                0x000008cc
-#define  NV50_2D_BLIT_SRC_X_FRACT                                                      0x000008d0
-#define  NV50_2D_BLIT_SRC_X_INT                                                                0x000008d4
-#define  NV50_2D_BLIT_SRC_Y_FRACT                                                      0x000008d8
-#define  NV50_2D_BLIT_SRC_Y_INT                                                                0x000008dc
-
-
-#define NV50TCL                                                                                0x00005097
-
-#define  NV50TCL_NOP                                                                   0x00000100
-#define  NV50TCL_NOTIFY                                                                        0x00000104
-#define  NV50TCL_SERIALIZE                                                             0x00000110
-#define  NV50TCL_DMA_NOTIFY                                                            0x00000180
-#define  NV50TCL_DMA_ZETA                                                              0x00000184
-#define  NV50TCL_DMA_QUERY                                                             0x00000188
-#define  NV50TCL_DMA_VTXBUF0                                                           0x0000018c
-#define  NV50TCL_DMA_LOCAL                                                             0x00000190
-#define  NV50TCL_DMA_STACK                                                             0x00000194
-#define  NV50TCL_DMA_CODE_CB                                                           0x00000198
-#define  NV50TCL_DMA_TSC                                                               0x0000019c
-#define  NV50TCL_DMA_TIC                                                               0x000001a0
-#define  NV50TCL_DMA_TEXTURE                                                           0x000001a4
-#define  NV50TCL_DMA_STRMOUT                                                           0x000001a8
-#define  NV50TCL_DMA_CLIPID                                                            0x000001ac
-#define  NV50TCL_DMA_COLOR(x)                                                          (0x000001c0+((x)*4))
-#define  NV50TCL_DMA_COLOR__SIZE                                                       0x00000008
-#define  NV50TCL_RT_ADDRESS_HIGH(x)                                                    (0x00000200+((x)*32))
-#define  NV50TCL_RT_ADDRESS_HIGH__SIZE                                                 0x00000008
-#define  NV50TCL_RT_ADDRESS_LOW(x)                                                     (0x00000204+((x)*32))
-#define  NV50TCL_RT_ADDRESS_LOW__SIZE                                                  0x00000008
-#define  NV50TCL_RT_FORMAT(x)                                                          (0x00000208+((x)*32))
-#define  NV50TCL_RT_FORMAT__SIZE                                                       0x00000008
-#define   NV50TCL_RT_FORMAT_R32G32B32A32_FLOAT                                         0x000000c0
-#define   NV50TCL_RT_FORMAT_R32G32B32A32_SINT                                          0x000000c1
-#define   NV50TCL_RT_FORMAT_R32G32B32A32_UINT                                          0x000000c2
-#define   NV50TCL_RT_FORMAT_R32G32B32X32_FLOAT                                         0x000000c3
-#define   NV50TCL_RT_FORMAT_R16G16B16A16_UNORM                                         0x000000c6
-#define   NV50TCL_RT_FORMAT_R16G16B16A16_SNORM                                         0x000000c7
-#define   NV50TCL_RT_FORMAT_R16G16B16A16_SINT                                          0x000000c8
-#define   NV50TCL_RT_FORMAT_R16G16B16A16_UINT                                          0x000000c9
-#define   NV50TCL_RT_FORMAT_R16G16B16A16_FLOAT                                         0x000000ca
-#define   NV50TCL_RT_FORMAT_R32G32_FLOAT                                               0x000000cb
-#define   NV50TCL_RT_FORMAT_R32G32_SINT                                                        0x000000cc
-#define   NV50TCL_RT_FORMAT_R32G32_UINT                                                        0x000000cd
-#define   NV50TCL_RT_FORMAT_R16G16B16X16_FLOAT                                         0x000000ce
-#define   NV50TCL_RT_FORMAT_A8R8G8B8_UNORM                                             0x000000cf
-#define   NV50TCL_RT_FORMAT_A8R8G8B8_SRGB                                              0x000000d0
-#define   NV50TCL_RT_FORMAT_A2B10G10R10_UNORM                                          0x000000d1
-#define   NV50TCL_RT_FORMAT_A2B10G10R10_UINT                                           0x000000d2
-#define   NV50TCL_RT_FORMAT_A8B8G8R8_UNORM                                             0x000000d5
-#define   NV50TCL_RT_FORMAT_A8B8G8R8_SRGB                                              0x000000d6
-#define   NV50TCL_RT_FORMAT_A8B8G8R8_SNORM                                             0x000000d7
-#define   NV50TCL_RT_FORMAT_A8B8G8R8_SINT                                              0x000000d8
-#define   NV50TCL_RT_FORMAT_A8B8G8R8_UINT                                              0x000000d9
-#define   NV50TCL_RT_FORMAT_R16G16_UNORM                                               0x000000da
-#define   NV50TCL_RT_FORMAT_R16G16_SNORM                                               0x000000db
-#define   NV50TCL_RT_FORMAT_R16G16_SINT                                                        0x000000dc
-#define   NV50TCL_RT_FORMAT_R16G16_UINT                                                        0x000000dd
-#define   NV50TCL_RT_FORMAT_R16G16_FLOAT                                               0x000000de
-#define   NV50TCL_RT_FORMAT_A2R10G10B10_UNORM                                          0x000000df
-#define   NV50TCL_RT_FORMAT_B10G11R11_FLOAT                                            0x000000e0
-#define   NV50TCL_RT_FORMAT_R32_FLOAT                                                  0x000000e5
-#define   NV50TCL_RT_FORMAT_X8R8G8B8_UNORM                                             0x000000e6
-#define   NV50TCL_RT_FORMAT_X8R8G8B8_SRGB                                              0x000000e7
-#define   NV50TCL_RT_FORMAT_R5G6B5_UNORM                                               0x000000e8
-#define   NV50TCL_RT_FORMAT_A1R5G5B5_UNORM                                             0x000000e9
-#define   NV50TCL_RT_FORMAT_R8G8_UNORM                                                 0x000000ea
-#define   NV50TCL_RT_FORMAT_R8G8_SNORM                                                 0x000000eb
-#define   NV50TCL_RT_FORMAT_R8G8_SINT                                                  0x000000ec
-#define   NV50TCL_RT_FORMAT_R8G8_UINT                                                  0x000000ed
-#define   NV50TCL_RT_FORMAT_R16_UNORM                                                  0x000000ee
-#define   NV50TCL_RT_FORMAT_R16_SNORM                                                  0x000000ef
-#define   NV50TCL_RT_FORMAT_R16_SINT                                                   0x000000f0
-#define   NV50TCL_RT_FORMAT_R16_UINT                                                   0x000000f1
-#define   NV50TCL_RT_FORMAT_R16_FLOAT                                                  0x000000f2
-#define   NV50TCL_RT_FORMAT_R8_UNORM                                                   0x000000f3
-#define   NV50TCL_RT_FORMAT_R8_SNORM                                                   0x000000f4
-#define   NV50TCL_RT_FORMAT_R8_SINT                                                    0x000000f5
-#define   NV50TCL_RT_FORMAT_R8_UINT                                                    0x000000f6
-#define   NV50TCL_RT_FORMAT_A8_UNORM                                                   0x000000f7
-#define   NV50TCL_RT_FORMAT_X1R5G5B5_UNORM                                             0x000000f8
-#define   NV50TCL_RT_FORMAT_X8B8G8R8_UNORM                                             0x000000f9
-#define   NV50TCL_RT_FORMAT_X8B8G8R8_SRGB                                              0x000000fa
-#define  NV50TCL_RT_TILE_MODE(x)                                                       (0x0000020c+((x)*32))
-#define  NV50TCL_RT_TILE_MODE__SIZE                                                    0x00000008
-#define  NV50TCL_RT_LAYER_STRIDE(x)                                                    (0x00000210+((x)*32))
-#define  NV50TCL_RT_LAYER_STRIDE__SIZE                                                 0x00000008
-#define  NV50TCL_VTX_ATTR_1F(x)                                                                (0x00000300+((x)*4))
-#define  NV50TCL_VTX_ATTR_1F__SIZE                                                     0x00000010
-#define  NV50TCL_VTX_ATTR_2H(x)                                                                (0x00000340+((x)*4))
-#define  NV50TCL_VTX_ATTR_2H__SIZE                                                     0x00000010
-#define   NV50TCL_VTX_ATTR_2H_X_SHIFT                                                  0
-#define   NV50TCL_VTX_ATTR_2H_X_MASK                                                   0x0000ffff
-#define   NV50TCL_VTX_ATTR_2H_Y_SHIFT                                                  16
-#define   NV50TCL_VTX_ATTR_2H_Y_MASK                                                   0xffff0000
-#define  NV50TCL_VTX_ATTR_2F_X(x)                                                      (0x00000380+((x)*8))
-#define  NV50TCL_VTX_ATTR_2F_X__SIZE                                                   0x00000010
-#define  NV50TCL_VTX_ATTR_2F_Y(x)                                                      (0x00000384+((x)*8))
-#define  NV50TCL_VTX_ATTR_2F_Y__SIZE                                                   0x00000010
-#define  NV50TCL_VTX_ATTR_3F_X(x)                                                      (0x00000400+((x)*16))
-#define  NV50TCL_VTX_ATTR_3F_X__SIZE                                                   0x00000010
-#define  NV50TCL_VTX_ATTR_3F_Y(x)                                                      (0x00000404+((x)*16))
-#define  NV50TCL_VTX_ATTR_3F_Y__SIZE                                                   0x00000010
-#define  NV50TCL_VTX_ATTR_3F_Z(x)                                                      (0x00000408+((x)*16))
-#define  NV50TCL_VTX_ATTR_3F_Z__SIZE                                                   0x00000010
-#define  NV50TCL_VTX_ATTR_4F_X(x)                                                      (0x00000500+((x)*16))
-#define  NV50TCL_VTX_ATTR_4F_X__SIZE                                                   0x00000010
-#define  NV50TCL_VTX_ATTR_4F_Y(x)                                                      (0x00000504+((x)*16))
-#define  NV50TCL_VTX_ATTR_4F_Y__SIZE                                                   0x00000010
-#define  NV50TCL_VTX_ATTR_4F_Z(x)                                                      (0x00000508+((x)*16))
-#define  NV50TCL_VTX_ATTR_4F_Z__SIZE                                                   0x00000010
-#define  NV50TCL_VTX_ATTR_4F_W(x)                                                      (0x0000050c+((x)*16))
-#define  NV50TCL_VTX_ATTR_4F_W__SIZE                                                   0x00000010
-#define  NV50TCL_VTX_ATTR_4H_0(x)                                                      (0x00000600+((x)*8))
-#define  NV50TCL_VTX_ATTR_4H_0__SIZE                                                   0x00000010
-#define   NV50TCL_VTX_ATTR_4H_0_X_SHIFT                                                        0
-#define   NV50TCL_VTX_ATTR_4H_0_X_MASK                                                 0x0000ffff
-#define   NV50TCL_VTX_ATTR_4H_0_Y_SHIFT                                                        16
-#define   NV50TCL_VTX_ATTR_4H_0_Y_MASK                                                 0xffff0000
-#define  NV50TCL_VTX_ATTR_4H_1(x)                                                      (0x00000604+((x)*8))
-#define  NV50TCL_VTX_ATTR_4H_1__SIZE                                                   0x00000010
-#define   NV50TCL_VTX_ATTR_4H_1_Z_SHIFT                                                        0
-#define   NV50TCL_VTX_ATTR_4H_1_Z_MASK                                                 0x0000ffff
-#define   NV50TCL_VTX_ATTR_4H_1_W_SHIFT                                                        16
-#define   NV50TCL_VTX_ATTR_4H_1_W_MASK                                                 0xffff0000
-#define  NV50TCL_VTX_ATTR_2I(x)                                                                (0x00000680+((x)*4))
-#define  NV50TCL_VTX_ATTR_2I__SIZE                                                     0x00000010
-#define   NV50TCL_VTX_ATTR_2I_X_SHIFT                                                  0
-#define   NV50TCL_VTX_ATTR_2I_X_MASK                                                   0x0000ffff
-#define   NV50TCL_VTX_ATTR_2I_Y_SHIFT                                                  16
-#define   NV50TCL_VTX_ATTR_2I_Y_MASK                                                   0xffff0000
-#define  NV50TCL_VTX_ATTR_2NI(x)                                                       (0x000006c0+((x)*4))
-#define  NV50TCL_VTX_ATTR_2NI__SIZE                                                    0x00000010
-#define   NV50TCL_VTX_ATTR_2NI_X_SHIFT                                                 0
-#define   NV50TCL_VTX_ATTR_2NI_X_MASK                                                  0x0000ffff
-#define   NV50TCL_VTX_ATTR_2NI_Y_SHIFT                                                 16
-#define   NV50TCL_VTX_ATTR_2NI_Y_MASK                                                  0xffff0000
-#define  NV50TCL_VTX_ATTR_4I_0(x)                                                      (0x00000700+((x)*8))
-#define  NV50TCL_VTX_ATTR_4I_0__SIZE                                                   0x00000010
-#define   NV50TCL_VTX_ATTR_4I_0_X_SHIFT                                                        0
-#define   NV50TCL_VTX_ATTR_4I_0_X_MASK                                                 0x0000ffff
-#define   NV50TCL_VTX_ATTR_4I_0_Y_SHIFT                                                        16
-#define   NV50TCL_VTX_ATTR_4I_0_Y_MASK                                                 0xffff0000
-#define  NV50TCL_VTX_ATTR_4I_1(x)                                                      (0x00000704+((x)*8))
-#define  NV50TCL_VTX_ATTR_4I_1__SIZE                                                   0x00000010
-#define   NV50TCL_VTX_ATTR_4I_1_Z_SHIFT                                                        0
-#define   NV50TCL_VTX_ATTR_4I_1_Z_MASK                                                 0x0000ffff
-#define   NV50TCL_VTX_ATTR_4I_1_W_SHIFT                                                        16
-#define   NV50TCL_VTX_ATTR_4I_1_W_MASK                                                 0xffff0000
-#define  NV50TCL_VTX_ATTR_4NI_0(x)                                                     (0x00000780+((x)*8))
-#define  NV50TCL_VTX_ATTR_4NI_0__SIZE                                                  0x00000010
-#define   NV50TCL_VTX_ATTR_4NI_0_X_SHIFT                                               0
-#define   NV50TCL_VTX_ATTR_4NI_0_X_MASK                                                        0x0000ffff
-#define   NV50TCL_VTX_ATTR_4NI_0_Y_SHIFT                                               16
-#define   NV50TCL_VTX_ATTR_4NI_0_Y_MASK                                                        0xffff0000
-#define  NV50TCL_VTX_ATTR_4NI_1(x)                                                     (0x00000784+((x)*8))
-#define  NV50TCL_VTX_ATTR_4NI_1__SIZE                                                  0x00000010
-#define   NV50TCL_VTX_ATTR_4NI_1_Z_SHIFT                                               0
-#define   NV50TCL_VTX_ATTR_4NI_1_Z_MASK                                                        0x0000ffff
-#define   NV50TCL_VTX_ATTR_4NI_1_W_SHIFT                                               16
-#define   NV50TCL_VTX_ATTR_4NI_1_W_MASK                                                        0xffff0000
-#define  NV50TCL_VTX_ATTR_4UB(x)                                                       (0x00000800+((x)*4))
-#define  NV50TCL_VTX_ATTR_4UB__SIZE                                                    0x00000010
-#define   NV50TCL_VTX_ATTR_4UB_X_SHIFT                                                 0
-#define   NV50TCL_VTX_ATTR_4UB_X_MASK                                                  0x000000ff
-#define   NV50TCL_VTX_ATTR_4UB_Y_SHIFT                                                 8
-#define   NV50TCL_VTX_ATTR_4UB_Y_MASK                                                  0x0000ff00
-#define   NV50TCL_VTX_ATTR_4UB_Z_SHIFT                                                 16
-#define   NV50TCL_VTX_ATTR_4UB_Z_MASK                                                  0x00ff0000
-#define   NV50TCL_VTX_ATTR_4UB_W_SHIFT                                                 24
-#define   NV50TCL_VTX_ATTR_4UB_W_MASK                                                  0xff000000
-#define  NV50TCL_VTX_ATTR_4B(x)                                                                (0x00000840+((x)*4))
-#define  NV50TCL_VTX_ATTR_4B__SIZE                                                     0x00000010
-#define   NV50TCL_VTX_ATTR_4B_X_SHIFT                                                  0
-#define   NV50TCL_VTX_ATTR_4B_X_MASK                                                   0x000000ff
-#define   NV50TCL_VTX_ATTR_4B_Y_SHIFT                                                  8
-#define   NV50TCL_VTX_ATTR_4B_Y_MASK                                                   0x0000ff00
-#define   NV50TCL_VTX_ATTR_4B_Z_SHIFT                                                  16
-#define   NV50TCL_VTX_ATTR_4B_Z_MASK                                                   0x00ff0000
-#define   NV50TCL_VTX_ATTR_4B_W_SHIFT                                                  24
-#define   NV50TCL_VTX_ATTR_4B_W_MASK                                                   0xff000000
-#define  NV50TCL_VTX_ATTR_4NUB(x)                                                      (0x00000880+((x)*4))
-#define  NV50TCL_VTX_ATTR_4NUB__SIZE                                                   0x00000010
-#define   NV50TCL_VTX_ATTR_4NUB_X_SHIFT                                                        0
-#define   NV50TCL_VTX_ATTR_4NUB_X_MASK                                                 0x000000ff
-#define   NV50TCL_VTX_ATTR_4NUB_Y_SHIFT                                                        8
-#define   NV50TCL_VTX_ATTR_4NUB_Y_MASK                                                 0x0000ff00
-#define   NV50TCL_VTX_ATTR_4NUB_Z_SHIFT                                                        16
-#define   NV50TCL_VTX_ATTR_4NUB_Z_MASK                                                 0x00ff0000
-#define   NV50TCL_VTX_ATTR_4NUB_W_SHIFT                                                        24
-#define   NV50TCL_VTX_ATTR_4NUB_W_MASK                                                 0xff000000
-#define  NV50TCL_VTX_ATTR_4NB(x)                                                       (0x000008c0+((x)*4))
-#define  NV50TCL_VTX_ATTR_4NB__SIZE                                                    0x00000010
-#define   NV50TCL_VTX_ATTR_4NB_X_SHIFT                                                 0
-#define   NV50TCL_VTX_ATTR_4NB_X_MASK                                                  0x000000ff
-#define   NV50TCL_VTX_ATTR_4NB_Y_SHIFT                                                 8
-#define   NV50TCL_VTX_ATTR_4NB_Y_MASK                                                  0x0000ff00
-#define   NV50TCL_VTX_ATTR_4NB_Z_SHIFT                                                 16
-#define   NV50TCL_VTX_ATTR_4NB_Z_MASK                                                  0x00ff0000
-#define   NV50TCL_VTX_ATTR_4NB_W_SHIFT                                                 24
-#define   NV50TCL_VTX_ATTR_4NB_W_MASK                                                  0xff000000
-#define  NV50TCL_VERTEX_ARRAY_FORMAT(x)                                                        (0x00000900+((x)*16))
-#define  NV50TCL_VERTEX_ARRAY_FORMAT__SIZE                                             0x00000010
-#define   NV50TCL_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT                                     0
-#define   NV50TCL_VERTEX_ARRAY_FORMAT_STRIDE_MASK                                      0x00000fff
-#define   NV50TCL_VERTEX_ARRAY_FORMAT_ENABLE                                           (1 << 29)
-#define  NV50TCL_VERTEX_ARRAY_START_HIGH(x)                                            (0x00000904+((x)*16))
-#define  NV50TCL_VERTEX_ARRAY_START_HIGH__SIZE                                         0x00000010
-#define  NV50TCL_VERTEX_ARRAY_START_LOW(x)                                             (0x00000908+((x)*16))
-#define  NV50TCL_VERTEX_ARRAY_START_LOW__SIZE                                          0x00000010
-#define  NV50TCL_VIEWPORT_SCALE_X(x)                                                   (0x00000a00+((x)*32))
-#define  NV50TCL_VIEWPORT_SCALE_X__SIZE                                                        0x00000010
-#define  NV50TCL_VIEWPORT_SCALE_Y(x)                                                   (0x00000a04+((x)*32))
-#define  NV50TCL_VIEWPORT_SCALE_Y__SIZE                                                        0x00000010
-#define  NV50TCL_VIEWPORT_SCALE_Z(x)                                                   (0x00000a08+((x)*32))
-#define  NV50TCL_VIEWPORT_SCALE_Z__SIZE                                                        0x00000010
-#define  NV50TCL_VIEWPORT_TRANSLATE_X(x)                                               (0x00000a0c+((x)*32))
-#define  NV50TCL_VIEWPORT_TRANSLATE_X__SIZE                                            0x00000010
-#define  NV50TCL_VIEWPORT_TRANSLATE_Y(x)                                               (0x00000a10+((x)*32))
-#define  NV50TCL_VIEWPORT_TRANSLATE_Y__SIZE                                            0x00000010
-#define  NV50TCL_VIEWPORT_TRANSLATE_Z(x)                                               (0x00000a14+((x)*32))
-#define  NV50TCL_VIEWPORT_TRANSLATE_Z__SIZE                                            0x00000010
-#define  NV50TCL_VIEWPORT_HORIZ(x)                                                     (0x00000c00+((x)*16))
-#define  NV50TCL_VIEWPORT_HORIZ__SIZE                                                  0x00000010
-#define   NV50TCL_VIEWPORT_HORIZ_X_SHIFT                                               0
-#define   NV50TCL_VIEWPORT_HORIZ_X_MASK                                                        0x0000ffff
-#define   NV50TCL_VIEWPORT_HORIZ_W_SHIFT                                               16
-#define   NV50TCL_VIEWPORT_HORIZ_W_MASK                                                        0xffff0000
-#define  NV50TCL_VIEWPORT_VERT(x)                                                      (0x00000c04+((x)*16))
-#define  NV50TCL_VIEWPORT_VERT__SIZE                                                   0x00000010
-#define   NV50TCL_VIEWPORT_VERT_Y_SHIFT                                                        0
-#define   NV50TCL_VIEWPORT_VERT_Y_MASK                                                 0x0000ffff
-#define   NV50TCL_VIEWPORT_VERT_H_SHIFT                                                        16
-#define   NV50TCL_VIEWPORT_VERT_H_MASK                                                 0xffff0000
-#define  NV50TCL_DEPTH_RANGE_NEAR(x)                                                   (0x00000c08+((x)*16))
-#define  NV50TCL_DEPTH_RANGE_NEAR__SIZE                                                        0x00000010
-#define  NV50TCL_DEPTH_RANGE_FAR(x)                                                    (0x00000c0c+((x)*16))
-#define  NV50TCL_DEPTH_RANGE_FAR__SIZE                                                 0x00000010
-#define  NV50TCL_VIEWPORT_CLIP_HORIZ(x)                                                        (0x00000d00+((x)*8))
-#define  NV50TCL_VIEWPORT_CLIP_HORIZ__SIZE                                             0x00000008
-#define   NV50TCL_VIEWPORT_CLIP_HORIZ_MIN_SHIFT                                                0
-#define   NV50TCL_VIEWPORT_CLIP_HORIZ_MIN_MASK                                         0x0000ffff
-#define   NV50TCL_VIEWPORT_CLIP_HORIZ_MAX_SHIFT                                                16
-#define   NV50TCL_VIEWPORT_CLIP_HORIZ_MAX_MASK                                         0xffff0000
-#define  NV50TCL_VIEWPORT_CLIP_VERT(x)                                                 (0x00000d04+((x)*8))
-#define  NV50TCL_VIEWPORT_CLIP_VERT__SIZE                                              0x00000008
-#define   NV50TCL_VIEWPORT_CLIP_VERT_MIN_SHIFT                                         0
-#define   NV50TCL_VIEWPORT_CLIP_VERT_MIN_MASK                                          0x0000ffff
-#define   NV50TCL_VIEWPORT_CLIP_VERT_MAX_SHIFT                                         16
-#define   NV50TCL_VIEWPORT_CLIP_VERT_MAX_MASK                                          0xffff0000
-#define  NV50TCL_CLIPID_REGION_HORIZ(x)                                                        (0x00000d40+((x)*8))
-#define  NV50TCL_CLIPID_REGION_HORIZ__SIZE                                             0x00000004
-#define  NV50TCL_CLIPID_REGION_VERT(x)                                                 (0x00000d44+((x)*8))
-#define  NV50TCL_CLIPID_REGION_VERT__SIZE                                              0x00000004
-#define  NV50TCL_VERTEX_BUFFER_FIRST                                                   0x00000d74
-#define  NV50TCL_VERTEX_BUFFER_COUNT                                                   0x00000d78
-#define  NV50TCL_CLEAR_COLOR(x)                                                                (0x00000d80+((x)*4))
-#define  NV50TCL_CLEAR_COLOR__SIZE                                                     0x00000004
-#define  NV50TCL_CLEAR_DEPTH                                                           0x00000d90
-#define  NV50TCL_STACK_ADDRESS_HIGH                                                    0x00000d94
-#define  NV50TCL_STACK_ADDRESS_LOW                                                     0x00000d98
-#define  NV50TCL_STACK_SIZE_LOG                                                                0x00000d9c
-#define  NV50TCL_CLEAR_STENCIL                                                         0x00000da0
-#define  NV50TCL_STRMOUT_PRIMITIVE_COUNT                                               0x00000da8
-#define  NV50TCL_POLYGON_MODE_FRONT                                                    0x00000dac
-#define   NV50TCL_POLYGON_MODE_FRONT_POINT                                             0x00001b00
-#define   NV50TCL_POLYGON_MODE_FRONT_LINE                                              0x00001b01
-#define   NV50TCL_POLYGON_MODE_FRONT_FILL                                              0x00001b02
-#define  NV50TCL_POLYGON_MODE_BACK                                                     0x00000db0
-#define   NV50TCL_POLYGON_MODE_BACK_POINT                                              0x00001b00
-#define   NV50TCL_POLYGON_MODE_BACK_LINE                                               0x00001b01
-#define   NV50TCL_POLYGON_MODE_BACK_FILL                                               0x00001b02
-#define  NV50TCL_POLYGON_SMOOTH_ENABLE                                                 0x00000db4
-#define  NV50TCL_POLYGON_OFFSET_POINT_ENABLE                                           0x00000dc0
-#define  NV50TCL_POLYGON_OFFSET_LINE_ENABLE                                            0x00000dc4
-#define  NV50TCL_POLYGON_OFFSET_FILL_ENABLE                                            0x00000dc8
-#define  NV50TCL_WATCHDOG_TIMER                                                                0x00000de4
-#define  NV50TCL_WINDOW_OFFSET_X                                                       0x00000df8
-#define  NV50TCL_WINDOW_OFFSET_Y                                                       0x00000dfc
-#define  NV50TCL_SCISSOR_ENABLE(x)                                                     (0x00000e00+((x)*16))
-#define  NV50TCL_SCISSOR_ENABLE__SIZE                                                  0x00000010
-#define  NV50TCL_SCISSOR_HORIZ(x)                                                      (0x00000e04+((x)*16))
-#define  NV50TCL_SCISSOR_HORIZ__SIZE                                                   0x00000010
-#define   NV50TCL_SCISSOR_HORIZ_MIN_SHIFT                                              0
-#define   NV50TCL_SCISSOR_HORIZ_MIN_MASK                                               0x0000ffff
-#define   NV50TCL_SCISSOR_HORIZ_MAX_SHIFT                                              16
-#define   NV50TCL_SCISSOR_HORIZ_MAX_MASK                                               0xffff0000
-#define  NV50TCL_SCISSOR_VERT(x)                                                       (0x00000e08+((x)*16))
-#define  NV50TCL_SCISSOR_VERT__SIZE                                                    0x00000010
-#define   NV50TCL_SCISSOR_VERT_MIN_SHIFT                                               0
-#define   NV50TCL_SCISSOR_VERT_MIN_MASK                                                        0x0000ffff
-#define   NV50TCL_SCISSOR_VERT_MAX_SHIFT                                               16
-#define   NV50TCL_SCISSOR_VERT_MAX_MASK                                                        0xffff0000
-#define  NV50TCL_CB_ADDR                                                               0x00000f00
-#define   NV50TCL_CB_ADDR_ID_SHIFT                                                     8
-#define   NV50TCL_CB_ADDR_ID_MASK                                                      0x003fff00
-#define   NV50TCL_CB_ADDR_BUFFER_SHIFT                                                 0
-#define   NV50TCL_CB_ADDR_BUFFER_MASK                                                  0x0000007f
-#define  NV50TCL_CB_DATA(x)                                                            (0x00000f04+((x)*4))
-#define  NV50TCL_CB_DATA__SIZE                                                         0x00000010
-#define  NV50TCL_LOCAL_WARPS_LOG_ALLOC                                                 0x00000f44
-#define  NV50TCL_LOCAL_WARPS_NO_CLAMP                                                  0x00000f48
-#define  NV50TCL_STACK_WARPS_LOG_ALLOC                                                 0x00000f4c
-#define  NV50TCL_STACK_WARPS_NO_CLAMP                                                  0x00000f50
-#define  NV50TCL_STENCIL_BACK_FUNC_REF                                                 0x00000f54
-#define  NV50TCL_STENCIL_BACK_MASK                                                     0x00000f58
-#define  NV50TCL_STENCIL_BACK_FUNC_MASK                                                        0x00000f5c
-#define  NV50TCL_GP_ADDRESS_HIGH                                                       0x00000f70
-#define  NV50TCL_GP_ADDRESS_LOW                                                                0x00000f74
-#define  NV50TCL_VP_ADDRESS_HIGH                                                       0x00000f7c
-#define  NV50TCL_VP_ADDRESS_LOW                                                                0x00000f80
-#define  NV50TCL_VERTEX_RUNOUT_HIGH                                                    0x00000f84
-#define  NV50TCL_VERTEX_RUNOUT_LOW                                                     0x00000f88
-#define  NV50TCL_DEPTH_BOUNDS(x)                                                       (0x00000f9c+((x)*4))
-#define  NV50TCL_DEPTH_BOUNDS__SIZE                                                    0x00000002
-#define  NV50TCL_FP_ADDRESS_HIGH                                                       0x00000fa4
-#define  NV50TCL_FP_ADDRESS_LOW                                                                0x00000fa8
-#define  NV50TCL_MSAA_MASK(x)                                                          (0x00000fbc+((x)*4))
-#define  NV50TCL_MSAA_MASK__SIZE                                                       0x00000004
-#define  NV50TCL_CLIPID_ADDRESS_HIGH                                                   0x00000fcc
-#define  NV50TCL_CLIPID_ADDRESS_LOW                                                    0x00000fd0
-#define  NV50TCL_ZETA_ADDRESS_HIGH                                                     0x00000fe0
-#define  NV50TCL_ZETA_ADDRESS_LOW                                                      0x00000fe4
-#define  NV50TCL_ZETA_FORMAT                                                           0x00000fe8
-#define   NV50TCL_ZETA_FORMAT_Z32_FLOAT                                                        0x0000000a
-#define   NV50TCL_ZETA_FORMAT_Z16_UNORM                                                        0x00000013
-#define   NV50TCL_ZETA_FORMAT_Z24S8_UNORM                                              0x00000014
-#define   NV50TCL_ZETA_FORMAT_X8Z24_UNORM                                              0x00000015
-#define   NV50TCL_ZETA_FORMAT_S8Z24_UNORM                                              0x00000016
-#define   NV50TCL_ZETA_FORMAT_Z32_FLOAT_X24S8_UNORM                                    0x00000019
-#define  NV50TCL_ZETA_TILE_MODE                                                                0x00000fec
-#define  NV50TCL_ZETA_LAYER_STRIDE                                                     0x00000ff0
-#define  NV50TCL_SCREEN_SCISSOR_HORIZ                                                  0x00000ff4
-#define   NV50TCL_SCREEN_SCISSOR_HORIZ_W_SHIFT                                         16
-#define   NV50TCL_SCREEN_SCISSOR_HORIZ_W_MASK                                          0xffff0000
-#define   NV50TCL_SCREEN_SCISSOR_HORIZ_X_SHIFT                                         0
-#define   NV50TCL_SCREEN_SCISSOR_HORIZ_X_MASK                                          0x0000ffff
-#define  NV50TCL_SCREEN_SCISSOR_VERT                                                   0x00000ff8
-#define   NV50TCL_SCREEN_SCISSOR_VERT_H_SHIFT                                          16
-#define   NV50TCL_SCREEN_SCISSOR_VERT_H_MASK                                           0xffff0000
-#define   NV50TCL_SCREEN_SCISSOR_VERT_Y_SHIFT                                          0
-#define   NV50TCL_SCREEN_SCISSOR_VERT_Y_MASK                                           0x0000ffff
-#define  NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(x)                                            (0x00001080+((x)*8))
-#define  NV50TCL_VERTEX_ARRAY_LIMIT_HIGH__SIZE                                         0x00000010
-#define  NV50TCL_VERTEX_ARRAY_LIMIT_LOW(x)                                             (0x00001084+((x)*8))
-#define  NV50TCL_VERTEX_ARRAY_LIMIT_LOW__SIZE                                          0x00000010
-#define  NV50TCL_RT_CONTROL                                                            0x0000121c
-#define   NV50TCL_RT_CONTROL_COUNT_SHIFT                                               0
-#define   NV50TCL_RT_CONTROL_COUNT_MASK                                                        0x0000000f
-#define   NV50TCL_RT_CONTROL_MAP0_SHIFT                                                        4
-#define   NV50TCL_RT_CONTROL_MAP0_MASK                                                 0x00000070
-#define   NV50TCL_RT_CONTROL_MAP1_SHIFT                                                        7
-#define   NV50TCL_RT_CONTROL_MAP1_MASK                                                 0x00000380
-#define   NV50TCL_RT_CONTROL_MAP2_SHIFT                                                        10
-#define   NV50TCL_RT_CONTROL_MAP2_MASK                                                 0x00001c00
-#define   NV50TCL_RT_CONTROL_MAP3_SHIFT                                                        13
-#define   NV50TCL_RT_CONTROL_MAP3_MASK                                                 0x0000e000
-#define   NV50TCL_RT_CONTROL_MAP4_SHIFT                                                        16
-#define   NV50TCL_RT_CONTROL_MAP4_MASK                                                 0x00070000
-#define   NV50TCL_RT_CONTROL_MAP5_SHIFT                                                        19
-#define   NV50TCL_RT_CONTROL_MAP5_MASK                                                 0x00380000
-#define   NV50TCL_RT_CONTROL_MAP6_SHIFT                                                        22
-#define   NV50TCL_RT_CONTROL_MAP6_MASK                                                 0x01c00000
-#define   NV50TCL_RT_CONTROL_MAP7_SHIFT                                                        25
-#define   NV50TCL_RT_CONTROL_MAP7_MASK                                                 0x0e000000
-#define  NV50TCL_RT_ARRAY_MODE                                                         0x00001224
-#define   NV50TCL_RT_ARRAY_MODE_LAYERS_SHIFT                                           0
-#define   NV50TCL_RT_ARRAY_MODE_LAYERS_MASK                                            0x0000ffff
-#define   NV50TCL_RT_ARRAY_MODE_VOLUME                                                 (1 << 16)
-#define  NV50TCL_ZETA_HORIZ                                                            0x00001228
-#define  NV50TCL_ZETA_VERT                                                             0x0000122c
-#define  NV50TCL_ZETA_ARRAY_MODE                                                       0x00001230
-#define   NV50TCL_ZETA_ARRAY_MODE_LAYERS_SHIFT                                         0
-#define   NV50TCL_ZETA_ARRAY_MODE_LAYERS_MASK                                          0x0000ffff
-#define   NV50TCL_ZETA_ARRAY_MODE_UNK                                                  (1 << 16)
-#define  NV50TCL_LINKED_TSC                                                            0x00001234
-#define  NV50TCL_RT_HORIZ(x)                                                           (0x00001240+((x)*8))
-#define  NV50TCL_RT_HORIZ__SIZE                                                                0x00000008
-#define  NV50TCL_RT_VERT(x)                                                            (0x00001244+((x)*8))
-#define  NV50TCL_RT_VERT__SIZE                                                         0x00000008
-#define  NV50TCL_CB_DEF_ADDRESS_HIGH                                                   0x00001280
-#define  NV50TCL_CB_DEF_ADDRESS_LOW                                                    0x00001284
-#define  NV50TCL_CB_DEF_SET                                                            0x00001288
-#define   NV50TCL_CB_DEF_SET_SIZE_SHIFT                                                        0
-#define   NV50TCL_CB_DEF_SET_SIZE_MASK                                                 0x0000ffff
-#define   NV50TCL_CB_DEF_SET_BUFFER_SHIFT                                              16
-#define   NV50TCL_CB_DEF_SET_BUFFER_MASK                                               0x007f0000
-#define  NV50TCL_STRMOUT_BUFFERS_CTRL                                                  0x00001294
-#define   NV50TCL_STRMOUT_BUFFERS_CTRL_INTERLEAVED                                     (1 <<  0)
-#define   NV50TCL_STRMOUT_BUFFERS_CTRL_SEPARATE_SHIFT                                  4
-#define   NV50TCL_STRMOUT_BUFFERS_CTRL_SEPARATE_MASK                                   0x000000f0
-#define   NV50TCL_STRMOUT_BUFFERS_CTRL_STRIDE_SHIFT                                    8
-#define   NV50TCL_STRMOUT_BUFFERS_CTRL_STRIDE_MASK                                     0x0000ff00
-#define  NV50TCL_FP_RESULT_COUNT                                                       0x00001298
-#define  NV50TCL_DEPTH_TEST_ENABLE                                                     0x000012cc
-#define  NV50TCL_SHADE_MODEL                                                           0x000012d4
-#define   NV50TCL_SHADE_MODEL_FLAT                                                     0x00001d00
-#define   NV50TCL_SHADE_MODEL_SMOOTH                                                   0x00001d01
-#define  NV50TCL_LOCAL_ADDRESS_HIGH                                                    0x000012d8
-#define  NV50TCL_LOCAL_ADDRESS_LOW                                                     0x000012dc
-#define  NV50TCL_LOCAL_SIZE_LOG                                                                0x000012e0
-#define  NV50TCL_DEPTH_WRITE_ENABLE                                                    0x000012e8
-#define  NV50TCL_ALPHA_TEST_ENABLE                                                     0x000012ec
-#define  NV50TCL_PM_SET(x)                                                             (0x000012f0+((x)*4))
-#define  NV50TCL_PM_SET__SIZE                                                          0x00000004
-#define  NV50TCL_VB_ELEMENT_U8_SETUP                                                   0x00001300
-#define   NV50TCL_VB_ELEMENT_U8_SETUP_OFFSET_SHIFT                                     30
-#define   NV50TCL_VB_ELEMENT_U8_SETUP_OFFSET_MASK                                      0xc0000000
-#define   NV50TCL_VB_ELEMENT_U8_SETUP_COUNT_SHIFT                                      0
-#define   NV50TCL_VB_ELEMENT_U8_SETUP_COUNT_MASK                                       0x3fffffff
-#define  NV50TCL_VB_ELEMENT_U8                                                         0x00001304
-#define   NV50TCL_VB_ELEMENT_U8_I0_SHIFT                                               0
-#define   NV50TCL_VB_ELEMENT_U8_I0_MASK                                                        0x000000ff
-#define   NV50TCL_VB_ELEMENT_U8_I1_SHIFT                                               8
-#define   NV50TCL_VB_ELEMENT_U8_I1_MASK                                                        0x0000ff00
-#define   NV50TCL_VB_ELEMENT_U8_I2_SHIFT                                               16
-#define   NV50TCL_VB_ELEMENT_U8_I2_MASK                                                        0x00ff0000
-#define   NV50TCL_VB_ELEMENT_U8_I3_SHIFT                                               24
-#define   NV50TCL_VB_ELEMENT_U8_I3_MASK                                                        0xff000000
-#define  NV50TCL_DEPTH_TEST_FUNC                                                       0x0000130c
-#define   NV50TCL_DEPTH_TEST_FUNC_NEVER                                                        0x00000200
-#define   NV50TCL_DEPTH_TEST_FUNC_LESS                                                 0x00000201
-#define   NV50TCL_DEPTH_TEST_FUNC_EQUAL                                                        0x00000202
-#define   NV50TCL_DEPTH_TEST_FUNC_LEQUAL                                               0x00000203
-#define   NV50TCL_DEPTH_TEST_FUNC_GREATER                                              0x00000204
-#define   NV50TCL_DEPTH_TEST_FUNC_NOTEQUAL                                             0x00000205
-#define   NV50TCL_DEPTH_TEST_FUNC_GEQUAL                                               0x00000206
-#define   NV50TCL_DEPTH_TEST_FUNC_ALWAYS                                               0x00000207
-#define  NV50TCL_ALPHA_TEST_REF                                                                0x00001310
-#define  NV50TCL_ALPHA_TEST_FUNC                                                       0x00001314
-#define   NV50TCL_ALPHA_TEST_FUNC_NEVER                                                        0x00000200
-#define   NV50TCL_ALPHA_TEST_FUNC_LESS                                                 0x00000201
-#define   NV50TCL_ALPHA_TEST_FUNC_EQUAL                                                        0x00000202
-#define   NV50TCL_ALPHA_TEST_FUNC_LEQUAL                                               0x00000203
-#define   NV50TCL_ALPHA_TEST_FUNC_GREATER                                              0x00000204
-#define   NV50TCL_ALPHA_TEST_FUNC_NOTEQUAL                                             0x00000205
-#define   NV50TCL_ALPHA_TEST_FUNC_GEQUAL                                               0x00000206
-#define   NV50TCL_ALPHA_TEST_FUNC_ALWAYS                                               0x00000207
-#define  NV50TCL_BLEND_COLOR(x)                                                                (0x0000131c+((x)*4))
-#define  NV50TCL_BLEND_COLOR__SIZE                                                     0x00000004
-#define  NV50TCL_TIC_FLUSH                                                             0x00001330
-#define  NV50TCL_TSC_FLUSH                                                             0x00001334
-#define  NV50TCL_TEX_CACHE_CTL                                                         0x00001338
-#define  NV50TCL_BLEND_EQUATION_RGB                                                    0x00001340
-#define   NV50TCL_BLEND_EQUATION_RGB_FUNC_ADD                                          0x00008006
-#define   NV50TCL_BLEND_EQUATION_RGB_MIN                                               0x00008007
-#define   NV50TCL_BLEND_EQUATION_RGB_MAX                                               0x00008008
-#define   NV50TCL_BLEND_EQUATION_RGB_FUNC_SUBTRACT                                     0x0000800a
-#define   NV50TCL_BLEND_EQUATION_RGB_FUNC_REVERSE_SUBTRACT                             0x0000800b
-#define  NV50TCL_BLEND_FUNC_SRC_RGB                                                    0x00001344
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_ZERO                                              0x00004000
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_ONE                                               0x00004001
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_SRC_COLOR                                         0x00004300
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_COLOR                               0x00004301
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA                                         0x00004302
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_ALPHA                               0x00004303
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_DST_ALPHA                                         0x00004304
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_ALPHA                               0x00004305
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_DST_COLOR                                         0x00004306
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_COLOR                               0x00004307
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA_SATURATE                                        0x00004308
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_COLOR                                    0x0000c001
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_COLOR                          0x0000c002
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_ALPHA                                    0x0000c003
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_ALPHA                          0x0000c004
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_SRC1_COLOR                                                0x0000c900
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC1_COLOR                              0x0000c901
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_SRC1_ALPHA                                                0x0000c902
-#define   NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC1_ALPHA                              0x0000c903
-#define  NV50TCL_BLEND_FUNC_DST_RGB                                                    0x00001348
-#define   NV50TCL_BLEND_FUNC_DST_RGB_ZERO                                              0x00004000
-#define   NV50TCL_BLEND_FUNC_DST_RGB_ONE                                               0x00004001
-#define   NV50TCL_BLEND_FUNC_DST_RGB_SRC_COLOR                                         0x00004300
-#define   NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_COLOR                               0x00004301
-#define   NV50TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA                                         0x00004302
-#define   NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA                               0x00004303
-#define   NV50TCL_BLEND_FUNC_DST_RGB_DST_ALPHA                                         0x00004304
-#define   NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_ALPHA                               0x00004305
-#define   NV50TCL_BLEND_FUNC_DST_RGB_DST_COLOR                                         0x00004306
-#define   NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_COLOR                               0x00004307
-#define   NV50TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA_SATURATE                                        0x00004308
-#define   NV50TCL_BLEND_FUNC_DST_RGB_CONSTANT_COLOR                                    0x0000c001
-#define   NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_COLOR                          0x0000c002
-#define   NV50TCL_BLEND_FUNC_DST_RGB_CONSTANT_ALPHA                                    0x0000c003
-#define   NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_ALPHA                          0x0000c004
-#define   NV50TCL_BLEND_FUNC_DST_RGB_SRC1_COLOR                                                0x0000c900
-#define   NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC1_COLOR                              0x0000c901
-#define   NV50TCL_BLEND_FUNC_DST_RGB_SRC1_ALPHA                                                0x0000c902
-#define   NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC1_ALPHA                              0x0000c903
-#define  NV50TCL_BLEND_EQUATION_ALPHA                                                  0x0000134c
-#define   NV50TCL_BLEND_EQUATION_ALPHA_FUNC_ADD                                                0x00008006
-#define   NV50TCL_BLEND_EQUATION_ALPHA_MIN                                             0x00008007
-#define   NV50TCL_BLEND_EQUATION_ALPHA_MAX                                             0x00008008
-#define   NV50TCL_BLEND_EQUATION_ALPHA_FUNC_SUBTRACT                                   0x0000800a
-#define   NV50TCL_BLEND_EQUATION_ALPHA_FUNC_REVERSE_SUBTRACT                           0x0000800b
-#define  NV50TCL_BLEND_FUNC_SRC_ALPHA                                                  0x00001350
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_ZERO                                            0x00004000
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE                                             0x00004001
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_COLOR                                       0x00004300
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_COLOR                             0x00004301
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA                                       0x00004302
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_ALPHA                             0x00004303
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_DST_ALPHA                                       0x00004304
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_ALPHA                             0x00004305
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_DST_COLOR                                       0x00004306
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_COLOR                             0x00004307
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA_SATURATE                              0x00004308
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_COLOR                                  0x0000c001
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_COLOR                                0x0000c002
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_ALPHA                                  0x0000c003
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_ALPHA                                0x0000c004
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC1_COLOR                                      0x0000c900
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC1_COLOR                            0x0000c901
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC1_ALPHA                                      0x0000c902
-#define   NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC1_ALPHA                            0x0000c903
-#define  NV50TCL_BLEND_FUNC_DST_ALPHA                                                  0x00001358
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_ZERO                                            0x00004000
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_ONE                                             0x00004001
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_COLOR                                       0x00004300
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_COLOR                             0x00004301
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA                                       0x00004302
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_ALPHA                             0x00004303
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_DST_ALPHA                                       0x00004304
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_ALPHA                             0x00004305
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_DST_COLOR                                       0x00004306
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_COLOR                             0x00004307
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA_SATURATE                              0x00004308
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_COLOR                                  0x0000c001
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_COLOR                                0x0000c002
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_ALPHA                                  0x0000c003
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_ALPHA                                0x0000c004
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_SRC1_COLOR                                      0x0000c900
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC1_COLOR                            0x0000c901
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_SRC1_ALPHA                                      0x0000c902
-#define   NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC1_ALPHA                            0x0000c903
-#define  NV50TCL_BLEND_ENABLE(x)                                                       (0x00001360+((x)*4))
-#define  NV50TCL_BLEND_ENABLE__SIZE                                                    0x00000008
-#define  NV50TCL_STENCIL_FRONT_ENABLE                                                  0x00001380
-#define  NV50TCL_STENCIL_FRONT_OP_FAIL                                                 0x00001384
-#define   NV50TCL_STENCIL_FRONT_OP_FAIL_ZERO                                           0x00000000
-#define   NV50TCL_STENCIL_FRONT_OP_FAIL_INVERT                                         0x0000150a
-#define   NV50TCL_STENCIL_FRONT_OP_FAIL_KEEP                                           0x00001e00
-#define   NV50TCL_STENCIL_FRONT_OP_FAIL_REPLACE                                                0x00001e01
-#define   NV50TCL_STENCIL_FRONT_OP_FAIL_INCR                                           0x00001e02
-#define   NV50TCL_STENCIL_FRONT_OP_FAIL_DECR                                           0x00001e03
-#define   NV50TCL_STENCIL_FRONT_OP_FAIL_INCR_WRAP                                      0x00008507
-#define   NV50TCL_STENCIL_FRONT_OP_FAIL_DECR_WRAP                                      0x00008508
-#define  NV50TCL_STENCIL_FRONT_OP_ZFAIL                                                        0x00001388
-#define   NV50TCL_STENCIL_FRONT_OP_ZFAIL_ZERO                                          0x00000000
-#define   NV50TCL_STENCIL_FRONT_OP_ZFAIL_INVERT                                                0x0000150a
-#define   NV50TCL_STENCIL_FRONT_OP_ZFAIL_KEEP                                          0x00001e00
-#define   NV50TCL_STENCIL_FRONT_OP_ZFAIL_REPLACE                                       0x00001e01
-#define   NV50TCL_STENCIL_FRONT_OP_ZFAIL_INCR                                          0x00001e02
-#define   NV50TCL_STENCIL_FRONT_OP_ZFAIL_DECR                                          0x00001e03
-#define   NV50TCL_STENCIL_FRONT_OP_ZFAIL_INCR_WRAP                                     0x00008507
-#define   NV50TCL_STENCIL_FRONT_OP_ZFAIL_DECR_WRAP                                     0x00008508
-#define  NV50TCL_STENCIL_FRONT_OP_ZPASS                                                        0x0000138c
-#define   NV50TCL_STENCIL_FRONT_OP_ZPASS_ZERO                                          0x00000000
-#define   NV50TCL_STENCIL_FRONT_OP_ZPASS_INVERT                                                0x0000150a
-#define   NV50TCL_STENCIL_FRONT_OP_ZPASS_KEEP                                          0x00001e00
-#define   NV50TCL_STENCIL_FRONT_OP_ZPASS_REPLACE                                       0x00001e01
-#define   NV50TCL_STENCIL_FRONT_OP_ZPASS_INCR                                          0x00001e02
-#define   NV50TCL_STENCIL_FRONT_OP_ZPASS_DECR                                          0x00001e03
-#define   NV50TCL_STENCIL_FRONT_OP_ZPASS_INCR_WRAP                                     0x00008507
-#define   NV50TCL_STENCIL_FRONT_OP_ZPASS_DECR_WRAP                                     0x00008508
-#define  NV50TCL_STENCIL_FRONT_FUNC_FUNC                                               0x00001390
-#define   NV50TCL_STENCIL_FRONT_FUNC_FUNC_NEVER                                                0x00000200
-#define   NV50TCL_STENCIL_FRONT_FUNC_FUNC_LESS                                         0x00000201
-#define   NV50TCL_STENCIL_FRONT_FUNC_FUNC_EQUAL                                                0x00000202
-#define   NV50TCL_STENCIL_FRONT_FUNC_FUNC_LEQUAL                                       0x00000203
-#define   NV50TCL_STENCIL_FRONT_FUNC_FUNC_GREATER                                      0x00000204
-#define   NV50TCL_STENCIL_FRONT_FUNC_FUNC_NOTEQUAL                                     0x00000205
-#define   NV50TCL_STENCIL_FRONT_FUNC_FUNC_GEQUAL                                       0x00000206
-#define   NV50TCL_STENCIL_FRONT_FUNC_FUNC_ALWAYS                                       0x00000207
-#define  NV50TCL_STENCIL_FRONT_FUNC_REF                                                        0x00001394
-#define  NV50TCL_STENCIL_FRONT_MASK                                                    0x00001398
-#define  NV50TCL_STENCIL_FRONT_FUNC_MASK                                               0x0000139c
-#define  NV50TCL_FRAG_COLOR_CLAMP_EN                                                   0x000013a8
-#define  NV50TCL_Y_ORIGIN_BOTTOM                                                       0x000013ac
-#define  NV50TCL_LINE_WIDTH                                                            0x000013b0
-#define  NV50TCL_TEX_LIMITS(x)                                                         (0x000013b4+((x)*4))
-#define  NV50TCL_TEX_LIMITS__SIZE                                                      0x00000003
-#define   NV50TCL_TEX_LIMITS_SAMPLERS_LOG2_SHIFT                                       0
-#define   NV50TCL_TEX_LIMITS_SAMPLERS_LOG2_MASK                                                0x0000000f
-#define   NV50TCL_TEX_LIMITS_TEXTURES_LOG2_SHIFT                                       4
-#define   NV50TCL_TEX_LIMITS_TEXTURES_LOG2_MASK                                                0x000000f0
-#define  NV50TCL_POINT_COORD_REPLACE_MAP(x)                                            (0x000013c0+((x)*4))
-#define  NV50TCL_POINT_COORD_REPLACE_MAP__SIZE                                         0x00000008
-#define  NV50TCL_VP_START_ID                                                           0x0000140c
-#define  NV50TCL_GP_START_ID                                                           0x00001410
-#define  NV50TCL_FP_START_ID                                                           0x00001414
-#define  NV50TCL_GP_VERTEX_OUTPUT_COUNT                                                        0x00001420
-#define  NV50TCL_VB_ELEMENT_BASE                                                       0x00001434
-#define  NV50TCL_CLEAR_FLAGS                                                           0x0000143c
-#define   NV50TCL_CLEAR_FLAGS_OGL                                                      (1 <<  0)
-#define   NV50TCL_CLEAR_FLAGS_D3D                                                      (1 <<  4)
-#define  NV50TCL_INSTANCE_BASE                                                         0x00001438
-#define  NV50TCL_CODE_CB_FLUSH                                                         0x00001440
-#define  NV50TCL_BIND_TSC(x)                                                           (0x00001444+((x)*8))
-#define  NV50TCL_BIND_TSC__SIZE                                                                0x00000003
-#define   NV50TCL_BIND_TSC_VALID                                                       (1 <<  0)
-#define   NV50TCL_BIND_TSC_SAMPLER_SHIFT                                               4
-#define   NV50TCL_BIND_TSC_SAMPLER_MASK                                                        0x000000f0
-#define   NV50TCL_BIND_TSC_TSC_SHIFT                                                   12
-#define   NV50TCL_BIND_TSC_TSC_MASK                                                    0x001ff000
-#define  NV50TCL_BIND_TIC(x)                                                           (0x00001448+((x)*8))
-#define  NV50TCL_BIND_TIC__SIZE                                                                0x00000003
-#define   NV50TCL_BIND_TIC_VALID                                                       (1 <<  0)
-#define   NV50TCL_BIND_TIC_TEXTURE_SHIFT                                               1
-#define   NV50TCL_BIND_TIC_TEXTURE_MASK                                                        0x000001fe
-#define   NV50TCL_BIND_TIC_TIC_SHIFT                                                   9
-#define   NV50TCL_BIND_TIC_TIC_MASK                                                    0x7ffffe00
-#define  NV50TCL_STRMOUT_MAP(x)                                                                (0x00001480+((x)*4))
-#define  NV50TCL_STRMOUT_MAP__SIZE                                                     0x00000020
-#define  NV50TCL_CLIPID_HEIGHT                                                         0x00001504
-#define  NV50TCL_VP_CLIP_DISTANCE_ENABLE                                               0x00001510
-#define   NV50TCL_VP_CLIP_DISTANCE_ENABLE_0                                            (1 <<  0)
-#define   NV50TCL_VP_CLIP_DISTANCE_ENABLE_1                                            (1 <<  1)
-#define   NV50TCL_VP_CLIP_DISTANCE_ENABLE_2                                            (1 <<  2)
-#define   NV50TCL_VP_CLIP_DISTANCE_ENABLE_3                                            (1 <<  3)
-#define   NV50TCL_VP_CLIP_DISTANCE_ENABLE_4                                            (1 <<  4)
-#define   NV50TCL_VP_CLIP_DISTANCE_ENABLE_5                                            (1 <<  5)
-#define   NV50TCL_VP_CLIP_DISTANCE_ENABLE_6                                            (1 <<  6)
-#define   NV50TCL_VP_CLIP_DISTANCE_ENABLE_7                                            (1 <<  7)
-#define  NV50TCL_SAMPLECNT_ENABLE                                                      0x00001514
-#define  NV50TCL_POINT_SIZE                                                            0x00001518
-#define  NV50TCL_POINT_SPRITE_ENABLE                                                   0x00001520
-#define  NV50TCL_SAMPLECNT_RESET                                                       0x00001530
-#define  NV50TCL_ZETA_ENABLE                                                           0x00001538
-#define  NV50TCL_MULTISAMPLE_CTRL                                                      0x0000153c
-#define   NV50TCL_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE                                   (1 <<  0)
-#define   NV50TCL_MULTISAMPLE_CTRL_ALPHA_TO_ONE                                                (1 <<  4)
-#define  NV50TCL_NOPERSPECTIVE_BITMAP(x)                                               (0x00001540+((x)*4))
-#define  NV50TCL_NOPERSPECTIVE_BITMAP__SIZE                                            0x00000004
-#define  NV50TCL_COND_ADDRESS_HIGH                                                     0x00001550
-#define  NV50TCL_COND_ADDRESS_LOW                                                      0x00001554
-#define  NV50TCL_COND_MODE                                                             0x00001558
-#define   NV50TCL_COND_MODE_NEVER                                                      0x00000000
-#define   NV50TCL_COND_MODE_ALWAYS                                                     0x00000001
-#define   NV50TCL_COND_MODE_RES                                                                0x00000002
-#define   NV50TCL_COND_MODE_NOT_RES_AND_NOT_ID                                         0x00000003
-#define   NV50TCL_COND_MODE_RES_OR_ID                                                  0x00000004
-#define  NV50TCL_TSC_ADDRESS_HIGH                                                      0x0000155c
-#define  NV50TCL_TSC_ADDRESS_LOW                                                       0x00001560
-#define  NV50TCL_TSC_LIMIT                                                             0x00001564
-#define  NV50TCL_POLYGON_OFFSET_FACTOR                                                 0x0000156c
-#define  NV50TCL_LINE_SMOOTH_ENABLE                                                    0x00001570
-#define  NV50TCL_TIC_ADDRESS_HIGH                                                      0x00001574
-#define  NV50TCL_TIC_ADDRESS_LOW                                                       0x00001578
-#define  NV50TCL_TIC_LIMIT                                                             0x0000157c
-#define  NV50TCL_PM_CONTROL(x)                                                         (0x00001580+((x)*4))
-#define  NV50TCL_PM_CONTROL__SIZE                                                      0x00000004
-#define   NV50TCL_PM_CONTROL_UNK0                                                      (1 <<  0)
-#define   NV50TCL_PM_CONTROL_UNK1_SHIFT                                                        4
-#define   NV50TCL_PM_CONTROL_UNK1_MASK                                                 0x00000070
-#define   NV50TCL_PM_CONTROL_UNK2_SHIFT                                                        8
-#define   NV50TCL_PM_CONTROL_UNK2_MASK                                                 0xffffff00
-#define  NV50TCL_STENCIL_BACK_ENABLE                                                   0x00001594
-#define  NV50TCL_STENCIL_BACK_OP_FAIL                                                  0x00001598
-#define   NV50TCL_STENCIL_BACK_OP_FAIL_ZERO                                            0x00000000
-#define   NV50TCL_STENCIL_BACK_OP_FAIL_INVERT                                          0x0000150a
-#define   NV50TCL_STENCIL_BACK_OP_FAIL_KEEP                                            0x00001e00
-#define   NV50TCL_STENCIL_BACK_OP_FAIL_REPLACE                                         0x00001e01
-#define   NV50TCL_STENCIL_BACK_OP_FAIL_INCR                                            0x00001e02
-#define   NV50TCL_STENCIL_BACK_OP_FAIL_DECR                                            0x00001e03
-#define   NV50TCL_STENCIL_BACK_OP_FAIL_INCR_WRAP                                       0x00008507
-#define   NV50TCL_STENCIL_BACK_OP_FAIL_DECR_WRAP                                       0x00008508
-#define  NV50TCL_STENCIL_BACK_OP_ZFAIL                                                 0x0000159c
-#define   NV50TCL_STENCIL_BACK_OP_ZFAIL_ZERO                                           0x00000000
-#define   NV50TCL_STENCIL_BACK_OP_ZFAIL_INVERT                                         0x0000150a
-#define   NV50TCL_STENCIL_BACK_OP_ZFAIL_KEEP                                           0x00001e00
-#define   NV50TCL_STENCIL_BACK_OP_ZFAIL_REPLACE                                                0x00001e01
-#define   NV50TCL_STENCIL_BACK_OP_ZFAIL_INCR                                           0x00001e02
-#define   NV50TCL_STENCIL_BACK_OP_ZFAIL_DECR                                           0x00001e03
-#define   NV50TCL_STENCIL_BACK_OP_ZFAIL_INCR_WRAP                                      0x00008507
-#define   NV50TCL_STENCIL_BACK_OP_ZFAIL_DECR_WRAP                                      0x00008508
-#define  NV50TCL_STENCIL_BACK_OP_ZPASS                                                 0x000015a0
-#define   NV50TCL_STENCIL_BACK_OP_ZPASS_ZERO                                           0x00000000
-#define   NV50TCL_STENCIL_BACK_OP_ZPASS_INVERT                                         0x0000150a
-#define   NV50TCL_STENCIL_BACK_OP_ZPASS_KEEP                                           0x00001e00
-#define   NV50TCL_STENCIL_BACK_OP_ZPASS_REPLACE                                                0x00001e01
-#define   NV50TCL_STENCIL_BACK_OP_ZPASS_INCR                                           0x00001e02
-#define   NV50TCL_STENCIL_BACK_OP_ZPASS_DECR                                           0x00001e03
-#define   NV50TCL_STENCIL_BACK_OP_ZPASS_INCR_WRAP                                      0x00008507
-#define   NV50TCL_STENCIL_BACK_OP_ZPASS_DECR_WRAP                                      0x00008508
-#define  NV50TCL_STENCIL_BACK_FUNC_FUNC                                                        0x000015a4
-#define   NV50TCL_STENCIL_BACK_FUNC_FUNC_NEVER                                         0x00000200
-#define   NV50TCL_STENCIL_BACK_FUNC_FUNC_LESS                                          0x00000201
-#define   NV50TCL_STENCIL_BACK_FUNC_FUNC_EQUAL                                         0x00000202
-#define   NV50TCL_STENCIL_BACK_FUNC_FUNC_LEQUAL                                                0x00000203
-#define   NV50TCL_STENCIL_BACK_FUNC_FUNC_GREATER                                       0x00000204
-#define   NV50TCL_STENCIL_BACK_FUNC_FUNC_NOTEQUAL                                      0x00000205
-#define   NV50TCL_STENCIL_BACK_FUNC_FUNC_GEQUAL                                                0x00000206
-#define   NV50TCL_STENCIL_BACK_FUNC_FUNC_ALWAYS                                                0x00000207
-#define  NV50TCL_FRAMEBUFFER_SRGB                                                      0x000015b8
-#define  NV50TCL_POLYGON_OFFSET_UNITS                                                  0x000015bc
-#define  NV50TCL_GP_BUILTIN_RESULT_EN                                                  0x000015cc
-#define   NV50TCL_GP_BUILTIN_RESULT_EN_VPORT_IDX                                       (1 <<  0)
-#define   NV50TCL_GP_BUILTIN_RESULT_EN_LAYER_IDX                                       (1 << 16)
-#define  NV50TCL_MULTISAMPLE_MODE                                                      0x000015d0
-#define   NV50TCL_MULTISAMPLE_MODE_1X                                                  0x00000000
-#define   NV50TCL_MULTISAMPLE_MODE_2XMS                                                        0x00000001
-#define   NV50TCL_MULTISAMPLE_MODE_4XMS                                                        0x00000002
-#define   NV50TCL_MULTISAMPLE_MODE_8XMS                                                        0x00000004
-#define   NV50TCL_MULTISAMPLE_MODE_4XMS_4XCS                                           0x00000008
-#define   NV50TCL_MULTISAMPLE_MODE_4XMS_12XCS                                          0x00000009
-#define   NV50TCL_MULTISAMPLE_MODE_8XMS_8XCS                                           0x0000000a
-#define  NV50TCL_VERTEX_BEGIN                                                          0x000015dc
-#define   NV50TCL_VERTEX_BEGIN_POINTS                                                  0x00000000
-#define   NV50TCL_VERTEX_BEGIN_LINES                                                   0x00000001
-#define   NV50TCL_VERTEX_BEGIN_LINE_LOOP                                               0x00000002
-#define   NV50TCL_VERTEX_BEGIN_LINE_STRIP                                              0x00000003
-#define   NV50TCL_VERTEX_BEGIN_TRIANGLES                                               0x00000004
-#define   NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP                                          0x00000005
-#define   NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN                                            0x00000006
-#define   NV50TCL_VERTEX_BEGIN_QUADS                                                   0x00000007
-#define   NV50TCL_VERTEX_BEGIN_QUAD_STRIP                                              0x00000008
-#define   NV50TCL_VERTEX_BEGIN_POLYGON                                                 0x00000009
-#define   NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY                                         0x0000000a
-#define   NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY                                    0x0000000b
-#define   NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY                                     0x0000000c
-#define   NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY                                        0x0000000d
-#define   NV50TCL_VERTEX_BEGIN_PATCHES                                                 0x0000000e
-#define  NV50TCL_VERTEX_END                                                            0x000015e0
-#define  NV50TCL_EDGEFLAG_ENABLE                                                       0x000015e4
-#define  NV50TCL_VB_ELEMENT_U32                                                                0x000015e8
-#define  NV50TCL_VB_ELEMENT_U16_SETUP                                                  0x000015ec
-#define   NV50TCL_VB_ELEMENT_U16_SETUP_OFFSET_SHIFT                                    30
-#define   NV50TCL_VB_ELEMENT_U16_SETUP_OFFSET_MASK                                     0xc0000000
-#define   NV50TCL_VB_ELEMENT_U16_SETUP_COUNT_SHIFT                                     0
-#define   NV50TCL_VB_ELEMENT_U16_SETUP_COUNT_MASK                                      0x3fffffff
-#define  NV50TCL_VB_ELEMENT_U16                                                                0x000015f0
-#define   NV50TCL_VB_ELEMENT_U16_I0_SHIFT                                              0
-#define   NV50TCL_VB_ELEMENT_U16_I0_MASK                                               0x0000ffff
-#define   NV50TCL_VB_ELEMENT_U16_I1_SHIFT                                              16
-#define   NV50TCL_VB_ELEMENT_U16_I1_MASK                                               0xffff0000
-#define  NV50TCL_VERTEX_BASE_HIGH                                                      0x000015f4
-#define  NV50TCL_VERTEX_BASE_LOW                                                       0x000015f8
-#define  NV50TCL_VERTEX_DATA                                                           0x00001640
-#define  NV50TCL_PRIM_RESTART_ENABLE                                                   0x00001644
-#define  NV50TCL_PRIM_RESTART_INDEX                                                    0x00001648
-#define  NV50TCL_VP_GP_BUILTIN_ATTR_EN                                                 0x0000164c
-#define   NV50TCL_VP_GP_BUILTIN_ATTR_EN_VERTEX_ID                                      (1 <<  0)
-#define   NV50TCL_VP_GP_BUILTIN_ATTR_EN_INSTANCE_ID                                    (1 <<  4)
-#define   NV50TCL_VP_GP_BUILTIN_ATTR_EN_PRIMITIVE_ID                                   (1 <<  8)
-#define   NV50TCL_VP_GP_BUILTIN_ATTR_EN_UNK12                                          (1 << 12)
-#define  NV50TCL_VP_ATTR_EN_0                                                          0x00001650
-#define   NV50TCL_VP_ATTR_EN_0_7_SHIFT                                                 28
-#define   NV50TCL_VP_ATTR_EN_0_7_MASK                                                  0xf0000000
-#define    NV50TCL_VP_ATTR_EN_0_7_NONE                                                 0x00000000
-#define    NV50TCL_VP_ATTR_EN_0_7_XNNN                                                 0x10000000
-#define    NV50TCL_VP_ATTR_EN_0_7_NYNN                                                 0x20000000
-#define    NV50TCL_VP_ATTR_EN_0_7_XYNN                                                 0x30000000
-#define    NV50TCL_VP_ATTR_EN_0_7_NNZN                                                 0x40000000
-#define    NV50TCL_VP_ATTR_EN_0_7_XNZN                                                 0x50000000
-#define    NV50TCL_VP_ATTR_EN_0_7_NYZN                                                 0x60000000
-#define    NV50TCL_VP_ATTR_EN_0_7_XYZN                                                 0x70000000
-#define    NV50TCL_VP_ATTR_EN_0_7_NNNW                                                 0x80000000
-#define    NV50TCL_VP_ATTR_EN_0_7_XNNW                                                 0x90000000
-#define    NV50TCL_VP_ATTR_EN_0_7_NYNW                                                 0xa0000000
-#define    NV50TCL_VP_ATTR_EN_0_7_XYNW                                                 0xb0000000
-#define    NV50TCL_VP_ATTR_EN_0_7_NNZW                                                 0xc0000000
-#define    NV50TCL_VP_ATTR_EN_0_7_XNZW                                                 0xd0000000
-#define    NV50TCL_VP_ATTR_EN_0_7_NYZW                                                 0xe0000000
-#define    NV50TCL_VP_ATTR_EN_0_7_XYZW                                                 0xf0000000
-#define   NV50TCL_VP_ATTR_EN_0_6_SHIFT                                                 24
-#define   NV50TCL_VP_ATTR_EN_0_6_MASK                                                  0x0f000000
-#define    NV50TCL_VP_ATTR_EN_0_6_NONE                                                 0x00000000
-#define    NV50TCL_VP_ATTR_EN_0_6_XNNN                                                 0x01000000
-#define    NV50TCL_VP_ATTR_EN_0_6_NYNN                                                 0x02000000
-#define    NV50TCL_VP_ATTR_EN_0_6_XYNN                                                 0x03000000
-#define    NV50TCL_VP_ATTR_EN_0_6_NNZN                                                 0x04000000
-#define    NV50TCL_VP_ATTR_EN_0_6_XNZN                                                 0x05000000
-#define    NV50TCL_VP_ATTR_EN_0_6_NYZN                                                 0x06000000
-#define    NV50TCL_VP_ATTR_EN_0_6_XYZN                                                 0x07000000
-#define    NV50TCL_VP_ATTR_EN_0_6_NNNW                                                 0x08000000
-#define    NV50TCL_VP_ATTR_EN_0_6_XNNW                                                 0x09000000
-#define    NV50TCL_VP_ATTR_EN_0_6_NYNW                                                 0x0a000000
-#define    NV50TCL_VP_ATTR_EN_0_6_XYNW                                                 0x0b000000
-#define    NV50TCL_VP_ATTR_EN_0_6_NNZW                                                 0x0c000000
-#define    NV50TCL_VP_ATTR_EN_0_6_XNZW                                                 0x0d000000
-#define    NV50TCL_VP_ATTR_EN_0_6_NYZW                                                 0x0e000000
-#define    NV50TCL_VP_ATTR_EN_0_6_XYZW                                                 0x0f000000
-#define   NV50TCL_VP_ATTR_EN_0_5_SHIFT                                                 20
-#define   NV50TCL_VP_ATTR_EN_0_5_MASK                                                  0x00f00000
-#define    NV50TCL_VP_ATTR_EN_0_5_NONE                                                 0x00000000
-#define    NV50TCL_VP_ATTR_EN_0_5_XNNN                                                 0x00100000
-#define    NV50TCL_VP_ATTR_EN_0_5_NYNN                                                 0x00200000
-#define    NV50TCL_VP_ATTR_EN_0_5_XYNN                                                 0x00300000
-#define    NV50TCL_VP_ATTR_EN_0_5_NNZN                                                 0x00400000
-#define    NV50TCL_VP_ATTR_EN_0_5_XNZN                                                 0x00500000
-#define    NV50TCL_VP_ATTR_EN_0_5_NYZN                                                 0x00600000
-#define    NV50TCL_VP_ATTR_EN_0_5_XYZN                                                 0x00700000
-#define    NV50TCL_VP_ATTR_EN_0_5_NNNW                                                 0x00800000
-#define    NV50TCL_VP_ATTR_EN_0_5_XNNW                                                 0x00900000
-#define    NV50TCL_VP_ATTR_EN_0_5_NYNW                                                 0x00a00000
-#define    NV50TCL_VP_ATTR_EN_0_5_XYNW                                                 0x00b00000
-#define    NV50TCL_VP_ATTR_EN_0_5_NNZW                                                 0x00c00000
-#define    NV50TCL_VP_ATTR_EN_0_5_XNZW                                                 0x00d00000
-#define    NV50TCL_VP_ATTR_EN_0_5_NYZW                                                 0x00e00000
-#define    NV50TCL_VP_ATTR_EN_0_5_XYZW                                                 0x00f00000
-#define   NV50TCL_VP_ATTR_EN_0_4_SHIFT                                                 16
-#define   NV50TCL_VP_ATTR_EN_0_4_MASK                                                  0x000f0000
-#define    NV50TCL_VP_ATTR_EN_0_4_NONE                                                 0x00000000
-#define    NV50TCL_VP_ATTR_EN_0_4_XNNN                                                 0x00010000
-#define    NV50TCL_VP_ATTR_EN_0_4_NYNN                                                 0x00020000
-#define    NV50TCL_VP_ATTR_EN_0_4_XYNN                                                 0x00030000
-#define    NV50TCL_VP_ATTR_EN_0_4_NNZN                                                 0x00040000
-#define    NV50TCL_VP_ATTR_EN_0_4_XNZN                                                 0x00050000
-#define    NV50TCL_VP_ATTR_EN_0_4_NYZN                                                 0x00060000
-#define    NV50TCL_VP_ATTR_EN_0_4_XYZN                                                 0x00070000
-#define    NV50TCL_VP_ATTR_EN_0_4_NNNW                                                 0x00080000
-#define    NV50TCL_VP_ATTR_EN_0_4_XNNW                                                 0x00090000
-#define    NV50TCL_VP_ATTR_EN_0_4_NYNW                                                 0x000a0000
-#define    NV50TCL_VP_ATTR_EN_0_4_XYNW                                                 0x000b0000
-#define    NV50TCL_VP_ATTR_EN_0_4_NNZW                                                 0x000c0000
-#define    NV50TCL_VP_ATTR_EN_0_4_XNZW                                                 0x000d0000
-#define    NV50TCL_VP_ATTR_EN_0_4_NYZW                                                 0x000e0000
-#define    NV50TCL_VP_ATTR_EN_0_4_XYZW                                                 0x000f0000
-#define   NV50TCL_VP_ATTR_EN_0_3_SHIFT                                                 12
-#define   NV50TCL_VP_ATTR_EN_0_3_MASK                                                  0x0000f000
-#define    NV50TCL_VP_ATTR_EN_0_3_NONE                                                 0x00000000
-#define    NV50TCL_VP_ATTR_EN_0_3_XNNN                                                 0x00001000
-#define    NV50TCL_VP_ATTR_EN_0_3_NYNN                                                 0x00002000
-#define    NV50TCL_VP_ATTR_EN_0_3_XYNN                                                 0x00003000
-#define    NV50TCL_VP_ATTR_EN_0_3_NNZN                                                 0x00004000
-#define    NV50TCL_VP_ATTR_EN_0_3_XNZN                                                 0x00005000
-#define    NV50TCL_VP_ATTR_EN_0_3_NYZN                                                 0x00006000
-#define    NV50TCL_VP_ATTR_EN_0_3_XYZN                                                 0x00007000
-#define    NV50TCL_VP_ATTR_EN_0_3_NNNW                                                 0x00008000
-#define    NV50TCL_VP_ATTR_EN_0_3_XNNW                                                 0x00009000
-#define    NV50TCL_VP_ATTR_EN_0_3_NYNW                                                 0x0000a000
-#define    NV50TCL_VP_ATTR_EN_0_3_XYNW                                                 0x0000b000
-#define    NV50TCL_VP_ATTR_EN_0_3_NNZW                                                 0x0000c000
-#define    NV50TCL_VP_ATTR_EN_0_3_XNZW                                                 0x0000d000
-#define    NV50TCL_VP_ATTR_EN_0_3_NYZW                                                 0x0000e000
-#define    NV50TCL_VP_ATTR_EN_0_3_XYZW                                                 0x0000f000
-#define   NV50TCL_VP_ATTR_EN_0_2_SHIFT                                                 8
-#define   NV50TCL_VP_ATTR_EN_0_2_MASK                                                  0x00000f00
-#define    NV50TCL_VP_ATTR_EN_0_2_NONE                                                 0x00000000
-#define    NV50TCL_VP_ATTR_EN_0_2_XNNN                                                 0x00000100
-#define    NV50TCL_VP_ATTR_EN_0_2_NYNN                                                 0x00000200
-#define    NV50TCL_VP_ATTR_EN_0_2_XYNN                                                 0x00000300
-#define    NV50TCL_VP_ATTR_EN_0_2_NNZN                                                 0x00000400
-#define    NV50TCL_VP_ATTR_EN_0_2_XNZN                                                 0x00000500
-#define    NV50TCL_VP_ATTR_EN_0_2_NYZN                                                 0x00000600
-#define    NV50TCL_VP_ATTR_EN_0_2_XYZN                                                 0x00000700
-#define    NV50TCL_VP_ATTR_EN_0_2_NNNW                                                 0x00000800
-#define    NV50TCL_VP_ATTR_EN_0_2_XNNW                                                 0x00000900
-#define    NV50TCL_VP_ATTR_EN_0_2_NYNW                                                 0x00000a00
-#define    NV50TCL_VP_ATTR_EN_0_2_XYNW                                                 0x00000b00
-#define    NV50TCL_VP_ATTR_EN_0_2_NNZW                                                 0x00000c00
-#define    NV50TCL_VP_ATTR_EN_0_2_XNZW                                                 0x00000d00
-#define    NV50TCL_VP_ATTR_EN_0_2_NYZW                                                 0x00000e00
-#define    NV50TCL_VP_ATTR_EN_0_2_XYZW                                                 0x00000f00
-#define   NV50TCL_VP_ATTR_EN_0_1_SHIFT                                                 4
-#define   NV50TCL_VP_ATTR_EN_0_1_MASK                                                  0x000000f0
-#define    NV50TCL_VP_ATTR_EN_0_1_NONE                                                 0x00000000
-#define    NV50TCL_VP_ATTR_EN_0_1_XNNN                                                 0x00000010
-#define    NV50TCL_VP_ATTR_EN_0_1_NYNN                                                 0x00000020
-#define    NV50TCL_VP_ATTR_EN_0_1_XYNN                                                 0x00000030
-#define    NV50TCL_VP_ATTR_EN_0_1_NNZN                                                 0x00000040
-#define    NV50TCL_VP_ATTR_EN_0_1_XNZN                                                 0x00000050
-#define    NV50TCL_VP_ATTR_EN_0_1_NYZN                                                 0x00000060
-#define    NV50TCL_VP_ATTR_EN_0_1_XYZN                                                 0x00000070
-#define    NV50TCL_VP_ATTR_EN_0_1_NNNW                                                 0x00000080
-#define    NV50TCL_VP_ATTR_EN_0_1_XNNW                                                 0x00000090
-#define    NV50TCL_VP_ATTR_EN_0_1_NYNW                                                 0x000000a0
-#define    NV50TCL_VP_ATTR_EN_0_1_XYNW                                                 0x000000b0
-#define    NV50TCL_VP_ATTR_EN_0_1_NNZW                                                 0x000000c0
-#define    NV50TCL_VP_ATTR_EN_0_1_XNZW                                                 0x000000d0
-#define    NV50TCL_VP_ATTR_EN_0_1_NYZW                                                 0x000000e0
-#define    NV50TCL_VP_ATTR_EN_0_1_XYZW                                                 0x000000f0
-#define   NV50TCL_VP_ATTR_EN_0_0_SHIFT                                                 0
-#define   NV50TCL_VP_ATTR_EN_0_0_MASK                                                  0x0000000f
-#define    NV50TCL_VP_ATTR_EN_0_0_NONE                                                 0x00000000
-#define    NV50TCL_VP_ATTR_EN_0_0_XNNN                                                 0x00000001
-#define    NV50TCL_VP_ATTR_EN_0_0_NYNN                                                 0x00000002
-#define    NV50TCL_VP_ATTR_EN_0_0_XYNN                                                 0x00000003
-#define    NV50TCL_VP_ATTR_EN_0_0_NNZN                                                 0x00000004
-#define    NV50TCL_VP_ATTR_EN_0_0_XNZN                                                 0x00000005
-#define    NV50TCL_VP_ATTR_EN_0_0_NYZN                                                 0x00000006
-#define    NV50TCL_VP_ATTR_EN_0_0_XYZN                                                 0x00000007
-#define    NV50TCL_VP_ATTR_EN_0_0_NNNW                                                 0x00000008
-#define    NV50TCL_VP_ATTR_EN_0_0_XNNW                                                 0x00000009
-#define    NV50TCL_VP_ATTR_EN_0_0_NYNW                                                 0x0000000a
-#define    NV50TCL_VP_ATTR_EN_0_0_XYNW                                                 0x0000000b
-#define    NV50TCL_VP_ATTR_EN_0_0_NNZW                                                 0x0000000c
-#define    NV50TCL_VP_ATTR_EN_0_0_XNZW                                                 0x0000000d
-#define    NV50TCL_VP_ATTR_EN_0_0_NYZW                                                 0x0000000e
-#define    NV50TCL_VP_ATTR_EN_0_0_XYZW                                                 0x0000000f
-#define  NV50TCL_VP_ATTR_EN_1                                                          0x00001654
-#define   NV50TCL_VP_ATTR_EN_1_15_SHIFT                                                        28
-#define   NV50TCL_VP_ATTR_EN_1_15_MASK                                                 0xf0000000
-#define    NV50TCL_VP_ATTR_EN_1_15_NONE                                                        0x00000000
-#define    NV50TCL_VP_ATTR_EN_1_15_XNNN                                                        0x10000000
-#define    NV50TCL_VP_ATTR_EN_1_15_NYNN                                                        0x20000000
-#define    NV50TCL_VP_ATTR_EN_1_15_XYNN                                                        0x30000000
-#define    NV50TCL_VP_ATTR_EN_1_15_NNZN                                                        0x40000000
-#define    NV50TCL_VP_ATTR_EN_1_15_XNZN                                                        0x50000000
-#define    NV50TCL_VP_ATTR_EN_1_15_NYZN                                                        0x60000000
-#define    NV50TCL_VP_ATTR_EN_1_15_XYZN                                                        0x70000000
-#define    NV50TCL_VP_ATTR_EN_1_15_NNNW                                                        0x80000000
-#define    NV50TCL_VP_ATTR_EN_1_15_XNNW                                                        0x90000000
-#define    NV50TCL_VP_ATTR_EN_1_15_NYNW                                                        0xa0000000
-#define    NV50TCL_VP_ATTR_EN_1_15_XYNW                                                        0xb0000000
-#define    NV50TCL_VP_ATTR_EN_1_15_NNZW                                                        0xc0000000
-#define    NV50TCL_VP_ATTR_EN_1_15_XNZW                                                        0xd0000000
-#define    NV50TCL_VP_ATTR_EN_1_15_NYZW                                                        0xe0000000
-#define    NV50TCL_VP_ATTR_EN_1_15_XYZW                                                        0xf0000000
-#define   NV50TCL_VP_ATTR_EN_1_14_SHIFT                                                        24
-#define   NV50TCL_VP_ATTR_EN_1_14_MASK                                                 0x0f000000
-#define    NV50TCL_VP_ATTR_EN_1_14_NONE                                                        0x00000000
-#define    NV50TCL_VP_ATTR_EN_1_14_XNNN                                                        0x01000000
-#define    NV50TCL_VP_ATTR_EN_1_14_NYNN                                                        0x02000000
-#define    NV50TCL_VP_ATTR_EN_1_14_XYNN                                                        0x03000000
-#define    NV50TCL_VP_ATTR_EN_1_14_NNZN                                                        0x04000000
-#define    NV50TCL_VP_ATTR_EN_1_14_XNZN                                                        0x05000000
-#define    NV50TCL_VP_ATTR_EN_1_14_NYZN                                                        0x06000000
-#define    NV50TCL_VP_ATTR_EN_1_14_XYZN                                                        0x07000000
-#define    NV50TCL_VP_ATTR_EN_1_14_NNNW                                                        0x08000000
-#define    NV50TCL_VP_ATTR_EN_1_14_XNNW                                                        0x09000000
-#define    NV50TCL_VP_ATTR_EN_1_14_NYNW                                                        0x0a000000
-#define    NV50TCL_VP_ATTR_EN_1_14_XYNW                                                        0x0b000000
-#define    NV50TCL_VP_ATTR_EN_1_14_NNZW                                                        0x0c000000
-#define    NV50TCL_VP_ATTR_EN_1_14_XNZW                                                        0x0d000000
-#define    NV50TCL_VP_ATTR_EN_1_14_NYZW                                                        0x0e000000
-#define    NV50TCL_VP_ATTR_EN_1_14_XYZW                                                        0x0f000000
-#define   NV50TCL_VP_ATTR_EN_1_13_SHIFT                                                        20
-#define   NV50TCL_VP_ATTR_EN_1_13_MASK                                                 0x00f00000
-#define    NV50TCL_VP_ATTR_EN_1_13_NONE                                                        0x00000000
-#define    NV50TCL_VP_ATTR_EN_1_13_XNNN                                                        0x00100000
-#define    NV50TCL_VP_ATTR_EN_1_13_NYNN                                                        0x00200000
-#define    NV50TCL_VP_ATTR_EN_1_13_XYNN                                                        0x00300000
-#define    NV50TCL_VP_ATTR_EN_1_13_NNZN                                                        0x00400000
-#define    NV50TCL_VP_ATTR_EN_1_13_XNZN                                                        0x00500000
-#define    NV50TCL_VP_ATTR_EN_1_13_NYZN                                                        0x00600000
-#define    NV50TCL_VP_ATTR_EN_1_13_XYZN                                                        0x00700000
-#define    NV50TCL_VP_ATTR_EN_1_13_NNNW                                                        0x00800000
-#define    NV50TCL_VP_ATTR_EN_1_13_XNNW                                                        0x00900000
-#define    NV50TCL_VP_ATTR_EN_1_13_NYNW                                                        0x00a00000
-#define    NV50TCL_VP_ATTR_EN_1_13_XYNW                                                        0x00b00000
-#define    NV50TCL_VP_ATTR_EN_1_13_NNZW                                                        0x00c00000
-#define    NV50TCL_VP_ATTR_EN_1_13_XNZW                                                        0x00d00000
-#define    NV50TCL_VP_ATTR_EN_1_13_NYZW                                                        0x00e00000
-#define    NV50TCL_VP_ATTR_EN_1_13_XYZW                                                        0x00f00000
-#define   NV50TCL_VP_ATTR_EN_1_12_SHIFT                                                        16
-#define   NV50TCL_VP_ATTR_EN_1_12_MASK                                                 0x000f0000
-#define    NV50TCL_VP_ATTR_EN_1_12_NONE                                                        0x00000000
-#define    NV50TCL_VP_ATTR_EN_1_12_XNNN                                                        0x00010000
-#define    NV50TCL_VP_ATTR_EN_1_12_NYNN                                                        0x00020000
-#define    NV50TCL_VP_ATTR_EN_1_12_XYNN                                                        0x00030000
-#define    NV50TCL_VP_ATTR_EN_1_12_NNZN                                                        0x00040000
-#define    NV50TCL_VP_ATTR_EN_1_12_XNZN                                                        0x00050000
-#define    NV50TCL_VP_ATTR_EN_1_12_NYZN                                                        0x00060000
-#define    NV50TCL_VP_ATTR_EN_1_12_XYZN                                                        0x00070000
-#define    NV50TCL_VP_ATTR_EN_1_12_NNNW                                                        0x00080000
-#define    NV50TCL_VP_ATTR_EN_1_12_XNNW                                                        0x00090000
-#define    NV50TCL_VP_ATTR_EN_1_12_NYNW                                                        0x000a0000
-#define    NV50TCL_VP_ATTR_EN_1_12_XYNW                                                        0x000b0000
-#define    NV50TCL_VP_ATTR_EN_1_12_NNZW                                                        0x000c0000
-#define    NV50TCL_VP_ATTR_EN_1_12_XNZW                                                        0x000d0000
-#define    NV50TCL_VP_ATTR_EN_1_12_NYZW                                                        0x000e0000
-#define    NV50TCL_VP_ATTR_EN_1_12_XYZW                                                        0x000f0000
-#define   NV50TCL_VP_ATTR_EN_1_11_SHIFT                                                        12
-#define   NV50TCL_VP_ATTR_EN_1_11_MASK                                                 0x0000f000
-#define    NV50TCL_VP_ATTR_EN_1_11_NONE                                                        0x00000000
-#define    NV50TCL_VP_ATTR_EN_1_11_XNNN                                                        0x00001000
-#define    NV50TCL_VP_ATTR_EN_1_11_NYNN                                                        0x00002000
-#define    NV50TCL_VP_ATTR_EN_1_11_XYNN                                                        0x00003000
-#define    NV50TCL_VP_ATTR_EN_1_11_NNZN                                                        0x00004000
-#define    NV50TCL_VP_ATTR_EN_1_11_XNZN                                                        0x00005000
-#define    NV50TCL_VP_ATTR_EN_1_11_NYZN                                                        0x00006000
-#define    NV50TCL_VP_ATTR_EN_1_11_XYZN                                                        0x00007000
-#define    NV50TCL_VP_ATTR_EN_1_11_NNNW                                                        0x00008000
-#define    NV50TCL_VP_ATTR_EN_1_11_XNNW                                                        0x00009000
-#define    NV50TCL_VP_ATTR_EN_1_11_NYNW                                                        0x0000a000
-#define    NV50TCL_VP_ATTR_EN_1_11_XYNW                                                        0x0000b000
-#define    NV50TCL_VP_ATTR_EN_1_11_NNZW                                                        0x0000c000
-#define    NV50TCL_VP_ATTR_EN_1_11_XNZW                                                        0x0000d000
-#define    NV50TCL_VP_ATTR_EN_1_11_NYZW                                                        0x0000e000
-#define    NV50TCL_VP_ATTR_EN_1_11_XYZW                                                        0x0000f000
-#define   NV50TCL_VP_ATTR_EN_1_10_SHIFT                                                        8
-#define   NV50TCL_VP_ATTR_EN_1_10_MASK                                                 0x00000f00
-#define    NV50TCL_VP_ATTR_EN_1_10_NONE                                                        0x00000000
-#define    NV50TCL_VP_ATTR_EN_1_10_XNNN                                                        0x00000100
-#define    NV50TCL_VP_ATTR_EN_1_10_NYNN                                                        0x00000200
-#define    NV50TCL_VP_ATTR_EN_1_10_XYNN                                                        0x00000300
-#define    NV50TCL_VP_ATTR_EN_1_10_NNZN                                                        0x00000400
-#define    NV50TCL_VP_ATTR_EN_1_10_XNZN                                                        0x00000500
-#define    NV50TCL_VP_ATTR_EN_1_10_NYZN                                                        0x00000600
-#define    NV50TCL_VP_ATTR_EN_1_10_XYZN                                                        0x00000700
-#define    NV50TCL_VP_ATTR_EN_1_10_NNNW                                                        0x00000800
-#define    NV50TCL_VP_ATTR_EN_1_10_XNNW                                                        0x00000900
-#define    NV50TCL_VP_ATTR_EN_1_10_NYNW                                                        0x00000a00
-#define    NV50TCL_VP_ATTR_EN_1_10_XYNW                                                        0x00000b00
-#define    NV50TCL_VP_ATTR_EN_1_10_NNZW                                                        0x00000c00
-#define    NV50TCL_VP_ATTR_EN_1_10_XNZW                                                        0x00000d00
-#define    NV50TCL_VP_ATTR_EN_1_10_NYZW                                                        0x00000e00
-#define    NV50TCL_VP_ATTR_EN_1_10_XYZW                                                        0x00000f00
-#define   NV50TCL_VP_ATTR_EN_1_9_SHIFT                                                 4
-#define   NV50TCL_VP_ATTR_EN_1_9_MASK                                                  0x000000f0
-#define    NV50TCL_VP_ATTR_EN_1_9_NONE                                                 0x00000000
-#define    NV50TCL_VP_ATTR_EN_1_9_XNNN                                                 0x00000010
-#define    NV50TCL_VP_ATTR_EN_1_9_NYNN                                                 0x00000020
-#define    NV50TCL_VP_ATTR_EN_1_9_XYNN                                                 0x00000030
-#define    NV50TCL_VP_ATTR_EN_1_9_NNZN                                                 0x00000040
-#define    NV50TCL_VP_ATTR_EN_1_9_XNZN                                                 0x00000050
-#define    NV50TCL_VP_ATTR_EN_1_9_NYZN                                                 0x00000060
-#define    NV50TCL_VP_ATTR_EN_1_9_XYZN                                                 0x00000070
-#define    NV50TCL_VP_ATTR_EN_1_9_NNNW                                                 0x00000080
-#define    NV50TCL_VP_ATTR_EN_1_9_XNNW                                                 0x00000090
-#define    NV50TCL_VP_ATTR_EN_1_9_NYNW                                                 0x000000a0
-#define    NV50TCL_VP_ATTR_EN_1_9_XYNW                                                 0x000000b0
-#define    NV50TCL_VP_ATTR_EN_1_9_NNZW                                                 0x000000c0
-#define    NV50TCL_VP_ATTR_EN_1_9_XNZW                                                 0x000000d0
-#define    NV50TCL_VP_ATTR_EN_1_9_NYZW                                                 0x000000e0
-#define    NV50TCL_VP_ATTR_EN_1_9_XYZW                                                 0x000000f0
-#define   NV50TCL_VP_ATTR_EN_1_8_SHIFT                                                 0
-#define   NV50TCL_VP_ATTR_EN_1_8_MASK                                                  0x0000000f
-#define    NV50TCL_VP_ATTR_EN_1_8_NONE                                                 0x00000000
-#define    NV50TCL_VP_ATTR_EN_1_8_XNNN                                                 0x00000001
-#define    NV50TCL_VP_ATTR_EN_1_8_NYNN                                                 0x00000002
-#define    NV50TCL_VP_ATTR_EN_1_8_XYNN                                                 0x00000003
-#define    NV50TCL_VP_ATTR_EN_1_8_NNZN                                                 0x00000004
-#define    NV50TCL_VP_ATTR_EN_1_8_XNZN                                                 0x00000005
-#define    NV50TCL_VP_ATTR_EN_1_8_NYZN                                                 0x00000006
-#define    NV50TCL_VP_ATTR_EN_1_8_XYZN                                                 0x00000007
-#define    NV50TCL_VP_ATTR_EN_1_8_NNNW                                                 0x00000008
-#define    NV50TCL_VP_ATTR_EN_1_8_XNNW                                                 0x00000009
-#define    NV50TCL_VP_ATTR_EN_1_8_NYNW                                                 0x0000000a
-#define    NV50TCL_VP_ATTR_EN_1_8_XYNW                                                 0x0000000b
-#define    NV50TCL_VP_ATTR_EN_1_8_NNZW                                                 0x0000000c
-#define    NV50TCL_VP_ATTR_EN_1_8_XNZW                                                 0x0000000d
-#define    NV50TCL_VP_ATTR_EN_1_8_NYZW                                                 0x0000000e
-#define    NV50TCL_VP_ATTR_EN_1_8_XYZW                                                 0x0000000f
-#define  NV50TCL_POINT_SPRITE_CTRL                                                     0x00001660
-#define  NV50TCL_LINE_STIPPLE_ENABLE                                                   0x0000166c
-#define  NV50TCL_LINE_STIPPLE_PATTERN                                                  0x00001680
-#define  NV50TCL_PROVOKING_VERTEX_LAST                                                 0x00001684
-#define  NV50TCL_VERTEX_TWO_SIDE_ENABLE                                                        0x00001688
-#define  NV50TCL_POLYGON_STIPPLE_ENABLE                                                        0x0000168c
-#define  NV50TCL_SET_PROGRAM_CB                                                                0x00001694
-#define   NV50TCL_SET_PROGRAM_CB_PROGRAM_SHIFT                                         4
-#define   NV50TCL_SET_PROGRAM_CB_PROGRAM_MASK                                          0x000000f0
-#define    NV50TCL_SET_PROGRAM_CB_PROGRAM_VERTEX                                       0x00000000
-#define    NV50TCL_SET_PROGRAM_CB_PROGRAM_GEOMETRY                                     0x00000020
-#define    NV50TCL_SET_PROGRAM_CB_PROGRAM_FRAGMENT                                     0x00000030
-#define   NV50TCL_SET_PROGRAM_CB_INDEX_SHIFT                                           8
-#define   NV50TCL_SET_PROGRAM_CB_INDEX_MASK                                            0x00000f00
-#define   NV50TCL_SET_PROGRAM_CB_BUFFER_SHIFT                                          12
-#define   NV50TCL_SET_PROGRAM_CB_BUFFER_MASK                                           0x0007f000
-#define   NV50TCL_SET_PROGRAM_CB_VALID                                                 (1 <<  0)
-#define  NV50TCL_VP_RESULT_MAP_SIZE                                                    0x000016ac
-#define  NV50TCL_VP_REG_ALLOC_TEMP                                                     0x000016b0
-#define  NV50TCL_VP_REG_ALLOC_RESULT                                                   0x000016b8
-#define  NV50TCL_VP_RESULT_MAP(x)                                                      (0x000016bc+((x)*4))
-#define  NV50TCL_VP_RESULT_MAP__SIZE                                                   0x00000010
-#define   NV50TCL_VP_RESULT_MAP_0_SHIFT                                                        0
-#define   NV50TCL_VP_RESULT_MAP_0_MASK                                                 0x000000ff
-#define   NV50TCL_VP_RESULT_MAP_1_SHIFT                                                        8
-#define   NV50TCL_VP_RESULT_MAP_1_MASK                                                 0x0000ff00
-#define   NV50TCL_VP_RESULT_MAP_2_SHIFT                                                        16
-#define   NV50TCL_VP_RESULT_MAP_2_MASK                                                 0x00ff0000
-#define   NV50TCL_VP_RESULT_MAP_3_SHIFT                                                        24
-#define   NV50TCL_VP_RESULT_MAP_3_MASK                                                 0xff000000
-#define  NV50TCL_POLYGON_STIPPLE_PATTERN(x)                                            (0x00001700+((x)*4))
-#define  NV50TCL_POLYGON_STIPPLE_PATTERN__SIZE                                         0x00000020
-#define  NV50TCL_GP_ENABLE                                                             0x00001798
-#define  NV50TCL_GP_REG_ALLOC_TEMP                                                     0x000017a0
-#define  NV50TCL_GP_REG_ALLOC_RESULT                                                   0x000017a8
-#define  NV50TCL_GP_RESULT_MAP_SIZE                                                    0x000017ac
-#define  NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE                                              0x000017b0
-#define   NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_POINTS                                      0x00000001
-#define   NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_LINE_STRIP                                  0x00000002
-#define   NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_TRIANGLE_STRIP                              0x00000003
-#define  NV50TCL_RASTERIZE_ENABLE                                                      0x000017b4
-#define  NV50TCL_STRMOUT_ENABLE                                                                0x000017b8
-#define  NV50TCL_GP_RESULT_MAP(x)                                                      (0x000017fc+((x)*4))
-#define  NV50TCL_GP_RESULT_MAP__SIZE                                                   0x00000020
-#define   NV50TCL_GP_RESULT_MAP_0_SHIFT                                                        0
-#define   NV50TCL_GP_RESULT_MAP_0_MASK                                                 0x000000ff
-#define   NV50TCL_GP_RESULT_MAP_1_SHIFT                                                        8
-#define   NV50TCL_GP_RESULT_MAP_1_MASK                                                 0x0000ff00
-#define   NV50TCL_GP_RESULT_MAP_2_SHIFT                                                        16
-#define   NV50TCL_GP_RESULT_MAP_2_MASK                                                 0x00ff0000
-#define   NV50TCL_GP_RESULT_MAP_3_SHIFT                                                        24
-#define   NV50TCL_GP_RESULT_MAP_3_MASK                                                 0xff000000
-#define  NV50TCL_MAP_SEMANTIC_0                                                                0x00001904
-#define   NV50TCL_MAP_SEMANTIC_0_FFC0_ID_SHIFT                                         0
-#define   NV50TCL_MAP_SEMANTIC_0_FFC0_ID_MASK                                          0x000000ff
-#define   NV50TCL_MAP_SEMANTIC_0_BFC0_ID_SHIFT                                         8
-#define   NV50TCL_MAP_SEMANTIC_0_BFC0_ID_MASK                                          0x0000ff00
-#define   NV50TCL_MAP_SEMANTIC_0_COLR_NR_SHIFT                                         16
-#define   NV50TCL_MAP_SEMANTIC_0_COLR_NR_MASK                                          0x00ff0000
-#define   NV50TCL_MAP_SEMANTIC_0_CLMP_EN_SHIFT                                         24
-#define   NV50TCL_MAP_SEMANTIC_0_CLMP_EN_MASK                                          0xff000000
-#define  NV50TCL_MAP_SEMANTIC_1                                                                0x00001908
-#define   NV50TCL_MAP_SEMANTIC_1_CLIP_LO_SHIFT                                         0
-#define   NV50TCL_MAP_SEMANTIC_1_CLIP_LO_MASK                                          0x000000ff
-#define   NV50TCL_MAP_SEMANTIC_1_CLIP_HI_SHIFT                                         8
-#define   NV50TCL_MAP_SEMANTIC_1_CLIP_HI_MASK                                          0x0000ff00
-#define  NV50TCL_MAP_SEMANTIC_2                                                                0x0000190c
-#define   NV50TCL_MAP_SEMANTIC_2_LAYER_ID_SHIFT                                                0
-#define   NV50TCL_MAP_SEMANTIC_2_LAYER_ID_MASK                                         0x000000ff
-#define  NV50TCL_MAP_SEMANTIC_3                                                                0x00001910
-#define   NV50TCL_MAP_SEMANTIC_3_PTSZ_EN                                               (1 <<  0)
-#define   NV50TCL_MAP_SEMANTIC_3_PTSZ_ID_SHIFT                                         4
-#define   NV50TCL_MAP_SEMANTIC_3_PTSZ_ID_MASK                                          0x00000ff0
-#define  NV50TCL_MAP_SEMANTIC_4                                                                0x00001914
-#define   NV50TCL_MAP_SEMANTIC_4_PRIM_ID_SHIFT                                         0
-#define   NV50TCL_MAP_SEMANTIC_4_PRIM_ID_MASK                                          0x000000ff
-#define  NV50TCL_CULL_FACE_ENABLE                                                      0x00001918
-#define  NV50TCL_FRONT_FACE                                                            0x0000191c
-#define   NV50TCL_FRONT_FACE_CW                                                                0x00000900
-#define   NV50TCL_FRONT_FACE_CCW                                                       0x00000901
-#define  NV50TCL_CULL_FACE                                                             0x00001920
-#define   NV50TCL_CULL_FACE_FRONT                                                      0x00000404
-#define   NV50TCL_CULL_FACE_BACK                                                       0x00000405
-#define   NV50TCL_CULL_FACE_FRONT_AND_BACK                                             0x00000408
-#define  NV50TCL_VIEWPORT_TRANSFORM_EN                                                 0x0000192c
-#define  NV50TCL_VIEW_VOLUME_CLIP_CTRL                                                 0x0000193c
-#define  NV50TCL_VIEWPORT_CLIP_RECTS_EN                                                        0x0000194c
-#define  NV50TCL_VIEWPORT_CLIP_MODE                                                    0x00001950
-#define   NV50TCL_VIEWPORT_CLIP_MODE_INCLUDE                                           0x00000000
-#define   NV50TCL_VIEWPORT_CLIP_MODE_EXCLUDE                                           0x00000001
-#define   NV50TCL_VIEWPORT_CLIP_MODE_UNKNOWN                                           0x00000002
-#define  NV50TCL_FP_CTRL_UNK196C                                                       0x0000196c
-#define  NV50TCL_CLIPID_ENABLE                                                         0x0000197c
-#define  NV50TCL_CLIPID_WIDTH                                                          0x00001980
-#define  NV50TCL_CLIPID_ID                                                             0x00001984
-#define  NV50TCL_FP_INTERPOLANT_CTRL                                                   0x00001988
-#define   NV50TCL_FP_INTERPOLANT_CTRL_UMASK_SHIFT                                      24
-#define   NV50TCL_FP_INTERPOLANT_CTRL_UMASK_MASK                                       0xff000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NONE                                      0x00000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNNN                                      0x01000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYNN                                      0x02000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYNN                                      0x03000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NNZN                                      0x04000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNZN                                      0x05000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYZN                                      0x06000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYZN                                      0x07000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NNNW                                      0x08000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNNW                                      0x09000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYNW                                      0x0a000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYNW                                      0x0b000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NNZW                                      0x0c000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNZW                                      0x0d000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYZW                                      0x0e000000
-#define    NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYZW                                      0x0f000000
-#define   NV50TCL_FP_INTERPOLANT_CTRL_COUNT_NONFLAT_SHIFT                              16
-#define   NV50TCL_FP_INTERPOLANT_CTRL_COUNT_NONFLAT_MASK                               0x00ff0000
-#define   NV50TCL_FP_INTERPOLANT_CTRL_OFFSET_SHIFT                                     8
-#define   NV50TCL_FP_INTERPOLANT_CTRL_OFFSET_MASK                                      0x0000ff00
-#define   NV50TCL_FP_INTERPOLANT_CTRL_COUNT_SHIFT                                      0
-#define   NV50TCL_FP_INTERPOLANT_CTRL_COUNT_MASK                                       0x000000ff
-#define  NV50TCL_FP_REG_ALLOC_TEMP                                                     0x0000198c
-#define  NV50TCL_REG_MODE                                                              0x000019a0
-#define   NV50TCL_REG_MODE_PACKED                                                      0x00000001
-#define   NV50TCL_REG_MODE_STRIPED                                                     0x00000002
-#define  NV50TCL_FP_CONTROL                                                            0x000019a8
-#define   NV50TCL_FP_CONTROL_MULTIPLE_RESULTS                                          (1 <<  0)
-#define   NV50TCL_FP_CONTROL_EXPORTS_Z                                                 (1 <<  8)
-#define   NV50TCL_FP_CONTROL_USES_KIL                                                  (1 << 20)
-#define  NV50TCL_DEPTH_BOUNDS_EN                                                       0x000019bc
-#define  NV50TCL_LOGIC_OP_ENABLE                                                       0x000019c4
-#define  NV50TCL_LOGIC_OP                                                              0x000019c8
-#define   NV50TCL_LOGIC_OP_CLEAR                                                       0x00001500
-#define   NV50TCL_LOGIC_OP_AND                                                         0x00001501
-#define   NV50TCL_LOGIC_OP_AND_REVERSE                                                 0x00001502
-#define   NV50TCL_LOGIC_OP_COPY                                                                0x00001503
-#define   NV50TCL_LOGIC_OP_AND_INVERTED                                                        0x00001504
-#define   NV50TCL_LOGIC_OP_NOOP                                                                0x00001505
-#define   NV50TCL_LOGIC_OP_XOR                                                         0x00001506
-#define   NV50TCL_LOGIC_OP_OR                                                          0x00001507
-#define   NV50TCL_LOGIC_OP_NOR                                                         0x00001508
-#define   NV50TCL_LOGIC_OP_EQUIV                                                       0x00001509
-#define   NV50TCL_LOGIC_OP_INVERT                                                      0x0000150a
-#define   NV50TCL_LOGIC_OP_OR_REVERSE                                                  0x0000150b
-#define   NV50TCL_LOGIC_OP_COPY_INVERTED                                               0x0000150c
-#define   NV50TCL_LOGIC_OP_OR_INVERTED                                                 0x0000150d
-#define   NV50TCL_LOGIC_OP_NAND                                                                0x0000150e
-#define   NV50TCL_LOGIC_OP_SET                                                         0x0000150f
-#define  NV50TCL_CLEAR_BUFFERS                                                         0x000019d0
-#define   NV50TCL_CLEAR_BUFFERS_Z                                                      (1 <<  0)
-#define   NV50TCL_CLEAR_BUFFERS_S                                                      (1 <<  1)
-#define   NV50TCL_CLEAR_BUFFERS_R                                                      (1 <<  2)
-#define   NV50TCL_CLEAR_BUFFERS_G                                                      (1 <<  3)
-#define   NV50TCL_CLEAR_BUFFERS_B                                                      (1 <<  4)
-#define   NV50TCL_CLEAR_BUFFERS_A                                                      (1 <<  5)
-#define   NV50TCL_CLEAR_BUFFERS_RT_SHIFT                                               6
-#define   NV50TCL_CLEAR_BUFFERS_RT_MASK                                                        0x000003c0
-#define   NV50TCL_CLEAR_BUFFERS_LAYER_SHIFT                                            10
-#define   NV50TCL_CLEAR_BUFFERS_LAYER_MASK                                             0x0007fc00
-#define  NV50TCL_COLOR_MASK(x)                                                         (0x00001a00+((x)*4))
-#define  NV50TCL_COLOR_MASK__SIZE                                                      0x00000008
-#define   NV50TCL_COLOR_MASK_R_SHIFT                                                   0
-#define   NV50TCL_COLOR_MASK_R_MASK                                                    0x0000000f
-#define   NV50TCL_COLOR_MASK_G_SHIFT                                                   4
-#define   NV50TCL_COLOR_MASK_G_MASK                                                    0x000000f0
-#define   NV50TCL_COLOR_MASK_B_SHIFT                                                   8
-#define   NV50TCL_COLOR_MASK_B_MASK                                                    0x00000f00
-#define   NV50TCL_COLOR_MASK_A_SHIFT                                                   12
-#define   NV50TCL_COLOR_MASK_A_MASK                                                    0x0000f000
-#define  NV50TCL_STRMOUT_ADDRESS_HIGH(x)                                               (0x00001a80+((x)*16))
-#define  NV50TCL_STRMOUT_ADDRESS_HIGH__SIZE                                            0x00000004
-#define  NV50TCL_STRMOUT_ADDRESS_LOW(x)                                                        (0x00001a84+((x)*16))
-#define  NV50TCL_STRMOUT_ADDRESS_LOW__SIZE                                             0x00000004
-#define  NV50TCL_STRMOUT_NUM_ATTRIBS(x)                                                        (0x00001a88+((x)*16))
-#define  NV50TCL_STRMOUT_NUM_ATTRIBS__SIZE                                             0x00000004
-#define  NV50TCL_VERTEX_ARRAY_ATTRIB(x)                                                        (0x00001ac0+((x)*4))
-#define  NV50TCL_VERTEX_ARRAY_ATTRIB__SIZE                                             0x00000010
-#define   NV50TCL_VERTEX_ARRAY_ATTRIB_BUFFER_SHIFT                                     0
-#define   NV50TCL_VERTEX_ARRAY_ATTRIB_BUFFER_MASK                                      0x0000000f
-#define   NV50TCL_VERTEX_ARRAY_ATTRIB_CONST                                            (1 <<  4)
-#define   NV50TCL_VERTEX_ARRAY_ATTRIB_OFFSET_SHIFT                                     5
-#define   NV50TCL_VERTEX_ARRAY_ATTRIB_OFFSET_MASK                                      0x0007ffe0
-#define   NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_SHIFT                                     19
-#define   NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_MASK                                      0x01f80000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32_32                              0x00080000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32                                 0x00100000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16_16                              0x00180000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32                                    0x00200000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16                                 0x00280000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8_8                                  0x00500000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16                                    0x00780000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32                                       0x00900000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8                                    0x00980000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8                                      0x00c00000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16                                       0x00d80000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8                                                0x00e80000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_2_10_10_10                               0x01800000
-#define   NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SHIFT                                       25
-#define   NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_MASK                                                0x0e000000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT                                      0x0e000000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM                                      0x02000000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM                                      0x04000000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_USCALED                                    0x0a000000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED                                    0x0c000000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UINT                                       0x08000000
-#define    NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SINT                                       0x06000000
-#define   NV50TCL_VERTEX_ARRAY_ATTRIB_BGRA                                             (1 << 31)
-#define  NV50TCL_QUERY_ADDRESS_HIGH                                                    0x00001b00
-#define  NV50TCL_QUERY_ADDRESS_LOW                                                     0x00001b04
-#define  NV50TCL_QUERY_SEQUENCE                                                                0x00001b08
-#define  NV50TCL_QUERY_GET                                                             0x00001b0c
-
-
-#define NV84TCL                                                                                0x00008297
-
-
-
-#define NVA0TCL                                                                                0x00008397
-
-
-
-#define NVA8TCL                                                                                0x00008597
-
-
-
-#define NV50_COMPUTE                                                                   0x000050c0
-
-#define  NV50_COMPUTE_NOP                                                              0x00000100
-#define  NV50_COMPUTE_NOTIFY                                                           0x00000104
-#define  NV50_COMPUTE_SERIALIZE                                                                0x00000110
-#define  NV50_COMPUTE_DMA_NOTIFY                                                       0x00000180
-#define  NV50_COMPUTE_DMA_GLOBAL                                                       0x000001a0
-#define  NV50_COMPUTE_DMA_QUERY                                                                0x000001a4
-#define  NV50_COMPUTE_DMA_LOCAL                                                                0x000001b8
-#define  NV50_COMPUTE_DMA_STACK                                                                0x000001bc
-#define  NV50_COMPUTE_DMA_CODE_CB                                                      0x000001c0
-#define  NV50_COMPUTE_DMA_TSC                                                          0x000001c4
-#define  NV50_COMPUTE_DMA_TIC                                                          0x000001c8
-#define  NV50_COMPUTE_DMA_TEXTURE                                                      0x000001cc
-#define  NV50_COMPUTE_CP_ADDRESS_HIGH                                                  0x00000210
-#define  NV50_COMPUTE_CP_ADDRESS_LOW                                                   0x00000214
-#define  NV50_COMPUTE_STACK_ADDRESS_HIGH                                               0x00000218
-#define  NV50_COMPUTE_STACK_ADDRESS_LOW                                                        0x0000021c
-#define  NV50_COMPUTE_STACK_SIZE_LOG                                                   0x00000220
-#define  NV50_COMPUTE_TSC_ADDRESS_HIGH                                                 0x0000022c
-#define  NV50_COMPUTE_TSC_ADDRESS_LOW                                                  0x00000230
-#define  NV50_COMPUTE_TSC_LIMIT                                                                0x00000234
-#define  NV50_COMPUTE_CB_ADDR                                                          0x00000238
-#define   NV50_COMPUTE_CB_ADDR_ID_SHIFT                                                        8
-#define   NV50_COMPUTE_CB_ADDR_ID_MASK                                                 0x003fff00
-#define   NV50_COMPUTE_CB_ADDR_BUFFER_SHIFT                                            0
-#define   NV50_COMPUTE_CB_ADDR_BUFFER_MASK                                             0x0000007f
-#define  NV50_COMPUTE_CB_DATA(x)                                                       (0x0000023c+((x)*4))
-#define  NV50_COMPUTE_CB_DATA__SIZE                                                    0x00000010
-#define  NV50_COMPUTE_DELAY1                                                           0x00000284
-#define  NV50_COMPUTE_WATCHDOG_TIMER                                                   0x00000288
-#define  NV50_COMPUTE_DELAY2                                                           0x0000028c
-#define  NV50_COMPUTE_LOCAL_ADDRESS_HIGH                                               0x00000294
-#define  NV50_COMPUTE_LOCAL_ADDRESS_LOW                                                        0x00000298
-#define  NV50_COMPUTE_LOCAL_SIZE_LOG                                                   0x0000029c
-#define  NV50_COMPUTE_CB_DEF_ADDRESS_HIGH                                              0x000002a4
-#define  NV50_COMPUTE_CB_DEF_ADDRESS_LOW                                               0x000002a8
-#define  NV50_COMPUTE_CB_DEF_SET                                                       0x000002ac
-#define   NV50_COMPUTE_CB_DEF_SET_SIZE_SHIFT                                           0
-#define   NV50_COMPUTE_CB_DEF_SET_SIZE_MASK                                            0x0000ffff
-#define   NV50_COMPUTE_CB_DEF_SET_BUFFER_SHIFT                                         16
-#define   NV50_COMPUTE_CB_DEF_SET_BUFFER_MASK                                          0x007f0000
-#define  NV50_COMPUTE_BLOCK_ALLOC                                                      0x000002b4
-#define   NV50_COMPUTE_BLOCK_ALLOC_THREADS_SHIFT                                       0
-#define   NV50_COMPUTE_BLOCK_ALLOC_THREADS_MASK                                                0x0000ffff
-#define   NV50_COMPUTE_BLOCK_ALLOC_BARRIERS_SHIFT                                      16
-#define   NV50_COMPUTE_BLOCK_ALLOC_BARRIERS_MASK                                       0xffff0000
-#define  NV50_COMPUTE_LANES32_ENABLE                                                   0x000002b8
-#define  NV50_COMPUTE_CP_REG_ALLOC_TEMP                                                        0x000002c0
-#define  NV50_COMPUTE_TIC_ADDRESS_HIGH                                                 0x000002c4
-#define  NV50_COMPUTE_TIC_ADDRESS_LOW                                                  0x000002c8
-#define  NV50_COMPUTE_TIC_LIMIT                                                                0x000002cc
-#define  NV50_COMPUTE_PM_SET(x)                                                                (0x000002d0+((x)*4))
-#define  NV50_COMPUTE_PM_SET__SIZE                                                     0x00000004
-#define  NV50_COMPUTE_PM_CONTROL(x)                                                    (0x000002e0+((x)*4))
-#define  NV50_COMPUTE_PM_CONTROL__SIZE                                                 0x00000004
-#define   NV50_COMPUTE_PM_CONTROL_UNK0                                                 (1 <<  0)
-#define   NV50_COMPUTE_PM_CONTROL_UNK1_SHIFT                                           4
-#define   NV50_COMPUTE_PM_CONTROL_UNK1_MASK                                            0x00000070
-#define   NV50_COMPUTE_PM_CONTROL_UNK2_SHIFT                                           8
-#define   NV50_COMPUTE_PM_CONTROL_UNK2_MASK                                            0xffffff00
-#define  NV50_COMPUTE_LOCAL_WARPS_LOG_ALLOC                                            0x000002fc
-#define  NV50_COMPUTE_LOCAL_WARPS_NO_CLAMP                                             0x00000300
-#define  NV50_COMPUTE_STACK_WARPS_LOG_ALLOC                                            0x00000304
-#define  NV50_COMPUTE_STACK_WARPS_NO_CLAMP                                             0x00000308
-#define  NV50_COMPUTE_QUERY_ADDRESS_HIGH                                               0x00000310
-#define  NV50_COMPUTE_QUERY_ADDRESS_LOW                                                        0x00000314
-#define  NV50_COMPUTE_QUERY_COUNTER                                                    0x00000318
-#define  NV50_COMPUTE_QUERY_GET                                                                0x0000031c
-#define  NV50_COMPUTE_COND_ADDRESS_HIGH                                                        0x00000320
-#define  NV50_COMPUTE_COND_ADDRESS_LOW                                                 0x00000324
-#define  NV50_COMPUTE_COND_MODE                                                                0x00000328
-#define   NV50_COMPUTE_COND_MODE_NEVER                                                 0x00000000
-#define   NV50_COMPUTE_COND_MODE_ALWAYS                                                        0x00000001
-#define   NV50_COMPUTE_COND_MODE_RES                                                   0x00000002
-#define   NV50_COMPUTE_COND_MODE_NOT_RES_AND_NOT_ID                                    0x00000003
-#define   NV50_COMPUTE_COND_MODE_RES_OR_ID                                             0x00000004
-#define  NV50_COMPUTE_LAUNCH                                                           0x00000368
-#define  NV50_COMPUTE_USER_PARAM_COUNT                                                 0x00000374
-#define   NV50_COMPUTE_USER_PARAM_COUNT_COUNT_SHIFT                                    8
-#define   NV50_COMPUTE_USER_PARAM_COUNT_COUNT_MASK                                     0x0000ff00
-#define  NV50_COMPUTE_LINKED_TSC                                                       0x00000378
-#define  NV50_COMPUTE_CODE_CB_FLUSH                                                    0x00000380
-#define  NV50_COMPUTE_GRIDDIM                                                          0x000003a4
-#define   NV50_COMPUTE_GRIDDIM_X_SHIFT                                                 0
-#define   NV50_COMPUTE_GRIDDIM_X_MASK                                                  0x0000ffff
-#define   NV50_COMPUTE_GRIDDIM_Y_SHIFT                                                 16
-#define   NV50_COMPUTE_GRIDDIM_Y_MASK                                                  0xffff0000
-#define  NV50_COMPUTE_SHARED_SIZE                                                      0x000003a8
-#define  NV50_COMPUTE_BLOCKDIM_YX                                                      0x000003ac
-#define   NV50_COMPUTE_BLOCKDIM_YX_X_SHIFT                                             0
-#define   NV50_COMPUTE_BLOCKDIM_YX_X_MASK                                              0x0000ffff
-#define   NV50_COMPUTE_BLOCKDIM_YX_Y_SHIFT                                             16
-#define   NV50_COMPUTE_BLOCKDIM_YX_Y_MASK                                              0xffff0000
-#define  NV50_COMPUTE_BLOCKDIM_Z                                                       0x000003b0
-#define  NV50_COMPUTE_CP_START_ID                                                      0x000003b4
-#define  NV50_COMPUTE_REG_MODE                                                         0x000003b8
-#define   NV50_COMPUTE_REG_MODE_PACKED                                                 0x00000001
-#define   NV50_COMPUTE_REG_MODE_STRIPED                                                        0x00000002
-#define  NV50_COMPUTE_TEX_LIMITS                                                       0x000003bc
-#define   NV50_COMPUTE_TEX_LIMITS_SAMPLERS_LOG2_SHIFT                                  0
-#define   NV50_COMPUTE_TEX_LIMITS_SAMPLERS_LOG2_MASK                                   0x0000000f
-#define   NV50_COMPUTE_TEX_LIMITS_TEXTURES_LOG2_SHIFT                                  4
-#define   NV50_COMPUTE_TEX_LIMITS_TEXTURES_LOG2_MASK                                   0x000000f0
-#define  NV50_COMPUTE_BIND_TSC                                                         0x000003c0
-#define   NV50_COMPUTE_BIND_TSC_VALID                                                  (1 <<  0)
-#define   NV50_COMPUTE_BIND_TSC_SAMPLER_SHIFT                                          4
-#define   NV50_COMPUTE_BIND_TSC_SAMPLER_MASK                                           0x000000f0
-#define   NV50_COMPUTE_BIND_TSC_TSC_SHIFT                                              12
-#define   NV50_COMPUTE_BIND_TSC_TSC_MASK                                               0x001ff000
-#define  NV50_COMPUTE_BIND_TIC                                                         0x000003c4
-#define   NV50_COMPUTE_BIND_TIC_VALID                                                  (1 <<  0)
-#define   NV50_COMPUTE_BIND_TIC_TEXTURE_SHIFT                                          1
-#define   NV50_COMPUTE_BIND_TIC_TEXTURE_MASK                                           0x000001fe
-#define   NV50_COMPUTE_BIND_TIC_TIC_SHIFT                                              9
-#define   NV50_COMPUTE_BIND_TIC_TIC_MASK                                               0x7ffffe00
-#define  NV50_COMPUTE_SET_PROGRAM_CB                                                   0x000003c8
-#define   NV50_COMPUTE_SET_PROGRAM_CB_INDEX_SHIFT                                      8
-#define   NV50_COMPUTE_SET_PROGRAM_CB_INDEX_MASK                                       0x00000f00
-#define   NV50_COMPUTE_SET_PROGRAM_CB_BUFFER_SHIFT                                     12
-#define   NV50_COMPUTE_SET_PROGRAM_CB_BUFFER_MASK                                      0x0007f000
-#define   NV50_COMPUTE_SET_PROGRAM_CB_VALID                                            (1 <<  0)
-#define  NV50_COMPUTE_GLOBAL_ADDRESS_HIGH(x)                                           (0x00000400+((x)*32))
-#define  NV50_COMPUTE_GLOBAL_ADDRESS_HIGH__SIZE                                                0x00000010
-#define  NV50_COMPUTE_GLOBAL_ADDRESS_LOW(x)                                            (0x00000404+((x)*32))
-#define  NV50_COMPUTE_GLOBAL_ADDRESS_LOW__SIZE                                         0x00000010
-#define  NV50_COMPUTE_GLOBAL_PITCH(x)                                                  (0x00000408+((x)*32))
-#define  NV50_COMPUTE_GLOBAL_PITCH__SIZE                                               0x00000010
-#define  NV50_COMPUTE_GLOBAL_LIMIT(x)                                                  (0x0000040c+((x)*32))
-#define  NV50_COMPUTE_GLOBAL_LIMIT__SIZE                                               0x00000010
-#define  NV50_COMPUTE_GLOBAL_MODE(x)                                                   (0x00000410+((x)*32))
-#define  NV50_COMPUTE_GLOBAL_MODE__SIZE                                                        0x00000010
-#define   NV50_COMPUTE_GLOBAL_MODE_LINEAR                                              (1 <<  0)
-#define   NV50_COMPUTE_GLOBAL_MODE_TILE_MODE_SHIFT                                     8
-#define   NV50_COMPUTE_GLOBAL_MODE_TILE_MODE_MASK                                      0x00000f00
-#define  NV50_COMPUTE_USER_PARAM(x)                                                    (0x00000600+((x)*4))
-#define  NV50_COMPUTE_USER_PARAM__SIZE                                                 0x00000040
-
-
-#endif /* NOUVEAU_REG_H */
index 6c0a9696355de2d5bbdf25408344ebcedd88f5af..ae1a2bf55da56d5ca078bd33c36f2ebfa74d9487 100644 (file)
@@ -3,65 +3,66 @@
 #include "nv50_resource.h"
 #include "nouveau/nouveau_screen.h"
 
-
-/* This doesn't look quite right - this query is supposed to ask
- * whether the particular context has references to the resource in
- * any unflushed rendering command buffer, and hence requires a
- * pipe->flush() for serializing some modification to that resource.
- *
- * This seems to be answering the question of whether the resource is
- * currently on hardware.
- */
-static unsigned int
+static unsigned
 nv50_resource_is_referenced(struct pipe_context *pipe,
-                           struct pipe_resource *resource,
-                           unsigned level, int layer)
+                            struct pipe_resource *resource,
+                            unsigned face, int layer)
 {
-       return nouveau_reference_flags(nv50_resource(resource)->bo);
+   struct nv50_resource *res = nv50_resource(resource);
+   unsigned flags = 0;
+   unsigned bo_flags = nouveau_bo_pending(res->bo);
+
+   if (bo_flags & NOUVEAU_BO_RD)
+      flags = PIPE_REFERENCED_FOR_READ;
+   if (bo_flags & NOUVEAU_BO_WR)
+      flags |= PIPE_REFERENCED_FOR_WRITE;
+
+   return flags;
 }
 
 static struct pipe_resource *
 nv50_resource_create(struct pipe_screen *screen,
-                    const struct pipe_resource *template)
+                     const struct pipe_resource *templ)
 {
-       if (template->target == PIPE_BUFFER)
-               return nv50_buffer_create(screen, template);
-       else
-               return nv50_miptree_create(screen, template);
+   switch (templ->target) {
+   case PIPE_BUFFER:
+      return nv50_buffer_create(screen, templ);
+   default:
+      return nv50_miptree_create(screen, templ);
+   }
 }
 
 static struct pipe_resource *
 nv50_resource_from_handle(struct pipe_screen * screen,
-                         const struct pipe_resource *template,
-                         struct winsys_handle *whandle)
+                          const struct pipe_resource *templ,
+                          struct winsys_handle *whandle)
 {
-       if (template->target == PIPE_BUFFER)
-               return NULL;
-       else
-               return nv50_miptree_from_handle(screen, template, whandle);
+   if (templ->target == PIPE_BUFFER)
+      return NULL;
+   else
+      return nv50_miptree_from_handle(screen, templ, whandle);
 }
 
 void
 nv50_init_resource_functions(struct pipe_context *pcontext)
 {
-       pcontext->get_transfer = u_get_transfer_vtbl;
-       pcontext->transfer_map = u_transfer_map_vtbl;
-       pcontext->transfer_flush_region = u_transfer_flush_region_vtbl;
-       pcontext->transfer_unmap = u_transfer_unmap_vtbl;
-       pcontext->transfer_destroy = u_transfer_destroy_vtbl;
-       pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
-       pcontext->is_resource_referenced = nv50_resource_is_referenced;
-
-       pcontext->create_surface = nv50_miptree_surface_new;
-       pcontext->surface_destroy = nv50_miptree_surface_del;
+   pcontext->get_transfer = u_get_transfer_vtbl;
+   pcontext->transfer_map = u_transfer_map_vtbl;
+   pcontext->transfer_flush_region = u_transfer_flush_region_vtbl;
+   pcontext->transfer_unmap = u_transfer_unmap_vtbl;
+   pcontext->transfer_destroy = u_transfer_destroy_vtbl;
+   pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
+   pcontext->is_resource_referenced = nv50_resource_is_referenced;
+   pcontext->create_surface = nv50_miptree_surface_new;
+   pcontext->surface_destroy = nv50_miptree_surface_del;
 }
 
 void
 nv50_screen_init_resource_functions(struct pipe_screen *pscreen)
 {
-       pscreen->resource_create = nv50_resource_create;
-       pscreen->resource_from_handle = nv50_resource_from_handle;
-       pscreen->resource_get_handle = u_resource_get_handle_vtbl;
-       pscreen->resource_destroy = u_resource_destroy_vtbl;
-       pscreen->user_buffer_create = nv50_user_buffer_create;
+   pscreen->resource_create = nv50_resource_create;
+   pscreen->resource_from_handle = nv50_resource_from_handle;
+   pscreen->resource_get_handle = u_resource_get_handle_vtbl;
+   pscreen->resource_destroy = u_resource_destroy_vtbl;
+   pscreen->user_buffer_create = nv50_user_buffer_create;
 }
index 4b2a75e11ad9341e94891a0671f4c287178b1db7..f0e022b320b517c9e3ca888642b97f5f9e9570ad 100644 (file)
 
-#ifndef NV50_RESOURCE_H
-#define NV50_RESOURCE_H
+#ifndef __NV50_RESOURCE_H__
+#define __NV50_RESOURCE_H__
 
 #include "util/u_transfer.h"
-
+#include "util/u_double_list.h"
+#define NOUVEAU_NVC0
 #include "nouveau/nouveau_winsys.h"
+#undef NOUVEAU_NVC0
+
+#include "nv50_fence.h"
 
 struct pipe_resource;
 struct nouveau_bo;
+struct nv50_context;
 
+#define NV50_BUFFER_SCORE_MIN -25000
+#define NV50_BUFFER_SCORE_MAX  25000
+#define NV50_BUFFER_SCORE_VRAM_THRESHOLD 20000
 
-/* This gets further specialized into either buffer or texture
- * structures.  In the future we'll want to remove much of that
- * distinction, but for now try to keep as close to the existing code
- * as possible and use the vtbl struct to choose between the two
- * underlying implementations.
+/* DIRTY: buffer was (or will be after the next flush) written to by GPU and
+ *  resource->data has not been updated to reflect modified VRAM contents
+ *
+ * USER_MEMORY: resource->data is a pointer to client memory and may change
+ *  between GL calls
+ */
+#define NV50_BUFFER_STATUS_DIRTY       (1 << 0)
+#define NV50_BUFFER_STATUS_USER_MEMORY (1 << 7)
+
+/* Resources, if mapped into the GPU's address space, are guaranteed to
+ * have constant virtual addresses.
+ * The address of a resource will lie within the nouveau_bo referenced,
+ * and this bo should be added to the memory manager's validation list.
  */
 struct nv50_resource {
-       struct pipe_resource base;
-       const struct u_resource_vtbl *vtbl;
-       struct nouveau_bo *bo;
+   struct pipe_resource base;
+   const struct u_resource_vtbl *vtbl;
+
+   uint8_t *data;
+   struct nouveau_bo *bo;
+   uint32_t offset;
+
+   uint8_t status;
+   uint8_t domain;
+
+   int16_t score; /* low if mapped very often, if high can move to VRAM */
+
+   struct nv50_fence *fence;
+   struct nv50_fence *fence_wr;
+
+   struct nv50_mm_allocation *mm;
 };
 
+void
+nv50_buffer_release_gpu_storage(struct nv50_resource *);
+
+boolean
+nv50_buffer_download(struct nv50_context *, struct nv50_resource *,
+                     unsigned start, unsigned size);
+
+boolean
+nv50_buffer_migrate(struct nv50_context *,
+                    struct nv50_resource *, unsigned domain);
+
+static INLINE void
+nv50_buffer_adjust_score(struct nv50_context *nv50, struct nv50_resource *res,
+                         int16_t score)
+{
+   if (score < 0) {
+      if (res->score > NV50_BUFFER_SCORE_MIN)
+         res->score += score;
+   } else
+   if (score > 0){
+      if (res->score < NV50_BUFFER_SCORE_MAX)
+         res->score += score;
+      if (res->domain == NOUVEAU_BO_GART &&
+          res->score > NV50_BUFFER_SCORE_VRAM_THRESHOLD)
+         nv50_buffer_migrate(nv50, res, NOUVEAU_BO_VRAM);
+   }
+}
+
+/* XXX: wait for fence (atm only using this for vertex push) */
+static INLINE void *
+nv50_resource_map_offset(struct nv50_context *nv50,
+                         struct nv50_resource *res, uint32_t offset,
+                         uint32_t flags)
+{
+   void *map;
+
+   nv50_buffer_adjust_score(nv50, res, -250);
+
+   if ((res->domain == NOUVEAU_BO_VRAM) &&
+       (res->status & NV50_BUFFER_STATUS_DIRTY))
+      nv50_buffer_download(nv50, res, 0, res->base.width0);
+
+   if ((res->domain != NOUVEAU_BO_GART) ||
+       (res->status & NV50_BUFFER_STATUS_USER_MEMORY))
+      return res->data + offset;
+
+   if (res->mm)
+      flags |= NOUVEAU_BO_NOSYNC;
+
+   if (nouveau_bo_map_range(res->bo, res->offset + offset,
+                            res->base.width0, flags))
+      return NULL;
+
+   map = res->bo->map;
+   nouveau_bo_unmap(res->bo);
+   return map;
+}
+
+static INLINE void
+nv50_resource_unmap(struct nv50_resource *res)
+{
+   /* no-op */
+}
+
+#define NV50_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf)
+
+#define NV50_TILE_PITCH(m)  (64 << 0)
+#define NV50_TILE_HEIGHT(m) ( 4 << NV50_TILE_DIM_SHIFT(m, 0))
+#define NV50_TILE_DEPTH(m)  ( 1 << NV50_TILE_DIM_SHIFT(m, 1))
+
+#define NV50_TILE_SIZE_2D(m) ((64 * 8) <<                     \
+                              NV50_TILE_DIM_SHIFT(m, 0))
+
+#define NV50_TILE_SIZE(m) (NV50_TILE_SIZE_2D(m) << NV50_TILE_DIM_SHIFT(m, 1))
+
 struct nv50_miptree_level {
-       int *image_offset;
-       unsigned pitch;
-       unsigned tile_mode;
+   uint32_t offset;
+   uint32_t pitch;
+   uint32_t tile_mode;
 };
 
 #define NV50_MAX_TEXTURE_LEVELS 16
 
 struct nv50_miptree {
-       struct nv50_resource base;
-
-       struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS];
-       int image_nr;
-       int total_size;
+   struct nv50_resource base;
+   struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS];
+   uint32_t total_size;
+   uint32_t layer_stride;
+   boolean layout_3d; /* TRUE if layer count varies with mip level */
 };
 
 static INLINE struct nv50_miptree *
 nv50_miptree(struct pipe_resource *pt)
 {
-       return (struct nv50_miptree *)pt;
+   return (struct nv50_miptree *)pt;
 }
 
-
-static INLINE 
-struct nv50_resource *nv50_resource(struct pipe_resource *resource)
+static INLINE struct nv50_resource *
+nv50_resource(struct pipe_resource *resource)
 {
-       return (struct nv50_resource *)resource;
+   return (struct nv50_resource *)resource;
 }
 
 /* is resource mapped into the GPU's address space (i.e. VRAM or GART) ? */
 static INLINE boolean
 nv50_resource_mapped_by_gpu(struct pipe_resource *resource)
 {
-   return nv50_resource(resource)->bo->handle;
+   return nv50_resource(resource)->domain != 0;
 }
 
 void
@@ -64,34 +167,37 @@ nv50_init_resource_functions(struct pipe_context *pcontext);
 void
 nv50_screen_init_resource_functions(struct pipe_screen *pscreen);
 
-/* Internal functions
+/* Internal functions:
  */
 struct pipe_resource *
 nv50_miptree_create(struct pipe_screen *pscreen,
-                   const struct pipe_resource *tmp);
+                    const struct pipe_resource *tmp);
 
 struct pipe_resource *
 nv50_miptree_from_handle(struct pipe_screen *pscreen,
-                        const struct pipe_resource *template,
-                        struct winsys_handle *whandle);
+                         const struct pipe_resource *template,
+                         struct winsys_handle *whandle);
 
 struct pipe_resource *
 nv50_buffer_create(struct pipe_screen *pscreen,
-                  const struct pipe_resource *template);
+                   const struct pipe_resource *templ);
 
 struct pipe_resource *
 nv50_user_buffer_create(struct pipe_screen *screen,
-                       void *ptr,
-                       unsigned bytes,
-                       unsigned usage);
+                        void *ptr,
+                        unsigned bytes,
+                        unsigned usage);
 
 
 struct pipe_surface *
-nv50_miptree_surface_new(struct pipe_context *pipe, struct pipe_resource *pt,
-                        const struct pipe_surface *surf_tmpl);
+nv50_miptree_surface_new(struct pipe_context *,
+                         struct pipe_resource *,
+                         const struct pipe_surface *templ);
 
 void
-nv50_miptree_surface_del(struct pipe_context *pipe, struct pipe_surface *ps);
+nv50_miptree_surface_del(struct pipe_context *, struct pipe_surface *);
 
+boolean
+nv50_user_buffer_upload(struct nv50_resource *, unsigned base, unsigned size);
 
 #endif
index edc3d54d01287c57621beb92cadeec4d32d01a4a..77cf959940dc5368451cd6d7b9d6e0fcf3bed785 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Ben Skeggs
+ * Copyright 2010 Christoph Bumiller
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "util/u_format_s3tc.h"
 #include "pipe/p_screen.h"
 
+#include "nv50_fence.h"
 #include "nv50_context.h"
 #include "nv50_screen.h"
-#include "nv50_resource.h"
-#include "nv50_program.h"
 
-#include "nouveau/nouveau_stateobj.h"
+#include "nouveau/nv_object.xml.h"
+
+#ifndef NOUVEAU_GETPARAM_GRAPH_UNITS
+# define NOUVEAU_GETPARAM_GRAPH_UNITS 13
+#endif
+
+extern int nouveau_device_get_param(struct nouveau_device *dev,
+                                    uint64_t param, uint64_t *value);
 
 static boolean
 nv50_screen_is_format_supported(struct pipe_screen *pscreen,
-                               enum pipe_format format,
-                               enum pipe_texture_target target,
-                               unsigned sample_count,
-                               unsigned usage, unsigned geom_flags)
+                                enum pipe_format format,
+                                enum pipe_texture_target target,
+                                unsigned sample_count,
+                                unsigned bindings, unsigned geom_flags)
 {
-       if (sample_count > 1)
-               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;
-               }
-       }
-
-       switch (format) {
-       case PIPE_FORMAT_Z16_UNORM:
-               if ((nouveau_screen(pscreen)->device->chipset & 0xf0) != 0xa0)
-                       return FALSE;
-               break;
-       default:
-               break;
-       }
-
-       /* transfers & shared are always supported */
-       usage &= ~(PIPE_BIND_TRANSFER_READ |
-                  PIPE_BIND_TRANSFER_WRITE |
-                  PIPE_BIND_SHARED);
-
-       return (nv50_format_table[format].usage & usage) == usage;
+   if (sample_count > 1)
+      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;
+      }
+   }
+
+   switch (format) {
+   case PIPE_FORMAT_Z16_UNORM:
+      if ((nouveau_screen(pscreen)->device->chipset & 0xf0) != 0xa0)
+         return FALSE;
+      break;
+   default:
+      break;
+   }
+
+   /* transfers & shared are always supported */
+   bindings &= ~(PIPE_BIND_TRANSFER_READ |
+                 PIPE_BIND_TRANSFER_WRITE |
+                 PIPE_BIND_SHARED);
+
+   return (nv50_format_table[format].usage & bindings) == bindings;
 }
 
 static int
 nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 {
-       switch (param) {
-       case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
-               return 32;
-       case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
-               return 32;
-       case PIPE_CAP_MAX_COMBINED_SAMPLERS:
-               return 64;
-       case PIPE_CAP_NPOT_TEXTURES:
-               return 1;
-       case PIPE_CAP_TWO_SIDED_STENCIL:
-               return 1;
-       case PIPE_CAP_GLSL:
-       case PIPE_CAP_SM3:
-               return 1;
-       case PIPE_CAP_ANISOTROPIC_FILTER:
-               return 1;
-       case PIPE_CAP_POINT_SPRITE:
-               return 1;
-       case PIPE_CAP_MAX_RENDER_TARGETS:
-               return 8;
-       case PIPE_CAP_OCCLUSION_QUERY:
-               return 1;
-        case PIPE_CAP_TIMER_QUERY:
-               return 0;
-       case PIPE_CAP_STREAM_OUTPUT:
-               return 0;
-       case PIPE_CAP_TEXTURE_SHADOW_MAP:
-               return 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_TEXTURE_MIRROR_CLAMP:
-       case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
-               return 1;
-       case PIPE_CAP_TEXTURE_SWIZZLE:
-               return 1;
-       case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-               return 1;
-       case PIPE_CAP_INDEP_BLEND_ENABLE:
-               return 1;
-       case PIPE_CAP_INDEP_BLEND_FUNC:
-               return 0;
-       case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
-               return 1;
-       case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
-       case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
-               return 1;
-       case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
-       case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
-               return 0;
-       case PIPE_CAP_DEPTH_CLAMP:
-               return 1;
-       case PIPE_CAP_SHADER_STENCIL_EXPORT:
-               return 0;
-       case PIPE_CAP_PRIMITIVE_RESTART:
-               return 0;
-       default:
-               NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
-               return 0;
-       }
+   switch (param) {
+   case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+   case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+      return 32;
+   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+      return 64;
+   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_ARRAY_TEXTURES: /* shader support missing */
+      return 0;
+   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
+   case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
+   case PIPE_CAP_TEXTURE_SWIZZLE:
+   case PIPE_CAP_TEXTURE_SHADOW_MAP:
+   case PIPE_CAP_NPOT_TEXTURES:
+   case PIPE_CAP_ANISOTROPIC_FILTER:
+      return 1;
+   case PIPE_CAP_TWO_SIDED_STENCIL:
+   case PIPE_CAP_DEPTH_CLAMP:
+   case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+   case PIPE_CAP_POINT_SPRITE:
+      return 1;
+   case PIPE_CAP_GLSL:
+   case PIPE_CAP_SM3:
+      return 1;
+   case PIPE_CAP_MAX_RENDER_TARGETS:
+      return 8;
+   case PIPE_CAP_TIMER_QUERY:
+   case PIPE_CAP_OCCLUSION_QUERY:
+      return 1;
+   case PIPE_CAP_STREAM_OUTPUT:
+      return 0;
+   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+   case PIPE_CAP_INDEP_BLEND_ENABLE:
+   case PIPE_CAP_INDEP_BLEND_FUNC:
+      return 1;
+   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+      return 1;
+   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+      return 0;
+   case PIPE_CAP_SHADER_STENCIL_EXPORT:
+      return 0;
+   case PIPE_CAP_PRIMITIVE_RESTART:
+   case PIPE_CAP_INSTANCED_DRAWING:
+      return 1;
+   default:
+      NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
+      return 0;
+   }
 }
 
 static int
 nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
-                            enum pipe_shader_cap param)
+                             enum pipe_shader_cap param)
 {
-       switch(shader) {
-       case PIPE_SHADER_FRAGMENT:
-       case PIPE_SHADER_VERTEX:
-               break;
-       case PIPE_SHADER_GEOMETRY:
-       default:
-               return 0;
-       }
-
-       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: /* arbitrary limit */
-               return 16384;
-       case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: /* need stack bo */
-               return 4;
-       case PIPE_SHADER_CAP_MAX_INPUTS: /* 128 / 4 with GP */
-               if (shader == PIPE_SHADER_GEOMETRY)
-                       return 128 / 4;
-               else
-                       return 64 / 4;
-       case PIPE_SHADER_CAP_MAX_CONSTS:
-               return 65536 / 16;
-       case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: /* 16 - 1, but not implemented */
-               return 1;
-       case PIPE_SHADER_CAP_MAX_ADDRS: /* no spilling atm */
-               return 1;
-       case PIPE_SHADER_CAP_MAX_PREDS: /* not yet handled */
-               return 0;
-       case PIPE_SHADER_CAP_MAX_TEMPS: /* no spilling atm */
-               return NV50_CAP_MAX_PROGRAM_TEMPS;
-       case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
-               return 1;
-       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:
-               return 1;
-       case PIPE_SHADER_CAP_SUBROUTINES:
-               return 0;
-       default:
-               return 0;
-       }
+   switch (shader) {
+   case PIPE_SHADER_VERTEX:
+   case PIPE_SHADER_GEOMETRY:
+   case PIPE_SHADER_FRAGMENT:
+      break;
+   default:
+      return 0;
+   }
+   
+   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 16384;
+   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+      return 4;
+   case PIPE_SHADER_CAP_MAX_INPUTS:
+      if (shader == PIPE_SHADER_VERTEX)
+         return 32;
+      return 0x300 / 16;
+   case PIPE_SHADER_CAP_MAX_CONSTS:
+      return 65536 / 16;
+   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+      return 14;
+   case PIPE_SHADER_CAP_MAX_ADDRS:
+      return 1;
+   case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
+   case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
+      return shader != PIPE_SHADER_FRAGMENT;
+   case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
+   case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
+      return 1;
+   case PIPE_SHADER_CAP_MAX_PREDS:
+      return 0;
+   case PIPE_SHADER_CAP_MAX_TEMPS:
+      return NV50_CAP_MAX_PROGRAM_TEMPS;
+   case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+      return 1;
+   case PIPE_SHADER_CAP_SUBROUTINES:
+      return 0; /* please inline, or provide function declarations */
+   default:
+      NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param);
+      return 0;
+   }
 }
 
 static float
 nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param)
 {
-       switch (param) {
-       case PIPE_CAP_MAX_LINE_WIDTH:
-       case PIPE_CAP_MAX_LINE_WIDTH_AA:
-               return 10.0;
-       case PIPE_CAP_MAX_POINT_WIDTH:
-       case PIPE_CAP_MAX_POINT_WIDTH_AA:
-               return 64.0;
-       case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
-               return 16.0;
-       case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
-               return 4.0;
-       default:
-               NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
-               return 0.0;
-       }
+   switch (param) {
+   case PIPE_CAP_MAX_LINE_WIDTH:
+   case PIPE_CAP_MAX_LINE_WIDTH_AA:
+      return 10.0f;
+   case PIPE_CAP_MAX_POINT_WIDTH:
+   case PIPE_CAP_MAX_POINT_WIDTH_AA:
+      return 64.0f;
+   case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+      return 16.0f;
+   case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+      return 4.0f;
+   default:
+      NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
+      return 0.0f;
+   }
 }
 
 static void
 nv50_screen_destroy(struct pipe_screen *pscreen)
 {
-       struct nv50_screen *screen = nv50_screen(pscreen);
-       unsigned i;
-
-       for (i = 0; i < 3; i++) {
-               if (screen->constbuf_parm[i])
-                       nouveau_bo_ref(NULL, &screen->constbuf_parm[i]);
-       }
-
-       if (screen->constbuf_misc[0])
-               nouveau_bo_ref(NULL, &screen->constbuf_misc[0]);
-       if (screen->tic)
-               nouveau_bo_ref(NULL, &screen->tic);
-       if (screen->tsc)
-               nouveau_bo_ref(NULL, &screen->tsc);
-
-       nouveau_notifier_free(&screen->sync);
-       nouveau_grobj_free(&screen->tesla);
-       nouveau_grobj_free(&screen->eng2d);
-       nouveau_grobj_free(&screen->m2mf);
-       nouveau_resource_destroy(&screen->immd_heap);
-       nouveau_screen_fini(&screen->base);
-       FREE(screen);
+   struct nv50_screen *screen = nv50_screen(pscreen);
+
+   if (screen->fence.current) {
+      nv50_fence_wait(screen->fence.current);
+      nv50_fence_reference(&screen->fence.current, NULL);
+   }
+
+   nouveau_bo_ref(NULL, &screen->code);
+   nouveau_bo_ref(NULL, &screen->tls_bo);
+   nouveau_bo_ref(NULL, &screen->stack_bo);
+   nouveau_bo_ref(NULL, &screen->txc);
+   nouveau_bo_ref(NULL, &screen->uniforms);
+   nouveau_bo_ref(NULL, &screen->fence.bo);
+
+   nouveau_resource_destroy(&screen->vp_code_heap);
+   nouveau_resource_destroy(&screen->gp_code_heap);
+   nouveau_resource_destroy(&screen->fp_code_heap);
+
+   if (screen->tic.entries)
+      FREE(screen->tic.entries);
+
+   nv50_mm_destroy(screen->mm_GART);
+   nv50_mm_destroy(screen->mm_VRAM);
+   nv50_mm_destroy(screen->mm_VRAM_fe0);
+
+   nouveau_grobj_free(&screen->tesla);
+   nouveau_grobj_free(&screen->eng2d);
+   nouveau_grobj_free(&screen->m2mf);
+
+   nouveau_notifier_free(&screen->sync);
+
+   nouveau_screen_fini(&screen->base);
+
+   FREE(screen);
 }
 
-#define BGN_RELOC(ch, bo, gr, m, n, fl) \
-   OUT_RELOC(ch, bo, (n << 18) | (gr->subc << 13) | m, fl, 0, 0)
+static void
+nv50_screen_fence_reference(struct pipe_screen *pscreen,
+                            struct pipe_fence_handle **ptr,
+                            struct pipe_fence_handle *fence)
+{
+   nv50_fence_reference((struct nv50_fence **)ptr, nv50_fence(fence));
+}
 
-void
-nv50_screen_reloc_constbuf(struct nv50_screen *screen, unsigned cbi)
+static int
+nv50_screen_fence_signalled(struct pipe_screen *pscreen,
+                            struct pipe_fence_handle *fence,
+                            unsigned flags)
 {
-       struct nouveau_bo *bo;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *tesla = screen->tesla;
-       unsigned size;
-       const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
-
-       switch (cbi) {
-       case NV50_CB_PMISC:
-               bo = screen->constbuf_misc[0];
-               size = 0x200;
-               break;
-       case NV50_CB_PVP:
-       case NV50_CB_PFP:
-       case NV50_CB_PGP:
-               bo = screen->constbuf_parm[cbi - NV50_CB_PVP];
-               size = 0;
-               break;
-       default:
-               return;
-       }
-
-       BGN_RELOC (chan, bo, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
-       OUT_RELOCh(chan, bo, 0, rl);
-       OUT_RELOCl(chan, bo, 0, rl);
-       OUT_RELOC (chan, bo, (cbi << 16) | size, rl, 0, 0);
+   return !(nv50_fence_signalled(nv50_fence(fence)));
 }
 
-void
-nv50_screen_relocs(struct nv50_screen *screen)
+static int
+nv50_screen_fence_finish(struct pipe_screen *pscreen,
+                         struct pipe_fence_handle *fence,
+                         unsigned flags)
 {
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *tesla = screen->tesla;
-       unsigned i;
-       const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
+   return nv50_fence_wait((struct nv50_fence *)fence) != TRUE;
+}
+
+#define FAIL_SCREEN_INIT(str, err)                    \
+   do {                                               \
+      NOUVEAU_ERR(str, err);                          \
+      nv50_screen_destroy(pscreen);                   \
+      return NULL;                                    \
+   } while(0)
 
-       MARK_RING (chan, 28, 26);
+struct pipe_screen *
+nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
+{
+   struct nv50_screen *screen;
+   struct nouveau_channel *chan;
+   struct pipe_screen *pscreen;
+   uint64_t value;
+   uint32_t tesla_class;
+   unsigned stack_size, max_warps, tls_space;
+   int ret;
+   unsigned i;
+
+   screen = CALLOC_STRUCT(nv50_screen);
+   if (!screen)
+      return NULL;
+   pscreen = &screen->base.base;
+
+   ret = nouveau_screen_init(&screen->base, dev);
+   if (ret)
+      FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret);
+
+   chan = screen->base.channel;
+
+   pscreen->winsys = ws;
+   pscreen->destroy = nv50_screen_destroy;
+   pscreen->context_create = nv50_create;
+   pscreen->is_format_supported = nv50_screen_is_format_supported;
+   pscreen->get_param = nv50_screen_get_param;
+   pscreen->get_shader_param = nv50_screen_get_shader_param;
+   pscreen->get_paramf = nv50_screen_get_paramf;
+   pscreen->fence_reference = nv50_screen_fence_reference;
+   pscreen->fence_signalled = nv50_screen_fence_signalled;
+   pscreen->fence_finish = nv50_screen_fence_finish;
+
+   nv50_screen_init_resource_functions(pscreen);
+
+   screen->base.vertex_buffer_flags = screen->base.index_buffer_flags =
+      NOUVEAU_BO_GART;
+
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096,
+                        &screen->fence.bo);
+   if (ret)
+      goto fail;
+   nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR);
+   screen->fence.map = screen->fence.bo->map;
+   nouveau_bo_unmap(screen->fence.bo);
+
+   ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
+   if (ret)
+      FAIL_SCREEN_INIT("Error allocating notifier: %d\n", ret);
+
+   ret = nouveau_grobj_alloc(chan, 0xbeef5039, NV50_M2MF, &screen->m2mf);
+   if (ret)
+      FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret);
+
+   BIND_RING (chan, screen->m2mf, NV50_SUBCH_MF);
+   BEGIN_RING(chan, RING_MF_(NV04_M2MF_DMA_NOTIFY), 3);
+   OUT_RING  (chan, screen->sync->handle);
+   OUT_RING  (chan, chan->vram->handle);
+   OUT_RING  (chan, chan->vram->handle);
+
+   ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d);
+   if (ret)
+      FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret);
+
+   BIND_RING (chan, screen->eng2d, NV50_SUBCH_2D);
+   BEGIN_RING(chan, RING_2D(DMA_NOTIFY), 4);
+   OUT_RING  (chan, screen->sync->handle);
+   OUT_RING  (chan, chan->vram->handle);
+   OUT_RING  (chan, chan->vram->handle);
+   OUT_RING  (chan, chan->vram->handle);
+   BEGIN_RING(chan, RING_2D(OPERATION), 1);
+   OUT_RING  (chan, NV50_2D_OPERATION_SRCCOPY);
+   BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1);
+   OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1);
+   OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_2D_(0x0888), 1);
+   OUT_RING  (chan, 1);
+
+   switch (dev->chipset & 0xf0) {
+   case 0x50:
+      tesla_class = NV50_3D;
+      break;
+   case 0x80:
+   case 0x90:
+      tesla_class = NV84_3D;
+      break;
+   case 0xa0:
+      switch (dev->chipset) {
+      case 0xa0:
+      case 0xaa:
+      case 0xac:
+         tesla_class = NVA0_3D;
+         break;
+      case 0xaf:
+         tesla_class = NVAF_3D;
+         break;
+      default:
+         tesla_class = NVA3_3D;
+         break;
+      }
+      break;
+   default:
+      FAIL_SCREEN_INIT("Not a known NV50 chipset: NV%02x\n", dev->chipset);
+      break;
+   }
+
+   ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla);
+   if (ret)
+      FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret);
+
+   BIND_RING (chan, screen->tesla, NV50_SUBCH_3D);
+
+   BEGIN_RING(chan, RING_3D(COND_MODE), 1);
+   OUT_RING  (chan, NV50_3D_COND_MODE_ALWAYS);
+
+   BEGIN_RING(chan, RING_3D(DMA_NOTIFY), 1);
+   OUT_RING  (chan, screen->sync->handle);
+   BEGIN_RING(chan, RING_3D(DMA_ZETA), 11);
+   for (i = 0; i < 11; ++i)
+      OUT_RING(chan, chan->vram->handle);
+   BEGIN_RING(chan, RING_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
+   for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
+      OUT_RING(chan, chan->vram->handle);
+
+   BEGIN_RING(chan, RING_3D(REG_MODE), 1);
+   OUT_RING  (chan, NV50_3D_REG_MODE_STRIPED);
+   BEGIN_RING(chan, RING_3D(UNK1400_LANES), 1);
+   OUT_RING  (chan, 0xf);
+
+   BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
+   OUT_RING  (chan, 1);
+
+   BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1);
+   OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1);
+   OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
+   OUT_RING  (chan, NV50_3D_MULTISAMPLE_MODE_MS1);
+   BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1);
+   OUT_RING  (chan, 0);
+
+   BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1);
+   OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_3D(ZCULL_REGION), 1); /* deactivate ZCULL */
+   OUT_RING  (chan, 0x3f);
+
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, &screen->code);
+   if (ret)
+      goto fail;
+
+   nouveau_resource_init(&screen->vp_code_heap, 0, 1 << 16);
+   nouveau_resource_init(&screen->gp_code_heap, 0, 1 << 16);
+   nouveau_resource_init(&screen->fp_code_heap, 0, 1 << 16);
+
+   BEGIN_RING(chan, RING_3D(VP_ADDRESS_HIGH), 2);
+   OUT_RELOCh(chan, screen->code, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, screen->code, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+
+   BEGIN_RING(chan, RING_3D(FP_ADDRESS_HIGH), 2);
+   OUT_RELOCh(chan, screen->code, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, screen->code, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+
+   BEGIN_RING(chan, RING_3D(GP_ADDRESS_HIGH), 2);
+   OUT_RELOCh(chan, screen->code, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, screen->code, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+
+   nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
+
+   max_warps  = util_bitcount(value & 0xffff);
+   max_warps *= util_bitcount((value >> 24) & 0xf) * 32;
+
+   stack_size = max_warps * 64 * 8;
+
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size,
+                        &screen->stack_bo);
+   if (ret)
+      FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret);
+
+   BEGIN_RING(chan, RING_3D(STACK_ADDRESS_HIGH), 3);
+   OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+   OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+   OUT_RING  (chan, 4);
+
+   tls_space = NV50_CAP_MAX_PROGRAM_TEMPS * 16;
+
+   screen->tls_size = tls_space * max_warps * 32;
+
+   debug_printf("max_warps = %i, tls_size = %lu KiB\n",
+                max_warps, screen->tls_size >> 10);
+
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size,
+                        &screen->tls_bo);
+   if (ret)
+      FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret);
+
+   BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 3);
+   OUT_RELOCh(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+   OUT_RELOCl(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+   OUT_RING  (chan, util_unsigned_logbase2(tls_space / 8));
+
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16,
+                        &screen->uniforms);
+   if (ret)
+      goto fail;
+
+   BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
+   OUT_RELOCh(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RING  (chan, (NV50_CB_PVP << 16) | 0x0000);
+
+   BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
+   OUT_RELOCh(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RING  (chan, (NV50_CB_PGP << 16) | 0x0000);
+
+   BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
+   OUT_RELOCh(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RING  (chan, (NV50_CB_PFP << 16) | 0x0000);
+
+   BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
+   OUT_RELOCh(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RING  (chan, (NV50_CB_AUX << 16) | 0x0200);
+
+   BEGIN_RING_NI(chan, RING_3D(SET_PROGRAM_CB), 6);
+   OUT_RING  (chan, (NV50_CB_PVP << 12) | 0x001);
+   OUT_RING  (chan, (NV50_CB_PGP << 12) | 0x021);
+   OUT_RING  (chan, (NV50_CB_PFP << 12) | 0x031);
+   OUT_RING  (chan, (NV50_CB_AUX << 12) | 0xf01);
+   OUT_RING  (chan, (NV50_CB_AUX << 12) | 0xf21);
+   OUT_RING  (chan, (NV50_CB_AUX << 12) | 0xf31);
+
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16,
+                        &screen->txc);
+   if (ret)
+      FAIL_SCREEN_INIT("Could not allocate TIC/TSC bo: %d\n", ret);
+
+   /* max TIC (bits 4:8) & TSC bindings, per program type */
+   for (i = 0; i < 3; ++i) {
+      BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1);
+      OUT_RING  (chan, 0x54);
+   }
+
+   BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3);
+   OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RING  (chan, NV50_TIC_MAX_ENTRIES - 1);
+
+   BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3);
+   OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   OUT_RING  (chan, NV50_TSC_MAX_ENTRIES - 1);
+
+   BEGIN_RING(chan, RING_3D(LINKED_TSC), 1);
+   OUT_RING  (chan, 0);
+
+   BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1);
+   OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1);
+   OUT_RING  (chan, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
+   BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
+   for (i = 0; i < 8 * 2; ++i)
+      OUT_RING(chan, 0);
+   BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1);
+   OUT_RING  (chan, 0);
+
+   BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
+   OUT_RING  (chan, 1);
+   BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
+   OUT_RINGf (chan, 0.0f);
+   OUT_RINGf (chan, 1.0f);
+
+   BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
+#ifdef NV50_SCISSORS_CLIPPING
+   OUT_RING  (chan, 0x0000);
+#else
+   OUT_RING  (chan, 0x1080);
+#endif
 
-       /* cause grobj autobind */
-       BEGIN_RING(chan, tesla, 0x0100, 1);
-       OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1);
+   OUT_RING  (chan, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);
 
-       BGN_RELOC (chan, screen->tic, tesla, NV50TCL_TIC_ADDRESS_HIGH, 2, rl);
-       OUT_RELOCh(chan, screen->tic, 0, rl);
-       OUT_RELOCl(chan, screen->tic, 0, rl);
+   /* We use scissors instead of exact view volume clipping,
+    * so they're always enabled.
+    */
+   BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3);
+   OUT_RING  (chan, 1);
+   OUT_RING  (chan, 8192 << 16);
+   OUT_RING  (chan, 8192 << 16);
 
-       BGN_RELOC (chan, screen->tsc, tesla, NV50TCL_TSC_ADDRESS_HIGH, 2, rl);
-       OUT_RELOCh(chan, screen->tsc, 0, rl);
-       OUT_RELOCl(chan, screen->tsc, 0, rl);
+   BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1);
+   OUT_RING  (chan, 1);
+   BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1);
+   OUT_RING  (chan, NV50_3D_POINT_RASTER_RULES_OGL);
+   BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1);
+   OUT_RING  (chan, 0x11111111);
+   BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
+   OUT_RING  (chan, 1);
 
-       nv50_screen_reloc_constbuf(screen, NV50_CB_PMISC);
+   FIRE_RING (chan);
 
-       BGN_RELOC (chan, screen->constbuf_misc[0],
-                  tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
-       OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl);
-       OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl);
-       OUT_RELOC (chan, screen->constbuf_misc[0],
-                  (NV50_CB_AUX << 16) | 0x0200, rl, 0, 0);
+   screen->tic.entries = CALLOC(4096, sizeof(void *));
+   screen->tsc.entries = screen->tic.entries + 2048;
 
-       for (i = 0; i < 3; ++i)
-               nv50_screen_reloc_constbuf(screen, NV50_CB_PVP + i);
+   screen->mm_GART = nv50_mm_create(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
+                                    0x000);
+   screen->mm_VRAM = nv50_mm_create(dev, NOUVEAU_BO_VRAM, 0x000);
+   screen->mm_VRAM_fe0 = nv50_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0);
 
-       BGN_RELOC (chan, screen->stack_bo,
-                  tesla, NV50TCL_STACK_ADDRESS_HIGH, 2, rl);
-       OUT_RELOCh(chan, screen->stack_bo, 0, rl);
-       OUT_RELOCl(chan, screen->stack_bo, 0, rl);
+   nv50_screen_fence_new(screen, &screen->fence.current, FALSE);
 
-       if (!screen->cur_ctx->req_lmem)
-               return;
+   return pscreen;
 
-       BGN_RELOC (chan, screen->local_bo,
-                  tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 2, rl);
-       OUT_RELOCh(chan, screen->local_bo, 0, rl);
-       OUT_RELOCl(chan, screen->local_bo, 0, rl);
+fail:
+   nv50_screen_destroy(pscreen);
+   return NULL;
 }
 
-#ifndef NOUVEAU_GETPARAM_GRAPH_UNITS
-# define NOUVEAU_GETPARAM_GRAPH_UNITS 13
-#endif
+void
+nv50_screen_make_buffers_resident(struct nv50_screen *screen)
+{
+   struct nouveau_channel *chan = screen->base.channel;
 
-extern int nouveau_device_get_param(struct nouveau_device *dev,
-                                    uint64_t param, uint64_t *value);
+   const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
 
-struct pipe_screen *
-nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
+   MARK_RING(chan, 5, 5);
+   nouveau_bo_validate(chan, screen->code, flags);
+   nouveau_bo_validate(chan, screen->uniforms, flags);
+   nouveau_bo_validate(chan, screen->txc, flags);
+   nouveau_bo_validate(chan, screen->tls_bo, flags);
+   nouveau_bo_validate(chan, screen->stack_bo, flags);
+}
+
+int
+nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry)
 {
-       struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
-       struct nouveau_channel *chan;
-       struct pipe_screen *pscreen;
-       uint64_t value;
-       unsigned chipset = dev->chipset;
-       unsigned tesla_class = 0;
-       unsigned stack_size, local_size, max_warps;
-       int ret, i;
-       const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
-
-       if (!screen)
-               return NULL;
-       pscreen = &screen->base.base;
-
-       ret = nouveau_screen_init(&screen->base, dev);
-       if (ret) {
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-       chan = screen->base.channel;
-
-       pscreen->winsys = ws;
-       pscreen->destroy = nv50_screen_destroy;
-       pscreen->get_param = nv50_screen_get_param;
-       pscreen->get_shader_param = nv50_screen_get_shader_param;
-       pscreen->get_paramf = nv50_screen_get_paramf;
-       pscreen->is_format_supported = nv50_screen_is_format_supported;
-       pscreen->context_create = nv50_create;
-
-       nv50_screen_init_resource_functions(pscreen);
-
-       /* DMA engine object */
-       ret = nouveau_grobj_alloc(chan, 0xbeef5039,
-               NV50_MEMORY_TO_MEMORY_FORMAT, &screen->m2mf);
-       if (ret) {
-               NOUVEAU_ERR("Error creating M2MF object: %d\n", ret);
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-
-       /* 2D object */
-       ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d);
-       if (ret) {
-               NOUVEAU_ERR("Error creating 2D object: %d\n", ret);
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-
-       /* 3D object */
-       switch (chipset & 0xf0) {
-       case 0x50:
-               tesla_class = NV50TCL;
-               break;
-       case 0x80:
-       case 0x90:
-               tesla_class = NV84TCL;
-               break;
-       case 0xa0:
-               switch (chipset) {
-               case 0xa0:
-               case 0xaa:
-               case 0xac:
-                       tesla_class = NVA0TCL;
-                       break;
-               default:
-                       tesla_class = NVA8TCL;
-                       break;
-               }
-               break;
-       default:
-               NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset);
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-
-       ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class,
-               &screen->tesla);
-       if (ret) {
-               NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-
-       /* this is necessary for the new RING_3D / statebuffer code */
-       BIND_RING(chan, screen->tesla, 7);
-
-       /* Sync notifier */
-       ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
-       if (ret) {
-               NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-
-       /* Static M2MF init */
-       BEGIN_RING(chan, screen->m2mf,
-                  NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
-       OUT_RING  (chan, screen->sync->handle);
-       OUT_RING  (chan, chan->vram->handle);
-       OUT_RING  (chan, chan->vram->handle);
-
-       /* Static 2D init */
-       BEGIN_RING(chan, screen->eng2d, NV50_2D_DMA_NOTIFY, 4);
-       OUT_RING  (chan, screen->sync->handle);
-       OUT_RING  (chan, chan->vram->handle);
-       OUT_RING  (chan, chan->vram->handle);
-       OUT_RING  (chan, chan->vram->handle);
-       BEGIN_RING(chan, screen->eng2d, NV50_2D_OPERATION, 1);
-       OUT_RING  (chan, NV50_2D_OPERATION_SRCCOPY);
-       BEGIN_RING(chan, screen->eng2d, NV50_2D_CLIP_ENABLE, 1);
-       OUT_RING  (chan, 0);
-       BEGIN_RING(chan, screen->eng2d, 0x0888, 1);
-       OUT_RING  (chan, 1);
-
-       /* Static tesla init */
-       BEGIN_RING(chan, screen->tesla, NV50TCL_COND_MODE, 1);
-       OUT_RING  (chan, NV50TCL_COND_MODE_ALWAYS);
-       BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
-       OUT_RING  (chan, screen->sync->handle);
-       BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_ZETA, 11);
-       for (i = 0; i < 11; i++)
-               OUT_RING  (chan, chan->vram->handle);
-       BEGIN_RING(chan, screen->tesla,
-                  NV50TCL_DMA_COLOR(0), NV50TCL_DMA_COLOR__SIZE);
-       for (i = 0; i < NV50TCL_DMA_COLOR__SIZE; i++)
-               OUT_RING  (chan, chan->vram->handle);
-
-       BEGIN_RING(chan, screen->tesla, NV50TCL_RT_CONTROL, 1);
-       OUT_RING  (chan, 1);
-
-       /* activate all 32 lanes (threads) in a warp */
-       BEGIN_RING(chan, screen->tesla, NV50TCL_REG_MODE, 1);
-       OUT_RING  (chan, NV50TCL_REG_MODE_STRIPED);
-       BEGIN_RING(chan, screen->tesla, 0x1400, 1);
-       OUT_RING  (chan, 0xf);
-
-       /* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */
-       for (i = 0; i < 3; ++i) {
-               BEGIN_RING(chan, screen->tesla, NV50TCL_TEX_LIMITS(i), 1);
-               OUT_RING  (chan, 0x54);
-       }
-
-       /* origin is top left (set to 1 for bottom left) */
-       BEGIN_RING(chan, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1);
-       OUT_RING  (chan, 0);
-       BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
-       OUT_RING  (chan, 8);
-
-       BEGIN_RING(chan, screen->tesla, NV50TCL_CLEAR_FLAGS, 1);
-       OUT_RING  (chan, NV50TCL_CLEAR_FLAGS_D3D);
-
-       /* constant buffers for immediates and VP/FP parameters */
-       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4,
-                            &screen->constbuf_misc[0]);
-       if (ret) {
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-       BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
-       OUT_RELOCh(chan, screen->constbuf_misc[0], 0, rl);
-       OUT_RELOCl(chan, screen->constbuf_misc[0], 0, rl);
-       OUT_RING  (chan, (NV50_CB_PMISC << 16) | 0x0200);
-       BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
-       OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl);
-       OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl);
-       OUT_RING  (chan, (NV50_CB_AUX << 16) | 0x0200);
-
-       for (i = 0; i < 3; i++) {
-               ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (4096 * 4) * 4,
-                                    &screen->constbuf_parm[i]);
-               if (ret) {
-                       nv50_screen_destroy(pscreen);
-                       return NULL;
-               }
-               BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
-               OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl);
-               OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl);
-               /* CB_DEF_SET_SIZE value of 0x0000 means 65536 */
-               OUT_RING  (chan, ((NV50_CB_PVP + i) << 16) | 0x0000);
-       }
-
-       if (nouveau_resource_init(&screen->immd_heap, 0, 128)) {
-               NOUVEAU_ERR("Error initialising shader immediates heap.\n");
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-
-       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),
-                            &screen->tic);
-       if (ret) {
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-       BEGIN_RING(chan, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
-       OUT_RELOCh(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RELOCl(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RING  (chan, 3 * 32 - 1);
-
-       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),
-                            &screen->tsc);
-       if (ret) {
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-       BEGIN_RING(chan, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3);
-       OUT_RELOCh(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RELOCl(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RING  (chan, 0); /* ignored if TSC_LINKED (0x1234) == 1 */
-
-       /* map constant buffers:
-        *  B = buffer ID (maybe more than 1 byte)
-        *  N = CB index used in shader instruction
-        *  P = program type (0 = VP, 2 = GP, 3 = FP)
-        * SET_PROGRAM_CB = 0x000BBNP1
-        */
-       BEGIN_RING_NI(chan, screen->tesla, NV50TCL_SET_PROGRAM_CB, 8);
-       /* bind immediate buffer */
-       OUT_RING  (chan, 0x001 | (NV50_CB_PMISC << 12));
-       OUT_RING  (chan, 0x021 | (NV50_CB_PMISC << 12));
-       OUT_RING  (chan, 0x031 | (NV50_CB_PMISC << 12));
-       /* bind auxiliary constbuf to immediate data bo */
-       OUT_RING  (chan, 0x201 | (NV50_CB_AUX << 12));
-       OUT_RING  (chan, 0x221 | (NV50_CB_AUX << 12));
-       /* bind parameter buffers */
-       OUT_RING  (chan, 0x101 | (NV50_CB_PVP << 12));
-       OUT_RING  (chan, 0x121 | (NV50_CB_PGP << 12));
-       OUT_RING  (chan, 0x131 | (NV50_CB_PFP << 12));
-
-       /* shader stack */
-       nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
-
-       max_warps  = util_bitcount(value & 0xffff);
-       max_warps *= util_bitcount((value >> 24) & 0xf) * 32;
-
-       stack_size = max_warps * 64 * 8;
-
-       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
-                            stack_size, &screen->stack_bo);
-       if (ret) {
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-       BEGIN_RING(chan, screen->tesla, NV50TCL_STACK_ADDRESS_HIGH, 3);
-       OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RING  (chan, 4);
-
-       local_size = (NV50_CAP_MAX_PROGRAM_TEMPS * 16) * max_warps * 32;
-
-       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
-                            local_size, &screen->local_bo);
-       if (ret) {
-               nv50_screen_destroy(pscreen);
-               return NULL;
-       }
-
-       local_size = NV50_CAP_MAX_PROGRAM_TEMPS * 16;
-
-       BEGIN_RING(chan, screen->tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 3);
-       OUT_RELOCh(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RING  (chan, util_unsigned_logbase2(local_size / 8));
-
-       /* Vertex array limits - max them out */
-       for (i = 0; i < 16; i++) {
-               BEGIN_RING(chan, screen->tesla,
-                          NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
-               OUT_RING  (chan, 0x000000ff);
-               OUT_RING  (chan, 0xffffffff);
-       }
-
-       BEGIN_RING(chan, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2);
-       OUT_RINGf (chan, 0.0f);
-       OUT_RINGf (chan, 1.0f);
-
-       BEGIN_RING(chan, screen->tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
-       OUT_RING  (chan, 1);
-
-       /* no dynamic combination of TIC & TSC entries => only BIND_TIC used */
-       BEGIN_RING(chan, screen->tesla, NV50TCL_LINKED_TSC, 1);
-       OUT_RING  (chan, 1);
-
-       BEGIN_RING(chan, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
-       OUT_RING  (chan, 1); /* default edgeflag to TRUE */
-
-       FIRE_RING (chan);
-
-       screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE);
-       if(!screen->force_push)
-               screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART;
-       return pscreen;
+   int i = screen->tic.next;
+
+   while (screen->tic.lock[i / 32] & (1 << (i % 32)))
+      i = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1);
+
+   screen->tic.next = (i + 1) & (NV50_TIC_MAX_ENTRIES - 1);
+
+   if (screen->tic.entries[i])
+      nv50_tic_entry(screen->tic.entries[i])->id = -1;
+
+   screen->tic.entries[i] = entry;
+   return i;
 }
 
+int
+nv50_screen_tsc_alloc(struct nv50_screen *screen, void *entry)
+{
+   int i = screen->tsc.next;
+
+   while (screen->tsc.lock[i / 32] & (1 << (i % 32)))
+      i = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1);
+
+   screen->tsc.next = (i + 1) & (NV50_TSC_MAX_ENTRIES - 1);
+
+   if (screen->tsc.entries[i])
+      nv50_tsc_entry(screen->tsc.entries[i])->id = -1;
+
+   screen->tsc.entries[i] = entry;
+   return i;
+}
index 6e15230b486fa604cc35c4142483d4ab8b8b5e04..c78ed50fe351224cc6376133be4038ae805493fc 100644 (file)
 #ifndef __NV50_SCREEN_H__
 #define __NV50_SCREEN_H__
 
+#define NOUVEAU_NVC0
 #include "nouveau/nouveau_screen.h"
+#undef NOUVEAU_NVC0
+#include "nv50_winsys.h"
+#include "nv50_stateobj.h"
 
+#define NV50_TIC_MAX_ENTRIES 2048
+#define NV50_TSC_MAX_ENTRIES 2048
+
+struct nv50_mman;
 struct nv50_context;
+struct nv50_fence;
+
+#define NV50_SCRATCH_SIZE (2 << 20)
+#define NV50_SCRATCH_NR_BUFFERS 2
 
 struct nv50_screen {
-       struct nouveau_screen base;
+   struct nouveau_screen base;
+   struct nouveau_winsys *nvws;
+
+   struct nv50_context *cur_ctx;
+
+   struct nouveau_bo *code;
+   struct nouveau_bo *uniforms;
+   struct nouveau_bo *txc; /* TIC (offset 0) and TSC (65536) */
+   struct nouveau_bo *stack_bo;
+   struct nouveau_bo *tls_bo;
+
+   uint64_t tls_size;
+
+   struct nouveau_resource *vp_code_heap;
+   struct nouveau_resource *gp_code_heap;
+   struct nouveau_resource *fp_code_heap;
+
+   struct {
+      void **entries;
+      int next;
+      uint32_t lock[NV50_TIC_MAX_ENTRIES / 32];
+   } tic;
+   
+   struct {
+      void **entries;
+      int next;
+      uint32_t lock[NV50_TSC_MAX_ENTRIES / 32];
+   } tsc;
+
+   struct {
+      uint32_t *map;
+      struct nv50_fence *head;
+      struct nv50_fence *tail;
+      struct nv50_fence *current;
+      uint32_t sequence;
+      uint32_t sequence_ack;
+      struct nouveau_bo *bo;
+   } fence;
+
+   struct nouveau_notifier *sync;
+
+   struct nv50_mman *mm_GART;
+   struct nv50_mman *mm_VRAM;
+   struct nv50_mman *mm_VRAM_fe0;
+
+   struct nouveau_grobj *tesla;
+   struct nouveau_grobj *eng2d;
+   struct nouveau_grobj *m2mf;
+};
 
-       struct nouveau_winsys *nvws;
+static INLINE struct nv50_screen *
+nv50_screen(struct pipe_screen *screen)
+{
+   return (struct nv50_screen *)screen;
+}
 
-       struct nv50_context *cur_ctx;
+/* Since a resource can be migrated, we need to decouple allocations from
+ * them. This struct is linked with fences for delayed freeing of allocs.
+ */
+struct nv50_mm_allocation {
+   struct nv50_mm_allocation *next;
+   void *priv;
+   uint32_t offset;
+};
 
-       struct nouveau_grobj *tesla;
-       struct nouveau_grobj *eng2d;
-       struct nouveau_grobj *m2mf;
-       struct nouveau_notifier *sync;
+static INLINE void
+nv50_fence_sched_release(struct nv50_fence *nf, struct nv50_mm_allocation *mm)
+{
+   mm->next = nf->buffers;
+   nf->buffers = mm;
+}
 
-       struct nouveau_bo *constbuf_misc[1];
-       struct nouveau_bo *constbuf_parm[PIPE_SHADER_TYPES];
+extern struct nv50_mman *
+nv50_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type);
 
-       struct nouveau_resource *immd_heap;
+extern void
+nv50_mm_destroy(struct nv50_mman *);
 
-       struct nouveau_bo *tic;
-       struct nouveau_bo *tsc;
+extern struct nv50_mm_allocation *
+nv50_mm_allocate(struct nv50_mman *,
+                 uint32_t size, struct nouveau_bo **, uint32_t *offset);
+extern void
+nv50_mm_free(struct nv50_mm_allocation *);
 
-       struct nouveau_bo *stack_bo; /* control flow stack */
-       struct nouveau_bo *local_bo; /* l[] memory */
+void nv50_screen_make_buffers_resident(struct nv50_screen *);
 
-       boolean force_push;
-};
+int nv50_screen_tic_alloc(struct nv50_screen *, void *);
+int nv50_screen_tsc_alloc(struct nv50_screen *, void *);
 
-static INLINE struct nv50_screen *
-nv50_screen(struct pipe_screen *screen)
+static INLINE void
+nv50_resource_fence(struct nv50_resource *res, uint32_t flags)
 {
-       return (struct nv50_screen *)screen;
+   struct nv50_screen *screen = nv50_screen(res->base.screen);
+
+   if (res->mm) {
+      nv50_fence_reference(&res->fence, screen->fence.current);
+
+      if (flags & NOUVEAU_BO_WR)
+         nv50_fence_reference(&res->fence_wr, screen->fence.current);
+   }
 }
 
-extern void nv50_screen_relocs(struct nv50_screen *);
+static INLINE void
+nv50_resource_validate(struct nv50_resource *res, uint32_t flags)
+{
+   struct nv50_screen *screen = nv50_screen(res->base.screen);
+
+   if (likely(res->bo)) {
+      nouveau_bo_validate(screen->base.channel, res->bo, flags);
+
+      nv50_resource_fence(res, flags);
+   }
+}
 
-extern void nv50_screen_reloc_constbuf(struct nv50_screen *, unsigned cbi);
+
+boolean
+nv50_screen_fence_new(struct nv50_screen *, struct nv50_fence **, boolean emit);
+
+void
+nv50_screen_fence_next(struct nv50_screen *);
+void
+nv50_screen_fence_update(struct nv50_screen *, boolean flushed);
+
+static INLINE boolean
+nv50_screen_fence_emit(struct nv50_screen *screen)
+{
+   nv50_fence_emit(screen->fence.current);
+
+   return nv50_screen_fence_new(screen, &screen->fence.current, FALSE);
+}
 
 struct nv50_format {
-       uint32_t rt;
-       uint32_t tic;
-       uint32_t vtx;
-       uint32_t usage;
+   uint32_t rt;
+   uint32_t tic;
+   uint32_t vtx;
+   uint32_t usage;
 };
 
 extern const struct nv50_format nv50_format_table[];
 
+static INLINE void
+nv50_screen_tic_unlock(struct nv50_screen *screen, struct nv50_tic_entry *tic)
+{
+   if (tic->id >= 0)
+      screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32));
+}
+
+static INLINE void
+nv50_screen_tsc_unlock(struct nv50_screen *screen, struct nv50_tsc_entry *tsc)
+{
+   if (tsc->id >= 0)
+      screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32));
+}
+
+static INLINE void
+nv50_screen_tic_free(struct nv50_screen *screen, struct nv50_tic_entry *tic)
+{
+   if (tic->id >= 0) {
+      screen->tic.entries[tic->id] = NULL;
+      screen->tic.lock[tic->id / 32] &= ~(1 << (tic->id % 32));
+   }
+}
+
+static INLINE void
+nv50_screen_tsc_free(struct nv50_screen *screen, struct nv50_tsc_entry *tsc)
+{
+   if (tsc->id >= 0) {
+      screen->tsc.entries[tsc->id] = NULL;
+      screen->tsc.lock[tsc->id / 32] &= ~(1 << (tsc->id % 32));
+   }
+}
+
 #endif
index 1c1b66deb3cd86d7549ebf12c7ece7804ff42601..e530b3390a9d8ae9ec1731c1b311bbf2ae6e2906 100644 (file)
 
 #include "nv50_context.h"
 
-static void
-nv50_transfer_constbuf(struct nv50_context *nv50,
-                       struct pipe_resource *buf, unsigned size, unsigned cbi)
+void
+nv50_constbufs_validate(struct nv50_context *nv50)
 {
-   struct pipe_context *pipe = &nv50->pipe;
-   struct pipe_transfer *transfer;
    struct nouveau_channel *chan = nv50->screen->base.channel;
-   struct nouveau_grobj *tesla = nv50->screen->tesla;
-   uint32_t *map;
-   unsigned count, start;
+   unsigned s;
 
-   if (buf == NULL)
-      return;
+   for (s = 0; s < 3; ++s) {
+      struct nv50_resource *res;
+      int i;
+      unsigned p, b;
 
-   map = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &transfer);
-   if (!map)
-      return;
+      if (s == PIPE_SHADER_FRAGMENT)
+         p = NV50_3D_SET_PROGRAM_CB_PROGRAM_FRAGMENT;
+      else
+      if (s == PIPE_SHADER_GEOMETRY)
+         p = NV50_3D_SET_PROGRAM_CB_PROGRAM_GEOMETRY;
+      else
+         p = NV50_3D_SET_PROGRAM_CB_PROGRAM_VERTEX;
+
+      while (nv50->constbuf_dirty[s]) {
+         struct nouveau_bo *bo;
+         unsigned start = 0;
+         unsigned words = 0;
+
+         i = ffs(nv50->constbuf_dirty[s]) - 1;
+         nv50->constbuf_dirty[s] &= ~(1 << i);
+
+         res = nv50_resource(nv50->constbuf[s][i]);
+         if (!res) {
+            if (i != 0) {
+               BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1);
+               OUT_RING  (chan, (i << 8) | p | 0);
+            }
+            continue;
+         }
 
-   count = (buf->width0 + 3) / 4;
-   start = 0;
+         if (i == 0) {
+            b = NV50_CB_PVP + s;
 
-   while (count) {
-      unsigned nr = AVAIL_RING(chan);
+            /* always upload GL uniforms through CB DATA */
+            bo = nv50->screen->uniforms;
+            words = res->base.width0 / 4;
+         } else {
+            b = s * 16 + i;
 
-      if (nr < 8) {
-         FIRE_RING(chan);
-         continue;
-      }
-      nr = MIN2(count, nr - 7);
-      nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
-
-      nv50_screen_reloc_constbuf(nv50->screen, cbi);
+            assert(0);
 
-      BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
-      OUT_RING  (chan, (start << 8) | cbi);
-      BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), nr);
-      OUT_RINGp (chan, map, nr);
+            if (!nv50_resource_mapped_by_gpu(&res->base)) {
+               nv50_buffer_migrate(nv50, res, NOUVEAU_BO_VRAM);
 
-      count -= nr;
-      start += nr;
-      map += nr;
-   }
+               BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1);
+               OUT_RING  (chan, 0);
+            }
+            MARK_RING (chan, 6, 2);
+            BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
+            OUT_RESRCh(chan, res, 0, NOUVEAU_BO_RD);
+            OUT_RESRCl(chan, res, 0, NOUVEAU_BO_RD);
+            OUT_RING  (chan, (b << 16) | (res->base.width0 & 0xffff));
+            BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1);
+            OUT_RING  (chan, (b << 12) | (i << 8) | p | 1);
 
-   pipe_buffer_unmap(pipe, transfer);
-}
+            bo = res->bo;
 
-static void
-nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
-{
-   struct nouveau_channel *chan = nv50->screen->base.channel;
-   struct nouveau_grobj *tesla = nv50->screen->tesla;
-   unsigned cbi;
-
-   if (p->immd_size) {
-      uint32_t *data = p->immd;
-      unsigned count = p->immd_size / 4;
-      unsigned start = 0;
+            nv50_bufctx_add_resident(nv50, NV50_BUFCTX_CONSTANT, res,
+                                     res->domain | NOUVEAU_BO_RD);
+         }
 
-      while (count) {
-         unsigned nr = AVAIL_RING(chan);
+         if (words) {
+            MARK_RING(chan, 8, 1);
 
-         if (nr < 8) {
-            FIRE_RING(chan);
-            continue;
+            nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR);
          }
-         nr = MIN2(count, nr - 7);
-         nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
 
-         nv50_screen_reloc_constbuf(nv50->screen, NV50_CB_PMISC);
+         while (words) {
+            unsigned nr = AVAIL_RING(chan);
 
-         BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
-         OUT_RING  (chan, (start << 8) | NV50_CB_PMISC);
-         BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), nr);
-         OUT_RINGp (chan, data, nr);
+            if (nr < 16) {
+               FIRE_RING(chan);
+               nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR);
+               continue;
+            }
+            nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN);
 
-         count -= nr;
-         start += nr;
-         data += nr;
-      }
-   }
+            BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
+            OUT_RING  (chan, (start << 8) | b);
+            BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nr);
+            OUT_RINGp (chan, &res->data[start * 4], nr);
 
-   /* If the state tracker doesn't change the constbuf, and it is first
-    * validated with a program that doesn't use it, this check prevents
-    * it from even being uploaded. */
-   /*
-   if (p->parm_size == 0)
-      return;
-   */
-
-   switch (p->type) {
-   case PIPE_SHADER_VERTEX:
-      cbi = NV50_CB_PVP;
-      break;
-   case PIPE_SHADER_FRAGMENT:
-      cbi = NV50_CB_PFP;
-      break;
-   case PIPE_SHADER_GEOMETRY:
-      cbi = NV50_CB_PGP;
-      break;
-   default:
-      assert(0);
-      return;
+            start += nr;
+            words -= nr;
+         }
+      }
    }
-
-   nv50_transfer_constbuf(nv50, nv50->constbuf[p->type], p->parm_size, cbi);
 }
 
-static void
-nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
+static boolean
+nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
-   struct nouveau_grobj *tesla = nv50->screen->tesla;
-   struct nouveau_grobj *eng2d = nv50->screen->eng2d;
+   struct nouveau_resource *heap;
    int ret;
-   unsigned offset;
-   unsigned size = p->code_size;
-   uint32_t *data = p->code;
-
-   assert(p->translated);
+   unsigned size;
 
-   /* TODO: use a single bo (for each type) for shader code */
-   if (p->bo)
-      return;
-   ret = nouveau_bo_new(chan->device, NOUVEAU_BO_VRAM, 0x100, size, &p->bo);
-   assert(!ret);
-
-   offset = p->code_start = 0;
-
-   BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2);
-   OUT_RING  (chan, NV50_2D_DST_FORMAT_R8_UNORM);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 1);
-   OUT_RING  (chan, 0x40000);
-   BEGIN_RING(chan, eng2d, NV50_2D_DST_WIDTH, 2);
-   OUT_RING  (chan, 0x10000);
-   OUT_RING  (chan, 1);
-
-   while (size) {
-      unsigned nr = size / 4;
-
-      if (AVAIL_RING(chan) < 32)
-         FIRE_RING(chan);
-
-      nr = MIN2(nr, AVAIL_RING(chan) - 18);
-      nr = MIN2(nr, 1792);
-      if (nr < (size / 4))
-         nr &= ~0x3f;
-      assert(!(size & 3));
-
-      BEGIN_RING(chan, eng2d, NV50_2D_DST_ADDRESS_HIGH, 2);
-      OUT_RELOCh(chan, p->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-      OUT_RELOCl(chan, p->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-      BEGIN_RING(chan, eng2d, NV50_2D_SIFC_BITMAP_ENABLE, 2);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, NV50_2D_SIFC_FORMAT_R8_UNORM);
-      BEGIN_RING(chan, eng2d, NV50_2D_SIFC_WIDTH, 10);
-      OUT_RING  (chan, nr * 4);
-      OUT_RING  (chan, 1);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, 1);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, 1);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, 0);
-
-      BEGIN_RING_NI(chan, eng2d, NV50_2D_SIFC_DATA, nr);
-      OUT_RINGp (chan, data, nr);
-
-      data += nr;
-      offset += nr * 4;
-      size -= nr * 4;
-   }
+   if (prog->translated)
+      return TRUE;
 
-   BEGIN_RING(chan, tesla, NV50TCL_CODE_CB_FLUSH, 1);
-   OUT_RING  (chan, 0);
-}
+   prog->translated = nv50_program_translate(prog);
+   if (!prog->translated)
+      return FALSE;
 
-static void
-nv50_vp_update_stateobj(struct nv50_context *nv50, struct nv50_program *p)
-{
-   struct nouveau_grobj *tesla = nv50->screen->tesla;
-   struct nouveau_stateobj *so = so_new(5, 7, 2);
-
-   nv50_program_validate_code(nv50, p);
-
-   so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2);
-   so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
-             NOUVEAU_BO_HIGH, 0, 0);
-   so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
-             NOUVEAU_BO_LOW, 0, 0);
-   so_method(so, tesla, NV50TCL_VP_ATTR_EN_0, 2);
-   so_data  (so, p->vp.attrs[0]);
-   so_data  (so, p->vp.attrs[1]);
-   so_method(so, tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
-   so_data  (so, p->max_out);
-   so_method(so, tesla, NV50TCL_VP_REG_ALLOC_TEMP, 1);
-   so_data  (so, p->max_gpr);
-   so_method(so, tesla, NV50TCL_VP_START_ID, 1);
-   so_data  (so, p->code_start);
-
-   so_ref(so, &p->so);
-   so_ref(NULL, &so);
-}
+   if (prog->type == PIPE_SHADER_FRAGMENT) heap = nv50->screen->fp_code_heap;
+   if (prog->type == PIPE_SHADER_GEOMETRY) heap = nv50->screen->gp_code_heap;
+   else
+      heap = nv50->screen->vp_code_heap;
 
-static void
-nv50_fp_update_stateobj(struct nv50_context *nv50, struct nv50_program *p)
-{
-   struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so = so_new(6, 7, 2);
-
-   nv50_program_validate_code(nv50, p);
-
-   so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2);
-   so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
-             NOUVEAU_BO_HIGH, 0, 0);
-   so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
-             NOUVEAU_BO_LOW, 0, 0);
-   so_method(so, tesla, NV50TCL_FP_REG_ALLOC_TEMP, 1);
-   so_data  (so, p->max_gpr);
-   so_method(so, tesla, NV50TCL_FP_RESULT_COUNT, 1);
-   so_data  (so, p->max_out);
-   so_method(so, tesla, NV50TCL_FP_CONTROL, 1);
-   so_data  (so, p->fp.flags[0]);
-   so_method(so, tesla, NV50TCL_FP_CTRL_UNK196C, 1);
-   so_data  (so, p->fp.flags[1]);
-   so_method(so, tesla, NV50TCL_FP_START_ID, 1);
-   so_data  (so, p->code_start);
-
-   so_ref(so, &p->so);
-   so_ref(NULL, &so);
-}
+   size = align(prog->code_size, 0x100);
 
-static void
-nv50_gp_update_stateobj(struct nv50_context *nv50, struct nv50_program *p)
-{
-   struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so = so_new(6, 7, 2);
-
-   nv50_program_validate_code(nv50, p);
-
-   so_method(so, tesla, NV50TCL_GP_ADDRESS_HIGH, 2);
-   so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
-             NOUVEAU_BO_HIGH, 0, 0);
-   so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
-             NOUVEAU_BO_LOW, 0, 0);
-   so_method(so, tesla, NV50TCL_GP_REG_ALLOC_TEMP, 1);
-   so_data  (so, p->max_gpr);
-   so_method(so, tesla, NV50TCL_GP_REG_ALLOC_RESULT, 1);
-   so_data  (so, p->max_out);
-   so_method(so, tesla, NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE, 1);
-   so_data  (so, p->gp.prim_type);
-   so_method(so, tesla, NV50TCL_GP_VERTEX_OUTPUT_COUNT, 1);
-   so_data  (so, p->gp.vert_count);
-   so_method(so, tesla, NV50TCL_GP_START_ID, 1);
-   so_data  (so, p->code_start);
-
-   so_ref(so, &p->so);
-   so_ref(NULL, &so);
-}
+   ret = nouveau_resource_alloc(heap, size, prog, &prog->res);
+   if (ret)
+      return FALSE;
+   prog->code_base = prog->res->start;
 
-static boolean
-nv50_program_validate(struct nv50_program *p)
-{
-   p->translated = nv50_program_tx(p);
-   assert(p->translated);
-   return p->translated;
-}
+   nv50_sifc_linear_u8(nv50, nv50->screen->code, NOUVEAU_BO_VRAM,
+                       (prog->type << 16) + prog->code_base, prog->code_size,
+                       prog->code);
 
-static INLINE void
-nv50_program_validate_common(struct nv50_context *nv50, struct nv50_program *p)
-{
-   nv50_program_validate_code(nv50, p);
+   BEGIN_RING(nv50->screen->base.channel, RING_3D(CODE_CB_FLUSH), 1);
+   OUT_RING  (nv50->screen->base.channel, 0);
 
-   if (p->uses_lmem)
-      nv50->req_lmem |= 1 << p->type;
-   else
-      nv50->req_lmem &= ~(1 << p->type);
+   return TRUE;
 }
 
-struct nouveau_stateobj *
+void
 nv50_vertprog_validate(struct nv50_context *nv50)
 {
-   struct nv50_program *p = nv50->vertprog;
-   struct nouveau_stateobj *so = NULL;
-
-   if (!p->translated) {
-      if (nv50_program_validate(p))
-         nv50_vp_update_stateobj(nv50, p);
-      else
-         return NULL;
-   }
-
-   if (nv50->dirty & NV50_NEW_VERTPROG_CB)
-      nv50_program_validate_data(nv50, p);
-
-   if (!(nv50->dirty & NV50_NEW_VERTPROG))
-      return NULL;
-
-   nv50_program_validate_common(nv50, p);
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nv50_program *vp = nv50->vertprog;
 
-   so_ref(p->so, &so);
-   return so;
+   if (!nv50_program_validate(nv50, vp))
+         return;
+
+   BEGIN_RING(chan, RING_3D(VP_ATTR_EN(0)), 2);
+   OUT_RING  (chan, vp->vp.attrs[0]);
+   OUT_RING  (chan, vp->vp.attrs[1]);
+   BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_RESULT), 1);
+   OUT_RING  (chan, vp->max_out);
+   BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_TEMP), 1);
+   OUT_RING  (chan, vp->max_gpr);
+   BEGIN_RING(chan, RING_3D(VP_START_ID), 1);
+   OUT_RING  (chan, vp->code_base);
 }
 
-struct nouveau_stateobj *
+void
 nv50_fragprog_validate(struct nv50_context *nv50)
 {
-   struct nv50_program *p = nv50->fragprog;
-   struct nouveau_stateobj *so = NULL;
-
-   if (!p->translated) {
-      if (nv50_program_validate(p))
-         nv50_fp_update_stateobj(nv50, p);
-      else
-         return NULL;
-   }
-
-   if (nv50->dirty & NV50_NEW_FRAGPROG_CB)
-      nv50_program_validate_data(nv50, p);
-
-   if (!(nv50->dirty & NV50_NEW_FRAGPROG))
-      return NULL;
-
-   nv50_program_validate_common(nv50, p);
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nv50_program *fp = nv50->fragprog;
 
-   so_ref(p->so, &so);
-   return so;
+   if (!nv50_program_validate(nv50, fp))
+         return;
+
+   BEGIN_RING(chan, RING_3D(FP_REG_ALLOC_TEMP), 1);
+   OUT_RING  (chan, fp->max_gpr);
+   BEGIN_RING(chan, RING_3D(FP_RESULT_COUNT), 1);
+   OUT_RING  (chan, fp->max_out);
+   BEGIN_RING(chan, RING_3D(FP_CONTROL), 1);
+   OUT_RING  (chan, fp->fp.flags[0]);
+   BEGIN_RING(chan, RING_3D(FP_CTRL_UNK196C), 1);
+   OUT_RING  (chan, fp->fp.flags[1]);
+   BEGIN_RING(chan, RING_3D(FP_START_ID), 1);
+   OUT_RING  (chan, fp->code_base);
 }
 
-struct nouveau_stateobj *
-nv50_geomprog_validate(struct nv50_context *nv50)
+void
+nv50_gmtyprog_validate(struct nv50_context *nv50)
 {
-   struct nv50_program *p = nv50->geomprog;
-   struct nouveau_stateobj *so = NULL;
-
-   /* GP may be NULL, but VP and FP may not */
-   if (!p)
-      return NULL; /* GP is deactivated in linkage validation */
-
-   if (!p->translated) {
-      if (nv50_program_validate(p))
-         nv50_gp_update_stateobj(nv50, p);
-      else
-         return NULL;
-   }
-
-   if (nv50->dirty & NV50_NEW_GEOMPROG_CB)
-      nv50_program_validate_data(nv50, p);
-
-   if (!(nv50->dirty & NV50_NEW_GEOMPROG))
-      return NULL;
-
-   nv50_program_validate_common(nv50, p);
-
-   so_ref(p->so, &so);
-   return so;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nv50_program *gp = nv50->vertprog;
+
+   if (!nv50_program_validate(nv50, gp))
+         return;
+
+   BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_TEMP), 1);
+   OUT_RING  (chan, gp->max_gpr);
+   BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_RESULT), 1);
+   OUT_RING  (chan, gp->max_out);
+   BEGIN_RING(chan, RING_3D(GP_OUTPUT_PRIMITIVE_TYPE), 1);
+   OUT_RING  (chan, gp->gp.prim_type);
+   BEGIN_RING(chan, RING_3D(GP_VERTEX_OUTPUT_COUNT), 1);
+   OUT_RING  (chan, gp->gp.vert_count);
+   BEGIN_RING(chan, RING_3D(GP_START_ID), 1);
+   OUT_RING  (chan, gp->code_base);
 }
 
-/* XXX: this might not work correctly in all cases yet: we assume that
- * an FP generic input that is not written in the VP is gl_PointCoord.
- */
-static uint32_t
+static void
 nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned m)
 {
-   struct nv50_program *vp = nv50->vertprog;
    struct nv50_program *fp = nv50->fragprog;
    unsigned i, c;
 
    memset(pntc, 0, 8 * sizeof(uint32_t));
 
-   if (nv50->geomprog)
-      vp = nv50->geomprog;
-
    for (i = 0; i < fp->in_nr; i++) {
-      unsigned j, n = util_bitcount(fp->in[i].mask);
+      unsigned n = util_bitcount(fp->in[i].mask);
 
       if (fp->in[i].sn != TGSI_SEMANTIC_GENERIC) {
          m += n;
          continue;
       }
-
-      for (j = 0; j < vp->out_nr; ++j)
-         if (vp->out[j].sn == fp->in[i].sn && vp->out[j].si == fp->in[i].si)
-            break;
-
-      if (j < vp->out_nr) {
-         uint32_t en = nv50->rasterizer->pipe.sprite_coord_enable;
-
-         if (!(en & (1 << vp->out[j].si))) {
-            m += n;
-            continue;
-         }
+      if (!(nv50->rast->pipe.sprite_coord_enable & (1 << fp->in[i].si))) {
+         m += n;
+         continue;
       }
 
-      /* this is either PointCoord or replaced by sprite coords */
-      for (c = 0; c < 4; c++) {
-         if (!(fp->in[i].mask & (1 << c)))
-            continue;
-         pntc[m / 8] |= (c + 1) << ((m % 8) * 4);
-         ++m;
+      for (c = 0; c < 4; ++c) {
+         if (fp->in[i].mask & (1 << c)) {
+            pntc[m / 8] |= (c + 1) << ((m % 8) * 4);
+            ++m;
+         }
       }
    }
-   if (nv50->rasterizer->pipe.sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT)
-      return 0;
-   return (1 << 4);
 }
 
 static int
-nv50_vec4_map(uint32_t *map32, int mid, uint32_t lin[4],
+nv50_vec4_map(uint8_t *map, int mid, uint32_t lin[4],
               struct nv50_varying *in, struct nv50_varying *out)
 {
    int c;
    uint8_t mv = out->mask, mf = in->mask, oid = out->hw;
-   uint8_t *map = (uint8_t *)map32;
 
    for (c = 0; c < 4; ++c) {
       if (mf & 1) {
@@ -465,140 +277,120 @@ nv50_vec4_map(uint32_t *map32, int mid, uint32_t lin[4],
    return mid;
 }
 
-struct nouveau_stateobj *
+void
 nv50_fp_linkage_validate(struct nv50_context *nv50)
 {
-   struct nouveau_grobj *tesla = nv50->screen->tesla;
-   struct nv50_program *vp;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nv50_program *vp = nv50->gmtyprog ? nv50->gmtyprog : nv50->vertprog;
    struct nv50_program *fp = nv50->fragprog;
-   struct nouveau_stateobj *so;
    struct nv50_varying dummy;
    int i, n, c, m;
-
-   uint32_t map[16], lin[4], pntc[8];
-
+   uint32_t primid = 0;
+   uint32_t psiz = 0x000;
    uint32_t interp = fp->fp.interp;
    uint32_t colors = fp->fp.colors;
-   uint32_t clip = 0x04;
-   uint32_t psiz = 0x000;
-   uint32_t primid = 0;
-   uint32_t sysval = 0;
+   uint32_t lin[4], pntc[8];
+   uint8_t map[64];
 
-   if (nv50->geomprog) {
-      vp = nv50->geomprog;
-      memset(map, 0x80, sizeof(map));
-   } else {
-      vp = nv50->vertprog;
-      memset(map, 0x40, sizeof(map));
-   }
-   memset(lin, 0, sizeof(lin));
+   memset(lin, 0x00, sizeof(lin));
+
+   /* XXX: in buggy-endian mode, is the first element of map (u32)0x000000xx
+    *  or is it the first byte ?
+    */
+   memset(map, nv50->gmtyprog ? 0x80 : 0x40, sizeof(map));
 
-   dummy.linear = 0;
    dummy.mask = 0xf; /* map all components of HPOS */
+   dummy.linear = 0;
    m = nv50_vec4_map(map, 0, lin, &dummy, &vp->out[0]);
 
-   if (vp->vp.clpd < 0x40) {
-      for (c = 0; c < vp->vp.clpd_nr; ++c) {
-         map[m / 4] |= (vp->vp.clpd + c) << ((m % 4) * 8);
-         ++m;
-      }
-      clip |= vp->vp.clpd_nr << 8;
-   }
+   for (c = 0; c < vp->vp.clpd_nr; ++c)
+      map[m++] |= vp->vp.clpd + c;
 
    colors |= m << 8; /* adjust BFC0 id */
 
-   /* if light_twoside is active, it seems FFC0_ID == BFC0_ID is bad */
-   if (nv50->rasterizer->pipe.light_twoside) {
+   /* if light_twoside is active, FFC0_ID == BFC0_ID is invalid */
+   if (nv50->rast->pipe.light_twoside) {
       for (i = 0; i < 2; ++i)
          m = nv50_vec4_map(map, m, lin,
-                           &fp->in[fp->vp.bfc[i]],
-                           &vp->out[vp->vp.bfc[i]]);
+                           &fp->in[fp->vp.bfc[i]], &vp->out[vp->vp.bfc[i]]);
    }
-
    colors += m - 4; /* adjust FFC0 id */
-   interp |= m << 8; /* set mid where 'normal' FP inputs start */
+   interp |= m << 8; /* set map id where 'normal' FP inputs start */
 
    dummy.mask = 0x0;
-   for (i = 0; i < fp->in_nr; i++) {
+   for (i = 0; i < fp->in_nr; ++i) {
       for (n = 0; n < vp->out_nr; ++n)
          if (vp->out[n].sn == fp->in[i].sn &&
              vp->out[n].si == fp->in[i].si)
             break;
-
       m = nv50_vec4_map(map, m, lin,
                         &fp->in[i], (n < vp->out_nr) ? &vp->out[n] : &dummy);
-       }
+   }
 
    /* PrimitiveID either is replaced by the system value, or
     * written by the geometry shader into an output register
     */
    if (fp->gp.primid < 0x40) {
-      i = (m % 4) * 8;
-      map[m / 4] = (map[m / 4] & ~(0xff << i)) | (vp->gp.primid << i);
-      primid = m++;
+      primid = m;
+      map[m++] = vp->gp.primid;
    }
 
-   if (nv50->rasterizer->pipe.point_size_per_vertex) {
-      i = (m % 4) * 8;
-      map[m / 4] = (map[m / 4] & ~(0xff << i)) | (vp->vp.psiz << i);
-      psiz = (m++ << 4) | 1;
+   if (nv50->rast->pipe.point_size_per_vertex) {
+      psiz = (m << 4) | 1;
+      map[m++] = vp->vp.psiz;
    }
 
-   /* now fill the stateobj (at most 28 so_data)  */
-   so = so_new(10, 54, 0);
-
    n = (m + 3) / 4;
    assert(m <= 64);
-   if (vp->type == PIPE_SHADER_GEOMETRY) {
-      so_method(so, tesla, NV50TCL_GP_RESULT_MAP_SIZE, 1);
-      so_data  (so, m);
-      so_method(so, tesla, NV50TCL_GP_RESULT_MAP(0), n);
-      so_datap (so, map, n);
+
+   if (unlikely(nv50->gmtyprog)) {
+      BEGIN_RING(chan, RING_3D(GP_RESULT_MAP_SIZE), 1);
+      OUT_RING  (chan, m);
+      BEGIN_RING(chan, RING_3D(GP_RESULT_MAP(0)), n);
+      OUT_RINGp (chan, map, n);
    } else {
-      so_method(so, tesla, NV50TCL_VP_GP_BUILTIN_ATTR_EN, 1);
-      so_data  (so, vp->vp.attrs[2]);
+      BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1);
+      OUT_RING  (chan, vp->vp.attrs[2]);
 
-      so_method(so, tesla, NV50TCL_MAP_SEMANTIC_4, 1);
-      so_data  (so, primid);
+      BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_4), 1);
+      OUT_RING  (chan, primid);
 
-      so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1);
-      so_data  (so, m);
-      so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), n);
-      so_datap (so, map, n);
+      BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1);
+      OUT_RING  (chan, m);
+      BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n);
+      OUT_RINGp (chan, map, n);
    }
 
-   so_method(so, tesla, NV50TCL_MAP_SEMANTIC_0, 4);
-   so_data  (so, colors);
-   so_data  (so, clip);
-   so_data  (so, sysval);
-   so_data  (so, psiz);
+   BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 4);
+   OUT_RING  (chan, colors);
+   OUT_RING  (chan, (vp->vp.clpd_nr << 8) | 4);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, psiz);
 
-   so_method(so, tesla, NV50TCL_FP_INTERPOLANT_CTRL, 1);
-   so_data  (so, interp);
+   BEGIN_RING(chan, RING_3D(FP_INTERPOLANT_CTRL), 1);
+   OUT_RING  (chan, interp);
 
-   so_method(so, tesla, NV50TCL_NOPERSPECTIVE_BITMAP(0), 4);
-   so_datap (so, lin, 4);
+   BEGIN_RING(chan, RING_3D(NOPERSPECTIVE_BITMAP(0)), 4);
+   OUT_RINGp (chan, lin, 4);
 
-   if (nv50->rasterizer->pipe.point_quad_rasterization) {
-      so_method(so, tesla, NV50TCL_POINT_SPRITE_CTRL, 1);
-      so_data  (so,
-                nv50_pntc_replace(nv50, pntc, (interp >> 8) & 0xff));
+   if (nv50->rast->pipe.point_quad_rasterization) {
+      nv50_pntc_replace(nv50, pntc, (interp >> 8) & 0xff);
 
-      so_method(so, tesla, NV50TCL_POINT_COORD_REPLACE_MAP(0), 8);
-      so_datap (so, pntc, 8);
+      BEGIN_RING(chan, RING_3D(POINT_SPRITE_CTRL), 1);
+      OUT_RING  (chan, (nv50->rast->pipe.sprite_coord_mode ==
+                        PIPE_SPRITE_COORD_LOWER_LEFT) ? 0 : 0x10);
+      BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8);
+      OUT_RINGp (chan, pntc, 8);
    }
 
-   so_method(so, tesla, NV50TCL_GP_ENABLE, 1);
-   so_data  (so, (vp->type == PIPE_SHADER_GEOMETRY) ? 1 : 0);
-
-   return so;
+   BEGIN_RING(chan, RING_3D(GP_ENABLE), 1);
+   OUT_RING  (chan, nv50->gmtyprog ? 1 : 0);
 }
 
 static int
-nv50_vp_gp_mapping(uint32_t *map32, int m,
+nv50_vp_gp_mapping(uint8_t *map, int m,
                    struct nv50_program *vp, struct nv50_program *gp)
 {
-   uint8_t *map = (uint8_t *)map32;
    int i, j, c;
 
    for (i = 0; i < gp->in_nr; ++i) {
@@ -625,34 +417,29 @@ nv50_vp_gp_mapping(uint32_t *map32, int m,
    return m;
 }
 
-struct nouveau_stateobj *
+void
 nv50_gp_linkage_validate(struct nv50_context *nv50)
 {
-   struct nouveau_grobj *tesla = nv50->screen->tesla;
-   struct nouveau_stateobj *so;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
    struct nv50_program *vp = nv50->vertprog;
-   struct nv50_program *gp = nv50->geomprog;
-   uint32_t map[16];
+   struct nv50_program *gp = nv50->gmtyprog;
    int m = 0;
+   int n;
+   uint8_t map[64];
 
    if (!gp)
-      return NULL;
+      return;
    memset(map, 0, sizeof(map));
 
    m = nv50_vp_gp_mapping(map, m, vp, gp);
 
-   so = so_new(3, 24 - 3, 0);
-
-   so_method(so, tesla, NV50TCL_VP_GP_BUILTIN_ATTR_EN, 1);
-   so_data  (so, vp->vp.attrs[2] | gp->vp.attrs[2]);
-
-   assert(m <= 32);
-   so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1);
-   so_data  (so, m);
+   n = (m + 3) / 4;
 
-   m = (m + 3) / 4;
-   so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), m);
-   so_datap (so, map, m);
+   BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1);
+   OUT_RING  (chan, vp->vp.attrs[2] | gp->vp.attrs[2]);
 
-   return so;
+   BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1);
+   OUT_RING  (chan, m);
+   BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n);
+   OUT_RINGp (chan, map, n);
 }
index ba2c3e8c2815e38bc0204eaa6b9aa53e09f001b9..5e1fff46e4178748d37a125909f3e6a5ed39460c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Ben Skeggs
+ * Copyright 2010 Christoph Bumiller
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * SOFTWARE.
  */
 
-#include "pipe/p_state.h"
 #include "pipe/p_defines.h"
 #include "util/u_inlines.h"
 #include "util/u_transfer.h"
 
 #include "tgsi/tgsi_parse.h"
 
+#include "nv50_stateobj.h"
 #include "nv50_context.h"
-#include "nv50_texture.h"
 
-#include "nouveau/nouveau_stateobj.h"
+#include "nv50_3d.xml.h"
+#include "nv50_texture.xml.h"
+
+#include "nouveau/nouveau_gldefs.h"
 
 static INLINE uint32_t
 nv50_colormask(unsigned mask)
 {
-       uint32_t cmask = 0;
+   uint32_t ret = 0;
 
-       if (mask & PIPE_MASK_R)
-               cmask |= 0x0001;
-       if (mask & PIPE_MASK_G)
-               cmask |= 0x0010;
-       if (mask & PIPE_MASK_B)
-               cmask |= 0x0100;
-       if (mask & PIPE_MASK_A)
-               cmask |= 0x1000;
+   if (mask & PIPE_MASK_R)
+      ret |= 0x0001;
+   if (mask & PIPE_MASK_G)
+      ret |= 0x0010;
+   if (mask & PIPE_MASK_B)
+      ret |= 0x0100;
+   if (mask & PIPE_MASK_A)
+      ret |= 0x1000;
 
-       return cmask;
+   return ret;
 }
 
+#define NV50_BLEND_FACTOR_CASE(a, b) \
+   case PIPE_BLENDFACTOR_##a: return NV50_3D_BLEND_FACTOR_##b
+
 static INLINE uint32_t
-nv50_blend_func(unsigned factor)
-{
-       switch (factor) {
-       case PIPE_BLENDFACTOR_ZERO:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ZERO;
-       case PIPE_BLENDFACTOR_ONE:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ONE;
-       case PIPE_BLENDFACTOR_SRC_COLOR:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_SRC_COLOR;
-       case PIPE_BLENDFACTOR_INV_SRC_COLOR:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_COLOR;
-       case PIPE_BLENDFACTOR_SRC_ALPHA:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA;
-       case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_ALPHA;
-       case PIPE_BLENDFACTOR_DST_ALPHA:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_DST_ALPHA;
-       case PIPE_BLENDFACTOR_INV_DST_ALPHA:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_ALPHA;
-       case PIPE_BLENDFACTOR_DST_COLOR:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_DST_COLOR;
-       case PIPE_BLENDFACTOR_INV_DST_COLOR:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_COLOR;
-       case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA_SATURATE;
-       case PIPE_BLENDFACTOR_CONST_COLOR:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_COLOR;
-       case PIPE_BLENDFACTOR_INV_CONST_COLOR:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_COLOR;
-       case PIPE_BLENDFACTOR_CONST_ALPHA:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_ALPHA;
-       case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_ALPHA;
-       case PIPE_BLENDFACTOR_SRC1_COLOR:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_SRC1_COLOR;
-       case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC1_COLOR;
-       case PIPE_BLENDFACTOR_SRC1_ALPHA:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_SRC1_ALPHA;
-       case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC1_ALPHA;
-       default:
-               return NV50TCL_BLEND_FUNC_SRC_RGB_ZERO;
-       }
+nv50_blend_fac(unsigned factor)
+{
+   switch (factor) {
+   NV50_BLEND_FACTOR_CASE(ONE, ONE);
+   NV50_BLEND_FACTOR_CASE(SRC_COLOR, SRC_COLOR);
+   NV50_BLEND_FACTOR_CASE(SRC_ALPHA, SRC_ALPHA);
+   NV50_BLEND_FACTOR_CASE(DST_ALPHA, DST_ALPHA);
+   NV50_BLEND_FACTOR_CASE(DST_COLOR, DST_COLOR);
+   NV50_BLEND_FACTOR_CASE(SRC_ALPHA_SATURATE, SRC_ALPHA_SATURATE);
+   NV50_BLEND_FACTOR_CASE(CONST_COLOR, CONSTANT_COLOR);
+   NV50_BLEND_FACTOR_CASE(CONST_ALPHA, CONSTANT_ALPHA);
+   NV50_BLEND_FACTOR_CASE(SRC1_COLOR, SRC1_COLOR);
+   NV50_BLEND_FACTOR_CASE(SRC1_ALPHA, SRC1_ALPHA);
+   NV50_BLEND_FACTOR_CASE(ZERO, ZERO);
+   NV50_BLEND_FACTOR_CASE(INV_SRC_COLOR, ONE_MINUS_SRC_COLOR);
+   NV50_BLEND_FACTOR_CASE(INV_SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
+   NV50_BLEND_FACTOR_CASE(INV_DST_ALPHA, ONE_MINUS_DST_ALPHA);
+   NV50_BLEND_FACTOR_CASE(INV_DST_COLOR, ONE_MINUS_DST_COLOR);
+   NV50_BLEND_FACTOR_CASE(INV_CONST_COLOR, ONE_MINUS_CONSTANT_COLOR);
+   NV50_BLEND_FACTOR_CASE(INV_CONST_ALPHA, ONE_MINUS_CONSTANT_ALPHA);
+   NV50_BLEND_FACTOR_CASE(INV_SRC1_COLOR, ONE_MINUS_SRC1_COLOR);
+   NV50_BLEND_FACTOR_CASE(INV_SRC1_ALPHA, ONE_MINUS_SRC1_ALPHA);
+   default:
+      return NV50_3D_BLEND_FACTOR_ZERO;
+   }
 }
 
 static void *
 nv50_blend_state_create(struct pipe_context *pipe,
-                       const struct pipe_blend_state *cso)
-{
-       struct nouveau_stateobj *so = so_new(5, 24, 0);
-       struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
-       struct nv50_blend_stateobj *bso = CALLOC_STRUCT(nv50_blend_stateobj);
-       unsigned i, blend_enabled = 0;
-
-       /*XXX ignored:
-        *      - dither
-        */
-
-       so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8);
-       if (cso->independent_blend_enable) {
-               for (i = 0; i < 8; ++i) {
-                       so_data(so, cso->rt[i].blend_enable);
-                       if (cso->rt[i].blend_enable)
-                               blend_enabled = 1;
-               }
-       } else
-       if (cso->rt[0].blend_enable) {
-               blend_enabled = 1;
-               for (i = 0; i < 8; i++)
-                       so_data(so, 1);
-       } else {
-               for (i = 0; i < 8; i++)
-                       so_data(so, 0);
-       }
-       if (blend_enabled) {
-               so_method(so, tesla, NV50TCL_BLEND_EQUATION_RGB, 5);
-               so_data  (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
-               so_data  (so, nv50_blend_func(cso->rt[0].rgb_src_factor));
-               so_data  (so, nv50_blend_func(cso->rt[0].rgb_dst_factor));
-               so_data  (so, nvgl_blend_eqn(cso->rt[0].alpha_func));
-               so_data  (so, nv50_blend_func(cso->rt[0].alpha_src_factor));
-               so_method(so, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1);
-               so_data  (so, nv50_blend_func(cso->rt[0].alpha_dst_factor));
-       }
-
-       if (cso->logicop_enable == 0 ) {
-               so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 1);
-               so_data  (so, 0);
-       } else {
-               so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 2);
-               so_data  (so, 1);
-               so_data  (so, nvgl_logicop_func(cso->logicop_func));
-       }
-
-       so_method(so, tesla, NV50TCL_COLOR_MASK(0), 8);
-       if (cso->independent_blend_enable)
-               for (i = 0; i < 8; ++i)
-                       so_data(so, nv50_colormask(cso->rt[i].colormask));
-       else {
-               uint32_t cmask = nv50_colormask(cso->rt[0].colormask);
-               for (i = 0; i < 8; i++)
-                       so_data(so, cmask);
-       }
-
-       bso->pipe = *cso;
-       so_ref(so, &bso->so);
-       so_ref(NULL, &so);
-       return (void *)bso;
+                        const struct pipe_blend_state *cso)
+{
+   struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj);
+   int i;
+   boolean blend_enabled = cso->rt[0].blend_enable;
+
+   so->pipe = *cso;
+
+   SB_BEGIN_3D(so, BLEND_ENABLE(0), 8);
+   if (cso->independent_blend_enable) {
+      for (i = 0; i < 8; ++i) {
+         SB_DATA(so, cso->rt[i].blend_enable);
+         if (cso->rt[i].blend_enable)
+            blend_enabled = TRUE;
+      }
+   } else {
+      for (i = 0; i < 8; ++i)
+         SB_DATA(so, blend_enabled);
+   }
+
+   if (blend_enabled) {
+      SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);
+      SB_DATA    (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
+      SB_DATA    (so, nv50_blend_fac(cso->rt[0].rgb_src_factor));
+      SB_DATA    (so, nv50_blend_fac(cso->rt[0].rgb_dst_factor));
+      SB_DATA    (so, nvgl_blend_eqn(cso->rt[0].alpha_func));
+      SB_DATA    (so, nv50_blend_fac(cso->rt[0].alpha_src_factor));
+      SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1);
+      SB_DATA    (so, nv50_blend_fac(cso->rt[0].alpha_dst_factor));
+   }
+
+   if (cso->logicop_enable) {
+      SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2);
+      SB_DATA    (so, 1);
+      SB_DATA    (so, nvgl_logicop_func(cso->logicop_func));
+   } else {
+      SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 1);
+      SB_DATA    (so, 0);
+   }
+
+   SB_BEGIN_3D(so, COLOR_MASK(0), 8);
+   if (cso->independent_blend_enable) {
+      for (i = 0; i < 8; ++i)
+         SB_DATA(so, nv50_colormask(cso->rt[i].colormask));
+   } else {
+      uint32_t cmask = nv50_colormask(cso->rt[0].colormask);
+      for (i = 0; i < 8; ++i)
+         SB_DATA(so, cmask);
+   }
+
+   assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
+   return so;
 }
 
 static void
 nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50->blend = hwcso;
-       nv50->dirty |= NV50_NEW_BLEND;
+   nv50->blend = hwcso;
+   nv50->dirty |= NV50_NEW_BLEND;
 }
 
 static void
 nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso)
 {
-       struct nv50_blend_stateobj *bso = hwcso;
-
-       so_ref(NULL, &bso->so);
-       FREE(bso);
+   FREE(hwcso);
 }
 
-static INLINE unsigned
-wrap_mode(unsigned wrap)
-{
-       switch (wrap) {
-       case PIPE_TEX_WRAP_REPEAT:
-               return NV50TSC_1_0_WRAPS_REPEAT;
-       case PIPE_TEX_WRAP_MIRROR_REPEAT:
-               return NV50TSC_1_0_WRAPS_MIRROR_REPEAT;
-       case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-               return NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE;
-       case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-               return NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER;
-       case PIPE_TEX_WRAP_CLAMP:
-               return NV50TSC_1_0_WRAPS_CLAMP;
-       case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
-               return NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_EDGE;
-       case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
-               return NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_BORDER;
-       case PIPE_TEX_WRAP_MIRROR_CLAMP:
-               return NV50TSC_1_0_WRAPS_MIRROR_CLAMP;
-       default:
-               NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
-               return NV50TSC_1_0_WRAPS_REPEAT;
-       }
-}
 static void *
-nv50_sampler_state_create(struct pipe_context *pipe,
-                         const struct pipe_sampler_state *cso)
-{
-       struct nv50_sampler_stateobj *sso = CALLOC(1, sizeof(*sso));
-       unsigned *tsc = sso->tsc;
-       float limit;
-
-       tsc[0] = (0x00026000 |
-                 (wrap_mode(cso->wrap_s) << 0) |
-                 (wrap_mode(cso->wrap_t) << 3) |
-                 (wrap_mode(cso->wrap_r) << 6));
-
-       switch (cso->mag_img_filter) {
-       case PIPE_TEX_FILTER_LINEAR:
-               tsc[1] |= NV50TSC_1_1_MAGF_LINEAR;
-               break;
-       case PIPE_TEX_FILTER_NEAREST:
-       default:
-               tsc[1] |= NV50TSC_1_1_MAGF_NEAREST;
-               break;
-       }
-
-       switch (cso->min_img_filter) {
-       case PIPE_TEX_FILTER_LINEAR:
-               tsc[1] |= NV50TSC_1_1_MINF_LINEAR;
-               break;
-       case PIPE_TEX_FILTER_NEAREST:
-       default:
-               tsc[1] |= NV50TSC_1_1_MINF_NEAREST;
-               break;
-       }
-
-       switch (cso->min_mip_filter) {
-       case PIPE_TEX_MIPFILTER_LINEAR:
-               tsc[1] |= NV50TSC_1_1_MIPF_LINEAR;
-               break;
-       case PIPE_TEX_MIPFILTER_NEAREST:
-               tsc[1] |= NV50TSC_1_1_MIPF_NEAREST;
-               break;
-       case PIPE_TEX_MIPFILTER_NONE:
-       default:
-               tsc[1] |= NV50TSC_1_1_MIPF_NONE;
-               break;
-       }
-
-       if (cso->max_anisotropy >= 16)
-               tsc[0] |= (7 << 20);
-       else
-       if (cso->max_anisotropy >= 12)
-               tsc[0] |= (6 << 20);
-       else {
-               tsc[0] |= (cso->max_anisotropy >> 1) << 20;
-
-               if (cso->max_anisotropy >= 4)
-                       tsc[1] |= NV50TSC_1_1_UNKN_ANISO_35;
-               else
-               if (cso->max_anisotropy >= 2)
-                       tsc[1] |= NV50TSC_1_1_UNKN_ANISO_15;
-       }
-
-       if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
-               /* XXX: must be deactivated for non-shadow textures */
-               tsc[0] |= (1 << 9);
-               tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10;
-       }
-
-       limit = CLAMP(cso->lod_bias, -16.0, 15.0);
-       tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 12;
-
-       tsc[2] |= ((int)CLAMP(cso->max_lod, 0.0, 15.0) << 20) |
-                 ((int)CLAMP(cso->min_lod, 0.0, 15.0) << 8);
-
-       tsc[4] = fui(cso->border_color[0]);
-       tsc[5] = fui(cso->border_color[1]);
-       tsc[6] = fui(cso->border_color[2]);
-       tsc[7] = fui(cso->border_color[3]);
-
-       sso->normalized = cso->normalized_coords;
-       return (void *)sso;
-}
-
-/* type == 0 for VPs, 1 for GPs, 2 for FPs, which is how the
- * relevant tesla methods are indexed (NV50TCL_BIND_TSC etc.)
- */
-static INLINE void
-nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type,
-                       unsigned nr, void **sampler)
+nv50_rasterizer_state_create(struct pipe_context *pipe,
+                             const struct pipe_rasterizer_state *cso)
+{
+   struct nv50_rasterizer_stateobj *so;
+
+   so = CALLOC_STRUCT(nv50_rasterizer_stateobj);
+   if (!so)
+      return NULL;
+   so->pipe = *cso;
+
+#ifndef NV50_SCISSORS_CLIPPING
+   SB_BEGIN_3D(so, SCISSOR_ENABLE(0), 1);
+   SB_DATA    (so, cso->scissor);
+#endif
+    
+   SB_BEGIN_3D(so, SHADE_MODEL, 1);
+   SB_DATA    (so, cso->flatshade ? NV50_3D_SHADE_MODEL_FLAT :
+                                    NV50_3D_SHADE_MODEL_SMOOTH);
+   SB_BEGIN_3D(so, PROVOKING_VERTEX_LAST, 1);
+   SB_DATA    (so, !cso->flatshade_first);
+   SB_BEGIN_3D(so, VERTEX_TWO_SIDE_ENABLE, 1);
+   SB_DATA    (so, cso->light_twoside);
+
+   SB_BEGIN_3D(so, LINE_WIDTH, 1);
+   SB_DATA    (so, fui(cso->line_width));
+   SB_BEGIN_3D(so, LINE_SMOOTH_ENABLE, 1);
+   SB_DATA    (so, cso->line_smooth);
+
+   SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1);
+   if (cso->line_stipple_enable) {
+      SB_DATA    (so, 1);
+      SB_BEGIN_3D(so, LINE_STIPPLE, 1);
+      SB_DATA    (so, (cso->line_stipple_pattern << 8) |
+                  cso->line_stipple_factor);
+   } else {
+      SB_DATA    (so, 0);
+   }
+
+   if (!cso->point_size_per_vertex) {
+      SB_BEGIN_3D(so, POINT_SIZE, 1);
+      SB_DATA    (so, fui(cso->point_size));
+   }
+   SB_BEGIN_3D(so, POINT_SPRITE_ENABLE, 1);
+   SB_DATA    (so, cso->point_quad_rasterization);
+   SB_BEGIN_3D(so, POINT_SMOOTH_ENABLE, 1);
+   SB_DATA    (so, cso->point_smooth);
+
+   SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 3);
+   SB_DATA    (so, nvgl_polygon_mode(cso->fill_front));
+   SB_DATA    (so, nvgl_polygon_mode(cso->fill_back));
+   SB_DATA    (so, cso->poly_smooth);
+
+   SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3);
+   SB_DATA    (so, cso->cull_face != PIPE_FACE_NONE);
+   SB_DATA    (so, cso->front_ccw ? NV50_3D_FRONT_FACE_CCW :
+                                    NV50_3D_FRONT_FACE_CW);
+   switch (cso->cull_face) {
+   case PIPE_FACE_FRONT_AND_BACK:
+      SB_DATA(so, NV50_3D_CULL_FACE_FRONT_AND_BACK);
+      break;
+   case PIPE_FACE_FRONT:
+      SB_DATA(so, NV50_3D_CULL_FACE_FRONT);
+      break;
+   case PIPE_FACE_BACK:
+   default:
+     SB_DATA(so, NV50_3D_CULL_FACE_BACK);
+     break;
+   }
+
+   SB_BEGIN_3D(so, POLYGON_STIPPLE_ENABLE, 1);
+   SB_DATA    (so, cso->poly_stipple_enable);
+   SB_BEGIN_3D(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_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1);
+      SB_DATA    (so, fui(cso->offset_scale));
+      SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);
+      SB_DATA    (so, fui(cso->offset_units)); /* XXX: multiply by 2 ? */
+   }
+
+   assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
+   return (void *)so;
+}
+
+static void
+nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       memcpy(nv50->sampler[type], sampler, nr * sizeof(void *));
+   nv50->rast = hwcso;
+   nv50->dirty |= NV50_NEW_RASTERIZER;
+}
 
-       nv50->sampler_nr[type] = nr;
-       nv50->dirty |= NV50_NEW_SAMPLER;
+static void
+nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+   FREE(hwcso);
+}
+
+static void *
+nv50_zsa_state_create(struct pipe_context *pipe,
+                      const struct pipe_depth_stencil_alpha_state *cso)
+{
+   struct nv50_zsa_stateobj *so = CALLOC_STRUCT(nv50_zsa_stateobj);
+
+   so->pipe = *cso;
+
+   SB_BEGIN_3D(so, DEPTH_WRITE_ENABLE, 1);
+   SB_DATA    (so, cso->depth.writemask);
+   SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1);
+   if (cso->depth.enabled) {
+      SB_DATA    (so, 1);
+      SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);
+      SB_DATA    (so, nvgl_comparison_op(cso->depth.func));
+   } else {
+      SB_DATA    (so, 0);
+   }
+
+   if (cso->stencil[0].enabled) {
+      SB_BEGIN_3D(so, STENCIL_ENABLE, 5);
+      SB_DATA    (so, 1);
+      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));
+      SB_DATA    (so, nvgl_comparison_op(cso->stencil[0].func));
+      SB_BEGIN_3D(so, STENCIL_FRONT_MASK, 2);
+      SB_DATA    (so, cso->stencil[0].writemask);
+      SB_DATA    (so, cso->stencil[0].valuemask);
+   } else {
+      SB_BEGIN_3D(so, STENCIL_ENABLE, 1);
+      SB_DATA    (so, 0);
+   }
+
+   if (cso->stencil[1].enabled) {
+      assert(cso->stencil[0].enabled);
+      SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5);
+      SB_DATA    (so, 1);
+      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));
+      SB_DATA    (so, nvgl_comparison_op(cso->stencil[1].func));
+      SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2);
+      SB_DATA    (so, cso->stencil[1].writemask);
+      SB_DATA    (so, cso->stencil[1].valuemask);
+   } else {
+      SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 1);
+      SB_DATA    (so, 0);
+   }
+    
+   SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1);
+   if (cso->alpha.enabled) {
+      SB_DATA    (so, 1);
+      SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);
+      SB_DATA    (so, fui(cso->alpha.ref_value));
+      SB_DATA    (so, nvgl_comparison_op(cso->alpha.func));
+   } else {
+      SB_DATA    (so, 0);
+   }
+
+   assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
+   return (void *)so;
 }
 
 static void
-nv50_vp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s)
+nv50_zsa_state_bind(struct pipe_context *pipe, void *hwcso)
 {
-       nv50_sampler_state_bind(pipe, 0, nr, s);
+   struct nv50_context *nv50 = nv50_context(pipe);
+
+   nv50->zsa = hwcso;
+   nv50->dirty |= NV50_NEW_ZSA;
 }
 
 static void
-nv50_fp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s)
+nv50_zsa_state_delete(struct pipe_context *pipe, void *hwcso)
 {
-       nv50_sampler_state_bind(pipe, 2, nr, s);
+   FREE(hwcso);
+}
+
+/* ====================== SAMPLERS AND TEXTURES ================================
+ */
+
+#define NV50_TSC_WRAP_CASE(n) \
+    case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n
+
+static INLINE unsigned
+nv50_tsc_wrap_mode(unsigned wrap)
+{
+   switch (wrap) {
+   NV50_TSC_WRAP_CASE(REPEAT);
+   NV50_TSC_WRAP_CASE(MIRROR_REPEAT);
+   NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE);
+   NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER);
+   NV50_TSC_WRAP_CASE(CLAMP);
+   NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE);
+   NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER);
+   NV50_TSC_WRAP_CASE(MIRROR_CLAMP);
+   default:
+       NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
+       return NV50_TSC_WRAP_REPEAT;
+   }
+}
+
+static void *
+nv50_sampler_state_create(struct pipe_context *pipe,
+                          const struct pipe_sampler_state *cso)
+{
+   struct nv50_tsc_entry *so = CALLOC_STRUCT(nv50_tsc_entry);
+   float f[2];
+
+   so->id = -1;
+
+   so->tsc[0] = (0x00026000 |
+                 (nv50_tsc_wrap_mode(cso->wrap_s) << 0) |
+                 (nv50_tsc_wrap_mode(cso->wrap_t) << 3) |
+                 (nv50_tsc_wrap_mode(cso->wrap_r) << 6));
+
+   switch (cso->mag_img_filter) {
+   case PIPE_TEX_FILTER_LINEAR:
+      so->tsc[1] |= NV50_TSC_1_MAGF_LINEAR;
+      break;
+   case PIPE_TEX_FILTER_NEAREST:
+   default:
+      so->tsc[1] |= NV50_TSC_1_MAGF_NEAREST;
+      break;
+   }
+
+   switch (cso->min_img_filter) {
+   case PIPE_TEX_FILTER_LINEAR:
+      so->tsc[1] |= NV50_TSC_1_MINF_LINEAR;
+      break;
+   case PIPE_TEX_FILTER_NEAREST:
+   default:
+      so->tsc[1] |= NV50_TSC_1_MINF_NEAREST;
+      break;
+   }
+
+   switch (cso->min_mip_filter) {
+   case PIPE_TEX_MIPFILTER_LINEAR:
+      so->tsc[1] |= NV50_TSC_1_MIPF_LINEAR;
+      break;
+   case PIPE_TEX_MIPFILTER_NEAREST:
+      so->tsc[1] |= NV50_TSC_1_MIPF_NEAREST;
+      break;
+   case PIPE_TEX_MIPFILTER_NONE:
+   default:
+      so->tsc[1] |= NV50_TSC_1_MIPF_NONE;
+      break;
+   }
+
+   if (cso->max_anisotropy >= 16)
+      so->tsc[0] |= (7 << 20);
+   else
+   if (cso->max_anisotropy >= 12)
+      so->tsc[0] |= (6 << 20);
+   else {
+      so->tsc[0] |= (cso->max_anisotropy >> 1) << 20;
+
+      if (cso->max_anisotropy >= 4)
+         so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_35;
+      else
+      if (cso->max_anisotropy >= 2)
+         so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_15;
+   }
+
+   if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+      /* NOTE: must be deactivated for non-shadow textures */
+      so->tsc[0] |= (1 << 9);
+      so->tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10;
+   }
+
+   f[0] = CLAMP(cso->lod_bias, -16.0f, 15.0f);
+   so->tsc[1] |= ((int)(f[0] * 256.0f) & 0x1fff) << 12;
+
+   f[0] = CLAMP(cso->min_lod, 0.0f, 15.0f);
+   f[1] = CLAMP(cso->max_lod, 0.0f, 15.0f);
+   so->tsc[2] |=
+      (((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff);
+
+   so->tsc[4] = fui(cso->border_color[0]);
+   so->tsc[5] = fui(cso->border_color[1]);
+   so->tsc[6] = fui(cso->border_color[2]);
+   so->tsc[7] = fui(cso->border_color[3]);
+
+   return (void *)so;
 }
 
 static void
 nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
 {
-       FREE(hwcso);
+   unsigned s, i;
+
+   for (s = 0; s < 5; ++s)
+      for (i = 0; i < nv50_context(pipe)->num_samplers[s]; ++i)
+         if (nv50_context(pipe)->samplers[s][i] == hwcso)
+            nv50_context(pipe)->samplers[s][i] = NULL;
+
+   nv50_screen_tsc_free(nv50_context(pipe)->screen, nv50_tsc_entry(hwcso));
+
+   FREE(hwcso);
 }
 
 static INLINE void
-nv50_set_sampler_views(struct pipe_context *pipe, unsigned p,
-                      unsigned nr,
-                      struct pipe_sampler_view **views)
+nv50_stage_sampler_states_bind(struct nv50_context *nv50, int s,
+                               unsigned nr, void **hwcso)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       unsigned i;
+   unsigned i;
+
+   for (i = 0; i < nr; ++i) {
+      struct nv50_tsc_entry *old = nv50->samplers[s][i];
 
-       for (i = 0; i < nr; i++)
-               pipe_sampler_view_reference(&nv50->sampler_views[p][i],
-                                           views[i]);
+      nv50->samplers[s][i] = nv50_tsc_entry(hwcso[i]);
+      if (old)
+         nv50_screen_tsc_unlock(nv50->screen, old);
+   }
+   for (; i < nv50->num_samplers[s]; ++i)
+      if (nv50->samplers[s][i])
+         nv50_screen_tsc_unlock(nv50->screen, nv50->samplers[s][i]);
 
-       for (i = nr; i < nv50->sampler_view_nr[p]; i++)
-               pipe_sampler_view_reference(&nv50->sampler_views[p][i], NULL);
+   nv50->num_samplers[s] = nr;
 
-       nv50->sampler_view_nr[p] = nr;
-       nv50->dirty |= NV50_NEW_TEXTURE;
+   nv50->dirty |= NV50_NEW_SAMPLERS;
 }
 
 static void
-nv50_set_vp_sampler_views(struct pipe_context *pipe,
-                         unsigned nr,
-                         struct pipe_sampler_view **views)
+nv50_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
 {
-       nv50_set_sampler_views(pipe, 0, nr, views);
+   nv50_stage_sampler_states_bind(nv50_context(pipe), 0, nr, s);
 }
 
 static void
-nv50_set_fp_sampler_views(struct pipe_context *pipe,
-                         unsigned nr,
-                         struct pipe_sampler_view **views)
+nv50_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
 {
-       nv50_set_sampler_views(pipe, 2, nr, views);
+   nv50_stage_sampler_states_bind(nv50_context(pipe), 2, nr, s);
 }
 
 static void
-nv50_sampler_view_destroy(struct pipe_context *pipe,
-                         struct pipe_sampler_view *view)
+nv50_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
 {
-       pipe_resource_reference(&view->texture, NULL);
-       FREE(nv50_sampler_view(view));
+   nv50_stage_sampler_states_bind(nv50_context(pipe), 1, nr, s);
 }
 
-static struct pipe_sampler_view *
-nv50_create_sampler_view(struct pipe_context *pipe,
-                        struct pipe_resource *texture,
-                        const struct pipe_sampler_view *templ)
+/* NOTE: only called when not referenced anywhere, won't be bound */
+static void
+nv50_sampler_view_destroy(struct pipe_context *pipe,
+                          struct pipe_sampler_view *view)
 {
-       struct nv50_sampler_view *view = CALLOC_STRUCT(nv50_sampler_view);
+   pipe_resource_reference(&view->texture, NULL);
 
-       view->pipe = *templ;
-       view->pipe.reference.count = 1;
-       view->pipe.texture = NULL;
-       pipe_resource_reference(&view->pipe.texture, texture);
-       view->pipe.context = pipe;
+   nv50_screen_tic_free(nv50_context(pipe)->screen, nv50_tic_entry(view));
 
-       if (!nv50_tex_construct(view)) {
-               nv50_sampler_view_destroy(pipe, &view->pipe);
-               return NULL;
-       }
-       return &view->pipe;
+   FREE(nv50_tic_entry(view));
 }
 
+static INLINE void
+nv50_stage_set_sampler_views(struct nv50_context *nv50, int s,
+                             unsigned nr,
+                             struct pipe_sampler_view **views)
+{
+   unsigned i;
+
+   for (i = 0; i < nr; ++i) {
+      struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
+      if (old)
+         nv50_screen_tic_unlock(nv50->screen, old);
 
-static void *
-nv50_rasterizer_state_create(struct pipe_context *pipe,
-                            const struct pipe_rasterizer_state *cso)
-{
-       struct nouveau_stateobj *so = so_new(16, 22, 0);
-       struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
-       struct nv50_rasterizer_stateobj *rso =
-               CALLOC_STRUCT(nv50_rasterizer_stateobj);
-
-       /*XXX: ignored
-        *      - light_twoside
-        *      - point_smooth
-        *      - multisample
-        *      - point_sprite / sprite_coord_mode
-        */
-
-       so_method(so, tesla, NV50TCL_SCISSOR_ENABLE(0), 1);
-       so_data  (so, cso->scissor);
-
-       so_method(so, tesla, NV50TCL_SHADE_MODEL, 1);
-       so_data  (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT :
-                                      NV50TCL_SHADE_MODEL_SMOOTH);
-       so_method(so, tesla, NV50TCL_PROVOKING_VERTEX_LAST, 1);
-       so_data  (so, cso->flatshade_first ? 0 : 1);
-
-       so_method(so, tesla, NV50TCL_VERTEX_TWO_SIDE_ENABLE, 1);
-       so_data  (so, cso->light_twoside);
-
-       so_method(so, tesla, NV50TCL_LINE_WIDTH, 1);
-       so_data  (so, fui(cso->line_width));
-       so_method(so, tesla, NV50TCL_LINE_SMOOTH_ENABLE, 1);
-       so_data  (so, cso->line_smooth ? 1 : 0);
-       if (cso->line_stipple_enable) {
-               so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1);
-               so_data  (so, 1);
-               so_method(so, tesla, NV50TCL_LINE_STIPPLE_PATTERN, 1);
-               so_data  (so, (cso->line_stipple_pattern << 8) |
-                              cso->line_stipple_factor);
-       } else {
-               so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1);
-               so_data  (so, 0);
-       }
-
-       so_method(so, tesla, NV50TCL_POINT_SIZE, 1);
-       so_data  (so, fui(cso->point_size));
-
-       so_method(so, tesla, NV50TCL_POINT_SPRITE_ENABLE, 1);
-       so_data  (so, cso->point_quad_rasterization ? 1 : 0);
-
-       so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3);
-        so_data(so, nvgl_polygon_mode(cso->fill_front));
-        so_data(so, nvgl_polygon_mode(cso->fill_back));
-       so_data(so, cso->poly_smooth ? 1 : 0);
-
-       so_method(so, tesla, NV50TCL_CULL_FACE_ENABLE, 3);
-       so_data  (so, cso->cull_face != PIPE_FACE_NONE);
-       if (cso->front_ccw) {
-               so_data(so, NV50TCL_FRONT_FACE_CCW);
-        }
-        else {
-               so_data(so, NV50TCL_FRONT_FACE_CW);
-        }
-       switch (cso->cull_face) {
-       case PIPE_FACE_FRONT:
-               so_data(so, NV50TCL_CULL_FACE_FRONT);
-               break;
-       case PIPE_FACE_BACK:
-               so_data(so, NV50TCL_CULL_FACE_BACK);
-               break;
-       case PIPE_FACE_FRONT_AND_BACK:
-               so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK);
-               break;
-       default:
-               so_data(so, NV50TCL_CULL_FACE_BACK);
-               break;
-       }
-
-       so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_ENABLE, 1);
-       so_data  (so, cso->poly_stipple_enable ? 1 : 0);
-
-       so_method(so, tesla, NV50TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
-        so_data(so, cso->offset_point);
-        so_data(so, cso->offset_line);
-        so_data(so, cso->offset_tri);
-
-       if (cso->offset_point ||
-            cso->offset_line ||
-            cso->offset_tri) {
-               so_method(so, tesla, NV50TCL_POLYGON_OFFSET_FACTOR, 1);
-               so_data  (so, fui(cso->offset_scale));
-               so_method(so, tesla, NV50TCL_POLYGON_OFFSET_UNITS, 1);
-               so_data  (so, fui(cso->offset_units * 2.0f));
-       }
-
-       rso->pipe = *cso;
-       so_ref(so, &rso->so);
-       so_ref(NULL, &so);
-       return (void *)rso;
+      pipe_sampler_view_reference(&nv50->textures[s][i], views[i]);
+   }
+
+   for (i = nr; i < nv50->num_textures[s]; ++i) {
+      struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
+      if (!old)
+         continue;
+      nv50_screen_tic_unlock(nv50->screen, old);
+
+      pipe_sampler_view_reference(&nv50->textures[s][i], NULL);
+   }
+
+   nv50->num_textures[s] = nr;
+
+   nv50_bufctx_reset(nv50, NV50_BUFCTX_TEXTURES);
+
+   nv50->dirty |= NV50_NEW_TEXTURES;
 }
 
 static void
-nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
+nv50_vp_set_sampler_views(struct pipe_context *pipe,
+                          unsigned nr,
+                          struct pipe_sampler_view **views)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-
-       nv50->rasterizer = hwcso;
-       nv50->dirty |= NV50_NEW_RASTERIZER;
+   nv50_stage_set_sampler_views(nv50_context(pipe), 0, nr, views);
 }
 
 static void
-nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
+nv50_fp_set_sampler_views(struct pipe_context *pipe,
+                          unsigned nr,
+                          struct pipe_sampler_view **views)
 {
-       struct nv50_rasterizer_stateobj *rso = hwcso;
-
-       so_ref(NULL, &rso->so);
-       FREE(rso);
+   nv50_stage_set_sampler_views(nv50_context(pipe), 2, nr, views);
 }
 
-static void *
-nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe,
-                       const struct pipe_depth_stencil_alpha_state *cso)
-{
-       struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
-       struct nv50_zsa_stateobj *zsa = CALLOC_STRUCT(nv50_zsa_stateobj);
-       struct nouveau_stateobj *so = so_new(9, 21, 0);
-
-       so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1);
-       so_data  (so, cso->depth.writemask ? 1 : 0);
-       if (cso->depth.enabled) {
-               so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1);
-               so_data  (so, 1);
-               so_method(so, tesla, NV50TCL_DEPTH_TEST_FUNC, 1);
-               so_data  (so, nvgl_comparison_op(cso->depth.func));
-       } else {
-               so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1);
-               so_data  (so, 0);
-       }
-
-       if (cso->stencil[0].enabled) {
-               so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 5);
-               so_data  (so, 1);
-               so_data  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
-               so_data  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
-               so_data  (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
-               so_data  (so, nvgl_comparison_op(cso->stencil[0].func));
-               so_method(so, tesla, NV50TCL_STENCIL_FRONT_MASK, 2);
-               so_data  (so, cso->stencil[0].writemask);
-               so_data  (so, cso->stencil[0].valuemask);
-       } else {
-               so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1);
-               so_data  (so, 0);
-       }
-
-       if (cso->stencil[1].enabled) {
-               so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 5);
-               so_data  (so, 1);
-               so_data  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
-               so_data  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
-               so_data  (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
-               so_data  (so, nvgl_comparison_op(cso->stencil[1].func));
-               so_method(so, tesla, NV50TCL_STENCIL_BACK_MASK, 2);
-               so_data  (so, cso->stencil[1].writemask);
-               so_data  (so, cso->stencil[1].valuemask);
-       } else {
-               so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1);
-               so_data  (so, 0);
-       }
-
-       if (cso->alpha.enabled) {
-               so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1);
-               so_data  (so, 1);
-               so_method(so, tesla, NV50TCL_ALPHA_TEST_REF, 2);
-               so_data  (so, fui(cso->alpha.ref_value));
-               so_data  (so, nvgl_comparison_op(cso->alpha.func));
-       } else {
-               so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1);
-               so_data  (so, 0);
-       }
-
-       zsa->pipe = *cso;
-       so_ref(so, &zsa->so);
-       so_ref(NULL, &so);
-       return (void *)zsa;
+static void
+nv50_gp_set_sampler_views(struct pipe_context *pipe,
+                          unsigned nr,
+                          struct pipe_sampler_view **views)
+{
+   nv50_stage_set_sampler_views(nv50_context(pipe), 1, nr, views);
 }
 
-static void
-nv50_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
+/* ============================= SHADERS =======================================
+ */
+
+static void *
+nv50_sp_state_create(struct pipe_context *pipe,
+                     const struct pipe_shader_state *cso, unsigned type)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_program *prog;
 
-       nv50->zsa = hwcso;
-       nv50->dirty |= NV50_NEW_ZSA;
+   prog = CALLOC_STRUCT(nv50_program);
+   if (!prog)
+      return NULL;
+
+   prog->type = type;
+   prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+
+   return (void *)prog;
 }
 
 static void
-nv50_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
+nv50_sp_state_delete(struct pipe_context *pipe, void *hwcso)
 {
-       struct nv50_zsa_stateobj *zsa = hwcso;
+   struct nv50_program *prog = (struct nv50_program *)hwcso;
+
+   nv50_program_destroy(nv50_context(pipe), prog);
 
-       so_ref(NULL, &zsa->so);
-       FREE(zsa);
+   FREE((void *)prog->pipe.tokens);
+   FREE(prog);
 }
 
 static void *
 nv50_vp_state_create(struct pipe_context *pipe,
-                    const struct pipe_shader_state *cso)
+                     const struct pipe_shader_state *cso)
 {
-       struct nv50_program *p = CALLOC_STRUCT(nv50_program);
-
-       p->pipe.tokens = tgsi_dup_tokens(cso->tokens);
-       p->type = PIPE_SHADER_VERTEX;
-       return (void *)p;
+   return nv50_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX);
 }
 
 static void
 nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-
-       nv50->vertprog = hwcso;
-       nv50->dirty |= NV50_NEW_VERTPROG;
-}
-
-static void
-nv50_vp_state_delete(struct pipe_context *pipe, void *hwcso)
-{
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nv50_program *p = hwcso;
+    struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50_program_destroy(nv50, p);
-       FREE((void *)p->pipe.tokens);
-       FREE(p);
+    nv50->vertprog = hwcso;
+    nv50->dirty |= NV50_NEW_VERTPROG;
 }
 
 static void *
 nv50_fp_state_create(struct pipe_context *pipe,
-                    const struct pipe_shader_state *cso)
+                     const struct pipe_shader_state *cso)
 {
-       struct nv50_program *p = CALLOC_STRUCT(nv50_program);
-
-       p->pipe.tokens = tgsi_dup_tokens(cso->tokens);
-       p->type = PIPE_SHADER_FRAGMENT;
-       return (void *)p;
+   return nv50_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT);
 }
 
 static void
 nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+    struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50->fragprog = hwcso;
-       nv50->dirty |= NV50_NEW_FRAGPROG;
-}
-
-static void
-nv50_fp_state_delete(struct pipe_context *pipe, void *hwcso)
-{
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nv50_program *p = hwcso;
-
-       nv50_program_destroy(nv50, p);
-       FREE((void *)p->pipe.tokens);
-       FREE(p);
+    nv50->fragprog = hwcso;
+    nv50->dirty |= NV50_NEW_FRAGPROG;
 }
 
 static void *
 nv50_gp_state_create(struct pipe_context *pipe,
-                    const struct pipe_shader_state *cso)
+                     const struct pipe_shader_state *cso)
 {
-       struct nv50_program *p = CALLOC_STRUCT(nv50_program);
-
-       p->pipe.tokens = tgsi_dup_tokens(cso->tokens);
-       p->type = PIPE_SHADER_GEOMETRY;
-       return (void *)p;
+   return nv50_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY);
 }
 
 static void
 nv50_gp_state_bind(struct pipe_context *pipe, void *hwcso)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+    struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50->geomprog = hwcso;
-       nv50->dirty |= NV50_NEW_GEOMPROG;
+    nv50->gmtyprog = hwcso;
+    nv50->dirty |= NV50_NEW_GMTYPROG;
 }
 
 static void
-nv50_gp_state_delete(struct pipe_context *pipe, void *hwcso)
+nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
+                         struct pipe_resource *res)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nv50_program *p = hwcso;
+   struct nv50_context *nv50 = nv50_context(pipe);
+
+   if (nv50->constbuf[shader][index])
+      nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT,
+                              nv50_resource(
+                                      nv50->constbuf[shader][index]));
+
+   pipe_resource_reference(&nv50->constbuf[shader][index], res);
 
-       nv50_program_destroy(nv50, p);
-       FREE((void *)p->pipe.tokens);
-       FREE(p);
+   nv50->constbuf_dirty[shader] |= 1 << index;
+
+   nv50->dirty |= NV50_NEW_CONSTBUF;
 }
 
+/* =============================================================================
+ */
+
 static void
 nv50_set_blend_color(struct pipe_context *pipe,
-                    const struct pipe_blend_color *bcol)
+                     const struct pipe_blend_color *bcol)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50->blend_colour = *bcol;
-       nv50->dirty |= NV50_NEW_BLEND_COLOUR;
+   nv50->blend_colour = *bcol;
+   nv50->dirty |= NV50_NEW_BLEND_COLOUR;
 }
 
- static void
+static void
 nv50_set_stencil_ref(struct pipe_context *pipe,
-                    const struct pipe_stencil_ref *sr)
+                     const struct pipe_stencil_ref *sr)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50->stencil_ref = *sr;
-       nv50->dirty |= NV50_NEW_STENCIL_REF;
+   nv50->stencil_ref = *sr;
+   nv50->dirty |= NV50_NEW_STENCIL_REF;
 }
 
 static void
 nv50_set_clip_state(struct pipe_context *pipe,
-                   const struct pipe_clip_state *clip)
+                    const struct pipe_clip_state *clip)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
+   const unsigned size = clip->nr * sizeof(clip->ucp[0]);
 
-       nv50->clip.depth_clamp = clip->depth_clamp;
-       nv50->dirty |= NV50_NEW_CLIP;
-}
+   memcpy(&nv50->clip.ucp[0][0], &clip->ucp[0][0], size);
+   nv50->clip.nr = clip->nr;
 
-static void
-nv50_set_sample_mask(struct pipe_context *pipe,
-                    unsigned sample_mask)
-{
+   nv50->clip.depth_clamp = clip->depth_clamp;
+
+   nv50->dirty |= NV50_NEW_CLIP;
 }
 
 static void
-nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
-                        struct pipe_resource *buf )
+nv50_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-
-       if (shader == PIPE_SHADER_VERTEX) {
-               nv50->dirty |= NV50_NEW_VERTPROG_CB;
-       } else
-       if (shader == PIPE_SHADER_FRAGMENT) {
-               nv50->dirty |= NV50_NEW_FRAGPROG_CB;
-       } else {
-               assert(shader == PIPE_SHADER_GEOMETRY);
-               nv50->dirty |= NV50_NEW_GEOMPROG_CB;
-       }
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       pipe_resource_reference(&nv50->constbuf[shader], buf);
+   nv50->sample_mask = sample_mask;
+   nv50->dirty |= NV50_NEW_SAMPLE_MASK;
 }
 
+
 static void
 nv50_set_framebuffer_state(struct pipe_context *pipe,
-                          const struct pipe_framebuffer_state *fb)
+                           const struct pipe_framebuffer_state *fb)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50->framebuffer = *fb;
-       nv50->dirty |= NV50_NEW_FRAMEBUFFER;
+   nv50->framebuffer = *fb;
+   nv50->dirty |= NV50_NEW_FRAMEBUFFER;
 }
 
 static void
 nv50_set_polygon_stipple(struct pipe_context *pipe,
-                        const struct pipe_poly_stipple *stipple)
+                         const struct pipe_poly_stipple *stipple)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50->stipple = *stipple;
-       nv50->dirty |= NV50_NEW_STIPPLE;
+   nv50->stipple = *stipple;
+   nv50->dirty |= NV50_NEW_STIPPLE;
 }
 
 static void
 nv50_set_scissor_state(struct pipe_context *pipe,
-                      const struct pipe_scissor_state *s)
+                       const struct pipe_scissor_state *scissor)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50->scissor = *s;
-       nv50->dirty |= NV50_NEW_SCISSOR;
+   nv50->scissor = *scissor;
+   nv50->dirty |= NV50_NEW_SCISSOR;
 }
 
 static void
 nv50_set_viewport_state(struct pipe_context *pipe,
-                       const struct pipe_viewport_state *vpt)
+                        const struct pipe_viewport_state *vpt)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50->viewport = *vpt;
-       nv50->dirty |= NV50_NEW_VIEWPORT;
+   nv50->viewport = *vpt;
+   nv50->dirty |= NV50_NEW_VIEWPORT;
 }
 
 static void
-nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
-                       const struct pipe_vertex_buffer *vb)
+nv50_set_vertex_buffers(struct pipe_context *pipe,
+                        unsigned count,
+                        const struct pipe_vertex_buffer *vb)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
+   unsigned i;
 
-        util_copy_vertex_buffers(nv50->vtxbuf,
-                                 &nv50->vtxbuf_nr,
-                                 vb, count);
+   for (i = 0; i < count; ++i)
+      pipe_resource_reference(&nv50->vtxbuf[i].buffer, vb[i].buffer);
+   for (; i < nv50->num_vtxbufs; ++i)
+      pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
 
-       nv50->dirty |= NV50_NEW_ARRAYS;
-}
+   memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count);
+   nv50->num_vtxbufs = count;
 
-static void
-nv50_set_index_buffer(struct pipe_context *pipe,
-                     const struct pipe_index_buffer *ib)
-{
-       struct nv50_context *nv50 = nv50_context(pipe);
-
-       if (ib)
-               memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
-       else
-               memset(&nv50->idxbuf, 0, sizeof(nv50->idxbuf));
-
-       /* TODO make this more like a state */
-}
-
-static void *
-nv50_vtxelts_state_create(struct pipe_context *pipe,
-                         unsigned num_elements,
-                         const struct pipe_vertex_element *elements)
-{
-       struct nv50_vtxelt_stateobj *cso = CALLOC_STRUCT(nv50_vtxelt_stateobj);
-
-       assert(num_elements < 16); /* not doing fallbacks yet */
-       cso->num_elements = num_elements;
-       memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
+   nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
 
-       nv50_vtxelt_construct(cso);
-
-       return (void *)cso;
+   nv50->dirty |= NV50_NEW_ARRAYS;
 }
 
 static void
-nv50_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
+nv50_set_index_buffer(struct pipe_context *pipe,
+                      const struct pipe_index_buffer *ib)
 {
-       FREE(hwcso);
+   struct nv50_context *nv50 = nv50_context(pipe);
+
+   if (ib)
+      memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
+   else
+      nv50->idxbuf.buffer = NULL;
 }
 
 static void
-nv50_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
+nv50_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_context *nv50 = nv50_context(pipe);
 
-       nv50->vtxelt = hwcso;
-       nv50->dirty |= NV50_NEW_ARRAYS;
+   nv50->vertex = hwcso;
+   nv50->dirty |= NV50_NEW_VERTEX;
 }
 
 void
 nv50_init_state_functions(struct nv50_context *nv50)
 {
-       nv50->pipe.create_blend_state = nv50_blend_state_create;
-       nv50->pipe.bind_blend_state = nv50_blend_state_bind;
-       nv50->pipe.delete_blend_state = nv50_blend_state_delete;
-
-       nv50->pipe.create_sampler_state = nv50_sampler_state_create;
-       nv50->pipe.delete_sampler_state = nv50_sampler_state_delete;
-       nv50->pipe.bind_fragment_sampler_states = nv50_fp_sampler_state_bind;
-       nv50->pipe.bind_vertex_sampler_states   = nv50_vp_sampler_state_bind;
-       nv50->pipe.set_fragment_sampler_views = nv50_set_fp_sampler_views;
-       nv50->pipe.set_vertex_sampler_views   = nv50_set_vp_sampler_views;
-       nv50->pipe.create_sampler_view = nv50_create_sampler_view;
-       nv50->pipe.sampler_view_destroy = nv50_sampler_view_destroy;
-
-       nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create;
-       nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind;
-       nv50->pipe.delete_rasterizer_state = nv50_rasterizer_state_delete;
-
-       nv50->pipe.create_depth_stencil_alpha_state =
-               nv50_depth_stencil_alpha_state_create;
-       nv50->pipe.bind_depth_stencil_alpha_state =
-               nv50_depth_stencil_alpha_state_bind;
-       nv50->pipe.delete_depth_stencil_alpha_state =
-               nv50_depth_stencil_alpha_state_delete;
-
-       nv50->pipe.create_vs_state = nv50_vp_state_create;
-       nv50->pipe.bind_vs_state = nv50_vp_state_bind;
-       nv50->pipe.delete_vs_state = nv50_vp_state_delete;
-
-       nv50->pipe.create_fs_state = nv50_fp_state_create;
-       nv50->pipe.bind_fs_state = nv50_fp_state_bind;
-       nv50->pipe.delete_fs_state = nv50_fp_state_delete;
-
-       nv50->pipe.create_gs_state = nv50_gp_state_create;
-       nv50->pipe.bind_gs_state = nv50_gp_state_bind;
-       nv50->pipe.delete_gs_state = nv50_gp_state_delete;
-
-       nv50->pipe.set_blend_color = nv50_set_blend_color;
-        nv50->pipe.set_stencil_ref = nv50_set_stencil_ref;
-       nv50->pipe.set_clip_state = nv50_set_clip_state;
-       nv50->pipe.set_sample_mask = nv50_set_sample_mask;
-       nv50->pipe.set_constant_buffer = nv50_set_constant_buffer;
-       nv50->pipe.set_framebuffer_state = nv50_set_framebuffer_state;
-       nv50->pipe.set_polygon_stipple = nv50_set_polygon_stipple;
-       nv50->pipe.set_scissor_state = nv50_set_scissor_state;
-       nv50->pipe.set_viewport_state = nv50_set_viewport_state;
-
-       nv50->pipe.create_vertex_elements_state = nv50_vtxelts_state_create;
-       nv50->pipe.delete_vertex_elements_state = nv50_vtxelts_state_delete;
-       nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind;
-
-       nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
-       nv50->pipe.set_index_buffer = nv50_set_index_buffer;
-       nv50->pipe.redefine_user_buffer = u_default_redefine_user_buffer;
+   nv50->pipe.create_blend_state = nv50_blend_state_create;
+   nv50->pipe.bind_blend_state = nv50_blend_state_bind;
+   nv50->pipe.delete_blend_state = nv50_blend_state_delete;
+
+   nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create;
+   nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind;
+   nv50->pipe.delete_rasterizer_state = nv50_rasterizer_state_delete;
+
+   nv50->pipe.create_depth_stencil_alpha_state = nv50_zsa_state_create;
+   nv50->pipe.bind_depth_stencil_alpha_state = nv50_zsa_state_bind;
+   nv50->pipe.delete_depth_stencil_alpha_state = nv50_zsa_state_delete;
+
+   nv50->pipe.create_sampler_state = nv50_sampler_state_create;
+   nv50->pipe.delete_sampler_state = nv50_sampler_state_delete;
+   nv50->pipe.bind_vertex_sampler_states   = nv50_vp_sampler_states_bind;
+   nv50->pipe.bind_fragment_sampler_states = nv50_fp_sampler_states_bind;
+   nv50->pipe.bind_geometry_sampler_states = nv50_gp_sampler_states_bind;
+
+   nv50->pipe.create_sampler_view = nv50_create_sampler_view;
+   nv50->pipe.sampler_view_destroy = nv50_sampler_view_destroy;
+   nv50->pipe.set_vertex_sampler_views   = nv50_vp_set_sampler_views;
+   nv50->pipe.set_fragment_sampler_views = nv50_fp_set_sampler_views;
+   nv50->pipe.set_geometry_sampler_views = nv50_gp_set_sampler_views;
+   nv50->pipe.create_vs_state = nv50_vp_state_create;
+   nv50->pipe.create_fs_state = nv50_fp_state_create;
+   nv50->pipe.create_gs_state = nv50_gp_state_create;
+   nv50->pipe.bind_vs_state = nv50_vp_state_bind;
+   nv50->pipe.bind_fs_state = nv50_fp_state_bind;
+   nv50->pipe.bind_gs_state = nv50_gp_state_bind;
+   nv50->pipe.delete_vs_state = nv50_sp_state_delete;
+   nv50->pipe.delete_fs_state = nv50_sp_state_delete;
+   nv50->pipe.delete_gs_state = nv50_sp_state_delete;
+
+   nv50->pipe.set_blend_color = nv50_set_blend_color;
+   nv50->pipe.set_stencil_ref = nv50_set_stencil_ref;
+   nv50->pipe.set_clip_state = nv50_set_clip_state;
+   nv50->pipe.set_sample_mask = nv50_set_sample_mask;
+   nv50->pipe.set_constant_buffer = nv50_set_constant_buffer;
+   nv50->pipe.set_framebuffer_state = nv50_set_framebuffer_state;
+   nv50->pipe.set_polygon_stipple = nv50_set_polygon_stipple;
+   nv50->pipe.set_scissor_state = nv50_set_scissor_state;
+   nv50->pipe.set_viewport_state = nv50_set_viewport_state;
+
+   nv50->pipe.create_vertex_elements_state = nv50_vertex_state_create;
+   nv50->pipe.delete_vertex_elements_state = nv50_vertex_state_delete;
+   nv50->pipe.bind_vertex_elements_state = nv50_vertex_state_bind;
+
+   nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
+   nv50->pipe.set_index_buffer = nv50_set_index_buffer;
 }
 
index ae02143e352f92e38e6885e8199aa95e3e64c8e2..a8f48b2a28eb91d004bc982cda83149ab2a66ca3 100644 (file)
-/*
- * Copyright 2008 Ben Skeggs
- *
- * 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.
- */
-
-#include "util/u_format.h"
 
 #include "nv50_context.h"
-#include "nv50_resource.h"
-#include "nouveau/nouveau_stateobj.h"
+#include "os/os_time.h"
 
-static struct nouveau_stateobj *
-validate_fb(struct nv50_context *nv50)
+static void
+nv50_validate_fb(struct nv50_context *nv50)
 {
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so = so_new(32, 79, 18);
-       struct pipe_framebuffer_state *fb = &nv50->framebuffer;
-       unsigned i, w = 0, h = 0, gw = 0;
-
-       /* Set nr of active RTs and select RT for each colour output.
-        * FP result 0 always goes to RT[0], bits 4 - 6 are ignored.
-        * Ambiguous assignment results in no rendering (no DATA_ERROR).
-        */
-       so_method(so, tesla, NV50TCL_RT_CONTROL, 1);
-       so_data  (so, fb->nr_cbufs |
-                 (0 <<  4) | (1 <<  7) | (2 << 10) | (3 << 13) |
-                 (4 << 16) | (5 << 19) | (6 << 22) | (7 << 25));
-
-       for (i = 0; i < fb->nr_cbufs; i++) {
-               struct pipe_resource *pt = fb->cbufs[i]->texture;
-               struct nouveau_bo *bo = nv50_miptree(pt)->base.bo;
-
-               if (!gw) {
-                       w = fb->cbufs[i]->width;
-                       h = fb->cbufs[i]->height;
-                       gw = 1;
-               } else {
-                       assert(w == fb->cbufs[i]->width);
-                       assert(h == fb->cbufs[i]->height);
-               }
-
-               assert(nv50_format_table[fb->cbufs[i]->format].rt);
-
-               so_method(so, tesla, NV50TCL_RT_HORIZ(i), 2);
-               so_data  (so, fb->cbufs[i]->width);
-               so_data  (so, fb->cbufs[i]->height);
-
-               so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5);
-               so_reloc (so, bo, ((struct nv50_surface *)fb->cbufs[i])->offset, NOUVEAU_BO_VRAM |
-                             NOUVEAU_BO_HIGH | NOUVEAU_BO_RDWR, 0, 0);
-               so_reloc (so, bo, ((struct nv50_surface *)fb->cbufs[i])->offset, NOUVEAU_BO_VRAM |
-                             NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);
-               so_data  (so, nv50_format_table[fb->cbufs[i]->format].rt);
-               so_data  (so, nv50_miptree(pt)->
-                             level[fb->cbufs[i]->u.tex.level].tile_mode << 4);
-               so_data(so, 0x00000000);
-
-               so_method(so, tesla, NV50TCL_RT_ARRAY_MODE, 1);
-               so_data  (so, 1);
-       }
-
-       if (fb->zsbuf) {
-               struct pipe_resource *pt = fb->zsbuf->texture;
-               struct nouveau_bo *bo = nv50_miptree(pt)->base.bo;
-
-               if (!gw) {
-                       w = fb->zsbuf->width;
-                       h = fb->zsbuf->height;
-                       gw = 1;
-               } else {
-                       assert(w == fb->zsbuf->width);
-                       assert(h == fb->zsbuf->height);
-               }
-
-               assert(nv50_format_table[fb->zsbuf->format].rt);
-
-               so_method(so, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5);
-               so_reloc (so, bo, ((struct nv50_surface *)(fb->zsbuf))->offset, NOUVEAU_BO_VRAM |
-                             NOUVEAU_BO_HIGH | NOUVEAU_BO_RDWR, 0, 0);
-               so_reloc (so, bo, ((struct nv50_surface *)(fb->zsbuf))->offset, NOUVEAU_BO_VRAM |
-                             NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);
-               so_data  (so, nv50_format_table[fb->zsbuf->format].rt);
-               so_data  (so, nv50_miptree(pt)->
-                             level[fb->zsbuf->u.tex.level].tile_mode << 4);
-               so_data  (so, 0x00000000);
-
-               so_method(so, tesla, NV50TCL_ZETA_ENABLE, 1);
-               so_data  (so, 1);
-               so_method(so, tesla, NV50TCL_ZETA_HORIZ, 3);
-               so_data  (so, fb->zsbuf->width);
-               so_data  (so, fb->zsbuf->height);
-               so_data  (so, 0x00010001);
-       } else {
-               so_method(so, tesla, NV50TCL_ZETA_ENABLE, 1);
-               so_data  (so, 0);
-       }
-
-       so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2);
-       so_data  (so, w << 16);
-       so_data  (so, h << 16);
-       /* set window lower left corner */
-       so_method(so, tesla, NV50TCL_WINDOW_OFFSET_X, 2);
-       so_data  (so, 0);
-       so_data  (so, 0);
-       /* set screen scissor rectangle */
-       so_method(so, tesla, NV50TCL_SCREEN_SCISSOR_HORIZ, 2);
-       so_data  (so, w << 16);
-       so_data  (so, h << 16);
-
-       return so;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct pipe_framebuffer_state *fb = &nv50->framebuffer;
+   unsigned i;
+
+   nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME);
+
+   BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
+   OUT_RING  (chan, (076543210 << 4) | fb->nr_cbufs);
+   BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
+   OUT_RING  (chan, fb->width << 16);
+   OUT_RING  (chan, fb->height << 16);
+
+   MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs);
+
+   for (i = 0; i < fb->nr_cbufs; ++i) {
+      struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture);
+      struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
+      struct nouveau_bo *bo = mt->base.bo;
+      uint32_t offset = sf->offset;
+
+      BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 5);
+      OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+      OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+      OUT_RING  (chan, nv50_format_table[sf->base.format].rt);
+      OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
+      OUT_RING  (chan, mt->layer_stride >> 2);
+      BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
+      OUT_RING  (chan, sf->width);
+      OUT_RING  (chan, sf->height);
+      BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
+      OUT_RING  (chan, sf->depth);
+
+      nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
+                               NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+   }
+
+   if (fb->zsbuf) {
+      struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
+      struct nv50_surface *sf = nv50_surface(fb->zsbuf);
+      struct nouveau_bo *bo = mt->base.bo;
+      int unk = mt->base.base.target == PIPE_TEXTURE_2D;
+      uint32_t offset = sf->offset;
+
+      MARK_RING (chan, 12, 2);
+      BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
+      OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+      OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+      OUT_RING  (chan, nv50_format_table[fb->zsbuf->format].rt);
+      OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
+      OUT_RING  (chan, mt->layer_stride >> 2);
+      BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
+      OUT_RING  (chan, 1);
+      BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
+      OUT_RING  (chan, sf->width);
+      OUT_RING  (chan, sf->height);
+      OUT_RING  (chan, (unk << 16) | sf->depth);
+
+      nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
+                               NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+   } else {
+      BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
+      OUT_RING  (chan, 0);
+   }
+
+   BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
+   OUT_RING  (chan, fb->width << 16);
+   OUT_RING  (chan, fb->height << 16);
 }
 
 static void
-nv50_validate_samplers(struct nv50_context *nv50, struct nouveau_stateobj *so,
-                      unsigned p)
+nv50_validate_blend_colour(struct nv50_context *nv50)
 {
-       struct nouveau_grobj *eng2d = nv50->screen->eng2d;
-       unsigned i, j, dw = nv50->sampler_nr[p] * 8;
-
-       if (!dw)
-               return;
-       nv50_so_init_sifc(nv50, so, nv50->screen->tsc, NOUVEAU_BO_VRAM,
-                         p * (32 * 8 * 4), dw * 4);
-
-       so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), dw);
-
-       for (i = 0; i < nv50->sampler_nr[p]; ++i) {
-               if (nv50->sampler[p][i])
-                       so_datap(so, nv50->sampler[p][i]->tsc, 8);
-               else {
-                       for (j = 0; j < 8; ++j) /* you get punished */
-                               so_data(so, 0); /* ... for leaving holes */
-               }
-       }
-}
+   struct nouveau_channel *chan = nv50->screen->base.channel;
 
-static struct nouveau_stateobj *
-validate_blend(struct nv50_context *nv50)
-{
-       struct nouveau_stateobj *so = NULL;
-       so_ref(nv50->blend->so, &so);
-       return so;
+   BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4);
+   OUT_RINGf (chan, nv50->blend_colour.color[0]);
+   OUT_RINGf (chan, nv50->blend_colour.color[1]);
+   OUT_RINGf (chan, nv50->blend_colour.color[2]);
+   OUT_RINGf (chan, nv50->blend_colour.color[3]);    
 }
 
-static struct nouveau_stateobj *
-validate_zsa(struct nv50_context *nv50)
+static void
+nv50_validate_stencil_ref(struct nv50_context *nv50)
 {
-       struct nouveau_stateobj *so = NULL;
-       so_ref(nv50->zsa->so, &so);
-       return so;
-}
+   struct nouveau_channel *chan = nv50->screen->base.channel;
 
-static struct nouveau_stateobj *
-validate_rast(struct nv50_context *nv50)
-{
-       struct nouveau_stateobj *so = NULL;
-       so_ref(nv50->rasterizer->so, &so);
-       return so;
+   BEGIN_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), 1);
+   OUT_RING  (chan, nv50->stencil_ref.ref_value[0]);
+   BEGIN_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), 1);
+   OUT_RING  (chan, nv50->stencil_ref.ref_value[1]);
 }
 
-static struct nouveau_stateobj *
-validate_blend_colour(struct nv50_context *nv50)
+static void
+nv50_validate_stipple(struct nv50_context *nv50)
 {
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so = so_new(1, 4, 0);
-
-       so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
-       so_data  (so, fui(nv50->blend_colour.color[0]));
-       so_data  (so, fui(nv50->blend_colour.color[1]));
-       so_data  (so, fui(nv50->blend_colour.color[2]));
-       so_data  (so, fui(nv50->blend_colour.color[3]));
-       return so;
-}
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   unsigned i;
 
-static struct nouveau_stateobj *
-validate_stencil_ref(struct nv50_context *nv50)
-{
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so = so_new(2, 2, 0);
-
-       so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1);
-       so_data  (so, nv50->stencil_ref.ref_value[0]);
-       so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1);
-       so_data  (so, nv50->stencil_ref.ref_value[1]);
-       return so;
+   BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
+   for (i = 0; i < 32; ++i)
+      OUT_RING(chan, util_bswap32(nv50->stipple.stipple[i]));
 }
 
-static struct nouveau_stateobj *
-validate_stipple(struct nv50_context *nv50)
+static void
+nv50_validate_scissor(struct nv50_context *nv50)
 {
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so = so_new(1, 32, 0);
-       int i;
-
-       so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
-       for (i = 0; i < 32; i++)
-               so_data(so, util_bswap32(nv50->stipple.stipple[i]));
-       return so;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct pipe_scissor_state *s = &nv50->scissor;
+#ifdef NV50_SCISSORS_CLIPPING
+   struct pipe_viewport_state *vp = &nv50->viewport;
+   int minx, maxx, miny, maxy;
+
+   if (!(nv50->dirty &
+         (NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT | NV50_NEW_FRAMEBUFFER)) &&
+       nv50->state.scissor == nv50->rast->pipe.scissor)
+      return;
+   nv50->state.scissor = nv50->rast->pipe.scissor;
+
+   if (nv50->state.scissor) {
+      minx = s->minx;
+      maxx = s->maxx;
+      miny = s->miny;
+      maxy = s->maxy;
+   } else {
+      minx = 0;
+      maxx = nv50->framebuffer.width;
+      miny = 0;
+      maxy = nv50->framebuffer.height;
+   }
+
+   minx = MAX2(minx, (int)(vp->translate[0] - fabsf(vp->scale[0])));
+   maxx = MIN2(maxx, (int)(vp->translate[0] + fabsf(vp->scale[0])));
+   miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1])));
+   maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1])));
+
+   BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
+   OUT_RING  (chan, (maxx << 16) | minx);
+   OUT_RING  (chan, (maxy << 16) | miny);
+#else
+   BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
+   OUT_RING  (chan, (s->maxx << 16) | s->minx);
+   OUT_RING  (chan, (s->maxy << 16) | s->miny);
+#endif
 }
 
-static struct nouveau_stateobj *
-validate_scissor(struct nv50_context *nv50)
+static void
+nv50_validate_viewport(struct nv50_context *nv50)
 {
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-        struct pipe_scissor_state *s = &nv50->scissor;
-       struct nouveau_stateobj *so;
-
-       so = so_new(1, 2, 0);
-       so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2);
-       so_data  (so, (s->maxx << 16) | s->minx);
-       so_data  (so, (s->maxy << 16) | s->miny);
-       return so;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   float zmin, zmax;
+
+   BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
+   OUT_RINGf (chan, nv50->viewport.translate[0]);
+   OUT_RINGf (chan, nv50->viewport.translate[1]);
+   OUT_RINGf (chan, nv50->viewport.translate[2]);
+   BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3);
+   OUT_RINGf (chan, nv50->viewport.scale[0]);
+   OUT_RINGf (chan, nv50->viewport.scale[1]);
+   OUT_RINGf (chan, nv50->viewport.scale[2]);
+
+   zmin = nv50->viewport.translate[2] - fabsf(nv50->viewport.scale[2]);
+   zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]);
+
+#ifdef NV50_SCISSORS_CLIPPING
+   BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
+   OUT_RINGf (chan, zmin);
+   OUT_RINGf (chan, zmax);
+#endif
 }
 
-static struct nouveau_stateobj *
-validate_viewport(struct nv50_context *nv50)
+static void
+nv50_validate_clip(struct nv50_context *nv50)
 {
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so = so_new(3, 7, 0);
-
-       so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
-       so_data  (so, fui(nv50->viewport.translate[0]));
-       so_data  (so, fui(nv50->viewport.translate[1]));
-       so_data  (so, fui(nv50->viewport.translate[2]));
-       so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
-       so_data  (so, fui(nv50->viewport.scale[0]));
-       so_data  (so, fui(nv50->viewport.scale[1]));
-       so_data  (so, fui(nv50->viewport.scale[2]));
-
-       /* no idea what 0f90 does */
-       so_method(so, tesla, 0x0f90, 1);
-       so_data  (so, 0);
-
-       return so;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   uint32_t clip;
+
+   clip = nv50->clip.depth_clamp ? 0x0018 : 0x0000;
+#ifndef NV50_SCISSORS_CLIPPING
+   clip |= 0x1080;
+#endif
+
+   BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
+   OUT_RING  (chan, clip);
+
+   if (nv50->clip.nr) {
+      BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
+      OUT_RING  (chan, (0 << 8) | NV50_CB_AUX);
+      BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nv50->clip.nr * 4);
+      OUT_RINGp (chan, &nv50->clip.ucp[0][0], nv50->clip.nr * 4);
+   }
+
+   BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1);
+   OUT_RING  (chan, (1 << nv50->clip.nr) - 1);
 }
 
-static struct nouveau_stateobj *
-validate_sampler(struct nv50_context *nv50)
+static void
+nv50_validate_blend(struct nv50_context *nv50)
 {
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so;
-       unsigned nr = 0, i;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
 
-       for (i = 0; i < 3; ++i)
-               nr += nv50->sampler_nr[i];
-
-       so = so_new(1 + 5 * 3, 1 + 19 * 3 + nr * 8, 3 * 2);
-
-       nv50_validate_samplers(nv50, so, 0); /* VP */
-       nv50_validate_samplers(nv50, so, 2); /* FP */
-
-       so_method(so, tesla, 0x1334, 1); /* flush TSC */
-       so_data  (so, 0);
-
-       return so;
+   WAIT_RING(chan, nv50->blend->size);
+   OUT_RINGp(chan, nv50->blend->state, nv50->blend->size);
 }
 
-static struct nouveau_stateobj *
-validate_vtxbuf(struct nv50_context *nv50)
+static void
+nv50_validate_zsa(struct nv50_context *nv50)
 {
-       struct nouveau_stateobj *so = NULL;
-       so_ref(nv50->state.vtxbuf, &so);
-       return so;
-}
+   struct nouveau_channel *chan = nv50->screen->base.channel;
 
-static struct nouveau_stateobj *
-validate_vtxattr(struct nv50_context *nv50)
-{
-       struct nouveau_stateobj *so = NULL;
-       so_ref(nv50->state.vtxattr, &so);
-       return so;
+   WAIT_RING(chan, nv50->zsa->size);
+   OUT_RINGp(chan, nv50->zsa->state, nv50->zsa->size);
 }
 
-static struct nouveau_stateobj *
-validate_clip(struct nv50_context *nv50)
+static void
+nv50_validate_rasterizer(struct nv50_context *nv50)
 {
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so = so_new(1, 1, 0);
-       uint32_t vvcc;
-
-       /* 0x0000 = remove whole primitive only (xyz)
-        * 0x1018 = remove whole primitive only (xy), clamp z
-        * 0x1080 = clip primitive (xyz)
-        * 0x1098 = clip primitive (xy), clamp z
-        */
-       vvcc = nv50->clip.depth_clamp ? 0x1098 : 0x1080;
-
-       so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
-       so_data  (so, vvcc);
+   struct nouveau_channel *chan = nv50->screen->base.channel;
 
-       return so;
+   WAIT_RING(chan, nv50->rast->size);
+   OUT_RINGp(chan, nv50->rast->state, nv50->rast->size);
 }
 
-struct state_validate {
-       struct nouveau_stateobj *(*func)(struct nv50_context *nv50);
-       unsigned states;
+static struct state_validate {
+    void (*func)(struct nv50_context *);
+    uint32_t states;
 } validate_list[] = {
-       { validate_fb             , NV50_NEW_FRAMEBUFFER                      },
-       { validate_blend          , NV50_NEW_BLEND                            },
-       { validate_zsa            , NV50_NEW_ZSA                              },
-       { nv50_vertprog_validate  , NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB  },
-       { nv50_fragprog_validate  , NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB  },
-       { nv50_geomprog_validate  , NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB  },
-       { nv50_fp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG |
-                                   NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER   },
-       { nv50_gp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG     },
-       { validate_rast           , NV50_NEW_RASTERIZER                       },
-       { validate_blend_colour   , NV50_NEW_BLEND_COLOUR                     },
-       { validate_stencil_ref    , NV50_NEW_STENCIL_REF                      },
-       { validate_stipple        , NV50_NEW_STIPPLE                          },
-       { validate_scissor        , NV50_NEW_SCISSOR                          },
-       { validate_viewport       , NV50_NEW_VIEWPORT                         },
-       { validate_sampler        , NV50_NEW_SAMPLER                          },
-       { nv50_tex_validate       , NV50_NEW_TEXTURE | NV50_NEW_SAMPLER       },
-       { nv50_vbo_validate       , NV50_NEW_ARRAYS                           },
-       { validate_vtxbuf         , NV50_NEW_ARRAYS                           },
-       { validate_vtxattr        , NV50_NEW_ARRAYS                           },
-       { validate_clip           , NV50_NEW_CLIP                             },
-       { NULL                    , 0                                         }
+    { nv50_validate_fb,            NV50_NEW_FRAMEBUFFER },
+    { nv50_validate_blend,         NV50_NEW_BLEND },
+    { nv50_validate_zsa,           NV50_NEW_ZSA },
+    { nv50_validate_rasterizer,    NV50_NEW_RASTERIZER },
+    { nv50_validate_blend_colour,  NV50_NEW_BLEND_COLOUR },
+    { nv50_validate_stencil_ref,   NV50_NEW_STENCIL_REF },
+    { nv50_validate_stipple,       NV50_NEW_STIPPLE },
+#ifdef NV50_SCISSORS_CLIPPING
+    { nv50_validate_scissor,       NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT |
+                                   NV50_NEW_RASTERIZER |
+                                   NV50_NEW_FRAMEBUFFER },
+#else
+    { nv50_validate_scissor,       NV50_NEW_SCISSOR },
+#endif
+    { nv50_validate_viewport,      NV50_NEW_VIEWPORT },
+    { nv50_validate_clip,          NV50_NEW_CLIP },
+    { nv50_vertprog_validate,      NV50_NEW_VERTPROG },
+    { nv50_gmtyprog_validate,      NV50_NEW_GMTYPROG },
+    { nv50_fragprog_validate,      NV50_NEW_FRAGPROG },
+    { nv50_fp_linkage_validate,    NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
+                                   NV50_NEW_GMTYPROG },
+    { nv50_gp_linkage_validate,    NV50_NEW_GMTYPROG | NV50_NEW_VERTPROG },
+    { nv50_constbufs_validate,     NV50_NEW_CONSTBUF },
+    { nv50_validate_textures,      NV50_NEW_TEXTURES },
+    { nv50_validate_samplers,      NV50_NEW_SAMPLERS },
+    { nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS }
 };
 #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
 
 boolean
-nv50_state_validate(struct nv50_context *nv50, unsigned wait_dwords)
-{
-       struct nouveau_channel *chan = nv50->screen->base.channel;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       unsigned nr_relocs = 128, nr_dwords = wait_dwords + 128 + 4;
-       int ret, i;
-
-       for (i = 0; i < validate_list_len; i++) {
-               struct state_validate *validate = &validate_list[i];
-               struct nouveau_stateobj *so;
-
-               if (!(nv50->dirty & validate->states))
-                       continue;
-
-               so = validate->func(nv50);
-               if (!so)
-                       continue;
-
-               nr_dwords += (so->total + so->cur);
-               nr_relocs += so->cur_reloc;
-
-               so_ref(so, &nv50->state.hw[i]);
-               so_ref(NULL, &so);
-               nv50->state.hw_dirty |= (1 << i);
-       }
-       nv50->dirty = 0;
-
-       if (nv50->screen->cur_ctx != nv50) {
-               for (i = 0; i < validate_list_len; i++) {
-                       if (!nv50->state.hw[i] ||
-                           (nv50->state.hw_dirty & (1 << i)))
-                               continue;
-
-                       nr_dwords += (nv50->state.hw[i]->total +
-                                     nv50->state.hw[i]->cur);
-                       nr_relocs += nv50->state.hw[i]->cur_reloc;
-                       nv50->state.hw_dirty |= (1 << i);
-               }
-
-               nv50->screen->cur_ctx = nv50;
-       }
-
-       ret = MARK_RING(chan, nr_dwords, nr_relocs);
-       if (ret) {
-               debug_printf("MARK_RING(%d, %d) failed: %d\n",
-                            nr_dwords, nr_relocs, ret);
-               return FALSE;
-       }
-
-       while (nv50->state.hw_dirty) {
-               i = ffs(nv50->state.hw_dirty) - 1;
-               nv50->state.hw_dirty &= ~(1 << i);
-
-               so_emit(chan, nv50->state.hw[i]);
-       }
-
-       /* Yes, really, we need to do this.  If a buffer that is referenced
-        * on the hardware isn't part of changed state above, without doing
-        * this the kernel is given no clue that the buffer is being used
-        * still.  This can cause all sorts of fun issues.
-        */
-       nv50_tex_relocs(nv50);
-       so_emit_reloc_markers(chan, nv50->state.hw[0]); /* fb */
-       so_emit_reloc_markers(chan, nv50->state.hw[3]); /* vp */
-       so_emit_reloc_markers(chan, nv50->state.hw[4]); /* fp */
-       so_emit_reloc_markers(chan, nv50->state.hw[17]); /* vb */
-       nv50_screen_relocs(nv50->screen);
-
-       /* No idea.. */
-       BEGIN_RING(chan, tesla, 0x142c, 1);
-       OUT_RING  (chan, 0);
-       BEGIN_RING(chan, tesla, 0x142c, 1);
-       OUT_RING  (chan, 0);
-       return TRUE;
-}
-
-void nv50_so_init_sifc(struct nv50_context *nv50,
-                      struct nouveau_stateobj *so,
-                      struct nouveau_bo *bo, unsigned reloc,
-                      unsigned offset, unsigned size)
+nv50_state_validate(struct nv50_context *nv50)
 {
-       struct nouveau_grobj *eng2d = nv50->screen->eng2d;
-
-       reloc |= NOUVEAU_BO_WR;
-
-       so_method(so, eng2d, NV50_2D_DST_FORMAT, 2);
-       so_data  (so, NV50_2D_DST_FORMAT_R8_UNORM);
-       so_data  (so, 1);
-       so_method(so, eng2d, NV50_2D_DST_PITCH, 5);
-       so_data  (so, 262144);
-       so_data  (so, 65536);
-       so_data  (so, 1);
-       so_reloc (so, bo, offset, reloc | NOUVEAU_BO_HIGH, 0, 0);
-       so_reloc (so, bo, offset, reloc | NOUVEAU_BO_LOW, 0, 0);
-       so_method(so, eng2d, NV50_2D_SIFC_BITMAP_ENABLE, 2);
-       so_data  (so, 0);
-       so_data  (so, NV50_2D_SIFC_FORMAT_R8_UNORM);
-       so_method(so, eng2d, NV50_2D_SIFC_WIDTH, 10);
-       so_data  (so, size);
-       so_data  (so, 1);
-       so_data  (so, 0);
-       so_data  (so, 1);
-       so_data  (so, 0);
-       so_data  (so, 1);
-       so_data  (so, 0);
-       so_data  (so, 0);
-       so_data  (so, 0);
-       so_data  (so, 0);
+   unsigned i;
+#if 0
+   if (nv50->screen->cur_ctx != nv50) /* FIXME: not everything is valid */
+      nv50->dirty = 0xffffffff;
+#endif
+   nv50->screen->cur_ctx = nv50;
+
+   if (nv50->dirty) {
+      for (i = 0; i < validate_list_len; ++i) {
+         struct state_validate *validate = &validate_list[i];
+
+         if (nv50->dirty & validate->states)
+            validate->func(nv50);
+      }
+      nv50->dirty = 0;
+   }
+
+   nv50_bufctx_emit_relocs(nv50);
+
+   return TRUE;
 }
diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h
new file mode 100644 (file)
index 0000000..49f1837
--- /dev/null
@@ -0,0 +1,72 @@
+
+#ifndef __NV50_STATEOBJ_H__
+#define __NV50_STATEOBJ_H__
+
+#include "pipe/p_state.h"
+
+#define NV50_SCISSORS_CLIPPING
+
+#define SB_BEGIN_3D(so, m, s)                                                  \
+   (so)->state[(so)->size++] =                                                 \
+      ((s) << 18) | (NV50_SUBCH_3D << 13) | NV50_3D_##m
+
+#define SB_DATA(so, u) (so)->state[(so)->size++] = (u)
+
+struct nv50_blend_stateobj {
+   struct pipe_blend_state pipe;
+   int size;
+   uint32_t state[29];
+};
+
+struct nv50_tsc_entry {
+   int id;
+   uint32_t tsc[8];
+};
+
+static INLINE struct nv50_tsc_entry *
+nv50_tsc_entry(void *hwcso)
+{
+   return (struct nv50_tsc_entry *)hwcso;
+}
+
+struct nv50_tic_entry {
+   struct pipe_sampler_view pipe;
+   int id;
+   uint32_t tic[8];
+};
+
+static INLINE struct nv50_tic_entry *
+nv50_tic_entry(struct pipe_sampler_view *view)
+{
+   return (struct nv50_tic_entry *)view;
+}
+
+struct nv50_rasterizer_stateobj {
+   struct pipe_rasterizer_state pipe;
+   int size;
+   uint32_t state[40];
+};
+
+struct nv50_zsa_stateobj {
+   struct pipe_depth_stencil_alpha_state pipe;
+   int size;
+   uint32_t state[29];
+};
+
+struct nv50_vertex_element {
+   struct pipe_vertex_element pipe;
+   uint32_t state;
+};
+
+struct nv50_vertex_stateobj {
+   struct translate *translate;
+   unsigned num_elements;
+   uint32_t instance_elts;
+   uint32_t instance_bufs;
+   boolean need_conversion;
+   unsigned vertex_size;
+   unsigned packet_vertex_limit;
+   struct nv50_vertex_element element[1];
+};
+
+#endif
index a99df76cee339607a5431291be8a94834e26e58d..b1f54f623ab48f5126ad18a5f2988c5c3a8fb447 100644 (file)
  * SOFTWARE.
  */
 
-#define __NOUVEAU_PUSH_H__
 #include <stdint.h>
-#include "nouveau/nv04_pushbuf.h"
-#include "nv50_context.h"
-#include "nv50_resource.h"
+
 #include "pipe/p_defines.h"
+
 #include "util/u_inlines.h"
 #include "util/u_pack_color.h"
-
 #include "util/u_format.h"
 
+#include "nv50_context.h"
+#include "nv50_resource.h"
+
+#include "nv50_defs.xml.h"
+
 /* return TRUE for formats that can be converted among each other by NV50_2D */
 static INLINE boolean
 nv50_2d_format_faithful(enum pipe_format format)
 {
-       switch (format) {
-       case PIPE_FORMAT_B8G8R8A8_UNORM:
-       case PIPE_FORMAT_B8G8R8X8_UNORM:
-       case PIPE_FORMAT_B8G8R8A8_SRGB:
-       case PIPE_FORMAT_B8G8R8X8_SRGB:
-       case PIPE_FORMAT_B5G6R5_UNORM:
-       case PIPE_FORMAT_B5G5R5A1_UNORM:
-       case PIPE_FORMAT_B10G10R10A2_UNORM:
-       case PIPE_FORMAT_R8_UNORM:
-       case PIPE_FORMAT_R32G32B32A32_FLOAT:
-       case PIPE_FORMAT_R32G32B32_FLOAT:
-               return TRUE;
-       default:
-               return FALSE;
-       }
+   switch (format) {
+   case PIPE_FORMAT_B8G8R8A8_UNORM:
+   case PIPE_FORMAT_B8G8R8X8_UNORM:
+   case PIPE_FORMAT_B8G8R8A8_SRGB:
+   case PIPE_FORMAT_B8G8R8X8_SRGB:
+   case PIPE_FORMAT_B5G6R5_UNORM:
+   case PIPE_FORMAT_B5G5R5A1_UNORM:
+   case PIPE_FORMAT_B10G10R10A2_UNORM:
+   case PIPE_FORMAT_R8_UNORM:
+   case PIPE_FORMAT_R32G32B32A32_FLOAT:
+   case PIPE_FORMAT_R32G32B32_FLOAT:
+      return TRUE;
+   default:
+      return FALSE;
+   }
 }
 
 static INLINE uint8_t
 nv50_2d_format(enum pipe_format format)
 {
-       uint8_t id = nv50_format_table[format].rt;
-
-       /* Hardware values for color formats range from 0xc0 to 0xff,
-        * but the 2D engine doesn't support all of them.
-        */
-       if ((id >= 0xc0) && (0xff0843e080608409ULL & (1ULL << (id - 0xc0))))
-               return id;
-
-       switch (util_format_get_blocksize(format)) {
-       case 1:
-               return NV50_2D_DST_FORMAT_R8_UNORM;
-       case 2:
-               return NV50_2D_DST_FORMAT_R16_UNORM;
-       case 4:
-               return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM;
-       default:
-               return 0;
-       }
+   uint8_t id = nv50_format_table[format].rt;
+
+   /* Hardware values for color formats range from 0xc0 to 0xff,
+    * but the 2D engine doesn't support all of them.
+    */
+   if ((id >= 0xc0) && (0xff0843e080608409ULL & (1ULL << (id - 0xc0))))
+      return id;
+
+   switch (util_format_get_blocksize(format)) {
+   case 1:
+      return NV50_SURFACE_FORMAT_R8_UNORM;
+   case 2:
+      return NV50_SURFACE_FORMAT_R16_UNORM;
+   case 4:
+      return NV50_SURFACE_FORMAT_A8R8G8B8_UNORM;
+   default:
+      return 0;
+   }
 }
 
 static int
-nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
+nv50_2d_texture_set(struct nouveau_channel *chan, int dst,
+                    struct nv50_miptree *mt, unsigned level, unsigned layer)
 {
-       struct nv50_miptree *mt = nv50_miptree(ps->texture);
-       struct nouveau_channel *chan = screen->eng2d->channel;
-       struct nouveau_grobj *eng2d = screen->eng2d;
-       struct nouveau_bo *bo = nv50_miptree(ps->texture)->base.bo;
-       int format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
-       int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
-
-       format = nv50_2d_format(ps->format);
-       if (!format) {
-               NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
-                           util_format_name(ps->format));
-               return 1;
-       }
-
-       if (!nouveau_bo_tile_layout(bo)) {
-               BEGIN_RING(chan, eng2d, mthd, 2);
-               OUT_RING  (chan, format);
-               OUT_RING  (chan, 1);
-               BEGIN_RING(chan, eng2d, mthd + 0x14, 5);
-               OUT_RING  (chan, mt->level[ps->u.tex.level].pitch);
-               OUT_RING  (chan, ps->width);
-               OUT_RING  (chan, ps->height);
-               OUT_RELOCh(chan, bo, ((struct nv50_surface *)ps)->offset, flags);
-               OUT_RELOCl(chan, bo, ((struct nv50_surface *)ps)->offset, flags);
-       } else {
-               BEGIN_RING(chan, eng2d, mthd, 5);
-               OUT_RING  (chan, format);
-               OUT_RING  (chan, 0);
-               OUT_RING  (chan, mt->level[ps->u.tex.level].tile_mode << 4);
-               OUT_RING  (chan, 1);
-               OUT_RING  (chan, 0);
-               BEGIN_RING(chan, eng2d, mthd + 0x18, 4);
-               OUT_RING  (chan, ps->width);
-               OUT_RING  (chan, ps->height);
-               OUT_RELOCh(chan, bo, ((struct nv50_surface *)ps)->offset, flags);
-               OUT_RELOCl(chan, bo, ((struct nv50_surface *)ps)->offset, flags);
-       }
+   struct nouveau_bo *bo = mt->base.bo;
+   uint32_t width, height, depth;
+   uint32_t format;
+   uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
+   uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
+   uint32_t offset = mt->level[level].offset;
+
+   format = nv50_2d_format(mt->base.base.format);
+   if (!format) {
+      NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
+                  util_format_name(mt->base.base.format));
+      return 1;
+   }
+
+   width = u_minify(mt->base.base.width0, level);
+   height = u_minify(mt->base.base.height0, level);
+
+   offset = mt->level[level].offset;
+   if (!mt->layout_3d) {
+      offset += mt->layer_stride * layer;
+      depth = 1;
+      layer = 0;
+   } else {
+      depth = u_minify(mt->base.base.depth0, level);
+   }
+
+   if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) {
+      BEGIN_RING(chan, RING_2D_(mthd), 2);
+      OUT_RING  (chan, format);
+      OUT_RING  (chan, 1);
+      BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5);
+      OUT_RING  (chan, mt->level[level].pitch);
+      OUT_RING  (chan, width);
+      OUT_RING  (chan, height);
+      OUT_RELOCh(chan, bo, offset, flags);
+      OUT_RELOCl(chan, bo, offset, flags);
+   } else {
+      BEGIN_RING(chan, RING_2D_(mthd), 5);
+      OUT_RING  (chan, format);
+      OUT_RING  (chan, 0);
+      OUT_RING  (chan, mt->level[level].tile_mode << 4);
+      OUT_RING  (chan, depth);
+      OUT_RING  (chan, layer);
+      BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4);
+      OUT_RING  (chan, width);
+      OUT_RING  (chan, height);
+      OUT_RELOCh(chan, bo, offset, flags);
+      OUT_RELOCl(chan, bo, offset, flags);
+   }
+
 #if 0
-       if (dst) {
-               BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
-               OUT_RING  (chan, 0);
-               OUT_RING  (chan, 0);
-               OUT_RING  (chan, surf->width);
-               OUT_RING  (chan, surf->height);
-       }
+   if (dst) {
+      BEGIN_RING(chan, RING_2D_(NV50_2D_CLIP_X), 4);
+      OUT_RING  (chan, 0);
+      OUT_RING  (chan, 0);
+      OUT_RING  (chan, width);
+      OUT_RING  (chan, height);
+   }
 #endif
-  
-       return 0;
+   return 0;
 }
 
-int
-nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst,
-                    int dx, int dy, struct pipe_surface *src, int sx, int sy,
-                    int w, int h)
+static int
+nv50_2d_texture_do_copy(struct nouveau_channel *chan,
+                        struct nv50_miptree *dst, unsigned dst_level,
+                        unsigned dx, unsigned dy, unsigned dz,
+                        struct nv50_miptree *src, unsigned src_level,
+                        unsigned sx, unsigned sy, unsigned sz,
+                        unsigned w, unsigned h)
 {
-       struct nouveau_channel *chan = screen->eng2d->channel;
-       struct nouveau_grobj *eng2d = screen->eng2d;
-       int ret;
-
-       ret = MARK_RING(chan, 2*16 + 32, 4);
-       if (ret)
-               return ret;
-
-       ret = nv50_surface_set(screen, dst, 1);
-       if (ret)
-               return ret;
-
-       ret = nv50_surface_set(screen, src, 0);
-       if (ret)
-               return ret;
-
-       BEGIN_RING(chan, eng2d, 0x088c, 1);
-       OUT_RING  (chan, 0);
-       BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4);
-       OUT_RING  (chan, dx);
-       OUT_RING  (chan, dy);
-       OUT_RING  (chan, w);
-       OUT_RING  (chan, h);
-       BEGIN_RING(chan, eng2d, 0x08c0, 4);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, 1);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, 1);
-       BEGIN_RING(chan, eng2d, 0x08d0, 4);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, sx);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, sy);
-
-       return 0;
+   int ret;
+
+   ret = MARK_RING(chan, 2 * 16 + 32, 4);
+   if (ret)
+      return ret;
+
+   ret = nv50_2d_texture_set(chan, 1, dst, dst_level, dz);
+   if (ret)
+      return ret;
+
+   ret = nv50_2d_texture_set(chan, 0, src, src_level, sz);
+   if (ret)
+      return ret;
+
+   /* 0/1 = CENTER/CORNER, 10/00 = POINT/BILINEAR */
+   BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1);
+   OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4);
+   OUT_RING  (chan, dx);
+   OUT_RING  (chan, dy);
+   OUT_RING  (chan, w);
+   OUT_RING  (chan, h);
+   BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, 1);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, 1);
+   BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, sx);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, sy);
+
+   return 0;
 }
 
 static void
-nv50_surface_copy(struct pipe_context *pipe,
-                 struct pipe_resource *dest, unsigned dst_level,
-                 unsigned destx, unsigned desty, unsigned destz,
-                 struct pipe_resource *src, unsigned src_level,
-                 const struct pipe_box *src_box)
+nv50_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)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nv50_screen *screen = nv50->screen;
-       struct pipe_surface *ps_dst, *ps_src, surf_tmpl;
-
-
-       assert((src->format == dest->format) ||
-              (nv50_2d_format_faithful(src->format) &&
-               nv50_2d_format_faithful(dest->format)));
-       assert(src_box->depth == 1);
-
-       memset(&surf_tmpl, 0, sizeof(surf_tmpl));
-       surf_tmpl.format = src->format;
-       surf_tmpl.usage = 0; /* no bind flag - not a surface */
-       surf_tmpl.u.tex.level = src_level;
-       surf_tmpl.u.tex.first_layer = src_box->z;
-       surf_tmpl.u.tex.last_layer = src_box->z;
-       /* XXX really need surfaces here? */
-       ps_src = nv50_miptree_surface_new(pipe, src, &surf_tmpl);
-       surf_tmpl.format = dest->format;
-       surf_tmpl.usage = 0; /* no bind flag - not a surface */
-       surf_tmpl.u.tex.level = dst_level;
-       surf_tmpl.u.tex.first_layer = destz;
-       surf_tmpl.u.tex.last_layer = destz;
-       ps_dst = nv50_miptree_surface_new(pipe, dest, &surf_tmpl);
-
-       nv50_surface_do_copy(screen, ps_dst, destx, desty, ps_src, src_box->x,
-                            src_box->y, src_box->width, src_box->height);
-
-       nv50_miptree_surface_del(pipe, ps_src);
-       nv50_miptree_surface_del(pipe, ps_dst);
+   struct nv50_screen *screen = nv50_context(pipe)->screen;
+   int ret;
+   unsigned dst_layer = dstz, src_layer = src_box->z;
+
+   assert((src->format == dst->format) ||
+          (nv50_2d_format_faithful(src->format) &&
+           nv50_2d_format_faithful(dst->format)));
+
+   for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
+      ret = nv50_2d_texture_do_copy(screen->base.channel,
+                                    nv50_miptree(dst), dst_level,
+                                    dstx, dsty, dst_layer,
+                                    nv50_miptree(src), src_level,
+                                    src_box->x, src_box->y, src_layer,
+                                    src_box->width, src_box->height);
+      if (ret)
+         return;
+   }
 }
 
 static void
 nv50_clear_render_target(struct pipe_context *pipe,
-                        struct pipe_surface *dst,
-                        const float *rgba,
-                        unsigned dstx, unsigned dsty,
-                        unsigned width, unsigned height)
+                         struct pipe_surface *dst,
+                         const float *rgba,
+                         unsigned dstx, unsigned dsty,
+                         unsigned width, unsigned height)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nv50_screen *screen = nv50->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *tesla = screen->tesla;
-       struct nv50_miptree *mt = nv50_miptree(dst->texture);
-       struct nouveau_bo *bo = mt->base.bo;
-
-       BEGIN_RING(chan, tesla, NV50TCL_CLEAR_COLOR(0), 4);
-       OUT_RINGf (chan, rgba[0]);
-       OUT_RINGf (chan, rgba[1]);
-       OUT_RINGf (chan, rgba[2]);
-       OUT_RINGf (chan, rgba[3]);
-
-       if (MARK_RING(chan, 18, 2))
-               return;
-
-       BEGIN_RING(chan, tesla, NV50TCL_RT_CONTROL, 1);
-       OUT_RING  (chan, 1);
-       BEGIN_RING(chan, tesla, NV50TCL_RT_ADDRESS_HIGH(0), 5);
-       OUT_RELOCh(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RING  (chan, nv50_format_table[dst->format].rt);
-       OUT_RING  (chan, mt->level[dst->u.tex.level].tile_mode << 4);
-       OUT_RING  (chan, 0);
-       BEGIN_RING(chan, tesla, NV50TCL_RT_HORIZ(0), 2);
-       OUT_RING  (chan, dst->width);
-       OUT_RING  (chan, dst->height);
-       BEGIN_RING(chan, tesla, NV50TCL_RT_ARRAY_MODE, 1);
-       OUT_RING  (chan, 1);
-
-       /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
-
-       BEGIN_RING(chan, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2);
-       OUT_RING  (chan, (width << 16) | dstx);
-       OUT_RING  (chan, (height << 16) | dsty);
-
-       BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
-       OUT_RING  (chan, 0x3c);
-
-       nv50->dirty |= NV50_NEW_FRAMEBUFFER;
+   struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_screen *screen = nv50->screen;
+   struct nouveau_channel *chan = screen->base.channel;
+   struct nv50_miptree *mt = nv50_miptree(dst->texture);
+   struct nv50_surface *sf = nv50_surface(dst);
+   struct nouveau_bo *bo = mt->base.bo;
+
+   BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
+   OUT_RINGf (chan, rgba[0]);
+   OUT_RINGf (chan, rgba[1]);
+   OUT_RINGf (chan, rgba[2]);
+   OUT_RINGf (chan, rgba[3]);
+
+   if (MARK_RING(chan, 18, 2))
+      return;
+
+   BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
+   OUT_RING  (chan, 1);
+   BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 5);
+   OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+   OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+   OUT_RING  (chan, nv50_format_table[dst->format].rt);
+   OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
+   OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_3D(RT_HORIZ(0)), 2);
+   OUT_RING  (chan, sf->width);
+   OUT_RING  (chan, sf->height);
+   BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
+   OUT_RING  (chan, 1);
+
+   /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
+
+   BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
+   OUT_RING  (chan, (width << 16) | dstx);
+   OUT_RING  (chan, (height << 16) | dsty);
+
+   BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
+   OUT_RING  (chan, 0x3c);
+
+   nv50->dirty |= NV50_NEW_FRAMEBUFFER;
 }
 
 static void
 nv50_clear_depth_stencil(struct pipe_context *pipe,
-                        struct pipe_surface *dst,
-                        unsigned clear_flags,
-                        double depth,
-                        unsigned stencil,
-                        unsigned dstx, unsigned dsty,
-                        unsigned width, unsigned height)
+                         struct pipe_surface *dst,
+                         unsigned clear_flags,
+                         double depth,
+                         unsigned stencil,
+                         unsigned dstx, unsigned dsty,
+                         unsigned width, unsigned height)
+{
+   struct nv50_context *nv50 = nv50_context(pipe);
+   struct nv50_screen *screen = nv50->screen;
+   struct nouveau_channel *chan = screen->base.channel;
+   struct nv50_miptree *mt = nv50_miptree(dst->texture);
+   struct nv50_surface *sf = nv50_surface(dst);
+   struct nouveau_bo *bo = mt->base.bo;
+   uint32_t mode = 0;
+
+   if (clear_flags & PIPE_CLEAR_DEPTH) {
+      BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
+      OUT_RINGf (chan, depth);
+      mode |= NV50_3D_CLEAR_BUFFERS_Z;
+   }
+
+   if (clear_flags & PIPE_CLEAR_STENCIL) {
+      BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
+      OUT_RING  (chan, stencil & 0xff);
+      mode |= NV50_3D_CLEAR_BUFFERS_S;
+   }
+
+   if (MARK_RING(chan, 17, 2))
+      return;
+
+   BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
+   OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+   OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+   OUT_RING  (chan, nv50_format_table[dst->format].rt);
+   OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
+   OUT_RING  (chan, 0);
+   BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
+   OUT_RING  (chan, 1);
+   BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
+   OUT_RING  (chan, sf->width);
+   OUT_RING  (chan, sf->height);
+   OUT_RING  (chan, (1 << 16) | 1);
+
+   BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
+   OUT_RING  (chan, (width << 16) | dstx);
+   OUT_RING  (chan, (height << 16) | dsty);
+
+   BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
+   OUT_RING  (chan, mode);
+
+   nv50->dirty |= NV50_NEW_FRAMEBUFFER;
+}
+
+void
+nv50_clear(struct pipe_context *pipe, unsigned buffers,
+           const float *rgba, double depth, unsigned stencil)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nv50_screen *screen = nv50->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *tesla = screen->tesla;
-       struct nv50_miptree *mt = nv50_miptree(dst->texture);
-       struct nouveau_bo *bo = mt->base.bo;
-       uint32_t mode = 0;
-
-       if (clear_flags & PIPE_CLEAR_DEPTH) {
-               BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1);
-               OUT_RINGf (chan, depth);
-               mode |= NV50TCL_CLEAR_BUFFERS_Z;
-       }
-
-       if (clear_flags & PIPE_CLEAR_STENCIL) {
-               BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1);
-               OUT_RING  (chan, stencil & 0xff);
-               mode |= NV50TCL_CLEAR_BUFFERS_S;
-       }
-
-       if (MARK_RING(chan, 17, 2))
-               return;
-
-       BEGIN_RING(chan, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5);
-       OUT_RELOCh(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(chan, bo, ((struct nv50_surface *)dst)->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RING  (chan, nv50_format_table[dst->format].rt);
-       OUT_RING  (chan, mt->level[dst->u.tex.level].tile_mode << 4);
-       OUT_RING  (chan, 0);
-       BEGIN_RING(chan, tesla, NV50TCL_ZETA_ENABLE, 1);
-       OUT_RING  (chan, 1);
-       BEGIN_RING(chan, tesla, NV50TCL_ZETA_HORIZ, 3);
-       OUT_RING  (chan, dst->width);
-       OUT_RING  (chan, dst->height);
-       OUT_RING  (chan, (1 << 16) | 1);
-
-       BEGIN_RING(chan, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2);
-       OUT_RING  (chan, (width << 16) | dstx);
-       OUT_RING  (chan, (height << 16) | dsty);
-
-       BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
-       OUT_RING  (chan, mode);
-
-       nv50->dirty |= NV50_NEW_FRAMEBUFFER;
+   struct nv50_context *nv50 = nv50_context(pipe);
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct pipe_framebuffer_state *fb = &nv50->framebuffer;
+   unsigned i;
+   const unsigned dirty = nv50->dirty;
+   uint32_t mode = 0;
+
+   /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
+   nv50->dirty &= NV50_NEW_FRAMEBUFFER;
+   if (!nv50_state_validate(nv50))
+      return;
+
+   if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
+      BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
+      OUT_RINGf (chan, rgba[0]);
+      OUT_RINGf (chan, rgba[1]);
+      OUT_RINGf (chan, rgba[2]);
+      OUT_RINGf (chan, rgba[3]);
+      mode =
+         NV50_3D_CLEAR_BUFFERS_R | NV50_3D_CLEAR_BUFFERS_G |
+         NV50_3D_CLEAR_BUFFERS_B | NV50_3D_CLEAR_BUFFERS_A;
+   }
+
+   if (buffers & PIPE_CLEAR_DEPTH) {
+      BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
+      OUT_RING  (chan, fui(depth));
+      mode |= NV50_3D_CLEAR_BUFFERS_Z;
+   }
+
+   if (buffers & PIPE_CLEAR_STENCIL) {
+      BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
+      OUT_RING  (chan, stencil & 0xff);
+      mode |= NV50_3D_CLEAR_BUFFERS_S;
+   }
+
+   BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
+   OUT_RING  (chan, mode);
+
+   for (i = 1; i < fb->nr_cbufs; i++) {
+      BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
+      OUT_RING  (chan, (i << 6) | 0x3c);
+   }
+
+   nv50->dirty = dirty & ~NV50_NEW_FRAMEBUFFER;
 }
 
 void
 nv50_init_surface_functions(struct nv50_context *nv50)
 {
-       nv50->pipe.resource_copy_region = nv50_surface_copy;
-       nv50->pipe.clear_render_target = nv50_clear_render_target;
-       nv50->pipe.clear_depth_stencil = nv50_clear_depth_stencil;
+   nv50->pipe.resource_copy_region = nv50_resource_copy_region;
+   nv50->pipe.clear_render_target = nv50_clear_render_target;
+   nv50->pipe.clear_depth_stencil = nv50_clear_depth_stencil;
 }
 
 
index 9243f9edceda320bb2c3c448f625fe2aa073ac98..93e74ca0597098be79ad94ebd284c4f2941c3d93 100644 (file)
  */
 
 #include "nv50_context.h"
-#include "nv50_texture.h"
 #include "nv50_resource.h"
-
-#include "nouveau/nouveau_stateobj.h"
-#include "nouveau/nouveau_reloc.h"
+#include "nv50_texture.xml.h"
+#include "nv50_defs.xml.h"
 
 #include "util/u_format.h"
 
 static INLINE uint32_t
 nv50_tic_swizzle(uint32_t tc, unsigned swz)
 {
-       switch (swz) {
-       case PIPE_SWIZZLE_RED:
-               return (tc & NV50TIC_0_0_MAPR_MASK) >> NV50TIC_0_0_MAPR_SHIFT;
-       case PIPE_SWIZZLE_GREEN:
-               return (tc & NV50TIC_0_0_MAPG_MASK) >> NV50TIC_0_0_MAPG_SHIFT;
-       case PIPE_SWIZZLE_BLUE:
-               return (tc & NV50TIC_0_0_MAPB_MASK) >> NV50TIC_0_0_MAPB_SHIFT;
-       case PIPE_SWIZZLE_ALPHA:
-               return (tc & NV50TIC_0_0_MAPA_MASK) >> NV50TIC_0_0_MAPA_SHIFT;
-       case PIPE_SWIZZLE_ONE:
-               return 7;
-       case PIPE_SWIZZLE_ZERO:
-       default:
-               return 0;
-       }
+   switch (swz) {
+   case PIPE_SWIZZLE_RED:
+      return (tc & NV50_TIC_0_MAPR__MASK) >> NV50_TIC_0_MAPR__SHIFT;
+   case PIPE_SWIZZLE_GREEN:
+      return (tc & NV50_TIC_0_MAPG__MASK) >> NV50_TIC_0_MAPG__SHIFT;
+   case PIPE_SWIZZLE_BLUE:
+      return (tc & NV50_TIC_0_MAPB__MASK) >> NV50_TIC_0_MAPB__SHIFT;
+   case PIPE_SWIZZLE_ALPHA:
+      return (tc & NV50_TIC_0_MAPA__MASK) >> NV50_TIC_0_MAPA__SHIFT;
+   case PIPE_SWIZZLE_ONE:
+      return NV50_TIC_MAP_ONE;
+   case PIPE_SWIZZLE_ZERO:
+   default:
+      return NV50_TIC_MAP_ZERO;
+   }
 }
 
-boolean
-nv50_tex_construct(struct nv50_sampler_view *view)
+struct pipe_sampler_view *
+nv50_create_sampler_view(struct pipe_context *pipe,
+                         struct pipe_resource *texture,
+                         const struct pipe_sampler_view *templ)
 {
-       const struct util_format_description *desc;
-       struct nv50_miptree *mt = nv50_miptree(view->pipe.texture);
-       uint32_t swz[4], *tic = view->tic;
-
-       tic[0] = nv50_format_table[view->pipe.format].tic;
-
-       swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r);
-       swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g);
-       swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b);
-       swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a);
-       view->tic[0] = (tic[0] &  ~NV50TIC_0_0_SWIZZLE_MASK) |
-               (swz[0] << NV50TIC_0_0_MAPR_SHIFT) |
-               (swz[1] << NV50TIC_0_0_MAPG_SHIFT) |
-               (swz[2] << NV50TIC_0_0_MAPB_SHIFT) |
-               (swz[3] << NV50TIC_0_0_MAPA_SHIFT);
-
-       tic[2] = 0x50001000;
-       tic[2] |= ((mt->base.bo->tile_mode & 0x0f) << 22) |
-                 ((mt->base.bo->tile_mode & 0xf0) << 21);
-
-       desc = util_format_description(mt->base.base.format);
-       if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
-               tic[2] |= NV50TIC_0_2_COLORSPACE_SRGB;
-
-       switch (mt->base.base.target) {
-       case PIPE_TEXTURE_1D:
-               tic[2] |= NV50TIC_0_2_TARGET_1D;
-               break;
-       case PIPE_TEXTURE_2D:
-               tic[2] |= NV50TIC_0_2_TARGET_2D;
-               break;
-       case PIPE_TEXTURE_RECT:
-               tic[2] |= NV50TIC_0_2_TARGET_RECT;
-               break;
-       case PIPE_TEXTURE_3D:
-               tic[2] |= NV50TIC_0_2_TARGET_3D;
-               break;
-       case PIPE_TEXTURE_CUBE:
-               tic[2] |= NV50TIC_0_2_TARGET_CUBE;
-               break;
-       default:
-               NOUVEAU_ERR("invalid texture target: %d\n",
-                           mt->base.base.target);
-               return FALSE;
-       }
-
-       tic[3] = 0x00300000;
-
-       tic[4] = (1 << 31) | mt->base.base.width0;
-       tic[5] = (mt->base.base.last_level << 28) |
-               (mt->base.base.depth0 << 16) | mt->base.base.height0;
-
-       tic[6] = 0x03000000;
-
-       tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
-
-       return TRUE;
+   const struct util_format_description *desc;
+   uint32_t *tic;
+   uint32_t swz[4];
+   uint32_t depth;
+   struct nv50_tic_entry *view;
+   struct nv50_miptree *mt = nv50_miptree(texture);
+
+   view = MALLOC_STRUCT(nv50_tic_entry);
+   if (!view)
+      return NULL;
+
+   view->pipe = *templ;
+   view->pipe.reference.count = 1;
+   view->pipe.texture = NULL;
+   view->pipe.context = pipe;
+
+   view->id = -1;
+
+   pipe_resource_reference(&view->pipe.texture, texture);
+
+   tic = &view->tic[0];
+
+   desc = util_format_description(mt->base.base.format);
+
+   /* TIC[0] */
+
+   tic[0] = nv50_format_table[view->pipe.format].tic;
+
+   swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r);
+   swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g);
+   swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b);
+   swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a);
+   tic[0] = (tic[0] & ~NV50_TIC_0_SWIZZLE__MASK) |
+      (swz[0] << NV50_TIC_0_MAPR__SHIFT) |
+      (swz[1] << NV50_TIC_0_MAPG__SHIFT) |
+      (swz[2] << NV50_TIC_0_MAPB__SHIFT) |
+      (swz[3] << NV50_TIC_0_MAPA__SHIFT);
+
+   /* tic[1] = mt->base.bo->offset; */
+   tic[2] = /* mt->base.bo->offset >> 32 */ 0;
+
+   tic[2] |= 0x10001000 | /* NV50_TIC_2_NO_BORDER */ 0x40000000;
+
+   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
+      tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
+
+   if (mt->base.base.target != PIPE_TEXTURE_RECT)
+      tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
+
+   tic[2] |=
+      ((mt->base.bo->tile_mode & 0x0f) << (22 - 0)) |
+      ((mt->base.bo->tile_mode & 0xf0) << (25 - 4));
+
+   depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
+
+   switch (mt->base.base.target) {
+   case PIPE_TEXTURE_1D:
+      tic[2] |= NV50_TIC_2_TARGET_1D;
+      break;
+   case PIPE_TEXTURE_2D:
+      tic[2] |= NV50_TIC_2_TARGET_2D;
+      break;
+   case PIPE_TEXTURE_RECT:
+      tic[2] |= NV50_TIC_2_TARGET_RECT;
+      break;
+   case PIPE_TEXTURE_3D:
+      tic[2] |= NV50_TIC_2_TARGET_3D;
+      break;
+   case PIPE_TEXTURE_CUBE:
+      depth /= 6;
+      if (depth > 1)
+         tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
+      else
+         tic[2] |= NV50_TIC_2_TARGET_CUBE;
+      break;
+   case PIPE_TEXTURE_1D_ARRAY:
+      tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY;
+      break;
+   case PIPE_TEXTURE_2D_ARRAY:
+      tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY;
+      break;
+   case PIPE_BUFFER:
+      tic[2] |= NV50_TIC_2_TARGET_BUFFER | /* NV50_TIC_2_LINEAR */ (1 << 18);
+   default:
+      NOUVEAU_ERR("invalid texture target: %d\n", mt->base.base.target);
+      return FALSE;
+   }
+
+   if (mt->base.base.target == PIPE_BUFFER)
+      tic[3] = mt->base.base.width0;
+   else
+      tic[3] = 0x00300000;
+
+   tic[4] = (1 << 31) | mt->base.base.width0;
+
+   tic[5] = mt->base.base.height0 & 0xffff;
+   tic[5] |= depth << 16;
+   tic[5] |= mt->base.base.last_level << 28;
+
+   tic[6] = 0x03000000;
+
+   tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
+
+   return &view->pipe;
 }
 
-static int
-nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so,
-                      unsigned p)
+static boolean
+nv50_validate_tic(struct nv50_context *nv50, int s)
 {
-       struct nouveau_grobj *eng2d = nv50->screen->eng2d;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       unsigned unit, j;
-
-       const unsigned rll = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW;
-       const unsigned rlh = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH
-               | NOUVEAU_BO_OR;
-
-       nv50_so_init_sifc(nv50, so, nv50->screen->tic, NOUVEAU_BO_VRAM,
-                         p * (32 * 8 * 4), nv50->sampler_view_nr[p] * 8 * 4);
-
-       for (unit = 0; unit < nv50->sampler_view_nr[p]; ++unit) {
-               struct nv50_sampler_view *view =
-                       nv50_sampler_view(nv50->sampler_views[p][unit]);
-
-               so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8);
-               if (view) {
-                       uint32_t tic2 = view->tic[2];
-                       struct nv50_miptree *mt =
-                               nv50_miptree(view->pipe.texture);
-
-                       tic2 &= ~NV50TIC_0_2_NORMALIZED_COORDS;
-                       if (nv50->sampler[p][unit]->normalized)
-                               tic2 |= NV50TIC_0_2_NORMALIZED_COORDS;
-                       view->tic[2] = tic2;
-
-                       so_data  (so, view->tic[0]);
-                       so_reloc (so, mt->base.bo, 0, rll, 0, 0);
-                       so_reloc (so, mt->base.bo, 0, rlh, tic2, tic2);
-                       so_datap (so, &view->tic[3], 5);
-
-                       /* Set TEX insn $t src binding $unit in program type p
-                        * to TIC, TSC entry (32 * p + unit), mark valid (1).
-                        */
-                       so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);
-                       so_data  (so, ((32 * p + unit) << 9) | (unit << 1) | 1);
-               } else {
-                       for (j = 0; j < 8; ++j)
-                               so_data(so, 0);
-                       so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);
-                       so_data  (so, (unit << 1) | 0);
-               }
-       }
-
-       for (; unit < nv50->state.sampler_view_nr[p]; unit++) {
-               /* Make other bindings invalid. */
-               so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);
-               so_data  (so, (unit << 1) | 0);
-       }
-
-       nv50->state.sampler_view_nr[p] = nv50->sampler_view_nr[p];
-       return TRUE;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_bo *txc = nv50->screen->txc;
+   unsigned i;
+   boolean need_flush = FALSE;
+
+   for (i = 0; i < nv50->num_textures[s]; ++i) {
+      struct nv50_tic_entry *tic = nv50_tic_entry(nv50->textures[s][i]);
+      struct nv50_resource *res;
+
+      if (!tic) {
+         BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
+         OUT_RING  (chan, (i << 1) | 0);
+         continue;
+      }
+      res = &nv50_miptree(tic->pipe.texture)->base;
+
+      if (tic->id < 0) {
+         tic->id = nv50_screen_tic_alloc(nv50->screen, tic);
+
+         MARK_RING (chan, 24 + 8, 4);
+         BEGIN_RING(chan, RING_2D(DST_FORMAT), 2);
+         OUT_RING  (chan, NV50_SURFACE_FORMAT_R8_UNORM);
+         OUT_RING  (chan, 1);
+         BEGIN_RING(chan, RING_2D(DST_PITCH), 5);
+         OUT_RING  (chan, 262144);
+         OUT_RING  (chan, 65536);
+         OUT_RING  (chan, 1);
+         OUT_RELOCh(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+         OUT_RELOCl(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+         BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2);
+         OUT_RING  (chan, 0);
+         OUT_RING  (chan, NV50_SURFACE_FORMAT_R8_UNORM);
+         BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10);
+         OUT_RING  (chan, 32);
+         OUT_RING  (chan, 1);
+         OUT_RING  (chan, 0);
+         OUT_RING  (chan, 1);
+         OUT_RING  (chan, 0);
+         OUT_RING  (chan, 1);
+         OUT_RING  (chan, 0);
+         OUT_RING  (chan, tic->id * 32);
+         OUT_RING  (chan, 0);
+         OUT_RING  (chan, 0);
+         BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), 8);
+         OUT_RING  (chan, tic->tic[0]);
+         OUT_RELOCl(chan, res->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+         OUT_RELOC (chan, res->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
+                    NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, tic->tic[2], tic->tic[2]);
+         OUT_RINGp (chan, &tic->tic[3], 5);
+
+         need_flush = TRUE;
+      }
+      nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
+
+      nv50_bufctx_add_resident(nv50, NV50_BUFCTX_TEXTURES, res,
+                               NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+
+      BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
+      OUT_RING  (chan, (tic->id << 9) | (i << 1) | 1);
+   }
+   for (; i < nv50->state.num_textures[s]; ++i) {
+      BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
+      OUT_RING  (chan, (i << 1) | 0);
+   }
+   nv50->state.num_textures[s] = nv50->num_textures[s];
+
+   return need_flush;
 }
 
-static void
-nv50_emit_texture_relocs(struct nv50_context *nv50, int prog)
+void nv50_validate_textures(struct nv50_context *nv50)
 {
-       struct nouveau_channel *chan = nv50->screen->base.channel;
-       struct nouveau_bo *tic = nv50->screen->tic;
-       int unit;
-
-       for (unit = 0; unit < nv50->sampler_view_nr[prog]; unit++) {
-               struct nv50_sampler_view *view;
-               struct nv50_miptree *mt;
-               const unsigned base = ((prog * 32) + unit) * 32;
-
-               view = nv50_sampler_view(nv50->sampler_views[prog][unit]);
-               if (!view)
-                       continue;
-               mt = nv50_miptree(view->pipe.texture);
-
-               nouveau_reloc_emit(chan, tic, base + 4, NULL, mt->base.bo, 0, 0,
-                                  NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
-                                  NOUVEAU_BO_LOW, 0, 0);
-               nouveau_reloc_emit(chan, tic, base + 8, NULL, mt->base.bo, 0, 0,
-                                  NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
-                                  NOUVEAU_BO_HIGH, view->tic[2], view->tic[2]);
-       }
+   boolean need_flush;
+
+   need_flush  = nv50_validate_tic(nv50, 0);
+   need_flush |= nv50_validate_tic(nv50, 2);
+
+   if (need_flush) {
+      BEGIN_RING(nv50->screen->base.channel, RING_3D(TIC_FLUSH), 1);
+      OUT_RING  (nv50->screen->base.channel, 0);
+   }
 }
 
-void
-nv50_tex_relocs(struct nv50_context *nv50)
+static boolean
+nv50_validate_tsc(struct nv50_context *nv50, int s)
 {
-       nv50_emit_texture_relocs(nv50, 2); /* FP */
-       nv50_emit_texture_relocs(nv50, 0); /* VP */
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   unsigned i;
+   boolean need_flush = FALSE;
+
+   for (i = 0; i < nv50->num_samplers[s]; ++i) {
+      struct nv50_tsc_entry *tsc = nv50_tsc_entry(nv50->samplers[s][i]);
+
+      if (!tsc) {
+         BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
+         OUT_RING  (chan, (i << 4) | 0);
+         continue;
+      }
+      if (tsc->id < 0) {
+         tsc->id = nv50_screen_tsc_alloc(nv50->screen, tsc);
+
+         nv50_sifc_linear_u8(nv50, nv50->screen->txc, NOUVEAU_BO_VRAM,
+                             65536 + tsc->id * 32, 32, tsc->tsc);
+         need_flush = TRUE;
+      }
+      nv50->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
+
+      BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
+      OUT_RING  (chan, (tsc->id << 12) | (i << 4) | 1);
+   }
+   for (; i < nv50->state.num_samplers[s]; ++i) {
+      BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
+      OUT_RING  (chan, (i << 4) | 0);
+   }
+   nv50->state.num_samplers[s] = nv50->num_samplers[s];
+
+   return need_flush;
 }
 
-struct nouveau_stateobj *
-nv50_tex_validate(struct nv50_context *nv50)
+void nv50_validate_samplers(struct nv50_context *nv50)
 {
-       struct nouveau_stateobj *so;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       unsigned p, m = 0, d = 0, r = 0;
-
-       for (p = 0; p < 3; ++p) {
-               unsigned nr = MAX2(nv50->sampler_view_nr[p],
-                                  nv50->state.sampler_view_nr[p]);
-               m += nr;
-               d += nr;
-               r += nv50->sampler_view_nr[p];
-       }
-       m = m * 2 + 3 * 4 + 1;
-       d = d * 9 + 3 * 19 + 1;
-       r = r * 2 + 3 * 2;
-
-       so = so_new(m, d, r);
-
-       if (nv50_validate_textures(nv50, so, 0) == FALSE ||
-           nv50_validate_textures(nv50, so, 2) == FALSE) {
-               so_ref(NULL, &so);
-
-               NOUVEAU_ERR("failed tex validate\n");
-               return NULL;
-       }
-
-       so_method(so, tesla, 0x1330, 1); /* flush TIC */
-       so_data  (so, 0);
-
-       return so;
+   boolean need_flush;
+
+   need_flush  = nv50_validate_tsc(nv50, 0);
+   need_flush |= nv50_validate_tsc(nv50, 2);
+
+   if (need_flush) {
+      BEGIN_RING(nv50->screen->base.channel, RING_3D(TSC_FLUSH), 1);
+      OUT_RING  (nv50->screen->base.channel, 0);
+   }
 }
diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h
deleted file mode 100644 (file)
index b493994..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-#ifndef __NV50_TEXTURE_H__
-#define __NV50_TEXTURE_H__
-
-/* It'd be really nice to have these in nouveau_class.h generated by
- * renouveau like the rest of the object header - but not sure it can
- * handle non-object stuff nicely - need to look into it.
- */
-
-/* Texture image control block */
-#define NV50TIC_0_0_SWIZZLE_MASK                                  0x3ffc0000
-#define NV50TIC_0_0_MAPA_MASK                                     0x38000000
-#define NV50TIC_0_0_MAPA_SHIFT                                            27
-#define NV50TIC_0_0_MAPA_ZERO                                     0x00000000
-#define NV50TIC_0_0_MAPA_C0                                       0x10000000
-#define NV50TIC_0_0_MAPA_C1                                       0x18000000
-#define NV50TIC_0_0_MAPA_C2                                       0x20000000
-#define NV50TIC_0_0_MAPA_C3                                       0x28000000
-#define NV50TIC_0_0_MAPA_ONE                                      0x38000000
-#define NV50TIC_0_0_MAPB_MASK                                     0x07000000
-#define NV50TIC_0_0_MAPB_SHIFT                                            24
-#define NV50TIC_0_0_MAPB_ZERO                                     0x00000000
-#define NV50TIC_0_0_MAPB_C0                                       0x02000000
-#define NV50TIC_0_0_MAPB_C1                                       0x03000000
-#define NV50TIC_0_0_MAPB_C2                                       0x04000000
-#define NV50TIC_0_0_MAPB_C3                                       0x05000000
-#define NV50TIC_0_0_MAPB_ONE                                      0x07000000
-#define NV50TIC_0_0_MAPG_MASK                                     0x00e00000
-#define NV50TIC_0_0_MAPG_SHIFT                                            21
-#define NV50TIC_0_0_MAPG_ZERO                                     0x00000000
-#define NV50TIC_0_0_MAPG_C0                                       0x00400000
-#define NV50TIC_0_0_MAPG_C1                                       0x00600000
-#define NV50TIC_0_0_MAPG_C2                                       0x00800000
-#define NV50TIC_0_0_MAPG_C3                                       0x00a00000
-#define NV50TIC_0_0_MAPG_ONE                                      0x00e00000
-#define NV50TIC_0_0_MAPR_MASK                                     0x001c0000
-#define NV50TIC_0_0_MAPR_SHIFT                                            18
-#define NV50TIC_0_0_MAPR_ZERO                                     0x00000000
-#define NV50TIC_0_0_MAPR_C0                                       0x00080000
-#define NV50TIC_0_0_MAPR_C1                                       0x000c0000
-#define NV50TIC_0_0_MAPR_C2                                       0x00100000
-#define NV50TIC_0_0_MAPR_C3                                       0x00140000
-#define NV50TIC_0_0_MAPR_ONE                                      0x001c0000
-#define NV50TIC_0_0_TYPEA_MASK                                    0x00038000
-#define NV50TIC_0_0_TYPEA_UNORM                                   0x00010000
-#define NV50TIC_0_0_TYPEA_SNORM                                   0x00008000
-#define NV50TIC_0_0_TYPEA_SINT                                    0x00018000
-#define NV50TIC_0_0_TYPEA_UINT                                    0x00020000
-#define NV50TIC_0_0_TYPEA_SSCALED                                 0x00028000
-#define NV50TIC_0_0_TYPEA_USCALED                                 0x00030000
-#define NV50TIC_0_0_TYPEA_FLOAT                                   0x00038000
-#define NV50TIC_0_0_TYPEB_MASK                                    0x00007000
-#define NV50TIC_0_0_TYPEB_UNORM                                   0x00002000
-#define NV50TIC_0_0_TYPEB_SNORM                                   0x00001000
-#define NV50TIC_0_0_TYPEB_SINT                                    0x00003000
-#define NV50TIC_0_0_TYPEB_UINT                                    0x00004000
-#define NV50TIC_0_0_TYPEB_SSCALED                                 0x00005000
-#define NV50TIC_0_0_TYPEB_USCALED                                 0x00006000
-#define NV50TIC_0_0_TYPEB_FLOAT                                   0x00007000
-#define NV50TIC_0_0_TYPEG_MASK                                    0x00000e00
-#define NV50TIC_0_0_TYPEG_UNORM                                   0x00000400
-#define NV50TIC_0_0_TYPEG_SNORM                                   0x00000200
-#define NV50TIC_0_0_TYPEG_SINT                                    0x00000600
-#define NV50TIC_0_0_TYPEG_UINT                                    0x00000800
-#define NV50TIC_0_0_TYPEG_SSCALED                                 0x00000a00
-#define NV50TIC_0_0_TYPEG_USCALED                                 0x00000c00
-#define NV50TIC_0_0_TYPEG_FLOAT                                   0x00000e00
-#define NV50TIC_0_0_TYPER_MASK                                    0x000001c0
-#define NV50TIC_0_0_TYPER_UNORM                                   0x00000080
-#define NV50TIC_0_0_TYPER_SNORM                                   0x00000040
-#define NV50TIC_0_0_TYPER_SINT                                    0x000000c0
-#define NV50TIC_0_0_TYPER_UINT                                    0x00000100
-#define NV50TIC_0_0_TYPER_SSCALED                                 0x00000140
-#define NV50TIC_0_0_TYPER_USCALED                                 0x00000180
-#define NV50TIC_0_0_TYPER_FLOAT                                   0x000001c0
-#define NV50TIC_0_0_FMT_MASK                                      0x0000003f
-#define NV50TIC_0_0_FMT_32_32_32_32                               0x00000001
-#define NV50TIC_0_0_FMT_16_16_16_16                               0x00000003
-#define NV50TIC_0_0_FMT_32_32                                     0x00000004
-#define NV50TIC_0_0_FMT_8_8_8_8                                   0x00000008
-#define NV50TIC_0_0_FMT_2_10_10_10                                0x00000009
-#define NV50TIC_0_0_FMT_16_16                                     0x0000000c
-#define NV50TIC_0_0_FMT_32                                        0x0000000f
-#define NV50TIC_0_0_FMT_4_4_4_4                                   0x00000012
-/* #define NV50TIC_0_0_FMT_1_5_5_5                                0x00000013 */
-#define NV50TIC_0_0_FMT_1_5_5_5                                   0x00000014
-#define NV50TIC_0_0_FMT_5_6_5                                     0x00000015
-#define NV50TIC_0_0_FMT_8_8                                       0x00000018
-#define NV50TIC_0_0_FMT_16                                        0x0000001b
-#define NV50TIC_0_0_FMT_8                                         0x0000001d
-#define NV50TIC_0_0_FMT_5_9_9_9                                   0x00000020
-#define NV50TIC_0_0_FMT_10_11_11                                  0x00000021
-#define NV50TIC_0_0_FMT_DXT1                                      0x00000024
-#define NV50TIC_0_0_FMT_DXT3                                      0x00000025
-#define NV50TIC_0_0_FMT_DXT5                                      0x00000026
-#define NV50TIC_0_0_FMT_RGTC1                                     0x00000027
-#define NV50TIC_0_0_FMT_RGTC2                                     0x00000028
-#define NV50TIC_0_0_FMT_24_8                                      0x00000029
-#define NV50TIC_0_0_FMT_8_24                                      0x0000002a
-#define NV50TIC_0_0_FMT_32_DEPTH                                  0x0000002f
-#define NV50TIC_0_0_FMT_32_8                                      0x00000030
-#define NV50TIC_0_0_FMT_16_DEPTH                                  0x0000003a
-
-#define NV50TIC_0_1_OFFSET_LOW_MASK                               0xffffffff
-#define NV50TIC_0_1_OFFSET_LOW_SHIFT                                       0
-
-#define NV50TIC_0_2_COLORSPACE_SRGB                               0x00000400
-#define NV50TIC_0_2_TARGET_1D                                     0x00000000
-#define NV50TIC_0_2_TARGET_2D                                     0x00004000
-#define NV50TIC_0_2_TARGET_3D                                     0x00008000
-#define NV50TIC_0_2_TARGET_CUBE                                   0x0000c000
-#define NV50TIC_0_2_TARGET_1D_ARRAY                               0x00010000
-#define NV50TIC_0_2_TARGET_2D_ARRAY                               0x00014000
-#define NV50TIC_0_2_TARGET_BUFFER                                 0x00018000
-#define NV50TIC_0_2_TARGET_RECT                                   0x0001c000
-/* #define NV50TIC_0_0_TILE_MODE_LINEAR                           0x00040000 */
-#define NV50TIC_0_2_TILE_MODE_Y_MASK                              0x01c00000
-#define NV50TIC_0_2_TILE_MODE_Y_SHIFT                                     22
-#define NV50TIC_0_2_TILE_MODE_Z_MASK                              0x0e000000
-#define NV50TIC_0_2_TILE_MODE_Z_SHIFT                                     25
-#define NV50TIC_0_2_NORMALIZED_COORDS                             0x80000000
-
-#define NV50TIC_0_3_UNKNOWN_MASK                                  0xffffffff
-
-#define NV50TIC_0_4_WIDTH_MASK                                    0x0000ffff
-#define NV50TIC_0_4_WIDTH_SHIFT                                            0
-
-#define NV50TIC_0_5_LAST_LEVEL_MASK                               0xf0000000
-#define NV50TIC_0_5_LAST_LEVEL_SHIFT                                      28
-#define NV50TIC_0_5_DEPTH_MASK                                    0x0fff0000
-#define NV50TIC_0_5_DEPTH_SHIFT                                           16
-#define NV50TIC_0_5_HEIGHT_MASK                                   0x0000ffff
-#define NV50TIC_0_5_HEIGHT_SHIFT                                           0
-#define NV50TIC_0_6_UNKNOWN_MASK                                  0xffffffff
-
-#define NV50TIC_0_7_BASE_LEVEL_MASK                               0x0000000f
-#define NV50TIC_0_7_BASE_LEVEL_SHIFT                                       0
-#define NV50TIC_0_7_MAX_LEVEL_MASK                                0x000000f0
-#define NV50TIC_0_7_MAX_LEVEL_SHIFT                                        4
-
-/* Texture sampler control block */
-#define NV50TSC_1_0_WRAPS_MASK                                   0x00000007
-#define NV50TSC_1_0_WRAPS_REPEAT                                 0x00000000
-#define NV50TSC_1_0_WRAPS_MIRROR_REPEAT                          0x00000001
-#define NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE                          0x00000002
-#define NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER                        0x00000003
-#define NV50TSC_1_0_WRAPS_CLAMP                                  0x00000004
-#define NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_EDGE                   0x00000005
-#define NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_BORDER                 0x00000006
-#define NV50TSC_1_0_WRAPS_MIRROR_CLAMP                           0x00000007
-#define NV50TSC_1_0_WRAPT_MASK                                   0x00000038
-#define NV50TSC_1_0_WRAPT_REPEAT                                 0x00000000
-#define NV50TSC_1_0_WRAPT_MIRROR_REPEAT                          0x00000008
-#define NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE                          0x00000010
-#define NV50TSC_1_0_WRAPT_CLAMP_TO_BORDER                        0x00000018
-#define NV50TSC_1_0_WRAPT_CLAMP                                  0x00000020
-#define NV50TSC_1_0_WRAPT_MIRROR_CLAMP_TO_EDGE                   0x00000028
-#define NV50TSC_1_0_WRAPT_MIRROR_CLAMP_TO_BORDER                 0x00000030
-#define NV50TSC_1_0_WRAPT_MIRROR_CLAMP                           0x00000038
-#define NV50TSC_1_0_WRAPR_MASK                                   0x000001c0
-#define NV50TSC_1_0_WRAPR_REPEAT                                 0x00000000
-#define NV50TSC_1_0_WRAPR_MIRROR_REPEAT                          0x00000040
-#define NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE                          0x00000080
-#define NV50TSC_1_0_WRAPR_CLAMP_TO_BORDER                        0x000000c0
-#define NV50TSC_1_0_WRAPR_CLAMP                                  0x00000100
-#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_EDGE                   0x00000140
-#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_BORDER                 0x00000180
-#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP                           0x000001c0
-#define NV50TSC_1_0_MAX_ANISOTROPY_MASK                          0x00700000
-
-#define NV50TSC_1_1_MAGF_MASK                                    0x00000003
-#define NV50TSC_1_1_MAGF_NEAREST                                 0x00000001
-#define NV50TSC_1_1_MAGF_LINEAR                                  0x00000002
-#define NV50TSC_1_1_MINF_MASK                                    0x00000030
-#define NV50TSC_1_1_MINF_NEAREST                                 0x00000010
-#define NV50TSC_1_1_MINF_LINEAR                                  0x00000020
-#define NV50TSC_1_1_MIPF_MASK                                    0x000000c0
-#define NV50TSC_1_1_MIPF_NONE                                    0x00000040
-#define NV50TSC_1_1_MIPF_NEAREST                                 0x00000080
-#define NV50TSC_1_1_MIPF_LINEAR                                  0x000000c0
-#define NV50TSC_1_1_LOD_BIAS_MASK                                0x01fff000
-#define NV50TSC_1_1_UNKN_ANISO_15                                0x10000000
-#define NV50TSC_1_1_UNKN_ANISO_35                                0x18000000
-
-#define NV50TSC_1_2_MIN_LOD_MASK                                 0x00000f00
-#define NV50TSC_1_2_MAX_LOD_MASK                                 0x00f00000
-
-#define NV50TSC_1_3_UNKNOWN_MASK                                 0xffffffff
-
-#define NV50TSC_1_4_BORDER_COLOR_RED_MASK                        0xffffffff
-
-#define NV50TSC_1_5_BORDER_COLOR_GREEN_MASK                      0xffffffff
-
-#define NV50TSC_1_6_BORDER_COLOR_BLUE_MASK                       0xffffffff
-
-#define NV50TSC_1_7_BORDER_COLOR_ALPHA_MASK                      0xffffffff
-
-#endif
diff --git a/src/gallium/drivers/nv50/nv50_texture.xml.h b/src/gallium/drivers/nv50/nv50_texture.xml.h
new file mode 100644 (file)
index 0000000..9f83206
--- /dev/null
@@ -0,0 +1,259 @@
+#ifndef NV50_TEXTURE_XML
+#define NV50_TEXTURE_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:
+- nv50_texture.xml (   6871 bytes, from 2010-10-03 13:18:37)
+- copyright.xml    (   6498 bytes, from 2010-10-03 13:18:37)
+
+Copyright (C) 2006-2010 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, curro_, currojerez)
+- 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 NV50_TIC_MAP_ZERO                                      0x00000000
+#define NV50_TIC_MAP_C0                                                0x00000002
+#define NV50_TIC_MAP_C1                                                0x00000003
+#define NV50_TIC_MAP_C2                                                0x00000004
+#define NV50_TIC_MAP_C3                                                0x00000005
+#define NV50_TIC_MAP_ONE                                       0x00000007
+#define NV50_TIC_TYPE_SNORM                                    0x00000001
+#define NV50_TIC_TYPE_UNORM                                    0x00000002
+#define NV50_TIC_TYPE_SINT                                     0x00000003
+#define NV50_TIC_TYPE_UINT                                     0x00000004
+#define NV50_TIC_TYPE_SSCALED                                  0x00000005
+#define NV50_TIC_TYPE_USCALED                                  0x00000006
+#define NV50_TIC_TYPE_FLOAT                                    0x00000007
+#define NV50_TSC_WRAP_REPEAT                                   0x00000000
+#define NV50_TSC_WRAP_MIRROR_REPEAT                            0x00000001
+#define NV50_TSC_WRAP_CLAMP_TO_EDGE                            0x00000002
+#define NV50_TSC_WRAP_CLAMP_TO_BORDER                          0x00000003
+#define NV50_TSC_WRAP_CLAMP                                    0x00000004
+#define NV50_TSC_WRAP_MIRROR_CLAMP_TO_EDGE                     0x00000005
+#define NV50_TSC_WRAP_MIRROR_CLAMP_TO_BORDER                   0x00000006
+#define NV50_TSC_WRAP_MIRROR_CLAMP                             0x00000007
+#define NV50_TIC__SIZE                                         0x00000020
+#define NV50_TIC_0                                             0x00000000
+#define NV50_TIC_0_MAPA__MASK                                  0x38000000
+#define NV50_TIC_0_MAPA__SHIFT                                 27
+#define NV50_TIC_0_MAPB__MASK                                  0x07000000
+#define NV50_TIC_0_MAPB__SHIFT                                 24
+#define NV50_TIC_0_MAPG__MASK                                  0x00e00000
+#define NV50_TIC_0_MAPG__SHIFT                                 21
+#define NV50_TIC_0_MAPR__MASK                                  0x001c0000
+#define NV50_TIC_0_MAPR__SHIFT                                 18
+#define NV50_TIC_0_TYPE3__MASK                                 0x00038000
+#define NV50_TIC_0_TYPE3__SHIFT                                        15
+#define NV50_TIC_0_TYPE2__MASK                                 0x00007000
+#define NV50_TIC_0_TYPE2__SHIFT                                        12
+#define NV50_TIC_0_TYPE1__MASK                                 0x00000e00
+#define NV50_TIC_0_TYPE1__SHIFT                                        9
+#define NV50_TIC_0_TYPE0__MASK                                 0x000001c0
+#define NV50_TIC_0_TYPE0__SHIFT                                        6
+#define NV50_TIC_0_SWIZZLE__MASK                               0x3ffc0000
+#define NV50_TIC_0_FMT__MASK                                   0x0000003f
+#define NV50_TIC_0_FMT__SHIFT                                  0
+#define NV50_TIC_0_FMT_32_32_32_32                             0x00000001
+#define NV50_TIC_0_FMT_16_16_16_16                             0x00000003
+#define NV50_TIC_0_FMT_32_32                                   0x00000004
+#define NV50_TIC_0_FMT_32_8                                    0x00000005
+#define NV50_TIC_0_FMT_8_8_8_8                                 0x00000008
+#define NV50_TIC_0_FMT_2_10_10_10                              0x00000009
+#define NV50_TIC_0_FMT_16_16                                   0x0000000c
+#define NV50_TIC_0_FMT_8_24                                    0x0000000d
+#define NV50_TIC_0_FMT_24_8                                    0x0000000e
+#define NV50_TIC_0_FMT_32                                      0x0000000f
+#define NV50_TIC_0_FMT_4_4_4_4                                 0x00000012
+#define NV50_TIC_0_FMT_5_5_5_1                                 0x00000013
+#define NV50_TIC_0_FMT_1_5_5_5                                 0x00000014
+#define NV50_TIC_0_FMT_5_6_5                                   0x00000015
+#define NV50_TIC_0_FMT_6_5_5                                   0x00000016
+#define NV50_TIC_0_FMT_8_8                                     0x00000018
+#define NV50_TIC_0_FMT_16                                      0x0000001b
+#define NV50_TIC_0_FMT_8                                       0x0000001d
+#define NV50_TIC_0_FMT_4_4                                     0x0000001e
+#define NV50_TIC_0_FMT_UNK1F                                   0x0000001f
+#define NV50_TIC_0_FMT_E5_9_9_9                                        0x00000020
+#define NV50_TIC_0_FMT_10_11_11                                        0x00000021
+#define NV50_TIC_0_FMT_C1_C2_C1_C0                             0x00000022
+#define NV50_TIC_0_FMT_C2_C1_C0_C1                             0x00000023
+#define NV50_TIC_0_FMT_DXT1                                    0x00000024
+#define NV50_TIC_0_FMT_DXT3                                    0x00000025
+#define NV50_TIC_0_FMT_DXT5                                    0x00000026
+#define NV50_TIC_0_FMT_RGTC1                                   0x00000027
+#define NV50_TIC_0_FMT_RGTC2                                   0x00000028
+#define NV50_TIC_0_FMT_24_8_ZETA                               0x00000029
+#define NV50_TIC_0_FMT_8_24_ZETA                               0x0000002a
+#define NV50_TIC_0_FMT_UNK2C_ZETA                              0x0000002c
+#define NV50_TIC_0_FMT_UNK2D_ZETA                              0x0000002d
+#define NV50_TIC_0_FMT_UNK2E_ZETA                              0x0000002e
+#define NV50_TIC_0_FMT_32_ZETA                                 0x0000002f
+#define NV50_TIC_0_FMT_32_8_ZETA                               0x00000030
+#define NV50_TIC_0_FMT_16_ZETA                         0x0000003a
+
+#define NV50_TIC_1                                             0x00000004
+#define NV50_TIC_1_OFFSET_LOW__MASK                            0xffffffff
+#define NV50_TIC_1_OFFSET_LOW__SHIFT                           0
+
+#define NV50_TIC_2                                             0x00000008
+#define NV50_TIC_2_OFFSET_HIGH__MASK                           0x000000ff
+#define NV50_TIC_2_OFFSET_HIGH__SHIFT                          0
+#define NV50_TIC_2_COLORSPACE_SRGB                             0x00000400
+#define NV50_TIC_2_TARGET__MASK                                        0x0003c000
+#define NV50_TIC_2_TARGET__SHIFT                               14
+#define NV50_TIC_2_TARGET_1D                                   0x00000000
+#define NV50_TIC_2_TARGET_2D                                   0x00004000
+#define NV50_TIC_2_TARGET_3D                                   0x00008000
+#define NV50_TIC_2_TARGET_CUBE                                 0x0000c000
+#define NV50_TIC_2_TARGET_1D_ARRAY                             0x00010000
+#define NV50_TIC_2_TARGET_2D_ARRAY                             0x00014000
+#define NV50_TIC_2_TARGET_BUFFER                               0x00018000
+#define NV50_TIC_2_TARGET_RECT                                 0x0001c000
+#define NV50_TIC_2_TARGET_CUBE_ARRAY                           0x00020000
+#define NV50_TIC_2_TILE_MODE_LINEAR                            0x00040000
+#define NV50_TIC_2_TILE_MODE_Y__MASK                           0x01c00000
+#define NV50_TIC_2_TILE_MODE_Y__SHIFT                          22
+#define NV50_TIC_2_TILE_MODE_Z__MASK                           0x0e000000
+#define NV50_TIC_2_TILE_MODE_Z__SHIFT                          25
+#define NV50_TIC_2_2D_UNK0258__MASK                            0x30000000
+#define NV50_TIC_2_2D_UNK0258__SHIFT                           28
+#define NV50_TIC_2_NORMALIZED_COORDS                           0x80000000
+
+#define NV50_TIC_3                                             0x0000000c
+#define NV50_TIC_3_PITCH__MASK                                 0xffffffff
+#define NV50_TIC_3_PITCH__SHIFT                                        0
+
+#define NV50_TIC_4                                             0x00000010
+#define NV50_TIC_4_WIDTH__MASK                                 0xffffffff
+#define NV50_TIC_4_WIDTH__SHIFT                                        0
+
+#define NV50_TIC_5                                             0x00000014
+#define NV50_TIC_5_LAST_LEVEL__MASK                            0xf0000000
+#define NV50_TIC_5_LAST_LEVEL__SHIFT                           28
+#define NV50_TIC_5_DEPTH__MASK                                 0x0fff0000
+#define NV50_TIC_5_DEPTH__SHIFT                                        16
+#define NV50_TIC_5_HEIGHT__MASK                                        0x0000ffff
+#define NV50_TIC_5_HEIGHT__SHIFT                               0
+
+#define NV50_TIC_7                                             0x0000001c
+#define NV50_TIC_7_BASE_LEVEL__MASK                            0x0000000f
+#define NV50_TIC_7_BASE_LEVEL__SHIFT                           0
+#define NV50_TIC_7_MAX_LEVEL__MASK                             0x000000f0
+#define NV50_TIC_7_MAX_LEVEL__SHIFT                            4
+
+#define NV50_TSC__SIZE                                         0x00000020
+#define NV50_TSC_0                                             0x00000000
+#define NV50_TSC_0_WRAPS__MASK                                 0x00000007
+#define NV50_TSC_0_WRAPS__SHIFT                                        0
+#define NV50_TSC_0_WRAPT__MASK                                 0x00000038
+#define NV50_TSC_0_WRAPT__SHIFT                                        3
+#define NV50_TSC_0_WRAPR__MASK                                 0x000001c0
+#define NV50_TSC_0_WRAPR__SHIFT                                        6
+#define NV50_TSC_0_SHADOW_COMPARE_ENABLE                       0x00000200
+#define NV50_TSC_0_SHADOW_COMPARE_FUNC__MASK                   0x00001c00
+#define NV50_TSC_0_SHADOW_COMPARE_FUNC__SHIFT                  10
+#define NV50_TSC_0_ANISOTROPY_MASK__MASK                       0x00700000
+#define NV50_TSC_0_ANISOTROPY_MASK__SHIFT                      20
+
+#define NV50_TSC_1                                             0x00000004
+#define NV50_TSC_1_UNKN_ANISO_15                               0x10000000
+#define NV50_TSC_1_UNKN_ANISO_35                               0x18000000
+#define NV50_TSC_1_MAGF__MASK                                  0x00000003
+#define NV50_TSC_1_MAGF__SHIFT                                 0
+#define NV50_TSC_1_MAGF_NEAREST                                        0x00000001
+#define NV50_TSC_1_MAGF_LINEAR                                 0x00000002
+#define NV50_TSC_1_MINF__MASK                                  0x00000030
+#define NV50_TSC_1_MINF__SHIFT                                 4
+#define NV50_TSC_1_MINF_NEAREST                                        0x00000010
+#define NV50_TSC_1_MINF_LINEAR                                 0x00000020
+#define NV50_TSC_1_MIPF__MASK                                  0x000000c0
+#define NV50_TSC_1_MIPF__SHIFT                                 6
+#define NV50_TSC_1_MIPF_NONE                                   0x00000040
+#define NV50_TSC_1_MIPF_NEAREST                                        0x00000080
+#define NV50_TSC_1_MIPF_LINEAR                                 0x000000c0
+#define NV50_TSC_1_LOD_BIAS__MASK                              0x01fff000
+#define NV50_TSC_1_LOD_BIAS__SHIFT                             12
+
+#define NV50_TSC_2                                             0x00000008
+#define NV50_TSC_2_MIN_LOD__MASK                               0x00000f00
+#define NV50_TSC_2_MIN_LOD__SHIFT                              8
+#define NV50_TSC_2_MAX_LOD__MASK                               0x00f00000
+#define NV50_TSC_2_MAX_LOD__SHIFT                              20
+
+#define NV50_TSC_4                                             0x00000010
+#define NV50_TSC_4_BORDER_COLOR_RED__MASK                      0xffffffff
+#define NV50_TSC_4_BORDER_COLOR_RED__SHIFT                     0
+
+#define NV50_TSC_5                                             0x00000014
+#define NV50_TSC_5_BORDER_COLOR_GREEN__MASK                    0xffffffff
+#define NV50_TSC_5_BORDER_COLOR_GREEN__SHIFT                   0
+
+#define NV50_TSC_6                                             0x00000018
+#define NV50_TSC_6_BORDER_COLOR_BLUE__MASK                     0xffffffff
+#define NV50_TSC_6_BORDER_COLOR_BLUE__SHIFT                    0
+
+#define NV50_TSC_7                                             0x0000001c
+#define NV50_TSC_7_BORDER_COLOR_ALPHA__MASK                    0xffffffff
+#define NV50_TSC_7_BORDER_COLOR_ALPHA__SHIFT                   0
+
+
+#endif /* NV50_TEXTURE_XML */
index ce9300ad8fd1328304a106be0b78f03331534756..54b78e850ed5d99ce874ec54c3e05bb8faf6feb1 100644 (file)
@@ -476,6 +476,7 @@ bld_loop_end(struct bld_context *bld, struct nv_basic_block *bb)
       stk = (struct bld_value_stack *)phi->target;
       phi->target = NULL;
 
+      /* start with s == 1, src[0] is from outside the loop */
       for (s = 1, n = 0; n < bb->num_in; ++n) {
          if (bb->in_kind[n] != CFG_EDGE_BACK)
             continue;
@@ -487,8 +488,11 @@ bld_loop_end(struct bld_context *bld, struct nv_basic_block *bb)
          for (i = 0; i < 4; ++i)
             if (phi->src[i] && phi->src[i]->value == val)
                break;
-         if (i == 4)
+         if (i == 4) {
+            /* skip values we do not want to replace */
+            for (; phi->src[s] && phi->src[s]->value != phi->def[0]; ++s);
             nv_reference(bld->pc, &phi->src[s++], val);
+         }
       }
       bld->pc->current_block = save;
 
@@ -1102,9 +1106,8 @@ emit_fetch(struct bld_context *bld, const struct tgsi_full_instruction *insn,
 
    switch (src->Register.File) {
    case TGSI_FILE_CONSTANT:
-      dim_idx = src->Dimension.Index ? src->Dimension.Index + 2 : 1;
-      assert(dim_idx < 14);
-      assert(dim_idx == 1); /* for now */
+      dim_idx = src->Dimension.Index;
+      assert(dim_idx < 15);
 
       res = new_value(bld->pc, NV_FILE_MEM_C(dim_idx), type);
       SET_TYPE(res, type);
@@ -1468,7 +1471,7 @@ bld_tex(struct bld_context *bld, struct nv_value *dst0[4],
    uint opcode = translate_opcode(insn->Instruction.Opcode);
    int arg, dim, c;
    const int tic = insn->Src[1].Register.Index;
-   const int tsc = 0;
+   const int tsc = tic;
    const int cube = (insn->Texture.Texture  == TGSI_TEXTURE_CUBE) ? 1 : 0;
 
    get_tex_dim(insn, &dim, &arg);
@@ -1717,6 +1720,10 @@ bld_instruction(struct bld_context *bld,
    {
       struct nv_basic_block *b = new_basic_block(bld->pc);
 
+      if (bld->pc->current_block->exit &&
+          !bld->pc->current_block->exit->is_terminator)
+         bld_flow(bld, NV_OP_BRA, NV_CC_TR, NULL, b, FALSE);
+
       --bld->cond_lvl;
       nvbb_attach_block(bld->pc->current_block, b, bld->out_kind);
       nvbb_attach_block(bld->cond_bb[bld->cond_lvl], b, CFG_EDGE_FORWARD);
@@ -1923,6 +1930,7 @@ bld_instruction(struct bld_context *bld,
          dst0[c] = bld_insn_2(bld, NV_OP_XOR, temp, temp);
          dst0[c]->insn->cc = NV_CC_EQ;
          nv_reference(bld->pc, &dst0[c]->insn->flags_src, src1);
+         dst0[c] = bld_insn_2(bld, NV_OP_SELECT, dst0[c], temp);
       }
       break;
    case TGSI_OPCODE_SUB:
index bf5af4ddc653cf580f4aa2546ab20d28688dc45b..696350d10c8b457a7226a8ea48be0b987978b055 100644 (file)
 
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
 #include "util/u_format.h"
-#include "util/u_math.h"
 
 #include "nv50_context.h"
 #include "nv50_transfer.h"
-#include "nv50_resource.h"
+
+#include "nv50_defs.xml.h"
 
 struct nv50_transfer {
-       struct pipe_transfer base;
-       struct nouveau_bo *bo;
-       int map_refcnt;
-       unsigned level_offset;
-       unsigned level_tiling;
-       int level_pitch;
-       int level_width;
-       int level_height;
-       int level_depth;
-       int level_x;
-       int level_y;
-       int level_z;
-       unsigned nblocksx;
-       unsigned nblocksy;
+   struct pipe_transfer base;
+   struct nv50_m2mf_rect rect[2];
+   uint32_t nblocksx;
+   uint32_t nblocksy;
 };
 
 static void
-nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
-                       struct nouveau_bo *src_bo, unsigned src_offset,
-                       int src_pitch, unsigned src_tile_mode,
-                       int sx, int sy, int sz, int sw, int sh, int sd,
-                       struct nouveau_bo *dst_bo, unsigned dst_offset,
-                       int dst_pitch, unsigned dst_tile_mode,
-                       int dx, int dy, int dz, int dw, int dh, int dd,
-                       int cpp, int width, int height,
-                       unsigned src_reloc, unsigned dst_reloc)
+nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
+                        const struct nv50_m2mf_rect *dst,
+                        const struct nv50_m2mf_rect *src,
+                        uint32_t nblocksx, uint32_t nblocksy)
 {
-       struct nv50_screen *screen = nv50_screen(pscreen);
-       struct nouveau_channel *chan = screen->m2mf->channel;
-       struct nouveau_grobj *m2mf = screen->m2mf;
-
-       src_reloc |= NOUVEAU_BO_RD;
-       dst_reloc |= NOUVEAU_BO_WR;
-
-       WAIT_RING (chan, 14);
-
-       if (!nouveau_bo_tile_layout(src_bo)) {
-               BEGIN_RING(chan, m2mf,
-                       NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 1);
-               OUT_RING  (chan, 1);
-               BEGIN_RING(chan, m2mf,
-                       NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_IN, 1);
-               OUT_RING  (chan, src_pitch);
-               src_offset += (sy * src_pitch) + (sx * cpp);
-       } else {
-               BEGIN_RING(chan, m2mf,
-                       NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 6);
-               OUT_RING  (chan, 0);
-               OUT_RING  (chan, src_tile_mode << 4);
-               OUT_RING  (chan, sw * cpp);
-               OUT_RING  (chan, sh);
-               OUT_RING  (chan, sd);
-               OUT_RING  (chan, sz); /* copying only 1 zslice per call */
-       }
-
-       if (!nouveau_bo_tile_layout(dst_bo)) {
-               BEGIN_RING(chan, m2mf,
-                       NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 1);
-               OUT_RING  (chan, 1);
-               BEGIN_RING(chan, m2mf,
-                       NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT, 1);
-               OUT_RING  (chan, dst_pitch);
-               dst_offset += (dy * dst_pitch) + (dx * cpp);
-       } else {
-               BEGIN_RING(chan, m2mf,
-                       NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 6);
-               OUT_RING  (chan, 0);
-               OUT_RING  (chan, dst_tile_mode << 4);
-               OUT_RING  (chan, dw * cpp);
-               OUT_RING  (chan, dh);
-               OUT_RING  (chan, dd);
-               OUT_RING  (chan, dz); /* copying only 1 zslice per call */
-       }
-
-       while (height) {
-               int line_count = height > 2047 ? 2047 : height;
-
-               MARK_RING (chan, 15, 4); /* flush on lack of space or relocs */
-               BEGIN_RING(chan, m2mf,
-                       NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH, 2);
-               OUT_RELOCh(chan, src_bo, src_offset, src_reloc);
-               OUT_RELOCh(chan, dst_bo, dst_offset, dst_reloc);
-               BEGIN_RING(chan, m2mf,
-                       NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 2);
-               OUT_RELOCl(chan, src_bo, src_offset, src_reloc);
-               OUT_RELOCl(chan, dst_bo, dst_offset, dst_reloc);
-               if (nouveau_bo_tile_layout(src_bo)) {
-                       BEGIN_RING(chan, m2mf,
-                               NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN, 1);
-                       OUT_RING  (chan, (sy << 16) | (sx * cpp));
-               } else {
-                       src_offset += (line_count * src_pitch);
-               }
-               if (nouveau_bo_tile_layout(dst_bo)) {
-                       BEGIN_RING(chan, m2mf,
-                               NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT, 1);
-                       OUT_RING  (chan, (dy << 16) | (dx * cpp));
-               } else {
-                       dst_offset += (line_count * dst_pitch);
-               }
-               BEGIN_RING(chan, m2mf,
-                       NV04_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN, 4);
-               OUT_RING  (chan, width * cpp);
-               OUT_RING  (chan, line_count);
-               OUT_RING  (chan, 0x00000101);
-               OUT_RING  (chan, 0);
-               FIRE_RING (chan);
-
-               height -= line_count;
-               sy += line_count;
-               dy += line_count;
-       }
+   struct nouveau_channel *chan = nouveau_screen(pscreen)->channel;
+   const int cpp = dst->cpp;
+   uint32_t src_ofst = src->base;
+   uint32_t dst_ofst = dst->base;
+   uint32_t height = nblocksy;
+   uint32_t sy = src->y;
+   uint32_t dy = dst->y;
+
+   assert(dst->cpp == src->cpp);
+
+   if (nouveau_bo_tile_layout(src->bo)) {
+      BEGIN_RING(chan, RING_MF(LINEAR_IN), 6);
+      OUT_RING  (chan, 0);
+      OUT_RING  (chan, src->tile_mode << 4);
+      OUT_RING  (chan, src->width * cpp);
+      OUT_RING  (chan, src->height);
+      OUT_RING  (chan, src->depth);
+      OUT_RING  (chan, src->z);
+   } else {
+      src_ofst += src->y * src->pitch + src->x * cpp;
+
+      BEGIN_RING(chan, RING_MF(LINEAR_IN), 1);
+      OUT_RING  (chan, 1);
+      BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_IN), 1);
+      OUT_RING  (chan, src->pitch);
+   }
+
+   if (nouveau_bo_tile_layout(dst->bo)) {
+      BEGIN_RING(chan, RING_MF(LINEAR_OUT), 6);
+      OUT_RING  (chan, 0);
+      OUT_RING  (chan, dst->tile_mode << 4);
+      OUT_RING  (chan, dst->width * cpp);
+      OUT_RING  (chan, dst->height);
+      OUT_RING  (chan, dst->depth);
+      OUT_RING  (chan, dst->z);
+   } else {
+      dst_ofst += dst->y * dst->pitch + dst->x * cpp;
+
+      BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1);
+      OUT_RING  (chan, 1);
+      BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_OUT), 1);
+      OUT_RING  (chan, dst->pitch);
+   }
+
+   while (height) {
+      int line_count = height > 2047 ? 2047 : height;
+
+      MARK_RING (chan, 17, 4);
+
+      BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
+      OUT_RELOCh(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
+      OUT_RELOCh(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
+
+      BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2);
+      OUT_RELOCl(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
+      OUT_RELOCl(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
+
+      if (nouveau_bo_tile_layout(src->bo)) {
+         BEGIN_RING(chan, RING_MF(TILING_POSITION_IN), 1);
+         OUT_RING  (chan, (sy << 16) | (src->x * cpp));
+      } else {
+         src_ofst += line_count * src->pitch;
+      }
+      if (nouveau_bo_tile_layout(dst->bo)) {
+         BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT), 1);
+         OUT_RING  (chan, (dy << 16) | (dst->x * cpp));
+      } else {
+         dst_ofst += line_count * dst->pitch;
+      }
+
+      BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4);
+      OUT_RING  (chan, nblocksx * cpp);
+      OUT_RING  (chan, line_count);
+      OUT_RING  (chan, (1 << 8) | (1 << 0));
+      OUT_RING  (chan, 0);
+
+      height -= line_count;
+      sy += line_count;
+      dy += line_count;
+   }
 }
 
-struct pipe_transfer *
-nv50_miptree_transfer_new(struct pipe_context *pcontext,
-                         struct pipe_resource *pt,
-                         unsigned level,
-                         unsigned usage,
-                         const struct pipe_box *box)
+void
+nv50_sifc_linear_u8(struct nv50_context *nv50,
+                    struct nouveau_bo *dst, unsigned domain, int offset,
+                    unsigned size, void *data)
 {
-        struct pipe_screen *pscreen = pcontext->screen;
-       struct nouveau_device *dev = nouveau_screen(pscreen)->device;
-       struct nv50_miptree *mt = nv50_miptree(pt);
-       struct nv50_miptree_level *lvl = &mt->level[level];
-       struct nv50_transfer *tx;
-       unsigned nx, ny, image = 0, boxz = 0;
-       int ret;
-
-       /* XXX can't unify these here? */
-       if (pt->target == PIPE_TEXTURE_CUBE)
-               image = box->z;
-       else if (pt->target == PIPE_TEXTURE_3D)
-               boxz = box->z;
-
-       tx = CALLOC_STRUCT(nv50_transfer);
-       if (!tx)
-               return NULL;
-
-       /* Don't handle 3D transfers yet.
-        */
-       assert(box->depth == 1);
-
-
-       pipe_resource_reference(&tx->base.resource, pt);
-       tx->base.level = level;
-       tx->base.usage = usage;
-       tx->base.box = *box;
-       tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, level));
-       tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, level));
-       tx->base.stride = tx->nblocksx * util_format_get_blocksize(pt->format);
-       tx->base.usage = usage;
-
-       tx->level_pitch = lvl->pitch;
-       tx->level_width = u_minify(mt->base.base.width0, level);
-       tx->level_height = u_minify(mt->base.base.height0, level);
-       tx->level_depth = u_minify(mt->base.base.depth0, level);
-       tx->level_offset = lvl->image_offset[image];
-       tx->level_tiling = lvl->tile_mode;
-       tx->level_z = boxz;
-       tx->level_x = util_format_get_nblocksx(pt->format, box->x);
-       tx->level_y = util_format_get_nblocksy(pt->format, box->y);
-       ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
-                            tx->nblocksy * tx->base.stride, &tx->bo);
-       if (ret) {
-               FREE(tx);
-               return NULL;
-       }
-
-       if (usage & PIPE_TRANSFER_READ) {
-               nx = util_format_get_nblocksx(pt->format, box->width);
-               ny = util_format_get_nblocksy(pt->format, box->height);
-
-               nv50_transfer_rect_m2mf(pscreen, mt->base.bo, tx->level_offset,
-                                       tx->level_pitch, tx->level_tiling,
-                                       box->x, box->y, boxz,
-                                       tx->nblocksx, tx->nblocksy,
-                                       tx->level_depth,
-                                       tx->bo, 0,
-                                       tx->base.stride, tx->bo->tile_mode,
-                                       0, 0, 0,
-                                       tx->nblocksx, tx->nblocksy, 1,
-                                       util_format_get_blocksize(pt->format), nx, ny,
-                                       NOUVEAU_BO_VRAM | NOUVEAU_BO_GART,
-                                       NOUVEAU_BO_GART);
-       }
-
-       return &tx->base;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   uint32_t *src = (uint32_t *)data;
+   unsigned count = (size + 3) / 4;
+   unsigned xcoord = offset & 0xff;
+
+   offset &= ~0xff;
+
+   MARK_RING (chan, 23, 4);
+   BEGIN_RING(chan, RING_2D(DST_FORMAT), 2);
+   OUT_RING  (chan, NV50_SURFACE_FORMAT_R8_UNORM);
+   OUT_RING  (chan, 1);
+   BEGIN_RING(chan, RING_2D(DST_PITCH), 5);
+   OUT_RING  (chan, 262144);
+   OUT_RING  (chan, 65536);
+   OUT_RING  (chan, 1);
+   OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR);
+   OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR);
+   BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, NV50_SURFACE_FORMAT_R8_UNORM);
+   BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10);
+   OUT_RING  (chan, size);
+   OUT_RING  (chan, 1);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, 1);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, 1);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, xcoord);
+   OUT_RING  (chan, 0);
+   OUT_RING  (chan, 0);
+
+   while (count) {
+      unsigned nr = AVAIL_RING(chan);
+
+      if (nr < 9) {
+         FIRE_RING(chan);
+         nouveau_bo_validate(chan, dst, NOUVEAU_BO_WR);
+         continue;
+      }
+      nr = MIN2(count, nr - 1);
+      nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
+
+      BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), nr);
+      OUT_RINGp (chan, src, nr);
+
+      src += nr;
+      count -= nr;
+   }
 }
 
 void
-nv50_miptree_transfer_del(struct pipe_context *pcontext,
-                         struct pipe_transfer *ptx)
+nv50_m2mf_copy_linear(struct nv50_context *nv50,
+                      struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
+                      struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
+                      unsigned size)
 {
-       struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
-       struct nv50_miptree *mt = nv50_miptree(ptx->resource);
-       struct pipe_resource *pt = ptx->resource;
-
-       unsigned nx = util_format_get_nblocksx(pt->format, tx->base.box.width);
-       unsigned ny = util_format_get_nblocksy(pt->format, tx->base.box.height);
-
-       if (ptx->usage & PIPE_TRANSFER_WRITE) {
-               struct pipe_screen *pscreen = pcontext->screen;
-
-               nv50_transfer_rect_m2mf(pscreen, tx->bo, 0,
-                                       tx->base.stride, tx->bo->tile_mode,
-                                       0, 0, 0,
-                                       tx->nblocksx, tx->nblocksy, 1,
-                                       mt->base.bo, tx->level_offset,
-                                       tx->level_pitch, tx->level_tiling,
-                                       tx->level_x, tx->level_y, tx->level_z,
-                                       tx->nblocksx, tx->nblocksy,
-                                       tx->level_depth,
-                                       util_format_get_blocksize(pt->format), nx, ny,
-                                       NOUVEAU_BO_GART, NOUVEAU_BO_VRAM |
-                                       NOUVEAU_BO_GART);
-       }
-
-       nouveau_bo_ref(NULL, &tx->bo);
-       pipe_resource_reference(&ptx->resource, NULL);
-       FREE(ptx);
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+
+   BEGIN_RING(chan, RING_MF(LINEAR_IN), 1);
+   OUT_RING  (chan, 1);
+   BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1);
+   OUT_RING  (chan, 1);
+
+   while (size) {
+      unsigned bytes = MIN2(size, 1 << 17);
+
+      MARK_RING (chan, 11, 4);
+      BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
+      OUT_RELOCh(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
+      OUT_RELOCh(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
+      BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2);
+      OUT_RELOCl(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
+      OUT_RELOCl(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
+      BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4);
+      OUT_RING  (chan, bytes);
+      OUT_RING  (chan, 1);
+      OUT_RING  (chan, (1 << 8) | (1 << 0));
+      OUT_RING  (chan, 0);
+
+      srcoff += bytes;
+      dstoff += bytes;
+      size -= bytes;
+   }
 }
 
-void *
-nv50_miptree_transfer_map(struct pipe_context *pcontext,
-                         struct pipe_transfer *ptx)
+struct pipe_transfer *
+nv50_miptree_transfer_new(struct pipe_context *pctx,
+                          struct pipe_resource *res,
+                          unsigned level,
+                          unsigned usage,
+                          const struct pipe_box *box)
 {
-       struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
-       unsigned flags = 0;
-       int ret;
-
-       if (tx->map_refcnt++)
-               return tx->bo->map;
-
-       if (ptx->usage & PIPE_TRANSFER_WRITE)
-               flags |= NOUVEAU_BO_WR;
-       if (ptx->usage & PIPE_TRANSFER_READ)
-               flags |= NOUVEAU_BO_RD;
-
-       ret = nouveau_bo_map(tx->bo, flags);
-       if (ret) {
-               tx->map_refcnt = 0;
-               return NULL;
-       }
-       return tx->bo->map;
+   struct nv50_context *nv50 = nv50_context(pctx);
+   struct pipe_screen *pscreen = pctx->screen;
+   struct nouveau_device *dev = nv50->screen->base.device;
+   struct nv50_miptree *mt = nv50_miptree(res);
+   struct nv50_miptree_level *lvl = &mt->level[level];
+   struct nv50_transfer *tx;
+   uint32_t size;
+   uint32_t w, h, d, z, layer;
+   int ret;
+
+   if (mt->layout_3d) {
+      z = box->z;
+      d = u_minify(res->depth0, level);
+      layer = 0;
+   } else {
+      z = 0;
+      d = 1;
+      layer = box->z;
+   }
+
+   tx = CALLOC_STRUCT(nv50_transfer);
+   if (!tx)
+      return NULL;
+
+   pipe_resource_reference(&tx->base.resource, res);
+
+   tx->base.level = level;
+   tx->base.usage = usage;
+   tx->base.box = *box;
+
+   tx->nblocksx = util_format_get_nblocksx(res->format, box->width);
+   tx->nblocksy = util_format_get_nblocksy(res->format, box->height);
+
+   tx->base.stride = tx->nblocksx * util_format_get_blocksize(res->format);
+   tx->base.layer_stride = tx->nblocksy * tx->base.stride;
+
+   w = u_minify(res->width0, level);
+   h = u_minify(res->height0, level);
+
+   tx->rect[0].cpp = tx->rect[1].cpp = util_format_get_blocksize(res->format);
+
+   tx->rect[0].bo = mt->base.bo;
+   tx->rect[0].base = lvl->offset + layer * mt->layer_stride;
+   tx->rect[0].tile_mode = lvl->tile_mode;
+   tx->rect[0].x = util_format_get_nblocksx(res->format, box->x);
+   tx->rect[0].y = util_format_get_nblocksy(res->format, box->y);
+   tx->rect[0].z = z;
+   tx->rect[0].width = util_format_get_nblocksx(res->format, w);
+   tx->rect[0].height = util_format_get_nblocksy(res->format, h);
+   tx->rect[0].depth = d;
+   tx->rect[0].pitch = lvl->pitch;
+   tx->rect[0].domain = NOUVEAU_BO_VRAM;
+
+   size = tx->base.layer_stride;
+
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
+                        size * tx->base.box.depth, &tx->rect[1].bo);
+   if (ret) {
+      FREE(tx);
+      return NULL;
+   }
+
+   tx->rect[1].width = tx->nblocksx;
+   tx->rect[1].height = tx->nblocksy;
+   tx->rect[1].depth = 1;
+   tx->rect[1].pitch = tx->base.stride;
+   tx->rect[1].domain = NOUVEAU_BO_GART;
+
+   if (usage & PIPE_TRANSFER_READ) {
+      unsigned base = tx->rect[0].base;
+      unsigned i;
+      for (i = 0; i < box->depth; ++i) {
+         nv50_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0],
+                                 tx->nblocksx, tx->nblocksy);
+         if (mt->layout_3d)
+            tx->rect[0].z++;
+         else
+            tx->rect[0].base += mt->layer_stride;
+         tx->rect[1].base += size;
+      }
+      tx->rect[0].z = z;
+      tx->rect[0].base = base;
+      tx->rect[1].base = 0;
+   }
+
+   return &tx->base;
 }
 
 void
-nv50_miptree_transfer_unmap(struct pipe_context *pcontext,
-                           struct pipe_transfer *ptx)
+nv50_miptree_transfer_del(struct pipe_context *pctx,
+                          struct pipe_transfer *transfer)
 {
-       struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
-
-       if (--tx->map_refcnt)
-               return;
-       nouveau_bo_unmap(tx->bo);
+   struct pipe_screen *pscreen = pctx->screen;
+   struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
+   struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
+   unsigned i;
+
+   if (tx->base.usage & PIPE_TRANSFER_WRITE) {
+      for (i = 0; i < tx->base.box.depth; ++i) {
+         nv50_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1],
+                                 tx->nblocksx, tx->nblocksy);
+         if (mt->layout_3d)
+            tx->rect[0].z++;
+         else
+            tx->rect[0].base += mt->layer_stride;
+         tx->rect[1].base += tx->nblocksy * tx->base.stride;
+      }
+   }
+
+   nouveau_bo_ref(NULL, &tx->rect[1].bo);
+   pipe_resource_reference(&transfer->resource, NULL);
+
+   FREE(tx);
 }
 
+void *
+nv50_miptree_transfer_map(struct pipe_context *pctx,
+                          struct pipe_transfer *transfer)
+{
+   struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
+   int ret;
+   unsigned flags = 0;
+
+   if (tx->rect[1].bo->map)
+      return tx->rect[1].bo->map;
+
+   if (transfer->usage & PIPE_TRANSFER_READ)
+      flags = NOUVEAU_BO_RD;
+   if (transfer->usage & PIPE_TRANSFER_WRITE)
+      flags |= NOUVEAU_BO_WR;
+
+   ret = nouveau_bo_map(tx->rect[1].bo, flags);
+   if (ret)
+      return NULL;
+   return tx->rect[1].bo->map;
+}
 
 void
-nv50_upload_sifc(struct nv50_context *nv50,
-                struct nouveau_bo *bo, unsigned dst_offset, unsigned reloc,
-                unsigned dst_format, int dst_w, int dst_h, int dst_pitch,
-                void *src, unsigned src_format, int src_pitch,
-                int x, int y, int w, int h, int cpp)
+nv50_miptree_transfer_unmap(struct pipe_context *pctx,
+                            struct pipe_transfer *transfer)
 {
-       struct nouveau_channel *chan = nv50->screen->base.channel;
-       struct nouveau_grobj *eng2d = nv50->screen->eng2d;
-       unsigned line_dwords = (w * cpp + 3) / 4;
-
-       reloc |= NOUVEAU_BO_WR;
-
-       MARK_RING (chan, 32, 2); /* flush on lack of space or relocs */
-
-       if (nouveau_bo_tile_layout(bo)) {
-               BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 5);
-               OUT_RING  (chan, dst_format);
-               OUT_RING  (chan, 0);
-               OUT_RING  (chan, bo->tile_mode << 4);
-               OUT_RING  (chan, 1);
-               OUT_RING  (chan, 0);
-       } else {
-               BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2);
-               OUT_RING  (chan, dst_format);
-               OUT_RING  (chan, 1);
-               BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 1);
-               OUT_RING  (chan, dst_pitch);
-       }
-
-       BEGIN_RING(chan, eng2d, NV50_2D_DST_WIDTH, 4);
-       OUT_RING  (chan, dst_w);
-       OUT_RING  (chan, dst_h);
-       OUT_RELOCh(chan, bo, dst_offset, reloc);
-       OUT_RELOCl(chan, bo, dst_offset, reloc);
-
-       /* NV50_2D_OPERATION_SRCCOPY assumed already set */
-
-       BEGIN_RING(chan, eng2d, NV50_2D_SIFC_BITMAP_ENABLE, 2);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, src_format);
-       BEGIN_RING(chan, eng2d, NV50_2D_SIFC_WIDTH, 10);
-       OUT_RING  (chan, w);
-       OUT_RING  (chan, h);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, 1);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, 1);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, x);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, y);
-
-       while (h--) {
-               const uint32_t *p = src;
-               unsigned count = line_dwords;
-
-               while (count) {
-                       unsigned nr = MIN2(count, 1792);
-
-                       if (AVAIL_RING(chan) <= nr) {
-                               FIRE_RING (chan);
-
-                               BEGIN_RING(chan, eng2d,
-                                          NV50_2D_DST_ADDRESS_HIGH, 2);
-                               OUT_RELOCh(chan, bo, dst_offset, reloc);
-                               OUT_RELOCl(chan, bo, dst_offset, reloc);
-                       }
-                       assert(AVAIL_RING(chan) > nr);
-
-                       BEGIN_RING(chan, eng2d,
-                                  NV50_2D_SIFC_DATA | (2 << 29), nr);
-                       OUT_RINGp (chan, p, nr);
-
-                       p += nr;
-                       count -= nr;
-               }
-
-               src = (uint8_t *) src + src_pitch;
-       }
+   struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
+
+   nouveau_bo_unmap(tx->rect[1].bo);
 }
+
index 6699bf546eabff47a1be5c5c7ead934eb8fcab1b..d3259ef4a5da9fa477bcaf7f0ab03aa126207d5f 100644 (file)
@@ -1,31 +1,38 @@
 
-#ifndef NV50_TRANSFER_H
-#define NV50_TRANSFER_H
+#ifndef __NV50_TRANSFER_H__
+#define __NV50_TRANSFER_H__
 
 #include "pipe/p_state.h"
 
-
 struct pipe_transfer *
 nv50_miptree_transfer_new(struct pipe_context *pcontext,
-                         struct pipe_resource *pt,
-                         unsigned level,
-                         unsigned usage,
-                         const struct pipe_box *box);
+                          struct pipe_resource *pt,
+                          unsigned level,
+                          unsigned usage,
+                          const struct pipe_box *box);
 void
 nv50_miptree_transfer_del(struct pipe_context *pcontext,
-                         struct pipe_transfer *ptx);
+                          struct pipe_transfer *ptx);
 void *
 nv50_miptree_transfer_map(struct pipe_context *pcontext,
-                         struct pipe_transfer *ptx);
+                          struct pipe_transfer *ptx);
 void
 nv50_miptree_transfer_unmap(struct pipe_context *pcontext,
-                           struct pipe_transfer *ptx);
+                            struct pipe_transfer *ptx);
 
-extern void
-nv50_upload_sifc(struct nv50_context *nv50,
-                struct nouveau_bo *bo, unsigned dst_offset, unsigned reloc,
-                unsigned dst_format, int dst_w, int dst_h, int dst_pitch,
-                void *src, unsigned src_format, int src_pitch,
-                int x, int y, int w, int h, int cpp);
+struct nv50_m2mf_rect {
+   struct nouveau_bo *bo;
+   uint32_t base;
+   unsigned domain;
+   uint32_t pitch;
+   uint32_t width;
+   uint32_t x;
+   uint32_t height;
+   uint32_t y;
+   uint16_t depth;
+   uint16_t z;
+   uint16_t tile_mode;
+   uint16_t cpp;
+};
 
 #endif
index 53f319acf468b8e6cda64f75f2a53a782ee3f404..0e0d48d661c81911a483fb722b543940549db16d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Ben Skeggs
+ * Copyright 2010 Christoph Bumiller
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "pipe/p_state.h"
 #include "util/u_inlines.h"
 #include "util/u_format.h"
-#include "util/u_split_prim.h"
+#include "translate/translate.h"
 
 #include "nv50_context.h"
 #include "nv50_resource.h"
 
-struct instance {
-       struct nouveau_bo *bo;
-       unsigned delta;
-       unsigned stride;
-       unsigned step;
-       unsigned divisor;
-};
+#include "nv50_3d.xml.h"
 
-static void
-instance_init(struct nv50_context *nv50, struct instance *a, unsigned first)
+void
+nv50_vertex_state_delete(struct pipe_context *pipe,
+                         void *hwcso)
 {
-       int i;
-
-       for (i = 0; i < nv50->vtxelt->num_elements; i++) {
-               struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
-               struct pipe_vertex_buffer *vb;
-
-               a[i].divisor = ve->instance_divisor;
-               if (a[i].divisor) {
-                       vb = &nv50->vtxbuf[ve->vertex_buffer_index];
-
-                       a[i].bo = nv50_resource(vb->buffer)->bo;
-                       a[i].stride = vb->stride;
-                       a[i].step = first % a[i].divisor;
-                       a[i].delta = vb->buffer_offset + ve->src_offset +
-                                    (first * a[i].stride);
-               }
-       }
+   struct nv50_vertex_stateobj *so = hwcso;
+
+   if (so->translate)
+      so->translate->release(so->translate);
+   FREE(hwcso);
 }
 
-static void
-instance_step(struct nv50_context *nv50, struct instance *a)
+void *
+nv50_vertex_state_create(struct pipe_context *pipe,
+                         unsigned num_elements,
+                         const struct pipe_vertex_element *elements)
 {
-       struct nouveau_channel *chan = nv50->screen->tesla->channel;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       int i;
-
-       for (i = 0; i < nv50->vtxelt->num_elements; i++) {
-               if (!a[i].divisor)
-                       continue;
-
-               BEGIN_RING(chan, tesla,
-                          NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2);
-               OUT_RELOCh(chan, a[i].bo, a[i].delta, NOUVEAU_BO_RD |
-                          NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
-               OUT_RELOCl(chan, a[i].bo, a[i].delta, NOUVEAU_BO_RD |
-                          NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
-               if (++a[i].step == a[i].divisor) {
-                       a[i].step = 0;
-                       a[i].delta += a[i].stride;
-               }
-       }
+    struct nv50_vertex_stateobj *so;
+    struct translate_key transkey;
+    unsigned i;
+
+    assert(num_elements);
+
+    so = MALLOC(sizeof(*so) +
+                (num_elements - 1) * sizeof(struct nv50_vertex_element));
+    if (!so)
+        return NULL;
+    so->num_elements = num_elements;
+    so->instance_elts = 0;
+    so->instance_bufs = 0;
+    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].pipe = elements[i];
+        so->element[i].state = nv50_format_table[fmt].vtx;
+
+        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 = nv50_format_table[fmt].vtx;
+            so->need_conversion = TRUE;
+        }
+        so->element[i].state |= i;
+
+        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;
+
+            if (unlikely(ve->instance_divisor)) {
+               so->instance_elts |= 1 << i;
+               so->instance_bufs |= 1 << vbi;
+            }
+        }
+    }
+
+    so->translate = translate_create(&transkey);
+    so->vertex_size = transkey.output_stride / 4;
+    so->packet_vertex_limit = NV04_PFIFO_MAX_PACKET_LEN /
+       MAX2(so->vertex_size, 1);
+
+    return so;
 }
 
+#define NV50_3D_VERTEX_ATTRIB_INACTIVE              \
+   NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT |         \
+   NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32_32 | \
+   NV50_3D_VERTEX_ARRAY_ATTRIB_CONST
+
 static void
-nv50_draw_arrays_instanced(struct pipe_context *pipe,
-                          unsigned mode, unsigned start, unsigned count,
-                          unsigned startInstance, unsigned instanceCount)
+nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb,
+                  struct pipe_vertex_element *ve, unsigned attr)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nouveau_channel *chan = nv50->screen->tesla->channel;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct instance a[16];
-       unsigned prim = nv50_prim(mode);
-
-       instance_init(nv50, a, startInstance);
-       if (!nv50_state_validate(nv50, 10 + 16*3))
-               return;
-
-       if (nv50->vbo_fifo) {
-               nv50_push_elements_instanced(pipe, NULL, 0, 0, mode, start,
-                                            count, startInstance,
-                                            instanceCount);
-               return;
-       }
-
-       BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
-       OUT_RING  (chan, NV50_CB_AUX | (24 << 8));
-       OUT_RING  (chan, startInstance);
-       while (instanceCount--) {
-               if (AVAIL_RING(chan) < (7 + 16*3)) {
-                       FIRE_RING(chan);
-                       if (!nv50_state_validate(nv50, 7 + 16*3)) {
-                               assert(0);
-                               return;
-                       }
-               }
-               instance_step(nv50, a);
-
-               BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
-               OUT_RING  (chan, prim);
-               BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2);
-               OUT_RING  (chan, start);
-               OUT_RING  (chan, count);
-               BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
-               OUT_RING  (chan, 0);
-
-               prim |= (1 << 28);
-       }
+   const void *data;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nv50_resource *res = nv50_resource(vb->buffer);
+   float v[4];
+   const unsigned nc = util_format_get_nr_components(ve->src_format);
+
+   data = nv50_resource_map_offset(nv50, 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_RING(chan, RING_3D(VTX_ATTR_4F_X(attr)), 4);
+      OUT_RINGf (chan, v[0]);
+      OUT_RINGf (chan, v[1]);
+      OUT_RINGf (chan, v[2]);
+      OUT_RINGf (chan, v[3]);
+      break;
+   case 3:
+      BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(attr)), 3);
+      OUT_RINGf (chan, v[0]);
+      OUT_RINGf (chan, v[1]);
+      OUT_RINGf (chan, v[2]);
+      break;
+   case 2:
+      BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(attr)), 2);
+      OUT_RINGf (chan, v[0]);
+      OUT_RINGf (chan, v[1]);
+      break;
+   case 1:
+      if (attr == nv50->vertprog->vp.edgeflag) {
+         BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
+         OUT_RING  (chan, v[0] ? 1 : 0);
+      }
+      BEGIN_RING(chan, RING_3D(VTX_ATTR_1F(attr)), 1);
+      OUT_RINGf (chan, v[0]);
+      break;
+   default:
+      assert(0);
+      break;
+   }
 }
 
-struct inline_ctx {
-       struct nv50_context *nv50;
-       void *map;
-};
+static INLINE void
+nv50_vbuf_range(struct nv50_context *nv50, int vbi,
+                uint32_t *base, uint32_t *size)
+{
+   if (unlikely(nv50->vertex->instance_bufs & (1 << vbi))) {
+      /* TODO: use min and max instance divisor to get a proper range */
+      *base = 0;
+      *size = nv50->vtxbuf[vbi].buffer->width0;
+   } else {
+      assert(nv50->vbo_max_index != ~0);
+      *base = nv50->vbo_min_index * nv50->vtxbuf[vbi].stride;
+      *size = (nv50->vbo_max_index -
+               nv50->vbo_min_index + 1) * nv50->vtxbuf[vbi].stride;
+   }
+}
 
 static void
-inline_elt08(void *priv, unsigned start, unsigned count)
+nv50_prevalidate_vbufs(struct nv50_context *nv50)
 {
-       struct inline_ctx *ctx = priv;
-       struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
-       struct nouveau_channel *chan = tesla->channel;
-       uint8_t *map = (uint8_t *)ctx->map + start;
-
-       if (count & 1) {
-               BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1);
-               OUT_RING  (chan, map[0]);
-               map++;
-               count &= ~1;
-       }
-
-       count >>= 1;
-       if (!count)
-               return;
-
-       BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count);
-       while (count--) {
-               OUT_RING(chan, (map[1] << 16) | map[0]);
-               map += 2;
-       }
+   struct pipe_vertex_buffer *vb;
+   struct nv50_resource *buf;
+   int i;
+   uint32_t base, size;
+
+   nv50->vbo_fifo = nv50->vbo_user = 0;
+
+   nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
+
+   for (i = 0; i < nv50->num_vtxbufs; ++i) {
+      vb = &nv50->vtxbuf[i];
+      if (!vb->stride)
+         continue;
+      buf = nv50_resource(vb->buffer);
+
+      /* NOTE: user buffers with temporary storage count as mapped by GPU */
+      if (!nv50_resource_mapped_by_gpu(vb->buffer)) {
+         if (nv50->vbo_push_hint) {
+            nv50->vbo_fifo = ~0;
+            continue;
+         } else {
+            if (buf->status & NV50_BUFFER_STATUS_USER_MEMORY) {
+               nv50->vbo_user |= 1 << i;
+               assert(vb->stride > vb->buffer_offset);
+               nv50_vbuf_range(nv50, i, &base, &size);
+               nv50_user_buffer_upload(buf, base, size);
+            } else {
+               nv50_buffer_migrate(nv50, buf, NOUVEAU_BO_GART);
+            }
+            nv50->vbo_dirty = TRUE;
+         }
+      }
+      nv50_bufctx_add_resident(nv50, NV50_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD);
+      nv50_buffer_adjust_score(nv50, buf, 1);
+   }
 }
 
 static void
-inline_elt16(void *priv, unsigned start, unsigned count)
+nv50_update_user_vbufs(struct nv50_context *nv50)
 {
-       struct inline_ctx *ctx = priv;
-       struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
-       struct nouveau_channel *chan = tesla->channel;
-       uint16_t *map = (uint16_t *)ctx->map + start;
-
-       if (count & 1) {
-               BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1);
-               OUT_RING  (chan, map[0]);
-               count &= ~1;
-               map++;
-       }
-
-       count >>= 1;
-       if (!count)
-               return;
-
-       BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count);
-       while (count--) {
-               OUT_RING(chan, (map[1] << 16) | map[0]);
-               map += 2;
-       }
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   uint32_t base, offset, size;
+   int i;
+   uint32_t written = 0;
+
+   for (i = 0; i < nv50->vertex->num_elements; ++i) {
+      struct pipe_vertex_element *ve = &nv50->vertex->element[i].pipe;
+      const int b = ve->vertex_buffer_index;
+      struct pipe_vertex_buffer *vb = &nv50->vtxbuf[b];
+      struct nv50_resource *buf = nv50_resource(vb->buffer);
+
+      if (!(nv50->vbo_user & (1 << b)))
+         continue;
+
+      if (!vb->stride) {
+         nv50_emit_vtxattr(nv50, vb, ve, i);
+         continue;
+      }
+      nv50_vbuf_range(nv50, b, &base, &size);
+
+      if (!(written & (1 << b))) {
+         written |= 1 << b;
+         nv50_user_buffer_upload(buf, base, size);
+      }
+      offset = vb->buffer_offset + ve->src_offset;
+
+      MARK_RING (chan, 6, 4);
+      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
+      OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD);
+      OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD);
+      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
+      OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD);
+      OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD);
+   }
+   nv50->vbo_dirty = TRUE;
 }
 
-static void
-inline_elt32(void *priv, unsigned start, unsigned count)
+static INLINE void
+nv50_release_user_vbufs(struct nv50_context *nv50)
 {
-       struct inline_ctx *ctx = priv;
-       struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
-       struct nouveau_channel *chan = tesla->channel;
+   uint32_t vbo_user = nv50->vbo_user;
 
-       BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, count);
-       OUT_RINGp    (chan, (uint32_t *)ctx->map + start, count);
+   while (vbo_user) {
+      int i = ffs(vbo_user) - 1;
+      vbo_user &= ~(1 << i);
+
+      nv50_buffer_release_gpu_storage(nv50_resource(nv50->vtxbuf[i].buffer));
+   }
 }
 
-static void
-inline_edgeflag(void *priv, boolean enabled)
+void
+nv50_vertex_arrays_validate(struct nv50_context *nv50)
 {
-       struct inline_ctx *ctx = priv;
-       struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
-       struct nouveau_channel *chan = tesla->channel;
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nv50_vertex_stateobj *vertex = nv50->vertex;
+   struct pipe_vertex_buffer *vb;
+   struct nv50_vertex_element *ve;
+   unsigned i;
+
+   if (unlikely(vertex->need_conversion)) {
+      nv50->vbo_fifo = ~0;
+      nv50->vbo_user = 0;
+   } else {
+      nv50_prevalidate_vbufs(nv50);
+   }
+
+   BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(0)), vertex->num_elements);
+   for (i = 0; i < vertex->num_elements; ++i) {
+      ve = &vertex->element[i];
+      vb = &nv50->vtxbuf[ve->pipe.vertex_buffer_index];
+
+      if (likely(vb->stride) || nv50->vbo_fifo) {
+         OUT_RING(chan, ve->state);
+      } else {
+         OUT_RING(chan, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST);
+         nv50->vbo_fifo &= ~(1 << i);
+      }
+   }
+
+   for (i = 0; i < vertex->num_elements; ++i) {
+      struct nv50_resource *res;
+      unsigned size, offset;
+      
+      ve = &vertex->element[i];
+      vb = &nv50->vtxbuf[ve->pipe.vertex_buffer_index];
+
+      if (unlikely(ve->pipe.instance_divisor)) {
+         if (!(nv50->state.instance_elts & (1 << i))) {
+            BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
+            OUT_RING  (chan, 1);
+         }
+         BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
+         OUT_RING  (chan, ve->pipe.instance_divisor);
+      } else
+      if (unlikely(nv50->state.instance_elts & (1 << i))) {
+         BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
+         OUT_RING  (chan, 0);
+      }
+
+      res = nv50_resource(vb->buffer);
+
+      if (nv50->vbo_fifo || unlikely(vb->stride == 0)) {
+         if (!nv50->vbo_fifo)
+            nv50_emit_vtxattr(nv50, vb, &ve->pipe, i);
+         BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
+         OUT_RING  (chan, 0);
+         continue;
+      }
+
+      size = vb->buffer->width0;
+      offset = ve->pipe.src_offset + vb->buffer_offset;
+
+      MARK_RING (chan, 8, 4);
+      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
+      OUT_RING  (chan, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
+      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
+      OUT_RESRCh(chan, res, size - 1, NOUVEAU_BO_RD);
+      OUT_RESRCl(chan, res, size - 1, NOUVEAU_BO_RD);
+      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
+      OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD);
+      OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD);
+   }
+   for (; i < nv50->state.num_vtxelts; ++i) {
+      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(i)), 1);
+      OUT_RING  (chan, NV50_3D_VERTEX_ATTRIB_INACTIVE);
+      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
+      OUT_RING  (chan, 0);
+   }
+
+   nv50->state.num_vtxelts = vertex->num_elements;
+   nv50->state.instance_elts = vertex->instance_elts;
+}
+
+#define NV50_PRIM_GL_CASE(n) \
+   case PIPE_PRIM_##n: return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n
 
-       BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
-       OUT_RING  (chan, enabled ? 1 : 0);
+static INLINE unsigned
+nv50_prim_gl(unsigned prim)
+{
+   switch (prim) {
+   NV50_PRIM_GL_CASE(POINTS);
+   NV50_PRIM_GL_CASE(LINES);
+   NV50_PRIM_GL_CASE(LINE_LOOP);
+   NV50_PRIM_GL_CASE(LINE_STRIP);
+   NV50_PRIM_GL_CASE(TRIANGLES);
+   NV50_PRIM_GL_CASE(TRIANGLE_STRIP);
+   NV50_PRIM_GL_CASE(TRIANGLE_FAN);
+   NV50_PRIM_GL_CASE(QUADS);
+   NV50_PRIM_GL_CASE(QUAD_STRIP);
+   NV50_PRIM_GL_CASE(POLYGON);
+   NV50_PRIM_GL_CASE(LINES_ADJACENCY);
+   NV50_PRIM_GL_CASE(LINE_STRIP_ADJACENCY);
+   NV50_PRIM_GL_CASE(TRIANGLES_ADJACENCY);
+   NV50_PRIM_GL_CASE(TRIANGLE_STRIP_ADJACENCY);
+   default:
+      return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS;
+      break;
+   }
 }
 
 static void
-nv50_draw_elements_inline(struct pipe_context *pipe,
-                         struct pipe_resource *indexBuffer, unsigned indexSize,
-                         unsigned mode, unsigned start, unsigned count,
-                         unsigned startInstance, unsigned instanceCount)
+nv50_draw_vbo_flush_notify(struct nouveau_channel *chan)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nouveau_channel *chan = nv50->screen->tesla->channel;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct pipe_transfer *transfer;
-       struct instance a[16];
-       struct inline_ctx ctx;
-       struct util_split_prim s;
-       boolean nzi = FALSE;
-       unsigned overhead;
-
-       overhead = 16*3; /* potential instance adjustments */
-       overhead += 4; /* Begin()/End() */
-       overhead += 4; /* potential edgeflag disable/reenable */
-       overhead += 3; /* potentially 3 VTX_ELT_U16/U32 packet headers */
-
-       s.priv = &ctx;
-       if (indexSize == 1)
-               s.emit = inline_elt08;
-       else
-       if (indexSize == 2)
-               s.emit = inline_elt16;
-       else
-               s.emit = inline_elt32;
-       s.edge = inline_edgeflag;
-
-       ctx.nv50 = nv50;
-       ctx.map = pipe_buffer_map(pipe, indexBuffer, PIPE_TRANSFER_READ, &transfer);
-       assert(ctx.map);
-       if (!ctx.map)
-               return;
-
-       instance_init(nv50, a, startInstance);
-       if (!nv50_state_validate(nv50, overhead + 6 + 3))
-               return;
-
-       BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
-       OUT_RING  (chan, NV50_CB_AUX | (24 << 8));
-       OUT_RING  (chan, startInstance);
-       while (instanceCount--) {
-               unsigned max_verts;
-               boolean done;
-
-               util_split_prim_init(&s, mode, start, count);
-               do {
-                       if (AVAIL_RING(chan) < (overhead + 6)) {
-                               FIRE_RING(chan);
-                               if (!nv50_state_validate(nv50, (overhead + 6))) {
-                                       assert(0);
-                                       return;
-                               }
-                       }
-
-                       max_verts = AVAIL_RING(chan) - overhead;
-                       if (max_verts > 2047)
-                               max_verts = 2047;
-                       if (indexSize != 4)
-                               max_verts <<= 1;
-                       instance_step(nv50, a);
-
-                       BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
-                       OUT_RING  (chan, nv50_prim(s.mode) | (nzi ? (1<<28) : 0));
-                       done = util_split_prim_next(&s, max_verts);
-                       BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
-                       OUT_RING  (chan, 0);
-               } while (!done);
-
-               nzi = TRUE;
-       }
-
-       pipe_buffer_unmap(pipe, transfer);
+   struct nv50_context *nv50 = chan->user_private;
+
+   nv50_screen_fence_update(nv50->screen, TRUE);
+
+   nv50_bufctx_emit_relocs(nv50);
 }
 
 static void
-nv50_draw_elements_instanced(struct pipe_context *pipe,
-                            struct pipe_resource *indexBuffer,
-                            unsigned indexSize, int indexBias,
-                            unsigned mode, unsigned start, unsigned count,
-                            unsigned startInstance, unsigned instanceCount)
+nv50_draw_arrays(struct nv50_context *nv50,
+                 unsigned mode, unsigned start, unsigned count,
+                 unsigned instance_count)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-       struct nouveau_channel *chan = nv50->screen->tesla->channel;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct instance a[16];
-       unsigned prim = nv50_prim(mode);
-
-       instance_init(nv50, a, startInstance);
-       if (!nv50_state_validate(nv50, 13 + 16*3))
-               return;
-
-       if (nv50->vbo_fifo) {
-               nv50_push_elements_instanced(pipe, indexBuffer, indexSize,
-                                            indexBias, mode, start, count,
-                                            startInstance, instanceCount);
-               return;
-       }
-
-       /* indices are uint32 internally, so large indexBias means negative */
-       BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_BASE, 1);
-       OUT_RING  (chan, indexBias);
-
-       if (!nv50_resource_mapped_by_gpu(indexBuffer) || indexSize == 1) {
-               nv50_draw_elements_inline(pipe, indexBuffer, indexSize,
-                                         mode, start, count, startInstance,
-                                         instanceCount);
-               return;
-       }
-
-       BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
-       OUT_RING  (chan, NV50_CB_AUX | (24 << 8));
-       OUT_RING  (chan, startInstance);
-       while (instanceCount--) {
-               if (AVAIL_RING(chan) < (7 + 16*3)) {
-                       FIRE_RING(chan);
-                       if (!nv50_state_validate(nv50, 10 + 16*3)) {
-                               assert(0);
-                               return;
-                       }
-               }
-               instance_step(nv50, a);
-
-               BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
-               OUT_RING  (chan, prim);
-               if (indexSize == 4) {
-                       BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
-                       OUT_RING  (chan, count);
-                       nouveau_pushbuf_submit(chan, 
-                                              nv50_resource(indexBuffer)->bo,
-                                              start << 2, count << 2);
-               } else
-               if (indexSize == 2) {
-                       unsigned vb_start = (start & ~1);
-                       unsigned vb_end = (start + count + 1) & ~1;
-                       unsigned dwords = (vb_end - vb_start) >> 1;
-
-                       BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
-                       OUT_RING  (chan, ((start & 1) << 31) | count);
-                       BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
-                       OUT_RING  (chan, dwords);
-                       nouveau_pushbuf_submit(chan,
-                                              nv50_resource(indexBuffer)->bo,
-                                              vb_start << 1, dwords << 2);
-                       BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
-                       OUT_RING  (chan, 0);
-               }
-               BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
-               OUT_RING  (chan, 0);
-
-               prim |= (1 << 28);
-       }
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   unsigned prim;
+
+   chan->flush_notify = nv50_draw_vbo_flush_notify;
+   chan->user_private = nv50;
+
+   prim = nv50_prim_gl(mode);
+
+   while (instance_count--) {
+      BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
+      OUT_RING  (chan, prim);
+      BEGIN_RING(chan, RING_3D(VERTEX_BUFFER_FIRST), 2);
+      OUT_RING  (chan, start);
+      OUT_RING  (chan, count);
+      BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
+      OUT_RING  (chan, 0);
+
+      prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
+   }
+
+   chan->flush_notify = nv50_default_flush_notify;
 }
 
-void
-nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+static void
+nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
+                              unsigned start, unsigned count)
 {
-       struct nv50_context *nv50 = nv50_context(pipe);
-
-       if (info->indexed && nv50->idxbuf.buffer) {
-               unsigned offset;
-
-               assert(nv50->idxbuf.offset % nv50->idxbuf.index_size == 0);
-               offset = nv50->idxbuf.offset / nv50->idxbuf.index_size;
-
-               nv50_draw_elements_instanced(pipe,
-                                            nv50->idxbuf.buffer,
-                                            nv50->idxbuf.index_size,
-                                            info->index_bias,
-                                            info->mode,
-                                            info->start + offset,
-                                            info->count,
-                                            info->start_instance,
-                                            info->instance_count);
-       }
-       else {
-               nv50_draw_arrays_instanced(pipe,
-                                          info->mode,
-                                          info->start,
-                                          info->count,
-                                          info->start_instance,
-                                          info->instance_count);
-       }
+   map += start;
+
+   if (count & 3) {
+      unsigned i;
+      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), count & 3);
+      for (i = 0; i < (count & 3); ++i)
+         OUT_RING(chan, *map++);
+      count &= ~3;
+   }
+   while (count) {
+      unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 4) / 4;
+
+      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U8), nr);
+      for (i = 0; i < nr; ++i) {
+         OUT_RING(chan,
+                  (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
+         map += 4;
+      }
+      count -= nr * 4;
+   }
 }
 
-static INLINE boolean
-nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
-                      struct nouveau_stateobj **pso,
-                      struct pipe_vertex_element *ve,
-                      struct pipe_vertex_buffer *vb)
-
+static void
+nv50_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
+                              unsigned start, unsigned count)
 {
-       struct nouveau_stateobj *so;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo;
-       float v[4];
-       int ret;
-       unsigned nr_components = util_format_get_nr_components(ve->src_format);
-
-       ret = nouveau_bo_map(bo, NOUVEAU_BO_RD);
-       if (ret)
-               return FALSE;
-
-       util_format_read_4f(ve->src_format, v, 0, (uint8_t *)bo->map +
-                           (vb->buffer_offset + ve->src_offset), 0,
-                           0, 0, 1, 1);
-       so = *pso;
-       if (!so)
-               *pso = so = so_new(nv50->vtxelt->num_elements,
-                                  nv50->vtxelt->num_elements * 4, 0);
-
-       switch (nr_components) {
-       case 4:
-               so_method(so, tesla, NV50TCL_VTX_ATTR_4F_X(attrib), 4);
-               so_data  (so, fui(v[0]));
-               so_data  (so, fui(v[1]));
-               so_data  (so, fui(v[2]));
-               so_data  (so, fui(v[3]));
-               break;
-       case 3:
-               so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 3);
-               so_data  (so, fui(v[0]));
-               so_data  (so, fui(v[1]));
-               so_data  (so, fui(v[2]));
-               break;
-       case 2:
-               so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 2);
-               so_data  (so, fui(v[0]));
-               so_data  (so, fui(v[1]));
-               break;
-       case 1:
-               if (attrib == nv50->vertprog->vp.edgeflag) {
-                       so_method(so, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
-                       so_data  (so, v[0] ? 1 : 0);
-               }
-               so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 1);
-               so_data  (so, fui(v[0]));
-               break;
-       default:
-               nouveau_bo_unmap(bo);
-               return FALSE;
-       }
-
-       nouveau_bo_unmap(bo);
-       return TRUE;
+   map += start;
+
+   if (count & 1) {
+      count &= ~1;
+      BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
+      OUT_RING  (chan, *map++);
+   }
+   while (count) {
+      unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
+
+      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
+      for (i = 0; i < nr; ++i) {
+         OUT_RING(chan, (map[1] << 16) | map[0]);
+         map += 2;
+      }
+      count -= nr * 2;
+   }
 }
 
-void
-nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso)
+static void
+nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
+                              unsigned start, unsigned count)
 {
-       unsigned i;
+   map += start;
+
+   while (count) {
+      const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
 
-       for (i = 0; i < cso->num_elements; ++i)
-               cso->hw[i] = nv50_format_table[cso->pipe[i].src_format].vtx;
+      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), nr);
+      OUT_RINGp    (chan, map, nr);
+
+      map += nr;
+      count -= nr;
+   }
 }
 
-struct nouveau_stateobj *
-nv50_vbo_validate(struct nv50_context *nv50)
+static void
+nv50_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map,
+                                    unsigned start, unsigned count)
 {
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *vtxbuf, *vtxfmt, *vtxattr;
-       unsigned i, n_ve;
-
-       /* don't validate if Gallium took away our buffers */
-       if (nv50->vtxbuf_nr == 0)
-               return NULL;
-
-       nv50->vbo_fifo = 0;
-       if (nv50->screen->force_push ||
-           nv50->vertprog->vp.edgeflag < 16)
-               nv50->vbo_fifo = 0xffff;
-
-       for (i = 0; i < nv50->vtxbuf_nr; i++) {
-               if (nv50->vtxbuf[i].stride &&
-                   !nv50_resource_mapped_by_gpu(nv50->vtxbuf[i].buffer))
-                       nv50->vbo_fifo = 0xffff;
-       }
-
-       n_ve = MAX2(nv50->vtxelt->num_elements, nv50->state.vtxelt_nr);
-
-       vtxattr = NULL;
-       vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt->num_elements * 4);
-       vtxfmt = so_new(1, n_ve, 0);
-       so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0), n_ve);
-
-       for (i = 0; i < nv50->vtxelt->num_elements; i++) {
-               struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
-               struct pipe_vertex_buffer *vb =
-                       &nv50->vtxbuf[ve->vertex_buffer_index];
-               struct nouveau_bo *bo = nv50_resource(vb->buffer)->bo;
-               uint32_t hw = nv50->vtxelt->hw[i];
-
-               if (!vb->stride &&
-                   nv50_vbo_static_attrib(nv50, i, &vtxattr, ve, vb)) {
-                       so_data(vtxfmt, hw | (1 << 4));
-
-                       so_method(vtxbuf, tesla,
-                                 NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
-                       so_data  (vtxbuf, 0);
-
-                       nv50->vbo_fifo &= ~(1 << i);
-                       continue;
-               }
-
-               if (nv50->vbo_fifo) {
-                       so_data  (vtxfmt, hw | (ve->instance_divisor ? (1 << 4) : i));
-                       so_method(vtxbuf, tesla,
-                                 NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
-                       so_data  (vtxbuf, 0);
-                       continue;
-               }
-
-               so_data(vtxfmt, hw | i);
-
-               so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3);
-               so_data  (vtxbuf, 0x20000000 |
-                         (ve->instance_divisor ? 0 : vb->stride));
-               so_reloc (vtxbuf, bo, vb->buffer_offset +
-                         ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
-                         NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
-               so_reloc (vtxbuf, bo, vb->buffer_offset +
-                         ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
-                         NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
-
-               /* vertex array limits */
-               so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
-               so_reloc (vtxbuf, bo, vb->buffer->width0 - 1,
-                         NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
-                         NOUVEAU_BO_HIGH, 0, 0);
-               so_reloc (vtxbuf, bo, vb->buffer->width0 - 1,
-                         NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
-                         NOUVEAU_BO_LOW, 0, 0);
-       }
-       for (; i < n_ve; ++i) {
-               so_data  (vtxfmt, 0x7e080010);
-
-               so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
-               so_data  (vtxbuf, 0);
-       }
-       nv50->state.vtxelt_nr = nv50->vtxelt->num_elements;
-
-       so_ref (vtxbuf, &nv50->state.vtxbuf);
-       so_ref (vtxattr, &nv50->state.vtxattr);
-       so_ref (NULL, &vtxbuf);
-       so_ref (NULL, &vtxattr);
-       return vtxfmt;
+   map += start;
+
+   if (count & 1) {
+      count--;
+      BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
+      OUT_RING  (chan, *map++);
+   }
+   while (count) {
+      unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
+
+      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
+      for (i = 0; i < nr; ++i) {
+         OUT_RING(chan, (map[1] << 16) | map[0]);
+         map += 2;
+      }
+      count -= nr * 2;
+   }
 }
 
+static void
+nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
+                   unsigned mode, unsigned start, unsigned count,
+                   unsigned instance_count, int32_t index_bias)
+{
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+   void *data;
+   unsigned prim;
+   const unsigned index_size = nv50->idxbuf.index_size;
+
+   chan->flush_notify = nv50_draw_vbo_flush_notify;
+   chan->user_private = nv50;
+
+   prim = nv50_prim_gl(mode);
+
+   if (index_bias != nv50->state.index_bias) {
+      BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1);
+      OUT_RING  (chan, index_bias);
+      nv50->state.index_bias = index_bias;
+   }
+
+   if (nv50_resource_mapped_by_gpu(nv50->idxbuf.buffer) && 0) {
+      struct nv50_resource *res = nv50_resource(nv50->idxbuf.buffer);
+      unsigned offset = res->offset + nv50->idxbuf.offset;
+
+      nv50_buffer_adjust_score(nv50, res, 1);
+
+      while (instance_count--) {
+         BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
+         OUT_RING  (chan, mode);
+
+         switch (index_size) {
+         case 4:
+         {
+            WAIT_RING (chan, 2);
+            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32) | 0x30000, 0);
+            OUT_RING  (chan, count);
+            nouveau_pushbuf_submit(chan, res->bo,
+                                   (start << 2) + offset,
+                                   (count << 2));
+         }
+            break;
+         case 2:
+         {
+            unsigned pb_start = (start & ~1);
+            unsigned pb_words = (((start + count + 1) & ~1) - pb_start) >> 1;
+
+            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1);
+            OUT_RING  (chan, (start << 31) | count);
+            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16) | 0x30000, 0);
+            OUT_RING  (chan, pb_words);
+            nouveau_pushbuf_submit(chan, res->bo,
+                                   (pb_start << 1) + offset, pb_words << 2);
+            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1);
+            OUT_RING  (chan, 0);
+            break;
+         }
+         case 1:
+         {
+            unsigned pb_start = (start & ~3);
+            unsigned pb_words = (((start + count + 3) & ~3) - pb_start) >> 1;
+
+            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1);
+            OUT_RING  (chan, (start << 30) | count);
+            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8) | 0x30000, 0);
+            OUT_RING  (chan, pb_words);
+            nouveau_pushbuf_submit(chan, res->bo,
+                                   pb_start + offset, pb_words << 2);
+            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1);
+            OUT_RING  (chan, 0);
+            break;
+         }
+         default:
+            assert(0);
+            return;
+         }
+
+         nv50_resource_fence(res, NOUVEAU_BO_RD);
+
+         mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
+      }
+   } else {
+      data = nv50_resource_map_offset(nv50, nv50_resource(nv50->idxbuf.buffer),
+                                      nv50->idxbuf.offset, NOUVEAU_BO_RD);
+      if (!data)
+         return;
+
+      while (instance_count--) {
+         BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
+         OUT_RING  (chan, prim);
+         switch (index_size) {
+         case 1:
+            nv50_draw_elements_inline_u08(chan, data, start, count);
+            break;
+         case 2:
+            nv50_draw_elements_inline_u16(chan, data, start, count);
+            break;
+         case 4:
+            if (shorten)
+               nv50_draw_elements_inline_u32_short(chan, data, start, count);
+            else
+               nv50_draw_elements_inline_u32(chan, data, start, count);
+            break;
+         default:
+            assert(0);
+            return;
+         }
+         BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
+         OUT_RING  (chan, 0);
+
+         prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
+      }
+   }
+
+   chan->flush_notify = nv50_default_flush_notify;
+}
 
+void
+nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+   struct nv50_context *nv50 = nv50_context(pipe);
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+
+   /* 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.
+    */
+   nv50->vbo_push_hint = /* the 64 is heuristic */
+      !(info->indexed &&
+        ((info->max_index - info->min_index + 64) < info->count));
+
+   nv50->vbo_min_index = info->min_index;
+   nv50->vbo_max_index = info->max_index;
+
+   if (nv50->vbo_push_hint != !!nv50->vbo_fifo)
+      nv50->dirty |= NV50_NEW_ARRAYS;
+
+   if (nv50->vbo_user && !(nv50->dirty & (NV50_NEW_VERTEX | NV50_NEW_ARRAYS)))
+      nv50_update_user_vbufs(nv50);
+
+   nv50_state_validate(nv50);
+
+   if (nv50->vbo_fifo) {
+      nv50_push_vbo(nv50, info);
+      return;
+   }
+
+   if (nv50->state.instance_base != info->start_instance) {
+      nv50->state.instance_base = info->start_instance;
+      /* NOTE: this does not affect the shader input, should it ? */
+      BEGIN_RING(chan, RING_3D(VB_INSTANCE_BASE), 1);
+      OUT_RING  (chan, info->start_instance);
+   }
+
+   if (nv50->vbo_dirty) {
+      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1);
+      OUT_RING  (chan, 0);
+      nv50->vbo_dirty = FALSE;
+   }
+
+   if (!info->indexed) {
+      nv50_draw_arrays(nv50,
+                       info->mode, info->start, info->count,
+                       info->instance_count);
+   } else {
+      boolean shorten = info->max_index <= 65535;
+
+      assert(nv50->idxbuf.buffer);
+
+      if (info->primitive_restart != nv50->state.prim_restart) {
+         if (info->primitive_restart) {
+            BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 2);
+            OUT_RING  (chan, 1);
+            OUT_RING  (chan, info->restart_index);
+
+            if (info->restart_index > 65535)
+               shorten = FALSE;
+         } else {
+            BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 1);
+            OUT_RING  (chan, 0);
+         }
+         nv50->state.prim_restart = info->primitive_restart;
+      } else
+      if (info->primitive_restart) {
+         BEGIN_RING(chan, RING_3D(PRIM_RESTART_INDEX), 1);
+         OUT_RING  (chan, info->restart_index);
+
+         if (info->restart_index > 65535)
+            shorten = FALSE;
+      }
+
+      nv50_draw_elements(nv50, shorten,
+                         info->mode, info->start, info->count,
+                         info->instance_count, info->index_bias);
+   }
+
+   nv50_release_user_vbufs(nv50);
+}
diff --git a/src/gallium/drivers/nv50/nv50_winsys.h b/src/gallium/drivers/nv50/nv50_winsys.h
new file mode 100644 (file)
index 0000000..8aaf24c
--- /dev/null
@@ -0,0 +1,104 @@
+
+#ifndef __NV50_WINSYS_H__
+#define __NV50_WINSYS_H__
+
+#include <stdint.h>
+#include <unistd.h>
+#include "pipe/p_defines.h"
+
+#include "nouveau/nouveau_bo.h"
+#include "nouveau/nouveau_channel.h"
+#include "nouveau/nouveau_grobj.h"
+#include "nouveau/nouveau_device.h"
+#include "nouveau/nouveau_resource.h"
+#include "nouveau/nouveau_pushbuf.h"
+#include "nouveau/nouveau_reloc.h"
+
+#include "nv50_resource.h" /* OUT_RESRC */
+
+#ifndef NV04_PFIFO_MAX_PACKET_LEN
+#define NV04_PFIFO_MAX_PACKET_LEN 2047
+#endif
+
+#define NV50_SUBCH_3D 5
+#define NV50_SUBCH_2D 6
+#define NV50_SUBCH_MF 7
+
+#define NV50_MF_(n) NV50_M2MF_##n
+
+#define RING_3D(n) ((NV50_SUBCH_3D << 13) | NV50_3D_##n)
+#define RING_2D(n) ((NV50_SUBCH_2D << 13) | NV50_2D_##n)
+#define RING_MF(n) ((NV50_SUBCH_MF << 13) | NV50_MF_(n))
+
+#define RING_3D_(m) ((NV50_SUBCH_3D << 13) | (m))
+#define RING_2D_(m) ((NV50_SUBCH_2D << 13) | (m))
+#define RING_MF_(m) ((NV50_SUBCH_MF << 13) | (m))
+
+#define RING_GR(gr, m) (((gr)->subc << 13) | (m))
+
+int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
+
+static inline uint32_t
+nouveau_bo_tile_layout(struct nouveau_bo *bo)
+{
+   return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK;
+}
+
+static INLINE void
+nouveau_bo_validate(struct nouveau_channel *chan,
+                    struct nouveau_bo *bo, unsigned flags)
+{
+   nouveau_reloc_emit(chan, NULL, 0, NULL, bo, 0, 0, flags, 0, 0);
+}
+
+/* incremental methods */
+static INLINE void
+BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+{
+   WAIT_RING(chan, size + 1);
+   OUT_RING (chan, (size << 18) | mthd);
+}
+
+/* non-incremental */
+static INLINE void
+BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+{
+   WAIT_RING(chan, size + 1);
+   OUT_RING (chan, (0x2 << 29) | (size << 18) | mthd);
+}
+
+static INLINE int
+OUT_RESRCh(struct nouveau_channel *chan, struct nv50_resource *res,
+           unsigned delta, unsigned flags)
+{
+   return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags);
+}
+
+static INLINE int
+OUT_RESRCl(struct nouveau_channel *chan, struct nv50_resource *res,
+           unsigned delta, unsigned flags)
+{
+   if (flags & NOUVEAU_BO_WR)
+      res->status |= NV50_BUFFER_STATUS_DIRTY;
+   return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
+}
+
+static INLINE void
+BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned s)
+{
+   struct nouveau_subchannel *subc = &gr->channel->subc[s];
+
+   assert(s < 8);
+   if (subc->gr) {
+      assert(subc->gr->bound != NOUVEAU_GROBJ_BOUND_EXPLICIT);
+      subc->gr->bound = NOUVEAU_GROBJ_UNBOUND;
+   }
+   subc->gr = gr;
+   subc->gr->subc = s;
+   subc->gr->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
+
+   BEGIN_RING(chan, RING_GR(gr, 0x0000), 1);
+   OUT_RING  (chan, gr->handle);
+}
+
+#endif