diff options
author | Christoph Bumiller <[email protected]> | 2011-02-28 12:41:09 +0100 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2011-02-28 12:41:09 +0100 |
commit | f80c03e1875fe96ff2f4c022e3cb76357828140d (patch) | |
tree | 58317ec9b7f6bba05b14e7c28ca2918a4f6a9a47 /src | |
parent | d1dbbf7bf41959df489195d11eb50f8222d293d3 (diff) |
nv50: replace most of it with nvc0 driver ported to nv50
We'll have to do some unification now to reduce code duplication.
Diffstat (limited to 'src')
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 |