summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nv50/Makefile9
-rw-r--r--src/gallium/drivers/nv50/SConscript8
-rw-r--r--src/gallium/drivers/nv50/nv50_2d.xml.h393
-rw-r--r--src/gallium/drivers/nv50/nv50_3d.xml.h2084
-rw-r--r--src/gallium/drivers/nv50/nv50_3ddefs.xml.h98
-rw-r--r--src/gallium/drivers/nv50/nv50_buffer.c529
-rw-r--r--src/gallium/drivers/nv50/nv50_clear.c74
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c173
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h394
-rw-r--r--src/gallium/drivers/nv50/nv50_defs.xml.h142
-rw-r--r--src/gallium/drivers/nv50/nv50_draw.c37
-rw-r--r--src/gallium/drivers/nv50/nv50_fence.c216
-rw-r--r--src/gallium/drivers/nv50/nv50_fence.h49
-rw-r--r--src/gallium/drivers/nv50/nv50_formats.c146
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c484
-rw-r--r--src/gallium/drivers/nv50/nv50_mm.c277
-rw-r--r--src/gallium/drivers/nv50/nv50_pc.c5
-rw-r--r--src/gallium/drivers/nv50/nv50_pc.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_pc_optimize.c6
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c17
-rw-r--r--src/gallium/drivers/nv50/nv50_program.h7
-rw-r--r--src/gallium/drivers/nv50/nv50_push.c488
-rw-r--r--src/gallium/drivers/nv50/nv50_query.c362
-rw-r--r--src/gallium/drivers/nv50/nv50_reg.h1827
-rw-r--r--src/gallium/drivers/nv50/nv50_resource.c79
-rw-r--r--src/gallium/drivers/nv50/nv50_resource.h178
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c1120
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h190
-rw-r--r--src/gallium/drivers/nv50/nv50_shader_state.c675
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c1286
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c641
-rw-r--r--src/gallium/drivers/nv50/nv50_stateobj.h72
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c568
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c438
-rw-r--r--src/gallium/drivers/nv50/nv50_texture.h197
-rw-r--r--src/gallium/drivers/nv50/nv50_texture.xml.h259
-rw-r--r--src/gallium/drivers/nv50/nv50_tgsi_to_nc.c18
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c636
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.h39
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c1119
-rw-r--r--src/gallium/drivers/nv50/nv50_winsys.h104
41 files changed, 8825 insertions, 6621 deletions
diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile
index b3535c0976e..d0a60c7ac13 100644
--- a/src/gallium/drivers/nv50/Makefile
+++ b/src/gallium/drivers/nv50/Makefile
@@ -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)
diff --git a/src/gallium/drivers/nv50/SConscript b/src/gallium/drivers/nv50/SConscript
index 8e7892a9ab6..84644515ede 100644
--- a/src/gallium/drivers/nv50/SConscript
+++ b/src/gallium/drivers/nv50/SConscript
@@ -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
index 00000000000..bc9bcf7839e
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_2d.xml.h
@@ -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 <[email protected]> (ahuillet)
+- Ben Skeggs (darktama, darktama_)
+- B. R. <[email protected]> (koala_br)
+- Carlos Martin <[email protected]> (carlosmn)
+- Christoph Bumiller <[email protected]> (calim, chrisbmr)
+- Dawid Gajownik <[email protected]> (gajownik)
+- Dmitry Baryshkov
+- Dmitry Eremin-Solenikov <[email protected]> (lumag)
+- EdB <[email protected]> (edb_)
+- Erik Waling <[email protected]> (erikwaling)
+- Francisco Jerez <[email protected]> (curro)
+- imirkin <[email protected]> (imirkin)
+- jb17bsome <[email protected]> (jb17bsome)
+- Jeremy Kolb <[email protected]> (kjeremy)
+- Laurent Carlier <[email protected]> (lordheavy)
+- Luca Barbieri <[email protected]> (lb, lb1)
+- Maarten Maathuis <[email protected]> (stillunknown)
+- Marcin Koƛcielnicki <[email protected]> (mwk, koriakin)
+- Mark Carey <[email protected]> (careym)
+- Matthieu Castet <[email protected]> (mat-c)
+- nvidiaman <[email protected]> (nvidiaman)
+- Patrice Mandin <[email protected]> (pmandin, pmdata)
+- Pekka Paalanen <[email protected]> (pq, ppaalanen)
+- Peter Popov <[email protected]> (ironpeter)
+- Richard Hughes <[email protected]> (hughsient)
+- Rudi Cilibrasi <[email protected]> (cilibrar)
+- Serge Martin
+- Simon Raffeiner
+- Stephane Loeuillet <[email protected]> (leroutier)
+- Stephane Marchesin <[email protected]> (marcheu)
+- sturmflut <[email protected]> (sturmflut)
+- Sylvain Munaut <[email protected]>
+- Victor Stinner <[email protected]> (haypo)
+- Wladmir van der Laan <[email protected]> (miathan6)
+- Younes Manton <[email protected]> (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
index 00000000000..eb05bd40951
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_3d.xml.h
@@ -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 <[email protected]> (ahuillet)
+- Ben Skeggs (darktama, darktama_)
+- B. R. <[email protected]> (koala_br)
+- Carlos Martin <[email protected]> (carlosmn)
+- Christoph Bumiller <[email protected]> (calim, chrisbmr)
+- Dawid Gajownik <[email protected]> (gajownik)
+- Dmitry Baryshkov
+- Dmitry Eremin-Solenikov <[email protected]> (lumag)
+- EdB <[email protected]> (edb_)
+- Erik Waling <[email protected]> (erikwaling)
+- Francisco Jerez <[email protected]> (curro)
+- imirkin <[email protected]> (imirkin)
+- jb17bsome <[email protected]> (jb17bsome)
+- Jeremy Kolb <[email protected]> (kjeremy)
+- Laurent Carlier <[email protected]> (lordheavy)
+- Luca Barbieri <[email protected]> (lb, lb1)
+- Maarten Maathuis <[email protected]> (stillunknown)
+- Marcin Koƛcielnicki <[email protected]> (mwk, koriakin)
+- Mark Carey <[email protected]> (careym)
+- Matthieu Castet <[email protected]> (mat-c)
+- nvidiaman <[email protected]> (nvidiaman)
+- Patrice Mandin <[email protected]> (pmandin, pmdata)
+- Pekka Paalanen <[email protected]> (pq, ppaalanen)
+- Peter Popov <[email protected]> (ironpeter)
+- Richard Hughes <[email protected]> (hughsient)
+- Rudi Cilibrasi <[email protected]> (cilibrar)
+- Serge Martin
+- Simon Raffeiner
+- Stephane Loeuillet <[email protected]> (leroutier)
+- Stephane Marchesin <[email protected]> (marcheu)
+- sturmflut <[email protected]> (sturmflut)
+- Sylvain Munaut <[email protected]>
+- Victor Stinner <[email protected]> (haypo)
+- Wladmir van der Laan <[email protected]> (miathan6)
+- Younes Manton <[email protected]> (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
index 00000000000..f26ac45da40
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_3ddefs.xml.h
@@ -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 <[email protected]> (ahuillet)
+- Ben Skeggs (darktama, darktama_)
+- B. R. <[email protected]> (koala_br)
+- Carlos Martin <[email protected]> (carlosmn)
+- Christoph Bumiller <[email protected]> (calim, chrisbmr)
+- Dawid Gajownik <[email protected]> (gajownik)
+- Dmitry Baryshkov
+- Dmitry Eremin-Solenikov <[email protected]> (lumag)
+- EdB <[email protected]> (edb_)
+- Erik Waling <[email protected]> (erikwaling)
+- Francisco Jerez <[email protected]> (curro, curro_, currojerez)
+- imirkin <[email protected]> (imirkin)
+- jb17bsome <[email protected]> (jb17bsome)
+- Jeremy Kolb <[email protected]> (kjeremy)
+- Laurent Carlier <[email protected]> (lordheavy)
+- Luca Barbieri <[email protected]> (lb, lb1)
+- Maarten Maathuis <[email protected]> (stillunknown)
+- Marcin Koƛcielnicki <[email protected]> (mwk, koriakin)
+- Mark Carey <[email protected]> (careym)
+- Matthieu Castet <[email protected]> (mat-c)
+- nvidiaman <[email protected]> (nvidiaman)
+- Patrice Mandin <[email protected]> (pmandin, pmdata)
+- Pekka Paalanen <[email protected]> (pq, ppaalanen)
+- Peter Popov <[email protected]> (ironpeter)
+- Richard Hughes <[email protected]> (hughsient)
+- Rudi Cilibrasi <[email protected]> (cilibrar)
+- Serge Martin
+- Simon Raffeiner
+- Stephane Loeuillet <[email protected]> (leroutier)
+- Stephane Marchesin <[email protected]> (marcheu)
+- sturmflut <[email protected]> (sturmflut)
+- Sylvain Munaut <[email protected]>
+- Victor Stinner <[email protected]> (haypo)
+- Wladmir van der Laan <[email protected]> (miathan6)
+- Younes Manton <[email protected]> (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 */
diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c
index 45356f9f637..5cb2e628e7a 100644
--- a/src/gallium/drivers/nv50/nv50_buffer.c
+++ b/src/gallium/drivers/nv50/nv50_buffer.c
@@ -3,149 +3,492 @@
#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
index ee7cf281f4a..00000000000
--- a/src/gallium/drivers/nv50/nv50_clear.c
+++ /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;
-}
-
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 4f976161760..bb6272a4a23 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -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"),
@@ -27,80 +27,153 @@
#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);
}
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index b2b0b72fe26..a6275d79587 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -5,265 +5,227 @@
#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
index 00000000000..1bf2f802b56
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_defs.xml.h
@@ -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 <[email protected]> (ahuillet)
+- Ben Skeggs (darktama, darktama_)
+- B. R. <[email protected]> (koala_br)
+- Carlos Martin <[email protected]> (carlosmn)
+- Christoph Bumiller <[email protected]> (calim, chrisbmr)
+- Dawid Gajownik <[email protected]> (gajownik)
+- Dmitry Baryshkov
+- Dmitry Eremin-Solenikov <[email protected]> (lumag)
+- EdB <[email protected]> (edb_)
+- Erik Waling <[email protected]> (erikwaling)
+- Francisco Jerez <[email protected]> (curro, curro_, currojerez)
+- imirkin <[email protected]> (imirkin)
+- jb17bsome <[email protected]> (jb17bsome)
+- Jeremy Kolb <[email protected]> (kjeremy)
+- Laurent Carlier <[email protected]> (lordheavy)
+- Luca Barbieri <[email protected]> (lb, lb1)
+- Maarten Maathuis <[email protected]> (stillunknown)
+- Marcin Koƛcielnicki <[email protected]> (mwk, koriakin)
+- Mark Carey <[email protected]> (careym)
+- Matthieu Castet <[email protected]> (mat-c)
+- nvidiaman <[email protected]> (nvidiaman)
+- Patrice Mandin <[email protected]> (pmandin, pmdata)
+- Pekka Paalanen <[email protected]> (pq, ppaalanen)
+- Peter Popov <[email protected]> (ironpeter)
+- Richard Hughes <[email protected]> (hughsient)
+- Rudi Cilibrasi <[email protected]> (cilibrar)
+- Serge Martin
+- Simon Raffeiner
+- Stephane Loeuillet <[email protected]> (leroutier)
+- Stephane Marchesin <[email protected]> (marcheu)
+- sturmflut <[email protected]> (sturmflut)
+- Sylvain Munaut <[email protected]>
+- Victor Stinner <[email protected]> (haypo)
+- Wladmir van der Laan <[email protected]> (miathan6)
+- Younes Manton <[email protected]> (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 */
diff --git a/src/gallium/drivers/nv50/nv50_draw.c b/src/gallium/drivers/nv50/nv50_draw.c
index 2f6f607261e..1d8598829c5 100644
--- a/src/gallium/drivers/nv50/nv50_draw.c
+++ b/src/gallium/drivers/nv50/nv50_draw.c
@@ -25,32 +25,32 @@
#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
index 00000000000..936cf81ac75
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_fence.c
@@ -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
index 00000000000..dd0b74e89fa
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_fence.h
@@ -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__
diff --git a/src/gallium/drivers/nv50/nv50_formats.c b/src/gallium/drivers/nv50/nv50_formats.c
index 42828094547..194e826fa66 100644
--- a/src/gallium/drivers/nv50/nv50_formats.c
+++ b/src/gallium/drivers/nv50/nv50_formats.c
@@ -21,26 +21,34 @@
*/
#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
@@ -49,98 +57,96 @@
#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 },
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 309b6503ca5..a7bd5bcbb6f 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -29,300 +29,288 @@
#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
index 00000000000..f991d6192e8
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_mm.c
@@ -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);
+ }
+}
+
diff --git a/src/gallium/drivers/nv50/nv50_pc.c b/src/gallium/drivers/nv50/nv50_pc.c
index c88e7ba742e..82f1b846527 100644
--- a/src/gallium/drivers/nv50/nv50_pc.c
+++ b/src/gallium/drivers/nv50/nv50_pc.c
@@ -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);
diff --git a/src/gallium/drivers/nv50/nv50_pc.h b/src/gallium/drivers/nv50/nv50_pc.h
index 2ead80430b0..e6f3815bafe 100644
--- a/src/gallium/drivers/nv50/nv50_pc.h
+++ b/src/gallium/drivers/nv50/nv50_pc.h
@@ -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
diff --git a/src/gallium/drivers/nv50/nv50_pc_optimize.c b/src/gallium/drivers/nv50/nv50_pc_optimize.c
index 679e5ea1485..281ccf7ac61 100644
--- a/src/gallium/drivers/nv50/nv50_pc_optimize.c
+++ b/src/gallium/drivers/nv50/nv50_pc_optimize.c
@@ -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;
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index db681764910..1c1a4201b60 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -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);
diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h
index 33c4c8ca6df..8f5b51757d8 100644
--- a/src/gallium/drivers/nv50/nv50_program.h
+++ b/src/gallium/drivers/nv50/nv50_program.h
@@ -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)
diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c
index 380f69406a2..51ada6d7499 100644
--- a/src/gallium/drivers/nv50/nv50_push.c
+++ b/src/gallium/drivers/nv50/nv50_push.c
@@ -1,362 +1,292 @@
+
#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));
}
diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c
index f3418df8381..e769aa18fe9 100644
--- a/src/gallium/drivers/nv50/nv50_query.c
+++ b/src/gallium/drivers/nv50/nv50_query.c
@@ -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"),
@@ -18,150 +18,318 @@
* 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
index 949838b33f5..00000000000
--- a/src/gallium/drivers/nv50/nv50_reg.h
+++ /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:[email protected]:/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 */
diff --git a/src/gallium/drivers/nv50/nv50_resource.c b/src/gallium/drivers/nv50/nv50_resource.c
index 6c0a9696355..ae1a2bf55da 100644
--- a/src/gallium/drivers/nv50/nv50_resource.c
+++ b/src/gallium/drivers/nv50/nv50_resource.c
@@ -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;
}
diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h
index 4b2a75e11ad..f0e022b320b 100644
--- a/src/gallium/drivers/nv50/nv50_resource.h
+++ b/src/gallium/drivers/nv50/nv50_resource.h
@@ -1,61 +1,164 @@
-#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
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index edc3d54d012..77cf959940d 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -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"),
@@ -23,598 +23,628 @@
#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;
+}
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index 6e15230b486..c78ed50fe35 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -1,53 +1,193 @@
#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
diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c
index 1c1b66deb3c..e530b3390a9 100644
--- a/src/gallium/drivers/nv50/nv50_shader_state.c
+++ b/src/gallium/drivers/nv50/nv50_shader_state.c
@@ -28,422 +28,234 @@
#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);
}
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index ba2c3e8c281..5e1fff46e41 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -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"),
@@ -20,873 +20,829 @@
* 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;
}
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index ae02143e352..a8f48b2a28e 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -1,449 +1,286 @@
-/*
- * 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
index 00000000000..49f1837bfeb
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_stateobj.h
@@ -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
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index a99df76cee3..b1f54f623ab 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -20,306 +20,360 @@
* 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;
}
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index 9243f9edced..93e74ca0597 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -21,217 +21,273 @@
*/
#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
index b4939943e8a..00000000000
--- a/src/gallium/drivers/nv50/nv50_texture.h
+++ /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
index 00000000000..9f83206516f
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_texture.xml.h
@@ -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 <[email protected]> (ahuillet)
+- Ben Skeggs (darktama, darktama_)
+- B. R. <[email protected]> (koala_br)
+- Carlos Martin <[email protected]> (carlosmn)
+- Christoph Bumiller <[email protected]> (calim, chrisbmr)
+- Dawid Gajownik <[email protected]> (gajownik)
+- Dmitry Baryshkov
+- Dmitry Eremin-Solenikov <[email protected]> (lumag)
+- EdB <[email protected]> (edb_)
+- Erik Waling <[email protected]> (erikwaling)
+- Francisco Jerez <[email protected]> (curro, curro_, currojerez)
+- imirkin <[email protected]> (imirkin)
+- jb17bsome <[email protected]> (jb17bsome)
+- Jeremy Kolb <[email protected]> (kjeremy)
+- Laurent Carlier <[email protected]> (lordheavy)
+- Luca Barbieri <[email protected]> (lb, lb1)
+- Maarten Maathuis <[email protected]> (stillunknown)
+- Marcin Koƛcielnicki <[email protected]> (mwk, koriakin)
+- Mark Carey <[email protected]> (careym)
+- Matthieu Castet <[email protected]> (mat-c)
+- nvidiaman <[email protected]> (nvidiaman)
+- Patrice Mandin <[email protected]> (pmandin, pmdata)
+- Pekka Paalanen <[email protected]> (pq, ppaalanen)
+- Peter Popov <[email protected]> (ironpeter)
+- Richard Hughes <[email protected]> (hughsient)
+- Rudi Cilibrasi <[email protected]> (cilibrar)
+- Serge Martin
+- Simon Raffeiner
+- Stephane Loeuillet <[email protected]> (leroutier)
+- Stephane Marchesin <[email protected]> (marcheu)
+- sturmflut <[email protected]> (sturmflut)
+- Sylvain Munaut <[email protected]>
+- Victor Stinner <[email protected]> (haypo)
+- Wladmir van der Laan <[email protected]> (miathan6)
+- Younes Manton <[email protected]> (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 */
diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
index ce9300ad8fd..54b78e850ed 100644
--- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
+++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
@@ -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:
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index bf5af4ddc65..696350d10c8 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -1,351 +1,347 @@
-#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);
}
+
diff --git a/src/gallium/drivers/nv50/nv50_transfer.h b/src/gallium/drivers/nv50/nv50_transfer.h
index 6699bf546ea..d3259ef4a5d 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.h
+++ b/src/gallium/drivers/nv50/nv50_transfer.h
@@ -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
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 53f319acf46..0e0d48d661c 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -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"),
@@ -24,540 +24,691 @@
#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
index 00000000000..8aaf24c0093
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_winsys.h
@@ -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