From f80c03e1875fe96ff2f4c022e3cb76357828140d Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Mon, 28 Feb 2011 12:41:09 +0100 Subject: [PATCH 01/53] nv50: replace most of it with nvc0 driver ported to nv50 We'll have to do some unification now to reduce code duplication. --- src/gallium/drivers/nv50/Makefile | 9 +- src/gallium/drivers/nv50/SConscript | 8 +- src/gallium/drivers/nv50/nv50_2d.xml.h | 393 ++++ src/gallium/drivers/nv50/nv50_3d.xml.h | 2084 +++++++++++++++++ src/gallium/drivers/nv50/nv50_3ddefs.xml.h | 98 + src/gallium/drivers/nv50/nv50_buffer.c | 533 ++++- src/gallium/drivers/nv50/nv50_clear.c | 74 - src/gallium/drivers/nv50/nv50_context.c | 173 +- src/gallium/drivers/nv50/nv50_context.h | 412 ++-- src/gallium/drivers/nv50/nv50_defs.xml.h | 142 ++ src/gallium/drivers/nv50/nv50_draw.c | 37 +- src/gallium/drivers/nv50/nv50_fence.c | 216 ++ src/gallium/drivers/nv50/nv50_fence.h | 49 + src/gallium/drivers/nv50/nv50_formats.c | 144 +- src/gallium/drivers/nv50/nv50_miptree.c | 430 ++-- src/gallium/drivers/nv50/nv50_mm.c | 277 +++ src/gallium/drivers/nv50/nv50_pc.c | 5 +- src/gallium/drivers/nv50/nv50_pc.h | 2 + src/gallium/drivers/nv50/nv50_pc_optimize.c | 6 +- src/gallium/drivers/nv50/nv50_program.c | 17 +- src/gallium/drivers/nv50/nv50_program.h | 7 +- src/gallium/drivers/nv50/nv50_push.c | 508 ++-- src/gallium/drivers/nv50/nv50_query.c | 352 ++- src/gallium/drivers/nv50/nv50_reg.h | 1827 --------------- src/gallium/drivers/nv50/nv50_resource.c | 79 +- src/gallium/drivers/nv50/nv50_resource.h | 178 +- src/gallium/drivers/nv50/nv50_screen.c | 1112 ++++----- src/gallium/drivers/nv50/nv50_screen.h | 184 +- src/gallium/drivers/nv50/nv50_shader_state.c | 691 ++---- src/gallium/drivers/nv50/nv50_state.c | 1342 +++++------ .../drivers/nv50/nv50_state_validate.c | 613 ++--- src/gallium/drivers/nv50/nv50_stateobj.h | 72 + src/gallium/drivers/nv50/nv50_surface.c | 518 ++-- src/gallium/drivers/nv50/nv50_tex.c | 394 ++-- src/gallium/drivers/nv50/nv50_texture.h | 197 -- src/gallium/drivers/nv50/nv50_texture.xml.h | 259 ++ src/gallium/drivers/nv50/nv50_tgsi_to_nc.c | 18 +- src/gallium/drivers/nv50/nv50_transfer.c | 594 +++-- src/gallium/drivers/nv50/nv50_transfer.h | 39 +- src/gallium/drivers/nv50/nv50_vbo.c | 1079 +++++---- src/gallium/drivers/nv50/nv50_winsys.h | 104 + 41 files changed, 8740 insertions(+), 6536 deletions(-) create mode 100644 src/gallium/drivers/nv50/nv50_2d.xml.h create mode 100644 src/gallium/drivers/nv50/nv50_3d.xml.h create mode 100644 src/gallium/drivers/nv50/nv50_3ddefs.xml.h delete mode 100644 src/gallium/drivers/nv50/nv50_clear.c create mode 100644 src/gallium/drivers/nv50/nv50_defs.xml.h create mode 100644 src/gallium/drivers/nv50/nv50_fence.c create mode 100644 src/gallium/drivers/nv50/nv50_fence.h create mode 100644 src/gallium/drivers/nv50/nv50_mm.c delete mode 100644 src/gallium/drivers/nv50/nv50_reg.h create mode 100644 src/gallium/drivers/nv50/nv50_stateobj.h delete mode 100644 src/gallium/drivers/nv50/nv50_texture.h create mode 100644 src/gallium/drivers/nv50/nv50_texture.xml.h create mode 100644 src/gallium/drivers/nv50/nv50_winsys.h 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 (ahuillet) +- Ben Skeggs (darktama, darktama_) +- B. R. (koala_br) +- Carlos Martin (carlosmn) +- Christoph Bumiller (calim, chrisbmr) +- Dawid Gajownik (gajownik) +- Dmitry Baryshkov +- Dmitry Eremin-Solenikov (lumag) +- EdB (edb_) +- Erik Waling (erikwaling) +- Francisco Jerez (curro) +- imirkin (imirkin) +- jb17bsome (jb17bsome) +- Jeremy Kolb (kjeremy) +- Laurent Carlier (lordheavy) +- Luca Barbieri (lb, lb1) +- Maarten Maathuis (stillunknown) +- Marcin Koƛcielnicki (mwk, koriakin) +- Mark Carey (careym) +- Matthieu Castet (mat-c) +- nvidiaman (nvidiaman) +- Patrice Mandin (pmandin, pmdata) +- Pekka Paalanen (pq, ppaalanen) +- Peter Popov (ironpeter) +- Richard Hughes (hughsient) +- Rudi Cilibrasi (cilibrar) +- Serge Martin +- Simon Raffeiner +- Stephane Loeuillet (leroutier) +- Stephane Marchesin (marcheu) +- sturmflut (sturmflut) +- Sylvain Munaut +- Victor Stinner (haypo) +- Wladmir van der Laan (miathan6) +- Younes Manton (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 (ahuillet) +- Ben Skeggs (darktama, darktama_) +- B. R. (koala_br) +- Carlos Martin (carlosmn) +- Christoph Bumiller (calim, chrisbmr) +- Dawid Gajownik (gajownik) +- Dmitry Baryshkov +- Dmitry Eremin-Solenikov (lumag) +- EdB (edb_) +- Erik Waling (erikwaling) +- Francisco Jerez (curro) +- imirkin (imirkin) +- jb17bsome (jb17bsome) +- Jeremy Kolb (kjeremy) +- Laurent Carlier (lordheavy) +- Luca Barbieri (lb, lb1) +- Maarten Maathuis (stillunknown) +- Marcin Koƛcielnicki (mwk, koriakin) +- Mark Carey (careym) +- Matthieu Castet (mat-c) +- nvidiaman (nvidiaman) +- Patrice Mandin (pmandin, pmdata) +- Pekka Paalanen (pq, ppaalanen) +- Peter Popov (ironpeter) +- Richard Hughes (hughsient) +- Rudi Cilibrasi (cilibrar) +- Serge Martin +- Simon Raffeiner +- Stephane Loeuillet (leroutier) +- Stephane Marchesin (marcheu) +- sturmflut (sturmflut) +- Sylvain Munaut +- Victor Stinner (haypo) +- Wladmir van der Laan (miathan6) +- Younes Manton (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 (ahuillet) +- Ben Skeggs (darktama, darktama_) +- B. R. (koala_br) +- Carlos Martin (carlosmn) +- Christoph Bumiller (calim, chrisbmr) +- Dawid Gajownik (gajownik) +- Dmitry Baryshkov +- Dmitry Eremin-Solenikov (lumag) +- EdB (edb_) +- Erik Waling (erikwaling) +- Francisco Jerez (curro, curro_, currojerez) +- imirkin (imirkin) +- jb17bsome (jb17bsome) +- Jeremy Kolb (kjeremy) +- Laurent Carlier (lordheavy) +- Luca Barbieri (lb, lb1) +- Maarten Maathuis (stillunknown) +- Marcin Koƛcielnicki (mwk, koriakin) +- Mark Carey (careym) +- Matthieu Castet (mat-c) +- nvidiaman (nvidiaman) +- Patrice Mandin (pmandin, pmdata) +- Pekka Paalanen (pq, ppaalanen) +- Peter Popov (ironpeter) +- Richard Hughes (hughsient) +- Rudi Cilibrasi (cilibrar) +- Serge Martin +- Simon Raffeiner +- Stephane Loeuillet (leroutier) +- Stephane Marchesin (marcheu) +- sturmflut (sturmflut) +- Sylvain Munaut +- Victor Stinner (haypo) +- Wladmir van der Laan (miathan6) +- Younes Manton (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 void nv50_buffer_destroy(struct pipe_screen *pscreen, - struct pipe_resource *presource) +static INLINE struct nv50_transfer * +nv50_transfer(struct pipe_transfer *transfer) { - struct nv50_resource *buffer = nv50_resource(presource); - - nouveau_screen_bo_release(pscreen, buffer->bo); - FREE(buffer); + return (struct nv50_transfer *)transfer; } +static INLINE boolean +nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf, + unsigned domain) +{ + 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; +} +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; +} + +static INLINE boolean +nv50_buffer_reallocate(struct nv50_screen *screen, struct nv50_resource *buf, + unsigned domain) +{ + nv50_buffer_release_gpu_storage(buf); + + 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); + + 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_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; + + 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 boolean +nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf, + unsigned start, unsigned size) +{ + 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; +} + +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; + } + + FREE(xfr); +} + +static INLINE boolean +nv50_buffer_sync(struct nv50_resource *buf, unsigned rw) +{ + 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)); +} -/* 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 ) +nv50_buffer_transfer_map(struct pipe_context *pipe, + struct pipe_transfer *transfer) { - struct nv50_resource *buffer = nv50_resource(transfer->resource); - uint8_t *map; + 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; - 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; + 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) +static void +nv50_buffer_transfer_flush_region(struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) { - struct nv50_resource *buffer = nv50_resource(transfer->resource); + struct nv50_resource *res = nv50_resource(transfer->resource); + struct nouveau_bo *bo = res->bo; + unsigned offset = res->offset + transfer->box.x + box->x; - nouveau_screen_bo_map_flush_range(pipe->screen, - buffer->bo, - transfer->box.x + box->x, - box->width); + /* 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 ) +static void +nv50_buffer_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) { - struct nv50_resource *buffer = nv50_resource(transfer->resource); - - nouveau_screen_bo_unmap(pipe->screen, buffer->bo); + /* 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 */ - 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 */ + 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) + void *ptr, + unsigned bytes, + unsigned bind) { - struct nv50_resource *buffer; + struct nv50_resource *buffer; - buffer = CALLOC_STRUCT(nv50_resource); - if (!buffer) - return NULL; + 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; + 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->bo = nouveau_screen_bo_user(pscreen, ptr, bytes); - if (!buffer->bo) - goto fail; - - return &buffer->base; + buffer->data = ptr; + buffer->status = NV50_BUFFER_STATUS_USER_MEMORY; -fail: - FREE(buffer); - return NULL; + return &buffer->base; } +/* 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; + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; - if (flags & PIPE_FLUSH_TEXTURE_CACHE) { - BEGIN_RING(chan, nv50->screen->tesla, 0x1338, 1); - OUT_RING (chan, 0x20); - } + 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 (flags & PIPE_FLUSH_FRAME) - FIRE_RING(chan); + 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 = chan->user_private; + + if (!nv50) + return; + + nv50_screen_fence_update(nv50->screen, TRUE); + + nv50_screen_fence_next(nv50->screen); } static void nv50_destroy(struct pipe_context *pipe) { - struct nv50_context *nv50 = nv50_context(pipe); - int i; + struct nv50_context *nv50 = nv50_context(pipe); - for (i = 0; i < nv50->vtxbuf_nr; i++) { - pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL); - } + draw_destroy(nv50->draw); - for (i = 0; i < 64; i++) { - if (!nv50->state.hw[i]) - continue; - so_ref(NULL, &nv50->state.hw[i]); - } + if (nv50->screen->cur_ctx == nv50) { + nv50->screen->base.channel->user_private = NULL; + nv50->screen->cur_ctx = NULL; + } - draw_destroy(nv50->draw); - - 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 = 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.winsys = pipe_winsys; + nv50->pipe.screen = pscreen; + nv50->pipe.priv = priv; - nv50->pipe.destroy = nv50_destroy; + nv50->pipe.destroy = nv50_destroy; - nv50->pipe.draw_vbo = nv50_draw_vbo; - nv50->pipe.clear = nv50_clear; + nv50->pipe.draw_vbo = nv50_draw_vbo; + nv50->pipe.clear = nv50_clear; - nv50->pipe.flush = nv50_flush; + nv50->pipe.flush = nv50_flush; - screen->base.channel->user_private = nv50; + screen->base.channel->user_private = nv50; + screen->base.channel->flush_notify = nv50_default_flush_notify; - nv50_init_surface_functions(nv50); - nv50_init_state_functions(nv50); - nv50_init_query_functions(nv50); - nv50_init_resource_functions(&nv50->pipe); + nv50_init_query_functions(nv50); + nv50_init_surface_functions(nv50); + nv50_init_state_functions(nv50); + nv50_init_resource_functions(&nv50->pipe); - nv50->draw = draw_create(&nv50->pipe); - assert(nv50->draw); - draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50)); + nv50->draw = draw_create(&nv50->pipe); + assert(nv50->draw); + draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50)); - return &nv50->pipe; + 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; + + for (ctx = 0; ctx < NV50_BUFCTX_COUNT; ++ctx) { + array = &nv50->residents[ctx]; + + 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_resource_validate(rsd->res, rsd->flags); + } + } + + 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" + +#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" #define NOUVEAU_ERR(fmt, args...) \ - fprintf(stderr, "%s:%d - "fmt, __FUNCTION__, __LINE__, ##args); -#define NOUVEAU_MSG(fmt, args...) \ - fprintf(stderr, "nouveau: "fmt, ##args); + fprintf(stderr, "%s:%d - "fmt, __FUNCTION__, __LINE__, ##args); -#define nouveau_bo_tile_layout(nvbo) \ - ((nvbo)->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) +#ifdef NOUVEAU_DEBUG +# define NOUVEAU_DBG(args...) printf(args); +#else +# define NOUVEAU_DBG(args...) +#endif -/* 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_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_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) +#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 -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; -}; - -struct nv50_rasterizer_stateobj { - struct pipe_rasterizer_state pipe; - struct nouveau_stateobj *so; -}; - -struct nv50_sampler_stateobj { - boolean normalized; - unsigned tsc[8]; -}; - -struct nv50_sampler_view { - struct pipe_sampler_view pipe; - uint32_t tic[8]; -}; - -struct nv50_vtxelt_stateobj { - struct pipe_vertex_element pipe[16]; - unsigned num_elements; - uint32_t hw[16]; -}; - -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) -{ - return 1 << (tile_mode >> 4); -} - - -struct nv50_surface { - struct pipe_surface base; - unsigned offset; -}; - -static INLINE struct nv50_surface * -nv50_surface(struct pipe_surface *pt) -{ - return (struct nv50_surface *)pt; -} - -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; -}; +/* 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_context { - struct pipe_context pipe; + struct pipe_context pipe; - struct nv50_screen *screen; + struct nv50_screen *screen; - struct draw_context *draw; + struct util_dynarray residents[NV50_BUFCTX_COUNT]; - struct nv50_state state; + uint32_t dirty; - 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]; + 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; - unsigned vbo_fifo; - unsigned req_lmem; + 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_context * nv50_context(struct pipe_context *pipe) { - return (struct nv50_context *)pipe; + return (struct nv50_context *)pipe; } -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); - -/* 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_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_clear.c */ -extern void nv50_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil); - -/* 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_validate.c */ -extern boolean nv50_state_validate(struct nv50_context *nv50, unsigned dwords); - -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_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 *); +struct nv50_surface { + 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 *ps) +{ + return (struct nv50_surface *)ps; +} /* nv50_context.c */ -struct pipe_context * -nv50_create(struct pipe_screen *pscreen, void *priv); +struct pipe_context *nv50_create(struct pipe_screen *, void *); -static INLINE unsigned -nv50_prim(unsigned mode) +void nv50_default_flush_notify(struct nouveau_channel *); + +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) { - 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; + util_dynarray_resize(&nv50->residents[ctx], 0); } +/* nv50_draw.c */ +extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *); + +/* nv50_program.c */ +boolean nv50_program_translate(struct nv50_program *); +void nv50_program_destroy(struct nv50_context *, struct nv50_program *); + +/* nv50_query.c */ +void nv50_init_query_functions(struct nv50_context *); + +/* 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_state.c */ +extern void nv50_init_state_functions(struct nv50_context *); + +/* nv50_state_validate.c */ +extern boolean nv50_state_validate(struct nv50_context *); + +/* 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 */ +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); + +void nv50_vertex_arrays_validate(struct nv50_context *nv50); + +/* 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 (ahuillet) +- Ben Skeggs (darktama, darktama_) +- B. R. (koala_br) +- Carlos Martin (carlosmn) +- Christoph Bumiller (calim, chrisbmr) +- Dawid Gajownik (gajownik) +- Dmitry Baryshkov +- Dmitry Eremin-Solenikov (lumag) +- EdB (edb_) +- Erik Waling (erikwaling) +- Francisco Jerez (curro, curro_, currojerez) +- imirkin (imirkin) +- jb17bsome (jb17bsome) +- Jeremy Kolb (kjeremy) +- Laurent Carlier (lordheavy) +- Luca Barbieri (lb, lb1) +- Maarten Maathuis (stillunknown) +- Marcin Koƛcielnicki (mwk, koriakin) +- Mark Carey (careym) +- Matthieu Castet (mat-c) +- nvidiaman (nvidiaman) +- Patrice Mandin (pmandin, pmdata) +- Pekka Paalanen (pq, ppaalanen) +- Peter Popov (ironpeter) +- Richard Hughes (hughsient) +- Rudi Cilibrasi (cilibrar) +- Serge Martin +- Simon Raffeiner +- Stephane Loeuillet (leroutier) +- Stephane Marchesin (marcheu) +- sturmflut (sturmflut) +- Sylvain Munaut +- Victor Stinner (haypo) +- Wladmir van der Laan (miathan6) +- Younes Manton (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 +#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 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) \ - 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 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; + 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 (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 (d == 1) - return tile_mode; - else - if (tile_mode > 0x02) - tile_mode = 0x02; + if (nz == 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 */ + 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; + 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; + 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; + if (!mt) + return NULL; - *pt = *tmp; - mt->base.vtbl = &nv50_miptree_vtbl; - pipe_reference_init(&pt->reference, 1); - pt->screen = pscreen; + mt->base.vtbl = &nv50_miptree_vtbl; + *pt = *templ; + 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; - } + mt->layout_3d = pt->target == PIPE_TEXTURE_3D; - /* XXX: texture arrays */ - mt->image_nr = (pt->target == PIPE_TEXTURE_CUBE) ? 6 : 1; + w = pt->width0; + h = pt->height0; + d = mt->layout_3d ? pt->depth0 : 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); + 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; + } - 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); + /* 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); - width = u_minify(width, 1); - height = u_minify(height, 1); - depth = u_minify(depth, 1); - } + 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)); - image_alignment = get_tile_height(mt->level[0].tile_mode) * 64; - image_alignment *= get_tile_depth(mt->level[0].tile_mode); + mt->total_size += lvl->pitch * + align(nby, NV50_TILE_HEIGHT(lvl->tile_mode)) * + align(d, NV50_TILE_DEPTH(lvl->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); + w = u_minify(w, 1); + h = u_minify(h, 1); + d = u_minify(d, 1); + } - 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); + 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; + } - lvl->image_offset[i] = mt->total_size; + alloc_size = 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, alloc_size, + mt->level[0].tile_mode, tile_flags, + &mt->base.bo); + if (ret) { + FREE(mt); + return NULL; + } + mt->base.domain = NOUVEAU_BO_VRAM; - 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; + 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; + 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; + /* 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 = 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.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; - 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; + /* 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; + 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]; - assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer); + ns = CALLOC_STRUCT(nv50_surface); + if (!ns) + return NULL; + ps = &ns->base; - /* 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; + 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 = 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]; + 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; - 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); - } + /* comment says there are going to be removed, but they're used by the st */ + ps->width = ns->width; + ps->height = ns->height; - return &ns->base; + 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(&s->base.texture, NULL); - FREE(s); + pipe_resource_reference(&ps->texture, NULL); + + 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; + unsigned i; + for (i = 0; i < push; ++i) + if (elts[i] == index) + break; + return i; +} - OUT_RING(chan, v[0]); +static INLINE unsigned +prim_restart_search_i16(uint16_t *elts, unsigned push, uint16_t index) +{ + unsigned i; + for (i = 0; i < push; ++i) + if (elts[i] == index) + break; + return i; +} + +static INLINE unsigned +prim_restart_search_i32(uint32_t *elts, unsigned push, uint32_t index) +{ + unsigned i; + for (i = 0; i < push; ++i) + if (elts[i] == index) + break; + return i; } static void -emit_b32_2(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]); -} + while (count) { + unsigned push = MIN2(count, ctx->packet_vertex_limit); + unsigned size, nr; -static void -emit_b32_3(struct nouveau_channel *chan, void *data) -{ - uint32_t *v = data; + nr = push; + if (ctx->primitive_restart) + nr = prim_restart_search_i08(elts, push, ctx->restart_index); - OUT_RING(chan, v[0]); - OUT_RING(chan, v[1]); - OUT_RING(chan, v[2]); -} + size = ctx->vertex_words * nr; -static void -emit_b32_4(struct nouveau_channel *chan, void *data) -{ - uint32_t *v = data; + BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); - OUT_RING(chan, v[0]); - OUT_RING(chan, v[1]); - OUT_RING(chan, v[2]); - OUT_RING(chan, v[3]); -} + ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id, + ctx->chan->cur); -static void -emit_b16_1(struct nouveau_channel *chan, void *data) -{ - uint16_t *v = data; + ctx->chan->cur += size; + count -= nr; + elts += nr; - OUT_RING(chan, v[0]); -} - -static void -emit_b16_3(struct nouveau_channel *chan, void *data) -{ - uint16_t *v = data; - - OUT_RING(chan, (v[1] << 16) | v[0]); - OUT_RING(chan, v[2]); -} - -static void -emit_b08_1(struct nouveau_channel *chan, void *data) -{ - uint8_t *v = data; - - OUT_RING(chan, v[0]); -} - -static void -emit_b08_3(struct nouveau_channel *chan, void *data) -{ - uint8_t *v = data; - - OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]); -} - -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; + 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)); } } - - 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); } static void -emit_edgeflag(void *priv, boolean enabled) +emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count) { - struct push_context *ctx = priv; - struct nouveau_grobj *tesla = ctx->nv50->screen->tesla; - struct nouveau_channel *chan = tesla->channel; + uint16_t *elts = (uint16_t *)ctx->idxbuf + start; - BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1); - OUT_RING (chan, enabled ? 1 : 0); + while (count) { + unsigned push = MIN2(count, ctx->packet_vertex_limit); + unsigned size, nr; + + nr = push; + if (ctx->primitive_restart) + nr = prim_restart_search_i16(elts, push, ctx->restart_index); + + size = ctx->vertex_words * nr; + + BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + + ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id, + ctx->chan->cur); + + ctx->chan->cur += size; + count -= nr; + elts += nr; + + 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(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++]); + while (count) { + unsigned push = MIN2(count, ctx->packet_vertex_limit); + unsigned size, nr; + + nr = push; + if (ctx->primitive_restart) + nr = prim_restart_search_i32(elts, push, ctx->restart_index); + + size = ctx->vertex_words * nr; + + BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + + ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id, + ctx->chan->cur); + + ctx->chan->cur += size; + count -= nr; + elts += nr; + + 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_seq(struct push_context *ctx, unsigned start, unsigned count) { - struct push_context *ctx = priv; - uint8_t *idxbuf = ctx->idxbuf; + while (count) { + unsigned push = MIN2(count, ctx->packet_vertex_limit); + unsigned size = ctx->vertex_words * push; - while (count--) - emit_vertex(ctx, idxbuf[start++] + ctx->idxbias); + BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); + + ctx->translate->run(ctx->translate, start, push, ctx->instance_id, + ctx->chan->cur); + ctx->chan->cur += size; + count -= push; + start += push; + } } -static void -emit_elt16(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) { - struct push_context *ctx = priv; - uint16_t *idxbuf = ctx->idxbuf; - - while (count--) - emit_vertex(ctx, idxbuf[start++]); -} - -static void -emit_elt16_biased(void *priv, unsigned start, unsigned count) -{ - struct push_context *ctx = priv; - uint16_t *idxbuf = ctx->idxbuf; - - while (count--) - emit_vertex(ctx, idxbuf[start++] + ctx->idxbias); -} - -static void -emit_elt32(void *priv, unsigned start, unsigned count) -{ - struct push_context *ctx = priv; - uint32_t *idxbuf = ctx->idxbuf; - - while (count--) - emit_vertex(ctx, idxbuf[start++]); -} - -static void -emit_elt32_biased(void *priv, unsigned start, unsigned count) -{ - struct push_context *ctx = priv; - uint32_t *idxbuf = ctx->idxbuf; - - while (count--) - emit_vertex(ctx, idxbuf[start++] + ctx->idxbias); -} - -static void -emit_verts(void *priv, unsigned start, unsigned count) -{ - 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; + unsigned i, index_size; + unsigned inst = info->instance_count; + boolean apply_bias = info->indexed && info->index_bias; - 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; + 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; - /* 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; + 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); - if (!(nv50->vbo_fifo & (1 << i))) - continue; - n = ctx.attr_nr++; + data = nv50_resource_map_offset(nv50, res, + vb->buffer_offset, NOUVEAU_BO_RD); - if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) { - assert(bo->map); + 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); + 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.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; - } + 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; + BEGIN_RING(ctx.chan, RING_3D(VERTEX_END_GL), 1); + OUT_RING (ctx.chan, 0); - /* map index buffer, if present */ - if (idxbuf) { - struct nouveau_bo *bo = nv50_resource(idxbuf)->bo; - - 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; + if (info->indexed) + nv50_resource_unmap(nv50_resource(nv50->idxbuf.buffer)); - /* 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; - } - - 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 struct pipe_query * -nv50_query_create(struct pipe_context *pipe, unsigned type) +static boolean +nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size) { - struct nouveau_device *dev = nouveau_screen(pipe->screen)->device; - struct nv50_query *q = CALLOC_STRUCT(nv50_query); - int ret; + struct nv50_screen *screen = nv50->screen; + int ret; - assert (type == PIPE_QUERY_OCCLUSION_COUNTER); - q->type = type; + 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_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 256, - 16, &q->bo); - if (ret) { - FREE(q); - return NULL; - } - - return (struct pipe_query *)q; + 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) { - struct nv50_query *q = nv50_query(pq); + nv50_query_allocate(nv50_context(pipe), nv50_query(pq), 0); + FREE(nv50_query(pq)); +} - if (q) { - nouveau_bo_ref(NULL, &q->bo); - FREE(q); - } +static struct pipe_query * +nv50_query_create(struct pipe_context *pipe, unsigned type) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_query *q; + + q = CALLOC_STRUCT(nv50_query); + if (!q) + return NULL; + + if (!nv50_query_allocate(nv50, q, NV50_QUERY_ALLOC_SPACE)) { + FREE(q); + return NULL; + } + + q->is64bit = (type == PIPE_QUERY_PRIMITIVES_GENERATED || + type == PIPE_QUERY_PRIMITIVES_EMITTED || + type == PIPE_QUERY_SO_STATISTICS); + q->type = type; + + 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_get(struct nouveau_channel *chan, struct nv50_query *q, + unsigned offset, uint32_t get) +{ + offset += q->offset; + + 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); - BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_RESET, 1); - OUT_RING (chan, 1); - BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_ENABLE, 1); - OUT_RING (chan, 1); + /* 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); - q->ready = FALSE; + /* 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 */ + + 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); + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + 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); + 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; + } +} - BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_ENABLE, 1); - OUT_RING (chan, 0); +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; + struct nv50_query *q = nv50_query(pq); + uint64_t *res64 = result; + boolean *res8 = result; + uint64_t *data64 = (uint64_t *)q->data; - 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); - } + if (q->type == PIPE_QUERY_GPU_FINISHED) { + res8[0] = nv50_query_ready(q); + return TRUE; + } - *result = q->result; - return q->ready; + 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; + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + 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 (!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) { - /* XXX: big fence, FIFO semaphore might be better */ - BEGIN_RING(chan, tesla, 0x0110, 1); - OUT_RING (chan, 0); - } + 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); + } - 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); + 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:anonymous@nouveau.cvs.sourceforge.net:/cvsroot/nouveau co -P renouveau - -************************************************************************** - - Copyright (C) 2006-2008 : - Dmitry Baryshkov, - Laurent Carlier, - Matthieu Castet, - Dawid Gajownik, - Jeremy Kolb, - Stephane Loeuillet, - Patrice Mandin, - Stephane Marchesin, - Serge Martin, - Sylvain Munaut, - Simon Raffeiner, - Ben Skeggs, - Erik Waling, - koala_br, - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*************************************************************************/ - - -#ifndef NOUVEAU_REG_H -#define NOUVEAU_REG_H 1 - - -#define NV04_MEMORY_TO_MEMORY_FORMAT 0x00000039 - -#define NV04_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100 -#define NV04_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 -#define NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY 0x00000180 -#define NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN 0x00000184 -#define NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_OUT 0x00000188 -#define NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c -#define NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT 0x00000310 -#define NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_IN 0x00000314 -#define NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT 0x00000318 -#define NV04_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN 0x0000031c -#define NV04_MEMORY_TO_MEMORY_FORMAT_LINE_COUNT 0x00000320 -#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT 0x00000324 -#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_INPUT_INC_SHIFT 0 -#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_INPUT_INC_MASK 0x000000ff -#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_OUTPUT_INC_SHIFT 8 -#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_OUTPUT_INC_MASK 0x0000ff00 -#define NV04_MEMORY_TO_MEMORY_FORMAT_BUF_NOTIFY 0x00000328 - - -#define NV50_MEMORY_TO_MEMORY_FORMAT 0x00005039 - -#define NV50_MEMORY_TO_MEMORY_FORMAT_SERIALIZE 0x00000110 -#define NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN 0x00000200 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_MODE_IN 0x00000204 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_PITCH_IN 0x00000208 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_HEIGHT_IN 0x0000020c -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_DEPTH_IN 0x00000210 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_Z 0x00000214 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN 0x00000218 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_X_SHIFT 0 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_X_MASK 0x0000ffff -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_Y_SHIFT 16 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN_Y_MASK 0xffff0000 -#define NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT 0x0000021c -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_MODE_OUT 0x00000220 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_PITCH_OUT 0x00000224 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_HEIGHT_OUT 0x00000228 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_DEPTH_OUT 0x0000022c -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_Z 0x00000230 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT 0x00000234 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_X_SHIFT 0 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_X_MASK 0x0000ffff -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_Y_SHIFT 16 -#define NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT_Y_MASK 0xffff0000 -#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH 0x00000238 -#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH 0x0000023c - - -#define NV50_2D 0x0000502d - -#define NV50_2D_NOP 0x00000100 -#define NV50_2D_NOTIFY 0x00000104 -#define NV50_2D_SERIALIZE 0x00000110 -#define NV50_2D_DMA_NOTIFY 0x00000180 -#define NV50_2D_DMA_DST 0x00000184 -#define NV50_2D_DMA_SRC 0x00000188 -#define NV50_2D_DMA_COND 0x0000018c -#define NV50_2D_DST_FORMAT 0x00000200 -#define NV50_2D_DST_FORMAT_R32G32B32A32_FLOAT 0x000000c0 -#define NV50_2D_DST_FORMAT_R32G32B32A32_SINT 0x000000c1 -#define NV50_2D_DST_FORMAT_R32G32B32A32_UINT 0x000000c2 -#define NV50_2D_DST_FORMAT_R32G32B32X32_FLOAT 0x000000c3 -#define NV50_2D_DST_FORMAT_R16G16B16A16_UNORM 0x000000c6 -#define NV50_2D_DST_FORMAT_R16G16B16A16_SNORM 0x000000c7 -#define NV50_2D_DST_FORMAT_R16G16B16A16_SINT 0x000000c8 -#define NV50_2D_DST_FORMAT_R16G16B16A16_UINT 0x000000c9 -#define NV50_2D_DST_FORMAT_R16G16B16A16_FLOAT 0x000000ca -#define NV50_2D_DST_FORMAT_R32G32_FLOAT 0x000000cb -#define NV50_2D_DST_FORMAT_R32G32_SINT 0x000000cc -#define NV50_2D_DST_FORMAT_R32G32_UINT 0x000000cd -#define NV50_2D_DST_FORMAT_R16G16B16X16_FLOAT 0x000000ce -#define NV50_2D_DST_FORMAT_A8R8G8B8_UNORM 0x000000cf -#define NV50_2D_DST_FORMAT_A8R8G8B8_SRGB 0x000000d0 -#define NV50_2D_DST_FORMAT_A2B10G10R10_UNORM 0x000000d1 -#define NV50_2D_DST_FORMAT_A2B10G10R10_UINT 0x000000d2 -#define NV50_2D_DST_FORMAT_A8B8G8R8_UNORM 0x000000d5 -#define NV50_2D_DST_FORMAT_A8B8G8R8_SRGB 0x000000d6 -#define NV50_2D_DST_FORMAT_A8B8G8R8_SNORM 0x000000d7 -#define NV50_2D_DST_FORMAT_A8B8G8R8_SINT 0x000000d8 -#define NV50_2D_DST_FORMAT_A8B8G8R8_UINT 0x000000d9 -#define NV50_2D_DST_FORMAT_R16G16_UNORM 0x000000da -#define NV50_2D_DST_FORMAT_R16G16_SNORM 0x000000db -#define NV50_2D_DST_FORMAT_R16G16_SINT 0x000000dc -#define NV50_2D_DST_FORMAT_R16G16_UINT 0x000000dd -#define NV50_2D_DST_FORMAT_R16G16_FLOAT 0x000000de -#define NV50_2D_DST_FORMAT_A2R10G10B10_UNORM 0x000000df -#define NV50_2D_DST_FORMAT_B10G11R11_FLOAT 0x000000e0 -#define NV50_2D_DST_FORMAT_R32_FLOAT 0x000000e5 -#define NV50_2D_DST_FORMAT_X8R8G8B8_UNORM 0x000000e6 -#define NV50_2D_DST_FORMAT_X8R8G8B8_SRGB 0x000000e7 -#define NV50_2D_DST_FORMAT_R5G6B5_UNORM 0x000000e8 -#define NV50_2D_DST_FORMAT_A1R5G5B5_UNORM 0x000000e9 -#define NV50_2D_DST_FORMAT_R8G8_UNORM 0x000000ea -#define NV50_2D_DST_FORMAT_R8G8_SNORM 0x000000eb -#define NV50_2D_DST_FORMAT_R8G8_SINT 0x000000ec -#define NV50_2D_DST_FORMAT_R8G8_UINT 0x000000ed -#define NV50_2D_DST_FORMAT_R16_UNORM 0x000000ee -#define NV50_2D_DST_FORMAT_R16_SNORM 0x000000ef -#define NV50_2D_DST_FORMAT_R16_SINT 0x000000f0 -#define NV50_2D_DST_FORMAT_R16_UINT 0x000000f1 -#define NV50_2D_DST_FORMAT_R16_FLOAT 0x000000f2 -#define NV50_2D_DST_FORMAT_R8_UNORM 0x000000f3 -#define NV50_2D_DST_FORMAT_R8_SNORM 0x000000f4 -#define NV50_2D_DST_FORMAT_R8_SINT 0x000000f5 -#define NV50_2D_DST_FORMAT_R8_UINT 0x000000f6 -#define NV50_2D_DST_FORMAT_A8_UNORM 0x000000f7 -#define NV50_2D_DST_FORMAT_X1R5G5B5_UNORM 0x000000f8 -#define NV50_2D_DST_FORMAT_X8B8G8R8_UNORM 0x000000f9 -#define NV50_2D_DST_FORMAT_X8B8G8R8_SRGB 0x000000fa -#define NV50_2D_DST_LINEAR 0x00000204 -#define NV50_2D_DST_TILE_MODE 0x00000208 -#define NV50_2D_DST_DEPTH 0x0000020c -#define NV50_2D_DST_LAYER 0x00000210 -#define NV50_2D_DST_PITCH 0x00000214 -#define NV50_2D_DST_WIDTH 0x00000218 -#define NV50_2D_DST_HEIGHT 0x0000021c -#define NV50_2D_DST_ADDRESS_HIGH 0x00000220 -#define NV50_2D_DST_ADDRESS_LOW 0x00000224 -#define NV50_2D_SRC_FORMAT 0x00000230 -#define NV50_2D_SRC_FORMAT_R32G32B32A32_FLOAT 0x000000c0 -#define NV50_2D_SRC_FORMAT_R32G32B32A32_SINT 0x000000c1 -#define NV50_2D_SRC_FORMAT_R32G32B32A32_UINT 0x000000c2 -#define NV50_2D_SRC_FORMAT_R32G32B32X32_FLOAT 0x000000c3 -#define NV50_2D_SRC_FORMAT_R16G16B16A16_UNORM 0x000000c6 -#define NV50_2D_SRC_FORMAT_R16G16B16A16_SNORM 0x000000c7 -#define NV50_2D_SRC_FORMAT_R16G16B16A16_SINT 0x000000c8 -#define NV50_2D_SRC_FORMAT_R16G16B16A16_UINT 0x000000c9 -#define NV50_2D_SRC_FORMAT_R16G16B16A16_FLOAT 0x000000ca -#define NV50_2D_SRC_FORMAT_R32G32_FLOAT 0x000000cb -#define NV50_2D_SRC_FORMAT_R32G32_SINT 0x000000cc -#define NV50_2D_SRC_FORMAT_R32G32_UINT 0x000000cd -#define NV50_2D_SRC_FORMAT_R16G16B16X16_FLOAT 0x000000ce -#define NV50_2D_SRC_FORMAT_A8R8G8B8_UNORM 0x000000cf -#define NV50_2D_SRC_FORMAT_A8R8G8B8_SRGB 0x000000d0 -#define NV50_2D_SRC_FORMAT_A2B10G10R10_UNORM 0x000000d1 -#define NV50_2D_SRC_FORMAT_A2B10G10R10_UINT 0x000000d2 -#define NV50_2D_SRC_FORMAT_A8B8G8R8_UNORM 0x000000d5 -#define NV50_2D_SRC_FORMAT_A8B8G8R8_SRGB 0x000000d6 -#define NV50_2D_SRC_FORMAT_A8B8G8R8_SNORM 0x000000d7 -#define NV50_2D_SRC_FORMAT_A8B8G8R8_SINT 0x000000d8 -#define NV50_2D_SRC_FORMAT_A8B8G8R8_UINT 0x000000d9 -#define NV50_2D_SRC_FORMAT_R16G16_UNORM 0x000000da -#define NV50_2D_SRC_FORMAT_R16G16_SNORM 0x000000db -#define NV50_2D_SRC_FORMAT_R16G16_SINT 0x000000dc -#define NV50_2D_SRC_FORMAT_R16G16_UINT 0x000000dd -#define NV50_2D_SRC_FORMAT_R16G16_FLOAT 0x000000de -#define NV50_2D_SRC_FORMAT_A2R10G10B10_UNORM 0x000000df -#define NV50_2D_SRC_FORMAT_B10G11R11_FLOAT 0x000000e0 -#define NV50_2D_SRC_FORMAT_R32_FLOAT 0x000000e5 -#define NV50_2D_SRC_FORMAT_X8R8G8B8_UNORM 0x000000e6 -#define NV50_2D_SRC_FORMAT_X8R8G8B8_SRGB 0x000000e7 -#define NV50_2D_SRC_FORMAT_R5G6B5_UNORM 0x000000e8 -#define NV50_2D_SRC_FORMAT_A1R5G5B5_UNORM 0x000000e9 -#define NV50_2D_SRC_FORMAT_R8G8_UNORM 0x000000ea -#define NV50_2D_SRC_FORMAT_R8G8_SNORM 0x000000eb -#define NV50_2D_SRC_FORMAT_R8G8_SINT 0x000000ec -#define NV50_2D_SRC_FORMAT_R8G8_UINT 0x000000ed -#define NV50_2D_SRC_FORMAT_R16_UNORM 0x000000ee -#define NV50_2D_SRC_FORMAT_R16_SNORM 0x000000ef -#define NV50_2D_SRC_FORMAT_R16_SINT 0x000000f0 -#define NV50_2D_SRC_FORMAT_R16_UINT 0x000000f1 -#define NV50_2D_SRC_FORMAT_R16_FLOAT 0x000000f2 -#define NV50_2D_SRC_FORMAT_R8_UNORM 0x000000f3 -#define NV50_2D_SRC_FORMAT_R8_SNORM 0x000000f4 -#define NV50_2D_SRC_FORMAT_R8_SINT 0x000000f5 -#define NV50_2D_SRC_FORMAT_R8_UINT 0x000000f6 -#define NV50_2D_SRC_FORMAT_A8_UNORM 0x000000f7 -#define NV50_2D_SRC_FORMAT_X1R5G5B5_UNORM 0x000000f8 -#define NV50_2D_SRC_FORMAT_X8B8G8R8_UNORM 0x000000f9 -#define NV50_2D_SRC_FORMAT_X8B8G8R8_SRGB 0x000000fa -#define NV50_2D_SRC_LINEAR 0x00000234 -#define NV50_2D_SRC_TILE_MODE 0x00000238 -#define NV50_2D_SRC_DEPTH 0x0000023c -#define NV50_2D_SRC_LAYER 0x00000240 -#define NV50_2D_SRC_PITCH 0x00000244 -#define NV50_2D_SRC_WIDTH 0x00000248 -#define NV50_2D_SRC_HEIGHT 0x0000024c -#define NV50_2D_SRC_ADDRESS_HIGH 0x00000250 -#define NV50_2D_SRC_ADDRESS_LOW 0x00000254 -#define NV50_2D_COND_ADDRESS_HIGH 0x00000264 -#define NV50_2D_COND_ADDRESS_LOW 0x00000268 -#define NV50_2D_COND_MODE 0x0000026c -#define NV50_2D_COND_MODE_NEVER 0x00000000 -#define NV50_2D_COND_MODE_ALWAYS 0x00000001 -#define NV50_2D_COND_MODE_RES 0x00000002 -#define NV50_2D_COND_MODE_NOT_RES_AND_NOT_ID 0x00000003 -#define NV50_2D_COND_MODE_RES_OR_ID 0x00000004 -#define NV50_2D_CLIP_X 0x00000280 -#define NV50_2D_CLIP_Y 0x00000284 -#define NV50_2D_CLIP_W 0x00000288 -#define NV50_2D_CLIP_H 0x0000028c -#define NV50_2D_CLIP_ENABLE 0x00000290 -#define NV50_2D_COLOR_KEY_FORMAT 0x00000294 -#define NV50_2D_COLOR_KEY_FORMAT_16BPP 0x00000000 -#define NV50_2D_COLOR_KEY_FORMAT_15BPP 0x00000001 -#define NV50_2D_COLOR_KEY_FORMAT_24BPP 0x00000002 -#define NV50_2D_COLOR_KEY_FORMAT_30BPP 0x00000003 -#define NV50_2D_COLOR_KEY_FORMAT_8BPP 0x00000004 -#define NV50_2D_COLOR_KEY_FORMAT_16BPP2 0x00000005 -#define NV50_2D_COLOR_KEY_FORMAT_32BPP 0x00000006 -#define NV50_2D_COLOR_KEY 0x00000298 -#define NV50_2D_COLOR_KEY_ENABLE 0x0000029c -#define NV50_2D_ROP 0x000002a0 -#define NV50_2D_OPERATION 0x000002ac -#define NV50_2D_OPERATION_SRCCOPY_AND 0x00000000 -#define NV50_2D_OPERATION_ROP_AND 0x00000001 -#define NV50_2D_OPERATION_BLEND_AND 0x00000002 -#define NV50_2D_OPERATION_SRCCOPY 0x00000003 -#define NV50_2D_OPERATION_SRCCOPY_PREMULT 0x00000004 -#define NV50_2D_OPERATION_BLEND_PREMULT 0x00000005 -#define NV50_2D_PATTERN_FORMAT 0x000002e8 -#define NV50_2D_PATTERN_FORMAT_16BPP 0x00000000 -#define NV50_2D_PATTERN_FORMAT_15BPP 0x00000001 -#define NV50_2D_PATTERN_FORMAT_32BPP 0x00000002 -#define NV50_2D_PATTERN_FORMAT_8BPP 0x00000003 -#define NV50_2D_PATTERN_COLOR(x) (0x000002f0+((x)*4)) -#define NV50_2D_PATTERN_COLOR__SIZE 0x00000002 -#define NV50_2D_PATTERN_BITMAP(x) (0x000002f8+((x)*4)) -#define NV50_2D_PATTERN_BITMAP__SIZE 0x00000002 -#define NV50_2D_DRAW_SHAPE 0x00000580 -#define NV50_2D_DRAW_SHAPE_POINTS 0x00000000 -#define NV50_2D_DRAW_SHAPE_LINES 0x00000001 -#define NV50_2D_DRAW_SHAPE_LINE_STRIP 0x00000002 -#define NV50_2D_DRAW_SHAPE_TRIANGLES 0x00000003 -#define NV50_2D_DRAW_SHAPE_RECTANGLES 0x00000004 -#define NV50_2D_DRAW_COLOR_FORMAT 0x00000584 -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32B32A32_FLOAT 0x000000c0 -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32B32A32_SINT 0x000000c1 -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32B32A32_UINT 0x000000c2 -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32B32X32_FLOAT 0x000000c3 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_UNORM 0x000000c6 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_SNORM 0x000000c7 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_SINT 0x000000c8 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_UINT 0x000000c9 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16A16_FLOAT 0x000000ca -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32_FLOAT 0x000000cb -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32_SINT 0x000000cc -#define NV50_2D_DRAW_COLOR_FORMAT_R32G32_UINT 0x000000cd -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16B16X16_FLOAT 0x000000ce -#define NV50_2D_DRAW_COLOR_FORMAT_A8R8G8B8_UNORM 0x000000cf -#define NV50_2D_DRAW_COLOR_FORMAT_A8R8G8B8_SRGB 0x000000d0 -#define NV50_2D_DRAW_COLOR_FORMAT_A2B10G10R10_UNORM 0x000000d1 -#define NV50_2D_DRAW_COLOR_FORMAT_A2B10G10R10_UINT 0x000000d2 -#define NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_UNORM 0x000000d5 -#define NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_SRGB 0x000000d6 -#define NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_SNORM 0x000000d7 -#define NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_SINT 0x000000d8 -#define NV50_2D_DRAW_COLOR_FORMAT_A8B8G8R8_UINT 0x000000d9 -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16_UNORM 0x000000da -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16_SNORM 0x000000db -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16_SINT 0x000000dc -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16_UINT 0x000000dd -#define NV50_2D_DRAW_COLOR_FORMAT_R16G16_FLOAT 0x000000de -#define NV50_2D_DRAW_COLOR_FORMAT_A2R10G10B10_UNORM 0x000000df -#define NV50_2D_DRAW_COLOR_FORMAT_B10G11R11_FLOAT 0x000000e0 -#define NV50_2D_DRAW_COLOR_FORMAT_R32_FLOAT 0x000000e5 -#define NV50_2D_DRAW_COLOR_FORMAT_X8R8G8B8_UNORM 0x000000e6 -#define NV50_2D_DRAW_COLOR_FORMAT_X8R8G8B8_SRGB 0x000000e7 -#define NV50_2D_DRAW_COLOR_FORMAT_R5G6B5_UNORM 0x000000e8 -#define NV50_2D_DRAW_COLOR_FORMAT_A1R5G5B5_UNORM 0x000000e9 -#define NV50_2D_DRAW_COLOR_FORMAT_R8G8_UNORM 0x000000ea -#define NV50_2D_DRAW_COLOR_FORMAT_R8G8_SNORM 0x000000eb -#define NV50_2D_DRAW_COLOR_FORMAT_R8G8_SINT 0x000000ec -#define NV50_2D_DRAW_COLOR_FORMAT_R8G8_UINT 0x000000ed -#define NV50_2D_DRAW_COLOR_FORMAT_R16_UNORM 0x000000ee -#define NV50_2D_DRAW_COLOR_FORMAT_R16_SNORM 0x000000ef -#define NV50_2D_DRAW_COLOR_FORMAT_R16_SINT 0x000000f0 -#define NV50_2D_DRAW_COLOR_FORMAT_R16_UINT 0x000000f1 -#define NV50_2D_DRAW_COLOR_FORMAT_R16_FLOAT 0x000000f2 -#define NV50_2D_DRAW_COLOR_FORMAT_R8_UNORM 0x000000f3 -#define NV50_2D_DRAW_COLOR_FORMAT_R8_SNORM 0x000000f4 -#define NV50_2D_DRAW_COLOR_FORMAT_R8_SINT 0x000000f5 -#define NV50_2D_DRAW_COLOR_FORMAT_R8_UINT 0x000000f6 -#define NV50_2D_DRAW_COLOR_FORMAT_A8_UNORM 0x000000f7 -#define NV50_2D_DRAW_COLOR_FORMAT_X1R5G5B5_UNORM 0x000000f8 -#define NV50_2D_DRAW_COLOR_FORMAT_X8B8G8R8_UNORM 0x000000f9 -#define NV50_2D_DRAW_COLOR_FORMAT_X8B8G8R8_SRGB 0x000000fa -#define NV50_2D_DRAW_COLOR 0x00000588 -#define NV50_2D_DRAW_POINT16 0x000005e0 -#define NV50_2D_DRAW_POINT16_X_SHIFT 0 -#define NV50_2D_DRAW_POINT16_X_MASK 0x0000ffff -#define NV50_2D_DRAW_POINT16_Y_SHIFT 16 -#define NV50_2D_DRAW_POINT16_Y_MASK 0xffff0000 -#define NV50_2D_DRAW_POINT32_X(x) (0x00000600+((x)*8)) -#define NV50_2D_DRAW_POINT32_X__SIZE 0x00000040 -#define NV50_2D_DRAW_POINT32_Y(x) (0x00000604+((x)*8)) -#define NV50_2D_DRAW_POINT32_Y__SIZE 0x00000040 -#define NV50_2D_SIFC_BITMAP_ENABLE 0x00000800 -#define NV50_2D_SIFC_FORMAT 0x00000804 -#define NV50_2D_SIFC_FORMAT_R32G32B32A32_FLOAT 0x000000c0 -#define NV50_2D_SIFC_FORMAT_R32G32B32A32_SINT 0x000000c1 -#define NV50_2D_SIFC_FORMAT_R32G32B32A32_UINT 0x000000c2 -#define NV50_2D_SIFC_FORMAT_R32G32B32X32_FLOAT 0x000000c3 -#define NV50_2D_SIFC_FORMAT_R16G16B16A16_UNORM 0x000000c6 -#define NV50_2D_SIFC_FORMAT_R16G16B16A16_SNORM 0x000000c7 -#define NV50_2D_SIFC_FORMAT_R16G16B16A16_SINT 0x000000c8 -#define NV50_2D_SIFC_FORMAT_R16G16B16A16_UINT 0x000000c9 -#define NV50_2D_SIFC_FORMAT_R16G16B16A16_FLOAT 0x000000ca -#define NV50_2D_SIFC_FORMAT_R32G32_FLOAT 0x000000cb -#define NV50_2D_SIFC_FORMAT_R32G32_SINT 0x000000cc -#define NV50_2D_SIFC_FORMAT_R32G32_UINT 0x000000cd -#define NV50_2D_SIFC_FORMAT_R16G16B16X16_FLOAT 0x000000ce -#define NV50_2D_SIFC_FORMAT_A8R8G8B8_UNORM 0x000000cf -#define NV50_2D_SIFC_FORMAT_A8R8G8B8_SRGB 0x000000d0 -#define NV50_2D_SIFC_FORMAT_A2B10G10R10_UNORM 0x000000d1 -#define NV50_2D_SIFC_FORMAT_A2B10G10R10_UINT 0x000000d2 -#define NV50_2D_SIFC_FORMAT_A8B8G8R8_UNORM 0x000000d5 -#define NV50_2D_SIFC_FORMAT_A8B8G8R8_SRGB 0x000000d6 -#define NV50_2D_SIFC_FORMAT_A8B8G8R8_SNORM 0x000000d7 -#define NV50_2D_SIFC_FORMAT_A8B8G8R8_SINT 0x000000d8 -#define NV50_2D_SIFC_FORMAT_A8B8G8R8_UINT 0x000000d9 -#define NV50_2D_SIFC_FORMAT_R16G16_UNORM 0x000000da -#define NV50_2D_SIFC_FORMAT_R16G16_SNORM 0x000000db -#define NV50_2D_SIFC_FORMAT_R16G16_SINT 0x000000dc -#define NV50_2D_SIFC_FORMAT_R16G16_UINT 0x000000dd -#define NV50_2D_SIFC_FORMAT_R16G16_FLOAT 0x000000de -#define NV50_2D_SIFC_FORMAT_A2R10G10B10_UNORM 0x000000df -#define NV50_2D_SIFC_FORMAT_B10G11R11_FLOAT 0x000000e0 -#define NV50_2D_SIFC_FORMAT_R32_FLOAT 0x000000e5 -#define NV50_2D_SIFC_FORMAT_X8R8G8B8_UNORM 0x000000e6 -#define NV50_2D_SIFC_FORMAT_X8R8G8B8_SRGB 0x000000e7 -#define NV50_2D_SIFC_FORMAT_R5G6B5_UNORM 0x000000e8 -#define NV50_2D_SIFC_FORMAT_A1R5G5B5_UNORM 0x000000e9 -#define NV50_2D_SIFC_FORMAT_R8G8_UNORM 0x000000ea -#define NV50_2D_SIFC_FORMAT_R8G8_SNORM 0x000000eb -#define NV50_2D_SIFC_FORMAT_R8G8_SINT 0x000000ec -#define NV50_2D_SIFC_FORMAT_R8G8_UINT 0x000000ed -#define NV50_2D_SIFC_FORMAT_R16_UNORM 0x000000ee -#define NV50_2D_SIFC_FORMAT_R16_SNORM 0x000000ef -#define NV50_2D_SIFC_FORMAT_R16_SINT 0x000000f0 -#define NV50_2D_SIFC_FORMAT_R16_UINT 0x000000f1 -#define NV50_2D_SIFC_FORMAT_R16_FLOAT 0x000000f2 -#define NV50_2D_SIFC_FORMAT_R8_UNORM 0x000000f3 -#define NV50_2D_SIFC_FORMAT_R8_SNORM 0x000000f4 -#define NV50_2D_SIFC_FORMAT_R8_SINT 0x000000f5 -#define NV50_2D_SIFC_FORMAT_R8_UINT 0x000000f6 -#define NV50_2D_SIFC_FORMAT_A8_UNORM 0x000000f7 -#define NV50_2D_SIFC_FORMAT_X1R5G5B5_UNORM 0x000000f8 -#define NV50_2D_SIFC_FORMAT_X8B8G8R8_UNORM 0x000000f9 -#define NV50_2D_SIFC_FORMAT_X8B8G8R8_SRGB 0x000000fa -#define NV50_2D_SIFC_BITMAP_UNK808 0x00000808 -#define NV50_2D_SIFC_BITMAP_LSB_FIRST 0x0000080c -#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE 0x00000810 -#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_PACKED 0x00000000 -#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_BYTE 0x00000001 -#define NV50_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_WORD 0x00000002 -#define NV50_2D_SIFC_BITMAP_COLOR_BIT0 0x00000814 -#define NV50_2D_SIFC_BITMAP_COLOR_BIT1 0x00000818 -#define NV50_2D_SIFC_BITMAP_WRITE_BIT0_ENABLE 0x0000081c -#define NV50_2D_SIFC_WIDTH 0x00000838 -#define NV50_2D_SIFC_HEIGHT 0x0000083c -#define NV50_2D_SIFC_DX_DU_FRACT 0x00000840 -#define NV50_2D_SIFC_DX_DU_INT 0x00000844 -#define NV50_2D_SIFC_DY_DV_FRACT 0x00000848 -#define NV50_2D_SIFC_DY_DV_INT 0x0000084c -#define NV50_2D_SIFC_DST_X_FRACT 0x00000850 -#define NV50_2D_SIFC_DST_X_INT 0x00000854 -#define NV50_2D_SIFC_DST_Y_FRACT 0x00000858 -#define NV50_2D_SIFC_DST_Y_INT 0x0000085c -#define NV50_2D_SIFC_DATA 0x00000860 -#define NV50_2D_BLIT_DST_X 0x000008b0 -#define NV50_2D_BLIT_DST_Y 0x000008b4 -#define NV50_2D_BLIT_DST_W 0x000008b8 -#define NV50_2D_BLIT_DST_H 0x000008bc -#define NV50_2D_BLIT_DU_DX_FRACT 0x000008c0 -#define NV50_2D_BLIT_DU_DX_INT 0x000008c4 -#define NV50_2D_BLIT_DV_DY_FRACT 0x000008c8 -#define NV50_2D_BLIT_DV_DY_INT 0x000008cc -#define NV50_2D_BLIT_SRC_X_FRACT 0x000008d0 -#define NV50_2D_BLIT_SRC_X_INT 0x000008d4 -#define NV50_2D_BLIT_SRC_Y_FRACT 0x000008d8 -#define NV50_2D_BLIT_SRC_Y_INT 0x000008dc - - -#define NV50TCL 0x00005097 - -#define NV50TCL_NOP 0x00000100 -#define NV50TCL_NOTIFY 0x00000104 -#define NV50TCL_SERIALIZE 0x00000110 -#define NV50TCL_DMA_NOTIFY 0x00000180 -#define NV50TCL_DMA_ZETA 0x00000184 -#define NV50TCL_DMA_QUERY 0x00000188 -#define NV50TCL_DMA_VTXBUF0 0x0000018c -#define NV50TCL_DMA_LOCAL 0x00000190 -#define NV50TCL_DMA_STACK 0x00000194 -#define NV50TCL_DMA_CODE_CB 0x00000198 -#define NV50TCL_DMA_TSC 0x0000019c -#define NV50TCL_DMA_TIC 0x000001a0 -#define NV50TCL_DMA_TEXTURE 0x000001a4 -#define NV50TCL_DMA_STRMOUT 0x000001a8 -#define NV50TCL_DMA_CLIPID 0x000001ac -#define NV50TCL_DMA_COLOR(x) (0x000001c0+((x)*4)) -#define NV50TCL_DMA_COLOR__SIZE 0x00000008 -#define NV50TCL_RT_ADDRESS_HIGH(x) (0x00000200+((x)*32)) -#define NV50TCL_RT_ADDRESS_HIGH__SIZE 0x00000008 -#define NV50TCL_RT_ADDRESS_LOW(x) (0x00000204+((x)*32)) -#define NV50TCL_RT_ADDRESS_LOW__SIZE 0x00000008 -#define NV50TCL_RT_FORMAT(x) (0x00000208+((x)*32)) -#define NV50TCL_RT_FORMAT__SIZE 0x00000008 -#define NV50TCL_RT_FORMAT_R32G32B32A32_FLOAT 0x000000c0 -#define NV50TCL_RT_FORMAT_R32G32B32A32_SINT 0x000000c1 -#define NV50TCL_RT_FORMAT_R32G32B32A32_UINT 0x000000c2 -#define NV50TCL_RT_FORMAT_R32G32B32X32_FLOAT 0x000000c3 -#define NV50TCL_RT_FORMAT_R16G16B16A16_UNORM 0x000000c6 -#define NV50TCL_RT_FORMAT_R16G16B16A16_SNORM 0x000000c7 -#define NV50TCL_RT_FORMAT_R16G16B16A16_SINT 0x000000c8 -#define NV50TCL_RT_FORMAT_R16G16B16A16_UINT 0x000000c9 -#define NV50TCL_RT_FORMAT_R16G16B16A16_FLOAT 0x000000ca -#define NV50TCL_RT_FORMAT_R32G32_FLOAT 0x000000cb -#define NV50TCL_RT_FORMAT_R32G32_SINT 0x000000cc -#define NV50TCL_RT_FORMAT_R32G32_UINT 0x000000cd -#define NV50TCL_RT_FORMAT_R16G16B16X16_FLOAT 0x000000ce -#define NV50TCL_RT_FORMAT_A8R8G8B8_UNORM 0x000000cf -#define NV50TCL_RT_FORMAT_A8R8G8B8_SRGB 0x000000d0 -#define NV50TCL_RT_FORMAT_A2B10G10R10_UNORM 0x000000d1 -#define NV50TCL_RT_FORMAT_A2B10G10R10_UINT 0x000000d2 -#define NV50TCL_RT_FORMAT_A8B8G8R8_UNORM 0x000000d5 -#define NV50TCL_RT_FORMAT_A8B8G8R8_SRGB 0x000000d6 -#define NV50TCL_RT_FORMAT_A8B8G8R8_SNORM 0x000000d7 -#define NV50TCL_RT_FORMAT_A8B8G8R8_SINT 0x000000d8 -#define NV50TCL_RT_FORMAT_A8B8G8R8_UINT 0x000000d9 -#define NV50TCL_RT_FORMAT_R16G16_UNORM 0x000000da -#define NV50TCL_RT_FORMAT_R16G16_SNORM 0x000000db -#define NV50TCL_RT_FORMAT_R16G16_SINT 0x000000dc -#define NV50TCL_RT_FORMAT_R16G16_UINT 0x000000dd -#define NV50TCL_RT_FORMAT_R16G16_FLOAT 0x000000de -#define NV50TCL_RT_FORMAT_A2R10G10B10_UNORM 0x000000df -#define NV50TCL_RT_FORMAT_B10G11R11_FLOAT 0x000000e0 -#define NV50TCL_RT_FORMAT_R32_FLOAT 0x000000e5 -#define NV50TCL_RT_FORMAT_X8R8G8B8_UNORM 0x000000e6 -#define NV50TCL_RT_FORMAT_X8R8G8B8_SRGB 0x000000e7 -#define NV50TCL_RT_FORMAT_R5G6B5_UNORM 0x000000e8 -#define NV50TCL_RT_FORMAT_A1R5G5B5_UNORM 0x000000e9 -#define NV50TCL_RT_FORMAT_R8G8_UNORM 0x000000ea -#define NV50TCL_RT_FORMAT_R8G8_SNORM 0x000000eb -#define NV50TCL_RT_FORMAT_R8G8_SINT 0x000000ec -#define NV50TCL_RT_FORMAT_R8G8_UINT 0x000000ed -#define NV50TCL_RT_FORMAT_R16_UNORM 0x000000ee -#define NV50TCL_RT_FORMAT_R16_SNORM 0x000000ef -#define NV50TCL_RT_FORMAT_R16_SINT 0x000000f0 -#define NV50TCL_RT_FORMAT_R16_UINT 0x000000f1 -#define NV50TCL_RT_FORMAT_R16_FLOAT 0x000000f2 -#define NV50TCL_RT_FORMAT_R8_UNORM 0x000000f3 -#define NV50TCL_RT_FORMAT_R8_SNORM 0x000000f4 -#define NV50TCL_RT_FORMAT_R8_SINT 0x000000f5 -#define NV50TCL_RT_FORMAT_R8_UINT 0x000000f6 -#define NV50TCL_RT_FORMAT_A8_UNORM 0x000000f7 -#define NV50TCL_RT_FORMAT_X1R5G5B5_UNORM 0x000000f8 -#define NV50TCL_RT_FORMAT_X8B8G8R8_UNORM 0x000000f9 -#define NV50TCL_RT_FORMAT_X8B8G8R8_SRGB 0x000000fa -#define NV50TCL_RT_TILE_MODE(x) (0x0000020c+((x)*32)) -#define NV50TCL_RT_TILE_MODE__SIZE 0x00000008 -#define NV50TCL_RT_LAYER_STRIDE(x) (0x00000210+((x)*32)) -#define NV50TCL_RT_LAYER_STRIDE__SIZE 0x00000008 -#define NV50TCL_VTX_ATTR_1F(x) (0x00000300+((x)*4)) -#define NV50TCL_VTX_ATTR_1F__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_2H(x) (0x00000340+((x)*4)) -#define NV50TCL_VTX_ATTR_2H__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_2H_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_2H_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_2H_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_2H_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_2F_X(x) (0x00000380+((x)*8)) -#define NV50TCL_VTX_ATTR_2F_X__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_2F_Y(x) (0x00000384+((x)*8)) -#define NV50TCL_VTX_ATTR_2F_Y__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_3F_X(x) (0x00000400+((x)*16)) -#define NV50TCL_VTX_ATTR_3F_X__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_3F_Y(x) (0x00000404+((x)*16)) -#define NV50TCL_VTX_ATTR_3F_Y__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_3F_Z(x) (0x00000408+((x)*16)) -#define NV50TCL_VTX_ATTR_3F_Z__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4F_X(x) (0x00000500+((x)*16)) -#define NV50TCL_VTX_ATTR_4F_X__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4F_Y(x) (0x00000504+((x)*16)) -#define NV50TCL_VTX_ATTR_4F_Y__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4F_Z(x) (0x00000508+((x)*16)) -#define NV50TCL_VTX_ATTR_4F_Z__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4F_W(x) (0x0000050c+((x)*16)) -#define NV50TCL_VTX_ATTR_4F_W__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4H_0(x) (0x00000600+((x)*8)) -#define NV50TCL_VTX_ATTR_4H_0__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4H_0_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4H_0_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4H_0_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_4H_0_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4H_1(x) (0x00000604+((x)*8)) -#define NV50TCL_VTX_ATTR_4H_1__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4H_1_Z_SHIFT 0 -#define NV50TCL_VTX_ATTR_4H_1_Z_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4H_1_W_SHIFT 16 -#define NV50TCL_VTX_ATTR_4H_1_W_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_2I(x) (0x00000680+((x)*4)) -#define NV50TCL_VTX_ATTR_2I__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_2I_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_2I_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_2I_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_2I_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_2NI(x) (0x000006c0+((x)*4)) -#define NV50TCL_VTX_ATTR_2NI__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_2NI_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_2NI_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_2NI_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_2NI_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4I_0(x) (0x00000700+((x)*8)) -#define NV50TCL_VTX_ATTR_4I_0__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4I_0_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4I_0_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4I_0_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_4I_0_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4I_1(x) (0x00000704+((x)*8)) -#define NV50TCL_VTX_ATTR_4I_1__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4I_1_Z_SHIFT 0 -#define NV50TCL_VTX_ATTR_4I_1_Z_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4I_1_W_SHIFT 16 -#define NV50TCL_VTX_ATTR_4I_1_W_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4NI_0(x) (0x00000780+((x)*8)) -#define NV50TCL_VTX_ATTR_4NI_0__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4NI_0_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4NI_0_X_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4NI_0_Y_SHIFT 16 -#define NV50TCL_VTX_ATTR_4NI_0_Y_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4NI_1(x) (0x00000784+((x)*8)) -#define NV50TCL_VTX_ATTR_4NI_1__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4NI_1_Z_SHIFT 0 -#define NV50TCL_VTX_ATTR_4NI_1_Z_MASK 0x0000ffff -#define NV50TCL_VTX_ATTR_4NI_1_W_SHIFT 16 -#define NV50TCL_VTX_ATTR_4NI_1_W_MASK 0xffff0000 -#define NV50TCL_VTX_ATTR_4UB(x) (0x00000800+((x)*4)) -#define NV50TCL_VTX_ATTR_4UB__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4UB_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4UB_X_MASK 0x000000ff -#define NV50TCL_VTX_ATTR_4UB_Y_SHIFT 8 -#define NV50TCL_VTX_ATTR_4UB_Y_MASK 0x0000ff00 -#define NV50TCL_VTX_ATTR_4UB_Z_SHIFT 16 -#define NV50TCL_VTX_ATTR_4UB_Z_MASK 0x00ff0000 -#define NV50TCL_VTX_ATTR_4UB_W_SHIFT 24 -#define NV50TCL_VTX_ATTR_4UB_W_MASK 0xff000000 -#define NV50TCL_VTX_ATTR_4B(x) (0x00000840+((x)*4)) -#define NV50TCL_VTX_ATTR_4B__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4B_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4B_X_MASK 0x000000ff -#define NV50TCL_VTX_ATTR_4B_Y_SHIFT 8 -#define NV50TCL_VTX_ATTR_4B_Y_MASK 0x0000ff00 -#define NV50TCL_VTX_ATTR_4B_Z_SHIFT 16 -#define NV50TCL_VTX_ATTR_4B_Z_MASK 0x00ff0000 -#define NV50TCL_VTX_ATTR_4B_W_SHIFT 24 -#define NV50TCL_VTX_ATTR_4B_W_MASK 0xff000000 -#define NV50TCL_VTX_ATTR_4NUB(x) (0x00000880+((x)*4)) -#define NV50TCL_VTX_ATTR_4NUB__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4NUB_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4NUB_X_MASK 0x000000ff -#define NV50TCL_VTX_ATTR_4NUB_Y_SHIFT 8 -#define NV50TCL_VTX_ATTR_4NUB_Y_MASK 0x0000ff00 -#define NV50TCL_VTX_ATTR_4NUB_Z_SHIFT 16 -#define NV50TCL_VTX_ATTR_4NUB_Z_MASK 0x00ff0000 -#define NV50TCL_VTX_ATTR_4NUB_W_SHIFT 24 -#define NV50TCL_VTX_ATTR_4NUB_W_MASK 0xff000000 -#define NV50TCL_VTX_ATTR_4NB(x) (0x000008c0+((x)*4)) -#define NV50TCL_VTX_ATTR_4NB__SIZE 0x00000010 -#define NV50TCL_VTX_ATTR_4NB_X_SHIFT 0 -#define NV50TCL_VTX_ATTR_4NB_X_MASK 0x000000ff -#define NV50TCL_VTX_ATTR_4NB_Y_SHIFT 8 -#define NV50TCL_VTX_ATTR_4NB_Y_MASK 0x0000ff00 -#define NV50TCL_VTX_ATTR_4NB_Z_SHIFT 16 -#define NV50TCL_VTX_ATTR_4NB_Z_MASK 0x00ff0000 -#define NV50TCL_VTX_ATTR_4NB_W_SHIFT 24 -#define NV50TCL_VTX_ATTR_4NB_W_MASK 0xff000000 -#define NV50TCL_VERTEX_ARRAY_FORMAT(x) (0x00000900+((x)*16)) -#define NV50TCL_VERTEX_ARRAY_FORMAT__SIZE 0x00000010 -#define NV50TCL_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT 0 -#define NV50TCL_VERTEX_ARRAY_FORMAT_STRIDE_MASK 0x00000fff -#define NV50TCL_VERTEX_ARRAY_FORMAT_ENABLE (1 << 29) -#define NV50TCL_VERTEX_ARRAY_START_HIGH(x) (0x00000904+((x)*16)) -#define NV50TCL_VERTEX_ARRAY_START_HIGH__SIZE 0x00000010 -#define NV50TCL_VERTEX_ARRAY_START_LOW(x) (0x00000908+((x)*16)) -#define NV50TCL_VERTEX_ARRAY_START_LOW__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_SCALE_X(x) (0x00000a00+((x)*32)) -#define NV50TCL_VIEWPORT_SCALE_X__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_SCALE_Y(x) (0x00000a04+((x)*32)) -#define NV50TCL_VIEWPORT_SCALE_Y__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_SCALE_Z(x) (0x00000a08+((x)*32)) -#define NV50TCL_VIEWPORT_SCALE_Z__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_TRANSLATE_X(x) (0x00000a0c+((x)*32)) -#define NV50TCL_VIEWPORT_TRANSLATE_X__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_TRANSLATE_Y(x) (0x00000a10+((x)*32)) -#define NV50TCL_VIEWPORT_TRANSLATE_Y__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_TRANSLATE_Z(x) (0x00000a14+((x)*32)) -#define NV50TCL_VIEWPORT_TRANSLATE_Z__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_HORIZ(x) (0x00000c00+((x)*16)) -#define NV50TCL_VIEWPORT_HORIZ__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_HORIZ_X_SHIFT 0 -#define NV50TCL_VIEWPORT_HORIZ_X_MASK 0x0000ffff -#define NV50TCL_VIEWPORT_HORIZ_W_SHIFT 16 -#define NV50TCL_VIEWPORT_HORIZ_W_MASK 0xffff0000 -#define NV50TCL_VIEWPORT_VERT(x) (0x00000c04+((x)*16)) -#define NV50TCL_VIEWPORT_VERT__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_VERT_Y_SHIFT 0 -#define NV50TCL_VIEWPORT_VERT_Y_MASK 0x0000ffff -#define NV50TCL_VIEWPORT_VERT_H_SHIFT 16 -#define NV50TCL_VIEWPORT_VERT_H_MASK 0xffff0000 -#define NV50TCL_DEPTH_RANGE_NEAR(x) (0x00000c08+((x)*16)) -#define NV50TCL_DEPTH_RANGE_NEAR__SIZE 0x00000010 -#define NV50TCL_DEPTH_RANGE_FAR(x) (0x00000c0c+((x)*16)) -#define NV50TCL_DEPTH_RANGE_FAR__SIZE 0x00000010 -#define NV50TCL_VIEWPORT_CLIP_HORIZ(x) (0x00000d00+((x)*8)) -#define NV50TCL_VIEWPORT_CLIP_HORIZ__SIZE 0x00000008 -#define NV50TCL_VIEWPORT_CLIP_HORIZ_MIN_SHIFT 0 -#define NV50TCL_VIEWPORT_CLIP_HORIZ_MIN_MASK 0x0000ffff -#define NV50TCL_VIEWPORT_CLIP_HORIZ_MAX_SHIFT 16 -#define NV50TCL_VIEWPORT_CLIP_HORIZ_MAX_MASK 0xffff0000 -#define NV50TCL_VIEWPORT_CLIP_VERT(x) (0x00000d04+((x)*8)) -#define NV50TCL_VIEWPORT_CLIP_VERT__SIZE 0x00000008 -#define NV50TCL_VIEWPORT_CLIP_VERT_MIN_SHIFT 0 -#define NV50TCL_VIEWPORT_CLIP_VERT_MIN_MASK 0x0000ffff -#define NV50TCL_VIEWPORT_CLIP_VERT_MAX_SHIFT 16 -#define NV50TCL_VIEWPORT_CLIP_VERT_MAX_MASK 0xffff0000 -#define NV50TCL_CLIPID_REGION_HORIZ(x) (0x00000d40+((x)*8)) -#define NV50TCL_CLIPID_REGION_HORIZ__SIZE 0x00000004 -#define NV50TCL_CLIPID_REGION_VERT(x) (0x00000d44+((x)*8)) -#define NV50TCL_CLIPID_REGION_VERT__SIZE 0x00000004 -#define NV50TCL_VERTEX_BUFFER_FIRST 0x00000d74 -#define NV50TCL_VERTEX_BUFFER_COUNT 0x00000d78 -#define NV50TCL_CLEAR_COLOR(x) (0x00000d80+((x)*4)) -#define NV50TCL_CLEAR_COLOR__SIZE 0x00000004 -#define NV50TCL_CLEAR_DEPTH 0x00000d90 -#define NV50TCL_STACK_ADDRESS_HIGH 0x00000d94 -#define NV50TCL_STACK_ADDRESS_LOW 0x00000d98 -#define NV50TCL_STACK_SIZE_LOG 0x00000d9c -#define NV50TCL_CLEAR_STENCIL 0x00000da0 -#define NV50TCL_STRMOUT_PRIMITIVE_COUNT 0x00000da8 -#define NV50TCL_POLYGON_MODE_FRONT 0x00000dac -#define NV50TCL_POLYGON_MODE_FRONT_POINT 0x00001b00 -#define NV50TCL_POLYGON_MODE_FRONT_LINE 0x00001b01 -#define NV50TCL_POLYGON_MODE_FRONT_FILL 0x00001b02 -#define NV50TCL_POLYGON_MODE_BACK 0x00000db0 -#define NV50TCL_POLYGON_MODE_BACK_POINT 0x00001b00 -#define NV50TCL_POLYGON_MODE_BACK_LINE 0x00001b01 -#define NV50TCL_POLYGON_MODE_BACK_FILL 0x00001b02 -#define NV50TCL_POLYGON_SMOOTH_ENABLE 0x00000db4 -#define NV50TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000dc0 -#define NV50TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000dc4 -#define NV50TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000dc8 -#define NV50TCL_WATCHDOG_TIMER 0x00000de4 -#define NV50TCL_WINDOW_OFFSET_X 0x00000df8 -#define NV50TCL_WINDOW_OFFSET_Y 0x00000dfc -#define NV50TCL_SCISSOR_ENABLE(x) (0x00000e00+((x)*16)) -#define NV50TCL_SCISSOR_ENABLE__SIZE 0x00000010 -#define NV50TCL_SCISSOR_HORIZ(x) (0x00000e04+((x)*16)) -#define NV50TCL_SCISSOR_HORIZ__SIZE 0x00000010 -#define NV50TCL_SCISSOR_HORIZ_MIN_SHIFT 0 -#define NV50TCL_SCISSOR_HORIZ_MIN_MASK 0x0000ffff -#define NV50TCL_SCISSOR_HORIZ_MAX_SHIFT 16 -#define NV50TCL_SCISSOR_HORIZ_MAX_MASK 0xffff0000 -#define NV50TCL_SCISSOR_VERT(x) (0x00000e08+((x)*16)) -#define NV50TCL_SCISSOR_VERT__SIZE 0x00000010 -#define NV50TCL_SCISSOR_VERT_MIN_SHIFT 0 -#define NV50TCL_SCISSOR_VERT_MIN_MASK 0x0000ffff -#define NV50TCL_SCISSOR_VERT_MAX_SHIFT 16 -#define NV50TCL_SCISSOR_VERT_MAX_MASK 0xffff0000 -#define NV50TCL_CB_ADDR 0x00000f00 -#define NV50TCL_CB_ADDR_ID_SHIFT 8 -#define NV50TCL_CB_ADDR_ID_MASK 0x003fff00 -#define NV50TCL_CB_ADDR_BUFFER_SHIFT 0 -#define NV50TCL_CB_ADDR_BUFFER_MASK 0x0000007f -#define NV50TCL_CB_DATA(x) (0x00000f04+((x)*4)) -#define NV50TCL_CB_DATA__SIZE 0x00000010 -#define NV50TCL_LOCAL_WARPS_LOG_ALLOC 0x00000f44 -#define NV50TCL_LOCAL_WARPS_NO_CLAMP 0x00000f48 -#define NV50TCL_STACK_WARPS_LOG_ALLOC 0x00000f4c -#define NV50TCL_STACK_WARPS_NO_CLAMP 0x00000f50 -#define NV50TCL_STENCIL_BACK_FUNC_REF 0x00000f54 -#define NV50TCL_STENCIL_BACK_MASK 0x00000f58 -#define NV50TCL_STENCIL_BACK_FUNC_MASK 0x00000f5c -#define NV50TCL_GP_ADDRESS_HIGH 0x00000f70 -#define NV50TCL_GP_ADDRESS_LOW 0x00000f74 -#define NV50TCL_VP_ADDRESS_HIGH 0x00000f7c -#define NV50TCL_VP_ADDRESS_LOW 0x00000f80 -#define NV50TCL_VERTEX_RUNOUT_HIGH 0x00000f84 -#define NV50TCL_VERTEX_RUNOUT_LOW 0x00000f88 -#define NV50TCL_DEPTH_BOUNDS(x) (0x00000f9c+((x)*4)) -#define NV50TCL_DEPTH_BOUNDS__SIZE 0x00000002 -#define NV50TCL_FP_ADDRESS_HIGH 0x00000fa4 -#define NV50TCL_FP_ADDRESS_LOW 0x00000fa8 -#define NV50TCL_MSAA_MASK(x) (0x00000fbc+((x)*4)) -#define NV50TCL_MSAA_MASK__SIZE 0x00000004 -#define NV50TCL_CLIPID_ADDRESS_HIGH 0x00000fcc -#define NV50TCL_CLIPID_ADDRESS_LOW 0x00000fd0 -#define NV50TCL_ZETA_ADDRESS_HIGH 0x00000fe0 -#define NV50TCL_ZETA_ADDRESS_LOW 0x00000fe4 -#define NV50TCL_ZETA_FORMAT 0x00000fe8 -#define NV50TCL_ZETA_FORMAT_Z32_FLOAT 0x0000000a -#define NV50TCL_ZETA_FORMAT_Z16_UNORM 0x00000013 -#define NV50TCL_ZETA_FORMAT_Z24S8_UNORM 0x00000014 -#define NV50TCL_ZETA_FORMAT_X8Z24_UNORM 0x00000015 -#define NV50TCL_ZETA_FORMAT_S8Z24_UNORM 0x00000016 -#define NV50TCL_ZETA_FORMAT_Z32_FLOAT_X24S8_UNORM 0x00000019 -#define NV50TCL_ZETA_TILE_MODE 0x00000fec -#define NV50TCL_ZETA_LAYER_STRIDE 0x00000ff0 -#define NV50TCL_SCREEN_SCISSOR_HORIZ 0x00000ff4 -#define NV50TCL_SCREEN_SCISSOR_HORIZ_W_SHIFT 16 -#define NV50TCL_SCREEN_SCISSOR_HORIZ_W_MASK 0xffff0000 -#define NV50TCL_SCREEN_SCISSOR_HORIZ_X_SHIFT 0 -#define NV50TCL_SCREEN_SCISSOR_HORIZ_X_MASK 0x0000ffff -#define NV50TCL_SCREEN_SCISSOR_VERT 0x00000ff8 -#define NV50TCL_SCREEN_SCISSOR_VERT_H_SHIFT 16 -#define NV50TCL_SCREEN_SCISSOR_VERT_H_MASK 0xffff0000 -#define NV50TCL_SCREEN_SCISSOR_VERT_Y_SHIFT 0 -#define NV50TCL_SCREEN_SCISSOR_VERT_Y_MASK 0x0000ffff -#define NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(x) (0x00001080+((x)*8)) -#define NV50TCL_VERTEX_ARRAY_LIMIT_HIGH__SIZE 0x00000010 -#define NV50TCL_VERTEX_ARRAY_LIMIT_LOW(x) (0x00001084+((x)*8)) -#define NV50TCL_VERTEX_ARRAY_LIMIT_LOW__SIZE 0x00000010 -#define NV50TCL_RT_CONTROL 0x0000121c -#define NV50TCL_RT_CONTROL_COUNT_SHIFT 0 -#define NV50TCL_RT_CONTROL_COUNT_MASK 0x0000000f -#define NV50TCL_RT_CONTROL_MAP0_SHIFT 4 -#define NV50TCL_RT_CONTROL_MAP0_MASK 0x00000070 -#define NV50TCL_RT_CONTROL_MAP1_SHIFT 7 -#define NV50TCL_RT_CONTROL_MAP1_MASK 0x00000380 -#define NV50TCL_RT_CONTROL_MAP2_SHIFT 10 -#define NV50TCL_RT_CONTROL_MAP2_MASK 0x00001c00 -#define NV50TCL_RT_CONTROL_MAP3_SHIFT 13 -#define NV50TCL_RT_CONTROL_MAP3_MASK 0x0000e000 -#define NV50TCL_RT_CONTROL_MAP4_SHIFT 16 -#define NV50TCL_RT_CONTROL_MAP4_MASK 0x00070000 -#define NV50TCL_RT_CONTROL_MAP5_SHIFT 19 -#define NV50TCL_RT_CONTROL_MAP5_MASK 0x00380000 -#define NV50TCL_RT_CONTROL_MAP6_SHIFT 22 -#define NV50TCL_RT_CONTROL_MAP6_MASK 0x01c00000 -#define NV50TCL_RT_CONTROL_MAP7_SHIFT 25 -#define NV50TCL_RT_CONTROL_MAP7_MASK 0x0e000000 -#define NV50TCL_RT_ARRAY_MODE 0x00001224 -#define NV50TCL_RT_ARRAY_MODE_LAYERS_SHIFT 0 -#define NV50TCL_RT_ARRAY_MODE_LAYERS_MASK 0x0000ffff -#define NV50TCL_RT_ARRAY_MODE_VOLUME (1 << 16) -#define NV50TCL_ZETA_HORIZ 0x00001228 -#define NV50TCL_ZETA_VERT 0x0000122c -#define NV50TCL_ZETA_ARRAY_MODE 0x00001230 -#define NV50TCL_ZETA_ARRAY_MODE_LAYERS_SHIFT 0 -#define NV50TCL_ZETA_ARRAY_MODE_LAYERS_MASK 0x0000ffff -#define NV50TCL_ZETA_ARRAY_MODE_UNK (1 << 16) -#define NV50TCL_LINKED_TSC 0x00001234 -#define NV50TCL_RT_HORIZ(x) (0x00001240+((x)*8)) -#define NV50TCL_RT_HORIZ__SIZE 0x00000008 -#define NV50TCL_RT_VERT(x) (0x00001244+((x)*8)) -#define NV50TCL_RT_VERT__SIZE 0x00000008 -#define NV50TCL_CB_DEF_ADDRESS_HIGH 0x00001280 -#define NV50TCL_CB_DEF_ADDRESS_LOW 0x00001284 -#define NV50TCL_CB_DEF_SET 0x00001288 -#define NV50TCL_CB_DEF_SET_SIZE_SHIFT 0 -#define NV50TCL_CB_DEF_SET_SIZE_MASK 0x0000ffff -#define NV50TCL_CB_DEF_SET_BUFFER_SHIFT 16 -#define NV50TCL_CB_DEF_SET_BUFFER_MASK 0x007f0000 -#define NV50TCL_STRMOUT_BUFFERS_CTRL 0x00001294 -#define NV50TCL_STRMOUT_BUFFERS_CTRL_INTERLEAVED (1 << 0) -#define NV50TCL_STRMOUT_BUFFERS_CTRL_SEPARATE_SHIFT 4 -#define NV50TCL_STRMOUT_BUFFERS_CTRL_SEPARATE_MASK 0x000000f0 -#define NV50TCL_STRMOUT_BUFFERS_CTRL_STRIDE_SHIFT 8 -#define NV50TCL_STRMOUT_BUFFERS_CTRL_STRIDE_MASK 0x0000ff00 -#define NV50TCL_FP_RESULT_COUNT 0x00001298 -#define NV50TCL_DEPTH_TEST_ENABLE 0x000012cc -#define NV50TCL_SHADE_MODEL 0x000012d4 -#define NV50TCL_SHADE_MODEL_FLAT 0x00001d00 -#define NV50TCL_SHADE_MODEL_SMOOTH 0x00001d01 -#define NV50TCL_LOCAL_ADDRESS_HIGH 0x000012d8 -#define NV50TCL_LOCAL_ADDRESS_LOW 0x000012dc -#define NV50TCL_LOCAL_SIZE_LOG 0x000012e0 -#define NV50TCL_DEPTH_WRITE_ENABLE 0x000012e8 -#define NV50TCL_ALPHA_TEST_ENABLE 0x000012ec -#define NV50TCL_PM_SET(x) (0x000012f0+((x)*4)) -#define NV50TCL_PM_SET__SIZE 0x00000004 -#define NV50TCL_VB_ELEMENT_U8_SETUP 0x00001300 -#define NV50TCL_VB_ELEMENT_U8_SETUP_OFFSET_SHIFT 30 -#define NV50TCL_VB_ELEMENT_U8_SETUP_OFFSET_MASK 0xc0000000 -#define NV50TCL_VB_ELEMENT_U8_SETUP_COUNT_SHIFT 0 -#define NV50TCL_VB_ELEMENT_U8_SETUP_COUNT_MASK 0x3fffffff -#define NV50TCL_VB_ELEMENT_U8 0x00001304 -#define NV50TCL_VB_ELEMENT_U8_I0_SHIFT 0 -#define NV50TCL_VB_ELEMENT_U8_I0_MASK 0x000000ff -#define NV50TCL_VB_ELEMENT_U8_I1_SHIFT 8 -#define NV50TCL_VB_ELEMENT_U8_I1_MASK 0x0000ff00 -#define NV50TCL_VB_ELEMENT_U8_I2_SHIFT 16 -#define NV50TCL_VB_ELEMENT_U8_I2_MASK 0x00ff0000 -#define NV50TCL_VB_ELEMENT_U8_I3_SHIFT 24 -#define NV50TCL_VB_ELEMENT_U8_I3_MASK 0xff000000 -#define NV50TCL_DEPTH_TEST_FUNC 0x0000130c -#define NV50TCL_DEPTH_TEST_FUNC_NEVER 0x00000200 -#define NV50TCL_DEPTH_TEST_FUNC_LESS 0x00000201 -#define NV50TCL_DEPTH_TEST_FUNC_EQUAL 0x00000202 -#define NV50TCL_DEPTH_TEST_FUNC_LEQUAL 0x00000203 -#define NV50TCL_DEPTH_TEST_FUNC_GREATER 0x00000204 -#define NV50TCL_DEPTH_TEST_FUNC_NOTEQUAL 0x00000205 -#define NV50TCL_DEPTH_TEST_FUNC_GEQUAL 0x00000206 -#define NV50TCL_DEPTH_TEST_FUNC_ALWAYS 0x00000207 -#define NV50TCL_ALPHA_TEST_REF 0x00001310 -#define NV50TCL_ALPHA_TEST_FUNC 0x00001314 -#define NV50TCL_ALPHA_TEST_FUNC_NEVER 0x00000200 -#define NV50TCL_ALPHA_TEST_FUNC_LESS 0x00000201 -#define NV50TCL_ALPHA_TEST_FUNC_EQUAL 0x00000202 -#define NV50TCL_ALPHA_TEST_FUNC_LEQUAL 0x00000203 -#define NV50TCL_ALPHA_TEST_FUNC_GREATER 0x00000204 -#define NV50TCL_ALPHA_TEST_FUNC_NOTEQUAL 0x00000205 -#define NV50TCL_ALPHA_TEST_FUNC_GEQUAL 0x00000206 -#define NV50TCL_ALPHA_TEST_FUNC_ALWAYS 0x00000207 -#define NV50TCL_BLEND_COLOR(x) (0x0000131c+((x)*4)) -#define NV50TCL_BLEND_COLOR__SIZE 0x00000004 -#define NV50TCL_TIC_FLUSH 0x00001330 -#define NV50TCL_TSC_FLUSH 0x00001334 -#define NV50TCL_TEX_CACHE_CTL 0x00001338 -#define NV50TCL_BLEND_EQUATION_RGB 0x00001340 -#define NV50TCL_BLEND_EQUATION_RGB_FUNC_ADD 0x00008006 -#define NV50TCL_BLEND_EQUATION_RGB_MIN 0x00008007 -#define NV50TCL_BLEND_EQUATION_RGB_MAX 0x00008008 -#define NV50TCL_BLEND_EQUATION_RGB_FUNC_SUBTRACT 0x0000800a -#define NV50TCL_BLEND_EQUATION_RGB_FUNC_REVERSE_SUBTRACT 0x0000800b -#define NV50TCL_BLEND_FUNC_SRC_RGB 0x00001344 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ZERO 0x00004000 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE 0x00004001 -#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC_COLOR 0x00004300 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_COLOR 0x00004301 -#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA 0x00004302 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_ALPHA 0x00004303 -#define NV50TCL_BLEND_FUNC_SRC_RGB_DST_ALPHA 0x00004304 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_ALPHA 0x00004305 -#define NV50TCL_BLEND_FUNC_SRC_RGB_DST_COLOR 0x00004306 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_COLOR 0x00004307 -#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA_SATURATE 0x00004308 -#define NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_COLOR 0x0000c001 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_COLOR 0x0000c002 -#define NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_ALPHA 0x0000c003 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_ALPHA 0x0000c004 -#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC1_COLOR 0x0000c900 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC1_COLOR 0x0000c901 -#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC1_ALPHA 0x0000c902 -#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC1_ALPHA 0x0000c903 -#define NV50TCL_BLEND_FUNC_DST_RGB 0x00001348 -#define NV50TCL_BLEND_FUNC_DST_RGB_ZERO 0x00004000 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE 0x00004001 -#define NV50TCL_BLEND_FUNC_DST_RGB_SRC_COLOR 0x00004300 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_COLOR 0x00004301 -#define NV50TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA 0x00004302 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA 0x00004303 -#define NV50TCL_BLEND_FUNC_DST_RGB_DST_ALPHA 0x00004304 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_ALPHA 0x00004305 -#define NV50TCL_BLEND_FUNC_DST_RGB_DST_COLOR 0x00004306 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_COLOR 0x00004307 -#define NV50TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA_SATURATE 0x00004308 -#define NV50TCL_BLEND_FUNC_DST_RGB_CONSTANT_COLOR 0x0000c001 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_COLOR 0x0000c002 -#define NV50TCL_BLEND_FUNC_DST_RGB_CONSTANT_ALPHA 0x0000c003 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_ALPHA 0x0000c004 -#define NV50TCL_BLEND_FUNC_DST_RGB_SRC1_COLOR 0x0000c900 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC1_COLOR 0x0000c901 -#define NV50TCL_BLEND_FUNC_DST_RGB_SRC1_ALPHA 0x0000c902 -#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC1_ALPHA 0x0000c903 -#define NV50TCL_BLEND_EQUATION_ALPHA 0x0000134c -#define NV50TCL_BLEND_EQUATION_ALPHA_FUNC_ADD 0x00008006 -#define NV50TCL_BLEND_EQUATION_ALPHA_MIN 0x00008007 -#define NV50TCL_BLEND_EQUATION_ALPHA_MAX 0x00008008 -#define NV50TCL_BLEND_EQUATION_ALPHA_FUNC_SUBTRACT 0x0000800a -#define NV50TCL_BLEND_EQUATION_ALPHA_FUNC_REVERSE_SUBTRACT 0x0000800b -#define NV50TCL_BLEND_FUNC_SRC_ALPHA 0x00001350 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ZERO 0x00004000 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE 0x00004001 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_COLOR 0x00004300 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_COLOR 0x00004301 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA 0x00004302 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_ALPHA 0x00004303 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_DST_ALPHA 0x00004304 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_ALPHA 0x00004305 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_DST_COLOR 0x00004306 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_COLOR 0x00004307 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA_SATURATE 0x00004308 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_COLOR 0x0000c001 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_COLOR 0x0000c002 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_ALPHA 0x0000c003 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_ALPHA 0x0000c004 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC1_COLOR 0x0000c900 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC1_COLOR 0x0000c901 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC1_ALPHA 0x0000c902 -#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC1_ALPHA 0x0000c903 -#define NV50TCL_BLEND_FUNC_DST_ALPHA 0x00001358 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ZERO 0x00004000 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE 0x00004001 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_COLOR 0x00004300 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_COLOR 0x00004301 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA 0x00004302 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_ALPHA 0x00004303 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_DST_ALPHA 0x00004304 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_ALPHA 0x00004305 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_DST_COLOR 0x00004306 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_COLOR 0x00004307 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA_SATURATE 0x00004308 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_COLOR 0x0000c001 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_COLOR 0x0000c002 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_ALPHA 0x0000c003 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_ALPHA 0x0000c004 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC1_COLOR 0x0000c900 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC1_COLOR 0x0000c901 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC1_ALPHA 0x0000c902 -#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC1_ALPHA 0x0000c903 -#define NV50TCL_BLEND_ENABLE(x) (0x00001360+((x)*4)) -#define NV50TCL_BLEND_ENABLE__SIZE 0x00000008 -#define NV50TCL_STENCIL_FRONT_ENABLE 0x00001380 -#define NV50TCL_STENCIL_FRONT_OP_FAIL 0x00001384 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_ZERO 0x00000000 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_INVERT 0x0000150a -#define NV50TCL_STENCIL_FRONT_OP_FAIL_KEEP 0x00001e00 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_INCR 0x00001e02 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_DECR 0x00001e03 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_FRONT_OP_FAIL_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL 0x00001388 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_ZERO 0x00000000 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_INVERT 0x0000150a -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_KEEP 0x00001e00 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_INCR 0x00001e02 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_DECR 0x00001e03 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_FRONT_OP_ZFAIL_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS 0x0000138c -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_ZERO 0x00000000 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_INVERT 0x0000150a -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_KEEP 0x00001e00 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_INCR 0x00001e02 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_DECR 0x00001e03 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_FRONT_OP_ZPASS_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC 0x00001390 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_NEVER 0x00000200 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_LESS 0x00000201 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_EQUAL 0x00000202 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_LEQUAL 0x00000203 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_GREATER 0x00000204 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_NOTEQUAL 0x00000205 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_GEQUAL 0x00000206 -#define NV50TCL_STENCIL_FRONT_FUNC_FUNC_ALWAYS 0x00000207 -#define NV50TCL_STENCIL_FRONT_FUNC_REF 0x00001394 -#define NV50TCL_STENCIL_FRONT_MASK 0x00001398 -#define NV50TCL_STENCIL_FRONT_FUNC_MASK 0x0000139c -#define NV50TCL_FRAG_COLOR_CLAMP_EN 0x000013a8 -#define NV50TCL_Y_ORIGIN_BOTTOM 0x000013ac -#define NV50TCL_LINE_WIDTH 0x000013b0 -#define NV50TCL_TEX_LIMITS(x) (0x000013b4+((x)*4)) -#define NV50TCL_TEX_LIMITS__SIZE 0x00000003 -#define NV50TCL_TEX_LIMITS_SAMPLERS_LOG2_SHIFT 0 -#define NV50TCL_TEX_LIMITS_SAMPLERS_LOG2_MASK 0x0000000f -#define NV50TCL_TEX_LIMITS_TEXTURES_LOG2_SHIFT 4 -#define NV50TCL_TEX_LIMITS_TEXTURES_LOG2_MASK 0x000000f0 -#define NV50TCL_POINT_COORD_REPLACE_MAP(x) (0x000013c0+((x)*4)) -#define NV50TCL_POINT_COORD_REPLACE_MAP__SIZE 0x00000008 -#define NV50TCL_VP_START_ID 0x0000140c -#define NV50TCL_GP_START_ID 0x00001410 -#define NV50TCL_FP_START_ID 0x00001414 -#define NV50TCL_GP_VERTEX_OUTPUT_COUNT 0x00001420 -#define NV50TCL_VB_ELEMENT_BASE 0x00001434 -#define NV50TCL_CLEAR_FLAGS 0x0000143c -#define NV50TCL_CLEAR_FLAGS_OGL (1 << 0) -#define NV50TCL_CLEAR_FLAGS_D3D (1 << 4) -#define NV50TCL_INSTANCE_BASE 0x00001438 -#define NV50TCL_CODE_CB_FLUSH 0x00001440 -#define NV50TCL_BIND_TSC(x) (0x00001444+((x)*8)) -#define NV50TCL_BIND_TSC__SIZE 0x00000003 -#define NV50TCL_BIND_TSC_VALID (1 << 0) -#define NV50TCL_BIND_TSC_SAMPLER_SHIFT 4 -#define NV50TCL_BIND_TSC_SAMPLER_MASK 0x000000f0 -#define NV50TCL_BIND_TSC_TSC_SHIFT 12 -#define NV50TCL_BIND_TSC_TSC_MASK 0x001ff000 -#define NV50TCL_BIND_TIC(x) (0x00001448+((x)*8)) -#define NV50TCL_BIND_TIC__SIZE 0x00000003 -#define NV50TCL_BIND_TIC_VALID (1 << 0) -#define NV50TCL_BIND_TIC_TEXTURE_SHIFT 1 -#define NV50TCL_BIND_TIC_TEXTURE_MASK 0x000001fe -#define NV50TCL_BIND_TIC_TIC_SHIFT 9 -#define NV50TCL_BIND_TIC_TIC_MASK 0x7ffffe00 -#define NV50TCL_STRMOUT_MAP(x) (0x00001480+((x)*4)) -#define NV50TCL_STRMOUT_MAP__SIZE 0x00000020 -#define NV50TCL_CLIPID_HEIGHT 0x00001504 -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE 0x00001510 -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_0 (1 << 0) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_1 (1 << 1) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_2 (1 << 2) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_3 (1 << 3) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_4 (1 << 4) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_5 (1 << 5) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_6 (1 << 6) -#define NV50TCL_VP_CLIP_DISTANCE_ENABLE_7 (1 << 7) -#define NV50TCL_SAMPLECNT_ENABLE 0x00001514 -#define NV50TCL_POINT_SIZE 0x00001518 -#define NV50TCL_POINT_SPRITE_ENABLE 0x00001520 -#define NV50TCL_SAMPLECNT_RESET 0x00001530 -#define NV50TCL_ZETA_ENABLE 0x00001538 -#define NV50TCL_MULTISAMPLE_CTRL 0x0000153c -#define NV50TCL_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE (1 << 0) -#define NV50TCL_MULTISAMPLE_CTRL_ALPHA_TO_ONE (1 << 4) -#define NV50TCL_NOPERSPECTIVE_BITMAP(x) (0x00001540+((x)*4)) -#define NV50TCL_NOPERSPECTIVE_BITMAP__SIZE 0x00000004 -#define NV50TCL_COND_ADDRESS_HIGH 0x00001550 -#define NV50TCL_COND_ADDRESS_LOW 0x00001554 -#define NV50TCL_COND_MODE 0x00001558 -#define NV50TCL_COND_MODE_NEVER 0x00000000 -#define NV50TCL_COND_MODE_ALWAYS 0x00000001 -#define NV50TCL_COND_MODE_RES 0x00000002 -#define NV50TCL_COND_MODE_NOT_RES_AND_NOT_ID 0x00000003 -#define NV50TCL_COND_MODE_RES_OR_ID 0x00000004 -#define NV50TCL_TSC_ADDRESS_HIGH 0x0000155c -#define NV50TCL_TSC_ADDRESS_LOW 0x00001560 -#define NV50TCL_TSC_LIMIT 0x00001564 -#define NV50TCL_POLYGON_OFFSET_FACTOR 0x0000156c -#define NV50TCL_LINE_SMOOTH_ENABLE 0x00001570 -#define NV50TCL_TIC_ADDRESS_HIGH 0x00001574 -#define NV50TCL_TIC_ADDRESS_LOW 0x00001578 -#define NV50TCL_TIC_LIMIT 0x0000157c -#define NV50TCL_PM_CONTROL(x) (0x00001580+((x)*4)) -#define NV50TCL_PM_CONTROL__SIZE 0x00000004 -#define NV50TCL_PM_CONTROL_UNK0 (1 << 0) -#define NV50TCL_PM_CONTROL_UNK1_SHIFT 4 -#define NV50TCL_PM_CONTROL_UNK1_MASK 0x00000070 -#define NV50TCL_PM_CONTROL_UNK2_SHIFT 8 -#define NV50TCL_PM_CONTROL_UNK2_MASK 0xffffff00 -#define NV50TCL_STENCIL_BACK_ENABLE 0x00001594 -#define NV50TCL_STENCIL_BACK_OP_FAIL 0x00001598 -#define NV50TCL_STENCIL_BACK_OP_FAIL_ZERO 0x00000000 -#define NV50TCL_STENCIL_BACK_OP_FAIL_INVERT 0x0000150a -#define NV50TCL_STENCIL_BACK_OP_FAIL_KEEP 0x00001e00 -#define NV50TCL_STENCIL_BACK_OP_FAIL_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_BACK_OP_FAIL_INCR 0x00001e02 -#define NV50TCL_STENCIL_BACK_OP_FAIL_DECR 0x00001e03 -#define NV50TCL_STENCIL_BACK_OP_FAIL_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_BACK_OP_FAIL_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL 0x0000159c -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_ZERO 0x00000000 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_INVERT 0x0000150a -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_KEEP 0x00001e00 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_INCR 0x00001e02 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_DECR 0x00001e03 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_BACK_OP_ZFAIL_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_BACK_OP_ZPASS 0x000015a0 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_ZERO 0x00000000 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_INVERT 0x0000150a -#define NV50TCL_STENCIL_BACK_OP_ZPASS_KEEP 0x00001e00 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_REPLACE 0x00001e01 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_INCR 0x00001e02 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_DECR 0x00001e03 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_INCR_WRAP 0x00008507 -#define NV50TCL_STENCIL_BACK_OP_ZPASS_DECR_WRAP 0x00008508 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC 0x000015a4 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_NEVER 0x00000200 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_LESS 0x00000201 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_EQUAL 0x00000202 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_LEQUAL 0x00000203 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_GREATER 0x00000204 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_NOTEQUAL 0x00000205 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_GEQUAL 0x00000206 -#define NV50TCL_STENCIL_BACK_FUNC_FUNC_ALWAYS 0x00000207 -#define NV50TCL_FRAMEBUFFER_SRGB 0x000015b8 -#define NV50TCL_POLYGON_OFFSET_UNITS 0x000015bc -#define NV50TCL_GP_BUILTIN_RESULT_EN 0x000015cc -#define NV50TCL_GP_BUILTIN_RESULT_EN_VPORT_IDX (1 << 0) -#define NV50TCL_GP_BUILTIN_RESULT_EN_LAYER_IDX (1 << 16) -#define NV50TCL_MULTISAMPLE_MODE 0x000015d0 -#define NV50TCL_MULTISAMPLE_MODE_1X 0x00000000 -#define NV50TCL_MULTISAMPLE_MODE_2XMS 0x00000001 -#define NV50TCL_MULTISAMPLE_MODE_4XMS 0x00000002 -#define NV50TCL_MULTISAMPLE_MODE_8XMS 0x00000004 -#define NV50TCL_MULTISAMPLE_MODE_4XMS_4XCS 0x00000008 -#define NV50TCL_MULTISAMPLE_MODE_4XMS_12XCS 0x00000009 -#define NV50TCL_MULTISAMPLE_MODE_8XMS_8XCS 0x0000000a -#define NV50TCL_VERTEX_BEGIN 0x000015dc -#define NV50TCL_VERTEX_BEGIN_POINTS 0x00000000 -#define NV50TCL_VERTEX_BEGIN_LINES 0x00000001 -#define NV50TCL_VERTEX_BEGIN_LINE_LOOP 0x00000002 -#define NV50TCL_VERTEX_BEGIN_LINE_STRIP 0x00000003 -#define NV50TCL_VERTEX_BEGIN_TRIANGLES 0x00000004 -#define NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP 0x00000005 -#define NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN 0x00000006 -#define NV50TCL_VERTEX_BEGIN_QUADS 0x00000007 -#define NV50TCL_VERTEX_BEGIN_QUAD_STRIP 0x00000008 -#define NV50TCL_VERTEX_BEGIN_POLYGON 0x00000009 -#define NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY 0x0000000a -#define NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY 0x0000000b -#define NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY 0x0000000c -#define NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY 0x0000000d -#define NV50TCL_VERTEX_BEGIN_PATCHES 0x0000000e -#define NV50TCL_VERTEX_END 0x000015e0 -#define NV50TCL_EDGEFLAG_ENABLE 0x000015e4 -#define NV50TCL_VB_ELEMENT_U32 0x000015e8 -#define NV50TCL_VB_ELEMENT_U16_SETUP 0x000015ec -#define NV50TCL_VB_ELEMENT_U16_SETUP_OFFSET_SHIFT 30 -#define NV50TCL_VB_ELEMENT_U16_SETUP_OFFSET_MASK 0xc0000000 -#define NV50TCL_VB_ELEMENT_U16_SETUP_COUNT_SHIFT 0 -#define NV50TCL_VB_ELEMENT_U16_SETUP_COUNT_MASK 0x3fffffff -#define NV50TCL_VB_ELEMENT_U16 0x000015f0 -#define NV50TCL_VB_ELEMENT_U16_I0_SHIFT 0 -#define NV50TCL_VB_ELEMENT_U16_I0_MASK 0x0000ffff -#define NV50TCL_VB_ELEMENT_U16_I1_SHIFT 16 -#define NV50TCL_VB_ELEMENT_U16_I1_MASK 0xffff0000 -#define NV50TCL_VERTEX_BASE_HIGH 0x000015f4 -#define NV50TCL_VERTEX_BASE_LOW 0x000015f8 -#define NV50TCL_VERTEX_DATA 0x00001640 -#define NV50TCL_PRIM_RESTART_ENABLE 0x00001644 -#define NV50TCL_PRIM_RESTART_INDEX 0x00001648 -#define NV50TCL_VP_GP_BUILTIN_ATTR_EN 0x0000164c -#define NV50TCL_VP_GP_BUILTIN_ATTR_EN_VERTEX_ID (1 << 0) -#define NV50TCL_VP_GP_BUILTIN_ATTR_EN_INSTANCE_ID (1 << 4) -#define NV50TCL_VP_GP_BUILTIN_ATTR_EN_PRIMITIVE_ID (1 << 8) -#define NV50TCL_VP_GP_BUILTIN_ATTR_EN_UNK12 (1 << 12) -#define NV50TCL_VP_ATTR_EN_0 0x00001650 -#define NV50TCL_VP_ATTR_EN_0_7_SHIFT 28 -#define NV50TCL_VP_ATTR_EN_0_7_MASK 0xf0000000 -#define NV50TCL_VP_ATTR_EN_0_7_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_7_XNNN 0x10000000 -#define NV50TCL_VP_ATTR_EN_0_7_NYNN 0x20000000 -#define NV50TCL_VP_ATTR_EN_0_7_XYNN 0x30000000 -#define NV50TCL_VP_ATTR_EN_0_7_NNZN 0x40000000 -#define NV50TCL_VP_ATTR_EN_0_7_XNZN 0x50000000 -#define NV50TCL_VP_ATTR_EN_0_7_NYZN 0x60000000 -#define NV50TCL_VP_ATTR_EN_0_7_XYZN 0x70000000 -#define NV50TCL_VP_ATTR_EN_0_7_NNNW 0x80000000 -#define NV50TCL_VP_ATTR_EN_0_7_XNNW 0x90000000 -#define NV50TCL_VP_ATTR_EN_0_7_NYNW 0xa0000000 -#define NV50TCL_VP_ATTR_EN_0_7_XYNW 0xb0000000 -#define NV50TCL_VP_ATTR_EN_0_7_NNZW 0xc0000000 -#define NV50TCL_VP_ATTR_EN_0_7_XNZW 0xd0000000 -#define NV50TCL_VP_ATTR_EN_0_7_NYZW 0xe0000000 -#define NV50TCL_VP_ATTR_EN_0_7_XYZW 0xf0000000 -#define NV50TCL_VP_ATTR_EN_0_6_SHIFT 24 -#define NV50TCL_VP_ATTR_EN_0_6_MASK 0x0f000000 -#define NV50TCL_VP_ATTR_EN_0_6_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_6_XNNN 0x01000000 -#define NV50TCL_VP_ATTR_EN_0_6_NYNN 0x02000000 -#define NV50TCL_VP_ATTR_EN_0_6_XYNN 0x03000000 -#define NV50TCL_VP_ATTR_EN_0_6_NNZN 0x04000000 -#define NV50TCL_VP_ATTR_EN_0_6_XNZN 0x05000000 -#define NV50TCL_VP_ATTR_EN_0_6_NYZN 0x06000000 -#define NV50TCL_VP_ATTR_EN_0_6_XYZN 0x07000000 -#define NV50TCL_VP_ATTR_EN_0_6_NNNW 0x08000000 -#define NV50TCL_VP_ATTR_EN_0_6_XNNW 0x09000000 -#define NV50TCL_VP_ATTR_EN_0_6_NYNW 0x0a000000 -#define NV50TCL_VP_ATTR_EN_0_6_XYNW 0x0b000000 -#define NV50TCL_VP_ATTR_EN_0_6_NNZW 0x0c000000 -#define NV50TCL_VP_ATTR_EN_0_6_XNZW 0x0d000000 -#define NV50TCL_VP_ATTR_EN_0_6_NYZW 0x0e000000 -#define NV50TCL_VP_ATTR_EN_0_6_XYZW 0x0f000000 -#define NV50TCL_VP_ATTR_EN_0_5_SHIFT 20 -#define NV50TCL_VP_ATTR_EN_0_5_MASK 0x00f00000 -#define NV50TCL_VP_ATTR_EN_0_5_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_5_XNNN 0x00100000 -#define NV50TCL_VP_ATTR_EN_0_5_NYNN 0x00200000 -#define NV50TCL_VP_ATTR_EN_0_5_XYNN 0x00300000 -#define NV50TCL_VP_ATTR_EN_0_5_NNZN 0x00400000 -#define NV50TCL_VP_ATTR_EN_0_5_XNZN 0x00500000 -#define NV50TCL_VP_ATTR_EN_0_5_NYZN 0x00600000 -#define NV50TCL_VP_ATTR_EN_0_5_XYZN 0x00700000 -#define NV50TCL_VP_ATTR_EN_0_5_NNNW 0x00800000 -#define NV50TCL_VP_ATTR_EN_0_5_XNNW 0x00900000 -#define NV50TCL_VP_ATTR_EN_0_5_NYNW 0x00a00000 -#define NV50TCL_VP_ATTR_EN_0_5_XYNW 0x00b00000 -#define NV50TCL_VP_ATTR_EN_0_5_NNZW 0x00c00000 -#define NV50TCL_VP_ATTR_EN_0_5_XNZW 0x00d00000 -#define NV50TCL_VP_ATTR_EN_0_5_NYZW 0x00e00000 -#define NV50TCL_VP_ATTR_EN_0_5_XYZW 0x00f00000 -#define NV50TCL_VP_ATTR_EN_0_4_SHIFT 16 -#define NV50TCL_VP_ATTR_EN_0_4_MASK 0x000f0000 -#define NV50TCL_VP_ATTR_EN_0_4_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_4_XNNN 0x00010000 -#define NV50TCL_VP_ATTR_EN_0_4_NYNN 0x00020000 -#define NV50TCL_VP_ATTR_EN_0_4_XYNN 0x00030000 -#define NV50TCL_VP_ATTR_EN_0_4_NNZN 0x00040000 -#define NV50TCL_VP_ATTR_EN_0_4_XNZN 0x00050000 -#define NV50TCL_VP_ATTR_EN_0_4_NYZN 0x00060000 -#define NV50TCL_VP_ATTR_EN_0_4_XYZN 0x00070000 -#define NV50TCL_VP_ATTR_EN_0_4_NNNW 0x00080000 -#define NV50TCL_VP_ATTR_EN_0_4_XNNW 0x00090000 -#define NV50TCL_VP_ATTR_EN_0_4_NYNW 0x000a0000 -#define NV50TCL_VP_ATTR_EN_0_4_XYNW 0x000b0000 -#define NV50TCL_VP_ATTR_EN_0_4_NNZW 0x000c0000 -#define NV50TCL_VP_ATTR_EN_0_4_XNZW 0x000d0000 -#define NV50TCL_VP_ATTR_EN_0_4_NYZW 0x000e0000 -#define NV50TCL_VP_ATTR_EN_0_4_XYZW 0x000f0000 -#define NV50TCL_VP_ATTR_EN_0_3_SHIFT 12 -#define NV50TCL_VP_ATTR_EN_0_3_MASK 0x0000f000 -#define NV50TCL_VP_ATTR_EN_0_3_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_3_XNNN 0x00001000 -#define NV50TCL_VP_ATTR_EN_0_3_NYNN 0x00002000 -#define NV50TCL_VP_ATTR_EN_0_3_XYNN 0x00003000 -#define NV50TCL_VP_ATTR_EN_0_3_NNZN 0x00004000 -#define NV50TCL_VP_ATTR_EN_0_3_XNZN 0x00005000 -#define NV50TCL_VP_ATTR_EN_0_3_NYZN 0x00006000 -#define NV50TCL_VP_ATTR_EN_0_3_XYZN 0x00007000 -#define NV50TCL_VP_ATTR_EN_0_3_NNNW 0x00008000 -#define NV50TCL_VP_ATTR_EN_0_3_XNNW 0x00009000 -#define NV50TCL_VP_ATTR_EN_0_3_NYNW 0x0000a000 -#define NV50TCL_VP_ATTR_EN_0_3_XYNW 0x0000b000 -#define NV50TCL_VP_ATTR_EN_0_3_NNZW 0x0000c000 -#define NV50TCL_VP_ATTR_EN_0_3_XNZW 0x0000d000 -#define NV50TCL_VP_ATTR_EN_0_3_NYZW 0x0000e000 -#define NV50TCL_VP_ATTR_EN_0_3_XYZW 0x0000f000 -#define NV50TCL_VP_ATTR_EN_0_2_SHIFT 8 -#define NV50TCL_VP_ATTR_EN_0_2_MASK 0x00000f00 -#define NV50TCL_VP_ATTR_EN_0_2_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_2_XNNN 0x00000100 -#define NV50TCL_VP_ATTR_EN_0_2_NYNN 0x00000200 -#define NV50TCL_VP_ATTR_EN_0_2_XYNN 0x00000300 -#define NV50TCL_VP_ATTR_EN_0_2_NNZN 0x00000400 -#define NV50TCL_VP_ATTR_EN_0_2_XNZN 0x00000500 -#define NV50TCL_VP_ATTR_EN_0_2_NYZN 0x00000600 -#define NV50TCL_VP_ATTR_EN_0_2_XYZN 0x00000700 -#define NV50TCL_VP_ATTR_EN_0_2_NNNW 0x00000800 -#define NV50TCL_VP_ATTR_EN_0_2_XNNW 0x00000900 -#define NV50TCL_VP_ATTR_EN_0_2_NYNW 0x00000a00 -#define NV50TCL_VP_ATTR_EN_0_2_XYNW 0x00000b00 -#define NV50TCL_VP_ATTR_EN_0_2_NNZW 0x00000c00 -#define NV50TCL_VP_ATTR_EN_0_2_XNZW 0x00000d00 -#define NV50TCL_VP_ATTR_EN_0_2_NYZW 0x00000e00 -#define NV50TCL_VP_ATTR_EN_0_2_XYZW 0x00000f00 -#define NV50TCL_VP_ATTR_EN_0_1_SHIFT 4 -#define NV50TCL_VP_ATTR_EN_0_1_MASK 0x000000f0 -#define NV50TCL_VP_ATTR_EN_0_1_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_1_XNNN 0x00000010 -#define NV50TCL_VP_ATTR_EN_0_1_NYNN 0x00000020 -#define NV50TCL_VP_ATTR_EN_0_1_XYNN 0x00000030 -#define NV50TCL_VP_ATTR_EN_0_1_NNZN 0x00000040 -#define NV50TCL_VP_ATTR_EN_0_1_XNZN 0x00000050 -#define NV50TCL_VP_ATTR_EN_0_1_NYZN 0x00000060 -#define NV50TCL_VP_ATTR_EN_0_1_XYZN 0x00000070 -#define NV50TCL_VP_ATTR_EN_0_1_NNNW 0x00000080 -#define NV50TCL_VP_ATTR_EN_0_1_XNNW 0x00000090 -#define NV50TCL_VP_ATTR_EN_0_1_NYNW 0x000000a0 -#define NV50TCL_VP_ATTR_EN_0_1_XYNW 0x000000b0 -#define NV50TCL_VP_ATTR_EN_0_1_NNZW 0x000000c0 -#define NV50TCL_VP_ATTR_EN_0_1_XNZW 0x000000d0 -#define NV50TCL_VP_ATTR_EN_0_1_NYZW 0x000000e0 -#define NV50TCL_VP_ATTR_EN_0_1_XYZW 0x000000f0 -#define NV50TCL_VP_ATTR_EN_0_0_SHIFT 0 -#define NV50TCL_VP_ATTR_EN_0_0_MASK 0x0000000f -#define NV50TCL_VP_ATTR_EN_0_0_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_0_0_XNNN 0x00000001 -#define NV50TCL_VP_ATTR_EN_0_0_NYNN 0x00000002 -#define NV50TCL_VP_ATTR_EN_0_0_XYNN 0x00000003 -#define NV50TCL_VP_ATTR_EN_0_0_NNZN 0x00000004 -#define NV50TCL_VP_ATTR_EN_0_0_XNZN 0x00000005 -#define NV50TCL_VP_ATTR_EN_0_0_NYZN 0x00000006 -#define NV50TCL_VP_ATTR_EN_0_0_XYZN 0x00000007 -#define NV50TCL_VP_ATTR_EN_0_0_NNNW 0x00000008 -#define NV50TCL_VP_ATTR_EN_0_0_XNNW 0x00000009 -#define NV50TCL_VP_ATTR_EN_0_0_NYNW 0x0000000a -#define NV50TCL_VP_ATTR_EN_0_0_XYNW 0x0000000b -#define NV50TCL_VP_ATTR_EN_0_0_NNZW 0x0000000c -#define NV50TCL_VP_ATTR_EN_0_0_XNZW 0x0000000d -#define NV50TCL_VP_ATTR_EN_0_0_NYZW 0x0000000e -#define NV50TCL_VP_ATTR_EN_0_0_XYZW 0x0000000f -#define NV50TCL_VP_ATTR_EN_1 0x00001654 -#define NV50TCL_VP_ATTR_EN_1_15_SHIFT 28 -#define NV50TCL_VP_ATTR_EN_1_15_MASK 0xf0000000 -#define NV50TCL_VP_ATTR_EN_1_15_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_15_XNNN 0x10000000 -#define NV50TCL_VP_ATTR_EN_1_15_NYNN 0x20000000 -#define NV50TCL_VP_ATTR_EN_1_15_XYNN 0x30000000 -#define NV50TCL_VP_ATTR_EN_1_15_NNZN 0x40000000 -#define NV50TCL_VP_ATTR_EN_1_15_XNZN 0x50000000 -#define NV50TCL_VP_ATTR_EN_1_15_NYZN 0x60000000 -#define NV50TCL_VP_ATTR_EN_1_15_XYZN 0x70000000 -#define NV50TCL_VP_ATTR_EN_1_15_NNNW 0x80000000 -#define NV50TCL_VP_ATTR_EN_1_15_XNNW 0x90000000 -#define NV50TCL_VP_ATTR_EN_1_15_NYNW 0xa0000000 -#define NV50TCL_VP_ATTR_EN_1_15_XYNW 0xb0000000 -#define NV50TCL_VP_ATTR_EN_1_15_NNZW 0xc0000000 -#define NV50TCL_VP_ATTR_EN_1_15_XNZW 0xd0000000 -#define NV50TCL_VP_ATTR_EN_1_15_NYZW 0xe0000000 -#define NV50TCL_VP_ATTR_EN_1_15_XYZW 0xf0000000 -#define NV50TCL_VP_ATTR_EN_1_14_SHIFT 24 -#define NV50TCL_VP_ATTR_EN_1_14_MASK 0x0f000000 -#define NV50TCL_VP_ATTR_EN_1_14_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_14_XNNN 0x01000000 -#define NV50TCL_VP_ATTR_EN_1_14_NYNN 0x02000000 -#define NV50TCL_VP_ATTR_EN_1_14_XYNN 0x03000000 -#define NV50TCL_VP_ATTR_EN_1_14_NNZN 0x04000000 -#define NV50TCL_VP_ATTR_EN_1_14_XNZN 0x05000000 -#define NV50TCL_VP_ATTR_EN_1_14_NYZN 0x06000000 -#define NV50TCL_VP_ATTR_EN_1_14_XYZN 0x07000000 -#define NV50TCL_VP_ATTR_EN_1_14_NNNW 0x08000000 -#define NV50TCL_VP_ATTR_EN_1_14_XNNW 0x09000000 -#define NV50TCL_VP_ATTR_EN_1_14_NYNW 0x0a000000 -#define NV50TCL_VP_ATTR_EN_1_14_XYNW 0x0b000000 -#define NV50TCL_VP_ATTR_EN_1_14_NNZW 0x0c000000 -#define NV50TCL_VP_ATTR_EN_1_14_XNZW 0x0d000000 -#define NV50TCL_VP_ATTR_EN_1_14_NYZW 0x0e000000 -#define NV50TCL_VP_ATTR_EN_1_14_XYZW 0x0f000000 -#define NV50TCL_VP_ATTR_EN_1_13_SHIFT 20 -#define NV50TCL_VP_ATTR_EN_1_13_MASK 0x00f00000 -#define NV50TCL_VP_ATTR_EN_1_13_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_13_XNNN 0x00100000 -#define NV50TCL_VP_ATTR_EN_1_13_NYNN 0x00200000 -#define NV50TCL_VP_ATTR_EN_1_13_XYNN 0x00300000 -#define NV50TCL_VP_ATTR_EN_1_13_NNZN 0x00400000 -#define NV50TCL_VP_ATTR_EN_1_13_XNZN 0x00500000 -#define NV50TCL_VP_ATTR_EN_1_13_NYZN 0x00600000 -#define NV50TCL_VP_ATTR_EN_1_13_XYZN 0x00700000 -#define NV50TCL_VP_ATTR_EN_1_13_NNNW 0x00800000 -#define NV50TCL_VP_ATTR_EN_1_13_XNNW 0x00900000 -#define NV50TCL_VP_ATTR_EN_1_13_NYNW 0x00a00000 -#define NV50TCL_VP_ATTR_EN_1_13_XYNW 0x00b00000 -#define NV50TCL_VP_ATTR_EN_1_13_NNZW 0x00c00000 -#define NV50TCL_VP_ATTR_EN_1_13_XNZW 0x00d00000 -#define NV50TCL_VP_ATTR_EN_1_13_NYZW 0x00e00000 -#define NV50TCL_VP_ATTR_EN_1_13_XYZW 0x00f00000 -#define NV50TCL_VP_ATTR_EN_1_12_SHIFT 16 -#define NV50TCL_VP_ATTR_EN_1_12_MASK 0x000f0000 -#define NV50TCL_VP_ATTR_EN_1_12_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_12_XNNN 0x00010000 -#define NV50TCL_VP_ATTR_EN_1_12_NYNN 0x00020000 -#define NV50TCL_VP_ATTR_EN_1_12_XYNN 0x00030000 -#define NV50TCL_VP_ATTR_EN_1_12_NNZN 0x00040000 -#define NV50TCL_VP_ATTR_EN_1_12_XNZN 0x00050000 -#define NV50TCL_VP_ATTR_EN_1_12_NYZN 0x00060000 -#define NV50TCL_VP_ATTR_EN_1_12_XYZN 0x00070000 -#define NV50TCL_VP_ATTR_EN_1_12_NNNW 0x00080000 -#define NV50TCL_VP_ATTR_EN_1_12_XNNW 0x00090000 -#define NV50TCL_VP_ATTR_EN_1_12_NYNW 0x000a0000 -#define NV50TCL_VP_ATTR_EN_1_12_XYNW 0x000b0000 -#define NV50TCL_VP_ATTR_EN_1_12_NNZW 0x000c0000 -#define NV50TCL_VP_ATTR_EN_1_12_XNZW 0x000d0000 -#define NV50TCL_VP_ATTR_EN_1_12_NYZW 0x000e0000 -#define NV50TCL_VP_ATTR_EN_1_12_XYZW 0x000f0000 -#define NV50TCL_VP_ATTR_EN_1_11_SHIFT 12 -#define NV50TCL_VP_ATTR_EN_1_11_MASK 0x0000f000 -#define NV50TCL_VP_ATTR_EN_1_11_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_11_XNNN 0x00001000 -#define NV50TCL_VP_ATTR_EN_1_11_NYNN 0x00002000 -#define NV50TCL_VP_ATTR_EN_1_11_XYNN 0x00003000 -#define NV50TCL_VP_ATTR_EN_1_11_NNZN 0x00004000 -#define NV50TCL_VP_ATTR_EN_1_11_XNZN 0x00005000 -#define NV50TCL_VP_ATTR_EN_1_11_NYZN 0x00006000 -#define NV50TCL_VP_ATTR_EN_1_11_XYZN 0x00007000 -#define NV50TCL_VP_ATTR_EN_1_11_NNNW 0x00008000 -#define NV50TCL_VP_ATTR_EN_1_11_XNNW 0x00009000 -#define NV50TCL_VP_ATTR_EN_1_11_NYNW 0x0000a000 -#define NV50TCL_VP_ATTR_EN_1_11_XYNW 0x0000b000 -#define NV50TCL_VP_ATTR_EN_1_11_NNZW 0x0000c000 -#define NV50TCL_VP_ATTR_EN_1_11_XNZW 0x0000d000 -#define NV50TCL_VP_ATTR_EN_1_11_NYZW 0x0000e000 -#define NV50TCL_VP_ATTR_EN_1_11_XYZW 0x0000f000 -#define NV50TCL_VP_ATTR_EN_1_10_SHIFT 8 -#define NV50TCL_VP_ATTR_EN_1_10_MASK 0x00000f00 -#define NV50TCL_VP_ATTR_EN_1_10_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_10_XNNN 0x00000100 -#define NV50TCL_VP_ATTR_EN_1_10_NYNN 0x00000200 -#define NV50TCL_VP_ATTR_EN_1_10_XYNN 0x00000300 -#define NV50TCL_VP_ATTR_EN_1_10_NNZN 0x00000400 -#define NV50TCL_VP_ATTR_EN_1_10_XNZN 0x00000500 -#define NV50TCL_VP_ATTR_EN_1_10_NYZN 0x00000600 -#define NV50TCL_VP_ATTR_EN_1_10_XYZN 0x00000700 -#define NV50TCL_VP_ATTR_EN_1_10_NNNW 0x00000800 -#define NV50TCL_VP_ATTR_EN_1_10_XNNW 0x00000900 -#define NV50TCL_VP_ATTR_EN_1_10_NYNW 0x00000a00 -#define NV50TCL_VP_ATTR_EN_1_10_XYNW 0x00000b00 -#define NV50TCL_VP_ATTR_EN_1_10_NNZW 0x00000c00 -#define NV50TCL_VP_ATTR_EN_1_10_XNZW 0x00000d00 -#define NV50TCL_VP_ATTR_EN_1_10_NYZW 0x00000e00 -#define NV50TCL_VP_ATTR_EN_1_10_XYZW 0x00000f00 -#define NV50TCL_VP_ATTR_EN_1_9_SHIFT 4 -#define NV50TCL_VP_ATTR_EN_1_9_MASK 0x000000f0 -#define NV50TCL_VP_ATTR_EN_1_9_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_9_XNNN 0x00000010 -#define NV50TCL_VP_ATTR_EN_1_9_NYNN 0x00000020 -#define NV50TCL_VP_ATTR_EN_1_9_XYNN 0x00000030 -#define NV50TCL_VP_ATTR_EN_1_9_NNZN 0x00000040 -#define NV50TCL_VP_ATTR_EN_1_9_XNZN 0x00000050 -#define NV50TCL_VP_ATTR_EN_1_9_NYZN 0x00000060 -#define NV50TCL_VP_ATTR_EN_1_9_XYZN 0x00000070 -#define NV50TCL_VP_ATTR_EN_1_9_NNNW 0x00000080 -#define NV50TCL_VP_ATTR_EN_1_9_XNNW 0x00000090 -#define NV50TCL_VP_ATTR_EN_1_9_NYNW 0x000000a0 -#define NV50TCL_VP_ATTR_EN_1_9_XYNW 0x000000b0 -#define NV50TCL_VP_ATTR_EN_1_9_NNZW 0x000000c0 -#define NV50TCL_VP_ATTR_EN_1_9_XNZW 0x000000d0 -#define NV50TCL_VP_ATTR_EN_1_9_NYZW 0x000000e0 -#define NV50TCL_VP_ATTR_EN_1_9_XYZW 0x000000f0 -#define NV50TCL_VP_ATTR_EN_1_8_SHIFT 0 -#define NV50TCL_VP_ATTR_EN_1_8_MASK 0x0000000f -#define NV50TCL_VP_ATTR_EN_1_8_NONE 0x00000000 -#define NV50TCL_VP_ATTR_EN_1_8_XNNN 0x00000001 -#define NV50TCL_VP_ATTR_EN_1_8_NYNN 0x00000002 -#define NV50TCL_VP_ATTR_EN_1_8_XYNN 0x00000003 -#define NV50TCL_VP_ATTR_EN_1_8_NNZN 0x00000004 -#define NV50TCL_VP_ATTR_EN_1_8_XNZN 0x00000005 -#define NV50TCL_VP_ATTR_EN_1_8_NYZN 0x00000006 -#define NV50TCL_VP_ATTR_EN_1_8_XYZN 0x00000007 -#define NV50TCL_VP_ATTR_EN_1_8_NNNW 0x00000008 -#define NV50TCL_VP_ATTR_EN_1_8_XNNW 0x00000009 -#define NV50TCL_VP_ATTR_EN_1_8_NYNW 0x0000000a -#define NV50TCL_VP_ATTR_EN_1_8_XYNW 0x0000000b -#define NV50TCL_VP_ATTR_EN_1_8_NNZW 0x0000000c -#define NV50TCL_VP_ATTR_EN_1_8_XNZW 0x0000000d -#define NV50TCL_VP_ATTR_EN_1_8_NYZW 0x0000000e -#define NV50TCL_VP_ATTR_EN_1_8_XYZW 0x0000000f -#define NV50TCL_POINT_SPRITE_CTRL 0x00001660 -#define NV50TCL_LINE_STIPPLE_ENABLE 0x0000166c -#define NV50TCL_LINE_STIPPLE_PATTERN 0x00001680 -#define NV50TCL_PROVOKING_VERTEX_LAST 0x00001684 -#define NV50TCL_VERTEX_TWO_SIDE_ENABLE 0x00001688 -#define NV50TCL_POLYGON_STIPPLE_ENABLE 0x0000168c -#define NV50TCL_SET_PROGRAM_CB 0x00001694 -#define NV50TCL_SET_PROGRAM_CB_PROGRAM_SHIFT 4 -#define NV50TCL_SET_PROGRAM_CB_PROGRAM_MASK 0x000000f0 -#define NV50TCL_SET_PROGRAM_CB_PROGRAM_VERTEX 0x00000000 -#define NV50TCL_SET_PROGRAM_CB_PROGRAM_GEOMETRY 0x00000020 -#define NV50TCL_SET_PROGRAM_CB_PROGRAM_FRAGMENT 0x00000030 -#define NV50TCL_SET_PROGRAM_CB_INDEX_SHIFT 8 -#define NV50TCL_SET_PROGRAM_CB_INDEX_MASK 0x00000f00 -#define NV50TCL_SET_PROGRAM_CB_BUFFER_SHIFT 12 -#define NV50TCL_SET_PROGRAM_CB_BUFFER_MASK 0x0007f000 -#define NV50TCL_SET_PROGRAM_CB_VALID (1 << 0) -#define NV50TCL_VP_RESULT_MAP_SIZE 0x000016ac -#define NV50TCL_VP_REG_ALLOC_TEMP 0x000016b0 -#define NV50TCL_VP_REG_ALLOC_RESULT 0x000016b8 -#define NV50TCL_VP_RESULT_MAP(x) (0x000016bc+((x)*4)) -#define NV50TCL_VP_RESULT_MAP__SIZE 0x00000010 -#define NV50TCL_VP_RESULT_MAP_0_SHIFT 0 -#define NV50TCL_VP_RESULT_MAP_0_MASK 0x000000ff -#define NV50TCL_VP_RESULT_MAP_1_SHIFT 8 -#define NV50TCL_VP_RESULT_MAP_1_MASK 0x0000ff00 -#define NV50TCL_VP_RESULT_MAP_2_SHIFT 16 -#define NV50TCL_VP_RESULT_MAP_2_MASK 0x00ff0000 -#define NV50TCL_VP_RESULT_MAP_3_SHIFT 24 -#define NV50TCL_VP_RESULT_MAP_3_MASK 0xff000000 -#define NV50TCL_POLYGON_STIPPLE_PATTERN(x) (0x00001700+((x)*4)) -#define NV50TCL_POLYGON_STIPPLE_PATTERN__SIZE 0x00000020 -#define NV50TCL_GP_ENABLE 0x00001798 -#define NV50TCL_GP_REG_ALLOC_TEMP 0x000017a0 -#define NV50TCL_GP_REG_ALLOC_RESULT 0x000017a8 -#define NV50TCL_GP_RESULT_MAP_SIZE 0x000017ac -#define NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE 0x000017b0 -#define NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_POINTS 0x00000001 -#define NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_LINE_STRIP 0x00000002 -#define NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_TRIANGLE_STRIP 0x00000003 -#define NV50TCL_RASTERIZE_ENABLE 0x000017b4 -#define NV50TCL_STRMOUT_ENABLE 0x000017b8 -#define NV50TCL_GP_RESULT_MAP(x) (0x000017fc+((x)*4)) -#define NV50TCL_GP_RESULT_MAP__SIZE 0x00000020 -#define NV50TCL_GP_RESULT_MAP_0_SHIFT 0 -#define NV50TCL_GP_RESULT_MAP_0_MASK 0x000000ff -#define NV50TCL_GP_RESULT_MAP_1_SHIFT 8 -#define NV50TCL_GP_RESULT_MAP_1_MASK 0x0000ff00 -#define NV50TCL_GP_RESULT_MAP_2_SHIFT 16 -#define NV50TCL_GP_RESULT_MAP_2_MASK 0x00ff0000 -#define NV50TCL_GP_RESULT_MAP_3_SHIFT 24 -#define NV50TCL_GP_RESULT_MAP_3_MASK 0xff000000 -#define NV50TCL_MAP_SEMANTIC_0 0x00001904 -#define NV50TCL_MAP_SEMANTIC_0_FFC0_ID_SHIFT 0 -#define NV50TCL_MAP_SEMANTIC_0_FFC0_ID_MASK 0x000000ff -#define NV50TCL_MAP_SEMANTIC_0_BFC0_ID_SHIFT 8 -#define NV50TCL_MAP_SEMANTIC_0_BFC0_ID_MASK 0x0000ff00 -#define NV50TCL_MAP_SEMANTIC_0_COLR_NR_SHIFT 16 -#define NV50TCL_MAP_SEMANTIC_0_COLR_NR_MASK 0x00ff0000 -#define NV50TCL_MAP_SEMANTIC_0_CLMP_EN_SHIFT 24 -#define NV50TCL_MAP_SEMANTIC_0_CLMP_EN_MASK 0xff000000 -#define NV50TCL_MAP_SEMANTIC_1 0x00001908 -#define NV50TCL_MAP_SEMANTIC_1_CLIP_LO_SHIFT 0 -#define NV50TCL_MAP_SEMANTIC_1_CLIP_LO_MASK 0x000000ff -#define NV50TCL_MAP_SEMANTIC_1_CLIP_HI_SHIFT 8 -#define NV50TCL_MAP_SEMANTIC_1_CLIP_HI_MASK 0x0000ff00 -#define NV50TCL_MAP_SEMANTIC_2 0x0000190c -#define NV50TCL_MAP_SEMANTIC_2_LAYER_ID_SHIFT 0 -#define NV50TCL_MAP_SEMANTIC_2_LAYER_ID_MASK 0x000000ff -#define NV50TCL_MAP_SEMANTIC_3 0x00001910 -#define NV50TCL_MAP_SEMANTIC_3_PTSZ_EN (1 << 0) -#define NV50TCL_MAP_SEMANTIC_3_PTSZ_ID_SHIFT 4 -#define NV50TCL_MAP_SEMANTIC_3_PTSZ_ID_MASK 0x00000ff0 -#define NV50TCL_MAP_SEMANTIC_4 0x00001914 -#define NV50TCL_MAP_SEMANTIC_4_PRIM_ID_SHIFT 0 -#define NV50TCL_MAP_SEMANTIC_4_PRIM_ID_MASK 0x000000ff -#define NV50TCL_CULL_FACE_ENABLE 0x00001918 -#define NV50TCL_FRONT_FACE 0x0000191c -#define NV50TCL_FRONT_FACE_CW 0x00000900 -#define NV50TCL_FRONT_FACE_CCW 0x00000901 -#define NV50TCL_CULL_FACE 0x00001920 -#define NV50TCL_CULL_FACE_FRONT 0x00000404 -#define NV50TCL_CULL_FACE_BACK 0x00000405 -#define NV50TCL_CULL_FACE_FRONT_AND_BACK 0x00000408 -#define NV50TCL_VIEWPORT_TRANSFORM_EN 0x0000192c -#define NV50TCL_VIEW_VOLUME_CLIP_CTRL 0x0000193c -#define NV50TCL_VIEWPORT_CLIP_RECTS_EN 0x0000194c -#define NV50TCL_VIEWPORT_CLIP_MODE 0x00001950 -#define NV50TCL_VIEWPORT_CLIP_MODE_INCLUDE 0x00000000 -#define NV50TCL_VIEWPORT_CLIP_MODE_EXCLUDE 0x00000001 -#define NV50TCL_VIEWPORT_CLIP_MODE_UNKNOWN 0x00000002 -#define NV50TCL_FP_CTRL_UNK196C 0x0000196c -#define NV50TCL_CLIPID_ENABLE 0x0000197c -#define NV50TCL_CLIPID_WIDTH 0x00001980 -#define NV50TCL_CLIPID_ID 0x00001984 -#define NV50TCL_FP_INTERPOLANT_CTRL 0x00001988 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_SHIFT 24 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_MASK 0xff000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NONE 0x00000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNNN 0x01000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYNN 0x02000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYNN 0x03000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NNZN 0x04000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNZN 0x05000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYZN 0x06000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYZN 0x07000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NNNW 0x08000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNNW 0x09000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYNW 0x0a000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYNW 0x0b000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NNZW 0x0c000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XNZW 0x0d000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_NYZW 0x0e000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_UMASK_XYZW 0x0f000000 -#define NV50TCL_FP_INTERPOLANT_CTRL_COUNT_NONFLAT_SHIFT 16 -#define NV50TCL_FP_INTERPOLANT_CTRL_COUNT_NONFLAT_MASK 0x00ff0000 -#define NV50TCL_FP_INTERPOLANT_CTRL_OFFSET_SHIFT 8 -#define NV50TCL_FP_INTERPOLANT_CTRL_OFFSET_MASK 0x0000ff00 -#define NV50TCL_FP_INTERPOLANT_CTRL_COUNT_SHIFT 0 -#define NV50TCL_FP_INTERPOLANT_CTRL_COUNT_MASK 0x000000ff -#define NV50TCL_FP_REG_ALLOC_TEMP 0x0000198c -#define NV50TCL_REG_MODE 0x000019a0 -#define NV50TCL_REG_MODE_PACKED 0x00000001 -#define NV50TCL_REG_MODE_STRIPED 0x00000002 -#define NV50TCL_FP_CONTROL 0x000019a8 -#define NV50TCL_FP_CONTROL_MULTIPLE_RESULTS (1 << 0) -#define NV50TCL_FP_CONTROL_EXPORTS_Z (1 << 8) -#define NV50TCL_FP_CONTROL_USES_KIL (1 << 20) -#define NV50TCL_DEPTH_BOUNDS_EN 0x000019bc -#define NV50TCL_LOGIC_OP_ENABLE 0x000019c4 -#define NV50TCL_LOGIC_OP 0x000019c8 -#define NV50TCL_LOGIC_OP_CLEAR 0x00001500 -#define NV50TCL_LOGIC_OP_AND 0x00001501 -#define NV50TCL_LOGIC_OP_AND_REVERSE 0x00001502 -#define NV50TCL_LOGIC_OP_COPY 0x00001503 -#define NV50TCL_LOGIC_OP_AND_INVERTED 0x00001504 -#define NV50TCL_LOGIC_OP_NOOP 0x00001505 -#define NV50TCL_LOGIC_OP_XOR 0x00001506 -#define NV50TCL_LOGIC_OP_OR 0x00001507 -#define NV50TCL_LOGIC_OP_NOR 0x00001508 -#define NV50TCL_LOGIC_OP_EQUIV 0x00001509 -#define NV50TCL_LOGIC_OP_INVERT 0x0000150a -#define NV50TCL_LOGIC_OP_OR_REVERSE 0x0000150b -#define NV50TCL_LOGIC_OP_COPY_INVERTED 0x0000150c -#define NV50TCL_LOGIC_OP_OR_INVERTED 0x0000150d -#define NV50TCL_LOGIC_OP_NAND 0x0000150e -#define NV50TCL_LOGIC_OP_SET 0x0000150f -#define NV50TCL_CLEAR_BUFFERS 0x000019d0 -#define NV50TCL_CLEAR_BUFFERS_Z (1 << 0) -#define NV50TCL_CLEAR_BUFFERS_S (1 << 1) -#define NV50TCL_CLEAR_BUFFERS_R (1 << 2) -#define NV50TCL_CLEAR_BUFFERS_G (1 << 3) -#define NV50TCL_CLEAR_BUFFERS_B (1 << 4) -#define NV50TCL_CLEAR_BUFFERS_A (1 << 5) -#define NV50TCL_CLEAR_BUFFERS_RT_SHIFT 6 -#define NV50TCL_CLEAR_BUFFERS_RT_MASK 0x000003c0 -#define NV50TCL_CLEAR_BUFFERS_LAYER_SHIFT 10 -#define NV50TCL_CLEAR_BUFFERS_LAYER_MASK 0x0007fc00 -#define NV50TCL_COLOR_MASK(x) (0x00001a00+((x)*4)) -#define NV50TCL_COLOR_MASK__SIZE 0x00000008 -#define NV50TCL_COLOR_MASK_R_SHIFT 0 -#define NV50TCL_COLOR_MASK_R_MASK 0x0000000f -#define NV50TCL_COLOR_MASK_G_SHIFT 4 -#define NV50TCL_COLOR_MASK_G_MASK 0x000000f0 -#define NV50TCL_COLOR_MASK_B_SHIFT 8 -#define NV50TCL_COLOR_MASK_B_MASK 0x00000f00 -#define NV50TCL_COLOR_MASK_A_SHIFT 12 -#define NV50TCL_COLOR_MASK_A_MASK 0x0000f000 -#define NV50TCL_STRMOUT_ADDRESS_HIGH(x) (0x00001a80+((x)*16)) -#define NV50TCL_STRMOUT_ADDRESS_HIGH__SIZE 0x00000004 -#define NV50TCL_STRMOUT_ADDRESS_LOW(x) (0x00001a84+((x)*16)) -#define NV50TCL_STRMOUT_ADDRESS_LOW__SIZE 0x00000004 -#define NV50TCL_STRMOUT_NUM_ATTRIBS(x) (0x00001a88+((x)*16)) -#define NV50TCL_STRMOUT_NUM_ATTRIBS__SIZE 0x00000004 -#define NV50TCL_VERTEX_ARRAY_ATTRIB(x) (0x00001ac0+((x)*4)) -#define NV50TCL_VERTEX_ARRAY_ATTRIB__SIZE 0x00000010 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_BUFFER_SHIFT 0 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_BUFFER_MASK 0x0000000f -#define NV50TCL_VERTEX_ARRAY_ATTRIB_CONST (1 << 4) -#define NV50TCL_VERTEX_ARRAY_ATTRIB_OFFSET_SHIFT 5 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_OFFSET_MASK 0x0007ffe0 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_SHIFT 19 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_MASK 0x01f80000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32_32 0x00080000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32 0x00100000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16_16 0x00180000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32 0x00200000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16 0x00280000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8_8 0x00500000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16 0x00780000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32 0x00900000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8 0x00980000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8 0x00c00000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16 0x00d80000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8 0x00e80000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_2_10_10_10 0x01800000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SHIFT 25 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_MASK 0x0e000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT 0x0e000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM 0x02000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM 0x04000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_USCALED 0x0a000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED 0x0c000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UINT 0x08000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SINT 0x06000000 -#define NV50TCL_VERTEX_ARRAY_ATTRIB_BGRA (1 << 31) -#define NV50TCL_QUERY_ADDRESS_HIGH 0x00001b00 -#define NV50TCL_QUERY_ADDRESS_LOW 0x00001b04 -#define NV50TCL_QUERY_SEQUENCE 0x00001b08 -#define NV50TCL_QUERY_GET 0x00001b0c - - -#define NV84TCL 0x00008297 - - - -#define NVA0TCL 0x00008397 - - - -#define NVA8TCL 0x00008597 - - - -#define NV50_COMPUTE 0x000050c0 - -#define NV50_COMPUTE_NOP 0x00000100 -#define NV50_COMPUTE_NOTIFY 0x00000104 -#define NV50_COMPUTE_SERIALIZE 0x00000110 -#define NV50_COMPUTE_DMA_NOTIFY 0x00000180 -#define NV50_COMPUTE_DMA_GLOBAL 0x000001a0 -#define NV50_COMPUTE_DMA_QUERY 0x000001a4 -#define NV50_COMPUTE_DMA_LOCAL 0x000001b8 -#define NV50_COMPUTE_DMA_STACK 0x000001bc -#define NV50_COMPUTE_DMA_CODE_CB 0x000001c0 -#define NV50_COMPUTE_DMA_TSC 0x000001c4 -#define NV50_COMPUTE_DMA_TIC 0x000001c8 -#define NV50_COMPUTE_DMA_TEXTURE 0x000001cc -#define NV50_COMPUTE_CP_ADDRESS_HIGH 0x00000210 -#define NV50_COMPUTE_CP_ADDRESS_LOW 0x00000214 -#define NV50_COMPUTE_STACK_ADDRESS_HIGH 0x00000218 -#define NV50_COMPUTE_STACK_ADDRESS_LOW 0x0000021c -#define NV50_COMPUTE_STACK_SIZE_LOG 0x00000220 -#define NV50_COMPUTE_TSC_ADDRESS_HIGH 0x0000022c -#define NV50_COMPUTE_TSC_ADDRESS_LOW 0x00000230 -#define NV50_COMPUTE_TSC_LIMIT 0x00000234 -#define NV50_COMPUTE_CB_ADDR 0x00000238 -#define NV50_COMPUTE_CB_ADDR_ID_SHIFT 8 -#define NV50_COMPUTE_CB_ADDR_ID_MASK 0x003fff00 -#define NV50_COMPUTE_CB_ADDR_BUFFER_SHIFT 0 -#define NV50_COMPUTE_CB_ADDR_BUFFER_MASK 0x0000007f -#define NV50_COMPUTE_CB_DATA(x) (0x0000023c+((x)*4)) -#define NV50_COMPUTE_CB_DATA__SIZE 0x00000010 -#define NV50_COMPUTE_DELAY1 0x00000284 -#define NV50_COMPUTE_WATCHDOG_TIMER 0x00000288 -#define NV50_COMPUTE_DELAY2 0x0000028c -#define NV50_COMPUTE_LOCAL_ADDRESS_HIGH 0x00000294 -#define NV50_COMPUTE_LOCAL_ADDRESS_LOW 0x00000298 -#define NV50_COMPUTE_LOCAL_SIZE_LOG 0x0000029c -#define NV50_COMPUTE_CB_DEF_ADDRESS_HIGH 0x000002a4 -#define NV50_COMPUTE_CB_DEF_ADDRESS_LOW 0x000002a8 -#define NV50_COMPUTE_CB_DEF_SET 0x000002ac -#define NV50_COMPUTE_CB_DEF_SET_SIZE_SHIFT 0 -#define NV50_COMPUTE_CB_DEF_SET_SIZE_MASK 0x0000ffff -#define NV50_COMPUTE_CB_DEF_SET_BUFFER_SHIFT 16 -#define NV50_COMPUTE_CB_DEF_SET_BUFFER_MASK 0x007f0000 -#define NV50_COMPUTE_BLOCK_ALLOC 0x000002b4 -#define NV50_COMPUTE_BLOCK_ALLOC_THREADS_SHIFT 0 -#define NV50_COMPUTE_BLOCK_ALLOC_THREADS_MASK 0x0000ffff -#define NV50_COMPUTE_BLOCK_ALLOC_BARRIERS_SHIFT 16 -#define NV50_COMPUTE_BLOCK_ALLOC_BARRIERS_MASK 0xffff0000 -#define NV50_COMPUTE_LANES32_ENABLE 0x000002b8 -#define NV50_COMPUTE_CP_REG_ALLOC_TEMP 0x000002c0 -#define NV50_COMPUTE_TIC_ADDRESS_HIGH 0x000002c4 -#define NV50_COMPUTE_TIC_ADDRESS_LOW 0x000002c8 -#define NV50_COMPUTE_TIC_LIMIT 0x000002cc -#define NV50_COMPUTE_PM_SET(x) (0x000002d0+((x)*4)) -#define NV50_COMPUTE_PM_SET__SIZE 0x00000004 -#define NV50_COMPUTE_PM_CONTROL(x) (0x000002e0+((x)*4)) -#define NV50_COMPUTE_PM_CONTROL__SIZE 0x00000004 -#define NV50_COMPUTE_PM_CONTROL_UNK0 (1 << 0) -#define NV50_COMPUTE_PM_CONTROL_UNK1_SHIFT 4 -#define NV50_COMPUTE_PM_CONTROL_UNK1_MASK 0x00000070 -#define NV50_COMPUTE_PM_CONTROL_UNK2_SHIFT 8 -#define NV50_COMPUTE_PM_CONTROL_UNK2_MASK 0xffffff00 -#define NV50_COMPUTE_LOCAL_WARPS_LOG_ALLOC 0x000002fc -#define NV50_COMPUTE_LOCAL_WARPS_NO_CLAMP 0x00000300 -#define NV50_COMPUTE_STACK_WARPS_LOG_ALLOC 0x00000304 -#define NV50_COMPUTE_STACK_WARPS_NO_CLAMP 0x00000308 -#define NV50_COMPUTE_QUERY_ADDRESS_HIGH 0x00000310 -#define NV50_COMPUTE_QUERY_ADDRESS_LOW 0x00000314 -#define NV50_COMPUTE_QUERY_COUNTER 0x00000318 -#define NV50_COMPUTE_QUERY_GET 0x0000031c -#define NV50_COMPUTE_COND_ADDRESS_HIGH 0x00000320 -#define NV50_COMPUTE_COND_ADDRESS_LOW 0x00000324 -#define NV50_COMPUTE_COND_MODE 0x00000328 -#define NV50_COMPUTE_COND_MODE_NEVER 0x00000000 -#define NV50_COMPUTE_COND_MODE_ALWAYS 0x00000001 -#define NV50_COMPUTE_COND_MODE_RES 0x00000002 -#define NV50_COMPUTE_COND_MODE_NOT_RES_AND_NOT_ID 0x00000003 -#define NV50_COMPUTE_COND_MODE_RES_OR_ID 0x00000004 -#define NV50_COMPUTE_LAUNCH 0x00000368 -#define NV50_COMPUTE_USER_PARAM_COUNT 0x00000374 -#define NV50_COMPUTE_USER_PARAM_COUNT_COUNT_SHIFT 8 -#define NV50_COMPUTE_USER_PARAM_COUNT_COUNT_MASK 0x0000ff00 -#define NV50_COMPUTE_LINKED_TSC 0x00000378 -#define NV50_COMPUTE_CODE_CB_FLUSH 0x00000380 -#define NV50_COMPUTE_GRIDDIM 0x000003a4 -#define NV50_COMPUTE_GRIDDIM_X_SHIFT 0 -#define NV50_COMPUTE_GRIDDIM_X_MASK 0x0000ffff -#define NV50_COMPUTE_GRIDDIM_Y_SHIFT 16 -#define NV50_COMPUTE_GRIDDIM_Y_MASK 0xffff0000 -#define NV50_COMPUTE_SHARED_SIZE 0x000003a8 -#define NV50_COMPUTE_BLOCKDIM_YX 0x000003ac -#define NV50_COMPUTE_BLOCKDIM_YX_X_SHIFT 0 -#define NV50_COMPUTE_BLOCKDIM_YX_X_MASK 0x0000ffff -#define NV50_COMPUTE_BLOCKDIM_YX_Y_SHIFT 16 -#define NV50_COMPUTE_BLOCKDIM_YX_Y_MASK 0xffff0000 -#define NV50_COMPUTE_BLOCKDIM_Z 0x000003b0 -#define NV50_COMPUTE_CP_START_ID 0x000003b4 -#define NV50_COMPUTE_REG_MODE 0x000003b8 -#define NV50_COMPUTE_REG_MODE_PACKED 0x00000001 -#define NV50_COMPUTE_REG_MODE_STRIPED 0x00000002 -#define NV50_COMPUTE_TEX_LIMITS 0x000003bc -#define NV50_COMPUTE_TEX_LIMITS_SAMPLERS_LOG2_SHIFT 0 -#define NV50_COMPUTE_TEX_LIMITS_SAMPLERS_LOG2_MASK 0x0000000f -#define NV50_COMPUTE_TEX_LIMITS_TEXTURES_LOG2_SHIFT 4 -#define NV50_COMPUTE_TEX_LIMITS_TEXTURES_LOG2_MASK 0x000000f0 -#define NV50_COMPUTE_BIND_TSC 0x000003c0 -#define NV50_COMPUTE_BIND_TSC_VALID (1 << 0) -#define NV50_COMPUTE_BIND_TSC_SAMPLER_SHIFT 4 -#define NV50_COMPUTE_BIND_TSC_SAMPLER_MASK 0x000000f0 -#define NV50_COMPUTE_BIND_TSC_TSC_SHIFT 12 -#define NV50_COMPUTE_BIND_TSC_TSC_MASK 0x001ff000 -#define NV50_COMPUTE_BIND_TIC 0x000003c4 -#define NV50_COMPUTE_BIND_TIC_VALID (1 << 0) -#define NV50_COMPUTE_BIND_TIC_TEXTURE_SHIFT 1 -#define NV50_COMPUTE_BIND_TIC_TEXTURE_MASK 0x000001fe -#define NV50_COMPUTE_BIND_TIC_TIC_SHIFT 9 -#define NV50_COMPUTE_BIND_TIC_TIC_MASK 0x7ffffe00 -#define NV50_COMPUTE_SET_PROGRAM_CB 0x000003c8 -#define NV50_COMPUTE_SET_PROGRAM_CB_INDEX_SHIFT 8 -#define NV50_COMPUTE_SET_PROGRAM_CB_INDEX_MASK 0x00000f00 -#define NV50_COMPUTE_SET_PROGRAM_CB_BUFFER_SHIFT 12 -#define NV50_COMPUTE_SET_PROGRAM_CB_BUFFER_MASK 0x0007f000 -#define NV50_COMPUTE_SET_PROGRAM_CB_VALID (1 << 0) -#define NV50_COMPUTE_GLOBAL_ADDRESS_HIGH(x) (0x00000400+((x)*32)) -#define NV50_COMPUTE_GLOBAL_ADDRESS_HIGH__SIZE 0x00000010 -#define NV50_COMPUTE_GLOBAL_ADDRESS_LOW(x) (0x00000404+((x)*32)) -#define NV50_COMPUTE_GLOBAL_ADDRESS_LOW__SIZE 0x00000010 -#define NV50_COMPUTE_GLOBAL_PITCH(x) (0x00000408+((x)*32)) -#define NV50_COMPUTE_GLOBAL_PITCH__SIZE 0x00000010 -#define NV50_COMPUTE_GLOBAL_LIMIT(x) (0x0000040c+((x)*32)) -#define NV50_COMPUTE_GLOBAL_LIMIT__SIZE 0x00000010 -#define NV50_COMPUTE_GLOBAL_MODE(x) (0x00000410+((x)*32)) -#define NV50_COMPUTE_GLOBAL_MODE__SIZE 0x00000010 -#define NV50_COMPUTE_GLOBAL_MODE_LINEAR (1 << 0) -#define NV50_COMPUTE_GLOBAL_MODE_TILE_MODE_SHIFT 8 -#define NV50_COMPUTE_GLOBAL_MODE_TILE_MODE_MASK 0x00000f00 -#define NV50_COMPUTE_USER_PARAM(x) (0x00000600+((x)*4)) -#define NV50_COMPUTE_USER_PARAM__SIZE 0x00000040 - - -#endif /* NOUVEAU_REG_H */ 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,297 +23,11 @@ #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" - -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) -{ - 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; -} - -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; - } -} - -static int -nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, - 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; - } -} - -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; - } -} - -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); -} - -#define BGN_RELOC(ch, bo, gr, m, n, fl) \ - OUT_RELOC(ch, bo, (n << 18) | (gr->subc << 13) | m, fl, 0, 0) - -void -nv50_screen_reloc_constbuf(struct nv50_screen *screen, unsigned cbi) -{ - 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); -} - -void -nv50_screen_relocs(struct nv50_screen *screen) -{ - 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; - - MARK_RING (chan, 28, 26); - - /* cause grobj autobind */ - BEGIN_RING(chan, tesla, 0x0100, 1); - OUT_RING (chan, 0); - - 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); - - 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); - - nv50_screen_reloc_constbuf(screen, NV50_CB_PMISC); - - 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); - - for (i = 0; i < 3; ++i) - nv50_screen_reloc_constbuf(screen, NV50_CB_PVP + i); - - 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); - - if (!screen->cur_ctx->req_lmem) - return; - - 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); -} +#include "nouveau/nv_object.xml.h" #ifndef NOUVEAU_GETPARAM_GRAPH_UNITS # define NOUVEAU_GETPARAM_GRAPH_UNITS 13 @@ -322,299 +36,615 @@ nv50_screen_relocs(struct nv50_screen *screen) 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 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 */ + 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: + 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) +{ + 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.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); + + 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); +} + +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)); +} + +static int +nv50_screen_fence_signalled(struct pipe_screen *pscreen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + return !(nv50_fence_signalled(nv50_fence(fence))); +} + +static int +nv50_screen_fence_finish(struct pipe_screen *pscreen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + 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) + struct pipe_screen * nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) { - 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; + 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; - if (!screen) - return NULL; - pscreen = &screen->base.base; + screen = CALLOC_STRUCT(nv50_screen); + 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; + ret = nouveau_screen_init(&screen->base, dev); + if (ret) + FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret); - 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; + chan = screen->base.channel; - nv50_screen_init_resource_functions(pscreen); + 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; - /* 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; - } + nv50_screen_init_resource_functions(pscreen); - /* 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; - } + screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = + NOUVEAU_BO_GART; - /* 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_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_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; - } + ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); + if (ret) + FAIL_SCREEN_INIT("Error allocating notifier: %d\n", ret); - /* this is necessary for the new RING_3D / statebuffer code */ - BIND_RING(chan, screen->tesla, 7); + ret = nouveau_grobj_alloc(chan, 0xbeef5039, NV50_M2MF, &screen->m2mf); + if (ret) + FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret); - /* 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; - } + 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); - /* 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); + ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d); + if (ret) + FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret); - /* 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); + 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); - /* 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); + 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; + } - BEGIN_RING(chan, screen->tesla, NV50TCL_RT_CONTROL, 1); - OUT_RING (chan, 1); + ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla); + if (ret) + FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret); - /* 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); + BIND_RING (chan, screen->tesla, NV50_SUBCH_3D); - /* 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); - } + BEGIN_RING(chan, RING_3D(COND_MODE), 1); + OUT_RING (chan, NV50_3D_COND_MODE_ALWAYS); - /* 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, 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, screen->tesla, NV50TCL_CLEAR_FLAGS, 1); - OUT_RING (chan, NV50TCL_CLEAR_FLAGS_D3D); + 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); - /* 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); + BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); + OUT_RING (chan, 1); - 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); - } + 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); - if (nouveau_resource_init(&screen->immd_heap, 0, 128)) { - NOUVEAU_ERR("Error initialising shader immediates heap.\n"); - nv50_screen_destroy(pscreen); - return NULL; - } + 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, 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, 1 << 16, 3 << 16, &screen->code); + if (ret) + goto fail; - 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 */ + 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); - /* 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)); + 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); - /* shader stack */ - nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); + 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); - max_warps = util_bitcount(value & 0xffff); - max_warps *= util_bitcount((value >> 24) & 0xf) * 32; + 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); - stack_size = max_warps * 64 * 8; + nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); - 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); + max_warps = util_bitcount(value & 0xffff); + max_warps *= util_bitcount((value >> 24) & 0xf) * 32; - local_size = (NV50_CAP_MAX_PROGRAM_TEMPS * 16) * max_warps * 32; + stack_size = max_warps * 64 * 8; - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, - local_size, &screen->local_bo); - if (ret) { - nv50_screen_destroy(pscreen); - return NULL; - } + 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); - local_size = NV50_CAP_MAX_PROGRAM_TEMPS * 16; + 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); - 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)); + tls_space = NV50_CAP_MAX_PROGRAM_TEMPS * 16; - /* 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); - } + screen->tls_size = tls_space * max_warps * 32; - BEGIN_RING(chan, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2); - OUT_RINGf (chan, 0.0f); - OUT_RINGf (chan, 1.0f); + debug_printf("max_warps = %i, tls_size = %lu KiB\n", + max_warps, screen->tls_size >> 10); - BEGIN_RING(chan, screen->tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); - OUT_RING (chan, 1); + 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); - /* 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, 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)); - BEGIN_RING(chan, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1); - OUT_RING (chan, 1); /* default edgeflag to TRUE */ + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, + &screen->uniforms); + if (ret) + goto fail; - FIRE_RING (chan); + 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); - 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; + 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 + + BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1); + OUT_RING (chan, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT); + + /* 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); + + 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); + + FIRE_RING (chan); + + screen->tic.entries = CALLOC(4096, sizeof(void *)); + screen->tsc.entries = screen->tic.entries + 2048; + + 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); + + nv50_screen_fence_new(screen, &screen->fence.current, FALSE); + + return pscreen; + +fail: + nv50_screen_destroy(pscreen); + return NULL; } +void +nv50_screen_make_buffers_resident(struct nv50_screen *screen) +{ + struct nouveau_channel *chan = screen->base.channel; + + const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; + + 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) +{ + 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 nouveau_winsys *nvws; + struct nv50_context *cur_ctx; - 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; - struct nouveau_grobj *tesla; - struct nouveau_grobj *eng2d; - struct nouveau_grobj *m2mf; - struct nouveau_notifier *sync; + uint64_t tls_size; - struct nouveau_bo *constbuf_misc[1]; - struct nouveau_bo *constbuf_parm[PIPE_SHADER_TYPES]; + struct nouveau_resource *vp_code_heap; + struct nouveau_resource *gp_code_heap; + struct nouveau_resource *fp_code_heap; - struct nouveau_resource *immd_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 nouveau_bo *tic; - struct nouveau_bo *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_bo *stack_bo; /* control flow stack */ - struct nouveau_bo *local_bo; /* l[] memory */ + struct nouveau_notifier *sync; - boolean force_push; + 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; }; static INLINE struct nv50_screen * nv50_screen(struct pipe_screen *screen) { - return (struct nv50_screen *)screen; + return (struct nv50_screen *)screen; } -extern void nv50_screen_relocs(struct nv50_screen *); +/* 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; +}; -extern void nv50_screen_reloc_constbuf(struct nv50_screen *, unsigned cbi); +static INLINE void +nv50_fence_sched_release(struct nv50_fence *nf, struct nv50_mm_allocation *mm) +{ + mm->next = nf->buffers; + nf->buffers = mm; +} + +extern struct nv50_mman * +nv50_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type); + +extern void +nv50_mm_destroy(struct nv50_mman *); + +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 *); + +void nv50_screen_make_buffers_resident(struct nv50_screen *); + +int nv50_screen_tic_alloc(struct nv50_screen *, void *); +int nv50_screen_tsc_alloc(struct nv50_screen *, void *); + +static INLINE void +nv50_resource_fence(struct nv50_resource *res, uint32_t flags) +{ + 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); + } +} + +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); + } +} + + +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) -{ - 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; - - if (buf == NULL) - return; - - map = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &transfer); - if (!map) - return; - - count = (buf->width0 + 3) / 4; - start = 0; - - while (count) { - unsigned nr = AVAIL_RING(chan); - - 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); - - 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); - - count -= nr; - start += nr; - map += nr; - } - - pipe_buffer_unmap(pipe, transfer); -} - -static void -nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) +void +nv50_constbufs_validate(struct nv50_context *nv50) { struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - unsigned cbi; + unsigned s; - if (p->immd_size) { - uint32_t *data = p->immd; - unsigned count = p->immd_size / 4; - unsigned start = 0; + for (s = 0; s < 3; ++s) { + struct nv50_resource *res; + int i; + unsigned p, b; - while (count) { - unsigned nr = AVAIL_RING(chan); + 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; - if (nr < 8) { - FIRE_RING(chan); + 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; } - nr = MIN2(count, nr - 7); - nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN); - nv50_screen_reloc_constbuf(nv50->screen, NV50_CB_PMISC); + if (i == 0) { + b = NV50_CB_PVP + s; - 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); + /* always upload GL uniforms through CB DATA */ + bo = nv50->screen->uniforms; + words = res->base.width0 / 4; + } else { + b = s * 16 + i; - count -= nr; - start += nr; - data += nr; + assert(0); + + if (!nv50_resource_mapped_by_gpu(&res->base)) { + nv50_buffer_migrate(nv50, res, NOUVEAU_BO_VRAM); + + 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); + + bo = res->bo; + + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_CONSTANT, res, + res->domain | NOUVEAU_BO_RD); + } + + if (words) { + MARK_RING(chan, 8, 1); + + nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR); + } + + while (words) { + unsigned nr = AVAIL_RING(chan); + + 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); + + 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); + + start += nr; + words -= 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; - } - - 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) -{ - struct nouveau_channel *chan = nv50->screen->base.channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_grobj *eng2d = nv50->screen->eng2d; - int ret; - unsigned offset; - unsigned size = p->code_size; - uint32_t *data = p->code; - - assert(p->translated); - - /* 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; - } - - BEGIN_RING(chan, tesla, NV50TCL_CODE_CB_FLUSH, 1); - OUT_RING (chan, 0); -} - -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); -} - -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); -} - -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); } static boolean -nv50_program_validate(struct nv50_program *p) +nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) { - p->translated = nv50_program_tx(p); - assert(p->translated); - return p->translated; -} + struct nouveau_resource *heap; + int ret; + unsigned size; -static INLINE void -nv50_program_validate_common(struct nv50_context *nv50, struct nv50_program *p) -{ - nv50_program_validate_code(nv50, p); + if (prog->translated) + return TRUE; - if (p->uses_lmem) - nv50->req_lmem |= 1 << p->type; + prog->translated = nv50_program_translate(prog); + if (!prog->translated) + return FALSE; + + 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 - nv50->req_lmem &= ~(1 << p->type); + heap = nv50->screen->vp_code_heap; + + size = align(prog->code_size, 0x100); + + ret = nouveau_resource_alloc(heap, size, prog, &prog->res); + if (ret) + return FALSE; + prog->code_base = prog->res->start; + + nv50_sifc_linear_u8(nv50, nv50->screen->code, NOUVEAU_BO_VRAM, + (prog->type << 16) + prog->code_base, prog->code_size, + prog->code); + + BEGIN_RING(nv50->screen->base.channel, RING_3D(CODE_CB_FLUSH), 1); + OUT_RING (nv50->screen->base.channel, 0); + + return TRUE; } -struct nouveau_stateobj * +void nv50_vertprog_validate(struct nv50_context *nv50) { - struct nv50_program *p = nv50->vertprog; - struct nouveau_stateobj *so = NULL; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_program *vp = nv50->vertprog; - if (!p->translated) { - if (nv50_program_validate(p)) - nv50_vp_update_stateobj(nv50, p); - else - return NULL; - } + if (!nv50_program_validate(nv50, vp)) + return; - 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); - - so_ref(p->so, &so); - return so; + 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; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_program *fp = nv50->fragprog; - if (!p->translated) { - if (nv50_program_validate(p)) - nv50_fp_update_stateobj(nv50, p); - else - return NULL; - } + if (!nv50_program_validate(nv50, fp)) + return; - 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); - - so_ref(p->so, &so); - return so; + 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; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nv50_program *gp = nv50->vertprog; - /* GP may be NULL, but VP and FP may not */ - if (!p) - return NULL; /* GP is deactivated in linkage validation */ + if (!nv50_program_validate(nv50, gp)) + return; - 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; + 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; } + if (!(nv50->rast->pipe.sprite_coord_enable & (1 << fp->in[i].si))) { + 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; + for (c = 0; c < 4; ++c) { + if (fp->in[i].mask & (1 << c)) { + pntc[m / 8] |= (c + 1) << ((m % 8) * 4); + ++m; } } - - /* 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; - } } - 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); + n = (m + 3) / 4; - so_method(so, tesla, NV50TCL_VP_GP_BUILTIN_ATTR_EN, 1); - so_data (so, vp->vp.attrs[2] | gp->vp.attrs[2]); + BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1); + OUT_RING (chan, 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); - - m = (m + 3) / 4; - so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), m); - so_datap (so, map, m); - - 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) +nv50_blend_fac(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; - } + 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) + 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; + struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj); + int i; + boolean blend_enabled = cso->rt[0].blend_enable; - /*XXX ignored: - * - dither - */ + so->pipe = *cso; - 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)); - } + 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 (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)); - } + 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)); + } - 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); - } + 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); + } - bso->pipe = *cso; - so_ref(so, &bso->so); - so_ref(NULL, &so); - return (void *)bso; + 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) -{ - struct nv50_context *nv50 = nv50_context(pipe); - - memcpy(nv50->sampler[type], sampler, nr * sizeof(void *)); - - nv50->sampler_nr[type] = nr; - nv50->dirty |= NV50_NEW_SAMPLER; -} - -static void -nv50_vp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s) -{ - nv50_sampler_state_bind(pipe, 0, nr, s); -} - -static void -nv50_fp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s) -{ - nv50_sampler_state_bind(pipe, 2, nr, s); -} - -static void -nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso) -{ - FREE(hwcso); -} - -static INLINE void -nv50_set_sampler_views(struct pipe_context *pipe, unsigned p, - unsigned nr, - struct pipe_sampler_view **views) -{ - struct nv50_context *nv50 = nv50_context(pipe); - unsigned i; - - for (i = 0; i < nr; i++) - pipe_sampler_view_reference(&nv50->sampler_views[p][i], - views[i]); - - for (i = nr; i < nv50->sampler_view_nr[p]; i++) - pipe_sampler_view_reference(&nv50->sampler_views[p][i], NULL); - - nv50->sampler_view_nr[p] = nr; - nv50->dirty |= NV50_NEW_TEXTURE; -} - -static void -nv50_set_vp_sampler_views(struct pipe_context *pipe, - unsigned nr, - struct pipe_sampler_view **views) -{ - nv50_set_sampler_views(pipe, 0, nr, views); -} - -static void -nv50_set_fp_sampler_views(struct pipe_context *pipe, - unsigned nr, - struct pipe_sampler_view **views) -{ - nv50_set_sampler_views(pipe, 2, nr, views); -} - -static void -nv50_sampler_view_destroy(struct pipe_context *pipe, - struct pipe_sampler_view *view) -{ - pipe_resource_reference(&view->texture, NULL); - FREE(nv50_sampler_view(view)); -} - -static struct pipe_sampler_view * -nv50_create_sampler_view(struct pipe_context *pipe, - struct pipe_resource *texture, - const struct pipe_sampler_view *templ) -{ - struct nv50_sampler_view *view = CALLOC_STRUCT(nv50_sampler_view); - - view->pipe = *templ; - view->pipe.reference.count = 1; - view->pipe.texture = NULL; - pipe_resource_reference(&view->pipe.texture, texture); - view->pipe.context = pipe; - - if (!nv50_tex_construct(view)) { - nv50_sampler_view_destroy(pipe, &view->pipe); - return NULL; - } - return &view->pipe; -} - - static void * nv50_rasterizer_state_create(struct pipe_context *pipe, - const struct pipe_rasterizer_state *cso) + 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); + struct nv50_rasterizer_stateobj *so; - /*XXX: ignored - * - light_twoside - * - point_smooth - * - multisample - * - point_sprite / sprite_coord_mode - */ + so = CALLOC_STRUCT(nv50_rasterizer_stateobj); + if (!so) + return NULL; + so->pipe = *cso; - so_method(so, tesla, NV50TCL_SCISSOR_ENABLE(0), 1); - so_data (so, cso->scissor); +#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); - 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); + 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); - so_method(so, tesla, NV50TCL_VERTEX_TWO_SIDE_ENABLE, 1); - so_data (so, cso->light_twoside); + 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); + } - 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); - } + 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); - so_method(so, tesla, NV50TCL_POINT_SIZE, 1); - so_data (so, fui(cso->point_size)); + 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); - so_method(so, tesla, NV50TCL_POINT_SPRITE_ENABLE, 1); - so_data (so, cso->point_quad_rasterization ? 1 : 0); + 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; + } - 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); + 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); - 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; - } + 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 ? */ + } - 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; + 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); - nv50->rasterizer = hwcso; - nv50->dirty |= NV50_NEW_RASTERIZER; + nv50->rast = hwcso; + nv50->dirty |= NV50_NEW_RASTERIZER; } static void nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nv50_rasterizer_stateobj *rso = hwcso; - - so_ref(NULL, &rso->so); - FREE(rso); + FREE(hwcso); } static void * -nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *cso) +nv50_zsa_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); + struct nv50_zsa_stateobj *so = CALLOC_STRUCT(nv50_zsa_stateobj); - 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); - } + so->pipe = *cso; - 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); - } + 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[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->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->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); - } + 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); + } - zsa->pipe = *cso; - so_ref(so, &zsa->so); - so_ref(NULL, &so); - return (void *)zsa; + assert(so->size < (sizeof(so->state) / sizeof(so->state[0]))); + return (void *)so; } static void -nv50_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +nv50_zsa_state_bind(struct pipe_context *pipe, void *hwcso) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->zsa = hwcso; - nv50->dirty |= NV50_NEW_ZSA; + nv50->zsa = hwcso; + nv50->dirty |= NV50_NEW_ZSA; } static void -nv50_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +nv50_zsa_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nv50_zsa_stateobj *zsa = hwcso; + FREE(hwcso); +} - so_ref(NULL, &zsa->so); - FREE(zsa); +/* ====================== 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) +{ + 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_stage_sampler_states_bind(struct nv50_context *nv50, int s, + unsigned nr, void **hwcso) +{ + unsigned i; + + for (i = 0; i < nr; ++i) { + struct nv50_tsc_entry *old = nv50->samplers[s][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]); + + nv50->num_samplers[s] = nr; + + nv50->dirty |= NV50_NEW_SAMPLERS; +} + +static void +nv50_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) +{ + nv50_stage_sampler_states_bind(nv50_context(pipe), 0, nr, s); +} + +static void +nv50_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) +{ + nv50_stage_sampler_states_bind(nv50_context(pipe), 2, nr, s); +} + +static void +nv50_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) +{ + nv50_stage_sampler_states_bind(nv50_context(pipe), 1, nr, s); +} + +/* 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) +{ + pipe_resource_reference(&view->texture, NULL); + + nv50_screen_tic_free(nv50_context(pipe)->screen, nv50_tic_entry(view)); + + 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); + + 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_vp_set_sampler_views(struct pipe_context *pipe, + unsigned nr, + struct pipe_sampler_view **views) +{ + nv50_stage_set_sampler_views(nv50_context(pipe), 0, nr, views); +} + +static void +nv50_fp_set_sampler_views(struct pipe_context *pipe, + unsigned nr, + struct pipe_sampler_view **views) +{ + nv50_stage_set_sampler_views(nv50_context(pipe), 2, nr, views); +} + +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); +} + +/* ============================= SHADERS ======================================= + */ + +static void * +nv50_sp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso, unsigned type) +{ + struct nv50_program *prog; + + 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_sp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv50_program *prog = (struct nv50_program *)hwcso; + + nv50_program_destroy(nv50_context(pipe), prog); + + 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); + 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; - - 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; -} - -static void -nv50_gp_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); -} - -static void -nv50_set_blend_color(struct pipe_context *pipe, - const struct pipe_blend_color *bcol) -{ - struct nv50_context *nv50 = nv50_context(pipe); - - nv50->blend_colour = *bcol; - nv50->dirty |= NV50_NEW_BLEND_COLOUR; -} - - static void -nv50_set_stencil_ref(struct pipe_context *pipe, - const struct pipe_stencil_ref *sr) -{ - struct nv50_context *nv50 = nv50_context(pipe); - - 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) -{ - struct nv50_context *nv50 = nv50_context(pipe); - - nv50->clip.depth_clamp = clip->depth_clamp; - nv50->dirty |= NV50_NEW_CLIP; -} - -static void -nv50_set_sample_mask(struct pipe_context *pipe, - unsigned sample_mask) -{ + nv50->gmtyprog = hwcso; + nv50->dirty |= NV50_NEW_GMTYPROG; } static void nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_resource *buf ) + struct pipe_resource *res) { - struct nv50_context *nv50 = nv50_context(pipe); + 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; - } + 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], buf); + pipe_resource_reference(&nv50->constbuf[shader][index], res); + + 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) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->blend_colour = *bcol; + nv50->dirty |= NV50_NEW_BLEND_COLOUR; } static void -nv50_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) +nv50_set_stencil_ref(struct pipe_context *pipe, + const struct pipe_stencil_ref *sr) { - struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_context *nv50 = nv50_context(pipe); - nv50->framebuffer = *fb; - nv50->dirty |= NV50_NEW_FRAMEBUFFER; + 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) +{ + struct nv50_context *nv50 = nv50_context(pipe); + const unsigned size = clip->nr * sizeof(clip->ucp[0]); + + memcpy(&nv50->clip.ucp[0][0], &clip->ucp[0][0], size); + nv50->clip.nr = clip->nr; + + nv50->clip.depth_clamp = clip->depth_clamp; + + nv50->dirty |= NV50_NEW_CLIP; +} + +static void +nv50_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + 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) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + 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; + + nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX); + + nv50->dirty |= NV50_NEW_ARRAYS; } static void nv50_set_index_buffer(struct pipe_context *pipe, - const struct pipe_index_buffer *ib) + const struct pipe_index_buffer *ib) { - struct nv50_context *nv50 = nv50_context(pipe); + 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_vtxelt_construct(cso); - - return (void *)cso; + if (ib) + memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf)); + else + nv50->idxbuf.buffer = NULL; } static void -nv50_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso) +nv50_vertex_state_bind(struct pipe_context *pipe, void *hwcso) { - FREE(hwcso); -} + struct nv50_context *nv50 = nv50_context(pipe); -static void -nv50_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso) -{ - 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_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_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_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_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_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_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.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.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_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.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_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.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; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct pipe_framebuffer_state *fb = &nv50->framebuffer; + unsigned i; - /* 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)); + nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME); - 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; + 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); - 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); - } + MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs); - assert(nv50_format_table[fb->cbufs[i]->format].rt); + 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; - so_method(so, tesla, NV50TCL_RT_HORIZ(i), 2); - so_data (so, fb->cbufs[i]->width); - so_data (so, fb->cbufs[i]->height); + 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); - 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); + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + } - so_method(so, tesla, NV50TCL_RT_ARRAY_MODE, 1); - so_data (so, 1); - } + 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; - if (fb->zsbuf) { - struct pipe_resource *pt = fb->zsbuf->texture; - struct nouveau_bo *bo = nv50_miptree(pt)->base.bo; + 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); - if (!gw) { - w = fb->zsbuf->width; - h = fb->zsbuf->height; - gw = 1; - } else { - assert(w == fb->zsbuf->width); - assert(h == fb->zsbuf->height); - } + 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); + } - 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; + 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; + struct nouveau_channel *chan = nv50->screen->base.channel; - 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 */ - } - } + 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_blend(struct nv50_context *nv50) +static void +nv50_validate_stencil_ref(struct nv50_context *nv50) { - struct nouveau_stateobj *so = NULL; - so_ref(nv50->blend->so, &so); - return so; + struct nouveau_channel *chan = nv50->screen->base.channel; + + 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_zsa(struct nv50_context *nv50) +static void +nv50_validate_stipple(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; + unsigned i; + + 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_rast(struct nv50_context *nv50) +static void +nv50_validate_scissor(struct nv50_context *nv50) { - struct nouveau_stateobj *so = NULL; - so_ref(nv50->rasterizer->so, &so); - 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_blend_colour(struct nv50_context *nv50) +static void +nv50_validate_viewport(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(1, 4, 0); + struct nouveau_channel *chan = nv50->screen->base.channel; + float zmin, zmax; - 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; + 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_stencil_ref(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(2, 2, 0); + struct nouveau_channel *chan = nv50->screen->base.channel; + uint32_t clip; - 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; + 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_stipple(struct nv50_context *nv50) +static void +nv50_validate_blend(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so = so_new(1, 32, 0); - int i; + struct nouveau_channel *chan = nv50->screen->base.channel; - 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; + WAIT_RING(chan, nv50->blend->size); + OUT_RINGp(chan, nv50->blend->state, nv50->blend->size); } -static struct nouveau_stateobj * -validate_scissor(struct nv50_context *nv50) +static void +nv50_validate_zsa(struct nv50_context *nv50) { - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct pipe_scissor_state *s = &nv50->scissor; - struct nouveau_stateobj *so; + struct nouveau_channel *chan = nv50->screen->base.channel; - 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; + WAIT_RING(chan, nv50->zsa->size); + OUT_RINGp(chan, nv50->zsa->state, nv50->zsa->size); } -static struct nouveau_stateobj * -validate_viewport(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(3, 7, 0); + struct nouveau_channel *chan = nv50->screen->base.channel; - 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; + WAIT_RING(chan, nv50->rast->size); + OUT_RINGp(chan, nv50->rast->state, nv50->rast->size); } -static struct nouveau_stateobj * -validate_sampler(struct nv50_context *nv50) -{ - struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *so; - unsigned nr = 0, i; - - 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; -} - -static struct nouveau_stateobj * -validate_vtxbuf(struct nv50_context *nv50) -{ - struct nouveau_stateobj *so = NULL; - so_ref(nv50->state.vtxbuf, &so); - return so; -} - -static struct nouveau_stateobj * -validate_vtxattr(struct nv50_context *nv50) -{ - struct nouveau_stateobj *so = NULL; - so_ref(nv50->state.vtxattr, &so); - return so; -} - -static struct nouveau_stateobj * -validate_clip(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); - - return so; -} - -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) +nv50_state_validate(struct nv50_context *nv50) { - 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; + unsigned i; +#if 0 + if (nv50->screen->cur_ctx != nv50) /* FIXME: not everything is valid */ + nv50->dirty = 0xffffffff; +#endif + nv50->screen->cur_ctx = nv50; - for (i = 0; i < validate_list_len; i++) { - struct state_validate *validate = &validate_list[i]; - struct nouveau_stateobj *so; + if (nv50->dirty) { + for (i = 0; i < validate_list_len; ++i) { + struct state_validate *validate = &validate_list[i]; - if (!(nv50->dirty & validate->states)) - continue; + if (nv50->dirty & validate->states) + validate->func(nv50); + } + nv50->dirty = 0; + } - so = validate->func(nv50); - if (!so) - continue; + nv50_bufctx_emit_relocs(nv50); - 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) -{ - 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); + 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 -#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; + 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; + /* 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; - } + 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); + 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(ps->format); - if (!format) { - NOUVEAU_ERR("invalid/unsupported surface format: %s\n", - util_format_name(ps->format)); - return 1; - } + 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 (!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); - } - #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; + int ret; - ret = MARK_RING(chan, 2*16 + 32, 4); - if (ret) - return 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_2d_texture_set(chan, 1, dst, dst_level, dz); + if (ret) + return ret; - ret = nv50_surface_set(screen, src, 0); - if (ret) - return ret; + ret = nv50_2d_texture_set(chan, 0, src, src_level, sz); + 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); + /* 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; + 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; + 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))); - 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); + 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; + 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, 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]); + 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; + 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); + 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) */ + /* 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, RING_3D(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); + BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); + OUT_RING (chan, 0x3c); - nv50->dirty |= NV50_NEW_FRAMEBUFFER; + 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 nouveau_grobj *tesla = screen->tesla; - struct nv50_miptree *mt = nv50_miptree(dst->texture); - struct nouveau_bo *bo = mt->base.bo; - uint32_t mode = 0; + 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, tesla, NV50TCL_CLEAR_DEPTH, 1); - OUT_RINGf (chan, depth); - mode |= NV50TCL_CLEAR_BUFFERS_Z; - } + 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, tesla, NV50TCL_CLEAR_STENCIL, 1); - OUT_RING (chan, stencil & 0xff); - mode |= NV50TCL_CLEAR_BUFFERS_S; - } + 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; + 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, 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, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2); - OUT_RING (chan, (width << 16) | dstx); - OUT_RING (chan, (height << 16) | dsty); + BEGIN_RING(chan, RING_3D(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); + BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); + OUT_RING (chan, mode); - nv50->dirty |= NV50_NEW_FRAMEBUFFER; + 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 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; + 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); - tic[0] = nv50_format_table[view->pipe.format].tic; + view = MALLOC_STRUCT(nv50_tic_entry); + if (!view) + return NULL; - 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); + view->pipe = *templ; + view->pipe.reference.count = 1; + view->pipe.texture = NULL; + view->pipe.context = pipe; - tic[2] = 0x50001000; - tic[2] |= ((mt->base.bo->tile_mode & 0x0f) << 22) | - ((mt->base.bo->tile_mode & 0xf0) << 21); + view->id = -1; - desc = util_format_description(mt->base.base.format); - if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) - tic[2] |= NV50TIC_0_2_COLORSPACE_SRGB; + pipe_resource_reference(&view->pipe.texture, texture); - 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 = &view->tic[0]; - tic[3] = 0x00300000; + desc = util_format_description(mt->base.base.format); - 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[0] */ - tic[6] = 0x03000000; + tic[0] = nv50_format_table[view->pipe.format].tic; - tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level; + 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); - return TRUE; + /* 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; + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_bo *txc = nv50->screen->txc; + unsigned i; + boolean need_flush = FALSE; - 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; + 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; - nv50_so_init_sifc(nv50, so, nv50->screen->tic, NOUVEAU_BO_VRAM, - p * (32 * 8 * 4), nv50->sampler_view_nr[p] * 8 * 4); + 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; - for (unit = 0; unit < nv50->sampler_view_nr[p]; ++unit) { - struct nv50_sampler_view *view = - nv50_sampler_view(nv50->sampler_views[p][unit]); + if (tic->id < 0) { + tic->id = nv50_screen_tic_alloc(nv50->screen, tic); - 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); + 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); - tic2 &= ~NV50TIC_0_2_NORMALIZED_COORDS; - if (nv50->sampler[p][unit]->normalized) - tic2 |= NV50TIC_0_2_NORMALIZED_COORDS; - view->tic[2] = tic2; + need_flush = TRUE; + } + nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); - 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); + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_TEXTURES, res, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - /* 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); - } - } + 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]; - 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; + 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; + boolean need_flush; - 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; + need_flush = nv50_validate_tic(nv50, 0); + need_flush |= nv50_validate_tic(nv50, 2); - 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]); - } + 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; + boolean need_flush; - 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; + need_flush = nv50_validate_tsc(nv50, 0); + need_flush |= nv50_validate_tsc(nv50, 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; + 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 (ahuillet) +- Ben Skeggs (darktama, darktama_) +- B. R. (koala_br) +- Carlos Martin (carlosmn) +- Christoph Bumiller (calim, chrisbmr) +- Dawid Gajownik (gajownik) +- Dmitry Baryshkov +- Dmitry Eremin-Solenikov (lumag) +- EdB (edb_) +- Erik Waling (erikwaling) +- Francisco Jerez (curro, curro_, currojerez) +- imirkin (imirkin) +- jb17bsome (jb17bsome) +- Jeremy Kolb (kjeremy) +- Laurent Carlier (lordheavy) +- Luca Barbieri (lb, lb1) +- Maarten Maathuis (stillunknown) +- Marcin Koƛcielnicki (mwk, koriakin) +- Mark Carey (careym) +- Matthieu Castet (mat-c) +- nvidiaman (nvidiaman) +- Patrice Mandin (pmandin, pmdata) +- Pekka Paalanen (pq, ppaalanen) +- Peter Popov (ironpeter) +- Richard Hughes (hughsient) +- Rudi Cilibrasi (cilibrar) +- Serge Martin +- Simon Raffeiner +- Stephane Loeuillet (leroutier) +- Stephane Marchesin (marcheu) +- sturmflut (sturmflut) +- Sylvain Munaut +- Victor Stinner (haypo) +- Wladmir van der Laan (miathan6) +- Younes Manton (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; + 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; - src_reloc |= NOUVEAU_BO_RD; - dst_reloc |= NOUVEAU_BO_WR; + assert(dst->cpp == src->cpp); - WAIT_RING (chan, 14); + 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; - 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 */ - } + 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, 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 */ - } + 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; - while (height) { - int line_count = height > 2047 ? 2047 : height; + 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); + } - 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); + while (height) { + int line_count = height > 2047 ? 2047 : height; - height -= line_count; - sy += line_count; - dy += line_count; - } + 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; + } +} + +void +nv50_sifc_linear_u8(struct nv50_context *nv50, + struct nouveau_bo *dst, unsigned domain, int offset, + unsigned size, void *data) +{ + 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_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 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; + } } struct pipe_transfer * -nv50_miptree_transfer_new(struct pipe_context *pcontext, - struct pipe_resource *pt, - unsigned level, - unsigned usage, - const struct pipe_box *box) +nv50_miptree_transfer_new(struct pipe_context *pctx, + struct pipe_resource *res, + unsigned level, + unsigned usage, + const struct pipe_box *box) { - 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; + 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; - /* 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; + 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; + 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, res); + tx->base.level = level; + tx->base.usage = usage; + tx->base.box = *box; - 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->nblocksx = util_format_get_nblocksx(res->format, box->width); + tx->nblocksy = util_format_get_nblocksy(res->format, box->height); - 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; - } + tx->base.stride = tx->nblocksx * util_format_get_blocksize(res->format); + tx->base.layer_stride = tx->nblocksy * tx->base.stride; - if (usage & PIPE_TRANSFER_READ) { - nx = util_format_get_nblocksx(pt->format, box->width); - ny = util_format_get_nblocksy(pt->format, box->height); + w = u_minify(res->width0, level); + h = u_minify(res->height0, level); - 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); - } + tx->rect[0].cpp = tx->rect[1].cpp = util_format_get_blocksize(res->format); - return &tx->base; + 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_del(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; - struct nv50_miptree *mt = nv50_miptree(ptx->resource); - struct pipe_resource *pt = ptx->resource; + 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; - 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 (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; + } + } - if (ptx->usage & PIPE_TRANSFER_WRITE) { - struct pipe_screen *pscreen = pcontext->screen; + nouveau_bo_ref(NULL, &tx->rect[1].bo); + pipe_resource_reference(&transfer->resource, NULL); - 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); + FREE(tx); } void * -nv50_miptree_transfer_map(struct pipe_context *pcontext, - struct pipe_transfer *ptx) +nv50_miptree_transfer_map(struct pipe_context *pctx, + struct pipe_transfer *transfer) { - struct nv50_transfer *tx = (struct nv50_transfer *)ptx; - unsigned flags = 0; - int ret; + struct nv50_transfer *tx = (struct nv50_transfer *)transfer; + int ret; + unsigned flags = 0; - if (tx->map_refcnt++) - return tx->bo->map; + if (tx->rect[1].bo->map) + return tx->rect[1].bo->map; - if (ptx->usage & PIPE_TRANSFER_WRITE) - flags |= NOUVEAU_BO_WR; - if (ptx->usage & PIPE_TRANSFER_READ) - flags |= NOUVEAU_BO_RD; + 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->bo, flags); - if (ret) { - tx->map_refcnt = 0; - return NULL; - } - return tx->bo->map; + ret = nouveau_bo_map(tx->rect[1].bo, flags); + if (ret) + return NULL; + return tx->rect[1].bo->map; } void -nv50_miptree_transfer_unmap(struct pipe_context *pcontext, - struct pipe_transfer *ptx) +nv50_miptree_transfer_unmap(struct pipe_context *pctx, + struct pipe_transfer *transfer) { - struct nv50_transfer *tx = (struct nv50_transfer *)ptx; + struct nv50_transfer *tx = (struct nv50_transfer *)transfer; - if (--tx->map_refcnt) - return; - nouveau_bo_unmap(tx->bo); + nouveau_bo_unmap(tx->rect[1].bo); } - -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 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; - } -} 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" + +void +nv50_vertex_state_delete(struct pipe_context *pipe, + void *hwcso) +{ + struct nv50_vertex_stateobj *so = hwcso; + + if (so->translate) + so->translate->release(so->translate); + FREE(hwcso); +} + +void * +nv50_vertex_state_create(struct pipe_context *pipe, + unsigned num_elements, + const struct pipe_vertex_element *elements) +{ + 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 -instance_init(struct nv50_context *nv50, struct instance *a, unsigned first) +nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb, + struct pipe_vertex_element *ve, unsigned attr) { - int i; + 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); - for (i = 0; i < nv50->vtxelt->num_elements; i++) { - struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i]; - struct pipe_vertex_buffer *vb; + data = nv50_resource_map_offset(nv50, res, vb->buffer_offset + + ve->src_offset, NOUVEAU_BO_RD); - a[i].divisor = ve->instance_divisor; - if (a[i].divisor) { - vb = &nv50->vtxbuf[ve->vertex_buffer_index]; + util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1); - 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); - } - } + 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; + } +} + +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 -instance_step(struct nv50_context *nv50, struct instance *a) +nv50_prevalidate_vbufs(struct nv50_context *nv50) { - struct nouveau_channel *chan = nv50->screen->tesla->channel; - struct nouveau_grobj *tesla = nv50->screen->tesla; - int i; + struct pipe_vertex_buffer *vb; + struct nv50_resource *buf; + int i; + uint32_t base, size; - for (i = 0; i < nv50->vtxelt->num_elements; i++) { - if (!a[i].divisor) - continue; + nv50->vbo_fifo = nv50->vbo_user = 0; - 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; - } - } + 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 -nv50_draw_arrays_instanced(struct pipe_context *pipe, - unsigned mode, unsigned start, unsigned count, - unsigned startInstance, unsigned instanceCount) +nv50_update_user_vbufs(struct nv50_context *nv50) { - 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); + struct nouveau_channel *chan = nv50->screen->base.channel; + uint32_t base, offset, size; + int i; + uint32_t written = 0; - instance_init(nv50, a, startInstance); - if (!nv50_state_validate(nv50, 10 + 16*3)) - return; + 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_fifo) { - nv50_push_elements_instanced(pipe, NULL, 0, 0, mode, start, - count, startInstance, - instanceCount); - return; - } + if (!(nv50->vbo_user & (1 << b))) + continue; - 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); + if (!vb->stride) { + nv50_emit_vtxattr(nv50, vb, ve, i); + continue; + } + nv50_vbuf_range(nv50, b, &base, &size); - 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); + if (!(written & (1 << b))) { + written |= 1 << b; + nv50_user_buffer_upload(buf, base, size); + } + offset = vb->buffer_offset + ve->src_offset; - prim |= (1 << 28); - } + 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; } -struct inline_ctx { - struct nv50_context *nv50; - void *map; -}; - -static void -inline_elt08(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; - uint8_t *map = (uint8_t *)ctx->map + start; + uint32_t vbo_user = nv50->vbo_user; - if (count & 1) { - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1); - OUT_RING (chan, map[0]); - map++; - count &= ~1; - } + while (vbo_user) { + int i = ffs(vbo_user) - 1; + vbo_user &= ~(1 << i); - count >>= 1; - if (!count) - return; + nv50_buffer_release_gpu_storage(nv50_resource(nv50->vtxbuf[i].buffer)); + } +} - BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count); - while (count--) { - OUT_RING(chan, (map[1] << 16) | map[0]); - map += 2; - } +void +nv50_vertex_arrays_validate(struct nv50_context *nv50) +{ + 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 + +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 -inline_elt16(void *priv, unsigned start, unsigned count) +nv50_draw_vbo_flush_notify(struct nouveau_channel *chan) { - 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; + struct nv50_context *nv50 = chan->user_private; - if (count & 1) { - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1); - OUT_RING (chan, map[0]); - count &= ~1; - map++; - } + nv50_screen_fence_update(nv50->screen, TRUE); - 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; - } + nv50_bufctx_emit_relocs(nv50); } static void -inline_elt32(void *priv, unsigned start, unsigned count) +nv50_draw_arrays(struct nv50_context *nv50, + unsigned mode, unsigned start, unsigned count, + unsigned instance_count) { - 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; + unsigned prim; - BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, count); - OUT_RINGp (chan, (uint32_t *)ctx->map + start, count); + 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; } static void -inline_edgeflag(void *priv, boolean enabled) +nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map, + unsigned start, unsigned count) { - struct inline_ctx *ctx = priv; - struct nouveau_grobj *tesla = ctx->nv50->screen->tesla; - struct nouveau_channel *chan = tesla->channel; + map += start; - BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1); - OUT_RING (chan, enabled ? 1 : 0); + 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 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_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map, + unsigned start, unsigned count) { - 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; + map += start; - 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 */ + 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; - 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); + 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_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_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map, + unsigned start, unsigned 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); + map += start; - instance_init(nv50, a, startInstance); - if (!nv50_state_validate(nv50, 13 + 16*3)) - return; + while (count) { + const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN); - if (nv50->vbo_fifo) { - nv50_push_elements_instanced(pipe, indexBuffer, indexSize, - indexBias, mode, start, count, - startInstance, instanceCount); - return; - } + BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), nr); + OUT_RINGp (chan, map, nr); - /* indices are uint32 internally, so large indexBias means negative */ - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_BASE, 1); - OUT_RING (chan, indexBias); + map += nr; + count -= nr; + } +} - if (!nv50_resource_mapped_by_gpu(indexBuffer) || indexSize == 1) { - nv50_draw_elements_inline(pipe, indexBuffer, indexSize, - mode, start, count, startInstance, - instanceCount); - return; - } +static void +nv50_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map, + unsigned start, unsigned count) +{ + map += start; - 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); + 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(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_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; + } +} - 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); +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; - prim |= (1 << 28); - } + 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 nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; - if (info->indexed && nv50->idxbuf.buffer) { - unsigned offset; + /* 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)); - assert(nv50->idxbuf.offset % nv50->idxbuf.index_size == 0); - offset = nv50->idxbuf.offset / nv50->idxbuf.index_size; + nv50->vbo_min_index = info->min_index; + nv50->vbo_max_index = info->max_index; - 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); - } + 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); } - -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) - -{ - 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; -} - -void -nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso) -{ - unsigned i; - - for (i = 0; i < cso->num_elements; ++i) - cso->hw[i] = nv50_format_table[cso->pipe[i].src_format].vtx; -} - -struct nouveau_stateobj * -nv50_vbo_validate(struct nv50_context *nv50) -{ - 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; -} - - 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 +#include +#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 From 48e191f90cbb7735cadf30c444e1fb599311c55a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 14:37:06 +1000 Subject: [PATCH 02/53] nv50-nvc0: set cur_ctx during init if none currently bound Signed-off-by: Ben Skeggs --- src/gallium/drivers/nv50/nv50_context.c | 2 ++ src/gallium/drivers/nvc0/nvc0_context.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index bb6272a4a23..8eb59e20d8d 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -102,6 +102,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv) nv50->pipe.flush = nv50_flush; + if (!screen->cur_ctx) + screen->cur_ctx = nv50; screen->base.channel->user_private = nv50; screen->base.channel->flush_notify = nv50_default_flush_notify; diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index f02de4d044a..ebdf5f2f9e8 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -101,6 +101,8 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) nvc0->pipe.flush = nvc0_flush; + if (!screen->cur_ctx) + screen->cur_ctx = nvc0; screen->base.channel->user_private = nvc0; screen->base.channel->flush_notify = nvc0_default_flush_notify; From 5a0915870c7e994d20334042b7647db749e79224 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 09:25:48 +1000 Subject: [PATCH 03/53] nouveau: move nv50/nvc0 fencing to common location, and modify slightly Modified from original to remove chipset-specific code, and to be decoupled from the mm present in said drivers. Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/Makefile | 3 +- src/gallium/drivers/nouveau/nouveau_fence.c | 220 +++++++++++++++++++ src/gallium/drivers/nouveau/nouveau_fence.h | 58 +++++ src/gallium/drivers/nouveau/nouveau_screen.c | 7 +- src/gallium/drivers/nouveau/nouveau_screen.h | 12 + 5 files changed, 296 insertions(+), 4 deletions(-) create mode 100644 src/gallium/drivers/nouveau/nouveau_fence.c create mode 100644 src/gallium/drivers/nouveau/nouveau_fence.h diff --git a/src/gallium/drivers/nouveau/Makefile b/src/gallium/drivers/nouveau/Makefile index a33bf5ebc28..a338be9a0b8 100644 --- a/src/gallium/drivers/nouveau/Makefile +++ b/src/gallium/drivers/nouveau/Makefile @@ -7,6 +7,7 @@ LIBRARY_INCLUDES = \ $(LIBDRM_CFLAGS) \ -I$(TOP)/src/gallium/drivers/nouveau/include -C_SOURCES = nouveau_screen.c +C_SOURCES = nouveau_screen.c \ + nouveau_fence.c include ../../Makefile.template diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c new file mode 100644 index 00000000000..18bdb18ad41 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_fence.c @@ -0,0 +1,220 @@ +/* + * 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 "util/u_double_list.h" + +#include "nouveau_screen.h" +#include "nouveau_fence.h" + +#include "nouveau/nouveau_pushbuf.h" + +#ifdef PIPE_OS_UNIX +#include +#endif + +boolean +nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence **fence, + boolean emit) +{ + *fence = CALLOC_STRUCT(nouveau_fence); + if (!*fence) + return FALSE; + + (*fence)->screen = screen; + (*fence)->ref = 1; + LIST_INITHEAD(&(*fence)->work); + + if (emit) + nouveau_fence_emit(*fence); + + return TRUE; +} + +static void +nouveau_fence_trigger_work(struct nouveau_fence *fence) +{ + struct nouveau_fence_work *work, *tmp; + + LIST_FOR_EACH_ENTRY_SAFE(work, tmp, &fence->work, list) { + work->func(work->data); + LIST_DEL(&work->list); + FREE(work); + } +} + +boolean +nouveau_fence_work(struct nouveau_fence *fence, + void (*func)(void *), void *data) +{ + struct nouveau_fence_work *work; + + if (!fence || fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) { + func(data); + return TRUE; + } + + work = CALLOC_STRUCT(nouveau_fence_work); + if (!work) + return FALSE; + work->func = func; + work->data = data; + LIST_ADD(&work->list, &fence->work); + return TRUE; +} + +void +nouveau_fence_emit(struct nouveau_fence *fence) +{ + struct nouveau_screen *screen = fence->screen; + + fence->sequence = ++screen->fence.sequence; + + assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE); + + screen->fence.emit(&screen->base, fence->sequence); + + ++fence->ref; + + if (screen->fence.tail) + screen->fence.tail->next = fence; + else + screen->fence.head = fence; + + screen->fence.tail = fence; + + fence->state = NOUVEAU_FENCE_STATE_EMITTED; +} + +void +nouveau_fence_del(struct nouveau_fence *fence) +{ + struct nouveau_fence *it; + struct nouveau_screen *screen = fence->screen; + + if (fence->state == NOUVEAU_FENCE_STATE_EMITTED || + fence->state == NOUVEAU_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 (!LIST_IS_EMPTY(&fence->work)) { + debug_printf("WARNING: deleting fence with work still pending !\n"); + nouveau_fence_trigger_work(fence); + } + + FREE(fence); +} + +void +nouveau_fence_update(struct nouveau_screen *screen, boolean flushed) +{ + struct nouveau_fence *fence; + struct nouveau_fence *next = NULL; + u32 sequence = screen->fence.update(&screen->base); + + 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 = NOUVEAU_FENCE_STATE_SIGNALLED; + + nouveau_fence_trigger_work(fence); + nouveau_fence_ref(NULL, &fence); + + 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 = NOUVEAU_FENCE_STATE_FLUSHED; + } +} + +#define NOUVEAU_FENCE_MAX_SPINS (1 << 31) + +boolean +nouveau_fence_signalled(struct nouveau_fence *fence) +{ + struct nouveau_screen *screen = fence->screen; + + if (fence->state >= NOUVEAU_FENCE_STATE_EMITTED) + nouveau_fence_update(screen, FALSE); + + return fence->state == NOUVEAU_FENCE_STATE_SIGNALLED; +} + +boolean +nouveau_fence_wait(struct nouveau_fence *fence) +{ + struct nouveau_screen *screen = fence->screen; + uint32_t spins = 0; + + if (fence->state < NOUVEAU_FENCE_STATE_EMITTED) { + nouveau_fence_emit(fence); + + if (fence == screen->fence.current) + nouveau_fence_new(screen, &screen->fence.current, FALSE); + } + if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED) + FIRE_RING(screen->channel); + + do { + nouveau_fence_update(screen, FALSE); + + if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) + return TRUE; + spins++; +#ifdef PIPE_OS_UNIX + if (!(spins % 8)) /* donate a few cycles */ + sched_yield(); +#endif + } while (spins < NOUVEAU_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 +nouveau_fence_next(struct nouveau_screen *screen) +{ + nouveau_fence_emit(screen->fence.current); + nouveau_fence_new(screen, &screen->fence.current, FALSE); +} diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h new file mode 100644 index 00000000000..785fc8d2a0a --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_fence.h @@ -0,0 +1,58 @@ + +#ifndef __NOUVEAU_FENCE_H__ +#define __NOUVEAU_FENCE_H__ + +#include "util/u_inlines.h" +#include "util/u_double_list.h" + +#define NOUVEAU_FENCE_STATE_AVAILABLE 0 +#define NOUVEAU_FENCE_STATE_EMITTED 1 +#define NOUVEAU_FENCE_STATE_FLUSHED 2 +#define NOUVEAU_FENCE_STATE_SIGNALLED 3 + +struct nouveau_fence_work { + struct list_head list; + void (*func)(void *); + void *data; +}; + +struct nouveau_fence { + struct nouveau_fence *next; + struct nouveau_screen *screen; + int state; + int ref; + uint32_t sequence; + struct list_head work; +}; + +void nouveau_fence_emit(struct nouveau_fence *); +void nouveau_fence_del(struct nouveau_fence *); + +boolean nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **, + boolean emit); +boolean nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *); +void nouveau_fence_update(struct nouveau_screen *, boolean flushed); +void nouveau_fence_next(struct nouveau_screen *); +boolean nouveau_fence_wait(struct nouveau_fence *); +boolean nouveau_fence_signalled(struct nouveau_fence *); + +static INLINE void +nouveau_fence_ref(struct nouveau_fence *fence, struct nouveau_fence **ref) +{ + if (*ref) { + if (--(*ref)->ref == 0) + nouveau_fence_del(*ref); + } + if (fence) + ++fence->ref; + + *ref = fence; +} + +static INLINE struct nouveau_fence * +nouveau_fence(struct pipe_fence_handle *fence) +{ + return (struct nouveau_fence *)fence; +} + +#endif // __NOUVEAU_FENCE_H__ diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index a9426df686f..e14f2346a3e 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -14,6 +14,7 @@ #include "nouveau/nouveau_bo.h" #include "nouveau_winsys.h" #include "nouveau_screen.h" +#include "nouveau_fence.h" /* XXX this should go away */ #include "state_tracker/drm_driver.h" @@ -150,7 +151,7 @@ nouveau_screen_fence_ref(struct pipe_screen *pscreen, struct pipe_fence_handle **ptr, struct pipe_fence_handle *pfence) { - *ptr = pfence; + nouveau_fence_ref(nouveau_fence(pfence), (struct nouveau_fence **)ptr); } static int @@ -158,7 +159,7 @@ nouveau_screen_fence_signalled(struct pipe_screen *screen, struct pipe_fence_handle *pfence, unsigned flags) { - return 0; + return !nouveau_fence_signalled(nouveau_fence(pfence)); } static int @@ -166,7 +167,7 @@ nouveau_screen_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *pfence, unsigned flags) { - return 0; + return !nouveau_fence_wait(nouveau_fence(pfence)); } diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index 1f4e5171c01..e4a460ec657 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -2,6 +2,8 @@ #define __NOUVEAU_SCREEN_H__ #include "pipe/p_screen.h" +#include "util/u_memory.h" +typedef uint32_t u32; struct nouveau_screen { struct pipe_screen base; @@ -12,6 +14,16 @@ struct nouveau_screen { * these almost always should be set to the same value */ unsigned vertex_buffer_flags; unsigned index_buffer_flags; + + struct { + struct nouveau_fence *head; + struct nouveau_fence *tail; + struct nouveau_fence *current; + u32 sequence; + u32 sequence_ack; + void (*emit)(struct pipe_screen *, u32 sequence); + u32 (*update)(struct pipe_screen *); + } fence; }; static INLINE struct nouveau_screen * From 7a8ee058a83f1eda2c783d83fc5967fd9ef75660 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 10:17:28 +1000 Subject: [PATCH 04/53] nv50: move onto shared fence code Signed-off-by: Ben Skeggs --- src/gallium/drivers/nv50/Makefile | 1 - src/gallium/drivers/nv50/nv50_buffer.c | 24 ++- src/gallium/drivers/nv50/nv50_context.c | 9 +- src/gallium/drivers/nv50/nv50_fence.c | 216 ----------------------- src/gallium/drivers/nv50/nv50_fence.h | 49 ----- src/gallium/drivers/nv50/nv50_query.c | 2 +- src/gallium/drivers/nv50/nv50_resource.h | 6 +- src/gallium/drivers/nv50/nv50_screen.c | 50 +++--- src/gallium/drivers/nv50/nv50_screen.h | 35 +--- src/gallium/drivers/nv50/nv50_vbo.c | 2 +- 10 files changed, 46 insertions(+), 348 deletions(-) delete mode 100644 src/gallium/drivers/nv50/nv50_fence.c delete mode 100644 src/gallium/drivers/nv50/nv50_fence.h diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index d0a60c7ac13..61fb94913b3 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -26,7 +26,6 @@ C_SOURCES = \ nv50_pc_optimize.c \ nv50_pc_regalloc.c \ nv50_push.c \ - nv50_fence.c \ nv50_mm.c \ nv50_query.c diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c index 5cb2e628e7a..21aad9f9496 100644 --- a/src/gallium/drivers/nv50/nv50_buffer.c +++ b/src/gallium/drivers/nv50/nv50_buffer.c @@ -49,13 +49,9 @@ nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf, } static INLINE void -release_allocation(struct nv50_mm_allocation **mm, struct nv50_fence *fence) +release_allocation(struct nv50_mm_allocation **mm, struct nouveau_fence *fence) { - if (fence && fence->state != NV50_FENCE_STATE_SIGNALLED) { - nv50_fence_sched_release(fence, *mm); - } else { - nv50_mm_free(*mm); - } + nouveau_fence_work(fence, nv50_mm_free, *mm); (*mm) = NULL; } @@ -153,7 +149,7 @@ nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf, nouveau_bo_ref(NULL, &bounce); if (mm) - release_allocation(&mm, nv50->screen->fence.current); + release_allocation(&mm, nv50->screen->base.fence.current); if (start == 0 && size == buf->base.width0) buf->status &= ~NV50_BUFFER_STATUS_DIRTY; @@ -217,17 +213,17 @@ nv50_buffer_sync(struct nv50_resource *buf, unsigned rw) if (rw == PIPE_TRANSFER_READ) { if (!buf->fence_wr) return TRUE; - if (!nv50_fence_wait(buf->fence_wr)) + if (!nouveau_fence_wait(buf->fence_wr)) return FALSE; } else { if (!buf->fence) return TRUE; - if (!nv50_fence_wait(buf->fence)) + if (!nouveau_fence_wait(buf->fence)) return FALSE; - nv50_fence_reference(&buf->fence, NULL); + nouveau_fence_ref(NULL, &buf->fence); } - nv50_fence_reference(&buf->fence_wr, NULL); + nouveau_fence_ref(NULL, &buf->fence_wr); return TRUE; } @@ -236,9 +232,9 @@ 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)); + return (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr)); else - return (buf->fence && !nv50_fence_signalled(buf->fence)); + return (buf->fence && !nouveau_fence_signalled(buf->fence)); } static void * @@ -453,7 +449,7 @@ nv50_buffer_migrate(struct nv50_context *nv50, nouveau_bo_ref(NULL, &bo); if (mm) - release_allocation(&mm, screen->fence.current); + release_allocation(&mm, screen->base.fence.current); } else if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) { if (!nv50_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM)) diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 8eb59e20d8d..4380945a1ee 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -44,8 +44,8 @@ nv50_flush(struct pipe_context *pipe, unsigned flags, } if (fence) - nv50_fence_reference((struct nv50_fence **)fence, - nv50->screen->fence.current); + nouveau_fence_ref(nv50->screen->base.fence.current, + (struct nouveau_fence **)fence); if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME)) FIRE_RING(chan); @@ -59,9 +59,8 @@ nv50_default_flush_notify(struct nouveau_channel *chan) if (!nv50) return; - nv50_screen_fence_update(nv50->screen, TRUE); - - nv50_screen_fence_next(nv50->screen); + nouveau_fence_update(&nv50->screen->base, TRUE); + nouveau_fence_next(&nv50->screen->base); } static void diff --git a/src/gallium/drivers/nv50/nv50_fence.c b/src/gallium/drivers/nv50/nv50_fence.c deleted file mode 100644 index 936cf81ac75..00000000000 --- a/src/gallium/drivers/nv50/nv50_fence.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * 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 -#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 deleted file mode 100644 index dd0b74e89fa..00000000000 --- a/src/gallium/drivers/nv50/nv50_fence.h +++ /dev/null @@ -1,49 +0,0 @@ - -#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_query.c b/src/gallium/drivers/nv50/nv50_query.c index e769aa18fe9..42391ec5b1f 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -64,7 +64,7 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size) if (q->ready) nv50_mm_free(q->mm); else - nv50_fence_sched_release(screen->fence.current, q->mm); + nouveau_fence_work(screen->base.fence.current, nv50_mm_free, q->mm); } } if (size) { diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h index f0e022b320b..f42179c88f3 100644 --- a/src/gallium/drivers/nv50/nv50_resource.h +++ b/src/gallium/drivers/nv50/nv50_resource.h @@ -8,8 +8,6 @@ #include "nouveau/nouveau_winsys.h" #undef NOUVEAU_NVC0 -#include "nv50_fence.h" - struct pipe_resource; struct nouveau_bo; struct nv50_context; @@ -45,8 +43,8 @@ struct nv50_resource { int16_t score; /* low if mapped very often, if high can move to VRAM */ - struct nv50_fence *fence; - struct nv50_fence *fence_wr; + struct nouveau_fence *fence; + struct nouveau_fence *fence_wr; struct nv50_mm_allocation *mm; }; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 77cf959940d..e5b50103ef7 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -23,7 +23,6 @@ #include "util/u_format_s3tc.h" #include "pipe/p_screen.h" -#include "nv50_fence.h" #include "nv50_context.h" #include "nv50_screen.h" @@ -211,9 +210,9 @@ nv50_screen_destroy(struct pipe_screen *pscreen) { struct nv50_screen *screen = nv50_screen(pscreen); - if (screen->fence.current) { - nv50_fence_wait(screen->fence.current); - nv50_fence_reference(&screen->fence.current, NULL); + if (screen->base.fence.current) { + nouveau_fence_wait(screen->base.fence.current); + nouveau_fence_ref (NULL, &screen->base.fence.current); } nouveau_bo_ref(NULL, &screen->code); @@ -246,27 +245,29 @@ nv50_screen_destroy(struct pipe_screen *pscreen) } static void -nv50_screen_fence_reference(struct pipe_screen *pscreen, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) +nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 sequence) { - nv50_fence_reference((struct nv50_fence **)ptr, nv50_fence(fence)); + struct nv50_screen *screen = nv50_screen(pscreen); + struct nouveau_channel *chan = screen->base.channel; + + 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, 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); } -static int -nv50_screen_fence_signalled(struct pipe_screen *pscreen, - struct pipe_fence_handle *fence, - unsigned flags) +static u32 +nv50_screen_fence_update(struct pipe_screen *pscreen) { - return !(nv50_fence_signalled(nv50_fence(fence))); -} - -static int -nv50_screen_fence_finish(struct pipe_screen *pscreen, - struct pipe_fence_handle *fence, - unsigned flags) -{ - return nv50_fence_wait((struct nv50_fence *)fence) != TRUE; + struct nv50_screen *screen = nv50_screen(pscreen); + return screen->fence.map[0]; } #define FAIL_SCREEN_INIT(str, err) \ @@ -306,9 +307,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) 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); @@ -322,6 +320,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR); screen->fence.map = screen->fence.bo->map; nouveau_bo_unmap(screen->fence.bo); + screen->base.fence.emit = nv50_screen_fence_emit; + screen->base.fence.update = nv50_screen_fence_update; ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); if (ret) @@ -591,7 +591,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->mm_VRAM = nv50_mm_create(dev, NOUVEAU_BO_VRAM, 0x000); screen->mm_VRAM_fe0 = nv50_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); - nv50_screen_fence_new(screen, &screen->fence.current, FALSE); + nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); return pscreen; diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index c78ed50fe35..c2ec3b58dc2 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -3,6 +3,7 @@ #define NOUVEAU_NVC0 #include "nouveau/nouveau_screen.h" +#include "nouveau/nouveau_fence.h" #undef NOUVEAU_NVC0 #include "nv50_winsys.h" #include "nv50_stateobj.h" @@ -12,7 +13,6 @@ struct nv50_mman; struct nv50_context; -struct nv50_fence; #define NV50_SCRATCH_SIZE (2 << 20) #define NV50_SCRATCH_NR_BUFFERS 2 @@ -49,11 +49,6 @@ struct nv50_screen { 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; @@ -83,13 +78,6 @@ struct nv50_mm_allocation { uint32_t offset; }; -static INLINE void -nv50_fence_sched_release(struct nv50_fence *nf, struct nv50_mm_allocation *mm) -{ - mm->next = nf->buffers; - nf->buffers = mm; -} - extern struct nv50_mman * nv50_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type); @@ -113,10 +101,10 @@ nv50_resource_fence(struct nv50_resource *res, uint32_t flags) struct nv50_screen *screen = nv50_screen(res->base.screen); if (res->mm) { - nv50_fence_reference(&res->fence, screen->fence.current); + nouveau_fence_ref(screen->base.fence.current, &res->fence); if (flags & NOUVEAU_BO_WR) - nv50_fence_reference(&res->fence_wr, screen->fence.current); + nouveau_fence_ref(screen->base.fence.current, &res->fence_wr); } } @@ -132,23 +120,6 @@ nv50_resource_validate(struct nv50_resource *res, uint32_t flags) } } - -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; diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 0e0d48d661c..d18b2dffd1d 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -393,7 +393,7 @@ nv50_draw_vbo_flush_notify(struct nouveau_channel *chan) { struct nv50_context *nv50 = chan->user_private; - nv50_screen_fence_update(nv50->screen, TRUE); + nouveau_fence_update(&nv50->screen->base, TRUE); nv50_bufctx_emit_relocs(nv50); } From 2f30a5bdaad480118e23ac4243de3b4a11ba62a8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 10:27:45 +1000 Subject: [PATCH 05/53] nv50: make mm available as common code Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/Makefile | 3 +- .../{nv50/nv50_mm.c => nouveau/nouveau_mm.c} | 41 ++++++++++--------- src/gallium/drivers/nouveau/nouveau_mm.h | 29 +++++++++++++ src/gallium/drivers/nv50/Makefile | 1 - src/gallium/drivers/nv50/nv50_buffer.c | 25 +++++------ src/gallium/drivers/nv50/nv50_query.c | 8 ++-- src/gallium/drivers/nv50/nv50_resource.h | 2 +- src/gallium/drivers/nv50/nv50_screen.c | 14 +++---- src/gallium/drivers/nv50/nv50_screen.h | 29 ++----------- 9 files changed, 82 insertions(+), 70 deletions(-) rename src/gallium/drivers/{nv50/nv50_mm.c => nouveau/nouveau_mm.c} (85%) create mode 100644 src/gallium/drivers/nouveau/nouveau_mm.h diff --git a/src/gallium/drivers/nouveau/Makefile b/src/gallium/drivers/nouveau/Makefile index a338be9a0b8..f9ab9d18609 100644 --- a/src/gallium/drivers/nouveau/Makefile +++ b/src/gallium/drivers/nouveau/Makefile @@ -8,6 +8,7 @@ LIBRARY_INCLUDES = \ -I$(TOP)/src/gallium/drivers/nouveau/include C_SOURCES = nouveau_screen.c \ - nouveau_fence.c + nouveau_fence.c \ + nouveau_mm.c include ../../Makefile.template diff --git a/src/gallium/drivers/nv50/nv50_mm.c b/src/gallium/drivers/nouveau/nouveau_mm.c similarity index 85% rename from src/gallium/drivers/nv50/nv50_mm.c rename to src/gallium/drivers/nouveau/nouveau_mm.c index f991d6192e8..1c4bb61af88 100644 --- a/src/gallium/drivers/nv50/nv50_mm.c +++ b/src/gallium/drivers/nouveau/nouveau_mm.c @@ -3,7 +3,10 @@ #include "util/u_memory.h" #include "util/u_double_list.h" -#include "nv50_screen.h" +#include "nouveau_screen.h" +#include "nouveau_mm.h" + +#include "nouveau/nouveau_bo.h" #define MM_MIN_ORDER 7 #define MM_MAX_ORDER 20 @@ -20,7 +23,7 @@ struct mm_bucket { int num_free; }; -struct nv50_mman { +struct nouveau_mman { struct nouveau_device *dev; struct mm_bucket bucket[MM_NUM_BUCKETS]; uint32_t storage_type; @@ -31,7 +34,7 @@ struct nv50_mman { struct mm_slab { struct list_head head; struct nouveau_bo *bo; - struct nv50_mman *cache; + struct nouveau_mman *cache; int order; int count; int free; @@ -79,7 +82,7 @@ mm_get_order(uint32_t size) } static struct mm_bucket * -mm_bucket_by_order(struct nv50_mman *cache, int order) +mm_bucket_by_order(struct nouveau_mman *cache, int order) { if (order > MM_MAX_ORDER) return NULL; @@ -87,7 +90,7 @@ mm_bucket_by_order(struct nv50_mman *cache, int order) } static struct mm_bucket * -mm_bucket_by_size(struct nv50_mman *cache, unsigned size) +mm_bucket_by_size(struct nouveau_mman *cache, unsigned size) { return mm_bucket_by_order(cache, mm_get_order(size)); } @@ -107,7 +110,7 @@ mm_default_slab_size(unsigned chunk_order) } static int -mm_slab_new(struct nv50_mman *cache, int chunk_order) +mm_slab_new(struct nouveau_mman *cache, int chunk_order) { struct mm_slab *slab; int words, ret; @@ -147,13 +150,13 @@ mm_slab_new(struct nv50_mman *cache, int chunk_order) } /* @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, +struct nouveau_mm_allocation * +nouveau_mm_allocate(struct nouveau_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; + struct nouveau_mm_allocation *alloc; int ret; bucket = mm_bucket_by_size(cache, size); @@ -181,7 +184,7 @@ nv50_mm_allocate(struct nv50_mman *cache, *offset = mm_slab_alloc(slab) << slab->order; - alloc = MALLOC_STRUCT(nv50_mm_allocation); + alloc = MALLOC_STRUCT(nouveau_mm_allocation); if (!alloc) return NULL; @@ -200,7 +203,7 @@ nv50_mm_allocate(struct nv50_mman *cache, } void -nv50_mm_free(struct nv50_mm_allocation *alloc) +nouveau_mm_free(struct nouveau_mm_allocation *alloc) { struct mm_slab *slab = (struct mm_slab *)alloc->priv; struct mm_bucket *bucket = mm_bucket_by_order(slab->cache, slab->order); @@ -219,11 +222,11 @@ nv50_mm_free(struct nv50_mm_allocation *alloc) FREE(alloc); } -struct nv50_mman * -nv50_mm_create(struct nouveau_device *dev, uint32_t domain, +struct nouveau_mman * +nouveau_mm_create(struct nouveau_device *dev, uint32_t domain, uint32_t storage_type) { - struct nv50_mman *cache = MALLOC_STRUCT(nv50_mman); + struct nouveau_mman *cache = MALLOC_STRUCT(nouveau_mman); int i; if (!cache) @@ -244,7 +247,7 @@ nv50_mm_create(struct nouveau_device *dev, uint32_t domain, } static INLINE void -nv50_mm_free_slabs(struct list_head *head) +nouveau_mm_free_slabs(struct list_head *head) { struct mm_slab *slab, *next; @@ -256,7 +259,7 @@ nv50_mm_free_slabs(struct list_head *head) } void -nv50_mm_destroy(struct nv50_mman *cache) +nouveau_mm_destroy(struct nouveau_mman *cache) { int i; @@ -269,9 +272,9 @@ nv50_mm_destroy(struct nv50_mman *cache) 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); + nouveau_mm_free_slabs(&cache->bucket[i].free); + nouveau_mm_free_slabs(&cache->bucket[i].used); + nouveau_mm_free_slabs(&cache->bucket[i].full); } } diff --git a/src/gallium/drivers/nouveau/nouveau_mm.h b/src/gallium/drivers/nouveau/nouveau_mm.h new file mode 100644 index 00000000000..23e50d4ae54 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_mm.h @@ -0,0 +1,29 @@ +#ifndef __NOUVEAU_MM_H__ +#define __NOUVEAU_MM_H__ + +struct nouveau_mman; + +/* 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 nouveau_mm_allocation { + struct nouveau_mm_allocation *next; + void *priv; + uint32_t offset; +}; + +extern struct nouveau_mman * +nouveau_mm_create(struct nouveau_device *, uint32_t domain, + uint32_t storage_type); + +extern void +nouveau_mm_destroy(struct nouveau_mman *); + +extern struct nouveau_mm_allocation * +nouveau_mm_allocate(struct nouveau_mman *, uint32_t size, + struct nouveau_bo **, uint32_t *offset); + +extern void +nouveau_mm_free(struct nouveau_mm_allocation *); + +#endif // __NOUVEAU_MM_H__ diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index 61fb94913b3..dc9ea0eeba7 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -26,7 +26,6 @@ C_SOURCES = \ nv50_pc_optimize.c \ nv50_pc_regalloc.c \ nv50_push.c \ - nv50_mm.c \ nv50_query.c LIBRARY_INCLUDES = \ diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c index 21aad9f9496..f808adb0f62 100644 --- a/src/gallium/drivers/nv50/nv50_buffer.c +++ b/src/gallium/drivers/nv50/nv50_buffer.c @@ -6,6 +6,7 @@ #define NOUVEAU_NVC0 #include "nouveau/nouveau_screen.h" #include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_mm.h" #undef NOUVEAU_NVC0 #include "nv50_context.h" @@ -26,14 +27,14 @@ nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf, unsigned domain) { if (domain == NOUVEAU_BO_VRAM) { - buf->mm = nv50_mm_allocate(screen->mm_VRAM, buf->base.width0, &buf->bo, - &buf->offset); + buf->mm = nouveau_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); + buf->mm = nouveau_mm_allocate(screen->mm_GART, buf->base.width0, &buf->bo, + &buf->offset); if (!buf->bo) return FALSE; } @@ -49,9 +50,9 @@ nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf, } static INLINE void -release_allocation(struct nv50_mm_allocation **mm, struct nouveau_fence *fence) +release_allocation(struct nouveau_mm_allocation **mm, struct nouveau_fence *fence) { - nouveau_fence_work(fence, nv50_mm_free, *mm); + nouveau_fence_work(fence, nouveau_mm_free, *mm); (*mm) = NULL; } @@ -94,13 +95,13 @@ boolean nv50_buffer_download(struct nv50_context *nv50, struct nv50_resource *buf, unsigned start, unsigned size) { - struct nv50_mm_allocation *mm; + struct nouveau_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); + mm = nouveau_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset); if (!bounce) return FALSE; @@ -117,7 +118,7 @@ nv50_buffer_download(struct nv50_context *nv50, struct nv50_resource *buf, nouveau_bo_ref(NULL, &bounce); if (mm) - nv50_mm_free(mm); + nouveau_mm_free(mm); return TRUE; } @@ -125,7 +126,7 @@ static boolean nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf, unsigned start, unsigned size) { - struct nv50_mm_allocation *mm; + struct nouveau_mm_allocation *mm; struct nouveau_bo *bounce = NULL; uint32_t offset; @@ -135,7 +136,7 @@ nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf, return TRUE; } - mm = nv50_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset); + mm = nouveau_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset); if (!bounce) return FALSE; @@ -429,7 +430,7 @@ nv50_buffer_migrate(struct nv50_context *nv50, FREE(buf->data); } else if (old_domain != 0 && new_domain != 0) { - struct nv50_mm_allocation *mm = buf->mm; + struct nouveau_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 */ diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 42391ec5b1f..8a2bca6850a 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -41,7 +41,7 @@ struct nv50_query { uint32_t offset; /* base + i * 16 */ boolean ready; boolean is64bit; - struct nv50_mm_allocation *mm; + struct nouveau_mm_allocation *mm; }; #define NV50_QUERY_ALLOC_SPACE 128 @@ -62,13 +62,13 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size) nouveau_bo_ref(NULL, &q->bo); if (q->mm) { if (q->ready) - nv50_mm_free(q->mm); + nouveau_mm_free(q->mm); else - nouveau_fence_work(screen->base.fence.current, nv50_mm_free, q->mm); + nouveau_fence_work(screen->base.fence.current, nouveau_mm_free, q->mm); } } if (size) { - q->mm = nv50_mm_allocate(screen->mm_GART, size, &q->bo, &q->base); + q->mm = nouveau_mm_allocate(screen->mm_GART, size, &q->bo, &q->base); if (!q->bo) return FALSE; q->offset = q->base; diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h index f42179c88f3..64563421fd0 100644 --- a/src/gallium/drivers/nv50/nv50_resource.h +++ b/src/gallium/drivers/nv50/nv50_resource.h @@ -46,7 +46,7 @@ struct nv50_resource { struct nouveau_fence *fence; struct nouveau_fence *fence_wr; - struct nv50_mm_allocation *mm; + struct nouveau_mm_allocation *mm; }; void diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index e5b50103ef7..bd645b87164 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -229,9 +229,9 @@ nv50_screen_destroy(struct pipe_screen *pscreen) 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_mm_destroy(screen->mm_GART); + nouveau_mm_destroy(screen->mm_VRAM); + nouveau_mm_destroy(screen->mm_VRAM_fe0); nouveau_grobj_free(&screen->tesla); nouveau_grobj_free(&screen->eng2d); @@ -586,10 +586,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->tic.entries = CALLOC(4096, sizeof(void *)); screen->tsc.entries = screen->tic.entries + 2048; - 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); + screen->mm_GART = nouveau_mm_create(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, + 0x000); + screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0x000); + screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index c2ec3b58dc2..672891b6b7f 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -4,6 +4,7 @@ #define NOUVEAU_NVC0 #include "nouveau/nouveau_screen.h" #include "nouveau/nouveau_fence.h" +#include "nouveau/nouveau_mm.h" #undef NOUVEAU_NVC0 #include "nv50_winsys.h" #include "nv50_stateobj.h" @@ -11,7 +12,6 @@ #define NV50_TIC_MAX_ENTRIES 2048 #define NV50_TSC_MAX_ENTRIES 2048 -struct nv50_mman; struct nv50_context; #define NV50_SCRATCH_SIZE (2 << 20) @@ -54,9 +54,9 @@ struct nv50_screen { struct nouveau_notifier *sync; - struct nv50_mman *mm_GART; - struct nv50_mman *mm_VRAM; - struct nv50_mman *mm_VRAM_fe0; + struct nouveau_mman *mm_GART; + struct nouveau_mman *mm_VRAM; + struct nouveau_mman *mm_VRAM_fe0; struct nouveau_grobj *tesla; struct nouveau_grobj *eng2d; @@ -69,27 +69,6 @@ nv50_screen(struct pipe_screen *screen) return (struct nv50_screen *)screen; } -/* 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; -}; - -extern struct nv50_mman * -nv50_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type); - -extern void -nv50_mm_destroy(struct nv50_mman *); - -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 *); - void nv50_screen_make_buffers_resident(struct nv50_screen *); int nv50_screen_tic_alloc(struct nv50_screen *, void *); From d6bdf1f6ae6f8d06db740ad75e9151ef275755b2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 10:31:54 +1000 Subject: [PATCH 06/53] nouveau: fix compiler complaint Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_mm.c | 6 ++++++ src/gallium/drivers/nouveau/nouveau_mm.h | 3 +++ src/gallium/drivers/nv50/nv50_buffer.c | 2 +- src/gallium/drivers/nv50/nv50_query.c | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_mm.c b/src/gallium/drivers/nouveau/nouveau_mm.c index 1c4bb61af88..332b8dc02e3 100644 --- a/src/gallium/drivers/nouveau/nouveau_mm.c +++ b/src/gallium/drivers/nouveau/nouveau_mm.c @@ -222,6 +222,12 @@ nouveau_mm_free(struct nouveau_mm_allocation *alloc) FREE(alloc); } +void +nouveau_mm_free_work(void *data) +{ + nouveau_mm_free(data); +} + struct nouveau_mman * nouveau_mm_create(struct nouveau_device *dev, uint32_t domain, uint32_t storage_type) diff --git a/src/gallium/drivers/nouveau/nouveau_mm.h b/src/gallium/drivers/nouveau/nouveau_mm.h index 23e50d4ae54..5b57c8ba4f2 100644 --- a/src/gallium/drivers/nouveau/nouveau_mm.h +++ b/src/gallium/drivers/nouveau/nouveau_mm.h @@ -26,4 +26,7 @@ nouveau_mm_allocate(struct nouveau_mman *, uint32_t size, extern void nouveau_mm_free(struct nouveau_mm_allocation *); +extern void +nouveau_mm_free_work(void *); + #endif // __NOUVEAU_MM_H__ diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c index f808adb0f62..7b2b47a1e05 100644 --- a/src/gallium/drivers/nv50/nv50_buffer.c +++ b/src/gallium/drivers/nv50/nv50_buffer.c @@ -52,7 +52,7 @@ nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf, static INLINE void release_allocation(struct nouveau_mm_allocation **mm, struct nouveau_fence *fence) { - nouveau_fence_work(fence, nouveau_mm_free, *mm); + nouveau_fence_work(fence, nouveau_mm_free_work, *mm); (*mm) = NULL; } diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 8a2bca6850a..2803626d18c 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -64,7 +64,7 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size) if (q->ready) nouveau_mm_free(q->mm); else - nouveau_fence_work(screen->base.fence.current, nouveau_mm_free, q->mm); + nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, q->mm); } } if (size) { From 3a38a4b0a8caae9be9a66f10e12ad41a1806037f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 10:43:44 +1000 Subject: [PATCH 07/53] nouveau: fix fence_ref() where fence and *ref are the same fence Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_fence.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h index 785fc8d2a0a..680c75e99f9 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.h +++ b/src/gallium/drivers/nouveau/nouveau_fence.h @@ -39,12 +39,13 @@ boolean nouveau_fence_signalled(struct nouveau_fence *); static INLINE void nouveau_fence_ref(struct nouveau_fence *fence, struct nouveau_fence **ref) { + if (fence) + ++fence->ref; + if (*ref) { if (--(*ref)->ref == 0) nouveau_fence_del(*ref); } - if (fence) - ++fence->ref; *ref = fence; } From cd24fcedecfc41d77047fb827a88db528ed292ca Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 10:49:36 +1000 Subject: [PATCH 08/53] nouveau: create linear gart/vram mman in common screen init Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_screen.c | 9 +++++++++ src/gallium/drivers/nouveau/nouveau_screen.h | 3 +++ src/gallium/drivers/nv50/nv50_buffer.c | 12 ++++++------ src/gallium/drivers/nv50/nv50_query.c | 2 +- src/gallium/drivers/nv50/nv50_screen.c | 5 ----- src/gallium/drivers/nv50/nv50_screen.h | 2 -- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index e14f2346a3e..e6cd3064c9a 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -251,6 +251,10 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) util_format_s3tc_init(); + screen->mm_GART = nouveau_mm_create(dev, + NOUVEAU_BO_GART | NOUVEAU_BO_MAP, + 0x000); + screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0x000); return 0; } @@ -258,7 +262,12 @@ void nouveau_screen_fini(struct nouveau_screen *screen) { struct pipe_winsys *ws = screen->base.winsys; + + nouveau_mm_destroy(screen->mm_GART); + nouveau_mm_destroy(screen->mm_VRAM); + nouveau_channel_free(&screen->channel); + if (ws) ws->destroy(ws); } diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index e4a460ec657..173592d6ea7 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -24,6 +24,9 @@ struct nouveau_screen { void (*emit)(struct pipe_screen *, u32 sequence); u32 (*update)(struct pipe_screen *); } fence; + + struct nouveau_mman *mm_VRAM; + struct nouveau_mman *mm_GART; }; static INLINE struct nouveau_screen * diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c index 7b2b47a1e05..ae65591e7f2 100644 --- a/src/gallium/drivers/nv50/nv50_buffer.c +++ b/src/gallium/drivers/nv50/nv50_buffer.c @@ -27,14 +27,14 @@ nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf, unsigned domain) { if (domain == NOUVEAU_BO_VRAM) { - buf->mm = nouveau_mm_allocate(screen->mm_VRAM, buf->base.width0, &buf->bo, - &buf->offset); + buf->mm = nouveau_mm_allocate(screen->base.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 = nouveau_mm_allocate(screen->mm_GART, buf->base.width0, &buf->bo, - &buf->offset); + buf->mm = nouveau_mm_allocate(screen->base.mm_GART, buf->base.width0, + &buf->bo, &buf->offset); if (!buf->bo) return FALSE; } @@ -101,7 +101,7 @@ nv50_buffer_download(struct nv50_context *nv50, struct nv50_resource *buf, assert(buf->domain == NOUVEAU_BO_VRAM); - mm = nouveau_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset); + mm = nouveau_mm_allocate(nv50->screen->base.mm_GART, size, &bounce, &offset); if (!bounce) return FALSE; @@ -136,7 +136,7 @@ nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf, return TRUE; } - mm = nouveau_mm_allocate(nv50->screen->mm_GART, size, &bounce, &offset); + mm = nouveau_mm_allocate(nv50->screen->base.mm_GART, size, &bounce, &offset); if (!bounce) return FALSE; diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 2803626d18c..2e65c54e548 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -68,7 +68,7 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size) } } if (size) { - q->mm = nouveau_mm_allocate(screen->mm_GART, size, &q->bo, &q->base); + q->mm = nouveau_mm_allocate(screen->base.mm_GART, size, &q->bo, &q->base); if (!q->bo) return FALSE; q->offset = q->base; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index bd645b87164..f2b03e8156e 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -229,8 +229,6 @@ nv50_screen_destroy(struct pipe_screen *pscreen) if (screen->tic.entries) FREE(screen->tic.entries); - nouveau_mm_destroy(screen->mm_GART); - nouveau_mm_destroy(screen->mm_VRAM); nouveau_mm_destroy(screen->mm_VRAM_fe0); nouveau_grobj_free(&screen->tesla); @@ -586,9 +584,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->tic.entries = CALLOC(4096, sizeof(void *)); screen->tsc.entries = screen->tic.entries + 2048; - screen->mm_GART = nouveau_mm_create(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0x000); - screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0x000); screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 672891b6b7f..3bf67eb656b 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -54,8 +54,6 @@ struct nv50_screen { struct nouveau_notifier *sync; - struct nouveau_mman *mm_GART; - struct nouveau_mman *mm_VRAM; struct nouveau_mman *mm_VRAM_fe0; struct nouveau_grobj *tesla; From 5c1c4f8593073c0bad9bada9234657dda1b25ff0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 11:30:25 +1000 Subject: [PATCH 09/53] nouveau: common linear buffer manager, ported from nv50/nvc0 drivers nv50_resource is being called nv04_resource now temporarily, to avoid a naming conflict with nouveau_resource from libdrm. Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/Makefile | 3 +- src/gallium/drivers/nouveau/nouveau_buffer.c | 489 +++++++++++++++++++ src/gallium/drivers/nouveau/nouveau_buffer.h | 137 ++++++ src/gallium/drivers/nouveau/nouveau_screen.h | 9 + src/gallium/drivers/nouveau/nouveau_winsys.h | 1 - src/gallium/drivers/nvfx/nvfx_context.h | 1 + 6 files changed, 638 insertions(+), 2 deletions(-) create mode 100644 src/gallium/drivers/nouveau/nouveau_buffer.c create mode 100644 src/gallium/drivers/nouveau/nouveau_buffer.h diff --git a/src/gallium/drivers/nouveau/Makefile b/src/gallium/drivers/nouveau/Makefile index f9ab9d18609..3210d1ff77b 100644 --- a/src/gallium/drivers/nouveau/Makefile +++ b/src/gallium/drivers/nouveau/Makefile @@ -9,6 +9,7 @@ LIBRARY_INCLUDES = \ C_SOURCES = nouveau_screen.c \ nouveau_fence.c \ - nouveau_mm.c + nouveau_mm.c \ + nouveau_buffer.c include ../../Makefile.template diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c new file mode 100644 index 00000000000..4f4b24fdd21 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -0,0 +1,489 @@ + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_math.h" + +#include "nouveau_screen.h" +#include "nouveau_winsys.h" +#include "nouveau_fence.h" +#include "nouveau_buffer.h" +#include "nouveau_mm.h" + +struct nouveau_transfer { + struct pipe_transfer base; +}; + +static INLINE struct nouveau_transfer * +nouveau_transfer(struct pipe_transfer *transfer) +{ + return (struct nouveau_transfer *)transfer; +} + +static INLINE boolean +nouveau_buffer_allocate(struct nouveau_screen *screen, + struct nv04_resource *buf, unsigned domain) +{ + if (domain == NOUVEAU_BO_VRAM) { + buf->mm = nouveau_mm_allocate(screen->mm_VRAM, buf->base.width0, + &buf->bo, &buf->offset); + if (!buf->bo) + return nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_GART); + } else + if (domain == NOUVEAU_BO_GART) { + buf->mm = nouveau_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; +} + +static INLINE void +release_allocation(struct nouveau_mm_allocation **mm, + struct nouveau_fence *fence) +{ + nouveau_fence_work(fence, nouveau_mm_free_work, *mm); + (*mm) = NULL; +} + +INLINE void +nouveau_buffer_release_gpu_storage(struct nv04_resource *buf) +{ + nouveau_bo_ref(NULL, &buf->bo); + + if (buf->mm) + release_allocation(&buf->mm, buf->fence); + + buf->domain = 0; +} + +static INLINE boolean +nouveau_buffer_reallocate(struct nouveau_screen *screen, + struct nv04_resource *buf, unsigned domain) +{ + nouveau_buffer_release_gpu_storage(buf); + + return nouveau_buffer_allocate(screen, buf, domain); +} + +static void +nouveau_buffer_destroy(struct pipe_screen *pscreen, + struct pipe_resource *presource) +{ + struct nv04_resource *res = nv04_resource(presource); + + nouveau_buffer_release_gpu_storage(res); + + if (res->data && !(res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY)) + FREE(res->data); + + FREE(res); +} + +/* Maybe just migrate to GART right away if we actually need to do this. */ +boolean +nouveau_buffer_download(struct pipe_context *pipe, struct nv04_resource *buf, + unsigned start, unsigned size) +{ + struct nouveau_screen *screen = nouveau_screen(pipe->screen); + struct nouveau_mm_allocation *mm; + struct nouveau_bo *bounce = NULL; + uint32_t offset; + + assert(buf->domain == NOUVEAU_BO_VRAM); + + mm = nouveau_mm_allocate(screen->mm_GART, size, &bounce, &offset); + if (!bounce) + return FALSE; + + screen->copy_data(pipe, 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 &= ~NOUVEAU_BUFFER_STATUS_DIRTY; + + nouveau_bo_ref(NULL, &bounce); + if (mm) + nouveau_mm_free(mm); + return TRUE; +} + +static boolean +nouveau_buffer_upload(struct pipe_context *pipe, struct nv04_resource *buf, + unsigned start, unsigned size) +{ + struct nouveau_screen *screen = nouveau_screen(pipe->screen); + struct nouveau_mm_allocation *mm; + struct nouveau_bo *bounce = NULL; + uint32_t offset; + + if (size <= 192) { + screen->push_data(pipe, buf->bo, buf->offset + start, buf->domain, + size, buf->data + start); + return TRUE; + } + + mm = nouveau_mm_allocate(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); + + screen->copy_data(pipe, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, + bounce, offset, NOUVEAU_BO_GART, size); + + nouveau_bo_ref(NULL, &bounce); + if (mm) + release_allocation(&mm, screen->fence.current); + + if (start == 0 && size == buf->base.width0) + buf->status &= ~NOUVEAU_BUFFER_STATUS_DIRTY; + return TRUE; +} + +static struct pipe_transfer * +nouveau_buffer_transfer_get(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, unsigned usage, + const struct pipe_box *box) +{ + struct nv04_resource *buf = nv04_resource(resource); + struct nouveau_transfer *xfr = CALLOC_STRUCT(nouveau_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 & NOUVEAU_BUFFER_STATUS_DIRTY) + nouveau_buffer_download(pipe, buf, 0, buf->base.width0); + } + } + + return &xfr->base; +} + +static void +nouveau_buffer_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct nv04_resource *buf = nv04_resource(transfer->resource); + struct nouveau_transfer *xfr = nouveau_transfer(transfer); + + if (xfr->base.usage & PIPE_TRANSFER_WRITE) { + /* writing is worse */ + nouveau_buffer_adjust_score(pipe, buf, -5000); + + if (buf->domain == NOUVEAU_BO_VRAM) { + nouveau_buffer_upload(pipe, buf, transfer->box.x, transfer->box.width); + } + +#if 0 + if (buf->domain != 0 && (buf->base.bind & (PIPE_BIND_VERTEX_BUFFER | + PIPE_BIND_INDEX_BUFFER))) + nouveau_context(pipe)->vbo_dirty = TRUE; +#endif + } + + FREE(xfr); +} + +static INLINE boolean +nouveau_buffer_sync(struct nv04_resource *buf, unsigned rw) +{ + if (rw == PIPE_TRANSFER_READ) { + if (!buf->fence_wr) + return TRUE; + if (!nouveau_fence_wait(buf->fence_wr)) + return FALSE; + } else { + if (!buf->fence) + return TRUE; + if (!nouveau_fence_wait(buf->fence)) + return FALSE; + + nouveau_fence_ref(NULL, &buf->fence); + } + nouveau_fence_ref(NULL, &buf->fence_wr); + + return TRUE; +} + +static INLINE boolean +nouveau_buffer_busy(struct nv04_resource *buf, unsigned rw) +{ + if (rw == PIPE_TRANSFER_READ) + return (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr)); + else + return (buf->fence && !nouveau_fence_signalled(buf->fence)); +} + +static void * +nouveau_buffer_transfer_map(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + struct nouveau_transfer *xfr = nouveau_transfer(transfer); + struct nv04_resource *buf = nv04_resource(transfer->resource); + struct nouveau_bo *bo = buf->bo; + uint8_t *map; + int ret; + uint32_t offset = xfr->base.box.x; + uint32_t flags; + + nouveau_buffer_adjust_score(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 (nouveau_buffer_busy(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE)) + return NULL; + } else + if (!(xfr->base.usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { + nouveau_buffer_sync(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE); + } + } + return map; +} + + + +static void +nouveau_buffer_transfer_flush_region(struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) +{ + struct nv04_resource *res = nv04_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 +nouveau_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 nouveau_buffer_vtbl = +{ + u_default_resource_get_handle, /* get_handle */ + nouveau_buffer_destroy, /* resource_destroy */ + NULL, /* is_resource_referenced */ + nouveau_buffer_transfer_get, /* get_transfer */ + nouveau_buffer_transfer_destroy, /* transfer_destroy */ + nouveau_buffer_transfer_map, /* transfer_map */ + nouveau_buffer_transfer_flush_region, /* transfer_flush_region */ + nouveau_buffer_transfer_unmap, /* transfer_unmap */ + u_default_transfer_inline_write /* transfer_inline_write */ +}; + +struct pipe_resource * +nouveau_buffer_create(struct pipe_screen *pscreen, + const struct pipe_resource *templ) +{ + struct nouveau_screen *screen = nouveau_screen(pscreen); + struct nv04_resource *buffer; + boolean ret; + + buffer = CALLOC_STRUCT(nv04_resource); + if (!buffer) + return NULL; + + buffer->base = *templ; + buffer->vtbl = &nouveau_buffer_vtbl; + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = pscreen; + + if (buffer->base.bind & PIPE_BIND_CONSTANT_BUFFER) + ret = nouveau_buffer_allocate(screen, buffer, 0); + else + ret = nouveau_buffer_allocate(screen, buffer, NOUVEAU_BO_GART); + + if (ret == FALSE) + goto fail; + + return &buffer->base; + +fail: + FREE(buffer); + return NULL; +} + + +struct pipe_resource * +nouveau_user_buffer_create(struct pipe_screen *pscreen, void *ptr, + unsigned bytes, unsigned bind) +{ + struct nv04_resource *buffer; + + buffer = CALLOC_STRUCT(nv04_resource); + if (!buffer) + return NULL; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->vtbl = &nouveau_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 = NOUVEAU_BUFFER_STATUS_USER_MEMORY; + + return &buffer->base; +} + +/* Like download, but for GART buffers. Merge ? */ +static INLINE boolean +nouveau_buffer_data_fetch(struct nv04_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 +nouveau_buffer_migrate(struct pipe_context *pipe, + struct nv04_resource *buf, const unsigned new_domain) +{ + struct nouveau_screen *screen = nouveau_screen(pipe->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 (!nouveau_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 nouveau_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 (!nouveau_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; + nouveau_buffer_allocate(screen, buf, new_domain); + + screen->copy_data(pipe, 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 (!nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM)) + return FALSE; + if (!nouveau_buffer_upload(pipe, 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 +nouveau_user_buffer_upload(struct nv04_resource *buf, + unsigned base, unsigned size) +{ + struct nouveau_screen *screen = nouveau_screen(buf->base.screen); + int ret; + + assert(buf->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY); + + buf->base.width0 = base + size; + if (!nouveau_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/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h new file mode 100644 index 00000000000..e0d75dcc9f9 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_buffer.h @@ -0,0 +1,137 @@ +#ifndef __NOUVEAU_RESOURCE_H__ +#define __NOUVEAU_RESOURCE_H__ + +#include "util/u_transfer.h" +#include "util/u_double_list.h" + +struct pipe_resource; +struct nouveau_bo; + +#define NOUVEAU_BUFFER_SCORE_MIN -25000 +#define NOUVEAU_BUFFER_SCORE_MAX 25000 +#define NOUVEAU_BUFFER_SCORE_VRAM_THRESHOLD 20000 + +/* 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 NOUVEAU_BUFFER_STATUS_DIRTY (1 << 0) +#define NOUVEAU_BUFFER_STATUS_USER_MEMORY (1 << 7) + +/* Resources, if mapped into the GPU's address space, are guaranteed to + * have constant virtual addresses (nv50+). + * + * 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 nv04_resource { + 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 nouveau_fence *fence; + struct nouveau_fence *fence_wr; + + struct nouveau_mm_allocation *mm; +}; + +void +nouveau_buffer_release_gpu_storage(struct nv04_resource *); + +boolean +nouveau_buffer_download(struct pipe_context *, struct nv04_resource *, + unsigned start, unsigned size); + +boolean +nouveau_buffer_migrate(struct pipe_context *, + struct nv04_resource *, unsigned domain); + +static INLINE void +nouveau_buffer_adjust_score(struct pipe_context *pipe, + struct nv04_resource *res, int16_t score) +{ + if (score < 0) { + if (res->score > NOUVEAU_BUFFER_SCORE_MIN) + res->score += score; + } else + if (score > 0){ + if (res->score < NOUVEAU_BUFFER_SCORE_MAX) + res->score += score; + if (res->domain == NOUVEAU_BO_GART && + res->score > NOUVEAU_BUFFER_SCORE_VRAM_THRESHOLD) + nouveau_buffer_migrate(pipe, res, NOUVEAU_BO_VRAM); + } +} + +/* XXX: wait for fence (atm only using this for vertex push) */ +static INLINE void * +nouveau_resource_map_offset(struct pipe_context *pipe, + struct nv04_resource *res, uint32_t offset, + uint32_t flags) +{ + void *map; + + nouveau_buffer_adjust_score(pipe, res, -250); + + if ((res->domain == NOUVEAU_BO_VRAM) && + (res->status & NOUVEAU_BUFFER_STATUS_DIRTY)) + nouveau_buffer_download(pipe, res, 0, res->base.width0); + + if ((res->domain != NOUVEAU_BO_GART) || + (res->status & NOUVEAU_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 +nouveau_resource_unmap(struct nv04_resource *res) +{ + /* no-op */ +} + +static INLINE struct nv04_resource * +nv04_resource(struct pipe_resource *resource) +{ + return (struct nv04_resource *)resource; +} + +/* is resource mapped into the GPU's address space (i.e. VRAM or GART) ? */ +static INLINE boolean +nouveau_resource_mapped_by_gpu(struct pipe_resource *resource) +{ + return nv04_resource(resource)->domain != 0; +} + +struct pipe_resource * +nouveau_buffer_create(struct pipe_screen *pscreen, + const struct pipe_resource *templ); + +struct pipe_resource * +nouveau_user_buffer_create(struct pipe_screen *screen, void *ptr, + unsigned bytes, unsigned usage); + +boolean +nouveau_user_buffer_upload(struct nv04_resource *, unsigned base, + unsigned size); + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index 173592d6ea7..c64b7b16ad2 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -5,6 +5,8 @@ #include "util/u_memory.h" typedef uint32_t u32; +struct nouveau_bo; + struct nouveau_screen { struct pipe_screen base; struct nouveau_device *device; @@ -27,6 +29,13 @@ struct nouveau_screen { struct nouveau_mman *mm_VRAM; struct nouveau_mman *mm_GART; + void (*copy_data)(struct pipe_context *, + struct nouveau_bo *dst, unsigned, unsigned, + struct nouveau_bo *src, unsigned, unsigned, + unsigned); + void (*push_data)(struct pipe_context *, + struct nouveau_bo *dst, unsigned, unsigned, + unsigned, void *); }; static INLINE struct nouveau_screen * diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 8dfb84a596f..484f870bd86 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -9,7 +9,6 @@ #include "nouveau/nouveau_device.h" #include "nouveau/nouveau_grobj.h" #include "nouveau/nouveau_notifier.h" -#include "nouveau/nouveau_resource.h" #ifndef NOUVEAU_NVC0 #include "nouveau/nv04_pushbuf.h" #endif diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index 2238aa1ad0e..dad912b2aee 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -18,6 +18,7 @@ #include "nouveau/nouveau_winsys.h" #include "nouveau/nouveau_gldefs.h" +#include "nouveau/nouveau_resource.h" #include "nv30-40_3d.xml.h" #include "nvfx_state.h" From 79079141fa7cbf395d1ffc77364ac301d9824211 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 12:26:20 +1000 Subject: [PATCH 10/53] nv50: move onto common linear buffer manager Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_buffer.h | 4 +- src/gallium/drivers/nv50/Makefile | 1 - src/gallium/drivers/nv50/nv50_buffer.c | 491 ------------------- src/gallium/drivers/nv50/nv50_context.c | 6 +- src/gallium/drivers/nv50/nv50_context.h | 10 +- src/gallium/drivers/nv50/nv50_push.c | 16 +- src/gallium/drivers/nv50/nv50_resource.c | 6 +- src/gallium/drivers/nv50/nv50_resource.h | 141 +----- src/gallium/drivers/nv50/nv50_screen.c | 2 + src/gallium/drivers/nv50/nv50_screen.h | 4 +- src/gallium/drivers/nv50/nv50_shader_state.c | 14 +- src/gallium/drivers/nv50/nv50_state.c | 3 +- src/gallium/drivers/nv50/nv50_tex.c | 7 +- src/gallium/drivers/nv50/nv50_transfer.c | 8 +- src/gallium/drivers/nv50/nv50_vbo.c | 41 +- src/gallium/drivers/nv50/nv50_winsys.h | 10 +- 16 files changed, 74 insertions(+), 690 deletions(-) delete mode 100644 src/gallium/drivers/nv50/nv50_buffer.c diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h index e0d75dcc9f9..d75bc4e0c38 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.h +++ b/src/gallium/drivers/nouveau/nouveau_buffer.h @@ -1,5 +1,5 @@ -#ifndef __NOUVEAU_RESOURCE_H__ -#define __NOUVEAU_RESOURCE_H__ +#ifndef __NOUVEAU_BUFFER_H__ +#define __NOUVEAU_BUFFER_H__ #include "util/u_transfer.h" #include "util/u_double_list.h" diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index dc9ea0eeba7..02bcc26cfb3 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -4,7 +4,6 @@ include $(TOP)/configs/current LIBNAME = nv50 C_SOURCES = \ - nv50_buffer.c \ nv50_context.c \ nv50_draw.c \ nv50_formats.c \ diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c deleted file mode 100644 index ae65591e7f2..00000000000 --- a/src/gallium/drivers/nv50/nv50_buffer.c +++ /dev/null @@ -1,491 +0,0 @@ - -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_math.h" - -#define NOUVEAU_NVC0 -#include "nouveau/nouveau_screen.h" -#include "nouveau/nouveau_winsys.h" -#include "nouveau/nouveau_mm.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 INLINE boolean -nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf, - unsigned domain) -{ - if (domain == NOUVEAU_BO_VRAM) { - buf->mm = nouveau_mm_allocate(screen->base.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 = nouveau_mm_allocate(screen->base.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; -} - -static INLINE void -release_allocation(struct nouveau_mm_allocation **mm, struct nouveau_fence *fence) -{ - nouveau_fence_work(fence, nouveau_mm_free_work, *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; -} - -static INLINE boolean -nv50_buffer_reallocate(struct nv50_screen *screen, struct nv50_resource *buf, - unsigned domain) -{ - nv50_buffer_release_gpu_storage(buf); - - 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); - - 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 nouveau_mm_allocation *mm; - struct nouveau_bo *bounce = NULL; - uint32_t offset; - - assert(buf->domain == NOUVEAU_BO_VRAM); - - mm = nouveau_mm_allocate(nv50->screen->base.mm_GART, size, &bounce, &offset); - if (!bounce) - return FALSE; - - 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) - nouveau_mm_free(mm); - return TRUE; -} - -static boolean -nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf, - unsigned start, unsigned size) -{ - struct nouveau_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 = nouveau_mm_allocate(nv50->screen->base.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->base.fence.current); - - if (start == 0 && size == buf->base.width0) - buf->status &= ~NV50_BUFFER_STATUS_DIRTY; - return TRUE; -} - -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; - } - - FREE(xfr); -} - -static INLINE boolean -nv50_buffer_sync(struct nv50_resource *buf, unsigned rw) -{ - if (rw == PIPE_TRANSFER_READ) { - if (!buf->fence_wr) - return TRUE; - if (!nouveau_fence_wait(buf->fence_wr)) - return FALSE; - } else { - if (!buf->fence) - return TRUE; - if (!nouveau_fence_wait(buf->fence)) - return FALSE; - - nouveau_fence_ref(NULL, &buf->fence); - } - nouveau_fence_ref(NULL, &buf->fence_wr); - - return TRUE; -} - -static INLINE boolean -nv50_buffer_busy(struct nv50_resource *buf, unsigned rw) -{ - if (rw == PIPE_TRANSFER_READ) - return (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr)); - else - return (buf->fence && !nouveau_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 *templ) -{ - struct nv50_screen *screen = nv50_screen(pscreen); - struct nv50_resource *buffer; - boolean ret; - - buffer = CALLOC_STRUCT(nv50_resource); - if (!buffer) - return NULL; - - buffer->base = *templ; - buffer->vtbl = &nv50_buffer_vtbl; - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = pscreen; - - 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 (ret == FALSE) - goto fail; - - return &buffer->base; - -fail: - 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->data = ptr; - buffer->status = NV50_BUFFER_STATUS_USER_MEMORY; - - return &buffer->base; -} - -/* 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 nouveau_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->base.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_context.c b/src/gallium/drivers/nv50/nv50_context.c index 4380945a1ee..03a5c3d2d91 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -119,13 +119,13 @@ nv50_create(struct pipe_screen *pscreen, void *priv) } struct resident { - struct nv50_resource *res; + struct nv04_resource *res; uint32_t flags; }; void nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx, - struct nv50_resource *resource, uint32_t flags) + struct nv04_resource *resource, uint32_t flags) { struct resident rsd = { resource, flags }; @@ -140,7 +140,7 @@ nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx, void nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx, - struct nv50_resource *resource) + struct nv04_resource *resource) { struct resident *rsd, *top; unsigned i; diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index a6275d79587..55d996da27f 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -155,9 +155,9 @@ void nv50_default_flush_notify(struct nouveau_channel *); void nv50_bufctx_emit_relocs(struct nv50_context *); void nv50_bufctx_add_resident(struct nv50_context *, int ctx, - struct nv50_resource *, uint32_t flags); + struct nv04_resource *, uint32_t flags); void nv50_bufctx_del_resident(struct nv50_context *, int ctx, - struct nv50_resource *); + struct nv04_resource *); static INLINE void nv50_bufctx_reset(struct nv50_context *nv50, int ctx) { @@ -204,11 +204,11 @@ nv50_create_sampler_view(struct pipe_context *, /* nv50_transfer.c */ void -nv50_sifc_linear_u8(struct nv50_context *nv50, - struct nouveau_bo *dst, unsigned domain, int offset, +nv50_sifc_linear_u8(struct pipe_context *pipe, + struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data); void -nv50_m2mf_copy_linear(struct nv50_context *nv50, +nv50_m2mf_copy_linear(struct pipe_context *pipe, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size); diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c index 51ada6d7499..07034bdcf62 100644 --- a/src/gallium/drivers/nv50/nv50_push.c +++ b/src/gallium/drivers/nv50/nv50_push.c @@ -227,10 +227,10 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) 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); + struct nv04_resource *res = nv04_resource(vb->buffer); - data = nv50_resource_map_offset(nv50, res, - vb->buffer_offset, NOUVEAU_BO_RD); + data = nouveau_resource_map_offset(&nv50->pipe, res, + vb->buffer_offset, NOUVEAU_BO_RD); if (apply_bias && likely(!(nv50->vertex->instance_bufs & (1 << i)))) data += info->index_bias * vb->stride; @@ -239,9 +239,9 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) } if (info->indexed) { - ctx.idxbuf = nv50_resource_map_offset(nv50, - nv50_resource(nv50->idxbuf.buffer), - nv50->idxbuf.offset, NOUVEAU_BO_RD); + ctx.idxbuf = nouveau_resource_map_offset(&nv50->pipe, + nv04_resource(nv50->idxbuf.buffer), + nv50->idxbuf.offset, NOUVEAU_BO_RD); if (!ctx.idxbuf) return; index_size = nv50->idxbuf.index_size; @@ -285,8 +285,8 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) } if (info->indexed) - nv50_resource_unmap(nv50_resource(nv50->idxbuf.buffer)); + nouveau_resource_unmap(nv04_resource(nv50->idxbuf.buffer)); for (i = 0; i < nv50->num_vtxbufs; ++i) - nv50_resource_unmap(nv50_resource(nv50->vtxbuf[i].buffer)); + nouveau_resource_unmap(nv04_resource(nv50->vtxbuf[i].buffer)); } diff --git a/src/gallium/drivers/nv50/nv50_resource.c b/src/gallium/drivers/nv50/nv50_resource.c index ae1a2bf55da..2a2fb0e32bc 100644 --- a/src/gallium/drivers/nv50/nv50_resource.c +++ b/src/gallium/drivers/nv50/nv50_resource.c @@ -8,7 +8,7 @@ nv50_resource_is_referenced(struct pipe_context *pipe, struct pipe_resource *resource, unsigned face, int layer) { - struct nv50_resource *res = nv50_resource(resource); + struct nv04_resource *res = nv04_resource(resource); unsigned flags = 0; unsigned bo_flags = nouveau_bo_pending(res->bo); @@ -26,7 +26,7 @@ nv50_resource_create(struct pipe_screen *screen, { switch (templ->target) { case PIPE_BUFFER: - return nv50_buffer_create(screen, templ); + return nouveau_buffer_create(screen, templ); default: return nv50_miptree_create(screen, templ); } @@ -64,5 +64,5 @@ nv50_screen_init_resource_functions(struct pipe_screen *pscreen) 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->user_buffer_create = nouveau_user_buffer_create; } diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h index 64563421fd0..76229298f7c 100644 --- a/src/gallium/drivers/nv50/nv50_resource.h +++ b/src/gallium/drivers/nv50/nv50_resource.h @@ -6,112 +6,14 @@ #include "util/u_double_list.h" #define NOUVEAU_NVC0 #include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_buffer.h" #undef NOUVEAU_NVC0 -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 - -/* 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; - - 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 nouveau_fence *fence; - struct nouveau_fence *fence_wr; - - struct nouveau_mm_allocation *mm; -}; +void +nv50_init_resource_functions(struct pipe_context *pcontext); 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 */ -} +nv50_screen_init_resource_functions(struct pipe_screen *pscreen); #define NV50_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf) @@ -133,7 +35,7 @@ struct nv50_miptree_level { #define NV50_MAX_TEXTURE_LEVELS 16 struct nv50_miptree { - struct nv50_resource base; + struct nv04_resource base; struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS]; uint32_t total_size; uint32_t layer_stride; @@ -146,25 +48,6 @@ nv50_miptree(struct pipe_resource *pt) return (struct nv50_miptree *)pt; } -static INLINE struct nv50_resource * -nv50_resource(struct pipe_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)->domain != 0; -} - -void -nv50_init_resource_functions(struct pipe_context *pcontext); - -void -nv50_screen_init_resource_functions(struct pipe_screen *pscreen); - /* Internal functions: */ struct pipe_resource * @@ -176,17 +59,6 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen, const struct pipe_resource *template, struct winsys_handle *whandle); -struct pipe_resource * -nv50_buffer_create(struct pipe_screen *pscreen, - const struct pipe_resource *templ); - -struct pipe_resource * -nv50_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes, - unsigned usage); - - struct pipe_surface * nv50_miptree_surface_new(struct pipe_context *, struct pipe_resource *, @@ -195,7 +67,4 @@ nv50_miptree_surface_new(struct pipe_context *, void 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 f2b03e8156e..13c03b1a7e6 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -310,6 +310,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART; + screen->base.copy_data = nv50_m2mf_copy_linear; + screen->base.push_data = nv50_sifc_linear_u8; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 3bf67eb656b..eb9743a05d0 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -73,7 +73,7 @@ int nv50_screen_tic_alloc(struct nv50_screen *, void *); int nv50_screen_tsc_alloc(struct nv50_screen *, void *); static INLINE void -nv50_resource_fence(struct nv50_resource *res, uint32_t flags) +nv50_resource_fence(struct nv04_resource *res, uint32_t flags) { struct nv50_screen *screen = nv50_screen(res->base.screen); @@ -86,7 +86,7 @@ nv50_resource_fence(struct nv50_resource *res, uint32_t flags) } static INLINE void -nv50_resource_validate(struct nv50_resource *res, uint32_t flags) +nv50_resource_validate(struct nv04_resource *res, uint32_t flags) { struct nv50_screen *screen = nv50_screen(res->base.screen); diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index e530b3390a9..2d7572820f2 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -35,7 +35,7 @@ nv50_constbufs_validate(struct nv50_context *nv50) unsigned s; for (s = 0; s < 3; ++s) { - struct nv50_resource *res; + struct nv04_resource *res; int i; unsigned p, b; @@ -55,7 +55,7 @@ nv50_constbufs_validate(struct nv50_context *nv50) i = ffs(nv50->constbuf_dirty[s]) - 1; nv50->constbuf_dirty[s] &= ~(1 << i); - res = nv50_resource(nv50->constbuf[s][i]); + res = nv04_resource(nv50->constbuf[s][i]); if (!res) { if (i != 0) { BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1); @@ -75,8 +75,8 @@ nv50_constbufs_validate(struct nv50_context *nv50) assert(0); - if (!nv50_resource_mapped_by_gpu(&res->base)) { - nv50_buffer_migrate(nv50, res, NOUVEAU_BO_VRAM); + if (!nouveau_resource_mapped_by_gpu(&res->base)) { + nouveau_buffer_migrate(&nv50->pipe, res, NOUVEAU_BO_VRAM); BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1); OUT_RING (chan, 0); @@ -149,9 +149,9 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) return FALSE; prog->code_base = prog->res->start; - nv50_sifc_linear_u8(nv50, nv50->screen->code, NOUVEAU_BO_VRAM, - (prog->type << 16) + prog->code_base, prog->code_size, - prog->code); + nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->code, + (prog->type << 16) + prog->code_base, + NOUVEAU_BO_VRAM, prog->code_size, prog->code); BEGIN_RING(nv50->screen->base.channel, RING_3D(CODE_CB_FLUSH), 1); OUT_RING (nv50->screen->base.channel, 0); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 5e1fff46e41..ed2fd3b0f88 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -651,8 +651,7 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, if (nv50->constbuf[shader][index]) nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT, - nv50_resource( - nv50->constbuf[shader][index])); + nv04_resource(nv50->constbuf[shader][index])); pipe_resource_reference(&nv50->constbuf[shader][index], res); diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 93e74ca0597..eaee0a1107f 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -168,7 +168,7 @@ nv50_validate_tic(struct nv50_context *nv50, int s) 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; + struct nv04_resource *res; if (!tic) { BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); @@ -261,8 +261,9 @@ nv50_validate_tsc(struct nv50_context *nv50, int s) 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); + nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->txc, + 65536 + tsc->id * 32, + NOUVEAU_BO_VRAM, 32, tsc->tsc); need_flush = TRUE; } nv50->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index 696350d10c8..d80a5354904 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -102,10 +102,11 @@ nv50_m2mf_transfer_rect(struct pipe_screen *pscreen, } void -nv50_sifc_linear_u8(struct nv50_context *nv50, - struct nouveau_bo *dst, unsigned domain, int offset, +nv50_sifc_linear_u8(struct pipe_context *pipe, + struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data) { + struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_channel *chan = nv50->screen->base.channel; uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; @@ -158,11 +159,12 @@ nv50_sifc_linear_u8(struct nv50_context *nv50, } void -nv50_m2mf_copy_linear(struct nv50_context *nv50, +nv50_m2mf_copy_linear(struct pipe_context *pipe, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size) { + struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_channel *chan = nv50->screen->base.channel; BEGIN_RING(chan, RING_MF(LINEAR_IN), 1); diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index d18b2dffd1d..1f0d34ed792 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -127,12 +127,12 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb, { const void *data; struct nouveau_channel *chan = nv50->screen->base.channel; - struct nv50_resource *res = nv50_resource(vb->buffer); + struct nv04_resource *res = nv04_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); + data = nouveau_resource_map_offset(&nv50->pipe, 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); @@ -189,7 +189,7 @@ static void nv50_prevalidate_vbufs(struct nv50_context *nv50) { struct pipe_vertex_buffer *vb; - struct nv50_resource *buf; + struct nv04_resource *buf; int i; uint32_t base, size; @@ -201,27 +201,27 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50) vb = &nv50->vtxbuf[i]; if (!vb->stride) continue; - buf = nv50_resource(vb->buffer); + buf = nv04_resource(vb->buffer); /* NOTE: user buffers with temporary storage count as mapped by GPU */ - if (!nv50_resource_mapped_by_gpu(vb->buffer)) { + if (!nouveau_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) { + if (buf->status & NOUVEAU_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); + nouveau_user_buffer_upload(buf, base, size); } else { - nv50_buffer_migrate(nv50, buf, NOUVEAU_BO_GART); + nouveau_buffer_migrate(&nv50->pipe, 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); + nouveau_buffer_adjust_score(&nv50->pipe, buf, 1); } } @@ -237,7 +237,7 @@ nv50_update_user_vbufs(struct nv50_context *nv50) 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); + struct nv04_resource *buf = nv04_resource(vb->buffer); if (!(nv50->vbo_user & (1 << b))) continue; @@ -250,7 +250,7 @@ nv50_update_user_vbufs(struct nv50_context *nv50) if (!(written & (1 << b))) { written |= 1 << b; - nv50_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(buf, base, size); } offset = vb->buffer_offset + ve->src_offset; @@ -274,7 +274,7 @@ nv50_release_user_vbufs(struct nv50_context *nv50) int i = ffs(vbo_user) - 1; vbo_user &= ~(1 << i); - nv50_buffer_release_gpu_storage(nv50_resource(nv50->vtxbuf[i].buffer)); + nouveau_buffer_release_gpu_storage(nv04_resource(nv50->vtxbuf[i].buffer)); } } @@ -308,7 +308,7 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50) } for (i = 0; i < vertex->num_elements; ++i) { - struct nv50_resource *res; + struct nv04_resource *res; unsigned size, offset; ve = &vertex->element[i]; @@ -327,7 +327,7 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50) OUT_RING (chan, 0); } - res = nv50_resource(vb->buffer); + res = nv04_resource(vb->buffer); if (nv50->vbo_fifo || unlikely(vb->stride == 0)) { if (!nv50->vbo_fifo) @@ -536,11 +536,11 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, 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); + if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer) && 0) { + struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer); unsigned offset = res->offset + nv50->idxbuf.offset; - nv50_buffer_adjust_score(nv50, res, 1); + nouveau_buffer_adjust_score(&nv50->pipe, res, 1); while (instance_count--) { BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); @@ -597,8 +597,9 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, 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); + data = nouveau_resource_map_offset(&nv50->pipe, + nv04_resource(nv50->idxbuf.buffer), + nv50->idxbuf.offset, NOUVEAU_BO_RD); if (!data) return; diff --git a/src/gallium/drivers/nv50/nv50_winsys.h b/src/gallium/drivers/nv50/nv50_winsys.h index 8aaf24c0093..35e79210a66 100644 --- a/src/gallium/drivers/nv50/nv50_winsys.h +++ b/src/gallium/drivers/nv50/nv50_winsys.h @@ -4,6 +4,7 @@ #include #include + #include "pipe/p_defines.h" #include "nouveau/nouveau_bo.h" @@ -13,8 +14,9 @@ #include "nouveau/nouveau_resource.h" #include "nouveau/nouveau_pushbuf.h" #include "nouveau/nouveau_reloc.h" +#include "nouveau/nouveau_notifier.h" -#include "nv50_resource.h" /* OUT_RESRC */ +#include "nouveau/nouveau_buffer.h" #ifndef NV04_PFIFO_MAX_PACKET_LEN #define NV04_PFIFO_MAX_PACKET_LEN 2047 @@ -68,18 +70,18 @@ BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size) } static INLINE int -OUT_RESRCh(struct nouveau_channel *chan, struct nv50_resource *res, +OUT_RESRCh(struct nouveau_channel *chan, struct nv04_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, +OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res, unsigned delta, unsigned flags) { if (flags & NOUVEAU_BO_WR) - res->status |= NV50_BUFFER_STATUS_DIRTY; + res->status |= NOUVEAU_BUFFER_STATUS_DIRTY; return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags); } From be68782d9aebf6f6575bb8cc9cfc66b7bad79644 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 13:09:41 +1000 Subject: [PATCH 11/53] nv50: sync textures with render targets ourselves Port of the nvc0 commit doing the same. Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_buffer.c | 6 +++--- src/gallium/drivers/nouveau/nouveau_buffer.h | 5 +++-- src/gallium/drivers/nv50/nv50_3d.xml.h | 2 +- src/gallium/drivers/nv50/nv50_screen.h | 5 +++++ src/gallium/drivers/nv50/nv50_state_validate.c | 16 ++++++++++++++++ src/gallium/drivers/nv50/nv50_tex.c | 8 ++++++++ src/gallium/drivers/nv50/nv50_winsys.h | 2 +- 7 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index 4f4b24fdd21..efb16824e46 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -112,7 +112,7 @@ nouveau_buffer_download(struct pipe_context *pipe, struct nv04_resource *buf, memcpy(buf->data + start, bounce->map, size); nouveau_bo_unmap(bounce); - buf->status &= ~NOUVEAU_BUFFER_STATUS_DIRTY; + buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; nouveau_bo_ref(NULL, &bounce); if (mm) @@ -152,7 +152,7 @@ nouveau_buffer_upload(struct pipe_context *pipe, struct nv04_resource *buf, release_allocation(&mm, screen->fence.current); if (start == 0 && size == buf->base.width0) - buf->status &= ~NOUVEAU_BUFFER_STATUS_DIRTY; + buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; return TRUE; } @@ -174,7 +174,7 @@ nouveau_buffer_transfer_get(struct pipe_context *pipe, if (buf->domain == NOUVEAU_BO_VRAM) { if (usage & PIPE_TRANSFER_READ) { - if (buf->status & NOUVEAU_BUFFER_STATUS_DIRTY) + if (buf->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) nouveau_buffer_download(pipe, buf, 0, buf->base.width0); } } diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h index d75bc4e0c38..c3e0c2cf924 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.h +++ b/src/gallium/drivers/nouveau/nouveau_buffer.h @@ -17,7 +17,8 @@ struct nouveau_bo; * USER_MEMORY: resource->data is a pointer to client memory and may change * between GL calls */ -#define NOUVEAU_BUFFER_STATUS_DIRTY (1 << 0) +#define NOUVEAU_BUFFER_STATUS_GPU_READING (1 << 0) +#define NOUVEAU_BUFFER_STATUS_GPU_WRITING (1 << 1) #define NOUVEAU_BUFFER_STATUS_USER_MEMORY (1 << 7) /* Resources, if mapped into the GPU's address space, are guaranteed to @@ -84,7 +85,7 @@ nouveau_resource_map_offset(struct pipe_context *pipe, nouveau_buffer_adjust_score(pipe, res, -250); if ((res->domain == NOUVEAU_BO_VRAM) && - (res->status & NOUVEAU_BUFFER_STATUS_DIRTY)) + (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING)) nouveau_buffer_download(pipe, res, 0, res->base.width0); if ((res->domain != NOUVEAU_BO_GART) || diff --git a/src/gallium/drivers/nv50/nv50_3d.xml.h b/src/gallium/drivers/nv50/nv50_3d.xml.h index eb05bd40951..9bb3211728c 100644 --- a/src/gallium/drivers/nv50/nv50_3d.xml.h +++ b/src/gallium/drivers/nv50/nv50_3d.xml.h @@ -74,7 +74,7 @@ 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_SERIALIZE 0x00000110 #define NV50_3D_DMA_NOTIFY 0x00000180 diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index eb9743a05d0..3886d8068cc 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -93,6 +93,11 @@ nv50_resource_validate(struct nv04_resource *res, uint32_t flags) if (likely(res->bo)) { nouveau_bo_validate(screen->base.channel, res->bo, flags); + if (flags & NOUVEAU_BO_WR) + res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + if (flags & NOUVEAU_BO_RD) + res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; + nv50_resource_fence(res, flags); } } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index a8f48b2a28e..c97927624e4 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -8,6 +8,7 @@ nv50_validate_fb(struct nv50_context *nv50) struct nouveau_channel *chan = nv50->screen->base.channel; struct pipe_framebuffer_state *fb = &nv50->framebuffer; unsigned i; + boolean serialize = FALSE; nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME); @@ -37,6 +38,11 @@ nv50_validate_fb(struct nv50_context *nv50) BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); OUT_RING (chan, sf->depth); + if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) + serialize = TRUE; + mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING; + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); } @@ -62,6 +68,11 @@ nv50_validate_fb(struct nv50_context *nv50) OUT_RING (chan, sf->height); OUT_RING (chan, (unk << 16) | sf->depth); + if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) + serialize = TRUE; + mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING; + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); } else { @@ -72,6 +83,11 @@ nv50_validate_fb(struct nv50_context *nv50) BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2); OUT_RING (chan, fb->width << 16); OUT_RING (chan, fb->height << 16); + + if (serialize) { + BEGIN_RING(chan, RING_3D(SERIALIZE), 1); + OUT_RING (chan, 0); + } } static void diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index eaee0a1107f..a76139ad37e 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -212,9 +212,17 @@ nv50_validate_tic(struct nv50_context *nv50, int s) OUT_RINGp (chan, &tic->tic[3], 5); need_flush = TRUE; + } else + if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { + BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); + OUT_RING (chan, 0x20); //(tic->id << 4) | 1); } + nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); + res->status &= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; + nv50_bufctx_add_resident(nv50, NV50_BUFCTX_TEXTURES, res, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); diff --git a/src/gallium/drivers/nv50/nv50_winsys.h b/src/gallium/drivers/nv50/nv50_winsys.h index 35e79210a66..afa2a00c7a2 100644 --- a/src/gallium/drivers/nv50/nv50_winsys.h +++ b/src/gallium/drivers/nv50/nv50_winsys.h @@ -81,7 +81,7 @@ OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res, unsigned delta, unsigned flags) { if (flags & NOUVEAU_BO_WR) - res->status |= NOUVEAU_BUFFER_STATUS_DIRTY; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags); } From 40d7a87a8ee774655e77d45cb1a8070dbae62537 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 13:11:26 +1000 Subject: [PATCH 12/53] nv50: multiply polygon offset units by 2 Signed-off-by: Ben Skeggs --- src/gallium/drivers/nv50/nv50_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index ed2fd3b0f88..6b1106341ce 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -234,7 +234,7 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, 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 ? */ + SB_DATA (so, fui(cso->offset_units * 2.0f)); } assert(so->size < (sizeof(so->state) / sizeof(so->state[0]))); From 4826cd0f6125b071530026143ffd8205d84b3d5e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 13:38:10 +1000 Subject: [PATCH 13/53] nvc0: port to common fence/mm/buffer code Signed-off-by: Ben Skeggs --- src/gallium/drivers/nvc0/Makefile | 3 - src/gallium/drivers/nvc0/nvc0_buffer.c | 494 ------------------ src/gallium/drivers/nvc0/nvc0_context.c | 14 +- src/gallium/drivers/nvc0/nvc0_context.h | 10 +- src/gallium/drivers/nvc0/nvc0_fence.c | 210 -------- src/gallium/drivers/nvc0/nvc0_fence.h | 49 -- src/gallium/drivers/nvc0/nvc0_mm.c | 274 ---------- src/gallium/drivers/nvc0/nvc0_push.c | 16 +- src/gallium/drivers/nvc0/nvc0_query.c | 8 +- src/gallium/drivers/nvc0/nvc0_resource.c | 6 +- src/gallium/drivers/nvc0/nvc0_resource.h | 145 +---- src/gallium/drivers/nvc0/nvc0_screen.c | 69 ++- src/gallium/drivers/nvc0/nvc0_screen.h | 70 +-- src/gallium/drivers/nvc0/nvc0_shader_state.c | 10 +- src/gallium/drivers/nvc0/nvc0_state.c | 3 +- .../drivers/nvc0/nvc0_state_validate.c | 18 +- src/gallium/drivers/nvc0/nvc0_surface.c | 6 +- src/gallium/drivers/nvc0/nvc0_tex.c | 13 +- src/gallium/drivers/nvc0/nvc0_transfer.c | 8 +- src/gallium/drivers/nvc0/nvc0_vbo.c | 43 +- src/gallium/drivers/nvc0/nvc0_winsys.h | 6 +- 21 files changed, 128 insertions(+), 1347 deletions(-) delete mode 100644 src/gallium/drivers/nvc0/nvc0_buffer.c delete mode 100644 src/gallium/drivers/nvc0/nvc0_fence.c delete mode 100644 src/gallium/drivers/nvc0/nvc0_fence.h delete mode 100644 src/gallium/drivers/nvc0/nvc0_mm.c diff --git a/src/gallium/drivers/nvc0/Makefile b/src/gallium/drivers/nvc0/Makefile index 54f1ab7fa93..e1cd188eec5 100644 --- a/src/gallium/drivers/nvc0/Makefile +++ b/src/gallium/drivers/nvc0/Makefile @@ -4,7 +4,6 @@ include $(TOP)/configs/current LIBNAME = nvc0 C_SOURCES = \ - nvc0_buffer.c \ nvc0_context.c \ nvc0_draw.c \ nvc0_formats.c \ @@ -27,8 +26,6 @@ C_SOURCES = \ nvc0_pc_regalloc.c \ nvc0_push.c \ nvc0_push2.c \ - nvc0_fence.c \ - nvc0_mm.c \ nvc0_query.c LIBRARY_INCLUDES = \ diff --git a/src/gallium/drivers/nvc0/nvc0_buffer.c b/src/gallium/drivers/nvc0/nvc0_buffer.c deleted file mode 100644 index aa949bdfa36..00000000000 --- a/src/gallium/drivers/nvc0/nvc0_buffer.c +++ /dev/null @@ -1,494 +0,0 @@ - -#include "util/u_inlines.h" -#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 "nvc0_context.h" -#include "nvc0_resource.h" - -struct nvc0_transfer { - struct pipe_transfer base; -}; - -static INLINE struct nvc0_transfer * -nvc0_transfer(struct pipe_transfer *transfer) -{ - return (struct nvc0_transfer *)transfer; -} - -static INLINE boolean -nvc0_buffer_allocate(struct nvc0_screen *screen, struct nvc0_resource *buf, - unsigned domain) -{ - if (domain == NOUVEAU_BO_VRAM) { - buf->mm = nvc0_mm_allocate(screen->mm_VRAM, buf->base.width0, &buf->bo, - &buf->offset); - if (!buf->bo) - return nvc0_buffer_allocate(screen, buf, NOUVEAU_BO_GART); - } else - if (domain == NOUVEAU_BO_GART) { - buf->mm = nvc0_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; -} - -static INLINE void -release_allocation(struct nvc0_mm_allocation **mm, struct nvc0_fence *fence) -{ - if (fence && fence->state != NVC0_FENCE_STATE_SIGNALLED) { - nvc0_fence_sched_release(fence, *mm); - } else { - nvc0_mm_free(*mm); - } - (*mm) = NULL; -} - -INLINE void -nvc0_buffer_release_gpu_storage(struct nvc0_resource *buf) -{ - nouveau_bo_ref(NULL, &buf->bo); - - if (buf->mm) - release_allocation(&buf->mm, buf->fence); - - buf->domain = 0; -} - -static INLINE boolean -nvc0_buffer_reallocate(struct nvc0_screen *screen, struct nvc0_resource *buf, - unsigned domain) -{ - nvc0_buffer_release_gpu_storage(buf); - - return nvc0_buffer_allocate(screen, buf, domain); -} - -static void -nvc0_buffer_destroy(struct pipe_screen *pscreen, - struct pipe_resource *presource) -{ - struct nvc0_resource *res = nvc0_resource(presource); - - nvc0_buffer_release_gpu_storage(res); - - if (res->data && !(res->status & NVC0_BUFFER_STATUS_USER_MEMORY)) - FREE(res->data); - - FREE(res); -} - -/* Maybe just migrate to GART right away if we actually need to do this. */ -boolean -nvc0_buffer_download(struct nvc0_context *nvc0, struct nvc0_resource *buf, - unsigned start, unsigned size) -{ - struct nvc0_mm_allocation *mm; - struct nouveau_bo *bounce = NULL; - uint32_t offset; - - assert(buf->domain == NOUVEAU_BO_VRAM); - - mm = nvc0_mm_allocate(nvc0->screen->mm_GART, size, &bounce, &offset); - if (!bounce) - return FALSE; - - nvc0_m2mf_copy_linear(nvc0, 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 &= ~NVC0_BUFFER_STATUS_GPU_WRITING; - - nouveau_bo_ref(NULL, &bounce); - if (mm) - nvc0_mm_free(mm); - return TRUE; -} - -static boolean -nvc0_buffer_upload(struct nvc0_context *nvc0, struct nvc0_resource *buf, - unsigned start, unsigned size) -{ - struct nvc0_mm_allocation *mm; - struct nouveau_bo *bounce = NULL; - uint32_t offset; - - if (size <= 192) { - nvc0_m2mf_push_linear(nvc0, buf->bo, buf->domain, buf->offset + start, - size, buf->data + start); - return TRUE; - } - - mm = nvc0_mm_allocate(nvc0->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); - - nvc0_m2mf_copy_linear(nvc0, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, - bounce, offset, NOUVEAU_BO_GART, size); - - nouveau_bo_ref(NULL, &bounce); - if (mm) - release_allocation(&mm, nvc0->screen->fence.current); - - if (start == 0 && size == buf->base.width0) - buf->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING; - return TRUE; -} - -static struct pipe_transfer * -nvc0_buffer_transfer_get(struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, - unsigned usage, - const struct pipe_box *box) -{ - struct nvc0_resource *buf = nvc0_resource(resource); - struct nvc0_transfer *xfr = CALLOC_STRUCT(nvc0_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 & NVC0_BUFFER_STATUS_GPU_WRITING) - nvc0_buffer_download(nvc0_context(pipe), buf, 0, buf->base.width0); - } - } - - return &xfr->base; -} - -static void -nvc0_buffer_transfer_destroy(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct nvc0_resource *buf = nvc0_resource(transfer->resource); - struct nvc0_transfer *xfr = nvc0_transfer(transfer); - - if (xfr->base.usage & PIPE_TRANSFER_WRITE) { - /* writing is worse */ - nvc0_buffer_adjust_score(nvc0_context(pipe), buf, -5000); - - if (buf->domain == NOUVEAU_BO_VRAM) { - nvc0_buffer_upload(nvc0_context(pipe), buf, - transfer->box.x, transfer->box.width); - } - - if (buf->domain != 0 && (buf->base.bind & (PIPE_BIND_VERTEX_BUFFER | - PIPE_BIND_INDEX_BUFFER))) - nvc0_context(pipe)->vbo_dirty = TRUE; - } - - FREE(xfr); -} - -static INLINE boolean -nvc0_buffer_sync(struct nvc0_resource *buf, unsigned rw) -{ - if (rw == PIPE_TRANSFER_READ) { - if (!buf->fence_wr) - return TRUE; - if (!nvc0_fence_wait(buf->fence_wr)) - return FALSE; - } else { - if (!buf->fence) - return TRUE; - if (!nvc0_fence_wait(buf->fence)) - return FALSE; - - nvc0_fence_reference(&buf->fence, NULL); - } - nvc0_fence_reference(&buf->fence_wr, NULL); - - return TRUE; -} - -static INLINE boolean -nvc0_buffer_busy(struct nvc0_resource *buf, unsigned rw) -{ - if (rw == PIPE_TRANSFER_READ) - return (buf->fence_wr && !nvc0_fence_signalled(buf->fence_wr)); - else - return (buf->fence && !nvc0_fence_signalled(buf->fence)); -} - -static void * -nvc0_buffer_transfer_map(struct pipe_context *pipe, - struct pipe_transfer *transfer) -{ - struct nvc0_transfer *xfr = nvc0_transfer(transfer); - struct nvc0_resource *buf = nvc0_resource(transfer->resource); - struct nouveau_bo *bo = buf->bo; - uint8_t *map; - int ret; - uint32_t offset = xfr->base.box.x; - uint32_t flags; - - nvc0_buffer_adjust_score(nvc0_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 (nvc0_buffer_busy(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE)) - return NULL; - } else - if (!(xfr->base.usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { - nvc0_buffer_sync(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE); - } - } - return map; -} - - - -static void -nvc0_buffer_transfer_flush_region(struct pipe_context *pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) -{ - struct nvc0_resource *res = nvc0_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 -nvc0_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 nvc0_buffer_vtbl = -{ - u_default_resource_get_handle, /* get_handle */ - nvc0_buffer_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ - nvc0_buffer_transfer_get, /* get_transfer */ - nvc0_buffer_transfer_destroy, /* transfer_destroy */ - nvc0_buffer_transfer_map, /* transfer_map */ - nvc0_buffer_transfer_flush_region, /* transfer_flush_region */ - nvc0_buffer_transfer_unmap, /* transfer_unmap */ - u_default_transfer_inline_write /* transfer_inline_write */ -}; - -struct pipe_resource * -nvc0_buffer_create(struct pipe_screen *pscreen, - const struct pipe_resource *templ) -{ - struct nvc0_screen *screen = nvc0_screen(pscreen); - struct nvc0_resource *buffer; - boolean ret; - - buffer = CALLOC_STRUCT(nvc0_resource); - if (!buffer) - return NULL; - - buffer->base = *templ; - buffer->vtbl = &nvc0_buffer_vtbl; - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = pscreen; - - if (buffer->base.bind & PIPE_BIND_CONSTANT_BUFFER) - ret = nvc0_buffer_allocate(screen, buffer, 0); - else - ret = nvc0_buffer_allocate(screen, buffer, NOUVEAU_BO_GART); - - if (ret == FALSE) - goto fail; - - return &buffer->base; - -fail: - FREE(buffer); - return NULL; -} - - -struct pipe_resource * -nvc0_user_buffer_create(struct pipe_screen *pscreen, - void *ptr, - unsigned bytes, - unsigned bind) -{ - struct nvc0_resource *buffer; - - buffer = CALLOC_STRUCT(nvc0_resource); - if (!buffer) - return NULL; - - pipe_reference_init(&buffer->base.reference, 1); - buffer->vtbl = &nvc0_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 = NVC0_BUFFER_STATUS_USER_MEMORY; - - return &buffer->base; -} - -/* Like download, but for GART buffers. Merge ? */ -static INLINE boolean -nvc0_buffer_data_fetch(struct nvc0_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 -nvc0_buffer_migrate(struct nvc0_context *nvc0, - struct nvc0_resource *buf, const unsigned new_domain) -{ - struct nvc0_screen *screen = nvc0_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 (!nvc0_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 nvc0_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 (!nvc0_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; - nvc0_buffer_allocate(screen, buf, new_domain); - - nvc0_m2mf_copy_linear(nvc0, 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 (!nvc0_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM)) - return FALSE; - if (!nvc0_buffer_upload(nvc0, 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 -nvc0_user_buffer_upload(struct nvc0_resource *buf, unsigned base, unsigned size) -{ - struct nvc0_screen *screen = nvc0_screen(buf->base.screen); - int ret; - - assert(buf->status & NVC0_BUFFER_STATUS_USER_MEMORY); - - buf->base.width0 = base + size; - if (!nvc0_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/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index ebdf5f2f9e8..4979aab51c4 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -48,8 +48,8 @@ nvc0_flush(struct pipe_context *pipe, unsigned flags, } if (fence) - nvc0_fence_reference((struct nvc0_fence **)fence, - nvc0->screen->fence.current); + nouveau_fence_ref(nvc0->screen->base.fence.current, + (struct nouveau_fence **)fence); if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME)) FIRE_RING(chan); @@ -73,9 +73,9 @@ nvc0_default_flush_notify(struct nouveau_channel *chan) { struct nvc0_context *nvc0 = chan->user_private; - nvc0_screen_fence_update(nvc0->screen, TRUE); + nouveau_fence_update(&nvc0->screen->base, TRUE); - nvc0_screen_fence_next(nvc0->screen); + nouveau_fence_next(&nvc0->screen->base); } struct pipe_context * @@ -119,13 +119,13 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) } struct resident { - struct nvc0_resource *res; + struct nv04_resource *res; uint32_t flags; }; void nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx, - struct nvc0_resource *resource, uint32_t flags) + struct nv04_resource *resource, uint32_t flags) { struct resident rsd = { resource, flags }; @@ -140,7 +140,7 @@ nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx, void nvc0_bufctx_del_resident(struct nvc0_context *nvc0, int ctx, - struct nvc0_resource *resource) + struct nv04_resource *resource) { struct resident *rsd, *top; unsigned i; diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index 1ce5554f7b7..d779777ed3a 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -161,9 +161,9 @@ void nvc0_default_flush_notify(struct nouveau_channel *); void nvc0_bufctx_emit_relocs(struct nvc0_context *); void nvc0_bufctx_add_resident(struct nvc0_context *, int ctx, - struct nvc0_resource *, uint32_t flags); + struct nv04_resource *, uint32_t flags); void nvc0_bufctx_del_resident(struct nvc0_context *, int ctx, - struct nvc0_resource *); + struct nv04_resource *); static INLINE void nvc0_bufctx_reset(struct nvc0_context *nvc0, int ctx) { @@ -211,11 +211,11 @@ nvc0_create_sampler_view(struct pipe_context *, /* nvc0_transfer.c */ void -nvc0_m2mf_push_linear(struct nvc0_context *nvc0, - struct nouveau_bo *dst, unsigned domain, int offset, +nvc0_m2mf_push_linear(struct pipe_context *pipe, + struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data); void -nvc0_m2mf_copy_linear(struct nvc0_context *nvc0, +nvc0_m2mf_copy_linear(struct pipe_context *pipe, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size); diff --git a/src/gallium/drivers/nvc0/nvc0_fence.c b/src/gallium/drivers/nvc0/nvc0_fence.c deleted file mode 100644 index f2d4b1451bf..00000000000 --- a/src/gallium/drivers/nvc0/nvc0_fence.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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 "nvc0_fence.h" -#include "nvc0_context.h" -#include "nvc0_screen.h" - -#ifdef PIPE_OS_UNIX -#include -#endif - -boolean -nvc0_screen_fence_new(struct nvc0_screen *screen, struct nvc0_fence **fence, - boolean emit) -{ - *fence = CALLOC_STRUCT(nvc0_fence); - if (!*fence) - return FALSE; - - (*fence)->screen = screen; - (*fence)->ref = 1; - - if (emit) - nvc0_fence_emit(*fence); - - return TRUE; -} - -void -nvc0_fence_emit(struct nvc0_fence *fence) -{ - struct nvc0_screen *screen = fence->screen; - struct nouveau_channel *chan = screen->base.channel; - - fence->sequence = ++screen->fence.sequence; - - assert(fence->state == NVC0_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, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT | - (0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT)); - - ++fence->ref; - - if (screen->fence.tail) - screen->fence.tail->next = fence; - else - screen->fence.head = fence; - - screen->fence.tail = fence; - - fence->state = NVC0_FENCE_STATE_EMITTED; -} - -static void -nvc0_fence_trigger_release_buffers(struct nvc0_fence *fence); - -void -nvc0_fence_del(struct nvc0_fence *fence) -{ - struct nvc0_fence *it; - struct nvc0_screen *screen = fence->screen; - - if (fence->state == NVC0_FENCE_STATE_EMITTED || - fence->state == NVC0_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"); - nvc0_fence_trigger_release_buffers(fence); - } - - FREE(fence); -} - -static void -nvc0_fence_trigger_release_buffers(struct nvc0_fence *fence) -{ - struct nvc0_mm_allocation *alloc = fence->buffers; - - while (alloc) { - struct nvc0_mm_allocation *next = alloc->next; - nvc0_mm_free(alloc); - alloc = next; - }; - fence->buffers = NULL; -} - -void -nvc0_screen_fence_update(struct nvc0_screen *screen, boolean flushed) -{ - struct nvc0_fence *fence; - struct nvc0_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 = NVC0_FENCE_STATE_SIGNALLED; - - if (fence->buffers) - nvc0_fence_trigger_release_buffers(fence); - - nvc0_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 = NVC0_FENCE_STATE_FLUSHED; - } -} - -boolean -nvc0_fence_signalled(struct nvc0_fence *fence) -{ - struct nvc0_screen *screen = fence->screen; - - if (fence->state >= NVC0_FENCE_STATE_EMITTED) - nvc0_screen_fence_update(screen, FALSE); - - return fence->state == NVC0_FENCE_STATE_SIGNALLED; -} - -#define NVC0_FENCE_MAX_SPINS (1 << 31) - -boolean -nvc0_fence_wait(struct nvc0_fence *fence) -{ - struct nvc0_screen *screen = fence->screen; - uint32_t spins = 0; - - if (fence->state < NVC0_FENCE_STATE_EMITTED) { - nvc0_fence_emit(fence); - - if (fence == screen->fence.current) - nvc0_screen_fence_new(screen, &screen->fence.current, FALSE); - } - if (fence->state < NVC0_FENCE_STATE_FLUSHED) - FIRE_RING(screen->base.channel); - - do { - nvc0_screen_fence_update(screen, FALSE); - - if (fence->state == NVC0_FENCE_STATE_SIGNALLED) - return TRUE; - spins++; -#ifdef PIPE_OS_UNIX - if (!(spins % 8)) /* donate a few cycles */ - sched_yield(); -#endif - } while (spins < NVC0_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 -nvc0_screen_fence_next(struct nvc0_screen *screen) -{ - nvc0_fence_emit(screen->fence.current); - nvc0_screen_fence_new(screen, &screen->fence.current, FALSE); -} diff --git a/src/gallium/drivers/nvc0/nvc0_fence.h b/src/gallium/drivers/nvc0/nvc0_fence.h deleted file mode 100644 index 3d8c3f8ba60..00000000000 --- a/src/gallium/drivers/nvc0/nvc0_fence.h +++ /dev/null @@ -1,49 +0,0 @@ - -#ifndef __NVC0_FENCE_H__ -#define __NVC0_FENCE_H__ - -#include "util/u_inlines.h" -#include "util/u_double_list.h" - -#define NVC0_FENCE_STATE_AVAILABLE 0 -#define NVC0_FENCE_STATE_EMITTED 1 -#define NVC0_FENCE_STATE_FLUSHED 2 -#define NVC0_FENCE_STATE_SIGNALLED 3 - -struct nvc0_mm_allocation; - -struct nvc0_fence { - struct nvc0_fence *next; - struct nvc0_screen *screen; - int state; - int ref; - uint32_t sequence; - struct nvc0_mm_allocation *buffers; -}; - -void nvc0_fence_emit(struct nvc0_fence *); -void nvc0_fence_del(struct nvc0_fence *); - -boolean nvc0_fence_wait(struct nvc0_fence *); -boolean nvc0_fence_signalled(struct nvc0_fence *); - -static INLINE void -nvc0_fence_reference(struct nvc0_fence **ref, struct nvc0_fence *fence) -{ - if (*ref) { - if (--(*ref)->ref == 0) - nvc0_fence_del(*ref); - } - if (fence) - ++fence->ref; - - *ref = fence; -} - -static INLINE struct nvc0_fence * -nvc0_fence(struct pipe_fence_handle *fence) -{ - return (struct nvc0_fence *)fence; -} - -#endif // __NVC0_FENCE_H__ diff --git a/src/gallium/drivers/nvc0/nvc0_mm.c b/src/gallium/drivers/nvc0/nvc0_mm.c deleted file mode 100644 index 516d2e31b55..00000000000 --- a/src/gallium/drivers/nvc0/nvc0_mm.c +++ /dev/null @@ -1,274 +0,0 @@ - -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_double_list.h" - -#include "nvc0_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 nvc0_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 nvc0_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 nvc0_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 nvc0_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 nvc0_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 nvc0_mm_allocation * -nvc0_mm_allocate(struct nvc0_mman *cache, - uint32_t size, struct nouveau_bo **bo, uint32_t *offset) -{ - struct mm_bucket *bucket; - struct mm_slab *slab; - struct nvc0_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(nvc0_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 -nvc0_mm_free(struct nvc0_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 nvc0_mman * -nvc0_mm_create(struct nouveau_device *dev, uint32_t domain, - uint32_t storage_type) -{ - struct nvc0_mman *cache = MALLOC_STRUCT(nvc0_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 -nvc0_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 -nvc0_mm_destroy(struct nvc0_mman *cache) -{ - int i; - - 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"); - - nvc0_mm_free_slabs(&cache->bucket[i].free); - nvc0_mm_free_slabs(&cache->bucket[i].used); - nvc0_mm_free_slabs(&cache->bucket[i].full); - } -} - diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c index fcbb7da41a3..84533f0443e 100644 --- a/src/gallium/drivers/nvc0/nvc0_push.c +++ b/src/gallium/drivers/nvc0/nvc0_push.c @@ -227,10 +227,10 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) for (i = 0; i < nvc0->num_vtxbufs; ++i) { uint8_t *data; struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[i]; - struct nvc0_resource *res = nvc0_resource(vb->buffer); + struct nv04_resource *res = nv04_resource(vb->buffer); - data = nvc0_resource_map_offset(nvc0, res, - vb->buffer_offset, NOUVEAU_BO_RD); + data = nouveau_resource_map_offset(&nvc0->pipe, res, + vb->buffer_offset, NOUVEAU_BO_RD); if (apply_bias && likely(!(nvc0->vertex->instance_bufs & (1 << i)))) data += info->index_bias * vb->stride; @@ -239,9 +239,9 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) } if (info->indexed) { - ctx.idxbuf = nvc0_resource_map_offset(nvc0, - nvc0_resource(nvc0->idxbuf.buffer), - nvc0->idxbuf.offset, NOUVEAU_BO_RD); + ctx.idxbuf = nouveau_resource_map_offset(&nvc0->pipe, + nv04_resource(nvc0->idxbuf.buffer), + nvc0->idxbuf.offset, NOUVEAU_BO_RD); if (!ctx.idxbuf) return; index_size = nvc0->idxbuf.index_size; @@ -284,8 +284,8 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) } if (info->indexed) - nvc0_resource_unmap(nvc0_resource(nvc0->idxbuf.buffer)); + nouveau_resource_unmap(nv04_resource(nvc0->idxbuf.buffer)); for (i = 0; i < nvc0->num_vtxbufs; ++i) - nvc0_resource_unmap(nvc0_resource(nvc0->vtxbuf[i].buffer)); + nouveau_resource_unmap(nv04_resource(nvc0->vtxbuf[i].buffer)); } diff --git a/src/gallium/drivers/nvc0/nvc0_query.c b/src/gallium/drivers/nvc0/nvc0_query.c index e5e43c0e7a5..338359bdfd2 100644 --- a/src/gallium/drivers/nvc0/nvc0_query.c +++ b/src/gallium/drivers/nvc0/nvc0_query.c @@ -41,7 +41,7 @@ struct nvc0_query { uint32_t offset; /* base + i * 16 */ boolean ready; boolean is64bit; - struct nvc0_mm_allocation *mm; + struct nouveau_mm_allocation *mm; }; #define NVC0_QUERY_ALLOC_SPACE 128 @@ -62,13 +62,13 @@ nvc0_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q, int size) nouveau_bo_ref(NULL, &q->bo); if (q->mm) { if (q->ready) - nvc0_mm_free(q->mm); + nouveau_mm_free(q->mm); else - nvc0_fence_sched_release(screen->fence.current, q->mm); + nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, q->mm); } } if (size) { - q->mm = nvc0_mm_allocate(screen->mm_GART, size, &q->bo, &q->base); + q->mm = nouveau_mm_allocate(screen->base.mm_GART, size, &q->bo, &q->base); if (!q->bo) return FALSE; q->offset = q->base; diff --git a/src/gallium/drivers/nvc0/nvc0_resource.c b/src/gallium/drivers/nvc0/nvc0_resource.c index 7e42cedd163..fb5a496b84b 100644 --- a/src/gallium/drivers/nvc0/nvc0_resource.c +++ b/src/gallium/drivers/nvc0/nvc0_resource.c @@ -8,7 +8,7 @@ nvc0_resource_is_referenced(struct pipe_context *pipe, struct pipe_resource *resource, unsigned face, int layer) { - struct nvc0_resource *res = nvc0_resource(resource); + struct nv04_resource *res = nv04_resource(resource); unsigned flags = 0; #ifdef NOUVEAU_USERSPACE_MM @@ -29,7 +29,7 @@ nvc0_resource_create(struct pipe_screen *screen, { switch (templ->target) { case PIPE_BUFFER: - return nvc0_buffer_create(screen, templ); + return nouveau_buffer_create(screen, templ); default: return nvc0_miptree_create(screen, templ); } @@ -67,5 +67,5 @@ nvc0_screen_init_resource_functions(struct pipe_screen *pscreen) pscreen->resource_from_handle = nvc0_resource_from_handle; pscreen->resource_get_handle = u_resource_get_handle_vtbl; pscreen->resource_destroy = u_resource_destroy_vtbl; - pscreen->user_buffer_create = nvc0_user_buffer_create; + pscreen->user_buffer_create = nouveau_user_buffer_create; } diff --git a/src/gallium/drivers/nvc0/nvc0_resource.h b/src/gallium/drivers/nvc0/nvc0_resource.h index 599823c0dc9..7821db51b72 100644 --- a/src/gallium/drivers/nvc0/nvc0_resource.h +++ b/src/gallium/drivers/nvc0/nvc0_resource.h @@ -6,115 +6,15 @@ #include "util/u_double_list.h" #define NOUVEAU_NVC0 #include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_fence.h" +#include "nouveau/nouveau_buffer.h" #undef NOUVEAU_NVC0 -#include "nvc0_fence.h" - -struct pipe_resource; -struct nouveau_bo; -struct nvc0_context; - -#define NVC0_BUFFER_SCORE_MIN -25000 -#define NVC0_BUFFER_SCORE_MAX 25000 -#define NVC0_BUFFER_SCORE_VRAM_THRESHOLD 20000 - -/* 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 NVC0_BUFFER_STATUS_GPU_READING (1 << 0) -#define NVC0_BUFFER_STATUS_GPU_WRITING (1 << 1) -#define NVC0_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 nvc0_resource { - 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 nvc0_fence *fence; - struct nvc0_fence *fence_wr; - - struct nvc0_mm_allocation *mm; -}; +void +nvc0_init_resource_functions(struct pipe_context *pcontext); void -nvc0_buffer_release_gpu_storage(struct nvc0_resource *); - -boolean -nvc0_buffer_download(struct nvc0_context *, struct nvc0_resource *, - unsigned start, unsigned size); - -boolean -nvc0_buffer_migrate(struct nvc0_context *, - struct nvc0_resource *, unsigned domain); - -static INLINE void -nvc0_buffer_adjust_score(struct nvc0_context *nvc0, struct nvc0_resource *res, - int16_t score) -{ - if (score < 0) { - if (res->score > NVC0_BUFFER_SCORE_MIN) - res->score += score; - } else - if (score > 0){ - if (res->score < NVC0_BUFFER_SCORE_MAX) - res->score += score; - if (res->domain == NOUVEAU_BO_GART && - res->score > NVC0_BUFFER_SCORE_VRAM_THRESHOLD) - nvc0_buffer_migrate(nvc0, res, NOUVEAU_BO_VRAM); - } -} - -/* XXX: wait for fence (atm only using this for vertex push) */ -static INLINE void * -nvc0_resource_map_offset(struct nvc0_context *nvc0, - struct nvc0_resource *res, uint32_t offset, - uint32_t flags) -{ - void *map; - - nvc0_buffer_adjust_score(nvc0, res, -250); - - if ((res->domain == NOUVEAU_BO_VRAM) && - (res->status & NVC0_BUFFER_STATUS_GPU_WRITING)) - nvc0_buffer_download(nvc0, res, 0, res->base.width0); - - if ((res->domain != NOUVEAU_BO_GART) || - (res->status & NVC0_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 -nvc0_resource_unmap(struct nvc0_resource *res) -{ - /* no-op */ -} +nvc0_screen_init_resource_functions(struct pipe_screen *pscreen); #define NVC0_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf) @@ -137,7 +37,7 @@ struct nvc0_miptree_level { #define NVC0_MAX_TEXTURE_LEVELS 16 struct nvc0_miptree { - struct nvc0_resource base; + struct nv04_resource base; struct nvc0_miptree_level level[NVC0_MAX_TEXTURE_LEVELS]; uint32_t total_size; uint32_t layer_stride; @@ -150,25 +50,6 @@ nvc0_miptree(struct pipe_resource *pt) return (struct nvc0_miptree *)pt; } -static INLINE struct nvc0_resource * -nvc0_resource(struct pipe_resource *resource) -{ - return (struct nvc0_resource *)resource; -} - -/* is resource mapped into the GPU's address space (i.e. VRAM or GART) ? */ -static INLINE boolean -nvc0_resource_mapped_by_gpu(struct pipe_resource *resource) -{ - return nvc0_resource(resource)->domain != 0; -} - -void -nvc0_init_resource_functions(struct pipe_context *pcontext); - -void -nvc0_screen_init_resource_functions(struct pipe_screen *pscreen); - /* Internal functions: */ struct pipe_resource * @@ -180,17 +61,6 @@ nvc0_miptree_from_handle(struct pipe_screen *pscreen, const struct pipe_resource *template, struct winsys_handle *whandle); -struct pipe_resource * -nvc0_buffer_create(struct pipe_screen *pscreen, - const struct pipe_resource *templ); - -struct pipe_resource * -nvc0_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes, - unsigned usage); - - struct pipe_surface * nvc0_miptree_surface_new(struct pipe_context *, struct pipe_resource *, @@ -199,7 +69,4 @@ nvc0_miptree_surface_new(struct pipe_context *, void nvc0_miptree_surface_del(struct pipe_context *, struct pipe_surface *); -boolean -nvc0_user_buffer_upload(struct nvc0_resource *, unsigned base, unsigned size); - #endif diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index f7f1fd09a12..82209c58c2c 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -23,7 +23,6 @@ #include "util/u_format_s3tc.h" #include "pipe/p_screen.h" -#include "nvc0_fence.h" #include "nvc0_context.h" #include "nvc0_screen.h" @@ -200,8 +199,8 @@ nvc0_screen_destroy(struct pipe_screen *pscreen) { struct nvc0_screen *screen = nvc0_screen(pscreen); - nvc0_fence_wait(screen->fence.current); - nvc0_fence_reference(&screen->fence.current, NULL); + nouveau_fence_wait(screen->base.fence.current); + nouveau_fence_ref(NULL, &screen->base.fence.current); nouveau_bo_ref(NULL, &screen->text); nouveau_bo_ref(NULL, &screen->tls); @@ -214,9 +213,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen) if (screen->tic.entries) FREE(screen->tic.entries); - nvc0_mm_destroy(screen->mm_GART); - nvc0_mm_destroy(screen->mm_VRAM); - nvc0_mm_destroy(screen->mm_VRAM_fe0); + nouveau_mm_destroy(screen->mm_VRAM_fe0); nouveau_grobj_free(&screen->fermi); nouveau_grobj_free(&screen->eng2d); @@ -245,30 +242,6 @@ nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos, return pos + size; } -static void -nvc0_screen_fence_reference(struct pipe_screen *pscreen, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ - nvc0_fence_reference((struct nvc0_fence **)ptr, nvc0_fence(fence)); -} - -static int -nvc0_screen_fence_signalled(struct pipe_screen *pscreen, - struct pipe_fence_handle *fence, - unsigned flags) -{ - return !(nvc0_fence_signalled(nvc0_fence(fence))); -} - -static int -nvc0_screen_fence_finish(struct pipe_screen *pscreen, - struct pipe_fence_handle *fence, - unsigned flags) -{ - return nvc0_fence_wait((struct nvc0_fence *)fence) != TRUE; -} - static void nvc0_magic_3d_init(struct nouveau_channel *chan) { @@ -342,6 +315,28 @@ nvc0_magic_3d_init(struct nouveau_channel *chan) OUT_RING (chan, 0); } +static void +nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 sequence) +{ + struct nvc0_screen *screen = nvc0_screen(pscreen); + struct nouveau_channel *chan = screen->base.channel; + + 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, sequence); + OUT_RING (chan, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT | + (0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT)); +} + +static u32 +nvc0_screen_fence_update(struct pipe_screen *pscreen) +{ + struct nvc0_screen *screen = nvc0_screen(pscreen); + return screen->fence.map[0]; +} + #define FAIL_SCREEN_INIT(str, err) \ do { \ NOUVEAU_ERR(str, err); \ @@ -377,14 +372,13 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) pscreen->get_param = nvc0_screen_get_param; pscreen->get_shader_param = nvc0_screen_get_shader_param; pscreen->get_paramf = nvc0_screen_get_paramf; - pscreen->fence_reference = nvc0_screen_fence_reference; - pscreen->fence_signalled = nvc0_screen_fence_signalled; - pscreen->fence_finish = nvc0_screen_fence_finish; nvc0_screen_init_resource_functions(pscreen); screen->base.vertex_buffer_flags = NOUVEAU_BO_GART; screen->base.index_buffer_flags = 0; + screen->base.copy_data = nvc0_m2mf_copy_linear; + screen->base.push_data = nvc0_m2mf_push_linear; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); @@ -393,6 +387,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR); screen->fence.map = screen->fence.bo->map; nouveau_bo_unmap(screen->fence.bo); + screen->base.fence.emit = nvc0_screen_fence_emit; + screen->base.fence.update = nvc0_screen_fence_update; for (i = 0; i < NVC0_SCRATCH_NR_BUFFERS; ++i) { ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE, @@ -619,12 +615,9 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->tic.entries = CALLOC(4096, sizeof(void *)); screen->tsc.entries = screen->tic.entries + 2048; - screen->mm_GART = nvc0_mm_create(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, - 0x000); - screen->mm_VRAM = nvc0_mm_create(dev, NOUVEAU_BO_VRAM, 0x000); - screen->mm_VRAM_fe0 = nvc0_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); + screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); - nvc0_screen_fence_new(screen, &screen->fence.current, FALSE); + nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); return pscreen; diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h index d952ff1f9b1..d8b8c5e3dc8 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.h +++ b/src/gallium/drivers/nvc0/nvc0_screen.h @@ -3,6 +3,7 @@ #define NOUVEAU_NVC0 #include "nouveau/nouveau_screen.h" +#include "nouveau/nouveau_mm.h" #undef NOUVEAU_NVC0 #include "nvc0_winsys.h" #include "nvc0_stateobj.h" @@ -10,9 +11,7 @@ #define NVC0_TIC_MAX_ENTRIES 2048 #define NVC0_TSC_MAX_ENTRIES 2048 -struct nvc0_mman; struct nvc0_context; -struct nvc0_fence; #define NVC0_SCRATCH_SIZE (2 << 20) #define NVC0_SCRATCH_NR_BUFFERS 2 @@ -53,18 +52,11 @@ struct nvc0_screen { } tsc; struct { - uint32_t *map; - struct nvc0_fence *head; - struct nvc0_fence *tail; - struct nvc0_fence *current; - uint32_t sequence; - uint32_t sequence_ack; struct nouveau_bo *bo; + uint32_t *map; } fence; - struct nvc0_mman *mm_GART; - struct nvc0_mman *mm_VRAM; - struct nvc0_mman *mm_VRAM_fe0; + struct nouveau_mman *mm_VRAM_fe0; struct nouveau_grobj *fermi; struct nouveau_grobj *eng2d; @@ -77,54 +69,26 @@ nvc0_screen(struct pipe_screen *screen) return (struct nvc0_screen *)screen; } -/* 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 nvc0_mm_allocation { - struct nvc0_mm_allocation *next; - void *priv; - uint32_t offset; -}; - -static INLINE void -nvc0_fence_sched_release(struct nvc0_fence *nf, struct nvc0_mm_allocation *mm) -{ - mm->next = nf->buffers; - nf->buffers = mm; -} - -extern struct nvc0_mman * -nvc0_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type); - -extern void -nvc0_mm_destroy(struct nvc0_mman *); - -extern struct nvc0_mm_allocation * -nvc0_mm_allocate(struct nvc0_mman *, - uint32_t size, struct nouveau_bo **, uint32_t *offset); -extern void -nvc0_mm_free(struct nvc0_mm_allocation *); - void nvc0_screen_make_buffers_resident(struct nvc0_screen *); int nvc0_screen_tic_alloc(struct nvc0_screen *, void *); int nvc0_screen_tsc_alloc(struct nvc0_screen *, void *); static INLINE void -nvc0_resource_fence(struct nvc0_resource *res, uint32_t flags) +nvc0_resource_fence(struct nv04_resource *res, uint32_t flags) { struct nvc0_screen *screen = nvc0_screen(res->base.screen); if (res->mm) { - nvc0_fence_reference(&res->fence, screen->fence.current); + nouveau_fence_ref(screen->base.fence.current, &res->fence); if (flags & NOUVEAU_BO_WR) - nvc0_fence_reference(&res->fence_wr, screen->fence.current); + nouveau_fence_ref(screen->base.fence.current, &res->fence_wr); } } static INLINE void -nvc0_resource_validate(struct nvc0_resource *res, uint32_t flags) +nvc0_resource_validate(struct nv04_resource *res, uint32_t flags) { struct nvc0_screen *screen = nvc0_screen(res->base.screen); @@ -132,30 +96,14 @@ nvc0_resource_validate(struct nvc0_resource *res, uint32_t flags) nouveau_bo_validate(screen->base.channel, res->bo, flags); if (flags & NOUVEAU_BO_WR) - res->status |= NVC0_BUFFER_STATUS_GPU_WRITING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; if (flags & NOUVEAU_BO_RD) - res->status |= NVC0_BUFFER_STATUS_GPU_READING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; nvc0_resource_fence(res, flags); } } - -boolean -nvc0_screen_fence_new(struct nvc0_screen *, struct nvc0_fence **, boolean emit); -void -nvc0_screen_fence_next(struct nvc0_screen *); -void -nvc0_screen_fence_update(struct nvc0_screen *, boolean flushed); - -static INLINE boolean -nvc0_screen_fence_emit(struct nvc0_screen *screen) -{ - nvc0_fence_emit(screen->fence.current); - - return nvc0_screen_fence_new(screen, &screen->fence.current, FALSE); -} - struct nvc0_format { uint32_t rt; uint32_t tic; diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c index 357f8b80deb..765f1dae576 100644 --- a/src/gallium/drivers/nvc0/nvc0_shader_state.c +++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c @@ -59,11 +59,11 @@ nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog) prog->code_base = prog->res->start; - nvc0_m2mf_push_linear(nvc0, nvc0->screen->text, NOUVEAU_BO_VRAM, - prog->code_base, NVC0_SHADER_HEADER_SIZE, prog->hdr); - nvc0_m2mf_push_linear(nvc0, nvc0->screen->text, NOUVEAU_BO_VRAM, + nvc0_m2mf_push_linear(&nvc0->pipe, nvc0->screen->text, prog->code_base, + NOUVEAU_BO_VRAM, NVC0_SHADER_HEADER_SIZE, prog->hdr); + nvc0_m2mf_push_linear(&nvc0->pipe, nvc0->screen->text, prog->code_base + NVC0_SHADER_HEADER_SIZE, - prog->code_size, prog->code); + NOUVEAU_BO_VRAM, prog->code_size, prog->code); BEGIN_RING(nvc0->screen->base.channel, RING_3D(MEM_BARRIER), 1); OUT_RING (nvc0->screen->base.channel, 0x1111); @@ -217,7 +217,7 @@ nvc0_tfb_validate(struct nvc0_context *nvc0) for (b = 0; b < nvc0->num_tfbbufs; ++b) { uint8_t idx, var[128]; int i, n; - struct nvc0_resource *buf = nvc0_resource(nvc0->tfbbuf[b]); + struct nv04_resource *buf = nv04_resource(nvc0->tfbbuf[b]); BEGIN_RING(chan, RING_3D(TFB_BUFFER_ENABLE(b)), 5); OUT_RING (chan, 1); diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index aa437195764..36c751e251c 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -666,8 +666,7 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, if (nvc0->constbuf[shader][index]) nvc0_bufctx_del_resident(nvc0, NVC0_BUFCTX_CONSTANT, - nvc0_resource( - nvc0->constbuf[shader][index])); + nv04_resource(nvc0->constbuf[shader][index])); pipe_resource_reference(&nvc0->constbuf[shader][index], res); diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index 70c418fad9b..ab8119a3bbb 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -87,10 +87,10 @@ nvc0_validate_fb(struct nvc0_context *nvc0) OUT_RING (chan, sf->depth); OUT_RING (chan, mt->layer_stride >> 2); - if (mt->base.status & NVC0_BUFFER_STATUS_GPU_READING) + if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) serialize = TRUE; - mt->base.status |= NVC0_BUFFER_STATUS_GPU_WRITING; - mt->base.status &= ~NVC0_BUFFER_STATUS_GPU_READING; + mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING; nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); @@ -117,10 +117,10 @@ nvc0_validate_fb(struct nvc0_context *nvc0) OUT_RING (chan, sf->height); OUT_RING (chan, (unk << 16) | sf->depth); - if (mt->base.status & NVC0_BUFFER_STATUS_GPU_READING) + if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING) serialize = TRUE; - mt->base.status |= NVC0_BUFFER_STATUS_GPU_WRITING; - mt->base.status &= ~NVC0_BUFFER_STATUS_GPU_READING; + mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING; nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); @@ -323,7 +323,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) unsigned s; for (s = 0; s < 5; ++s) { - struct nvc0_resource *res; + struct nv04_resource *res; int i; while (nvc0->constbuf_dirty[s]) { @@ -334,7 +334,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) i = ffs(nvc0->constbuf_dirty[s]) - 1; nvc0->constbuf_dirty[s] &= ~(1 << i); - res = nvc0_resource(nvc0->constbuf[s][i]); + res = nv04_resource(nvc0->constbuf[s][i]); if (!res) { BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1); OUT_RING (chan, (i << 4) | 0); @@ -343,7 +343,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) continue; } - if (!nvc0_resource_mapped_by_gpu(&res->base)) { + if (!nouveau_resource_mapped_by_gpu(&res->base)) { if (i == 0) { base = s << 16; bo = nvc0->screen->uniforms; diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index 8898bc733a3..6f39bbbb170 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -367,9 +367,9 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers, void nvc0_init_surface_functions(struct nvc0_context *nvc0) { - nvc0->pipe.resource_copy_region = nvc0_resource_copy_region; - nvc0->pipe.clear_render_target = nvc0_clear_render_target; - nvc0->pipe.clear_depth_stencil = nvc0_clear_depth_stencil; + nvc0->pipe.resource_copy_region = nvc0_resource_copy_region; + nvc0->pipe.clear_render_target = nvc0_clear_render_target; + nvc0->pipe.clear_depth_stencil = nvc0_clear_depth_stencil; } diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c index 968558a5869..f651e54e1db 100644 --- a/src/gallium/drivers/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nvc0/nvc0_tex.c @@ -167,7 +167,7 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s) for (i = 0; i < nvc0->num_textures[s]; ++i) { struct nvc0_tic_entry *tic = nvc0_tic_entry(nvc0->textures[s][i]); - struct nvc0_resource *res; + struct nv04_resource *res; if (!tic) { BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1); @@ -197,14 +197,14 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s) need_flush = TRUE; } else - if (res->status & NVC0_BUFFER_STATUS_GPU_WRITING) { + if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) { BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); OUT_RING (chan, (tic->id << 4) | 1); } nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32); - res->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING; - res->status |= NVC0_BUFFER_STATUS_GPU_READING; + res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING; nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TEXTURES, res, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); @@ -252,8 +252,9 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s) if (tsc->id < 0) { tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc); - nvc0_m2mf_push_linear(nvc0, nvc0->screen->txc, NOUVEAU_BO_VRAM, - 65536 + tsc->id * 32, 32, tsc->tsc); + nvc0_m2mf_push_linear(&nvc0->pipe, nvc0->screen->txc, + 65536 + tsc->id * 32, NOUVEAU_BO_VRAM, + 32, tsc->tsc); need_flush = TRUE; } nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32); diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c index b279bdc6e7d..bbb24fa0528 100644 --- a/src/gallium/drivers/nvc0/nvc0_transfer.c +++ b/src/gallium/drivers/nvc0/nvc0_transfer.c @@ -104,10 +104,11 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen, } void -nvc0_m2mf_push_linear(struct nvc0_context *nvc0, - struct nouveau_bo *dst, unsigned domain, int offset, +nvc0_m2mf_push_linear(struct pipe_context *pipe, + struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data) { + struct nvc0_context *nvc0 = nvc0_context(pipe); struct nouveau_channel *chan = nvc0->screen->base.channel; uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; @@ -143,11 +144,12 @@ nvc0_m2mf_push_linear(struct nvc0_context *nvc0, } void -nvc0_m2mf_copy_linear(struct nvc0_context *nvc0, +nvc0_m2mf_copy_linear(struct pipe_context *pipe, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size) { + struct nvc0_context *nvc0 = nvc0_context(pipe); struct nouveau_channel *chan = nvc0->screen->base.channel; while (size) { diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index 2db43d8704b..14bea675a11 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -131,13 +131,13 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb, { const void *data; struct nouveau_channel *chan = nvc0->screen->base.channel; - struct nvc0_resource *res = nvc0_resource(vb->buffer); + struct nv04_resource *res = nv04_resource(vb->buffer); float v[4]; int i; const unsigned nc = util_format_get_nr_components(ve->src_format); - data = nvc0_resource_map_offset(nvc0, res, vb->buffer_offset + - ve->src_offset, NOUVEAU_BO_RD); + data = nouveau_resource_map_offset(&nvc0->pipe, 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); @@ -167,7 +167,7 @@ static void nvc0_prevalidate_vbufs(struct nvc0_context *nvc0) { struct pipe_vertex_buffer *vb; - struct nvc0_resource *buf; + struct nv04_resource *buf; int i; uint32_t base, size; @@ -179,27 +179,27 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0) vb = &nvc0->vtxbuf[i]; if (!vb->stride) continue; - buf = nvc0_resource(vb->buffer); + buf = nv04_resource(vb->buffer); /* NOTE: user buffers with temporary storage count as mapped by GPU */ - if (!nvc0_resource_mapped_by_gpu(vb->buffer)) { + if (!nouveau_resource_mapped_by_gpu(vb->buffer)) { if (nvc0->vbo_push_hint) { nvc0->vbo_fifo = ~0; continue; } else { - if (buf->status & NVC0_BUFFER_STATUS_USER_MEMORY) { + if (buf->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY) { nvc0->vbo_user |= 1 << i; assert(vb->stride > vb->buffer_offset); nvc0_vbuf_range(nvc0, i, &base, &size); - nvc0_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(buf, base, size); } else { - nvc0_buffer_migrate(nvc0, buf, NOUVEAU_BO_GART); + nouveau_buffer_migrate(&nvc0->pipe, buf, NOUVEAU_BO_GART); } nvc0->vbo_dirty = TRUE; } } nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); - nvc0_buffer_adjust_score(nvc0, buf, 1); + nouveau_buffer_adjust_score(&nvc0->pipe, buf, 1); } } @@ -215,7 +215,7 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0) struct pipe_vertex_element *ve = &nvc0->vertex->element[i].pipe; const int b = ve->vertex_buffer_index; struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[b]; - struct nvc0_resource *buf = nvc0_resource(vb->buffer); + struct nv04_resource *buf = nv04_resource(vb->buffer); if (!(nvc0->vbo_user & (1 << b))) continue; @@ -228,7 +228,7 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0) if (!(written & (1 << b))) { written |= 1 << b; - nvc0_user_buffer_upload(buf, base, size); + nouveau_user_buffer_upload(buf, base, size); } offset = vb->buffer_offset + ve->src_offset; @@ -252,7 +252,7 @@ nvc0_release_user_vbufs(struct nvc0_context *nvc0) int i = ffs(vbo_user) - 1; vbo_user &= ~(1 << i); - nvc0_buffer_release_gpu_storage(nvc0_resource(nvc0->vtxbuf[i].buffer)); + nouveau_buffer_release_gpu_storage(nv04_resource(nvc0->vtxbuf[i].buffer)); } } @@ -286,7 +286,7 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) } for (i = 0; i < vertex->num_elements; ++i) { - struct nvc0_resource *res; + struct nv04_resource *res; unsigned size, offset; ve = &vertex->element[i]; @@ -303,7 +303,7 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0); } - res = nvc0_resource(vb->buffer); + res = nv04_resource(vb->buffer); if (nvc0->vbo_fifo || unlikely(vb->stride == 0)) { if (!nvc0->vbo_fifo) @@ -371,7 +371,7 @@ nvc0_draw_vbo_flush_notify(struct nouveau_channel *chan) { struct nvc0_context *nvc0 = chan->user_private; - nvc0_screen_fence_update(nvc0->screen, TRUE); + nouveau_fence_update(&nvc0->screen->base, TRUE); nvc0_bufctx_emit_relocs(nvc0); } @@ -513,12 +513,12 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, nvc0->state.index_bias = index_bias; } - if (nvc0_resource_mapped_by_gpu(nvc0->idxbuf.buffer)) { - struct nvc0_resource *res = nvc0_resource(nvc0->idxbuf.buffer); + if (nouveau_resource_mapped_by_gpu(nvc0->idxbuf.buffer)) { + struct nv04_resource *res = nv04_resource(nvc0->idxbuf.buffer); unsigned offset = nvc0->idxbuf.offset; unsigned limit = nvc0->idxbuf.buffer->width0 - 1; - nvc0_buffer_adjust_score(nvc0, res, 1); + nouveau_buffer_adjust_score(&nvc0->pipe, res, 1); while (instance_count--) { MARK_RING (chan, 11, 4); @@ -539,8 +539,9 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } else { - data = nvc0_resource_map_offset(nvc0, nvc0_resource(nvc0->idxbuf.buffer), - nvc0->idxbuf.offset, NOUVEAU_BO_RD); + data = nouveau_resource_map_offset(&nvc0->pipe, + nv04_resource(nvc0->idxbuf.buffer), + nvc0->idxbuf.offset, NOUVEAU_BO_RD); if (!data) return; diff --git a/src/gallium/drivers/nvc0/nvc0_winsys.h b/src/gallium/drivers/nvc0/nvc0_winsys.h index 45f71967eff..6519ce8e19f 100644 --- a/src/gallium/drivers/nvc0/nvc0_winsys.h +++ b/src/gallium/drivers/nvc0/nvc0_winsys.h @@ -84,18 +84,18 @@ IMMED_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned data) } static INLINE int -OUT_RESRCh(struct nouveau_channel *chan, struct nvc0_resource *res, +OUT_RESRCh(struct nouveau_channel *chan, struct nv04_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 nvc0_resource *res, +OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res, unsigned delta, unsigned flags) { if (flags & NOUVEAU_BO_WR) - res->status |= NVC0_BUFFER_STATUS_GPU_WRITING; + res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags); } From 96d57722fda62e7710eb5281bcf014ddfb824ef9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 14:39:04 +1000 Subject: [PATCH 14/53] nouveau: fix leak of nouveau_mman structs Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_mm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/drivers/nouveau/nouveau_mm.c b/src/gallium/drivers/nouveau/nouveau_mm.c index 332b8dc02e3..7edeb4d21d6 100644 --- a/src/gallium/drivers/nouveau/nouveau_mm.c +++ b/src/gallium/drivers/nouveau/nouveau_mm.c @@ -282,5 +282,7 @@ nouveau_mm_destroy(struct nouveau_mman *cache) nouveau_mm_free_slabs(&cache->bucket[i].used); nouveau_mm_free_slabs(&cache->bucket[i].full); } + + FREE(cache); } From 1ba8e9510812f155359d380bda6876cdee5ba21e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 15:28:26 +1000 Subject: [PATCH 15/53] nouveau: ensure vbo_dirty is set when buffer write transfer complete This introduces a shared nouveau_context struct to track such things. Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_buffer.c | 47 +++++---- src/gallium/drivers/nouveau/nouveau_buffer.h | 9 +- src/gallium/drivers/nouveau/nouveau_context.h | 26 +++++ src/gallium/drivers/nouveau/nouveau_screen.h | 7 -- src/gallium/drivers/nv50/nv50_context.c | 26 +++-- src/gallium/drivers/nv50/nv50_context.h | 8 +- src/gallium/drivers/nv50/nv50_push.c | 4 +- src/gallium/drivers/nv50/nv50_query.c | 14 +-- src/gallium/drivers/nv50/nv50_screen.c | 2 - src/gallium/drivers/nv50/nv50_shader_state.c | 4 +- src/gallium/drivers/nv50/nv50_state.c | 86 +++++++++-------- src/gallium/drivers/nv50/nv50_surface.c | 8 +- src/gallium/drivers/nv50/nv50_tex.c | 2 +- src/gallium/drivers/nv50/nv50_transfer.c | 10 +- src/gallium/drivers/nv50/nv50_vbo.c | 18 ++-- src/gallium/drivers/nvc0/nvc0_context.c | 26 +++-- src/gallium/drivers/nvc0/nvc0_context.h | 9 +- src/gallium/drivers/nvc0/nvc0_push.c | 4 +- src/gallium/drivers/nvc0/nvc0_query.c | 14 +-- src/gallium/drivers/nvc0/nvc0_screen.c | 2 - src/gallium/drivers/nvc0/nvc0_shader_state.c | 4 +- src/gallium/drivers/nvc0/nvc0_state.c | 96 ++++++++++--------- src/gallium/drivers/nvc0/nvc0_surface.c | 8 +- src/gallium/drivers/nvc0/nvc0_tex.c | 2 +- src/gallium/drivers/nvc0/nvc0_transfer.c | 10 +- src/gallium/drivers/nvc0/nvc0_vbo.c | 18 ++-- 26 files changed, 250 insertions(+), 214 deletions(-) create mode 100644 src/gallium/drivers/nouveau/nouveau_context.h diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index efb16824e46..571fa0c608b 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -4,6 +4,7 @@ #include "util/u_math.h" #include "nouveau_screen.h" +#include "nouveau_context.h" #include "nouveau_winsys.h" #include "nouveau_fence.h" #include "nouveau_buffer.h" @@ -90,22 +91,21 @@ nouveau_buffer_destroy(struct pipe_screen *pscreen, /* Maybe just migrate to GART right away if we actually need to do this. */ boolean -nouveau_buffer_download(struct pipe_context *pipe, struct nv04_resource *buf, +nouveau_buffer_download(struct nouveau_context *nv, struct nv04_resource *buf, unsigned start, unsigned size) { - struct nouveau_screen *screen = nouveau_screen(pipe->screen); struct nouveau_mm_allocation *mm; struct nouveau_bo *bounce = NULL; uint32_t offset; assert(buf->domain == NOUVEAU_BO_VRAM); - mm = nouveau_mm_allocate(screen->mm_GART, size, &bounce, &offset); + mm = nouveau_mm_allocate(nv->screen->mm_GART, size, &bounce, &offset); if (!bounce) return FALSE; - screen->copy_data(pipe, bounce, offset, NOUVEAU_BO_GART, - buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, size); + nv->copy_data(nv, 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; @@ -121,21 +121,20 @@ nouveau_buffer_download(struct pipe_context *pipe, struct nv04_resource *buf, } static boolean -nouveau_buffer_upload(struct pipe_context *pipe, struct nv04_resource *buf, +nouveau_buffer_upload(struct nouveau_context *nv, struct nv04_resource *buf, unsigned start, unsigned size) { - struct nouveau_screen *screen = nouveau_screen(pipe->screen); struct nouveau_mm_allocation *mm; struct nouveau_bo *bounce = NULL; uint32_t offset; if (size <= 192) { - screen->push_data(pipe, buf->bo, buf->offset + start, buf->domain, - size, buf->data + start); + nv->push_data(nv, buf->bo, buf->offset + start, buf->domain, + size, buf->data + start); return TRUE; } - mm = nouveau_mm_allocate(screen->mm_GART, size, &bounce, &offset); + mm = nouveau_mm_allocate(nv->screen->mm_GART, size, &bounce, &offset); if (!bounce) return FALSE; @@ -144,12 +143,12 @@ nouveau_buffer_upload(struct pipe_context *pipe, struct nv04_resource *buf, memcpy(bounce->map, buf->data + start, size); nouveau_bo_unmap(bounce); - screen->copy_data(pipe, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, - bounce, offset, NOUVEAU_BO_GART, size); + nv->copy_data(nv, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, + bounce, offset, NOUVEAU_BO_GART, size); nouveau_bo_ref(NULL, &bounce); if (mm) - release_allocation(&mm, screen->fence.current); + release_allocation(&mm, nv->screen->fence.current); if (start == 0 && size == buf->base.width0) buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING; @@ -163,6 +162,7 @@ nouveau_buffer_transfer_get(struct pipe_context *pipe, const struct pipe_box *box) { struct nv04_resource *buf = nv04_resource(resource); + struct nouveau_context *nv = nouveau_context(pipe); struct nouveau_transfer *xfr = CALLOC_STRUCT(nouveau_transfer); if (!xfr) return NULL; @@ -175,7 +175,7 @@ nouveau_buffer_transfer_get(struct pipe_context *pipe, if (buf->domain == NOUVEAU_BO_VRAM) { if (usage & PIPE_TRANSFER_READ) { if (buf->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) - nouveau_buffer_download(pipe, buf, 0, buf->base.width0); + nouveau_buffer_download(nv, buf, 0, buf->base.width0); } } @@ -188,20 +188,19 @@ nouveau_buffer_transfer_destroy(struct pipe_context *pipe, { struct nv04_resource *buf = nv04_resource(transfer->resource); struct nouveau_transfer *xfr = nouveau_transfer(transfer); + struct nouveau_context *nv = nouveau_context(pipe); if (xfr->base.usage & PIPE_TRANSFER_WRITE) { /* writing is worse */ - nouveau_buffer_adjust_score(pipe, buf, -5000); + nouveau_buffer_adjust_score(nv, buf, -5000); if (buf->domain == NOUVEAU_BO_VRAM) { - nouveau_buffer_upload(pipe, buf, transfer->box.x, transfer->box.width); + nouveau_buffer_upload(nv, buf, transfer->box.x, transfer->box.width); } -#if 0 if (buf->domain != 0 && (buf->base.bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))) nouveau_context(pipe)->vbo_dirty = TRUE; -#endif } FREE(xfr); @@ -249,7 +248,7 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe, uint32_t offset = xfr->base.box.x; uint32_t flags; - nouveau_buffer_adjust_score(pipe, buf, -250); + nouveau_buffer_adjust_score(nouveau_context(pipe), buf, -250); if (buf->domain != NOUVEAU_BO_GART) return buf->data + offset; @@ -403,10 +402,10 @@ nouveau_buffer_data_fetch(struct nv04_resource *buf, struct nouveau_bo *bo, /* Migrate a linear buffer (vertex, index, constants) USER -> GART -> VRAM. */ boolean -nouveau_buffer_migrate(struct pipe_context *pipe, +nouveau_buffer_migrate(struct nouveau_context *nv, struct nv04_resource *buf, const unsigned new_domain) { - struct nouveau_screen *screen = nouveau_screen(pipe->screen); + struct nouveau_screen *screen = nv->screen; struct nouveau_bo *bo; const unsigned old_domain = buf->domain; unsigned size = buf->base.width0; @@ -442,8 +441,8 @@ nouveau_buffer_migrate(struct pipe_context *pipe, buf->mm = NULL; nouveau_buffer_allocate(screen, buf, new_domain); - screen->copy_data(pipe, buf->bo, buf->offset, new_domain, - bo, offset, old_domain, buf->base.width0); + nv->copy_data(nv, buf->bo, buf->offset, new_domain, + bo, offset, old_domain, buf->base.width0); nouveau_bo_ref(NULL, &bo); if (mm) @@ -452,7 +451,7 @@ nouveau_buffer_migrate(struct pipe_context *pipe, if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) { if (!nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM)) return FALSE; - if (!nouveau_buffer_upload(pipe, buf, 0, buf->base.width0)) + if (!nouveau_buffer_upload(nv, buf, 0, buf->base.width0)) return FALSE; } else return FALSE; diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h index c3e0c2cf924..46e3554bdf7 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.h +++ b/src/gallium/drivers/nouveau/nouveau_buffer.h @@ -5,6 +5,7 @@ #include "util/u_double_list.h" struct pipe_resource; +struct nouveau_context; struct nouveau_bo; #define NOUVEAU_BUFFER_SCORE_MIN -25000 @@ -50,15 +51,15 @@ void nouveau_buffer_release_gpu_storage(struct nv04_resource *); boolean -nouveau_buffer_download(struct pipe_context *, struct nv04_resource *, +nouveau_buffer_download(struct nouveau_context *, struct nv04_resource *, unsigned start, unsigned size); boolean -nouveau_buffer_migrate(struct pipe_context *, +nouveau_buffer_migrate(struct nouveau_context *, struct nv04_resource *, unsigned domain); static INLINE void -nouveau_buffer_adjust_score(struct pipe_context *pipe, +nouveau_buffer_adjust_score(struct nouveau_context *pipe, struct nv04_resource *res, int16_t score) { if (score < 0) { @@ -76,7 +77,7 @@ nouveau_buffer_adjust_score(struct pipe_context *pipe, /* XXX: wait for fence (atm only using this for vertex push) */ static INLINE void * -nouveau_resource_map_offset(struct pipe_context *pipe, +nouveau_resource_map_offset(struct nouveau_context *pipe, struct nv04_resource *res, uint32_t offset, uint32_t flags) { diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h new file mode 100644 index 00000000000..696e0d3f24e --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_context.h @@ -0,0 +1,26 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "pipe/p_context.h" + +struct nouveau_context { + struct pipe_context pipe; + struct nouveau_screen *screen; + + boolean vbo_dirty; + + void (*copy_data)(struct nouveau_context *, + struct nouveau_bo *dst, unsigned, unsigned, + struct nouveau_bo *src, unsigned, unsigned, unsigned); + void (*push_data)(struct nouveau_context *, + struct nouveau_bo *dst, unsigned, unsigned, + unsigned, void *); +}; + +static INLINE struct nouveau_context * +nouveau_context(struct pipe_context *pipe) +{ + return (struct nouveau_context *)pipe; +} + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index c64b7b16ad2..580b4da6b4e 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -29,13 +29,6 @@ struct nouveau_screen { struct nouveau_mman *mm_VRAM; struct nouveau_mman *mm_GART; - void (*copy_data)(struct pipe_context *, - struct nouveau_bo *dst, unsigned, unsigned, - struct nouveau_bo *src, unsigned, unsigned, - unsigned); - void (*push_data)(struct pipe_context *, - struct nouveau_bo *dst, unsigned, unsigned, - unsigned, void *); }; static INLINE struct nouveau_screen * diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 03a5c3d2d91..912367b8391 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -84,22 +84,28 @@ 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_context *pipe; nv50 = CALLOC_STRUCT(nv50_context); if (!nv50) return NULL; + pipe = &nv50->base.pipe; + nv50->screen = screen; + nv50->base.screen = &screen->base; + nv50->base.copy_data = nv50_m2mf_copy_linear; + nv50->base.push_data = nv50_sifc_linear_u8; - nv50->pipe.winsys = pipe_winsys; - nv50->pipe.screen = pscreen; - nv50->pipe.priv = priv; + pipe->winsys = pipe_winsys; + pipe->screen = pscreen; + pipe->priv = priv; - nv50->pipe.destroy = nv50_destroy; + pipe->destroy = nv50_destroy; - nv50->pipe.draw_vbo = nv50_draw_vbo; - nv50->pipe.clear = nv50_clear; + pipe->draw_vbo = nv50_draw_vbo; + pipe->clear = nv50_clear; - nv50->pipe.flush = nv50_flush; + pipe->flush = nv50_flush; if (!screen->cur_ctx) screen->cur_ctx = nv50; @@ -109,13 +115,13 @@ nv50_create(struct pipe_screen *pscreen, void *priv) nv50_init_query_functions(nv50); nv50_init_surface_functions(nv50); nv50_init_state_functions(nv50); - nv50_init_resource_functions(&nv50->pipe); + nv50_init_resource_functions(pipe); - nv50->draw = draw_create(&nv50->pipe); + nv50->draw = draw_create(pipe); assert(nv50->draw); draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50)); - return &nv50->pipe; + return pipe; } struct resident { diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 55d996da27f..e6079a621a9 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -19,6 +19,7 @@ #include "nv50_program.h" #include "nv50_resource.h" +#include "nouveau/nouveau_context.h" #include "nouveau/nv_object.xml.h" #include "nouveau/nv_m2mf.xml.h" #include "nv50_3ddefs.xml.h" @@ -67,7 +68,7 @@ #define NV50_CB_AUX 127 struct nv50_context { - struct pipe_context pipe; + struct nouveau_context base; struct nv50_screen *screen; @@ -122,7 +123,6 @@ struct nv50_context { unsigned sample_mask; - boolean vbo_dirty; boolean vbo_push_hint; struct draw_context *draw; @@ -204,11 +204,11 @@ nv50_create_sampler_view(struct pipe_context *, /* nv50_transfer.c */ void -nv50_sifc_linear_u8(struct pipe_context *pipe, +nv50_sifc_linear_u8(struct nouveau_context *pipe, struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data); void -nv50_m2mf_copy_linear(struct pipe_context *pipe, +nv50_m2mf_copy_linear(struct nouveau_context *pipe, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size); diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c index 07034bdcf62..71b5995a4f8 100644 --- a/src/gallium/drivers/nv50/nv50_push.c +++ b/src/gallium/drivers/nv50/nv50_push.c @@ -229,7 +229,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i]; struct nv04_resource *res = nv04_resource(vb->buffer); - data = nouveau_resource_map_offset(&nv50->pipe, res, + data = nouveau_resource_map_offset(&nv50->base, res, vb->buffer_offset, NOUVEAU_BO_RD); if (apply_bias && likely(!(nv50->vertex->instance_bufs & (1 << i)))) @@ -239,7 +239,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) } if (info->indexed) { - ctx.idxbuf = nouveau_resource_map_offset(&nv50->pipe, + ctx.idxbuf = nouveau_resource_map_offset(&nv50->base, nv04_resource(nv50->idxbuf.buffer), nv50->idxbuf.offset, NOUVEAU_BO_RD); if (!ctx.idxbuf) diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 2e65c54e548..2dce94a4775 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -326,10 +326,12 @@ nv50_render_condition(struct pipe_context *pipe, 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; + struct pipe_context *pipe = &nv50->base.pipe; + + pipe->create_query = nv50_query_create; + pipe->destroy_query = nv50_query_destroy; + pipe->begin_query = nv50_query_begin; + pipe->end_query = nv50_query_end; + pipe->get_query_result = nv50_query_result; + pipe->render_condition = nv50_render_condition; } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 13c03b1a7e6..f2b03e8156e 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -310,8 +310,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART; - screen->base.copy_data = nv50_m2mf_copy_linear; - screen->base.push_data = nv50_sifc_linear_u8; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index 2d7572820f2..7d4b12bde17 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -76,7 +76,7 @@ nv50_constbufs_validate(struct nv50_context *nv50) assert(0); if (!nouveau_resource_mapped_by_gpu(&res->base)) { - nouveau_buffer_migrate(&nv50->pipe, res, NOUVEAU_BO_VRAM); + nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM); BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1); OUT_RING (chan, 0); @@ -149,7 +149,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) return FALSE; prog->code_base = prog->res->start; - nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->code, + nv50_sifc_linear_u8(&nv50->base, nv50->screen->code, (prog->type << 16) + prog->code_base, NOUVEAU_BO_VRAM, prog->code_size, prog->code); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 6b1106341ce..17f272bb3bf 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -793,55 +793,57 @@ nv50_vertex_state_bind(struct pipe_context *pipe, void *hwcso) 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; + struct pipe_context *pipe = &nv50->base.pipe; - 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; + pipe->create_blend_state = nv50_blend_state_create; + pipe->bind_blend_state = nv50_blend_state_bind; + pipe->delete_blend_state = nv50_blend_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; + pipe->create_rasterizer_state = nv50_rasterizer_state_create; + pipe->bind_rasterizer_state = nv50_rasterizer_state_bind; + pipe->delete_rasterizer_state = nv50_rasterizer_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; + pipe->create_depth_stencil_alpha_state = nv50_zsa_state_create; + pipe->bind_depth_stencil_alpha_state = nv50_zsa_state_bind; + pipe->delete_depth_stencil_alpha_state = nv50_zsa_state_delete; - 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; + pipe->create_sampler_state = nv50_sampler_state_create; + pipe->delete_sampler_state = nv50_sampler_state_delete; + pipe->bind_vertex_sampler_states = nv50_vp_sampler_states_bind; + pipe->bind_fragment_sampler_states = nv50_fp_sampler_states_bind; + pipe->bind_geometry_sampler_states = nv50_gp_sampler_states_bind; + + pipe->create_sampler_view = nv50_create_sampler_view; + pipe->sampler_view_destroy = nv50_sampler_view_destroy; + pipe->set_vertex_sampler_views = nv50_vp_set_sampler_views; + pipe->set_fragment_sampler_views = nv50_fp_set_sampler_views; + 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; + pipe->create_vs_state = nv50_vp_state_create; + pipe->create_fs_state = nv50_fp_state_create; + pipe->create_gs_state = nv50_gp_state_create; + pipe->bind_vs_state = nv50_vp_state_bind; + pipe->bind_fs_state = nv50_fp_state_bind; + pipe->bind_gs_state = nv50_gp_state_bind; + pipe->delete_vs_state = nv50_sp_state_delete; + pipe->delete_fs_state = nv50_sp_state_delete; + 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; + pipe->set_blend_color = nv50_set_blend_color; + pipe->set_stencil_ref = nv50_set_stencil_ref; + pipe->set_clip_state = nv50_set_clip_state; + pipe->set_sample_mask = nv50_set_sample_mask; + pipe->set_constant_buffer = nv50_set_constant_buffer; + pipe->set_framebuffer_state = nv50_set_framebuffer_state; + pipe->set_polygon_stipple = nv50_set_polygon_stipple; + pipe->set_scissor_state = nv50_set_scissor_state; + 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; + pipe->create_vertex_elements_state = nv50_vertex_state_create; + pipe->delete_vertex_elements_state = nv50_vertex_state_delete; + 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; + pipe->set_vertex_buffers = nv50_set_vertex_buffers; + pipe->set_index_buffer = nv50_set_index_buffer; } diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index b1f54f623ab..dc9e2880f0f 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -371,9 +371,11 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, void nv50_init_surface_functions(struct nv50_context *nv50) { - 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; + struct pipe_context *pipe = &nv50->base.pipe; + + pipe->resource_copy_region = nv50_resource_copy_region; + pipe->clear_render_target = nv50_clear_render_target; + 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 a76139ad37e..4456553a868 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -269,7 +269,7 @@ nv50_validate_tsc(struct nv50_context *nv50, int s) if (tsc->id < 0) { tsc->id = nv50_screen_tsc_alloc(nv50->screen, tsc); - nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->txc, + nv50_sifc_linear_u8(&nv50->base, nv50->screen->txc, 65536 + tsc->id * 32, NOUVEAU_BO_VRAM, 32, tsc->tsc); need_flush = TRUE; diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index d80a5354904..74869774595 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -102,12 +102,11 @@ nv50_m2mf_transfer_rect(struct pipe_screen *pscreen, } void -nv50_sifc_linear_u8(struct pipe_context *pipe, +nv50_sifc_linear_u8(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_channel *chan = nv->screen->channel; uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; unsigned xcoord = offset & 0xff; @@ -159,13 +158,12 @@ nv50_sifc_linear_u8(struct pipe_context *pipe, } void -nv50_m2mf_copy_linear(struct pipe_context *pipe, +nv50_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_channel *chan = nv->screen->channel; BEGIN_RING(chan, RING_MF(LINEAR_IN), 1); OUT_RING (chan, 1); diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 1f0d34ed792..e94a2b6fa3d 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -131,7 +131,7 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb, float v[4]; const unsigned nc = util_format_get_nr_components(ve->src_format); - data = nouveau_resource_map_offset(&nv50->pipe, res, vb->buffer_offset + + data = nouveau_resource_map_offset(&nv50->base, res, vb->buffer_offset + ve->src_offset, NOUVEAU_BO_RD); util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1); @@ -215,13 +215,13 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50) nv50_vbuf_range(nv50, i, &base, &size); nouveau_user_buffer_upload(buf, base, size); } else { - nouveau_buffer_migrate(&nv50->pipe, buf, NOUVEAU_BO_GART); + nouveau_buffer_migrate(&nv50->base, buf, NOUVEAU_BO_GART); } - nv50->vbo_dirty = TRUE; + nv50->base.vbo_dirty = TRUE; } } nv50_bufctx_add_resident(nv50, NV50_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); - nouveau_buffer_adjust_score(&nv50->pipe, buf, 1); + nouveau_buffer_adjust_score(&nv50->base, buf, 1); } } @@ -262,7 +262,7 @@ nv50_update_user_vbufs(struct nv50_context *nv50) OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD); OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD); } - nv50->vbo_dirty = TRUE; + nv50->base.vbo_dirty = TRUE; } static INLINE void @@ -540,7 +540,7 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer); unsigned offset = res->offset + nv50->idxbuf.offset; - nouveau_buffer_adjust_score(&nv50->pipe, res, 1); + nouveau_buffer_adjust_score(&nv50->base, res, 1); while (instance_count--) { BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); @@ -597,7 +597,7 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } else { - data = nouveau_resource_map_offset(&nv50->pipe, + data = nouveau_resource_map_offset(&nv50->base, nv04_resource(nv50->idxbuf.buffer), nv50->idxbuf.offset, NOUVEAU_BO_RD); if (!data) @@ -669,10 +669,10 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) OUT_RING (chan, info->start_instance); } - if (nv50->vbo_dirty) { + if (nv50->base.vbo_dirty) { BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1); OUT_RING (chan, 0); - nv50->vbo_dirty = FALSE; + nv50->base.vbo_dirty = FALSE; } if (!info->indexed) { diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index 4979aab51c4..d5dcf1fb028 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -84,22 +84,28 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) struct pipe_winsys *pipe_winsys = pscreen->winsys; struct nvc0_screen *screen = nvc0_screen(pscreen); struct nvc0_context *nvc0; + struct pipe_context *pipe; nvc0 = CALLOC_STRUCT(nvc0_context); if (!nvc0) return NULL; + pipe = &nvc0->base.pipe; + nvc0->screen = screen; + nvc0->base.screen = &screen->base; + nvc0->base.copy_data = nvc0_m2mf_copy_linear; + nvc0->base.push_data = nvc0_m2mf_push_linear; - nvc0->pipe.winsys = pipe_winsys; - nvc0->pipe.screen = pscreen; - nvc0->pipe.priv = priv; + pipe->winsys = pipe_winsys; + pipe->screen = pscreen; + pipe->priv = priv; - nvc0->pipe.destroy = nvc0_destroy; + pipe->destroy = nvc0_destroy; - nvc0->pipe.draw_vbo = nvc0_draw_vbo; - nvc0->pipe.clear = nvc0_clear; + pipe->draw_vbo = nvc0_draw_vbo; + pipe->clear = nvc0_clear; - nvc0->pipe.flush = nvc0_flush; + pipe->flush = nvc0_flush; if (!screen->cur_ctx) screen->cur_ctx = nvc0; @@ -109,13 +115,13 @@ nvc0_create(struct pipe_screen *pscreen, void *priv) nvc0_init_query_functions(nvc0); nvc0_init_surface_functions(nvc0); nvc0_init_state_functions(nvc0); - nvc0_init_resource_functions(&nvc0->pipe); + nvc0_init_resource_functions(pipe); - nvc0->draw = draw_create(&nvc0->pipe); + nvc0->draw = draw_create(pipe); assert(nvc0->draw); draw_set_rasterize_stage(nvc0->draw, nvc0_draw_render_stage(nvc0)); - return &nvc0->pipe; + return pipe; } struct resident { diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index d779777ed3a..114e664fc58 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -19,6 +19,8 @@ #include "nvc0_program.h" #include "nvc0_resource.h" +#include "nouveau/nouveau_context.h" + #include "nvc0_3ddefs.xml.h" #include "nvc0_3d.xml.h" #include "nvc0_2d.xml.h" @@ -64,7 +66,7 @@ #define NVC0_BUFCTX_COUNT 4 struct nvc0_context { - struct pipe_context pipe; + struct nouveau_context base; struct nvc0_screen *screen; @@ -123,7 +125,6 @@ struct nvc0_context { unsigned sample_mask; - boolean vbo_dirty; boolean vbo_push_hint; struct nvc0_transform_feedback_state *tfb; @@ -211,11 +212,11 @@ nvc0_create_sampler_view(struct pipe_context *, /* nvc0_transfer.c */ void -nvc0_m2mf_push_linear(struct pipe_context *pipe, +nvc0_m2mf_push_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data); void -nvc0_m2mf_copy_linear(struct pipe_context *pipe, +nvc0_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size); diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c index 84533f0443e..68544c90d29 100644 --- a/src/gallium/drivers/nvc0/nvc0_push.c +++ b/src/gallium/drivers/nvc0/nvc0_push.c @@ -229,7 +229,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[i]; struct nv04_resource *res = nv04_resource(vb->buffer); - data = nouveau_resource_map_offset(&nvc0->pipe, res, + data = nouveau_resource_map_offset(&nvc0->base, res, vb->buffer_offset, NOUVEAU_BO_RD); if (apply_bias && likely(!(nvc0->vertex->instance_bufs & (1 << i)))) @@ -239,7 +239,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) } if (info->indexed) { - ctx.idxbuf = nouveau_resource_map_offset(&nvc0->pipe, + ctx.idxbuf = nouveau_resource_map_offset(&nvc0->base, nv04_resource(nvc0->idxbuf.buffer), nvc0->idxbuf.offset, NOUVEAU_BO_RD); if (!ctx.idxbuf) diff --git a/src/gallium/drivers/nvc0/nvc0_query.c b/src/gallium/drivers/nvc0/nvc0_query.c index 338359bdfd2..ead015b6b84 100644 --- a/src/gallium/drivers/nvc0/nvc0_query.c +++ b/src/gallium/drivers/nvc0/nvc0_query.c @@ -330,10 +330,12 @@ nvc0_render_condition(struct pipe_context *pipe, void nvc0_init_query_functions(struct nvc0_context *nvc0) { - nvc0->pipe.create_query = nvc0_query_create; - nvc0->pipe.destroy_query = nvc0_query_destroy; - nvc0->pipe.begin_query = nvc0_query_begin; - nvc0->pipe.end_query = nvc0_query_end; - nvc0->pipe.get_query_result = nvc0_query_result; - nvc0->pipe.render_condition = nvc0_render_condition; + struct pipe_context *pipe = &nvc0->base.pipe; + + pipe->create_query = nvc0_query_create; + pipe->destroy_query = nvc0_query_destroy; + pipe->begin_query = nvc0_query_begin; + pipe->end_query = nvc0_query_end; + pipe->get_query_result = nvc0_query_result; + pipe->render_condition = nvc0_render_condition; } diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index 82209c58c2c..b84a1bee8da 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -377,8 +377,6 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->base.vertex_buffer_flags = NOUVEAU_BO_GART; screen->base.index_buffer_flags = 0; - screen->base.copy_data = nvc0_m2mf_copy_linear; - screen->base.push_data = nvc0_m2mf_push_linear; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c index 765f1dae576..79b5f3d81cc 100644 --- a/src/gallium/drivers/nvc0/nvc0_shader_state.c +++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c @@ -59,9 +59,9 @@ nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog) prog->code_base = prog->res->start; - nvc0_m2mf_push_linear(&nvc0->pipe, nvc0->screen->text, prog->code_base, + nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->text, prog->code_base, NOUVEAU_BO_VRAM, NVC0_SHADER_HEADER_SIZE, prog->hdr); - nvc0_m2mf_push_linear(&nvc0->pipe, nvc0->screen->text, + nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->text, prog->code_base + NVC0_SHADER_HEADER_SIZE, NOUVEAU_BO_VRAM, prog->code_size, prog->code); diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index 36c751e251c..ee4680efeca 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -876,62 +876,64 @@ nvc0_set_transform_feedback_buffers(struct pipe_context *pipe, void nvc0_init_state_functions(struct nvc0_context *nvc0) { - nvc0->pipe.create_blend_state = nvc0_blend_state_create; - nvc0->pipe.bind_blend_state = nvc0_blend_state_bind; - nvc0->pipe.delete_blend_state = nvc0_blend_state_delete; + struct pipe_context *pipe = &nvc0->base.pipe; - nvc0->pipe.create_rasterizer_state = nvc0_rasterizer_state_create; - nvc0->pipe.bind_rasterizer_state = nvc0_rasterizer_state_bind; - nvc0->pipe.delete_rasterizer_state = nvc0_rasterizer_state_delete; + pipe->create_blend_state = nvc0_blend_state_create; + pipe->bind_blend_state = nvc0_blend_state_bind; + pipe->delete_blend_state = nvc0_blend_state_delete; - nvc0->pipe.create_depth_stencil_alpha_state = nvc0_zsa_state_create; - nvc0->pipe.bind_depth_stencil_alpha_state = nvc0_zsa_state_bind; - nvc0->pipe.delete_depth_stencil_alpha_state = nvc0_zsa_state_delete; + pipe->create_rasterizer_state = nvc0_rasterizer_state_create; + pipe->bind_rasterizer_state = nvc0_rasterizer_state_bind; + pipe->delete_rasterizer_state = nvc0_rasterizer_state_delete; - nvc0->pipe.create_sampler_state = nvc0_sampler_state_create; - nvc0->pipe.delete_sampler_state = nvc0_sampler_state_delete; - nvc0->pipe.bind_vertex_sampler_states = nvc0_vp_sampler_states_bind; - nvc0->pipe.bind_fragment_sampler_states = nvc0_fp_sampler_states_bind; - nvc0->pipe.bind_geometry_sampler_states = nvc0_gp_sampler_states_bind; + pipe->create_depth_stencil_alpha_state = nvc0_zsa_state_create; + pipe->bind_depth_stencil_alpha_state = nvc0_zsa_state_bind; + pipe->delete_depth_stencil_alpha_state = nvc0_zsa_state_delete; - nvc0->pipe.create_sampler_view = nvc0_create_sampler_view; - nvc0->pipe.sampler_view_destroy = nvc0_sampler_view_destroy; - nvc0->pipe.set_vertex_sampler_views = nvc0_vp_set_sampler_views; - nvc0->pipe.set_fragment_sampler_views = nvc0_fp_set_sampler_views; - nvc0->pipe.set_geometry_sampler_views = nvc0_gp_set_sampler_views; + pipe->create_sampler_state = nvc0_sampler_state_create; + pipe->delete_sampler_state = nvc0_sampler_state_delete; + pipe->bind_vertex_sampler_states = nvc0_vp_sampler_states_bind; + pipe->bind_fragment_sampler_states = nvc0_fp_sampler_states_bind; + pipe->bind_geometry_sampler_states = nvc0_gp_sampler_states_bind; - nvc0->pipe.create_vs_state = nvc0_vp_state_create; - nvc0->pipe.create_fs_state = nvc0_fp_state_create; - nvc0->pipe.create_gs_state = nvc0_gp_state_create; - nvc0->pipe.bind_vs_state = nvc0_vp_state_bind; - nvc0->pipe.bind_fs_state = nvc0_fp_state_bind; - nvc0->pipe.bind_gs_state = nvc0_gp_state_bind; - nvc0->pipe.delete_vs_state = nvc0_sp_state_delete; - nvc0->pipe.delete_fs_state = nvc0_sp_state_delete; - nvc0->pipe.delete_gs_state = nvc0_sp_state_delete; + pipe->create_sampler_view = nvc0_create_sampler_view; + pipe->sampler_view_destroy = nvc0_sampler_view_destroy; + pipe->set_vertex_sampler_views = nvc0_vp_set_sampler_views; + pipe->set_fragment_sampler_views = nvc0_fp_set_sampler_views; + pipe->set_geometry_sampler_views = nvc0_gp_set_sampler_views; - nvc0->pipe.set_blend_color = nvc0_set_blend_color; - nvc0->pipe.set_stencil_ref = nvc0_set_stencil_ref; - nvc0->pipe.set_clip_state = nvc0_set_clip_state; - nvc0->pipe.set_sample_mask = nvc0_set_sample_mask; - nvc0->pipe.set_constant_buffer = nvc0_set_constant_buffer; - nvc0->pipe.set_framebuffer_state = nvc0_set_framebuffer_state; - nvc0->pipe.set_polygon_stipple = nvc0_set_polygon_stipple; - nvc0->pipe.set_scissor_state = nvc0_set_scissor_state; - nvc0->pipe.set_viewport_state = nvc0_set_viewport_state; + pipe->create_vs_state = nvc0_vp_state_create; + pipe->create_fs_state = nvc0_fp_state_create; + pipe->create_gs_state = nvc0_gp_state_create; + pipe->bind_vs_state = nvc0_vp_state_bind; + pipe->bind_fs_state = nvc0_fp_state_bind; + pipe->bind_gs_state = nvc0_gp_state_bind; + pipe->delete_vs_state = nvc0_sp_state_delete; + pipe->delete_fs_state = nvc0_sp_state_delete; + pipe->delete_gs_state = nvc0_sp_state_delete; - nvc0->pipe.create_vertex_elements_state = nvc0_vertex_state_create; - nvc0->pipe.delete_vertex_elements_state = nvc0_vertex_state_delete; - nvc0->pipe.bind_vertex_elements_state = nvc0_vertex_state_bind; + pipe->set_blend_color = nvc0_set_blend_color; + pipe->set_stencil_ref = nvc0_set_stencil_ref; + pipe->set_clip_state = nvc0_set_clip_state; + pipe->set_sample_mask = nvc0_set_sample_mask; + pipe->set_constant_buffer = nvc0_set_constant_buffer; + pipe->set_framebuffer_state = nvc0_set_framebuffer_state; + pipe->set_polygon_stipple = nvc0_set_polygon_stipple; + pipe->set_scissor_state = nvc0_set_scissor_state; + pipe->set_viewport_state = nvc0_set_viewport_state; - nvc0->pipe.set_vertex_buffers = nvc0_set_vertex_buffers; - nvc0->pipe.set_index_buffer = nvc0_set_index_buffer; + pipe->create_vertex_elements_state = nvc0_vertex_state_create; + pipe->delete_vertex_elements_state = nvc0_vertex_state_delete; + pipe->bind_vertex_elements_state = nvc0_vertex_state_bind; - nvc0->pipe.create_stream_output_state = nvc0_tfb_state_create; - nvc0->pipe.delete_stream_output_state = nvc0_tfb_state_delete; - nvc0->pipe.bind_stream_output_state = nvc0_tfb_state_bind; - nvc0->pipe.set_stream_output_buffers = nvc0_set_transform_feedback_buffers; + pipe->set_vertex_buffers = nvc0_set_vertex_buffers; + pipe->set_index_buffer = nvc0_set_index_buffer; - nvc0->pipe.redefine_user_buffer = u_default_redefine_user_buffer; + pipe->create_stream_output_state = nvc0_tfb_state_create; + pipe->delete_stream_output_state = nvc0_tfb_state_delete; + pipe->bind_stream_output_state = nvc0_tfb_state_bind; + pipe->set_stream_output_buffers = nvc0_set_transform_feedback_buffers; + + pipe->redefine_user_buffer = u_default_redefine_user_buffer; } diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index 6f39bbbb170..a4b2b948123 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -367,9 +367,11 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers, void nvc0_init_surface_functions(struct nvc0_context *nvc0) { - nvc0->pipe.resource_copy_region = nvc0_resource_copy_region; - nvc0->pipe.clear_render_target = nvc0_clear_render_target; - nvc0->pipe.clear_depth_stencil = nvc0_clear_depth_stencil; + struct pipe_context *pipe = &nvc0->base.pipe; + + pipe->resource_copy_region = nvc0_resource_copy_region; + pipe->clear_render_target = nvc0_clear_render_target; + pipe->clear_depth_stencil = nvc0_clear_depth_stencil; } diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c index f651e54e1db..6822e597b36 100644 --- a/src/gallium/drivers/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nvc0/nvc0_tex.c @@ -252,7 +252,7 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s) if (tsc->id < 0) { tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc); - nvc0_m2mf_push_linear(&nvc0->pipe, nvc0->screen->txc, + nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->txc, 65536 + tsc->id * 32, NOUVEAU_BO_VRAM, 32, tsc->tsc); need_flush = TRUE; diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c index bbb24fa0528..a38bdb8f0a6 100644 --- a/src/gallium/drivers/nvc0/nvc0_transfer.c +++ b/src/gallium/drivers/nvc0/nvc0_transfer.c @@ -104,12 +104,11 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen, } void -nvc0_m2mf_push_linear(struct pipe_context *pipe, +nvc0_m2mf_push_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned offset, unsigned domain, unsigned size, void *data) { - struct nvc0_context *nvc0 = nvc0_context(pipe); - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_channel *chan = nv->screen->channel; uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; @@ -144,13 +143,12 @@ nvc0_m2mf_push_linear(struct pipe_context *pipe, } void -nvc0_m2mf_copy_linear(struct pipe_context *pipe, +nvc0_m2mf_copy_linear(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, unsigned size) { - struct nvc0_context *nvc0 = nvc0_context(pipe); - struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nouveau_channel *chan = nv->screen->channel; while (size) { unsigned bytes = MIN2(size, 1 << 17); diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index 14bea675a11..e7e7ce7dc22 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -136,7 +136,7 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb, int i; const unsigned nc = util_format_get_nr_components(ve->src_format); - data = nouveau_resource_map_offset(&nvc0->pipe, res, vb->buffer_offset + + data = nouveau_resource_map_offset(&nvc0->base, res, vb->buffer_offset + ve->src_offset, NOUVEAU_BO_RD); util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1); @@ -193,13 +193,13 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0) nvc0_vbuf_range(nvc0, i, &base, &size); nouveau_user_buffer_upload(buf, base, size); } else { - nouveau_buffer_migrate(&nvc0->pipe, buf, NOUVEAU_BO_GART); + nouveau_buffer_migrate(&nvc0->base, buf, NOUVEAU_BO_GART); } - nvc0->vbo_dirty = TRUE; + nvc0->base.vbo_dirty = TRUE; } } nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); - nouveau_buffer_adjust_score(&nvc0->pipe, buf, 1); + nouveau_buffer_adjust_score(&nvc0->base, buf, 1); } } @@ -240,7 +240,7 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0) OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD); OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD); } - nvc0->vbo_dirty = TRUE; + nvc0->base.vbo_dirty = TRUE; } static INLINE void @@ -518,7 +518,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, unsigned offset = nvc0->idxbuf.offset; unsigned limit = nvc0->idxbuf.buffer->width0 - 1; - nouveau_buffer_adjust_score(&nvc0->pipe, res, 1); + nouveau_buffer_adjust_score(&nvc0->base, res, 1); while (instance_count--) { MARK_RING (chan, 11, 4); @@ -539,7 +539,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } else { - data = nouveau_resource_map_offset(&nvc0->pipe, + data = nouveau_resource_map_offset(&nvc0->base, nv04_resource(nvc0->idxbuf.buffer), nvc0->idxbuf.offset, NOUVEAU_BO_RD); if (!data) @@ -610,10 +610,10 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) OUT_RING (chan, info->start_instance); } - if (nvc0->vbo_dirty) { + if (nvc0->base.vbo_dirty) { BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1); OUT_RING (chan, 0); - nvc0->vbo_dirty = FALSE; + nvc0->base.vbo_dirty = FALSE; } if (!info->indexed) { From 28eb7214db3387eb55109273317a308617341a3f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 17:08:03 +1000 Subject: [PATCH 16/53] nvc0: fix a crash on context destruction Signed-off-by: Ben Skeggs --- src/gallium/drivers/nvc0/nvc0_context.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index d5dcf1fb028..d6de979b132 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -62,8 +62,10 @@ nvc0_destroy(struct pipe_context *pipe) draw_destroy(nvc0->draw); - if (nvc0->screen->cur_ctx == nvc0) + if (nvc0->screen->cur_ctx == nvc0) { + nvc0->screen->base.channel->user_private = NULL; nvc0->screen->cur_ctx = NULL; + } FREE(nvc0); } @@ -73,8 +75,10 @@ nvc0_default_flush_notify(struct nouveau_channel *chan) { struct nvc0_context *nvc0 = chan->user_private; - nouveau_fence_update(&nvc0->screen->base, TRUE); + if (!nvc0) + return; + nouveau_fence_update(&nvc0->screen->base, TRUE); nouveau_fence_next(&nvc0->screen->base); } From 450aa241bfd9d72737775633a6cf88db23952ebf Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 1 Mar 2011 17:43:13 +1000 Subject: [PATCH 17/53] nouveau: remove nouveau_stateobj.h Signed-off-by: Ben Skeggs --- .../drivers/nouveau/nouveau_stateobj.h | 316 ------------------ 1 file changed, 316 deletions(-) delete mode 100644 src/gallium/drivers/nouveau/nouveau_stateobj.h diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h deleted file mode 100644 index e920cf9f3bc..00000000000 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ /dev/null @@ -1,316 +0,0 @@ -#ifndef __NOUVEAU_STATEOBJ_H__ -#define __NOUVEAU_STATEOBJ_H__ - -#include "util/u_debug.h" - -#ifdef DEBUG -#define DEBUG_NOUVEAU_STATEOBJ -#endif /* DEBUG */ - -struct nouveau_stateobj_reloc { - struct nouveau_bo *bo; - - struct nouveau_grobj *gr; - uint32_t push_offset; - uint32_t mthd; - - uint32_t data; - unsigned flags; - unsigned vor; - unsigned tor; -}; - -struct nouveau_stateobj_start { - struct nouveau_grobj *gr; - uint32_t mthd; - uint32_t size; - unsigned offset; -}; - -struct nouveau_stateobj { - struct pipe_reference reference; - - struct nouveau_stateobj_start *start; - struct nouveau_stateobj_reloc *reloc; - - /* Common memory pool for data. */ - uint32_t *pool; - unsigned pool_cur; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - unsigned start_alloc; - unsigned reloc_alloc; - unsigned pool_alloc; -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - unsigned total; /* includes begin_ring */ - unsigned cur; /* excludes begin_ring, offset from "cur_start" */ - unsigned cur_start; - unsigned cur_reloc; -}; - -static INLINE void -so_dump(struct nouveau_stateobj *so) -{ - unsigned i, nr, total = 0; - - for (i = 0; i < so->cur_start; i++) { - if (so->start[i].gr->subc > -1) - debug_printf("+0x%04x: 0x%08x\n", total++, - (so->start[i].size << 18) | (so->start[i].gr->subc << 13) - | so->start[i].mthd); - else - debug_printf("+0x%04x: 0x%08x\n", total++, - (so->start[i].size << 18) | so->start[i].mthd); - for (nr = 0; nr < so->start[i].size; nr++, total++) - debug_printf("+0x%04x: 0x%08x\n", total, - so->pool[so->start[i].offset + nr]); - } -} - -static INLINE struct nouveau_stateobj * -so_new(unsigned start, unsigned push, unsigned reloc) -{ - struct nouveau_stateobj *so; - - so = MALLOC(sizeof(struct nouveau_stateobj)); - pipe_reference_init(&so->reference, 1); - so->total = so->cur = so->cur_start = so->cur_reloc = 0; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - so->start_alloc = start; - so->reloc_alloc = reloc; - so->pool_alloc = push; -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - so->start = MALLOC(start * sizeof(struct nouveau_stateobj_start)); - so->reloc = MALLOC(reloc * sizeof(struct nouveau_stateobj_reloc)); - so->pool = MALLOC(push * sizeof(uint32_t)); - so->pool_cur = 0; - - if (!so->start || !so->reloc || !so->pool) { - debug_printf("malloc failed\n"); - assert(0); - } - - return so; -} - -static INLINE void -so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso) -{ - struct nouveau_stateobj *so = *pso; - int i; - - if (pipe_reference(&(*pso)->reference, &ref->reference)) { - FREE(so->start); - for (i = 0; i < so->cur_reloc; i++) - nouveau_bo_ref(NULL, &so->reloc[i].bo); - FREE(so->reloc); - FREE(so->pool); - FREE(so); - } - *pso = ref; -} - -static INLINE void -so_data(struct nouveau_stateobj *so, uint32_t data) -{ -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->cur >= so->start[so->cur_start - 1].size) { - debug_printf("exceeding specified size\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - so->pool[so->start[so->cur_start - 1].offset + so->cur++] = data; -} - -static INLINE void -so_datap(struct nouveau_stateobj *so, uint32_t *data, unsigned size) -{ -#ifdef DEBUG_NOUVEAU_STATEOBJ - if ((so->cur + size) > so->start[so->cur_start - 1].size) { - debug_printf("exceeding specified size\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - while (size--) - so->pool[so->start[so->cur_start - 1].offset + so->cur++] = - *data++; -} - -static INLINE void -so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr, - unsigned mthd, unsigned size) -{ - struct nouveau_stateobj_start *start; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->start_alloc <= so->cur_start) { - debug_printf("exceeding num_start size\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - start = so->start; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->cur_start > 0 && start[so->cur_start - 1].size > so->cur) { - debug_printf("previous so_method was not filled\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - start[so->cur_start].gr = gr; - start[so->cur_start].mthd = mthd; - start[so->cur_start].size = size; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->pool_alloc < (size + so->pool_cur)) { - debug_printf("exceeding num_pool size\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - start[so->cur_start].offset = so->pool_cur; - so->pool_cur += size; - - so->cur_start++; - /* The 1 is for *this* begin_ring. */ - so->total += so->cur + 1; - so->cur = 0; -} - -static INLINE void -so_reloc(struct nouveau_stateobj *so, struct nouveau_bo *bo, - unsigned data, unsigned flags, unsigned vor, unsigned tor) -{ - struct nouveau_stateobj_reloc *r; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->reloc_alloc <= so->cur_reloc) { - debug_printf("exceeding num_reloc size\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - r = so->reloc; - - r[so->cur_reloc].bo = NULL; - nouveau_bo_ref(bo, &(r[so->cur_reloc].bo)); - r[so->cur_reloc].gr = so->start[so->cur_start-1].gr; - r[so->cur_reloc].push_offset = so->total + so->cur; - r[so->cur_reloc].data = data; - r[so->cur_reloc].flags = flags; - r[so->cur_reloc].mthd = so->start[so->cur_start-1].mthd + - (so->cur << 2); - r[so->cur_reloc].vor = vor; - r[so->cur_reloc].tor = tor; - - so_data(so, data); - so->cur_reloc++; -} - -/* Determine if this buffer object is referenced by this state object. */ -static INLINE boolean -so_bo_is_reloc(struct nouveau_stateobj *so, struct nouveau_bo *bo) -{ - int i; - - for (i = 0; i < so->cur_reloc; i++) - if (so->reloc[i].bo == bo) - return true; - - return false; -} - -static INLINE void -so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so) -{ - unsigned nr, i; - int ret = 0; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (so->start[so->cur_start - 1].size > so->cur) { - debug_printf("emit: previous so_method was not filled\n"); - assert(0); - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - /* We cannot update total in case we so_emit again. */ - nr = so->total + so->cur; - - /* This will flush if we need space. - * We don't actually need the marker. - */ - if ((ret = nouveau_pushbuf_marker_emit(chan, nr, so->cur_reloc))) { - debug_printf("so_emit failed marker emit with error %d\n", ret); - assert(0); - } - - /* Submit data. This will ensure proper binding of objects. */ - for (i = 0; i < so->cur_start; i++) { - BEGIN_RING(chan, so->start[i].gr, so->start[i].mthd, so->start[i].size); - OUT_RINGp(chan, &(so->pool[so->start[i].offset]), so->start[i].size); - } - - for (i = 0; i < so->cur_reloc; i++) { - struct nouveau_stateobj_reloc *r = &so->reloc[i]; - - if ((ret = nouveau_pushbuf_emit_reloc(chan, chan->cur - nr + - r->push_offset, r->bo, r->data, - 0, r->flags, r->vor, r->tor))) { - debug_printf("so_emit failed reloc with error %d\n", ret); - assert(0); - } - } -} - -static INLINE void -so_emit_reloc_markers(struct nouveau_channel *chan, struct nouveau_stateobj *so) -{ - unsigned i; - int ret = 0; - - if (!so) - return; - - /* If we need to flush in flush notify, then we have a problem anyway. */ - for (i = 0; i < so->cur_reloc; i++) { - struct nouveau_stateobj_reloc *r = &so->reloc[i]; - -#ifdef DEBUG_NOUVEAU_STATEOBJ - if (r->mthd & 0x40000000) { - debug_printf("error: NI mthd 0x%08X\n", r->mthd); - continue; - } -#endif /* DEBUG_NOUVEAU_STATEOBJ */ - - /* We don't need to autobind, since there are enough subchannels - * for all objects we use. If this is changed, account for the extra - * space in callers of this function. - */ - assert(r->gr->bound != NOUVEAU_GROBJ_UNBOUND); - - /* Some relocs really don't like to be hammered, - * NOUVEAU_BO_DUMMY makes sure it only - * happens when needed. - */ - ret = OUT_RELOC(chan, r->bo, (r->gr->subc << 13) | (1<< 18) | - r->mthd, (r->flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART - | NOUVEAU_BO_RDWR)) | NOUVEAU_BO_DUMMY, 0, 0); - if (ret) { - debug_printf("OUT_RELOC failed %d\n", ret); - assert(0); - } - - ret = OUT_RELOC(chan, r->bo, r->data, r->flags | - NOUVEAU_BO_DUMMY, r->vor, r->tor); - if (ret) { - debug_printf("OUT_RELOC failed %d\n", ret); - assert(0); - } - } -} - -#endif From 040ff18a2116c7acee51c57b7b0442ca18cdb0ad Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 2 Mar 2011 20:57:29 +0100 Subject: [PATCH 18/53] nv50: fix wrong miptree tile flags taken over from nvc0 --- src/gallium/drivers/nv50/nv50_miptree.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index a7bd5bcbb6f..aadffeec36a 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -158,9 +158,6 @@ nv50_miptree_create(struct pipe_screen *pscreen, 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) From 908013b7370f8dfe20a1ab41b353968a60a9055d Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 2 Mar 2011 15:39:57 +0100 Subject: [PATCH 19/53] nv50: apply relocations to shader code On nv50, branches are absolute, so we need to adjust them according to the shader's position in the code buffer. --- src/gallium/drivers/nv50/nv50_shader_state.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index 7d4b12bde17..f5685c1cd7d 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -149,6 +149,8 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) return FALSE; prog->code_base = prog->res->start; + nv50_relocate_program(prog, prog->code_base, 0); + nv50_sifc_linear_u8(&nv50->base, nv50->screen->code, (prog->type << 16) + prog->code_base, NOUVEAU_BO_VRAM, prog->code_size, prog->code); From dbdbbce066de9af2856c207f5de8be7f10c74597 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 2 Mar 2011 15:41:19 +0100 Subject: [PATCH 20/53] nv50: allow accidentally disabled IB index buffers again Must have sneaked in from debugging. --- src/gallium/drivers/nv50/nv50_vbo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index e94a2b6fa3d..85cf9bd8a61 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -536,7 +536,7 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, nv50->state.index_bias = index_bias; } - if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer) && 0) { + if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer)) { struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer); unsigned offset = res->offset + nv50->idxbuf.offset; From 223d98bb8d49c9e52e498a12980722467ae2bf87 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 2 Mar 2011 19:02:59 +0100 Subject: [PATCH 21/53] nv50: fix point sprite state validation Wasn't updated if the FP didn't change, and coordinate replacement wasn't disabled anymore. --- src/gallium/drivers/nv50/nv50_context.h | 3 ++ src/gallium/drivers/nv50/nv50_shader_state.c | 47 +++++++++++++------ .../drivers/nv50/nv50_state_validate.c | 2 + 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index e6079a621a9..46e6c2250af 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -79,8 +79,10 @@ struct nv50_context { struct { uint32_t instance_elts; /* bitmask of per-instance elements */ uint32_t instance_base; + uint32_t interpolant_ctrl; int32_t index_bias; boolean prim_restart; + boolean point_sprite; uint8_t num_vtxbufs; uint8_t num_vtxelts; uint8_t num_textures[3]; @@ -181,6 +183,7 @@ 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 *); +void nv50_sprite_coords_validate(struct nv50_context *); /* nv50_state.c */ extern void nv50_init_state_functions(struct nv50_context *); diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index f5685c1cd7d..ee50ef8ed16 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -223,13 +223,29 @@ nv50_gmtyprog_validate(struct nv50_context *nv50) OUT_RING (chan, gp->code_base); } -static void -nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned m) +void +nv50_sprite_coords_validate(struct nv50_context *nv50) { + struct nouveau_channel *chan = nv50->screen->base.channel; + uint32_t pntc[8], mode; struct nv50_program *fp = nv50->fragprog; unsigned i, c; + unsigned m = (nv50->state.interpolant_ctrl >> 8) & 0xff; - memset(pntc, 0, 8 * sizeof(uint32_t)); + if (!nv50->rast->pipe.point_quad_rasterization) { + if (nv50->state.point_sprite) { + BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 1); + for (i = 0; i < 8; ++i) + OUT_RING(chan, 0); + + nv50->state.point_sprite = FALSE; + } + return; + } else { + nv50->state.point_sprite = TRUE; + } + + memset(pntc, 0, sizeof(pntc)); for (i = 0; i < fp->in_nr; i++) { unsigned n = util_bitcount(fp->in[i].mask); @@ -250,6 +266,17 @@ nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned m) } } } + + if (nv50->rast->pipe.sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT) + mode = 0x00; + else + mode = 0x10; + + BEGIN_RING(chan, RING_3D(POINT_SPRITE_CTRL), 1); + OUT_RING (chan, mode); + + BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 1); + OUT_RINGp (chan, pntc, 8); } static int @@ -291,7 +318,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50) uint32_t psiz = 0x000; uint32_t interp = fp->fp.interp; uint32_t colors = fp->fp.colors; - uint32_t lin[4], pntc[8]; + uint32_t lin[4]; uint8_t map[64]; memset(lin, 0x00, sizeof(lin)); @@ -372,19 +399,11 @@ nv50_fp_linkage_validate(struct nv50_context *nv50) BEGIN_RING(chan, RING_3D(FP_INTERPOLANT_CTRL), 1); OUT_RING (chan, interp); + nv50->state.interpolant_ctrl = interp; + BEGIN_RING(chan, RING_3D(NOPERSPECTIVE_BITMAP(0)), 4); OUT_RINGp (chan, lin, 4); - if (nv50->rast->pipe.point_quad_rasterization) { - nv50_pntc_replace(nv50, pntc, (interp >> 8) & 0xff); - - 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); - } - BEGIN_RING(chan, RING_3D(GP_ENABLE), 1); OUT_RING (chan, nv50->gmtyprog ? 1 : 0); } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index c97927624e4..d0b4af6c41b 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -269,6 +269,8 @@ static struct state_validate { { nv50_fp_linkage_validate, NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG }, { nv50_gp_linkage_validate, NV50_NEW_GMTYPROG | NV50_NEW_VERTPROG }, + { nv50_sprite_coords_validate, NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER | + NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG }, { nv50_constbufs_validate, NV50_NEW_CONSTBUF }, { nv50_validate_textures, NV50_NEW_TEXTURES }, { nv50_validate_samplers, NV50_NEW_SAMPLERS }, From 669de7016ce3e95c6d1e4ee8e41b5bfe95f32105 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 2 Mar 2011 19:21:46 +0100 Subject: [PATCH 22/53] nv50: fix tile size calculations --- src/gallium/drivers/nv50/nv50_miptree.c | 2 +- src/gallium/drivers/nv50/nv50_resource.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index aadffeec36a..ae6b26af1eb 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -61,7 +61,7 @@ static INLINE unsigned calc_zslice_offset(uint32_t tile_mode, unsigned z, unsigned pitch, unsigned nbh) { unsigned tile_h = NV50_TILE_HEIGHT(tile_mode); - unsigned tile_d_shift = NV50_TILE_DIM_SHIFT(tile_mode, 2); + unsigned tile_d_shift = NV50_TILE_DIM_SHIFT(tile_mode, 1); unsigned tile_d = 1 << tile_d_shift; /* stride_2d == to next slice within this volume tile */ diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h index 76229298f7c..0e9f0a2557e 100644 --- a/src/gallium/drivers/nv50/nv50_resource.h +++ b/src/gallium/drivers/nv50/nv50_resource.h @@ -21,7 +21,7 @@ nv50_screen_init_resource_functions(struct pipe_screen *pscreen); #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) << \ +#define NV50_TILE_SIZE_2D(m) ((64 * 4) << \ NV50_TILE_DIM_SHIFT(m, 0)) #define NV50_TILE_SIZE(m) (NV50_TILE_SIZE_2D(m) << NV50_TILE_DIM_SHIFT(m, 1)) From ddcb90248fb491a3a9e2ada8c595f94b0bd95515 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 2 Mar 2011 19:41:08 +0100 Subject: [PATCH 23/53] nv50: implement independent blend functions for nva3+ and fix cap --- src/gallium/drivers/nv50/nv50_screen.c | 3 ++- src/gallium/drivers/nv50/nv50_state.c | 31 +++++++++++++++++++++--- src/gallium/drivers/nv50/nv50_stateobj.h | 6 ++++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index f2b03e8156e..2bc26e57500 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -115,8 +115,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 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_INDEP_BLEND_FUNC: + return nv50_screen(pscreen)->base.device->chipset >= 0xa3; case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 1; diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 17f272bb3bf..2f6fdb4c48c 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -88,7 +88,14 @@ nv50_blend_state_create(struct pipe_context *pipe, { struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj); int i; - boolean blend_enabled = cso->rt[0].blend_enable; + boolean emit_common_func = cso->rt[0].blend_enable; + + const uint32_t chipset = nv50_context(pipe)->screen->base.device->chipset; + + if (chipset >= 0xa3) { + SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1); + SB_DATA (so, cso->independent_blend_enable); + } so->pipe = *cso; @@ -97,14 +104,30 @@ nv50_blend_state_create(struct pipe_context *pipe, for (i = 0; i < 8; ++i) { SB_DATA(so, cso->rt[i].blend_enable); if (cso->rt[i].blend_enable) - blend_enabled = TRUE; + emit_common_func = TRUE; + } + + if (chipset >= 0xa3) { + emit_common_func = FALSE; + + for (i = 0; i < 8; ++i) { + if (!cso->rt[i].blend_enable) + continue; + SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6); + SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func)); + SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_src_factor)); + SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor)); + SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func)); + SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_src_factor)); + SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor)); + } } } else { for (i = 0; i < 8; ++i) - SB_DATA(so, blend_enabled); + SB_DATA(so, cso->rt[0].blend_enable); } - if (blend_enabled) { + if (emit_common_func) { 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)); diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h index 49f1837bfeb..f4e458b0c05 100644 --- a/src/gallium/drivers/nv50/nv50_stateobj.h +++ b/src/gallium/drivers/nv50/nv50_stateobj.h @@ -10,12 +10,16 @@ (so)->state[(so)->size++] = \ ((s) << 18) | (NV50_SUBCH_3D << 13) | NV50_3D_##m +#define SB_BEGIN_3D_(so, m, s) \ + (so)->state[(so)->size++] = \ + ((s) << 18) | (NV50_SUBCH_3D << 13) | 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]; + uint32_t state[78]; }; struct nv50_tsc_entry { From b8646bc2af87f4b2cde50980da878b89d09cdf96 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 2 Mar 2011 20:15:01 +0100 Subject: [PATCH 24/53] nv50: fix depth clamp for disabled primitive clipping --- src/gallium/drivers/nv50/nv50_state_validate.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index d0b4af6c41b..bf46296e7ef 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -197,9 +197,19 @@ nv50_validate_clip(struct nv50_context *nv50) struct nouveau_channel *chan = nv50->screen->base.channel; uint32_t clip; - clip = nv50->clip.depth_clamp ? 0x0018 : 0x0000; + if (nv50->clip.depth_clamp) { + clip = + NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR | + NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR | + NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1; + } else { + clip = 0; + } + #ifndef NV50_SCISSORS_CLIPPING - clip |= 0x1080; + clip |= + NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7 | + NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1; #endif BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1); From 47a62b1ca1357ea1f60ae60dd0cfd72f8e5fa1b3 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 2 Mar 2011 20:48:20 +0100 Subject: [PATCH 25/53] nv50: primitive restart trick for vertex data through FIFO mode Also, on nv50 the VERTEX_BEGIN method doesn't follow VERTEX_END, which was erroneously taken over from nvc0 and is fixed now. --- src/gallium/drivers/nv50/nv50_push.c | 29 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c index 71b5995a4f8..e8ad1ddd38a 100644 --- a/src/gallium/drivers/nv50/nv50_push.c +++ b/src/gallium/drivers/nv50/nv50_push.c @@ -86,10 +86,8 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count) 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)); + BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1); + OUT_RING (ctx->chan, ctx->restart_index); } } } @@ -121,10 +119,8 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count) 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)); + BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1); + OUT_RING (ctx->chan, ctx->restart_index); } } } @@ -156,10 +152,8 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count) 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)); + BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1); + OUT_RING (ctx->chan, ctx->restart_index); } } } @@ -257,6 +251,17 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) ctx.instance_id = info->start_instance; ctx.prim = nv50_prim_gl(info->mode); + if (info->primitive_restart) { + BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 2); + OUT_RING (ctx.chan, 1); + OUT_RING (ctx.chan, info->restart_index); + } else + if (nv50->state.prim_restart) { + BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 1); + OUT_RING (ctx.chan, 0); + } + nv50->state.prim_restart = info->primitive_restart; + while (inst--) { BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1); OUT_RING (ctx.chan, ctx.prim); From fa94f8b209c111f2c3cd9250d9fec6cd03726114 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 2 Mar 2011 21:07:33 +0100 Subject: [PATCH 26/53] nv50: fix POINT_COORD_REPLACE_MAP method size Introduced in 223d98bb8d49c9e52e498a12980722467ae2bf87. --- src/gallium/drivers/nv50/nv50_shader_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index ee50ef8ed16..f7d78a3b11b 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -234,7 +234,7 @@ nv50_sprite_coords_validate(struct nv50_context *nv50) if (!nv50->rast->pipe.point_quad_rasterization) { if (nv50->state.point_sprite) { - BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 1); + BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8); for (i = 0; i < 8; ++i) OUT_RING(chan, 0); @@ -275,7 +275,7 @@ nv50_sprite_coords_validate(struct nv50_context *nv50) BEGIN_RING(chan, RING_3D(POINT_SPRITE_CTRL), 1); OUT_RING (chan, mode); - BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 1); + BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8); OUT_RINGp (chan, pntc, 8); } From 0c0e996d59380af2d247336e3e9cfae58a80791a Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 2 Mar 2011 22:36:22 +0100 Subject: [PATCH 27/53] nv50: fix IB index buffer path Add missing VERTEX_END and treat unaligned offsets correctly. --- src/gallium/drivers/nv50/nv50_vbo.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 85cf9bd8a61..4f0a5018459 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -538,7 +538,8 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer)) { struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer); - unsigned offset = res->offset + nv50->idxbuf.offset; + + start += nv50->idxbuf.offset >> (index_size >> 1); nouveau_buffer_adjust_score(&nv50->base, res, 1); @@ -552,9 +553,8 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, 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)); + nouveau_pushbuf_submit(chan, res->bo, res->offset + start * 4, + count * 4); } break; case 2: @@ -564,10 +564,11 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1); OUT_RING (chan, (start << 31) | count); + WAIT_RING (chan, 2); 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); + nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start * 2, + pb_words * 4); BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1); OUT_RING (chan, 0); break; @@ -579,10 +580,11 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1); OUT_RING (chan, (start << 30) | count); + WAIT_RING (chan, 2); 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); + nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start, + pb_words * 4); BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1); OUT_RING (chan, 0); break; @@ -591,6 +593,8 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten, assert(0); return; } + BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1); + OUT_RING (chan, 0); nv50_resource_fence(res, NOUVEAU_BO_RD); From 118ecb1a2226494929a87c36b7802b64451ca004 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 3 Mar 2011 10:30:06 +0800 Subject: [PATCH 28/53] i965: SNB GT1 has only 32k urb and max 128 urb entries. Signed-off-by: Zou Nan hai --- src/mesa/drivers/dri/i965/gen6_urb.c | 19 +++++++++++++++---- src/mesa/drivers/dri/intel/intel_chipset.h | 4 ++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mesa/drivers/dri/i965/gen6_urb.c b/src/mesa/drivers/dri/i965/gen6_urb.c index 57be50a4451..c3819f9b360 100644 --- a/src/mesa/drivers/dri/i965/gen6_urb.c +++ b/src/mesa/drivers/dri/i965/gen6_urb.c @@ -34,15 +34,26 @@ static void prepare_urb( struct brw_context *brw ) { - brw->urb.nr_vs_entries = 256; - brw->urb.nr_gs_entries = 256; + int urb_size, max_urb_entry; + struct intel_context *intel = &brw->intel; + + if (IS_GT1(intel->intelScreen->deviceID)) { + urb_size = 32 * 1024; + max_urb_entry = 128; + } else { + urb_size = 64 * 1024; + max_urb_entry = 256; + } + + brw->urb.nr_vs_entries = max_urb_entry; + brw->urb.nr_gs_entries = max_urb_entry; /* CACHE_NEW_VS_PROG */ brw->urb.vs_size = MAX2(brw->vs.prog_data->urb_entry_size, 1); - if (256 * brw->urb.vs_size > 64 * 1024) + if (2 * brw->urb.vs_size > urb_size) brw->urb.nr_vs_entries = brw->urb.nr_gs_entries = - (64 * 1024 ) / brw->urb.vs_size; + (urb_size ) / (2 * brw->urb.vs_size); } static void diff --git a/src/mesa/drivers/dri/intel/intel_chipset.h b/src/mesa/drivers/dri/intel/intel_chipset.h index 4fecdbed203..4ff9140d56e 100644 --- a/src/mesa/drivers/dri/intel/intel_chipset.h +++ b/src/mesa/drivers/dri/intel/intel_chipset.h @@ -133,6 +133,10 @@ devid == PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS || \ devid == PCI_CHIP_SANDYBRIDGE_S) +#define IS_GT1(devid) (devid == PCI_CHIP_SANDYBRIDGE_GT1 || \ + devid == PCI_CHIP_SANDYBRIDGE_M_GT1 || \ + devid == PCI_CHIP_SANDYBRIDGE_S) + #define IS_965(devid) (IS_GEN4(devid) || \ IS_G4X(devid) || \ IS_GEN5(devid) || \ From 6b4e3e8941f41b6d15ac557e3d47bf4f1aa8b185 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 3 Mar 2011 15:56:20 +1000 Subject: [PATCH 29/53] nouveau: allow pipe driver to define which buffers should start in sysmem PIPE_BIND_CONSTANT_BUFFER alone was OK for nv50/nvc0, but nv30 will need to be able to set others on certain chipsets. Signed-off-by: Ben Skeggs --- src/gallium/drivers/nouveau/nouveau_buffer.c | 2 +- src/gallium/drivers/nouveau/nouveau_screen.h | 1 + src/gallium/drivers/nv50/nv50_screen.c | 5 ++--- src/gallium/drivers/nvc0/nvc0_screen.c | 5 ++--- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index 571fa0c608b..d0cc29104b8 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -340,7 +340,7 @@ nouveau_buffer_create(struct pipe_screen *pscreen, pipe_reference_init(&buffer->base.reference, 1); buffer->base.screen = pscreen; - if (buffer->base.bind & PIPE_BIND_CONSTANT_BUFFER) + if ((buffer->base.bind & screen->sysmem_bindings) == screen->sysmem_bindings) ret = nouveau_buffer_allocate(screen, buffer, 0); else ret = nouveau_buffer_allocate(screen, buffer, NOUVEAU_BO_GART); diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index 580b4da6b4e..c091abf2786 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -16,6 +16,7 @@ struct nouveau_screen { * these almost always should be set to the same value */ unsigned vertex_buffer_flags; unsigned index_buffer_flags; + unsigned sysmem_bindings; struct { struct nouveau_fence *head; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 2bc26e57500..3f148436e81 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -293,6 +293,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; pscreen = &screen->base.base; + screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; + ret = nouveau_screen_init(&screen->base, dev); if (ret) FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret); @@ -309,9 +311,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) 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) diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index b84a1bee8da..923bb83e8a3 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -358,6 +358,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; pscreen = &screen->base.base; + screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; + ret = nouveau_screen_init(&screen->base, dev); if (ret) { nvc0_screen_destroy(pscreen); @@ -375,9 +377,6 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) nvc0_screen_init_resource_functions(pscreen); - screen->base.vertex_buffer_flags = NOUVEAU_BO_GART; - screen->base.index_buffer_flags = 0; - ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &screen->fence.bo); if (ret) From 7048ad62f89289c9e642203c009dca38ce8753f8 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Thu, 3 Mar 2011 12:25:12 +0100 Subject: [PATCH 30/53] nv50: increase size of shader code bo 512 KiB should be quite enough, but dynamic resize might be nicer. --- src/gallium/drivers/nv50/nv50_pc_emit.c | 3 ++- src/gallium/drivers/nv50/nv50_screen.c | 25 +++++++++++--------- src/gallium/drivers/nv50/nv50_screen.h | 2 ++ src/gallium/drivers/nv50/nv50_shader_state.c | 7 ++++-- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_pc_emit.c b/src/gallium/drivers/nv50/nv50_pc_emit.c index f37dc51e6aa..252c58dd8ff 100644 --- a/src/gallium/drivers/nv50/nv50_pc_emit.c +++ b/src/gallium/drivers/nv50/nv50_pc_emit.c @@ -762,7 +762,8 @@ emit_flow(struct nv_pc *pc, struct nv_instruction *i, ubyte flow_op) new_fixup(pc, NV50_FIXUP_CODE_RELOC, 0, pos, 0xffff << 11, 9); new_fixup(pc, NV50_FIXUP_CODE_RELOC, 1, pos, 0x3f << 14, -4); - pc->emit[0] |= (pos / 4) << 11; + pc->emit[0] |= ((pos >> 2) & 0xffff) << 11; + pc->emit[1] |= ((pos >> 18) & 0x003f) << 14; } } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 3f148436e81..3ccaff2838a 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -286,7 +286,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) uint32_t tesla_class; unsigned stack_size, max_warps, tls_space; int ret; - unsigned i; + unsigned i, base; screen = CALLOC_STRUCT(nv50_screen); if (!screen) @@ -425,25 +425,28 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) 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); + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, + 3 << NV50_CODE_BO_SIZE_LOG2, &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); + nouveau_resource_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); + nouveau_resource_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); + nouveau_resource_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2); + + base = 1 << NV50_CODE_BO_SIZE_LOG2; 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); + OUT_RELOCh(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->code, base * 0, 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); + OUT_RELOCh(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->code, base * 1, 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); + OUT_RELOCh(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 3886d8068cc..aea434b8679 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -14,6 +14,8 @@ struct nv50_context; +#define NV50_CODE_BO_SIZE_LOG2 19 + #define NV50_SCRATCH_SIZE (2 << 20) #define NV50_SCRATCH_NR_BUFFERS 2 diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index f7d78a3b11b..bea9c095bb3 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -138,6 +138,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) return FALSE; if (prog->type == PIPE_SHADER_FRAGMENT) heap = nv50->screen->fp_code_heap; + else if (prog->type == PIPE_SHADER_GEOMETRY) heap = nv50->screen->gp_code_heap; else heap = nv50->screen->vp_code_heap; @@ -145,14 +146,16 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog) size = align(prog->code_size, 0x100); ret = nouveau_resource_alloc(heap, size, prog, &prog->res); - if (ret) + if (ret) { + NOUVEAU_ERR("out of code space for shader type %i\n", prog->type); return FALSE; + } prog->code_base = prog->res->start; nv50_relocate_program(prog, prog->code_base, 0); nv50_sifc_linear_u8(&nv50->base, nv50->screen->code, - (prog->type << 16) + prog->code_base, + (prog->type << NV50_CODE_BO_SIZE_LOG2) + prog->code_base, NOUVEAU_BO_VRAM, prog->code_size, prog->code); BEGIN_RING(nv50->screen->base.channel, RING_3D(CODE_CB_FLUSH), 1); From 3bf92a281bdc6ebf2ec5975729d02bd9062e11f5 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Thu, 3 Mar 2011 12:31:35 +0100 Subject: [PATCH 31/53] nv50: check grclass instead of chipset for 3D caps --- src/gallium/drivers/nv50/nv50_screen.c | 4 ++-- src/gallium/drivers/nv50/nv50_state.c | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 3ccaff2838a..ae0365eb5c5 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -59,7 +59,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, switch (format) { case PIPE_FORMAT_Z16_UNORM: - if ((nouveau_screen(pscreen)->device->chipset & 0xf0) != 0xa0) + if (nv50_screen(pscreen)->tesla->grclass < NVA0_3D) return FALSE; break; default: @@ -117,7 +117,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_INDEP_BLEND_ENABLE: return 1; case PIPE_CAP_INDEP_BLEND_FUNC: - return nv50_screen(pscreen)->base.device->chipset >= 0xa3; + return nv50_screen(pscreen)->tesla->grclass >= NVA3_3D; case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 1; diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 2f6fdb4c48c..3d6423b2238 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -90,9 +90,7 @@ nv50_blend_state_create(struct pipe_context *pipe, int i; boolean emit_common_func = cso->rt[0].blend_enable; - const uint32_t chipset = nv50_context(pipe)->screen->base.device->chipset; - - if (chipset >= 0xa3) { + if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) { SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1); SB_DATA (so, cso->independent_blend_enable); } @@ -107,7 +105,7 @@ nv50_blend_state_create(struct pipe_context *pipe, emit_common_func = TRUE; } - if (chipset >= 0xa3) { + if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) { emit_common_func = FALSE; for (i = 0; i < 8; ++i) { From 8987109c27899273bffca941c48b466218ba56ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 3 Mar 2011 15:28:36 +0000 Subject: [PATCH 32/53] scons: Always load lex/yacc tool. lex/yacc is not loaded by default when toolchain is not default either, e.g., when toolchain=crossmingw. --- scons/gallium.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scons/gallium.py b/scons/gallium.py index 112f6c89dca..34523d5898b 100755 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -598,6 +598,8 @@ def generate(env): env.Append(LIBS = []) # Load tools + env.Tool('lex') + env.Tool('yacc') if env['llvm']: env.Tool('llvm') env.Tool('udis86') From 54d8c5e3c2fc7db643a2bae61be203ab9cbb1efa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 3 Mar 2011 15:42:58 +0000 Subject: [PATCH 33/53] scons: Add human friendlier build messages for lex/yacc. --- scons/custom.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scons/custom.py b/scons/custom.py index 364da292dd3..7c59fe985d0 100644 --- a/scons/custom.py +++ b/scons/custom.py @@ -56,6 +56,8 @@ def quietCommandLines(env): env['SHLINKCOMSTR'] = " Linking $TARGET ..." env['LDMODULECOMSTR'] = " Linking $TARGET ..." env['SWIGCOMSTR'] = " Generating $TARGET ..." + env['LEXCOMSTR'] = " Generating $TARGET ..." + env['YACCCOMSTR'] = " Generating $TARGET ..." env['CODEGENCOMSTR'] = " Generating $TARGET ..." From dbfbb8cf6da472e9000481ebd6a2a6b4e4845560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 3 Mar 2011 15:43:18 +0000 Subject: [PATCH 34/53] scons: Ensure generated headers are in the include path. --- src/glsl/SConscript | 3 +++ src/mesa/SConscript | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/glsl/SConscript b/src/glsl/SConscript index 10abab6f945..c2e5d45ebad 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -24,6 +24,9 @@ glcpp_parser = env.CFile('glcpp/glcpp-parse.c', 'glcpp/glcpp-parse.y') glsl_lexer = parser_env.CXXFile('glsl_lexer.cpp', 'glsl_lexer.ll') glsl_parser = parser_env.CXXFile('glsl_parser.cpp', 'glsl_parser.yy') +# Make glcpp/glcpp-parse.h reacheable from the include path +env.Append(CPPPATH = [glcpp_parser[0].dir.up()]) + sources = [ glcpp_lexer, glcpp_parser[0], diff --git a/src/mesa/SConscript b/src/mesa/SConscript index acbf86ebd2d..ca36bf27f94 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -218,6 +218,10 @@ env.Append(YACCFLAGS = '-d') program_lex = env.CFile('program/lex.yy.c', 'program/program_lexer.l') program_parse = env.CFile('program/program_parse.tab.c', 'program/program_parse.y') + +# Make program/program_parse.tab.h reacheable from the include path +env.Append(CPPPATH = [program_parse[0].dir.up()]) + program_sources = [ 'program/arbprogparse.c', 'program/hash_table.c', From 5d0e8beaa2051c28a7ac941e8aaad286e39e1267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 3 Mar 2011 16:57:38 +0000 Subject: [PATCH 35/53] scons: More tweaks to fix MinGW build. --- src/glsl/SConscript | 21 ++++++++++++++++----- src/mesa/SConscript | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/glsl/SConscript b/src/glsl/SConscript index c2e5d45ebad..bb02a87c790 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -14,19 +14,22 @@ env.Prepend(CPPPATH = [ '#src/glsl/glcpp', ]) +# Make glcpp/glcpp-parse.h and glsl_parser.h reacheable from the include path +env.Append(CPPPATH = [Dir('.').abspath]) + env.Append(YACCFLAGS = '-d') -parser_env = env.Clone(); -parser_env.Append(YACCFLAGS = ['--defines=src/glsl/glsl_parser.h', '-p', '_mesa_glsl_']) +parser_env = env.Clone() +parser_env.Append(YACCFLAGS = [ + '--defines=%s' % File('glsl_parser.h').abspath, + '-p', '_mesa_glsl_', +]) glcpp_lexer = env.CFile('glcpp/glcpp-lex.c', 'glcpp/glcpp-lex.l') glcpp_parser = env.CFile('glcpp/glcpp-parse.c', 'glcpp/glcpp-parse.y') glsl_lexer = parser_env.CXXFile('glsl_lexer.cpp', 'glsl_lexer.ll') glsl_parser = parser_env.CXXFile('glsl_parser.cpp', 'glsl_parser.yy') -# Make glcpp/glcpp-parse.h reacheable from the include path -env.Append(CPPPATH = [glcpp_parser[0].dir.up()]) - sources = [ glcpp_lexer, glcpp_parser[0], @@ -110,6 +113,10 @@ else: '#src/mesa/program/symbol_table.c'], ) + # SCons builtin dependency scanner doesn't detect that glsl_lexer.ll + # depends on glsl_parser.h + env.Depends(builtin_compiler, glsl_parser) + builtin_glsl_function = env.CodeGenerate( target = 'builtin_function.cpp', script = 'builtins/tools/generate_builtins.py', @@ -132,6 +139,10 @@ glsl = env.ConvenienceLibrary( source = sources, ) +# SCons builtin dependency scanner doesn't detect that glsl_lexer.ll depends on +# glsl_parser.h +env.Depends(glsl, glsl_parser) + Export('glsl') # FIXME: We can't build the programs because there's a cyclic dependency between tis directory and src/mesa diff --git a/src/mesa/SConscript b/src/mesa/SConscript index ca36bf27f94..7e8bb2486c3 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -220,7 +220,7 @@ program_parse = env.CFile('program/program_parse.tab.c', 'program/program_parse.y') # Make program/program_parse.tab.h reacheable from the include path -env.Append(CPPPATH = [program_parse[0].dir.up()]) +env.Append(CPPPATH = [Dir('.').abspath]) program_sources = [ 'program/arbprogparse.c', From 4bd27cfecc236a0552d31782a6e122da4602c927 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 3 Mar 2011 18:25:49 +0000 Subject: [PATCH 36/53] rbug: Fix depth stencil surface not being sent to the client --- src/gallium/drivers/rbug/rbug_context.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c index 3aefb5b3bb5..4a5d5413d8c 100644 --- a/src/gallium/drivers/rbug/rbug_context.c +++ b/src/gallium/drivers/rbug/rbug_context.c @@ -544,6 +544,7 @@ rbug_set_framebuffer_state(struct pipe_context *_pipe, rb_pipe->curr.nr_cbufs = 0; memset(rb_pipe->curr.cbufs, 0, sizeof(rb_pipe->curr.cbufs)); + rb_pipe->curr.zsbuf = NULL; /* unwrap the input state */ if (_state) { @@ -556,6 +557,8 @@ rbug_set_framebuffer_state(struct pipe_context *_pipe, rb_pipe->curr.cbufs[i] = rbug_resource(_state->cbufs[i]->texture); } unwrapped_state.zsbuf = rbug_surface_unwrap(_state->zsbuf); + if (_state->zsbuf) + rb_pipe->curr.zsbuf = rbug_resource(_state->zsbuf->texture); state = &unwrapped_state; } From b56f30c2b23f6d7b5499f01fa2d3ee04f2ce546e Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 2 Mar 2011 23:26:24 -0800 Subject: [PATCH 37/53] glcpp/tests: Update 063-comments.c.expected to match output. The expected result has been out of sync with what glcpp produces for some time; glcpp's actual result seems to be correct and is very close to GCC's cpp. Updating this will make it easier to catch regressions in upcoming commits. --- src/glsl/glcpp/tests/063-comments.c.expected | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/glsl/glcpp/tests/063-comments.c.expected b/src/glsl/glcpp/tests/063-comments.c.expected index ed4feedd457..73ca7071faa 100644 --- a/src/glsl/glcpp/tests/063-comments.c.expected +++ b/src/glsl/glcpp/tests/063-comments.c.expected @@ -5,8 +5,15 @@ f = g /h; l(); m = n + p; + + + + + + more code here + are not treated like comments. From f20656e9446b9acde55b9dd41a2b47d7d5b7a56a Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 1 Mar 2011 12:24:58 -0800 Subject: [PATCH 38/53] glcpp: Rework lexer to use a SKIP state rather than REJECT. Previously, the rule deleted by this commit was matched every single time (being the longest match). If not skipping, it used REJECT to continue on to the actual correct rule. The flex manual advises against using REJECT where possible, as it is one of the most expensive lexer features. So using it on every match seems undesirable. Perhaps more importantly, it made it necessary for the #if directive rules to contain a look-ahead pattern to make them as long as the (now deleted) "skip the whole line" rule. This patch introduces an exclusive start state, SKIP, to avoid REJECTs. Each time the lexer is called, the code at the top of the rules section will run, implicitly switching the state to the correct one. Fixes piglit tests 16384-consecutive-chars.frag and 16385-consecutive-chars.frag. --- src/glsl/glcpp/glcpp-lex.l | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l index 11b73aea88b..2c9eda68d6e 100644 --- a/src/glsl/glcpp/glcpp-lex.l +++ b/src/glsl/glcpp/glcpp-lex.l @@ -57,7 +57,7 @@ void glcpp_set_column (int column_no , yyscan_t yyscanner); %option stack %option never-interactive -%x DONE COMMENT UNREACHABLE +%x DONE COMMENT UNREACHABLE SKIP SPACE [[:space:]] NONSPACE [^[:space:]] @@ -74,6 +74,17 @@ OCTAL_INTEGER 0[0-7]*[uU]? HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? %% + /* Implicitly switch between SKIP and INITIAL (non-skipping); + * don't switch if some other state was explicitly set. + */ + glcpp_parser_t *parser = yyextra; + if (YY_START == 0 || YY_START == SKIP) { + if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) { + BEGIN 0; + } else { + BEGIN SKIP; + } + } /* Single-line comments */ "//"[^\n]* { @@ -137,6 +148,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? yylineno = strtol(ptr, &ptr, 0) - 1; } +{ {HASH}ifdef/.*\n { yyextra->lexing_if = 1; yyextra->space_tokens = 0; @@ -170,27 +182,10 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? yyextra->space_tokens = 0; return HASH_ENDIF; } - - /* When skipping (due to an #if 0 or similar) consume anything - * up to a newline. We do this with less priority than any - * #if-related directive (#if, #elif, #else, #endif), but with - * more priority than any other directive or token to avoid - * any side-effects from skipped content. - * - * We use the lexing_if flag to avoid skipping any part of an - * if conditional expression. */ -[^\n]+/\n { - /* Since this rule always matches, YY_USER_ACTION gets called for it, - * wrongly incrementing yycolumn. We undo that effect here. */ - yycolumn -= yyleng; - if (yyextra->lexing_if || - yyextra->skip_stack == NULL || - yyextra->skip_stack->type == SKIP_NO_SKIP) - { - REJECT; - } } +[^\n] ; + {HASH}error.* { char *p; for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */ @@ -293,7 +288,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? } } -\n { +\n { yyextra->lexing_if = 0; yylineno++; yycolumn = 0; From 09e1bebc25140eecafa0c3eacefcf63010ce4f10 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 3 Mar 2011 09:52:36 -0800 Subject: [PATCH 39/53] glcpp: Remove trailing contexts from #if rules. These are now unnecessary. --- src/glsl/glcpp/glcpp-lex.l | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l index 2c9eda68d6e..68e44eb7902 100644 --- a/src/glsl/glcpp/glcpp-lex.l +++ b/src/glsl/glcpp/glcpp-lex.l @@ -149,36 +149,36 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? } { -{HASH}ifdef/.*\n { +{HASH}ifdef { yyextra->lexing_if = 1; yyextra->space_tokens = 0; return HASH_IFDEF; } -{HASH}ifndef/.*\n { +{HASH}ifndef { yyextra->lexing_if = 1; yyextra->space_tokens = 0; return HASH_IFNDEF; } -{HASH}if/[^_a-zA-Z0-9].*\n { +{HASH}if/[^_a-zA-Z0-9] { yyextra->lexing_if = 1; yyextra->space_tokens = 0; return HASH_IF; } -{HASH}elif/.*\n { +{HASH}elif { yyextra->lexing_if = 1; yyextra->space_tokens = 0; return HASH_ELIF; } -{HASH}else/.*\n { +{HASH}else { yyextra->space_tokens = 0; return HASH_ELSE; } -{HASH}endif/.*\n { +{HASH}endif { yyextra->space_tokens = 0; return HASH_ENDIF; } From 9f3c59a35093c61fb11aab6d3ed5cb45f2b8c2a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 3 Mar 2011 19:15:24 +0000 Subject: [PATCH 40/53] tgsi: Update assert. Elements(mach->Inputs) is wrong now that mach->Inputs is dynamically allocated. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 6576c74fbde..9cf74a838fe 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1084,7 +1084,7 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, }*/ int pos = index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i]; assert(pos >= 0); - assert(pos < Elements(mach->Inputs)); + assert(pos < TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS); chan->u[i] = mach->Inputs[pos].xyzw[swizzle].u[i]; } break; From 137d44e0f2ce7d99d34f301f7d943645cefb289c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Mar 2011 08:42:33 +1000 Subject: [PATCH 41/53] r600g: disable tiling by default again. we still have a lot of corner cases that aren't working. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_texture.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 483292198ec..df83302b38e 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -415,10 +415,10 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, */ if (force_tiling == -1) { struct r600_screen *rscreen = (struct r600_screen *)screen; - if (r600_get_minor_version(rscreen->radeon) >= 9) - force_tiling = debug_get_bool_option("R600_TILING", TRUE); - else - force_tiling = debug_get_bool_option("R600_TILING", FALSE); + /* reenable when 2D tiling is fixed better */ + /*if (r600_get_minor_version(rscreen->radeon) >= 9) + force_tiling = debug_get_bool_option("R600_TILING", TRUE);*/ + force_tiling = debug_get_bool_option("R600_TILING", FALSE); } if (force_tiling && permit_hardware_blit(screen, templ)) { From b93684f5f311f89c965960ab42bfea71a397b180 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 3 Mar 2011 11:25:30 +0000 Subject: [PATCH 42/53] i965: Prevent using a zero sized (or of unknown type) vertex array Signed-off-by: Chris Wilson --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 185f1ffa598..351ae0728e2 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -208,7 +208,7 @@ static GLuint get_surface_type( GLenum type, GLuint size, case GL_UNSIGNED_SHORT: return ushort_types_scale[size]; case GL_UNSIGNED_BYTE: return ubyte_types_scale[size]; default: assert(0); return 0; - } + } } } @@ -225,11 +225,11 @@ static GLuint get_size( GLenum type ) case GL_UNSIGNED_INT: return sizeof(GLuint); case GL_UNSIGNED_SHORT: return sizeof(GLushort); case GL_UNSIGNED_BYTE: return sizeof(GLubyte); - default: return 0; - } + default: assert(0); return 0; + } } -static GLuint get_index_type(GLenum type) +static GLuint get_index_type(GLenum type) { switch (type) { case GL_UNSIGNED_BYTE: return BRW_INDEX_BYTE; @@ -295,7 +295,8 @@ static void brw_prepare_vertices(struct brw_context *brw) struct brw_vertex_element *input = &brw->vb.inputs[i]; vs_inputs &= ~(1 << i); - brw->vb.enabled[brw->vb.nr_enabled++] = input; + if (input->glarray->Size && get_size(input->glarray->Type)) + brw->vb.enabled[brw->vb.nr_enabled++] = input; } if (brw->vb.nr_enabled == 0) From 1c0d09cd4efabf4e804780ebc45f1d120f6509c5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 27 Feb 2011 19:21:54 +0000 Subject: [PATCH 43/53] intel: Add couple of missing gen6 commands to decode Signed-off-by: Chris Wilson --- src/mesa/drivers/dri/intel/intel_decode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mesa/drivers/dri/intel/intel_decode.c b/src/mesa/drivers/dri/intel/intel_decode.c index 25b4131594f..688b8fee642 100644 --- a/src/mesa/drivers/dri/intel/intel_decode.c +++ b/src/mesa/drivers/dri/intel/intel_decode.c @@ -1601,10 +1601,12 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int { 0x790a, 3, 3, "3DSTATE_AA_LINE_PARAMETERS" }, { 0x790b, 4, 4, "3DSTATE_GS_SVB_INDEX" }, { 0x790d, 3, 3, "3DSTATE_MULTISAMPLE" }, + { 0x7910, 2, 2, "3DSTATE_CLEAR_PARAMS" }, { 0x7b00, 6, 6, "3DPRIMITIVE" }, { 0x7802, 4, 4, "3DSTATE_SAMPLER_STATE_POINTERS" }, { 0x7805, 3, 3, "3DSTATE_URB" }, { 0x780e, 4, 4, "3DSTATE_CC_STATE_POINTERS" }, + { 0x780f, 2, 2, "3DSTATE_SCISSOR_STATE_POINTERS" }, { 0x7810, 6, 6, "3DSTATE_VS_STATE" }, { 0x7811, 7, 7, "3DSTATE_GS_STATE" }, { 0x7812, 4, 4, "3DSTATE_CLIP_STATE" }, From 1546291e5b8d3ac02f5bee38252f9d479bcf95cc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 3 Mar 2011 15:56:39 +0000 Subject: [PATCH 44/53] i965: Align index to type size and flush if the type changes Signed-off-by: Chris Wilson --- src/mesa/drivers/dri/i965/brw_context.h | 4 ++-- src/mesa/drivers/dri/i965/brw_draw_upload.c | 21 ++++++++++++------- .../drivers/dri/intel/intel_buffer_objects.c | 6 +++--- .../drivers/dri/intel/intel_buffer_objects.h | 1 + src/mesa/drivers/dri/intel/intel_tex_image.c | 3 ++- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 897220b6ea3..26a6388f342 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -517,9 +517,9 @@ struct brw_context */ const struct _mesa_index_buffer *ib; - /* Updates to these fields are signaled by BRW_NEW_INDEX_BUFFER. */ + /* Updates are signaled by BRW_NEW_INDEX_BUFFER. */ drm_intel_bo *bo; - unsigned int offset; + GLuint type; /* Offset to index buffer index to use in CMD_3D_PRIM so that we can * avoid re-uploading the IB packet over and over if we're actually diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 351ae0728e2..4478ef936e9 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -343,7 +343,8 @@ static void brw_prepare_vertices(struct brw_context *brw) struct brw_vertex_buffer *buffer = &brw->vb.buffers[j]; /* Named buffer object: Just reference its contents directly. */ - buffer->bo = intel_bufferobj_source(intel, intel_buffer, + buffer->bo = intel_bufferobj_source(intel, + intel_buffer, type_size, &buffer->offset); drm_intel_bo_reference(buffer->bo); buffer->offset += (uintptr_t)glarray->Ptr; @@ -670,7 +671,6 @@ static void brw_prepare_indices(struct brw_context *brw) intel_upload_data(&brw->intel, index_buffer->ptr, ib_size, ib_type_size, &bo, &offset); brw->ib.start_vertex_offset = offset / ib_type_size; - offset = 0; } else { offset = (GLuint) (unsigned long) index_buffer->ptr; @@ -687,7 +687,6 @@ static void brw_prepare_indices(struct brw_context *brw) intel_upload_data(&brw->intel, map, ib_size, ib_type_size, &bo, &offset); brw->ib.start_vertex_offset = offset / ib_type_size; - offset = 0; ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobj); } else { @@ -697,22 +696,30 @@ static void brw_prepare_indices(struct brw_context *brw) */ brw->ib.start_vertex_offset = offset / ib_type_size; - bo = intel_bufferobj_source(intel, intel_buffer_object(bufferobj), + bo = intel_bufferobj_source(intel, + intel_buffer_object(bufferobj), + ib_type_size, &offset); drm_intel_bo_reference(bo); + + brw->ib.start_vertex_offset += offset / ib_type_size; } } - if (brw->ib.bo != bo || brw->ib.offset != offset) { + if (brw->ib.bo != bo) { drm_intel_bo_unreference(brw->ib.bo); brw->ib.bo = bo; - brw->ib.offset = offset; brw_add_validated_bo(brw, brw->ib.bo); brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER; } else { drm_intel_bo_unreference(bo); } + + if (index_buffer->type != brw->ib.type) { + brw->ib.type = index_buffer->type; + brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER; + } } const struct brw_tracked_state brw_indices = { @@ -739,7 +746,7 @@ static void brw_emit_index_buffer(struct brw_context *brw) 1); OUT_RELOC(brw->ib.bo, I915_GEM_DOMAIN_VERTEX, 0, - brw->ib.offset); + 0); OUT_RELOC(brw->ib.bo, I915_GEM_DOMAIN_VERTEX, 0, brw->ib.bo->size - 1); diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index 2f750a768af..439d6fc8247 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -723,11 +723,11 @@ void intel_upload_unmap(struct intel_context *intel, drm_intel_bo * intel_bufferobj_source(struct intel_context *intel, struct intel_buffer_object *intel_obj, - GLuint *offset) + GLuint align, GLuint *offset) { if (intel_obj->buffer == NULL) { intel_upload_data(intel, - intel_obj->sys_buffer, intel_obj->Base.Size, 64, + intel_obj->sys_buffer, intel_obj->Base.Size, align, &intel_obj->buffer, &intel_obj->offset); intel_obj->source = 1; } @@ -782,7 +782,7 @@ intel_bufferobj_copy_subdata(struct gl_context *ctx, /* Otherwise, we have real BOs, so blit them. */ dst_bo = intel_bufferobj_buffer(intel, intel_dst, INTEL_WRITE_PART); - src_bo = intel_bufferobj_source(intel, intel_src, &src_offset); + src_bo = intel_bufferobj_source(intel, intel_src, 64, &src_offset); intel_emit_linear_blit(intel, dst_bo, write_offset, diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.h b/src/mesa/drivers/dri/intel/intel_buffer_objects.h index 3ec3a521382..81ee21f0626 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.h @@ -68,6 +68,7 @@ drm_intel_bo *intel_bufferobj_buffer(struct intel_context *intel, GLuint flag); drm_intel_bo *intel_bufferobj_source(struct intel_context *intel, struct intel_buffer_object *obj, + GLuint align, GLuint *offset); void intel_upload_data(struct intel_context *intel, diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 1ffc19756e6..906f8a62710 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -237,7 +237,8 @@ try_pbo_upload(struct intel_context *intel, { GLuint offset; - drm_intel_bo *src_buffer = intel_bufferobj_source(intel, pbo, &offset); + drm_intel_bo *src_buffer = + intel_bufferobj_source(intel, pbo, 64, &offset); if (!intelEmitCopyBlit(intel, intelImage->mt->cpp, From 18dd7932c7fc13e230384bcab08311a5de5d6de7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 3 Mar 2011 18:15:03 +0000 Subject: [PATCH 45/53] i965: Handle URB_FENCE erratum for Broadwater There is a silicon bug which causes unpredictable behaviour if the URB_FENCE command should cross a cache-line boundary. Pad before the command to avoid such occurrences. As this command only applies to gen4/5, do the fixup unconditionally as the specs do not actually state for which chip it was fixed (and the cost is negligible)... Signed-off-by: Chris Wilson --- src/mesa/drivers/dri/i965/brw_urb.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c index dfc1551aca6..b0419d8a420 100644 --- a/src/mesa/drivers/dri/i965/brw_urb.c +++ b/src/mesa/drivers/dri/i965/brw_urb.c @@ -248,5 +248,13 @@ void brw_upload_urb_fence(struct brw_context *brw) uf.bits1.sf_fence = brw->urb.cs_start; uf.bits1.cs_fence = brw->urb.size; + /* erratum: URB_FENCE must not cross a 64byte cacheline */ + if ((brw->intel.batch.used & 15) > 12) { + int pad = 16 - (brw->intel.batch.used & 15); + do + brw->intel.batch.map[brw->intel.batch.used++] = MI_NOOP; + while (--pad); + } + BRW_BATCH_STRUCT(brw, &uf); } From 9d31138f53c0bee9193af73850ab6febddd29f51 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 3 Mar 2011 22:34:22 +0000 Subject: [PATCH 46/53] i965: Fix extending VB packets Computation of the delta of this array from the last had a silly little bug and ignored any initial delta==0 causing grief in Nexuiz and friends. Signed-off-by: Chris Wilson --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 4478ef936e9..e96c32a93a6 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -484,7 +484,7 @@ static void brw_prepare_vertices(struct brw_context *brw) } /* can we simply extend the current vb? */ - if (0 && j == brw->vb.nr_current_buffers) { + if (j == brw->vb.nr_current_buffers) { int delta = 0; for (i = 0; i < j; i++) { int d; @@ -494,7 +494,7 @@ static void brw_prepare_vertices(struct brw_context *brw) break; d = brw->vb.buffers[i].offset - brw->vb.current_buffers[i].offset; - if (delta == 0) + if (i == 0) delta = d / brw->vb.current_buffers[i].stride; if (delta * brw->vb.current_buffers[i].stride != d) break; From d40b868db5b82529cbe07598b2ebef23cc31a7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 4 Mar 2011 11:46:13 +0000 Subject: [PATCH 47/53] gallium: Define __func__ on MSVC. --- src/gallium/include/pipe/p_compiler.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 3d6b5b5c81d..3441db685ce 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -171,6 +171,18 @@ typedef unsigned char boolean; # define __FUNCTION__ "" # endif #endif +#ifndef __func__ +# if (__STDC_VERSION__ >= 199901L) || \ + (defined(__SUNPRO_C) && defined(__C99FEATURES__)) + /* __func__ is part of C99 */ +# elif defined(_MSC_VER) +# if _MSC_VER >= 1300 +# define __func__ __FUNCTION__ +# else +# define __func__ "" +# endif +# endif +#endif From f52660c3dc85632b4dce76d16bf6d78266c35173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 4 Mar 2011 12:49:55 +0000 Subject: [PATCH 48/53] glsl: Define YY_NO_UNISTD_H on MSVC. --- src/glsl/glcpp/glcpp-lex.l | 4 ++++ src/glsl/glsl_lexer.ll | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l index 68e44eb7902..86618870885 100644 --- a/src/glsl/glcpp/glcpp-lex.l +++ b/src/glsl/glcpp/glcpp-lex.l @@ -34,6 +34,10 @@ int glcpp_get_column (yyscan_t yyscanner); void glcpp_set_column (int column_no , yyscan_t yyscanner); +#ifdef _MSC_VER +#define YY_NO_UNISTD_H +#endif + #define YY_NO_INPUT #define YY_USER_ACTION \ diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll index e4c469f9e0a..cfd89261757 100644 --- a/src/glsl/glsl_lexer.ll +++ b/src/glsl/glsl_lexer.ll @@ -29,6 +29,10 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *); +#ifdef _MSC_VER +#define YY_NO_UNISTD_H +#endif + #define YY_USER_ACTION \ do { \ yylloc->source = 0; \ From 12d17bcadf79d473b29c902c1ac949dcc65ff354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 4 Mar 2011 12:53:14 +0000 Subject: [PATCH 49/53] glsl/glcpp: Use stdio.h instead of unistd.h. --- src/glsl/glcpp/glcpp.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/src/glsl/glcpp/glcpp.c b/src/glsl/glcpp/glcpp.c index 564194caac2..325289129d5 100644 --- a/src/glsl/glcpp/glcpp.c +++ b/src/glsl/glcpp/glcpp.c @@ -21,10 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include -#include -#include -#include +#include #include #include #include "glcpp.h" @@ -40,16 +37,16 @@ _mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, *ptr = sh; } -/* Read from fd until EOF and return a string of everything read. +/* Read from fp until EOF and return a string of everything read. */ static char * -load_text_fd (void *ctx, int fd) +load_text_fp (void *ctx, FILE *fp) { #define CHUNK 4096 char *text = NULL; - ssize_t text_size = 0; - ssize_t total_read = 0; - ssize_t bytes; + size_t text_size = 0; + size_t total_read = 0; + size_t bytes; while (1) { if (total_read + CHUNK + 1 > text_size) { @@ -60,19 +57,12 @@ load_text_fd (void *ctx, int fd) return NULL; } } - bytes = read (fd, text + total_read, CHUNK); - if (bytes < 0) { - fprintf (stderr, "Error while reading: %s\n", - strerror (errno)); - ralloc_free (text); - return NULL; - } + bytes = fread (text + total_read, 1, CHUNK, fp); + total_read += bytes; - if (bytes == 0) { + if (bytes < CHUNK) { break; } - - total_read += bytes; } text[total_read] = '\0'; @@ -84,21 +74,21 @@ static char * load_text_file(void *ctx, const char *filename) { char *text; - int fd; + FILE *fp; if (filename == NULL || strcmp (filename, "-") == 0) - return load_text_fd (ctx, STDIN_FILENO); + return load_text_fp (ctx, stdin); - fd = open (filename, O_RDONLY); - if (fd < 0) { + fp = fopen (filename, "r"); + if (fp == NULL) { fprintf (stderr, "Failed to open file %s: %s\n", filename, strerror (errno)); return NULL; } - text = load_text_fd (ctx, fd); + text = load_text_fp (ctx, fp); - close(fd); + fclose(fp); return text; } From 53789834176396ae69e21e460881600f36124fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 4 Mar 2011 13:11:49 +0000 Subject: [PATCH 50/53] scons: Get glsl2 and glcpp programs building correctly. --- src/glsl/SConscript | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/glsl/SConscript b/src/glsl/SConscript index bb02a87c790..ef10ca9751e 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -30,7 +30,7 @@ glcpp_parser = env.CFile('glcpp/glcpp-parse.c', 'glcpp/glcpp-parse.y') glsl_lexer = parser_env.CXXFile('glsl_lexer.cpp', 'glsl_lexer.ll') glsl_parser = parser_env.CXXFile('glsl_parser.cpp', 'glsl_parser.yy') -sources = [ +glsl_sources = [ glcpp_lexer, glcpp_parser[0], 'glcpp/pp.c', @@ -98,19 +98,23 @@ sources = [ 'strtod.c', ] +if env['msvc']: + env.Prepend(CPPPATH = ['#/src/getopt']) + env.PrependUnique(LIBS = [getopt]) + +main_obj = env.StaticObject('main.cpp') + +mesa_objs = env.StaticObject([ + '#src/mesa/program/hash_table.c', + '#src/mesa/program/symbol_table.c', +]) if env['crosscompile'] and env['platform'] != 'embedded': Import('builtin_glsl_function') else: - if env['msvc']: - env.Prepend(CPPPATH = ['#/src/getopt']) - env.PrependUnique(LIBS = [getopt]) - builtin_compiler = env.Program( target = 'builtin_compiler', - source = sources + ['main.cpp', 'builtin_stubs.cpp', - '#src/mesa/program/hash_table.c', - '#src/mesa/program/symbol_table.c'], + source = main_obj + glsl_sources + ['builtin_stubs.cpp'] + mesa_objs, ) # SCons builtin dependency scanner doesn't detect that glsl_lexer.ll @@ -132,11 +136,11 @@ else: Return() -sources += builtin_glsl_function +glsl_sources += builtin_glsl_function glsl = env.ConvenienceLibrary( target = 'glsl', - source = sources, + source = glsl_sources, ) # SCons builtin dependency scanner doesn't detect that glsl_lexer.ll depends on @@ -145,9 +149,6 @@ env.Depends(glsl, glsl_parser) Export('glsl') -# FIXME: We can't build the programs because there's a cyclic dependency between tis directory and src/mesa -Return() - env = env.Clone() if env['platform'] == 'windows': @@ -157,14 +158,14 @@ if env['platform'] == 'windows': env.Prepend(LIBS = [glsl]) -env.Program( +glsl2 = env.Program( target = 'glsl2', - source = [ - 'main.cpp', - ] + source = main_obj + mesa_objs, ) +env.Alias('glsl2', glsl2) -env.Program( - target = 'glcpp', - source = ['glcpp/glcpp.c'], +glcpp = env.Program( + target = 'glcpp/glcpp', + source = ['glcpp/glcpp.c'] + mesa_objs, ) +env.Alias('glcpp', glcpp) From ba48811fa8cbe80c67cdbbb9b8180aaf64433c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 4 Mar 2011 06:38:13 +0100 Subject: [PATCH 51/53] st/mesa: set PIPE_BIND_RENDER_TARGET for sRGB formats if UNORM is supported Because the format can be changed to UNORM in a surface. This fixes: state_tracker/st_atom_framebuffer.c:163:update_framebuffer_state: Assertion `framebuffer->cbufs[i]->texture->bind & (1 << 1)' failed. --- src/mesa/state_tracker/st_cb_texture.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index c3c4246d139..3f98ffd3d6f 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -227,8 +227,15 @@ default_bindings(struct st_context *st, enum pipe_format format) if (screen->is_format_supported(screen, format, target, 0, bindings, geom)) return bindings; - else - return PIPE_BIND_SAMPLER_VIEW; + else { + /* Try non-sRGB. */ + format = util_format_linear(format); + + if (screen->is_format_supported(screen, format, target, 0, bindings, geom)) + return bindings; + else + return PIPE_BIND_SAMPLER_VIEW; + } } From c8e904e159e6ddfe68fa5dc4de72b12eb7b7747d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 4 Mar 2011 14:29:06 +0000 Subject: [PATCH 52/53] scons: Unbreak mingw cross compilation. --- src/glsl/SConscript | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/glsl/SConscript b/src/glsl/SConscript index ef10ca9751e..9ecc155c9c9 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -102,16 +102,16 @@ if env['msvc']: env.Prepend(CPPPATH = ['#/src/getopt']) env.PrependUnique(LIBS = [getopt]) -main_obj = env.StaticObject('main.cpp') - -mesa_objs = env.StaticObject([ - '#src/mesa/program/hash_table.c', - '#src/mesa/program/symbol_table.c', -]) - if env['crosscompile'] and env['platform'] != 'embedded': Import('builtin_glsl_function') else: + main_obj = env.StaticObject('main.cpp') + + mesa_objs = env.StaticObject([ + '#src/mesa/program/hash_table.c', + '#src/mesa/program/symbol_table.c', + ]) + builtin_compiler = env.Program( target = 'builtin_compiler', source = main_obj + glsl_sources + ['builtin_stubs.cpp'] + mesa_objs, @@ -149,6 +149,11 @@ env.Depends(glsl, glsl_parser) Export('glsl') +# Skip building these programs as they will cause SCons error "Two environments +# with different actions were specified for the same target" +if env['crosscompile'] or env['platform'] == 'embedded': + Return() + env = env.Clone() if env['platform'] == 'windows': From 6838c9ce74f16c765474c0d2b4ae1469dd4a64d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 4 Mar 2011 14:54:24 +0000 Subject: [PATCH 53/53] tgsi: Disable SSE2 code generation. It's broken now that tgsi_exec_machine::Inputs/Ouputs are pointers. Temporary if anybody still cares about tgsi_sse2.c. Permanent otherwise. --- src/gallium/auxiliary/tgsi/tgsi_sse2.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 92ba8b8f033..664946b00f6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -28,7 +28,9 @@ #include "pipe/p_config.h" -#if defined(PIPE_ARCH_X86) +#include "tgsi/tgsi_sse2.h" + +#if defined(PIPE_ARCH_X86) && 0 /* See FIXME notes below */ #include "util/u_debug.h" #include "pipe/p_shader_tokens.h" @@ -42,7 +44,6 @@ #include "tgsi/tgsi_util.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_exec.h" -#include "tgsi/tgsi_sse2.h" #include "rtasm/rtasm_x86sse.h" @@ -118,6 +119,7 @@ get_machine_base( void ) static struct x86_reg get_input_base( void ) { + /* FIXME: tgsi_exec_machine::Inputs is a pointer now! */ return x86_make_disp( get_machine_base(), Offset(struct tgsi_exec_machine, Inputs) ); @@ -126,6 +128,7 @@ get_input_base( void ) static struct x86_reg get_output_base( void ) { + /* FIXME: tgsi_exec_machine::Ouputs is a pointer now! */ return x86_make_disp( get_machine_base(), Offset(struct tgsi_exec_machine, Outputs) ); @@ -2760,6 +2763,7 @@ static void aos_to_soa( struct x86_function *func, x86_mov( func, aos_input, x86_fn_arg( func, arg_aos ) ); x86_mov( func, soa_input, x86_fn_arg( func, arg_machine ) ); + /* FIXME: tgsi_exec_machine::Inputs is a pointer now! */ x86_lea( func, soa_input, x86_make_disp( soa_input, Offset(struct tgsi_exec_machine, Inputs) ) ); @@ -2828,6 +2832,7 @@ static void soa_to_aos( struct x86_function *func, x86_mov( func, aos_output, x86_fn_arg( func, arg_aos ) ); x86_mov( func, soa_output, x86_fn_arg( func, arg_machine ) ); + /* FIXME: tgsi_exec_machine::Ouputs is a pointer now! */ x86_lea( func, soa_output, x86_make_disp( soa_output, Offset(struct tgsi_exec_machine, Outputs) ) ); @@ -3082,4 +3087,16 @@ tgsi_emit_sse2( return ok; } -#endif /* PIPE_ARCH_X86 */ +#else /* !PIPE_ARCH_X86 */ + +unsigned +tgsi_emit_sse2( + const struct tgsi_token *tokens, + struct x86_function *func, + float (*immediates)[4], + boolean do_swizzles ) +{ + return 0; +} + +#endif /* !PIPE_ARCH_X86 */