diff options
154 files changed, 32186 insertions, 2 deletions
diff --git a/configs/default b/configs/default index 2776a118057..a8d1fe6bec2 100644 --- a/configs/default +++ b/configs/default @@ -70,7 +70,7 @@ PROGRAM_DIRS = demos redbook samples glsl xdemos # Gallium directories and GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi sct translate rtasm util GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) -GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple failover +GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv10 nv30 nv40 nv50 failover GALLIUM_WINSYS_COMMON_DIRS = GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = xlib egl_xlib diff --git a/configs/linux-dri b/configs/linux-dri index 9fd37212656..74f81bf83b6 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -68,4 +68,4 @@ GALLIUM_WINSYS_COMMON_DIRS = intel_drm # gamma are missing because they have not been converted to use the new # interface. -DRI_DIRS = intel +DRI_DIRS = nouveau diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 2f263cf06a9..678c70e4782 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -63,8 +63,10 @@ struct draw_context *draw_create( void ) if (!draw_pt_init( draw )) goto fail; +#ifdef PIPE_ARCH_X86 if (!draw_vs_init( draw )) goto fail; +#endif return draw; diff --git a/src/gallium/drivers/nouveau/nouveau_bo.h b/src/gallium/drivers/nouveau/nouveau_bo.h new file mode 100644 index 00000000000..18020e9c652 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_bo.h @@ -0,0 +1,51 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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. + */ + +#ifndef __NOUVEAU_BO_H__ +#define __NOUVEAU_BO_H__ + +/* Relocation/Buffer type flags */ +#define NOUVEAU_BO_VRAM (1 << 0) +#define NOUVEAU_BO_GART (1 << 1) +#define NOUVEAU_BO_RD (1 << 2) +#define NOUVEAU_BO_WR (1 << 3) +#define NOUVEAU_BO_RDWR (NOUVEAU_BO_RD | NOUVEAU_BO_WR) +#define NOUVEAU_BO_MAP (1 << 4) +#define NOUVEAU_BO_PIN (1 << 5) +#define NOUVEAU_BO_LOW (1 << 6) +#define NOUVEAU_BO_HIGH (1 << 7) +#define NOUVEAU_BO_OR (1 << 8) +#define NOUVEAU_BO_LOCAL (1 << 9) +#define NOUVEAU_BO_DUMMY (1 << 31) + +struct nouveau_bo { + struct nouveau_device *device; + uint64_t handle; + + uint64_t size; + void *map; + + uint32_t flags; + uint64_t offset; +}; + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_channel.h b/src/gallium/drivers/nouveau/nouveau_channel.h new file mode 100644 index 00000000000..cd99a676bdc --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_channel.h @@ -0,0 +1,40 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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. + */ + +#ifndef __NOUVEAU_CHANNEL_H__ +#define __NOUVEAU_CHANNEL_H__ + +struct nouveau_channel { + struct nouveau_device *device; + int id; + + struct nouveau_pushbuf *pushbuf; + + struct nouveau_grobj *nullobj; + struct nouveau_grobj *vram; + struct nouveau_grobj *gart; + + void *user_private; + void (*hang_notify)(struct nouveau_channel *); +}; + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h new file mode 100644 index 00000000000..3c29fa0d1be --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -0,0 +1,6193 @@ +/************************************************************************* + + Autogenerated file, do not edit ! + +************************************************************************** + + 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 NV01_ROOT 0x00000001 + + + +#define NV01_CONTEXT_DMA 0x00000002 + + + +#define NV01_DEVICE 0x00000003 + + + +#define NV01_TIMER 0x00000004 + +#define NV01_TIMER_SYNCHRONIZE 0x00000100 +#define NV01_TIMER_STOP_ALARM 0x00000104 +#define NV01_TIMER_DMA_NOTIFY 0x00000180 +#define NV01_TIMER_TIME(x) (0x00000300+((x)*4)) +#define NV01_TIMER_TIME__SIZE 0x00000002 +#define NV01_TIMER_ALARM_NOTIFY 0x00000308 + + +#define NV_IMAGE_STENCIL 0x00000010 + +#define NV_IMAGE_STENCIL_NOTIFY 0x00000104 +#define NV_IMAGE_STENCIL_DMA_NOTIFY 0x00000180 +#define NV_IMAGE_STENCIL_IMAGE_OUTPUT 0x00000200 +#define NV_IMAGE_STENCIL_IMAGE_INPUT(x) (0x00000204+((x)*4)) +#define NV_IMAGE_STENCIL_IMAGE_INPUT__SIZE 0x00000002 + + +#define NV_IMAGE_BLEND_AND 0x00000011 + +#define NV_IMAGE_BLEND_AND_NOP 0x00000100 +#define NV_IMAGE_BLEND_AND_NOTIFY 0x00000104 +#define NV_IMAGE_BLEND_AND_DMA_NOTIFY 0x00000180 +#define NV_IMAGE_BLEND_AND_IMAGE_OUTPUT 0x00000200 +#define NV_IMAGE_BLEND_AND_BETA_INPUT 0x00000204 +#define NV_IMAGE_BLEND_AND_IMAGE_INPUT 0x00000208 + + +#define NV01_CONTEXT_BETA1 0x00000012 + +#define NV01_CONTEXT_BETA1_NOP 0x00000100 +#define NV01_CONTEXT_BETA1_NOTIFY 0x00000104 +#define NV01_CONTEXT_BETA1_DMA_NOTIFY 0x00000180 +#define NV01_CONTEXT_BETA1_BETA_1D31 0x00000300 + + +#define NV_IMAGE_ROP_AND 0x00000013 + +#define NV_IMAGE_ROP_AND_NOTIFY 0x00000104 +#define NV_IMAGE_ROP_AND_DMA_NOTIFY 0x00000180 +#define NV_IMAGE_ROP_AND_IMAGE_OUTPUT 0x00000200 +#define NV_IMAGE_ROP_AND_ROP_INPUT 0x00000204 +#define NV_IMAGE_ROP_AND_IMAGE_INPUT(x) (0x00000208+((x)*4)) +#define NV_IMAGE_ROP_AND_IMAGE_INPUT__SIZE 0x00000002 + + +#define NV_IMAGE_COLOR_KEY 0x00000015 + + + +#define NV01_CONTEXT_COLOR_KEY 0x00000017 + +#define NV01_CONTEXT_COLOR_KEY_NOP 0x00000100 +#define NV01_CONTEXT_COLOR_KEY_NOTIFY 0x00000104 +#define NV01_CONTEXT_COLOR_KEY_DMA_NOTIFY 0x00000180 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT 0x00000300 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X16A8Y8 0x00000001 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X24Y8 0x00000002 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X16A1R5G5B5 0x00000003 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X17R5G5B5 0x00000004 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_A8R8G8B8 0x00000005 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X8R8G8B8 0x00000006 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_A16Y16 0x00000007 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X16Y16 0x00000008 +#define NV01_CONTEXT_COLOR_KEY_COLOR 0x00000304 + + +#define NV01_CONTEXT_PATTERN 0x00000018 + +#define NV01_CONTEXT_PATTERN_NOP 0x00000100 +#define NV01_CONTEXT_PATTERN_NOTIFY 0x00000104 +#define NV01_CONTEXT_PATTERN_DMA_NOTIFY 0x00000180 +#define NV01_CONTEXT_PATTERN_COLOR_FORMAT 0x00000300 +#define NV01_CONTEXT_PATTERN_MONOCHROME_FORMAT 0x00000304 +#define NV01_CONTEXT_PATTERN_SHAPE 0x00000308 +#define NV01_CONTEXT_PATTERN_COLOR(x) (0x00000310+((x)*4)) +#define NV01_CONTEXT_PATTERN_COLOR__SIZE 0x00000002 +#define NV01_CONTEXT_PATTERN_PATTERN(x) (0x00000318+((x)*4)) +#define NV01_CONTEXT_PATTERN_PATTERN__SIZE 0x00000002 + + +#define NV01_CONTEXT_CLIP_RECTANGLE 0x00000019 + +#define NV01_CONTEXT_CLIP_RECTANGLE_NOP 0x00000100 +#define NV01_CONTEXT_CLIP_RECTANGLE_NOTIFY 0x00000104 +#define NV01_CONTEXT_CLIP_RECTANGLE_DMA_NOTIFY 0x00000180 +#define NV01_CONTEXT_CLIP_RECTANGLE_POINT 0x00000300 +#define NV01_CONTEXT_CLIP_RECTANGLE_POINT_X_SHIFT 0 +#define NV01_CONTEXT_CLIP_RECTANGLE_POINT_X_MASK 0x0000ffff +#define NV01_CONTEXT_CLIP_RECTANGLE_POINT_Y_SHIFT 16 +#define NV01_CONTEXT_CLIP_RECTANGLE_POINT_Y_MASK 0xffff0000 +#define NV01_CONTEXT_CLIP_RECTANGLE_SIZE 0x00000304 +#define NV01_CONTEXT_CLIP_RECTANGLE_SIZE_W_SHIFT 0 +#define NV01_CONTEXT_CLIP_RECTANGLE_SIZE_W_MASK 0x0000ffff +#define NV01_CONTEXT_CLIP_RECTANGLE_SIZE_H_SHIFT 16 +#define NV01_CONTEXT_CLIP_RECTANGLE_SIZE_H_MASK 0xffff0000 + + +#define NV01_RENDER_SOLID_LINE 0x0000001c + +#define NV01_RENDER_SOLID_LINE_NOP 0x00000100 +#define NV01_RENDER_SOLID_LINE_NOTIFY 0x00000104 +#define NV01_RENDER_SOLID_LINE_PATCH 0x0000010c +#define NV01_RENDER_SOLID_LINE_DMA_NOTIFY 0x00000180 +#define NV01_RENDER_SOLID_LINE_CLIP_RECTANGLE 0x00000184 +#define NV01_RENDER_SOLID_LINE_PATTERN 0x00000188 +#define NV01_RENDER_SOLID_LINE_ROP 0x0000018c +#define NV01_RENDER_SOLID_LINE_BETA1 0x00000190 +#define NV01_RENDER_SOLID_LINE_SURFACE 0x00000194 +#define NV01_RENDER_SOLID_LINE_OPERATION 0x000002fc +#define NV01_RENDER_SOLID_LINE_OPERATION_SRCCOPY_AND 0x00000000 +#define NV01_RENDER_SOLID_LINE_OPERATION_ROP_AND 0x00000001 +#define NV01_RENDER_SOLID_LINE_OPERATION_BLEND_AND 0x00000002 +#define NV01_RENDER_SOLID_LINE_OPERATION_SRCCOPY 0x00000003 +#define NV01_RENDER_SOLID_LINE_OPERATION_SRCCOPY_PREMULT 0x00000004 +#define NV01_RENDER_SOLID_LINE_OPERATION_BLEND_PREMULT 0x00000005 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT 0x00000300 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X16A8Y8 0x00000001 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X24Y8 0x00000002 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X16A1R5G5B5 0x00000003 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X17R5G5B5 0x00000004 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_A8R8G8B8 0x00000005 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X8R8G8B8 0x00000006 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_A16Y16 0x00000007 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X16Y16 0x00000008 +#define NV01_RENDER_SOLID_LINE_COLOR 0x00000304 +#define NV01_RENDER_SOLID_LINE_LINE_POINT0(x) (0x00000400+((x)*8)) +#define NV01_RENDER_SOLID_LINE_LINE_POINT0__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_LINE_POINT0_X_SHIFT 0 +#define NV01_RENDER_SOLID_LINE_LINE_POINT0_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_LINE_LINE_POINT0_Y_SHIFT 16 +#define NV01_RENDER_SOLID_LINE_LINE_POINT0_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_LINE_LINE_POINT1(x) (0x00000404+((x)*8)) +#define NV01_RENDER_SOLID_LINE_LINE_POINT1__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_LINE_POINT1_X_SHIFT 0 +#define NV01_RENDER_SOLID_LINE_LINE_POINT1_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_LINE_LINE_POINT1_Y_SHIFT 16 +#define NV01_RENDER_SOLID_LINE_LINE_POINT1_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_LINE_LINE32_POINT0_X(x) (0x00000480+((x)*16)) +#define NV01_RENDER_SOLID_LINE_LINE32_POINT0_X__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_LINE32_POINT0_Y(x) (0x00000484+((x)*16)) +#define NV01_RENDER_SOLID_LINE_LINE32_POINT0_Y__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_LINE32_POINT1_X(x) (0x00000488+((x)*16)) +#define NV01_RENDER_SOLID_LINE_LINE32_POINT1_X__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_LINE32_POINT1_Y(x) (0x0000048c+((x)*16)) +#define NV01_RENDER_SOLID_LINE_LINE32_POINT1_Y__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_POLYLINE(x) (0x00000500+((x)*4)) +#define NV01_RENDER_SOLID_LINE_POLYLINE__SIZE 0x00000020 +#define NV01_RENDER_SOLID_LINE_POLYLINE_X_SHIFT 0 +#define NV01_RENDER_SOLID_LINE_POLYLINE_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_LINE_POLYLINE_Y_SHIFT 16 +#define NV01_RENDER_SOLID_LINE_POLYLINE_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_LINE_POLYLINE32_POINT_X(x) (0x00000580+((x)*8)) +#define NV01_RENDER_SOLID_LINE_POLYLINE32_POINT_X__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_POLYLINE32_POINT_Y(x) (0x00000584+((x)*8)) +#define NV01_RENDER_SOLID_LINE_POLYLINE32_POINT_Y__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_COLOR(x) (0x00000600+((x)*8)) +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_COLOR__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT(x) (0x00000604+((x)*8)) +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT_X_SHIFT 0 +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT_Y_SHIFT 16 +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT_Y_MASK 0xffff0000 + + +#define NV01_RENDER_SOLID_TRIANGLE 0x0000001d + +#define NV01_RENDER_SOLID_TRIANGLE_NOP 0x00000100 +#define NV01_RENDER_SOLID_TRIANGLE_NOTIFY 0x00000104 +#define NV01_RENDER_SOLID_TRIANGLE_PATCH 0x0000010c +#define NV01_RENDER_SOLID_TRIANGLE_DMA_NOTIFY 0x00000180 +#define NV01_RENDER_SOLID_TRIANGLE_CLIP_RECTANGLE 0x00000184 +#define NV01_RENDER_SOLID_TRIANGLE_PATTERN 0x00000188 +#define NV01_RENDER_SOLID_TRIANGLE_ROP 0x0000018c +#define NV01_RENDER_SOLID_TRIANGLE_BETA1 0x00000190 +#define NV01_RENDER_SOLID_TRIANGLE_SURFACE 0x00000194 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION 0x000002fc +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_SRCCOPY_AND 0x00000000 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_ROP_AND 0x00000001 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_BLEND_AND 0x00000002 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_SRCCOPY 0x00000003 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_SRCCOPY_PREMULT 0x00000004 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_BLEND_PREMULT 0x00000005 +#define NV01_RENDER_SOLID_TRIANGLE_COLOR_FORMAT 0x00000300 +#define NV01_RENDER_SOLID_TRIANGLE_COLOR 0x00000304 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT0 0x00000310 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT0_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT0_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT0_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT0_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT1 0x00000314 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT1_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT1_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT1_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT1_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT2 0x00000318 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT2_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT2_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT2_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT2_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE32_POINT0_X 0x00000320 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE32_POINT0_Y 0x00000324 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE32_POINT1_X 0x00000328 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE32_POINT1_Y 0x0000032c +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE32_POINT2_X 0x00000330 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE32_POINT2_Y 0x00000334 +#define NV01_RENDER_SOLID_TRIANGLE_TRIMESH(x) (0x00000400+((x)*4)) +#define NV01_RENDER_SOLID_TRIANGLE_TRIMESH__SIZE 0x00000020 +#define NV01_RENDER_SOLID_TRIANGLE_TRIMESH_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_TRIMESH_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_TRIMESH_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_TRIMESH_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_TRIANGLE_TRIMESH32_POINT_X(x) (0x00000480+((x)*8)) +#define NV01_RENDER_SOLID_TRIANGLE_TRIMESH32_POINT_X__SIZE 0x00000010 +#define NV01_RENDER_SOLID_TRIANGLE_TRIMESH32_POINT_Y(x) (0x00000484+((x)*8)) +#define NV01_RENDER_SOLID_TRIANGLE_TRIMESH32_POINT_Y__SIZE 0x00000010 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_COLOR(x) (0x00000500+((x)*16)) +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_COLOR__SIZE 0x00000008 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT0(x) (0x00000504+((x)*16)) +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT0__SIZE 0x00000008 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT0_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT0_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT0_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT0_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT1(x) (0x00000508+((x)*16)) +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT1__SIZE 0x00000008 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT1_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT1_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT1_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT1_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT2(x) (0x0000050c+((x)*16)) +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT2__SIZE 0x00000008 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT2_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT2_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT2_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIANGLE_POINT2_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIMESH_COLOR(x) (0x00000580+((x)*8)) +#define NV01_RENDER_SOLID_TRIANGLE_CTRIMESH_COLOR__SIZE 0x00000010 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIMESH_POINT(x) (0x00000584+((x)*8)) +#define NV01_RENDER_SOLID_TRIANGLE_CTRIMESH_POINT__SIZE 0x00000010 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIMESH_POINT_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIMESH_POINT_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_CTRIMESH_POINT_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_CTRIMESH_POINT_Y_MASK 0xffff0000 + + +#define NV01_RENDER_SOLID_RECTANGLE 0x0000001e + +#define NV01_RENDER_SOLID_RECTANGLE_NOP 0x00000100 +#define NV01_RENDER_SOLID_RECTANGLE_NOTIFY 0x00000104 +#define NV01_RENDER_SOLID_RECTANGLE_PATCH 0x0000010c +#define NV01_RENDER_SOLID_RECTANGLE_DMA_NOTIFY 0x00000180 +#define NV01_RENDER_SOLID_RECTANGLE_CLIP_RECTANGLE 0x00000184 +#define NV01_RENDER_SOLID_RECTANGLE_PATTERN 0x00000188 +#define NV01_RENDER_SOLID_RECTANGLE_ROP 0x0000018c +#define NV01_RENDER_SOLID_RECTANGLE_BETA1 0x00000190 +#define NV01_RENDER_SOLID_RECTANGLE_SURFACE 0x00000194 +#define NV01_RENDER_SOLID_RECTANGLE_OPERATION 0x000002fc +#define NV01_RENDER_SOLID_RECTANGLE_OPERATION_SRCCOPY_AND 0x00000000 +#define NV01_RENDER_SOLID_RECTANGLE_OPERATION_ROP_AND 0x00000001 +#define NV01_RENDER_SOLID_RECTANGLE_OPERATION_BLEND_AND 0x00000002 +#define NV01_RENDER_SOLID_RECTANGLE_OPERATION_SRCCOPY 0x00000003 +#define NV01_RENDER_SOLID_RECTANGLE_OPERATION_SRCCOPY_PREMULT 0x00000004 +#define NV01_RENDER_SOLID_RECTANGLE_OPERATION_BLEND_PREMULT 0x00000005 +#define NV01_RENDER_SOLID_RECTANGLE_COLOR_FORMAT 0x00000300 +#define NV01_RENDER_SOLID_RECTANGLE_COLOR 0x00000304 +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_POINT(x) (0x00000400+((x)*8)) +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_POINT__SIZE 0x00000010 +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_POINT_X_SHIFT 0 +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_POINT_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_POINT_Y_SHIFT 16 +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_POINT_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_SIZE(x) (0x00000404+((x)*8)) +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_SIZE__SIZE 0x00000010 +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_SIZE_W_SHIFT 0 +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_SIZE_W_MASK 0x0000ffff +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_SIZE_H_SHIFT 16 +#define NV01_RENDER_SOLID_RECTANGLE_RECTANGLE_SIZE_H_MASK 0xffff0000 + + +#define NV01_IMAGE_BLIT 0x0000001f + +#define NV01_IMAGE_BLIT_NOP 0x00000100 +#define NV01_IMAGE_BLIT_NOTIFY 0x00000104 +#define NV01_IMAGE_BLIT_PATCH 0x0000010c +#define NV01_IMAGE_BLIT_DMA_NOTIFY 0x00000180 +#define NV01_IMAGE_BLIT_COLOR_KEY 0x00000184 +#define NV01_IMAGE_BLIT_CLIP_RECTANGLE 0x00000188 +#define NV01_IMAGE_BLIT_PATTERN 0x0000018c +#define NV01_IMAGE_BLIT_ROP 0x00000190 +#define NV01_IMAGE_BLIT_BETA1 0x00000194 +#define NV01_IMAGE_BLIT_SURFACE 0x0000019c +#define NV01_IMAGE_BLIT_OPERATION 0x000002fc +#define NV01_IMAGE_BLIT_IMAGE_INPUT 0x00000204 +#define NV01_IMAGE_BLIT_POINT_IN 0x00000300 +#define NV01_IMAGE_BLIT_POINT_IN_X_SHIFT 0 +#define NV01_IMAGE_BLIT_POINT_IN_X_MASK 0x0000ffff +#define NV01_IMAGE_BLIT_POINT_IN_Y_SHIFT 16 +#define NV01_IMAGE_BLIT_POINT_IN_Y_MASK 0xffff0000 +#define NV01_IMAGE_BLIT_POINT_OUT 0x00000304 +#define NV01_IMAGE_BLIT_POINT_OUT_X_SHIFT 0 +#define NV01_IMAGE_BLIT_POINT_OUT_X_MASK 0x0000ffff +#define NV01_IMAGE_BLIT_POINT_OUT_Y_SHIFT 16 +#define NV01_IMAGE_BLIT_POINT_OUT_Y_MASK 0xffff0000 +#define NV01_IMAGE_BLIT_SIZE 0x00000308 +#define NV01_IMAGE_BLIT_SIZE_W_SHIFT 0 +#define NV01_IMAGE_BLIT_SIZE_W_MASK 0x0000ffff +#define NV01_IMAGE_BLIT_SIZE_H_SHIFT 16 +#define NV01_IMAGE_BLIT_SIZE_H_MASK 0xffff0000 + + +#define NV01_IMAGE_FROM_CPU 0x00000021 + +#define NV01_IMAGE_FROM_CPU_NOP 0x00000100 +#define NV01_IMAGE_FROM_CPU_NOTIFY 0x00000104 +#define NV01_IMAGE_FROM_CPU_PATCH 0x0000010c +#define NV01_IMAGE_FROM_CPU_DMA_NOTIFY 0x00000180 +#define NV01_IMAGE_FROM_CPU_COLOR_KEY 0x00000184 +#define NV01_IMAGE_FROM_CPU_CLIP_RECTANGLE 0x00000188 +#define NV01_IMAGE_FROM_CPU_PATTERN 0x0000018c +#define NV01_IMAGE_FROM_CPU_ROP 0x00000190 +#define NV01_IMAGE_FROM_CPU_BETA1 0x00000194 +#define NV01_IMAGE_FROM_CPU_SURFACE 0x00000198 +#define NV01_IMAGE_FROM_CPU_OPERATION 0x000002fc +#define NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY_AND 0x00000000 +#define NV01_IMAGE_FROM_CPU_OPERATION_ROP_AND 0x00000001 +#define NV01_IMAGE_FROM_CPU_OPERATION_BLEND_AND 0x00000002 +#define NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY 0x00000003 +#define NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY_PREMULT 0x00000004 +#define NV01_IMAGE_FROM_CPU_OPERATION_BLEND_PREMULT 0x00000005 +#define NV01_IMAGE_FROM_CPU_COLOR_FORMAT 0x00000300 +#define NV01_IMAGE_FROM_CPU_COLOR_FORMAT_Y8 0x00000001 +#define NV01_IMAGE_FROM_CPU_COLOR_FORMAT_A1R5G5B5 0x00000002 +#define NV01_IMAGE_FROM_CPU_COLOR_FORMAT_X1R5G5B5 0x00000003 +#define NV01_IMAGE_FROM_CPU_COLOR_FORMAT_A8R8G8B8 0x00000004 +#define NV01_IMAGE_FROM_CPU_COLOR_FORMAT_X8R8G8B8 0x00000005 +#define NV01_IMAGE_FROM_CPU_POINT 0x00000304 +#define NV01_IMAGE_FROM_CPU_POINT_X_SHIFT 0 +#define NV01_IMAGE_FROM_CPU_POINT_X_MASK 0x0000ffff +#define NV01_IMAGE_FROM_CPU_POINT_Y_SHIFT 16 +#define NV01_IMAGE_FROM_CPU_POINT_Y_MASK 0xffff0000 +#define NV01_IMAGE_FROM_CPU_SIZE_OUT 0x00000308 +#define NV01_IMAGE_FROM_CPU_SIZE_OUT_W_SHIFT 0 +#define NV01_IMAGE_FROM_CPU_SIZE_OUT_W_MASK 0x0000ffff +#define NV01_IMAGE_FROM_CPU_SIZE_OUT_H_SHIFT 16 +#define NV01_IMAGE_FROM_CPU_SIZE_OUT_H_MASK 0xffff0000 +#define NV01_IMAGE_FROM_CPU_SIZE_IN 0x0000030c +#define NV01_IMAGE_FROM_CPU_SIZE_IN_W_SHIFT 0 +#define NV01_IMAGE_FROM_CPU_SIZE_IN_W_MASK 0x0000ffff +#define NV01_IMAGE_FROM_CPU_SIZE_IN_H_SHIFT 16 +#define NV01_IMAGE_FROM_CPU_SIZE_IN_H_MASK 0xffff0000 +#define NV01_IMAGE_FROM_CPU_COLOR(x) (0x00000400+((x)*4)) +#define NV01_IMAGE_FROM_CPU_COLOR__SIZE 0x00000020 + + +#define NV01_NULL 0x00000030 + + + +#define NV03_STRETCHED_IMAGE_FROM_CPU 0x00000036 + +#define NV03_STRETCHED_IMAGE_FROM_CPU_NOP 0x00000100 +#define NV03_STRETCHED_IMAGE_FROM_CPU_NOTIFY 0x00000104 +#define NV03_STRETCHED_IMAGE_FROM_CPU_PATCH 0x0000010c +#define NV03_STRETCHED_IMAGE_FROM_CPU_DMA_NOTIFY 0x00000180 +#define NV03_STRETCHED_IMAGE_FROM_CPU_COLOR_KEY 0x00000184 +#define NV03_STRETCHED_IMAGE_FROM_CPU_PATTERN 0x00000188 +#define NV03_STRETCHED_IMAGE_FROM_CPU_ROP 0x0000018c +#define NV03_STRETCHED_IMAGE_FROM_CPU_BETA1 0x00000190 +#define NV03_STRETCHED_IMAGE_FROM_CPU_SURFACE 0x00000194 +#define NV03_STRETCHED_IMAGE_FROM_CPU_OPERATION 0x000002fc +#define NV03_STRETCHED_IMAGE_FROM_CPU_COLOR_FORMAT 0x00000300 +#define NV03_STRETCHED_IMAGE_FROM_CPU_SIZE_IN 0x00000304 +#define NV03_STRETCHED_IMAGE_FROM_CPU_SIZE_IN_W_SHIFT 0 +#define NV03_STRETCHED_IMAGE_FROM_CPU_SIZE_IN_W_MASK 0x0000ffff +#define NV03_STRETCHED_IMAGE_FROM_CPU_SIZE_IN_H_SHIFT 16 +#define NV03_STRETCHED_IMAGE_FROM_CPU_SIZE_IN_H_MASK 0xffff0000 +#define NV03_STRETCHED_IMAGE_FROM_CPU_DX_DU 0x00000308 +#define NV03_STRETCHED_IMAGE_FROM_CPU_DY_DV 0x0000030c +#define NV03_STRETCHED_IMAGE_FROM_CPU_CLIP_POINT 0x00000310 +#define NV03_STRETCHED_IMAGE_FROM_CPU_CLIP_POINT_X_SHIFT 0 +#define NV03_STRETCHED_IMAGE_FROM_CPU_CLIP_POINT_X_MASK 0x0000ffff +#define NV03_STRETCHED_IMAGE_FROM_CPU_CLIP_POINT_Y_SHIFT 16 +#define NV03_STRETCHED_IMAGE_FROM_CPU_CLIP_POINT_Y_MASK 0xffff0000 +#define NV03_STRETCHED_IMAGE_FROM_CPU_CLIP_SIZE 0x00000314 +#define NV03_STRETCHED_IMAGE_FROM_CPU_CLIP_SIZE_W_SHIFT 0 +#define NV03_STRETCHED_IMAGE_FROM_CPU_CLIP_SIZE_W_MASK 0x0000ffff +#define NV03_STRETCHED_IMAGE_FROM_CPU_CLIP_SIZE_H_SHIFT 16 +#define NV03_STRETCHED_IMAGE_FROM_CPU_CLIP_SIZE_H_MASK 0xffff0000 +#define NV03_STRETCHED_IMAGE_FROM_CPU_POINT12D4 0x00000318 +#define NV03_STRETCHED_IMAGE_FROM_CPU_POINT12D4_X_SHIFT 0 +#define NV03_STRETCHED_IMAGE_FROM_CPU_POINT12D4_X_MASK 0x0000ffff +#define NV03_STRETCHED_IMAGE_FROM_CPU_POINT12D4_Y_SHIFT 16 +#define NV03_STRETCHED_IMAGE_FROM_CPU_POINT12D4_Y_MASK 0xffff0000 +#define NV03_STRETCHED_IMAGE_FROM_CPU_COLOR(x) (0x00000400+((x)*4)) +#define NV03_STRETCHED_IMAGE_FROM_CPU_COLOR__SIZE 0x00000020 + + +#define NV03_SCALED_IMAGE_FROM_MEMORY 0x00000037 + +#define NV03_SCALED_IMAGE_FROM_MEMORY_NOP 0x00000100 +#define NV03_SCALED_IMAGE_FROM_MEMORY_NOTIFY 0x00000104 +#define NV03_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY 0x00000180 +#define NV03_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE 0x00000184 +#define NV03_SCALED_IMAGE_FROM_MEMORY_PATTERN 0x00000188 +#define NV03_SCALED_IMAGE_FROM_MEMORY_ROP 0x0000018c +#define NV03_SCALED_IMAGE_FROM_MEMORY_BETA1 0x00000190 +#define NV03_SCALED_IMAGE_FROM_MEMORY_SURFACE 0x00000194 +#define NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT 0x00000300 +#define NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5 0x00000001 +#define NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X1R5G5B5 0x00000002 +#define NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8 0x00000003 +#define NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8 0x00000004 +#define NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_V8YB8U8YA8 0x00000005 +#define NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_YB8V8YA8U8 0x00000006 +#define NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5 0x00000007 +#define NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_Y8 0x00000008 +#define NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_AY8 0x00000009 +#define NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304 +#define NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY_AND 0x00000000 +#define NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_ROP_AND 0x00000001 +#define NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_BLEND_AND 0x00000002 +#define NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY 0x00000003 +#define NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY_PREMULT 0x00000004 +#define NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_BLEND_PREMULT 0x00000005 +#define NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT 0x00000308 +#define NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_X_SHIFT 0 +#define NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_X_MASK 0x0000ffff +#define NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_Y_SHIFT 16 +#define NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_Y_MASK 0xffff0000 +#define NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE 0x0000030c +#define NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_W_SHIFT 0 +#define NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_W_MASK 0x0000ffff +#define NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_H_SHIFT 16 +#define NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_H_MASK 0xffff0000 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_OUT_POINT 0x00000310 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_OUT_POINT_X_SHIFT 0 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_OUT_POINT_X_MASK 0x0000ffff +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_OUT_POINT_Y_SHIFT 16 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_OUT_POINT_Y_MASK 0xffff0000 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_OUT_SIZE 0x00000314 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_OUT_SIZE_W_SHIFT 0 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_OUT_SIZE_W_MASK 0x0000ffff +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_OUT_SIZE_H_SHIFT 16 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_OUT_SIZE_H_MASK 0xffff0000 +#define NV03_SCALED_IMAGE_FROM_MEMORY_DELTA_DU_DX 0x00000318 +#define NV03_SCALED_IMAGE_FROM_MEMORY_DELTA_DV_DY 0x0000031c +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_SIZE 0x00000400 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_SIZE_W_SHIFT 0 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_SIZE_W_MASK 0x0000ffff +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_SIZE_H_SHIFT 16 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_SIZE_H_MASK 0xffff0000 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_FORMAT 0x00000404 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_FORMAT_PITCH_SHIFT 0 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_FORMAT_PITCH_MASK 0x0000ffff +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_FORMAT_ORIGIN_SHIFT 16 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_FORMAT_ORIGIN_MASK 0x00ff0000 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_FORMAT_ORIGIN_CENTER 0x00010000 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_FORMAT_ORIGIN_CORNER 0x00020000 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_FORMAT_INTERPOLATOR_SHIFT 24 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_FORMAT_INTERPOLATOR_MASK 0xff000000 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_OFFSET 0x00000408 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_POINT 0x0000040c +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_POINT_U_SHIFT 0 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_POINT_U_MASK 0x0000ffff +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_POINT_V_SHIFT 16 +#define NV03_SCALED_IMAGE_FROM_MEMORY_IMAGE_IN_POINT_V_MASK 0xffff0000 + + +#define NV04_DVD_SUBPICTURE 0x00000038 + +#define NV04_DVD_SUBPICTURE_NOP 0x00000100 +#define NV04_DVD_SUBPICTURE_NOTIFY 0x00000104 +#define NV04_DVD_SUBPICTURE_WAIT_FOR_IDLE 0x00000108 +#define NV04_DVD_SUBPICTURE_DMA_NOTIFY 0x00000180 +#define NV04_DVD_SUBPICTURE_DMA_OVERLAY 0x00000184 +#define NV04_DVD_SUBPICTURE_DMA_IMAGEIN 0x00000188 +#define NV04_DVD_SUBPICTURE_DMA_IMAGEOUT 0x0000018c +#define NV04_DVD_SUBPICTURE_IMAGEOUT_POINT 0x00000300 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_POINT_X_SHIFT 0 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_POINT_X_MASK 0x0000ffff +#define NV04_DVD_SUBPICTURE_IMAGEOUT_POINT_Y_SHIFT 16 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_POINT_Y_MASK 0xffff0000 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_SIZE 0x00000304 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_SIZE_W_SHIFT 0 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_SIZE_W_MASK 0x0000ffff +#define NV04_DVD_SUBPICTURE_IMAGEOUT_SIZE_H_SHIFT 16 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_SIZE_H_MASK 0xffff0000 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_FORMAT 0x00000308 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_FORMAT_PITCH_SHIFT 0 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_FORMAT_PITCH_MASK 0x0000ffff +#define NV04_DVD_SUBPICTURE_IMAGEOUT_FORMAT_COLOR_SHIFT 16 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_FORMAT_COLOR_MASK 0xffff0000 +#define NV04_DVD_SUBPICTURE_IMAGEOUT_OFFSET 0x0000030c +#define NV04_DVD_SUBPICTURE_IMAGEIN_DELTA_DU_DX 0x00000310 +#define NV04_DVD_SUBPICTURE_IMAGEIN_DELTA_DV_DY 0x00000314 +#define NV04_DVD_SUBPICTURE_IMAGEIN_SIZE 0x00000318 +#define NV04_DVD_SUBPICTURE_IMAGEIN_SIZE_W_SHIFT 0 +#define NV04_DVD_SUBPICTURE_IMAGEIN_SIZE_W_MASK 0x0000ffff +#define NV04_DVD_SUBPICTURE_IMAGEIN_SIZE_H_SHIFT 16 +#define NV04_DVD_SUBPICTURE_IMAGEIN_SIZE_H_MASK 0xffff0000 +#define NV04_DVD_SUBPICTURE_IMAGEIN_FORMAT 0x0000031c +#define NV04_DVD_SUBPICTURE_IMAGEIN_FORMAT_PITCH_SHIFT 0 +#define NV04_DVD_SUBPICTURE_IMAGEIN_FORMAT_PITCH_MASK 0x0000ffff +#define NV04_DVD_SUBPICTURE_IMAGEIN_FORMAT_COLOR_SHIFT 16 +#define NV04_DVD_SUBPICTURE_IMAGEIN_FORMAT_COLOR_MASK 0xffff0000 +#define NV04_DVD_SUBPICTURE_IMAGEIN_OFFSET 0x00000320 +#define NV04_DVD_SUBPICTURE_IMAGEIN_POINT 0x00000324 +#define NV04_DVD_SUBPICTURE_IMAGEIN_POINT_U_SHIFT 0 +#define NV04_DVD_SUBPICTURE_IMAGEIN_POINT_U_MASK 0x0000ffff +#define NV04_DVD_SUBPICTURE_IMAGEIN_POINT_V_SHIFT 16 +#define NV04_DVD_SUBPICTURE_IMAGEIN_POINT_V_MASK 0xffff0000 +#define NV04_DVD_SUBPICTURE_OVERLAY_DELTA_DU_DX 0x00000328 +#define NV04_DVD_SUBPICTURE_OVERLAY_DELTA_DV_DY 0x0000032c +#define NV04_DVD_SUBPICTURE_OVERLAY_SIZE 0x00000330 +#define NV04_DVD_SUBPICTURE_OVERLAY_SIZE_W_SHIFT 0 +#define NV04_DVD_SUBPICTURE_OVERLAY_SIZE_W_MASK 0x0000ffff +#define NV04_DVD_SUBPICTURE_OVERLAY_SIZE_H_SHIFT 16 +#define NV04_DVD_SUBPICTURE_OVERLAY_SIZE_H_MASK 0xffff0000 +#define NV04_DVD_SUBPICTURE_OVERLAY_FORMAT 0x00000334 +#define NV04_DVD_SUBPICTURE_OVERLAY_FORMAT_PITCH_SHIFT 0 +#define NV04_DVD_SUBPICTURE_OVERLAY_FORMAT_PITCH_MASK 0x0000ffff +#define NV04_DVD_SUBPICTURE_OVERLAY_FORMAT_COLOR_SHIFT 16 +#define NV04_DVD_SUBPICTURE_OVERLAY_FORMAT_COLOR_MASK 0xffff0000 +#define NV04_DVD_SUBPICTURE_OVERLAY_OFFSET 0x00000338 +#define NV04_DVD_SUBPICTURE_OVERLAY_POINT 0x0000033c +#define NV04_DVD_SUBPICTURE_OVERLAY_POINT_U_SHIFT 0 +#define NV04_DVD_SUBPICTURE_OVERLAY_POINT_U_MASK 0x0000ffff +#define NV04_DVD_SUBPICTURE_OVERLAY_POINT_V_SHIFT 16 +#define NV04_DVD_SUBPICTURE_OVERLAY_POINT_V_MASK 0xffff0000 + + +#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 0x0000000f +#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_OUTPUT_INC_SHIFT 8 +#define NV04_MEMORY_TO_MEMORY_FORMAT_FORMAT_OUTPUT_INC_MASK 0x00000f00 +#define NV04_MEMORY_TO_MEMORY_FORMAT_BUF_NOTIFY 0x00000328 + + +#define NV01_MEMORY_LOCAL_BANKED 0x0000003d + + + +#define NV01_MAPPING_SYSTEM 0x0000003e + + + +#define NV03_MEMORY_LOCAL_CURSOR 0x0000003f + + + +#define NV01_MEMORY_LOCAL_LINEAR 0x00000040 + + + +#define NV01_MAPPING_LOCAL 0x00000041 + + + +#define NV04_CONTEXT_SURFACES_2D 0x00000042 + +#define NV04_CONTEXT_SURFACES_2D_NOP 0x00000100 +#define NV04_CONTEXT_SURFACES_2D_NOTIFY 0x00000104 +#define NV04_CONTEXT_SURFACES_2D_PM_TRIGGER 0x00000140 +#define NV04_CONTEXT_SURFACES_2D_DMA_NOTIFY 0x00000180 +#define NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE 0x00000184 +#define NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_DESTIN 0x00000188 +#define NV04_CONTEXT_SURFACES_2D_FORMAT 0x00000300 +#define NV04_CONTEXT_SURFACES_2D_FORMAT_Y8 0x00000001 +#define NV04_CONTEXT_SURFACES_2D_FORMAT_X1R5G5B5_Z1R5G5B5 0x00000002 +#define NV04_CONTEXT_SURFACES_2D_FORMAT_X1R5G5B5_X1R5G5B5 0x00000003 +#define NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5 0x00000004 +#define NV04_CONTEXT_SURFACES_2D_FORMAT_Y16 0x00000005 +#define NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8 0x00000006 +#define NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_X8R8G8B8 0x00000007 +#define NV04_CONTEXT_SURFACES_2D_FORMAT_X1A7R8G8B8_Z1A7R8G8B8 0x00000008 +#define NV04_CONTEXT_SURFACES_2D_FORMAT_X1A7R8G8B8_X1A7R8G8B8 0x00000009 +#define NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8 0x0000000a +#define NV04_CONTEXT_SURFACES_2D_FORMAT_Y32 0x0000000b +#define NV04_CONTEXT_SURFACES_2D_PITCH 0x00000304 +#define NV04_CONTEXT_SURFACES_2D_PITCH_SOURCE_SHIFT 0 +#define NV04_CONTEXT_SURFACES_2D_PITCH_SOURCE_MASK 0x0000ffff +#define NV04_CONTEXT_SURFACES_2D_PITCH_DESTIN_SHIFT 16 +#define NV04_CONTEXT_SURFACES_2D_PITCH_DESTIN_MASK 0xffff0000 +#define NV04_CONTEXT_SURFACES_2D_OFFSET_SOURCE 0x00000308 +#define NV04_CONTEXT_SURFACES_2D_OFFSET_DESTIN 0x0000030c + + +#define NV03_CONTEXT_ROP 0x00000043 + +#define NV03_CONTEXT_ROP_NOP 0x00000100 +#define NV03_CONTEXT_ROP_NOTIFY 0x00000104 +#define NV03_CONTEXT_ROP_DMA_NOTIFY 0x00000180 +#define NV03_CONTEXT_ROP_ROP 0x00000300 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_SHIFT 0 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_MASK 0x0000000f +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_CLEAR 0x00000000 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_NOR 0x00000001 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_AND_INVERTED 0x00000002 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_COPY_INVERTED 0x00000003 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_AND_REVERSE 0x00000004 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_INVERT 0x00000005 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_XOR 0x00000006 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_NAND 0x00000007 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_AND 0x00000008 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_EQUI 0x00000009 +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_NOOP 0x0000000a +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_OR_INVERTED 0x0000000b +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_COPY 0x0000000c +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_OR_REVERSE 0x0000000d +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_OR 0x0000000e +#define NV03_CONTEXT_ROP_ROP_DST_LOGIC_OP_SET 0x0000000f +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_SHIFT 4 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_MASK 0x000000f0 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_CLEAR 0x00000000 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_NOR 0x00000010 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_AND_INVERTED 0x00000020 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_COPY_INVERTED 0x00000030 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_AND_REVERSE 0x00000040 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_INVERT 0x00000050 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_XOR 0x00000060 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_NAND 0x00000070 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_AND 0x00000080 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_EQUI 0x00000090 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_NOOP 0x000000a0 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_OR_INVERTED 0x000000b0 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_COPY 0x000000c0 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_OR_REVERSE 0x000000d0 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_OR 0x000000e0 +#define NV03_CONTEXT_ROP_ROP_SRC_LOGIC_OP_SET 0x000000f0 + + +#define NV04_IMAGE_PATTERN 0x00000044 + +#define NV04_IMAGE_PATTERN_NOP 0x00000100 +#define NV04_IMAGE_PATTERN_NOTIFY 0x00000104 +#define NV04_IMAGE_PATTERN_DMA_NOTIFY 0x00000180 +#define NV04_IMAGE_PATTERN_COLOR_FORMAT 0x00000300 +#define NV04_IMAGE_PATTERN_COLOR_FORMAT_A16R5G6B5 0x00000001 +#define NV04_IMAGE_PATTERN_COLOR_FORMAT_X16A1R5G5B5 0x00000002 +#define NV04_IMAGE_PATTERN_COLOR_FORMAT_A8R8G8B8 0x00000003 +#define NV04_IMAGE_PATTERN_MONOCHROME_FORMAT 0x00000304 +#define NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_CGA6 0x00000001 +#define NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE 0x00000002 +#define NV04_IMAGE_PATTERN_MONOCHROME_SHAPE 0x00000308 +#define NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8 0x00000000 +#define NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_64X1 0x00000001 +#define NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_1X64 0x00000002 +#define NV04_IMAGE_PATTERN_PATTERN_SELECT 0x0000030c +#define NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO 0x00000001 +#define NV04_IMAGE_PATTERN_PATTERN_SELECT_COLOR 0x00000002 +#define NV04_IMAGE_PATTERN_MONOCHROME_COLOR0 0x00000310 +#define NV04_IMAGE_PATTERN_MONOCHROME_COLOR1 0x00000314 +#define NV04_IMAGE_PATTERN_MONOCHROME_PATTERN0 0x00000318 +#define NV04_IMAGE_PATTERN_MONOCHROME_PATTERN1 0x0000031c +#define NV04_IMAGE_PATTERN_PATTERN_Y8(x) (0x00000400+((x)*4)) +#define NV04_IMAGE_PATTERN_PATTERN_Y8__SIZE 0x00000010 +#define NV04_IMAGE_PATTERN_PATTERN_Y8_Y0_SHIFT 0 +#define NV04_IMAGE_PATTERN_PATTERN_Y8_Y0_MASK 0x000000ff +#define NV04_IMAGE_PATTERN_PATTERN_Y8_Y1_SHIFT 8 +#define NV04_IMAGE_PATTERN_PATTERN_Y8_Y1_MASK 0x0000ff00 +#define NV04_IMAGE_PATTERN_PATTERN_Y8_Y2_SHIFT 16 +#define NV04_IMAGE_PATTERN_PATTERN_Y8_Y2_MASK 0x00ff0000 +#define NV04_IMAGE_PATTERN_PATTERN_Y8_Y3_SHIFT 24 +#define NV04_IMAGE_PATTERN_PATTERN_Y8_Y3_MASK 0xff000000 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5(x) (0x00000500+((x)*4)) +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5__SIZE 0x00000020 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_B0_SHIFT 0 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_B0_MASK 0x0000001f +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_G0_SHIFT 5 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_G0_MASK 0x000007e0 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_R0_SHIFT 11 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_R0_MASK 0x0000f800 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_B1_SHIFT 16 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_B1_MASK 0x001f0000 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_G1_SHIFT 21 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_G1_MASK 0x07e00000 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_R1_SHIFT 27 +#define NV04_IMAGE_PATTERN_PATTERN_R5G6B5_R1_MASK 0xf8000000 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5(x) (0x00000600+((x)*4)) +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5__SIZE 0x00000020 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_B0_SHIFT 0 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_B0_MASK 0x0000001f +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_G0_SHIFT 5 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_G0_MASK 0x000003e0 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_R0_SHIFT 10 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_R0_MASK 0x00007c00 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_B1_SHIFT 16 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_B1_MASK 0x001f0000 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_G1_SHIFT 21 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_G1_MASK 0x03e00000 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_R1_SHIFT 26 +#define NV04_IMAGE_PATTERN_PATTERN_X1R5G5B5_R1_MASK 0x7c000000 +#define NV04_IMAGE_PATTERN_PATTERN_X8R8G8B8(x) (0x00000700+((x)*4)) +#define NV04_IMAGE_PATTERN_PATTERN_X8R8G8B8__SIZE 0x00000040 +#define NV04_IMAGE_PATTERN_PATTERN_X8R8G8B8_B_SHIFT 0 +#define NV04_IMAGE_PATTERN_PATTERN_X8R8G8B8_B_MASK 0x000000ff +#define NV04_IMAGE_PATTERN_PATTERN_X8R8G8B8_G_SHIFT 8 +#define NV04_IMAGE_PATTERN_PATTERN_X8R8G8B8_G_MASK 0x0000ff00 +#define NV04_IMAGE_PATTERN_PATTERN_X8R8G8B8_R_SHIFT 16 +#define NV04_IMAGE_PATTERN_PATTERN_X8R8G8B8_R_MASK 0x00ff0000 + + +#define NV03_VIDEO_LUT_CURSOR_DAC 0x00000046 + +#define NV03_VIDEO_LUT_CURSOR_DAC_SYNCHRONIZE 0x00000100 +#define NV03_VIDEO_LUT_CURSOR_DAC_STOP_IMAGE 0x00000104 +#define NV03_VIDEO_LUT_CURSOR_DAC_STOP_CURSOR 0x00000108 +#define NV03_VIDEO_LUT_CURSOR_DAC_STOP_DAC 0x0000010c +#define NV03_VIDEO_LUT_CURSOR_DAC_DMA_NOTIFY 0x00000180 +#define NV03_VIDEO_LUT_CURSOR_DAC_DMA_IMAGE(x) (0x00000184+((x)*4)) +#define NV03_VIDEO_LUT_CURSOR_DAC_DMA_IMAGE__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_DMA_LUT(x) (0x0000018c+((x)*4)) +#define NV03_VIDEO_LUT_CURSOR_DAC_DMA_LUT__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_DMA_CURSOR(x) (0x00000194+((x)*4)) +#define NV03_VIDEO_LUT_CURSOR_DAC_DMA_CURSOR__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_GET 0x000002fc +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_IMAGE_OFFSET(x) (0x00000300+((x)*8)) +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_IMAGE_OFFSET__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_IMAGE_FORMAT(x) (0x00000304+((x)*8)) +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_IMAGE_FORMAT__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_IMAGE_FORMAT_PITCH_SHIFT 0 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_IMAGE_FORMAT_PITCH_MASK 0x0000ffff +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_IMAGE_FORMAT_COLOR_SHIFT 16 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_IMAGE_FORMAT_COLOR_MASK 0x0fff0000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_IMAGE_FORMAT_NOTIFY_SHIFT 28 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_IMAGE_FORMAT_NOTIFY_MASK 0xf0000000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_OFFSET(x) (0x00000340+((x)*12)) +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_OFFSET__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT(x) (0x00000344+((x)*12)) +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT_X_SHIFT 0 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT_X_MASK 0x0000ffff +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT_Y_SHIFT 16 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT_Y_MASK 0xffff0000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_FORMAT(x) (0x00000348+((x)*12)) +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_FORMAT__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT_A 0x00000358 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT_A_X_SHIFT 0 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT_A_X_MASK 0x0000ffff +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT_A_Y_SHIFT 16 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_CURSOR_POINT_OUT_A_Y_MASK 0xffff0000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_IMAGE_SIZE(x) (0x00000380+((x)*16)) +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_IMAGE_SIZE__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_IMAGE_SIZE_W_SHIFT 0 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_IMAGE_SIZE_W_MASK 0x0000ffff +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_IMAGE_SIZE_H_SHIFT 16 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_IMAGE_SIZE_H_MASK 0xffff0000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_HSYNC(x) (0x00000384+((x)*16)) +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_HSYNC__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_HSYNC_START_SHIFT 0 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_HSYNC_START_MASK 0x0000ffff +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_HSYNC_WIDTH_SHIFT 16 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_HSYNC_WIDTH_MASK 0x0fff0000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_HSYNC_POLARITY_SHIFT 28 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_HSYNC_POLARITY_MASK 0xf0000000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_VSYNC(x) (0x00000388+((x)*16)) +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_VSYNC__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_VSYNC_START_SHIFT 0 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_VSYNC_START_MASK 0x0000ffff +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_VSYNC_WIDTH_SHIFT 16 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_VSYNC_WIDTH_MASK 0x0fff0000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_VSYNC_POLARITY_SHIFT 28 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_VSYNC_POLARITY_MASK 0xf0000000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_TOTAL_SIZE(x) (0x0000038c+((x)*16)) +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_TOTAL_SIZE__SIZE 0x00000002 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_TOTAL_SIZE_WIDTH_SHIFT 0 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_TOTAL_SIZE_WIDTH_MASK 0x0000ffff +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_TOTAL_SIZE_HEIGHT_SHIFT 16 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_TOTAL_SIZE_HEIGHT_MASK 0x0fff0000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_TOTAL_SIZE_NOTIFY_SHIFT 28 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_DAC_TOTAL_SIZE_NOTIFY_MASK 0xf0000000 +#define NV03_VIDEO_LUT_CURSOR_DAC_SET_PIXEL_CLOCK 0x000003a0 + + +#define NV03_DX3_TEXTURED_TRIANGLE 0x00000048 + +#define NV03_DX3_TEXTURED_TRIANGLE_NOP 0x00000100 +#define NV03_DX3_TEXTURED_TRIANGLE_NOTIFY 0x00000104 +#define NV03_DX3_TEXTURED_TRIANGLE_PATCH 0x0000010c +#define NV03_DX3_TEXTURED_TRIANGLE_DMA_NOTIFY 0x00000180 +#define NV03_DX3_TEXTURED_TRIANGLE_DMA_TEXTURE 0x00000184 +#define NV03_DX3_TEXTURED_TRIANGLE_CLIP_RECTANGLE 0x00000188 +#define NV03_DX3_TEXTURED_TRIANGLE_SURFACE 0x0000018c +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_OFFSET 0x00000304 +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT 0x00000308 +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT_COLOR_KEY_MASK_SHIFT 0 +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT_COLOR_KEY_MASK_MASK 0x0000ffff +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT_COLOR_KEY_ENABLE_SHIFT 16 +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT_COLOR_KEY_ENABLE_MASK 0x000f0000 +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT_COLOR_SHIFT 20 +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT_COLOR_MASK 0x00f00000 +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT_SIZE_MIN_SHIFT 24 +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT_SIZE_MIN_MASK 0x0f000000 +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT_SIZE_MAX_SHIFT 28 +#define NV03_DX3_TEXTURED_TRIANGLE_TEXTURE_FORMAT_SIZE_MAX_MASK 0xf0000000 +#define NV03_DX3_TEXTURED_TRIANGLE_FILTER 0x0000030c +#define NV03_DX3_TEXTURED_TRIANGLE_FILTER_SPREAD_X_SHIFT 0 +#define NV03_DX3_TEXTURED_TRIANGLE_FILTER_SPREAD_X_MASK 0x0000001f +#define NV03_DX3_TEXTURED_TRIANGLE_FILTER_SPREAD_Y_SHIFT 8 +#define NV03_DX3_TEXTURED_TRIANGLE_FILTER_SPREAD_Y_MASK 0x00001f00 +#define NV03_DX3_TEXTURED_TRIANGLE_FILTER_SIZE_ADJUST_SHIFT 16 +#define NV03_DX3_TEXTURED_TRIANGLE_FILTER_SIZE_ADJUST_MASK 0x00ff0000 +#define NV03_DX3_TEXTURED_TRIANGLE_FOG_COLOR 0x00000310 +#define NV03_DX3_TEXTURED_TRIANGLE_FOG_COLOR_B_SHIFT 0 +#define NV03_DX3_TEXTURED_TRIANGLE_FOG_COLOR_B_MASK 0x000000ff +#define NV03_DX3_TEXTURED_TRIANGLE_FOG_COLOR_G_SHIFT 8 +#define NV03_DX3_TEXTURED_TRIANGLE_FOG_COLOR_G_MASK 0x0000ff00 +#define NV03_DX3_TEXTURED_TRIANGLE_FOG_COLOR_R_SHIFT 16 +#define NV03_DX3_TEXTURED_TRIANGLE_FOG_COLOR_R_MASK 0x00ff0000 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT 0x00000314 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_INTERPOLATOR_SHIFT 0 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_INTERPOLATOR_MASK 0x0000000f +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_WRAP_U_SHIFT 4 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_WRAP_U_MASK 0x00000030 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_WRAP_V_SHIFT 6 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_WRAP_V_MASK 0x000000c0 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_SOURCE_COLOR_SHIFT 8 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_SOURCE_COLOR_MASK 0x00000f00 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_CULLING_SHIFT 12 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_CULLING_MASK 0x00007000 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_Z_PERSPECTIVE_ENABLE (1 << 15) +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_Z_FUNC_SHIFT 16 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_Z_FUNC_MASK 0x000f0000 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_Z_WRITE_ENABLE_SHIFT 20 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_Z_WRITE_ENABLE_MASK 0x00f00000 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_COLOR_WRITE_ENABLE_SHIFT 24 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_COLOR_WRITE_ENABLE_MASK 0x07000000 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_ROP_SHIFT 27 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_ROP_MASK 0x18000000 +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_BETA (1 << 29) +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_DST_BLEND (1 << 30) +#define NV03_DX3_TEXTURED_TRIANGLE_CONTROL_OUT_SRC_BLEND (1 << 31) +#define NV03_DX3_TEXTURED_TRIANGLE_ALPHA_CONTROL 0x00000318 +#define NV03_DX3_TEXTURED_TRIANGLE_ALPHA_CONTROL_ALPHA_REF_SHIFT 0 +#define NV03_DX3_TEXTURED_TRIANGLE_ALPHA_CONTROL_ALPHA_REF_MASK 0x000000ff +#define NV03_DX3_TEXTURED_TRIANGLE_ALPHA_CONTROL_ALPHA_FUNC_SHIFT 8 +#define NV03_DX3_TEXTURED_TRIANGLE_ALPHA_CONTROL_ALPHA_FUNC_MASK 0xffffff00 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR(x) (0x00001000+((x)*32)) +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR__SIZE 0x00000040 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I0_SHIFT 0 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I0_MASK 0x0000000f +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I1_SHIFT 4 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I1_MASK 0x000000f0 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I2_SHIFT 8 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I2_MASK 0x00000f00 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I3_SHIFT 12 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I3_MASK 0x0000f000 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I4_SHIFT 16 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I4_MASK 0x000f0000 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I5_SHIFT 20 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_I5_MASK 0x00f00000 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_FOG_SHIFT 24 +#define NV03_DX3_TEXTURED_TRIANGLE_SPECULAR_FOG_MASK 0xff000000 +#define NV03_DX3_TEXTURED_TRIANGLE_COLOR(x) (0x00001004+((x)*32)) +#define NV03_DX3_TEXTURED_TRIANGLE_COLOR__SIZE 0x00000040 +#define NV03_DX3_TEXTURED_TRIANGLE_X(x) (0x00001008+((x)*32)) +#define NV03_DX3_TEXTURED_TRIANGLE_X__SIZE 0x00000040 +#define NV03_DX3_TEXTURED_TRIANGLE_Y(x) (0x0000100c+((x)*32)) +#define NV03_DX3_TEXTURED_TRIANGLE_Y__SIZE 0x00000040 +#define NV03_DX3_TEXTURED_TRIANGLE_Z(x) (0x00001010+((x)*32)) +#define NV03_DX3_TEXTURED_TRIANGLE_Z__SIZE 0x00000040 +#define NV03_DX3_TEXTURED_TRIANGLE_M(x) (0x00001014+((x)*32)) +#define NV03_DX3_TEXTURED_TRIANGLE_M__SIZE 0x00000040 +#define NV03_DX3_TEXTURED_TRIANGLE_U(x) (0x00001018+((x)*32)) +#define NV03_DX3_TEXTURED_TRIANGLE_U__SIZE 0x00000040 +#define NV03_DX3_TEXTURED_TRIANGLE_V(x) (0x0000101c+((x)*32)) +#define NV03_DX3_TEXTURED_TRIANGLE_V__SIZE 0x00000040 + + +#define NV04_GDI_RECTANGLE_TEXT 0x0000004a + +#define NV04_GDI_RECTANGLE_TEXT_NOP 0x00000100 +#define NV04_GDI_RECTANGLE_TEXT_NOTIFY 0x00000104 +#define NV04_GDI_RECTANGLE_TEXT_PATCH 0x0000010c +#define NV04_GDI_RECTANGLE_TEXT_PM_TRIGGER 0x00000140 +#define NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY 0x00000180 +#define NV04_GDI_RECTANGLE_TEXT_DMA_FONTS 0x00000184 +#define NV04_GDI_RECTANGLE_TEXT_PATTERN 0x00000188 +#define NV04_GDI_RECTANGLE_TEXT_ROP 0x0000018c +#define NV04_GDI_RECTANGLE_TEXT_BETA1 0x00000190 +#define NV04_GDI_RECTANGLE_TEXT_BETA4 0x00000194 +#define NV04_GDI_RECTANGLE_TEXT_SURFACE 0x00000198 +#define NV04_GDI_RECTANGLE_TEXT_OPERATION 0x000002fc +#define NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY_AND 0x00000000 +#define NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND 0x00000001 +#define NV04_GDI_RECTANGLE_TEXT_OPERATION_BLEND_AND 0x00000002 +#define NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY 0x00000003 +#define NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY_PREMULT 0x00000004 +#define NV04_GDI_RECTANGLE_TEXT_OPERATION_BLEND_PREMULT 0x00000005 +#define NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT 0x00000300 +#define NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5 0x00000001 +#define NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_X16A1R5G5B5 0x00000002 +#define NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8 0x00000003 +#define NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT 0x00000304 +#define NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_CGA6 0x00000001 +#define NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE 0x00000002 +#define NV04_GDI_RECTANGLE_TEXT_COLOR1_A 0x000003fc +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(x) (0x00000400+((x)*8)) +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT__SIZE 0x00000020 +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT_Y_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT_Y_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT_X_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT_X_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE(x) (0x00000404+((x)*8)) +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE__SIZE 0x00000020 +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE_H_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE_H_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE_W_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE_W_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_B_POINT0 0x000005f4 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_B_POINT0_L_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_B_POINT0_L_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIP_B_POINT0_T_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_B_POINT0_T_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_B_POINT1 0x000005f8 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_B_POINT1_R_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_B_POINT1_R_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIP_B_POINT1_B_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_B_POINT1_B_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_COLOR1_B 0x000005fc +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0(x) (0x00000600+((x)*8)) +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0__SIZE 0x00000020 +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0_L_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0_L_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0_T_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0_T_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1(x) (0x00000604+((x)*8)) +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1__SIZE 0x00000020 +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1_R_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1_R_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1_B_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1_B_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_C_POINT0 0x000007ec +#define NV04_GDI_RECTANGLE_TEXT_CLIP_C_POINT0_L_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_C_POINT0_L_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIP_C_POINT0_T_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_C_POINT0_T_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_C_POINT1 0x000007f0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_C_POINT1_R_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_C_POINT1_R_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIP_C_POINT1_B_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_C_POINT1_B_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_COLOR1_C 0x000007f4 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_C 0x000007f8 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_C_W_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_C_W_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_SIZE_C_H_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_C_H_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_POINT_C 0x000007fc +#define NV04_GDI_RECTANGLE_TEXT_POINT_C_X_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_POINT_C_X_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_POINT_C_Y_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_POINT_C_Y_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_MONOCHROME_COLOR1_C(x) (0x00000800+((x)*4)) +#define NV04_GDI_RECTANGLE_TEXT_MONOCHROME_COLOR1_C__SIZE 0x00000080 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_E_POINT0 0x00000be4 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_E_POINT0_L_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_E_POINT0_L_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIP_E_POINT0_T_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_E_POINT0_T_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_E_POINT1 0x00000be8 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_E_POINT1_R_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_E_POINT1_R_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIP_E_POINT1_B_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_E_POINT1_B_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_COLOR0_E 0x00000bec +#define NV04_GDI_RECTANGLE_TEXT_COLOR1_E 0x00000bf0 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_IN_E 0x00000bf4 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_IN_E_W_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_IN_E_W_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_SIZE_IN_E_H_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_IN_E_H_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_OUT_E 0x00000bf8 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_OUT_E_W_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_OUT_E_W_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_SIZE_OUT_E_H_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_SIZE_OUT_E_H_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_POINT_E 0x00000bfc +#define NV04_GDI_RECTANGLE_TEXT_POINT_E_X_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_POINT_E_X_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_POINT_E_Y_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_POINT_E_Y_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_MONOCHROME_COLOR01_E(x) (0x00000c00+((x)*4)) +#define NV04_GDI_RECTANGLE_TEXT_MONOCHROME_COLOR01_E__SIZE 0x00000080 +#define NV04_GDI_RECTANGLE_TEXT_FONT_F 0x00000ff0 +#define NV04_GDI_RECTANGLE_TEXT_FONT_F_OFFSET_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_FONT_F_OFFSET_MASK 0x0fffffff +#define NV04_GDI_RECTANGLE_TEXT_FONT_F_PITCH_SHIFT 28 +#define NV04_GDI_RECTANGLE_TEXT_FONT_F_PITCH_MASK 0xf0000000 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_F_POINT0 0x00000ff4 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_F_POINT0_L_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_F_POINT0_L_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIP_F_POINT0_T_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_F_POINT0_T_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_F_POINT1 0x00000ff8 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_F_POINT1_R_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_F_POINT1_R_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIP_F_POINT1_B_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_F_POINT1_B_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_COLOR1_F 0x00000ffc +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_F(x) (0x00001000+((x)*4)) +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_F__SIZE 0x00000100 +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_F_INDEX_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_F_INDEX_MASK 0x000000ff +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_F_X_SHIFT 8 +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_F_X_MASK 0x000fff00 +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_F_Y_SHIFT 20 +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_F_Y_MASK 0xfff00000 +#define NV04_GDI_RECTANGLE_TEXT_FONT_G 0x000017f0 +#define NV04_GDI_RECTANGLE_TEXT_FONT_G_OFFSET_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_FONT_G_OFFSET_MASK 0x0fffffff +#define NV04_GDI_RECTANGLE_TEXT_FONT_G_PITCH_SHIFT 28 +#define NV04_GDI_RECTANGLE_TEXT_FONT_G_PITCH_MASK 0xf0000000 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_G_POINT0 0x000017f4 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_G_POINT0_L_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_G_POINT0_L_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIP_G_POINT0_T_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_G_POINT0_T_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_G_POINT1 0x000017f8 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_G_POINT1_R_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_G_POINT1_R_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CLIP_G_POINT1_B_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CLIP_G_POINT1_B_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_COLOR1_G 0x000017fc +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_G_POINT(x) (0x00001800+((x)*8)) +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_G_POINT__SIZE 0x00000100 +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_G_POINT_X_SHIFT 0 +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_G_POINT_X_MASK 0x0000ffff +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_G_POINT_Y_SHIFT 16 +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_G_POINT_Y_MASK 0xffff0000 +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_G_INDEX(x) (0x00001804+((x)*8)) +#define NV04_GDI_RECTANGLE_TEXT_CHARACTER_COLOR1_G_INDEX__SIZE 0x00000100 + + +#define NV03_GDI_RECTANGLE_TEXT 0x0000004b + +#define NV03_GDI_RECTANGLE_TEXT_NOP 0x00000100 +#define NV03_GDI_RECTANGLE_TEXT_NOTIFY 0x00000104 +#define NV03_GDI_RECTANGLE_TEXT_DMA_NOTIFY 0x00000180 +#define NV03_GDI_RECTANGLE_TEXT_PATTERN 0x00000184 +#define NV03_GDI_RECTANGLE_TEXT_ROP 0x00000188 +#define NV03_GDI_RECTANGLE_TEXT_BETA1 0x0000018c +#define NV03_GDI_RECTANGLE_TEXT_SURFACE 0x00000190 +#define NV03_GDI_RECTANGLE_TEXT_OPERATION 0x000002fc +#define NV03_GDI_RECTANGLE_TEXT_COLOR_FORMAT 0x00000300 +#define NV03_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT 0x00000304 +#define NV03_GDI_RECTANGLE_TEXT_COLOR1_A 0x000003fc +#define NV03_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT 0x00000400 +#define NV03_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT_Y_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT_Y_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT_X_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT_X_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE 0x00000404 +#define NV03_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE_H_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE_H_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE_W_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_SIZE_W_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_POINT0_B 0x000007f4 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_POINT0_B_L_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_POINT0_B_L_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_CLIP_POINT0_B_T_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_POINT0_B_T_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_POINT1_B 0x000007f8 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_POINT1_B_R_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_POINT1_B_R_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_CLIP_POINT1_B_B_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_POINT1_B_B_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_COLOR1_B 0x000007fc +#define NV03_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0 0x00000800 +#define NV03_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0_L_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0_L_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0_T_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_0_T_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1 0x00000804 +#define NV03_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1_R_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1_R_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1_B_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_CLIPPED_RECTANGLE_POINT_1_B_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_C_POINT0 0x00000bec +#define NV03_GDI_RECTANGLE_TEXT_CLIP_C_POINT0_L_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_C_POINT0_L_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_CLIP_C_POINT0_T_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_C_POINT0_T_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_C_POINT1 0x00000bf0 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_C_POINT1_R_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_C_POINT1_R_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_CLIP_C_POINT1_B_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_C_POINT1_B_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_COLOR1_C 0x00000bf4 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_C 0x00000bf8 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_C_W_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_C_W_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_SIZE_C_H_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_C_H_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_POINT_C 0x00000bfc +#define NV03_GDI_RECTANGLE_TEXT_POINT_C_X_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_POINT_C_X_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_POINT_C_Y_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_POINT_C_Y_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_MONOCHROME_COLOR1_C(x) (0x00000c00+((x)*4)) +#define NV03_GDI_RECTANGLE_TEXT_MONOCHROME_COLOR1_C__SIZE 0x00000020 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_D_POINT0 0x00000fe8 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_D_POINT0_L_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_D_POINT0_L_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_CLIP_D_POINT0_T_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_D_POINT0_T_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_D_POINT1 0x00000fec +#define NV03_GDI_RECTANGLE_TEXT_CLIP_D_POINT1_R_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_D_POINT1_R_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_CLIP_D_POINT1_B_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_D_POINT1_B_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_COLOR1_D 0x00000ff0 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_IN_D 0x00000ff4 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_IN_D_W_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_IN_D_W_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_SIZE_IN_D_H_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_IN_D_H_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_OUT_D 0x00000ff8 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_OUT_D_W_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_OUT_D_W_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_SIZE_OUT_D_H_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_OUT_D_H_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_POINT_D 0x00000ffc +#define NV03_GDI_RECTANGLE_TEXT_POINT_D_X_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_POINT_D_X_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_POINT_D_Y_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_POINT_D_Y_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_MONOCHROME_COLOR1_D(x) (0x00001000+((x)*4)) +#define NV03_GDI_RECTANGLE_TEXT_MONOCHROME_COLOR1_D__SIZE 0x00000020 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_E_POINT0 0x000013e4 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_E_POINT0_L_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_E_POINT0_L_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_CLIP_E_POINT0_T_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_E_POINT0_T_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_E_POINT1 0x000013e8 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_E_POINT1_R_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_E_POINT1_R_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_CLIP_E_POINT1_B_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_CLIP_E_POINT1_B_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_COLOR0_E 0x000013ec +#define NV03_GDI_RECTANGLE_TEXT_COLOR1_E 0x000013f0 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_IN_E 0x000013f4 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_IN_E_W_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_IN_E_W_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_SIZE_IN_E_H_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_IN_E_H_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_OUT_E 0x000013f8 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_OUT_E_W_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_OUT_E_W_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_SIZE_OUT_E_H_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_SIZE_OUT_E_H_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_POINT_E 0x000013fc +#define NV03_GDI_RECTANGLE_TEXT_POINT_E_X_SHIFT 0 +#define NV03_GDI_RECTANGLE_TEXT_POINT_E_X_MASK 0x0000ffff +#define NV03_GDI_RECTANGLE_TEXT_POINT_E_Y_SHIFT 16 +#define NV03_GDI_RECTANGLE_TEXT_POINT_E_Y_MASK 0xffff0000 +#define NV03_GDI_RECTANGLE_TEXT_MONOCHROME_COLOR01_E(x) (0x00001400+((x)*4)) +#define NV03_GDI_RECTANGLE_TEXT_MONOCHROME_COLOR01_E__SIZE 0x00000020 + + +#define NV04_SWIZZLED_SURFACE 0x00000052 + +#define NV04_SWIZZLED_SURFACE_NOP 0x00000100 +#define NV04_SWIZZLED_SURFACE_NOTIFY 0x00000104 +#define NV04_SWIZZLED_SURFACE_DMA_NOTIFY 0x00000180 +#define NV04_SWIZZLED_SURFACE_DMA_IMAGE 0x00000184 +#define NV04_SWIZZLED_SURFACE_FORMAT 0x00000300 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_SHIFT 0 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_MASK 0x000000ff +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_Y8 0x00000001 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_X1R5G5B5_Z1R5G5B5 0x00000002 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_X1R5G5B5_X1R5G5B5 0x00000003 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_R5G6B5 0x00000004 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_Y16 0x00000005 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_X8R8G8B8_Z8R8G8B8 0x00000006 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_X8R8G8B8_X8R8G8B8 0x00000007 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_X1A7R8G8B8_Z1A7R8G8B8 0x00000008 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_X1A7R8G8B8_X1A7R8G8B8 0x00000009 +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8 0x0000000a +#define NV04_SWIZZLED_SURFACE_FORMAT_COLOR_Y32 0x0000000b +#define NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT 16 +#define NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_MASK 0x00ff0000 +#define NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT 24 +#define NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_MASK 0xff000000 +#define NV04_SWIZZLED_SURFACE_OFFSET 0x00000304 + + +#define NV04_CONTEXT_SURFACES_3D 0x00000053 + +#define NV04_CONTEXT_SURFACES_3D_NOP 0x00000100 +#define NV04_CONTEXT_SURFACES_3D_NOTIFY 0x00000104 +#define NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY 0x00000180 +#define NV04_CONTEXT_SURFACES_3D_DMA_COLOR 0x00000184 +#define NV04_CONTEXT_SURFACES_3D_DMA_ZETA 0x00000188 +#define NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL 0x000002f8 +#define NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL_X_SHIFT 0 +#define NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL_X_MASK 0x0000ffff +#define NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL_W_SHIFT 16 +#define NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL_W_MASK 0xffff0000 +#define NV04_CONTEXT_SURFACES_3D_CLIP_VERTICAL 0x000002fc +#define NV04_CONTEXT_SURFACES_3D_CLIP_VERTICAL_Y_SHIFT 0 +#define NV04_CONTEXT_SURFACES_3D_CLIP_VERTICAL_Y_MASK 0x0000ffff +#define NV04_CONTEXT_SURFACES_3D_CLIP_VERTICAL_H_SHIFT 16 +#define NV04_CONTEXT_SURFACES_3D_CLIP_VERTICAL_H_MASK 0xffff0000 +#define NV04_CONTEXT_SURFACES_3D_FORMAT 0x00000300 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_COLOR_SHIFT 0 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_COLOR_MASK 0x000000ff +#define NV04_CONTEXT_SURFACES_3D_FORMAT_COLOR_X1R5G5B5_Z1R5G5B5 0x00000001 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_COLOR_X1R5G5B5_X1R5G5B5 0x00000002 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_COLOR_R5G6B5 0x00000003 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_COLOR_X8R8G8B8_Z8R8G8B8 0x00000004 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_COLOR_X8R8G8B8_X8R8G8B8 0x00000005 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_COLOR_X1A7R8G8B8_Z1A7R8G8B8 0x00000006 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_COLOR_X1A7R8G8B8_X1A7R8G8B8 0x00000007 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_COLOR_A8R8G8B8 0x00000008 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_TYPE_SHIFT 8 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_TYPE_MASK 0x0000ff00 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_TYPE_PITCH 0x00000100 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_TYPE_SWIZZLE 0x00000200 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_BASE_SIZE_U_SHIFT 16 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_BASE_SIZE_U_MASK 0x00ff0000 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_BASE_SIZE_V_SHIFT 24 +#define NV04_CONTEXT_SURFACES_3D_FORMAT_BASE_SIZE_V_MASK 0xff000000 +#define NV04_CONTEXT_SURFACES_3D_CLIP_SIZE 0x00000304 +#define NV04_CONTEXT_SURFACES_3D_CLIP_SIZE_W_SHIFT 0 +#define NV04_CONTEXT_SURFACES_3D_CLIP_SIZE_W_MASK 0x0000ffff +#define NV04_CONTEXT_SURFACES_3D_CLIP_SIZE_H_SHIFT 16 +#define NV04_CONTEXT_SURFACES_3D_CLIP_SIZE_H_MASK 0xffff0000 +#define NV04_CONTEXT_SURFACES_3D_PITCH 0x00000308 +#define NV04_CONTEXT_SURFACES_3D_PITCH_COLOR_SHIFT 0 +#define NV04_CONTEXT_SURFACES_3D_PITCH_COLOR_MASK 0x0000ffff +#define NV04_CONTEXT_SURFACES_3D_PITCH_ZETA_SHIFT 16 +#define NV04_CONTEXT_SURFACES_3D_PITCH_ZETA_MASK 0xffff0000 +#define NV04_CONTEXT_SURFACES_3D_OFFSET_COLOR 0x0000030c +#define NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA 0x00000310 + + +#define NV04_DX5_TEXTURED_TRIANGLE 0x00000054 + +#define NV04_DX5_TEXTURED_TRIANGLE_NOP 0x00000100 +#define NV04_DX5_TEXTURED_TRIANGLE_NOTIFY 0x00000104 +#define NV04_DX5_TEXTURED_TRIANGLE_DMA_NOTIFY 0x00000180 +#define NV04_DX5_TEXTURED_TRIANGLE_DMA_A 0x00000184 +#define NV04_DX5_TEXTURED_TRIANGLE_DMA_B 0x00000188 +#define NV04_DX5_TEXTURED_TRIANGLE_SURFACE 0x0000018c +#define NV04_DX5_TEXTURED_TRIANGLE_COLORKEY 0x00000300 +#define NV04_DX5_TEXTURED_TRIANGLE_OFFSET 0x00000304 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT 0x00000308 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_DMA_SHIFT 0 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_DMA_MASK 0x00000003 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_KEY_MATCH_SHIFT 2 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_KEY_MATCH_MASK 0x0000000c +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_SHIFT 4 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_MASK 0x00000030 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_CENTER 0x00000010 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_CORNER 0x00000020 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_SHIFT 6 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_MASK 0x000000c0 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CENTER 0x00000040 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CORNER 0x00000080 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_SHIFT 8 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_MASK 0x00000f00 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_Y8 0x00000100 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_A1R5G5B5 0x00000200 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_X1R5G5B5 0x00000300 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_A4R4G4B4 0x00000400 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_R5G6B5 0x00000500 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8 0x00000600 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_X8R8G8B8 0x00000700 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT 12 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_MASK 0x0000f000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT 16 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_MASK 0x000f0000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT 20 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_MASK 0x00f00000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT 24 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MASK 0x07000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT 0x01000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT 0x02000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE 0x03000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER 0x04000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP 0x05000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_WRAPU (1 << 27) +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT 28 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_MASK 0x70000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_REPEAT 0x10000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_MIRRORED_REPEAT 0x20000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP_TO_EDGE 0x30000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP_TO_BORDER 0x40000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP 0x50000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FORMAT_WRAPV (1 << 31) +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER 0x0000030c +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_KERNEL_SIZE_X_SHIFT 0 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_KERNEL_SIZE_X_MASK 0x000000ff +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_KERNEL_SIZE_Y_SHIFT 8 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_KERNEL_SIZE_Y_MASK 0x00007f00 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MIPMAP_DITHER_ENABLE (1 << 15) +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MIPMAP_LODBIAS_SHIFT 16 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MIPMAP_LODBIAS_MASK 0x00ff0000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_SHIFT 24 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_MASK 0x07000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST 0x01000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR 0x02000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST 0x03000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST 0x04000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR 0x05000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR 0x06000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE (1 << 27) +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_SHIFT 28 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_MASK 0x70000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST 0x10000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR 0x20000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE (1 << 31) +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND 0x00000310 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_TEXTURE_MAP_SHIFT 0 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_TEXTURE_MAP_MASK 0x0000000f +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_MASK_BIT_SHIFT 4 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_MASK_BIT_MASK 0x00000030 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_SHIFT 6 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_MASK 0x000000c0 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT 0x00000040 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD 0x00000080 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_PHONG 0x000000c0 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE_SHIFT 8 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE_MASK 0x00000f00 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_SPECULAR_ENABLE_SHIFT 12 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_SPECULAR_ENABLE_MASK 0x0000f000 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE_SHIFT 16 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE_MASK 0x000f0000 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_ALPHA_ENABLE_SHIFT 20 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_ALPHA_ENABLE_MASK 0x00f00000 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_SRC_SHIFT 24 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_SRC_MASK 0x0f000000 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_DST_SHIFT 28 +#define NV04_DX5_TEXTURED_TRIANGLE_BLEND_DST_MASK 0xf0000000 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL 0x00000314 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_REF_SHIFT 0 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_REF_MASK 0x000000ff +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT 8 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_MASK 0x00000f00 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_TEST_ENABLE (1 << 12) +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ORIGIN (1 << 13) +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE_SHIFT 14 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE_MASK 0x0000c000 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT 16 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_MASK 0x000f0000 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT 20 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_MASK 0x00300000 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE (1 << 22) +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE (1 << 23) +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_WRITE_ENABLE_SHIFT 24 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_WRITE_ENABLE_MASK 0x3f000000 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_SHIFT 30 +#define NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_MASK 0xc0000000 +#define NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR 0x00000318 +#define NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR_B_SHIFT 0 +#define NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR_B_MASK 0x000000ff +#define NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR_G_SHIFT 8 +#define NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR_G_MASK 0x0000ff00 +#define NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR_R_SHIFT 16 +#define NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR_R_MASK 0x00ff0000 +#define NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR_A_SHIFT 24 +#define NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR_A_MASK 0xff000000 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(x) (0x00000400+((x)*32)) +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX__SIZE 0x00000010 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SY(x) (0x00000404+((x)*32)) +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SY__SIZE 0x00000010 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SZ(x) (0x00000408+((x)*32)) +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SZ__SIZE 0x00000010 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_RHW(x) (0x0000040c+((x)*32)) +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_RHW__SIZE 0x00000010 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_COLOR(x) (0x00000410+((x)*32)) +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_COLOR__SIZE 0x00000010 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_COLOR_B_SHIFT 0 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_COLOR_B_MASK 0x000000ff +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_COLOR_G_SHIFT 8 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_COLOR_G_MASK 0x0000ff00 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_COLOR_R_SHIFT 16 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_COLOR_R_MASK 0x00ff0000 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_COLOR_A_SHIFT 24 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_COLOR_A_MASK 0xff000000 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SPECULAR(x) (0x00000414+((x)*32)) +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SPECULAR__SIZE 0x00000010 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SPECULAR_B_SHIFT 0 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SPECULAR_B_MASK 0x000000ff +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SPECULAR_G_SHIFT 8 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SPECULAR_G_MASK 0x0000ff00 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SPECULAR_R_SHIFT 16 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SPECULAR_R_MASK 0x00ff0000 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SPECULAR_FOG_SHIFT 24 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SPECULAR_FOG_MASK 0xff000000 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_TU(x) (0x00000418+((x)*32)) +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_TU__SIZE 0x00000010 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_TV(x) (0x0000041c+((x)*32)) +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_TV__SIZE 0x00000010 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE(x) (0x00000600+((x)*4)) +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE__SIZE 0x00000040 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I0_SHIFT 0 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I0_MASK 0x0000000f +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I1_SHIFT 4 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I1_MASK 0x000000f0 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I2_SHIFT 8 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I2_MASK 0x00000f00 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I3_SHIFT 12 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I3_MASK 0x0000f000 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I4_SHIFT 16 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I4_MASK 0x000f0000 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I5_SHIFT 20 +#define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE_I5_MASK 0x00f00000 + + +#define NV04_DX6_MULTITEX_TRIANGLE 0x00000055 + +#define NV04_DX6_MULTITEX_TRIANGLE_NOP 0x00000100 +#define NV04_DX6_MULTITEX_TRIANGLE_NOTIFY 0x00000104 +#define NV04_DX6_MULTITEX_TRIANGLE_DMA_NOTIFY 0x00000180 +#define NV04_DX6_MULTITEX_TRIANGLE_DMA_A 0x00000184 +#define NV04_DX6_MULTITEX_TRIANGLE_DMA_B 0x00000188 +#define NV04_DX6_MULTITEX_TRIANGLE_SURFACE 0x0000018c +#define NV04_DX6_MULTITEX_TRIANGLE_OFFSET(x) (0x00000308+((x)*4)) +#define NV04_DX6_MULTITEX_TRIANGLE_OFFSET__SIZE 0x00000002 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT(x) (0x00000310+((x)*4)) +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT__SIZE 0x00000002 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_DMA_SHIFT 0 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_DMA_MASK 0x0000000f +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_ORIGIN_ZOH_SHIFT 4 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_ORIGIN_ZOH_MASK 0x00000030 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_ORIGIN_FOH_SHIFT 6 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_ORIGIN_FOH_MASK 0x000000c0 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_COLOR_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_COLOR_MASK 0x00000f00 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT 12 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_MIPMAP_LEVELS_MASK 0x0000f000 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT 16 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_BASE_SIZE_U_MASK 0x000f0000 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT 20 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_BASE_SIZE_V_MASK 0x00f00000 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_ADDRESSU_SHIFT 24 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_ADDRESSU_MASK 0x07000000 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_WRAPU (1 << 27) +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_ADDRESSV_SHIFT 28 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_ADDRESSV_MASK 0x70000000 +#define NV04_DX6_MULTITEX_TRIANGLE_FORMAT_WRAPV (1 << 31) +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER(x) (0x00000318+((x)*4)) +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER__SIZE 0x00000002 +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_KERNEL_SIZE_X_SHIFT 0 +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_KERNEL_SIZE_X_MASK 0x000000ff +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_KERNEL_SIZE_Y_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_KERNEL_SIZE_Y_MASK 0x00007f00 +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_MIPMAP_DITHER_ENABLE (1 << 15) +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_MIPMAP_LODBIAS_SHIFT 16 +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_MIPMAP_LODBIAS_MASK 0x00ff0000 +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_MINIFY_SHIFT 24 +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_MINIFY_MASK 0x07000000 +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE (1 << 27) +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_MAGNIFY_SHIFT 28 +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_MAGNIFY_MASK 0x70000000 +#define NV04_DX6_MULTITEX_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE (1 << 31) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA 0x00000320 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_INVERSE0 (1 << 0) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ALPHA0 (1 << 1) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ARGUMENT0_SHIFT 2 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ARGUMENT0_MASK 0x000000fc +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_INVERSE1 (1 << 8) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ALPHA1 (1 << 9) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ARGUMENT1_SHIFT 10 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ARGUMENT1_MASK 0x0000fc00 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_INVERSE2 (1 << 16) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ALPHA2 (1 << 17) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ARGUMENT2_SHIFT 18 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ARGUMENT2_MASK 0x00fc0000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_INVERSE3 (1 << 24) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ALPHA3 (1 << 25) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ARGUMENT3_SHIFT 26 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_ARGUMENT3_MASK 0x1c000000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_OPERATION_SHIFT 29 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA_OPERATION_MASK 0xe0000000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR 0x00000324 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_INVERSE0 (1 << 0) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ALPHA0 (1 << 1) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ARGUMENT0_SHIFT 2 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ARGUMENT0_MASK 0x000000fc +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_INVERSE1 (1 << 8) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ALPHA1 (1 << 9) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ARGUMENT1_SHIFT 10 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ARGUMENT1_MASK 0x0000fc00 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_INVERSE2 (1 << 16) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ALPHA2 (1 << 17) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ARGUMENT2_SHIFT 18 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ARGUMENT2_MASK 0x00fc0000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_INVERSE3 (1 << 24) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ALPHA3 (1 << 25) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ARGUMENT3_SHIFT 26 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_ARGUMENT3_MASK 0x1c000000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_OPERATION_SHIFT 29 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR_OPERATION_MASK 0xe0000000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA 0x0000032c +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_INVERSE0 (1 << 0) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ALPHA0 (1 << 1) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ARGUMENT0_SHIFT 2 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ARGUMENT0_MASK 0x000000fc +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_INVERSE1 (1 << 8) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ALPHA1 (1 << 9) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ARGUMENT1_SHIFT 10 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ARGUMENT1_MASK 0x0000fc00 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_INVERSE2 (1 << 16) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ALPHA2 (1 << 17) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ARGUMENT2_SHIFT 18 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ARGUMENT2_MASK 0x00fc0000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_INVERSE3 (1 << 24) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ALPHA3 (1 << 25) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ARGUMENT3_SHIFT 26 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_ARGUMENT3_MASK 0x1c000000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_OPERATION_SHIFT 29 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA_OPERATION_MASK 0xe0000000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR 0x00000330 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_INVERSE0 (1 << 0) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ALPHA0 (1 << 1) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ARGUMENT0_SHIFT 2 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ARGUMENT0_MASK 0x000000fc +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_INVERSE1 (1 << 8) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ALPHA1 (1 << 9) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ARGUMENT1_SHIFT 10 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ARGUMENT1_MASK 0x0000fc00 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_INVERSE2 (1 << 16) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ALPHA2 (1 << 17) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ARGUMENT2_SHIFT 18 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ARGUMENT2_MASK 0x00fc0000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_INVERSE3 (1 << 24) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ALPHA3 (1 << 25) +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ARGUMENT3_SHIFT 26 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_ARGUMENT3_MASK 0x1c000000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_OPERATION_SHIFT 29 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR_OPERATION_MASK 0xe0000000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR 0x00000334 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR_B_SHIFT 0 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR_B_MASK 0x000000ff +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR_G_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR_G_MASK 0x0000ff00 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR_R_SHIFT 16 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR_R_MASK 0x00ff0000 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR_A_SHIFT 24 +#define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR_A_MASK 0xff000000 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND 0x00000338 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_MASK_BIT_SHIFT 4 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_MASK_BIT_MASK 0x00000030 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_SHIFT 6 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_MASK 0x000000c0 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE_MASK 0x00000f00 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_SPECULAR_ENABLE_SHIFT 12 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_SPECULAR_ENABLE_MASK 0x0000f000 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_FOG_ENABLE_SHIFT 16 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_FOG_ENABLE_MASK 0x000f0000 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_ALPHA_ENABLE_SHIFT 20 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_ALPHA_ENABLE_MASK 0x00f00000 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_SRC_SHIFT 24 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_SRC_MASK 0x0f000000 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_DST_SHIFT 28 +#define NV04_DX6_MULTITEX_TRIANGLE_BLEND_DST_MASK 0xf0000000 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0 0x0000033c +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_ALPHA_REF_SHIFT 0 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_ALPHA_REF_MASK 0x000000ff +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_ALPHA_FUNC_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_ALPHA_FUNC_MASK 0x00000f00 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_ALPHA_TEST_ENABLE (1 << 12) +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_ORIGIN (1 << 13) +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_Z_ENABLE_SHIFT 14 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_Z_ENABLE_MASK 0x0000c000 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_Z_FUNC_SHIFT 16 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_Z_FUNC_MASK 0x000f0000 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_SHIFT 20 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_MASK 0x00300000 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_DITHER_ENABLE (1 << 22) +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_Z_PERSPECTIVE_ENABLE (1 << 23) +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_Z_WRITE_ENABLE (1 << 24) +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE_ENABLE (1 << 25) +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE_ENABLE (1 << 26) +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE_ENABLE (1 << 27) +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE_ENABLE (1 << 28) +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE_ENABLE (1 << 29) +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_Z_FORMAT_SHIFT 30 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0_Z_FORMAT_MASK 0xc0000000 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1 0x00000340 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1_STENCIL_TEST_ENABLE_SHIFT 0 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1_STENCIL_TEST_ENABLE_MASK 0x0000000f +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1_STENCIL_FUNC_SHIFT 4 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1_STENCIL_FUNC_MASK 0x000000f0 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1_STENCIL_REF_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1_STENCIL_REF_MASK 0x0000ff00 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1_STENCIL_MASK_READ_SHIFT 16 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1_STENCIL_MASK_READ_MASK 0x00ff0000 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1_STENCIL_MASK_WRITE_SHIFT 24 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1_STENCIL_MASK_WRITE_MASK 0xff000000 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL2 0x00000344 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL2_STENCIL_OP_FAIL_SHIFT 0 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL2_STENCIL_OP_FAIL_MASK 0x0000000f +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL2_STENCIL_OP_ZFAIL_SHIFT 4 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL2_STENCIL_OP_ZFAIL_MASK 0x000000f0 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL2_STENCIL_OP_ZPASS_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_CONTROL2_STENCIL_OP_ZPASS_MASK 0x00000f00 +#define NV04_DX6_MULTITEX_TRIANGLE_FOGCOLOR 0x00000348 +#define NV04_DX6_MULTITEX_TRIANGLE_FOGCOLOR_B_SHIFT 0 +#define NV04_DX6_MULTITEX_TRIANGLE_FOGCOLOR_B_MASK 0x000000ff +#define NV04_DX6_MULTITEX_TRIANGLE_FOGCOLOR_G_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_FOGCOLOR_G_MASK 0x0000ff00 +#define NV04_DX6_MULTITEX_TRIANGLE_FOGCOLOR_R_SHIFT 16 +#define NV04_DX6_MULTITEX_TRIANGLE_FOGCOLOR_R_MASK 0x00ff0000 +#define NV04_DX6_MULTITEX_TRIANGLE_FOGCOLOR_A_SHIFT 24 +#define NV04_DX6_MULTITEX_TRIANGLE_FOGCOLOR_A_MASK 0xff000000 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SX(x) (0x00000400+((x)*40)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SX__SIZE 0x00000008 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SY(x) (0x00000404+((x)*40)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SY__SIZE 0x00000008 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SZ(x) (0x00000408+((x)*40)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SZ__SIZE 0x00000008 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_RHW(x) (0x0000040c+((x)*40)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_RHW__SIZE 0x00000008 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_COLOR(x) (0x00000410+((x)*40)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_COLOR__SIZE 0x00000008 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_COLOR_B_SHIFT 0 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_COLOR_B_MASK 0x000000ff +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_COLOR_G_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_COLOR_G_MASK 0x0000ff00 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_COLOR_R_SHIFT 16 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_COLOR_R_MASK 0x00ff0000 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_COLOR_A_SHIFT 24 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_COLOR_A_MASK 0xff000000 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SPECULAR(x) (0x00000414+((x)*40)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SPECULAR__SIZE 0x00000008 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SPECULAR_B_SHIFT 0 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SPECULAR_B_MASK 0x000000ff +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SPECULAR_G_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SPECULAR_G_MASK 0x0000ff00 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SPECULAR_R_SHIFT 16 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SPECULAR_R_MASK 0x00ff0000 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SPECULAR_FOG_SHIFT 24 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_SPECULAR_FOG_MASK 0xff000000 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_TU0(x) (0x00000418+((x)*40)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_TU0__SIZE 0x00000008 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_TV0(x) (0x0000041c+((x)*40)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_TV0__SIZE 0x00000008 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_TU1(x) (0x00000420+((x)*40)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_TU1__SIZE 0x00000008 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_TV1(x) (0x00000424+((x)*40)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_TV1__SIZE 0x00000008 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE(x) (0x00000540+((x)*4)) +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE__SIZE 0x00000030 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I0_SHIFT 0 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I0_MASK 0x0000000f +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I1_SHIFT 4 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I1_MASK 0x000000f0 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I2_SHIFT 8 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I2_MASK 0x00000f00 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I3_SHIFT 12 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I3_MASK 0x0000f000 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I4_SHIFT 16 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I4_MASK 0x000f0000 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I5_SHIFT 20 +#define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I5_MASK 0x00f00000 + + +#define NV10_DX5_TEXTURED_TRIANGLE 0x00000094 + + + +#define NV10TCL 0x00000056 + +#define NV10TCL_NOP 0x00000100 +#define NV10TCL_NOTIFY 0x00000104 +#define NV10TCL_DMA_NOTIFY 0x00000180 +#define NV10TCL_DMA_IN_MEMORY0 0x00000184 +#define NV10TCL_DMA_IN_MEMORY1 0x00000188 +#define NV10TCL_DMA_VTXBUF0 0x0000018c +#define NV10TCL_DMA_IN_MEMORY2 0x00000194 +#define NV10TCL_DMA_IN_MEMORY3 0x00000198 +#define NV10TCL_RT_HORIZ 0x00000200 +#define NV10TCL_RT_HORIZ_X_SHIFT 0 +#define NV10TCL_RT_HORIZ_X_MASK 0x0000ffff +#define NV10TCL_RT_HORIZ_W_SHIFT 16 +#define NV10TCL_RT_HORIZ_W_MASK 0xffff0000 +#define NV10TCL_RT_VERT 0x00000204 +#define NV10TCL_RT_VERT_Y_SHIFT 0 +#define NV10TCL_RT_VERT_Y_MASK 0x0000ffff +#define NV10TCL_RT_VERT_H_SHIFT 16 +#define NV10TCL_RT_VERT_H_MASK 0xffff0000 +#define NV10TCL_RT_FORMAT 0x00000208 +#define NV10TCL_RT_FORMAT_TYPE_SHIFT 8 +#define NV10TCL_RT_FORMAT_TYPE_MASK 0x00000f00 +#define NV10TCL_RT_FORMAT_TYPE_LINEAR 0x00000100 +#define NV10TCL_RT_FORMAT_TYPE_SWIZZLED 0x00000200 +#define NV10TCL_RT_FORMAT_COLOR_SHIFT 0 +#define NV10TCL_RT_FORMAT_COLOR_MASK 0x0000001f +#define NV10TCL_RT_FORMAT_COLOR_R5G6B5 0x00000003 +#define NV10TCL_RT_FORMAT_COLOR_X8R8G8B8 0x00000005 +#define NV10TCL_RT_FORMAT_COLOR_A8R8G8B8 0x00000008 +#define NV10TCL_RT_FORMAT_COLOR_B8 0x00000009 +#define NV10TCL_RT_FORMAT_COLOR_X8B8G8R8 0x0000000f +#define NV10TCL_RT_FORMAT_COLOR_A8B8G8R8 0x00000010 +#define NV10TCL_RT_PITCH 0x0000020c +#define NV10TCL_RT_PITCH_COLOR_PITCH_SHIFT 0 +#define NV10TCL_RT_PITCH_COLOR_PITCH_MASK 0x0000ffff +#define NV10TCL_RT_PITCH_ZETA_PITCH_SHIFT 16 +#define NV10TCL_RT_PITCH_ZETA_PITCH_MASK 0xffff0000 +#define NV10TCL_COLOR_OFFSET 0x00000210 +#define NV10TCL_ZETA_OFFSET 0x00000214 +#define NV10TCL_TX_OFFSET(x) (0x00000218+((x)*4)) +#define NV10TCL_TX_OFFSET__SIZE 0x00000002 +#define NV10TCL_TX_FORMAT(x) (0x00000220+((x)*4)) +#define NV10TCL_TX_FORMAT__SIZE 0x00000002 +#define NV10TCL_TX_FORMAT_DMA0 (1 << 0) +#define NV10TCL_TX_FORMAT_DMA1 (1 << 1) +#define NV10TCL_TX_FORMAT_CUBE_MAP (1 << 2) +#define NV10TCL_TX_FORMAT_FORMAT_SHIFT 7 +#define NV10TCL_TX_FORMAT_FORMAT_MASK 0x00000780 +#define NV10TCL_TX_FORMAT_FORMAT_L8 0x00000000 +#define NV10TCL_TX_FORMAT_FORMAT_A8 0x00000080 +#define NV10TCL_TX_FORMAT_FORMAT_A1R5G5B5 0x00000100 +#define NV10TCL_TX_FORMAT_FORMAT_A8_RECT 0x00000180 +#define NV10TCL_TX_FORMAT_FORMAT_A4R4G4B4 0x00000200 +#define NV10TCL_TX_FORMAT_FORMAT_A8R8G8B8 0x00000300 +#define NV10TCL_TX_FORMAT_FORMAT_X8R8G8B8 0x00000380 +#define NV10TCL_TX_FORMAT_FORMAT_INDEX8 0x00000580 +#define NV10TCL_TX_FORMAT_FORMAT_DXT1 0x00000600 +#define NV10TCL_TX_FORMAT_FORMAT_DXT3 0x00000700 +#define NV10TCL_TX_FORMAT_FORMAT_DXT5 0x00000780 +#define NV10TCL_TX_FORMAT_FORMAT_A1R5G5B5_RECT 0x00000800 +#define NV10TCL_TX_FORMAT_FORMAT_A8R8G8B8_RECT 0x00000900 +#define NV10TCL_TX_FORMAT_FORMAT_L8_RECT 0x00000980 +#define NV10TCL_TX_FORMAT_FORMAT_A8L8 0x00000d00 +#define NV10TCL_TX_FORMAT_FORMAT_A8_RECT2 0x00000d80 +#define NV10TCL_TX_FORMAT_FORMAT_R8G8B8_RECT 0x00000f00 +#define NV10TCL_TX_FORMAT_FORMAT_A4R4G4B4_RECT 0x00000e80 +#define NV10TCL_TX_FORMAT_FORMAT_L8A8_RECT 0x00001000 +#define NV10TCL_TX_FORMAT_FORMAT_A16 0x00001900 +#define NV10TCL_TX_FORMAT_FORMAT_A16_RECT 0x00001a80 +#define NV10TCL_TX_FORMAT_FORMAT_FLOAT_RGBA16_NV 0x00002500 +#define NV10TCL_TX_FORMAT_FORMAT_FLOAT_RGBA32_NV 0x00002580 +#define NV10TCL_TX_FORMAT_FORMAT_FLOAT_R32_NV 0x00002600 +#define NV10TCL_TX_FORMAT_NPOT (1 << 11) +#define NV10TCL_TX_FORMAT_MIPMAP_LEVELS_SHIFT 12 +#define NV10TCL_TX_FORMAT_MIPMAP_LEVELS_MASK 0x0000f000 +#define NV10TCL_TX_FORMAT_BASE_SIZE_U_SHIFT 16 +#define NV10TCL_TX_FORMAT_BASE_SIZE_U_MASK 0x000f0000 +#define NV10TCL_TX_FORMAT_BASE_SIZE_V_SHIFT 20 +#define NV10TCL_TX_FORMAT_BASE_SIZE_V_MASK 0x00f00000 +#define NV10TCL_TX_FORMAT_WRAP_S_SHIFT 24 +#define NV10TCL_TX_FORMAT_WRAP_S_MASK 0x0f000000 +#define NV10TCL_TX_FORMAT_WRAP_S_REPEAT 0x01000000 +#define NV10TCL_TX_FORMAT_WRAP_S_MIRRORED_REPEAT 0x02000000 +#define NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE 0x03000000 +#define NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_BORDER 0x04000000 +#define NV10TCL_TX_FORMAT_WRAP_S_CLAMP 0x05000000 +#define NV10TCL_TX_FORMAT_WRAP_T_SHIFT 28 +#define NV10TCL_TX_FORMAT_WRAP_T_MASK 0xf0000000 +#define NV10TCL_TX_FORMAT_WRAP_T_REPEAT 0x10000000 +#define NV10TCL_TX_FORMAT_WRAP_T_MIRRORED_REPEAT 0x20000000 +#define NV10TCL_TX_FORMAT_WRAP_T_CLAMP_TO_EDGE 0x30000000 +#define NV10TCL_TX_FORMAT_WRAP_T_CLAMP_TO_BORDER 0x40000000 +#define NV10TCL_TX_FORMAT_WRAP_T_CLAMP 0x50000000 +#define NV10TCL_TX_ENABLE(x) (0x00000228+((x)*4)) +#define NV10TCL_TX_ENABLE__SIZE 0x00000002 +#define NV10TCL_TX_ENABLE_ANISOTROPY_SHIFT 4 +#define NV10TCL_TX_ENABLE_ANISOTROPY_MASK 0x00000030 +#define NV10TCL_TX_ENABLE_ENABLE (1 << 30) +#define NV10TCL_TX_NPOT_PITCH(x) (0x00000230+((x)*4)) +#define NV10TCL_TX_NPOT_PITCH__SIZE 0x00000002 +#define NV10TCL_TX_NPOT_PITCH_PITCH_SHIFT 16 +#define NV10TCL_TX_NPOT_PITCH_PITCH_MASK 0xffff0000 +#define NV10TCL_TX_NPOT_SIZE(x) (0x00000240+((x)*4)) +#define NV10TCL_TX_NPOT_SIZE__SIZE 0x00000002 +#define NV10TCL_TX_NPOT_SIZE_H_SHIFT 0 +#define NV10TCL_TX_NPOT_SIZE_H_MASK 0x0000ffff +#define NV10TCL_TX_NPOT_SIZE_W_SHIFT 16 +#define NV10TCL_TX_NPOT_SIZE_W_MASK 0xffff0000 +#define NV10TCL_TX_FILTER(x) (0x00000248+((x)*4)) +#define NV10TCL_TX_FILTER__SIZE 0x00000002 +#define NV10TCL_TX_FILTER_MINIFY_SHIFT 24 +#define NV10TCL_TX_FILTER_MINIFY_MASK 0x0f000000 +#define NV10TCL_TX_FILTER_MINIFY_NEAREST 0x01000000 +#define NV10TCL_TX_FILTER_MINIFY_LINEAR 0x02000000 +#define NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST 0x03000000 +#define NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST 0x04000000 +#define NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR 0x05000000 +#define NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR 0x06000000 +#define NV10TCL_TX_FILTER_MAGNIFY_SHIFT 28 +#define NV10TCL_TX_FILTER_MAGNIFY_MASK 0xf0000000 +#define NV10TCL_TX_FILTER_MAGNIFY_NEAREST 0x10000000 +#define NV10TCL_TX_FILTER_MAGNIFY_LINEAR 0x20000000 +#define NV10TCL_TX_PALETTE_OFFSET(x) (0x00000250+((x)*4)) +#define NV10TCL_TX_PALETTE_OFFSET__SIZE 0x00000002 +#define NV10TCL_RC_IN_ALPHA(x) (0x00000260+((x)*4)) +#define NV10TCL_RC_IN_ALPHA__SIZE 0x00000002 +#define NV10TCL_RC_IN_ALPHA_D_INPUT_SHIFT 0 +#define NV10TCL_RC_IN_ALPHA_D_INPUT_MASK 0x0000000f +#define NV10TCL_RC_IN_ALPHA_D_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_IN_ALPHA_D_INPUT_CONSTANT_COLOR0_NV 0x00000001 +#define NV10TCL_RC_IN_ALPHA_D_INPUT_CONSTANT_COLOR1_NV 0x00000002 +#define NV10TCL_RC_IN_ALPHA_D_INPUT_FOG 0x00000003 +#define NV10TCL_RC_IN_ALPHA_D_INPUT_PRIMARY_COLOR_NV 0x00000004 +#define NV10TCL_RC_IN_ALPHA_D_INPUT_SECONDARY_COLOR_NV 0x00000005 +#define NV10TCL_RC_IN_ALPHA_D_INPUT_TEXTURE0_ARB 0x00000008 +#define NV10TCL_RC_IN_ALPHA_D_INPUT_TEXTURE1_ARB 0x00000009 +#define NV10TCL_RC_IN_ALPHA_D_INPUT_SPARE0_NV 0x0000000c +#define NV10TCL_RC_IN_ALPHA_D_INPUT_SPARE1_NV 0x0000000d +#define NV10TCL_RC_IN_ALPHA_D_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x0000000e +#define NV10TCL_RC_IN_ALPHA_D_INPUT_E_TIMES_F_NV 0x0000000f +#define NV10TCL_RC_IN_ALPHA_D_COMPONENT_USAGE (1 << 4) +#define NV10TCL_RC_IN_ALPHA_D_COMPONENT_USAGE_BLUE 0x00000000 +#define NV10TCL_RC_IN_ALPHA_D_COMPONENT_USAGE_ALPHA 0x00000010 +#define NV10TCL_RC_IN_ALPHA_D_MAPPING_SHIFT 5 +#define NV10TCL_RC_IN_ALPHA_D_MAPPING_MASK 0x000000e0 +#define NV10TCL_RC_IN_ALPHA_D_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_IN_ALPHA_D_MAPPING_UNSIGNED_INVERT_NV 0x00000020 +#define NV10TCL_RC_IN_ALPHA_D_MAPPING_EXPAND_NORMAL_NV 0x00000040 +#define NV10TCL_RC_IN_ALPHA_D_MAPPING_EXPAND_NEGATE_NV 0x00000060 +#define NV10TCL_RC_IN_ALPHA_D_MAPPING_HALF_BIAS_NORMAL_NV 0x00000080 +#define NV10TCL_RC_IN_ALPHA_D_MAPPING_HALF_BIAS_NEGATE_NV 0x000000a0 +#define NV10TCL_RC_IN_ALPHA_D_MAPPING_SIGNED_IDENTITY_NV 0x000000c0 +#define NV10TCL_RC_IN_ALPHA_D_MAPPING_SIGNED_NEGATE_NV 0x000000e0 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_SHIFT 8 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_MASK 0x00000f00 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_CONSTANT_COLOR0_NV 0x00000100 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_CONSTANT_COLOR1_NV 0x00000200 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_FOG 0x00000300 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_PRIMARY_COLOR_NV 0x00000400 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_SECONDARY_COLOR_NV 0x00000500 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_TEXTURE0_ARB 0x00000800 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_TEXTURE1_ARB 0x00000900 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_SPARE0_NV 0x00000c00 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_SPARE1_NV 0x00000d00 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x00000e00 +#define NV10TCL_RC_IN_ALPHA_C_INPUT_E_TIMES_F_NV 0x00000f00 +#define NV10TCL_RC_IN_ALPHA_C_COMPONENT_USAGE (1 << 12) +#define NV10TCL_RC_IN_ALPHA_C_COMPONENT_USAGE_BLUE 0x00000000 +#define NV10TCL_RC_IN_ALPHA_C_COMPONENT_USAGE_ALPHA 0x00001000 +#define NV10TCL_RC_IN_ALPHA_C_MAPPING_SHIFT 13 +#define NV10TCL_RC_IN_ALPHA_C_MAPPING_MASK 0x0000e000 +#define NV10TCL_RC_IN_ALPHA_C_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_IN_ALPHA_C_MAPPING_UNSIGNED_INVERT_NV 0x00002000 +#define NV10TCL_RC_IN_ALPHA_C_MAPPING_EXPAND_NORMAL_NV 0x00004000 +#define NV10TCL_RC_IN_ALPHA_C_MAPPING_EXPAND_NEGATE_NV 0x00006000 +#define NV10TCL_RC_IN_ALPHA_C_MAPPING_HALF_BIAS_NORMAL_NV 0x00008000 +#define NV10TCL_RC_IN_ALPHA_C_MAPPING_HALF_BIAS_NEGATE_NV 0x0000a000 +#define NV10TCL_RC_IN_ALPHA_C_MAPPING_SIGNED_IDENTITY_NV 0x0000c000 +#define NV10TCL_RC_IN_ALPHA_C_MAPPING_SIGNED_NEGATE_NV 0x0000e000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_SHIFT 16 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_MASK 0x000f0000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_CONSTANT_COLOR0_NV 0x00010000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_CONSTANT_COLOR1_NV 0x00020000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_FOG 0x00030000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_PRIMARY_COLOR_NV 0x00040000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_SECONDARY_COLOR_NV 0x00050000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_TEXTURE0_ARB 0x00080000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_TEXTURE1_ARB 0x00090000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_SPARE0_NV 0x000c0000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_SPARE1_NV 0x000d0000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x000e0000 +#define NV10TCL_RC_IN_ALPHA_B_INPUT_E_TIMES_F_NV 0x000f0000 +#define NV10TCL_RC_IN_ALPHA_B_COMPONENT_USAGE (1 << 20) +#define NV10TCL_RC_IN_ALPHA_B_COMPONENT_USAGE_BLUE 0x00000000 +#define NV10TCL_RC_IN_ALPHA_B_COMPONENT_USAGE_ALPHA 0x00100000 +#define NV10TCL_RC_IN_ALPHA_B_MAPPING_SHIFT 21 +#define NV10TCL_RC_IN_ALPHA_B_MAPPING_MASK 0x00e00000 +#define NV10TCL_RC_IN_ALPHA_B_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_IN_ALPHA_B_MAPPING_UNSIGNED_INVERT_NV 0x00200000 +#define NV10TCL_RC_IN_ALPHA_B_MAPPING_EXPAND_NORMAL_NV 0x00400000 +#define NV10TCL_RC_IN_ALPHA_B_MAPPING_EXPAND_NEGATE_NV 0x00600000 +#define NV10TCL_RC_IN_ALPHA_B_MAPPING_HALF_BIAS_NORMAL_NV 0x00800000 +#define NV10TCL_RC_IN_ALPHA_B_MAPPING_HALF_BIAS_NEGATE_NV 0x00a00000 +#define NV10TCL_RC_IN_ALPHA_B_MAPPING_SIGNED_IDENTITY_NV 0x00c00000 +#define NV10TCL_RC_IN_ALPHA_B_MAPPING_SIGNED_NEGATE_NV 0x00e00000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_SHIFT 24 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_MASK 0x0f000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_CONSTANT_COLOR0_NV 0x01000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_CONSTANT_COLOR1_NV 0x02000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_FOG 0x03000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_PRIMARY_COLOR_NV 0x04000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_SECONDARY_COLOR_NV 0x05000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_TEXTURE0_ARB 0x08000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_TEXTURE1_ARB 0x09000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_SPARE0_NV 0x0c000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_SPARE1_NV 0x0d000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x0e000000 +#define NV10TCL_RC_IN_ALPHA_A_INPUT_E_TIMES_F_NV 0x0f000000 +#define NV10TCL_RC_IN_ALPHA_A_COMPONENT_USAGE (1 << 28) +#define NV10TCL_RC_IN_ALPHA_A_COMPONENT_USAGE_BLUE 0x00000000 +#define NV10TCL_RC_IN_ALPHA_A_COMPONENT_USAGE_ALPHA 0x10000000 +#define NV10TCL_RC_IN_ALPHA_A_MAPPING_SHIFT 29 +#define NV10TCL_RC_IN_ALPHA_A_MAPPING_MASK 0xe0000000 +#define NV10TCL_RC_IN_ALPHA_A_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_IN_ALPHA_A_MAPPING_UNSIGNED_INVERT_NV 0x20000000 +#define NV10TCL_RC_IN_ALPHA_A_MAPPING_EXPAND_NORMAL_NV 0x40000000 +#define NV10TCL_RC_IN_ALPHA_A_MAPPING_EXPAND_NEGATE_NV 0x60000000 +#define NV10TCL_RC_IN_ALPHA_A_MAPPING_HALF_BIAS_NORMAL_NV 0x80000000 +#define NV10TCL_RC_IN_ALPHA_A_MAPPING_HALF_BIAS_NEGATE_NV 0xa0000000 +#define NV10TCL_RC_IN_ALPHA_A_MAPPING_SIGNED_IDENTITY_NV 0xc0000000 +#define NV10TCL_RC_IN_ALPHA_A_MAPPING_SIGNED_NEGATE_NV 0xe0000000 +#define NV10TCL_RC_IN_RGB(x) (0x00000268+((x)*4)) +#define NV10TCL_RC_IN_RGB__SIZE 0x00000002 +#define NV10TCL_RC_IN_RGB_D_INPUT_SHIFT 0 +#define NV10TCL_RC_IN_RGB_D_INPUT_MASK 0x0000000f +#define NV10TCL_RC_IN_RGB_D_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_IN_RGB_D_INPUT_CONSTANT_COLOR0_NV 0x00000001 +#define NV10TCL_RC_IN_RGB_D_INPUT_CONSTANT_COLOR1_NV 0x00000002 +#define NV10TCL_RC_IN_RGB_D_INPUT_FOG 0x00000003 +#define NV10TCL_RC_IN_RGB_D_INPUT_PRIMARY_COLOR_NV 0x00000004 +#define NV10TCL_RC_IN_RGB_D_INPUT_SECONDARY_COLOR_NV 0x00000005 +#define NV10TCL_RC_IN_RGB_D_INPUT_TEXTURE0_ARB 0x00000008 +#define NV10TCL_RC_IN_RGB_D_INPUT_TEXTURE1_ARB 0x00000009 +#define NV10TCL_RC_IN_RGB_D_INPUT_SPARE0_NV 0x0000000c +#define NV10TCL_RC_IN_RGB_D_INPUT_SPARE1_NV 0x0000000d +#define NV10TCL_RC_IN_RGB_D_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x0000000e +#define NV10TCL_RC_IN_RGB_D_INPUT_E_TIMES_F_NV 0x0000000f +#define NV10TCL_RC_IN_RGB_D_COMPONENT_USAGE (1 << 4) +#define NV10TCL_RC_IN_RGB_D_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_IN_RGB_D_COMPONENT_USAGE_ALPHA 0x00000010 +#define NV10TCL_RC_IN_RGB_D_MAPPING_SHIFT 5 +#define NV10TCL_RC_IN_RGB_D_MAPPING_MASK 0x000000e0 +#define NV10TCL_RC_IN_RGB_D_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_IN_RGB_D_MAPPING_UNSIGNED_INVERT_NV 0x00000020 +#define NV10TCL_RC_IN_RGB_D_MAPPING_EXPAND_NORMAL_NV 0x00000040 +#define NV10TCL_RC_IN_RGB_D_MAPPING_EXPAND_NEGATE_NV 0x00000060 +#define NV10TCL_RC_IN_RGB_D_MAPPING_HALF_BIAS_NORMAL_NV 0x00000080 +#define NV10TCL_RC_IN_RGB_D_MAPPING_HALF_BIAS_NEGATE_NV 0x000000a0 +#define NV10TCL_RC_IN_RGB_D_MAPPING_SIGNED_IDENTITY_NV 0x000000c0 +#define NV10TCL_RC_IN_RGB_D_MAPPING_SIGNED_NEGATE_NV 0x000000e0 +#define NV10TCL_RC_IN_RGB_C_INPUT_SHIFT 8 +#define NV10TCL_RC_IN_RGB_C_INPUT_MASK 0x00000f00 +#define NV10TCL_RC_IN_RGB_C_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_IN_RGB_C_INPUT_CONSTANT_COLOR0_NV 0x00000100 +#define NV10TCL_RC_IN_RGB_C_INPUT_CONSTANT_COLOR1_NV 0x00000200 +#define NV10TCL_RC_IN_RGB_C_INPUT_FOG 0x00000300 +#define NV10TCL_RC_IN_RGB_C_INPUT_PRIMARY_COLOR_NV 0x00000400 +#define NV10TCL_RC_IN_RGB_C_INPUT_SECONDARY_COLOR_NV 0x00000500 +#define NV10TCL_RC_IN_RGB_C_INPUT_TEXTURE0_ARB 0x00000800 +#define NV10TCL_RC_IN_RGB_C_INPUT_TEXTURE1_ARB 0x00000900 +#define NV10TCL_RC_IN_RGB_C_INPUT_SPARE0_NV 0x00000c00 +#define NV10TCL_RC_IN_RGB_C_INPUT_SPARE1_NV 0x00000d00 +#define NV10TCL_RC_IN_RGB_C_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x00000e00 +#define NV10TCL_RC_IN_RGB_C_INPUT_E_TIMES_F_NV 0x00000f00 +#define NV10TCL_RC_IN_RGB_C_COMPONENT_USAGE (1 << 12) +#define NV10TCL_RC_IN_RGB_C_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_IN_RGB_C_COMPONENT_USAGE_ALPHA 0x00001000 +#define NV10TCL_RC_IN_RGB_C_MAPPING_SHIFT 13 +#define NV10TCL_RC_IN_RGB_C_MAPPING_MASK 0x0000e000 +#define NV10TCL_RC_IN_RGB_C_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_IN_RGB_C_MAPPING_UNSIGNED_INVERT_NV 0x00002000 +#define NV10TCL_RC_IN_RGB_C_MAPPING_EXPAND_NORMAL_NV 0x00004000 +#define NV10TCL_RC_IN_RGB_C_MAPPING_EXPAND_NEGATE_NV 0x00006000 +#define NV10TCL_RC_IN_RGB_C_MAPPING_HALF_BIAS_NORMAL_NV 0x00008000 +#define NV10TCL_RC_IN_RGB_C_MAPPING_HALF_BIAS_NEGATE_NV 0x0000a000 +#define NV10TCL_RC_IN_RGB_C_MAPPING_SIGNED_IDENTITY_NV 0x0000c000 +#define NV10TCL_RC_IN_RGB_C_MAPPING_SIGNED_NEGATE_NV 0x0000e000 +#define NV10TCL_RC_IN_RGB_B_INPUT_SHIFT 16 +#define NV10TCL_RC_IN_RGB_B_INPUT_MASK 0x000f0000 +#define NV10TCL_RC_IN_RGB_B_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_IN_RGB_B_INPUT_CONSTANT_COLOR0_NV 0x00010000 +#define NV10TCL_RC_IN_RGB_B_INPUT_CONSTANT_COLOR1_NV 0x00020000 +#define NV10TCL_RC_IN_RGB_B_INPUT_FOG 0x00030000 +#define NV10TCL_RC_IN_RGB_B_INPUT_PRIMARY_COLOR_NV 0x00040000 +#define NV10TCL_RC_IN_RGB_B_INPUT_SECONDARY_COLOR_NV 0x00050000 +#define NV10TCL_RC_IN_RGB_B_INPUT_TEXTURE0_ARB 0x00080000 +#define NV10TCL_RC_IN_RGB_B_INPUT_TEXTURE1_ARB 0x00090000 +#define NV10TCL_RC_IN_RGB_B_INPUT_SPARE0_NV 0x000c0000 +#define NV10TCL_RC_IN_RGB_B_INPUT_SPARE1_NV 0x000d0000 +#define NV10TCL_RC_IN_RGB_B_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x000e0000 +#define NV10TCL_RC_IN_RGB_B_INPUT_E_TIMES_F_NV 0x000f0000 +#define NV10TCL_RC_IN_RGB_B_COMPONENT_USAGE (1 << 20) +#define NV10TCL_RC_IN_RGB_B_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_IN_RGB_B_COMPONENT_USAGE_ALPHA 0x00100000 +#define NV10TCL_RC_IN_RGB_B_MAPPING_SHIFT 21 +#define NV10TCL_RC_IN_RGB_B_MAPPING_MASK 0x00e00000 +#define NV10TCL_RC_IN_RGB_B_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_IN_RGB_B_MAPPING_UNSIGNED_INVERT_NV 0x00200000 +#define NV10TCL_RC_IN_RGB_B_MAPPING_EXPAND_NORMAL_NV 0x00400000 +#define NV10TCL_RC_IN_RGB_B_MAPPING_EXPAND_NEGATE_NV 0x00600000 +#define NV10TCL_RC_IN_RGB_B_MAPPING_HALF_BIAS_NORMAL_NV 0x00800000 +#define NV10TCL_RC_IN_RGB_B_MAPPING_HALF_BIAS_NEGATE_NV 0x00a00000 +#define NV10TCL_RC_IN_RGB_B_MAPPING_SIGNED_IDENTITY_NV 0x00c00000 +#define NV10TCL_RC_IN_RGB_B_MAPPING_SIGNED_NEGATE_NV 0x00e00000 +#define NV10TCL_RC_IN_RGB_A_INPUT_SHIFT 24 +#define NV10TCL_RC_IN_RGB_A_INPUT_MASK 0x0f000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_CONSTANT_COLOR0_NV 0x01000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_CONSTANT_COLOR1_NV 0x02000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_FOG 0x03000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_PRIMARY_COLOR_NV 0x04000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_SECONDARY_COLOR_NV 0x05000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_TEXTURE0_ARB 0x08000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_TEXTURE1_ARB 0x09000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_SPARE0_NV 0x0c000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_SPARE1_NV 0x0d000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x0e000000 +#define NV10TCL_RC_IN_RGB_A_INPUT_E_TIMES_F_NV 0x0f000000 +#define NV10TCL_RC_IN_RGB_A_COMPONENT_USAGE (1 << 28) +#define NV10TCL_RC_IN_RGB_A_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_IN_RGB_A_COMPONENT_USAGE_ALPHA 0x10000000 +#define NV10TCL_RC_IN_RGB_A_MAPPING_SHIFT 29 +#define NV10TCL_RC_IN_RGB_A_MAPPING_MASK 0xe0000000 +#define NV10TCL_RC_IN_RGB_A_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_IN_RGB_A_MAPPING_UNSIGNED_INVERT_NV 0x20000000 +#define NV10TCL_RC_IN_RGB_A_MAPPING_EXPAND_NORMAL_NV 0x40000000 +#define NV10TCL_RC_IN_RGB_A_MAPPING_EXPAND_NEGATE_NV 0x60000000 +#define NV10TCL_RC_IN_RGB_A_MAPPING_HALF_BIAS_NORMAL_NV 0x80000000 +#define NV10TCL_RC_IN_RGB_A_MAPPING_HALF_BIAS_NEGATE_NV 0xa0000000 +#define NV10TCL_RC_IN_RGB_A_MAPPING_SIGNED_IDENTITY_NV 0xc0000000 +#define NV10TCL_RC_IN_RGB_A_MAPPING_SIGNED_NEGATE_NV 0xe0000000 +#define NV10TCL_RC_COLOR(x) (0x00000270+((x)*4)) +#define NV10TCL_RC_COLOR__SIZE 0x00000002 +#define NV10TCL_RC_COLOR_B_SHIFT 0 +#define NV10TCL_RC_COLOR_B_MASK 0x000000ff +#define NV10TCL_RC_COLOR_G_SHIFT 8 +#define NV10TCL_RC_COLOR_G_MASK 0x0000ff00 +#define NV10TCL_RC_COLOR_R_SHIFT 16 +#define NV10TCL_RC_COLOR_R_MASK 0x00ff0000 +#define NV10TCL_RC_COLOR_A_SHIFT 24 +#define NV10TCL_RC_COLOR_A_MASK 0xff000000 +#define NV10TCL_RC_OUT_ALPHA(x) (0x00000278+((x)*4)) +#define NV10TCL_RC_OUT_ALPHA__SIZE 0x00000002 +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_SHIFT 0 +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_MASK 0x0000000f +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_ZERO 0x00000000 +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_CONSTANT_COLOR0_NV 0x00000001 +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_CONSTANT_COLOR1_NV 0x00000002 +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_FOG 0x00000003 +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_PRIMARY_COLOR_NV 0x00000004 +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_SECONDARY_COLOR_NV 0x00000005 +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_TEXTURE0_ARB 0x00000008 +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_TEXTURE1_ARB 0x00000009 +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_SPARE0_NV 0x0000000c +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_SPARE1_NV 0x0000000d +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x0000000e +#define NV10TCL_RC_OUT_ALPHA_CD_OUTPUT_E_TIMES_F_NV 0x0000000f +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_SHIFT 4 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_MASK 0x000000f0 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_ZERO 0x00000000 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_CONSTANT_COLOR0_NV 0x00000010 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_CONSTANT_COLOR1_NV 0x00000020 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_FOG 0x00000030 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_PRIMARY_COLOR_NV 0x00000040 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_SECONDARY_COLOR_NV 0x00000050 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_TEXTURE0_ARB 0x00000080 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_TEXTURE1_ARB 0x00000090 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_SPARE0_NV 0x000000c0 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_SPARE1_NV 0x000000d0 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x000000e0 +#define NV10TCL_RC_OUT_ALPHA_AB_OUTPUT_E_TIMES_F_NV 0x000000f0 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_SHIFT 8 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_MASK 0x00000f00 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_ZERO 0x00000000 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_CONSTANT_COLOR0_NV 0x00000100 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_CONSTANT_COLOR1_NV 0x00000200 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_FOG 0x00000300 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_PRIMARY_COLOR_NV 0x00000400 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_SECONDARY_COLOR_NV 0x00000500 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_TEXTURE0_ARB 0x00000800 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_TEXTURE1_ARB 0x00000900 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_SPARE0_NV 0x00000c00 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_SPARE1_NV 0x00000d00 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x00000e00 +#define NV10TCL_RC_OUT_ALPHA_SUM_OUTPUT_E_TIMES_F_NV 0x00000f00 +#define NV10TCL_RC_OUT_ALPHA_CD_DOT_PRODUCT (1 << 12) +#define NV10TCL_RC_OUT_ALPHA_AB_DOT_PRODUCT (1 << 13) +#define NV10TCL_RC_OUT_ALPHA_MUX_SUM (1 << 14) +#define NV10TCL_RC_OUT_ALPHA_BIAS (1 << 15) +#define NV10TCL_RC_OUT_ALPHA_BIAS_NONE 0x00000000 +#define NV10TCL_RC_OUT_ALPHA_BIAS_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x00008000 +#define NV10TCL_RC_OUT_ALPHA_SCALE_SHIFT 17 +#define NV10TCL_RC_OUT_ALPHA_SCALE_MASK 0x00000000 +#define NV10TCL_RC_OUT_ALPHA_SCALE_NONE 0x00000000 +#define NV10TCL_RC_OUT_ALPHA_SCALE_SCALE_BY_TWO_NV 0x00020000 +#define NV10TCL_RC_OUT_ALPHA_SCALE_SCALE_BY_FOUR_NV 0x00040000 +#define NV10TCL_RC_OUT_ALPHA_SCALE_SCALE_BY_ONE_HALF_NV 0x00060000 +#define NV10TCL_RC_OUT_RGB(x) (0x00000280+((x)*4)) +#define NV10TCL_RC_OUT_RGB__SIZE 0x00000002 +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_SHIFT 0 +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_MASK 0x0000000f +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_ZERO 0x00000000 +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_CONSTANT_COLOR0_NV 0x00000001 +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_CONSTANT_COLOR1_NV 0x00000002 +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_FOG 0x00000003 +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_PRIMARY_COLOR_NV 0x00000004 +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_SECONDARY_COLOR_NV 0x00000005 +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_TEXTURE0_ARB 0x00000008 +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_TEXTURE1_ARB 0x00000009 +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_SPARE0_NV 0x0000000c +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_SPARE1_NV 0x0000000d +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x0000000e +#define NV10TCL_RC_OUT_RGB_CD_OUTPUT_E_TIMES_F_NV 0x0000000f +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_SHIFT 4 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_MASK 0x000000f0 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_ZERO 0x00000000 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_CONSTANT_COLOR0_NV 0x00000010 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_CONSTANT_COLOR1_NV 0x00000020 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_FOG 0x00000030 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_PRIMARY_COLOR_NV 0x00000040 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_SECONDARY_COLOR_NV 0x00000050 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_TEXTURE0_ARB 0x00000080 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_TEXTURE1_ARB 0x00000090 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_SPARE0_NV 0x000000c0 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_SPARE1_NV 0x000000d0 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x000000e0 +#define NV10TCL_RC_OUT_RGB_AB_OUTPUT_E_TIMES_F_NV 0x000000f0 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_SHIFT 8 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_MASK 0x00000f00 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_ZERO 0x00000000 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_CONSTANT_COLOR0_NV 0x00000100 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_CONSTANT_COLOR1_NV 0x00000200 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_FOG 0x00000300 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_PRIMARY_COLOR_NV 0x00000400 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_SECONDARY_COLOR_NV 0x00000500 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_TEXTURE0_ARB 0x00000800 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_TEXTURE1_ARB 0x00000900 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_SPARE0_NV 0x00000c00 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_SPARE1_NV 0x00000d00 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x00000e00 +#define NV10TCL_RC_OUT_RGB_SUM_OUTPUT_E_TIMES_F_NV 0x00000f00 +#define NV10TCL_RC_OUT_RGB_CD_DOT_PRODUCT (1 << 12) +#define NV10TCL_RC_OUT_RGB_AB_DOT_PRODUCT (1 << 13) +#define NV10TCL_RC_OUT_RGB_MUX_SUM (1 << 14) +#define NV10TCL_RC_OUT_RGB_BIAS (1 << 15) +#define NV10TCL_RC_OUT_RGB_BIAS_NONE 0x00000000 +#define NV10TCL_RC_OUT_RGB_BIAS_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x00008000 +#define NV10TCL_RC_OUT_RGB_SCALE_SHIFT 17 +#define NV10TCL_RC_OUT_RGB_SCALE_MASK 0x00000000 +#define NV10TCL_RC_OUT_RGB_SCALE_NONE 0x00000000 +#define NV10TCL_RC_OUT_RGB_SCALE_SCALE_BY_TWO_NV 0x00020000 +#define NV10TCL_RC_OUT_RGB_SCALE_SCALE_BY_FOUR_NV 0x00040000 +#define NV10TCL_RC_OUT_RGB_SCALE_SCALE_BY_ONE_HALF_NV 0x00060000 +#define NV10TCL_RC_OUT_RGB_OPERATION_SHIFT 27 +#define NV10TCL_RC_OUT_RGB_OPERATION_MASK 0x38000000 +#define NV10TCL_RC_FINAL0 0x00000288 +#define NV10TCL_RC_FINAL0_D_INPUT_SHIFT 0 +#define NV10TCL_RC_FINAL0_D_INPUT_MASK 0x0000000f +#define NV10TCL_RC_FINAL0_D_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_FINAL0_D_INPUT_CONSTANT_COLOR0_NV 0x00000001 +#define NV10TCL_RC_FINAL0_D_INPUT_CONSTANT_COLOR1_NV 0x00000002 +#define NV10TCL_RC_FINAL0_D_INPUT_FOG 0x00000003 +#define NV10TCL_RC_FINAL0_D_INPUT_PRIMARY_COLOR_NV 0x00000004 +#define NV10TCL_RC_FINAL0_D_INPUT_SECONDARY_COLOR_NV 0x00000005 +#define NV10TCL_RC_FINAL0_D_INPUT_TEXTURE0_ARB 0x00000008 +#define NV10TCL_RC_FINAL0_D_INPUT_TEXTURE1_ARB 0x00000009 +#define NV10TCL_RC_FINAL0_D_INPUT_SPARE0_NV 0x0000000c +#define NV10TCL_RC_FINAL0_D_INPUT_SPARE1_NV 0x0000000d +#define NV10TCL_RC_FINAL0_D_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x0000000e +#define NV10TCL_RC_FINAL0_D_INPUT_E_TIMES_F_NV 0x0000000f +#define NV10TCL_RC_FINAL0_D_COMPONENT_USAGE (1 << 4) +#define NV10TCL_RC_FINAL0_D_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_FINAL0_D_COMPONENT_USAGE_ALPHA 0x00000010 +#define NV10TCL_RC_FINAL0_D_MAPPING_SHIFT 5 +#define NV10TCL_RC_FINAL0_D_MAPPING_MASK 0x000000e0 +#define NV10TCL_RC_FINAL0_D_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_FINAL0_D_MAPPING_UNSIGNED_INVERT_NV 0x00000020 +#define NV10TCL_RC_FINAL0_D_MAPPING_EXPAND_NORMAL_NV 0x00000040 +#define NV10TCL_RC_FINAL0_D_MAPPING_EXPAND_NEGATE_NV 0x00000060 +#define NV10TCL_RC_FINAL0_D_MAPPING_HALF_BIAS_NORMAL_NV 0x00000080 +#define NV10TCL_RC_FINAL0_D_MAPPING_HALF_BIAS_NEGATE_NV 0x000000a0 +#define NV10TCL_RC_FINAL0_D_MAPPING_SIGNED_IDENTITY_NV 0x000000c0 +#define NV10TCL_RC_FINAL0_D_MAPPING_SIGNED_NEGATE_NV 0x000000e0 +#define NV10TCL_RC_FINAL0_C_INPUT_SHIFT 8 +#define NV10TCL_RC_FINAL0_C_INPUT_MASK 0x00000f00 +#define NV10TCL_RC_FINAL0_C_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_FINAL0_C_INPUT_CONSTANT_COLOR0_NV 0x00000100 +#define NV10TCL_RC_FINAL0_C_INPUT_CONSTANT_COLOR1_NV 0x00000200 +#define NV10TCL_RC_FINAL0_C_INPUT_FOG 0x00000300 +#define NV10TCL_RC_FINAL0_C_INPUT_PRIMARY_COLOR_NV 0x00000400 +#define NV10TCL_RC_FINAL0_C_INPUT_SECONDARY_COLOR_NV 0x00000500 +#define NV10TCL_RC_FINAL0_C_INPUT_TEXTURE0_ARB 0x00000800 +#define NV10TCL_RC_FINAL0_C_INPUT_TEXTURE1_ARB 0x00000900 +#define NV10TCL_RC_FINAL0_C_INPUT_SPARE0_NV 0x00000c00 +#define NV10TCL_RC_FINAL0_C_INPUT_SPARE1_NV 0x00000d00 +#define NV10TCL_RC_FINAL0_C_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x00000e00 +#define NV10TCL_RC_FINAL0_C_INPUT_E_TIMES_F_NV 0x00000f00 +#define NV10TCL_RC_FINAL0_C_COMPONENT_USAGE (1 << 12) +#define NV10TCL_RC_FINAL0_C_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_FINAL0_C_COMPONENT_USAGE_ALPHA 0x00001000 +#define NV10TCL_RC_FINAL0_C_MAPPING_SHIFT 13 +#define NV10TCL_RC_FINAL0_C_MAPPING_MASK 0x0000e000 +#define NV10TCL_RC_FINAL0_C_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_FINAL0_C_MAPPING_UNSIGNED_INVERT_NV 0x00002000 +#define NV10TCL_RC_FINAL0_C_MAPPING_EXPAND_NORMAL_NV 0x00004000 +#define NV10TCL_RC_FINAL0_C_MAPPING_EXPAND_NEGATE_NV 0x00006000 +#define NV10TCL_RC_FINAL0_C_MAPPING_HALF_BIAS_NORMAL_NV 0x00008000 +#define NV10TCL_RC_FINAL0_C_MAPPING_HALF_BIAS_NEGATE_NV 0x0000a000 +#define NV10TCL_RC_FINAL0_C_MAPPING_SIGNED_IDENTITY_NV 0x0000c000 +#define NV10TCL_RC_FINAL0_C_MAPPING_SIGNED_NEGATE_NV 0x0000e000 +#define NV10TCL_RC_FINAL0_B_INPUT_SHIFT 16 +#define NV10TCL_RC_FINAL0_B_INPUT_MASK 0x000f0000 +#define NV10TCL_RC_FINAL0_B_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_FINAL0_B_INPUT_CONSTANT_COLOR0_NV 0x00010000 +#define NV10TCL_RC_FINAL0_B_INPUT_CONSTANT_COLOR1_NV 0x00020000 +#define NV10TCL_RC_FINAL0_B_INPUT_FOG 0x00030000 +#define NV10TCL_RC_FINAL0_B_INPUT_PRIMARY_COLOR_NV 0x00040000 +#define NV10TCL_RC_FINAL0_B_INPUT_SECONDARY_COLOR_NV 0x00050000 +#define NV10TCL_RC_FINAL0_B_INPUT_TEXTURE0_ARB 0x00080000 +#define NV10TCL_RC_FINAL0_B_INPUT_TEXTURE1_ARB 0x00090000 +#define NV10TCL_RC_FINAL0_B_INPUT_SPARE0_NV 0x000c0000 +#define NV10TCL_RC_FINAL0_B_INPUT_SPARE1_NV 0x000d0000 +#define NV10TCL_RC_FINAL0_B_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x000e0000 +#define NV10TCL_RC_FINAL0_B_INPUT_E_TIMES_F_NV 0x000f0000 +#define NV10TCL_RC_FINAL0_B_COMPONENT_USAGE (1 << 20) +#define NV10TCL_RC_FINAL0_B_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_FINAL0_B_COMPONENT_USAGE_ALPHA 0x00100000 +#define NV10TCL_RC_FINAL0_B_MAPPING_SHIFT 21 +#define NV10TCL_RC_FINAL0_B_MAPPING_MASK 0x00e00000 +#define NV10TCL_RC_FINAL0_B_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_FINAL0_B_MAPPING_UNSIGNED_INVERT_NV 0x00200000 +#define NV10TCL_RC_FINAL0_B_MAPPING_EXPAND_NORMAL_NV 0x00400000 +#define NV10TCL_RC_FINAL0_B_MAPPING_EXPAND_NEGATE_NV 0x00600000 +#define NV10TCL_RC_FINAL0_B_MAPPING_HALF_BIAS_NORMAL_NV 0x00800000 +#define NV10TCL_RC_FINAL0_B_MAPPING_HALF_BIAS_NEGATE_NV 0x00a00000 +#define NV10TCL_RC_FINAL0_B_MAPPING_SIGNED_IDENTITY_NV 0x00c00000 +#define NV10TCL_RC_FINAL0_B_MAPPING_SIGNED_NEGATE_NV 0x00e00000 +#define NV10TCL_RC_FINAL0_A_INPUT_SHIFT 24 +#define NV10TCL_RC_FINAL0_A_INPUT_MASK 0x0f000000 +#define NV10TCL_RC_FINAL0_A_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_FINAL0_A_INPUT_CONSTANT_COLOR0_NV 0x01000000 +#define NV10TCL_RC_FINAL0_A_INPUT_CONSTANT_COLOR1_NV 0x02000000 +#define NV10TCL_RC_FINAL0_A_INPUT_FOG 0x03000000 +#define NV10TCL_RC_FINAL0_A_INPUT_PRIMARY_COLOR_NV 0x04000000 +#define NV10TCL_RC_FINAL0_A_INPUT_SECONDARY_COLOR_NV 0x05000000 +#define NV10TCL_RC_FINAL0_A_INPUT_TEXTURE0_ARB 0x08000000 +#define NV10TCL_RC_FINAL0_A_INPUT_TEXTURE1_ARB 0x09000000 +#define NV10TCL_RC_FINAL0_A_INPUT_SPARE0_NV 0x0c000000 +#define NV10TCL_RC_FINAL0_A_INPUT_SPARE1_NV 0x0d000000 +#define NV10TCL_RC_FINAL0_A_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x0e000000 +#define NV10TCL_RC_FINAL0_A_INPUT_E_TIMES_F_NV 0x0f000000 +#define NV10TCL_RC_FINAL0_A_COMPONENT_USAGE (1 << 28) +#define NV10TCL_RC_FINAL0_A_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_FINAL0_A_COMPONENT_USAGE_ALPHA 0x10000000 +#define NV10TCL_RC_FINAL0_A_MAPPING_SHIFT 29 +#define NV10TCL_RC_FINAL0_A_MAPPING_MASK 0xe0000000 +#define NV10TCL_RC_FINAL0_A_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_FINAL0_A_MAPPING_UNSIGNED_INVERT_NV 0x20000000 +#define NV10TCL_RC_FINAL0_A_MAPPING_EXPAND_NORMAL_NV 0x40000000 +#define NV10TCL_RC_FINAL0_A_MAPPING_EXPAND_NEGATE_NV 0x60000000 +#define NV10TCL_RC_FINAL0_A_MAPPING_HALF_BIAS_NORMAL_NV 0x80000000 +#define NV10TCL_RC_FINAL0_A_MAPPING_HALF_BIAS_NEGATE_NV 0xa0000000 +#define NV10TCL_RC_FINAL0_A_MAPPING_SIGNED_IDENTITY_NV 0xc0000000 +#define NV10TCL_RC_FINAL0_A_MAPPING_SIGNED_NEGATE_NV 0xe0000000 +#define NV10TCL_RC_FINAL1 0x0000028c +#define NV10TCL_RC_FINAL1_COLOR_SUM_CLAMP (1 << 7) +#define NV10TCL_RC_FINAL1_G_INPUT_SHIFT 8 +#define NV10TCL_RC_FINAL1_G_INPUT_MASK 0x00000f00 +#define NV10TCL_RC_FINAL1_G_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_FINAL1_G_INPUT_CONSTANT_COLOR0_NV 0x00000100 +#define NV10TCL_RC_FINAL1_G_INPUT_CONSTANT_COLOR1_NV 0x00000200 +#define NV10TCL_RC_FINAL1_G_INPUT_FOG 0x00000300 +#define NV10TCL_RC_FINAL1_G_INPUT_PRIMARY_COLOR_NV 0x00000400 +#define NV10TCL_RC_FINAL1_G_INPUT_SECONDARY_COLOR_NV 0x00000500 +#define NV10TCL_RC_FINAL1_G_INPUT_TEXTURE0_ARB 0x00000800 +#define NV10TCL_RC_FINAL1_G_INPUT_TEXTURE1_ARB 0x00000900 +#define NV10TCL_RC_FINAL1_G_INPUT_SPARE0_NV 0x00000c00 +#define NV10TCL_RC_FINAL1_G_INPUT_SPARE1_NV 0x00000d00 +#define NV10TCL_RC_FINAL1_G_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x00000e00 +#define NV10TCL_RC_FINAL1_G_INPUT_E_TIMES_F_NV 0x00000f00 +#define NV10TCL_RC_FINAL1_G_COMPONENT_USAGE (1 << 12) +#define NV10TCL_RC_FINAL1_G_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_FINAL1_G_COMPONENT_USAGE_ALPHA 0x00001000 +#define NV10TCL_RC_FINAL1_G_MAPPING_SHIFT 13 +#define NV10TCL_RC_FINAL1_G_MAPPING_MASK 0x0000e000 +#define NV10TCL_RC_FINAL1_G_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_FINAL1_G_MAPPING_UNSIGNED_INVERT_NV 0x00002000 +#define NV10TCL_RC_FINAL1_G_MAPPING_EXPAND_NORMAL_NV 0x00004000 +#define NV10TCL_RC_FINAL1_G_MAPPING_EXPAND_NEGATE_NV 0x00006000 +#define NV10TCL_RC_FINAL1_G_MAPPING_HALF_BIAS_NORMAL_NV 0x00008000 +#define NV10TCL_RC_FINAL1_G_MAPPING_HALF_BIAS_NEGATE_NV 0x0000a000 +#define NV10TCL_RC_FINAL1_G_MAPPING_SIGNED_IDENTITY_NV 0x0000c000 +#define NV10TCL_RC_FINAL1_G_MAPPING_SIGNED_NEGATE_NV 0x0000e000 +#define NV10TCL_RC_FINAL1_F_INPUT_SHIFT 16 +#define NV10TCL_RC_FINAL1_F_INPUT_MASK 0x000f0000 +#define NV10TCL_RC_FINAL1_F_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_FINAL1_F_INPUT_CONSTANT_COLOR0_NV 0x00010000 +#define NV10TCL_RC_FINAL1_F_INPUT_CONSTANT_COLOR1_NV 0x00020000 +#define NV10TCL_RC_FINAL1_F_INPUT_FOG 0x00030000 +#define NV10TCL_RC_FINAL1_F_INPUT_PRIMARY_COLOR_NV 0x00040000 +#define NV10TCL_RC_FINAL1_F_INPUT_SECONDARY_COLOR_NV 0x00050000 +#define NV10TCL_RC_FINAL1_F_INPUT_TEXTURE0_ARB 0x00080000 +#define NV10TCL_RC_FINAL1_F_INPUT_TEXTURE1_ARB 0x00090000 +#define NV10TCL_RC_FINAL1_F_INPUT_SPARE0_NV 0x000c0000 +#define NV10TCL_RC_FINAL1_F_INPUT_SPARE1_NV 0x000d0000 +#define NV10TCL_RC_FINAL1_F_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x000e0000 +#define NV10TCL_RC_FINAL1_F_INPUT_E_TIMES_F_NV 0x000f0000 +#define NV10TCL_RC_FINAL1_F_COMPONENT_USAGE (1 << 20) +#define NV10TCL_RC_FINAL1_F_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_FINAL1_F_COMPONENT_USAGE_ALPHA 0x00100000 +#define NV10TCL_RC_FINAL1_F_MAPPING_SHIFT 21 +#define NV10TCL_RC_FINAL1_F_MAPPING_MASK 0x00e00000 +#define NV10TCL_RC_FINAL1_F_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_FINAL1_F_MAPPING_UNSIGNED_INVERT_NV 0x00200000 +#define NV10TCL_RC_FINAL1_F_MAPPING_EXPAND_NORMAL_NV 0x00400000 +#define NV10TCL_RC_FINAL1_F_MAPPING_EXPAND_NEGATE_NV 0x00600000 +#define NV10TCL_RC_FINAL1_F_MAPPING_HALF_BIAS_NORMAL_NV 0x00800000 +#define NV10TCL_RC_FINAL1_F_MAPPING_HALF_BIAS_NEGATE_NV 0x00a00000 +#define NV10TCL_RC_FINAL1_F_MAPPING_SIGNED_IDENTITY_NV 0x00c00000 +#define NV10TCL_RC_FINAL1_F_MAPPING_SIGNED_NEGATE_NV 0x00e00000 +#define NV10TCL_RC_FINAL1_E_INPUT_SHIFT 24 +#define NV10TCL_RC_FINAL1_E_INPUT_MASK 0x0f000000 +#define NV10TCL_RC_FINAL1_E_INPUT_ZERO 0x00000000 +#define NV10TCL_RC_FINAL1_E_INPUT_CONSTANT_COLOR0_NV 0x01000000 +#define NV10TCL_RC_FINAL1_E_INPUT_CONSTANT_COLOR1_NV 0x02000000 +#define NV10TCL_RC_FINAL1_E_INPUT_FOG 0x03000000 +#define NV10TCL_RC_FINAL1_E_INPUT_PRIMARY_COLOR_NV 0x04000000 +#define NV10TCL_RC_FINAL1_E_INPUT_SECONDARY_COLOR_NV 0x05000000 +#define NV10TCL_RC_FINAL1_E_INPUT_TEXTURE0_ARB 0x08000000 +#define NV10TCL_RC_FINAL1_E_INPUT_TEXTURE1_ARB 0x09000000 +#define NV10TCL_RC_FINAL1_E_INPUT_SPARE0_NV 0x0c000000 +#define NV10TCL_RC_FINAL1_E_INPUT_SPARE1_NV 0x0d000000 +#define NV10TCL_RC_FINAL1_E_INPUT_SPARE0_PLUS_SECONDARY_COLOR_NV 0x0e000000 +#define NV10TCL_RC_FINAL1_E_INPUT_E_TIMES_F_NV 0x0f000000 +#define NV10TCL_RC_FINAL1_E_COMPONENT_USAGE (1 << 28) +#define NV10TCL_RC_FINAL1_E_COMPONENT_USAGE_RGB 0x00000000 +#define NV10TCL_RC_FINAL1_E_COMPONENT_USAGE_ALPHA 0x10000000 +#define NV10TCL_RC_FINAL1_E_MAPPING_SHIFT 29 +#define NV10TCL_RC_FINAL1_E_MAPPING_MASK 0xe0000000 +#define NV10TCL_RC_FINAL1_E_MAPPING_UNSIGNED_IDENTITY_NV 0x00000000 +#define NV10TCL_RC_FINAL1_E_MAPPING_UNSIGNED_INVERT_NV 0x20000000 +#define NV10TCL_RC_FINAL1_E_MAPPING_EXPAND_NORMAL_NV 0x40000000 +#define NV10TCL_RC_FINAL1_E_MAPPING_EXPAND_NEGATE_NV 0x60000000 +#define NV10TCL_RC_FINAL1_E_MAPPING_HALF_BIAS_NORMAL_NV 0x80000000 +#define NV10TCL_RC_FINAL1_E_MAPPING_HALF_BIAS_NEGATE_NV 0xa0000000 +#define NV10TCL_RC_FINAL1_E_MAPPING_SIGNED_IDENTITY_NV 0xc0000000 +#define NV10TCL_RC_FINAL1_E_MAPPING_SIGNED_NEGATE_NV 0xe0000000 +#define NV10TCL_LIGHT_MODEL 0x00000294 +#define NV10TCL_LIGHT_MODEL_COLOR_CONTROL (1 << 1) +#define NV10TCL_LIGHT_MODEL_LOCAL_VIEWER (1 << 16) +#define NV10TCL_COLOR_MATERIAL_ENABLE 0x00000298 +#define NV10TCL_COLOR_MATERIAL_ENABLE_SPECULAR (1 << 0) +#define NV10TCL_COLOR_MATERIAL_ENABLE_DIFFUSE (1 << 1) +#define NV10TCL_COLOR_MATERIAL_ENABLE_AMBIENT (1 << 2) +#define NV10TCL_COLOR_MATERIAL_ENABLE_EMISSION (1 << 3) +#define NV10TCL_FOG_MODE 0x0000029c +#define NV10TCL_FOG_MODE_EXP 0x00000800 +#define NV10TCL_FOG_MODE_EXP_2 0x00000802 +#define NV10TCL_FOG_MODE_EXP2 0x00000803 +#define NV10TCL_FOG_MODE_LINEAR 0x00000804 +#define NV10TCL_FOG_MODE_LINEAR_2 0x00002601 +#define NV10TCL_FOG_COORD_DIST 0x000002a0 +#define NV10TCL_FOG_ENABLE 0x000002a4 +#define NV10TCL_FOG_COLOR 0x000002a8 +#define NV10TCL_FOG_COLOR_R_SHIFT 0 +#define NV10TCL_FOG_COLOR_R_MASK 0x000000ff +#define NV10TCL_FOG_COLOR_G_SHIFT 8 +#define NV10TCL_FOG_COLOR_G_MASK 0x0000ff00 +#define NV10TCL_FOG_COLOR_B_SHIFT 16 +#define NV10TCL_FOG_COLOR_B_MASK 0x00ff0000 +#define NV10TCL_FOG_COLOR_A_SHIFT 24 +#define NV10TCL_FOG_COLOR_A_MASK 0xff000000 +#define NV10TCL_VIEWPORT_CLIP_MODE 0x000002b4 +#define NV10TCL_VIEWPORT_CLIP_HORIZ(x) (0x000002c0+((x)*4)) +#define NV10TCL_VIEWPORT_CLIP_HORIZ__SIZE 0x00000008 +#define NV10TCL_VIEWPORT_CLIP_HORIZ_CLIP_L_SHIFT 0 +#define NV10TCL_VIEWPORT_CLIP_HORIZ_CLIP_L_MASK 0x000007ff +#define NV10TCL_VIEWPORT_CLIP_HORIZ_CLIP_LEFT_ENABLE (1 << 11) +#define NV10TCL_VIEWPORT_CLIP_HORIZ_CLIP_R_SHIFT 16 +#define NV10TCL_VIEWPORT_CLIP_HORIZ_CLIP_R_MASK 0x07ff0000 +#define NV10TCL_VIEWPORT_CLIP_HORIZ_CLIP_RIGHT_ENABLE (1 << 27) +#define NV10TCL_VIEWPORT_CLIP_VERT(x) (0x000002e0+((x)*4)) +#define NV10TCL_VIEWPORT_CLIP_VERT__SIZE 0x00000008 +#define NV10TCL_VIEWPORT_CLIP_VERT_CLIP_T_SHIFT 0 +#define NV10TCL_VIEWPORT_CLIP_VERT_CLIP_T_MASK 0x000007ff +#define NV10TCL_VIEWPORT_CLIP_VERT_CLIP_TOP_ENABLE (1 << 11) +#define NV10TCL_VIEWPORT_CLIP_VERT_CLIP_B_SHIFT 16 +#define NV10TCL_VIEWPORT_CLIP_VERT_CLIP_B_MASK 0x07ff0000 +#define NV10TCL_VIEWPORT_CLIP_VERT_CLIP_BOTTOM_ENABLE (1 << 27) +#define NV10TCL_ALPHA_FUNC_ENABLE 0x00000300 +#define NV10TCL_BLEND_FUNC_ENABLE 0x00000304 +#define NV10TCL_CULL_FACE_ENABLE 0x00000308 +#define NV10TCL_DEPTH_TEST_ENABLE 0x0000030c +#define NV10TCL_DITHER_ENABLE 0x00000310 +#define NV10TCL_LIGHTING_ENABLE 0x00000314 +#define NV10TCL_POINT_PARAMETERS_ENABLE 0x00000318 +#define NV10TCL_POINT_SMOOTH_ENABLE 0x0000031c +#define NV10TCL_LINE_SMOOTH_ENABLE 0x00000320 +#define NV10TCL_POLYGON_SMOOTH_ENABLE 0x00000324 +#define NV10TCL_VERTEX_WEIGHT_ENABLE 0x00000328 +#define NV10TCL_STENCIL_ENABLE 0x0000032c +#define NV10TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000330 +#define NV10TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000334 +#define NV10TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000338 +#define NV10TCL_ALPHA_FUNC_FUNC 0x0000033c +#define NV10TCL_ALPHA_FUNC_FUNC_NEVER 0x00000200 +#define NV10TCL_ALPHA_FUNC_FUNC_LESS 0x00000201 +#define NV10TCL_ALPHA_FUNC_FUNC_EQUAL 0x00000202 +#define NV10TCL_ALPHA_FUNC_FUNC_LEQUAL 0x00000203 +#define NV10TCL_ALPHA_FUNC_FUNC_GREATER 0x00000204 +#define NV10TCL_ALPHA_FUNC_FUNC_GREATER 0x00000204 +#define NV10TCL_ALPHA_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV10TCL_ALPHA_FUNC_FUNC_GEQUAL 0x00000206 +#define NV10TCL_ALPHA_FUNC_FUNC_ALWAYS 0x00000207 +#define NV10TCL_ALPHA_FUNC_REF 0x00000340 +#define NV10TCL_BLEND_FUNC_SRC 0x00000344 +#define NV10TCL_BLEND_FUNC_SRC_ZERO 0x00000000 +#define NV10TCL_BLEND_FUNC_SRC_ONE 0x00000001 +#define NV10TCL_BLEND_FUNC_SRC_SRC_COLOR 0x00000300 +#define NV10TCL_BLEND_FUNC_SRC_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV10TCL_BLEND_FUNC_SRC_SRC_ALPHA 0x00000302 +#define NV10TCL_BLEND_FUNC_SRC_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV10TCL_BLEND_FUNC_SRC_DST_ALPHA 0x00000304 +#define NV10TCL_BLEND_FUNC_SRC_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV10TCL_BLEND_FUNC_SRC_DST_COLOR 0x00000306 +#define NV10TCL_BLEND_FUNC_SRC_ONE_MINUS_DST_COLOR 0x00000307 +#define NV10TCL_BLEND_FUNC_SRC_SRC_ALPHA_SATURATE 0x00000308 +#define NV10TCL_BLEND_FUNC_SRC_CONSTANT_COLOR 0x00008001 +#define NV10TCL_BLEND_FUNC_SRC_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV10TCL_BLEND_FUNC_SRC_CONSTANT_ALPHA 0x00008003 +#define NV10TCL_BLEND_FUNC_SRC_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV10TCL_BLEND_FUNC_DST 0x00000348 +#define NV10TCL_BLEND_FUNC_DST_ZERO 0x00000000 +#define NV10TCL_BLEND_FUNC_DST_ONE 0x00000001 +#define NV10TCL_BLEND_FUNC_DST_SRC_COLOR 0x00000300 +#define NV10TCL_BLEND_FUNC_DST_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV10TCL_BLEND_FUNC_DST_SRC_ALPHA 0x00000302 +#define NV10TCL_BLEND_FUNC_DST_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV10TCL_BLEND_FUNC_DST_DST_ALPHA 0x00000304 +#define NV10TCL_BLEND_FUNC_DST_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV10TCL_BLEND_FUNC_DST_DST_COLOR 0x00000306 +#define NV10TCL_BLEND_FUNC_DST_ONE_MINUS_DST_COLOR 0x00000307 +#define NV10TCL_BLEND_FUNC_DST_SRC_ALPHA_SATURATE 0x00000308 +#define NV10TCL_BLEND_FUNC_DST_CONSTANT_COLOR 0x00008001 +#define NV10TCL_BLEND_FUNC_DST_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV10TCL_BLEND_FUNC_DST_CONSTANT_ALPHA 0x00008003 +#define NV10TCL_BLEND_FUNC_DST_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV10TCL_BLEND_COLOR 0x0000034c +#define NV10TCL_BLEND_COLOR_B_SHIFT 0 +#define NV10TCL_BLEND_COLOR_B_MASK 0x000000ff +#define NV10TCL_BLEND_COLOR_G_SHIFT 8 +#define NV10TCL_BLEND_COLOR_G_MASK 0x0000ff00 +#define NV10TCL_BLEND_COLOR_R_SHIFT 16 +#define NV10TCL_BLEND_COLOR_R_MASK 0x00ff0000 +#define NV10TCL_BLEND_COLOR_A_SHIFT 24 +#define NV10TCL_BLEND_COLOR_A_MASK 0xff000000 +#define NV10TCL_BLEND_EQUATION 0x00000350 +#define NV10TCL_BLEND_EQUATION_FUNC_ADD 0x00008006 +#define NV10TCL_BLEND_EQUATION_MIN 0x00008007 +#define NV10TCL_BLEND_EQUATION_MAX 0x00008008 +#define NV10TCL_BLEND_EQUATION_FUNC_SUBTRACT 0x0000800a +#define NV10TCL_BLEND_EQUATION_FUNC_REVERSE_SUBTRACT 0x0000800b +#define NV10TCL_DEPTH_FUNC 0x00000354 +#define NV10TCL_DEPTH_FUNC_NEVER 0x00000200 +#define NV10TCL_DEPTH_FUNC_LESS 0x00000201 +#define NV10TCL_DEPTH_FUNC_EQUAL 0x00000202 +#define NV10TCL_DEPTH_FUNC_LEQUAL 0x00000203 +#define NV10TCL_DEPTH_FUNC_GREATER 0x00000204 +#define NV10TCL_DEPTH_FUNC_GREATER 0x00000204 +#define NV10TCL_DEPTH_FUNC_NOTEQUAL 0x00000205 +#define NV10TCL_DEPTH_FUNC_GEQUAL 0x00000206 +#define NV10TCL_DEPTH_FUNC_ALWAYS 0x00000207 +#define NV10TCL_COLOR_MASK 0x00000358 +#define NV10TCL_COLOR_MASK_B (1 << 0) +#define NV10TCL_COLOR_MASK_G (1 << 8) +#define NV10TCL_COLOR_MASK_R (1 << 16) +#define NV10TCL_COLOR_MASK_A (1 << 24) +#define NV10TCL_DEPTH_WRITE_ENABLE 0x0000035c +#define NV10TCL_STENCIL_MASK 0x00000360 +#define NV10TCL_STENCIL_FUNC_FUNC 0x00000364 +#define NV10TCL_STENCIL_FUNC_FUNC_NEVER 0x00000200 +#define NV10TCL_STENCIL_FUNC_FUNC_LESS 0x00000201 +#define NV10TCL_STENCIL_FUNC_FUNC_EQUAL 0x00000202 +#define NV10TCL_STENCIL_FUNC_FUNC_LEQUAL 0x00000203 +#define NV10TCL_STENCIL_FUNC_FUNC_GREATER 0x00000204 +#define NV10TCL_STENCIL_FUNC_FUNC_GREATER 0x00000204 +#define NV10TCL_STENCIL_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV10TCL_STENCIL_FUNC_FUNC_GEQUAL 0x00000206 +#define NV10TCL_STENCIL_FUNC_FUNC_ALWAYS 0x00000207 +#define NV10TCL_STENCIL_FUNC_REF 0x00000368 +#define NV10TCL_STENCIL_FUNC_MASK 0x0000036c +#define NV10TCL_STENCIL_OP_FAIL 0x00000370 +#define NV10TCL_STENCIL_OP_FAIL_ZERO 0x00000000 +#define NV10TCL_STENCIL_OP_FAIL_INVERT 0x0000150a +#define NV10TCL_STENCIL_OP_FAIL_KEEP 0x00001e00 +#define NV10TCL_STENCIL_OP_FAIL_REPLACE 0x00001e01 +#define NV10TCL_STENCIL_OP_FAIL_INCR 0x00001e02 +#define NV10TCL_STENCIL_OP_FAIL_DECR 0x00001e03 +#define NV10TCL_STENCIL_OP_FAIL_INCR_WRAP 0x00008507 +#define NV10TCL_STENCIL_OP_FAIL_DECR_WRAP 0x00008508 +#define NV10TCL_STENCIL_OP_ZFAIL 0x00000374 +#define NV10TCL_STENCIL_OP_ZFAIL_ZERO 0x00000000 +#define NV10TCL_STENCIL_OP_ZFAIL_INVERT 0x0000150a +#define NV10TCL_STENCIL_OP_ZFAIL_KEEP 0x00001e00 +#define NV10TCL_STENCIL_OP_ZFAIL_REPLACE 0x00001e01 +#define NV10TCL_STENCIL_OP_ZFAIL_INCR 0x00001e02 +#define NV10TCL_STENCIL_OP_ZFAIL_DECR 0x00001e03 +#define NV10TCL_STENCIL_OP_ZFAIL_INCR_WRAP 0x00008507 +#define NV10TCL_STENCIL_OP_ZFAIL_DECR_WRAP 0x00008508 +#define NV10TCL_STENCIL_OP_ZPASS 0x00000378 +#define NV10TCL_STENCIL_OP_ZPASS_ZERO 0x00000000 +#define NV10TCL_STENCIL_OP_ZPASS_INVERT 0x0000150a +#define NV10TCL_STENCIL_OP_ZPASS_KEEP 0x00001e00 +#define NV10TCL_STENCIL_OP_ZPASS_REPLACE 0x00001e01 +#define NV10TCL_STENCIL_OP_ZPASS_INCR 0x00001e02 +#define NV10TCL_STENCIL_OP_ZPASS_DECR 0x00001e03 +#define NV10TCL_STENCIL_OP_ZPASS_INCR_WRAP 0x00008507 +#define NV10TCL_STENCIL_OP_ZPASS_DECR_WRAP 0x00008508 +#define NV10TCL_SHADE_MODEL 0x0000037c +#define NV10TCL_SHADE_MODEL_FLAT 0x00001d00 +#define NV10TCL_SHADE_MODEL_SMOOTH 0x00001d01 +#define NV10TCL_LINE_WIDTH 0x00000380 +#define NV10TCL_POLYGON_OFFSET_FACTOR 0x00000384 +#define NV10TCL_POLYGON_OFFSET_UNITS 0x00000388 +#define NV10TCL_POLYGON_MODE_FRONT 0x0000038c +#define NV10TCL_POLYGON_MODE_FRONT_POINT 0x00001b00 +#define NV10TCL_POLYGON_MODE_FRONT_LINE 0x00001b01 +#define NV10TCL_POLYGON_MODE_FRONT_FILL 0x00001b02 +#define NV10TCL_POLYGON_MODE_BACK 0x00000390 +#define NV10TCL_POLYGON_MODE_BACK_POINT 0x00001b00 +#define NV10TCL_POLYGON_MODE_BACK_LINE 0x00001b01 +#define NV10TCL_POLYGON_MODE_BACK_FILL 0x00001b02 +#define NV10TCL_DEPTH_RANGE_NEAR 0x00000394 +#define NV10TCL_DEPTH_RANGE_FAR 0x00000398 +#define NV10TCL_CULL_FACE 0x0000039c +#define NV10TCL_CULL_FACE_FRONT 0x00000404 +#define NV10TCL_CULL_FACE_BACK 0x00000405 +#define NV10TCL_CULL_FACE_FRONT_AND_BACK 0x00000408 +#define NV10TCL_FRONT_FACE 0x000003a0 +#define NV10TCL_FRONT_FACE_CW 0x00000900 +#define NV10TCL_FRONT_FACE_CCW 0x00000901 +#define NV10TCL_NORMALIZE_ENABLE 0x000003a4 +#define NV10TCL_COLOR_MATERIAL_R 0x000003a8 +#define NV10TCL_COLOR_MATERIAL_G 0x000003ac +#define NV10TCL_COLOR_MATERIAL_B 0x000003b0 +#define NV10TCL_COLOR_MATERIAL_A 0x000003b4 +#define NV10TCL_COLOR_CONTROL 0x000003b8 +#define NV10TCL_ENABLED_LIGHTS 0x000003bc +#define NV10TCL_ENABLED_LIGHTS_LIGHT0 (1 << 0) +#define NV10TCL_ENABLED_LIGHTS_LIGHT1 (1 << 2) +#define NV10TCL_ENABLED_LIGHTS_LIGHT2 (1 << 4) +#define NV10TCL_ENABLED_LIGHTS_LIGHT3 (1 << 6) +#define NV10TCL_ENABLED_LIGHTS_LIGHT4 (1 << 8) +#define NV10TCL_ENABLED_LIGHTS_LIGHT5 (1 << 10) +#define NV10TCL_ENABLED_LIGHTS_LIGHT6 (1 << 12) +#define NV10TCL_ENABLED_LIGHTS_LIGHT7 (1 << 14) +#define NV10TCL_CLIP_PLANE_ENABLE(x) (0x000003c0+((x)*4)) +#define NV10TCL_CLIP_PLANE_ENABLE__SIZE 0x00000008 +#define NV10TCL_CLIP_PLANE_ENABLE_FALSE 0x00000000 +#define NV10TCL_CLIP_PLANE_ENABLE_EYE_LINEAR 0x00002400 +#define NV10TCL_CLIP_PLANE_ENABLE_OBJECT_LINEAR 0x00002401 +#define NV10TCL_TX_MATRIX_ENABLE(x) (0x000003e0+((x)*4)) +#define NV10TCL_TX_MATRIX_ENABLE__SIZE 0x00000002 +#define NV10TCL_VIEW_MATRIX_ENABLE 0x000003e8 +#define NV10TCL_VIEW_MATRIX_ENABLE_MODELVIEW1 (1 << 0) +#define NV10TCL_VIEW_MATRIX_ENABLE_MODELVIEW0 (1 << 1) +#define NV10TCL_VIEW_MATRIX_ENABLE_PROJECTION (1 << 2) +#define NV10TCL_POINT_SIZE 0x000003ec +#define NV10TCL_MODELVIEW0_MATRIX(x) (0x00000400+((x)*4)) +#define NV10TCL_MODELVIEW0_MATRIX__SIZE 0x00000010 +#define NV10TCL_MODELVIEW1_MATRIX(x) (0x00000440+((x)*4)) +#define NV10TCL_MODELVIEW1_MATRIX__SIZE 0x00000010 +#define NV10TCL_INVERSE_MODELVIEW0_MATRIX(x) (0x00000480+((x)*4)) +#define NV10TCL_INVERSE_MODELVIEW0_MATRIX__SIZE 0x00000010 +#define NV10TCL_INVERSE_MODELVIEW1_MATRIX(x) (0x000004c0+((x)*4)) +#define NV10TCL_INVERSE_MODELVIEW1_MATRIX__SIZE 0x00000010 +#define NV10TCL_PROJECTION_MATRIX(x) (0x00000500+((x)*4)) +#define NV10TCL_PROJECTION_MATRIX__SIZE 0x00000010 +#define NV10TCL_TX0_MATRIX(x) (0x00000540+((x)*4)) +#define NV10TCL_TX0_MATRIX__SIZE 0x00000010 +#define NV10TCL_TX1_MATRIX(x) (0x00000580+((x)*4)) +#define NV10TCL_TX1_MATRIX__SIZE 0x00000010 +#define NV10TCL_CLIP_PLANE_A(x) (0x00000600+((x)*16)) +#define NV10TCL_CLIP_PLANE_A__SIZE 0x00000008 +#define NV10TCL_CLIP_PLANE_B(x) (0x00000604+((x)*16)) +#define NV10TCL_CLIP_PLANE_B__SIZE 0x00000008 +#define NV10TCL_CLIP_PLANE_C(x) (0x00000608+((x)*16)) +#define NV10TCL_CLIP_PLANE_C__SIZE 0x00000008 +#define NV10TCL_CLIP_PLANE_D(x) (0x0000060c+((x)*16)) +#define NV10TCL_CLIP_PLANE_D__SIZE 0x00000008 +#define NV10TCL_FOG_EQUATION_CONSTANT 0x00000680 +#define NV10TCL_FOG_EQUATION_LINEAR 0x00000684 +#define NV10TCL_FOG_EQUATION_QUADRATIC 0x00000688 +#define NV10TCL_FRONT_MATERIAL_SHININESS(x) (0x000006a0+((x)*4)) +#define NV10TCL_FRONT_MATERIAL_SHININESS__SIZE 0x00000006 +#define NV10TCL_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000006c4 +#define NV10TCL_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000006c8 +#define NV10TCL_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000006cc +#define NV10TCL_VIEWPORT_SCALE_X 0x000006e8 +#define NV10TCL_VIEWPORT_SCALE_Y 0x000006ec +#define NV10TCL_VIEWPORT_SCALE_Z 0x000006f0 +#define NV10TCL_VIEWPORT_SCALE_W 0x000006f4 +#define NV10TCL_POINT_PARAMETER(x) (0x000006f8+((x)*4)) +#define NV10TCL_POINT_PARAMETER__SIZE 0x00000008 +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(x) (0x00000800+((x)*128)) +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R__SIZE 0x00000008 +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(x) (0x00000804+((x)*128)) +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G__SIZE 0x00000008 +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(x) (0x00000808+((x)*128)) +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B__SIZE 0x00000008 +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(x) (0x0000080c+((x)*128)) +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R__SIZE 0x00000008 +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(x) (0x00000810+((x)*128)) +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G__SIZE 0x00000008 +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(x) (0x00000814+((x)*128)) +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B__SIZE 0x00000008 +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(x) (0x00000818+((x)*128)) +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R__SIZE 0x00000008 +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(x) (0x0000081c+((x)*128)) +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G__SIZE 0x00000008 +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(x) (0x00000820+((x)*128)) +#define NV10TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B__SIZE 0x00000008 +#define NV10TCL_LIGHT_HALF_VECTOR_X(x) (0x00000828+((x)*128)) +#define NV10TCL_LIGHT_HALF_VECTOR_X__SIZE 0x00000008 +#define NV10TCL_LIGHT_HALF_VECTOR_Y(x) (0x0000082c+((x)*128)) +#define NV10TCL_LIGHT_HALF_VECTOR_Y__SIZE 0x00000008 +#define NV10TCL_LIGHT_HALF_VECTOR_Z(x) (0x00000830+((x)*128)) +#define NV10TCL_LIGHT_HALF_VECTOR_Z__SIZE 0x00000008 +#define NV10TCL_LIGHT_DIRECTION_X(x) (0x00000834+((x)*128)) +#define NV10TCL_LIGHT_DIRECTION_X__SIZE 0x00000008 +#define NV10TCL_LIGHT_DIRECTION_Y(x) (0x00000838+((x)*128)) +#define NV10TCL_LIGHT_DIRECTION_Y__SIZE 0x00000008 +#define NV10TCL_LIGHT_DIRECTION_Z(x) (0x0000083c+((x)*128)) +#define NV10TCL_LIGHT_DIRECTION_Z__SIZE 0x00000008 +#define NV10TCL_LIGHT_SPOT_CUTOFF_A(x) (0x00000840+((x)*128)) +#define NV10TCL_LIGHT_SPOT_CUTOFF_A__SIZE 0x00000008 +#define NV10TCL_LIGHT_SPOT_CUTOFF_B(x) (0x00000844+((x)*128)) +#define NV10TCL_LIGHT_SPOT_CUTOFF_B__SIZE 0x00000008 +#define NV10TCL_LIGHT_SPOT_CUTOFF_C(x) (0x00000848+((x)*128)) +#define NV10TCL_LIGHT_SPOT_CUTOFF_C__SIZE 0x00000008 +#define NV10TCL_LIGHT_SPOT_DIR_X(x) (0x0000084c+((x)*128)) +#define NV10TCL_LIGHT_SPOT_DIR_X__SIZE 0x00000008 +#define NV10TCL_LIGHT_SPOT_DIR_Y(x) (0x00000850+((x)*128)) +#define NV10TCL_LIGHT_SPOT_DIR_Y__SIZE 0x00000008 +#define NV10TCL_LIGHT_SPOT_DIR_Z(x) (0x00000854+((x)*128)) +#define NV10TCL_LIGHT_SPOT_DIR_Z__SIZE 0x00000008 +#define NV10TCL_LIGHT_SPOT_CUTOFF_D(x) (0x00000858+((x)*128)) +#define NV10TCL_LIGHT_SPOT_CUTOFF_D__SIZE 0x00000008 +#define NV10TCL_LIGHT_POSITION_X(x) (0x0000085c+((x)*128)) +#define NV10TCL_LIGHT_POSITION_X__SIZE 0x00000008 +#define NV10TCL_LIGHT_POSITION_Y(x) (0x00000860+((x)*128)) +#define NV10TCL_LIGHT_POSITION_Y__SIZE 0x00000008 +#define NV10TCL_LIGHT_POSITION_Z(x) (0x00000864+((x)*128)) +#define NV10TCL_LIGHT_POSITION_Z__SIZE 0x00000008 +#define NV10TCL_LIGHT_ATTENUATION_CONSTANT(x) (0x00000868+((x)*128)) +#define NV10TCL_LIGHT_ATTENUATION_CONSTANT__SIZE 0x00000008 +#define NV10TCL_LIGHT_ATTENUATION_LINEAR(x) (0x0000086c+((x)*128)) +#define NV10TCL_LIGHT_ATTENUATION_LINEAR__SIZE 0x00000008 +#define NV10TCL_LIGHT_ATTENUATION_QUADRATIC(x) (0x00000870+((x)*128)) +#define NV10TCL_LIGHT_ATTENUATION_QUADRATIC__SIZE 0x00000008 +#define NV10TCL_VERTEX_POS_3F_X 0x00000c00 +#define NV10TCL_VERTEX_POS_3F_Y 0x00000c04 +#define NV10TCL_VERTEX_POS_3F_Z 0x00000c08 +#define NV10TCL_VERTEX_POS_4F_X 0x00000c18 +#define NV10TCL_VERTEX_POS_4F_Y 0x00000c1c +#define NV10TCL_VERTEX_POS_4F_Z 0x00000c20 +#define NV10TCL_VERTEX_POS_4F_W 0x00000c24 +#define NV10TCL_VERTEX_NOR_3F_X 0x00000c30 +#define NV10TCL_VERTEX_NOR_3F_Y 0x00000c34 +#define NV10TCL_VERTEX_NOR_3F_Z 0x00000c38 +#define NV10TCL_VERTEX_NOR_3I_XY 0x00000c40 +#define NV10TCL_VERTEX_NOR_3I_XY_X_SHIFT 0 +#define NV10TCL_VERTEX_NOR_3I_XY_X_MASK 0x0000ffff +#define NV10TCL_VERTEX_NOR_3I_XY_Y_SHIFT 16 +#define NV10TCL_VERTEX_NOR_3I_XY_Y_MASK 0xffff0000 +#define NV10TCL_VERTEX_NOR_3I_Z 0x00000c44 +#define NV10TCL_VERTEX_NOR_3I_Z_Z_SHIFT 0 +#define NV10TCL_VERTEX_NOR_3I_Z_Z_MASK 0x0000ffff +#define NV10TCL_VERTEX_COL_4F_R 0x00000c50 +#define NV10TCL_VERTEX_COL_4F_G 0x00000c54 +#define NV10TCL_VERTEX_COL_4F_B 0x00000c58 +#define NV10TCL_VERTEX_COL_4F_A 0x00000c5c +#define NV10TCL_VERTEX_COL_3F_R 0x00000c60 +#define NV10TCL_VERTEX_COL_3F_G 0x00000c64 +#define NV10TCL_VERTEX_COL_3F_B 0x00000c68 +#define NV10TCL_VERTEX_COL_4I 0x00000c6c +#define NV10TCL_VERTEX_COL_4I_R_SHIFT 0 +#define NV10TCL_VERTEX_COL_4I_R_MASK 0x000000ff +#define NV10TCL_VERTEX_COL_4I_G_SHIFT 8 +#define NV10TCL_VERTEX_COL_4I_G_MASK 0x0000ff00 +#define NV10TCL_VERTEX_COL_4I_B_SHIFT 16 +#define NV10TCL_VERTEX_COL_4I_B_MASK 0x00ff0000 +#define NV10TCL_VERTEX_COL_4I_A_SHIFT 24 +#define NV10TCL_VERTEX_COL_4I_A_MASK 0xff000000 +#define NV10TCL_VERTEX_COL2_3F_R 0x00000c80 +#define NV10TCL_VERTEX_COL2_3F_G 0x00000c84 +#define NV10TCL_VERTEX_COL2_3F_B 0x00000c88 +#define NV10TCL_VERTEX_COL2_3I 0x00000c8c +#define NV10TCL_VERTEX_COL2_3I_R_SHIFT 0 +#define NV10TCL_VERTEX_COL2_3I_R_MASK 0x000000ff +#define NV10TCL_VERTEX_COL2_3I_G_SHIFT 8 +#define NV10TCL_VERTEX_COL2_3I_G_MASK 0x0000ff00 +#define NV10TCL_VERTEX_COL2_3I_B_SHIFT 16 +#define NV10TCL_VERTEX_COL2_3I_B_MASK 0x00ff0000 +#define NV10TCL_VERTEX_TX0_2F_S 0x00000c90 +#define NV10TCL_VERTEX_TX0_2F_T 0x00000c94 +#define NV10TCL_VERTEX_TX0_2I 0x00000c98 +#define NV10TCL_VERTEX_TX0_2I_S_SHIFT 0 +#define NV10TCL_VERTEX_TX0_2I_S_MASK 0x0000ffff +#define NV10TCL_VERTEX_TX0_2I_T_SHIFT 16 +#define NV10TCL_VERTEX_TX0_2I_T_MASK 0xffff0000 +#define NV10TCL_VERTEX_TX0_4F_S 0x00000ca0 +#define NV10TCL_VERTEX_TX0_4F_T 0x00000ca4 +#define NV10TCL_VERTEX_TX0_4F_R 0x00000ca8 +#define NV10TCL_VERTEX_TX0_4F_Q 0x00000cac +#define NV10TCL_VERTEX_TX0_4I_ST 0x00000cb0 +#define NV10TCL_VERTEX_TX0_4I_ST_S_SHIFT 0 +#define NV10TCL_VERTEX_TX0_4I_ST_S_MASK 0x0000ffff +#define NV10TCL_VERTEX_TX0_4I_ST_T_SHIFT 16 +#define NV10TCL_VERTEX_TX0_4I_ST_T_MASK 0xffff0000 +#define NV10TCL_VERTEX_TX0_4I_RQ 0x00000cb4 +#define NV10TCL_VERTEX_TX0_4I_RQ_R_SHIFT 0 +#define NV10TCL_VERTEX_TX0_4I_RQ_R_MASK 0x0000ffff +#define NV10TCL_VERTEX_TX0_4I_RQ_Q_SHIFT 16 +#define NV10TCL_VERTEX_TX0_4I_RQ_Q_MASK 0xffff0000 +#define NV10TCL_VERTEX_TX1_2F_S 0x00000cb8 +#define NV10TCL_VERTEX_TX1_2F_T 0x00000cbc +#define NV10TCL_VERTEX_TX1_2I 0x00000cc0 +#define NV10TCL_VERTEX_TX1_2I_S_SHIFT 0 +#define NV10TCL_VERTEX_TX1_2I_S_MASK 0x0000ffff +#define NV10TCL_VERTEX_TX1_2I_T_SHIFT 16 +#define NV10TCL_VERTEX_TX1_2I_T_MASK 0xffff0000 +#define NV10TCL_VERTEX_TX1_4F_S 0x00000cc8 +#define NV10TCL_VERTEX_TX1_4F_T 0x00000ccc +#define NV10TCL_VERTEX_TX1_4F_R 0x00000cd0 +#define NV10TCL_VERTEX_TX1_4F_Q 0x00000cd4 +#define NV10TCL_VERTEX_TX1_4I_ST 0x00000cd8 +#define NV10TCL_VERTEX_TX1_4I_ST_S_SHIFT 0 +#define NV10TCL_VERTEX_TX1_4I_ST_S_MASK 0x0000ffff +#define NV10TCL_VERTEX_TX1_4I_ST_T_SHIFT 16 +#define NV10TCL_VERTEX_TX1_4I_ST_T_MASK 0xffff0000 +#define NV10TCL_VERTEX_TX1_4I_RQ 0x00000cdc +#define NV10TCL_VERTEX_TX1_4I_RQ_R_SHIFT 0 +#define NV10TCL_VERTEX_TX1_4I_RQ_R_MASK 0x0000ffff +#define NV10TCL_VERTEX_TX1_4I_RQ_Q_SHIFT 16 +#define NV10TCL_VERTEX_TX1_4I_RQ_Q_MASK 0xffff0000 +#define NV10TCL_VERTEX_FOG_1F 0x00000ce0 +#define NV10TCL_VERTEX_WGH_1F 0x00000ce4 +#define NV10TCL_EDGEFLAG_ENABLE 0x00000cec +#define NV10TCL_VERTEX_ARRAY_VALIDATE 0x00000cf0 +#define NV10TCL_VERTEX_ARRAY_ATTRIB_OFFSET(x) (0x00000d00+((x)*8)) +#define NV10TCL_VERTEX_ARRAY_ATTRIB_OFFSET__SIZE 0x00000008 +#define NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT(x) (0x00000d04+((x)*8)) +#define NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT__SIZE 0x00000008 +#define NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT_TYPE_SHIFT 0 +#define NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT_TYPE_MASK 0x0000000f +#define NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT_FIELDS_SHIFT 4 +#define NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT_FIELDS_MASK 0x000000f0 +#define NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT_STRIDE_SHIFT 8 +#define NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT_STRIDE_MASK 0x0000ff00 +#define NV10TCL_VERTEX_ARRAY_OFFSET_POS 0x00000d00 +#define NV10TCL_VERTEX_ARRAY_FORMAT_POS 0x00000d04 +#define NV10TCL_VERTEX_ARRAY_FORMAT_POS_TYPE_SHIFT 0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_POS_TYPE_MASK 0x0000000f +#define NV10TCL_VERTEX_ARRAY_FORMAT_POS_FIELDS_SHIFT 4 +#define NV10TCL_VERTEX_ARRAY_FORMAT_POS_FIELDS_MASK 0x000000f0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_POS_STRIDE_SHIFT 8 +#define NV10TCL_VERTEX_ARRAY_FORMAT_POS_STRIDE_MASK 0x0000ff00 +#define NV10TCL_VERTEX_ARRAY_OFFSET_COL 0x00000d08 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL 0x00000d0c +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL_TYPE_SHIFT 0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL_TYPE_MASK 0x0000000f +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL_FIELDS_SHIFT 4 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL_FIELDS_MASK 0x000000f0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL_STRIDE_SHIFT 8 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL_STRIDE_MASK 0x0000ff00 +#define NV10TCL_VERTEX_ARRAY_OFFSET_COL2 0x00000d10 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL2 0x00000d14 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL2_TYPE_SHIFT 0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL2_TYPE_MASK 0x0000000f +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL2_FIELDS_SHIFT 4 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL2_FIELDS_MASK 0x000000f0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL2_STRIDE_SHIFT 8 +#define NV10TCL_VERTEX_ARRAY_FORMAT_COL2_STRIDE_MASK 0x0000ff00 +#define NV10TCL_VERTEX_ARRAY_OFFSET_TX0 0x00000d18 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX0 0x00000d1c +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX0_TYPE_SHIFT 0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX0_TYPE_MASK 0x0000000f +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX0_FIELDS_SHIFT 4 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX0_FIELDS_MASK 0x000000f0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX0_STRIDE_SHIFT 8 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX0_STRIDE_MASK 0x0000ff00 +#define NV10TCL_VERTEX_ARRAY_OFFSET_TX1 0x00000d20 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX1 0x00000d24 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX1_TYPE_SHIFT 0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX1_TYPE_MASK 0x0000000f +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX1_FIELDS_SHIFT 4 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX1_FIELDS_MASK 0x000000f0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX1_STRIDE_SHIFT 8 +#define NV10TCL_VERTEX_ARRAY_FORMAT_TX1_STRIDE_MASK 0x0000ff00 +#define NV10TCL_VERTEX_ARRAY_OFFSET_NOR 0x00000d28 +#define NV10TCL_VERTEX_ARRAY_FORMAT_NOR 0x00000d2c +#define NV10TCL_VERTEX_ARRAY_FORMAT_NOR_TYPE_SHIFT 0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_NOR_TYPE_MASK 0x0000000f +#define NV10TCL_VERTEX_ARRAY_FORMAT_NOR_FIELDS_SHIFT 4 +#define NV10TCL_VERTEX_ARRAY_FORMAT_NOR_FIELDS_MASK 0x000000f0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_NOR_STRIDE_SHIFT 8 +#define NV10TCL_VERTEX_ARRAY_FORMAT_NOR_STRIDE_MASK 0x0000ff00 +#define NV10TCL_VERTEX_ARRAY_OFFSET_WGH 0x00000d30 +#define NV10TCL_VERTEX_ARRAY_FORMAT_WGH 0x00000d34 +#define NV10TCL_VERTEX_ARRAY_FORMAT_WGH_TYPE_SHIFT 0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_WGH_TYPE_MASK 0x0000000f +#define NV10TCL_VERTEX_ARRAY_FORMAT_WGH_FIELDS_SHIFT 4 +#define NV10TCL_VERTEX_ARRAY_FORMAT_WGH_FIELDS_MASK 0x000000f0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_WGH_STRIDE_SHIFT 8 +#define NV10TCL_VERTEX_ARRAY_FORMAT_WGH_STRIDE_MASK 0x0000ff00 +#define NV10TCL_VERTEX_ARRAY_OFFSET_FOG 0x00000d38 +#define NV10TCL_VERTEX_ARRAY_FORMAT_FOG 0x00000d3c +#define NV10TCL_VERTEX_ARRAY_FORMAT_FOG_TYPE_SHIFT 0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_FOG_TYPE_MASK 0x0000000f +#define NV10TCL_VERTEX_ARRAY_FORMAT_FOG_FIELDS_SHIFT 4 +#define NV10TCL_VERTEX_ARRAY_FORMAT_FOG_FIELDS_MASK 0x000000f0 +#define NV10TCL_VERTEX_ARRAY_FORMAT_FOG_STRIDE_SHIFT 8 +#define NV10TCL_VERTEX_ARRAY_FORMAT_FOG_STRIDE_MASK 0x0000ff00 +#define NV10TCL_VERTEX_BEGIN_END 0x00000dfc +#define NV10TCL_VERTEX_BEGIN_END_STOP 0x00000000 +#define NV10TCL_VERTEX_BEGIN_END_POINTS 0x00000001 +#define NV10TCL_VERTEX_BEGIN_END_LINES 0x00000002 +#define NV10TCL_VERTEX_BEGIN_END_LINE_LOOP 0x00000003 +#define NV10TCL_VERTEX_BEGIN_END_LINE_STRIP 0x00000004 +#define NV10TCL_VERTEX_BEGIN_END_TRIANGLES 0x00000005 +#define NV10TCL_VERTEX_BEGIN_END_TRIANGLE_STRIP 0x00000006 +#define NV10TCL_VERTEX_BEGIN_END_TRIANGLE_FAN 0x00000007 +#define NV10TCL_VERTEX_BEGIN_END_QUADS 0x00000008 +#define NV10TCL_VERTEX_BEGIN_END_QUAD_STRIP 0x00000009 +#define NV10TCL_VERTEX_BEGIN_END_POLYGON 0x0000000a +#define NV10TCL_VB_ELEMENT_U16 0x00000e00 +#define NV10TCL_VB_ELEMENT_U16_I0_SHIFT 0 +#define NV10TCL_VB_ELEMENT_U16_I0_MASK 0x0000ffff +#define NV10TCL_VB_ELEMENT_U16_I1_SHIFT 16 +#define NV10TCL_VB_ELEMENT_U16_I1_MASK 0xffff0000 +#define NV10TCL_VB_ELEMENT_U32 0x00001100 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END 0x000013fc +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_STOP 0x00000000 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_POINTS 0x00000001 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_LINES 0x00000002 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_LINE_LOOP 0x00000003 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_LINE_STRIP 0x00000004 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_TRIANGLES 0x00000005 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_TRIANGLE_STRIP 0x00000006 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_TRIANGLE_FAN 0x00000007 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_QUADS 0x00000008 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_QUAD_STRIP 0x00000009 +#define NV10TCL_VERTEX_BUFFER_BEGIN_END_POLYGON 0x0000000a +#define NV10TCL_VERTEX_BUFFER_DRAW_ARRAYS 0x00001400 +#define NV10TCL_VERTEX_BUFFER_DRAW_ARRAYS_FIRST_SHIFT 0 +#define NV10TCL_VERTEX_BUFFER_DRAW_ARRAYS_FIRST_MASK 0x0000ffff +#define NV10TCL_VERTEX_BUFFER_DRAW_ARRAYS_LAST_SHIFT 24 +#define NV10TCL_VERTEX_BUFFER_DRAW_ARRAYS_LAST_MASK 0xff000000 +#define NV10TCL_VERTEX_ARRAY_DATA 0x00001800 + + +#define NV04_CONTEXT_COLOR_KEY 0x00000057 + + + +#define NV03_CONTEXT_SURFACES_2D 0x00000058 + +#define NV03_CONTEXT_SURFACES_2D_SYNCHRONIZE 0x00000100 +#define NV03_CONTEXT_SURFACES_2D_DMA_NOTIFY 0x00000180 +#define NV03_CONTEXT_SURFACES_2D_DMA_SOURCE 0x00000184 +#define NV03_CONTEXT_SURFACES_2D_DMA_DESTIN 0x00000188 +#define NV03_CONTEXT_SURFACES_2D_COLOR_FORMAT 0x00000300 +#define NV03_CONTEXT_SURFACES_2D_PITCH 0x00000304 +#define NV03_CONTEXT_SURFACES_2D_PITCH_SOURCE_SHIFT 0 +#define NV03_CONTEXT_SURFACES_2D_PITCH_SOURCE_MASK 0x0000ffff +#define NV03_CONTEXT_SURFACES_2D_PITCH_DESTIN_SHIFT 16 +#define NV03_CONTEXT_SURFACES_2D_PITCH_DESTIN_MASK 0xffff0000 +#define NV03_CONTEXT_SURFACES_2D_OFFSET_SOURCE 0x00000308 +#define NV03_CONTEXT_SURFACES_2D_OFFSET_DESTIN 0x0000030c + + +#define NV03_CONTEXT_SURFACES_3D 0x0000005a + +#define NV03_CONTEXT_SURFACES_3D_SYNCHRONIZE 0x00000100 +#define NV03_CONTEXT_SURFACES_3D_DMA_NOTIFY 0x00000180 +#define NV03_CONTEXT_SURFACES_3D_DMA_SURFACE 0x00000184 +#define NV03_CONTEXT_SURFACES_3D_PITCH 0x00000300 +#define NV03_CONTEXT_SURFACES_3D_OFFSET_COLOR 0x00000304 +#define NV03_CONTEXT_SURFACES_3D_OFFSET_ZETA 0x00000308 + + +#define NV04_RENDER_SOLID_LINE 0x0000005c + +#define NV04_RENDER_SOLID_LINE_SURFACE 0x00000198 + + +#define NV04_RENDER_SOLID_TRIANGLE 0x0000005d + + + +#define NV04_RENDER_SOLID_RECTANGLE 0x0000005e + +#define NV04_RENDER_SOLID_RECTANGLE_SURFACE 0x00000198 + + +#define NV04_IMAGE_BLIT 0x0000005f + +#define NV04_IMAGE_BLIT_NOP 0x00000100 +#define NV04_IMAGE_BLIT_NOTIFY 0x00000104 +#define NV04_IMAGE_BLIT_DMA_NOTIFY 0x00000180 +#define NV04_IMAGE_BLIT_COLOR_KEY 0x00000184 +#define NV04_IMAGE_BLIT_CLIP_RECTANGLE 0x00000188 +#define NV04_IMAGE_BLIT_PATTERN 0x0000018c +#define NV04_IMAGE_BLIT_ROP 0x00000190 +#define NV04_IMAGE_BLIT_BETA4 0x00000198 +#define NV04_IMAGE_BLIT_SURFACE 0x0000019c +#define NV04_IMAGE_BLIT_OPERATION 0x000002fc +#define NV04_IMAGE_BLIT_OPERATION_SRCCOPY_AND 0x00000000 +#define NV04_IMAGE_BLIT_OPERATION_ROP_AND 0x00000001 +#define NV04_IMAGE_BLIT_OPERATION_BLEND_AND 0x00000002 +#define NV04_IMAGE_BLIT_OPERATION_SRCCOPY 0x00000003 +#define NV04_IMAGE_BLIT_OPERATION_SRCCOPY_PREMULT 0x00000004 +#define NV04_IMAGE_BLIT_OPERATION_BLEND_PREMULT 0x00000005 + + +#define NV04_INDEXED_IMAGE_FROM_CPU 0x00000060 + +#define NV04_INDEXED_IMAGE_FROM_CPU_NOP 0x00000100 +#define NV04_INDEXED_IMAGE_FROM_CPU_NOTIFY 0x00000104 +#define NV04_INDEXED_IMAGE_FROM_CPU_PATCH 0x0000010c +#define NV04_INDEXED_IMAGE_FROM_CPU_DMA_NOTIFY 0x00000180 +#define NV04_INDEXED_IMAGE_FROM_CPU_DMA_LUT 0x00000184 +#define NV04_INDEXED_IMAGE_FROM_CPU_COLOR_FORMAT 0x000003e8 +#define NV04_INDEXED_IMAGE_FROM_CPU_INDEX_FORMAT 0x000003ec +#define NV04_INDEXED_IMAGE_FROM_CPU_LUT_OFFSET 0x000003f0 +#define NV04_INDEXED_IMAGE_FROM_CPU_POINT 0x000003f4 +#define NV04_INDEXED_IMAGE_FROM_CPU_SIZE_OUT 0x000003f8 +#define NV04_INDEXED_IMAGE_FROM_CPU_SIZE_IN 0x000003fc +#define NV04_INDEXED_IMAGE_FROM_CPU_COLOR 0x00000400 + + +#define NV04_IMAGE_FROM_CPU 0x00000061 + +#define NV04_IMAGE_FROM_CPU_BETA4 0x00000198 +#define NV04_IMAGE_FROM_CPU_SURFACE 0x0000019c + + +#define NV10_CONTEXT_SURFACES_2D 0x00000062 + + + +#define NV05_SCALED_IMAGE_FROM_MEMORY 0x00000063 + +#define NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION 0x000002fc +#define NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_DITHER 0x00000000 +#define NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE 0x00000001 +#define NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_SUBTR_TRUNCATE 0x00000002 + + +#define NV01_IMAGE_SRCCOPY_AND 0x00000064 + +#define NV01_IMAGE_SRCCOPY_AND_NOTIFY 0x00000104 +#define NV01_IMAGE_SRCCOPY_AND_DMA_NOTIFY 0x00000180 +#define NV01_IMAGE_SRCCOPY_AND_IMAGE_OUTPUT 0x00000200 +#define NV01_IMAGE_SRCCOPY_AND_IMAGE_INPUT 0x00000204 + + +#define NV05_INDEXED_IMAGE_FROM_CPU 0x00000064 + +#define NV05_INDEXED_IMAGE_FROM_CPU_COLOR_KEY 0x00000188 +#define NV05_INDEXED_IMAGE_FROM_CPU_CLIP_RECTANGLE 0x0000018c +#define NV05_INDEXED_IMAGE_FROM_CPU_PATTERN 0x00000190 +#define NV05_INDEXED_IMAGE_FROM_CPU_ROP 0x00000194 +#define NV05_INDEXED_IMAGE_FROM_CPU_BETA1 0x00000198 +#define NV05_INDEXED_IMAGE_FROM_CPU_BETA4 0x0000019c +#define NV05_INDEXED_IMAGE_FROM_CPU_SURFACE 0x000001a0 +#define NV05_INDEXED_IMAGE_FROM_CPU_COLOR_CONVERSION 0x000003e0 +#define NV05_INDEXED_IMAGE_FROM_CPU_OPERATION 0x000003e4 +#define NV05_INDEXED_IMAGE_FROM_CPU_INDICES 0x00000400 + + +#define NV05_IMAGE_FROM_CPU 0x00000065 + +#define NV05_IMAGE_FROM_CPU_BETA4 0x00000198 +#define NV05_IMAGE_FROM_CPU_SURFACE 0x0000019c + + +#define NV05_STRETCHED_IMAGE_FROM_CPU 0x00000066 + +#define NV05_STRETCHED_IMAGE_FROM_CPU_BETA4 0x00000194 +#define NV05_STRETCHED_IMAGE_FROM_CPU_SURFACE 0x00000198 +#define NV05_STRETCHED_IMAGE_FROM_CPU_COLOR_CONVERSION 0x000002f8 + + +#define NV04_IMAGE_BLEND_PREMULT 0x00000067 + +#define NV04_IMAGE_BLEND_PREMULT_NOP 0x00000100 +#define NV04_IMAGE_BLEND_PREMULT_NOTIFY 0x00000104 +#define NV04_IMAGE_BLEND_PREMULT_DMA_NOTIFY 0x00000180 +#define NV04_IMAGE_BLEND_PREMULT_IMAGE_OUTPUT 0x00000200 +#define NV04_IMAGE_BLEND_PREMULT_BETA_INPUT 0x00000204 +#define NV04_IMAGE_BLEND_PREMULT_IMAGE_INPUT 0x00000208 + + +#define NV03_CHANNEL_PIO 0x0000006a + + + +#define NV03_CHANNEL_DMA 0x0000006b + + + +#define NV04_BETA_SOLID 0x00000072 + +#define NV04_BETA_SOLID_NOP 0x00000100 +#define NV04_BETA_SOLID_NOTIFY 0x00000104 +#define NV04_BETA_SOLID_DMA_NOTIFY 0x00000180 +#define NV04_BETA_SOLID_BETA_OUTPUT 0x00000200 +#define NV04_BETA_SOLID_BETA_FACTOR 0x00000300 + + +#define NV04_STRETCHED_IMAGE_FROM_CPU 0x00000076 + + + +#define NV04_SCALED_IMAGE_FROM_MEMORY 0x00000077 + +#define NV04_SCALED_IMAGE_FROM_MEMORY_NOP 0x00000100 +#define NV04_SCALED_IMAGE_FROM_MEMORY_NOTIFY 0x00000104 +#define NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY 0x00000180 +#define NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE 0x00000184 +#define NV04_SCALED_IMAGE_FROM_MEMORY_PATTERN 0x00000188 +#define NV04_SCALED_IMAGE_FROM_MEMORY_ROP 0x0000018c +#define NV04_SCALED_IMAGE_FROM_MEMORY_BETA1 0x00000190 +#define NV04_SCALED_IMAGE_FROM_MEMORY_BETA4 0x00000194 +#define NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE 0x00000198 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION 0x000002fc +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_DITHER 0x00000000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE 0x00000001 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_SUBTR_TRUNCATE 0x00000002 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT 0x00000300 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5 0x00000001 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X1R5G5B5 0x00000002 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8 0x00000003 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8 0x00000004 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_V8YB8U8YA8 0x00000005 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_YB8V8YA8U8 0x00000006 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5 0x00000007 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_Y8 0x00000008 +#define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_AY8 0x00000009 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY_AND 0x00000000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_ROP_AND 0x00000001 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_BLEND_AND 0x00000002 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY 0x00000003 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY_PREMULT 0x00000004 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_BLEND_PREMULT 0x00000005 +#define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT 0x00000308 +#define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_X_SHIFT 0 +#define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_X_MASK 0x0000ffff +#define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_Y_SHIFT 16 +#define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_Y_MASK 0xffff0000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE 0x0000030c +#define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_W_SHIFT 0 +#define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_W_MASK 0x0000ffff +#define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_H_SHIFT 16 +#define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_H_MASK 0xffff0000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_POINT 0x00000310 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_POINT_X_SHIFT 0 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_POINT_X_MASK 0x0000ffff +#define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_POINT_Y_SHIFT 16 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_POINT_Y_MASK 0xffff0000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE 0x00000314 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE_W_SHIFT 0 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE_W_MASK 0x0000ffff +#define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE_H_SHIFT 16 +#define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE_H_MASK 0xffff0000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_DU_DX 0x00000318 +#define NV04_SCALED_IMAGE_FROM_MEMORY_DV_DY 0x0000031c +#define NV04_SCALED_IMAGE_FROM_MEMORY_SIZE 0x00000400 +#define NV04_SCALED_IMAGE_FROM_MEMORY_SIZE_W_SHIFT 0 +#define NV04_SCALED_IMAGE_FROM_MEMORY_SIZE_W_MASK 0x0000ffff +#define NV04_SCALED_IMAGE_FROM_MEMORY_SIZE_H_SHIFT 16 +#define NV04_SCALED_IMAGE_FROM_MEMORY_SIZE_H_MASK 0xffff0000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT 0x00000404 +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_PITCH_SHIFT 0 +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_PITCH_MASK 0x0000ffff +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_SHIFT 16 +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_MASK 0x00ff0000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER 0x00010000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CORNER 0x00020000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_SHIFT 24 +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_MASK 0xff000000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE 0x00000000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_BILINEAR 0x01000000 +#define NV04_SCALED_IMAGE_FROM_MEMORY_ADDRESS 0x00000408 +#define NV04_SCALED_IMAGE_FROM_MEMORY_POINT 0x0000040c +#define NV04_SCALED_IMAGE_FROM_MEMORY_POINT_X_SHIFT 0 +#define NV04_SCALED_IMAGE_FROM_MEMORY_POINT_X_MASK 0x0000ffff +#define NV04_SCALED_IMAGE_FROM_MEMORY_POINT_Y_SHIFT 16 +#define NV04_SCALED_IMAGE_FROM_MEMORY_POINT_Y_MASK 0xffff0000 + + +#define NV10_TEXTURE_FROM_CPU 0x0000007b + +#define NV10_TEXTURE_FROM_CPU_NOP 0x00000100 +#define NV10_TEXTURE_FROM_CPU_NOTIFY 0x00000104 +#define NV10_TEXTURE_FROM_CPU_WAIT_FOR_IDLE 0x00000108 +#define NV10_TEXTURE_FROM_CPU_PM_TRIGGER 0x00000140 +#define NV10_TEXTURE_FROM_CPU_DMA_NOTIFY 0x00000180 +#define NV10_TEXTURE_FROM_CPU_SURFACE 0x00000184 +#define NV10_TEXTURE_FROM_CPU_COLOR_FORMAT 0x00000300 +#define NV10_TEXTURE_FROM_CPU_POINT 0x00000304 +#define NV10_TEXTURE_FROM_CPU_POINT_X_SHIFT 0 +#define NV10_TEXTURE_FROM_CPU_POINT_X_MASK 0x0000ffff +#define NV10_TEXTURE_FROM_CPU_POINT_Y_SHIFT 16 +#define NV10_TEXTURE_FROM_CPU_POINT_Y_MASK 0xffff0000 +#define NV10_TEXTURE_FROM_CPU_SIZE 0x00000308 +#define NV10_TEXTURE_FROM_CPU_SIZE_W_SHIFT 0 +#define NV10_TEXTURE_FROM_CPU_SIZE_W_MASK 0x0000ffff +#define NV10_TEXTURE_FROM_CPU_SIZE_H_SHIFT 16 +#define NV10_TEXTURE_FROM_CPU_SIZE_H_MASK 0xffff0000 +#define NV10_TEXTURE_FROM_CPU_CLIP_HORIZONTAL 0x0000030c +#define NV10_TEXTURE_FROM_CPU_CLIP_HORIZONTAL_X_SHIFT 0 +#define NV10_TEXTURE_FROM_CPU_CLIP_HORIZONTAL_X_MASK 0x0000ffff +#define NV10_TEXTURE_FROM_CPU_CLIP_HORIZONTAL_W_SHIFT 16 +#define NV10_TEXTURE_FROM_CPU_CLIP_HORIZONTAL_W_MASK 0xffff0000 +#define NV10_TEXTURE_FROM_CPU_CLIP_VERTICAL 0x00000310 +#define NV10_TEXTURE_FROM_CPU_CLIP_VERTICAL_Y_SHIFT 0 +#define NV10_TEXTURE_FROM_CPU_CLIP_VERTICAL_Y_MASK 0x0000ffff +#define NV10_TEXTURE_FROM_CPU_CLIP_VERTICAL_H_SHIFT 16 +#define NV10_TEXTURE_FROM_CPU_CLIP_VERTICAL_H_MASK 0xffff0000 +#define NV10_TEXTURE_FROM_CPU_COLOR(x) (0x00000400+((x)*4)) +#define NV10_TEXTURE_FROM_CPU_COLOR__SIZE 0x00000700 + + +#define NV10_VIDEO_DISPLAY 0x0000007c + + + +#define NV10_DVD_SUBPICTURE 0x00000088 + + + +#define NV10_SCALED_IMAGE_FROM_MEMORY 0x00000089 + +#define NV10_SCALED_IMAGE_FROM_MEMORY_WAIT_FOR_IDLE 0x00000108 + + +#define NV10_IMAGE_FROM_CPU 0x0000008a + +#define NV10_IMAGE_FROM_CPU_COLOR_CONVERSION 0x000002f8 + + +#define NV10_CONTEXT_SURFACES_3D 0x00000093 + + + +#define NV10_DX5_TEXTURE_TRIANGLE 0x00000094 + + + +#define NV10_DX6_MULTI_TEXTURE_TRIANGLE 0x00000095 + + + +#define NV11TCL 0x00000096 + +#define NV11TCL_COLOR_LOGIC_OP_ENABLE 0x00000d40 +#define NV11TCL_COLOR_LOGIC_OP_OP 0x00000d44 +#define NV11TCL_COLOR_LOGIC_OP_OP_CLEAR 0x00001500 +#define NV11TCL_COLOR_LOGIC_OP_OP_AND 0x00001501 +#define NV11TCL_COLOR_LOGIC_OP_OP_AND_REVERSE 0x00001502 +#define NV11TCL_COLOR_LOGIC_OP_OP_COPY 0x00001503 +#define NV11TCL_COLOR_LOGIC_OP_OP_AND_INVERTED 0x00001504 +#define NV11TCL_COLOR_LOGIC_OP_OP_NOOP 0x00001505 +#define NV11TCL_COLOR_LOGIC_OP_OP_XOR 0x00001506 +#define NV11TCL_COLOR_LOGIC_OP_OP_OR 0x00001507 +#define NV11TCL_COLOR_LOGIC_OP_OP_NOR 0x00001508 +#define NV11TCL_COLOR_LOGIC_OP_OP_EQUIV 0x00001509 +#define NV11TCL_COLOR_LOGIC_OP_OP_INVERT 0x0000150a +#define NV11TCL_COLOR_LOGIC_OP_OP_OR_REVERSE 0x0000150b +#define NV11TCL_COLOR_LOGIC_OP_OP_COPY_INVERTED 0x0000150c +#define NV11TCL_COLOR_LOGIC_OP_OP_OR_INVERTED 0x0000150d +#define NV11TCL_COLOR_LOGIC_OP_OP_NAND 0x0000150e +#define NV11TCL_COLOR_LOGIC_OP_OP_SET 0x0000150f + + +#define NV20TCL 0x00000097 + +#define NV20TCL_NOP 0x00000100 +#define NV20TCL_NOTIFY 0x00000104 +#define NV20TCL_DMA_NOTIFY 0x00000180 +#define NV20TCL_DMA_IN_MEMORY0 0x00000184 +#define NV20TCL_DMA_IN_MEMORY1 0x00000188 +#define NV20TCL_DMA_IN_MEMORY2 0x00000194 +#define NV20TCL_DMA_IN_MEMORY3 0x00000198 +#define NV20TCL_DMA_IN_MEMORY6 0x000001a4 +#define NV20TCL_DMA_IN_MEMORY7 0x000001a8 +#define NV20TCL_VIEWPORT_HORIZ 0x00000200 +#define NV20TCL_VIEWPORT_VERT 0x00000204 +#define NV20TCL_BUFFER_FORMAT 0x00000208 +#define NV20TCL_BUFFER_PITCH 0x0000020c +#define NV20TCL_COLOR_OFFSET 0x00000210 +#define NV20TCL_ZETA_OFFSET 0x00000214 +#define NV20TCL_RC_IN_ALPHA(x) (0x00000260+((x)*4)) +#define NV20TCL_RC_IN_ALPHA__SIZE 0x00000008 +#define NV20TCL_RC_FINAL0 0x00000288 +#define NV20TCL_RC_FINAL1 0x0000028c +#define NV20TCL_LIGHT_CONTROL 0x00000294 +#define NV20TCL_FOG_MODE 0x0000029c +#define NV20TCL_FOG_COORD_DIST 0x000002a0 +#define NV20TCL_FOG_ENABLE 0x000002a4 +#define NV20TCL_FOG_COLOR 0x000002a8 +#define NV20TCL_VIEWPORT_CLIP_MODE 0x000002b4 +#define NV20TCL_VIEWPORT_CLIP_HORIZ(x) (0x000002c0+((x)*4)) +#define NV20TCL_VIEWPORT_CLIP_HORIZ__SIZE 0x00000008 +#define NV20TCL_VIEWPORT_CLIP_VERT(x) (0x000002e0+((x)*4)) +#define NV20TCL_VIEWPORT_CLIP_VERT__SIZE 0x00000008 +#define NV20TCL_ALPHA_FUNC_ENABLE 0x00000300 +#define NV20TCL_BLEND_FUNC_ENABLE 0x00000304 +#define NV20TCL_CULL_FACE_ENABLE 0x00000308 +#define NV20TCL_DEPTH_TEST_ENABLE 0x0000030c +#define NV20TCL_DITHER_ENABLE 0x00000310 +#define NV20TCL_LIGHTING_ENABLE 0x00000314 +#define NV20TCL_POINT_PARAMETERS_ENABLE 0x00000318 +#define NV20TCL_LINE_SMOOTH_ENABLE 0x00000320 +#define NV20TCL_POLYGON_SMOOTH_ENABLE 0x00000324 +#define NV20TCL_STENCIL_ENABLE 0x0000032c +#define NV20TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000330 +#define NV20TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000334 +#define NV20TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000338 +#define NV20TCL_ALPHA_FUNC_FUNC 0x0000033c +#define NV20TCL_ALPHA_FUNC_FUNC_NEVER 0x00000200 +#define NV20TCL_ALPHA_FUNC_FUNC_LESS 0x00000201 +#define NV20TCL_ALPHA_FUNC_FUNC_EQUAL 0x00000202 +#define NV20TCL_ALPHA_FUNC_FUNC_LEQUAL 0x00000203 +#define NV20TCL_ALPHA_FUNC_FUNC_GREATER 0x00000204 +#define NV20TCL_ALPHA_FUNC_FUNC_GREATER 0x00000204 +#define NV20TCL_ALPHA_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV20TCL_ALPHA_FUNC_FUNC_GEQUAL 0x00000206 +#define NV20TCL_ALPHA_FUNC_FUNC_ALWAYS 0x00000207 +#define NV20TCL_ALPHA_FUNC_REF 0x00000340 +#define NV20TCL_BLEND_FUNC_SRC 0x00000344 +#define NV20TCL_BLEND_FUNC_SRC_ZERO 0x00000000 +#define NV20TCL_BLEND_FUNC_SRC_ONE 0x00000001 +#define NV20TCL_BLEND_FUNC_SRC_SRC_COLOR 0x00000300 +#define NV20TCL_BLEND_FUNC_SRC_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV20TCL_BLEND_FUNC_SRC_SRC_ALPHA 0x00000302 +#define NV20TCL_BLEND_FUNC_SRC_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV20TCL_BLEND_FUNC_SRC_DST_ALPHA 0x00000304 +#define NV20TCL_BLEND_FUNC_SRC_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV20TCL_BLEND_FUNC_SRC_DST_COLOR 0x00000306 +#define NV20TCL_BLEND_FUNC_SRC_ONE_MINUS_DST_COLOR 0x00000307 +#define NV20TCL_BLEND_FUNC_SRC_SRC_ALPHA_SATURATE 0x00000308 +#define NV20TCL_BLEND_FUNC_SRC_CONSTANT_COLOR 0x00008001 +#define NV20TCL_BLEND_FUNC_SRC_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV20TCL_BLEND_FUNC_SRC_CONSTANT_ALPHA 0x00008003 +#define NV20TCL_BLEND_FUNC_SRC_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV20TCL_BLEND_FUNC_DST 0x00000348 +#define NV20TCL_BLEND_FUNC_DST_ZERO 0x00000000 +#define NV20TCL_BLEND_FUNC_DST_ONE 0x00000001 +#define NV20TCL_BLEND_FUNC_DST_SRC_COLOR 0x00000300 +#define NV20TCL_BLEND_FUNC_DST_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV20TCL_BLEND_FUNC_DST_SRC_ALPHA 0x00000302 +#define NV20TCL_BLEND_FUNC_DST_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV20TCL_BLEND_FUNC_DST_DST_ALPHA 0x00000304 +#define NV20TCL_BLEND_FUNC_DST_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV20TCL_BLEND_FUNC_DST_DST_COLOR 0x00000306 +#define NV20TCL_BLEND_FUNC_DST_ONE_MINUS_DST_COLOR 0x00000307 +#define NV20TCL_BLEND_FUNC_DST_SRC_ALPHA_SATURATE 0x00000308 +#define NV20TCL_BLEND_FUNC_DST_CONSTANT_COLOR 0x00008001 +#define NV20TCL_BLEND_FUNC_DST_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV20TCL_BLEND_FUNC_DST_CONSTANT_ALPHA 0x00008003 +#define NV20TCL_BLEND_FUNC_DST_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV20TCL_BLEND_COLOR 0x0000034c +#define NV20TCL_BLEND_EQUATION 0x00000350 +#define NV20TCL_BLEND_EQUATION_FUNC_ADD 0x00008006 +#define NV20TCL_BLEND_EQUATION_MIN 0x00008007 +#define NV20TCL_BLEND_EQUATION_MAX 0x00008008 +#define NV20TCL_BLEND_EQUATION_FUNC_SUBTRACT 0x0000800a +#define NV20TCL_BLEND_EQUATION_FUNC_REVERSE_SUBTRACT 0x0000800b +#define NV20TCL_DEPTH_FUNC 0x00000354 +#define NV20TCL_DEPTH_FUNC_NEVER 0x00000200 +#define NV20TCL_DEPTH_FUNC_LESS 0x00000201 +#define NV20TCL_DEPTH_FUNC_EQUAL 0x00000202 +#define NV20TCL_DEPTH_FUNC_LEQUAL 0x00000203 +#define NV20TCL_DEPTH_FUNC_GREATER 0x00000204 +#define NV20TCL_DEPTH_FUNC_GREATER 0x00000204 +#define NV20TCL_DEPTH_FUNC_NOTEQUAL 0x00000205 +#define NV20TCL_DEPTH_FUNC_GEQUAL 0x00000206 +#define NV20TCL_DEPTH_FUNC_ALWAYS 0x00000207 +#define NV20TCL_COLOR_MASK 0x00000358 +#define NV20TCL_DEPTH_WRITE_ENABLE 0x0000035c +#define NV20TCL_STENCIL_MASK 0x00000360 +#define NV20TCL_STENCIL_FUNC_FUNC 0x00000364 +#define NV20TCL_STENCIL_FUNC_FUNC_NEVER 0x00000200 +#define NV20TCL_STENCIL_FUNC_FUNC_LESS 0x00000201 +#define NV20TCL_STENCIL_FUNC_FUNC_EQUAL 0x00000202 +#define NV20TCL_STENCIL_FUNC_FUNC_LEQUAL 0x00000203 +#define NV20TCL_STENCIL_FUNC_FUNC_GREATER 0x00000204 +#define NV20TCL_STENCIL_FUNC_FUNC_GREATER 0x00000204 +#define NV20TCL_STENCIL_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV20TCL_STENCIL_FUNC_FUNC_GEQUAL 0x00000206 +#define NV20TCL_STENCIL_FUNC_FUNC_ALWAYS 0x00000207 +#define NV20TCL_STENCIL_FUNC_REF 0x00000368 +#define NV20TCL_STENCIL_FUNC_MASK 0x0000036c +#define NV20TCL_STENCIL_OP_FAIL 0x00000370 +#define NV20TCL_STENCIL_OP_FAIL_ZERO 0x00000000 +#define NV20TCL_STENCIL_OP_FAIL_INVERT 0x0000150a +#define NV20TCL_STENCIL_OP_FAIL_KEEP 0x00001e00 +#define NV20TCL_STENCIL_OP_FAIL_REPLACE 0x00001e01 +#define NV20TCL_STENCIL_OP_FAIL_INCR 0x00001e02 +#define NV20TCL_STENCIL_OP_FAIL_DECR 0x00001e03 +#define NV20TCL_STENCIL_OP_FAIL_INCR_WRAP 0x00008507 +#define NV20TCL_STENCIL_OP_FAIL_DECR_WRAP 0x00008508 +#define NV20TCL_STENCIL_OP_ZFAIL 0x00000374 +#define NV20TCL_STENCIL_OP_ZFAIL_ZERO 0x00000000 +#define NV20TCL_STENCIL_OP_ZFAIL_INVERT 0x0000150a +#define NV20TCL_STENCIL_OP_ZFAIL_KEEP 0x00001e00 +#define NV20TCL_STENCIL_OP_ZFAIL_REPLACE 0x00001e01 +#define NV20TCL_STENCIL_OP_ZFAIL_INCR 0x00001e02 +#define NV20TCL_STENCIL_OP_ZFAIL_DECR 0x00001e03 +#define NV20TCL_STENCIL_OP_ZFAIL_INCR_WRAP 0x00008507 +#define NV20TCL_STENCIL_OP_ZFAIL_DECR_WRAP 0x00008508 +#define NV20TCL_STENCIL_OP_ZPASS 0x00000378 +#define NV20TCL_STENCIL_OP_ZPASS_ZERO 0x00000000 +#define NV20TCL_STENCIL_OP_ZPASS_INVERT 0x0000150a +#define NV20TCL_STENCIL_OP_ZPASS_KEEP 0x00001e00 +#define NV20TCL_STENCIL_OP_ZPASS_REPLACE 0x00001e01 +#define NV20TCL_STENCIL_OP_ZPASS_INCR 0x00001e02 +#define NV20TCL_STENCIL_OP_ZPASS_DECR 0x00001e03 +#define NV20TCL_STENCIL_OP_ZPASS_INCR_WRAP 0x00008507 +#define NV20TCL_STENCIL_OP_ZPASS_DECR_WRAP 0x00008508 +#define NV20TCL_SHADE_MODEL 0x0000037c +#define NV20TCL_SHADE_MODEL_FLAT 0x00001d00 +#define NV20TCL_SHADE_MODEL_SMOOTH 0x00001d01 +#define NV20TCL_LINE_WIDTH 0x00000380 +#define NV20TCL_POLYGON_OFFSET_FACTOR 0x00000384 +#define NV20TCL_POLYGON_OFFSET_UNITS 0x00000388 +#define NV20TCL_POLYGON_MODE_FRONT 0x0000038c +#define NV20TCL_POLYGON_MODE_FRONT_POINT 0x00001b00 +#define NV20TCL_POLYGON_MODE_FRONT_LINE 0x00001b01 +#define NV20TCL_POLYGON_MODE_FRONT_FILL 0x00001b02 +#define NV20TCL_POLYGON_MODE_BACK 0x00000390 +#define NV20TCL_POLYGON_MODE_BACK_POINT 0x00001b00 +#define NV20TCL_POLYGON_MODE_BACK_LINE 0x00001b01 +#define NV20TCL_POLYGON_MODE_BACK_FILL 0x00001b02 +#define NV20TCL_DEPTH_RANGE_NEAR 0x00000394 +#define NV20TCL_DEPTH_RANGE_FAR 0x00000398 +#define NV20TCL_CULL_FACE 0x0000039c +#define NV20TCL_CULL_FACE_FRONT 0x00000404 +#define NV20TCL_CULL_FACE_BACK 0x00000405 +#define NV20TCL_CULL_FACE_FRONT_AND_BACK 0x00000408 +#define NV20TCL_FRONT_FACE 0x000003a0 +#define NV20TCL_FRONT_FACE_CW 0x00000900 +#define NV20TCL_FRONT_FACE_CCW 0x00000901 +#define NV20TCL_NORMALIZE_ENABLE 0x000003a4 +#define NV20TCL_SEPARATE_SPECULAR_ENABLE 0x000003b8 +#define NV20TCL_ENABLED_LIGHTS 0x000003bc +#define NV20TCL_CLIP_PLANE_ENABLE(x) (0x000003c0+((x)*4)) +#define NV20TCL_CLIP_PLANE_ENABLE__SIZE 0x00000010 +#define NV20TCL_TX_MATRIX_ENABLE(x) (0x00000420+((x)*4)) +#define NV20TCL_TX_MATRIX_ENABLE__SIZE 0x00000004 +#define NV20TCL_POINT_SIZE 0x0000043c +#define NV20TCL_MODELVIEW_MATRIX(x) (0x00000480+((x)*4)) +#define NV20TCL_MODELVIEW_MATRIX__SIZE 0x00000010 +#define NV20TCL_PROJECTION_MATRIX(x) (0x00000680+((x)*4)) +#define NV20TCL_PROJECTION_MATRIX__SIZE 0x00000010 +#define NV20TCL_TX0_MATRIX(x) (0x000006c0+((x)*4)) +#define NV20TCL_TX0_MATRIX__SIZE 0x00000010 +#define NV20TCL_TX1_MATRIX(x) (0x00000700+((x)*4)) +#define NV20TCL_TX1_MATRIX__SIZE 0x00000010 +#define NV20TCL_TX2_MATRIX(x) (0x00000740+((x)*4)) +#define NV20TCL_TX2_MATRIX__SIZE 0x00000010 +#define NV20TCL_TX3_MATRIX(x) (0x00000780+((x)*4)) +#define NV20TCL_TX3_MATRIX__SIZE 0x00000010 +#define NV20TCL_FOG_EQUATION_CONSTANT 0x000009c0 +#define NV20TCL_FOG_EQUATION_LINEAR 0x000009c4 +#define NV20TCL_FOG_EQUATION_QUADRATIC 0x000009c8 +#define NV20TCL_VIEWPORT_SCALE0_X 0x00000a20 +#define NV20TCL_VIEWPORT_SCALE0_Y 0x00000a24 +#define NV20TCL_VIEWPORT_SCALE0_Z 0x00000a28 +#define NV20TCL_VIEWPORT_SCALE0_W 0x00000a2c +#define NV20TCL_POINT_PARAMETER(x) (0x00000a30+((x)*4)) +#define NV20TCL_POINT_PARAMETER__SIZE 0x00000007 +#define NV20TCL_RC_CONSTANT_COLOR0(x) (0x00000a60+((x)*4)) +#define NV20TCL_RC_CONSTANT_COLOR0__SIZE 0x00000008 +#define NV20TCL_RC_CONSTANT_COLOR1(x) (0x00000a80+((x)*4)) +#define NV20TCL_RC_CONSTANT_COLOR1__SIZE 0x00000008 +#define NV20TCL_RC_OUT_ALPHA(x) (0x00000aa0+((x)*4)) +#define NV20TCL_RC_OUT_ALPHA__SIZE 0x00000008 +#define NV20TCL_RC_IN_RGB(x) (0x00000ac0+((x)*4)) +#define NV20TCL_RC_IN_RGB__SIZE 0x00000008 +#define NV20TCL_VIEWPORT_SCALE1_X 0x00000af0 +#define NV20TCL_VIEWPORT_SCALE1_Y 0x00000af4 +#define NV20TCL_VIEWPORT_SCALE1_Z 0x00000af8 +#define NV20TCL_VIEWPORT_SCALE1_W 0x00000afc +#define NV20TCL_VP_UPLOAD_INST(x) (0x00000b00+((x)*4)) +#define NV20TCL_VP_UPLOAD_INST__SIZE 0x00000004 +#define NV20TCL_VP_UPLOAD_CONST(x) (0x00000b80+((x)*4)) +#define NV20TCL_VP_UPLOAD_CONST__SIZE 0x00000004 +#define NV20TCL_POLYGON_STIPPLE_ENABLE 0x0000147c +#define NV20TCL_POLYGON_STIPPLE_PATTERN(x) (0x00001480+((x)*4)) +#define NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE 0x00000020 +#define NV20TCL_VERTEX_POS_3F_X 0x00001500 +#define NV20TCL_VERTEX_POS_3F_Y 0x00001504 +#define NV20TCL_VERTEX_POS_3F_Z 0x00001508 +#define NV20TCL_VERTEX_POS_4F_X 0x00001518 +#define NV20TCL_VERTEX_POS_4F_Y 0x0000151c +#define NV20TCL_VERTEX_POS_4F_Z 0x00001520 +#define NV20TCL_VERTEX_POS_3I_XY 0x00001528 +#define NV20TCL_VERTEX_POS_3I_XY_X_SHIFT 0 +#define NV20TCL_VERTEX_POS_3I_XY_X_MASK 0x0000ffff +#define NV20TCL_VERTEX_POS_3I_XY_Y_SHIFT 16 +#define NV20TCL_VERTEX_POS_3I_XY_Y_MASK 0xffff0000 +#define NV20TCL_VERTEX_POS_3I_Z 0x0000152c +#define NV20TCL_VERTEX_POS_3I_Z_Z_SHIFT 0 +#define NV20TCL_VERTEX_POS_3I_Z_Z_MASK 0x0000ffff +#define NV20TCL_VERTEX_NOR_3F_X 0x00001530 +#define NV20TCL_VERTEX_NOR_3F_Y 0x00001534 +#define NV20TCL_VERTEX_NOR_3F_Z 0x00001538 +#define NV20TCL_VERTEX_NOR_3I_XY 0x00001540 +#define NV20TCL_VERTEX_NOR_3I_XY_X_SHIFT 0 +#define NV20TCL_VERTEX_NOR_3I_XY_X_MASK 0x0000ffff +#define NV20TCL_VERTEX_NOR_3I_XY_Y_SHIFT 16 +#define NV20TCL_VERTEX_NOR_3I_XY_Y_MASK 0xffff0000 +#define NV20TCL_VERTEX_NOR_3I_Z 0x00001544 +#define NV20TCL_VERTEX_NOR_3I_Z_Z_SHIFT 0 +#define NV20TCL_VERTEX_NOR_3I_Z_Z_MASK 0x0000ffff +#define NV20TCL_VERTEX_COL_4F_X 0x00001550 +#define NV20TCL_VERTEX_COL_4F_Y 0x00001554 +#define NV20TCL_VERTEX_COL_4F_Z 0x00001558 +#define NV20TCL_VERTEX_COL_4F_W 0x0000155c +#define NV20TCL_VERTEX_COL_3F_X 0x00001560 +#define NV20TCL_VERTEX_COL_3F_Y 0x00001564 +#define NV20TCL_VERTEX_COL_3F_Z 0x00001568 +#define NV20TCL_VERTEX_COL_4I 0x0000156c +#define NV20TCL_VERTEX_COL_4I_R_SHIFT 0 +#define NV20TCL_VERTEX_COL_4I_R_MASK 0x000000ff +#define NV20TCL_VERTEX_COL_4I_G_SHIFT 8 +#define NV20TCL_VERTEX_COL_4I_G_MASK 0x0000ff00 +#define NV20TCL_VERTEX_COL_4I_B_SHIFT 16 +#define NV20TCL_VERTEX_COL_4I_B_MASK 0x00ff0000 +#define NV20TCL_VERTEX_COL_4I_A_SHIFT 24 +#define NV20TCL_VERTEX_COL_4I_A_MASK 0xff000000 +#define NV20TCL_VERTEX_COL2_3F_X 0x00001580 +#define NV20TCL_VERTEX_COL2_3F_Y 0x00001584 +#define NV20TCL_VERTEX_COL2_3F_Z 0x00001588 +#define NV20TCL_VERTEX_COL2_4I 0x0000158c +#define NV20TCL_VERTEX_COL2_4I_R_SHIFT 0 +#define NV20TCL_VERTEX_COL2_4I_R_MASK 0x000000ff +#define NV20TCL_VERTEX_COL2_4I_G_SHIFT 8 +#define NV20TCL_VERTEX_COL2_4I_G_MASK 0x0000ff00 +#define NV20TCL_VERTEX_COL2_4I_B_SHIFT 16 +#define NV20TCL_VERTEX_COL2_4I_B_MASK 0x00ff0000 +#define NV20TCL_VERTEX_COL2_4I_A_SHIFT 24 +#define NV20TCL_VERTEX_COL2_4I_A_MASK 0xff000000 +#define NV20TCL_VERTEX_TX0_2F_S 0x00001590 +#define NV20TCL_VERTEX_TX0_2F_T 0x00001594 +#define NV20TCL_VERTEX_TX0_2I 0x00001598 +#define NV20TCL_VERTEX_TX0_2I_S_SHIFT 0 +#define NV20TCL_VERTEX_TX0_2I_S_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX0_2I_T_SHIFT 16 +#define NV20TCL_VERTEX_TX0_2I_T_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX0_4F_S 0x000015a0 +#define NV20TCL_VERTEX_TX0_4F_T 0x000015a4 +#define NV20TCL_VERTEX_TX0_4F_R 0x000015a8 +#define NV20TCL_VERTEX_TX0_4F_Q 0x000015ac +#define NV20TCL_VERTEX_TX0_4I_ST 0x000015b0 +#define NV20TCL_VERTEX_TX0_4I_ST_S_SHIFT 0 +#define NV20TCL_VERTEX_TX0_4I_ST_S_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX0_4I_ST_T_SHIFT 16 +#define NV20TCL_VERTEX_TX0_4I_ST_T_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX0_4I_RQ 0x000015b4 +#define NV20TCL_VERTEX_TX0_4I_RQ_R_SHIFT 0 +#define NV20TCL_VERTEX_TX0_4I_RQ_R_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX0_4I_RQ_Q_SHIFT 16 +#define NV20TCL_VERTEX_TX0_4I_RQ_Q_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX1_2F_S 0x000015b8 +#define NV20TCL_VERTEX_TX1_2F_T 0x000015bc +#define NV20TCL_VERTEX_TX1_2I 0x000015c0 +#define NV20TCL_VERTEX_TX1_2I_S_SHIFT 0 +#define NV20TCL_VERTEX_TX1_2I_S_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX1_2I_T_SHIFT 16 +#define NV20TCL_VERTEX_TX1_2I_T_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX1_4F_S 0x000015c8 +#define NV20TCL_VERTEX_TX1_4F_T 0x000015cc +#define NV20TCL_VERTEX_TX1_4F_R 0x000015d0 +#define NV20TCL_VERTEX_TX1_4F_Q 0x000015d4 +#define NV20TCL_VERTEX_TX1_4I_ST 0x000015d8 +#define NV20TCL_VERTEX_TX1_4I_ST_S_SHIFT 0 +#define NV20TCL_VERTEX_TX1_4I_ST_S_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX1_4I_ST_T_SHIFT 16 +#define NV20TCL_VERTEX_TX1_4I_ST_T_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX1_4I_RQ 0x000015dc +#define NV20TCL_VERTEX_TX1_4I_RQ_R_SHIFT 0 +#define NV20TCL_VERTEX_TX1_4I_RQ_R_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX1_4I_RQ_Q_SHIFT 16 +#define NV20TCL_VERTEX_TX1_4I_RQ_Q_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX2_2F_S 0x000015e0 +#define NV20TCL_VERTEX_TX2_2F_T 0x000015e4 +#define NV20TCL_VERTEX_TX2_2I 0x000015e8 +#define NV20TCL_VERTEX_TX2_2I_S_SHIFT 0 +#define NV20TCL_VERTEX_TX2_2I_S_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX2_2I_T_SHIFT 16 +#define NV20TCL_VERTEX_TX2_2I_T_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX2_4F_S 0x000015f0 +#define NV20TCL_VERTEX_TX2_4F_T 0x000015f4 +#define NV20TCL_VERTEX_TX2_4F_R 0x000015f8 +#define NV20TCL_VERTEX_TX2_4F_Q 0x000015fc +#define NV20TCL_VERTEX_TX2_4I_ST 0x00001600 +#define NV20TCL_VERTEX_TX2_4I_ST_S_SHIFT 0 +#define NV20TCL_VERTEX_TX2_4I_ST_S_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX2_4I_ST_T_SHIFT 16 +#define NV20TCL_VERTEX_TX2_4I_ST_T_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX2_4I_RQ 0x00001604 +#define NV20TCL_VERTEX_TX2_4I_RQ_R_SHIFT 0 +#define NV20TCL_VERTEX_TX2_4I_RQ_R_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX2_4I_RQ_Q_SHIFT 16 +#define NV20TCL_VERTEX_TX2_4I_RQ_Q_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX3_2F_S 0x00001608 +#define NV20TCL_VERTEX_TX3_2F_T 0x0000160c +#define NV20TCL_VERTEX_TX3_2I 0x00001610 +#define NV20TCL_VERTEX_TX3_2I_S_SHIFT 0 +#define NV20TCL_VERTEX_TX3_2I_S_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX3_2I_T_SHIFT 16 +#define NV20TCL_VERTEX_TX3_2I_T_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX3_4F_S 0x00001620 +#define NV20TCL_VERTEX_TX3_4F_T 0x00001624 +#define NV20TCL_VERTEX_TX3_4F_R 0x00001628 +#define NV20TCL_VERTEX_TX3_4F_Q 0x0000162c +#define NV20TCL_VERTEX_TX3_4I_ST 0x00001630 +#define NV20TCL_VERTEX_TX3_4I_ST_S_SHIFT 0 +#define NV20TCL_VERTEX_TX3_4I_ST_S_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX3_4I_ST_T_SHIFT 16 +#define NV20TCL_VERTEX_TX3_4I_ST_T_MASK 0xffff0000 +#define NV20TCL_VERTEX_TX3_4I_RQ 0x00001634 +#define NV20TCL_VERTEX_TX3_4I_RQ_R_SHIFT 0 +#define NV20TCL_VERTEX_TX3_4I_RQ_R_MASK 0x0000ffff +#define NV20TCL_VERTEX_TX3_4I_RQ_Q_SHIFT 16 +#define NV20TCL_VERTEX_TX3_4I_RQ_Q_MASK 0xffff0000 +#define NV20TCL_EDGEFLAG_ENABLE 0x000016bc +#define NV20TCL_VERTEX_ATTR_OFFSET(x) (0x00001720+((x)*4)) +#define NV20TCL_VERTEX_ATTR_OFFSET__SIZE 0x00000010 +#define NV20TCL_VERTEX_ARRAY_FORMAT(x) (0x00001760+((x)*4)) +#define NV20TCL_VERTEX_ARRAY_FORMAT__SIZE 0x00000010 +#define NV20TCL_VERTEX_ARRAY_FORMAT_TYPE_SHIFT 0 +#define NV20TCL_VERTEX_ARRAY_FORMAT_TYPE_MASK 0x0000000f +#define NV20TCL_VERTEX_ARRAY_FORMAT_FIELDS_SHIFT 4 +#define NV20TCL_VERTEX_ARRAY_FORMAT_FIELDS_MASK 0x000000f0 +#define NV20TCL_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT 8 +#define NV20TCL_VERTEX_ARRAY_FORMAT_STRIDE_MASK 0x0000ff00 +#define NV20TCL_COLOR_LOGIC_OP_ENABLE 0x000017bc +#define NV20TCL_COLOR_LOGIC_OP_OP 0x000017c0 +#define NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE 0x000017c4 +#define NV20TCL_TX_SHADER_CULL_MODE 0x000017f8 +#define NV20TCL_VERTEX_BEGIN_END 0x000017fc +#define NV20TCL_VERTEX_BUFFER_DRAW_ARRAYS 0x00001810 +#define NV20TCL_VERTEX_ARRAY_DATA 0x00001818 +#define NV20TCL_TX_OFFSET(x) (0x00001b00+((x)*64)) +#define NV20TCL_TX_OFFSET__SIZE 0x00000004 +#define NV20TCL_TX_FORMAT(x) (0x00001b04+((x)*64)) +#define NV20TCL_TX_FORMAT__SIZE 0x00000004 +#define NV20TCL_TX_WRAP(x) (0x00001b08+((x)*64)) +#define NV20TCL_TX_WRAP__SIZE 0x00000004 +#define NV20TCL_TX_ENABLE(x) (0x00001b0c+((x)*64)) +#define NV20TCL_TX_ENABLE__SIZE 0x00000004 +#define NV20TCL_TX_FILTER(x) (0x00001b14+((x)*64)) +#define NV20TCL_TX_FILTER__SIZE 0x00000004 +#define NV20TCL_TX_BORDER_COLOR(x) (0x00001b24+((x)*64)) +#define NV20TCL_TX_BORDER_COLOR__SIZE 0x00000004 +#define NV20TCL_SCISSOR_HORIZ 0x00001c30 +#define NV20TCL_SCISSOR_VERT 0x00001c50 +#define NV20TCL_MULTISAMPLE_CONTROL 0x00001d7c +#define NV20TCL_CLEAR_VALUE 0x00001d90 +#define NV20TCL_CLEAR_BUFFERS 0x00001d94 +#define NV20TCL_RC_COLOR0 0x00001e20 +#define NV20TCL_RC_COLOR1 0x00001e24 +#define NV20TCL_RC_OUT_RGB(x) (0x00001e40+((x)*4)) +#define NV20TCL_RC_OUT_RGB__SIZE 0x00000008 +#define NV20TCL_RC_ENABLE 0x00001e60 +#define NV20TCL_TX_SHADER_OP 0x00001e70 +#define NV20TCL_VP_UPLOAD_CONST_ID 0x00001ea4 + + +#define NV17TCL 0x00000099 + +#define NV17TCL_DMA_IN_MEMORY4 0x000001ac +#define NV17TCL_DMA_IN_MEMORY5 0x000001b0 +#define NV17TCL_COLOR_MASK_ENABLE 0x000002bc +#define NV17TCL_LMA_DEPTH_BUFFER_PITCH 0x00000d5c +#define NV17TCL_LMA_DEPTH_BUFFER_OFFSET 0x00000d60 +#define NV17TCL_LMA_DEPTH_FILL_VALUE 0x00000d68 +#define NV17TCL_LMA_DEPTH_BUFFER_CLEAR 0x00000d6c +#define NV17TCL_LMA_DEPTH_ENABLE 0x00001658 + + +#define NV20_SWIZZLED_SURFACE 0x0000009e + + + +#define NV12_IMAGE_BLIT 0x0000009f + + + +#define NV30_CONTEXT_SURFACES_2D 0x00000362 + + + +#define NV30_STRETCHED_IMAGE_FROM_CPU 0x00000366 + + + +#define NV30_TEXTURE_FROM_CPU 0x0000037b + + + +#define NV30_SCALED_IMAGE_FROM_MEMORY 0x00000389 + + + +#define NV30_IMAGE_FROM_CPU 0x0000038a + + + +#define NV30TCL 0x00000397 + + + +#define NV30_SWIZZLED_SURFACE 0x0000039e + + + +#define NV35TCL 0x00000497 + + + +#define NV25TCL 0x00000597 + +#define NV25TCL_DMA_IN_MEMORY4 0x0000019c +#define NV25TCL_DMA_IN_MEMORY5 0x000001a0 +#define NV25TCL_DMA_IN_MEMORY8 0x000001ac +#define NV25TCL_DMA_IN_MEMORY9 0x000001b0 + + +#define NV34TCL 0x00000697 + +#define NV34TCL_NOP 0x00000100 +#define NV34TCL_NOTIFY 0x00000104 +#define NV34TCL_DMA_NOTIFY 0x00000180 +#define NV34TCL_DMA_TEXTURE0 0x00000184 +#define NV34TCL_DMA_TEXTURE1 0x00000188 +#define NV34TCL_DMA_COLOR1 0x0000018c +#define NV34TCL_DMA_COLOR0 0x00000194 +#define NV34TCL_DMA_ZETA 0x00000198 +#define NV34TCL_DMA_VTXBUF0 0x0000019c +#define NV34TCL_DMA_VTXBUF1 0x000001a0 +#define NV34TCL_DMA_FENCE 0x000001a4 +#define NV34TCL_DMA_QUERY 0x000001a8 +#define NV34TCL_DMA_IN_MEMORY7 0x000001ac +#define NV34TCL_DMA_IN_MEMORY8 0x000001b0 +#define NV34TCL_RT_HORIZ 0x00000200 +#define NV34TCL_RT_HORIZ_X_SHIFT 0 +#define NV34TCL_RT_HORIZ_X_MASK 0x0000ffff +#define NV34TCL_RT_HORIZ_W_SHIFT 16 +#define NV34TCL_RT_HORIZ_W_MASK 0xffff0000 +#define NV34TCL_RT_VERT 0x00000204 +#define NV34TCL_RT_VERT_Y_SHIFT 0 +#define NV34TCL_RT_VERT_Y_MASK 0x0000ffff +#define NV34TCL_RT_VERT_H_SHIFT 16 +#define NV34TCL_RT_VERT_H_MASK 0xffff0000 +#define NV34TCL_RT_FORMAT 0x00000208 +#define NV34TCL_RT_FORMAT_TYPE_SHIFT 8 +#define NV34TCL_RT_FORMAT_TYPE_MASK 0x00000f00 +#define NV34TCL_RT_FORMAT_TYPE_LINEAR 0x00000100 +#define NV34TCL_RT_FORMAT_TYPE_SWIZZLED 0x00000200 +#define NV34TCL_RT_FORMAT_ZETA_SHIFT 5 +#define NV34TCL_RT_FORMAT_ZETA_MASK 0x000000e0 +#define NV34TCL_RT_FORMAT_ZETA_Z16 0x00000020 +#define NV34TCL_RT_FORMAT_ZETA_Z24S8 0x00000040 +#define NV34TCL_RT_FORMAT_COLOR_SHIFT 0 +#define NV34TCL_RT_FORMAT_COLOR_MASK 0x0000001f +#define NV34TCL_RT_FORMAT_COLOR_R5G6B5 0x00000003 +#define NV34TCL_RT_FORMAT_COLOR_X8R8G8B8 0x00000005 +#define NV34TCL_RT_FORMAT_COLOR_A8R8G8B8 0x00000008 +#define NV34TCL_RT_FORMAT_COLOR_B8 0x00000009 +#define NV34TCL_RT_FORMAT_COLOR_X8B8G8R8 0x0000000f +#define NV34TCL_RT_FORMAT_COLOR_A8B8G8R8 0x00000010 +#define NV34TCL_COLOR0_PITCH 0x0000020c +#define NV34TCL_COLOR0_PITCH_COLOR0_SHIFT 0 +#define NV34TCL_COLOR0_PITCH_COLOR0_MASK 0x0000ffff +#define NV34TCL_COLOR0_PITCH_ZETA_SHIFT 16 +#define NV34TCL_COLOR0_PITCH_ZETA_MASK 0xffff0000 +#define NV34TCL_COLOR0_OFFSET 0x00000210 +#define NV34TCL_ZETA_OFFSET 0x00000214 +#define NV34TCL_COLOR1_OFFSET 0x00000218 +#define NV34TCL_COLOR1_PITCH 0x0000021c +#define NV34TCL_RT_ENABLE 0x00000220 +#define NV34TCL_RT_ENABLE_MRT (1 << 4) +#define NV34TCL_RT_ENABLE_COLOR3 (1 << 3) +#define NV34TCL_RT_ENABLE_COLOR2 (1 << 2) +#define NV34TCL_RT_ENABLE_COLOR1 (1 << 1) +#define NV34TCL_RT_ENABLE_COLOR0 (1 << 0) +#define NV34TCL_LMA_DEPTH_PITCH 0x0000022c +#define NV34TCL_LMA_DEPTH_OFFSET 0x00000230 +#define NV34TCL_TX_UNITS_ENABLE 0x0000023c +#define NV34TCL_TX_UNITS_ENABLE_TX0 (1 << 0) +#define NV34TCL_TX_UNITS_ENABLE_TX1 (1 << 1) +#define NV34TCL_TX_UNITS_ENABLE_TX2 (1 << 2) +#define NV34TCL_TX_UNITS_ENABLE_TX3 (1 << 3) +#define NV34TCL_TX_MATRIX_ENABLE(x) (0x00000240+((x)*4)) +#define NV34TCL_TX_MATRIX_ENABLE__SIZE 0x00000004 +#define NV34TCL_UNK0250(x) (0x00000250+((x)*4)) +#define NV34TCL_UNK0250__SIZE 0x00000004 +#define NV34TCL_VIEWPORT_TX_ORIGIN 0x000002b8 +#define NV34TCL_VIEWPORT_TX_ORIGIN_X_SHIFT 0 +#define NV34TCL_VIEWPORT_TX_ORIGIN_X_MASK 0x0000ffff +#define NV34TCL_VIEWPORT_TX_ORIGIN_Y_SHIFT 16 +#define NV34TCL_VIEWPORT_TX_ORIGIN_Y_MASK 0xffff0000 +#define NV34TCL_VIEWPORT_CLIP_HORIZ(x) (0x000002c0+((x)*8)) +#define NV34TCL_VIEWPORT_CLIP_HORIZ__SIZE 0x00000008 +#define NV34TCL_VIEWPORT_CLIP_HORIZ_L_SHIFT 0 +#define NV34TCL_VIEWPORT_CLIP_HORIZ_L_MASK 0x0000ffff +#define NV34TCL_VIEWPORT_CLIP_HORIZ_R_SHIFT 16 +#define NV34TCL_VIEWPORT_CLIP_HORIZ_R_MASK 0xffff0000 +#define NV34TCL_VIEWPORT_CLIP_VERT(x) (0x000002c4+((x)*8)) +#define NV34TCL_VIEWPORT_CLIP_VERT__SIZE 0x00000008 +#define NV34TCL_VIEWPORT_CLIP_VERT_T_SHIFT 0 +#define NV34TCL_VIEWPORT_CLIP_VERT_T_MASK 0x0000ffff +#define NV34TCL_VIEWPORT_CLIP_VERT_D_SHIFT 16 +#define NV34TCL_VIEWPORT_CLIP_VERT_D_MASK 0xffff0000 +#define NV34TCL_DITHER_ENABLE 0x00000300 +#define NV34TCL_ALPHA_FUNC_ENABLE 0x00000304 +#define NV34TCL_ALPHA_FUNC_FUNC 0x00000308 +#define NV34TCL_ALPHA_FUNC_FUNC_NEVER 0x00000200 +#define NV34TCL_ALPHA_FUNC_FUNC_LESS 0x00000201 +#define NV34TCL_ALPHA_FUNC_FUNC_EQUAL 0x00000202 +#define NV34TCL_ALPHA_FUNC_FUNC_LEQUAL 0x00000203 +#define NV34TCL_ALPHA_FUNC_FUNC_GREATER 0x00000204 +#define NV34TCL_ALPHA_FUNC_FUNC_GREATER 0x00000204 +#define NV34TCL_ALPHA_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV34TCL_ALPHA_FUNC_FUNC_GEQUAL 0x00000206 +#define NV34TCL_ALPHA_FUNC_FUNC_ALWAYS 0x00000207 +#define NV34TCL_ALPHA_FUNC_REF 0x0000030c +#define NV34TCL_BLEND_FUNC_ENABLE 0x00000310 +#define NV34TCL_BLEND_FUNC_SRC 0x00000314 +#define NV34TCL_BLEND_FUNC_SRC_RGB_SHIFT 0 +#define NV34TCL_BLEND_FUNC_SRC_RGB_MASK 0x0000ffff +#define NV34TCL_BLEND_FUNC_SRC_RGB_ZERO 0x00000000 +#define NV34TCL_BLEND_FUNC_SRC_RGB_ONE 0x00000001 +#define NV34TCL_BLEND_FUNC_SRC_RGB_SRC_COLOR 0x00000300 +#define NV34TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV34TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA 0x00000302 +#define NV34TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV34TCL_BLEND_FUNC_SRC_RGB_DST_ALPHA 0x00000304 +#define NV34TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV34TCL_BLEND_FUNC_SRC_RGB_DST_COLOR 0x00000306 +#define NV34TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_COLOR 0x00000307 +#define NV34TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA_SATURATE 0x00000308 +#define NV34TCL_BLEND_FUNC_SRC_RGB_CONSTANT_COLOR 0x00008001 +#define NV34TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV34TCL_BLEND_FUNC_SRC_RGB_CONSTANT_ALPHA 0x00008003 +#define NV34TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_SHIFT 16 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_MASK 0xffff0000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_ZERO 0x00000000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_ONE 0x00010000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_SRC_COLOR 0x03000000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_COLOR 0x03010000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA 0x03020000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_ALPHA 0x03030000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_DST_ALPHA 0x03040000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_ALPHA 0x03050000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_DST_COLOR 0x03060000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_COLOR 0x03070000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA_SATURATE 0x03080000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_COLOR 0x80010000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_COLOR 0x80020000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_ALPHA 0x80030000 +#define NV34TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_ALPHA 0x80040000 +#define NV34TCL_BLEND_FUNC_DST 0x00000318 +#define NV34TCL_BLEND_FUNC_DST_RGB_SHIFT 0 +#define NV34TCL_BLEND_FUNC_DST_RGB_MASK 0x0000ffff +#define NV34TCL_BLEND_FUNC_DST_RGB_ZERO 0x00000000 +#define NV34TCL_BLEND_FUNC_DST_RGB_ONE 0x00000001 +#define NV34TCL_BLEND_FUNC_DST_RGB_SRC_COLOR 0x00000300 +#define NV34TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV34TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA 0x00000302 +#define NV34TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV34TCL_BLEND_FUNC_DST_RGB_DST_ALPHA 0x00000304 +#define NV34TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV34TCL_BLEND_FUNC_DST_RGB_DST_COLOR 0x00000306 +#define NV34TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_COLOR 0x00000307 +#define NV34TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA_SATURATE 0x00000308 +#define NV34TCL_BLEND_FUNC_DST_RGB_CONSTANT_COLOR 0x00008001 +#define NV34TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV34TCL_BLEND_FUNC_DST_RGB_CONSTANT_ALPHA 0x00008003 +#define NV34TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_SHIFT 16 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_MASK 0xffff0000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_ZERO 0x00000000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_ONE 0x00010000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_SRC_COLOR 0x03000000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_COLOR 0x03010000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA 0x03020000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_ALPHA 0x03030000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_DST_ALPHA 0x03040000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_ALPHA 0x03050000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_DST_COLOR 0x03060000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_COLOR 0x03070000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA_SATURATE 0x03080000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_COLOR 0x80010000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_COLOR 0x80020000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_ALPHA 0x80030000 +#define NV34TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_ALPHA 0x80040000 +#define NV34TCL_BLEND_COLOR 0x0000031c +#define NV34TCL_BLEND_EQUATION 0x00000320 +#define NV34TCL_BLEND_EQUATION_FUNC_ADD 0x00008006 +#define NV34TCL_BLEND_EQUATION_MIN 0x00008007 +#define NV34TCL_BLEND_EQUATION_MAX 0x00008008 +#define NV34TCL_BLEND_EQUATION_FUNC_SUBTRACT 0x0000800a +#define NV34TCL_BLEND_EQUATION_FUNC_REVERSE_SUBTRACT 0x0000800b +#define NV34TCL_COLOR_MASK 0x00000324 +#define NV34TCL_COLOR_MASK_B_SHIFT 0 +#define NV34TCL_COLOR_MASK_B_MASK 0x000000ff +#define NV34TCL_COLOR_MASK_G_SHIFT 8 +#define NV34TCL_COLOR_MASK_G_MASK 0x0000ff00 +#define NV34TCL_COLOR_MASK_R_SHIFT 16 +#define NV34TCL_COLOR_MASK_R_MASK 0x00ff0000 +#define NV34TCL_COLOR_MASK_A_SHIFT 24 +#define NV34TCL_COLOR_MASK_A_MASK 0xff000000 +#define NV34TCL_STENCIL_BACK_ENABLE 0x00000328 +#define NV34TCL_STENCIL_BACK_MASK 0x0000032c +#define NV34TCL_STENCIL_BACK_FUNC_FUNC 0x00000330 +#define NV34TCL_STENCIL_BACK_FUNC_FUNC_NEVER 0x00000200 +#define NV34TCL_STENCIL_BACK_FUNC_FUNC_LESS 0x00000201 +#define NV34TCL_STENCIL_BACK_FUNC_FUNC_EQUAL 0x00000202 +#define NV34TCL_STENCIL_BACK_FUNC_FUNC_LEQUAL 0x00000203 +#define NV34TCL_STENCIL_BACK_FUNC_FUNC_GREATER 0x00000204 +#define NV34TCL_STENCIL_BACK_FUNC_FUNC_GREATER 0x00000204 +#define NV34TCL_STENCIL_BACK_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV34TCL_STENCIL_BACK_FUNC_FUNC_GEQUAL 0x00000206 +#define NV34TCL_STENCIL_BACK_FUNC_FUNC_ALWAYS 0x00000207 +#define NV34TCL_STENCIL_BACK_FUNC_REF 0x00000334 +#define NV34TCL_STENCIL_BACK_FUNC_MASK 0x00000338 +#define NV34TCL_STENCIL_BACK_OP_FAIL 0x0000033c +#define NV34TCL_STENCIL_BACK_OP_FAIL_ZERO 0x00000000 +#define NV34TCL_STENCIL_BACK_OP_FAIL_INVERT 0x0000150a +#define NV34TCL_STENCIL_BACK_OP_FAIL_KEEP 0x00001e00 +#define NV34TCL_STENCIL_BACK_OP_FAIL_REPLACE 0x00001e01 +#define NV34TCL_STENCIL_BACK_OP_FAIL_INCR 0x00001e02 +#define NV34TCL_STENCIL_BACK_OP_FAIL_DECR 0x00001e03 +#define NV34TCL_STENCIL_BACK_OP_FAIL_INCR_WRAP 0x00008507 +#define NV34TCL_STENCIL_BACK_OP_FAIL_DECR_WRAP 0x00008508 +#define NV34TCL_STENCIL_BACK_OP_ZFAIL 0x00000340 +#define NV34TCL_STENCIL_BACK_OP_ZFAIL_ZERO 0x00000000 +#define NV34TCL_STENCIL_BACK_OP_ZFAIL_INVERT 0x0000150a +#define NV34TCL_STENCIL_BACK_OP_ZFAIL_KEEP 0x00001e00 +#define NV34TCL_STENCIL_BACK_OP_ZFAIL_REPLACE 0x00001e01 +#define NV34TCL_STENCIL_BACK_OP_ZFAIL_INCR 0x00001e02 +#define NV34TCL_STENCIL_BACK_OP_ZFAIL_DECR 0x00001e03 +#define NV34TCL_STENCIL_BACK_OP_ZFAIL_INCR_WRAP 0x00008507 +#define NV34TCL_STENCIL_BACK_OP_ZFAIL_DECR_WRAP 0x00008508 +#define NV34TCL_STENCIL_BACK_OP_ZPASS 0x00000344 +#define NV34TCL_STENCIL_BACK_OP_ZPASS_ZERO 0x00000000 +#define NV34TCL_STENCIL_BACK_OP_ZPASS_INVERT 0x0000150a +#define NV34TCL_STENCIL_BACK_OP_ZPASS_KEEP 0x00001e00 +#define NV34TCL_STENCIL_BACK_OP_ZPASS_REPLACE 0x00001e01 +#define NV34TCL_STENCIL_BACK_OP_ZPASS_INCR 0x00001e02 +#define NV34TCL_STENCIL_BACK_OP_ZPASS_DECR 0x00001e03 +#define NV34TCL_STENCIL_BACK_OP_ZPASS_INCR_WRAP 0x00008507 +#define NV34TCL_STENCIL_BACK_OP_ZPASS_DECR_WRAP 0x00008508 +#define NV34TCL_STENCIL_FRONT_ENABLE 0x00000348 +#define NV34TCL_STENCIL_FRONT_MASK 0x0000034c +#define NV34TCL_STENCIL_FRONT_FUNC_FUNC 0x00000350 +#define NV34TCL_STENCIL_FRONT_FUNC_FUNC_NEVER 0x00000200 +#define NV34TCL_STENCIL_FRONT_FUNC_FUNC_LESS 0x00000201 +#define NV34TCL_STENCIL_FRONT_FUNC_FUNC_EQUAL 0x00000202 +#define NV34TCL_STENCIL_FRONT_FUNC_FUNC_LEQUAL 0x00000203 +#define NV34TCL_STENCIL_FRONT_FUNC_FUNC_GREATER 0x00000204 +#define NV34TCL_STENCIL_FRONT_FUNC_FUNC_GREATER 0x00000204 +#define NV34TCL_STENCIL_FRONT_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV34TCL_STENCIL_FRONT_FUNC_FUNC_GEQUAL 0x00000206 +#define NV34TCL_STENCIL_FRONT_FUNC_FUNC_ALWAYS 0x00000207 +#define NV34TCL_STENCIL_FRONT_FUNC_REF 0x00000354 +#define NV34TCL_STENCIL_FRONT_FUNC_MASK 0x00000358 +#define NV34TCL_STENCIL_FRONT_OP_FAIL 0x0000035c +#define NV34TCL_STENCIL_FRONT_OP_FAIL_ZERO 0x00000000 +#define NV34TCL_STENCIL_FRONT_OP_FAIL_INVERT 0x0000150a +#define NV34TCL_STENCIL_FRONT_OP_FAIL_KEEP 0x00001e00 +#define NV34TCL_STENCIL_FRONT_OP_FAIL_REPLACE 0x00001e01 +#define NV34TCL_STENCIL_FRONT_OP_FAIL_INCR 0x00001e02 +#define NV34TCL_STENCIL_FRONT_OP_FAIL_DECR 0x00001e03 +#define NV34TCL_STENCIL_FRONT_OP_FAIL_INCR_WRAP 0x00008507 +#define NV34TCL_STENCIL_FRONT_OP_FAIL_DECR_WRAP 0x00008508 +#define NV34TCL_STENCIL_FRONT_OP_ZFAIL 0x00000360 +#define NV34TCL_STENCIL_FRONT_OP_ZFAIL_ZERO 0x00000000 +#define NV34TCL_STENCIL_FRONT_OP_ZFAIL_INVERT 0x0000150a +#define NV34TCL_STENCIL_FRONT_OP_ZFAIL_KEEP 0x00001e00 +#define NV34TCL_STENCIL_FRONT_OP_ZFAIL_REPLACE 0x00001e01 +#define NV34TCL_STENCIL_FRONT_OP_ZFAIL_INCR 0x00001e02 +#define NV34TCL_STENCIL_FRONT_OP_ZFAIL_DECR 0x00001e03 +#define NV34TCL_STENCIL_FRONT_OP_ZFAIL_INCR_WRAP 0x00008507 +#define NV34TCL_STENCIL_FRONT_OP_ZFAIL_DECR_WRAP 0x00008508 +#define NV34TCL_STENCIL_FRONT_OP_ZPASS 0x00000364 +#define NV34TCL_STENCIL_FRONT_OP_ZPASS_ZERO 0x00000000 +#define NV34TCL_STENCIL_FRONT_OP_ZPASS_INVERT 0x0000150a +#define NV34TCL_STENCIL_FRONT_OP_ZPASS_KEEP 0x00001e00 +#define NV34TCL_STENCIL_FRONT_OP_ZPASS_REPLACE 0x00001e01 +#define NV34TCL_STENCIL_FRONT_OP_ZPASS_INCR 0x00001e02 +#define NV34TCL_STENCIL_FRONT_OP_ZPASS_DECR 0x00001e03 +#define NV34TCL_STENCIL_FRONT_OP_ZPASS_INCR_WRAP 0x00008507 +#define NV34TCL_STENCIL_FRONT_OP_ZPASS_DECR_WRAP 0x00008508 +#define NV34TCL_SHADE_MODEL 0x00000368 +#define NV34TCL_SHADE_MODEL_FLAT 0x00001d00 +#define NV34TCL_SHADE_MODEL_SMOOTH 0x00001d01 +#define NV34TCL_FOG_ENABLE 0x0000036c +#define NV34TCL_FOG_COLOR 0x00000370 +#define NV34TCL_COLOR_LOGIC_OP_ENABLE 0x00000374 +#define NV34TCL_COLOR_LOGIC_OP_OP 0x00000378 +#define NV34TCL_COLOR_LOGIC_OP_OP_CLEAR 0x00001500 +#define NV34TCL_COLOR_LOGIC_OP_OP_AND 0x00001501 +#define NV34TCL_COLOR_LOGIC_OP_OP_AND_REVERSE 0x00001502 +#define NV34TCL_COLOR_LOGIC_OP_OP_COPY 0x00001503 +#define NV34TCL_COLOR_LOGIC_OP_OP_AND_INVERTED 0x00001504 +#define NV34TCL_COLOR_LOGIC_OP_OP_NOOP 0x00001505 +#define NV34TCL_COLOR_LOGIC_OP_OP_XOR 0x00001506 +#define NV34TCL_COLOR_LOGIC_OP_OP_OR 0x00001507 +#define NV34TCL_COLOR_LOGIC_OP_OP_NOR 0x00001508 +#define NV34TCL_COLOR_LOGIC_OP_OP_EQUIV 0x00001509 +#define NV34TCL_COLOR_LOGIC_OP_OP_INVERT 0x0000150a +#define NV34TCL_COLOR_LOGIC_OP_OP_OR_REVERSE 0x0000150b +#define NV34TCL_COLOR_LOGIC_OP_OP_COPY_INVERTED 0x0000150c +#define NV34TCL_COLOR_LOGIC_OP_OP_OR_INVERTED 0x0000150d +#define NV34TCL_COLOR_LOGIC_OP_OP_NAND 0x0000150e +#define NV34TCL_COLOR_LOGIC_OP_OP_SET 0x0000150f +#define NV34TCL_NORMALIZE_ENABLE 0x0000037c +#define NV34TCL_COLOR_MATERIAL 0x00000390 +#define NV34TCL_COLOR_MATERIAL_FRONT_EMISSION_ENABLE (1 << 0) +#define NV34TCL_COLOR_MATERIAL_FRONT_AMBIENT_ENABLE (1 << 2) +#define NV34TCL_COLOR_MATERIAL_FRONT_DIFFUSE_ENABLE (1 << 4) +#define NV34TCL_COLOR_MATERIAL_FRONT_SPECULAR_ENABLE (1 << 6) +#define NV34TCL_COLOR_MATERIAL_BACK_EMISSION_ENABLE (1 << 8) +#define NV34TCL_COLOR_MATERIAL_BACK_AMBIENT_ENABLE (1 << 10) +#define NV34TCL_COLOR_MATERIAL_BACK_DIFFUSE_ENABLE (1 << 12) +#define NV34TCL_COLOR_MATERIAL_BACK_SPECULAR_ENABLE (1 << 14) +#define NV34TCL_DEPTH_RANGE_NEAR 0x00000394 +#define NV34TCL_DEPTH_RANGE_FAR 0x00000398 +#define NV34TCL_COLOR_MATERIAL_FRONT_R 0x000003a0 +#define NV34TCL_COLOR_MATERIAL_FRONT_G 0x000003a4 +#define NV34TCL_COLOR_MATERIAL_FRONT_B 0x000003a8 +#define NV34TCL_COLOR_MATERIAL_FRONT_A 0x000003b4 +#define NV34TCL_LINE_WIDTH 0x000003b8 +#define NV34TCL_LINE_SMOOTH_ENABLE 0x000003bc +#define NV34TCL_CLIP_PLANE_ENABLE(x) (0x00000400+((x)*4)) +#define NV34TCL_CLIP_PLANE_ENABLE__SIZE 0x00000020 +#define NV34TCL_CLIP_PLANE_ENABLE_FALSE 0x00000000 +#define NV34TCL_CLIP_PLANE_ENABLE_EYE_LINEAR 0x00002400 +#define NV34TCL_CLIP_PLANE_ENABLE_OBJECT_LINEAR 0x00002401 +#define NV34TCL_MODELVIEW_MATRIX(x) (0x00000480+((x)*4)) +#define NV34TCL_MODELVIEW_MATRIX__SIZE 0x00000010 +#define NV34TCL_INVERSE_MODELVIEW_MATRIX(x) (0x00000580+((x)*4)) +#define NV34TCL_INVERSE_MODELVIEW_MATRIX__SIZE 0x0000000c +#define NV34TCL_PROJECTION_MATRIX(x) (0x00000680+((x)*4)) +#define NV34TCL_PROJECTION_MATRIX__SIZE 0x00000010 +#define NV34TCL_TX0_MATRIX(x) (0x000006c0+((x)*4)) +#define NV34TCL_TX0_MATRIX__SIZE 0x00000010 +#define NV34TCL_TX1_MATRIX(x) (0x00000700+((x)*4)) +#define NV34TCL_TX1_MATRIX__SIZE 0x00000010 +#define NV34TCL_TX2_MATRIX(x) (0x00000740+((x)*4)) +#define NV34TCL_TX2_MATRIX__SIZE 0x00000010 +#define NV34TCL_TX3_MATRIX(x) (0x00000780+((x)*4)) +#define NV34TCL_TX3_MATRIX__SIZE 0x00000010 +#define NV34TCL_SCISSOR_HORIZ 0x000008c0 +#define NV34TCL_SCISSOR_HORIZ_X_SHIFT 0 +#define NV34TCL_SCISSOR_HORIZ_X_MASK 0x0000ffff +#define NV34TCL_SCISSOR_HORIZ_W_SHIFT 16 +#define NV34TCL_SCISSOR_HORIZ_W_MASK 0xffff0000 +#define NV34TCL_SCISSOR_VERT 0x000008c4 +#define NV34TCL_SCISSOR_VERT_Y_SHIFT 0 +#define NV34TCL_SCISSOR_VERT_Y_MASK 0x0000ffff +#define NV34TCL_SCISSOR_VERT_H_SHIFT 16 +#define NV34TCL_SCISSOR_VERT_H_MASK 0xffff0000 +#define NV34TCL_FOG_COORD_DIST 0x000008c8 +#define NV34TCL_FOG_MODE 0x000008cc +#define NV34TCL_FOG_MODE_EXP 0x00000800 +#define NV34TCL_FOG_MODE_EXP_2 0x00000802 +#define NV34TCL_FOG_MODE_EXP2 0x00000803 +#define NV34TCL_FOG_MODE_LINEAR 0x00000804 +#define NV34TCL_FOG_MODE_LINEAR_2 0x00002601 +#define NV34TCL_FOG_EQUATION_CONSTANT 0x000008d0 +#define NV34TCL_FOG_EQUATION_LINEAR 0x000008d4 +#define NV34TCL_FOG_EQUATION_QUADRATIC 0x000008d8 +#define NV34TCL_FP_ACTIVE_PROGRAM 0x000008e4 +#define NV34TCL_FP_ACTIVE_PROGRAM_DMA0 (1 << 0) +#define NV34TCL_FP_ACTIVE_PROGRAM_DMA1 (1 << 1) +#define NV34TCL_FP_ACTIVE_PROGRAM_OFFSET_SHIFT 2 +#define NV34TCL_FP_ACTIVE_PROGRAM_OFFSET_MASK 0xfffffffc +#define NV34TCL_RC_COLOR0 0x000008ec +#define NV34TCL_RC_COLOR0_B_SHIFT 0 +#define NV34TCL_RC_COLOR0_B_MASK 0x000000ff +#define NV34TCL_RC_COLOR0_G_SHIFT 8 +#define NV34TCL_RC_COLOR0_G_MASK 0x0000ff00 +#define NV34TCL_RC_COLOR0_R_SHIFT 16 +#define NV34TCL_RC_COLOR0_R_MASK 0x00ff0000 +#define NV34TCL_RC_COLOR0_A_SHIFT 24 +#define NV34TCL_RC_COLOR0_A_MASK 0xff000000 +#define NV34TCL_RC_COLOR1 0x000008f0 +#define NV34TCL_RC_COLOR1_B_SHIFT 0 +#define NV34TCL_RC_COLOR1_B_MASK 0x000000ff +#define NV34TCL_RC_COLOR1_G_SHIFT 8 +#define NV34TCL_RC_COLOR1_G_MASK 0x0000ff00 +#define NV34TCL_RC_COLOR1_R_SHIFT 16 +#define NV34TCL_RC_COLOR1_R_MASK 0x00ff0000 +#define NV34TCL_RC_COLOR1_A_SHIFT 24 +#define NV34TCL_RC_COLOR1_A_MASK 0xff000000 +#define NV34TCL_RC_FINAL0 0x000008f4 +#define NV34TCL_RC_FINAL1 0x000008f8 +#define NV34TCL_RC_ENABLE 0x000008fc +#define NV34TCL_RC_IN_ALPHA(x) (0x00000900+((x)*32)) +#define NV34TCL_RC_IN_ALPHA__SIZE 0x00000008 +#define NV34TCL_RC_IN_RGB(x) (0x00000904+((x)*32)) +#define NV34TCL_RC_IN_RGB__SIZE 0x00000008 +#define NV34TCL_RC_CONSTANT_COLOR0(x) (0x00000908+((x)*32)) +#define NV34TCL_RC_CONSTANT_COLOR0__SIZE 0x00000008 +#define NV34TCL_RC_CONSTANT_COLOR0_B_SHIFT 0 +#define NV34TCL_RC_CONSTANT_COLOR0_B_MASK 0x000000ff +#define NV34TCL_RC_CONSTANT_COLOR0_G_SHIFT 8 +#define NV34TCL_RC_CONSTANT_COLOR0_G_MASK 0x0000ff00 +#define NV34TCL_RC_CONSTANT_COLOR0_R_SHIFT 16 +#define NV34TCL_RC_CONSTANT_COLOR0_R_MASK 0x00ff0000 +#define NV34TCL_RC_CONSTANT_COLOR0_A_SHIFT 24 +#define NV34TCL_RC_CONSTANT_COLOR0_A_MASK 0xff000000 +#define NV34TCL_RC_CONSTANT_COLOR1(x) (0x0000090c+((x)*32)) +#define NV34TCL_RC_CONSTANT_COLOR1__SIZE 0x00000008 +#define NV34TCL_RC_CONSTANT_COLOR1_B_SHIFT 0 +#define NV34TCL_RC_CONSTANT_COLOR1_B_MASK 0x000000ff +#define NV34TCL_RC_CONSTANT_COLOR1_G_SHIFT 8 +#define NV34TCL_RC_CONSTANT_COLOR1_G_MASK 0x0000ff00 +#define NV34TCL_RC_CONSTANT_COLOR1_R_SHIFT 16 +#define NV34TCL_RC_CONSTANT_COLOR1_R_MASK 0x00ff0000 +#define NV34TCL_RC_CONSTANT_COLOR1_A_SHIFT 24 +#define NV34TCL_RC_CONSTANT_COLOR1_A_MASK 0xff000000 +#define NV34TCL_RC_OUT_ALPHA(x) (0x00000910+((x)*32)) +#define NV34TCL_RC_OUT_ALPHA__SIZE 0x00000008 +#define NV34TCL_RC_OUT_RGB(x) (0x00000914+((x)*32)) +#define NV34TCL_RC_OUT_RGB__SIZE 0x00000008 +#define NV34TCL_VIEWPORT_HORIZ 0x00000a00 +#define NV34TCL_VIEWPORT_HORIZ_X_SHIFT 0 +#define NV34TCL_VIEWPORT_HORIZ_X_MASK 0x0000ffff +#define NV34TCL_VIEWPORT_HORIZ_W_SHIFT 16 +#define NV34TCL_VIEWPORT_HORIZ_W_MASK 0xffff0000 +#define NV34TCL_VIEWPORT_VERT 0x00000a04 +#define NV34TCL_VIEWPORT_VERT_Y_SHIFT 0 +#define NV34TCL_VIEWPORT_VERT_Y_MASK 0x0000ffff +#define NV34TCL_VIEWPORT_VERT_H_SHIFT 16 +#define NV34TCL_VIEWPORT_VERT_H_MASK 0xffff0000 +#define NV34TCL_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x00000a10 +#define NV34TCL_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x00000a14 +#define NV34TCL_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x00000a18 +#define NV34TCL_VIEWPORT_TRANSLATE_X 0x00000a20 +#define NV34TCL_VIEWPORT_TRANSLATE_Y 0x00000a24 +#define NV34TCL_VIEWPORT_TRANSLATE_Z 0x00000a28 +#define NV34TCL_VIEWPORT_TRANSLATE_W 0x00000a2c +#define NV34TCL_VIEWPORT_SCALE_X 0x00000a30 +#define NV34TCL_VIEWPORT_SCALE_Y 0x00000a34 +#define NV34TCL_VIEWPORT_SCALE_Z 0x00000a38 +#define NV34TCL_VIEWPORT_SCALE_W 0x00000a3c +#define NV34TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000a60 +#define NV34TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000a64 +#define NV34TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000a68 +#define NV34TCL_DEPTH_FUNC 0x00000a6c +#define NV34TCL_DEPTH_FUNC_NEVER 0x00000200 +#define NV34TCL_DEPTH_FUNC_LESS 0x00000201 +#define NV34TCL_DEPTH_FUNC_EQUAL 0x00000202 +#define NV34TCL_DEPTH_FUNC_LEQUAL 0x00000203 +#define NV34TCL_DEPTH_FUNC_GREATER 0x00000204 +#define NV34TCL_DEPTH_FUNC_GREATER 0x00000204 +#define NV34TCL_DEPTH_FUNC_NOTEQUAL 0x00000205 +#define NV34TCL_DEPTH_FUNC_GEQUAL 0x00000206 +#define NV34TCL_DEPTH_FUNC_ALWAYS 0x00000207 +#define NV34TCL_DEPTH_WRITE_ENABLE 0x00000a70 +#define NV34TCL_DEPTH_TEST_ENABLE 0x00000a74 +#define NV34TCL_POLYGON_OFFSET_FACTOR 0x00000a78 +#define NV34TCL_POLYGON_OFFSET_UNITS 0x00000a7c +#define NV34TCL_VTX_ATTR_3I_XY(x) (0x00000a80+((x)*8)) +#define NV34TCL_VTX_ATTR_3I_XY__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_3I_XY_X_SHIFT 0 +#define NV34TCL_VTX_ATTR_3I_XY_X_MASK 0x0000ffff +#define NV34TCL_VTX_ATTR_3I_XY_Y_SHIFT 16 +#define NV34TCL_VTX_ATTR_3I_XY_Y_MASK 0xffff0000 +#define NV34TCL_VTX_ATTR_3I_Z(x) (0x00000a84+((x)*8)) +#define NV34TCL_VTX_ATTR_3I_Z__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_3I_Z_Z_SHIFT 0 +#define NV34TCL_VTX_ATTR_3I_Z_Z_MASK 0x0000ffff +#define NV34TCL_VP_UPLOAD_INST(x) (0x00000b80+((x)*4)) +#define NV34TCL_VP_UPLOAD_INST__SIZE 0x00000004 +#define NV34TCL_CLIP_PLANE_A(x) (0x00000e00+((x)*16)) +#define NV34TCL_CLIP_PLANE_A__SIZE 0x00000020 +#define NV34TCL_CLIP_PLANE_B(x) (0x00000e04+((x)*16)) +#define NV34TCL_CLIP_PLANE_B__SIZE 0x00000020 +#define NV34TCL_CLIP_PLANE_C(x) (0x00000e08+((x)*16)) +#define NV34TCL_CLIP_PLANE_C__SIZE 0x00000020 +#define NV34TCL_CLIP_PLANE_D(x) (0x00000e0c+((x)*16)) +#define NV34TCL_CLIP_PLANE_D__SIZE 0x00000020 +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(x) (0x00001000+((x)*64)) +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R__SIZE 0x00000008 +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(x) (0x00001004+((x)*64)) +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G__SIZE 0x00000008 +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(x) (0x00001008+((x)*64)) +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B__SIZE 0x00000008 +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(x) (0x0000100c+((x)*64)) +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R__SIZE 0x00000008 +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(x) (0x00001010+((x)*64)) +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G__SIZE 0x00000008 +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(x) (0x00001014+((x)*64)) +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B__SIZE 0x00000008 +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(x) (0x00001018+((x)*64)) +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R__SIZE 0x00000008 +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(x) (0x0000101c+((x)*64)) +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G__SIZE 0x00000008 +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(x) (0x00001020+((x)*64)) +#define NV34TCL_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B__SIZE 0x00000008 +#define NV34TCL_LIGHT_HALF_VECTOR_X(x) (0x00001028+((x)*64)) +#define NV34TCL_LIGHT_HALF_VECTOR_X__SIZE 0x00000008 +#define NV34TCL_LIGHT_HALF_VECTOR_Y(x) (0x0000102c+((x)*64)) +#define NV34TCL_LIGHT_HALF_VECTOR_Y__SIZE 0x00000008 +#define NV34TCL_LIGHT_HALF_VECTOR_Z(x) (0x00001030+((x)*64)) +#define NV34TCL_LIGHT_HALF_VECTOR_Z__SIZE 0x00000008 +#define NV34TCL_LIGHT_DIRECTION_X(x) (0x00001034+((x)*64)) +#define NV34TCL_LIGHT_DIRECTION_X__SIZE 0x00000008 +#define NV34TCL_LIGHT_DIRECTION_Y(x) (0x00001038+((x)*64)) +#define NV34TCL_LIGHT_DIRECTION_Y__SIZE 0x00000008 +#define NV34TCL_LIGHT_DIRECTION_Z(x) (0x0000103c+((x)*64)) +#define NV34TCL_LIGHT_DIRECTION_Z__SIZE 0x00000008 +#define NV34TCL_LIGHT_SPOT_CUTOFF_A(x) (0x00001200+((x)*64)) +#define NV34TCL_LIGHT_SPOT_CUTOFF_A__SIZE 0x00000008 +#define NV34TCL_LIGHT_SPOT_CUTOFF_B(x) (0x00001204+((x)*64)) +#define NV34TCL_LIGHT_SPOT_CUTOFF_B__SIZE 0x00000008 +#define NV34TCL_LIGHT_SPOT_CUTOFF_C(x) (0x00001208+((x)*64)) +#define NV34TCL_LIGHT_SPOT_CUTOFF_C__SIZE 0x00000008 +#define NV34TCL_LIGHT_SPOT_DIR_X(x) (0x0000120c+((x)*64)) +#define NV34TCL_LIGHT_SPOT_DIR_X__SIZE 0x00000008 +#define NV34TCL_LIGHT_SPOT_DIR_Y(x) (0x00001210+((x)*64)) +#define NV34TCL_LIGHT_SPOT_DIR_Y__SIZE 0x00000008 +#define NV34TCL_LIGHT_SPOT_DIR_Z(x) (0x00001214+((x)*64)) +#define NV34TCL_LIGHT_SPOT_DIR_Z__SIZE 0x00000008 +#define NV34TCL_LIGHT_SPOT_CUTOFF_D(x) (0x00001218+((x)*64)) +#define NV34TCL_LIGHT_SPOT_CUTOFF_D__SIZE 0x00000008 +#define NV34TCL_LIGHT_POSITION_X(x) (0x0000121c+((x)*64)) +#define NV34TCL_LIGHT_POSITION_X__SIZE 0x00000008 +#define NV34TCL_LIGHT_POSITION_Y(x) (0x00001220+((x)*64)) +#define NV34TCL_LIGHT_POSITION_Y__SIZE 0x00000008 +#define NV34TCL_LIGHT_POSITION_Z(x) (0x00001224+((x)*64)) +#define NV34TCL_LIGHT_POSITION_Z__SIZE 0x00000008 +#define NV34TCL_LIGHT_ATTENUATION_CONSTANT(x) (0x00001228+((x)*64)) +#define NV34TCL_LIGHT_ATTENUATION_CONSTANT__SIZE 0x00000008 +#define NV34TCL_LIGHT_ATTENUATION_LINEAR(x) (0x0000122c+((x)*64)) +#define NV34TCL_LIGHT_ATTENUATION_LINEAR__SIZE 0x00000008 +#define NV34TCL_LIGHT_ATTENUATION_QUADRATIC(x) (0x00001230+((x)*64)) +#define NV34TCL_LIGHT_ATTENUATION_QUADRATIC__SIZE 0x00000008 +#define NV34TCL_FRONT_MATERIAL_SHININESS(x) (0x00001400+((x)*4)) +#define NV34TCL_FRONT_MATERIAL_SHININESS__SIZE 0x00000006 +#define NV34TCL_ENABLED_LIGHTS 0x00001420 +#define NV34TCL_FP_REG_CONTROL 0x00001450 +#define NV34TCL_FP_REG_CONTROL_UNK1_SHIFT 16 +#define NV34TCL_FP_REG_CONTROL_UNK1_MASK 0xffff0000 +#define NV34TCL_FP_REG_CONTROL_UNK0_SHIFT 0 +#define NV34TCL_FP_REG_CONTROL_UNK0_MASK 0x0000ffff +#define NV34TCL_VP_CLIP_PLANES_ENABLE 0x00001478 +#define NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE0 (1 << 1) +#define NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE1 (1 << 5) +#define NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE2 (1 << 9) +#define NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE3 (1 << 13) +#define NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE4 (1 << 17) +#define NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE5 (1 << 21) +#define NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE6 (1 << 25) +#define NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE7 (1 << 29) +#define NV34TCL_POLYGON_STIPPLE_ENABLE 0x0000147c +#define NV34TCL_POLYGON_STIPPLE_PATTERN(x) (0x00001480+((x)*4)) +#define NV34TCL_POLYGON_STIPPLE_PATTERN__SIZE 0x00000020 +#define NV34TCL_VTX_ATTR_3F_X(x) (0x00001500+((x)*16)) +#define NV34TCL_VTX_ATTR_3F_X__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_3F_Y(x) (0x00001504+((x)*16)) +#define NV34TCL_VTX_ATTR_3F_Y__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_3F_Z(x) (0x00001508+((x)*16)) +#define NV34TCL_VTX_ATTR_3F_Z__SIZE 0x00000010 +#define NV34TCL_VP_CLIP_PLANE_A(x) (0x00001600+((x)*16)) +#define NV34TCL_VP_CLIP_PLANE_A__SIZE 0x00000006 +#define NV34TCL_VP_CLIP_PLANE_B(x) (0x00001604+((x)*16)) +#define NV34TCL_VP_CLIP_PLANE_B__SIZE 0x00000006 +#define NV34TCL_VP_CLIP_PLANE_C(x) (0x00001608+((x)*16)) +#define NV34TCL_VP_CLIP_PLANE_C__SIZE 0x00000006 +#define NV34TCL_VP_CLIP_PLANE_D(x) (0x0000160c+((x)*16)) +#define NV34TCL_VP_CLIP_PLANE_D__SIZE 0x00000006 +#define NV34TCL_VTXBUF_ADDRESS(x) (0x00001680+((x)*4)) +#define NV34TCL_VTXBUF_ADDRESS__SIZE 0x00000010 +#define NV34TCL_VTXBUF_ADDRESS_DMA1 (1 << 31) +#define NV34TCL_VTXBUF_ADDRESS_OFFSET_SHIFT 0 +#define NV34TCL_VTXBUF_ADDRESS_OFFSET_MASK 0x0fffffff +#define NV34TCL_VTXFMT(x) (0x00001740+((x)*4)) +#define NV34TCL_VTXFMT__SIZE 0x00000010 +#define NV34TCL_VTXFMT_TYPE_SHIFT 0 +#define NV34TCL_VTXFMT_TYPE_MASK 0x0000000f +#define NV34TCL_VTXFMT_TYPE_FLOAT 0x00000002 +#define NV34TCL_VTXFMT_TYPE_UBYTE 0x00000004 +#define NV34TCL_VTXFMT_TYPE_USHORT 0x00000005 +#define NV34TCL_VTXFMT_SIZE_SHIFT 4 +#define NV34TCL_VTXFMT_SIZE_MASK 0x000000f0 +#define NV34TCL_VTXFMT_STRIDE_SHIFT 8 +#define NV34TCL_VTXFMT_STRIDE_MASK 0x0000ff00 +#define NV34TCL_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 +#define NV34TCL_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 +#define NV34TCL_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 +#define NV34TCL_COLOR_MATERIAL_BACK_R 0x000017b0 +#define NV34TCL_COLOR_MATERIAL_BACK_G 0x000017b4 +#define NV34TCL_COLOR_MATERIAL_BACK_B 0x000017b8 +#define NV34TCL_COLOR_MATERIAL_BACK_A 0x000017c0 +#define NV34TCL_QUERY_RESET 0x000017c8 +#define NV34TCL_QUERY_UNK17CC 0x000017cc +#define NV34TCL_QUERY_GET 0x00001800 +#define NV34TCL_QUERY_GET_UNK24_SHIFT 24 +#define NV34TCL_QUERY_GET_UNK24_MASK 0xff000000 +#define NV34TCL_QUERY_GET_OFFSET_SHIFT 0 +#define NV34TCL_QUERY_GET_OFFSET_MASK 0x00ffffff +#define NV34TCL_VERTEX_BEGIN_END 0x00001808 +#define NV34TCL_VERTEX_BEGIN_END_STOP 0x00000000 +#define NV34TCL_VERTEX_BEGIN_END_POINTS 0x00000001 +#define NV34TCL_VERTEX_BEGIN_END_LINES 0x00000002 +#define NV34TCL_VERTEX_BEGIN_END_LINE_LOOP 0x00000003 +#define NV34TCL_VERTEX_BEGIN_END_LINE_STRIP 0x00000004 +#define NV34TCL_VERTEX_BEGIN_END_TRIANGLES 0x00000005 +#define NV34TCL_VERTEX_BEGIN_END_TRIANGLE_STRIP 0x00000006 +#define NV34TCL_VERTEX_BEGIN_END_TRIANGLE_FAN 0x00000007 +#define NV34TCL_VERTEX_BEGIN_END_QUADS 0x00000008 +#define NV34TCL_VERTEX_BEGIN_END_QUAD_STRIP 0x00000009 +#define NV34TCL_VERTEX_BEGIN_END_POLYGON 0x0000000a +#define NV34TCL_VB_ELEMENT_U16 0x0000180c +#define NV34TCL_VB_ELEMENT_U16_I0_SHIFT 0 +#define NV34TCL_VB_ELEMENT_U16_I0_MASK 0x0000ffff +#define NV34TCL_VB_ELEMENT_U16_I1_SHIFT 16 +#define NV34TCL_VB_ELEMENT_U16_I1_MASK 0xffff0000 +#define NV34TCL_VB_ELEMENT_U32 0x00001810 +#define NV34TCL_VB_VERTEX_BATCH 0x00001814 +#define NV34TCL_VB_VERTEX_BATCH_OFFSET_SHIFT 0 +#define NV34TCL_VB_VERTEX_BATCH_OFFSET_MASK 0x00ffffff +#define NV34TCL_VB_VERTEX_BATCH_COUNT_SHIFT 24 +#define NV34TCL_VB_VERTEX_BATCH_COUNT_MASK 0xff000000 +#define NV34TCL_VERTEX_DATA 0x00001818 +#define NV34TCL_IDXBUF_ADDRESS 0x0000181c +#define NV34TCL_IDXBUF_FORMAT 0x00001820 +#define NV34TCL_IDXBUF_FORMAT_TYPE_SHIFT 4 +#define NV34TCL_IDXBUF_FORMAT_TYPE_MASK 0x000000f0 +#define NV34TCL_IDXBUF_FORMAT_TYPE_U32 0x00000000 +#define NV34TCL_IDXBUF_FORMAT_TYPE_U16 0x00000010 +#define NV34TCL_IDXBUF_FORMAT_DMA1 (1 << 0) +#define NV34TCL_VB_INDEX_BATCH 0x00001824 +#define NV34TCL_VB_INDEX_BATCH_COUNT_SHIFT 24 +#define NV34TCL_VB_INDEX_BATCH_COUNT_MASK 0xff000000 +#define NV34TCL_VB_INDEX_BATCH_START_SHIFT 0 +#define NV34TCL_VB_INDEX_BATCH_START_MASK 0x00ffffff +#define NV34TCL_POLYGON_MODE_FRONT 0x00001828 +#define NV34TCL_POLYGON_MODE_FRONT_POINT 0x00001b00 +#define NV34TCL_POLYGON_MODE_FRONT_LINE 0x00001b01 +#define NV34TCL_POLYGON_MODE_FRONT_FILL 0x00001b02 +#define NV34TCL_POLYGON_MODE_BACK 0x0000182c +#define NV34TCL_POLYGON_MODE_BACK_POINT 0x00001b00 +#define NV34TCL_POLYGON_MODE_BACK_LINE 0x00001b01 +#define NV34TCL_POLYGON_MODE_BACK_FILL 0x00001b02 +#define NV34TCL_CULL_FACE 0x00001830 +#define NV34TCL_CULL_FACE_FRONT 0x00000404 +#define NV34TCL_CULL_FACE_BACK 0x00000405 +#define NV34TCL_CULL_FACE_FRONT_AND_BACK 0x00000408 +#define NV34TCL_FRONT_FACE 0x00001834 +#define NV34TCL_FRONT_FACE_CW 0x00000900 +#define NV34TCL_FRONT_FACE_CCW 0x00000901 +#define NV34TCL_POLYGON_SMOOTH_ENABLE 0x00001838 +#define NV34TCL_CULL_FACE_ENABLE 0x0000183c +#define NV34TCL_VTX_ATTR_2F_X(x) (0x00001880+((x)*8)) +#define NV34TCL_VTX_ATTR_2F_X__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_2F_Y(x) (0x00001884+((x)*8)) +#define NV34TCL_VTX_ATTR_2F_Y__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_2I(x) (0x00001900+((x)*4)) +#define NV34TCL_VTX_ATTR_2I__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_2I_X_SHIFT 0 +#define NV34TCL_VTX_ATTR_2I_X_MASK 0x0000ffff +#define NV34TCL_VTX_ATTR_2I_Y_SHIFT 16 +#define NV34TCL_VTX_ATTR_2I_Y_MASK 0xffff0000 +#define NV34TCL_VTX_ATTR_4UB(x) (0x00001940+((x)*4)) +#define NV34TCL_VTX_ATTR_4UB__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_4UB_X_SHIFT 0 +#define NV34TCL_VTX_ATTR_4UB_X_MASK 0x000000ff +#define NV34TCL_VTX_ATTR_4UB_Y_SHIFT 8 +#define NV34TCL_VTX_ATTR_4UB_Y_MASK 0x0000ff00 +#define NV34TCL_VTX_ATTR_4UB_Z_SHIFT 16 +#define NV34TCL_VTX_ATTR_4UB_Z_MASK 0x00ff0000 +#define NV34TCL_VTX_ATTR_4UB_W_SHIFT 24 +#define NV34TCL_VTX_ATTR_4UB_W_MASK 0xff000000 +#define NV34TCL_VTX_ATTR_4I_XY(x) (0x00001980+((x)*8)) +#define NV34TCL_VTX_ATTR_4I_XY__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_4I_XY_X_SHIFT 0 +#define NV34TCL_VTX_ATTR_4I_XY_X_MASK 0x0000ffff +#define NV34TCL_VTX_ATTR_4I_XY_Y_SHIFT 16 +#define NV34TCL_VTX_ATTR_4I_XY_Y_MASK 0xffff0000 +#define NV34TCL_VTX_ATTR_4I_ZW(x) (0x00001984+((x)*8)) +#define NV34TCL_VTX_ATTR_4I_ZW__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_4I_ZW_Z_SHIFT 0 +#define NV34TCL_VTX_ATTR_4I_ZW_Z_MASK 0x0000ffff +#define NV34TCL_VTX_ATTR_4I_ZW_W_SHIFT 16 +#define NV34TCL_VTX_ATTR_4I_ZW_W_MASK 0xffff0000 +#define NV34TCL_TX_OFFSET(x) (0x00001a00+((x)*32)) +#define NV34TCL_TX_OFFSET__SIZE 0x00000004 +#define NV34TCL_TX_FORMAT(x) (0x00001a04+((x)*32)) +#define NV34TCL_TX_FORMAT__SIZE 0x00000004 +#define NV34TCL_TX_FORMAT_DMA0 (1 << 0) +#define NV34TCL_TX_FORMAT_DMA1 (1 << 1) +#define NV34TCL_TX_FORMAT_CUBE_MAP (1 << 2) +#define NV34TCL_TX_FORMAT_DIMS_SHIFT 4 +#define NV34TCL_TX_FORMAT_DIMS_MASK 0x000000f0 +#define NV34TCL_TX_FORMAT_DIMS_1D 0x00000010 +#define NV34TCL_TX_FORMAT_DIMS_2D 0x00000020 +#define NV34TCL_TX_FORMAT_DIMS_3D 0x00000030 +#define NV34TCL_TX_FORMAT_FORMAT_SHIFT 8 +#define NV34TCL_TX_FORMAT_FORMAT_MASK 0x0000ff00 +#define NV34TCL_TX_FORMAT_FORMAT_L8 0x00000000 +#define NV34TCL_TX_FORMAT_FORMAT_A8 0x00000100 +#define NV34TCL_TX_FORMAT_FORMAT_A1R5G5B5 0x00000200 +#define NV34TCL_TX_FORMAT_FORMAT_A8_RECT 0x00000300 +#define NV34TCL_TX_FORMAT_FORMAT_A4R4G4B4 0x00000400 +#define NV34TCL_TX_FORMAT_FORMAT_A8R8G8B8 0x00000600 +#define NV34TCL_TX_FORMAT_FORMAT_X8R8G8B8 0x00000700 +#define NV34TCL_TX_FORMAT_FORMAT_INDEX8 0x00000b00 +#define NV34TCL_TX_FORMAT_FORMAT_DXT1 0x00000c00 +#define NV34TCL_TX_FORMAT_FORMAT_DXT3 0x00000e00 +#define NV34TCL_TX_FORMAT_FORMAT_DXT5 0x00000f00 +#define NV34TCL_TX_FORMAT_FORMAT_A1R5G5B5_RECT 0x00001000 +#define NV34TCL_TX_FORMAT_FORMAT_A8R8G8B8_RECT 0x00001200 +#define NV34TCL_TX_FORMAT_FORMAT_L8_RECT 0x00001300 +#define NV34TCL_TX_FORMAT_FORMAT_A8L8 0x00001a00 +#define NV34TCL_TX_FORMAT_FORMAT_A8_RECT2 0x00001b00 +#define NV34TCL_TX_FORMAT_FORMAT_R8G8B8_RECT 0x00001e00 +#define NV34TCL_TX_FORMAT_FORMAT_A4R4G4B4_RECT 0x00001d00 +#define NV34TCL_TX_FORMAT_FORMAT_L8A8_RECT 0x00002000 +#define NV34TCL_TX_FORMAT_FORMAT_A16 0x00003200 +#define NV34TCL_TX_FORMAT_FORMAT_A16_RECT 0x00003500 +#define NV34TCL_TX_FORMAT_FORMAT_FLOAT_RGBA16_NV 0x00004a00 +#define NV34TCL_TX_FORMAT_FORMAT_FLOAT_RGBA32_NV 0x00004b00 +#define NV34TCL_TX_FORMAT_FORMAT_FLOAT_R32_NV 0x00004c00 +#define NV34TCL_TX_FORMAT_NPOT (1 << 12) +#define NV34TCL_TX_FORMAT_RECT (1 << 14) +#define NV34TCL_TX_FORMAT_MIPMAP_LEVELS_SHIFT 16 +#define NV34TCL_TX_FORMAT_MIPMAP_LEVELS_MASK 0x000f0000 +#define NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT 20 +#define NV34TCL_TX_FORMAT_BASE_SIZE_U_MASK 0x00f00000 +#define NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT 24 +#define NV34TCL_TX_FORMAT_BASE_SIZE_V_MASK 0x0f000000 +#define NV34TCL_TX_FORMAT_BASE_SIZE_W_SHIFT 28 +#define NV34TCL_TX_FORMAT_BASE_SIZE_W_MASK 0xf0000000 +#define NV34TCL_TX_WRAP(x) (0x00001a08+((x)*32)) +#define NV34TCL_TX_WRAP__SIZE 0x00000004 +#define NV34TCL_TX_WRAP_S_SHIFT 0 +#define NV34TCL_TX_WRAP_S_MASK 0x000000ff +#define NV34TCL_TX_WRAP_S_REPEAT 0x00000001 +#define NV34TCL_TX_WRAP_S_MIRRORED_REPEAT 0x00000002 +#define NV34TCL_TX_WRAP_S_CLAMP_TO_EDGE 0x00000003 +#define NV34TCL_TX_WRAP_S_CLAMP_TO_BORDER 0x00000004 +#define NV34TCL_TX_WRAP_S_CLAMP 0x00000005 +#define NV34TCL_TX_WRAP_T_SHIFT 8 +#define NV34TCL_TX_WRAP_T_MASK 0x0000ff00 +#define NV34TCL_TX_WRAP_T_REPEAT 0x00000100 +#define NV34TCL_TX_WRAP_T_MIRRORED_REPEAT 0x00000200 +#define NV34TCL_TX_WRAP_T_CLAMP_TO_EDGE 0x00000300 +#define NV34TCL_TX_WRAP_T_CLAMP_TO_BORDER 0x00000400 +#define NV34TCL_TX_WRAP_T_CLAMP 0x00000500 +#define NV34TCL_TX_WRAP_R_SHIFT 16 +#define NV34TCL_TX_WRAP_R_MASK 0x00ff0000 +#define NV34TCL_TX_WRAP_R_REPEAT 0x00010000 +#define NV34TCL_TX_WRAP_R_MIRRORED_REPEAT 0x00020000 +#define NV34TCL_TX_WRAP_R_CLAMP_TO_EDGE 0x00030000 +#define NV34TCL_TX_WRAP_R_CLAMP_TO_BORDER 0x00040000 +#define NV34TCL_TX_WRAP_R_CLAMP 0x00050000 +#define NV34TCL_TX_ENABLE(x) (0x00001a0c+((x)*32)) +#define NV34TCL_TX_ENABLE__SIZE 0x00000004 +#define NV34TCL_TX_ENABLE_ENABLE (1 << 30) +#define NV34TCL_TX_SWIZZLE(x) (0x00001a10+((x)*32)) +#define NV34TCL_TX_SWIZZLE__SIZE 0x00000004 +#define NV34TCL_TX_SWIZZLE_S0_X_SHIFT 14 +#define NV34TCL_TX_SWIZZLE_S0_X_MASK 0x0000c000 +#define NV34TCL_TX_SWIZZLE_S0_X_ZERO 0x00000000 +#define NV34TCL_TX_SWIZZLE_S0_X_ONE 0x00004000 +#define NV34TCL_TX_SWIZZLE_S0_X_S1 0x00008000 +#define NV34TCL_TX_SWIZZLE_S0_Y_SHIFT 12 +#define NV34TCL_TX_SWIZZLE_S0_Y_MASK 0x00003000 +#define NV34TCL_TX_SWIZZLE_S0_Y_ZERO 0x00000000 +#define NV34TCL_TX_SWIZZLE_S0_Y_ONE 0x00001000 +#define NV34TCL_TX_SWIZZLE_S0_Y_S1 0x00002000 +#define NV34TCL_TX_SWIZZLE_S0_Z_SHIFT 10 +#define NV34TCL_TX_SWIZZLE_S0_Z_MASK 0x00000c00 +#define NV34TCL_TX_SWIZZLE_S0_Z_ZERO 0x00000000 +#define NV34TCL_TX_SWIZZLE_S0_Z_ONE 0x00000400 +#define NV34TCL_TX_SWIZZLE_S0_Z_S1 0x00000800 +#define NV34TCL_TX_SWIZZLE_S0_W_SHIFT 8 +#define NV34TCL_TX_SWIZZLE_S0_W_MASK 0x00000300 +#define NV34TCL_TX_SWIZZLE_S0_W_ZERO 0x00000000 +#define NV34TCL_TX_SWIZZLE_S0_W_ONE 0x00000100 +#define NV34TCL_TX_SWIZZLE_S0_W_S1 0x00000200 +#define NV34TCL_TX_SWIZZLE_S1_X_SHIFT 6 +#define NV34TCL_TX_SWIZZLE_S1_X_MASK 0x000000c0 +#define NV34TCL_TX_SWIZZLE_S1_X_W 0x00000000 +#define NV34TCL_TX_SWIZZLE_S1_X_Z 0x00000040 +#define NV34TCL_TX_SWIZZLE_S1_X_Y 0x00000080 +#define NV34TCL_TX_SWIZZLE_S1_X_X 0x000000c0 +#define NV34TCL_TX_SWIZZLE_S1_Y_SHIFT 4 +#define NV34TCL_TX_SWIZZLE_S1_Y_MASK 0x00000030 +#define NV34TCL_TX_SWIZZLE_S1_Y_W 0x00000000 +#define NV34TCL_TX_SWIZZLE_S1_Y_Z 0x00000010 +#define NV34TCL_TX_SWIZZLE_S1_Y_Y 0x00000020 +#define NV34TCL_TX_SWIZZLE_S1_Y_X 0x00000030 +#define NV34TCL_TX_SWIZZLE_S1_Z_SHIFT 2 +#define NV34TCL_TX_SWIZZLE_S1_Z_MASK 0x0000000c +#define NV34TCL_TX_SWIZZLE_S1_Z_W 0x00000000 +#define NV34TCL_TX_SWIZZLE_S1_Z_Z 0x00000004 +#define NV34TCL_TX_SWIZZLE_S1_Z_Y 0x00000008 +#define NV34TCL_TX_SWIZZLE_S1_Z_X 0x0000000c +#define NV34TCL_TX_SWIZZLE_S1_W_SHIFT 0 +#define NV34TCL_TX_SWIZZLE_S1_W_MASK 0x00000003 +#define NV34TCL_TX_SWIZZLE_S1_W_W 0x00000000 +#define NV34TCL_TX_SWIZZLE_S1_W_Z 0x00000001 +#define NV34TCL_TX_SWIZZLE_S1_W_Y 0x00000002 +#define NV34TCL_TX_SWIZZLE_S1_W_X 0x00000003 +#define NV34TCL_TX_SWIZZLE_RECT_PITCH_SHIFT 16 +#define NV34TCL_TX_SWIZZLE_RECT_PITCH_MASK 0xffff0000 +#define NV34TCL_TX_FILTER(x) (0x00001a14+((x)*32)) +#define NV34TCL_TX_FILTER__SIZE 0x00000004 +#define NV34TCL_TX_FILTER_MINIFY_SHIFT 16 +#define NV34TCL_TX_FILTER_MINIFY_MASK 0x000f0000 +#define NV34TCL_TX_FILTER_MINIFY_NEAREST 0x00010000 +#define NV34TCL_TX_FILTER_MINIFY_LINEAR 0x00020000 +#define NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST 0x00030000 +#define NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST 0x00040000 +#define NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR 0x00050000 +#define NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR 0x00060000 +#define NV34TCL_TX_FILTER_MAGNIFY_SHIFT 24 +#define NV34TCL_TX_FILTER_MAGNIFY_MASK 0x0f000000 +#define NV34TCL_TX_FILTER_MAGNIFY_NEAREST 0x01000000 +#define NV34TCL_TX_FILTER_MAGNIFY_LINEAR 0x02000000 +#define NV34TCL_TX_FILTER_SIGNED_BLUE (1 << 28) +#define NV34TCL_TX_FILTER_SIGNED_GREEN (1 << 29) +#define NV34TCL_TX_FILTER_SIGNED_RED (1 << 30) +#define NV34TCL_TX_FILTER_SIGNED_ALPHA (1 << 31) +#define NV34TCL_TX_NPOT_SIZE(x) (0x00001a18+((x)*32)) +#define NV34TCL_TX_NPOT_SIZE__SIZE 0x00000004 +#define NV34TCL_TX_NPOT_SIZE_H_SHIFT 0 +#define NV34TCL_TX_NPOT_SIZE_H_MASK 0x0000ffff +#define NV34TCL_TX_NPOT_SIZE_W_SHIFT 16 +#define NV34TCL_TX_NPOT_SIZE_W_MASK 0xffff0000 +#define NV34TCL_TX_BORDER_COLOR(x) (0x00001a1c+((x)*32)) +#define NV34TCL_TX_BORDER_COLOR__SIZE 0x00000004 +#define NV34TCL_TX_BORDER_COLOR_B_SHIFT 0 +#define NV34TCL_TX_BORDER_COLOR_B_MASK 0x000000ff +#define NV34TCL_TX_BORDER_COLOR_G_SHIFT 8 +#define NV34TCL_TX_BORDER_COLOR_G_MASK 0x0000ff00 +#define NV34TCL_TX_BORDER_COLOR_R_SHIFT 16 +#define NV34TCL_TX_BORDER_COLOR_R_MASK 0x00ff0000 +#define NV34TCL_TX_BORDER_COLOR_A_SHIFT 24 +#define NV34TCL_TX_BORDER_COLOR_A_MASK 0xff000000 +#define NV34TCL_VTX_ATTR_4F_X(x) (0x00001c00+((x)*16)) +#define NV34TCL_VTX_ATTR_4F_X__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_4F_Y(x) (0x00001c04+((x)*16)) +#define NV34TCL_VTX_ATTR_4F_Y__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_4F_Z(x) (0x00001c08+((x)*16)) +#define NV34TCL_VTX_ATTR_4F_Z__SIZE 0x00000010 +#define NV34TCL_VTX_ATTR_4F_W(x) (0x00001c0c+((x)*16)) +#define NV34TCL_VTX_ATTR_4F_W__SIZE 0x00000010 +#define NV34TCL_FP_CONTROL 0x00001d60 +#define NV34TCL_FP_CONTROL_USES_KIL (1 << 7) +#define NV34TCL_FP_CONTROL_USED_REGS_MINUS1_DIV2_SHIFT 0 +#define NV34TCL_FP_CONTROL_USED_REGS_MINUS1_DIV2_MASK 0x0000000f +#define NV34TCL_MULTISAMPLE_CONTROL 0x00001d7c +#define NV34TCL_CLEAR_DEPTH_VALUE 0x00001d8c +#define NV34TCL_CLEAR_COLOR_VALUE 0x00001d90 +#define NV34TCL_CLEAR_COLOR_VALUE_B_SHIFT 0 +#define NV34TCL_CLEAR_COLOR_VALUE_B_MASK 0x000000ff +#define NV34TCL_CLEAR_COLOR_VALUE_G_SHIFT 8 +#define NV34TCL_CLEAR_COLOR_VALUE_G_MASK 0x0000ff00 +#define NV34TCL_CLEAR_COLOR_VALUE_R_SHIFT 16 +#define NV34TCL_CLEAR_COLOR_VALUE_R_MASK 0x00ff0000 +#define NV34TCL_CLEAR_COLOR_VALUE_A_SHIFT 24 +#define NV34TCL_CLEAR_COLOR_VALUE_A_MASK 0xff000000 +#define NV34TCL_CLEAR_BUFFERS 0x00001d94 +#define NV34TCL_CLEAR_BUFFERS_COLOR_A (1 << 7) +#define NV34TCL_CLEAR_BUFFERS_COLOR_B (1 << 6) +#define NV34TCL_CLEAR_BUFFERS_COLOR_G (1 << 5) +#define NV34TCL_CLEAR_BUFFERS_COLOR_R (1 << 4) +#define NV34TCL_CLEAR_BUFFERS_STENCIL (1 << 1) +#define NV34TCL_CLEAR_BUFFERS_DEPTH (1 << 0) +#define NV34TCL_DO_VERTICES 0x00001dac +#define NV34TCL_LINE_STIPPLE_ENABLE 0x00001db4 +#define NV34TCL_LINE_STIPPLE_PATTERN 0x00001db8 +#define NV34TCL_LINE_STIPPLE_PATTERN_FACTOR_SHIFT 0 +#define NV34TCL_LINE_STIPPLE_PATTERN_FACTOR_MASK 0x0000ffff +#define NV34TCL_LINE_STIPPLE_PATTERN_PATTERN_SHIFT 16 +#define NV34TCL_LINE_STIPPLE_PATTERN_PATTERN_MASK 0xffff0000 +#define NV34TCL_BACK_MATERIAL_SHININESS(x) (0x00001e20+((x)*4)) +#define NV34TCL_BACK_MATERIAL_SHININESS__SIZE 0x00000006 +#define NV34TCL_VTX_ATTR_1F(x) (0x00001e40+((x)*4)) +#define NV34TCL_VTX_ATTR_1F__SIZE 0x00000010 +#define NV34TCL_VP_UPLOAD_FROM_ID 0x00001e9c +#define NV34TCL_VP_START_FROM_ID 0x00001ea0 +#define NV34TCL_POINT_PARAMETERS(x) (0x00001ec0+((x)*4)) +#define NV34TCL_POINT_PARAMETERS__SIZE 0x00000008 +#define NV34TCL_POINT_SIZE 0x00001ee0 +#define NV34TCL_POINT_PARAMETERS_ENABLE 0x00001ee4 +#define NV34TCL_POINT_SPRITE 0x00001ee8 +#define NV34TCL_POINT_SPRITE_ENABLE (1 << 0) +#define NV34TCL_POINT_SPRITE_R_MODE_SHIFT 1 +#define NV34TCL_POINT_SPRITE_R_MODE_MASK 0x00000006 +#define NV34TCL_POINT_SPRITE_R_MODE_GL_ZERO 0x00000000 +#define NV34TCL_POINT_SPRITE_R_MODE_GL_R 0x00000002 +#define NV34TCL_POINT_SPRITE_R_MODE_GL_S 0x00000004 +#define NV34TCL_POINT_SPRITE_COORD_REPLACE (1 << 11) +#define NV34TCL_VP_UPLOAD_CONST_ID 0x00001efc +#define NV34TCL_VP_UPLOAD_CONST_X(x) (0x00001f00+((x)*16)) +#define NV34TCL_VP_UPLOAD_CONST_X__SIZE 0x00000004 +#define NV34TCL_VP_UPLOAD_CONST_Y(x) (0x00001f04+((x)*16)) +#define NV34TCL_VP_UPLOAD_CONST_Y__SIZE 0x00000004 +#define NV34TCL_VP_UPLOAD_CONST_Z(x) (0x00001f08+((x)*16)) +#define NV34TCL_VP_UPLOAD_CONST_Z__SIZE 0x00000004 +#define NV34TCL_VP_UPLOAD_CONST_W(x) (0x00001f0c+((x)*16)) +#define NV34TCL_VP_UPLOAD_CONST_W__SIZE 0x00000004 +#define NV34TCL_UNK1f80(x) (0x00001f80+((x)*4)) +#define NV34TCL_UNK1f80__SIZE 0x00000010 +#define NV34TCL_VP_ATTRIB_EN 0x00001ff0 +#define NV34TCL_VP_RESULT_EN 0x00001ff4 + + +#define NV40_CONTEXT_SURFACES_2D 0x00003062 + + + +#define NV40_STRETCHED_IMAGE_FROM_CPU 0x00003066 + + + +#define NV40_TEXTURE_FROM_CPU 0x0000307b + + + +#define NV40_SCALED_IMAGE_FROM_MEMORY 0x00003089 + + + +#define NV40_IMAGE_FROM_CPU 0x0000308a + + + +#define NV40_SWIZZLED_SURFACE 0x0000309e + + + +#define NV40TCL 0x00004097 + +#define NV40TCL_REF_CNT 0x00000050 +#define NV40TCL_NOP 0x00000100 +#define NV40TCL_NOTIFY 0x00000104 +#define NV40TCL_DMA_NOTIFY 0x00000180 +#define NV40TCL_DMA_TEXTURE0 0x00000184 +#define NV40TCL_DMA_TEXTURE1 0x00000188 +#define NV40TCL_DMA_COLOR1 0x0000018c +#define NV40TCL_DMA_COLOR0 0x00000194 +#define NV40TCL_DMA_ZETA 0x00000198 +#define NV40TCL_DMA_VTXBUF0 0x0000019c +#define NV40TCL_DMA_VTXBUF1 0x000001a0 +#define NV40TCL_DMA_FENCE 0x000001a4 +#define NV40TCL_DMA_QUERY 0x000001a8 +#define NV40TCL_DMA_UNK01AC 0x000001ac +#define NV40TCL_DMA_UNK01B0 0x000001b0 +#define NV40TCL_DMA_COLOR2 0x000001b4 +#define NV40TCL_DMA_COLOR3 0x000001b8 +#define NV40TCL_RT_HORIZ 0x00000200 +#define NV40TCL_RT_HORIZ_W_SHIFT 16 +#define NV40TCL_RT_HORIZ_W_MASK 0xffff0000 +#define NV40TCL_RT_HORIZ_X_SHIFT 0 +#define NV40TCL_RT_HORIZ_X_MASK 0x0000ffff +#define NV40TCL_RT_VERT 0x00000204 +#define NV40TCL_RT_VERT_H_SHIFT 16 +#define NV40TCL_RT_VERT_H_MASK 0xffff0000 +#define NV40TCL_RT_VERT_Y_SHIFT 0 +#define NV40TCL_RT_VERT_Y_MASK 0x0000ffff +#define NV40TCL_RT_FORMAT 0x00000208 +#define NV40TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT 24 +#define NV40TCL_RT_FORMAT_LOG2_HEIGHT_MASK 0xff000000 +#define NV40TCL_RT_FORMAT_LOG2_WIDTH_SHIFT 16 +#define NV40TCL_RT_FORMAT_LOG2_WIDTH_MASK 0x00ff0000 +#define NV40TCL_RT_FORMAT_TYPE_SHIFT 8 +#define NV40TCL_RT_FORMAT_TYPE_MASK 0x00000f00 +#define NV40TCL_RT_FORMAT_TYPE_LINEAR 0x00000100 +#define NV40TCL_RT_FORMAT_TYPE_SWIZZLED 0x00000200 +#define NV40TCL_RT_FORMAT_ZETA_SHIFT 5 +#define NV40TCL_RT_FORMAT_ZETA_MASK 0x000000e0 +#define NV40TCL_RT_FORMAT_ZETA_Z16 0x00000020 +#define NV40TCL_RT_FORMAT_ZETA_Z24S8 0x00000040 +#define NV40TCL_RT_FORMAT_COLOR_SHIFT 0 +#define NV40TCL_RT_FORMAT_COLOR_MASK 0x0000001f +#define NV40TCL_RT_FORMAT_COLOR_R5G6B5 0x00000003 +#define NV40TCL_RT_FORMAT_COLOR_X8R8G8B8 0x00000005 +#define NV40TCL_RT_FORMAT_COLOR_A8R8G8B8 0x00000008 +#define NV40TCL_RT_FORMAT_COLOR_B8 0x00000009 +#define NV40TCL_RT_FORMAT_COLOR_X8B8G8R8 0x0000000f +#define NV40TCL_RT_FORMAT_COLOR_A8B8G8R8 0x00000010 +#define NV40TCL_COLOR0_PITCH 0x0000020c +#define NV40TCL_COLOR0_OFFSET 0x00000210 +#define NV40TCL_ZETA_OFFSET 0x00000214 +#define NV40TCL_COLOR1_OFFSET 0x00000218 +#define NV40TCL_COLOR1_PITCH 0x0000021c +#define NV40TCL_RT_ENABLE 0x00000220 +#define NV40TCL_RT_ENABLE_MRT (1 << 4) +#define NV40TCL_RT_ENABLE_COLOR3 (1 << 3) +#define NV40TCL_RT_ENABLE_COLOR2 (1 << 2) +#define NV40TCL_RT_ENABLE_COLOR1 (1 << 1) +#define NV40TCL_RT_ENABLE_COLOR0 (1 << 0) +#define NV40TCL_ZETA_PITCH 0x0000022c +#define NV40TCL_COLOR2_PITCH 0x00000280 +#define NV40TCL_COLOR3_PITCH 0x00000284 +#define NV40TCL_COLOR2_OFFSET 0x00000288 +#define NV40TCL_COLOR3_OFFSET 0x0000028c +#define NV40TCL_VIEWPORT_CLIP_HORIZ(x) (0x000002c0+((x)*8)) +#define NV40TCL_VIEWPORT_CLIP_HORIZ__SIZE 0x00000008 +#define NV40TCL_VIEWPORT_CLIP_VERT(x) (0x000002c4+((x)*8)) +#define NV40TCL_VIEWPORT_CLIP_VERT__SIZE 0x00000008 +#define NV40TCL_DITHER_ENABLE 0x00000300 +#define NV40TCL_ALPHA_TEST_ENABLE 0x00000304 +#define NV40TCL_ALPHA_TEST_FUNC 0x00000308 +#define NV40TCL_ALPHA_TEST_FUNC_NEVER 0x00000200 +#define NV40TCL_ALPHA_TEST_FUNC_LESS 0x00000201 +#define NV40TCL_ALPHA_TEST_FUNC_EQUAL 0x00000202 +#define NV40TCL_ALPHA_TEST_FUNC_LEQUAL 0x00000203 +#define NV40TCL_ALPHA_TEST_FUNC_GREATER 0x00000204 +#define NV40TCL_ALPHA_TEST_FUNC_GREATER 0x00000204 +#define NV40TCL_ALPHA_TEST_FUNC_NOTEQUAL 0x00000205 +#define NV40TCL_ALPHA_TEST_FUNC_GEQUAL 0x00000206 +#define NV40TCL_ALPHA_TEST_FUNC_ALWAYS 0x00000207 +#define NV40TCL_ALPHA_TEST_REF 0x0000030c +#define NV40TCL_BLEND_ENABLE 0x00000310 +#define NV40TCL_BLEND_FUNC_SRC 0x00000314 +#define NV40TCL_BLEND_FUNC_SRC_RGB_SHIFT 0 +#define NV40TCL_BLEND_FUNC_SRC_RGB_MASK 0x0000ffff +#define NV40TCL_BLEND_FUNC_SRC_RGB_ZERO 0x00000000 +#define NV40TCL_BLEND_FUNC_SRC_RGB_ONE 0x00000001 +#define NV40TCL_BLEND_FUNC_SRC_RGB_SRC_COLOR 0x00000300 +#define NV40TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV40TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA 0x00000302 +#define NV40TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV40TCL_BLEND_FUNC_SRC_RGB_DST_ALPHA 0x00000304 +#define NV40TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV40TCL_BLEND_FUNC_SRC_RGB_DST_COLOR 0x00000306 +#define NV40TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_COLOR 0x00000307 +#define NV40TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA_SATURATE 0x00000308 +#define NV40TCL_BLEND_FUNC_SRC_RGB_CONSTANT_COLOR 0x00008001 +#define NV40TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV40TCL_BLEND_FUNC_SRC_RGB_CONSTANT_ALPHA 0x00008003 +#define NV40TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_SHIFT 16 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_MASK 0xffff0000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_ZERO 0x00000000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_ONE 0x00010000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_SRC_COLOR 0x03000000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_COLOR 0x03010000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA 0x03020000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_ALPHA 0x03030000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_DST_ALPHA 0x03040000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_ALPHA 0x03050000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_DST_COLOR 0x03060000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_COLOR 0x03070000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA_SATURATE 0x03080000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_COLOR 0x80010000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_COLOR 0x80020000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_ALPHA 0x80030000 +#define NV40TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_ALPHA 0x80040000 +#define NV40TCL_BLEND_FUNC_DST 0x00000318 +#define NV40TCL_BLEND_FUNC_DST_RGB_SHIFT 0 +#define NV40TCL_BLEND_FUNC_DST_RGB_MASK 0x0000ffff +#define NV40TCL_BLEND_FUNC_DST_RGB_ZERO 0x00000000 +#define NV40TCL_BLEND_FUNC_DST_RGB_ONE 0x00000001 +#define NV40TCL_BLEND_FUNC_DST_RGB_SRC_COLOR 0x00000300 +#define NV40TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV40TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA 0x00000302 +#define NV40TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV40TCL_BLEND_FUNC_DST_RGB_DST_ALPHA 0x00000304 +#define NV40TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV40TCL_BLEND_FUNC_DST_RGB_DST_COLOR 0x00000306 +#define NV40TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_COLOR 0x00000307 +#define NV40TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA_SATURATE 0x00000308 +#define NV40TCL_BLEND_FUNC_DST_RGB_CONSTANT_COLOR 0x00008001 +#define NV40TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV40TCL_BLEND_FUNC_DST_RGB_CONSTANT_ALPHA 0x00008003 +#define NV40TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_SHIFT 16 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_MASK 0xffff0000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_ZERO 0x00000000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_ONE 0x00010000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_SRC_COLOR 0x03000000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_COLOR 0x03010000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA 0x03020000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_ALPHA 0x03030000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_DST_ALPHA 0x03040000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_ALPHA 0x03050000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_DST_COLOR 0x03060000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_COLOR 0x03070000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA_SATURATE 0x03080000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_COLOR 0x80010000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_COLOR 0x80020000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_ALPHA 0x80030000 +#define NV40TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_ALPHA 0x80040000 +#define NV40TCL_BLEND_COLOR 0x0000031c +#define NV40TCL_BLEND_EQUATION 0x00000320 +#define NV40TCL_BLEND_EQUATION_RGB_SHIFT 0 +#define NV40TCL_BLEND_EQUATION_RGB_MASK 0x0000ffff +#define NV40TCL_BLEND_EQUATION_RGB_FUNC_ADD 0x00008006 +#define NV40TCL_BLEND_EQUATION_RGB_MIN 0x00008007 +#define NV40TCL_BLEND_EQUATION_RGB_MAX 0x00008008 +#define NV40TCL_BLEND_EQUATION_RGB_FUNC_SUBTRACT 0x0000800a +#define NV40TCL_BLEND_EQUATION_RGB_FUNC_REVERSE_SUBTRACT 0x0000800b +#define NV40TCL_BLEND_EQUATION_ALPHA_SHIFT 16 +#define NV40TCL_BLEND_EQUATION_ALPHA_MASK 0xffff0000 +#define NV40TCL_BLEND_EQUATION_ALPHA_FUNC_ADD 0x80060000 +#define NV40TCL_BLEND_EQUATION_ALPHA_MIN 0x80070000 +#define NV40TCL_BLEND_EQUATION_ALPHA_MAX 0x80080000 +#define NV40TCL_BLEND_EQUATION_ALPHA_FUNC_SUBTRACT 0x800a0000 +#define NV40TCL_BLEND_EQUATION_ALPHA_FUNC_REVERSE_SUBTRACT 0x800b0000 +#define NV40TCL_COLOR_MASK 0x00000324 +#define NV40TCL_COLOR_MASK_BUFFER0_B_SHIFT 0 +#define NV40TCL_COLOR_MASK_BUFFER0_B_MASK 0x000000ff +#define NV40TCL_COLOR_MASK_BUFFER0_G_SHIFT 8 +#define NV40TCL_COLOR_MASK_BUFFER0_G_MASK 0x0000ff00 +#define NV40TCL_COLOR_MASK_BUFFER0_R_SHIFT 16 +#define NV40TCL_COLOR_MASK_BUFFER0_R_MASK 0x00ff0000 +#define NV40TCL_COLOR_MASK_BUFFER0_A_SHIFT 24 +#define NV40TCL_COLOR_MASK_BUFFER0_A_MASK 0xff000000 +#define NV40TCL_STENCIL_FRONT_ENABLE 0x00000328 +#define NV40TCL_STENCIL_FRONT_MASK 0x0000032c +#define NV40TCL_STENCIL_FRONT_FUNC_FUNC 0x00000330 +#define NV40TCL_STENCIL_FRONT_FUNC_FUNC_NEVER 0x00000200 +#define NV40TCL_STENCIL_FRONT_FUNC_FUNC_LESS 0x00000201 +#define NV40TCL_STENCIL_FRONT_FUNC_FUNC_EQUAL 0x00000202 +#define NV40TCL_STENCIL_FRONT_FUNC_FUNC_LEQUAL 0x00000203 +#define NV40TCL_STENCIL_FRONT_FUNC_FUNC_GREATER 0x00000204 +#define NV40TCL_STENCIL_FRONT_FUNC_FUNC_GREATER 0x00000204 +#define NV40TCL_STENCIL_FRONT_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV40TCL_STENCIL_FRONT_FUNC_FUNC_GEQUAL 0x00000206 +#define NV40TCL_STENCIL_FRONT_FUNC_FUNC_ALWAYS 0x00000207 +#define NV40TCL_STENCIL_FRONT_FUNC_REF 0x00000334 +#define NV40TCL_STENCIL_FRONT_FUNC_MASK 0x00000338 +#define NV40TCL_STENCIL_FRONT_OP_FAIL 0x0000033c +#define NV40TCL_STENCIL_FRONT_OP_FAIL_ZERO 0x00000000 +#define NV40TCL_STENCIL_FRONT_OP_FAIL_INVERT 0x0000150a +#define NV40TCL_STENCIL_FRONT_OP_FAIL_KEEP 0x00001e00 +#define NV40TCL_STENCIL_FRONT_OP_FAIL_REPLACE 0x00001e01 +#define NV40TCL_STENCIL_FRONT_OP_FAIL_INCR 0x00001e02 +#define NV40TCL_STENCIL_FRONT_OP_FAIL_DECR 0x00001e03 +#define NV40TCL_STENCIL_FRONT_OP_FAIL_INCR_WRAP 0x00008507 +#define NV40TCL_STENCIL_FRONT_OP_FAIL_DECR_WRAP 0x00008508 +#define NV40TCL_STENCIL_FRONT_OP_ZFAIL 0x00000340 +#define NV40TCL_STENCIL_FRONT_OP_ZFAIL_ZERO 0x00000000 +#define NV40TCL_STENCIL_FRONT_OP_ZFAIL_INVERT 0x0000150a +#define NV40TCL_STENCIL_FRONT_OP_ZFAIL_KEEP 0x00001e00 +#define NV40TCL_STENCIL_FRONT_OP_ZFAIL_REPLACE 0x00001e01 +#define NV40TCL_STENCIL_FRONT_OP_ZFAIL_INCR 0x00001e02 +#define NV40TCL_STENCIL_FRONT_OP_ZFAIL_DECR 0x00001e03 +#define NV40TCL_STENCIL_FRONT_OP_ZFAIL_INCR_WRAP 0x00008507 +#define NV40TCL_STENCIL_FRONT_OP_ZFAIL_DECR_WRAP 0x00008508 +#define NV40TCL_STENCIL_FRONT_OP_ZPASS 0x00000344 +#define NV40TCL_STENCIL_FRONT_OP_ZPASS_ZERO 0x00000000 +#define NV40TCL_STENCIL_FRONT_OP_ZPASS_INVERT 0x0000150a +#define NV40TCL_STENCIL_FRONT_OP_ZPASS_KEEP 0x00001e00 +#define NV40TCL_STENCIL_FRONT_OP_ZPASS_REPLACE 0x00001e01 +#define NV40TCL_STENCIL_FRONT_OP_ZPASS_INCR 0x00001e02 +#define NV40TCL_STENCIL_FRONT_OP_ZPASS_DECR 0x00001e03 +#define NV40TCL_STENCIL_FRONT_OP_ZPASS_INCR_WRAP 0x00008507 +#define NV40TCL_STENCIL_FRONT_OP_ZPASS_DECR_WRAP 0x00008508 +#define NV40TCL_STENCIL_BACK_ENABLE 0x00000348 +#define NV40TCL_STENCIL_BACK_MASK 0x0000034c +#define NV40TCL_STENCIL_BACK_FUNC_FUNC 0x00000350 +#define NV40TCL_STENCIL_BACK_FUNC_FUNC_NEVER 0x00000200 +#define NV40TCL_STENCIL_BACK_FUNC_FUNC_LESS 0x00000201 +#define NV40TCL_STENCIL_BACK_FUNC_FUNC_EQUAL 0x00000202 +#define NV40TCL_STENCIL_BACK_FUNC_FUNC_LEQUAL 0x00000203 +#define NV40TCL_STENCIL_BACK_FUNC_FUNC_GREATER 0x00000204 +#define NV40TCL_STENCIL_BACK_FUNC_FUNC_GREATER 0x00000204 +#define NV40TCL_STENCIL_BACK_FUNC_FUNC_NOTEQUAL 0x00000205 +#define NV40TCL_STENCIL_BACK_FUNC_FUNC_GEQUAL 0x00000206 +#define NV40TCL_STENCIL_BACK_FUNC_FUNC_ALWAYS 0x00000207 +#define NV40TCL_STENCIL_BACK_FUNC_REF 0x00000354 +#define NV40TCL_STENCIL_BACK_FUNC_MASK 0x00000358 +#define NV40TCL_STENCIL_BACK_OP_FAIL 0x0000035c +#define NV40TCL_STENCIL_BACK_OP_FAIL_ZERO 0x00000000 +#define NV40TCL_STENCIL_BACK_OP_FAIL_INVERT 0x0000150a +#define NV40TCL_STENCIL_BACK_OP_FAIL_KEEP 0x00001e00 +#define NV40TCL_STENCIL_BACK_OP_FAIL_REPLACE 0x00001e01 +#define NV40TCL_STENCIL_BACK_OP_FAIL_INCR 0x00001e02 +#define NV40TCL_STENCIL_BACK_OP_FAIL_DECR 0x00001e03 +#define NV40TCL_STENCIL_BACK_OP_FAIL_INCR_WRAP 0x00008507 +#define NV40TCL_STENCIL_BACK_OP_FAIL_DECR_WRAP 0x00008508 +#define NV40TCL_STENCIL_BACK_OP_ZFAIL 0x00000360 +#define NV40TCL_STENCIL_BACK_OP_ZFAIL_ZERO 0x00000000 +#define NV40TCL_STENCIL_BACK_OP_ZFAIL_INVERT 0x0000150a +#define NV40TCL_STENCIL_BACK_OP_ZFAIL_KEEP 0x00001e00 +#define NV40TCL_STENCIL_BACK_OP_ZFAIL_REPLACE 0x00001e01 +#define NV40TCL_STENCIL_BACK_OP_ZFAIL_INCR 0x00001e02 +#define NV40TCL_STENCIL_BACK_OP_ZFAIL_DECR 0x00001e03 +#define NV40TCL_STENCIL_BACK_OP_ZFAIL_INCR_WRAP 0x00008507 +#define NV40TCL_STENCIL_BACK_OP_ZFAIL_DECR_WRAP 0x00008508 +#define NV40TCL_STENCIL_BACK_OP_ZPASS 0x00000364 +#define NV40TCL_STENCIL_BACK_OP_ZPASS_ZERO 0x00000000 +#define NV40TCL_STENCIL_BACK_OP_ZPASS_INVERT 0x0000150a +#define NV40TCL_STENCIL_BACK_OP_ZPASS_KEEP 0x00001e00 +#define NV40TCL_STENCIL_BACK_OP_ZPASS_REPLACE 0x00001e01 +#define NV40TCL_STENCIL_BACK_OP_ZPASS_INCR 0x00001e02 +#define NV40TCL_STENCIL_BACK_OP_ZPASS_DECR 0x00001e03 +#define NV40TCL_STENCIL_BACK_OP_ZPASS_INCR_WRAP 0x00008507 +#define NV40TCL_STENCIL_BACK_OP_ZPASS_DECR_WRAP 0x00008508 +#define NV40TCL_SHADE_MODEL 0x00000368 +#define NV40TCL_SHADE_MODEL_FLAT 0x00001d00 +#define NV40TCL_SHADE_MODEL_SMOOTH 0x00001d01 +#define NV40TCL_MRT_COLOR_MASK 0x00000370 +#define NV40TCL_MRT_COLOR_MASK_BUFFER1_A (1 << 4) +#define NV40TCL_MRT_COLOR_MASK_BUFFER1_R (1 << 5) +#define NV40TCL_MRT_COLOR_MASK_BUFFER1_G (1 << 6) +#define NV40TCL_MRT_COLOR_MASK_BUFFER1_B (1 << 7) +#define NV40TCL_MRT_COLOR_MASK_BUFFER2_A (1 << 8) +#define NV40TCL_MRT_COLOR_MASK_BUFFER2_R (1 << 9) +#define NV40TCL_MRT_COLOR_MASK_BUFFER2_G (1 << 10) +#define NV40TCL_MRT_COLOR_MASK_BUFFER2_B (1 << 11) +#define NV40TCL_MRT_COLOR_MASK_BUFFER3_A (1 << 12) +#define NV40TCL_MRT_COLOR_MASK_BUFFER3_R (1 << 13) +#define NV40TCL_MRT_COLOR_MASK_BUFFER3_G (1 << 14) +#define NV40TCL_MRT_COLOR_MASK_BUFFER3_B (1 << 15) +#define NV40TCL_COLOR_LOGIC_OP_ENABLE 0x00000374 +#define NV40TCL_COLOR_LOGIC_OP 0x00000378 +#define NV40TCL_COLOR_LOGIC_OP_CLEAR 0x00001500 +#define NV40TCL_COLOR_LOGIC_OP_AND 0x00001501 +#define NV40TCL_COLOR_LOGIC_OP_AND_REVERSE 0x00001502 +#define NV40TCL_COLOR_LOGIC_OP_COPY 0x00001503 +#define NV40TCL_COLOR_LOGIC_OP_AND_INVERTED 0x00001504 +#define NV40TCL_COLOR_LOGIC_OP_NOOP 0x00001505 +#define NV40TCL_COLOR_LOGIC_OP_XOR 0x00001506 +#define NV40TCL_COLOR_LOGIC_OP_OR 0x00001507 +#define NV40TCL_COLOR_LOGIC_OP_NOR 0x00001508 +#define NV40TCL_COLOR_LOGIC_OP_EQUIV 0x00001509 +#define NV40TCL_COLOR_LOGIC_OP_INVERT 0x0000150a +#define NV40TCL_COLOR_LOGIC_OP_OR_REVERSE 0x0000150b +#define NV40TCL_COLOR_LOGIC_OP_COPY_INVERTED 0x0000150c +#define NV40TCL_COLOR_LOGIC_OP_OR_INVERTED 0x0000150d +#define NV40TCL_COLOR_LOGIC_OP_NAND 0x0000150e +#define NV40TCL_COLOR_LOGIC_OP_SET 0x0000150f +#define NV40TCL_DEPTH_RANGE_NEAR 0x00000394 +#define NV40TCL_DEPTH_RANGE_FAR 0x00000398 +#define NV40TCL_LINE_WIDTH 0x000003b8 +#define NV40TCL_LINE_SMOOTH_ENABLE 0x000003bc +#define NV40TCL_UNK03C0(x) (0x000003c0+((x)*4)) +#define NV40TCL_UNK03C0__SIZE 0x00000010 +#define NV40TCL_UNK0400(x) (0x00000400+((x)*4)) +#define NV40TCL_UNK0400__SIZE 0x00000010 +#define NV40TCL_UNK0440(x) (0x00000440+((x)*4)) +#define NV40TCL_UNK0440__SIZE 0x00000020 +#define NV40TCL_SCISSOR_HORIZ 0x000008c0 +#define NV40TCL_SCISSOR_HORIZ_X_SHIFT 0 +#define NV40TCL_SCISSOR_HORIZ_X_MASK 0x0000ffff +#define NV40TCL_SCISSOR_HORIZ_W_SHIFT 16 +#define NV40TCL_SCISSOR_HORIZ_W_MASK 0xffff0000 +#define NV40TCL_SCISSOR_VERT 0x000008c4 +#define NV40TCL_SCISSOR_VERT_Y_SHIFT 0 +#define NV40TCL_SCISSOR_VERT_Y_MASK 0x0000ffff +#define NV40TCL_SCISSOR_VERT_H_SHIFT 16 +#define NV40TCL_SCISSOR_VERT_H_MASK 0xffff0000 +#define NV40TCL_FOG_MODE 0x000008cc +#define NV40TCL_FOG_EQUATION_CONSTANT 0x000008d0 +#define NV40TCL_FOG_EQUATION_LINEAR 0x000008d4 +#define NV40TCL_FOG_EQUATION_QUADRATIC 0x000008d8 +#define NV40TCL_FP_ADDRESS 0x000008e4 +#define NV40TCL_FP_ADDRESS_OFFSET_SHIFT 8 +#define NV40TCL_FP_ADDRESS_OFFSET_MASK 0xffffff00 +#define NV40TCL_FP_ADDRESS_DMA1 (1 << 1) +#define NV40TCL_FP_ADDRESS_DMA0 (1 << 0) +#define NV40TCL_VIEWPORT_HORIZ 0x00000a00 +#define NV40TCL_VIEWPORT_HORIZ_W_SHIFT 16 +#define NV40TCL_VIEWPORT_HORIZ_W_MASK 0xffff0000 +#define NV40TCL_VIEWPORT_HORIZ_X_SHIFT 0 +#define NV40TCL_VIEWPORT_HORIZ_X_MASK 0x0000ffff +#define NV40TCL_VIEWPORT_VERT 0x00000a04 +#define NV40TCL_VIEWPORT_VERT_H_SHIFT 16 +#define NV40TCL_VIEWPORT_VERT_H_MASK 0xffff0000 +#define NV40TCL_VIEWPORT_VERT_Y_SHIFT 0 +#define NV40TCL_VIEWPORT_VERT_Y_MASK 0x0000ffff +#define NV40TCL_VIEWPORT_TRANSLATE_X 0x00000a20 +#define NV40TCL_VIEWPORT_TRANSLATE_Y 0x00000a24 +#define NV40TCL_VIEWPORT_TRANSLATE_Z 0x00000a28 +#define NV40TCL_VIEWPORT_TRANSLATE_W 0x00000a2c +#define NV40TCL_VIEWPORT_SCALE_X 0x00000a30 +#define NV40TCL_VIEWPORT_SCALE_Y 0x00000a34 +#define NV40TCL_VIEWPORT_SCALE_Z 0x00000a38 +#define NV40TCL_VIEWPORT_SCALE_W 0x00000a3c +#define NV40TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000a60 +#define NV40TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000a64 +#define NV40TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000a68 +#define NV40TCL_DEPTH_FUNC 0x00000a6c +#define NV40TCL_DEPTH_FUNC_NEVER 0x00000200 +#define NV40TCL_DEPTH_FUNC_LESS 0x00000201 +#define NV40TCL_DEPTH_FUNC_EQUAL 0x00000202 +#define NV40TCL_DEPTH_FUNC_LEQUAL 0x00000203 +#define NV40TCL_DEPTH_FUNC_GREATER 0x00000204 +#define NV40TCL_DEPTH_FUNC_GREATER 0x00000204 +#define NV40TCL_DEPTH_FUNC_NOTEQUAL 0x00000205 +#define NV40TCL_DEPTH_FUNC_GEQUAL 0x00000206 +#define NV40TCL_DEPTH_FUNC_ALWAYS 0x00000207 +#define NV40TCL_DEPTH_WRITE_ENABLE 0x00000a70 +#define NV40TCL_DEPTH_TEST_ENABLE 0x00000a74 +#define NV40TCL_POLYGON_OFFSET_FACTOR 0x00000a78 +#define NV40TCL_POLYGON_OFFSET_UNITS 0x00000a7c +#define NV40TCL_VTX_ATTR_3I_XY(x) (0x00000a80+((x)*8)) +#define NV40TCL_VTX_ATTR_3I_XY__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_3I_XY_X_SHIFT 0 +#define NV40TCL_VTX_ATTR_3I_XY_X_MASK 0x0000ffff +#define NV40TCL_VTX_ATTR_3I_XY_Y_SHIFT 16 +#define NV40TCL_VTX_ATTR_3I_XY_Y_MASK 0xffff0000 +#define NV40TCL_VTX_ATTR_3I_Z(x) (0x00000a84+((x)*8)) +#define NV40TCL_VTX_ATTR_3I_Z__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_3I_Z_Z_SHIFT 0 +#define NV40TCL_VTX_ATTR_3I_Z_Z_MASK 0x0000ffff +#define NV40TCL_UNK0B40(x) (0x00000b40+((x)*4)) +#define NV40TCL_UNK0B40__SIZE 0x00000008 +#define NV40TCL_VP_UPLOAD_INST(x) (0x00000b80+((x)*4)) +#define NV40TCL_VP_UPLOAD_INST__SIZE 0x00000004 +#define NV40TCL_CLIP_PLANE_ENABLE 0x00001478 +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE0 (1 << 1) +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE1 (1 << 5) +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE2 (1 << 9) +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE3 (1 << 13) +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE4 (1 << 17) +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE5 (1 << 21) +#define NV40TCL_POLYGON_STIPPLE_ENABLE 0x0000147c +#define NV40TCL_POLYGON_STIPPLE_PATTERN(x) (0x00001480+((x)*4)) +#define NV40TCL_POLYGON_STIPPLE_PATTERN__SIZE 0x00000020 +#define NV40TCL_VTX_ATTR_3F_X(x) (0x00001500+((x)*16)) +#define NV40TCL_VTX_ATTR_3F_X__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_3F_Y(x) (0x00001504+((x)*16)) +#define NV40TCL_VTX_ATTR_3F_Y__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_3F_Z(x) (0x00001508+((x)*16)) +#define NV40TCL_VTX_ATTR_3F_Z__SIZE 0x00000010 +#define NV40TCL_VTXBUF_ADDRESS(x) (0x00001680+((x)*4)) +#define NV40TCL_VTXBUF_ADDRESS__SIZE 0x00000010 +#define NV40TCL_VTXBUF_ADDRESS_DMA1 (1 << 31) +#define NV40TCL_VTXBUF_ADDRESS_OFFSET_SHIFT 0 +#define NV40TCL_VTXBUF_ADDRESS_OFFSET_MASK 0x0fffffff +#define NV40TCL_VTX_CACHE_INVALIDATE 0x00001714 +#define NV40TCL_VTXFMT(x) (0x00001740+((x)*4)) +#define NV40TCL_VTXFMT__SIZE 0x00000010 +#define NV40TCL_VTXFMT_TYPE_SHIFT 0 +#define NV40TCL_VTXFMT_TYPE_MASK 0x0000000f +#define NV40TCL_VTXFMT_TYPE_FLOAT 0x00000002 +#define NV40TCL_VTXFMT_TYPE_UBYTE 0x00000004 +#define NV40TCL_VTXFMT_TYPE_USHORT 0x00000005 +#define NV40TCL_VTXFMT_SIZE_SHIFT 4 +#define NV40TCL_VTXFMT_SIZE_MASK 0x000000f0 +#define NV40TCL_VTXFMT_STRIDE_SHIFT 8 +#define NV40TCL_VTXFMT_STRIDE_MASK 0x0000ff00 +#define NV40TCL_QUERY_RESET 0x000017c8 +#define NV40TCL_QUERY_UNK17CC 0x000017cc +#define NV40TCL_QUERY_GET 0x00001800 +#define NV40TCL_QUERY_GET_UNK24_SHIFT 24 +#define NV40TCL_QUERY_GET_UNK24_MASK 0xff000000 +#define NV40TCL_QUERY_GET_OFFSET_SHIFT 0 +#define NV40TCL_QUERY_GET_OFFSET_MASK 0x00ffffff +#define NV40TCL_BEGIN_END 0x00001808 +#define NV40TCL_BEGIN_END_STOP 0x00000000 +#define NV40TCL_BEGIN_END_POINTS 0x00000001 +#define NV40TCL_BEGIN_END_LINES 0x00000002 +#define NV40TCL_BEGIN_END_LINE_LOOP 0x00000003 +#define NV40TCL_BEGIN_END_LINE_STRIP 0x00000004 +#define NV40TCL_BEGIN_END_TRIANGLES 0x00000005 +#define NV40TCL_BEGIN_END_TRIANGLE_STRIP 0x00000006 +#define NV40TCL_BEGIN_END_TRIANGLE_FAN 0x00000007 +#define NV40TCL_BEGIN_END_QUADS 0x00000008 +#define NV40TCL_BEGIN_END_QUAD_STRIP 0x00000009 +#define NV40TCL_BEGIN_END_POLYGON 0x0000000a +#define NV40TCL_VB_ELEMENT_U16 0x0000180c +#define NV40TCL_VB_ELEMENT_U16_1_SHIFT 16 +#define NV40TCL_VB_ELEMENT_U16_1_MASK 0xffff0000 +#define NV40TCL_VB_ELEMENT_U16_0_SHIFT 0 +#define NV40TCL_VB_ELEMENT_U16_0_MASK 0x0000ffff +#define NV40TCL_VB_ELEMENT_U32 0x00001810 +#define NV40TCL_VB_VERTEX_BATCH 0x00001814 +#define NV40TCL_VB_VERTEX_BATCH_COUNT_SHIFT 24 +#define NV40TCL_VB_VERTEX_BATCH_COUNT_MASK 0xff000000 +#define NV40TCL_VB_VERTEX_BATCH_START_SHIFT 0 +#define NV40TCL_VB_VERTEX_BATCH_START_MASK 0x00ffffff +#define NV40TCL_VERTEX_DATA 0x00001818 +#define NV40TCL_IDXBUF_ADDRESS 0x0000181c +#define NV40TCL_IDXBUF_FORMAT 0x00001820 +#define NV40TCL_IDXBUF_FORMAT_TYPE_SHIFT 4 +#define NV40TCL_IDXBUF_FORMAT_TYPE_MASK 0x000000f0 +#define NV40TCL_IDXBUF_FORMAT_TYPE_U32 0x00000000 +#define NV40TCL_IDXBUF_FORMAT_TYPE_U16 0x00000010 +#define NV40TCL_IDXBUF_FORMAT_DMA1 (1 << 0) +#define NV40TCL_VB_INDEX_BATCH 0x00001824 +#define NV40TCL_VB_INDEX_BATCH_COUNT_SHIFT 24 +#define NV40TCL_VB_INDEX_BATCH_COUNT_MASK 0xff000000 +#define NV40TCL_VB_INDEX_BATCH_START_SHIFT 0 +#define NV40TCL_VB_INDEX_BATCH_START_MASK 0x00ffffff +#define NV40TCL_POLYGON_MODE_FRONT 0x00001828 +#define NV40TCL_POLYGON_MODE_FRONT_POINT 0x00001b00 +#define NV40TCL_POLYGON_MODE_FRONT_LINE 0x00001b01 +#define NV40TCL_POLYGON_MODE_FRONT_FILL 0x00001b02 +#define NV40TCL_POLYGON_MODE_BACK 0x0000182c +#define NV40TCL_POLYGON_MODE_BACK_POINT 0x00001b00 +#define NV40TCL_POLYGON_MODE_BACK_LINE 0x00001b01 +#define NV40TCL_POLYGON_MODE_BACK_FILL 0x00001b02 +#define NV40TCL_CULL_FACE 0x00001830 +#define NV40TCL_CULL_FACE_FRONT 0x00000404 +#define NV40TCL_CULL_FACE_BACK 0x00000405 +#define NV40TCL_CULL_FACE_FRONT_AND_BACK 0x00000408 +#define NV40TCL_FRONT_FACE 0x00001834 +#define NV40TCL_FRONT_FACE_CW 0x00000900 +#define NV40TCL_FRONT_FACE_CCW 0x00000901 +#define NV40TCL_POLYGON_SMOOTH_ENABLE 0x00001838 +#define NV40TCL_CULL_FACE_ENABLE 0x0000183c +#define NV40TCL_TEX_SIZE1(x) (0x00001840+((x)*4)) +#define NV40TCL_TEX_SIZE1__SIZE 0x00000008 +#define NV40TCL_TEX_SIZE1_DEPTH_SHIFT 20 +#define NV40TCL_TEX_SIZE1_DEPTH_MASK 0xfff00000 +#define NV40TCL_TEX_SIZE1_PITCH_SHIFT 0 +#define NV40TCL_TEX_SIZE1_PITCH_MASK 0x0000ffff +#define NV40TCL_VTX_ATTR_2F_X(x) (0x00001880+((x)*8)) +#define NV40TCL_VTX_ATTR_2F_X__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_2F_Y(x) (0x00001884+((x)*8)) +#define NV40TCL_VTX_ATTR_2F_Y__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_2I(x) (0x00001900+((x)*4)) +#define NV40TCL_VTX_ATTR_2I__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_2I_X_SHIFT 0 +#define NV40TCL_VTX_ATTR_2I_X_MASK 0x0000ffff +#define NV40TCL_VTX_ATTR_2I_Y_SHIFT 16 +#define NV40TCL_VTX_ATTR_2I_Y_MASK 0xffff0000 +#define NV40TCL_VTX_ATTR_4UB(x) (0x00001940+((x)*4)) +#define NV40TCL_VTX_ATTR_4UB__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_4UB_X_SHIFT 0 +#define NV40TCL_VTX_ATTR_4UB_X_MASK 0x000000ff +#define NV40TCL_VTX_ATTR_4UB_Y_SHIFT 8 +#define NV40TCL_VTX_ATTR_4UB_Y_MASK 0x0000ff00 +#define NV40TCL_VTX_ATTR_4UB_Z_SHIFT 16 +#define NV40TCL_VTX_ATTR_4UB_Z_MASK 0x00ff0000 +#define NV40TCL_VTX_ATTR_4UB_W_SHIFT 24 +#define NV40TCL_VTX_ATTR_4UB_W_MASK 0xff000000 +#define NV40TCL_VTX_ATTR_4I_XY(x) (0x00001980+((x)*8)) +#define NV40TCL_VTX_ATTR_4I_XY__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_4I_XY_X_SHIFT 0 +#define NV40TCL_VTX_ATTR_4I_XY_X_MASK 0x0000ffff +#define NV40TCL_VTX_ATTR_4I_XY_Y_SHIFT 16 +#define NV40TCL_VTX_ATTR_4I_XY_Y_MASK 0xffff0000 +#define NV40TCL_VTX_ATTR_4I_ZW(x) (0x00001984+((x)*8)) +#define NV40TCL_VTX_ATTR_4I_ZW__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_4I_ZW_Z_SHIFT 0 +#define NV40TCL_VTX_ATTR_4I_ZW_Z_MASK 0x0000ffff +#define NV40TCL_VTX_ATTR_4I_ZW_W_SHIFT 16 +#define NV40TCL_VTX_ATTR_4I_ZW_W_MASK 0xffff0000 +#define NV40TCL_TEX_OFFSET(x) (0x00001a00+((x)*32)) +#define NV40TCL_TEX_OFFSET__SIZE 0x00000010 +#define NV40TCL_TEX_FORMAT(x) (0x00001a04+((x)*32)) +#define NV40TCL_TEX_FORMAT__SIZE 0x00000010 +#define NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT 16 +#define NV40TCL_TEX_FORMAT_MIPMAP_COUNT_MASK 0x000f0000 +#define NV40TCL_TEX_FORMAT_RECT (1 << 14) +#define NV40TCL_TEX_FORMAT_LINEAR (1 << 13) +#define NV40TCL_TEX_FORMAT_FORMAT_SHIFT 8 +#define NV40TCL_TEX_FORMAT_FORMAT_MASK 0x00001f00 +#define NV40TCL_TEX_FORMAT_FORMAT_L8 0x00000100 +#define NV40TCL_TEX_FORMAT_FORMAT_A1R5G5B5 0x00000200 +#define NV40TCL_TEX_FORMAT_FORMAT_A4R4G4B4 0x00000300 +#define NV40TCL_TEX_FORMAT_FORMAT_R5G6B5 0x00000400 +#define NV40TCL_TEX_FORMAT_FORMAT_A8R8G8B8 0x00000500 +#define NV40TCL_TEX_FORMAT_FORMAT_DXT1 0x00000600 +#define NV40TCL_TEX_FORMAT_FORMAT_DXT3 0x00000700 +#define NV40TCL_TEX_FORMAT_FORMAT_DXT5 0x00000800 +#define NV40TCL_TEX_FORMAT_FORMAT_A8L8 0x00000b00 +#define NV40TCL_TEX_FORMAT_FORMAT_Z24 0x00001000 +#define NV40TCL_TEX_FORMAT_FORMAT_Z16 0x00001200 +#define NV40TCL_TEX_FORMAT_FORMAT_HILO8 0x00001800 +#define NV40TCL_TEX_FORMAT_FORMAT_RGBA16F 0x00001a00 +#define NV40TCL_TEX_FORMAT_FORMAT_RGBA32F 0x00001b00 +#define NV40TCL_TEX_FORMAT_DIMS_SHIFT 4 +#define NV40TCL_TEX_FORMAT_DIMS_MASK 0x000000f0 +#define NV40TCL_TEX_FORMAT_DIMS_1D 0x00000010 +#define NV40TCL_TEX_FORMAT_DIMS_2D 0x00000020 +#define NV40TCL_TEX_FORMAT_DIMS_3D 0x00000030 +#define NV40TCL_TEX_FORMAT_NO_BORDER (1 << 3) +#define NV40TCL_TEX_FORMAT_CUBIC (1 << 2) +#define NV40TCL_TEX_FORMAT_DMA1 (1 << 1) +#define NV40TCL_TEX_FORMAT_DMA0 (1 << 0) +#define NV40TCL_TEX_WRAP(x) (0x00001a08+((x)*32)) +#define NV40TCL_TEX_WRAP__SIZE 0x00000010 +#define NV40TCL_TEX_WRAP_S_SHIFT 0 +#define NV40TCL_TEX_WRAP_S_MASK 0x000000ff +#define NV40TCL_TEX_WRAP_S_REPEAT 0x00000001 +#define NV40TCL_TEX_WRAP_S_MIRRORED_REPEAT 0x00000002 +#define NV40TCL_TEX_WRAP_S_CLAMP_TO_EDGE 0x00000003 +#define NV40TCL_TEX_WRAP_S_CLAMP_TO_BORDER 0x00000004 +#define NV40TCL_TEX_WRAP_S_CLAMP 0x00000005 +#define NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_EDGE 0x00000006 +#define NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_BORDER 0x00000007 +#define NV40TCL_TEX_WRAP_S_MIRROR_CLAMP 0x00000008 +#define NV40TCL_TEX_WRAP_T_SHIFT 8 +#define NV40TCL_TEX_WRAP_T_MASK 0x0000ff00 +#define NV40TCL_TEX_WRAP_T_REPEAT 0x00000100 +#define NV40TCL_TEX_WRAP_T_MIRRORED_REPEAT 0x00000200 +#define NV40TCL_TEX_WRAP_T_CLAMP_TO_EDGE 0x00000300 +#define NV40TCL_TEX_WRAP_T_CLAMP_TO_BORDER 0x00000400 +#define NV40TCL_TEX_WRAP_T_CLAMP 0x00000500 +#define NV40TCL_TEX_WRAP_T_MIRROR_CLAMP_TO_EDGE 0x00000600 +#define NV40TCL_TEX_WRAP_T_MIRROR_CLAMP_TO_BORDER 0x00000700 +#define NV40TCL_TEX_WRAP_T_MIRROR_CLAMP 0x00000800 +#define NV40TCL_TEX_WRAP_R_SHIFT 16 +#define NV40TCL_TEX_WRAP_R_MASK 0x00ff0000 +#define NV40TCL_TEX_WRAP_R_REPEAT 0x00010000 +#define NV40TCL_TEX_WRAP_R_MIRRORED_REPEAT 0x00020000 +#define NV40TCL_TEX_WRAP_R_CLAMP_TO_EDGE 0x00030000 +#define NV40TCL_TEX_WRAP_R_CLAMP_TO_BORDER 0x00040000 +#define NV40TCL_TEX_WRAP_R_CLAMP 0x00050000 +#define NV40TCL_TEX_WRAP_R_MIRROR_CLAMP_TO_EDGE 0x00060000 +#define NV40TCL_TEX_WRAP_R_MIRROR_CLAMP_TO_BORDER 0x00070000 +#define NV40TCL_TEX_WRAP_R_MIRROR_CLAMP 0x00080000 +#define NV40TCL_TEX_WRAP_RCOMP_SHIFT 28 +#define NV40TCL_TEX_WRAP_RCOMP_MASK 0xf0000000 +#define NV40TCL_TEX_WRAP_RCOMP_NEVER 0x00000000 +#define NV40TCL_TEX_WRAP_RCOMP_GREATER 0x10000000 +#define NV40TCL_TEX_WRAP_RCOMP_EQUAL 0x20000000 +#define NV40TCL_TEX_WRAP_RCOMP_GEQUAL 0x30000000 +#define NV40TCL_TEX_WRAP_RCOMP_LESS 0x40000000 +#define NV40TCL_TEX_WRAP_RCOMP_NOTEQUAL 0x50000000 +#define NV40TCL_TEX_WRAP_RCOMP_LEQUAL 0x60000000 +#define NV40TCL_TEX_WRAP_RCOMP_ALWAYS 0x70000000 +#define NV40TCL_TEX_ENABLE(x) (0x00001a0c+((x)*32)) +#define NV40TCL_TEX_ENABLE__SIZE 0x00000010 +#define NV40TCL_TEX_ENABLE_ENABLE (1 << 31) +#define NV40TCL_TEX_ENABLE_ANISO_SHIFT 4 +#define NV40TCL_TEX_ENABLE_ANISO_MASK 0x000000f0 +#define NV40TCL_TEX_ENABLE_ANISO_NONE 0x00000000 +#define NV40TCL_TEX_ENABLE_ANISO_2X 0x00000010 +#define NV40TCL_TEX_ENABLE_ANISO_4X 0x00000020 +#define NV40TCL_TEX_ENABLE_ANISO_6X 0x00000030 +#define NV40TCL_TEX_ENABLE_ANISO_8X 0x00000040 +#define NV40TCL_TEX_ENABLE_ANISO_10X 0x00000050 +#define NV40TCL_TEX_ENABLE_ANISO_12X 0x00000060 +#define NV40TCL_TEX_ENABLE_ANISO_16X 0x00000070 +#define NV40TCL_TEX_SWIZZLE(x) (0x00001a10+((x)*32)) +#define NV40TCL_TEX_SWIZZLE__SIZE 0x00000010 +#define NV40TCL_TEX_SWIZZLE_S0_X_SHIFT 14 +#define NV40TCL_TEX_SWIZZLE_S0_X_MASK 0x0000c000 +#define NV40TCL_TEX_SWIZZLE_S0_X_ZERO 0x00000000 +#define NV40TCL_TEX_SWIZZLE_S0_X_ONE 0x00004000 +#define NV40TCL_TEX_SWIZZLE_S0_X_S1 0x00008000 +#define NV40TCL_TEX_SWIZZLE_S0_Y_SHIFT 12 +#define NV40TCL_TEX_SWIZZLE_S0_Y_MASK 0x00003000 +#define NV40TCL_TEX_SWIZZLE_S0_Y_ZERO 0x00000000 +#define NV40TCL_TEX_SWIZZLE_S0_Y_ONE 0x00001000 +#define NV40TCL_TEX_SWIZZLE_S0_Y_S1 0x00002000 +#define NV40TCL_TEX_SWIZZLE_S0_Z_SHIFT 10 +#define NV40TCL_TEX_SWIZZLE_S0_Z_MASK 0x00000c00 +#define NV40TCL_TEX_SWIZZLE_S0_Z_ZERO 0x00000000 +#define NV40TCL_TEX_SWIZZLE_S0_Z_ONE 0x00000400 +#define NV40TCL_TEX_SWIZZLE_S0_Z_S1 0x00000800 +#define NV40TCL_TEX_SWIZZLE_S0_W_SHIFT 8 +#define NV40TCL_TEX_SWIZZLE_S0_W_MASK 0x00000300 +#define NV40TCL_TEX_SWIZZLE_S0_W_ZERO 0x00000000 +#define NV40TCL_TEX_SWIZZLE_S0_W_ONE 0x00000100 +#define NV40TCL_TEX_SWIZZLE_S0_W_S1 0x00000200 +#define NV40TCL_TEX_SWIZZLE_S1_X_SHIFT 6 +#define NV40TCL_TEX_SWIZZLE_S1_X_MASK 0x000000c0 +#define NV40TCL_TEX_SWIZZLE_S1_X_W 0x00000000 +#define NV40TCL_TEX_SWIZZLE_S1_X_Z 0x00000040 +#define NV40TCL_TEX_SWIZZLE_S1_X_Y 0x00000080 +#define NV40TCL_TEX_SWIZZLE_S1_X_X 0x000000c0 +#define NV40TCL_TEX_SWIZZLE_S1_Y_SHIFT 4 +#define NV40TCL_TEX_SWIZZLE_S1_Y_MASK 0x00000030 +#define NV40TCL_TEX_SWIZZLE_S1_Y_W 0x00000000 +#define NV40TCL_TEX_SWIZZLE_S1_Y_Z 0x00000010 +#define NV40TCL_TEX_SWIZZLE_S1_Y_Y 0x00000020 +#define NV40TCL_TEX_SWIZZLE_S1_Y_X 0x00000030 +#define NV40TCL_TEX_SWIZZLE_S1_Z_SHIFT 2 +#define NV40TCL_TEX_SWIZZLE_S1_Z_MASK 0x0000000c +#define NV40TCL_TEX_SWIZZLE_S1_Z_W 0x00000000 +#define NV40TCL_TEX_SWIZZLE_S1_Z_Z 0x00000004 +#define NV40TCL_TEX_SWIZZLE_S1_Z_Y 0x00000008 +#define NV40TCL_TEX_SWIZZLE_S1_Z_X 0x0000000c +#define NV40TCL_TEX_SWIZZLE_S1_W_SHIFT 0 +#define NV40TCL_TEX_SWIZZLE_S1_W_MASK 0x00000003 +#define NV40TCL_TEX_SWIZZLE_S1_W_W 0x00000000 +#define NV40TCL_TEX_SWIZZLE_S1_W_Z 0x00000001 +#define NV40TCL_TEX_SWIZZLE_S1_W_Y 0x00000002 +#define NV40TCL_TEX_SWIZZLE_S1_W_X 0x00000003 +#define NV40TCL_TEX_FILTER(x) (0x00001a14+((x)*32)) +#define NV40TCL_TEX_FILTER__SIZE 0x00000010 +#define NV40TCL_TEX_FILTER_SIGNED_ALPHA (1 << 31) +#define NV40TCL_TEX_FILTER_SIGNED_RED (1 << 30) +#define NV40TCL_TEX_FILTER_SIGNED_GREEN (1 << 29) +#define NV40TCL_TEX_FILTER_SIGNED_BLUE (1 << 28) +#define NV40TCL_TEX_FILTER_MIN_SHIFT 16 +#define NV40TCL_TEX_FILTER_MIN_MASK 0x000f0000 +#define NV40TCL_TEX_FILTER_MIN_NEAREST 0x00010000 +#define NV40TCL_TEX_FILTER_MIN_LINEAR 0x00020000 +#define NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_NEAREST 0x00030000 +#define NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_NEAREST 0x00040000 +#define NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_LINEAR 0x00050000 +#define NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_LINEAR 0x00060000 +#define NV40TCL_TEX_FILTER_MAG_SHIFT 24 +#define NV40TCL_TEX_FILTER_MAG_MASK 0x0f000000 +#define NV40TCL_TEX_FILTER_MAG_NEAREST 0x01000000 +#define NV40TCL_TEX_FILTER_MAG_LINEAR 0x02000000 +#define NV40TCL_TEX_SIZE0(x) (0x00001a18+((x)*32)) +#define NV40TCL_TEX_SIZE0__SIZE 0x00000010 +#define NV40TCL_TEX_SIZE0_H_SHIFT 0 +#define NV40TCL_TEX_SIZE0_H_MASK 0x0000ffff +#define NV40TCL_TEX_SIZE0_W_SHIFT 16 +#define NV40TCL_TEX_SIZE0_W_MASK 0xffff0000 +#define NV40TCL_TEX_BORDER_COLOR(x) (0x00001a1c+((x)*32)) +#define NV40TCL_TEX_BORDER_COLOR__SIZE 0x00000010 +#define NV40TCL_TEX_BORDER_COLOR_B_SHIFT 0 +#define NV40TCL_TEX_BORDER_COLOR_B_MASK 0x000000ff +#define NV40TCL_TEX_BORDER_COLOR_G_SHIFT 8 +#define NV40TCL_TEX_BORDER_COLOR_G_MASK 0x0000ff00 +#define NV40TCL_TEX_BORDER_COLOR_R_SHIFT 16 +#define NV40TCL_TEX_BORDER_COLOR_R_MASK 0x00ff0000 +#define NV40TCL_TEX_BORDER_COLOR_A_SHIFT 24 +#define NV40TCL_TEX_BORDER_COLOR_A_MASK 0xff000000 +#define NV40TCL_VTX_ATTR_4F_X(x) (0x00001c00+((x)*16)) +#define NV40TCL_VTX_ATTR_4F_X__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_4F_Y(x) (0x00001c04+((x)*16)) +#define NV40TCL_VTX_ATTR_4F_Y__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_4F_Z(x) (0x00001c08+((x)*16)) +#define NV40TCL_VTX_ATTR_4F_Z__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_4F_W(x) (0x00001c0c+((x)*16)) +#define NV40TCL_VTX_ATTR_4F_W__SIZE 0x00000010 +#define NV40TCL_FP_CONTROL 0x00001d60 +#define NV40TCL_FP_CONTROL_TEMP_COUNT_SHIFT 24 +#define NV40TCL_FP_CONTROL_TEMP_COUNT_MASK 0xff000000 +#define NV40TCL_FP_CONTROL_KIL (1 << 7) +#define NV40TCL_MULTISAMPLE_CONTROL 0x00001d7c +#define NV40TCL_CLEAR_VALUE_DEPTH 0x00001d8c +#define NV40TCL_CLEAR_VALUE_COLOR 0x00001d90 +#define NV40TCL_CLEAR_BUFFERS 0x00001d94 +#define NV40TCL_CLEAR_BUFFERS_COLOR_A (1 << 7) +#define NV40TCL_CLEAR_BUFFERS_COLOR_B (1 << 6) +#define NV40TCL_CLEAR_BUFFERS_COLOR_G (1 << 5) +#define NV40TCL_CLEAR_BUFFERS_COLOR_R (1 << 4) +#define NV40TCL_CLEAR_BUFFERS_STENCIL (1 << 1) +#define NV40TCL_CLEAR_BUFFERS_DEPTH (1 << 0) +#define NV40TCL_LINE_STIPPLE_ENABLE 0x00001db4 +#define NV40TCL_LINE_STIPPLE_PATTERN 0x00001db8 +#define NV40TCL_LINE_STIPPLE_PATTERN_FACTOR_SHIFT 0 +#define NV40TCL_LINE_STIPPLE_PATTERN_FACTOR_MASK 0x0000ffff +#define NV40TCL_LINE_STIPPLE_PATTERN_PATTERN_SHIFT 16 +#define NV40TCL_LINE_STIPPLE_PATTERN_PATTERN_MASK 0xffff0000 +#define NV40TCL_VTX_ATTR_1F(x) (0x00001e40+((x)*4)) +#define NV40TCL_VTX_ATTR_1F__SIZE 0x00000010 +#define NV40TCL_VP_UPLOAD_FROM_ID 0x00001e9c +#define NV40TCL_VP_START_FROM_ID 0x00001ea0 +#define NV40TCL_POINT_SIZE 0x00001ee0 +#define NV40TCL_POINT_SPRITE 0x00001ee8 +#define NV40TCL_VP_UPLOAD_CONST_ID 0x00001efc +#define NV40TCL_VP_UPLOAD_CONST_X(x) (0x00001f00+((x)*16)) +#define NV40TCL_VP_UPLOAD_CONST_X__SIZE 0x00000004 +#define NV40TCL_VP_UPLOAD_CONST_Y(x) (0x00001f04+((x)*16)) +#define NV40TCL_VP_UPLOAD_CONST_Y__SIZE 0x00000004 +#define NV40TCL_VP_UPLOAD_CONST_Z(x) (0x00001f08+((x)*16)) +#define NV40TCL_VP_UPLOAD_CONST_Z__SIZE 0x00000004 +#define NV40TCL_VP_UPLOAD_CONST_W(x) (0x00001f0c+((x)*16)) +#define NV40TCL_VP_UPLOAD_CONST_W__SIZE 0x00000004 +#define NV40TCL_TEX_CACHE_CTL 0x00001fd8 +#define NV40TCL_VP_ATTRIB_EN 0x00001ff0 +#define NV40TCL_VP_RESULT_EN 0x00001ff4 + + +#define NV44TCL 0x00004497 + + + +#define NV50_2D 0x0000502d + +#define NV50_2D_NOP 0x00000100 +#define NV50_2D_NOTIFY 0x00000104 +#define NV50_2D_DMA_NOTIFY 0x00000180 +#define NV50_2D_DMA_IN_MEMORY0 0x00000184 +#define NV50_2D_DMA_IN_MEMORY1 0x00000188 +#define NV50_2D_DMA_IN_MEMORY2 0x0000018c +#define NV50_2D_DST_FORMAT 0x00000200 +#define NV50_2D_DST_FORMAT_32BPP 0x000000cf +#define NV50_2D_DST_FORMAT_24BPP 0x000000e6 +#define NV50_2D_DST_FORMAT_16BPP 0x000000e8 +#define NV50_2D_DST_FORMAT_8BPP 0x000000f3 +#define NV50_2D_DST_FORMAT_15BPP 0x000000f8 +#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_32BPP 0x000000cf +#define NV50_2D_SRC_FORMAT_24BPP 0x000000e6 +#define NV50_2D_SRC_FORMAT_16BPP 0x000000e8 +#define NV50_2D_SRC_FORMAT_8BPP 0x000000f3 +#define NV50_2D_SRC_FORMAT_15BPP 0x000000f8 +#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_CLIP_X 0x00000280 +#define NV50_2D_CLIP_Y 0x00000284 +#define NV50_2D_CLIP_Z 0x00000288 +#define NV50_2D_CLIP_W 0x0000028c +#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_RECT_FORMAT 0x00000584 +#define NV50_2D_RECT_FORMAT_32BPP 0x000000cf +#define NV50_2D_RECT_FORMAT_24BPP 0x000000e6 +#define NV50_2D_RECT_FORMAT_16BPP 0x000000e8 +#define NV50_2D_RECT_FORMAT_8BPP 0x000000f3 +#define NV50_2D_RECT_FORMAT_15BPP 0x000000f8 +#define NV50_2D_RECT_COLOR 0x00000588 +#define NV50_2D_RECT_X1 0x00000600 +#define NV50_2D_RECT_Y1 0x00000604 +#define NV50_2D_RECT_X2 0x00000608 +#define NV50_2D_RECT_Y2 0x0000060c +#define NV50_2D_SIFC_UNK0800 0x00000800 +#define NV50_2D_SIFC_FORMAT 0x00000804 +#define NV50_2D_SIFC_FORMAT_32BPP 0x000000cf +#define NV50_2D_SIFC_FORMAT_24BPP 0x000000e6 +#define NV50_2D_SIFC_FORMAT_16BPP 0x000000e8 +#define NV50_2D_SIFC_FORMAT_8BPP 0x000000f3 +#define NV50_2D_SIFC_FORMAT_15BPP 0x000000f8 +#define NV50_2D_SIFC_WIDTH 0x00000838 +#define NV50_2D_SIFC_HEIGHT 0x0000083c +#define NV50_2D_SIFC_SCALE_UNK0840 0x00000840 +#define NV50_2D_SIFC_SCALE_UNK0844 0x00000844 +#define NV50_2D_SIFC_SCALE_UNK0848 0x00000848 +#define NV50_2D_SIFC_SCALE_UNK084C 0x0000084c +#define NV50_2D_SIFC_UNK0850 0x00000850 +#define NV50_2D_SIFC_DST_X 0x00000854 +#define NV50_2D_SIFC_UNK0858 0x00000858 +#define NV50_2D_SIFC_DST_Y 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_SRC_X 0x000008d4 +#define NV50_2D_BLIT_SRC_Y 0x000008dc + + +#define NV50_MEMORY_TO_MEMORY_FORMAT 0x00005039 + +#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH 0x00000238 +#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH 0x0000023c + + +#define NV50TCL 0x00005097 + +#define NV50TCL_NOP 0x00000100 +#define NV50TCL_NOTIFY 0x00000104 +#define NV50TCL_DMA_NOTIFY 0x00000180 +#define NV50TCL_DMA_IN_MEMORY0(x) (0x00000184+((x)*4)) +#define NV50TCL_DMA_IN_MEMORY0__SIZE 0x0000000b +#define NV50TCL_DMA_IN_MEMORY1(x) (0x000001c0+((x)*4)) +#define NV50TCL_DMA_IN_MEMORY1__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_UNK3(x) (0x0000020c+((x)*32)) +#define NV50TCL_RT_UNK3__SIZE 0x00000008 +#define NV50TCL_RT_UNK4(x) (0x00000210+((x)*32)) +#define NV50TCL_RT_UNK4__SIZE 0x00000008 +#define NV50TCL_VTX_ATTR_1F(x) (0x00000300+((x)*4)) +#define NV50TCL_VTX_ATTR_1F__SIZE 0x00000010 +#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_3F_W(x) (0x0000040c+((x)*16)) +#define NV50TCL_VTX_ATTR_3F_W__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_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_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_VERTEX_ARRAY_FORMAT(x) (0x00000900+((x)*16)) +#define NV50TCL_VERTEX_ARRAY_FORMAT__SIZE 0x00000010 +#define NV50TCL_VIEWPORT_UNK0(x) (0x00000a00+((x)*4)) +#define NV50TCL_VIEWPORT_UNK0__SIZE 0x00000003 +#define NV50TCL_VIEWPORT_UNK1(x) (0x00000a0c+((x)*4)) +#define NV50TCL_VIEWPORT_UNK1__SIZE 0x00000003 +#define NV50TCL_VIEWPORT_HORIZ 0x00000c00 +#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 0x00000c04 +#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 0x00000c08 +#define NV50TCL_DEPTH_RANGE_FAR 0x00000c0c +#define NV50TCL_VIEWPORT_CLIP_HORIZ(x) (0x00000d00+((x)*8)) +#define NV50TCL_VIEWPORT_CLIP_HORIZ__SIZE 0x00000008 +#define NV50TCL_VIEWPORT_CLIP_VERT(x) (0x00000d04+((x)*8)) +#define NV50TCL_VIEWPORT_CLIP_VERT__SIZE 0x00000008 +#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_CLEAR_STENCIL 0x00000da0 +#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_SCISSOR_HORIZ 0x00000e04 +#define NV50TCL_SCISSOR_HORIZ_L_SHIFT 0 +#define NV50TCL_SCISSOR_HORIZ_L_MASK 0x0000ffff +#define NV50TCL_SCISSOR_HORIZ_R_SHIFT 16 +#define NV50TCL_SCISSOR_HORIZ_R_MASK 0xffff0000 +#define NV50TCL_SCISSOR_VERT 0x00000e08 +#define NV50TCL_SCISSOR_VERT_T_SHIFT 0 +#define NV50TCL_SCISSOR_VERT_T_MASK 0x0000ffff +#define NV50TCL_SCISSOR_VERT_B_SHIFT 16 +#define NV50TCL_SCISSOR_VERT_B_MASK 0xffff0000 +#define NV50TCL_VP_UPLOAD_CONST_ID 0x00000f00 +#define NV50TCL_VP_UPLOAD_CONST(x) (0x00000f04+((x)*4)) +#define NV50TCL_VP_UPLOAD_CONST__SIZE 0x00000010 +#define NV50TCL_STENCIL_FRONT_FUNC_REF 0x00000f54 +#define NV50TCL_STENCIL_FRONT_MASK 0x00000f58 +#define NV50TCL_STENCIL_FRONT_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_FP_ADDRESS_HIGH 0x00000fa4 +#define NV50TCL_FP_ADDRESS_LOW 0x00000fa8 +#define NV50TCL_ZETA_ADDRESS_HIGH 0x00000fe0 +#define NV50TCL_ZETA_ADDRESS_LOW 0x00000fe4 +#define NV50TCL_UNKFF4 0x00000ff4 +#define NV50TCL_UNKFF4_W_SHIFT 16 +#define NV50TCL_UNKFF4_W_MASK 0xffff0000 +#define NV50TCL_UNKFF8 0x00000ff8 +#define NV50TCL_UNKFF8_H_SHIFT 16 +#define NV50TCL_UNKFF8_H_MASK 0xffff0000 +#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_DEPTH_TEST_ENABLE 0x000012cc +#define NV50TCL_SHADE_MODEL 0x000012d4 +#define NV50TCL_SHADE_MODEL_FLAT 0x00001d00 +#define NV50TCL_SHADE_MODEL_SMOOTH 0x00001d01 +#define NV50TCL_DEPTH_WRITE_ENABLE 0x000012e8 +#define NV50TCL_ALPHA_TEST_ENABLE 0x000012ec +#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_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_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_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 0x00000000 +#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE 0x00000001 +#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC_COLOR 0x00000300 +#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA 0x00000302 +#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV50TCL_BLEND_FUNC_SRC_RGB_DST_ALPHA 0x00000304 +#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV50TCL_BLEND_FUNC_SRC_RGB_DST_COLOR 0x00000306 +#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_DST_COLOR 0x00000307 +#define NV50TCL_BLEND_FUNC_SRC_RGB_SRC_ALPHA_SATURATE 0x00000308 +#define NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_COLOR 0x00008001 +#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV50TCL_BLEND_FUNC_SRC_RGB_CONSTANT_ALPHA 0x00008003 +#define NV50TCL_BLEND_FUNC_SRC_RGB_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV50TCL_BLEND_FUNC_DST_RGB 0x00001348 +#define NV50TCL_BLEND_FUNC_DST_RGB_ZERO 0x00000000 +#define NV50TCL_BLEND_FUNC_DST_RGB_ONE 0x00000001 +#define NV50TCL_BLEND_FUNC_DST_RGB_SRC_COLOR 0x00000300 +#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV50TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA 0x00000302 +#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV50TCL_BLEND_FUNC_DST_RGB_DST_ALPHA 0x00000304 +#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV50TCL_BLEND_FUNC_DST_RGB_DST_COLOR 0x00000306 +#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_DST_COLOR 0x00000307 +#define NV50TCL_BLEND_FUNC_DST_RGB_SRC_ALPHA_SATURATE 0x00000308 +#define NV50TCL_BLEND_FUNC_DST_RGB_CONSTANT_COLOR 0x00008001 +#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV50TCL_BLEND_FUNC_DST_RGB_CONSTANT_ALPHA 0x00008003 +#define NV50TCL_BLEND_FUNC_DST_RGB_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#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 0x00000000 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE 0x00000001 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_COLOR 0x00000300 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA 0x00000302 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_DST_ALPHA 0x00000304 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_DST_COLOR 0x00000306 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_DST_COLOR 0x00000307 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA_SATURATE 0x00000308 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_COLOR 0x00008001 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_CONSTANT_ALPHA 0x00008003 +#define NV50TCL_BLEND_FUNC_SRC_ALPHA_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV50TCL_BLEND_FUNC_DST_ALPHA 0x00001358 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_ZERO 0x00000000 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE 0x00000001 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_COLOR 0x00000300 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_COLOR 0x00000301 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA 0x00000302 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_SRC_ALPHA 0x00000303 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_DST_ALPHA 0x00000304 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_ALPHA 0x00000305 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_DST_COLOR 0x00000306 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_DST_COLOR 0x00000307 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_SRC_ALPHA_SATURATE 0x00000308 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_COLOR 0x00008001 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_COLOR 0x00008002 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_CONSTANT_ALPHA 0x00008003 +#define NV50TCL_BLEND_FUNC_DST_ALPHA_ONE_MINUS_CONSTANT_ALPHA 0x00008004 +#define NV50TCL_BLEND_ENABLE(x) (0x00001360+((x)*4)) +#define NV50TCL_BLEND_ENABLE__SIZE 0x00000008 +#define NV50TCL_STENCIL_BACK_ENABLE 0x00001380 +#define NV50TCL_STENCIL_BACK_OP_FAIL 0x00001384 +#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 0x00001388 +#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 0x0000138c +#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 0x00001390 +#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_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_STENCIL_BACK_FUNC_REF 0x00001394 +#define NV50TCL_STENCIL_BACK_MASK 0x00001398 +#define NV50TCL_STENCIL_BACK_FUNC_MASK 0x0000139c +#define NV50TCL_LINE_WIDTH 0x000013b0 +#define NV50TCL_VP_START_ID 0x0000140c +#define NV50TCL_GP_START_ID 0x00001410 +#define NV50TCL_FP_START_ID 0x00001414 +#define NV50TCL_POINT_SIZE 0x00001518 +#define NV50TCL_TEX_CB0_ADDRESS_HIGH 0x0000155c +#define NV50TCL_TEX_CB0_ADDRESS_LOW 0x00001560 +#define NV50TCL_POLYGON_OFFSET_FACTOR 0x0000156c +#define NV50TCL_LINE_SMOOTH_ENABLE 0x00001570 +#define NV50TCL_TEX_CB1_ADDRESS_HIGH 0x00001574 +#define NV50TCL_TEX_CB1_ADDRESS_LOW 0x00001578 +#define NV50TCL_STENCIL_FRONT_ENABLE 0x00001594 +#define NV50TCL_STENCIL_FRONT_OP_FAIL 0x00001598 +#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 0x0000159c +#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 0x000015a0 +#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 0x000015a4 +#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_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_POLYGON_OFFSET_UNITS 0x000015bc +#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_END 0x000015e0 +#define NV50TCL_VERTEX_DATA 0x00001640 +#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_LINE_STIPPLE_ENABLE 0x0000166c +#define NV50TCL_LINE_STIPPLE_PATTERN 0x00001680 +#define NV50TCL_POLYGON_STIPPLE_ENABLE 0x0000168c +#define NV50TCL_VP_REG_HPOS 0x000016bc +#define NV50TCL_VP_REG_HPOS_X_SHIFT 0 +#define NV50TCL_VP_REG_HPOS_X_MASK 0x000000ff +#define NV50TCL_VP_REG_HPOS_Y_SHIFT 8 +#define NV50TCL_VP_REG_HPOS_Y_MASK 0x0000ff00 +#define NV50TCL_VP_REG_HPOS_Z_SHIFT 16 +#define NV50TCL_VP_REG_HPOS_Z_MASK 0x00ff0000 +#define NV50TCL_VP_REG_HPOS_W_SHIFT 24 +#define NV50TCL_VP_REG_HPOS_W_MASK 0xff000000 +#define NV50TCL_VP_REG_COL0 0x000016c0 +#define NV50TCL_VP_REG_COL0_X_SHIFT 0 +#define NV50TCL_VP_REG_COL0_X_MASK 0x000000ff +#define NV50TCL_VP_REG_COL0_Y_SHIFT 8 +#define NV50TCL_VP_REG_COL0_Y_MASK 0x0000ff00 +#define NV50TCL_VP_REG_COL0_Z_SHIFT 16 +#define NV50TCL_VP_REG_COL0_Z_MASK 0x00ff0000 +#define NV50TCL_VP_REG_COL0_W_SHIFT 24 +#define NV50TCL_VP_REG_COL0_W_MASK 0xff000000 +#define NV50TCL_POLYGON_STIPPLE_PATTERN(x) (0x00001700+((x)*4)) +#define NV50TCL_POLYGON_STIPPLE_PATTERN__SIZE 0x00000020 +#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_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_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 NV50_COMPUTE 0x000050c0 + +#define NV50_COMPUTE_DMA_UNK0 0x000001a0 +#define NV50_COMPUTE_DMA_STATUS 0x000001a4 +#define NV50_COMPUTE_DMA_UNK1 0x000001b8 +#define NV50_COMPUTE_DMA_UNK2 0x000001bc +#define NV50_COMPUTE_DMA_UNK3 0x000001c0 +#define NV50_COMPUTE_UNK4_HIGH 0x00000210 +#define NV50_COMPUTE_UNK4_LOW 0x00000214 +#define NV50_COMPUTE_UNK5_HIGH 0x00000218 +#define NV50_COMPUTE_UNK5_LOW 0x0000021c +#define NV50_COMPUTE_UNK6_HIGH 0x00000294 +#define NV50_COMPUTE_UNK6_LOW 0x00000298 +#define NV50_COMPUTE_CONST_BASE_HIGH 0x000002a4 +#define NV50_COMPUTE_CONST_BASE_LO 0x000002a8 +#define NV50_COMPUTE_CONST_SIZE_SEG 0x000002ac +#define NV50_COMPUTE_REG_COUNT 0x000002c0 +#define NV50_COMPUTE_STATUS_HIGH 0x00000310 +#define NV50_COMPUTE_STATUS_LOW 0x00000314 +#define NV50_COMPUTE_EXECUTE 0x0000031c +#define NV50_COMPUTE_USER_PARAM_COUNT 0x00000374 +#define NV50_COMPUTE_GRIDDIM_YX 0x000003a4 +#define NV50_COMPUTE_SHARED_SIZE 0x000003a8 +#define NV50_COMPUTE_BLOCKDIM_YX 0x000003ac +#define NV50_COMPUTE_BLOCKDIM_Z 0x000003b0 +#define NV50_COMPUTE_CALL_ADDRESS 0x000003b4 +#define NV50_COMPUTE_GLOBAL_BASE_HIGH(x) (0x00000400+((x)*32)) +#define NV50_COMPUTE_GLOBAL_BASE_HIGH__SIZE 0x00000010 +#define NV50_COMPUTE_GLOBAL_BASE_LOW(x) (0x00000404+((x)*32)) +#define NV50_COMPUTE_GLOBAL_BASE_LOW__SIZE 0x00000010 +#define NV50_COMPUTE_GLOBAL_LIMIT_HIGH(x) (0x00000408+((x)*32)) +#define NV50_COMPUTE_GLOBAL_LIMIT_HIGH__SIZE 0x00000010 +#define NV50_COMPUTE_GLOBAL_LIMIT_LOW(x) (0x0000040c+((x)*32)) +#define NV50_COMPUTE_GLOBAL_LIMIT_LOW__SIZE 0x00000010 +#define NV50_COMPUTE_GLOBAL_UNK(x) (0x00000410+((x)*32)) +#define NV50_COMPUTE_GLOBAL_UNK__SIZE 0x00000010 +#define NV50_COMPUTE_USER_PARAM(x) (0x00000600+((x)*4)) +#define NV50_COMPUTE_USER_PARAM__SIZE 0x00000040 + + +#define NV54TCL 0x00008297 + + + +#endif /* NOUVEAU_REG_H */ diff --git a/src/gallium/drivers/nouveau/nouveau_device.h b/src/gallium/drivers/nouveau/nouveau_device.h new file mode 100644 index 00000000000..e25e89fedda --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_device.h @@ -0,0 +1,30 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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. + */ + +#ifndef __NOUVEAU_DEVICE_H__ +#define __NOUVEAU_DEVICE_H__ + +struct nouveau_device { + unsigned chipset; +}; + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_gldefs.h b/src/gallium/drivers/nouveau/nouveau_gldefs.h new file mode 100644 index 00000000000..e1015c93a27 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_gldefs.h @@ -0,0 +1,196 @@ +#ifndef __NOUVEAU_GLDEFS_H__ +#define __NOUVEAU_GLDEFS_H__ + +static INLINE unsigned +nvgl_blend_func(unsigned factor) +{ + switch (factor) { + case PIPE_BLENDFACTOR_ZERO: + return 0x0000; + case PIPE_BLENDFACTOR_ONE: + return 0x0001; + case PIPE_BLENDFACTOR_SRC_COLOR: + return 0x0300; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + return 0x0301; + case PIPE_BLENDFACTOR_SRC_ALPHA: + return 0x0302; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + return 0x0303; + case PIPE_BLENDFACTOR_DST_ALPHA: + return 0x0304; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + return 0x0305; + case PIPE_BLENDFACTOR_DST_COLOR: + return 0x0306; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + return 0x0307; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + return 0x0308; + case PIPE_BLENDFACTOR_CONST_COLOR: + return 0x8001; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + return 0x8002; + case PIPE_BLENDFACTOR_CONST_ALPHA: + return 0x8003; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + return 0x8004; + default: + return 0x0000; + } +} + +static INLINE unsigned +nvgl_blend_eqn(unsigned func) +{ + switch (func) { + case PIPE_BLEND_ADD: + return 0x8006; + case PIPE_BLEND_MIN: + return 0x8007; + case PIPE_BLEND_MAX: + return 0x8008; + case PIPE_BLEND_SUBTRACT: + return 0x800a; + case PIPE_BLEND_REVERSE_SUBTRACT: + return 0x800b; + default: + return 0x8006; + } +} + +static INLINE unsigned +nvgl_logicop_func(unsigned func) +{ + switch (func) { + case PIPE_LOGICOP_CLEAR: + return 0x1500; + case PIPE_LOGICOP_NOR: + return 0x1508; + case PIPE_LOGICOP_AND_INVERTED: + return 0x1504; + case PIPE_LOGICOP_COPY_INVERTED: + return 0x150c; + case PIPE_LOGICOP_AND_REVERSE: + return 0x1502; + case PIPE_LOGICOP_INVERT: + return 0x150a; + case PIPE_LOGICOP_XOR: + return 0x1506; + case PIPE_LOGICOP_NAND: + return 0x150e; + case PIPE_LOGICOP_AND: + return 0x1501; + case PIPE_LOGICOP_EQUIV: + return 0x1509; + case PIPE_LOGICOP_NOOP: + return 0x1505; + case PIPE_LOGICOP_OR_INVERTED: + return 0x150d; + case PIPE_LOGICOP_COPY: + return 0x1503; + case PIPE_LOGICOP_OR_REVERSE: + return 0x150b; + case PIPE_LOGICOP_OR: + return 0x1507; + case PIPE_LOGICOP_SET: + return 0x150f; + default: + return 0x1505; + } +} + +static INLINE unsigned +nvgl_comparison_op(unsigned op) +{ + switch (op) { + case PIPE_FUNC_NEVER: + return 0x0200; + case PIPE_FUNC_LESS: + return 0x0201; + case PIPE_FUNC_EQUAL: + return 0x0202; + case PIPE_FUNC_LEQUAL: + return 0x0203; + case PIPE_FUNC_GREATER: + return 0x0204; + case PIPE_FUNC_NOTEQUAL: + return 0x0205; + case PIPE_FUNC_GEQUAL: + return 0x0206; + case PIPE_FUNC_ALWAYS: + return 0x0207; + default: + return 0x0207; + } +} + +static INLINE unsigned +nvgl_polygon_mode(unsigned mode) +{ + switch (mode) { + case PIPE_POLYGON_MODE_POINT: + return 0x1b00; + case PIPE_POLYGON_MODE_LINE: + return 0x1b01; + case PIPE_POLYGON_MODE_FILL: + return 0x1b02; + default: + return 0x1b02; + } +} + +static INLINE unsigned +nvgl_stencil_op(unsigned op) +{ + switch (op) { + case PIPE_STENCIL_OP_ZERO: + return 0x0000; + case PIPE_STENCIL_OP_INVERT: + return 0x150a; + case PIPE_STENCIL_OP_KEEP: + return 0x1e00; + case PIPE_STENCIL_OP_REPLACE: + return 0x1e01; + case PIPE_STENCIL_OP_INCR: + return 0x1e02; + case PIPE_STENCIL_OP_DECR: + return 0x1e03; + case PIPE_STENCIL_OP_INCR_WRAP: + return 0x8507; + case PIPE_STENCIL_OP_DECR_WRAP: + return 0x8508; + default: + return 0x1e00; + } +} + +static INLINE unsigned +nvgl_primitive(unsigned prim) { + switch (prim) { + case PIPE_PRIM_POINTS: + return 0x0001; + case PIPE_PRIM_LINES: + return 0x0002; + case PIPE_PRIM_LINE_LOOP: + return 0x0003; + case PIPE_PRIM_LINE_STRIP: + return 0x0004; + case PIPE_PRIM_TRIANGLES: + return 0x0005; + case PIPE_PRIM_TRIANGLE_STRIP: + return 0x0006; + case PIPE_PRIM_TRIANGLE_FAN: + return 0x0007; + case PIPE_PRIM_QUADS: + return 0x0008; + case PIPE_PRIM_QUAD_STRIP: + return 0x0009; + case PIPE_PRIM_POLYGON: + return 0x000a; + default: + return 0x0001; + } +} + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_grobj.h b/src/gallium/drivers/nouveau/nouveau_grobj.h new file mode 100644 index 00000000000..8f5abf90514 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_grobj.h @@ -0,0 +1,35 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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. + */ + +#ifndef __NOUVEAU_GROBJ_H__ +#define __NOUVEAU_GROBJ_H__ + +#include "nouveau_channel.h" + +struct nouveau_grobj { + struct nouveau_channel *channel; + int grclass; + uint32_t handle; + int subc; +}; + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_notifier.h b/src/gallium/drivers/nouveau/nouveau_notifier.h new file mode 100644 index 00000000000..35adde1e324 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_notifier.h @@ -0,0 +1,43 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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. + */ + +#ifndef __NOUVEAU_NOTIFIER_H__ +#define __NOUVEAU_NOTIFIER_H__ + +#define NV_NOTIFIER_SIZE 32 +#define NV_NOTIFY_TIME_0 0x00000000 +#define NV_NOTIFY_TIME_1 0x00000004 +#define NV_NOTIFY_RETURN_VALUE 0x00000008 +#define NV_NOTIFY_STATE 0x0000000C +#define NV_NOTIFY_STATE_STATUS_MASK 0xFF000000 +#define NV_NOTIFY_STATE_STATUS_SHIFT 24 +#define NV_NOTIFY_STATE_STATUS_COMPLETED 0x00 +#define NV_NOTIFY_STATE_STATUS_IN_PROCESS 0x01 +#define NV_NOTIFY_STATE_ERROR_CODE_MASK 0x0000FFFF +#define NV_NOTIFY_STATE_ERROR_CODE_SHIFT 0 + +struct nouveau_notifier { + struct nouveau_channel *channel; + uint32_t handle; +}; + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_push.h b/src/gallium/drivers/nouveau/nouveau_push.h new file mode 100644 index 00000000000..54ef1c1291e --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_push.h @@ -0,0 +1,82 @@ +#ifndef __NOUVEAU_PUSH_H__ +#define __NOUVEAU_PUSH_H__ + +#include "nouveau/nouveau_winsys.h" + +#ifndef NOUVEAU_PUSH_CONTEXT +#error undefined push context +#endif + +#define OUT_RING(data) do { \ + NOUVEAU_PUSH_CONTEXT(pc); \ + (*pc->nvws->channel->pushbuf->cur++) = (data); \ +} while(0) + +#define OUT_RINGp(src,size) do { \ + NOUVEAU_PUSH_CONTEXT(pc); \ + memcpy(pc->nvws->channel->pushbuf->cur, (src), (size) * 4); \ + pc->nvws->channel->pushbuf->cur += (size); \ +} while(0) + +#define OUT_RINGf(data) do { \ + union { float v; uint32_t u; } c; \ + c.v = (data); \ + OUT_RING(c.u); \ +} while(0) + +#define BEGIN_RING(obj,mthd,size) do { \ + NOUVEAU_PUSH_CONTEXT(pc); \ + if (pc->nvws->channel->pushbuf->remaining < ((size) + 1)) \ + pc->nvws->push_flush(pc->nvws, ((size) + 1), NULL); \ + OUT_RING((pc->obj->subc << 13) | ((size) << 18) | (mthd)); \ + pc->nvws->channel->pushbuf->remaining -= ((size) + 1); \ +} while(0) + +#define BEGIN_RING_NI(obj,mthd,size) do { \ + BEGIN_RING(obj, (mthd) | 0x40000000, (size)); \ +} while(0) + +#define FIRE_RING(fence) do { \ + NOUVEAU_PUSH_CONTEXT(pc); \ + pc->nvws->push_flush(pc->nvws, 0, fence); \ +} while(0) + +#define OUT_RELOC(bo,data,flags,vor,tor) do { \ + NOUVEAU_PUSH_CONTEXT(pc); \ + pc->nvws->push_reloc(pc->nvws, pc->nvws->channel->pushbuf->cur++, \ + (bo), (data), (flags), (vor), (tor)); \ +} while(0) + +/* Raw data + flags depending on FB/TT buffer */ +#define OUT_RELOCd(bo,data,flags,vor,tor) do { \ + OUT_RELOC((bo), (data), (flags) | NOUVEAU_BO_OR, (vor), (tor)); \ +} while(0) + +/* FB/TT object handle */ +#define OUT_RELOCo(bo,flags) do { \ + OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR, \ + pc->nvws->channel->vram->handle, \ + pc->nvws->channel->gart->handle); \ +} while(0) + +/* Low 32-bits of offset */ +#define OUT_RELOCl(bo,delta,flags) do { \ + OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_LOW, 0, 0); \ +} while(0) + +/* High 32-bits of offset */ +#define OUT_RELOCh(bo,delta,flags) do { \ + OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_HIGH, 0, 0); \ +} while(0) + +/* A reloc which'll recombine into a NV_DMA_METHOD packet header */ +#define OUT_RELOCm(bo, flags, obj, mthd, size) do { \ + NOUVEAU_PUSH_CONTEXT(pc); \ + if (pc->nvws->channel->pushbuf->remaining < ((size) + 1)) \ + pc->nvws->push_flush(pc->nvws->channel, ((size) + 1), NULL); \ + OUT_RELOCd((bo), (pc->obj->subc << 13) | ((size) << 18) | (mthd), \ + (flags), 0, 0); \ + pc->nvws->channel->pushbuf->remaining -= ((size) + 1); \ +} while(0) + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_pushbuf.h b/src/gallium/drivers/nouveau/nouveau_pushbuf.h new file mode 100644 index 00000000000..19097650982 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_pushbuf.h @@ -0,0 +1,32 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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. + */ + +#ifndef __NOUVEAU_PUSHBUF_H__ +#define __NOUVEAU_PUSHBUF_H__ + +struct nouveau_pushbuf { + struct nouveau_channel *channel; + unsigned remaining; + uint32_t *cur; +}; + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_resource.h b/src/gallium/drivers/nouveau/nouveau_resource.h new file mode 100644 index 00000000000..1af7961d301 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_resource.h @@ -0,0 +1,37 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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. + */ + +#ifndef __NOUVEAU_RESOURCE_H__ +#define __NOUVEAU_RESOURCE_H__ + +struct nouveau_resource { + struct nouveau_resource *prev; + struct nouveau_resource *next; + + int in_use; + void *priv; + + unsigned int start; + unsigned int size; +}; + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h new file mode 100644 index 00000000000..d501b76b51e --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -0,0 +1,138 @@ +#ifndef __NOUVEAU_STATEOBJ_H__ +#define __NOUVEAU_STATEOBJ_H__ + +#include "pipe/p_util.h" + +struct nouveau_stateobj_reloc { + struct pipe_buffer *bo; + + unsigned offset; + unsigned packet; + + unsigned data; + unsigned flags; + unsigned vor; + unsigned tor; +}; + +struct nouveau_stateobj { + int refcount; + + unsigned *push; + struct nouveau_stateobj_reloc *reloc; + + unsigned *cur; + unsigned cur_packet; + unsigned cur_reloc; +}; + +static INLINE struct nouveau_stateobj * +so_new(unsigned push, unsigned reloc) +{ + struct nouveau_stateobj *so; + + so = MALLOC(sizeof(struct nouveau_stateobj)); + so->refcount = 0; + so->push = MALLOC(sizeof(unsigned) * push); + so->reloc = MALLOC(sizeof(struct nouveau_stateobj_reloc) * reloc); + + so->cur = so->push; + so->cur_reloc = so->cur_packet = 0; + + return so; +} + +static INLINE void +so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso) +{ + struct nouveau_stateobj *so = *pso; + + if (ref) { + ref->refcount++; + } + + if (so && --so->refcount <= 0) { + free(so->push); + free(so->reloc); + free(so); + } + + *pso = ref; +} + +static INLINE void +so_data(struct nouveau_stateobj *so, unsigned data) +{ + (*so->cur++) = (data); + so->cur_packet += 4; +} + +static INLINE void +so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr, + unsigned mthd, unsigned size) +{ + so->cur_packet = (gr->subc << 13) | (1 << 18) | (mthd - 4); + so_data(so, (gr->subc << 13) | (size << 18) | mthd); +} + +static INLINE void +so_reloc(struct nouveau_stateobj *so, struct pipe_buffer *bo, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + struct nouveau_stateobj_reloc *r = &so->reloc[so->cur_reloc++]; + + r->bo = bo; + r->offset = so->cur - so->push; + r->packet = so->cur_packet; + r->data = data; + r->flags = flags; + r->vor = vor; + r->tor = tor; + so_data(so, data); +} + +static INLINE void +so_emit(struct nouveau_winsys *nvws, struct nouveau_stateobj *so) +{ + struct nouveau_pushbuf *pb = nvws->channel->pushbuf; + unsigned nr, i; + + nr = so->cur - so->push; + if (pb->remaining < nr) + nvws->push_flush(nvws, nr, NULL); + pb->remaining -= nr; + + memcpy(pb->cur, so->push, nr * 4); + for (i = 0; i < so->cur_reloc; i++) { + struct nouveau_stateobj_reloc *r = &so->reloc[i]; + + nvws->push_reloc(nvws, pb->cur + r->offset, r->bo, + r->data, r->flags, r->vor, r->tor); + } + pb->cur += nr; +} + +static INLINE void +so_emit_reloc_markers(struct nouveau_winsys *nvws, struct nouveau_stateobj *so) +{ + struct nouveau_pushbuf *pb = nvws->channel->pushbuf; + unsigned i; + + i = so->cur_reloc << 1; + if (nvws->channel->pushbuf->remaining < i) + nvws->push_flush(nvws, i, NULL); + nvws->channel->pushbuf->remaining -= i; + + for (i = 0; i < so->cur_reloc; i++) { + struct nouveau_stateobj_reloc *r = &so->reloc[i]; + + nvws->push_reloc(nvws, pb->cur++, r->bo, r->packet, + (r->flags & + (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART)) | + NOUVEAU_BO_DUMMY, 0, 0); + nvws->push_reloc(nvws, pb->cur++, r->bo, r->data, + r->flags | NOUVEAU_BO_DUMMY, r->vor, r->tor); + } +} + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_util.h b/src/gallium/drivers/nouveau/nouveau_util.h new file mode 100644 index 00000000000..c92041ebeba --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_util.h @@ -0,0 +1,64 @@ +#ifndef __NOUVEAU_UTIL_H__ +#define __NOUVEAU_UTIL_H__ + +/* Determine how many vertices can be pushed into the command stream. + * Where the remaining space isn't large enough to represent all verices, + * split the buffer at primitive boundaries. + * + * Returns a count of vertices that can be rendered, and an index to + * restart drawing at after a flush. + */ +static INLINE unsigned +nouveau_vbuf_split(unsigned remaining, unsigned overhead, unsigned vpp, + unsigned mode, unsigned start, unsigned count, + unsigned *restart) +{ + int max, adj = 0; + + max = remaining - overhead; + if (max < 0) + return 0; + + max *= vpp; + if (max >= count) + return count; + + switch (mode) { + case PIPE_PRIM_POINTS: + break; + case PIPE_PRIM_LINES: + max = max & 1; + break; + case PIPE_PRIM_TRIANGLES: + max = max - (max % 3); + break; + case PIPE_PRIM_QUADS: + max = max & 3; + break; + case PIPE_PRIM_LINE_LOOP: + case PIPE_PRIM_LINE_STRIP: + if (max < 2) + max = 0; + adj = 1; + break; + case PIPE_PRIM_POLYGON: + case PIPE_PRIM_TRIANGLE_STRIP: + case PIPE_PRIM_TRIANGLE_FAN: + if (max < 3) + max = 0; + adj = 2; + break; + case PIPE_PRIM_QUAD_STRIP: + if (max < 4) + max = 0; + adj = 3; + break; + default: + assert(0); + } + + *restart = start + max - adj; + return max; +} + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h new file mode 100644 index 00000000000..07a41dcf4a1 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -0,0 +1,83 @@ +#ifndef NOUVEAU_WINSYS_H +#define NOUVEAU_WINSYS_H + +#include <stdint.h> +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" + +#include "nouveau/nouveau_bo.h" +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_class.h" +#include "nouveau/nouveau_device.h" +#include "nouveau/nouveau_grobj.h" +#include "nouveau/nouveau_notifier.h" +#include "nouveau/nouveau_resource.h" +#include "nouveau/nouveau_pushbuf.h" + +#define NOUVEAU_CAP_HW_VTXBUF (0xbeef0000) +#define NOUVEAU_CAP_HW_IDXBUF (0xbeef0001) + +#define NOUVEAU_BUFFER_USAGE_TEXTURE (1 << 16) + +struct nouveau_winsys { + struct nouveau_context *nv; + + struct nouveau_channel *channel; + + int (*res_init)(struct nouveau_resource **heap, unsigned start, + unsigned size); + int (*res_alloc)(struct nouveau_resource *heap, int size, void *priv, + struct nouveau_resource **); + void (*res_free)(struct nouveau_resource **); + + int (*push_reloc)(struct nouveau_winsys *, void *ptr, + struct pipe_buffer *, uint32_t data, + uint32_t flags, uint32_t vor, uint32_t tor); + int (*push_flush)(struct nouveau_winsys *, unsigned size, + struct pipe_fence_handle **fence); + + int (*grobj_alloc)(struct nouveau_winsys *, int grclass, + struct nouveau_grobj **); + void (*grobj_free)(struct nouveau_grobj **); + + int (*notifier_alloc)(struct nouveau_winsys *, int count, + struct nouveau_notifier **); + void (*notifier_free)(struct nouveau_notifier **); + void (*notifier_reset)(struct nouveau_notifier *, int id); + uint32_t (*notifier_status)(struct nouveau_notifier *, int id); + uint32_t (*notifier_retval)(struct nouveau_notifier *, int id); + int (*notifier_wait)(struct nouveau_notifier *, int id, + int status, int timeout); + + int (*surface_copy)(struct nouveau_winsys *, struct pipe_surface *, + unsigned, unsigned, struct pipe_surface *, + unsigned, unsigned, unsigned, unsigned); + int (*surface_fill)(struct nouveau_winsys *, struct pipe_surface *, + unsigned, unsigned, unsigned, unsigned, unsigned); +}; + +extern struct pipe_screen * +nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); + +extern struct pipe_context * +nv10_create(struct pipe_screen *, unsigned pctx_id); + +extern struct pipe_screen * +nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); + +extern struct pipe_context * +nv30_create(struct pipe_screen *, unsigned pctx_id); + +extern struct pipe_screen * +nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); + +extern struct pipe_context * +nv40_create(struct pipe_screen *, unsigned pctx_id); + +extern struct pipe_screen * +nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); + +extern struct pipe_context * +nv50_create(struct pipe_screen *, unsigned pctx_id); + +#endif diff --git a/src/gallium/drivers/nv10/Makefile b/src/gallium/drivers/nv10/Makefile new file mode 100644 index 00000000000..4ba7ce586d6 --- /dev/null +++ b/src/gallium/drivers/nv10/Makefile @@ -0,0 +1,28 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = nv10 + +DRIVER_SOURCES = \ + nv10_clear.c \ + nv10_context.c \ + nv10_fragprog.c \ + nv10_fragtex.c \ + nv10_miptree.c \ + nv10_prim_vbuf.c \ + nv10_screen.c \ + nv10_state.c \ + nv10_state_emit.c \ + nv10_surface.c \ + nv10_vbo.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/nv10/nv10_clear.c b/src/gallium/drivers/nv10/nv10_clear.c new file mode 100644 index 00000000000..be7e09cf4b0 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_clear.c @@ -0,0 +1,12 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "nv10_context.h" + +void +nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); +} diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c new file mode 100644 index 00000000000..9fcd0b0fc3a --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -0,0 +1,297 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv10_context.h" +#include "nv10_screen.h" + +static void +nv10_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + draw_flush(nv10->draw); + + FIRE_RING(fence); +} + +static void +nv10_destroy(struct pipe_context *pipe) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + if (nv10->draw) + draw_destroy(nv10->draw); + + FREE(nv10); +} + +static void nv10_init_hwctx(struct nv10_context *nv10) +{ + struct nv10_screen *screen = nv10->screen; + struct nouveau_winsys *nvws = screen->nvws; + int i; + float projectionmatrix[16]; + + BEGIN_RING(celsius, NV10TCL_DMA_NOTIFY, 1); + OUT_RING (screen->sync->handle); + BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY0, 2); + OUT_RING (nvws->channel->vram->handle); + OUT_RING (nvws->channel->gart->handle); + BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY2, 2); + OUT_RING (nvws->channel->vram->handle); + OUT_RING (nvws->channel->vram->handle); + + BEGIN_RING(celsius, NV10TCL_NOP, 1); + OUT_RING (0); + + BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 2); + OUT_RING (0); + OUT_RING (0); + + BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING ((0x7ff<<16)|0x800); + BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING ((0x7ff<<16)|0x800); + + for (i=1;i<8;i++) { + BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING (0); + } + + BEGIN_RING(celsius, 0x290, 1); + OUT_RING ((0x10<<16)|1); + BEGIN_RING(celsius, 0x3f4, 1); + OUT_RING (0); + + BEGIN_RING(celsius, NV10TCL_NOP, 1); + OUT_RING (0); + + if (nv10->screen->celsius->grclass != NV10TCL) { + /* For nv11, nv17 */ + BEGIN_RING(celsius, 0x120, 3); + OUT_RING (0); + OUT_RING (1); + OUT_RING (2); + + BEGIN_RING(celsius, NV10TCL_NOP, 1); + OUT_RING (0); + } + + BEGIN_RING(celsius, NV10TCL_NOP, 1); + OUT_RING (0); + + /* Set state */ + BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); + OUT_RING (0x207); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_TX_ENABLE(0), 2); + OUT_RING (0); + OUT_RING (0); + + BEGIN_RING(celsius, NV10TCL_RC_IN_ALPHA(0), 12); + OUT_RING (0x30141010); + OUT_RING (0); + OUT_RING (0x20040000); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0x00000c00); + OUT_RING (0); + OUT_RING (0x00000c00); + OUT_RING (0x18000000); + OUT_RING (0x300e0300); + OUT_RING (0x0c091c80); + + BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 2); + OUT_RING (1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_SRC, 4); + OUT_RING (1); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0x8006); + BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 8); + OUT_RING (0xff); + OUT_RING (0x207); + OUT_RING (0); + OUT_RING (0xff); + OUT_RING (0x1e00); + OUT_RING (0x1e00); + OUT_RING (0x1e00); + OUT_RING (0x1d01); + BEGIN_RING(celsius, NV10TCL_NORMALIZE_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 2); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_LIGHT_MODEL, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_COLOR_CONTROL, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_ENABLED_LIGHTS, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 1); + OUT_RING (0x201); + BEGIN_RING(celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING (8); + BEGIN_RING(celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_LINE_WIDTH, 1); + OUT_RING (8); + BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING (0x1b02); + OUT_RING (0x1b02); + BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); + OUT_RING (0x405); + OUT_RING (0x901); + BEGIN_RING(celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_CLIP_PLANE_ENABLE(0), 8); + for (i=0;i<8;i++) { + OUT_RING (0); + } + BEGIN_RING(celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RING (0x3fc00000); /* -1.50 */ + OUT_RING (0xbdb8aa0a); /* -0.09 */ + OUT_RING (0); /* 0.00 */ + + BEGIN_RING(celsius, NV10TCL_NOP, 1); + OUT_RING (0); + + BEGIN_RING(celsius, NV10TCL_FOG_MODE, 2); + OUT_RING (0x802); + OUT_RING (2); + /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when + * using texturing, except when using the texture matrix + */ + BEGIN_RING(celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1); + OUT_RING (6); + BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING (0x01010101); + + /* Set vertex component */ + BEGIN_RING(celsius, NV10TCL_VERTEX_COL_4F_R, 4); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + BEGIN_RING(celsius, NV10TCL_VERTEX_COL2_3F_R, 3); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_VERTEX_NOR_3F_X, 3); + OUT_RING (0); + OUT_RING (0); + OUT_RINGf (1.0); + BEGIN_RING(celsius, NV10TCL_VERTEX_TX0_4F_S, 4); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + BEGIN_RING(celsius, NV10TCL_VERTEX_TX1_4F_S, 4); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + BEGIN_RING(celsius, NV10TCL_VERTEX_FOG_1F, 1); + OUT_RINGf (0.0); + BEGIN_RING(celsius, NV10TCL_EDGEFLAG_ENABLE, 1); + OUT_RING (1); + + memset(projectionmatrix, 0, sizeof(projectionmatrix)); + BEGIN_RING(celsius, NV10TCL_PROJECTION_MATRIX(0), 16); + projectionmatrix[0*4+0] = 1.0; + projectionmatrix[1*4+1] = 1.0; + projectionmatrix[2*4+2] = 1.0; + projectionmatrix[3*4+3] = 1.0; + for (i=0;i<16;i++) { + OUT_RINGf (projectionmatrix[i]); + } + + BEGIN_RING(celsius, NV10TCL_DEPTH_RANGE_NEAR, 2); + OUT_RING (0.0); + OUT_RINGf (16777216.0); + + BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4); + OUT_RINGf (-2048.0); + OUT_RINGf (-2048.0); + OUT_RINGf (16777215.0 * 0.5); + OUT_RING (0); + + FIRE_RING (NULL); +} + +static void +nv10_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +{ +} + +struct pipe_context * +nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) +{ + struct nv10_screen *screen = nv10_screen(pscreen); + struct pipe_winsys *ws = pscreen->winsys; + struct nv10_context *nv10; + struct nouveau_winsys *nvws = screen->nvws; + + nv10 = CALLOC(1, sizeof(struct nv10_context)); + if (!nv10) + return NULL; + nv10->screen = screen; + nv10->pctx_id = pctx_id; + + nv10->nvws = nvws; + + nv10->pipe.winsys = ws; + nv10->pipe.screen = pscreen; + nv10->pipe.destroy = nv10_destroy; + nv10->pipe.set_edgeflags = nv10_set_edgeflags; + nv10->pipe.draw_arrays = nv10_draw_arrays; + nv10->pipe.draw_elements = nv10_draw_elements; + nv10->pipe.clear = nv10_clear; + nv10->pipe.flush = nv10_flush; + + nv10_init_surface_functions(nv10); + nv10_init_state_functions(nv10); + + nv10->draw = draw_create(); + assert(nv10->draw); + draw_set_rasterize_stage(nv10->draw, nv10_draw_vbuf_stage(nv10)); + + nv10_init_hwctx(nv10); + + return &nv10->pipe; +} + diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h new file mode 100644 index 00000000000..2bdba53db8a --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -0,0 +1,149 @@ +#ifndef __NV10_CONTEXT_H__ +#define __NV10_CONTEXT_H__ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "draw/draw_vertex.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_gldefs.h" + +#define NOUVEAU_PUSH_CONTEXT(ctx) \ + struct nv10_screen *ctx = nv10->screen +#include "nouveau/nouveau_push.h" + +#include "nv10_state.h" + +#define NOUVEAU_ERR(fmt, args...) \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); +#define NOUVEAU_MSG(fmt, args...) \ + fprintf(stderr, "nouveau: "fmt, ##args); + +#define NV10_NEW_VERTPROG (1 << 0) +#define NV10_NEW_FRAGPROG (1 << 1) +#define NV10_NEW_VTXARRAYS (1 << 2) +#define NV10_NEW_BLEND (1 << 3) +#define NV10_NEW_BLENDCOL (1 << 4) +#define NV10_NEW_RAST (1 << 5) +#define NV10_NEW_DSA (1 << 6) +#define NV10_NEW_VIEWPORT (1 << 7) +#define NV10_NEW_SCISSOR (1 << 8) +#define NV10_NEW_FRAMEBUFFER (1 << 9) + +#include "nv10_screen.h" + +struct nv10_context { + struct pipe_context pipe; + + struct nouveau_winsys *nvws; + struct nv10_screen *screen; + unsigned pctx_id; + + struct draw_context *draw; + + uint32_t dirty; + + struct nv10_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; + struct nv10_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; + unsigned dirty_samplers; + unsigned fp_samplers; + unsigned vp_samplers; + + uint32_t rt_enable; + struct pipe_buffer *rt[4]; + struct pipe_buffer *zeta; + uint32_t lma_offset; + + struct nv10_blend_state *blend; + struct pipe_blend_color *blend_color; + struct nv10_rasterizer_state *rast; + struct nv10_depth_stencil_alpha_state *dsa; + struct pipe_viewport_state *viewport; + struct pipe_scissor_state *scissor; + struct pipe_framebuffer_state *framebuffer; + + //struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + float *constbuf[PIPE_SHADER_TYPES][32][4]; + unsigned constbuf_nr[PIPE_SHADER_TYPES]; + + struct vertex_info vertex_info; + + struct { + struct pipe_buffer *buffer; + uint32_t format; + } tex[2]; + + unsigned vb_enable; + struct { + struct pipe_buffer *buffer; + unsigned delta; + } vb[16]; + +/* struct { + + struct nouveau_resource *exec_heap; + struct nouveau_resource *data_heap; + + struct nv10_vertex_program *active; + + struct nv10_vertex_program *current; + } vertprog; +*/ + struct { + struct nv10_fragment_program *active; + + struct nv10_fragment_program *current; + struct pipe_buffer *constant_buf; + } fragprog; + + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; +}; + +static INLINE struct nv10_context * +nv10_context(struct pipe_context *pipe) +{ + return (struct nv10_context *)pipe; +} + +extern void nv10_init_state_functions(struct nv10_context *nv10); +extern void nv10_init_surface_functions(struct nv10_context *nv10); + +extern void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen); + +/* nv10_clear.c */ +extern void nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + +/* nv10_draw.c */ +extern struct draw_stage *nv10_draw_render_stage(struct nv10_context *nv10); + +/* nv10_fragprog.c */ +extern void nv10_fragprog_bind(struct nv10_context *, + struct nv10_fragment_program *); +extern void nv10_fragprog_destroy(struct nv10_context *, + struct nv10_fragment_program *); + +/* nv10_fragtex.c */ +extern void nv10_fragtex_bind(struct nv10_context *); + +/* nv10_prim_vbuf.c */ +struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 ); +extern void nv10_vtxbuf_bind(struct nv10_context* nv10); + +/* nv10_state.c and friends */ +extern void nv10_emit_hw_state(struct nv10_context *nv10); +extern void nv10_state_tex_update(struct nv10_context *nv10); + +/* nv10_vbo.c */ +extern boolean nv10_draw_arrays(struct pipe_context *, unsigned mode, + unsigned start, unsigned count); +extern boolean nv10_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned prim, unsigned start, unsigned count); + + +#endif diff --git a/src/gallium/drivers/nv10/nv10_fragprog.c b/src/gallium/drivers/nv10/nv10_fragprog.c new file mode 100644 index 00000000000..2a63c8a704e --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_fragprog.c @@ -0,0 +1,22 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" + +#include "nv10_context.h" + +void +nv10_fragprog_bind(struct nv10_context *nv10, struct nv10_fragment_program *fp) +{ +} + +void +nv10_fragprog_destroy(struct nv10_context *nv10, + struct nv10_fragment_program *fp) +{ +} + diff --git a/src/gallium/drivers/nv10/nv10_fragtex.c b/src/gallium/drivers/nv10/nv10_fragtex.c new file mode 100644 index 00000000000..238634d0bb4 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_fragtex.c @@ -0,0 +1,149 @@ +#include "nv10_context.h" + +static INLINE int log2i(int i) +{ + int r = 0; + + if (i & 0xffff0000) { + i >>= 16; + r += 16; + } + if (i & 0x0000ff00) { + i >>= 8; + r += 8; + } + if (i & 0x000000f0) { + i >>= 4; + r += 4; + } + if (i & 0x0000000c) { + i >>= 2; + r += 2; + } + if (i & 0x00000002) { + r += 1; + } + return r; +} + +#define _(m,tf) \ +{ \ + TRUE, \ + PIPE_FORMAT_##m, \ + NV10TCL_TX_FORMAT_FORMAT_##tf, \ +} + +struct nv10_texture_format { + boolean defined; + uint pipe; + int format; +}; + +static struct nv10_texture_format +nv10_texture_formats[] = { + _(A8R8G8B8_UNORM, A8R8G8B8), + _(A1R5G5B5_UNORM, A1R5G5B5), + _(A4R4G4B4_UNORM, A4R4G4B4), + _(L8_UNORM , L8 ), + _(A8_UNORM , A8 ), + _(A8L8_UNORM , A8L8 ), +// _(RGB_DXT1 , DXT1, ), +// _(RGBA_DXT1 , DXT1, ), +// _(RGBA_DXT3 , DXT3, ), +// _(RGBA_DXT5 , DXT5, ), + {}, +}; + +static struct nv10_texture_format * +nv10_fragtex_format(uint pipe_format) +{ + struct nv10_texture_format *tf = nv10_texture_formats; + + while (tf->defined) { + if (tf->pipe == pipe_format) + return tf; + tf++; + } + + return NULL; +} + + +static void +nv10_fragtex_build(struct nv10_context *nv10, int unit) +{ +#if 0 + struct nv10_sampler_state *ps = nv10->tex_sampler[unit]; + struct nv10_miptree *nv10mt = nv10->tex_miptree[unit]; + struct pipe_texture *pt = &nv10mt->base; + struct nv10_texture_format *tf; + uint32_t txf, txs, txp; + + tf = nv10_fragtex_format(pt->format); + if (!tf || !tf->defined) { + NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format); + return; + } + + txf = tf->format << 8; + txf |= (pt->last_level + 1) << 16; + txf |= log2i(pt->width[0]) << 20; + txf |= log2i(pt->height[0]) << 24; + txf |= log2i(pt->depth[0]) << 28; + txf |= 8; + + switch (pt->target) { + case PIPE_TEXTURE_CUBE: + txf |= NV10TCL_TX_FORMAT_CUBE_MAP; + /* fall-through */ + case PIPE_TEXTURE_2D: + txf |= (2<<4); + break; + case PIPE_TEXTURE_1D: + txf |= (1<<4); + break; + default: + NOUVEAU_ERR("Unknown target %d\n", pt->target); + return; + } + + BEGIN_RING(celsius, NV10TCL_TX_OFFSET(unit), 8); + OUT_RELOCl(nv10mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCd(nv10mt->buffer,txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); + OUT_RING (ps->wrap); + OUT_RING (0x40000000); /* enable */ + OUT_RING (txs); + OUT_RING (ps->filt | 0x2000 /* magic */); + OUT_RING ((pt->width[0] << 16) | pt->height[0]); + OUT_RING (ps->bcol); +#endif +} + +void +nv10_fragtex_bind(struct nv10_context *nv10) +{ +#if 0 + struct nv10_fragment_program *fp = nv10->fragprog.active; + unsigned samplers, unit; + + samplers = nv10->fp_samplers & ~fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + BEGIN_RING(celsius, NV10TCL_TX_ENABLE(unit), 1); + OUT_RING (0); + } + + samplers = nv10->dirty_samplers & fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + nv10_fragtex_build(nv10, unit); + } + + nv10->fp_samplers = fp->samplers; +#endif +} + diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c new file mode 100644 index 00000000000..1b9947354d6 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -0,0 +1,147 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nv10_context.h" +#include "nv10_screen.h" + +static void +nv10_miptree_layout(struct nv10_miptree *nv10mt) +{ + struct pipe_texture *pt = &nv10mt->base; + boolean swizzled = FALSE; + uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; + uint offset = 0; + int nr_faces, l, f; + + if (pt->target == PIPE_TEXTURE_CUBE) { + nr_faces = 6; + } else { + nr_faces = 1; + } + + for (l = 0; l <= pt->last_level; l++) { + pt->width[l] = width; + pt->height[l] = height; + pt->depth[l] = depth; + + if (swizzled) + nv10mt->level[l].pitch = pt->width[l] * pt->cpp; + else + nv10mt->level[l].pitch = pt->width[0] * pt->cpp; + nv10mt->level[l].pitch = (nv10mt->level[l].pitch + 63) & ~63; + + nv10mt->level[l].image_offset = + CALLOC(nr_faces, sizeof(unsigned)); + + width = MAX2(1, width >> 1); + height = MAX2(1, height >> 1); + depth = MAX2(1, depth >> 1); + + } + + for (f = 0; f < nr_faces; f++) { + for (l = 0; l <= pt->last_level; l++) { + nv10mt->level[l].image_offset[f] = offset; + offset += nv10mt->level[l].pitch * pt->height[l]; + } + } + + nv10mt->total_size = offset; +} + +static struct pipe_texture * +nv10_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) +{ + struct pipe_winsys *ws = screen->winsys; + struct nv10_miptree *mt; + + mt = MALLOC(sizeof(struct nv10_miptree)); + if (!mt) + return NULL; + mt->base = *pt; + mt->base.refcount = 1; + mt->base.screen = screen; + + nv10_miptree_layout(mt); + + mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + mt->total_size); + if (!mt->buffer) { + FREE(mt); + return NULL; + } + + return &mt->base; +} + +static void +nv10_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) +{ + struct pipe_winsys *ws = screen->winsys; + struct pipe_texture *mt = *pt; + + *pt = NULL; + if (--mt->refcount <= 0) { + struct nv10_miptree *nv10mt = (struct nv10_miptree *)mt; + int l; + + pipe_buffer_reference(ws, &nv10mt->buffer, NULL); + for (l = 0; l <= mt->last_level; l++) { + if (nv10mt->level[l].image_offset) + FREE(nv10mt->level[l].image_offset); + } + FREE(nv10mt); + } +} + +static void +nv10_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, + uint face, uint levels) +{ +} + + +static struct pipe_surface * +nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) +{ + struct pipe_winsys *ws = screen->winsys; + struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt; + struct pipe_surface *ps; + + ps = ws->surface_alloc(ws); + if (!ps) + return NULL; + pipe_buffer_reference(ws, &ps->buffer, nv10mt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = nv10mt->level[level].pitch / ps->cpp; + + if (pt->target == PIPE_TEXTURE_CUBE) { + ps->offset = nv10mt->level[level].image_offset[face]; + } else { + ps->offset = nv10mt->level[level].image_offset[0]; + } + + return ps; +} + +static void +nv10_miptree_surface_release(struct pipe_screen *screen, + struct pipe_surface **surface) +{ +} + +void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen) +{ + pscreen->texture_create = nv10_miptree_create; + pscreen->texture_release = nv10_miptree_release; + pscreen->get_tex_surface = nv10_miptree_surface_get; + pscreen->tex_surface_release = nv10_miptree_surface_release; +} + diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c new file mode 100644 index 00000000000..930536b9468 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c @@ -0,0 +1,240 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +/** + * \file + * Build post-transformation, post-clipping vertex buffers and element + * lists by hooking into the end of the primitive pipeline and + * manipulating the vertex_id field in the vertex headers. + * + * XXX: work in progress + * + * \author José Fonseca <[email protected]> + * \author Keith Whitwell <[email protected]> + */ + + +#include "draw/draw_vbuf.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" + +#include "nv10_context.h" +#include "nv10_state.h" + + +/** + * Primitive renderer for nv10. + */ +struct nv10_vbuf_render { + struct vbuf_render base; + + struct nv10_context *nv10; + + /** Vertex buffer */ + struct pipe_buffer* buffer; + + /** Vertex size in bytes */ + unsigned vertex_size; + + /** Hardware primitive */ + unsigned hwprim; +}; + + +void nv10_vtxbuf_bind( struct nv10_context* nv10 ) +{ + int i; + for(i = 0; i < 8; i++) { + BEGIN_RING(celsius, NV10TCL_VERTEX_ARRAY_ATTRIB_OFFSET(i), 1); + OUT_RING(0/*nv10->vtxbuf*/); + BEGIN_RING(celsius, NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT(i) ,1); + OUT_RING(0/*XXX*/); + } +} + +/** + * Basically a cast wrapper. + */ +static INLINE struct nv10_vbuf_render * +nv10_vbuf_render( struct vbuf_render *render ) +{ + assert(render); + return (struct nv10_vbuf_render *)render; +} + + +static const struct vertex_info * +nv10_vbuf_render_get_vertex_info( struct vbuf_render *render ) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + struct nv10_context *nv10 = nv10_render->nv10; + + nv10_emit_hw_state(nv10); + + return &nv10->vertex_info; +} + + +static void * +nv10_vbuf_render_allocate_vertices( struct vbuf_render *render, + ushort vertex_size, + ushort nr_vertices ) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + struct nv10_context *nv10 = nv10_render->nv10; + struct pipe_winsys *winsys = nv10->pipe.winsys; + size_t size = (size_t)vertex_size * (size_t)nr_vertices; + + assert(!nv10_render->buffer); + nv10_render->buffer = winsys->buffer_create(winsys, 64, PIPE_BUFFER_USAGE_VERTEX, size); + + nv10->dirty |= NV10_NEW_VTXARRAYS; + + return winsys->buffer_map(winsys, + nv10_render->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE); +} + + +static void +nv10_vbuf_render_set_primitive( struct vbuf_render *render, + unsigned prim ) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + nv10_render->hwprim = prim + 1; +} + + +static void +nv10_vbuf_render_draw( struct vbuf_render *render, + const ushort *indices, + uint nr_indices) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + struct nv10_context *nv10 = nv10_render->nv10; + int push, i; + + nv10_emit_hw_state(nv10); + + BEGIN_RING(celsius, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1); + OUT_RELOCl(nv10_render->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + + BEGIN_RING(celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); + OUT_RING(nv10_render->hwprim); + + if (nr_indices & 1) { + BEGIN_RING(celsius, NV10TCL_VB_ELEMENT_U32, 1); + OUT_RING (indices[0]); + indices++; nr_indices--; + } + + while (nr_indices) { + // XXX too big/small ? check the size + push = MIN2(nr_indices, 1200 * 2); + + BEGIN_RING_NI(celsius, NV10TCL_VB_ELEMENT_U16, push >> 1); + for (i = 0; i < push; i+=2) + OUT_RING((indices[i+1] << 16) | indices[i]); + + nr_indices -= push; + indices += push; + } + + BEGIN_RING(celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); + OUT_RING (0); +} + + +static void +nv10_vbuf_render_release_vertices( struct vbuf_render *render, + void *vertices, + unsigned vertex_size, + unsigned vertices_used ) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + struct nv10_context *nv10 = nv10_render->nv10; + struct pipe_winsys *winsys = nv10->pipe.winsys; + + assert(nv10_render->buffer); + winsys->buffer_unmap(winsys, nv10_render->buffer); + pipe_buffer_reference(winsys, &nv10_render->buffer, NULL); +} + + +static void +nv10_vbuf_render_destroy( struct vbuf_render *render ) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + FREE(nv10_render); +} + + +/** + * Create a new primitive render. + */ +static struct vbuf_render * +nv10_vbuf_render_create( struct nv10_context *nv10 ) +{ + struct nv10_vbuf_render *nv10_render = CALLOC_STRUCT(nv10_vbuf_render); + + nv10_render->nv10 = nv10; + + nv10_render->base.max_vertex_buffer_bytes = 16*1024; + nv10_render->base.max_indices = 1024; + nv10_render->base.get_vertex_info = nv10_vbuf_render_get_vertex_info; + nv10_render->base.allocate_vertices = nv10_vbuf_render_allocate_vertices; + nv10_render->base.set_primitive = nv10_vbuf_render_set_primitive; + nv10_render->base.draw = nv10_vbuf_render_draw; + nv10_render->base.release_vertices = nv10_vbuf_render_release_vertices; + nv10_render->base.destroy = nv10_vbuf_render_destroy; + + return &nv10_render->base; +} + + +/** + * Create a new primitive vbuf/render stage. + */ +struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 ) +{ + struct vbuf_render *render; + struct draw_stage *stage; + + render = nv10_vbuf_render_create(nv10); + if(!render) + return NULL; + + stage = draw_vbuf_stage( nv10->draw, render ); + if(!stage) { + render->destroy(render); + return NULL; + } + + return stage; +} diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c new file mode 100644 index 00000000000..67787d8e9ce --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -0,0 +1,212 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv10_context.h" +#include "nv10_screen.h" + +static const char * +nv10_screen_get_name(struct pipe_screen *screen) +{ + struct nv10_screen *nv10screen = nv10_screen(screen); + struct nouveau_device *dev = nv10screen->nvws->channel->device; + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); + return buffer; +} + +static const char * +nv10_screen_get_vendor(struct pipe_screen *screen) +{ + return "nouveau"; +} + +static int +nv10_screen_get_param(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 2; + case PIPE_CAP_NPOT_TEXTURES: + return 0; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 0; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 1; + case PIPE_CAP_POINT_SPRITE: + return 0; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 0; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 0; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 12; + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 0; + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 12; + case NOUVEAU_CAP_HW_VTXBUF: + case NOUVEAU_CAP_HW_IDXBUF: + return 0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv10_screen_get_paramf(struct pipe_screen *screen, int 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 2.0; + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 4.0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0.0; + } +} + +static boolean +nv10_screen_is_format_supported(struct pipe_screen *screen, + enum pipe_format format, uint type) +{ + switch (type) { + case PIPE_SURFACE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + return TRUE; + default: + break; + } + break; + case PIPE_TEXTURE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A4R4G4B4_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static void * +nv10_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, + unsigned flags ) +{ + struct pipe_winsys *ws = screen->winsys; + void *map; + + map = ws->buffer_map(ws, surface->buffer, flags); + if (!map) + return NULL; + + return map + surface->offset; +} + +static void +nv10_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) +{ + struct pipe_winsys *ws = screen->winsys; + + ws->buffer_unmap(ws, surface->buffer); +} + +static void +nv10_screen_destroy(struct pipe_screen *pscreen) +{ + struct nv10_screen *screen = nv10_screen(pscreen); + struct nouveau_winsys *nvws = screen->nvws; + + nvws->notifier_free(&screen->sync); + nvws->grobj_free(&screen->celsius); + + FREE(pscreen); +} + +struct pipe_screen * +nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) +{ + struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen); + unsigned celsius_class; + unsigned chipset = nvws->channel->device->chipset; + int ret; + + if (!screen) + return NULL; + screen->nvws = nvws; + + /* 3D object */ + if (chipset>=0x20) + celsius_class=NV11TCL; + else if (chipset>=0x17) + celsius_class=NV17TCL; + else if (chipset>=0x11) + celsius_class=NV11TCL; + else + celsius_class=NV10TCL; + + if (!celsius_class) { + NOUVEAU_ERR("Unknown nv1x chipset: nv%02x\n", chipset); + return NULL; + } + + ret = nvws->grobj_alloc(nvws, celsius_class, &screen->celsius); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return FALSE; + } + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &screen->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv10_screen_destroy(&screen->pipe); + return NULL; + } + + screen->pipe.winsys = ws; + screen->pipe.destroy = nv10_screen_destroy; + + screen->pipe.get_name = nv10_screen_get_name; + screen->pipe.get_vendor = nv10_screen_get_vendor; + screen->pipe.get_param = nv10_screen_get_param; + screen->pipe.get_paramf = nv10_screen_get_paramf; + + screen->pipe.is_format_supported = nv10_screen_is_format_supported; + + screen->pipe.surface_map = nv10_surface_map; + screen->pipe.surface_unmap = nv10_surface_unmap; + + nv10_screen_init_miptree_functions(&screen->pipe); + + return &screen->pipe; +} + diff --git a/src/gallium/drivers/nv10/nv10_screen.h b/src/gallium/drivers/nv10/nv10_screen.h new file mode 100644 index 00000000000..3f8750a13f7 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_screen.h @@ -0,0 +1,22 @@ +#ifndef __NV10_SCREEN_H__ +#define __NV10_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv10_screen { + struct pipe_screen pipe; + + struct nouveau_winsys *nvws; + + /* HW graphics objects */ + struct nouveau_grobj *celsius; + struct nouveau_notifier *sync; +}; + +static INLINE struct nv10_screen * +nv10_screen(struct pipe_screen *screen) +{ + return (struct nv10_screen *)screen; +} + +#endif diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c new file mode 100644 index 00000000000..11664fae2af --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -0,0 +1,587 @@ +#include "draw/draw_context.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + + +#include "nv10_context.h" +#include "nv10_state.h" + +static void * +nv10_blend_state_create(struct pipe_context *pipe, + const struct pipe_blend_state *cso) +{ + struct nv10_blend_state *cb; + + cb = malloc(sizeof(struct nv10_blend_state)); + + cb->b_enable = cso->blend_enable ? 1 : 0; + cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | + (nvgl_blend_func(cso->rgb_src_factor))); + cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) | + (nvgl_blend_func(cso->rgb_dst_factor))); + + cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) | + ((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) | + ((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) | + ((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0)); + + cb->d_enable = cso->dither ? 1 : 0; + + return (void *)cb; +} + +static void +nv10_blend_state_bind(struct pipe_context *pipe, void *blend) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->blend = (struct nv10_blend_state*)blend; + + nv10->dirty |= NV10_NEW_BLEND; +} + +static void +nv10_blend_state_delete(struct pipe_context *pipe, void *hwcso) +{ + FREE(hwcso); +} + + +static INLINE unsigned +wrap_mode(unsigned wrap) { + unsigned ret; + + switch (wrap) { + case PIPE_TEX_WRAP_REPEAT: + ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT; + break; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + ret = NV10TCL_TX_FORMAT_WRAP_S_MIRRORED_REPEAT; + break; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE; + break; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_BORDER; + break; + case PIPE_TEX_WRAP_CLAMP: + ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + case PIPE_TEX_WRAP_MIRROR_CLAMP: + default: + NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); + ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT; + break; + } + + return ret >> NV10TCL_TX_FORMAT_WRAP_S_SHIFT; +} + +static void * +nv10_sampler_state_create(struct pipe_context *pipe, + const struct pipe_sampler_state *cso) +{ + struct nv10_sampler_state *ps; + uint32_t filter = 0; + + ps = malloc(sizeof(struct nv10_sampler_state)); + + ps->wrap = ((wrap_mode(cso->wrap_s) << NV10TCL_TX_FORMAT_WRAP_S_SHIFT) | + (wrap_mode(cso->wrap_t) << NV10TCL_TX_FORMAT_WRAP_T_SHIFT)); + + ps->en = 0; + if (cso->max_anisotropy > 1.0) { + /* no idea, binary driver sets it, works without it.. meh.. */ + ps->wrap |= (1 << 5); + +/* if (cso->max_anisotropy >= 16.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_16X; + } else + if (cso->max_anisotropy >= 12.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_12X; + } else + if (cso->max_anisotropy >= 10.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_10X; + } else + if (cso->max_anisotropy >= 8.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_8X; + } else + if (cso->max_anisotropy >= 6.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_6X; + } else + if (cso->max_anisotropy >= 4.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_4X; + } else { + ps->en |= NV10TCL_TX_ENABLE_ANISO_2X; + }*/ + } + + switch (cso->mag_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + filter |= NV10TCL_TX_FILTER_MAGNIFY_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + filter |= NV10TCL_TX_FILTER_MAGNIFY_NEAREST; + break; + } + + switch (cso->min_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR; + break; + } + break; + case PIPE_TEX_FILTER_NEAREST: + default: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST; + break; + } + break; + } + + ps->filt = filter; + +/* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + switch (cso->compare_func) { + case PIPE_FUNC_NEVER: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER; + break; + case PIPE_FUNC_GREATER: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER; + break; + case PIPE_FUNC_EQUAL: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL; + break; + case PIPE_FUNC_GEQUAL: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL; + break; + case PIPE_FUNC_LESS: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS; + break; + case PIPE_FUNC_NOTEQUAL: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL; + break; + case PIPE_FUNC_LEQUAL: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL; + break; + case PIPE_FUNC_ALWAYS: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS; + break; + default: + break; + } + }*/ + + ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) | + (float_to_ubyte(cso->border_color[0]) << 16) | + (float_to_ubyte(cso->border_color[1]) << 8) | + (float_to_ubyte(cso->border_color[2]) << 0)); + + return (void *)ps; +} + +static void +nv10_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) +{ + struct nv10_context *nv10 = nv10_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nv10->tex_sampler[unit] = sampler[unit]; + nv10->dirty_samplers |= (1 << unit); + } +} + +static void +nv10_sampler_state_delete(struct pipe_context *pipe, void *hwcso) +{ + FREE(hwcso); +} + +static void +nv10_set_sampler_texture(struct pipe_context *pipe, unsigned nr, + struct pipe_texture **miptree) +{ + struct nv10_context *nv10 = nv10_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nv10->tex_miptree[unit] = (struct nv10_miptree *)miptree[unit]; + nv10->dirty_samplers |= (1 << unit); + } +} + +static void * +nv10_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + struct nv10_rasterizer_state *rs; + int i; + + /*XXX: ignored: + * light_twoside + * offset_cw/ccw -nohw + * scissor + * point_smooth -nohw + * multisample + * offset_units / offset_scale + */ + rs = malloc(sizeof(struct nv10_rasterizer_state)); + + rs->templ = cso; + + rs->shade_model = cso->flatshade ? 0x1d00 : 0x1d01; + + rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff; + rs->line_smooth_en = cso->line_smooth ? 1 : 0; + + rs->point_size = *(uint32_t*)&cso->point_size; + + rs->poly_smooth_en = cso->poly_smooth ? 1 : 0; + + if (cso->front_winding == PIPE_WINDING_CCW) { + rs->front_face = NV10TCL_FRONT_FACE_CCW; + rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw); + rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw); + } else { + rs->front_face = NV10TCL_FRONT_FACE_CW; + rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw); + rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw); + } + + switch (cso->cull_mode) { + case PIPE_WINDING_CCW: + rs->cull_face_en = 1; + if (cso->front_winding == PIPE_WINDING_CCW) + rs->cull_face = NV10TCL_CULL_FACE_FRONT; + else + rs->cull_face = NV10TCL_CULL_FACE_BACK; + break; + case PIPE_WINDING_CW: + rs->cull_face_en = 1; + if (cso->front_winding == PIPE_WINDING_CW) + rs->cull_face = NV10TCL_CULL_FACE_FRONT; + else + rs->cull_face = NV10TCL_CULL_FACE_BACK; + break; + case PIPE_WINDING_BOTH: + rs->cull_face_en = 1; + rs->cull_face = NV10TCL_CULL_FACE_FRONT_AND_BACK; + break; + case PIPE_WINDING_NONE: + default: + rs->cull_face_en = 0; + rs->cull_face = 0; + break; + } + + if (cso->point_sprite) { + rs->point_sprite = (1 << 0); + for (i = 0; i < 8; i++) { + if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE) + rs->point_sprite |= (1 << (8 + i)); + } + } else { + rs->point_sprite = 0; + } + + return (void *)rs; +} + +static void +nv10_rasterizer_state_bind(struct pipe_context *pipe, void *rast) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->rast = (struct nv10_rasterizer_state*)rast; + + draw_set_rasterizer_state(nv10->draw, (nv10->rast ? nv10->rast->templ : NULL)); + + nv10->dirty |= NV10_NEW_RAST; +} + +static void +nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +{ + FREE(hwcso); +} + +static void * +nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) +{ + struct nv10_depth_stencil_alpha_state *hw; + + hw = malloc(sizeof(struct nv10_depth_stencil_alpha_state)); + + hw->depth.func = nvgl_comparison_op(cso->depth.func); + hw->depth.write_enable = cso->depth.writemask ? 1 : 0; + hw->depth.test_enable = cso->depth.enabled ? 1 : 0; + + hw->stencil.enable = cso->stencil[0].enabled ? 1 : 0; + hw->stencil.wmask = cso->stencil[0].write_mask; + hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func); + hw->stencil.ref = cso->stencil[0].ref_value; + hw->stencil.vmask = cso->stencil[0].value_mask; + hw->stencil.fail = nvgl_stencil_op(cso->stencil[0].fail_op); + hw->stencil.zfail = nvgl_stencil_op(cso->stencil[0].zfail_op); + hw->stencil.zpass = nvgl_stencil_op(cso->stencil[0].zpass_op); + + hw->alpha.enabled = cso->alpha.enabled ? 1 : 0; + hw->alpha.func = nvgl_comparison_op(cso->alpha.func); + hw->alpha.ref = float_to_ubyte(cso->alpha.ref); + + return (void *)hw; +} + +static void +nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->dsa = (struct nv10_depth_stencil_alpha_state*)dsa; + + nv10->dirty |= NV10_NEW_DSA; +} + +static void +nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +{ + FREE(hwcso); +} + +static void * +nv10_vp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + return draw_create_vertex_shader(nv10->draw, templ); +} + +static void +nv10_vp_state_bind(struct pipe_context *pipe, void *shader) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + draw_bind_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader); + + nv10->dirty |= NV10_NEW_VERTPROG; +} + +static void +nv10_vp_state_delete(struct pipe_context *pipe, void *shader) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + draw_delete_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader); +} + +static void * +nv10_fp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv10_fragment_program *fp; + + fp = CALLOC(1, sizeof(struct nv10_fragment_program)); + fp->pipe = cso; + + tgsi_scan_shader(cso->tokens, &fp->info); + + return (void *)fp; +} + +static void +nv10_fp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_fragment_program *fp = hwcso; + + nv10->fragprog.current = fp; + nv10->dirty |= NV10_NEW_FRAGPROG; +} + +static void +nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_fragment_program *fp = hwcso; + + nv10_fragprog_destroy(nv10, fp); + FREE(fp); +} + +static void +nv10_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *bcol) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->blend_color = (struct pipe_blend_color*)bcol; + + nv10->dirty |= NV10_NEW_BLENDCOL; +} + +static void +nv10_set_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *clip) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + draw_set_clip_state(nv10->draw, clip); +} + +static void +nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + const struct pipe_constant_buffer *buf ) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + + assert(shader < PIPE_SHADER_TYPES); + assert(index == 0); + + if (buf) { + void *mapped; + if (buf->size && (mapped = ws->buffer_map(ws, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ))) + { + memcpy(nv10->constbuf[shader], mapped, buf->size); + nv10->constbuf_nr[shader] = + buf->size / (4 * sizeof(float)); + ws->buffer_unmap(ws, buf->buffer); + } + } +} + +static void +nv10_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->framebuffer = (struct pipe_framebuffer_state*)fb; + + nv10->dirty |= NV10_NEW_FRAMEBUFFER; +} + +static void +nv10_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + NOUVEAU_ERR("line stipple hahaha\n"); +} + +static void +nv10_set_scissor_state(struct pipe_context *pipe, + const struct pipe_scissor_state *s) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->scissor = (struct pipe_scissor_state*)s; + + nv10->dirty |= NV10_NEW_SCISSOR; +} + +static void +nv10_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *vpt) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->viewport = (struct pipe_viewport_state*)vpt; + + draw_set_viewport_state(nv10->draw, nv10->viewport); + + nv10->dirty |= NV10_NEW_VIEWPORT; +} + +static void +nv10_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *vb) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + memcpy(nv10->vtxbuf, vb, sizeof(*vb) * count); + nv10->dirty |= NV10_NEW_VTXARRAYS; + + draw_set_vertex_buffers(nv10->draw, count, vb); +} + +static void +nv10_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *ve) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + memcpy(nv10->vtxelt, ve, sizeof(*ve) * count); + nv10->dirty |= NV10_NEW_VTXARRAYS; + + draw_set_vertex_elements(nv10->draw, count, ve); +} + +void +nv10_init_state_functions(struct nv10_context *nv10) +{ + nv10->pipe.create_blend_state = nv10_blend_state_create; + nv10->pipe.bind_blend_state = nv10_blend_state_bind; + nv10->pipe.delete_blend_state = nv10_blend_state_delete; + + nv10->pipe.create_sampler_state = nv10_sampler_state_create; + nv10->pipe.bind_sampler_states = nv10_sampler_state_bind; + nv10->pipe.delete_sampler_state = nv10_sampler_state_delete; + nv10->pipe.set_sampler_textures = nv10_set_sampler_texture; + + nv10->pipe.create_rasterizer_state = nv10_rasterizer_state_create; + nv10->pipe.bind_rasterizer_state = nv10_rasterizer_state_bind; + nv10->pipe.delete_rasterizer_state = nv10_rasterizer_state_delete; + + nv10->pipe.create_depth_stencil_alpha_state = + nv10_depth_stencil_alpha_state_create; + nv10->pipe.bind_depth_stencil_alpha_state = + nv10_depth_stencil_alpha_state_bind; + nv10->pipe.delete_depth_stencil_alpha_state = + nv10_depth_stencil_alpha_state_delete; + + nv10->pipe.create_vs_state = nv10_vp_state_create; + nv10->pipe.bind_vs_state = nv10_vp_state_bind; + nv10->pipe.delete_vs_state = nv10_vp_state_delete; + + nv10->pipe.create_fs_state = nv10_fp_state_create; + nv10->pipe.bind_fs_state = nv10_fp_state_bind; + nv10->pipe.delete_fs_state = nv10_fp_state_delete; + + nv10->pipe.set_blend_color = nv10_set_blend_color; + nv10->pipe.set_clip_state = nv10_set_clip_state; + nv10->pipe.set_constant_buffer = nv10_set_constant_buffer; + nv10->pipe.set_framebuffer_state = nv10_set_framebuffer_state; + nv10->pipe.set_polygon_stipple = nv10_set_polygon_stipple; + nv10->pipe.set_scissor_state = nv10_set_scissor_state; + nv10->pipe.set_viewport_state = nv10_set_viewport_state; + + nv10->pipe.set_vertex_buffers = nv10_set_vertex_buffers; + nv10->pipe.set_vertex_elements = nv10_set_vertex_elements; +} + diff --git a/src/gallium/drivers/nv10/nv10_state.h b/src/gallium/drivers/nv10/nv10_state.h new file mode 100644 index 00000000000..3ca501d1356 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_state.h @@ -0,0 +1,139 @@ +#ifndef __NV10_STATE_H__ +#define __NV10_STATE_H__ + +#include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" + +struct nv10_blend_state { + uint32_t b_enable; + uint32_t b_srcfunc; + uint32_t b_dstfunc; + + uint32_t c_mask; + + uint32_t d_enable; +}; + +struct nv10_sampler_state { + uint32_t wrap; + uint32_t en; + uint32_t filt; + uint32_t bcol; +}; + +struct nv10_rasterizer_state { + uint32_t shade_model; + + uint32_t line_width; + uint32_t line_smooth_en; + + uint32_t point_size; + + uint32_t poly_smooth_en; + + uint32_t poly_mode_front; + uint32_t poly_mode_back; + + uint32_t front_face; + uint32_t cull_face; + uint32_t cull_face_en; + + uint32_t point_sprite; + + const struct pipe_rasterizer_state *templ; +}; + +struct nv10_vertex_program_exec { + uint32_t data[4]; + boolean has_branch_offset; + int const_index; +}; + +struct nv10_vertex_program_data { + int index; /* immediates == -1 */ + float value[4]; +}; + +struct nv10_vertex_program { + const struct pipe_shader_state *pipe; + + boolean translated; + struct nv10_vertex_program_exec *insns; + unsigned nr_insns; + struct nv10_vertex_program_data *consts; + unsigned nr_consts; + + struct nouveau_resource *exec; + unsigned exec_start; + struct nouveau_resource *data; + unsigned data_start; + unsigned data_start_min; + + uint32_t ir; + uint32_t or; +}; + +struct nv10_fragment_program_data { + unsigned offset; + unsigned index; +}; + +struct nv10_fragment_program { + const struct pipe_shader_state *pipe; + struct tgsi_shader_info info; + + boolean translated; + boolean on_hw; + unsigned samplers; + + uint32_t *insn; + int insn_len; + + struct nv10_fragment_program_data *consts; + unsigned nr_consts; + + struct pipe_buffer *buffer; + + uint32_t fp_control; + uint32_t fp_reg_control; +}; + + +struct nv10_depth_stencil_alpha_state { + struct { + uint32_t func; + uint32_t write_enable; + uint32_t test_enable; + } depth; + + struct { + uint32_t enable; + uint32_t wmask; + uint32_t func; + uint32_t ref; + uint32_t vmask; + uint32_t fail; + uint32_t zfail; + uint32_t zpass; + } stencil; + + struct { + uint32_t enabled; + uint32_t func; + uint32_t ref; + } alpha; +}; + +struct nv10_miptree { + struct pipe_texture base; + + struct pipe_buffer *buffer; + uint total_size; + + struct { + uint pitch; + uint *image_offset; + } level[PIPE_MAX_TEXTURE_LEVELS]; +}; + +#endif diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c new file mode 100644 index 00000000000..41422c88825 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -0,0 +1,305 @@ +#include "pipe/p_util.h" + +#include "nv10_context.h" +#include "nv10_state.h" + +static void nv10_state_emit_blend(struct nv10_context* nv10) +{ + struct nv10_blend_state *b = nv10->blend; + + BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 1); + OUT_RING (b->d_enable); + + BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 3); + OUT_RING (b->b_enable); + OUT_RING (b->b_srcfunc); + OUT_RING (b->b_dstfunc); + + BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING (b->c_mask); +} + +static void nv10_state_emit_blend_color(struct nv10_context* nv10) +{ + struct pipe_blend_color *c = nv10->blend_color; + + BEGIN_RING(celsius, NV10TCL_BLEND_COLOR, 1); + OUT_RING ((float_to_ubyte(c->color[3]) << 24)| + (float_to_ubyte(c->color[0]) << 16)| + (float_to_ubyte(c->color[1]) << 8) | + (float_to_ubyte(c->color[2]) << 0)); +} + +static void nv10_state_emit_rast(struct nv10_context* nv10) +{ + struct nv10_rasterizer_state *r = nv10->rast; + + BEGIN_RING(celsius, NV10TCL_SHADE_MODEL, 2); + OUT_RING (r->shade_model); + OUT_RING (r->line_width); + + + BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING (r->point_size); + + BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING (r->poly_mode_front); + OUT_RING (r->poly_mode_back); + + + BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); + OUT_RING (r->cull_face); + OUT_RING (r->front_face); + + BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2); + OUT_RING (r->line_smooth_en); + OUT_RING (r->poly_smooth_en); + + BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING (r->cull_face_en); +} + +static void nv10_state_emit_dsa(struct nv10_context* nv10) +{ + struct nv10_depth_stencil_alpha_state *d = nv10->dsa; + + BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 1); + OUT_RING (d->depth.func); + + BEGIN_RING(celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + OUT_RING (d->depth.write_enable); + + BEGIN_RING(celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + OUT_RING (d->depth.test_enable); + +#if 0 + BEGIN_RING(celsius, NV10TCL_STENCIL_ENABLE, 1); + OUT_RING (d->stencil.enable); + BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 7); + OUT_RINGp ((uint32_t *)&(d->stencil.wmask), 7); +#endif + + BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING (d->alpha.enabled); + + BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_FUNC, 1); + OUT_RING (d->alpha.func); + + BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_REF, 1); + OUT_RING (d->alpha.ref); +} + +static void nv10_state_emit_viewport(struct nv10_context* nv10) +{ +} + +static void nv10_state_emit_scissor(struct nv10_context* nv10) +{ + // XXX this is so not working +/* struct pipe_scissor_state *s = nv10->scissor; + BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2); + OUT_RING (((s->maxx - s->minx) << 16) | s->minx); + OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/ +} + +static void nv10_state_emit_framebuffer(struct nv10_context* nv10) +{ + struct pipe_framebuffer_state* fb = nv10->framebuffer; + struct pipe_surface *rt, *zeta = NULL; + uint32_t rt_format, w, h; + int colour_format = 0, zeta_format = 0; + + w = fb->cbufs[0]->width; + h = fb->cbufs[0]->height; + colour_format = fb->cbufs[0]->format; + rt = fb->cbufs[0]; + + if (fb->zsbuf) { + if (colour_format) { + assert(w == fb->zsbuf->width); + assert(h == fb->zsbuf->height); + } else { + w = fb->zsbuf->width; + h = fb->zsbuf->height; + } + + zeta_format = fb->zsbuf->format; + zeta = fb->zsbuf; + } + + rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR; + + switch (colour_format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case 0: + rt_format |= NV10TCL_RT_FORMAT_COLOR_A8R8G8B8; + break; + case PIPE_FORMAT_R5G6B5_UNORM: + rt_format |= NV10TCL_RT_FORMAT_COLOR_R5G6B5; + break; + default: + assert(0); + } + + if (zeta) { + BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); + OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->cpp) << 16) ); + } else { + BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); + OUT_RING ( (rt->pitch * rt->cpp) | ( (rt->pitch * rt->cpp) << 16) ); + } + + nv10->rt[0] = rt->buffer; + + if (zeta_format) + { + nv10->zeta = zeta->buffer; + } + + BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 3); + OUT_RING ((w << 16) | 0); + OUT_RING ((h << 16) | 0); + OUT_RING (rt_format); + BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2); + OUT_RING (((w - 1) << 16) | 0 | 0x08000800); + OUT_RING (((h - 1) << 16) | 0 | 0x08000800); +} + +static void nv10_vertex_layout(struct nv10_context *nv10) +{ + struct nv10_fragment_program *fp = nv10->fragprog.current; + uint32_t src = 0; + int i; + struct vertex_info vinfo; + + memset(&vinfo, 0, sizeof(vinfo)); + + for (i = 0; i < fp->info.num_inputs; i++) { + switch (fp->info.input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); + break; + case TGSI_SEMANTIC_COLOR: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); + break; + default: + case TGSI_SEMANTIC_GENERIC: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); + break; + case TGSI_SEMANTIC_FOG: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); + break; + } + } + draw_compute_vertex_size(&vinfo); +} + +void +nv10_emit_hw_state(struct nv10_context *nv10) +{ + int i; + + if (nv10->dirty & NV10_NEW_VERTPROG) { + //nv10_vertprog_bind(nv10, nv10->vertprog.current); + nv10->dirty &= ~NV10_NEW_VERTPROG; + } + + if (nv10->dirty & NV10_NEW_FRAGPROG) { + nv10_fragprog_bind(nv10, nv10->fragprog.current); + /*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */ + nv10->dirty_samplers |= (1<<10); + nv10->dirty_samplers = 0; + } + + if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) { + nv10_fragtex_bind(nv10); + nv10->dirty &= ~NV10_NEW_FRAGPROG; + } + + if (nv10->dirty & NV10_NEW_VTXARRAYS) { + nv10->dirty &= ~NV10_NEW_VTXARRAYS; + nv10_vertex_layout(nv10); + nv10_vtxbuf_bind(nv10); + } + + if (nv10->dirty & NV10_NEW_BLEND) { + nv10->dirty &= ~NV10_NEW_BLEND; + nv10_state_emit_blend(nv10); + } + + if (nv10->dirty & NV10_NEW_BLENDCOL) { + nv10->dirty &= ~NV10_NEW_BLENDCOL; + nv10_state_emit_blend_color(nv10); + } + + if (nv10->dirty & NV10_NEW_RAST) { + nv10->dirty &= ~NV10_NEW_RAST; + nv10_state_emit_rast(nv10); + } + + if (nv10->dirty & NV10_NEW_DSA) { + nv10->dirty &= ~NV10_NEW_DSA; + nv10_state_emit_dsa(nv10); + } + + if (nv10->dirty & NV10_NEW_VIEWPORT) { + nv10->dirty &= ~NV10_NEW_VIEWPORT; + nv10_state_emit_viewport(nv10); + } + + if (nv10->dirty & NV10_NEW_SCISSOR) { + nv10->dirty &= ~NV10_NEW_SCISSOR; + nv10_state_emit_scissor(nv10); + } + + if (nv10->dirty & NV10_NEW_FRAMEBUFFER) { + nv10->dirty &= ~NV10_NEW_FRAMEBUFFER; + nv10_state_emit_framebuffer(nv10); + } + + /* Emit relocs for every referenced buffer. + * This is to ensure the bufmgr has an accurate idea of how + * the buffer is used. This isn't very efficient, but we don't + * seem to take a significant performance hit. Will be improved + * at some point. Vertex arrays are emitted by nv10_vbo.c + */ + + /* Render target */ +// XXX figre out who's who for NV10TCL_DMA_* and fill accordingly +// BEGIN_RING(celsius, NV10TCL_DMA_COLOR0, 1); +// OUT_RELOCo(nv10->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(celsius, NV10TCL_COLOR_OFFSET, 1); + OUT_RELOCl(nv10->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + if (nv10->zeta) { +// XXX +// BEGIN_RING(celsius, NV10TCL_DMA_ZETA, 1); +// OUT_RELOCo(nv10->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(celsius, NV10TCL_ZETA_OFFSET, 1); + OUT_RELOCl(nv10->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + /* XXX for when we allocate LMA on nv17 */ +/* BEGIN_RING(celsius, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1); + OUT_RELOCl(nv10->zeta + lma_offset);*/ + } + + /* Vertex buffer */ + BEGIN_RING(celsius, NV10TCL_DMA_VTXBUF0, 1); + OUT_RELOCo(nv10->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(celsius, NV10TCL_COLOR_OFFSET, 1); + OUT_RELOCl(nv10->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + /* Texture images */ + for (i = 0; i < 2; i++) { + if (!(nv10->fp_samplers & (1 << i))) + continue; + BEGIN_RING(celsius, NV10TCL_TX_OFFSET(i), 1); + OUT_RELOCl(nv10->tex[i].buffer, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + BEGIN_RING(celsius, NV10TCL_TX_FORMAT(i), 1); + OUT_RELOCd(nv10->tex[i].buffer, nv10->tex[i].format, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | + NOUVEAU_BO_OR, NV10TCL_TX_FORMAT_DMA0, + NV10TCL_TX_FORMAT_DMA1); + } +} + diff --git a/src/gallium/drivers/nv10/nv10_surface.c b/src/gallium/drivers/nv10/nv10_surface.c new file mode 100644 index 00000000000..2e230ebbecc --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_surface.c @@ -0,0 +1,65 @@ + +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#include "nv10_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_inlines.h" +#include "util/p_tile.h" + +static void +nv10_surface_copy(struct pipe_context *pipe, unsigned do_flip, + struct pipe_surface *dest, unsigned destx, unsigned desty, + struct pipe_surface *src, unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nouveau_winsys *nvws = nv10->nvws; + + nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, + width, height); +} + +static void +nv10_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, + unsigned destx, unsigned desty, unsigned width, + unsigned height, unsigned value) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nouveau_winsys *nvws = nv10->nvws; + + nvws->surface_fill(nvws, dest, destx, desty, width, height, value); +} + +void +nv10_init_surface_functions(struct nv10_context *nv10) +{ + nv10->pipe.surface_copy = nv10_surface_copy; + nv10->pipe.surface_fill = nv10_surface_fill; +} diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c new file mode 100644 index 00000000000..f024f534209 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_vbo.c @@ -0,0 +1,78 @@ +#include "draw/draw_context.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "nv10_context.h" +#include "nv10_state.h" + +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_pushbuf.h" + +boolean nv10_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned prim, unsigned start, unsigned count) +{ + struct nv10_context *nv10 = nv10_context( pipe ); + struct draw_context *draw = nv10->draw; + unsigned i; + + nv10_emit_hw_state(nv10); + + /* + * Map vertex buffers + */ + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { + if (nv10->vtxbuf[i].buffer) { + void *buf + = pipe->winsys->buffer_map(pipe->winsys, + nv10->vtxbuf[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); + } + } + /* Map index buffer, if present */ + if (indexBuffer) { + void *mapped_indexes + = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); + } + else { + /* no index/element buffer */ + draw_set_mapped_element_buffer(draw, 0, NULL); + } + + draw_set_mapped_constant_buffer(draw, + nv10->constbuf[PIPE_SHADER_VERTEX], + nv10->constbuf_nr[PIPE_SHADER_VERTEX]); + + /* draw! */ + draw_arrays(nv10->draw, prim, start, count); + + /* + * unmap vertex/index buffers + */ + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { + if (nv10->vtxbuf[i].buffer) { + pipe->winsys->buffer_unmap(pipe->winsys, nv10->vtxbuf[i].buffer); + draw_set_mapped_vertex_buffer(draw, i, NULL); + } + } + if (indexBuffer) { + pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); + draw_set_mapped_element_buffer(draw, 0, NULL); + } + + return TRUE; +} + +boolean nv10_draw_arrays( struct pipe_context *pipe, + unsigned prim, unsigned start, unsigned count) +{ + return nv10_draw_elements(pipe, NULL, 0, prim, start, count); +} + + + diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile new file mode 100644 index 00000000000..69f2790dfe2 --- /dev/null +++ b/src/gallium/drivers/nv30/Makefile @@ -0,0 +1,37 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = nv30 + +DRIVER_SOURCES = \ + nv30_clear.c \ + nv30_context.c \ + nv30_draw.c \ + nv30_fragprog.c \ + nv30_fragtex.c \ + nv30_miptree.c \ + nv30_query.c \ + nv30_screen.c \ + nv30_state.c \ + nv30_state_blend.c \ + nv30_state_emit.c \ + nv30_state_fb.c \ + nv30_state_rasterizer.c \ + nv30_state_scissor.c \ + nv30_state_stipple.c \ + nv30_state_viewport.c \ + nv30_state_zsa.c \ + nv30_surface.c \ + nv30_vbo.c \ + nv30_vertprog.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/nv30/nv30_clear.c b/src/gallium/drivers/nv30/nv30_clear.c new file mode 100644 index 00000000000..8c3ca204d58 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_clear.c @@ -0,0 +1,13 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "nv30_context.h" + +void +nv30_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + ps->status = PIPE_SURFACE_STATUS_CLEAR; +} diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c new file mode 100644 index 00000000000..b2d9d3f1814 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -0,0 +1,80 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv30_context.h" +#include "nv30_screen.h" + +static void +nv30_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(rankine, 0x1fd8, 1); + OUT_RING (2); + BEGIN_RING(rankine, 0x1fd8, 1); + OUT_RING (1); + } + + FIRE_RING(fence); +} + +static void +nv30_destroy(struct pipe_context *pipe) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + if (nv30->draw) + draw_destroy(nv30->draw); + FREE(nv30); +} + + +static void +nv30_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +{ +} + +struct pipe_context * +nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) +{ + struct nv30_screen *screen = nv30_screen(pscreen); + struct pipe_winsys *ws = pscreen->winsys; + struct nv30_context *nv30; + struct nouveau_winsys *nvws = screen->nvws; + + nv30 = CALLOC(1, sizeof(struct nv30_context)); + if (!nv30) + return NULL; + nv30->screen = screen; + nv30->pctx_id = pctx_id; + + nv30->nvws = nvws; + + nv30->pipe.winsys = ws; + nv30->pipe.screen = pscreen; + nv30->pipe.destroy = nv30_destroy; + nv30->pipe.set_edgeflags = nv30_set_edgeflags; + nv30->pipe.draw_arrays = nv30_draw_arrays; + nv30->pipe.draw_elements = nv30_draw_elements; + nv30->pipe.clear = nv30_clear; + nv30->pipe.flush = nv30_flush; + + nv30_init_query_functions(nv30); + nv30_init_surface_functions(nv30); + nv30_init_state_functions(nv30); + + /* Create, configure, and install fallback swtnl path */ + nv30->draw = draw_create(); + draw_wide_point_threshold(nv30->draw, 9999999.0); + draw_wide_line_threshold(nv30->draw, 9999999.0); + draw_enable_line_stipple(nv30->draw, FALSE); + draw_enable_point_sprites(nv30->draw, FALSE); + draw_set_rasterize_stage(nv30->draw, nv30_draw_render_stage(nv30)); + + return &nv30->pipe; +} + diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h new file mode 100644 index 00000000000..dce077b2b4b --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -0,0 +1,227 @@ +#ifndef __NV30_CONTEXT_H__ +#define __NV30_CONTEXT_H__ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "draw/draw_vertex.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_gldefs.h" + +#define NOUVEAU_PUSH_CONTEXT(ctx) \ + struct nv30_screen *ctx = nv30->screen +#include "nouveau/nouveau_push.h" +#include "nouveau/nouveau_stateobj.h" + +#include "nv30_state.h" + +#define NOUVEAU_ERR(fmt, args...) \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); +#define NOUVEAU_MSG(fmt, args...) \ + fprintf(stderr, "nouveau: "fmt, ##args); + +enum nv30_state_index { + NV30_STATE_FB = 0, + NV30_STATE_VIEWPORT = 1, + NV30_STATE_BLEND = 2, + NV30_STATE_RAST = 3, + NV30_STATE_ZSA = 4, + NV30_STATE_BCOL = 5, + NV30_STATE_CLIP = 6, + NV30_STATE_SCISSOR = 7, + NV30_STATE_STIPPLE = 8, + NV30_STATE_FRAGPROG = 9, + NV30_STATE_VERTPROG = 10, + NV30_STATE_FRAGTEX0 = 11, + NV30_STATE_FRAGTEX1 = 12, + NV30_STATE_FRAGTEX2 = 13, + NV30_STATE_FRAGTEX3 = 14, + NV30_STATE_FRAGTEX4 = 15, + NV30_STATE_FRAGTEX5 = 16, + NV30_STATE_FRAGTEX6 = 17, + NV30_STATE_FRAGTEX7 = 18, + NV30_STATE_FRAGTEX8 = 19, + NV30_STATE_FRAGTEX9 = 20, + NV30_STATE_FRAGTEX10 = 21, + NV30_STATE_FRAGTEX11 = 22, + NV30_STATE_FRAGTEX12 = 23, + NV30_STATE_FRAGTEX13 = 24, + NV30_STATE_FRAGTEX14 = 25, + NV30_STATE_FRAGTEX15 = 26, + NV30_STATE_VERTTEX0 = 27, + NV30_STATE_VERTTEX1 = 28, + NV30_STATE_VERTTEX2 = 29, + NV30_STATE_VERTTEX3 = 30, + NV30_STATE_VTXBUF = 31, + NV30_STATE_VTXFMT = 32, + NV30_STATE_VTXATTR = 33, + NV30_STATE_MAX = 34 +}; + +#include "nv30_screen.h" + +#define NV30_NEW_BLEND (1 << 0) +#define NV30_NEW_RAST (1 << 1) +#define NV30_NEW_ZSA (1 << 2) +#define NV30_NEW_SAMPLER (1 << 3) +#define NV30_NEW_FB (1 << 4) +#define NV30_NEW_STIPPLE (1 << 5) +#define NV30_NEW_SCISSOR (1 << 6) +#define NV30_NEW_VIEWPORT (1 << 7) +#define NV30_NEW_BCOL (1 << 8) +#define NV30_NEW_VERTPROG (1 << 9) +#define NV30_NEW_FRAGPROG (1 << 10) +#define NV30_NEW_ARRAYS (1 << 11) +#define NV30_NEW_UCP (1 << 12) + +/* TODO: rename when removing the old state emitter */ +struct nv30_rasterizer_state_new { + struct pipe_rasterizer_state pipe; + struct nouveau_stateobj *so; +}; + +struct nv30_zsa_state { + struct pipe_depth_stencil_alpha_state pipe; + struct nouveau_stateobj *so; +}; + +/* TODO: rename when removing the old state emitter */ +struct nv30_blend_state_new { + struct pipe_blend_state pipe; + struct nouveau_stateobj *so; +}; + + +struct nv30_state { + unsigned scissor_enabled; + unsigned stipple_enabled; + unsigned viewport_bypass; + + struct nouveau_stateobj *hw[NV30_STATE_MAX]; +}; + +struct nv30_context { + struct pipe_context pipe; + + struct nouveau_winsys *nvws; + struct nv30_screen *screen; + unsigned pctx_id; + + struct draw_context *draw; + + /* HW state derived from pipe states */ + struct nv30_state state; + struct pipe_scissor_state scissor; + + uint32_t dirty; + + struct nv30_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; + struct nv30_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; + unsigned dirty_samplers; + unsigned fp_samplers; + unsigned vp_samplers; + + /* Context state */ + struct nv30_blend_state_new *blend; + struct pipe_blend_color blend_colour; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + struct nv30_rasterizer_state_new *rasterizer; + struct nv30_zsa_state *zsa; + unsigned stipple[32]; + + uint32_t rt_enable; + struct pipe_buffer *rt[2]; + struct pipe_buffer *zeta; + + /*struct { + struct pipe_buffer *buffer; + uint32_t format; + } tex[16];*/ + + unsigned vb_enable; + struct { + struct pipe_buffer *buffer; + unsigned delta; + } vb[16]; + + struct { + struct nv30_vertex_program *active; + + struct nv30_vertex_program *current; + struct pipe_buffer *constant_buf; + } vertprog; + + struct { + struct nv30_fragment_program *active; + + struct nv30_fragment_program *current; + struct pipe_buffer *constant_buf; + } fragprog; + + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; +}; + +static INLINE struct nv30_context * +nv30_context(struct pipe_context *pipe) +{ + return (struct nv30_context *)pipe; +} + +struct nv30_state_entry { + boolean (*validate)(struct nv30_context *nv30); + struct { + unsigned pipe; + unsigned hw; + } dirty; +}; + +extern void nv30_init_state_functions(struct nv30_context *nv30); +extern void nv30_init_surface_functions(struct nv30_context *nv30); +extern void nv30_init_query_functions(struct nv30_context *nv30); + +extern void nv30_screen_init_miptree_functions(struct pipe_screen *pscreen); + +/* nv30_draw.c */ +extern struct draw_stage *nv30_draw_render_stage(struct nv30_context *nv30); + +/* nv30_vertprog.c */ +extern void nv30_vertprog_translate(struct nv30_context *, + struct nv30_vertex_program *); +extern void nv30_vertprog_bind(struct nv30_context *, + struct nv30_vertex_program *); +extern void nv30_vertprog_destroy(struct nv30_context *, + struct nv30_vertex_program *); + +/* nv30_fragprog.c */ +extern void nv30_fragprog_translate(struct nv30_context *, + struct nv30_fragment_program *); +extern void nv30_fragprog_bind(struct nv30_context *, + struct nv30_fragment_program *); +extern void nv30_fragprog_destroy(struct nv30_context *, + struct nv30_fragment_program *); + +/* nv30_fragtex.c */ +extern void nv30_fragtex_bind(struct nv30_context *); + +/* nv30_state.c and friends */ +extern void nv30_emit_hw_state(struct nv30_context *nv30); +extern void nv30_state_tex_update(struct nv30_context *nv30); + +/* nv30_vbo.c */ +extern boolean nv30_draw_arrays(struct pipe_context *, unsigned mode, + unsigned start, unsigned count); +extern boolean nv30_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, + unsigned count); + +/* nv30_clear.c */ +extern void nv30_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + +#endif diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c new file mode 100644 index 00000000000..aeeaf58f20a --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_draw.c @@ -0,0 +1,62 @@ +#include "draw/draw_pipe.h" +#include "pipe/p_util.h" + +#include "nv30_context.h" + +struct nv30_draw_stage { + struct draw_stage draw; + struct nv30_context *nv30; +}; + +static void +nv30_draw_point(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv30_draw_line(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv30_draw_tri(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv30_draw_flush(struct draw_stage *draw, unsigned flags) +{ +} + +static void +nv30_draw_reset_stipple_counter(struct draw_stage *draw) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv30_draw_destroy(struct draw_stage *draw) +{ + FREE(draw); +} + +struct draw_stage * +nv30_draw_render_stage(struct nv30_context *nv30) +{ + struct nv30_draw_stage *nv30draw = CALLOC_STRUCT(nv30_draw_stage); + + nv30draw->nv30 = nv30; + nv30draw->draw.draw = nv30->draw; + nv30draw->draw.point = nv30_draw_point; + nv30draw->draw.line = nv30_draw_line; + nv30draw->draw.tri = nv30_draw_tri; + nv30draw->draw.flush = nv30_draw_flush; + nv30draw->draw.reset_stipple_counter = nv30_draw_reset_stipple_counter; + nv30draw->draw.destroy = nv30_draw_destroy; + + return &nv30draw->draw; +} + diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c new file mode 100644 index 00000000000..54d6bea55f7 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -0,0 +1,834 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" + +#include "nv30_context.h" + +#define SWZ_X 0 +#define SWZ_Y 1 +#define SWZ_Z 2 +#define SWZ_W 3 +#define MASK_X 1 +#define MASK_Y 2 +#define MASK_Z 4 +#define MASK_W 8 +#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W) +#define DEF_SCALE NV30_FP_OP_DST_SCALE_1X +#define DEF_CTEST NV30_FP_OP_COND_TR +#include "nv30_shader.h" + +#define swz(s,x,y,z,w) nv30_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w) +#define neg(s) nv30_sr_neg((s)) +#define abs(s) nv30_sr_abs((s)) +#define scale(s,v) nv30_sr_scale((s), NV30_FP_OP_DST_SCALE_##v) + +#define MAX_CONSTS 128 +#define MAX_IMM 32 +struct nv30_fpc { + struct nv30_fragment_program *fp; + + uint attrib_map[PIPE_MAX_SHADER_INPUTS]; + + int high_temp; + int temp_temp_count; + int num_regs; + + uint depth_id; + uint colour_id; + + unsigned inst_offset; + + struct { + int pipe; + float vals[4]; + } consts[MAX_CONSTS]; + int nr_consts; + + struct nv30_sreg imm[MAX_IMM]; + unsigned nr_imm; +}; + +static INLINE struct nv30_sreg +temp(struct nv30_fpc *fpc) +{ + int idx; + + idx = fpc->temp_temp_count++; + idx += fpc->high_temp + 1; + return nv30_sr(NV30SR_TEMP, idx); +} + +static INLINE struct nv30_sreg +constant(struct nv30_fpc *fpc, int pipe, float vals[4]) +{ + int idx; + + if (fpc->nr_consts == MAX_CONSTS) + assert(0); + idx = fpc->nr_consts++; + + fpc->consts[idx].pipe = pipe; + if (pipe == -1) + memcpy(fpc->consts[idx].vals, vals, 4 * sizeof(float)); + return nv30_sr(NV30SR_CONST, idx); +} + +#define arith(cc,s,o,d,m,s0,s1,s2) \ + nv30_fp_arith((cc), (s), NV30_FP_OP_OPCODE_##o, \ + (d), (m), (s0), (s1), (s2)) +#define tex(cc,s,o,u,d,m,s0,s1,s2) \ + nv30_fp_tex((cc), (s), NV30_FP_OP_OPCODE_##o, (u), \ + (d), (m), (s0), none, none) + +static void +grow_insns(struct nv30_fpc *fpc, int size) +{ + struct nv30_fragment_program *fp = fpc->fp; + + fp->insn_len += size; + fp->insn = realloc(fp->insn, sizeof(uint32_t) * fp->insn_len); +} + +static void +emit_src(struct nv30_fpc *fpc, int pos, struct nv30_sreg src) +{ + struct nv30_fragment_program *fp = fpc->fp; + uint32_t *hw = &fp->insn[fpc->inst_offset]; + uint32_t sr = 0; + + switch (src.type) { + case NV30SR_INPUT: + sr |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT); + hw[0] |= (src.index << NV30_FP_OP_INPUT_SRC_SHIFT); + break; + case NV30SR_OUTPUT: + sr |= NV30_FP_REG_SRC_HALF; + /* fall-through */ + case NV30SR_TEMP: + sr |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT); + sr |= (src.index << NV30_FP_REG_SRC_SHIFT); + break; + case NV30SR_CONST: + grow_insns(fpc, 4); + hw = &fp->insn[fpc->inst_offset]; + if (fpc->consts[src.index].pipe >= 0) { + struct nv30_fragment_program_data *fpd; + + fp->consts = realloc(fp->consts, ++fp->nr_consts * + sizeof(*fpd)); + fpd = &fp->consts[fp->nr_consts - 1]; + fpd->offset = fpc->inst_offset + 4; + fpd->index = fpc->consts[src.index].pipe; + memset(&fp->insn[fpd->offset], 0, sizeof(uint32_t) * 4); + } else { + memcpy(&fp->insn[fpc->inst_offset + 4], + fpc->consts[src.index].vals, + sizeof(uint32_t) * 4); + } + + sr |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT); + break; + case NV30SR_NONE: + sr |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT); + break; + default: + assert(0); + } + + if (src.negate) + sr |= NV30_FP_REG_NEGATE; + + if (src.abs) + hw[1] |= (1 << (29 + pos)); + + sr |= ((src.swz[0] << NV30_FP_REG_SWZ_X_SHIFT) | + (src.swz[1] << NV30_FP_REG_SWZ_Y_SHIFT) | + (src.swz[2] << NV30_FP_REG_SWZ_Z_SHIFT) | + (src.swz[3] << NV30_FP_REG_SWZ_W_SHIFT)); + + hw[pos + 1] |= sr; +} + +static void +emit_dst(struct nv30_fpc *fpc, struct nv30_sreg dst) +{ + struct nv30_fragment_program *fp = fpc->fp; + uint32_t *hw = &fp->insn[fpc->inst_offset]; + + switch (dst.type) { + case NV30SR_TEMP: + if (fpc->num_regs < (dst.index + 1)) + fpc->num_regs = dst.index + 1; + break; + case NV30SR_OUTPUT: + if (dst.index == 1) { + fp->fp_control |= 0xe; + } else { + hw[0] |= NV30_FP_OP_OUT_REG_HALF; + } + break; + case NV30SR_NONE: + hw[0] |= (1 << 30); + break; + default: + assert(0); + } + + hw[0] |= (dst.index << NV30_FP_OP_OUT_REG_SHIFT); +} + +static void +nv30_fp_arith(struct nv30_fpc *fpc, int sat, int op, + struct nv30_sreg dst, int mask, + struct nv30_sreg s0, struct nv30_sreg s1, struct nv30_sreg s2) +{ + struct nv30_fragment_program *fp = fpc->fp; + uint32_t *hw; + + fpc->inst_offset = fp->insn_len; + grow_insns(fpc, 4); + hw = &fp->insn[fpc->inst_offset]; + memset(hw, 0, sizeof(uint32_t) * 4); + + if (op == NV30_FP_OP_OPCODE_KIL) + fp->fp_control |= NV34TCL_FP_CONTROL_USES_KIL; + hw[0] |= (op << NV30_FP_OP_OPCODE_SHIFT); + hw[0] |= (mask << NV30_FP_OP_OUTMASK_SHIFT); + hw[2] |= (dst.dst_scale << NV30_FP_OP_DST_SCALE_SHIFT); + + if (sat) + hw[0] |= NV30_FP_OP_OUT_SAT; + + if (dst.cc_update) + hw[0] |= NV30_FP_OP_COND_WRITE_ENABLE; + hw[1] |= (dst.cc_test << NV30_FP_OP_COND_SHIFT); + hw[1] |= ((dst.cc_swz[0] << NV30_FP_OP_COND_SWZ_X_SHIFT) | + (dst.cc_swz[1] << NV30_FP_OP_COND_SWZ_Y_SHIFT) | + (dst.cc_swz[2] << NV30_FP_OP_COND_SWZ_Z_SHIFT) | + (dst.cc_swz[3] << NV30_FP_OP_COND_SWZ_W_SHIFT)); + + emit_dst(fpc, dst); + emit_src(fpc, 0, s0); + emit_src(fpc, 1, s1); + emit_src(fpc, 2, s2); +} + +static void +nv30_fp_tex(struct nv30_fpc *fpc, int sat, int op, int unit, + struct nv30_sreg dst, int mask, + struct nv30_sreg s0, struct nv30_sreg s1, struct nv30_sreg s2) +{ + struct nv30_fragment_program *fp = fpc->fp; + + nv30_fp_arith(fpc, sat, op, dst, mask, s0, s1, s2); + + fp->insn[fpc->inst_offset] |= (unit << NV30_FP_OP_TEX_UNIT_SHIFT); + fp->samplers |= (1 << unit); +} + +static INLINE struct nv30_sreg +tgsi_src(struct nv30_fpc *fpc, const struct tgsi_full_src_register *fsrc) +{ + struct nv30_sreg src; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + src = nv30_sr(NV30SR_INPUT, + fpc->attrib_map[fsrc->SrcRegister.Index]); + break; + case TGSI_FILE_CONSTANT: + src = constant(fpc, fsrc->SrcRegister.Index, NULL); + break; + case TGSI_FILE_IMMEDIATE: + assert(fsrc->SrcRegister.Index < fpc->nr_imm); + src = fpc->imm[fsrc->SrcRegister.Index]; + break; + case TGSI_FILE_TEMPORARY: + src = nv30_sr(NV30SR_TEMP, fsrc->SrcRegister.Index + 1); + if (fpc->high_temp < src.index) + fpc->high_temp = src.index; + break; + /* This is clearly insane, but gallium hands us shaders like this. + * Luckily fragprog results are just temp regs.. + */ + case TGSI_FILE_OUTPUT: + if (fsrc->SrcRegister.Index == fpc->colour_id) + return nv30_sr(NV30SR_OUTPUT, 0); + else + return nv30_sr(NV30SR_OUTPUT, 1); + break; + default: + NOUVEAU_ERR("bad src file\n"); + break; + } + + src.abs = fsrc->SrcRegisterExtMod.Absolute; + src.negate = fsrc->SrcRegister.Negate; + src.swz[0] = fsrc->SrcRegister.SwizzleX; + src.swz[1] = fsrc->SrcRegister.SwizzleY; + src.swz[2] = fsrc->SrcRegister.SwizzleZ; + src.swz[3] = fsrc->SrcRegister.SwizzleW; + return src; +} + +static INLINE struct nv30_sreg +tgsi_dst(struct nv30_fpc *fpc, const struct tgsi_full_dst_register *fdst) { + int idx; + + switch (fdst->DstRegister.File) { + case TGSI_FILE_OUTPUT: + if (fdst->DstRegister.Index == fpc->colour_id) + return nv30_sr(NV30SR_OUTPUT, 0); + else + return nv30_sr(NV30SR_OUTPUT, 1); + break; + case TGSI_FILE_TEMPORARY: + idx = fdst->DstRegister.Index + 1; + if (fpc->high_temp < idx) + fpc->high_temp = idx; + return nv30_sr(NV30SR_TEMP, idx); + case TGSI_FILE_NULL: + return nv30_sr(NV30SR_NONE, 0); + default: + NOUVEAU_ERR("bad dst file %d\n", fdst->DstRegister.File); + return nv30_sr(NV30SR_NONE, 0); + } +} + +static INLINE int +tgsi_mask(uint tgsi) +{ + int mask = 0; + + if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X; + if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y; + if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z; + if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W; + return mask; +} + +static boolean +src_native_swz(struct nv30_fpc *fpc, const struct tgsi_full_src_register *fsrc, + struct nv30_sreg *src) +{ + const struct nv30_sreg none = nv30_sr(NV30SR_NONE, 0); + struct nv30_sreg tgsi = tgsi_src(fpc, fsrc); + uint mask = 0, zero_mask = 0, one_mask = 0, neg_mask = 0; + uint neg[4] = { fsrc->SrcRegisterExtSwz.NegateX, + fsrc->SrcRegisterExtSwz.NegateY, + fsrc->SrcRegisterExtSwz.NegateZ, + fsrc->SrcRegisterExtSwz.NegateW }; + uint c; + + for (c = 0; c < 4; c++) { + switch (tgsi_util_get_full_src_register_extswizzle(fsrc, c)) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + mask |= (1 << c); + break; + case TGSI_EXTSWIZZLE_ZERO: + zero_mask |= (1 << c); + tgsi.swz[c] = SWZ_X; + break; + case TGSI_EXTSWIZZLE_ONE: + one_mask |= (1 << c); + tgsi.swz[c] = SWZ_X; + break; + default: + assert(0); + } + + if (!tgsi.negate && neg[c]) + neg_mask |= (1 << c); + } + + if (mask == MASK_ALL && !neg_mask) + return TRUE; + + *src = temp(fpc); + + if (mask) + arith(fpc, 0, MOV, *src, mask, tgsi, none, none); + + if (zero_mask) + arith(fpc, 0, SFL, *src, zero_mask, *src, none, none); + + if (one_mask) + arith(fpc, 0, STR, *src, one_mask, *src, none, none); + + if (neg_mask) { + struct nv30_sreg one = temp(fpc); + arith(fpc, 0, STR, one, neg_mask, one, none, none); + arith(fpc, 0, MUL, *src, neg_mask, *src, neg(one), none); + } + + return FALSE; +} + +static boolean +nv30_fragprog_parse_instruction(struct nv30_fpc *fpc, + const struct tgsi_full_instruction *finst) +{ + const struct nv30_sreg none = nv30_sr(NV30SR_NONE, 0); + struct nv30_sreg src[3], dst, tmp; + int mask, sat, unit = 0; + int ai = -1, ci = -1; + int i; + + if (finst->Instruction.Opcode == TGSI_OPCODE_END) + return TRUE; + + fpc->temp_temp_count = 0; + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) { + src[i] = tgsi_src(fpc, fsrc); + } + } + + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + case TGSI_FILE_CONSTANT: + case TGSI_FILE_TEMPORARY: + if (!src_native_swz(fpc, fsrc, &src[i])) + continue; + break; + default: + break; + } + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + if (ai == -1 || ai == fsrc->SrcRegister.Index) { + ai = fsrc->SrcRegister.Index; + src[i] = tgsi_src(fpc, fsrc); + } else { + NOUVEAU_MSG("extra src attr %d\n", + fsrc->SrcRegister.Index); + src[i] = temp(fpc); + arith(fpc, 0, MOV, src[i], MASK_ALL, + tgsi_src(fpc, fsrc), none, none); + } + break; + case TGSI_FILE_CONSTANT: + case TGSI_FILE_IMMEDIATE: + if (ci == -1 || ci == fsrc->SrcRegister.Index) { + ci = fsrc->SrcRegister.Index; + src[i] = tgsi_src(fpc, fsrc); + } else { + src[i] = temp(fpc); + arith(fpc, 0, MOV, src[i], MASK_ALL, + tgsi_src(fpc, fsrc), none, none); + } + break; + case TGSI_FILE_TEMPORARY: + /* handled above */ + break; + case TGSI_FILE_SAMPLER: + unit = fsrc->SrcRegister.Index; + break; + case TGSI_FILE_OUTPUT: + break; + default: + NOUVEAU_ERR("bad src file\n"); + return FALSE; + } + } + + dst = tgsi_dst(fpc, &finst->FullDstRegisters[0]); + mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask); + sat = (finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE); + + switch (finst->Instruction.Opcode) { + case TGSI_OPCODE_ABS: + arith(fpc, sat, MOV, dst, mask, abs(src[0]), none, none); + break; + case TGSI_OPCODE_ADD: + arith(fpc, sat, ADD, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_CMP: + tmp = temp(fpc); + arith(fpc, sat, MOV, dst, mask, src[2], none, none); + tmp.cc_update = 1; + arith(fpc, 0, MOV, tmp, 0xf, src[0], none, none); + dst.cc_test = NV30_VP_INST_COND_LT; + arith(fpc, sat, MOV, dst, mask, src[1], none, none); + break; + case TGSI_OPCODE_COS: + arith(fpc, sat, COS, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_DP3: + arith(fpc, sat, DP3, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DP4: + arith(fpc, sat, DP4, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DPH: + tmp = temp(fpc); + arith(fpc, 0, DP3, tmp, MASK_X, src[0], src[1], none); + arith(fpc, sat, ADD, dst, mask, swz(tmp, X, X, X, X), + swz(src[1], W, W, W, W), none); + break; + case TGSI_OPCODE_DST: + arith(fpc, sat, DST, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_EX2: + arith(fpc, sat, EX2, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_FLR: + arith(fpc, sat, FLR, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_FRC: + arith(fpc, sat, FRC, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_KIL: + arith(fpc, 0, KIL, none, 0, none, none, none); + break; + case TGSI_OPCODE_KILP: + dst = nv30_sr(NV30SR_NONE, 0); + dst.cc_update = 1; + arith(fpc, 0, MOV, dst, MASK_ALL, src[0], none, none); + dst.cc_update = 0; dst.cc_test = NV30_FP_OP_COND_LT; + arith(fpc, 0, KIL, dst, 0, none, none, none); + break; + case TGSI_OPCODE_LG2: + arith(fpc, sat, LG2, dst, mask, src[0], none, none); + break; +// case TGSI_OPCODE_LIT: + case TGSI_OPCODE_LRP: + tmp = temp(fpc); + arith(fpc, 0, MAD, tmp, mask, neg(src[0]), src[2], src[2]); + arith(fpc, sat, MAD, dst, mask, src[0], src[1], tmp); + break; + case TGSI_OPCODE_MAD: + arith(fpc, sat, MAD, dst, mask, src[0], src[1], src[2]); + break; + case TGSI_OPCODE_MAX: + arith(fpc, sat, MAX, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MIN: + arith(fpc, sat, MIN, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MOV: + arith(fpc, sat, MOV, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_MUL: + arith(fpc, sat, MUL, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_POW: + tmp = temp(fpc); + arith(fpc, 0, LG2, tmp, MASK_X, + swz(src[0], X, X, X, X), none, none); + arith(fpc, 0, MUL, tmp, MASK_X, swz(tmp, X, X, X, X), + swz(src[1], X, X, X, X), none); + arith(fpc, sat, EX2, dst, mask, + swz(tmp, X, X, X, X), none, none); + break; + case TGSI_OPCODE_RCP: + arith(fpc, sat, RCP, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_RET: + assert(0); + break; + case TGSI_OPCODE_RFL: + tmp = temp(fpc); + arith(fpc, 0, DP3, tmp, MASK_X, src[0], src[0], none); + arith(fpc, 0, DP3, tmp, MASK_Y, src[0], src[1], none); + arith(fpc, 0, DIV, scale(tmp, 2X), MASK_Z, + swz(tmp, Y, Y, Y, Y), swz(tmp, X, X, X, X), none); + arith(fpc, sat, MAD, dst, mask, + swz(tmp, Z, Z, Z, Z), src[0], neg(src[1])); + break; + case TGSI_OPCODE_RSQ: + tmp = temp(fpc); + arith(fpc, 0, LG2, scale(tmp, INV_2X), MASK_X, + abs(swz(src[0], X, X, X, X)), none, none); + arith(fpc, sat, EX2, dst, mask, + neg(swz(tmp, X, X, X, X)), none, none); + break; + case TGSI_OPCODE_SCS: + if (mask & MASK_X) { + arith(fpc, sat, COS, dst, MASK_X, + swz(src[0], X, X, X, X), none, none); + } + if (mask & MASK_Y) { + arith(fpc, sat, SIN, dst, MASK_Y, + swz(src[0], X, X, X, X), none, none); + } + break; + case TGSI_OPCODE_SIN: + arith(fpc, sat, SIN, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_SGE: + arith(fpc, sat, SGE, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SLT: + arith(fpc, sat, SLT, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SUB: + arith(fpc, sat, ADD, dst, mask, src[0], neg(src[1]), none); + break; + case TGSI_OPCODE_TEX: + tex(fpc, sat, TEX, unit, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_TXB: + tex(fpc, sat, TXB, unit, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_TXP: + tex(fpc, sat, TXP, unit, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_XPD: + tmp = temp(fpc); + arith(fpc, 0, MUL, tmp, mask, + swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none); + arith(fpc, sat, MAD, dst, (mask & ~MASK_W), + swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y), + neg(tmp)); + break; + default: + NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode); + return FALSE; + } + + return TRUE; +} + +static boolean +nv30_fragprog_parse_decl_attrib(struct nv30_fpc *fpc, + const struct tgsi_full_declaration *fdec) +{ + int hw; + + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + hw = NV30_FP_OP_INPUT_SRC_POSITION; + break; + case TGSI_SEMANTIC_COLOR: + if (fdec->Semantic.SemanticIndex == 0) { + hw = NV30_FP_OP_INPUT_SRC_COL0; + } else + if (fdec->Semantic.SemanticIndex == 1) { + hw = NV30_FP_OP_INPUT_SRC_COL1; + } else { + NOUVEAU_ERR("bad colour semantic index\n"); + return FALSE; + } + break; + case TGSI_SEMANTIC_FOG: + hw = NV30_FP_OP_INPUT_SRC_FOGC; + break; + case TGSI_SEMANTIC_GENERIC: + if (fdec->Semantic.SemanticIndex <= 7) { + hw = NV30_FP_OP_INPUT_SRC_TC(fdec->Semantic. + SemanticIndex); + } else { + NOUVEAU_ERR("bad generic semantic index\n"); + return FALSE; + } + break; + default: + NOUVEAU_ERR("bad input semantic\n"); + return FALSE; + } + + fpc->attrib_map[fdec->DeclarationRange.First] = hw; + return TRUE; +} + +static boolean +nv30_fragprog_parse_decl_output(struct nv30_fpc *fpc, + const struct tgsi_full_declaration *fdec) +{ + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + fpc->depth_id = fdec->DeclarationRange.First; + break; + case TGSI_SEMANTIC_COLOR: + fpc->colour_id = fdec->DeclarationRange.First; + break; + default: + NOUVEAU_ERR("bad output semantic\n"); + return FALSE; + } + + return TRUE; +} + +void +nv30_fragprog_translate(struct nv30_context *nv30, + struct nv30_fragment_program *fp) +{ + struct tgsi_parse_context parse; + struct nv30_fpc *fpc = NULL; + + fpc = CALLOC(1, sizeof(struct nv30_fpc)); + if (!fpc) + return; + fpc->fp = fp; + fpc->high_temp = -1; + fpc->num_regs = 2; + + tgsi_parse_init(&parse, fp->pipe.tokens); + + while (!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *fdec; + fdec = &parse.FullToken.FullDeclaration; + switch (fdec->Declaration.File) { + case TGSI_FILE_INPUT: + if (!nv30_fragprog_parse_decl_attrib(fpc, fdec)) + goto out_err; + break; + case TGSI_FILE_OUTPUT: + if (!nv30_fragprog_parse_decl_output(fpc, fdec)) + goto out_err; + break; + default: + break; + } + } + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *imm; + float vals[4]; + int i; + + imm = &parse.FullToken.FullImmediate; + assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); + assert(fpc->nr_imm < MAX_IMM); + + for (i = 0; i < 4; i++) + vals[i] = imm->u.ImmediateFloat32[i].Float; + fpc->imm[fpc->nr_imm++] = constant(fpc, -1, vals); + } + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + const struct tgsi_full_instruction *finst; + + finst = &parse.FullToken.FullInstruction; + if (!nv30_fragprog_parse_instruction(fpc, finst)) + goto out_err; + } + break; + default: + break; + } + } + + fp->fp_control |= (fpc->num_regs-1)/2; + fp->fp_reg_control = (1<<16)|0x4; + + /* Terminate final instruction */ + fp->insn[fpc->inst_offset] |= 0x00000001; + + /* Append NOP + END instruction, may or may not be necessary. */ + fpc->inst_offset = fp->insn_len; + grow_insns(fpc, 4); + fp->insn[fpc->inst_offset + 0] = 0x00000001; + fp->insn[fpc->inst_offset + 1] = 0x00000000; + fp->insn[fpc->inst_offset + 2] = 0x00000000; + fp->insn[fpc->inst_offset + 3] = 0x00000000; + + fp->translated = TRUE; + fp->on_hw = FALSE; +out_err: + tgsi_parse_free(&parse); + FREE(fpc); +} + +void +nv30_fragprog_bind(struct nv30_context *nv30, struct nv30_fragment_program *fp) +{ + struct pipe_winsys *ws = nv30->pipe.winsys; + int i; + + if (!fp->translated) { + nv30_fragprog_translate(nv30, fp); + if (!fp->translated) + assert(0); + } + + if (fp->nr_consts) { + float *map = ws->buffer_map(ws, nv30->fragprog.constant_buf, + PIPE_BUFFER_USAGE_CPU_READ); + for (i = 0; i < fp->nr_consts; i++) { + struct nv30_fragment_program_data *fpd = &fp->consts[i]; + uint32_t *p = &fp->insn[fpd->offset]; + uint32_t *cb = (uint32_t *)&map[fpd->index * 4]; + + if (!memcmp(p, cb, 4 * sizeof(float))) + continue; + memcpy(p, cb, 4 * sizeof(float)); + fp->on_hw = 0; + } + ws->buffer_unmap(ws, nv30->fragprog.constant_buf); + } + + if (!fp->on_hw) { + const uint32_t le = 1; + uint32_t *map; + + if (!fp->buffer) + fp->buffer = ws->buffer_create(ws, 0x100, 0, + fp->insn_len * 4); + map = ws->buffer_map(ws, fp->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE); + +#if 0 + for (i = 0; i < fp->insn_len; i++) { + NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]); + } +#endif + + if ((*(const uint8_t *)&le)) { + for (i = 0; i < fp->insn_len; i++) { + map[i] = fp->insn[i]; + } + } else { + /* Weird swapping for big-endian chips */ + for (i = 0; i < fp->insn_len; i++) { + map[i] = ((fp->insn[i] & 0xffff) << 16) | + ((fp->insn[i] >> 16) & 0xffff); + } + } + + ws->buffer_unmap(ws, fp->buffer); + fp->on_hw = TRUE; + } + + BEGIN_RING(rankine, NV34TCL_FP_CONTROL, 1); + OUT_RING (fp->fp_control); + BEGIN_RING(rankine, NV34TCL_FP_REG_CONTROL, 1); + OUT_RING (fp->fp_reg_control); + + nv30->fragprog.active = fp; +} + +void +nv30_fragprog_destroy(struct nv30_context *nv30, + struct nv30_fragment_program *fp) +{ + if (fp->insn_len) + FREE(fp->insn); +} + diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c new file mode 100644 index 00000000000..47f3ff047db --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -0,0 +1,160 @@ +#include "nv30_context.h" + +static INLINE int log2i(int i) +{ + int r = 0; + + if (i & 0xffff0000) { + i >>= 16; + r += 16; + } + if (i & 0x0000ff00) { + i >>= 8; + r += 8; + } + if (i & 0x000000f0) { + i >>= 4; + r += 4; + } + if (i & 0x0000000c) { + i >>= 2; + r += 2; + } + if (i & 0x00000002) { + r += 1; + } + return r; +} + +#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \ +{ \ + TRUE, \ + PIPE_FORMAT_##m, \ + NV34TCL_TX_FORMAT_FORMAT_##tf, \ + (NV34TCL_TX_SWIZZLE_S0_X_##ts0x | NV34TCL_TX_SWIZZLE_S0_Y_##ts0y | \ + NV34TCL_TX_SWIZZLE_S0_Z_##ts0z | NV34TCL_TX_SWIZZLE_S0_W_##ts0w | \ + NV34TCL_TX_SWIZZLE_S1_X_##ts1x | NV34TCL_TX_SWIZZLE_S1_Y_##ts1y | \ + NV34TCL_TX_SWIZZLE_S1_Z_##ts1z | NV34TCL_TX_SWIZZLE_S1_W_##ts1w), \ +} + +struct nv30_texture_format { + boolean defined; + uint pipe; + int format; + int swizzle; +}; + +static struct nv30_texture_format +nv30_texture_formats[] = { + _(A8R8G8B8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W), + _(A1R5G5B5_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W), + _(A4R4G4B4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W), +// _(R5G6B5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W), + _(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X), + _(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X), + _(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X), + _(A8L8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y), +// _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X), +// _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X), +// _(RGB_DXT1 , 0x86, S1, S1, S1, ONE, X, Y, Z, W, 0x00, 0x00), +// _(RGBA_DXT1 , 0x86, S1, S1, S1, S1, X, Y, Z, W, 0x00, 0x00), +// _(RGBA_DXT3 , 0x87, S1, S1, S1, S1, X, Y, Z, W, 0x00, 0x00), +// _(RGBA_DXT5 , 0x88, S1, S1, S1, S1, X, Y, Z, W, 0x00, 0x00), + {}, +}; + +static struct nv30_texture_format * +nv30_fragtex_format(uint pipe_format) +{ + struct nv30_texture_format *tf = nv30_texture_formats; + + while (tf->defined) { + if (tf->pipe == pipe_format) + return tf; + tf++; + } + + return NULL; +} + + +static void +nv30_fragtex_build(struct nv30_context *nv30, int unit) +{ + struct nv30_sampler_state *ps = nv30->tex_sampler[unit]; + struct nv30_miptree *nv30mt = nv30->tex_miptree[unit]; + struct pipe_texture *pt = &nv30mt->base; + struct nv30_texture_format *tf; + uint32_t txf, txs, txp; + int swizzled = 0; /*XXX: implement in region code? */ + + tf = nv30_fragtex_format(pt->format); + if (!tf || !tf->defined) { + NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format); + return; + } + + txf = tf->format << 8; + txf |= (pt->last_level + 1) << 16; + txf |= log2i(pt->width[0]) << 20; + txf |= log2i(pt->height[0]) << 24; + txf |= log2i(pt->depth[0]) << 28; + txf |= 8; + + switch (pt->target) { +/* case PIPE_TEXTURE_CUBE: + txf |= NV34TCL_TEX_FORMAT_CUBIC;*/ + /* fall-through */ + case PIPE_TEXTURE_2D: + txf |= (2<<4); + break; + case PIPE_TEXTURE_3D: + txf |= (3<<4); + break; + case PIPE_TEXTURE_1D: + txf |= (1<<4); + break; + default: + NOUVEAU_ERR("Unknown target %d\n", pt->target); + return; + } + + txs = tf->swizzle; + + BEGIN_RING(rankine, NV34TCL_TX_OFFSET(unit), 8); + OUT_RELOCl(nv30mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCd(nv30mt->buffer,txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); + OUT_RING (ps->wrap); + OUT_RING (0x40000000); /* enable */ + OUT_RING (txs); + OUT_RING (ps->filt | 0x2000 /* magic */); + OUT_RING ((pt->width[0] << 16) | pt->height[0]); + OUT_RING (ps->bcol); +} + +void +nv30_fragtex_bind(struct nv30_context *nv30) +{ + struct nv30_fragment_program *fp = nv30->fragprog.active; + unsigned samplers, unit; + + samplers = nv30->fp_samplers & ~fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + BEGIN_RING(rankine, NV34TCL_TX_ENABLE(unit), 1); + OUT_RING (0); + } + + samplers = nv30->dirty_samplers & fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + nv30_fragtex_build(nv30, unit); + } + + nv30->fp_samplers = fp->samplers; +} + diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c new file mode 100644 index 00000000000..6078b1865e2 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -0,0 +1,148 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nv30_context.h" + +static void +nv30_miptree_layout(struct nv30_miptree *nv30mt) +{ + struct pipe_texture *pt = &nv30mt->base; + boolean swizzled = FALSE; + uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; + uint offset = 0; + int nr_faces, l, f, pitch; + + if (pt->target == PIPE_TEXTURE_CUBE) { + nr_faces = 6; + } else + if (pt->target == PIPE_TEXTURE_3D) { + nr_faces = pt->depth[0]; + } else { + nr_faces = 1; + } + + pitch = pt->width[0]; + for (l = 0; l <= pt->last_level; l++) { + pt->width[l] = width; + pt->height[l] = height; + pt->depth[l] = depth; + + if (swizzled) + pitch = pt->width[l]; + pitch = (pitch + 63) & ~63; + + nv30mt->level[l].pitch = pitch * pt->cpp; + nv30mt->level[l].image_offset = + CALLOC(nr_faces, sizeof(unsigned)); + + width = MAX2(1, width >> 1); + height = MAX2(1, height >> 1); + depth = MAX2(1, depth >> 1); + + } + + for (f = 0; f < nr_faces; f++) { + for (l = 0; l <= pt->last_level; l++) { + nv30mt->level[l].image_offset[f] = offset; + offset += nv30mt->level[l].pitch * pt->height[l]; + } + } + + nv30mt->total_size = offset; +} + +static struct pipe_texture * +nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) +{ + struct pipe_winsys *ws = pscreen->winsys; + struct nv30_miptree *mt; + + mt = MALLOC(sizeof(struct nv30_miptree)); + if (!mt) + return NULL; + mt->base = *pt; + mt->base.refcount = 1; + mt->base.screen = pscreen; + + nv30_miptree_layout(mt); + + mt->buffer = ws->buffer_create(ws, 256, + PIPE_BUFFER_USAGE_PIXEL | + NOUVEAU_BUFFER_USAGE_TEXTURE, + mt->total_size); + if (!mt->buffer) { + FREE(mt); + return NULL; + } + + return &mt->base; +} + +static void +nv30_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) +{ + struct pipe_winsys *ws = pscreen->winsys; + struct pipe_texture *mt = *pt; + + *pt = NULL; + if (--mt->refcount <= 0) { + struct nv30_miptree *nv30mt = (struct nv30_miptree *)mt; + int l; + + pipe_buffer_reference(ws, &nv30mt->buffer, NULL); + for (l = 0; l <= mt->last_level; l++) { + if (nv30mt->level[l].image_offset) + FREE(nv30mt->level[l].image_offset); + } + FREE(nv30mt); + } +} + +static struct pipe_surface * +nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) +{ + struct pipe_winsys *ws = pscreen->winsys; + struct nv30_miptree *nv30mt = (struct nv30_miptree *)pt; + struct pipe_surface *ps; + + ps = ws->surface_alloc(ws); + if (!ps) + return NULL; + pipe_buffer_reference(ws, &ps->buffer, nv30mt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = nv30mt->level[level].pitch / ps->cpp; + + if (pt->target == PIPE_TEXTURE_CUBE) { + ps->offset = nv30mt->level[level].image_offset[face]; + } else + if (pt->target == PIPE_TEXTURE_3D) { + ps->offset = nv30mt->level[level].image_offset[zslice]; + } else { + ps->offset = nv30mt->level[level].image_offset[0]; + } + + return ps; +} + +static void +nv30_miptree_surface_del(struct pipe_screen *pscreen, + struct pipe_surface **psurface) +{ +} + +void +nv30_screen_init_miptree_functions(struct pipe_screen *pscreen) +{ + pscreen->texture_create = nv30_miptree_create; + pscreen->texture_release = nv30_miptree_release; + pscreen->get_tex_surface = nv30_miptree_surface_new; + pscreen->tex_surface_release = nv30_miptree_surface_del; +} + diff --git a/src/gallium/drivers/nv30/nv30_query.c b/src/gallium/drivers/nv30/nv30_query.c new file mode 100644 index 00000000000..d40d75f2640 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_query.c @@ -0,0 +1,122 @@ +#include "pipe/p_context.h" + +#include "nv30_context.h" + +struct nv30_query { + struct nouveau_resource *object; + unsigned type; + boolean ready; + uint64_t result; +}; + +static INLINE struct nv30_query * +nv30_query(struct pipe_query *pipe) +{ + return (struct nv30_query *)pipe; +} + +static struct pipe_query * +nv30_query_create(struct pipe_context *pipe, unsigned query_type) +{ + struct nv30_query *q; + + q = CALLOC(1, sizeof(struct nv30_query)); + q->type = query_type; + + return (struct pipe_query *)q; +} + +static void +nv30_query_destroy(struct pipe_context *pipe, struct pipe_query *pq) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_query *q = nv30_query(pq); + + if (q->object) + nv30->nvws->res_free(&q->object); + FREE(q); +} + +static void +nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_query *q = nv30_query(pq); + + assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER); + + /* Happens when end_query() is called, then another begin_query() + * without querying the result in-between. For now we'll wait for + * the existing query to notify completion, but it could be better. + */ + if (q->object) { + uint64 tmp; + pipe->get_query_result(pipe, pq, 1, &tmp); + } + + if (nv30->nvws->res_alloc(nv30->screen->query_heap, 1, NULL, &q->object)) + assert(0); + nv30->nvws->notifier_reset(nv30->screen->query, q->object->start); + + BEGIN_RING(rankine, NV34TCL_QUERY_RESET, 1); + OUT_RING (1); + BEGIN_RING(rankine, NV34TCL_QUERY_UNK17CC, 1); + OUT_RING (1); + + q->ready = FALSE; +} + +static void +nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_query *q = nv30_query(pq); + + BEGIN_RING(rankine, NV34TCL_QUERY_GET, 1); + OUT_RING ((0x01 << NV34TCL_QUERY_GET_UNK24_SHIFT) | + ((q->object->start * 32) << NV34TCL_QUERY_GET_OFFSET_SHIFT)); + FIRE_RING(NULL); +} + +static boolean +nv30_query_result(struct pipe_context *pipe, struct pipe_query *pq, + boolean wait, uint64 *result) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_query *q = nv30_query(pq); + struct nouveau_winsys *nvws = nv30->nvws; + + assert(q->object && q->type == PIPE_QUERY_OCCLUSION_COUNTER); + + if (!q->ready) { + unsigned status; + + status = nvws->notifier_status(nv30->screen->query, + q->object->start); + if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) { + if (wait == FALSE) + return FALSE; + nvws->notifier_wait(nv30->screen->query, q->object->start, + NV_NOTIFY_STATE_STATUS_COMPLETED, + 0); + } + + q->result = nvws->notifier_retval(nv30->screen->query, + q->object->start); + q->ready = TRUE; + nvws->res_free(&q->object); + } + + *result = q->result; + return TRUE; +} + +void +nv30_init_query_functions(struct nv30_context *nv30) +{ + nv30->pipe.create_query = nv30_query_create; + nv30->pipe.destroy_query = nv30_query_destroy; + nv30->pipe.begin_query = nv30_query_begin; + nv30->pipe.end_query = nv30_query_end; + nv30->pipe.get_query_result = nv30_query_result; +} diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c new file mode 100644 index 00000000000..9c576369891 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -0,0 +1,332 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv30_context.h" +#include "nv30_screen.h" + +#define NV30TCL_CHIPSET_3X_MASK 0x00000003 +#define NV34TCL_CHIPSET_3X_MASK 0x00000010 +#define NV35TCL_CHIPSET_3X_MASK 0x000001e0 + +static const char * +nv30_screen_get_name(struct pipe_screen *pscreen) +{ + struct nv30_screen *screen = nv30_screen(pscreen); + struct nouveau_device *dev = screen->nvws->channel->device; + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); + return buffer; +} + +static const char * +nv30_screen_get_vendor(struct pipe_screen *pscreen) +{ + return "nouveau"; +} + +static int +nv30_screen_get_param(struct pipe_screen *pscreen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 16; + case PIPE_CAP_NPOT_TEXTURES: + return 0; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 1; + case PIPE_CAP_POINT_SPRITE: + return 1; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 2; + case PIPE_CAP_OCCLUSION_QUERY: + return 1; + 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 NOUVEAU_CAP_HW_VTXBUF: + case NOUVEAU_CAP_HW_IDXBUF: + return 0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv30_screen_get_paramf(struct pipe_screen *pscreen, int 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 boolean +nv30_screen_surface_format_supported(struct pipe_screen *pscreen, + enum pipe_format format, uint type) +{ + switch (type) { + case PIPE_SURFACE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + return TRUE; + default: + break; + } + break; + case PIPE_TEXTURE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A4R4G4B4_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_A8L8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static void * +nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, + unsigned flags ) +{ + struct pipe_winsys *ws = screen->winsys; + void *map; + + map = ws->buffer_map(ws, surface->buffer, flags); + if (!map) + return NULL; + + return map + surface->offset; +} + +static void +nv30_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) +{ + struct pipe_winsys *ws = screen->winsys; + + ws->buffer_unmap(ws, surface->buffer); +} + +static void +nv30_screen_destroy(struct pipe_screen *pscreen) +{ + struct nv30_screen *screen = nv30_screen(pscreen); + struct nouveau_winsys *nvws = screen->nvws; + + nvws->res_free(&screen->vp_exec_heap); + nvws->res_free(&screen->vp_data_heap); + nvws->res_free(&screen->query_heap); + nvws->notifier_free(&screen->query); + nvws->notifier_free(&screen->sync); + nvws->grobj_free(&screen->rankine); + + FREE(pscreen); +} + +struct pipe_screen * +nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) +{ + struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen); + struct nouveau_stateobj *so; + unsigned rankine_class = 0; + unsigned chipset = nvws->channel->device->chipset; + int ret, i; + + if (!screen) + return NULL; + screen->nvws = nvws; + + /* 3D object */ + switch (chipset & 0xf0) { + case 0x30: + if (NV30TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f))) + rankine_class = 0x0397; + else + if (NV34TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f))) + rankine_class = 0x0697; + else + if (NV35TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f))) + rankine_class = 0x0497; + break; + default: + break; + } + + if (!rankine_class) { + NOUVEAU_ERR("Unknown nv3x chipset: nv%02x\n", chipset); + return NULL; + } + + ret = nvws->grobj_alloc(nvws, rankine_class, &screen->rankine); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return FALSE; + } + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &screen->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv30_screen_destroy(&screen->pipe); + return NULL; + } + + /* Query objects */ + ret = nvws->notifier_alloc(nvws, 32, &screen->query); + if (ret) { + NOUVEAU_ERR("Error initialising query objects: %d\n", ret); + nv30_screen_destroy(&screen->pipe); + return NULL; + } + + ret = nvws->res_init(&screen->query_heap, 0, 32); + if (ret) { + NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); + nv30_screen_destroy(&screen->pipe); + return NULL; + } + + /* Vtxprog resources */ + if (nvws->res_init(&screen->vp_exec_heap, 0, 256) || + nvws->res_init(&screen->vp_data_heap, 0, 256)) { + nv30_screen_destroy(&screen->pipe); + return NULL; + } + + /* Static rankine initialisation */ + so = so_new(128, 0); + so_method(so, screen->rankine, NV34TCL_DMA_NOTIFY, 1); + so_data (so, screen->sync->handle); + so_method(so, screen->rankine, NV34TCL_DMA_TEXTURE0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, screen->rankine, NV34TCL_DMA_COLOR1, 1); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->rankine, NV34TCL_DMA_COLOR0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->rankine, NV34TCL_DMA_VTXBUF0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); +/* so_method(so, screen->rankine, NV34TCL_DMA_FENCE, 2); + so_data (so, 0); + so_data (so, screen->query->handle);*/ + so_method(so, screen->rankine, NV34TCL_DMA_IN_MEMORY7, 1); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->rankine, NV34TCL_DMA_IN_MEMORY8, 1); + so_data (so, nvws->channel->vram->handle); + + for (i=1; i<8; i++) { + so_method(so, screen->rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(i), 1); + so_data (so, 0); + so_method(so, screen->rankine, NV34TCL_VIEWPORT_CLIP_VERT(i), 1); + so_data (so, 0); + } + + so_method(so, screen->rankine, 0x220, 1); + so_data (so, 1); + + so_method(so, screen->rankine, 0x03b0, 1); + so_data (so, 0x00100000); + so_method(so, screen->rankine, 0x1454, 1); + so_data (so, 0); + so_method(so, screen->rankine, 0x1d80, 1); + so_data (so, 3); + so_method(so, screen->rankine, 0x1450, 1); + so_data (so, 0x00030004); + + /* NEW */ + so_method(so, screen->rankine, 0x1e98, 1); + so_data (so, 0); + so_method(so, screen->rankine, 0x17e0, 3); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(1.0)); + so_method(so, screen->rankine, 0x1f80, 16); + for (i=0; i<16; i++) { + so_data (so, (i==8) ? 0x0000ffff : 0); + } + + so_method(so, screen->rankine, 0x120, 3); + so_data (so, 0); + so_data (so, 1); + so_data (so, 2); + + so_method(so, screen->rankine, 0x1d88, 1); + so_data (so, 0x00001200); + + so_method(so, screen->rankine, NV34TCL_RC_ENABLE, 1); + so_data (so, 0); + + so_method(so, screen->rankine, NV34TCL_DEPTH_RANGE_NEAR, 2); + so_data (so, fui(0.0)); + so_data (so, fui(1.0)); + + so_method(so, screen->rankine, NV34TCL_MULTISAMPLE_CONTROL, 1); + so_data (so, 0xffff0000); + + /* enables use of vp rather than fixed-function somehow */ + so_method(so, screen->rankine, 0x1e94, 1); + so_data (so, 0x13); + + so_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws, 0, NULL); + + screen->pipe.winsys = ws; + screen->pipe.destroy = nv30_screen_destroy; + + screen->pipe.get_name = nv30_screen_get_name; + screen->pipe.get_vendor = nv30_screen_get_vendor; + screen->pipe.get_param = nv30_screen_get_param; + screen->pipe.get_paramf = nv30_screen_get_paramf; + + screen->pipe.is_format_supported = nv30_screen_surface_format_supported; + + screen->pipe.surface_map = nv30_surface_map; + screen->pipe.surface_unmap = nv30_surface_unmap; + + nv30_screen_init_miptree_functions(&screen->pipe); + + return &screen->pipe; +} + diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h new file mode 100644 index 00000000000..b7ddc2a9594 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_screen.h @@ -0,0 +1,35 @@ +#ifndef __NV30_SCREEN_H__ +#define __NV30_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv30_screen { + struct pipe_screen pipe; + + struct nouveau_winsys *nvws; + + unsigned cur_pctx; + + /* HW graphics objects */ + struct nouveau_grobj *rankine; + struct nouveau_notifier *sync; + + /* Query object resources */ + struct nouveau_notifier *query; + struct nouveau_resource *query_heap; + + /* Vtxprog resources */ + struct nouveau_resource *vp_exec_heap; + struct nouveau_resource *vp_data_heap; + + /* Current 3D state of channel */ + struct nouveau_stateobj *state[NV30_STATE_MAX]; +}; + +static INLINE struct nv30_screen * +nv30_screen(struct pipe_screen *screen) +{ + return (struct nv30_screen *)screen; +} + +#endif diff --git a/src/gallium/drivers/nv30/nv30_shader.h b/src/gallium/drivers/nv30/nv30_shader.h new file mode 100644 index 00000000000..dd3a36f78f3 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_shader.h @@ -0,0 +1,490 @@ +#ifndef __NV30_SHADER_H__ +#define __NV30_SHADER_H__ + +/* Vertex programs instruction set + * + * 128bit opcodes, split into 4 32-bit ones for ease of use. + * + * Non-native instructions + * ABS - MOV + NV40_VP_INST0_DEST_ABS + * POW - EX2 + MUL + LG2 + * SUB - ADD, second source negated + * SWZ - MOV + * XPD - + * + * Register access + * - Only one INPUT can be accessed per-instruction (move extras into TEMPs) + * - Only one CONST can be accessed per-instruction (move extras into TEMPs) + * + * Relative Addressing + * According to the value returned for + * MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB + * + * there are only two address registers available. The destination in the + * ARL instruction is set to TEMP <n> (The temp isn't actually written). + * + * When using vanilla ARB_v_p, the proprietary driver will squish both the + * available ADDRESS regs into the first hardware reg in the X and Y + * components. + * + * To use an address reg as an index into consts, the CONST_SRC is set to + * (const_base + offset) and INDEX_CONST is set. + * + * To access the second address reg use ADDR_REG_SELECT_1. A particular + * component of the address regs is selected with ADDR_SWZ. + * + * Only one address register can be accessed per instruction. + * + * Conditional execution (see NV_vertex_program{2,3} for details) Conditional + * execution of an instruction is enabled by setting COND_TEST_ENABLE, and + * selecting the condition which will allow the test to pass with + * COND_{FL,LT,...}. It is possible to swizzle the values in the condition + * register, which allows for testing against an individual component. + * + * Branching: + * + * The BRA/CAL instructions seem to follow a slightly different opcode + * layout. The destination instruction ID (IADDR) overlaps a source field. + * Instruction ID's seem to be numbered based on the UPLOAD_FROM_ID FIFO + * command, and is incremented automatically on each UPLOAD_INST FIFO + * command. + * + * Conditional branching is achieved by using the condition tests described + * above. There doesn't appear to be dedicated looping instructions, but + * this can be done using a temp reg + conditional branching. + * + * Subroutines may be uploaded before the main program itself, but the first + * executed instruction is determined by the PROGRAM_START_ID FIFO command. + * + */ + +/* DWORD 0 */ + +#define NV30_VP_INST_ADDR_REG_SELECT_1 (1 << 24) +#define NV30_VP_INST_SRC2_ABS (1 << 23) /* guess */ +#define NV30_VP_INST_SRC1_ABS (1 << 22) /* guess */ +#define NV30_VP_INST_SRC0_ABS (1 << 21) /* guess */ +#define NV30_VP_INST_VEC_RESULT (1 << 20) +#define NV30_VP_INST_DEST_TEMP_ID_SHIFT 16 +#define NV30_VP_INST_DEST_TEMP_ID_MASK (0x0F << 16) +#define NV30_VP_INST_COND_UPDATE_ENABLE (1<<15) +#define NV30_VP_INST_VEC_DEST_TEMP_MASK (0xF << 16) +#define NV30_VP_INST_COND_TEST_ENABLE (1<<14) +#define NV30_VP_INST_COND_SHIFT 11 +#define NV30_VP_INST_COND_MASK (0x07 << 11) +# define NV30_VP_INST_COND_FL 0 /* guess */ +# define NV30_VP_INST_COND_LT 1 +# define NV30_VP_INST_COND_EQ 2 +# define NV30_VP_INST_COND_LE 3 +# define NV30_VP_INST_COND_GT 4 +# define NV30_VP_INST_COND_NE 5 +# define NV30_VP_INST_COND_GE 6 +# define NV30_VP_INST_COND_TR 7 /* guess */ +#define NV30_VP_INST_COND_SWZ_X_SHIFT 9 +#define NV30_VP_INST_COND_SWZ_X_MASK (0x03 << 9) +#define NV30_VP_INST_COND_SWZ_Y_SHIFT 7 +#define NV30_VP_INST_COND_SWZ_Y_MASK (0x03 << 7) +#define NV30_VP_INST_COND_SWZ_Z_SHIFT 5 +#define NV30_VP_INST_COND_SWZ_Z_MASK (0x03 << 5) +#define NV30_VP_INST_COND_SWZ_W_SHIFT 3 +#define NV30_VP_INST_COND_SWZ_W_MASK (0x03 << 3) +#define NV30_VP_INST_COND_SWZ_ALL_SHIFT 3 +#define NV30_VP_INST_COND_SWZ_ALL_MASK (0xFF << 3) +#define NV30_VP_INST_ADDR_SWZ_SHIFT 1 +#define NV30_VP_INST_ADDR_SWZ_MASK (0x03 << 1) +#define NV30_VP_INST_SCA_OPCODEH_SHIFT 0 +#define NV30_VP_INST_SCA_OPCODEH_MASK (0x01 << 0) + +/* DWORD 1 */ +#define NV30_VP_INST_SCA_OPCODEL_SHIFT 28 +#define NV30_VP_INST_SCA_OPCODEL_MASK (0x0F << 28) +# define NV30_VP_INST_OP_NOP 0x00 +# define NV30_VP_INST_OP_RCP 0x02 +# define NV30_VP_INST_OP_RCC 0x03 +# define NV30_VP_INST_OP_RSQ 0x04 +# define NV30_VP_INST_OP_EXP 0x05 +# define NV30_VP_INST_OP_LOG 0x06 +# define NV30_VP_INST_OP_LIT 0x07 +# define NV30_VP_INST_OP_BRA 0x09 +# define NV30_VP_INST_OP_CAL 0x0B +# define NV30_VP_INST_OP_RET 0x0C +# define NV30_VP_INST_OP_LG2 0x0D +# define NV30_VP_INST_OP_EX2 0x0E +# define NV30_VP_INST_OP_SIN 0x0F +# define NV30_VP_INST_OP_COS 0x10 +#define NV30_VP_INST_VEC_OPCODE_SHIFT 23 +#define NV30_VP_INST_VEC_OPCODE_MASK (0x1F << 23) +# define NV30_VP_INST_OP_NOPV 0x00 +# define NV30_VP_INST_OP_MOV 0x01 +# define NV30_VP_INST_OP_MUL 0x02 +# define NV30_VP_INST_OP_ADD 0x03 +# define NV30_VP_INST_OP_MAD 0x04 +# define NV30_VP_INST_OP_DP3 0x05 +# define NV30_VP_INST_OP_DP4 0x07 +# define NV30_VP_INST_OP_DPH 0x06 +# define NV30_VP_INST_OP_DST 0x08 +# define NV30_VP_INST_OP_MIN 0x09 +# define NV30_VP_INST_OP_MAX 0x0A +# define NV30_VP_INST_OP_SLT 0x0B +# define NV30_VP_INST_OP_SGE 0x0C +# define NV30_VP_INST_OP_ARL 0x0D +# define NV30_VP_INST_OP_FRC 0x0E +# define NV30_VP_INST_OP_FLR 0x0F +# define NV30_VP_INST_OP_SEQ 0x10 +# define NV30_VP_INST_OP_SFL 0x11 +# define NV30_VP_INST_OP_SGT 0x12 +# define NV30_VP_INST_OP_SLE 0x13 +# define NV30_VP_INST_OP_SNE 0x14 +# define NV30_VP_INST_OP_STR 0x15 +# define NV30_VP_INST_OP_SSG 0x16 +# define NV30_VP_INST_OP_ARR 0x17 +# define NV30_VP_INST_OP_ARA 0x18 +#define NV30_VP_INST_CONST_SRC_SHIFT 14 +#define NV30_VP_INST_CONST_SRC_MASK (0xFF << 14) +#define NV30_VP_INST_INPUT_SRC_SHIFT 9 /*NV20*/ +#define NV30_VP_INST_INPUT_SRC_MASK (0x0F << 9) /*NV20*/ +# define NV30_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */ +# define NV30_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */ +# define NV30_VP_INST_IN_NORMAL 2 +# define NV30_VP_INST_IN_COL0 3 /* Should probably confirm them all though */ +# define NV30_VP_INST_IN_COL1 4 +# define NV30_VP_INST_IN_FOGC 5 +# define NV30_VP_INST_IN_TC0 8 +# define NV30_VP_INST_IN_TC(n) (8+n) +#define NV30_VP_INST_SRC0H_SHIFT 0 /*NV20*/ +#define NV30_VP_INST_SRC0H_MASK (0x1FF << 0) /*NV20*/ + +/* Please note: the IADDR fields overlap other fields because they are used + * only for branch instructions. See Branching: label above + * + * DWORD 2 + */ +#define NV30_VP_INST_SRC0L_SHIFT 26 /*NV20*/ +#define NV30_VP_INST_SRC0L_MASK (0x3F <<26) /* NV30_VP_SRC0_LOW_MASK << 26 */ +#define NV30_VP_INST_SRC1_SHIFT 11 /*NV20*/ +#define NV30_VP_INST_SRC1_MASK (0x7FFF<<11) /*NV20*/ +#define NV30_VP_INST_SRC2H_SHIFT 0 /*NV20*/ +#define NV30_VP_INST_SRC2H_MASK (0x7FF << 0) /* NV30_VP_SRC2_HIGH_MASK >> 4*/ +#define NV30_VP_INST_IADDR_SHIFT 2 +#define NV30_VP_INST_IADDR_MASK (0xF << 28) /* NV30_VP_SRC2_LOW_MASK << 28 */ + +/* DWORD 3 */ +#define NV30_VP_INST_SRC2L_SHIFT 28 /*NV20*/ +#define NV30_VP_INST_SRC2L_MASK (0x0F <<28) /*NV20*/ +#define NV30_VP_INST_STEMP_WRITEMASK_SHIFT 24 +#define NV30_VP_INST_STEMP_WRITEMASK_MASK (0x0F << 24) +#define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT 20 +#define NV30_VP_INST_VTEMP_WRITEMASK_MASK (0x0F << 20) +#define NV30_VP_INST_SDEST_WRITEMASK_SHIFT 16 +#define NV30_VP_INST_SDEST_WRITEMASK_MASK (0x0F << 16) +#define NV30_VP_INST_VDEST_WRITEMASK_SHIFT 12 /*NV20*/ +#define NV30_VP_INST_VDEST_WRITEMASK_MASK (0x0F << 12) /*NV20*/ +#define NV30_VP_INST_DEST_SHIFT 2 +#define NV30_VP_INST_DEST_MASK (0x0F << 2) +# define NV30_VP_INST_DEST_POS 0 +# define NV30_VP_INST_DEST_BFC0 1 +# define NV30_VP_INST_DEST_BFC1 2 +# define NV30_VP_INST_DEST_COL0 3 +# define NV30_VP_INST_DEST_COL1 4 +# define NV30_VP_INST_DEST_FOGC 5 +# define NV30_VP_INST_DEST_PSZ 6 +# define NV30_VP_INST_DEST_TC(n) (8+n) + +#define NV30_VP_INST_LAST (1 << 0) + +/* Useful to split the source selection regs into their pieces */ +#define NV30_VP_SRC0_HIGH_SHIFT 6 +#define NV30_VP_SRC0_HIGH_MASK 0x00007FC0 +#define NV30_VP_SRC0_LOW_MASK 0x0000003F +#define NV30_VP_SRC2_HIGH_SHIFT 4 +#define NV30_VP_SRC2_HIGH_MASK 0x00007FF0 +#define NV30_VP_SRC2_LOW_MASK 0x0000000F + + +/* Source-register definition - matches NV20 exactly */ +#define NV30_VP_SRC_NEGATE (1<<14) +#define NV30_VP_SRC_SWZ_X_SHIFT 12 +#define NV30_VP_SRC_REG_SWZ_X_MASK (0x03 <<12) +#define NV30_VP_SRC_SWZ_Y_SHIFT 10 +#define NV30_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10) +#define NV30_VP_SRC_SWZ_Z_SHIFT 8 +#define NV30_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8) +#define NV30_VP_SRC_SWZ_W_SHIFT 6 +#define NV30_VP_SRC_REG_SWZ_W_MASK (0x03 << 6) +#define NV30_VP_SRC_REG_SWZ_ALL_SHIFT 6 +#define NV30_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6) +#define NV30_VP_SRC_TEMP_SRC_SHIFT 2 +#define NV30_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0) +#define NV30_VP_SRC_REG_TYPE_SHIFT 0 +#define NV30_VP_SRC_REG_TYPE_MASK (0x03 << 0) +#define NV30_VP_SRC_REG_TYPE_TEMP 1 +#define NV30_VP_SRC_REG_TYPE_INPUT 2 +#define NV30_VP_SRC_REG_TYPE_CONST 3 /* guess */ + +/* + * Each fragment program opcode appears to be comprised of 4 32-bit values. + * + * 0 - Opcode, output reg/mask, ATTRIB source + * 1 - Source 0 + * 2 - Source 1 + * 3 - Source 2 + * + * There appears to be no special difference between result regs and temp regs. + * result.color == R0.xyzw + * result.depth == R1.z + * When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0 + * otherwise it is set to 1. + * + * Constants are inserted directly after the instruction that uses them. + * + * It appears that it's not possible to use two input registers in one + * instruction as the input sourcing is done in the instruction dword + * and not the source selection dwords. As such instructions such as: + * + * ADD result.color, fragment.color, fragment.texcoord[0]; + * + * must be split into two MOV's and then an ADD (nvidia does this) but + * I'm not sure why it's not just one MOV and then source the second input + * in the ADD instruction.. + * + * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary + * negation requires multiplication with a const. + * + * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE + * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO + * is implemented simply by not writing to the relevant components of the destination. + * + * Conditional execution + * TODO + * + * Non-native instructions: + * LIT + * LRP - MAD+MAD + * SUB - ADD, negate second source + * RSQ - LG2 + EX2 + * POW - LG2 + MUL + EX2 + * SCS - COS + SIN + * XPD + */ + +//== Opcode / Destination selection == +#define NV30_FP_OP_PROGRAM_END (1 << 0) +#define NV30_FP_OP_OUT_REG_SHIFT 1 +#define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */ +/* Needs to be set when writing outputs to get expected result.. */ +#define NV30_FP_OP_OUT_REG_HALF (1 << 7) +#define NV30_FP_OP_COND_WRITE_ENABLE (1 << 8) +#define NV30_FP_OP_OUTMASK_SHIFT 9 +#define NV30_FP_OP_OUTMASK_MASK (0xF << 9) +# define NV30_FP_OP_OUT_X (1<<9) +# define NV30_FP_OP_OUT_Y (1<<10) +# define NV30_FP_OP_OUT_Z (1<<11) +# define NV30_FP_OP_OUT_W (1<<12) +/* Uncertain about these, especially the input_src values.. it's possible that + * they can be dynamically changed. + */ +#define NV30_FP_OP_INPUT_SRC_SHIFT 13 +#define NV30_FP_OP_INPUT_SRC_MASK (15 << 13) +# define NV30_FP_OP_INPUT_SRC_POSITION 0x0 +# define NV30_FP_OP_INPUT_SRC_COL0 0x1 +# define NV30_FP_OP_INPUT_SRC_COL1 0x2 +# define NV30_FP_OP_INPUT_SRC_FOGC 0x3 +# define NV30_FP_OP_INPUT_SRC_TC0 0x4 +# define NV30_FP_OP_INPUT_SRC_TC(n) (0x4 + n) +#define NV30_FP_OP_TEX_UNIT_SHIFT 17 +#define NV30_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */ +#define NV30_FP_OP_PRECISION_SHIFT 22 +#define NV30_FP_OP_PRECISION_MASK (3 << 22) +# define NV30_FP_PRECISION_FP32 0 +# define NV30_FP_PRECISION_FP16 1 +# define NV30_FP_PRECISION_FX12 2 +#define NV30_FP_OP_OPCODE_SHIFT 24 +#define NV30_FP_OP_OPCODE_MASK (0x3F << 24) +# define NV30_FP_OP_OPCODE_NOP 0x00 +# define NV30_FP_OP_OPCODE_MOV 0x01 +# define NV30_FP_OP_OPCODE_MUL 0x02 +# define NV30_FP_OP_OPCODE_ADD 0x03 +# define NV30_FP_OP_OPCODE_MAD 0x04 +# define NV30_FP_OP_OPCODE_DP3 0x05 +# define NV30_FP_OP_OPCODE_DP4 0x06 +# define NV30_FP_OP_OPCODE_DST 0x07 +# define NV30_FP_OP_OPCODE_MIN 0x08 +# define NV30_FP_OP_OPCODE_MAX 0x09 +# define NV30_FP_OP_OPCODE_SLT 0x0A +# define NV30_FP_OP_OPCODE_SGE 0x0B +# define NV30_FP_OP_OPCODE_SLE 0x0C +# define NV30_FP_OP_OPCODE_SGT 0x0D +# define NV30_FP_OP_OPCODE_SNE 0x0E +# define NV30_FP_OP_OPCODE_SEQ 0x0F +# define NV30_FP_OP_OPCODE_FRC 0x10 +# define NV30_FP_OP_OPCODE_FLR 0x11 +# define NV30_FP_OP_OPCODE_KIL 0x12 +# define NV30_FP_OP_OPCODE_PK4B 0x13 +# define NV30_FP_OP_OPCODE_UP4B 0x14 +# define NV30_FP_OP_OPCODE_DDX 0x15 /* can only write XY */ +# define NV30_FP_OP_OPCODE_DDY 0x16 /* can only write XY */ +# define NV30_FP_OP_OPCODE_TEX 0x17 +# define NV30_FP_OP_OPCODE_TXP 0x18 +# define NV30_FP_OP_OPCODE_TXD 0x19 +# define NV30_FP_OP_OPCODE_RCP 0x1A +# define NV30_FP_OP_OPCODE_RSQ 0x1B +# define NV30_FP_OP_OPCODE_EX2 0x1C +# define NV30_FP_OP_OPCODE_LG2 0x1D +# define NV30_FP_OP_OPCODE_LIT 0x1E +# define NV30_FP_OP_OPCODE_LRP 0x1F +# define NV30_FP_OP_OPCODE_STR 0x20 +# define NV30_FP_OP_OPCODE_SFL 0x21 +# define NV30_FP_OP_OPCODE_COS 0x22 +# define NV30_FP_OP_OPCODE_SIN 0x23 +# define NV30_FP_OP_OPCODE_PK2H 0x24 +# define NV30_FP_OP_OPCODE_UP2H 0x25 +# define NV30_FP_OP_OPCODE_POW 0x26 +# define NV30_FP_OP_OPCODE_PK4UB 0x27 +# define NV30_FP_OP_OPCODE_UP4UB 0x28 +# define NV30_FP_OP_OPCODE_PK2US 0x29 +# define NV30_FP_OP_OPCODE_UP2US 0x2A +# define NV30_FP_OP_OPCODE_DP2A 0x2E +# define NV30_FP_OP_OPCODE_TXB 0x31 +# define NV30_FP_OP_OPCODE_RFL 0x36 +# define NV30_FP_OP_OPCODE_DIV 0x3A +#define NV30_FP_OP_OUT_SAT (1 << 31) + +/* high order bits of SRC0 */ +#define NV30_FP_OP_OUT_ABS (1 << 29) +#define NV30_FP_OP_COND_SWZ_W_SHIFT 27 +#define NV30_FP_OP_COND_SWZ_W_MASK (3 << 27) +#define NV30_FP_OP_COND_SWZ_Z_SHIFT 25 +#define NV30_FP_OP_COND_SWZ_Z_MASK (3 << 25) +#define NV30_FP_OP_COND_SWZ_Y_SHIFT 23 +#define NV30_FP_OP_COND_SWZ_Y_MASK (3 << 23) +#define NV30_FP_OP_COND_SWZ_X_SHIFT 21 +#define NV30_FP_OP_COND_SWZ_X_MASK (3 << 21) +#define NV30_FP_OP_COND_SWZ_ALL_SHIFT 21 +#define NV30_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21) +#define NV30_FP_OP_COND_SHIFT 18 +#define NV30_FP_OP_COND_MASK (0x07 << 18) +# define NV30_FP_OP_COND_FL 0 +# define NV30_FP_OP_COND_LT 1 +# define NV30_FP_OP_COND_EQ 2 +# define NV30_FP_OP_COND_LE 3 +# define NV30_FP_OP_COND_GT 4 +# define NV30_FP_OP_COND_NE 5 +# define NV30_FP_OP_COND_GE 6 +# define NV30_FP_OP_COND_TR 7 + +/* high order bits of SRC1 */ +#define NV30_FP_OP_DST_SCALE_SHIFT 28 +#define NV30_FP_OP_DST_SCALE_MASK (3 << 28) +#define NV30_FP_OP_DST_SCALE_1X 0 +#define NV30_FP_OP_DST_SCALE_2X 1 +#define NV30_FP_OP_DST_SCALE_4X 2 +#define NV30_FP_OP_DST_SCALE_8X 3 +#define NV30_FP_OP_DST_SCALE_INV_2X 5 +#define NV30_FP_OP_DST_SCALE_INV_4X 6 +#define NV30_FP_OP_DST_SCALE_INV_8X 7 + + +/* high order bits of SRC2 */ +#define NV30_FP_OP_INDEX_INPUT (1 << 30) + +//== Register selection == +#define NV30_FP_REG_TYPE_SHIFT 0 +#define NV30_FP_REG_TYPE_MASK (3 << 0) +# define NV30_FP_REG_TYPE_TEMP 0 +# define NV30_FP_REG_TYPE_INPUT 1 +# define NV30_FP_REG_TYPE_CONST 2 +#define NV30_FP_REG_SRC_SHIFT 2 /* uncertain */ +#define NV30_FP_REG_SRC_MASK (31 << 2) +#define NV30_FP_REG_SRC_HALF (1 << 8) +#define NV30_FP_REG_SWZ_ALL_SHIFT 9 +#define NV30_FP_REG_SWZ_ALL_MASK (255 << 9) +#define NV30_FP_REG_SWZ_X_SHIFT 9 +#define NV30_FP_REG_SWZ_X_MASK (3 << 9) +#define NV30_FP_REG_SWZ_Y_SHIFT 11 +#define NV30_FP_REG_SWZ_Y_MASK (3 << 11) +#define NV30_FP_REG_SWZ_Z_SHIFT 13 +#define NV30_FP_REG_SWZ_Z_MASK (3 << 13) +#define NV30_FP_REG_SWZ_W_SHIFT 15 +#define NV30_FP_REG_SWZ_W_MASK (3 << 15) +# define NV30_FP_SWIZZLE_X 0 +# define NV30_FP_SWIZZLE_Y 1 +# define NV30_FP_SWIZZLE_Z 2 +# define NV30_FP_SWIZZLE_W 3 +#define NV30_FP_REG_NEGATE (1 << 17) + +#define NV30SR_NONE 0 +#define NV30SR_OUTPUT 1 +#define NV30SR_INPUT 2 +#define NV30SR_TEMP 3 +#define NV30SR_CONST 4 + +struct nv30_sreg { + int type; + int index; + + int dst_scale; + + int negate; + int abs; + int swz[4]; + + int cc_update; + int cc_update_reg; + int cc_test; + int cc_test_reg; + int cc_swz[4]; +}; + +static INLINE struct nv30_sreg +nv30_sr(int type, int index) +{ + struct nv30_sreg temp = { + .type = type, + .index = index, + .dst_scale = DEF_SCALE, + .abs = 0, + .negate = 0, + .swz = { 0, 1, 2, 3 }, + .cc_update = 0, + .cc_update_reg = 0, + .cc_test = DEF_CTEST, + .cc_test_reg = 0, + .cc_swz = { 0, 1, 2, 3 }, + }; + return temp; +} + +static INLINE struct nv30_sreg +nv30_sr_swz(struct nv30_sreg src, int x, int y, int z, int w) +{ + struct nv30_sreg dst = src; + + dst.swz[SWZ_X] = src.swz[x]; + dst.swz[SWZ_Y] = src.swz[y]; + dst.swz[SWZ_Z] = src.swz[z]; + dst.swz[SWZ_W] = src.swz[w]; + return dst; +} + +static INLINE struct nv30_sreg +nv30_sr_neg(struct nv30_sreg src) +{ + src.negate = !src.negate; + return src; +} + +static INLINE struct nv30_sreg +nv30_sr_abs(struct nv30_sreg src) +{ + src.abs = 1; + return src; +} + +static INLINE struct nv30_sreg +nv30_sr_scale(struct nv30_sreg src, int scale) +{ + src.dst_scale = scale; + return src; +} + +#endif diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c new file mode 100644 index 00000000000..84f016eeadc --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -0,0 +1,774 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" + +#include "nv30_context.h" +#include "nv30_state.h" + +static void * +nv30_blend_state_create(struct pipe_context *pipe, + const struct pipe_blend_state *cso) +{ + struct nv30_blend_state *cb; + + cb = malloc(sizeof(struct nv30_blend_state)); + + cb->b_enable = cso->blend_enable ? 1 : 0; + cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | + (nvgl_blend_func(cso->rgb_src_factor))); + cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) | + (nvgl_blend_func(cso->rgb_dst_factor))); + cb->b_eqn = ((nvgl_blend_eqn(cso->alpha_func) << 16) | + (nvgl_blend_eqn(cso->rgb_func))); + + cb->l_enable = cso->logicop_enable ? 1 : 0; + cb->l_op = nvgl_logicop_func(cso->logicop_func); + + cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) | + ((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) | + ((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) | + ((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0)); + + cb->d_enable = cso->dither ? 1 : 0; + + return (void *)cb; +} + +static void +nv30_blend_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_blend_state *cb = hwcso; + + if (!hwcso) { + return; + } + + BEGIN_RING(rankine, NV34TCL_DITHER_ENABLE, 1); + OUT_RING (cb->d_enable); + + BEGIN_RING(rankine, NV34TCL_BLEND_FUNC_ENABLE, 3); + OUT_RING (cb->b_enable); + OUT_RING (cb->b_srcfunc); + OUT_RING (cb->b_dstfunc); + BEGIN_RING(rankine, NV34TCL_BLEND_EQUATION, 1); + OUT_RING (cb->b_eqn); + + BEGIN_RING(rankine, NV34TCL_COLOR_MASK, 1); + OUT_RING (cb->c_mask); + + BEGIN_RING(rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2); + OUT_RING (cb->l_enable); + OUT_RING (cb->l_op); +} + +static void +nv30_blend_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + + +static INLINE unsigned +wrap_mode(unsigned wrap) { + unsigned ret; + + switch (wrap) { + case PIPE_TEX_WRAP_REPEAT: + ret = NV34TCL_TX_WRAP_S_REPEAT; + break; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + ret = NV34TCL_TX_WRAP_S_MIRRORED_REPEAT; + break; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + ret = NV34TCL_TX_WRAP_S_CLAMP_TO_EDGE; + break; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + ret = NV34TCL_TX_WRAP_S_CLAMP_TO_BORDER; + break; + case PIPE_TEX_WRAP_CLAMP: + ret = NV34TCL_TX_WRAP_S_CLAMP; + break; +/* case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP_TO_EDGE; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP_TO_BORDER; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP; + break;*/ + default: + NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); + ret = NV34TCL_TX_WRAP_S_REPEAT; + break; + } + + return ret >> NV34TCL_TX_WRAP_S_SHIFT; +} + +static void * +nv30_sampler_state_create(struct pipe_context *pipe, + const struct pipe_sampler_state *cso) +{ + struct nv30_sampler_state *ps; + uint32_t filter = 0; + + ps = malloc(sizeof(struct nv30_sampler_state)); + + ps->fmt = 0; + if (!cso->normalized_coords) + ps->fmt |= NV34TCL_TX_FORMAT_RECT; + + ps->wrap = ((wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) | + (wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) | + (wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT)); + + ps->en = 0; + if (cso->max_anisotropy >= 2.0) { + /* no idea, binary driver sets it, works without it.. meh.. */ + ps->wrap |= (1 << 5); + +/* if (cso->max_anisotropy >= 16.0) { + ps->en |= NV34TCL_TX_ENABLE_ANISO_16X; + } else + if (cso->max_anisotropy >= 12.0) { + ps->en |= NV34TCL_TX_ENABLE_ANISO_12X; + } else + if (cso->max_anisotropy >= 10.0) { + ps->en |= NV34TCL_TX_ENABLE_ANISO_10X; + } else + if (cso->max_anisotropy >= 8.0) { + ps->en |= NV34TCL_TX_ENABLE_ANISO_8X; + } else + if (cso->max_anisotropy >= 6.0) { + ps->en |= NV34TCL_TX_ENABLE_ANISO_6X; + } else + if (cso->max_anisotropy >= 4.0) { + ps->en |= NV34TCL_TX_ENABLE_ANISO_4X; + } else { + ps->en |= NV34TCL_TX_ENABLE_ANISO_2X; + }*/ + } + + switch (cso->mag_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + filter |= NV34TCL_TX_FILTER_MAGNIFY_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + filter |= NV34TCL_TX_FILTER_MAGNIFY_NEAREST; + break; + } + + switch (cso->min_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR; + break; + } + break; + case PIPE_TEX_FILTER_NEAREST: + default: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST; + break; + } + break; + } + + ps->filt = filter; + +/* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + switch (cso->compare_func) { + case PIPE_FUNC_NEVER: + ps->wrap |= NV34TCL_TX_WRAP_RCOMP_NEVER; + break; + case PIPE_FUNC_GREATER: + ps->wrap |= NV34TCL_TX_WRAP_RCOMP_GREATER; + break; + case PIPE_FUNC_EQUAL: + ps->wrap |= NV34TCL_TX_WRAP_RCOMP_EQUAL; + break; + case PIPE_FUNC_GEQUAL: + ps->wrap |= NV34TCL_TX_WRAP_RCOMP_GEQUAL; + break; + case PIPE_FUNC_LESS: + ps->wrap |= NV34TCL_TX_WRAP_RCOMP_LESS; + break; + case PIPE_FUNC_NOTEQUAL: + ps->wrap |= NV34TCL_TX_WRAP_RCOMP_NOTEQUAL; + break; + case PIPE_FUNC_LEQUAL: + ps->wrap |= NV34TCL_TX_WRAP_RCOMP_LEQUAL; + break; + case PIPE_FUNC_ALWAYS: + ps->wrap |= NV34TCL_TX_WRAP_RCOMP_ALWAYS; + break; + default: + break; + } + }*/ + + ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) | + (float_to_ubyte(cso->border_color[0]) << 16) | + (float_to_ubyte(cso->border_color[1]) << 8) | + (float_to_ubyte(cso->border_color[2]) << 0)); + + return (void *)ps; +} + +static void +nv30_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) +{ + struct nv30_context *nv30 = nv30_context(pipe); + unsigned unit; + + if (!sampler) { + return; + } + + for (unit = 0; unit < nr; unit++) { + nv30->tex_sampler[unit] = sampler[unit]; + nv30->dirty_samplers |= (1 << unit); + } +} + +static void +nv30_sampler_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void +nv30_set_sampler_texture(struct pipe_context *pipe, unsigned nr, + struct pipe_texture **miptree) +{ + struct nv30_context *nv30 = nv30_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nv30->tex_miptree[unit] = (struct nv30_miptree *)miptree[unit]; + nv30->dirty_samplers |= (1 << unit); + } +} + +static void * +nv30_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + struct nv30_rasterizer_state *rs; + int i; + + /*XXX: ignored: + * light_twoside + * offset_cw/ccw -nohw + * scissor + * point_smooth -nohw + * multisample + * offset_units / offset_scale + */ + rs = malloc(sizeof(struct nv30_rasterizer_state)); + + rs->shade_model = cso->flatshade ? 0x1d00 : 0x1d01; + + rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff; + rs->line_smooth_en = cso->line_smooth ? 1 : 0; + rs->line_stipple_en = cso->line_stipple_enable ? 1 : 0; + rs->line_stipple = (cso->line_stipple_pattern << 16) | + cso->line_stipple_factor; + + rs->point_size = *(uint32_t*)&cso->point_size; + + rs->poly_smooth_en = cso->poly_smooth ? 1 : 0; + rs->poly_stipple_en = cso->poly_stipple_enable ? 1 : 0; + + if (cso->front_winding == PIPE_WINDING_CCW) { + rs->front_face = NV34TCL_FRONT_FACE_CCW; + rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw); + rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw); + } else { + rs->front_face = NV34TCL_FRONT_FACE_CW; + rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw); + rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw); + } + + switch (cso->cull_mode) { + case PIPE_WINDING_CCW: + rs->cull_face_en = 1; + if (cso->front_winding == PIPE_WINDING_CCW) + rs->cull_face = NV34TCL_CULL_FACE_FRONT; + else + rs->cull_face = NV34TCL_CULL_FACE_BACK; + break; + case PIPE_WINDING_CW: + rs->cull_face_en = 1; + if (cso->front_winding == PIPE_WINDING_CW) + rs->cull_face = NV34TCL_CULL_FACE_FRONT; + else + rs->cull_face = NV34TCL_CULL_FACE_BACK; + break; + case PIPE_WINDING_BOTH: + rs->cull_face_en = 1; + rs->cull_face = NV34TCL_CULL_FACE_FRONT_AND_BACK; + break; + case PIPE_WINDING_NONE: + default: + rs->cull_face_en = 0; + rs->cull_face = 0; + break; + } + + if (cso->point_sprite) { + rs->point_sprite = (1 << 0); + for (i = 0; i < 8; i++) { + if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE) + rs->point_sprite |= (1 << (8 + i)); + } + } else { + rs->point_sprite = 0; + } + + return (void *)rs; +} + +static void +nv30_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_rasterizer_state *rs = hwcso; + + if (!hwcso) { + return; + } + + BEGIN_RING(rankine, NV34TCL_SHADE_MODEL, 1); + OUT_RING (rs->shade_model); + + BEGIN_RING(rankine, NV34TCL_LINE_WIDTH, 2); + OUT_RING (rs->line_width); + OUT_RING (rs->line_smooth_en); + BEGIN_RING(rankine, NV34TCL_LINE_STIPPLE_ENABLE, 2); + OUT_RING (rs->line_stipple_en); + OUT_RING (rs->line_stipple); + + BEGIN_RING(rankine, NV34TCL_POINT_SIZE, 1); + OUT_RING (rs->point_size); + + BEGIN_RING(rankine, NV34TCL_POLYGON_MODE_FRONT, 6); + OUT_RING (rs->poly_mode_front); + OUT_RING (rs->poly_mode_back); + OUT_RING (rs->cull_face); + OUT_RING (rs->front_face); + OUT_RING (rs->poly_smooth_en); + OUT_RING (rs->cull_face_en); + + BEGIN_RING(rankine, NV34TCL_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING (rs->poly_stipple_en); + + BEGIN_RING(rankine, NV34TCL_POINT_SPRITE, 1); + OUT_RING (rs->point_sprite); +} + +static void +nv30_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void +nv30_translate_stencil(const struct pipe_depth_stencil_alpha_state *cso, + unsigned idx, struct nv30_stencil_push *hw) +{ + hw->enable = cso->stencil[idx].enabled ? 1 : 0; + hw->wmask = cso->stencil[idx].write_mask; + hw->func = nvgl_comparison_op(cso->stencil[idx].func); + hw->ref = cso->stencil[idx].ref_value; + hw->vmask = cso->stencil[idx].value_mask; + hw->fail = nvgl_stencil_op(cso->stencil[idx].fail_op); + hw->zfail = nvgl_stencil_op(cso->stencil[idx].zfail_op); + hw->zpass = nvgl_stencil_op(cso->stencil[idx].zpass_op); +} + +static void * +nv30_depth_stencil_alpha_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) +{ + struct nv30_depth_stencil_alpha_state *hw; + + hw = malloc(sizeof(struct nv30_depth_stencil_alpha_state)); + + hw->depth.func = nvgl_comparison_op(cso->depth.func); + hw->depth.write_enable = cso->depth.writemask ? 1 : 0; + hw->depth.test_enable = cso->depth.enabled ? 1 : 0; + + nv30_translate_stencil(cso, 0, &hw->stencil.front); + nv30_translate_stencil(cso, 1, &hw->stencil.back); + + hw->alpha.enabled = cso->alpha.enabled ? 1 : 0; + hw->alpha.func = nvgl_comparison_op(cso->alpha.func); + hw->alpha.ref = float_to_ubyte(cso->alpha.ref); + + return (void *)hw; +} + +static void +nv30_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_depth_stencil_alpha_state *hw = hwcso; + + if (!hwcso) { + return; + } + + BEGIN_RING(rankine, NV34TCL_DEPTH_FUNC, 3); + OUT_RINGp ((uint32_t *)&hw->depth, 3); + BEGIN_RING(rankine, NV34TCL_STENCIL_BACK_ENABLE, 16); + OUT_RINGp ((uint32_t *)&hw->stencil.back, 8); + OUT_RINGp ((uint32_t *)&hw->stencil.front, 8); + BEGIN_RING(rankine, NV34TCL_ALPHA_FUNC_ENABLE, 3); + OUT_RINGp ((uint32_t *)&hw->alpha.enabled, 3); +} + +static void +nv30_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void * +nv30_vp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv30_vertex_program *vp; + + vp = CALLOC(1, sizeof(struct nv30_vertex_program)); + vp->pipe = *cso; + + return (void *)vp; +} + +static void +nv30_vp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_vertex_program *vp = hwcso; + + if (!hwcso) { + return; + } + + nv30->vertprog.current = vp; + nv30->dirty |= NV30_NEW_VERTPROG; +} + +static void +nv30_vp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_vertex_program *vp = hwcso; + + nv30_vertprog_destroy(nv30, vp); + FREE(vp); +} + +static void * +nv30_fp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv30_fragment_program *fp; + + fp = CALLOC(1, sizeof(struct nv30_fragment_program)); + fp->pipe = *cso; + + return (void *)fp; +} + +static void +nv30_fp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_fragment_program *fp = hwcso; + + if (!hwcso) { + return; + } + + nv30->fragprog.current = fp; + nv30->dirty |= NV30_NEW_FRAGPROG; +} + +static void +nv30_fp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_fragment_program *fp = hwcso; + + nv30_fragprog_destroy(nv30, fp); + FREE(fp); +} + +static void +nv30_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *bcol) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + BEGIN_RING(rankine, NV34TCL_BLEND_COLOR, 1); + OUT_RING ((float_to_ubyte(bcol->color[3]) << 24) | + (float_to_ubyte(bcol->color[0]) << 16) | + (float_to_ubyte(bcol->color[1]) << 8) | + (float_to_ubyte(bcol->color[2]) << 0)); +} + +static void +nv30_set_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *clip) +{ +} + +static void +nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + const struct pipe_constant_buffer *buf ) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + if (shader == PIPE_SHADER_VERTEX) { + nv30->vertprog.constant_buf = buf->buffer; + nv30->dirty |= NV30_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nv30->fragprog.constant_buf = buf->buffer; + nv30->dirty |= NV30_NEW_FRAGPROG; + } +} + +static void +nv30_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct pipe_surface *rt[2], *zeta = NULL; + uint32_t rt_enable, rt_format, w = 0, h = 0; + int i, colour_format = 0, zeta_format = 0; + + rt_enable = 0; + for (i = 0; i < 2; i++) { + if (!fb->cbufs[i]) + continue; + + if (colour_format) { + assert(w == fb->cbufs[i]->width); + assert(h == fb->cbufs[i]->height); + assert(colour_format == fb->cbufs[i]->format); + } else { + w = fb->cbufs[i]->width; + h = fb->cbufs[i]->height; + colour_format = fb->cbufs[i]->format; + rt_enable |= (NV34TCL_RT_ENABLE_COLOR0 << i); + rt[i] = fb->cbufs[i]; + } + } + + if (rt_enable & (NV34TCL_RT_ENABLE_COLOR1 | NV34TCL_RT_ENABLE_COLOR2 | + NV34TCL_RT_ENABLE_COLOR3)) + rt_enable |= NV34TCL_RT_ENABLE_MRT; + + if (fb->zsbuf) { + if (colour_format) { + assert(w == fb->zsbuf->width); + assert(h == fb->zsbuf->height); + } else { + w = fb->zsbuf->width; + h = fb->zsbuf->height; + } + + zeta_format = fb->zsbuf->format; + zeta = fb->zsbuf; + } + + rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR; + + switch (colour_format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case 0: + rt_format |= NV34TCL_RT_FORMAT_COLOR_A8R8G8B8; + break; + case PIPE_FORMAT_R5G6B5_UNORM: + rt_format |= NV34TCL_RT_FORMAT_COLOR_R5G6B5; + break; + default: + assert(0); + } + + switch (zeta_format) { + case PIPE_FORMAT_Z16_UNORM: + rt_format |= NV34TCL_RT_FORMAT_ZETA_Z16; + break; + case PIPE_FORMAT_Z24S8_UNORM: + case 0: + rt_format |= NV34TCL_RT_FORMAT_ZETA_Z24S8; + break; + default: + assert(0); + } + + if (rt_enable & NV34TCL_RT_ENABLE_COLOR0) { + uint32_t pitch = rt[0]->pitch * rt[0]->cpp; + if (zeta) { + pitch |= (zeta->pitch * zeta->cpp)<<16; + } else { + pitch |= pitch<<16; + } + + BEGIN_RING(rankine, NV34TCL_COLOR0_PITCH, 1); + OUT_RING ( pitch ); + nv30->rt[0] = rt[0]->buffer; + } + + if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) { + BEGIN_RING(rankine, NV34TCL_COLOR1_PITCH, 1); + OUT_RING (rt[1]->pitch * rt[1]->cpp); + nv30->rt[1] = rt[1]->buffer; + } + + if (zeta_format) + { + nv30->zeta = zeta->buffer; + } + + nv30->rt_enable = rt_enable; + BEGIN_RING(rankine, NV34TCL_RT_ENABLE, 1); + OUT_RING (rt_enable); + BEGIN_RING(rankine, NV34TCL_RT_HORIZ, 3); + OUT_RING ((w << 16) | 0); + OUT_RING ((h << 16) | 0); + OUT_RING (rt_format); + BEGIN_RING(rankine, NV34TCL_VIEWPORT_HORIZ, 2); + OUT_RING ((w << 16) | 0); + OUT_RING ((h << 16) | 0); + BEGIN_RING(rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2); + OUT_RING (((w - 1) << 16) | 0); + OUT_RING (((h - 1) << 16) | 0); + BEGIN_RING(rankine, NV34TCL_VIEWPORT_TX_ORIGIN, 1); + OUT_RING (0); +} + +static void +nv30_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + BEGIN_RING(rankine, NV34TCL_POLYGON_STIPPLE_PATTERN(0), 32); + OUT_RINGp ((uint32_t *)stipple->stipple, 32); +} + +static void +nv30_set_scissor_state(struct pipe_context *pipe, + const struct pipe_scissor_state *s) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + BEGIN_RING(rankine, NV34TCL_SCISSOR_HORIZ, 2); + OUT_RING (((s->maxx - s->minx) << 16) | s->minx); + OUT_RING (((s->maxy - s->miny) << 16) | s->miny); +} + +static void +nv30_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *vpt) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + BEGIN_RING(rankine, NV34TCL_VIEWPORT_TRANSLATE_X, 8); + OUT_RINGf (vpt->translate[0]); + OUT_RINGf (vpt->translate[1]); + OUT_RINGf (vpt->translate[2]); + OUT_RINGf (vpt->translate[3]); + OUT_RINGf (vpt->scale[0]); + OUT_RINGf (vpt->scale[1]); + OUT_RINGf (vpt->scale[2]); + OUT_RINGf (vpt->scale[3]); +} + +static void +nv30_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *vb) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + memcpy(nv30->vtxbuf, vb, sizeof(*vb) * count); + nv30->dirty |= NV30_NEW_ARRAYS; +} + +static void +nv30_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *ve) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + memcpy(nv30->vtxelt, ve, sizeof(*ve) * count); + nv30->dirty |= NV30_NEW_ARRAYS; +} + +void +nv30_init_state_functions(struct nv30_context *nv30) +{ + nv30->pipe.create_blend_state = nv30_blend_state_create; + nv30->pipe.bind_blend_state = nv30_blend_state_bind; + nv30->pipe.delete_blend_state = nv30_blend_state_delete; + + nv30->pipe.create_sampler_state = nv30_sampler_state_create; + nv30->pipe.bind_sampler_states = nv30_sampler_state_bind; + nv30->pipe.delete_sampler_state = nv30_sampler_state_delete; + nv30->pipe.set_sampler_textures = nv30_set_sampler_texture; + + nv30->pipe.create_rasterizer_state = nv30_rasterizer_state_create; + nv30->pipe.bind_rasterizer_state = nv30_rasterizer_state_bind; + nv30->pipe.delete_rasterizer_state = nv30_rasterizer_state_delete; + + nv30->pipe.create_depth_stencil_alpha_state = + nv30_depth_stencil_alpha_state_create; + nv30->pipe.bind_depth_stencil_alpha_state = + nv30_depth_stencil_alpha_state_bind; + nv30->pipe.delete_depth_stencil_alpha_state = + nv30_depth_stencil_alpha_state_delete; + + nv30->pipe.create_vs_state = nv30_vp_state_create; + nv30->pipe.bind_vs_state = nv30_vp_state_bind; + nv30->pipe.delete_vs_state = nv30_vp_state_delete; + + nv30->pipe.create_fs_state = nv30_fp_state_create; + nv30->pipe.bind_fs_state = nv30_fp_state_bind; + nv30->pipe.delete_fs_state = nv30_fp_state_delete; + + nv30->pipe.set_blend_color = nv30_set_blend_color; + nv30->pipe.set_clip_state = nv30_set_clip_state; + nv30->pipe.set_constant_buffer = nv30_set_constant_buffer; + nv30->pipe.set_framebuffer_state = nv30_set_framebuffer_state; + nv30->pipe.set_polygon_stipple = nv30_set_polygon_stipple; + nv30->pipe.set_scissor_state = nv30_set_scissor_state; + nv30->pipe.set_viewport_state = nv30_set_viewport_state; + + nv30->pipe.set_vertex_buffers = nv30_set_vertex_buffers; + nv30->pipe.set_vertex_elements = nv30_set_vertex_elements; +} + diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h new file mode 100644 index 00000000000..117520dd13c --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state.h @@ -0,0 +1,147 @@ +#ifndef __NV30_STATE_H__ +#define __NV30_STATE_H__ + +#include "pipe/p_state.h" + +struct nv30_blend_state { + uint32_t b_enable; + uint32_t b_srcfunc; + uint32_t b_dstfunc; + uint32_t b_eqn; + + uint32_t l_enable; + uint32_t l_op; + + uint32_t c_mask; + + uint32_t d_enable; +}; + +struct nv30_sampler_state { + uint32_t fmt; + uint32_t wrap; + uint32_t en; + uint32_t filt; + uint32_t bcol; +}; + +struct nv30_rasterizer_state { + uint32_t shade_model; + + uint32_t line_width; + uint32_t line_smooth_en; + uint32_t line_stipple_en; + uint32_t line_stipple; + + uint32_t point_size; + + uint32_t poly_smooth_en; + uint32_t poly_stipple_en; + + uint32_t poly_mode_front; + uint32_t poly_mode_back; + + uint32_t front_face; + uint32_t cull_face; + uint32_t cull_face_en; + + uint32_t point_sprite; +}; + +struct nv30_vertex_program_exec { + uint32_t data[4]; + boolean has_branch_offset; + int const_index; +}; + +struct nv30_vertex_program_data { + int index; /* immediates == -1 */ + float value[4]; +}; + +struct nv30_vertex_program { + struct pipe_shader_state pipe; + + boolean translated; + struct nv30_vertex_program_exec *insns; + unsigned nr_insns; + struct nv30_vertex_program_data *consts; + unsigned nr_consts; + + struct nouveau_resource *exec; + unsigned exec_start; + struct nouveau_resource *data; + unsigned data_start; + unsigned data_start_min; + + uint32_t ir; + uint32_t or; +}; + +struct nv30_fragment_program_data { + unsigned offset; + unsigned index; +}; + +struct nv30_fragment_program { + struct pipe_shader_state pipe; + + boolean translated; + boolean on_hw; + unsigned samplers; + + uint32_t *insn; + int insn_len; + + struct nv30_fragment_program_data *consts; + unsigned nr_consts; + + struct pipe_buffer *buffer; + + uint32_t fp_control; + uint32_t fp_reg_control; +}; + +struct nv30_stencil_push { + uint32_t enable; + uint32_t wmask; + uint32_t func; + uint32_t ref; + uint32_t vmask; + uint32_t fail; + uint32_t zfail; + uint32_t zpass; +}; + +struct nv30_depth_stencil_alpha_state { + struct { + uint32_t func; + uint32_t write_enable; + uint32_t test_enable; + } depth; + + struct { + struct nv30_stencil_push back; + struct nv30_stencil_push front; + } stencil; + + struct { + uint32_t enabled; + uint32_t func; + uint32_t ref; + } alpha; +}; + +struct nv30_miptree { + struct pipe_texture base; + + struct pipe_buffer *buffer; + uint total_size; + + struct { + uint pitch; + uint *image_offset; + } level[PIPE_MAX_TEXTURE_LEVELS]; +}; + +#endif diff --git a/src/gallium/drivers/nv30/nv30_state_blend.c b/src/gallium/drivers/nv30/nv30_state_blend.c new file mode 100644 index 00000000000..a1b0100472d --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state_blend.c @@ -0,0 +1,40 @@ +#include "nv30_context.h" + +static boolean +nv30_state_blend_validate(struct nv30_context *nv30) +{ + so_ref(nv30->blend->so, &nv30->state.hw[NV30_STATE_BLEND]); + return TRUE; +} + +struct nv30_state_entry nv30_state_blend_new = { + .validate = nv30_state_blend_validate, + .dirty = { + .pipe = NV30_NEW_BLEND, + .hw = NV30_STATE_BLEND + } +}; + +static boolean +nv30_state_blend_colour_validate(struct nv30_context *nv30) +{ + struct nouveau_stateobj *so = so_new(2, 0); + struct pipe_blend_color *bcol = &nv30->blend_colour; + + so_method(so, nv30->screen->rankine, NV34TCL_BLEND_COLOR, 1); + so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) | + (float_to_ubyte(bcol->color[0]) << 16) | + (float_to_ubyte(bcol->color[1]) << 8) | + (float_to_ubyte(bcol->color[2]) << 0))); + + so_ref(so, &nv30->state.hw[NV30_STATE_BCOL]); + return TRUE; +} + +struct nv30_state_entry nv30_state_blend_colour = { + .validate = nv30_state_blend_colour_validate, + .dirty = { + .pipe = NV30_NEW_BCOL, + .hw = NV30_STATE_BCOL + } +}; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c new file mode 100644 index 00000000000..eda2fd45f56 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -0,0 +1,85 @@ +#include "nv30_context.h" +#include "nv30_state.h" + +void +nv30_emit_hw_state(struct nv30_context *nv30) +{ + int i; + + if (nv30->dirty & NV30_NEW_FRAGPROG) { + nv30_fragprog_bind(nv30, nv30->fragprog.current); + /*XXX: clear NV30_NEW_FRAGPROG if no new program uploaded */ + } + + if (nv30->dirty_samplers || (nv30->dirty & NV30_NEW_FRAGPROG)) { + nv30_fragtex_bind(nv30); +/* + BEGIN_RING(rankine, NV34TCL_TX_CACHE_CTL, 1); + OUT_RING (2); + BEGIN_RING(rankine, NV34TCL_TX_CACHE_CTL, 1); + OUT_RING (1);*/ + nv30->dirty &= ~NV30_NEW_FRAGPROG; + } + + if (nv30->dirty & NV30_NEW_VERTPROG) { + nv30_vertprog_bind(nv30, nv30->vertprog.current); + nv30->dirty &= ~NV30_NEW_VERTPROG; + } + + nv30->dirty_samplers = 0; + + /* Emit relocs for every referenced buffer. + * This is to ensure the bufmgr has an accurate idea of how + * the buffer is used. This isn't very efficient, but we don't + * seem to take a significant performance hit. Will be improved + * at some point. Vertex arrays are emitted by nv30_vbo.c + */ + + /* Render targets */ + if (nv30->rt_enable & NV34TCL_RT_ENABLE_COLOR0) { + BEGIN_RING(rankine, NV34TCL_DMA_COLOR0, 1); + OUT_RELOCo(nv30->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(rankine, NV34TCL_COLOR0_OFFSET, 1); + OUT_RELOCl(nv30->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + } + + if (nv30->rt_enable & NV34TCL_RT_ENABLE_COLOR1) { + BEGIN_RING(rankine, NV34TCL_DMA_COLOR1, 1); + OUT_RELOCo(nv30->rt[1], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(rankine, NV34TCL_COLOR1_OFFSET, 1); + OUT_RELOCl(nv30->rt[1], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + } + + if (nv30->zeta) { + BEGIN_RING(rankine, NV34TCL_DMA_ZETA, 1); + OUT_RELOCo(nv30->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(rankine, NV34TCL_ZETA_OFFSET, 1); + OUT_RELOCl(nv30->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + /* XXX allocate LMA */ +/* BEGIN_RING(rankine, NV34TCL_LMA_DEPTH_OFFSET, 1); + OUT_RING(0);*/ + } + + /* Texture images, emitted in nv30_fragtex_build */ +#if 0 + for (i = 0; i < 16; i++) { + if (!(nv30->fp_samplers & (1 << i))) + continue; + BEGIN_RING(rankine, NV34TCL_TX_OFFSET(i), 2); + OUT_RELOCl(nv30->tex[i].buffer, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCd(nv30->tex[i].buffer, nv30->tex[i].format, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | + NOUVEAU_BO_OR, NV34TCL_TX_FORMAT_DMA0, + NV34TCL_TX_FORMAT_DMA1); + } +#endif + + /* Fragment program */ + BEGIN_RING(rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1); + OUT_RELOC (nv30->fragprog.active->buffer, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW | + NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0, + NV34TCL_FP_ACTIVE_PROGRAM_DMA1); +} + diff --git a/src/gallium/drivers/nv30/nv30_state_fb.c b/src/gallium/drivers/nv30/nv30_state_fb.c new file mode 100644 index 00000000000..73c97e298ad --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state_fb.c @@ -0,0 +1,151 @@ +#include "nv30_context.h" + +static boolean +nv30_state_framebuffer_validate(struct nv30_context *nv30) +{ + struct pipe_framebuffer_state *fb = &nv30->framebuffer; + struct pipe_surface *rt[4], *zeta = NULL; + uint32_t rt_enable, rt_format; + int i, colour_format = 0, zeta_format = 0; + struct nouveau_stateobj *so = so_new(64, 10); + unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM; + unsigned w = fb->width; + unsigned h = fb->height; + + rt_enable = 0; + for (i = 0; i < fb->num_cbufs; i++) { + if (colour_format) { + assert(colour_format == fb->cbufs[i]->format); + } else { + colour_format = fb->cbufs[i]->format; + rt_enable |= (NV34TCL_RT_ENABLE_COLOR0 << i); + rt[i] = fb->cbufs[i]; + } + } + + if (rt_enable & (NV34TCL_RT_ENABLE_COLOR1 | NV34TCL_RT_ENABLE_COLOR2 | + NV34TCL_RT_ENABLE_COLOR3)) + rt_enable |= NV34TCL_RT_ENABLE_MRT; + + if (fb->zsbuf) { + zeta_format = fb->zsbuf->format; + zeta = fb->zsbuf; + } + + rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR; + + switch (colour_format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case 0: + rt_format |= NV34TCL_RT_FORMAT_COLOR_A8R8G8B8; + break; + case PIPE_FORMAT_R5G6B5_UNORM: + rt_format |= NV34TCL_RT_FORMAT_COLOR_R5G6B5; + break; + default: + assert(0); + } + + switch (zeta_format) { + case PIPE_FORMAT_Z16_UNORM: + rt_format |= NV34TCL_RT_FORMAT_ZETA_Z16; + break; + case PIPE_FORMAT_Z24S8_UNORM: + case 0: + rt_format |= NV34TCL_RT_FORMAT_ZETA_Z24S8; + break; + default: + assert(0); + } + + if (rt_enable & NV34TCL_RT_ENABLE_COLOR0) { + uint32_t pitch = rt[0]->pitch * rt[0]->cpp; + if (zeta) { + pitch |= (zeta->pitch * zeta->cpp)<<16; + } else { + pitch |= pitch<<16; + } + + so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR0, 1); + so_reloc (so, rt[0]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv30->nvws->channel->vram->handle, + nv30->nvws->channel->gart->handle); + so_method(so, nv30->screen->rankine, NV34TCL_COLOR0_PITCH, 2); + so_data (so, pitch); + so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + } + + if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) { + so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR1, 1); + so_reloc (so, rt[1]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv30->nvws->channel->vram->handle, + nv30->nvws->channel->gart->handle); + so_method(so, nv30->screen->rankine, NV34TCL_COLOR1_OFFSET, 2); + so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_data (so, rt[1]->pitch * rt[1]->cpp); + } +/* + if (rt_enable & NV34TCL_RT_ENABLE_COLOR2) { + so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR2, 1); + so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv30->nvws->channel->vram->handle, + nv30->nvws->channel->gart->handle); + so_method(so, nv30->screen->rankine, NV34TCL_COLOR2_OFFSET, 1); + so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv30->screen->rankine, NV34TCL_COLOR2_PITCH, 1); + so_data (so, rt[2]->pitch * rt[2]->cpp); + } + + if (rt_enable & NV34TCL_RT_ENABLE_COLOR3) { + so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR3, 1); + so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv30->nvws->channel->vram->handle, + nv30->nvws->channel->gart->handle); + so_method(so, nv30->screen->rankine, NV34TCL_COLOR3_OFFSET, 1); + so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv30->screen->rankine, NV34TCL_COLOR3_PITCH, 1); + so_data (so, rt[3]->pitch * rt[3]->cpp); + } +*/ + if (zeta_format) { + so_method(so, nv30->screen->rankine, NV34TCL_DMA_ZETA, 1); + so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv30->nvws->channel->vram->handle, + nv30->nvws->channel->gart->handle); + so_method(so, nv30->screen->rankine, NV34TCL_ZETA_OFFSET, 1); + so_reloc (so, zeta->buffer, zeta->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + /*so_method(so, nv30->screen->rankine, NV34TCL_ZETA_PITCH, 1); + so_data (so, zeta->pitch * zeta->cpp);*/ + } + + so_method(so, nv30->screen->rankine, NV34TCL_RT_ENABLE, 1); + so_data (so, rt_enable); + so_method(so, nv30->screen->rankine, NV34TCL_RT_HORIZ, 3); + so_data (so, (w << 16) | 0); + so_data (so, (h << 16) | 0); + so_data (so, rt_format); + so_method(so, nv30->screen->rankine, NV34TCL_VIEWPORT_HORIZ, 2); + so_data (so, (w << 16) | 0); + so_data (so, (h << 16) | 0); + so_method(so, nv30->screen->rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2); + so_data (so, ((w - 1) << 16) | 0); + so_data (so, ((h - 1) << 16) | 0); + so_method(so, nv30->screen->rankine, 0x1d88, 1); + so_data (so, (1 << 12) | h); + + so_ref(so, &nv30->state.hw[NV30_STATE_FB]); + return TRUE; +} + +struct nv30_state_entry nv30_state_framebuffer = { + .validate = nv30_state_framebuffer_validate, + .dirty = { + .pipe = NV30_NEW_FB, + .hw = NV30_STATE_FB + } +}; diff --git a/src/gallium/drivers/nv30/nv30_state_rasterizer.c b/src/gallium/drivers/nv30/nv30_state_rasterizer.c new file mode 100644 index 00000000000..6d1b60e043d --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state_rasterizer.c @@ -0,0 +1,17 @@ +#include "nv30_context.h" + +static boolean +nv30_state_rasterizer_validate(struct nv30_context *nv30) +{ + so_ref(nv30->rasterizer->so, + &nv30->state.hw[NV30_STATE_RAST]); + return TRUE; +} + +struct nv30_state_entry nv30_state_rasterizer = { + .validate = nv30_state_rasterizer_validate, + .dirty = { + .pipe = NV30_NEW_RAST, + .hw = NV30_STATE_RAST + } +}; diff --git a/src/gallium/drivers/nv30/nv30_state_scissor.c b/src/gallium/drivers/nv30/nv30_state_scissor.c new file mode 100644 index 00000000000..1db9bc17955 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state_scissor.c @@ -0,0 +1,35 @@ +#include "nv30_context.h" + +static boolean +nv30_state_scissor_validate(struct nv30_context *nv30) +{ + struct pipe_rasterizer_state *rast = &nv30->rasterizer->pipe; + struct pipe_scissor_state *s = &nv30->scissor; + struct nouveau_stateobj *so; + + if (nv30->state.hw[NV30_STATE_SCISSOR] && + (rast->scissor == 0 && nv30->state.scissor_enabled == 0)) + return FALSE; + nv30->state.scissor_enabled = rast->scissor; + + so = so_new(3, 0); + so_method(so, nv30->screen->rankine, NV34TCL_SCISSOR_HORIZ, 2); + if (nv30->state.scissor_enabled) { + so_data (so, ((s->maxx - s->minx) << 16) | s->minx); + so_data (so, ((s->maxy - s->miny) << 16) | s->miny); + } else { + so_data (so, 4096 << 16); + so_data (so, 4096 << 16); + } + + so_ref(so, &nv30->state.hw[NV30_STATE_SCISSOR]); + return TRUE; +} + +struct nv30_state_entry nv30_state_scissor = { + .validate = nv30_state_scissor_validate, + .dirty = { + .pipe = NV30_NEW_SCISSOR | NV30_NEW_RAST, + .hw = NV30_STATE_SCISSOR + } +}; diff --git a/src/gallium/drivers/nv30/nv30_state_stipple.c b/src/gallium/drivers/nv30/nv30_state_stipple.c new file mode 100644 index 00000000000..41b42813b49 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state_stipple.c @@ -0,0 +1,39 @@ +#include "nv30_context.h" + +static boolean +nv30_state_stipple_validate(struct nv30_context *nv30) +{ + struct pipe_rasterizer_state *rast = &nv30->rasterizer->pipe; + struct nouveau_grobj *rankine = nv30->screen->rankine; + struct nouveau_stateobj *so; + + if (nv30->state.hw[NV30_STATE_STIPPLE] && + (rast->poly_stipple_enable == 0 && nv30->state.stipple_enabled == 0)) + return FALSE; + + if (rast->poly_stipple_enable) { + unsigned i; + + so = so_new(35, 0); + so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, 1); + so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_PATTERN(0), 32); + for (i = 0; i < 32; i++) + so_data(so, nv30->stipple[i]); + } else { + so = so_new(2, 0); + so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, 0); + } + + so_ref(so, &nv30->state.hw[NV30_STATE_STIPPLE]); + return TRUE; +} + +struct nv30_state_entry nv30_state_stipple = { + .validate = nv30_state_stipple_validate, + .dirty = { + .pipe = NV30_NEW_STIPPLE | NV30_NEW_RAST, + .hw = NV30_STATE_STIPPLE, + } +}; diff --git a/src/gallium/drivers/nv30/nv30_state_viewport.c b/src/gallium/drivers/nv30/nv30_state_viewport.c new file mode 100644 index 00000000000..951d40ebfdd --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state_viewport.c @@ -0,0 +1,70 @@ +#include "nv30_context.h" + +static boolean +nv30_state_viewport_validate(struct nv30_context *nv30) +{ + struct pipe_viewport_state *vpt = &nv30->viewport; + struct nouveau_stateobj *so; + unsigned bypass; + + if (/*nv30->render_mode == HW &&*/ !nv30->rasterizer->pipe.bypass_clipping) + bypass = 0; + else + bypass = 1; + + if (nv30->state.hw[NV30_STATE_VIEWPORT] && + (bypass || !(nv30->dirty & NV30_NEW_VIEWPORT)) && + nv30->state.viewport_bypass == bypass) + return FALSE; + nv30->state.viewport_bypass = bypass; + + so = so_new(11, 0); + if (!bypass) { + so_method(so, nv30->screen->rankine, + NV34TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(vpt->translate[0])); + so_data (so, fui(vpt->translate[1])); + so_data (so, fui(vpt->translate[2])); + so_data (so, fui(vpt->translate[3])); + so_data (so, fui(vpt->scale[0])); + so_data (so, fui(vpt->scale[1])); + so_data (so, fui(vpt->scale[2])); + so_data (so, fui(vpt->scale[3])); +/* so_method(so, nv30->screen->rankine, 0x1d78, 1); + so_data (so, 1); +*/ } else { + so_method(so, nv30->screen->rankine, + NV34TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(1.0)); + so_data (so, fui(1.0)); + so_data (so, fui(1.0)); + so_data (so, fui(0.0)); + /* Not entirely certain what this is yet. The DDX uses this + * value also as it fixes rendering when you pass + * pre-transformed vertices to the GPU. My best gusss is that + * this bypasses some culling/clipping stage. Might be worth + * noting that points/lines are uneffected by whatever this + * value fixes, only filled polygons are effected. + */ +/* so_method(so, nv30->screen->rankine, 0x1d78, 1); + so_data (so, 0x110); +*/ } + /* TODO/FIXME: never saw value 0x0110 in renouveau dumps, only 0x0001 */ + so_method(so, nv30->screen->rankine, 0x1d78, 1); + so_data (so, 1); + + so_ref(so, &nv30->state.hw[NV30_STATE_VIEWPORT]); + return TRUE; +} + +struct nv30_state_entry nv30_state_viewport = { + .validate = nv30_state_viewport_validate, + .dirty = { + .pipe = NV30_NEW_VIEWPORT | NV30_NEW_RAST, + .hw = NV30_STATE_VIEWPORT + } +}; diff --git a/src/gallium/drivers/nv30/nv30_state_zsa.c b/src/gallium/drivers/nv30/nv30_state_zsa.c new file mode 100644 index 00000000000..0940b7269b2 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state_zsa.c @@ -0,0 +1,17 @@ +#include "nv30_context.h" + +static boolean +nv30_state_zsa_validate(struct nv30_context *nv30) +{ + so_ref(nv30->zsa->so, + &nv30->state.hw[NV30_STATE_ZSA]); + return TRUE; +} + +struct nv30_state_entry nv30_state_zsa = { + .validate = nv30_state_zsa_validate, + .dirty = { + .pipe = NV30_NEW_ZSA, + .hw = NV30_STATE_ZSA + } +}; diff --git a/src/gallium/drivers/nv30/nv30_surface.c b/src/gallium/drivers/nv30/nv30_surface.c new file mode 100644 index 00000000000..b22211ac86e --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_surface.c @@ -0,0 +1,77 @@ + +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#include "nv30_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_inlines.h" +#include "util/p_tile.h" + +static void +nv30_surface_copy(struct pipe_context *pipe, unsigned do_flip, + struct pipe_surface *dest, unsigned destx, unsigned desty, + struct pipe_surface *src, unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nouveau_winsys *nvws = nv30->nvws; + + if (do_flip) { + /*XXX: This dodgyness will do for now for correctness. But, + * need to investigate whether the 2D engine is able to + * manage a flip (perhaps SIFM?), if not, use the 3D engine + */ + desty += height; + while (height--) { + nvws->surface_copy(nvws, dest, destx, desty--, src, + srcx, srcy++, width, 1); + } + } else { + nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, + width, height); + } +} + +static void +nv30_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, + unsigned destx, unsigned desty, unsigned width, + unsigned height, unsigned value) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nouveau_winsys *nvws = nv30->nvws; + + nvws->surface_fill(nvws, dest, destx, desty, width, height, value); +} + +void +nv30_init_surface_functions(struct nv30_context *nv30) +{ + nv30->pipe.surface_copy = nv30_surface_copy; + nv30->pipe.surface_fill = nv30_surface_fill; +} diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c new file mode 100644 index 00000000000..359e443bb1c --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -0,0 +1,425 @@ +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "nv30_context.h" +#include "nv30_state.h" + +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_pushbuf.h" + +static INLINE int +nv30_vbo_ncomp(uint format) +{ + int ncomp = 0; + + if (pf_size_x(format)) ncomp++; + if (pf_size_y(format)) ncomp++; + if (pf_size_z(format)) ncomp++; + if (pf_size_w(format)) ncomp++; + + return ncomp; +} + +static INLINE int +nv30_vbo_type(uint format) +{ + switch (pf_type(format)) { + case PIPE_FORMAT_TYPE_FLOAT: + return NV34TCL_VTXFMT_TYPE_FLOAT; + case PIPE_FORMAT_TYPE_UNORM: + return NV34TCL_VTXFMT_TYPE_UBYTE; + default: + NOUVEAU_ERR("Unknown format 0x%08x\n", format); + return NV34TCL_VTXFMT_TYPE_FLOAT; + } +} + +static boolean +nv30_vbo_static_attrib(struct nv30_context *nv30, int attrib, + struct pipe_vertex_element *ve, + struct pipe_vertex_buffer *vb) +{ + struct pipe_winsys *ws = nv30->pipe.winsys; + int type, ncomp; + void *map; + + type = nv30_vbo_type(ve->src_format); + ncomp = nv30_vbo_ncomp(ve->src_format); + + map = ws->buffer_map(ws, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); + map += vb->buffer_offset + ve->src_offset; + + switch (type) { + case NV34TCL_VTXFMT_TYPE_FLOAT: + { + float *v = map; + + BEGIN_RING(rankine, NV34TCL_VTX_ATTR_4F_X(attrib), 4); + switch (ncomp) { + case 4: + OUT_RINGf(v[0]); + OUT_RINGf(v[1]); + OUT_RINGf(v[2]); + OUT_RINGf(v[3]); + break; + case 3: + OUT_RINGf(v[0]); + OUT_RINGf(v[1]); + OUT_RINGf(v[2]); + OUT_RINGf(1.0); + break; + case 2: + OUT_RINGf(v[0]); + OUT_RINGf(v[1]); + OUT_RINGf(0.0); + OUT_RINGf(1.0); + break; + case 1: + OUT_RINGf(v[0]); + OUT_RINGf(0.0); + OUT_RINGf(0.0); + OUT_RINGf(1.0); + break; + default: + ws->buffer_unmap(ws, vb->buffer); + return FALSE; + } + } + break; + default: + ws->buffer_unmap(ws, vb->buffer); + return FALSE; + } + + ws->buffer_unmap(ws, vb->buffer); + + return TRUE; +} + +static void +nv30_vbo_arrays_update(struct nv30_context *nv30) +{ + struct nv30_vertex_program *vp = nv30->vertprog.active; + uint32_t inputs, vtxfmt[16]; + int hw, num_hw = 0; + + nv30->vb_enable = 0; + + inputs = vp->ir; + for (hw = 0; hw < 16 && inputs; hw++) { + if (inputs & (1 << hw)) { + num_hw = hw; + inputs &= ~(1 << hw); + } + } + num_hw++; + + inputs = vp->ir; + for (hw = 0; hw < num_hw; hw++) { + struct pipe_vertex_element *ve; + struct pipe_vertex_buffer *vb; + + if (!(inputs & (1 << hw))) { + vtxfmt[hw] = NV34TCL_VTXFMT_TYPE_FLOAT; + continue; + } + + ve = &nv30->vtxelt[hw]; + vb = &nv30->vtxbuf[ve->vertex_buffer_index]; + + if (vb->pitch == 0) { + vtxfmt[hw] = NV34TCL_VTXFMT_TYPE_FLOAT; + if (nv30_vbo_static_attrib(nv30, hw, ve, vb) == TRUE) + continue; + } + + nv30->vb_enable |= (1 << hw); + nv30->vb[hw].delta = vb->buffer_offset + ve->src_offset; + nv30->vb[hw].buffer = vb->buffer; + + vtxfmt[hw] = ((vb->pitch << NV34TCL_VTXFMT_STRIDE_SHIFT) | + (nv30_vbo_ncomp(ve->src_format) << + NV34TCL_VTXFMT_SIZE_SHIFT) | + nv30_vbo_type(ve->src_format)); + } + + BEGIN_RING(rankine, NV34TCL_VTXFMT(0), num_hw); + OUT_RINGp (vtxfmt, num_hw); +} + +static boolean +nv30_vbo_validate_state(struct nv30_context *nv30, + struct pipe_buffer *ib, unsigned ib_format) +{ + unsigned inputs; + + nv30_emit_hw_state(nv30); + + if (nv30->dirty & NV30_NEW_ARRAYS) { + nv30_vbo_arrays_update(nv30); + nv30->dirty &= ~NV30_NEW_ARRAYS; + } + + inputs = nv30->vb_enable; + while (inputs) { + unsigned a = ffs(inputs) - 1; + + inputs &= ~(1 << a); + + BEGIN_RING(rankine, NV34TCL_VTXBUF_ADDRESS(a), 1); + OUT_RELOC (nv30->vb[a].buffer, nv30->vb[a].delta, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_LOW | + NOUVEAU_BO_OR | NOUVEAU_BO_RD, 0, + NV34TCL_VTXBUF_ADDRESS_DMA1); + } + + if (ib) { + BEGIN_RING(rankine, NV34TCL_IDXBUF_ADDRESS, 2); + OUT_RELOCl(ib, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | + NOUVEAU_BO_RD); + OUT_RELOCd(ib, ib_format, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | + NOUVEAU_BO_RD | NOUVEAU_BO_OR, + 0, NV34TCL_IDXBUF_FORMAT_DMA1); + } + + BEGIN_RING(rankine, 0x1710, 1); + OUT_RING (0); /* vtx cache flush */ + + return TRUE; +} + +boolean +nv30_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, + unsigned count) +{ + struct nv30_context *nv30 = nv30_context(pipe); + unsigned nr; + boolean ret; + + ret = nv30_vbo_validate_state(nv30, NULL, 0); + if (!ret) { + NOUVEAU_ERR("state validate failed\n"); + return FALSE; + } + + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + nr = (count & 0xff); + if (nr) { + BEGIN_RING(rankine, NV34TCL_VB_VERTEX_BATCH, 1); + OUT_RING (((nr - 1) << 24) | start); + start += nr; + } + + nr = count >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; + + nr -= push; + + BEGIN_RING_NI(rankine, NV34TCL_VB_VERTEX_BATCH, push); + while (push--) { + OUT_RING(((0x100 - 1) << 24) | start); + start += 0x100; + } + } + + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (0); + + pipe->flush(pipe, 0, NULL); + return TRUE; +} + +static INLINE void +nv30_draw_elements_u08(struct nv30_context *nv30, void *ib, + unsigned start, unsigned count) +{ + uint8_t *elts = (uint8_t *)ib + start; + int push, i; + + if (count & 1) { + BEGIN_RING(rankine, NV34TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; count--; + } + + while (count) { + push = MIN2(count, 2047 * 2); + + BEGIN_RING_NI(rankine, NV34TCL_VB_ELEMENT_U16, push >> 1); + for (i = 0; i < push; i+=2) + OUT_RING((elts[i+1] << 16) | elts[i]); + + count -= push; + elts += push; + } +} + +static INLINE void +nv30_draw_elements_u16(struct nv30_context *nv30, void *ib, + unsigned start, unsigned count) +{ + uint16_t *elts = (uint16_t *)ib + start; + int push, i; + + if (count & 1) { + BEGIN_RING(rankine, NV34TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; count--; + } + + while (count) { + push = MIN2(count, 2047 * 2); + + BEGIN_RING_NI(rankine, NV34TCL_VB_ELEMENT_U16, push >> 1); + for (i = 0; i < push; i+=2) + OUT_RING((elts[i+1] << 16) | elts[i]); + + count -= push; + elts += push; + } +} + +static INLINE void +nv30_draw_elements_u32(struct nv30_context *nv30, void *ib, + unsigned start, unsigned count) +{ + uint32_t *elts = (uint32_t *)ib + start; + int push; + + while (count) { + push = MIN2(count, 2047); + + BEGIN_RING_NI(rankine, NV34TCL_VB_ELEMENT_U32, push); + OUT_RINGp (elts, push); + + count -= push; + elts += push; + } +} + +static boolean +nv30_draw_elements_inline(struct pipe_context *pipe, + struct pipe_buffer *ib, unsigned ib_size, + unsigned mode, unsigned start, unsigned count) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + boolean ret; + void *map; + + ret = nv30_vbo_validate_state(nv30, NULL, 0); + if (!ret) { + NOUVEAU_ERR("state validate failed\n"); + return FALSE; + } + + map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); + if (!ib) { + NOUVEAU_ERR("failed mapping ib\n"); + return FALSE; + } + + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + switch (ib_size) { + case 1: + nv30_draw_elements_u08(nv30, map, start, count); + break; + case 2: + nv30_draw_elements_u16(nv30, map, start, count); + break; + case 4: + nv30_draw_elements_u32(nv30, map, start, count); + break; + default: + NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); + break; + } + + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (0); + + ws->buffer_unmap(ws, ib); + + return TRUE; +} + +static boolean +nv30_draw_elements_vbo(struct pipe_context *pipe, + struct pipe_buffer *ib, unsigned ib_size, + unsigned mode, unsigned start, unsigned count) +{ + struct nv30_context *nv30 = nv30_context(pipe); + unsigned nr, type; + boolean ret; + + switch (ib_size) { + case 2: + type = NV34TCL_IDXBUF_FORMAT_TYPE_U16; + break; + case 4: + type = NV34TCL_IDXBUF_FORMAT_TYPE_U32; + break; + default: + NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); + return FALSE; + } + + ret = nv30_vbo_validate_state(nv30, ib, type); + if (!ret) { + NOUVEAU_ERR("failed state validation\n"); + return FALSE; + } + + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + nr = (count & 0xff); + if (nr) { + BEGIN_RING(rankine, NV34TCL_VB_INDEX_BATCH, 1); + OUT_RING (((nr - 1) << 24) | start); + start += nr; + } + + nr = count >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; + + nr -= push; + + BEGIN_RING_NI(rankine, NV34TCL_VB_INDEX_BATCH, push); + while (push--) { + OUT_RING(((0x100 - 1) << 24) | start); + start += 0x100; + } + } + + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (0); + + return TRUE; +} + +boolean +nv30_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ +/* if (indexSize != 1) { + nv30_draw_elements_vbo(pipe, indexBuffer, indexSize, + mode, start, count); + } else */{ + nv30_draw_elements_inline(pipe, indexBuffer, indexSize, + mode, start, count); + } + + pipe->flush(pipe, 0, NULL); + return TRUE; +} + + diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c new file mode 100644 index 00000000000..1b34d2e4b29 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -0,0 +1,816 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" + +#include "nv30_context.h" +#include "nv30_state.h" + +/* TODO (at least...): + * 1. Indexed consts + ARL + * 2. Arb. swz/negation + * 3. NV_vp11, NV_vp2, NV_vp3 features + * - extra arith opcodes + * - branching + * - texture sampling + * - indexed attribs + * - indexed results + * 4. bugs + */ + +#define SWZ_X 0 +#define SWZ_Y 1 +#define SWZ_Z 2 +#define SWZ_W 3 +#define MASK_X 8 +#define MASK_Y 4 +#define MASK_Z 2 +#define MASK_W 1 +#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W) +#define DEF_SCALE 0 +#define DEF_CTEST 0 +#include "nv30_shader.h" + +#define swz(s,x,y,z,w) nv30_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w) +#define neg(s) nv30_sr_neg((s)) +#define abs(s) nv30_sr_abs((s)) + +struct nv30_vpc { + struct nv30_vertex_program *vp; + + struct nv30_vertex_program_exec *vpi; + + unsigned output_map[PIPE_MAX_SHADER_OUTPUTS]; + + int high_temp; + int temp_temp_count; + + struct nv30_sreg *imm; + unsigned nr_imm; +}; + +static struct nv30_sreg +temp(struct nv30_vpc *vpc) +{ + int idx; + + idx = vpc->temp_temp_count++; + idx += vpc->high_temp + 1; + return nv30_sr(NV30SR_TEMP, idx); +} + +static struct nv30_sreg +constant(struct nv30_vpc *vpc, int pipe, float x, float y, float z, float w) +{ + struct nv30_vertex_program *vp = vpc->vp; + struct nv30_vertex_program_data *vpd; + int idx; + + if (pipe >= 0) { + for (idx = 0; idx < vp->nr_consts; idx++) { + if (vp->consts[idx].index == pipe) + return nv30_sr(NV30SR_CONST, idx); + } + } + + idx = vp->nr_consts++; + vp->consts = realloc(vp->consts, sizeof(*vpd) * vp->nr_consts); + vpd = &vp->consts[idx]; + + vpd->index = pipe; + vpd->value[0] = x; + vpd->value[1] = y; + vpd->value[2] = z; + vpd->value[3] = w; + return nv30_sr(NV30SR_CONST, idx); +} + +#define arith(cc,s,o,d,m,s0,s1,s2) \ + nv30_vp_arith((cc), (s), NV30_VP_INST_##o, (d), (m), (s0), (s1), (s2)) + +static void +emit_src(struct nv30_vpc *vpc, uint32_t *hw, int pos, struct nv30_sreg src) +{ + struct nv30_vertex_program *vp = vpc->vp; + uint32_t sr = 0; + + switch (src.type) { + case NV30SR_TEMP: + sr |= (NV30_VP_SRC_REG_TYPE_TEMP << NV30_VP_SRC_REG_TYPE_SHIFT); + sr |= (src.index << NV30_VP_SRC_TEMP_SRC_SHIFT); + break; + case NV30SR_INPUT: + sr |= (NV30_VP_SRC_REG_TYPE_INPUT << + NV30_VP_SRC_REG_TYPE_SHIFT); + vp->ir |= (1 << src.index); + hw[1] |= (src.index << NV30_VP_INST_INPUT_SRC_SHIFT); + break; + case NV30SR_CONST: + sr |= (NV30_VP_SRC_REG_TYPE_CONST << + NV30_VP_SRC_REG_TYPE_SHIFT); + assert(vpc->vpi->const_index == -1 || + vpc->vpi->const_index == src.index); + vpc->vpi->const_index = src.index; + break; + case NV30SR_NONE: + sr |= (NV30_VP_SRC_REG_TYPE_INPUT << + NV30_VP_SRC_REG_TYPE_SHIFT); + break; + default: + assert(0); + } + + if (src.negate) + sr |= NV30_VP_SRC_NEGATE; + + if (src.abs) + hw[0] |= (1 << (21 + pos)); + + sr |= ((src.swz[0] << NV30_VP_SRC_SWZ_X_SHIFT) | + (src.swz[1] << NV30_VP_SRC_SWZ_Y_SHIFT) | + (src.swz[2] << NV30_VP_SRC_SWZ_Z_SHIFT) | + (src.swz[3] << NV30_VP_SRC_SWZ_W_SHIFT)); + +/* + * |VVV| + * d�.�b + * \u/ + * + */ + + switch (pos) { + case 0: + hw[1] |= ((sr & NV30_VP_SRC0_HIGH_MASK) >> + NV30_VP_SRC0_HIGH_SHIFT) << NV30_VP_INST_SRC0H_SHIFT; + hw[2] |= (sr & NV30_VP_SRC0_LOW_MASK) << + NV30_VP_INST_SRC0L_SHIFT; + break; + case 1: + hw[2] |= sr << NV30_VP_INST_SRC1_SHIFT; + break; + case 2: + hw[2] |= ((sr & NV30_VP_SRC2_HIGH_MASK) >> + NV30_VP_SRC2_HIGH_SHIFT) << NV30_VP_INST_SRC2H_SHIFT; + hw[3] |= (sr & NV30_VP_SRC2_LOW_MASK) << + NV30_VP_INST_SRC2L_SHIFT; + break; + default: + assert(0); + } +} + +static void +emit_dst(struct nv30_vpc *vpc, uint32_t *hw, int slot, struct nv30_sreg dst) +{ + struct nv30_vertex_program *vp = vpc->vp; + + switch (dst.type) { + case NV30SR_TEMP: + hw[0] |= (dst.index << NV30_VP_INST_DEST_TEMP_ID_SHIFT); + break; + case NV30SR_OUTPUT: + switch (dst.index) { + case NV30_VP_INST_DEST_COL0 : vp->or |= (1 << 0); break; + case NV30_VP_INST_DEST_COL1 : vp->or |= (1 << 1); break; + case NV30_VP_INST_DEST_BFC0 : vp->or |= (1 << 2); break; + case NV30_VP_INST_DEST_BFC1 : vp->or |= (1 << 3); break; + case NV30_VP_INST_DEST_FOGC : vp->or |= (1 << 4); break; + case NV30_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break; + case NV30_VP_INST_DEST_TC(0): vp->or |= (1 << 14); break; + case NV30_VP_INST_DEST_TC(1): vp->or |= (1 << 15); break; + case NV30_VP_INST_DEST_TC(2): vp->or |= (1 << 16); break; + case NV30_VP_INST_DEST_TC(3): vp->or |= (1 << 17); break; + case NV30_VP_INST_DEST_TC(4): vp->or |= (1 << 18); break; + case NV30_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break; + case NV30_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break; + case NV30_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break; + default: + break; + } + + hw[3] |= (dst.index << NV30_VP_INST_DEST_SHIFT); + hw[0] |= NV30_VP_INST_VEC_DEST_TEMP_MASK | (1<<20); + + /*XXX: no way this is entirely correct, someone needs to + * figure out what exactly it is. + */ + hw[3] |= 0x800; + break; + default: + assert(0); + } +} + +static void +nv30_vp_arith(struct nv30_vpc *vpc, int slot, int op, + struct nv30_sreg dst, int mask, + struct nv30_sreg s0, struct nv30_sreg s1, + struct nv30_sreg s2) +{ + struct nv30_vertex_program *vp = vpc->vp; + uint32_t *hw; + + vp->insns = realloc(vp->insns, ++vp->nr_insns * sizeof(*vpc->vpi)); + vpc->vpi = &vp->insns[vp->nr_insns - 1]; + memset(vpc->vpi, 0, sizeof(*vpc->vpi)); + vpc->vpi->const_index = -1; + + hw = vpc->vpi->data; + + hw[0] |= (NV30_VP_INST_COND_TR << NV30_VP_INST_COND_SHIFT); + hw[0] |= ((0 << NV30_VP_INST_COND_SWZ_X_SHIFT) | + (1 << NV30_VP_INST_COND_SWZ_Y_SHIFT) | + (2 << NV30_VP_INST_COND_SWZ_Z_SHIFT) | + (3 << NV30_VP_INST_COND_SWZ_W_SHIFT)); + + hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT); +// hw[3] |= NV30_VP_INST_SCA_DEST_TEMP_MASK; +// hw[3] |= (mask << NV30_VP_INST_VEC_WRITEMASK_SHIFT); + + if (dst.type == NV30SR_OUTPUT) { + if (slot) + hw[3] |= (mask << NV30_VP_INST_SDEST_WRITEMASK_SHIFT); + else + hw[3] |= (mask << NV30_VP_INST_VDEST_WRITEMASK_SHIFT); + } else { + if (slot) + hw[3] |= (mask << NV30_VP_INST_STEMP_WRITEMASK_SHIFT); + else + hw[3] |= (mask << NV30_VP_INST_VTEMP_WRITEMASK_SHIFT); + } + + emit_dst(vpc, hw, slot, dst); + emit_src(vpc, hw, 0, s0); + emit_src(vpc, hw, 1, s1); + emit_src(vpc, hw, 2, s2); +} + +static INLINE struct nv30_sreg +tgsi_src(struct nv30_vpc *vpc, const struct tgsi_full_src_register *fsrc) { + struct nv30_sreg src; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + src = nv30_sr(NV30SR_INPUT, fsrc->SrcRegister.Index); + break; + case TGSI_FILE_CONSTANT: + src = constant(vpc, fsrc->SrcRegister.Index, 0, 0, 0, 0); + break; + case TGSI_FILE_IMMEDIATE: + src = vpc->imm[fsrc->SrcRegister.Index]; + break; + case TGSI_FILE_TEMPORARY: + if (vpc->high_temp < fsrc->SrcRegister.Index) + vpc->high_temp = fsrc->SrcRegister.Index; + src = nv30_sr(NV30SR_TEMP, fsrc->SrcRegister.Index); + break; + default: + NOUVEAU_ERR("bad src file\n"); + break; + } + + src.abs = fsrc->SrcRegisterExtMod.Absolute; + src.negate = fsrc->SrcRegister.Negate; + src.swz[0] = fsrc->SrcRegister.SwizzleX; + src.swz[1] = fsrc->SrcRegister.SwizzleY; + src.swz[2] = fsrc->SrcRegister.SwizzleZ; + src.swz[3] = fsrc->SrcRegister.SwizzleW; + return src; +} + +static INLINE struct nv30_sreg +tgsi_dst(struct nv30_vpc *vpc, const struct tgsi_full_dst_register *fdst) { + struct nv30_sreg dst; + + switch (fdst->DstRegister.File) { + case TGSI_FILE_OUTPUT: + dst = nv30_sr(NV30SR_OUTPUT, + vpc->output_map[fdst->DstRegister.Index]); + + break; + case TGSI_FILE_TEMPORARY: + dst = nv30_sr(NV30SR_TEMP, fdst->DstRegister.Index); + if (vpc->high_temp < dst.index) + vpc->high_temp = dst.index; + break; + default: + NOUVEAU_ERR("bad dst file\n"); + break; + } + + return dst; +} + +static INLINE int +tgsi_mask(uint tgsi) +{ + int mask = 0; + + if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X; + if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y; + if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z; + if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W; + return mask; +} + +static boolean +nv30_vertprog_parse_instruction(struct nv30_vpc *vpc, + const struct tgsi_full_instruction *finst) +{ + struct nv30_sreg src[3], dst, tmp; + struct nv30_sreg none = nv30_sr(NV30SR_NONE, 0); + int mask; + int ai = -1, ci = -1; + int i; + + if (finst->Instruction.Opcode == TGSI_OPCODE_END) + return TRUE; + + vpc->temp_temp_count = 0; + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) { + src[i] = tgsi_src(vpc, fsrc); + } + } + + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + if (ai == -1 || ai == fsrc->SrcRegister.Index) { + ai = fsrc->SrcRegister.Index; + src[i] = tgsi_src(vpc, fsrc); + } else { + src[i] = temp(vpc); + arith(vpc, 0, OP_MOV, src[i], MASK_ALL, + tgsi_src(vpc, fsrc), none, none); + } + break; + /*XXX: index comparison is broken now that consts come from + * two different register files. + */ + case TGSI_FILE_CONSTANT: + case TGSI_FILE_IMMEDIATE: + if (ci == -1 || ci == fsrc->SrcRegister.Index) { + ci = fsrc->SrcRegister.Index; + src[i] = tgsi_src(vpc, fsrc); + } else { + src[i] = temp(vpc); + arith(vpc, 0, OP_MOV, src[i], MASK_ALL, + tgsi_src(vpc, fsrc), none, none); + } + break; + case TGSI_FILE_TEMPORARY: + /* handled above */ + break; + default: + NOUVEAU_ERR("bad src file\n"); + return FALSE; + } + } + + dst = tgsi_dst(vpc, &finst->FullDstRegisters[0]); + mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask); + + switch (finst->Instruction.Opcode) { + case TGSI_OPCODE_ABS: + arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none); + break; + case TGSI_OPCODE_ADD: + arith(vpc, 0, OP_ADD, dst, mask, src[0], none, src[1]); + break; + case TGSI_OPCODE_ARL: + arith(vpc, 0, OP_ARL, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_DP3: + arith(vpc, 0, OP_DP3, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DP4: + arith(vpc, 0, OP_DP4, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DPH: + arith(vpc, 0, OP_DPH, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DST: + arith(vpc, 0, OP_DST, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_EX2: + arith(vpc, 1, OP_EX2, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_EXP: + arith(vpc, 1, OP_EXP, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_FLR: + arith(vpc, 0, OP_FLR, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_FRC: + arith(vpc, 0, OP_FRC, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_LG2: + arith(vpc, 1, OP_LG2, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_LIT: + arith(vpc, 1, OP_LIT, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_LOG: + arith(vpc, 1, OP_LOG, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_MAD: + arith(vpc, 0, OP_MAD, dst, mask, src[0], src[1], src[2]); + break; + case TGSI_OPCODE_MAX: + arith(vpc, 0, OP_MAX, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MIN: + arith(vpc, 0, OP_MIN, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MOV: + arith(vpc, 0, OP_MOV, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_MUL: + arith(vpc, 0, OP_MUL, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_POW: + tmp = temp(vpc); + arith(vpc, 1, OP_LG2, tmp, MASK_X, none, none, + swz(src[0], X, X, X, X)); + arith(vpc, 0, OP_MUL, tmp, MASK_X, swz(tmp, X, X, X, X), + swz(src[1], X, X, X, X), none); + arith(vpc, 1, OP_EX2, dst, mask, none, none, + swz(tmp, X, X, X, X)); + break; + case TGSI_OPCODE_RCP: + arith(vpc, 1, OP_RCP, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_RET: + break; + case TGSI_OPCODE_RSQ: + arith(vpc, 1, OP_RSQ, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_SGE: + arith(vpc, 0, OP_SGE, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SLT: + arith(vpc, 0, OP_SLT, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SUB: + arith(vpc, 0, OP_ADD, dst, mask, src[0], none, neg(src[1])); + break; + case TGSI_OPCODE_XPD: + tmp = temp(vpc); + arith(vpc, 0, OP_MUL, tmp, mask, + swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none); + arith(vpc, 0, OP_MAD, dst, (mask & ~MASK_W), + swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y), + neg(tmp)); + break; + default: + NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode); + return FALSE; + } + + return TRUE; +} + +static boolean +nv30_vertprog_parse_decl_output(struct nv30_vpc *vpc, + const struct tgsi_full_declaration *fdec) +{ + int hw; + + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + hw = NV30_VP_INST_DEST_POS; + break; + case TGSI_SEMANTIC_COLOR: + if (fdec->Semantic.SemanticIndex == 0) { + hw = NV30_VP_INST_DEST_COL0; + } else + if (fdec->Semantic.SemanticIndex == 1) { + hw = NV30_VP_INST_DEST_COL1; + } else { + NOUVEAU_ERR("bad colour semantic index\n"); + return FALSE; + } + break; + case TGSI_SEMANTIC_BCOLOR: + if (fdec->Semantic.SemanticIndex == 0) { + hw = NV30_VP_INST_DEST_BFC0; + } else + if (fdec->Semantic.SemanticIndex == 1) { + hw = NV30_VP_INST_DEST_BFC1; + } else { + NOUVEAU_ERR("bad bcolour semantic index\n"); + return FALSE; + } + break; + case TGSI_SEMANTIC_FOG: + hw = NV30_VP_INST_DEST_FOGC; + break; + case TGSI_SEMANTIC_PSIZE: + hw = NV30_VP_INST_DEST_PSZ; + break; + case TGSI_SEMANTIC_GENERIC: + if (fdec->Semantic.SemanticIndex <= 7) { + hw = NV30_VP_INST_DEST_TC(fdec->Semantic.SemanticIndex); + } else { + NOUVEAU_ERR("bad generic semantic index\n"); + return FALSE; + } + break; + default: + NOUVEAU_ERR("bad output semantic\n"); + return FALSE; + } + + vpc->output_map[fdec->DeclarationRange.First] = hw; + return TRUE; +} + +static boolean +nv30_vertprog_prepare(struct nv30_vpc *vpc) +{ + struct tgsi_parse_context p; + int nr_imm = 0; + + tgsi_parse_init(&p, vpc->vp->pipe.tokens); + while (!tgsi_parse_end_of_tokens(&p)) { + const union tgsi_full_token *tok = &p.FullToken; + + tgsi_parse_token(&p); + switch(tok->Token.Type) { + case TGSI_TOKEN_TYPE_IMMEDIATE: + nr_imm++; + break; + default: + break; + } + } + tgsi_parse_free(&p); + + if (nr_imm) { + vpc->imm = CALLOC(nr_imm, sizeof(struct nv30_sreg)); + assert(vpc->imm); + } + + return TRUE; +} + +void +nv30_vertprog_translate(struct nv30_context *nv30, + struct nv30_vertex_program *vp) +{ + struct tgsi_parse_context parse; + struct nv30_vpc *vpc = NULL; + + vpc = CALLOC(1, sizeof(struct nv30_vpc)); + if (!vpc) + return; + vpc->vp = vp; + vpc->high_temp = -1; + + if (!nv30_vertprog_prepare(vpc)) { + FREE(vpc); + return; + } + + tgsi_parse_init(&parse, vp->pipe.tokens); + + while (!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *fdec; + fdec = &parse.FullToken.FullDeclaration; + switch (fdec->Declaration.File) { + case TGSI_FILE_OUTPUT: + if (!nv30_vertprog_parse_decl_output(vpc, fdec)) + goto out_err; + break; + default: + break; + } + } + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + const struct tgsi_full_immediate *imm; + + imm = &parse.FullToken.FullImmediate; + assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); +// assert(imm->Immediate.Size == 4); + vpc->imm[vpc->nr_imm++] = + constant(vpc, -1, + imm->u.ImmediateFloat32[0].Float, + imm->u.ImmediateFloat32[1].Float, + imm->u.ImmediateFloat32[2].Float, + imm->u.ImmediateFloat32[3].Float); + } + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + const struct tgsi_full_instruction *finst; + finst = &parse.FullToken.FullInstruction; + if (!nv30_vertprog_parse_instruction(vpc, finst)) + goto out_err; + } + break; + default: + break; + } + } + + vp->insns[vp->nr_insns - 1].data[3] |= NV30_VP_INST_LAST; + vp->translated = TRUE; +out_err: + tgsi_parse_free(&parse); + FREE(vpc); +} + +void +nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) +{ + struct nouveau_winsys *nvws = nv30->nvws; + struct pipe_winsys *ws = nv30->pipe.winsys; + boolean upload_code = FALSE, upload_data = FALSE; + int i; + + /* Translate TGSI shader into hw bytecode */ + if (!vp->translated) { + nv30_vertprog_translate(nv30, vp); + if (!vp->translated) + assert(0); + } + + /* Allocate hw vtxprog exec slots */ + if (!vp->exec) { + struct nouveau_resource *heap = nv30->screen->vp_exec_heap; + uint vplen = vp->nr_insns; + + if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) { + while (heap->next && heap->size < vplen) { + struct nv30_vertex_program *evict; + + evict = heap->next->priv; + nvws->res_free(&evict->exec); + } + + if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) + assert(0); + } + + upload_code = TRUE; + } + + /* Allocate hw vtxprog const slots */ + if (vp->nr_consts && !vp->data) { + struct nouveau_resource *heap = nv30->screen->vp_data_heap; + + if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) { + while (heap->next && heap->size < vp->nr_consts) { + struct nv30_vertex_program *evict; + + evict = heap->next->priv; + nvws->res_free(&evict->data); + } + + if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) + assert(0); + } + + /*XXX: handle this some day */ + assert(vp->data->start >= vp->data_start_min); + + upload_data = TRUE; + if (vp->data_start != vp->data->start) + upload_code = TRUE; + } + + /* If exec or data segments moved we need to patch the program to + * fixup offsets and register IDs. + */ + if (vp->exec_start != vp->exec->start) { + for (i = 0; i < vp->nr_insns; i++) { + struct nv30_vertex_program_exec *vpi = &vp->insns[i]; + + if (vpi->has_branch_offset) { + assert(0); + } + } + + vp->exec_start = vp->exec->start; + } + + if (vp->nr_consts && vp->data_start != vp->data->start) { + for (i = 0; i < vp->nr_insns; i++) { + struct nv30_vertex_program_exec *vpi = &vp->insns[i]; + + if (vpi->const_index >= 0) { + vpi->data[1] &= ~NV30_VP_INST_CONST_SRC_MASK; + vpi->data[1] |= + (vpi->const_index + vp->data->start) << + NV30_VP_INST_CONST_SRC_SHIFT; + + } + } + + vp->data_start = vp->data->start; + } + + /* Update + Upload constant values */ + if (vp->nr_consts) { + float *map = NULL; + + if (nv30->vertprog.constant_buf) { + map = ws->buffer_map(ws, nv30->vertprog.constant_buf, + PIPE_BUFFER_USAGE_CPU_READ); + } + + for (i = 0; i < vp->nr_consts; i++) { + struct nv30_vertex_program_data *vpd = &vp->consts[i]; + + if (vpd->index >= 0) { + if (!upload_data && + !memcmp(vpd->value, &map[vpd->index * 4], + 4 * sizeof(float))) + continue; + memcpy(vpd->value, &map[vpd->index * 4], + 4 * sizeof(float)); + } + + BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_CONST_ID, 5); + OUT_RING (i + vp->data->start); + OUT_RINGp ((uint32_t *)vpd->value, 4); +#if 0 + NOUVEAU_MSG("VP const %d: %f %f %f %f\n", + i, vpd->value[0], vpd->value[1], + vpd->value[2], vpd->value[3]); +#endif + } + + if (map) { + ws->buffer_unmap(ws, nv30->vertprog.constant_buf); + } + } + + /* Upload vtxprog */ + if (upload_code) { +#if 0 + for (i = 0; i < vp->nr_insns; i++) { + NOUVEAU_MSG("VP inst %d: 0x%08x 0x%08x 0x%08x 0x%08x\n", + i, vp->insns[i].data[0], vp->insns[i].data[1], + vp->insns[i].data[2], vp->insns[i].data[3]); + } +#endif + BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_FROM_ID, 1); + OUT_RING (vp->exec->start); + for (i = 0; i < vp->nr_insns; i++) { + BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_INST(0), 4); + OUT_RINGp (vp->insns[i].data, 4); + } + } + + BEGIN_RING(rankine, NV34TCL_VP_START_FROM_ID, 1); + OUT_RING (vp->exec->start); + + nv30->vertprog.active = vp; +} + +void +nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp) +{ + struct nouveau_winsys *nvws = nv30->screen->nvws; + + vp->translated = FALSE; + + if (vp->nr_insns) { + FREE(vp->insns); + vp->insns = NULL; + vp->nr_insns = 0; + } + + if (vp->nr_consts) { + FREE(vp->consts); + vp->consts = NULL; + vp->nr_consts = 0; + } + + nvws->res_free(&vp->exec); + vp->exec_start = 0; + nvws->res_free(&vp->data); + vp->data_start = 0; + vp->data_start_min = 0; + + /* vp->ir = vp->or = vp->clip_ctrl = 0; + so_ref(NULL, &vp->so); */ +} + diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile new file mode 100644 index 00000000000..9c8eadf7e44 --- /dev/null +++ b/src/gallium/drivers/nv40/Makefile @@ -0,0 +1,37 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = nv40 + +DRIVER_SOURCES = \ + nv40_clear.c \ + nv40_context.c \ + nv40_draw.c \ + nv40_fragprog.c \ + nv40_fragtex.c \ + nv40_miptree.c \ + nv40_query.c \ + nv40_screen.c \ + nv40_state.c \ + nv40_state_blend.c \ + nv40_state_emit.c \ + nv40_state_fb.c \ + nv40_state_rasterizer.c \ + nv40_state_scissor.c \ + nv40_state_stipple.c \ + nv40_state_viewport.c \ + nv40_state_zsa.c \ + nv40_surface.c \ + nv40_vbo.c \ + nv40_vertprog.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/nv40/nv40_clear.c b/src/gallium/drivers/nv40/nv40_clear.c new file mode 100644 index 00000000000..59efd620e32 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_clear.c @@ -0,0 +1,13 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "nv40_context.h" + +void +nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + ps->status = PIPE_SURFACE_STATUS_CLEAR; +} diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c new file mode 100644 index 00000000000..a40f14895f4 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -0,0 +1,73 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" +#include "nv40_screen.h" + +static void +nv40_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(curie, 0x1fd8, 1); + OUT_RING (2); + BEGIN_RING(curie, 0x1fd8, 1); + OUT_RING (1); + } + + FIRE_RING(fence); +} + +static void +nv40_destroy(struct pipe_context *pipe) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + if (nv40->draw) + draw_destroy(nv40->draw); + FREE(nv40); +} + +struct pipe_context * +nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) +{ + struct nv40_screen *screen = nv40_screen(pscreen); + struct pipe_winsys *ws = pscreen->winsys; + struct nv40_context *nv40; + struct nouveau_winsys *nvws = screen->nvws; + + nv40 = CALLOC(1, sizeof(struct nv40_context)); + if (!nv40) + return NULL; + nv40->screen = screen; + nv40->pctx_id = pctx_id; + + nv40->nvws = nvws; + + nv40->pipe.winsys = ws; + nv40->pipe.screen = pscreen; + nv40->pipe.destroy = nv40_destroy; + nv40->pipe.draw_arrays = nv40_draw_arrays; + nv40->pipe.draw_elements = nv40_draw_elements; + nv40->pipe.clear = nv40_clear; + nv40->pipe.flush = nv40_flush; + + nv40_init_query_functions(nv40); + nv40_init_surface_functions(nv40); + nv40_init_state_functions(nv40); + + /* Create, configure, and install fallback swtnl path */ + nv40->draw = draw_create(); + draw_wide_point_threshold(nv40->draw, 9999999.0); + draw_wide_line_threshold(nv40->draw, 9999999.0); + draw_enable_line_stipple(nv40->draw, FALSE); + draw_enable_point_sprites(nv40->draw, FALSE); + draw_set_rasterize_stage(nv40->draw, nv40_draw_render_stage(nv40)); + + return &nv40->pipe; +} + diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h new file mode 100644 index 00000000000..8e60a81e68e --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -0,0 +1,229 @@ +#ifndef __NV40_CONTEXT_H__ +#define __NV40_CONTEXT_H__ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "draw/draw_vertex.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_gldefs.h" + +#define NOUVEAU_PUSH_CONTEXT(ctx) \ + struct nv40_screen *ctx = nv40->screen +#include "nouveau/nouveau_push.h" +#include "nouveau/nouveau_stateobj.h" + +#include "nv40_state.h" + +#define NOUVEAU_ERR(fmt, args...) \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); +#define NOUVEAU_MSG(fmt, args...) \ + fprintf(stderr, "nouveau: "fmt, ##args); + +enum nv40_state_index { + NV40_STATE_FB = 0, + NV40_STATE_VIEWPORT = 1, + NV40_STATE_BLEND = 2, + NV40_STATE_RAST = 3, + NV40_STATE_ZSA = 4, + NV40_STATE_BCOL = 5, + NV40_STATE_CLIP = 6, + NV40_STATE_SCISSOR = 7, + NV40_STATE_STIPPLE = 8, + NV40_STATE_FRAGPROG = 9, + NV40_STATE_VERTPROG = 10, + NV40_STATE_FRAGTEX0 = 11, + NV40_STATE_FRAGTEX1 = 12, + NV40_STATE_FRAGTEX2 = 13, + NV40_STATE_FRAGTEX3 = 14, + NV40_STATE_FRAGTEX4 = 15, + NV40_STATE_FRAGTEX5 = 16, + NV40_STATE_FRAGTEX6 = 17, + NV40_STATE_FRAGTEX7 = 18, + NV40_STATE_FRAGTEX8 = 19, + NV40_STATE_FRAGTEX9 = 20, + NV40_STATE_FRAGTEX10 = 21, + NV40_STATE_FRAGTEX11 = 22, + NV40_STATE_FRAGTEX12 = 23, + NV40_STATE_FRAGTEX13 = 24, + NV40_STATE_FRAGTEX14 = 25, + NV40_STATE_FRAGTEX15 = 26, + NV40_STATE_VERTTEX0 = 27, + NV40_STATE_VERTTEX1 = 28, + NV40_STATE_VERTTEX2 = 29, + NV40_STATE_VERTTEX3 = 30, + NV40_STATE_VTXBUF = 31, + NV40_STATE_VTXFMT = 32, + NV40_STATE_VTXATTR = 33, + NV40_STATE_MAX = 34 +}; + +#include "nv40_screen.h" + +#define NV40_NEW_BLEND (1 << 0) +#define NV40_NEW_RAST (1 << 1) +#define NV40_NEW_ZSA (1 << 2) +#define NV40_NEW_SAMPLER (1 << 3) +#define NV40_NEW_FB (1 << 4) +#define NV40_NEW_STIPPLE (1 << 5) +#define NV40_NEW_SCISSOR (1 << 6) +#define NV40_NEW_VIEWPORT (1 << 7) +#define NV40_NEW_BCOL (1 << 8) +#define NV40_NEW_VERTPROG (1 << 9) +#define NV40_NEW_FRAGPROG (1 << 10) +#define NV40_NEW_ARRAYS (1 << 11) +#define NV40_NEW_UCP (1 << 12) + +struct nv40_rasterizer_state { + struct pipe_rasterizer_state pipe; + struct nouveau_stateobj *so; +}; + +struct nv40_zsa_state { + struct pipe_depth_stencil_alpha_state pipe; + struct nouveau_stateobj *so; +}; + +struct nv40_blend_state { + struct pipe_blend_state pipe; + struct nouveau_stateobj *so; +}; + + +struct nv40_state { + unsigned scissor_enabled; + unsigned stipple_enabled; + unsigned viewport_bypass; + unsigned fp_samplers; + + uint64_t dirty; + struct nouveau_stateobj *hw[NV40_STATE_MAX]; +}; + +struct nv40_context { + struct pipe_context pipe; + + struct nouveau_winsys *nvws; + struct nv40_screen *screen; + unsigned pctx_id; + + struct draw_context *draw; + + /* HW state derived from pipe states */ + struct nv40_state state; + struct { + struct nv40_vertex_program *vertprog; + + unsigned nr_attribs; + unsigned hw[PIPE_MAX_SHADER_INPUTS]; + unsigned draw[PIPE_MAX_SHADER_INPUTS]; + unsigned emit[PIPE_MAX_SHADER_INPUTS]; + } swtnl; + + enum { + HW, SWTNL, SWRAST + } render_mode; + unsigned fallback_swtnl; + unsigned fallback_swrast; + + /* Context state */ + unsigned dirty, draw_dirty; + struct pipe_scissor_state scissor; + unsigned stipple[32]; + struct pipe_clip_state clip; + struct nv40_vertex_program *vertprog; + struct nv40_fragment_program *fragprog; + struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + unsigned constbuf_nr[PIPE_SHADER_TYPES]; + struct nv40_rasterizer_state *rasterizer; + struct nv40_zsa_state *zsa; + struct nv40_blend_state *blend; + struct pipe_blend_color blend_colour; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + struct pipe_buffer *idxbuf; + unsigned idxbuf_format; + struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; + struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; + unsigned nr_samplers; + unsigned nr_textures; + unsigned dirty_samplers; + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; + unsigned vtxbuf_nr; + struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; + unsigned vtxelt_nr; + const unsigned *edgeflags; +}; + +static INLINE struct nv40_context * +nv40_context(struct pipe_context *pipe) +{ + return (struct nv40_context *)pipe; +} + +struct nv40_state_entry { + boolean (*validate)(struct nv40_context *nv40); + struct { + unsigned pipe; + unsigned hw; + } dirty; +}; + +extern void nv40_init_state_functions(struct nv40_context *nv40); +extern void nv40_init_surface_functions(struct nv40_context *nv40); +extern void nv40_init_query_functions(struct nv40_context *nv40); + +extern void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen); + +/* nv40_draw.c */ +extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40); +extern boolean nv40_draw_elements_swtnl(struct pipe_context *pipe, + struct pipe_buffer *idxbuf, + unsigned ib_size, unsigned mode, + unsigned start, unsigned count); + +/* nv40_vertprog.c */ +extern void nv40_vertprog_destroy(struct nv40_context *, + struct nv40_vertex_program *); + +/* nv40_fragprog.c */ +extern void nv40_fragprog_destroy(struct nv40_context *, + struct nv40_fragment_program *); + +/* nv40_fragtex.c */ +extern void nv40_fragtex_bind(struct nv40_context *); + +/* nv40_state.c and friends */ +extern boolean nv40_state_validate(struct nv40_context *nv40); +extern boolean nv40_state_validate_swtnl(struct nv40_context *nv40); +extern void nv40_state_emit(struct nv40_context *nv40); +extern struct nv40_state_entry nv40_state_rasterizer; +extern struct nv40_state_entry nv40_state_scissor; +extern struct nv40_state_entry nv40_state_stipple; +extern struct nv40_state_entry nv40_state_fragprog; +extern struct nv40_state_entry nv40_state_vertprog; +extern struct nv40_state_entry nv40_state_blend; +extern struct nv40_state_entry nv40_state_blend_colour; +extern struct nv40_state_entry nv40_state_zsa; +extern struct nv40_state_entry nv40_state_viewport; +extern struct nv40_state_entry nv40_state_framebuffer; +extern struct nv40_state_entry nv40_state_fragtex; +extern struct nv40_state_entry nv40_state_vbo; +extern struct nv40_state_entry nv40_state_vtxfmt; + +/* nv40_vbo.c */ +extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, + unsigned start, unsigned count); +extern boolean nv40_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, + unsigned count); + +/* nv40_clear.c */ +extern void nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + +#endif diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c new file mode 100644 index 00000000000..2cf58e2950a --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -0,0 +1,348 @@ +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#include "draw/draw_context.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pipe.h" + +#include "nv40_context.h" +#define NV40_SHADER_NO_FUCKEDNESS +#include "nv40_shader.h" + +/* Simple, but crappy, swtnl path, hopefully we wont need to hit this very + * often at all. Uses "quadro style" vertex submission + a fixed vertex + * layout to avoid the need to generate a vertex program or vtxfmt. + */ + +struct nv40_render_stage { + struct draw_stage stage; + struct nv40_context *nv40; + unsigned prim; +}; + +static INLINE struct nv40_render_stage * +nv40_render_stage(struct draw_stage *stage) +{ + return (struct nv40_render_stage *)stage; +} + +static INLINE void +nv40_render_vertex(struct nv40_context *nv40, const struct vertex_header *v) +{ + unsigned i; + + for (i = 0; i < nv40->swtnl.nr_attribs; i++) { + unsigned idx = nv40->swtnl.draw[i]; + unsigned hw = nv40->swtnl.hw[i]; + + switch (nv40->swtnl.emit[i]) { + case EMIT_OMIT: + break; + case EMIT_1F: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_1F(hw), 1); + OUT_RING (fui(v->data[idx][0])); + break; + case EMIT_2F: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_2F_X(hw), 2); + OUT_RING (fui(v->data[idx][0])); + OUT_RING (fui(v->data[idx][1])); + break; + case EMIT_3F: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_3F_X(hw), 3); + OUT_RING (fui(v->data[idx][0])); + OUT_RING (fui(v->data[idx][1])); + OUT_RING (fui(v->data[idx][2])); + break; + case EMIT_4F: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_4F_X(hw), 4); + OUT_RING (fui(v->data[idx][0])); + OUT_RING (fui(v->data[idx][1])); + OUT_RING (fui(v->data[idx][2])); + OUT_RING (fui(v->data[idx][3])); + break; + case EMIT_4UB: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_4UB(hw), 1); + OUT_RING (pack_ub4(float_to_ubyte(v->data[idx][0]), + float_to_ubyte(v->data[idx][1]), + float_to_ubyte(v->data[idx][2]), + float_to_ubyte(v->data[idx][3]))); + break; + default: + assert(0); + break; + } + } +} + +static INLINE void +nv40_render_prim(struct draw_stage *stage, struct prim_header *prim, + unsigned mode, unsigned count) +{ + struct nv40_render_stage *rs = nv40_render_stage(stage); + struct nv40_context *nv40 = rs->nv40; + struct nouveau_pushbuf *pb = nv40->nvws->channel->pushbuf; + unsigned i; + + /* Ensure there's room for 4xfloat32 + potentially 3 begin/end */ + if (pb->remaining < ((count * 20) + 6)) { + if (rs->prim != NV40TCL_BEGIN_END_STOP) { + NOUVEAU_ERR("AIII, missed flush\n"); + assert(0); + } + FIRE_RING(NULL); + nv40_state_emit(nv40); + } + + /* Switch primitive modes if necessary */ + if (rs->prim != mode) { + if (rs->prim != NV40TCL_BEGIN_END_STOP) { + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (NV40TCL_BEGIN_END_STOP); + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (mode); + rs->prim = mode; + } + + /* Emit vertex data */ + for (i = 0; i < count; i++) + nv40_render_vertex(nv40, prim->v[i]); + + /* If it's likely we'll need to empty the push buffer soon, finish + * off the primitive now. + */ + if (pb->remaining < ((count * 20) + 6)) { + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (NV40TCL_BEGIN_END_STOP); + rs->prim = NV40TCL_BEGIN_END_STOP; + } +} + +static void +nv40_render_point(struct draw_stage *draw, struct prim_header *prim) +{ + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_POINTS, 1); +} + +static void +nv40_render_line(struct draw_stage *draw, struct prim_header *prim) +{ + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_LINES, 2); +} + +static void +nv40_render_tri(struct draw_stage *draw, struct prim_header *prim) +{ + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_TRIANGLES, 3); +} + +static void +nv40_render_flush(struct draw_stage *draw, unsigned flags) +{ + struct nv40_render_stage *rs = nv40_render_stage(draw); + struct nv40_context *nv40 = rs->nv40; + + if (rs->prim != NV40TCL_BEGIN_END_STOP) { + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (NV40TCL_BEGIN_END_STOP); + rs->prim = NV40TCL_BEGIN_END_STOP; + } +} + +static void +nv40_render_reset_stipple_counter(struct draw_stage *draw) +{ +} + +static void +nv40_render_destroy(struct draw_stage *draw) +{ + FREE(draw); +} + +static INLINE void +emit_mov(struct nv40_vertex_program *vp, + unsigned dst, unsigned src, unsigned vor, unsigned mask) +{ + struct nv40_vertex_program_exec *inst; + + vp->insns = realloc(vp->insns, + sizeof(struct nv40_vertex_program_exec) * + ++vp->nr_insns); + inst = &vp->insns[vp->nr_insns - 1]; + + inst->data[0] = 0x401f9c6c; + inst->data[1] = 0x0040000d | (src << 8); + inst->data[2] = 0x8106c083; + inst->data[3] = 0x6041ff80 | (dst << 2) | (mask << 13); + inst->const_index = -1; + inst->has_branch_offset = FALSE; + + vp->ir |= (1 << src); + if (vor != ~0) + vp->or |= (1 << vor); +} + +static struct nv40_vertex_program * +create_drawvp(struct nv40_context *nv40) +{ + struct nv40_vertex_program *vp = CALLOC_STRUCT(nv40_vertex_program); + unsigned i; + + emit_mov(vp, NV40_VP_INST_DEST_POS, 0, ~0, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_COL0, 3, 0, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_COL1, 4, 1, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_BFC0, 3, 2, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_BFC1, 4, 3, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_FOGC, 5, 4, 0x8); + for (i = 0; i < 8; i++) + emit_mov(vp, NV40_VP_INST_DEST_TC(i), 8 + i, 14 + i, 0xf); + + vp->insns[vp->nr_insns - 1].data[3] |= 1; + vp->translated = TRUE; + return vp; +} + +struct draw_stage * +nv40_draw_render_stage(struct nv40_context *nv40) +{ + struct nv40_render_stage *render = CALLOC_STRUCT(nv40_render_stage); + + if (!nv40->swtnl.vertprog) + nv40->swtnl.vertprog = create_drawvp(nv40); + + render->nv40 = nv40; + render->stage.draw = nv40->draw; + render->stage.point = nv40_render_point; + render->stage.line = nv40_render_line; + render->stage.tri = nv40_render_tri; + render->stage.flush = nv40_render_flush; + render->stage.reset_stipple_counter = nv40_render_reset_stipple_counter; + render->stage.destroy = nv40_render_destroy; + + return &render->stage; +} + +boolean +nv40_draw_elements_swtnl(struct pipe_context *pipe, + struct pipe_buffer *idxbuf, unsigned idxbuf_size, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + unsigned i; + void *map; + + if (!nv40_state_validate_swtnl(nv40)) + return FALSE; + nv40->state.dirty &= ~(1ULL << NV40_STATE_VTXBUF); + nv40_state_emit(nv40); + + for (i = 0; i < nv40->vtxbuf_nr; i++) { + map = ws->buffer_map(ws, nv40->vtxbuf[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(nv40->draw, i, map); + } + + if (idxbuf) { + map = ws->buffer_map(ws, idxbuf, PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer(nv40->draw, idxbuf_size, map); + } else { + draw_set_mapped_element_buffer(nv40->draw, 0, NULL); + } + + if (nv40->constbuf[PIPE_SHADER_VERTEX]) { + const unsigned nr = nv40->constbuf_nr[PIPE_SHADER_VERTEX]; + + map = ws->buffer_map(ws, nv40->constbuf[PIPE_SHADER_VERTEX], + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_constant_buffer(nv40->draw, map, nr); + } + + draw_arrays(nv40->draw, mode, start, count); + + for (i = 0; i < nv40->vtxbuf_nr; i++) + ws->buffer_unmap(ws, nv40->vtxbuf[i].buffer); + + if (idxbuf) + ws->buffer_unmap(ws, idxbuf); + + if (nv40->constbuf[PIPE_SHADER_VERTEX]) + ws->buffer_unmap(ws, nv40->constbuf[PIPE_SHADER_VERTEX]); + + draw_flush(nv40->draw); + pipe->flush(pipe, 0, NULL); + + return TRUE; +} + +static INLINE void +emit_attrib(struct nv40_context *nv40, unsigned hw, unsigned emit, + unsigned semantic, unsigned index) +{ + unsigned draw_out = draw_find_vs_output(nv40->draw, semantic, index); + unsigned a = nv40->swtnl.nr_attribs++; + + nv40->swtnl.hw[a] = hw; + nv40->swtnl.emit[a] = emit; + nv40->swtnl.draw[a] = draw_out; +} + +static boolean +nv40_state_vtxfmt_validate(struct nv40_context *nv40) +{ + struct nv40_fragment_program *fp = nv40->fragprog; + unsigned colour = 0, texcoords = 0, fog = 0, i; + + /* Determine needed fragprog inputs */ + for (i = 0; i < fp->info.num_inputs; i++) { + switch (fp->info.input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + break; + case TGSI_SEMANTIC_COLOR: + colour |= (1 << fp->info.input_semantic_index[i]); + break; + case TGSI_SEMANTIC_GENERIC: + texcoords |= (1 << fp->info.input_semantic_index[i]); + break; + case TGSI_SEMANTIC_FOG: + fog = 1; + break; + default: + assert(0); + } + } + + nv40->swtnl.nr_attribs = 0; + + /* Map draw vtxprog output to hw attribute IDs */ + for (i = 0; i < 2; i++) { + if (!(colour & (1 << i))) + continue; + emit_attrib(nv40, 3 + i, EMIT_4UB, TGSI_SEMANTIC_COLOR, i); + } + + for (i = 0; i < 8; i++) { + if (!(texcoords & (1 << i))) + continue; + emit_attrib(nv40, 8 + i, EMIT_4F, TGSI_SEMANTIC_GENERIC, i); + } + + if (fog) { + emit_attrib(nv40, 5, EMIT_1F, TGSI_SEMANTIC_FOG, 0); + } + + emit_attrib(nv40, 0, EMIT_3F, TGSI_SEMANTIC_POSITION, 0); + + return FALSE; +} + +struct nv40_state_entry nv40_state_vtxfmt = { + .validate = nv40_state_vtxfmt_validate, + .dirty = { + .pipe = NV40_NEW_ARRAYS | NV40_NEW_FRAGPROG, + .hw = 0 + } +}; + diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c new file mode 100644 index 00000000000..428348c3388 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -0,0 +1,991 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" + +#include "nv40_context.h" + +#define SWZ_X 0 +#define SWZ_Y 1 +#define SWZ_Z 2 +#define SWZ_W 3 +#define MASK_X 1 +#define MASK_Y 2 +#define MASK_Z 4 +#define MASK_W 8 +#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W) +#define DEF_SCALE NV40_FP_OP_DST_SCALE_1X +#define DEF_CTEST NV40_FP_OP_COND_TR +#include "nv40_shader.h" + +#define swz(s,x,y,z,w) nv40_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w) +#define neg(s) nv40_sr_neg((s)) +#define abs(s) nv40_sr_abs((s)) +#define scale(s,v) nv40_sr_scale((s), NV40_FP_OP_DST_SCALE_##v) + +#define MAX_CONSTS 128 +#define MAX_IMM 32 +struct nv40_fpc { + struct nv40_fragment_program *fp; + + uint attrib_map[PIPE_MAX_SHADER_INPUTS]; + + unsigned r_temps; + unsigned r_temps_discard; + struct nv40_sreg r_result[PIPE_MAX_SHADER_OUTPUTS]; + struct nv40_sreg *r_temp; + + int num_regs; + + unsigned inst_offset; + unsigned have_const; + + struct { + int pipe; + float vals[4]; + } consts[MAX_CONSTS]; + int nr_consts; + + struct nv40_sreg imm[MAX_IMM]; + unsigned nr_imm; +}; + +static INLINE struct nv40_sreg +temp(struct nv40_fpc *fpc) +{ + int idx = ffs(~fpc->r_temps) - 1; + + if (idx < 0) { + NOUVEAU_ERR("out of temps!!\n"); + assert(0); + return nv40_sr(NV40SR_TEMP, 0); + } + + fpc->r_temps |= (1 << idx); + fpc->r_temps_discard |= (1 << idx); + return nv40_sr(NV40SR_TEMP, idx); +} + +static INLINE void +release_temps(struct nv40_fpc *fpc) +{ + fpc->r_temps &= ~fpc->r_temps_discard; + fpc->r_temps_discard = 0; +} + +static INLINE struct nv40_sreg +constant(struct nv40_fpc *fpc, int pipe, float vals[4]) +{ + int idx; + + if (fpc->nr_consts == MAX_CONSTS) + assert(0); + idx = fpc->nr_consts++; + + fpc->consts[idx].pipe = pipe; + if (pipe == -1) + memcpy(fpc->consts[idx].vals, vals, 4 * sizeof(float)); + return nv40_sr(NV40SR_CONST, idx); +} + +#define arith(cc,s,o,d,m,s0,s1,s2) \ + nv40_fp_arith((cc), (s), NV40_FP_OP_OPCODE_##o, \ + (d), (m), (s0), (s1), (s2)) +#define tex(cc,s,o,u,d,m,s0,s1,s2) \ + nv40_fp_tex((cc), (s), NV40_FP_OP_OPCODE_##o, (u), \ + (d), (m), (s0), none, none) + +static void +grow_insns(struct nv40_fpc *fpc, int size) +{ + struct nv40_fragment_program *fp = fpc->fp; + + fp->insn_len += size; + fp->insn = realloc(fp->insn, sizeof(uint32_t) * fp->insn_len); +} + +static void +emit_src(struct nv40_fpc *fpc, int pos, struct nv40_sreg src) +{ + struct nv40_fragment_program *fp = fpc->fp; + uint32_t *hw = &fp->insn[fpc->inst_offset]; + uint32_t sr = 0; + + switch (src.type) { + case NV40SR_INPUT: + sr |= (NV40_FP_REG_TYPE_INPUT << NV40_FP_REG_TYPE_SHIFT); + hw[0] |= (src.index << NV40_FP_OP_INPUT_SRC_SHIFT); + break; + case NV40SR_OUTPUT: + sr |= NV40_FP_REG_SRC_HALF; + /* fall-through */ + case NV40SR_TEMP: + sr |= (NV40_FP_REG_TYPE_TEMP << NV40_FP_REG_TYPE_SHIFT); + sr |= (src.index << NV40_FP_REG_SRC_SHIFT); + break; + case NV40SR_CONST: + if (!fpc->have_const) { + grow_insns(fpc, 4); + fpc->have_const = 1; + } + + hw = &fp->insn[fpc->inst_offset]; + if (fpc->consts[src.index].pipe >= 0) { + struct nv40_fragment_program_data *fpd; + + fp->consts = realloc(fp->consts, ++fp->nr_consts * + sizeof(*fpd)); + fpd = &fp->consts[fp->nr_consts - 1]; + fpd->offset = fpc->inst_offset + 4; + fpd->index = fpc->consts[src.index].pipe; + memset(&fp->insn[fpd->offset], 0, sizeof(uint32_t) * 4); + } else { + memcpy(&fp->insn[fpc->inst_offset + 4], + fpc->consts[src.index].vals, + sizeof(uint32_t) * 4); + } + + sr |= (NV40_FP_REG_TYPE_CONST << NV40_FP_REG_TYPE_SHIFT); + break; + case NV40SR_NONE: + sr |= (NV40_FP_REG_TYPE_INPUT << NV40_FP_REG_TYPE_SHIFT); + break; + default: + assert(0); + } + + if (src.negate) + sr |= NV40_FP_REG_NEGATE; + + if (src.abs) + hw[1] |= (1 << (29 + pos)); + + sr |= ((src.swz[0] << NV40_FP_REG_SWZ_X_SHIFT) | + (src.swz[1] << NV40_FP_REG_SWZ_Y_SHIFT) | + (src.swz[2] << NV40_FP_REG_SWZ_Z_SHIFT) | + (src.swz[3] << NV40_FP_REG_SWZ_W_SHIFT)); + + hw[pos + 1] |= sr; +} + +static void +emit_dst(struct nv40_fpc *fpc, struct nv40_sreg dst) +{ + struct nv40_fragment_program *fp = fpc->fp; + uint32_t *hw = &fp->insn[fpc->inst_offset]; + + switch (dst.type) { + case NV40SR_TEMP: + if (fpc->num_regs < (dst.index + 1)) + fpc->num_regs = dst.index + 1; + break; + case NV40SR_OUTPUT: + if (dst.index == 1) { + fp->fp_control |= 0xe; + } else { + hw[0] |= NV40_FP_OP_OUT_REG_HALF; + } + break; + case NV40SR_NONE: + hw[0] |= (1 << 30); + break; + default: + assert(0); + } + + hw[0] |= (dst.index << NV40_FP_OP_OUT_REG_SHIFT); +} + +static void +nv40_fp_arith(struct nv40_fpc *fpc, int sat, int op, + struct nv40_sreg dst, int mask, + struct nv40_sreg s0, struct nv40_sreg s1, struct nv40_sreg s2) +{ + struct nv40_fragment_program *fp = fpc->fp; + uint32_t *hw; + + fpc->inst_offset = fp->insn_len; + fpc->have_const = 0; + grow_insns(fpc, 4); + hw = &fp->insn[fpc->inst_offset]; + memset(hw, 0, sizeof(uint32_t) * 4); + + if (op == NV40_FP_OP_OPCODE_KIL) + fp->fp_control |= NV40TCL_FP_CONTROL_KIL; + hw[0] |= (op << NV40_FP_OP_OPCODE_SHIFT); + hw[0] |= (mask << NV40_FP_OP_OUTMASK_SHIFT); + hw[2] |= (dst.dst_scale << NV40_FP_OP_DST_SCALE_SHIFT); + + if (sat) + hw[0] |= NV40_FP_OP_OUT_SAT; + + if (dst.cc_update) + hw[0] |= NV40_FP_OP_COND_WRITE_ENABLE; + hw[1] |= (dst.cc_test << NV40_FP_OP_COND_SHIFT); + hw[1] |= ((dst.cc_swz[0] << NV40_FP_OP_COND_SWZ_X_SHIFT) | + (dst.cc_swz[1] << NV40_FP_OP_COND_SWZ_Y_SHIFT) | + (dst.cc_swz[2] << NV40_FP_OP_COND_SWZ_Z_SHIFT) | + (dst.cc_swz[3] << NV40_FP_OP_COND_SWZ_W_SHIFT)); + + emit_dst(fpc, dst); + emit_src(fpc, 0, s0); + emit_src(fpc, 1, s1); + emit_src(fpc, 2, s2); +} + +static void +nv40_fp_tex(struct nv40_fpc *fpc, int sat, int op, int unit, + struct nv40_sreg dst, int mask, + struct nv40_sreg s0, struct nv40_sreg s1, struct nv40_sreg s2) +{ + struct nv40_fragment_program *fp = fpc->fp; + + nv40_fp_arith(fpc, sat, op, dst, mask, s0, s1, s2); + + fp->insn[fpc->inst_offset] |= (unit << NV40_FP_OP_TEX_UNIT_SHIFT); + fp->samplers |= (1 << unit); +} + +static INLINE struct nv40_sreg +tgsi_src(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc) +{ + struct nv40_sreg src; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + src = nv40_sr(NV40SR_INPUT, + fpc->attrib_map[fsrc->SrcRegister.Index]); + break; + case TGSI_FILE_CONSTANT: + src = constant(fpc, fsrc->SrcRegister.Index, NULL); + break; + case TGSI_FILE_IMMEDIATE: + assert(fsrc->SrcRegister.Index < fpc->nr_imm); + src = fpc->imm[fsrc->SrcRegister.Index]; + break; + case TGSI_FILE_TEMPORARY: + src = fpc->r_temp[fsrc->SrcRegister.Index]; + break; + /* NV40 fragprog result regs are just temps, so this is simple */ + case TGSI_FILE_OUTPUT: + src = fpc->r_result[fsrc->SrcRegister.Index]; + break; + default: + NOUVEAU_ERR("bad src file\n"); + break; + } + + src.abs = fsrc->SrcRegisterExtMod.Absolute; + src.negate = fsrc->SrcRegister.Negate; + src.swz[0] = fsrc->SrcRegister.SwizzleX; + src.swz[1] = fsrc->SrcRegister.SwizzleY; + src.swz[2] = fsrc->SrcRegister.SwizzleZ; + src.swz[3] = fsrc->SrcRegister.SwizzleW; + return src; +} + +static INLINE struct nv40_sreg +tgsi_dst(struct nv40_fpc *fpc, const struct tgsi_full_dst_register *fdst) { + switch (fdst->DstRegister.File) { + case TGSI_FILE_OUTPUT: + return fpc->r_result[fdst->DstRegister.Index]; + case TGSI_FILE_TEMPORARY: + return fpc->r_temp[fdst->DstRegister.Index]; + case TGSI_FILE_NULL: + return nv40_sr(NV40SR_NONE, 0); + default: + NOUVEAU_ERR("bad dst file %d\n", fdst->DstRegister.File); + return nv40_sr(NV40SR_NONE, 0); + } +} + +static INLINE int +tgsi_mask(uint tgsi) +{ + int mask = 0; + + if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X; + if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y; + if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z; + if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W; + return mask; +} + +static boolean +src_native_swz(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc, + struct nv40_sreg *src) +{ + const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + struct nv40_sreg tgsi = tgsi_src(fpc, fsrc); + uint mask = 0, zero_mask = 0, one_mask = 0, neg_mask = 0; + uint neg[4] = { fsrc->SrcRegisterExtSwz.NegateX, + fsrc->SrcRegisterExtSwz.NegateY, + fsrc->SrcRegisterExtSwz.NegateZ, + fsrc->SrcRegisterExtSwz.NegateW }; + uint c; + + for (c = 0; c < 4; c++) { + switch (tgsi_util_get_full_src_register_extswizzle(fsrc, c)) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + mask |= (1 << c); + break; + case TGSI_EXTSWIZZLE_ZERO: + zero_mask |= (1 << c); + tgsi.swz[c] = SWZ_X; + break; + case TGSI_EXTSWIZZLE_ONE: + one_mask |= (1 << c); + tgsi.swz[c] = SWZ_X; + break; + default: + assert(0); + } + + if (!tgsi.negate && neg[c]) + neg_mask |= (1 << c); + } + + if (mask == MASK_ALL && !neg_mask) + return TRUE; + + *src = temp(fpc); + + if (mask) + arith(fpc, 0, MOV, *src, mask, tgsi, none, none); + + if (zero_mask) + arith(fpc, 0, SFL, *src, zero_mask, *src, none, none); + + if (one_mask) + arith(fpc, 0, STR, *src, one_mask, *src, none, none); + + if (neg_mask) { + struct nv40_sreg one = temp(fpc); + arith(fpc, 0, STR, one, neg_mask, one, none, none); + arith(fpc, 0, MUL, *src, neg_mask, *src, neg(one), none); + } + + return FALSE; +} + +static boolean +nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, + const struct tgsi_full_instruction *finst) +{ + const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + struct nv40_sreg src[3], dst, tmp; + int mask, sat, unit; + int ai = -1, ci = -1, ii = -1; + int i; + + if (finst->Instruction.Opcode == TGSI_OPCODE_END) + return TRUE; + + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) { + src[i] = tgsi_src(fpc, fsrc); + } + } + + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + case TGSI_FILE_CONSTANT: + case TGSI_FILE_TEMPORARY: + if (!src_native_swz(fpc, fsrc, &src[i])) + continue; + break; + default: + break; + } + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + if (ai == -1 || ai == fsrc->SrcRegister.Index) { + ai = fsrc->SrcRegister.Index; + src[i] = tgsi_src(fpc, fsrc); + } else { + src[i] = temp(fpc); + arith(fpc, 0, MOV, src[i], MASK_ALL, + tgsi_src(fpc, fsrc), none, none); + } + break; + case TGSI_FILE_CONSTANT: + if ((ci == -1 && ii == -1) || + ci == fsrc->SrcRegister.Index) { + ci = fsrc->SrcRegister.Index; + src[i] = tgsi_src(fpc, fsrc); + } else { + src[i] = temp(fpc); + arith(fpc, 0, MOV, src[i], MASK_ALL, + tgsi_src(fpc, fsrc), none, none); + } + break; + case TGSI_FILE_IMMEDIATE: + if ((ci == -1 && ii == -1) || + ii == fsrc->SrcRegister.Index) { + ii = fsrc->SrcRegister.Index; + src[i] = tgsi_src(fpc, fsrc); + } else { + src[i] = temp(fpc); + arith(fpc, 0, MOV, src[i], MASK_ALL, + tgsi_src(fpc, fsrc), none, none); + } + break; + case TGSI_FILE_TEMPORARY: + /* handled above */ + break; + case TGSI_FILE_SAMPLER: + unit = fsrc->SrcRegister.Index; + break; + case TGSI_FILE_OUTPUT: + break; + default: + NOUVEAU_ERR("bad src file\n"); + return FALSE; + } + } + + dst = tgsi_dst(fpc, &finst->FullDstRegisters[0]); + mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask); + sat = (finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE); + + switch (finst->Instruction.Opcode) { + case TGSI_OPCODE_ABS: + arith(fpc, sat, MOV, dst, mask, abs(src[0]), none, none); + break; + case TGSI_OPCODE_ADD: + arith(fpc, sat, ADD, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_CMP: + tmp = temp(fpc); + arith(fpc, sat, MOV, dst, mask, src[2], none, none); + tmp.cc_update = 1; + arith(fpc, 0, MOV, tmp, 0xf, src[0], none, none); + dst.cc_test = NV40_VP_INST_COND_LT; + arith(fpc, sat, MOV, dst, mask, src[1], none, none); + break; + case TGSI_OPCODE_COS: + arith(fpc, sat, COS, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_DDX: + if (mask & (MASK_Z | MASK_W)) { + tmp = temp(fpc); + arith(fpc, sat, DDX, tmp, MASK_X | MASK_Y, + swz(src[0], Z, W, Z, W), none, none); + arith(fpc, 0, MOV, tmp, MASK_Z | MASK_W, + swz(tmp, X, Y, X, Y), none, none); + arith(fpc, sat, DDX, tmp, MASK_X | MASK_Y, src[0], + none, none); + arith(fpc, 0, MOV, dst, mask, tmp, none, none); + } else { + arith(fpc, sat, DDX, dst, mask, src[0], none, none); + } + break; + case TGSI_OPCODE_DDY: + if (mask & (MASK_Z | MASK_W)) { + tmp = temp(fpc); + arith(fpc, sat, DDY, tmp, MASK_X | MASK_Y, + swz(src[0], Z, W, Z, W), none, none); + arith(fpc, 0, MOV, tmp, MASK_Z | MASK_W, + swz(tmp, X, Y, X, Y), none, none); + arith(fpc, sat, DDY, tmp, MASK_X | MASK_Y, src[0], + none, none); + arith(fpc, 0, MOV, dst, mask, tmp, none, none); + } else { + arith(fpc, sat, DDY, dst, mask, src[0], none, none); + } + break; + case TGSI_OPCODE_DP3: + arith(fpc, sat, DP3, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DP4: + arith(fpc, sat, DP4, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DPH: + tmp = temp(fpc); + arith(fpc, 0, DP3, tmp, MASK_X, src[0], src[1], none); + arith(fpc, sat, ADD, dst, mask, swz(tmp, X, X, X, X), + swz(src[1], W, W, W, W), none); + break; + case TGSI_OPCODE_DST: + arith(fpc, sat, DST, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_EX2: + arith(fpc, sat, EX2, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_FLR: + arith(fpc, sat, FLR, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_FRC: + arith(fpc, sat, FRC, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_KIL: + arith(fpc, 0, KIL, none, 0, none, none, none); + break; + case TGSI_OPCODE_KILP: + dst = nv40_sr(NV40SR_NONE, 0); + dst.cc_update = 1; + arith(fpc, 0, MOV, dst, MASK_ALL, src[0], none, none); + dst.cc_update = 0; dst.cc_test = NV40_FP_OP_COND_LT; + arith(fpc, 0, KIL, dst, 0, none, none, none); + break; + case TGSI_OPCODE_LG2: + arith(fpc, sat, LG2, dst, mask, src[0], none, none); + break; +// case TGSI_OPCODE_LIT: + case TGSI_OPCODE_LRP: + tmp = temp(fpc); + arith(fpc, 0, MAD, tmp, mask, neg(src[0]), src[2], src[2]); + arith(fpc, sat, MAD, dst, mask, src[0], src[1], tmp); + break; + case TGSI_OPCODE_MAD: + arith(fpc, sat, MAD, dst, mask, src[0], src[1], src[2]); + break; + case TGSI_OPCODE_MAX: + arith(fpc, sat, MAX, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MIN: + arith(fpc, sat, MIN, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MOV: + arith(fpc, sat, MOV, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_MUL: + arith(fpc, sat, MUL, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_NOISE1: + case TGSI_OPCODE_NOISE2: + case TGSI_OPCODE_NOISE3: + case TGSI_OPCODE_NOISE4: + arith(fpc, sat, SFL, dst, mask, none, none, none); + break; + case TGSI_OPCODE_POW: + tmp = temp(fpc); + arith(fpc, 0, LG2, tmp, MASK_X, + swz(src[0], X, X, X, X), none, none); + arith(fpc, 0, MUL, tmp, MASK_X, swz(tmp, X, X, X, X), + swz(src[1], X, X, X, X), none); + arith(fpc, sat, EX2, dst, mask, + swz(tmp, X, X, X, X), none, none); + break; + case TGSI_OPCODE_RCP: + arith(fpc, sat, RCP, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_RET: + assert(0); + break; + case TGSI_OPCODE_RFL: + tmp = temp(fpc); + arith(fpc, 0, DP3, tmp, MASK_X, src[0], src[0], none); + arith(fpc, 0, DP3, tmp, MASK_Y, src[0], src[1], none); + arith(fpc, 0, DIV, scale(tmp, 2X), MASK_Z, + swz(tmp, Y, Y, Y, Y), swz(tmp, X, X, X, X), none); + arith(fpc, sat, MAD, dst, mask, + swz(tmp, Z, Z, Z, Z), src[0], neg(src[1])); + break; + case TGSI_OPCODE_RSQ: + tmp = temp(fpc); + arith(fpc, 0, LG2, scale(tmp, INV_2X), MASK_X, + abs(swz(src[0], X, X, X, X)), none, none); + arith(fpc, sat, EX2, dst, mask, + neg(swz(tmp, X, X, X, X)), none, none); + break; + case TGSI_OPCODE_SCS: + if (mask & MASK_X) { + arith(fpc, sat, COS, dst, MASK_X, + swz(src[0], X, X, X, X), none, none); + } + if (mask & MASK_Y) { + arith(fpc, sat, SIN, dst, MASK_Y, + swz(src[0], X, X, X, X), none, none); + } + break; + case TGSI_OPCODE_SEQ: + arith(fpc, sat, SEQ, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SFL: + arith(fpc, sat, SFL, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SGE: + arith(fpc, sat, SGE, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SGT: + arith(fpc, sat, SGT, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SIN: + arith(fpc, sat, SIN, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_SLE: + arith(fpc, sat, SLE, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SLT: + arith(fpc, sat, SLT, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SNE: + arith(fpc, sat, SNE, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_STR: + arith(fpc, sat, STR, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SUB: + arith(fpc, sat, ADD, dst, mask, src[0], neg(src[1]), none); + break; + case TGSI_OPCODE_TEX: + tex(fpc, sat, TEX, unit, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_TXB: + tex(fpc, sat, TXB, unit, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_TXP: + tex(fpc, sat, TXP, unit, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_XPD: + tmp = temp(fpc); + arith(fpc, 0, MUL, tmp, mask, + swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none); + arith(fpc, sat, MAD, dst, (mask & ~MASK_W), + swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y), + neg(tmp)); + break; + default: + NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode); + return FALSE; + } + + release_temps(fpc); + return TRUE; +} + +static boolean +nv40_fragprog_parse_decl_attrib(struct nv40_fpc *fpc, + const struct tgsi_full_declaration *fdec) +{ + int hw; + + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + hw = NV40_FP_OP_INPUT_SRC_POSITION; + break; + case TGSI_SEMANTIC_COLOR: + if (fdec->Semantic.SemanticIndex == 0) { + hw = NV40_FP_OP_INPUT_SRC_COL0; + } else + if (fdec->Semantic.SemanticIndex == 1) { + hw = NV40_FP_OP_INPUT_SRC_COL1; + } else { + NOUVEAU_ERR("bad colour semantic index\n"); + return FALSE; + } + break; + case TGSI_SEMANTIC_FOG: + hw = NV40_FP_OP_INPUT_SRC_FOGC; + break; + case TGSI_SEMANTIC_GENERIC: + if (fdec->Semantic.SemanticIndex <= 7) { + hw = NV40_FP_OP_INPUT_SRC_TC(fdec->Semantic. + SemanticIndex); + } else { + NOUVEAU_ERR("bad generic semantic index\n"); + return FALSE; + } + break; + default: + NOUVEAU_ERR("bad input semantic\n"); + return FALSE; + } + + fpc->attrib_map[fdec->DeclarationRange.First] = hw; + return TRUE; +} + +static boolean +nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, + const struct tgsi_full_declaration *fdec) +{ + unsigned idx = fdec->DeclarationRange.First; + unsigned hw; + + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + hw = 1; + break; + case TGSI_SEMANTIC_COLOR: + switch (fdec->Semantic.SemanticIndex) { + case 0: hw = 0; break; + case 1: hw = 2; break; + case 2: hw = 3; break; + case 3: hw = 4; break; + default: + NOUVEAU_ERR("bad rcol index\n"); + return FALSE; + } + break; + default: + NOUVEAU_ERR("bad output semantic\n"); + return FALSE; + } + + fpc->r_result[idx] = nv40_sr(NV40SR_OUTPUT, hw); + fpc->r_temps |= (1 << hw); + return TRUE; +} + +static boolean +nv40_fragprog_prepare(struct nv40_fpc *fpc) +{ + struct tgsi_parse_context p; + int high_temp = -1, i; + + tgsi_parse_init(&p, fpc->fp->pipe.tokens); + while (!tgsi_parse_end_of_tokens(&p)) { + const union tgsi_full_token *tok = &p.FullToken; + + tgsi_parse_token(&p); + switch(tok->Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *fdec; + fdec = &p.FullToken.FullDeclaration; + switch (fdec->Declaration.File) { + case TGSI_FILE_INPUT: + if (!nv40_fragprog_parse_decl_attrib(fpc, fdec)) + goto out_err; + break; + case TGSI_FILE_OUTPUT: + if (!nv40_fragprog_parse_decl_output(fpc, fdec)) + goto out_err; + break; + case TGSI_FILE_TEMPORARY: + if (fdec->DeclarationRange.Last > high_temp) { + high_temp = + fdec->DeclarationRange.Last; + } + break; + default: + break; + } + } + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *imm; + float vals[4]; + + imm = &p.FullToken.FullImmediate; + assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); + assert(fpc->nr_imm < MAX_IMM); + + vals[0] = imm->u.ImmediateFloat32[0].Float; + vals[1] = imm->u.ImmediateFloat32[1].Float; + vals[2] = imm->u.ImmediateFloat32[2].Float; + vals[3] = imm->u.ImmediateFloat32[3].Float; + fpc->imm[fpc->nr_imm++] = constant(fpc, -1, vals); + } + break; + default: + break; + } + } + tgsi_parse_free(&p); + + if (++high_temp) { + fpc->r_temp = CALLOC(high_temp, sizeof(struct nv40_sreg)); + for (i = 0; i < high_temp; i++) + fpc->r_temp[i] = temp(fpc); + fpc->r_temps_discard = 0; + } + + return TRUE; + +out_err: + if (fpc->r_temp) + FREE(fpc->r_temp); + tgsi_parse_free(&p); + return FALSE; +} + +static void +nv40_fragprog_translate(struct nv40_context *nv40, + struct nv40_fragment_program *fp) +{ + struct tgsi_parse_context parse; + struct nv40_fpc *fpc = NULL; + + fpc = CALLOC(1, sizeof(struct nv40_fpc)); + if (!fpc) + return; + fpc->fp = fp; + fpc->num_regs = 2; + + if (!nv40_fragprog_prepare(fpc)) { + FREE(fpc); + return; + } + + tgsi_parse_init(&parse, fp->pipe.tokens); + + while (!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + const struct tgsi_full_instruction *finst; + + finst = &parse.FullToken.FullInstruction; + if (!nv40_fragprog_parse_instruction(fpc, finst)) + goto out_err; + } + break; + default: + break; + } + } + + fp->fp_control |= fpc->num_regs << NV40TCL_FP_CONTROL_TEMP_COUNT_SHIFT; + + /* Terminate final instruction */ + fp->insn[fpc->inst_offset] |= 0x00000001; + + /* Append NOP + END instruction, may or may not be necessary. */ + fpc->inst_offset = fp->insn_len; + grow_insns(fpc, 4); + fp->insn[fpc->inst_offset + 0] = 0x00000001; + fp->insn[fpc->inst_offset + 1] = 0x00000000; + fp->insn[fpc->inst_offset + 2] = 0x00000000; + fp->insn[fpc->inst_offset + 3] = 0x00000000; + + fp->translated = TRUE; +out_err: + tgsi_parse_free(&parse); + if (fpc->r_temp) + FREE(fpc->r_temp); + FREE(fpc); +} + +static void +nv40_fragprog_upload(struct nv40_context *nv40, + struct nv40_fragment_program *fp) +{ + struct pipe_winsys *ws = nv40->pipe.winsys; + const uint32_t le = 1; + uint32_t *map; + int i; + + map = ws->buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + +#if 0 + for (i = 0; i < fp->insn_len; i++) { + fflush(stdout); fflush(stderr); + NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]); + fflush(stdout); fflush(stderr); + } +#endif + + if ((*(const uint8_t *)&le)) { + for (i = 0; i < fp->insn_len; i++) { + map[i] = fp->insn[i]; + } + } else { + /* Weird swapping for big-endian chips */ + for (i = 0; i < fp->insn_len; i++) { + map[i] = ((fp->insn[i] & 0xffff) << 16) | + ((fp->insn[i] >> 16) & 0xffff); + } + } + + ws->buffer_unmap(ws, fp->buffer); +} + +static boolean +nv40_fragprog_validate(struct nv40_context *nv40) +{ + struct nv40_fragment_program *fp = nv40->fragprog; + struct pipe_buffer *constbuf = + nv40->constbuf[PIPE_SHADER_FRAGMENT]; + struct pipe_winsys *ws = nv40->pipe.winsys; + struct nouveau_stateobj *so; + boolean new_consts = FALSE; + int i; + + if (fp->translated) + goto update_constants; + + nv40->fallback_swrast &= ~NV40_NEW_FRAGPROG; + nv40_fragprog_translate(nv40, fp); + if (!fp->translated) { + nv40->fallback_swrast |= NV40_NEW_FRAGPROG; + return FALSE; + } + + fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); + nv40_fragprog_upload(nv40, fp); + + so = so_new(4, 1); + so_method(so, nv40->screen->curie, NV40TCL_FP_ADDRESS, 1); + so_reloc (so, fp->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, + NV40TCL_FP_ADDRESS_DMA0, NV40TCL_FP_ADDRESS_DMA1); + so_method(so, nv40->screen->curie, NV40TCL_FP_CONTROL, 1); + so_data (so, fp->fp_control); + so_ref(so, &fp->so); + +update_constants: + if (fp->nr_consts) { + float *map; + + map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); + for (i = 0; i < fp->nr_consts; i++) { + struct nv40_fragment_program_data *fpd = &fp->consts[i]; + uint32_t *p = &fp->insn[fpd->offset]; + uint32_t *cb = (uint32_t *)&map[fpd->index * 4]; + + if (!memcmp(p, cb, 4 * sizeof(float))) + continue; + memcpy(p, cb, 4 * sizeof(float)); + new_consts = TRUE; + } + ws->buffer_unmap(ws, constbuf); + + if (new_consts) + nv40_fragprog_upload(nv40, fp); + } + + if (new_consts || fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) { + so_ref(fp->so, &nv40->state.hw[NV40_STATE_FRAGPROG]); + return TRUE; + } + + return FALSE; +} + +void +nv40_fragprog_destroy(struct nv40_context *nv40, + struct nv40_fragment_program *fp) +{ + if (fp->insn_len) + FREE(fp->insn); +} + +struct nv40_state_entry nv40_state_fragprog = { + .validate = nv40_fragprog_validate, + .dirty = { + .pipe = NV40_NEW_FRAGPROG, + .hw = NV40_STATE_FRAGPROG + } +}; + diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c new file mode 100644 index 00000000000..c79ea8becb3 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -0,0 +1,167 @@ +#include "nv40_context.h" + +#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \ +{ \ + TRUE, \ + PIPE_FORMAT_##m, \ + NV40TCL_TEX_FORMAT_FORMAT_##tf, \ + (NV40TCL_TEX_SWIZZLE_S0_X_##ts0x | NV40TCL_TEX_SWIZZLE_S0_Y_##ts0y | \ + NV40TCL_TEX_SWIZZLE_S0_Z_##ts0z | NV40TCL_TEX_SWIZZLE_S0_W_##ts0w | \ + NV40TCL_TEX_SWIZZLE_S1_X_##ts1x | NV40TCL_TEX_SWIZZLE_S1_Y_##ts1y | \ + NV40TCL_TEX_SWIZZLE_S1_Z_##ts1z | NV40TCL_TEX_SWIZZLE_S1_W_##ts1w), \ +} + +struct nv40_texture_format { + boolean defined; + uint pipe; + int format; + int swizzle; +}; + +static struct nv40_texture_format +nv40_texture_formats[] = { + _(A8R8G8B8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W), + _(A1R5G5B5_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W), + _(A4R4G4B4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W), + _(R5G6B5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W), + _(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X), + _(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X), + _(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X), + _(A8L8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y), + _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X), + _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X), + _(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W), + _(DXT1_RGBA , DXT1 , S1, S1, S1, S1, X, Y, Z, W), + _(DXT3_RGBA , DXT3 , S1, S1, S1, S1, X, Y, Z, W), + _(DXT5_RGBA , DXT5 , S1, S1, S1, S1, X, Y, Z, W), + {}, +}; + +static struct nv40_texture_format * +nv40_fragtex_format(uint pipe_format) +{ + struct nv40_texture_format *tf = nv40_texture_formats; + char fs[128]; + + while (tf->defined) { + if (tf->pipe == pipe_format) + return tf; + tf++; + } + + pf_sprint_name(fs, pipe_format); + NOUVEAU_ERR("unknown texture format %s\n", fs); + return NULL; +} + + +static struct nouveau_stateobj * +nv40_fragtex_build(struct nv40_context *nv40, int unit) +{ + struct nv40_sampler_state *ps = nv40->tex_sampler[unit]; + struct nv40_miptree *nv40mt = nv40->tex_miptree[unit]; + struct pipe_texture *pt = &nv40mt->base; + struct nv40_texture_format *tf; + struct nouveau_stateobj *so; + uint32_t txf, txs, txp; + int swizzled = 0; /*XXX: implement in region code? */ + unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + + tf = nv40_fragtex_format(pt->format); + if (!tf) + assert(0); + + txf = ps->fmt; + txf |= tf->format | 0x8000; + txf |= ((pt->last_level + 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT); + + if (1) /* XXX */ + txf |= NV40TCL_TEX_FORMAT_NO_BORDER; + + switch (pt->target) { + case PIPE_TEXTURE_CUBE: + txf |= NV40TCL_TEX_FORMAT_CUBIC; + /* fall-through */ + case PIPE_TEXTURE_2D: + txf |= NV40TCL_TEX_FORMAT_DIMS_2D; + break; + case PIPE_TEXTURE_3D: + txf |= NV40TCL_TEX_FORMAT_DIMS_3D; + break; + case PIPE_TEXTURE_1D: + txf |= NV40TCL_TEX_FORMAT_DIMS_1D; + break; + default: + NOUVEAU_ERR("Unknown target %d\n", pt->target); + return NULL; + } + + if (swizzled) { + txp = 0; + } else { + txp = nv40mt->level[0].pitch; + txf |= NV40TCL_TEX_FORMAT_LINEAR; + } + + txs = tf->swizzle; + + so = so_new(16, 2); + so_method(so, nv40->screen->curie, NV40TCL_TEX_OFFSET(unit), 8); + so_reloc (so, nv40mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0); + so_reloc (so, nv40mt->buffer, txf, tex_flags | NOUVEAU_BO_OR, + NV40TCL_TEX_FORMAT_DMA0, NV40TCL_TEX_FORMAT_DMA1); + so_data (so, ps->wrap); + so_data (so, NV40TCL_TEX_ENABLE_ENABLE | ps->en); + so_data (so, txs); + so_data (so, ps->filt | 0x2000 /*voodoo*/); + so_data (so, (pt->width[0] << NV40TCL_TEX_SIZE0_W_SHIFT) | + pt->height[0]); + so_data (so, ps->bcol); + so_method(so, nv40->screen->curie, NV40TCL_TEX_SIZE1(unit), 1); + so_data (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); + + return so; +} + +static boolean +nv40_fragtex_validate(struct nv40_context *nv40) +{ + struct nv40_fragment_program *fp = nv40->fragprog; + struct nv40_state *state = &nv40->state; + struct nouveau_stateobj *so; + unsigned samplers, unit; + + samplers = state->fp_samplers & ~fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + so = so_new(2, 0); + so_method(so, nv40->screen->curie, NV40TCL_TEX_ENABLE(unit), 1); + so_data (so, 0); + so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); + state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit)); + } + + samplers = nv40->dirty_samplers & fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + so = nv40_fragtex_build(nv40, unit); + so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); + state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit)); + } + + nv40->state.fp_samplers = fp->samplers; + return FALSE; +} + +struct nv40_state_entry nv40_state_fragtex = { + .validate = nv40_fragtex_validate, + .dirty = { + .pipe = NV40_NEW_SAMPLER | NV40_NEW_FRAGPROG, + .hw = 0 + } +}; + diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c new file mode 100644 index 00000000000..23da6e36a3e --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -0,0 +1,148 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nv40_context.h" + +static void +nv40_miptree_layout(struct nv40_miptree *nv40mt) +{ + struct pipe_texture *pt = &nv40mt->base; + boolean swizzled = FALSE; + uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; + uint offset = 0; + int nr_faces, l, f, pitch; + + if (pt->target == PIPE_TEXTURE_CUBE) { + nr_faces = 6; + } else + if (pt->target == PIPE_TEXTURE_3D) { + nr_faces = pt->depth[0]; + } else { + nr_faces = 1; + } + + pitch = pt->width[0]; + for (l = 0; l <= pt->last_level; l++) { + pt->width[l] = width; + pt->height[l] = height; + pt->depth[l] = depth; + + if (swizzled) + pitch = pt->width[l]; + pitch = (pitch + 63) & ~63; + + nv40mt->level[l].pitch = pitch * pt->cpp; + nv40mt->level[l].image_offset = + CALLOC(nr_faces, sizeof(unsigned)); + + width = MAX2(1, width >> 1); + height = MAX2(1, height >> 1); + depth = MAX2(1, depth >> 1); + + } + + for (f = 0; f < nr_faces; f++) { + for (l = 0; l <= pt->last_level; l++) { + nv40mt->level[l].image_offset[f] = offset; + offset += nv40mt->level[l].pitch * pt->height[l]; + } + } + + nv40mt->total_size = offset; +} + +static struct pipe_texture * +nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) +{ + struct pipe_winsys *ws = pscreen->winsys; + struct nv40_miptree *mt; + + mt = MALLOC(sizeof(struct nv40_miptree)); + if (!mt) + return NULL; + mt->base = *pt; + mt->base.refcount = 1; + mt->base.screen = pscreen; + + nv40_miptree_layout(mt); + + mt->buffer = ws->buffer_create(ws, 256, + PIPE_BUFFER_USAGE_PIXEL | + NOUVEAU_BUFFER_USAGE_TEXTURE, + mt->total_size); + if (!mt->buffer) { + FREE(mt); + return NULL; + } + + return &mt->base; +} + +static void +nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) +{ + struct pipe_winsys *ws = pscreen->winsys; + struct pipe_texture *mt = *pt; + + *pt = NULL; + if (--mt->refcount <= 0) { + struct nv40_miptree *nv40mt = (struct nv40_miptree *)mt; + int l; + + pipe_buffer_reference(ws, &nv40mt->buffer, NULL); + for (l = 0; l <= mt->last_level; l++) { + if (nv40mt->level[l].image_offset) + FREE(nv40mt->level[l].image_offset); + } + FREE(nv40mt); + } +} + +static struct pipe_surface * +nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) +{ + struct pipe_winsys *ws = pscreen->winsys; + struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; + struct pipe_surface *ps; + + ps = ws->surface_alloc(ws); + if (!ps) + return NULL; + pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = nv40mt->level[level].pitch / ps->cpp; + + if (pt->target == PIPE_TEXTURE_CUBE) { + ps->offset = nv40mt->level[level].image_offset[face]; + } else + if (pt->target == PIPE_TEXTURE_3D) { + ps->offset = nv40mt->level[level].image_offset[zslice]; + } else { + ps->offset = nv40mt->level[level].image_offset[0]; + } + + return ps; +} + +static void +nv40_miptree_surface_del(struct pipe_screen *pscreen, + struct pipe_surface **psurface) +{ +} + +void +nv40_screen_init_miptree_functions(struct pipe_screen *pscreen) +{ + pscreen->texture_create = nv40_miptree_create; + pscreen->texture_release = nv40_miptree_release; + pscreen->get_tex_surface = nv40_miptree_surface_new; + pscreen->tex_surface_release = nv40_miptree_surface_del; +} + diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c new file mode 100644 index 00000000000..57f39cfab0c --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -0,0 +1,122 @@ +#include "pipe/p_context.h" + +#include "nv40_context.h" + +struct nv40_query { + struct nouveau_resource *object; + unsigned type; + boolean ready; + uint64_t result; +}; + +static INLINE struct nv40_query * +nv40_query(struct pipe_query *pipe) +{ + return (struct nv40_query *)pipe; +} + +static struct pipe_query * +nv40_query_create(struct pipe_context *pipe, unsigned query_type) +{ + struct nv40_query *q; + + q = CALLOC(1, sizeof(struct nv40_query)); + q->type = query_type; + + return (struct pipe_query *)q; +} + +static void +nv40_query_destroy(struct pipe_context *pipe, struct pipe_query *pq) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_query *q = nv40_query(pq); + + if (q->object) + nv40->nvws->res_free(&q->object); + FREE(q); +} + +static void +nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_query *q = nv40_query(pq); + + assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER); + + /* Happens when end_query() is called, then another begin_query() + * without querying the result in-between. For now we'll wait for + * the existing query to notify completion, but it could be better. + */ + if (q->object) { + uint64 tmp; + pipe->get_query_result(pipe, pq, 1, &tmp); + } + + if (nv40->nvws->res_alloc(nv40->screen->query_heap, 1, NULL, &q->object)) + assert(0); + nv40->nvws->notifier_reset(nv40->screen->query, q->object->start); + + BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1); + OUT_RING (1); + BEGIN_RING(curie, NV40TCL_QUERY_UNK17CC, 1); + OUT_RING (1); + + q->ready = FALSE; +} + +static void +nv40_query_end(struct pipe_context *pipe, struct pipe_query *pq) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_query *q = nv40_query(pq); + + BEGIN_RING(curie, NV40TCL_QUERY_GET, 1); + OUT_RING ((0x01 << NV40TCL_QUERY_GET_UNK24_SHIFT) | + ((q->object->start * 32) << NV40TCL_QUERY_GET_OFFSET_SHIFT)); + FIRE_RING(NULL); +} + +static boolean +nv40_query_result(struct pipe_context *pipe, struct pipe_query *pq, + boolean wait, uint64 *result) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_query *q = nv40_query(pq); + struct nouveau_winsys *nvws = nv40->nvws; + + assert(q->object && q->type == PIPE_QUERY_OCCLUSION_COUNTER); + + if (!q->ready) { + unsigned status; + + status = nvws->notifier_status(nv40->screen->query, + q->object->start); + if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) { + if (wait == FALSE) + return FALSE; + nvws->notifier_wait(nv40->screen->query, q->object->start, + NV_NOTIFY_STATE_STATUS_COMPLETED, + 0); + } + + q->result = nvws->notifier_retval(nv40->screen->query, + q->object->start); + q->ready = TRUE; + nvws->res_free(&q->object); + } + + *result = q->result; + return TRUE; +} + +void +nv40_init_query_functions(struct nv40_context *nv40) +{ + nv40->pipe.create_query = nv40_query_create; + nv40->pipe.destroy_query = nv40_query_destroy; + nv40->pipe.begin_query = nv40_query_begin; + nv40->pipe.end_query = nv40_query_end; + nv40->pipe.get_query_result = nv40_query_result; +} diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c new file mode 100644 index 00000000000..ed0215b4862 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -0,0 +1,314 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" +#include "nv40_screen.h" + +#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf +#define NV4X_GRCLASS4497_CHIPSETS 0x00005450 +#define NV6X_GRCLASS4497_CHIPSETS 0x00000088 + +static const char * +nv40_screen_get_name(struct pipe_screen *pscreen) +{ + struct nv40_screen *screen = nv40_screen(pscreen); + struct nouveau_device *dev = screen->nvws->channel->device; + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); + return buffer; +} + +static const char * +nv40_screen_get_vendor(struct pipe_screen *pscreen) +{ + return "nouveau"; +} + +static int +nv40_screen_get_param(struct pipe_screen *pscreen, int param) +{ + struct nv40_screen *screen = nv40_screen(pscreen); + + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 16; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 1; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 1; + case PIPE_CAP_POINT_SPRITE: + return 1; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 4; + case PIPE_CAP_OCCLUSION_QUERY: + return 1; + 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 NOUVEAU_CAP_HW_VTXBUF: + return 1; + case NOUVEAU_CAP_HW_IDXBUF: + if (screen->curie->grclass == NV40TCL) + return 1; + return 0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv40_screen_get_paramf(struct pipe_screen *pscreen, int 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 16.0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0.0; + } +} + +static boolean +nv40_screen_surface_format_supported(struct pipe_screen *pscreen, + enum pipe_format format, uint type) +{ + switch (type) { + case PIPE_SURFACE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + return TRUE; + default: + break; + } + break; + case PIPE_TEXTURE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A4R4G4B4_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_A8L8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static void * +nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, + unsigned flags ) +{ + struct pipe_winsys *ws = screen->winsys; + void *map; + + map = ws->buffer_map(ws, surface->buffer, flags); + if (!map) + return NULL; + + return map + surface->offset; +} + +static void +nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) +{ + struct pipe_winsys *ws = screen->winsys; + + ws->buffer_unmap(ws, surface->buffer); +} + +static void +nv40_screen_destroy(struct pipe_screen *pscreen) +{ + struct nv40_screen *screen = nv40_screen(pscreen); + struct nouveau_winsys *nvws = screen->nvws; + + nvws->res_free(&screen->vp_exec_heap); + nvws->res_free(&screen->vp_data_heap); + nvws->res_free(&screen->query_heap); + nvws->notifier_free(&screen->query); + nvws->notifier_free(&screen->sync); + nvws->grobj_free(&screen->curie); + + FREE(pscreen); +} + +struct pipe_screen * +nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) +{ + struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); + struct nouveau_stateobj *so; + unsigned curie_class; + unsigned chipset = nvws->channel->device->chipset; + int ret; + + if (!screen) + return NULL; + screen->nvws = nvws; + + /* 3D object */ + switch (chipset & 0xf0) { + case 0x40: + if (NV4X_GRCLASS4097_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV40TCL; + else + if (NV4X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV44TCL; + break; + case 0x60: + if (NV6X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV44TCL; + break; + default: + break; + } + + if (!curie_class) { + NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", chipset); + return NULL; + } + + ret = nvws->grobj_alloc(nvws, curie_class, &screen->curie); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return FALSE; + } + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &screen->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + /* Query objects */ + ret = nvws->notifier_alloc(nvws, 32, &screen->query); + if (ret) { + NOUVEAU_ERR("Error initialising query objects: %d\n", ret); + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + ret = nvws->res_init(&screen->query_heap, 0, 32); + if (ret) { + NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + /* Vtxprog resources */ + if (nvws->res_init(&screen->vp_exec_heap, 0, 512) || + nvws->res_init(&screen->vp_data_heap, 0, 256)) { + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + /* Static curie initialisation */ + so = so_new(128, 0); + so_method(so, screen->curie, NV40TCL_DMA_NOTIFY, 1); + so_data (so, screen->sync->handle); + so_method(so, screen->curie, NV40TCL_DMA_TEXTURE0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, screen->curie, NV40TCL_DMA_COLOR1, 1); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->curie, NV40TCL_DMA_COLOR0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->curie, NV40TCL_DMA_VTXBUF0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, screen->curie, NV40TCL_DMA_FENCE, 2); + so_data (so, 0); + so_data (so, screen->query->handle); + so_method(so, screen->curie, NV40TCL_DMA_UNK01AC, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->curie, NV40TCL_DMA_COLOR2, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + + so_method(so, screen->curie, 0x1ea4, 3); + so_data (so, 0x00000010); + so_data (so, 0x01000100); + so_data (so, 0xff800006); + + /* vtxprog output routing */ + so_method(so, screen->curie, 0x1fc4, 1); + so_data (so, 0x06144321); + so_method(so, screen->curie, 0x1fc8, 2); + so_data (so, 0xedcba987); + so_data (so, 0x00000021); + so_method(so, screen->curie, 0x1fd0, 1); + so_data (so, 0x00171615); + so_method(so, screen->curie, 0x1fd4, 1); + so_data (so, 0x001b1a19); + + so_method(so, screen->curie, 0x1ef8, 1); + so_data (so, 0x0020ffff); + so_method(so, screen->curie, 0x1d64, 1); + so_data (so, 0x00d30000); + so_method(so, screen->curie, 0x1e94, 1); + so_data (so, 0x00000001); + + so_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws, 0, NULL); + + screen->pipe.winsys = ws; + screen->pipe.destroy = nv40_screen_destroy; + + screen->pipe.get_name = nv40_screen_get_name; + screen->pipe.get_vendor = nv40_screen_get_vendor; + screen->pipe.get_param = nv40_screen_get_param; + screen->pipe.get_paramf = nv40_screen_get_paramf; + + screen->pipe.is_format_supported = nv40_screen_surface_format_supported; + + screen->pipe.surface_map = nv40_surface_map; + screen->pipe.surface_unmap = nv40_surface_unmap; + + nv40_screen_init_miptree_functions(&screen->pipe); + + return &screen->pipe; +} + diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h new file mode 100644 index 00000000000..c04a1275a00 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -0,0 +1,35 @@ +#ifndef __NV40_SCREEN_H__ +#define __NV40_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv40_screen { + struct pipe_screen pipe; + + struct nouveau_winsys *nvws; + + unsigned cur_pctx; + + /* HW graphics objects */ + struct nouveau_grobj *curie; + struct nouveau_notifier *sync; + + /* Query object resources */ + struct nouveau_notifier *query; + struct nouveau_resource *query_heap; + + /* Vtxprog resources */ + struct nouveau_resource *vp_exec_heap; + struct nouveau_resource *vp_data_heap; + + /* Current 3D state of channel */ + struct nouveau_stateobj *state[NV40_STATE_MAX]; +}; + +static INLINE struct nv40_screen * +nv40_screen(struct pipe_screen *screen) +{ + return (struct nv40_screen *)screen; +} + +#endif diff --git a/src/gallium/drivers/nv40/nv40_shader.h b/src/gallium/drivers/nv40/nv40_shader.h new file mode 100644 index 00000000000..854dccf5486 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_shader.h @@ -0,0 +1,556 @@ +#ifndef __NV40_SHADER_H__ +#define __NV40_SHADER_H__ + +/* Vertex programs instruction set + * + * The NV40 instruction set is very similar to NV30. Most fields are in + * a slightly different position in the instruction however. + * + * Merged instructions + * In some cases it is possible to put two instructions into one opcode + * slot. The rules for when this is OK is not entirely clear to me yet. + * + * There are separate writemasks and dest temp register fields for each + * grouping of instructions. There is however only one field with the + * ID of a result register. Writing to temp/result regs is selected by + * setting VEC_RESULT/SCA_RESULT. + * + * Temporary registers + * The source/dest temp register fields have been extended by 1 bit, to + * give a total of 32 temporary registers. + * + * Relative Addressing + * NV40 can use an address register to index into vertex attribute regs. + * This is done by putting the offset value into INPUT_SRC and setting + * the INDEX_INPUT flag. + * + * Conditional execution (see NV_vertex_program{2,3} for details) + * There is a second condition code register on NV40, it's use is enabled + * by setting the COND_REG_SELECT_1 flag. + * + * Texture lookup + * TODO + */ + +/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */ +#define NV40_VP_INST_VEC_RESULT (1 << 30) +/* uncertain.. */ +#define NV40_VP_INST_COND_UPDATE_ENABLE ((1 << 14)|1<<29) +/* use address reg as index into attribs */ +#define NV40_VP_INST_INDEX_INPUT (1 << 27) +#define NV40_VP_INST_COND_REG_SELECT_1 (1 << 25) +#define NV40_VP_INST_ADDR_REG_SELECT_1 (1 << 24) +#define NV40_VP_INST_SRC2_ABS (1 << 23) +#define NV40_VP_INST_SRC1_ABS (1 << 22) +#define NV40_VP_INST_SRC0_ABS (1 << 21) +#define NV40_VP_INST_VEC_DEST_TEMP_SHIFT 15 +#define NV40_VP_INST_VEC_DEST_TEMP_MASK (0x1F << 15) +#define NV40_VP_INST_COND_TEST_ENABLE (1 << 13) +#define NV40_VP_INST_COND_SHIFT 10 +#define NV40_VP_INST_COND_MASK (0x7 << 10) +# define NV40_VP_INST_COND_FL 0 +# define NV40_VP_INST_COND_LT 1 +# define NV40_VP_INST_COND_EQ 2 +# define NV40_VP_INST_COND_LE 3 +# define NV40_VP_INST_COND_GT 4 +# define NV40_VP_INST_COND_NE 5 +# define NV40_VP_INST_COND_GE 6 +# define NV40_VP_INST_COND_TR 7 +#define NV40_VP_INST_COND_SWZ_X_SHIFT 8 +#define NV40_VP_INST_COND_SWZ_X_MASK (3 << 8) +#define NV40_VP_INST_COND_SWZ_Y_SHIFT 6 +#define NV40_VP_INST_COND_SWZ_Y_MASK (3 << 6) +#define NV40_VP_INST_COND_SWZ_Z_SHIFT 4 +#define NV40_VP_INST_COND_SWZ_Z_MASK (3 << 4) +#define NV40_VP_INST_COND_SWZ_W_SHIFT 2 +#define NV40_VP_INST_COND_SWZ_W_MASK (3 << 2) +#define NV40_VP_INST_COND_SWZ_ALL_SHIFT 2 +#define NV40_VP_INST_COND_SWZ_ALL_MASK (0xFF << 2) +#define NV40_VP_INST_ADDR_SWZ_SHIFT 0 +#define NV40_VP_INST_ADDR_SWZ_MASK (0x03 << 0) +#define NV40_VP_INST0_KNOWN ( \ + NV40_VP_INST_INDEX_INPUT | \ + NV40_VP_INST_COND_REG_SELECT_1 | \ + NV40_VP_INST_ADDR_REG_SELECT_1 | \ + NV40_VP_INST_SRC2_ABS | \ + NV40_VP_INST_SRC1_ABS | \ + NV40_VP_INST_SRC0_ABS | \ + NV40_VP_INST_VEC_DEST_TEMP_MASK | \ + NV40_VP_INST_COND_TEST_ENABLE | \ + NV40_VP_INST_COND_MASK | \ + NV40_VP_INST_COND_SWZ_ALL_MASK | \ + NV40_VP_INST_ADDR_SWZ_MASK) + +/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */ +#define NV40_VP_INST_VEC_OPCODE_SHIFT 22 +#define NV40_VP_INST_VEC_OPCODE_MASK (0x1F << 22) +# define NV40_VP_INST_OP_NOP 0x00 +# define NV40_VP_INST_OP_MOV 0x01 +# define NV40_VP_INST_OP_MUL 0x02 +# define NV40_VP_INST_OP_ADD 0x03 +# define NV40_VP_INST_OP_MAD 0x04 +# define NV40_VP_INST_OP_DP3 0x05 +# define NV40_VP_INST_OP_DPH 0x06 +# define NV40_VP_INST_OP_DP4 0x07 +# define NV40_VP_INST_OP_DST 0x08 +# define NV40_VP_INST_OP_MIN 0x09 +# define NV40_VP_INST_OP_MAX 0x0A +# define NV40_VP_INST_OP_SLT 0x0B +# define NV40_VP_INST_OP_SGE 0x0C +# define NV40_VP_INST_OP_ARL 0x0D +# define NV40_VP_INST_OP_FRC 0x0E +# define NV40_VP_INST_OP_FLR 0x0F +# define NV40_VP_INST_OP_SEQ 0x10 +# define NV40_VP_INST_OP_SFL 0x11 +# define NV40_VP_INST_OP_SGT 0x12 +# define NV40_VP_INST_OP_SLE 0x13 +# define NV40_VP_INST_OP_SNE 0x14 +# define NV40_VP_INST_OP_STR 0x15 +# define NV40_VP_INST_OP_SSG 0x16 +# define NV40_VP_INST_OP_ARR 0x17 +# define NV40_VP_INST_OP_ARA 0x18 +# define NV40_VP_INST_OP_TXL 0x19 +#define NV40_VP_INST_SCA_OPCODE_SHIFT 27 +#define NV40_VP_INST_SCA_OPCODE_MASK (0x1F << 27) +# define NV40_VP_INST_OP_NOP 0x00 +# define NV40_VP_INST_OP_MOV 0x01 +# define NV40_VP_INST_OP_RCP 0x02 +# define NV40_VP_INST_OP_RCC 0x03 +# define NV40_VP_INST_OP_RSQ 0x04 +# define NV40_VP_INST_OP_EXP 0x05 +# define NV40_VP_INST_OP_LOG 0x06 +# define NV40_VP_INST_OP_LIT 0x07 +# define NV40_VP_INST_OP_BRA 0x09 +# define NV40_VP_INST_OP_CAL 0x0B +# define NV40_VP_INST_OP_RET 0x0C +# define NV40_VP_INST_OP_LG2 0x0D +# define NV40_VP_INST_OP_EX2 0x0E +# define NV40_VP_INST_OP_SIN 0x0F +# define NV40_VP_INST_OP_COS 0x10 +# define NV40_VP_INST_OP_PUSHA 0x13 +# define NV40_VP_INST_OP_POPA 0x14 +#define NV40_VP_INST_CONST_SRC_SHIFT 12 +#define NV40_VP_INST_CONST_SRC_MASK (0xFF << 12) +#define NV40_VP_INST_INPUT_SRC_SHIFT 8 +#define NV40_VP_INST_INPUT_SRC_MASK (0x0F << 8) +# define NV40_VP_INST_IN_POS 0 +# define NV40_VP_INST_IN_WEIGHT 1 +# define NV40_VP_INST_IN_NORMAL 2 +# define NV40_VP_INST_IN_COL0 3 +# define NV40_VP_INST_IN_COL1 4 +# define NV40_VP_INST_IN_FOGC 5 +# define NV40_VP_INST_IN_TC0 8 +# define NV40_VP_INST_IN_TC(n) (8+n) +#define NV40_VP_INST_SRC0H_SHIFT 0 +#define NV40_VP_INST_SRC0H_MASK (0xFF << 0) +#define NV40_VP_INST1_KNOWN ( \ + NV40_VP_INST_VEC_OPCODE_MASK | \ + NV40_VP_INST_SCA_OPCODE_MASK | \ + NV40_VP_INST_CONST_SRC_MASK | \ + NV40_VP_INST_INPUT_SRC_MASK | \ + NV40_VP_INST_SRC0H_MASK \ + ) + +/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */ +#define NV40_VP_INST_SRC0L_SHIFT 23 +#define NV40_VP_INST_SRC0L_MASK (0x1FF << 23) +#define NV40_VP_INST_SRC1_SHIFT 6 +#define NV40_VP_INST_SRC1_MASK (0x1FFFF << 6) +#define NV40_VP_INST_SRC2H_SHIFT 0 +#define NV40_VP_INST_SRC2H_MASK (0x3F << 0) +#define NV40_VP_INST_IADDRH_SHIFT 0 +#define NV40_VP_INST_IADDRH_MASK (0x1F << 0) + +/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */ +#define NV40_VP_INST_IADDRL_SHIFT 29 +#define NV40_VP_INST_IADDRL_MASK (7 << 29) +#define NV40_VP_INST_SRC2L_SHIFT 21 +#define NV40_VP_INST_SRC2L_MASK (0x7FF << 21) +#define NV40_VP_INST_SCA_WRITEMASK_SHIFT 17 +#define NV40_VP_INST_SCA_WRITEMASK_MASK (0xF << 17) +# define NV40_VP_INST_SCA_WRITEMASK_X (1 << 20) +# define NV40_VP_INST_SCA_WRITEMASK_Y (1 << 19) +# define NV40_VP_INST_SCA_WRITEMASK_Z (1 << 18) +# define NV40_VP_INST_SCA_WRITEMASK_W (1 << 17) +#define NV40_VP_INST_VEC_WRITEMASK_SHIFT 13 +#define NV40_VP_INST_VEC_WRITEMASK_MASK (0xF << 13) +# define NV40_VP_INST_VEC_WRITEMASK_X (1 << 16) +# define NV40_VP_INST_VEC_WRITEMASK_Y (1 << 15) +# define NV40_VP_INST_VEC_WRITEMASK_Z (1 << 14) +# define NV40_VP_INST_VEC_WRITEMASK_W (1 << 13) +#define NV40_VP_INST_SCA_RESULT (1 << 12) +#define NV40_VP_INST_SCA_DEST_TEMP_SHIFT 7 +#define NV40_VP_INST_SCA_DEST_TEMP_MASK (0x1F << 7) +#define NV40_VP_INST_DEST_SHIFT 2 +#define NV40_VP_INST_DEST_MASK (31 << 2) +# define NV40_VP_INST_DEST_POS 0 +# define NV40_VP_INST_DEST_COL0 1 +# define NV40_VP_INST_DEST_COL1 2 +# define NV40_VP_INST_DEST_BFC0 3 +# define NV40_VP_INST_DEST_BFC1 4 +# define NV40_VP_INST_DEST_FOGC 5 +# define NV40_VP_INST_DEST_PSZ 6 +# define NV40_VP_INST_DEST_TC0 7 +# define NV40_VP_INST_DEST_TC(n) (7+n) +# define NV40_VP_INST_DEST_TEMP 0x1F +#define NV40_VP_INST_INDEX_CONST (1 << 1) +#define NV40_VP_INST_LAST (1 << 0) +#define NV40_VP_INST3_KNOWN ( \ + NV40_VP_INST_SRC2L_MASK |\ + NV40_VP_INST_SCA_WRITEMASK_MASK |\ + NV40_VP_INST_VEC_WRITEMASK_MASK |\ + NV40_VP_INST_SCA_DEST_TEMP_MASK |\ + NV40_VP_INST_DEST_MASK |\ + NV40_VP_INST_INDEX_CONST) + +/* Useful to split the source selection regs into their pieces */ +#define NV40_VP_SRC0_HIGH_SHIFT 9 +#define NV40_VP_SRC0_HIGH_MASK 0x0001FE00 +#define NV40_VP_SRC0_LOW_MASK 0x000001FF +#define NV40_VP_SRC2_HIGH_SHIFT 11 +#define NV40_VP_SRC2_HIGH_MASK 0x0001F800 +#define NV40_VP_SRC2_LOW_MASK 0x000007FF + +/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */ +#define NV40_VP_SRC_NEGATE (1 << 16) +#define NV40_VP_SRC_SWZ_X_SHIFT 14 +#define NV40_VP_SRC_SWZ_X_MASK (3 << 14) +#define NV40_VP_SRC_SWZ_Y_SHIFT 12 +#define NV40_VP_SRC_SWZ_Y_MASK (3 << 12) +#define NV40_VP_SRC_SWZ_Z_SHIFT 10 +#define NV40_VP_SRC_SWZ_Z_MASK (3 << 10) +#define NV40_VP_SRC_SWZ_W_SHIFT 8 +#define NV40_VP_SRC_SWZ_W_MASK (3 << 8) +#define NV40_VP_SRC_SWZ_ALL_SHIFT 8 +#define NV40_VP_SRC_SWZ_ALL_MASK (0xFF << 8) +#define NV40_VP_SRC_TEMP_SRC_SHIFT 2 +#define NV40_VP_SRC_TEMP_SRC_MASK (0x1F << 2) +#define NV40_VP_SRC_REG_TYPE_SHIFT 0 +#define NV40_VP_SRC_REG_TYPE_MASK (3 << 0) +# define NV40_VP_SRC_REG_TYPE_UNK0 0 +# define NV40_VP_SRC_REG_TYPE_TEMP 1 +# define NV40_VP_SRC_REG_TYPE_INPUT 2 +# define NV40_VP_SRC_REG_TYPE_CONST 3 + + +/* + * Each fragment program opcode appears to be comprised of 4 32-bit values. + * + * 0 - Opcode, output reg/mask, ATTRIB source + * 1 - Source 0 + * 2 - Source 1 + * 3 - Source 2 + * + * There appears to be no special difference between result regs and temp regs. + * result.color == R0.xyzw + * result.depth == R1.z + * When the fragprog contains instructions to write depth, + * NV30_TCL_PRIMITIVE_3D_UNK1D78=0 otherwise it is set to 1. + * + * Constants are inserted directly after the instruction that uses them. + * + * It appears that it's not possible to use two input registers in one + * instruction as the input sourcing is done in the instruction dword + * and not the source selection dwords. As such instructions such as: + * + * ADD result.color, fragment.color, fragment.texcoord[0]; + * + * must be split into two MOV's and then an ADD (nvidia does this) but + * I'm not sure why it's not just one MOV and then source the second input + * in the ADD instruction.. + * + * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary + * negation requires multiplication with a const. + * + * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO and + * SWIZZLE_ONE. + * + * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as + * SWIZZLE_ZERO is implemented simply by not writing to the relevant components + * of the destination. + * + * Looping + * Loops appear to be fairly expensive on NV40 at least, the proprietary + * driver goes to a lot of effort to avoid using the native looping + * instructions. If the total number of *executed* instructions between + * REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop. + * The maximum loop count is 255. + * + * Conditional execution + * TODO + * + * Non-native instructions: + * LIT + * LRP - MAD+MAD + * SUB - ADD, negate second source + * RSQ - LG2 + EX2 + * POW - LG2 + MUL + EX2 + * SCS - COS + SIN + * XPD + * DP2 - MUL + ADD + * NRM + */ + +//== Opcode / Destination selection == +#define NV40_FP_OP_PROGRAM_END (1 << 0) +#define NV40_FP_OP_OUT_REG_SHIFT 1 +#define NV40_FP_OP_OUT_REG_MASK (63 << 1) +/* Needs to be set when writing outputs to get expected result.. */ +#define NV40_FP_OP_OUT_REG_HALF (1 << 7) +#define NV40_FP_OP_COND_WRITE_ENABLE (1 << 8) +#define NV40_FP_OP_OUTMASK_SHIFT 9 +#define NV40_FP_OP_OUTMASK_MASK (0xF << 9) +# define NV40_FP_OP_OUT_X (1 << 9) +# define NV40_FP_OP_OUT_Y (1 <<10) +# define NV40_FP_OP_OUT_Z (1 <<11) +# define NV40_FP_OP_OUT_W (1 <<12) +/* Uncertain about these, especially the input_src values.. it's possible that + * they can be dynamically changed. + */ +#define NV40_FP_OP_INPUT_SRC_SHIFT 13 +#define NV40_FP_OP_INPUT_SRC_MASK (15 << 13) +# define NV40_FP_OP_INPUT_SRC_POSITION 0x0 +# define NV40_FP_OP_INPUT_SRC_COL0 0x1 +# define NV40_FP_OP_INPUT_SRC_COL1 0x2 +# define NV40_FP_OP_INPUT_SRC_FOGC 0x3 +# define NV40_FP_OP_INPUT_SRC_TC0 0x4 +# define NV40_FP_OP_INPUT_SRC_TC(n) (0x4 + n) +# define NV40_FP_OP_INPUT_SRC_FACING 0xE +#define NV40_FP_OP_TEX_UNIT_SHIFT 17 +#define NV40_FP_OP_TEX_UNIT_MASK (0xF << 17) +#define NV40_FP_OP_PRECISION_SHIFT 22 +#define NV40_FP_OP_PRECISION_MASK (3 << 22) +# define NV40_FP_PRECISION_FP32 0 +# define NV40_FP_PRECISION_FP16 1 +# define NV40_FP_PRECISION_FX12 2 +#define NV40_FP_OP_OPCODE_SHIFT 24 +#define NV40_FP_OP_OPCODE_MASK (0x3F << 24) +# define NV40_FP_OP_OPCODE_NOP 0x00 +# define NV40_FP_OP_OPCODE_MOV 0x01 +# define NV40_FP_OP_OPCODE_MUL 0x02 +# define NV40_FP_OP_OPCODE_ADD 0x03 +# define NV40_FP_OP_OPCODE_MAD 0x04 +# define NV40_FP_OP_OPCODE_DP3 0x05 +# define NV40_FP_OP_OPCODE_DP4 0x06 +# define NV40_FP_OP_OPCODE_DST 0x07 +# define NV40_FP_OP_OPCODE_MIN 0x08 +# define NV40_FP_OP_OPCODE_MAX 0x09 +# define NV40_FP_OP_OPCODE_SLT 0x0A +# define NV40_FP_OP_OPCODE_SGE 0x0B +# define NV40_FP_OP_OPCODE_SLE 0x0C +# define NV40_FP_OP_OPCODE_SGT 0x0D +# define NV40_FP_OP_OPCODE_SNE 0x0E +# define NV40_FP_OP_OPCODE_SEQ 0x0F +# define NV40_FP_OP_OPCODE_FRC 0x10 +# define NV40_FP_OP_OPCODE_FLR 0x11 +# define NV40_FP_OP_OPCODE_KIL 0x12 +# define NV40_FP_OP_OPCODE_PK4B 0x13 +# define NV40_FP_OP_OPCODE_UP4B 0x14 +/* DDX/DDY can only write to XY */ +# define NV40_FP_OP_OPCODE_DDX 0x15 +# define NV40_FP_OP_OPCODE_DDY 0x16 +# define NV40_FP_OP_OPCODE_TEX 0x17 +# define NV40_FP_OP_OPCODE_TXP 0x18 +# define NV40_FP_OP_OPCODE_TXD 0x19 +# define NV40_FP_OP_OPCODE_RCP 0x1A +# define NV40_FP_OP_OPCODE_EX2 0x1C +# define NV40_FP_OP_OPCODE_LG2 0x1D +# define NV40_FP_OP_OPCODE_STR 0x20 +# define NV40_FP_OP_OPCODE_SFL 0x21 +# define NV40_FP_OP_OPCODE_COS 0x22 +# define NV40_FP_OP_OPCODE_SIN 0x23 +# define NV40_FP_OP_OPCODE_PK2H 0x24 +# define NV40_FP_OP_OPCODE_UP2H 0x25 +# define NV40_FP_OP_OPCODE_PK4UB 0x27 +# define NV40_FP_OP_OPCODE_UP4UB 0x28 +# define NV40_FP_OP_OPCODE_PK2US 0x29 +# define NV40_FP_OP_OPCODE_UP2US 0x2A +# define NV40_FP_OP_OPCODE_DP2A 0x2E +# define NV40_FP_OP_OPCODE_TXL 0x2F +# define NV40_FP_OP_OPCODE_TXB 0x31 +# define NV40_FP_OP_OPCODE_DIV 0x3A +# define NV40_FP_OP_OPCODE_UNK_LIT 0x3C +/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/ +# define NV40_FP_OP_BRA_OPCODE_BRK 0x0 +# define NV40_FP_OP_BRA_OPCODE_CAL 0x1 +# define NV40_FP_OP_BRA_OPCODE_IF 0x2 +# define NV40_FP_OP_BRA_OPCODE_LOOP 0x3 +# define NV40_FP_OP_BRA_OPCODE_REP 0x4 +# define NV40_FP_OP_BRA_OPCODE_RET 0x5 +#define NV40_FP_OP_OUT_SAT (1 << 31) + +/* high order bits of SRC0 */ +#define NV40_FP_OP_OUT_ABS (1 << 29) +#define NV40_FP_OP_COND_SWZ_W_SHIFT 27 +#define NV40_FP_OP_COND_SWZ_W_MASK (3 << 27) +#define NV40_FP_OP_COND_SWZ_Z_SHIFT 25 +#define NV40_FP_OP_COND_SWZ_Z_MASK (3 << 25) +#define NV40_FP_OP_COND_SWZ_Y_SHIFT 23 +#define NV40_FP_OP_COND_SWZ_Y_MASK (3 << 23) +#define NV40_FP_OP_COND_SWZ_X_SHIFT 21 +#define NV40_FP_OP_COND_SWZ_X_MASK (3 << 21) +#define NV40_FP_OP_COND_SWZ_ALL_SHIFT 21 +#define NV40_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21) +#define NV40_FP_OP_COND_SHIFT 18 +#define NV40_FP_OP_COND_MASK (0x07 << 18) +# define NV40_FP_OP_COND_FL 0 +# define NV40_FP_OP_COND_LT 1 +# define NV40_FP_OP_COND_EQ 2 +# define NV40_FP_OP_COND_LE 3 +# define NV40_FP_OP_COND_GT 4 +# define NV40_FP_OP_COND_NE 5 +# define NV40_FP_OP_COND_GE 6 +# define NV40_FP_OP_COND_TR 7 + +/* high order bits of SRC1 */ +#define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31) +#define NV40_FP_OP_DST_SCALE_SHIFT 28 +#define NV40_FP_OP_DST_SCALE_MASK (3 << 28) +#define NV40_FP_OP_DST_SCALE_1X 0 +#define NV40_FP_OP_DST_SCALE_2X 1 +#define NV40_FP_OP_DST_SCALE_4X 2 +#define NV40_FP_OP_DST_SCALE_8X 3 +#define NV40_FP_OP_DST_SCALE_INV_2X 5 +#define NV40_FP_OP_DST_SCALE_INV_4X 6 +#define NV40_FP_OP_DST_SCALE_INV_8X 7 + +/* SRC1 LOOP */ +#define NV40_FP_OP_LOOP_INCR_SHIFT 19 +#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19) +#define NV40_FP_OP_LOOP_INDEX_SHIFT 10 +#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10) +#define NV40_FP_OP_LOOP_COUNT_SHIFT 2 +#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2) + +/* SRC1 IF */ +#define NV40_FP_OP_ELSE_ID_SHIFT 2 +#define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2) + +/* SRC1 CAL */ +#define NV40_FP_OP_IADDR_SHIFT 2 +#define NV40_FP_OP_IADDR_MASK (0xFF << 2) + +/* SRC1 REP + * I have no idea why there are 3 count values here.. but they + * have always been filled with the same value in my tests so + * far.. + */ +#define NV40_FP_OP_REP_COUNT1_SHIFT 2 +#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2) +#define NV40_FP_OP_REP_COUNT2_SHIFT 10 +#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10) +#define NV40_FP_OP_REP_COUNT3_SHIFT 19 +#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19) + +/* SRC2 REP/IF */ +#define NV40_FP_OP_END_ID_SHIFT 2 +#define NV40_FP_OP_END_ID_MASK (0xFF << 2) + +// SRC2 high-order +#define NV40_FP_OP_INDEX_INPUT (1 << 30) +#define NV40_FP_OP_ADDR_INDEX_SHIFT 19 +#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19) + +//== Register selection == +#define NV40_FP_REG_TYPE_SHIFT 0 +#define NV40_FP_REG_TYPE_MASK (3 << 0) +# define NV40_FP_REG_TYPE_TEMP 0 +# define NV40_FP_REG_TYPE_INPUT 1 +# define NV40_FP_REG_TYPE_CONST 2 +#define NV40_FP_REG_SRC_SHIFT 2 +#define NV40_FP_REG_SRC_MASK (63 << 2) +#define NV40_FP_REG_SRC_HALF (1 << 8) +#define NV40_FP_REG_SWZ_ALL_SHIFT 9 +#define NV40_FP_REG_SWZ_ALL_MASK (255 << 9) +#define NV40_FP_REG_SWZ_X_SHIFT 9 +#define NV40_FP_REG_SWZ_X_MASK (3 << 9) +#define NV40_FP_REG_SWZ_Y_SHIFT 11 +#define NV40_FP_REG_SWZ_Y_MASK (3 << 11) +#define NV40_FP_REG_SWZ_Z_SHIFT 13 +#define NV40_FP_REG_SWZ_Z_MASK (3 << 13) +#define NV40_FP_REG_SWZ_W_SHIFT 15 +#define NV40_FP_REG_SWZ_W_MASK (3 << 15) +# define NV40_FP_SWIZZLE_X 0 +# define NV40_FP_SWIZZLE_Y 1 +# define NV40_FP_SWIZZLE_Z 2 +# define NV40_FP_SWIZZLE_W 3 +#define NV40_FP_REG_NEGATE (1 << 17) + +#ifndef NV40_SHADER_NO_FUCKEDNESS +#define NV40SR_NONE 0 +#define NV40SR_OUTPUT 1 +#define NV40SR_INPUT 2 +#define NV40SR_TEMP 3 +#define NV40SR_CONST 4 + +struct nv40_sreg { + int type; + int index; + + int dst_scale; + + int negate; + int abs; + int swz[4]; + + int cc_update; + int cc_update_reg; + int cc_test; + int cc_test_reg; + int cc_swz[4]; +}; + +static INLINE struct nv40_sreg +nv40_sr(int type, int index) +{ + struct nv40_sreg temp = { + .type = type, + .index = index, + .dst_scale = DEF_SCALE, + .abs = 0, + .negate = 0, + .swz = { 0, 1, 2, 3 }, + .cc_update = 0, + .cc_update_reg = 0, + .cc_test = DEF_CTEST, + .cc_test_reg = 0, + .cc_swz = { 0, 1, 2, 3 }, + }; + return temp; +} + +static INLINE struct nv40_sreg +nv40_sr_swz(struct nv40_sreg src, int x, int y, int z, int w) +{ + struct nv40_sreg dst = src; + + dst.swz[SWZ_X] = src.swz[x]; + dst.swz[SWZ_Y] = src.swz[y]; + dst.swz[SWZ_Z] = src.swz[z]; + dst.swz[SWZ_W] = src.swz[w]; + return dst; +} + +static INLINE struct nv40_sreg +nv40_sr_neg(struct nv40_sreg src) +{ + src.negate = !src.negate; + return src; +} + +static INLINE struct nv40_sreg +nv40_sr_abs(struct nv40_sreg src) +{ + src.abs = 1; + return src; +} + +static INLINE struct nv40_sreg +nv40_sr_scale(struct nv40_sreg src, int scale) +{ + src.dst_scale = scale; + return src; +} +#endif + +#endif diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c new file mode 100644 index 00000000000..afcf336a65b --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -0,0 +1,737 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "draw/draw_context.h" + +#include "nv40_context.h" +#include "nv40_state.h" + +static void * +nv40_blend_state_create(struct pipe_context *pipe, + const struct pipe_blend_state *cso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_grobj *curie = nv40->screen->curie; + struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso)); + struct nouveau_stateobj *so = so_new(16, 0); + + if (cso->blend_enable) { + so_method(so, curie, NV40TCL_BLEND_ENABLE, 3); + so_data (so, 1); + so_data (so, (nvgl_blend_func(cso->alpha_src_factor) << 16) | + nvgl_blend_func(cso->rgb_src_factor)); + so_data (so, nvgl_blend_func(cso->alpha_dst_factor) << 16 | + nvgl_blend_func(cso->rgb_dst_factor)); + so_method(so, curie, NV40TCL_BLEND_EQUATION, 1); + so_data (so, nvgl_blend_eqn(cso->alpha_func) << 16 | + nvgl_blend_eqn(cso->rgb_func)); + } else { + so_method(so, curie, NV40TCL_BLEND_ENABLE, 1); + so_data (so, 0); + } + + so_method(so, curie, NV40TCL_COLOR_MASK, 1); + so_data (so, (((cso->colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | + ((cso->colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | + ((cso->colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | + ((cso->colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); + + if (cso->logicop_enable) { + so_method(so, curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 2); + so_data (so, 1); + so_data (so, nvgl_logicop_func(cso->logicop_func)); + } else { + so_method(so, curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 1); + so_data (so, 0); + } + + so_method(so, curie, NV40TCL_DITHER_ENABLE, 1); + so_data (so, cso->dither ? 1 : 0); + + so_ref(so, &bso->so); + bso->pipe = *cso; + return (void *)bso; +} + +static void +nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->blend = hwcso; + nv40->dirty |= NV40_NEW_BLEND; +} + +static void +nv40_blend_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_blend_state *bso = hwcso; + + so_ref(NULL, &bso->so); + FREE(bso); +} + + +static INLINE unsigned +wrap_mode(unsigned wrap) { + unsigned ret; + + switch (wrap) { + case PIPE_TEX_WRAP_REPEAT: + ret = NV40TCL_TEX_WRAP_S_REPEAT; + break; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + ret = NV40TCL_TEX_WRAP_S_MIRRORED_REPEAT; + break; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + ret = NV40TCL_TEX_WRAP_S_CLAMP_TO_EDGE; + break; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + ret = NV40TCL_TEX_WRAP_S_CLAMP_TO_BORDER; + break; + case PIPE_TEX_WRAP_CLAMP: + ret = NV40TCL_TEX_WRAP_S_CLAMP; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_EDGE; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_BORDER; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP; + break; + default: + NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); + ret = NV40TCL_TEX_WRAP_S_REPEAT; + break; + } + + return ret >> NV40TCL_TEX_WRAP_S_SHIFT; +} + +static void * +nv40_sampler_state_create(struct pipe_context *pipe, + const struct pipe_sampler_state *cso) +{ + struct nv40_sampler_state *ps; + uint32_t filter = 0; + + ps = MALLOC(sizeof(struct nv40_sampler_state)); + + ps->fmt = 0; + if (!cso->normalized_coords) + ps->fmt |= NV40TCL_TEX_FORMAT_RECT; + + ps->wrap = ((wrap_mode(cso->wrap_s) << NV40TCL_TEX_WRAP_S_SHIFT) | + (wrap_mode(cso->wrap_t) << NV40TCL_TEX_WRAP_T_SHIFT) | + (wrap_mode(cso->wrap_r) << NV40TCL_TEX_WRAP_R_SHIFT)); + + ps->en = 0; + if (cso->max_anisotropy >= 2.0) { + /* no idea, binary driver sets it, works without it.. meh.. */ + ps->wrap |= (1 << 5); + + if (cso->max_anisotropy >= 16.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X; + } else + if (cso->max_anisotropy >= 12.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X; + } else + if (cso->max_anisotropy >= 10.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X; + } else + if (cso->max_anisotropy >= 8.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X; + } else + if (cso->max_anisotropy >= 6.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X; + } else + if (cso->max_anisotropy >= 4.0) { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X; + } else { + ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X; + } + } + + switch (cso->mag_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + filter |= NV40TCL_TEX_FILTER_MAG_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + filter |= NV40TCL_TEX_FILTER_MAG_NEAREST; + break; + } + + switch (cso->min_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV40TCL_TEX_FILTER_MIN_LINEAR; + break; + } + break; + case PIPE_TEX_FILTER_NEAREST: + default: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV40TCL_TEX_FILTER_MIN_NEAREST; + break; + } + break; + } + + ps->filt = filter; + + { + float limit; + + limit = CLAMP(cso->lod_bias, -16.0, 15.0); + ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff; + + limit = CLAMP(cso->max_lod, 0.0, 15.0); + ps->en |= (int)(limit * 256.0) << 7; + + limit = CLAMP(cso->min_lod, 0.0, 15.0); + ps->en |= (int)(limit * 256.0) << 19; + } + + + if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + switch (cso->compare_func) { + case PIPE_FUNC_NEVER: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_NEVER; + break; + case PIPE_FUNC_GREATER: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_GREATER; + break; + case PIPE_FUNC_EQUAL: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_EQUAL; + break; + case PIPE_FUNC_GEQUAL: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_GEQUAL; + break; + case PIPE_FUNC_LESS: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_LESS; + break; + case PIPE_FUNC_NOTEQUAL: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_NOTEQUAL; + break; + case PIPE_FUNC_LEQUAL: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_LEQUAL; + break; + case PIPE_FUNC_ALWAYS: + ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_ALWAYS; + break; + default: + break; + } + } + + ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) | + (float_to_ubyte(cso->border_color[0]) << 16) | + (float_to_ubyte(cso->border_color[1]) << 8) | + (float_to_ubyte(cso->border_color[2]) << 0)); + + return (void *)ps; +} + +static void +nv40_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) +{ + struct nv40_context *nv40 = nv40_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nv40->tex_sampler[unit] = sampler[unit]; + nv40->dirty_samplers |= (1 << unit); + } + + for (unit = nr; unit < nv40->nr_samplers; unit++) { + nv40->tex_sampler[unit] = NULL; + nv40->dirty_samplers |= (1 << unit); + } + + nv40->nr_samplers = nr; + nv40->dirty |= NV40_NEW_SAMPLER; +} + +static void +nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso) +{ + FREE(hwcso); +} + +static void +nv40_set_sampler_texture(struct pipe_context *pipe, unsigned nr, + struct pipe_texture **miptree) +{ + struct nv40_context *nv40 = nv40_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + pipe_texture_reference((struct pipe_texture **) + &nv40->tex_miptree[unit], miptree[unit]); + nv40->dirty_samplers |= (1 << unit); + } + + for (unit = nr; unit < nv40->nr_textures; unit++) { + pipe_texture_reference((struct pipe_texture **) + &nv40->tex_miptree[unit], NULL); + nv40->dirty_samplers |= (1 << unit); + } + + nv40->nr_textures = nr; + nv40->dirty |= NV40_NEW_SAMPLER; +} + +static void * +nv40_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso)); + struct nouveau_stateobj *so = so_new(32, 0); + struct nouveau_grobj *curie = nv40->screen->curie; + + /*XXX: ignored: + * light_twoside + * point_smooth -nohw + * multisample + */ + + so_method(so, curie, NV40TCL_SHADE_MODEL, 1); + so_data (so, cso->flatshade ? NV40TCL_SHADE_MODEL_FLAT : + NV40TCL_SHADE_MODEL_SMOOTH); + + so_method(so, curie, NV40TCL_LINE_WIDTH, 2); + so_data (so, (unsigned char)(cso->line_width * 8.0) & 0xff); + so_data (so, cso->line_smooth ? 1 : 0); + so_method(so, curie, NV40TCL_LINE_STIPPLE_ENABLE, 2); + so_data (so, cso->line_stipple_enable ? 1 : 0); + so_data (so, (cso->line_stipple_pattern << 16) | + cso->line_stipple_factor); + + so_method(so, curie, NV40TCL_POINT_SIZE, 1); + so_data (so, fui(cso->point_size)); + + so_method(so, curie, NV40TCL_POLYGON_MODE_FRONT, 6); + if (cso->front_winding == PIPE_WINDING_CCW) { + so_data(so, nvgl_polygon_mode(cso->fill_ccw)); + so_data(so, nvgl_polygon_mode(cso->fill_cw)); + switch (cso->cull_mode) { + case PIPE_WINDING_CCW: + so_data(so, NV40TCL_CULL_FACE_FRONT); + break; + case PIPE_WINDING_CW: + so_data(so, NV40TCL_CULL_FACE_BACK); + break; + case PIPE_WINDING_BOTH: + so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, NV40TCL_CULL_FACE_BACK); + break; + } + so_data(so, NV40TCL_FRONT_FACE_CCW); + } else { + so_data(so, nvgl_polygon_mode(cso->fill_cw)); + so_data(so, nvgl_polygon_mode(cso->fill_ccw)); + switch (cso->cull_mode) { + case PIPE_WINDING_CCW: + so_data(so, NV40TCL_CULL_FACE_BACK); + break; + case PIPE_WINDING_CW: + so_data(so, NV40TCL_CULL_FACE_FRONT); + break; + case PIPE_WINDING_BOTH: + so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, NV40TCL_CULL_FACE_BACK); + break; + } + so_data(so, NV40TCL_FRONT_FACE_CW); + } + so_data(so, cso->poly_smooth ? 1 : 0); + so_data(so, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0); + + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, cso->poly_stipple_enable ? 1 : 0); + + so_method(so, curie, NV40TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) || + (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT)) + so_data(so, 1); + else + so_data(so, 0); + if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) || + (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE)) + so_data(so, 1); + else + so_data(so, 0); + if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) || + (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL)) + so_data(so, 1); + else + so_data(so, 0); + if (cso->offset_cw || cso->offset_ccw) { + so_method(so, curie, NV40TCL_POLYGON_OFFSET_FACTOR, 2); + so_data (so, fui(cso->offset_scale)); + so_data (so, fui(cso->offset_units * 2)); + } + + so_method(so, curie, NV40TCL_POINT_SPRITE, 1); + if (cso->point_sprite) { + unsigned psctl = (1 << 0), i; + + for (i = 0; i < 8; i++) { + if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE) + psctl |= (1 << (8 + i)); + } + + so_data(so, psctl); + } else { + so_data(so, 0); + } + + so_ref(so, &rsso->so); + rsso->pipe = *cso; + return (void *)rsso; +} + +static void +nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->rasterizer = hwcso; + nv40->dirty |= NV40_NEW_RAST; + nv40->draw_dirty |= NV40_NEW_RAST; +} + +static void +nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_rasterizer_state *rsso = hwcso; + + so_ref(NULL, &rsso->so); + FREE(rsso); +} + +static void * +nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); + struct nouveau_stateobj *so = so_new(32, 0); + struct nouveau_grobj *curie = nv40->screen->curie; + + so_method(so, curie, NV40TCL_DEPTH_FUNC, 3); + so_data (so, nvgl_comparison_op(cso->depth.func)); + so_data (so, cso->depth.writemask ? 1 : 0); + so_data (so, cso->depth.enabled ? 1 : 0); + + so_method(so, curie, NV40TCL_ALPHA_TEST_ENABLE, 3); + so_data (so, cso->alpha.enabled ? 1 : 0); + so_data (so, nvgl_comparison_op(cso->alpha.func)); + so_data (so, float_to_ubyte(cso->alpha.ref)); + + if (cso->stencil[0].enabled) { + so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); + so_data (so, cso->stencil[0].enabled ? 1 : 0); + so_data (so, cso->stencil[0].write_mask); + so_data (so, nvgl_comparison_op(cso->stencil[0].func)); + so_data (so, cso->stencil[0].ref_value); + so_data (so, cso->stencil[0].value_mask); + 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)); + } else { + so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); + so_data (so, 0); + } + + if (cso->stencil[1].enabled) { + so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 8); + so_data (so, cso->stencil[1].enabled ? 1 : 0); + so_data (so, cso->stencil[1].write_mask); + so_data (so, nvgl_comparison_op(cso->stencil[1].func)); + so_data (so, cso->stencil[1].ref_value); + so_data (so, cso->stencil[1].value_mask); + 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)); + } else { + so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 1); + so_data (so, 0); + } + + so_ref(so, &zsaso->so); + zsaso->pipe = *cso; + return (void *)zsaso; +} + +static void +nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->zsa = hwcso; + nv40->dirty |= NV40_NEW_ZSA; +} + +static void +nv40_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_zsa_state *zsaso = hwcso; + + so_ref(NULL, &zsaso->so); + FREE(zsaso); +} + +static void * +nv40_vp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_vertex_program *vp; + + vp = CALLOC(1, sizeof(struct nv40_vertex_program)); + vp->pipe = *cso; + vp->draw = draw_create_vertex_shader(nv40->draw, &vp->pipe); + + return (void *)vp; +} + +static void +nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->vertprog = hwcso; + nv40->dirty |= NV40_NEW_VERTPROG; + nv40->draw_dirty |= NV40_NEW_VERTPROG; +} + +static void +nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_vertex_program *vp = hwcso; + + draw_delete_vertex_shader(nv40->draw, vp->draw); + nv40_vertprog_destroy(nv40, vp); + FREE(vp); +} + +static void * +nv40_fp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv40_fragment_program *fp; + + fp = CALLOC(1, sizeof(struct nv40_fragment_program)); + fp->pipe = *cso; + + tgsi_scan_shader(fp->pipe.tokens, &fp->info); + + return (void *)fp; +} + +static void +nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->fragprog = hwcso; + nv40->dirty |= NV40_NEW_FRAGPROG; +} + +static void +nv40_fp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_fragment_program *fp = hwcso; + + nv40_fragprog_destroy(nv40, fp); + FREE(fp); +} + +static void +nv40_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *bcol) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->blend_colour = *bcol; + nv40->dirty |= NV40_NEW_BCOL; +} + +static void +nv40_set_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *clip) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->clip = *clip; + nv40->dirty |= NV40_NEW_UCP; + nv40->draw_dirty |= NV40_NEW_UCP; +} + +static void +nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + const struct pipe_constant_buffer *buf ) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->constbuf[shader] = buf->buffer; + nv40->constbuf_nr[shader] = buf->size / (4 * sizeof(float)); + + if (shader == PIPE_SHADER_VERTEX) { + nv40->dirty |= NV40_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nv40->dirty |= NV40_NEW_FRAGPROG; + } +} + +static void +nv40_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->framebuffer = *fb; + nv40->dirty |= NV40_NEW_FB; +} + +static void +nv40_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + memcpy(nv40->stipple, stipple->stipple, 4 * 32); + nv40->dirty |= NV40_NEW_STIPPLE; +} + +static void +nv40_set_scissor_state(struct pipe_context *pipe, + const struct pipe_scissor_state *s) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->scissor = *s; + nv40->dirty |= NV40_NEW_SCISSOR; +} + +static void +nv40_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *vpt) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->viewport = *vpt; + nv40->dirty |= NV40_NEW_VIEWPORT; + nv40->draw_dirty |= NV40_NEW_VIEWPORT; +} + +static void +nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *vb) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + memcpy(nv40->vtxbuf, vb, sizeof(*vb) * count); + nv40->vtxbuf_nr = count; + + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->draw_dirty |= NV40_NEW_ARRAYS; +} + +static void +nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *ve) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + memcpy(nv40->vtxelt, ve, sizeof(*ve) * count); + nv40->vtxelt_nr = count; + + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->draw_dirty |= NV40_NEW_ARRAYS; +} + +static void +nv40_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->edgeflags = bitfield; + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->draw_dirty |= NV40_NEW_ARRAYS; +} + +void +nv40_init_state_functions(struct nv40_context *nv40) +{ + nv40->pipe.create_blend_state = nv40_blend_state_create; + nv40->pipe.bind_blend_state = nv40_blend_state_bind; + nv40->pipe.delete_blend_state = nv40_blend_state_delete; + + nv40->pipe.create_sampler_state = nv40_sampler_state_create; + nv40->pipe.bind_sampler_states = nv40_sampler_state_bind; + nv40->pipe.delete_sampler_state = nv40_sampler_state_delete; + nv40->pipe.set_sampler_textures = nv40_set_sampler_texture; + + nv40->pipe.create_rasterizer_state = nv40_rasterizer_state_create; + nv40->pipe.bind_rasterizer_state = nv40_rasterizer_state_bind; + nv40->pipe.delete_rasterizer_state = nv40_rasterizer_state_delete; + + nv40->pipe.create_depth_stencil_alpha_state = + nv40_depth_stencil_alpha_state_create; + nv40->pipe.bind_depth_stencil_alpha_state = + nv40_depth_stencil_alpha_state_bind; + nv40->pipe.delete_depth_stencil_alpha_state = + nv40_depth_stencil_alpha_state_delete; + + nv40->pipe.create_vs_state = nv40_vp_state_create; + nv40->pipe.bind_vs_state = nv40_vp_state_bind; + nv40->pipe.delete_vs_state = nv40_vp_state_delete; + + nv40->pipe.create_fs_state = nv40_fp_state_create; + nv40->pipe.bind_fs_state = nv40_fp_state_bind; + nv40->pipe.delete_fs_state = nv40_fp_state_delete; + + nv40->pipe.set_blend_color = nv40_set_blend_color; + nv40->pipe.set_clip_state = nv40_set_clip_state; + nv40->pipe.set_constant_buffer = nv40_set_constant_buffer; + nv40->pipe.set_framebuffer_state = nv40_set_framebuffer_state; + nv40->pipe.set_polygon_stipple = nv40_set_polygon_stipple; + nv40->pipe.set_scissor_state = nv40_set_scissor_state; + nv40->pipe.set_viewport_state = nv40_set_viewport_state; + + nv40->pipe.set_edgeflags = nv40_set_edgeflags; + nv40->pipe.set_vertex_buffers = nv40_set_vertex_buffers; + nv40->pipe.set_vertex_elements = nv40_set_vertex_elements; +} + diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h new file mode 100644 index 00000000000..2b4225deb2e --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -0,0 +1,88 @@ +#ifndef __NV40_STATE_H__ +#define __NV40_STATE_H__ + +#include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" + +struct nv40_sampler_state { + uint32_t fmt; + uint32_t wrap; + uint32_t en; + uint32_t filt; + uint32_t bcol; +}; + +struct nv40_vertex_program_exec { + uint32_t data[4]; + boolean has_branch_offset; + int const_index; +}; + +struct nv40_vertex_program_data { + int index; /* immediates == -1 */ + float value[4]; +}; + +struct nv40_vertex_program { + struct pipe_shader_state pipe; + + struct draw_vertex_shader *draw; + + boolean translated; + + struct pipe_clip_state ucp; + + struct nv40_vertex_program_exec *insns; + unsigned nr_insns; + struct nv40_vertex_program_data *consts; + unsigned nr_consts; + + struct nouveau_resource *exec; + unsigned exec_start; + struct nouveau_resource *data; + unsigned data_start; + unsigned data_start_min; + + uint32_t ir; + uint32_t or; + uint32_t clip_ctrl; + struct nouveau_stateobj *so; +}; + +struct nv40_fragment_program_data { + unsigned offset; + unsigned index; +}; + +struct nv40_fragment_program { + struct pipe_shader_state pipe; + struct tgsi_shader_info info; + + boolean translated; + unsigned samplers; + + uint32_t *insn; + int insn_len; + + struct nv40_fragment_program_data *consts; + unsigned nr_consts; + + struct pipe_buffer *buffer; + + uint32_t fp_control; + struct nouveau_stateobj *so; +}; + +struct nv40_miptree { + struct pipe_texture base; + + struct pipe_buffer *buffer; + uint total_size; + + struct { + uint pitch; + uint *image_offset; + } level[PIPE_MAX_TEXTURE_LEVELS]; +}; + +#endif diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c new file mode 100644 index 00000000000..95e6d7394f4 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -0,0 +1,40 @@ +#include "nv40_context.h" + +static boolean +nv40_state_blend_validate(struct nv40_context *nv40) +{ + so_ref(nv40->blend->so, &nv40->state.hw[NV40_STATE_BLEND]); + return TRUE; +} + +struct nv40_state_entry nv40_state_blend = { + .validate = nv40_state_blend_validate, + .dirty = { + .pipe = NV40_NEW_BLEND, + .hw = NV40_STATE_BLEND + } +}; + +static boolean +nv40_state_blend_colour_validate(struct nv40_context *nv40) +{ + struct nouveau_stateobj *so = so_new(2, 0); + struct pipe_blend_color *bcol = &nv40->blend_colour; + + so_method(so, nv40->screen->curie, NV40TCL_BLEND_COLOR, 1); + so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) | + (float_to_ubyte(bcol->color[0]) << 16) | + (float_to_ubyte(bcol->color[1]) << 8) | + (float_to_ubyte(bcol->color[2]) << 0))); + + so_ref(so, &nv40->state.hw[NV40_STATE_BCOL]); + return TRUE; +} + +struct nv40_state_entry nv40_state_blend_colour = { + .validate = nv40_state_blend_colour_validate, + .dirty = { + .pipe = NV40_NEW_BCOL, + .hw = NV40_STATE_BCOL + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c new file mode 100644 index 00000000000..ab88dc416e5 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -0,0 +1,184 @@ +#include "nv40_context.h" +#include "nv40_state.h" +#include "draw/draw_context.h" + +static struct nv40_state_entry *render_states[] = { + &nv40_state_framebuffer, + &nv40_state_rasterizer, + &nv40_state_scissor, + &nv40_state_stipple, + &nv40_state_fragprog, + &nv40_state_fragtex, + &nv40_state_vertprog, + &nv40_state_blend, + &nv40_state_blend_colour, + &nv40_state_zsa, + &nv40_state_viewport, + &nv40_state_vbo, + NULL +}; + +static struct nv40_state_entry *swtnl_states[] = { + &nv40_state_framebuffer, + &nv40_state_rasterizer, + &nv40_state_scissor, + &nv40_state_stipple, + &nv40_state_fragprog, + &nv40_state_fragtex, + &nv40_state_vertprog, + &nv40_state_blend, + &nv40_state_blend_colour, + &nv40_state_zsa, + &nv40_state_viewport, + &nv40_state_vtxfmt, + NULL +}; + +static void +nv40_state_do_validate(struct nv40_context *nv40, + struct nv40_state_entry **states) +{ + const struct pipe_framebuffer_state *fb = &nv40->framebuffer; + unsigned i; + + for (i = 0; i < fb->num_cbufs; i++) + fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; + if (fb->zsbuf) + fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; + + while (*states) { + struct nv40_state_entry *e = *states; + + if (nv40->dirty & e->dirty.pipe) { + if (e->validate(nv40)) + nv40->state.dirty |= (1ULL << e->dirty.hw); + } + + states++; + } + nv40->dirty = 0; +} + +void +nv40_state_emit(struct nv40_context *nv40) +{ + struct nv40_state *state = &nv40->state; + struct nv40_screen *screen = nv40->screen; + unsigned i, samplers; + uint64 states; + + if (nv40->pctx_id != screen->cur_pctx) { + for (i = 0; i < NV40_STATE_MAX; i++) { + if (state->hw[i] && screen->state[i] != state->hw[i]) + state->dirty |= (1ULL << i); + } + + screen->cur_pctx = nv40->pctx_id; + } + + for (i = 0, states = state->dirty; states; i++) { + if (!(states & (1ULL << i))) + continue; + so_ref (state->hw[i], &nv40->screen->state[i]); + if (state->hw[i]) + so_emit(nv40->nvws, nv40->screen->state[i]); + states &= ~(1ULL << i); + } + + if (state->dirty & ((1ULL << NV40_STATE_FRAGPROG) | + (1ULL << NV40_STATE_FRAGTEX0))) { + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (2); + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (1); + } + + state->dirty = 0; + + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]); + for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { + if (!(samplers & (1 << i))) + continue; + so_emit_reloc_markers(nv40->nvws, + state->hw[NV40_STATE_FRAGTEX0+i]); + samplers &= ~(1ULL << i); + } + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]); + if (state->hw[NV40_STATE_VTXBUF] && nv40->render_mode == HW) + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]); +} + +boolean +nv40_state_validate(struct nv40_context *nv40) +{ + boolean was_sw = nv40->fallback_swtnl ? TRUE : FALSE; + + if (nv40->render_mode != HW) { + /* Don't even bother trying to go back to hw if none + * of the states that caused swtnl previously have changed. + */ + if ((nv40->fallback_swtnl & nv40->dirty) + != nv40->fallback_swtnl) + return FALSE; + + /* Attempt to go to hwtnl again */ + nv40->pipe.flush(&nv40->pipe, 0, NULL); + nv40->dirty |= (NV40_NEW_VIEWPORT | + NV40_NEW_VERTPROG | + NV40_NEW_ARRAYS); + nv40->render_mode = HW; + } + + nv40_state_do_validate(nv40, render_states); + if (nv40->fallback_swtnl || nv40->fallback_swrast) + return FALSE; + + if (was_sw) + NOUVEAU_ERR("swtnl->hw\n"); + + return TRUE; +} + +boolean +nv40_state_validate_swtnl(struct nv40_context *nv40) +{ + struct draw_context *draw = nv40->draw; + + /* Setup for swtnl */ + if (nv40->render_mode == HW) { + NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl); + nv40->pipe.flush(&nv40->pipe, 0, NULL); + nv40->dirty |= (NV40_NEW_VIEWPORT | + NV40_NEW_VERTPROG | + NV40_NEW_ARRAYS); + nv40->render_mode = SWTNL; + } + + if (nv40->draw_dirty & NV40_NEW_VERTPROG) + draw_bind_vertex_shader(draw, nv40->vertprog->draw); + + if (nv40->draw_dirty & NV40_NEW_RAST) + draw_set_rasterizer_state(draw, &nv40->rasterizer->pipe); + + if (nv40->draw_dirty & NV40_NEW_UCP) + draw_set_clip_state(draw, &nv40->clip); + + if (nv40->draw_dirty & NV40_NEW_VIEWPORT) + draw_set_viewport_state(draw, &nv40->viewport); + + if (nv40->draw_dirty & NV40_NEW_ARRAYS) { + draw_set_edgeflags(draw, nv40->edgeflags); + draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf); + draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt); + } + + nv40_state_do_validate(nv40, swtnl_states); + if (nv40->fallback_swrast) { + NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast); + return FALSE; + } + + nv40->draw_dirty = 0; + return TRUE; +} + diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c new file mode 100644 index 00000000000..88baf61ffb3 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -0,0 +1,144 @@ +#include "nv40_context.h" + +static boolean +nv40_state_framebuffer_validate(struct nv40_context *nv40) +{ + struct pipe_framebuffer_state *fb = &nv40->framebuffer; + struct pipe_surface *rt[4], *zeta; + uint32_t rt_enable, rt_format; + int i, colour_format = 0, zeta_format = 0; + struct nouveau_stateobj *so = so_new(64, 10); + unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM; + unsigned w = fb->width; + unsigned h = fb->height; + + rt_enable = 0; + for (i = 0; i < fb->num_cbufs; i++) { + if (colour_format) { + assert(colour_format == fb->cbufs[i]->format); + } else { + colour_format = fb->cbufs[i]->format; + rt_enable |= (NV40TCL_RT_ENABLE_COLOR0 << i); + rt[i] = fb->cbufs[i]; + } + } + + if (rt_enable & (NV40TCL_RT_ENABLE_COLOR1 | NV40TCL_RT_ENABLE_COLOR2 | + NV40TCL_RT_ENABLE_COLOR3)) + rt_enable |= NV40TCL_RT_ENABLE_MRT; + + if (fb->zsbuf) { + zeta_format = fb->zsbuf->format; + zeta = fb->zsbuf; + } + + rt_format = NV40TCL_RT_FORMAT_TYPE_LINEAR; + + switch (colour_format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case 0: + rt_format |= NV40TCL_RT_FORMAT_COLOR_A8R8G8B8; + break; + case PIPE_FORMAT_R5G6B5_UNORM: + rt_format |= NV40TCL_RT_FORMAT_COLOR_R5G6B5; + break; + default: + assert(0); + } + + switch (zeta_format) { + case PIPE_FORMAT_Z16_UNORM: + rt_format |= NV40TCL_RT_FORMAT_ZETA_Z16; + break; + case PIPE_FORMAT_Z24S8_UNORM: + case 0: + rt_format |= NV40TCL_RT_FORMAT_ZETA_Z24S8; + break; + default: + assert(0); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) { + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR0, 1); + so_reloc (so, rt[0]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->screen->curie, NV40TCL_COLOR0_PITCH, 2); + so_data (so, rt[0]->pitch * rt[0]->cpp); + so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) { + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR1, 1); + so_reloc (so, rt[1]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->screen->curie, NV40TCL_COLOR1_OFFSET, 2); + so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_data (so, rt[1]->pitch * rt[1]->cpp); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) { + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR2, 1); + so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->screen->curie, NV40TCL_COLOR2_OFFSET, 1); + so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->screen->curie, NV40TCL_COLOR2_PITCH, 1); + so_data (so, rt[2]->pitch * rt[2]->cpp); + } + + if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) { + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR3, 1); + so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->screen->curie, NV40TCL_COLOR3_OFFSET, 1); + so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->screen->curie, NV40TCL_COLOR3_PITCH, 1); + so_data (so, rt[3]->pitch * rt[3]->cpp); + } + + if (zeta_format) { + so_method(so, nv40->screen->curie, NV40TCL_DMA_ZETA, 1); + so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR, + nv40->nvws->channel->vram->handle, + nv40->nvws->channel->gart->handle); + so_method(so, nv40->screen->curie, NV40TCL_ZETA_OFFSET, 1); + so_reloc (so, zeta->buffer, zeta->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->screen->curie, NV40TCL_ZETA_PITCH, 1); + so_data (so, zeta->pitch * zeta->cpp); + } + + so_method(so, nv40->screen->curie, NV40TCL_RT_ENABLE, 1); + so_data (so, rt_enable); + so_method(so, nv40->screen->curie, NV40TCL_RT_HORIZ, 3); + so_data (so, (w << 16) | 0); + so_data (so, (h << 16) | 0); + so_data (so, rt_format); + so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_HORIZ, 2); + so_data (so, (w << 16) | 0); + so_data (so, (h << 16) | 0); + so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); + so_data (so, ((w - 1) << 16) | 0); + so_data (so, ((h - 1) << 16) | 0); + so_method(so, nv40->screen->curie, 0x1d88, 1); + so_data (so, (1 << 12) | h); + + so_ref(so, &nv40->state.hw[NV40_STATE_FB]); + return TRUE; +} + +struct nv40_state_entry nv40_state_framebuffer = { + .validate = nv40_state_framebuffer_validate, + .dirty = { + .pipe = NV40_NEW_FB, + .hw = NV40_STATE_FB + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_rasterizer.c b/src/gallium/drivers/nv40/nv40_state_rasterizer.c new file mode 100644 index 00000000000..9ecda5990f0 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_rasterizer.c @@ -0,0 +1,17 @@ +#include "nv40_context.h" + +static boolean +nv40_state_rasterizer_validate(struct nv40_context *nv40) +{ + so_ref(nv40->rasterizer->so, + &nv40->state.hw[NV40_STATE_RAST]); + return TRUE; +} + +struct nv40_state_entry nv40_state_rasterizer = { + .validate = nv40_state_rasterizer_validate, + .dirty = { + .pipe = NV40_NEW_RAST, + .hw = NV40_STATE_RAST + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c new file mode 100644 index 00000000000..285239ef419 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -0,0 +1,35 @@ +#include "nv40_context.h" + +static boolean +nv40_state_scissor_validate(struct nv40_context *nv40) +{ + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct pipe_scissor_state *s = &nv40->scissor; + struct nouveau_stateobj *so; + + if (nv40->state.hw[NV40_STATE_SCISSOR] && + (rast->scissor == 0 && nv40->state.scissor_enabled == 0)) + return FALSE; + nv40->state.scissor_enabled = rast->scissor; + + so = so_new(3, 0); + so_method(so, nv40->screen->curie, NV40TCL_SCISSOR_HORIZ, 2); + if (nv40->state.scissor_enabled) { + so_data (so, ((s->maxx - s->minx) << 16) | s->minx); + so_data (so, ((s->maxy - s->miny) << 16) | s->miny); + } else { + so_data (so, 4096 << 16); + so_data (so, 4096 << 16); + } + + so_ref(so, &nv40->state.hw[NV40_STATE_SCISSOR]); + return TRUE; +} + +struct nv40_state_entry nv40_state_scissor = { + .validate = nv40_state_scissor_validate, + .dirty = { + .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, + .hw = NV40_STATE_SCISSOR + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c new file mode 100644 index 00000000000..b51024ad9b2 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -0,0 +1,39 @@ +#include "nv40_context.h" + +static boolean +nv40_state_stipple_validate(struct nv40_context *nv40) +{ + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct nouveau_grobj *curie = nv40->screen->curie; + struct nouveau_stateobj *so; + + if (nv40->state.hw[NV40_STATE_STIPPLE] && + (rast->poly_stipple_enable == 0 && nv40->state.stipple_enabled == 0)) + return FALSE; + + if (rast->poly_stipple_enable) { + unsigned i; + + so = so_new(35, 0); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, 1); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); + for (i = 0; i < 32; i++) + so_data(so, nv40->stipple[i]); + } else { + so = so_new(2, 0); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, 0); + } + + so_ref(so, &nv40->state.hw[NV40_STATE_STIPPLE]); + return TRUE; +} + +struct nv40_state_entry nv40_state_stipple = { + .validate = nv40_state_stipple_validate, + .dirty = { + .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, + .hw = NV40_STATE_STIPPLE, + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c new file mode 100644 index 00000000000..869a55b4053 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -0,0 +1,67 @@ +#include "nv40_context.h" + +static boolean +nv40_state_viewport_validate(struct nv40_context *nv40) +{ + struct pipe_viewport_state *vpt = &nv40->viewport; + struct nouveau_stateobj *so; + unsigned bypass; + + if (nv40->render_mode == HW && !nv40->rasterizer->pipe.bypass_clipping) + bypass = 0; + else + bypass = 1; + + if (nv40->state.hw[NV40_STATE_VIEWPORT] && + (bypass || !(nv40->dirty & NV40_NEW_VIEWPORT)) && + nv40->state.viewport_bypass == bypass) + return FALSE; + nv40->state.viewport_bypass = bypass; + + so = so_new(11, 0); + if (!bypass) { + so_method(so, nv40->screen->curie, + NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(vpt->translate[0])); + so_data (so, fui(vpt->translate[1])); + so_data (so, fui(vpt->translate[2])); + so_data (so, fui(vpt->translate[3])); + so_data (so, fui(vpt->scale[0])); + so_data (so, fui(vpt->scale[1])); + so_data (so, fui(vpt->scale[2])); + so_data (so, fui(vpt->scale[3])); + so_method(so, nv40->screen->curie, 0x1d78, 1); + so_data (so, 1); + } else { + so_method(so, nv40->screen->curie, + NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(1.0)); + so_data (so, fui(1.0)); + so_data (so, fui(1.0)); + so_data (so, fui(0.0)); + /* Not entirely certain what this is yet. The DDX uses this + * value also as it fixes rendering when you pass + * pre-transformed vertices to the GPU. My best gusss is that + * this bypasses some culling/clipping stage. Might be worth + * noting that points/lines are uneffected by whatever this + * value fixes, only filled polygons are effected. + */ + so_method(so, nv40->screen->curie, 0x1d78, 1); + so_data (so, 0x110); + } + + so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]); + return TRUE; +} + +struct nv40_state_entry nv40_state_viewport = { + .validate = nv40_state_viewport_validate, + .dirty = { + .pipe = NV40_NEW_VIEWPORT | NV40_NEW_RAST, + .hw = NV40_STATE_VIEWPORT + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_zsa.c b/src/gallium/drivers/nv40/nv40_state_zsa.c new file mode 100644 index 00000000000..fb760677c88 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_zsa.c @@ -0,0 +1,17 @@ +#include "nv40_context.h" + +static boolean +nv40_state_zsa_validate(struct nv40_context *nv40) +{ + so_ref(nv40->zsa->so, + &nv40->state.hw[NV40_STATE_ZSA]); + return TRUE; +} + +struct nv40_state_entry nv40_state_zsa = { + .validate = nv40_state_zsa_validate, + .dirty = { + .pipe = NV40_NEW_ZSA, + .hw = NV40_STATE_ZSA + } +}; diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c new file mode 100644 index 00000000000..c0d135eb36d --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -0,0 +1,77 @@ + +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#include "nv40_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_inlines.h" +#include "util/p_tile.h" + +static void +nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip, + struct pipe_surface *dest, unsigned destx, unsigned desty, + struct pipe_surface *src, unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_winsys *nvws = nv40->nvws; + + if (do_flip) { + /*XXX: This dodgyness will do for now for correctness. But, + * need to investigate whether the 2D engine is able to + * manage a flip (perhaps SIFM?), if not, use the 3D engine + */ + desty += height; + while (height--) { + nvws->surface_copy(nvws, dest, destx, desty--, src, + srcx, srcy++, width, 1); + } + } else { + nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, + width, height); + } +} + +static void +nv40_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, + unsigned destx, unsigned desty, unsigned width, + unsigned height, unsigned value) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_winsys *nvws = nv40->nvws; + + nvws->surface_fill(nvws, dest, destx, desty, width, height, value); +} + +void +nv40_init_surface_functions(struct nv40_context *nv40) +{ + nv40->pipe.surface_copy = nv40_surface_copy; + nv40->pipe.surface_fill = nv40_surface_fill; +} diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c new file mode 100644 index 00000000000..93669e6192f --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -0,0 +1,560 @@ +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" +#include "nv40_state.h" + +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_pushbuf.h" +#include "nouveau/nouveau_util.h" + +#define FORCE_SWTNL 0 + +static INLINE int +nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) +{ + char fs[128]; + + switch (pipe) { + case PIPE_FORMAT_R32_FLOAT: + case PIPE_FORMAT_R32G32_FLOAT: + case PIPE_FORMAT_R32G32B32_FLOAT: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + *fmt = NV40TCL_VTXFMT_TYPE_FLOAT; + break; + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8G8_UNORM: + case PIPE_FORMAT_R8G8B8_UNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM: + *fmt = NV40TCL_VTXFMT_TYPE_UBYTE; + break; + case PIPE_FORMAT_R16_SSCALED: + case PIPE_FORMAT_R16G16_SSCALED: + case PIPE_FORMAT_R16G16B16_SSCALED: + case PIPE_FORMAT_R16G16B16A16_SSCALED: + *fmt = NV40TCL_VTXFMT_TYPE_USHORT; + break; + default: + pf_sprint_name(fs, pipe); + NOUVEAU_ERR("Unknown format %s\n", fs); + return 1; + } + + switch (pipe) { + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R32_FLOAT: + case PIPE_FORMAT_R16_SSCALED: + *ncomp = 1; + break; + case PIPE_FORMAT_R8G8_UNORM: + case PIPE_FORMAT_R32G32_FLOAT: + case PIPE_FORMAT_R16G16_SSCALED: + *ncomp = 2; + break; + case PIPE_FORMAT_R8G8B8_UNORM: + case PIPE_FORMAT_R32G32B32_FLOAT: + case PIPE_FORMAT_R16G16B16_SSCALED: + *ncomp = 3; + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + case PIPE_FORMAT_R16G16B16A16_SSCALED: + *ncomp = 4; + break; + default: + pf_sprint_name(fs, pipe); + NOUVEAU_ERR("Unknown format %s\n", fs); + return 1; + } + + return 0; +} + +static boolean +nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, + unsigned ib_size) +{ + struct pipe_screen *pscreen = &nv40->screen->pipe; + unsigned type; + + if (!ib) { + nv40->idxbuf = NULL; + nv40->idxbuf_format = 0xdeadbeef; + return FALSE; + } + + if (!pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF) || ib_size == 1) + return FALSE; + + switch (ib_size) { + case 2: + type = NV40TCL_IDXBUF_FORMAT_TYPE_U16; + break; + case 4: + type = NV40TCL_IDXBUF_FORMAT_TYPE_U32; + break; + default: + return FALSE; + } + + if (ib != nv40->idxbuf || + type != nv40->idxbuf_format) { + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->idxbuf = ib; + nv40->idxbuf_format = type; + } + + return TRUE; +} + +static boolean +nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so, + int attrib, struct pipe_vertex_element *ve, + struct pipe_vertex_buffer *vb) +{ + struct pipe_winsys *ws = nv40->pipe.winsys; + struct nouveau_grobj *curie = nv40->screen->curie; + unsigned type, ncomp; + void *map; + + if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) + return FALSE; + + map = ws->buffer_map(ws, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); + map += vb->buffer_offset + ve->src_offset; + + switch (type) { + case NV40TCL_VTXFMT_TYPE_FLOAT: + { + float *v = map; + + switch (ncomp) { + case 4: + so_method(so, curie, NV40TCL_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, curie, NV40TCL_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, curie, NV40TCL_VTX_ATTR_2F_X(attrib), 2); + so_data (so, fui(v[0])); + so_data (so, fui(v[1])); + break; + case 1: + so_method(so, curie, NV40TCL_VTX_ATTR_1F(attrib), 1); + so_data (so, fui(v[0])); + break; + default: + ws->buffer_unmap(ws, vb->buffer); + return FALSE; + } + } + break; + default: + ws->buffer_unmap(ws, vb->buffer); + return FALSE; + } + + ws->buffer_unmap(ws, vb->buffer); + + return TRUE; +} + +boolean +nv40_draw_arrays(struct pipe_context *pipe, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_channel *chan = nv40->nvws->channel; + unsigned restart; + + nv40_vbo_set_idxbuf(nv40, NULL, 0); + if (FORCE_SWTNL || !nv40_state_validate(nv40)) { + return nv40_draw_elements_swtnl(pipe, NULL, 0, + mode, start, count); + } + + while (count) { + unsigned vc, nr; + + nv40_state_emit(nv40); + + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + mode, start, count, &restart); + if (!vc) { + FIRE_RING(NULL); + continue; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + nr = (vc & 0xff); + if (nr) { + BEGIN_RING(curie, NV40TCL_VB_VERTEX_BATCH, 1); + OUT_RING (((nr - 1) << 24) | start); + start += nr; + } + + nr = vc >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; + + nr -= push; + + BEGIN_RING_NI(curie, NV40TCL_VB_VERTEX_BATCH, push); + while (push--) { + OUT_RING(((0x100 - 1) << 24) | start); + start += 0x100; + } + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + count -= vc; + start = restart; + } + + pipe->flush(pipe, 0, NULL); + return TRUE; +} + +static INLINE void +nv40_draw_elements_u08(struct nv40_context *nv40, void *ib, + unsigned mode, unsigned start, unsigned count) +{ + struct nouveau_channel *chan = nv40->nvws->channel; + + while (count) { + uint8_t *elts = (uint8_t *)ib + start; + unsigned vc, push, restart; + + nv40_state_emit(nv40); + + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2, + mode, start, count, &restart); + if (vc == 0) { + FIRE_RING(NULL); + continue; + } + count -= vc; + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + if (vc & 1) { + BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; vc--; + } + + while (vc) { + unsigned i; + + push = MIN2(vc, 2047 * 2); + + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1); + for (i = 0; i < push; i+=2) + OUT_RING((elts[i+1] << 16) | elts[i]); + + vc -= push; + elts += push; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + start = restart; + } +} + +static INLINE void +nv40_draw_elements_u16(struct nv40_context *nv40, void *ib, + unsigned mode, unsigned start, unsigned count) +{ + struct nouveau_channel *chan = nv40->nvws->channel; + + while (count) { + uint16_t *elts = (uint16_t *)ib + start; + unsigned vc, push, restart; + + nv40_state_emit(nv40); + + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2, + mode, start, count, &restart); + if (vc == 0) { + FIRE_RING(NULL); + continue; + } + count -= vc; + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + if (vc & 1) { + BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; vc--; + } + + while (vc) { + unsigned i; + + push = MIN2(vc, 2047 * 2); + + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1); + for (i = 0; i < push; i+=2) + OUT_RING((elts[i+1] << 16) | elts[i]); + + vc -= push; + elts += push; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + start = restart; + } +} + +static INLINE void +nv40_draw_elements_u32(struct nv40_context *nv40, void *ib, + unsigned mode, unsigned start, unsigned count) +{ + struct nouveau_channel *chan = nv40->nvws->channel; + + while (count) { + uint32_t *elts = (uint32_t *)ib + start; + unsigned vc, push, restart; + + nv40_state_emit(nv40); + + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 5, 1, + mode, start, count, &restart); + if (vc == 0) { + FIRE_RING(NULL); + continue; + } + count -= vc; + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + while (vc) { + push = MIN2(vc, 2047); + + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U32, push); + OUT_RINGp (elts, push); + + vc -= push; + elts += push; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + start = restart; + } +} + +static boolean +nv40_draw_elements_inline(struct pipe_context *pipe, + struct pipe_buffer *ib, unsigned ib_size, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + void *map; + + map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); + if (!ib) { + NOUVEAU_ERR("failed mapping ib\n"); + return FALSE; + } + + switch (ib_size) { + case 1: + nv40_draw_elements_u08(nv40, map, mode, start, count); + break; + case 2: + nv40_draw_elements_u16(nv40, map, mode, start, count); + break; + case 4: + nv40_draw_elements_u32(nv40, map, mode, start, count); + break; + default: + NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); + break; + } + + ws->buffer_unmap(ws, ib); + return TRUE; +} + +static boolean +nv40_draw_elements_vbo(struct pipe_context *pipe, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_channel *chan = nv40->nvws->channel; + unsigned restart; + + while (count) { + unsigned nr, vc; + + nv40_state_emit(nv40); + + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + mode, start, count, &restart); + if (!vc) { + FIRE_RING(NULL); + continue; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + nr = (vc & 0xff); + if (nr) { + BEGIN_RING(curie, NV40TCL_VB_INDEX_BATCH, 1); + OUT_RING (((nr - 1) << 24) | start); + start += nr; + } + + nr = vc >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; + + nr -= push; + + BEGIN_RING_NI(curie, NV40TCL_VB_INDEX_BATCH, push); + while (push--) { + OUT_RING(((0x100 - 1) << 24) | start); + start += 0x100; + } + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + count -= vc; + start = restart; + } + + return TRUE; +} + +boolean +nv40_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + boolean idxbuf; + + idxbuf = nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize); + if (FORCE_SWTNL || !nv40_state_validate(nv40)) { + return nv40_draw_elements_swtnl(pipe, NULL, 0, + mode, start, count); + } + + if (idxbuf) { + nv40_draw_elements_vbo(pipe, mode, start, count); + } else { + nv40_draw_elements_inline(pipe, indexBuffer, indexSize, + mode, start, count); + } + + pipe->flush(pipe, 0, NULL); + return TRUE; +} + +static boolean +nv40_vbo_validate(struct nv40_context *nv40) +{ + struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL; + struct nouveau_grobj *curie = nv40->screen->curie; + struct pipe_buffer *ib = nv40->idxbuf; + unsigned ib_format = nv40->idxbuf_format; + unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + int hw; + + if (nv40->edgeflags) { + nv40->fallback_swtnl |= NV40_NEW_ARRAYS; + return FALSE; + } + + vtxbuf = so_new(20, 18); + so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt_nr); + vtxfmt = so_new(17, 0); + so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt_nr); + + for (hw = 0; hw < nv40->vtxelt_nr; hw++) { + struct pipe_vertex_element *ve; + struct pipe_vertex_buffer *vb; + unsigned type, ncomp; + + ve = &nv40->vtxelt[hw]; + vb = &nv40->vtxbuf[ve->vertex_buffer_index]; + + if (!vb->pitch) { + if (!sattr) + sattr = so_new(16 * 5, 0); + + if (nv40_vbo_static_attrib(nv40, sattr, hw, ve, vb)) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); + continue; + } + } + + if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) { + nv40->fallback_swtnl |= NV40_NEW_ARRAYS; + so_ref(NULL, &vtxbuf); + so_ref(NULL, &vtxfmt); + return FALSE; + } + + so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset, + vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, + 0, NV40TCL_VTXBUF_ADDRESS_DMA1); + so_data (vtxfmt, ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) | + (ncomp << NV40TCL_VTXFMT_SIZE_SHIFT) | type)); + } + + if (ib) { + so_method(vtxbuf, curie, NV40TCL_IDXBUF_ADDRESS, 2); + so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0); + so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR, + 0, NV40TCL_IDXBUF_FORMAT_DMA1); + } + + so_method(vtxbuf, curie, 0x1710, 1); + so_data (vtxbuf, 0); + + so_ref(vtxbuf, &nv40->state.hw[NV40_STATE_VTXBUF]); + nv40->state.dirty |= (1ULL << NV40_STATE_VTXBUF); + so_ref(vtxfmt, &nv40->state.hw[NV40_STATE_VTXFMT]); + nv40->state.dirty |= (1ULL << NV40_STATE_VTXFMT); + so_ref(sattr, &nv40->state.hw[NV40_STATE_VTXATTR]); + nv40->state.dirty |= (1ULL << NV40_STATE_VTXATTR); + return FALSE; +} + +struct nv40_state_entry nv40_state_vbo = { + .validate = nv40_vbo_validate, + .dirty = { + .pipe = NV40_NEW_ARRAYS, + .hw = 0, + } +}; + diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c new file mode 100644 index 00000000000..1e486a66ef0 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -0,0 +1,1070 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" + +#include "nv40_context.h" +#include "nv40_state.h" + +/* TODO (at least...): + * 1. Indexed consts + ARL + * 3. NV_vp11, NV_vp2, NV_vp3 features + * - extra arith opcodes + * - branching + * - texture sampling + * - indexed attribs + * - indexed results + * 4. bugs + */ + +#define SWZ_X 0 +#define SWZ_Y 1 +#define SWZ_Z 2 +#define SWZ_W 3 +#define MASK_X 8 +#define MASK_Y 4 +#define MASK_Z 2 +#define MASK_W 1 +#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W) +#define DEF_SCALE 0 +#define DEF_CTEST 0 +#include "nv40_shader.h" + +#define swz(s,x,y,z,w) nv40_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w) +#define neg(s) nv40_sr_neg((s)) +#define abs(s) nv40_sr_abs((s)) + +#define NV40_VP_INST_DEST_CLIP(n) ((~0 - 6) + (n)) + +struct nv40_vpc { + struct nv40_vertex_program *vp; + + struct nv40_vertex_program_exec *vpi; + + unsigned r_temps; + unsigned r_temps_discard; + struct nv40_sreg r_result[PIPE_MAX_SHADER_OUTPUTS]; + struct nv40_sreg *r_address; + struct nv40_sreg *r_temp; + + struct nv40_sreg *imm; + unsigned nr_imm; + + unsigned hpos_idx; +}; + +static struct nv40_sreg +temp(struct nv40_vpc *vpc) +{ + int idx = ffs(~vpc->r_temps) - 1; + + if (idx < 0) { + NOUVEAU_ERR("out of temps!!\n"); + assert(0); + return nv40_sr(NV40SR_TEMP, 0); + } + + vpc->r_temps |= (1 << idx); + vpc->r_temps_discard |= (1 << idx); + return nv40_sr(NV40SR_TEMP, idx); +} + +static INLINE void +release_temps(struct nv40_vpc *vpc) +{ + vpc->r_temps &= ~vpc->r_temps_discard; + vpc->r_temps_discard = 0; +} + +static struct nv40_sreg +constant(struct nv40_vpc *vpc, int pipe, float x, float y, float z, float w) +{ + struct nv40_vertex_program *vp = vpc->vp; + struct nv40_vertex_program_data *vpd; + int idx; + + if (pipe >= 0) { + for (idx = 0; idx < vp->nr_consts; idx++) { + if (vp->consts[idx].index == pipe) + return nv40_sr(NV40SR_CONST, idx); + } + } + + idx = vp->nr_consts++; + vp->consts = realloc(vp->consts, sizeof(*vpd) * vp->nr_consts); + vpd = &vp->consts[idx]; + + vpd->index = pipe; + vpd->value[0] = x; + vpd->value[1] = y; + vpd->value[2] = z; + vpd->value[3] = w; + return nv40_sr(NV40SR_CONST, idx); +} + +#define arith(cc,s,o,d,m,s0,s1,s2) \ + nv40_vp_arith((cc), (s), NV40_VP_INST_##o, (d), (m), (s0), (s1), (s2)) + +static void +emit_src(struct nv40_vpc *vpc, uint32_t *hw, int pos, struct nv40_sreg src) +{ + struct nv40_vertex_program *vp = vpc->vp; + uint32_t sr = 0; + + switch (src.type) { + case NV40SR_TEMP: + sr |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT); + sr |= (src.index << NV40_VP_SRC_TEMP_SRC_SHIFT); + break; + case NV40SR_INPUT: + sr |= (NV40_VP_SRC_REG_TYPE_INPUT << + NV40_VP_SRC_REG_TYPE_SHIFT); + vp->ir |= (1 << src.index); + hw[1] |= (src.index << NV40_VP_INST_INPUT_SRC_SHIFT); + break; + case NV40SR_CONST: + sr |= (NV40_VP_SRC_REG_TYPE_CONST << + NV40_VP_SRC_REG_TYPE_SHIFT); + assert(vpc->vpi->const_index == -1 || + vpc->vpi->const_index == src.index); + vpc->vpi->const_index = src.index; + break; + case NV40SR_NONE: + sr |= (NV40_VP_SRC_REG_TYPE_INPUT << + NV40_VP_SRC_REG_TYPE_SHIFT); + break; + default: + assert(0); + } + + if (src.negate) + sr |= NV40_VP_SRC_NEGATE; + + if (src.abs) + hw[0] |= (1 << (21 + pos)); + + sr |= ((src.swz[0] << NV40_VP_SRC_SWZ_X_SHIFT) | + (src.swz[1] << NV40_VP_SRC_SWZ_Y_SHIFT) | + (src.swz[2] << NV40_VP_SRC_SWZ_Z_SHIFT) | + (src.swz[3] << NV40_VP_SRC_SWZ_W_SHIFT)); + + switch (pos) { + case 0: + hw[1] |= ((sr & NV40_VP_SRC0_HIGH_MASK) >> + NV40_VP_SRC0_HIGH_SHIFT) << NV40_VP_INST_SRC0H_SHIFT; + hw[2] |= (sr & NV40_VP_SRC0_LOW_MASK) << + NV40_VP_INST_SRC0L_SHIFT; + break; + case 1: + hw[2] |= sr << NV40_VP_INST_SRC1_SHIFT; + break; + case 2: + hw[2] |= ((sr & NV40_VP_SRC2_HIGH_MASK) >> + NV40_VP_SRC2_HIGH_SHIFT) << NV40_VP_INST_SRC2H_SHIFT; + hw[3] |= (sr & NV40_VP_SRC2_LOW_MASK) << + NV40_VP_INST_SRC2L_SHIFT; + break; + default: + assert(0); + } +} + +static void +emit_dst(struct nv40_vpc *vpc, uint32_t *hw, int slot, struct nv40_sreg dst) +{ + struct nv40_vertex_program *vp = vpc->vp; + + switch (dst.type) { + case NV40SR_TEMP: + hw[3] |= NV40_VP_INST_DEST_MASK; + if (slot == 0) { + hw[0] |= (dst.index << + NV40_VP_INST_VEC_DEST_TEMP_SHIFT); + } else { + hw[3] |= (dst.index << + NV40_VP_INST_SCA_DEST_TEMP_SHIFT); + } + break; + case NV40SR_OUTPUT: + switch (dst.index) { + case NV40_VP_INST_DEST_COL0 : vp->or |= (1 << 0); break; + case NV40_VP_INST_DEST_COL1 : vp->or |= (1 << 1); break; + case NV40_VP_INST_DEST_BFC0 : vp->or |= (1 << 2); break; + case NV40_VP_INST_DEST_BFC1 : vp->or |= (1 << 3); break; + case NV40_VP_INST_DEST_FOGC : vp->or |= (1 << 4); break; + case NV40_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break; + case NV40_VP_INST_DEST_TC(0): vp->or |= (1 << 14); break; + case NV40_VP_INST_DEST_TC(1): vp->or |= (1 << 15); break; + case NV40_VP_INST_DEST_TC(2): vp->or |= (1 << 16); break; + case NV40_VP_INST_DEST_TC(3): vp->or |= (1 << 17); break; + case NV40_VP_INST_DEST_TC(4): vp->or |= (1 << 18); break; + case NV40_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break; + case NV40_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break; + case NV40_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break; + case NV40_VP_INST_DEST_CLIP(0): + vp->or |= (1 << 6); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE0; + dst.index = NV40_VP_INST_DEST_FOGC; + break; + case NV40_VP_INST_DEST_CLIP(1): + vp->or |= (1 << 7); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE1; + dst.index = NV40_VP_INST_DEST_FOGC; + break; + case NV40_VP_INST_DEST_CLIP(2): + vp->or |= (1 << 8); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE2; + dst.index = NV40_VP_INST_DEST_FOGC; + break; + case NV40_VP_INST_DEST_CLIP(3): + vp->or |= (1 << 9); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE3; + dst.index = NV40_VP_INST_DEST_PSZ; + break; + case NV40_VP_INST_DEST_CLIP(4): + vp->or |= (1 << 10); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE4; + dst.index = NV40_VP_INST_DEST_PSZ; + break; + case NV40_VP_INST_DEST_CLIP(5): + vp->or |= (1 << 11); + vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE5; + dst.index = NV40_VP_INST_DEST_PSZ; + break; + default: + break; + } + + hw[3] |= (dst.index << NV40_VP_INST_DEST_SHIFT); + if (slot == 0) { + hw[0] |= NV40_VP_INST_VEC_RESULT; + hw[0] |= NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20); + } else { + hw[3] |= NV40_VP_INST_SCA_RESULT; + hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK; + } + break; + default: + assert(0); + } +} + +static void +nv40_vp_arith(struct nv40_vpc *vpc, int slot, int op, + struct nv40_sreg dst, int mask, + struct nv40_sreg s0, struct nv40_sreg s1, + struct nv40_sreg s2) +{ + struct nv40_vertex_program *vp = vpc->vp; + uint32_t *hw; + + vp->insns = realloc(vp->insns, ++vp->nr_insns * sizeof(*vpc->vpi)); + vpc->vpi = &vp->insns[vp->nr_insns - 1]; + memset(vpc->vpi, 0, sizeof(*vpc->vpi)); + vpc->vpi->const_index = -1; + + hw = vpc->vpi->data; + + hw[0] |= (NV40_VP_INST_COND_TR << NV40_VP_INST_COND_SHIFT); + hw[0] |= ((0 << NV40_VP_INST_COND_SWZ_X_SHIFT) | + (1 << NV40_VP_INST_COND_SWZ_Y_SHIFT) | + (2 << NV40_VP_INST_COND_SWZ_Z_SHIFT) | + (3 << NV40_VP_INST_COND_SWZ_W_SHIFT)); + + if (slot == 0) { + hw[1] |= (op << NV40_VP_INST_VEC_OPCODE_SHIFT); + hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK; + hw[3] |= (mask << NV40_VP_INST_VEC_WRITEMASK_SHIFT); + } else { + hw[1] |= (op << NV40_VP_INST_SCA_OPCODE_SHIFT); + hw[0] |= (NV40_VP_INST_VEC_DEST_TEMP_MASK | (1 << 20)); + hw[3] |= (mask << NV40_VP_INST_SCA_WRITEMASK_SHIFT); + } + + emit_dst(vpc, hw, slot, dst); + emit_src(vpc, hw, 0, s0); + emit_src(vpc, hw, 1, s1); + emit_src(vpc, hw, 2, s2); +} + +static INLINE struct nv40_sreg +tgsi_src(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc) { + struct nv40_sreg src; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + src = nv40_sr(NV40SR_INPUT, fsrc->SrcRegister.Index); + break; + case TGSI_FILE_CONSTANT: + src = constant(vpc, fsrc->SrcRegister.Index, 0, 0, 0, 0); + break; + case TGSI_FILE_IMMEDIATE: + src = vpc->imm[fsrc->SrcRegister.Index]; + break; + case TGSI_FILE_TEMPORARY: + src = vpc->r_temp[fsrc->SrcRegister.Index]; + break; + default: + NOUVEAU_ERR("bad src file\n"); + break; + } + + src.abs = fsrc->SrcRegisterExtMod.Absolute; + src.negate = fsrc->SrcRegister.Negate; + src.swz[0] = fsrc->SrcRegister.SwizzleX; + src.swz[1] = fsrc->SrcRegister.SwizzleY; + src.swz[2] = fsrc->SrcRegister.SwizzleZ; + src.swz[3] = fsrc->SrcRegister.SwizzleW; + return src; +} + +static INLINE struct nv40_sreg +tgsi_dst(struct nv40_vpc *vpc, const struct tgsi_full_dst_register *fdst) { + struct nv40_sreg dst; + + switch (fdst->DstRegister.File) { + case TGSI_FILE_OUTPUT: + dst = vpc->r_result[fdst->DstRegister.Index]; + break; + case TGSI_FILE_TEMPORARY: + dst = vpc->r_temp[fdst->DstRegister.Index]; + break; + case TGSI_FILE_ADDRESS: + dst = vpc->r_address[fdst->DstRegister.Index]; + break; + default: + NOUVEAU_ERR("bad dst file\n"); + break; + } + + return dst; +} + +static INLINE int +tgsi_mask(uint tgsi) +{ + int mask = 0; + + if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X; + if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y; + if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z; + if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W; + return mask; +} + +static boolean +src_native_swz(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc, + struct nv40_sreg *src) +{ + const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + struct nv40_sreg tgsi = tgsi_src(vpc, fsrc); + uint mask = 0, zero_mask = 0, one_mask = 0, neg_mask = 0; + uint neg[4] = { fsrc->SrcRegisterExtSwz.NegateX, + fsrc->SrcRegisterExtSwz.NegateY, + fsrc->SrcRegisterExtSwz.NegateZ, + fsrc->SrcRegisterExtSwz.NegateW }; + uint c; + + for (c = 0; c < 4; c++) { + switch (tgsi_util_get_full_src_register_extswizzle(fsrc, c)) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + mask |= tgsi_mask(1 << c); + break; + case TGSI_EXTSWIZZLE_ZERO: + zero_mask |= tgsi_mask(1 << c); + tgsi.swz[c] = SWZ_X; + break; + case TGSI_EXTSWIZZLE_ONE: + one_mask |= tgsi_mask(1 << c); + tgsi.swz[c] = SWZ_X; + break; + default: + assert(0); + } + + if (!tgsi.negate && neg[c]) + neg_mask |= tgsi_mask(1 << c); + } + + if (mask == MASK_ALL && !neg_mask) + return TRUE; + + *src = temp(vpc); + + if (mask) + arith(vpc, 0, OP_MOV, *src, mask, tgsi, none, none); + + if (zero_mask) + arith(vpc, 0, OP_SFL, *src, zero_mask, *src, none, none); + + if (one_mask) + arith(vpc, 0, OP_STR, *src, one_mask, *src, none, none); + + if (neg_mask) { + struct nv40_sreg one = temp(vpc); + arith(vpc, 0, OP_STR, one, neg_mask, one, none, none); + arith(vpc, 0, OP_MUL, *src, neg_mask, *src, neg(one), none); + } + + return FALSE; +} + +static boolean +nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, + const struct tgsi_full_instruction *finst) +{ + struct nv40_sreg src[3], dst, tmp; + struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + int mask; + int ai = -1, ci = -1, ii = -1; + int i; + + if (finst->Instruction.Opcode == TGSI_OPCODE_END) + return TRUE; + + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) { + src[i] = tgsi_src(vpc, fsrc); + } + } + + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *fsrc; + + fsrc = &finst->FullSrcRegisters[i]; + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + case TGSI_FILE_CONSTANT: + case TGSI_FILE_TEMPORARY: + if (!src_native_swz(vpc, fsrc, &src[i])) + continue; + break; + default: + break; + } + + switch (fsrc->SrcRegister.File) { + case TGSI_FILE_INPUT: + if (ai == -1 || ai == fsrc->SrcRegister.Index) { + ai = fsrc->SrcRegister.Index; + src[i] = tgsi_src(vpc, fsrc); + } else { + src[i] = temp(vpc); + arith(vpc, 0, OP_MOV, src[i], MASK_ALL, + tgsi_src(vpc, fsrc), none, none); + } + break; + case TGSI_FILE_CONSTANT: + if ((ci == -1 && ii == -1) || + ci == fsrc->SrcRegister.Index) { + ci = fsrc->SrcRegister.Index; + src[i] = tgsi_src(vpc, fsrc); + } else { + src[i] = temp(vpc); + arith(vpc, 0, OP_MOV, src[i], MASK_ALL, + tgsi_src(vpc, fsrc), none, none); + } + break; + case TGSI_FILE_IMMEDIATE: + if ((ci == -1 && ii == -1) || + ii == fsrc->SrcRegister.Index) { + ii = fsrc->SrcRegister.Index; + src[i] = tgsi_src(vpc, fsrc); + } else { + src[i] = temp(vpc); + arith(vpc, 0, OP_MOV, src[i], MASK_ALL, + tgsi_src(vpc, fsrc), none, none); + } + break; + case TGSI_FILE_TEMPORARY: + /* handled above */ + break; + default: + NOUVEAU_ERR("bad src file\n"); + return FALSE; + } + } + + dst = tgsi_dst(vpc, &finst->FullDstRegisters[0]); + mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask); + + switch (finst->Instruction.Opcode) { + case TGSI_OPCODE_ABS: + arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none); + break; + case TGSI_OPCODE_ADD: + arith(vpc, 0, OP_ADD, dst, mask, src[0], none, src[1]); + break; + case TGSI_OPCODE_ARL: + arith(vpc, 0, OP_ARL, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_DP3: + arith(vpc, 0, OP_DP3, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DP4: + arith(vpc, 0, OP_DP4, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DPH: + arith(vpc, 0, OP_DPH, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_DST: + arith(vpc, 0, OP_DST, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_EX2: + arith(vpc, 1, OP_EX2, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_EXP: + arith(vpc, 1, OP_EXP, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_FLR: + arith(vpc, 0, OP_FLR, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_FRC: + arith(vpc, 0, OP_FRC, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_LG2: + arith(vpc, 1, OP_LG2, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_LIT: + arith(vpc, 1, OP_LIT, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_LOG: + arith(vpc, 1, OP_LOG, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_MAD: + arith(vpc, 0, OP_MAD, dst, mask, src[0], src[1], src[2]); + break; + case TGSI_OPCODE_MAX: + arith(vpc, 0, OP_MAX, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MIN: + arith(vpc, 0, OP_MIN, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_MOV: + arith(vpc, 0, OP_MOV, dst, mask, src[0], none, none); + break; + case TGSI_OPCODE_MUL: + arith(vpc, 0, OP_MUL, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_POW: + tmp = temp(vpc); + arith(vpc, 1, OP_LG2, tmp, MASK_X, none, none, + swz(src[0], X, X, X, X)); + arith(vpc, 0, OP_MUL, tmp, MASK_X, swz(tmp, X, X, X, X), + swz(src[1], X, X, X, X), none); + arith(vpc, 1, OP_EX2, dst, mask, none, none, + swz(tmp, X, X, X, X)); + break; + case TGSI_OPCODE_RCP: + arith(vpc, 1, OP_RCP, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_RET: + break; + case TGSI_OPCODE_RSQ: + arith(vpc, 1, OP_RSQ, dst, mask, none, none, src[0]); + break; + case TGSI_OPCODE_SGE: + arith(vpc, 0, OP_SGE, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SLT: + arith(vpc, 0, OP_SLT, dst, mask, src[0], src[1], none); + break; + case TGSI_OPCODE_SUB: + arith(vpc, 0, OP_ADD, dst, mask, src[0], none, neg(src[1])); + break; + case TGSI_OPCODE_XPD: + tmp = temp(vpc); + arith(vpc, 0, OP_MUL, tmp, mask, + swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none); + arith(vpc, 0, OP_MAD, dst, (mask & ~MASK_W), + swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y), + neg(tmp)); + break; + default: + NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode); + return FALSE; + } + + release_temps(vpc); + return TRUE; +} + +static boolean +nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, + const struct tgsi_full_declaration *fdec) +{ + unsigned idx = fdec->DeclarationRange.First; + int hw; + + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + hw = NV40_VP_INST_DEST_POS; + vpc->hpos_idx = idx; + break; + case TGSI_SEMANTIC_COLOR: + if (fdec->Semantic.SemanticIndex == 0) { + hw = NV40_VP_INST_DEST_COL0; + } else + if (fdec->Semantic.SemanticIndex == 1) { + hw = NV40_VP_INST_DEST_COL1; + } else { + NOUVEAU_ERR("bad colour semantic index\n"); + return FALSE; + } + break; + case TGSI_SEMANTIC_BCOLOR: + if (fdec->Semantic.SemanticIndex == 0) { + hw = NV40_VP_INST_DEST_BFC0; + } else + if (fdec->Semantic.SemanticIndex == 1) { + hw = NV40_VP_INST_DEST_BFC1; + } else { + NOUVEAU_ERR("bad bcolour semantic index\n"); + return FALSE; + } + break; + case TGSI_SEMANTIC_FOG: + hw = NV40_VP_INST_DEST_FOGC; + break; + case TGSI_SEMANTIC_PSIZE: + hw = NV40_VP_INST_DEST_PSZ; + break; + case TGSI_SEMANTIC_GENERIC: + if (fdec->Semantic.SemanticIndex <= 7) { + hw = NV40_VP_INST_DEST_TC(fdec->Semantic.SemanticIndex); + } else { + NOUVEAU_ERR("bad generic semantic index\n"); + return FALSE; + } + break; + default: + NOUVEAU_ERR("bad output semantic\n"); + return FALSE; + } + + vpc->r_result[idx] = nv40_sr(NV40SR_OUTPUT, hw); + return TRUE; +} + +static boolean +nv40_vertprog_prepare(struct nv40_vpc *vpc) +{ + struct tgsi_parse_context p; + int high_temp = -1, high_addr = -1, nr_imm = 0, i; + + tgsi_parse_init(&p, vpc->vp->pipe.tokens); + while (!tgsi_parse_end_of_tokens(&p)) { + const union tgsi_full_token *tok = &p.FullToken; + + tgsi_parse_token(&p); + switch(tok->Token.Type) { + case TGSI_TOKEN_TYPE_IMMEDIATE: + nr_imm++; + break; + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *fdec; + + fdec = &p.FullToken.FullDeclaration; + switch (fdec->Declaration.File) { + case TGSI_FILE_TEMPORARY: + if (fdec->DeclarationRange.Last > high_temp) { + high_temp = + fdec->DeclarationRange.Last; + } + break; +#if 0 /* this would be nice.. except gallium doesn't track it */ + case TGSI_FILE_ADDRESS: + if (fdec->DeclarationRange.Last > high_addr) { + high_addr = + fdec->DeclarationRange.Last; + } + break; +#endif + case TGSI_FILE_OUTPUT: + if (!nv40_vertprog_parse_decl_output(vpc, fdec)) + return FALSE; + break; + default: + break; + } + } + break; +#if 1 /* yay, parse instructions looking for address regs instead */ + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + const struct tgsi_full_instruction *finst; + const struct tgsi_full_dst_register *fdst; + + finst = &p.FullToken.FullInstruction; + fdst = &finst->FullDstRegisters[0]; + + if (fdst->DstRegister.File == TGSI_FILE_ADDRESS) { + if (fdst->DstRegister.Index > high_addr) + high_addr = fdst->DstRegister.Index; + } + + } + break; +#endif + default: + break; + } + } + tgsi_parse_free(&p); + + if (nr_imm) { + vpc->imm = CALLOC(nr_imm, sizeof(struct nv40_sreg)); + assert(vpc->imm); + } + + if (++high_temp) { + vpc->r_temp = CALLOC(high_temp, sizeof(struct nv40_sreg)); + for (i = 0; i < high_temp; i++) + vpc->r_temp[i] = temp(vpc); + } + + if (++high_addr) { + vpc->r_address = CALLOC(high_addr, sizeof(struct nv40_sreg)); + for (i = 0; i < high_addr; i++) + vpc->r_address[i] = temp(vpc); + } + + vpc->r_temps_discard = 0; + return TRUE; +} + +static void +nv40_vertprog_translate(struct nv40_context *nv40, + struct nv40_vertex_program *vp) +{ + struct tgsi_parse_context parse; + struct nv40_vpc *vpc = NULL; + struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); + int i; + + vpc = CALLOC(1, sizeof(struct nv40_vpc)); + if (!vpc) + return; + vpc->vp = vp; + + if (!nv40_vertprog_prepare(vpc)) { + FREE(vpc); + return; + } + + /* Redirect post-transform vertex position to a temp if user clip + * planes are enabled. We need to append code the the vtxprog + * to handle clip planes later. + */ + if (vp->ucp.nr) { + vpc->r_result[vpc->hpos_idx] = temp(vpc); + vpc->r_temps_discard = 0; + } + + tgsi_parse_init(&parse, vp->pipe.tokens); + + while (!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + const struct tgsi_full_immediate *imm; + + imm = &parse.FullToken.FullImmediate; + assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); +// assert(imm->Immediate.Size == 4); + vpc->imm[vpc->nr_imm++] = + constant(vpc, -1, + imm->u.ImmediateFloat32[0].Float, + imm->u.ImmediateFloat32[1].Float, + imm->u.ImmediateFloat32[2].Float, + imm->u.ImmediateFloat32[3].Float); + } + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + const struct tgsi_full_instruction *finst; + finst = &parse.FullToken.FullInstruction; + if (!nv40_vertprog_parse_instruction(vpc, finst)) + goto out_err; + } + break; + default: + break; + } + } + + /* Write out HPOS if it was redirected to a temp earlier */ + if (vpc->r_result[vpc->hpos_idx].type != NV40SR_OUTPUT) { + struct nv40_sreg hpos = nv40_sr(NV40SR_OUTPUT, + NV40_VP_INST_DEST_POS); + struct nv40_sreg htmp = vpc->r_result[vpc->hpos_idx]; + + arith(vpc, 0, OP_MOV, hpos, MASK_ALL, htmp, none, none); + } + + /* Insert code to handle user clip planes */ + for (i = 0; i < vp->ucp.nr; i++) { + struct nv40_sreg cdst = nv40_sr(NV40SR_OUTPUT, + NV40_VP_INST_DEST_CLIP(i)); + struct nv40_sreg ceqn = constant(vpc, -1, + nv40->clip.ucp[i][0], + nv40->clip.ucp[i][1], + nv40->clip.ucp[i][2], + nv40->clip.ucp[i][3]); + struct nv40_sreg htmp = vpc->r_result[vpc->hpos_idx]; + unsigned mask; + + switch (i) { + case 0: case 3: mask = MASK_Y; break; + case 1: case 4: mask = MASK_Z; break; + case 2: case 5: mask = MASK_W; break; + default: + NOUVEAU_ERR("invalid clip dist #%d\n", i); + goto out_err; + } + + arith(vpc, 0, OP_DP4, cdst, mask, htmp, ceqn, none); + } + + vp->insns[vp->nr_insns - 1].data[3] |= NV40_VP_INST_LAST; + vp->translated = TRUE; +out_err: + tgsi_parse_free(&parse); + if (vpc->r_temp) + FREE(vpc->r_temp); + if (vpc->r_address) + FREE(vpc->r_address); + if (vpc->imm) + FREE(vpc->imm); + FREE(vpc); +} + +static boolean +nv40_vertprog_validate(struct nv40_context *nv40) +{ + struct nouveau_winsys *nvws = nv40->nvws; + struct pipe_winsys *ws = nv40->pipe.winsys; + struct nouveau_grobj *curie = nv40->screen->curie; + struct nv40_vertex_program *vp; + struct pipe_buffer *constbuf; + boolean upload_code = FALSE, upload_data = FALSE; + int i; + + if (nv40->render_mode == HW) { + vp = nv40->vertprog; + constbuf = nv40->constbuf[PIPE_SHADER_VERTEX]; + + if ((nv40->dirty & NV40_NEW_UCP) || + memcmp(&nv40->clip, &vp->ucp, sizeof(vp->ucp))) { + nv40_vertprog_destroy(nv40, vp); + memcpy(&vp->ucp, &nv40->clip, sizeof(vp->ucp)); + } + } else { + vp = nv40->swtnl.vertprog; + constbuf = NULL; + } + + /* Translate TGSI shader into hw bytecode */ + if (vp->translated) + goto check_gpu_resources; + + nv40->fallback_swtnl &= ~NV40_NEW_VERTPROG; + nv40_vertprog_translate(nv40, vp); + if (!vp->translated) { + nv40->fallback_swtnl |= NV40_NEW_VERTPROG; + return FALSE; + } + +check_gpu_resources: + /* Allocate hw vtxprog exec slots */ + if (!vp->exec) { + struct nouveau_resource *heap = nv40->screen->vp_exec_heap; + struct nouveau_stateobj *so; + uint vplen = vp->nr_insns; + + if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) { + while (heap->next && heap->size < vplen) { + struct nv40_vertex_program *evict; + + evict = heap->next->priv; + nvws->res_free(&evict->exec); + } + + if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) + assert(0); + } + + so = so_new(7, 0); + so_method(so, curie, NV40TCL_VP_START_FROM_ID, 1); + so_data (so, vp->exec->start); + so_method(so, curie, NV40TCL_VP_ATTRIB_EN, 2); + so_data (so, vp->ir); + so_data (so, vp->or); + so_method(so, curie, NV40TCL_CLIP_PLANE_ENABLE, 1); + so_data (so, vp->clip_ctrl); + so_ref(so, &vp->so); + + upload_code = TRUE; + } + + /* Allocate hw vtxprog const slots */ + if (vp->nr_consts && !vp->data) { + struct nouveau_resource *heap = nv40->screen->vp_data_heap; + + if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) { + while (heap->next && heap->size < vp->nr_consts) { + struct nv40_vertex_program *evict; + + evict = heap->next->priv; + nvws->res_free(&evict->data); + } + + if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) + assert(0); + } + + /*XXX: handle this some day */ + assert(vp->data->start >= vp->data_start_min); + + upload_data = TRUE; + if (vp->data_start != vp->data->start) + upload_code = TRUE; + } + + /* If exec or data segments moved we need to patch the program to + * fixup offsets and register IDs. + */ + if (vp->exec_start != vp->exec->start) { + for (i = 0; i < vp->nr_insns; i++) { + struct nv40_vertex_program_exec *vpi = &vp->insns[i]; + + if (vpi->has_branch_offset) { + assert(0); + } + } + + vp->exec_start = vp->exec->start; + } + + if (vp->nr_consts && vp->data_start != vp->data->start) { + for (i = 0; i < vp->nr_insns; i++) { + struct nv40_vertex_program_exec *vpi = &vp->insns[i]; + + if (vpi->const_index >= 0) { + vpi->data[1] &= ~NV40_VP_INST_CONST_SRC_MASK; + vpi->data[1] |= + (vpi->const_index + vp->data->start) << + NV40_VP_INST_CONST_SRC_SHIFT; + + } + } + + vp->data_start = vp->data->start; + } + + /* Update + Upload constant values */ + if (vp->nr_consts) { + float *map = NULL; + + if (constbuf) { + map = ws->buffer_map(ws, constbuf, + PIPE_BUFFER_USAGE_CPU_READ); + } + + for (i = 0; i < vp->nr_consts; i++) { + struct nv40_vertex_program_data *vpd = &vp->consts[i]; + + if (vpd->index >= 0) { + if (!upload_data && + !memcmp(vpd->value, &map[vpd->index * 4], + 4 * sizeof(float))) + continue; + memcpy(vpd->value, &map[vpd->index * 4], + 4 * sizeof(float)); + } + + BEGIN_RING(curie, NV40TCL_VP_UPLOAD_CONST_ID, 5); + OUT_RING (i + vp->data->start); + OUT_RINGp ((uint32_t *)vpd->value, 4); + } + + if (constbuf) + ws->buffer_unmap(ws, constbuf); + } + + /* Upload vtxprog */ + if (upload_code) { +#if 0 + for (i = 0; i < vp->nr_insns; i++) { + NOUVEAU_MSG("VP %d: 0x%08x\n", i, vp->insns[i].data[0]); + NOUVEAU_MSG("VP %d: 0x%08x\n", i, vp->insns[i].data[1]); + NOUVEAU_MSG("VP %d: 0x%08x\n", i, vp->insns[i].data[2]); + NOUVEAU_MSG("VP %d: 0x%08x\n", i, vp->insns[i].data[3]); + } +#endif + BEGIN_RING(curie, NV40TCL_VP_UPLOAD_FROM_ID, 1); + OUT_RING (vp->exec->start); + for (i = 0; i < vp->nr_insns; i++) { + BEGIN_RING(curie, NV40TCL_VP_UPLOAD_INST(0), 4); + OUT_RINGp (vp->insns[i].data, 4); + } + } + + if (vp->so != nv40->state.hw[NV40_STATE_VERTPROG]) { + so_ref(vp->so, &nv40->state.hw[NV40_STATE_VERTPROG]); + return TRUE; + } + + return FALSE; +} + +void +nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp) +{ + struct nouveau_winsys *nvws = nv40->screen->nvws; + + vp->translated = FALSE; + + if (vp->nr_insns) { + FREE(vp->insns); + vp->insns = NULL; + vp->nr_insns = 0; + } + + if (vp->nr_consts) { + FREE(vp->consts); + vp->consts = NULL; + vp->nr_consts = 0; + } + + nvws->res_free(&vp->exec); + vp->exec_start = 0; + nvws->res_free(&vp->data); + vp->data_start = 0; + vp->data_start_min = 0; + + vp->ir = vp->or = vp->clip_ctrl = 0; + so_ref(NULL, &vp->so); +} + +struct nv40_state_entry nv40_state_vertprog = { + .validate = nv40_vertprog_validate, + .dirty = { + .pipe = NV40_NEW_VERTPROG | NV40_NEW_UCP, + .hw = NV40_STATE_VERTPROG, + } +}; + diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile new file mode 100644 index 00000000000..a62a4d961bc --- /dev/null +++ b/src/gallium/drivers/nv50/Makefile @@ -0,0 +1,27 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = nv50 + +DRIVER_SOURCES = \ + nv50_clear.c \ + nv50_context.c \ + nv50_draw.c \ + nv50_miptree.c \ + nv50_query.c \ + nv50_screen.c \ + nv50_state.c \ + nv50_state_validate.c \ + nv50_surface.c \ + nv50_vbo.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c new file mode 100644 index 00000000000..552b92f72e2 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_clear.c @@ -0,0 +1,12 @@ +#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, struct pipe_surface *ps, + unsigned clearValue) +{ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); +} diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c new file mode 100644 index 00000000000..a225c4bf728 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -0,0 +1,69 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv50_context.h" +#include "nv50_screen.h" + +static void +nv50_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) +{ + struct nv50_context *nv50 = (struct nv50_context *)pipe; + + FIRE_RING(fence); +} + +static void +nv50_destroy(struct pipe_context *pipe) +{ + struct nv50_context *nv50 = (struct nv50_context *)pipe; + + draw_destroy(nv50->draw); + free(nv50); +} + + +static void +nv50_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +{ +} + +struct pipe_context * +nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) +{ + 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->pctx_id = pctx_id; + + nv50->pipe.winsys = pipe_winsys; + nv50->pipe.screen = pscreen; + + nv50->pipe.destroy = nv50_destroy; + + nv50->pipe.set_edgeflags = nv50_set_edgeflags; + nv50->pipe.draw_arrays = nv50_draw_arrays; + nv50->pipe.draw_elements = nv50_draw_elements; + nv50->pipe.clear = nv50_clear; + + nv50->pipe.flush = nv50_flush; + + nv50_init_surface_functions(nv50); + nv50_init_state_functions(nv50); + nv50_init_query_functions(nv50); + + nv50->draw = draw_create(); + assert(nv50->draw); + draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50)); + + return &nv50->pipe; +} + + diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h new file mode 100644 index 00000000000..e68c702deae --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -0,0 +1,98 @@ +#ifndef __NV50_CONTEXT_H__ +#define __NV50_CONTEXT_H__ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "draw/draw_vertex.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_gldefs.h" + +#define NOUVEAU_PUSH_CONTEXT(ctx) \ + struct nv50_screen *ctx = nv50->screen +#include "nouveau/nouveau_push.h" + +#include "nv50_state.h" +#include "nv50_screen.h" + +#define NOUVEAU_ERR(fmt, args...) \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); +#define NOUVEAU_MSG(fmt, args...) \ + fprintf(stderr, "nouveau: "fmt, ##args); + +#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) + +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_context { + struct pipe_context pipe; + + struct nv50_screen *screen; + unsigned pctx_id; + + struct draw_context *draw; + + 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_poly_stipple stipple; + struct pipe_scissor_state scissor; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; +}; + +static INLINE struct nv50_context * +nv50_context(struct pipe_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_screen_init_miptree_functions(struct pipe_screen *pscreen); + +/* nv50_draw.c */ +extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50); + +/* nv50_vbo.c */ +extern boolean nv50_draw_arrays(struct pipe_context *, unsigned mode, + unsigned start, unsigned count); +extern boolean nv50_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, + unsigned count); + +/* nv50_clear.c */ +extern void nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + +extern boolean nv50_state_validate(struct nv50_context *nv50); + +#endif diff --git a/src/gallium/drivers/nv50/nv50_draw.c b/src/gallium/drivers/nv50/nv50_draw.c new file mode 100644 index 00000000000..d185d999502 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_draw.c @@ -0,0 +1,68 @@ +#include "draw/draw_pipe.h" +#include "pipe/p_util.h" + +#include "nv50_context.h" + +struct nv50_render_stage { + 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; +} + +static void +nv50_render_point(struct draw_stage *stage, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv50_render_line(struct draw_stage *stage, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv50_render_tri(struct draw_stage *stage, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv50_render_flush(struct draw_stage *stage, unsigned flags) +{ +} + +static void +nv50_render_reset_stipple_counter(struct draw_stage *stage) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv50_render_destroy(struct draw_stage *stage) +{ + free(stage); +} + +struct draw_stage * +nv50_draw_render_stage(struct nv50_context *nv50) +{ + 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; + + return &rs->stage; +} + diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c new file mode 100644 index 00000000000..ccb916d6acc --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -0,0 +1,98 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nv50_context.h" + +struct nv50_miptree { + struct pipe_texture base; + struct pipe_buffer *buffer; +}; + +static INLINE struct nv50_miptree * +nv50_miptree(struct pipe_texture *pt) +{ + return (struct nv50_miptree *)pt; +} + +static struct pipe_texture * +nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) +{ + struct pipe_winsys *ws = pscreen->winsys; + struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); + + NOUVEAU_ERR("unimplemented\n"); + + mt->base = *pt; + mt->base.refcount = 1; + mt->base.screen = pscreen; + + mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + 512*32*4); + if (!mt->buffer) { + FREE(mt); + return NULL; + } + + return &mt->base; +} + +static void +nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) +{ + struct pipe_winsys *ws = pscreen->winsys; + struct pipe_texture *pt = *ppt; + + NOUVEAU_ERR("unimplemented\n"); + + *ppt = NULL; + if (--pt->refcount <= 0) { + struct nv50_miptree *mt = nv50_miptree(pt); + + pipe_buffer_reference(ws, &mt->buffer, NULL); + FREE(mt); + } +} + +static struct pipe_surface * +nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) +{ + struct pipe_winsys *ws = pscreen->winsys; + struct nv50_miptree *mt = nv50_miptree(pt); + struct pipe_surface *ps; + + NOUVEAU_ERR("unimplemented\n"); + + ps = ws->surface_alloc(ws); + if (!ps) + return NULL; + + pipe_buffer_reference(ws, &ps->buffer, mt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = ps->width; + ps->offset = 0; + + return ps; +} + +static void +nv50_miptree_surface_del(struct pipe_screen *pscreen, + struct pipe_surface **psurface) +{ +} + +void +nv50_screen_init_miptree_functions(struct pipe_screen *pscreen) +{ + pscreen->texture_create = nv50_miptree_create; + pscreen->texture_release = nv50_miptree_release; + pscreen->get_tex_surface = nv50_miptree_surface_new; + pscreen->tex_surface_release = nv50_miptree_surface_del; +} + diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c new file mode 100644 index 00000000000..d8c3491c2c5 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -0,0 +1,47 @@ +#include "pipe/p_context.h" + +#include "nv50_context.h" + +static struct pipe_query * +nv50_query_create(struct pipe_context *pipe, unsigned type) +{ + NOUVEAU_ERR("unimplemented\n"); + return NULL; +} + +static void +nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *q) +{ + NOUVEAU_ERR("unimplemented\n"); +} + +static void +nv50_query_begin(struct pipe_context *pipe, struct pipe_query *q) +{ + NOUVEAU_ERR("unimplemented\n"); +} + +static void +nv50_query_end(struct pipe_context *pipe, struct pipe_query *q) +{ + NOUVEAU_ERR("unimplemented\n"); +} + +static boolean +nv50_query_result(struct pipe_context *pipe, struct pipe_query *q, + boolean wait, uint64 *result) +{ + NOUVEAU_ERR("unimplemented\n"); + *result = 0xdeadcafe; + return TRUE; +} + +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; +} diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c new file mode 100644 index 00000000000..29c057a1453 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -0,0 +1,241 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv50_context.h" +#include "nv50_screen.h" + +#include "nouveau/nouveau_stateobj.h" + +#define NV5X_GRCLASS5097_CHIPSETS 0x00000001 +#define NV8X_GRCLASS8297_CHIPSETS 0x00000010 +#define NV9X_GRCLASS8297_CHIPSETS 0x00000004 + +static boolean +nv50_screen_is_format_supported(struct pipe_screen *pscreen, + enum pipe_format format, uint type) +{ + switch (type) { + case PIPE_SURFACE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + return TRUE; + default: + break; + } + break; + case PIPE_TEXTURE: + switch (format) { + case PIPE_FORMAT_I8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + } + + return FALSE; +} + +static const char * +nv50_screen_get_name(struct pipe_screen *pscreen) +{ + struct nv50_screen *screen = nv50_screen(pscreen); + struct nouveau_device *dev = screen->nvws->channel->device; + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); + return buffer; +} + +static const char * +nv50_screen_get_vendor(struct pipe_screen *pscreen) +{ + return "nouveau"; +} + +static int +nv50_screen_get_param(struct pipe_screen *pscreen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 32; + case PIPE_CAP_NPOT_TEXTURES: + return 0; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 0; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 8; + case PIPE_CAP_OCCLUSION_QUERY: + return 0; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 0; + 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 NOUVEAU_CAP_HW_VTXBUF: + case NOUVEAU_CAP_HW_IDXBUF: + return 0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv50_screen_get_paramf(struct pipe_screen *pscreen, int 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_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, + unsigned flags ) +{ + struct pipe_winsys *ws = screen->winsys; + void *map; + + map = ws->buffer_map(ws, surface->buffer, flags); + if (!map) + return NULL; + + return map + surface->offset; +} + +static void +nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) +{ + struct pipe_winsys *ws = screen->winsys; + + ws->buffer_unmap(ws, surface->buffer); +} + +static void +nv50_screen_destroy(struct pipe_screen *pscreen) +{ + FREE(pscreen); +} + +struct pipe_screen * +nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) +{ + struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); + struct nouveau_stateobj *so; + unsigned tesla_class = 0, ret; + unsigned chipset = nvws->channel->device->chipset; + int i; + + if (!screen) + return NULL; + screen->nvws = nvws; + + /* 3D object */ + if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) { + NOUVEAU_ERR("Not a G8x chipset\n"); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + switch (chipset & 0xf0) { + case 0x50: + if (NV5X_GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) + tesla_class = 0x5097; + break; + case 0x80: + if (NV8X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) + tesla_class = 0x8297; + break; + case 0x90: + if (NV9X_GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) + tesla_class = 0x8297; + break; + default: + break; + } + + if (tesla_class == 0) { + NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + ret = nvws->grobj_alloc(nvws, tesla_class, &screen->tesla); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + /* Sync notifier */ + ret = nvws->notifier_alloc(nvws, 1, &screen->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + + /* Static tesla init */ + so = so_new(128, 0); + so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1); + so_data (so, screen->sync->handle); + so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY0(0), + NV50TCL_DMA_IN_MEMORY0__SIZE); + for (i = 0; i < NV50TCL_DMA_IN_MEMORY0__SIZE; i++) + so_data(so, nvws->channel->vram->handle); + so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY1(0), + NV50TCL_DMA_IN_MEMORY1__SIZE); + for (i = 0; i < NV50TCL_DMA_IN_MEMORY1__SIZE; i++) + so_data(so, nvws->channel->vram->handle); + + so_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws, 0, NULL); + + screen->pipe.winsys = ws; + + screen->pipe.destroy = nv50_screen_destroy; + + screen->pipe.get_name = nv50_screen_get_name; + screen->pipe.get_vendor = nv50_screen_get_vendor; + screen->pipe.get_param = nv50_screen_get_param; + screen->pipe.get_paramf = nv50_screen_get_paramf; + + screen->pipe.is_format_supported = nv50_screen_is_format_supported; + + screen->pipe.surface_map = nv50_surface_map; + screen->pipe.surface_unmap = nv50_surface_unmap; + + nv50_screen_init_miptree_functions(&screen->pipe); + + return &screen->pipe; +} + diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h new file mode 100644 index 00000000000..5a2732e37f4 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -0,0 +1,23 @@ +#ifndef __NV50_SCREEN_H__ +#define __NV50_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv50_screen { + struct pipe_screen pipe; + + struct nouveau_winsys *nvws; + + unsigned cur_pctx; + + struct nouveau_grobj *tesla; + struct nouveau_notifier *sync; +}; + +static INLINE struct nv50_screen * +nv50_screen(struct pipe_screen *screen) +{ + return (struct nv50_screen *)screen; +} + +#endif diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c new file mode 100644 index 00000000000..f42bae0c28d --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -0,0 +1,477 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" + +#include "nv50_context.h" +#include "nv50_state.h" + +#include "nouveau/nouveau_stateobj.h" + +static void * +nv50_blend_state_create(struct pipe_context *pipe, + const struct pipe_blend_state *cso) +{ + struct nouveau_stateobj *so = so_new(64, 0); + struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; + struct nv50_blend_stateobj *bso = CALLOC_STRUCT(nv50_blend_stateobj); + unsigned cmask = 0, i; + + /*XXX ignored: + * - dither + */ + + if (cso->blend_enable == 0) { + so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); + for (i = 0; i < 8; i++) + so_data(so, 0); + } else { + so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); + for (i = 0; i < 8; i++) + so_data(so, 1); + so_method(so, tesla, NV50TCL_BLEND_EQUATION_RGB, 5); + so_data (so, nvgl_blend_eqn(cso->rgb_func)); + so_data (so, nvgl_blend_func(cso->rgb_src_factor)); + so_data (so, nvgl_blend_func(cso->rgb_dst_factor)); + so_data (so, nvgl_blend_eqn(cso->alpha_func)); + so_data (so, nvgl_blend_func(cso->alpha_src_factor)); + so_method(so, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1); + so_data (so, nvgl_blend_func(cso->alpha_dst_factor)); + } + + if (cso->logicop_enable == 0 ) { + so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 1); + so_data (so, 0); + } else { + so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 2); + so_data (so, 1); + so_data (so, nvgl_logicop_func(cso->logicop_func)); + } + + if (cso->colormask & PIPE_MASK_R) + cmask |= (1 << 0); + if (cso->colormask & PIPE_MASK_G) + cmask |= (1 << 4); + if (cso->colormask & PIPE_MASK_B) + cmask |= (1 << 8); + if (cso->colormask & PIPE_MASK_A) + cmask |= (1 << 12); + so_method(so, tesla, NV50TCL_COLOR_MASK(0), 8); + for (i = 0; i < 8; i++) + so_data(so, cmask); + + bso->pipe = *cso; + so_ref(so, &bso->so); + return (void *)bso; +} + +static void +nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + 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); +} + +static void * +nv50_sampler_state_create(struct pipe_context *pipe, + const struct pipe_sampler_state *cso) +{ + return NULL; +} + +static void +nv50_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) +{ +} + +static void +nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso) +{ +} + +static void +nv50_set_sampler_texture(struct pipe_context *pipe, unsigned nr, + struct pipe_texture **pt) +{ +} + +static void * +nv50_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + struct nouveau_stateobj *so = so_new(64, 0); + struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; + struct nv50_rasterizer_stateobj *rso = + CALLOC_STRUCT(nv50_rasterizer_stateobj); + + /*XXX: ignored + * - light_twosize + * - point_smooth + * - multisample + * - point_sprite / sprite_coord_mode + */ + + 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_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 << 16) | + cso->line_stipple_factor); + } else { + so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1); + so_data (so, 0); + } + + so_method(so, tesla, NV50TCL_POINT_SIZE, 1); + so_data (so, fui(cso->point_size)); + + so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3); + if (cso->front_winding == PIPE_WINDING_CCW) { + so_data(so, nvgl_polygon_mode(cso->fill_ccw)); + so_data(so, nvgl_polygon_mode(cso->fill_cw)); + } else { + so_data(so, nvgl_polygon_mode(cso->fill_cw)); + so_data(so, nvgl_polygon_mode(cso->fill_ccw)); + } + so_data(so, cso->poly_smooth ? 1 : 0); + + so_method(so, tesla, NV50TCL_CULL_FACE_ENABLE, 3); + so_data (so, cso->cull_mode != PIPE_WINDING_NONE); + if (cso->front_winding == PIPE_WINDING_CCW) { + so_data(so, NV50TCL_FRONT_FACE_CCW); + switch (cso->cull_mode) { + case PIPE_WINDING_CCW: + so_data(so, NV50TCL_CULL_FACE_FRONT); + break; + case PIPE_WINDING_CW: + so_data(so, NV50TCL_CULL_FACE_BACK); + break; + case PIPE_WINDING_BOTH: + so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, NV50TCL_CULL_FACE_BACK); + break; + } + } else { + so_data(so, NV50TCL_FRONT_FACE_CW); + switch (cso->cull_mode) { + case PIPE_WINDING_CCW: + so_data(so, NV50TCL_CULL_FACE_BACK); + break; + case PIPE_WINDING_CW: + so_data(so, NV50TCL_CULL_FACE_FRONT); + break; + case PIPE_WINDING_BOTH: + so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, NV50TCL_CULL_FACE_BACK); + break; + } + } + + so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, cso->poly_stipple_enable ? 1 : 0); + + so_method(so, tesla, NV50TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) || + (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT)) + so_data(so, 1); + else + so_data(so, 0); + if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) || + (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE)) + so_data(so, 1); + else + so_data(so, 0); + if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) || + (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL)) + so_data(so, 1); + else + so_data(so, 0); + + if (cso->offset_cw || cso->offset_ccw) { + 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)); + } + + rso->pipe = *cso; + so_ref(so, &rso->so); + return (void *)rso; +} + +static void +nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->rasterizer = 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); +} + +static void * +nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) +{ + struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; + struct nv50_zsa_stateobj *zsa = CALLOC_STRUCT(nv50_zsa_stateobj); + struct nouveau_stateobj *so = so_new(64, 0); + + so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1); + so_data (so, cso->depth.writemask ? 1 : 0); + if (cso->depth.enabled) { + so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1); + so_data (so, 1); + so_method(so, tesla, NV50TCL_DEPTH_TEST_FUNC, 1); + so_data (so, nvgl_comparison_op(cso->depth.func)); + } else { + so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1); + so_data (so, 0); + } + + if (cso->stencil[0].enabled) { + so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 5); + so_data (so, 1); + so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op)); + so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); + so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); + so_data (so, nvgl_comparison_op(cso->stencil[0].func)); + so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 3); + so_data (so, cso->stencil[0].ref_value); + so_data (so, cso->stencil[0].write_mask); + so_data (so, cso->stencil[0].value_mask); + } else { + so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1); + so_data (so, 0); + } + + if (cso->stencil[1].enabled) { + so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 8); + 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_data (so, cso->stencil[1].ref_value); + so_data (so, cso->stencil[1].write_mask); + so_data (so, cso->stencil[1].value_mask); + } else { + so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1); + so_data (so, 0); + } + + if (cso->alpha.enabled) { + so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1); + so_data (so, 1); + so_method(so, tesla, NV50TCL_ALPHA_TEST_REF, 2); + so_data (so, fui(cso->alpha.ref)); + so_data (so, nvgl_comparison_op(cso->alpha.func)); + } else { + so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1); + so_data (so, 0); + } + + zsa->pipe = *cso; + so_ref(so, &zsa->so); + return (void *)zsa; +} + +static void +nv50_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->zsa = hwcso; + nv50->dirty |= NV50_NEW_ZSA; +} + +static void +nv50_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv50_zsa_stateobj *zsa = hwcso; + + so_ref(NULL, &zsa->so); + FREE(zsa); +} + +static void * +nv50_vp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + return NULL; +} + +static void +nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso) +{ +} + +static void +nv50_vp_state_delete(struct pipe_context *pipe, void *hwcso) +{ +} + +static void * +nv50_fp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + return NULL; +} + +static void +nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso) +{ +} + +static void +nv50_fp_state_delete(struct pipe_context *pipe, void *hwcso) +{ +} + +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_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *clip) +{ +} + +static void +nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + const struct pipe_constant_buffer *buf ) +{ +} + +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) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->stipple = *stipple; + nv50->dirty |= NV50_NEW_STIPPLE; +} + +static void +nv50_set_scissor_state(struct pipe_context *pipe, + const struct pipe_scissor_state *s) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->scissor = *s; + nv50->dirty |= NV50_NEW_SCISSOR; +} + +static void +nv50_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *vpt) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + 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) +{ +} + +static void +nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *ve) +{ +} + +void +nv50_init_state_functions(struct nv50_context *nv50) +{ + nv50->pipe.create_blend_state = nv50_blend_state_create; + nv50->pipe.bind_blend_state = nv50_blend_state_bind; + nv50->pipe.delete_blend_state = nv50_blend_state_delete; + + nv50->pipe.create_sampler_state = nv50_sampler_state_create; + nv50->pipe.bind_sampler_states = nv50_sampler_state_bind; + nv50->pipe.delete_sampler_state = nv50_sampler_state_delete; + nv50->pipe.set_sampler_textures = nv50_set_sampler_texture; + + nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create; + nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind; + nv50->pipe.delete_rasterizer_state = nv50_rasterizer_state_delete; + + nv50->pipe.create_depth_stencil_alpha_state = + nv50_depth_stencil_alpha_state_create; + nv50->pipe.bind_depth_stencil_alpha_state = + nv50_depth_stencil_alpha_state_bind; + nv50->pipe.delete_depth_stencil_alpha_state = + nv50_depth_stencil_alpha_state_delete; + + nv50->pipe.create_vs_state = nv50_vp_state_create; + nv50->pipe.bind_vs_state = nv50_vp_state_bind; + nv50->pipe.delete_vs_state = nv50_vp_state_delete; + + nv50->pipe.create_fs_state = nv50_fp_state_create; + nv50->pipe.bind_fs_state = nv50_fp_state_bind; + nv50->pipe.delete_fs_state = nv50_fp_state_delete; + + nv50->pipe.set_blend_color = nv50_set_blend_color; + nv50->pipe.set_clip_state = nv50_set_clip_state; + 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.set_vertex_buffers = nv50_set_vertex_buffers; + nv50->pipe.set_vertex_elements = nv50_set_vertex_elements; +} + diff --git a/src/gallium/drivers/nv50/nv50_state.h b/src/gallium/drivers/nv50/nv50_state.h new file mode 100644 index 00000000000..a3b781d4c61 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_state.h @@ -0,0 +1,7 @@ +#ifndef __NV50_STATE_H__ +#define __NV50_STATE_H__ + +#include "pipe/p_state.h" + + +#endif diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c new file mode 100644 index 00000000000..68d419f9fc8 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -0,0 +1,162 @@ +#include "nv50_context.h" +#include "nouveau/nouveau_stateobj.h" + +static void +nv50_state_validate_fb(struct nv50_context *nv50) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_stateobj *so = so_new(128, 18); + struct pipe_framebuffer_state *fb = &nv50->framebuffer; + unsigned i, w, h, gw = 0; + + for (i = 0; i < fb->num_cbufs; i++) { + 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); + } + + so_method(so, tesla, NV50TCL_RT_HORIZ(i), 2); + so_data (so, fb->cbufs[i]->width); + so_data (so, fb->cbufs[i]->height); + + so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5); + so_reloc (so, fb->cbufs[i]->buffer, fb->cbufs[i]->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, fb->cbufs[i]->buffer, fb->cbufs[i]->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0); + switch (fb->cbufs[i]->format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + so_data(so, 0xcf); + break; + case PIPE_FORMAT_R5G6B5_UNORM: + so_data(so, 0xe8); + break; + default: + { + char fmt[128]; + pf_sprint_name(fmt, fb->cbufs[i]->format); + NOUVEAU_ERR("AIIII unknown format %s\n", fmt); + } + so_data(so, 0xe6); + break; + } + so_data(so, 0x00000040); + so_data(so, 0x00000000); + } + + if (fb->zsbuf) { + if (!gw) { + w = fb->zsbuf->width; + h = fb->zsbuf->height; + gw = 1; + } else { + assert(w != fb->zsbuf->width); + assert(h != fb->zsbuf->height); + } + + so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5); + so_reloc (so, fb->zsbuf->buffer, fb->zsbuf->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, fb->zsbuf->buffer, fb->zsbuf->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0); + switch (fb->zsbuf->format) { + case PIPE_FORMAT_Z24S8_UNORM: + so_data(so, 0x16); + break; + default: + { + char fmt[128]; + pf_sprint_name(fmt, fb->zsbuf->format); + NOUVEAU_ERR("AIIII unknown format %s\n", fmt); + } + so_data(so, 0x16); + break; + } + so_data(so, 0x00000040); + so_data(so, 0x00000000); + } + + so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2); + so_data (so, w << 16); + so_data (so, h << 16); + so_method(so, tesla, 0xff0, 2); + so_data (so, w << 16); + so_data (so, h << 16); + + so_emit(nv50->screen->nvws, so); + so_ref(NULL, &so); +} + +boolean +nv50_state_validate(struct nv50_context *nv50) +{ + struct nouveau_winsys *nvws = nv50->screen->nvws; + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_stateobj *so; + unsigned i; + + if (nv50->dirty & NV50_NEW_FRAMEBUFFER) + nv50_state_validate_fb(nv50); + + if (nv50->dirty & NV50_NEW_BLEND) + so_emit(nvws, nv50->blend->so); + + if (nv50->dirty & NV50_NEW_ZSA) + so_emit(nvws, nv50->zsa->so); + + if (nv50->dirty & NV50_NEW_RASTERIZER) + so_emit(nvws, nv50->rasterizer->so); + + if (nv50->dirty & NV50_NEW_BLEND_COLOUR) { + so = so_new(5, 0); + so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 8); + so_data (so, fui(nv50->blend_colour.color[3])); + 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_emit(nvws, so); + so_ref(NULL, &so); + } + + if (nv50->dirty & NV50_NEW_STIPPLE) { + so = so_new(33, 0); + so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32); + for (i = 0; i < 32; i++) + so_data(so, nv50->stipple.stipple[i]); + so_emit(nvws, so); + so_ref(NULL, &so); + } + + if (nv50->dirty & NV50_NEW_SCISSOR) { + so = so_new(3, 0); + so_method(so, tesla, NV50TCL_SCISSOR_HORIZ, 2); + so_data (so, (nv50->scissor.maxx << 16) | + nv50->scissor.minx); + so_data (so, (nv50->scissor.maxy << 16) | + nv50->scissor.miny); + so_emit(nvws, so); + so_ref(NULL, &so); + } + + if (nv50->dirty & NV50_NEW_VIEWPORT) { + so = so_new(8, 0); + so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(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_UNK1(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])); + so_emit(nvws, so); + so_ref(NULL, &so); + } + + nv50->dirty = 0; + return TRUE; +} + diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c new file mode 100644 index 00000000000..4e294198b07 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -0,0 +1,65 @@ + +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#include "nv50_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_inlines.h" +#include "util/p_tile.h" + +static void +nv50_surface_copy(struct pipe_context *pipe, unsigned flip, + struct pipe_surface *dest, unsigned destx, unsigned desty, + struct pipe_surface *src, unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct nv50_context *nv50 = (struct nv50_context *)pipe; + struct nouveau_winsys *nvws = nv50->screen->nvws; + + nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, + width, height); +} + +static void +nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, + unsigned destx, unsigned desty, unsigned width, + unsigned height, unsigned value) +{ + struct nv50_context *nv50 = (struct nv50_context *)pipe; + struct nouveau_winsys *nvws = nv50->screen->nvws; + + nvws->surface_fill(nvws, dest, destx, desty, width, height, value); +} + +void +nv50_init_surface_functions(struct nv50_context *nv50) +{ + nv50->pipe.surface_copy = nv50_surface_copy; + nv50->pipe.surface_fill = nv50_surface_fill; +} diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c new file mode 100644 index 00000000000..b01ce1d42c5 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -0,0 +1,32 @@ +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "nv50_context.h" +#include "nv50_state.h" + +boolean +nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, + unsigned count) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + nv50_state_validate(nv50); + + NOUVEAU_ERR("unimplemented\n"); + return TRUE; +} + +boolean +nv50_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + nv50_state_validate(nv50); + + NOUVEAU_ERR("unimplemented\n"); + return TRUE; +} + diff --git a/src/gallium/state_trackers/g3dvl/Makefile b/src/gallium/state_trackers/g3dvl/Makefile new file mode 100644 index 00000000000..a0d85fbcc8f --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/Makefile @@ -0,0 +1,18 @@ +TARGET = libg3dvl.a +OBJECTS = vl_context.o vl_data.o vl_surface.o +GALLIUMDIR = ../.. + +CFLAGS += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary + +############################################# + +.PHONY = all clean + +all: ${TARGET} + +${TARGET}: ${OBJECTS} + ar rcs $@ $^ + +clean: + rm -rf ${OBJECTS} ${TARGET} + diff --git a/src/gallium/state_trackers/g3dvl/tests/.gitignore b/src/gallium/state_trackers/g3dvl/tests/.gitignore new file mode 100644 index 00000000000..939666da9ab --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/.gitignore @@ -0,0 +1,6 @@ +test_context +test_surface +test_i_rendering +test_p_rendering +test_b_rendering + diff --git a/src/gallium/state_trackers/g3dvl/tests/Makefile b/src/gallium/state_trackers/g3dvl/tests/Makefile new file mode 100644 index 00000000000..8f983593c3a --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/Makefile @@ -0,0 +1,42 @@ +GALLIUMDIR = ../../.. + +CFLAGS += -g -Wall -Werror \ + -I${GALLIUMDIR}/state_trackers/g3dvl \ + -I${GALLIUMDIR}/winsys/g3dvl \ + -I${GALLIUMDIR}/include \ + -I${GALLIUMDIR}/auxiliary \ + -I${GALLIUMDIR}/drivers +LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \ + -L${GALLIUMDIR}/drivers/softpipe \ + -L${GALLIUMDIR}/auxiliary/tgsi \ + -L${GALLIUMDIR}/auxiliary/draw \ + -L${GALLIUMDIR}/auxiliary/util \ + -L${GALLIUMDIR}/auxiliary/translate \ + -L${GALLIUMDIR}/auxiliary/cso_cache \ + -L${GALLIUMDIR}/auxiliary/rtasm +LIBS += -lg3dvl -lsoftpipe -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lutil -lX11 -lm + +############################################# + +.PHONY = all clean + +all: test_context test_surface test_i_rendering test_p_rendering test_b_rendering + +test_context: test_context.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o + $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} + +test_surface: test_surface.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o + $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} + +test_i_rendering: test_i_rendering.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o + $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} + +test_p_rendering: test_p_rendering.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o + $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} + +test_b_rendering: test_b_rendering.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o + $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} + +clean: + rm -rf *.o test_context test_surface test_i_rendering test_p_rendering test_b_rendering + diff --git a/src/gallium/state_trackers/g3dvl/tests/test_b_rendering.c b/src/gallium/state_trackers/g3dvl/tests/test_b_rendering.c new file mode 100644 index 00000000000..b78cc851ae4 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_b_rendering.c @@ -0,0 +1,226 @@ +#include <stdio.h> +#include <X11/Xlib.h> +#include <vl_context.h> +#include <vl_surface.h> +#include <xsp_winsys.h> + +static const unsigned short ycbcr16x16_420[8*8*6] = +{ + 0x00A5,0x00A5,0x00A5,0x0072,0x00A5,0x0072,0x0072,0x0072, + 0x0072,0x00A5,0x0072,0x0072,0x00A5,0x0072,0x0072,0x0072, + 0x0072,0x00A5,0x0072,0x0072,0x00A5,0x00A5,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5, + 0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5,0x00A5, + + 0x004F,0x004F,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F,0x004F, + + 0x003E,0x003E,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E,0x003E +}; + +static const signed short ycbcr16x16_420_2[8*8*6] = +{ + -0x00A5,-0x00A5,-0x00A5,-0x0072,-0x00A5,-0x0072,-0x0072,-0x0072, + -0x0072,-0x00A5,-0x0072,-0x0072,-0x00A5,-0x0072,-0x0072,-0x0072, + -0x0072,-0x00A5,-0x0072,-0x0072,-0x00A5,-0x00A5,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x00A5, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x00A5,-0x00A5, + -0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x00A5,-0x00A5,-0x00A5, + -0x0072,-0x0072,-0x0072,-0x0072,-0x00A5,-0x00A5,-0x00A5,-0x00A5, + + -0x004F,-0x004F,-0x004F,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2, + -0x00B2,-0x00B2,-0x004F,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2, + -0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2, + -0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2, + -0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2, + -0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2, + -0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x004F, + -0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x004F,-0x004F, + + -0x003E,-0x003E,-0x003E,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060, + -0x0060,-0x0060,-0x003E,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060, + -0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060, + -0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060, + -0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060, + -0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060, + -0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x003E, + -0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x003E,-0x003E +}; + +int main(int argc, char **argv) +{ + const unsigned int video_width = 32, video_height = 32; + const unsigned int window_width = video_width * 2, window_height = video_height * 2; + int quit = 0; + Display *display; + Window root, window; + Pixmap framebuffer; + XEvent event; + struct pipe_context *pipe; + struct VL_CONTEXT *ctx; + struct VL_SURFACE *sfc, *past_sfc, *future_sfc; + struct VL_MOTION_VECTOR motion_vector[2] = + { + { + {0, 0}, {0, 0} + }, + { + {0, 0}, {0, 0} + } + }; + + display = XOpenDisplay(NULL); + root = XDefaultRootWindow(display); + window = XCreateSimpleWindow(display, root, 0, 0, window_width, window_height, 0, 0, 0); + framebuffer = XCreatePixmap(display, root, window_width, window_height, 24); + + XSelectInput(display, window, ExposureMask | KeyPressMask); + XMapWindow(display, window); + XSync(display, 0); + + pipe = create_pipe_context(display); + vlCreateContext(display, pipe, video_width, video_height, VL_FORMAT_YCBCR_420, &ctx); + vlCreateSurface(ctx, &sfc); + vlCreateSurface(ctx, &past_sfc); + vlCreateSurface(ctx, &future_sfc); + + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, past_sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, past_sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, past_sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, past_sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, future_sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, future_sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, future_sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, future_sfc); + vlRenderBMacroBlock + ( + VL_FRAME_PICTURE, + VL_FIELD_FIRST, + 0, + 0, + VL_FRAME_MC, + motion_vector, + 0x3F, + VL_DCT_FRAME_CODED, + (short*)ycbcr16x16_420_2, + past_sfc, + future_sfc, + sfc + ); + vlPutSurface(sfc, framebuffer, 0, 0, video_width, video_height, 0, 0, window_width, window_height, VL_FRAME_PICTURE); + + puts("Press any key to continue..."); + + while (!quit) + { + XNextEvent(display, &event); + switch (event.type) + { + case Expose: + { + XCopyArea + ( + display, + framebuffer, + window, + XDefaultGC(display, XDefaultScreen(display)), + 0, + 0, + window_width, + window_height, + 0, + 0 + ); + break; + } + case KeyPress: + { + quit = 1; + break; + } + } + } + + vlDestroySurface(sfc); + vlDestroySurface(past_sfc); + vlDestroySurface(future_sfc); + vlDestroyContext(ctx); + + XFreePixmap(display, framebuffer); + XDestroyWindow(display, window); + XCloseDisplay(display); + + return 0; +} + diff --git a/src/gallium/state_trackers/g3dvl/tests/test_context.c b/src/gallium/state_trackers/g3dvl/tests/test_context.c new file mode 100644 index 00000000000..2002977ee24 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_context.c @@ -0,0 +1,22 @@ +#include <vl_context.h> +#include <xsp_winsys.h> + +int main(int argc, char **argv) +{ + const unsigned int video_width = 32, video_height = 32; + + Display *display; + struct pipe_context *pipe; + struct VL_CONTEXT *ctx; + + display = XOpenDisplay(NULL); + pipe = create_pipe_context(display); + + vlCreateContext(display, pipe, video_width, video_height, VL_FORMAT_YCBCR_420, &ctx); + vlDestroyContext(ctx); + + XCloseDisplay(display); + + return 0; +} + diff --git a/src/gallium/state_trackers/g3dvl/tests/test_i_rendering.c b/src/gallium/state_trackers/g3dvl/tests/test_i_rendering.c new file mode 100644 index 00000000000..1f964711308 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_i_rendering.c @@ -0,0 +1,137 @@ +#include <stdio.h> +#include <X11/Xlib.h> +#include <vl_context.h> +#include <vl_surface.h> +#include <xsp_winsys.h> + +static const unsigned short ycbcr16x16_420[8*8*6] = +{ + 0x00A5,0x00A5,0x00A5,0x0072,0x00A5,0x0072,0x0072,0x0072, + 0x0072,0x00A5,0x0072,0x0072,0x00A5,0x0072,0x0072,0x0072, + 0x0072,0x00A5,0x0072,0x0072,0x00A5,0x00A5,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5, + 0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5,0x00A5, + + 0x004F,0x004F,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F,0x004F, + + 0x003E,0x003E,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E,0x003E +}; + +int main(int argc, char **argv) +{ + const unsigned int video_width = 32, video_height = 32; + const unsigned int window_width = video_width * 2, window_height = video_height * 2; + int quit = 0; + Display *display; + Window root, window; + Pixmap framebuffer; + XEvent event; + struct pipe_context *pipe; + struct VL_CONTEXT *ctx; + struct VL_SURFACE *sfc; + + display = XOpenDisplay(NULL); + root = XDefaultRootWindow(display); + window = XCreateSimpleWindow(display, root, 0, 0, window_width, window_height, 0, 0, 0); + framebuffer = XCreatePixmap(display, root, window_width, window_height, 24); + + XSelectInput(display, window, ExposureMask | KeyPressMask); + XMapWindow(display, window); + XSync(display, 0); + + pipe = create_pipe_context(display); + vlCreateContext(display, pipe, video_width, video_height, VL_FORMAT_YCBCR_420, &ctx); + vlCreateSurface(ctx, &sfc); + + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, sfc); + vlPutSurface(sfc, framebuffer, 0, 0, video_width, video_height, 0, 0, window_width, window_height, VL_FRAME_PICTURE); + + puts("Press any key to continue..."); + + while (!quit) + { + XNextEvent(display, &event); + switch (event.type) + { + case Expose: + { + XCopyArea + ( + display, + framebuffer, + window, + XDefaultGC(display, XDefaultScreen(display)), + 0, + 0, + window_width, + window_height, + 0, + 0 + ); + break; + } + case KeyPress: + { + quit = 1; + break; + } + } + } + + vlDestroySurface(sfc); + vlDestroyContext(ctx); + + XFreePixmap(display, framebuffer); + XDestroyWindow(display, window); + XCloseDisplay(display); + + return 0; +} + diff --git a/src/gallium/state_trackers/g3dvl/tests/test_p_rendering.c b/src/gallium/state_trackers/g3dvl/tests/test_p_rendering.c new file mode 100644 index 00000000000..2203349784f --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_p_rendering.c @@ -0,0 +1,214 @@ +#include <stdio.h> +#include <X11/Xlib.h> +#include <vl_context.h> +#include <vl_surface.h> +#include <xsp_winsys.h> + +static const unsigned short ycbcr16x16_420[8*8*6] = +{ + 0x00A5,0x00A5,0x00A5,0x0072,0x00A5,0x0072,0x0072,0x0072, + 0x0072,0x00A5,0x0072,0x0072,0x00A5,0x0072,0x0072,0x0072, + 0x0072,0x00A5,0x0072,0x0072,0x00A5,0x00A5,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5, + 0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5, + 0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5,0x00A5, + + 0x004F,0x004F,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F, + 0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F,0x004F, + + 0x003E,0x003E,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E, + 0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E,0x003E +}; + +static const signed short ycbcr16x16_420_2[8*8*6] = +{ + -51,-51,-51, 0,-51, 0, 0, 0, + 0,-51, 0, 0,-51, 0, 0, 0, + 0,-51, 0, 0,-51,-51, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 99, 99, 99, 0, 0, 0, 0, 0, + 0, 0, 99, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 33, 33, 33, 0, 0, 0, 0, 0, + 0, 0, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +int main(int argc, char **argv) +{ + const unsigned int video_width = 32, video_height = 32; + const unsigned int window_width = video_width * 2, window_height = video_height * 2; + int quit = 0; + Display *display; + Window root, window; + Pixmap framebuffer; + XEvent event; + struct pipe_context *pipe; + struct VL_CONTEXT *ctx; + struct VL_SURFACE *sfc, *ref_sfc; + struct VL_MOTION_VECTOR motion_vector = + { + {0, 0}, {0, 0} + }; + + display = XOpenDisplay(NULL); + root = XDefaultRootWindow(display); + window = XCreateSimpleWindow(display, root, 0, 0, window_width, window_height, 0, 0, 0); + framebuffer = XCreatePixmap(display, root, window_width, window_height, 24); + + XSelectInput(display, window, ExposureMask | KeyPressMask); + XMapWindow(display, window); + XSync(display, 0); + + pipe = create_pipe_context(display); + vlCreateContext(display, pipe, video_width, video_height, VL_FORMAT_YCBCR_420, &ctx); + vlCreateSurface(ctx, &sfc); + vlCreateSurface(ctx, &ref_sfc); + + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, ref_sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, ref_sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, ref_sfc); + vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, ref_sfc); + vlRenderPMacroBlock + ( + VL_FRAME_PICTURE, + VL_FIELD_FIRST, + 0, + 0, + VL_FRAME_MC, + &motion_vector, + 0x3F, + VL_DCT_FRAME_CODED, + (short*)ycbcr16x16_420_2, + ref_sfc, + sfc + ); + vlPutSurface(sfc, framebuffer, 0, 0, video_width, video_height, 0, 0, window_width, window_height, VL_FRAME_PICTURE); + + puts("Press any key to continue..."); + + while (!quit) + { + XNextEvent(display, &event); + switch (event.type) + { + case Expose: + { + XCopyArea + ( + display, + framebuffer, + window, + XDefaultGC(display, XDefaultScreen(display)), + 0, + 0, + window_width, + window_height, + 0, + 0 + ); + break; + } + case KeyPress: + { + quit = 1; + break; + } + } + } + + vlDestroySurface(sfc); + vlDestroySurface(ref_sfc); + vlDestroyContext(ctx); + + XFreePixmap(display, framebuffer); + XDestroyWindow(display, window); + XCloseDisplay(display); + + return 0; +} + diff --git a/src/gallium/state_trackers/g3dvl/tests/test_surface.c b/src/gallium/state_trackers/g3dvl/tests/test_surface.c new file mode 100644 index 00000000000..4d1946396af --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_surface.c @@ -0,0 +1,26 @@ +#include <vl_context.h> +#include <vl_surface.h> +#include <xsp_winsys.h> + +int main(int argc, char **argv) +{ + const unsigned int video_width = 32, video_height = 32; + + Display *display; + struct pipe_context *pipe; + struct VL_CONTEXT *ctx; + struct VL_SURFACE *sfc; + + display = XOpenDisplay(NULL); + pipe = create_pipe_context(display); + + vlCreateContext(display, pipe, video_width, video_height, VL_FORMAT_YCBCR_420, &ctx); + vlCreateSurface(ctx, &sfc); + vlDestroySurface(sfc); + vlDestroyContext(ctx); + + XCloseDisplay(display); + + return 0; +} + diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c new file mode 100644 index 00000000000..2d1d5434955 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -0,0 +1,2246 @@ +#include "vl_context.h" +#include <assert.h> +#include <stdlib.h> +#include <pipe/p_context.h> +#include <pipe/p_winsys.h> +#include <pipe/p_screen.h> +#include <pipe/p_state.h> +#include <pipe/p_inlines.h> +#include <pipe/p_shader_tokens.h> +#include <tgsi/util/tgsi_parse.h> +#include <tgsi/util/tgsi_build.h> +#include "vl_data.h" + +static int vlInitIDCT(struct VL_CONTEXT *context) +{ + assert(context); + + + + return 0; +} + +static int vlDestroyIDCT(struct VL_CONTEXT *context) +{ + assert(context); + + + + return 0; +} + +static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 50; + const unsigned int num_attribs = 3; + const unsigned int semantic_names[3] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, + }; + const unsigned int semantic_indexes[3] = {0, 1, 2}; + const unsigned int proc_type = TGSI_PROCESSOR_VERTEX; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token)); + + /* Version */ + *(struct tgsi_version*)&tokens[0] = tgsi_build_version(); + + /* Header */ + header = (struct tgsi_header*)&tokens[1]; + *header = tgsi_build_header(); + + /* Processor */ + processor = (struct tgsi_processor*)&tokens[2]; + *processor = tgsi_build_processor(proc_type, header); + + ti = 3; + + /* Declare inputs (pos, texcoords) */ + for (i = 0; i < num_attribs; i++) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = semantic_names[i]; + decl.Semantic.SemanticIndex = semantic_indexes[i]; + + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* Declare constant inputs */ + /* C[0] scales the normalized MB to cover 16x16 pixels, + C[1] translates the macroblock into position on the surface */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_CONSTANT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 1; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare outputs (pos, texcoords) */ + for (i = 0; i < num_attribs; i++) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = semantic_names[i]; + decl.Semantic.SemanticIndex = semantic_indexes[i]; + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* mul t0, i0, c0 ; Scale normalized coords to window coords */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MUL; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* add o0, t0, c1 ; Translate vertex into position */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* + mov o1, i1 ; Move texcoords to output + mov o2, i2 + */ + for (i = 1; i < num_attribs; ++i) + { + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MOV; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = i; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* END */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + vs.tokens = tokens; + + context->states.mc.i_vs = pipe->create_vs_state(pipe, &vs); + + return 0; +} + +static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 50; + const unsigned int proc_type = TGSI_PROCESSOR_FRAGMENT; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token)); + + /* Version */ + *(struct tgsi_version*)&tokens[0] = tgsi_build_version(); + + /* Header */ + header = (struct tgsi_header*)&tokens[1]; + *header = tgsi_build_header(); + + /* Processor */ + processor = (struct tgsi_processor*)&tokens[2]; + *processor = tgsi_build_processor(proc_type, header); + + ti = 3; + + /* Declare inputs (texcoords) */ + for (i = 0; i < 2; ++i) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = i + 1; + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* Declare output (color) */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare samplers */ + for (i = 0; i < 3; ++i) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* + tex2d o0.x, i0, s0 ; Read texel from luma texture into .x channel + tex2d o0.y, i1, s1 ; Read texel from chroma Cb texture into .y channel + tex2d o0.z, i1, s2 ; Read texel from chroma Cr texture into .z channel + */ + for (i = 0; i < 3; ++i) + { + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_TEX; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i > 0 ? 1 : 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + inst.FullSrcRegisters[1].SrcRegister.Index = i; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* END */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + fs.tokens = tokens; + + context->states.mc.i_fs = pipe->create_fs_state(pipe, &fs); + + return 0; +} + +static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 100; + const unsigned int num_input_attribs = 3; + const unsigned int num_output_attribs = 4; + const unsigned int input_semantic_names[3] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC + }; + const unsigned int output_semantic_names[4] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC + }; + const unsigned int input_semantic_indexes[3] = {0, 1, 2}; + const unsigned int output_semantic_indexes[4] = {0, 1, 2, 3}; + const unsigned int proc_type = TGSI_PROCESSOR_VERTEX; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token)); + + /* Version */ + *(struct tgsi_version*)&tokens[0] = tgsi_build_version(); + + /* Header */ + header = (struct tgsi_header*)&tokens[1]; + *header = tgsi_build_header(); + + /* Processor */ + processor = (struct tgsi_processor*)&tokens[2]; + *processor = tgsi_build_processor(proc_type, header); + + ti = 3; + + /* Declare inputs (pos, texcoords) */ + for (i = 0; i < num_input_attribs; i++) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = input_semantic_names[i]; + decl.Semantic.SemanticIndex = input_semantic_indexes[i]; + + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* Declare constant inputs */ + /* C[0] scales the normalized MB to cover 16x16 pixels, + C[1] translates the macroblock into position on the surface + C[2] translates the ref surface texcoords to the ref macroblock */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_CONSTANT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 2; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare outputs (pos, texcoords) */ + for (i = 0; i < num_output_attribs; i++) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = output_semantic_names[i]; + decl.Semantic.SemanticIndex = output_semantic_indexes[i]; + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* mul t0, i0, c0 ; Scale normalized coords to window coords */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MUL; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* add o0, t0, c1 ; Translate vertex into position */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* + mov o1, i1 ; Move luma & chroma texcoords to output + mov o2, i2 + */ + for (i = 1; i < num_output_attribs - 1; ++i) + { + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MOV; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = i; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* add o3, t0, c2 ; Translate texcoords into position */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 3; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 2; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* END */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + vs.tokens = tokens; + + context->states.mc.p_vs = pipe->create_vs_state(pipe, &vs); + + return 0; +} + +static int vlCreateFragmentShaderPMC(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 100; + const unsigned int proc_type = TGSI_PROCESSOR_FRAGMENT; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token)); + + /* Version */ + *(struct tgsi_version*)&tokens[0] = tgsi_build_version(); + + /* Header */ + header = (struct tgsi_header*)&tokens[1]; + *header = tgsi_build_header(); + + /* Processor */ + processor = (struct tgsi_processor*)&tokens[2]; + *processor = tgsi_build_processor(proc_type, header); + + ti = 3; + + /* Declare inputs (texcoords) */ + for (i = 0; i < 3; ++i) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = i + 1; + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* Declare constant input */ + /* C[0] is a multiplier to use when concatenating differential into a single channel + C[0] is a bias to get differential back to -1,1 range*/ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_CONSTANT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 1; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare output */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare samplers */ + for (i = 0; i < 4; ++i) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* + tex2d t0.xw, i0, s0 ; Read texel from luma texture into .x and .w channels + mov t1.x, t0.w ; Move high part from .w channel to .x + tex2d t0.yw, i1, s1 ; Read texel from chroma Cb texture into .y and .w channels + mov t1.y, t0.w ; Move high part from .w channel to .y + tex2d t0.zw, i1, s2 ; Read texel from chroma Cr texture into .z and .w channels + mov t1.z, t0.w ; Move high part from .w channel to .z + */ + for (i = 0; i < 3; ++i) + { + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_TEX; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.FullDstRegisters[0].DstRegister.WriteMask = (TGSI_WRITEMASK_X << i) | TGSI_WRITEMASK_W; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i > 0 ? 1 : 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + inst.FullSrcRegisters[1].SrcRegister.Index = i; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MOV; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 1; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* mul t1, t1, c0 ; Muliply high part by multiplier to get back its full value */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MUL; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 1; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 1; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* add t0, t0, t1 ; Add luma and chroma low and high parts to get a single value */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* sub t0, t0, c1 ; Subtract bias to get back the signed value */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_SUB; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* tex2d t1, i2, s3 ; Read texel from ref macroblock */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_TEX; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 1; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 2; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + inst.FullSrcRegisters[1].SrcRegister.Index = 3; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* add o0, t0, t1 ; Add ref and differential to form final output */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* END */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + fs.tokens = tokens; + + context->states.mc.p_fs = pipe->create_fs_state(pipe, &fs); + + return 0; +} + +static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 100; + const unsigned int num_input_attribs = 3; + const unsigned int num_output_attribs = 5; + const unsigned int input_semantic_names[3] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC + }; + const unsigned int output_semantic_names[5] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC + }; + const unsigned int input_semantic_indexes[3] = {0, 1, 2}; + const unsigned int output_semantic_indexes[5] = {0, 1, 2, 3, 4}; + const unsigned int proc_type = TGSI_PROCESSOR_VERTEX; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token)); + + /* Version */ + *(struct tgsi_version*)&tokens[0] = tgsi_build_version(); + + /* Header */ + header = (struct tgsi_header*)&tokens[1]; + *header = tgsi_build_header(); + + /* Processor */ + processor = (struct tgsi_processor*)&tokens[2]; + *processor = tgsi_build_processor(proc_type, header); + + ti = 3; + + /* Declare inputs (pos, texcoords) */ + for (i = 0; i < num_input_attribs; i++) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = input_semantic_names[i]; + decl.Semantic.SemanticIndex = input_semantic_indexes[i]; + + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* Declare constant inputs */ + /* C[0] scales the normalized MB to cover 16x16 pixels, + C[1] translates the macroblock into position on the surface + C[2] translates the past surface texcoords to the ref macroblock + C[3] translates the future surface texcoords to the ref macroblock */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_CONSTANT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 3; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare outputs (pos, texcoords) */ + for (i = 0; i < num_output_attribs; i++) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = output_semantic_names[i]; + decl.Semantic.SemanticIndex = output_semantic_indexes[i]; + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* mul t0, i0, c0 ; Scale normalized coords to window coords */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MUL; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* add o0, t0, c1 ; Translate vertex into position */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* + mov o1, i1 ; Move luma & chroma texcoords to output + mov o2, i2 + */ + for (i = 1; i < num_output_attribs - 2; ++i) + { + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MOV; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = i; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* add o3, t0, c2 ; Translate past surface texcoords into position + add o4, t0, c3 ; Repeat for future surface texcoords */ + for (i = 0; i < 2; ++i) + { + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = i + 3; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = i + 2; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* END */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + vs.tokens = tokens; + + context->states.mc.b_vs = pipe->create_vs_state(pipe, &vs); + + return 0; +} + +static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 100; + const unsigned int proc_type = TGSI_PROCESSOR_FRAGMENT; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token)); + + /* Version */ + *(struct tgsi_version*)&tokens[0] = tgsi_build_version(); + + /* Header */ + header = (struct tgsi_header*)&tokens[1]; + *header = tgsi_build_header(); + + /* Processor */ + processor = (struct tgsi_processor*)&tokens[2]; + *processor = tgsi_build_processor(proc_type, header); + + ti = 3; + + /* Declare inputs (texcoords) */ + for (i = 0; i < 4; ++i) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = i + 1; + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* Declare constant input */ + /* C[0] is a multiplier to use when concatenating differential into a single channel + C[0] is a bias to get differential back to -1,1 range*/ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_CONSTANT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 1; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare output */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare samplers */ + for (i = 0; i < 5; ++i) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* + tex2d t0.xw, i0, s0 ; Read texel from luma texture into .x and .w channels + mov t1.x, t0.w ; Move high part from .w channel to .x + tex2d t0.yw, i1, s1 ; Read texel from chroma Cb texture into .y and .w channels + mov t1.y, t0.w ; Move high part from .w channel to .y + tex2d t0.zw, i1, s2 ; Read texel from chroma Cr texture into .z and .w channels + mov t1.z, t0.w ; Move high part from .w channel to .z + */ + for (i = 0; i < 3; ++i) + { + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_TEX; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.FullDstRegisters[0].DstRegister.WriteMask = (TGSI_WRITEMASK_X << i) | TGSI_WRITEMASK_W; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i > 0 ? 1 : 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + inst.FullSrcRegisters[1].SrcRegister.Index = i; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MOV; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 1; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* mul t1, t1, c0 ; Muliply high part by multiplier to get back its full value */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MUL; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 1; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 1; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* add t0, t0, t1 ; Add luma and chroma low and high parts to get a single value */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* sub t0, t0, c1 ; Subtract bias to get back the signed value */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_SUB; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* tex2d t1, i2, s3 ; Read texel from past macroblock + tex2d t2, i3, s4 ; Read texel from future macroblock */ + for (i = 0; i < 2; ++i) + { + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_TEX; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = i + 1; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i + 2; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + inst.FullSrcRegisters[1].SrcRegister.Index = i + 3; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* add t0, t0, t1 ; Add past and differential to form partial output */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* add o0, t0, t2 ; Add future and differential to form final output */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 2; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* END */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + fs.tokens = tokens; + + context->states.mc.b_fs = pipe->create_fs_state(pipe, &fs); + + return 0; +} + +int vlCreateDataBufsMC(struct VL_CONTEXT *context) +{ + struct pipe_context *pipe; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + /* Create our vertex buffer and vertex buffer element */ + context->states.mc.vertex_bufs[0].pitch = sizeof(struct VL_VERTEX2F); + context->states.mc.vertex_bufs[0].max_index = 23; + context->states.mc.vertex_bufs[0].buffer_offset = 0; + context->states.mc.vertex_bufs[0].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct VL_VERTEX2F) * 24 + ); + + context->states.mc.vertex_buf_elems[0].src_offset = 0; + context->states.mc.vertex_buf_elems[0].vertex_buffer_index = 0; + context->states.mc.vertex_buf_elems[0].nr_components = 2; + context->states.mc.vertex_buf_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Create our texcoord buffers and texcoord buffer elements */ + /* TODO: Should be able to use 1 texcoord buf for chroma textures, 1 buf for ref surfaces */ + for (i = 1; i < 3; ++i) + { + context->states.mc.vertex_bufs[i].pitch = sizeof(struct VL_TEXCOORD2F); + context->states.mc.vertex_bufs[i].max_index = 23; + context->states.mc.vertex_bufs[i].buffer_offset = 0; + context->states.mc.vertex_bufs[i].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct VL_TEXCOORD2F) * 24 + ); + + context->states.mc.vertex_buf_elems[i].src_offset = 0; + context->states.mc.vertex_buf_elems[i].vertex_buffer_index = i; + context->states.mc.vertex_buf_elems[i].nr_components = 2; + context->states.mc.vertex_buf_elems[i].src_format = PIPE_FORMAT_R32G32_FLOAT; + } + + /* Fill buffers */ + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, context->states.mc.vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + vl_chroma_420_texcoords, + sizeof(struct VL_VERTEX2F) * 24 + ); + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, context->states.mc.vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + vl_luma_texcoords, + sizeof(struct VL_TEXCOORD2F) * 24 + ); + /* TODO: Accomodate 422, 444 */ + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, context->states.mc.vertex_bufs[2].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + vl_chroma_420_texcoords, + sizeof(struct VL_TEXCOORD2F) * 24 + ); + + for (i = 0; i < 3; ++i) + pipe->winsys->buffer_unmap(pipe->winsys, context->states.mc.vertex_bufs[i].buffer); + + /* Create our constant buffer */ + context->states.mc.vs_const_buf.size = sizeof(struct VL_MC_VS_CONSTS); + context->states.mc.vs_const_buf.buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + context->states.mc.vs_const_buf.size + ); + + context->states.mc.fs_const_buf.size = sizeof(struct VL_MC_FS_CONSTS); + context->states.mc.fs_const_buf.buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + context->states.mc.fs_const_buf.size + ); + + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, context->states.mc.fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + &vl_mc_fs_consts, + sizeof(struct VL_MC_FS_CONSTS) + ); + + pipe->winsys->buffer_unmap(pipe->winsys, context->states.mc.fs_const_buf.buffer); + + return 0; +} + +static int vlInitMC(struct VL_CONTEXT *context) +{ + struct pipe_context *pipe; + struct pipe_sampler_state sampler; + struct pipe_texture template; + unsigned int filters[5]; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + context->states.mc.viewport.scale[0] = context->video_width; + context->states.mc.viewport.scale[1] = context->video_height; + context->states.mc.viewport.scale[2] = 1; + context->states.mc.viewport.scale[3] = 1; + context->states.mc.viewport.translate[0] = 0; + context->states.mc.viewport.translate[1] = 0; + context->states.mc.viewport.translate[2] = 0; + context->states.mc.viewport.translate[3] = 0; + + context->states.mc.render_target.width = context->video_width; + context->states.mc.render_target.height = context->video_height; + context->states.mc.render_target.num_cbufs = 1; + /* FB for MC stage is a VL_SURFACE, set in vlSetRenderSurface() */ + /*context->states.mc.render_target.cbufs[0] = ;*/ + context->states.mc.render_target.zsbuf = NULL; + + filters[0] = PIPE_TEX_FILTER_NEAREST; + filters[1] = context->video_format == VL_FORMAT_YCBCR_444 ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; + filters[2] = context->video_format == VL_FORMAT_YCBCR_444 ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; + filters[3] = PIPE_TEX_FILTER_NEAREST; + filters[4] = PIPE_TEX_FILTER_NEAREST; + + for (i = 0; i < 5; ++i) + { + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_img_filter = filters[i]; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.mag_img_filter = filters[i]; + sampler.compare_mode = PIPE_TEX_COMPARE_NONE; + sampler.compare_func = PIPE_FUNC_ALWAYS; + sampler.normalized_coords = 1; + /*sampler.prefilter = ;*/ + /*sampler.shadow_ambient = ;*/ + /*sampler.lod_bias = ;*/ + /*sampler.min_lod = ;*/ + /*sampler.max_lod = ;*/ + /*sampler.border_color[i] = ;*/ + /*sampler.max_anisotropy = ;*/ + context->states.mc.samplers[i] = pipe->create_sampler_state(pipe, &sampler); + } + + memset(&template, 0, sizeof(struct pipe_texture)); + template.target = PIPE_TEXTURE_2D; + template.format = PIPE_FORMAT_A8L8_UNORM; + template.last_level = 0; + template.width[0] = 8; + template.height[0] = 8 * 4; + template.depth[0] = 1; + template.compressed = 0; + template.cpp = 2; + context->states.mc.textures[0] = pipe->screen->texture_create(pipe->screen, &template); + + if (context->video_format == VL_FORMAT_YCBCR_420) + template.height[0] = 8; + else if (context->video_format == VL_FORMAT_YCBCR_422) + template.height[0] = 8 * 2; + else if (context->video_format == VL_FORMAT_YCBCR_444) + template.height[0] = 8 * 4; + else + assert(0); + + context->states.mc.textures[1] = pipe->screen->texture_create(pipe->screen, &template); + context->states.mc.textures[2] = pipe->screen->texture_create(pipe->screen, &template); + + /* textures[3] & textures[4] are assigned from VL_SURFACEs for P and B macroblocks at render time */ + + vlCreateVertexShaderIMC(context); + vlCreateFragmentShaderIMC(context); + vlCreateVertexShaderPMC(context); + vlCreateFragmentShaderPMC(context); + vlCreateVertexShaderBMC(context); + vlCreateFragmentShaderBMC(context); + vlCreateDataBufsMC(context); + + return 0; +} + +static int vlDestroyMC(struct VL_CONTEXT *context) +{ + unsigned int i; + + assert(context); + + for (i = 0; i < 5; ++i) + context->pipe->delete_sampler_state(context->pipe, context->states.mc.samplers[i]); + + for (i = 0; i < 3; ++i) + context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.mc.vertex_bufs[i].buffer); + + /* Textures 3 & 4 are not created directly, no need to release them here */ + for (i = 0; i < 3; ++i) + pipe_texture_release(&context->states.mc.textures[i]); + + context->pipe->delete_vs_state(context->pipe, context->states.mc.i_vs); + context->pipe->delete_fs_state(context->pipe, context->states.mc.i_fs); + context->pipe->delete_vs_state(context->pipe, context->states.mc.p_vs); + context->pipe->delete_fs_state(context->pipe, context->states.mc.p_fs); + context->pipe->delete_vs_state(context->pipe, context->states.mc.b_vs); + context->pipe->delete_fs_state(context->pipe, context->states.mc.b_fs); + + context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.mc.vs_const_buf.buffer); + context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.mc.fs_const_buf.buffer); + + return 0; +} + +static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 50; + const unsigned int num_attribs = 2; + const unsigned int semantic_names[2] = {TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC}; + const unsigned int semantic_indexes[2] = {0, 1}; + const unsigned int proc_type = TGSI_PROCESSOR_VERTEX; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token)); + + /* Version */ + *(struct tgsi_version*)&tokens[0] = tgsi_build_version(); + + /* Header */ + header = (struct tgsi_header*)&tokens[1]; + *header = tgsi_build_header(); + + /* Processor */ + processor = (struct tgsi_processor*)&tokens[2]; + *processor = tgsi_build_processor(proc_type, header); + + ti = 3; + + /* Declare inputs (pos, texcoords) */ + for (i = 0; i < num_attribs; i++) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = semantic_names[i]; + decl.Semantic.SemanticIndex = semantic_indexes[i]; + + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* Declare outputs (pos, texcoords) */ + for (i = 0; i < num_attribs; i++) + { + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = semantic_names[i]; + decl.Semantic.SemanticIndex = semantic_indexes[i]; + decl.u.DeclarationRange.First = i; + decl.u.DeclarationRange.Last = i; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* MOV instructions */ + /* mov o0, i0 + mov o1, i1 */ + for (i = 0; i < num_attribs; i++) + { + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MOV; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = i; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* END instruction */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + vs.tokens = tokens; + + context->states.csc.vertex_shader = pipe->create_vs_state(pipe, &vs); + + return 0; +} + +static int vlCreateFragmentShaderCSC(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 50; + const unsigned int proc_type = TGSI_PROCESSOR_FRAGMENT; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token)); + + /* Version */ + *(struct tgsi_version*)&tokens[0] = tgsi_build_version(); + + /* Header */ + header = (struct tgsi_header*)&tokens[1]; + *header = tgsi_build_header(); + + /* Processor */ + processor = (struct tgsi_processor*)&tokens[2]; + *processor = tgsi_build_processor(proc_type, header); + + ti = 3; + + /* Declare TEX[0] input */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 1; + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare constant input */ + /* Constants include bias vector, 4x4 csc matrix, total 5 vectors */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_CONSTANT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 4; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare output */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* Declare sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = 0; + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + + /* TEX instruction */ + /* tex2d t0, i0, s0 */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_TEX; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + inst.FullSrcRegisters[1].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* SUB instruction */ + /* sub t0, t0, c0 */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_SUB; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* DP4 instruction */ + /* dp4 o0.x, t0, c1 + dp4 o0.y, t0, c2 + dp4 o0.z, t0, c3 + dp4 o0.w, t0, c4 */ + for (i = 0; i < 4; ++i) + { + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_DP4; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = i + 1; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* END instruction */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + fs.tokens = tokens; + + context->states.csc.fragment_shader = pipe->create_fs_state(pipe, &fs); + + return 0; +} + +static int vlCreateDataBufsCSC(struct VL_CONTEXT *context) +{ + struct pipe_context *pipe; + + assert(context); + + pipe = context->pipe; + + /* + Create our vertex buffer and vertex buffer element + VB contains 4 vertices that render a quad covering the entire window + to display a rendered surface + Quad is rendered as a tri strip + */ + context->states.csc.vertex_bufs[0].pitch = sizeof(struct VL_VERTEX2F); + context->states.csc.vertex_bufs[0].max_index = 3; + context->states.csc.vertex_bufs[0].buffer_offset = 0; + context->states.csc.vertex_bufs[0].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct VL_VERTEX2F) * 4 + ); + + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, context->states.csc.vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + vl_surface_vertex_positions, + sizeof(struct VL_VERTEX2F) * 4 + ); + + pipe->winsys->buffer_unmap(pipe->winsys, context->states.csc.vertex_bufs[0].buffer); + + context->states.csc.vertex_buf_elems[0].src_offset = 0; + context->states.csc.vertex_buf_elems[0].vertex_buffer_index = 0; + context->states.csc.vertex_buf_elems[0].nr_components = 2; + context->states.csc.vertex_buf_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* + Create our texcoord buffer and texcoord buffer element + Texcoord buffer contains the TCs for mapping the rendered surface to the 4 vertices + */ + context->states.csc.vertex_bufs[1].pitch = sizeof(struct VL_TEXCOORD2F); + context->states.csc.vertex_bufs[1].max_index = 3; + context->states.csc.vertex_bufs[1].buffer_offset = 0; + context->states.csc.vertex_bufs[1].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct VL_TEXCOORD2F) * 4 + ); + + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, context->states.csc.vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + vl_surface_texcoords, + sizeof(struct VL_TEXCOORD2F) * 4 + ); + + pipe->winsys->buffer_unmap(pipe->winsys, context->states.csc.vertex_bufs[1].buffer); + + context->states.csc.vertex_buf_elems[1].src_offset = 0; + context->states.csc.vertex_buf_elems[1].vertex_buffer_index = 1; + context->states.csc.vertex_buf_elems[1].nr_components = 2; + context->states.csc.vertex_buf_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* + Create our fragment shader's constant buffer + Const buffer contains the color conversion matrix and bias vectors + */ + context->states.csc.fs_const_buf.size = sizeof(struct VL_CSC_FS_CONSTS); + context->states.csc.fs_const_buf.buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + context->states.csc.fs_const_buf.size + ); + + /* + TODO: Refactor this into a seperate function, + allow changing the csc matrix at runtime to switch between regular & full versions + */ + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, context->states.csc.fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + &vl_csc_fs_consts_601, + sizeof(struct VL_CSC_FS_CONSTS) + ); + + pipe->winsys->buffer_unmap(pipe->winsys, context->states.csc.fs_const_buf.buffer); + + return 0; +} + +static int vlInitCSC(struct VL_CONTEXT *context) +{ + struct pipe_context *pipe; + struct pipe_sampler_state sampler; + + assert(context); + + pipe = context->pipe; + + /* Delay creating the FB until vlPutSurface() so we know window size */ + context->states.csc.framebuffer.num_cbufs = 1; + context->states.csc.framebuffer.cbufs[0] = NULL; + context->states.csc.framebuffer.zsbuf = NULL; + + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.compare_mode = PIPE_TEX_COMPARE_NONE; + sampler.compare_func = PIPE_FUNC_ALWAYS; + sampler.normalized_coords = 1; + /*sampler.prefilter = ;*/ + /*sampler.shadow_ambient = ;*/ + /*sampler.lod_bias = ;*/ + /*sampler.min_lod = ;*/ + /*sampler.max_lod = ;*/ + /*sampler.border_color[i] = ;*/ + /*sampler.max_anisotropy = ;*/ + context->states.csc.sampler = pipe->create_sampler_state(pipe, &sampler); + + vlCreateVertexShaderCSC(context); + vlCreateFragmentShaderCSC(context); + vlCreateDataBufsCSC(context); + + return 0; +} + +static int vlDestroyCSC(struct VL_CONTEXT *context) +{ + assert(context); + + /* + Since we create the final FB when we display our first surface, + it may not be created if vlPutSurface() is never called + */ + if (context->states.csc.framebuffer.cbufs[0]) + context->pipe->winsys->surface_release(context->pipe->winsys, &context->states.csc.framebuffer.cbufs[0]); + context->pipe->delete_sampler_state(context->pipe, context->states.csc.sampler); + context->pipe->delete_vs_state(context->pipe, context->states.csc.vertex_shader); + context->pipe->delete_fs_state(context->pipe, context->states.csc.fragment_shader); + context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.csc.vertex_bufs[0].buffer); + context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.csc.vertex_bufs[1].buffer); + context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.csc.fs_const_buf.buffer); + + return 0; +} + +static int vlInitCommon(struct VL_CONTEXT *context) +{ + struct pipe_context *pipe; + struct pipe_rasterizer_state rast; + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state dsa; + unsigned int i; + + assert(context); + + pipe = context->pipe; + + rast.flatshade = 1; + rast.light_twoside = 0; + rast.front_winding = PIPE_WINDING_CCW; + rast.cull_mode = PIPE_WINDING_CW; + rast.fill_cw = PIPE_POLYGON_MODE_FILL; + rast.fill_ccw = PIPE_POLYGON_MODE_FILL; + rast.offset_cw = 0; + rast.offset_ccw = 0; + rast.scissor = 0; + rast.poly_smooth = 0; + rast.point_sprite = 0; + rast.point_size_per_vertex = 0; + rast.multisample = 0; + rast.line_smooth = 0; + rast.line_stipple_enable = 0; + rast.line_stipple_factor = 0; + rast.line_stipple_pattern = 0; + rast.line_last_pixel = 0; + /* Don't need clipping, but viewport mapping done here */ + rast.bypass_clipping = 0; + rast.bypass_vs = 0; + rast.origin_lower_left = 0; + rast.line_width = 1; + rast.point_size = 1; + rast.offset_units = 1; + rast.offset_scale = 1; + /*rast.sprite_coord_mode[i] = ;*/ + context->states.common.raster = pipe->create_rasterizer_state(pipe, &rast); + pipe->bind_rasterizer_state(pipe, context->states.common.raster); + + blend.blend_enable = 0; + blend.rgb_func = PIPE_BLEND_ADD; + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_func = PIPE_BLEND_ADD; + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.logicop_enable = 0; + blend.logicop_func = PIPE_LOGICOP_CLEAR; + /* Needed to allow color writes to FB, even if blending disabled */ + blend.colormask = PIPE_MASK_RGBA; + blend.dither = 0; + context->states.common.blend = pipe->create_blend_state(pipe, &blend); + pipe->bind_blend_state(pipe, context->states.common.blend); + + dsa.depth.enabled = 0; + dsa.depth.writemask = 0; + dsa.depth.func = PIPE_FUNC_ALWAYS; + dsa.depth.occlusion_count = 0; + for (i = 0; i < 2; ++i) + { + dsa.stencil[i].enabled = 0; + dsa.stencil[i].func = PIPE_FUNC_ALWAYS; + dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].ref_value = 0; + dsa.stencil[i].value_mask = 0; + dsa.stencil[i].write_mask = 0; + } + dsa.alpha.enabled = 0; + dsa.alpha.func = PIPE_FUNC_ALWAYS; + dsa.alpha.ref = 0; + context->states.common.dsa = pipe->create_depth_stencil_alpha_state(pipe, &dsa); + pipe->bind_depth_stencil_alpha_state(pipe, context->states.common.dsa); + + return 0; +} + +static int vlDestroyCommon(struct VL_CONTEXT *context) +{ + assert(context); + + context->pipe->delete_blend_state(context->pipe, context->states.common.blend); + context->pipe->delete_rasterizer_state(context->pipe, context->states.common.raster); + context->pipe->delete_depth_stencil_alpha_state(context->pipe, context->states.common.dsa); + + return 0; +} + +static int vlInit(struct VL_CONTEXT *context) +{ + assert(context); + + vlInitCommon(context); + vlInitCSC(context); + vlInitMC(context); + vlInitIDCT(context); + + return 0; +} + +static int vlDestroy(struct VL_CONTEXT *context) +{ + assert(context); + + /* Must unbind shaders before we can delete them for some reason */ + context->pipe->bind_vs_state(context->pipe, NULL); + context->pipe->bind_fs_state(context->pipe, NULL); + + vlDestroyCommon(context); + vlDestroyCSC(context); + vlDestroyMC(context); + vlDestroyIDCT(context); + + return 0; +} + +int vlCreateContext +( + Display *display, + struct pipe_context *pipe, + unsigned int video_width, + unsigned int video_height, + enum VL_FORMAT video_format, + struct VL_CONTEXT **context +) +{ + struct VL_CONTEXT *ctx; + + assert(display); + assert(pipe); + assert(context); + + ctx = calloc(1, sizeof(struct VL_CONTEXT)); + + ctx->display = display; + ctx->pipe = pipe; + ctx->video_width = video_width; + ctx->video_height = video_height; + ctx->video_format = video_format; + + vlInit(ctx); + + /* Since we only change states in vlPutSurface() we need to start in render mode */ + vlBeginRender(ctx); + + *context = ctx; + + return 0; +} + +int vlDestroyContext(struct VL_CONTEXT *context) +{ + assert(context); + + vlDestroy(context); + + free(context); + + return 0; +} + +int vlBeginRender(struct VL_CONTEXT *context) +{ + struct pipe_context *pipe; + + assert(context); + + pipe = context->pipe; + + /* Frame buffer set in vlRender*Macroblock() */ + /* Shaders, samplers, textures set in vlRender*Macroblock() */ + pipe->set_vertex_buffers(pipe, 3, context->states.mc.vertex_bufs); + pipe->set_vertex_elements(pipe, 3, context->states.mc.vertex_buf_elems); + pipe->set_viewport_state(pipe, &context->states.mc.viewport); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &context->states.mc.vs_const_buf); + pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &context->states.mc.fs_const_buf); + + return 0; +} + +int vlEndRender(struct VL_CONTEXT *context) +{ + struct pipe_context *pipe; + + assert(context); + + pipe = context->pipe; + + pipe->set_framebuffer_state(pipe, &context->states.csc.framebuffer); + pipe->set_viewport_state(pipe, &context->states.csc.viewport); + pipe->bind_sampler_states(pipe, 1, (void**)&context->states.csc.sampler); + /* Source texture set in vlPutSurface() */ + pipe->bind_vs_state(pipe, context->states.csc.vertex_shader); + pipe->bind_fs_state(pipe, context->states.csc.fragment_shader); + pipe->set_vertex_buffers(pipe, 2, context->states.csc.vertex_bufs); + pipe->set_vertex_elements(pipe, 2, context->states.csc.vertex_buf_elems); + pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &context->states.csc.fs_const_buf); + + return 0; +} + diff --git a/src/gallium/state_trackers/g3dvl/vl_context.h b/src/gallium/state_trackers/g3dvl/vl_context.h new file mode 100644 index 00000000000..f26a4c5b6a7 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_context.h @@ -0,0 +1,73 @@ +#ifndef vl_context_h +#define vl_context_h + +#include <X11/Xlib.h> +#include <pipe/p_state.h> +#include "vl_types.h" + +struct pipe_context; + +struct VL_CONTEXT +{ + Display *display; + struct pipe_context *pipe; + unsigned int video_width; + unsigned int video_height; + enum VL_FORMAT video_format; + + struct + { + struct + { + struct pipe_rasterizer_state *raster; + struct pipe_depth_stencil_alpha_state *dsa; + struct pipe_blend_state *blend; + } common; + + struct + { + } idct; + + struct + { + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state render_target; + struct pipe_sampler_state *samplers[5]; + struct pipe_texture *textures[5]; + struct pipe_shader_state *i_vs, *p_vs, *b_vs; + struct pipe_shader_state *i_fs, *p_fs, *b_fs; + struct pipe_vertex_buffer vertex_bufs[3]; + struct pipe_vertex_element vertex_buf_elems[3]; + struct pipe_constant_buffer vs_const_buf, fs_const_buf; + } mc; + + struct + { + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + struct pipe_sampler_state *sampler; + struct pipe_shader_state *vertex_shader, *fragment_shader; + struct pipe_vertex_buffer vertex_bufs[2]; + struct pipe_vertex_element vertex_buf_elems[2]; + struct pipe_constant_buffer fs_const_buf; + } csc; + } states; +}; + +int vlCreateContext +( + Display *display, + struct pipe_context *pipe, + unsigned int video_width, + unsigned int video_height, + enum VL_FORMAT video_format, + struct VL_CONTEXT **context +); + +int vlDestroyContext(struct VL_CONTEXT *context); + +int vlBeginRender(struct VL_CONTEXT *context); +int vlEndRender(struct VL_CONTEXT *context); + +#endif + diff --git a/src/gallium/state_trackers/g3dvl/vl_data.c b/src/gallium/state_trackers/g3dvl/vl_data.c new file mode 100644 index 00000000000..27893aee95e --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_data.c @@ -0,0 +1,180 @@ +#include "vl_data.h" + +/* + * Represents 8 triangles (4 quads, 1 per block) in noormalized coords + * that render a macroblock. + * Need to be scaled to cover mbW*mbH macroblock pixels and translated into + * position on target surface. + */ +const struct VL_VERTEX2F vl_mb_vertex_positions[24] = +{ + {0.0f, 0.0f}, {0.0f, 0.5f}, {0.5f, 0.0f}, + {0.5f, 0.0f}, {0.0f, 0.5f}, {0.5f, 0.5f}, + + {0.5f, 0.0f}, {0.5f, 0.5f}, {1.0f, 0.0f}, + {1.0f, 0.0f}, {0.5f, 0.5f}, {1.0f, 0.5f}, + + {0.0f, 0.5f}, {0.0f, 1.0f}, {0.5f, 0.5f}, + {0.5f, 0.5f}, {0.0f, 1.0f}, {0.5f, 1.0f}, + + {0.5f, 0.5f}, {0.5f, 1.0f}, {1.0f, 0.5f}, + {1.0f, 0.5f}, {0.5f, 1.0f}, {1.0f, 1.0f} +}; + +/* + * Represents texcoords for the above for rendering 4 luma blocks arranged + * in a bW*(bH*4) texture. First luma block located at 0,0->bW,bH; second at + * 0,bH->bW,2bH; third at 0,2bH->bW,3bH; fourth at 0,3bH->bW,4bH. + */ +const struct VL_TEXCOORD2F vl_luma_texcoords[24] = +{ + {0.0f, 0.0f}, {0.0f, 0.25f}, {1.0f, 0.0f}, + {1.0f, 0.0f}, {0.0f, 0.25f}, {1.0f, 0.25f}, + + {0.0f, 0.25f}, {0.0f, 0.5f}, {1.0f, 0.25f}, + {1.0f, 0.25f}, {0.0f, 0.5f}, {1.0f, 0.5f}, + + {0.0f, 0.5f}, {0.0f, 0.75f}, {1.0f, 0.5f}, + {1.0f, 0.5f}, {0.0f, 0.75f}, {1.0f, 0.75f}, + + {0.0f, 0.75f}, {0.0f, 1.0f}, {1.0f, 0.75f}, + {1.0f, 0.75f}, {0.0f, 1.0f}, {1.0f, 1.0f} +}; + +/* + * Represents texcoords for the above for rendering 1 chroma block. + * Straight forward 0,0->1,1 mapping so we can reuse the MB pos vectors. + */ +const struct VL_TEXCOORD2F *vl_chroma_420_texcoords = (const struct VL_TEXCOORD2F*)vl_mb_vertex_positions; + +/* + * Represents texcoords for the above for rendering 2 chroma blocks arranged + * in a bW*(bH*2) texture. First chroma block located at 0,0->bW,bH; second at + * 0,bH->bW,2bH. We can render this with 0,0->1,1 mapping. + * Straight forward 0,0->1,1 mapping so we can reuse MB pos vectors. + */ +const struct VL_TEXCOORD2F *vl_chroma_422_texcoords = (const struct VL_TEXCOORD2F*)vl_mb_vertex_positions; + +/* + * Represents texcoords for the above for rendering 4 chroma blocks. + * Same case as 4 luma blocks. + */ +const struct VL_TEXCOORD2F *vl_chroma_444_texcoords = vl_luma_texcoords; + +/* + * Represents 2 triangles in a strip in normalized coords. + * Used to render the surface onto the frame buffer. + */ +const struct VL_VERTEX2F vl_surface_vertex_positions[4] = +{ + {0.0f, 0.0f}, + {0.0f, 1.0f}, + {1.0f, 0.0f}, + {1.0f, 1.0f} +}; + +/* + * Represents texcoords for the above. We can use the position values directly. + */ +const struct VL_TEXCOORD2F *vl_surface_texcoords = (const struct VL_TEXCOORD2F*)vl_surface_vertex_positions; + +/* + * Used when rendering P and B macroblocks, multiplier is applied to the A channel, + * which is then added to the L channel, then the bias is subtracted from that to + * get back the differential. The differential is then added to the samples from the + * reference surface(s). + */ +const struct VL_MC_FS_CONSTS vl_mc_fs_consts = +{ + {256.0f, 256.0f, 256.0f, 0.0f}, + {256.0f / 255.0f, 256.0f / 255.0f, 256.0f / 255.0f, 0.0f} +}; + +/* + * Identity color conversion constants, for debugging + */ +const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_identity = +{ + { + 0.0f, 0.0f, 0.0f, 0.0f + }, + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } +}; + +/* + * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [16,235] + */ +const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_601 = +{ + { + 0.0f, 0.501960784f, 0.501960784f, 0.0f + }, + { + 1.0f, 0.0f, 1.371f, 0.0f, + 1.0f, -0.336f, -0.698f, 0.0f, + 1.0f, 1.732f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } +}; + +/* + * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [0,255] + */ +const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_601_full = +{ + { + 0.062745098f, 0.501960784f, 0.501960784f, 0.0f + }, + { + 1.164f, 0.0f, 1.596f, 0.0f, + 1.164f, -0.391f, -0.813f, 0.0f, + 1.164f, 2.018f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } +}; + +/* + * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [16,235] + */ +const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_709 = +{ + { + 0.0f, 0.501960784f, 0.501960784f, 0.0f + }, + { + 1.0f, 0.0f, 1.540f, 0.0f, + 1.0f, -0.183f, -0.459f, 0.0f, + 1.0f, 1.816f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } +}; + +/* + * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [0,255] + */ +const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_709_full = +{ + { + 0.062745098f, 0.501960784f, 0.501960784f, 0.0f + }, + { + 1.164f, 0.0f, 1.793f, 0.0f, + 1.164f, -0.213f, -0.534f, 0.0f, + 1.164f, 2.115f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } +}; + diff --git a/src/gallium/state_trackers/g3dvl/vl_data.h b/src/gallium/state_trackers/g3dvl/vl_data.h new file mode 100644 index 00000000000..8f347273ad7 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_data.h @@ -0,0 +1,24 @@ +#ifndef vl_data_h +#define vl_data_h + +#include "vl_types.h" + +extern const struct VL_VERTEX2F vl_mb_vertex_positions[24]; +extern const struct VL_TEXCOORD2F vl_luma_texcoords[24]; +extern const struct VL_TEXCOORD2F *vl_chroma_420_texcoords; +extern const struct VL_TEXCOORD2F *vl_chroma_422_texcoords; +extern const struct VL_TEXCOORD2F *vl_chroma_444_texcoords; + +extern const struct VL_VERTEX2F vl_surface_vertex_positions[4]; +extern const struct VL_TEXCOORD2F *vl_surface_texcoords; + +extern const struct VL_MC_FS_CONSTS vl_mc_fs_consts; + +extern const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_identity; +extern const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_601; +extern const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_601_full; +extern const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_709; +extern const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_709_full; + +#endif + diff --git a/src/gallium/state_trackers/g3dvl/vl_defs.h b/src/gallium/state_trackers/g3dvl/vl_defs.h new file mode 100644 index 00000000000..e668a7a10e0 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_defs.h @@ -0,0 +1,12 @@ +#ifndef vl_defs_h +#define vl_defs_h + +#define VL_BLOCK_WIDTH 8 +#define VL_BLOCK_HEIGHT 8 +#define VL_BLOCK_SIZE (VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT) +#define VL_MACROBLOCK_WIDTH 16 +#define VL_MACROBLOCK_HEIGHT 16 +#define VL_MACROBLOCK_SIZE (VL_MACROBLOCK_WIDTH * VL_MACROBLOCK_HEIGHT) + +#endif + diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c new file mode 100644 index 00000000000..0e1adea4729 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -0,0 +1,533 @@ +#include "vl_surface.h" +#include <assert.h> +#include <stdlib.h> +#include <pipe/p_context.h> +#include <pipe/p_state.h> +#include <pipe/p_format.h> +#include <pipe/p_inlines.h> +#include "vl_context.h" +#include "vl_defs.h" + +static int vlGrabBlocks +( + struct VL_CONTEXT *context, + unsigned int coded_block_pattern, + enum VL_DCT_TYPE dct_type, + enum VL_SAMPLE_TYPE sample_type, + short *blocks +) +{ + struct pipe_surface *tex_surface; + short *texels; + unsigned int b, x, y, y2; + + assert(context); + assert(blocks); + + tex_surface = context->pipe->screen->get_tex_surface + ( + context->pipe->screen, + context->states.mc.textures[0], + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE + ); + + texels = pipe_surface_map(tex_surface, 0); + + for (b = 0; b < 4; ++b) + { + if ((coded_block_pattern >> b) & 1) + { + if (dct_type == VL_DCT_FRAME_CODED) + { + if (sample_type == VL_FULL_SAMPLE) + { + for (y = VL_BLOCK_HEIGHT * b; y < VL_BLOCK_HEIGHT * (b + 1); ++y) + memcpy + ( + texels + y * tex_surface->pitch, + blocks + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + } + else + { + for (y = VL_BLOCK_HEIGHT * b; y < VL_BLOCK_HEIGHT * (b + 1); ++y) + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + texels[y * tex_surface->pitch + x] = + blocks[y * VL_BLOCK_WIDTH + x] + 0x100; + } + } + else + { + if (sample_type == VL_FULL_SAMPLE) + { + for + ( + y = VL_BLOCK_HEIGHT * (b % 2), y2 = VL_BLOCK_HEIGHT * b; + y < VL_BLOCK_HEIGHT * ((b % 2) + 1); + y += 2, ++y2 + ) + memcpy + ( + texels + y * tex_surface->pitch, + blocks + y2 * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + for + ( + y = VL_BLOCK_HEIGHT * ((b % 2) + 2); + y < VL_BLOCK_HEIGHT * (((b % 2) + 2) + 1); + y += 2, ++y2 + ) + memcpy + ( + texels + y * tex_surface->pitch, + blocks + y2 * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + } + else + { + for + ( + y = VL_BLOCK_HEIGHT * (b % 2), y2 = VL_BLOCK_HEIGHT * b; + y < VL_BLOCK_HEIGHT * ((b % 2) + 1); + y += 2, ++y2 + ) + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + texels[y * tex_surface->pitch + x] = + blocks[y2 * VL_BLOCK_WIDTH + x] + 0x100; + for + ( + y = VL_BLOCK_HEIGHT * ((b % 2) + 2); + y < VL_BLOCK_HEIGHT * (((b % 2) + 2) + 1); + y += 2, ++y2 + ) + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + texels[y * tex_surface->pitch + x] = + blocks[y2 * VL_BLOCK_WIDTH + x] + 0x100; + } + } + } + else + { + for (y = VL_BLOCK_HEIGHT * b; y < VL_BLOCK_HEIGHT * (b + 1); ++y) + { + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + texels[y * tex_surface->pitch + x] = 0x100; + } + } + } + + pipe_surface_unmap(tex_surface); + + /* TODO: Implement 422, 444 */ + for (b = 0; b < 2; ++b) + { + tex_surface = context->pipe->screen->get_tex_surface + ( + context->pipe->screen, + context->states.mc.textures[b + 1], + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE + ); + + texels = pipe_surface_map(tex_surface, 0); + + if ((coded_block_pattern >> (b + 4)) & 1) + { + if (sample_type == VL_FULL_SAMPLE) + { + for (y = 0; y < tex_surface->height; ++y) + memcpy + ( + texels + y * tex_surface->pitch, + blocks + VL_BLOCK_SIZE * (b + 4) + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + } + else + { + for (y = 0; y < tex_surface->height; ++y) + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + texels[y * tex_surface->pitch + x] = + blocks[VL_BLOCK_SIZE * (b + 4) + y * VL_BLOCK_WIDTH + x] + 0x100; + } + } + else + { + for (y = 0; y < tex_surface->height; ++y) + { + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + texels[y * tex_surface->pitch + x] = 0x100; + } + } + + pipe_surface_unmap(tex_surface); + } + + return 0; +} + +int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface) +{ + struct pipe_context *pipe; + struct pipe_texture template; + struct VL_SURFACE *sfc; + + assert(context); + assert(surface); + + pipe = context->pipe; + + sfc = calloc(1, sizeof(struct VL_SURFACE)); + + sfc->context = context; + sfc->width = context->video_width; + sfc->height = context->video_height; + sfc->format = context->video_format; + + memset(&template, 0, sizeof(struct pipe_texture)); + template.target = PIPE_TEXTURE_2D; + template.format = PIPE_FORMAT_A8R8G8B8_UNORM; + template.last_level = 0; + template.width[0] = sfc->width; + template.height[0] = sfc->height; + template.depth[0] = 1; + template.compressed = 0; + template.cpp = 4; + + sfc->texture = pipe->screen->texture_create(pipe->screen, &template); + + *surface = sfc; + + return 0; +} + +int vlDestroySurface(struct VL_SURFACE *surface) +{ + assert(surface); + pipe_texture_release(&surface->texture); + free(surface); + + return 0; +} + +int vlRenderIMacroBlock +( + enum VL_PICTURE picture_type, + enum VL_FIELD_ORDER field_order, + unsigned int mbx, + unsigned int mby, + unsigned int coded_block_pattern, + enum VL_DCT_TYPE dct_type, + short *blocks, + struct VL_SURFACE *surface +) +{ + struct pipe_context *pipe; + struct VL_MC_VS_CONSTS *vscbdata; + + assert(blocks); + assert(surface); + + /* TODO: Implement interlaced rendering */ + /*assert(picture_type == VL_FRAME_PICTURE);*/ + if (picture_type != VL_FRAME_PICTURE) + { + /*fprintf(stderr, "field picture (I) unimplemented, ignoring\n");*/ + return 0; + } + + pipe = surface->context->pipe; + + vscbdata = pipe->winsys->buffer_map + ( + pipe->winsys, + surface->context->states.mc.vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ); + + vscbdata->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width; + vscbdata->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height; + vscbdata->scale.z = 1.0f; + vscbdata->scale.w = 1.0f; + vscbdata->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width; + vscbdata->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height; + vscbdata->mb_pos_trans.z = 0.0f; + vscbdata->mb_pos_trans.w = 0.0f; + + pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.mc.vs_const_buf.buffer); + + vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_FULL_SAMPLE, blocks); + + surface->context->states.mc.render_target.cbufs[0] = pipe->screen->get_tex_surface + ( + pipe->screen, + surface->texture, + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE + ); + pipe->set_framebuffer_state(pipe, &surface->context->states.mc.render_target); + pipe->set_sampler_textures(pipe, 3, surface->context->states.mc.textures); + pipe->bind_sampler_states(pipe, 3, (void**)surface->context->states.mc.samplers); + pipe->bind_vs_state(pipe, surface->context->states.mc.i_vs); + pipe->bind_fs_state(pipe, surface->context->states.mc.i_fs); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); + + return 0; +} + +int vlRenderPMacroBlock +( + enum VL_PICTURE picture_type, + enum VL_FIELD_ORDER field_order, + unsigned int mbx, + unsigned int mby, + enum VL_MC_TYPE mc_type, + struct VL_MOTION_VECTOR *motion_vector, + unsigned int coded_block_pattern, + enum VL_DCT_TYPE dct_type, + short *blocks, + struct VL_SURFACE *ref_surface, + struct VL_SURFACE *surface +) +{ + struct pipe_context *pipe; + struct VL_MC_VS_CONSTS *vscbdata; + + assert(motion_vectors); + assert(blocks); + assert(ref_surface); + assert(surface); + + /* TODO: Implement interlaced rendering */ + /*assert(picture_type == VL_FRAME_PICTURE);*/ + if (picture_type != VL_FRAME_PICTURE) + { + /*fprintf(stderr, "field picture (P) unimplemented, ignoring\n");*/ + return 0; + } + /* TODO: Implement field based motion compensation */ + /*assert(mc_type == VL_FRAME_MC);*/ + if (mc_type != VL_FRAME_MC) + { + /*fprintf(stderr, "field MC (P) unimplemented, ignoring\n");*/ + return 0; + } + + pipe = surface->context->pipe; + + vscbdata = pipe->winsys->buffer_map + ( + pipe->winsys, + surface->context->states.mc.vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ); + + vscbdata->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width; + vscbdata->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height; + vscbdata->scale.z = 1.0f; + vscbdata->scale.w = 1.0f; + vscbdata->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width; + vscbdata->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height; + vscbdata->mb_pos_trans.z = 0.0f; + vscbdata->mb_pos_trans.w = 0.0f; + vscbdata->mb_tc_trans[0].x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector->top_field.x * 0.5f) / (float)surface->width; + vscbdata->mb_tc_trans[0].y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector->top_field.y * 0.5f) / (float)surface->height; + vscbdata->mb_tc_trans[0].z = 0.0f; + vscbdata->mb_tc_trans[0].w = 0.0f; + + pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.mc.vs_const_buf.buffer); + + vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks); + + surface->context->states.mc.render_target.cbufs[0] = pipe->screen->get_tex_surface + ( + pipe->screen, + surface->texture, + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE + ); + pipe->set_framebuffer_state(pipe, &surface->context->states.mc.render_target); + + surface->context->states.mc.textures[3] = ref_surface->texture; + pipe->set_sampler_textures(pipe, 4, surface->context->states.mc.textures); + pipe->bind_sampler_states(pipe, 4, (void**)surface->context->states.mc.samplers); + pipe->bind_vs_state(pipe, surface->context->states.mc.p_vs); + pipe->bind_fs_state(pipe, surface->context->states.mc.p_fs); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); + + return 0; +} + +int vlRenderBMacroBlock +( + enum VL_PICTURE picture_type, + enum VL_FIELD_ORDER field_order, + unsigned int mbx, + unsigned int mby, + enum VL_MC_TYPE mc_type, + struct VL_MOTION_VECTOR *motion_vector, + unsigned int coded_block_pattern, + enum VL_DCT_TYPE dct_type, + short *blocks, + struct VL_SURFACE *past_surface, + struct VL_SURFACE *future_surface, + struct VL_SURFACE *surface +) +{ + struct pipe_context *pipe; + struct VL_MC_VS_CONSTS *vscbdata; + + assert(motion_vectors); + assert(blocks); + assert(ref_surface); + assert(surface); + + /* TODO: Implement interlaced rendering */ + /*assert(picture_type == VL_FRAME_PICTURE);*/ + if (picture_type != VL_FRAME_PICTURE) + { + /*fprintf(stderr, "field picture (B) unimplemented, ignoring\n");*/ + return 0; + } + /* TODO: Implement field based motion compensation */ + /*assert(mc_type == VL_FRAME_MC);*/ + if (mc_type != VL_FRAME_MC) + { + /*fprintf(stderr, "field MC (B) unimplemented, ignoring\n");*/ + return 0; + } + + pipe = surface->context->pipe; + + vscbdata = pipe->winsys->buffer_map + ( + pipe->winsys, + surface->context->states.mc.vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ); + + vscbdata->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width; + vscbdata->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height; + vscbdata->scale.z = 1.0f; + vscbdata->scale.w = 1.0f; + vscbdata->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width; + vscbdata->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height; + vscbdata->mb_pos_trans.z = 0.0f; + vscbdata->mb_pos_trans.w = 0.0f; + vscbdata->mb_tc_trans[0].x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[0].top_field.x * 0.5f) / (float)surface->width; + vscbdata->mb_tc_trans[0].y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[0].top_field.y * 0.5f) / (float)surface->height; + vscbdata->mb_tc_trans[0].z = 0.0f; + vscbdata->mb_tc_trans[0].w = 0.0f; + vscbdata->mb_tc_trans[1].x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[1].top_field.x * 0.5f) / (float)surface->width; + vscbdata->mb_tc_trans[1].y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[1].top_field.y * 0.5f) / (float)surface->height; + vscbdata->mb_tc_trans[1].z = 0.0f; + vscbdata->mb_tc_trans[1].w = 0.0f; + + pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.mc.vs_const_buf.buffer); + + vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks); + + surface->context->states.mc.render_target.cbufs[0] = pipe->screen->get_tex_surface + ( + pipe->screen, + surface->texture, + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE + ); + pipe->set_framebuffer_state(pipe, &surface->context->states.mc.render_target); + + surface->context->states.mc.textures[3] = past_surface->texture; + surface->context->states.mc.textures[4] = future_surface->texture; + pipe->set_sampler_textures(pipe, 5, surface->context->states.mc.textures); + pipe->bind_sampler_states(pipe, 5, (void**)surface->context->states.mc.samplers); + pipe->bind_vs_state(pipe, surface->context->states.mc.b_vs); + pipe->bind_fs_state(pipe, surface->context->states.mc.b_fs); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); + + return 0; +} + +int vlPutSurface +( + struct VL_SURFACE *surface, + Drawable drawable, + unsigned int srcx, + unsigned int srcy, + unsigned int srcw, + unsigned int srch, + unsigned int destx, + unsigned int desty, + unsigned int destw, + unsigned int desth, + enum VL_PICTURE picture_type +) +{ + unsigned int create_fb = 0; + struct pipe_context *pipe; + + assert(surface); + + pipe = surface->context->pipe; + + if (!surface->context->states.csc.framebuffer.cbufs[0]) + create_fb = 1; + else if + ( + surface->context->states.csc.framebuffer.width != destw || + surface->context->states.csc.framebuffer.height != desth + ) + { + pipe->winsys->surface_release + ( + pipe->winsys, + &surface->context->states.csc.framebuffer.cbufs[0] + ); + + create_fb = 1; + } + + if (create_fb) + { + surface->context->states.csc.viewport.scale[0] = destw; + surface->context->states.csc.viewport.scale[1] = desth; + surface->context->states.csc.viewport.scale[2] = 1; + surface->context->states.csc.viewport.scale[3] = 1; + surface->context->states.csc.viewport.translate[0] = 0; + surface->context->states.csc.viewport.translate[1] = 0; + surface->context->states.csc.viewport.translate[2] = 0; + surface->context->states.csc.viewport.translate[3] = 0; + + surface->context->states.csc.framebuffer.width = destw; + surface->context->states.csc.framebuffer.height = desth; + surface->context->states.csc.framebuffer.cbufs[0] = pipe->winsys->surface_alloc(pipe->winsys); + pipe->winsys->surface_alloc_storage + ( + pipe->winsys, + surface->context->states.csc.framebuffer.cbufs[0], + destw, + desth, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE, + 0 + ); + } + + vlEndRender(surface->context); + + pipe->set_sampler_textures(pipe, 1, &surface->texture); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + pipe->winsys->flush_frontbuffer + ( + pipe->winsys, + surface->context->states.csc.framebuffer.cbufs[0], + &drawable + ); + + vlBeginRender(surface->context); + + return 0; +} + diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.h b/src/gallium/state_trackers/g3dvl/vl_surface.h new file mode 100644 index 00000000000..9f56b77e1e7 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_surface.h @@ -0,0 +1,81 @@ +#ifndef vl_surface_h +#define vl_surface_h + +#include <X11/Xlib.h> +#include "vl_types.h" + +struct pipe_texture; + +struct VL_SURFACE +{ + struct VL_CONTEXT *context; + unsigned int width; + unsigned int height; + enum VL_FORMAT format; + struct pipe_texture *texture; +}; + +int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface); + +int vlDestroySurface(struct VL_SURFACE *surface); + +int vlRenderIMacroBlock +( + enum VL_PICTURE picture_type, + enum VL_FIELD_ORDER field_order, + unsigned int mbx, + unsigned int mby, + unsigned int coded_block_pattern, + enum VL_DCT_TYPE dct_type, + short *blocks, + struct VL_SURFACE *surface +); + +int vlRenderPMacroBlock +( + enum VL_PICTURE picture_type, + enum VL_FIELD_ORDER field_order, + unsigned int mbx, + unsigned int mby, + enum VL_MC_TYPE mc_type, + struct VL_MOTION_VECTOR *motion_vector, + unsigned int coded_block_pattern, + enum VL_DCT_TYPE dct_type, + short *blocks, + struct VL_SURFACE *ref_surface, + struct VL_SURFACE *surface +); + +int vlRenderBMacroBlock +( + enum VL_PICTURE picture_type, + enum VL_FIELD_ORDER field_order, + unsigned int mbx, + unsigned int mby, + enum VL_MC_TYPE mc_type, + struct VL_MOTION_VECTOR *motion_vector, + unsigned int coded_block_pattern, + enum VL_DCT_TYPE dct_type, + short *blocks, + struct VL_SURFACE *past_surface, + struct VL_SURFACE *future_surface, + struct VL_SURFACE *surface +); + +int vlPutSurface +( + struct VL_SURFACE *surface, + Drawable drawable, + unsigned int srcx, + unsigned int srcy, + unsigned int srcw, + unsigned int srch, + unsigned int destx, + unsigned int desty, + unsigned int destw, + unsigned int desth, + enum VL_PICTURE picture_type +); + +#endif + diff --git a/src/gallium/state_trackers/g3dvl/vl_types.h b/src/gallium/state_trackers/g3dvl/vl_types.h new file mode 100644 index 00000000000..7040b745036 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_types.h @@ -0,0 +1,88 @@ +#ifndef vl_types_h +#define vl_types_h + +enum VL_FORMAT +{ + VL_FORMAT_YCBCR_420, + VL_FORMAT_YCBCR_422, + VL_FORMAT_YCBCR_444 +}; + +enum VL_PICTURE +{ + VL_TOP_FIELD, + VL_BOTTOM_FIELD, + VL_FRAME_PICTURE +}; + +enum VL_FIELD_ORDER +{ + VL_FIELD_FIRST, + VL_FIELD_SECOND +}; + +enum VL_DCT_TYPE +{ + VL_DCT_FIELD_CODED, + VL_DCT_FRAME_CODED +}; + +enum VL_SAMPLE_TYPE +{ + VL_FULL_SAMPLE, + VL_DIFFERENCE_SAMPLE +}; + +enum VL_MC_TYPE +{ + VL_FIELD_MC, + VL_FRAME_MC +}; + +struct VL_VERTEX4F +{ + float x, y, z, w; +}; + +struct VL_VERTEX2F +{ + float x, y; +}; + +struct VL_TEXCOORD2F +{ + float s, t; +}; + +struct VL_MC_VS_CONSTS +{ + struct VL_VERTEX4F scale; + struct VL_VERTEX4F mb_pos_trans; + struct VL_VERTEX4F mb_tc_trans[2]; +}; + +struct VL_MC_FS_CONSTS +{ + struct VL_VERTEX4F multiplier; + struct VL_VERTEX4F bias; +}; + +struct VL_CSC_FS_CONSTS +{ + struct VL_VERTEX4F bias; + float matrix[16]; +}; + +struct VL_MOTION_VECTOR +{ + struct + { + int x, y; + } top_field, bottom_field; +}; + +struct VL_CONTEXT; +struct VL_SURFACE; + +#endif + diff --git a/src/gallium/winsys/dri/nouveau/Makefile b/src/gallium/winsys/dri/nouveau/Makefile new file mode 100644 index 00000000000..f637b2cebfc --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/Makefile @@ -0,0 +1,44 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = nouveau_dri.so + +MINIGLX_SOURCES = + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/nv10/libnv10.a \ + $(TOP)/src/gallium/drivers/nv30/libnv30.a \ + $(TOP)/src/gallium/drivers/nv40/libnv40.a \ + $(TOP)/src/gallium/drivers/nv50/libnv50.a + +DRIVER_SOURCES = \ + nouveau_bo.c \ + nouveau_channel.c \ + nouveau_context.c \ + nouveau_device.c \ + nouveau_dma.c \ + nouveau_fence.c \ + nouveau_grobj.c \ + nouveau_lock.c \ + nouveau_notifier.c \ + nouveau_pushbuf.c \ + nouveau_resource.c \ + nouveau_screen.c \ + nouveau_swapbuffers.c \ + nouveau_winsys.c \ + nouveau_winsys_pipe.c \ + nouveau_winsys_softpipe.c \ + nv04_surface.c \ + nv50_surface.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../Makefile.template + +symlinks: diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c new file mode 100644 index 00000000000..57f5b7d1ae1 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -0,0 +1,454 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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 <stdint.h> +#include <stdlib.h> +#include <errno.h> +#include <assert.h> + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static void +nouveau_mem_free(struct nouveau_device *dev, struct drm_nouveau_mem_alloc *ma, + void **map) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_mem_free mf; + + if (map && *map) { + drmUnmap(*map, ma->size); + *map = NULL; + } + + if (ma->size) { + mf.offset = ma->offset; + mf.flags = ma->flags; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_MEM_FREE, + &mf, sizeof(mf)); + ma->size = 0; + } +} + +static int +nouveau_mem_alloc(struct nouveau_device *dev, unsigned size, unsigned align, + uint32_t flags, struct drm_nouveau_mem_alloc *ma, void **map) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + int ret; + + ma->alignment = align; + ma->size = size; + ma->flags = flags; + if (map) + ma->flags |= NOUVEAU_MEM_MAPPED; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_MEM_ALLOC, ma, + sizeof(struct drm_nouveau_mem_alloc)); + if (ret) + return ret; + + if (map) { + ret = drmMap(nvdev->fd, ma->map_handle, ma->size, map); + if (ret) { + *map = NULL; + nouveau_mem_free(dev, ma, map); + return ret; + } + } + + return 0; +} + +static void +nouveau_bo_tmp_del(void *priv) +{ + struct nouveau_resource *r = priv; + + nouveau_fence_ref(NULL, (struct nouveau_fence **)&r->priv); + nouveau_resource_free(&r); +} + +static unsigned +nouveau_bo_tmp_max(struct nouveau_device_priv *nvdev) +{ + struct nouveau_resource *r = nvdev->sa_heap; + unsigned max = 0; + + while (r) { + if (r->in_use && !nouveau_fence(r->priv)->emitted) { + r = r->next; + continue; + } + + if (max < r->size) + max = r->size; + r = r->next; + } + + return max; +} + +static struct nouveau_resource * +nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, + struct nouveau_fence *fence) +{ + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_resource *r = NULL; + struct nouveau_fence *ref = NULL; + + if (fence) + nouveau_fence_ref(fence, &ref); + else + nouveau_fence_new(chan, &ref); + assert(ref); + + while (nouveau_resource_alloc(nvdev->sa_heap, size, ref, &r)) { + if (nouveau_bo_tmp_max(nvdev) < size) { + nouveau_fence_ref(NULL, &ref); + return NULL; + } + + nouveau_fence_flush(chan); + } + nouveau_fence_signal_cb(ref, nouveau_bo_tmp_del, r); + + return r; +} + +int +nouveau_bo_init(struct nouveau_device *dev) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + int ret; + + ret = nouveau_mem_alloc(dev, 128*1024, 0, NOUVEAU_MEM_AGP | + NOUVEAU_MEM_PCI, &nvdev->sa, &nvdev->sa_map); + if (ret) + return ret; + + ret = nouveau_resource_init(&nvdev->sa_heap, 0, nvdev->sa.size); + if (ret) { + nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); + return ret; + } + + return 0; +} + +void +nouveau_bo_takedown(struct nouveau_device *dev) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nouveau_mem_free(dev, &nvdev->sa, &nvdev->sa_map); +} + +int +nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, + int size, struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + int ret; + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo = calloc(1, sizeof(struct nouveau_bo_priv)); + if (!nvbo) + return -ENOMEM; + nvbo->base.device = dev; + nvbo->base.size = size; + nvbo->base.handle = bo_to_ptr(nvbo); + nvbo->drm.alignment = align; + nvbo->refcount = 1; + + ret = nouveau_bo_set_status(&nvbo->base, flags); + if (ret) { + free(nvbo); + return ret; + } + + *bo = &nvbo->base; + return 0; +} + +int +nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size, + struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo = calloc(1, sizeof(*nvbo)); + if (!nvbo) + return -ENOMEM; + nvbo->base.device = dev; + + nvbo->sysmem = ptr; + nvbo->user = 1; + + nvbo->base.size = size; + nvbo->base.offset = nvbo->drm.offset; + nvbo->base.handle = bo_to_ptr(nvbo); + nvbo->refcount = 1; + *bo = &nvbo->base; + return 0; +} + +int +nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, + struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo = ptr_to_bo(handle); + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo->refcount++; + *bo = &nvbo->base; + return 0; +} + +static void +nouveau_bo_del_cb(void *priv) +{ + struct nouveau_bo_priv *nvbo = priv; + + nouveau_fence_ref(NULL, &nvbo->fence); + nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); + if (nvbo->sysmem && !nvbo->user) + free(nvbo->sysmem); + free(nvbo); +} + +void +nouveau_bo_del(struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + + if (!bo || !*bo) + return; + nvbo = nouveau_bo(*bo); + *bo = NULL; + + if (--nvbo->refcount) + return; + + if (nvbo->pending) + nouveau_pushbuf_flush(nvbo->pending->channel, 0); + + if (nvbo->fence) + nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo); + else + nouveau_bo_del_cb(nvbo); +} + +int +nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + + if (!nvbo) + return -EINVAL; + + if (nvbo->pending && + (nvbo->pending->flags & NOUVEAU_BO_WR || flags & NOUVEAU_BO_WR)) { + nouveau_pushbuf_flush(nvbo->pending->channel, 0); + } + + if (flags & NOUVEAU_BO_WR) + nouveau_fence_wait(&nvbo->fence); + else + nouveau_fence_wait(&nvbo->wr_fence); + + if (nvbo->sysmem) + bo->map = nvbo->sysmem; + else + bo->map = nvbo->map; + return 0; +} + +void +nouveau_bo_unmap(struct nouveau_bo *bo) +{ + bo->map = NULL; +} + +static int +nouveau_bo_upload(struct nouveau_bo_priv *nvbo) +{ + if (nvbo->fence) + nouveau_fence_wait(&nvbo->fence); + memcpy(nvbo->map, nvbo->sysmem, nvbo->drm.size); + return 0; +} + +int +nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct drm_nouveau_mem_alloc new; + void *new_map = NULL, *new_sysmem = NULL; + unsigned new_flags = 0, ret; + + assert(!bo->map); + + /* Check current memtype vs requested, if they match do nothing */ + if ((nvbo->drm.flags & NOUVEAU_MEM_FB) && (flags & NOUVEAU_BO_VRAM)) + return 0; + if ((nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) && + (flags & NOUVEAU_BO_GART)) + return 0; + if (nvbo->drm.size == 0 && nvbo->sysmem && (flags & NOUVEAU_BO_LOCAL)) + return 0; + + memset(&new, 0x00, sizeof(new)); + + /* Allocate new memory */ + if (flags & NOUVEAU_BO_VRAM) + new_flags |= NOUVEAU_MEM_FB; + else + if (flags & NOUVEAU_BO_GART) + new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); + + if (new_flags) { + ret = nouveau_mem_alloc(bo->device, bo->size, + nvbo->drm.alignment, new_flags, + &new, &new_map); + if (ret) + return ret; + } else + if (!nvbo->user) { + new_sysmem = malloc(bo->size); + } + + /* Copy old -> new */ + /*XXX: use M2MF */ + if (nvbo->sysmem || nvbo->map) { + nouveau_bo_map(bo, NOUVEAU_BO_RD); + memcpy(new_map, bo->map, bo->size); + nouveau_bo_unmap(bo); + } + + /* Free old memory */ + if (nvbo->fence) + nouveau_fence_wait(&nvbo->fence); + nouveau_mem_free(bo->device, &nvbo->drm, &nvbo->map); + if (nvbo->sysmem && !nvbo->user) + free(nvbo->sysmem); + + nvbo->drm = new; + nvbo->map = new_map; + if (!nvbo->user) + nvbo->sysmem = new_sysmem; + bo->flags = flags; + bo->offset = nvbo->drm.offset; + return 0; +} + +static int +nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, + struct nouveau_fence *fence, uint32_t flags) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_resource *r; + + if (nvchan->user_charge + bo->size > nvdev->sa.size) + return 1; + + if (!(flags & NOUVEAU_BO_GART)) + return 1; + + r = nouveau_bo_tmp(chan, bo->size, fence); + if (!r) + return 1; + nvchan->user_charge += bo->size; + + memcpy(nvdev->sa_map + r->start, nvbo->sysmem, bo->size); + + nvbo->offset = nvdev->sa.offset + r->start; + nvbo->flags = NOUVEAU_BO_GART; + return 0; +} + +static int +nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, + struct nouveau_fence *fence, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + int ret; + + ret = nouveau_bo_set_status(bo, flags); + if (ret) { + nouveau_fence_flush(chan); + + ret = nouveau_bo_set_status(bo, flags); + if (ret) + return ret; + } + + if (nvbo->user) + nouveau_bo_upload(nvbo); + + nvbo->offset = nvbo->drm.offset; + if (nvbo->drm.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) + nvbo->flags = NOUVEAU_BO_GART; + else + nvbo->flags = NOUVEAU_BO_VRAM; + + return 0; +} + +int +nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, + uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_fence *fence = nouveau_pushbuf(chan->pushbuf)->fence; + int ret; + + assert(bo->map == NULL); + + if (nvbo->user) { + ret = nouveau_bo_validate_user(chan, bo, fence, flags); + if (ret) { + ret = nouveau_bo_validate_bo(chan, bo, fence, flags); + if (ret) + return ret; + } + } else { + ret = nouveau_bo_validate_bo(chan, bo, fence, flags); + if (ret) + return ret; + } + + if (flags & NOUVEAU_BO_WR) + nouveau_fence_ref(fence, &nvbo->wr_fence); + nouveau_fence_ref(fence, &nvbo->fence); + return 0; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_channel.c b/src/gallium/winsys/dri/nouveau/nouveau_channel.c new file mode 100644 index 00000000000..3b4dcd1ecf2 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_channel.c @@ -0,0 +1,126 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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 <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +int +nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, + uint32_t tt_ctxdma, struct nouveau_channel **chan) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct nouveau_channel_priv *nvchan; + int ret; + + if (!nvdev || !chan || *chan) + return -EINVAL; + + nvchan = calloc(1, sizeof(struct nouveau_channel_priv)); + if (!nvchan) + return -ENOMEM; + nvchan->base.device = dev; + + nvchan->drm.fb_ctxdma_handle = fb_ctxdma; + nvchan->drm.tt_ctxdma_handle = tt_ctxdma; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, + &nvchan->drm, sizeof(nvchan->drm)); + if (ret) { + free(nvchan); + return ret; + } + + nvchan->base.id = nvchan->drm.channel; + if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle, + &nvchan->base.vram) || + nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle, + &nvchan->base.gart)) { + nouveau_channel_free((void *)&nvchan); + return -EINVAL; + } + + ret = drmMap(nvdev->fd, nvchan->drm.ctrl, nvchan->drm.ctrl_size, + (void*)&nvchan->user); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + nvchan->put = &nvchan->user[0x40/4]; + nvchan->get = &nvchan->user[0x44/4]; + nvchan->ref_cnt = &nvchan->user[0x48/4]; + + ret = drmMap(nvdev->fd, nvchan->drm.notifier, nvchan->drm.notifier_size, + (drmAddressPtr)&nvchan->notifier_block); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + ret = drmMap(nvdev->fd, nvchan->drm.cmdbuf, nvchan->drm.cmdbuf_size, + (void*)&nvchan->pushbuf); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030, + &nvchan->base.nullobj); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + nouveau_dma_channel_init(&nvchan->base); + nouveau_pushbuf_init(&nvchan->base); + + *chan = &nvchan->base; + return 0; +} + +void +nouveau_channel_free(struct nouveau_channel **chan) +{ + struct nouveau_channel_priv *nvchan; + struct nouveau_device_priv *nvdev; + struct drm_nouveau_channel_free cf; + + if (!chan || !*chan) + return; + nvchan = nouveau_channel(*chan); + *chan = NULL; + nvdev = nouveau_device(nvchan->base.device); + + FIRE_RING_CH(&nvchan->base); + + nouveau_grobj_free(&nvchan->base.vram); + nouveau_grobj_free(&nvchan->base.gart); + nouveau_grobj_free(&nvchan->base.nullobj); + + cf.channel = nvchan->drm.channel; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); + free(nvchan); +} + + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c new file mode 100644 index 00000000000..ef5fb7ec0d3 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -0,0 +1,341 @@ +#include "main/glheader.h" +#include "glapi/glthread.h" +#include <GL/internal/glcore.h> +#include "utils.h" + +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" + +#include "nouveau_context.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_winsys_pipe.h" + +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + { "bo", DEBUG_BO }, + { NULL, 0 } +}; +int __nouveau_debug = 0; +#endif + +static void +nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) +{ + nouveau_grobj_free(&nvc->NvCtxSurf2D); + nouveau_grobj_free(&nvc->NvImageBlit); + nouveau_grobj_free(&nvc->NvGdiRect); + nouveau_grobj_free(&nvc->NvM2MF); + nouveau_grobj_free(&nvc->Nv2D); + nouveau_grobj_free(&nvc->NvSwzSurf); + nouveau_grobj_free(&nvc->NvSIFM); + + nouveau_notifier_free(&nvc->sync_notifier); + + nouveau_channel_free(&nvc->channel); + + FREE(nvc); +} + +static struct nouveau_channel_context * +nouveau_channel_context_create(struct nouveau_device *dev) +{ + struct nouveau_channel_context *nvc; + int ret; + + nvc = CALLOC_STRUCT(nouveau_channel_context); + if (!nvc) + return NULL; + + if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002, + &nvc->channel))) { + NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + nvc->next_handle = 0x80000000; + + if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1, + &nvc->sync_notifier))) { + NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + ret = nouveau_surface_channel_create_nv50(nvc); + break; + default: + ret = nouveau_surface_channel_create_nv04(nvc); + break; + } + + if (ret) { + NOUVEAU_ERR("Error initialising surface objects: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + return nvc; +} + +GLboolean +nouveau_context_create(const __GLcontextModes *glVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate) +{ + __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; + struct nouveau_screen *nv_screen = driScrnPriv->private; + struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context); + struct pipe_context *pipe = NULL; + struct st_context *st_share = NULL; + struct nouveau_channel_context *nvc = NULL; + struct nouveau_device *dev = nv_screen->device; + int i; + + if (sharedContextPrivate) { + st_share = ((struct nouveau_context *)sharedContextPrivate)->st; + } + + switch (dev->chipset & 0xf0) { + case 0x10: + case 0x20: + /* NV10 */ + case 0x30: + /* NV30 */ + case 0x40: + case 0x60: + /* NV40 */ + case 0x50: + case 0x80: + case 0x90: + /* G80 */ + break; + default: + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset); + return GL_FALSE; + } + + driContextPriv->driverPrivate = (void *)nv; + nv->nv_screen = nv_screen; + nv->dri_screen = driScrnPriv; + + { + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nvdev->ctx = driContextPriv->hHWContext; + nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; + } + + driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, + nv->dri_screen->myNum, "nouveau"); +#ifdef DEBUG + __nouveau_debug = driParseDebugString(getenv("NOUVEAU_DEBUG"), + debug_control); +#endif + + /*XXX: Hack up a fake region and buffer object for front buffer. + * This will go away with TTM, replaced with a simple reference + * of the front buffer handle passed to us by the DDX. + */ + { + struct pipe_surface *fb_surf; + struct nouveau_pipe_buffer *fb_buf; + struct nouveau_bo_priv *fb_bo; + + fb_bo = calloc(1, sizeof(struct nouveau_bo_priv)); + fb_bo->drm.offset = nv_screen->front_offset; + fb_bo->drm.flags = NOUVEAU_MEM_FB; + fb_bo->drm.size = nv_screen->front_pitch * + nv_screen->front_height; + fb_bo->refcount = 1; + fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM; + fb_bo->base.offset = fb_bo->drm.offset; + fb_bo->base.handle = (unsigned long)fb_bo; + fb_bo->base.size = fb_bo->drm.size; + fb_bo->base.device = nv_screen->device; + + fb_buf = calloc(1, sizeof(struct nouveau_pipe_buffer)); + fb_buf->bo = &fb_bo->base; + + fb_surf = calloc(1, sizeof(struct pipe_surface)); + fb_surf->cpp = nv_screen->front_cpp; + fb_surf->pitch = nv_screen->front_pitch / fb_surf->cpp; + fb_surf->height = nv_screen->front_height; + fb_surf->refcount = 1; + fb_surf->buffer = &fb_buf->base; + + nv->frontbuffer = fb_surf; + } + + /* Attempt to share a single channel between multiple contexts from + * a single process. + */ + nvc = nv_screen->nvc; + if (!nvc && st_share) { + struct nouveau_context *snv = st_share->pipe->priv; + if (snv) { + nvc = snv->nvc; + } + } + + /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */ + switch (dev->chipset & 0xf0) { + case 0x40: + case 0x60: + /* NV40 class */ + case 0x50: + case 0x80: + case 0x90: + /* G80 class */ + break; + default: + nvc = NULL; + break; + } + + if (!nvc) { + nvc = nouveau_channel_context_create(dev); + if (!nvc) { + NOUVEAU_ERR("Failed initialising GPU context\n"); + return GL_FALSE; + } + nv_screen->nvc = nvc; + } + + nvc->refcount++; + nv->nvc = nvc; + + /* Find a free slot for a pipe context, allocate a new one if needed */ + nv->pctx_id = -1; + for (i = 0; i < nvc->nr_pctx; i++) { + if (nvc->pctx[i] == NULL) { + nv->pctx_id = i; + break; + } + } + + if (nv->pctx_id < 0) { + nv->pctx_id = nvc->nr_pctx++; + nvc->pctx = + realloc(nvc->pctx, + sizeof(struct pipe_context *) * nvc->nr_pctx); + } + + /* Create pipe */ + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + if (nouveau_surface_init_nv50(nv)) + return GL_FALSE; + break; + default: + if (nouveau_surface_init_nv04(nv)) + return GL_FALSE; + break; + } + + if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { + struct pipe_screen *pscreen; + + pipe = nouveau_pipe_create(nv); + if (!pipe) + NOUVEAU_ERR("Couldn't create hw pipe\n"); + pscreen = nvc->pscreen; + + nv->cap.hw_vertex_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF); + nv->cap.hw_index_buffer = + pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF); + } + + if (!pipe) { + NOUVEAU_MSG("Using softpipe\n"); + pipe = nouveau_create_softpipe(nv); + if (!pipe) { + NOUVEAU_ERR("Error creating pipe, bailing\n"); + return GL_FALSE; + } + } + + pipe->priv = nv; + nv->st = st_create_context(pipe, glVis, st_share); + return GL_TRUE; +} + +void +nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) +{ + struct nouveau_context *nv = driContextPriv->driverPrivate; + struct nouveau_channel_context *nvc = nv->nvc; + + assert(nv); + + st_finish(nv->st); + st_destroy_context(nv->st); + + if (nv->pctx_id >= 0) { + nvc->pctx[nv->pctx_id] = NULL; + if (--nvc->refcount <= 0) { + nouveau_channel_context_destroy(nvc); + nv->nv_screen->nvc = NULL; + } + } + + free(nv); +} + +GLboolean +nouveau_context_bind(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + struct nouveau_context *nv; + struct nouveau_framebuffer *draw, *read; + + if (!driContextPriv) { + st_make_current(NULL, NULL, NULL); + return GL_TRUE; + } + + nv = driContextPriv->driverPrivate; + draw = driDrawPriv->driverPrivate; + read = driReadPriv->driverPrivate; + + st_make_current(nv->st, draw->stfb, read->stfb); + + if ((nv->dri_drawable != driDrawPriv) || + (nv->last_stamp != driDrawPriv->lastStamp)) { + nv->dri_drawable = driDrawPriv; + st_resize_framebuffer(draw->stfb, driDrawPriv->w, + driDrawPriv->h); + nv->last_stamp = driDrawPriv->lastStamp; + } + + if (driDrawPriv != driReadPriv) { + st_resize_framebuffer(read->stfb, driReadPriv->w, + driReadPriv->h); + } + + return GL_TRUE; +} + +GLboolean +nouveau_context_unbind(__DRIcontextPrivate *driContextPriv) +{ + struct nouveau_context *nv = driContextPriv->driverPrivate; + (void)nv; + + st_flush(nv->st, 0, NULL); + return GL_TRUE; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h new file mode 100644 index 00000000000..77e2147a2c7 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -0,0 +1,113 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "dri_util.h" +#include "xmlconfig.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +struct nouveau_framebuffer { + struct st_framebuffer *stfb; +}; + +struct nouveau_channel_context { + struct pipe_screen *pscreen; + int refcount; + + unsigned cur_pctx; + unsigned nr_pctx; + struct pipe_context **pctx; + + struct nouveau_channel *channel; + + struct nouveau_notifier *sync_notifier; + + /* Common */ + struct nouveau_grobj *NvM2MF; + /* NV04-NV40 */ + struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvSwzSurf; + struct nouveau_grobj *NvImageBlit; + struct nouveau_grobj *NvGdiRect; + struct nouveau_grobj *NvSIFM; + /* G80 */ + struct nouveau_grobj *Nv2D; + + uint32_t next_handle; + uint32_t next_subchannel; + uint32_t next_sequence; +}; + +struct nouveau_context { + struct st_context *st; + + /* DRI stuff */ + __DRIscreenPrivate *dri_screen; + __DRIdrawablePrivate *dri_drawable; + unsigned int last_stamp; + driOptionCache dri_option_cache; + drm_context_t drm_context; + drmLock drm_lock; + GLboolean locked; + struct nouveau_screen *nv_screen; + struct pipe_surface *frontbuffer; + + struct { + int hw_vertex_buffer; + int hw_index_buffer; + } cap; + + /* Hardware context */ + struct nouveau_channel_context *nvc; + int pctx_id; + + /* pipe_surface accel */ + struct pipe_surface *surf_src, *surf_dst; + unsigned surf_src_offset, surf_dst_offset; + int (*surface_copy_prep)(struct nouveau_context *, + struct pipe_surface *dst, + struct pipe_surface *src); + void (*surface_copy)(struct nouveau_context *, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h); + void (*surface_copy_done)(struct nouveau_context *); + int (*surface_fill)(struct nouveau_context *, struct pipe_surface *, + unsigned, unsigned, unsigned, unsigned, unsigned); +}; + +extern GLboolean nouveau_context_create(const __GLcontextModes *, + __DRIcontextPrivate *, void *); +extern void nouveau_context_destroy(__DRIcontextPrivate *); +extern GLboolean nouveau_context_bind(__DRIcontextPrivate *, + __DRIdrawablePrivate *draw, + __DRIdrawablePrivate *read); +extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *); + +#ifdef DEBUG +extern int __nouveau_debug; + +#define DEBUG_BO (1 << 0) + +#define DBG(flag, ...) do { \ + if (__nouveau_debug & (DEBUG_##flag)) \ + NOUVEAU_ERR(__VA_ARGS__); \ +} while(0) +#else +#define DBG(flag, ...) +#endif + +extern void LOCK_HARDWARE(struct nouveau_context *); +extern void UNLOCK_HARDWARE(struct nouveau_context *); + +extern int +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *); +extern int +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *); +extern int nouveau_surface_init_nv04(struct nouveau_context *); +extern int nouveau_surface_init_nv50(struct nouveau_context *); + +extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int); +extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *); + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_device.c b/src/gallium/winsys/dri/nouveau/nouveau_device.c new file mode 100644 index 00000000000..0b452fcd02d --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_device.c @@ -0,0 +1,159 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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 <stdio.h> +#include <stdlib.h> +#include <errno.h> + +#include "nouveau_drmif.h" + +int +nouveau_device_open_existing(struct nouveau_device **dev, int close, + int fd, drm_context_t ctx) +{ + struct nouveau_device_priv *nvdev; + int ret; + + if (!dev || *dev) + return -EINVAL; + + nvdev = calloc(1, sizeof(*nvdev)); + if (!nvdev) + return -ENOMEM; + nvdev->fd = fd; + nvdev->ctx = ctx; + nvdev->needs_close = close; + + drmCommandNone(nvdev->fd, DRM_NOUVEAU_CARD_INIT); + + if ((ret = nouveau_bo_init(&nvdev->base))) { + nouveau_device_close((void *)&nvdev); + return ret; + } + + { + uint64_t value; + + ret = nouveau_device_get_param(&nvdev->base, + NOUVEAU_GETPARAM_CHIPSET_ID, + &value); + if (ret) { + nouveau_device_close((void *)&nvdev); + return ret; + } + nvdev->base.chipset = value; + } + + *dev = &nvdev->base; + return 0; +} + +int +nouveau_device_open(struct nouveau_device **dev, const char *busid) +{ + drm_context_t ctx; + int fd, ret; + + if (!dev || *dev) + return -EINVAL; + + fd = drmOpen("nouveau", busid); + if (fd < 0) + return -EINVAL; + + ret = drmCreateContext(fd, &ctx); + if (ret) { + drmClose(fd); + return ret; + } + + ret = nouveau_device_open_existing(dev, 1, fd, ctx); + if (ret) { + drmDestroyContext(fd, ctx); + drmClose(fd); + return ret; + } + + return 0; +} + +void +nouveau_device_close(struct nouveau_device **dev) +{ + struct nouveau_device_priv *nvdev; + + if (dev || !*dev) + return; + nvdev = nouveau_device(*dev); + *dev = NULL; + + nouveau_bo_takedown(&nvdev->base); + + if (nvdev->needs_close) { + drmDestroyContext(nvdev->fd, nvdev->ctx); + drmClose(nvdev->fd); + } + free(nvdev); +} + +int +nouveau_device_get_param(struct nouveau_device *dev, + uint64_t param, uint64_t *value) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_getparam g; + int ret; + + if (!nvdev || !value) + return -EINVAL; + + g.param = param; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GETPARAM, + &g, sizeof(g)); + if (ret) + return ret; + + *value = g.value; + return 0; +} + +int +nouveau_device_set_param(struct nouveau_device *dev, + uint64_t param, uint64_t value) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct drm_nouveau_setparam s; + int ret; + + if (!nvdev) + return -EINVAL; + + s.param = param; + s.value = value; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_SETPARAM, + &s, sizeof(s)); + if (ret) + return ret; + + return 0; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_dma.c b/src/gallium/winsys/dri/nouveau/nouveau_dma.c new file mode 100644 index 00000000000..f8a8ba04f6d --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_dma.c @@ -0,0 +1,219 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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 <stdint.h> +#include <assert.h> +#include <errno.h> + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static inline uint32_t +READ_GET(struct nouveau_channel_priv *nvchan) +{ + return *nvchan->get; +} + +static inline void +WRITE_PUT(struct nouveau_channel_priv *nvchan, uint32_t val) +{ + uint32_t put = ((val << 2) + nvchan->dma->base); + volatile int dum; + + NOUVEAU_DMA_BARRIER; + dum = READ_GET(nvchan); + + *nvchan->put = put; + nvchan->dma->put = val; +#ifdef NOUVEAU_DMA_TRACE + NOUVEAU_MSG("WRITE_PUT %d/0x%08x\n", nvchan->drm.channel, put); +#endif + + NOUVEAU_DMA_BARRIER; +} + +static inline int +LOCAL_GET(struct nouveau_dma_priv *dma, uint32_t *val) +{ + uint32_t get = *val; + + if (get >= dma->base && get <= (dma->base + (dma->max << 2))) { + *val = (get - dma->base) >> 2; + return 1; + } + + return 0; +} + +void +nouveau_dma_channel_init(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + int i; + + nvchan->dma = &nvchan->dma_master; + nvchan->dma->base = nvchan->drm.put_base; + nvchan->dma->cur = nvchan->dma->put = 0; + nvchan->dma->max = (nvchan->drm.cmdbuf_size >> 2) - 2; + nvchan->dma->free = nvchan->dma->max - nvchan->dma->cur; + + RING_SPACE_CH(chan, RING_SKIPS); + for (i = 0; i < RING_SKIPS; i++) + OUT_RING_CH(chan, 0); +} + +#define CHECK_TIMEOUT() do { \ + if ((NOUVEAU_TIME_MSEC() - t_start) > NOUVEAU_DMA_TIMEOUT) \ + return - EBUSY; \ +} while(0) + +int +nouveau_dma_wait(struct nouveau_channel *chan, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + uint32_t get, t_start; + + FIRE_RING_CH(chan); + + t_start = NOUVEAU_TIME_MSEC(); + while (dma->free < size) { + CHECK_TIMEOUT(); + + get = READ_GET(nvchan); + if (!LOCAL_GET(dma, &get)) + continue; + + if (dma->put >= get) { + dma->free = dma->max - dma->cur; + + if (dma->free < size) { +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free = 1; +#endif + OUT_RING_CH(chan, 0x20000000 | dma->base); + if (get <= RING_SKIPS) { + /*corner case - will be idle*/ + if (dma->put <= RING_SKIPS) + WRITE_PUT(nvchan, + RING_SKIPS + 1); + + do { + CHECK_TIMEOUT(); + get = READ_GET(nvchan); + if (!LOCAL_GET(dma, &get)) + get = 0; + } while (get <= RING_SKIPS); + } + + WRITE_PUT(nvchan, RING_SKIPS); + dma->cur = dma->put = RING_SKIPS; + dma->free = get - (RING_SKIPS + 1); + } + } else { + dma->free = get - dma->cur - 1; + } + } + + return 0; +} + +#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF +static void +nouveau_dma_parse_pushbuf(struct nouveau_channel *chan, int get, int put) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + unsigned mthd_count = 0; + + while (get != put) { + uint32_t gpuget = (get << 2) + nvchan->drm.put_base; + uint32_t data; + + if (get < 0 || get >= nvchan->drm.cmdbuf_size) { + NOUVEAU_ERR("DMA_PT 0x%08x\n", gpuget); + assert(0); + } + data = nvchan->pushbuf[get++]; + + if (mthd_count) { + NOUVEAU_MSG("0x%08x 0x%08x\n", gpuget, data); + mthd_count--; + continue; + } + + switch (data & 0x60000000) { + case 0x00000000: + mthd_count = (data >> 18) & 0x7ff; + NOUVEAU_MSG("0x%08x 0x%08x MTHD " + "Sc %d Mthd 0x%04x Size %d\n", + gpuget, data, (data>>13) & 7, data & 0x1ffc, + mthd_count); + break; + case 0x20000000: + get = (data & 0x1ffffffc) >> 2; + NOUVEAU_MSG("0x%08x 0x%08x JUMP 0x%08x\n", + gpuget, data, data & 0x1ffffffc); + continue; + case 0x40000000: + mthd_count = (data >> 18) & 0x7ff; + NOUVEAU_MSG("0x%08x 0x%08x NINC " + "Sc %d Mthd 0x%04x Size %d\n", + gpuget, data, (data>>13) & 7, data & 0x1ffc, + mthd_count); + break; + case 0x60000000: + /* DMA_OPCODE_CALL apparently, doesn't seem to work on + * my NV40 at least.. + */ + /* fall-through */ + default: + NOUVEAU_MSG("DMA_PUSHER 0x%08x 0x%08x\n", + gpuget, data); + assert(0); + } + } +} +#endif + +void +nouveau_dma_kickoff(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + + if (dma->cur == dma->put) + return; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free) { + NOUVEAU_ERR("Packet incomplete: %d left\n", dma->push_free); + return; + } +#endif + +#ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF + nouveau_dma_parse_pushbuf(chan, dma->put, dma->cur); +#endif + + WRITE_PUT(nvchan, dma->cur); +} diff --git a/src/gallium/winsys/dri/nouveau/nouveau_dma.h b/src/gallium/winsys/dri/nouveau/nouveau_dma.h new file mode 100644 index 00000000000..cfa6d26e828 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_dma.h @@ -0,0 +1,143 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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. + */ + +#ifndef __NOUVEAU_DMA_H__ +#define __NOUVEAU_DMA_H__ + +#include <string.h> +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +#define RING_SKIPS 8 + +extern int nouveau_dma_wait(struct nouveau_channel *chan, int size); +extern void nouveau_dma_subc_bind(struct nouveau_grobj *); +extern void nouveau_dma_channel_init(struct nouveau_channel *); +extern void nouveau_dma_kickoff(struct nouveau_channel *); + +#ifdef NOUVEAU_DMA_DEBUG +static char faulty[1024]; +#endif + +static inline void +nouveau_dma_out(struct nouveau_channel *chan, uint32_t data) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free == 0) { + NOUVEAU_ERR("No space left in packet at %s\n", faulty); + return; + } + dma->push_free--; +#endif +#ifdef NOUVEAU_DMA_TRACE + { + uint32_t offset = (dma->cur << 2) + dma->base; + NOUVEAU_MSG("\tOUT_RING %d/0x%08x -> 0x%08x\n", + nvchan->drm.channel, offset, data); + } +#endif + nvchan->pushbuf[dma->cur + (dma->base - nvchan->drm.put_base)/4] = data; + dma->cur++; +} + +static inline void +nouveau_dma_outp(struct nouveau_channel *chan, uint32_t *ptr, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + (void)dma; + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free < size) { + NOUVEAU_ERR("Packet too small. Free=%d, Need=%d\n", + dma->push_free, size); + return; + } +#endif +#ifdef NOUVEAU_DMA_TRACE + while (size--) { + nouveau_dma_out(chan, *ptr); + ptr++; + } +#else + memcpy(&nvchan->pushbuf[dma->cur], ptr, size << 2); +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free -= size; +#endif + dma->cur += size; +#endif +} + +static inline void +nouveau_dma_space(struct nouveau_channel *chan, int size) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + + if (dma->free < size) { + if (nouveau_dma_wait(chan, size) && chan->hang_notify) + chan->hang_notify(chan); + } + dma->free -= size; +#ifdef NOUVEAU_DMA_DEBUG + dma->push_free = size; +#endif +} + +static inline void +nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj, + int method, int size, const char* file, int line) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *dma = nvchan->dma; + (void)dma; + +#ifdef NOUVEAU_DMA_TRACE + NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel, + grobj->handle, grobj->subc, method, size); +#endif + +#ifdef NOUVEAU_DMA_DEBUG + if (dma->push_free) { + NOUVEAU_ERR("Previous packet incomplete: %d left at %s\n", + dma->push_free, faulty); + return; + } + sprintf(faulty,"%s:%d",file,line); +#endif + + nouveau_dma_space(chan, (size + 1)); + nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method); +} + +#define RING_SPACE_CH(ch,sz) nouveau_dma_space((ch), (sz)) +#define BEGIN_RING_CH(ch,gr,m,sz) nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ ) +#define OUT_RING_CH(ch, data) nouveau_dma_out((ch), (data)) +#define OUT_RINGp_CH(ch,ptr,dwords) nouveau_dma_outp((ch), (void*)(ptr), \ + (dwords)) +#define FIRE_RING_CH(ch) nouveau_dma_kickoff((ch)) +#define WAIT_RING_CH(ch,sz) nouveau_dma_wait((ch), (sz)) + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_dri.h b/src/gallium/winsys/dri/nouveau/nouveau_dri.h new file mode 100644 index 00000000000..1207c2d609c --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_dri.h @@ -0,0 +1,28 @@ +#ifndef _NOUVEAU_DRI_ +#define _NOUVEAU_DRI_ + +#include "xf86drm.h" +#include "drm.h" +#include "nouveau_drm.h" + +struct nouveau_dri { + uint32_t device_id; /**< \brief PCI device ID */ + uint32_t width; /**< \brief width in pixels of display */ + uint32_t height; /**< \brief height in scanlines of display */ + uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */ + uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */ + + uint32_t bus_type; /**< \brief ths bus type */ + uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */ + + uint32_t front_offset; /**< \brief front buffer offset */ + uint32_t front_pitch; /**< \brief front buffer pitch */ + uint32_t back_offset; /**< \brief private back buffer offset */ + uint32_t back_pitch; /**< \brief private back buffer pitch */ + uint32_t depth_offset; /**< \brief private depth buffer offset */ + uint32_t depth_pitch; /**< \brief private depth buffer pitch */ + +}; + +#endif + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h new file mode 100644 index 00000000000..5829f649cd5 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -0,0 +1,309 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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. + */ + +#ifndef __NOUVEAU_DRMIF_H__ +#define __NOUVEAU_DRMIF_H__ + +#include <stdint.h> +#include <xf86drm.h> +#include <nouveau_drm.h> + +#include "nouveau/nouveau_device.h" +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_grobj.h" +#include "nouveau/nouveau_notifier.h" +#include "nouveau/nouveau_bo.h" +#include "nouveau/nouveau_resource.h" +#include "nouveau/nouveau_pushbuf.h" + +struct nouveau_device_priv { + struct nouveau_device base; + + int fd; + drm_context_t ctx; + drmLock *lock; + int needs_close; + + struct drm_nouveau_mem_alloc sa; + void *sa_map; + struct nouveau_resource *sa_heap; +}; +#define nouveau_device(n) ((struct nouveau_device_priv *)(n)) + +extern int +nouveau_device_open_existing(struct nouveau_device **, int close, + int fd, drm_context_t ctx); + +extern int +nouveau_device_open(struct nouveau_device **, const char *busid); + +extern void +nouveau_device_close(struct nouveau_device **); + +extern int +nouveau_device_get_param(struct nouveau_device *, uint64_t param, uint64_t *v); + +extern int +nouveau_device_set_param(struct nouveau_device *, uint64_t param, uint64_t val); + +struct nouveau_fence { + struct nouveau_channel *channel; +}; + +struct nouveau_fence_cb { + struct nouveau_fence_cb *next; + void (*func)(void *); + void *priv; +}; + +struct nouveau_fence_priv { + struct nouveau_fence base; + int refcount; + + struct nouveau_fence *next; + struct nouveau_fence_cb *signal_cb; + + uint32_t sequence; + int emitted; + int signalled; +}; +#define nouveau_fence(n) ((struct nouveau_fence_priv *)(n)) + +extern int +nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **); + +extern int +nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **); + +extern int +nouveau_fence_signal_cb(struct nouveau_fence *, void (*)(void *), void *); + +extern void +nouveau_fence_emit(struct nouveau_fence *); + +extern int +nouveau_fence_wait(struct nouveau_fence **); + +extern void +nouveau_fence_flush(struct nouveau_channel *); + +struct nouveau_pushbuf_reloc { + struct nouveau_pushbuf_bo *pbbo; + uint32_t *ptr; + uint32_t flags; + uint32_t data; + uint32_t vor; + uint32_t tor; +}; + +struct nouveau_pushbuf_bo { + struct nouveau_channel *channel; + struct nouveau_bo *bo; + unsigned flags; + unsigned handled; +}; + +#define NOUVEAU_PUSHBUF_MAX_BUFFERS 1024 +#define NOUVEAU_PUSHBUF_MAX_RELOCS 1024 +struct nouveau_pushbuf_priv { + struct nouveau_pushbuf base; + + struct nouveau_fence *fence; + + unsigned nop_jump; + unsigned start; + unsigned size; + + struct nouveau_pushbuf_bo *buffers; + unsigned nr_buffers; + struct nouveau_pushbuf_reloc *relocs; + unsigned nr_relocs; +}; +#define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) + +#define pbbo_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_pbbo(h) ((struct nouveau_pushbuf_bo *)(unsigned long)(h)) +#define pbrel_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_pbrel(h) ((struct nouveau_pushbuf_reloc *)(unsigned long)(h)) +#define bo_to_ptr(o) ((uint64_t)(unsigned long)(o)) +#define ptr_to_bo(h) ((struct nouveau_bo_priv *)(unsigned long)(h)) + +extern int +nouveau_pushbuf_init(struct nouveau_channel *); + +extern int +nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); + +extern int +nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, + struct nouveau_bo *, uint32_t data, uint32_t flags, + uint32_t vor, uint32_t tor); + +struct nouveau_dma_priv { + uint32_t base; + uint32_t max; + uint32_t cur; + uint32_t put; + uint32_t free; + + int push_free; +} dma; + +struct nouveau_channel_priv { + struct nouveau_channel base; + + struct drm_nouveau_channel_alloc drm; + + uint32_t *pushbuf; + void *notifier_block; + + volatile uint32_t *user; + volatile uint32_t *put; + volatile uint32_t *get; + volatile uint32_t *ref_cnt; + + struct nouveau_dma_priv dma_master; + struct nouveau_dma_priv dma_bufmgr; + struct nouveau_dma_priv *dma; + + struct nouveau_fence *fence_head; + struct nouveau_fence *fence_tail; + uint32_t fence_sequence; + + struct nouveau_pushbuf_priv pb; + + unsigned user_charge; +}; +#define nouveau_channel(n) ((struct nouveau_channel_priv *)(n)) + +extern int +nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt, + struct nouveau_channel **); + +extern void +nouveau_channel_free(struct nouveau_channel **); + +struct nouveau_grobj_priv { + struct nouveau_grobj base; +}; +#define nouveau_grobj(n) ((struct nouveau_grobj_priv *)(n)) + +extern int nouveau_grobj_alloc(struct nouveau_channel *, uint32_t handle, + int class, struct nouveau_grobj **); +extern int nouveau_grobj_ref(struct nouveau_channel *, uint32_t handle, + struct nouveau_grobj **); +extern void nouveau_grobj_free(struct nouveau_grobj **); + + +struct nouveau_notifier_priv { + struct nouveau_notifier base; + + struct drm_nouveau_notifierobj_alloc drm; + volatile void *map; +}; +#define nouveau_notifier(n) ((struct nouveau_notifier_priv *)(n)) + +extern int +nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, int count, + struct nouveau_notifier **); + +extern void +nouveau_notifier_free(struct nouveau_notifier **); + +extern void +nouveau_notifier_reset(struct nouveau_notifier *, int id); + +extern uint32_t +nouveau_notifier_status(struct nouveau_notifier *, int id); + +extern uint32_t +nouveau_notifier_return_val(struct nouveau_notifier *, int id); + +extern int +nouveau_notifier_wait_status(struct nouveau_notifier *, int id, int status, + int timeout); + +struct nouveau_bo_priv { + struct nouveau_bo base; + + struct nouveau_pushbuf_bo *pending; + struct nouveau_fence *fence; + struct nouveau_fence *wr_fence; + + struct drm_nouveau_mem_alloc drm; + void *map; + + void *sysmem; + int user; + + int refcount; + + uint64_t offset; + uint64_t flags; +}; +#define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) + +extern int +nouveau_bo_init(struct nouveau_device *); + +extern void +nouveau_bo_takedown(struct nouveau_device *); + +extern int +nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size, + struct nouveau_bo **); + +extern int +nouveau_bo_user(struct nouveau_device *, void *ptr, int size, + struct nouveau_bo **); + +extern int +nouveau_bo_ref(struct nouveau_device *, uint64_t handle, struct nouveau_bo **); + +extern int +nouveau_bo_set_status(struct nouveau_bo *, uint32_t flags); + +extern void +nouveau_bo_del(struct nouveau_bo **); + +extern int +nouveau_bo_map(struct nouveau_bo *, uint32_t flags); + +extern void +nouveau_bo_unmap(struct nouveau_bo *); + +extern int +nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, + uint32_t flags); + +extern int +nouveau_resource_init(struct nouveau_resource **heap, unsigned start, + unsigned size); + +extern int +nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, + struct nouveau_resource **); + +extern void +nouveau_resource_free(struct nouveau_resource **); + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_fence.c b/src/gallium/winsys/dri/nouveau/nouveau_fence.c new file mode 100644 index 00000000000..e7b0b4ff079 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_fence.c @@ -0,0 +1,214 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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 <stdlib.h> +#include <errno.h> +#include <assert.h> + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" +#include "nouveau_local.h" + +static void +nouveau_fence_del_unsignalled(struct nouveau_fence *fence) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); + struct nouveau_fence *le; + + if (nvchan->fence_head == fence) { + nvchan->fence_head = nouveau_fence(fence)->next; + if (nvchan->fence_head == NULL) + nvchan->fence_tail = NULL; + return; + } + + le = nvchan->fence_head; + while (le && nouveau_fence(le)->next != fence) + le = nouveau_fence(le)->next; + assert(le && nouveau_fence(le)->next == fence); + nouveau_fence(le)->next = nouveau_fence(fence)->next; + if (nvchan->fence_tail == fence) + nvchan->fence_tail = le; +} + +static void +nouveau_fence_del(struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence || !*fence) + return; + nvfence = nouveau_fence(*fence); + *fence = NULL; + + if (--nvfence->refcount) + return; + + if (nvfence->emitted && !nvfence->signalled) { + if (nvfence->signal_cb) { + nvfence->refcount++; + nouveau_fence_wait((void *)&nvfence); + return; + } + + nouveau_fence_del_unsignalled(&nvfence->base); + } + free(nvfence); +} + +int +nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!chan || !fence || *fence) + return -EINVAL; + + nvfence = calloc(1, sizeof(struct nouveau_fence_priv)); + if (!nvfence) + return -ENOMEM; + nvfence->base.channel = chan; + nvfence->refcount = 1; + + *fence = &nvfence->base; + return 0; +} + +int +nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence) + return -EINVAL; + + if (*fence) { + nouveau_fence_del(fence); + *fence = NULL; + } + + if (ref) { + nvfence = nouveau_fence(ref); + nvfence->refcount++; + *fence = &nvfence->base; + } + + return 0; +} + +int +nouveau_fence_signal_cb(struct nouveau_fence *fence, void (*func)(void *), + void *priv) +{ + struct nouveau_fence_priv *nvfence = nouveau_fence(fence); + struct nouveau_fence_cb *cb; + + if (!nvfence || !func) + return -EINVAL; + + cb = malloc(sizeof(struct nouveau_fence_cb)); + if (!cb) + return -ENOMEM; + + cb->func = func; + cb->priv = priv; + cb->next = nvfence->signal_cb; + nvfence->signal_cb = cb; + return 0; +} + +void +nouveau_fence_emit(struct nouveau_fence *fence) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); + struct nouveau_fence_priv *nvfence = nouveau_fence(fence); + + nvfence->emitted = 1; + nvfence->sequence = ++nvchan->fence_sequence; + if (nvfence->sequence == 0xffffffff) + NOUVEAU_ERR("AII wrap unhandled\n"); + + /*XXX: assumes subc 0 is populated */ + RING_SPACE_CH(fence->channel, 2); + OUT_RING_CH (fence->channel, 0x00040050); + OUT_RING_CH (fence->channel, nvfence->sequence); + + if (nvchan->fence_tail) { + nouveau_fence(nvchan->fence_tail)->next = fence; + } else { + nvchan->fence_head = fence; + } + nvchan->fence_tail = fence; +} + +void +nouveau_fence_flush(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + uint32_t sequence = *nvchan->ref_cnt; + + while (nvchan->fence_head) { + struct nouveau_fence_priv *nvfence; + + nvfence = nouveau_fence(nvchan->fence_head); + if (nvfence->sequence > sequence) + break; + nouveau_fence_del_unsignalled(&nvfence->base); + nvfence->signalled = 1; + + if (nvfence->signal_cb) { + struct nouveau_fence *fence = NULL; + + nouveau_fence_ref(&nvfence->base, &fence); + + while (nvfence->signal_cb) { + struct nouveau_fence_cb *cb; + + cb = nvfence->signal_cb; + nvfence->signal_cb = cb->next; + cb->func(cb->priv); + free(cb); + } + + nouveau_fence_ref(NULL, &fence); + } + } +} + +int +nouveau_fence_wait(struct nouveau_fence **fence) +{ + struct nouveau_fence_priv *nvfence; + + if (!fence || !*fence) + return -EINVAL; + nvfence = nouveau_fence(*fence); + + if (nvfence->emitted) { + while (!nvfence->signalled) + nouveau_fence_flush(nvfence->base.channel); + } + nouveau_fence_ref(NULL, fence); + + return 0; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_grobj.c b/src/gallium/winsys/dri/nouveau/nouveau_grobj.c new file mode 100644 index 00000000000..51523897d58 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_grobj.c @@ -0,0 +1,107 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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 <stdlib.h> +#include <errno.h> + +#include "nouveau_drmif.h" + +int +nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle, + int class, struct nouveau_grobj **grobj) +{ + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_grobj_priv *nvgrobj; + struct drm_nouveau_grobj_alloc g; + int ret; + + if (!nvdev || !grobj || *grobj) + return -EINVAL; + + nvgrobj = calloc(1, sizeof(*nvgrobj)); + if (!nvgrobj) + return -ENOMEM; + nvgrobj->base.channel = chan; + nvgrobj->base.handle = handle; + nvgrobj->base.grclass = class; + + g.channel = chan->id; + g.handle = handle; + g.class = class; + ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC, + &g, sizeof(g)); + if (ret) { + nouveau_grobj_free((void *)&nvgrobj); + return ret; + } + + *grobj = &nvgrobj->base; + return 0; +} + +int +nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle, + struct nouveau_grobj **grobj) +{ + struct nouveau_grobj_priv *nvgrobj; + + if (!chan || !grobj || *grobj) + return -EINVAL; + + nvgrobj = calloc(1, sizeof(struct nouveau_grobj_priv)); + if (!nvgrobj) + return -ENOMEM; + nvgrobj->base.channel = chan; + nvgrobj->base.handle = handle; + nvgrobj->base.grclass = 0; + + *grobj = &nvgrobj->base; + return 0; +} + +void +nouveau_grobj_free(struct nouveau_grobj **grobj) +{ + struct nouveau_device_priv *nvdev; + struct nouveau_channel_priv *chan; + struct nouveau_grobj_priv *nvgrobj; + + if (!grobj || !*grobj) + return; + nvgrobj = nouveau_grobj(*grobj); + *grobj = NULL; + + + chan = nouveau_channel(nvgrobj->base.channel); + nvdev = nouveau_device(chan->base.device); + + if (nvgrobj->base.grclass) { + struct drm_nouveau_gpuobj_free f; + + f.channel = chan->drm.channel; + f.handle = nvgrobj->base.handle; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, + &f, sizeof(f)); + } + free(nvgrobj); +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_local.h b/src/gallium/winsys/dri/nouveau/nouveau_local.h new file mode 100644 index 00000000000..e878a408037 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_local.h @@ -0,0 +1,117 @@ +#ifndef __NOUVEAU_LOCAL_H__ +#define __NOUVEAU_LOCAL_H__ + +#include "pipe/p_compiler.h" +#include "nouveau_winsys_pipe.h" +#include <stdio.h> + +struct pipe_buffer; + +/* Debug output */ +#define NOUVEAU_MSG(fmt, args...) do { \ + fprintf(stdout, "nouveau: "fmt, ##args); \ + fflush(stdout); \ +} while(0) + +#define NOUVEAU_ERR(fmt, args...) do { \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); \ + fflush(stderr); \ +} while(0) + +#define NOUVEAU_TIME_MSEC() 0 + +/* User FIFO control */ +//#define NOUVEAU_DMA_TRACE +//#define NOUVEAU_DMA_DEBUG +//#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF +#define NOUVEAU_DMA_BARRIER +#define NOUVEAU_DMA_TIMEOUT 2000 + +/* Push buffer access macros */ +static INLINE void +OUT_RING(struct nouveau_channel *chan, unsigned data) +{ + *(chan->pushbuf->cur++) = (data); +} + +static INLINE void +OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size) +{ + memcpy(chan->pushbuf->cur, data, size * 4); + chan->pushbuf->cur += size; +} + +static INLINE void +OUT_RINGf(struct nouveau_channel *chan, float f) +{ + union { uint32_t i; float f; } c; + c.f = f; + OUT_RING(chan, c.i); +} + +static INLINE void +BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, + unsigned mthd, unsigned size) +{ + if (chan->pushbuf->remaining < (size + 1)) + nouveau_pushbuf_flush(chan, (size + 1)); + OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd); + chan->pushbuf->remaining -= (size + 1); +} + +static INLINE void +FIRE_RING(struct nouveau_channel *chan) +{ + nouveau_pushbuf_flush(chan, 0); +} + +static INLINE void +BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) +{ + gr->subc = subc; + BEGIN_RING(chan, gr, 0x0000, 1); + OUT_RING (chan, gr->handle); +} + +static INLINE void +OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, + data, flags, vor, tor); +} + +/* Raw data + flags depending on FB/TT buffer */ +static INLINE void +OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); +} + +/* FB/TT object handle */ +static INLINE void +OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned flags) +{ + OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, + chan->vram->handle, chan->gart->handle); +} + +/* Low 32-bits of offset */ +static INLINE void +OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); +} + +/* High 32-bits of offset */ +static INLINE void +OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); +} + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_lock.c b/src/gallium/winsys/dri/nouveau/nouveau_lock.c new file mode 100644 index 00000000000..9adb9ac8547 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_lock.c @@ -0,0 +1,94 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#include "main/glheader.h" +#include "glapi/glthread.h" +#include <GL/internal/glcore.h> + +#include "nouveau_context.h" +#include "nouveau_screen.h" + +_glthread_DECLARE_STATIC_MUTEX( lockMutex ); + +static void +nouveau_contended_lock(struct nouveau_context *nv, GLuint flags) +{ + __DRIdrawablePrivate *dPriv = nv->dri_drawable; + __DRIscreenPrivate *sPriv = nv->dri_screen; + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + drmGetLock(nvdev->fd, nvdev->ctx, flags); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + if (dPriv) + DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); +} + +/* Lock the hardware and validate our state. + */ +void +LOCK_HARDWARE(struct nouveau_context *nv) +{ + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + char __ret=0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!nv->locked); + + DRM_CAS(nvdev->lock, nvdev->ctx, + (DRM_LOCK_HELD | nvdev->ctx), __ret); + + if (__ret) + nouveau_contended_lock(nv, 0); + nv->locked = GL_TRUE; +} + + + /* Unlock the hardware using the global current context + */ +void +UNLOCK_HARDWARE(struct nouveau_context *nv) +{ + struct nouveau_screen *nv_screen = nv->nv_screen; + struct nouveau_device *dev = nv_screen->device; + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + assert(nv->locked); + nv->locked = GL_FALSE; + + DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); + + _glthread_UNLOCK_MUTEX(lockMutex); +} diff --git a/src/gallium/winsys/dri/nouveau/nouveau_notifier.c b/src/gallium/winsys/dri/nouveau/nouveau_notifier.c new file mode 100644 index 00000000000..01e8f38440e --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_notifier.c @@ -0,0 +1,137 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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 <stdlib.h> +#include <errno.h> + +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +#define NOTIFIER(__v) \ + struct nouveau_notifier_priv *nvnotify = nouveau_notifier(notifier); \ + volatile uint32_t *__v = (void*)nvnotify->map + (id * 32) + +int +nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, + int count, struct nouveau_notifier **notifier) +{ + struct nouveau_notifier_priv *nvnotify; + int ret; + + if (!chan || !notifier || *notifier) + return -EINVAL; + + nvnotify = calloc(1, sizeof(struct nouveau_notifier_priv)); + if (!nvnotify) + return -ENOMEM; + nvnotify->base.channel = chan; + nvnotify->base.handle = handle; + + nvnotify->drm.channel = chan->id; + nvnotify->drm.handle = handle; + nvnotify->drm.count = count; + if ((ret = drmCommandWriteRead(nouveau_device(chan->device)->fd, + DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, + &nvnotify->drm, + sizeof(nvnotify->drm)))) { + nouveau_notifier_free((void *)&nvnotify); + return ret; + } + + nvnotify->map = (void *)nouveau_channel(chan)->notifier_block + + nvnotify->drm.offset; + *notifier = &nvnotify->base; + return 0; +} + +void +nouveau_notifier_free(struct nouveau_notifier **notifier) +{ + + struct nouveau_notifier_priv *nvnotify; + struct nouveau_channel_priv *nvchan; + struct nouveau_device_priv *nvdev; + struct drm_nouveau_gpuobj_free f; + + if (!notifier || !*notifier) + return; + nvnotify = nouveau_notifier(*notifier); + *notifier = NULL; + + nvchan = nouveau_channel(nvnotify->base.channel); + nvdev = nouveau_device(nvchan->base.device); + + f.channel = nvchan->drm.channel; + f.handle = nvnotify->base.handle; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f)); + free(nvnotify); +} + +void +nouveau_notifier_reset(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + n[NV_NOTIFY_TIME_0 /4] = 0x00000000; + n[NV_NOTIFY_TIME_1 /4] = 0x00000000; + n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; + n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS << + NV_NOTIFY_STATE_STATUS_SHIFT); +} + +uint32_t +nouveau_notifier_status(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; +} + +uint32_t +nouveau_notifier_return_val(struct nouveau_notifier *notifier, int id) +{ + NOTIFIER(n); + + return n[NV_NOTIFY_RETURN_VALUE/4]; +} + +int +nouveau_notifier_wait_status(struct nouveau_notifier *notifier, int id, + int status, int timeout) +{ + NOTIFIER(n); + uint32_t time = 0, t_start = NOUVEAU_TIME_MSEC(); + + while (time <= timeout) { + uint32_t v; + + v = n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; + if (v == status) + return 0; + + if (timeout) + time = NOUVEAU_TIME_MSEC() - t_start; + } + + return -EBUSY; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c new file mode 100644 index 00000000000..815046ba85f --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -0,0 +1,271 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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 <stdlib.h> +#include <errno.h> +#include <assert.h> + +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +#define PB_BUFMGR_DWORDS (4096 / 2) +#define PB_MIN_USER_DWORDS 2048 + +static int +nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; + + assert((min + 1) <= nvchan->dma->max); + + /* Wait for enough space in push buffer */ + min = min < PB_MIN_USER_DWORDS ? PB_MIN_USER_DWORDS : min; + min += 1; /* a bit extra for the NOP */ + if (nvchan->dma->free < min) + WAIT_RING_CH(chan, min); + + /* Insert NOP, may turn into a jump later */ + RING_SPACE_CH(chan, 1); + nvpb->nop_jump = nvchan->dma->cur; + OUT_RING_CH(chan, 0); + + /* Any remaining space is available to the user */ + nvpb->start = nvchan->dma->cur; + nvpb->size = nvchan->dma->free; + nvpb->base.channel = chan; + nvpb->base.remaining = nvpb->size; + nvpb->base.cur = &nvchan->pushbuf[nvpb->start]; + + /* Create a new fence object for this "frame" */ + nouveau_fence_ref(NULL, &nvpb->fence); + nouveau_fence_new(chan, &nvpb->fence); + + return 0; +} + +int +nouveau_pushbuf_init(struct nouveau_channel *chan) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_dma_priv *m = &nvchan->dma_master; + struct nouveau_dma_priv *b = &nvchan->dma_bufmgr; + int i; + + if (!nvchan) + return -EINVAL; + + /* Reassign last bit of push buffer for a "separate" bufmgr + * ring buffer + */ + m->max -= PB_BUFMGR_DWORDS; + m->free -= PB_BUFMGR_DWORDS; + + b->base = m->base + ((m->max + 2) << 2); + b->max = PB_BUFMGR_DWORDS - 2; + b->cur = b->put = 0; + b->free = b->max - b->cur; + + /* Some NOPs just to be safe + *XXX: RING_SKIPS + */ + nvchan->dma = b; + RING_SPACE_CH(chan, 8); + for (i = 0; i < 8; i++) + OUT_RING_CH(chan, 0); + nvchan->dma = m; + + nouveau_pushbuf_space(chan, 0); + chan->pushbuf = &nvchan->pb.base; + + nvchan->pb.buffers = calloc(NOUVEAU_PUSHBUF_MAX_BUFFERS, + sizeof(struct nouveau_pushbuf_bo)); + nvchan->pb.relocs = calloc(NOUVEAU_PUSHBUF_MAX_RELOCS, + sizeof(struct nouveau_pushbuf_reloc)); + return 0; +} + +static uint32_t +nouveau_pushbuf_calc_reloc(struct nouveau_bo *bo, + struct nouveau_pushbuf_reloc *r) +{ + uint32_t push; + + if (r->flags & NOUVEAU_BO_LOW) { + push = bo->offset + r->data; + } else + if (r->flags & NOUVEAU_BO_HIGH) { + push = (bo->offset + r->data) >> 32; + } else { + push = r->data; + } + + if (r->flags & NOUVEAU_BO_OR) { + if (bo->flags & NOUVEAU_BO_VRAM) + push |= r->vor; + else + push |= r->tor; + } + + return push; +} + +/* This would be our TTM "superioctl" */ +int +nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) +{ + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; + int ret, i; + + if (nvpb->base.remaining == nvpb->size) + return 0; + + nouveau_fence_flush(chan); + + nvpb->size -= nvpb->base.remaining; + nvchan->dma->cur += nvpb->size; + nvchan->dma->free -= nvpb->size; + assert(nvchan->dma->cur <= nvchan->dma->max); + + nvchan->dma = &nvchan->dma_bufmgr; + nvchan->pushbuf[nvpb->nop_jump] = 0x20000000 | + (nvchan->dma->base + (nvchan->dma->cur << 2)); + + /* Validate buffers + apply relocations */ + nvchan->user_charge = 0; + for (i = 0; i < nvpb->nr_relocs; i++) { + struct nouveau_pushbuf_reloc *r = &nvpb->relocs[i]; + struct nouveau_pushbuf_bo *pbbo = r->pbbo; + struct nouveau_bo *bo = pbbo->bo; + + /* Validated, mem matches presumed, no relocation necessary */ + if (pbbo->handled & 2) { + if (!(pbbo->handled & 1)) + assert(0); + continue; + } + + /* Not yet validated, do it now */ + if (!(pbbo->handled & 1)) { + ret = nouveau_bo_validate(chan, bo, pbbo->flags); + if (ret) { + assert(0); + return ret; + } + pbbo->handled |= 1; + + if (bo->offset == nouveau_bo(bo)->offset && + bo->flags == nouveau_bo(bo)->flags) { + pbbo->handled |= 2; + continue; + } + bo->offset = nouveau_bo(bo)->offset; + bo->flags = nouveau_bo(bo)->flags; + } + + /* Apply the relocation */ + *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); + } + nvpb->nr_relocs = 0; + + /* Dereference all buffers on validate list */ + for (i = 0; i < nvpb->nr_buffers; i++) { + struct nouveau_pushbuf_bo *pbbo = &nvpb->buffers[i]; + + nouveau_bo(pbbo->bo)->pending = NULL; + nouveau_bo_del(&pbbo->bo); + } + nvpb->nr_buffers = 0; + + /* Switch back to user's ring */ + RING_SPACE_CH(chan, 1); + OUT_RING_CH(chan, 0x20000000 | ((nvpb->start << 2) + + nvchan->dma_master.base)); + nvchan->dma = &nvchan->dma_master; + + /* Fence + kickoff */ + nouveau_fence_emit(nvpb->fence); + FIRE_RING_CH(chan); + + /* Allocate space for next push buffer */ + ret = nouveau_pushbuf_space(chan, min); + assert(!ret); + + return 0; +} + +static struct nouveau_pushbuf_bo * +nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) +{ + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_pushbuf_bo *pbbo; + + if (nvbo->pending) + return nvbo->pending; + + if (nvpb->nr_buffers >= NOUVEAU_PUSHBUF_MAX_BUFFERS) + return NULL; + pbbo = nvpb->buffers + nvpb->nr_buffers++; + nvbo->pending = pbbo; + + nouveau_bo_ref(bo->device, bo->handle, &pbbo->bo); + pbbo->channel = chan; + pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + pbbo->handled = 0; + return pbbo; +} + +int +nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, + struct nouveau_bo *bo, uint32_t data, uint32_t flags, + uint32_t vor, uint32_t tor) +{ + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); + struct nouveau_pushbuf_bo *pbbo; + struct nouveau_pushbuf_reloc *r; + + if (nvpb->nr_relocs >= NOUVEAU_PUSHBUF_MAX_RELOCS) + return -ENOMEM; + + pbbo = nouveau_pushbuf_emit_buffer(chan, bo); + if (!pbbo) + return -ENOMEM; + pbbo->flags |= (flags & NOUVEAU_BO_RDWR); + pbbo->flags &= (flags | NOUVEAU_BO_RDWR); + + r = nvpb->relocs + nvpb->nr_relocs++; + r->pbbo = pbbo; + r->ptr = ptr; + r->flags = flags; + r->data = data; + r->vor = vor; + r->tor = tor; + + if (flags & NOUVEAU_BO_DUMMY) + *(uint32_t *)ptr = 0; + else + *(uint32_t *)ptr = nouveau_pushbuf_calc_reloc(bo, r); + return 0; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_resource.c b/src/gallium/winsys/dri/nouveau/nouveau_resource.c new file mode 100644 index 00000000000..3bbcb5c45e0 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_resource.c @@ -0,0 +1,116 @@ +/* + * Copyright 2007 Nouveau Project + * + * 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 <stdlib.h> +#include <errno.h> + +#include "nouveau_drmif.h" +#include "nouveau_local.h" + +int +nouveau_resource_init(struct nouveau_resource **heap, + unsigned start, unsigned size) +{ + struct nouveau_resource *r; + + r = calloc(1, sizeof(struct nouveau_resource)); + if (!r) + return 1; + + r->start = start; + r->size = size; + *heap = r; + return 0; +} + +int +nouveau_resource_alloc(struct nouveau_resource *heap, int size, void *priv, + struct nouveau_resource **res) +{ + struct nouveau_resource *r; + + if (!heap || !size || !res || *res) + return 1; + + while (heap) { + if (!heap->in_use && heap->size >= size) { + r = calloc(1, sizeof(struct nouveau_resource)); + if (!r) + return 1; + + r->start = (heap->start + heap->size) - size; + r->size = size; + r->in_use = 1; + r->priv = priv; + + heap->size -= size; + + r->next = heap->next; + if (heap->next) + heap->next->prev = r; + r->prev = heap; + heap->next = r; + + *res = r; + return 0; + } + + heap = heap->next; + } + + return 1; +} + +void +nouveau_resource_free(struct nouveau_resource **res) +{ + struct nouveau_resource *r; + + if (!res || !*res) + return; + r = *res; + *res = NULL; + + r->in_use = 0; + + if (r->next && !r->next->in_use) { + struct nouveau_resource *new = r->next; + + new->prev = r->prev; + if (r->prev) + r->prev->next = new; + new->size += r->size; + new->start = r->start; + + free(r); + r = new; + } + + if (r->prev && !r->prev->in_use) { + r->prev->next = r->next; + if (r->next) + r->next->prev = r->prev; + r->prev->size += r->size; + free(r); + } + +} diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c new file mode 100644 index 00000000000..9041275a88f --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -0,0 +1,307 @@ +#include "utils.h" +#include "vblank.h" +#include "xmlpool.h" + +#include "pipe/p_context.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_cb_fbo.h" + +#include "nouveau_context.h" +#include "nouveau_drm.h" +#include "nouveau_dri.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 +#error nouveau_drm.h version does not match expected version +#endif + +/* Extension stuff, enabling of extensions handled by Gallium's GL state + * tracker. But, we still need to define the entry points we want. + */ +#define need_GL_ARB_fragment_program +#define need_GL_ARB_multisample +#define need_GL_ARB_occlusion_query +#define need_GL_ARB_point_parameters +#define need_GL_ARB_shader_objects +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_program +#define need_GL_ARB_vertex_shader +#define need_GL_ARB_vertex_buffer_object +#define need_GL_EXT_compiled_vertex_array +#define need_GL_EXT_fog_coord +#define need_GL_EXT_secondary_color +#define need_GL_EXT_framebuffer_object +#define need_GL_VERSION_2_0 +#define need_GL_VERSION_2_1 +#include "extension_helper.h" + +const struct dri_extension card_extensions[] = +{ + { "GL_ARB_multisample", GL_ARB_multisample_functions }, + { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions }, + { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, + { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions }, + { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions }, + { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions }, + { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, + { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, + { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions }, + { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, + { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions }, + { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, + { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, + { NULL, 0 } +}; + +PUBLIC const char __driConfigOptions[] = +DRI_CONF_BEGIN +DRI_CONF_END; +static const GLuint __driNConfigOptions = 0; + +extern const struct dri_extension common_extensions[]; +extern const struct dri_extension nv40_extensions[]; + +static GLboolean +nouveau_screen_create(__DRIscreenPrivate *driScrnPriv) +{ + struct nouveau_dri *nv_dri = driScrnPriv->pDevPriv; + struct nouveau_screen *nv_screen; + int ret; + + if (driScrnPriv->devPrivSize != sizeof(struct nouveau_dri)) { + NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n"); + return GL_FALSE; + } + + nv_screen = CALLOC_STRUCT(nouveau_screen); + if (!nv_screen) + return GL_FALSE; + nv_screen->driScrnPriv = driScrnPriv; + driScrnPriv->private = (void *)nv_screen; + + driParseOptionInfo(&nv_screen->option_cache, + __driConfigOptions, __driNConfigOptions); + + if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, + driScrnPriv->fd, 0))) { + NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret); + return GL_FALSE; + } + + nv_screen->front_offset = nv_dri->front_offset; + nv_screen->front_pitch = nv_dri->front_pitch * (nv_dri->bpp / 8); + nv_screen->front_cpp = nv_dri->bpp / 8; + nv_screen->front_height = nv_dri->height; + + return GL_TRUE; +} + +static void +nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv) +{ + struct nouveau_screen *nv_screen = driScrnPriv->private; + + driScrnPriv->private = NULL; + FREE(nv_screen); +} + +static GLboolean +nouveau_create_buffer(__DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + const __GLcontextModes *glVis, GLboolean pixmapBuffer) +{ + struct nouveau_framebuffer *nvfb; + enum pipe_format colour, depth, stencil; + + if (pixmapBuffer) + return GL_FALSE; + + nvfb = CALLOC_STRUCT(nouveau_framebuffer); + if (!nvfb) + return GL_FALSE; + + if (glVis->redBits == 5) + colour = PIPE_FORMAT_R5G6B5_UNORM; + else + colour = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (glVis->depthBits == 16) + depth = PIPE_FORMAT_Z16_UNORM; + else if (glVis->depthBits == 24) + depth = PIPE_FORMAT_Z24S8_UNORM; + else + depth = PIPE_FORMAT_NONE; + + if (glVis->stencilBits == 8) + stencil = PIPE_FORMAT_Z24S8_UNORM; + else + stencil = PIPE_FORMAT_NONE; + + nvfb->stfb = st_create_framebuffer(glVis, colour, depth, stencil, + driDrawPriv->w, driDrawPriv->h, + (void*)nvfb); + if (!nvfb->stfb) { + free(nvfb); + return GL_FALSE; + } + + driDrawPriv->driverPrivate = (void *)nvfb; + return GL_TRUE; +} + +static void +nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv) +{ + struct nouveau_framebuffer *nvfb; + + nvfb = (struct nouveau_framebuffer *)driDrawPriv->driverPrivate; + st_unreference_framebuffer(&nvfb->stfb); + free(nvfb); +} + +static struct __DriverAPIRec +nouveau_api = { + .InitDriver = nouveau_screen_create, + .DestroyScreen = nouveau_screen_destroy, + .CreateContext = nouveau_context_create, + .DestroyContext = nouveau_context_destroy, + .CreateBuffer = nouveau_create_buffer, + .DestroyBuffer = nouveau_destroy_buffer, + .SwapBuffers = nouveau_swap_buffers, + .MakeCurrent = nouveau_context_bind, + .UnbindContext = nouveau_context_unbind, + .GetSwapInfo = NULL, + .GetMSC = NULL, + .WaitForMSC = NULL, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = nouveau_copy_sub_buffer, + .setTexOffset = NULL +}; + +static __GLcontextModes * +nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) +{ + __GLcontextModes * modes; + __GLcontextModes * m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + int i; + + static const struct { + GLenum format; + GLenum type; + } fb_format_array[] = { + { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, + { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV }, + }; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[4] = { 0, 16, 24, 24 }; + u_int8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; + + depth_buffer_factor = 4; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = ((pixel_bits==16) ? 1 : 2) * + depth_buffer_factor * back_buffer_factor * 4; + modes = (*dri_interface->createContextModes)(num_modes, + sizeof(__GLcontextModes)); + m = modes; + + for (i=((pixel_bits==16)?0:1);i<((pixel_bits==16)?1:3);i++) { + if (!driFillInModes(&m, fb_format_array[i].format, + fb_format_array[i].type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + GLX_TRUE_COLOR)) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + + if (!driFillInModes(&m, fb_format_array[i].format, + fb_format_array[i].type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + GLX_DIRECT_COLOR)) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + } + + return modes; +} +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay *dpy, int scrn, + __DRIscreen *psc, const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + void * pSAREA, int fd, int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = + { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = + { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; + struct nouveau_dri *nv_dri = NULL; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("nouveau", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + if (drm_expected.patch != drm_version->patch) { + fprintf(stderr, "Incompatible DRM patch level.\n" + "Expected: %d\n" "Current : %d\n", + drm_expected.patch, drm_version->patch); + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, + &nouveau_api); + if (psp == NULL) + return NULL; + nv_dri = psp->pDevPriv; + + *driver_modes = nouveau_fill_in_modes(nv_dri->bpp, + (nv_dri->bpp == 16) ? 16 : 24, + (nv_dri->bpp == 16) ? 0 : 8, + 1); + + driInitExtensions(NULL, card_extensions, GL_FALSE); + + return (void *)psp; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.h b/src/gallium/winsys/dri/nouveau/nouveau_screen.h new file mode 100644 index 00000000000..388d6be9bbc --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.h @@ -0,0 +1,20 @@ +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +#include "xmlconfig.h" + +struct nouveau_screen { + __DRIscreenPrivate *driScrnPriv; + driOptionCache option_cache; + + struct nouveau_device *device; + + uint32_t front_offset; + uint32_t front_pitch; + uint32_t front_cpp; + uint32_t front_height; + + void *nvc; +}; + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c new file mode 100644 index 00000000000..70e0104e83b --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c @@ -0,0 +1,86 @@ +#include "main/glheader.h" +#include "glapi/glthread.h" +#include <GL/internal/glcore.h> + +#include "pipe/p_context.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_fbo.h" + +#include "nouveau_context.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +void +nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate; + drm_clip_rect_t *pbox; + int nbox, i; + + LOCK_HARDWARE(nv); + if (!dPriv->numClipRects) { + UNLOCK_HARDWARE(nv); + return; + } + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + + nv->surface_copy_prep(nv, nv->frontbuffer, surf); + for (i = 0; i < nbox; i++, pbox++) { + int sx, sy, dx, dy, w, h; + + sx = pbox->x1 - dPriv->x; + sy = pbox->y1 - dPriv->y; + dx = pbox->x1; + dy = pbox->y1; + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + + nv->surface_copy(nv, dx, dy, sx, sy, w, h); + } + + FIRE_RING(nv->nvc->channel); + UNLOCK_HARDWARE(nv); + + if (nv->last_stamp != dPriv->lastStamp) { + struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; + st_resize_framebuffer(nvfb->stfb, dPriv->w, dPriv->h); + nv->last_stamp = dPriv->lastStamp; + } +} + +void +nouveau_copy_sub_buffer(__DRIdrawablePrivate *dPriv, int x, int y, int w, int h) +{ + struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; + struct pipe_surface *surf; + + surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); + if (surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = x + w; + rect.y2 = y + h; + + st_notify_swapbuffers(nvfb->stfb); + nouveau_copy_buffer(dPriv, surf, &rect); + } +} + +void +nouveau_swap_buffers(__DRIdrawablePrivate *dPriv) +{ + struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; + struct pipe_surface *surf; + + surf = st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT); + if (surf) { + st_notify_swapbuffers(nvfb->stfb); + nouveau_copy_buffer(dPriv, surf, NULL); + } +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h new file mode 100644 index 00000000000..825d3da6da5 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h @@ -0,0 +1,10 @@ +#ifndef __NOUVEAU_SWAPBUFFERS_H__ +#define __NOUVEAU_SWAPBUFFERS_H__ + +extern void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *, + const drm_clip_rect_t *); +extern void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, + int x, int y, int w, int h); +extern void nouveau_swap_buffers(__DRIdrawablePrivate *); + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c new file mode 100644 index 00000000000..5eabbc88939 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -0,0 +1,158 @@ +#include "pipe/p_util.h" + +#include "nouveau_context.h" +#include "nouveau_screen.h" +#include "nouveau_winsys_pipe.h" + +#include "nouveau/nouveau_winsys.h" + +static int +nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, + struct nouveau_notifier **notify) +{ + struct nouveau_context *nv = nvws->nv; + + return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++, + count, notify); +} + +static int +nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass, + struct nouveau_grobj **grobj) +{ + struct nouveau_context *nv = nvws->nv; + struct nouveau_channel *chan = nv->nvc->channel; + int ret; + + ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++, + grclass, grobj); + if (ret) + return ret; + + assert(nv->nvc->next_subchannel < 7); + BIND_RING(chan, *grobj, nv->nvc->next_subchannel++); + return 0; +} + +static int +nouveau_pipe_surface_copy(struct nouveau_winsys *nvws, struct pipe_surface *dst, + unsigned dx, unsigned dy, struct pipe_surface *src, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_context *nv = nvws->nv; + + if (nv->surface_copy_prep(nv, dst, src)) + return 1; + nv->surface_copy(nv, dx, dy, sx, sy, w, h); + nv->surface_copy_done(nv); + + return 0; +} + +static int +nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + if (nvws->nv->surface_fill(nvws->nv, dst, dx, dy, w, h, value)) + return 1; + return 0; +} + +static int +nouveau_pipe_push_reloc(struct nouveau_winsys *nvws, void *ptr, + struct pipe_buffer *buf, uint32_t data, + uint32_t flags, uint32_t vor, uint32_t tor) +{ + return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, + nouveau_buffer(buf)->bo, + data, flags, vor, tor); +} + +static int +nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size, + struct pipe_fence_handle **fence) +{ + if (fence) { + struct nouveau_pushbuf *pb = nvws->channel->pushbuf; + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(pb); + struct nouveau_fence *ref = NULL; + + nouveau_fence_ref(nvpb->fence, &ref); + *fence = (struct pipe_fence_handle *)ref; + } + + return nouveau_pushbuf_flush(nvws->channel, size); +} + +struct pipe_context * +nouveau_pipe_create(struct nouveau_context *nv) +{ + struct nouveau_channel_context *nvc = nv->nvc; + struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); + struct pipe_screen *(*hws_create)(struct pipe_winsys *, + struct nouveau_winsys *); + struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); + struct pipe_winsys *ws; + unsigned chipset = nv->nv_screen->device->chipset; + + if (!nvws) + return NULL; + + switch (chipset & 0xf0) { + case 0x10: + case 0x20: + hws_create = nv10_screen_create; + hw_create = nv10_create; + break; + case 0x30: + hws_create = nv30_screen_create; + hw_create = nv30_create; + break; + case 0x40: + case 0x60: + hws_create = nv40_screen_create; + hw_create = nv40_create; + break; + case 0x50: + case 0x80: + case 0x90: + hws_create = nv50_screen_create; + hw_create = nv50_create; + break; + default: + NOUVEAU_ERR("Unknown chipset NV%02x\n", chipset); + return NULL; + } + + nvws->nv = nv; + nvws->channel = nv->nvc->channel; + + nvws->res_init = nouveau_resource_init; + nvws->res_alloc = nouveau_resource_alloc; + nvws->res_free = nouveau_resource_free; + + nvws->push_reloc = nouveau_pipe_push_reloc; + nvws->push_flush = nouveau_pipe_push_flush; + + nvws->grobj_alloc = nouveau_pipe_grobj_alloc; + nvws->grobj_free = nouveau_grobj_free; + + nvws->notifier_alloc = nouveau_pipe_notifier_alloc; + nvws->notifier_free = nouveau_notifier_free; + nvws->notifier_reset = nouveau_notifier_reset; + nvws->notifier_status = nouveau_notifier_status; + nvws->notifier_retval = nouveau_notifier_return_val; + nvws->notifier_wait = nouveau_notifier_wait_status; + + nvws->surface_copy = nouveau_pipe_surface_copy; + nvws->surface_fill = nouveau_pipe_surface_fill; + + ws = nouveau_create_pipe_winsys(nv); + + if (!nvc->pscreen) + nvc->pscreen = hws_create(ws, nvws); + nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); + return nvc->pctx[nv->pctx_id]; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c new file mode 100644 index 00000000000..ba5dd2eea4b --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -0,0 +1,223 @@ +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nouveau_context.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" +#include "nouveau_winsys_pipe.h" + +static void +nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, + void *context_private) +{ + struct nouveau_context *nv = context_private; + __DRIdrawablePrivate *dPriv = nv->dri_drawable; + + nouveau_copy_buffer(dPriv, surf, NULL); +} + +static const char * +nouveau_get_name(struct pipe_winsys *pws) +{ + return "Nouveau/DRI"; +} + +static struct pipe_surface * +nouveau_surface_alloc(struct pipe_winsys *ws) +{ + struct pipe_surface *surf; + + surf = CALLOC_STRUCT(pipe_surface); + if (!surf) + return NULL; + + surf->refcount = 1; + surf->winsys = ws; + return surf; +} + +static void +nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + + *s = NULL; + if (--surf->refcount <= 0) { + if (surf->buffer) + pipe_buffer_reference(ws, &surf->buffer, NULL); + free(surf); + } +} + +static struct pipe_buffer * +nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, + unsigned usage, unsigned size) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + uint32_t flags; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 1; + nvbuf->base.alignment = alignment; + nvbuf->base.usage = usage; + nvbuf->base.size = size; + + flags = NOUVEAU_BO_LOCAL; + + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) + flags |= NOUVEAU_BO_GART; + flags |= NOUVEAU_BO_VRAM; + } + + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + if (nv->cap.hw_vertex_buffer) + flags |= NOUVEAU_BO_GART; + } + + if (usage & PIPE_BUFFER_USAGE_INDEX) { + if (nv->cap.hw_index_buffer) + flags |= NOUVEAU_BO_GART; + } + + if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) { + free(nvbuf); + return NULL; + } + + return &nvbuf->base; +} + +static struct pipe_buffer * +nouveau_pipe_bo_user_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws; + struct nouveau_device *dev = nvpws->nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + + nvbuf = calloc(1, sizeof(*nvbuf)); + if (!nvbuf) + return NULL; + nvbuf->base.refcount = 1; + nvbuf->base.size = bytes; + + if (nouveau_bo_user(dev, ptr, bytes, &nvbuf->bo)) { + free(nvbuf); + return NULL; + } + + return &nvbuf->base; +} + +static void +nouveau_pipe_bo_del(struct pipe_winsys *ws, struct pipe_buffer *buf) +{ + struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + + nouveau_bo_del(&nvbuf->bo); + free(nvbuf); +} + +static void * +nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf, + unsigned flags) +{ + struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + uint32_t map_flags = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_READ) + map_flags |= NOUVEAU_BO_RD; + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + map_flags |= NOUVEAU_BO_WR; + + if (nouveau_bo_map(nvbuf->bo, map_flags)) + return NULL; + return nvbuf->bo->map; +} + +static void +nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct nouveau_pipe_buffer *nvbuf = nouveau_buffer(buf); + + nouveau_bo_unmap(nvbuf->bo); +} + +static INLINE struct nouveau_fence * +nouveau_pipe_fence(struct pipe_fence_handle *pfence) +{ + return (struct nouveau_fence *)pfence; +} + +static void +nouveau_pipe_fence_reference(struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *pfence) +{ + nouveau_fence_ref((void *)pfence, (void *)ptr); +} + +static int +nouveau_pipe_fence_signalled(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)ws; + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + + if (nouveau_fence(fence)->signalled == 0) + nouveau_fence_flush(nvpws->nv->nvc->channel); + + return !nouveau_fence(fence)->signalled; +} + +static int +nouveau_pipe_fence_finish(struct pipe_winsys *ws, + struct pipe_fence_handle *pfence, unsigned flag) +{ + struct nouveau_fence *fence = nouveau_pipe_fence(pfence); + struct nouveau_fence *ref = NULL; + + nouveau_fence_ref(fence, &ref); + return nouveau_fence_wait(&ref); +} + +struct pipe_winsys * +nouveau_create_pipe_winsys(struct nouveau_context *nv) +{ + struct nouveau_pipe_winsys *nvpws; + struct pipe_winsys *pws; + + nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); + if (!nvpws) + return NULL; + nvpws->nv = nv; + pws = &nvpws->pws; + + pws->flush_frontbuffer = nouveau_flush_frontbuffer; + + pws->surface_alloc = nouveau_surface_alloc; + pws->surface_release = nouveau_surface_release; + + pws->buffer_create = nouveau_pipe_bo_create; + pws->buffer_destroy = nouveau_pipe_bo_del; + pws->user_buffer_create = nouveau_pipe_bo_user_create; + pws->buffer_map = nouveau_pipe_bo_map; + pws->buffer_unmap = nouveau_pipe_bo_unmap; + + pws->fence_reference = nouveau_pipe_fence_reference; + pws->fence_signalled = nouveau_pipe_fence_signalled; + pws->fence_finish = nouveau_pipe_fence_finish; + + pws->get_name = nouveau_get_name; + + return &nvpws->pws; +} + diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h new file mode 100644 index 00000000000..6a03ac0d773 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h @@ -0,0 +1,34 @@ +#ifndef NOUVEAU_PIPE_WINSYS_H +#define NOUVEAU_PIPE_WINSYS_H + +#include "pipe/p_context.h" +#include "pipe/p_winsys.h" +#include "nouveau_context.h" + +struct nouveau_pipe_buffer { + struct pipe_buffer base; + struct nouveau_bo *bo; +}; + +static inline struct nouveau_pipe_buffer * +nouveau_buffer(struct pipe_buffer *buf) +{ + return (struct nouveau_pipe_buffer *)buf; +} + +struct nouveau_pipe_winsys { + struct pipe_winsys pws; + + struct nouveau_context *nv; +}; + +extern struct pipe_winsys * +nouveau_create_pipe_winsys(struct nouveau_context *nv); + +struct pipe_context * +nouveau_create_softpipe(struct nouveau_context *nv); + +struct pipe_context * +nouveau_pipe_create(struct nouveau_context *nv); + +#endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c new file mode 100644 index 00000000000..704f6c77506 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c @@ -0,0 +1,85 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com> + */ + +#include "imports.h" + +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "softpipe/sp_winsys.h" + +#include "nouveau_context.h" +#include "nouveau_winsys_pipe.h" + +struct nouveau_softpipe_winsys { + struct softpipe_winsys sws; + struct nouveau_context *nv; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean +nouveau_is_format_supported(struct softpipe_winsys *sws, uint format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + }; + + return FALSE; +} + +struct pipe_context * +nouveau_create_softpipe(struct nouveau_context *nv) +{ + struct nouveau_softpipe_winsys *nvsws; + struct pipe_screen *pscreen; + struct pipe_winsys *ws; + + ws = nouveau_create_pipe_winsys(nv); + if (!ws) + return NULL; + pscreen = softpipe_create_screen(ws); + + nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); + if (!nvsws) + return NULL; + + nvsws->sws.is_format_supported = nouveau_is_format_supported; + nvsws->nv = nv; + + return softpipe_create(pscreen, ws, &nvsws->sws); +} + diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c new file mode 100644 index 00000000000..83c790db17a --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -0,0 +1,303 @@ +#include "pipe/p_context.h" + +#include "nouveau_context.h" + +static INLINE int +nv04_surface_format(int cpp) +{ + switch (cpp) { + case 1: return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + case 2: return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + case 4: return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; + default: + return -1; + } +} + +static INLINE int +nv04_rect_format(int cpp) +{ + switch (cpp) { + case 1: return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + case 2: return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + case 4: return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + default: + return -1; + } +} + +static void +nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct pipe_surface *dst = nv->surf_dst; + struct pipe_surface *src = nv->surf_src; + unsigned dst_offset, src_offset; + + dst_offset = dst->offset + (dy * dst->pitch + dx) * dst->cpp; + src_offset = src->offset + (sy * src->pitch + sx) * src->cpp; + + while (h) { + int count = (h > 2047) ? 2047 : h; + + BEGIN_RING(chan, nv->nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src_offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst_offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RING (chan, src->pitch * src->cpp); + OUT_RING (chan, dst->pitch * dst->cpp); + OUT_RING (chan, w * src->cpp); + OUT_RING (chan, count); + OUT_RING (chan, 0x0101); + OUT_RING (chan, 0); + + h -= count; + src_offset += src->pitch * src->cpp * count; + dst_offset += dst->pitch * dst->cpp * count; + } +} + +static void +nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + + BEGIN_RING(chan, nv->nvc->NvImageBlit, 0x0300, 3); + OUT_RING (chan, (sy << 16) | sx); + OUT_RING (chan, (dy << 16) | dx); + OUT_RING (chan, ( h << 16) | w); +} + +static int +nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, + struct pipe_surface *src) +{ + struct nouveau_channel *chan = nv->nvc->channel; + int format; + + if (src->cpp != dst->cpp) + return 1; + + /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback + * to NV_MEMORY_TO_MEMORY_FORMAT in this case. + */ + if ((src->offset & 63) || (dst->offset & 63)) { + BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + nv->surface_copy = nv04_surface_copy_m2mf; + nv->surf_dst = dst; + nv->surf_src = src; + return 0; + + } + + if ((format = nv04_surface_format(dst->cpp)) < 0) { + NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + return 1; + } + nv->surface_copy = nv04_surface_copy_blit; + + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, format); + OUT_RING (chan, ((dst->pitch * dst->cpp) << 16) | + (src->pitch * src->cpp)); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + return 0; +} + +static void +nv04_surface_copy_done(struct nouveau_context *nv) +{ + FIRE_RING(nv->nvc->channel); +} + +static int +nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *surf2d = nv->nvc->NvCtxSurf2D; + struct nouveau_grobj *rect = nv->nvc->NvGdiRect; + int cs2d_format, gdirect_format; + + if ((cs2d_format = nv04_surface_format(dst->cpp)) < 0) { + NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + return 1; + } + + if ((gdirect_format = nv04_rect_format(dst->cpp)) < 0) { + NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + return 1; + } + + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, cs2d_format); + OUT_RING (chan, ((dst->pitch * dst->cpp) << 16) | + (dst->pitch * dst->cpp)); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); + OUT_RING (chan, gdirect_format); + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); + OUT_RING (chan, value); + BEGIN_RING(chan, rect, + NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); + OUT_RING (chan, (dx << 16) | dy); + OUT_RING (chan, ( w << 16) | h); + + FIRE_RING(chan); + return 0; +} + +int +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) +{ + struct nouveau_channel *chan = nvc->channel; + unsigned chipset = nvc->channel->device->chipset, class; + int ret; + + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39, + &nvc->NvM2MF))) { + NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvM2MF, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + + class = chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : + NV10_CONTEXT_SURFACES_2D; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvCtxSurf2D))) { + NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvCtxSurf2D, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RING (chan, nvc->channel->vram->handle); + OUT_RING (chan, nvc->channel->vram->handle); + + class = chipset < 0x10 ? NV04_IMAGE_BLIT : NV12_IMAGE_BLIT; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvImageBlit))) { + NOUVEAU_ERR("Error creating blit object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvImageBlit, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); + OUT_RING (chan, nvc->NvCtxSurf2D->handle); + BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); + OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_SRCCOPY); + + class = NV04_GDI_RECTANGLE_TEXT; + if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvGdiRect))) { + NOUVEAU_ERR("Error creating rect object: %d\n", ret); + return 1; + } + BIND_RING (chan, nvc->NvGdiRect, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + OUT_RING (chan, nvc->NvCtxSurf2D->handle); + BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); + BEGIN_RING(chan, nvc->NvGdiRect, + NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + + switch (chipset & 0xf0) { + case 0x00: + case 0x10: + class = NV04_SWIZZLED_SURFACE; + break; + case 0x20: + class = NV20_SWIZZLED_SURFACE; + break; + case 0x30: + class = NV30_SWIZZLED_SURFACE; + break; + case 0x40: + case 0x60: + class = NV40_SWIZZLED_SURFACE; + break; + default: + /* Famous last words: this really can't happen.. */ + assert(0); + break; + } + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvSwzSurf); + if (ret) { + NOUVEAU_ERR("Error creating swizzled surface: %d\n", ret); + return 1; + } + + BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); + + if (chipset < 0x10) { + class = NV04_SCALED_IMAGE_FROM_MEMORY; + } else + if (chipset < 0x40) { + class = NV10_SCALED_IMAGE_FROM_MEMORY; + } else { + class = NV40_SCALED_IMAGE_FROM_MEMORY; + } + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class, + &nvc->NvSIFM); + if (ret) { + NOUVEAU_ERR("Error creating scaled image object: %d\n", ret); + return 1; + } + + BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); + + return 0; +} + +int +nouveau_surface_init_nv04(struct nouveau_context *nv) +{ + nv->surface_copy_prep = nv04_surface_copy_prep; + nv->surface_copy = nv04_surface_copy_blit; + nv->surface_copy_done = nv04_surface_copy_done; + nv->surface_fill = nv04_surface_fill; + return 0; +} + diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c new file mode 100644 index 00000000000..d6da116b774 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -0,0 +1,182 @@ +#include "pipe/p_context.h" + +#include "nouveau_context.h" + +static INLINE int +nv50_format(int cpp) +{ + switch (cpp) { + case 4: return NV50_2D_DST_FORMAT_32BPP; + case 3: return NV50_2D_DST_FORMAT_24BPP; + case 2: return NV50_2D_DST_FORMAT_16BPP; + case 1: return NV50_2D_DST_FORMAT_8BPP; + default: + return -1; + } +} + +static int +nv50_surface_copy_prep(struct nouveau_context *nv, + struct pipe_surface *dst, struct pipe_surface *src) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + int surf_format; + + assert(src->cpp == dst->cpp); + + surf_format = nv50_format(dst->cpp); + assert(surf_format >= 0); + + BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); + OUT_RING (chan, dst->pitch * dst->cpp); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + + BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5); + OUT_RING (chan, src->pitch * src->cpp); + OUT_RING (chan, src->pitch); + OUT_RING (chan, src->height); + OUT_RELOCh(chan, nouveau_buffer(src->buffer)->bo, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + + return 0; +} + +static void +nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + + BEGIN_RING(chan, eng2d, 0x0110, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + 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, sx); + OUT_RING (chan, 0); + OUT_RING (chan, sy); +} + +static void +nv50_surface_copy_done(struct nouveau_context *nv) +{ + FIRE_RING(nv->nvc->channel); +} + +static int +nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + int surf_format, rect_format; + + surf_format = nv50_format(dst->cpp); + if (surf_format < 0) + return 1; + + rect_format = nv50_format(dst->cpp); + if (rect_format < 0) + return 1; + + BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5); + OUT_RING (chan, dst->pitch * dst->cpp); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, dst->height); + + BEGIN_RING(chan, eng2d, 0x0580, 3); + OUT_RING (chan, 4); + OUT_RING (chan, rect_format); + OUT_RING (chan, value); + + BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, dx + w); + OUT_RING (chan, dy + h); + + FIRE_RING(chan); + + return 0; +} + +int +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) +{ + int ret; + + ret = nouveau_grobj_alloc(nvc->channel, nvc->next_handle++, NV50_2D, + &nvc->Nv2D); + if (ret) + return ret; + BIND_RING (nvc->channel, nvc->Nv2D, nvc->next_subchannel++); + BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_NOTIFY, 1); + OUT_RING (nvc->channel, nvc->sync_notifier->handle); + BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RING (nvc->channel, nvc->channel->vram->handle); + OUT_RING (nvc->channel, nvc->channel->vram->handle); + BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_OPERATION, 1); + OUT_RING (nvc->channel, NV50_2D_OPERATION_SRCCOPY); + + return 0; +} + +int +nouveau_surface_init_nv50(struct nouveau_context *nv) +{ + nv->surface_copy_prep = nv50_surface_copy_prep; + nv->surface_copy = nv50_surface_copy; + nv->surface_copy_done = nv50_surface_copy_done; + nv->surface_fill = nv50_surface_fill; + return 0; +} + diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c new file mode 100644 index 00000000000..eb4c9085d6d --- /dev/null +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -0,0 +1,256 @@ +#include "xsp_winsys.h" +#include <X11/Xutil.h> +#include <pipe/p_winsys.h> +#include <pipe/p_state.h> +#include <pipe/p_util.h> +#include <pipe/p_inlines.h> +#include <softpipe/sp_winsys.h> + +/* pipe_winsys implementation */ + +struct xsp_pipe_winsys +{ + struct pipe_winsys base; + Display *display; + XImage fbimage; +}; + +struct xsp_buffer +{ + struct pipe_buffer base; + boolean is_user_buffer; + void *data; + void *mapped_data; +}; + +static struct pipe_buffer* xsp_buffer_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size) +{ + struct xsp_buffer *buffer; + + assert(pws); + + buffer = calloc(1, sizeof(struct xsp_buffer)); + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + buffer->data = align_malloc(size, alignment); + + return (struct pipe_buffer*)buffer; +} + +static struct pipe_buffer* xsp_user_buffer_create(struct pipe_winsys *pws, void *data, unsigned size) +{ + struct xsp_buffer *buffer; + + assert(pws); + + buffer = calloc(1, sizeof(struct xsp_buffer)); + buffer->base.refcount = 1; + buffer->base.size = size; + buffer->is_user_buffer = TRUE; + buffer->data = data; + + return (struct pipe_buffer*)buffer; +} + +static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, unsigned flags) +{ + struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; + + assert(pws); + assert(buffer); + + xsp_buf->mapped_data = xsp_buf->data; + return xsp_buf->mapped_data; +} + +static void xsp_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buffer) +{ + struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; + + assert(pws); + assert(buffer); + + xsp_buf->mapped_data = NULL; +} + +static void xsp_buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buffer) +{ + struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer; + + assert(pws); + assert(buffer); + + if (!xsp_buf->is_user_buffer) + align_free(xsp_buf->data); + + free(xsp_buf); +} + +static struct pipe_surface* xsp_surface_alloc(struct pipe_winsys *pws) +{ + struct pipe_surface *surface; + + assert(pws); + + surface = calloc(1, sizeof(struct pipe_surface)); + surface->refcount = 1; + surface->winsys = pws; + + return surface; +} + +static int xsp_surface_alloc_storage +( + struct pipe_winsys *pws, + struct pipe_surface *surface, + unsigned width, + unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage +) +{ + const unsigned int ALIGNMENT = 1; + + assert(pws); + assert(surface); + + surface->width = width; + surface->height = height; + surface->format = format; + surface->cpp = pf_get_size(format); + surface->pitch = width; + surface->usage = flags; + surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->pitch * surface->cpp * height); + + return 0; +} + +static void xsp_surface_release(struct pipe_winsys *pws, struct pipe_surface **surface) +{ + struct pipe_surface *s; + + assert(pws); + assert(surface); + assert(*surface); + + s = *surface; + + s->refcount--; + + if (s->refcount == 0) + { + pipe_buffer_reference(pws, &s->buffer, NULL); + free(s); + } + + *surface = NULL; +} + +static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) +{ + struct xsp_pipe_winsys *xsp_winsys; + + assert(pws); + assert(surface); + assert(context_private); + + xsp_winsys = (struct xsp_pipe_winsys*)pws; + + xsp_winsys->fbimage.width = surface->width; + xsp_winsys->fbimage.height = surface->height; + xsp_winsys->fbimage.bytes_per_line = surface->width * (xsp_winsys->fbimage.bits_per_pixel >> 3); + xsp_winsys->fbimage.data = pipe_surface_map(surface, 0); + + XPutImage + ( + xsp_winsys->display, + *(Drawable*)context_private, + XDefaultGC(xsp_winsys->display, XDefaultScreen(xsp_winsys->display)), + &xsp_winsys->fbimage, + 0, + 0, + 0, + 0, + surface->width, + surface->height + ); + XFlush(xsp_winsys->display); + pipe_surface_unmap(surface); +} + +static const char* xsp_get_name(struct pipe_winsys *pws) +{ + assert(pws); + return "X11 SoftPipe"; +} + +/* softpipe_winsys implementation */ + +static boolean xsp_is_format_supported(struct softpipe_winsys *spws, enum pipe_format format) +{ + assert(spws); + + /* TODO: Test that 'format' is equal to our output window's format */ + return TRUE; +} + +/* Show starts here */ + +struct pipe_context* create_pipe_context(Display *display) +{ + struct xsp_pipe_winsys *xsp_winsys; + struct softpipe_winsys *sp_winsys; + struct pipe_screen *p_screen; + struct pipe_context *p_context; + + assert(display); + + xsp_winsys = calloc(1, sizeof(struct xsp_pipe_winsys)); + xsp_winsys->base.buffer_create = xsp_buffer_create; + xsp_winsys->base.user_buffer_create = xsp_user_buffer_create; + xsp_winsys->base.buffer_map = xsp_buffer_map; + xsp_winsys->base.buffer_unmap = xsp_buffer_unmap; + xsp_winsys->base.buffer_destroy = xsp_buffer_destroy; + xsp_winsys->base.surface_alloc = xsp_surface_alloc; + xsp_winsys->base.surface_alloc_storage = xsp_surface_alloc_storage; + xsp_winsys->base.surface_release = xsp_surface_release; + xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer; + xsp_winsys->base.get_name = xsp_get_name; + xsp_winsys->display = display; + + { + /* XXX: Can't use the returned XImage* directly, + since we don't have control over winsys destruction + and we wouldn't be able to free it */ + XImage *template = XCreateImage + ( + display, + XDefaultVisual(display, XDefaultScreen(display)), + XDefaultDepth(display, XDefaultScreen(display)), + ZPixmap, + 0, + NULL, + 0, /* Don't know the width and height until flush_frontbuffer */ + 0, + 32, + 0 + ); + + memcpy(&xsp_winsys->fbimage, template, sizeof(XImage)); + XInitImage(&xsp_winsys->fbimage); + + XDestroyImage(template); + } + + sp_winsys = calloc(1, sizeof(struct softpipe_winsys)); + sp_winsys->is_format_supported = xsp_is_format_supported; + + p_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); + p_context = softpipe_create(p_screen, (struct pipe_winsys*)xsp_winsys, sp_winsys); + + return p_context; +} + diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.h b/src/gallium/winsys/g3dvl/xsp_winsys.h new file mode 100644 index 00000000000..47a6ac6e251 --- /dev/null +++ b/src/gallium/winsys/g3dvl/xsp_winsys.h @@ -0,0 +1,11 @@ +#ifndef xsp_winsys_h +#define xsp_winsys_h + +#include <X11/Xlib.h> + +struct pipe_context; + +struct pipe_context* create_pipe_context(Display *display); + +#endif + diff --git a/src/libXvMC/Makefile b/src/libXvMC/Makefile new file mode 100644 index 00000000000..b2f41e176d4 --- /dev/null +++ b/src/libXvMC/Makefile @@ -0,0 +1,33 @@ +TARGET = libXvMCg3dvl.so +SONAME = libXvMCg3dvl.so.1 +GALLIUMDIR = ../gallium +OBJECTS = block.o surface.o context.o subpicture.o attributes.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o + +CFLAGS += -g -fPIC -Wall -Werror \ + -I${GALLIUMDIR}/state_trackers/g3dvl \ + -I${GALLIUMDIR}/winsys/g3dvl \ + -I${GALLIUMDIR}/include \ + -I${GALLIUMDIR}/auxiliary \ + -I${GALLIUMDIR}/drivers +LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \ + -L${GALLIUMDIR}/drivers/softpipe \ + -L${GALLIUMDIR}/auxiliary/tgsi \ + -L${GALLIUMDIR}/auxiliary/draw \ + -L${GALLIUMDIR}/auxiliary/translate \ + -L${GALLIUMDIR}/auxiliary/cso_cache \ + -L${GALLIUMDIR}/auxiliary/util \ + -L${GALLIUMDIR}/auxiliary/rtasm +LIBS += -lg3dvl -lsoftpipe -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lutil + +############################################# + +.PHONY = all clean + +all: ${TARGET} + +${TARGET}: ${OBJECTS} + $(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ $^ ${LIBS} + +clean: + rm -rf ${OBJECTS} ${TARGET} + diff --git a/src/libXvMC/attributes.c b/src/libXvMC/attributes.c new file mode 100644 index 00000000000..674524b8b82 --- /dev/null +++ b/src/libXvMC/attributes.c @@ -0,0 +1,20 @@ +#include <assert.h> +#include <X11/Xlib.h> +#include <X11/extensions/Xvlib.h> +#include <X11/extensions/XvMC.h> + +XvAttribute* XvMCQueryAttributes(Display *display, XvMCContext *context, int *number) +{ + return NULL; +} + +Status XvMCSetAttribute(Display *display, XvMCContext *context, Atom attribute, int value) +{ + return BadImplementation; +} + +Status XvMCGetAttribute(Display *display, XvMCContext *context, Atom attribute, int *value) +{ + return BadImplementation; +} + diff --git a/src/libXvMC/block.c b/src/libXvMC/block.c new file mode 100644 index 00000000000..b56348d4645 --- /dev/null +++ b/src/libXvMC/block.c @@ -0,0 +1,85 @@ +#include <assert.h> +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/extensions/XvMC.h> +#include <vl_context.h> + +/* + * XvMC defines 64 element blocks (8x8 elements). + * Elements are 8 bits when they represent color values, + * 9 bits when they reprecent DCT coefficients, we + * store them in 2 bytes in either case. DCT coefficients + * can be signed or unsigned, at our option. + */ +#define BLOCK_SIZE (64 * 2) + +Status XvMCCreateBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCBlockArray *blocks) +{ + struct vl_context *vl_ctx; + + assert(display); + + if (!context) + return XvMCBadContext; + if (num_blocks == 0) + return BadValue; + + assert(blocks); + + vl_ctx = context->privData; + assert(display == vl_ctx->display); + + blocks->context_id = context->context_id; + blocks->num_blocks = num_blocks; + blocks->blocks = malloc(BLOCK_SIZE * num_blocks); + /* Since we don't have a VL type for blocks, set privData to the display so we can catch mismatches */ + blocks->privData = display; + + return Success; +} + +Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *blocks) +{ + assert(display); + assert(blocks); + assert(display == blocks->privData); + free(blocks->blocks); + + return Success; +} + +Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCMacroBlockArray *blocks) +{ + struct vl_context *vl_ctx; + + assert(display); + + if (!context) + return XvMCBadContext; + if (num_blocks == 0) + return BadValue; + + assert(blocks); + + vl_ctx = context->privData; + assert(display == vl_ctx->display); + + blocks->context_id = context->context_id; + blocks->num_blocks = num_blocks; + blocks->macro_blocks = malloc(sizeof(XvMCMacroBlock) * num_blocks); + /* Since we don't have a VL type for blocks, set privData to the display so we can catch mismatches */ + blocks->privData = display; + + return Success; +} + +Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *blocks) +{ + assert(display); + assert(blocks); + assert(display == blocks->privData); + free(blocks->macro_blocks); + + return Success; +} + diff --git a/src/libXvMC/context.c b/src/libXvMC/context.c new file mode 100644 index 00000000000..c835a6acf7a --- /dev/null +++ b/src/libXvMC/context.c @@ -0,0 +1,154 @@ +#include <assert.h> +#include <X11/Xlib.h> +#include <X11/extensions/XvMClib.h> +#include <vl_context.h> +#include <xsp_winsys.h> + +static Status Validate(Display *display, XvPortID port, int surface_type_id, unsigned int width, unsigned int height, int flags, int *chroma_format) +{ + unsigned int found_port = 0; + unsigned int found_surface = 0; + XvAdaptorInfo *adaptor_info; + unsigned int num_adaptors; + int num_types; + unsigned int max_width, max_height; + Status ret; + unsigned int i, j, k; + + assert(display && chroma_format); + + ret = XvQueryAdaptors(display, XDefaultRootWindow(display), &num_adaptors, &adaptor_info); + if (ret != Success) + return ret; + + /* Scan through all adaptors looking for this port and surface */ + for (i = 0; i < num_adaptors && !found_port; ++i) + { + /* Scan through all ports of this adaptor looking for our port */ + for (j = 0; j < adaptor_info[i].num_ports && !found_port; ++j) + { + /* If this is our port, scan through all its surfaces looking for our surface */ + if (adaptor_info[i].base_id + j == port) + { + XvMCSurfaceInfo *surface_info; + + found_port = 1; + surface_info = XvMCListSurfaceTypes(display, adaptor_info[i].base_id, &num_types); + + if (surface_info) + { + for (k = 0; k < num_types && !found_surface; ++k) + { + if (surface_info[k].surface_type_id == surface_type_id) + { + found_surface = 1; + max_width = surface_info[k].max_width; + max_height = surface_info[k].max_height; + *chroma_format = surface_info[k].chroma_format; + } + } + + XFree(surface_info); + } + else + { + XvFreeAdaptorInfo(adaptor_info); + return BadAlloc; + } + } + } + } + + XvFreeAdaptorInfo(adaptor_info); + + if (!found_port) + return XvBadPort; + if (!found_surface) + return BadMatch; + if (width > max_width || height > max_height) + return BadValue; + if (flags != XVMC_DIRECT && flags != 0) + return BadValue; + + return Success; +} + +static enum VL_FORMAT FormatToVL(int xvmc_format) +{ + enum VL_FORMAT vl_format; + + switch (xvmc_format) + { + case XVMC_CHROMA_FORMAT_420: + { + vl_format = VL_FORMAT_YCBCR_420; + break; + } + case XVMC_CHROMA_FORMAT_422: + { + vl_format = VL_FORMAT_YCBCR_422; + break; + } + case XVMC_CHROMA_FORMAT_444: + { + vl_format = VL_FORMAT_YCBCR_444; + break; + } + default: + assert(0); + } + + return vl_format; +} + +Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context) +{ + int chroma_format; + Status ret; + struct VL_CONTEXT *vl_ctx; + struct pipe_context *pipe; + + assert(display); + + if (!context) + return XvMCBadContext; + + ret = Validate(display, port, surface_type_id, width, height, flags, &chroma_format); + if (ret != Success) + return ret; + + pipe = create_pipe_context(display); + + assert(pipe); + + vlCreateContext(display, pipe, width, height, FormatToVL(chroma_format), &vl_ctx); + + context->context_id = XAllocID(display); + context->surface_type_id = surface_type_id; + context->width = width; + context->height = height; + context->flags = flags; + context->port = port; + context->privData = vl_ctx; + + return Success; +} + +Status XvMCDestroyContext(Display *display, XvMCContext *context) +{ + struct VL_CONTEXT *vl_ctx; + + assert(display); + + if (!context) + return XvMCBadContext; + + vl_ctx = context->privData; + + assert(display == vl_ctx->display); + + vlDestroyContext(vl_ctx); + + return Success; +} + diff --git a/src/libXvMC/subpicture.c b/src/libXvMC/subpicture.c new file mode 100644 index 00000000000..38d93438334 --- /dev/null +++ b/src/libXvMC/subpicture.c @@ -0,0 +1,110 @@ +#include <assert.h> +#include <X11/Xlib.h> +#include <X11/extensions/Xvlib.h> +#include <X11/extensions/XvMC.h> + +Status XvMCCreateSubpicture +( + Display *display, + XvMCContext *context, + XvMCSubpicture *subpicture, + unsigned short width, + unsigned short height, + int xvimage_id +) +{ + return BadImplementation; +} + +Status XvMCClearSubpicture +( + Display *display, + XvMCSubpicture *subpicture, + short x, + short y, + unsigned short width, + unsigned short height, + unsigned int color +) +{ + return BadImplementation; +} + +Status XvMCCompositeSubpicture +( + Display *display, + XvMCSubpicture *subpicture, + XvImage *image, + short srcx, + short srcy, + unsigned short width, + unsigned short height, + short dstx, + short dsty +) +{ + return BadImplementation; +} + +Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) +{ + return BadImplementation; +} + +Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture, unsigned char *palette) +{ + return BadImplementation; +} + +Status XvMCBlendSubpicture +( + Display *display, + XvMCSurface *target_surface, + XvMCSubpicture *subpicture, + short subx, + short suby, + unsigned short subw, + unsigned short subh, + short surfx, + short surfy, + unsigned short surfw, + unsigned short surfh +) +{ + return BadImplementation; +} + +Status XvMCBlendSubpicture2 +( + Display *display, + XvMCSurface *source_surface, + XvMCSurface *target_surface, + XvMCSubpicture *subpicture, + short subx, + short suby, + unsigned short subw, + unsigned short subh, + short surfx, + short surfy, + unsigned short surfw, + unsigned short surfh +) +{ + return BadImplementation; +} + +Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) +{ + return BadImplementation; +} + +Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) +{ + return BadImplementation; +} + +Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture, int *status) +{ + return BadImplementation; +} + diff --git a/src/libXvMC/surface.c b/src/libXvMC/surface.c new file mode 100644 index 00000000000..e4602d82042 --- /dev/null +++ b/src/libXvMC/surface.c @@ -0,0 +1,373 @@ +#include <assert.h> +#include <X11/Xlib.h> +#include <X11/extensions/XvMC.h> +#include <vl_context.h> +#include <vl_surface.h> + +static enum VL_PICTURE PictureToVL(int xvmc_pic) +{ + enum VL_PICTURE vl_pic; + + switch (xvmc_pic) + { + case XVMC_TOP_FIELD: + { + vl_pic = VL_TOP_FIELD; + break; + } + case XVMC_BOTTOM_FIELD: + { + vl_pic = VL_BOTTOM_FIELD; + break; + } + case XVMC_FRAME_PICTURE: + { + vl_pic = VL_FRAME_PICTURE; + break; + } + default: + assert(0); + } + + return vl_pic; +} + +Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) +{ + struct VL_CONTEXT *vl_ctx; + struct VL_SURFACE *vl_sfc; + + assert(display); + + if (!context) + return XvMCBadContext; + if (!surface) + return XvMCBadSurface; + + vl_ctx = context->privData; + + assert(display == vl_ctx->display); + + vlCreateSurface(vl_ctx, &vl_sfc); + + surface->surface_id = XAllocID(display); + surface->context_id = context->context_id; + surface->surface_type_id = context->surface_type_id; + surface->width = context->width; + surface->height = context->height; + surface->privData = vl_sfc; + + return Success; +} + +Status XvMCRenderSurface +( + Display *display, + XvMCContext *context, + unsigned int picture_structure, + XvMCSurface *target_surface, + XvMCSurface *past_surface, + XvMCSurface *future_surface, + unsigned int flags, + unsigned int num_macroblocks, + unsigned int first_macroblock, + XvMCMacroBlockArray *macroblocks, + XvMCBlockArray *blocks +) +{ + struct VL_CONTEXT *vl_ctx; + struct VL_SURFACE *target_vl_surface; + struct VL_SURFACE *past_vl_surface; + struct VL_SURFACE *future_vl_surface; + unsigned int i; + + assert(display); + + if (!context) + return XvMCBadContext; + if (!target_surface) + return XvMCBadSurface; + + if + ( + picture_structure != XVMC_TOP_FIELD && + picture_structure != XVMC_BOTTOM_FIELD && + picture_structure != XVMC_FRAME_PICTURE + ) + return BadValue; + if (future_surface && !past_surface) + return BadMatch; + + vl_ctx = context->privData; + + assert(display == vl_ctx->display); + + target_vl_surface = target_surface->privData; + past_vl_surface = past_surface ? past_surface->privData : NULL; + future_vl_surface = future_surface ? future_surface->privData : NULL; + + assert(vl_ctx == target_vl_surface->context); + assert(!past_vl_surface || vl_ctx == past_vl_surface->context); + assert(!future_vl_surface || vl_ctx == future_vl_surface->context); + + assert(macroblocks); + assert(blocks); + + assert(macroblocks->context_id == context->context_id); + assert(blocks->context_id == context->context_id); + + assert(flags == 0 || flags == XVMC_SECOND_FIELD); + + for (i = first_macroblock; i < first_macroblock + num_macroblocks; ++i) + if (macroblocks->macro_blocks[i].macroblock_type & XVMC_MB_TYPE_INTRA) + vlRenderIMacroBlock + ( + PictureToVL(picture_structure), + flags == XVMC_SECOND_FIELD ? VL_FIELD_SECOND : VL_FIELD_FIRST, + macroblocks->macro_blocks[i].x, + macroblocks->macro_blocks[i].y, + macroblocks->macro_blocks[i].coded_block_pattern, + macroblocks->macro_blocks[i].dct_type == XVMC_DCT_TYPE_FIELD ? VL_DCT_FIELD_CODED : VL_DCT_FRAME_CODED, + blocks->blocks + (macroblocks->macro_blocks[i].index * 64), + target_vl_surface + ); + else if + ( + (macroblocks->macro_blocks[i].macroblock_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) + == XVMC_MB_TYPE_MOTION_FORWARD + ) + { + struct VL_MOTION_VECTOR motion_vector = + { + { + macroblocks->macro_blocks[i].PMV[0][0][0], + macroblocks->macro_blocks[i].PMV[0][0][1], + }, + { + macroblocks->macro_blocks[i].PMV[1][0][0], + macroblocks->macro_blocks[i].PMV[1][0][1], + } + }; + + vlRenderPMacroBlock + ( + PictureToVL(picture_structure), + flags == XVMC_SECOND_FIELD ? VL_FIELD_SECOND : VL_FIELD_FIRST, + macroblocks->macro_blocks[i].x, + macroblocks->macro_blocks[i].y, + macroblocks->macro_blocks[i].motion_type == XVMC_PREDICTION_FRAME ? VL_FIELD_MC : VL_FRAME_MC, + &motion_vector, + macroblocks->macro_blocks[i].coded_block_pattern, + macroblocks->macro_blocks[i].dct_type == XVMC_DCT_TYPE_FIELD ? VL_DCT_FIELD_CODED : VL_DCT_FRAME_CODED, + blocks->blocks + (macroblocks->macro_blocks[i].index * 64), + past_vl_surface, + target_vl_surface + ); + } + else if + ( + (macroblocks->macro_blocks[i].macroblock_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) + == XVMC_MB_TYPE_MOTION_BACKWARD + ) + { + struct VL_MOTION_VECTOR motion_vector = + { + { + macroblocks->macro_blocks[i].PMV[0][1][0], + macroblocks->macro_blocks[i].PMV[0][1][1], + }, + { + macroblocks->macro_blocks[i].PMV[1][1][0], + macroblocks->macro_blocks[i].PMV[1][1][1], + } + }; + + vlRenderPMacroBlock + ( + PictureToVL(picture_structure), + flags == XVMC_SECOND_FIELD ? VL_FIELD_SECOND : VL_FIELD_FIRST, + macroblocks->macro_blocks[i].x, + macroblocks->macro_blocks[i].y, + macroblocks->macro_blocks[i].motion_type == XVMC_PREDICTION_FRAME ? VL_FIELD_MC : VL_FRAME_MC, + &motion_vector, + macroblocks->macro_blocks[i].coded_block_pattern, + macroblocks->macro_blocks[i].dct_type == XVMC_DCT_TYPE_FIELD ? VL_DCT_FIELD_CODED : VL_DCT_FRAME_CODED, + blocks->blocks + (macroblocks->macro_blocks[i].index * 64), + future_vl_surface, + target_vl_surface + ); + } + else if + ( + (macroblocks->macro_blocks[i].macroblock_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) + == (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD) + ) + { + struct VL_MOTION_VECTOR motion_vector[2] = + { + { + { + macroblocks->macro_blocks[i].PMV[0][0][0], + macroblocks->macro_blocks[i].PMV[0][0][1], + }, + { + macroblocks->macro_blocks[i].PMV[1][0][0], + macroblocks->macro_blocks[i].PMV[1][0][1], + } + }, + { + { + macroblocks->macro_blocks[i].PMV[0][1][0], + macroblocks->macro_blocks[i].PMV[0][1][1], + }, + { + macroblocks->macro_blocks[i].PMV[1][1][0], + macroblocks->macro_blocks[i].PMV[1][1][1], + } + } + }; + + vlRenderBMacroBlock + ( + PictureToVL(picture_structure), + flags == XVMC_SECOND_FIELD ? VL_FIELD_SECOND : VL_FIELD_FIRST, + macroblocks->macro_blocks[i].x, + macroblocks->macro_blocks[i].y, + macroblocks->macro_blocks[i].motion_type == XVMC_PREDICTION_FRAME ? VL_FIELD_MC : VL_FRAME_MC, + motion_vector, + macroblocks->macro_blocks[i].coded_block_pattern, + macroblocks->macro_blocks[i].dct_type == XVMC_DCT_TYPE_FIELD ? VL_DCT_FIELD_CODED : VL_DCT_FRAME_CODED, + blocks->blocks + (macroblocks->macro_blocks[i].index * 64), + past_vl_surface, + future_vl_surface, + target_vl_surface + ); + } + else + fprintf(stderr, "Unrecognized macroblock\n"); + + return Success; +} + +Status XvMCFlushSurface(Display *display, XvMCSurface *surface) +{ + /* TODO: Check display & surface match */ + return BadImplementation; +} + +Status XvMCSyncSurface(Display *display, XvMCSurface *surface) +{ + /* TODO: Check display & surface match */ + return BadImplementation; +} + +Status XvMCPutSurface +( + Display *display, + XvMCSurface *surface, + Drawable drawable, + short srcx, + short srcy, + unsigned short srcw, + unsigned short srch, + short destx, + short desty, + unsigned short destw, + unsigned short desth, + int flags +) +{ + Window root; + int x, y; + unsigned int width, height; + unsigned int border_width; + unsigned int depth; + struct VL_SURFACE *vl_sfc; + + assert(display); + + if (!surface) + return XvMCBadSurface; + + if (XGetGeometry(display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable) + return BadDrawable; + + assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE); + + /* TODO: Correct for negative srcx,srcy & destx,desty by clipping */ + + assert(srcx + srcw - 1 < surface->width); + assert(srcy + srch - 1 < surface->height); + assert(destx + destw - 1 < width); + assert(desty + desth - 1 < height); + + vl_sfc = surface->privData; + + vlPutSurface(vl_sfc, drawable, srcx, srcy, srcw, srch, destx, desty, destw, desth, PictureToVL(flags)); + + return Success; +} + +Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *status) +{ + struct VL_CONTEXT *vl_ctx; + struct VL_SURFACE *vl_sfc; + + assert(display); + + if (!surface) + return XvMCBadSurface; + + assert(status); + + vl_sfc = surface->privData; + vl_ctx = vl_sfc->context; + + assert(display == vl_ctx->display); + + /* TODO */ + *status = 0; + + return BadImplementation; +} + +Status XvMCDestroySurface(Display *display, XvMCSurface *surface) +{ + struct VL_CONTEXT *vl_ctx; + struct VL_SURFACE *vl_sfc; + + assert(display); + + if (!surface) + return XvMCBadSurface; + + vl_sfc = surface->privData; + vl_ctx = vl_sfc->context; + + assert(display == vl_ctx->display); + + vlDestroySurface(vl_sfc); + + return Success; +} + +Status XvMCHideSurface(Display *display, XvMCSurface *surface) +{ + struct VL_CONTEXT *vl_ctx; + struct VL_SURFACE *vl_sfc; + + assert(display); + + if (!surface) + return XvMCBadSurface; + + vl_sfc = surface->privData; + vl_ctx = vl_sfc->context; + + assert(display == vl_ctx->display); + + /* No op, only for overlaid rendering */ + + return Success; +} + diff --git a/src/libXvMC/tests/.gitignore b/src/libXvMC/tests/.gitignore new file mode 100644 index 00000000000..eb1ef8a0761 --- /dev/null +++ b/src/libXvMC/tests/.gitignore @@ -0,0 +1,5 @@ +test_context +test_surface +test_blocks +test_rendering + diff --git a/src/libXvMC/tests/Makefile b/src/libXvMC/tests/Makefile new file mode 100644 index 00000000000..2cbc97e88ba --- /dev/null +++ b/src/libXvMC/tests/Makefile @@ -0,0 +1,25 @@ +CFLAGS += -g -Wall -Werror +LDFLAGS += +LIBS += -lXvMCW -lXvMC -lXv + +############################################# + +.PHONY = all clean + +all: test_context test_surface test_blocks test_rendering + +test_context: test_context.o testlib.o + $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} + +test_surface: test_surface.o testlib.o + $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} + +test_blocks: test_blocks.o testlib.o + $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} + +test_rendering: test_rendering.o testlib.o + $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} + +clean: + rm -rf *.o test_context test_surface test_blocks test_rendering + diff --git a/src/libXvMC/tests/test_blocks.c b/src/libXvMC/tests/test_blocks.c new file mode 100644 index 00000000000..0b895ee7737 --- /dev/null +++ b/src/libXvMC/tests/test_blocks.c @@ -0,0 +1,95 @@ +#include <assert.h> +#include <error.h> +#include "testlib.h" + +int main(int argc, char **argv) +{ + const unsigned int width = 16, height = 16; + const unsigned int min_required_blocks = 1, min_required_macroblocks = 1; + const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2}; + + Display *display; + XvPortID port_num; + int surface_type_id; + unsigned int is_overlay, intra_unsigned; + int colorkey; + XvMCContext context; + XvMCSurface surface; + XvMCBlockArray blocks = {0}; + XvMCMacroBlockArray macroblocks = {0}; + + display = XOpenDisplay(NULL); + + if (!GetPort + ( + display, + width, + height, + XVMC_CHROMA_FORMAT_420, + mc_types, + 2, + &port_num, + &surface_type_id, + &is_overlay, + &intra_unsigned + )) + { + XCloseDisplay(display); + error(1, 0, "Error, unable to find a good port.\n"); + } + + if (is_overlay) + { + Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0); + XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey); + } + + assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success); + assert(XvMCCreateSurface(display, &context, &surface) == Success); + + /* Test NULL context */ + assert(XvMCCreateBlocks(display, NULL, 1, &blocks) == XvMCBadContext); + /* Test 0 blocks */ + assert(XvMCCreateBlocks(display, &context, 0, &blocks) == BadValue); + /* Test too many blocks */ + /*assert(XvMCCreateBlocks(display, &context, 16384, &blocks) == BadAlloc);*/ + + /* Note: No XvMCBadBlock(s) error in spec */ + + /* Test valid params */ + assert(XvMCCreateBlocks(display, &context, min_required_blocks, &blocks) == Success); + /* Test context id assigned and correct */ + assert(blocks.context_id == context.context_id); + /* Test number of blocks assigned and correct */ + assert(blocks.num_blocks == min_required_blocks); + /* Test block pointer valid */ + assert(blocks.blocks != NULL); + /* Test NULL context */ + assert(XvMCCreateMacroBlocks(display, NULL, 1, ¯oblocks) == XvMCBadContext); + /* Test 0 macroblocks */ + assert(XvMCCreateMacroBlocks(display, &context, 0, ¯oblocks) == BadValue); + /* Test too many macroblocks */ + /*assert(XvMCCreateMacroBlocks(display, &context, 16384, ¯oblocks) == BadAlloc);*/ + + /* Note: No XvMCBadMacroBlock(s) error in spec */ + + /* Test valid params */ + assert(XvMCCreateMacroBlocks(display, &context, min_required_macroblocks, ¯oblocks) == Success); + /* Test context id assigned and correct */ + assert(macroblocks.context_id == context.context_id); + /* Test macroblock pointer valid */ + assert(macroblocks.macro_blocks != NULL); + /* Test valid params */ + assert(XvMCDestroyMacroBlocks(display, ¯oblocks) == Success); + /* Test valid params */ + assert(XvMCDestroyBlocks(display, &blocks) == Success); + + assert(XvMCDestroySurface(display, &surface) == Success); + assert(XvMCDestroyContext(display, &context) == Success); + + XvUngrabPort(display, port_num, CurrentTime); + XCloseDisplay(display); + + return 0; +} + diff --git a/src/libXvMC/tests/test_context.c b/src/libXvMC/tests/test_context.c new file mode 100644 index 00000000000..22afb7ada4e --- /dev/null +++ b/src/libXvMC/tests/test_context.c @@ -0,0 +1,94 @@ +#include <assert.h> +#include <error.h> +#include "testlib.h" + +int main(int argc, char **argv) +{ + const unsigned int width = 16, height = 16; + const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2}; + + Display *display; + XvPortID port_num; + int surface_type_id; + unsigned int is_overlay, intra_unsigned; + int colorkey; + XvMCContext context = {0}; + + display = XOpenDisplay(NULL); + + if (!GetPort + ( + display, + width, + height, + XVMC_CHROMA_FORMAT_420, + mc_types, + 2, + &port_num, + &surface_type_id, + &is_overlay, + &intra_unsigned + )) + { + XCloseDisplay(display); + error(1, 0, "Error, unable to find a good port.\n"); + } + + if (is_overlay) + { + Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0); + XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey); + } + + /* Note: XvMCBadContext not a valid return for XvMCCreateContext in the XvMC API, but openChrome driver returns it */ + /* Note: Nvidia binary driver segfaults on NULL context, halts with debug output on bad port */ + + /* Test NULL context */ + assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, NULL) == XvMCBadContext); + /* Test invalid port */ + assert(XvMCCreateContext(display, port_num + 1, surface_type_id, width, height, XVMC_DIRECT, &context) == XvBadPort); + /* Test invalid surface */ + assert(XvMCCreateContext(display, port_num, surface_type_id + 1, width, height, XVMC_DIRECT, &context) == BadMatch); + /* Test invalid flags */ + assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, -1, &context) == BadValue); + /* Test huge width */ + assert(XvMCCreateContext(display, port_num, surface_type_id, 16384, height, XVMC_DIRECT, &context) == BadValue); + /* Test huge height */ + assert(XvMCCreateContext(display, port_num, surface_type_id, width, 16384, XVMC_DIRECT, &context) == BadValue); + /* Test huge width & height */ + assert(XvMCCreateContext(display, port_num, surface_type_id, 16384, 16384, XVMC_DIRECT, &context) == BadValue); + /* Test valid params */ + assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success); + /* Test context id assigned */ + assert(context.context_id != 0); + /* Test surface type id assigned and correct */ + assert(context.surface_type_id == surface_type_id); + /* Test width & height assigned and correct */ + assert(context.width == width && context.height == height); + /* Test port assigned and correct */ + assert(context.port == port_num); + /* Test flags assigned and correct */ + assert(context.flags == XVMC_DIRECT); + /* Test NULL context */ + assert(XvMCDestroyContext(display, NULL) == XvMCBadContext); + /* Test valid params */ + assert(XvMCDestroyContext(display, &context) == Success); + /* Test awkward but valid width */ + assert(XvMCCreateContext(display, port_num, surface_type_id, width + 1, height, XVMC_DIRECT, &context) == Success); + assert(context.width >= width + 1); + assert(XvMCDestroyContext(display, &context) == Success); + /* Test awkward but valid height */ + assert(XvMCCreateContext(display, port_num, surface_type_id, width, height + 1, XVMC_DIRECT, &context) == Success); + assert(context.height >= height + 1); + assert(XvMCDestroyContext(display, &context) == Success); + /* Test awkward but valid width & height */ + assert(XvMCCreateContext(display, port_num, surface_type_id, width + 1, height + 1, XVMC_DIRECT, &context) == Success); + assert(context.width >= width + 1 && context.height >= height + 1); + assert(XvMCDestroyContext(display, &context) == Success); + + XvUngrabPort(display, port_num, CurrentTime); + XCloseDisplay(display); + + return 0; +} + diff --git a/src/libXvMC/tests/test_rendering.c b/src/libXvMC/tests/test_rendering.c new file mode 100644 index 00000000000..1914b1fb628 --- /dev/null +++ b/src/libXvMC/tests/test_rendering.c @@ -0,0 +1,153 @@ +#include <assert.h> +#include <stdio.h> +#include <error.h> +#include "testlib.h" + +int main(int argc, char **argv) +{ + const unsigned int width = 32, height = 32; + const unsigned int mwidth = width / 16, mheight = height / 16; + const unsigned int num_macroblocks = mwidth * mheight; + const unsigned int num_blocks = num_macroblocks * 6; + const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2}; + + int quit = 0; + Display *display; + Window root, window; + Pixmap framebuffer; + XEvent event; + XvPortID port_num; + int surface_type_id; + unsigned int is_overlay, intra_unsigned; + int colorkey; + XvMCContext context; + XvMCSurface surface; + XvMCBlockArray blocks; + XvMCMacroBlockArray macroblocks; + unsigned int b, x, y; + + display = XOpenDisplay(NULL); + + if (!GetPort + ( + display, + width, + height, + XVMC_CHROMA_FORMAT_420, + mc_types, + 2, + &port_num, + &surface_type_id, + &is_overlay, + &intra_unsigned + )) + { + XCloseDisplay(display); + error(1, 0, "Error, unable to find a good port.\n"); + } + + if (is_overlay) + { + Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0); + XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey); + } + + root = XDefaultRootWindow(display); + window = XCreateSimpleWindow(display, root, 0, 0, width, height, 0, 0, colorkey); + framebuffer = XCreatePixmap(display, root, width, height, 24); + + XSelectInput(display, window, ExposureMask | KeyPressMask); + XMapWindow(display, window); + XSync(display, 0); + + assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success); + assert(XvMCCreateSurface(display, &context, &surface) == Success); + assert(XvMCCreateBlocks(display, &context, num_blocks, &blocks) == Success); + assert(XvMCCreateMacroBlocks(display, &context, num_macroblocks, ¯oblocks) == Success); + + for (b = 0; b < 6; ++b) + { + for (y = 0; y < 8; ++y) + { + for (x = 0; x < 8; ++x) + { + blocks.blocks[b * 64 + y * 8 + x] = 0xFFFF; + } + } + } + + for (y = 0; y < mheight; ++y) + { + for (x = 0; x < mwidth; ++x) + { + macroblocks.macro_blocks[y * mwidth + x].x = x; + macroblocks.macro_blocks[y * mwidth + x].y = y; + macroblocks.macro_blocks[y * mwidth + x].index = (y * mwidth + x) * 6; + macroblocks.macro_blocks[y * mwidth + x].macroblock_type = XVMC_MB_TYPE_INTRA; + macroblocks.macro_blocks[y * mwidth + x].coded_block_pattern = 0x3F; + macroblocks.macro_blocks[y * mwidth + x].dct_type = XVMC_DCT_TYPE_FRAME; + } + } + + /* Test NULL context */ + assert(XvMCRenderSurface(display, NULL, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, 1, 0, ¯oblocks, &blocks) == XvMCBadContext); + /* Test NULL surface */ + assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, NULL, NULL, NULL, 0, 1, 0, ¯oblocks, &blocks) == XvMCBadSurface); + /* Test bad picture structure */ + assert(XvMCRenderSurface(display, &context, 0, &surface, NULL, NULL, 0, 1, 0, ¯oblocks, &blocks) == BadValue); + /* Test valid params */ + assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, num_macroblocks, 0, ¯oblocks, &blocks) == Success); + + /* Test NULL surface */ + assert(XvMCPutSurface(display, NULL, window, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == XvMCBadSurface); + /* Test bad window */ + /* X halts with a bad drawable for some reason, doesn't return BadDrawable as expected */ + /*assert(XvMCPutSurface(display, &surface, 0, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == BadDrawable);*/ + /* Test valid params */ + assert(XvMCPutSurface(display, &surface, framebuffer, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == Success); + + puts("Press any key to continue..."); + + while (!quit) + { + XNextEvent(display, &event); + switch (event.type) + { + case Expose: + { + XCopyArea + ( + display, + framebuffer, + window, + XDefaultGC(display, XDefaultScreen(display)), + 0, + 0, + width, + height, + 0, + 0 + ); + break; + } + case KeyPress: + { + quit = 1; + break; + } + } + } + + assert(XvMCDestroyBlocks(display, &blocks) == Success); + assert(XvMCDestroyMacroBlocks(display, ¯oblocks) == Success); + assert(XvMCDestroySurface(display, &surface) == Success); + assert(XvMCDestroyContext(display, &context) == Success); + + XFreePixmap(display, framebuffer); + XvUngrabPort(display, port_num, CurrentTime); + XDestroyWindow(display, window); + XCloseDisplay(display); + + return 0; +} + diff --git a/src/libXvMC/tests/test_surface.c b/src/libXvMC/tests/test_surface.c new file mode 100644 index 00000000000..25ebdcc4fcf --- /dev/null +++ b/src/libXvMC/tests/test_surface.c @@ -0,0 +1,72 @@ +#include <assert.h> +#include <error.h> +#include "testlib.h" + +int main(int argc, char **argv) +{ + const unsigned int width = 16, height = 16; + const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2}; + + Display *display; + XvPortID port_num; + int surface_type_id; + unsigned int is_overlay, intra_unsigned; + int colorkey; + XvMCContext context; + XvMCSurface surface = {0}; + + display = XOpenDisplay(NULL); + + if (!GetPort + ( + display, + width, + height, + XVMC_CHROMA_FORMAT_420, + mc_types, + 2, + &port_num, + &surface_type_id, + &is_overlay, + &intra_unsigned + )) + { + XCloseDisplay(display); + error(1, 0, "Error, unable to find a good port.\n"); + } + + if (is_overlay) + { + Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0); + XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey); + } + + assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success); + + /* Test NULL context */ + assert(XvMCCreateSurface(display, NULL, &surface) == XvMCBadContext); + /* Test NULL surface */ + assert(XvMCCreateSurface(display, &context, NULL) == XvMCBadSurface); + /* Test valid params */ + assert(XvMCCreateSurface(display, &context, &surface) == Success); + /* Test surface id assigned */ + assert(surface.surface_id != 0); + /* Test context id assigned and correct */ + assert(surface.context_id == context.context_id); + /* Test surface type id assigned and correct */ + assert(surface.surface_type_id == surface_type_id); + /* Test width & height assigned and correct */ + assert(surface.width == width && surface.height == height); + /* Test valid params */ + assert(XvMCDestroySurface(display, &surface) == Success); + /* Test NULL surface */ + assert(XvMCDestroySurface(display, NULL) == XvMCBadSurface); + + assert(XvMCDestroyContext(display, &context) == Success); + + XvUngrabPort(display, port_num, CurrentTime); + XCloseDisplay(display); + + return 0; +} + diff --git a/src/libXvMC/tests/testlib.c b/src/libXvMC/tests/testlib.c new file mode 100644 index 00000000000..8672aa99998 --- /dev/null +++ b/src/libXvMC/tests/testlib.c @@ -0,0 +1,87 @@ +#include "testlib.h" +#include <stdio.h> + +/* +void test(int pred, const char *pred_string, const char *doc_string, const char *file, unsigned int line) +{ + fputs(doc_string, stderr); + if (!pred) + fprintf(stderr, " FAIL!\n\t\"%s\" at %s:%u\n", pred_string, file, line); + else + fputs(" PASS!\n", stderr); +} +*/ + +int GetPort +( + Display *display, + unsigned int width, + unsigned int height, + unsigned int chroma_format, + const unsigned int *mc_types, + unsigned int num_mc_types, + XvPortID *port_id, + int *surface_type_id, + unsigned int *is_overlay, + unsigned int *intra_unsigned +) +{ + unsigned int found_port = 0; + XvAdaptorInfo *adaptor_info; + unsigned int num_adaptors; + int num_types; + int ev_base, err_base; + unsigned int i, j, k, l; + + if (!XvMCQueryExtension(display, &ev_base, &err_base)) + return 0; + if (XvQueryAdaptors(display, XDefaultRootWindow(display), &num_adaptors, &adaptor_info) != Success) + return 0; + + for (i = 0; i < num_adaptors && !found_port; ++i) + { + if (adaptor_info[i].type & XvImageMask) + { + XvMCSurfaceInfo *surface_info = XvMCListSurfaceTypes(display, adaptor_info[i].base_id, &num_types); + + if (surface_info) + { + for (j = 0; j < num_types && !found_port; ++j) + { + if + ( + surface_info[j].chroma_format == chroma_format && + surface_info[j].max_width >= width && + surface_info[j].max_height >= height + ) + { + for (k = 0; k < num_mc_types && !found_port; ++k) + { + if (surface_info[j].mc_type == mc_types[k]) + { + for (l = 0; l < adaptor_info[i].num_ports && !found_port; ++l) + { + if (XvGrabPort(display, adaptor_info[i].base_id + l, CurrentTime) == Success) + { + *port_id = adaptor_info[i].base_id + l; + *surface_type_id = surface_info[j].surface_type_id; + *is_overlay = surface_info[j].flags & XVMC_OVERLAID_SURFACE; + *intra_unsigned = surface_info[j].flags & XVMC_INTRA_UNSIGNED; + found_port = 1; + } + } + } + } + } + } + + XFree(surface_info); + } + } + } + + XvFreeAdaptorInfo(adaptor_info); + + return found_port; +} + diff --git a/src/libXvMC/tests/testlib.h b/src/libXvMC/tests/testlib.h new file mode 100644 index 00000000000..c73845807ec --- /dev/null +++ b/src/libXvMC/tests/testlib.h @@ -0,0 +1,38 @@ +#ifndef testlib_h +#define testlib_h + +/* +#define TEST(pred, doc) test(pred, #pred, doc, __FILE__, __LINE__) + +void test(int pred, const char *pred_string, const char *doc_string, const char *file, unsigned int line); +*/ + +#include <X11/Xlib.h> +#include <X11/extensions/XvMClib.h> + +/* + * display: IN A valid X display + * width, height: IN Surface size that the port must display + * chroma_format: IN Chroma format that the port must display + * mc_types, num_mc_types: IN List of MC types that the port must support, first port that matches the first mc_type will be returned + * port_id: OUT Your port's ID + * surface_type_id: OUT Your port's surface ID + * is_overlay: OUT If 1, port uses overlay surfaces, you need to set a colorkey + * intra_unsigned: OUT If 1, port uses unsigned values for intra-coded blocks + */ +int GetPort +( + Display *display, + unsigned int width, + unsigned int height, + unsigned int chroma_format, + const unsigned int *mc_types, + unsigned int num_mc_types, + XvPortID *port_id, + int *surface_type_id, + unsigned int *is_overlay, + unsigned int *intra_unsigned +); + +#endif + |