From 26add9288c88108e3485ffc57c51ea9bdc0ee719 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 16 Feb 2008 17:23:12 +1100 Subject: nouveau: match gallium code reorginisation. That was... fun.. --- src/gallium/drivers/Makefile | 3 +- src/gallium/drivers/nouveau/nouveau_bo.h | 51 + src/gallium/drivers/nouveau/nouveau_channel.h | 39 + src/gallium/drivers/nouveau/nouveau_class.h | 6134 ++++++++++++++++++++ src/gallium/drivers/nouveau/nouveau_gldefs.h | 196 + src/gallium/drivers/nouveau/nouveau_grobj.h | 35 + src/gallium/drivers/nouveau/nouveau_notifier.h | 43 + src/gallium/drivers/nouveau/nouveau_push.h | 83 + src/gallium/drivers/nouveau/nouveau_pushbuf.h | 32 + src/gallium/drivers/nouveau/nouveau_resource.h | 37 + src/gallium/drivers/nouveau/nouveau_stateobj.h | 141 + src/gallium/drivers/nouveau/nouveau_winsys.h | 61 + src/gallium/drivers/nv30/Makefile | 29 + src/gallium/drivers/nv30/nv30_clear.c | 12 + src/gallium/drivers/nv30/nv30_context.c | 431 ++ src/gallium/drivers/nv30/nv30_context.h | 136 + src/gallium/drivers/nv30/nv30_draw.c | 62 + src/gallium/drivers/nv30/nv30_fragprog.c | 835 +++ src/gallium/drivers/nv30/nv30_fragtex.c | 160 + src/gallium/drivers/nv30/nv30_miptree.c | 105 + src/gallium/drivers/nv30/nv30_query.c | 113 + src/gallium/drivers/nv30/nv30_shader.h | 490 ++ src/gallium/drivers/nv30/nv30_state.c | 739 +++ src/gallium/drivers/nv30/nv30_state.h | 147 + src/gallium/drivers/nv30/nv30_state_emit.c | 83 + src/gallium/drivers/nv30/nv30_surface.c | 137 + src/gallium/drivers/nv30/nv30_vbo.c | 425 ++ src/gallium/drivers/nv30/nv30_vertprog.c | 777 +++ src/gallium/drivers/nv40/Makefile | 29 + src/gallium/drivers/nv40/nv40_clear.c | 12 + src/gallium/drivers/nv40/nv40_context.c | 312 + src/gallium/drivers/nv40/nv40_context.h | 153 + src/gallium/drivers/nv40/nv40_dma.h | 66 + src/gallium/drivers/nv40/nv40_draw.c | 62 + src/gallium/drivers/nv40/nv40_fragprog.c | 842 +++ src/gallium/drivers/nv40/nv40_fragtex.c | 151 + src/gallium/drivers/nv40/nv40_miptree.c | 104 + src/gallium/drivers/nv40/nv40_query.c | 113 + src/gallium/drivers/nv40/nv40_shader.h | 554 ++ src/gallium/drivers/nv40/nv40_state.c | 823 +++ src/gallium/drivers/nv40/nv40_state.h | 80 + src/gallium/drivers/nv40/nv40_state_emit.c | 77 + src/gallium/drivers/nv40/nv40_surface.c | 137 + src/gallium/drivers/nv40/nv40_vbo.c | 424 ++ src/gallium/drivers/nv40/nv40_vertprog.c | 790 +++ src/gallium/drivers/nv50/Makefile | 25 + src/gallium/drivers/nv50/nv50_clear.c | 12 + src/gallium/drivers/nv50/nv50_context.c | 202 + src/gallium/drivers/nv50/nv50_context.h | 57 + src/gallium/drivers/nv50/nv50_draw.c | 55 + src/gallium/drivers/nv50/nv50_miptree.c | 25 + src/gallium/drivers/nv50/nv50_query.c | 47 + src/gallium/drivers/nv50/nv50_state.c | 213 + src/gallium/drivers/nv50/nv50_state.h | 7 + src/gallium/drivers/nv50/nv50_surface.c | 75 + src/gallium/drivers/nv50/nv50_vbo.c | 24 + src/gallium/winsys/dri/nouveau/Makefile | 43 + src/gallium/winsys/dri/nouveau/nouveau_bo.c | 402 ++ src/gallium/winsys/dri/nouveau/nouveau_channel.c | 118 + src/gallium/winsys/dri/nouveau/nouveau_context.c | 206 + src/gallium/winsys/dri/nouveau/nouveau_context.h | 89 + src/gallium/winsys/dri/nouveau/nouveau_device.c | 146 + src/gallium/winsys/dri/nouveau/nouveau_device.h | 29 + src/gallium/winsys/dri/nouveau/nouveau_dma.c | 219 + src/gallium/winsys/dri/nouveau/nouveau_dma.h | 143 + src/gallium/winsys/dri/nouveau/nouveau_dri.h | 28 + src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 304 + src/gallium/winsys/dri/nouveau/nouveau_fence.c | 215 + src/gallium/winsys/dri/nouveau/nouveau_grobj.c | 107 + src/gallium/winsys/dri/nouveau/nouveau_local.h | 89 + src/gallium/winsys/dri/nouveau/nouveau_lock.c | 94 + src/gallium/winsys/dri/nouveau/nouveau_notifier.c | 137 + src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 261 + src/gallium/winsys/dri/nouveau/nouveau_resource.c | 111 + src/gallium/winsys/dri/nouveau/nouveau_screen.c | 308 + src/gallium/winsys/dri/nouveau/nouveau_screen.h | 19 + .../winsys/dri/nouveau/nouveau_swapbuffers.c | 86 + .../winsys/dri/nouveau/nouveau_swapbuffers.h | 10 + src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 124 + .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 196 + .../winsys/dri/nouveau/nouveau_winsys_pipe.h | 34 + .../winsys/dri/nouveau/nouveau_winsys_softpipe.c | 83 + src/gallium/winsys/dri/nouveau/nv04_surface.c | 226 + src/gallium/winsys/dri/nouveau/nv50_surface.c | 160 + 84 files changed, 20993 insertions(+), 1 deletion(-) create mode 100644 src/gallium/drivers/nouveau/nouveau_bo.h create mode 100644 src/gallium/drivers/nouveau/nouveau_channel.h create mode 100644 src/gallium/drivers/nouveau/nouveau_class.h create mode 100644 src/gallium/drivers/nouveau/nouveau_gldefs.h create mode 100644 src/gallium/drivers/nouveau/nouveau_grobj.h create mode 100644 src/gallium/drivers/nouveau/nouveau_notifier.h create mode 100644 src/gallium/drivers/nouveau/nouveau_push.h create mode 100644 src/gallium/drivers/nouveau/nouveau_pushbuf.h create mode 100644 src/gallium/drivers/nouveau/nouveau_resource.h create mode 100644 src/gallium/drivers/nouveau/nouveau_stateobj.h create mode 100644 src/gallium/drivers/nouveau/nouveau_winsys.h create mode 100644 src/gallium/drivers/nv30/Makefile create mode 100644 src/gallium/drivers/nv30/nv30_clear.c create mode 100644 src/gallium/drivers/nv30/nv30_context.c create mode 100644 src/gallium/drivers/nv30/nv30_context.h create mode 100644 src/gallium/drivers/nv30/nv30_draw.c create mode 100644 src/gallium/drivers/nv30/nv30_fragprog.c create mode 100644 src/gallium/drivers/nv30/nv30_fragtex.c create mode 100644 src/gallium/drivers/nv30/nv30_miptree.c create mode 100644 src/gallium/drivers/nv30/nv30_query.c create mode 100644 src/gallium/drivers/nv30/nv30_shader.h create mode 100644 src/gallium/drivers/nv30/nv30_state.c create mode 100644 src/gallium/drivers/nv30/nv30_state.h create mode 100644 src/gallium/drivers/nv30/nv30_state_emit.c create mode 100644 src/gallium/drivers/nv30/nv30_surface.c create mode 100644 src/gallium/drivers/nv30/nv30_vbo.c create mode 100644 src/gallium/drivers/nv30/nv30_vertprog.c create mode 100644 src/gallium/drivers/nv40/Makefile create mode 100644 src/gallium/drivers/nv40/nv40_clear.c create mode 100644 src/gallium/drivers/nv40/nv40_context.c create mode 100644 src/gallium/drivers/nv40/nv40_context.h create mode 100644 src/gallium/drivers/nv40/nv40_dma.h create mode 100644 src/gallium/drivers/nv40/nv40_draw.c create mode 100644 src/gallium/drivers/nv40/nv40_fragprog.c create mode 100644 src/gallium/drivers/nv40/nv40_fragtex.c create mode 100644 src/gallium/drivers/nv40/nv40_miptree.c create mode 100644 src/gallium/drivers/nv40/nv40_query.c create mode 100644 src/gallium/drivers/nv40/nv40_shader.h create mode 100644 src/gallium/drivers/nv40/nv40_state.c create mode 100644 src/gallium/drivers/nv40/nv40_state.h create mode 100644 src/gallium/drivers/nv40/nv40_state_emit.c create mode 100644 src/gallium/drivers/nv40/nv40_surface.c create mode 100644 src/gallium/drivers/nv40/nv40_vbo.c create mode 100644 src/gallium/drivers/nv40/nv40_vertprog.c create mode 100644 src/gallium/drivers/nv50/Makefile create mode 100644 src/gallium/drivers/nv50/nv50_clear.c create mode 100644 src/gallium/drivers/nv50/nv50_context.c create mode 100644 src/gallium/drivers/nv50/nv50_context.h create mode 100644 src/gallium/drivers/nv50/nv50_draw.c create mode 100644 src/gallium/drivers/nv50/nv50_miptree.c create mode 100644 src/gallium/drivers/nv50/nv50_query.c create mode 100644 src/gallium/drivers/nv50/nv50_state.c create mode 100644 src/gallium/drivers/nv50/nv50_state.h create mode 100644 src/gallium/drivers/nv50/nv50_surface.c create mode 100644 src/gallium/drivers/nv50/nv50_vbo.c create mode 100644 src/gallium/winsys/dri/nouveau/Makefile create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_bo.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_channel.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_context.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_context.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_device.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_device.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dma.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dma.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dri.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_drmif.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_fence.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_grobj.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_local.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_lock.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_notifier.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_resource.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_screen.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_screen.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h create mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c create mode 100644 src/gallium/winsys/dri/nouveau/nv04_surface.c create mode 100644 src/gallium/winsys/dri/nouveau/nv50_surface.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/Makefile b/src/gallium/drivers/Makefile index c0345a9cb5..58df6c5009 100644 --- a/src/gallium/drivers/Makefile +++ b/src/gallium/drivers/Makefile @@ -6,7 +6,8 @@ ifeq ($(CONFIG_NAME), linux-cell) CELL_DIR = cell endif -SUBDIRS = softpipe i915simple i965simple failover pipebuffer $(CELL_DIR) +SUBDIRS = softpipe i915simple i965simple nv30 nv40 nv50 \ + failover pipebuffer $(CELL_DIR) default: subdirs diff --git a/src/gallium/drivers/nouveau/nouveau_bo.h b/src/gallium/drivers/nouveau/nouveau_bo.h new file mode 100644 index 0000000000..18020e9c65 --- /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 0000000000..b99de9add8 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_channel.h @@ -0,0 +1,39 @@ +/* + * 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 *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 0000000000..5998945677 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -0,0 +1,6134 @@ +/************************************************************************* + + Autogenerated file, do not edit ! + +************************************************************************** + + Copyright (C) 2006-2007 : + 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 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_DISPLAY_LIST 0x0000018c +#define NV10TCL_DMA_IN_MEMORY2 0x00000194 +#define NV10TCL_DMA_IN_MEMORY3 0x00000198 +#define NV10TCL_VIEWPORT_HORIZ 0x00000200 +#define NV10TCL_VIEWPORT_HORIZ_X_SHIFT 0 +#define NV10TCL_VIEWPORT_HORIZ_X_MASK 0x0000ffff +#define NV10TCL_VIEWPORT_HORIZ_W_SHIFT 16 +#define NV10TCL_VIEWPORT_HORIZ_W_MASK 0xffff0000 +#define NV10TCL_VIEWPORT_VERT 0x00000204 +#define NV10TCL_VIEWPORT_VERT_Y_SHIFT 0 +#define NV10TCL_VIEWPORT_VERT_Y_MASK 0x0000ffff +#define NV10TCL_VIEWPORT_VERT_H_SHIFT 16 +#define NV10TCL_VIEWPORT_VERT_H_MASK 0xffff0000 +#define NV10TCL_BUFFER_FORMAT 0x00000208 +#define NV10TCL_BUFFER_PITCH 0x0000020c +#define NV10TCL_BUFFER_PITCH_COLOR_PITCH_SHIFT 0 +#define NV10TCL_BUFFER_PITCH_COLOR_PITCH_MASK 0x0000ffff +#define NV10TCL_BUFFER_PITCH_ZETA_PITCH_SHIFT 16 +#define NV10TCL_BUFFER_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_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_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_DRAW_INDEX 0x00000e00 +#define NV10TCL_DRAW_INDEX_I0_SHIFT 0 +#define NV10TCL_DRAW_INDEX_I0_MASK 0x0000ffff +#define NV10TCL_DRAW_INDEX_I1_SHIFT 24 +#define NV10TCL_DRAW_INDEX_I1_MASK 0xff000000 +#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_ZETA_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_FUNC_COLOR 0x0000031c +#define NV34TCL_BLEND_FUNC_EQUATION 0x00000320 +#define NV34TCL_BLEND_FUNC_EQUATION_FUNC_ADD 0x00008006 +#define NV34TCL_BLEND_FUNC_EQUATION_MIN 0x00008007 +#define NV34TCL_BLEND_FUNC_EQUATION_MAX 0x00008008 +#define NV34TCL_BLEND_FUNC_EQUATION_FUNC_SUBTRACT 0x0000800a +#define NV34TCL_BLEND_FUNC_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_FILL_ENABLE 0x00000a60 +#define NV34TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000a64 +#define NV34TCL_POLYGON_OFFSET_POINT_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_VERTEX_NOR_3I_XY 0x00000a90 +#define NV34TCL_VERTEX_NOR_3I_XY_X_SHIFT 0 +#define NV34TCL_VERTEX_NOR_3I_XY_X_MASK 0x0000ffff +#define NV34TCL_VERTEX_NOR_3I_XY_Y_SHIFT 16 +#define NV34TCL_VERTEX_NOR_3I_XY_Y_MASK 0xffff0000 +#define NV34TCL_VERTEX_NOR_3I_Z 0x00000a94 +#define NV34TCL_VERTEX_NOR_3I_Z_Z_SHIFT 0 +#define NV34TCL_VERTEX_NOR_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_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_VERTEX_ATTR_3F_X(x) (0x00001500+((x)*16)) +#define NV34TCL_VERTEX_ATTR_3F_X__SIZE 0x00000010 +#define NV34TCL_VERTEX_ATTR_3F_Y(x) (0x00001504+((x)*16)) +#define NV34TCL_VERTEX_ATTR_3F_Y__SIZE 0x00000010 +#define NV34TCL_VERTEX_ATTR_3F_Z(x) (0x00001508+((x)*16)) +#define NV34TCL_VERTEX_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_VERTEX_BUFFER_ADDRESS(x) (0x00001680+((x)*4)) +#define NV34TCL_VERTEX_BUFFER_ADDRESS__SIZE 0x00000010 +#define NV34TCL_VERTEX_BUFFER_ADDRESS_DMA1 (1 << 31) +#define NV34TCL_VERTEX_BUFFER_ADDRESS_OFFSET_SHIFT 0 +#define NV34TCL_VERTEX_BUFFER_ADDRESS_OFFSET_MASK 0x0fffffff +#define NV34TCL_VERTEX_ARRAY_FORMAT(x) (0x00001740+((x)*4)) +#define NV34TCL_VERTEX_ARRAY_FORMAT__SIZE 0x00000010 +#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_SHIFT 0 +#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_MASK 0x0000000f +#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT 0x00000002 +#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_UBYTE 0x00000004 +#define NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_SHIFT 4 +#define NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_MASK 0x000000f0 +#define NV34TCL_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT 8 +#define NV34TCL_VERTEX_ARRAY_FORMAT_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_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_VERTEX_ATTR_2F_X(x) (0x00001880+((x)*8)) +#define NV34TCL_VERTEX_ATTR_2F_X__SIZE 0x00000010 +#define NV34TCL_VERTEX_ATTR_2F_Y(x) (0x00001884+((x)*8)) +#define NV34TCL_VERTEX_ATTR_2F_Y__SIZE 0x00000010 +#define NV34TCL_VERTEX_ATTR_2I(x) (0x00001900+((x)*4)) +#define NV34TCL_VERTEX_ATTR_2I__SIZE 0x00000010 +#define NV34TCL_VERTEX_ATTR_2I_Y_SHIFT 16 +#define NV34TCL_VERTEX_ATTR_2I_Y_MASK 0xffff0000 +#define NV34TCL_VERTEX_ATTR_2I_X_SHIFT 0 +#define NV34TCL_VERTEX_ATTR_2I_X_MASK 0x0000ffff +#define NV34TCL_VERTEX_COL_4I(x) (0x0000194c+((x)*4)) +#define NV34TCL_VERTEX_COL_4I__SIZE 0x00000002 +#define NV34TCL_VERTEX_COL_4I_R_SHIFT 0 +#define NV34TCL_VERTEX_COL_4I_R_MASK 0x000000ff +#define NV34TCL_VERTEX_COL_4I_G_SHIFT 8 +#define NV34TCL_VERTEX_COL_4I_G_MASK 0x0000ff00 +#define NV34TCL_VERTEX_COL_4I_B_SHIFT 16 +#define NV34TCL_VERTEX_COL_4I_B_MASK 0x00ff0000 +#define NV34TCL_VERTEX_COL_4I_A_SHIFT 24 +#define NV34TCL_VERTEX_COL_4I_A_MASK 0xff000000 +#define NV34TCL_VERTEX_POS_4I_XY 0x00001980 +#define NV34TCL_VERTEX_POS_4I_XY_X_SHIFT 0 +#define NV34TCL_VERTEX_POS_4I_XY_X_MASK 0x0000ffff +#define NV34TCL_VERTEX_POS_4I_XY_Y_SHIFT 16 +#define NV34TCL_VERTEX_POS_4I_XY_Y_MASK 0xffff0000 +#define NV34TCL_VERTEX_POS_4I_ZW 0x00001984 +#define NV34TCL_VERTEX_POS_4I_ZW_Z_SHIFT 0 +#define NV34TCL_VERTEX_POS_4I_ZW_Z_MASK 0x0000ffff +#define NV34TCL_VERTEX_POS_4I_ZW_W_SHIFT 16 +#define NV34TCL_VERTEX_POS_4I_ZW_W_MASK 0xffff0000 +#define NV34TCL_VERTEX_TX_4I_ST(x) (0x000019c0+((x)*8)) +#define NV34TCL_VERTEX_TX_4I_ST__SIZE 0x00000004 +#define NV34TCL_VERTEX_TX_4I_ST_S_SHIFT 0 +#define NV34TCL_VERTEX_TX_4I_ST_S_MASK 0x0000ffff +#define NV34TCL_VERTEX_TX_4I_ST_T_SHIFT 16 +#define NV34TCL_VERTEX_TX_4I_ST_T_MASK 0xffff0000 +#define NV34TCL_VERTEX_TX_4I_RQ(x) (0x000019c4+((x)*8)) +#define NV34TCL_VERTEX_TX_4I_RQ__SIZE 0x00000004 +#define NV34TCL_VERTEX_TX_4I_RQ_R_SHIFT 0 +#define NV34TCL_VERTEX_TX_4I_RQ_R_MASK 0x0000ffff +#define NV34TCL_VERTEX_TX_4I_RQ_Q_SHIFT 16 +#define NV34TCL_VERTEX_TX_4I_RQ_Q_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_VERTEX_ATTR_4F_X(x) (0x00001c00+((x)*16)) +#define NV34TCL_VERTEX_ATTR_4F_X__SIZE 0x00000010 +#define NV34TCL_VERTEX_ATTR_4F_Y(x) (0x00001c04+((x)*16)) +#define NV34TCL_VERTEX_ATTR_4F_Y__SIZE 0x00000010 +#define NV34TCL_VERTEX_ATTR_4F_Z(x) (0x00001c08+((x)*16)) +#define NV34TCL_VERTEX_ATTR_4F_Z__SIZE 0x00000010 +#define NV34TCL_VERTEX_ATTR_4F_W(x) (0x00001c0c+((x)*16)) +#define NV34TCL_VERTEX_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_VERTEX_FOG_1F 0x00001e54 +#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_FILL_ENABLE 0x00000a60 +#define NV40TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000a64 +#define NV40TCL_POLYGON_OFFSET_POINT_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_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 << 2) +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE1 (1 << 6) +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE2 (1 << 10) +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE3 (1 << 14) +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE4 (1 << 18) +#define NV40TCL_CLIP_PLANE_ENABLE_PLANE5 (1 << 22) +#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_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_Y_SHIFT 16 +#define NV40TCL_VTX_ATTR_2I_Y_MASK 0xffff0000 +#define NV40TCL_VTX_ATTR_2I_X_SHIFT 0 +#define NV40TCL_VTX_ATTR_2I_X_MASK 0x0000ffff +#define NV40TCL_VTX_ATTR_4I_0(x) (0x00001900+((x)*8)) +#define NV40TCL_VTX_ATTR_4I_0__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_4I_0_Y_SHIFT 16 +#define NV40TCL_VTX_ATTR_4I_0_Y_MASK 0xffff0000 +#define NV40TCL_VTX_ATTR_4I_0_X_SHIFT 0 +#define NV40TCL_VTX_ATTR_4I_0_X_MASK 0x0000ffff +#define NV40TCL_VTX_ATTR_4I_1(x) (0x00001904+((x)*8)) +#define NV40TCL_VTX_ATTR_4I_1__SIZE 0x00000010 +#define NV40TCL_VTX_ATTR_4I_1_W_SHIFT 16 +#define NV40TCL_VTX_ATTR_4I_1_W_MASK 0xffff0000 +#define NV40TCL_VTX_ATTR_4I_1_Z_SHIFT 0 +#define NV40TCL_VTX_ATTR_4I_1_Z_MASK 0x0000ffff +#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_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_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_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_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_gldefs.h b/src/gallium/drivers/nouveau/nouveau_gldefs.h new file mode 100644 index 0000000000..e1015c93a2 --- /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 0000000000..8f5abf9051 --- /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 0000000000..35adde1e32 --- /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 0000000000..c5c5d988d5 --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_push.h @@ -0,0 +1,83 @@ +#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->channel, ((size) + 1)); \ + 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() do { \ + NOUVEAU_PUSH_CONTEXT(pc); \ + pc->nvws->push_flush(pc->nvws->channel, 0); \ +} while(0) + +#define OUT_RELOC(bo,data,flags,vor,tor) do { \ + NOUVEAU_PUSH_CONTEXT(pc); \ + pc->nvws->push_reloc(pc->nvws->channel, \ + 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)); \ + 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 0000000000..1909765098 --- /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 0000000000..1af7961d30 --- /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 0000000000..07c31b014a --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -0,0 +1,141 @@ +#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 = 1; + 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; + + so = *pso; + if (so) { + if (--so->refcount <= 0) { + free(so->push); + free(so->reloc); + free(so); + } + *pso = NULL; + } + + if (ref) { + ref->refcount++; + *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->channel, nr); + 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->channel, 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->channel, i); + 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->channel, pb->cur++, r->bo, r->packet, + (r->flags & + (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART)) | + NOUVEAU_BO_DUMMY, 0, 0); + nvws->push_reloc(nvws->channel, pb->cur++, r->bo, r->data, + r->flags | NOUVEAU_BO_DUMMY, r->vor, r->tor); + } +} + +#endif diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h new file mode 100644 index 0000000000..b5e470cfaa --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -0,0 +1,61 @@ +#ifndef NOUVEAU_WINSYS_H +#define NOUVEAU_WINSYS_H + +#include +#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_grobj.h" +#include "nouveau/nouveau_notifier.h" +#include "nouveau/nouveau_resource.h" +#include "nouveau/nouveau_pushbuf.h" + +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_channel *, void *ptr, + struct pipe_buffer *, uint32_t data, + uint32_t flags, uint32_t vor, uint32_t tor); + int (*push_flush)(struct nouveau_channel *, unsigned size); + + 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_context * +nv30_create(struct pipe_winsys *, struct nouveau_winsys *, unsigned chipset); + +extern struct pipe_context * +nv40_create(struct pipe_winsys *, struct nouveau_winsys *, unsigned chipset); + +extern struct pipe_context * +nv50_create(struct pipe_winsys *, struct nouveau_winsys *, unsigned chipset); + +#endif diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile new file mode 100644 index 0000000000..b7c252fc98 --- /dev/null +++ b/src/gallium/drivers/nv30/Makefile @@ -0,0 +1,29 @@ +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_state.c \ + nv30_state_emit.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 0000000000..71f413588e --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_clear.c @@ -0,0 +1,12 @@ +#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); +} diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c new file mode 100644 index 0000000000..e9afeb8017 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -0,0 +1,431 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv30_context.h" + +static const char * +nv30_get_name(struct pipe_context *pipe) +{ + struct nv30_context *nv30 = nv30_context(pipe); + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", nv30->chipset); + return buffer; +} + +static const char * +nv30_get_vendor(struct pipe_context *pipe) +{ + return "nouveau"; +} + +static int +nv30_get_param(struct pipe_context *pipe, 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; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv30_get_paramf(struct pipe_context *pipe, 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; + case PIPE_CAP_BITMAP_TEXCOORD_BIAS: + return 0.0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0.0; + } +} + +static void +nv30_flush(struct pipe_context *pipe, unsigned flags) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nouveau_winsys *nvws = nv30->nvws; + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(rankine, 0x1fd8, 1); + OUT_RING (2); + BEGIN_RING(rankine, 0x1fd8, 1); + OUT_RING (1); + } + + if (flags & PIPE_FLUSH_WAIT) { + nvws->notifier_reset(nv30->sync, 0); + BEGIN_RING(rankine, 0x104, 1); + OUT_RING (0); + BEGIN_RING(rankine, 0x100, 1); + OUT_RING (0); + } + + FIRE_RING(); + + if (flags & PIPE_FLUSH_WAIT) + nvws->notifier_wait(nv30->sync, 0, 0, 2000); +} + +static void +nv30_destroy(struct pipe_context *pipe) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nouveau_winsys *nvws = nv30->nvws; + + if (nv30->draw) + draw_destroy(nv30->draw); + + nvws->res_free(&nv30->vertprog.exec_heap); + nvws->res_free(&nv30->vertprog.data_heap); + + nvws->res_free(&nv30->query_heap); + nvws->notifier_free(&nv30->query); + + nvws->notifier_free(&nv30->sync); + + nvws->grobj_free(&nv30->rankine); + + free(nv30); +} + +static boolean +nv30_init_hwctx(struct nv30_context *nv30, int rankine_class) +{ + struct nouveau_winsys *nvws = nv30->nvws; + int ret; + int i; + + ret = nvws->grobj_alloc(nvws, rankine_class, &nv30->rankine); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return FALSE; + } + + BEGIN_RING(rankine, NV34TCL_DMA_NOTIFY, 1); + OUT_RING (nv30->sync->handle); + BEGIN_RING(rankine, NV34TCL_DMA_TEXTURE0, 2); + OUT_RING (nvws->channel->vram->handle); + OUT_RING (nvws->channel->gart->handle); + BEGIN_RING(rankine, NV34TCL_DMA_COLOR1, 1); + OUT_RING (nvws->channel->vram->handle); + BEGIN_RING(rankine, NV34TCL_DMA_COLOR0, 2); + OUT_RING (nvws->channel->vram->handle); + OUT_RING (nvws->channel->vram->handle); + BEGIN_RING(rankine, NV34TCL_DMA_VTXBUF0, 2); + OUT_RING (nvws->channel->vram->handle); + OUT_RING (nvws->channel->gart->handle); +/* BEGIN_RING(rankine, NV34TCL_DMA_FENCE, 2); + OUT_RING (0); + OUT_RING (nv30->query->handle);*/ + BEGIN_RING(rankine, NV34TCL_DMA_IN_MEMORY7, 1); + OUT_RING (nvws->channel->vram->handle); + BEGIN_RING(rankine, NV34TCL_DMA_IN_MEMORY8, 1); + OUT_RING (nvws->channel->vram->handle); + + for (i=1; i<8; i++) { + BEGIN_RING(rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING (0); + BEGIN_RING(rankine, NV34TCL_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING (0); + } + + BEGIN_RING(rankine, 0x220, 1); + OUT_RING (1); + + BEGIN_RING(rankine, 0x03b0, 1); + OUT_RING (0x00100000); + BEGIN_RING(rankine, 0x1454, 1); + OUT_RING (0); + BEGIN_RING(rankine, 0x1d80, 1); + OUT_RING (3); + BEGIN_RING(rankine, 0x1450, 1); + OUT_RING (0x00030004); + + /* NEW */ + BEGIN_RING(rankine, 0x1e98, 1); + OUT_RING (0); + BEGIN_RING(rankine, 0x17e0, 3); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0x3f800000); + BEGIN_RING(rankine, 0x1f80, 16); + OUT_RING (0); OUT_RING (0); OUT_RING (0); OUT_RING (0); + OUT_RING (0); OUT_RING (0); OUT_RING (0); OUT_RING (0); + OUT_RING (0x0000ffff); + OUT_RING (0); OUT_RING (0); OUT_RING (0); OUT_RING (0); + OUT_RING (0); OUT_RING (0); OUT_RING (0); + + BEGIN_RING(rankine, 0x120, 3); + OUT_RING (0); + OUT_RING (1); + OUT_RING (2); + + BEGIN_RING(rankine, 0x1d88, 1); + OUT_RING (0x00001200); + + BEGIN_RING(rankine, NV34TCL_RC_ENABLE, 1); + OUT_RING (0); + + /* Attempt to setup a known state.. Probably missing a heap of + * stuff here.. + */ + BEGIN_RING(rankine, NV34TCL_STENCIL_FRONT_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(rankine, NV34TCL_STENCIL_BACK_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(rankine, NV34TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(rankine, NV34TCL_DEPTH_WRITE_ENABLE, 2); + OUT_RING (0); /* wr disable */ + OUT_RING (0); /* test disable */ + BEGIN_RING(rankine, NV34TCL_COLOR_MASK, 1); + OUT_RING (0x01010101); /* TR,TR,TR,TR */ + BEGIN_RING(rankine, NV34TCL_CULL_FACE_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(rankine, NV34TCL_BLEND_FUNC_ENABLE, 5); + OUT_RING (0); /* Blend enable */ + OUT_RING (0); /* Blend src */ + OUT_RING (0); /* Blend dst */ + OUT_RING (0x00000000); /* Blend colour */ + OUT_RING (0x8006); /* FUNC_ADD */ + BEGIN_RING(rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2); + OUT_RING (0); + OUT_RING (0x1503 /*GL_COPY*/); + BEGIN_RING(rankine, NV34TCL_DITHER_ENABLE, 1); + OUT_RING (1); + BEGIN_RING(rankine, NV34TCL_SHADE_MODEL, 1); + OUT_RING (0x1d01 /*GL_SMOOTH*/); + BEGIN_RING(rankine, NV34TCL_POLYGON_OFFSET_FACTOR,2); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + BEGIN_RING(rankine, NV34TCL_POLYGON_MODE_FRONT, 2); + OUT_RING (0x1b02 /*GL_FILL*/); + OUT_RING (0x1b02 /*GL_FILL*/); + /* - Disable texture units + * - Set fragprog to MOVR result.color, fragment.color */ + for (i=0;i<16;i++) { + BEGIN_RING(rankine, + NV34TCL_TX_ENABLE(i), 1); + OUT_RING (0); + } + /* Polygon stipple */ + BEGIN_RING(rankine, + NV34TCL_POLYGON_STIPPLE_PATTERN(0), 0x20); + for (i=0;i<0x20;i++) + OUT_RING (0xFFFFFFFF); + + int w=4096; + int h=4096; + int pitch=4096*4; + BEGIN_RING(rankine, NV34TCL_RT_HORIZ, 5); + OUT_RING (w<<16); + OUT_RING (h<<16); + OUT_RING (0x148); /* format */ + OUT_RING (pitch << 16 | pitch); + OUT_RING (0x0); + BEGIN_RING(rankine, 0x0a00, 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); + OUT_RING ((h-1)<<16); + BEGIN_RING(rankine, NV34TCL_SCISSOR_HORIZ, 2); + OUT_RING (w<<16); + OUT_RING (h<<16); + BEGIN_RING(rankine, NV34TCL_VIEWPORT_HORIZ, 2); + OUT_RING (w<<16); + OUT_RING (h<<16); + + BEGIN_RING(rankine, NV34TCL_VIEWPORT_TRANSLATE_X, 8); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + OUT_RINGf (0.0); + + BEGIN_RING(rankine, NV34TCL_MODELVIEW_MATRIX(0), 16); + OUT_RINGf (1.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + + BEGIN_RING(rankine, NV34TCL_PROJECTION_MATRIX(0), 16); + OUT_RINGf (1.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + + BEGIN_RING(rankine, NV34TCL_SCISSOR_HORIZ, 2); + OUT_RING (4096<<16); + OUT_RING (4096<<16); + + BEGIN_RING(rankine, NV34TCL_MULTISAMPLE_CONTROL, 1); + OUT_RING (0xffff0000); + + FIRE_RING (); + return TRUE; +} + +#define NV30TCL_CHIPSET_3X_MASK 0x00000003 +#define NV34TCL_CHIPSET_3X_MASK 0x00000010 +#define NV35TCL_CHIPSET_3X_MASK 0x000001e0 + +struct pipe_context * +nv30_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws, + unsigned chipset) +{ + struct nv30_context *nv30; + int rankine_class = 0, ret; + + if ((chipset & 0xf0) != 0x30) { + NOUVEAU_ERR("Not a NV3X chipset\n"); + return NULL; + } + + 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; + } else { + NOUVEAU_ERR("Unknown NV3X chipset: NV%02x\n", chipset); + return NULL; + } + + nv30 = CALLOC_STRUCT(nv30_context); + if (!nv30) + return NULL; + nv30->chipset = chipset; + nv30->nvws = nvws; + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &nv30->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv30_destroy(&nv30->pipe); + return NULL; + } + + /* Query objects */ + ret = nvws->notifier_alloc(nvws, 32, &nv30->query); + if (ret) { + NOUVEAU_ERR("Error initialising query objects: %d\n", ret); + nv30_destroy(&nv30->pipe); + return NULL; + } + + ret = nvws->res_init(&nv30->query_heap, 0, 32); + if (ret) { + NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); + nv30_destroy(&nv30->pipe); + return NULL; + } + + /* Vtxprog resources */ + if (nvws->res_init(&nv30->vertprog.exec_heap, 0, 512) || + nvws->res_init(&nv30->vertprog.data_heap, 0, 256)) { + nv30_destroy(&nv30->pipe); + return NULL; + } + + /* Static rankine initialisation */ + if (!nv30_init_hwctx(nv30, rankine_class)) { + nv30_destroy(&nv30->pipe); + return NULL; + } + + /* Pipe context setup */ + nv30->pipe.winsys = pipe_winsys; + + nv30->pipe.destroy = nv30_destroy; + nv30->pipe.get_name = nv30_get_name; + nv30->pipe.get_vendor = nv30_get_vendor; + nv30->pipe.get_param = nv30_get_param; + nv30->pipe.get_paramf = nv30_get_paramf; + + 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); + nv30_init_miptree_functions(nv30); + + nv30->draw = draw_create(); + assert(nv30->draw); + 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 0000000000..d6d16ee868 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -0,0 +1,136 @@ +#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_context *ctx = nv30 +#include "nouveau/nouveau_push.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); + +#define NV30_NEW_VERTPROG (1 << 1) +#define NV30_NEW_FRAGPROG (1 << 2) +#define NV30_NEW_ARRAYS (1 << 3) + +struct nv30_context { + struct pipe_context pipe; + struct nouveau_winsys *nvws; + + struct draw_context *draw; + + int chipset; + struct nouveau_grobj *rankine; + struct nouveau_notifier *sync; + + /* query objects */ + struct nouveau_notifier *query; + struct nouveau_resource *query_heap; + + 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; + + uint32_t rt_enable; + struct pipe_buffer *rt[4]; + 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 nouveau_resource *exec_heap; + struct nouveau_resource *data_heap; + + 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_ATTRIB_MAX]; + struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; +}; + +static INLINE struct nv30_context * +nv30_context(struct pipe_context *pipe) +{ + return (struct nv30_context *)pipe; +} + +extern void nv30_init_state_functions(struct nv30_context *nv30); +extern void nv30_init_surface_functions(struct nv30_context *nv30); +extern void nv30_init_miptree_functions(struct nv30_context *nv30); +extern void nv30_init_query_functions(struct nv30_context *nv30); + +/* 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 0000000000..59a7265799 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_draw.c @@ -0,0 +1,62 @@ +#include "draw/draw_private.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 0000000000..09ad555c32 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -0,0 +1,835 @@ +#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; + 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: + if (finst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide == + TGSI_EXTSWIZZLE_W) { + tex(fpc, sat, TXP, unit, dst, mask, src[0], none, none); + } else + 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_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->u.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->u.DeclarationRange.First; + break; + case TGSI_SEMANTIC_COLOR: + fpc->colour_id = fdec->u.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 0000000000..45ee6db8d6 --- /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), + _(U_L8 , L8 , S1, S1, S1, ONE, X, X, X, X), + _(U_A8 , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X), + _(U_I8 , L8 , S1, S1, S1, S1, X, X, X, X), + _(U_A8_L8 , 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 0000000000..5fb89f4cfd --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -0,0 +1,105 @@ +#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; + + 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; + } + + for (l = 0; l <= pt->last_level; l++) { + pt->width[l] = width; + pt->height[l] = height; + pt->depth[l] = depth; + + if (swizzled) + nv30mt->level[l].pitch = pt->width[l] * pt->cpp; + else + nv30mt->level[l].pitch = pt->width[0] * pt->cpp; + nv30mt->level[l].pitch = (nv30mt->level[l].pitch + 63) & ~63; + + 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 void +nv30_miptree_create(struct pipe_context *pipe, struct pipe_texture **pt) +{ + struct pipe_winsys *ws = pipe->winsys; + struct nv30_miptree *nv30mt; + + nv30mt = realloc(*pt, sizeof(struct nv30_miptree)); + if (!nv30mt) + return; + *pt = NULL; + + nv30_miptree_layout(nv30mt); + + nv30mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + nv30mt->total_size); + if (!nv30mt->buffer) { + free(nv30mt); + return; + } + + *pt = &nv30mt->base; +} + +static void +nv30_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + struct pipe_winsys *ws = pipe->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); + } +} + +void +nv30_init_miptree_functions(struct nv30_context *nv30) +{ + nv30->pipe.texture_create = nv30_miptree_create; + nv30->pipe.texture_release = nv30_miptree_release; +} + diff --git a/src/gallium/drivers/nv30/nv30_query.c b/src/gallium/drivers/nv30/nv30_query.c new file mode 100644 index 0000000000..71fdcfa24d --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_query.c @@ -0,0 +1,113 @@ +#include "pipe/p_context.h" +#include "pipe/p_util.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); + + if (nv30->nvws->res_alloc(nv30->query_heap, 1, NULL, &q->object)) + assert(0); + nv30->nvws->notifier_reset(nv30->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(); +} + +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->query, q->object->start); + if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) { + if (wait == FALSE) + return FALSE; + nvws->notifier_wait(nv30->query, q->object->start, + NV_NOTIFY_STATE_STATUS_COMPLETED, + 0); + } + + q->result = nvws->notifier_retval(nv30->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_shader.h b/src/gallium/drivers/nv30/nv30_shader.h new file mode 100644 index 0000000000..dd3a36f78f --- /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 (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 0000000000..53368561e0 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -0,0 +1,739 @@ +#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; + + 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_FUNC_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 unit, + void *hwcso) +{ + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_sampler_state *ps = hwcso; + + nv30->tex_sampler[unit] = ps; + 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 unit, + struct pipe_texture *miptree) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + nv30->tex_miptree[unit] = (struct nv30_miptree *)miptree; + 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; + + 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; + + 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; + + 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; + + 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_FUNC_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[4], *zeta; + uint32_t rt_enable, rt_format, w, h; + int i, colour_format = 0, zeta_format = 0; + + rt_enable = 0; + for (i = 0; i < 4; 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) { + BEGIN_RING(rankine, NV34TCL_COLOR0_PITCH, 1); + OUT_RING ( (rt[0]->pitch * rt[0]->cpp) | ( (zeta->pitch * zeta->cpp) << 16) ); + nv30->rt[0] = rt[0]->buffer; + } + + if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) { + BEGIN_RING(rankine, NV34TCL_COLOR1_PITCH, 2); + 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); +} + +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_buffer(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_buffer *vb) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + nv30->vtxbuf[index] = *vb; + + nv30->dirty |= NV30_NEW_ARRAYS; +} + +static void +nv30_set_vertex_element(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_element *ve) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + nv30->vtxelt[index] = *ve; + + 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_state = nv30_sampler_state_bind; + nv30->pipe.delete_sampler_state = nv30_sampler_state_delete; + nv30->pipe.set_sampler_texture = 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_buffer = nv30_set_vertex_buffer; + nv30->pipe.set_vertex_element = nv30_set_vertex_element; +} + diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h new file mode 100644 index 0000000000..233600f69a --- /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 { + const 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 { + const 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_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c new file mode 100644 index 0000000000..70b98836f0 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -0,0 +1,83 @@ +#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 */ + 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); + } + + /* 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_surface.c b/src/gallium/drivers/nv30/nv30_surface.c new file mode 100644 index 0000000000..974965679f --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_surface.c @@ -0,0 +1,137 @@ + +/************************************************************************** + * + * 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 boolean +nv30_surface_format_supported(struct pipe_context *pipe, + 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_U_L8: + case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static struct pipe_surface * +nv30_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = pipe->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_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; + + 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.is_format_supported = nv30_surface_format_supported; + nv30->pipe.get_tex_surface = nv30_get_tex_surface; + 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 0000000000..9e00cdac3f --- /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_VERTEX_ARRAY_FORMAT_TYPE_FLOAT; + case PIPE_FORMAT_TYPE_UNORM: + return NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_UBYTE; + default: + NOUVEAU_ERR("Unknown format 0x%08x\n", format); + return NV40TCL_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_VERTEX_ARRAY_FORMAT_TYPE_FLOAT: + { + float *v = map; + + BEGIN_RING(rankine, NV34TCL_VERTEX_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; + + 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_VERTEX_ARRAY_FORMAT_TYPE_FLOAT; + continue; + } + + ve = &nv30->vtxelt[hw]; + vb = &nv30->vtxbuf[ve->vertex_buffer_index]; + + if (vb->pitch == 0) { + vtxfmt[hw] = NV34TCL_VERTEX_ARRAY_FORMAT_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_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT) | + (nv30_vbo_ncomp(ve->src_format) << + NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_SHIFT) | + nv30_vbo_type(ve->src_format)); + } + + BEGIN_RING(rankine, NV34TCL_VERTEX_ARRAY_FORMAT(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_VERTEX_BUFFER_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_VERTEX_BUFFER_ADDRESS_DMA1); + } + + if (ib) { + BEGIN_RING(rankine, NV40TCL_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, NV40TCL_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); + 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 = NV40TCL_IDXBUF_FORMAT_TYPE_U16; + break; + case 4: + type = NV40TCL_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, NV40TCL_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, NV40TCL_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); + 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 0000000000..4a8269d5dd --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -0,0 +1,777 @@ +#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 "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); + 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); + + 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->u.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->vertprog.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->vertprog.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 (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 %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(rankine, NV34TCL_VP_UPLOAD_FROM_ID, 1); + OUT_RING (/*vp->exec->start*/0); + 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); + OUT_RING (0); + + nv30->vertprog.active = vp; +} + +void +nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp) +{ + if (vp->nr_consts) + free(vp->consts); + if (vp->nr_insns) + free(vp->insns); +} + diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile new file mode 100644 index 0000000000..2a9de4a2dc --- /dev/null +++ b/src/gallium/drivers/nv40/Makefile @@ -0,0 +1,29 @@ +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_state.c \ + nv40_state_emit.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 0000000000..2c4e8f01fd --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_clear.c @@ -0,0 +1,12 @@ +#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); +} diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c new file mode 100644 index 0000000000..8b5cc693de --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -0,0 +1,312 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" + +#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf +#define NV4X_GRCLASS4497_CHIPSETS 0x00005450 +#define NV6X_GRCLASS4497_CHIPSETS 0x00000088 + +static const char * +nv40_get_name(struct pipe_context *pipe) +{ + struct nv40_context *nv40 = nv40_context(pipe); + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", nv40->chipset); + return buffer; +} + +static const char * +nv40_get_vendor(struct pipe_context *pipe) +{ + return "nouveau"; +} + +static int +nv40_get_param(struct pipe_context *pipe, int param) +{ + 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 0; + 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; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv40_get_paramf(struct pipe_context *pipe, 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; + case PIPE_CAP_BITMAP_TEXCOORD_BIAS: + return 0.0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0.0; + } +} + +static void +nv40_flush(struct pipe_context *pipe, unsigned flags) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_winsys *nvws = nv40->nvws; + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(curie, 0x1fd8, 1); + OUT_RING (2); + BEGIN_RING(curie, 0x1fd8, 1); + OUT_RING (1); + } + + if (flags & PIPE_FLUSH_WAIT) { + nvws->notifier_reset(nv40->hw->sync, 0); + BEGIN_RING(curie, 0x104, 1); + OUT_RING (0); + BEGIN_RING(curie, 0x100, 1); + OUT_RING (0); + } + + FIRE_RING(); + + if (flags & PIPE_FLUSH_WAIT) + nvws->notifier_wait(nv40->hw->sync, 0, 0, 2000); +} + +static void +nv40_channel_takedown(struct nv40_channel_context *cnv40) +{ + struct nouveau_winsys *nvws = cnv40->nvws; + + nvws->res_free(&cnv40->vp_exec_heap); + nvws->res_free(&cnv40->vp_data_heap); + nvws->res_free(&cnv40->query_heap); + nvws->notifier_free(&cnv40->query); + nvws->notifier_free(&cnv40->sync); + nvws->grobj_free(&cnv40->curie); + free(cnv40); +} + +static struct nv40_channel_context * +nv40_channel_init(struct pipe_winsys *ws, struct nouveau_winsys *nvws, + unsigned chipset) +{ + struct nv40_channel_context *cnv40 = NULL; + struct nouveau_stateobj *so; + unsigned curie_class = 0; + int ret; + + 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; + } + + cnv40 = CALLOC(1, sizeof(struct nv40_channel_context)); + if (!cnv40) + return NULL; + cnv40->chipset = chipset; + cnv40->nvws = nvws; + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &cnv40->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv40_channel_takedown(cnv40); + return NULL; + } + + /* Query objects */ + ret = nvws->notifier_alloc(nvws, 32, &cnv40->query); + if (ret) { + NOUVEAU_ERR("Error initialising query objects: %d\n", ret); + nv40_channel_takedown(cnv40); + return NULL; + } + + ret = nvws->res_init(&cnv40->query_heap, 0, 32); + if (ret) { + NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); + nv40_channel_takedown(cnv40); + return NULL; + } + + /* Vtxprog resources */ + if (nvws->res_init(&cnv40->vp_exec_heap, 0, 512) || + nvws->res_init(&cnv40->vp_data_heap, 0, 256)) { + nv40_channel_takedown(cnv40); + return NULL; + } + + /* 3D object */ + ret = nvws->grobj_alloc(nvws, curie_class, &cnv40->curie); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return FALSE; + } + + /* Static curie initialisation */ + so = so_new(128, 0); + so_method(so, cnv40->curie, NV40TCL_DMA_NOTIFY, 1); + so_data (so, cnv40->sync->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_TEXTURE0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_COLOR1, 1); + so_data (so, nvws->channel->vram->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_COLOR0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_VTXBUF0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_FENCE, 2); + so_data (so, 0); + so_data (so, cnv40->query->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_UNK01AC, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, cnv40->curie, NV40TCL_DMA_COLOR2, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + + so_method(so, cnv40->curie, 0x1ea4, 3); + so_data (so, 0x00000010); + so_data (so, 0x01000100); + so_data (so, 0xff800006); + + /* vtxprog output routing */ + so_method(so, cnv40->curie, 0x1fc4, 1); + so_data (so, 0x06144321); + so_method(so, cnv40->curie, 0x1fc8, 2); + so_data (so, 0xedcba987); + so_data (so, 0x00000021); + so_method(so, cnv40->curie, 0x1fd0, 1); + so_data (so, 0x00171615); + so_method(so, cnv40->curie, 0x1fd4, 1); + so_data (so, 0x001b1a19); + + so_method(so, cnv40->curie, 0x1ef8, 1); + so_data (so, 0x0020ffff); + so_method(so, cnv40->curie, 0x1d64, 1); + so_data (so, 0x00d30000); + so_method(so, cnv40->curie, 0x1e94, 1); + so_data (so, 0x00000001); + + so_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws->channel, 0); + + return cnv40; +} + +static void +nv40_destroy(struct pipe_context *pipe) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + if (nv40->draw) + draw_destroy(nv40->draw); + + if (nv40->hw) { + if (--nv40->hw->refcount == 0) + nv40_channel_takedown(nv40->hw); + } + + free(nv40); +} + +struct pipe_context * +nv40_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, + unsigned chipset) +{ + struct nv40_context *nv40; + + nv40 = CALLOC(1, sizeof(struct nv40_context)); + if (!nv40) + return NULL; + + nv40->hw = nv40_channel_init(ws, nvws, chipset); + if (!nv40->hw) { + nv40_destroy(&nv40->pipe); + return NULL; + } + + nv40->chipset = chipset; + nv40->nvws = nvws; + + nv40->pipe.winsys = ws; + nv40->pipe.destroy = nv40_destroy; + nv40->pipe.get_name = nv40_get_name; + nv40->pipe.get_vendor = nv40_get_vendor; + nv40->pipe.get_param = nv40_get_param; + nv40->pipe.get_paramf = nv40_get_paramf; + 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); + nv40_init_miptree_functions(nv40); + + nv40->draw = draw_create(); + assert(nv40->draw); + 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 0000000000..f511759e3b --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -0,0 +1,153 @@ +#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_channel_context *ctx = nv40->hw +#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); + +#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) + +struct nv40_channel_context { + struct nouveau_winsys *nvws; + unsigned refcount; + + unsigned chipset; + + /* 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; +}; + +struct nv40_context { + struct pipe_context pipe; + struct nouveau_winsys *nvws; + + struct nv40_channel_context *hw; + struct draw_context *draw; + + int chipset; + + uint32_t dirty; + + struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; + struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; + unsigned dirty_samplers; + unsigned fp_samplers; + unsigned vp_samplers; + + struct nouveau_stateobj *so_framebuffer; + struct nouveau_stateobj *so_fragtex[16]; + struct nouveau_stateobj *so_vtxbuf; + struct nouveau_stateobj *so_blend; + struct nouveau_stateobj *so_rast; + struct nouveau_stateobj *so_zsa; + struct nouveau_stateobj *so_bcol; + struct nouveau_stateobj *so_scissor; + struct nouveau_stateobj *so_viewport; + struct nouveau_stateobj *so_stipple; + + struct { + struct nv40_vertex_program *active; + + struct nv40_vertex_program *current; + struct pipe_buffer *constant_buf; + } vertprog; + + struct { + struct nv40_fragment_program *active; + + struct nv40_fragment_program *current; + struct pipe_buffer *constant_buf; + } fragprog; + + struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; +}; + +static INLINE struct nv40_context * +nv40_context(struct pipe_context *pipe) +{ + return (struct nv40_context *)pipe; +} + +extern void nv40_init_state_functions(struct nv40_context *nv40); +extern void nv40_init_surface_functions(struct nv40_context *nv40); +extern void nv40_init_miptree_functions(struct nv40_context *nv40); +extern void nv40_init_query_functions(struct nv40_context *nv40); + +/* nv40_draw.c */ +extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40); + +/* nv40_vertprog.c */ +extern void nv40_vertprog_translate(struct nv40_context *, + struct nv40_vertex_program *); +extern void nv40_vertprog_bind(struct nv40_context *, + struct nv40_vertex_program *); +extern void nv40_vertprog_destroy(struct nv40_context *, + struct nv40_vertex_program *); + +/* nv40_fragprog.c */ +extern void nv40_fragprog_translate(struct nv40_context *, + struct nv40_fragment_program *); +extern void nv40_fragprog_bind(struct nv40_context *, + struct nv40_fragment_program *); +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 void nv40_emit_hw_state(struct nv40_context *nv40); +extern void nv40_state_tex_update(struct nv40_context *nv40); + +/* 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_dma.h b/src/gallium/drivers/nv40/nv40_dma.h new file mode 100644 index 0000000000..1fb8267768 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_dma.h @@ -0,0 +1,66 @@ +#ifndef __NV40_DMA_H__ +#define __NV40_DMA_H__ + +#include "pipe/nouveau/nouveau_winsys.h" + +#define OUT_RING(data) do { \ + (*nv40->nvws->channel->pushbuf->cur++) = (data); \ +} while(0) + +#define OUT_RINGp(src,size) do { \ + memcpy(nv40->nvws->channel->pushbuf->cur, (src), (size) * 4); \ + nv40->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 { \ + if (nv40->nvws->channel->pushbuf->remaining < ((size) + 1)) \ + nv40->nvws->push_flush(nv40->nvws->channel, ((size) + 1)); \ + OUT_RING((nv40->obj->subc << 13) | ((size) << 18) | (mthd)); \ + nv40->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() do { \ + nv40->nvws->push_flush(nv40->nvws->channel, 0); \ +} while(0) + +#define OUT_RELOC(bo,data,flags,vor,tor) do { \ + nv40->nvws->push_reloc(nv40->nvws->channel, \ + nv40->nvws->channel->pushbuf->cur, \ + (struct nouveau_bo *)(bo), \ + (data), (flags), (vor), (tor)); \ + OUT_RING(0); \ +} 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, \ + nv40->nvws->channel->vram->handle, \ + nv40->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) + +#endif diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c new file mode 100644 index 0000000000..a39bb85e99 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -0,0 +1,62 @@ +#include "draw/draw_private.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" + +struct nv40_draw_stage { + struct draw_stage draw; + struct nv40_context *nv40; +}; + +static void +nv40_draw_point(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv40_draw_line(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv40_draw_tri(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv40_draw_flush(struct draw_stage *draw, unsigned flags) +{ +} + +static void +nv40_draw_reset_stipple_counter(struct draw_stage *draw) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv40_draw_destroy(struct draw_stage *draw) +{ + free(draw); +} + +struct draw_stage * +nv40_draw_render_stage(struct nv40_context *nv40) +{ + struct nv40_draw_stage *nv40draw = CALLOC_STRUCT(nv40_draw_stage); + + nv40draw->nv40 = nv40; + nv40draw->draw.draw = nv40->draw; + nv40draw->draw.point = nv40_draw_point; + nv40draw->draw.line = nv40_draw_line; + nv40draw->draw.tri = nv40_draw_tri; + nv40draw->draw.flush = nv40_draw_flush; + nv40draw->draw.reset_stipple_counter = nv40_draw_reset_stipple_counter; + nv40draw->draw.destroy = nv40_draw_destroy; + + return &nv40draw->draw; +} + diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c new file mode 100644 index 0000000000..07a418c1e9 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -0,0 +1,842 @@ +#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]; + + 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 nv40_sreg imm[MAX_IMM]; + unsigned nr_imm; +}; + +static INLINE struct nv40_sreg +temp(struct nv40_fpc *fpc) +{ + int idx; + + idx = fpc->temp_temp_count++; + idx += fpc->high_temp + 1; + return nv40_sr(NV40SR_TEMP, idx); +} + +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: + grow_insns(fpc, 4); + 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; + 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 = nv40_sr(NV40SR_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 nv40_sr(NV40SR_OUTPUT, 0); + else + return nv40_sr(NV40SR_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 nv40_sreg +tgsi_dst(struct nv40_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 nv40_sr(NV40SR_OUTPUT, 0); + else + return nv40_sr(NV40SR_OUTPUT, 1); + break; + case TGSI_FILE_TEMPORARY: + idx = fdst->DstRegister.Index + 1; + if (fpc->high_temp < idx) + fpc->high_temp = idx; + return nv40_sr(NV40SR_TEMP, idx); + 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; + 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 = 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_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_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: + if (finst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide == + TGSI_EXTSWIZZLE_W) { + tex(fpc, sat, TXP, unit, dst, mask, src[0], none, none); + } else + 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_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 +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->u.DeclarationRange.First] = hw; + return TRUE; +} + +static boolean +nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, + const struct tgsi_full_declaration *fdec) +{ + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + fpc->depth_id = fdec->u.DeclarationRange.First; + break; + case TGSI_SEMANTIC_COLOR: + fpc->colour_id = fdec->u.DeclarationRange.First; + break; + default: + NOUVEAU_ERR("bad output semantic\n"); + return FALSE; + } + + return TRUE; +} + +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->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 (!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; + default: + break; + } + } + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *imm; + float vals[4]; + + imm = &parse.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; + 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; + fp->on_hw = FALSE; +out_err: + tgsi_parse_free(&parse); + free(fpc); +} + +void +nv40_fragprog_bind(struct nv40_context *nv40, struct nv40_fragment_program *fp) +{ + struct pipe_winsys *ws = nv40->pipe.winsys; + struct nouveau_stateobj *so; + int i; + + if (!fp->translated) { + nv40_fragprog_translate(nv40, fp); + if (!fp->translated) + assert(0); + } + + if (fp->nr_consts) { + float *map = ws->buffer_map(ws, nv40->fragprog.constant_buf, + 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)); + fp->on_hw = 0; + } + ws->buffer_unmap(ws, nv40->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; + } + + so = so_new(4, 1); + so_method(so, nv40->hw->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->hw->curie, NV40TCL_FP_CONTROL, 1); + so_data (so, fp->fp_control); + + so_emit(nv40->nvws, so); + so_ref(so, &fp->so); + so_ref(NULL, &so); + + nv40->fragprog.active = fp; +} + +void +nv40_fragprog_destroy(struct nv40_context *nv40, + struct nv40_fragment_program *fp) +{ + if (fp->insn_len) + free(fp->insn); +} + diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c new file mode 100644 index 0000000000..5af5fbe746 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -0,0 +1,151 @@ +#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), + _(U_L8 , L8 , S1, S1, S1, ONE, X, X, X, X), + _(U_A8 , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X), + _(U_I8 , L8 , S1, S1, S1, S1, X, X, X, X), + _(U_A8_L8 , 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 nv40_texture_format * +nv40_fragtex_format(uint pipe_format) +{ + struct nv40_texture_format *tf = nv40_texture_formats; + + while (tf->defined) { + if (tf->pipe == pipe_format) + return tf; + tf++; + } + + return NULL; +} + + +static void +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; + } + + 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->hw->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->hw->curie, NV40TCL_TEX_SIZE1(unit), 1); + so_data (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); + + so_emit(nv40->nvws, so); + so_ref (so, &nv40->so_fragtex[unit]); + so_ref (NULL, &so); +} + +void +nv40_fragtex_bind(struct nv40_context *nv40) +{ + struct nv40_fragment_program *fp = nv40->fragprog.active; + unsigned samplers, unit; + + samplers = nv40->fp_samplers & ~fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + so_ref(NULL, &nv40->so_fragtex[unit]); + BEGIN_RING(curie, NV40TCL_TEX_ENABLE(unit), 1); + OUT_RING (0); + } + + samplers = nv40->dirty_samplers & fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + nv40_fragtex_build(nv40, unit); + } + + nv40->fp_samplers = fp->samplers; +} + diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c new file mode 100644 index 0000000000..92e6b3a43d --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -0,0 +1,104 @@ +#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; + + 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; + } + + for (l = 0; l <= pt->last_level; l++) { + pt->width[l] = width; + pt->height[l] = height; + pt->depth[l] = depth; + + if (swizzled) + nv40mt->level[l].pitch = pt->width[l] * pt->cpp; + else + nv40mt->level[l].pitch = pt->width[0] * pt->cpp; + nv40mt->level[l].pitch = (nv40mt->level[l].pitch + 63) & ~63; + + 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_context *pipe, const struct pipe_texture *pt) +{ + struct pipe_winsys *ws = pipe->winsys; + struct nv40_miptree *mt; + + mt = MALLOC(sizeof(struct nv40_miptree)); + if (!mt) + return NULL; + mt->base = *pt; + nv40_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 +nv40_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + struct pipe_winsys *ws = pipe->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); + } +} + +void +nv40_init_miptree_functions(struct nv40_context *nv40) +{ + nv40->pipe.texture_create = nv40_miptree_create; + nv40->pipe.texture_release = nv40_miptree_release; +} + diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c new file mode 100644 index 0000000000..8bca2788b9 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -0,0 +1,113 @@ +#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); + + if (nv40->nvws->res_alloc(nv40->hw->query_heap, 1, NULL, &q->object)) + assert(0); + nv40->nvws->notifier_reset(nv40->hw->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(); +} + +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->hw->query, + q->object->start); + if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) { + if (wait == FALSE) + return FALSE; + nvws->notifier_wait(nv40->hw->query, q->object->start, + NV_NOTIFY_STATE_STATUS_COMPLETED, + 0); + } + + q->result = nvws->notifier_retval(nv40->hw->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_shader.h b/src/gallium/drivers/nv40/nv40_shader.h new file mode 100644 index 0000000000..5909c70713 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_shader.h @@ -0,0 +1,554 @@ +#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) + +#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 diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c new file mode 100644 index 0000000000..713f31dbb1 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -0,0 +1,823 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.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->hw->curie; + 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); + + return (void *)so; +} + +static void +nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + so_ref(hwcso, &nv40->so_blend); + nv40->dirty |= NV40_NEW_BLEND; +} + +static void +nv40_blend_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nouveau_stateobj *so = hwcso; + + so_ref(NULL, &so); +} + + +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 unit, + void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_sampler_state *ps = hwcso; + + nv40->tex_sampler[unit] = ps; + nv40->dirty_samplers |= (1 << unit); +} + +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 unit, + struct pipe_texture *miptree) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->tex_miptree[unit] = (struct nv40_miptree *)miptree; + nv40->dirty_samplers |= (1 << unit); +} + +static void * +nv40_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nouveau_stateobj *so = so_new(32, 0); + + /*XXX: ignored: + * light_twoside + * offset_cw/ccw -nohw + * scissor + * point_smooth -nohw + * multisample + * offset_units / offset_scale + */ + + so_method(so, nv40->hw->curie, NV40TCL_SHADE_MODEL, 1); + so_data (so, cso->flatshade ? NV40TCL_SHADE_MODEL_FLAT : + NV40TCL_SHADE_MODEL_SMOOTH); + + so_method(so, nv40->hw->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, nv40->hw->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, nv40->hw->curie, NV40TCL_POINT_SIZE, 1); + so_data (so, fui(cso->point_size)); + + so_method(so, nv40->hw->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, 0); + 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, 0); + 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, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, cso->poly_stipple_enable ? 1 : 0); + + so_method(so, nv40->hw->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); + } + + return (void *)so; +} + +static void +nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + so_ref(hwcso, &nv40->so_rast); + nv40->dirty |= NV40_NEW_RAST; +} + +static void +nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nouveau_stateobj *so = hwcso; + + so_ref(NULL, &so); +} + +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 nouveau_stateobj *so = so_new(32, 0); + + so_method(so, nv40->hw->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, nv40->hw->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, nv40->hw->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, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); + so_data (so, 0); + } + + if (cso->stencil[1].enabled) { + so_method(so, nv40->hw->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, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 1); + so_data (so, 0); + } + + return (void *)so; +} + +static void +nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + so_ref(hwcso, &nv40->so_zsa); + nv40->dirty |= NV40_NEW_ZSA; +} + +static void +nv40_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nouveau_stateobj *so = hwcso; + + so_ref(NULL, &so); +} + +static void * +nv40_vp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv40_vertex_program *vp; + + vp = CALLOC(1, sizeof(struct nv40_vertex_program)); + vp->pipe = cso; + + return (void *)vp; +} + +static void +nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_vertex_program *vp = hwcso; + + nv40->vertprog.current = vp; + nv40->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; + + 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; + + return (void *)fp; +} + +static void +nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_fragment_program *fp = hwcso; + + nv40->fragprog.current = fp; + 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); + struct nouveau_stateobj *so = so_new(2, 0); + + so_method(so, nv40->hw->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->so_bcol); + so_ref(NULL, &so); + nv40->dirty |= NV40_NEW_BCOL; +} + +static void +nv40_set_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *clip) +{ +} + +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); + + if (shader == PIPE_SHADER_VERTEX) { + nv40->vertprog.constant_buf = buf->buffer; + nv40->dirty |= NV40_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nv40->fragprog.constant_buf = buf->buffer; + 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); + struct pipe_surface *rt[4], *zeta; + uint32_t rt_enable, rt_format, w, h; + 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; + + rt_enable = 0; + for (i = 0; i < 4; 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 |= (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) { + 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 = 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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->curie, NV40TCL_COLOR3_PITCH, 1); + so_data (so, rt[3]->pitch * rt[3]->cpp); + } + + if (zeta_format) { + so_method(so, nv40->hw->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->hw->curie, NV40TCL_ZETA_OFFSET, 1); + so_reloc (so, zeta->buffer, zeta->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->hw->curie, NV40TCL_ZETA_PITCH, 1); + so_data (so, zeta->pitch * zeta->cpp); + } + + so_method(so, nv40->hw->curie, NV40TCL_RT_ENABLE, 1); + so_data (so, rt_enable); + so_method(so, nv40->hw->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->hw->curie, NV40TCL_VIEWPORT_HORIZ, 2); + so_data (so, (w << 16) | 0); + so_data (so, (h << 16) | 0); + so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); + so_data (so, ((w - 1) << 16) | 0); + so_data (so, ((h - 1) << 16) | 0); + + so_ref(so, &nv40->so_framebuffer); + so_ref(NULL, &so); + 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); + struct nouveau_stateobj *so = so_new(33, 0); + unsigned i; + + so_method(so, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); + for (i = 0; i < 32; i++) + so_data(so, stipple->stipple[i]); + + so_ref(so, &nv40->so_stipple); + so_ref(NULL, &so); + 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); + struct nouveau_stateobj *so = so_new(3, 0); + + so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); + so_data (so, ((s->maxx - s->minx) << 16) | s->minx); + so_data (so, ((s->maxy - s->miny) << 16) | s->miny); + + so_ref(so, &nv40->so_scissor); + so_ref(NULL, &so); + 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); + struct nouveau_stateobj *so = so_new(9, 0); + + so_method(so, nv40->hw->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_ref(so, &nv40->so_viewport); + so_ref(NULL, &so); + nv40->dirty |= NV40_NEW_VIEWPORT; +} + +static void +nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_buffer *vb) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->vtxbuf[index] = *vb; + + nv40->dirty |= NV40_NEW_ARRAYS; +} + +static void +nv40_set_vertex_element(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_element *ve) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->vtxelt[index] = *ve; + + nv40->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_state = nv40_sampler_state_bind; + nv40->pipe.delete_sampler_state = nv40_sampler_state_delete; + nv40->pipe.set_sampler_texture = 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_vertex_buffer = nv40_set_vertex_buffer; + nv40->pipe.set_vertex_element = nv40_set_vertex_element; +} + diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h new file mode 100644 index 0000000000..e82ab9de98 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -0,0 +1,80 @@ +#ifndef __NV40_STATE_H__ +#define __NV40_STATE_H__ + +#include "pipe/p_state.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 { + const struct pipe_shader_state *pipe; + + boolean translated; + 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; +}; + +struct nv40_fragment_program_data { + unsigned offset; + unsigned index; +}; + +struct nv40_fragment_program { + const struct pipe_shader_state *pipe; + + boolean translated; + boolean on_hw; + 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_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c new file mode 100644 index 0000000000..a10c995548 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -0,0 +1,77 @@ +#include "nv40_context.h" +#include "nv40_state.h" + +/* Emit relocs for every referenced buffer. + * + * This is to ensure the bufmgr has an accurate idea of how + * the buffer is used. These relocs appear in the push buffer as + * NOPs, and will only be turned into state changes if a buffer + * actually moves. + */ +static void +nv40_state_emit_dummy_relocs(struct nv40_context *nv40) +{ + unsigned i; + + so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer); + for (i = 0; i < 16; i++) { + if (!(nv40->fp_samplers & (1 << i))) + continue; + so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]); + } + so_emit_reloc_markers(nv40->nvws, nv40->fragprog.active->so); +} + +void +nv40_emit_hw_state(struct nv40_context *nv40) +{ + if (nv40->dirty & NV40_NEW_FB) + so_emit(nv40->nvws, nv40->so_framebuffer); + + if (nv40->dirty & NV40_NEW_BLEND) + so_emit(nv40->nvws, nv40->so_blend); + + if (nv40->dirty & NV40_NEW_RAST) + so_emit(nv40->nvws, nv40->so_rast); + + if (nv40->dirty & NV40_NEW_ZSA) + so_emit(nv40->nvws, nv40->so_zsa); + + if (nv40->dirty & NV40_NEW_BCOL) + so_emit(nv40->nvws, nv40->so_bcol); + + if (nv40->dirty & NV40_NEW_SCISSOR) + so_emit(nv40->nvws, nv40->so_scissor); + + if (nv40->dirty & NV40_NEW_VIEWPORT) + so_emit(nv40->nvws, nv40->so_viewport); + + if (nv40->dirty & NV40_NEW_STIPPLE) + so_emit(nv40->nvws, nv40->so_stipple); + + if (nv40->dirty & NV40_NEW_FRAGPROG) { + nv40_fragprog_bind(nv40, nv40->fragprog.current); + /*XXX: clear NV40_NEW_FRAGPROG if no new program uploaded */ + } + + if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { + nv40_fragtex_bind(nv40); + + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (2); + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (1); + nv40->dirty &= ~NV40_NEW_FRAGPROG; + } + + if (nv40->dirty & NV40_NEW_VERTPROG) { + nv40_vertprog_bind(nv40, nv40->vertprog.current); + nv40->dirty &= ~NV40_NEW_VERTPROG; + } + + nv40->dirty_samplers = 0; + nv40->dirty = 0; + + nv40_state_emit_dummy_relocs(nv40); +} + diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c new file mode 100644 index 0000000000..9726ab4e4d --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -0,0 +1,137 @@ + +/************************************************************************** + * + * 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 boolean +nv40_surface_format_supported(struct pipe_context *pipe, + 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_U_L8: + case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static struct pipe_surface * +nv40_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = pipe->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_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; + + 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.is_format_supported = nv40_surface_format_supported; + nv40->pipe.get_tex_surface = nv40_get_tex_surface; + 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 0000000000..fa827ef0c5 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -0,0 +1,424 @@ +#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" + +static INLINE int +nv40_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 +nv40_vbo_type(uint format) +{ + switch (pf_type(format)) { + case PIPE_FORMAT_TYPE_FLOAT: + return NV40TCL_VTXFMT_TYPE_FLOAT; + case PIPE_FORMAT_TYPE_UNORM: + return NV40TCL_VTXFMT_TYPE_UBYTE; + default: + NOUVEAU_ERR("Unknown format 0x%08x\n", format); + return NV40TCL_VTXFMT_TYPE_FLOAT; + } +} + +static boolean +nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, + struct pipe_vertex_element *ve, + struct pipe_vertex_buffer *vb) +{ + struct pipe_winsys *ws = nv40->pipe.winsys; + int type, ncomp; + void *map; + + type = nv40_vbo_type(ve->src_format); + ncomp = nv40_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 NV40TCL_VTXFMT_TYPE_FLOAT: + { + float *v = map; + + BEGIN_RING(curie, NV40TCL_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 +nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib, + unsigned ib_format) +{ + struct nv40_vertex_program *vp = nv40->vertprog.active; + struct nouveau_stateobj *vtxbuf, *vtxfmt; + unsigned inputs, hw, num_hw; + unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + + inputs = vp->ir; + for (hw = 0; hw < 16 && inputs; hw++) { + if (inputs & (1 << hw)) { + num_hw = hw; + inputs &= ~(1 << hw); + } + } + num_hw++; + + vtxbuf = so_new(20, 18); + so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + vtxfmt = so_new(17, 0); + so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), 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))) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); + continue; + } + + ve = &nv40->vtxelt[hw]; + vb = &nv40->vtxbuf[ve->vertex_buffer_index]; + + if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); + continue; + } + + 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) | + (nv40_vbo_ncomp(ve->src_format) << + NV40TCL_VTXFMT_SIZE_SHIFT) | + nv40_vbo_type(ve->src_format))); + } + + if (ib) { + so_method(vtxbuf, nv40->hw->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_emit(nv40->nvws, vtxfmt); + so_emit(nv40->nvws, vtxbuf); + so_ref (vtxbuf, &nv40->so_vtxbuf); + so_ref (NULL, &vtxbuf); + so_ref (NULL, &vtxfmt); +} + +static boolean +nv40_vbo_validate_state(struct nv40_context *nv40, + struct pipe_buffer *ib, unsigned ib_format) +{ + unsigned vdn = nv40->dirty & NV40_NEW_ARRAYS; + + nv40_emit_hw_state(nv40); + if (vdn || ib) { + nv40_vbo_arrays_update(nv40, ib, ib_format); + nv40->dirty &= ~NV40_NEW_ARRAYS; + } + + so_emit_reloc_markers(nv40->nvws, nv40->so_vtxbuf); + + BEGIN_RING(curie, 0x1710, 1); + OUT_RING (0); /* vtx cache flush */ + + return TRUE; +} + +boolean +nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, + unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + unsigned nr; + boolean ret; + + ret = nv40_vbo_validate_state(nv40, NULL, 0); + if (!ret) { + NOUVEAU_ERR("state validate failed\n"); + return FALSE; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + nr = (count & 0xff); + if (nr) { + BEGIN_RING(curie, NV40TCL_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(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); + + pipe->flush(pipe, 0); + return TRUE; +} + +static INLINE void +nv40_draw_elements_u08(struct nv40_context *nv40, void *ib, + unsigned start, unsigned count) +{ + uint8_t *elts = (uint8_t *)ib + start; + int push, i; + + if (count & 1) { + BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; count--; + } + + while (count) { + push = MIN2(count, 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]); + + count -= push; + elts += push; + } +} + +static INLINE void +nv40_draw_elements_u16(struct nv40_context *nv40, void *ib, + unsigned start, unsigned count) +{ + uint16_t *elts = (uint16_t *)ib + start; + int push, i; + + if (count & 1) { + BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; count--; + } + + while (count) { + push = MIN2(count, 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]); + + count -= push; + elts += push; + } +} + +static INLINE void +nv40_draw_elements_u32(struct nv40_context *nv40, void *ib, + unsigned start, unsigned count) +{ + uint32_t *elts = (uint32_t *)ib + start; + int push; + + while (count) { + push = MIN2(count, 2047); + + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U32, push); + OUT_RINGp (elts, push); + + count -= push; + elts += push; + } +} + +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; + boolean ret; + void *map; + + ret = nv40_vbo_validate_state(nv40, 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(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + switch (ib_size) { + case 1: + nv40_draw_elements_u08(nv40, map, start, count); + break; + case 2: + nv40_draw_elements_u16(nv40, map, start, count); + break; + case 4: + nv40_draw_elements_u32(nv40, map, start, count); + break; + default: + NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); + break; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + ws->buffer_unmap(ws, ib); + + return TRUE; +} + +static boolean +nv40_draw_elements_vbo(struct pipe_context *pipe, + struct pipe_buffer *ib, unsigned ib_size, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + unsigned nr, type; + boolean ret; + + switch (ib_size) { + case 2: + type = NV40TCL_IDXBUF_FORMAT_TYPE_U16; + break; + case 4: + type = NV40TCL_IDXBUF_FORMAT_TYPE_U32; + break; + default: + NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); + return FALSE; + } + + ret = nv40_vbo_validate_state(nv40, ib, type); + if (!ret) { + NOUVEAU_ERR("failed state validation\n"); + return FALSE; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + nr = (count & 0xff); + if (nr) { + BEGIN_RING(curie, NV40TCL_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(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); + + 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); + + /* 0x4497 doesn't support real index buffers, and there doesn't appear + * to be support on any chipset for 8-bit indices. + */ + if (nv40->hw->curie->grclass == NV44TCL || indexSize == 1) { + nv40_draw_elements_inline(pipe, indexBuffer, indexSize, + mode, start, count); + } else { + nv40_draw_elements_vbo(pipe, indexBuffer, indexSize, + mode, start, count); + } + + pipe->flush(pipe, 0); + return TRUE; +} + + diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c new file mode 100644 index 0000000000..9f4738b830 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -0,0 +1,790 @@ +#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 "nv40_context.h" +#include "nv40_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 "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)) + +struct nv40_vpc { + struct nv40_vertex_program *vp; + + struct nv40_vertex_program_exec *vpi; + + unsigned output_map[PIPE_MAX_SHADER_OUTPUTS]; + + int high_temp; + int temp_temp_count; + + struct nv40_sreg *imm; + unsigned nr_imm; +}; + +static struct nv40_sreg +temp(struct nv40_vpc *vpc) +{ + int idx; + + idx = vpc->temp_temp_count++; + idx += vpc->high_temp + 1; + return nv40_sr(NV40SR_TEMP, idx); +} + +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; + 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: + if (vpc->high_temp < fsrc->SrcRegister.Index) + vpc->high_temp = fsrc->SrcRegister.Index; + src = nv40_sr(NV40SR_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 = nv40_sr(NV40SR_OUTPUT, + vpc->output_map[fdst->DstRegister.Index]); + + break; + case TGSI_FILE_TEMPORARY: + dst = nv40_sr(NV40SR_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 +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; + 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 +nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, + const struct tgsi_full_declaration *fdec) +{ + int hw; + + switch (fdec->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: + hw = NV40_VP_INST_DEST_POS; + 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->output_map[fdec->u.DeclarationRange.First] = hw; + return TRUE; +} + +static boolean +nv40_vertprog_prepare(struct nv40_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 nv40_sreg)); + assert(vpc->imm); + } + + return TRUE; +} + +void +nv40_vertprog_translate(struct nv40_context *nv40, + struct nv40_vertex_program *vp) +{ + struct tgsi_parse_context parse; + struct nv40_vpc *vpc = NULL; + + vpc = CALLOC(1, sizeof(struct nv40_vpc)); + if (!vpc) + return; + vpc->vp = vp; + vpc->high_temp = -1; + + if (!nv40_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 (!nv40_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 (!nv40_vertprog_parse_instruction(vpc, finst)) + goto out_err; + } + break; + default: + break; + } + } + + vp->insns[vp->nr_insns - 1].data[3] |= NV40_VP_INST_LAST; + vp->translated = TRUE; +out_err: + tgsi_parse_free(&parse); + free(vpc); +} + +void +nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) +{ + struct nouveau_winsys *nvws = nv40->nvws; + struct pipe_winsys *ws = nv40->pipe.winsys; + boolean upload_code = FALSE, upload_data = FALSE; + int i; + + /* Translate TGSI shader into hw bytecode */ + if (!vp->translated) { + nv40_vertprog_translate(nv40, vp); + if (!vp->translated) + assert(0); + } + + /* Allocate hw vtxprog exec slots */ + if (!vp->exec) { + struct nouveau_resource *heap = nv40->hw->vp_exec_heap; + 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); + } + + upload_code = TRUE; + } + + /* Allocate hw vtxprog const slots */ + if (vp->nr_consts && !vp->data) { + struct nouveau_resource *heap = nv40->hw->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 (nv40->vertprog.constant_buf) { + map = ws->buffer_map(ws, nv40->vertprog.constant_buf, + 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 (map) { + ws->buffer_unmap(ws, nv40->vertprog.constant_buf); + } + } + + /* 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); + } + } + + BEGIN_RING(curie, NV40TCL_VP_START_FROM_ID, 1); + OUT_RING (vp->exec->start); + BEGIN_RING(curie, NV40TCL_VP_ATTRIB_EN, 2); + OUT_RING (vp->ir); + OUT_RING (vp->or); + + nv40->vertprog.active = vp; +} + +void +nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp) +{ + if (vp->nr_consts) + free(vp->consts); + if (vp->nr_insns) + free(vp->insns); +} + diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile new file mode 100644 index 0000000000..68eb49ff2a --- /dev/null +++ b/src/gallium/drivers/nv50/Makefile @@ -0,0 +1,25 @@ +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_state.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 0000000000..552b92f72e --- /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 0000000000..3c5a54bfd3 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -0,0 +1,202 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv50_context.h" + +static boolean +nv50_is_format_supported(struct pipe_context *pipe, enum pipe_format format, + uint type) +{ + return FALSE; +} + +static const char * +nv50_get_name(struct pipe_context *pipe) +{ + struct nv50_context *nv50 = (struct nv50_context *)pipe; + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", nv50->chipset); + return buffer; +} + +static const char * +nv50_get_vendor(struct pipe_context *pipe) +{ + return "nouveau"; +} + +static int +nv50_get_param(struct pipe_context *pipe, 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; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv50_get_paramf(struct pipe_context *pipe, 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_flush(struct pipe_context *pipe, unsigned flags) +{ + struct nv50_context *nv50 = (struct nv50_context *)pipe; + struct nouveau_winsys *nvws = nv50->nvws; + + if (flags & PIPE_FLUSH_WAIT) { + nvws->notifier_reset(nv50->sync, 0); + BEGIN_RING(tesla, 0x104, 1); + OUT_RING (0); + BEGIN_RING(tesla, 0x100, 1); + OUT_RING (0); + } + + FIRE_RING(); + + if (flags & PIPE_FLUSH_WAIT) + nvws->notifier_wait(nv50->sync, 0, 0, 2000); +} + +static void +nv50_destroy(struct pipe_context *pipe) +{ + struct nv50_context *nv50 = (struct nv50_context *)pipe; + + draw_destroy(nv50->draw); + free(nv50); +} + +static boolean +nv50_init_hwctx(struct nv50_context *nv50, int tesla_class) +{ + struct nouveau_winsys *nvws = nv50->nvws; + int ret; + + if ((ret = nvws->grobj_alloc(nvws, tesla_class, &nv50->tesla))) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return FALSE; + } + + BEGIN_RING(tesla, NV50TCL_DMA_NOTIFY, 1); + OUT_RING (nv50->sync->handle); + + FIRE_RING (); + return TRUE; +} + +#define GRCLASS5097_CHIPSETS 0x00000000 +#define GRCLASS8297_CHIPSETS 0x00000010 +struct pipe_context * +nv50_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws, + unsigned chipset) +{ + struct nv50_context *nv50; + int tesla_class, ret; + + if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) { + NOUVEAU_ERR("Not a G8x chipset\n"); + return NULL; + } + + if (GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) { + tesla_class = 0x5097; + } else + if (GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) { + tesla_class = 0x8297; + } else { + NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset); + return NULL; + } + + nv50 = CALLOC_STRUCT(nv50_context); + if (!nv50) + return NULL; + nv50->chipset = chipset; + nv50->nvws = nvws; + + if ((ret = nvws->notifier_alloc(nvws, 1, &nv50->sync))) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + free(nv50); + return NULL; + } + + if (!nv50_init_hwctx(nv50, tesla_class)) { + free(nv50); + return NULL; + } + + nv50->pipe.winsys = pipe_winsys; + + nv50->pipe.destroy = nv50_destroy; + nv50->pipe.is_format_supported = nv50_is_format_supported; + nv50->pipe.get_name = nv50_get_name; + nv50->pipe.get_vendor = nv50_get_vendor; + nv50->pipe.get_param = nv50_get_param; + nv50->pipe.get_paramf = nv50_get_paramf; + + 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_miptree_functions(nv50); + 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 0000000000..b99254f619 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -0,0 +1,57 @@ +#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_context *ctx = nv50 +#include "nouveau/nouveau_push.h" + +#include "nv50_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); + +struct nv50_context { + struct pipe_context pipe; + struct nouveau_winsys *nvws; + + struct draw_context *draw; + + int chipset; + struct nouveau_grobj *tesla; + struct nouveau_notifier *sync; +}; + + +extern void nv50_init_miptree_functions(struct nv50_context *nv50); +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); + +/* 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); + +#endif diff --git a/src/gallium/drivers/nv50/nv50_draw.c b/src/gallium/drivers/nv50/nv50_draw.c new file mode 100644 index 0000000000..c6ed6838c6 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_draw.c @@ -0,0 +1,55 @@ +#include "draw/draw_private.h" +#include "pipe/p_util.h" + +#include "nv50_context.h" + +struct nv50_draw_stage { + struct draw_stage draw; + struct nv50_context *nv50; +}; + +static void +nv50_draw_point(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv50_draw_line(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv50_draw_tri(struct draw_stage *draw, struct prim_header *prim) +{ + NOUVEAU_ERR("\n"); +} + +static void +nv50_draw_flush(struct draw_stage *draw, unsigned flags) +{ +} + +static void +nv50_draw_reset_stipple_counter(struct draw_stage *draw) +{ + NOUVEAU_ERR("\n"); +} + +struct draw_stage * +nv50_draw_render_stage(struct nv50_context *nv50) +{ + struct nv50_draw_stage *nv50draw = CALLOC_STRUCT(nv50_draw_stage); + + nv50draw->nv50 = nv50; + nv50draw->draw.draw = nv50->draw; + nv50draw->draw.point = nv50_draw_point; + nv50draw->draw.line = nv50_draw_line; + nv50draw->draw.tri = nv50_draw_tri; + nv50draw->draw.flush = nv50_draw_flush; + nv50draw->draw.reset_stipple_counter = nv50_draw_reset_stipple_counter; + + return &nv50draw->draw; +} + diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c new file mode 100644 index 0000000000..0c034ed438 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -0,0 +1,25 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" + +#include "nv50_context.h" + +static struct pipe_texture * +nv50_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) +{ + NOUVEAU_ERR("unimplemented\n"); + return NULL; +} + +static void +nv50_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + NOUVEAU_ERR("unimplemented\n"); +} + +void +nv50_init_miptree_functions(struct nv50_context *nv50) +{ + nv50->pipe.texture_create = nv50_miptree_create; + nv50->pipe.texture_release = nv50_miptree_release; +} diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c new file mode 100644 index 0000000000..d8c3491c2c --- /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_state.c b/src/gallium/drivers/nv50/nv50_state.c new file mode 100644 index 0000000000..99dcab51b2 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -0,0 +1,213 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" + +#include "nv50_context.h" +#include "nv50_state.h" + +static void * +nv50_blend_state_create(struct pipe_context *pipe, + const struct pipe_blend_state *cso) +{ + return NULL; +} + +static void +nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso) +{ +} + +static void +nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso) +{ +} + +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 unit, + void *hwcso) +{ +} + +static void +nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso) +{ +} + +static void +nv50_set_sampler_texture(struct pipe_context *pipe, unsigned unit, + struct pipe_texture *pt) +{ +} + +static void * +nv50_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + return NULL; +} + +static void +nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) +{ +} + +static void +nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +{ +} + +static void * +nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) +{ + return NULL; +} + +static void +nv50_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +{ +} + +static void +nv50_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +{ +} + +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) +{ +} + +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) +{ +} + +static void +nv50_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ +} + +static void +nv50_set_scissor_state(struct pipe_context *pipe, + const struct pipe_scissor_state *s) +{ +} + +static void +nv50_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *vpt) +{ +} + +static void +nv50_set_vertex_buffer(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_buffer *vb) +{ +} + +static void +nv50_set_vertex_element(struct pipe_context *pipe, unsigned index, + 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_state = nv50_sampler_state_bind; + nv50->pipe.delete_sampler_state = nv50_sampler_state_delete; + nv50->pipe.set_sampler_texture = 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_buffer = nv50_set_vertex_buffer; + nv50->pipe.set_vertex_element = nv50_set_vertex_element; +} + diff --git a/src/gallium/drivers/nv50/nv50_state.h b/src/gallium/drivers/nv50/nv50_state.h new file mode 100644 index 0000000000..a3b781d4c6 --- /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_surface.c b/src/gallium/drivers/nv50/nv50_surface.c new file mode 100644 index 0000000000..ca92ff02b8 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -0,0 +1,75 @@ + +/************************************************************************** + * + * 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 struct pipe_surface * +nv50_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + NOUVEAU_ERR("unimplemented\n"); + return NULL; +} + +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->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->nvws; + + nvws->surface_fill(nvws, dest, destx, desty, width, height, value); +} + +void +nv50_init_surface_functions(struct nv50_context *nv50) +{ + nv50->pipe.get_tex_surface = nv50_get_tex_surface; + 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 0000000000..6c0dc23a43 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -0,0 +1,24 @@ +#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) +{ + 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) +{ + NOUVEAU_ERR("unimplemented\n"); + return TRUE; +} + diff --git a/src/gallium/winsys/dri/nouveau/Makefile b/src/gallium/winsys/dri/nouveau/Makefile new file mode 100644 index 0000000000..b463f218fd --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/Makefile @@ -0,0 +1,43 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = nouveau_dri.so + +MINIGLX_SOURCES = + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.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 0000000000..6887ffa688 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -0,0 +1,402 @@ +/* + * 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 +#include +#include +#include + +#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 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)) { + 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; +} + +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->fence) + nouveau_fence_wait(&nvbo->fence); + nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); + if (nvbo->sysmem && !nvbo->user) + free(nvbo->sysmem); + free(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 (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) && (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 { + 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) + free(nvbo->sysmem); + + nvbo->drm = new; + nvbo->map = new_map; + 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; + nvchan->user_charge += bo->size; + + if (!(flags & NOUVEAU_BO_GART)) + return 1; + + r = nouveau_bo_tmp(chan, bo->size, fence); + if (!r) + return 1; + + 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) + 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, + struct nouveau_fence *fence, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + 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 0000000000..df80d04add --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_channel.c @@ -0,0 +1,118 @@ +/* + * 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 +#include +#include + +#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; + } + + 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); + + 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 0000000000..01fada5b89 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -0,0 +1,206 @@ +#include "main/glheader.h" +#include "glapi/glthread.h" +#include +#include "utils.h" + +#include "state_tracker/st_public.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.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 + +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 nouveau_device_priv *nvdev; + struct pipe_context *pipe = NULL; + struct st_context *st_share = NULL; + int ret; + + if (sharedContextPrivate) { + st_share = ((struct nouveau_context *)sharedContextPrivate)->st; + } + + if ((ret = nouveau_device_get_param(nv_screen->device, + NOUVEAU_GETPARAM_CHIPSET_ID, + &nv->chipset))) { + NOUVEAU_ERR("Error determining chipset id: %d\n", ret); + return GL_FALSE; + } + + if ((ret = nouveau_channel_alloc(nv_screen->device, + 0x8003d001, 0x8003d002, + &nv->channel))) { + NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); + return GL_FALSE; + } + + driContextPriv->driverPrivate = (void *)nv; + nv->nv_screen = nv_screen; + nv->dri_screen = driScrnPriv; + + nvdev = nouveau_device(nv_screen->device); + 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; + } + + if ((ret = nouveau_grobj_alloc(nv->channel, 0x00000000, 0x30, + &nv->NvNull))) { + NOUVEAU_ERR("Error creating NULL object: %d\n", ret); + return GL_FALSE; + } + nv->next_handle = 0x80000000; + + if ((ret = nouveau_notifier_alloc(nv->channel, nv->next_handle++, 1, + &nv->sync_notifier))) { + NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + return GL_FALSE; + } + + if (nv->chipset < 0x50) + ret = nouveau_surface_init_nv04(nv); + else + ret = nouveau_surface_init_nv50(nv); + if (ret) { + return GL_FALSE; + } + + if (!getenv("NOUVEAU_FORCE_SOFTPIPE")) { + pipe = nouveau_pipe_create(nv); + if (!pipe) + NOUVEAU_ERR("Couldn't create hw pipe\n"); + } + + 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; + + assert(nv); + + st_flush(nv->st, PIPE_FLUSH_WAIT); + st_destroy_context(nv->st); + + nouveau_grobj_free(&nv->NvCtxSurf2D); + nouveau_grobj_free(&nv->NvImageBlit); + nouveau_channel_free(&nv->channel); + + 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); + 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 0000000000..5805f969ba --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -0,0 +1,89 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "dri_util.h" +#include "xmlconfig.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau_device.h" +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +struct nouveau_framebuffer { + struct st_framebuffer *stfb; +}; + +struct nouveau_context { + struct st_context *st; + + /* Misc HW info */ + uint64_t chipset; + + /* 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; + + /* Hardware context */ + struct nouveau_channel *channel; + struct nouveau_notifier *sync_notifier; + struct nouveau_grobj *NvNull; + struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvImageBlit; + struct nouveau_grobj *NvGdiRect; + struct nouveau_grobj *NvM2MF; + struct nouveau_grobj *Nv2D; + uint32_t next_handle; + uint32_t next_subchannel; + uint32_t next_sequence; + + /* 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_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 0000000000..409e4415f7 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_device.c @@ -0,0 +1,146 @@ +/* + * 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 +#include +#include + +#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; + } + + *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_device.h b/src/gallium/winsys/dri/nouveau/nouveau_device.h new file mode 100644 index 0000000000..744a89f74b --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_device.h @@ -0,0 +1,29 @@ +/* + * 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 { +}; + +#endif 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 0000000000..f8a8ba04f6 --- /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 +#include +#include + +#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 0000000000..cfa6d26e82 --- /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 +#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 0000000000..1207c2d609 --- /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 0000000000..37e404fc6c --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -0,0 +1,304 @@ +/* + * 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 +#include +#include + +#include "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 { + uint64_t next; + uint64_t handle; + uint32_t *ptr; + uint32_t flags; + uint32_t data; + uint32_t vor; + uint32_t tor; +}; + +struct nouveau_pushbuf_bo { + uint64_t next; + uint64_t handle; + uint64_t flags; + uint64_t relocs; + int nr_relocs; +}; + +struct nouveau_pushbuf_priv { + struct nouveau_pushbuf base; + + unsigned nop_jump; + unsigned start; + unsigned size; + + uint64_t buffers; + int nr_buffers; +}; +#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_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 *, + struct nouveau_fence *fence, 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 0000000000..7714e6f248 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_fence.c @@ -0,0 +1,215 @@ +/* + * 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 +#include +#include + +#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(nvchan->fence_head, &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 0000000000..55dfeb99aa --- /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 +#include + +#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 *)&grobj); + 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 0000000000..59febca292 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_local.h @@ -0,0 +1,89 @@ +#ifndef __NOUVEAU_LOCAL_H__ +#define __NOUVEAU_LOCAL_H__ + +#include + +/* 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 */ +#define OUT_RING(data) do { \ + (*nv->channel->pushbuf->cur++) = (data); \ +} while(0) + +#define OUT_RINGp(src,size) do { \ + memcpy(nv->channel->pushbuf->cur, (src), (size)<<2); \ + nv->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 FIRE_RING() do { \ + nouveau_pushbuf_flush(nv->channel, 0); \ +} while(0) + +#define BEGIN_RING_GR(obj,mthd,size) do { \ + if (nv->channel->pushbuf->remaining < ((size) + 1)) \ + nouveau_pushbuf_flush(nv->channel, ((size) + 1)); \ + OUT_RING(((obj)->subc << 13) | ((size) << 18) | (mthd)); \ + nv->channel->pushbuf->remaining -= ((size) + 1); \ +} while(0) + +#define BEGIN_RING(obj,mthd,size) do { \ + BEGIN_RING_GR(nv->obj, (mthd), (size)); \ +} while(0) + +#define BIND_RING(o,s) do { \ + nv->o->subc = (s); \ + BEGIN_RING(o, 0x0000, 1); \ + OUT_RING (nv->o->handle); \ +} while(0) + +#define OUT_RELOC(buf,data,flags,vor,tor) do { \ + nouveau_pipe_emit_reloc(nv->channel, nv->channel->pushbuf->cur++, \ + buf, (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, \ + nv->channel->vram->handle, nv->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) + +#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 0000000000..9adb9ac854 --- /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 + +#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 0000000000..01e8f38440 --- /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 +#include + +#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 0000000000..7d5eddb92f --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -0,0 +1,261 @@ +/* + * 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 +#include +#include + +#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]; + + 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; + + 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; + struct nouveau_pushbuf_bo *pbbo; + struct nouveau_fence *fence = NULL; + int ret; + + if (nvpb->base.remaining == nvpb->size) + return 0; + + nvpb->size -= nvpb->base.remaining; + nvchan->dma->cur += nvpb->size; + nvchan->dma->free -= nvpb->size; + assert(nvchan->dma->cur <= nvchan->dma->max); + + ret = nouveau_fence_new(chan, &fence); + if (ret) + return ret; + + 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; + while ((pbbo = ptr_to_pbbo(nvpb->buffers))) { + struct nouveau_pushbuf_reloc *r; + struct nouveau_bo *bo = &ptr_to_bo(pbbo->handle)->base; + + ret = nouveau_bo_validate(chan, bo, fence, pbbo->flags); + assert (ret == 0); + + if (bo->offset == nouveau_bo(bo)->offset && + bo->flags == nouveau_bo(bo)->flags) { + while ((r = ptr_to_pbrel(pbbo->relocs))) { + pbbo->relocs = r->next; + free(r); + } + + nvpb->buffers = pbbo->next; + free(pbbo); + continue; + } + bo->offset = nouveau_bo(bo)->offset; + bo->flags = nouveau_bo(bo)->flags; + + while ((r = ptr_to_pbrel(pbbo->relocs))) { + *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); + pbbo->relocs = r->next; + free(r); + } + + nvpb->buffers = pbbo->next; + free(pbbo); + } + 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(fence); + FIRE_RING_CH(chan); + nouveau_fence_ref(NULL, &fence); + + /* Allocate space for next push buffer */ + assert(!nouveau_pushbuf_space(chan, min)); + + 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_pushbuf_bo *pbbo = ptr_to_pbbo(nvpb->buffers); + + while (pbbo) { + if (pbbo->handle == bo->handle) + return pbbo; + pbbo = ptr_to_pbbo(pbbo->next); + } + + pbbo = malloc(sizeof(struct nouveau_pushbuf_bo)); + pbbo->next = nvpb->buffers; + nvpb->buffers = pbbo_to_ptr(pbbo); + nvpb->nr_buffers++; + + pbbo->handle = bo_to_ptr(bo); + pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + pbbo->relocs = 0; + pbbo->nr_relocs = 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_bo *pbbo; + struct nouveau_pushbuf_reloc *r; + + if (!chan) + return -EINVAL; + + pbbo = nouveau_pushbuf_emit_buffer(chan, bo); + if (!pbbo) + return -EFAULT; + + r = malloc(sizeof(struct nouveau_pushbuf_reloc)); + r->next = pbbo->relocs; + pbbo->relocs = pbrel_to_ptr(r); + pbbo->nr_relocs++; + + pbbo->flags |= (flags & NOUVEAU_BO_RDWR); + pbbo->flags &= (flags | NOUVEAU_BO_RDWR); + + r->handle = bo_to_ptr(r); + 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 0000000000..5d9d578b4f --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_resource.c @@ -0,0 +1,111 @@ +/* + * 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 +#include + +#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; + + 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); + } else + if (r->next && !r->next->in_use) { + r->next->prev = r->prev; + if (r->prev) + r->prev->next = r->next; + r->next->size += r->size; + r->next->start = r->start; + free(r); + } else { + r->in_use = 0; + } + + *res = NULL; +} 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 0000000000..f06e178483 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -0,0 +1,308 @@ +#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_device.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 0000000000..019823bd44 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.h @@ -0,0 +1,19 @@ +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +#include "xmlconfig.h" +#include "nouveau_device.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; +}; + +#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 0000000000..91bf243f42 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c @@ -0,0 +1,86 @@ +#include "main/glheader.h" +#include "glapi/glthread.h" +#include + +#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(); + 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 0000000000..825d3da6da --- /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 0000000000..2ca05d84c6 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -0,0 +1,124 @@ +#include "pipe/p_util.h" + +#include "nouveau_context.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->channel, nv->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; + int ret; + + ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, + grclass, grobj); + if (ret) + return ret; + + (*grobj)->subc = nv->next_subchannel++; + assert((*grobj)->subc <= 7); + BEGIN_RING_GR(*grobj, 0x0000, 1); + OUT_RING ((*grobj)->handle); + 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; +} + +int +nouveau_pipe_emit_reloc(struct nouveau_channel *chan, void *ptr, + struct pipe_buffer *buf, uint32_t data, + uint32_t flags, uint32_t vor, uint32_t tor) +{ + return nouveau_pushbuf_emit_reloc(chan, ptr, nouveau_buffer(buf)->bo, + data, flags, vor, tor); +} + +struct pipe_context * +nouveau_pipe_create(struct nouveau_context *nv) +{ + struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); + struct pipe_context *(*hw_create)(struct pipe_winsys *, + struct nouveau_winsys *, + unsigned); + + if (!nvws) + return NULL; + + switch (nv->chipset & 0xf0) { + case 0x30: + hw_create = nv30_create; + break; + case 0x40: + case 0x60: + hw_create = nv40_create; + break; + case 0x50: + case 0x80: + hw_create = nv50_create; + break; + default: + NOUVEAU_ERR("Unknown chipset NV%02x\n", (int)nv->chipset); + return NULL; + } + + nvws->nv = nv; + nvws->channel = nv->channel; + + nvws->res_init = nouveau_resource_init; + nvws->res_alloc = nouveau_resource_alloc; + nvws->res_free = nouveau_resource_free; + + nvws->push_reloc = nouveau_pipe_emit_reloc; + nvws->push_flush = nouveau_pushbuf_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; + + return hw_create(nouveau_create_pipe_winsys(nv), nvws, nv->chipset); +} + 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 0000000000..e1a9271395 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -0,0 +1,196 @@ +#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_device.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 void +nouveau_printf(struct pipe_winsys *pws, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); +} + +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 int +nouveau_surface_alloc_storage(struct pipe_winsys *ws, struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, unsigned flags) +{ + unsigned pitch = ((width * pf_get_size(format)) + 63) & ~63; + + surf->format = format; + surf->width = width; + surf->height = height; + surf->cpp = pf_get_size(format); + surf->pitch = pitch / surf->cpp; + + surf->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + pitch * height); + if (!surf->buffer) + return 1; + + return 0; +} + +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_device *dev = nvpws->nv->nv_screen->device; + struct nouveau_pipe_buffer *nvbuf; + uint32_t flags = 0; + + 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 (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); +} + +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->printf = nouveau_printf; + + pws->surface_alloc = nouveau_surface_alloc; + pws->surface_alloc_storage = nouveau_surface_alloc_storage; + 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->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 0000000000..6a03ac0d77 --- /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 0000000000..0e1b4273d1 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c @@ -0,0 +1,83 @@ +/************************************************************************** + * + * 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 + */ + +#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; + + nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); + + /* Fill in this struct with callbacks that softpipe will need to + * communicate with the window system, buffer manager, etc. + */ + nvsws->sws.is_format_supported = nouveau_is_format_supported; + nvsws->nv = nv; + + /* Create the softpipe context: + */ + return softpipe_create(nouveau_create_pipe_winsys(nv), &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 0000000000..fe1ea4ed70 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -0,0 +1,226 @@ +#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 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(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(src->buffer, src_offset, NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCl(dst->buffer, dst_offset, NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RING (src->pitch * src->cpp); + OUT_RING (dst->pitch * dst->cpp); + OUT_RING (w * src->cpp); + OUT_RING (count); + OUT_RING (0x0101); + OUT_RING (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) +{ + BEGIN_RING(NvImageBlit, 0x0300, 3); + OUT_RING ((sy << 16) | sx); + OUT_RING ((dy << 16) | dx); + OUT_RING (( h << 16) | w); +} + +static int +nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, + struct pipe_surface *src) +{ + 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(NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); + OUT_RELOCo(src->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD); + OUT_RELOCo(dst->buffer, 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(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (format); + OUT_RING (((dst->pitch * dst->cpp) << 16) | (src->pitch * src->cpp)); + OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + return 0; +} + +static void +nv04_surface_copy_done(struct nouveau_context *nv) +{ + FIRE_RING(); +} + +static int +nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + 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(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (cs2d_format); + OUT_RING (((dst->pitch * dst->cpp) << 16) | (dst->pitch * dst->cpp)); + OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); + OUT_RING (gdirect_format); + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); + OUT_RING (value); + BEGIN_RING(NvGdiRect, + NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); + OUT_RING ((dx << 16) | dy); + OUT_RING (( w << 16) | h); + + FIRE_RING(); + return 0; +} + +int +nouveau_surface_init_nv04(struct nouveau_context *nv) +{ + unsigned class; + int ret; + + if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, 0x39, + &nv->NvM2MF))) { + NOUVEAU_ERR("Error creating m2mf object: %d\n", ret); + return 1; + } + BIND_RING (NvM2MF, nv->next_subchannel++); + BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (nv->sync_notifier->handle); + + class = nv->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : + NV10_CONTEXT_SURFACES_2D; + if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, + &nv->NvCtxSurf2D))) { + NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret); + return 1; + } + BIND_RING (NvCtxSurf2D, nv->next_subchannel++); + BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RING (nv->channel->vram->handle); + OUT_RING (nv->channel->vram->handle); + + class = nv->chipset < 0x10 ? NV04_IMAGE_BLIT : + NV12_IMAGE_BLIT; + if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, + &nv->NvImageBlit))) { + NOUVEAU_ERR("Error creating blit object: %d\n", ret); + return 1; + } + BIND_RING (NvImageBlit, nv->next_subchannel++); + BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); + OUT_RING (nv->sync_notifier->handle); + BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); + OUT_RING (nv->NvCtxSurf2D->handle); + BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); + OUT_RING (NV04_IMAGE_BLIT_OPERATION_SRCCOPY); + + class = NV04_GDI_RECTANGLE_TEXT; + if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, + &nv->NvGdiRect))) { + NOUVEAU_ERR("Error creating rect object: %d\n", ret); + return 1; + } + BIND_RING (NvGdiRect, nv->next_subchannel++); + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); + OUT_RING (nv->sync_notifier->handle); + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + OUT_RING (nv->NvCtxSurf2D->handle); + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING (NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); + BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); + OUT_RING (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + + 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 0000000000..15a1002861 --- /dev/null +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -0,0 +1,160 @@ +#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) +{ + int surf_format; + + assert(src->cpp == dst->cpp); + + surf_format = nv50_format(dst->cpp); + assert(surf_format >= 0); + + BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); + OUT_RING (surf_format); + OUT_RING (1); + BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); + OUT_RING (dst->pitch * dst->cpp); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); + OUT_RING (0); + OUT_RING (0); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + + BEGIN_RING(Nv2D, NV50_2D_SRC_FORMAT, 2); + OUT_RING (surf_format); + OUT_RING (1); + BEGIN_RING(Nv2D, NV50_2D_SRC_PITCH, 5); + OUT_RING (src->pitch * src->cpp); + OUT_RING (src->pitch); + OUT_RING (src->height); + OUT_RELOCh(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(src->buffer, 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) +{ + BEGIN_RING(Nv2D, 0x0110, 1); + OUT_RING (0); + BEGIN_RING(Nv2D, NV50_2D_BLIT_DST_X, 12); + OUT_RING (dx); + OUT_RING (dy); + OUT_RING (w); + OUT_RING (h); + OUT_RING (0); + OUT_RING (1); + OUT_RING (0); + OUT_RING (1); + OUT_RING (0); + OUT_RING (sx); + OUT_RING (0); + OUT_RING (sy); +} + +static void +nv50_surface_copy_done(struct nouveau_context *nv) +{ + FIRE_RING(); +} + +static int +nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, + unsigned dx, unsigned dy, unsigned w, unsigned h, + unsigned value) +{ + 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(Nv2D, NV50_2D_DMA_IN_MEMORY1, 1); + OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); + OUT_RING (surf_format); + OUT_RING (1); + BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); + OUT_RING (dst->pitch * dst->cpp); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); + OUT_RING (0); + OUT_RING (0); + OUT_RING (dst->pitch); + OUT_RING (dst->height); + + BEGIN_RING(Nv2D, 0x0580, 3); + OUT_RING (4); + OUT_RING (rect_format); + OUT_RING (value); + + BEGIN_RING(Nv2D, NV50_2D_RECT_X1, 4); + OUT_RING (dx); + OUT_RING (dy); + OUT_RING (dx + w); + OUT_RING (dy + h); + + FIRE_RING(); + + return 0; +} + +int +nouveau_surface_init_nv50(struct nouveau_context *nv) +{ + int ret; + + ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, NV50_2D, + &nv->Nv2D); + if (ret) + return ret; + BIND_RING (Nv2D, 0); + BEGIN_RING(Nv2D, NV50_2D_DMA_NOTIFY, 1); + OUT_RING (nv->sync_notifier->handle); + BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RING (nv->channel->vram->handle); + OUT_RING (nv->channel->vram->handle); + BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1); + OUT_RING (NV50_2D_OPERATION_SRCCOPY); + + 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; +} + -- cgit v1.2.3 From c303cf15dcf2744028f920cf71d7e6fda709bd15 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 16 Feb 2008 17:51:44 +1100 Subject: nouveau: fix potential userbuf crash. --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 6887ffa688..ad587bafdf 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -295,7 +295,8 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) &new, &new_map); if (ret) return ret; - } else { + } else + if (!nvbo->user) { new_sysmem = malloc(bo->size); } @@ -311,12 +312,13 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) if (nvbo->fence) nouveau_fence_wait(&nvbo->fence); nouveau_mem_free(bo->device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem) + if (nvbo->sysmem && !nvbo->user) free(nvbo->sysmem); nvbo->drm = new; nvbo->map = new_map; - nvbo->sysmem = new_sysmem; + if (!nvbo->user) + nvbo->sysmem = new_sysmem; bo->flags = flags; bo->offset = nvbo->drm.offset; return 0; @@ -333,7 +335,6 @@ nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, if (nvchan->user_charge + bo->size > nvdev->sa.size) return 1; - nvchan->user_charge += bo->size; if (!(flags & NOUVEAU_BO_GART)) return 1; @@ -341,6 +342,7 @@ nouveau_bo_validate_user(struct nouveau_channel *chan, struct nouveau_bo *bo, 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); -- cgit v1.2.3 From 5e091b573aa0a0c45f8ff34429f2a9d4198bb80a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 16 Feb 2008 21:27:53 +1100 Subject: nv40: ensure scissor gets disabled where necessary Fixes progs/demos/lodbias. Makes a complete mess of things, but now there's a motivation to finish this off :) --- src/gallium/drivers/nv40/nv40_context.h | 19 ++++++++- src/gallium/drivers/nv40/nv40_state.c | 23 +++++------ src/gallium/drivers/nv40/nv40_state_emit.c | 65 +++++++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index f511759e3b..c4523112db 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -54,6 +54,11 @@ struct nv40_channel_context { struct nouveau_resource *vp_data_heap; }; +struct nv40_rasterizer_state { + struct pipe_rasterizer_state pipe; + struct nouveau_stateobj *so; +}; + struct nv40_context { struct pipe_context pipe; struct nouveau_winsys *nvws; @@ -63,7 +68,8 @@ struct nv40_context { int chipset; - uint32_t dirty; + unsigned dirty; + unsigned hw_dirty; struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; @@ -71,14 +77,23 @@ struct nv40_context { unsigned fp_samplers; unsigned vp_samplers; + struct { + struct pipe_scissor_state scissor; + } pipe_state; + + struct { + unsigned scissor_enabled; + struct nouveau_stateobj *scissor; + } state; + struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; struct nouveau_stateobj *so_vtxbuf; struct nouveau_stateobj *so_blend; + struct nv40_rasterizer_state *rasterizer; struct nouveau_stateobj *so_rast; struct nouveau_stateobj *so_zsa; struct nouveau_stateobj *so_bcol; - struct nouveau_stateobj *so_scissor; struct nouveau_stateobj *so_viewport; struct nouveau_stateobj *so_stipple; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 713f31dbb1..bb9b6b139f 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -278,12 +278,12 @@ 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 = MALLOC(sizeof(*rsso)); struct nouveau_stateobj *so = so_new(32, 0); /*XXX: ignored: * light_twoside * offset_cw/ccw -nohw - * scissor * point_smooth -nohw * multisample * offset_units / offset_scale @@ -362,24 +362,29 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, 0); } - return (void *)so; + rsso->so = 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); + struct nv40_rasterizer_state *rsso = hwcso; - so_ref(hwcso, &nv40->so_rast); + so_ref(rsso->so, &nv40->so_rast); + nv40->rasterizer = rsso; nv40->dirty |= NV40_NEW_RAST; } static void nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nouveau_stateobj *so = hwcso; + struct nv40_rasterizer_state *rsso = hwcso; - so_ref(NULL, &so); + so_ref(NULL, &rsso->so); + free(rsso); } static void * @@ -723,14 +728,8 @@ nv40_set_scissor_state(struct pipe_context *pipe, const struct pipe_scissor_state *s) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_stateobj *so = so_new(3, 0); - so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); - so_data (so, ((s->maxx - s->minx) << 16) | s->minx); - so_data (so, ((s->maxy - s->miny) << 16) | s->miny); - - so_ref(so, &nv40->so_scissor); - so_ref(NULL, &so); + nv40->pipe_state.scissor = *s; nv40->dirty |= NV40_NEW_SCISSOR; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index a10c995548..74306fe22b 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -22,9 +22,68 @@ nv40_state_emit_dummy_relocs(struct nv40_context *nv40) so_emit_reloc_markers(nv40->nvws, nv40->fragprog.active->so); } +static boolean +nv40_state_scissor_validate(struct nv40_context *nv40) +{ + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct pipe_scissor_state *s = &nv40->pipe_state.scissor; + struct nouveau_stateobj *so; + + if (nv40->state.scissor && + (rast->scissor == 0 && nv40->state.scissor_enabled == 0)) + return FALSE; + + so = so_new(3, 0); + so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); + if (rast->scissor) { + 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.scissor); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_atom { + boolean (*validate)(struct nv40_context *nv40); + struct { + unsigned pipe; + unsigned hw; + } dirty; +}; + +static struct nv40_state_atom states[] = { + { + .validate = nv40_state_scissor_validate, + .dirty = { + .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, + .hw = NV40_NEW_SCISSOR, + } + } +}; + +static void +nv40_state_validate(struct nv40_context *nv40) +{ + unsigned i; + + for (i = 0; i < sizeof(states) / sizeof(states[0]); i++) { + if (nv40->dirty & states[i].dirty.pipe) { + if (states[i].validate(nv40)) + nv40->hw_dirty |= states[i].dirty.hw; + } + } +} + void nv40_emit_hw_state(struct nv40_context *nv40) { + nv40_state_validate(nv40); + if (nv40->dirty & NV40_NEW_FB) so_emit(nv40->nvws, nv40->so_framebuffer); @@ -40,8 +99,10 @@ nv40_emit_hw_state(struct nv40_context *nv40) if (nv40->dirty & NV40_NEW_BCOL) so_emit(nv40->nvws, nv40->so_bcol); - if (nv40->dirty & NV40_NEW_SCISSOR) - so_emit(nv40->nvws, nv40->so_scissor); + if (nv40->hw_dirty & NV40_NEW_SCISSOR) { + so_emit(nv40->nvws, nv40->state.scissor); + nv40->hw_dirty &= ~NV40_NEW_SCISSOR; + } if (nv40->dirty & NV40_NEW_VIEWPORT) so_emit(nv40->nvws, nv40->so_viewport); -- cgit v1.2.3 From 12e0aa7b1d587b7c30897762d2f8f368a4a7d453 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 14:12:58 +1100 Subject: nv40: similar changes to polygon stipple as were done for scissor --- src/gallium/drivers/nv40/nv40_context.h | 18 ++++++++--- src/gallium/drivers/nv40/nv40_state.c | 9 +----- src/gallium/drivers/nv40/nv40_state_emit.c | 52 ++++++++++++++++++++++++++---- 3 files changed, 61 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index c4523112db..7d5806f5f7 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -59,6 +59,18 @@ struct nv40_rasterizer_state { struct nouveau_stateobj *so; }; +struct nv40_state { + struct { + unsigned enabled; + struct nouveau_stateobj *so; + } scissor; + + struct { + unsigned enabled; + struct nouveau_stateobj *so; + } stipple; +}; + struct nv40_context { struct pipe_context pipe; struct nouveau_winsys *nvws; @@ -79,12 +91,10 @@ struct nv40_context { struct { struct pipe_scissor_state scissor; + unsigned stipple[32]; } pipe_state; - struct { - unsigned scissor_enabled; - struct nouveau_stateobj *scissor; - } state; + struct nv40_state state; struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index bb9b6b139f..a36efd37f6 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -711,15 +711,8 @@ nv40_set_polygon_stipple(struct pipe_context *pipe, const struct pipe_poly_stipple *stipple) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_stateobj *so = so_new(33, 0); - unsigned i; - so_method(so, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); - for (i = 0; i < 32; i++) - so_data(so, stipple->stipple[i]); - - so_ref(so, &nv40->so_stipple); - so_ref(NULL, &so); + memcpy(nv40->pipe_state.stipple, stipple->stipple, 4 * 32); nv40->dirty |= NV40_NEW_STIPPLE; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 74306fe22b..244c6838f3 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -29,8 +29,8 @@ nv40_state_scissor_validate(struct nv40_context *nv40) struct pipe_scissor_state *s = &nv40->pipe_state.scissor; struct nouveau_stateobj *so; - if (nv40->state.scissor && - (rast->scissor == 0 && nv40->state.scissor_enabled == 0)) + if (nv40->state.scissor.so && + (rast->scissor == 0 && nv40->state.scissor.enabled == 0)) return FALSE; so = so_new(3, 0); @@ -43,7 +43,38 @@ nv40_state_scissor_validate(struct nv40_context *nv40) so_data (so, 4096 << 16); } - so_ref(so, &nv40->state.scissor); + so_ref(so, &nv40->state.scissor.so); + so_ref(NULL, &so); + return TRUE; +} + +static boolean +nv40_state_stipple_validate(struct nv40_context *nv40) +{ + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_stateobj *so; + + if (nv40->state.stipple.so && (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->pipe_state.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.stipple.so); so_ref(NULL, &so); return TRUE; } @@ -63,6 +94,13 @@ static struct nv40_state_atom states[] = { .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, .hw = NV40_NEW_SCISSOR, } + }, + { + .validate = nv40_state_stipple_validate, + .dirty = { + .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, + .hw = NV40_NEW_STIPPLE, + } } }; @@ -100,15 +138,17 @@ nv40_emit_hw_state(struct nv40_context *nv40) so_emit(nv40->nvws, nv40->so_bcol); if (nv40->hw_dirty & NV40_NEW_SCISSOR) { - so_emit(nv40->nvws, nv40->state.scissor); + so_emit(nv40->nvws, nv40->state.scissor.so); nv40->hw_dirty &= ~NV40_NEW_SCISSOR; } if (nv40->dirty & NV40_NEW_VIEWPORT) so_emit(nv40->nvws, nv40->so_viewport); - if (nv40->dirty & NV40_NEW_STIPPLE) - so_emit(nv40->nvws, nv40->so_stipple); + if (nv40->hw_dirty & NV40_NEW_STIPPLE) { + so_emit(nv40->nvws, nv40->state.stipple.so); + nv40->hw_dirty &= ~NV40_NEW_STIPPLE; + } if (nv40->dirty & NV40_NEW_FRAGPROG) { nv40_fragprog_bind(nv40, nv40->fragprog.current); -- cgit v1.2.3 From 037570fa5a6cf83d3aaaa6cdacc10eb0b5da45bf Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 15:17:39 +1100 Subject: nv40: obey polygon offset state Almost sure this isn't entirely correct. However, I'm not sure what gallium expects yet, and this fixes some bugs, so it'll do for now. --- src/gallium/drivers/nv40/nv40_state.c | 39 +++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index a36efd37f6..fec8f946c3 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -280,31 +280,30 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, struct nv40_context *nv40 = nv40_context(pipe); struct nv40_rasterizer_state *rsso = MALLOC(sizeof(*rsso)); struct nouveau_stateobj *so = so_new(32, 0); + struct nouveau_grobj *curie = nv40->hw->curie; /*XXX: ignored: * light_twoside - * offset_cw/ccw -nohw * point_smooth -nohw * multisample - * offset_units / offset_scale */ - so_method(so, nv40->hw->curie, NV40TCL_SHADE_MODEL, 1); + so_method(so, curie, NV40TCL_SHADE_MODEL, 1); so_data (so, cso->flatshade ? NV40TCL_SHADE_MODEL_FLAT : NV40TCL_SHADE_MODEL_SMOOTH); - so_method(so, nv40->hw->curie, NV40TCL_LINE_WIDTH, 2); + 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, nv40->hw->curie, NV40TCL_LINE_STIPPLE_ENABLE, 2); + 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, nv40->hw->curie, NV40TCL_POINT_SIZE, 1); + so_method(so, curie, NV40TCL_POINT_SIZE, 1); so_data (so, fui(cso->point_size)); - so_method(so, nv40->hw->curie, NV40TCL_POLYGON_MODE_FRONT, 6); + 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)); @@ -345,10 +344,32 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, cso->poly_smooth ? 1 : 0); so_data(so, cso->cull_mode != PIPE_WINDING_NONE ? 1 : 0); - so_method(so, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); so_data (so, cso->poly_stipple_enable ? 1 : 0); - so_method(so, nv40->hw->curie, NV40TCL_POINT_SPRITE, 1); + so_method(so, curie, 0x0a60, 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; -- cgit v1.2.3 From f911235f64d610e57da88487133d0483c7a094e7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 15:31:55 +1100 Subject: nouveau: header update --- src/gallium/drivers/nouveau/nouveau_class.h | 4 ++-- src/gallium/drivers/nv40/nv40_state.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index 5998945677..c80461038b 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -4926,9 +4926,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV40TCL_VIEWPORT_SCALE_Y 0x00000a34 #define NV40TCL_VIEWPORT_SCALE_Z 0x00000a38 #define NV40TCL_VIEWPORT_SCALE_W 0x00000a3c -#define NV40TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000a60 +#define NV40TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000a60 #define NV40TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000a64 -#define NV40TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000a68 +#define NV40TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000a68 #define NV40TCL_DEPTH_FUNC 0x00000a6c #define NV40TCL_DEPTH_FUNC_NEVER 0x00000200 #define NV40TCL_DEPTH_FUNC_LESS 0x00000201 diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index fec8f946c3..d7379e9090 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -347,7 +347,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); so_data (so, cso->poly_stipple_enable ? 1 : 0); - so_method(so, curie, 0x0a60, 3); + 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); -- cgit v1.2.3 From 112ba3355a3fa53768efb9a9fb0eeb677bd28d47 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 16:26:33 +1100 Subject: nv40: until gallium is fixed we'll need a fallback for user clip planes --- src/gallium/drivers/nv40/nv40_context.h | 13 +++++++++++ src/gallium/drivers/nv40/nv40_state.c | 4 ++++ src/gallium/drivers/nv40/nv40_state_emit.c | 37 ++++++++++++++++++++++-------- 3 files changed, 45 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 7d5806f5f7..e9ed7ea3fb 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -34,6 +34,9 @@ #define NV40_NEW_VERTPROG (1 << 9) #define NV40_NEW_FRAGPROG (1 << 10) #define NV40_NEW_ARRAYS (1 << 11) +#define NV40_NEW_UCP (1 << 12) + +#define NV40_FALLBACK_TNL (1 << 0) struct nv40_channel_context { struct nouveau_winsys *nvws; @@ -92,9 +95,11 @@ struct nv40_context { struct { struct pipe_scissor_state scissor; unsigned stipple[32]; + struct pipe_clip_state clip; } pipe_state; struct nv40_state state; + unsigned fallback; struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; @@ -131,6 +136,14 @@ 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_miptree_functions(struct nv40_context *nv40); diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index d7379e9090..c203b00240 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -561,6 +561,10 @@ static void nv40_set_clip_state(struct pipe_context *pipe, const struct pipe_clip_state *clip) { + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->pipe_state.clip = *clip; + nv40->dirty |= NV40_NEW_UCP; } static void diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 244c6838f3..ce52a3863e 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -79,15 +79,15 @@ nv40_state_stipple_validate(struct nv40_context *nv40) return TRUE; } -struct nv40_state_atom { - boolean (*validate)(struct nv40_context *nv40); - struct { - unsigned pipe; - unsigned hw; - } dirty; -}; +static boolean +nv40_state_clip_validate(struct nv40_context *nv40) +{ + if (nv40->pipe_state.clip.nr) + nv40->fallback |= NV40_FALLBACK_TNL; + return FALSE; +} -static struct nv40_state_atom states[] = { +static struct nv40_state_entry states[] = { { .validate = nv40_state_scissor_validate, .dirty = { @@ -101,13 +101,23 @@ static struct nv40_state_atom states[] = { .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, .hw = NV40_NEW_STIPPLE, } + }, + { + .validate = nv40_state_clip_validate, + .dirty = { + .pipe = NV40_NEW_UCP, + .hw = 0, + } } }; static void nv40_state_validate(struct nv40_context *nv40) { - unsigned i; + unsigned i, last_fallback; + + last_fallback = nv40->fallback; + nv40->fallback = 0; for (i = 0; i < sizeof(states) / sizeof(states[0]); i++) { if (nv40->dirty & states[i].dirty.pipe) { @@ -115,6 +125,15 @@ nv40_state_validate(struct nv40_context *nv40) nv40->hw_dirty |= states[i].dirty.hw; } } + + if (nv40->fallback & NV40_FALLBACK_TNL && + !(last_fallback & NV40_FALLBACK_TNL)) { + NOUVEAU_ERR("XXX: hwtnl->swtnl\n"); + } else + if (last_fallback & NV40_FALLBACK_TNL && + !(nv40->fallback & NV40_FALLBACK_TNL)) { + NOUVEAU_ERR("XXX: swtnl->hwtnl\n"); + } } void -- cgit v1.2.3 From 56045da083d6530a56a2a7585e3121df0b07bac4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 16:38:27 +1100 Subject: nv40: move some things around --- src/gallium/drivers/nv40/Makefile | 3 + src/gallium/drivers/nv40/nv40_context.h | 3 + src/gallium/drivers/nv40/nv40_state_clip.c | 18 +++++ src/gallium/drivers/nv40/nv40_state_emit.c | 99 ++++----------------------- src/gallium/drivers/nv40/nv40_state_scissor.c | 35 ++++++++++ src/gallium/drivers/nv40/nv40_state_stipple.c | 40 +++++++++++ 6 files changed, 114 insertions(+), 84 deletions(-) create mode 100644 src/gallium/drivers/nv40/nv40_state_clip.c create mode 100644 src/gallium/drivers/nv40/nv40_state_scissor.c create mode 100644 src/gallium/drivers/nv40/nv40_state_stipple.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 2a9de4a2dc..12b8eef259 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -13,6 +13,9 @@ DRIVER_SOURCES = \ nv40_query.c \ nv40_state.c \ nv40_state_emit.c \ + nv40_state_clip.c \ + nv40_state_scissor.c \ + nv40_state_stipple.c \ nv40_surface.c \ nv40_vbo.c \ nv40_vertprog.c diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index e9ed7ea3fb..432204b825 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -174,6 +174,9 @@ extern void nv40_fragtex_bind(struct nv40_context *); /* nv40_state.c and friends */ extern void nv40_emit_hw_state(struct nv40_context *nv40); extern void nv40_state_tex_update(struct nv40_context *nv40); +extern struct nv40_state_entry nv40_state_clip; +extern struct nv40_state_entry nv40_state_scissor; +extern struct nv40_state_entry nv40_state_stipple; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c new file mode 100644 index 0000000000..19f1c3b36d --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_clip.c @@ -0,0 +1,18 @@ +#include "nv40_context.h" + +static boolean +nv40_state_clip_validate(struct nv40_context *nv40) +{ + if (nv40->pipe_state.clip.nr) + nv40->fallback |= NV40_FALLBACK_TNL; + + return FALSE; +} + +struct nv40_state_entry nv40_state_clip = { + .validate = nv40_state_clip_validate, + .dirty = { + .pipe = NV40_NEW_UCP, + .hw = 0 + } +}; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index ce52a3863e..b5d0d68d6b 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -22,63 +22,6 @@ nv40_state_emit_dummy_relocs(struct nv40_context *nv40) so_emit_reloc_markers(nv40->nvws, nv40->fragprog.active->so); } -static boolean -nv40_state_scissor_validate(struct nv40_context *nv40) -{ - struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; - struct pipe_scissor_state *s = &nv40->pipe_state.scissor; - struct nouveau_stateobj *so; - - if (nv40->state.scissor.so && - (rast->scissor == 0 && nv40->state.scissor.enabled == 0)) - return FALSE; - - so = so_new(3, 0); - so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); - if (rast->scissor) { - 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.scissor.so); - so_ref(NULL, &so); - return TRUE; -} - -static boolean -nv40_state_stipple_validate(struct nv40_context *nv40) -{ - struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; - struct nouveau_grobj *curie = nv40->hw->curie; - struct nouveau_stateobj *so; - - if (nv40->state.stipple.so && (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->pipe_state.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.stipple.so); - so_ref(NULL, &so); - return TRUE; -} - static boolean nv40_state_clip_validate(struct nv40_context *nv40) { @@ -87,43 +30,31 @@ nv40_state_clip_validate(struct nv40_context *nv40) return FALSE; } -static struct nv40_state_entry states[] = { - { - .validate = nv40_state_scissor_validate, - .dirty = { - .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, - .hw = NV40_NEW_SCISSOR, - } - }, - { - .validate = nv40_state_stipple_validate, - .dirty = { - .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, - .hw = NV40_NEW_STIPPLE, - } - }, - { - .validate = nv40_state_clip_validate, - .dirty = { - .pipe = NV40_NEW_UCP, - .hw = 0, - } - } +static struct nv40_state_entry *render_states[] = { + &nv40_state_clip, + &nv40_state_scissor, + &nv40_state_stipple, + NULL }; static void nv40_state_validate(struct nv40_context *nv40) { - unsigned i, last_fallback; + struct nv40_state_entry **states = render_states; + unsigned last_fallback; last_fallback = nv40->fallback; nv40->fallback = 0; - for (i = 0; i < sizeof(states) / sizeof(states[0]); i++) { - if (nv40->dirty & states[i].dirty.pipe) { - if (states[i].validate(nv40)) - nv40->hw_dirty |= states[i].dirty.hw; + while (*states) { + struct nv40_state_entry *e = *states; + + if (nv40->dirty & e->dirty.pipe) { + if (e->validate(nv40)) + nv40->hw_dirty |= e->dirty.hw; } + + states++; } if (nv40->fallback & NV40_FALLBACK_TNL && 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 0000000000..556b820e58 --- /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->pipe_state.scissor; + struct nouveau_stateobj *so; + + if (nv40->state.scissor.so && + (rast->scissor == 0 && nv40->state.scissor.enabled == 0)) + return FALSE; + + so = so_new(3, 0); + so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); + if (rast->scissor) { + 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.scissor.so); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_scissor = { + .validate = nv40_state_scissor_validate, + .dirty = { + .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, + .hw = NV40_NEW_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 0000000000..52462a0b50 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -0,0 +1,40 @@ +#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->hw->curie; + struct nouveau_stateobj *so; + + if (nv40->state.stipple.so && (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->pipe_state.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.stipple.so); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_stipple = { + .validate = nv40_state_stipple_validate, + .dirty = { + .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, + .hw = NV40_NEW_STIPPLE + } +}; -- cgit v1.2.3 From 4a9cb97bbf6961cc4106c4c54e59296a74e889e9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 17:07:59 +1100 Subject: nv40: get fragprog onto new state mechanism --- src/gallium/drivers/nv40/nv40_context.h | 17 ++-- src/gallium/drivers/nv40/nv40_fragprog.c | 127 +++++++++++++++++------------ src/gallium/drivers/nv40/nv40_fragtex.c | 2 +- src/gallium/drivers/nv40/nv40_state.c | 5 +- src/gallium/drivers/nv40/nv40_state.h | 1 - src/gallium/drivers/nv40/nv40_state_emit.c | 26 +++--- 6 files changed, 97 insertions(+), 81 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 432204b825..ce0933fea4 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -37,6 +37,7 @@ #define NV40_NEW_UCP (1 << 12) #define NV40_FALLBACK_TNL (1 << 0) +#define NV40_FALLBACK_RAST (1 << 1) struct nv40_channel_context { struct nouveau_winsys *nvws; @@ -72,6 +73,8 @@ struct nv40_state { unsigned enabled; struct nouveau_stateobj *so; } stipple; + + struct nouveau_stateobj *fragprog; }; struct nv40_context { @@ -96,6 +99,8 @@ struct nv40_context { struct pipe_scissor_state scissor; unsigned stipple[32]; struct pipe_clip_state clip; + struct nv40_fragment_program *fragprog; + struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; } pipe_state; struct nv40_state state; @@ -119,13 +124,6 @@ struct nv40_context { struct pipe_buffer *constant_buf; } vertprog; - struct { - struct nv40_fragment_program *active; - - struct nv40_fragment_program *current; - struct pipe_buffer *constant_buf; - } fragprog; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; }; @@ -161,10 +159,6 @@ extern void nv40_vertprog_destroy(struct nv40_context *, struct nv40_vertex_program *); /* nv40_fragprog.c */ -extern void nv40_fragprog_translate(struct nv40_context *, - struct nv40_fragment_program *); -extern void nv40_fragprog_bind(struct nv40_context *, - struct nv40_fragment_program *); extern void nv40_fragprog_destroy(struct nv40_context *, struct nv40_fragment_program *); @@ -177,6 +171,7 @@ extern void nv40_state_tex_update(struct nv40_context *nv40); extern struct nv40_state_entry nv40_state_clip; extern struct nv40_state_entry nv40_state_scissor; extern struct nv40_state_entry nv40_state_stipple; +extern struct nv40_state_entry nv40_state_fragprog; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 07a418c1e9..bfc75eb462 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -668,7 +668,7 @@ nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, return TRUE; } -void +static void nv40_fragprog_translate(struct nv40_context *nv40, struct nv40_fragment_program *fp) { @@ -750,72 +750,66 @@ nv40_fragprog_translate(struct nv40_context *nv40, fp->insn[fpc->inst_offset + 3] = 0x00000000; fp->translated = TRUE; - fp->on_hw = FALSE; out_err: tgsi_parse_free(&parse); free(fpc); } -void -nv40_fragprog_bind(struct nv40_context *nv40, struct nv40_fragment_program *fp) +static void +nv40_fragprog_upload(struct nv40_context *nv40, + struct nv40_fragment_program *fp) { struct pipe_winsys *ws = nv40->pipe.winsys; - struct nouveau_stateobj *so; + const uint32_t le = 1; + uint32_t *map; int i; - if (!fp->translated) { - nv40_fragprog_translate(nv40, fp); - if (!fp->translated) - assert(0); - } + map = ws->buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); - if (fp->nr_consts) { - float *map = ws->buffer_map(ws, nv40->fragprog.constant_buf, - 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 0 + for (i = 0; i < fp->insn_len; i++) { + NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]); + } +#endif - if (!memcmp(p, cb, 4 * sizeof(float))) - continue; - memcpy(p, cb, 4 * sizeof(float)); - fp->on_hw = 0; + 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, nv40->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); + ws->buffer_unmap(ws, fp->buffer); +} -#if 0 - for (i = 0; i < fp->insn_len; i++) { - NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]); - } -#endif +static boolean +nv40_fragprog_validate(struct nv40_context *nv40) +{ + struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct pipe_buffer *constbuf = + nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT]; + struct pipe_winsys *ws = nv40->pipe.winsys; + struct nouveau_stateobj *so; + unsigned new_program = FALSE; + int i; - 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); - } - } + if (fp->translated) + goto update_constants; - ws->buffer_unmap(ws, fp->buffer); - fp->on_hw = TRUE; + nv40_fragprog_translate(nv40, fp); + if (!fp->translated) { + nv40->fallback |= NV40_FALLBACK_RAST; + return FALSE; } + new_program = TRUE; + + 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->hw->curie, NV40TCL_FP_ADDRESS, 1); @@ -824,12 +818,33 @@ nv40_fragprog_bind(struct nv40_context *nv40, struct nv40_fragment_program *fp) NV40TCL_FP_ADDRESS_DMA0, NV40TCL_FP_ADDRESS_DMA1); so_method(so, nv40->hw->curie, NV40TCL_FP_CONTROL, 1); so_data (so, fp->fp_control); - - so_emit(nv40->nvws, so); so_ref(so, &fp->so); so_ref(NULL, &so); - nv40->fragprog.active = fp; +update_constants: + if (fp->nr_consts) { + boolean new_consts = FALSE; + 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); + } + + so_ref(fp->so, &nv40->state.fragprog); + return new_program; } void @@ -840,3 +855,11 @@ nv40_fragprog_destroy(struct nv40_context *nv40, free(fp->insn); } +struct nv40_state_entry nv40_state_fragprog = { + .validate = nv40_fragprog_validate, + .dirty = { + .pipe = NV40_NEW_FRAGPROG, + .hw = NV40_NEW_FRAGPROG + } +}; + diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 5af5fbe746..811f3098ba 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -125,7 +125,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) void nv40_fragtex_bind(struct nv40_context *nv40) { - struct nv40_fragment_program *fp = nv40->fragprog.active; + struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; unsigned samplers, unit; samplers = nv40->fp_samplers & ~fp->samplers; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index c203b00240..2886c6b0dc 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -523,9 +523,8 @@ static void nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_fragment_program *fp = hwcso; - nv40->fragprog.current = fp; + nv40->pipe_state.fragprog = hwcso; nv40->dirty |= NV40_NEW_FRAGPROG; } @@ -578,7 +577,7 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, nv40->dirty |= NV40_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { - nv40->fragprog.constant_buf = buf->buffer; + nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; nv40->dirty |= NV40_NEW_FRAGPROG; } } diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index e82ab9de98..2701294a07 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -50,7 +50,6 @@ struct nv40_fragment_program { const struct pipe_shader_state *pipe; boolean translated; - boolean on_hw; unsigned samplers; uint32_t *insn; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index b5d0d68d6b..e10e178432 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -19,21 +19,14 @@ nv40_state_emit_dummy_relocs(struct nv40_context *nv40) continue; so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]); } - so_emit_reloc_markers(nv40->nvws, nv40->fragprog.active->so); -} - -static boolean -nv40_state_clip_validate(struct nv40_context *nv40) -{ - if (nv40->pipe_state.clip.nr) - nv40->fallback |= NV40_FALLBACK_TNL; - return FALSE; + so_emit_reloc_markers(nv40->nvws, nv40->state.fragprog); } static struct nv40_state_entry *render_states[] = { &nv40_state_clip, &nv40_state_scissor, &nv40_state_stipple, + &nv40_state_fragprog, NULL }; @@ -65,6 +58,15 @@ nv40_state_validate(struct nv40_context *nv40) !(nv40->fallback & NV40_FALLBACK_TNL)) { NOUVEAU_ERR("XXX: swtnl->hwtnl\n"); } + + if (nv40->fallback & NV40_FALLBACK_RAST && + !(last_fallback & NV40_FALLBACK_RAST)) { + NOUVEAU_ERR("XXX: hwrast->swrast\n"); + } else + if (last_fallback & NV40_FALLBACK_RAST && + !(nv40->fallback & NV40_FALLBACK_RAST)) { + NOUVEAU_ERR("XXX: swrast->hwrast\n"); + } } void @@ -100,10 +102,8 @@ nv40_emit_hw_state(struct nv40_context *nv40) nv40->hw_dirty &= ~NV40_NEW_STIPPLE; } - if (nv40->dirty & NV40_NEW_FRAGPROG) { - nv40_fragprog_bind(nv40, nv40->fragprog.current); - /*XXX: clear NV40_NEW_FRAGPROG if no new program uploaded */ - } + if (nv40->hw_dirty & NV40_NEW_FRAGPROG) + so_emit(nv40->nvws, nv40->state.fragprog); if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { nv40_fragtex_bind(nv40); -- cgit v1.2.3 From 9a5dd26fe22c37b85787130a2b724e6e8ef4f553 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 17:36:24 +1100 Subject: nv40: and vertprog.. --- src/gallium/drivers/nv40/nv40_context.h | 14 ++------ src/gallium/drivers/nv40/nv40_fragprog.c | 10 +++--- src/gallium/drivers/nv40/nv40_state.c | 5 ++- src/gallium/drivers/nv40/nv40_state.h | 1 + src/gallium/drivers/nv40/nv40_state_emit.c | 3 +- src/gallium/drivers/nv40/nv40_vbo.c | 2 +- src/gallium/drivers/nv40/nv40_vertprog.c | 57 +++++++++++++++++++++--------- 7 files changed, 55 insertions(+), 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index ce0933fea4..28a0274d77 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -75,6 +75,7 @@ struct nv40_state { } stipple; struct nouveau_stateobj *fragprog; + struct nouveau_stateobj *vertprog; }; struct nv40_context { @@ -99,6 +100,7 @@ struct nv40_context { 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]; } pipe_state; @@ -117,13 +119,6 @@ struct nv40_context { struct nouveau_stateobj *so_viewport; struct nouveau_stateobj *so_stipple; - struct { - struct nv40_vertex_program *active; - - struct nv40_vertex_program *current; - struct pipe_buffer *constant_buf; - } vertprog; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; }; @@ -151,10 +146,6 @@ extern void nv40_init_query_functions(struct nv40_context *nv40); extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40); /* nv40_vertprog.c */ -extern void nv40_vertprog_translate(struct nv40_context *, - struct nv40_vertex_program *); -extern void nv40_vertprog_bind(struct nv40_context *, - struct nv40_vertex_program *); extern void nv40_vertprog_destroy(struct nv40_context *, struct nv40_vertex_program *); @@ -172,6 +163,7 @@ extern struct nv40_state_entry nv40_state_clip; 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; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index bfc75eb462..77ac8ab2c6 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -795,7 +795,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_winsys *ws = nv40->pipe.winsys; struct nouveau_stateobj *so; - unsigned new_program = FALSE; int i; if (fp->translated) @@ -806,7 +805,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) nv40->fallback |= NV40_FALLBACK_RAST; return FALSE; } - new_program = TRUE; fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); nv40_fragprog_upload(nv40, fp); @@ -843,8 +841,12 @@ update_constants: nv40_fragprog_upload(nv40, fp); } - so_ref(fp->so, &nv40->state.fragprog); - return new_program; + if (fp->so != nv40->state.fragprog) { + so_ref(fp->so, &nv40->state.fragprog); + return TRUE; + } + + return FALSE; } void diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 2886c6b0dc..8ffbb131f7 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -491,9 +491,8 @@ static void nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_vertex_program *vp = hwcso; - nv40->vertprog.current = vp; + nv40->pipe_state.vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; } @@ -573,7 +572,7 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct nv40_context *nv40 = nv40_context(pipe); if (shader == PIPE_SHADER_VERTEX) { - nv40->vertprog.constant_buf = buf->buffer; + nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX] = buf->buffer; nv40->dirty |= NV40_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index 2701294a07..e5217fe91c 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -39,6 +39,7 @@ struct nv40_vertex_program { uint32_t ir; uint32_t or; + struct nouveau_stateobj *so; }; struct nv40_fragment_program_data { diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index e10e178432..e702b10323 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -27,6 +27,7 @@ static struct nv40_state_entry *render_states[] = { &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, + &nv40_state_vertprog, NULL }; @@ -116,7 +117,7 @@ nv40_emit_hw_state(struct nv40_context *nv40) } if (nv40->dirty & NV40_NEW_VERTPROG) { - nv40_vertprog_bind(nv40, nv40->vertprog.current); + so_emit(nv40->nvws, nv40->state.vertprog); nv40->dirty &= ~NV40_NEW_VERTPROG; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index fa827ef0c5..3bfcb264db 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -101,7 +101,7 @@ static void nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib, unsigned ib_format) { - struct nv40_vertex_program *vp = nv40->vertprog.active; + struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; struct nouveau_stateobj *vtxbuf, *vtxfmt; unsigned inputs, hw, num_hw; unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 9f4738b830..4a15e51eb3 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -558,7 +558,7 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) return TRUE; } -void +static void nv40_vertprog_translate(struct nv40_context *nv40, struct nv40_vertex_program *vp) { @@ -631,24 +631,32 @@ out_err: free(vpc); } -void -nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) +static boolean +nv40_vertprog_validate(struct nv40_context *nv40) { + struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct pipe_buffer *constbuf = + nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX]; struct nouveau_winsys *nvws = nv40->nvws; struct pipe_winsys *ws = nv40->pipe.winsys; boolean upload_code = FALSE, upload_data = FALSE; int i; /* Translate TGSI shader into hw bytecode */ + if (vp->translated) + goto check_gpu_resources; + + nv40_vertprog_translate(nv40, vp); if (!vp->translated) { - nv40_vertprog_translate(nv40, vp); - if (!vp->translated) - assert(0); + nv40->fallback |= NV40_FALLBACK_TNL; + return FALSE; } +check_gpu_resources: /* Allocate hw vtxprog exec slots */ if (!vp->exec) { struct nouveau_resource *heap = nv40->hw->vp_exec_heap; + struct nouveau_stateobj *so; uint vplen = vp->nr_insns; if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) { @@ -663,6 +671,15 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) assert(0); } + so = so_new(5, 0); + so_method(so, nv40->hw->curie, NV40TCL_VP_START_FROM_ID, 1); + so_data (so, vp->exec->start); + so_method(so, nv40->hw->curie, NV40TCL_VP_ATTRIB_EN, 2); + so_data (so, vp->ir); + so_data (so, vp->or); + so_ref(so, &vp->so); + so_ref(NULL, &so); + upload_code = TRUE; } @@ -725,8 +742,8 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) if (vp->nr_consts) { float *map = NULL; - if (nv40->vertprog.constant_buf) { - map = ws->buffer_map(ws, nv40->vertprog.constant_buf, + if (constbuf) { + map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); } @@ -747,9 +764,8 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) OUT_RINGp ((uint32_t *)vpd->value, 4); } - if (map) { - ws->buffer_unmap(ws, nv40->vertprog.constant_buf); - } + if (constbuf) + ws->buffer_unmap(ws, constbuf); } /* Upload vtxprog */ @@ -770,13 +786,12 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) } } - BEGIN_RING(curie, NV40TCL_VP_START_FROM_ID, 1); - OUT_RING (vp->exec->start); - BEGIN_RING(curie, NV40TCL_VP_ATTRIB_EN, 2); - OUT_RING (vp->ir); - OUT_RING (vp->or); + if (vp->so != nv40->state.vertprog) { + so_ref(vp->so, &nv40->state.vertprog); + return TRUE; + } - nv40->vertprog.active = vp; + return FALSE; } void @@ -788,3 +803,11 @@ nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp) free(vp->insns); } +struct nv40_state_entry nv40_state_vertprog = { + .validate = nv40_vertprog_validate, + .dirty = { + .pipe = NV40_NEW_VERTPROG, + .hw = NV40_NEW_VERTPROG + } +}; + -- cgit v1.2.3 From c0f9cab905f3f54cc01bf947665f8a731b8cb347 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Feb 2008 18:23:12 +1100 Subject: nouveau: cleanups + fixes --- src/gallium/drivers/nouveau/nouveau_stateobj.h | 21 +++++++++------------ src/gallium/drivers/nv40/nv40_state_emit.c | 8 +++++--- 2 files changed, 14 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index 07c31b014a..459cc7d77a 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -45,22 +45,19 @@ so_new(unsigned push, unsigned reloc) static INLINE void so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso) { - struct nouveau_stateobj *so; - - so = *pso; - if (so) { - if (--so->refcount <= 0) { - free(so->push); - free(so->reloc); - free(so); - } - *pso = NULL; - } + struct nouveau_stateobj *so = *pso; if (ref) { ref->refcount++; - *pso = ref; } + + if (so && --so->refcount <= 0) { + free(so->push); + free(so->reloc); + free(so); + } + + *pso = ref; } static INLINE void diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index e702b10323..e8230111bb 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -103,8 +103,10 @@ nv40_emit_hw_state(struct nv40_context *nv40) nv40->hw_dirty &= ~NV40_NEW_STIPPLE; } - if (nv40->hw_dirty & NV40_NEW_FRAGPROG) + if (nv40->hw_dirty & NV40_NEW_FRAGPROG) { so_emit(nv40->nvws, nv40->state.fragprog); + nv40->hw_dirty &= ~NV40_NEW_FRAGPROG; + } if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { nv40_fragtex_bind(nv40); @@ -116,9 +118,9 @@ nv40_emit_hw_state(struct nv40_context *nv40) nv40->dirty &= ~NV40_NEW_FRAGPROG; } - if (nv40->dirty & NV40_NEW_VERTPROG) { + if (nv40->hw_dirty & NV40_NEW_VERTPROG) { so_emit(nv40->nvws, nv40->state.vertprog); - nv40->dirty &= ~NV40_NEW_VERTPROG; + nv40->hw_dirty &= ~NV40_NEW_VERTPROG; } nv40->dirty_samplers = 0; -- cgit v1.2.3 From 46c3d0918dd7a47f69c21e4eb1a3fd2a2fbe6223 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Feb 2008 16:21:28 +1100 Subject: nv40: keep track of generated context state vs current channel state --- src/gallium/drivers/nv40/nv40_context.h | 26 ++++++----- src/gallium/drivers/nv40/nv40_fragprog.c | 6 +-- src/gallium/drivers/nv40/nv40_state_emit.c | 67 ++++++++++----------------- src/gallium/drivers/nv40/nv40_state_scissor.c | 8 ++-- src/gallium/drivers/nv40/nv40_state_stipple.c | 8 ++-- src/gallium/drivers/nv40/nv40_vertprog.c | 6 +-- 6 files changed, 53 insertions(+), 68 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 28a0274d77..2dd137ead0 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -22,6 +22,15 @@ #define NOUVEAU_MSG(fmt, args...) \ fprintf(stderr, "nouveau: "fmt, ##args); +enum nv40_state_index { + NV40_STATE_CLIP = 1ULL, + NV40_STATE_SCISSOR = 2ULL, + NV40_STATE_STIPPLE = 3ULL, + NV40_STATE_FRAGPROG = 4ULL, + NV40_STATE_VERTPROG = 5ULL, + NV40_STATE_MAX = 6ULL +}; + #define NV40_NEW_BLEND (1 << 0) #define NV40_NEW_RAST (1 << 1) #define NV40_NEW_ZSA (1 << 2) @@ -56,6 +65,9 @@ struct nv40_channel_context { /* 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]; }; struct nv40_rasterizer_state { @@ -64,18 +76,10 @@ struct nv40_rasterizer_state { }; struct nv40_state { - struct { - unsigned enabled; - struct nouveau_stateobj *so; - } scissor; - - struct { - unsigned enabled; - struct nouveau_stateobj *so; - } stipple; + unsigned scissor_enabled; + unsigned stipple_enabled; - struct nouveau_stateobj *fragprog; - struct nouveau_stateobj *vertprog; + struct nouveau_stateobj *hw[NV40_STATE_MAX]; }; struct nv40_context { diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 77ac8ab2c6..db2613ef8b 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -841,8 +841,8 @@ update_constants: nv40_fragprog_upload(nv40, fp); } - if (fp->so != nv40->state.fragprog) { - so_ref(fp->so, &nv40->state.fragprog); + if (fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) { + so_ref(fp->so, &nv40->state.hw[NV40_STATE_FRAGPROG]); return TRUE; } @@ -861,7 +861,7 @@ struct nv40_state_entry nv40_state_fragprog = { .validate = nv40_fragprog_validate, .dirty = { .pipe = NV40_NEW_FRAGPROG, - .hw = NV40_NEW_FRAGPROG + .hw = NV40_STATE_FRAGPROG } }; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index e8230111bb..58beb72389 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -1,27 +1,6 @@ #include "nv40_context.h" #include "nv40_state.h" -/* Emit relocs for every referenced buffer. - * - * This is to ensure the bufmgr has an accurate idea of how - * the buffer is used. These relocs appear in the push buffer as - * NOPs, and will only be turned into state changes if a buffer - * actually moves. - */ -static void -nv40_state_emit_dummy_relocs(struct nv40_context *nv40) -{ - unsigned i; - - so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer); - for (i = 0; i < 16; i++) { - if (!(nv40->fp_samplers & (1 << i))) - continue; - so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]); - } - so_emit_reloc_markers(nv40->nvws, nv40->state.fragprog); -} - static struct nv40_state_entry *render_states[] = { &nv40_state_clip, &nv40_state_scissor, @@ -45,7 +24,7 @@ nv40_state_validate(struct nv40_context *nv40) if (nv40->dirty & e->dirty.pipe) { if (e->validate(nv40)) - nv40->hw_dirty |= e->dirty.hw; + nv40->hw_dirty |= (1 << e->dirty.hw); } states++; @@ -70,6 +49,28 @@ nv40_state_validate(struct nv40_context *nv40) } } +static void +nv40_state_emit(struct nv40_context *nv40) +{ + unsigned i; + + while (nv40->hw_dirty) { + unsigned idx = ffs(nv40->hw_dirty) - 1; + nv40->hw_dirty &= ~(1 << idx); + + so_ref (nv40->state.hw[idx], &nv40->hw->state[idx]); + so_emit(nv40->nvws, nv40->hw->state[idx]); + } + + so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer); + for (i = 0; i < 16; i++) { + if (!(nv40->fp_samplers & (1 << i))) + continue; + so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]); + } + so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FRAGPROG]); +} + void nv40_emit_hw_state(struct nv40_context *nv40) { @@ -90,24 +91,9 @@ nv40_emit_hw_state(struct nv40_context *nv40) if (nv40->dirty & NV40_NEW_BCOL) so_emit(nv40->nvws, nv40->so_bcol); - if (nv40->hw_dirty & NV40_NEW_SCISSOR) { - so_emit(nv40->nvws, nv40->state.scissor.so); - nv40->hw_dirty &= ~NV40_NEW_SCISSOR; - } - if (nv40->dirty & NV40_NEW_VIEWPORT) so_emit(nv40->nvws, nv40->so_viewport); - if (nv40->hw_dirty & NV40_NEW_STIPPLE) { - so_emit(nv40->nvws, nv40->state.stipple.so); - nv40->hw_dirty &= ~NV40_NEW_STIPPLE; - } - - if (nv40->hw_dirty & NV40_NEW_FRAGPROG) { - so_emit(nv40->nvws, nv40->state.fragprog); - nv40->hw_dirty &= ~NV40_NEW_FRAGPROG; - } - if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { nv40_fragtex_bind(nv40); @@ -118,14 +104,9 @@ nv40_emit_hw_state(struct nv40_context *nv40) nv40->dirty &= ~NV40_NEW_FRAGPROG; } - if (nv40->hw_dirty & NV40_NEW_VERTPROG) { - so_emit(nv40->nvws, nv40->state.vertprog); - nv40->hw_dirty &= ~NV40_NEW_VERTPROG; - } + nv40_state_emit(nv40); nv40->dirty_samplers = 0; nv40->dirty = 0; - - nv40_state_emit_dummy_relocs(nv40); } diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index 556b820e58..dc7b6d3a9d 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -7,8 +7,8 @@ nv40_state_scissor_validate(struct nv40_context *nv40) struct pipe_scissor_state *s = &nv40->pipe_state.scissor; struct nouveau_stateobj *so; - if (nv40->state.scissor.so && - (rast->scissor == 0 && nv40->state.scissor.enabled == 0)) + if (nv40->state.hw[NV40_STATE_SCISSOR] && + (rast->scissor == 0 && nv40->state.scissor_enabled == 0)) return FALSE; so = so_new(3, 0); @@ -21,7 +21,7 @@ nv40_state_scissor_validate(struct nv40_context *nv40) so_data (so, 4096 << 16); } - so_ref(so, &nv40->state.scissor.so); + so_ref(so, &nv40->state.hw[NV40_STATE_SCISSOR]); so_ref(NULL, &so); return TRUE; } @@ -30,6 +30,6 @@ struct nv40_state_entry nv40_state_scissor = { .validate = nv40_state_scissor_validate, .dirty = { .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, - .hw = NV40_NEW_SCISSOR + .hw = NV40_STATE_SCISSOR } }; diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index 52462a0b50..1b0b194432 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -7,8 +7,8 @@ nv40_state_stipple_validate(struct nv40_context *nv40) struct nouveau_grobj *curie = nv40->hw->curie; struct nouveau_stateobj *so; - if (nv40->state.stipple.so && (rast->poly_stipple_enable == 0 && - nv40->state.stipple.enabled == 0)) + if (nv40->state.hw[NV40_STATE_STIPPLE] && + (rast->poly_stipple_enable == 0 && nv40->state.stipple_enabled == 0)) return FALSE; if (rast->poly_stipple_enable) { @@ -26,7 +26,7 @@ nv40_state_stipple_validate(struct nv40_context *nv40) so_data (so, 0); } - so_ref(so, &nv40->state.stipple.so); + so_ref(so, &nv40->state.hw[NV40_STATE_STIPPLE]); so_ref(NULL, &so); return TRUE; } @@ -35,6 +35,6 @@ struct nv40_state_entry nv40_state_stipple = { .validate = nv40_state_stipple_validate, .dirty = { .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, - .hw = NV40_NEW_STIPPLE + .hw = NV40_STATE_STIPPLE, } }; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 4a15e51eb3..8a2d233697 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -786,8 +786,8 @@ check_gpu_resources: } } - if (vp->so != nv40->state.vertprog) { - so_ref(vp->so, &nv40->state.vertprog); + if (vp->so != nv40->state.hw[NV40_STATE_VERTPROG]) { + so_ref(vp->so, &nv40->state.hw[NV40_STATE_VERTPROG]); return TRUE; } @@ -807,7 +807,7 @@ struct nv40_state_entry nv40_state_vertprog = { .validate = nv40_vertprog_validate, .dirty = { .pipe = NV40_NEW_VERTPROG, - .hw = NV40_NEW_VERTPROG + .hw = NV40_STATE_VERTPROG, } }; -- cgit v1.2.3 From 9cd10d7618a226fe46395b08beb19e420bc14a4f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Feb 2008 17:14:41 +1100 Subject: nv40: almost there.. --- src/gallium/drivers/nv40/Makefile | 6 ++- src/gallium/drivers/nv40/nv40_context.h | 66 +++++++++++++++++++----- src/gallium/drivers/nv40/nv40_state.c | 62 +++++++++------------- src/gallium/drivers/nv40/nv40_state_blend.c | 41 +++++++++++++++ src/gallium/drivers/nv40/nv40_state_emit.c | 20 ++----- src/gallium/drivers/nv40/nv40_state_rasterizer.c | 17 ++++++ src/gallium/drivers/nv40/nv40_state_scissor.c | 2 +- src/gallium/drivers/nv40/nv40_state_stipple.c | 2 +- src/gallium/drivers/nv40/nv40_state_viewport.c | 30 +++++++++++ src/gallium/drivers/nv40/nv40_state_zsa.c | 17 ++++++ 10 files changed, 194 insertions(+), 69 deletions(-) create mode 100644 src/gallium/drivers/nv40/nv40_state_blend.c create mode 100644 src/gallium/drivers/nv40/nv40_state_rasterizer.c create mode 100644 src/gallium/drivers/nv40/nv40_state_viewport.c create mode 100644 src/gallium/drivers/nv40/nv40_state_zsa.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 12b8eef259..82295cbefc 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -12,10 +12,14 @@ DRIVER_SOURCES = \ nv40_miptree.c \ nv40_query.c \ nv40_state.c \ - nv40_state_emit.c \ + nv40_state_blend.c \ nv40_state_clip.c \ + nv40_state_emit.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 diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 2dd137ead0..d71fe11a4a 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -23,12 +23,38 @@ fprintf(stderr, "nouveau: "fmt, ##args); enum nv40_state_index { - NV40_STATE_CLIP = 1ULL, - NV40_STATE_SCISSOR = 2ULL, - NV40_STATE_STIPPLE = 3ULL, - NV40_STATE_FRAGPROG = 4ULL, - NV40_STATE_VERTPROG = 5ULL, - NV40_STATE_MAX = 6ULL + 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_MAX = 31 }; #define NV40_NEW_BLEND (1 << 0) @@ -75,6 +101,17 @@ struct nv40_rasterizer_state { 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; @@ -107,6 +144,11 @@ struct nv40_context { struct nv40_vertex_program *vertprog; struct nv40_fragment_program *fragprog; struct pipe_buffer *constbuf[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; } pipe_state; struct nv40_state state; @@ -115,13 +157,6 @@ struct nv40_context { struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; struct nouveau_stateobj *so_vtxbuf; - struct nouveau_stateobj *so_blend; - struct nv40_rasterizer_state *rasterizer; - struct nouveau_stateobj *so_rast; - struct nouveau_stateobj *so_zsa; - struct nouveau_stateobj *so_bcol; - struct nouveau_stateobj *so_viewport; - struct nouveau_stateobj *so_stipple; struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; @@ -164,10 +199,15 @@ extern void nv40_fragtex_bind(struct nv40_context *); extern void nv40_emit_hw_state(struct nv40_context *nv40); extern void nv40_state_tex_update(struct nv40_context *nv40); extern struct nv40_state_entry nv40_state_clip; +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; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 8ffbb131f7..41631ef2dd 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -11,6 +11,7 @@ nv40_blend_state_create(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); struct nouveau_grobj *curie = nv40->hw->curie; + struct nv40_blend_state *bso = MALLOC(sizeof(*bso)); struct nouveau_stateobj *so = so_new(16, 0); if (cso->blend_enable) { @@ -46,7 +47,9 @@ nv40_blend_state_create(struct pipe_context *pipe, so_method(so, curie, NV40TCL_DITHER_ENABLE, 1); so_data (so, cso->dither ? 1 : 0); - return (void *)so; + bso->so = so; + bso->pipe = *cso; + return (void *)bso; } static void @@ -54,16 +57,17 @@ nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - so_ref(hwcso, &nv40->so_blend); + nv40->pipe_state.blend = hwcso; nv40->dirty |= NV40_NEW_BLEND; } static void nv40_blend_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nouveau_stateobj *so = hwcso; + struct nv40_blend_state *bso = hwcso; - so_ref(NULL, &so); + so_ref(NULL, &bso->so); + FREE(bso); } @@ -260,7 +264,7 @@ nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit, static void nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + FREE(hwcso); } static void @@ -392,10 +396,8 @@ static void nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_rasterizer_state *rsso = hwcso; - so_ref(rsso->so, &nv40->so_rast); - nv40->rasterizer = rsso; + nv40->pipe_state.rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; } @@ -405,7 +407,7 @@ nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) struct nv40_rasterizer_state *rsso = hwcso; so_ref(NULL, &rsso->so); - free(rsso); + FREE(rsso); } static void * @@ -413,6 +415,7 @@ 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 = MALLOC(sizeof(*zsaso)); struct nouveau_stateobj *so = so_new(32, 0); so_method(so, nv40->hw->curie, NV40TCL_DEPTH_FUNC, 3); @@ -455,7 +458,9 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, 0); } - return (void *)so; + zsaso->so = so; + zsaso->pipe = *cso; + return (void *)zsaso; } static void @@ -463,16 +468,17 @@ nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - so_ref(hwcso, &nv40->so_zsa); + nv40->pipe_state.zsa = hwcso; nv40->dirty |= NV40_NEW_ZSA; } static void nv40_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nouveau_stateobj *so = hwcso; + struct nv40_zsa_state *zsaso = hwcso; - so_ref(NULL, &so); + so_ref(NULL, &zsaso->so); + FREE(zsaso); } static void * @@ -503,7 +509,7 @@ nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv40_vertex_program *vp = hwcso; nv40_vertprog_destroy(nv40, vp); - free(vp); + FREE(vp); } static void * @@ -534,7 +540,7 @@ nv40_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv40_fragment_program *fp = hwcso; nv40_fragprog_destroy(nv40, fp); - free(fp); + FREE(fp); } static void @@ -542,16 +548,8 @@ nv40_set_blend_color(struct pipe_context *pipe, const struct pipe_blend_color *bcol) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_stateobj *so = so_new(2, 0); - - so_method(so, nv40->hw->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->so_bcol); - so_ref(NULL, &so); + nv40->pipe_state.blend_colour = *bcol; nv40->dirty |= NV40_NEW_BCOL; } @@ -754,20 +752,8 @@ nv40_set_viewport_state(struct pipe_context *pipe, const struct pipe_viewport_state *vpt) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_stateobj *so = so_new(9, 0); - - so_method(so, nv40->hw->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_ref(so, &nv40->so_viewport); - so_ref(NULL, &so); + + nv40->pipe_state.viewport = *vpt; nv40->dirty |= NV40_NEW_VIEWPORT; } 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 0000000000..b12f8b03dd --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -0,0 +1,41 @@ +#include "nv40_context.h" + +static boolean +nv40_state_blend_validate(struct nv40_context *nv40) +{ + so_ref(nv40->pipe_state.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->pipe_state.blend_colour; + + so_method(so, nv40->hw->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]); + so_ref(NULL, &so); + 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 index 58beb72389..65d7e2978a 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -2,11 +2,16 @@ #include "nv40_state.h" static struct nv40_state_entry *render_states[] = { + &nv40_state_rasterizer, &nv40_state_clip, &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, &nv40_state_vertprog, + &nv40_state_blend, + &nv40_state_blend_colour, + &nv40_state_zsa, + &nv40_state_viewport, NULL }; @@ -79,21 +84,6 @@ nv40_emit_hw_state(struct nv40_context *nv40) if (nv40->dirty & NV40_NEW_FB) so_emit(nv40->nvws, nv40->so_framebuffer); - if (nv40->dirty & NV40_NEW_BLEND) - so_emit(nv40->nvws, nv40->so_blend); - - if (nv40->dirty & NV40_NEW_RAST) - so_emit(nv40->nvws, nv40->so_rast); - - if (nv40->dirty & NV40_NEW_ZSA) - so_emit(nv40->nvws, nv40->so_zsa); - - if (nv40->dirty & NV40_NEW_BCOL) - so_emit(nv40->nvws, nv40->so_bcol); - - if (nv40->dirty & NV40_NEW_VIEWPORT) - so_emit(nv40->nvws, nv40->so_viewport); - if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { nv40_fragtex_bind(nv40); 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 0000000000..59b35d1d50 --- /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->pipe_state.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 index dc7b6d3a9d..2871fa2516 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -3,7 +3,7 @@ static boolean nv40_state_scissor_validate(struct nv40_context *nv40) { - struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct pipe_rasterizer_state *rast = &nv40->pipe_state.rasterizer->pipe; struct pipe_scissor_state *s = &nv40->pipe_state.scissor; struct nouveau_stateobj *so; diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index 1b0b194432..bd163582a3 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -3,7 +3,7 @@ static boolean nv40_state_stipple_validate(struct nv40_context *nv40) { - struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct pipe_rasterizer_state *rast = &nv40->pipe_state.rasterizer->pipe; struct nouveau_grobj *curie = nv40->hw->curie; struct nouveau_stateobj *so; 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 0000000000..79fcc31a8b --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -0,0 +1,30 @@ +#include "nv40_context.h" + +static boolean +nv40_state_viewport_validate(struct nv40_context *nv40) +{ + struct nouveau_stateobj *so = so_new(9, 0); + struct pipe_viewport_state *vpt = &nv40->pipe_state.viewport; + + so_method(so, nv40->hw->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_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_viewport = { + .validate = nv40_state_viewport_validate, + .dirty = { + .pipe = NV40_NEW_VIEWPORT, + .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 0000000000..061a3555cb --- /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->pipe_state.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 + } +}; -- cgit v1.2.3 From 759fa5fcc8038af4845a6d9c57b75933ef26559c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Feb 2008 17:22:40 +1100 Subject: nv40: fb state --- src/gallium/drivers/nv40/Makefile | 1 + src/gallium/drivers/nv40/nv40_context.h | 3 +- src/gallium/drivers/nv40/nv40_state.c | 140 +------------------------- src/gallium/drivers/nv40/nv40_state_emit.c | 6 +- src/gallium/drivers/nv40/nv40_state_fb.c | 156 +++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 144 deletions(-) create mode 100644 src/gallium/drivers/nv40/nv40_state_fb.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 82295cbefc..fd002b54e7 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -15,6 +15,7 @@ DRIVER_SOURCES = \ nv40_state_blend.c \ nv40_state_clip.c \ nv40_state_emit.c \ + nv40_state_fb.c \ nv40_state_rasterizer.c \ nv40_state_scissor.c \ nv40_state_stipple.c \ diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index d71fe11a4a..69062a8a20 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -149,12 +149,12 @@ struct nv40_context { struct nv40_blend_state *blend; struct pipe_blend_color blend_colour; struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; } pipe_state; struct nv40_state state; unsigned fallback; - struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; struct nouveau_stateobj *so_vtxbuf; @@ -208,6 +208,7 @@ 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; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 41631ef2dd..84818d6729 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -584,146 +584,8 @@ nv40_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct nv40_context *nv40 = nv40_context(pipe); - struct pipe_surface *rt[4], *zeta; - uint32_t rt_enable, rt_format, w, h; - 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; - - rt_enable = 0; - for (i = 0; i < 4; 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 |= (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) { - 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 = 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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->curie, NV40TCL_COLOR3_PITCH, 1); - so_data (so, rt[3]->pitch * rt[3]->cpp); - } - - if (zeta_format) { - so_method(so, nv40->hw->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->hw->curie, NV40TCL_ZETA_OFFSET, 1); - so_reloc (so, zeta->buffer, zeta->offset, rt_flags | - NOUVEAU_BO_LOW, 0, 0); - so_method(so, nv40->hw->curie, NV40TCL_ZETA_PITCH, 1); - so_data (so, zeta->pitch * zeta->cpp); - } - so_method(so, nv40->hw->curie, NV40TCL_RT_ENABLE, 1); - so_data (so, rt_enable); - so_method(so, nv40->hw->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->hw->curie, NV40TCL_VIEWPORT_HORIZ, 2); - so_data (so, (w << 16) | 0); - so_data (so, (h << 16) | 0); - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); - so_data (so, ((w - 1) << 16) | 0); - so_data (so, ((h - 1) << 16) | 0); - - so_ref(so, &nv40->so_framebuffer); - so_ref(NULL, &so); + nv40->pipe_state.framebuffer = *fb; nv40->dirty |= NV40_NEW_FB; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 65d7e2978a..a9ca71c5e9 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -2,6 +2,7 @@ #include "nv40_state.h" static struct nv40_state_entry *render_states[] = { + &nv40_state_framebuffer, &nv40_state_rasterizer, &nv40_state_clip, &nv40_state_scissor, @@ -67,7 +68,7 @@ nv40_state_emit(struct nv40_context *nv40) so_emit(nv40->nvws, nv40->hw->state[idx]); } - so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer); + so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FB]); for (i = 0; i < 16; i++) { if (!(nv40->fp_samplers & (1 << i))) continue; @@ -81,9 +82,6 @@ nv40_emit_hw_state(struct nv40_context *nv40) { nv40_state_validate(nv40); - if (nv40->dirty & NV40_NEW_FB) - so_emit(nv40->nvws, nv40->so_framebuffer); - if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { nv40_fragtex_bind(nv40); 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 0000000000..d3032f1be5 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -0,0 +1,156 @@ +#include "nv40_context.h" + +static boolean +nv40_state_framebuffer_validate(struct nv40_context *nv40) +{ + struct pipe_framebuffer_state *fb = &nv40->pipe_state.framebuffer; + struct pipe_surface *rt[4], *zeta; + uint32_t rt_enable, rt_format, w, h; + 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; + + rt_enable = 0; + for (i = 0; i < 4; 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 |= (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) { + 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 = 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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->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->hw->curie, NV40TCL_COLOR3_PITCH, 1); + so_data (so, rt[3]->pitch * rt[3]->cpp); + } + + if (zeta_format) { + so_method(so, nv40->hw->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->hw->curie, NV40TCL_ZETA_OFFSET, 1); + so_reloc (so, zeta->buffer, zeta->offset, rt_flags | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, nv40->hw->curie, NV40TCL_ZETA_PITCH, 1); + so_data (so, zeta->pitch * zeta->cpp); + } + + so_method(so, nv40->hw->curie, NV40TCL_RT_ENABLE, 1); + so_data (so, rt_enable); + so_method(so, nv40->hw->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->hw->curie, NV40TCL_VIEWPORT_HORIZ, 2); + so_data (so, (w << 16) | 0); + so_data (so, (h << 16) | 0); + so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); + so_data (so, ((w - 1) << 16) | 0); + so_data (so, ((h - 1) << 16) | 0); + + so_ref(so, &nv40->state.hw[NV40_STATE_FB]); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_framebuffer = { + .validate = nv40_state_framebuffer_validate, + .dirty = { + .pipe = NV40_NEW_FB, + .hw = NV40_STATE_FB + } +}; -- cgit v1.2.3 From 73e0e567dea3cf4e1591acb3e894eecef812f367 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Feb 2008 12:36:48 +1100 Subject: nouveau: fix build --- configs/default | 2 +- src/gallium/drivers/nv40/nv40_miptree.c | 38 +++++++++++++++++++++++++++++++++ src/gallium/drivers/nv40/nv40_surface.c | 31 --------------------------- 3 files changed, 39 insertions(+), 32 deletions(-) (limited to 'src/gallium') diff --git a/configs/default b/configs/default index 48ddd29282..af9ff6f426 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 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 nv30 nv40 nv50 failover GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = xlib diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 92e6b3a43d..5e1c7ade31 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -63,6 +63,7 @@ nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) if (!mt) return NULL; mt->base = *pt; + mt->base.refcount = 1; nv40_miptree_layout(mt); mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, @@ -95,10 +96,47 @@ nv40_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) } } +static void +nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) +{ +} + +static struct pipe_surface * +nv40_miptree_surface(struct pipe_context *pipe, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = pipe->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; +} + void nv40_init_miptree_functions(struct nv40_context *nv40) { nv40->pipe.texture_create = nv40_miptree_create; nv40->pipe.texture_release = nv40_miptree_release; + nv40->pipe.texture_update = nv40_miptree_update; + nv40->pipe.get_tex_surface = nv40_miptree_surface; } diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index 9726ab4e4d..df5d7abdbf 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -73,36 +73,6 @@ nv40_surface_format_supported(struct pipe_context *pipe, return FALSE; } -static struct pipe_surface * -nv40_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct pipe_winsys *ws = pipe->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_surface_copy(struct pipe_context *pipe, unsigned do_flip, struct pipe_surface *dest, unsigned destx, unsigned desty, @@ -131,7 +101,6 @@ void nv40_init_surface_functions(struct nv40_context *nv40) { nv40->pipe.is_format_supported = nv40_surface_format_supported; - nv40->pipe.get_tex_surface = nv40_get_tex_surface; nv40->pipe.surface_copy = nv40_surface_copy; nv40->pipe.surface_fill = nv40_surface_fill; } -- cgit v1.2.3 From 5b2ff28a2fd3bb0ca9df569edcaf80e8141ccaa1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Feb 2008 13:32:51 +1100 Subject: nv40: rework fragment texture state --- src/gallium/drivers/nv40/nv40_context.h | 2 +- src/gallium/drivers/nv40/nv40_fragtex.c | 36 +++++++++++++++++++++--------- src/gallium/drivers/nv40/nv40_state.c | 2 ++ src/gallium/drivers/nv40/nv40_state_emit.c | 22 +++++++----------- 4 files changed, 36 insertions(+), 26 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 69062a8a20..cbc798fbd6 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -155,7 +155,6 @@ struct nv40_context { struct nv40_state state; unsigned fallback; - struct nouveau_stateobj *so_fragtex[16]; struct nouveau_stateobj *so_vtxbuf; struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; @@ -209,6 +208,7 @@ 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; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 811f3098ba..826d4a9478 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -52,7 +52,7 @@ nv40_fragtex_format(uint pipe_format) } -static void +static struct nouveau_stateobj * nv40_fragtex_build(struct nv40_context *nv40, int unit) { struct nv40_sampler_state *ps = nv40->tex_sampler[unit]; @@ -90,7 +90,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) break; default: NOUVEAU_ERR("Unknown target %d\n", pt->target); - return; + return NULL; } if (swizzled) { @@ -117,15 +117,14 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) so_method(so, nv40->hw->curie, NV40TCL_TEX_SIZE1(unit), 1); so_data (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); - so_emit(nv40->nvws, so); - so_ref (so, &nv40->so_fragtex[unit]); - so_ref (NULL, &so); + return so; } -void -nv40_fragtex_bind(struct nv40_context *nv40) +static boolean +nv40_fragtex_validate(struct nv40_context *nv40) { struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct nouveau_stateobj *so; unsigned samplers, unit; samplers = nv40->fp_samplers & ~fp->samplers; @@ -133,9 +132,12 @@ nv40_fragtex_bind(struct nv40_context *nv40) unit = ffs(samplers) - 1; samplers &= ~(1 << unit); - so_ref(NULL, &nv40->so_fragtex[unit]); - BEGIN_RING(curie, NV40TCL_TEX_ENABLE(unit), 1); - OUT_RING (0); + so = so_new(2, 0); + so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1); + so_data (so, 0); + so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); + so_ref(NULL, &so); + nv40->hw_dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } samplers = nv40->dirty_samplers & fp->samplers; @@ -143,9 +145,21 @@ nv40_fragtex_bind(struct nv40_context *nv40) unit = ffs(samplers) - 1; samplers &= ~(1 << unit); - nv40_fragtex_build(nv40, unit); + so = nv40_fragtex_build(nv40, unit); + so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); + so_ref(NULL, &so); + nv40->hw_dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } nv40->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_state.c b/src/gallium/drivers/nv40/nv40_state.c index 84818d6729..74cbabb023 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -259,6 +259,7 @@ nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit, nv40->tex_sampler[unit] = ps; nv40->dirty_samplers |= (1 << unit); + nv40->dirty |= NV40_NEW_SAMPLER; } static void @@ -275,6 +276,7 @@ nv40_set_sampler_texture(struct pipe_context *pipe, unsigned unit, nv40->tex_miptree[unit] = (struct nv40_miptree *)miptree; nv40->dirty_samplers |= (1 << unit); + nv40->dirty |= NV40_NEW_SAMPLER; } static void * diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index a9ca71c5e9..6d87b7b52b 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -8,6 +8,7 @@ static struct nv40_state_entry *render_states[] = { &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, + &nv40_state_fragtex, &nv40_state_vertprog, &nv40_state_blend, &nv40_state_blend_colour, @@ -35,6 +36,7 @@ nv40_state_validate(struct nv40_context *nv40) states++; } + nv40->dirty = 0; if (nv40->fallback & NV40_FALLBACK_TNL && !(last_fallback & NV40_FALLBACK_TNL)) { @@ -72,7 +74,8 @@ nv40_state_emit(struct nv40_context *nv40) for (i = 0; i < 16; i++) { if (!(nv40->fp_samplers & (1 << i))) continue; - so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]); + so_emit_reloc_markers(nv40->nvws, + nv40->state.hw[NV40_STATE_FRAGTEX0+i]); } so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FRAGPROG]); } @@ -81,20 +84,11 @@ void nv40_emit_hw_state(struct nv40_context *nv40) { nv40_state_validate(nv40); - - if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) { - nv40_fragtex_bind(nv40); - - BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (2); - BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (1); - nv40->dirty &= ~NV40_NEW_FRAGPROG; - } - nv40_state_emit(nv40); - nv40->dirty_samplers = 0; - nv40->dirty = 0; + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (2); + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (1); } -- cgit v1.2.3 From c2e36bdd1a58ba6f58c4e72db1f7f64e8bd05901 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Feb 2008 13:55:18 +1100 Subject: nv40: move hw_dirty --- src/gallium/drivers/nv40/nv40_context.h | 5 ++--- src/gallium/drivers/nv40/nv40_fragtex.c | 9 +++++---- src/gallium/drivers/nv40/nv40_state_emit.c | 24 ++++++++++++------------ 3 files changed, 19 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index cbc798fbd6..c533b9e0ef 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -115,7 +115,9 @@ struct nv40_blend_state { struct nv40_state { unsigned scissor_enabled; unsigned stipple_enabled; + unsigned fp_samplers; + unsigned dirty; struct nouveau_stateobj *hw[NV40_STATE_MAX]; }; @@ -129,13 +131,10 @@ struct nv40_context { int chipset; unsigned dirty; - unsigned hw_dirty; struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; unsigned dirty_samplers; - unsigned fp_samplers; - unsigned vp_samplers; struct { struct pipe_scissor_state scissor; diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 826d4a9478..3d27a9bf13 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -124,10 +124,11 @@ static boolean nv40_fragtex_validate(struct nv40_context *nv40) { struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct nv40_state *state = &nv40->state; struct nouveau_stateobj *so; unsigned samplers, unit; - samplers = nv40->fp_samplers & ~fp->samplers; + samplers = state->fp_samplers & ~fp->samplers; while (samplers) { unit = ffs(samplers) - 1; samplers &= ~(1 << unit); @@ -137,7 +138,7 @@ nv40_fragtex_validate(struct nv40_context *nv40) so_data (so, 0); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); so_ref(NULL, &so); - nv40->hw_dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); + state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } samplers = nv40->dirty_samplers & fp->samplers; @@ -148,10 +149,10 @@ nv40_fragtex_validate(struct nv40_context *nv40) so = nv40_fragtex_build(nv40, unit); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); so_ref(NULL, &so); - nv40->hw_dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); + state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } - nv40->fp_samplers = fp->samplers; + nv40->state.fp_samplers = fp->samplers; return FALSE; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 6d87b7b52b..af09ed47d6 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -31,7 +31,7 @@ nv40_state_validate(struct nv40_context *nv40) if (nv40->dirty & e->dirty.pipe) { if (e->validate(nv40)) - nv40->hw_dirty |= (1 << e->dirty.hw); + nv40->state.dirty |= (1 << e->dirty.hw); } states++; @@ -60,24 +60,24 @@ nv40_state_validate(struct nv40_context *nv40) static void nv40_state_emit(struct nv40_context *nv40) { - unsigned i; + struct nv40_state *state = &nv40->state; + unsigned i, samplers; - while (nv40->hw_dirty) { - unsigned idx = ffs(nv40->hw_dirty) - 1; - nv40->hw_dirty &= ~(1 << idx); + while (state->dirty) { + unsigned idx = ffs(state->dirty) - 1; - so_ref (nv40->state.hw[idx], &nv40->hw->state[idx]); + so_ref (state->hw[idx], &nv40->hw->state[idx]); so_emit(nv40->nvws, nv40->hw->state[idx]); + state->dirty &= ~(1 << idx); } - so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FB]); - for (i = 0; i < 16; i++) { - if (!(nv40->fp_samplers & (1 << i))) - continue; + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]); + for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { so_emit_reloc_markers(nv40->nvws, - nv40->state.hw[NV40_STATE_FRAGTEX0+i]); + state->hw[NV40_STATE_FRAGTEX0+i]); + samplers &= ~(1 << i); } - so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FRAGPROG]); + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]); } void -- cgit v1.2.3 From 7b938431d0ab5ccce1e7e2b1c38e1dcbdc6001e8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Feb 2008 14:46:48 +1100 Subject: nv40: stateobj start out with 0 refcount --- src/gallium/drivers/nouveau/nouveau_stateobj.h | 2 +- src/gallium/drivers/nv40/nv40_fragprog.c | 1 - src/gallium/drivers/nv40/nv40_fragtex.c | 2 -- src/gallium/drivers/nv40/nv40_state.c | 12 ++++++------ src/gallium/drivers/nv40/nv40_state_blend.c | 1 - src/gallium/drivers/nv40/nv40_state_fb.c | 1 - src/gallium/drivers/nv40/nv40_state_scissor.c | 1 - src/gallium/drivers/nv40/nv40_state_stipple.c | 1 - src/gallium/drivers/nv40/nv40_state_viewport.c | 1 - src/gallium/drivers/nv40/nv40_vbo.c | 1 - src/gallium/drivers/nv40/nv40_vertprog.c | 1 - 11 files changed, 7 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index 459cc7d77a..439c7e4734 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -32,7 +32,7 @@ so_new(unsigned push, unsigned reloc) struct nouveau_stateobj *so; so = MALLOC(sizeof(struct nouveau_stateobj)); - so->refcount = 1; + so->refcount = 0; so->push = MALLOC(sizeof(unsigned) * push); so->reloc = MALLOC(sizeof(struct nouveau_stateobj_reloc) * reloc); diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index db2613ef8b..a4a1ea01e0 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -817,7 +817,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) so_method(so, nv40->hw->curie, NV40TCL_FP_CONTROL, 1); so_data (so, fp->fp_control); so_ref(so, &fp->so); - so_ref(NULL, &so); update_constants: if (fp->nr_consts) { diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 3d27a9bf13..c8a8120f30 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -137,7 +137,6 @@ nv40_fragtex_validate(struct nv40_context *nv40) so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1); so_data (so, 0); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); - so_ref(NULL, &so); state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } @@ -148,7 +147,6 @@ nv40_fragtex_validate(struct nv40_context *nv40) so = nv40_fragtex_build(nv40, unit); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); - so_ref(NULL, &so); state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 74cbabb023..107e60f179 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -11,7 +11,7 @@ nv40_blend_state_create(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); struct nouveau_grobj *curie = nv40->hw->curie; - struct nv40_blend_state *bso = MALLOC(sizeof(*bso)); + struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso)); struct nouveau_stateobj *so = so_new(16, 0); if (cso->blend_enable) { @@ -47,7 +47,7 @@ nv40_blend_state_create(struct pipe_context *pipe, so_method(so, curie, NV40TCL_DITHER_ENABLE, 1); so_data (so, cso->dither ? 1 : 0); - bso->so = so; + so_ref(so, &bso->so); bso->pipe = *cso; return (void *)bso; } @@ -284,7 +284,7 @@ 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 = MALLOC(sizeof(*rsso)); + struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso)); struct nouveau_stateobj *so = so_new(32, 0); struct nouveau_grobj *curie = nv40->hw->curie; @@ -389,7 +389,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, 0); } - rsso->so = so; + so_ref(so, &rsso->so); rsso->pipe = *cso; return (void *)rsso; } @@ -417,7 +417,7 @@ 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 = MALLOC(sizeof(*zsaso)); + struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); struct nouveau_stateobj *so = so_new(32, 0); so_method(so, nv40->hw->curie, NV40TCL_DEPTH_FUNC, 3); @@ -460,7 +460,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, 0); } - zsaso->so = so; + so_ref(so, &zsaso->so); zsaso->pipe = *cso; return (void *)zsaso; } diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c index b12f8b03dd..81b927a67a 100644 --- a/src/gallium/drivers/nv40/nv40_state_blend.c +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -28,7 +28,6 @@ nv40_state_blend_colour_validate(struct nv40_context *nv40) (float_to_ubyte(bcol->color[2]) << 0))); so_ref(so, &nv40->state.hw[NV40_STATE_BCOL]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index d3032f1be5..c3bf4d43a3 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -143,7 +143,6 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) so_data (so, ((h - 1) << 16) | 0); so_ref(so, &nv40->state.hw[NV40_STATE_FB]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index 2871fa2516..ee797094d3 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -22,7 +22,6 @@ nv40_state_scissor_validate(struct nv40_context *nv40) } so_ref(so, &nv40->state.hw[NV40_STATE_SCISSOR]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index bd163582a3..aad4d179ac 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -27,7 +27,6 @@ nv40_state_stipple_validate(struct nv40_context *nv40) } so_ref(so, &nv40->state.hw[NV40_STATE_STIPPLE]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 79fcc31a8b..68820d3133 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -17,7 +17,6 @@ nv40_state_viewport_validate(struct nv40_context *nv40) so_data (so, fui(vpt->scale[3])); so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 3bfcb264db..5abe4c9af1 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -159,7 +159,6 @@ nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib, so_emit(nv40->nvws, vtxfmt); so_emit(nv40->nvws, vtxbuf); so_ref (vtxbuf, &nv40->so_vtxbuf); - so_ref (NULL, &vtxbuf); so_ref (NULL, &vtxfmt); } diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 8a2d233697..c482964adc 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -678,7 +678,6 @@ check_gpu_resources: so_data (so, vp->ir); so_data (so, vp->or); so_ref(so, &vp->so); - so_ref(NULL, &so); upload_code = TRUE; } -- cgit v1.2.3 From 0a5ed0667e6bd934a150bf7f784349fa7f595309 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 22 Feb 2008 17:18:27 +0100 Subject: nv30: wrong number of parameters --- src/gallium/drivers/nv30/nv30_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 53368561e0..db4dac24c7 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -609,7 +609,7 @@ nv30_set_framebuffer_state(struct pipe_context *pipe, } if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) { - BEGIN_RING(rankine, NV34TCL_COLOR1_PITCH, 2); + BEGIN_RING(rankine, NV34TCL_COLOR1_PITCH, 1); OUT_RING (rt[1]->pitch * rt[1]->cpp); nv30->rt[1] = rt[1]->buffer; } -- cgit v1.2.3 From d8a9d850b9d63c7398d596fad2dfd2f05e55ef7d Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 22 Feb 2008 22:21:15 +0100 Subject: nv30: init zeta to NULL, use color pitch if no zeta --- src/gallium/drivers/nv30/nv30_state.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index db4dac24c7..aa3fe7837e 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -537,7 +537,7 @@ 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[4], *zeta; + struct pipe_surface *rt[4], *zeta = NULL; uint32_t rt_enable, rt_format, w, h; int i, colour_format = 0, zeta_format = 0; @@ -603,8 +603,15 @@ nv30_set_framebuffer_state(struct pipe_context *pipe, } 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 ( (rt[0]->pitch * rt[0]->cpp) | ( (zeta->pitch * zeta->cpp) << 16) ); + OUT_RING ( pitch ); nv30->rt[0] = rt[0]->buffer; } -- cgit v1.2.3 From 14de997d5df48512c751c627ab19d486691f591d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Feb 2008 12:26:48 +1100 Subject: nv40: dump meaningful names for surface formats --- src/gallium/drivers/nv40/nv40_fragtex.c | 3 +++ src/gallium/drivers/nv40/nv40_vbo.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index c8a8120f30..7adee8858d 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -41,6 +41,7 @@ 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) @@ -48,6 +49,8 @@ nv40_fragtex_format(uint pipe_format) tf++; } + pf_sprint_name(fs, pipe_format); + NOUVEAU_ERR("unknown texture format %s\n", fs); return NULL; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 5abe4c9af1..753c2fe64b 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -30,9 +30,13 @@ nv40_vbo_type(uint format) case PIPE_FORMAT_TYPE_UNORM: return NV40TCL_VTXFMT_TYPE_UBYTE; default: - NOUVEAU_ERR("Unknown format 0x%08x\n", format); + { + char fs[128]; + pf_sprint_name(fs, format); + NOUVEAU_ERR("Unknown format %s\n", fs); return NV40TCL_VTXFMT_TYPE_FLOAT; } + } } static boolean -- cgit v1.2.3 From 4058a9012764ce3bc7b90d03c4d79d020540f8e4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Feb 2008 13:29:16 +1100 Subject: nv40: construct vbo state the same way as the rest --- src/gallium/drivers/nv40/nv40_context.h | 11 +- src/gallium/drivers/nv40/nv40_fragtex.c | 4 +- src/gallium/drivers/nv40/nv40_state.c | 2 - src/gallium/drivers/nv40/nv40_state_emit.c | 10 +- src/gallium/drivers/nv40/nv40_vbo.c | 246 ++++++++++++++--------------- 5 files changed, 137 insertions(+), 136 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index c533b9e0ef..110d9d7ab7 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -54,7 +54,9 @@ enum nv40_state_index { NV40_STATE_VERTTEX1 = 28, NV40_STATE_VERTTEX2 = 29, NV40_STATE_VERTTEX3 = 30, - NV40_STATE_MAX = 31 + NV40_STATE_VTXBUF = 31, + NV40_STATE_VTXFMT = 32, + NV40_STATE_MAX = 33 }; #define NV40_NEW_BLEND (1 << 0) @@ -117,7 +119,7 @@ struct nv40_state { unsigned stipple_enabled; unsigned fp_samplers; - unsigned dirty; + uint64_t dirty; struct nouveau_stateobj *hw[NV40_STATE_MAX]; }; @@ -149,13 +151,13 @@ struct nv40_context { struct pipe_blend_color blend_colour; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; + struct pipe_buffer *idxbuf; + unsigned idxbuf_format; } pipe_state; struct nv40_state state; unsigned fallback; - struct nouveau_stateobj *so_vtxbuf; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; }; @@ -208,6 +210,7 @@ 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; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 7adee8858d..ed47d707b2 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -140,7 +140,7 @@ nv40_fragtex_validate(struct nv40_context *nv40) so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1); so_data (so, 0); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); - state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); + state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit)); } samplers = nv40->dirty_samplers & fp->samplers; @@ -150,7 +150,7 @@ nv40_fragtex_validate(struct nv40_context *nv40) so = nv40_fragtex_build(nv40, unit); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); - state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); + state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit)); } nv40->state.fp_samplers = fp->samplers; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 107e60f179..e6f2754dc5 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -628,7 +628,6 @@ nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index, struct nv40_context *nv40 = nv40_context(pipe); nv40->vtxbuf[index] = *vb; - nv40->dirty |= NV40_NEW_ARRAYS; } @@ -639,7 +638,6 @@ nv40_set_vertex_element(struct pipe_context *pipe, unsigned index, struct nv40_context *nv40 = nv40_context(pipe); nv40->vtxelt[index] = *ve; - nv40->dirty |= NV40_NEW_ARRAYS; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index af09ed47d6..bb2ce0f722 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -14,6 +14,7 @@ static struct nv40_state_entry *render_states[] = { &nv40_state_blend_colour, &nv40_state_zsa, &nv40_state_viewport, + &nv40_state_vbo, NULL }; @@ -31,7 +32,7 @@ nv40_state_validate(struct nv40_context *nv40) if (nv40->dirty & e->dirty.pipe) { if (e->validate(nv40)) - nv40->state.dirty |= (1 << e->dirty.hw); + nv40->state.dirty |= (1ULL << e->dirty.hw); } states++; @@ -64,20 +65,21 @@ nv40_state_emit(struct nv40_context *nv40) unsigned i, samplers; while (state->dirty) { - unsigned idx = ffs(state->dirty) - 1; + unsigned idx = ffsll(state->dirty) - 1; so_ref (state->hw[idx], &nv40->hw->state[idx]); so_emit(nv40->nvws, nv40->hw->state[idx]); - state->dirty &= ~(1 << idx); + state->dirty &= ~(1ULL << idx); } so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGTEX0+i]); - samplers &= ~(1 << i); + samplers &= ~(1ULL << i); } so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]); + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]); } void diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 753c2fe64b..b5faf06291 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -39,6 +39,43 @@ nv40_vbo_type(uint format) } } +static boolean +nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, + unsigned ib_size) +{ + unsigned type; + + if (!ib) { + nv40->pipe_state.idxbuf = NULL; + nv40->pipe_state.idxbuf_format = 0xdeadbeef; + return FALSE; + } + + /* No support for 8bit indices, no support at all on 0x4497 chips */ + if (nv40->hw->curie->grclass == NV44TCL || 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->pipe_state.idxbuf || + type != nv40->pipe_state.idxbuf_format) { + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->pipe_state.idxbuf = ib; + nv40->pipe_state.idxbuf_format = type; + } + + return TRUE; +} + static boolean nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, struct pipe_vertex_element *ve, @@ -101,104 +138,15 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, return TRUE; } -static void -nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib, - unsigned ib_format) -{ - struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; - struct nouveau_stateobj *vtxbuf, *vtxfmt; - unsigned inputs, hw, num_hw; - unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; - - inputs = vp->ir; - for (hw = 0; hw < 16 && inputs; hw++) { - if (inputs & (1 << hw)) { - num_hw = hw; - inputs &= ~(1 << hw); - } - } - num_hw++; - - vtxbuf = so_new(20, 18); - so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); - vtxfmt = so_new(17, 0); - so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), 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))) { - so_data(vtxbuf, 0); - so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); - continue; - } - - ve = &nv40->vtxelt[hw]; - vb = &nv40->vtxbuf[ve->vertex_buffer_index]; - - if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) { - so_data(vtxbuf, 0); - so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); - continue; - } - - 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) | - (nv40_vbo_ncomp(ve->src_format) << - NV40TCL_VTXFMT_SIZE_SHIFT) | - nv40_vbo_type(ve->src_format))); - } - - if (ib) { - so_method(vtxbuf, nv40->hw->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_emit(nv40->nvws, vtxfmt); - so_emit(nv40->nvws, vtxbuf); - so_ref (vtxbuf, &nv40->so_vtxbuf); - so_ref (NULL, &vtxfmt); -} - -static boolean -nv40_vbo_validate_state(struct nv40_context *nv40, - struct pipe_buffer *ib, unsigned ib_format) -{ - unsigned vdn = nv40->dirty & NV40_NEW_ARRAYS; - - nv40_emit_hw_state(nv40); - if (vdn || ib) { - nv40_vbo_arrays_update(nv40, ib, ib_format); - nv40->dirty &= ~NV40_NEW_ARRAYS; - } - - so_emit_reloc_markers(nv40->nvws, nv40->so_vtxbuf); - - BEGIN_RING(curie, 0x1710, 1); - OUT_RING (0); /* vtx cache flush */ - - return TRUE; -} - boolean nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { struct nv40_context *nv40 = nv40_context(pipe); unsigned nr; - boolean ret; - ret = nv40_vbo_validate_state(nv40, NULL, 0); - if (!ret) { - NOUVEAU_ERR("state validate failed\n"); - return FALSE; - } + nv40_vbo_set_idxbuf(nv40, NULL, 0); + nv40_emit_hw_state(nv40); BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (nvgl_primitive(mode)); @@ -305,14 +253,9 @@ nv40_draw_elements_inline(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); struct pipe_winsys *ws = pipe->winsys; - boolean ret; void *map; - ret = nv40_vbo_validate_state(nv40, NULL, 0); - if (!ret) { - NOUVEAU_ERR("state validate failed\n"); - return FALSE; - } + nv40_emit_hw_state(nv40); map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { @@ -348,30 +291,12 @@ nv40_draw_elements_inline(struct pipe_context *pipe, static boolean nv40_draw_elements_vbo(struct pipe_context *pipe, - struct pipe_buffer *ib, unsigned ib_size, unsigned mode, unsigned start, unsigned count) { struct nv40_context *nv40 = nv40_context(pipe); - unsigned nr, type; - boolean ret; - - switch (ib_size) { - case 2: - type = NV40TCL_IDXBUF_FORMAT_TYPE_U16; - break; - case 4: - type = NV40TCL_IDXBUF_FORMAT_TYPE_U32; - break; - default: - NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); - return FALSE; - } + unsigned nr; - ret = nv40_vbo_validate_state(nv40, ib, type); - if (!ret) { - NOUVEAU_ERR("failed state validation\n"); - return FALSE; - } + nv40_emit_hw_state(nv40); BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (nvgl_primitive(mode)); @@ -409,19 +334,92 @@ nv40_draw_elements(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - /* 0x4497 doesn't support real index buffers, and there doesn't appear - * to be support on any chipset for 8-bit indices. - */ - if (nv40->hw->curie->grclass == NV44TCL || indexSize == 1) { + if (nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize)) { + nv40_draw_elements_vbo(pipe, mode, start, count); + } else { nv40_draw_elements_inline(pipe, indexBuffer, indexSize, mode, start, count); - } else { - nv40_draw_elements_vbo(pipe, indexBuffer, indexSize, - mode, start, count); } pipe->flush(pipe, 0); return TRUE; } +static boolean +nv40_vbo_validate(struct nv40_context *nv40) +{ + struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct nouveau_stateobj *vtxbuf, *vtxfmt; + struct pipe_buffer *ib = nv40->pipe_state.idxbuf; + unsigned ib_format = nv40->pipe_state.idxbuf_format; + unsigned inputs, hw, num_hw; + unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + + inputs = vp->ir; + for (hw = 0; hw < 16 && inputs; hw++) { + if (inputs & (1 << hw)) { + num_hw = hw; + inputs &= ~(1 << hw); + } + } + num_hw++; + + vtxbuf = so_new(20, 18); + so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + vtxfmt = so_new(17, 0); + so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), 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))) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); + continue; + } + + ve = &nv40->vtxelt[hw]; + vb = &nv40->vtxbuf[ve->vertex_buffer_index]; + + if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); + continue; + } + + 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) | + (nv40_vbo_ncomp(ve->src_format) << + NV40TCL_VTXFMT_SIZE_SHIFT) | + nv40_vbo_type(ve->src_format))); + } + + if (ib) { + so_method(vtxbuf, nv40->hw->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, nv40->hw->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); + return FALSE; +} + +struct nv40_state_entry nv40_state_vbo = { + .validate = nv40_vbo_validate, + .dirty = { + .pipe = NV40_NEW_ARRAYS, + .hw = 0, + } +}; -- cgit v1.2.3 From 026e2fd3c6eb87a010a9c90341e8a77b09376b5b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Feb 2008 13:33:08 +1100 Subject: nv40: remove pipe_state struct now. --- src/gallium/drivers/nv40/nv40_context.h | 41 +++++++++++------------- src/gallium/drivers/nv40/nv40_fragprog.c | 4 +-- src/gallium/drivers/nv40/nv40_fragtex.c | 2 +- src/gallium/drivers/nv40/nv40_state.c | 26 +++++++-------- src/gallium/drivers/nv40/nv40_state_blend.c | 4 +-- src/gallium/drivers/nv40/nv40_state_clip.c | 2 +- src/gallium/drivers/nv40/nv40_state_fb.c | 2 +- src/gallium/drivers/nv40/nv40_state_rasterizer.c | 2 +- src/gallium/drivers/nv40/nv40_state_scissor.c | 4 +-- src/gallium/drivers/nv40/nv40_state_stipple.c | 4 +-- src/gallium/drivers/nv40/nv40_state_viewport.c | 2 +- src/gallium/drivers/nv40/nv40_state_zsa.c | 2 +- src/gallium/drivers/nv40/nv40_vbo.c | 18 +++++------ src/gallium/drivers/nv40/nv40_vertprog.c | 4 +-- 14 files changed, 57 insertions(+), 60 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 110d9d7ab7..16cc053ad9 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -132,32 +132,29 @@ struct nv40_context { int chipset; - unsigned dirty; + /* HW state derived from pipe states */ + struct nv40_state state; + unsigned fallback; + /* Context state */ + unsigned 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]; + 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 dirty_samplers; - - struct { - 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]; - 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; - } pipe_state; - - struct nv40_state state; - unsigned fallback; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; }; diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index a4a1ea01e0..2a8abb32a3 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -790,9 +790,9 @@ nv40_fragprog_upload(struct nv40_context *nv40, static boolean nv40_fragprog_validate(struct nv40_context *nv40) { - struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct nv40_fragment_program *fp = nv40->fragprog; struct pipe_buffer *constbuf = - nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT]; + nv40->constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_winsys *ws = nv40->pipe.winsys; struct nouveau_stateobj *so; int i; diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index ed47d707b2..6be8378c08 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -126,7 +126,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) static boolean nv40_fragtex_validate(struct nv40_context *nv40) { - struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct nv40_fragment_program *fp = nv40->fragprog; struct nv40_state *state = &nv40->state; struct nouveau_stateobj *so; unsigned samplers, unit; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index e6f2754dc5..24335fbc44 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -57,7 +57,7 @@ nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.blend = hwcso; + nv40->blend = hwcso; nv40->dirty |= NV40_NEW_BLEND; } @@ -399,7 +399,7 @@ nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.rasterizer = hwcso; + nv40->rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; } @@ -470,7 +470,7 @@ nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.zsa = hwcso; + nv40->zsa = hwcso; nv40->dirty |= NV40_NEW_ZSA; } @@ -500,7 +500,7 @@ nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.vertprog = hwcso; + nv40->vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; } @@ -531,7 +531,7 @@ nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.fragprog = hwcso; + nv40->fragprog = hwcso; nv40->dirty |= NV40_NEW_FRAGPROG; } @@ -551,7 +551,7 @@ nv40_set_blend_color(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.blend_colour = *bcol; + nv40->blend_colour = *bcol; nv40->dirty |= NV40_NEW_BCOL; } @@ -561,7 +561,7 @@ nv40_set_clip_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.clip = *clip; + nv40->clip = *clip; nv40->dirty |= NV40_NEW_UCP; } @@ -572,11 +572,11 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct nv40_context *nv40 = nv40_context(pipe); if (shader == PIPE_SHADER_VERTEX) { - nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX] = buf->buffer; + nv40->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; nv40->dirty |= NV40_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { - nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; + nv40->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; nv40->dirty |= NV40_NEW_FRAGPROG; } } @@ -587,7 +587,7 @@ nv40_set_framebuffer_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.framebuffer = *fb; + nv40->framebuffer = *fb; nv40->dirty |= NV40_NEW_FB; } @@ -597,7 +597,7 @@ nv40_set_polygon_stipple(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - memcpy(nv40->pipe_state.stipple, stipple->stipple, 4 * 32); + memcpy(nv40->stipple, stipple->stipple, 4 * 32); nv40->dirty |= NV40_NEW_STIPPLE; } @@ -607,7 +607,7 @@ nv40_set_scissor_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.scissor = *s; + nv40->scissor = *s; nv40->dirty |= NV40_NEW_SCISSOR; } @@ -617,7 +617,7 @@ nv40_set_viewport_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.viewport = *vpt; + nv40->viewport = *vpt; nv40->dirty |= NV40_NEW_VIEWPORT; } diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c index 81b927a67a..dd09830aa3 100644 --- a/src/gallium/drivers/nv40/nv40_state_blend.c +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -3,7 +3,7 @@ static boolean nv40_state_blend_validate(struct nv40_context *nv40) { - so_ref(nv40->pipe_state.blend->so, &nv40->state.hw[NV40_STATE_BLEND]); + so_ref(nv40->blend->so, &nv40->state.hw[NV40_STATE_BLEND]); return TRUE; } @@ -19,7 +19,7 @@ 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->pipe_state.blend_colour; + struct pipe_blend_color *bcol = &nv40->blend_colour; so_method(so, nv40->hw->curie, NV40TCL_BLEND_COLOR, 1); so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) | diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c index 19f1c3b36d..93e690161f 100644 --- a/src/gallium/drivers/nv40/nv40_state_clip.c +++ b/src/gallium/drivers/nv40/nv40_state_clip.c @@ -3,7 +3,7 @@ static boolean nv40_state_clip_validate(struct nv40_context *nv40) { - if (nv40->pipe_state.clip.nr) + if (nv40->clip.nr) nv40->fallback |= NV40_FALLBACK_TNL; return FALSE; diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index c3bf4d43a3..3d0ab92003 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -3,7 +3,7 @@ static boolean nv40_state_framebuffer_validate(struct nv40_context *nv40) { - struct pipe_framebuffer_state *fb = &nv40->pipe_state.framebuffer; + struct pipe_framebuffer_state *fb = &nv40->framebuffer; struct pipe_surface *rt[4], *zeta; uint32_t rt_enable, rt_format, w, h; int i, colour_format = 0, zeta_format = 0; diff --git a/src/gallium/drivers/nv40/nv40_state_rasterizer.c b/src/gallium/drivers/nv40/nv40_state_rasterizer.c index 59b35d1d50..9ecda5990f 100644 --- a/src/gallium/drivers/nv40/nv40_state_rasterizer.c +++ b/src/gallium/drivers/nv40/nv40_state_rasterizer.c @@ -3,7 +3,7 @@ static boolean nv40_state_rasterizer_validate(struct nv40_context *nv40) { - so_ref(nv40->pipe_state.rasterizer->so, + so_ref(nv40->rasterizer->so, &nv40->state.hw[NV40_STATE_RAST]); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index ee797094d3..09ffc49f96 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -3,8 +3,8 @@ static boolean nv40_state_scissor_validate(struct nv40_context *nv40) { - struct pipe_rasterizer_state *rast = &nv40->pipe_state.rasterizer->pipe; - struct pipe_scissor_state *s = &nv40->pipe_state.scissor; + 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] && diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index aad4d179ac..001c396d74 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -3,7 +3,7 @@ static boolean nv40_state_stipple_validate(struct nv40_context *nv40) { - struct pipe_rasterizer_state *rast = &nv40->pipe_state.rasterizer->pipe; + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; struct nouveau_grobj *curie = nv40->hw->curie; struct nouveau_stateobj *so; @@ -19,7 +19,7 @@ nv40_state_stipple_validate(struct nv40_context *nv40) so_data (so, 1); so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); for (i = 0; i < 32; i++) - so_data(so, nv40->pipe_state.stipple[i]); + so_data(so, nv40->stipple[i]); } else { so = so_new(2, 0); so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 68820d3133..9616be5052 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -4,7 +4,7 @@ static boolean nv40_state_viewport_validate(struct nv40_context *nv40) { struct nouveau_stateobj *so = so_new(9, 0); - struct pipe_viewport_state *vpt = &nv40->pipe_state.viewport; + struct pipe_viewport_state *vpt = &nv40->viewport; so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); so_data (so, fui(vpt->translate[0])); diff --git a/src/gallium/drivers/nv40/nv40_state_zsa.c b/src/gallium/drivers/nv40/nv40_state_zsa.c index 061a3555cb..fb760677c8 100644 --- a/src/gallium/drivers/nv40/nv40_state_zsa.c +++ b/src/gallium/drivers/nv40/nv40_state_zsa.c @@ -3,7 +3,7 @@ static boolean nv40_state_zsa_validate(struct nv40_context *nv40) { - so_ref(nv40->pipe_state.zsa->so, + so_ref(nv40->zsa->so, &nv40->state.hw[NV40_STATE_ZSA]); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index b5faf06291..1653ebf2a7 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -46,8 +46,8 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, unsigned type; if (!ib) { - nv40->pipe_state.idxbuf = NULL; - nv40->pipe_state.idxbuf_format = 0xdeadbeef; + nv40->idxbuf = NULL; + nv40->idxbuf_format = 0xdeadbeef; return FALSE; } @@ -66,11 +66,11 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, return FALSE; } - if (ib != nv40->pipe_state.idxbuf || - type != nv40->pipe_state.idxbuf_format) { + if (ib != nv40->idxbuf || + type != nv40->idxbuf_format) { nv40->dirty |= NV40_NEW_ARRAYS; - nv40->pipe_state.idxbuf = ib; - nv40->pipe_state.idxbuf_format = type; + nv40->idxbuf = ib; + nv40->idxbuf_format = type; } return TRUE; @@ -348,10 +348,10 @@ nv40_draw_elements(struct pipe_context *pipe, static boolean nv40_vbo_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct nv40_vertex_program *vp = nv40->vertprog; struct nouveau_stateobj *vtxbuf, *vtxfmt; - struct pipe_buffer *ib = nv40->pipe_state.idxbuf; - unsigned ib_format = nv40->pipe_state.idxbuf_format; + struct pipe_buffer *ib = nv40->idxbuf; + unsigned ib_format = nv40->idxbuf_format; unsigned inputs, hw, num_hw; unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index c482964adc..d3ed57b199 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -634,9 +634,9 @@ out_err: static boolean nv40_vertprog_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct nv40_vertex_program *vp = nv40->vertprog; struct pipe_buffer *constbuf = - nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX]; + nv40->constbuf[PIPE_SHADER_VERTEX]; struct nouveau_winsys *nvws = nv40->nvws; struct pipe_winsys *ws = nv40->pipe.winsys; boolean upload_code = FALSE, upload_data = FALSE; -- cgit v1.2.3 From 84cc07dc89c0ebce4ad55b4b3684d4420a202683 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 15:03:57 +1100 Subject: nouveau: implement pipe_screen Untested on NV3x/NV5x. Quite possibly broken. --- src/gallium/drivers/nouveau/nouveau_winsys.h | 15 +- src/gallium/drivers/nv30/Makefile | 1 + src/gallium/drivers/nv30/nv30_context.c | 86 +----------- src/gallium/drivers/nv30/nv30_context.h | 2 +- src/gallium/drivers/nv30/nv30_miptree.c | 47 ++++++- src/gallium/drivers/nv30/nv30_screen.c | 151 +++++++++++++++++++++ src/gallium/drivers/nv30/nv30_screen.h | 20 +++ src/gallium/drivers/nv30/nv30_surface.c | 72 ---------- src/gallium/drivers/nv40/Makefile | 1 + src/gallium/drivers/nv40/nv40_context.c | 85 +----------- src/gallium/drivers/nv40/nv40_context.h | 2 + src/gallium/drivers/nv40/nv40_miptree.c | 25 ++-- src/gallium/drivers/nv40/nv40_screen.c | 151 +++++++++++++++++++++ src/gallium/drivers/nv40/nv40_screen.h | 20 +++ src/gallium/drivers/nv40/nv40_surface.c | 41 ------ src/gallium/drivers/nv50/Makefile | 1 + src/gallium/drivers/nv50/nv50_context.c | 91 +------------ src/gallium/drivers/nv50/nv50_context.h | 2 + src/gallium/drivers/nv50/nv50_miptree.c | 29 +++- src/gallium/drivers/nv50/nv50_screen.c | 117 ++++++++++++++++ src/gallium/drivers/nv50/nv50_screen.h | 20 +++ src/gallium/drivers/nv50/nv50_surface.c | 10 -- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 16 ++- .../winsys/dri/nouveau/nouveau_winsys_softpipe.c | 30 ++-- 24 files changed, 623 insertions(+), 412 deletions(-) create mode 100644 src/gallium/drivers/nv30/nv30_screen.c create mode 100644 src/gallium/drivers/nv30/nv30_screen.h create mode 100644 src/gallium/drivers/nv40/nv40_screen.c create mode 100644 src/gallium/drivers/nv40/nv40_screen.h create mode 100644 src/gallium/drivers/nv50/nv50_screen.c create mode 100644 src/gallium/drivers/nv50/nv50_screen.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index b5e470cfaa..98d95e94a5 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -49,13 +49,22 @@ struct nouveau_winsys { unsigned, unsigned, unsigned, unsigned, unsigned); }; +extern struct pipe_screen * +nv30_screen_create(struct pipe_winsys *ws, unsigned chipset); + extern struct pipe_context * -nv30_create(struct pipe_winsys *, struct nouveau_winsys *, unsigned chipset); +nv30_create(struct pipe_screen *, struct nouveau_winsys *); + +extern struct pipe_screen * +nv40_screen_create(struct pipe_winsys *ws, unsigned chipset); extern struct pipe_context * -nv40_create(struct pipe_winsys *, struct nouveau_winsys *, unsigned chipset); +nv40_create(struct pipe_screen *, struct nouveau_winsys *); + +extern struct pipe_screen * +nv50_screen_create(struct pipe_winsys *ws, unsigned chipset); extern struct pipe_context * -nv50_create(struct pipe_winsys *, struct nouveau_winsys *, unsigned chipset); +nv50_create(struct pipe_screen *, struct nouveau_winsys *); #endif diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile index b7c252fc98..3f80fb87c9 100644 --- a/src/gallium/drivers/nv30/Makefile +++ b/src/gallium/drivers/nv30/Makefile @@ -11,6 +11,7 @@ DRIVER_SOURCES = \ nv30_fragtex.c \ nv30_miptree.c \ nv30_query.c \ + nv30_screen.c \ nv30_state.c \ nv30_state_emit.c \ nv30_surface.c \ diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index e9afeb8017..b8452e23b1 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -4,80 +4,7 @@ #include "pipe/p_util.h" #include "nv30_context.h" - -static const char * -nv30_get_name(struct pipe_context *pipe) -{ - struct nv30_context *nv30 = nv30_context(pipe); - static char buffer[128]; - - snprintf(buffer, sizeof(buffer), "NV%02X", nv30->chipset); - return buffer; -} - -static const char * -nv30_get_vendor(struct pipe_context *pipe) -{ - return "nouveau"; -} - -static int -nv30_get_param(struct pipe_context *pipe, 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; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0; - } -} - -static float -nv30_get_paramf(struct pipe_context *pipe, 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; - case PIPE_CAP_BITMAP_TEXCOORD_BIAS: - return 0.0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0.0; - } -} +#include "nv30_screen.h" static void nv30_flush(struct pipe_context *pipe, unsigned flags) @@ -338,9 +265,10 @@ nv30_init_hwctx(struct nv30_context *nv30, int rankine_class) #define NV35TCL_CHIPSET_3X_MASK 0x000001e0 struct pipe_context * -nv30_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws, - unsigned chipset) +nv30_create(struct pipe_screen *screen, struct nouveau_winsys *nvws) { + struct pipe_winsys *pipe_winsys = screen->winsys; + unsigned chipset = nv30_screen(screen)->chipset; struct nv30_context *nv30; int rankine_class = 0, ret; @@ -404,12 +332,9 @@ nv30_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws, /* Pipe context setup */ nv30->pipe.winsys = pipe_winsys; + nv30->pipe.screen = screen; nv30->pipe.destroy = nv30_destroy; - nv30->pipe.get_name = nv30_get_name; - nv30->pipe.get_vendor = nv30_get_vendor; - nv30->pipe.get_param = nv30_get_param; - nv30->pipe.get_paramf = nv30_get_paramf; nv30->pipe.draw_arrays = nv30_draw_arrays; nv30->pipe.draw_elements = nv30_draw_elements; @@ -420,7 +345,6 @@ nv30_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws, nv30_init_query_functions(nv30); nv30_init_surface_functions(nv30); nv30_init_state_functions(nv30); - nv30_init_miptree_functions(nv30); nv30->draw = draw_create(); assert(nv30->draw); diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index d6d16ee868..c63847a087 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -91,7 +91,7 @@ nv30_context(struct pipe_context *pipe) extern void nv30_init_state_functions(struct nv30_context *nv30); extern void nv30_init_surface_functions(struct nv30_context *nv30); -extern void nv30_init_miptree_functions(struct nv30_context *nv30); +extern void nv30_init_miptree_functions(struct pipe_screen *screen); extern void nv30_init_query_functions(struct nv30_context *nv30); /* nv30_draw.c */ diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index 5fb89f4cfd..23bcef08eb 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -4,6 +4,7 @@ #include "pipe/p_inlines.h" #include "nv30_context.h" +#include "nv30_screen.h" static void nv30_miptree_layout(struct nv30_miptree *nv30mt) @@ -54,9 +55,9 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) } static void -nv30_miptree_create(struct pipe_context *pipe, struct pipe_texture **pt) +nv30_miptree_create(struct pipe_screen *screen, struct pipe_texture **pt) { - struct pipe_winsys *ws = pipe->winsys; + struct pipe_winsys *ws = screen->winsys; struct nv30_miptree *nv30mt; nv30mt = realloc(*pt, sizeof(struct nv30_miptree)); @@ -77,9 +78,9 @@ nv30_miptree_create(struct pipe_context *pipe, struct pipe_texture **pt) } static void -nv30_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) +nv30_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) { - struct pipe_winsys *ws = pipe->winsys; + struct pipe_winsys *ws = screen->winsys; struct pipe_texture *mt = *pt; *pt = NULL; @@ -96,10 +97,42 @@ nv30_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) } } +static struct pipe_surface * +nv30_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = screen->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; +} void -nv30_init_miptree_functions(struct nv30_context *nv30) +nv30_init_miptree_functions(struct pipe_screen *screen) { - nv30->pipe.texture_create = nv30_miptree_create; - nv30->pipe.texture_release = nv30_miptree_release; + struct nv30_screen *nv30screen = nv30_screen(screen); + + nv30screen->screen.texture_create = nv30_miptree_create; + nv30screen->screen.texture_release = nv30_miptree_release; + nv30screen->screen.get_tex_surface = nv30_miptree_surface_get; } diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c new file mode 100644 index 0000000000..6d64025528 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -0,0 +1,151 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv30_context.h" +#include "nv30_screen.h" + +static const char * +nv30_screen_get_name(struct pipe_screen *screen) +{ + struct nv30_screen *nv30screen = nv30_screen(screen); + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", nv30screen->chipset); + return buffer; +} + +static const char * +nv30_screen_get_vendor(struct pipe_screen *screen) +{ + return "nouveau"; +} + +static int +nv30_screen_get_param(struct pipe_screen *screen, 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; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv30_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 16.0; + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 4.0; + case PIPE_CAP_BITMAP_TEXCOORD_BIAS: + return 0.0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0.0; + } +} + +static boolean +nv30_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_U_L8: + case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static void +nv30_screen_destroy(struct pipe_screen *screen) +{ + FREE(screen); +} + +struct pipe_screen * +nv30_screen_create(struct pipe_winsys *winsys, unsigned chipset) +{ + struct nv30_screen *nv30screen = CALLOC_STRUCT(nv30_screen); + + if (!nv30screen) + return NULL; + + nv30screen->chipset = chipset; + + nv30screen->screen.winsys = winsys; + + nv30screen->screen.destroy = nv30_screen_destroy; + + nv30screen->screen.get_name = nv30_screen_get_name; + nv30screen->screen.get_vendor = nv30_screen_get_vendor; + nv30screen->screen.get_param = nv30_screen_get_param; + nv30screen->screen.get_paramf = nv30_screen_get_paramf; + nv30screen->screen.is_format_supported = + nv30_screen_is_format_supported; + + nv30_init_miptree_functions(&nv30screen->screen); + return &nv30screen->screen; +} + diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h new file mode 100644 index 0000000000..e55242fbf7 --- /dev/null +++ b/src/gallium/drivers/nv30/nv30_screen.h @@ -0,0 +1,20 @@ +#ifndef __NV30_SCREEN_H__ +#define __NV30_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv30_screen { + struct pipe_screen screen; + unsigned chipset; +}; + +static INLINE struct nv30_screen * +nv30_screen(struct pipe_screen *screen) +{ + return (struct nv30_screen *)screen; +} + +extern struct pipe_screen * +nv30_screen_create(struct pipe_winsys *winsys, unsigned chipset); + +#endif diff --git a/src/gallium/drivers/nv30/nv30_surface.c b/src/gallium/drivers/nv30/nv30_surface.c index 974965679f..b20a3dd4c1 100644 --- a/src/gallium/drivers/nv30/nv30_surface.c +++ b/src/gallium/drivers/nv30/nv30_surface.c @@ -33,76 +33,6 @@ #include "pipe/p_inlines.h" #include "util/p_tile.h" -static boolean -nv30_surface_format_supported(struct pipe_context *pipe, - 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_U_L8: - case PIPE_FORMAT_U_A8: - case PIPE_FORMAT_U_I8: - case PIPE_FORMAT_U_A8_L8: - case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return TRUE; - default: - break; - } - break; - default: - assert(0); - }; - - return FALSE; -} - -static struct pipe_surface * -nv30_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct pipe_winsys *ws = pipe->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_surface_copy(struct pipe_context *pipe, unsigned do_flip, struct pipe_surface *dest, unsigned destx, unsigned desty, @@ -130,8 +60,6 @@ nv30_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, void nv30_init_surface_functions(struct nv30_context *nv30) { - nv30->pipe.is_format_supported = nv30_surface_format_supported; - nv30->pipe.get_tex_surface = nv30_get_tex_surface; nv30->pipe.surface_copy = nv30_surface_copy; nv30->pipe.surface_fill = nv30_surface_fill; } diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index fd002b54e7..3369a21574 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -11,6 +11,7 @@ DRIVER_SOURCES = \ nv40_fragtex.c \ nv40_miptree.c \ nv40_query.c \ + nv40_screen.c \ nv40_state.c \ nv40_state_blend.c \ nv40_state_clip.c \ diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 8b5cc693de..a7f64c6e9e 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -4,85 +4,12 @@ #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_get_name(struct pipe_context *pipe) -{ - struct nv40_context *nv40 = nv40_context(pipe); - static char buffer[128]; - - snprintf(buffer, sizeof(buffer), "NV%02X", nv40->chipset); - return buffer; -} - -static const char * -nv40_get_vendor(struct pipe_context *pipe) -{ - return "nouveau"; -} - -static int -nv40_get_param(struct pipe_context *pipe, int param) -{ - 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 0; - 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; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0; - } -} - -static float -nv40_get_paramf(struct pipe_context *pipe, 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; - case PIPE_CAP_BITMAP_TEXCOORD_BIAS: - return 0.0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0.0; - } -} - static void nv40_flush(struct pipe_context *pipe, unsigned flags) { @@ -269,10 +196,11 @@ nv40_destroy(struct pipe_context *pipe) } struct pipe_context * -nv40_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +nv40_create(struct pipe_screen *pscreen, struct nouveau_winsys *nvws) { + struct pipe_winsys *ws = pscreen->winsys; struct nv40_context *nv40; + unsigned chipset = nv40_screen(pscreen)->chipset; nv40 = CALLOC(1, sizeof(struct nv40_context)); if (!nv40) @@ -288,11 +216,8 @@ nv40_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, nv40->nvws = nvws; nv40->pipe.winsys = ws; + nv40->pipe.screen = pscreen; nv40->pipe.destroy = nv40_destroy; - nv40->pipe.get_name = nv40_get_name; - nv40->pipe.get_vendor = nv40_get_vendor; - nv40->pipe.get_param = nv40_get_param; - nv40->pipe.get_paramf = nv40_get_paramf; nv40->pipe.draw_arrays = nv40_draw_arrays; nv40->pipe.draw_elements = nv40_draw_elements; nv40->pipe.clear = nv40_clear; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 16cc053ad9..3ddfbd43f6 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -178,6 +178,8 @@ extern void nv40_init_surface_functions(struct nv40_context *nv40); extern void nv40_init_miptree_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); diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 5e1c7ade31..94ba05b710 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -54,9 +54,9 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) } static struct pipe_texture * -nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) +nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) { - struct pipe_winsys *ws = pipe->winsys; + struct pipe_winsys *ws = pscreen->winsys; struct nv40_miptree *mt; mt = MALLOC(sizeof(struct nv40_miptree)); @@ -64,6 +64,8 @@ nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) 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, @@ -77,9 +79,9 @@ nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) } static void -nv40_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) +nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) { - struct pipe_winsys *ws = pipe->winsys; + struct pipe_winsys *ws = pscreen->winsys; struct pipe_texture *mt = *pt; *pt = NULL; @@ -102,10 +104,10 @@ nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) } static struct pipe_surface * -nv40_miptree_surface(struct pipe_context *pipe, struct pipe_texture *pt, +nv40_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) { - struct pipe_winsys *ws = pipe->winsys; + struct pipe_winsys *ws = pscreen->winsys; struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; struct pipe_surface *ps; @@ -134,9 +136,14 @@ nv40_miptree_surface(struct pipe_context *pipe, struct pipe_texture *pt, void nv40_init_miptree_functions(struct nv40_context *nv40) { - nv40->pipe.texture_create = nv40_miptree_create; - nv40->pipe.texture_release = nv40_miptree_release; nv40->pipe.texture_update = nv40_miptree_update; - nv40->pipe.get_tex_surface = nv40_miptree_surface; +} + +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; } diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c new file mode 100644 index 0000000000..1941598c64 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -0,0 +1,151 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv40_context.h" +#include "nv40_screen.h" + +static const char * +nv40_screen_get_name(struct pipe_screen *pscreen) +{ + struct nv40_screen *screen = nv40_screen(pscreen); + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", screen->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) +{ + 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 0; + 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; + 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; + case PIPE_CAP_BITMAP_TEXCOORD_BIAS: + return 0.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_U_L8: + case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static void +nv40_screen_destroy(struct pipe_screen *pscreen) +{ + FREE(pscreen); +} + +struct pipe_screen * +nv40_screen_create(struct pipe_winsys *ws, unsigned chipset) +{ + struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); + + if (!screen) + return NULL; + + screen->chipset = chipset; + + 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; + + 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 0000000000..b30a6c5ad5 --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -0,0 +1,20 @@ +#ifndef __NV40_SCREEN_H__ +#define __NV40_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv40_screen { + struct pipe_screen pipe; + unsigned chipset; +}; + +static INLINE struct nv40_screen * +nv40_screen(struct pipe_screen *screen) +{ + return (struct nv40_screen *)screen; +} + +extern struct pipe_screen * +nv40_screen_create(struct pipe_winsys *winsys, unsigned chipset); + +#endif diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index df5d7abdbf..e8a6011696 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -33,46 +33,6 @@ #include "pipe/p_inlines.h" #include "util/p_tile.h" -static boolean -nv40_surface_format_supported(struct pipe_context *pipe, - 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_U_L8: - case PIPE_FORMAT_U_A8: - case PIPE_FORMAT_U_I8: - case PIPE_FORMAT_U_A8_L8: - case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return TRUE; - default: - break; - } - break; - default: - assert(0); - }; - - return FALSE; -} - static void nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip, struct pipe_surface *dest, unsigned destx, unsigned desty, @@ -100,7 +60,6 @@ nv40_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, void nv40_init_surface_functions(struct nv40_context *nv40) { - nv40->pipe.is_format_supported = nv40_surface_format_supported; nv40->pipe.surface_copy = nv40_surface_copy; nv40->pipe.surface_fill = nv40_surface_fill; } diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index 68eb49ff2a..1c0b82887a 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -9,6 +9,7 @@ DRIVER_SOURCES = \ nv50_draw.c \ nv50_miptree.c \ nv50_query.c \ + nv50_screen.c \ nv50_state.c \ nv50_surface.c \ nv50_vbo.c diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 3c5a54bfd3..98022809a6 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -4,85 +4,7 @@ #include "pipe/p_util.h" #include "nv50_context.h" - -static boolean -nv50_is_format_supported(struct pipe_context *pipe, enum pipe_format format, - uint type) -{ - return FALSE; -} - -static const char * -nv50_get_name(struct pipe_context *pipe) -{ - struct nv50_context *nv50 = (struct nv50_context *)pipe; - static char buffer[128]; - - snprintf(buffer, sizeof(buffer), "NV%02X", nv50->chipset); - return buffer; -} - -static const char * -nv50_get_vendor(struct pipe_context *pipe) -{ - return "nouveau"; -} - -static int -nv50_get_param(struct pipe_context *pipe, 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; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0; - } -} - -static float -nv50_get_paramf(struct pipe_context *pipe, 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; - } -} +#include "nv50_screen.h" static void nv50_flush(struct pipe_context *pipe, unsigned flags) @@ -134,9 +56,10 @@ nv50_init_hwctx(struct nv50_context *nv50, int tesla_class) #define GRCLASS5097_CHIPSETS 0x00000000 #define GRCLASS8297_CHIPSETS 0x00000010 struct pipe_context * -nv50_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws, - unsigned chipset) +nv50_create(struct pipe_screen *pscreen, struct nouveau_winsys *nvws) { + struct pipe_winsys *pipe_winsys = pscreen->winsys; + unsigned chipset = nv50_screen(pscreen)->chipset; struct nv50_context *nv50; int tesla_class, ret; @@ -173,13 +96,9 @@ nv50_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws, } nv50->pipe.winsys = pipe_winsys; + nv50->pipe.screen = pscreen; nv50->pipe.destroy = nv50_destroy; - nv50->pipe.is_format_supported = nv50_is_format_supported; - nv50->pipe.get_name = nv50_get_name; - nv50->pipe.get_vendor = nv50_get_vendor; - nv50->pipe.get_param = nv50_get_param; - nv50->pipe.get_paramf = nv50_get_paramf; nv50->pipe.draw_arrays = nv50_draw_arrays; nv50->pipe.draw_elements = nv50_draw_elements; diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index b99254f619..a529bf3c3e 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -38,6 +38,8 @@ 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); diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 0c034ed438..720d33fda9 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -1,25 +1,46 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "pipe/p_screen.h" #include "nv50_context.h" static struct pipe_texture * -nv50_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) +nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) { NOUVEAU_ERR("unimplemented\n"); return NULL; } static void -nv50_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) +nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) { NOUVEAU_ERR("unimplemented\n"); } +static struct pipe_surface * +nv50_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + NOUVEAU_ERR("unimplemented\n"); + return NULL; +} + +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; +} + +static void +nv50_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) +{ +} + void nv50_init_miptree_functions(struct nv50_context *nv50) { - nv50->pipe.texture_create = nv50_miptree_create; - nv50->pipe.texture_release = nv50_miptree_release; + nv50->pipe.texture_update = nv50_miptree_update; } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c new file mode 100644 index 0000000000..8bf82eb0bc --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -0,0 +1,117 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv50_context.h" +#include "nv50_screen.h" + +static boolean +nv50_screen_is_format_supported(struct pipe_screen *pscreen, + enum pipe_format format, uint type) +{ + return FALSE; +} + +static const char * +nv50_screen_get_name(struct pipe_screen *pscreen) +{ + struct nv50_screen *screen = nv50_screen(pscreen); + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", screen->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; + 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_screen_destroy(struct pipe_screen *pscreen) +{ + FREE(pscreen); +} + +struct pipe_screen * +nv50_screen_create(struct pipe_winsys *ws, unsigned chipset) +{ + struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); + + if (!screen) + return NULL; + + screen->chipset = chipset; + + 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; + + 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 0000000000..45ebbb8051 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -0,0 +1,20 @@ +#ifndef __NV50_SCREEN_H__ +#define __NV50_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv50_screen { + struct pipe_screen pipe; + unsigned chipset; +}; + +static INLINE struct nv50_screen * +nv50_screen(struct pipe_screen *screen) +{ + return (struct nv50_screen *)screen; +} + +extern struct pipe_screen * +nv50_screen_create(struct pipe_winsys *winsys, unsigned chipset); + +#endif diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index ca92ff02b8..39cf675a57 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -33,15 +33,6 @@ #include "pipe/p_inlines.h" #include "util/p_tile.h" -static struct pipe_surface * -nv50_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - NOUVEAU_ERR("unimplemented\n"); - return NULL; -} - static void nv50_surface_copy(struct pipe_context *pipe, unsigned flip, struct pipe_surface *dest, unsigned destx, unsigned desty, @@ -69,7 +60,6 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, void nv50_init_surface_functions(struct nv50_context *nv50) { - nv50->pipe.get_tex_surface = nv50_get_tex_surface; nv50->pipe.surface_copy = nv50_surface_copy; nv50->pipe.surface_fill = nv50_surface_fill; } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 2ca05d84c6..1d758e29e7 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -72,23 +72,29 @@ struct pipe_context * nouveau_pipe_create(struct nouveau_context *nv) { struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); - struct pipe_context *(*hw_create)(struct pipe_winsys *, - struct nouveau_winsys *, - unsigned); + struct pipe_screen *(*hws_create)(struct pipe_winsys *, + unsigned chipset); + struct pipe_context *(*hw_create)(struct pipe_screen *, + struct nouveau_winsys *); + struct pipe_winsys *ws; + struct pipe_screen *pscreen; if (!nvws) return NULL; switch (nv->chipset & 0xf0) { 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: + hws_create = nv50_screen_create; hw_create = nv50_create; break; default: @@ -119,6 +125,8 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->surface_copy = nouveau_pipe_surface_copy; nvws->surface_fill = nouveau_pipe_surface_fill; - return hw_create(nouveau_create_pipe_winsys(nv), nvws, nv->chipset); + ws = nouveau_create_pipe_winsys(nv); + pscreen = hws_create(ws, nv->chipset); + return hw_create(pscreen, nvws); } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c index 0e1b4273d1..704f6c7750 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c @@ -61,23 +61,25 @@ nouveau_is_format_supported(struct softpipe_winsys *sws, uint format) return FALSE; } - - struct pipe_context * nouveau_create_softpipe(struct nouveau_context *nv) { - struct nouveau_softpipe_winsys *nvsws; - - nvsws = CALLOC_STRUCT(nouveau_softpipe_winsys); - - /* Fill in this struct with callbacks that softpipe will need to - * communicate with the window system, buffer manager, etc. - */ - nvsws->sws.is_format_supported = nouveau_is_format_supported; - nvsws->nv = 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; - /* Create the softpipe context: - */ - return softpipe_create(nouveau_create_pipe_winsys(nv), &nvsws->sws); + return softpipe_create(pscreen, ws, &nvsws->sws); } -- cgit v1.2.3 From baaae562f02563c5966b857c61b3eae7341950e3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 22:54:40 +1100 Subject: nouveau: hand nouveau_winsys in with pipe_screen init --- src/gallium/drivers/nouveau/nouveau_winsys.h | 15 +++++++++------ src/gallium/drivers/nv30/nv30_context.c | 3 ++- src/gallium/drivers/nv30/nv30_screen.c | 4 +++- src/gallium/drivers/nv30/nv30_screen.h | 5 ++--- src/gallium/drivers/nv40/nv40_context.c | 3 ++- src/gallium/drivers/nv40/nv40_screen.c | 4 +++- src/gallium/drivers/nv40/nv40_screen.h | 5 ++--- src/gallium/drivers/nv50/nv50_context.c | 3 ++- src/gallium/drivers/nv50/nv50_screen.c | 4 +++- src/gallium/drivers/nv50/nv50_screen.h | 5 ++--- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 8 ++++---- 11 files changed, 34 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 98d95e94a5..11ca7e80dd 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -50,21 +50,24 @@ struct nouveau_winsys { }; extern struct pipe_screen * -nv30_screen_create(struct pipe_winsys *ws, unsigned chipset); +nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, + unsigned chipset); extern struct pipe_context * -nv30_create(struct pipe_screen *, struct nouveau_winsys *); +nv30_create(struct pipe_screen *); extern struct pipe_screen * -nv40_screen_create(struct pipe_winsys *ws, unsigned chipset); +nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, + unsigned chipset); extern struct pipe_context * -nv40_create(struct pipe_screen *, struct nouveau_winsys *); +nv40_create(struct pipe_screen *); extern struct pipe_screen * -nv50_screen_create(struct pipe_winsys *ws, unsigned chipset); +nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, + unsigned chipset); extern struct pipe_context * -nv50_create(struct pipe_screen *, struct nouveau_winsys *); +nv50_create(struct pipe_screen *); #endif diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index b8452e23b1..522fb13226 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -265,9 +265,10 @@ nv30_init_hwctx(struct nv30_context *nv30, int rankine_class) #define NV35TCL_CHIPSET_3X_MASK 0x000001e0 struct pipe_context * -nv30_create(struct pipe_screen *screen, struct nouveau_winsys *nvws) +nv30_create(struct pipe_screen *screen) { struct pipe_winsys *pipe_winsys = screen->winsys; + struct nouveau_winsys *nvws = nv30_screen(screen)->nvws; unsigned chipset = nv30_screen(screen)->chipset; struct nv30_context *nv30; int rankine_class = 0, ret; diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 6d64025528..39f2ac1af5 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -125,7 +125,8 @@ nv30_screen_destroy(struct pipe_screen *screen) } struct pipe_screen * -nv30_screen_create(struct pipe_winsys *winsys, unsigned chipset) +nv30_screen_create(struct pipe_winsys *winsys, struct nouveau_winsys *nvws, + unsigned chipset) { struct nv30_screen *nv30screen = CALLOC_STRUCT(nv30_screen); @@ -133,6 +134,7 @@ nv30_screen_create(struct pipe_winsys *winsys, unsigned chipset) return NULL; nv30screen->chipset = chipset; + nv30screen->nvws = nvws; nv30screen->screen.winsys = winsys; diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h index e55242fbf7..f878f81e11 100644 --- a/src/gallium/drivers/nv30/nv30_screen.h +++ b/src/gallium/drivers/nv30/nv30_screen.h @@ -5,6 +5,8 @@ struct nv30_screen { struct pipe_screen screen; + + struct nouveau_winsys *nvws; unsigned chipset; }; @@ -14,7 +16,4 @@ nv30_screen(struct pipe_screen *screen) return (struct nv30_screen *)screen; } -extern struct pipe_screen * -nv30_screen_create(struct pipe_winsys *winsys, unsigned chipset); - #endif diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index a7f64c6e9e..679c2ddc6b 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -196,11 +196,12 @@ nv40_destroy(struct pipe_context *pipe) } struct pipe_context * -nv40_create(struct pipe_screen *pscreen, struct nouveau_winsys *nvws) +nv40_create(struct pipe_screen *pscreen) { struct pipe_winsys *ws = pscreen->winsys; struct nv40_context *nv40; unsigned chipset = nv40_screen(pscreen)->chipset; + struct nouveau_winsys *nvws = nv40_screen(pscreen)->nvws; nv40 = CALLOC(1, sizeof(struct nv40_context)); if (!nv40) diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 1941598c64..66e84b6890 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -125,7 +125,8 @@ nv40_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv40_screen_create(struct pipe_winsys *ws, unsigned chipset) +nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, + unsigned chipset) { struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); @@ -133,6 +134,7 @@ nv40_screen_create(struct pipe_winsys *ws, unsigned chipset) return NULL; screen->chipset = chipset; + screen->nvws = nvws; screen->pipe.winsys = ws; screen->pipe.destroy = nv40_screen_destroy; diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index b30a6c5ad5..88b8fed26c 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -5,6 +5,8 @@ struct nv40_screen { struct pipe_screen pipe; + + struct nouveau_winsys *nvws; unsigned chipset; }; @@ -14,7 +16,4 @@ nv40_screen(struct pipe_screen *screen) return (struct nv40_screen *)screen; } -extern struct pipe_screen * -nv40_screen_create(struct pipe_winsys *winsys, unsigned chipset); - #endif diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 98022809a6..e5054e34f6 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -56,9 +56,10 @@ nv50_init_hwctx(struct nv50_context *nv50, int tesla_class) #define GRCLASS5097_CHIPSETS 0x00000000 #define GRCLASS8297_CHIPSETS 0x00000010 struct pipe_context * -nv50_create(struct pipe_screen *pscreen, struct nouveau_winsys *nvws) +nv50_create(struct pipe_screen *pscreen) { struct pipe_winsys *pipe_winsys = pscreen->winsys; + struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; unsigned chipset = nv50_screen(pscreen)->chipset; struct nv50_context *nv50; int tesla_class, ret; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 8bf82eb0bc..f091779e3b 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -90,7 +90,8 @@ nv50_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv50_screen_create(struct pipe_winsys *ws, unsigned chipset) +nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, + unsigned chipset) { struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); @@ -98,6 +99,7 @@ nv50_screen_create(struct pipe_winsys *ws, unsigned chipset) return NULL; screen->chipset = chipset; + screen->nvws = nvws; screen->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 45ebbb8051..d664816a03 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -5,6 +5,8 @@ struct nv50_screen { struct pipe_screen pipe; + + struct nouveau_winsys *nvws; unsigned chipset; }; @@ -14,7 +16,4 @@ nv50_screen(struct pipe_screen *screen) return (struct nv50_screen *)screen; } -extern struct pipe_screen * -nv50_screen_create(struct pipe_winsys *winsys, unsigned chipset); - #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 1d758e29e7..529f577181 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -73,9 +73,9 @@ nouveau_pipe_create(struct nouveau_context *nv) { struct nouveau_winsys *nvws = CALLOC_STRUCT(nouveau_winsys); struct pipe_screen *(*hws_create)(struct pipe_winsys *, + struct nouveau_winsys *, unsigned chipset); - struct pipe_context *(*hw_create)(struct pipe_screen *, - struct nouveau_winsys *); + struct pipe_context *(*hw_create)(struct pipe_screen *); struct pipe_winsys *ws; struct pipe_screen *pscreen; @@ -126,7 +126,7 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->surface_fill = nouveau_pipe_surface_fill; ws = nouveau_create_pipe_winsys(nv); - pscreen = hws_create(ws, nv->chipset); - return hw_create(pscreen, nvws); + pscreen = hws_create(ws, nvws, nv->chipset); + return hw_create(pscreen); } -- cgit v1.2.3 From 17f6db9d0197657cd753249ef60355c6fd983032 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 23:08:01 +1100 Subject: nv40: move "channel context" stuff into nv40_screen --- src/gallium/drivers/nv40/nv40_context.c | 168 +------------------------ src/gallium/drivers/nv40/nv40_context.h | 29 +---- src/gallium/drivers/nv40/nv40_fragprog.c | 4 +- src/gallium/drivers/nv40/nv40_fragtex.c | 6 +- src/gallium/drivers/nv40/nv40_query.c | 10 +- src/gallium/drivers/nv40/nv40_screen.c | 128 ++++++++++++++++++- src/gallium/drivers/nv40/nv40_screen.h | 15 +++ src/gallium/drivers/nv40/nv40_state.c | 16 +-- src/gallium/drivers/nv40/nv40_state_blend.c | 2 +- src/gallium/drivers/nv40/nv40_state_emit.c | 4 +- src/gallium/drivers/nv40/nv40_state_fb.c | 34 ++--- src/gallium/drivers/nv40/nv40_state_scissor.c | 2 +- src/gallium/drivers/nv40/nv40_state_stipple.c | 2 +- src/gallium/drivers/nv40/nv40_state_viewport.c | 2 +- src/gallium/drivers/nv40/nv40_vbo.c | 10 +- src/gallium/drivers/nv40/nv40_vertprog.c | 8 +- 16 files changed, 203 insertions(+), 237 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 679c2ddc6b..084829ce28 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -6,10 +6,6 @@ #include "nv40_context.h" #include "nv40_screen.h" -#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf -#define NV4X_GRCLASS4497_CHIPSETS 0x00005450 -#define NV6X_GRCLASS4497_CHIPSETS 0x00000088 - static void nv40_flush(struct pipe_context *pipe, unsigned flags) { @@ -24,7 +20,7 @@ nv40_flush(struct pipe_context *pipe, unsigned flags) } if (flags & PIPE_FLUSH_WAIT) { - nvws->notifier_reset(nv40->hw->sync, 0); + nvws->notifier_reset(nv40->screen->sync, 0); BEGIN_RING(curie, 0x104, 1); OUT_RING (0); BEGIN_RING(curie, 0x100, 1); @@ -34,149 +30,7 @@ nv40_flush(struct pipe_context *pipe, unsigned flags) FIRE_RING(); if (flags & PIPE_FLUSH_WAIT) - nvws->notifier_wait(nv40->hw->sync, 0, 0, 2000); -} - -static void -nv40_channel_takedown(struct nv40_channel_context *cnv40) -{ - struct nouveau_winsys *nvws = cnv40->nvws; - - nvws->res_free(&cnv40->vp_exec_heap); - nvws->res_free(&cnv40->vp_data_heap); - nvws->res_free(&cnv40->query_heap); - nvws->notifier_free(&cnv40->query); - nvws->notifier_free(&cnv40->sync); - nvws->grobj_free(&cnv40->curie); - free(cnv40); -} - -static struct nv40_channel_context * -nv40_channel_init(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) -{ - struct nv40_channel_context *cnv40 = NULL; - struct nouveau_stateobj *so; - unsigned curie_class = 0; - int ret; - - 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; - } - - cnv40 = CALLOC(1, sizeof(struct nv40_channel_context)); - if (!cnv40) - return NULL; - cnv40->chipset = chipset; - cnv40->nvws = nvws; - - /* Notifier for sync purposes */ - ret = nvws->notifier_alloc(nvws, 1, &cnv40->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv40_channel_takedown(cnv40); - return NULL; - } - - /* Query objects */ - ret = nvws->notifier_alloc(nvws, 32, &cnv40->query); - if (ret) { - NOUVEAU_ERR("Error initialising query objects: %d\n", ret); - nv40_channel_takedown(cnv40); - return NULL; - } - - ret = nvws->res_init(&cnv40->query_heap, 0, 32); - if (ret) { - NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); - nv40_channel_takedown(cnv40); - return NULL; - } - - /* Vtxprog resources */ - if (nvws->res_init(&cnv40->vp_exec_heap, 0, 512) || - nvws->res_init(&cnv40->vp_data_heap, 0, 256)) { - nv40_channel_takedown(cnv40); - return NULL; - } - - /* 3D object */ - ret = nvws->grobj_alloc(nvws, curie_class, &cnv40->curie); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - - /* Static curie initialisation */ - so = so_new(128, 0); - so_method(so, cnv40->curie, NV40TCL_DMA_NOTIFY, 1); - so_data (so, cnv40->sync->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_TEXTURE0, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->gart->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_COLOR1, 1); - so_data (so, nvws->channel->vram->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_COLOR0, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->vram->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_VTXBUF0, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->gart->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_FENCE, 2); - so_data (so, 0); - so_data (so, cnv40->query->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_UNK01AC, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->vram->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_COLOR2, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->vram->handle); - - so_method(so, cnv40->curie, 0x1ea4, 3); - so_data (so, 0x00000010); - so_data (so, 0x01000100); - so_data (so, 0xff800006); - - /* vtxprog output routing */ - so_method(so, cnv40->curie, 0x1fc4, 1); - so_data (so, 0x06144321); - so_method(so, cnv40->curie, 0x1fc8, 2); - so_data (so, 0xedcba987); - so_data (so, 0x00000021); - so_method(so, cnv40->curie, 0x1fd0, 1); - so_data (so, 0x00171615); - so_method(so, cnv40->curie, 0x1fd4, 1); - so_data (so, 0x001b1a19); - - so_method(so, cnv40->curie, 0x1ef8, 1); - so_data (so, 0x0020ffff); - so_method(so, cnv40->curie, 0x1d64, 1); - so_data (so, 0x00d30000); - so_method(so, cnv40->curie, 0x1e94, 1); - so_data (so, 0x00000001); - - so_emit(nvws, so); - so_ref(NULL, &so); - nvws->push_flush(nvws->channel, 0); - - return cnv40; + nvws->notifier_wait(nv40->screen->sync, 0, 0, 2000); } static void @@ -186,32 +40,22 @@ nv40_destroy(struct pipe_context *pipe) if (nv40->draw) draw_destroy(nv40->draw); - - if (nv40->hw) { - if (--nv40->hw->refcount == 0) - nv40_channel_takedown(nv40->hw); - } - free(nv40); } struct pipe_context * nv40_create(struct pipe_screen *pscreen) { + struct nv40_screen *screen = nv40_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; struct nv40_context *nv40; - unsigned chipset = nv40_screen(pscreen)->chipset; - struct nouveau_winsys *nvws = nv40_screen(pscreen)->nvws; + unsigned chipset = screen->chipset; + struct nouveau_winsys *nvws = screen->nvws; nv40 = CALLOC(1, sizeof(struct nv40_context)); if (!nv40) return NULL; - - nv40->hw = nv40_channel_init(ws, nvws, chipset); - if (!nv40->hw) { - nv40_destroy(&nv40->pipe); - return NULL; - } + nv40->screen = screen; nv40->chipset = chipset; nv40->nvws = nvws; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 3ddfbd43f6..3b669594dc 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -11,7 +11,7 @@ #include "nouveau/nouveau_gldefs.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ - struct nv40_channel_context *ctx = nv40->hw + struct nv40_screen *ctx = nv40->screen #include "nouveau/nouveau_push.h" #include "nouveau/nouveau_stateobj.h" @@ -59,6 +59,8 @@ enum nv40_state_index { NV40_STATE_MAX = 33 }; +#include "nv40_screen.h" + #define NV40_NEW_BLEND (1 << 0) #define NV40_NEW_RAST (1 << 1) #define NV40_NEW_ZSA (1 << 2) @@ -76,28 +78,6 @@ enum nv40_state_index { #define NV40_FALLBACK_TNL (1 << 0) #define NV40_FALLBACK_RAST (1 << 1) -struct nv40_channel_context { - struct nouveau_winsys *nvws; - unsigned refcount; - - unsigned chipset; - - /* 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]; -}; - struct nv40_rasterizer_state { struct pipe_rasterizer_state pipe; struct nouveau_stateobj *so; @@ -125,9 +105,10 @@ struct nv40_state { struct nv40_context { struct pipe_context pipe; + struct nouveau_winsys *nvws; + struct nv40_screen *screen; - struct nv40_channel_context *hw; struct draw_context *draw; int chipset; diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 2a8abb32a3..3c4ea7e99e 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -810,11 +810,11 @@ nv40_fragprog_validate(struct nv40_context *nv40) nv40_fragprog_upload(nv40, fp); so = so_new(4, 1); - so_method(so, nv40->hw->curie, NV40TCL_FP_ADDRESS, 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->hw->curie, NV40TCL_FP_CONTROL, 1); + so_method(so, nv40->screen->curie, NV40TCL_FP_CONTROL, 1); so_data (so, fp->fp_control); so_ref(so, &fp->so); diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 6be8378c08..436f954cec 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -106,7 +106,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) txs = tf->swizzle; so = so_new(16, 2); - so_method(so, nv40->hw->curie, NV40TCL_TEX_OFFSET(unit), 8); + 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); @@ -117,7 +117,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) so_data (so, (pt->width[0] << NV40TCL_TEX_SIZE0_W_SHIFT) | pt->height[0]); so_data (so, ps->bcol); - so_method(so, nv40->hw->curie, NV40TCL_TEX_SIZE1(unit), 1); + 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; @@ -137,7 +137,7 @@ nv40_fragtex_validate(struct nv40_context *nv40) samplers &= ~(1 << unit); so = so_new(2, 0); - so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1); + 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)); diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c index 8bca2788b9..0317845624 100644 --- a/src/gallium/drivers/nv40/nv40_query.c +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -45,9 +45,9 @@ nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq) assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER); - if (nv40->nvws->res_alloc(nv40->hw->query_heap, 1, NULL, &q->object)) + if (nv40->nvws->res_alloc(nv40->screen->query_heap, 1, NULL, &q->object)) assert(0); - nv40->nvws->notifier_reset(nv40->hw->query, q->object->start); + nv40->nvws->notifier_reset(nv40->screen->query, q->object->start); BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1); OUT_RING (1); @@ -82,17 +82,17 @@ nv40_query_result(struct pipe_context *pipe, struct pipe_query *pq, if (!q->ready) { unsigned status; - status = nvws->notifier_status(nv40->hw->query, + 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->hw->query, q->object->start, + nvws->notifier_wait(nv40->screen->query, q->object->start, NV_NOTIFY_STATE_STATUS_COMPLETED, 0); } - q->result = nvws->notifier_retval(nv40->hw->query, + q->result = nvws->notifier_retval(nv40->screen->query, q->object->start); q->ready = TRUE; nvws->res_free(&q->object); diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 66e84b6890..268ca83ce0 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -4,6 +4,10 @@ #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) { @@ -121,6 +125,16 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, 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); } @@ -129,13 +143,125 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, unsigned chipset) { struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); + struct nouveau_stateobj *so; + unsigned curie_class; + int ret; if (!screen) return NULL; - screen->chipset = chipset; 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->channel, 0); + screen->pipe.winsys = ws; screen->pipe.destroy = nv40_screen_destroy; diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index 88b8fed26c..9f9668dbb6 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -8,6 +8,21 @@ struct nv40_screen { struct nouveau_winsys *nvws; unsigned chipset; + + /* 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 * diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 24335fbc44..caa2f9df0c 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -10,7 +10,7 @@ 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->hw->curie; + struct nouveau_grobj *curie = nv40->screen->curie; struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso)); struct nouveau_stateobj *so = so_new(16, 0); @@ -286,7 +286,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, 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->hw->curie; + struct nouveau_grobj *curie = nv40->screen->curie; /*XXX: ignored: * light_twoside @@ -420,18 +420,18 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); struct nouveau_stateobj *so = so_new(32, 0); - so_method(so, nv40->hw->curie, NV40TCL_DEPTH_FUNC, 3); + so_method(so, nv40->screen->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, nv40->hw->curie, NV40TCL_ALPHA_TEST_ENABLE, 3); + so_method(so, nv40->screen->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, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); + so_method(so, nv40->screen->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)); @@ -441,12 +441,12 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, 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, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); so_data (so, 0); } if (cso->stencil[1].enabled) { - so_method(so, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 8); + so_method(so, nv40->screen->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)); @@ -456,7 +456,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, 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, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 1); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 1); so_data (so, 0); } diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c index dd09830aa3..95e6d7394f 100644 --- a/src/gallium/drivers/nv40/nv40_state_blend.c +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -21,7 +21,7 @@ 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->hw->curie, NV40TCL_BLEND_COLOR, 1); + 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) | diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index bb2ce0f722..221503617c 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -67,8 +67,8 @@ nv40_state_emit(struct nv40_context *nv40) while (state->dirty) { unsigned idx = ffsll(state->dirty) - 1; - so_ref (state->hw[idx], &nv40->hw->state[idx]); - so_emit(nv40->nvws, nv40->hw->state[idx]); + so_ref (state->hw[idx], &nv40->screen->state[idx]); + so_emit(nv40->nvws, nv40->screen->state[idx]); state->dirty &= ~(1ULL << idx); } diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 3d0ab92003..71795ab182 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -72,73 +72,73 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) } if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR0, 1); + 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->hw->curie, NV40TCL_COLOR0_PITCH, 2); + 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->hw->curie, NV40TCL_DMA_COLOR1, 1); + 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->hw->curie, NV40TCL_COLOR1_OFFSET, 2); + 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->hw->curie, NV40TCL_DMA_COLOR2, 1); + 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->hw->curie, NV40TCL_COLOR2_OFFSET, 1); + 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->hw->curie, NV40TCL_COLOR2_PITCH, 1); + 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->hw->curie, NV40TCL_DMA_COLOR3, 1); + 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->hw->curie, NV40TCL_COLOR3_OFFSET, 1); + 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->hw->curie, NV40TCL_COLOR3_PITCH, 1); + 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->hw->curie, NV40TCL_DMA_ZETA, 1); + 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->hw->curie, NV40TCL_ZETA_OFFSET, 1); + 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->hw->curie, NV40TCL_ZETA_PITCH, 1); + so_method(so, nv40->screen->curie, NV40TCL_ZETA_PITCH, 1); so_data (so, zeta->pitch * zeta->cpp); } - so_method(so, nv40->hw->curie, NV40TCL_RT_ENABLE, 1); + so_method(so, nv40->screen->curie, NV40TCL_RT_ENABLE, 1); so_data (so, rt_enable); - so_method(so, nv40->hw->curie, NV40TCL_RT_HORIZ, 3); + 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->hw->curie, NV40TCL_VIEWPORT_HORIZ, 2); + 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->hw->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); + 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); diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index 09ffc49f96..9e9eadc511 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -12,7 +12,7 @@ nv40_state_scissor_validate(struct nv40_context *nv40) return FALSE; so = so_new(3, 0); - so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); + so_method(so, nv40->screen->curie, NV40TCL_SCISSOR_HORIZ, 2); if (rast->scissor) { so_data (so, ((s->maxx - s->minx) << 16) | s->minx); so_data (so, ((s->maxy - s->miny) << 16) | s->miny); diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index 001c396d74..b51024ad9b 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -4,7 +4,7 @@ static boolean nv40_state_stipple_validate(struct nv40_context *nv40) { struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; - struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_grobj *curie = nv40->screen->curie; struct nouveau_stateobj *so; if (nv40->state.hw[NV40_STATE_STIPPLE] && diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 9616be5052..3a32533907 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -6,7 +6,7 @@ nv40_state_viewport_validate(struct nv40_context *nv40) struct nouveau_stateobj *so = so_new(9, 0); struct pipe_viewport_state *vpt = &nv40->viewport; - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); + 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])); diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 1653ebf2a7..bedc8c6d4e 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -52,7 +52,7 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, } /* No support for 8bit indices, no support at all on 0x4497 chips */ - if (nv40->hw->curie->grclass == NV44TCL || ib_size == 1) + if (nv40->screen->curie->grclass == NV44TCL || ib_size == 1) return FALSE; switch (ib_size) { @@ -365,9 +365,9 @@ nv40_vbo_validate(struct nv40_context *nv40) num_hw++; vtxbuf = so_new(20, 18); - so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + so_method(vtxbuf, nv40->screen->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); vtxfmt = so_new(17, 0); - so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), num_hw); + so_method(vtxfmt, nv40->screen->curie, NV40TCL_VTXFMT(0), num_hw); inputs = vp->ir; for (hw = 0; hw < num_hw; hw++) { @@ -399,13 +399,13 @@ nv40_vbo_validate(struct nv40_context *nv40) } if (ib) { - so_method(vtxbuf, nv40->hw->curie, NV40TCL_IDXBUF_ADDRESS, 2); + so_method(vtxbuf, nv40->screen->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, nv40->hw->curie, 0x1710, 1); + so_method(vtxbuf, nv40->screen->curie, 0x1710, 1); so_data (vtxbuf, 0); so_ref(vtxbuf, &nv40->state.hw[NV40_STATE_VTXBUF]); diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index d3ed57b199..5b7a343e55 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -655,7 +655,7 @@ nv40_vertprog_validate(struct nv40_context *nv40) check_gpu_resources: /* Allocate hw vtxprog exec slots */ if (!vp->exec) { - struct nouveau_resource *heap = nv40->hw->vp_exec_heap; + struct nouveau_resource *heap = nv40->screen->vp_exec_heap; struct nouveau_stateobj *so; uint vplen = vp->nr_insns; @@ -672,9 +672,9 @@ check_gpu_resources: } so = so_new(5, 0); - so_method(so, nv40->hw->curie, NV40TCL_VP_START_FROM_ID, 1); + so_method(so, nv40->screen->curie, NV40TCL_VP_START_FROM_ID, 1); so_data (so, vp->exec->start); - so_method(so, nv40->hw->curie, NV40TCL_VP_ATTRIB_EN, 2); + so_method(so, nv40->screen->curie, NV40TCL_VP_ATTRIB_EN, 2); so_data (so, vp->ir); so_data (so, vp->or); so_ref(so, &vp->so); @@ -684,7 +684,7 @@ check_gpu_resources: /* Allocate hw vtxprog const slots */ if (vp->nr_consts && !vp->data) { - struct nouveau_resource *heap = nv40->hw->vp_data_heap; + 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) { -- cgit v1.2.3 From 0a12e4587ccf2c4fa71e93bb00b4582deb99a82c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 14:09:57 +1100 Subject: nouveau: turn pushbuf macros into inline functions --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 93 +++++++--- src/gallium/winsys/dri/nouveau/nouveau_context.h | 35 ++-- src/gallium/winsys/dri/nouveau/nouveau_local.h | 133 ++++++++------ .../winsys/dri/nouveau/nouveau_swapbuffers.c | 2 +- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 13 +- src/gallium/winsys/dri/nouveau/nv04_surface.c | 192 ++++++++++++--------- src/gallium/winsys/dri/nouveau/nv50_surface.c | 187 +++++++++++--------- 7 files changed, 396 insertions(+), 259 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 01fada5b89..7915afae22 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -21,6 +21,75 @@ static const struct dri_debug_control debug_control[] = { int __nouveau_debug = 0; #endif +static void +nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) +{ + nouveau_grobj_free(&nvc->NvNull); + 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_notifier_free(&nvc->sync_notifier); + + nouveau_channel_free(&nvc->channel); + + FREE(nvc); +} + +static struct nouveau_channel_context * +nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) +{ + struct nouveau_channel_context *nvc; + int ret; + + nvc = CALLOC_STRUCT(nouveau_channel_context); + if (!nvc) + return NULL; + nvc->chipset = chipset; + + if ((ret = nouveau_channel_alloc(nvdev, 0x8003d001, 0x8003d002, + &nvc->channel))) { + NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); + nouveau_channel_context_destroy(nvc); + return NULL; + } + + if ((ret = nouveau_grobj_alloc(nvc->channel, 0x00000000, 0x30, + &nvc->NvNull))) { + NOUVEAU_ERR("Error creating NULL object: %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 (chipset) { + case 0x50: + case 0x80: + 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, @@ -45,13 +114,6 @@ nouveau_context_create(const __GLcontextModes *glVis, return GL_FALSE; } - if ((ret = nouveau_channel_alloc(nv_screen->device, - 0x8003d001, 0x8003d002, - &nv->channel))) { - NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); - return GL_FALSE; - } - driContextPriv->driverPrivate = (void *)nv; nv->nv_screen = nv_screen; nv->dri_screen = driScrnPriv; @@ -101,16 +163,9 @@ nouveau_context_create(const __GLcontextModes *glVis, nv->frontbuffer = fb_surf; } - if ((ret = nouveau_grobj_alloc(nv->channel, 0x00000000, 0x30, - &nv->NvNull))) { - NOUVEAU_ERR("Error creating NULL object: %d\n", ret); - return GL_FALSE; - } - nv->next_handle = 0x80000000; - - if ((ret = nouveau_notifier_alloc(nv->channel, nv->next_handle++, 1, - &nv->sync_notifier))) { - NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret); + nv->nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset); + if (!nv->nvc) { + NOUVEAU_ERR("Failed initialising GPU channel context\n"); return GL_FALSE; } @@ -152,9 +207,7 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) st_flush(nv->st, PIPE_FLUSH_WAIT); st_destroy_context(nv->st); - nouveau_grobj_free(&nv->NvCtxSurf2D); - nouveau_grobj_free(&nv->NvImageBlit); - nouveau_channel_free(&nv->channel); + nouveau_channel_context_destroy(nv->nvc); free(nv); } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 5805f969ba..736c8d8bef 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -13,6 +13,25 @@ struct nouveau_framebuffer { struct st_framebuffer *stfb; }; +struct nouveau_channel_context { + unsigned chipset; + + struct nouveau_channel *channel; + + struct nouveau_notifier *sync_notifier; + + struct nouveau_grobj *NvNull; + struct nouveau_grobj *NvCtxSurf2D; + struct nouveau_grobj *NvImageBlit; + struct nouveau_grobj *NvGdiRect; + struct nouveau_grobj *NvM2MF; + struct nouveau_grobj *Nv2D; + + uint32_t next_handle; + uint32_t next_subchannel; + uint32_t next_sequence; +}; + struct nouveau_context { struct st_context *st; @@ -31,17 +50,7 @@ struct nouveau_context { struct pipe_surface *frontbuffer; /* Hardware context */ - struct nouveau_channel *channel; - struct nouveau_notifier *sync_notifier; - struct nouveau_grobj *NvNull; - struct nouveau_grobj *NvCtxSurf2D; - struct nouveau_grobj *NvImageBlit; - struct nouveau_grobj *NvGdiRect; - struct nouveau_grobj *NvM2MF; - struct nouveau_grobj *Nv2D; - uint32_t next_handle; - uint32_t next_subchannel; - uint32_t next_sequence; + struct nouveau_channel_context *nvc; /* pipe_surface accel */ struct pipe_surface *surf_src, *surf_dst; @@ -80,6 +89,10 @@ extern int __nouveau_debug; 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 *); diff --git a/src/gallium/winsys/dri/nouveau/nouveau_local.h b/src/gallium/winsys/dri/nouveau/nouveau_local.h index 59febca292..f7d91fc748 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_local.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_local.h @@ -1,8 +1,11 @@ #ifndef __NOUVEAU_LOCAL_H__ #define __NOUVEAU_LOCAL_H__ +#include "pipe/p_compiler.h" #include +struct pipe_buffer; + /* Debug output */ #define NOUVEAU_MSG(fmt, args...) do { \ fprintf(stdout, "nouveau: "fmt, ##args); \ @@ -24,66 +27,90 @@ #define NOUVEAU_DMA_TIMEOUT 2000 /* Push buffer access macros */ -#define OUT_RING(data) do { \ - (*nv->channel->pushbuf->cur++) = (data); \ -} while(0) - -#define OUT_RINGp(src,size) do { \ - memcpy(nv->channel->pushbuf->cur, (src), (size)<<2); \ - nv->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 FIRE_RING() do { \ - nouveau_pushbuf_flush(nv->channel, 0); \ -} while(0) - -#define BEGIN_RING_GR(obj,mthd,size) do { \ - if (nv->channel->pushbuf->remaining < ((size) + 1)) \ - nouveau_pushbuf_flush(nv->channel, ((size) + 1)); \ - OUT_RING(((obj)->subc << 13) | ((size) << 18) | (mthd)); \ - nv->channel->pushbuf->remaining -= ((size) + 1); \ -} while(0) - -#define BEGIN_RING(obj,mthd,size) do { \ - BEGIN_RING_GR(nv->obj, (mthd), (size)); \ -} while(0) - -#define BIND_RING(o,s) do { \ - nv->o->subc = (s); \ - BEGIN_RING(o, 0x0000, 1); \ - OUT_RING (nv->o->handle); \ -} while(0) - -#define OUT_RELOC(buf,data,flags,vor,tor) do { \ - nouveau_pipe_emit_reloc(nv->channel, nv->channel->pushbuf->cur++, \ - buf, (data), (flags), (vor), (tor)); \ -} while(0) +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 pipe_buffer *buf, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + nouveau_pipe_emit_reloc(chan, chan->pushbuf->cur++, buf, + data, flags, vor, tor); +} /* 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) +static INLINE void +OUT_RELOCd(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned data, unsigned flags, unsigned vor, unsigned tor) +{ + OUT_RELOC(chan, buf, data, flags | NOUVEAU_BO_OR, vor, tor); +} /* FB/TT object handle */ -#define OUT_RELOCo(bo,flags) do { \ - OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR, \ - nv->channel->vram->handle, nv->channel->gart->handle); \ -} while(0) +static INLINE void +OUT_RELOCo(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned flags) +{ + OUT_RELOC(chan, buf, 0, flags | NOUVEAU_BO_OR, + chan->vram->handle, chan->gart->handle); +} /* Low 32-bits of offset */ -#define OUT_RELOCl(bo,delta,flags) do { \ - OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_LOW, 0, 0); \ -} while(0) +static INLINE void +OUT_RELOCl(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_LOW, 0, 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) +static INLINE void +OUT_RELOCh(struct nouveau_channel *chan, struct pipe_buffer *buf, + unsigned delta, unsigned flags) +{ + OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_HIGH, 0, 0); +} #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c index 91bf243f42..70e0104e83 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c @@ -42,7 +42,7 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, nv->surface_copy(nv, dx, dy, sx, sy, w, h); } - FIRE_RING(); + FIRE_RING(nv->nvc->channel); UNLOCK_HARDWARE(nv); if (nv->last_stamp != dPriv->lastStamp) { diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 529f577181..50d7549b1b 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -11,7 +11,7 @@ nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count, { struct nouveau_context *nv = nvws->nv; - return nouveau_notifier_alloc(nv->channel, nv->next_handle++, + return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++, count, notify); } @@ -20,17 +20,16 @@ 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(nv->channel, nv->next_handle++, + ret = nouveau_grobj_alloc(chan, nv->nvc->next_handle++, grclass, grobj); if (ret) return ret; - (*grobj)->subc = nv->next_subchannel++; - assert((*grobj)->subc <= 7); - BEGIN_RING_GR(*grobj, 0x0000, 1); - OUT_RING ((*grobj)->handle); + assert(nv->nvc->next_subchannel < 7); + BIND_RING(chan, *grobj, nv->nvc->next_subchannel++); return 0; } @@ -103,7 +102,7 @@ nouveau_pipe_create(struct nouveau_context *nv) } nvws->nv = nv; - nvws->channel = nv->channel; + nvws->channel = nv->nvc->channel; nvws->res_init = nouveau_resource_init; nvws->res_alloc = nouveau_resource_alloc; diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index fe1ea4ed70..cdcd71eaad 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -30,6 +30,7 @@ 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; @@ -40,17 +41,18 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, while (h) { int count = (h > 2047) ? 2047 : h; - BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RELOCl(src->buffer, src_offset, NOUVEAU_BO_VRAM | + BEGIN_RING(chan, nv->nvc->NvM2MF, + NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(chan, src->buffer, src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(dst->buffer, dst_offset, NOUVEAU_BO_VRAM | + OUT_RELOCl(chan, dst->buffer, dst_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR); - OUT_RING (src->pitch * src->cpp); - OUT_RING (dst->pitch * dst->cpp); - OUT_RING (w * src->cpp); - OUT_RING (count); - OUT_RING (0x0101); - OUT_RING (0); + 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; @@ -62,16 +64,19 @@ static void nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) { - BEGIN_RING(NvImageBlit, 0x0300, 3); - OUT_RING ((sy << 16) | sx); - OUT_RING ((dy << 16) | dx); - OUT_RING (( h << 16) | w); + 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) @@ -81,12 +86,12 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, * to NV_MEMORY_TO_MEMORY_FORMAT in this case. */ if ((src->offset & 63) || (dst->offset & 63)) { - BEGIN_RING(NvM2MF, + BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); - OUT_RELOCo(src->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | - NOUVEAU_BO_RD); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | - NOUVEAU_BO_WR); + OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_GART | + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_GART | + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); nv->surface_copy = nv04_surface_copy_m2mf; nv->surf_dst = dst; @@ -101,15 +106,20 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, } nv->surface_copy = nv04_surface_copy_blit; - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (format); - OUT_RING (((dst->pitch * dst->cpp) << 16) | (src->pitch * src->cpp)); - OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, + NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, dst->buffer, 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, src->buffer, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); return 0; } @@ -117,7 +127,7 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, static void nv04_surface_copy_done(struct nouveau_context *nv) { - FIRE_RING(); + FIRE_RING(nv->nvc->channel); } static int @@ -125,6 +135,9 @@ 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) { @@ -137,86 +150,99 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, return 1; } - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (cs2d_format); - OUT_RING (((dst->pitch * dst->cpp) << 16) | (dst->pitch * dst->cpp)); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); - OUT_RING (gdirect_format); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); - OUT_RING (value); - BEGIN_RING(NvGdiRect, + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCo(chan, dst->buffer, 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, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->buffer, 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 ((dx << 16) | dy); - OUT_RING (( w << 16) | h); + OUT_RING (chan, (dx << 16) | dy); + OUT_RING (chan, ( w << 16) | h); - FIRE_RING(); + FIRE_RING(chan); return 0; } int -nouveau_surface_init_nv04(struct nouveau_context *nv) +nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) { + struct nouveau_channel *chan = nvc->channel; unsigned class; int ret; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, 0x39, - &nv->NvM2MF))) { + 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 (NvM2MF, nv->next_subchannel++); - BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - - class = nv->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : - NV10_CONTEXT_SURFACES_2D; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, - &nv->NvCtxSurf2D))) { + 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 = nvc->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 (NvCtxSurf2D, nv->next_subchannel++); - BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RING (nv->channel->vram->handle); - OUT_RING (nv->channel->vram->handle); - - class = nv->chipset < 0x10 ? NV04_IMAGE_BLIT : - NV12_IMAGE_BLIT; - if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class, - &nv->NvImageBlit))) { + 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 = nvc->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 (NvImageBlit, nv->next_subchannel++); - BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1); - OUT_RING (nv->NvCtxSurf2D->handle); - BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1); - OUT_RING (NV04_IMAGE_BLIT_OPERATION_SRCCOPY); + 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(nv->channel, nv->next_handle++, class, - &nv->NvGdiRect))) { + 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 (NvGdiRect, nv->next_subchannel++); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); - OUT_RING (nv->NvCtxSurf2D->handle); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); - OUT_RING (NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); - BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); - OUT_RING (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + 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); + 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; diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index 15a1002861..5d74fb8d2b 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -19,6 +19,8 @@ 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); @@ -26,34 +28,38 @@ nv50_surface_copy_prep(struct nouveau_context *nv, surf_format = nv50_format(dst->cpp); assert(surf_format >= 0); - BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); - OUT_RING (surf_format); - OUT_RING (1); - BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); - OUT_RING (dst->pitch * dst->cpp); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); - OUT_RING (0); - OUT_RING (0); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - - BEGIN_RING(Nv2D, NV50_2D_SRC_FORMAT, 2); - OUT_RING (surf_format); - OUT_RING (1); - BEGIN_RING(Nv2D, NV50_2D_SRC_PITCH, 5); - OUT_RING (src->pitch * src->cpp); - OUT_RING (src->pitch); - OUT_RING (src->height); - OUT_RELOCh(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2); + OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCo(chan, dst->buffer, 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, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->buffer, 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, src->buffer, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, src->buffer, src->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); return 0; } @@ -62,27 +68,30 @@ static void nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) { - BEGIN_RING(Nv2D, 0x0110, 1); - OUT_RING (0); - BEGIN_RING(Nv2D, NV50_2D_BLIT_DST_X, 12); - OUT_RING (dx); - OUT_RING (dy); - OUT_RING (w); - OUT_RING (h); - OUT_RING (0); - OUT_RING (1); - OUT_RING (0); - OUT_RING (1); - OUT_RING (0); - OUT_RING (sx); - OUT_RING (0); - OUT_RING (sy); + 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(); + FIRE_RING(nv->nvc->channel); } static int @@ -90,6 +99,8 @@ 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); @@ -100,57 +111,65 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, if (rect_format < 0) return 1; - BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY1, 1); - OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2); - OUT_RING (surf_format); - OUT_RING (1); - BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5); - OUT_RING (dst->pitch * dst->cpp); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4); - OUT_RING (0); - OUT_RING (0); - OUT_RING (dst->pitch); - OUT_RING (dst->height); - - BEGIN_RING(Nv2D, 0x0580, 3); - OUT_RING (4); - OUT_RING (rect_format); - OUT_RING (value); - - BEGIN_RING(Nv2D, NV50_2D_RECT_X1, 4); - OUT_RING (dx); - OUT_RING (dy); - OUT_RING (dx + w); - OUT_RING (dy + h); - - FIRE_RING(); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1); + OUT_RELOCo(chan, dst->buffer, 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, dst->buffer, dst->offset, + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->buffer, 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_init_nv50(struct nouveau_context *nv) +nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) { int ret; - ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, NV50_2D, - &nv->Nv2D); + ret = nouveau_grobj_alloc(nvc->channel, nvc->next_handle++, NV50_2D, + &nvc->Nv2D); if (ret) return ret; - BIND_RING (Nv2D, 0); - BEGIN_RING(Nv2D, NV50_2D_DMA_NOTIFY, 1); - OUT_RING (nv->sync_notifier->handle); - BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RING (nv->channel->vram->handle); - OUT_RING (nv->channel->vram->handle); - BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1); - OUT_RING (NV50_2D_OPERATION_SRCCOPY); + BIND_RING (nvc->channel, nvc->Nv2D, 0); + 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; -- cgit v1.2.3 From b560ed2444383b9634786fe742b8cb6f5cdfc781 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 14:56:42 +1100 Subject: nouveau: enable multi-context/single-channel support for nv40 --- src/gallium/drivers/nouveau/nouveau_winsys.h | 6 +-- src/gallium/drivers/nv30/nv30_context.c | 2 +- src/gallium/drivers/nv40/nv40_context.c | 3 +- src/gallium/drivers/nv40/nv40_context.h | 1 + src/gallium/drivers/nv40/nv40_screen.h | 2 + src/gallium/drivers/nv40/nv40_state_emit.c | 10 ++++ src/gallium/drivers/nv50/nv50_context.c | 2 +- src/gallium/winsys/dri/nouveau/nouveau_context.c | 63 +++++++++++++++++++++--- src/gallium/winsys/dri/nouveau/nouveau_context.h | 8 +++ src/gallium/winsys/dri/nouveau/nouveau_screen.h | 2 + src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 10 ++-- 11 files changed, 94 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 11ca7e80dd..44c8bb919b 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -54,20 +54,20 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, unsigned chipset); extern struct pipe_context * -nv30_create(struct pipe_screen *); +nv30_create(struct pipe_screen *, unsigned pctx_id); extern struct pipe_screen * nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, unsigned chipset); extern struct pipe_context * -nv40_create(struct pipe_screen *); +nv40_create(struct pipe_screen *, unsigned pctx_id); extern struct pipe_screen * nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, unsigned chipset); extern struct pipe_context * -nv50_create(struct pipe_screen *); +nv50_create(struct pipe_screen *, unsigned pctx_id); #endif diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 522fb13226..28d3f057cc 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -265,7 +265,7 @@ nv30_init_hwctx(struct nv30_context *nv30, int rankine_class) #define NV35TCL_CHIPSET_3X_MASK 0x000001e0 struct pipe_context * -nv30_create(struct pipe_screen *screen) +nv30_create(struct pipe_screen *screen, unsigned pctx_id) { struct pipe_winsys *pipe_winsys = screen->winsys; struct nouveau_winsys *nvws = nv30_screen(screen)->nvws; diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 084829ce28..203c843a01 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -44,7 +44,7 @@ nv40_destroy(struct pipe_context *pipe) } struct pipe_context * -nv40_create(struct pipe_screen *pscreen) +nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) { struct nv40_screen *screen = nv40_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; @@ -56,6 +56,7 @@ nv40_create(struct pipe_screen *pscreen) if (!nv40) return NULL; nv40->screen = screen; + nv40->pctx_id = pctx_id; nv40->chipset = chipset; nv40->nvws = nvws; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 3b669594dc..e118776306 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -108,6 +108,7 @@ struct nv40_context { struct nouveau_winsys *nvws; struct nv40_screen *screen; + unsigned pctx_id; struct draw_context *draw; diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index 9f9668dbb6..3ea78aadfd 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -9,6 +9,8 @@ struct nv40_screen { struct nouveau_winsys *nvws; unsigned chipset; + unsigned cur_pctx; + /* HW graphics objects */ struct nouveau_grobj *curie; struct nouveau_notifier *sync; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 221503617c..a95e2472e2 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -62,8 +62,18 @@ static void nv40_state_emit(struct nv40_context *nv40) { struct nv40_state *state = &nv40->state; + struct nv40_screen *screen = nv40->screen; unsigned i, samplers; + if (nv40->pctx_id != screen->cur_pctx) { + for (i = 0; i < NV40_STATE_MAX; i++) { + if (screen->state[i] != state->hw[i] && state->hw[i]) + state->dirty |= (1ULL << i); + } + + screen->cur_pctx = nv40->pctx_id; + } + while (state->dirty) { unsigned idx = ffsll(state->dirty) - 1; diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index e5054e34f6..c937b8de6d 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -56,7 +56,7 @@ nv50_init_hwctx(struct nv50_context *nv50, int tesla_class) #define GRCLASS5097_CHIPSETS 0x00000000 #define GRCLASS8297_CHIPSETS 0x00000010 struct pipe_context * -nv50_create(struct pipe_screen *pscreen) +nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) { struct pipe_winsys *pipe_winsys = pscreen->winsys; struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 7915afae22..dc852c9f49 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -4,6 +4,7 @@ #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" @@ -101,7 +102,8 @@ nouveau_context_create(const __GLcontextModes *glVis, struct nouveau_device_priv *nvdev; struct pipe_context *pipe = NULL; struct st_context *st_share = NULL; - int ret; + struct nouveau_channel_context *nvc = NULL; + int i, ret; if (sharedContextPrivate) { st_share = ((struct nouveau_context *)sharedContextPrivate)->st; @@ -163,12 +165,56 @@ nouveau_context_create(const __GLcontextModes *glVis, nv->frontbuffer = fb_surf; } - nv->nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset); - if (!nv->nvc) { - NOUVEAU_ERR("Failed initialising GPU channel context\n"); - return GL_FALSE; + /* 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 non-NV4x */ + switch (nv->chipset & 0xf0) { + case 0x40: + case 0x60: + break; + default: + nvc = NULL; + break; + } + + if (!nvc) { + nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset); + 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 */ if (nv->chipset < 0x50) ret = nouveau_surface_init_nv04(nv); else @@ -201,13 +247,18 @@ void nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) { struct nouveau_context *nv = driContextPriv->driverPrivate; + struct nouveau_channel_context *nvc = nv->nvc; assert(nv); st_flush(nv->st, PIPE_FLUSH_WAIT); st_destroy_context(nv->st); - nouveau_channel_context_destroy(nv->nvc); + if (nv->pctx_id >= 0) { + nvc->pctx[nv->pctx_id] = NULL; + if (--nvc->refcount <= 0) + nouveau_channel_context_destroy(nvc); + } free(nv); } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 736c8d8bef..92f551855a 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -14,6 +14,13 @@ struct nouveau_framebuffer { }; struct nouveau_channel_context { + struct pipe_screen *pscreen; + int refcount; + + unsigned cur_pctx; + unsigned nr_pctx; + struct pipe_context **pctx; + unsigned chipset; struct nouveau_channel *channel; @@ -51,6 +58,7 @@ struct nouveau_context { /* Hardware context */ struct nouveau_channel_context *nvc; + int pctx_id; /* pipe_surface accel */ struct pipe_surface *surf_src, *surf_dst; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.h b/src/gallium/winsys/dri/nouveau/nouveau_screen.h index 019823bd44..e9da202690 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.h @@ -14,6 +14,8 @@ struct nouveau_screen { uint32_t front_pitch; uint32_t front_cpp; uint32_t front_height; + + void *nvc; }; #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 50d7549b1b..87619bdcfb 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -70,11 +70,12 @@ nouveau_pipe_emit_reloc(struct nouveau_channel *chan, void *ptr, 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 *, unsigned chipset); - struct pipe_context *(*hw_create)(struct pipe_screen *); + struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); struct pipe_winsys *ws; struct pipe_screen *pscreen; @@ -125,7 +126,10 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->surface_fill = nouveau_pipe_surface_fill; ws = nouveau_create_pipe_winsys(nv); - pscreen = hws_create(ws, nvws, nv->chipset); - return hw_create(pscreen); + + if (!nvc->pscreen) + nvc->pscreen = hws_create(ws, nvws, nv->chipset); + nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); + return nvc->pctx[nv->pctx_id]; } -- cgit v1.2.3 From 59d4b7cc626704dbbd9c817019ec2dd9183322ad Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 15:28:24 +1100 Subject: nv40: fix segv when app "skips" texture units. --- src/gallium/drivers/nv40/nv40_state_emit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index a95e2472e2..9f268640e0 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -67,7 +67,7 @@ nv40_state_emit(struct nv40_context *nv40) if (nv40->pctx_id != screen->cur_pctx) { for (i = 0; i < NV40_STATE_MAX; i++) { - if (screen->state[i] != state->hw[i] && state->hw[i]) + if (state->hw[i] && screen->state[i] != state->hw[i]) state->dirty |= (1ULL << i); } @@ -84,6 +84,8 @@ nv40_state_emit(struct nv40_context *nv40) 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); -- cgit v1.2.3 From 578b5cd9a030189bcba5c3e86080e1e26eb6e108 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 16:35:47 +1100 Subject: nouveau: fix potential crash --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index dc852c9f49..2e54729aa9 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -256,8 +256,10 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) if (nv->pctx_id >= 0) { nvc->pctx[nv->pctx_id] = NULL; - if (--nvc->refcount <= 0) + if (--nvc->refcount <= 0) { nouveau_channel_context_destroy(nvc); + nv->nv_screen->nvc = NULL; + } } free(nv); -- cgit v1.2.3 From a5966c8b28702bba1e4eb4bb4aec2247c90fcfa2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 16:39:24 +1100 Subject: nouveau: silence some warnings --- src/gallium/winsys/dri/nouveau/nouveau_local.h | 6 ++++-- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_local.h b/src/gallium/winsys/dri/nouveau/nouveau_local.h index f7d91fc748..8a52f26714 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_local.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_local.h @@ -2,6 +2,7 @@ #define __NOUVEAU_LOCAL_H__ #include "pipe/p_compiler.h" +#include "nouveau_winsys_pipe.h" #include struct pipe_buffer; @@ -76,8 +77,9 @@ static INLINE void OUT_RELOC(struct nouveau_channel *chan, struct pipe_buffer *buf, unsigned data, unsigned flags, unsigned vor, unsigned tor) { - nouveau_pipe_emit_reloc(chan, chan->pushbuf->cur++, buf, - data, flags, vor, tor); + nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, + nouveau_buffer(buf)->bo, + data, flags, vor, tor); } /* Raw data + flags depending on FB/TT buffer */ diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 87619bdcfb..dc7c4c3d71 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -58,7 +58,7 @@ nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, return 0; } -int +static int nouveau_pipe_emit_reloc(struct nouveau_channel *chan, void *ptr, struct pipe_buffer *buf, uint32_t data, uint32_t flags, uint32_t vor, uint32_t tor) @@ -77,7 +77,6 @@ nouveau_pipe_create(struct nouveau_context *nv) unsigned chipset); struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); struct pipe_winsys *ws; - struct pipe_screen *pscreen; if (!nvws) return NULL; -- cgit v1.2.3 From 57b8711aebdce9bc21bf3311c50dbfb0f9ad6d42 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 2 Mar 2008 16:48:15 +1100 Subject: nv40: nuke debug --- src/gallium/drivers/nv40/nv40_fragprog.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 3c4ea7e99e..d981a02a63 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -416,8 +416,6 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, 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); -- cgit v1.2.3 From 1de15ad83e5a6902ac57212a3df63bb9b829bc20 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 3 Mar 2008 00:01:44 +1100 Subject: nv40: re-do vtxbuf format code --- src/gallium/drivers/nv40/nv40_vbo.c | 79 +++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 29 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index bedc8c6d4e..f16afc23b8 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -9,34 +9,53 @@ #include "nouveau/nouveau_pushbuf.h" static INLINE int -nv40_vbo_ncomp(uint format) +nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) { - 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 -nv40_vbo_type(uint format) -{ - switch (pf_type(format)) { - case PIPE_FORMAT_TYPE_FLOAT: - return NV40TCL_VTXFMT_TYPE_FLOAT; - case PIPE_FORMAT_TYPE_UNORM: - return NV40TCL_VTXFMT_TYPE_UBYTE; + 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; default: - { - char fs[128]; - pf_sprint_name(fs, format); + pf_sprint_name(fs, pipe); NOUVEAU_ERR("Unknown format %s\n", fs); - return NV40TCL_VTXFMT_TYPE_FLOAT; + return 1; } + + switch (pipe) { + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R32_FLOAT: + *ncomp = 1; + break; + case PIPE_FORMAT_R8G8_UNORM: + case PIPE_FORMAT_R32G32_FLOAT: + *ncomp = 2; + break; + case PIPE_FORMAT_R8G8B8_UNORM: + case PIPE_FORMAT_R32G32B32_FLOAT: + *ncomp = 3; + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + *ncomp = 4; + break; + default: + pf_sprint_name(fs, pipe); + NOUVEAU_ERR("Unknown format %s\n", fs); + return 1; } + + return 0; } static boolean @@ -82,11 +101,11 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, struct pipe_vertex_buffer *vb) { struct pipe_winsys *ws = nv40->pipe.winsys; - int type, ncomp; + unsigned type, ncomp; void *map; - type = nv40_vbo_type(ve->src_format); - ncomp = nv40_vbo_ncomp(ve->src_format); + 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; @@ -373,6 +392,7 @@ nv40_vbo_validate(struct nv40_context *nv40) for (hw = 0; hw < num_hw; hw++) { struct pipe_vertex_element *ve; struct pipe_vertex_buffer *vb; + unsigned type, ncomp; if (!(inputs & (1 << hw))) { so_data(vtxbuf, 0); @@ -389,13 +409,14 @@ nv40_vbo_validate(struct nv40_context *nv40) continue; } + if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) + assert(0); + 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) | - (nv40_vbo_ncomp(ve->src_format) << - NV40TCL_VTXFMT_SIZE_SHIFT) | - nv40_vbo_type(ve->src_format))); + (ncomp << NV40TCL_VTXFMT_SIZE_SHIFT) | type)); } if (ib) { -- cgit v1.2.3 From 82f22d9e147ed55c2ca513ebc2d069e197d36ea8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 6 Mar 2008 11:52:25 +1100 Subject: nv30: a couple of vtxprog fixes --- src/gallium/drivers/nv30/nv30_context.c | 2 +- src/gallium/drivers/nv30/nv30_vertprog.c | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 28d3f057cc..0124f9af0f 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -319,7 +319,7 @@ nv30_create(struct pipe_screen *screen, unsigned pctx_id) } /* Vtxprog resources */ - if (nvws->res_init(&nv30->vertprog.exec_heap, 0, 512) || + if (nvws->res_init(&nv30->vertprog.exec_heap, 0, 256) || nvws->res_init(&nv30->vertprog.data_heap, 0, 256)) { nv30_destroy(&nv30->pipe); return NULL; diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 4a8269d5dd..548b6907d0 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -225,6 +225,18 @@ nv30_vp_arith(struct nv30_vpc *vpc, int slot, int op, // 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); @@ -752,7 +764,7 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) } #endif BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_FROM_ID, 1); - OUT_RING (/*vp->exec->start*/0); + 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); @@ -760,8 +772,7 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) } BEGIN_RING(rankine, NV34TCL_VP_START_FROM_ID, 1); -// OUT_RING (vp->exec->start); - OUT_RING (0); + OUT_RING (vp->exec->start); nv30->vertprog.active = vp; } -- cgit v1.2.3 From 66ba021e9fa2fa932cb9be8fc2fb8272baf51fc6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 7 Mar 2008 22:48:26 +1100 Subject: nouveau: another "argh gallium fscks with assert" fix --- src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c index 7d5eddb92f..fd9a5c5a96 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -193,7 +193,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) nouveau_fence_ref(NULL, &fence); /* Allocate space for next push buffer */ - assert(!nouveau_pushbuf_space(chan, min)); + ret = nouveau_pushbuf_space(chan, min); + assert(!ret); return 0; } -- cgit v1.2.3 From ae0e047ba4e05d25d6e0b9b0574e36c7e8ccd510 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 10 Mar 2008 14:27:22 +1100 Subject: nv30: put the card into vtxprog mode + small cleanups/fixes --- src/gallium/drivers/nv30/nv30_context.c | 122 ++----------------------------- src/gallium/drivers/nv30/nv30_vertprog.c | 5 ++ 2 files changed, 10 insertions(+), 117 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 0124f9af0f..b3906e28e3 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -133,129 +133,17 @@ nv30_init_hwctx(struct nv30_context *nv30, int rankine_class) BEGIN_RING(rankine, NV34TCL_RC_ENABLE, 1); OUT_RING (0); - /* Attempt to setup a known state.. Probably missing a heap of - * stuff here.. - */ - BEGIN_RING(rankine, NV34TCL_STENCIL_FRONT_ENABLE, 1); - OUT_RING (0); - BEGIN_RING(rankine, NV34TCL_STENCIL_BACK_ENABLE, 1); - OUT_RING (0); - BEGIN_RING(rankine, NV34TCL_ALPHA_FUNC_ENABLE, 1); - OUT_RING (0); - BEGIN_RING(rankine, NV34TCL_DEPTH_WRITE_ENABLE, 2); - OUT_RING (0); /* wr disable */ - OUT_RING (0); /* test disable */ - BEGIN_RING(rankine, NV34TCL_COLOR_MASK, 1); - OUT_RING (0x01010101); /* TR,TR,TR,TR */ - BEGIN_RING(rankine, NV34TCL_CULL_FACE_ENABLE, 1); - OUT_RING (0); - BEGIN_RING(rankine, NV34TCL_BLEND_FUNC_ENABLE, 5); - OUT_RING (0); /* Blend enable */ - OUT_RING (0); /* Blend src */ - OUT_RING (0); /* Blend dst */ - OUT_RING (0x00000000); /* Blend colour */ - OUT_RING (0x8006); /* FUNC_ADD */ - BEGIN_RING(rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2); - OUT_RING (0); - OUT_RING (0x1503 /*GL_COPY*/); - BEGIN_RING(rankine, NV34TCL_DITHER_ENABLE, 1); - OUT_RING (1); - BEGIN_RING(rankine, NV34TCL_SHADE_MODEL, 1); - OUT_RING (0x1d01 /*GL_SMOOTH*/); - BEGIN_RING(rankine, NV34TCL_POLYGON_OFFSET_FACTOR,2); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - BEGIN_RING(rankine, NV34TCL_POLYGON_MODE_FRONT, 2); - OUT_RING (0x1b02 /*GL_FILL*/); - OUT_RING (0x1b02 /*GL_FILL*/); - /* - Disable texture units - * - Set fragprog to MOVR result.color, fragment.color */ - for (i=0;i<16;i++) { - BEGIN_RING(rankine, - NV34TCL_TX_ENABLE(i), 1); - OUT_RING (0); - } - /* Polygon stipple */ - BEGIN_RING(rankine, - NV34TCL_POLYGON_STIPPLE_PATTERN(0), 0x20); - for (i=0;i<0x20;i++) - OUT_RING (0xFFFFFFFF); - - int w=4096; - int h=4096; - int pitch=4096*4; - BEGIN_RING(rankine, NV34TCL_RT_HORIZ, 5); - OUT_RING (w<<16); - OUT_RING (h<<16); - OUT_RING (0x148); /* format */ - OUT_RING (pitch << 16 | pitch); - OUT_RING (0x0); - BEGIN_RING(rankine, 0x0a00, 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); - OUT_RING ((h-1)<<16); - BEGIN_RING(rankine, NV34TCL_SCISSOR_HORIZ, 2); - OUT_RING (w<<16); - OUT_RING (h<<16); - BEGIN_RING(rankine, NV34TCL_VIEWPORT_HORIZ, 2); - OUT_RING (w<<16); - OUT_RING (h<<16); - - BEGIN_RING(rankine, NV34TCL_VIEWPORT_TRANSLATE_X, 8); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (1.0); - OUT_RINGf (1.0); - OUT_RINGf (1.0); - OUT_RINGf (0.0); - - BEGIN_RING(rankine, NV34TCL_MODELVIEW_MATRIX(0), 16); - OUT_RINGf (1.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (1.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (1.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (1.0); - - BEGIN_RING(rankine, NV34TCL_PROJECTION_MATRIX(0), 16); - OUT_RINGf (1.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); + BEGIN_RING(rankine, NV34TCL_DEPTH_RANGE_NEAR, 2); OUT_RINGf (0.0); OUT_RINGf (1.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (1.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (0.0); - OUT_RINGf (1.0); - - BEGIN_RING(rankine, NV34TCL_SCISSOR_HORIZ, 2); - OUT_RING (4096<<16); - OUT_RING (4096<<16); BEGIN_RING(rankine, NV34TCL_MULTISAMPLE_CONTROL, 1); OUT_RING (0xffff0000); + /* enables use of vp rather than fixed-function somehow */ + BEGIN_RING(rankine, 0x1e94, 1); + OUT_RING (0x13); + FIRE_RING (); return TRUE; } diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 548b6907d0..96bc4b5ef9 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -193,6 +193,11 @@ emit_dst(struct nv30_vpc *vpc, uint32_t *hw, int slot, struct nv30_sreg dst) 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); -- cgit v1.2.3 From 1fb3c94f03e07a80bb7a93777d4fef5173da71ca Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 02:20:40 +1100 Subject: nv50: some forgotten changes --- src/gallium/drivers/nv50/nv50_draw.c | 45 +++++++++++++++--------- src/gallium/drivers/nv50/nv50_screen.c | 2 ++ src/gallium/winsys/dri/nouveau/nouveau_context.c | 2 +- 3 files changed, 32 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_draw.c b/src/gallium/drivers/nv50/nv50_draw.c index c6ed6838c6..790408c6df 100644 --- a/src/gallium/drivers/nv50/nv50_draw.c +++ b/src/gallium/drivers/nv50/nv50_draw.c @@ -3,53 +3,66 @@ #include "nv50_context.h" -struct nv50_draw_stage { - struct draw_stage draw; +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_draw_point(struct draw_stage *draw, struct prim_header *prim) +nv50_render_point(struct draw_stage *stage, struct prim_header *prim) { NOUVEAU_ERR("\n"); } static void -nv50_draw_line(struct draw_stage *draw, struct prim_header *prim) +nv50_render_line(struct draw_stage *stage, struct prim_header *prim) { NOUVEAU_ERR("\n"); } static void -nv50_draw_tri(struct draw_stage *draw, struct prim_header *prim) +nv50_render_tri(struct draw_stage *stage, struct prim_header *prim) { NOUVEAU_ERR("\n"); } static void -nv50_draw_flush(struct draw_stage *draw, unsigned flags) +nv50_render_flush(struct draw_stage *stage, unsigned flags) { } static void -nv50_draw_reset_stipple_counter(struct draw_stage *draw) +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_draw_stage *nv50draw = CALLOC_STRUCT(nv50_draw_stage); + struct nv50_render_stage *rs = CALLOC_STRUCT(nv50_render_stage); - nv50draw->nv50 = nv50; - nv50draw->draw.draw = nv50->draw; - nv50draw->draw.point = nv50_draw_point; - nv50draw->draw.line = nv50_draw_line; - nv50draw->draw.tri = nv50_draw_tri; - nv50draw->draw.flush = nv50_draw_flush; - nv50draw->draw.reset_stipple_counter = nv50_draw_reset_stipple_counter; + rs->nv50 = nv50; + rs->stage.draw = nv50->draw; + rs->stage.destroy = nv50_render_destroy; + rs->stage.point = nv50_render_point; + rs->stage.line = nv50_render_line; + rs->stage.tri = nv50_render_tri; + rs->stage.flush = nv50_render_flush; + rs->stage.reset_stipple_counter = nv50_render_reset_stipple_counter; - return &nv50draw->draw; + return &rs->stage; } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index f091779e3b..77ceb678f2 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -77,6 +77,8 @@ nv50_screen_get_paramf(struct pipe_screen *pscreen, int param) return 16.0; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 4.0; + case PIPE_CAP_BITMAP_TEXCOORD_BIAS: + return 0.0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0.0; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 2e54729aa9..8dac08a5d2 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -72,7 +72,7 @@ nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) return NULL; } - switch (chipset) { + switch (chipset & 0xf0) { case 0x50: case 0x80: ret = nouveau_surface_channel_create_nv50(nvc); -- cgit v1.2.3 From b2e48f848496d5e315e536688c8c33dfb1fab7eb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 02:39:13 +1100 Subject: nv50: convert to hwctx-in-screen as nv40 is --- src/gallium/drivers/nv50/nv50_context.c | 61 ++++----------------------------- src/gallium/drivers/nv50/nv50_context.h | 11 +++--- src/gallium/drivers/nv50/nv50_screen.c | 49 +++++++++++++++++++++++++- src/gallium/drivers/nv50/nv50_screen.h | 5 +++ src/gallium/drivers/nv50/nv50_surface.c | 4 +-- 5 files changed, 67 insertions(+), 63 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index c937b8de6d..980d066c84 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -10,10 +10,11 @@ static void nv50_flush(struct pipe_context *pipe, unsigned flags) { struct nv50_context *nv50 = (struct nv50_context *)pipe; - struct nouveau_winsys *nvws = nv50->nvws; + struct nv50_screen *screen = nv50->screen; + struct nouveau_winsys *nvws = screen->nvws; if (flags & PIPE_FLUSH_WAIT) { - nvws->notifier_reset(nv50->sync, 0); + nvws->notifier_reset(screen->sync, 0); BEGIN_RING(tesla, 0x104, 1); OUT_RING (0); BEGIN_RING(tesla, 0x100, 1); @@ -23,7 +24,7 @@ nv50_flush(struct pipe_context *pipe, unsigned flags) FIRE_RING(); if (flags & PIPE_FLUSH_WAIT) - nvws->notifier_wait(nv50->sync, 0, 0, 2000); + nvws->notifier_wait(screen->sync, 0, 0, 2000); } static void @@ -35,66 +36,18 @@ nv50_destroy(struct pipe_context *pipe) free(nv50); } -static boolean -nv50_init_hwctx(struct nv50_context *nv50, int tesla_class) -{ - struct nouveau_winsys *nvws = nv50->nvws; - int ret; - - if ((ret = nvws->grobj_alloc(nvws, tesla_class, &nv50->tesla))) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - - BEGIN_RING(tesla, NV50TCL_DMA_NOTIFY, 1); - OUT_RING (nv50->sync->handle); - - FIRE_RING (); - return TRUE; -} - -#define GRCLASS5097_CHIPSETS 0x00000000 -#define GRCLASS8297_CHIPSETS 0x00000010 struct pipe_context * nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) { struct pipe_winsys *pipe_winsys = pscreen->winsys; - struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; - unsigned chipset = nv50_screen(pscreen)->chipset; + struct nv50_screen *screen = nv50_screen(pscreen); struct nv50_context *nv50; - int tesla_class, ret; - - if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) { - NOUVEAU_ERR("Not a G8x chipset\n"); - return NULL; - } - - if (GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) { - tesla_class = 0x5097; - } else - if (GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) { - tesla_class = 0x8297; - } else { - NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset); - return NULL; - } nv50 = CALLOC_STRUCT(nv50_context); if (!nv50) return NULL; - nv50->chipset = chipset; - nv50->nvws = nvws; - - if ((ret = nvws->notifier_alloc(nvws, 1, &nv50->sync))) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - free(nv50); - return NULL; - } - - if (!nv50_init_hwctx(nv50, tesla_class)) { - free(nv50); - return NULL; - } + nv50->screen = screen; + nv50->pctx_id = pctx_id; nv50->pipe.winsys = pipe_winsys; nv50->pipe.screen = pscreen; diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index a529bf3c3e..e2656bd539 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -11,10 +11,11 @@ #include "nouveau/nouveau_gldefs.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ - struct nv50_context *ctx = nv50 + 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); @@ -23,13 +24,11 @@ struct nv50_context { struct pipe_context pipe; - struct nouveau_winsys *nvws; - struct draw_context *draw; + struct nv50_screen *screen; + unsigned pctx_id; - int chipset; - struct nouveau_grobj *tesla; - struct nouveau_notifier *sync; + struct draw_context *draw; }; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 77ceb678f2..f8fd11dc5f 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -4,6 +4,11 @@ #include "nv50_context.h" #include "nv50_screen.h" +#include "nouveau/nouveau_stateobj.h" + +#define GRCLASS5097_CHIPSETS 0x00000000 +#define GRCLASS8297_CHIPSETS 0x00000010 + static boolean nv50_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, uint type) @@ -96,13 +101,55 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, unsigned chipset) { struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); + struct nouveau_stateobj *so; + unsigned tesla_class = 0, ret; if (!screen) return NULL; - screen->chipset = chipset; 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; + } + + if (GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) { + tesla_class = 0x5097; + } else + if (GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) { + tesla_class = 0x8297; + } else { + 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_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws->channel, 0); + screen->pipe.winsys = ws; screen->pipe.destroy = nv50_screen_destroy; diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index d664816a03..6e4120d669 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -8,6 +8,11 @@ struct nv50_screen { struct nouveau_winsys *nvws; unsigned chipset; + + unsigned cur_pctx; + + struct nouveau_grobj *tesla; + struct nouveau_notifier *sync; }; static INLINE struct nv50_screen * diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 39cf675a57..4e294198b0 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -40,7 +40,7 @@ nv50_surface_copy(struct pipe_context *pipe, unsigned flip, unsigned width, unsigned height) { struct nv50_context *nv50 = (struct nv50_context *)pipe; - struct nouveau_winsys *nvws = nv50->nvws; + struct nouveau_winsys *nvws = nv50->screen->nvws; nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, width, height); @@ -52,7 +52,7 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, unsigned height, unsigned value) { struct nv50_context *nv50 = (struct nv50_context *)pipe; - struct nouveau_winsys *nvws = nv50->nvws; + struct nouveau_winsys *nvws = nv50->screen->nvws; nvws->surface_fill(nvws, dest, destx, desty, width, height, value); } -- cgit v1.2.3 From 3250bacd2411d3f1af50135599380b2140238535 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 02:56:10 +1100 Subject: nv50: create blend stateobj --- src/gallium/drivers/nv50/nv50_context.h | 15 ++++++++ src/gallium/drivers/nv50/nv50_screen.c | 10 ++++++ src/gallium/drivers/nv50/nv50_state.c | 62 ++++++++++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index e2656bd539..6096818d40 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -22,6 +22,13 @@ #define NOUVEAU_MSG(fmt, args...) \ fprintf(stderr, "nouveau: "fmt, ##args); +#define NV50_NEW_BLEND (1 << 0) + +struct nv50_blend_stateobj { + struct pipe_blend_state pipe; + struct nouveau_stateobj *so; +}; + struct nv50_context { struct pipe_context pipe; @@ -29,8 +36,16 @@ struct nv50_context { unsigned pctx_id; struct draw_context *draw; + + unsigned dirty; + struct nv50_blend_stateobj *blend; }; +static INLINE struct nv50_context * +nv50_context(struct pipe_context *pipe) +{ + return (struct nv50_context *)pipe; +} extern void nv50_init_miptree_functions(struct nv50_context *nv50); extern void nv50_init_surface_functions(struct nv50_context *nv50); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index f8fd11dc5f..62c23c790c 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -103,6 +103,7 @@ 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; + int i; if (!screen) return NULL; @@ -146,6 +147,15 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, 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->channel, 0); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 99dcab51b2..7a01100fd7 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -5,21 +5,81 @@ #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) { - return NULL; + 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 * -- cgit v1.2.3 From 9c29512154992f95c11939615ddcbef185c6a96c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 02:59:20 +1100 Subject: nv50: crappy state validate/emit function Just for testing stateobjs to make sure they don't hang the engine. --- src/gallium/drivers/nv50/Makefile | 1 + src/gallium/drivers/nv50/nv50_context.h | 2 ++ src/gallium/drivers/nv50/nv50_state_validate.c | 14 ++++++++++++++ src/gallium/drivers/nv50/nv50_vbo.c | 8 ++++++++ 4 files changed, 25 insertions(+) create mode 100644 src/gallium/drivers/nv50/nv50_state_validate.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index 1c0b82887a..a62a4d961b 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -11,6 +11,7 @@ DRIVER_SOURCES = \ nv50_query.c \ nv50_screen.c \ nv50_state.c \ + nv50_state_validate.c \ nv50_surface.c \ nv50_vbo.c diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 6096818d40..98b9aba079 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -70,4 +70,6 @@ extern boolean nv50_draw_elements(struct pipe_context *pipe, 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_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c new file mode 100644 index 0000000000..a89d1526c5 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -0,0 +1,14 @@ +#include "nv50_context.h" +#include "nouveau/nouveau_stateobj.h" + +boolean +nv50_state_validate(struct nv50_context *nv50) +{ + struct nouveau_winsys *nvws = nv50->screen->nvws; + + if (nv50->dirty & NV50_NEW_BLEND) + so_emit(nvws, nv50->blend->so); + + return TRUE; +} + diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 6c0dc23a43..b01ce1d42c 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -9,6 +9,10 @@ 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; } @@ -18,6 +22,10 @@ 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; } -- cgit v1.2.3 From 9911ca2226cf87e2cc4ffc32e40bccaf0a4e5745 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 03:21:48 +1100 Subject: nv50: ouch, next_subchannel++ :) --- src/gallium/winsys/dri/nouveau/nv50_surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index 5d74fb8d2b..5c6733e44a 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -155,7 +155,7 @@ nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) &nvc->Nv2D); if (ret) return ret; - BIND_RING (nvc->channel, nvc->Nv2D, 0); + 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); -- cgit v1.2.3 From 06bd7d78b979df66915b161157f2b6b1c09ad285 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 03:41:05 +1100 Subject: nv50: depth_stencil_alpha stateobj --- src/gallium/drivers/nv50/nv50_context.h | 9 +++- src/gallium/drivers/nv50/nv50_state.c | 70 +++++++++++++++++++++++++- src/gallium/drivers/nv50/nv50_state_validate.c | 3 ++ 3 files changed, 80 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 98b9aba079..9302764894 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -22,13 +22,19 @@ #define NOUVEAU_MSG(fmt, args...) \ fprintf(stderr, "nouveau: "fmt, ##args); -#define NV50_NEW_BLEND (1 << 0) +#define NV50_NEW_BLEND (1 << 0) +#define NV50_NEW_ZSA (1 << 1) 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_context { struct pipe_context pipe; @@ -39,6 +45,7 @@ struct nv50_context { unsigned dirty; struct nv50_blend_stateobj *blend; + struct nv50_zsa_stateobj *zsa; }; static INLINE struct nv50_context * diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 7a01100fd7..8fd4f774e2 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -127,17 +127,85 @@ static void * nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, const struct pipe_depth_stencil_alpha_state *cso) { - return NULL; + 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 * diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index a89d1526c5..786987c76a 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -8,7 +8,10 @@ nv50_state_validate(struct nv50_context *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); + nv50->dirty = 0; return TRUE; } -- cgit v1.2.3 From 2fee5f76483feb301546b24c26eea699732ffb57 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 03:54:53 +1100 Subject: nv50: scissor/viewport/blend colour/stipple --- src/gallium/drivers/nv50/nv50_context.h | 12 +++++-- src/gallium/drivers/nv50/nv50_state.c | 16 +++++++++ src/gallium/drivers/nv50/nv50_state_validate.c | 49 ++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 9302764894..406ad2ca63 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -22,8 +22,12 @@ #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 (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) struct nv50_blend_stateobj { struct pipe_blend_state pipe; @@ -46,6 +50,10 @@ struct nv50_context { unsigned dirty; struct nv50_blend_stateobj *blend; struct nv50_zsa_stateobj *zsa; + struct pipe_blend_color blend_colour; + struct pipe_poly_stipple stipple; + struct pipe_scissor_state scissor; + struct pipe_viewport_state viewport; }; static INLINE struct nv50_context * diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 8fd4f774e2..40e23f4609 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -246,6 +246,10 @@ 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 @@ -270,18 +274,30 @@ 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 diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 786987c76a..8920b6f49b 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -5,12 +5,61 @@ 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_BLEND) so_emit(nvws, nv50->blend->so); + if (nv50->dirty & NV50_NEW_ZSA) so_emit(nvws, nv50->zsa->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; } -- cgit v1.2.3 From cd85dc1e5dfa37cb9bee696e5e18332e3f1d65a1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 04:29:58 +1100 Subject: nv50: rasterizer stateobj --- src/gallium/drivers/nv50/nv50_context.h | 7 ++ src/gallium/drivers/nv50/nv50_state.c | 120 ++++++++++++++++++++++++- src/gallium/drivers/nv50/nv50_state_validate.c | 3 + 3 files changed, 129 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 406ad2ca63..d839cf701e 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -28,6 +28,7 @@ #define NV50_NEW_STIPPLE (1 << 3) #define NV50_NEW_SCISSOR (1 << 4) #define NV50_NEW_VIEWPORT (1 << 5) +#define NV50_NEW_RASTERIZER (1 << 6) struct nv50_blend_stateobj { struct pipe_blend_state pipe; @@ -39,6 +40,11 @@ struct nv50_zsa_stateobj { struct nouveau_stateobj *so; }; +struct nv50_rasterizer_stateobj { + struct pipe_rasterizer_state pipe; + struct nouveau_stateobj *so; +}; + struct nv50_context { struct pipe_context pipe; @@ -50,6 +56,7 @@ struct nv50_context { 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; diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 40e23f4609..088df9e675 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -110,17 +110,135 @@ static void * nv50_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { - return NULL; + 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); + unsigned i; + + /*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 * diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 8920b6f49b..8921bfaf88 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -15,6 +15,9 @@ nv50_state_validate(struct nv50_context *nv50) 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); -- cgit v1.2.3 From cd9ed05aec9d1d9614973165fd13647ba2e1b8c7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 12 Mar 2008 04:50:53 +1100 Subject: nv50: start on fb state --- src/gallium/drivers/nv50/nv50_context.h | 2 + src/gallium/drivers/nv50/nv50_state.c | 4 ++ src/gallium/drivers/nv50/nv50_state_validate.c | 93 ++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index d839cf701e..f532fa6bfb 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -29,6 +29,7 @@ #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; @@ -61,6 +62,7 @@ struct nv50_context { 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 * diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 088df9e675..aa65fd482e 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -386,6 +386,10 @@ 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 diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 8921bfaf88..68d419f9fc 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -1,6 +1,96 @@ #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) { @@ -9,6 +99,9 @@ nv50_state_validate(struct nv50_context *nv50) 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); -- cgit v1.2.3 From 169912b71a4242389301890ef303046d49ce71df Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 11 Mar 2008 19:22:02 +0100 Subject: nv30: silence some warnings --- src/gallium/drivers/nv30/nv30_fragprog.c | 2 +- src/gallium/drivers/nv30/nv30_state.c | 2 +- src/gallium/drivers/nv30/nv30_vbo.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 09ad555c32..0a2ba04f95 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -378,7 +378,7 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc, { const struct nv30_sreg none = nv30_sr(NV30SR_NONE, 0); struct nv30_sreg src[3], dst, tmp; - int mask, sat, unit; + int mask, sat, unit = 0; int ai = -1, ci = -1; int i; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index aa3fe7837e..319d53fcca 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -538,7 +538,7 @@ nv30_set_framebuffer_state(struct pipe_context *pipe, { struct nv30_context *nv30 = nv30_context(pipe); struct pipe_surface *rt[4], *zeta = NULL; - uint32_t rt_enable, rt_format, w, h; + uint32_t rt_enable, rt_format, w = 0, h = 0; int i, colour_format = 0, zeta_format = 0; rt_enable = 0; diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index 9e00cdac3f..a62462f7bc 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -102,7 +102,7 @@ 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; + int hw, num_hw = 0; nv30->vb_enable = 0; -- cgit v1.2.3 From 6bd5e5ce00b1870a8d94337cc10faa8134cbefd5 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Wed, 12 Mar 2008 18:40:37 +0100 Subject: nv30: line up the miptree creation to latest changes. --- src/gallium/drivers/nv30/nv30_miptree.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index 23bcef08eb..19945e9ab8 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -54,27 +54,29 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) nv30mt->total_size = offset; } -static void -nv30_miptree_create(struct pipe_screen *screen, struct pipe_texture **pt) +static struct pipe_texture * +nv30_miptree_create(struct pipe_screen *screen, struct pipe_texture *pt) { struct pipe_winsys *ws = screen->winsys; - struct nv30_miptree *nv30mt; + struct nv30_miptree *mt; - nv30mt = realloc(*pt, sizeof(struct nv30_miptree)); - if (!nv30mt) - return; - *pt = NULL; + mt = MALLOC(sizeof(struct nv30_miptree)); + if (!mt) + return NULL; + mt->base = *pt; + mt->base.refcount = 1; + mt->base.screen = screen; - nv30_miptree_layout(nv30mt); + nv30_miptree_layout(mt); - nv30mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, - nv30mt->total_size); - if (!nv30mt->buffer) { - free(nv30mt); - return; + mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + mt->total_size); + if (!mt->buffer) { + free(mt); + return NULL; } - *pt = &nv30mt->base; + return &mt->base; } static void -- cgit v1.2.3 From 830b4709f0ac27915450b53b622a8886264d8c8c Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Wed, 12 Mar 2008 18:43:29 +0100 Subject: nouveau: update to latest reg header. --- src/gallium/drivers/nouveau/nouveau_class.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index c80461038b..61c3d97fd4 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -1747,7 +1747,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV10TCL_DMA_NOTIFY 0x00000180 #define NV10TCL_DMA_IN_MEMORY0 0x00000184 #define NV10TCL_DMA_IN_MEMORY1 0x00000188 -#define NV10TCL_DISPLAY_LIST 0x0000018c +#define NV10TCL_DMA_VTXBUF0 0x0000018c #define NV10TCL_DMA_IN_MEMORY2 0x00000194 #define NV10TCL_DMA_IN_MEMORY3 0x00000198 #define NV10TCL_VIEWPORT_HORIZ 0x00000200 @@ -2866,11 +2866,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV10TCL_VERTEX_BEGIN_END_QUADS 0x00000008 #define NV10TCL_VERTEX_BEGIN_END_QUAD_STRIP 0x00000009 #define NV10TCL_VERTEX_BEGIN_END_POLYGON 0x0000000a -#define NV10TCL_DRAW_INDEX 0x00000e00 -#define NV10TCL_DRAW_INDEX_I0_SHIFT 0 -#define NV10TCL_DRAW_INDEX_I0_MASK 0x0000ffff -#define NV10TCL_DRAW_INDEX_I1_SHIFT 24 -#define NV10TCL_DRAW_INDEX_I1_MASK 0xff000000 +#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 24 +#define NV10TCL_VB_ELEMENT_U16_I1_MASK 0xff000000 #define NV10TCL_VERTEX_BUFFER_BEGIN_END 0x000013fc #define NV10TCL_VERTEX_BUFFER_BEGIN_END_STOP 0x00000000 #define NV10TCL_VERTEX_BUFFER_BEGIN_END_POINTS 0x00000001 @@ -4099,9 +4099,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV34TCL_VIEWPORT_SCALE_Y 0x00000a34 #define NV34TCL_VIEWPORT_SCALE_Z 0x00000a38 #define NV34TCL_VIEWPORT_SCALE_W 0x00000a3c -#define NV34TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000a60 +#define NV34TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000a60 #define NV34TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000a64 -#define NV34TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000a68 +#define NV34TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000a68 #define NV34TCL_DEPTH_FUNC 0x00000a6c #define NV34TCL_DEPTH_FUNC_NEVER 0x00000200 #define NV34TCL_DEPTH_FUNC_LESS 0x00000201 -- cgit v1.2.3 From 3b2a9b01a0c9b80573556a21e9db11b6f64eff8e Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 12 Mar 2008 19:06:22 +0100 Subject: nv30: debug dumps vp constants --- src/gallium/drivers/nv30/nv30_vertprog.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 96bc4b5ef9..75f7351261 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -751,6 +751,11 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) 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) { @@ -762,10 +767,9 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) 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]); + 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); -- cgit v1.2.3 From bd4fe0e87c1b979973d9a76aa48de5fbbb8d52b7 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 13 Mar 2008 00:42:50 +0100 Subject: nouveau: update to latest nouveau_class.h --- src/gallium/drivers/nouveau/nouveau_class.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index 61c3d97fd4..1b01550790 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -2869,8 +2869,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 24 -#define NV10TCL_VB_ELEMENT_U16_I1_MASK 0xff000000 +#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 -- cgit v1.2.3 From 9a4938d7033101122b627786273ff37229b5558a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 13 Mar 2008 12:36:35 +1100 Subject: nouveau: match interface changes --- src/gallium/drivers/nv30/nv30_fragprog.c | 11 ++++---- src/gallium/drivers/nv30/nv30_state.c | 30 +++++++++++--------- src/gallium/drivers/nv30/nv30_state.h | 4 +-- src/gallium/drivers/nv30/nv30_vertprog.c | 4 +-- src/gallium/drivers/nv40/nv40_context.h | 2 ++ src/gallium/drivers/nv40/nv40_fragprog.c | 11 ++++---- src/gallium/drivers/nv40/nv40_state.c | 47 +++++++++++++++++++++++--------- src/gallium/drivers/nv40/nv40_state.h | 4 +-- src/gallium/drivers/nv40/nv40_vertprog.c | 4 +-- src/gallium/drivers/nv50/nv50_state.c | 11 ++++---- 10 files changed, 76 insertions(+), 52 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 0a2ba04f95..6f61d36f4e 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -583,15 +583,14 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc, arith(fpc, sat, ADD, dst, mask, src[0], neg(src[1]), none); break; case TGSI_OPCODE_TEX: - if (finst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide == - TGSI_EXTSWIZZLE_W) { - tex(fpc, sat, TXP, unit, dst, mask, src[0], none, none); - } else - tex(fpc, sat, TEX, unit, dst, mask, src[0], none, none); + 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, @@ -683,7 +682,7 @@ nv30_fragprog_translate(struct nv30_context *nv30, fpc->high_temp = -1; fpc->num_regs = 2; - tgsi_parse_init(&parse, fp->pipe->tokens); + tgsi_parse_init(&parse, fp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&parse)) { tgsi_parse_token(&parse); diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 319d53fcca..951a32bc81 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -231,14 +231,15 @@ nv30_sampler_state_create(struct pipe_context *pipe, } static void -nv30_sampler_state_bind(struct pipe_context *pipe, unsigned unit, - void *hwcso) +nv30_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) { struct nv30_context *nv30 = nv30_context(pipe); - struct nv30_sampler_state *ps = hwcso; + unsigned unit; - nv30->tex_sampler[unit] = ps; - nv30->dirty_samplers |= (1 << unit); + for (unit = 0; unit < nr; unit++) { + nv30->tex_sampler[unit] = sampler[unit]; + nv30->dirty_samplers |= (1 << unit); + } } static void @@ -248,13 +249,16 @@ nv30_sampler_state_delete(struct pipe_context *pipe, void *hwcso) } static void -nv30_set_sampler_texture(struct pipe_context *pipe, unsigned unit, - struct pipe_texture *miptree) +nv30_set_sampler_texture(struct pipe_context *pipe, unsigned nr, + struct pipe_texture **miptree) { struct nv30_context *nv30 = nv30_context(pipe); + unsigned unit; - nv30->tex_miptree[unit] = (struct nv30_miptree *)miptree; - nv30->dirty_samplers |= (1 << unit); + for (unit = 0; unit < nr; unit++) { + nv30->tex_miptree[unit] = (struct nv30_miptree *)miptree[unit]; + nv30->dirty_samplers |= (1 << unit); + } } static void * @@ -440,7 +444,7 @@ nv30_vp_state_create(struct pipe_context *pipe, struct nv30_vertex_program *vp; vp = CALLOC(1, sizeof(struct nv30_vertex_program)); - vp->pipe = cso; + vp->pipe = *cso; return (void *)vp; } @@ -472,7 +476,7 @@ nv30_fp_state_create(struct pipe_context *pipe, struct nv30_fragment_program *fp; fp = CALLOC(1, sizeof(struct nv30_fragment_program)); - fp->pipe = cso; + fp->pipe = *cso; return (void *)fp; } @@ -709,9 +713,9 @@ nv30_init_state_functions(struct nv30_context *nv30) nv30->pipe.delete_blend_state = nv30_blend_state_delete; nv30->pipe.create_sampler_state = nv30_sampler_state_create; - nv30->pipe.bind_sampler_state = nv30_sampler_state_bind; + nv30->pipe.bind_sampler_states = nv30_sampler_state_bind; nv30->pipe.delete_sampler_state = nv30_sampler_state_delete; - nv30->pipe.set_sampler_texture = nv30_set_sampler_texture; + 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; diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h index 233600f69a..117520dd13 100644 --- a/src/gallium/drivers/nv30/nv30_state.h +++ b/src/gallium/drivers/nv30/nv30_state.h @@ -60,7 +60,7 @@ struct nv30_vertex_program_data { }; struct nv30_vertex_program { - const struct pipe_shader_state *pipe; + struct pipe_shader_state pipe; boolean translated; struct nv30_vertex_program_exec *insns; @@ -84,7 +84,7 @@ struct nv30_fragment_program_data { }; struct nv30_fragment_program { - const struct pipe_shader_state *pipe; + struct pipe_shader_state pipe; boolean translated; boolean on_hw; diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 75f7351261..e9b62ff48b 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -541,7 +541,7 @@ nv30_vertprog_prepare(struct nv30_vpc *vpc) struct tgsi_parse_context p; int nr_imm = 0; - tgsi_parse_init(&p, vpc->vp->pipe->tokens); + tgsi_parse_init(&p, vpc->vp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&p)) { const union tgsi_full_token *tok = &p.FullToken; @@ -582,7 +582,7 @@ nv30_vertprog_translate(struct nv30_context *nv30, return; } - tgsi_parse_init(&parse, vp->pipe->tokens); + tgsi_parse_init(&parse, vp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&parse)) { tgsi_parse_token(&parse); diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index e118776306..100c678187 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -136,6 +136,8 @@ struct nv40_context { 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_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index d981a02a63..953f9cd908 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -580,15 +580,14 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, arith(fpc, sat, ADD, dst, mask, src[0], neg(src[1]), none); break; case TGSI_OPCODE_TEX: - if (finst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide == - TGSI_EXTSWIZZLE_W) { - tex(fpc, sat, TXP, unit, dst, mask, src[0], none, none); - } else - tex(fpc, sat, TEX, unit, dst, mask, src[0], none, none); + 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, @@ -680,7 +679,7 @@ nv40_fragprog_translate(struct nv40_context *nv40, fpc->high_temp = -1; fpc->num_regs = 2; - tgsi_parse_init(&parse, fp->pipe->tokens); + tgsi_parse_init(&parse, fp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&parse)) { tgsi_parse_token(&parse); diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index caa2f9df0c..321d5de041 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -1,6 +1,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "nv40_context.h" #include "nv40_state.h" @@ -251,14 +252,22 @@ nv40_sampler_state_create(struct pipe_context *pipe, } static void -nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit, - void *hwcso) +nv40_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_sampler_state *ps = hwcso; + unsigned unit; - nv40->tex_sampler[unit] = ps; - nv40->dirty_samplers |= (1 << 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; } @@ -269,13 +278,25 @@ nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso) } static void -nv40_set_sampler_texture(struct pipe_context *pipe, unsigned unit, - struct pipe_texture *miptree) +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->tex_miptree[unit] = (struct nv40_miptree *)miptree; - nv40->dirty_samplers |= (1 << unit); + nv40->nr_textures = nr; nv40->dirty |= NV40_NEW_SAMPLER; } @@ -490,7 +511,7 @@ nv40_vp_state_create(struct pipe_context *pipe, struct nv40_vertex_program *vp; vp = CALLOC(1, sizeof(struct nv40_vertex_program)); - vp->pipe = cso; + vp->pipe = *cso; return (void *)vp; } @@ -521,7 +542,7 @@ nv40_fp_state_create(struct pipe_context *pipe, struct nv40_fragment_program *fp; fp = CALLOC(1, sizeof(struct nv40_fragment_program)); - fp->pipe = cso; + fp->pipe = *cso; return (void *)fp; } @@ -649,9 +670,9 @@ nv40_init_state_functions(struct nv40_context *nv40) nv40->pipe.delete_blend_state = nv40_blend_state_delete; nv40->pipe.create_sampler_state = nv40_sampler_state_create; - nv40->pipe.bind_sampler_state = nv40_sampler_state_bind; + nv40->pipe.bind_sampler_states = nv40_sampler_state_bind; nv40->pipe.delete_sampler_state = nv40_sampler_state_delete; - nv40->pipe.set_sampler_texture = nv40_set_sampler_texture; + 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; diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index e5217fe91c..a02ea0c878 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -23,7 +23,7 @@ struct nv40_vertex_program_data { }; struct nv40_vertex_program { - const struct pipe_shader_state *pipe; + struct pipe_shader_state pipe; boolean translated; struct nv40_vertex_program_exec *insns; @@ -48,7 +48,7 @@ struct nv40_fragment_program_data { }; struct nv40_fragment_program { - const struct pipe_shader_state *pipe; + struct pipe_shader_state pipe; boolean translated; unsigned samplers; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 5b7a343e55..3d730c1a32 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -535,7 +535,7 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) struct tgsi_parse_context p; int nr_imm = 0; - tgsi_parse_init(&p, vpc->vp->pipe->tokens); + tgsi_parse_init(&p, vpc->vp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&p)) { const union tgsi_full_token *tok = &p.FullToken; @@ -576,7 +576,7 @@ nv40_vertprog_translate(struct nv40_context *nv40, return; } - tgsi_parse_init(&parse, vp->pipe->tokens); + tgsi_parse_init(&parse, vp->pipe.tokens); while (!tgsi_parse_end_of_tokens(&parse)) { tgsi_parse_token(&parse); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index aa65fd482e..b096a2583d 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -90,8 +90,7 @@ nv50_sampler_state_create(struct pipe_context *pipe, } static void -nv50_sampler_state_bind(struct pipe_context *pipe, unsigned unit, - void *hwcso) +nv50_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) { } @@ -101,8 +100,8 @@ nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso) } static void -nv50_set_sampler_texture(struct pipe_context *pipe, unsigned unit, - struct pipe_texture *pt) +nv50_set_sampler_texture(struct pipe_context *pipe, unsigned nr, + struct pipe_texture **pt) { } @@ -442,9 +441,9 @@ nv50_init_state_functions(struct nv50_context *nv50) nv50->pipe.delete_blend_state = nv50_blend_state_delete; nv50->pipe.create_sampler_state = nv50_sampler_state_create; - nv50->pipe.bind_sampler_state = nv50_sampler_state_bind; + nv50->pipe.bind_sampler_states = nv50_sampler_state_bind; nv50->pipe.delete_sampler_state = nv50_sampler_state_delete; - nv50->pipe.set_sampler_texture = nv50_set_sampler_texture; + 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; -- cgit v1.2.3 From 1cec61e441ad5b4b1ac8d1abcaa7535bc1827eb3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 13 Mar 2008 18:08:22 +1100 Subject: nouveau: NV9X is basically a G80, fix issue with NV6X being detected as G80. --- src/gallium/drivers/nv50/nv50_screen.c | 29 +++++++++++----- src/gallium/winsys/dri/nouveau/nouveau_context.c | 42 ++++++++++++++++++++---- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 1 + 3 files changed, 57 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 62c23c790c..721c6421d1 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -6,8 +6,9 @@ #include "nouveau/nouveau_stateobj.h" -#define GRCLASS5097_CHIPSETS 0x00000000 -#define GRCLASS8297_CHIPSETS 0x00000010 +#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, @@ -117,12 +118,24 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, return NULL; } - if (GRCLASS5097_CHIPSETS & (1 << (chipset & 0x0f))) { - tesla_class = 0x5097; - } else - if (GRCLASS8297_CHIPSETS & (1 << (chipset & 0x0f))) { - tesla_class = 0x8297; - } else { + 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; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 8dac08a5d2..8b20b3689c 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -75,6 +75,7 @@ nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) switch (chipset & 0xf0) { case 0x50: case 0x80: + case 0x90: ret = nouveau_surface_channel_create_nv50(nvc); break; default: @@ -109,6 +110,7 @@ nouveau_context_create(const __GLcontextModes *glVis, st_share = ((struct nouveau_context *)sharedContextPrivate)->st; } + /* Check for supported arch */ if ((ret = nouveau_device_get_param(nv_screen->device, NOUVEAU_GETPARAM_CHIPSET_ID, &nv->chipset))) { @@ -116,6 +118,22 @@ nouveau_context_create(const __GLcontextModes *glVis, return GL_FALSE; } + switch (nv->chipset & 0xf0) { + case 0x30: + /* NV30 */ + case 0x40: + case 0x60: + /* NV40 */ + case 0x50: + case 0x80: + case 0x90: + /* G80 */ + break; + default: + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", nv->chipset); + return GL_FALSE; + } + driContextPriv->driverPrivate = (void *)nv; nv->nv_screen = nv_screen; nv->dri_screen = driScrnPriv; @@ -176,10 +194,15 @@ nouveau_context_create(const __GLcontextModes *glVis, } } - /*XXX: temporary - disable multi-context/single-channel on non-NV4x */ + /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */ switch (nv->chipset & 0xf0) { case 0x40: case 0x60: + /* NV40 class */ + case 0x50: + case 0x80: + case 0x90: + /* G80 class */ break; default: nvc = NULL; @@ -215,12 +238,17 @@ nouveau_context_create(const __GLcontextModes *glVis, } /* Create pipe */ - if (nv->chipset < 0x50) - ret = nouveau_surface_init_nv04(nv); - else - ret = nouveau_surface_init_nv50(nv); - if (ret) { - return GL_FALSE; + switch (nv->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")) { diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index dc7c4c3d71..64e84fb68e 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -93,6 +93,7 @@ nouveau_pipe_create(struct nouveau_context *nv) break; case 0x50: case 0x80: + case 0x90: hws_create = nv50_screen_create; hw_create = nv50_create; break; -- cgit v1.2.3 From 9a3320e0791a4a03f5f4b7a6f9c3b0d9d78655b3 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 15 Mar 2008 04:42:48 +0100 Subject: nv30: only 2 RTs. --- src/gallium/drivers/nv30/nv30_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 951a32bc81..722626db1f 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -546,7 +546,7 @@ nv30_set_framebuffer_state(struct pipe_context *pipe, int i, colour_format = 0, zeta_format = 0; rt_enable = 0; - for (i = 0; i < 4; i++) { + for (i = 0; i < 2; i++) { if (!fb->cbufs[i]) continue; -- cgit v1.2.3 From 509044609d5121b2a09d64bd24d7aa37e3744a77 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 15 Mar 2008 04:43:12 +0100 Subject: nouveau: latest header. --- src/gallium/drivers/nouveau/nouveau_class.h | 44 ++++++++++++++++++----------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index 1b01550790..7392490df0 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -1750,22 +1750,34 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV10TCL_DMA_VTXBUF0 0x0000018c #define NV10TCL_DMA_IN_MEMORY2 0x00000194 #define NV10TCL_DMA_IN_MEMORY3 0x00000198 -#define NV10TCL_VIEWPORT_HORIZ 0x00000200 -#define NV10TCL_VIEWPORT_HORIZ_X_SHIFT 0 -#define NV10TCL_VIEWPORT_HORIZ_X_MASK 0x0000ffff -#define NV10TCL_VIEWPORT_HORIZ_W_SHIFT 16 -#define NV10TCL_VIEWPORT_HORIZ_W_MASK 0xffff0000 -#define NV10TCL_VIEWPORT_VERT 0x00000204 -#define NV10TCL_VIEWPORT_VERT_Y_SHIFT 0 -#define NV10TCL_VIEWPORT_VERT_Y_MASK 0x0000ffff -#define NV10TCL_VIEWPORT_VERT_H_SHIFT 16 -#define NV10TCL_VIEWPORT_VERT_H_MASK 0xffff0000 -#define NV10TCL_BUFFER_FORMAT 0x00000208 -#define NV10TCL_BUFFER_PITCH 0x0000020c -#define NV10TCL_BUFFER_PITCH_COLOR_PITCH_SHIFT 0 -#define NV10TCL_BUFFER_PITCH_COLOR_PITCH_MASK 0x0000ffff -#define NV10TCL_BUFFER_PITCH_ZETA_PITCH_SHIFT 16 -#define NV10TCL_BUFFER_PITCH_ZETA_PITCH_MASK 0xffff0000 +#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)) -- cgit v1.2.3 From d493203045b214770473f8afeaa610542fe42c2a Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 15 Mar 2008 05:37:57 +0100 Subject: nv10. --- configs/default | 2 +- configs/linux-dri | 2 +- src/gallium/drivers/nouveau/nouveau_winsys.h | 7 + src/gallium/drivers/nv10/Makefile | 28 + src/gallium/drivers/nv10/nv10_clear.c | 12 + src/gallium/drivers/nv10/nv10_context.c | 325 +++++++++++ src/gallium/drivers/nv10/nv10_context.h | 127 +++++ src/gallium/drivers/nv10/nv10_fragprog.c | 22 + src/gallium/drivers/nv10/nv10_fragtex.c | 145 +++++ src/gallium/drivers/nv10/nv10_miptree.c | 134 +++++ src/gallium/drivers/nv10/nv10_prim_vbuf.c | 224 ++++++++ src/gallium/drivers/nv10/nv10_screen.c | 150 +++++ src/gallium/drivers/nv10/nv10_screen.h | 19 + src/gallium/drivers/nv10/nv10_state.c | 697 +++++++++++++++++++++++ src/gallium/drivers/nv10/nv10_state.h | 135 +++++ src/gallium/drivers/nv10/nv10_state_emit.c | 69 +++ src/gallium/drivers/nv10/nv10_surface.c | 65 +++ src/gallium/drivers/nv10/nv10_vbo.c | 72 +++ src/gallium/winsys/dri/nouveau/Makefile | 1 + src/gallium/winsys/dri/nouveau/nouveau_context.c | 3 + src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 5 + 21 files changed, 2242 insertions(+), 2 deletions(-) create mode 100644 src/gallium/drivers/nv10/Makefile create mode 100644 src/gallium/drivers/nv10/nv10_clear.c create mode 100644 src/gallium/drivers/nv10/nv10_context.c create mode 100644 src/gallium/drivers/nv10/nv10_context.h create mode 100644 src/gallium/drivers/nv10/nv10_fragprog.c create mode 100644 src/gallium/drivers/nv10/nv10_fragtex.c create mode 100644 src/gallium/drivers/nv10/nv10_miptree.c create mode 100644 src/gallium/drivers/nv10/nv10_prim_vbuf.c create mode 100644 src/gallium/drivers/nv10/nv10_screen.c create mode 100644 src/gallium/drivers/nv10/nv10_screen.h create mode 100644 src/gallium/drivers/nv10/nv10_state.c create mode 100644 src/gallium/drivers/nv10/nv10_state.h create mode 100644 src/gallium/drivers/nv10/nv10_state_emit.c create mode 100644 src/gallium/drivers/nv10/nv10_surface.c create mode 100644 src/gallium/drivers/nv10/nv10_vbo.c (limited to 'src/gallium') diff --git a/configs/default b/configs/default index 49d3737ec7..d010721a10 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 rtasm util sct GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) -GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv30 nv40 nv50 failover +GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv10 nv30 nv40 nv50 failover GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = xlib diff --git a/configs/linux-dri b/configs/linux-dri index 67e60cbd4c..bf7881937e 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -65,4 +65,4 @@ GALLIUM_WINSYS_DIRS = dri # 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/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 44c8bb919b..e4b20478a0 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -49,6 +49,13 @@ struct nouveau_winsys { unsigned, unsigned, unsigned, unsigned, unsigned); }; +extern struct pipe_screen * +nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, + unsigned chipset); + +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 *, unsigned chipset); diff --git a/src/gallium/drivers/nv10/Makefile b/src/gallium/drivers/nv10/Makefile new file mode 100644 index 0000000000..4ba7ce586d --- /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 0000000000..be7e09cf4b --- /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 0000000000..2599acf286 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -0,0 +1,325 @@ +#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 nv10_context *nv10 = nv10_context(pipe); + struct nouveau_winsys *nvws = nv10->nvws; + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(celsius, 0x1fd8, 1); + OUT_RING (2); + BEGIN_RING(celsius, 0x1fd8, 1); + OUT_RING (1); + } + + if (flags & PIPE_FLUSH_WAIT) { + nvws->notifier_reset(nv10->sync, 0); + BEGIN_RING(celsius, 0x104, 1); + OUT_RING (0); + BEGIN_RING(celsius, 0x100, 1); + OUT_RING (0); + } + + FIRE_RING(); + + if (flags & PIPE_FLUSH_WAIT) + nvws->notifier_wait(nv10->sync, 0, 0, 2000); +} + +static void +nv10_destroy(struct pipe_context *pipe) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nouveau_winsys *nvws = nv10->nvws; + + if (nv10->draw) + draw_destroy(nv10->draw); + + nvws->res_free(&nv10->vertprog.exec_heap); + nvws->res_free(&nv10->vertprog.data_heap); + + nvws->notifier_free(&nv10->sync); + + nvws->grobj_free(&nv10->celsius); + + free(nv10); +} + +static boolean +nv10_init_hwctx(struct nv10_context *nv10, int celsius_class) +{ + struct nouveau_winsys *nvws = nv10->nvws; + int ret; + int i; + + ret = nvws->grobj_alloc(nvws, celsius_class, &nv10->celsius); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return FALSE; + } + + BEGIN_RING(celsius, NV10TCL_DMA_NOTIFY, 1); + OUT_RING (nv10->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 (celsius_class != 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_OUT_ALPHA(0), 6); + OUT_RING (0x00000c00); + OUT_RING (0); + OUT_RING (0x00000c00); + OUT_RING (0x18000000); + OUT_RING (0x300c0000); + OUT_RING (0x00001c80); + 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); + + + FIRE_RING (); + return TRUE; +} + +struct pipe_context * +nv10_create(struct pipe_screen *screen, unsigned pctx_id) +{ + struct pipe_winsys *pipe_winsys = screen->winsys; + struct nouveau_winsys *nvws = nv10_screen(screen)->nvws; + unsigned chipset = nv10_screen(screen)->chipset; + struct nv10_context *nv10; + int celsius_class = 0, ret; + + if (chipset>=0x20) + celsius_class=NV11TCL; + else if (chipset>=0x17) + celsius_class=NV17TCL; + else if (chipset>=0x11) + celsius_class=NV11TCL; + else + celsius_class=NV10TCL; + + nv10 = CALLOC_STRUCT(nv10_context); + if (!nv10) + return NULL; + nv10->chipset = chipset; + nv10->nvws = nvws; + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &nv10->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv10_destroy(&nv10->pipe); + return NULL; + } + + /* Vtxprog resources */ + if (nvws->res_init(&nv10->vertprog.exec_heap, 0, 512) || + nvws->res_init(&nv10->vertprog.data_heap, 0, 256)) { + nv10_destroy(&nv10->pipe); + return NULL; + } + + /* Static celsius initialisation */ + if (!nv10_init_hwctx(nv10, celsius_class)) { + nv10_destroy(&nv10->pipe); + return NULL; + } + + /* Pipe context setup */ + nv10->pipe.winsys = pipe_winsys; + + nv10->pipe.destroy = nv10_destroy; + + 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)); + + 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 0000000000..8269d6121f --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -0,0 +1,127 @@ +#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_context *ctx = nv10 +#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 << 1) +#define NV10_NEW_FRAGPROG (1 << 2) +#define NV10_NEW_ARRAYS (1 << 3) +#define NV10_NEW_VBO (1 << 4) + +struct nv10_context { + struct pipe_context pipe; + struct nouveau_winsys *nvws; + + struct draw_context *draw; + + int chipset; + struct nouveau_grobj *celsius; + struct nouveau_notifier *sync; + + 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; + + struct { + struct pipe_buffer *buffer; + uint32_t format; + } tex[16]; + + unsigned vb_enable; + struct { + struct pipe_buffer *buffer; + unsigned delta; + } vb[16]; + + struct vertex_info vertex_info; + struct { + + struct nouveau_resource *exec_heap; + struct nouveau_resource *data_heap; + + struct nv10_vertex_program *active; + + struct nv10_vertex_program *current; + struct pipe_buffer *constant_buf; + } vertprog; + + struct { + struct nv10_fragment_program *active; + + struct nv10_fragment_program *current; + struct pipe_buffer *constant_buf; + } fragprog; + + struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; +}; + +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_init_miptree_functions(struct pipe_screen *screen); + +/* 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 ); + +/* 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 0000000000..2a63c8a704 --- /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 0000000000..a4bf108284 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_fragtex.c @@ -0,0 +1,145 @@ +#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), + _(U_L8 , L8 ), + _(U_A8 , A8 ), + _(U_A8_L8 , 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) +{ + 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); +} + +void +nv10_fragtex_bind(struct nv10_context *nv10) +{ + 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; +} + diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c new file mode 100644 index 0000000000..7b7f39b80c --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -0,0 +1,134 @@ +#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, 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 struct pipe_surface * +nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + 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; +} +void +nv10_init_miptree_functions(struct pipe_screen *screen) +{ + struct nv10_screen *nv10screen = nv10_screen(screen); + + nv10screen->screen.texture_create = nv10_miptree_create; + nv10screen->screen.texture_release = nv10_miptree_release; + nv10screen->screen.get_tex_surface = nv10_miptree_surface_get; +} + 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 0000000000..1526891223 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c @@ -0,0 +1,224 @@ +/************************************************************************** + * + * 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 + * \author Keith Whitwell + */ + + +#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; +}; + + +/** + * 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; + 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_VBO; + + 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; + + 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 ? + push = MIN2(nr_indices, 2047 * 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 = 1024*1024; + nv10_render->base.max_indices = 64*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 0000000000..4d8e0b05cc --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -0,0 +1,150 @@ +#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); + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", nv10screen->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; + 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; + case PIPE_CAP_BITMAP_TEXCOORD_BIAS: + return 0.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_U_L8: + case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_U_I8: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static void +nv10_screen_destroy(struct pipe_screen *screen) +{ + FREE(screen); +} + +struct pipe_screen * +nv10_screen_create(struct pipe_winsys *winsys, struct nouveau_winsys *nvws, + unsigned chipset) +{ + struct nv10_screen *nv10screen = CALLOC_STRUCT(nv10_screen); + + if (!nv10screen) + return NULL; + + nv10screen->chipset = chipset; + nv10screen->nvws = nvws; + + nv10screen->screen.winsys = winsys; + + nv10screen->screen.destroy = nv10_screen_destroy; + + nv10screen->screen.get_name = nv10_screen_get_name; + nv10screen->screen.get_vendor = nv10_screen_get_vendor; + nv10screen->screen.get_param = nv10_screen_get_param; + nv10screen->screen.get_paramf = nv10_screen_get_paramf; + nv10screen->screen.is_format_supported = + nv10_screen_is_format_supported; + + nv10_init_miptree_functions(&nv10screen->screen); + return &nv10screen->screen; +} + diff --git a/src/gallium/drivers/nv10/nv10_screen.h b/src/gallium/drivers/nv10/nv10_screen.h new file mode 100644 index 0000000000..ac8c04072a --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_screen.h @@ -0,0 +1,19 @@ +#ifndef __NV10_SCREEN_H__ +#define __NV10_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv10_screen { + struct pipe_screen screen; + + struct nouveau_winsys *nvws; + unsigned chipset; +}; + +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 0000000000..313230fe88 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -0,0 +1,697 @@ +#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_vertex_layout(struct pipe_context* pipe) +{ + struct nv10_context *nv10 = nv10_context(pipe); + const struct pipe_shader_state *fs = nv10->fragprog.current->pipe; + uint32_t src = 0; + int i; + struct vertex_info vinfo; + + memset(&vinfo, 0, sizeof(vinfo)); + + for (i = 0; i < fs->num_inputs; i++) { + switch (fs->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); +} + +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 *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_blend_state *cb = hwcso; + + BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 1); + OUT_RING (cb->d_enable); + + BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 3); + OUT_RING (cb->b_enable); + OUT_RING (cb->b_srcfunc); + OUT_RING (cb->b_dstfunc); + + BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING (cb->c_mask); +} + +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->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 *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_rasterizer_state *rs = hwcso; + + BEGIN_RING(celsius, NV10TCL_SHADE_MODEL, 2); + OUT_RING (rs->shade_model); + OUT_RING (rs->line_width); + + + BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING (rs->point_size); + + BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING (rs->poly_mode_front); + OUT_RING (rs->poly_mode_back); + + + BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); + OUT_RING (rs->cull_face); + OUT_RING (rs->front_face); + + BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2); + OUT_RING (rs->line_smooth_en); + OUT_RING (rs->poly_smooth_en); + + BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING (rs->cull_face_en); + +/* BEGIN_RING(celsius, NV10TCL_POINT_SPRITE, 1); + OUT_RING (rs->point_sprite);*/ +} + +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 *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_depth_stencil_alpha_state *hw = hwcso; + + BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 3); + OUT_RINGp ((uint32_t *)&hw->depth, 3); + BEGIN_RING(celsius, NV10TCL_STENCIL_ENABLE, 1); + OUT_RING (hw->stencil.enable); + BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 7); + OUT_RINGp ((uint32_t *)&(hw->stencil.wmask), 7); + BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 3); + OUT_RINGp ((uint32_t *)&hw->alpha.enabled, 3); +} + +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 *cso) +{ + struct nv10_vertex_program *vp; + + vp = CALLOC(1, sizeof(struct nv10_vertex_program)); + vp->pipe = cso; + + return (void *)vp; +} + +static void +nv10_vp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_vertex_program *vp = hwcso; + + nv10->vertprog.current = vp; + nv10->dirty |= NV10_NEW_VERTPROG; +} + +static void +nv10_vp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_vertex_program *vp = hwcso; + + //nv10_vertprog_destroy(nv10, vp); + free(vp); +} + +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; + + 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); + + BEGIN_RING(celsius, NV10TCL_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 +nv10_set_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *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); + + if (shader == PIPE_SHADER_VERTEX) { + nv10->vertprog.constant_buf = buf->buffer; + nv10->dirty |= NV10_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nv10->fragprog.constant_buf = buf->buffer; + nv10->dirty |= NV10_NEW_FRAGPROG; + } +} + +static void +nv10_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct pipe_surface *rt, *zeta; + uint32_t rt_format, w, h; + int i, 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); + } + + BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); + OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->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); + OUT_RING (((h - 1) << 16) | 0); +} + +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); + + // XXX +/* 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_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *vpt) +{ + struct nv10_context *nv10 = nv10_context(pipe); + +/* OUT_RINGf (vpt->translate[0]); + OUT_RINGf (vpt->translate[1]); + OUT_RINGf (vpt->translate[2]); + OUT_RINGf (vpt->translate[3]);*/ + BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4); + OUT_RINGf (vpt->scale[0]); + OUT_RINGf (vpt->scale[1]); + OUT_RINGf (vpt->scale[2]); + OUT_RINGf (vpt->scale[3]); +} + +static void +nv10_set_vertex_buffer(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_buffer *vb) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->vtxbuf[index] = *vb; + + nv10->dirty |= NV10_NEW_ARRAYS; +} + +static void +nv10_set_vertex_element(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_element *ve) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->vtxelt[index] = *ve; + + nv10->dirty |= NV10_NEW_ARRAYS; +} + +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_buffer = nv10_set_vertex_buffer; + nv10->pipe.set_vertex_element = nv10_set_vertex_element; +} + diff --git a/src/gallium/drivers/nv10/nv10_state.h b/src/gallium/drivers/nv10/nv10_state.h new file mode 100644 index 0000000000..d4b703c7ad --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_state.h @@ -0,0 +1,135 @@ +#ifndef __NV10_STATE_H__ +#define __NV10_STATE_H__ + +#include "pipe/p_state.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; +}; + +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; + + 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 0000000000..1d104e2f91 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -0,0 +1,69 @@ +#include "nv10_context.h" +#include "nv10_state.h" + +void +nv10_emit_hw_state(struct nv10_context *nv10) +{ + int i; + + if (nv10->dirty & NV10_NEW_FRAGPROG) { + nv10_fragprog_bind(nv10, nv10->fragprog.current); + /*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */ + } + + if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) { + nv10_fragtex_bind(nv10); + nv10->dirty &= ~NV10_NEW_FRAGPROG; + } + + if (nv10->dirty & NV10_NEW_VERTPROG) { + //nv10_vertprog_bind(nv10, nv10->vertprog.current); + nv10->dirty &= ~NV10_NEW_VERTPROG; + } + + if (nv10->dirty & NV10_NEW_VBO) { + + } + + nv10->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 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_OFFSET, 1); + OUT_RELOCl(nv10->zeta+...);*/ + } + + /* Texture images */ + for (i = 0; i < 2; i++) { + if (!(nv10->fp_samplers & (1 << i))) + continue; + BEGIN_RING(celsius, NV10TCL_TX_OFFSET(i), 2); + OUT_RELOCl(nv10->tex[i].buffer, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + // XXX +/* 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 0000000000..2e230ebbec --- /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 0000000000..025ad6de4b --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_vbo.c @@ -0,0 +1,72 @@ +#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; + + /* + * Map vertex buffers + */ + for (i = 0; i < PIPE_ATTRIB_MAX; 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! */ + draw_arrays(nv10->draw, prim, start, count); + + /* + * unmap vertex/index buffers + */ + for (i = 0; i < PIPE_ATTRIB_MAX; 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/winsys/dri/nouveau/Makefile b/src/gallium/winsys/dri/nouveau/Makefile index b463f218fd..f637b2cebf 100644 --- a/src/gallium/winsys/dri/nouveau/Makefile +++ b/src/gallium/winsys/dri/nouveau/Makefile @@ -8,6 +8,7 @@ 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 diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 8b20b3689c..336dd65847 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -119,6 +119,9 @@ nouveau_context_create(const __GLcontextModes *glVis, } switch (nv->chipset & 0xf0) { + case 0x10: + case 0x20: + /* NV10 */ case 0x30: /* NV30 */ case 0x40: diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 64e84fb68e..6c85aab9f5 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -82,6 +82,11 @@ nouveau_pipe_create(struct nouveau_context *nv) return NULL; switch (nv->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; -- cgit v1.2.3 From 5e17088ee3d0ddfa8871d92d262bb5242bdd92bd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 15 Mar 2008 16:45:49 +0100 Subject: cso_context_destroy calls bind_state functions with NULL parameter --- src/gallium/drivers/nv30/nv30_state.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 722626db1f..80dfd9c5c0 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -40,6 +40,10 @@ 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); @@ -236,6 +240,10 @@ 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); @@ -346,6 +354,10 @@ 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); @@ -422,6 +434,10 @@ 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); @@ -455,6 +471,10 @@ 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; } @@ -487,6 +507,10 @@ 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; } -- cgit v1.2.3 From 7d2c63e90983088f1e2f49543caf0468aa91111f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 16 Mar 2008 12:55:02 +1100 Subject: nv10: fix build after merge --- src/gallium/drivers/nv10/nv10_state.c | 8 +++++--- src/gallium/drivers/nv10/nv10_state.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 313230fe88..d7c445f1b3 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -10,15 +10,15 @@ static void nv10_vertex_layout(struct pipe_context* pipe) { struct nv10_context *nv10 = nv10_context(pipe); - const struct pipe_shader_state *fs = nv10->fragprog.current->pipe; + 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 < fs->num_inputs; i++) { - switch (fs->input_semantic_name[i]) { + 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; @@ -476,6 +476,8 @@ nv10_fp_state_create(struct pipe_context *pipe, fp = CALLOC(1, sizeof(struct nv10_fragment_program)); fp->pipe = cso; + + tgsi_scan_shader(cso->tokens, &fp->info); return (void *)fp; } diff --git a/src/gallium/drivers/nv10/nv10_state.h b/src/gallium/drivers/nv10/nv10_state.h index d4b703c7ad..9bda8a7d6a 100644 --- a/src/gallium/drivers/nv10/nv10_state.h +++ b/src/gallium/drivers/nv10/nv10_state.h @@ -2,6 +2,7 @@ #define __NV10_STATE_H__ #include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" struct nv10_blend_state { uint32_t b_enable; @@ -77,6 +78,7 @@ struct nv10_fragment_program_data { struct nv10_fragment_program { const struct pipe_shader_state *pipe; + struct tgsi_shader_info info; boolean translated; boolean on_hw; -- cgit v1.2.3 From e1cf3f00e546f814effd25e9ccd072c941366444 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 13 Mar 2008 18:29:56 +1100 Subject: nv40: simple swtnl path (half broken, but getting there) --- src/gallium/drivers/nv40/nv40_context.c | 6 +- src/gallium/drivers/nv40/nv40_context.h | 25 +- src/gallium/drivers/nv40/nv40_draw.c | 334 +++++++++++++++++++++++-- src/gallium/drivers/nv40/nv40_fragprog.c | 3 +- src/gallium/drivers/nv40/nv40_shader.h | 2 + src/gallium/drivers/nv40/nv40_state.c | 27 +- src/gallium/drivers/nv40/nv40_state.h | 4 + src/gallium/drivers/nv40/nv40_state_clip.c | 8 +- src/gallium/drivers/nv40/nv40_state_emit.c | 130 +++++++--- src/gallium/drivers/nv40/nv40_state_viewport.c | 45 +++- src/gallium/drivers/nv40/nv40_vbo.c | 22 +- src/gallium/drivers/nv40/nv40_vertprog.c | 16 +- 12 files changed, 531 insertions(+), 91 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 203c843a01..58627443b8 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -74,8 +74,12 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40_init_state_functions(nv40); nv40_init_miptree_functions(nv40); + /* Create, configure, and install fallback swtnl path */ nv40->draw = draw_create(); - assert(nv40->draw); + 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 index 100c678187..02ca20b801 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -116,7 +116,20 @@ struct nv40_context { /* HW state derived from pipe states */ struct nv40_state state; - unsigned fallback; + 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; @@ -166,6 +179,10 @@ 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 *, @@ -179,8 +196,9 @@ extern void nv40_fragprog_destroy(struct nv40_context *, extern void nv40_fragtex_bind(struct nv40_context *); /* nv40_state.c and friends */ -extern void nv40_emit_hw_state(struct nv40_context *nv40); -extern void nv40_state_tex_update(struct nv40_context *nv40); +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_clip; extern struct nv40_state_entry nv40_state_rasterizer; extern struct nv40_state_entry nv40_state_scissor; @@ -194,6 +212,7 @@ 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, diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index a39bb85e99..ce0e0bc6f2 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -1,62 +1,350 @@ -#include "draw/draw_private.h" #include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#include "draw/draw_context.h" +#include "draw/draw_vertex.h" +#include "draw/draw_private.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_draw_stage { - struct draw_stage draw; +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, 0x1e40 + (hw * 4), 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, 0x1940 + (hw * 4), 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(); + 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_draw_point(struct draw_stage *draw, struct prim_header *prim) +nv40_render_point(struct draw_stage *draw, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_POINTS, 1); } static void -nv40_draw_line(struct draw_stage *draw, struct prim_header *prim) +nv40_render_line(struct draw_stage *draw, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_LINES, 2); } static void -nv40_draw_tri(struct draw_stage *draw, struct prim_header *prim) +nv40_render_tri(struct draw_stage *draw, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_TRIANGLES, 3); } static void -nv40_draw_flush(struct draw_stage *draw, unsigned flags) +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_draw_reset_stipple_counter(struct draw_stage *draw) +nv40_render_reset_stipple_counter(struct draw_stage *draw) { - NOUVEAU_ERR("\n"); } static void -nv40_draw_destroy(struct draw_stage *draw) +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_draw_stage *nv40draw = CALLOC_STRUCT(nv40_draw_stage); + 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_emit(nv40); - nv40draw->nv40 = nv40; - nv40draw->draw.draw = nv40->draw; - nv40draw->draw.point = nv40_draw_point; - nv40draw->draw.line = nv40_draw_line; - nv40draw->draw.tri = nv40_draw_tri; - nv40draw->draw.flush = nv40_draw_flush; - nv40draw->draw.reset_stipple_counter = nv40_draw_reset_stipple_counter; - nv40draw->draw.destroy = nv40_draw_destroy; + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (!nv40->vtxbuf[i].buffer) + continue; + map = ws->buffer_map(ws, nv40->vtxbuf[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(nv40->draw, i, map); + } - return &nv40draw->draw; + 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]) { + map = ws->buffer_map(ws, nv40->constbuf[PIPE_SHADER_VERTEX], + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_constant_buffer(nv40->draw, map); + } + + draw_arrays(nv40->draw, mode, start, count); + + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (!nv40->vtxbuf[i].buffer) + continue; + 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); + + 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_4F, 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 index 953f9cd908..82dbcd3eef 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -797,9 +797,10 @@ nv40_fragprog_validate(struct nv40_context *nv40) if (fp->translated) goto update_constants; + nv40->fallback_swrast &= ~NV40_NEW_FRAGPROG; nv40_fragprog_translate(nv40, fp); if (!fp->translated) { - nv40->fallback |= NV40_FALLBACK_RAST; + nv40->fallback_swrast |= NV40_NEW_FRAGPROG; return FALSE; } diff --git a/src/gallium/drivers/nv40/nv40_shader.h b/src/gallium/drivers/nv40/nv40_shader.h index 5909c70713..854dccf548 100644 --- a/src/gallium/drivers/nv40/nv40_shader.h +++ b/src/gallium/drivers/nv40/nv40_shader.h @@ -476,6 +476,7 @@ # 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 @@ -550,5 +551,6 @@ 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 index 321d5de041..3eafbece30 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -3,6 +3,8 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "draw/draw_context.h" + #include "nv40_context.h" #include "nv40_state.h" @@ -345,7 +347,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); break; default: - so_data(so, 0); + so_data(so, NV40TCL_CULL_FACE_BACK); break; } so_data(so, NV40TCL_FRONT_FACE_CCW); @@ -363,13 +365,13 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); break; default: - so_data(so, 0); + 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_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); @@ -419,6 +421,9 @@ static void nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_rasterizer_state *rsso = hwcso; + + draw_set_rasterizer_state(nv40->draw, &rsso->pipe); nv40->rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; @@ -508,10 +513,12 @@ 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; } @@ -520,6 +527,9 @@ static void nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_vertex_program *vp = hwcso; + + draw_bind_vertex_shader(nv40->draw, vp ? vp->draw : NULL); nv40->vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; @@ -531,6 +541,7 @@ 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); } @@ -544,6 +555,8 @@ nv40_fp_state_create(struct pipe_context *pipe, fp = CALLOC(1, sizeof(struct nv40_fragment_program)); fp->pipe = *cso; + tgsi_scan_shader(fp->pipe.tokens, &fp->info); + return (void *)fp; } @@ -582,6 +595,8 @@ nv40_set_clip_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_clip_state(nv40->draw, clip); + nv40->clip = *clip; nv40->dirty |= NV40_NEW_UCP; } @@ -638,6 +653,8 @@ nv40_set_viewport_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_viewport_state(nv40->draw, vpt); + nv40->viewport = *vpt; nv40->dirty |= NV40_NEW_VIEWPORT; } @@ -648,6 +665,8 @@ nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_vertex_buffer(nv40->draw, index, vb); + nv40->vtxbuf[index] = *vb; nv40->dirty |= NV40_NEW_ARRAYS; } @@ -658,6 +677,8 @@ nv40_set_vertex_element(struct pipe_context *pipe, unsigned index, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_vertex_element(nv40->draw, index, ve); + nv40->vtxelt[index] = *ve; nv40->dirty |= NV40_NEW_ARRAYS; } diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index a02ea0c878..ab2866eb7a 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -2,6 +2,7 @@ #define __NV40_STATE_H__ #include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" struct nv40_sampler_state { uint32_t fmt; @@ -25,6 +26,8 @@ struct nv40_vertex_program_data { struct nv40_vertex_program { struct pipe_shader_state pipe; + struct draw_vertex_shader *draw; + boolean translated; struct nv40_vertex_program_exec *insns; unsigned nr_insns; @@ -49,6 +52,7 @@ struct nv40_fragment_program_data { struct nv40_fragment_program { struct pipe_shader_state pipe; + struct tgsi_shader_info info; boolean translated; unsigned samplers; diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c index 93e690161f..c52390f9ed 100644 --- a/src/gallium/drivers/nv40/nv40_state_clip.c +++ b/src/gallium/drivers/nv40/nv40_state_clip.c @@ -3,8 +3,12 @@ static boolean nv40_state_clip_validate(struct nv40_context *nv40) { - if (nv40->clip.nr) - nv40->fallback |= NV40_FALLBACK_TNL; + + if (nv40->render_mode == HW) { + nv40->fallback_swtnl &= ~NV40_NEW_UCP; + if (nv40->clip.nr) + nv40->fallback_swtnl |= NV40_NEW_UCP; + } return FALSE; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 9f268640e0..056238cc83 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -1,5 +1,6 @@ #include "nv40_context.h" #include "nv40_state.h" +#include "draw/draw_context.h" static struct nv40_state_entry *render_states[] = { &nv40_state_framebuffer, @@ -18,15 +19,27 @@ static struct nv40_state_entry *render_states[] = { NULL }; +static struct nv40_state_entry *swtnl_states[] = { + &nv40_state_framebuffer, + &nv40_state_rasterizer, + &nv40_state_clip, + &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_validate(struct nv40_context *nv40) +nv40_state_do_validate(struct nv40_context *nv40, + struct nv40_state_entry **states) { - struct nv40_state_entry **states = render_states; - unsigned last_fallback; - - last_fallback = nv40->fallback; - nv40->fallback = 0; - while (*states) { struct nv40_state_entry *e = *states; @@ -38,32 +51,15 @@ nv40_state_validate(struct nv40_context *nv40) states++; } nv40->dirty = 0; - - if (nv40->fallback & NV40_FALLBACK_TNL && - !(last_fallback & NV40_FALLBACK_TNL)) { - NOUVEAU_ERR("XXX: hwtnl->swtnl\n"); - } else - if (last_fallback & NV40_FALLBACK_TNL && - !(nv40->fallback & NV40_FALLBACK_TNL)) { - NOUVEAU_ERR("XXX: swtnl->hwtnl\n"); - } - - if (nv40->fallback & NV40_FALLBACK_RAST && - !(last_fallback & NV40_FALLBACK_RAST)) { - NOUVEAU_ERR("XXX: hwrast->swrast\n"); - } else - if (last_fallback & NV40_FALLBACK_RAST && - !(nv40->fallback & NV40_FALLBACK_RAST)) { - NOUVEAU_ERR("XXX: swrast->hwrast\n"); - } } -static void +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++) { @@ -74,14 +70,24 @@ nv40_state_emit(struct nv40_context *nv40) screen->cur_pctx = nv40->pctx_id; } - while (state->dirty) { - unsigned idx = ffsll(state->dirty) - 1; + for (i = 0, states = state->dirty; states; i++) { + if (!(states & (1ULL << i))) + continue; + so_ref (state->hw[i], &nv40->screen->state[i]); + so_emit(nv40->nvws, nv40->screen->state[i]); + states &= ~(1ULL << i); + } - so_ref (state->hw[idx], &nv40->screen->state[idx]); - so_emit(nv40->nvws, nv40->screen->state[idx]); - state->dirty &= ~(1ULL << idx); + 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))) @@ -91,18 +97,62 @@ nv40_state_emit(struct nv40_context *nv40) samplers &= ~(1ULL << i); } so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]); - so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]); + if (state->hw[NV40_STATE_VTXBUF] && nv40->render_mode == HW) + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]); } -void -nv40_emit_hw_state(struct nv40_context *nv40) +boolean +nv40_state_validate(struct nv40_context *nv40) { - nv40_state_validate(nv40); - nv40_state_emit(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); + nv40->dirty |= (NV40_NEW_VIEWPORT | + NV40_NEW_VERTPROG | + NV40_NEW_ARRAYS | + NV40_NEW_UCP); + 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) +{ + /* Setup for swtnl */ + if (nv40->render_mode == HW) { + NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl); + nv40->pipe.flush(&nv40->pipe, 0); + nv40->dirty |= (NV40_NEW_VIEWPORT | + NV40_NEW_VERTPROG | + NV40_NEW_ARRAYS | + NV40_NEW_UCP); + nv40->render_mode = SWTNL; + } + + nv40_state_do_validate(nv40, swtnl_states); + if (nv40->fallback_swrast) { + NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast); + return FALSE; + } - BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (2); - BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (1); + return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 3a32533907..9e5c7a72a7 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -3,18 +3,43 @@ static boolean nv40_state_viewport_validate(struct nv40_context *nv40) { - struct nouveau_stateobj *so = so_new(9, 0); + struct nouveau_stateobj *so = so_new(11, 0); struct pipe_viewport_state *vpt = &nv40->viewport; - 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])); + if (nv40->render_mode == HW) { + 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; diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index f16afc23b8..fad423fdf8 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -8,6 +8,8 @@ #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_pushbuf.h" +#define FORCE_SWTNL 0 + static INLINE int nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) { @@ -165,7 +167,11 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned nr; nv40_vbo_set_idxbuf(nv40, NULL, 0); - nv40_emit_hw_state(nv40); + if (FORCE_SWTNL || !nv40_state_validate(nv40)) { + return nv40_draw_elements_swtnl(pipe, NULL, 0, + mode, start, count); + } + nv40_state_emit(nv40); BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (nvgl_primitive(mode)); @@ -274,7 +280,7 @@ nv40_draw_elements_inline(struct pipe_context *pipe, struct pipe_winsys *ws = pipe->winsys; void *map; - nv40_emit_hw_state(nv40); + nv40_state_emit(nv40); map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { @@ -315,7 +321,7 @@ nv40_draw_elements_vbo(struct pipe_context *pipe, struct nv40_context *nv40 = nv40_context(pipe); unsigned nr; - nv40_emit_hw_state(nv40); + nv40_state_emit(nv40); BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (nvgl_primitive(mode)); @@ -352,8 +358,16 @@ nv40_draw_elements(struct pipe_context *pipe, 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); + } + nv40_state_emit(nv40); - if (nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize)) { + if (idxbuf) { nv40_draw_elements_vbo(pipe, mode, start, count); } else { nv40_draw_elements_inline(pipe, indexBuffer, indexSize, diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 3d730c1a32..9f1ee575ce 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -634,21 +634,29 @@ out_err: static boolean nv40_vertprog_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->vertprog; - struct pipe_buffer *constbuf = - nv40->constbuf[PIPE_SHADER_VERTEX]; struct nouveau_winsys *nvws = nv40->nvws; struct pipe_winsys *ws = nv40->pipe.winsys; + 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]; + } 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 |= NV40_FALLBACK_TNL; + nv40->fallback_swtnl |= NV40_NEW_VERTPROG; return FALSE; } -- cgit v1.2.3 From b2f01b0777f27a093849f299490b377ab8aab2fb Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 17 Mar 2008 03:14:11 +0100 Subject: nouveau: latest header. --- src/gallium/drivers/nouveau/nouveau_class.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index 7392490df0..dc202086d2 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -1784,6 +1784,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 @@ -5360,12 +5362,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50_2D_RECT_Y1 0x00000604 #define NV50_2D_RECT_X2 0x00000608 #define NV50_2D_RECT_Y2 0x0000060c -#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_2D_SIFC_UNK0800 0x00000800 #define NV50_2D_SIFC_FORMAT 0x00000804 #define NV50_2D_SIFC_FORMAT_32BPP 0x000000cf @@ -5384,6 +5380,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 -- cgit v1.2.3 From 5c15b1276ed56064382197d73d9d357201e5f71f Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 17 Mar 2008 03:32:07 +0100 Subject: nv10: fixes. --- src/gallium/drivers/nv10/nv10_context.h | 3 ++- src/gallium/drivers/nv10/nv10_state_emit.c | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index 8269d6121f..386138556e 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -47,11 +47,12 @@ struct nv10_context { uint32_t rt_enable; struct pipe_buffer *rt[4]; struct pipe_buffer *zeta; + uint32_t lma_offset; struct { struct pipe_buffer *buffer; uint32_t format; - } tex[16]; + } tex[2]; unsigned vb_enable; struct { diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c index 1d104e2f91..8bf0bd2d68 100644 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -49,21 +49,21 @@ nv10_emit_hw_state(struct nv10_context *nv10) 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_OFFSET, 1); - OUT_RELOCl(nv10->zeta+...);*/ + OUT_RELOCl(nv10->zeta+lma_offset);*/ } /* Texture images */ for (i = 0; i < 2; i++) { if (!(nv10->fp_samplers & (1 << i))) continue; - BEGIN_RING(celsius, NV10TCL_TX_OFFSET(i), 2); + BEGIN_RING(celsius, NV10TCL_TX_OFFSET(i), 1); OUT_RELOCl(nv10->tex[i].buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - // XXX -/* OUT_RELOCd(nv10->tex[i].buffer, nv10->tex[i].format, + 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);*/ + NV10TCL_TX_FORMAT_DMA1); } } -- cgit v1.2.3 From 767cd2ed6e97ae09526b15728495f361d5e22cb2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 17 Mar 2008 13:49:03 +1100 Subject: nv40: workaround main swtnl breakage Not sure where the real bug is here yet, but for now this gives us correct rendering in far more cases than previously. --- src/gallium/drivers/nv40/nv40_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index ce0e0bc6f2..eb4f2395c4 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -335,7 +335,7 @@ nv40_state_vtxfmt_validate(struct nv40_context *nv40) emit_attrib(nv40, 5, EMIT_1F, TGSI_SEMANTIC_FOG, 0); } - emit_attrib(nv40, 0, EMIT_4F, TGSI_SEMANTIC_POSITION, 0); + emit_attrib(nv40, 0, EMIT_3F, TGSI_SEMANTIC_POSITION, 0); return FALSE; } -- cgit v1.2.3 From f93386de0fb281e79633c3bf57060f660abdfade Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 17 Mar 2008 14:22:36 +1100 Subject: nouveau: create fence object when allocating pushbuf, instead of submit --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 3 ++- src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 4 +++- src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 14 ++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index ad587bafdf..40d4667c47 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -376,9 +376,10 @@ nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, int nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, - struct nouveau_fence *fence, uint32_t flags) + 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); diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index 37e404fc6c..1c9b5799f9 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -127,6 +127,8 @@ struct nouveau_pushbuf_bo { struct nouveau_pushbuf_priv { struct nouveau_pushbuf base; + struct nouveau_fence *fence; + unsigned nop_jump; unsigned start; unsigned size; @@ -288,7 +290,7 @@ nouveau_bo_unmap(struct nouveau_bo *); extern int nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, - struct nouveau_fence *fence, uint32_t flags); + uint32_t flags); extern int nouveau_resource_init(struct nouveau_resource **heap, unsigned start, diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c index fd9a5c5a96..a2b9321b15 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -56,6 +56,10 @@ nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) 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; } @@ -128,7 +132,6 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) struct nouveau_channel_priv *nvchan = nouveau_channel(chan); struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; struct nouveau_pushbuf_bo *pbbo; - struct nouveau_fence *fence = NULL; int ret; if (nvpb->base.remaining == nvpb->size) @@ -139,10 +142,6 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) nvchan->dma->free -= nvpb->size; assert(nvchan->dma->cur <= nvchan->dma->max); - ret = nouveau_fence_new(chan, &fence); - if (ret) - return ret; - nvchan->dma = &nvchan->dma_bufmgr; nvchan->pushbuf[nvpb->nop_jump] = 0x20000000 | (nvchan->dma->base + (nvchan->dma->cur << 2)); @@ -153,7 +152,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) struct nouveau_pushbuf_reloc *r; struct nouveau_bo *bo = &ptr_to_bo(pbbo->handle)->base; - ret = nouveau_bo_validate(chan, bo, fence, pbbo->flags); + ret = nouveau_bo_validate(chan, bo, pbbo->flags); assert (ret == 0); if (bo->offset == nouveau_bo(bo)->offset && @@ -188,9 +187,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) nvchan->dma = &nvchan->dma_master; /* Fence + kickoff */ - nouveau_fence_emit(fence); + nouveau_fence_emit(nvpb->fence); FIRE_RING_CH(chan); - nouveau_fence_ref(NULL, &fence); /* Allocate space for next push buffer */ ret = nouveau_pushbuf_space(chan, min); -- cgit v1.2.3 From 6b3269900101a4e4745f95028bfc0c7cfced12a8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 17 Mar 2008 23:05:46 +1100 Subject: nv40: a few more fp opcodes --- src/gallium/drivers/nv40/nv40_fragprog.c | 50 ++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 82dbcd3eef..4fb28a01ea 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -468,6 +468,34 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, 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; @@ -567,15 +595,33 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, swz(src[0], X, X, X, X), none, none); } break; - case TGSI_OPCODE_SIN: - arith(fpc, sat, SIN, dst, mask, src[0], none, none); + 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; -- cgit v1.2.3 From a33da10b6c999a8ea348789ea13d2147f117a722 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 17 Mar 2008 18:13:18 +0100 Subject: nv30: only 2 render targets --- src/gallium/drivers/nv30/nv30_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index c63847a087..21cffc6d27 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -48,7 +48,7 @@ struct nv30_context { unsigned vp_samplers; uint32_t rt_enable; - struct pipe_buffer *rt[4]; + struct pipe_buffer *rt[2]; struct pipe_buffer *zeta; struct { -- cgit v1.2.3 From 3394ba65b10a1ec01345c37b7888e18dcfdbe808 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 17 Mar 2008 19:03:38 +0100 Subject: nv30: another 2 rt, and set viewport tx origin, so we render at the proper place \o/ --- src/gallium/drivers/nv30/nv30_state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 80dfd9c5c0..b0055892ae 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -565,7 +565,7 @@ 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[4], *zeta = NULL; + 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; @@ -667,6 +667,8 @@ nv30_set_framebuffer_state(struct pipe_context *pipe, 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 -- cgit v1.2.3 From a514aeb77899816d82c5b31f3bf2206d82d68893 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 18 Mar 2008 13:20:59 +0100 Subject: nv30: update miptree stuff for texturing --- src/gallium/drivers/nv30/nv30_context.c | 1 + src/gallium/drivers/nv30/nv30_context.h | 4 +++- src/gallium/drivers/nv30/nv30_miptree.c | 22 ++++++++++++++++------ src/gallium/drivers/nv30/nv30_screen.c | 3 ++- 4 files changed, 22 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index b3906e28e3..cdd662a9f1 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -234,6 +234,7 @@ nv30_create(struct pipe_screen *screen, unsigned pctx_id) nv30_init_query_functions(nv30); nv30_init_surface_functions(nv30); nv30_init_state_functions(nv30); + nv30_init_miptree_functions(nv30); nv30->draw = draw_create(); assert(nv30->draw); diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 21cffc6d27..0ee6cfdb33 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -91,9 +91,11 @@ nv30_context(struct pipe_context *pipe) extern void nv30_init_state_functions(struct nv30_context *nv30); extern void nv30_init_surface_functions(struct nv30_context *nv30); -extern void nv30_init_miptree_functions(struct pipe_screen *screen); +extern void nv30_init_miptree_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); diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index 19945e9ab8..f5659353ea 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -55,7 +55,7 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) } static struct pipe_texture * -nv30_miptree_create(struct pipe_screen *screen, struct pipe_texture *pt) +nv30_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) { struct pipe_winsys *ws = screen->winsys; struct nv30_miptree *mt; @@ -99,6 +99,11 @@ nv30_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) } } +static void +nv30_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) +{ +} + static struct pipe_surface * nv30_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) @@ -128,13 +133,18 @@ nv30_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, return ps; } + void -nv30_init_miptree_functions(struct pipe_screen *screen) +nv30_init_miptree_functions(struct nv30_context *nv30) { - struct nv30_screen *nv30screen = nv30_screen(screen); + nv30->pipe.texture_update = nv30_miptree_update; +} - nv30screen->screen.texture_create = nv30_miptree_create; - nv30screen->screen.texture_release = nv30_miptree_release; - nv30screen->screen.get_tex_surface = nv30_miptree_surface_get; +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_get; } diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 39f2ac1af5..3ca50e4fbf 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -147,7 +147,8 @@ nv30_screen_create(struct pipe_winsys *winsys, struct nouveau_winsys *nvws, nv30screen->screen.is_format_supported = nv30_screen_is_format_supported; - nv30_init_miptree_functions(&nv30screen->screen); + nv30_screen_init_miptree_functions(&nv30screen->screen); + return &nv30screen->screen; } -- cgit v1.2.3 From e4b5008de46659f13fca7dcd1b587504e9d4484c Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 18 Mar 2008 13:34:26 +0100 Subject: nv30: hmm, no buffer for texture --- src/gallium/drivers/nv30/nv30_state_emit.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 70b98836f0..2cb4692e17 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -64,6 +64,8 @@ nv30_emit_hw_state(struct nv30_context *nv30) for (i = 0; i < 16; i++) { if (!(nv30->fp_samplers & (1 << i))) continue; + if (!nv30->tex[i].buffer) + 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); -- cgit v1.2.3 From 75e714d476eb573a6e06585341ce693434eb237e Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 18 Mar 2008 21:50:01 +0100 Subject: nv30: disable emit texture image in state_emit, already done in fragtex --- src/gallium/drivers/nv30/nv30_context.h | 4 ++-- src/gallium/drivers/nv30/nv30_state_emit.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 0ee6cfdb33..c1cc3eca1e 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -51,10 +51,10 @@ struct nv30_context { struct pipe_buffer *rt[2]; struct pipe_buffer *zeta; - struct { + /*struct { struct pipe_buffer *buffer; uint32_t format; - } tex[16]; + } tex[16];*/ unsigned vb_enable; struct { diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 2cb4692e17..eda2fd45f5 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -60,12 +60,11 @@ nv30_emit_hw_state(struct nv30_context *nv30) OUT_RING(0);*/ } - /* Texture images */ + /* Texture images, emitted in nv30_fragtex_build */ +#if 0 for (i = 0; i < 16; i++) { if (!(nv30->fp_samplers & (1 << i))) continue; - if (!nv30->tex[i].buffer) - 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); @@ -74,6 +73,7 @@ nv30_emit_hw_state(struct nv30_context *nv30) NOUVEAU_BO_OR, NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1); } +#endif /* Fragment program */ BEGIN_RING(rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1); -- cgit v1.2.3 From 9575e35807c89c0b8a745671bc2dcd54d96379ff Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 19 Mar 2008 00:06:15 +1100 Subject: nouveau: pass nvws to nvws->push_* functions, rather than nouveau_channel* --- src/gallium/drivers/nouveau/nouveau_push.h | 7 ++- src/gallium/drivers/nouveau/nouveau_stateobj.h | 10 ++-- src/gallium/drivers/nouveau/nouveau_winsys.h | 4 +- src/gallium/drivers/nv40/nv40_dma.h | 66 ------------------------- src/gallium/drivers/nv40/nv40_screen.c | 2 +- src/gallium/drivers/nv50/nv50_screen.c | 2 +- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 15 ++++-- 7 files changed, 23 insertions(+), 83 deletions(-) delete mode 100644 src/gallium/drivers/nv40/nv40_dma.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_push.h b/src/gallium/drivers/nouveau/nouveau_push.h index c5c5d988d5..225c17744a 100644 --- a/src/gallium/drivers/nouveau/nouveau_push.h +++ b/src/gallium/drivers/nouveau/nouveau_push.h @@ -27,7 +27,7 @@ #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->channel, ((size) + 1)); \ + pc->nvws->push_flush(pc->nvws, ((size) + 1)); \ OUT_RING((pc->obj->subc << 13) | ((size) << 18) | (mthd)); \ pc->nvws->channel->pushbuf->remaining -= ((size) + 1); \ } while(0) @@ -38,13 +38,12 @@ #define FIRE_RING() do { \ NOUVEAU_PUSH_CONTEXT(pc); \ - pc->nvws->push_flush(pc->nvws->channel, 0); \ + pc->nvws->push_flush(pc->nvws, 0); \ } while(0) #define OUT_RELOC(bo,data,flags,vor,tor) do { \ NOUVEAU_PUSH_CONTEXT(pc); \ - pc->nvws->push_reloc(pc->nvws->channel, \ - pc->nvws->channel->pushbuf->cur++, \ + pc->nvws->push_reloc(pc->nvws, pc->nvws->channel->pushbuf->cur++, \ (bo), (data), (flags), (vor), (tor)); \ } while(0) diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index 439c7e4734..d465223748 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -99,14 +99,14 @@ so_emit(struct nouveau_winsys *nvws, struct nouveau_stateobj *so) nr = so->cur - so->push; if (pb->remaining < nr) - nvws->push_flush(nvws->channel, nr); + nvws->push_flush(nvws, nr); 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->channel, pb->cur + r->offset, r->bo, + nvws->push_reloc(nvws, pb->cur + r->offset, r->bo, r->data, r->flags, r->vor, r->tor); } pb->cur += nr; @@ -120,17 +120,17 @@ so_emit_reloc_markers(struct nouveau_winsys *nvws, struct nouveau_stateobj *so) i = so->cur_reloc << 1; if (nvws->channel->pushbuf->remaining < i) - nvws->push_flush(nvws->channel, i); + nvws->push_flush(nvws, i); 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->channel, pb->cur++, r->bo, r->packet, + 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->channel, pb->cur++, r->bo, r->data, + nvws->push_reloc(nvws, pb->cur++, r->bo, r->data, r->flags | NOUVEAU_BO_DUMMY, r->vor, r->tor); } } diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index e4b20478a0..7fa7cc0910 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -24,10 +24,10 @@ struct nouveau_winsys { struct nouveau_resource **); void (*res_free)(struct nouveau_resource **); - int (*push_reloc)(struct nouveau_channel *, void *ptr, + 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_channel *, unsigned size); + int (*push_flush)(struct nouveau_winsys *, unsigned size); int (*grobj_alloc)(struct nouveau_winsys *, int grclass, struct nouveau_grobj **); diff --git a/src/gallium/drivers/nv40/nv40_dma.h b/src/gallium/drivers/nv40/nv40_dma.h deleted file mode 100644 index 1fb8267768..0000000000 --- a/src/gallium/drivers/nv40/nv40_dma.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __NV40_DMA_H__ -#define __NV40_DMA_H__ - -#include "pipe/nouveau/nouveau_winsys.h" - -#define OUT_RING(data) do { \ - (*nv40->nvws->channel->pushbuf->cur++) = (data); \ -} while(0) - -#define OUT_RINGp(src,size) do { \ - memcpy(nv40->nvws->channel->pushbuf->cur, (src), (size) * 4); \ - nv40->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 { \ - if (nv40->nvws->channel->pushbuf->remaining < ((size) + 1)) \ - nv40->nvws->push_flush(nv40->nvws->channel, ((size) + 1)); \ - OUT_RING((nv40->obj->subc << 13) | ((size) << 18) | (mthd)); \ - nv40->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() do { \ - nv40->nvws->push_flush(nv40->nvws->channel, 0); \ -} while(0) - -#define OUT_RELOC(bo,data,flags,vor,tor) do { \ - nv40->nvws->push_reloc(nv40->nvws->channel, \ - nv40->nvws->channel->pushbuf->cur, \ - (struct nouveau_bo *)(bo), \ - (data), (flags), (vor), (tor)); \ - OUT_RING(0); \ -} 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, \ - nv40->nvws->channel->vram->handle, \ - nv40->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) - -#endif diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 268ca83ce0..bf30fbeca1 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -260,7 +260,7 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, so_emit(nvws, so); so_ref(NULL, &so); - nvws->push_flush(nvws->channel, 0); + nvws->push_flush(nvws, 0); screen->pipe.winsys = ws; screen->pipe.destroy = nv40_screen_destroy; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 721c6421d1..ff4aca81a5 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -171,7 +171,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, so_emit(nvws, so); so_ref(NULL, &so); - nvws->push_flush(nvws->channel, 0); + nvws->push_flush(nvws, 0); screen->pipe.winsys = ws; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 6c85aab9f5..bf1afce5d9 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -59,14 +59,21 @@ nouveau_pipe_surface_fill(struct nouveau_winsys *nvws, struct pipe_surface *dst, } static int -nouveau_pipe_emit_reloc(struct nouveau_channel *chan, void *ptr, +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(chan, ptr, nouveau_buffer(buf)->bo, + 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) +{ + return nouveau_pushbuf_flush(nvws->channel, size); +} + struct pipe_context * nouveau_pipe_create(struct nouveau_context *nv) { @@ -114,8 +121,8 @@ nouveau_pipe_create(struct nouveau_context *nv) nvws->res_alloc = nouveau_resource_alloc; nvws->res_free = nouveau_resource_free; - nvws->push_reloc = nouveau_pipe_emit_reloc; - nvws->push_flush = nouveau_pushbuf_flush; + 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; -- cgit v1.2.3 From 176df85568992a5d99aab7f0b1e382d41459aa13 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 19 Mar 2008 21:52:19 +1100 Subject: nv40: "implement" noise opcodes in fragprog For the moment, we do what NVIDIA does and return 0 unconditionally. This isn't correct, but it's an implementation at least. --- src/gallium/drivers/nv40/nv40_fragprog.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 4fb28a01ea..33aac37d56 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -554,6 +554,12 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, 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, -- cgit v1.2.3 From 1d9049c4df24d47446218f4032b891b817af0d00 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 00:18:18 +1100 Subject: nouveau: match gallium API changes --- src/gallium/drivers/nv30/nv30_miptree.c | 3 ++- src/gallium/drivers/nv40/nv40_miptree.c | 3 ++- src/gallium/drivers/nv50/nv50_miptree.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index f5659353ea..6fdcf42a24 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -100,7 +100,8 @@ nv30_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) } static void -nv30_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) +nv30_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, + uint face, uint levels) { } diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 94ba05b710..0dff9b3ad6 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -99,7 +99,8 @@ nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) } static void -nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) +nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, + uint face, uint levels) { } diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 720d33fda9..7474c65765 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -35,7 +35,8 @@ nv50_screen_init_miptree_functions(struct pipe_screen *pscreen) } static void -nv50_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) +nv50_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, + uint face, uint levels) { } -- cgit v1.2.3 From 95e8cad9a38181052790b34837daa6717e0c5171 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 12:57:05 +1100 Subject: nv40: use new pipe_framebuffer width/height fields --- src/gallium/drivers/nv40/nv40_state_fb.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 71795ab182..107b440028 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -5,10 +5,12 @@ 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, w, h; + 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 < 4; i++) { @@ -16,12 +18,8 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) 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 |= (NV40TCL_RT_ENABLE_COLOR0 << i); rt[i] = fb->cbufs[i]; @@ -33,14 +31,6 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) rt_enable |= NV40TCL_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; } -- cgit v1.2.3 From 5d2577e576635559da202d0d062601e404843b2c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 17:38:24 +1100 Subject: nouveau: try combining prev and next resources on free Fixes some cases where we end up with a list of many unused chunks that are too small to be useful. --- src/gallium/winsys/dri/nouveau/nouveau_resource.c | 29 +++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_resource.c b/src/gallium/winsys/dri/nouveau/nouveau_resource.c index 5d9d578b4f..3bbcb5c45e 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_resource.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_resource.c @@ -88,6 +88,22 @@ nouveau_resource_free(struct nouveau_resource **res) 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; @@ -95,17 +111,6 @@ nouveau_resource_free(struct nouveau_resource **res) r->next->prev = r->prev; r->prev->size += r->size; free(r); - } else - if (r->next && !r->next->in_use) { - r->next->prev = r->prev; - if (r->prev) - r->prev->next = r->next; - r->next->size += r->size; - r->next->start = r->start; - free(r); - } else { - r->in_use = 0; } - - *res = NULL; + } -- cgit v1.2.3 From 735ecf5de8587f8e52fe6ffc7f3f17403d140e23 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 17:40:01 +1100 Subject: nouveau: potentially delay buffer destruction Rather than spinning waiting for the GPU to finish with the buffer, add a callback on the buffer's fence object instead. Gives a sizable performance increase in OA. --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 40d4667c47..5dbb7d0374 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -206,6 +206,18 @@ nouveau_bo_ref(struct nouveau_device *dev, uint64_t handle, 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) { @@ -220,11 +232,9 @@ nouveau_bo_del(struct nouveau_bo **bo) return; if (nvbo->fence) - nouveau_fence_wait(&nvbo->fence); - nouveau_mem_free(nvbo->base.device, &nvbo->drm, &nvbo->map); - if (nvbo->sysmem && !nvbo->user) - free(nvbo->sysmem); - free(nvbo); + nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo); + else + nouveau_bo_del_cb(nvbo); } int -- cgit v1.2.3 From 83e94189c424303fee4218a9d9380fc73b7ba318 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 18:15:58 +1100 Subject: nouveau: use saved fence pointer, not head of unsignalled list It's possible for the unsignalled list head to change during fence_flush. Fixes valgrind complaint exposed by a previous commit. --- src/gallium/winsys/dri/nouveau/nouveau_fence.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_fence.c b/src/gallium/winsys/dri/nouveau/nouveau_fence.c index 7714e6f248..e7b0b4ff07 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_fence.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_fence.c @@ -172,14 +172,13 @@ nouveau_fence_flush(struct nouveau_channel *chan) 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(nvchan->fence_head, &fence); + nouveau_fence_ref(&nvfence->base, &fence); while (nvfence->signal_cb) { struct nouveau_fence_cb *cb; -- cgit v1.2.3 From 1a4dcde808dbd5daa58f939361d9a9b539f81b50 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 18:28:07 +1100 Subject: nouveau: do a retry if initial buffer alloc fails --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 5dbb7d0374..46c0759dbb 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -369,8 +369,13 @@ nouveau_bo_validate_bo(struct nouveau_channel *chan, struct nouveau_bo *bo, int ret; ret = nouveau_bo_set_status(bo, flags); - if (ret) - return ret; + if (ret) { + nouveau_fence_flush(chan); + + ret = nouveau_bo_set_status(bo, flags); + if (ret) + return ret; + } if (nvbo->user) nouveau_bo_upload(nvbo); -- cgit v1.2.3 From ebde8d3a1276f5c72d39936efabe72b5325f8e98 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 21:17:57 +1100 Subject: nv40: use num_cbufs --- src/gallium/drivers/nv40/nv40_state_fb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 107b440028..93b79377c9 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -13,10 +13,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) unsigned h = fb->height; rt_enable = 0; - for (i = 0; i < 4; i++) { - if (!fb->cbufs[i]) - continue; - + for (i = 0; i < fb->num_cbufs; i++) { if (colour_format) { assert(colour_format == fb->cbufs[i]->format); } else { -- cgit v1.2.3 From 32162871396f65e8afdd90c602b1ccd01233c2e2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 21:58:17 +1100 Subject: nv40: align each level to 64 pixels --- src/gallium/drivers/nv40/nv40_miptree.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 0dff9b3ad6..01b3952fe6 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -12,7 +12,7 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) boolean swizzled = FALSE; uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; uint offset = 0; - int nr_faces, l, f; + int nr_faces, l, f, pitch; if (pt->target == PIPE_TEXTURE_CUBE) { nr_faces = 6; @@ -22,18 +22,18 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) } 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) - nv40mt->level[l].pitch = pt->width[l] * pt->cpp; - else - nv40mt->level[l].pitch = pt->width[0] * pt->cpp; - nv40mt->level[l].pitch = (nv40mt->level[l].pitch + 63) & ~63; + 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)); @@ -49,6 +49,7 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) offset += nv40mt->level[l].pitch * pt->height[l]; } } + NOUVEAU_ERR("\n"); nv40mt->total_size = offset; } -- cgit v1.2.3 From 46b8dd9c16755e97ae547c0a1823e338f7a7c791 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 22:01:22 +1100 Subject: nv40: s/free/FREE/ --- src/gallium/drivers/nv40/nv40_context.c | 2 +- src/gallium/drivers/nv40/nv40_draw.c | 2 +- src/gallium/drivers/nv40/nv40_fragprog.c | 4 ++-- src/gallium/drivers/nv40/nv40_miptree.c | 6 +++--- src/gallium/drivers/nv40/nv40_query.c | 2 +- src/gallium/drivers/nv40/nv40_vertprog.c | 8 ++++---- 6 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 58627443b8..7fcf8b8619 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -40,7 +40,7 @@ nv40_destroy(struct pipe_context *pipe) if (nv40->draw) draw_destroy(nv40->draw); - free(nv40); + FREE(nv40); } struct pipe_context * diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index eb4f2395c4..7c5e0df5b8 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -158,7 +158,7 @@ nv40_render_reset_stipple_counter(struct draw_stage *draw) static void nv40_render_destroy(struct draw_stage *draw) { - free(draw); + FREE(draw); } static INLINE void diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 33aac37d56..2d82f86ef5 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -801,7 +801,7 @@ nv40_fragprog_translate(struct nv40_context *nv40, fp->translated = TRUE; out_err: tgsi_parse_free(&parse); - free(fpc); + FREE(fpc); } static void @@ -903,7 +903,7 @@ nv40_fragprog_destroy(struct nv40_context *nv40, struct nv40_fragment_program *fp) { if (fp->insn_len) - free(fp->insn); + FREE(fp->insn); } struct nv40_state_entry nv40_state_fragprog = { diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 01b3952fe6..215b91fcd0 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -72,7 +72,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, mt->total_size); if (!mt->buffer) { - free(mt); + FREE(mt); return NULL; } @@ -93,9 +93,9 @@ nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) 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->level[l].image_offset); } - free(nv40mt); + FREE(nv40mt); } } diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c index 0317845624..a0a3072406 100644 --- a/src/gallium/drivers/nv40/nv40_query.c +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -34,7 +34,7 @@ nv40_query_destroy(struct pipe_context *pipe, struct pipe_query *pq) if (q->object) nv40->nvws->res_free(&q->object); - free(q); + FREE(q); } static void diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 9f1ee575ce..385c8aa078 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -572,7 +572,7 @@ nv40_vertprog_translate(struct nv40_context *nv40, vpc->high_temp = -1; if (!nv40_vertprog_prepare(vpc)) { - free(vpc); + FREE(vpc); return; } @@ -628,7 +628,7 @@ nv40_vertprog_translate(struct nv40_context *nv40, vp->translated = TRUE; out_err: tgsi_parse_free(&parse); - free(vpc); + FREE(vpc); } static boolean @@ -805,9 +805,9 @@ void nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp) { if (vp->nr_consts) - free(vp->consts); + FREE(vp->consts); if (vp->nr_insns) - free(vp->insns); + FREE(vp->insns); } struct nv40_state_entry nv40_state_vertprog = { -- cgit v1.2.3 From 0c91f5991dee7827ea915214a2a6973c2d6a7257 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 22:02:49 +1100 Subject: nv40: oops --- src/gallium/drivers/nv40/nv40_miptree.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 215b91fcd0..502edc1629 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -49,7 +49,6 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) offset += nv40mt->level[l].pitch * pt->height[l]; } } - NOUVEAU_ERR("\n"); nv40mt->total_size = offset; } -- cgit v1.2.3 From 308d7b171179f40b767b6590f71f969473ade25c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 22:09:29 +1100 Subject: nv40: swtnl fallback on unsupported array format --- src/gallium/drivers/nv40/nv40_vbo.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index fad423fdf8..4a5b811939 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -423,8 +423,12 @@ nv40_vbo_validate(struct nv40_context *nv40) continue; } - if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) - assert(0); + 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, -- cgit v1.2.3 From 19b57690ad251e2b0714abe3a20893722bd99d54 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 22:23:19 +1100 Subject: nv40: call semi-magic 0x1d88 method --- src/gallium/drivers/nv40/nv40_state_fb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 93b79377c9..88baf61ffb 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -128,6 +128,8 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) 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; -- cgit v1.2.3 From 3a0dd2e6d162fad6f98f337ee4f6b5dada1e37f3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 23:03:25 +1100 Subject: nv40: ensure vb relocs don't end up on list for swtnl Avoids bo code bailing out because of mapped buffers being validated. --- src/gallium/drivers/nv40/nv40_draw.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 7c5e0df5b8..d05e5ad193 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -236,6 +236,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, if (!nv40_state_validate_swtnl(nv40)) return FALSE; + nv40->dirty &= ~(1ULL << NV40_STATE_VTXBUF); nv40_state_emit(nv40); for (i = 0; i < PIPE_ATTRIB_MAX; i++) { -- cgit v1.2.3 From 3be8785e08128bc2821c0cdff97f7adbb46c745b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 23:09:01 +1100 Subject: nv40: add 16-bit SSCALED vb formats --- src/gallium/drivers/nv40/nv40_vbo.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 4a5b811939..4fae10f74b 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -28,6 +28,12 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) 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 = 5; + break; default: pf_sprint_name(fs, pipe); NOUVEAU_ERR("Unknown format %s\n", fs); @@ -37,18 +43,22 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) 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: -- cgit v1.2.3 From 75b85fd33abe143d9cca6f8405f0a4243b6a5ddb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 21 Mar 2008 23:24:16 +1100 Subject: nv40: fix bug in query code --- src/gallium/drivers/nv40/nv40_query.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c index a0a3072406..15961591b9 100644 --- a/src/gallium/drivers/nv40/nv40_query.c +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -45,6 +45,15 @@ nv40_query_begin(struct pipe_context *pipe, struct pipe_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); -- cgit v1.2.3 From 62a8e7685f0567052f50a2b9aaa64054e5dfa0c6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 14:29:35 +1100 Subject: nv40: add dxtn formats (disabled) --- src/gallium/drivers/nv40/nv40_fragtex.c | 8 ++++---- src/gallium/drivers/nv40/nv40_screen.c | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 436f954cec..980705f94a 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -30,10 +30,10 @@ nv40_texture_formats[] = { _(U_A8_L8 , 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), + _(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), {}, }; diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index bf30fbeca1..75b965bb9d 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -110,6 +110,12 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_U_A8_L8: case PIPE_FORMAT_Z16_UNORM: case PIPE_FORMAT_Z24S8_UNORM: +#if 0 /* state tracker not up to the task just yet. */ + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: +#endif return TRUE; default: break; -- cgit v1.2.3 From 01cb2cd93efe7ad94d7fd36aa5a776c2e3ab4c7d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 16:11:03 +1100 Subject: nv40: workaround fp result.data[0] clobberage Temporary, the fp reg handling will get reworked at some point in the near future. But before that, there's a few bugs to find. --- src/gallium/drivers/nv40/nv40_fragprog.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 2d82f86ef5..4e42536698 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -58,7 +58,7 @@ temp(struct nv40_fpc *fpc) int idx; idx = fpc->temp_temp_count++; - idx += fpc->high_temp + 1; + idx += fpc->high_temp + 2; return nv40_sr(NV40SR_TEMP, idx); } @@ -817,7 +817,9 @@ nv40_fragprog_upload(struct nv40_context *nv40, #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 -- cgit v1.2.3 From ba223e91df8f372a983e99c453947e4340d7d884 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 16:26:42 +1100 Subject: nv40: fp: fix multiple refs to a single const withing an instruction --- src/gallium/drivers/nv40/nv40_fragprog.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 4e42536698..4cdbf962ab 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -41,6 +41,7 @@ struct nv40_fpc { uint colour_id; unsigned inst_offset; + unsigned have_const; struct { int pipe; @@ -113,7 +114,11 @@ emit_src(struct nv40_fpc *fpc, int pos, struct nv40_sreg src) sr |= (src.index << NV40_FP_REG_SRC_SHIFT); break; case NV40SR_CONST: - grow_insns(fpc, 4); + 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; @@ -190,6 +195,7 @@ nv40_fp_arith(struct nv40_fpc *fpc, int sat, int op, 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); -- cgit v1.2.3 From 3158035154915ae11bebca045e3f0ce3b0e264ee Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 16:31:31 +1100 Subject: nv40: catch fp extra-const cases where both const and immd have same idx --- src/gallium/drivers/nv40/nv40_fragprog.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 4cdbf962ab..c854ae89f7 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -384,7 +384,7 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, 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; + int ai = -1, ci = -1, ii = -1; int i; if (finst->Instruction.Opcode == TGSI_OPCODE_END) @@ -428,8 +428,8 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, } break; case TGSI_FILE_CONSTANT: - case TGSI_FILE_IMMEDIATE: - if (ci == -1 || ci == fsrc->SrcRegister.Index) { + if ((ci == -1 && ii == -1) || + ci == fsrc->SrcRegister.Index) { ci = fsrc->SrcRegister.Index; src[i] = tgsi_src(fpc, fsrc); } else { @@ -438,6 +438,17 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, 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; -- cgit v1.2.3 From 4dfcf912964f7c14c877abde04255a3896fb903d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 18:11:49 +1100 Subject: nv40: remove some badness from fp temp/result allocation Should hopefully be OK now (on the fragprog size) for MRT. The hack from a commit 01cb2cd93efe7ad94d7fd36aa5a776c2e3ab4c7d is no longer needed. --- src/gallium/drivers/nv40/nv40_fragprog.c | 158 +++++++++++++++++++++---------- 1 file changed, 107 insertions(+), 51 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index c854ae89f7..6d8a29ed9c 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -33,12 +33,12 @@ struct nv40_fpc { uint attrib_map[PIPE_MAX_SHADER_INPUTS]; - int high_temp; - int temp_temp_count; - int num_regs; + unsigned r_temps; + unsigned r_temps_discard; + struct nv40_sreg r_result[PIPE_MAX_SHADER_OUTPUTS]; + struct nv40_sreg *r_temp; - uint depth_id; - uint colour_id; + int num_regs; unsigned inst_offset; unsigned have_const; @@ -56,13 +56,26 @@ struct nv40_fpc { static INLINE struct nv40_sreg temp(struct nv40_fpc *fpc) { - int idx; + int idx = ffs(~fpc->r_temps) - 1; - idx = fpc->temp_temp_count++; - idx += fpc->high_temp + 2; + 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]) { @@ -254,18 +267,11 @@ tgsi_src(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc) src = fpc->imm[fsrc->SrcRegister.Index]; break; case TGSI_FILE_TEMPORARY: - src = nv40_sr(NV40SR_TEMP, fsrc->SrcRegister.Index + 1); - if (fpc->high_temp < src.index) - fpc->high_temp = src.index; + src = fpc->r_temp[fsrc->SrcRegister.Index]; break; - /* This is clearly insane, but gallium hands us shaders like this. - * Luckily fragprog results are just temp regs.. - */ + /* NV40 fragprog result regs are just temps, so this is simple */ case TGSI_FILE_OUTPUT: - if (fsrc->SrcRegister.Index == fpc->colour_id) - return nv40_sr(NV40SR_OUTPUT, 0); - else - return nv40_sr(NV40SR_OUTPUT, 1); + src = fpc->r_result[fsrc->SrcRegister.Index]; break; default: NOUVEAU_ERR("bad src file\n"); @@ -283,20 +289,11 @@ tgsi_src(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc) static INLINE struct nv40_sreg tgsi_dst(struct nv40_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 nv40_sr(NV40SR_OUTPUT, 0); - else - return nv40_sr(NV40SR_OUTPUT, 1); - break; + return fpc->r_result[fdst->DstRegister.Index]; case TGSI_FILE_TEMPORARY: - idx = fdst->DstRegister.Index + 1; - if (fpc->high_temp < idx) - fpc->high_temp = idx; - return nv40_sr(NV40SR_TEMP, idx); + return fpc->r_temp[fdst->DstRegister.Index]; case TGSI_FILE_NULL: return nv40_sr(NV40SR_NONE, 0); default: @@ -390,7 +387,6 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, 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; @@ -670,6 +666,7 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, return FALSE; } + release_temps(fpc); return TRUE; } @@ -719,45 +716,50 @@ static boolean nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, const struct tgsi_full_declaration *fdec) { + unsigned idx = fdec->u.DeclarationRange.First; + unsigned hw; + switch (fdec->Semantic.SemanticName) { case TGSI_SEMANTIC_POSITION: - fpc->depth_id = fdec->u.DeclarationRange.First; + hw = 1; break; case TGSI_SEMANTIC_COLOR: - fpc->colour_id = fdec->u.DeclarationRange.First; + switch (idx) { + 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 void -nv40_fragprog_translate(struct nv40_context *nv40, - struct nv40_fragment_program *fp) +static boolean +nv40_fragprog_prepare(struct nv40_fpc *fpc) { - struct tgsi_parse_context parse; - struct nv40_fpc *fpc = NULL; + struct tgsi_parse_context p; + int high_temp = -1, i; - fpc = CALLOC(1, sizeof(struct nv40_fpc)); - if (!fpc) - return; - fpc->fp = fp; - fpc->high_temp = -1; - fpc->num_regs = 2; + 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_init(&parse, fp->pipe.tokens); - - while (!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { + tgsi_parse_token(&p); + switch(tok->Token.Type) { case TGSI_TOKEN_TYPE_DECLARATION: { const struct tgsi_full_declaration *fdec; - fdec = &parse.FullToken.FullDeclaration; + fdec = &p.FullToken.FullDeclaration; switch (fdec->Declaration.File) { case TGSI_FILE_INPUT: if (!nv40_fragprog_parse_decl_attrib(fpc, fdec)) @@ -767,6 +769,12 @@ nv40_fragprog_translate(struct nv40_context *nv40, if (!nv40_fragprog_parse_decl_output(fpc, fdec)) goto out_err; break; + case TGSI_FILE_TEMPORARY: + if (fdec->u.DeclarationRange.Last > high_temp) { + high_temp = + fdec->u.DeclarationRange.Last; + } + break; default: break; } @@ -777,7 +785,7 @@ nv40_fragprog_translate(struct nv40_context *nv40, struct tgsi_full_immediate *imm; float vals[4]; - imm = &parse.FullToken.FullImmediate; + imm = &p.FullToken.FullImmediate; assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); assert(fpc->nr_imm < MAX_IMM); @@ -788,6 +796,52 @@ nv40_fragprog_translate(struct nv40_context *nv40, 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; @@ -818,6 +872,8 @@ nv40_fragprog_translate(struct nv40_context *nv40, fp->translated = TRUE; out_err: tgsi_parse_free(&parse); + if (fpc->r_temp) + FREE(fpc->r_temp); FREE(fpc); } -- cgit v1.2.3 From e1ad8c232ba31985a6f9e5b76279f2f131312d1d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 18:20:04 +1100 Subject: nv40: fix fp depth write --- src/gallium/drivers/nv40/nv40_fragprog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 6d8a29ed9c..87bca41cf6 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -724,7 +724,7 @@ nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, hw = 1; break; case TGSI_SEMANTIC_COLOR: - switch (idx) { + switch (fdec->Semantic.SemanticIndex) { case 0: hw = 0; break; case 1: hw = 2; break; case 2: hw = 3; break; -- cgit v1.2.3 From 17491ea27ffa6b48e31c0ad6ad6f795dd000c476 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 23 Mar 2008 19:08:59 +1100 Subject: nv40: vp reg changes similar to recent fp changes --- src/gallium/drivers/nv40/nv40_vertprog.c | 106 +++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 20 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 385c8aa078..e5ce894375 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -42,10 +42,11 @@ struct nv40_vpc { struct nv40_vertex_program_exec *vpi; - unsigned output_map[PIPE_MAX_SHADER_OUTPUTS]; - - int high_temp; - int temp_temp_count; + 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; @@ -54,13 +55,26 @@ struct nv40_vpc { static struct nv40_sreg temp(struct nv40_vpc *vpc) { - int idx; + int idx = ffs(~vpc->r_temps) - 1; + + if (idx < 0) { + NOUVEAU_ERR("out of temps!!\n"); + assert(0); + return nv40_sr(NV40SR_TEMP, 0); + } - idx = vpc->temp_temp_count++; - idx += vpc->high_temp + 1; + 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) { @@ -257,9 +271,7 @@ tgsi_src(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc) { 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 = nv40_sr(NV40SR_TEMP, fsrc->SrcRegister.Index); + src = vpc->r_temp[fsrc->SrcRegister.Index]; break; default: NOUVEAU_ERR("bad src file\n"); @@ -281,14 +293,13 @@ tgsi_dst(struct nv40_vpc *vpc, const struct tgsi_full_dst_register *fdst) { switch (fdst->DstRegister.File) { case TGSI_FILE_OUTPUT: - dst = nv40_sr(NV40SR_OUTPUT, - vpc->output_map[fdst->DstRegister.Index]); - + dst = vpc->r_result[fdst->DstRegister.Index]; break; case TGSI_FILE_TEMPORARY: - dst = nv40_sr(NV40SR_TEMP, fdst->DstRegister.Index); - if (vpc->high_temp < dst.index) - vpc->high_temp = dst.index; + 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"); @@ -323,7 +334,6 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, 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; @@ -471,6 +481,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, return FALSE; } + release_temps(vpc); return TRUE; } @@ -478,6 +489,7 @@ static boolean nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, const struct tgsi_full_declaration *fdec) { + unsigned idx = fdec->u.DeclarationRange.First; int hw; switch (fdec->Semantic.SemanticName) { @@ -525,7 +537,7 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, return FALSE; } - vpc->output_map[fdec->u.DeclarationRange.First] = hw; + vpc->r_result[idx] = nv40_sr(NV40SR_OUTPUT, hw); return TRUE; } @@ -533,7 +545,7 @@ static boolean nv40_vertprog_prepare(struct nv40_vpc *vpc) { struct tgsi_parse_context p; - int nr_imm = 0; + 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)) { @@ -544,6 +556,48 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) 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->u.DeclarationRange.Last > high_temp) { + high_temp = + fdec->u.DeclarationRange.Last; + } + break; +#if 0 /* this would be nice.. except gallium doesn't track it */ + case TGSI_FILE_ADDRESS: + if (fdec->u.DeclarationRange.Last > high_addr) { + high_addr = + fdec->u.DeclarationRange.Last; + } + break; +#endif + 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; } @@ -555,6 +609,19 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) 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; } @@ -569,7 +636,6 @@ nv40_vertprog_translate(struct nv40_context *nv40, if (!vpc) return; vpc->vp = vp; - vpc->high_temp = -1; if (!nv40_vertprog_prepare(vpc)) { FREE(vpc); -- cgit v1.2.3 From 46a7f297a1477b9b59a5a11bf090db0ecbdf1ed7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 24 Mar 2008 13:01:35 +1100 Subject: nouveau: fix infinite wait on space for userbuf. A recent commit removed a bug which essentially caused a sync after each use of a user buffer. In fixing it, the scratch area can now become fragmented under some circumstances leading to nouveau_bo_tmp() waiting forever for a large enough block of free space. This fixes ppracer, gl-117 and probably a heap of other apps. --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 46c0759dbb..792eaaa79e 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -88,6 +88,26 @@ nouveau_bo_tmp_del(void *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) @@ -103,6 +123,11 @@ nouveau_bo_tmp(struct nouveau_channel *chan, unsigned size, 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); -- cgit v1.2.3 From 799d3bce06e998e51ad8df6bcadeb41bd061801e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 24 Mar 2008 13:41:40 +1100 Subject: nv40: respect rasterizer cso bypass_clipping flag --- src/gallium/drivers/nv40/nv40_context.h | 1 + src/gallium/drivers/nv40/nv40_state_viewport.c | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 02ca20b801..b50f6f8fef 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -97,6 +97,7 @@ struct nv40_blend_state { struct nv40_state { unsigned scissor_enabled; unsigned stipple_enabled; + unsigned viewport_bypass; unsigned fp_samplers; uint64_t dirty; diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 9e5c7a72a7..1b6248e5b8 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -5,8 +5,20 @@ nv40_state_viewport_validate(struct nv40_context *nv40) { struct nouveau_stateobj *so = so_new(11, 0); struct pipe_viewport_state *vpt = &nv40->viewport; + unsigned bypass; - if (nv40->render_mode == HW) { + 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; + + if (!bypass) { so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); so_data (so, fui(vpt->translate[0])); @@ -48,7 +60,7 @@ nv40_state_viewport_validate(struct nv40_context *nv40) struct nv40_state_entry nv40_state_viewport = { .validate = nv40_state_viewport_validate, .dirty = { - .pipe = NV40_NEW_VIEWPORT, + .pipe = NV40_NEW_VIEWPORT | NV40_NEW_RAST, .hw = NV40_STATE_VIEWPORT } }; -- cgit v1.2.3 From 5ce37d42b3268102caf8225be4ca18418bfab7c4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 24 Mar 2008 13:45:38 +1100 Subject: nv40: maintain pipe_surface status field --- src/gallium/drivers/nv40/nv40_clear.c | 1 + src/gallium/drivers/nv40/nv40_state_emit.c | 8 ++++++++ 2 files changed, 9 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_clear.c b/src/gallium/drivers/nv40/nv40_clear.c index 2c4e8f01fd..59efd620e3 100644 --- a/src/gallium/drivers/nv40/nv40_clear.c +++ b/src/gallium/drivers/nv40/nv40_clear.c @@ -9,4 +9,5 @@ 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_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 056238cc83..a9a9abc922 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -40,6 +40,14 @@ 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; -- cgit v1.2.3 From 601b018a9a6143c634239d5bb51616724c2e593d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 25 Mar 2008 12:12:26 +1100 Subject: nouveau: refcount buffers on validate list. --- src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 1 - src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index 1c9b5799f9..d5a0e25b57 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -108,7 +108,6 @@ nouveau_fence_flush(struct nouveau_channel *); struct nouveau_pushbuf_reloc { uint64_t next; - uint64_t handle; uint32_t *ptr; uint32_t flags; uint32_t data; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c index a2b9321b15..2e3ac5492f 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -157,11 +157,13 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) if (bo->offset == nouveau_bo(bo)->offset && bo->flags == nouveau_bo(bo)->flags) { + while ((r = ptr_to_pbrel(pbbo->relocs))) { pbbo->relocs = r->next; free(r); } + nouveau_bo_del(&bo); nvpb->buffers = pbbo->next; free(pbbo); continue; @@ -175,6 +177,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) free(r); } + nouveau_bo_del(&bo); nvpb->buffers = pbbo->next; free(pbbo); } @@ -202,6 +205,7 @@ nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) { struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); struct nouveau_pushbuf_bo *pbbo = ptr_to_pbbo(nvpb->buffers); + struct nouveau_bo *ref = NULL; while (pbbo) { if (pbbo->handle == bo->handle) @@ -214,7 +218,8 @@ nouveau_pushbuf_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) nvpb->buffers = pbbo_to_ptr(pbbo); nvpb->nr_buffers++; - pbbo->handle = bo_to_ptr(bo); + nouveau_bo_ref(bo->device, bo->handle, &ref); + pbbo->handle = bo_to_ptr(ref); pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; pbbo->relocs = 0; pbbo->nr_relocs = 0; @@ -244,7 +249,6 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, pbbo->flags |= (flags & NOUVEAU_BO_RDWR); pbbo->flags &= (flags | NOUVEAU_BO_RDWR); - r->handle = bo_to_ptr(r); r->ptr = ptr; r->flags = flags; r->data = data; -- cgit v1.2.3 From ce64778ed1f436d81178862dc0032dfd16b4b7de Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 25 Mar 2008 12:57:36 +1100 Subject: nv40: respect do_flip in surface_copy() --- src/gallium/drivers/nv40/nv40_surface.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index e8a6011696..c0d135eb36 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -42,8 +42,20 @@ nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip, struct nv40_context *nv40 = nv40_context(pipe); struct nouveau_winsys *nvws = nv40->nvws; - nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, - width, height); + 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 -- cgit v1.2.3 From 3017999d9bee8f9d2ef170c1bb6926aab8e08393 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 30 Mar 2008 19:00:07 +1000 Subject: nv40: vp const/immd fix --- src/gallium/drivers/nv40/nv40_vertprog.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index e5ce894375..41885b9d4a 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -328,7 +328,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, struct nv40_sreg src[3], dst, tmp; struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0); int mask; - int ai = -1, ci = -1; + int ai = -1, ci = -1, ii = -1; int i; if (finst->Instruction.Opcode == TGSI_OPCODE_END) @@ -358,12 +358,9 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, 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) { + if ((ci == -1 && ii == -1) || + ci == fsrc->SrcRegister.Index) { ci = fsrc->SrcRegister.Index; src[i] = tgsi_src(vpc, fsrc); } else { @@ -372,6 +369,17 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, 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; -- cgit v1.2.3 From 68395f6726183a0776e324b900e429449ede2b22 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 30 Mar 2008 19:08:59 +1000 Subject: nv40: vp 1/0/- swz --- src/gallium/drivers/nv40/nv40_vertprog.c | 74 +++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 41885b9d4a..40ef7174a4 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -4,13 +4,13 @@ #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 - * 2. Arb. swz/negation * 3. NV_vp11, NV_vp2, NV_vp3 features * - extra arith opcodes * - branching @@ -321,6 +321,66 @@ tgsi_mask(uint tgsi) 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) @@ -347,6 +407,18 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, 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) { -- cgit v1.2.3 From bbefb541ad94382debb0f7a8daa636729799a31a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 30 Mar 2008 20:32:22 +1000 Subject: nouveau: adapt to recent gallium changes --- src/gallium/drivers/nouveau/nouveau_push.h | 8 ++--- src/gallium/drivers/nouveau/nouveau_stateobj.h | 4 +-- src/gallium/drivers/nouveau/nouveau_winsys.h | 3 +- src/gallium/drivers/nv10/nv10_context.c | 19 +++------- src/gallium/drivers/nv10/nv10_state.c | 18 +++++----- src/gallium/drivers/nv30/nv30_context.c | 19 +++------- src/gallium/drivers/nv30/nv30_query.c | 2 +- src/gallium/drivers/nv30/nv30_state.c | 18 +++++----- src/gallium/drivers/nv30/nv30_vbo.c | 4 +-- src/gallium/drivers/nv40/nv40_context.c | 17 ++------- src/gallium/drivers/nv40/nv40_draw.c | 4 +-- src/gallium/drivers/nv40/nv40_query.c | 2 +- src/gallium/drivers/nv40/nv40_screen.c | 2 +- src/gallium/drivers/nv40/nv40_state.c | 20 +++++------ src/gallium/drivers/nv40/nv40_state_emit.c | 4 +-- src/gallium/drivers/nv40/nv40_vbo.c | 4 +-- src/gallium/drivers/nv50/nv50_context.c | 18 ++-------- src/gallium/drivers/nv50/nv50_screen.c | 2 +- src/gallium/drivers/nv50/nv50_state.c | 12 +++---- src/gallium/winsys/dri/nouveau/nouveau_context.c | 4 +-- src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 12 ++++++- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 42 ++++++++++++++++++++++ 22 files changed, 121 insertions(+), 117 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_push.h b/src/gallium/drivers/nouveau/nouveau_push.h index 225c17744a..54ef1c1291 100644 --- a/src/gallium/drivers/nouveau/nouveau_push.h +++ b/src/gallium/drivers/nouveau/nouveau_push.h @@ -27,7 +27,7 @@ #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)); \ + 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) @@ -36,9 +36,9 @@ BEGIN_RING(obj, (mthd) | 0x40000000, (size)); \ } while(0) -#define FIRE_RING() do { \ +#define FIRE_RING(fence) do { \ NOUVEAU_PUSH_CONTEXT(pc); \ - pc->nvws->push_flush(pc->nvws, 0); \ + pc->nvws->push_flush(pc->nvws, 0, fence); \ } while(0) #define OUT_RELOC(bo,data,flags,vor,tor) do { \ @@ -73,7 +73,7 @@ #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)); \ + 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); \ diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index d465223748..d501b76b51 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -99,7 +99,7 @@ so_emit(struct nouveau_winsys *nvws, struct nouveau_stateobj *so) nr = so->cur - so->push; if (pb->remaining < nr) - nvws->push_flush(nvws, nr); + nvws->push_flush(nvws, nr, NULL); pb->remaining -= nr; memcpy(pb->cur, so->push, nr * 4); @@ -120,7 +120,7 @@ so_emit_reloc_markers(struct nouveau_winsys *nvws, struct nouveau_stateobj *so) i = so->cur_reloc << 1; if (nvws->channel->pushbuf->remaining < i) - nvws->push_flush(nvws, i); + nvws->push_flush(nvws, i, NULL); nvws->channel->pushbuf->remaining -= i; for (i = 0; i < so->cur_reloc; i++) { diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 7fa7cc0910..2a5305f7ce 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -27,7 +27,8 @@ struct nouveau_winsys { 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); + int (*push_flush)(struct nouveau_winsys *, unsigned size, + struct pipe_fence_handle **fence); int (*grobj_alloc)(struct nouveau_winsys *, int grclass, struct nouveau_grobj **); diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c index 2599acf286..14042fb2fb 100644 --- a/src/gallium/drivers/nv10/nv10_context.c +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -7,10 +7,10 @@ #include "nv10_screen.h" static void -nv10_flush(struct pipe_context *pipe, unsigned flags) +nv10_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) { struct nv10_context *nv10 = nv10_context(pipe); - struct nouveau_winsys *nvws = nv10->nvws; if (flags & PIPE_FLUSH_TEXTURE_CACHE) { BEGIN_RING(celsius, 0x1fd8, 1); @@ -19,18 +19,7 @@ nv10_flush(struct pipe_context *pipe, unsigned flags) OUT_RING (1); } - if (flags & PIPE_FLUSH_WAIT) { - nvws->notifier_reset(nv10->sync, 0); - BEGIN_RING(celsius, 0x104, 1); - OUT_RING (0); - BEGIN_RING(celsius, 0x100, 1); - OUT_RING (0); - } - - FIRE_RING(); - - if (flags & PIPE_FLUSH_WAIT) - nvws->notifier_wait(nv10->sync, 0, 0, 2000); + FIRE_RING(fence); } static void @@ -253,7 +242,7 @@ nv10_init_hwctx(struct nv10_context *nv10, int celsius_class) OUT_RING (1); - FIRE_RING (); + FIRE_RING (NULL); return TRUE; } diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index d7c445f1b3..1ff01de106 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -633,24 +633,22 @@ nv10_set_viewport_state(struct pipe_context *pipe, } static void -nv10_set_vertex_buffer(struct pipe_context *pipe, unsigned index, - const struct pipe_vertex_buffer *vb) +nv10_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *vb) { struct nv10_context *nv10 = nv10_context(pipe); - nv10->vtxbuf[index] = *vb; - + memcpy(nv10->vtxbuf, vb, sizeof(*vb) * count); nv10->dirty |= NV10_NEW_ARRAYS; } static void -nv10_set_vertex_element(struct pipe_context *pipe, unsigned index, - const struct pipe_vertex_element *ve) +nv10_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *ve) { struct nv10_context *nv10 = nv10_context(pipe); - nv10->vtxelt[index] = *ve; - + memcpy(nv10->vtxelt, ve, sizeof(*ve) * count); nv10->dirty |= NV10_NEW_ARRAYS; } @@ -693,7 +691,7 @@ nv10_init_state_functions(struct nv10_context *nv10) nv10->pipe.set_scissor_state = nv10_set_scissor_state; nv10->pipe.set_viewport_state = nv10_set_viewport_state; - nv10->pipe.set_vertex_buffer = nv10_set_vertex_buffer; - nv10->pipe.set_vertex_element = nv10_set_vertex_element; + nv10->pipe.set_vertex_buffers = nv10_set_vertex_buffers; + nv10->pipe.set_vertex_elements = nv10_set_vertex_elements; } diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index cdd662a9f1..1e729d789b 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -7,10 +7,10 @@ #include "nv30_screen.h" static void -nv30_flush(struct pipe_context *pipe, unsigned flags) +nv30_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) { struct nv30_context *nv30 = nv30_context(pipe); - struct nouveau_winsys *nvws = nv30->nvws; if (flags & PIPE_FLUSH_TEXTURE_CACHE) { BEGIN_RING(rankine, 0x1fd8, 1); @@ -19,18 +19,7 @@ nv30_flush(struct pipe_context *pipe, unsigned flags) OUT_RING (1); } - if (flags & PIPE_FLUSH_WAIT) { - nvws->notifier_reset(nv30->sync, 0); - BEGIN_RING(rankine, 0x104, 1); - OUT_RING (0); - BEGIN_RING(rankine, 0x100, 1); - OUT_RING (0); - } - - FIRE_RING(); - - if (flags & PIPE_FLUSH_WAIT) - nvws->notifier_wait(nv30->sync, 0, 0, 2000); + FIRE_RING(fence); } static void @@ -144,7 +133,7 @@ nv30_init_hwctx(struct nv30_context *nv30, int rankine_class) BEGIN_RING(rankine, 0x1e94, 1); OUT_RING (0x13); - FIRE_RING (); + FIRE_RING (NULL); return TRUE; } diff --git a/src/gallium/drivers/nv30/nv30_query.c b/src/gallium/drivers/nv30/nv30_query.c index 71fdcfa24d..e19cb455dc 100644 --- a/src/gallium/drivers/nv30/nv30_query.c +++ b/src/gallium/drivers/nv30/nv30_query.c @@ -67,7 +67,7 @@ nv30_query_end(struct pipe_context *pipe, struct pipe_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(); + FIRE_RING(NULL); } static boolean diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index b0055892ae..983638adcc 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -710,24 +710,22 @@ nv30_set_viewport_state(struct pipe_context *pipe, } static void -nv30_set_vertex_buffer(struct pipe_context *pipe, unsigned index, - const struct pipe_vertex_buffer *vb) +nv30_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *vb) { struct nv30_context *nv30 = nv30_context(pipe); - nv30->vtxbuf[index] = *vb; - + memcpy(nv30->vtxbuf, vb, sizeof(*vb) * count); nv30->dirty |= NV30_NEW_ARRAYS; } static void -nv30_set_vertex_element(struct pipe_context *pipe, unsigned index, - const struct pipe_vertex_element *ve) +nv30_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *ve) { struct nv30_context *nv30 = nv30_context(pipe); - nv30->vtxelt[index] = *ve; - + memcpy(nv30->vtxelt, ve, sizeof(*ve) * count); nv30->dirty |= NV30_NEW_ARRAYS; } @@ -770,7 +768,7 @@ nv30_init_state_functions(struct nv30_context *nv30) nv30->pipe.set_scissor_state = nv30_set_scissor_state; nv30->pipe.set_viewport_state = nv30_set_viewport_state; - nv30->pipe.set_vertex_buffer = nv30_set_vertex_buffer; - nv30->pipe.set_vertex_element = nv30_set_vertex_element; + 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_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index a62462f7bc..b18a407ec5 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -229,7 +229,7 @@ nv30_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); OUT_RING (0); - pipe->flush(pipe, 0); + pipe->flush(pipe, 0, NULL); return TRUE; } @@ -418,7 +418,7 @@ nv30_draw_elements(struct pipe_context *pipe, mode, start, count); } - pipe->flush(pipe, 0); + pipe->flush(pipe, 0, NULL); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 7fcf8b8619..f9c93f7a2d 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -7,10 +7,10 @@ #include "nv40_screen.h" static void -nv40_flush(struct pipe_context *pipe, unsigned flags) +nv40_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_winsys *nvws = nv40->nvws; if (flags & PIPE_FLUSH_TEXTURE_CACHE) { BEGIN_RING(curie, 0x1fd8, 1); @@ -19,18 +19,7 @@ nv40_flush(struct pipe_context *pipe, unsigned flags) OUT_RING (1); } - if (flags & PIPE_FLUSH_WAIT) { - nvws->notifier_reset(nv40->screen->sync, 0); - BEGIN_RING(curie, 0x104, 1); - OUT_RING (0); - BEGIN_RING(curie, 0x100, 1); - OUT_RING (0); - } - - FIRE_RING(); - - if (flags & PIPE_FLUSH_WAIT) - nvws->notifier_wait(nv40->screen->sync, 0, 0, 2000); + FIRE_RING(fence); } static void diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index d05e5ad193..9cd8fa6a49 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -89,7 +89,7 @@ nv40_render_prim(struct draw_stage *stage, struct prim_header *prim, NOUVEAU_ERR("AIII, missed flush\n"); assert(0); } - FIRE_RING(); + FIRE_RING(NULL); nv40_state_emit(nv40); } @@ -275,7 +275,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, ws->buffer_unmap(ws, nv40->constbuf[PIPE_SHADER_VERTEX]); draw_flush(nv40->draw); - pipe->flush(pipe, 0); + pipe->flush(pipe, 0, NULL); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c index 15961591b9..57f39cfab0 100644 --- a/src/gallium/drivers/nv40/nv40_query.c +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -75,7 +75,7 @@ nv40_query_end(struct pipe_context *pipe, struct pipe_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(); + FIRE_RING(NULL); } static boolean diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 75b965bb9d..e98005f749 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -266,7 +266,7 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, so_emit(nvws, so); so_ref(NULL, &so); - nvws->push_flush(nvws, 0); + nvws->push_flush(nvws, 0, NULL); screen->pipe.winsys = ws; screen->pipe.destroy = nv40_screen_destroy; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 3eafbece30..1417c95e75 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -660,26 +660,26 @@ nv40_set_viewport_state(struct pipe_context *pipe, } static void -nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index, - const struct pipe_vertex_buffer *vb) +nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *vb) { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_vertex_buffer(nv40->draw, index, vb); + draw_set_vertex_buffers(nv40->draw, count, vb); - nv40->vtxbuf[index] = *vb; + memcpy(nv40->vtxbuf, vb, sizeof(*vb) * count); nv40->dirty |= NV40_NEW_ARRAYS; } static void -nv40_set_vertex_element(struct pipe_context *pipe, unsigned index, - const struct pipe_vertex_element *ve) +nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *ve) { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_vertex_element(nv40->draw, index, ve); + draw_set_vertex_elements(nv40->draw, count, ve); - nv40->vtxelt[index] = *ve; + memcpy(nv40->vtxelt, ve, sizeof(*ve) * count); nv40->dirty |= NV40_NEW_ARRAYS; } @@ -722,7 +722,7 @@ nv40_init_state_functions(struct nv40_context *nv40) nv40->pipe.set_scissor_state = nv40_set_scissor_state; nv40->pipe.set_viewport_state = nv40_set_viewport_state; - nv40->pipe.set_vertex_buffer = nv40_set_vertex_buffer; - nv40->pipe.set_vertex_element = nv40_set_vertex_element; + 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_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index a9a9abc922..74feb6d4bf 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -123,7 +123,7 @@ nv40_state_validate(struct nv40_context *nv40) return FALSE; /* Attempt to go to hwtnl again */ - nv40->pipe.flush(&nv40->pipe, 0); + nv40->pipe.flush(&nv40->pipe, 0, NULL); nv40->dirty |= (NV40_NEW_VIEWPORT | NV40_NEW_VERTPROG | NV40_NEW_ARRAYS | @@ -147,7 +147,7 @@ nv40_state_validate_swtnl(struct nv40_context *nv40) /* Setup for swtnl */ if (nv40->render_mode == HW) { NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl); - nv40->pipe.flush(&nv40->pipe, 0); + nv40->pipe.flush(&nv40->pipe, 0, NULL); nv40->dirty |= (NV40_NEW_VIEWPORT | NV40_NEW_VERTPROG | NV40_NEW_ARRAYS | diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 4fae10f74b..b66bf26afb 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -209,7 +209,7 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (0); - pipe->flush(pipe, 0); + pipe->flush(pipe, 0, NULL); return TRUE; } @@ -384,7 +384,7 @@ nv40_draw_elements(struct pipe_context *pipe, mode, start, count); } - pipe->flush(pipe, 0); + pipe->flush(pipe, 0, NULL); return TRUE; } diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 980d066c84..e822d86394 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -7,24 +7,12 @@ #include "nv50_screen.h" static void -nv50_flush(struct pipe_context *pipe, unsigned flags) +nv50_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) { struct nv50_context *nv50 = (struct nv50_context *)pipe; - struct nv50_screen *screen = nv50->screen; - struct nouveau_winsys *nvws = screen->nvws; - if (flags & PIPE_FLUSH_WAIT) { - nvws->notifier_reset(screen->sync, 0); - BEGIN_RING(tesla, 0x104, 1); - OUT_RING (0); - BEGIN_RING(tesla, 0x100, 1); - OUT_RING (0); - } - - FIRE_RING(); - - if (flags & PIPE_FLUSH_WAIT) - nvws->notifier_wait(screen->sync, 0, 0, 2000); + FIRE_RING(fence); } static void diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index ff4aca81a5..586373a5c4 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -171,7 +171,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, so_emit(nvws, so); so_ref(NULL, &so); - nvws->push_flush(nvws, 0); + nvws->push_flush(nvws, 0, NULL); screen->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index b096a2583d..a614ea0335 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -422,14 +422,14 @@ nv50_set_viewport_state(struct pipe_context *pipe, } static void -nv50_set_vertex_buffer(struct pipe_context *pipe, unsigned index, - const struct pipe_vertex_buffer *vb) +nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *vb) { } static void -nv50_set_vertex_element(struct pipe_context *pipe, unsigned index, - const struct pipe_vertex_element *ve) +nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *ve) { } @@ -472,7 +472,7 @@ nv50_init_state_functions(struct nv50_context *nv50) nv50->pipe.set_scissor_state = nv50_set_scissor_state; nv50->pipe.set_viewport_state = nv50_set_viewport_state; - nv50->pipe.set_vertex_buffer = nv50_set_vertex_buffer; - nv50->pipe.set_vertex_element = nv50_set_vertex_element; + nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers; + nv50->pipe.set_vertex_elements = nv50_set_vertex_elements; } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 336dd65847..cf1d83b18f 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -282,7 +282,7 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) assert(nv); - st_flush(nv->st, PIPE_FLUSH_WAIT); + st_finish(nv->st); st_destroy_context(nv->st); if (nv->pctx_id >= 0) { @@ -337,7 +337,7 @@ nouveau_context_unbind(__DRIcontextPrivate *driContextPriv) struct nouveau_context *nv = driContextPriv->driverPrivate; (void)nv; - st_flush(nv->st, 0); + st_flush(nv->st, 0, NULL); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index bf1afce5d9..60fdbb8dfd 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -69,8 +69,18 @@ nouveau_pipe_push_reloc(struct nouveau_winsys *nvws, void *ptr, } static int -nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size) +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); } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index e1a9271395..453b3623f4 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -164,6 +164,44 @@ nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_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) { @@ -189,6 +227,10 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) 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; -- cgit v1.2.3 From 833b1fb152851ba0d4fa2a5ba4702ee98d9bc217 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Mar 2008 05:13:06 +1000 Subject: nv40: mark fp dirty even when only consts updated Fixes arbfplight "sticking". --- src/gallium/drivers/nv40/nv40_fragprog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 87bca41cf6..4b7667e038 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -919,6 +919,7 @@ nv40_fragprog_validate(struct nv40_context *nv40) 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) @@ -945,7 +946,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) update_constants: if (fp->nr_consts) { - boolean new_consts = FALSE; float *map; map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); @@ -965,7 +965,7 @@ update_constants: nv40_fragprog_upload(nv40, fp); } - if (fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) { + if (new_consts || fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) { so_ref(fp->so, &nv40->state.hw[NV40_STATE_FRAGPROG]); return TRUE; } -- cgit v1.2.3 From 7b389f8d2f307fa0714494f2a43e9141cc04ed3e Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 30 Mar 2008 21:52:36 +0200 Subject: nv30: use FREE macro --- src/gallium/drivers/nv30/nv30_context.c | 2 +- src/gallium/drivers/nv30/nv30_draw.c | 2 +- src/gallium/drivers/nv30/nv30_fragprog.c | 4 ++-- src/gallium/drivers/nv30/nv30_miptree.c | 6 +++--- src/gallium/drivers/nv30/nv30_query.c | 2 +- src/gallium/drivers/nv30/nv30_state.c | 4 ++-- src/gallium/drivers/nv30/nv30_vertprog.c | 8 ++++---- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 1e729d789b..b8e8b86d99 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -41,7 +41,7 @@ nv30_destroy(struct pipe_context *pipe) nvws->grobj_free(&nv30->rankine); - free(nv30); + FREE(nv30); } static boolean diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c index 59a7265799..8ec0835225 100644 --- a/src/gallium/drivers/nv30/nv30_draw.c +++ b/src/gallium/drivers/nv30/nv30_draw.c @@ -40,7 +40,7 @@ nv30_draw_reset_stipple_counter(struct draw_stage *draw) static void nv30_draw_destroy(struct draw_stage *draw) { - free(draw); + FREE(draw); } struct draw_stage * diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 6f61d36f4e..51000bd6fc 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -753,7 +753,7 @@ nv30_fragprog_translate(struct nv30_context *nv30, fp->on_hw = FALSE; out_err: tgsi_parse_free(&parse); - free(fpc); + FREE(fpc); } void @@ -829,6 +829,6 @@ nv30_fragprog_destroy(struct nv30_context *nv30, struct nv30_fragment_program *fp) { if (fp->insn_len) - free(fp->insn); + FREE(fp->insn); } diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index 6fdcf42a24..afb05fdd2b 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -72,7 +72,7 @@ nv30_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, mt->total_size); if (!mt->buffer) { - free(mt); + FREE(mt); return NULL; } @@ -93,9 +93,9 @@ nv30_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) 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->level[l].image_offset); } - free(nv30mt); + FREE(nv30mt); } } diff --git a/src/gallium/drivers/nv30/nv30_query.c b/src/gallium/drivers/nv30/nv30_query.c index e19cb455dc..0c2d941562 100644 --- a/src/gallium/drivers/nv30/nv30_query.c +++ b/src/gallium/drivers/nv30/nv30_query.c @@ -35,7 +35,7 @@ nv30_query_destroy(struct pipe_context *pipe, struct pipe_query *pq) if (q->object) nv30->nvws->res_free(&q->object); - free(q); + FREE(q); } static void diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 983638adcc..620038fa64 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -486,7 +486,7 @@ nv30_vp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv30_vertex_program *vp = hwcso; nv30_vertprog_destroy(nv30, vp); - free(vp); + FREE(vp); } static void * @@ -522,7 +522,7 @@ nv30_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv30_fragment_program *fp = hwcso; nv30_fragprog_destroy(nv30, fp); - free(fp); + FREE(fp); } static void diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index e9b62ff48b..fe1a467565 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -578,7 +578,7 @@ nv30_vertprog_translate(struct nv30_context *nv30, vpc->high_temp = -1; if (!nv30_vertprog_prepare(vpc)) { - free(vpc); + FREE(vpc); return; } @@ -634,7 +634,7 @@ nv30_vertprog_translate(struct nv30_context *nv30, vp->translated = TRUE; out_err: tgsi_parse_free(&parse); - free(vpc); + FREE(vpc); } void @@ -790,8 +790,8 @@ void nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp) { if (vp->nr_consts) - free(vp->consts); + FREE(vp->consts); if (vp->nr_insns) - free(vp->insns); + FREE(vp->insns); } -- cgit v1.2.3 From 6806519a0b2a8af0c950f71705b02e13876d460f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Mar 2008 06:35:43 +1000 Subject: nv40: track current scissor enable/disable state Not sure how this was forgotten :) Anyhow, fixes gearbox/bzflag/xmoto, probably other things that use scissored clears / hit the nasty clear-with-quad path. --- src/gallium/drivers/nv40/nv40_state_scissor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index 9e9eadc511..285239ef41 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -10,10 +10,11 @@ nv40_state_scissor_validate(struct nv40_context *nv40) 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 (rast->scissor) { + 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 { -- cgit v1.2.3 From 169faae6db9a289c5a2d9430d85c36ac36abd218 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Mar 2008 09:00:25 +1000 Subject: nv40: support vp clip distance regs, unused currently. --- src/gallium/drivers/nv40/nv40_state.h | 1 + src/gallium/drivers/nv40/nv40_vertprog.c | 106 ++++++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index ab2866eb7a..e018464c9f 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -42,6 +42,7 @@ struct nv40_vertex_program { uint32_t ir; uint32_t or; + uint32_t clip_ctrl; struct nouveau_stateobj *so; }; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 40ef7174a4..5906280e5e 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -37,6 +37,8 @@ #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; @@ -200,6 +202,36 @@ emit_dst(struct nv40_vpc *vpc, uint32_t *hw, int slot, struct nv40_sreg dst) 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; } @@ -391,6 +423,11 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, int ai = -1, ci = -1, ii = -1; int i; + struct { + struct nv40_sreg dst; + unsigned c, m; + } clip; + if (finst->Instruction.Opcode == TGSI_OPCODE_END) return TRUE; @@ -464,6 +501,51 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, dst = tgsi_dst(vpc, &finst->FullDstRegisters[0]); mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask); + /* If writing to clip distance regs, need to modify instruction to + * change which component is written to. On NV40 the clip regs + * are the unused components (yzw) of FOGC/PSZ + */ + clip.dst = none; + if (dst.type == NV40SR_OUTPUT && + dst.index >= NV40_VP_INST_DEST_CLIP(0) && + dst.index <= NV40_VP_INST_DEST_CLIP(5)) { + unsigned n = dst.index - NV40_VP_INST_DEST_CLIP(0); + unsigned c[] = { SWZ_Y, SWZ_Z, SWZ_W, SWZ_Y, SWZ_Z, SWZ_W }; + unsigned m[] = + { MASK_Y, MASK_Z, MASK_W, MASK_Y, MASK_Z, MASK_W }; + + /* Some instructions we can get away with swizzling and/or + * changing the writemask. Others, we'll use a temp reg. + */ + switch (finst->Instruction.Opcode) { + case TGSI_OPCODE_DST: + case TGSI_OPCODE_EXP: + case TGSI_OPCODE_LIT: + case TGSI_OPCODE_LOG: + case TGSI_OPCODE_XPD: + clip.dst = dst; + clip.c = c[n]; + clip.m = m[n]; + dst = temp(vpc); + break; + case TGSI_OPCODE_DP3: + case TGSI_OPCODE_DP4: + case TGSI_OPCODE_DPH: + case TGSI_OPCODE_POW: + case TGSI_OPCODE_RCP: + case TGSI_OPCODE_RSQ: + mask = m[n]; + break; + default: + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + src[i] = nv40_sr_swz(src[i], + c[n], c[n], c[n], c[n]); + } + mask = m[n]; + break; + } + } + switch (finst->Instruction.Opcode) { case TGSI_OPCODE_ABS: arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none); @@ -561,6 +643,12 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, return FALSE; } + if (clip.dst.type != NV40SR_NONE) { + arith(vpc, 0, OP_MOV, clip.dst, clip.m, + nv40_sr_swz(dst, clip.c, clip.c, clip.c, clip.c), + none, none); + } + release_temps(vpc); return TRUE; } @@ -612,6 +700,15 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, return FALSE; } break; +#if 0 + case TGSI_SEMANTIC_CLIP: + if (fdec->Semantic.SemanticIndex >= 6) { + NOUVEAU_ERR("bad clip distance index\n"); + return FALSE; + } + hw = NV40_VP_INST_DEST_CLIP(fdec->Semantic.SemanticIndex); + break; +#endif default: NOUVEAU_ERR("bad output semantic\n"); return FALSE; @@ -782,6 +879,7 @@ 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; @@ -825,12 +923,14 @@ check_gpu_resources: assert(0); } - so = so_new(5, 0); - so_method(so, nv40->screen->curie, NV40TCL_VP_START_FROM_ID, 1); + so = so_new(7, 0); + so_method(so, curie, NV40TCL_VP_START_FROM_ID, 1); so_data (so, vp->exec->start); - so_method(so, nv40->screen->curie, NV40TCL_VP_ATTRIB_EN, 2); + 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; -- cgit v1.2.3 From 4ad9dd6179787a46ecb223ab0e59e6b25b9368af Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Mar 2008 09:29:22 +1000 Subject: nouveau: update object header --- src/gallium/drivers/nouveau/nouveau_class.h | 14 ++++++++------ src/gallium/drivers/nv40/nv40_vbo.c | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index dc202086d2..bf1e622d2c 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -4249,6 +4249,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_MASK 0x0000000f #define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT 0x00000002 #define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_UBYTE 0x00000004 +#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_USHORT 0x00000005 #define NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_SHIFT 4 #define NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_MASK 0x000000f0 #define NV34TCL_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT 8 @@ -4963,12 +4964,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 << 2) -#define NV40TCL_CLIP_PLANE_ENABLE_PLANE1 (1 << 6) -#define NV40TCL_CLIP_PLANE_ENABLE_PLANE2 (1 << 10) -#define NV40TCL_CLIP_PLANE_ENABLE_PLANE3 (1 << 14) -#define NV40TCL_CLIP_PLANE_ENABLE_PLANE4 (1 << 18) -#define NV40TCL_CLIP_PLANE_ENABLE_PLANE5 (1 << 22) +#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 @@ -4990,6 +4991,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index b66bf26afb..bc53924a67 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -32,7 +32,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) case PIPE_FORMAT_R16G16_SSCALED: case PIPE_FORMAT_R16G16B16_SSCALED: case PIPE_FORMAT_R16G16B16A16_SSCALED: - *fmt = 5; + *fmt = NV40TCL_VTXFMT_TYPE_USHORT; break; default: pf_sprint_name(fs, pipe); -- cgit v1.2.3 From e616d3f3e2178e34e4e7d769b38b0dff4ad615fe Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 Mar 2008 09:37:57 +1000 Subject: nv40: fix slight thinko --- src/gallium/drivers/nv40/nv40_vertprog.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 5906280e5e..08d3f387e0 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -425,7 +425,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, struct { struct nv40_sreg dst; - unsigned c, m; + unsigned m; } clip; if (finst->Instruction.Opcode == TGSI_OPCODE_END) @@ -503,14 +503,13 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, /* If writing to clip distance regs, need to modify instruction to * change which component is written to. On NV40 the clip regs - * are the unused components (yzw) of FOGC/PSZ + * are the unused components (yzw) of FOGC/PSZ. */ clip.dst = none; if (dst.type == NV40SR_OUTPUT && dst.index >= NV40_VP_INST_DEST_CLIP(0) && dst.index <= NV40_VP_INST_DEST_CLIP(5)) { unsigned n = dst.index - NV40_VP_INST_DEST_CLIP(0); - unsigned c[] = { SWZ_Y, SWZ_Z, SWZ_W, SWZ_Y, SWZ_Z, SWZ_W }; unsigned m[] = { MASK_Y, MASK_Z, MASK_W, MASK_Y, MASK_Z, MASK_W }; @@ -524,7 +523,6 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, case TGSI_OPCODE_LOG: case TGSI_OPCODE_XPD: clip.dst = dst; - clip.c = c[n]; clip.m = m[n]; dst = temp(vpc); break; @@ -537,10 +535,8 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, mask = m[n]; break; default: - for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { - src[i] = nv40_sr_swz(src[i], - c[n], c[n], c[n], c[n]); - } + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) + src[i] = swz(src[i], X, X, X, X); mask = m[n]; break; } @@ -645,8 +641,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, if (clip.dst.type != NV40SR_NONE) { arith(vpc, 0, OP_MOV, clip.dst, clip.m, - nv40_sr_swz(dst, clip.c, clip.c, clip.c, clip.c), - none, none); + swz(dst, X, X, X, X), none, none); } release_temps(vpc); -- cgit v1.2.3 From 71d7aec2b3bb299f1dff7cdb2e8e96164976113a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 2 Apr 2008 00:40:18 +1000 Subject: nouveau: winsys printf disappeared :) --- src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index 453b3623f4..b1bf9c521a 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -20,15 +20,6 @@ nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, nouveau_copy_buffer(dPriv, surf, NULL); } -static void -nouveau_printf(struct pipe_winsys *pws, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); -} - static const char * nouveau_get_name(struct pipe_winsys *pws) { @@ -215,7 +206,6 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) pws = &nvpws->pws; pws->flush_frontbuffer = nouveau_flush_frontbuffer; - pws->printf = nouveau_printf; pws->surface_alloc = nouveau_surface_alloc; pws->surface_alloc_storage = nouveau_surface_alloc_storage; -- cgit v1.2.3 From bdf5b23bfd222ade9b3599ebd0f8932a5179431e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 2 Apr 2008 12:54:37 +1000 Subject: nv40: shorten zsa state lines --- src/gallium/drivers/nv40/nv40_state.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 1417c95e75..89f4078b72 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -445,19 +445,20 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, 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, nv40->screen->curie, NV40TCL_DEPTH_FUNC, 3); + 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, nv40->screen->curie, NV40TCL_ALPHA_TEST_ENABLE, 3); + 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, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); + 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)); @@ -467,12 +468,12 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, 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, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); + so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); so_data (so, 0); } if (cso->stencil[1].enabled) { - so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 8); + 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)); @@ -482,7 +483,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, 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, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 1); + so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 1); so_data (so, 0); } -- cgit v1.2.3 From ae87909d0d261d0f4e888f6a167e6329eb129a87 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 2 Apr 2008 13:04:06 +1000 Subject: nv40: only update draw module state when using swtnl --- src/gallium/drivers/nv40/nv40_context.h | 6 ++++-- src/gallium/drivers/nv40/nv40_state.c | 22 ++++++++++------------ src/gallium/drivers/nv40/nv40_state_emit.c | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index b50f6f8fef..525eef8d63 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -133,7 +133,7 @@ struct nv40_context { unsigned fallback_swrast; /* Context state */ - unsigned dirty; + unsigned dirty, draw_dirty; struct pipe_scissor_state scissor; unsigned stipple[32]; struct pipe_clip_state clip; @@ -153,8 +153,10 @@ struct nv40_context { unsigned nr_samplers; unsigned nr_textures; unsigned dirty_samplers; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; + unsigned vtxbuf_nr; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; + unsigned vtxelt_nr; }; static INLINE struct nv40_context * diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 89f4078b72..5dc2991212 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -423,10 +423,9 @@ nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) struct nv40_context *nv40 = nv40_context(pipe); struct nv40_rasterizer_state *rsso = hwcso; - draw_set_rasterizer_state(nv40->draw, &rsso->pipe); - nv40->rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; + nv40->draw_dirty |= NV40_NEW_RAST; } static void @@ -530,10 +529,9 @@ nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) struct nv40_context *nv40 = nv40_context(pipe); struct nv40_vertex_program *vp = hwcso; - draw_bind_vertex_shader(nv40->draw, vp ? vp->draw : NULL); - nv40->vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; + nv40->draw_dirty |= NV40_NEW_VERTPROG; } static void @@ -596,10 +594,9 @@ nv40_set_clip_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_clip_state(nv40->draw, clip); - nv40->clip = *clip; nv40->dirty |= NV40_NEW_UCP; + nv40->draw_dirty |= NV40_NEW_UCP; } static void @@ -654,10 +651,9 @@ nv40_set_viewport_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_viewport_state(nv40->draw, vpt); - nv40->viewport = *vpt; nv40->dirty |= NV40_NEW_VIEWPORT; + nv40->draw_dirty |= NV40_NEW_VIEWPORT; } static void @@ -666,10 +662,11 @@ nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count, { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_vertex_buffers(nv40->draw, count, vb); - memcpy(nv40->vtxbuf, vb, sizeof(*vb) * count); + nv40->vtxbuf_nr = count; + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->draw_dirty |= NV40_NEW_ARRAYS; } static void @@ -678,10 +675,11 @@ nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count, { struct nv40_context *nv40 = nv40_context(pipe); - draw_set_vertex_elements(nv40->draw, count, ve); - memcpy(nv40->vtxelt, ve, sizeof(*ve) * count); + nv40->vtxelt_nr = count; + nv40->dirty |= NV40_NEW_ARRAYS; + nv40->draw_dirty |= NV40_NEW_ARRAYS; } void diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 74feb6d4bf..722b9f31e6 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -144,6 +144,8 @@ nv40_state_validate(struct nv40_context *nv40) 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); @@ -155,12 +157,30 @@ nv40_state_validate_swtnl(struct nv40_context *nv40) 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_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; } -- cgit v1.2.3 From b1a361ba7a565063200c033e4939e6b28c006b13 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Wed, 2 Apr 2008 05:10:18 +0200 Subject: nv10: fix stuff and things. --- src/gallium/drivers/nouveau/nouveau_class.h | 24 +++- src/gallium/drivers/nv10/nv10_context.c | 92 +++--------- src/gallium/drivers/nv10/nv10_context.h | 31 +++- src/gallium/drivers/nv10/nv10_miptree.c | 28 ++-- src/gallium/drivers/nv10/nv10_prim_vbuf.c | 17 ++- src/gallium/drivers/nv10/nv10_screen.c | 70 ++++++--- src/gallium/drivers/nv10/nv10_screen.h | 6 +- src/gallium/drivers/nv10/nv10_state.c | 155 ++++---------------- src/gallium/drivers/nv10/nv10_state_emit.c | 216 ++++++++++++++++++++++++++-- 9 files changed, 395 insertions(+), 244 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index dc202086d2..880afe6ce0 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -2804,6 +2804,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 @@ -4249,6 +4259,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_MASK 0x0000000f #define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT 0x00000002 #define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_UBYTE 0x00000004 +#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_USHORT 0x00000005 #define NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_SHIFT 4 #define NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_MASK 0x000000f0 #define NV34TCL_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT 8 @@ -4963,12 +4974,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 << 2) -#define NV40TCL_CLIP_PLANE_ENABLE_PLANE1 (1 << 6) -#define NV40TCL_CLIP_PLANE_ENABLE_PLANE2 (1 << 10) -#define NV40TCL_CLIP_PLANE_ENABLE_PLANE3 (1 << 14) -#define NV40TCL_CLIP_PLANE_ENABLE_PLANE4 (1 << 18) -#define NV40TCL_CLIP_PLANE_ENABLE_PLANE5 (1 << 22) +#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 @@ -4990,6 +5001,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c index 14042fb2fb..42c496b959 100644 --- a/src/gallium/drivers/nv10/nv10_context.c +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -12,13 +12,6 @@ nv10_flush(struct pipe_context *pipe, unsigned flags, { struct nv10_context *nv10 = nv10_context(pipe); - if (flags & PIPE_FLUSH_TEXTURE_CACHE) { - BEGIN_RING(celsius, 0x1fd8, 1); - OUT_RING (2); - BEGIN_RING(celsius, 0x1fd8, 1); - OUT_RING (1); - } - FIRE_RING(fence); } @@ -26,36 +19,21 @@ static void nv10_destroy(struct pipe_context *pipe) { struct nv10_context *nv10 = nv10_context(pipe); - struct nouveau_winsys *nvws = nv10->nvws; if (nv10->draw) draw_destroy(nv10->draw); - nvws->res_free(&nv10->vertprog.exec_heap); - nvws->res_free(&nv10->vertprog.data_heap); - - nvws->notifier_free(&nv10->sync); - - nvws->grobj_free(&nv10->celsius); - - free(nv10); + FREE(nv10); } -static boolean -nv10_init_hwctx(struct nv10_context *nv10, int celsius_class) +static void nv10_init_hwctx(struct nv10_context *nv10) { - struct nouveau_winsys *nvws = nv10->nvws; - int ret; + struct nv10_screen *screen = nv10->screen; + struct nouveau_winsys *nvws = screen->nvws; int i; - ret = nvws->grobj_alloc(nvws, celsius_class, &nv10->celsius); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - BEGIN_RING(celsius, NV10TCL_DMA_NOTIFY, 1); - OUT_RING (nv10->sync->handle); + 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); @@ -90,7 +68,7 @@ nv10_init_hwctx(struct nv10_context *nv10, int celsius_class) BEGIN_RING(celsius, NV10TCL_NOP, 1); OUT_RING (0); - if (celsius_class != NV10TCL) { + if (nv10->screen->celsius->grclass != NV10TCL) { /* For nv11, nv17 */ BEGIN_RING(celsius, 0x120, 3); OUT_RING (0); @@ -243,72 +221,44 @@ nv10_init_hwctx(struct nv10_context *nv10, int celsius_class) FIRE_RING (NULL); - return TRUE; } struct pipe_context * -nv10_create(struct pipe_screen *screen, unsigned pctx_id) +nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) { - struct pipe_winsys *pipe_winsys = screen->winsys; - struct nouveau_winsys *nvws = nv10_screen(screen)->nvws; - unsigned chipset = nv10_screen(screen)->chipset; + struct nv10_screen *screen = nv10_screen(pscreen); + struct pipe_winsys *ws = pscreen->winsys; struct nv10_context *nv10; - int celsius_class = 0, ret; - - if (chipset>=0x20) - celsius_class=NV11TCL; - else if (chipset>=0x17) - celsius_class=NV17TCL; - else if (chipset>=0x11) - celsius_class=NV11TCL; - else - celsius_class=NV10TCL; - - nv10 = CALLOC_STRUCT(nv10_context); + unsigned chipset = screen->chipset; + 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->chipset = chipset; nv10->nvws = nvws; - /* Notifier for sync purposes */ - ret = nvws->notifier_alloc(nvws, 1, &nv10->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv10_destroy(&nv10->pipe); - return NULL; - } - - /* Vtxprog resources */ - if (nvws->res_init(&nv10->vertprog.exec_heap, 0, 512) || - nvws->res_init(&nv10->vertprog.data_heap, 0, 256)) { - nv10_destroy(&nv10->pipe); - return NULL; - } - - /* Static celsius initialisation */ - if (!nv10_init_hwctx(nv10, celsius_class)) { - nv10_destroy(&nv10->pipe); - return NULL; - } - - /* Pipe context setup */ - nv10->pipe.winsys = pipe_winsys; - + nv10->pipe.winsys = ws; + nv10->pipe.screen = pscreen; nv10->pipe.destroy = nv10_destroy; - 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_init_miptree_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 index 386138556e..61eb4e6a93 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -11,7 +11,7 @@ #include "nouveau/nouveau_gldefs.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ - struct nv10_context *ctx = nv10 + struct nv10_screen *ctx = nv10->screen #include "nouveau/nouveau_push.h" #include "nv10_state.h" @@ -24,17 +24,27 @@ #define NV10_NEW_VERTPROG (1 << 1) #define NV10_NEW_FRAGPROG (1 << 2) #define NV10_NEW_ARRAYS (1 << 3) -#define NV10_NEW_VBO (1 << 4) +#define NV10_NEW_VTXFMT (1 << 4) +#define NV10_NEW_BLEND (1 << 5) +#define NV10_NEW_BLENDCOL (1 << 6) +#define NV10_NEW_RAST (1 << 7) +#define NV10_NEW_DSA (1 << 8) +#define NV10_NEW_VIEWPORT (1 << 9) +#define NV10_NEW_SCISSOR (1 << 9) +#define NV10_NEW_FRAMEBUFFER (1 << 10) + +#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; int chipset; - struct nouveau_grobj *celsius; - struct nouveau_notifier *sync; uint32_t dirty; @@ -49,6 +59,14 @@ struct nv10_context { 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 { struct pipe_buffer *buffer; uint32_t format; @@ -91,7 +109,9 @@ nv10_context(struct pipe_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_init_miptree_functions(struct pipe_screen *screen); +extern void nv10_init_miptree_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, @@ -111,6 +131,7 @@ 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); diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c index 7b7f39b80c..4dfc675a6b 100644 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -69,7 +69,7 @@ nv10_miptree_create(struct pipe_screen *screen, struct pipe_texture *pt) mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, mt->total_size); if (!mt->buffer) { - free(mt); + FREE(mt); return NULL; } @@ -90,12 +90,19 @@ nv10_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) 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->level[l].image_offset); } - free(nv10mt); + 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) @@ -122,13 +129,16 @@ nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, return ps; } -void -nv10_init_miptree_functions(struct pipe_screen *screen) + +void nv10_init_miptree_functions(struct nv10_context *nv10) { - struct nv10_screen *nv10screen = nv10_screen(screen); + nv10->pipe.texture_update = nv10_miptree_update; +} - nv10screen->screen.texture_create = nv10_miptree_create; - nv10screen->screen.texture_release = nv10_miptree_release; - nv10screen->screen.get_tex_surface = nv10_miptree_surface_get; +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; } diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c index 1526891223..bbcfe1a2fd 100644 --- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c +++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c @@ -67,6 +67,17 @@ struct nv10_vbuf_render { }; +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. */ @@ -100,7 +111,7 @@ nv10_vbuf_render_allocate_vertices( struct vbuf_render *render, assert(!nv10_render->buffer); nv10_render->buffer = winsys->buffer_create(winsys, 64, PIPE_BUFFER_USAGE_VERTEX, size); - nv10->dirty |= NV10_NEW_VBO; + nv10->dirty |= NV10_NEW_ARRAYS; return winsys->buffer_map(winsys, nv10_render->buffer, @@ -139,8 +150,8 @@ nv10_vbuf_render_draw( struct vbuf_render *render, } while (nr_indices) { - // XXX too big ? - push = MIN2(nr_indices, 2047 * 2); + // 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) diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index 4d8e0b05cc..80676ead1a 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -116,35 +116,71 @@ nv10_screen_is_format_supported(struct pipe_screen *screen, } static void -nv10_screen_destroy(struct pipe_screen *screen) +nv10_screen_destroy(struct pipe_screen *pscreen) { - FREE(screen); + 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 *winsys, struct nouveau_winsys *nvws, +nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, unsigned chipset) { - struct nv10_screen *nv10screen = CALLOC_STRUCT(nv10_screen); + struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen); + unsigned celsius_class; + int ret; - if (!nv10screen) + if (!screen) + return NULL; + screen->chipset = chipset; + 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; + } - nv10screen->chipset = chipset; - nv10screen->nvws = nvws; + screen->pipe.winsys = ws; + screen->pipe.destroy = nv10_screen_destroy; - nv10screen->screen.winsys = winsys; + 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; - nv10screen->screen.destroy = nv10_screen_destroy; + screen->pipe.is_format_supported = nv10_screen_is_format_supported; - nv10screen->screen.get_name = nv10_screen_get_name; - nv10screen->screen.get_vendor = nv10_screen_get_vendor; - nv10screen->screen.get_param = nv10_screen_get_param; - nv10screen->screen.get_paramf = nv10_screen_get_paramf; - nv10screen->screen.is_format_supported = - nv10_screen_is_format_supported; + nv10_screen_init_miptree_functions(&screen->pipe); - nv10_init_miptree_functions(&nv10screen->screen); - return &nv10screen->screen; + return &screen->pipe; } diff --git a/src/gallium/drivers/nv10/nv10_screen.h b/src/gallium/drivers/nv10/nv10_screen.h index ac8c04072a..4192fe11ef 100644 --- a/src/gallium/drivers/nv10/nv10_screen.h +++ b/src/gallium/drivers/nv10/nv10_screen.h @@ -4,10 +4,14 @@ #include "pipe/p_screen.h" struct nv10_screen { - struct pipe_screen screen; + struct pipe_screen pipe; struct nouveau_winsys *nvws; unsigned chipset; + + /* HW graphics objects */ + struct nouveau_grobj *celsius; + struct nouveau_notifier *sync; }; static INLINE struct nv10_screen * diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 1ff01de106..12722709f6 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -35,6 +35,8 @@ static void nv10_vertex_layout(struct pipe_context* pipe) } } draw_compute_vertex_size(&vinfo); + + nv10->dirty |= NV10_NEW_VTXFMT; } static void * @@ -62,27 +64,19 @@ nv10_blend_state_create(struct pipe_context *pipe, } static void -nv10_blend_state_bind(struct pipe_context *pipe, void *hwcso) +nv10_blend_state_bind(struct pipe_context *pipe, void *blend) { struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_blend_state *cb = hwcso; - - BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 1); - OUT_RING (cb->d_enable); - BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 3); - OUT_RING (cb->b_enable); - OUT_RING (cb->b_srcfunc); - OUT_RING (cb->b_dstfunc); + nv10->blend = (struct nv10_blend_state*)blend; - BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); - OUT_RING (cb->c_mask); + nv10->dirty |= NV10_NEW_BLEND; } static void nv10_blend_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + FREE(hwcso); } @@ -255,7 +249,7 @@ nv10_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) static void nv10_sampler_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + FREE(hwcso); } static void @@ -347,43 +341,19 @@ nv10_rasterizer_state_create(struct pipe_context *pipe, } static void -nv10_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) +nv10_rasterizer_state_bind(struct pipe_context *pipe, void *rast) { struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_rasterizer_state *rs = hwcso; - - BEGIN_RING(celsius, NV10TCL_SHADE_MODEL, 2); - OUT_RING (rs->shade_model); - OUT_RING (rs->line_width); - - - BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); - OUT_RING (rs->point_size); - - BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); - OUT_RING (rs->poly_mode_front); - OUT_RING (rs->poly_mode_back); - - BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); - OUT_RING (rs->cull_face); - OUT_RING (rs->front_face); + nv10->rast = (struct nv10_rasterizer_state*)rast; - BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2); - OUT_RING (rs->line_smooth_en); - OUT_RING (rs->poly_smooth_en); - - BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1); - OUT_RING (rs->cull_face_en); - -/* BEGIN_RING(celsius, NV10TCL_POINT_SPRITE, 1); - OUT_RING (rs->point_sprite);*/ + nv10->dirty |= NV10_NEW_RAST; } static void nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + FREE(hwcso); } static void * @@ -415,25 +385,19 @@ nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe, } static void -nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa) { struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_depth_stencil_alpha_state *hw = hwcso; - - BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 3); - OUT_RINGp ((uint32_t *)&hw->depth, 3); - BEGIN_RING(celsius, NV10TCL_STENCIL_ENABLE, 1); - OUT_RING (hw->stencil.enable); - BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 7); - OUT_RINGp ((uint32_t *)&(hw->stencil.wmask), 7); - BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 3); - OUT_RINGp ((uint32_t *)&hw->alpha.enabled, 3); + + 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); + FREE(hwcso); } static void * @@ -461,11 +425,11 @@ nv10_vp_state_bind(struct pipe_context *pipe, void *hwcso) static void nv10_vp_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nv10_context *nv10 = nv10_context(pipe); + //struct nv10_context *nv10 = nv10_context(pipe); struct nv10_vertex_program *vp = hwcso; //nv10_vertprog_destroy(nv10, vp); - free(vp); + FREE(vp); } static void * @@ -499,7 +463,7 @@ nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv10_fragment_program *fp = hwcso; nv10_fragprog_destroy(nv10, fp); - free(fp); + FREE(fp); } static void @@ -508,11 +472,9 @@ nv10_set_blend_color(struct pipe_context *pipe, { struct nv10_context *nv10 = nv10_context(pipe); - BEGIN_RING(celsius, NV10TCL_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)); + nv10->blend_color = (struct pipe_blend_color*)bcol; + + nv10->dirty |= NV10_NEW_BLENDCOL; } static void @@ -542,58 +504,10 @@ nv10_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct nv10_context *nv10 = nv10_context(pipe); - struct pipe_surface *rt, *zeta; - uint32_t rt_format, w, h; - int i, 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; + nv10->framebuffer = (struct pipe_framebuffer_state*)fb; - 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); - } - - BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); - OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->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); - OUT_RING (((h - 1) << 16) | 0); + nv10->dirty |= NV10_NEW_FRAMEBUFFER; } static void @@ -609,10 +523,9 @@ nv10_set_scissor_state(struct pipe_context *pipe, { struct nv10_context *nv10 = nv10_context(pipe); - // XXX -/* 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);*/ + nv10->scissor = (struct pipe_scissor_state*)s; + + nv10->dirty |= NV10_NEW_SCISSOR; } static void @@ -621,15 +534,9 @@ nv10_set_viewport_state(struct pipe_context *pipe, { struct nv10_context *nv10 = nv10_context(pipe); -/* OUT_RINGf (vpt->translate[0]); - OUT_RINGf (vpt->translate[1]); - OUT_RINGf (vpt->translate[2]); - OUT_RINGf (vpt->translate[3]);*/ - BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4); - OUT_RINGf (vpt->scale[0]); - OUT_RINGf (vpt->scale[1]); - OUT_RINGf (vpt->scale[2]); - OUT_RINGf (vpt->scale[3]); + nv10->viewport = (struct pipe_viewport_state*)vpt; + + nv10->dirty |= NV10_NEW_VIEWPORT; } static void diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c index 8bf0bd2d68..0c52496389 100644 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -1,14 +1,174 @@ +#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, 3); + OUT_RINGp ((uint32_t *)&d->depth, 3); + 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); + BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 3); + OUT_RINGp ((uint32_t *)&d->alpha.enabled, 3); +} + +static void nv10_state_emit_viewport(struct nv10_context* nv10) +{ + struct pipe_viewport_state *vpt = nv10->viewport; + +/* OUT_RINGf (vpt->translate[0]); + OUT_RINGf (vpt->translate[1]); + OUT_RINGf (vpt->translate[2]); + OUT_RINGf (vpt->translate[3]);*/ + BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4); + OUT_RINGf (vpt->scale[0]); + OUT_RINGf (vpt->scale[1]); + OUT_RINGf (vpt->scale[2]); + OUT_RINGf (vpt->scale[3]); +} + +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; + 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); + } + + BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); + OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->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); + OUT_RING (((h - 1) << 16) | 0); +} + 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)) { @@ -16,16 +176,50 @@ nv10_emit_hw_state(struct nv10_context *nv10) nv10->dirty &= ~NV10_NEW_FRAGPROG; } - if (nv10->dirty & NV10_NEW_VERTPROG) { - //nv10_vertprog_bind(nv10, nv10->vertprog.current); - nv10->dirty &= ~NV10_NEW_VERTPROG; + if (nv10->dirty & NV10_NEW_ARRAYS) { + nv10->dirty &= ~NV10_NEW_ARRAYS; + // array state will be put here once it's not emitted at each frame } - if (nv10->dirty & NV10_NEW_VBO) { - + if (nv10->dirty & NV10_NEW_VTXFMT) { + nv10->dirty &= ~NV10_NEW_VTXFMT; + nv10_vtxbuf_bind(nv10); } - nv10->dirty_samplers = 0; + 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 @@ -48,10 +242,16 @@ nv10_emit_hw_state(struct nv10_context *nv10) 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_OFFSET, 1); - OUT_RELOCl(nv10->zeta+lma_offset);*/ +/* 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))) -- cgit v1.2.3 From 8f26e975ca6341cb3366a18beb352b5cdcaee2bc Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Wed, 2 Apr 2008 15:09:32 +0200 Subject: nv10: set rasterizer state. --- src/gallium/drivers/nv10/nv10_state.c | 4 ++++ src/gallium/drivers/nv10/nv10_state.h | 2 ++ 2 files changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 12722709f6..182f6857f5 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -282,6 +282,8 @@ nv10_rasterizer_state_create(struct pipe_context *pipe, */ 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; @@ -347,6 +349,8 @@ nv10_rasterizer_state_bind(struct pipe_context *pipe, void *rast) nv10->rast = (struct nv10_rasterizer_state*)rast; + draw_set_rasterizer_state(nv10->draw, (nv10->rast ? nv10->rast->templ : NULL)); + nv10->dirty |= NV10_NEW_RAST; } diff --git a/src/gallium/drivers/nv10/nv10_state.h b/src/gallium/drivers/nv10/nv10_state.h index 9bda8a7d6a..3ca501d135 100644 --- a/src/gallium/drivers/nv10/nv10_state.h +++ b/src/gallium/drivers/nv10/nv10_state.h @@ -39,6 +39,8 @@ struct nv10_rasterizer_state { uint32_t cull_face_en; uint32_t point_sprite; + + const struct pipe_rasterizer_state *templ; }; struct nv10_vertex_program_exec { -- cgit v1.2.3 From fb19b3393fbee26f7bb88b572b3d0cc2943f2edc Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Wed, 2 Apr 2008 18:26:49 +0200 Subject: nv10: fix some more state, work on the vertex emission code. --- src/gallium/auxiliary/draw/draw_vertex_fetch.c | 2 + src/gallium/drivers/nv10/nv10_context.h | 21 +++++---- src/gallium/drivers/nv10/nv10_fragtex.c | 4 ++ src/gallium/drivers/nv10/nv10_prim_vbuf.c | 7 ++- src/gallium/drivers/nv10/nv10_state.c | 60 ++++++-------------------- src/gallium/drivers/nv10/nv10_state_emit.c | 39 ++++++++++++++--- src/gallium/drivers/nv10/nv10_vbo.c | 2 + 7 files changed, 68 insertions(+), 67 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c index 11f99babf6..9a9ac4ee45 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c @@ -508,6 +508,7 @@ void draw_update_vertex_fetch( struct draw_context *draw ) draw->vertex_fetch.nr_attrs = nr_attrs; draw->vertex_fetch.fetch_func = generic_vertex_fetch; + printf("pouet vertex fetch %x\n",draw->vertex_fetch.fetch_func); switch (nr_attrs) { case 2: @@ -524,5 +525,6 @@ void draw_update_vertex_fetch( struct draw_context *draw ) default: break; } + printf("pouet vertex fetch %x\n",draw->vertex_fetch.fetch_func); } diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index 61eb4e6a93..8c13d6897f 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -21,17 +21,16 @@ #define NOUVEAU_MSG(fmt, args...) \ fprintf(stderr, "nouveau: "fmt, ##args); -#define NV10_NEW_VERTPROG (1 << 1) -#define NV10_NEW_FRAGPROG (1 << 2) -#define NV10_NEW_ARRAYS (1 << 3) -#define NV10_NEW_VTXFMT (1 << 4) -#define NV10_NEW_BLEND (1 << 5) -#define NV10_NEW_BLENDCOL (1 << 6) -#define NV10_NEW_RAST (1 << 7) -#define NV10_NEW_DSA (1 << 8) -#define NV10_NEW_VIEWPORT (1 << 9) -#define NV10_NEW_SCISSOR (1 << 9) -#define NV10_NEW_FRAMEBUFFER (1 << 10) +#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" diff --git a/src/gallium/drivers/nv10/nv10_fragtex.c b/src/gallium/drivers/nv10/nv10_fragtex.c index a4bf108284..67e0b4bd45 100644 --- a/src/gallium/drivers/nv10/nv10_fragtex.c +++ b/src/gallium/drivers/nv10/nv10_fragtex.c @@ -72,6 +72,7 @@ nv10_fragtex_format(uint pipe_format) 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; @@ -115,11 +116,13 @@ nv10_fragtex_build(struct nv10_context *nv10, int unit) 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; @@ -141,5 +144,6 @@ nv10_fragtex_bind(struct nv10_context *nv10) } nv10->fp_samplers = fp->samplers; +#endif } diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c index bbcfe1a2fd..412ee9a23f 100644 --- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c +++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c @@ -94,6 +94,9 @@ 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; } @@ -111,7 +114,7 @@ nv10_vbuf_render_allocate_vertices( struct vbuf_render *render, assert(!nv10_render->buffer); nv10_render->buffer = winsys->buffer_create(winsys, 64, PIPE_BUFFER_USAGE_VERTEX, size); - nv10->dirty |= NV10_NEW_ARRAYS; + nv10->dirty |= NV10_NEW_VTXARRAYS; return winsys->buffer_map(winsys, nv10_render->buffer, @@ -137,6 +140,8 @@ nv10_vbuf_render_draw( struct 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); diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 182f6857f5..924cf803ac 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -1,3 +1,4 @@ +#include "draw/draw_context.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" @@ -7,38 +8,6 @@ #include "nv10_context.h" #include "nv10_state.h" -static void nv10_vertex_layout(struct pipe_context* pipe) -{ - struct nv10_context *nv10 = nv10_context(pipe); - 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); - - nv10->dirty |= NV10_NEW_VTXFMT; -} - static void * nv10_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) @@ -406,34 +375,29 @@ nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) static void * nv10_vp_state_create(struct pipe_context *pipe, - const struct pipe_shader_state *cso) + const struct pipe_shader_state *templ) { - struct nv10_vertex_program *vp; - - vp = CALLOC(1, sizeof(struct nv10_vertex_program)); - vp->pipe = cso; + struct nv10_context *nv10 = nv10_context(pipe); - return (void *)vp; + return draw_create_vertex_shader(nv10->draw, templ); } static void -nv10_vp_state_bind(struct pipe_context *pipe, void *hwcso) +nv10_vp_state_bind(struct pipe_context *pipe, void *shader) { struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_vertex_program *vp = hwcso; - nv10->vertprog.current = vp; + 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 *hwcso) +nv10_vp_state_delete(struct pipe_context *pipe, void *shader) { - //struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_vertex_program *vp = hwcso; + struct nv10_context *nv10 = nv10_context(pipe); - //nv10_vertprog_destroy(nv10, vp); - FREE(vp); + draw_delete_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader); } static void * @@ -550,7 +514,7 @@ nv10_set_vertex_buffers(struct pipe_context *pipe, unsigned count, struct nv10_context *nv10 = nv10_context(pipe); memcpy(nv10->vtxbuf, vb, sizeof(*vb) * count); - nv10->dirty |= NV10_NEW_ARRAYS; + nv10->dirty |= NV10_NEW_VTXARRAYS; } static void @@ -560,7 +524,7 @@ nv10_set_vertex_elements(struct pipe_context *pipe, unsigned count, struct nv10_context *nv10 = nv10_context(pipe); memcpy(nv10->vtxelt, ve, sizeof(*ve) * count); - nv10->dirty |= NV10_NEW_ARRAYS; + nv10->dirty |= NV10_NEW_VTXARRAYS; } void diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c index 0c52496389..134e52bd62 100644 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -154,6 +154,35 @@ static void nv10_state_emit_framebuffer(struct nv10_context* nv10) OUT_RING (((h - 1) << 16) | 0); } +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) { @@ -176,13 +205,9 @@ nv10_emit_hw_state(struct nv10_context *nv10) nv10->dirty &= ~NV10_NEW_FRAGPROG; } - if (nv10->dirty & NV10_NEW_ARRAYS) { - nv10->dirty &= ~NV10_NEW_ARRAYS; - // array state will be put here once it's not emitted at each frame - } - - if (nv10->dirty & NV10_NEW_VTXFMT) { - nv10->dirty &= ~NV10_NEW_VTXFMT; + if (nv10->dirty & NV10_NEW_VTXARRAYS) { + nv10->dirty &= ~NV10_NEW_VTXARRAYS; + nv10_vertex_layout(nv10); nv10_vtxbuf_bind(nv10); } diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c index 025ad6de4b..0f5902602f 100644 --- a/src/gallium/drivers/nv10/nv10_vbo.c +++ b/src/gallium/drivers/nv10/nv10_vbo.c @@ -18,6 +18,8 @@ boolean nv10_draw_elements( struct pipe_context *pipe, struct draw_context *draw = nv10->draw; unsigned i; + nv10_emit_hw_state(nv10); + /* * Map vertex buffers */ -- cgit v1.2.3 From d3340cda9c2ee7165961517494f636e3fa361d5f Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Wed, 2 Apr 2008 18:28:44 +0200 Subject: don't push "pouets" --- src/gallium/auxiliary/draw/draw_vertex_fetch.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c index 9a9ac4ee45..11f99babf6 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c @@ -508,7 +508,6 @@ void draw_update_vertex_fetch( struct draw_context *draw ) draw->vertex_fetch.nr_attrs = nr_attrs; draw->vertex_fetch.fetch_func = generic_vertex_fetch; - printf("pouet vertex fetch %x\n",draw->vertex_fetch.fetch_func); switch (nr_attrs) { case 2: @@ -525,6 +524,5 @@ void draw_update_vertex_fetch( struct draw_context *draw ) default: break; } - printf("pouet vertex fetch %x\n",draw->vertex_fetch.fetch_func); } -- cgit v1.2.3 From 7f21b63a988a041bca120751c795f6f6abf0f2bd Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 3 Apr 2008 04:07:16 +0200 Subject: nv10: fix more vertex stuff --- src/gallium/drivers/nv10/nv10_context.h | 8 ++++---- src/gallium/drivers/nv10/nv10_state.c | 13 +++++++++++-- src/gallium/drivers/nv10/nv10_state_emit.c | 10 ++++++++-- src/gallium/drivers/nv10/nv10_vbo.c | 2 ++ 4 files changed, 25 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index 8c13d6897f..63d33ef7c9 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -65,6 +65,8 @@ struct nv10_context { struct pipe_viewport_state *viewport; struct pipe_scissor_state *scissor; struct pipe_framebuffer_state *framebuffer; + struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + struct vertex_info vertex_info; struct { struct pipe_buffer *buffer; @@ -77,8 +79,7 @@ struct nv10_context { unsigned delta; } vb[16]; - struct vertex_info vertex_info; - struct { +/* struct { struct nouveau_resource *exec_heap; struct nouveau_resource *data_heap; @@ -86,9 +87,8 @@ struct nv10_context { struct nv10_vertex_program *active; struct nv10_vertex_program *current; - struct pipe_buffer *constant_buf; } vertprog; - +*/ struct { struct nv10_fragment_program *active; diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 924cf803ac..1d9a202dd7 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -449,6 +449,9 @@ 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 @@ -458,11 +461,11 @@ nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct nv10_context *nv10 = nv10_context(pipe); if (shader == PIPE_SHADER_VERTEX) { - nv10->vertprog.constant_buf = buf->buffer; + nv10->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; nv10->dirty |= NV10_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { - nv10->fragprog.constant_buf = buf->buffer; + nv10->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; nv10->dirty |= NV10_NEW_FRAGPROG; } } @@ -504,6 +507,8 @@ nv10_set_viewport_state(struct pipe_context *pipe, nv10->viewport = (struct pipe_viewport_state*)vpt; + draw_set_viewport_state(nv10->draw, &nv10->viewport); + nv10->dirty |= NV10_NEW_VIEWPORT; } @@ -515,6 +520,8 @@ nv10_set_vertex_buffers(struct pipe_context *pipe, unsigned count, memcpy(nv10->vtxbuf, vb, sizeof(*vb) * count); nv10->dirty |= NV10_NEW_VTXARRAYS; + + draw_set_vertex_buffers(nv10->draw, count, vb); } static void @@ -525,6 +532,8 @@ nv10_set_vertex_elements(struct pipe_context *pipe, unsigned count, memcpy(nv10->vtxelt, ve, sizeof(*ve) * count); nv10->dirty |= NV10_NEW_VTXARRAYS; + + draw_set_vertex_elements(nv10->draw, count, ve); } void diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c index 134e52bd62..18566986b0 100644 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -136,8 +136,14 @@ static void nv10_state_emit_framebuffer(struct nv10_context* nv10) assert(0); } - BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); - OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->cpp) << 16) ); + 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) ); + } + nv10->rt[0] = rt->buffer; if (zeta_format) diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c index 0f5902602f..3a4f49e156 100644 --- a/src/gallium/drivers/nv10/nv10_vbo.c +++ b/src/gallium/drivers/nv10/nv10_vbo.c @@ -44,6 +44,8 @@ boolean nv10_draw_elements( struct pipe_context *pipe, draw_set_mapped_element_buffer(draw, 0, NULL); } + draw_set_mapped_constant_buffer(draw, nv10->constbuf[PIPE_SHADER_VERTEX]); + /* draw! */ draw_arrays(nv10->draw, prim, start, count); -- cgit v1.2.3 From 8ed894bd17bd6f426a0d87f7113f23043cda3bc3 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 3 Apr 2008 04:20:22 +0200 Subject: nv10: emit dummy zeta size when no zbuffer is used. --- src/gallium/drivers/nv10/nv10_state_emit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c index 18566986b0..edc194588d 100644 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -141,7 +141,7 @@ static void nv10_state_emit_framebuffer(struct nv10_context* nv10) 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) ); + OUT_RING ( (rt->pitch * rt->cpp) | ( (rt->pitch * rt->cpp) << 16) ); } nv10->rt[0] = rt->buffer; -- cgit v1.2.3 From 73322bba5c7102f0e100c9a07273a7a87705cf55 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 28 Mar 2008 23:51:24 +1100 Subject: nv40: need to resubmit buffers if pushbuf gets flushed during draw --- src/gallium/drivers/nouveau/nouveau_util.h | 64 +++++++++++++++ src/gallium/drivers/nv40/nv40_vbo.c | 120 ++++++++++++++++++----------- 2 files changed, 140 insertions(+), 44 deletions(-) create mode 100644 src/gallium/drivers/nouveau/nouveau_util.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_util.h b/src/gallium/drivers/nouveau/nouveau_util.h new file mode 100644 index 0000000000..c92041ebeb --- /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/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index bc53924a67..33d3efb58d 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -7,6 +7,7 @@ #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_pushbuf.h" +#include "nouveau/nouveau_util.h" #define FORCE_SWTNL 0 @@ -170,44 +171,60 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, } boolean -nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, - unsigned count) +nv40_draw_arrays(struct pipe_context *pipe, + unsigned mode, unsigned start, unsigned count) { struct nv40_context *nv40 = nv40_context(pipe); - unsigned nr; + 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); } - nv40_state_emit(nv40); - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (nvgl_primitive(mode)); + while (count) { + unsigned vc, nr; - nr = (count & 0xff); - if (nr) { - BEGIN_RING(curie, NV40TCL_VB_VERTEX_BATCH, 1); - OUT_RING (((nr - 1) << 24) | start); - start += nr; - } + nv40_state_emit(nv40); - nr = count >> 8; - while (nr) { - unsigned push = nr > 2047 ? 2047 : nr; + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + mode, start, count, &restart); + if (!vc) { + FIRE_RING(NULL); + continue; + } - nr -= push; + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); - BEGIN_RING_NI(curie, NV40TCL_VB_VERTEX_BATCH, push); - while (push--) { - OUT_RING(((0x100 - 1) << 24) | start); - start += 0x100; + nr = (vc & 0xff); + if (nr) { + BEGIN_RING(curie, NV40TCL_VB_VERTEX_BATCH, 1); + OUT_RING (((nr - 1) << 24) | start); + start += nr; } - } - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (0); + 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; @@ -329,35 +346,50 @@ nv40_draw_elements_vbo(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { struct nv40_context *nv40 = nv40_context(pipe); - unsigned nr; + struct nouveau_channel *chan = nv40->nvws->channel; + unsigned restart; - nv40_state_emit(nv40); + while (count) { + unsigned nr, vc; - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (nvgl_primitive(mode)); + nv40_state_emit(nv40); - nr = (count & 0xff); - if (nr) { - BEGIN_RING(curie, NV40TCL_VB_INDEX_BATCH, 1); - OUT_RING (((nr - 1) << 24) | start); - start += nr; - } + 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 = count >> 8; - while (nr) { - unsigned push = nr > 2047 ? 2047 : nr; + nr = vc >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; - nr -= push; + nr -= push; - BEGIN_RING_NI(curie, NV40TCL_VB_INDEX_BATCH, push); - while (push--) { - OUT_RING(((0x100 - 1) << 24) | start); - start += 0x100; + 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); + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + count -= vc; + start = restart; + } return TRUE; } -- cgit v1.2.3 From 7e9b83ac0ac59298f1b983e6a9aed3a8f2ccb147 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 29 Mar 2008 00:30:04 +1100 Subject: nv40: convert the inline idxbuf paths also --- src/gallium/drivers/nv40/nv40_vbo.c | 159 +++++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 48 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 33d3efb58d..8cc977a19a 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -232,69 +232,139 @@ nv40_draw_arrays(struct pipe_context *pipe, static INLINE void nv40_draw_elements_u08(struct nv40_context *nv40, void *ib, - unsigned start, unsigned count) + unsigned mode, unsigned start, unsigned count) { - uint8_t *elts = (uint8_t *)ib + start; - int push, i; - - if (count & 1) { - BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); - OUT_RING (elts[0]); - elts++; count--; - } + struct nouveau_channel *chan = nv40->nvws->channel; while (count) { - push = MIN2(count, 2047 * 2); + 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]); + 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]); - count -= push; - elts += push; + 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 start, unsigned count) + unsigned mode, unsigned start, unsigned count) { - uint16_t *elts = (uint16_t *)ib + start; - int push, i; - - if (count & 1) { - BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1); - OUT_RING (elts[0]); - elts++; count--; - } + struct nouveau_channel *chan = nv40->nvws->channel; while (count) { - push = MIN2(count, 2047 * 2); + uint16_t *elts = (uint16_t *)ib + start; + unsigned vc, push, restart; - 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]); + nv40_state_emit(nv40); - count -= push; - elts += push; + 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 start, unsigned count) + unsigned mode, unsigned start, unsigned count) { - uint32_t *elts = (uint32_t *)ib + start; - int push; + struct nouveau_channel *chan = nv40->nvws->channel; while (count) { - push = MIN2(count, 2047); + 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); + BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U32, push); + OUT_RINGp (elts, push); - count -= push; - elts += push; + vc -= push; + elts += push; + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (0); + + start = restart; } } @@ -315,29 +385,22 @@ nv40_draw_elements_inline(struct pipe_context *pipe, return FALSE; } - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (nvgl_primitive(mode)); - switch (ib_size) { case 1: - nv40_draw_elements_u08(nv40, map, start, count); + nv40_draw_elements_u08(nv40, map, mode, start, count); break; case 2: - nv40_draw_elements_u16(nv40, map, start, count); + nv40_draw_elements_u16(nv40, map, mode, start, count); break; case 4: - nv40_draw_elements_u32(nv40, map, start, count); + nv40_draw_elements_u32(nv40, map, mode, start, count); break; default: NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); break; } - BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); - OUT_RING (0); - ws->buffer_unmap(ws, ib); - return TRUE; } -- cgit v1.2.3 From 6fbc50e013f1ac7684d8d63d9433f6dd72b4c1cb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 3 Apr 2008 08:21:56 +1000 Subject: nv40: static attribs -> stateobj --- src/gallium/drivers/nv40/nv40_context.h | 3 +- src/gallium/drivers/nv40/nv40_state_emit.c | 3 +- src/gallium/drivers/nv40/nv40_vbo.c | 62 ++++++++++++++++-------------- 3 files changed, 38 insertions(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 525eef8d63..a1b5c88a06 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -56,7 +56,8 @@ enum nv40_state_index { NV40_STATE_VERTTEX3 = 30, NV40_STATE_VTXBUF = 31, NV40_STATE_VTXFMT = 32, - NV40_STATE_MAX = 33 + NV40_STATE_VTXATTR = 33, + NV40_STATE_MAX = 34 }; #include "nv40_screen.h" diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 722b9f31e6..c742e4f421 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -82,7 +82,8 @@ nv40_state_emit(struct nv40_context *nv40) if (!(states & (1ULL << i))) continue; so_ref (state->hw[i], &nv40->screen->state[i]); - so_emit(nv40->nvws, nv40->screen->state[i]); + if (state->hw[i]) + so_emit(nv40->nvws, nv40->screen->state[i]); states &= ~(1ULL << i); } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 8cc977a19a..e5ee5f3c47 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -109,11 +109,12 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, } static boolean -nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, - struct pipe_vertex_element *ve, +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; @@ -128,31 +129,28 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib, { float *v = map; - BEGIN_RING(curie, NV40TCL_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]); + 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: - OUT_RINGf(v[0]); - OUT_RINGf(v[1]); - OUT_RINGf(v[2]); - OUT_RINGf(1.0); + 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: - OUT_RINGf(v[0]); - OUT_RINGf(v[1]); - OUT_RINGf(0.0); - OUT_RINGf(1.0); + 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: - OUT_RINGf(v[0]); - OUT_RINGf(0.0); - OUT_RINGf(0.0); - OUT_RINGf(1.0); + so_method(so, curie, 0x1e40 + (attrib * 4), 1); + so_data (so, fui(v[0])); break; default: ws->buffer_unmap(ws, vb->buffer); @@ -487,7 +485,8 @@ static boolean nv40_vbo_validate(struct nv40_context *nv40) { struct nv40_vertex_program *vp = nv40->vertprog; - struct nouveau_stateobj *vtxbuf, *vtxfmt; + 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 inputs, hw, num_hw; @@ -503,9 +502,9 @@ nv40_vbo_validate(struct nv40_context *nv40) num_hw++; vtxbuf = so_new(20, 18); - so_method(vtxbuf, nv40->screen->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); vtxfmt = so_new(17, 0); - so_method(vtxfmt, nv40->screen->curie, NV40TCL_VTXFMT(0), num_hw); + so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), num_hw); inputs = vp->ir; for (hw = 0; hw < num_hw; hw++) { @@ -522,10 +521,15 @@ nv40_vbo_validate(struct nv40_context *nv40) ve = &nv40->vtxelt[hw]; vb = &nv40->vtxbuf[ve->vertex_buffer_index]; - if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) { - so_data(vtxbuf, 0); - so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); - continue; + 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)) { @@ -543,19 +547,21 @@ nv40_vbo_validate(struct nv40_context *nv40) } if (ib) { - so_method(vtxbuf, nv40->screen->curie, NV40TCL_IDXBUF_ADDRESS, 2); + 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, nv40->screen->curie, 0x1710, 1); + 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; } -- cgit v1.2.3 From 0b57662fa6feb3d4571e4a3bc3a2243547595816 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 3 Apr 2008 09:39:00 +1000 Subject: nv40: remove redundant state_emit() calls --- src/gallium/drivers/nv40/nv40_vbo.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index e5ee5f3c47..8c446936ea 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -375,8 +375,6 @@ nv40_draw_elements_inline(struct pipe_context *pipe, struct pipe_winsys *ws = pipe->winsys; void *map; - nv40_state_emit(nv40); - map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { NOUVEAU_ERR("failed mapping ib\n"); @@ -468,7 +466,6 @@ nv40_draw_elements(struct pipe_context *pipe, return nv40_draw_elements_swtnl(pipe, NULL, 0, mode, start, count); } - nv40_state_emit(nv40); if (idxbuf) { nv40_draw_elements_vbo(pipe, mode, start, count); -- cgit v1.2.3 From fbb6cc7842ec8a59b60018233275babc4deb6765 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Apr 2008 12:39:45 +1000 Subject: nouveau: in some cases don't create the buffer in local mem initially. --- src/gallium/drivers/nouveau/nouveau_winsys.h | 5 +++++ src/gallium/drivers/nv10/nv10_screen.c | 3 +++ src/gallium/drivers/nv30/nv30_screen.c | 3 +++ src/gallium/drivers/nv40/nv40_miptree.c | 4 +++- src/gallium/drivers/nv40/nv40_screen.c | 8 ++++++++ src/gallium/drivers/nv50/nv50_screen.c | 3 +++ src/gallium/winsys/dri/nouveau/nouveau_context.c | 11 ++++++++++- src/gallium/winsys/dri/nouveau/nouveau_context.h | 5 +++++ src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 2 ++ .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 22 ++++++++++++++++++++-- 10 files changed, 62 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 2a5305f7ce..fbde7adc6a 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -13,6 +13,11 @@ #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; diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index 80676ead1a..45fbde62ea 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -50,6 +50,9 @@ nv10_screen_get_param(struct pipe_screen *screen, int param) 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; diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 3ca50e4fbf..c7487b37bc 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -50,6 +50,9 @@ nv30_screen_get_param(struct pipe_screen *screen, int param) 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; diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 502edc1629..1b19217223 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -68,7 +68,9 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) nv40_miptree_layout(mt); - mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + mt->buffer = ws->buffer_create(ws, 256, + PIPE_BUFFER_USAGE_PIXEL | + NOUVEAU_BUFFER_USAGE_TEXTURE, mt->total_size); if (!mt->buffer) { FREE(mt); diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index e98005f749..a408d7262f 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -27,6 +27,8 @@ nv40_screen_get_vendor(struct pipe_screen *pscreen) 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; @@ -54,6 +56,12 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) 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; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 586373a5c4..adb724b9b7 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -63,6 +63,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) 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; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index cf1d83b18f..aaeaebd271 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -7,6 +7,7 @@ #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" @@ -133,7 +134,7 @@ nouveau_context_create(const __GLcontextModes *glVis, /* G80 */ break; default: - NOUVEAU_ERR("Unsupported chipset: NV%02x\n", nv->chipset); + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", (int)nv->chipset); return GL_FALSE; } @@ -255,9 +256,17 @@ nouveau_context_create(const __GLcontextModes *glVis, } 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) { diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 92f551855a..acb58fab44 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -56,6 +56,11 @@ struct nouveau_context { 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; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c index 2e3ac5492f..78919bdee8 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -137,6 +137,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) 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; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index b1bf9c521a..849e38d22b 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -79,9 +79,10 @@ 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_device *dev = nvpws->nv->nv_screen->device; + struct nouveau_context *nv = nvpws->nv; + struct nouveau_device *dev = nv->nv_screen->device; struct nouveau_pipe_buffer *nvbuf; - uint32_t flags = 0; + uint32_t flags; nvbuf = calloc(1, sizeof(*nvbuf)); if (!nvbuf) @@ -92,6 +93,23 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, 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; -- cgit v1.2.3 From a45a12e757a8f4d41daea2a3f632d4772ff69e38 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Apr 2008 13:02:37 +1000 Subject: nv40: have test for hw idxbuf in single place --- src/gallium/drivers/nv40/nv40_vbo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 8c446936ea..ec88470b31 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -75,6 +75,7 @@ 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) { @@ -83,8 +84,7 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, return FALSE; } - /* No support for 8bit indices, no support at all on 0x4497 chips */ - if (nv40->screen->curie->grclass == NV44TCL || ib_size == 1) + if (!pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF) || ib_size == 1) return FALSE; switch (ib_size) { -- cgit v1.2.3 From bc67533f29abe578e2306be2a24db392a0c62fc4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Apr 2008 16:14:15 +1000 Subject: nouveau: create swizzled surface + scaled image objects --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 2 + src/gallium/winsys/dri/nouveau/nouveau_context.h | 7 +++- src/gallium/winsys/dri/nouveau/nv04_surface.c | 48 ++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index aaeaebd271..ff08a870db 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -32,6 +32,8 @@ nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) 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); diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index acb58fab44..872ef93807 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -27,11 +27,16 @@ struct nouveau_channel_context { struct nouveau_notifier *sync_notifier; + /* Common */ struct nouveau_grobj *NvNull; + 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 *NvM2MF; + struct nouveau_grobj *NvSIFM; + /* G80 */ struct nouveau_grobj *Nv2D; uint32_t next_handle; diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index cdcd71eaad..f61bd1477f 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -237,6 +237,54 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + switch (nvc->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 (nvc->chipset < 0x10) { + class = NV04_SCALED_IMAGE_FROM_MEMORY; + } else + if (nvc->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; } -- cgit v1.2.3 From 2946a5a012f494bad280a0ecf082d81ed4e89c3b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Apr 2008 20:32:06 +1000 Subject: nv40: kill some warnings --- src/gallium/drivers/nv40/nv40_state.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 5dc2991212..997beca883 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -421,7 +421,6 @@ static void nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_rasterizer_state *rsso = hwcso; nv40->rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; @@ -527,7 +526,6 @@ static void nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_vertex_program *vp = hwcso; nv40->vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; -- cgit v1.2.3 From 2655f6901289bcfe3835cf28d7b9eefa242045b8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Apr 2008 20:10:40 +1000 Subject: nv40: implement user clip planes It turns out the user planes handed to the driver are already in clip space. Hence, we no longer need to transform incoming vertices before computing the clip distance, and no longer need to change the interface provided by gallium. Yay :) The clip state change handling could be better, but this works. --- src/gallium/drivers/nv40/Makefile | 1 - src/gallium/drivers/nv40/nv40_context.h | 4 - src/gallium/drivers/nv40/nv40_draw.c | 2 +- src/gallium/drivers/nv40/nv40_state.h | 3 + src/gallium/drivers/nv40/nv40_state_clip.c | 22 ---- src/gallium/drivers/nv40/nv40_state_emit.c | 8 +- src/gallium/drivers/nv40/nv40_vertprog.c | 159 +++++++++++++++-------------- 7 files changed, 87 insertions(+), 112 deletions(-) delete mode 100644 src/gallium/drivers/nv40/nv40_state_clip.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile index 3369a21574..9c8eadf7e4 100644 --- a/src/gallium/drivers/nv40/Makefile +++ b/src/gallium/drivers/nv40/Makefile @@ -14,7 +14,6 @@ DRIVER_SOURCES = \ nv40_screen.c \ nv40_state.c \ nv40_state_blend.c \ - nv40_state_clip.c \ nv40_state_emit.c \ nv40_state_fb.c \ nv40_state_rasterizer.c \ diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index a1b5c88a06..436351b6bc 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -76,9 +76,6 @@ enum nv40_state_index { #define NV40_NEW_ARRAYS (1 << 11) #define NV40_NEW_UCP (1 << 12) -#define NV40_FALLBACK_TNL (1 << 0) -#define NV40_FALLBACK_RAST (1 << 1) - struct nv40_rasterizer_state { struct pipe_rasterizer_state pipe; struct nouveau_stateobj *so; @@ -203,7 +200,6 @@ extern void nv40_fragtex_bind(struct nv40_context *); 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_clip; extern struct nv40_state_entry nv40_state_rasterizer; extern struct nv40_state_entry nv40_state_scissor; extern struct nv40_state_entry nv40_state_stipple; diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 9cd8fa6a49..7f008aca3a 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -236,7 +236,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, if (!nv40_state_validate_swtnl(nv40)) return FALSE; - nv40->dirty &= ~(1ULL << NV40_STATE_VTXBUF); + nv40->state.dirty &= ~(1ULL << NV40_STATE_VTXBUF); nv40_state_emit(nv40); for (i = 0; i < PIPE_ATTRIB_MAX; i++) { diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index e018464c9f..2b4225deb2 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -29,6 +29,9 @@ struct nv40_vertex_program { 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; diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c deleted file mode 100644 index c52390f9ed..0000000000 --- a/src/gallium/drivers/nv40/nv40_state_clip.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "nv40_context.h" - -static boolean -nv40_state_clip_validate(struct nv40_context *nv40) -{ - - if (nv40->render_mode == HW) { - nv40->fallback_swtnl &= ~NV40_NEW_UCP; - if (nv40->clip.nr) - nv40->fallback_swtnl |= NV40_NEW_UCP; - } - - return FALSE; -} - -struct nv40_state_entry nv40_state_clip = { - .validate = nv40_state_clip_validate, - .dirty = { - .pipe = NV40_NEW_UCP, - .hw = 0 - } -}; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index c742e4f421..864dfc2e0c 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -5,7 +5,6 @@ static struct nv40_state_entry *render_states[] = { &nv40_state_framebuffer, &nv40_state_rasterizer, - &nv40_state_clip, &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, @@ -22,7 +21,6 @@ static struct nv40_state_entry *render_states[] = { static struct nv40_state_entry *swtnl_states[] = { &nv40_state_framebuffer, &nv40_state_rasterizer, - &nv40_state_clip, &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, @@ -127,8 +125,7 @@ nv40_state_validate(struct nv40_context *nv40) nv40->pipe.flush(&nv40->pipe, 0, NULL); nv40->dirty |= (NV40_NEW_VIEWPORT | NV40_NEW_VERTPROG | - NV40_NEW_ARRAYS | - NV40_NEW_UCP); + NV40_NEW_ARRAYS); nv40->render_mode = HW; } @@ -153,8 +150,7 @@ nv40_state_validate_swtnl(struct nv40_context *nv40) nv40->pipe.flush(&nv40->pipe, 0, NULL); nv40->dirty |= (NV40_NEW_VIEWPORT | NV40_NEW_VERTPROG | - NV40_NEW_ARRAYS | - NV40_NEW_UCP); + NV40_NEW_ARRAYS); nv40->render_mode = SWTNL; } diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 08d3f387e0..e10250528e 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -52,6 +52,8 @@ struct nv40_vpc { struct nv40_sreg *imm; unsigned nr_imm; + + unsigned hpos_idx; }; static struct nv40_sreg @@ -423,11 +425,6 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, int ai = -1, ci = -1, ii = -1; int i; - struct { - struct nv40_sreg dst; - unsigned m; - } clip; - if (finst->Instruction.Opcode == TGSI_OPCODE_END) return TRUE; @@ -501,47 +498,6 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, dst = tgsi_dst(vpc, &finst->FullDstRegisters[0]); mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask); - /* If writing to clip distance regs, need to modify instruction to - * change which component is written to. On NV40 the clip regs - * are the unused components (yzw) of FOGC/PSZ. - */ - clip.dst = none; - if (dst.type == NV40SR_OUTPUT && - dst.index >= NV40_VP_INST_DEST_CLIP(0) && - dst.index <= NV40_VP_INST_DEST_CLIP(5)) { - unsigned n = dst.index - NV40_VP_INST_DEST_CLIP(0); - unsigned m[] = - { MASK_Y, MASK_Z, MASK_W, MASK_Y, MASK_Z, MASK_W }; - - /* Some instructions we can get away with swizzling and/or - * changing the writemask. Others, we'll use a temp reg. - */ - switch (finst->Instruction.Opcode) { - case TGSI_OPCODE_DST: - case TGSI_OPCODE_EXP: - case TGSI_OPCODE_LIT: - case TGSI_OPCODE_LOG: - case TGSI_OPCODE_XPD: - clip.dst = dst; - clip.m = m[n]; - dst = temp(vpc); - break; - case TGSI_OPCODE_DP3: - case TGSI_OPCODE_DP4: - case TGSI_OPCODE_DPH: - case TGSI_OPCODE_POW: - case TGSI_OPCODE_RCP: - case TGSI_OPCODE_RSQ: - mask = m[n]; - break; - default: - for (i = 0; i < finst->Instruction.NumSrcRegs; i++) - src[i] = swz(src[i], X, X, X, X); - mask = m[n]; - break; - } - } - switch (finst->Instruction.Opcode) { case TGSI_OPCODE_ABS: arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none); @@ -639,11 +595,6 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc, return FALSE; } - if (clip.dst.type != NV40SR_NONE) { - arith(vpc, 0, OP_MOV, clip.dst, clip.m, - swz(dst, X, X, X, X), none, none); - } - release_temps(vpc); return TRUE; } @@ -658,6 +609,7 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, 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) { @@ -695,15 +647,6 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, return FALSE; } break; -#if 0 - case TGSI_SEMANTIC_CLIP: - if (fdec->Semantic.SemanticIndex >= 6) { - NOUVEAU_ERR("bad clip distance index\n"); - return FALSE; - } - hw = NV40_VP_INST_DEST_CLIP(fdec->Semantic.SemanticIndex); - break; -#endif default: NOUVEAU_ERR("bad output semantic\n"); return FALSE; @@ -748,6 +691,10 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) } break; #endif + case TGSI_FILE_OUTPUT: + if (!nv40_vertprog_parse_decl_output(vpc, fdec)) + return FALSE; + break; default: break; } @@ -803,6 +750,8 @@ nv40_vertprog_translate(struct nv40_context *nv40, { 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) @@ -814,26 +763,21 @@ nv40_vertprog_translate(struct nv40_context *nv40, 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_DECLARATION: - { - const struct tgsi_full_declaration *fdec; - fdec = &parse.FullToken.FullDeclaration; - switch (fdec->Declaration.File) { - case TGSI_FILE_OUTPUT: - if (!nv40_vertprog_parse_decl_output(vpc, fdec)) - goto out_err; - break; - default: - break; - } - } - break; case TGSI_TOKEN_TYPE_IMMEDIATE: { const struct tgsi_full_immediate *imm; @@ -862,6 +806,39 @@ nv40_vertprog_translate(struct nv40_context *nv40, } } + /* 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: @@ -883,6 +860,12 @@ nv40_vertprog_validate(struct nv40_context *nv40) 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; @@ -1045,16 +1028,36 @@ check_gpu_resources: void nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp) { - if (vp->nr_consts) - FREE(vp->consts); - if (vp->nr_insns) + 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, + .pipe = NV40_NEW_VERTPROG | NV40_NEW_UCP, .hw = NV40_STATE_VERTPROG, } }; -- cgit v1.2.3 From bdfcce47921cdd808740ee26e6781837351bad98 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 9 Apr 2008 13:58:51 +1000 Subject: nv40: use vb/ve counts rather than shader inputs for related loops --- src/gallium/drivers/nv40/nv40_draw.c | 9 ++------- src/gallium/drivers/nv40/nv40_vbo.c | 25 ++++--------------------- 2 files changed, 6 insertions(+), 28 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 7f008aca3a..dd5cc8fc99 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -239,9 +239,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, nv40->state.dirty &= ~(1ULL << NV40_STATE_VTXBUF); nv40_state_emit(nv40); - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { - if (!nv40->vtxbuf[i].buffer) - continue; + 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); @@ -262,11 +260,8 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, draw_arrays(nv40->draw, mode, start, count); - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { - if (!nv40->vtxbuf[i].buffer) - continue; + for (i = 0; i < nv40->vtxbuf_nr; i++) ws->buffer_unmap(ws, nv40->vtxbuf[i].buffer); - } if (idxbuf) ws->buffer_unmap(ws, idxbuf); diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index ec88470b31..06374184b1 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -481,40 +481,23 @@ nv40_draw_elements(struct pipe_context *pipe, static boolean nv40_vbo_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->vertprog; 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 inputs, hw, num_hw; unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; - - inputs = vp->ir; - for (hw = 0; hw < 16 && inputs; hw++) { - if (inputs & (1 << hw)) { - num_hw = hw; - inputs &= ~(1 << hw); - } - } - num_hw++; + int hw; vtxbuf = so_new(20, 18); - so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt_nr); vtxfmt = so_new(17, 0); - so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), num_hw); + so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt_nr); - inputs = vp->ir; - for (hw = 0; hw < num_hw; hw++) { + for (hw = 0; hw < nv40->vtxelt_nr; hw++) { struct pipe_vertex_element *ve; struct pipe_vertex_buffer *vb; unsigned type, ncomp; - if (!(inputs & (1 << hw))) { - so_data(vtxbuf, 0); - so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT); - continue; - } - ve = &nv40->vtxelt[hw]; vb = &nv40->vtxbuf[ve->vertex_buffer_index]; -- cgit v1.2.3 From b1de9c948f9794db97ed7d34b8cbcdccc206ea77 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 11 Apr 2008 21:37:28 +0200 Subject: nv30: Set pipe status on clear --- src/gallium/drivers/nv30/nv30_clear.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_clear.c b/src/gallium/drivers/nv30/nv30_clear.c index 71f413588e..8c3ca204d5 100644 --- a/src/gallium/drivers/nv30/nv30_clear.c +++ b/src/gallium/drivers/nv30/nv30_clear.c @@ -9,4 +9,5 @@ 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; } -- cgit v1.2.3 From 4c498c1b0c38a3ba93649fa4435937d15689bae1 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 11 Apr 2008 21:37:41 +0200 Subject: nv30: Do flip --- src/gallium/drivers/nv30/nv30_surface.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_surface.c b/src/gallium/drivers/nv30/nv30_surface.c index b20a3dd4c1..b22211ac86 100644 --- a/src/gallium/drivers/nv30/nv30_surface.c +++ b/src/gallium/drivers/nv30/nv30_surface.c @@ -42,8 +42,20 @@ nv30_surface_copy(struct pipe_context *pipe, unsigned do_flip, struct nv30_context *nv30 = nv30_context(pipe); struct nouveau_winsys *nvws = nv30->nvws; - nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, - width, height); + 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 -- cgit v1.2.3 From 186277ee928a7c9ad8a31776f93e502613ad94fd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 11 Apr 2008 23:39:29 +0200 Subject: nv30: Move some structures and functions from context to screen --- src/gallium/drivers/nv30/nv30_context.c | 185 ++-------------------------- src/gallium/drivers/nv30/nv30_context.h | 71 +++++++++-- src/gallium/drivers/nv30/nv30_query.c | 23 ++-- src/gallium/drivers/nv30/nv30_screen.c | 202 +++++++++++++++++++++++++++---- src/gallium/drivers/nv30/nv30_screen.h | 17 ++- src/gallium/drivers/nv30/nv30_vertprog.c | 31 ++++- 6 files changed, 303 insertions(+), 226 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index b8e8b86d99..d38713e98a 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -26,198 +26,36 @@ static void nv30_destroy(struct pipe_context *pipe) { struct nv30_context *nv30 = nv30_context(pipe); - struct nouveau_winsys *nvws = nv30->nvws; if (nv30->draw) draw_destroy(nv30->draw); - - nvws->res_free(&nv30->vertprog.exec_heap); - nvws->res_free(&nv30->vertprog.data_heap); - - nvws->res_free(&nv30->query_heap); - nvws->notifier_free(&nv30->query); - - nvws->notifier_free(&nv30->sync); - - nvws->grobj_free(&nv30->rankine); - FREE(nv30); } -static boolean -nv30_init_hwctx(struct nv30_context *nv30, int rankine_class) -{ - struct nouveau_winsys *nvws = nv30->nvws; - int ret; - int i; - - ret = nvws->grobj_alloc(nvws, rankine_class, &nv30->rankine); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - - BEGIN_RING(rankine, NV34TCL_DMA_NOTIFY, 1); - OUT_RING (nv30->sync->handle); - BEGIN_RING(rankine, NV34TCL_DMA_TEXTURE0, 2); - OUT_RING (nvws->channel->vram->handle); - OUT_RING (nvws->channel->gart->handle); - BEGIN_RING(rankine, NV34TCL_DMA_COLOR1, 1); - OUT_RING (nvws->channel->vram->handle); - BEGIN_RING(rankine, NV34TCL_DMA_COLOR0, 2); - OUT_RING (nvws->channel->vram->handle); - OUT_RING (nvws->channel->vram->handle); - BEGIN_RING(rankine, NV34TCL_DMA_VTXBUF0, 2); - OUT_RING (nvws->channel->vram->handle); - OUT_RING (nvws->channel->gart->handle); -/* BEGIN_RING(rankine, NV34TCL_DMA_FENCE, 2); - OUT_RING (0); - OUT_RING (nv30->query->handle);*/ - BEGIN_RING(rankine, NV34TCL_DMA_IN_MEMORY7, 1); - OUT_RING (nvws->channel->vram->handle); - BEGIN_RING(rankine, NV34TCL_DMA_IN_MEMORY8, 1); - OUT_RING (nvws->channel->vram->handle); - - for (i=1; i<8; i++) { - BEGIN_RING(rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(i), 1); - OUT_RING (0); - BEGIN_RING(rankine, NV34TCL_VIEWPORT_CLIP_VERT(i), 1); - OUT_RING (0); - } - - BEGIN_RING(rankine, 0x220, 1); - OUT_RING (1); - - BEGIN_RING(rankine, 0x03b0, 1); - OUT_RING (0x00100000); - BEGIN_RING(rankine, 0x1454, 1); - OUT_RING (0); - BEGIN_RING(rankine, 0x1d80, 1); - OUT_RING (3); - BEGIN_RING(rankine, 0x1450, 1); - OUT_RING (0x00030004); - - /* NEW */ - BEGIN_RING(rankine, 0x1e98, 1); - OUT_RING (0); - BEGIN_RING(rankine, 0x17e0, 3); - OUT_RING (0); - OUT_RING (0); - OUT_RING (0x3f800000); - BEGIN_RING(rankine, 0x1f80, 16); - OUT_RING (0); OUT_RING (0); OUT_RING (0); OUT_RING (0); - OUT_RING (0); OUT_RING (0); OUT_RING (0); OUT_RING (0); - OUT_RING (0x0000ffff); - OUT_RING (0); OUT_RING (0); OUT_RING (0); OUT_RING (0); - OUT_RING (0); OUT_RING (0); OUT_RING (0); - - BEGIN_RING(rankine, 0x120, 3); - OUT_RING (0); - OUT_RING (1); - OUT_RING (2); - - BEGIN_RING(rankine, 0x1d88, 1); - OUT_RING (0x00001200); - - BEGIN_RING(rankine, NV34TCL_RC_ENABLE, 1); - OUT_RING (0); - - BEGIN_RING(rankine, NV34TCL_DEPTH_RANGE_NEAR, 2); - OUT_RINGf (0.0); - OUT_RINGf (1.0); - - BEGIN_RING(rankine, NV34TCL_MULTISAMPLE_CONTROL, 1); - OUT_RING (0xffff0000); - - /* enables use of vp rather than fixed-function somehow */ - BEGIN_RING(rankine, 0x1e94, 1); - OUT_RING (0x13); - - FIRE_RING (NULL); - return TRUE; -} - -#define NV30TCL_CHIPSET_3X_MASK 0x00000003 -#define NV34TCL_CHIPSET_3X_MASK 0x00000010 -#define NV35TCL_CHIPSET_3X_MASK 0x000001e0 - struct pipe_context * -nv30_create(struct pipe_screen *screen, unsigned pctx_id) +nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) { - struct pipe_winsys *pipe_winsys = screen->winsys; - struct nouveau_winsys *nvws = nv30_screen(screen)->nvws; - unsigned chipset = nv30_screen(screen)->chipset; + struct nv30_screen *screen = nv30_screen(pscreen); + struct pipe_winsys *ws = pscreen->winsys; struct nv30_context *nv30; - int rankine_class = 0, ret; + unsigned chipset = screen->chipset; + struct nouveau_winsys *nvws = screen->nvws; - if ((chipset & 0xf0) != 0x30) { - NOUVEAU_ERR("Not a NV3X chipset\n"); - return NULL; - } - - 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; - } else { - NOUVEAU_ERR("Unknown NV3X chipset: NV%02x\n", chipset); - return NULL; - } - - nv30 = CALLOC_STRUCT(nv30_context); + nv30 = CALLOC(1, sizeof(struct nv30_context)); if (!nv30) return NULL; + nv30->screen = screen; + nv30->pctx_id = pctx_id; + nv30->chipset = chipset; nv30->nvws = nvws; - /* Notifier for sync purposes */ - ret = nvws->notifier_alloc(nvws, 1, &nv30->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv30_destroy(&nv30->pipe); - return NULL; - } - - /* Query objects */ - ret = nvws->notifier_alloc(nvws, 32, &nv30->query); - if (ret) { - NOUVEAU_ERR("Error initialising query objects: %d\n", ret); - nv30_destroy(&nv30->pipe); - return NULL; - } - - ret = nvws->res_init(&nv30->query_heap, 0, 32); - if (ret) { - NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); - nv30_destroy(&nv30->pipe); - return NULL; - } - - /* Vtxprog resources */ - if (nvws->res_init(&nv30->vertprog.exec_heap, 0, 256) || - nvws->res_init(&nv30->vertprog.data_heap, 0, 256)) { - nv30_destroy(&nv30->pipe); - return NULL; - } - - /* Static rankine initialisation */ - if (!nv30_init_hwctx(nv30, rankine_class)) { - nv30_destroy(&nv30->pipe); - return NULL; - } - - /* Pipe context setup */ - nv30->pipe.winsys = pipe_winsys; - nv30->pipe.screen = screen; - + nv30->pipe.winsys = ws; + nv30->pipe.screen = pscreen; nv30->pipe.destroy = nv30_destroy; - 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); @@ -226,7 +64,6 @@ nv30_create(struct pipe_screen *screen, unsigned pctx_id) nv30_init_miptree_functions(nv30); nv30->draw = draw_create(); - assert(nv30->draw); 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 index c1cc3eca1e..180969731b 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -11,8 +11,9 @@ #include "nouveau/nouveau_gldefs.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ - struct nv30_context *ctx = nv30 + struct nv30_screen *ctx = nv30->screen #include "nouveau/nouveau_push.h" +#include "nouveau/nouveau_stateobj.h" #include "nv30_state.h" @@ -21,23 +22,70 @@ #define NOUVEAU_MSG(fmt, args...) \ fprintf(stderr, "nouveau: "fmt, ##args); -#define NV30_NEW_VERTPROG (1 << 1) -#define NV30_NEW_FRAGPROG (1 << 2) -#define NV30_NEW_ARRAYS (1 << 3) +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) struct nv30_context { struct pipe_context pipe; + struct nouveau_winsys *nvws; + struct nv30_screen *screen; + unsigned pctx_id; struct draw_context *draw; int chipset; - struct nouveau_grobj *rankine; - struct nouveau_notifier *sync; - - /* query objects */ - struct nouveau_notifier *query; - struct nouveau_resource *query_heap; uint32_t dirty; @@ -63,9 +111,6 @@ struct nv30_context { } vb[16]; struct { - struct nouveau_resource *exec_heap; - struct nouveau_resource *data_heap; - struct nv30_vertex_program *active; struct nv30_vertex_program *current; diff --git a/src/gallium/drivers/nv30/nv30_query.c b/src/gallium/drivers/nv30/nv30_query.c index 0c2d941562..d40d75f264 100644 --- a/src/gallium/drivers/nv30/nv30_query.c +++ b/src/gallium/drivers/nv30/nv30_query.c @@ -1,5 +1,4 @@ #include "pipe/p_context.h" -#include "pipe/p_util.h" #include "nv30_context.h" @@ -10,7 +9,7 @@ struct nv30_query { uint64_t result; }; -static inline struct nv30_query * +static INLINE struct nv30_query * nv30_query(struct pipe_query *pipe) { return (struct nv30_query *)pipe; @@ -46,9 +45,18 @@ nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq) assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER); - if (nv30->nvws->res_alloc(nv30->query_heap, 1, NULL, &q->object)) + /* 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->query, q->object->start); + nv30->nvws->notifier_reset(nv30->screen->query, q->object->start); BEGIN_RING(rankine, NV34TCL_QUERY_RESET, 1); OUT_RING (1); @@ -83,16 +91,17 @@ nv30_query_result(struct pipe_context *pipe, struct pipe_query *pq, if (!q->ready) { unsigned status; - status = nvws->notifier_status(nv30->query, q->object->start); + 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->query, q->object->start, + nvws->notifier_wait(nv30->screen->query, q->object->start, NV_NOTIFY_STATE_STATUS_COMPLETED, 0); } - q->result = nvws->notifier_retval(nv30->query, + q->result = nvws->notifier_retval(nv30->screen->query, q->object->start); q->ready = TRUE; nvws->res_free(&q->object); diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index c7487b37bc..ce6c9ec523 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -4,24 +4,28 @@ #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 *screen) +nv30_screen_get_name(struct pipe_screen *pscreen) { - struct nv30_screen *nv30screen = nv30_screen(screen); + struct nv30_screen *screen = nv30_screen(pscreen); static char buffer[128]; - snprintf(buffer, sizeof(buffer), "NV%02X", nv30screen->chipset); + snprintf(buffer, sizeof(buffer), "NV%02X", screen->chipset); return buffer; } static const char * -nv30_screen_get_vendor(struct pipe_screen *screen) +nv30_screen_get_vendor(struct pipe_screen *pscreen) { return "nouveau"; } static int -nv30_screen_get_param(struct pipe_screen *screen, int param) +nv30_screen_get_param(struct pipe_screen *pscreen, int param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: @@ -60,7 +64,7 @@ nv30_screen_get_param(struct pipe_screen *screen, int param) } static float -nv30_screen_get_paramf(struct pipe_screen *screen, int param) +nv30_screen_get_paramf(struct pipe_screen *pscreen, int param) { switch (param) { case PIPE_CAP_MAX_LINE_WIDTH: @@ -82,8 +86,8 @@ nv30_screen_get_paramf(struct pipe_screen *screen, int param) } static boolean -nv30_screen_is_format_supported(struct pipe_screen *screen, - enum pipe_format format, uint type) +nv30_screen_surface_format_supported(struct pipe_screen *pscreen, + enum pipe_format format, uint type) { switch (type) { case PIPE_SURFACE: @@ -122,36 +126,184 @@ nv30_screen_is_format_supported(struct pipe_screen *screen, } static void -nv30_screen_destroy(struct pipe_screen *screen) +nv30_screen_destroy(struct pipe_screen *pscreen) { - FREE(screen); + 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 *winsys, struct nouveau_winsys *nvws, +nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, unsigned chipset) { - struct nv30_screen *nv30screen = CALLOC_STRUCT(nv30_screen); + struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen); + struct nouveau_stateobj *so; + unsigned rankine_class = 0; + int ret, i; + + if (!screen) + return NULL; + screen->chipset = chipset; + 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 (!nv30screen) + 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); - nv30screen->chipset = chipset; - nv30screen->nvws = nvws; + so_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws, 0, NULL); - nv30screen->screen.winsys = winsys; + screen->pipe.winsys = ws; + screen->pipe.destroy = nv30_screen_destroy; - nv30screen->screen.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; - nv30screen->screen.get_name = nv30_screen_get_name; - nv30screen->screen.get_vendor = nv30_screen_get_vendor; - nv30screen->screen.get_param = nv30_screen_get_param; - nv30screen->screen.get_paramf = nv30_screen_get_paramf; - nv30screen->screen.is_format_supported = - nv30_screen_is_format_supported; + screen->pipe.is_format_supported = nv30_screen_surface_format_supported; - nv30_screen_init_miptree_functions(&nv30screen->screen); + nv30_screen_init_miptree_functions(&screen->pipe); - return &nv30screen->screen; + return &screen->pipe; } diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h index f878f81e11..56f8776a17 100644 --- a/src/gallium/drivers/nv30/nv30_screen.h +++ b/src/gallium/drivers/nv30/nv30_screen.h @@ -4,10 +4,25 @@ #include "pipe/p_screen.h" struct nv30_screen { - struct pipe_screen screen; + struct pipe_screen pipe; struct nouveau_winsys *nvws; unsigned chipset; + + /* 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 * diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index fe1a467565..71aea3a59c 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -1,7 +1,6 @@ #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" @@ -654,7 +653,7 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) /* Allocate hw vtxprog exec slots */ if (!vp->exec) { - struct nouveau_resource *heap = nv30->vertprog.exec_heap; + struct nouveau_resource *heap = nv30->screen->vp_exec_heap; uint vplen = vp->nr_insns; if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) { @@ -674,7 +673,7 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) /* Allocate hw vtxprog const slots */ if (vp->nr_consts && !vp->data) { - struct nouveau_resource *heap = nv30->vertprog.data_heap; + 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) { @@ -789,9 +788,29 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) void nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp) { - if (vp->nr_consts) - FREE(vp->consts); - if (vp->nr_insns) + 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); */ } -- cgit v1.2.3 From 7f811f2c42937f254ae1b11e5b0ece765a8ea31b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Apr 2008 22:16:42 +0200 Subject: nv30: Update miptree stuff --- src/gallium/drivers/nv30/nv30_miptree.c | 37 +++++++++++++++++---------------- 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index afb05fdd2b..10ab46e19a 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -4,7 +4,6 @@ #include "pipe/p_inlines.h" #include "nv30_context.h" -#include "nv30_screen.h" static void nv30_miptree_layout(struct nv30_miptree *nv30mt) @@ -13,7 +12,7 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) boolean swizzled = FALSE; uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; uint offset = 0; - int nr_faces, l, f; + int nr_faces, l, f, pitch; if (pt->target == PIPE_TEXTURE_CUBE) { nr_faces = 6; @@ -24,17 +23,17 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) 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) - nv30mt->level[l].pitch = pt->width[l] * pt->cpp; - else - nv30mt->level[l].pitch = pt->width[0] * pt->cpp; - nv30mt->level[l].pitch = (nv30mt->level[l].pitch + 63) & ~63; + 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)); @@ -55,9 +54,9 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) } static struct pipe_texture * -nv30_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) +nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) { - struct pipe_winsys *ws = screen->winsys; + struct pipe_winsys *ws = pscreen->winsys; struct nv30_miptree *mt; mt = MALLOC(sizeof(struct nv30_miptree)); @@ -65,24 +64,26 @@ nv30_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) return NULL; mt->base = *pt; mt->base.refcount = 1; - mt->base.screen = screen; + mt->base.screen = pscreen; nv30_miptree_layout(mt); - mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, - mt->total_size); + 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 *screen, struct pipe_texture **pt) +nv30_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) { - struct pipe_winsys *ws = screen->winsys; + struct pipe_winsys *ws = pscreen->winsys; struct pipe_texture *mt = *pt; *pt = NULL; @@ -106,10 +107,10 @@ nv30_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, } static struct pipe_surface * -nv30_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) +nv30_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) { - struct pipe_winsys *ws = screen->winsys; + struct pipe_winsys *ws = pscreen->winsys; struct nv30_miptree *nv30mt = (struct nv30_miptree *)pt; struct pipe_surface *ps; @@ -146,6 +147,6 @@ 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_get; + pscreen->get_tex_surface = nv30_miptree_surface; } -- cgit v1.2.3 From 7d2085bd7d9378703bfff3d974536ff5e9fd9b30 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 15 Apr 2008 13:25:28 +1000 Subject: nouveau: PIPE_ATTRIB_MAX -> PIPE_MAX_ATTRIBS --- src/gallium/drivers/nv10/nv10_context.h | 4 ++-- src/gallium/drivers/nv10/nv10_vbo.c | 4 ++-- src/gallium/drivers/nv30/nv30_context.h | 4 ++-- src/gallium/drivers/nv40/nv40_context.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index 63d33ef7c9..b80f36ad34 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -96,8 +96,8 @@ struct nv10_context { struct pipe_buffer *constant_buf; } fragprog; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; - struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; }; static INLINE struct nv10_context * diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c index 3a4f49e156..2a334e137d 100644 --- a/src/gallium/drivers/nv10/nv10_vbo.c +++ b/src/gallium/drivers/nv10/nv10_vbo.c @@ -23,7 +23,7 @@ boolean nv10_draw_elements( struct pipe_context *pipe, /* * Map vertex buffers */ - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { if (nv10->vtxbuf[i].buffer) { void *buf = pipe->winsys->buffer_map(pipe->winsys, @@ -52,7 +52,7 @@ boolean nv10_draw_elements( struct pipe_context *pipe, /* * unmap vertex/index buffers */ - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + 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); diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 180969731b..1a016405e6 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -124,8 +124,8 @@ struct nv30_context { struct pipe_buffer *constant_buf; } fragprog; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; - struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; }; static INLINE struct nv30_context * diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 436351b6bc..2f10540ff0 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -151,9 +151,9 @@ struct nv40_context { unsigned nr_samplers; unsigned nr_textures; unsigned dirty_samplers; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned vtxbuf_nr; - struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; unsigned vtxelt_nr; }; -- cgit v1.2.3 From e7bdf047f28ea9b928b3890c37d7d20db1e67e96 Mon Sep 17 00:00:00 2001 From: Peter Winters Date: Sun, 20 Apr 2008 16:07:04 +0200 Subject: nv10: fix random stuff --- src/gallium/drivers/nv10/nv10_context.c | 36 ++++++++++++++++++++++++++--- src/gallium/drivers/nv10/nv10_context.h | 5 +++- src/gallium/drivers/nv10/nv10_prim_vbuf.c | 4 ++-- src/gallium/drivers/nv10/nv10_state.c | 20 +++++++++------- src/gallium/drivers/nv10/nv10_state_emit.c | 37 +++++++++++++++++------------- 5 files changed, 72 insertions(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c index 42c496b959..bbd307d5d9 100644 --- a/src/gallium/drivers/nv10/nv10_context.c +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -12,6 +12,8 @@ nv10_flush(struct pipe_context *pipe, unsigned flags, { struct nv10_context *nv10 = nv10_context(pipe); + draw_flush(nv10->draw); + FIRE_RING(fence); } @@ -31,6 +33,7 @@ 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); @@ -93,13 +96,21 @@ static void nv10_init_hwctx(struct nv10_context *nv10) BEGIN_RING(celsius, NV10TCL_TX_ENABLE(0), 2); OUT_RING (0); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_RC_OUT_ALPHA(0), 6); + + 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 (0x300c0000); - OUT_RING (0x00001c80); + OUT_RING (0x300e0300); + OUT_RING (0x0c091c80); + BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); OUT_RING (0); BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 2); @@ -219,6 +230,25 @@ static void nv10_init_hwctx(struct nv10_context *nv10) 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); } diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index b80f36ad34..1b794c1872 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -65,7 +65,10 @@ struct nv10_context { struct pipe_viewport_state *viewport; struct pipe_scissor_state *scissor; struct pipe_framebuffer_state *framebuffer; - struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + + //struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + float *constbuf[PIPE_SHADER_TYPES][32][4]; + struct vertex_info vertex_info; struct { diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c index 412ee9a23f..930536b946 100644 --- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c +++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c @@ -205,8 +205,8 @@ nv10_vbuf_render_create( struct nv10_context *nv10 ) nv10_render->nv10 = nv10; - nv10_render->base.max_vertex_buffer_bytes = 1024*1024; - nv10_render->base.max_indices = 64*1024; + 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; diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 1d9a202dd7..4dcb9a31ab 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -459,14 +459,18 @@ 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; - if (shader == PIPE_SHADER_VERTEX) { - nv10->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; - nv10->dirty |= NV10_NEW_VERTPROG; - } else - if (shader == PIPE_SHADER_FRAGMENT) { - nv10->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; - nv10->dirty |= NV10_NEW_FRAGPROG; + 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); + ws->buffer_unmap(ws, buf->buffer); + } } } @@ -507,7 +511,7 @@ nv10_set_viewport_state(struct pipe_context *pipe, nv10->viewport = (struct pipe_viewport_state*)vpt; - draw_set_viewport_state(nv10->draw, &nv10->viewport); + draw_set_viewport_state(nv10->draw, nv10->viewport); nv10->dirty |= NV10_NEW_VIEWPORT; } diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c index edc194588d..b7ae57d500 100644 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -63,29 +63,34 @@ 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, 3); - OUT_RINGp ((uint32_t *)&d->depth, 3); + 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); - BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 3); - OUT_RINGp ((uint32_t *)&d->alpha.enabled, 3); +#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) { - struct pipe_viewport_state *vpt = nv10->viewport; - -/* OUT_RINGf (vpt->translate[0]); - OUT_RINGf (vpt->translate[1]); - OUT_RINGf (vpt->translate[2]); - OUT_RINGf (vpt->translate[3]);*/ - BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4); - OUT_RINGf (vpt->scale[0]); - OUT_RINGf (vpt->scale[1]); - OUT_RINGf (vpt->scale[2]); - OUT_RINGf (vpt->scale[3]); } static void nv10_state_emit_scissor(struct nv10_context* nv10) @@ -100,7 +105,7 @@ static void nv10_state_emit_scissor(struct nv10_context* nv10) static void nv10_state_emit_framebuffer(struct nv10_context* nv10) { struct pipe_framebuffer_state* fb = nv10->framebuffer; - struct pipe_surface *rt, *zeta; + struct pipe_surface *rt, *zeta = NULL; uint32_t rt_format, w, h; int colour_format = 0, zeta_format = 0; -- cgit v1.2.3 From b20acef90695d6e5975f538b6e9cb812b05f0cf6 Mon Sep 17 00:00:00 2001 From: Peter Winters Date: Sun, 20 Apr 2008 22:48:50 +0200 Subject: nv10: enable viewport clipping --- src/gallium/drivers/nv10/nv10_state_emit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c index b7ae57d500..41422c8882 100644 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -161,8 +161,8 @@ static void nv10_state_emit_framebuffer(struct nv10_context* nv10) OUT_RING ((h << 16) | 0); OUT_RING (rt_format); BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2); - OUT_RING (((w - 1) << 16) | 0); - OUT_RING (((h - 1) << 16) | 0); + OUT_RING (((w - 1) << 16) | 0 | 0x08000800); + OUT_RING (((h - 1) << 16) | 0 | 0x08000800); } static void nv10_vertex_layout(struct nv10_context *nv10) -- cgit v1.2.3 From a3265958994ce4107da2a3954c04b496e29cd8aa Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 23 Apr 2008 12:41:42 +1000 Subject: nouveau: fix build --- src/gallium/drivers/nv30/nv30_draw.c | 2 +- src/gallium/drivers/nv40/nv40_draw.c | 2 +- src/gallium/drivers/nv50/nv50_draw.c | 2 +- src/gallium/drivers/nv50/nv50_state.c | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c index 8ec0835225..aeeaf58f20 100644 --- a/src/gallium/drivers/nv30/nv30_draw.c +++ b/src/gallium/drivers/nv30/nv30_draw.c @@ -1,4 +1,4 @@ -#include "draw/draw_private.h" +#include "draw/draw_pipe.h" #include "pipe/p_util.h" #include "nv30_context.h" diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index dd5cc8fc99..a9a939af0c 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -3,7 +3,7 @@ #include "draw/draw_context.h" #include "draw/draw_vertex.h" -#include "draw/draw_private.h" +#include "draw/draw_pipe.h" #include "nv40_context.h" #define NV40_SHADER_NO_FUCKEDNESS diff --git a/src/gallium/drivers/nv50/nv50_draw.c b/src/gallium/drivers/nv50/nv50_draw.c index 790408c6df..d185d99950 100644 --- a/src/gallium/drivers/nv50/nv50_draw.c +++ b/src/gallium/drivers/nv50/nv50_draw.c @@ -1,4 +1,4 @@ -#include "draw/draw_private.h" +#include "draw/draw_pipe.h" #include "pipe/p_util.h" #include "nv50_context.h" diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index a614ea0335..f42bae0c28 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -113,7 +113,6 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; struct nv50_rasterizer_stateobj *rso = CALLOC_STRUCT(nv50_rasterizer_stateobj); - unsigned i; /*XXX: ignored * - light_twosize -- cgit v1.2.3 From 7342688286cc3b7c938af2dfeac22df4fa8c8464 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 23 Apr 2008 22:38:49 +0200 Subject: nv30: add stuff to init swtnl --- src/gallium/drivers/nv30/nv30_context.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index d38713e98a..57b0e71dad 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -63,7 +63,12 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) nv30_init_state_functions(nv30); nv30_init_miptree_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; -- cgit v1.2.3 From 2193578851b3b5a99c078b28187cf3158f4218f6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 27 Apr 2008 18:12:14 +1000 Subject: nouveau: stub set_edgeflags for all nv pipe drivers --- src/gallium/drivers/nv10/nv10_context.c | 6 ++++++ src/gallium/drivers/nv30/nv30_context.c | 7 +++++++ src/gallium/drivers/nv40/nv40_context.c | 6 ++++++ src/gallium/drivers/nv50/nv50_context.c | 7 +++++++ 4 files changed, 26 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c index bbd307d5d9..a25c082a5d 100644 --- a/src/gallium/drivers/nv10/nv10_context.c +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -253,6 +253,11 @@ static void nv10_init_hwctx(struct nv10_context *nv10) 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) { @@ -274,6 +279,7 @@ nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) 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; diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 57b0e71dad..4b0892971e 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -32,6 +32,12 @@ nv30_destroy(struct pipe_context *pipe) 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) { @@ -53,6 +59,7 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) 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; diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index f9c93f7a2d..f1d4f3c76f 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -32,6 +32,11 @@ nv40_destroy(struct pipe_context *pipe) FREE(nv40); } +static void +nv40_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +{ +} + struct pipe_context * nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) { @@ -53,6 +58,7 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40->pipe.winsys = ws; nv40->pipe.screen = pscreen; nv40->pipe.destroy = nv40_destroy; + nv40->pipe.set_edgeflags = nv40_set_edgeflags; nv40->pipe.draw_arrays = nv40_draw_arrays; nv40->pipe.draw_elements = nv40_draw_elements; nv40->pipe.clear = nv40_clear; diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index e822d86394..6eb1878b84 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -24,6 +24,12 @@ nv50_destroy(struct pipe_context *pipe) 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) { @@ -42,6 +48,7 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) 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; -- cgit v1.2.3 From 58b1bcaa094ed07a54bd7e4cdbddbcdcf1f629a7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 28 Apr 2008 15:42:19 +1000 Subject: nv40: do full swtnl fallback when edge flags present. This isn't necessary, with some effort we can do this on the hw. However, until I encounter something "real" that uses them there's not a lot of point. --- src/gallium/drivers/nv40/nv40_context.c | 6 ------ src/gallium/drivers/nv40/nv40_context.h | 1 + src/gallium/drivers/nv40/nv40_state.c | 11 +++++++++++ src/gallium/drivers/nv40/nv40_state_emit.c | 1 + src/gallium/drivers/nv40/nv40_vbo.c | 5 +++++ 5 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index f1d4f3c76f..f9c93f7a2d 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -32,11 +32,6 @@ nv40_destroy(struct pipe_context *pipe) FREE(nv40); } -static void -nv40_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) -{ -} - struct pipe_context * nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) { @@ -58,7 +53,6 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40->pipe.winsys = ws; nv40->pipe.screen = pscreen; nv40->pipe.destroy = nv40_destroy; - nv40->pipe.set_edgeflags = nv40_set_edgeflags; nv40->pipe.draw_arrays = nv40_draw_arrays; nv40->pipe.draw_elements = nv40_draw_elements; nv40->pipe.clear = nv40_clear; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 2f10540ff0..24e8cd2337 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -155,6 +155,7 @@ struct nv40_context { unsigned vtxbuf_nr; struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; unsigned vtxelt_nr; + const unsigned *edgeflags; }; static INLINE struct nv40_context * diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 997beca883..2d921d2b8a 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -680,6 +680,16 @@ nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count, 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) { @@ -719,6 +729,7 @@ nv40_init_state_functions(struct nv40_context *nv40) 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_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 864dfc2e0c..ab88dc416e 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -167,6 +167,7 @@ nv40_state_validate_swtnl(struct nv40_context *nv40) 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); } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 06374184b1..e5f9bd5668 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -488,6 +488,11 @@ nv40_vbo_validate(struct nv40_context *nv40) 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); -- cgit v1.2.3 From 480ab1b7893290505efba925ea95d3b173aa97d4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 29 Apr 2008 08:56:41 +1000 Subject: nv40: enable DXTn formats GL state tracker capable enough for progs/tests/texcompress2 at least. --- src/gallium/drivers/nv40/nv40_screen.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index a408d7262f..c64c3b1c39 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -39,7 +39,7 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) case PIPE_CAP_GLSL: return 0; case PIPE_CAP_S3TC: - return 0; + return 1; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: @@ -118,12 +118,10 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_U_A8_L8: case PIPE_FORMAT_Z16_UNORM: case PIPE_FORMAT_Z24S8_UNORM: -#if 0 /* state tracker not up to the task just yet. */ case PIPE_FORMAT_DXT1_RGB: case PIPE_FORMAT_DXT1_RGBA: case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT5_RGBA: -#endif return TRUE; default: break; -- cgit v1.2.3 From 612f44266cba78c4e5677a2f992581fdaa17f4e4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 5 May 2008 19:45:21 +1000 Subject: nouveau: bitmap texcoord bias has been removed --- src/gallium/drivers/nv10/nv10_screen.c | 2 -- src/gallium/drivers/nv30/nv30_screen.c | 2 -- src/gallium/drivers/nv40/nv40_screen.c | 2 -- src/gallium/drivers/nv50/nv50_screen.c | 2 -- 4 files changed, 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index 45fbde62ea..cf6b2fac84 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -73,8 +73,6 @@ nv10_screen_get_paramf(struct pipe_screen *screen, int param) return 2.0; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 4.0; - case PIPE_CAP_BITMAP_TEXCOORD_BIAS: - return 0.0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0.0; diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index ce6c9ec523..1de4507904 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -77,8 +77,6 @@ nv30_screen_get_paramf(struct pipe_screen *pscreen, int param) return 16.0; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 4.0; - case PIPE_CAP_BITMAP_TEXCOORD_BIAS: - return 0.0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0.0; diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index c64c3b1c39..7f68539a85 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -82,8 +82,6 @@ nv40_screen_get_paramf(struct pipe_screen *pscreen, int param) return 16.0; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 16.0; - case PIPE_CAP_BITMAP_TEXCOORD_BIAS: - return 0.0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0.0; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index adb724b9b7..4902f16de3 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -86,8 +86,6 @@ nv50_screen_get_paramf(struct pipe_screen *pscreen, int param) return 16.0; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 4.0; - case PIPE_CAP_BITMAP_TEXCOORD_BIAS: - return 0.0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0.0; -- cgit v1.2.3 From 32ed02bcfbe7a2132929658b1a73708ab16af006 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 5 May 2008 19:49:06 +1000 Subject: nv50: report some supported formats to keep the state tracker from asserting. --- src/gallium/drivers/nv50/nv50_screen.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 4902f16de3..e4ca72c717 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -14,6 +14,30 @@ 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; } -- cgit v1.2.3 From 9b0054c7f87e3cc89fc0e60408af41f3e86dfdff Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 5 May 2008 19:52:19 +1000 Subject: nv50: slightly less skeletal texture funcs, prevents fun segfaults --- src/gallium/drivers/nv50/nv50_miptree.c | 62 ++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 7474c65765..58584934b1 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -1,29 +1,83 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" -#include "pipe/p_screen.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"); - return NULL; + + 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 **pt) +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(struct pipe_screen *pscreen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) { + struct pipe_winsys *ws = pscreen->winsys; + struct nv50_miptree *mt = nv50_miptree(pt); + struct pipe_surface *ps; + NOUVEAU_ERR("unimplemented\n"); - return NULL; + + 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; } void -- cgit v1.2.3 From 83e6df12ea31ef48d251fe7b38acd882145f8f14 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2008 12:01:08 +1000 Subject: nouveau: chipset is a device property, remove from nv/nvc. --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 36 ++++++++++-------------- src/gallium/winsys/dri/nouveau/nouveau_context.h | 5 ---- src/gallium/winsys/dri/nouveau/nouveau_device.c | 13 +++++++++ src/gallium/winsys/dri/nouveau/nouveau_device.h | 1 + src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 8 ++++-- src/gallium/winsys/dri/nouveau/nv04_surface.c | 15 +++++----- 6 files changed, 41 insertions(+), 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index ff08a870db..e65b057335 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -43,7 +43,7 @@ nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) } static struct nouveau_channel_context * -nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) +nouveau_channel_context_create(struct nouveau_device *dev) { struct nouveau_channel_context *nvc; int ret; @@ -51,9 +51,8 @@ nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) nvc = CALLOC_STRUCT(nouveau_channel_context); if (!nvc) return NULL; - nvc->chipset = chipset; - if ((ret = nouveau_channel_alloc(nvdev, 0x8003d001, 0x8003d002, + if ((ret = nouveau_channel_alloc(dev, 0x8003d001, 0x8003d002, &nvc->channel))) { NOUVEAU_ERR("Error creating GPU channel: %d\n", ret); nouveau_channel_context_destroy(nvc); @@ -75,7 +74,7 @@ nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset) return NULL; } - switch (chipset & 0xf0) { + switch (dev->chipset & 0xf0) { case 0x50: case 0x80: case 0x90: @@ -103,25 +102,17 @@ nouveau_context_create(const __GLcontextModes *glVis, __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; struct nouveau_screen *nv_screen = driScrnPriv->private; struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context); - struct nouveau_device_priv *nvdev; 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, ret; if (sharedContextPrivate) { st_share = ((struct nouveau_context *)sharedContextPrivate)->st; } - /* Check for supported arch */ - if ((ret = nouveau_device_get_param(nv_screen->device, - NOUVEAU_GETPARAM_CHIPSET_ID, - &nv->chipset))) { - NOUVEAU_ERR("Error determining chipset id: %d\n", ret); - return GL_FALSE; - } - - switch (nv->chipset & 0xf0) { + switch (dev->chipset & 0xf0) { case 0x10: case 0x20: /* NV10 */ @@ -136,7 +127,7 @@ nouveau_context_create(const __GLcontextModes *glVis, /* G80 */ break; default: - NOUVEAU_ERR("Unsupported chipset: NV%02x\n", (int)nv->chipset); + NOUVEAU_ERR("Unsupported chipset: NV%02x\n", dev->chipset); return GL_FALSE; } @@ -144,9 +135,12 @@ nouveau_context_create(const __GLcontextModes *glVis, nv->nv_screen = nv_screen; nv->dri_screen = driScrnPriv; - nvdev = nouveau_device(nv_screen->device); - nvdev->ctx = driContextPriv->hHWContext; - nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; + { + 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"); @@ -201,7 +195,7 @@ nouveau_context_create(const __GLcontextModes *glVis, } /*XXX: temporary - disable multi-context/single-channel on pre-NV4x */ - switch (nv->chipset & 0xf0) { + switch (dev->chipset & 0xf0) { case 0x40: case 0x60: /* NV40 class */ @@ -216,7 +210,7 @@ nouveau_context_create(const __GLcontextModes *glVis, } if (!nvc) { - nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset); + nvc = nouveau_channel_context_create(dev); if (!nvc) { NOUVEAU_ERR("Failed initialising GPU context\n"); return GL_FALSE; @@ -244,7 +238,7 @@ nouveau_context_create(const __GLcontextModes *glVis, } /* Create pipe */ - switch (nv->chipset & 0xf0) { + switch (dev->chipset & 0xf0) { case 0x50: case 0x80: case 0x90: diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 872ef93807..9872d6b691 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -21,8 +21,6 @@ struct nouveau_channel_context { unsigned nr_pctx; struct pipe_context **pctx; - unsigned chipset; - struct nouveau_channel *channel; struct nouveau_notifier *sync_notifier; @@ -47,9 +45,6 @@ struct nouveau_channel_context { struct nouveau_context { struct st_context *st; - /* Misc HW info */ - uint64_t chipset; - /* DRI stuff */ __DRIscreenPrivate *dri_screen; __DRIdrawablePrivate *dri_drawable; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_device.c b/src/gallium/winsys/dri/nouveau/nouveau_device.c index 409e4415f7..0b452fcd02 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_device.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_device.c @@ -50,6 +50,19 @@ nouveau_device_open_existing(struct nouveau_device **dev, int close, 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; } diff --git a/src/gallium/winsys/dri/nouveau/nouveau_device.h b/src/gallium/winsys/dri/nouveau/nouveau_device.h index 744a89f74b..e25e89fedd 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_device.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_device.h @@ -24,6 +24,7 @@ #define __NOUVEAU_DEVICE_H__ struct nouveau_device { + unsigned chipset; }; #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 60fdbb8dfd..635fd478a9 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -1,6 +1,7 @@ #include "pipe/p_util.h" #include "nouveau_context.h" +#include "nouveau_screen.h" #include "nouveau_winsys_pipe.h" #include "nouveau/nouveau_winsys.h" @@ -94,11 +95,12 @@ nouveau_pipe_create(struct nouveau_context *nv) unsigned chipset); 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 (nv->chipset & 0xf0) { + switch (chipset & 0xf0) { case 0x10: case 0x20: hws_create = nv10_screen_create; @@ -120,7 +122,7 @@ nouveau_pipe_create(struct nouveau_context *nv) hw_create = nv50_create; break; default: - NOUVEAU_ERR("Unknown chipset NV%02x\n", (int)nv->chipset); + NOUVEAU_ERR("Unknown chipset NV%02x\n", chipset); return NULL; } @@ -150,7 +152,7 @@ nouveau_pipe_create(struct nouveau_context *nv) ws = nouveau_create_pipe_winsys(nv); if (!nvc->pscreen) - nvc->pscreen = hws_create(ws, nvws, nv->chipset); + nvc->pscreen = hws_create(ws, nvws, chipset); 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/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index f61bd1477f..dc167e4acf 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -179,7 +179,7 @@ int nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) { struct nouveau_channel *chan = nvc->channel; - unsigned class; + unsigned chipset = nvc->channel->device->chipset, class; int ret; if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39, @@ -192,8 +192,8 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); OUT_RING (chan, nvc->sync_notifier->handle); - class = nvc->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D : - NV10_CONTEXT_SURFACES_2D; + 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); @@ -205,8 +205,7 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) OUT_RING (chan, nvc->channel->vram->handle); OUT_RING (chan, nvc->channel->vram->handle); - class = nvc->chipset < 0x10 ? NV04_IMAGE_BLIT : - NV12_IMAGE_BLIT; + 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); @@ -237,7 +236,7 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); - switch (nvc->chipset & 0xf0) { + switch (chipset & 0xf0) { case 0x00: case 0x10: class = NV04_SWIZZLED_SURFACE; @@ -267,10 +266,10 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); - if (nvc->chipset < 0x10) { + if (chipset < 0x10) { class = NV04_SCALED_IMAGE_FROM_MEMORY; } else - if (nvc->chipset < 0x40) { + if (chipset < 0x40) { class = NV10_SCALED_IMAGE_FROM_MEMORY; } else { class = NV40_SCALED_IMAGE_FROM_MEMORY; -- cgit v1.2.3 From c962ad7cd5dbea12d13997b421a44b16af3c6662 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2008 12:06:32 +1000 Subject: nouveau: create objnull during channel creation --- src/gallium/drivers/nouveau/nouveau_channel.h | 1 + src/gallium/winsys/dri/nouveau/nouveau_channel.c | 8 ++++++++ src/gallium/winsys/dri/nouveau/nouveau_context.c | 7 ------- src/gallium/winsys/dri/nouveau/nouveau_context.h | 1 - src/gallium/winsys/dri/nouveau/nouveau_grobj.c | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_channel.h b/src/gallium/drivers/nouveau/nouveau_channel.h index b99de9add8..cd99a676bd 100644 --- a/src/gallium/drivers/nouveau/nouveau_channel.h +++ b/src/gallium/drivers/nouveau/nouveau_channel.h @@ -29,6 +29,7 @@ struct nouveau_channel { struct nouveau_pushbuf *pushbuf; + struct nouveau_grobj *nullobj; struct nouveau_grobj *vram; struct nouveau_grobj *gart; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_channel.c b/src/gallium/winsys/dri/nouveau/nouveau_channel.c index df80d04add..3b4dcd1ecf 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_channel.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_channel.c @@ -85,6 +85,13 @@ nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, 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); @@ -109,6 +116,7 @@ nouveau_channel_free(struct nouveau_channel **chan) 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)); diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index e65b057335..d9fc3f6ce1 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -26,7 +26,6 @@ int __nouveau_debug = 0; static void nouveau_channel_context_destroy(struct nouveau_channel_context *nvc) { - nouveau_grobj_free(&nvc->NvNull); nouveau_grobj_free(&nvc->NvCtxSurf2D); nouveau_grobj_free(&nvc->NvImageBlit); nouveau_grobj_free(&nvc->NvGdiRect); @@ -59,12 +58,6 @@ nouveau_channel_context_create(struct nouveau_device *dev) return NULL; } - if ((ret = nouveau_grobj_alloc(nvc->channel, 0x00000000, 0x30, - &nvc->NvNull))) { - NOUVEAU_ERR("Error creating NULL object: %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, diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index 9872d6b691..b20107a94c 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -26,7 +26,6 @@ struct nouveau_channel_context { struct nouveau_notifier *sync_notifier; /* Common */ - struct nouveau_grobj *NvNull; struct nouveau_grobj *NvM2MF; /* NV04-NV40 */ struct nouveau_grobj *NvCtxSurf2D; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_grobj.c b/src/gallium/winsys/dri/nouveau/nouveau_grobj.c index 55dfeb99aa..51523897d5 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_grobj.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_grobj.c @@ -50,7 +50,7 @@ nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle, ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC, &g, sizeof(g)); if (ret) { - nouveau_grobj_free((void *)&grobj); + nouveau_grobj_free((void *)&nvgrobj); return ret; } -- cgit v1.2.3 From 2f80d4d2a705835b272cf2274ea578fe5bbe1919 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2008 12:09:04 +1000 Subject: nouveau: make nouveau_device.h part of public API --- src/gallium/drivers/nouveau/nouveau_device.h | 30 ++++++++++++++++++++++ src/gallium/winsys/dri/nouveau/nouveau_context.h | 1 - src/gallium/winsys/dri/nouveau/nouveau_device.h | 30 ---------------------- src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 2 +- src/gallium/winsys/dri/nouveau/nouveau_screen.c | 1 - src/gallium/winsys/dri/nouveau/nouveau_screen.h | 1 - .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 1 - 7 files changed, 31 insertions(+), 35 deletions(-) create mode 100644 src/gallium/drivers/nouveau/nouveau_device.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_device.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_device.h b/src/gallium/drivers/nouveau/nouveau_device.h new file mode 100644 index 0000000000..e25e89fedd --- /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/winsys/dri/nouveau/nouveau_context.h b/src/gallium/winsys/dri/nouveau/nouveau_context.h index b20107a94c..77e2147a2c 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.h @@ -5,7 +5,6 @@ #include "xmlconfig.h" #include "nouveau/nouveau_winsys.h" -#include "nouveau_device.h" #include "nouveau_drmif.h" #include "nouveau_dma.h" diff --git a/src/gallium/winsys/dri/nouveau/nouveau_device.h b/src/gallium/winsys/dri/nouveau/nouveau_device.h deleted file mode 100644 index e25e89fedd..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_device.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index d5a0e25b57..a31c9a514b 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -27,7 +27,7 @@ #include #include -#include "nouveau_device.h" +#include "nouveau/nouveau_device.h" #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_grobj.h" #include "nouveau/nouveau_notifier.h" diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index f06e178483..9041275a88 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -7,7 +7,6 @@ #include "state_tracker/st_cb_fbo.h" #include "nouveau_context.h" -#include "nouveau_device.h" #include "nouveau_drm.h" #include "nouveau_dri.h" #include "nouveau_local.h" diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.h b/src/gallium/winsys/dri/nouveau/nouveau_screen.h index e9da202690..388d6be9bb 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.h @@ -2,7 +2,6 @@ #define __NOUVEAU_SCREEN_H__ #include "xmlconfig.h" -#include "nouveau_device.h" struct nouveau_screen { __DRIscreenPrivate *driScrnPriv; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index 849e38d22b..755c8b6997 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -4,7 +4,6 @@ #include "pipe/p_inlines.h" #include "nouveau_context.h" -#include "nouveau_device.h" #include "nouveau_local.h" #include "nouveau_screen.h" #include "nouveau_swapbuffers.h" -- cgit v1.2.3 From 1ef08564d2a201a422db772a6bb23d1129888304 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 13 May 2008 12:16:35 +1000 Subject: nouveau: remove chipset fields in all nv pipe driver context/screen structs. --- src/gallium/drivers/nouveau/nouveau_winsys.h | 13 +++++-------- src/gallium/drivers/nv10/nv10_context.c | 2 -- src/gallium/drivers/nv10/nv10_context.h | 2 -- src/gallium/drivers/nv10/nv10_screen.c | 8 ++++---- src/gallium/drivers/nv10/nv10_screen.h | 1 - src/gallium/drivers/nv30/nv30_context.c | 2 -- src/gallium/drivers/nv30/nv30_context.h | 2 -- src/gallium/drivers/nv30/nv30_screen.c | 8 ++++---- src/gallium/drivers/nv30/nv30_screen.h | 1 - src/gallium/drivers/nv40/nv40_context.c | 2 -- src/gallium/drivers/nv40/nv40_context.h | 2 -- src/gallium/drivers/nv40/nv40_screen.c | 8 ++++---- src/gallium/drivers/nv40/nv40_screen.h | 1 - src/gallium/drivers/nv50/nv50_screen.c | 8 ++++---- src/gallium/drivers/nv50/nv50_screen.h | 1 - src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 5 ++--- 16 files changed, 23 insertions(+), 43 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index fbde7adc6a..07a41dcf4a 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -8,6 +8,7 @@ #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" @@ -56,29 +57,25 @@ struct nouveau_winsys { }; extern struct pipe_screen * -nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, - unsigned chipset); +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 *, - unsigned chipset); +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 *, - unsigned chipset); +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 *, - unsigned chipset); +nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); extern struct pipe_context * nv50_create(struct pipe_screen *, unsigned pctx_id); diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c index a25c082a5d..79253f8a2b 100644 --- a/src/gallium/drivers/nv10/nv10_context.c +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -264,7 +264,6 @@ 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; - unsigned chipset = screen->chipset; struct nouveau_winsys *nvws = screen->nvws; nv10 = CALLOC(1, sizeof(struct nv10_context)); @@ -273,7 +272,6 @@ nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) nv10->screen = screen; nv10->pctx_id = pctx_id; - nv10->chipset = chipset; nv10->nvws = nvws; nv10->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index 1b794c1872..433d04dc2a 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -43,8 +43,6 @@ struct nv10_context { struct draw_context *draw; - int chipset; - uint32_t dirty; struct nv10_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index cf6b2fac84..fad96058b8 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -8,9 +8,10 @@ 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", nv10screen->chipset); + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); return buffer; } @@ -129,16 +130,15 @@ nv10_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +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->chipset = chipset; screen->nvws = nvws; /* 3D object */ diff --git a/src/gallium/drivers/nv10/nv10_screen.h b/src/gallium/drivers/nv10/nv10_screen.h index 4192fe11ef..3f8750a13f 100644 --- a/src/gallium/drivers/nv10/nv10_screen.h +++ b/src/gallium/drivers/nv10/nv10_screen.h @@ -7,7 +7,6 @@ struct nv10_screen { struct pipe_screen pipe; struct nouveau_winsys *nvws; - unsigned chipset; /* HW graphics objects */ struct nouveau_grobj *celsius; diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 4b0892971e..7a2fee7875 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -44,7 +44,6 @@ 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; - unsigned chipset = screen->chipset; struct nouveau_winsys *nvws = screen->nvws; nv30 = CALLOC(1, sizeof(struct nv30_context)); @@ -53,7 +52,6 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) nv30->screen = screen; nv30->pctx_id = pctx_id; - nv30->chipset = chipset; nv30->nvws = nvws; nv30->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 1a016405e6..f49450f82d 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -85,8 +85,6 @@ struct nv30_context { struct draw_context *draw; - int chipset; - uint32_t dirty; struct nv30_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 1de4507904..9b0ac55ff8 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -12,9 +12,10 @@ 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", screen->chipset); + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); return buffer; } @@ -140,17 +141,16 @@ nv30_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +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->chipset = chipset; screen->nvws = nvws; /* 3D object */ diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h index 56f8776a17..816ece94c4 100644 --- a/src/gallium/drivers/nv30/nv30_screen.h +++ b/src/gallium/drivers/nv30/nv30_screen.h @@ -7,7 +7,6 @@ struct nv30_screen { struct pipe_screen pipe; struct nouveau_winsys *nvws; - unsigned chipset; /* HW graphics objects */ struct nouveau_grobj *rankine; diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index f9c93f7a2d..d9d9accea8 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -38,7 +38,6 @@ 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; - unsigned chipset = screen->chipset; struct nouveau_winsys *nvws = screen->nvws; nv40 = CALLOC(1, sizeof(struct nv40_context)); @@ -47,7 +46,6 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40->screen = screen; nv40->pctx_id = pctx_id; - nv40->chipset = chipset; nv40->nvws = nvws; nv40->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 24e8cd2337..77b3da0ab9 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -111,8 +111,6 @@ struct nv40_context { struct draw_context *draw; - int chipset; - /* HW state derived from pipe states */ struct nv40_state state; struct { diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 7f68539a85..1bf0931e4d 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -12,9 +12,10 @@ 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", screen->chipset); + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); return buffer; } @@ -149,17 +150,16 @@ nv40_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +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; int ret; if (!screen) return NULL; - screen->chipset = chipset; screen->nvws = nvws; /* 3D object */ diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index 3ea78aadfd..c04a1275a0 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -7,7 +7,6 @@ struct nv40_screen { struct pipe_screen pipe; struct nouveau_winsys *nvws; - unsigned chipset; unsigned cur_pctx; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index e4ca72c717..d069639dc4 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -45,9 +45,10 @@ 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", screen->chipset); + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); return buffer; } @@ -123,17 +124,16 @@ nv50_screen_destroy(struct pipe_screen *pscreen) } struct pipe_screen * -nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) +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->chipset = chipset; screen->nvws = nvws; /* 3D object */ diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 6e4120d669..5a2732e37f 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -7,7 +7,6 @@ struct nv50_screen { struct pipe_screen pipe; struct nouveau_winsys *nvws; - unsigned chipset; unsigned cur_pctx; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 635fd478a9..5eabbc8893 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -91,8 +91,7 @@ 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 *, - unsigned chipset); + struct nouveau_winsys *); struct pipe_context *(*hw_create)(struct pipe_screen *, unsigned); struct pipe_winsys *ws; unsigned chipset = nv->nv_screen->device->chipset; @@ -152,7 +151,7 @@ nouveau_pipe_create(struct nouveau_context *nv) ws = nouveau_create_pipe_winsys(nv); if (!nvc->pscreen) - nvc->pscreen = hws_create(ws, nvws, chipset); + nvc->pscreen = hws_create(ws, nvws); nvc->pctx[nv->pctx_id] = hw_create(nvc->pscreen, nv->pctx_id); return nvc->pctx[nv->pctx_id]; } -- cgit v1.2.3 From 666ac923f016b1b231c5a8847cbe084321f697ca Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 14 May 2008 00:25:09 +1000 Subject: nouveau: remove winsys-related stuff from nouveau_local.h --- src/gallium/winsys/dri/nouveau/nouveau_local.h | 21 +++++++-------- src/gallium/winsys/dri/nouveau/nv04_surface.c | 36 ++++++++++++++------------ src/gallium/winsys/dri/nouveau/nv50_surface.c | 21 ++++++++------- 3 files changed, 42 insertions(+), 36 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_local.h b/src/gallium/winsys/dri/nouveau/nouveau_local.h index 8a52f26714..e878a40803 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_local.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_local.h @@ -74,45 +74,44 @@ BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc) } static INLINE void -OUT_RELOC(struct nouveau_channel *chan, struct pipe_buffer *buf, +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++, - nouveau_buffer(buf)->bo, + 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 pipe_buffer *buf, +OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, unsigned data, unsigned flags, unsigned vor, unsigned tor) { - OUT_RELOC(chan, buf, data, flags | NOUVEAU_BO_OR, vor, 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 pipe_buffer *buf, +OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, unsigned flags) { - OUT_RELOC(chan, buf, 0, flags | NOUVEAU_BO_OR, + 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 pipe_buffer *buf, +OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, unsigned delta, unsigned flags) { - OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_LOW, 0, 0); + 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 pipe_buffer *buf, +OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, unsigned delta, unsigned flags) { - OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_HIGH, 0, 0); + OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); } #endif diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index dc167e4acf..83c790db17 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -43,10 +43,10 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, BEGIN_RING(chan, nv->nvc->NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RELOCl(chan, src->buffer, src_offset, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCl(chan, dst->buffer, dst_offset, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_WR); + 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); @@ -88,10 +88,10 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, 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, src->buffer, NOUVEAU_BO_GART | - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_GART | - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + 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; @@ -108,17 +108,19 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, BEGIN_RING(chan, nv->nvc->NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + 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, src->buffer, src->offset, + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, dst->buffer, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); return 0; @@ -151,15 +153,17 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, } BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + 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, dst->buffer, dst->offset, + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst->buffer, dst->offset, + 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); diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index 5c6733e44a..d6da116b77 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -29,8 +29,10 @@ nv50_surface_copy_prep(struct nouveau_context *nv, assert(surf_format >= 0); BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2); - OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + 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); @@ -39,9 +41,9 @@ nv50_surface_copy_prep(struct nouveau_context *nv, OUT_RING (chan, dst->pitch * dst->cpp); OUT_RING (chan, dst->pitch); OUT_RING (chan, dst->height); - OUT_RELOCh(chan, dst->buffer, dst->offset, + OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst->buffer, dst->offset, + 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); @@ -56,9 +58,9 @@ nv50_surface_copy_prep(struct nouveau_context *nv, OUT_RING (chan, src->pitch * src->cpp); OUT_RING (chan, src->pitch); OUT_RING (chan, src->height); - OUT_RELOCh(chan, src->buffer, src->offset, + OUT_RELOCh(chan, nouveau_buffer(src->buffer)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, src->buffer, src->offset, + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); return 0; @@ -112,7 +114,8 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, return 1; BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1); - OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + 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); @@ -120,9 +123,9 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, OUT_RING (chan, dst->pitch * dst->cpp); OUT_RING (chan, dst->pitch); OUT_RING (chan, dst->height); - OUT_RELOCh(chan, dst->buffer, dst->offset, + OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst->buffer, dst->offset, + 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); -- cgit v1.2.3 From 9a01ee4424718e0c3015c1f0477cae63ee63d96b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 14 May 2008 18:35:37 +1000 Subject: nv40: fix typo in one of the previous commits --- src/gallium/drivers/nv40/nv40_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 1bf0931e4d..0336b84e5f 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -155,7 +155,7 @@ 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; + unsigned chipset = nvws->channel->device->chipset; int ret; if (!screen) -- cgit v1.2.3 From f5599a7a3c4a6335ce79fdbd82e18f08bb0ac8e7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 25 May 2008 14:25:15 +1000 Subject: nouveau: remove final PIPE_FORMAT_U_* usage --- src/gallium/drivers/nv10/nv10_fragtex.c | 6 +++--- src/gallium/drivers/nv10/nv10_screen.c | 6 +++--- src/gallium/drivers/nv30/nv30_fragtex.c | 8 ++++---- src/gallium/drivers/nv30/nv30_screen.c | 8 ++++---- src/gallium/drivers/nv40/nv40_fragtex.c | 8 ++++---- src/gallium/drivers/nv40/nv40_screen.c | 8 ++++---- 6 files changed, 22 insertions(+), 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_fragtex.c b/src/gallium/drivers/nv10/nv10_fragtex.c index 67e0b4bd45..238634d0bb 100644 --- a/src/gallium/drivers/nv10/nv10_fragtex.c +++ b/src/gallium/drivers/nv10/nv10_fragtex.c @@ -44,9 +44,9 @@ nv10_texture_formats[] = { _(A8R8G8B8_UNORM, A8R8G8B8), _(A1R5G5B5_UNORM, A1R5G5B5), _(A4R4G4B4_UNORM, A4R4G4B4), - _(U_L8 , L8 ), - _(U_A8 , A8 ), - _(U_A8_L8 , A8L8 ), + _(L8_UNORM , L8 ), + _(A8_UNORM , A8 ), + _(A8L8_UNORM , A8L8 ), // _(RGB_DXT1 , DXT1, ), // _(RGBA_DXT1 , DXT1, ), // _(RGBA_DXT3 , DXT3, ), diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index fad96058b8..5fe3a03081 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -102,9 +102,9 @@ nv10_screen_is_format_supported(struct pipe_screen *screen, case PIPE_FORMAT_A1R5G5B5_UNORM: case PIPE_FORMAT_A4R4G4B4_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_U_L8: - case PIPE_FORMAT_U_A8: - case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: return TRUE; default: break; diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index 45ee6db8d6..47f3ff047d 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -50,10 +50,10 @@ nv30_texture_formats[] = { _(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), - _(U_L8 , L8 , S1, S1, S1, ONE, X, X, X, X), - _(U_A8 , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X), - _(U_I8 , L8 , S1, S1, S1, S1, X, X, X, X), - _(U_A8_L8 , A8L8 , S1, S1, S1, S1, X, X, X, Y), + _(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), diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 9b0ac55ff8..bb77776ff1 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -106,10 +106,10 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_A1R5G5B5_UNORM: case PIPE_FORMAT_A4R4G4B4_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_U_L8: - case PIPE_FORMAT_U_A8: - case PIPE_FORMAT_U_I8: - case PIPE_FORMAT_U_A8_L8: + 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; diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 980705f94a..c79ea8becb 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -24,10 +24,10 @@ nv40_texture_formats[] = { _(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), - _(U_L8 , L8 , S1, S1, S1, ONE, X, X, X, X), - _(U_A8 , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X), - _(U_I8 , L8 , S1, S1, S1, S1, X, X, X, X), - _(U_A8_L8 , A8L8 , S1, S1, S1, S1, X, X, X, Y), + _(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), diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 0336b84e5f..5164053393 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -111,10 +111,10 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_A1R5G5B5_UNORM: case PIPE_FORMAT_A4R4G4B4_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_U_L8: - case PIPE_FORMAT_U_A8: - case PIPE_FORMAT_U_I8: - case PIPE_FORMAT_U_A8_L8: + 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: -- cgit v1.2.3 From 8f67f98959261d193cb5f3db274b55fb24e2bb1e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 25 May 2008 14:26:18 +1000 Subject: nouveau: missed PCI case --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 792eaaa79e..aca16a8b12 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -310,7 +310,8 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) /* 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) && (flags & NOUVEAU_BO_GART)) + 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; -- cgit v1.2.3 From fa4b2439d4f240a5e573d4ea198b829791d614f4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 27 May 2008 01:22:22 +1000 Subject: nouveau: very quick port to tex-surface changes. probably the last match-gallium-upstream merge for a bit, some cleanup+nv50 work coming RSN... --- src/gallium/drivers/nv10/nv10_context.c | 1 - src/gallium/drivers/nv10/nv10_context.h | 1 - src/gallium/drivers/nv10/nv10_miptree.c | 11 +++++++---- src/gallium/drivers/nv10/nv10_screen.c | 25 +++++++++++++++++++++++++ src/gallium/drivers/nv30/nv30_context.c | 1 - src/gallium/drivers/nv30/nv30_context.h | 1 - src/gallium/drivers/nv30/nv30_miptree.c | 20 ++++++++------------ src/gallium/drivers/nv30/nv30_screen.c | 25 +++++++++++++++++++++++++ src/gallium/drivers/nv40/nv40_context.c | 1 - src/gallium/drivers/nv40/nv40_context.h | 1 - src/gallium/drivers/nv40/nv40_miptree.c | 20 ++++++++------------ src/gallium/drivers/nv40/nv40_screen.c | 25 +++++++++++++++++++++++++ src/gallium/drivers/nv50/nv50_context.c | 1 - src/gallium/drivers/nv50/nv50_context.h | 1 - src/gallium/drivers/nv50/nv50_miptree.c | 25 +++++++++++-------------- src/gallium/drivers/nv50/nv50_screen.c | 25 +++++++++++++++++++++++++ 16 files changed, 134 insertions(+), 50 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c index 79253f8a2b..9fcd0b0fc3 100644 --- a/src/gallium/drivers/nv10/nv10_context.c +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -285,7 +285,6 @@ nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) nv10_init_surface_functions(nv10); nv10_init_state_functions(nv10); - nv10_init_miptree_functions(nv10); nv10->draw = draw_create(); assert(nv10->draw); diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index 433d04dc2a..5636dfc9d2 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -109,7 +109,6 @@ nv10_context(struct pipe_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_init_miptree_functions(struct nv10_context *nv10); extern void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen); diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c index 4dfc675a6b..1b9947354d 100644 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -52,7 +52,7 @@ nv10_miptree_layout(struct nv10_miptree *nv10mt) } static struct pipe_texture * -nv10_miptree_create(struct pipe_screen *screen, struct pipe_texture *pt) +nv10_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) { struct pipe_winsys *ws = screen->winsys; struct nv10_miptree *mt; @@ -105,7 +105,8 @@ nv10_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, static struct pipe_surface * nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) + unsigned face, unsigned level, unsigned zslice, + unsigned flags) { struct pipe_winsys *ws = screen->winsys; struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt; @@ -130,9 +131,10 @@ nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, return ps; } -void nv10_init_miptree_functions(struct nv10_context *nv10) +static void +nv10_miptree_surface_release(struct pipe_screen *screen, + struct pipe_surface **surface) { - nv10->pipe.texture_update = nv10_miptree_update; } void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen) @@ -140,5 +142,6 @@ 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_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index 5fe3a03081..67787d8e9c 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -117,6 +117,28 @@ nv10_screen_is_format_supported(struct pipe_screen *screen, 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) { @@ -180,6 +202,9 @@ nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) 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/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 7a2fee7875..b2d9d3f181 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -66,7 +66,6 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) nv30_init_query_functions(nv30); nv30_init_surface_functions(nv30); nv30_init_state_functions(nv30); - nv30_init_miptree_functions(nv30); /* Create, configure, and install fallback swtnl path */ nv30->draw = draw_create(); diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index f49450f82d..333bd4875c 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -134,7 +134,6 @@ nv30_context(struct pipe_context *pipe) extern void nv30_init_state_functions(struct nv30_context *nv30); extern void nv30_init_surface_functions(struct nv30_context *nv30); -extern void nv30_init_miptree_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); diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index 10ab46e19a..6078b1865e 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -100,15 +100,10 @@ nv30_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) } } -static void -nv30_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, - uint face, uint levels) -{ -} - static struct pipe_surface * -nv30_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) +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; @@ -136,10 +131,10 @@ nv30_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, return ps; } -void -nv30_init_miptree_functions(struct nv30_context *nv30) +static void +nv30_miptree_surface_del(struct pipe_screen *pscreen, + struct pipe_surface **psurface) { - nv30->pipe.texture_update = nv30_miptree_update; } void @@ -147,6 +142,7 @@ 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; + pscreen->get_tex_surface = nv30_miptree_surface_new; + pscreen->tex_surface_release = nv30_miptree_surface_del; } diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index bb77776ff1..9c57636989 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -124,6 +124,28 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen, 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) { @@ -300,6 +322,9 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) 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/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index d9d9accea8..a40f14895f 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -59,7 +59,6 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40_init_query_functions(nv40); nv40_init_surface_functions(nv40); nv40_init_state_functions(nv40); - nv40_init_miptree_functions(nv40); /* Create, configure, and install fallback swtnl path */ nv40->draw = draw_create(); diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 77b3da0ab9..d8d1891dff 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -172,7 +172,6 @@ struct nv40_state_entry { extern void nv40_init_state_functions(struct nv40_context *nv40); extern void nv40_init_surface_functions(struct nv40_context *nv40); -extern void nv40_init_miptree_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); diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 1b19217223..23da6e36a3 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -100,15 +100,10 @@ nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) } } -static void -nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, - uint face, uint levels) -{ -} - static struct pipe_surface * -nv40_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) +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; @@ -136,10 +131,10 @@ nv40_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, return ps; } -void -nv40_init_miptree_functions(struct nv40_context *nv40) +static void +nv40_miptree_surface_del(struct pipe_screen *pscreen, + struct pipe_surface **psurface) { - nv40->pipe.texture_update = nv40_miptree_update; } void @@ -147,6 +142,7 @@ 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; + pscreen->get_tex_surface = nv40_miptree_surface_new; + pscreen->tex_surface_release = nv40_miptree_surface_del; } diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 5164053393..ed0215b486 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -133,6 +133,28 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, 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) { @@ -282,6 +304,9 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) 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/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 6eb1878b84..a225c4bf72 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -55,7 +55,6 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) nv50->pipe.flush = nv50_flush; - nv50_init_miptree_functions(nv50); nv50_init_surface_functions(nv50); nv50_init_state_functions(nv50); nv50_init_query_functions(nv50); diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index f532fa6bfb..e68c702dea 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -71,7 +71,6 @@ nv50_context(struct pipe_context *pipe) return (struct nv50_context *)pipe; } -extern void nv50_init_miptree_functions(struct nv50_context *nv50); 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); diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 58584934b1..ccb916d6ac 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -56,8 +56,9 @@ nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) } static struct pipe_surface * -nv50_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) +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); @@ -80,22 +81,18 @@ nv50_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt, return ps; } -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; -} - static void -nv50_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, - uint face, uint levels) +nv50_miptree_surface_del(struct pipe_screen *pscreen, + struct pipe_surface **psurface) { } void -nv50_init_miptree_functions(struct nv50_context *nv50) +nv50_screen_init_miptree_functions(struct pipe_screen *pscreen) { - nv50->pipe.texture_update = nv50_miptree_update; + 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_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index d069639dc4..29c057a145 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -117,6 +117,28 @@ nv50_screen_get_paramf(struct pipe_screen *pscreen, int param) } } +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) { @@ -209,6 +231,9 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) 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; -- cgit v1.2.3 From d0c0c0d1e67f92df8866e6218b868b3de954a5e1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 00:28:29 +1000 Subject: nouveau: oops, more tex-surfaces fallout --- src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index 755c8b6997..2fab1eab65 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -42,7 +42,8 @@ nouveau_surface_alloc(struct pipe_winsys *ws) static int nouveau_surface_alloc_storage(struct pipe_winsys *ws, struct pipe_surface *surf, unsigned width, unsigned height, - enum pipe_format format, unsigned flags) + enum pipe_format format, unsigned flags, + unsigned tex_usage) { unsigned pitch = ((width * pf_get_size(format)) + 63) & ~63; -- cgit v1.2.3 From 524408f1a5b39c8c25a277e41e4eee54fd726b84 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 00:38:07 +1000 Subject: nouveau: rework buffer validation a bit --- src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 20 +++-- src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 109 ++++++++++++----------- 2 files changed, 69 insertions(+), 60 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index a31c9a514b..5829f649cd 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -107,7 +107,7 @@ extern void nouveau_fence_flush(struct nouveau_channel *); struct nouveau_pushbuf_reloc { - uint64_t next; + struct nouveau_pushbuf_bo *pbbo; uint32_t *ptr; uint32_t flags; uint32_t data; @@ -116,13 +116,14 @@ struct nouveau_pushbuf_reloc { }; struct nouveau_pushbuf_bo { - uint64_t next; - uint64_t handle; - uint64_t flags; - uint64_t relocs; - int nr_relocs; + 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; @@ -132,8 +133,10 @@ struct nouveau_pushbuf_priv { unsigned start; unsigned size; - uint64_t buffers; - int nr_buffers; + 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)) @@ -242,6 +245,7 @@ nouveau_notifier_wait_status(struct nouveau_notifier *, int id, int status, struct nouveau_bo_priv { struct nouveau_bo base; + struct nouveau_pushbuf_bo *pending; struct nouveau_fence *fence; struct nouveau_fence *wr_fence; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c index 78919bdee8..815046ba85 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c @@ -97,6 +97,10 @@ nouveau_pushbuf_init(struct nouveau_channel *chan) 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; } @@ -131,8 +135,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) { struct nouveau_channel_priv *nvchan = nouveau_channel(chan); struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; - struct nouveau_pushbuf_bo *pbbo; - int ret; + int ret, i; if (nvpb->base.remaining == nvpb->size) return 0; @@ -150,38 +153,47 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) /* Validate buffers + apply relocations */ nvchan->user_charge = 0; - while ((pbbo = ptr_to_pbbo(nvpb->buffers))) { - struct nouveau_pushbuf_reloc *r; - struct nouveau_bo *bo = &ptr_to_bo(pbbo->handle)->base; - - ret = nouveau_bo_validate(chan, bo, pbbo->flags); - assert (ret == 0); - - if (bo->offset == nouveau_bo(bo)->offset && - bo->flags == nouveau_bo(bo)->flags) { + 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; + } - while ((r = ptr_to_pbrel(pbbo->relocs))) { - pbbo->relocs = r->next; - free(r); + /* 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; - nouveau_bo_del(&bo); - nvpb->buffers = pbbo->next; - free(pbbo); - continue; + 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; } - bo->offset = nouveau_bo(bo)->offset; - bo->flags = nouveau_bo(bo)->flags; - while ((r = ptr_to_pbrel(pbbo->relocs))) { - *r->ptr = nouveau_pushbuf_calc_reloc(bo, r); - pbbo->relocs = r->next; - free(r); - } + /* 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_del(&bo); - nvpb->buffers = pbbo->next; - free(pbbo); + nouveau_bo(pbbo->bo)->pending = NULL; + nouveau_bo_del(&pbbo->bo); } nvpb->nr_buffers = 0; @@ -206,25 +218,21 @@ 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_pushbuf_bo *pbbo = ptr_to_pbbo(nvpb->buffers); - struct nouveau_bo *ref = NULL; + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct nouveau_pushbuf_bo *pbbo; - while (pbbo) { - if (pbbo->handle == bo->handle) - return pbbo; - pbbo = ptr_to_pbbo(pbbo->next); - } + if (nvbo->pending) + return nvbo->pending; - pbbo = malloc(sizeof(struct nouveau_pushbuf_bo)); - pbbo->next = nvpb->buffers; - nvpb->buffers = pbbo_to_ptr(pbbo); - nvpb->nr_buffers++; + 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, &ref); - pbbo->handle = bo_to_ptr(ref); + nouveau_bo_ref(bo->device, bo->handle, &pbbo->bo); + pbbo->channel = chan; pbbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; - pbbo->relocs = 0; - pbbo->nr_relocs = 0; + pbbo->handled = 0; return pbbo; } @@ -233,24 +241,21 @@ 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 (!chan) - return -EINVAL; + if (nvpb->nr_relocs >= NOUVEAU_PUSHBUF_MAX_RELOCS) + return -ENOMEM; pbbo = nouveau_pushbuf_emit_buffer(chan, bo); if (!pbbo) - return -EFAULT; - - r = malloc(sizeof(struct nouveau_pushbuf_reloc)); - r->next = pbbo->relocs; - pbbo->relocs = pbrel_to_ptr(r); - pbbo->nr_relocs++; - + 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; -- cgit v1.2.3 From 8b31d5fc8a5425b01adf80f4873cb816925ee0d1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 11:00:59 +1000 Subject: nouveau: flush pending pushbuf if buffer on validate list at map/del --- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index aca16a8b12..57f5b7d1ae 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -256,6 +256,9 @@ nouveau_bo_del(struct nouveau_bo **bo) 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 @@ -270,6 +273,11 @@ nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) 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 -- cgit v1.2.3 From 996b549fdbfe772ee56a51858e81e93bccaae5c5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 11:04:55 +1000 Subject: nv40: a couple of memory leaks --- src/gallium/drivers/nv40/nv40_state_viewport.c | 3 ++- src/gallium/drivers/nv40/nv40_vertprog.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 1b6248e5b8..869a55b405 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -3,8 +3,8 @@ static boolean nv40_state_viewport_validate(struct nv40_context *nv40) { - struct nouveau_stateobj *so = so_new(11, 0); struct pipe_viewport_state *vpt = &nv40->viewport; + struct nouveau_stateobj *so; unsigned bypass; if (nv40->render_mode == HW && !nv40->rasterizer->pipe.bypass_clipping) @@ -18,6 +18,7 @@ nv40_state_viewport_validate(struct nv40_context *nv40) 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); diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index e10250528e..eb14869bfe 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -843,6 +843,12 @@ nv40_vertprog_translate(struct nv40_context *nv40, 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); } -- cgit v1.2.3 From cf13cf245e91669eb916a6d51676b0d66ff62ead Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 14:32:59 +1000 Subject: nouveau: fix warning --- src/gallium/winsys/dri/nouveau/nouveau_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index d9fc3f6ce1..ef5fb7ec0d 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -99,7 +99,7 @@ nouveau_context_create(const __GLcontextModes *glVis, struct st_context *st_share = NULL; struct nouveau_channel_context *nvc = NULL; struct nouveau_device *dev = nv_screen->device; - int i, ret; + int i; if (sharedContextPrivate) { st_share = ((struct nouveau_context *)sharedContextPrivate)->st; -- cgit v1.2.3 From edea59e8e5a3ef4c6afdcb4f1d32961466be508b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 8 Jun 2008 12:50:47 +1000 Subject: nouveau: kill off surface_alloc_storage() --- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 23 ---------------------- 1 file changed, 23 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index 2fab1eab65..ba5dd2eea4 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -39,28 +39,6 @@ nouveau_surface_alloc(struct pipe_winsys *ws) return surf; } -static int -nouveau_surface_alloc_storage(struct pipe_winsys *ws, struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, unsigned flags, - unsigned tex_usage) -{ - unsigned pitch = ((width * pf_get_size(format)) + 63) & ~63; - - surf->format = format; - surf->width = width; - surf->height = height; - surf->cpp = pf_get_size(format); - surf->pitch = pitch / surf->cpp; - - surf->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, - pitch * height); - if (!surf->buffer) - return 1; - - return 0; -} - static void nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) { @@ -226,7 +204,6 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) pws->flush_frontbuffer = nouveau_flush_frontbuffer; pws->surface_alloc = nouveau_surface_alloc; - pws->surface_alloc_storage = nouveau_surface_alloc_storage; pws->surface_release = nouveau_surface_release; pws->buffer_create = nouveau_pipe_bo_create; -- cgit v1.2.3 From c11a7ec821d41b91a3825c5abfb4687c98b5bf98 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 8 Jun 2008 03:04:14 -0400 Subject: Initial commit for g3dvl. Initial commit for g3dvl, contains support for basic XvMC features. - Context, surface, block, macroblock creation and deletion - Surface rendering - Frame pictures - Frame based motion compensation - Intra-coded macroblocks - Predicted macroblocks - Bi-directionally predicted macroblocks - Surface display - Color conversion - Scaling --- src/gallium/state_trackers/g3dvl/Makefile | 18 + src/gallium/state_trackers/g3dvl/tests/.gitignore | 6 + src/gallium/state_trackers/g3dvl/tests/Makefile | 42 + .../state_trackers/g3dvl/tests/test_b_rendering.c | 226 ++ .../state_trackers/g3dvl/tests/test_context.c | 22 + .../state_trackers/g3dvl/tests/test_i_rendering.c | 137 ++ .../state_trackers/g3dvl/tests/test_p_rendering.c | 214 ++ .../state_trackers/g3dvl/tests/test_surface.c | 26 + src/gallium/state_trackers/g3dvl/vl_context.c | 2293 ++++++++++++++++++++ src/gallium/state_trackers/g3dvl/vl_context.h | 73 + src/gallium/state_trackers/g3dvl/vl_data.c | 188 ++ src/gallium/state_trackers/g3dvl/vl_data.h | 25 + src/gallium/state_trackers/g3dvl/vl_defs.h | 12 + src/gallium/state_trackers/g3dvl/vl_surface.c | 539 +++++ src/gallium/state_trackers/g3dvl/vl_surface.h | 81 + src/gallium/state_trackers/g3dvl/vl_types.h | 88 + src/gallium/winsys/g3dvl/xsp_winsys.c | 256 +++ src/gallium/winsys/g3dvl/xsp_winsys.h | 11 + src/libXvMC/Makefile | 33 + src/libXvMC/attributes.c | 20 + src/libXvMC/block.c | 85 + src/libXvMC/context.c | 154 ++ src/libXvMC/subpicture.c | 110 + src/libXvMC/surface.c | 373 ++++ src/libXvMC/tests/.gitignore | 5 + src/libXvMC/tests/Makefile | 25 + src/libXvMC/tests/test_blocks.c | 95 + src/libXvMC/tests/test_context.c | 94 + src/libXvMC/tests/test_rendering.c | 153 ++ src/libXvMC/tests/test_surface.c | 72 + src/libXvMC/tests/testlib.c | 87 + src/libXvMC/tests/testlib.h | 38 + 32 files changed, 5601 insertions(+) create mode 100644 src/gallium/state_trackers/g3dvl/Makefile create mode 100644 src/gallium/state_trackers/g3dvl/tests/.gitignore create mode 100644 src/gallium/state_trackers/g3dvl/tests/Makefile create mode 100644 src/gallium/state_trackers/g3dvl/tests/test_b_rendering.c create mode 100644 src/gallium/state_trackers/g3dvl/tests/test_context.c create mode 100644 src/gallium/state_trackers/g3dvl/tests/test_i_rendering.c create mode 100644 src/gallium/state_trackers/g3dvl/tests/test_p_rendering.c create mode 100644 src/gallium/state_trackers/g3dvl/tests/test_surface.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_context.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_context.h create mode 100644 src/gallium/state_trackers/g3dvl/vl_data.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_data.h create mode 100644 src/gallium/state_trackers/g3dvl/vl_defs.h create mode 100644 src/gallium/state_trackers/g3dvl/vl_surface.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_surface.h create mode 100644 src/gallium/state_trackers/g3dvl/vl_types.h create mode 100644 src/gallium/winsys/g3dvl/xsp_winsys.c create mode 100644 src/gallium/winsys/g3dvl/xsp_winsys.h create mode 100644 src/libXvMC/Makefile create mode 100644 src/libXvMC/attributes.c create mode 100644 src/libXvMC/block.c create mode 100644 src/libXvMC/context.c create mode 100644 src/libXvMC/subpicture.c create mode 100644 src/libXvMC/surface.c create mode 100644 src/libXvMC/tests/.gitignore create mode 100644 src/libXvMC/tests/Makefile create mode 100644 src/libXvMC/tests/test_blocks.c create mode 100644 src/libXvMC/tests/test_context.c create mode 100644 src/libXvMC/tests/test_rendering.c create mode 100644 src/libXvMC/tests/test_surface.c create mode 100644 src/libXvMC/tests/testlib.c create mode 100644 src/libXvMC/tests/testlib.h (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/Makefile b/src/gallium/state_trackers/g3dvl/Makefile new file mode 100644 index 0000000000..a0d85fbcc8 --- /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 0000000000..939666da9a --- /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 0000000000..8f983593c3 --- /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 0000000000..b78cc851ae --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_b_rendering.c @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include + +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 0000000000..2002977ee2 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_context.c @@ -0,0 +1,22 @@ +#include +#include + +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 0000000000..1f96471130 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_i_rendering.c @@ -0,0 +1,137 @@ +#include +#include +#include +#include +#include + +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 0000000000..2203349784 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_p_rendering.c @@ -0,0 +1,214 @@ +#include +#include +#include +#include +#include + +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 0000000000..4d1946396a --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_surface.c @@ -0,0 +1,26 @@ +#include +#include +#include + +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 0000000000..7193f7ccea --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -0,0 +1,2293 @@ +#include "vl_context.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 = 4; + const unsigned int semantic_names[4] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC + }; + const unsigned int 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_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 + mov o3, i3 + */ + 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 < 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 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, i2, 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; + 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_attribs = 5; + const unsigned int semantic_names[5] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC + }; + const unsigned int 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_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 + 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_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 luma & chroma texcoords to output + mov o2, i2 + mov o3, i3 + */ + for (i = 1; i < num_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 + ); + } + + /* mul t0, i4, 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 = 4; + 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 o4, 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 = 4; + 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 < 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 < 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, i2, 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; + 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, i3, 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 = 3; + 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_attribs = 6; + const unsigned int semantic_names[6] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC + }; + const unsigned int semantic_indexes[6] = {0, 1, 2, 3, 4, 5}; + 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 + 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_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 luma & chroma texcoords to output + mov o2, i2 + mov o3, i3 + */ + for (i = 1; i < num_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 + ); + } + + /* mul t0, i4, c0 ; Scale normalized coords to window coords + add o4, t0, c2 ; Translate texcoords into position + mul t1, i5, c0 ; Repeat for the future surface + add o5, t1, c3 */ + for (i = 0; i < 2; ++i) + { + 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 = i; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i + 4; + 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 + ); + + 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 + 4; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = i; + 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 < 5; ++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, i2, 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; + 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, i3, s3 ; Read texel from past macroblock + tex2d t2, i4, 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 + 3; + 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 < 6; ++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 + ); + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, context->states.mc.vertex_bufs[3].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + vl_chroma_420_texcoords, + sizeof(struct VL_TEXCOORD2F) * 24 + ); + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, context->states.mc.vertex_bufs[4].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + vl_ref_surface_texcoords, + sizeof(struct VL_TEXCOORD2F) * 24 + ); + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, context->states.mc.vertex_bufs[5].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + vl_ref_surface_texcoords, + sizeof(struct VL_TEXCOORD2F) * 24 + ); + + for (i = 0; i < 6; ++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]); + context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.mc.vertex_bufs[i].buffer); + } + + context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.mc.vertex_bufs[5].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, VBs, VB elements set in vlRender*Macroblock() */ + 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 0000000000..0aeba184cc --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_context.h @@ -0,0 +1,73 @@ +#ifndef vl_context_h +#define vl_context_h + +#include +#include +#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[6]; + struct pipe_vertex_element vertex_buf_elems[6]; + 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 0000000000..c04163276d --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_data.c @@ -0,0 +1,188 @@ +#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 texcoords for the above for rendering a predicted macroblock. + * Straight forward 0,0->1,1 mapping so we can reuse MB pos vectors. + * Texcoords need to be translated to cover source macroblock on the + * past/future surface. + */ + const struct VL_TEXCOORD2F *vl_ref_surface_texcoords = (const struct VL_TEXCOORD2F*)vl_mb_vertex_positions; + +/* + * 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 0000000000..67a0a74990 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_data.h @@ -0,0 +1,25 @@ +#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_TEXCOORD2F *vl_ref_surface_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 0000000000..e668a7a10e --- /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 0000000000..e58e434dab --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -0,0 +1,539 @@ +#include "vl_surface.h" +#include +#include +#include +#include +#include +#include +#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->set_vertex_buffers(pipe, 4, surface->context->states.mc.vertex_bufs); + pipe->set_vertex_elements(pipe, 4, surface->context->states.mc.vertex_buf_elems); + 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->set_vertex_buffers(pipe, 5, surface->context->states.mc.vertex_bufs); + pipe->set_vertex_elements(pipe, 5, surface->context->states.mc.vertex_buf_elems); + 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->set_vertex_buffers(pipe, 6, surface->context->states.mc.vertex_bufs); + pipe->set_vertex_elements(pipe, 6, surface->context->states.mc.vertex_buf_elems); + 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 0000000000..9f56b77e1e --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_surface.h @@ -0,0 +1,81 @@ +#ifndef vl_surface_h +#define vl_surface_h + +#include +#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 0000000000..7040b74503 --- /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/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c new file mode 100644 index 0000000000..eb4c9085d6 --- /dev/null +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -0,0 +1,256 @@ +#include "xsp_winsys.h" +#include +#include +#include +#include +#include +#include + +/* 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 0000000000..47a6ac6e25 --- /dev/null +++ b/src/gallium/winsys/g3dvl/xsp_winsys.h @@ -0,0 +1,11 @@ +#ifndef xsp_winsys_h +#define xsp_winsys_h + +#include + +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 0000000000..b2f41e176d --- /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 0000000000..674524b8b8 --- /dev/null +++ b/src/libXvMC/attributes.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +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 0000000000..b56348d464 --- /dev/null +++ b/src/libXvMC/block.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include + +/* + * 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 0000000000..c835a6acf7 --- /dev/null +++ b/src/libXvMC/context.c @@ -0,0 +1,154 @@ +#include +#include +#include +#include +#include + +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 0000000000..38d9343833 --- /dev/null +++ b/src/libXvMC/subpicture.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include + +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 0000000000..e4602d8204 --- /dev/null +++ b/src/libXvMC/surface.c @@ -0,0 +1,373 @@ +#include +#include +#include +#include +#include + +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 0000000000..eb1ef8a076 --- /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 0000000000..2cbc97e88b --- /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 0000000000..0b895ee773 --- /dev/null +++ b/src/libXvMC/tests/test_blocks.c @@ -0,0 +1,95 @@ +#include +#include +#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 0000000000..22afb7ada4 --- /dev/null +++ b/src/libXvMC/tests/test_context.c @@ -0,0 +1,94 @@ +#include +#include +#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 0000000000..1914b1fb62 --- /dev/null +++ b/src/libXvMC/tests/test_rendering.c @@ -0,0 +1,153 @@ +#include +#include +#include +#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 0000000000..25ebdcc4fc --- /dev/null +++ b/src/libXvMC/tests/test_surface.c @@ -0,0 +1,72 @@ +#include +#include +#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 0000000000..8672aa9999 --- /dev/null +++ b/src/libXvMC/tests/testlib.c @@ -0,0 +1,87 @@ +#include "testlib.h" +#include + +/* +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 0000000000..c73845807e --- /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 +#include + +/* + * 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 + -- cgit v1.2.3 From f5a3768c4e7733a11ad0421e3e4b84e6994af0e0 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 8 Jun 2008 14:34:41 -0400 Subject: g3dvl: Reduce number of input vert streams by copying, reusing in shaders. Reduce number of input vertex streams by using same texcoord stream for chroma textures, reusing pos stream when calculating texcoords for P, B macroblocks. --- src/gallium/state_trackers/g3dvl/vl_context.c | 175 ++++++++++---------------- src/gallium/state_trackers/g3dvl/vl_context.h | 4 +- src/gallium/state_trackers/g3dvl/vl_data.c | 8 -- src/gallium/state_trackers/g3dvl/vl_data.h | 1 - src/gallium/state_trackers/g3dvl/vl_surface.c | 6 - 5 files changed, 66 insertions(+), 128 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 7193f7ccea..2d1d543495 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -32,15 +32,14 @@ static int vlDestroyIDCT(struct VL_CONTEXT *context) static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) { const unsigned int max_tokens = 50; - const unsigned int num_attribs = 4; - const unsigned int semantic_names[4] = + const unsigned int num_attribs = 3; + const unsigned int semantic_names[3] = { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC, TGSI_SEMANTIC_GENERIC, - TGSI_SEMANTIC_GENERIC }; - const unsigned int semantic_indexes[4] = {0, 1, 2, 3}; + const unsigned int semantic_indexes[3] = {0, 1, 2}; const unsigned int proc_type = TGSI_PROCESSOR_VERTEX; struct pipe_context *pipe; @@ -173,7 +172,6 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) /* mov o1, i1 ; Move texcoords to output mov o2, i2 - mov o3, i3 */ for (i = 1; i < num_attribs; ++i) { @@ -251,7 +249,7 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) ti = 3; /* Declare inputs (texcoords) */ - for (i = 0; i < 3; ++i) + for (i = 0; i < 2; ++i) { decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; @@ -306,7 +304,7 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) /* 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, i2, s2 ; Read texel from chroma Cr texture into .z channel + tex2d o0.z, i1, s2 ; Read texel from chroma Cr texture into .z channel */ for (i = 0; i < 3; ++i) { @@ -319,7 +317,7 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) inst.Instruction.NumSrcRegs = 2; inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = i; + 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 @@ -354,16 +352,23 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) { const unsigned int max_tokens = 100; - const unsigned int num_attribs = 5; - const unsigned int semantic_names[5] = + 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 semantic_indexes[5] = {0, 1, 2, 3, 4}; + 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; @@ -398,14 +403,14 @@ static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) ti = 3; /* Declare inputs (pos, texcoords) */ - for (i = 0; i < num_attribs; i++) + 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 = semantic_names[i]; - decl.Semantic.SemanticIndex = semantic_indexes[i]; + decl.Semantic.SemanticName = input_semantic_names[i]; + decl.Semantic.SemanticIndex = input_semantic_indexes[i]; decl.u.DeclarationRange.First = i; decl.u.DeclarationRange.Last = i; @@ -438,13 +443,13 @@ static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) ); /* Declare outputs (pos, texcoords) */ - for (i = 0; i < num_attribs; i++) + 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 = semantic_names[i]; - decl.Semantic.SemanticIndex = semantic_indexes[i]; + 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 @@ -497,9 +502,8 @@ static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) /* mov o1, i1 ; Move luma & chroma texcoords to output mov o2, i2 - mov o3, i3 */ - for (i = 1; i < num_attribs - 1; ++i) + for (i = 1; i < num_output_attribs - 1; ++i) { inst = tgsi_default_full_instruction(); inst.Instruction.Opcode = TGSI_OPCODE_MOV; @@ -517,32 +521,13 @@ static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) max_tokens - ti ); } - - /* mul t0, i4, 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 = 4; - 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 o4, t0, c2 ; Translate texcoords into position */ + /* 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 = 4; + inst.FullDstRegisters[0].DstRegister.Index = 3; inst.Instruction.NumSrcRegs = 2; inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; inst.FullSrcRegisters[0].SrcRegister.Index = 0; @@ -613,7 +598,7 @@ static int vlCreateFragmentShaderPMC(struct VL_CONTEXT *context) ti = 3; /* Declare inputs (texcoords) */ - for (i = 0; i < 4; ++i) + for (i = 0; i < 3; ++i) { decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; @@ -688,7 +673,7 @@ static int vlCreateFragmentShaderPMC(struct VL_CONTEXT *context) 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, i2, s2 ; Read texel from chroma Cr texture into .z and .w channels + 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) @@ -702,7 +687,7 @@ static int vlCreateFragmentShaderPMC(struct VL_CONTEXT *context) inst.Instruction.NumSrcRegs = 2; inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = i; + 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 @@ -792,7 +777,7 @@ static int vlCreateFragmentShaderPMC(struct VL_CONTEXT *context) max_tokens - ti ); - /* tex2d t1, i3, s3 ; Read texel from ref macroblock */ + /* tex2d t1, i2, s3 ; Read texel from ref macroblock */ inst = tgsi_default_full_instruction(); inst.Instruction.Opcode = TGSI_OPCODE_TEX; inst.Instruction.NumDstRegs = 1; @@ -801,7 +786,7 @@ static int vlCreateFragmentShaderPMC(struct VL_CONTEXT *context) inst.Instruction.NumSrcRegs = 2; inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = 3; + 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 @@ -854,17 +839,24 @@ static int vlCreateFragmentShaderPMC(struct VL_CONTEXT *context) static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) { const unsigned int max_tokens = 100; - const unsigned int num_attribs = 6; - const unsigned int semantic_names[6] = + 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 semantic_indexes[6] = {0, 1, 2, 3, 4, 5}; + 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; @@ -899,14 +891,14 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) ti = 3; /* Declare inputs (pos, texcoords) */ - for (i = 0; i < num_attribs; i++) + 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 = semantic_names[i]; - decl.Semantic.SemanticIndex = semantic_indexes[i]; + decl.Semantic.SemanticName = input_semantic_names[i]; + decl.Semantic.SemanticIndex = input_semantic_indexes[i]; decl.u.DeclarationRange.First = i; decl.u.DeclarationRange.Last = i; @@ -940,13 +932,13 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) ); /* Declare outputs (pos, texcoords) */ - for (i = 0; i < num_attribs; i++) + 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 = semantic_names[i]; - decl.Semantic.SemanticIndex = semantic_indexes[i]; + 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 @@ -999,9 +991,8 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) /* mov o1, i1 ; Move luma & chroma texcoords to output mov o2, i2 - mov o3, i3 */ - for (i = 1; i < num_attribs - 1; ++i) + for (i = 1; i < num_output_attribs - 2; ++i) { inst = tgsi_default_full_instruction(); inst.Instruction.Opcode = TGSI_OPCODE_MOV; @@ -1020,38 +1011,18 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) ); } - /* mul t0, i4, c0 ; Scale normalized coords to window coords - add o4, t0, c2 ; Translate texcoords into position - mul t1, i5, c0 ; Repeat for the future surface - add o5, t1, c3 */ + /* 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_MUL; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = i; - inst.Instruction.NumSrcRegs = 2; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = i + 4; - 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 - ); - 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 + 4; + inst.FullDstRegisters[0].DstRegister.Index = i + 3; inst.Instruction.NumSrcRegs = 2; inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = i; + 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 @@ -1120,7 +1091,7 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) ti = 3; /* Declare inputs (texcoords) */ - for (i = 0; i < 5; ++i) + for (i = 0; i < 4; ++i) { decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; @@ -1195,7 +1166,7 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) 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, i2, s2 ; Read texel from chroma Cr texture into .z and .w channels + 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) @@ -1209,7 +1180,7 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) inst.Instruction.NumSrcRegs = 2; inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = i; + 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 @@ -1299,8 +1270,8 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) max_tokens - ti ); - /* tex2d t1, i3, s3 ; Read texel from past macroblock - tex2d t2, i4, s4 ; Read texel from future macroblock */ + /* 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(); @@ -1311,7 +1282,7 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) inst.Instruction.NumSrcRegs = 2; inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = i + 3; + 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 @@ -1409,7 +1380,7 @@ int vlCreateDataBufsMC(struct VL_CONTEXT *context) /* 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 < 6; ++i) + 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; @@ -1448,26 +1419,8 @@ int vlCreateDataBufsMC(struct VL_CONTEXT *context) vl_chroma_420_texcoords, sizeof(struct VL_TEXCOORD2F) * 24 ); - memcpy - ( - pipe->winsys->buffer_map(pipe->winsys, context->states.mc.vertex_bufs[3].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), - vl_chroma_420_texcoords, - sizeof(struct VL_TEXCOORD2F) * 24 - ); - memcpy - ( - pipe->winsys->buffer_map(pipe->winsys, context->states.mc.vertex_bufs[4].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), - vl_ref_surface_texcoords, - sizeof(struct VL_TEXCOORD2F) * 24 - ); - memcpy - ( - pipe->winsys->buffer_map(pipe->winsys, context->states.mc.vertex_bufs[5].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), - vl_ref_surface_texcoords, - sizeof(struct VL_TEXCOORD2F) * 24 - ); - for (i = 0; i < 6; ++i) + for (i = 0; i < 3; ++i) pipe->winsys->buffer_unmap(pipe->winsys, context->states.mc.vertex_bufs[i].buffer); /* Create our constant buffer */ @@ -1599,12 +1552,10 @@ static int vlDestroyMC(struct VL_CONTEXT *context) assert(context); for (i = 0; i < 5; ++i) - { context->pipe->delete_sampler_state(context->pipe, context->states.mc.samplers[i]); - context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.mc.vertex_bufs[i].buffer); - } - context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.mc.vertex_bufs[5].buffer); + 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) @@ -2262,7 +2213,9 @@ int vlBeginRender(struct VL_CONTEXT *context) pipe = context->pipe; /* Frame buffer set in vlRender*Macroblock() */ - /* Shaders, samplers, textures, VBs, VB elements 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); diff --git a/src/gallium/state_trackers/g3dvl/vl_context.h b/src/gallium/state_trackers/g3dvl/vl_context.h index 0aeba184cc..f26a4c5b6a 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.h +++ b/src/gallium/state_trackers/g3dvl/vl_context.h @@ -36,8 +36,8 @@ struct VL_CONTEXT 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[6]; - struct pipe_vertex_element vertex_buf_elems[6]; + 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; diff --git a/src/gallium/state_trackers/g3dvl/vl_data.c b/src/gallium/state_trackers/g3dvl/vl_data.c index c04163276d..27893aee95 100644 --- a/src/gallium/state_trackers/g3dvl/vl_data.c +++ b/src/gallium/state_trackers/g3dvl/vl_data.c @@ -61,14 +61,6 @@ const struct VL_TEXCOORD2F *vl_chroma_422_texcoords = (const struct VL_TEXCOORD2 */ const struct VL_TEXCOORD2F *vl_chroma_444_texcoords = vl_luma_texcoords; -/* - * Represents texcoords for the above for rendering a predicted macroblock. - * Straight forward 0,0->1,1 mapping so we can reuse MB pos vectors. - * Texcoords need to be translated to cover source macroblock on the - * past/future surface. - */ - const struct VL_TEXCOORD2F *vl_ref_surface_texcoords = (const struct VL_TEXCOORD2F*)vl_mb_vertex_positions; - /* * Represents 2 triangles in a strip in normalized coords. * Used to render the surface onto the frame buffer. diff --git a/src/gallium/state_trackers/g3dvl/vl_data.h b/src/gallium/state_trackers/g3dvl/vl_data.h index 67a0a74990..8f347273ad 100644 --- a/src/gallium/state_trackers/g3dvl/vl_data.h +++ b/src/gallium/state_trackers/g3dvl/vl_data.h @@ -8,7 +8,6 @@ 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_TEXCOORD2F *vl_ref_surface_texcoords; extern const struct VL_VERTEX2F vl_surface_vertex_positions[4]; extern const struct VL_TEXCOORD2F *vl_surface_texcoords; diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index e58e434dab..0e1adea472 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -269,8 +269,6 @@ int vlRenderIMacroBlock 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->set_vertex_buffers(pipe, 4, surface->context->states.mc.vertex_bufs); - pipe->set_vertex_elements(pipe, 4, surface->context->states.mc.vertex_buf_elems); pipe->bind_vs_state(pipe, surface->context->states.mc.i_vs); pipe->bind_fs_state(pipe, surface->context->states.mc.i_fs); @@ -354,8 +352,6 @@ int vlRenderPMacroBlock 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->set_vertex_buffers(pipe, 5, surface->context->states.mc.vertex_bufs); - pipe->set_vertex_elements(pipe, 5, surface->context->states.mc.vertex_buf_elems); pipe->bind_vs_state(pipe, surface->context->states.mc.p_vs); pipe->bind_fs_state(pipe, surface->context->states.mc.p_fs); @@ -445,8 +441,6 @@ int vlRenderBMacroBlock 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->set_vertex_buffers(pipe, 6, surface->context->states.mc.vertex_bufs); - pipe->set_vertex_elements(pipe, 6, surface->context->states.mc.vertex_buf_elems); pipe->bind_vs_state(pipe, surface->context->states.mc.b_vs); pipe->bind_fs_state(pipe, surface->context->states.mc.b_fs); -- cgit v1.2.3 From 5e1d657d50c247d903b865572bd3e74048e8a8f1 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 20 Jun 2008 22:19:22 +0200 Subject: nv30: Add separate nv30 state stuff for fb, based on nv40 one, need to use it now --- src/gallium/drivers/nv30/Makefile | 1 + src/gallium/drivers/nv30/nv30_context.h | 18 ++++ src/gallium/drivers/nv30/nv30_state_fb.c | 151 +++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 src/gallium/drivers/nv30/nv30_state_fb.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile index 3f80fb87c9..ec11de7644 100644 --- a/src/gallium/drivers/nv30/Makefile +++ b/src/gallium/drivers/nv30/Makefile @@ -14,6 +14,7 @@ DRIVER_SOURCES = \ nv30_screen.c \ nv30_state.c \ nv30_state_emit.c \ + nv30_state_fb.c \ nv30_surface.c \ nv30_vbo.c \ nv30_vertprog.c diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 333bd4875c..9fbe66dc74 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -76,6 +76,10 @@ enum nv30_state_index { #define NV30_NEW_ARRAYS (1 << 11) #define NV30_NEW_UCP (1 << 12) +struct nv30_state { + struct nouveau_stateobj *hw[NV30_STATE_MAX]; +}; + struct nv30_context { struct pipe_context pipe; @@ -85,6 +89,9 @@ struct nv30_context { struct draw_context *draw; + /* HW state derived from pipe states */ + struct nv30_state state; + uint32_t dirty; struct nv30_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; @@ -93,6 +100,9 @@ struct nv30_context { unsigned fp_samplers; unsigned vp_samplers; + /* Context state */ + struct pipe_framebuffer_state framebuffer; + uint32_t rt_enable; struct pipe_buffer *rt[2]; struct pipe_buffer *zeta; @@ -132,6 +142,14 @@ 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); 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 0000000000..73c97e298a --- /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 + } +}; -- cgit v1.2.3 From 582b39ebb9f67e3b67a776be0961fe2e51ee46f7 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 21 Jun 2008 10:11:37 +0200 Subject: nv30: Update nouveau_class.h to get its proper defines instead of using nv40 ones --- src/gallium/drivers/nouveau/nouveau_class.h | 77 ++++++++++++++++++----------- src/gallium/drivers/nv30/nv30_state.c | 4 +- src/gallium/drivers/nv30/nv30_vbo.c | 34 ++++++------- 3 files changed, 66 insertions(+), 49 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index 880afe6ce0..58c80ddcd2 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -4,7 +4,7 @@ ************************************************************************** - Copyright (C) 2006-2007 : + Copyright (C) 2006-2008 : Dmitry Baryshkov, Laurent Carlier, Matthieu Castet, @@ -1740,6 +1740,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV04_DX6_MULTITEX_TRIANGLE_TLMTVERTEX_DRAWPRIMITIVE_I5_MASK 0x00f00000 +#define NV10_DX5_TEXTURED_TRIANGLE 0x00000094 + + + #define NV10TCL 0x00000056 #define NV10TCL_NOP 0x00000100 @@ -3871,13 +3875,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_FUNC_COLOR 0x0000031c -#define NV34TCL_BLEND_FUNC_EQUATION 0x00000320 -#define NV34TCL_BLEND_FUNC_EQUATION_FUNC_ADD 0x00008006 -#define NV34TCL_BLEND_FUNC_EQUATION_MIN 0x00008007 -#define NV34TCL_BLEND_FUNC_EQUATION_MAX 0x00008008 -#define NV34TCL_BLEND_FUNC_EQUATION_FUNC_SUBTRACT 0x0000800a -#define NV34TCL_BLEND_FUNC_EQUATION_FUNC_REVERSE_SUBTRACT 0x0000800b +#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 @@ -4217,6 +4221,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 @@ -4234,12 +4239,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV34TCL_POLYGON_STIPPLE_ENABLE 0x0000147c #define NV34TCL_POLYGON_STIPPLE_PATTERN(x) (0x00001480+((x)*4)) #define NV34TCL_POLYGON_STIPPLE_PATTERN__SIZE 0x00000020 -#define NV34TCL_VERTEX_ATTR_3F_X(x) (0x00001500+((x)*16)) -#define NV34TCL_VERTEX_ATTR_3F_X__SIZE 0x00000010 -#define NV34TCL_VERTEX_ATTR_3F_Y(x) (0x00001504+((x)*16)) -#define NV34TCL_VERTEX_ATTR_3F_Y__SIZE 0x00000010 -#define NV34TCL_VERTEX_ATTR_3F_Z(x) (0x00001508+((x)*16)) -#define NV34TCL_VERTEX_ATTR_3F_Z__SIZE 0x00000010 +#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)) @@ -4248,22 +4253,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_VERTEX_BUFFER_ADDRESS(x) (0x00001680+((x)*4)) -#define NV34TCL_VERTEX_BUFFER_ADDRESS__SIZE 0x00000010 -#define NV34TCL_VERTEX_BUFFER_ADDRESS_DMA1 (1 << 31) -#define NV34TCL_VERTEX_BUFFER_ADDRESS_OFFSET_SHIFT 0 -#define NV34TCL_VERTEX_BUFFER_ADDRESS_OFFSET_MASK 0x0fffffff -#define NV34TCL_VERTEX_ARRAY_FORMAT(x) (0x00001740+((x)*4)) -#define NV34TCL_VERTEX_ARRAY_FORMAT__SIZE 0x00000010 -#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_SHIFT 0 -#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_MASK 0x0000000f -#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT 0x00000002 -#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_UBYTE 0x00000004 -#define NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_USHORT 0x00000005 -#define NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_SHIFT 4 -#define NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_MASK 0x000000f0 -#define NV34TCL_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT 8 -#define NV34TCL_VERTEX_ARRAY_FORMAT_STRIDE_MASK 0x0000ff00 +#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 @@ -4302,6 +4307,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 620038fa64..84f016eead 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -51,7 +51,7 @@ nv30_blend_state_bind(struct pipe_context *pipe, void *hwcso) OUT_RING (cb->b_enable); OUT_RING (cb->b_srcfunc); OUT_RING (cb->b_dstfunc); - BEGIN_RING(rankine, NV34TCL_BLEND_FUNC_EQUATION, 1); + BEGIN_RING(rankine, NV34TCL_BLEND_EQUATION, 1); OUT_RING (cb->b_eqn); BEGIN_RING(rankine, NV34TCL_COLOR_MASK, 1); @@ -531,7 +531,7 @@ nv30_set_blend_color(struct pipe_context *pipe, { struct nv30_context *nv30 = nv30_context(pipe); - BEGIN_RING(rankine, NV34TCL_BLEND_FUNC_COLOR, 1); + 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) | diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index b18a407ec5..ff0ce6ac81 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -26,12 +26,12 @@ nv30_vbo_type(uint format) { switch (pf_type(format)) { case PIPE_FORMAT_TYPE_FLOAT: - return NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT; + return NV34TCL_VTXFMT_TYPE_FLOAT; case PIPE_FORMAT_TYPE_UNORM: - return NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_UBYTE; + return NV34TCL_VTXFMT_TYPE_UBYTE; default: NOUVEAU_ERR("Unknown format 0x%08x\n", format); - return NV40TCL_VTXFMT_TYPE_FLOAT; + return NV34TCL_VTXFMT_TYPE_FLOAT; } } @@ -51,7 +51,7 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, int attrib, map += vb->buffer_offset + ve->src_offset; switch (type) { - case NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT: + case NV34TCL_VTXFMT_TYPE_FLOAT: { float *v = map; @@ -121,7 +121,7 @@ nv30_vbo_arrays_update(struct nv30_context *nv30) struct pipe_vertex_buffer *vb; if (!(inputs & (1 << hw))) { - vtxfmt[hw] = NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT; + vtxfmt[hw] = NV34TCL_VTXFMT_TYPE_FLOAT; continue; } @@ -129,7 +129,7 @@ nv30_vbo_arrays_update(struct nv30_context *nv30) vb = &nv30->vtxbuf[ve->vertex_buffer_index]; if (vb->pitch == 0) { - vtxfmt[hw] = NV34TCL_VERTEX_ARRAY_FORMAT_TYPE_FLOAT; + vtxfmt[hw] = NV34TCL_VTXFMT_TYPE_FLOAT; if (nv30_vbo_static_attrib(nv30, hw, ve, vb) == TRUE) continue; } @@ -138,13 +138,13 @@ nv30_vbo_arrays_update(struct nv30_context *nv30) nv30->vb[hw].delta = vb->buffer_offset + ve->src_offset; nv30->vb[hw].buffer = vb->buffer; - vtxfmt[hw] = ((vb->pitch << NV34TCL_VERTEX_ARRAY_FORMAT_STRIDE_SHIFT) | + vtxfmt[hw] = ((vb->pitch << NV34TCL_VTXFMT_STRIDE_SHIFT) | (nv30_vbo_ncomp(ve->src_format) << - NV34TCL_VERTEX_ARRAY_FORMAT_SIZE_SHIFT) | + NV34TCL_VTXFMT_SIZE_SHIFT) | nv30_vbo_type(ve->src_format)); } - BEGIN_RING(rankine, NV34TCL_VERTEX_ARRAY_FORMAT(0), num_hw); + BEGIN_RING(rankine, NV34TCL_VTXFMT(0), num_hw); OUT_RINGp (vtxfmt, num_hw); } @@ -167,20 +167,20 @@ nv30_vbo_validate_state(struct nv30_context *nv30, inputs &= ~(1 << a); - BEGIN_RING(rankine, NV34TCL_VERTEX_BUFFER_ADDRESS(a), 1); + 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_VERTEX_BUFFER_ADDRESS_DMA1); + NV34TCL_VTXBUF_ADDRESS_DMA1); } if (ib) { - BEGIN_RING(rankine, NV40TCL_IDXBUF_ADDRESS, 2); + 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, NV40TCL_IDXBUF_FORMAT_DMA1); + 0, NV34TCL_IDXBUF_FORMAT_DMA1); } BEGIN_RING(rankine, 0x1710, 1); @@ -360,10 +360,10 @@ nv30_draw_elements_vbo(struct pipe_context *pipe, switch (ib_size) { case 2: - type = NV40TCL_IDXBUF_FORMAT_TYPE_U16; + type = NV34TCL_IDXBUF_FORMAT_TYPE_U16; break; case 4: - type = NV40TCL_IDXBUF_FORMAT_TYPE_U32; + type = NV34TCL_IDXBUF_FORMAT_TYPE_U32; break; default: NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size); @@ -381,7 +381,7 @@ nv30_draw_elements_vbo(struct pipe_context *pipe, nr = (count & 0xff); if (nr) { - BEGIN_RING(rankine, NV40TCL_VB_INDEX_BATCH, 1); + BEGIN_RING(rankine, NV34TCL_VB_INDEX_BATCH, 1); OUT_RING (((nr - 1) << 24) | start); start += nr; } @@ -392,7 +392,7 @@ nv30_draw_elements_vbo(struct pipe_context *pipe, nr -= push; - BEGIN_RING_NI(rankine, NV40TCL_VB_INDEX_BATCH, push); + BEGIN_RING_NI(rankine, NV34TCL_VB_INDEX_BATCH, push); while (push--) { OUT_RING(((0x100 - 1) << 24) | start); start += 0x100; -- cgit v1.2.3 From 5fea663b5f7abcdca00c5ff5d1b77f200b0d06ec Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 21 Jun 2008 12:03:05 +0200 Subject: nv30: Add state for blend --- src/gallium/drivers/nv30/Makefile | 1 + src/gallium/drivers/nv30/nv30_context.h | 9 +++++++ src/gallium/drivers/nv30/nv30_state_blend.c | 40 +++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 src/gallium/drivers/nv30/nv30_state_blend.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile index ec11de7644..04f53ee456 100644 --- a/src/gallium/drivers/nv30/Makefile +++ b/src/gallium/drivers/nv30/Makefile @@ -13,6 +13,7 @@ DRIVER_SOURCES = \ nv30_query.c \ nv30_screen.c \ nv30_state.c \ + nv30_state_blend.c \ nv30_state_emit.c \ nv30_state_fb.c \ nv30_surface.c \ diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 9fbe66dc74..1695ba5a01 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -76,6 +76,13 @@ enum nv30_state_index { #define NV30_NEW_ARRAYS (1 << 11) #define NV30_NEW_UCP (1 << 12) +/* 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 { struct nouveau_stateobj *hw[NV30_STATE_MAX]; }; @@ -101,6 +108,8 @@ struct nv30_context { unsigned vp_samplers; /* Context state */ + struct nv30_blend_state_new *blend; + struct pipe_blend_color blend_colour; struct pipe_framebuffer_state framebuffer; uint32_t rt_enable; 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 0000000000..a1b0100472 --- /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 + } +}; -- cgit v1.2.3 From 8c26a521ee80f5d8a1d0aabd0910233aad400322 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 21 Jun 2008 22:59:05 +0200 Subject: Update for extra vertex attributes --- src/gallium/drivers/nouveau/nouveau_class.h | 163 +++++++++++++++------------- src/gallium/drivers/nv30/nv30_vbo.c | 2 +- src/gallium/drivers/nv40/nv40_draw.c | 4 +- src/gallium/drivers/nv40/nv40_vbo.c | 2 +- 4 files changed, 93 insertions(+), 78 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index 58c80ddcd2..3c29fa0d1b 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -3763,7 +3763,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV34TCL_RT_ENABLE_COLOR2 (1 << 2) #define NV34TCL_RT_ENABLE_COLOR1 (1 << 1) #define NV34TCL_RT_ENABLE_COLOR0 (1 << 0) -#define NV34TCL_ZETA_PITCH 0x0000022c +#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) @@ -4145,14 +4145,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV34TCL_DEPTH_TEST_ENABLE 0x00000a74 #define NV34TCL_POLYGON_OFFSET_FACTOR 0x00000a78 #define NV34TCL_POLYGON_OFFSET_UNITS 0x00000a7c -#define NV34TCL_VERTEX_NOR_3I_XY 0x00000a90 -#define NV34TCL_VERTEX_NOR_3I_XY_X_SHIFT 0 -#define NV34TCL_VERTEX_NOR_3I_XY_X_MASK 0x0000ffff -#define NV34TCL_VERTEX_NOR_3I_XY_Y_SHIFT 16 -#define NV34TCL_VERTEX_NOR_3I_XY_Y_MASK 0xffff0000 -#define NV34TCL_VERTEX_NOR_3I_Z 0x00000a94 -#define NV34TCL_VERTEX_NOR_3I_Z_Z_SHIFT 0 -#define NV34TCL_VERTEX_NOR_3I_Z_Z_MASK 0x0000ffff +#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)) @@ -4336,48 +4338,38 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV34TCL_FRONT_FACE_CCW 0x00000901 #define NV34TCL_POLYGON_SMOOTH_ENABLE 0x00001838 #define NV34TCL_CULL_FACE_ENABLE 0x0000183c -#define NV34TCL_VERTEX_ATTR_2F_X(x) (0x00001880+((x)*8)) -#define NV34TCL_VERTEX_ATTR_2F_X__SIZE 0x00000010 -#define NV34TCL_VERTEX_ATTR_2F_Y(x) (0x00001884+((x)*8)) -#define NV34TCL_VERTEX_ATTR_2F_Y__SIZE 0x00000010 -#define NV34TCL_VERTEX_ATTR_2I(x) (0x00001900+((x)*4)) -#define NV34TCL_VERTEX_ATTR_2I__SIZE 0x00000010 -#define NV34TCL_VERTEX_ATTR_2I_Y_SHIFT 16 -#define NV34TCL_VERTEX_ATTR_2I_Y_MASK 0xffff0000 -#define NV34TCL_VERTEX_ATTR_2I_X_SHIFT 0 -#define NV34TCL_VERTEX_ATTR_2I_X_MASK 0x0000ffff -#define NV34TCL_VERTEX_COL_4I(x) (0x0000194c+((x)*4)) -#define NV34TCL_VERTEX_COL_4I__SIZE 0x00000002 -#define NV34TCL_VERTEX_COL_4I_R_SHIFT 0 -#define NV34TCL_VERTEX_COL_4I_R_MASK 0x000000ff -#define NV34TCL_VERTEX_COL_4I_G_SHIFT 8 -#define NV34TCL_VERTEX_COL_4I_G_MASK 0x0000ff00 -#define NV34TCL_VERTEX_COL_4I_B_SHIFT 16 -#define NV34TCL_VERTEX_COL_4I_B_MASK 0x00ff0000 -#define NV34TCL_VERTEX_COL_4I_A_SHIFT 24 -#define NV34TCL_VERTEX_COL_4I_A_MASK 0xff000000 -#define NV34TCL_VERTEX_POS_4I_XY 0x00001980 -#define NV34TCL_VERTEX_POS_4I_XY_X_SHIFT 0 -#define NV34TCL_VERTEX_POS_4I_XY_X_MASK 0x0000ffff -#define NV34TCL_VERTEX_POS_4I_XY_Y_SHIFT 16 -#define NV34TCL_VERTEX_POS_4I_XY_Y_MASK 0xffff0000 -#define NV34TCL_VERTEX_POS_4I_ZW 0x00001984 -#define NV34TCL_VERTEX_POS_4I_ZW_Z_SHIFT 0 -#define NV34TCL_VERTEX_POS_4I_ZW_Z_MASK 0x0000ffff -#define NV34TCL_VERTEX_POS_4I_ZW_W_SHIFT 16 -#define NV34TCL_VERTEX_POS_4I_ZW_W_MASK 0xffff0000 -#define NV34TCL_VERTEX_TX_4I_ST(x) (0x000019c0+((x)*8)) -#define NV34TCL_VERTEX_TX_4I_ST__SIZE 0x00000004 -#define NV34TCL_VERTEX_TX_4I_ST_S_SHIFT 0 -#define NV34TCL_VERTEX_TX_4I_ST_S_MASK 0x0000ffff -#define NV34TCL_VERTEX_TX_4I_ST_T_SHIFT 16 -#define NV34TCL_VERTEX_TX_4I_ST_T_MASK 0xffff0000 -#define NV34TCL_VERTEX_TX_4I_RQ(x) (0x000019c4+((x)*8)) -#define NV34TCL_VERTEX_TX_4I_RQ__SIZE 0x00000004 -#define NV34TCL_VERTEX_TX_4I_RQ_R_SHIFT 0 -#define NV34TCL_VERTEX_TX_4I_RQ_R_MASK 0x0000ffff -#define NV34TCL_VERTEX_TX_4I_RQ_Q_SHIFT 16 -#define NV34TCL_VERTEX_TX_4I_RQ_Q_MASK 0xffff0000 +#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)) @@ -4534,14 +4526,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_VERTEX_ATTR_4F_X(x) (0x00001c00+((x)*16)) -#define NV34TCL_VERTEX_ATTR_4F_X__SIZE 0x00000010 -#define NV34TCL_VERTEX_ATTR_4F_Y(x) (0x00001c04+((x)*16)) -#define NV34TCL_VERTEX_ATTR_4F_Y__SIZE 0x00000010 -#define NV34TCL_VERTEX_ATTR_4F_Z(x) (0x00001c08+((x)*16)) -#define NV34TCL_VERTEX_ATTR_4F_Z__SIZE 0x00000010 -#define NV34TCL_VERTEX_ATTR_4F_W(x) (0x00001c0c+((x)*16)) -#define NV34TCL_VERTEX_ATTR_4F_W__SIZE 0x00000010 +#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 @@ -4573,7 +4565,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_VERTEX_FOG_1F 0x00001e54 +#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)) @@ -4986,6 +4979,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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)) @@ -5095,22 +5098,32 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_Y_SHIFT 16 -#define NV40TCL_VTX_ATTR_2I_Y_MASK 0xffff0000 #define NV40TCL_VTX_ATTR_2I_X_SHIFT 0 #define NV40TCL_VTX_ATTR_2I_X_MASK 0x0000ffff -#define NV40TCL_VTX_ATTR_4I_0(x) (0x00001900+((x)*8)) -#define NV40TCL_VTX_ATTR_4I_0__SIZE 0x00000010 -#define NV40TCL_VTX_ATTR_4I_0_Y_SHIFT 16 -#define NV40TCL_VTX_ATTR_4I_0_Y_MASK 0xffff0000 -#define NV40TCL_VTX_ATTR_4I_0_X_SHIFT 0 -#define NV40TCL_VTX_ATTR_4I_0_X_MASK 0x0000ffff -#define NV40TCL_VTX_ATTR_4I_1(x) (0x00001904+((x)*8)) -#define NV40TCL_VTX_ATTR_4I_1__SIZE 0x00000010 -#define NV40TCL_VTX_ATTR_4I_1_W_SHIFT 16 -#define NV40TCL_VTX_ATTR_4I_1_W_MASK 0xffff0000 -#define NV40TCL_VTX_ATTR_4I_1_Z_SHIFT 0 -#define NV40TCL_VTX_ATTR_4I_1_Z_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)) @@ -5307,6 +5320,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index ff0ce6ac81..359e443bb1 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -55,7 +55,7 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, int attrib, { float *v = map; - BEGIN_RING(rankine, NV34TCL_VERTEX_ATTR_4F_X(attrib), 4); + BEGIN_RING(rankine, NV34TCL_VTX_ATTR_4F_X(attrib), 4); switch (ncomp) { case 4: OUT_RINGf(v[0]); diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index a9a939af0c..1d78324dda 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -39,7 +39,7 @@ nv40_render_vertex(struct nv40_context *nv40, const struct vertex_header *v) case EMIT_OMIT: break; case EMIT_1F: - BEGIN_RING(curie, 0x1e40 + (hw * 4), 1); + BEGIN_RING(curie, NV40TCL_VTX_ATTR_1F(hw), 1); OUT_RING (fui(v->data[idx][0])); break; case EMIT_2F: @@ -61,7 +61,7 @@ nv40_render_vertex(struct nv40_context *nv40, const struct vertex_header *v) OUT_RING (fui(v->data[idx][3])); break; case EMIT_4UB: - BEGIN_RING(curie, 0x1940 + (hw * 4), 1); + 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]), diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index e5f9bd5668..93669e6192 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -149,7 +149,7 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so, so_data (so, fui(v[1])); break; case 1: - so_method(so, curie, 0x1e40 + (attrib * 4), 1); + so_method(so, curie, NV40TCL_VTX_ATTR_1F(attrib), 1); so_data (so, fui(v[0])); break; default: -- cgit v1.2.3 From 5a01060eb95cb2cb168cb7224ecc805020584c91 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 23 Jun 2008 00:14:21 +1000 Subject: nouveau: update for interface changes + hack around gallium x86_64 bustage --- src/gallium/auxiliary/draw/draw_context.c | 2 ++ src/gallium/drivers/nv10/nv10_context.h | 1 + src/gallium/drivers/nv10/nv10_state.c | 2 ++ src/gallium/drivers/nv10/nv10_vbo.c | 4 +++- src/gallium/drivers/nv30/nv30_fragprog.c | 6 +++--- src/gallium/drivers/nv30/nv30_vertprog.c | 2 +- src/gallium/drivers/nv40/nv40_context.h | 1 + src/gallium/drivers/nv40/nv40_draw.c | 4 +++- src/gallium/drivers/nv40/nv40_fragprog.c | 8 ++++---- src/gallium/drivers/nv40/nv40_state.c | 5 +++-- src/gallium/drivers/nv40/nv40_vertprog.c | 10 +++++----- 11 files changed, 28 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 2f263cf06a..0e6f55a928 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; +#ifndef PIPE_ARCH_X86 if (!draw_vs_init( draw )) goto fail; +#endif return draw; diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index 5636dfc9d2..2bdba53db8 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -66,6 +66,7 @@ struct nv10_context { //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; diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 4dcb9a31ab..11664fae2a 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -469,6 +469,8 @@ nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, 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); } } diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c index 2a334e137d..f024f53420 100644 --- a/src/gallium/drivers/nv10/nv10_vbo.c +++ b/src/gallium/drivers/nv10/nv10_vbo.c @@ -44,7 +44,9 @@ boolean nv10_draw_elements( struct pipe_context *pipe, draw_set_mapped_element_buffer(draw, 0, NULL); } - draw_set_mapped_constant_buffer(draw, nv10->constbuf[PIPE_SHADER_VERTEX]); + 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); diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 51000bd6fc..54d6bea55f 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -645,7 +645,7 @@ nv30_fragprog_parse_decl_attrib(struct nv30_fpc *fpc, return FALSE; } - fpc->attrib_map[fdec->u.DeclarationRange.First] = hw; + fpc->attrib_map[fdec->DeclarationRange.First] = hw; return TRUE; } @@ -655,10 +655,10 @@ nv30_fragprog_parse_decl_output(struct nv30_fpc *fpc, { switch (fdec->Semantic.SemanticName) { case TGSI_SEMANTIC_POSITION: - fpc->depth_id = fdec->u.DeclarationRange.First; + fpc->depth_id = fdec->DeclarationRange.First; break; case TGSI_SEMANTIC_COLOR: - fpc->colour_id = fdec->u.DeclarationRange.First; + fpc->colour_id = fdec->DeclarationRange.First; break; default: NOUVEAU_ERR("bad output semantic\n"); diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 71aea3a59c..1b34d2e4b2 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -530,7 +530,7 @@ nv30_vertprog_parse_decl_output(struct nv30_vpc *vpc, return FALSE; } - vpc->output_map[fdec->u.DeclarationRange.First] = hw; + vpc->output_map[fdec->DeclarationRange.First] = hw; return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index d8d1891dff..8e60a81e68 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -136,6 +136,7 @@ struct nv40_context { 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; diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 1d78324dda..2cf58e2950 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -253,9 +253,11 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, } 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); + draw_set_mapped_constant_buffer(nv40->draw, map, nr); } draw_arrays(nv40->draw, mode, start, count); diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 4b7667e038..428348c338 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -708,7 +708,7 @@ nv40_fragprog_parse_decl_attrib(struct nv40_fpc *fpc, return FALSE; } - fpc->attrib_map[fdec->u.DeclarationRange.First] = hw; + fpc->attrib_map[fdec->DeclarationRange.First] = hw; return TRUE; } @@ -716,7 +716,7 @@ static boolean nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc, const struct tgsi_full_declaration *fdec) { - unsigned idx = fdec->u.DeclarationRange.First; + unsigned idx = fdec->DeclarationRange.First; unsigned hw; switch (fdec->Semantic.SemanticName) { @@ -770,9 +770,9 @@ nv40_fragprog_prepare(struct nv40_fpc *fpc) goto out_err; break; case TGSI_FILE_TEMPORARY: - if (fdec->u.DeclarationRange.Last > high_temp) { + if (fdec->DeclarationRange.Last > high_temp) { high_temp = - fdec->u.DeclarationRange.Last; + fdec->DeclarationRange.Last; } break; default: diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 2d921d2b8a..afcf336a65 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -603,12 +603,13 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, { 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->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; nv40->dirty |= NV40_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { - nv40->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; nv40->dirty |= NV40_NEW_FRAGPROG; } } diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index eb14869bfe..1e486a66ef 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -603,7 +603,7 @@ static boolean nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc, const struct tgsi_full_declaration *fdec) { - unsigned idx = fdec->u.DeclarationRange.First; + unsigned idx = fdec->DeclarationRange.First; int hw; switch (fdec->Semantic.SemanticName) { @@ -678,16 +678,16 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) fdec = &p.FullToken.FullDeclaration; switch (fdec->Declaration.File) { case TGSI_FILE_TEMPORARY: - if (fdec->u.DeclarationRange.Last > high_temp) { + if (fdec->DeclarationRange.Last > high_temp) { high_temp = - fdec->u.DeclarationRange.Last; + fdec->DeclarationRange.Last; } break; #if 0 /* this would be nice.. except gallium doesn't track it */ case TGSI_FILE_ADDRESS: - if (fdec->u.DeclarationRange.Last > high_addr) { + if (fdec->DeclarationRange.Last > high_addr) { high_addr = - fdec->u.DeclarationRange.Last; + fdec->DeclarationRange.Last; } break; #endif -- cgit v1.2.3 From 8b72737a0ba33343673111261265c59546b408c6 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 23 Jun 2008 20:37:27 +0200 Subject: nv30: add state rasterizer, based on nv40 one --- src/gallium/drivers/nv30/Makefile | 1 + src/gallium/drivers/nv30/nv30_context.h | 7 +++++++ src/gallium/drivers/nv30/nv30_state_rasterizer.c | 17 +++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 src/gallium/drivers/nv30/nv30_state_rasterizer.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile index 04f53ee456..c5208fabf5 100644 --- a/src/gallium/drivers/nv30/Makefile +++ b/src/gallium/drivers/nv30/Makefile @@ -16,6 +16,7 @@ DRIVER_SOURCES = \ nv30_state_blend.c \ nv30_state_emit.c \ nv30_state_fb.c \ + nv30_state_rasterizer.c \ nv30_surface.c \ nv30_vbo.c \ nv30_vertprog.c diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 1695ba5a01..43ee8d13a0 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -76,6 +76,12 @@ enum nv30_state_index { #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; +}; + /* TODO: rename when removing the old state emitter */ struct nv30_blend_state_new { struct pipe_blend_state pipe; @@ -111,6 +117,7 @@ struct nv30_context { struct nv30_blend_state_new *blend; struct pipe_blend_color blend_colour; struct pipe_framebuffer_state framebuffer; + struct nv30_rasterizer_state_new *rasterizer; uint32_t rt_enable; struct pipe_buffer *rt[2]; 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 0000000000..6d1b60e043 --- /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 + } +}; -- cgit v1.2.3 From e5bbb18441f34824dc4f9f857b30c71c4ff6466f Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 23 Jun 2008 20:43:22 +0200 Subject: nv30: add state scissor, based on nv40 one --- src/gallium/drivers/nv30/Makefile | 1 + src/gallium/drivers/nv30/nv30_context.h | 3 +++ src/gallium/drivers/nv30/nv30_state_scissor.c | 35 +++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 src/gallium/drivers/nv30/nv30_state_scissor.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile index c5208fabf5..134130c0e0 100644 --- a/src/gallium/drivers/nv30/Makefile +++ b/src/gallium/drivers/nv30/Makefile @@ -17,6 +17,7 @@ DRIVER_SOURCES = \ nv30_state_emit.c \ nv30_state_fb.c \ nv30_state_rasterizer.c \ + nv30_state_scissor.c \ nv30_surface.c \ nv30_vbo.c \ nv30_vertprog.c diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 43ee8d13a0..428f17ae0d 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -90,6 +90,8 @@ struct nv30_blend_state_new { struct nv30_state { + unsigned scissor_enabled; + struct nouveau_stateobj *hw[NV30_STATE_MAX]; }; @@ -104,6 +106,7 @@ struct nv30_context { /* HW state derived from pipe states */ struct nv30_state state; + struct pipe_scissor_state scissor; uint32_t dirty; 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 0000000000..1db9bc1795 --- /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 + } +}; -- cgit v1.2.3 From d4bc56ca49ef39f9f083a2e5adeb3e89ca3bf538 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 23 Jun 2008 21:13:27 +0200 Subject: nv30: add state stipple, based on nv40 one --- src/gallium/drivers/nv30/Makefile | 1 + src/gallium/drivers/nv30/nv30_context.h | 2 ++ src/gallium/drivers/nv30/nv30_state_stipple.c | 39 +++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/gallium/drivers/nv30/nv30_state_stipple.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile index 134130c0e0..91601087a3 100644 --- a/src/gallium/drivers/nv30/Makefile +++ b/src/gallium/drivers/nv30/Makefile @@ -18,6 +18,7 @@ DRIVER_SOURCES = \ nv30_state_fb.c \ nv30_state_rasterizer.c \ nv30_state_scissor.c \ + nv30_state_stipple.c \ nv30_surface.c \ nv30_vbo.c \ nv30_vertprog.c diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 428f17ae0d..446e43a726 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -91,6 +91,7 @@ struct nv30_blend_state_new { struct nv30_state { unsigned scissor_enabled; + unsigned stipple_enabled; struct nouveau_stateobj *hw[NV30_STATE_MAX]; }; @@ -121,6 +122,7 @@ struct nv30_context { struct pipe_blend_color blend_colour; struct pipe_framebuffer_state framebuffer; struct nv30_rasterizer_state_new *rasterizer; + unsigned stipple[32]; uint32_t rt_enable; struct pipe_buffer *rt[2]; 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 0000000000..41b42813b4 --- /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, + } +}; -- cgit v1.2.3 From 0e1b36b0b257bfba4427a1e6e12c918e744b9977 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 23 Jun 2008 21:37:41 +0200 Subject: nv30: add state viewport, based on nv40 one --- src/gallium/drivers/nv30/Makefile | 1 + src/gallium/drivers/nv30/nv30_context.h | 2 + src/gallium/drivers/nv30/nv30_state_viewport.c | 70 ++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 src/gallium/drivers/nv30/nv30_state_viewport.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile index 91601087a3..a6a8cf1df9 100644 --- a/src/gallium/drivers/nv30/Makefile +++ b/src/gallium/drivers/nv30/Makefile @@ -19,6 +19,7 @@ DRIVER_SOURCES = \ nv30_state_rasterizer.c \ nv30_state_scissor.c \ nv30_state_stipple.c \ + nv30_state_viewport.c \ nv30_surface.c \ nv30_vbo.c \ nv30_vertprog.c diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 446e43a726..eb7e5a8b12 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -92,6 +92,7 @@ struct nv30_blend_state_new { struct nv30_state { unsigned scissor_enabled; unsigned stipple_enabled; + unsigned viewport_bypass; struct nouveau_stateobj *hw[NV30_STATE_MAX]; }; @@ -120,6 +121,7 @@ struct nv30_context { /* 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; unsigned stipple[32]; 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 0000000000..951d40ebfd --- /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 + } +}; -- cgit v1.2.3 From 95fe122f67024f55d555e2816a95409a8b53a49e Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 23 Jun 2008 21:46:51 +0200 Subject: nv30: add state zsa, based on nv40 one --- src/gallium/drivers/nv30/Makefile | 1 + src/gallium/drivers/nv30/nv30_context.h | 6 ++++++ src/gallium/drivers/nv30/nv30_state_zsa.c | 17 +++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 src/gallium/drivers/nv30/nv30_state_zsa.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile index a6a8cf1df9..69f2790dfe 100644 --- a/src/gallium/drivers/nv30/Makefile +++ b/src/gallium/drivers/nv30/Makefile @@ -20,6 +20,7 @@ DRIVER_SOURCES = \ 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 diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index eb7e5a8b12..dce077b2b4 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -82,6 +82,11 @@ struct nv30_rasterizer_state_new { 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; @@ -124,6 +129,7 @@ struct nv30_context { 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; 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 0000000000..0940b7269b --- /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 + } +}; -- cgit v1.2.3 From bb1089192572714a604cbef836c34cb16da933f4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 04:08:17 +1000 Subject: nouveau: major thinko --- src/gallium/auxiliary/draw/draw_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 0e6f55a928..678c70e478 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -63,7 +63,7 @@ struct draw_context *draw_create( void ) if (!draw_pt_init( draw )) goto fail; -#ifndef PIPE_ARCH_X86 +#ifdef PIPE_ARCH_X86 if (!draw_vs_init( draw )) goto fail; #endif -- cgit v1.2.3 From b831aa06dc0d099185bcaa180683ad10942feaa0 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 24 Jun 2008 21:04:37 +0200 Subject: nv30: add context value --- src/gallium/drivers/nv30/nv30_screen.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h index 816ece94c4..b7ddc2a959 100644 --- a/src/gallium/drivers/nv30/nv30_screen.h +++ b/src/gallium/drivers/nv30/nv30_screen.h @@ -8,6 +8,8 @@ struct nv30_screen { struct nouveau_winsys *nvws; + unsigned cur_pctx; + /* HW graphics objects */ struct nouveau_grobj *rankine; struct nouveau_notifier *sync; -- cgit v1.2.3 From b6478021d572d9ec30212d6e6992496ee4cf347d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 29 Jun 2008 13:26:04 +1000 Subject: nouveau: adapt to cpp->pf_block changes --- src/gallium/drivers/nv10/nv10_miptree.c | 12 +++-- src/gallium/drivers/nv10/nv10_state_emit.c | 4 +- src/gallium/drivers/nv30/nv30_miptree.c | 10 ++-- src/gallium/drivers/nv30/nv30_state.c | 10 ++-- src/gallium/drivers/nv30/nv30_state_fb.c | 8 +-- src/gallium/drivers/nv40/nv40_miptree.c | 29 ++++++++--- src/gallium/drivers/nv40/nv40_state_fb.c | 10 ++-- src/gallium/drivers/nv40/nv40_surface.c | 2 +- src/gallium/drivers/nv50/nv50_miptree.c | 6 ++- src/gallium/winsys/dri/nouveau/nouveau_context.c | 9 +++- src/gallium/winsys/dri/nouveau/nouveau_screen.c | 7 ++- src/gallium/winsys/dri/nouveau/nv04_surface.c | 63 +++++++++++++----------- src/gallium/winsys/dri/nouveau/nv50_surface.c | 42 +++++++++------- 13 files changed, 129 insertions(+), 83 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c index 1b9947354d..f1486a35df 100644 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -25,11 +25,13 @@ nv10_miptree_layout(struct nv10_miptree *nv10mt) pt->width[l] = width; pt->height[l] = height; pt->depth[l] = depth; + pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); if (swizzled) - nv10mt->level[l].pitch = pt->width[l] * pt->cpp; + nv10mt->level[l].pitch = pt->nblocksx[l] * pt->block.size; else - nv10mt->level[l].pitch = pt->width[0] * pt->cpp; + nv10mt->level[l].pitch = pt->nblocksx[0] * pt->block.size; nv10mt->level[l].pitch = (nv10mt->level[l].pitch + 63) & ~63; nv10mt->level[l].image_offset = @@ -117,10 +119,12 @@ nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, 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; + ps->block = pt->block; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = nv10mt->level[level].pitch; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = nv10mt->level[level].image_offset[face]; diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c index 41422c8882..d21368d33f 100644 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -143,10 +143,10 @@ static void nv10_state_emit_framebuffer(struct nv10_context* nv10) if (zeta) { BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); - OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->cpp) << 16) ); + OUT_RING (rt->stride | (zeta->stride << 16)); } else { BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); - OUT_RING ( (rt->pitch * rt->cpp) | ( (rt->pitch * rt->cpp) << 16) ); + OUT_RING (rt->stride | (rt->stride << 16)); } nv10->rt[0] = rt->buffer; diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index 6078b1865e..ad0b257fe2 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -28,12 +28,14 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) pt->width[l] = width; pt->height[l] = height; pt->depth[l] = depth; + pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); if (swizzled) pitch = pt->width[l]; pitch = (pitch + 63) & ~63; - nv30mt->level[l].pitch = pitch * pt->cpp; + nv30mt->level[l].pitch = pitch * pt->block.size; nv30mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); @@ -114,10 +116,12 @@ nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, 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; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->block = pt->block; + ps->stride = nv30mt->level[level].pitch; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = nv30mt->level[level].image_offset[face]; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 84f016eead..c1618041bb 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -631,21 +631,21 @@ nv30_set_framebuffer_state(struct pipe_context *pipe, } if (rt_enable & NV34TCL_RT_ENABLE_COLOR0) { - uint32_t pitch = rt[0]->pitch * rt[0]->cpp; + uint32_t pitch = rt[0]->stride; if (zeta) { - pitch |= (zeta->pitch * zeta->cpp)<<16; + pitch |= (zeta->stride << 16); } else { - pitch |= pitch<<16; + pitch |= (pitch << 16); } BEGIN_RING(rankine, NV34TCL_COLOR0_PITCH, 1); - OUT_RING ( pitch ); + 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); + OUT_RING (rt[1]->stride); nv30->rt[1] = rt[1]->buffer; } diff --git a/src/gallium/drivers/nv30/nv30_state_fb.c b/src/gallium/drivers/nv30/nv30_state_fb.c index 73c97e298a..a20df9f75d 100644 --- a/src/gallium/drivers/nv30/nv30_state_fb.c +++ b/src/gallium/drivers/nv30/nv30_state_fb.c @@ -59,11 +59,11 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30) } if (rt_enable & NV34TCL_RT_ENABLE_COLOR0) { - uint32_t pitch = rt[0]->pitch * rt[0]->cpp; + uint32_t pitch = rt[0]->stride; if (zeta) { - pitch |= (zeta->pitch * zeta->cpp)<<16; + pitch |= (zeta->stride << 16); } else { - pitch |= pitch<<16; + pitch |= (pitch << 16); } so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR0, 1); @@ -84,7 +84,7 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30) 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); + so_data (so, rt[1]->stride); } /* if (rt_enable & NV34TCL_RT_ENABLE_COLOR2) { diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 23da6e36a3..38e1a5f04c 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -28,19 +28,20 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) pt->width[l] = width; pt->height[l] = height; pt->depth[l] = depth; + pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); if (swizzled) - pitch = pt->width[l]; - pitch = (pitch + 63) & ~63; + pitch = pt->nblocksx[l]; + pitch = align_int(pitch, 64); - nv40mt->level[l].pitch = pitch * pt->cpp; + nv40mt->level[l].pitch = pitch * pt->block.size; 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++) { @@ -109,15 +110,20 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; struct pipe_surface *ps; - ps = ws->surface_alloc(ws); + ps = CALLOC_STRUCT(pipe_surface); if (!ps) return NULL; + pipe_texture_reference(&ps->texture, pt); 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; + ps->block = pt->block; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = nv40mt->level[level].pitch; + ps->usage = flags; + ps->status = PIPE_SURFACE_STATUS_DEFINED; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = nv40mt->level[level].image_offset[face]; @@ -135,6 +141,15 @@ static void nv40_miptree_surface_del(struct pipe_screen *pscreen, struct pipe_surface **psurface) { + struct pipe_surface *ps = *psurface; + + *psurface = NULL; + if (--ps->refcount > 0) + return; + + pipe_texture_reference(&ps->texture, NULL); + pipe_buffer_reference(pscreen->winsys, &ps->buffer, NULL); + FREE(ps); } void diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 88baf61ffb..0e4e60eaa7 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -64,7 +64,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) 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_data (so, rt[0]->stride); so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); } @@ -77,7 +77,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) 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); + so_data (so, rt[1]->stride); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) { @@ -89,7 +89,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) 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); + so_data (so, rt[2]->stride); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) { @@ -101,7 +101,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) 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); + so_data (so, rt[3]->stride); } if (zeta_format) { @@ -113,7 +113,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) 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_data (so, zeta->stride); } so_method(so, nv40->screen->curie, NV40TCL_RT_ENABLE, 1); diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index c0d135eb36..0916555d56 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -34,7 +34,7 @@ #include "util/p_tile.h" static void -nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip, +nv40_surface_copy(struct pipe_context *pipe, boolean do_flip, struct pipe_surface *dest, unsigned destx, unsigned desty, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index ccb916d6ac..6c838998fd 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -72,10 +72,12 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, 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->block = pt->block; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = ps->width * ps->block.size; ps->offset = 0; return ps; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index ef5fb7ec0d..74413c408f 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -167,9 +167,14 @@ nouveau_context_create(const __GLcontextModes *glVis, 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; + if (nv_screen->front_cpp == 2) + fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; + else + fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; + pf_get_block(fb_surf->format, &fb_surf->block); + fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; fb_surf->height = nv_screen->front_height; + fb_surf->stride = fb_surf->width * fb_surf->block.size; fb_surf->refcount = 1; fb_surf->buffer = &fb_buf->base; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index 9041275a88..b15ee7509c 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -209,8 +209,9 @@ nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, 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 }; + uint8_t depth_bits_array[4] = { 0, 16, 24, 24 }; + uint8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; + uint8_t msaa_samples_array[1] = { 0 }; depth_buffer_factor = 4; back_buffer_factor = (have_back_buffer) ? 3 : 1; @@ -229,6 +230,7 @@ nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, depth_buffer_factor, back_buffer_modes, back_buffer_factor, + msaa_samples_array, 1, GLX_TRUE_COLOR)) { fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__ ); @@ -242,6 +244,7 @@ nouveau_fill_in_modes(unsigned pixel_bits, unsigned depth_bits, depth_buffer_factor, back_buffer_modes, back_buffer_factor, + msaa_samples_array, 1, GLX_DIRECT_COLOR)) { fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__ ); diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index 83c790db17..0085b1c345 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -1,26 +1,35 @@ #include "pipe/p_context.h" +#include "pipe/p_format.h" #include "nouveau_context.h" static INLINE int -nv04_surface_format(int cpp) +nv04_surface_format(enum pipe_format format) { - 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; + switch (format) { + case PIPE_FORMAT_A8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; default: return -1; } } static INLINE int -nv04_rect_format(int cpp) +nv04_rect_format(enum pipe_format format) { - 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; + switch (format) { + case PIPE_FORMAT_A8_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; default: return -1; } @@ -35,8 +44,8 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, 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; + dst_offset = dst->offset + (dy * dst->stride) + (dx * dst->block.size); + src_offset = src->offset + (sy * src->stride) + (sx * src->block.size); while (h) { int count = (h > 2047) ? 2047 : h; @@ -47,16 +56,16 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, 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, src->stride); + OUT_RING (chan, dst->stride); + OUT_RING (chan, w * src->block.size); 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; + src_offset += src->stride * count; + dst_offset += dst->stride * count; } } @@ -79,7 +88,7 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, struct nouveau_channel *chan = nv->nvc->channel; int format; - if (src->cpp != dst->cpp) + if (src->format != dst->format) return 1; /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback @@ -100,8 +109,8 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, } - if ((format = nv04_surface_format(dst->cpp)) < 0) { - NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + if ((format = nv04_surface_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad surface format 0x%x\n", dst->format); return 1; } nv->surface_copy = nv04_surface_copy_blit; @@ -116,8 +125,7 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, 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_RING (chan, (dst->stride << 16) | src->stride); 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, @@ -142,13 +150,13 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, 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); + if ((cs2d_format = nv04_surface_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad format = %d\n", dst->format); return 1; } - if ((gdirect_format = nv04_rect_format(dst->cpp)) < 0) { - NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp); + if ((gdirect_format = nv04_rect_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad format = %d\n", dst->format); return 1; } @@ -159,8 +167,7 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, 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_RING (chan, (dst->stride << 16) | dst->stride); 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, diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index d6da116b77..cf76d76cf5 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -1,15 +1,21 @@ #include "pipe/p_context.h" +#include "pipe/p_format.h" #include "nouveau_context.h" static INLINE int -nv50_format(int cpp) +nv50_format(enum pipe_format format) { - 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; + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV50_2D_DST_FORMAT_32BPP; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return NV50_2D_DST_FORMAT_24BPP; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV50_2D_DST_FORMAT_16BPP; + case PIPE_FORMAT_A8_UNORM: + return NV50_2D_DST_FORMAT_8BPP; default: return -1; } @@ -23,9 +29,9 @@ nv50_surface_copy_prep(struct nouveau_context *nv, struct nouveau_grobj *eng2d = nv->nvc->Nv2D; int surf_format; - assert(src->cpp == dst->cpp); + assert(src->format == dst->format); - surf_format = nv50_format(dst->cpp); + surf_format = nv50_format(dst->format); assert(surf_format >= 0); BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2); @@ -38,8 +44,8 @@ nv50_surface_copy_prep(struct nouveau_context *nv, 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->stride); + OUT_RING (chan, dst->width); OUT_RING (chan, dst->height); OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); @@ -48,15 +54,15 @@ nv50_surface_copy_prep(struct nouveau_context *nv, 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->width); 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->stride); + OUT_RING (chan, src->width); OUT_RING (chan, src->height); OUT_RELOCh(chan, nouveau_buffer(src->buffer)->bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); @@ -105,11 +111,11 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, struct nouveau_grobj *eng2d = nv->nvc->Nv2D; int surf_format, rect_format; - surf_format = nv50_format(dst->cpp); + surf_format = nv50_format(dst->format); if (surf_format < 0) return 1; - rect_format = nv50_format(dst->cpp); + rect_format = nv50_format(dst->format); if (rect_format < 0) return 1; @@ -120,8 +126,8 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, 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->stride); + OUT_RING (chan, dst->width); OUT_RING (chan, dst->height); OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); @@ -130,7 +136,7 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, 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->width); OUT_RING (chan, dst->height); BEGIN_RING(chan, eng2d, 0x0580, 3); -- cgit v1.2.3 From f722fd937db2f3cacf1947d538c66528fd16eb89 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 1 Jun 2008 22:41:40 +1000 Subject: nv50: import current "state of the art" nv50 code --- src/gallium/drivers/nv50/Makefile | 1 + src/gallium/drivers/nv50/nv50_context.h | 18 + src/gallium/drivers/nv50/nv50_program.c | 742 +++++++++++++++++++++++++ src/gallium/drivers/nv50/nv50_screen.c | 68 ++- src/gallium/drivers/nv50/nv50_screen.h | 3 + src/gallium/drivers/nv50/nv50_state.c | 54 +- src/gallium/drivers/nv50/nv50_state.h | 30 + src/gallium/drivers/nv50/nv50_state_validate.c | 29 +- src/gallium/drivers/nv50/nv50_vbo.c | 85 ++- 9 files changed, 1017 insertions(+), 13 deletions(-) create mode 100644 src/gallium/drivers/nv50/nv50_program.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index a62a4d961b..2cc6e9de28 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -9,6 +9,7 @@ DRIVER_SOURCES = \ nv50_draw.c \ nv50_miptree.c \ nv50_query.c \ + nv50_program.c \ nv50_screen.c \ nv50_state.c \ nv50_state_validate.c \ diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index e68c702dea..d4d716b94b 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -9,6 +9,7 @@ #include "nouveau/nouveau_winsys.h" #include "nouveau/nouveau_gldefs.h" +#include "nouveau/nouveau_stateobj.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ struct nv50_screen *ctx = nv50->screen @@ -30,6 +31,9 @@ #define NV50_NEW_VIEWPORT (1 << 5) #define NV50_NEW_RASTERIZER (1 << 6) #define NV50_NEW_FRAMEBUFFER (1 << 7) +#define NV50_NEW_VERTPROG (1 << 8) +#define NV50_NEW_FRAGPROG (1 << 9) +#define NV50_NEW_ARRAYS (1 << 10) struct nv50_blend_stateobj { struct pipe_blend_state pipe; @@ -63,6 +67,13 @@ struct nv50_context { struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; + struct nv50_program *vertprog; + struct nv50_program *fragprog; + struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; + unsigned vtxbuf_nr; + struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; + unsigned vtxelt_nr; }; static INLINE struct nv50_context * @@ -88,11 +99,18 @@ extern boolean nv50_draw_elements(struct pipe_context *pipe, unsigned indexSize, unsigned mode, unsigned start, unsigned count); +extern void nv50_vbo_validate(struct nv50_context *nv50); /* nv50_clear.c */ extern void nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue); +/* nv50_program.c */ +extern void nv50_vertprog_validate(struct nv50_context *nv50); +extern void nv50_fragprog_validate(struct nv50_context *nv50); +extern void nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p); + +/* nv50_state_validate.c */ extern boolean nv50_state_validate(struct nv50_context *nv50); #endif diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c new file mode 100644 index 0000000000..30953b7d8a --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -0,0 +1,742 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.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_util.h" + +#include "nv50_context.h" +#include "nv50_state.h" + +#define OP_MOV 0x001 +#define OP_RCP 0x009 +#define OP_ADD 0x00b +#define OP_MUL 0x00c +#define NV50_SU_MAX_TEMP 64 + +struct nv50_reg { + enum { + P_TEMP, + P_ATTR, + P_RESULT, + P_CONST, + P_IMMD + } type; + int index; + + int hw; +}; + +struct nv50_pc { + struct nv50_program *p; + + /* hw resources */ + struct nv50_reg *r_temp[NV50_SU_MAX_TEMP]; + + /* tgsi resources */ + struct nv50_reg *temp; + int temp_nr; + struct nv50_reg *attr; + int attr_nr; + struct nv50_reg *result; + int result_nr; + struct nv50_reg *param; + int param_nr; + struct nv50_reg *immd; + float *immd_buf; + int immd_nr; +}; + +static void +alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg) +{ + int i; + + if (reg->type != P_TEMP || reg->hw >= 0) + return; + + for (i = 0; i < NV50_SU_MAX_TEMP; i++) { + if (!(pc->r_temp[i])) { + pc->r_temp[i] = reg; + reg->hw = i; + if (pc->p->cfg.vp.high_temp < (i + 1)) + pc->p->cfg.vp.high_temp = i + 1; + return; + } + } + + assert(0); +} + +static struct nv50_reg * +alloc_temp(struct nv50_pc *pc, struct nv50_reg *dst) +{ + struct nv50_reg *r; + int i; + + if (dst && dst->type == P_TEMP && dst->hw == -1) + return dst; + + for (i = 0; i < NV50_SU_MAX_TEMP; i++) { + if (!pc->r_temp[i]) { + r = CALLOC_STRUCT(nv50_reg); + r->type = P_TEMP; + r->index = -1; + r->hw = i; + pc->r_temp[i] = r; + return r; + } + } + + assert(0); + return NULL; +} + +static void +free_temp(struct nv50_pc *pc, struct nv50_reg *r) +{ + if (r->index == -1) { + FREE(pc->r_temp[r->hw]); + pc->r_temp[r->hw] = NULL; + } +} + +#if 0 +static struct nv50_reg * +constant(struct nv50_pc *pc, int pipe, int c, float v) +{ + struct nv50_reg *r = CALLOC_STRUCT(nv50_reg); + struct nv50_program *p = pc->p; + struct nv50_program_data *pd; + int idx; + + if (pipe >= 0) { + for (idx = 0; idx < p->nr_consts; idx++) { + if (p->consts[idx].index == pipe) + return nv40_sr(NV40SR_CONST, idx); + } + } + + idx = p->nr_consts++; + p->consts = realloc(p->consts, sizeof(*pd) * p->nr_consts); + pd = &p->consts[idx]; + + pd->index = pipe; + pd->component = c; + pd->value = v; + return nv40_sr(NV40SR_CONST, idx); +} +#endif + +static void +emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, + struct nv50_reg *src0, struct nv50_reg *src1, struct nv50_reg *src2) +{ + struct nv50_program *p = pc->p; + struct nv50_reg *tmp = NULL, *tmp2 = NULL; + unsigned inst[2] = { 0, 0 }; + + /* Grr.. Fun restrictions on where attribs can be sourced from.. */ + if (src1 && src1->type == P_ATTR) { + tmp = alloc_temp(pc, dst); + emit(pc, 1, tmp, src1, NULL, NULL); + src1 = tmp; + } + + if (src2 && src2->type == P_ATTR) { + tmp2 = alloc_temp(pc, dst); + emit(pc, 1, tmp2, src2, NULL, NULL); + src2 = tmp2; + } + + /* Get this out of the way first. What type of opcode do we + * want/need to build? + */ + if ((op & 0x3f0) || dst->type == P_RESULT || + (src0 && src0->type == P_ATTR) || src1 || src2) + inst[0] |= 0x00000001; + + if (inst[0] & 0x00000001) { + inst[0] |= ((op & 0xf) << 28); + inst[1] |= ((op >> 4) << 26); + + alloc_reg(pc, dst); + if (dst->type == P_RESULT) + inst[1] |= 0x00000008; + inst[0] |= (dst->hw << 2); + + if (src0) { + if (src0->type == P_ATTR) + inst[1] |= 0x00200000; + else + if (src0->type == P_CONST || src0->type == P_IMMD) + assert(0); + alloc_reg(pc, src0); + inst[0] |= (src0->hw << 9); + } + + if (src1) { + if (src1->type == P_CONST || src1->type == P_IMMD) { + inst[0] |= 0x00800000; /* src1 is const */ + /*XXX: does src1 come from "src2" now? */ + alloc_reg(pc, src1); + inst[0] |= (src1->hw << 16); + } else { + alloc_reg(pc, src1); + if (op == 0xc || op == 0xe) + inst[0] |= (src1->hw << 16); + else + inst[1] |= (src1->hw << 14); + } + } else { + inst[1] |= 0x0003c000; /*XXX FIXME */ + } + + if (src2) { + if (src2->type == P_CONST || src2->type == P_IMMD) { + inst[0] |= 0x01000000; /* src2 is const */ + inst[1] |= (src2->hw << 14); + } else { + alloc_reg(pc, src2); + if (inst[0] & 0x00800000 || op ==0xe) + inst[1] |= (src2->hw << 14); + else + inst[0] |= (src2->hw << 16); + } + } + + /*XXX: FIXME */ + if (op == 0xb || op == 0xc || op == 0x9 || op == 0xe) { + /* 0x04000000 negates arg0 */ + /* 0x08000000 negates arg1 */ + /*XXX: true for !0xb also ? */ + inst[1] |= 0x00000780; + } else { + /* 0x04000000 == arg0 32 bit, otherwise 16 bit */ + inst[1] |= 0x04000780; + } + } else { + inst[0] |= ((op & 0xf) << 28); + + alloc_reg(pc, dst); + inst[0] |= (dst->hw << 2); + + if (src0) { + alloc_reg(pc, src0); + inst[0] |= (src0->hw << 9); + } + + /*XXX: NFI if this even works - probably not.. */ + if (src1) { + alloc_reg(pc, src1); + inst[0] |= (src1->hw << 16); + } + } + + if (tmp) free_temp(pc, tmp); + if (tmp2) free_temp(pc, tmp2); + + if (inst[0] & 1) { + p->insns_nr += 2; + p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); + memcpy(p->insns + (p->insns_nr - 2), inst, sizeof(unsigned)*2); + } else { + p->insns_nr += 1; + p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); + memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned)); + } +} + +static struct nv50_reg * +tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) +{ + switch (dst->DstRegister.File) { + case TGSI_FILE_TEMPORARY: + return &pc->temp[dst->DstRegister.Index * 4 + c]; + case TGSI_FILE_OUTPUT: + return &pc->result[dst->DstRegister.Index * 4 + c]; + case TGSI_FILE_NULL: + return NULL; + default: + break; + } + + return NULL; +} + +static struct nv50_reg * +tgsi_src(struct nv50_pc *pc, int c, const struct tgsi_full_src_register *src) +{ + /* Handle swizzling */ + switch (c) { + case 0: c = src->SrcRegister.SwizzleX; break; + case 1: c = src->SrcRegister.SwizzleY; break; + case 2: c = src->SrcRegister.SwizzleZ; break; + case 3: c = src->SrcRegister.SwizzleW; break; + default: + assert(0); + } + + switch (src->SrcRegister.File) { + case TGSI_FILE_INPUT: + return &pc->attr[src->SrcRegister.Index * 4 + c]; + case TGSI_FILE_TEMPORARY: + return &pc->temp[src->SrcRegister.Index * 4 + c]; + case TGSI_FILE_CONSTANT: + return &pc->param[src->SrcRegister.Index * 4 + c]; + case TGSI_FILE_IMMEDIATE: + return &pc->immd[src->SrcRegister.Index * 4 + c]; + default: + break; + } + + return NULL; +} + +static boolean +nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) +{ + const struct tgsi_full_instruction *inst = &tok->FullInstruction; + struct nv50_reg *dst[4], *src[3][4], *none = NULL, *tmp; + unsigned mask; + int i, c; + + NOUVEAU_ERR("insn %p\n", tok); + + mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + dst[c] = tgsi_dst(pc, c, &inst->FullDstRegisters[0]); + else + dst[c] = NULL; + } + + for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { + for (c = 0; c < 4; c++) + src[i][c] = tgsi_src(pc, c, &inst->FullSrcRegisters[i]); + } + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ADD: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) { + emit(pc, 0x0b, dst[c], + src[0][c], src[1][c], none); + } + } + break; + case TGSI_OPCODE_DP3: + tmp = alloc_temp(pc, NULL); + emit(pc, 0x0c, tmp, src[0][0], src[1][0], NULL); + emit(pc, 0x0e, tmp, src[0][1], src[1][1], tmp); + emit(pc, 0x0e, tmp, src[0][2], src[1][2], tmp); + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x01, dst[c], tmp, none, none); + } + free_temp(pc, tmp); + break; + case TGSI_OPCODE_DP4: + tmp = alloc_temp(pc, NULL); + emit(pc, 0x0c, tmp, src[0][0], src[1][0], NULL); + emit(pc, 0x0e, tmp, src[0][1], src[1][1], tmp); + emit(pc, 0x0e, tmp, src[0][2], src[1][2], tmp); + emit(pc, 0x0e, tmp, src[0][3], src[1][3], tmp); + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x01, dst[c], tmp, none, none); + } + free_temp(pc, tmp); + break; + case TGSI_OPCODE_MAD: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x0e, dst[c], + src[0][c], src[1][c], src[2][c]); + } + break; + case TGSI_OPCODE_MOV: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x01, dst[c], src[0][c], none, none); + } + break; + case TGSI_OPCODE_MUL: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x0c, dst[c], + src[0][c], src[1][c], none); + } + break; + case TGSI_OPCODE_RCP: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, 0x09, dst[c], + src[0][c], none, none); + } + break; + case TGSI_OPCODE_END: + break; + default: + NOUVEAU_ERR("invalid opcode %d\n", inst->Instruction.Opcode); + return FALSE; + } + + return TRUE; +} + +static boolean +nv50_program_tx_prep(struct nv50_pc *pc) +{ + struct tgsi_parse_context p; + boolean ret = FALSE; + unsigned i, c; + + tgsi_parse_init(&p, pc->p->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: + { + const struct tgsi_full_immediate *imm = + &p.FullToken.FullImmediate; + + pc->immd_nr++; + pc->immd_buf = realloc(pc->immd_buf, 4 * pc->immd_nr * + sizeof(float)); + pc->immd_buf[4 * (pc->immd_nr - 1) + 0] = + imm->u.ImmediateFloat32[0].Float; + pc->immd_buf[4 * (pc->immd_nr - 1) + 1] = + imm->u.ImmediateFloat32[1].Float; + pc->immd_buf[4 * (pc->immd_nr - 1) + 2] = + imm->u.ImmediateFloat32[2].Float; + pc->immd_buf[4 * (pc->immd_nr - 1) + 3] = + imm->u.ImmediateFloat32[3].Float; + } + break; + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *d; + unsigned last; + + d = &p.FullToken.FullDeclaration; + last = d->u.DeclarationRange.Last; + + switch (d->Declaration.File) { + case TGSI_FILE_TEMPORARY: + if (pc->temp_nr < (last + 1)) + pc->temp_nr = last + 1; + break; + case TGSI_FILE_OUTPUT: + if (pc->result_nr < (last + 1)) + pc->result_nr = last + 1; + break; + case TGSI_FILE_INPUT: + if (pc->attr_nr < (last + 1)) + pc->attr_nr = last + 1; + break; + case TGSI_FILE_CONSTANT: + if (pc->param_nr < (last + 1)) + pc->param_nr = last + 1; + break; + default: + NOUVEAU_ERR("bad decl file %d\n", + d->Declaration.File); + goto out_err; + } + } + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + break; + default: + break; + } + } + + NOUVEAU_ERR("%d temps\n", pc->temp_nr); + if (pc->temp_nr) { + pc->temp = calloc(pc->temp_nr * 4, sizeof(struct nv50_reg)); + if (!pc->temp) + goto out_err; + + for (i = 0; i < pc->temp_nr; i++) { + for (c = 0; c < 4; c++) { + pc->temp[i*4+c].type = P_TEMP; + pc->temp[i*4+c].hw = -1; + pc->temp[i*4+c].index = i; + } + } + } + + NOUVEAU_ERR("%d attrib regs\n", pc->attr_nr); + if (pc->attr_nr) { + int aid = 0; + + pc->attr = calloc(pc->attr_nr * 4, sizeof(struct nv50_reg)); + if (!pc->attr) + goto out_err; + + for (i = 0; i < pc->attr_nr; i++) { + for (c = 0; c < 4; c++) { + pc->p->cfg.vp.attr[aid/32] |= (1 << (aid % 32)); + pc->attr[i*4+c].type = P_ATTR; + pc->attr[i*4+c].hw = aid++; + pc->attr[i*4+c].index = i; + } + } + } + + NOUVEAU_ERR("%d result regs\n", pc->result_nr); + if (pc->result_nr) { + int rid = 0; + + pc->result = calloc(pc->result_nr * 4, sizeof(struct nv50_reg)); + if (!pc->result) + goto out_err; + + for (i = 0; i < pc->result_nr; i++) { + for (c = 0; c < 4; c++) { + pc->result[i*4+c].type = P_RESULT; + pc->result[i*4+c].hw = rid++; + pc->result[i*4+c].index = i; + } + } + } + + NOUVEAU_ERR("%d param regs\n", pc->param_nr); + if (pc->param_nr) { + int rid = 0; + + pc->param = calloc(pc->param_nr * 4, sizeof(struct nv50_reg)); + if (!pc->param) + goto out_err; + + for (i = 0; i < pc->param_nr; i++) { + for (c = 0; c < 4; c++) { + pc->param[i*4+c].type = P_CONST; + pc->param[i*4+c].hw = rid++; + pc->param[i*4+c].index = i; + } + } + } + + if (pc->immd_nr) { + int rid = pc->param_nr * 4; + + pc->immd = calloc(pc->immd_nr * 4, sizeof(struct nv50_reg)); + if (!pc->immd) + goto out_err; + + for (i = 0; i < pc->immd_nr; i++) { + for (c = 0; c < 4; c++) { + pc->immd[i*4+c].type = P_IMMD; + pc->immd[i*4+c].hw = rid++; + pc->immd[i*4+c].index = i; + } + } + } + + ret = TRUE; +out_err: + tgsi_parse_free(&p); + return ret; +} + +static boolean +nv50_program_tx(struct nv50_program *p) +{ + struct tgsi_parse_context parse; + struct nv50_pc *pc; + boolean ret; + + pc = CALLOC_STRUCT(nv50_pc); + if (!pc) + return FALSE; + pc->p = p; + pc->p->cfg.vp.high_temp = 4; + + ret = nv50_program_tx_prep(pc); + if (ret == FALSE) + goto out_cleanup; + + tgsi_parse_init(&parse, pc->p->pipe.tokens); + while (!tgsi_parse_end_of_tokens(&parse)) { + const union tgsi_full_token *tok = &parse.FullToken; + + tgsi_parse_token(&parse); + + switch (tok->Token.Type) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + ret = nv50_program_tx_insn(pc, tok); + if (ret == FALSE) + goto out_err; + break; + default: + break; + } + } + + p->param_nr = pc->param_nr * 4; + p->immd_nr = pc->immd_nr * 4; + p->immd = pc->immd_buf; + +out_err: + tgsi_parse_free(&parse); + +out_cleanup: + return ret; +} + +static void +nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) +{ + struct tgsi_parse_context pc; + + tgsi_parse_init(&pc, p->pipe.tokens); + + if (pc.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { + p->insns_nr = 8; + p->insns = malloc(p->insns_nr * sizeof(unsigned)); + p->insns[0] = 0x80000000; + p->insns[1] = 0x9000000c; + p->insns[2] = 0x82010600; + p->insns[3] = 0x82020604; + p->insns[4] = 0x80030609; + p->insns[5] = 0x00020780; + p->insns[6] = 0x8004060d; + p->insns[7] = 0x00020781; + } else + if (pc.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) { + int i; + + if (nv50_program_tx(p) == FALSE) + assert(0); + p->insns[p->insns_nr - 1] |= 0x00000001; + + for (i = 0; i < p->insns_nr; i++) + NOUVEAU_ERR("%d 0x%08x\n", i, p->insns[i]); + } else { + NOUVEAU_ERR("invalid TGSI processor\n"); + tgsi_parse_free(&pc); + return; + } + + tgsi_parse_free(&pc); + + p->translated = TRUE; +} + +void +nv50_vertprog_validate(struct nv50_context *nv50) +{ + struct pipe_winsys *ws = nv50->pipe.winsys; + struct nouveau_winsys *nvws = nv50->screen->nvws; + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nv50_program *p = nv50->vertprog; + struct nouveau_stateobj *so; + void *map; + int i; + + if (!p->translated) { + nv50_program_validate(nv50, p); + if (!p->translated) + assert(0); + } + + if (!p->buffer) + p->buffer = ws->buffer_create(ws, 0x100, 0, p->insns_nr * 4); + map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + memcpy(map, p->insns, p->insns_nr * 4); + ws->buffer_unmap(ws, p->buffer); + + if (p->param_nr) { + float *cb; + + cb = ws->buffer_map(ws, nv50->constbuf[PIPE_SHADER_VERTEX], + PIPE_BUFFER_USAGE_CPU_READ); + for (i = 0; i < p->param_nr; i++) { + BEGIN_RING(tesla, 0x0f00, 2); + OUT_RING (i << 8); + OUT_RING (fui(cb[i])); + } + ws->buffer_unmap(ws, nv50->constbuf[PIPE_SHADER_VERTEX]); + } + + + for (i = 0; i < p->immd_nr; i++) { + BEGIN_RING(tesla, 0x0f00, 2); + OUT_RING ((p->param_nr + i) << 8); + OUT_RING (fui(p->immd[i])); + } + + so = so_new(11, 2); + so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2); + so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, tesla, 0x1650, 2); + so_data (so, p->cfg.vp.attr[0]); + so_data (so, p->cfg.vp.attr[1]); + so_method(so, tesla, 0x16ac, 2); + so_data (so, 8); + so_data (so, p->cfg.vp.high_temp); + so_method(so, tesla, 0x140c, 1); + so_data (so, 0); /* program start offset */ + so_emit(nv50->screen->nvws, so); + so_ref(NULL, &so); +} + +void +nv50_fragprog_validate(struct nv50_context *nv50) +{ + struct pipe_winsys *ws = nv50->pipe.winsys; + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nv50_program *p = nv50->fragprog; + struct nouveau_stateobj *so; + void *map; + + if (!p->translated) { + nv50_program_validate(nv50, p); + if (!p->translated) + assert(0); + } + + if (!p->buffer) + p->buffer = ws->buffer_create(ws, 0x100, 0, p->insns_nr * 4); + map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + memcpy(map, p->insns, p->insns_nr * 4); + ws->buffer_unmap(ws, p->buffer); + + so = so_new(3, 2); + so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2); + so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_LOW, 0, 0); + so_emit(nv50->screen->nvws, so); + so_ref(NULL, &so); +} + +void +nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) +{ + struct pipe_winsys *ws = nv50->pipe.winsys; + + if (p->insns_nr) { + if (p->insns) + FREE(p->insns); + p->insns_nr = 0; + } + + if (p->buffer) + pipe_buffer_reference(ws, &p->buffer, NULL); + + p->translated = 0; +} + diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 29c057a145..fc3eeed913 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -203,8 +203,19 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) return NULL; } + /* Static constant buffer */ + screen->constbuf = ws->buffer_create(ws, 0, 0, 256 * 4 * 4); + if (nvws->res_init(&screen->vp_data_heap, 0, 256)) { + NOUVEAU_ERR("Error initialising constant buffer\n"); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + /* Static tesla init */ - so = so_new(128, 0); + so = so_new(256, 20); + + so_method(so, screen->tesla, 0x1558, 1); + so_data (so, 1); 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), @@ -215,6 +226,61 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) NV50TCL_DMA_IN_MEMORY1__SIZE); for (i = 0; i < NV50TCL_DMA_IN_MEMORY1__SIZE; i++) so_data(so, nvws->channel->vram->handle); + so_method(so, screen->tesla, 0x121c, 1); + so_data (so, 1); + + so_method(so, screen->tesla, 0x13bc, 1); + so_data (so, 0x54); + so_method(so, screen->tesla, 0x13ac, 1); + so_data (so, 1); + so_method(so, screen->tesla, 0x16bc, 2); + so_data (so, 0x03020100); + so_data (so, 0x07060504); + so_method(so, screen->tesla, 0x1988, 2); + so_data (so, 0x08040404); + so_data (so, 0x00000004); + so_method(so, screen->tesla, 0x16ac, 2); + so_data (so, 8); + so_data (so, 4); + so_method(so, screen->tesla, 0x16b8, 1); + so_data (so, 8); + + so_method(so, screen->tesla, 0x1280, 3); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0x00001000); + so_method(so, screen->tesla, 0x1280, 3); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0x00014000); + so_method(so, screen->tesla, 0x1280, 3); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0x00024000); + so_method(so, screen->tesla, 0x1280, 3); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0x00034000); + so_method(so, screen->tesla, 0x1280, 3); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0x00040100); + + for (i = 0; i < 16; i++) { + so_method(so, screen->tesla, 0x1080 + (i * 8), 2); + so_data (so, 0x000000ff); + so_data (so, 0xffffffff); + } so_emit(nvws, so); so_ref(NULL, &so); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 5a2732e37f..d63dd48508 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -12,6 +12,9 @@ struct nv50_screen { struct nouveau_grobj *tesla; struct nouveau_notifier *sync; + + struct pipe_buffer *constbuf; + struct nouveau_resource *vp_data_heap; }; static INLINE struct nv50_screen * diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index f42bae0c28..fd10a38378 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -248,8 +248,8 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, 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_data (so, 0); //cso->depth.writemask ? 1 : 0); + if (0 && 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); @@ -328,34 +328,58 @@ static void * nv50_vp_state_create(struct pipe_context *pipe, const struct pipe_shader_state *cso) { - return NULL; + struct nv50_program *p = CALLOC_STRUCT(nv50_program); + + p->pipe = *cso; + tgsi_scan_shader(p->pipe.tokens, &p->info); + return (void *)p; } static void nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso) { + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->vertprog = hwcso; + nv50->dirty |= NV50_NEW_VERTPROG; } static void nv50_vp_state_delete(struct pipe_context *pipe, void *hwcso) { + struct nv50_context *nv50 = nv50_context(pipe); + + nv50_program_destroy(nv50, hwcso); + FREE(hwcso); } static void * nv50_fp_state_create(struct pipe_context *pipe, const struct pipe_shader_state *cso) { - return NULL; + struct nv50_program *p = CALLOC_STRUCT(nv50_program); + + p->pipe = *cso; + tgsi_scan_shader(p->pipe.tokens, &p->info); + return (void *)p; } static void nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso) { + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->fragprog = hwcso; + nv50->dirty |= NV50_NEW_FRAGPROG; } static void nv50_fp_state_delete(struct pipe_context *pipe, void *hwcso) { + struct nv50_context *nv50 = nv50_context(pipe); + + nv50_program_destroy(nv50, hwcso); + FREE(hwcso); } static void @@ -378,6 +402,16 @@ static void nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, const struct pipe_constant_buffer *buf ) { + struct nv50_context *nv50 = nv50_context(pipe); + + if (shader == PIPE_SHADER_VERTEX) { + nv50->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; + nv50->dirty |= NV50_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nv50->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; + nv50->dirty |= NV50_NEW_FRAGPROG; + } } static void @@ -424,12 +458,24 @@ static void nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count, const struct pipe_vertex_buffer *vb) { + struct nv50_context *nv50 = nv50_context(pipe); + + memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count); + nv50->vtxbuf_nr = count; + + nv50->dirty |= NV50_NEW_ARRAYS; } static void nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count, const struct pipe_vertex_element *ve) { + struct nv50_context *nv50 = nv50_context(pipe); + + memcpy(nv50->vtxelt, ve, sizeof(*ve) * count); + nv50->vtxelt_nr = count; + + nv50->dirty |= NV50_NEW_ARRAYS; } void diff --git a/src/gallium/drivers/nv50/nv50_state.h b/src/gallium/drivers/nv50/nv50_state.h index a3b781d4c6..be0c75ad6e 100644 --- a/src/gallium/drivers/nv50/nv50_state.h +++ b/src/gallium/drivers/nv50/nv50_state.h @@ -2,6 +2,36 @@ #define __NV50_STATE_H__ #include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" +struct nv50_program_data { + int index; + int component; + float value; +}; + +struct nv50_program { + struct pipe_shader_state pipe; + struct tgsi_shader_info info; + boolean translated; + + unsigned *insns; + unsigned insns_nr; + + struct pipe_buffer *buffer; + + unsigned param_nr; + float *immd; + unsigned immd_nr; + + struct nouveau_resource *data; + + union { + struct { + unsigned high_temp; + unsigned attr[2]; + } vp; + } cfg; +}; #endif diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 68d419f9fc..4a548378b7 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -15,8 +15,8 @@ nv50_state_validate_fb(struct nv50_context *nv50) h = fb->cbufs[i]->height; gw = 1; } else { - assert(w != fb->cbufs[i]->width); - assert(h != fb->cbufs[i]->height); + assert(w == fb->cbufs[i]->width); + assert(h == fb->cbufs[i]->height); } so_method(so, tesla, NV50TCL_RT_HORIZ(i), 2); @@ -46,6 +46,9 @@ nv50_state_validate_fb(struct nv50_context *nv50) } so_data(so, 0x00000040); so_data(so, 0x00000000); + + so_method(so, tesla, 0x1224, 1); + so_data (so, 1); } if (fb->zsbuf) { @@ -54,11 +57,11 @@ nv50_state_validate_fb(struct nv50_context *nv50) h = fb->zsbuf->height; gw = 1; } else { - assert(w != fb->zsbuf->width); - assert(h != fb->zsbuf->height); + assert(w == fb->zsbuf->width); + assert(h == fb->zsbuf->height); } - so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5); + so_method(so, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 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, @@ -83,9 +86,12 @@ nv50_state_validate_fb(struct nv50_context *nv50) 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_method(so, tesla, 0xff4, 2); so_data (so, w << 16); so_data (so, h << 16); + so_method(so, tesla, 0xdf8, 2); + so_data (so, 0); + so_data (so, h); so_emit(nv50->screen->nvws, so); so_ref(NULL, &so); @@ -108,6 +114,12 @@ nv50_state_validate(struct nv50_context *nv50) if (nv50->dirty & NV50_NEW_ZSA) so_emit(nvws, nv50->zsa->so); + if (nv50->dirty & NV50_NEW_VERTPROG) + nv50_vertprog_validate(nv50); + + if (nv50->dirty & NV50_NEW_FRAGPROG) + nv50_fragprog_validate(nv50); + if (nv50->dirty & NV50_NEW_RASTERIZER) so_emit(nvws, nv50->rasterizer->so); @@ -150,12 +162,15 @@ nv50_state_validate(struct nv50_context *nv50) 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[1])); so_data (so, fui(nv50->viewport.scale[2])); so_emit(nvws, so); so_ref(NULL, &so); } + if (nv50->dirty & NV50_NEW_ARRAYS) + nv50_vbo_validate(nv50); + nv50->dirty = 0; return TRUE; } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index b01ce1d42c..f086c76258 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -5,6 +5,29 @@ #include "nv50_context.h" #include "nv50_state.h" +static INLINE unsigned +nv50_prim(unsigned mode) +{ + switch (mode) { + case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS; + case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES; + case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP; + case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP; + case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES; + case PIPE_PRIM_TRIANGLE_STRIP: + return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP; + case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN; + case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS; + case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP; + case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON; + default: + break; + } + + NOUVEAU_ERR("invalid primitive type %d\n", mode); + return NV50TCL_VERTEX_BEGIN_POINTS; +} + boolean nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) @@ -12,8 +35,22 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, struct nv50_context *nv50 = nv50_context(pipe); nv50_state_validate(nv50); - NOUVEAU_ERR("unimplemented\n"); + + BEGIN_RING(tesla, 0x142c, 1); + OUT_RING (0); + BEGIN_RING(tesla, 0x142c, 1); + OUT_RING (0); + + BEGIN_RING(tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (nv50_prim(mode)); + BEGIN_RING(tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2); + OUT_RING (start); + OUT_RING (count); + BEGIN_RING(tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (0); + + pipe->flush(pipe, 0, NULL); return TRUE; } @@ -30,3 +67,49 @@ nv50_draw_elements(struct pipe_context *pipe, return TRUE; } +void +nv50_vbo_validate(struct nv50_context *nv50) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_stateobj *vtxbuf, *vtxfmt; + int i, vpi = 0; + + vtxbuf = so_new(nv50->vtxelt_nr * 4, nv50->vtxelt_nr * 2); + vtxfmt = so_new(nv50->vtxelt_nr + 1, 0); + so_method(vtxfmt, tesla, 0x1ac0, nv50->vtxelt_nr); + + for (i = 0; i < nv50->vtxelt_nr; i++) { + struct pipe_vertex_element *ve = &nv50->vtxelt[i]; + struct pipe_vertex_buffer *vb = + &nv50->vtxbuf[ve->vertex_buffer_index]; + + switch (ve->src_format) { + case PIPE_FORMAT_R32G32B32_FLOAT: + so_data(vtxfmt, 0x7e100000 | i); + break; + default: + { + char fmt[128]; + pf_sprint_name(fmt, ve->src_format); + NOUVEAU_ERR("invalid vbo format %s\n", fmt); + assert(0); + return; + } + } + + so_method(vtxbuf, tesla, 0x900 + (i * 16), 3); + so_data (vtxbuf, 0x20000000 | vb->pitch); + so_reloc (vtxbuf, vb->buffer, vb->buffer_offset + + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_HIGH, 0, 0); + so_reloc (vtxbuf, vb->buffer, vb->buffer_offset + + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_LOW, 0, 0); + } + + so_emit(nv50->screen->nvws, vtxfmt); + so_ref (NULL, &vtxfmt); + so_emit(nv50->screen->nvws, vtxbuf); + so_ref (NULL, &vtxbuf); +} + -- cgit v1.2.3 From 716c1cd2ecbc1e86c0fd747c9fa9e095ded5fd5d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 1 Jun 2008 23:10:31 +1000 Subject: nv50: use "real" constbufs for shaders + tcb uploads --- src/gallium/drivers/nv50/nv50_context.h | 14 ++++++- src/gallium/drivers/nv50/nv50_program.c | 27 +++++------- src/gallium/drivers/nv50/nv50_screen.c | 57 +++++++++++++++----------- src/gallium/drivers/nv50/nv50_screen.h | 3 ++ src/gallium/drivers/nv50/nv50_state.c | 4 +- src/gallium/drivers/nv50/nv50_state.h | 1 - src/gallium/drivers/nv50/nv50_state_validate.c | 29 +++++++++++++ 7 files changed, 90 insertions(+), 45 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index d4d716b94b..c4a8a4c064 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -23,6 +23,14 @@ #define NOUVEAU_MSG(fmt, args...) \ fprintf(stderr, "nouveau: "fmt, ##args); +/* Constant buffer assignment */ +#define NV50_CB_PMISC 0 +#define NV50_CB_PVP 1 +#define NV50_CB_PFP 2 +#define NV50_CB_PGP 3 +#define NV50_CB_TIC 4 +#define NV50_CB_TSC 5 + #define NV50_NEW_BLEND (1 << 0) #define NV50_NEW_ZSA (1 << 1) #define NV50_NEW_BLEND_COLOUR (1 << 2) @@ -32,8 +40,10 @@ #define NV50_NEW_RASTERIZER (1 << 6) #define NV50_NEW_FRAMEBUFFER (1 << 7) #define NV50_NEW_VERTPROG (1 << 8) -#define NV50_NEW_FRAGPROG (1 << 9) -#define NV50_NEW_ARRAYS (1 << 10) +#define NV50_NEW_VERTPROG_CB (1 << 9) +#define NV50_NEW_FRAGPROG (1 << 10) +#define NV50_NEW_FRAGPROG_CB (1 << 11) +#define NV50_NEW_ARRAYS (1 << 12) struct nv50_blend_stateobj { struct pipe_blend_state pipe; diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 30953b7d8a..0a43646923 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -179,6 +179,10 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, if (src1) { if (src1->type == P_CONST || src1->type == P_IMMD) { + if (src1->type == P_IMMD) + inst[1] |= (NV50_CB_PMISC << 22); + else + inst[1] |= (NV50_CB_PVP << 22); inst[0] |= 0x00800000; /* src1 is const */ /*XXX: does src1 come from "src2" now? */ alloc_reg(pc, src1); @@ -196,6 +200,10 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, if (src2) { if (src2->type == P_CONST || src2->type == P_IMMD) { + if (src2->type == P_IMMD) + inst[1] |= (NV50_CB_PMISC << 22); + else + inst[1] |= (NV50_CB_PVP << 22); inst[0] |= 0x01000000; /* src2 is const */ inst[1] |= (src2->hw << 14); } else { @@ -526,7 +534,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) } if (pc->immd_nr) { - int rid = pc->param_nr * 4; + int rid = 0; pc->immd = calloc(pc->immd_nr * 4, sizeof(struct nv50_reg)); if (!pc->immd) @@ -581,7 +589,6 @@ nv50_program_tx(struct nv50_program *p) } } - p->param_nr = pc->param_nr * 4; p->immd_nr = pc->immd_nr * 4; p->immd = pc->immd_buf; @@ -654,23 +661,9 @@ nv50_vertprog_validate(struct nv50_context *nv50) memcpy(map, p->insns, p->insns_nr * 4); ws->buffer_unmap(ws, p->buffer); - if (p->param_nr) { - float *cb; - - cb = ws->buffer_map(ws, nv50->constbuf[PIPE_SHADER_VERTEX], - PIPE_BUFFER_USAGE_CPU_READ); - for (i = 0; i < p->param_nr; i++) { - BEGIN_RING(tesla, 0x0f00, 2); - OUT_RING (i << 8); - OUT_RING (fui(cb[i])); - } - ws->buffer_unmap(ws, nv50->constbuf[PIPE_SHADER_VERTEX]); - } - - for (i = 0; i < p->immd_nr; i++) { BEGIN_RING(tesla, 0x0f00, 2); - OUT_RING ((p->param_nr + i) << 8); + OUT_RING ((NV50_CB_PMISC << 16) | (i << 8)); OUT_RING (fui(p->immd[i])); } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index fc3eeed913..6c0810a9cf 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -203,14 +203,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) return NULL; } - /* Static constant buffer */ - screen->constbuf = ws->buffer_create(ws, 0, 0, 256 * 4 * 4); - if (nvws->res_init(&screen->vp_data_heap, 0, 256)) { - NOUVEAU_ERR("Error initialising constant buffer\n"); - nv50_screen_destroy(&screen->pipe); - return NULL; - } - /* Static tesla init */ so = so_new(256, 20); @@ -245,37 +237,56 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_method(so, screen->tesla, 0x16b8, 1); so_data (so, 8); + /* Shared constant buffer */ + screen->constbuf = ws->buffer_create(ws, 0, 0, 256 * 4 * 4); + if (nvws->res_init(&screen->vp_data_heap, 0, 256)) { + NOUVEAU_ERR("Error initialising constant buffer\n"); + nv50_screen_destroy(&screen->pipe); + return NULL; + } + so_method(so, screen->tesla, 0x1280, 3); so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0x00001000); + so_data (so, (NV50_CB_PMISC << 16) | 0x00001000); + + /* Texture sampler/image unit setup - we abuse the constant buffer + * upload mechanism for the moment to upload data to the tex config + * blocks. At some point we *may* want to go the NVIDIA way of doing + * things? + */ + screen->tic = ws->buffer_create(ws, 0, 0, 32 * 8 * 4); so_method(so, screen->tesla, 0x1280, 3); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0x00014000); - so_method(so, screen->tesla, 0x1280, 3); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_data (so, (NV50_CB_TIC << 16) | 0x0800); + so_method(so, screen->tesla, 0x1574, 3); + so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0x00024000); + so_data (so, 0x00000800); + + screen->tsc = ws->buffer_create(ws, 0, 0, 32 * 8 * 4); so_method(so, screen->tesla, 0x1280, 3); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0x00034000); - so_method(so, screen->tesla, 0x1280, 3); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_data (so, (NV50_CB_TSC << 16) | 0x0800); + so_method(so, screen->tesla, 0x155c, 3); + so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM | + so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0x00040100); + so_data (so, 0x00000800); + + /* Vertex array limits - max them out */ for (i = 0; i < 16; i++) { so_method(so, screen->tesla, 0x1080 + (i * 8), 2); so_data (so, 0x000000ff); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index d63dd48508..5acb5003ba 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -15,6 +15,9 @@ struct nv50_screen { struct pipe_buffer *constbuf; struct nouveau_resource *vp_data_heap; + + struct pipe_buffer *tic; + struct pipe_buffer *tsc; }; static INLINE struct nv50_screen * diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index fd10a38378..ba3d04cede 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -406,11 +406,11 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, if (shader == PIPE_SHADER_VERTEX) { nv50->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; - nv50->dirty |= NV50_NEW_VERTPROG; + nv50->dirty |= NV50_NEW_VERTPROG_CB; } else if (shader == PIPE_SHADER_FRAGMENT) { nv50->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; - nv50->dirty |= NV50_NEW_FRAGPROG; + nv50->dirty |= NV50_NEW_FRAGPROG_CB; } } diff --git a/src/gallium/drivers/nv50/nv50_state.h b/src/gallium/drivers/nv50/nv50_state.h index be0c75ad6e..9e3876871b 100644 --- a/src/gallium/drivers/nv50/nv50_state.h +++ b/src/gallium/drivers/nv50/nv50_state.h @@ -20,7 +20,6 @@ struct nv50_program { struct pipe_buffer *buffer; - unsigned param_nr; float *immd; unsigned immd_nr; diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 4a548378b7..05395c6df7 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -168,6 +168,35 @@ nv50_state_validate(struct nv50_context *nv50) so_ref(NULL, &so); } + if (nv50->dirty & NV50_NEW_VERTPROG_CB) { + so = so_new(4, 2); + so_method(so, tesla, 0x1280, 3); + so_reloc (so, nv50->constbuf[PIPE_SHADER_VERTEX], 0, + NOUVEAU_BO_HIGH | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, + 0, 0); + so_reloc (so, nv50->constbuf[PIPE_SHADER_VERTEX], 0, + NOUVEAU_BO_LOW | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, + 0, 0); + so_data (so, (NV50_CB_PVP << 16) | 0x1000); + so_emit(nvws, so); + so_ref(NULL, &so); + } + + if (nv50->dirty & NV50_NEW_FRAGPROG_CB) { + so = so_new(4, 2); + so_method(so, tesla, 0x1280, 3); + so_reloc (so, nv50->constbuf[PIPE_SHADER_FRAGMENT], 0, + NOUVEAU_BO_HIGH | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, + 0, 0); + so_reloc (so, nv50->constbuf[PIPE_SHADER_FRAGMENT], 0, + NOUVEAU_BO_LOW | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, + 0, 0); + so_data (so, (NV50_CB_PFP << 16) | 0x1000); + so_emit(nvws, so); + so_ref(NULL, &so); + } + + if (nv50->dirty & NV50_NEW_ARRAYS) nv50_vbo_validate(nv50); -- cgit v1.2.3 From 41cd9bddf77ea60f84a957e83ddf098818c95c41 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 1 Jun 2008 23:16:17 +1000 Subject: nv50: fucking horrible hack, I really hate G8x shaders.. --- src/gallium/drivers/nv50/nv50_program.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 0a43646923..1b192b897c 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -135,10 +135,18 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, struct nv50_reg *src0, struct nv50_reg *src1, struct nv50_reg *src2) { struct nv50_program *p = pc->p; - struct nv50_reg *tmp = NULL, *tmp2 = NULL; + struct nv50_reg *tmp0 = NULL, *tmp = NULL, *tmp2 = NULL; unsigned inst[2] = { 0, 0 }; /* Grr.. Fun restrictions on where attribs can be sourced from.. */ + if (src0 && (src0->type == P_CONST || src0->type == P_IMMD) && + (op == 0xc || op == 0xe)) { + tmp = src1; + src1 = src0; + src0 = tmp; + tmp = NULL; + } + if (src1 && src1->type == P_ATTR) { tmp = alloc_temp(pc, dst); emit(pc, 1, tmp, src1, NULL, NULL); @@ -243,6 +251,7 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, } } + if (tmp0) free_temp(pc, tmp0); if (tmp) free_temp(pc, tmp); if (tmp2) free_temp(pc, tmp2); -- cgit v1.2.3 From 38ce697e5942550888c28bd4859ca2a92f247bf7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 2 Jun 2008 12:08:06 +1000 Subject: nv50: implement SUB --- src/gallium/drivers/nv50/nv50_program.c | 63 +++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 1b192b897c..41ff05dabe 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -11,9 +11,11 @@ #include "nv50_state.h" #define OP_MOV 0x001 +#define OP_INTERP 0x008 #define OP_RCP 0x009 #define OP_ADD 0x00b #define OP_MUL 0x00c +#define OP_MAD 0x00e #define NV50_SU_MAX_TEMP 64 struct nv50_reg { @@ -27,6 +29,7 @@ struct nv50_reg { int index; int hw; + int neg; }; struct nv50_pc { @@ -140,7 +143,7 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, /* Grr.. Fun restrictions on where attribs can be sourced from.. */ if (src0 && (src0->type == P_CONST || src0->type == P_IMMD) && - (op == 0xc || op == 0xe)) { + (op == OP_MUL || op == OP_MAD)) { tmp = src1; src1 = src0; src0 = tmp; @@ -149,12 +152,14 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, if (src1 && src1->type == P_ATTR) { tmp = alloc_temp(pc, dst); + tmp->neg = src1->neg; src1->neg = 0; emit(pc, 1, tmp, src1, NULL, NULL); src1 = tmp; } if (src2 && src2->type == P_ATTR) { tmp2 = alloc_temp(pc, dst); + tmp2->neg = src2->neg; src2->neg = 0; emit(pc, 1, tmp2, src2, NULL, NULL); src2 = tmp2; } @@ -197,7 +202,7 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, inst[0] |= (src1->hw << 16); } else { alloc_reg(pc, src1); - if (op == 0xc || op == 0xe) + if (op == OP_MUL || op == OP_MAD) inst[0] |= (src1->hw << 16); else inst[1] |= (src1->hw << 14); @@ -216,7 +221,7 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, inst[1] |= (src2->hw << 14); } else { alloc_reg(pc, src2); - if (inst[0] & 0x00800000 || op ==0xe) + if (inst[0] & 0x00800000 || op == OP_MAD) inst[1] |= (src2->hw << 14); else inst[0] |= (src2->hw << 16); @@ -224,14 +229,24 @@ emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, } /*XXX: FIXME */ - if (op == 0xb || op == 0xc || op == 0x9 || op == 0xe) { + switch (op) { + case OP_ADD: + case OP_MUL: + case OP_RCP: + case OP_MAD: /* 0x04000000 negates arg0 */ /* 0x08000000 negates arg1 */ /*XXX: true for !0xb also ? */ + if (src0 && src0->neg) + inst[1] |= 0x04000000; + if (src1 && src1->neg) + inst[1] |= 0x08000000; inst[1] |= 0x00000780; - } else { + break; + default: /* 0x04000000 == arg0 32 bit, otherwise 16 bit */ inst[1] |= 0x04000780; + break; } } else { inst[0] |= ((op & 0xf) << 28); @@ -340,61 +355,71 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) case TGSI_OPCODE_ADD: for (c = 0; c < 4; c++) { if (mask & (1 << c)) { - emit(pc, 0x0b, dst[c], + emit(pc, OP_ADD, dst[c], src[0][c], src[1][c], none); } } break; case TGSI_OPCODE_DP3: tmp = alloc_temp(pc, NULL); - emit(pc, 0x0c, tmp, src[0][0], src[1][0], NULL); - emit(pc, 0x0e, tmp, src[0][1], src[1][1], tmp); - emit(pc, 0x0e, tmp, src[0][2], src[1][2], tmp); + emit(pc, OP_MUL, tmp, src[0][0], src[1][0], NULL); + emit(pc, OP_MAD, tmp, src[0][1], src[1][1], tmp); + emit(pc, OP_MAD, tmp, src[0][2], src[1][2], tmp); for (c = 0; c < 4; c++) { if (mask & (1 << c)) - emit(pc, 0x01, dst[c], tmp, none, none); + emit(pc, OP_MOV, dst[c], tmp, none, none); } free_temp(pc, tmp); break; case TGSI_OPCODE_DP4: tmp = alloc_temp(pc, NULL); - emit(pc, 0x0c, tmp, src[0][0], src[1][0], NULL); - emit(pc, 0x0e, tmp, src[0][1], src[1][1], tmp); - emit(pc, 0x0e, tmp, src[0][2], src[1][2], tmp); - emit(pc, 0x0e, tmp, src[0][3], src[1][3], tmp); + emit(pc, OP_MUL, tmp, src[0][0], src[1][0], NULL); + emit(pc, OP_MAD, tmp, src[0][1], src[1][1], tmp); + emit(pc, OP_MAD, tmp, src[0][2], src[1][2], tmp); + emit(pc, OP_MAD, tmp, src[0][3], src[1][3], tmp); for (c = 0; c < 4; c++) { if (mask & (1 << c)) - emit(pc, 0x01, dst[c], tmp, none, none); + emit(pc, OP_MOV, dst[c], tmp, none, none); } free_temp(pc, tmp); break; case TGSI_OPCODE_MAD: for (c = 0; c < 4; c++) { if (mask & (1 << c)) - emit(pc, 0x0e, dst[c], + emit(pc, OP_MAD, dst[c], src[0][c], src[1][c], src[2][c]); } break; case TGSI_OPCODE_MOV: for (c = 0; c < 4; c++) { if (mask & (1 << c)) - emit(pc, 0x01, dst[c], src[0][c], none, none); + emit(pc, OP_MOV, dst[c], src[0][c], none, none); } break; case TGSI_OPCODE_MUL: for (c = 0; c < 4; c++) { if (mask & (1 << c)) - emit(pc, 0x0c, dst[c], + emit(pc, OP_MUL, dst[c], src[0][c], src[1][c], none); } break; case TGSI_OPCODE_RCP: for (c = 0; c < 4; c++) { if (mask & (1 << c)) - emit(pc, 0x09, dst[c], + emit(pc, OP_RCP, dst[c], src[0][c], none, none); } break; + case TGSI_OPCODE_SUB: + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) { + src[1][c]->neg = 1; + emit(pc, OP_ADD, dst[c], + src[0][c], src[1][c], none); + src[1][c]->neg = 0; + } + } + break; case TGSI_OPCODE_END: break; default: -- cgit v1.2.3 From 207b7974723c6b88aacfa3703a1e049ff35db6a8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 2 Jun 2008 12:12:16 +1000 Subject: nv50: DPH --- src/gallium/drivers/nv50/nv50_program.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 41ff05dabe..12bd419f4c 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -383,6 +383,18 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } free_temp(pc, tmp); break; + case TGSI_OPCODE_DPH: + tmp = alloc_temp(pc, NULL); + emit(pc, OP_MUL, tmp, src[0][0], src[1][0], NULL); + emit(pc, OP_MAD, tmp, src[0][1], src[1][1], tmp); + emit(pc, OP_MAD, tmp, src[0][2], src[1][2], tmp); + emit(pc, OP_ADD, tmp, src[1][3], tmp, NULL); + for (c = 0; c < 4; c++) { + if (mask & (1 << c)) + emit(pc, OP_MOV, dst[c], tmp, none, none); + } + free_temp(pc, tmp); + break; case TGSI_OPCODE_MAD: for (c = 0; c < 4; c++) { if (mask & (1 << c)) -- cgit v1.2.3 From 22e0acc466947b203574c88f4964f61ef46ae3fd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 2 Jun 2008 13:01:09 +1000 Subject: nv50: split code/data upload out, fp will use it later on --- src/gallium/drivers/nv50/nv50_program.c | 42 +++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 12bd419f4c..97e3eab906 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -684,16 +684,37 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) p->translated = TRUE; } +static void +nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) +{ + int i; + + for (i = 0; i < p->immd_nr; i++) { + BEGIN_RING(tesla, 0x0f00, 2); + OUT_RING ((NV50_CB_PMISC << 16) | (i << 8)); + OUT_RING (fui(p->immd[i])); + } +} + +static void +nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) +{ + struct pipe_winsys *ws = nv50->pipe.winsys; + void *map; + + if (!p->buffer) + p->buffer = ws->buffer_create(ws, 0x100, 0, p->insns_nr * 4); + map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + memcpy(map, p->insns, p->insns_nr * 4); + ws->buffer_unmap(ws, p->buffer); +} + void nv50_vertprog_validate(struct nv50_context *nv50) { - struct pipe_winsys *ws = nv50->pipe.winsys; - struct nouveau_winsys *nvws = nv50->screen->nvws; struct nouveau_grobj *tesla = nv50->screen->tesla; struct nv50_program *p = nv50->vertprog; struct nouveau_stateobj *so; - void *map; - int i; if (!p->translated) { nv50_program_validate(nv50, p); @@ -701,17 +722,8 @@ nv50_vertprog_validate(struct nv50_context *nv50) assert(0); } - if (!p->buffer) - p->buffer = ws->buffer_create(ws, 0x100, 0, p->insns_nr * 4); - map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); - memcpy(map, p->insns, p->insns_nr * 4); - ws->buffer_unmap(ws, p->buffer); - - for (i = 0; i < p->immd_nr; i++) { - BEGIN_RING(tesla, 0x0f00, 2); - OUT_RING ((NV50_CB_PMISC << 16) | (i << 8)); - OUT_RING (fui(p->immd[i])); - } + nv50_program_validate_data(nv50, p); + nv50_program_validate_code(nv50, p); so = so_new(11, 2); so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2); -- cgit v1.2.3 From 55b2fe1047b37d0d86641a252e1c745111030393 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 2 Jun 2008 23:52:58 +1000 Subject: nv50: drop the majority of the old shader code, reimplement, only MOV so far. --- src/gallium/drivers/nv50/nv50_program.c | 411 ++++++++++++-------------------- 1 file changed, 146 insertions(+), 265 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 97e3eab906..aa848faa49 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -10,13 +10,8 @@ #include "nv50_context.h" #include "nv50_state.h" -#define OP_MOV 0x001 -#define OP_INTERP 0x008 -#define OP_RCP 0x009 -#define OP_ADD 0x00b -#define OP_MUL 0x00c -#define OP_MAD 0x00e #define NV50_SU_MAX_TEMP 64 +#define TX_FRAGPROG 0 struct nv50_reg { enum { @@ -106,181 +101,6 @@ free_temp(struct nv50_pc *pc, struct nv50_reg *r) } } -#if 0 -static struct nv50_reg * -constant(struct nv50_pc *pc, int pipe, int c, float v) -{ - struct nv50_reg *r = CALLOC_STRUCT(nv50_reg); - struct nv50_program *p = pc->p; - struct nv50_program_data *pd; - int idx; - - if (pipe >= 0) { - for (idx = 0; idx < p->nr_consts; idx++) { - if (p->consts[idx].index == pipe) - return nv40_sr(NV40SR_CONST, idx); - } - } - - idx = p->nr_consts++; - p->consts = realloc(p->consts, sizeof(*pd) * p->nr_consts); - pd = &p->consts[idx]; - - pd->index = pipe; - pd->component = c; - pd->value = v; - return nv40_sr(NV40SR_CONST, idx); -} -#endif - -static void -emit(struct nv50_pc *pc, unsigned op, struct nv50_reg *dst, - struct nv50_reg *src0, struct nv50_reg *src1, struct nv50_reg *src2) -{ - struct nv50_program *p = pc->p; - struct nv50_reg *tmp0 = NULL, *tmp = NULL, *tmp2 = NULL; - unsigned inst[2] = { 0, 0 }; - - /* Grr.. Fun restrictions on where attribs can be sourced from.. */ - if (src0 && (src0->type == P_CONST || src0->type == P_IMMD) && - (op == OP_MUL || op == OP_MAD)) { - tmp = src1; - src1 = src0; - src0 = tmp; - tmp = NULL; - } - - if (src1 && src1->type == P_ATTR) { - tmp = alloc_temp(pc, dst); - tmp->neg = src1->neg; src1->neg = 0; - emit(pc, 1, tmp, src1, NULL, NULL); - src1 = tmp; - } - - if (src2 && src2->type == P_ATTR) { - tmp2 = alloc_temp(pc, dst); - tmp2->neg = src2->neg; src2->neg = 0; - emit(pc, 1, tmp2, src2, NULL, NULL); - src2 = tmp2; - } - - /* Get this out of the way first. What type of opcode do we - * want/need to build? - */ - if ((op & 0x3f0) || dst->type == P_RESULT || - (src0 && src0->type == P_ATTR) || src1 || src2) - inst[0] |= 0x00000001; - - if (inst[0] & 0x00000001) { - inst[0] |= ((op & 0xf) << 28); - inst[1] |= ((op >> 4) << 26); - - alloc_reg(pc, dst); - if (dst->type == P_RESULT) - inst[1] |= 0x00000008; - inst[0] |= (dst->hw << 2); - - if (src0) { - if (src0->type == P_ATTR) - inst[1] |= 0x00200000; - else - if (src0->type == P_CONST || src0->type == P_IMMD) - assert(0); - alloc_reg(pc, src0); - inst[0] |= (src0->hw << 9); - } - - if (src1) { - if (src1->type == P_CONST || src1->type == P_IMMD) { - if (src1->type == P_IMMD) - inst[1] |= (NV50_CB_PMISC << 22); - else - inst[1] |= (NV50_CB_PVP << 22); - inst[0] |= 0x00800000; /* src1 is const */ - /*XXX: does src1 come from "src2" now? */ - alloc_reg(pc, src1); - inst[0] |= (src1->hw << 16); - } else { - alloc_reg(pc, src1); - if (op == OP_MUL || op == OP_MAD) - inst[0] |= (src1->hw << 16); - else - inst[1] |= (src1->hw << 14); - } - } else { - inst[1] |= 0x0003c000; /*XXX FIXME */ - } - - if (src2) { - if (src2->type == P_CONST || src2->type == P_IMMD) { - if (src2->type == P_IMMD) - inst[1] |= (NV50_CB_PMISC << 22); - else - inst[1] |= (NV50_CB_PVP << 22); - inst[0] |= 0x01000000; /* src2 is const */ - inst[1] |= (src2->hw << 14); - } else { - alloc_reg(pc, src2); - if (inst[0] & 0x00800000 || op == OP_MAD) - inst[1] |= (src2->hw << 14); - else - inst[0] |= (src2->hw << 16); - } - } - - /*XXX: FIXME */ - switch (op) { - case OP_ADD: - case OP_MUL: - case OP_RCP: - case OP_MAD: - /* 0x04000000 negates arg0 */ - /* 0x08000000 negates arg1 */ - /*XXX: true for !0xb also ? */ - if (src0 && src0->neg) - inst[1] |= 0x04000000; - if (src1 && src1->neg) - inst[1] |= 0x08000000; - inst[1] |= 0x00000780; - break; - default: - /* 0x04000000 == arg0 32 bit, otherwise 16 bit */ - inst[1] |= 0x04000780; - break; - } - } else { - inst[0] |= ((op & 0xf) << 28); - - alloc_reg(pc, dst); - inst[0] |= (dst->hw << 2); - - if (src0) { - alloc_reg(pc, src0); - inst[0] |= (src0->hw << 9); - } - - /*XXX: NFI if this even works - probably not.. */ - if (src1) { - alloc_reg(pc, src1); - inst[0] |= (src1->hw << 16); - } - } - - if (tmp0) free_temp(pc, tmp0); - if (tmp) free_temp(pc, tmp); - if (tmp2) free_temp(pc, tmp2); - - if (inst[0] & 1) { - p->insns_nr += 2; - p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); - memcpy(p->insns + (p->insns_nr - 2), inst, sizeof(unsigned)*2); - } else { - p->insns_nr += 1; - p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); - memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned)); - } -} - static struct nv50_reg * tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) { @@ -327,11 +147,147 @@ tgsi_src(struct nv50_pc *pc, int c, const struct tgsi_full_src_register *src) return NULL; } +static void +emit(struct nv50_pc *pc, unsigned *inst) +{ + struct nv50_program *p = pc->p; + + if (inst[0] & 1) { + p->insns_nr += 2; + p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); + memcpy(p->insns + (p->insns_nr - 2), inst, sizeof(unsigned)*2); + } else { + p->insns_nr += 1; + p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); + memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned)); + } +} + +static INLINE void set_long(struct nv50_pc *, unsigned *); + +static boolean +is_long(unsigned *inst) +{ + if (inst[0] & 1) + return TRUE; + return FALSE; +} + +static boolean +is_immd(unsigned *inst) +{ + if (is_long(inst) && (inst[1] & 3) == 3) + return TRUE; + return FALSE; +} + +static INLINE void +set_pred(struct nv50_pc *pc, unsigned pred, unsigned idx, unsigned *inst) +{ + set_long(pc, inst); + inst[1] &= ~((0x1f << 7) | (0x3 << 12)); + inst[1] |= (pred << 7) | (idx << 12); +} + +static INLINE void +set_pred_wr(struct nv50_pc *pc, unsigned on, unsigned idx, unsigned *inst) +{ + set_long(pc, inst); + inst[1] &= ~((0x3 << 4) | (1 << 6)); + inst[1] |= (idx << 4) | (on << 6); +} + +static INLINE void +set_long(struct nv50_pc *pc, unsigned *inst) +{ + if (is_long(inst)) + return; + + inst[0] |= 1; + set_pred(pc, 0xf, 0, inst); + set_pred_wr(pc, 0, 0, inst); +} + +static INLINE void +set_dst(struct nv50_pc *pc, struct nv50_reg *dst, unsigned *inst) +{ + if (dst->type == P_RESULT) { + set_long(pc, inst); + inst[1] |= 0x00000008; + } + + alloc_reg(pc, dst); + inst[0] |= (dst->hw << 2); +} + +static INLINE void +set_immd(struct nv50_pc *pc, struct nv50_reg *imm, unsigned *inst) +{ + unsigned val = fui(pc->immd_buf[imm->hw]); /* XXX */ + + set_long(pc, inst); + /*XXX: can't be predicated - bits overlap.. catch cases where both + * are required and avoid them. */ + set_pred(pc, 0, 0, inst); + set_pred_wr(pc, 0, 0, inst); + + inst[1] |= 0x00000002 | 0x00000001; + inst[0] |= (val & 0x3f) << 16; + inst[1] |= (val >> 6) << 2; +} + +static void +emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) +{ + unsigned inst[2] = { 0, 0 }; + int i; + + inst[0] |= 0x10000000; + + set_dst(pc, dst, inst); + + if (dst->type != P_RESULT && src->type == P_IMMD) { + set_immd(pc, src, inst); + /*XXX: 32-bit, but steals part of "half" reg space - need to + * catch and handle this case if/when we do half-regs + */ + inst[0] |= 0x00008000; + } else + if (src->type == P_IMMD || src->type == P_CONST) { + set_long(pc, inst); + if (src->type == P_IMMD) + inst[1] |= (NV50_CB_PMISC << 22); + else + inst[1] |= (NV50_CB_PVP << 22); + inst[0] |= (src->hw << 9); + inst[1] |= 0x20000000; /* src0 const? */ + } else { + if (src->type == P_ATTR) { + set_long(pc, inst); + inst[1] |= 0x00200000; + } + + alloc_reg(pc, src); + inst[0] |= (src->hw << 9); + } + + /* We really should support "half" instructions here at some point, + * but I don't feel confident enough about them yet. + */ + set_long(pc, inst); + if (is_long(inst) && !is_immd(inst)) { + inst[1] |= 0x04000000; /* 32-bit */ + inst[1] |= 0x0003c000; /* "subsubop" 0xf == mov */ + } + + emit(pc, inst); +} + static boolean nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) { const struct tgsi_full_instruction *inst = &tok->FullInstruction; - struct nv50_reg *dst[4], *src[3][4], *none = NULL, *tmp; + struct nv50_reg *dst[4], *src[3][4]; unsigned mask; int i, c; @@ -352,85 +308,9 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ADD: - for (c = 0; c < 4; c++) { - if (mask & (1 << c)) { - emit(pc, OP_ADD, dst[c], - src[0][c], src[1][c], none); - } - } - break; - case TGSI_OPCODE_DP3: - tmp = alloc_temp(pc, NULL); - emit(pc, OP_MUL, tmp, src[0][0], src[1][0], NULL); - emit(pc, OP_MAD, tmp, src[0][1], src[1][1], tmp); - emit(pc, OP_MAD, tmp, src[0][2], src[1][2], tmp); - for (c = 0; c < 4; c++) { - if (mask & (1 << c)) - emit(pc, OP_MOV, dst[c], tmp, none, none); - } - free_temp(pc, tmp); - break; - case TGSI_OPCODE_DP4: - tmp = alloc_temp(pc, NULL); - emit(pc, OP_MUL, tmp, src[0][0], src[1][0], NULL); - emit(pc, OP_MAD, tmp, src[0][1], src[1][1], tmp); - emit(pc, OP_MAD, tmp, src[0][2], src[1][2], tmp); - emit(pc, OP_MAD, tmp, src[0][3], src[1][3], tmp); - for (c = 0; c < 4; c++) { - if (mask & (1 << c)) - emit(pc, OP_MOV, dst[c], tmp, none, none); - } - free_temp(pc, tmp); - break; - case TGSI_OPCODE_DPH: - tmp = alloc_temp(pc, NULL); - emit(pc, OP_MUL, tmp, src[0][0], src[1][0], NULL); - emit(pc, OP_MAD, tmp, src[0][1], src[1][1], tmp); - emit(pc, OP_MAD, tmp, src[0][2], src[1][2], tmp); - emit(pc, OP_ADD, tmp, src[1][3], tmp, NULL); - for (c = 0; c < 4; c++) { - if (mask & (1 << c)) - emit(pc, OP_MOV, dst[c], tmp, none, none); - } - free_temp(pc, tmp); - break; - case TGSI_OPCODE_MAD: - for (c = 0; c < 4; c++) { - if (mask & (1 << c)) - emit(pc, OP_MAD, dst[c], - src[0][c], src[1][c], src[2][c]); - } - break; case TGSI_OPCODE_MOV: - for (c = 0; c < 4; c++) { - if (mask & (1 << c)) - emit(pc, OP_MOV, dst[c], src[0][c], none, none); - } - break; - case TGSI_OPCODE_MUL: - for (c = 0; c < 4; c++) { - if (mask & (1 << c)) - emit(pc, OP_MUL, dst[c], - src[0][c], src[1][c], none); - } - break; - case TGSI_OPCODE_RCP: - for (c = 0; c < 4; c++) { - if (mask & (1 << c)) - emit(pc, OP_RCP, dst[c], - src[0][c], none, none); - } - break; - case TGSI_OPCODE_SUB: - for (c = 0; c < 4; c++) { - if (mask & (1 << c)) { - src[1][c]->neg = 1; - emit(pc, OP_ADD, dst[c], - src[0][c], src[1][c], none); - src[1][c]->neg = 0; - } - } + for (c = 0; c < 4; c++) + emit_mov(pc, dst[c], src[0][c]); break; case TGSI_OPCODE_END: break; @@ -648,6 +528,7 @@ out_cleanup: static void nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) { +#if TX_FRAGPROG == 0 struct tgsi_parse_context pc; tgsi_parse_init(&pc, p->pipe.tokens); @@ -665,6 +546,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) p->insns[7] = 0x00020781; } else if (pc.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) { +#endif int i; if (nv50_program_tx(p) == FALSE) @@ -673,6 +555,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) for (i = 0; i < p->insns_nr; i++) NOUVEAU_ERR("%d 0x%08x\n", i, p->insns[i]); +#if TX_FRAGPROG == 0 } else { NOUVEAU_ERR("invalid TGSI processor\n"); tgsi_parse_free(&pc); @@ -680,6 +563,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) } tgsi_parse_free(&pc); +#endif p->translated = TRUE; } @@ -758,11 +642,8 @@ nv50_fragprog_validate(struct nv50_context *nv50) assert(0); } - if (!p->buffer) - p->buffer = ws->buffer_create(ws, 0x100, 0, p->insns_nr * 4); - map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); - memcpy(map, p->insns, p->insns_nr * 4); - ws->buffer_unmap(ws, p->buffer); + nv50_program_validate_data(nv50, p); + nv50_program_validate_code(nv50, p); so = so_new(3, 2); so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2); -- cgit v1.2.3 From 8ec6415e9fcf876c67bc1624f3eb7dd7624b7791 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 3 Jun 2008 12:37:29 +1000 Subject: nv50: start using interpreter for fragprog too, not hardcoded passthrough --- src/gallium/drivers/nv50/nv50_program.c | 96 ++++++++++++++++++++++++++++----- src/gallium/drivers/nv50/nv50_state.c | 2 + src/gallium/drivers/nv50/nv50_state.h | 8 ++- 3 files changed, 92 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index aa848faa49..9d89f6d060 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -11,7 +11,7 @@ #include "nv50_state.h" #define NV50_SU_MAX_TEMP 64 -#define TX_FRAGPROG 0 +#define TX_FRAGPROG 1 struct nv50_reg { enum { @@ -52,15 +52,23 @@ alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg) { int i; - if (reg->type != P_TEMP || reg->hw >= 0) + if (reg->type != P_TEMP) return; + if (reg->hw >= 0) { + /*XXX: do this here too to catch FP temp-as-attr usage.. + * not clean, but works */ + if (pc->p->cfg.high_temp < (reg->hw + 1)) + pc->p->cfg.high_temp = reg->hw + 1; + return; + } + for (i = 0; i < NV50_SU_MAX_TEMP; i++) { if (!(pc->r_temp[i])) { pc->r_temp[i] = reg; reg->hw = i; - if (pc->p->cfg.vp.high_temp < (i + 1)) - pc->p->cfg.vp.high_temp = i + 1; + if (pc->p->cfg.high_temp < (i + 1)) + pc->p->cfg.high_temp = i + 1; return; } } @@ -236,6 +244,24 @@ set_immd(struct nv50_pc *pc, struct nv50_reg *imm, unsigned *inst) inst[1] |= (val >> 6) << 2; } +static void +emit_interp(struct nv50_pc *pc, struct nv50_reg *dst, + struct nv50_reg *src, struct nv50_reg *iv, boolean noperspective) +{ + unsigned inst[2] = { 0, 0 }; + + inst[0] |= 0x80000000; + set_dst(pc, dst, inst); + alloc_reg(pc, iv); + inst[0] |= (iv->hw << 9); + alloc_reg(pc, src); + inst[0] |= (src->hw << 16); + if (noperspective) + inst[0] |= (1 << 25); + + emit(pc, inst); +} + static void emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { @@ -409,20 +435,57 @@ nv50_program_tx_prep(struct nv50_pc *pc) NOUVEAU_ERR("%d attrib regs\n", pc->attr_nr); if (pc->attr_nr) { + struct nv50_reg *iv = NULL, *tmp = NULL; int aid = 0; pc->attr = calloc(pc->attr_nr * 4, sizeof(struct nv50_reg)); if (!pc->attr) goto out_err; + if (pc->p->type == NV50_PROG_FRAGMENT) { + iv = alloc_temp(pc, NULL); + aid++; + } + for (i = 0; i < pc->attr_nr; i++) { + struct nv50_reg *a = &pc->attr[i*4]; + for (c = 0; c < 4; c++) { - pc->p->cfg.vp.attr[aid/32] |= (1 << (aid % 32)); - pc->attr[i*4+c].type = P_ATTR; - pc->attr[i*4+c].hw = aid++; - pc->attr[i*4+c].index = i; + if (pc->p->type == NV50_PROG_FRAGMENT) { + struct nv50_reg *at = + alloc_temp(pc, NULL); + pc->attr[i*4+c].type = at->type; + pc->attr[i*4+c].hw = at->hw; + pc->attr[i*4+c].index = at->index; + } else { + pc->p->cfg.vp.attr[aid/32] |= + (1 << (aid % 32)); + pc->attr[i*4+c].type = P_ATTR; + pc->attr[i*4+c].hw = aid++; + pc->attr[i*4+c].index = i; + } } + + if (pc->p->type != NV50_PROG_FRAGMENT) + continue; + + emit_interp(pc, iv, iv, iv, FALSE); + tmp = alloc_temp(pc, NULL); + { + unsigned inst[2] = { 0, 0 }; + inst[0] = 0x90000000; + inst[0] |= (tmp->hw << 2); + emit(pc, inst); + } + emit_interp(pc, &a[0], &a[0], tmp, TRUE); + emit_interp(pc, &a[1], &a[1], tmp, TRUE); + emit_interp(pc, &a[2], &a[2], tmp, TRUE); + emit_interp(pc, &a[3], &a[3], tmp, TRUE); + free_temp(pc, tmp); } + + if (iv) + free_temp(pc, iv); } NOUVEAU_ERR("%d result regs\n", pc->result_nr); @@ -435,7 +498,10 @@ nv50_program_tx_prep(struct nv50_pc *pc) for (i = 0; i < pc->result_nr; i++) { for (c = 0; c < 4; c++) { - pc->result[i*4+c].type = P_RESULT; + if (pc->p->type == NV50_PROG_FRAGMENT) + pc->result[i*4+c].type = P_TEMP; + else + pc->result[i*4+c].type = P_RESULT; pc->result[i*4+c].hw = rid++; pc->result[i*4+c].index = i; } @@ -492,7 +558,7 @@ nv50_program_tx(struct nv50_program *p) if (!pc) return FALSE; pc->p = p; - pc->p->cfg.vp.high_temp = 4; + pc->p->cfg.high_temp = 4; ret = nv50_program_tx_prep(pc); if (ret == FALSE) @@ -551,6 +617,8 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) if (nv50_program_tx(p) == FALSE) assert(0); + /* *not* sufficient, it's fine if last inst is long and + * NOT immd - otherwise it's fucked fucked fucked */ p->insns[p->insns_nr - 1] |= 0x00000001; for (i = 0; i < p->insns_nr; i++) @@ -620,7 +688,7 @@ nv50_vertprog_validate(struct nv50_context *nv50) so_data (so, p->cfg.vp.attr[1]); so_method(so, tesla, 0x16ac, 2); so_data (so, 8); - so_data (so, p->cfg.vp.high_temp); + so_data (so, p->cfg.high_temp); so_method(so, tesla, 0x140c, 1); so_data (so, 0); /* program start offset */ so_emit(nv50->screen->nvws, so); @@ -645,12 +713,16 @@ nv50_fragprog_validate(struct nv50_context *nv50) nv50_program_validate_data(nv50, p); nv50_program_validate_code(nv50, p); - so = so_new(3, 2); + so = so_new(7, 2); so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2); so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_method(so, tesla, 0x198c, 1); + so_data (so, p->cfg.high_temp); + so_method(so, tesla, 0x1414, 1); + so_data (so, 0); /* program start offset */ so_emit(nv50->screen->nvws, so); so_ref(NULL, &so); } diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index ba3d04cede..48d09c296b 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -331,6 +331,7 @@ nv50_vp_state_create(struct pipe_context *pipe, struct nv50_program *p = CALLOC_STRUCT(nv50_program); p->pipe = *cso; + p->type = NV50_PROG_VERTEX; tgsi_scan_shader(p->pipe.tokens, &p->info); return (void *)p; } @@ -360,6 +361,7 @@ nv50_fp_state_create(struct pipe_context *pipe, struct nv50_program *p = CALLOC_STRUCT(nv50_program); p->pipe = *cso; + p->type = NV50_PROG_FRAGMENT; tgsi_scan_shader(p->pipe.tokens, &p->info); return (void *)p; } diff --git a/src/gallium/drivers/nv50/nv50_state.h b/src/gallium/drivers/nv50/nv50_state.h index 9e3876871b..dd352b6585 100644 --- a/src/gallium/drivers/nv50/nv50_state.h +++ b/src/gallium/drivers/nv50/nv50_state.h @@ -15,6 +15,10 @@ struct nv50_program { struct tgsi_shader_info info; boolean translated; + enum { + NV50_PROG_VERTEX, + NV50_PROG_FRAGMENT + } type; unsigned *insns; unsigned insns_nr; @@ -25,9 +29,9 @@ struct nv50_program { struct nouveau_resource *data; - union { + struct { + unsigned high_temp; struct { - unsigned high_temp; unsigned attr[2]; } vp; } cfg; -- cgit v1.2.3 From e55964099b0d47dea80920765daac09b9e2a61a7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 3 Jun 2008 12:38:12 +1000 Subject: nv50: remove hardcoded fp stuff --- src/gallium/drivers/nv50/nv50_program.c | 45 ++++++--------------------------- 1 file changed, 8 insertions(+), 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 9d89f6d060..df29069e62 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -11,7 +11,6 @@ #include "nv50_state.h" #define NV50_SU_MAX_TEMP 64 -#define TX_FRAGPROG 1 struct nv50_reg { enum { @@ -594,44 +593,16 @@ out_cleanup: static void nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) { -#if TX_FRAGPROG == 0 - struct tgsi_parse_context pc; - - tgsi_parse_init(&pc, p->pipe.tokens); - - if (pc.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { - p->insns_nr = 8; - p->insns = malloc(p->insns_nr * sizeof(unsigned)); - p->insns[0] = 0x80000000; - p->insns[1] = 0x9000000c; - p->insns[2] = 0x82010600; - p->insns[3] = 0x82020604; - p->insns[4] = 0x80030609; - p->insns[5] = 0x00020780; - p->insns[6] = 0x8004060d; - p->insns[7] = 0x00020781; - } else - if (pc.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) { -#endif - int i; - - if (nv50_program_tx(p) == FALSE) - assert(0); - /* *not* sufficient, it's fine if last inst is long and - * NOT immd - otherwise it's fucked fucked fucked */ - p->insns[p->insns_nr - 1] |= 0x00000001; + int i; - for (i = 0; i < p->insns_nr; i++) - NOUVEAU_ERR("%d 0x%08x\n", i, p->insns[i]); -#if TX_FRAGPROG == 0 - } else { - NOUVEAU_ERR("invalid TGSI processor\n"); - tgsi_parse_free(&pc); - return; - } + if (nv50_program_tx(p) == FALSE) + assert(0); + /* *not* sufficient, it's fine if last inst is long and + * NOT immd - otherwise it's fucked fucked fucked */ + p->insns[p->insns_nr - 1] |= 0x00000001; - tgsi_parse_free(&pc); -#endif + for (i = 0; i < p->insns_nr; i++) + NOUVEAU_ERR("%d 0x%08x\n", i, p->insns[i]); p->translated = TRUE; } -- cgit v1.2.3 From 2a1fb44d75364f2492a1ae5d232218a92b8ca807 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 4 Jun 2008 21:23:14 +1000 Subject: nv50: checkpoint: shader code now exceeds caps of "old" code --- src/gallium/drivers/nv50/nv50_program.c | 279 +++++++++++++++++++++++++++++++- 1 file changed, 272 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index df29069e62..bc0b7b2827 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -44,6 +44,9 @@ struct nv50_pc { struct nv50_reg *immd; float *immd_buf; int immd_nr; + + struct nv50_reg *temp_temp[4]; + unsigned temp_temp_nr; }; static void @@ -108,6 +111,26 @@ free_temp(struct nv50_pc *pc, struct nv50_reg *r) } } +static struct nv50_reg * +temp_temp(struct nv50_pc *pc) +{ + if (pc->temp_temp_nr >= 4) + assert(0); + + pc->temp_temp[pc->temp_temp_nr] = alloc_temp(pc, NULL); + return pc->temp_temp[pc->temp_temp_nr++]; +} + +static void +kill_temp_temp(struct nv50_pc *pc) +{ + int i; + + for (i = 0; i < pc->temp_temp_nr; i++) + free_temp(pc, pc->temp_temp[i]); + pc->temp_temp_nr = 0; +} + static struct nv50_reg * tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) { @@ -168,6 +191,8 @@ emit(struct nv50_pc *pc, unsigned *inst) p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned)); } + + kill_temp_temp(pc); } static INLINE void set_long(struct nv50_pc *, unsigned *); @@ -261,11 +286,24 @@ emit_interp(struct nv50_pc *pc, struct nv50_reg *dst, emit(pc, inst); } +static void +set_cseg(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) +{ + set_long(pc, inst); + if (src->type == P_IMMD) { + inst[1] |= (NV50_CB_PMISC << 22); + } else { + if (pc->p->type == NV50_PROG_VERTEX) + inst[1] |= (NV50_CB_PVP << 22); + else + inst[1] |= (NV50_CB_PFP << 22); + } +} + static void emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { unsigned inst[2] = { 0, 0 }; - int i; inst[0] |= 0x10000000; @@ -280,10 +318,7 @@ emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) } else if (src->type == P_IMMD || src->type == P_CONST) { set_long(pc, inst); - if (src->type == P_IMMD) - inst[1] |= (NV50_CB_PMISC << 22); - else - inst[1] |= (NV50_CB_PVP << 22); + set_cseg(pc, src, inst); inst[0] |= (src->hw << 9); inst[1] |= 0x20000000; /* src0 const? */ } else { @@ -308,11 +343,177 @@ emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) emit(pc, inst); } +static boolean +check_swap_src_0_1(struct nv50_pc *pc, + struct nv50_reg **s0, struct nv50_reg **s1) +{ + struct nv50_reg *src0 = *s0, *src1 = *s1; + + if (src0->type == P_CONST) { + if (src1->type != P_CONST) { + *s0 = src1; + *s1 = src0; + return TRUE; + } + } else + if (src1->type == P_ATTR) { + if (src0->type != P_ATTR) { + *s0 = src1; + *s1 = src0; + return TRUE; + } + } + + return FALSE; +} + +static void +set_src_0(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) +{ + if (src->type == P_ATTR) { + set_long(pc, inst); + inst[1] |= 0x00200000; + } else + if (src->type == P_CONST || src->type == P_IMMD) { + struct nv50_reg *temp = temp_temp(pc); + + emit_mov(pc, temp, src); + src = temp; + } + + alloc_reg(pc, src); + inst[0] |= (src->hw << 9); +} + +static void +set_src_1(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) +{ + if (src->type == P_ATTR) { + struct nv50_reg *temp = temp_temp(pc); + + emit_mov(pc, temp, src); + src = temp; + } else + if (src->type == P_CONST || src->type == P_IMMD) { + set_cseg(pc, src, inst); + inst[0] |= 0x00800000; + } + + alloc_reg(pc, src); + inst[0] |= (src->hw << 16); +} + +static void +set_src_2(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) +{ + set_long(pc, inst); + + if (src->type == P_ATTR) { + struct nv50_reg *temp = temp_temp(pc); + + emit_mov(pc, temp, src); + src = temp; + } else + if (src->type == P_CONST || src->type == P_IMMD) { + set_cseg(pc, src, inst); + inst[0] |= 0x01000000; + } + + alloc_reg(pc, src); + inst[1] |= (src->hw << 14); +} + +static void +emit_mul(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, + struct nv50_reg *src1) +{ + unsigned inst[2] = { 0, 0 }; + + inst[0] |= 0xc0000000; + + check_swap_src_0_1(pc, &src0, &src1); + set_dst(pc, dst, inst); + set_src_0(pc, src0, inst); + set_src_1(pc, src1, inst); + + emit(pc, inst); +} + +static void +emit_add(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, + struct nv50_reg *src1) +{ + unsigned inst[2] = { 0, 0 }; + + inst[0] |= 0xb0000000; + + check_swap_src_0_1(pc, &src0, &src1); + set_dst(pc, dst, inst); + set_src_0(pc, src0, inst); + set_src_2(pc, src1, inst); + + emit(pc, inst); +} + +static void +emit_sub(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, + struct nv50_reg *src1) +{ + unsigned inst[2] = { 0, 0 }; + + inst[0] |= 0xb0000000; + + set_long(pc, inst); + if (check_swap_src_0_1(pc, &src0, &src1)) + inst[1] |= 0x04000000; + else + inst[1] |= 0x08000000; + + set_dst(pc, dst, inst); + set_src_0(pc, src0, inst); + set_src_2(pc, src1, inst); + + emit(pc, inst); +} + +static void +emit_mad(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, + struct nv50_reg *src1, struct nv50_reg *src2) +{ + unsigned inst[2] = { 0, 0 }; + + inst[0] |= 0xe0000000; + + check_swap_src_0_1(pc, &src0, &src1); + set_dst(pc, dst, inst); + set_src_0(pc, src0, inst); + set_src_1(pc, src1, inst); + set_src_2(pc, src2, inst); + + emit(pc, inst); +} + +static void +emit_flop(struct nv50_pc *pc, unsigned sub, + struct nv50_reg *dst, struct nv50_reg *src) +{ + unsigned inst[2] = { 0, 0 }; + + set_long(pc, inst); + inst[0] |= 0x90000000; + inst[1] |= (sub << 29); + + set_dst(pc, dst, inst); + set_src_0(pc, src, inst); + + emit(pc, inst); +} + static boolean nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) { const struct tgsi_full_instruction *inst = &tok->FullInstruction; - struct nv50_reg *dst[4], *src[3][4]; + struct nv50_reg *dst[4], *src[3][4], *temp; unsigned mask; int i, c; @@ -333,10 +534,69 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ADD: + for (c = 0; c < 4; c++) + emit_add(pc, dst[c], src[0][c], src[1][c]); + break; + case TGSI_OPCODE_COS: + for (c = 0; c < 4; c++) + emit_flop(pc, 5, dst[c], src[0][c]); + break; + case TGSI_OPCODE_DP3: + temp = alloc_temp(pc, NULL); + emit_mul(pc, temp, src[0][0], src[1][0]); + emit_mad(pc, temp, src[0][1], src[1][1], temp); + emit_mad(pc, temp, src[0][2], src[1][2], temp); + for (c = 0; c < 4; c++) + emit_mov(pc, dst[c], temp); + free_temp(pc, temp); + break; + case TGSI_OPCODE_DP4: + temp = alloc_temp(pc, NULL); + emit_mul(pc, temp, src[0][0], src[1][0]); + emit_mad(pc, temp, src[0][1], src[1][1], temp); + emit_mad(pc, temp, src[0][2], src[1][2], temp); + emit_mad(pc, temp, src[0][3], src[1][3], temp); + for (c = 0; c < 4; c++) + emit_mov(pc, dst[c], temp); + free_temp(pc, temp); + break; + case TGSI_OPCODE_EX2: + for (c = 0; c < 4; c++) + emit_flop(pc, 6, dst[c], src[0][c]); + break; + case TGSI_OPCODE_LG2: + for (c = 0; c < 4; c++) + emit_flop(pc, 3, dst[c], src[0][c]); + break; + case TGSI_OPCODE_MAD: + for (c = 0; c < 4; c++) + emit_mad(pc, dst[c], src[0][c], src[1][c], src[2][c]); + break; case TGSI_OPCODE_MOV: for (c = 0; c < 4; c++) emit_mov(pc, dst[c], src[0][c]); break; + case TGSI_OPCODE_MUL: + for (c = 0; c < 4; c++) + emit_mul(pc, dst[c], src[0][c], src[1][c]); + break; + case TGSI_OPCODE_RCP: + for (c = 0; c < 4; c++) + emit_flop(pc, 0, dst[c], src[0][c]); + break; + case TGSI_OPCODE_RSQ: + for (c = 0; c < 4; c++) + emit_flop(pc, 2, dst[c], src[0][c]); + break; + case TGSI_OPCODE_SIN: + for (c = 0; c < 4; c++) + emit_flop(pc, 4, dst[c], src[0][c]); + break; + case TGSI_OPCODE_SUB: + for (c = 0; c < 4; c++) + emit_sub(pc, dst[c], src[0][c], src[1][c]); + break; case TGSI_OPCODE_END: break; default: @@ -601,8 +861,13 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) * NOT immd - otherwise it's fucked fucked fucked */ p->insns[p->insns_nr - 1] |= 0x00000001; + if (p->type == NV50_PROG_VERTEX) { + for (i = 0; i < p->insns_nr; i++) + NOUVEAU_ERR("VP0x%08x\n", p->insns[i]); + } else { for (i = 0; i < p->insns_nr; i++) - NOUVEAU_ERR("%d 0x%08x\n", i, p->insns[i]); + NOUVEAU_ERR("FP0x%08x\n", p->insns[i]); + } p->translated = TRUE; } -- cgit v1.2.3 From 52a69196c1680ff16d1ad1fc88e5869bc6055d00 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 4 Jun 2008 21:45:32 +1000 Subject: nv50: some fixes + MIN/MAX --- src/gallium/drivers/nv50/nv50_program.c | 48 ++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index bc0b7b2827..afc911cd26 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -45,7 +45,7 @@ struct nv50_pc { float *immd_buf; int immd_nr; - struct nv50_reg *temp_temp[4]; + struct nv50_reg *temp_temp[8]; unsigned temp_temp_nr; }; @@ -114,7 +114,7 @@ free_temp(struct nv50_pc *pc, struct nv50_reg *r) static struct nv50_reg * temp_temp(struct nv50_pc *pc) { - if (pc->temp_temp_nr >= 4) + if (pc->temp_temp_nr >= 8) assert(0); pc->temp_temp[pc->temp_temp_nr] = alloc_temp(pc, NULL); @@ -191,8 +191,6 @@ emit(struct nv50_pc *pc, unsigned *inst) p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned)); } - - kill_temp_temp(pc); } static INLINE void set_long(struct nv50_pc *, unsigned *); @@ -440,8 +438,8 @@ emit_mul(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, } static void -emit_add(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, - struct nv50_reg *src1) +emit_add(struct nv50_pc *pc, struct nv50_reg *dst, + struct nv50_reg *src0, struct nv50_reg *src1) { unsigned inst[2] = { 0, 0 }; @@ -450,7 +448,28 @@ emit_add(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, check_swap_src_0_1(pc, &src0, &src1); set_dst(pc, dst, inst); set_src_0(pc, src0, inst); - set_src_2(pc, src1, inst); + if (is_long(inst)) + set_src_2(pc, src1, inst); + else + set_src_1(pc, src1, inst); + + emit(pc, inst); +} + +static void +emit_minmax(struct nv50_pc *pc, unsigned sub, struct nv50_reg *dst, + struct nv50_reg *src0, struct nv50_reg *src1) +{ + unsigned inst[2] = { 0, 0 }; + + set_long(pc, inst); + inst[0] |= 0xb0000000; + inst[1] |= (sub << 29); + + check_swap_src_0_1(pc, &src0, &src1); + set_dst(pc, dst, inst); + set_src_0(pc, src0, inst); + set_src_1(pc, src1, inst); emit(pc, inst); } @@ -499,9 +518,11 @@ emit_flop(struct nv50_pc *pc, unsigned sub, { unsigned inst[2] = { 0, 0 }; - set_long(pc, inst); inst[0] |= 0x90000000; - inst[1] |= (sub << 29); + if (sub) { + set_long(pc, inst); + inst[1] |= (sub << 29); + } set_dst(pc, dst, inst); set_src_0(pc, src, inst); @@ -573,6 +594,14 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) for (c = 0; c < 4; c++) emit_mad(pc, dst[c], src[0][c], src[1][c], src[2][c]); break; + case TGSI_OPCODE_MAX: + for (c = 0; c < 4; c++) + emit_minmax(pc, 4, dst[c], src[0][c], src[1][c]); + break; + case TGSI_OPCODE_MIN: + for (c = 0; c < 4; c++) + emit_minmax(pc, 5, dst[c], src[0][c], src[1][c]); + break; case TGSI_OPCODE_MOV: for (c = 0; c < 4; c++) emit_mov(pc, dst[c], src[0][c]); @@ -604,6 +633,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) return FALSE; } + kill_temp_temp(pc); return TRUE; } -- cgit v1.2.3 From 7df7f7bb99441ed8e2fba2840e0459e72691f272 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 5 Jun 2008 18:39:00 +1000 Subject: nv50: big fuckup, fix it --- src/gallium/drivers/nv50/nv50_program.c | 75 ++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index afc911cd26..a293db6f72 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -556,20 +556,29 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ADD: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_add(pc, dst[c], src[0][c], src[1][c]); + } break; case TGSI_OPCODE_COS: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_flop(pc, 5, dst[c], src[0][c]); + } break; case TGSI_OPCODE_DP3: temp = alloc_temp(pc, NULL); emit_mul(pc, temp, src[0][0], src[1][0]); emit_mad(pc, temp, src[0][1], src[1][1], temp); emit_mad(pc, temp, src[0][2], src[1][2], temp); - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_mov(pc, dst[c], temp); + } free_temp(pc, temp); break; case TGSI_OPCODE_DP4: @@ -578,53 +587,89 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_mad(pc, temp, src[0][1], src[1][1], temp); emit_mad(pc, temp, src[0][2], src[1][2], temp); emit_mad(pc, temp, src[0][3], src[1][3], temp); - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_mov(pc, dst[c], temp); + } free_temp(pc, temp); break; case TGSI_OPCODE_EX2: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_flop(pc, 6, dst[c], src[0][c]); + } break; case TGSI_OPCODE_LG2: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_flop(pc, 3, dst[c], src[0][c]); + } break; case TGSI_OPCODE_MAD: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_mad(pc, dst[c], src[0][c], src[1][c], src[2][c]); + } break; case TGSI_OPCODE_MAX: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_minmax(pc, 4, dst[c], src[0][c], src[1][c]); + } break; case TGSI_OPCODE_MIN: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_minmax(pc, 5, dst[c], src[0][c], src[1][c]); + } break; case TGSI_OPCODE_MOV: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_mov(pc, dst[c], src[0][c]); + } break; case TGSI_OPCODE_MUL: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_mul(pc, dst[c], src[0][c], src[1][c]); + } break; case TGSI_OPCODE_RCP: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_flop(pc, 0, dst[c], src[0][c]); + } break; case TGSI_OPCODE_RSQ: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_flop(pc, 2, dst[c], src[0][c]); + } break; case TGSI_OPCODE_SIN: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_flop(pc, 4, dst[c], src[0][c]); + } break; case TGSI_OPCODE_SUB: - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; emit_sub(pc, dst[c], src[0][c], src[1][c]); + } break; case TGSI_OPCODE_END: break; -- cgit v1.2.3 From fbf4027dd9b279ec159906dcad134f71e34aaec8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 5 Jun 2008 18:52:16 +1000 Subject: nv50: fix EX2.. somehow --- src/gallium/drivers/nv50/nv50_program.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index a293db6f72..6d3d8ff302 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -595,11 +595,22 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) free_temp(pc, temp); break; case TGSI_OPCODE_EX2: + temp = alloc_temp(pc, NULL); for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_flop(pc, 6, dst[c], src[0][c]); + { + unsigned inst[2] = { 0, 0 }; + inst[0] |= 0xb0000000; + set_dst(pc, temp, inst); + set_src_0(pc, src[0][c], inst); + set_long(pc, inst); + inst[1] |= (6 << 29) | 0x00004000; + emit(pc, inst); + } + emit_flop(pc, 6, dst[c], temp); } + free_temp(pc, temp); break; case TGSI_OPCODE_LG2: for (c = 0; c < 4; c++) { -- cgit v1.2.3 From 21e18e2b74d71c93af06ef4c603ca371c4614237 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 5 Jun 2008 23:48:23 +1000 Subject: nv50: DPH, XPD, some TODOs --- src/gallium/drivers/nv50/nv50_program.c | 61 +++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 6d3d8ff302..91f24369f1 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -12,6 +12,25 @@ #define NV50_SU_MAX_TEMP 64 +/* ABS + * ARL + * DST - const(1.0) + * FLR + * FRC + * LIT + * POW + * SGE - cvt + * SLT - cvt + * SWZ + * + * MSB - Like MAD, but MUL+SUB + * - Fuck it off, introduce a way to negate args for ops that + * support it. + * + * Need ability to specifiy driver IMMD values, like nv40 constant() + * + * Look into inlining IMMD for ops other than MOV + */ struct nv50_reg { enum { P_TEMP, @@ -512,6 +531,25 @@ emit_mad(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, emit(pc, inst); } +static void +emit_msb(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, + struct nv50_reg *src1, struct nv50_reg *src2) +{ + unsigned inst[2] = { 0, 0 }; + + inst[0] |= 0xe0000000; + set_long(pc, inst); + inst[1] |= 0x08000000; /* src0 * src1 - src2 */ + + check_swap_src_0_1(pc, &src0, &src1); + set_dst(pc, dst, inst); + set_src_0(pc, src0, inst); + set_src_1(pc, src1, inst); + set_src_2(pc, src2, inst); + + emit(pc, inst); +} + static void emit_flop(struct nv50_pc *pc, unsigned sub, struct nv50_reg *dst, struct nv50_reg *src) @@ -594,6 +632,19 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } free_temp(pc, temp); break; + case TGSI_OPCODE_DPH: + temp = alloc_temp(pc, NULL); + emit_mul(pc, temp, src[0][0], src[1][0]); + emit_mad(pc, temp, src[0][1], src[1][1], temp); + emit_mad(pc, temp, src[0][2], src[1][2], temp); + emit_add(pc, temp, src[1][3], temp); + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; + emit_mov(pc, dst[c], temp); + } + free_temp(pc, temp); + break; case TGSI_OPCODE_EX2: temp = alloc_temp(pc, NULL); for (c = 0; c < 4; c++) { @@ -682,6 +733,16 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_sub(pc, dst[c], src[0][c], src[1][c]); } break; + case TGSI_OPCODE_XPD: + temp = alloc_temp(pc, NULL); + emit_mul(pc, temp, src[0][2], src[1][1]); + emit_msb(pc, dst[0], src[0][1], src[1][2], temp); + emit_mul(pc, temp, src[0][0], src[1][2]); + emit_msb(pc, dst[1], src[0][2], src[1][0], temp); + emit_mul(pc, temp, src[0][1], src[1][0]); + emit_msb(pc, dst[2], src[0][0], src[1][1], temp); + free_temp(pc, temp); + break; case TGSI_OPCODE_END: break; default: -- cgit v1.2.3 From d69f33423087fc054181c60724f4bcbe29195e08 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 6 Jun 2008 13:57:59 +1000 Subject: nv50: small cleanup --- src/gallium/drivers/nv50/nv50_program.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 91f24369f1..7295c2314c 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -568,6 +568,21 @@ emit_flop(struct nv50_pc *pc, unsigned sub, emit(pc, inst); } +static void +emit_preex2(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) +{ + unsigned inst[2] = { 0, 0 }; + + inst[0] |= 0xb0000000; + + set_dst(pc, dst, inst); + set_src_0(pc, src, inst); + set_long(pc, inst); + inst[1] |= (6 << 29) | 0x00004000; + + emit(pc, inst); +} + static boolean nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) { @@ -650,15 +665,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - { - unsigned inst[2] = { 0, 0 }; - inst[0] |= 0xb0000000; - set_dst(pc, temp, inst); - set_src_0(pc, src[0][c], inst); - set_long(pc, inst); - inst[1] |= (6 << 29) | 0x00004000; - emit(pc, inst); - } + emit_preex2(pc, temp, src[0][c]); emit_flop(pc, 6, dst[c], temp); } free_temp(pc, temp); @@ -1081,11 +1088,9 @@ nv50_vertprog_validate(struct nv50_context *nv50) void nv50_fragprog_validate(struct nv50_context *nv50) { - struct pipe_winsys *ws = nv50->pipe.winsys; struct nouveau_grobj *tesla = nv50->screen->tesla; struct nv50_program *p = nv50->fragprog; struct nouveau_stateobj *so; - void *map; if (!p->translated) { nv50_program_validate(nv50, p); -- cgit v1.2.3 From bdd31c20abb27665ca701a5a46e29d4cfa71f679 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 11:41:47 +1000 Subject: nv50: SGE/SLT --- src/gallium/drivers/nv50/nv50_program.c | 82 ++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 7295c2314c..fa16c7522e 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -19,8 +19,6 @@ * FRC * LIT * POW - * SGE - cvt - * SLT - cvt * SWZ * * MSB - Like MAD, but MUL+SUB @@ -201,15 +199,15 @@ emit(struct nv50_pc *pc, unsigned *inst) { struct nv50_program *p = pc->p; - if (inst[0] & 1) { - p->insns_nr += 2; - p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); - memcpy(p->insns + (p->insns_nr - 2), inst, sizeof(unsigned)*2); - } else { - p->insns_nr += 1; - p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); - memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned)); - } + if (inst[0] & 1) { + p->insns_nr += 2; + p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); + memcpy(p->insns + (p->insns_nr - 2), inst, sizeof(unsigned)*2); + } else { + p->insns_nr += 1; + p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); + memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned)); + } } static INLINE void set_long(struct nv50_pc *, unsigned *); @@ -582,6 +580,54 @@ emit_preex2(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) emit(pc, inst); } +/*XXX: inaccurate results.. why? */ +#define ALLOW_SET_SWAP 0 + +static void +emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst, + struct nv50_reg *src0, struct nv50_reg *src1) +{ + unsigned inst[2] = { 0, 0 }; +#if ALLOW_SET_SWAP + unsigned inv_cop[8] = { 0, 6, 2, 4, 3, 5, 1, 7 }; +#endif + struct nv50_reg *rdst; + +#if ALLOW_SET_SWAP + assert(c_op <= 7); + if (check_swap_src_0_1(pc, &src0, &src1)) + c_op = inv_cop[c_op]; +#endif + + rdst = dst; + if (dst->type != P_TEMP) + dst = alloc_temp(pc, NULL); + + /* set.u32 */ + set_long(pc, inst); + inst[0] |= 0xb0000000; + inst[1] |= (3 << 29); + inst[1] |= (c_op << 14); + /*XXX: breaks things, .u32 by default? + * decuda will disasm as .u16 and use .lo/.hi regs, but this + * doesn't seem to match what the hw actually does. + inst[1] |= 0x04000000; << breaks things.. .u32 by default? + */ + set_dst(pc, dst, inst); + set_src_0(pc, src0, inst); + set_src_1(pc, src1, inst); + emit(pc, inst); + + /* cvt.f32.u32 */ + inst[0] = 0xa0000001; + inst[1] = 0x64014780; + set_dst(pc, rdst, inst); + set_src_0(pc, dst, inst); + emit(pc, inst); + + if (dst != rdst) + free_temp(pc, dst); +} static boolean nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) @@ -726,6 +772,13 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_flop(pc, 2, dst[c], src[0][c]); } break; + case TGSI_OPCODE_SGE: + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; + emit_set(pc, 6, dst[c], src[0][c], src[1][c]); + } + break; case TGSI_OPCODE_SIN: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) @@ -733,6 +786,13 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_flop(pc, 4, dst[c], src[0][c]); } break; + case TGSI_OPCODE_SLT: + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; + emit_set(pc, 1, dst[c], src[0][c], src[1][c]); + } + break; case TGSI_OPCODE_SUB: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) -- cgit v1.2.3 From b4f7463585071236d633e4c857dbbdf67b03dc94 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 12:55:06 +1000 Subject: nv50: FLR/FRC --- src/gallium/drivers/nv50/nv50_program.c | 37 +++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index fa16c7522e..448062e767 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -15,8 +15,6 @@ /* ABS * ARL * DST - const(1.0) - * FLR - * FRC * LIT * POW * SWZ @@ -629,6 +627,24 @@ emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst, free_temp(pc, dst); } +static void +emit_flr(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) +{ + unsigned inst[2] = { 0, 0 }; + + set_long(pc, inst); + inst[0] = 0xa0000000; /* cvt */ + inst[1] |= (6 << 29); /* cvt */ + inst[1] |= 0x08000000; /* integer mode */ + inst[1] |= 0x04000000; /* 32 bit */ + inst[1] |= ((0x1 << 3)) << 14; /* .rn */ + inst[1] |= (1 << 14); /* src .f32 */ + set_dst(pc, dst, inst); + set_src_0(pc, src, inst); + + emit(pc, inst); +} + static boolean nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) { @@ -716,6 +732,23 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } free_temp(pc, temp); break; + case TGSI_OPCODE_FLR: + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; + emit_flr(pc, dst[c], src[0][c]); + } + break; + case TGSI_OPCODE_FRC: + temp = alloc_temp(pc, NULL); + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; + emit_flr(pc, temp, src[0][c]); + emit_sub(pc, dst[c], src[0][c], temp); + } + free_temp(pc, temp); + break; case TGSI_OPCODE_LG2: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) -- cgit v1.2.3 From 68091b0c89310c309b668c9d6d80640dc6040ab7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 13:01:58 +1000 Subject: nv50: ABS --- src/gallium/drivers/nv50/nv50_program.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 448062e767..7c2177d42d 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -12,8 +12,7 @@ #define NV50_SU_MAX_TEMP 64 -/* ABS - * ARL +/* ARL * DST - const(1.0) * LIT * POW @@ -670,6 +669,21 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ABS: + for (c = 0; c < 4; c++) { + unsigned inst[2] = { 0, 0 }; + + set_long(pc, inst); + inst[0] = 0xa0000000; /* cvt */ + inst[1] |= (6 << 29); /* cvt */ + inst[1] |= 0x04000000; /* 32 bit */ + inst[1] |= (1 << 14); /* src .f32 */ + inst[1] |= ((1 << 6) << 14); /* .abs */ + set_dst(pc, dst[c], inst); + set_src_0(pc, src[0][c], inst); + emit(pc, inst); + } + break; case TGSI_OPCODE_ADD: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) -- cgit v1.2.3 From 33e4d30d50344be26398a51365bea1be37487403 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 14:10:48 +1000 Subject: nv50: DST --- src/gallium/drivers/nv50/nv50_program.c | 61 ++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 7c2177d42d..49a731842f 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -13,18 +13,18 @@ #define NV50_SU_MAX_TEMP 64 /* ARL - * DST - const(1.0) - * LIT + * LIT - other buggery * POW - * SWZ + * SWZ - negation ARGH + * SAT * * MSB - Like MAD, but MUL+SUB * - Fuck it off, introduce a way to negate args for ops that * support it. * - * Need ability to specifiy driver IMMD values, like nv40 constant() - * * Look into inlining IMMD for ops other than MOV + * - Maybe even relax restrictions a bit, can't do P_RESULT + P_IMMD, + * but can emit to P_TEMP first - then MOV later. NVIDIA does this */ struct nv50_reg { enum { @@ -145,6 +145,32 @@ kill_temp_temp(struct nv50_pc *pc) pc->temp_temp_nr = 0; } +static int +ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w) +{ + pc->immd_buf = realloc(pc->immd_buf, (pc->immd_nr + 1) * 4 * + sizeof(float)); + pc->immd_buf[(pc->immd_nr * 4) + 0] = x; + pc->immd_buf[(pc->immd_nr * 4) + 1] = x; + pc->immd_buf[(pc->immd_nr * 4) + 2] = x; + pc->immd_buf[(pc->immd_nr * 4) + 3] = x; + + return pc->immd_nr++; +} + +static struct nv50_reg * +alloc_immd(struct nv50_pc *pc, float f) +{ + struct nv50_reg *r = CALLOC_STRUCT(nv50_reg); + unsigned hw; + + hw = ctor_immd(pc, f, 0, 0, 0); + r->type = P_IMMD; + r->hw = hw; + r->index = -1; + return r; +} + static struct nv50_reg * tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) { @@ -736,6 +762,16 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } free_temp(pc, temp); break; + case TGSI_OPCODE_DST: + { + struct nv50_reg *one = alloc_immd(pc, 1.0); + emit_mov(pc, dst[0], one); + emit_mul(pc, dst[1], src[0][1], src[1][1]); + emit_mov(pc, dst[2], src[0][2]); + emit_mov(pc, dst[3], src[1][3]); + FREE(one); + } + break; case TGSI_OPCODE_EX2: temp = alloc_temp(pc, NULL); for (c = 0; c < 4; c++) { @@ -886,17 +922,10 @@ nv50_program_tx_prep(struct nv50_pc *pc) const struct tgsi_full_immediate *imm = &p.FullToken.FullImmediate; - pc->immd_nr++; - pc->immd_buf = realloc(pc->immd_buf, 4 * pc->immd_nr * - sizeof(float)); - pc->immd_buf[4 * (pc->immd_nr - 1) + 0] = - imm->u.ImmediateFloat32[0].Float; - pc->immd_buf[4 * (pc->immd_nr - 1) + 1] = - imm->u.ImmediateFloat32[1].Float; - pc->immd_buf[4 * (pc->immd_nr - 1) + 2] = - imm->u.ImmediateFloat32[2].Float; - pc->immd_buf[4 * (pc->immd_nr - 1) + 3] = - imm->u.ImmediateFloat32[3].Float; + ctor_immd(pc, 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_DECLARATION: -- cgit v1.2.3 From 34abb858e2aaef2c1a066a7cdb3e0376d6c9f6bd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 15:21:05 +1000 Subject: nv50: handle 0/1 SWZ --- src/gallium/drivers/nv50/nv50_program.c | 56 +++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 49a731842f..cad1d9d679 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -15,7 +15,6 @@ /* ARL * LIT - other buggery * POW - * SWZ - negation ARGH * SAT * * MSB - Like MAD, but MUL+SUB @@ -189,32 +188,55 @@ tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) } static struct nv50_reg * -tgsi_src(struct nv50_pc *pc, int c, const struct tgsi_full_src_register *src) +tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src) { - /* Handle swizzling */ + struct nv50_reg *r = NULL; + unsigned c; + + c = tgsi_util_get_full_src_register_extswizzle(src, chan); switch (c) { - case 0: c = src->SrcRegister.SwizzleX; break; - case 1: c = src->SrcRegister.SwizzleY; break; - case 2: c = src->SrcRegister.SwizzleZ; break; - case 3: c = src->SrcRegister.SwizzleW; break; + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + switch (src->SrcRegister.File) { + case TGSI_FILE_INPUT: + r = &pc->attr[src->SrcRegister.Index * 4 + c]; + break; + case TGSI_FILE_TEMPORARY: + r = &pc->temp[src->SrcRegister.Index * 4 + c]; + break; + case TGSI_FILE_CONSTANT: + r = &pc->param[src->SrcRegister.Index * 4 + c]; + break; + case TGSI_FILE_IMMEDIATE: + r = &pc->immd[src->SrcRegister.Index * 4 + c]; + break; + default: + assert(0); + break; + } + break; + case TGSI_EXTSWIZZLE_ZERO: + r = alloc_immd(pc, 0.0); + break; + case TGSI_EXTSWIZZLE_ONE: + r = alloc_immd(pc, 1.0); + break; default: assert(0); + break; } - switch (src->SrcRegister.File) { - case TGSI_FILE_INPUT: - return &pc->attr[src->SrcRegister.Index * 4 + c]; - case TGSI_FILE_TEMPORARY: - return &pc->temp[src->SrcRegister.Index * 4 + c]; - case TGSI_FILE_CONSTANT: - return &pc->param[src->SrcRegister.Index * 4 + c]; - case TGSI_FILE_IMMEDIATE: - return &pc->immd[src->SrcRegister.Index * 4 + c]; + switch (tgsi_util_get_full_src_register_sign_mode(src, chan)) { + case TGSI_UTIL_SIGN_KEEP: + break; default: + assert(0); break; } - return NULL; + return r; } static void -- cgit v1.2.3 From 688064236ba8b5997014493eb6c6e3fe0739813e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 16:01:06 +1000 Subject: nv50: fixes + untested _SAT modifier --- src/gallium/drivers/nv50/nv50_program.c | 36 ++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index cad1d9d679..9fcd7c36c6 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -15,7 +15,6 @@ /* ARL * LIT - other buggery * POW - * SAT * * MSB - Like MAD, but MUL+SUB * - Fuck it off, introduce a way to negate args for ops that @@ -679,8 +678,8 @@ emit_flr(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { unsigned inst[2] = { 0, 0 }; - set_long(pc, inst); inst[0] = 0xa0000000; /* cvt */ + set_long(pc, inst); inst[1] |= (6 << 29); /* cvt */ inst[1] |= 0x08000000; /* integer mode */ inst[1] |= 0x04000000; /* 32 bit */ @@ -696,13 +695,14 @@ static boolean nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) { const struct tgsi_full_instruction *inst = &tok->FullInstruction; - struct nv50_reg *dst[4], *src[3][4], *temp; - unsigned mask; + struct nv50_reg *rdst[4], *dst[4], *src[3][4], *temp; + unsigned mask, sat; int i, c; NOUVEAU_ERR("insn %p\n", tok); mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + sat = inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE; for (c = 0; c < 4; c++) { if (mask & (1 << c)) @@ -716,13 +716,20 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) src[i][c] = tgsi_src(pc, c, &inst->FullSrcRegisters[i]); } + if (sat) { + for (c = 0; c < 4; c++) { + rdst[c] = dst[c]; + dst[c] = temp_temp(pc); + } + } + switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ABS: for (c = 0; c < 4; c++) { unsigned inst[2] = { 0, 0 }; - set_long(pc, inst); inst[0] = 0xa0000000; /* cvt */ + set_long(pc, inst); inst[1] |= (6 << 29); /* cvt */ inst[1] |= 0x04000000; /* 32 bit */ inst[1] |= (1 << 14); /* src .f32 */ @@ -922,6 +929,25 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) return FALSE; } + if (sat) { + for (c = 0; c < 4; c++) { + unsigned inst[2] = { 0, 0 }; + + if (!(mask & (1 << c))) + continue; + + inst[0] = 0xa0000000; /* cvt */ + set_long(pc, inst); + inst[1] |= (6 << 29); /* cvt */ + inst[1] |= 0x04000000; /* 32 bit */ + inst[1] |= (1 << 14); /* src .f32 */ + inst[1] |= ((1 << 5) << 14); /* .sat */ + set_dst(pc, rdst[c], inst); + set_src_0(pc, dst[c], inst); + emit(pc, inst); + } + } + kill_temp_temp(pc); return TRUE; } -- cgit v1.2.3 From ea4b09cbcbd9db82648ab30f18c0f46a66ab9f69 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 16:08:36 +1000 Subject: nv50: POW! --- src/gallium/drivers/nv50/nv50_program.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 9fcd7c36c6..79893a9ad4 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -14,15 +14,17 @@ /* ARL * LIT - other buggery - * POW * * MSB - Like MAD, but MUL+SUB * - Fuck it off, introduce a way to negate args for ops that * support it. * - * Look into inlining IMMD for ops other than MOV + * Look into inlining IMMD for ops other than MOV (make it general?) * - Maybe even relax restrictions a bit, can't do P_RESULT + P_IMMD, * but can emit to P_TEMP first - then MOV later. NVIDIA does this + * + * Verify half-insns work where expected - and force disable them where they + * don't work - MUL has it forcibly disabled atm as it fixes POW.. */ struct nv50_reg { enum { @@ -489,6 +491,7 @@ emit_mul(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, unsigned inst[2] = { 0, 0 }; inst[0] |= 0xc0000000; + set_long(pc, inst); check_swap_src_0_1(pc, &src0, &src1); set_dst(pc, dst, inst); @@ -870,6 +873,19 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_mul(pc, dst[c], src[0][c], src[1][c]); } break; + case TGSI_OPCODE_POW: + temp = alloc_temp(pc, NULL); + emit_flop(pc, 3, temp, src[0][0]); + emit_mul(pc, temp, temp, src[1][0]); + emit_preex2(pc, temp, temp); + emit_flop(pc, 6, temp, temp); + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; + emit_mov(pc, dst[c], temp); + } + free_temp(pc, temp); + break; case TGSI_OPCODE_RCP: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) -- cgit v1.2.3 From 686bc00c05094e8678747c111a6a70ad4b7063e3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 16:51:07 +1000 Subject: nv50: oops, copy+pasto --- src/gallium/drivers/nv50/nv50_program.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 79893a9ad4..b013435f99 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -151,9 +151,9 @@ ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w) pc->immd_buf = realloc(pc->immd_buf, (pc->immd_nr + 1) * 4 * sizeof(float)); pc->immd_buf[(pc->immd_nr * 4) + 0] = x; - pc->immd_buf[(pc->immd_nr * 4) + 1] = x; - pc->immd_buf[(pc->immd_nr * 4) + 2] = x; - pc->immd_buf[(pc->immd_nr * 4) + 3] = x; + pc->immd_buf[(pc->immd_nr * 4) + 1] = y; + pc->immd_buf[(pc->immd_nr * 4) + 2] = z; + pc->immd_buf[(pc->immd_nr * 4) + 3] = w; return pc->immd_nr++; } -- cgit v1.2.3 From faa1c02546db00f69c66db18076b5b0ac86d7138 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 17:36:10 +1000 Subject: nv50: create emit_pow() - emit_lit() will need to use it --- src/gallium/drivers/nv50/nv50_program.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index b013435f99..bc0a834aee 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -627,6 +627,7 @@ emit_preex2(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) emit(pc, inst); } + /*XXX: inaccurate results.. why? */ #define ALLOW_SET_SWAP 0 @@ -694,6 +695,20 @@ emit_flr(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) emit(pc, inst); } +static void +emit_pow(struct nv50_pc *pc, struct nv50_reg *dst, + struct nv50_reg *v, struct nv50_reg *e) +{ + struct nv50_reg *temp = alloc_temp(pc, NULL); + + emit_flop(pc, 3, temp, v); + emit_mul(pc, temp, temp, e); + emit_preex2(pc, temp, temp); + emit_flop(pc, 6, dst, temp); + + free_temp(pc, temp); +} + static boolean nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) { @@ -875,10 +890,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) break; case TGSI_OPCODE_POW: temp = alloc_temp(pc, NULL); - emit_flop(pc, 3, temp, src[0][0]); - emit_mul(pc, temp, temp, src[1][0]); - emit_preex2(pc, temp, temp); - emit_flop(pc, 6, temp, temp); + emit_pow(pc, temp, src[0][0], src[1][0]); for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; -- cgit v1.2.3 From fe90cc509f75772ce202930c934bade1d4b116c8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 17:42:00 +1000 Subject: nv50: obey per-source abs (TGSI_UTIL_SIGN_CLEAR) --- src/gallium/drivers/nv50/nv50_program.c | 175 +++++++++++++++++--------------- 1 file changed, 95 insertions(+), 80 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index bc0a834aee..fabd016491 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -171,75 +171,6 @@ alloc_immd(struct nv50_pc *pc, float f) return r; } -static struct nv50_reg * -tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) -{ - switch (dst->DstRegister.File) { - case TGSI_FILE_TEMPORARY: - return &pc->temp[dst->DstRegister.Index * 4 + c]; - case TGSI_FILE_OUTPUT: - return &pc->result[dst->DstRegister.Index * 4 + c]; - case TGSI_FILE_NULL: - return NULL; - default: - break; - } - - return NULL; -} - -static struct nv50_reg * -tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src) -{ - struct nv50_reg *r = NULL; - unsigned c; - - c = tgsi_util_get_full_src_register_extswizzle(src, chan); - switch (c) { - case TGSI_EXTSWIZZLE_X: - case TGSI_EXTSWIZZLE_Y: - case TGSI_EXTSWIZZLE_Z: - case TGSI_EXTSWIZZLE_W: - switch (src->SrcRegister.File) { - case TGSI_FILE_INPUT: - r = &pc->attr[src->SrcRegister.Index * 4 + c]; - break; - case TGSI_FILE_TEMPORARY: - r = &pc->temp[src->SrcRegister.Index * 4 + c]; - break; - case TGSI_FILE_CONSTANT: - r = &pc->param[src->SrcRegister.Index * 4 + c]; - break; - case TGSI_FILE_IMMEDIATE: - r = &pc->immd[src->SrcRegister.Index * 4 + c]; - break; - default: - assert(0); - break; - } - break; - case TGSI_EXTSWIZZLE_ZERO: - r = alloc_immd(pc, 0.0); - break; - case TGSI_EXTSWIZZLE_ONE: - r = alloc_immd(pc, 1.0); - break; - default: - assert(0); - break; - } - - switch (tgsi_util_get_full_src_register_sign_mode(src, chan)) { - case TGSI_UTIL_SIGN_KEEP: - break; - default: - assert(0); - break; - } - - return r; -} - static void emit(struct nv50_pc *pc, unsigned *inst) { @@ -709,6 +640,98 @@ emit_pow(struct nv50_pc *pc, struct nv50_reg *dst, free_temp(pc, temp); } +static void +emit_abs(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) +{ + unsigned inst[2] = { 0, 0 }; + + inst[0] = 0xa0000000; /* cvt */ + set_long(pc, inst); + inst[1] |= (6 << 29); /* cvt */ + inst[1] |= 0x04000000; /* 32 bit */ + inst[1] |= (1 << 14); /* src .f32 */ + inst[1] |= ((1 << 6) << 14); /* .abs */ + set_dst(pc, dst, inst); + set_src_0(pc, src, inst); + + emit(pc, inst); +} + +static struct nv50_reg * +tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) +{ + switch (dst->DstRegister.File) { + case TGSI_FILE_TEMPORARY: + return &pc->temp[dst->DstRegister.Index * 4 + c]; + case TGSI_FILE_OUTPUT: + return &pc->result[dst->DstRegister.Index * 4 + c]; + case TGSI_FILE_NULL: + return NULL; + default: + break; + } + + return NULL; +} + +static struct nv50_reg * +tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src) +{ + struct nv50_reg *r = NULL; + struct nv50_reg *temp; + unsigned c; + + c = tgsi_util_get_full_src_register_extswizzle(src, chan); + switch (c) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + switch (src->SrcRegister.File) { + case TGSI_FILE_INPUT: + r = &pc->attr[src->SrcRegister.Index * 4 + c]; + break; + case TGSI_FILE_TEMPORARY: + r = &pc->temp[src->SrcRegister.Index * 4 + c]; + break; + case TGSI_FILE_CONSTANT: + r = &pc->param[src->SrcRegister.Index * 4 + c]; + break; + case TGSI_FILE_IMMEDIATE: + r = &pc->immd[src->SrcRegister.Index * 4 + c]; + break; + default: + assert(0); + break; + } + break; + case TGSI_EXTSWIZZLE_ZERO: + r = alloc_immd(pc, 0.0); + break; + case TGSI_EXTSWIZZLE_ONE: + r = alloc_immd(pc, 1.0); + break; + default: + assert(0); + break; + } + + switch (tgsi_util_get_full_src_register_sign_mode(src, chan)) { + case TGSI_UTIL_SIGN_KEEP: + break; + case TGSI_UTIL_SIGN_CLEAR: + temp = temp_temp(pc); + emit_abs(pc, temp, r); + r = temp; + break; + default: + assert(0); + break; + } + + return r; +} + static boolean nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) { @@ -744,17 +767,9 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ABS: for (c = 0; c < 4; c++) { - unsigned inst[2] = { 0, 0 }; - - inst[0] = 0xa0000000; /* cvt */ - set_long(pc, inst); - inst[1] |= (6 << 29); /* cvt */ - inst[1] |= 0x04000000; /* 32 bit */ - inst[1] |= (1 << 14); /* src .f32 */ - inst[1] |= ((1 << 6) << 14); /* .abs */ - set_dst(pc, dst[c], inst); - set_src_0(pc, src[0][c], inst); - emit(pc, inst); + if (!(mask & (1 << c))) + continue; + emit_abs(pc, dst[c], src[0][c]); } break; case TGSI_OPCODE_ADD: -- cgit v1.2.3 From 01e36eb531dfb4b1b3fd38d3fc00c6770833b5ea Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 7 Jun 2008 19:54:04 +1000 Subject: nv50: LIT - sort-of *somehow* we have the exact same bug here as on nv4x, the difference being on nv4x the hw actually has a LIT opcode.. NVIDIA doesn't have the bug on either arch FWIW. --- src/gallium/drivers/nv50/nv50_program.c | 36 +++++++++++++++++++++++++++++++-- src/gallium/drivers/nv50/nv50_vbo.c | 1 - 2 files changed, 34 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index fabd016491..186eea5e13 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -13,7 +13,6 @@ #define NV50_SU_MAX_TEMP 64 /* ARL - * LIT - other buggery * * MSB - Like MAD, but MUL+SUB * - Fuck it off, introduce a way to negate args for ops that @@ -23,6 +22,8 @@ * - Maybe even relax restrictions a bit, can't do P_RESULT + P_IMMD, * but can emit to P_TEMP first - then MOV later. NVIDIA does this * + * Hmmm.. what happens if we have src1+src2 both consts.. ouch ! + * * Verify half-insns work where expected - and force disable them where they * don't work - MUL has it forcibly disabled atm as it fixes POW.. */ @@ -164,7 +165,7 @@ alloc_immd(struct nv50_pc *pc, float f) struct nv50_reg *r = CALLOC_STRUCT(nv50_reg); unsigned hw; - hw = ctor_immd(pc, f, 0, 0, 0); + hw = ctor_immd(pc, f, 0, 0, 0) * 4; r->type = P_IMMD; r->hw = hw; r->index = -1; @@ -657,6 +658,34 @@ emit_abs(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) emit(pc, inst); } +static void +emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, struct nv50_reg **src) +{ + struct nv50_reg *one = alloc_immd(pc, 1.0); + struct nv50_reg *zero = alloc_immd(pc, 0.0); + struct nv50_reg *neg128 = alloc_immd(pc, -127.999999); + struct nv50_reg *pos128 = alloc_immd(pc, 127.999999); + struct nv50_reg *tmp[4]; + + emit_mov(pc, dst[0], one); + emit_mov(pc, dst[3], one); + + tmp[0] = temp_temp(pc); + emit_minmax(pc, 4, dst[1], src[0], zero); + set_pred_wr(pc, 1, 0, &pc->p->insns[pc->p->insns_nr - 2]); + + tmp[1] = temp_temp(pc); + emit_minmax(pc, 4, tmp[1], src[1], zero); + + tmp[3] = temp_temp(pc); + emit_minmax(pc, 4, tmp[3], src[3], neg128); + emit_minmax(pc, 5, tmp[3], tmp[3], pos128); + + emit_pow(pc, dst[2], tmp[1], tmp[3]); + emit_mov(pc, dst[2], zero); + set_pred(pc, 3, 0, &pc->p->insns[pc->p->insns_nr - 2]); +} + static struct nv50_reg * tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) { @@ -861,6 +890,9 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } free_temp(pc, temp); break; + case TGSI_OPCODE_LIT: + emit_lit(pc, &dst[0], &src[0][0]); + break; case TGSI_OPCODE_LG2: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index f086c76258..badbef53df 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -35,7 +35,6 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, struct nv50_context *nv50 = nv50_context(pipe); nv50_state_validate(nv50); - NOUVEAU_ERR("unimplemented\n"); BEGIN_RING(tesla, 0x142c, 1); OUT_RING (0); -- cgit v1.2.3 From 9a37a56c8ab8c64bdadb1e1e807f885d6a5e3121 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 8 Jun 2008 11:23:06 +1000 Subject: nv50: obey writemask in a couple of places --- src/gallium/drivers/nv50/nv50_program.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 186eea5e13..7206e5d280 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -12,7 +12,7 @@ #define NV50_SU_MAX_TEMP 64 -/* ARL +/* ARL - gallium craps itself on progs/vp/arl.txt * * MSB - Like MAD, but MUL+SUB * - Fuck it off, introduce a way to negate args for ops that @@ -856,10 +856,14 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) case TGSI_OPCODE_DST: { struct nv50_reg *one = alloc_immd(pc, 1.0); - emit_mov(pc, dst[0], one); - emit_mul(pc, dst[1], src[0][1], src[1][1]); - emit_mov(pc, dst[2], src[0][2]); - emit_mov(pc, dst[3], src[1][3]); + if (mask & (1 << 0)) + emit_mov(pc, dst[0], one); + if (mask & (1 << 1)) + emit_mul(pc, dst[1], src[0][1], src[1][1]); + if (mask & (1 << 2)) + emit_mov(pc, dst[2], src[0][2]); + if (mask & (1 << 3)) + emit_mov(pc, dst[3], src[1][3]); FREE(one); } break; @@ -891,6 +895,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) free_temp(pc, temp); break; case TGSI_OPCODE_LIT: + /*XXX: writemask */ emit_lit(pc, &dst[0], &src[0][0]); break; case TGSI_OPCODE_LG2: @@ -989,12 +994,18 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) break; case TGSI_OPCODE_XPD: temp = alloc_temp(pc, NULL); - emit_mul(pc, temp, src[0][2], src[1][1]); - emit_msb(pc, dst[0], src[0][1], src[1][2], temp); - emit_mul(pc, temp, src[0][0], src[1][2]); - emit_msb(pc, dst[1], src[0][2], src[1][0], temp); - emit_mul(pc, temp, src[0][1], src[1][0]); - emit_msb(pc, dst[2], src[0][0], src[1][1], temp); + if (mask & (1 << 0)) { + emit_mul(pc, temp, src[0][2], src[1][1]); + emit_msb(pc, dst[0], src[0][1], src[1][2], temp); + } + if (mask & (1 << 1)) { + emit_mul(pc, temp, src[0][0], src[1][2]); + emit_msb(pc, dst[1], src[0][2], src[1][0], temp); + } + if (mask & (1 << 2)) { + emit_mul(pc, temp, src[0][1], src[1][0]); + emit_msb(pc, dst[2], src[0][0], src[1][1], temp); + } free_temp(pc, temp); break; case TGSI_OPCODE_END: -- cgit v1.2.3 From 6ca31aa55eada38ad8b8a249b9e79a83b9784c04 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 8 Jun 2008 12:27:36 +1000 Subject: nv50: hehe, damage from tex-surfaces.. surface_fill() reenabled now :) --- src/gallium/drivers/nv50/nv50_miptree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 6c838998fd..be85c3fd5c 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -21,7 +21,7 @@ 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; @@ -29,7 +29,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) mt->base.screen = pscreen; mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, - 512*32*4); + pt->width[0] * pt->cpp * pt->height[0]); if (!mt->buffer) { FREE(mt); return NULL; -- cgit v1.2.3 From afcaeaa0e4dc3ced40621c76304a2c0c5a3ab403 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 8 Jun 2008 14:12:01 +1000 Subject: nv50: note a critical bug --- src/gallium/drivers/nv50/nv50_program.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 7206e5d280..b151b540bf 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -26,6 +26,9 @@ * * Verify half-insns work where expected - and force disable them where they * don't work - MUL has it forcibly disabled atm as it fixes POW.. + * + * FUCK! watch dst==src vectors, can overwrite components that are needed. + * ie. SUB R0, R0.yzxw, R0 */ struct nv50_reg { enum { -- cgit v1.2.3 From 34a039ae7b158cacb5b20d91067e9d6458d30a56 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 8 Jun 2008 15:51:54 +1000 Subject: nv50: fix src1 & src2 == const --- src/gallium/drivers/nv50/nv50_program.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index b151b540bf..936a8ef9b3 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -22,8 +22,6 @@ * - Maybe even relax restrictions a bit, can't do P_RESULT + P_IMMD, * but can emit to P_TEMP first - then MOV later. NVIDIA does this * - * Hmmm.. what happens if we have src1+src2 both consts.. ouch ! - * * Verify half-insns work where expected - and force disable them where they * don't work - MUL has it forcibly disabled atm as it fixes POW.. * @@ -391,8 +389,16 @@ set_src_1(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) src = temp; } else if (src->type == P_CONST || src->type == P_IMMD) { - set_cseg(pc, src, inst); - inst[0] |= 0x00800000; + assert(!(inst[0] & 0x00800000)); + if (inst[0] & 0x01000000) { + struct nv50_reg *temp = temp_temp(pc); + + emit_mov(pc, temp, src); + src = temp; + } else { + set_cseg(pc, src, inst); + inst[0] |= 0x00800000; + } } alloc_reg(pc, src); @@ -411,8 +417,16 @@ set_src_2(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) src = temp; } else if (src->type == P_CONST || src->type == P_IMMD) { - set_cseg(pc, src, inst); - inst[0] |= 0x01000000; + assert(!(inst[0] & 0x01000000)); + if (inst[0] & 0x00800000) { + struct nv50_reg *temp = temp_temp(pc); + + emit_mov(pc, temp, src); + src = temp; + } else { + set_cseg(pc, src, inst); + inst[0] |= 0x01000000; + } } alloc_reg(pc, src); -- cgit v1.2.3 From 776e9581d16fc0fd28058fbcd879756fd5d40b96 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 9 Jun 2008 13:07:38 +1000 Subject: nv50: delayed write of fragprog result regs until end of program --- src/gallium/drivers/nv50/nv50_program.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 936a8ef9b3..1733cf97b7 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -27,6 +27,8 @@ * * FUCK! watch dst==src vectors, can overwrite components that are needed. * ie. SUB R0, R0.yzxw, R0 + * + * NV50_PROG* -> PIPE_SHADER* */ struct nv50_reg { enum { @@ -1198,11 +1200,13 @@ nv50_program_tx_prep(struct nv50_pc *pc) for (i = 0; i < pc->result_nr; i++) { for (c = 0; c < 4; c++) { - if (pc->p->type == NV50_PROG_FRAGMENT) + if (pc->p->type == NV50_PROG_FRAGMENT) { pc->result[i*4+c].type = P_TEMP; - else + pc->result[i*4+c].hw = -1; + } else { pc->result[i*4+c].type = P_RESULT; - pc->result[i*4+c].hw = rid++; + pc->result[i*4+c].hw = rid++; + } pc->result[i*4+c].index = i; } } @@ -1281,6 +1285,14 @@ nv50_program_tx(struct nv50_program *p) } } + if (p->type == NV50_PROG_FRAGMENT) { + struct nv50_reg out; + + out.type = P_TEMP; + for (out.hw = 0; out.hw < pc->result_nr * 4; out.hw++) + emit_mov(pc, &out, &pc->result[out.hw]); + } + p->immd_nr = pc->immd_nr * 4; p->immd = pc->immd_buf; -- cgit v1.2.3 From b5bbf09c42a9d563984fad875ced5c4814033a3d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 9 Jun 2008 13:09:55 +1000 Subject: nv50: remove NV50_PROG_{VERTEX,FRAGMENT} --- src/gallium/drivers/nv50/nv50_program.c | 19 +++++++++++-------- src/gallium/drivers/nv50/nv50_state.c | 4 ++-- src/gallium/drivers/nv50/nv50_state.h | 5 +---- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 1733cf97b7..6b8ba1bdfe 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -28,7 +28,10 @@ * FUCK! watch dst==src vectors, can overwrite components that are needed. * ie. SUB R0, R0.yzxw, R0 * - * NV50_PROG* -> PIPE_SHADER* + * Things to check with renouveau: + * SGE/SLT with needed src0/1 swap + * FP attr/result assignment - how? + * FP/VP constbuf usage */ struct nv50_reg { enum { @@ -289,7 +292,7 @@ set_cseg(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) if (src->type == P_IMMD) { inst[1] |= (NV50_CB_PMISC << 22); } else { - if (pc->p->type == NV50_PROG_VERTEX) + if (pc->p->type == PIPE_SHADER_VERTEX) inst[1] |= (NV50_CB_PVP << 22); else inst[1] |= (NV50_CB_PFP << 22); @@ -1144,7 +1147,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (!pc->attr) goto out_err; - if (pc->p->type == NV50_PROG_FRAGMENT) { + if (pc->p->type == PIPE_SHADER_FRAGMENT) { iv = alloc_temp(pc, NULL); aid++; } @@ -1153,7 +1156,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) struct nv50_reg *a = &pc->attr[i*4]; for (c = 0; c < 4; c++) { - if (pc->p->type == NV50_PROG_FRAGMENT) { + if (pc->p->type == PIPE_SHADER_FRAGMENT) { struct nv50_reg *at = alloc_temp(pc, NULL); pc->attr[i*4+c].type = at->type; @@ -1168,7 +1171,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) } } - if (pc->p->type != NV50_PROG_FRAGMENT) + if (pc->p->type != PIPE_SHADER_FRAGMENT) continue; emit_interp(pc, iv, iv, iv, FALSE); @@ -1200,7 +1203,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) for (i = 0; i < pc->result_nr; i++) { for (c = 0; c < 4; c++) { - if (pc->p->type == NV50_PROG_FRAGMENT) { + if (pc->p->type == PIPE_SHADER_FRAGMENT) { pc->result[i*4+c].type = P_TEMP; pc->result[i*4+c].hw = -1; } else { @@ -1285,7 +1288,7 @@ nv50_program_tx(struct nv50_program *p) } } - if (p->type == NV50_PROG_FRAGMENT) { + if (p->type == PIPE_SHADER_FRAGMENT) { struct nv50_reg out; out.type = P_TEMP; @@ -1314,7 +1317,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) * NOT immd - otherwise it's fucked fucked fucked */ p->insns[p->insns_nr - 1] |= 0x00000001; - if (p->type == NV50_PROG_VERTEX) { + if (p->type == PIPE_SHADER_VERTEX) { for (i = 0; i < p->insns_nr; i++) NOUVEAU_ERR("VP0x%08x\n", p->insns[i]); } else { diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 48d09c296b..774117326a 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -331,7 +331,7 @@ nv50_vp_state_create(struct pipe_context *pipe, struct nv50_program *p = CALLOC_STRUCT(nv50_program); p->pipe = *cso; - p->type = NV50_PROG_VERTEX; + p->type = PIPE_SHADER_VERTEX; tgsi_scan_shader(p->pipe.tokens, &p->info); return (void *)p; } @@ -361,7 +361,7 @@ nv50_fp_state_create(struct pipe_context *pipe, struct nv50_program *p = CALLOC_STRUCT(nv50_program); p->pipe = *cso; - p->type = NV50_PROG_FRAGMENT; + p->type = PIPE_SHADER_FRAGMENT; tgsi_scan_shader(p->pipe.tokens, &p->info); return (void *)p; } diff --git a/src/gallium/drivers/nv50/nv50_state.h b/src/gallium/drivers/nv50/nv50_state.h index dd352b6585..d568bf610d 100644 --- a/src/gallium/drivers/nv50/nv50_state.h +++ b/src/gallium/drivers/nv50/nv50_state.h @@ -15,10 +15,7 @@ struct nv50_program { struct tgsi_shader_info info; boolean translated; - enum { - NV50_PROG_VERTEX, - NV50_PROG_FRAGMENT - } type; + unsigned type; unsigned *insns; unsigned insns_nr; -- cgit v1.2.3 From 713ef6ccd2590bd866598bb6d4f646e9ec29ba78 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 9 Jun 2008 13:31:42 +1000 Subject: nv50: use emit_flop() instead of building RCP manually on interp --- src/gallium/drivers/nv50/nv50_program.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 6b8ba1bdfe..592435585d 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1176,12 +1176,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) emit_interp(pc, iv, iv, iv, FALSE); tmp = alloc_temp(pc, NULL); - { - unsigned inst[2] = { 0, 0 }; - inst[0] = 0x90000000; - inst[0] |= (tmp->hw << 2); - emit(pc, inst); - } + emit_flop(pc, 0, tmp, iv); emit_interp(pc, &a[0], &a[0], tmp, TRUE); emit_interp(pc, &a[1], &a[1], tmp, TRUE); emit_interp(pc, &a[2], &a[2], tmp, TRUE); -- cgit v1.2.3 From 6d0f7ea95475009ee17862786469f7b9a34a797f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 9 Jun 2008 16:26:51 +1000 Subject: nv50: note some things discovered during renouveau session --- src/gallium/drivers/nv50/nv50_program.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 592435585d..0274545131 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -28,10 +28,29 @@ * FUCK! watch dst==src vectors, can overwrite components that are needed. * ie. SUB R0, R0.yzxw, R0 * + * MOV dst, -src + * "delta" tmp, -src (0xa0000204,0xe4004780 - delta r0, -r0) + * mov dst, tmp + * * Things to check with renouveau: - * SGE/SLT with needed src0/1 swap * FP attr/result assignment - how? - * FP/VP constbuf usage + * attrib + * - 0x16bc maps vp output onto fp hpos + * - 0x16c0 maps vp output onto fp col0 + * result + * - colr always 0-3 + * - depr always 4 + * 0x16bc->0x16e8 --> some binding between vp/fp regs + * 0x16b8 --> VP output count + * + * 0x1298 --> "MOV rcol.x, fcol.y" "MOV depr, fcol.y" = 0x00000005 + * "MOV rcol.x, fcol.y" = 0x00000004 + * 0x19a8 --> as above but 0x00000100 and 0x00000000 + * - 0x00100000 used when KIL used + * 0x196c --> as above but 0x00000011 and 0x00000000 + * + * 0x1988 --> 0xXXNNNNNN + * - XX == FP high something */ struct nv50_reg { enum { -- cgit v1.2.3 From 31f6a24b59b0ac18e04336d2e3cbaa643358c88a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 9 Jun 2008 16:35:07 +1000 Subject: nv50: support the other TGSI_UTIL_SIGN modes --- src/gallium/drivers/nv50/nv50_program.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 0274545131..44914f41b6 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -727,6 +727,22 @@ emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, struct nv50_reg **src) set_pred(pc, 3, 0, &pc->p->insns[pc->p->insns_nr - 2]); } +static void +emit_neg(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) +{ + unsigned inst[2] = { 0, 0 }; + + set_long(pc, inst); + inst[0] |= 0xa0000000; /* delta */ + inst[1] |= (7 << 29); /* delta */ + inst[1] |= 0x04000000; /* negate arg0? probably not */ + inst[1] |= (1 << 14); /* src .f32 */ + set_dst(pc, dst, inst); + set_src_0(pc, src, inst); + + emit(pc, inst); +} + static struct nv50_reg * tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) { @@ -794,6 +810,17 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src) emit_abs(pc, temp, r); r = temp; break; + case TGSI_UTIL_SIGN_TOGGLE: + temp = temp_temp(pc); + emit_neg(pc, temp, r); + r = temp; + break; + case TGSI_UTIL_SIGN_SET: + temp = temp_temp(pc); + emit_abs(pc, temp, r); + emit_neg(pc, temp, r); + r = temp; + break; default: assert(0); break; -- cgit v1.2.3 From 51ea3aae03154046316b814053f7493bdb10c853 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 9 Jun 2008 16:41:08 +1000 Subject: nv50: fix SGE/SLT when sources need swapping --- src/gallium/drivers/nv50/nv50_program.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 44914f41b6..21341619de 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -601,24 +601,17 @@ emit_preex2(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) emit(pc, inst); } -/*XXX: inaccurate results.. why? */ -#define ALLOW_SET_SWAP 0 - static void emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst, struct nv50_reg *src0, struct nv50_reg *src1) { unsigned inst[2] = { 0, 0 }; -#if ALLOW_SET_SWAP - unsigned inv_cop[8] = { 0, 6, 2, 4, 3, 5, 1, 7 }; -#endif + unsigned inv_cop[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; struct nv50_reg *rdst; -#if ALLOW_SET_SWAP assert(c_op <= 7); if (check_swap_src_0_1(pc, &src0, &src1)) c_op = inv_cop[c_op]; -#endif rdst = dst; if (dst->type != P_TEMP) -- cgit v1.2.3 From 454394e749feca5ac00e7a270e6ca5529581d228 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 9 Jun 2008 17:36:22 +1000 Subject: nv50: quick hack so progs/fp/fp-tri works for the moment --- src/gallium/drivers/nv50/nv50_context.h | 4 ++-- src/gallium/drivers/nv50/nv50_program.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index c4a8a4c064..69c9dba675 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -24,8 +24,8 @@ fprintf(stderr, "nouveau: "fmt, ##args); /* Constant buffer assignment */ -#define NV50_CB_PMISC 0 -#define NV50_CB_PVP 1 +#define NV50_CB_PMISC 1 +#define NV50_CB_PVP 0 #define NV50_CB_PFP 2 #define NV50_CB_PGP 3 #define NV50_CB_TIC 4 diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 21341619de..843e036251 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1369,7 +1369,7 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) for (i = 0; i < p->immd_nr; i++) { BEGIN_RING(tesla, 0x0f00, 2); - OUT_RING ((NV50_CB_PMISC << 16) | (i << 8)); + OUT_RING ((NV50_CB_PMISC << 0) | (i << 8)); OUT_RING (fui(p->immd[i])); } } -- cgit v1.2.3 From 21e688e0a3faeef18b07c4d860bd71cc6e3ddf4a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 9 Jun 2008 18:01:03 +1000 Subject: nv50: LRP --- src/gallium/drivers/nv50/nv50_program.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 843e036251..33822a1a78 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -85,7 +85,7 @@ struct nv50_pc { float *immd_buf; int immd_nr; - struct nv50_reg *temp_temp[8]; + struct nv50_reg *temp_temp[16]; unsigned temp_temp_nr; }; @@ -154,7 +154,7 @@ free_temp(struct nv50_pc *pc, struct nv50_reg *r) static struct nv50_reg * temp_temp(struct nv50_pc *pc) { - if (pc->temp_temp_nr >= 8) + if (pc->temp_temp_nr >= 16) assert(0); pc->temp_temp[pc->temp_temp_nr] = alloc_temp(pc, NULL); @@ -966,6 +966,18 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_flop(pc, 3, dst[c], src[0][c]); } break; + case TGSI_OPCODE_LRP: + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; + /*XXX: we can do better than this */ + temp = alloc_temp(pc, NULL); + emit_neg(pc, temp, src[0][c]); + emit_mad(pc, temp, temp, src[2][c], src[2][c]); + emit_mad(pc, dst[c], src[0][c], src[1][c], temp); + free_temp(pc, temp); + } + break; case TGSI_OPCODE_MAD: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) -- cgit v1.2.3 From 7b7df34781844c39998d60bbb60880d960da3fb1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 9 Jun 2008 19:50:17 +1000 Subject: nv50: various fixes + SCS --- src/gallium/drivers/nv50/nv50_program.c | 89 ++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 23 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 33822a1a78..d69eb4b86b 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -601,6 +601,21 @@ emit_preex2(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) emit(pc, inst); } +static void +emit_precossin(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) +{ + unsigned inst[2] = { 0, 0 }; + + inst[0] |= 0xb0000000; + + set_dst(pc, dst, inst); + set_src_0(pc, src, inst); + set_long(pc, inst); + inst[1] |= (6 << 29); + + emit(pc, inst); +} + static void emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst, struct nv50_reg *src0, struct nv50_reg *src1) @@ -693,7 +708,8 @@ emit_abs(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) } static void -emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, struct nv50_reg **src) +emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask, + struct nv50_reg **src) { struct nv50_reg *one = alloc_immd(pc, 1.0); struct nv50_reg *zero = alloc_immd(pc, 0.0); @@ -701,23 +717,34 @@ emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, struct nv50_reg **src) struct nv50_reg *pos128 = alloc_immd(pc, 127.999999); struct nv50_reg *tmp[4]; - emit_mov(pc, dst[0], one); - emit_mov(pc, dst[3], one); + if (mask & (1 << 0)) + emit_mov(pc, dst[0], one); + + if (mask & (1 << 3)) + emit_mov(pc, dst[3], one); + + if (mask & (3 << 1)) { + if (mask & (1 << 1)) + tmp[0] = dst[1]; + else + tmp[0] = temp_temp(pc); + emit_minmax(pc, 4, tmp[0], src[0], zero); + } - tmp[0] = temp_temp(pc); - emit_minmax(pc, 4, dst[1], src[0], zero); - set_pred_wr(pc, 1, 0, &pc->p->insns[pc->p->insns_nr - 2]); + if (mask & (1 << 2)) { + set_pred_wr(pc, 1, 0, &pc->p->insns[pc->p->insns_nr - 2]); - tmp[1] = temp_temp(pc); - emit_minmax(pc, 4, tmp[1], src[1], zero); + tmp[1] = temp_temp(pc); + emit_minmax(pc, 4, tmp[1], src[1], zero); - tmp[3] = temp_temp(pc); - emit_minmax(pc, 4, tmp[3], src[3], neg128); - emit_minmax(pc, 5, tmp[3], tmp[3], pos128); + tmp[3] = temp_temp(pc); + emit_minmax(pc, 4, tmp[3], src[3], neg128); + emit_minmax(pc, 5, tmp[3], tmp[3], pos128); - emit_pow(pc, dst[2], tmp[1], tmp[3]); - emit_mov(pc, dst[2], zero); - set_pred(pc, 3, 0, &pc->p->insns[pc->p->insns_nr - 2]); + emit_pow(pc, dst[2], tmp[1], tmp[3]); + emit_mov(pc, dst[2], zero); + set_pred(pc, 3, 0, &pc->p->insns[pc->p->insns_nr - 2]); + } } static void @@ -870,10 +897,13 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } break; case TGSI_OPCODE_COS: + temp = alloc_temp(pc, NULL); + emit_precossin(pc, temp, src[0][0]); + emit_flop(pc, 5, temp, temp); for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_flop(pc, 5, dst[c], src[0][c]); + emit_mov(pc, dst[c], temp); } break; case TGSI_OPCODE_DP3: @@ -930,11 +960,12 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) break; case TGSI_OPCODE_EX2: temp = alloc_temp(pc, NULL); + emit_preex2(pc, temp, src[0][0]); + emit_flop(pc, 6, temp, temp); for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_preex2(pc, temp, src[0][c]); - emit_flop(pc, 6, dst[c], temp); + emit_mov(pc, dst[c], temp); } free_temp(pc, temp); break; @@ -956,14 +987,15 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) free_temp(pc, temp); break; case TGSI_OPCODE_LIT: - /*XXX: writemask */ - emit_lit(pc, &dst[0], &src[0][0]); + emit_lit(pc, &dst[0], mask, &src[0][0]); break; case TGSI_OPCODE_LG2: + temp = alloc_temp(pc, NULL); + emit_flop(pc, 3, temp, src[0][0]); for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_flop(pc, 3, dst[c], src[0][c]); + emit_mov(pc, dst[c], temp); } break; case TGSI_OPCODE_LRP: @@ -1027,16 +1059,24 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_flop(pc, 0, dst[c], src[0][c]); + emit_flop(pc, 0, dst[c], src[0][0]); } break; case TGSI_OPCODE_RSQ: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_flop(pc, 2, dst[c], src[0][c]); + emit_flop(pc, 2, dst[c], src[0][0]); } break; + case TGSI_OPCODE_SCS: + temp = alloc_temp(pc, NULL); + emit_precossin(pc, temp, src[0][0]); + if (mask & (1 << 0)) + emit_flop(pc, 5, dst[0], temp); + if (mask & (1 << 1)) + emit_flop(pc, 4, dst[1], temp); + break; case TGSI_OPCODE_SGE: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) @@ -1045,10 +1085,13 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } break; case TGSI_OPCODE_SIN: + temp = alloc_temp(pc, NULL); + emit_precossin(pc, temp, src[0][0]); + emit_flop(pc, 4, temp, temp); for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) continue; - emit_flop(pc, 4, dst[c], src[0][c]); + emit_mov(pc, dst[c], temp); } break; case TGSI_OPCODE_SLT: -- cgit v1.2.3 From 7e9f6e290da23d7963857241b541e00c1fcf20dc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 11 Jun 2008 13:00:20 +1000 Subject: nv50: move some magics --- src/gallium/drivers/nv50/nv50_program.c | 16 ++++++++++++++-- src/gallium/drivers/nv50/nv50_screen.c | 9 --------- 2 files changed, 14 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index d69eb4b86b..934b67fb71 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1492,14 +1492,26 @@ nv50_fragprog_validate(struct nv50_context *nv50) nv50_program_validate_data(nv50, p); nv50_program_validate_code(nv50, p); - so = so_new(7, 2); + so = so_new(64, 2); so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2); so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, 0x198c, 1); + so_method(so, tesla, 0x1904, 4); + so_data (so, 0x01040404); /* p: 0x01000404 */ + so_data (so, 0x00000004); + so_data (so, 0x00000000); + so_data (so, 0x00000000); + so_method(so, tesla, 0x16bc, 2); + so_data (so, 0x03020100); + so_data (so, 0x07060504); + so_method(so, tesla, 0x1988, 2); + so_data (so, 0x08040404); /* p: 0x0f000401 */ so_data (so, p->cfg.high_temp); + so_method(so, tesla, 0x16ac, 2); + so_data (so, 0x00000008); /* p: 0x00000004 */ + so_data (so, 0x00000004); so_method(so, tesla, 0x1414, 1); so_data (so, 0); /* program start offset */ so_emit(nv50->screen->nvws, so); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 6c0810a9cf..2417bf8001 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -225,15 +225,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, 0x54); so_method(so, screen->tesla, 0x13ac, 1); so_data (so, 1); - so_method(so, screen->tesla, 0x16bc, 2); - so_data (so, 0x03020100); - so_data (so, 0x07060504); - so_method(so, screen->tesla, 0x1988, 2); - so_data (so, 0x08040404); - so_data (so, 0x00000004); - so_method(so, screen->tesla, 0x16ac, 2); - so_data (so, 8); - so_data (so, 4); so_method(so, screen->tesla, 0x16b8, 1); so_data (so, 8); -- cgit v1.2.3 From bce558b37cde4be5c70117f49a2570f2988e5849 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 11 Jun 2008 13:15:23 +1000 Subject: Revert "nv50: move some magics" This reverts commit 0a38de30429d3075fc6dfc9ff3729c5ca11f0c2f. --- src/gallium/drivers/nv50/nv50_program.c | 16 ++-------------- src/gallium/drivers/nv50/nv50_screen.c | 9 +++++++++ 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 934b67fb71..d69eb4b86b 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1492,26 +1492,14 @@ nv50_fragprog_validate(struct nv50_context *nv50) nv50_program_validate_data(nv50, p); nv50_program_validate_code(nv50, p); - so = so_new(64, 2); + so = so_new(7, 2); so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2); so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, 0x1904, 4); - so_data (so, 0x01040404); /* p: 0x01000404 */ - so_data (so, 0x00000004); - so_data (so, 0x00000000); - so_data (so, 0x00000000); - so_method(so, tesla, 0x16bc, 2); - so_data (so, 0x03020100); - so_data (so, 0x07060504); - so_method(so, tesla, 0x1988, 2); - so_data (so, 0x08040404); /* p: 0x0f000401 */ + so_method(so, tesla, 0x198c, 1); so_data (so, p->cfg.high_temp); - so_method(so, tesla, 0x16ac, 2); - so_data (so, 0x00000008); /* p: 0x00000004 */ - so_data (so, 0x00000004); so_method(so, tesla, 0x1414, 1); so_data (so, 0); /* program start offset */ so_emit(nv50->screen->nvws, so); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 2417bf8001..6c0810a9cf 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -225,6 +225,15 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, 0x54); so_method(so, screen->tesla, 0x13ac, 1); so_data (so, 1); + so_method(so, screen->tesla, 0x16bc, 2); + so_data (so, 0x03020100); + so_data (so, 0x07060504); + so_method(so, screen->tesla, 0x1988, 2); + so_data (so, 0x08040404); + so_data (so, 0x00000004); + so_method(so, screen->tesla, 0x16ac, 2); + so_data (so, 8); + so_data (so, 4); so_method(so, screen->tesla, 0x16b8, 1); so_data (so, 8); -- cgit v1.2.3 From 585ae74d87f3d04a4b5b7c068b865292afd1a16b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 11 Jun 2008 13:24:32 +1000 Subject: nv50: move magics take 2 --- src/gallium/drivers/nv50/nv50_program.c | 13 +++++++++++-- src/gallium/drivers/nv50/nv50_screen.c | 9 --------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index d69eb4b86b..b73003123d 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1492,13 +1492,22 @@ nv50_fragprog_validate(struct nv50_context *nv50) nv50_program_validate_data(nv50, p); nv50_program_validate_code(nv50, p); - so = so_new(7, 2); + so = so_new(64, 2); so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2); so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, 0x198c, 1); + so_method(so, tesla, 0x1904, 4); + so_data (so, 0x01040404); /* p: 0x01000404 */ + so_data (so, 0x00000004); + so_data (so, 0x00000000); + so_data (so, 0x00000000); + so_method(so, tesla, 0x16bc, 2); /*XXX: fixme */ + so_data (so, 0x03020100); + so_data (so, 0x07060504); + so_method(so, tesla, 0x1988, 2); + so_data (so, 0x08040404); /* p: 0x0f000401 */ so_data (so, p->cfg.high_temp); so_method(so, tesla, 0x1414, 1); so_data (so, 0); /* program start offset */ diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 6c0810a9cf..2417bf8001 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -225,15 +225,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, 0x54); so_method(so, screen->tesla, 0x13ac, 1); so_data (so, 1); - so_method(so, screen->tesla, 0x16bc, 2); - so_data (so, 0x03020100); - so_data (so, 0x07060504); - so_method(so, screen->tesla, 0x1988, 2); - so_data (so, 0x08040404); - so_data (so, 0x00000004); - so_method(so, screen->tesla, 0x16ac, 2); - so_data (so, 8); - so_data (so, 4); so_method(so, screen->tesla, 0x16b8, 1); so_data (so, 8); -- cgit v1.2.3 From 19a1e9015e4ae429ab26e56848104fa209590338 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 11 Jun 2008 14:59:19 +1000 Subject: nv50: rename nv50_state.h to nv50_program.h --- src/gallium/drivers/nv50/nv50_context.h | 2 +- src/gallium/drivers/nv50/nv50_program.c | 1 - src/gallium/drivers/nv50/nv50_program.h | 37 +++++++++++++++++++++++++++++++++ src/gallium/drivers/nv50/nv50_state.c | 1 - src/gallium/drivers/nv50/nv50_state.h | 37 --------------------------------- src/gallium/drivers/nv50/nv50_vbo.c | 1 - 6 files changed, 38 insertions(+), 41 deletions(-) create mode 100644 src/gallium/drivers/nv50/nv50_program.h delete mode 100644 src/gallium/drivers/nv50/nv50_state.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 69c9dba675..72d859c468 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -15,8 +15,8 @@ struct nv50_screen *ctx = nv50->screen #include "nouveau/nouveau_push.h" -#include "nv50_state.h" #include "nv50_screen.h" +#include "nv50_program.h" #define NOUVEAU_ERR(fmt, args...) \ fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index b73003123d..2118d8ef85 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -8,7 +8,6 @@ #include "tgsi/util/tgsi_util.h" #include "nv50_context.h" -#include "nv50_state.h" #define NV50_SU_MAX_TEMP 64 diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h new file mode 100644 index 0000000000..dd5aed799a --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -0,0 +1,37 @@ +#ifndef __NV50_PROGRAM_H__ +#define __NV50_PROGRAM_H__ + +#include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" + +struct nv50_program_data { + int index; + int component; + float value; +}; + +struct nv50_program { + struct pipe_shader_state pipe; + struct tgsi_shader_info info; + boolean translated; + + unsigned type; + unsigned *insns; + unsigned insns_nr; + + struct pipe_buffer *buffer; + + float *immd; + unsigned immd_nr; + + struct nouveau_resource *data; + + struct { + unsigned high_temp; + struct { + unsigned attr[2]; + } vp; + } cfg; +}; + +#endif diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 774117326a..ed6cca9a0d 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -3,7 +3,6 @@ #include "pipe/p_util.h" #include "nv50_context.h" -#include "nv50_state.h" #include "nouveau/nouveau_stateobj.h" diff --git a/src/gallium/drivers/nv50/nv50_state.h b/src/gallium/drivers/nv50/nv50_state.h deleted file mode 100644 index d568bf610d..0000000000 --- a/src/gallium/drivers/nv50/nv50_state.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __NV50_STATE_H__ -#define __NV50_STATE_H__ - -#include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" - -struct nv50_program_data { - int index; - int component; - float value; -}; - -struct nv50_program { - struct pipe_shader_state pipe; - struct tgsi_shader_info info; - boolean translated; - - unsigned type; - unsigned *insns; - unsigned insns_nr; - - struct pipe_buffer *buffer; - - float *immd; - unsigned immd_nr; - - struct nouveau_resource *data; - - struct { - unsigned high_temp; - struct { - unsigned attr[2]; - } vp; - } cfg; -}; - -#endif diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index badbef53df..140d60cc9a 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -3,7 +3,6 @@ #include "pipe/p_util.h" #include "nv50_context.h" -#include "nv50_state.h" static INLINE unsigned nv50_prim(unsigned mode) -- cgit v1.2.3 From f50e78e83cf7bda3537ac82de863096d829f13ee Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 11 Jun 2008 15:28:41 +1000 Subject: nv50: get vp working again, fp is broken regardless somehow.. g8x sucks :) --- src/gallium/drivers/nv50/nv50_context.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 72d859c468..19ec492eb3 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -24,8 +24,8 @@ fprintf(stderr, "nouveau: "fmt, ##args); /* Constant buffer assignment */ -#define NV50_CB_PMISC 1 -#define NV50_CB_PVP 0 +#define NV50_CB_PMISC 0 +#define NV50_CB_PVP 1 #define NV50_CB_PFP 2 #define NV50_CB_PGP 3 #define NV50_CB_TIC 4 -- cgit v1.2.3 From 40137ea2631a0c8158f99ae30ca90ed038b72076 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 12:16:43 +1000 Subject: nv50: carry instructions around in nv50_program_exec, not a flat array --- src/gallium/drivers/nv50/nv50_program.c | 482 +++++++++++++++++--------------- src/gallium/drivers/nv50/nv50_program.h | 22 +- 2 files changed, 268 insertions(+), 236 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 2118d8ef85..3df3848761 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -196,168 +196,175 @@ alloc_immd(struct nv50_pc *pc, float f) return r; } +static struct nv50_program_exec * +exec(struct nv50_pc *pc) +{ + struct nv50_program_exec *e = CALLOC_STRUCT(nv50_program_exec); + + return e; +} + static void -emit(struct nv50_pc *pc, unsigned *inst) +emit(struct nv50_pc *pc, struct nv50_program_exec *e) { struct nv50_program *p = pc->p; - if (inst[0] & 1) { - p->insns_nr += 2; - p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); - memcpy(p->insns + (p->insns_nr - 2), inst, sizeof(unsigned)*2); - } else { - p->insns_nr += 1; - p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr); - memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned)); - } + if (p->exec_tail) + p->exec_tail->next = e; + if (!p->exec_head) + p->exec_head = e; + p->exec_tail = e; + p->exec_size += (e->inst[0] & 1) ? 2 : 1; } -static INLINE void set_long(struct nv50_pc *, unsigned *); +static INLINE void set_long(struct nv50_pc *, struct nv50_program_exec *); static boolean -is_long(unsigned *inst) +is_long(struct nv50_program_exec *e) { - if (inst[0] & 1) + if (e->inst[0] & 1) return TRUE; return FALSE; } static boolean -is_immd(unsigned *inst) +is_immd(struct nv50_program_exec *e) { - if (is_long(inst) && (inst[1] & 3) == 3) + if (is_long(e) && (e->inst[1] & 3) == 3) return TRUE; return FALSE; } static INLINE void -set_pred(struct nv50_pc *pc, unsigned pred, unsigned idx, unsigned *inst) +set_pred(struct nv50_pc *pc, unsigned pred, unsigned idx, + struct nv50_program_exec *e) { - set_long(pc, inst); - inst[1] &= ~((0x1f << 7) | (0x3 << 12)); - inst[1] |= (pred << 7) | (idx << 12); + set_long(pc, e); + e->inst[1] &= ~((0x1f << 7) | (0x3 << 12)); + e->inst[1] |= (pred << 7) | (idx << 12); } static INLINE void -set_pred_wr(struct nv50_pc *pc, unsigned on, unsigned idx, unsigned *inst) +set_pred_wr(struct nv50_pc *pc, unsigned on, unsigned idx, + struct nv50_program_exec *e) { - set_long(pc, inst); - inst[1] &= ~((0x3 << 4) | (1 << 6)); - inst[1] |= (idx << 4) | (on << 6); + set_long(pc, e); + e->inst[1] &= ~((0x3 << 4) | (1 << 6)); + e->inst[1] |= (idx << 4) | (on << 6); } static INLINE void -set_long(struct nv50_pc *pc, unsigned *inst) +set_long(struct nv50_pc *pc, struct nv50_program_exec *e) { - if (is_long(inst)) + if (is_long(e)) return; - inst[0] |= 1; - set_pred(pc, 0xf, 0, inst); - set_pred_wr(pc, 0, 0, inst); + e->inst[0] |= 1; + set_pred(pc, 0xf, 0, e); + set_pred_wr(pc, 0, 0, e); } static INLINE void -set_dst(struct nv50_pc *pc, struct nv50_reg *dst, unsigned *inst) +set_dst(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_program_exec *e) { if (dst->type == P_RESULT) { - set_long(pc, inst); - inst[1] |= 0x00000008; + set_long(pc, e); + e->inst[1] |= 0x00000008; } alloc_reg(pc, dst); - inst[0] |= (dst->hw << 2); + e->inst[0] |= (dst->hw << 2); } static INLINE void -set_immd(struct nv50_pc *pc, struct nv50_reg *imm, unsigned *inst) +set_immd(struct nv50_pc *pc, struct nv50_reg *imm, struct nv50_program_exec *e) { unsigned val = fui(pc->immd_buf[imm->hw]); /* XXX */ - set_long(pc, inst); + set_long(pc, e); /*XXX: can't be predicated - bits overlap.. catch cases where both * are required and avoid them. */ - set_pred(pc, 0, 0, inst); - set_pred_wr(pc, 0, 0, inst); + set_pred(pc, 0, 0, e); + set_pred_wr(pc, 0, 0, e); - inst[1] |= 0x00000002 | 0x00000001; - inst[0] |= (val & 0x3f) << 16; - inst[1] |= (val >> 6) << 2; + e->inst[1] |= 0x00000002 | 0x00000001; + e->inst[0] |= (val & 0x3f) << 16; + e->inst[1] |= (val >> 6) << 2; } static void emit_interp(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src, struct nv50_reg *iv, boolean noperspective) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - inst[0] |= 0x80000000; - set_dst(pc, dst, inst); + e->inst[0] |= 0x80000000; + set_dst(pc, dst, e); alloc_reg(pc, iv); - inst[0] |= (iv->hw << 9); + e->inst[0] |= (iv->hw << 9); alloc_reg(pc, src); - inst[0] |= (src->hw << 16); + e->inst[0] |= (src->hw << 16); if (noperspective) - inst[0] |= (1 << 25); + e->inst[0] |= (1 << 25); - emit(pc, inst); + emit(pc, e); } static void -set_cseg(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) +set_cseg(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) { - set_long(pc, inst); + set_long(pc, e); if (src->type == P_IMMD) { - inst[1] |= (NV50_CB_PMISC << 22); + e->inst[1] |= (NV50_CB_PMISC << 22); } else { if (pc->p->type == PIPE_SHADER_VERTEX) - inst[1] |= (NV50_CB_PVP << 22); + e->inst[1] |= (NV50_CB_PVP << 22); else - inst[1] |= (NV50_CB_PFP << 22); + e->inst[1] |= (NV50_CB_PFP << 22); } } static void emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - inst[0] |= 0x10000000; + e->inst[0] |= 0x10000000; - set_dst(pc, dst, inst); + set_dst(pc, dst, e); if (dst->type != P_RESULT && src->type == P_IMMD) { - set_immd(pc, src, inst); + set_immd(pc, src, e); /*XXX: 32-bit, but steals part of "half" reg space - need to * catch and handle this case if/when we do half-regs */ - inst[0] |= 0x00008000; + e->inst[0] |= 0x00008000; } else if (src->type == P_IMMD || src->type == P_CONST) { - set_long(pc, inst); - set_cseg(pc, src, inst); - inst[0] |= (src->hw << 9); - inst[1] |= 0x20000000; /* src0 const? */ + set_long(pc, e); + set_cseg(pc, src, e); + e->inst[0] |= (src->hw << 9); + e->inst[1] |= 0x20000000; /* src0 const? */ } else { if (src->type == P_ATTR) { - set_long(pc, inst); - inst[1] |= 0x00200000; + set_long(pc, e); + e->inst[1] |= 0x00200000; } alloc_reg(pc, src); - inst[0] |= (src->hw << 9); + e->inst[0] |= (src->hw << 9); } /* We really should support "half" instructions here at some point, * but I don't feel confident enough about them yet. */ - set_long(pc, inst); - if (is_long(inst) && !is_immd(inst)) { - inst[1] |= 0x04000000; /* 32-bit */ - inst[1] |= 0x0003c000; /* "subsubop" 0xf == mov */ + set_long(pc, e); + if (is_long(e) && !is_immd(e)) { + e->inst[1] |= 0x04000000; /* 32-bit */ + e->inst[1] |= 0x0003c000; /* "subsubop" 0xf == mov */ } - emit(pc, inst); + emit(pc, e); } static boolean @@ -385,11 +392,11 @@ check_swap_src_0_1(struct nv50_pc *pc, } static void -set_src_0(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) +set_src_0(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) { if (src->type == P_ATTR) { - set_long(pc, inst); - inst[1] |= 0x00200000; + set_long(pc, e); + e->inst[1] |= 0x00200000; } else if (src->type == P_CONST || src->type == P_IMMD) { struct nv50_reg *temp = temp_temp(pc); @@ -399,11 +406,11 @@ set_src_0(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) } alloc_reg(pc, src); - inst[0] |= (src->hw << 9); + e->inst[0] |= (src->hw << 9); } static void -set_src_1(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) +set_src_1(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) { if (src->type == P_ATTR) { struct nv50_reg *temp = temp_temp(pc); @@ -412,26 +419,26 @@ set_src_1(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) src = temp; } else if (src->type == P_CONST || src->type == P_IMMD) { - assert(!(inst[0] & 0x00800000)); - if (inst[0] & 0x01000000) { + assert(!(e->inst[0] & 0x00800000)); + if (e->inst[0] & 0x01000000) { struct nv50_reg *temp = temp_temp(pc); emit_mov(pc, temp, src); src = temp; } else { - set_cseg(pc, src, inst); - inst[0] |= 0x00800000; + set_cseg(pc, src, e); + e->inst[0] |= 0x00800000; } } alloc_reg(pc, src); - inst[0] |= (src->hw << 16); + e->inst[0] |= (src->hw << 16); } static void -set_src_2(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) +set_src_2(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) { - set_long(pc, inst); + set_long(pc, e); if (src->type == P_ATTR) { struct nv50_reg *temp = temp_temp(pc); @@ -440,186 +447,186 @@ set_src_2(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst) src = temp; } else if (src->type == P_CONST || src->type == P_IMMD) { - assert(!(inst[0] & 0x01000000)); - if (inst[0] & 0x00800000) { + assert(!(e->inst[0] & 0x01000000)); + if (e->inst[0] & 0x00800000) { struct nv50_reg *temp = temp_temp(pc); emit_mov(pc, temp, src); src = temp; } else { - set_cseg(pc, src, inst); - inst[0] |= 0x01000000; + set_cseg(pc, src, e); + e->inst[0] |= 0x01000000; } } alloc_reg(pc, src); - inst[1] |= (src->hw << 14); + e->inst[1] |= (src->hw << 14); } static void emit_mul(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, struct nv50_reg *src1) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - inst[0] |= 0xc0000000; - set_long(pc, inst); + e->inst[0] |= 0xc0000000; + set_long(pc, e); check_swap_src_0_1(pc, &src0, &src1); - set_dst(pc, dst, inst); - set_src_0(pc, src0, inst); - set_src_1(pc, src1, inst); + set_dst(pc, dst, e); + set_src_0(pc, src0, e); + set_src_1(pc, src1, e); - emit(pc, inst); + emit(pc, e); } static void emit_add(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, struct nv50_reg *src1) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - inst[0] |= 0xb0000000; + e->inst[0] |= 0xb0000000; check_swap_src_0_1(pc, &src0, &src1); - set_dst(pc, dst, inst); - set_src_0(pc, src0, inst); - if (is_long(inst)) - set_src_2(pc, src1, inst); + set_dst(pc, dst, e); + set_src_0(pc, src0, e); + if (is_long(e)) + set_src_2(pc, src1, e); else - set_src_1(pc, src1, inst); + set_src_1(pc, src1, e); - emit(pc, inst); + emit(pc, e); } static void emit_minmax(struct nv50_pc *pc, unsigned sub, struct nv50_reg *dst, struct nv50_reg *src0, struct nv50_reg *src1) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - set_long(pc, inst); - inst[0] |= 0xb0000000; - inst[1] |= (sub << 29); + set_long(pc, e); + e->inst[0] |= 0xb0000000; + e->inst[1] |= (sub << 29); check_swap_src_0_1(pc, &src0, &src1); - set_dst(pc, dst, inst); - set_src_0(pc, src0, inst); - set_src_1(pc, src1, inst); + set_dst(pc, dst, e); + set_src_0(pc, src0, e); + set_src_1(pc, src1, e); - emit(pc, inst); + emit(pc, e); } static void emit_sub(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, struct nv50_reg *src1) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - inst[0] |= 0xb0000000; + e->inst[0] |= 0xb0000000; - set_long(pc, inst); + set_long(pc, e); if (check_swap_src_0_1(pc, &src0, &src1)) - inst[1] |= 0x04000000; + e->inst[1] |= 0x04000000; else - inst[1] |= 0x08000000; + e->inst[1] |= 0x08000000; - set_dst(pc, dst, inst); - set_src_0(pc, src0, inst); - set_src_2(pc, src1, inst); + set_dst(pc, dst, e); + set_src_0(pc, src0, e); + set_src_2(pc, src1, e); - emit(pc, inst); + emit(pc, e); } static void emit_mad(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, struct nv50_reg *src1, struct nv50_reg *src2) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - inst[0] |= 0xe0000000; + e->inst[0] |= 0xe0000000; check_swap_src_0_1(pc, &src0, &src1); - set_dst(pc, dst, inst); - set_src_0(pc, src0, inst); - set_src_1(pc, src1, inst); - set_src_2(pc, src2, inst); + set_dst(pc, dst, e); + set_src_0(pc, src0, e); + set_src_1(pc, src1, e); + set_src_2(pc, src2, e); - emit(pc, inst); + emit(pc, e); } static void emit_msb(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0, struct nv50_reg *src1, struct nv50_reg *src2) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - inst[0] |= 0xe0000000; - set_long(pc, inst); - inst[1] |= 0x08000000; /* src0 * src1 - src2 */ + e->inst[0] |= 0xe0000000; + set_long(pc, e); + e->inst[1] |= 0x08000000; /* src0 * src1 - src2 */ check_swap_src_0_1(pc, &src0, &src1); - set_dst(pc, dst, inst); - set_src_0(pc, src0, inst); - set_src_1(pc, src1, inst); - set_src_2(pc, src2, inst); + set_dst(pc, dst, e); + set_src_0(pc, src0, e); + set_src_1(pc, src1, e); + set_src_2(pc, src2, e); - emit(pc, inst); + emit(pc, e); } static void emit_flop(struct nv50_pc *pc, unsigned sub, struct nv50_reg *dst, struct nv50_reg *src) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - inst[0] |= 0x90000000; + e->inst[0] |= 0x90000000; if (sub) { - set_long(pc, inst); - inst[1] |= (sub << 29); + set_long(pc, e); + e->inst[1] |= (sub << 29); } - set_dst(pc, dst, inst); - set_src_0(pc, src, inst); + set_dst(pc, dst, e); + set_src_0(pc, src, e); - emit(pc, inst); + emit(pc, e); } static void emit_preex2(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - inst[0] |= 0xb0000000; + e->inst[0] |= 0xb0000000; - set_dst(pc, dst, inst); - set_src_0(pc, src, inst); - set_long(pc, inst); - inst[1] |= (6 << 29) | 0x00004000; + set_dst(pc, dst, e); + set_src_0(pc, src, e); + set_long(pc, e); + e->inst[1] |= (6 << 29) | 0x00004000; - emit(pc, inst); + emit(pc, e); } static void emit_precossin(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - inst[0] |= 0xb0000000; + e->inst[0] |= 0xb0000000; - set_dst(pc, dst, inst); - set_src_0(pc, src, inst); - set_long(pc, inst); - inst[1] |= (6 << 29); + set_dst(pc, dst, e); + set_src_0(pc, src, e); + set_long(pc, e); + e->inst[1] |= (6 << 29); - emit(pc, inst); + emit(pc, e); } static void emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst, struct nv50_reg *src0, struct nv50_reg *src1) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); unsigned inv_cop[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; struct nv50_reg *rdst; @@ -632,26 +639,27 @@ emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst, dst = alloc_temp(pc, NULL); /* set.u32 */ - set_long(pc, inst); - inst[0] |= 0xb0000000; - inst[1] |= (3 << 29); - inst[1] |= (c_op << 14); + set_long(pc, e); + e->inst[0] |= 0xb0000000; + e->inst[1] |= (3 << 29); + e->inst[1] |= (c_op << 14); /*XXX: breaks things, .u32 by default? * decuda will disasm as .u16 and use .lo/.hi regs, but this * doesn't seem to match what the hw actually does. inst[1] |= 0x04000000; << breaks things.. .u32 by default? */ - set_dst(pc, dst, inst); - set_src_0(pc, src0, inst); - set_src_1(pc, src1, inst); - emit(pc, inst); + set_dst(pc, dst, e); + set_src_0(pc, src0, e); + set_src_1(pc, src1, e); + emit(pc, e); /* cvt.f32.u32 */ - inst[0] = 0xa0000001; - inst[1] = 0x64014780; - set_dst(pc, rdst, inst); - set_src_0(pc, dst, inst); - emit(pc, inst); + e = exec(pc); + e->inst[0] = 0xa0000001; + e->inst[1] = 0x64014780; + set_dst(pc, rdst, e); + set_src_0(pc, dst, e); + emit(pc, e); if (dst != rdst) free_temp(pc, dst); @@ -660,19 +668,19 @@ emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst, static void emit_flr(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { - unsigned inst[2] = { 0, 0 }; - - inst[0] = 0xa0000000; /* cvt */ - set_long(pc, inst); - inst[1] |= (6 << 29); /* cvt */ - inst[1] |= 0x08000000; /* integer mode */ - inst[1] |= 0x04000000; /* 32 bit */ - inst[1] |= ((0x1 << 3)) << 14; /* .rn */ - inst[1] |= (1 << 14); /* src .f32 */ - set_dst(pc, dst, inst); - set_src_0(pc, src, inst); - - emit(pc, inst); + struct nv50_program_exec *e = exec(pc); + + e->inst[0] = 0xa0000000; /* cvt */ + set_long(pc, e); + e->inst[1] |= (6 << 29); /* cvt */ + e->inst[1] |= 0x08000000; /* integer mode */ + e->inst[1] |= 0x04000000; /* 32 bit */ + e->inst[1] |= ((0x1 << 3)) << 14; /* .rn */ + e->inst[1] |= (1 << 14); /* src .f32 */ + set_dst(pc, dst, e); + set_src_0(pc, src, e); + + emit(pc, e); } static void @@ -692,18 +700,18 @@ emit_pow(struct nv50_pc *pc, struct nv50_reg *dst, static void emit_abs(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { - unsigned inst[2] = { 0, 0 }; - - inst[0] = 0xa0000000; /* cvt */ - set_long(pc, inst); - inst[1] |= (6 << 29); /* cvt */ - inst[1] |= 0x04000000; /* 32 bit */ - inst[1] |= (1 << 14); /* src .f32 */ - inst[1] |= ((1 << 6) << 14); /* .abs */ - set_dst(pc, dst, inst); - set_src_0(pc, src, inst); - - emit(pc, inst); + struct nv50_program_exec *e = exec(pc); + + e->inst[0] = 0xa0000000; /* cvt */ + set_long(pc, e); + e->inst[1] |= (6 << 29); /* cvt */ + e->inst[1] |= 0x04000000; /* 32 bit */ + e->inst[1] |= (1 << 14); /* src .f32 */ + e->inst[1] |= ((1 << 6) << 14); /* .abs */ + set_dst(pc, dst, e); + set_src_0(pc, src, e); + + emit(pc, e); } static void @@ -731,7 +739,7 @@ emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask, } if (mask & (1 << 2)) { - set_pred_wr(pc, 1, 0, &pc->p->insns[pc->p->insns_nr - 2]); + set_pred_wr(pc, 1, 0, pc->p->exec_tail); tmp[1] = temp_temp(pc); emit_minmax(pc, 4, tmp[1], src[1], zero); @@ -742,24 +750,24 @@ emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask, emit_pow(pc, dst[2], tmp[1], tmp[3]); emit_mov(pc, dst[2], zero); - set_pred(pc, 3, 0, &pc->p->insns[pc->p->insns_nr - 2]); + set_pred(pc, 3, 0, pc->p->exec_tail); } } static void emit_neg(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e = exec(pc); - set_long(pc, inst); - inst[0] |= 0xa0000000; /* delta */ - inst[1] |= (7 << 29); /* delta */ - inst[1] |= 0x04000000; /* negate arg0? probably not */ - inst[1] |= (1 << 14); /* src .f32 */ - set_dst(pc, dst, inst); - set_src_0(pc, src, inst); + set_long(pc, e); + e->inst[0] |= 0xa0000000; /* delta */ + e->inst[1] |= (7 << 29); /* delta */ + e->inst[1] |= 0x04000000; /* negate arg0? probably not */ + e->inst[1] |= (1 << 14); /* src .f32 */ + set_dst(pc, dst, e); + set_src_0(pc, src, e); - emit(pc, inst); + emit(pc, e); } static struct nv50_reg * @@ -1132,20 +1140,21 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) if (sat) { for (c = 0; c < 4; c++) { - unsigned inst[2] = { 0, 0 }; + struct nv50_program_exec *e; if (!(mask & (1 << c))) continue; - - inst[0] = 0xa0000000; /* cvt */ - set_long(pc, inst); - inst[1] |= (6 << 29); /* cvt */ - inst[1] |= 0x04000000; /* 32 bit */ - inst[1] |= (1 << 14); /* src .f32 */ - inst[1] |= ((1 << 5) << 14); /* .sat */ - set_dst(pc, rdst[c], inst); - set_src_0(pc, dst[c], inst); - emit(pc, inst); + e = exec(pc); + + e->inst[0] = 0xa0000000; /* cvt */ + set_long(pc, e); + e->inst[1] |= (6 << 29); /* cvt */ + e->inst[1] |= 0x04000000; /* 32 bit */ + e->inst[1] |= (1 << 14); /* src .f32 */ + e->inst[1] |= ((1 << 5) << 14); /* .sat */ + set_dst(pc, rdst[c], e); + set_src_0(pc, dst[c], e); + emit(pc, e); } } @@ -1384,6 +1393,9 @@ nv50_program_tx(struct nv50_program *p) emit_mov(pc, &out, &pc->result[out.hw]); } + assert(is_long(pc->p->exec_tail) && !is_immd(pc->p->exec_head)); + pc->p->exec_tail->inst[1] |= 0x00000001; + p->immd_nr = pc->immd_nr * 4; p->immd = pc->immd_buf; @@ -1397,20 +1409,17 @@ out_cleanup: static void nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) { - int i; + struct nv50_program_exec *e; if (nv50_program_tx(p) == FALSE) assert(0); - /* *not* sufficient, it's fine if last inst is long and - * NOT immd - otherwise it's fucked fucked fucked */ - p->insns[p->insns_nr - 1] |= 0x00000001; - if (p->type == PIPE_SHADER_VERTEX) { - for (i = 0; i < p->insns_nr; i++) - NOUVEAU_ERR("VP0x%08x\n", p->insns[i]); - } else { - for (i = 0; i < p->insns_nr; i++) - NOUVEAU_ERR("FP0x%08x\n", p->insns[i]); + e = p->exec_head; + while (e) { + NOUVEAU_ERR("0x%08x\n", e->inst[0]); + if (is_long(e)) + NOUVEAU_ERR("0x%08x\n", e->inst[1]); + e = e->next; } p->translated = TRUE; @@ -1432,12 +1441,18 @@ static void nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) { struct pipe_winsys *ws = nv50->pipe.winsys; - void *map; + struct nv50_program_exec *e; + unsigned *map; if (!p->buffer) - p->buffer = ws->buffer_create(ws, 0x100, 0, p->insns_nr * 4); + p->buffer = ws->buffer_create(ws, 0x100, 0, p->exec_size * 4); + map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); - memcpy(map, p->insns, p->insns_nr * 4); + for (e = p->exec_head; e; e = e->next) { + *(map++) = e->inst[0]; + if (is_long(e)) + *(map++) = e->inst[1]; + } ws->buffer_unmap(ws, p->buffer); } @@ -1519,11 +1534,14 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) { struct pipe_winsys *ws = nv50->pipe.winsys; - if (p->insns_nr) { - if (p->insns) - FREE(p->insns); - p->insns_nr = 0; + while (p->exec_head) { + struct nv50_program_exec *e = p->exec_head; + + p->exec_head = e->next; + FREE(e); } + p->exec_tail = NULL; + p->exec_size = 0; if (p->buffer) pipe_buffer_reference(ws, &p->buffer, NULL); diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h index dd5aed799a..6dafe56fbb 100644 --- a/src/gallium/drivers/nv50/nv50_program.h +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -10,22 +10,36 @@ struct nv50_program_data { float value; }; +struct nv50_program_exec { + struct nv50_program_exec *next; + + unsigned inst[2]; + struct { + int index; + unsigned mask; + unsigned shift; + } param; +}; + struct nv50_program { struct pipe_shader_state pipe; struct tgsi_shader_info info; boolean translated; unsigned type; - unsigned *insns; - unsigned insns_nr; + struct nv50_program_exec *exec_head; + struct nv50_program_exec *exec_tail; + unsigned exec_size; + struct nv50_program_data *data; + struct nouveau_resource *data_res; + unsigned data_nr; + unsigned data_start; struct pipe_buffer *buffer; float *immd; unsigned immd_nr; - struct nouveau_resource *data; - struct { unsigned high_temp; struct { -- cgit v1.2.3 From 1c7489bd7e5391136d0f2e68b467de89eb2d2bfc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 12:26:43 +1000 Subject: nv50: allow relocating a shader's constants at upload time --- src/gallium/drivers/nv50/nv50_program.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 3df3848761..6c5aeb237d 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -201,6 +201,7 @@ exec(struct nv50_pc *pc) { struct nv50_program_exec *e = CALLOC_STRUCT(nv50_program_exec); + e->param.index = -1; return e; } @@ -311,7 +312,8 @@ emit_interp(struct nv50_pc *pc, struct nv50_reg *dst, } static void -set_cseg(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) +set_data(struct nv50_pc *pc, struct nv50_reg *src, unsigned m, unsigned s, + struct nv50_program_exec *e) { set_long(pc, e); if (src->type == P_IMMD) { @@ -322,6 +324,10 @@ set_cseg(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) else e->inst[1] |= (NV50_CB_PFP << 22); } + + e->param.index = src->hw; + e->param.shift = s; + e->param.mask = m << (s % 32); } static void @@ -342,8 +348,7 @@ emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) } else if (src->type == P_IMMD || src->type == P_CONST) { set_long(pc, e); - set_cseg(pc, src, e); - e->inst[0] |= (src->hw << 9); + set_data(pc, src, 0x7f, 9, e); e->inst[1] |= 0x20000000; /* src0 const? */ } else { if (src->type == P_ATTR) { @@ -426,7 +431,7 @@ set_src_1(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) emit_mov(pc, temp, src); src = temp; } else { - set_cseg(pc, src, e); + set_data(pc, src, 0x7f, 16, e); e->inst[0] |= 0x00800000; } } @@ -454,7 +459,7 @@ set_src_2(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) emit_mov(pc, temp, src); src = temp; } else { - set_cseg(pc, src, e); + set_data(pc, src, 0x7f, 32+14, e); e->inst[0] |= 0x01000000; } } @@ -1449,6 +1454,12 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); for (e = p->exec_head; e; e = e->next) { + if (e->param.index >= 0) { + e->inst[e->param.shift / 32] &= ~e->param.mask; + e->inst[e->param.shift / 32] |= (e->param.index << + e->param.shift); + } + *(map++) = e->inst[0]; if (is_long(e)) *(map++) = e->inst[1]; -- cgit v1.2.3 From aea1669ff221f97682f0be6a60632e40c2739d09 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 12:39:35 +1000 Subject: nv50: use constbuf segment 0 for everything - I can't make the others work.. --- src/gallium/drivers/nv50/nv50_program.c | 70 ++++++++++++++++++++++++++------- src/gallium/drivers/nv50/nv50_program.h | 11 +----- 2 files changed, 57 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 6c5aeb237d..cbbecafb02 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -10,6 +10,7 @@ #include "nv50_context.h" #define NV50_SU_MAX_TEMP 64 +#define NV50_PROGRAM_DUMP /* ARL - gallium craps itself on progs/vp/arl.txt * @@ -316,6 +317,9 @@ set_data(struct nv50_pc *pc, struct nv50_reg *src, unsigned m, unsigned s, struct nv50_program_exec *e) { set_long(pc, e); +#if 1 + e->inst[1] |= (1 << 22); +#else if (src->type == P_IMMD) { e->inst[1] |= (NV50_CB_PMISC << 22); } else { @@ -324,6 +328,7 @@ set_data(struct nv50_pc *pc, struct nv50_reg *src, unsigned m, unsigned s, else e->inst[1] |= (NV50_CB_PFP << 22); } +#endif e->param.index = src->hw; e->param.shift = s; @@ -1335,7 +1340,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) } if (pc->immd_nr) { - int rid = 0; + int rid = pc->param_nr * 4; pc->immd = calloc(pc->immd_nr * 4, sizeof(struct nv50_reg)); if (!pc->immd) @@ -1401,6 +1406,7 @@ nv50_program_tx(struct nv50_program *p) assert(is_long(pc->p->exec_tail) && !is_immd(pc->p->exec_head)); pc->p->exec_tail->inst[1] |= 0x00000001; + p->param_nr = pc->param_nr * 4; p->immd_nr = pc->immd_nr * 4; p->immd = pc->immd_buf; @@ -1418,26 +1424,47 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) if (nv50_program_tx(p) == FALSE) assert(0); - - e = p->exec_head; - while (e) { - NOUVEAU_ERR("0x%08x\n", e->inst[0]); - if (is_long(e)) - NOUVEAU_ERR("0x%08x\n", e->inst[1]); - e = e->next; - } - p->translated = TRUE; } static void nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) { + struct nouveau_winsys *nvws = nv50->screen->nvws; + struct pipe_winsys *ws = nv50->pipe.winsys; + unsigned nr = p->param_nr + p->immd_nr; int i; + if (!p->data && nr) { + struct nouveau_resource *heap = nv50->screen->vp_data_heap; + + if (nvws->res_alloc(heap, nr, p, &p->data)) { + while (heap->next && heap->size < nr) { + struct nv50_program *evict = heap->next->priv; + nvws->res_free(&evict->data); + } + + if (nvws->res_alloc(heap, nr, p, &p->data)) + assert(0); + } + } + + if (p->param_nr) { + float *map = ws->buffer_map(ws, nv50->constbuf[p->type], + PIPE_BUFFER_USAGE_CPU_READ); + for (i = 0; i < p->param_nr; i++) { + BEGIN_RING(tesla, 0x0f00, 2); + OUT_RING ((NV50_CB_PMISC << 0) | + ((p->data->start + i) << 8)); + OUT_RING (fui(map[i])); + } + ws->buffer_unmap(ws, nv50->constbuf[p->type]); + } + for (i = 0; i < p->immd_nr; i++) { BEGIN_RING(tesla, 0x0f00, 2); - OUT_RING ((NV50_CB_PMISC << 0) | (i << 8)); + OUT_RING ((NV50_CB_PMISC << 0) | + ((p->data_start + p->param_nr + i) << 8)); OUT_RING (fui(p->immd[i])); } } @@ -1452,17 +1479,30 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) if (!p->buffer) p->buffer = ws->buffer_create(ws, 0x100, 0, p->exec_size * 4); - map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); - for (e = p->exec_head; e; e = e->next) { - if (e->param.index >= 0) { + if (p->data && p->data->start != p->data_start) { + for (e = p->exec_head; e; e = e->next) { + if (e->param.index < 0) + continue; e->inst[e->param.shift / 32] &= ~e->param.mask; e->inst[e->param.shift / 32] |= (e->param.index << e->param.shift); } + p->data_start = p->data->start; + } + + map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + for (e = p->exec_head; e; e = e->next) { +#ifdef NV50_PROGRAM_DUMP + NOUVEAU_ERR("0x%08x\n", e->inst[0]); +#endif *(map++) = e->inst[0]; - if (is_long(e)) + if (is_long(e)) { +#ifdef NV50_PROGRAM_DUMP + NOUVEAU_ERR("0x%08x\n", e->inst[1]); +#endif *(map++) = e->inst[1]; + } } ws->buffer_unmap(ws, p->buffer); } diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h index 6dafe56fbb..d143ae9797 100644 --- a/src/gallium/drivers/nv50/nv50_program.h +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -4,12 +4,6 @@ #include "pipe/p_state.h" #include "tgsi/util/tgsi_scan.h" -struct nv50_program_data { - int index; - int component; - float value; -}; - struct nv50_program_exec { struct nv50_program_exec *next; @@ -30,15 +24,14 @@ struct nv50_program { struct nv50_program_exec *exec_head; struct nv50_program_exec *exec_tail; unsigned exec_size; - struct nv50_program_data *data; - struct nouveau_resource *data_res; - unsigned data_nr; + struct nouveau_resource *data; unsigned data_start; struct pipe_buffer *buffer; float *immd; unsigned immd_nr; + unsigned param_nr; struct { unsigned high_temp; -- cgit v1.2.3 From ab3d55e2e3578db8deba84dcf47a024071486bd8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 13:11:41 +1000 Subject: nv50: more efficient const upload + fixes (fp/* works now!) --- src/gallium/drivers/nv50/nv50_program.c | 48 +++++++++++++++++++++------------ src/gallium/drivers/nv50/nv50_screen.c | 4 +-- 2 files changed, 33 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index cbbecafb02..4c41e5a7c2 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1420,20 +1420,35 @@ out_cleanup: static void nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p) { - struct nv50_program_exec *e; - if (nv50_program_tx(p) == FALSE) assert(0); p->translated = TRUE; } +static void +nv50_program_upload_data(struct nv50_context *nv50, float *map, + unsigned start, unsigned count) +{ + while (count) { + unsigned nr = count > 2047 ? 2047 : count; + + BEGIN_RING(tesla, 0x00000f00, 1); + OUT_RING ((NV50_CB_PMISC << 0) | (start << 8)); + BEGIN_RING(tesla, 0x40000f04, nr); + OUT_RINGp (map, nr); + + map += nr; + start += nr; + count -= nr; + } +} + static void nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) { struct nouveau_winsys *nvws = nv50->screen->nvws; struct pipe_winsys *ws = nv50->pipe.winsys; unsigned nr = p->param_nr + p->immd_nr; - int i; if (!p->data && nr) { struct nouveau_resource *heap = nv50->screen->vp_data_heap; @@ -1452,20 +1467,15 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) if (p->param_nr) { float *map = ws->buffer_map(ws, nv50->constbuf[p->type], PIPE_BUFFER_USAGE_CPU_READ); - for (i = 0; i < p->param_nr; i++) { - BEGIN_RING(tesla, 0x0f00, 2); - OUT_RING ((NV50_CB_PMISC << 0) | - ((p->data->start + i) << 8)); - OUT_RING (fui(map[i])); - } + nv50_program_upload_data(nv50, map, p->data->start, + p->param_nr); ws->buffer_unmap(ws, nv50->constbuf[p->type]); } - for (i = 0; i < p->immd_nr; i++) { - BEGIN_RING(tesla, 0x0f00, 2); - OUT_RING ((NV50_CB_PMISC << 0) | - ((p->data_start + p->param_nr + i) << 8)); - OUT_RING (fui(p->immd[i])); + if (p->immd_nr) { + nv50_program_upload_data(nv50, p->immd, + p->data->start + p->param_nr, + p->immd_nr); } } @@ -1481,11 +1491,15 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) if (p->data && p->data->start != p->data_start) { for (e = p->exec_head; e; e = e->next) { + unsigned ei, ci; + if (e->param.index < 0) continue; - e->inst[e->param.shift / 32] &= ~e->param.mask; - e->inst[e->param.shift / 32] |= (e->param.index << - e->param.shift); + ei = e->param.shift >> 5; + ci = e->param.index + p->data->start; + + e->inst[ei] &= ~e->param.mask; + e->inst[ei] |= (ci << e->param.shift); } p->data_start = p->data->start; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 2417bf8001..5f10fe2e44 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -229,8 +229,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, 8); /* Shared constant buffer */ - screen->constbuf = ws->buffer_create(ws, 0, 0, 256 * 4 * 4); - if (nvws->res_init(&screen->vp_data_heap, 0, 256)) { + screen->constbuf = ws->buffer_create(ws, 0, 0, 128 * 4 * 4); + if (nvws->res_init(&screen->vp_data_heap, 0, 128)) { NOUVEAU_ERR("Error initialising constant buffer\n"); nv50_screen_destroy(&screen->pipe); return NULL; -- cgit v1.2.3 From f700d6be6335a4d4394296891f783687b6f2d4f2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 13:50:56 +1000 Subject: nv50: remove some cruft, don't upload program unless really needed --- src/gallium/drivers/nv50/nv50_program.c | 9 ++++++- src/gallium/drivers/nv50/nv50_state_validate.c | 33 ++------------------------ 2 files changed, 10 insertions(+), 32 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 4c41e5a7c2..f71aa19312 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1484,10 +1484,13 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) { struct pipe_winsys *ws = nv50->pipe.winsys; struct nv50_program_exec *e; + boolean upload = FALSE; unsigned *map; - if (!p->buffer) + if (!p->buffer) { p->buffer = ws->buffer_create(ws, 0x100, 0, p->exec_size * 4); + upload = TRUE; + } if (p->data && p->data->start != p->data_start) { for (e = p->exec_head; e; e = e->next) { @@ -1503,8 +1506,12 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) } p->data_start = p->data->start; + upload = TRUE; } + if (!upload) + return FALSE; + map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); for (e = p->exec_head; e; e = e->next) { #ifdef NV50_PROGRAM_DUMP diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 05395c6df7..5f2244e3e8 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -114,10 +114,10 @@ nv50_state_validate(struct nv50_context *nv50) if (nv50->dirty & NV50_NEW_ZSA) so_emit(nvws, nv50->zsa->so); - if (nv50->dirty & NV50_NEW_VERTPROG) + if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB)) nv50_vertprog_validate(nv50); - if (nv50->dirty & NV50_NEW_FRAGPROG) + if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB)) nv50_fragprog_validate(nv50); if (nv50->dirty & NV50_NEW_RASTERIZER) @@ -168,35 +168,6 @@ nv50_state_validate(struct nv50_context *nv50) so_ref(NULL, &so); } - if (nv50->dirty & NV50_NEW_VERTPROG_CB) { - so = so_new(4, 2); - so_method(so, tesla, 0x1280, 3); - so_reloc (so, nv50->constbuf[PIPE_SHADER_VERTEX], 0, - NOUVEAU_BO_HIGH | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, - 0, 0); - so_reloc (so, nv50->constbuf[PIPE_SHADER_VERTEX], 0, - NOUVEAU_BO_LOW | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, - 0, 0); - so_data (so, (NV50_CB_PVP << 16) | 0x1000); - so_emit(nvws, so); - so_ref(NULL, &so); - } - - if (nv50->dirty & NV50_NEW_FRAGPROG_CB) { - so = so_new(4, 2); - so_method(so, tesla, 0x1280, 3); - so_reloc (so, nv50->constbuf[PIPE_SHADER_FRAGMENT], 0, - NOUVEAU_BO_HIGH | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, - 0, 0); - so_reloc (so, nv50->constbuf[PIPE_SHADER_FRAGMENT], 0, - NOUVEAU_BO_LOW | NOUVEAU_BO_RD | NOUVEAU_BO_VRAM, - 0, 0); - so_data (so, (NV50_CB_PFP << 16) | 0x1000); - so_emit(nvws, so); - so_ref(NULL, &so); - } - - if (nv50->dirty & NV50_NEW_ARRAYS) nv50_vbo_validate(nv50); -- cgit v1.2.3 From 163d9aa1fe33612e7806549e47b257b61ca5045e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 13:59:51 +1000 Subject: nv50: support a couple more common VBO formats --- src/gallium/drivers/nv50/nv50_vbo.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 140d60cc9a..74519489f7 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -82,9 +82,15 @@ nv50_vbo_validate(struct nv50_context *nv50) &nv50->vtxbuf[ve->vertex_buffer_index]; switch (ve->src_format) { + case PIPE_FORMAT_R32G32B32A32_FLOAT: + so_data(vtxfmt, 0x7e080000 | i); + break; case PIPE_FORMAT_R32G32B32_FLOAT: so_data(vtxfmt, 0x7e100000 | i); break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + so_data(vtxfmt, 0x24500000 | i); + break; default: { char fmt[128]; -- cgit v1.2.3 From 027ed25c12f69b39e205d3bbd26b68e9a02bea81 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 14:15:38 +1000 Subject: nv50: draw_elements() - inline only for the moment --- src/gallium/drivers/nv50/nv50_vbo.c | 96 ++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 74519489f7..586a6c49de 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -52,16 +52,110 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, return TRUE; } +static INLINE void +nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map, + unsigned start, unsigned count) +{ + map += start; + + if (count & 1) { + BEGIN_RING(tesla, 0x15e8, 1); + OUT_RING (map[0]); + map++; + count--; + } + + while (count) { + unsigned nr = count > 2046 ? 2046 : count; + int i; + + BEGIN_RING(tesla, 0x400015f0, nr >> 1); + for (i = 0; i < nr; i += 2) + OUT_RING ((map[1] << 16) | map[0]); + + count -= nr; + map += nr; + } +} + +static INLINE void +nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map, + unsigned start, unsigned count) +{ + map += start; + + if (count & 1) { + BEGIN_RING(tesla, 0x15e8, 1); + OUT_RING (map[0]); + map++; + count--; + } + + while (count) { + unsigned nr = count > 2046 ? 2046 : count; + int i; + + BEGIN_RING(tesla, 0x400015f0, nr >> 1); + for (i = 0; i < nr; i += 2) + OUT_RING ((map[1] << 16) | map[0]); + + count -= nr; + map += nr; + } +} + +static INLINE void +nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint8_t *map, + unsigned start, unsigned count) +{ + map += start; + + while (count) { + unsigned nr = count > 2047 ? 2047 : count; + + BEGIN_RING(tesla, 0x400015e8, nr); + OUT_RINGp (map, nr); + + count -= nr; + map += nr; + } +} + 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); + struct pipe_winsys *ws = pipe->winsys; + void *map = ws->buffer_map(ws, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ); nv50_state_validate(nv50); - NOUVEAU_ERR("unimplemented\n"); + BEGIN_RING(tesla, 0x142c, 1); + OUT_RING (0); + BEGIN_RING(tesla, 0x142c, 1); + OUT_RING (0); + + BEGIN_RING(tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (nv50_prim(mode)); + switch (indexSize) { + case 1: + nv50_draw_elements_inline_u08(nv50, map, start, count); + break; + case 2: + nv50_draw_elements_inline_u16(nv50, map, start, count); + break; + case 4: + nv50_draw_elements_inline_u32(nv50, map, start, count); + break; + default: + assert(0); + } + BEGIN_RING(tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (0); + + pipe->flush(pipe, 0, NULL); return TRUE; } -- cgit v1.2.3 From 619549a6377a58d54c9cf55f8863beed56b09566 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 14:21:28 +1000 Subject: nv50: valgrind complaint --- src/gallium/drivers/nv50/nv50_program.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index f71aa19312..af5ca84c8e 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -146,8 +146,10 @@ static void free_temp(struct nv50_pc *pc, struct nv50_reg *r) { if (r->index == -1) { - FREE(pc->r_temp[r->hw]); - pc->r_temp[r->hw] = NULL; + unsigned hw = r->hw; + + FREE(pc->r_temp[hw]); + pc->r_temp[hw] = NULL; } } -- cgit v1.2.3 From 4bde3a72ab0b4246cd779a6d1e2a72943f25c0f6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 14:40:20 +1000 Subject: nv50: fix blend cso --- src/gallium/drivers/nv50/nv50_state.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index ed6cca9a0d..b56a3992bc 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -29,12 +29,12 @@ nv50_blend_state_create(struct pipe_context *pipe, 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, 0x4000 | nvgl_blend_func(cso->rgb_src_factor)); + so_data (so, 0x4000 | 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_data (so, 0x4000 | 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)); + so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_dst_factor)); } if (cso->logicop_enable == 0 ) { -- cgit v1.2.3 From 4d520e0b76cf54ae8eb5464afc126c6cc5c6bfdc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 14:47:17 +1000 Subject: nv50: another vbo format --- src/gallium/drivers/nv50/nv50_vbo.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 586a6c49de..7a1c2f24ef 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -182,6 +182,9 @@ nv50_vbo_validate(struct nv50_context *nv50) case PIPE_FORMAT_R32G32B32_FLOAT: so_data(vtxfmt, 0x7e100000 | i); break; + case PIPE_FORMAT_R32G32_FLOAT: + so_data(vtxfmt, 0x7e200000 | i); + break; case PIPE_FORMAT_R8G8B8A8_UNORM: so_data(vtxfmt, 0x24500000 | i); break; -- cgit v1.2.3 From 2fdeb4d5a5cc8b93bf885ba646e3a29a68c755ed Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jun 2008 23:49:26 +1000 Subject: nv50: comment on a so-far unseen bug --- src/gallium/drivers/nv50/nv50_program.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index af5ca84c8e..39597c5481 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -22,6 +22,9 @@ * - Maybe even relax restrictions a bit, can't do P_RESULT + P_IMMD, * but can emit to P_TEMP first - then MOV later. NVIDIA does this * + * In ops such as ADD it's possible to construct a bad opcode in the !is_long() + * case, if the emit_src() causes the inst to suddenly become long. + * * Verify half-insns work where expected - and force disable them where they * don't work - MUL has it forcibly disabled atm as it fixes POW.. * -- cgit v1.2.3 From 101305f37f7268354a50b825bcb66894e4a0b777 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 13 Jun 2008 10:58:27 +1000 Subject: nv50: flag to indicate to winsys we want a surface for use as a zeta buffer NVIDIA love to make life difficult.. we need different flags in PTEs for zeta.. yay.. not. --- src/gallium/drivers/nouveau/nouveau_winsys.h | 1 + src/gallium/drivers/nv50/nv50_miptree.c | 13 ++++++++++++- src/gallium/drivers/nv50/nv50_screen.c | 4 ++++ src/gallium/drivers/nv50/nv50_state.c | 4 ++-- src/gallium/drivers/nv50/nv50_state_validate.c | 10 ++++++++++ 5 files changed, 29 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 07a41dcf4a..13810460bf 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -18,6 +18,7 @@ #define NOUVEAU_CAP_HW_IDXBUF (0xbeef0001) #define NOUVEAU_BUFFER_USAGE_TEXTURE (1 << 16) +#define NOUVEAU_BUFFER_USAGE_ZETA (1 << 17) struct nouveau_winsys { struct nouveau_context *nv; diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index be85c3fd5c..459e0ff9dd 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -21,6 +21,7 @@ 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); + unsigned usage; NOUVEAU_ERR("unimplemented\n"); @@ -28,7 +29,17 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) mt->base.refcount = 1; mt->base.screen = pscreen; - mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + usage = PIPE_BUFFER_USAGE_PIXEL; + switch (pt->format) { + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + usage |= NOUVEAU_BUFFER_USAGE_ZETA; + break; + default: + break; + } + + mt->buffer = ws->buffer_create(ws, 256, usage, pt->width[0] * pt->cpp * pt->height[0]); if (!mt->buffer) { FREE(mt); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 5f10fe2e44..d76cce9f79 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -284,6 +284,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, 0xffffffff); } + so_method(so, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR, 2); + so_data (so, fui(0.0)); + so_data (so, fui(1.0)); + so_emit(nvws, so); so_ref(NULL, &so); nvws->push_flush(nvws, 0, NULL); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index b56a3992bc..176ebff5da 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -247,8 +247,8 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, struct nouveau_stateobj *so = so_new(64, 0); so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1); - so_data (so, 0); //cso->depth.writemask ? 1 : 0); - if (0 && cso->depth.enabled) { + 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); diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 5f2244e3e8..a3f399a139 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -70,6 +70,9 @@ nv50_state_validate_fb(struct nv50_context *nv50) case PIPE_FORMAT_Z24S8_UNORM: so_data(so, 0x16); break; + case PIPE_FORMAT_Z16_UNORM: + so_data(so, 0x15); + break; default: { char fmt[128]; @@ -81,6 +84,13 @@ nv50_state_validate_fb(struct nv50_context *nv50) } so_data(so, 0x00000040); so_data(so, 0x00000000); + + so_method(so, tesla, 0x1538, 1); + so_data (so, 1); + so_method(so, tesla, 0x1228, 3); + so_data (so, fb->zsbuf->width); + so_data (so, fb->zsbuf->height); + so_data (so, 0x00010001); } so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2); -- cgit v1.2.3 From 0d7f25c890e1f1505625542c256d4512c065449a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 13 Jun 2008 11:50:13 +1000 Subject: nv50: disable ztest for now - it doesn't work still --- src/gallium/drivers/nv50/nv50_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 176ebff5da..0129b0fb14 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -247,10 +247,10 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, 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); + so_data (so, 0); //cso->depth.writemask ? 1 : 0); if (cso->depth.enabled) { so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1); - so_data (so, 1); + so_data (so, 0); //1); so_method(so, tesla, NV50TCL_DEPTH_TEST_FUNC, 1); so_data (so, nvgl_comparison_op(cso->depth.func)); } else { -- cgit v1.2.3 From c0ed6a871cd3513e17a1fab960f5626485ffed13 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 13 Jun 2008 12:09:46 +1000 Subject: nv50: do tsc/tic upload + stub out shader TEX stuff --- src/gallium/drivers/nv50/nv50_context.h | 17 +++++++++++++ src/gallium/drivers/nv50/nv50_miptree.c | 11 --------- src/gallium/drivers/nv50/nv50_program.c | 6 +++++ src/gallium/drivers/nv50/nv50_screen.c | 1 + src/gallium/drivers/nv50/nv50_state.c | 27 ++++++++++++++++++++- src/gallium/drivers/nv50/nv50_state_validate.c | 33 ++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 19ec492eb3..5214ce1a69 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -44,6 +44,8 @@ #define NV50_NEW_FRAGPROG (1 << 10) #define NV50_NEW_FRAGPROG_CB (1 << 11) #define NV50_NEW_ARRAYS (1 << 12) +#define NV50_NEW_SAMPLER (1 << 13) +#define NV50_NEW_TEXTURE (1 << 14) struct nv50_blend_stateobj { struct pipe_blend_state pipe; @@ -60,6 +62,17 @@ struct nv50_rasterizer_stateobj { struct nouveau_stateobj *so; }; +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; +} + struct nv50_context { struct pipe_context pipe; @@ -84,6 +97,10 @@ struct nv50_context { unsigned vtxbuf_nr; struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; unsigned vtxelt_nr; + unsigned *sampler[PIPE_MAX_SAMPLERS]; + unsigned sampler_nr; + struct nv50_miptree *miptree[PIPE_MAX_SAMPLERS]; + unsigned miptree_nr; }; static INLINE struct nv50_context * diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 459e0ff9dd..cdd98844f9 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -5,17 +5,6 @@ #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) { diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 39597c5481..5eec68e5e1 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -828,6 +828,8 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src) case TGSI_FILE_IMMEDIATE: r = &pc->immd[src->SrcRegister.Index * 4 + c]; break; + case TGSI_FILE_SAMPLER: + break; default: assert(0); break; @@ -1130,6 +1132,8 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_sub(pc, dst[c], src[0][c], src[1][c]); } break; + case TGSI_OPCODE_TEX: + break; case TGSI_OPCODE_XPD: temp = alloc_temp(pc, NULL); if (mask & (1 << 0)) { @@ -1226,6 +1230,8 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (pc->param_nr < (last + 1)) pc->param_nr = last + 1; break; + case TGSI_FILE_SAMPLER: + break; default: NOUVEAU_ERR("bad decl file %d\n", d->Declaration.File); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index d76cce9f79..b9cecb77f1 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -28,6 +28,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, break; case PIPE_TEXTURE: switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_I8_UNORM: return TRUE; default: diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 0129b0fb14..f36299db4d 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -1,6 +1,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "nv50_context.h" @@ -85,23 +86,47 @@ static void * nv50_sampler_state_create(struct pipe_context *pipe, const struct pipe_sampler_state *cso) { - return NULL; + unsigned *tsc = CALLOC(8, sizeof(unsigned)); + + tsc[0] = 0x00024080; + tsc[1] = 0x00000062; + + return (void *)tsc; } static void nv50_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) { + struct nv50_context *nv50 = nv50_context(pipe); + int i; + + nv50->sampler_nr = nr; + for (i = 0; i < nv50->sampler_nr; i++) + nv50->sampler[i] = sampler[i]; + + nv50->dirty |= NV50_NEW_SAMPLER; } static void nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso) { + FREE(hwcso); } static void nv50_set_sampler_texture(struct pipe_context *pipe, unsigned nr, struct pipe_texture **pt) { + struct nv50_context *nv50 = nv50_context(pipe); + int i; + + for (i = 0; i < nr; i++) + pipe_texture_reference(&nv50->miptree[i], pt[i]); + for (i = nr; i < nv50->miptree_nr; i++) + pipe_texture_reference(&nv50->miptree[i], NULL); + + nv50->miptree_nr = nr; + nv50->dirty |= NV50_NEW_TEXTURE; } static void * diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index a3f399a139..63c1756bcb 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -178,6 +178,39 @@ nv50_state_validate(struct nv50_context *nv50) so_ref(NULL, &so); } + if (nv50->dirty & NV50_NEW_SAMPLER) { + int i; + + BEGIN_RING(tesla, 0x0f00, 1); + OUT_RING ((NV50_CB_TSC << 0) | (0 << 8)); + BEGIN_RING(tesla, 0x40000f04, nv50->sampler_nr * 8); + for (i = 0; i < nv50->sampler_nr; i++) + OUT_RINGp(nv50->sampler[i], 8); + } + + if (nv50->dirty & NV50_NEW_TEXTURE) { + int i; + + BEGIN_RING(tesla, 0x0f00, 1); + OUT_RING ((NV50_CB_TIC << 0) | (0 << 8)); + BEGIN_RING(tesla, 0x40000f04, nv50->miptree_nr * 8); + for (i = 0; i < nv50->sampler_nr; i++) { + struct nv50_miptree *mt = nv50->miptree[i]; + + OUT_RING (0x2a712488); + OUT_RELOCl(mt->buffer, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW); + OUT_RING (0xd0c05000); + OUT_RING (0x00300000); + OUT_RING (mt->base.width[0]); + OUT_RING ((mt->base.depth[0] << 16) | + mt->base.height[0]); + OUT_RING (0x03000000); + OUT_RELOCh(mt->buffer, 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH); + } + } + if (nv50->dirty & NV50_NEW_ARRAYS) nv50_vbo_validate(nv50); -- cgit v1.2.3 From fa5cd63f96d2b69ded48d40b9cb7e57c147f7332 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 15 Jun 2008 15:49:25 +1000 Subject: nv50: simplify interp crap a bit... hopefully there wasn't a good reason I went the route I did.. can't recall.. --- src/gallium/drivers/nv50/nv50_program.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 5eec68e5e1..5800a347bf 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1263,7 +1263,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) NOUVEAU_ERR("%d attrib regs\n", pc->attr_nr); if (pc->attr_nr) { - struct nv50_reg *iv = NULL, *tmp = NULL; + struct nv50_reg *iv = NULL; int aid = 0; pc->attr = calloc(pc->attr_nr * 4, sizeof(struct nv50_reg)); @@ -1272,6 +1272,8 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (pc->p->type == PIPE_SHADER_FRAGMENT) { iv = alloc_temp(pc, NULL); + emit_interp(pc, iv, iv, iv, FALSE); + emit_flop(pc, 0, iv, iv); aid++; } @@ -1297,14 +1299,10 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (pc->p->type != PIPE_SHADER_FRAGMENT) continue; - emit_interp(pc, iv, iv, iv, FALSE); - tmp = alloc_temp(pc, NULL); - emit_flop(pc, 0, tmp, iv); - emit_interp(pc, &a[0], &a[0], tmp, TRUE); - emit_interp(pc, &a[1], &a[1], tmp, TRUE); - emit_interp(pc, &a[2], &a[2], tmp, TRUE); - emit_interp(pc, &a[3], &a[3], tmp, TRUE); - free_temp(pc, tmp); + emit_interp(pc, &a[0], &a[0], iv, TRUE); + emit_interp(pc, &a[1], &a[1], iv, TRUE); + emit_interp(pc, &a[2], &a[2], iv, TRUE); + emit_interp(pc, &a[3], &a[3], iv, TRUE); } if (iv) -- cgit v1.2.3 From da66b8a2f4c3c052ad71b2b6d5a845c2fd267c6e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 15 Jun 2008 15:53:22 +1000 Subject: nv50: disable inline IMMD for now, IMMD+pred == BANG! fixes progs/fp/lit.txt --- src/gallium/drivers/nv50/nv50_program.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 5800a347bf..845fc61190 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -31,10 +31,6 @@ * FUCK! watch dst==src vectors, can overwrite components that are needed. * ie. SUB R0, R0.yzxw, R0 * - * MOV dst, -src - * "delta" tmp, -src (0xa0000204,0xe4004780 - delta r0, -r0) - * mov dst, tmp - * * Things to check with renouveau: * FP attr/result assignment - how? * attrib @@ -349,7 +345,7 @@ emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) set_dst(pc, dst, e); - if (dst->type != P_RESULT && src->type == P_IMMD) { + if (0 && dst->type != P_RESULT && src->type == P_IMMD) { set_immd(pc, src, e); /*XXX: 32-bit, but steals part of "half" reg space - need to * catch and handle this case if/when we do half-regs -- cgit v1.2.3 From fea0b1651677444fc6c135e1a4b8ab6463a9fdf9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 16 Jun 2008 12:55:53 +1000 Subject: nv50: a couple more bits'n'pieces --- src/gallium/drivers/nv50/nv50_program.c | 10 +++++++++- src/gallium/drivers/nv50/nv50_program.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 845fc61190..2fe60ad51f 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -93,6 +93,11 @@ alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg) { int i; + if (reg->type == P_RESULT) { + if (pc->p->cfg.high_result < (reg->hw + 1)) + pc->p->cfg.high_result = reg->hw + 1; + } + if (reg->type != P_TEMP) return; @@ -1558,6 +1563,8 @@ nv50_vertprog_validate(struct nv50_context *nv50) so_method(so, tesla, 0x1650, 2); so_data (so, p->cfg.vp.attr[0]); so_data (so, p->cfg.vp.attr[1]); + so_method(so, tesla, 0x16b8, 1); + so_data (so, p->cfg.high_result); so_method(so, tesla, 0x16ac, 2); so_data (so, 8); so_data (so, p->cfg.high_temp); @@ -1594,9 +1601,10 @@ nv50_fragprog_validate(struct nv50_context *nv50) so_data (so, 0x00000004); so_data (so, 0x00000000); so_data (so, 0x00000000); - so_method(so, tesla, 0x16bc, 2); /*XXX: fixme */ + so_method(so, tesla, 0x16bc, 3); /*XXX: fixme */ so_data (so, 0x03020100); so_data (so, 0x07060504); + so_data (so, 0x0b0a0908); so_method(so, tesla, 0x1988, 2); so_data (so, 0x08040404); /* p: 0x0f000401 */ so_data (so, p->cfg.high_temp); diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h index d143ae9797..d643e8db21 100644 --- a/src/gallium/drivers/nv50/nv50_program.h +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -35,6 +35,7 @@ struct nv50_program { struct { unsigned high_temp; + unsigned high_result; struct { unsigned attr[2]; } vp; -- cgit v1.2.3 From cae38d0fcc6c936d3a4dc25ca2dbef3d106d05a5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 16 Jun 2008 16:29:40 +1000 Subject: nv50: abuse constbuf upload for program upload --- src/gallium/drivers/nv50/nv50_context.h | 1 + src/gallium/drivers/nv50/nv50_program.c | 50 +++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 5214ce1a69..cbb473410a 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -30,6 +30,7 @@ #define NV50_CB_PGP 3 #define NV50_CB_TIC 4 #define NV50_CB_TSC 5 +#define NV50_CB_PUPLOAD 6 #define NV50_NEW_BLEND (1 << 0) #define NV50_NEW_ZSA (1 << 1) diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 2fe60ad51f..2cf6275730 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1494,8 +1494,10 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) { struct pipe_winsys *ws = nv50->pipe.winsys; struct nv50_program_exec *e; + struct nouveau_stateobj *so; + const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR; + unsigned start, count, *up, *ptr; boolean upload = FALSE; - unsigned *map; if (!p->buffer) { p->buffer = ws->buffer_create(ws, 0x100, 0, p->exec_size * 4); @@ -1522,20 +1524,44 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) if (!upload) return FALSE; - map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + up = ptr = MALLOC(p->exec_size * 4); for (e = p->exec_head; e; e = e->next) { -#ifdef NV50_PROGRAM_DUMP - NOUVEAU_ERR("0x%08x\n", e->inst[0]); -#endif - *(map++) = e->inst[0]; - if (is_long(e)) { -#ifdef NV50_PROGRAM_DUMP - NOUVEAU_ERR("0x%08x\n", e->inst[1]); -#endif - *(map++) = e->inst[1]; + *(ptr++) = e->inst[0]; + if (is_long(e)) + *(ptr++) = e->inst[1]; + } + + so = so_new(3,2); + so_method(so, nv50->screen->tesla, 0x1280, 3); + so_reloc (so, p->buffer, 0, flags | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, p->buffer, 0, flags | NOUVEAU_BO_LOW, 0, 0); + so_data (so, (NV50_CB_PUPLOAD << 16) | 0x0800); //(p->exec_size * 4)); + + start = 0; count = p->exec_size; + while (count) { + struct nouveau_winsys *nvws = nv50->screen->nvws; + unsigned nr; + + so_emit(nvws, so); + + nr = MIN2(count, 2047); + nr = MIN2(nvws->channel->pushbuf->remaining, nr); + if (nvws->channel->pushbuf->remaining < (nr + 3)) { + FIRE_RING(NULL); + continue; } + + BEGIN_RING(tesla, 0x0f00, 1); + OUT_RING ((start << 8) | NV50_CB_PUPLOAD); + BEGIN_RING(tesla, 0x40000f04, nr); + OUT_RINGp (up + start, nr); + + start += nr; + count -= nr; } - ws->buffer_unmap(ws, p->buffer); + + FREE(up); + so_ref(NULL, &so); } void -- cgit v1.2.3 From bcbe6baac37915563bc120ad558cd930bc1ddec1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 16 Jun 2008 18:03:29 +1000 Subject: nv50: hacks for stuff I don't really get yet --- src/gallium/drivers/nv50/nv50_program.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 2cf6275730..fa5e24d3e9 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1592,7 +1592,7 @@ nv50_vertprog_validate(struct nv50_context *nv50) so_method(so, tesla, 0x16b8, 1); so_data (so, p->cfg.high_result); so_method(so, tesla, 0x16ac, 2); - so_data (so, 8); + so_data (so, p->cfg.high_result); //8); so_data (so, p->cfg.high_temp); so_method(so, tesla, 0x140c, 1); so_data (so, 0); /* program start offset */ @@ -1632,7 +1632,7 @@ nv50_fragprog_validate(struct nv50_context *nv50) so_data (so, 0x07060504); so_data (so, 0x0b0a0908); so_method(so, tesla, 0x1988, 2); - so_data (so, 0x08040404); /* p: 0x0f000401 */ + so_data (so, 0x08080408); //0x08040404); /* p: 0x0f000401 */ so_data (so, p->cfg.high_temp); so_method(so, tesla, 0x1414, 1); so_data (so, 0); /* program start offset */ -- cgit v1.2.3 From 431504b99cd55948522e86a249e656e78598ddbd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 16 Jun 2008 18:56:39 +1000 Subject: nv50: hack of a TEX opcode --- src/gallium/drivers/nv50/nv50_program.c | 19 +++++++++++++++++++ src/gallium/drivers/nv50/nv50_screen.c | 5 +++++ 2 files changed, 24 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index fa5e24d3e9..21945410b1 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1134,6 +1134,25 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } break; case TGSI_OPCODE_TEX: + { + struct nv50_reg *t0, *t1; + struct nv50_program_exec *e; + + t0 = alloc_temp(pc, NULL); + t0 = alloc_temp(pc, NULL); + t1 = alloc_temp(pc, NULL); + emit_mov(pc, t0, src[0][0]); + emit_mov(pc, t1, src[0][1]); + + e = exec(pc); + e->inst[0] = 0xf0400000; + set_long(pc, e); + e->inst[1] |= 0x0000c004; + set_dst(pc, t0, e); + emit(pc, e); + free_temp(pc, t0); + free_temp(pc, t1); + } break; case TGSI_OPCODE_XPD: temp = alloc_temp(pc, NULL); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index b9cecb77f1..8affb0f073 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -289,6 +289,11 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, fui(0.0)); so_data (so, fui(1.0)); + so_method(so, screen->tesla, 0x1234, 1); + so_data (so, 1); + so_method(so, screen->tesla, 0x1458, 1); + so_data (so, 1); + so_emit(nvws, so); so_ref(NULL, &so); nvws->push_flush(nvws, 0, NULL); -- cgit v1.2.3 From 5d3070149267251bafc1ff982b77e7f422554f50 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 16 Jun 2008 22:02:02 +1000 Subject: nv50: use stateobjs for sampler/image_control uploads --- src/gallium/drivers/nouveau/nouveau_stateobj.h | 18 +++++++++++ src/gallium/drivers/nv50/nv50_state_validate.c | 45 +++++++++++++++----------- 2 files changed, 44 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index d501b76b51..78b2738070 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -2,6 +2,7 @@ #define __NOUVEAU_STATEOBJ_H__ #include "pipe/p_util.h" +#include "pipe/p_debug.h" struct nouveau_stateobj_reloc { struct pipe_buffer *bo; @@ -67,6 +68,14 @@ so_data(struct nouveau_stateobj *so, unsigned data) so->cur_packet += 4; } +static INLINE void +so_datap(struct nouveau_stateobj *so, unsigned *data, unsigned size) +{ + so->cur_packet += (4 * size); + while (size--) + (*so->cur++) = (*data++); +} + static INLINE void so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr, unsigned mthd, unsigned size) @@ -91,6 +100,15 @@ so_reloc(struct nouveau_stateobj *so, struct pipe_buffer *bo, so_data(so, data); } +static INLINE void +so_dump(struct nouveau_stateobj *so) +{ + unsigned i, nr = so->cur - so->push; + + for (i = 0; i < nr; i++) + debug_printf("+0x%04x: 0x%08x\n", i, so->push[i]); +} + static INLINE void so_emit(struct nouveau_winsys *nvws, struct nouveau_stateobj *so) { diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 63c1756bcb..b5a9195231 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -181,34 +181,41 @@ nv50_state_validate(struct nv50_context *nv50) if (nv50->dirty & NV50_NEW_SAMPLER) { int i; - BEGIN_RING(tesla, 0x0f00, 1); - OUT_RING ((NV50_CB_TSC << 0) | (0 << 8)); - BEGIN_RING(tesla, 0x40000f04, nv50->sampler_nr * 8); + so = so_new(nv50->sampler_nr * 8 + 3, 0); + so_method(so, tesla, 0x0f00, 1); + so_data (so, NV50_CB_TSC); + so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8); for (i = 0; i < nv50->sampler_nr; i++) - OUT_RINGp(nv50->sampler[i], 8); + so_datap (so, nv50->sampler[i], 8); + so_emit(nvws, so); + so_ref(NULL, &so); } if (nv50->dirty & NV50_NEW_TEXTURE) { int i; - BEGIN_RING(tesla, 0x0f00, 1); - OUT_RING ((NV50_CB_TIC << 0) | (0 << 8)); - BEGIN_RING(tesla, 0x40000f04, nv50->miptree_nr * 8); - for (i = 0; i < nv50->sampler_nr; i++) { + so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2); + so_method(so, tesla, 0x0f00, 1); + so_data (so, NV50_CB_TIC); + so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8); + for (i = 0; i < nv50->miptree_nr; i++) { struct nv50_miptree *mt = nv50->miptree[i]; - OUT_RING (0x2a712488); - OUT_RELOCl(mt->buffer, 0, - NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW); - OUT_RING (0xd0c05000); - OUT_RING (0x00300000); - OUT_RING (mt->base.width[0]); - OUT_RING ((mt->base.depth[0] << 16) | - mt->base.height[0]); - OUT_RING (0x03000000); - OUT_RELOCh(mt->buffer, 0, - NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH); + so_data (so, 0x2a712488); + so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0xd0c05000); + so_data (so, 0x00300000); + so_data (so, mt->base.width[0]); + so_data (so, (mt->base.depth[0] << 16) | + mt->base.height[0]); + so_data (so, 0x03000000); + so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_HIGH, 0, 0); } + + so_emit(nvws, so); + so_ref(NULL, &so); } if (nv50->dirty & NV50_NEW_ARRAYS) -- cgit v1.2.3 From 94999d39d43d24a702f4cb55b515906d03a57277 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 16 Jun 2008 22:06:54 +1000 Subject: nv50: fix blend colour --- src/gallium/drivers/nv50/nv50_state_validate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index b5a9195231..9d93c04da7 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -135,11 +135,11 @@ nv50_state_validate(struct nv50_context *nv50) 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_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4); so_data (so, fui(nv50->blend_colour.color[0])); so_data (so, fui(nv50->blend_colour.color[1])); so_data (so, fui(nv50->blend_colour.color[2])); + so_data (so, fui(nv50->blend_colour.color[3])); so_emit(nvws, so); so_ref(NULL, &so); } -- cgit v1.2.3 From bb9efb5534a652878161e28bd73039eff5b11014 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 16 Jun 2008 22:24:16 +1000 Subject: nv50: separate state validation and upload, similar to nv40 --- src/gallium/drivers/nv50/nv50_context.h | 21 +++++++ src/gallium/drivers/nv50/nv50_program.c | 6 +- src/gallium/drivers/nv50/nv50_state_validate.c | 80 ++++++++++++++++++++------ src/gallium/drivers/nv50/nv50_vbo.c | 6 +- 4 files changed, 86 insertions(+), 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index cbb473410a..3e0e523ee3 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -74,6 +74,25 @@ nv50_miptree(struct pipe_texture *pt) return (struct nv50_miptree *)pt; } +struct nv50_state { + unsigned dirty; + + struct nouveau_stateobj *fb; + struct nouveau_stateobj *blend; + struct nouveau_stateobj *blend_colour; + struct nouveau_stateobj *zsa; + struct nouveau_stateobj *rast; + struct nouveau_stateobj *stipple; + struct nouveau_stateobj *scissor; + struct nouveau_stateobj *viewport; + struct nouveau_stateobj *tsc_upload; + struct nouveau_stateobj *tic_upload; + struct nouveau_stateobj *vertprog; + struct nouveau_stateobj *fragprog; + struct nouveau_stateobj *vtxfmt; + struct nouveau_stateobj *vtxbuf; +}; + struct nv50_context { struct pipe_context pipe; @@ -82,6 +101,8 @@ struct nv50_context { struct draw_context *draw; + struct nv50_state state; + unsigned dirty; struct nv50_blend_stateobj *blend; struct nv50_zsa_stateobj *zsa; diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 21945410b1..7bb2f454bb 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1615,8 +1615,7 @@ nv50_vertprog_validate(struct nv50_context *nv50) so_data (so, p->cfg.high_temp); so_method(so, tesla, 0x140c, 1); so_data (so, 0); /* program start offset */ - so_emit(nv50->screen->nvws, so); - so_ref(NULL, &so); + so_ref(so, &nv50->state.vertprog); } void @@ -1655,8 +1654,7 @@ nv50_fragprog_validate(struct nv50_context *nv50) so_data (so, p->cfg.high_temp); so_method(so, tesla, 0x1414, 1); so_data (so, 0); /* program start offset */ - so_emit(nv50->screen->nvws, so); - so_ref(NULL, &so); + so_ref(so, &nv50->state.fragprog); } void diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 9d93c04da7..566f95f682 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -103,14 +103,59 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_data (so, 0); so_data (so, h); - so_emit(nv50->screen->nvws, so); - so_ref(NULL, &so); + so_ref(so, &nv50->state.fb); +} + +static void +nv50_state_emit(struct nv50_context *nv50) +{ + struct nv50_screen *screen = nv50->screen; + struct nouveau_winsys *nvws = screen->nvws; + + if (nv50->pctx_id != screen->cur_pctx) { + nv50->state.dirty |= 0xffffffff; + screen->cur_pctx = nv50->pctx_id; + } + + if (nv50->state.dirty & NV50_NEW_FRAMEBUFFER) + so_emit(nvws, nv50->state.fb); + if (nv50->state.dirty & NV50_NEW_BLEND) + so_emit(nvws, nv50->state.blend); + if (nv50->state.dirty & NV50_NEW_ZSA) + so_emit(nvws, nv50->state.zsa); + if (nv50->state.dirty & NV50_NEW_VERTPROG) + so_emit(nvws, nv50->state.vertprog); + if (nv50->state.dirty & NV50_NEW_FRAGPROG) + so_emit(nvws, nv50->state.fragprog); + if (nv50->state.dirty & NV50_NEW_RASTERIZER) + so_emit(nvws, nv50->state.rast); + if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR) + so_emit(nvws, nv50->state.blend_colour); + if (nv50->state.dirty & NV50_NEW_STIPPLE) + so_emit(nvws, nv50->state.stipple); + if (nv50->state.dirty & NV50_NEW_SCISSOR) + so_emit(nvws, nv50->state.scissor); + if (nv50->state.dirty & NV50_NEW_VIEWPORT) + so_emit(nvws, nv50->state.viewport); + if (nv50->state.dirty & NV50_NEW_SAMPLER) + so_emit(nvws, nv50->state.tsc_upload); + if (nv50->state.dirty & NV50_NEW_TEXTURE) + so_emit(nvws, nv50->state.tic_upload); + if (nv50->state.dirty & NV50_NEW_ARRAYS) { + so_emit(nvws, nv50->state.vtxfmt); + so_emit(nvws, nv50->state.vtxbuf); + } + nv50->state.dirty = 0; + + so_emit_reloc_markers(nvws, nv50->state.fb); + so_emit_reloc_markers(nvws, nv50->state.vertprog); + so_emit_reloc_markers(nvws, nv50->state.fragprog); + so_emit_reloc_markers(nvws, nv50->state.vtxbuf); } 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; @@ -119,10 +164,10 @@ nv50_state_validate(struct nv50_context *nv50) nv50_state_validate_fb(nv50); if (nv50->dirty & NV50_NEW_BLEND) - so_emit(nvws, nv50->blend->so); + so_ref(nv50->blend->so, &nv50->state.blend); if (nv50->dirty & NV50_NEW_ZSA) - so_emit(nvws, nv50->zsa->so); + so_ref(nv50->zsa->so, &nv50->state.zsa); if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB)) nv50_vertprog_validate(nv50); @@ -131,7 +176,7 @@ nv50_state_validate(struct nv50_context *nv50) nv50_fragprog_validate(nv50); if (nv50->dirty & NV50_NEW_RASTERIZER) - so_emit(nvws, nv50->rasterizer->so); + so_ref(nv50->rasterizer->so, &nv50->state.rast); if (nv50->dirty & NV50_NEW_BLEND_COLOUR) { so = so_new(5, 0); @@ -140,8 +185,7 @@ nv50_state_validate(struct nv50_context *nv50) so_data (so, fui(nv50->blend_colour.color[1])); so_data (so, fui(nv50->blend_colour.color[2])); so_data (so, fui(nv50->blend_colour.color[3])); - so_emit(nvws, so); - so_ref(NULL, &so); + so_ref(so, &nv50->state.blend_colour); } if (nv50->dirty & NV50_NEW_STIPPLE) { @@ -149,8 +193,7 @@ nv50_state_validate(struct nv50_context *nv50) 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); + so_ref(so, &nv50->state.stipple); } if (nv50->dirty & NV50_NEW_SCISSOR) { @@ -160,8 +203,7 @@ nv50_state_validate(struct nv50_context *nv50) nv50->scissor.minx); so_data (so, (nv50->scissor.maxy << 16) | nv50->scissor.miny); - so_emit(nvws, so); - so_ref(NULL, &so); + so_ref(so, &nv50->state.scissor); } if (nv50->dirty & NV50_NEW_VIEWPORT) { @@ -174,8 +216,7 @@ nv50_state_validate(struct nv50_context *nv50) 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); + so_ref(so, &nv50->state.viewport); } if (nv50->dirty & NV50_NEW_SAMPLER) { @@ -187,8 +228,7 @@ nv50_state_validate(struct nv50_context *nv50) so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8); for (i = 0; i < nv50->sampler_nr; i++) so_datap (so, nv50->sampler[i], 8); - so_emit(nvws, so); - so_ref(NULL, &so); + so_ref(so, &nv50->state.tsc_upload); } if (nv50->dirty & NV50_NEW_TEXTURE) { @@ -213,15 +253,17 @@ nv50_state_validate(struct nv50_context *nv50) so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0); } - - so_emit(nvws, so); - so_ref(NULL, &so); + + so_ref(so, &nv50->state.tic_upload); } if (nv50->dirty & NV50_NEW_ARRAYS) nv50_vbo_validate(nv50); + nv50->state.dirty |= nv50->dirty; nv50->dirty = 0; + nv50_state_emit(nv50); + return TRUE; } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 7a1c2f24ef..3f0b66ae36 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -208,9 +208,7 @@ nv50_vbo_validate(struct nv50_context *nv50) NOUVEAU_BO_LOW, 0, 0); } - so_emit(nv50->screen->nvws, vtxfmt); - so_ref (NULL, &vtxfmt); - so_emit(nv50->screen->nvws, vtxbuf); - so_ref (NULL, &vtxbuf); + so_ref (vtxfmt, &nv50->state.vtxfmt); + so_ref (vtxbuf, &nv50->state.vtxbuf); } -- cgit v1.2.3 From 035a04d9c11e0e90e2dbcdba25f39c3156a64115 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 16 Jun 2008 22:34:50 +1000 Subject: nv50: get tri-scissor-tri working --- src/gallium/drivers/nv50/nv50_context.h | 1 + src/gallium/drivers/nv50/nv50_state_validate.c | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 3e0e523ee3..4ea01009fb 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -84,6 +84,7 @@ struct nv50_state { struct nouveau_stateobj *rast; struct nouveau_stateobj *stipple; struct nouveau_stateobj *scissor; + unsigned scissor_enabled; struct nouveau_stateobj *viewport; struct nouveau_stateobj *tsc_upload; struct nouveau_stateobj *tic_upload; diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 566f95f682..d99cdc73ca 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -196,15 +196,28 @@ nv50_state_validate(struct nv50_context *nv50) so_ref(so, &nv50->state.stipple); } - if (nv50->dirty & NV50_NEW_SCISSOR) { + if (nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_RASTERIZER)) { + struct pipe_rasterizer_state *rast = &nv50->rasterizer->pipe; + struct pipe_scissor_state *s = &nv50->scissor; + + if (nv50->state.scissor && + (rast->scissor == 0 && nv50->state.scissor_enabled == 0)) + goto scissor_uptodate; + nv50->state.scissor_enabled = rast->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_method(so, tesla, 0xff4, 2); //NV50TCL_SCISSOR_HORIZ, 2); + if (nv50->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, (8192 << 16)); + so_data(so, (8192 << 16)); + } so_ref(so, &nv50->state.scissor); + nv50->state.dirty |= NV50_NEW_SCISSOR; } +scissor_uptodate: if (nv50->dirty & NV50_NEW_VIEWPORT) { so = so_new(8, 0); -- cgit v1.2.3 From 598b2a51052913521e3059cdef7cf0c66a5adb90 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Jun 2008 01:36:36 +1000 Subject: nv50: make TEX a halfie --- src/gallium/drivers/nv50/nv50_program.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 7bb2f454bb..5ef0954239 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1145,9 +1145,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_mov(pc, t1, src[0][1]); e = exec(pc); - e->inst[0] = 0xf0400000; - set_long(pc, e); - e->inst[1] |= 0x0000c004; + e->inst[0] = 0xf0400100; set_dst(pc, t0, e); emit(pc, e); free_temp(pc, t0); -- cgit v1.2.3 From fd7412a7f1beab8b81ce307b1054331eee102e8b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Jun 2008 01:51:13 +1000 Subject: nv50: some people are just born stupid.. really.. --- src/gallium/drivers/nv50/nv50_program.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 5ef0954239..ba60b8c533 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1135,21 +1135,33 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) break; case TGSI_OPCODE_TEX: { - struct nv50_reg *t0, *t1; + struct nv50_reg *t0, *t1, *t2, *t3; struct nv50_program_exec *e; t0 = alloc_temp(pc, NULL); t0 = alloc_temp(pc, NULL); t1 = alloc_temp(pc, NULL); + t2 = alloc_temp(pc, NULL); + t3 = alloc_temp(pc, NULL); emit_mov(pc, t0, src[0][0]); emit_mov(pc, t1, src[0][1]); e = exec(pc); - e->inst[0] = 0xf0400100; + e->inst[0] = 0xf0400000; + set_long(pc, e); + e->inst[1] |= 0x0000c004; set_dst(pc, t0, e); emit(pc, e); + + if (mask & (1 << 0)) emit_mov(pc, dst[0], t0); + if (mask & (1 << 1)) emit_mov(pc, dst[1], t1); + if (mask & (1 << 2)) emit_mov(pc, dst[2], t2); + if (mask & (1 << 3)) emit_mov(pc, dst[3], t3); + free_temp(pc, t0); free_temp(pc, t1); + free_temp(pc, t2); + free_temp(pc, t3); } break; case TGSI_OPCODE_XPD: -- cgit v1.2.3 From 65ad8176ca91b5ed2a01b1b3ee145cfdce369419 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Jun 2008 23:43:38 +1000 Subject: nv50: move surface_map/unmap into nv50_surface.c --- src/gallium/drivers/nv50/nv50_screen.c | 26 +------------------------ src/gallium/drivers/nv50/nv50_screen.h | 2 ++ src/gallium/drivers/nv50/nv50_surface.c | 34 +++++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 8affb0f073..18f22c5960 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -118,28 +118,6 @@ nv50_screen_get_paramf(struct pipe_screen *pscreen, int param) } } -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) { @@ -309,10 +287,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) 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); + nv50_surface_init_screen_functions(&screen->pipe); return &screen->pipe; } diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 5acb5003ba..08d1f45089 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -26,4 +26,6 @@ nv50_screen(struct pipe_screen *screen) return (struct nv50_screen *)screen; } +void nv50_surface_init_screen_functions(struct pipe_screen *); + #endif diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 4e294198b0..acd7b501ef 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -57,9 +57,39 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, nvws->surface_fill(nvws, dest, destx, desty, width, height, value); } +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); +} + void nv50_init_surface_functions(struct nv50_context *nv50) { - nv50->pipe.surface_copy = nv50_surface_copy; - nv50->pipe.surface_fill = nv50_surface_fill; + nv50->pipe.surface_copy = nv50_surface_copy; + nv50->pipe.surface_fill = nv50_surface_fill; } + +void +nv50_surface_init_screen_functions(struct pipe_screen *pscreen) +{ + pscreen->surface_map = nv50_surface_map; + pscreen->surface_unmap = nv50_surface_unmap; +} + -- cgit v1.2.3 From 3b88c3f4112a8bac52b7f7e613b1c2df8a14b752 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Jun 2008 23:52:41 +1000 Subject: nv50: R32_FLOAT vbo format --- src/gallium/drivers/nv50/nv50_vbo.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 3f0b66ae36..c16bfe3a93 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -185,6 +185,9 @@ nv50_vbo_validate(struct nv50_context *nv50) case PIPE_FORMAT_R32G32_FLOAT: so_data(vtxfmt, 0x7e200000 | i); break; + case PIPE_FORMAT_R32_FLOAT: + so_data(vtxfmt, 0x7e900000 | i); + break; case PIPE_FORMAT_R8G8B8A8_UNORM: so_data(vtxfmt, 0x24500000 | i); break; -- cgit v1.2.3 From 714cb4a86c1f503334b37ca6c24272fa1bdf7899 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Jun 2008 23:55:23 +1000 Subject: nv50: make sure static buffers (constbuf, tex control etc) get on reloc list --- src/gallium/drivers/nv50/nv50_screen.c | 2 +- src/gallium/drivers/nv50/nv50_screen.h | 2 ++ src/gallium/drivers/nv50/nv50_state_validate.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 18f22c5960..5b4c5f96ac 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -273,7 +273,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, 1); so_emit(nvws, so); - so_ref(NULL, &so); + so_ref(so, &screen->static_init); nvws->push_flush(nvws, 0, NULL); screen->pipe.winsys = ws; diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 08d1f45089..400ddcef06 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -18,6 +18,8 @@ struct nv50_screen { struct pipe_buffer *tic; struct pipe_buffer *tsc; + + struct nouveau_stateobj *static_init; }; static INLINE struct nv50_screen * diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index d99cdc73ca..8229bce89e 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -151,6 +151,7 @@ nv50_state_emit(struct nv50_context *nv50) so_emit_reloc_markers(nvws, nv50->state.vertprog); so_emit_reloc_markers(nvws, nv50->state.fragprog); so_emit_reloc_markers(nvws, nv50->state.vtxbuf); + so_emit_reloc_markers(nvws, nv50->screen->static_init); } boolean -- cgit v1.2.3 From 5a3ea9ee59ac586955f7784eb25e7fd70d0c8882 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 18 Jun 2008 13:23:00 +1000 Subject: nv50: simplify emit_interp a bit --- src/gallium/drivers/nv50/nv50_program.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index ba60b8c533..3248f2aa3c 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -302,18 +302,19 @@ set_immd(struct nv50_pc *pc, struct nv50_reg *imm, struct nv50_program_exec *e) static void emit_interp(struct nv50_pc *pc, struct nv50_reg *dst, - struct nv50_reg *src, struct nv50_reg *iv, boolean noperspective) + struct nv50_reg *src, struct nv50_reg *iv) { struct nv50_program_exec *e = exec(pc); e->inst[0] |= 0x80000000; set_dst(pc, dst, e); - alloc_reg(pc, iv); - e->inst[0] |= (iv->hw << 9); alloc_reg(pc, src); e->inst[0] |= (src->hw << 16); - if (noperspective) + if (iv) { e->inst[0] |= (1 << 25); + alloc_reg(pc, iv); + e->inst[0] |= (iv->hw << 9); + } emit(pc, e); } @@ -1147,7 +1148,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) emit_mov(pc, t1, src[0][1]); e = exec(pc); - e->inst[0] = 0xf0400000; + e->inst[0] = 0xf6400000; set_long(pc, e); e->inst[1] |= 0x0000c004; set_dst(pc, t0, e); @@ -1302,7 +1303,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (pc->p->type == PIPE_SHADER_FRAGMENT) { iv = alloc_temp(pc, NULL); - emit_interp(pc, iv, iv, iv, FALSE); + emit_interp(pc, iv, iv, NULL); emit_flop(pc, 0, iv, iv); aid++; } @@ -1329,10 +1330,10 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (pc->p->type != PIPE_SHADER_FRAGMENT) continue; - emit_interp(pc, &a[0], &a[0], iv, TRUE); - emit_interp(pc, &a[1], &a[1], iv, TRUE); - emit_interp(pc, &a[2], &a[2], iv, TRUE); - emit_interp(pc, &a[3], &a[3], iv, TRUE); + emit_interp(pc, &a[0], &a[0], iv); + emit_interp(pc, &a[1], &a[1], iv); + emit_interp(pc, &a[2], &a[2], iv); + emit_interp(pc, &a[3], &a[3], iv); } if (iv) -- cgit v1.2.3 From e90130257527aff43f807ae16d802c5515d29e8e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 23 Jun 2008 23:42:53 +1000 Subject: nv50: remove some debug --- src/gallium/drivers/nv50/nv50_program.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 3248f2aa3c..148de3b7ea 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -883,8 +883,6 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) unsigned mask, sat; int i, c; - NOUVEAU_ERR("insn %p\n", tok); - mask = inst->FullDstRegisters[0].DstRegister.WriteMask; sat = inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE; @@ -1277,7 +1275,6 @@ nv50_program_tx_prep(struct nv50_pc *pc) } } - NOUVEAU_ERR("%d temps\n", pc->temp_nr); if (pc->temp_nr) { pc->temp = calloc(pc->temp_nr * 4, sizeof(struct nv50_reg)); if (!pc->temp) @@ -1292,7 +1289,6 @@ nv50_program_tx_prep(struct nv50_pc *pc) } } - NOUVEAU_ERR("%d attrib regs\n", pc->attr_nr); if (pc->attr_nr) { struct nv50_reg *iv = NULL; int aid = 0; @@ -1340,7 +1336,6 @@ nv50_program_tx_prep(struct nv50_pc *pc) free_temp(pc, iv); } - NOUVEAU_ERR("%d result regs\n", pc->result_nr); if (pc->result_nr) { int rid = 0; @@ -1362,7 +1357,6 @@ nv50_program_tx_prep(struct nv50_pc *pc) } } - NOUVEAU_ERR("%d param regs\n", pc->param_nr); if (pc->param_nr) { int rid = 0; -- cgit v1.2.3 From 47771bcd2fb5bcfecfa076c19360436351c21c95 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 23 Jun 2008 23:43:34 +1000 Subject: nv50: maintain pipe surface status field --- src/gallium/drivers/nv50/nv50_clear.c | 1 + src/gallium/drivers/nv50/nv50_state_validate.c | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c index 552b92f72e..f35087b37e 100644 --- a/src/gallium/drivers/nv50/nv50_clear.c +++ b/src/gallium/drivers/nv50/nv50_clear.c @@ -9,4 +9,5 @@ nv50_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/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 8229bce89e..f5c734699f 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -157,10 +157,17 @@ nv50_state_emit(struct nv50_context *nv50) boolean nv50_state_validate(struct nv50_context *nv50) { + const struct pipe_framebuffer_state *fb = &nv50->framebuffer; struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_stateobj *so; 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; + if (nv50->dirty & NV50_NEW_FRAMEBUFFER) nv50_state_validate_fb(nv50); -- cgit v1.2.3 From 5a3362521de5e17e4f340fd9136af1d5e3891e23 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 03:56:57 +1000 Subject: nv50: turn on depth test/write again, not 100% but winsys handles it better --- src/gallium/drivers/nv50/nv50_miptree.c | 7 ++++--- src/gallium/drivers/nv50/nv50_state.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index cdd98844f9..6ee09fc4dd 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -10,7 +10,7 @@ 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); - unsigned usage; + unsigned usage, pitch; NOUVEAU_ERR("unimplemented\n"); @@ -28,8 +28,9 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) break; } - mt->buffer = ws->buffer_create(ws, 256, usage, - pt->width[0] * pt->cpp * pt->height[0]); + pitch = ((pt->width[0] + 63) & ~63) * pt->cpp; + + mt->buffer = ws->buffer_create(ws, 256, usage, pitch * pt->height[0]); if (!mt->buffer) { FREE(mt); return NULL; diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index f36299db4d..1b765cb5c7 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -272,10 +272,10 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, struct nouveau_stateobj *so = so_new(64, 0); so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1); - so_data (so, 0); //cso->depth.writemask ? 1 : 0); + so_data (so, cso->depth.writemask ? 1 : 0); if (cso->depth.enabled) { so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1); - so_data (so, 0); //1); + so_data (so, 1); so_method(so, tesla, NV50TCL_DEPTH_TEST_FUNC, 1); so_data (so, nvgl_comparison_op(cso->depth.func)); } else { -- cgit v1.2.3 From 2c2cb8646168c8709e51d7ff583a86044e3f2040 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 04:53:34 +1000 Subject: nv50: rework miptree/texture/texsurf code a bit --- src/gallium/drivers/nv50/nv50_miptree.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 6ee09fc4dd..ec6e09aea0 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -12,8 +12,6 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); unsigned usage, pitch; - NOUVEAU_ERR("unimplemented\n"); - mt->base = *pt; mt->base.refcount = 1; mt->base.screen = pscreen; @@ -45,9 +43,8 @@ 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); @@ -65,13 +62,9 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, 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 = CALLOC_STRUCT(pipe_surface); + ps->refcount = 1; + ps->winsys = ws; ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; @@ -80,6 +73,11 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->nblocksy = pt->nblocksy[level]; ps->stride = ps->width * ps->block.size; ps->offset = 0; + ps->usage = flags; + ps->status = PIPE_SURFACE_STATUS_DEFINED; + + pipe_texture_reference(&ps->texture, pt); + pipe_buffer_reference(ws, &ps->buffer, mt->buffer); return ps; } @@ -88,6 +86,16 @@ static void nv50_miptree_surface_del(struct pipe_screen *pscreen, struct pipe_surface **psurface) { + struct pipe_winsys *ws = pscreen->winsys; + struct pipe_surface *surf = *psurface; + + *psurface = NULL; + + if (--surf->refcount <= 0) { + pipe_texture_reference(&surf->texture, NULL); + pipe_buffer_reference(ws, &surf->buffer, NULL); + FREE(surf); + } } void -- cgit v1.2.3 From e002ad77398fbe14a0efbd91824c3325ca09b4c1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 04:57:27 +1000 Subject: nv50: whoops --- src/gallium/drivers/nv50/nv50_program.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 148de3b7ea..bc45fe0bdf 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1555,7 +1555,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) *(ptr++) = e->inst[1]; } - so = so_new(3,2); + so = so_new(4,2); so_method(so, nv50->screen->tesla, 0x1280, 3); so_reloc (so, p->buffer, 0, flags | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->buffer, 0, flags | NOUVEAU_BO_LOW, 0, 0); @@ -1604,7 +1604,7 @@ nv50_vertprog_validate(struct nv50_context *nv50) nv50_program_validate_data(nv50, p); nv50_program_validate_code(nv50, p); - so = so_new(11, 2); + so = so_new(13, 2); so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2); so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); -- cgit v1.2.3 From 95d64ceb5a2b20032e757d6c1b0b5ef5e2b973e2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 05:11:46 +1000 Subject: nv50: vpt translate/scale backwards --- src/gallium/drivers/nv50/nv50_state_validate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index f5c734699f..eba13f8e62 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -229,11 +229,11 @@ scissor_uptodate: if (nv50->dirty & NV50_NEW_VIEWPORT) { so = so_new(8, 0); - so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3); + so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(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_method(so, tesla, NV50TCL_VIEWPORT_UNK0(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])); -- cgit v1.2.3 From e05f67cbe6d852d01da3c4e0c4d52b28723f3684 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 05:17:08 +1000 Subject: nv50: maybe some scissor fixes.. --- src/gallium/drivers/nv50/nv50_state_validate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index eba13f8e62..cf5a071a8d 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -96,7 +96,7 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2); so_data (so, w << 16); so_data (so, h << 16); - so_method(so, tesla, 0xff4, 2); + so_method(so, tesla, 0x0e04, 2); so_data (so, w << 16); so_data (so, h << 16); so_method(so, tesla, 0xdf8, 2); @@ -214,7 +214,7 @@ nv50_state_validate(struct nv50_context *nv50) nv50->state.scissor_enabled = rast->scissor; so = so_new(3, 0); - so_method(so, tesla, 0xff4, 2); //NV50TCL_SCISSOR_HORIZ, 2); + so_method(so, tesla, 0x0ff4, 2); if (nv50->state.scissor_enabled) { so_data(so, ((s->maxx - s->minx) << 16) | s->minx); so_data(so, ((s->maxy - s->miny) << 16) | s->miny); -- cgit v1.2.3 From fea9eb284248adda65afdc3833385d4b03bb25aa Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 05:58:35 +1000 Subject: nv50: don't multiply polygon offset units by 2.0 like on nv40 --- src/gallium/drivers/nv50/nv50_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 1b765cb5c7..cffcbc3e7d 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -237,7 +237,7 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, 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)); + so_data (so, fui(cso->offset_units)); } rso->pipe = *cso; -- cgit v1.2.3 From e52d37d56c91e152bc149230410ed700ff1cffe2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 06:01:30 +1000 Subject: nv50: fix line stipple --- src/gallium/drivers/nv50/nv50_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index cffcbc3e7d..d72886ac59 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -157,7 +157,7 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, 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) | + so_data (so, (cso->line_stipple_pattern << 8) | cso->line_stipple_factor); } else { so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1); -- cgit v1.2.3 From 70f0f0ebdfa40de0fe03ca94294d372b9fa4642d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 06:07:02 +1000 Subject: nv50: reverse stencil sides, header is wrong --- src/gallium/drivers/nv50/nv50_state.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index d72886ac59..665e3cc80d 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -283,24 +283,25 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, 0); } + /*XXX: yes, I know they're backwards.. header needs fixing */ if (cso->stencil[0].enabled) { - so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 5); + so_method(so, tesla, NV50TCL_STENCIL_BACK_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_method(so, tesla, NV50TCL_STENCIL_BACK_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_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1); so_data (so, 0); } if (cso->stencil[1].enabled) { - so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 8); + so_method(so, tesla, NV50TCL_STENCIL_FRONT_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)); @@ -310,7 +311,7 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, 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_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1); so_data (so, 0); } -- cgit v1.2.3 From bf94027fdde51aed476e9bfdd4326aa9040440b0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 29 Jun 2008 15:59:24 +1000 Subject: nv50: fixes after rebase + commits note on the code that was just pushed. OK, seems a lot of people have been getting the idea that nouveau is dying lately - I decided to commit some of the work I've been doing lately to prove them wrong :) Progress on my side is slow due to lack of time mainly, but I'm still around. Firstly, don't even bother trying to use gallium on G8x/G9x yet, it won't work. I've deliberately left all the necessary winsys changes out of the commits for a very good reason - I don't know what we're going to need from the DRM exactly yet and don't want to be continually breaking interfaces as I discover additional requirements. On my side, I think I've gone through about 3 different DRM interface changes, and have just discovered that I may need more yet. It'd be very annoying for everyone who uses nouveau to keep things in sync. Once I've got it sorted - I'll commit a lot of cool stuff. Stay tuned. Also, don't look at the shader code.. it's horribly nasty and full of hacks, I used it as an opportunity to learn G8x GPU programs at the same time. New semi-decent code is in works, and will follow at some point. :) --- src/gallium/drivers/nv50/nv50_miptree.c | 2 +- src/gallium/drivers/nv50/nv50_program.c | 4 ++-- src/gallium/drivers/nv50/nv50_state.c | 4 ++-- src/gallium/winsys/dri/nouveau/nouveau_screen.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index ec6e09aea0..f936a1f0e2 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -26,7 +26,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) break; } - pitch = ((pt->width[0] + 63) & ~63) * pt->cpp; + pitch = ((pt->width[0] + 63) & ~63) * pt->block.size; mt->buffer = ws->buffer_create(ws, 256, usage, pitch * pt->height[0]); if (!mt->buffer) { diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index bc45fe0bdf..cd6967b366 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1240,7 +1240,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) unsigned last; d = &p.FullToken.FullDeclaration; - last = d->u.DeclarationRange.Last; + last = d->DeclarationRange.Last; switch (d->Declaration.File) { case TGSI_FILE_TEMPORARY: @@ -1546,7 +1546,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) } if (!upload) - return FALSE; + return; up = ptr = MALLOC(p->exec_size * 4); for (e = p->exec_head; e; e = e->next) { diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 665e3cc80d..743de089d6 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -121,9 +121,9 @@ nv50_set_sampler_texture(struct pipe_context *pipe, unsigned nr, int i; for (i = 0; i < nr; i++) - pipe_texture_reference(&nv50->miptree[i], pt[i]); + pipe_texture_reference((void *)&nv50->miptree[i], pt[i]); for (i = nr; i < nv50->miptree_nr; i++) - pipe_texture_reference(&nv50->miptree[i], NULL); + pipe_texture_reference((void *)&nv50->miptree[i], NULL); nv50->miptree_nr = nr; nv50->dirty |= NV50_NEW_TEXTURE; diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index b15ee7509c..df1fe7e69b 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -13,7 +13,7 @@ #include "nouveau_screen.h" #include "nouveau_swapbuffers.h" -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 #error nouveau_drm.h version does not match expected version #endif -- cgit v1.2.3 From c6ddcc10e31f26d17c1c8181013268766aca9ac6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 29 Jun 2008 16:02:01 +1000 Subject: nouveau: oops, bump the drm patchlevel back down again --- src/gallium/winsys/dri/nouveau/nouveau_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index df1fe7e69b..b15ee7509c 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -13,7 +13,7 @@ #include "nouveau_screen.h" #include "nouveau_swapbuffers.h" -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 #error nouveau_drm.h version does not match expected version #endif -- cgit v1.2.3 From 14d4f9e44e55e2b427579ed6788e579d70b289e7 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 16 Jun 2008 23:18:20 -0400 Subject: g3dvl: Get rid of some Valgrind errors. Get rid of some Valgrind memory leak and uninitialized var errors. --- src/gallium/state_trackers/g3dvl/vl_context.c | 24 +++++++++++++++++++++++- src/gallium/state_trackers/g3dvl/vl_surface.c | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 2d1d543495..59a1ccd152 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -209,6 +209,8 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) context->states.mc.i_vs = pipe->create_vs_state(pipe, &vs); + free(tokens); + return 0; } @@ -346,6 +348,8 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) context->states.mc.i_fs = pipe->create_fs_state(pipe, &fs); + free(tokens); + return 0; } @@ -558,6 +562,8 @@ static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) context->states.mc.p_vs = pipe->create_vs_state(pipe, &vs); + free(tokens); + return 0; } @@ -833,6 +839,8 @@ static int vlCreateFragmentShaderPMC(struct VL_CONTEXT *context) context->states.mc.p_fs = pipe->create_fs_state(pipe, &fs); + free(tokens); + return 0; } @@ -1051,6 +1059,8 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) context->states.mc.b_vs = pipe->create_vs_state(pipe, &vs); + free(tokens); + return 0; } @@ -1349,6 +1359,8 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) context->states.mc.b_fs = pipe->create_fs_state(pipe, &fs); + free(tokens); + return 0; } @@ -1502,7 +1514,7 @@ static int vlInitMC(struct VL_CONTEXT *context) /*sampler.prefilter = ;*/ /*sampler.shadow_ambient = ;*/ /*sampler.lod_bias = ;*/ - /*sampler.min_lod = ;*/ + sampler.min_lod = 0; /*sampler.max_lod = ;*/ /*sampler.border_color[i] = ;*/ /*sampler.max_anisotropy = ;*/ @@ -1692,6 +1704,8 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context) context->states.csc.vertex_shader = pipe->create_vs_state(pipe, &vs); + free(tokens); + return 0; } @@ -1880,6 +1894,8 @@ static int vlCreateFragmentShaderCSC(struct VL_CONTEXT *context) context->states.csc.fragment_shader = pipe->create_fs_state(pipe, &fs); + free(tokens); + return 0; } @@ -2052,6 +2068,7 @@ static int vlInitCommon(struct VL_CONTEXT *context) pipe = context->pipe; rast.flatshade = 1; + rast.flatshade_first = 0; rast.light_twoside = 0; rast.front_winding = PIPE_WINDING_CCW; rast.cull_mode = PIPE_WINDING_CW; @@ -2061,6 +2078,7 @@ static int vlInitCommon(struct VL_CONTEXT *context) rast.offset_ccw = 0; rast.scissor = 0; rast.poly_smooth = 0; + rast.poly_stipple_enable = 0; rast.point_sprite = 0; rast.point_size_per_vertex = 0; rast.multisample = 0; @@ -2074,6 +2092,7 @@ static int vlInitCommon(struct VL_CONTEXT *context) rast.bypass_vs = 0; rast.origin_lower_left = 0; rast.line_width = 1; + rast.point_smooth = 0; rast.point_size = 1; rast.offset_units = 1; rast.offset_scale = 1; @@ -2199,6 +2218,9 @@ int vlDestroyContext(struct VL_CONTEXT *context) vlDestroy(context); + context->pipe->screen->destroy(context->pipe->screen); + context->pipe->destroy(context->pipe); + free(context); return 0; diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 0e1adea472..3f59d0f155 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -195,6 +195,7 @@ int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface) template.depth[0] = 1; template.compressed = 0; template.cpp = 4; + template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; sfc->texture = pipe->screen->texture_create(pipe->screen, &template); -- cgit v1.2.3 From 0a6aec8c0f2173cfb95ce95d12b66f090ea0ba1f Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 18 Jun 2008 22:21:11 -0400 Subject: g3dvl: Work around SP tex cache bug, specify resource usage flags. --- src/gallium/state_trackers/g3dvl/vl_context.c | 1 - src/gallium/state_trackers/g3dvl/vl_surface.c | 14 +++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 59a1ccd152..3b9afabbb8 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -2218,7 +2218,6 @@ int vlDestroyContext(struct VL_CONTEXT *context) vlDestroy(context); - context->pipe->screen->destroy(context->pipe->screen); context->pipe->destroy(context->pipe); free(context); diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 3f59d0f155..6451e54953 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -31,7 +31,7 @@ static int vlGrabBlocks 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE ); - texels = pipe_surface_map(tex_surface, 0); + texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); for (b = 0; b < 4; ++b) { @@ -131,7 +131,7 @@ static int vlGrabBlocks 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE ); - texels = pipe_surface_map(tex_surface, 0); + texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); if ((coded_block_pattern >> (b + 4)) & 1) { @@ -165,6 +165,9 @@ static int vlGrabBlocks pipe_surface_unmap(tex_surface); } + /* XXX: Texture cache is not invalidated when texture contents change */ + context->pipe->flush(context->pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL); + return 0; } @@ -265,7 +268,7 @@ int vlRenderIMacroBlock ( pipe->screen, surface->texture, - 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE + 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE ); pipe->set_framebuffer_state(pipe, &surface->context->states.mc.render_target); pipe->set_sampler_textures(pipe, 3, surface->context->states.mc.textures); @@ -346,7 +349,7 @@ int vlRenderPMacroBlock ( pipe->screen, surface->texture, - 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE + 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE ); pipe->set_framebuffer_state(pipe, &surface->context->states.mc.render_target); @@ -434,7 +437,7 @@ int vlRenderBMacroBlock ( pipe->screen, surface->texture, - 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE + 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE ); pipe->set_framebuffer_state(pipe, &surface->context->states.mc.render_target); @@ -510,6 +513,7 @@ int vlPutSurface destw, desth, PIPE_FORMAT_A8R8G8B8_UNORM, + /*XXX: SoftPipe doesn't change GPU usage to CPU like it does for textures */ PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE, 0 ); -- cgit v1.2.3 From 3933fec6bd62285506fecdc3a254306648cfefb2 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 28 Jun 2008 20:16:01 -0400 Subject: g3dvl: Support for field and frame based MC for progressive pictures. MC support for frame and field based motion prediction. Also various bug fixes, clean up. --- src/gallium/state_trackers/g3dvl/tests/.gitignore | 2 +- src/gallium/state_trackers/g3dvl/tests/Makefile | 7 +- .../state_trackers/g3dvl/tests/test_pf_rendering.c | 214 +++ src/gallium/state_trackers/g3dvl/vl_context.c | 1688 ++++++++++++++++++-- src/gallium/state_trackers/g3dvl/vl_context.h | 4 +- src/gallium/state_trackers/g3dvl/vl_data.c | 3 +- src/gallium/state_trackers/g3dvl/vl_surface.c | 404 ++--- src/gallium/state_trackers/g3dvl/vl_types.h | 12 +- src/libXvMC/surface.c | 34 +- 9 files changed, 2057 insertions(+), 311 deletions(-) create mode 100644 src/gallium/state_trackers/g3dvl/tests/test_pf_rendering.c (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/tests/.gitignore b/src/gallium/state_trackers/g3dvl/tests/.gitignore index 939666da9a..9b1ec4e212 100644 --- a/src/gallium/state_trackers/g3dvl/tests/.gitignore +++ b/src/gallium/state_trackers/g3dvl/tests/.gitignore @@ -2,5 +2,5 @@ test_context test_surface test_i_rendering test_p_rendering +test_pf_rendering test_b_rendering - diff --git a/src/gallium/state_trackers/g3dvl/tests/Makefile b/src/gallium/state_trackers/g3dvl/tests/Makefile index 8f983593c3..45cefa2e57 100644 --- a/src/gallium/state_trackers/g3dvl/tests/Makefile +++ b/src/gallium/state_trackers/g3dvl/tests/Makefile @@ -20,7 +20,7 @@ LIBS += -lg3dvl -lsoftpipe -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lutil .PHONY = all clean -all: test_context test_surface test_i_rendering test_p_rendering test_b_rendering +all: test_context test_surface test_i_rendering test_p_rendering test_pf_rendering test_b_rendering test_context: test_context.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} @@ -34,9 +34,12 @@ test_i_rendering: test_i_rendering.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o test_p_rendering: test_p_rendering.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o $(CC) ${LDFLAGS} -o $@ $^ ${LIBS} +test_pf_rendering: test_pf_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 + rm -rf *.o test_context test_surface test_i_rendering test_p_rendering test_pf_rendering test_b_rendering diff --git a/src/gallium/state_trackers/g3dvl/tests/test_pf_rendering.c b/src/gallium/state_trackers/g3dvl/tests/test_pf_rendering.c new file mode 100644 index 0000000000..43586fc553 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/tests/test_pf_rendering.c @@ -0,0 +1,214 @@ +#include +#include +#include +#include +#include + +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] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 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}, {32, 32} + }; + + 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_FIELD_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/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 3b9afabbb8..d2b1ad7948 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -36,8 +36,8 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) const unsigned int semantic_names[3] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC, - TGSI_SEMANTIC_GENERIC, + TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ + TGSI_SEMANTIC_GENERIC, /* Chroma texcoords */ }; const unsigned int semantic_indexes[3] = {0, 1, 2}; const unsigned int proc_type = TGSI_PROCESSOR_VERTEX; @@ -353,7 +353,7 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) return 0; } -static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) +static int vlCreateVertexShaderFramePMC(struct VL_CONTEXT *context) { const unsigned int max_tokens = 100; const unsigned int num_input_attribs = 3; @@ -361,15 +361,15 @@ static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) const unsigned int input_semantic_names[3] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC, - TGSI_SEMANTIC_GENERIC + TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ + TGSI_SEMANTIC_GENERIC /* Chroma texcoords */ }; const unsigned int output_semantic_names[4] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC, - TGSI_SEMANTIC_GENERIC, - TGSI_SEMANTIC_GENERIC + TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ + TGSI_SEMANTIC_GENERIC, /* Chroma texcoords */ + TGSI_SEMANTIC_GENERIC /* Ref surface texcoords */ }; const unsigned int input_semantic_indexes[3] = {0, 1, 2}; const unsigned int output_semantic_indexes[4] = {0, 1, 2, 3}; @@ -430,14 +430,15 @@ static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) /* 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 */ + C[2] unused + C[3] 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; + decl.u.DeclarationRange.Last = 3; ti += tgsi_build_full_declaration ( &decl, @@ -526,7 +527,7 @@ static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) ); } - /* add o3, t0, c2 ; Translate texcoords into position */ + /* add o3, t0, c3 ; Translate texcoords into position */ inst = tgsi_default_full_instruction(); inst.Instruction.Opcode = TGSI_OPCODE_ADD; inst.Instruction.NumDstRegs = 1; @@ -536,6 +537,264 @@ static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) 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 = 3; + 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[0] = pipe->create_vs_state(pipe, &vs); + + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 100; + const unsigned int num_input_attribs = 3; + const unsigned int num_output_attribs = 6; + const unsigned int input_semantic_names[3] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ + TGSI_SEMANTIC_GENERIC /* Chroma texcoords */ + }; + const unsigned int output_semantic_names[6] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ + TGSI_SEMANTIC_GENERIC, /* Chroma texcoords */ + TGSI_SEMANTIC_GENERIC, /* Top field surface texcoords */ + TGSI_SEMANTIC_GENERIC, /* Bottom field surface texcoords */ + TGSI_SEMANTIC_POSITION /* Pos */ + }; + const unsigned int input_semantic_indexes[3] = {0, 1, 2}; + const unsigned int output_semantic_indexes[6] = {0, 1, 2, 3, 4, 5}; + 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] denormalizes pos components + C[3] translates the ref surface top field texcoords to the ref macroblock + C[4] translates the ref surface bottom field 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 = 4; + 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 t1, 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_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 1; + 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 o0, t1 ; Move vertex pos to output */ + 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 = 0; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].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, c3 ; Translate top field texcoords into position + add o4, t0, c4 ; Translate bottom field texcoords into position */ + 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 + 3; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* mul o5, t1, c2 ; Denorm pos for fragment shader */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MUL; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 5; + 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 = 2; ti += tgsi_build_full_instruction ( @@ -560,14 +819,14 @@ static int vlCreateVertexShaderPMC(struct VL_CONTEXT *context) vs.tokens = tokens; - context->states.mc.p_vs = pipe->create_vs_state(pipe, &vs); + context->states.mc.p_vs[1] = pipe->create_vs_state(pipe, &vs); free(tokens); return 0; } -static int vlCreateFragmentShaderPMC(struct VL_CONTEXT *context) +static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) { const unsigned int max_tokens = 100; const unsigned int proc_type = TGSI_PROCESSOR_FRAGMENT; @@ -837,42 +1096,928 @@ static int vlCreateFragmentShaderPMC(struct VL_CONTEXT *context) fs.tokens = tokens; - context->states.mc.p_fs = pipe->create_fs_state(pipe, &fs); + context->states.mc.p_fs[0] = pipe->create_fs_state(pipe, &fs); free(tokens); return 0; } -static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) +static int vlCreateFragmentShaderFieldPMC(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, + const unsigned int max_tokens = 200; + 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) + I[0] Luma texcoords + I[1] Chroma texcoords + I[2] Ref top field surface texcoords + I[3] Ref bottom field surface texcoords + I[4] Denormalized texel pos */ + for (i = 0; i < 5; ++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[1] is a bias to get differential back to -1,1 range + C[2] is constants 2 and 1/2 for Y%2 field selector */ + 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 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 top field + tex2d t2, i3, s3 ; Read texel from ref macroblock bottom field */ + 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 = 3; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* XXX: Pos values off by 0.5 for rounding? */ + /* sub t4, i4.y, c2.x ; Sub 0.5 from position */ + 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 = 4; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 4; + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 2; + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* mul t3, t4, c2.x ; Divide pos y coord by 2 (mul by 0.5) */ + 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 = 3; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 4; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 2; + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* floor t3, t3 ; Get rid of fractional part */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_FLOOR; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 3; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 3; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* mul t3, t3, c2.y ; Multiply by 2 */ + 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 = 3; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 3; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 2; + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* sub t3, t4, t3 ; Subtract from y to get y % 2 */ + 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 = 3; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 4; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 3; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* lerp t1, t3, t1, t2 */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_LERP; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 1; + inst.Instruction.NumSrcRegs = 3; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 3; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + inst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[2].SrcRegister.Index = 2; + 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[1] = pipe->create_fs_state(pipe, &fs); + + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFrameBMC(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 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] unused + C[3] translates the past surface texcoords to the ref macroblock + C[4] unused + C[5] 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 = 5; + 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, c3 ; Translate past surface texcoords into position + add o4, t0, c5 ; 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 + 3; + 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[0] = pipe->create_vs_state(pipe, &vs); + + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFieldBMC(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 100; + const unsigned int num_input_attribs = 3; + const unsigned int num_output_attribs = 8; + const unsigned int input_semantic_names[3] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ + TGSI_SEMANTIC_GENERIC /* Chroma texcoords */ + }; + const unsigned int output_semantic_names[8] = + { + TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ + TGSI_SEMANTIC_GENERIC, /* Chroma texcoords */ + TGSI_SEMANTIC_GENERIC, /* Top field past surface texcoords */ + TGSI_SEMANTIC_GENERIC, /* Bottom field past surface texcoords */ + TGSI_SEMANTIC_GENERIC, /* Top field future surface texcoords */ + TGSI_SEMANTIC_GENERIC, /* Bottom field future surface texcoords */ + TGSI_SEMANTIC_POSITION /* Pos */ + }; + const unsigned int input_semantic_indexes[3] = {0, 1, 2}; + const unsigned int output_semantic_indexes[8] = {0, 1, 2, 3, 4, 5, 6, 7}; const unsigned int proc_type = TGSI_PROCESSOR_VERTEX; struct pipe_context *pipe; - struct pipe_shader_state vs; + 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] denormalizes pos components + C[3] translates the past surface top field texcoords to the ref macroblock + C[4] translates the past surface bottom field texcoords to the ref macroblock + C[5] translates the future surface top field texcoords to the ref macroblock + C[6] translates the future surface bottom field 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 = 6; + 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 t1, 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_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 1; + 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 o0, t1 ; Move vertex pos to output */ + 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 = 0; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].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, c3 ; Translate top field past texcoords into position + add o4, t0, c4 ; Translate bottom field past texcoords into position + add o5, t0, c5 ; Translate top field past texcoords into position + add o6, t0, c6 ; Translate bottom field past texcoords into position */ + for (i = 0; i < 4; ++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 + 3; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* mul o7, t1, c2 ; Denorm pos for fragment shader */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MUL; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 7; + 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 = 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[1] = pipe->create_vs_state(pipe, &vs); + + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderFrameBMC(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; @@ -882,12 +2027,12 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) 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(); @@ -898,16 +2043,16 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) ti = 3; - /* Declare inputs (pos, texcoords) */ - for (i = 0; i < num_input_attribs; i++) + /* 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 = input_semantic_names[i]; - decl.Semantic.SemanticIndex = input_semantic_indexes[i]; - + 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 @@ -919,18 +2064,17 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) ); } - /* 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 */ + /* Declare constant input */ + /* C[0] is a multiplier to use when concatenating differential into a single channel + C[1] is a bias to get differential back to -1,1 range + C[2] contains 0.5 in channel X for use as a weight to blend past and future samples */ 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; + decl.u.DeclarationRange.Last = 2; ti += tgsi_build_full_declaration ( &decl, @@ -939,14 +2083,27 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) max_tokens - ti ); - /* Declare outputs (pos, texcoords) */ - for (i = 0; i < num_output_attribs; i++) + /* 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_OUTPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = output_semantic_names[i]; - decl.Semantic.SemanticIndex = output_semantic_indexes[i]; + decl.Declaration.File = TGSI_FILE_SAMPLER; decl.u.DeclarationRange.First = i; decl.u.DeclarationRange.Last = i; ti += tgsi_build_full_declaration @@ -958,15 +2115,67 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) ); } - /* mul t0, i0, c0 ; Scale normalized coords to window coords */ + /* + 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 = 0; + inst.FullDstRegisters[0].DstRegister.Index = 1; inst.Instruction.NumSrcRegs = 2; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = 0; + 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 @@ -976,17 +2185,17 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) header, max_tokens - ti ); - - /* add o0, t0, c1 ; Translate vertex into position */ + + /* 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_OUTPUT; + 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.File = TGSI_FILE_TEMPORARY; inst.FullSrcRegisters[1].SrcRegister.Index = 1; ti += tgsi_build_full_instruction ( @@ -996,43 +2205,40 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) 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 - ); - } + /* 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 + ); - /* add o3, t0, c2 ; Translate past surface texcoords into position - add o4, t0, c3 ; Repeat for future surface texcoords */ + /* 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_ADD; + inst.Instruction.Opcode = TGSI_OPCODE_TEX; inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - inst.FullDstRegisters[0].DstRegister.Index = i + 3; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = i + 1; 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; + 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, @@ -1041,6 +2247,50 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) max_tokens - ti ); } + + /* lerp t1, c2.x, t1, t2 ; Blend past and future texels */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_LERP; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 1; + inst.Instruction.NumSrcRegs = 3; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[0].SrcRegister.Index = 2; + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + inst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[2].SrcRegister.Index = 2; + 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(); @@ -1054,19 +2304,19 @@ static int vlCreateVertexShaderBMC(struct VL_CONTEXT *context) header, max_tokens - ti ); + + fs.tokens = tokens; - vs.tokens = tokens; - - context->states.mc.b_vs = pipe->create_vs_state(pipe, &vs); + context->states.mc.b_fs[0] = pipe->create_fs_state(pipe, &fs); free(tokens); return 0; } -static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) +static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) { - const unsigned int max_tokens = 100; + const unsigned int max_tokens = 200; const unsigned int proc_type = TGSI_PROCESSOR_FRAGMENT; struct pipe_context *pipe; @@ -1100,8 +2350,15 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) ti = 3; - /* Declare inputs (texcoords) */ - for (i = 0; i < 4; ++i) + /* Declare inputs (texcoords) + I[0] Luma texcoords + I[1] Chroma texcoords + I[2] Past top field surface texcoords + I[3] Past bottom field surface texcoords + I[4] Future top field surface texcoords + I[5] Future bottom field surface texcoords + I[6] Denormalized texel pos */ + for (i = 0; i < 7; ++i) { decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; @@ -1123,14 +2380,15 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) /* 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*/ + C[1] is a bias to get differential back to -1,1 range + C[2] is constants 2 and 1/2 for Y%2 field selector */ 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; + decl.u.DeclarationRange.Last = 2; ti += tgsi_build_full_declaration ( &decl, @@ -1280,8 +2538,118 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) max_tokens - ti ); - /* tex2d t1, i2, s3 ; Read texel from past macroblock - tex2d t2, i3, s4 ; Read texel from future macroblock */ + /* XXX: Pos values off by 0.5 for rounding? */ + /* sub t4, i6.y, c2.x ; Sub 0.5 from position */ + 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 = 4; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 6; + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 2; + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* mul t3, t4, c2.x ; Divide pos y coord by 2 (mul by 0.5) */ + 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 = 3; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 4; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 2; + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* floor t3, t3 ; Get rid of fractional part */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_FLOOR; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 3; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 3; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* mul t3, t3, c2.y ; Multiply by 2 */ + 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 = 3; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 3; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[1].SrcRegister.Index = 2; + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* sub t3, t4, t3 ; Subtract from y to get y % 2 */ + 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 = 3; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 4; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 3; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* tex2d t1, i2, s3 ; Read texel from past macroblock top field + tex2d t2, i3, s3 ; Read texel from past macroblock bottom field */ for (i = 0; i < 2; ++i) { inst = tgsi_default_full_instruction(); @@ -1294,7 +2662,7 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) 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; + inst.FullSrcRegisters[1].SrcRegister.Index = 3; ti += tgsi_build_full_instruction ( &inst, @@ -1304,17 +2672,89 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) ); } - /* add t0, t0, t1 ; Add past and differential to form partial output */ + /* lerp t1, t3, t1, t2 */ inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_ADD; + inst.Instruction.Opcode = TGSI_OPCODE_LERP; inst.Instruction.NumDstRegs = 1; inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = 0; - inst.Instruction.NumSrcRegs = 2; + inst.FullDstRegisters[0].DstRegister.Index = 1; + inst.Instruction.NumSrcRegs = 3; inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[0].SrcRegister.Index = 3; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; + inst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[2].SrcRegister.Index = 2; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* tex2d t4, i4, s4 ; Read texel from future macroblock top field + tex2d t5, i5, s4 ; Read texel from future macroblock bottom field */ + 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 + 4; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i + 4; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + inst.FullSrcRegisters[1].SrcRegister.Index = 4; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* lerp t2, t3, t4, t5 */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_LERP; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 2; + inst.Instruction.NumSrcRegs = 3; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[0].SrcRegister.Index = 3; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[1].SrcRegister.Index = 4; + inst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[2].SrcRegister.Index = 5; + ti += tgsi_build_full_instruction + ( + &inst, + &tokens[ti], + header, + max_tokens - ti + ); + + /* lerp t1, c2.x, t1, t2 */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_LERP; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + inst.FullDstRegisters[0].DstRegister.Index = 1; + inst.Instruction.NumSrcRegs = 3; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_CONSTANT; + inst.FullSrcRegisters[0].SrcRegister.Index = 2; + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; inst.FullSrcRegisters[1].SrcRegister.Index = 1; + inst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; + inst.FullSrcRegisters[2].SrcRegister.Index = 2; ti += tgsi_build_full_instruction ( &inst, @@ -1323,7 +2763,7 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) max_tokens - ti ); - /* add o0, t0, t2 ; Add future and differential to form final output */ + /* add o0, t0, t1 ; Add future and differential to form final output */ inst = tgsi_default_full_instruction(); inst.Instruction.Opcode = TGSI_OPCODE_ADD; inst.Instruction.NumDstRegs = 1; @@ -1333,7 +2773,7 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) 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; + inst.FullSrcRegisters[1].SrcRegister.Index = 1; ti += tgsi_build_full_instruction ( &inst, @@ -1357,7 +2797,7 @@ static int vlCreateFragmentShaderBMC(struct VL_CONTEXT *context) fs.tokens = tokens; - context->states.mc.b_fs = pipe->create_fs_state(pipe, &fs); + context->states.mc.b_fs[1] = pipe->create_fs_state(pipe, &fs); free(tokens); @@ -1491,7 +2931,6 @@ static int vlInitMC(struct VL_CONTEXT *context) 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; @@ -1530,6 +2969,7 @@ static int vlInitMC(struct VL_CONTEXT *context) 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) @@ -1548,10 +2988,14 @@ static int vlInitMC(struct VL_CONTEXT *context) vlCreateVertexShaderIMC(context); vlCreateFragmentShaderIMC(context); - vlCreateVertexShaderPMC(context); - vlCreateFragmentShaderPMC(context); - vlCreateVertexShaderBMC(context); - vlCreateFragmentShaderBMC(context); + vlCreateVertexShaderFramePMC(context); + vlCreateVertexShaderFieldPMC(context); + vlCreateFragmentShaderFramePMC(context); + vlCreateFragmentShaderFieldPMC(context); + vlCreateVertexShaderFrameBMC(context); + vlCreateVertexShaderFieldBMC(context); + vlCreateFragmentShaderFrameBMC(context); + vlCreateFragmentShaderFieldBMC(context); vlCreateDataBufsMC(context); return 0; @@ -1575,10 +3019,14 @@ static int vlDestroyMC(struct VL_CONTEXT *context) 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); + + for (i = 0; i < 2; ++i) + { + context->pipe->delete_vs_state(context->pipe, context->states.mc.p_vs[i]); + context->pipe->delete_fs_state(context->pipe, context->states.mc.p_fs[i]); + context->pipe->delete_vs_state(context->pipe, context->states.mc.b_vs[i]); + context->pipe->delete_fs_state(context->pipe, context->states.mc.b_fs[i]); + } 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); @@ -1982,7 +3430,7 @@ static int vlCreateDataBufsCSC(struct VL_CONTEXT *context) /* TODO: Refactor this into a seperate function, - allow changing the csc matrix at runtime to switch between regular & full versions + allow changing the CSC matrix at runtime to switch between regular & full versions */ memcpy ( @@ -2166,7 +3614,7 @@ static int vlDestroy(struct VL_CONTEXT *context) { assert(context); - /* Must unbind shaders before we can delete them for some reason */ + /* XXX: 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); diff --git a/src/gallium/state_trackers/g3dvl/vl_context.h b/src/gallium/state_trackers/g3dvl/vl_context.h index f26a4c5b6a..8a12318073 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.h +++ b/src/gallium/state_trackers/g3dvl/vl_context.h @@ -34,8 +34,8 @@ struct VL_CONTEXT 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_shader_state *i_vs, *p_vs[2], *b_vs[2]; + struct pipe_shader_state *i_fs, *p_fs[2], *b_fs[2]; 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; diff --git a/src/gallium/state_trackers/g3dvl/vl_data.c b/src/gallium/state_trackers/g3dvl/vl_data.c index 27893aee95..7e6ee8ac12 100644 --- a/src/gallium/state_trackers/g3dvl/vl_data.c +++ b/src/gallium/state_trackers/g3dvl/vl_data.c @@ -87,7 +87,8 @@ const struct VL_TEXCOORD2F *vl_surface_texcoords = (const struct VL_TEXCOORD2F*) 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} + {256.0f / 255.0f, 256.0f / 255.0f, 256.0f / 255.0f, 0.0f}, + {0.5f, 2.0f, 0.0f, 0.0f} }; /* diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 6451e54953..d2220d7abf 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -8,6 +8,85 @@ #include "vl_context.h" #include "vl_defs.h" +static int vlGrabFrameCodedFullBlock(short *src, short *dst, unsigned int dst_pitch) +{ + unsigned int y; + + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + memcpy + ( + dst + y * dst_pitch, + src + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + + return 0; +} + +static int vlGrabFrameCodedDiffBlock(short *src, short *dst, unsigned int dst_pitch) +{ + unsigned int x, y; + + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + dst[y * dst_pitch + x] = src[y * VL_BLOCK_WIDTH + x] + 0x100; + + return 0; +} + +static int vlGrabFieldCodedFullBlock(short *src, short *dst, unsigned int dst_pitch) +{ + unsigned int y; + + for (y = 0; y < VL_BLOCK_HEIGHT / 2; ++y) + memcpy + ( + dst + y * dst_pitch * 2, + src + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + + dst += VL_BLOCK_HEIGHT * dst_pitch; + + for (; y < VL_BLOCK_HEIGHT; ++y) + memcpy + ( + dst + y * dst_pitch * 2, + src + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + + return 0; +} + +static int vlGrabFieldCodedDiffBlock(short *src, short *dst, unsigned int dst_pitch) +{ + unsigned int x, y; + + for (y = 0; y < VL_BLOCK_HEIGHT / 2; ++y) + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + dst[y * dst_pitch * 2 + x] = src[y * VL_BLOCK_WIDTH + x] + 0x100; + + dst += VL_BLOCK_HEIGHT * dst_pitch; + + for (; y < VL_BLOCK_HEIGHT; ++y) + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + dst[y * dst_pitch * 2 + x] = src[y * VL_BLOCK_WIDTH + x] + 0x100; + + return 0; +} + +static int vlGrabNoBlock(short *dst, unsigned int dst_pitch) +{ + unsigned int x, y; + + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + dst[y * dst_pitch + x] = 0x100; + + return 0; +} + static int vlGrabBlocks ( struct VL_CONTEXT *context, @@ -19,7 +98,7 @@ static int vlGrabBlocks { struct pipe_surface *tex_surface; short *texels; - unsigned int b, x, y, y2; + unsigned int tb, sb = 0; assert(context); assert(blocks); @@ -33,134 +112,81 @@ static int vlGrabBlocks texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); - for (b = 0; b < 4; ++b) + for (tb = 0; tb < 4; ++tb) { - if ((coded_block_pattern >> b) & 1) + if ((coded_block_pattern >> (5 - tb)) & 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 - ); - } + vlGrabFrameCodedFullBlock + ( + blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, + texels + tb * tex_surface->pitch * VL_BLOCK_HEIGHT, + tex_surface->pitch + ); 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; - } - } + vlGrabFrameCodedDiffBlock + ( + blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, + texels + tb * tex_surface->pitch * VL_BLOCK_HEIGHT, + tex_surface->pitch + ); else - { if (sample_type == VL_FULL_SAMPLE) - { - for + vlGrabFieldCodedFullBlock ( - 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 - ); - } + blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, + texels + (tb % 2) * tex_surface->pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_surface->pitch, + tex_surface->pitch + ); else - { - for + vlGrabFieldCodedDiffBlock ( - 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; - } - } + blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, + texels + (tb % 2) * tex_surface->pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_surface->pitch, + tex_surface->pitch + ); + ++sb; } 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; - } - } + vlGrabNoBlock(texels + tb * tex_surface->pitch * VL_BLOCK_HEIGHT, tex_surface->pitch); } pipe_surface_unmap(tex_surface); /* TODO: Implement 422, 444 */ - for (b = 0; b < 2; ++b) + for (tb = 0; tb < 2; ++tb) { 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 - ); + ( + context->pipe->screen, + context->states.mc.textures[tb + 1], + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE + ); texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); - if ((coded_block_pattern >> (b + 4)) & 1) - { + if ((coded_block_pattern >> (1 - tb)) & 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 - ); - } + vlGrabFrameCodedFullBlock + ( + blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, + texels, + tex_surface->pitch + ); 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; - } + vlGrabFrameCodedDiffBlock + ( + blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, + texels, + tex_surface->pitch + ); + + ++sb; } else - { - for (y = 0; y < tex_surface->height; ++y) - { - for (x = 0; x < VL_BLOCK_WIDTH; ++x) - texels[y * tex_surface->pitch + x] = 0x100; - } - } + vlGrabNoBlock(texels, tex_surface->pitch); pipe_surface_unmap(tex_surface); } @@ -229,41 +255,35 @@ int vlRenderIMacroBlock ) { struct pipe_context *pipe; - struct VL_MC_VS_CONSTS *vscbdata; + struct VL_MC_VS_CONSTS *vs_consts; 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 + vs_consts = 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; + vs_consts->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width; + vs_consts->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height; + vs_consts->scale.z = 1.0f; + vs_consts->scale.w = 1.0f; + vs_consts->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width; + vs_consts->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height; + vs_consts->mb_pos_trans.z = 0.0f; + vs_consts->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, @@ -276,6 +296,8 @@ int vlRenderIMacroBlock pipe->bind_vs_state(pipe, surface->context->states.mc.i_vs); pipe->bind_fs_state(pipe, surface->context->states.mc.i_fs); + vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_FULL_SAMPLE, blocks); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); return 0; @@ -297,7 +319,7 @@ int vlRenderPMacroBlock ) { struct pipe_context *pipe; - struct VL_MC_VS_CONSTS *vscbdata; + struct VL_MC_VS_CONSTS *vs_consts; assert(motion_vectors); assert(blocks); @@ -305,46 +327,55 @@ int vlRenderPMacroBlock 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");*/ + /* TODO: Implement other MC types */ + if (mc_type != VL_FRAME_MC && mc_type != VL_FIELD_MC) return 0; - } pipe = surface->context->pipe; - vscbdata = pipe->winsys->buffer_map + vs_consts = 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; + vs_consts->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width; + vs_consts->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height; + vs_consts->scale.z = 1.0f; + vs_consts->scale.w = 1.0f; + vs_consts->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width; + vs_consts->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height; + vs_consts->mb_pos_trans.z = 0.0f; + vs_consts->mb_pos_trans.w = 0.0f; + vs_consts->mb_tc_trans[0].top_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector->top_field.x * 0.5f) / (float)surface->width; + vs_consts->mb_tc_trans[0].top_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector->top_field.y * 0.5f) / (float)surface->height; + vs_consts->mb_tc_trans[0].top_field.z = 0.0f; + vs_consts->mb_tc_trans[0].top_field.w = 0.0f; + + if (mc_type == VL_FIELD_MC) + { + vs_consts->denorm.x = (float)surface->width; + vs_consts->denorm.y = (float)surface->height; + + vs_consts->mb_tc_trans[0].bottom_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector->bottom_field.x * 0.5f) / (float)surface->width; + vs_consts->mb_tc_trans[0].bottom_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector->bottom_field.y * 0.5f) / (float)surface->height; + vs_consts->mb_tc_trans[0].bottom_field.z = 0.0f; + vs_consts->mb_tc_trans[0].bottom_field.w = 0.0f; + + pipe->bind_vs_state(pipe, surface->context->states.mc.p_vs[1]); + pipe->bind_fs_state(pipe, surface->context->states.mc.p_fs[1]); + } + else + { + pipe->bind_vs_state(pipe, surface->context->states.mc.p_vs[0]); + pipe->bind_fs_state(pipe, surface->context->states.mc.p_fs[0]); + } 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, @@ -356,8 +387,8 @@ int vlRenderPMacroBlock 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); + + vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks); pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); @@ -381,7 +412,7 @@ int vlRenderBMacroBlock ) { struct pipe_context *pipe; - struct VL_MC_VS_CONSTS *vscbdata; + struct VL_MC_VS_CONSTS *vs_consts; assert(motion_vectors); assert(blocks); @@ -389,50 +420,63 @@ int vlRenderBMacroBlock 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");*/ + /* TODO: Implement other MC types */ + if (mc_type != VL_FRAME_MC && mc_type != VL_FIELD_MC) return 0; - } pipe = surface->context->pipe; - vscbdata = pipe->winsys->buffer_map + vs_consts = 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; + vs_consts->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width; + vs_consts->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height; + vs_consts->scale.z = 1.0f; + vs_consts->scale.w = 1.0f; + vs_consts->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width; + vs_consts->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height; + vs_consts->mb_pos_trans.z = 0.0f; + vs_consts->mb_pos_trans.w = 0.0f; + vs_consts->mb_tc_trans[0].top_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[0].top_field.x * 0.5f) / (float)surface->width; + vs_consts->mb_tc_trans[0].top_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[0].top_field.y * 0.5f) / (float)surface->height; + vs_consts->mb_tc_trans[0].top_field.z = 0.0f; + vs_consts->mb_tc_trans[0].top_field.w = 0.0f; + vs_consts->mb_tc_trans[1].top_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[1].top_field.x * 0.5f) / (float)surface->width; + vs_consts->mb_tc_trans[1].top_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[1].top_field.y * 0.5f) / (float)surface->height; + vs_consts->mb_tc_trans[1].top_field.z = 0.0f; + vs_consts->mb_tc_trans[1].top_field.w = 0.0f; + + if (mc_type == VL_FIELD_MC) + { + vs_consts->denorm.x = (float)surface->width; + vs_consts->denorm.y = (float)surface->height; + + vs_consts->mb_tc_trans[0].bottom_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[0].bottom_field.x * 0.5f) / (float)surface->width; + vs_consts->mb_tc_trans[0].bottom_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[0].bottom_field.y * 0.5f) / (float)surface->height; + vs_consts->mb_tc_trans[0].bottom_field.z = 0.0f; + vs_consts->mb_tc_trans[0].bottom_field.w = 0.0f; + vs_consts->mb_tc_trans[1].bottom_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[1].bottom_field.x * 0.5f) / (float)surface->width; + vs_consts->mb_tc_trans[1].bottom_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[1].bottom_field.y * 0.5f) / (float)surface->height; + vs_consts->mb_tc_trans[1].bottom_field.z = 0.0f; + vs_consts->mb_tc_trans[1].bottom_field.w = 0.0f; + + pipe->bind_vs_state(pipe, surface->context->states.mc.b_vs[1]); + pipe->bind_fs_state(pipe, surface->context->states.mc.b_fs[1]); + } + else + { + pipe->bind_vs_state(pipe, surface->context->states.mc.b_vs[0]); + pipe->bind_fs_state(pipe, surface->context->states.mc.b_fs[0]); + } 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, @@ -445,8 +489,8 @@ int vlRenderBMacroBlock 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); + + vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks); pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); @@ -513,7 +557,7 @@ int vlPutSurface destw, desth, PIPE_FORMAT_A8R8G8B8_UNORM, - /*XXX: SoftPipe doesn't change GPU usage to CPU like it does for textures */ + /* XXX: SoftPipe doesn't change GPU usage to CPU like it does for textures */ PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE, 0 ); diff --git a/src/gallium/state_trackers/g3dvl/vl_types.h b/src/gallium/state_trackers/g3dvl/vl_types.h index 7040b74503..97753699db 100644 --- a/src/gallium/state_trackers/g3dvl/vl_types.h +++ b/src/gallium/state_trackers/g3dvl/vl_types.h @@ -36,7 +36,9 @@ enum VL_SAMPLE_TYPE enum VL_MC_TYPE { VL_FIELD_MC, - VL_FRAME_MC + VL_FRAME_MC, + VL_DUAL_PRIME_MC, + VL_16x8_MC = VL_FRAME_MC }; struct VL_VERTEX4F @@ -58,13 +60,19 @@ struct VL_MC_VS_CONSTS { struct VL_VERTEX4F scale; struct VL_VERTEX4F mb_pos_trans; - struct VL_VERTEX4F mb_tc_trans[2]; + struct VL_VERTEX4F denorm; + struct + { + struct VL_VERTEX4F top_field; + struct VL_VERTEX4F bottom_field; + } mb_tc_trans[2]; }; struct VL_MC_FS_CONSTS { struct VL_VERTEX4F multiplier; struct VL_VERTEX4F bias; + struct VL_VERTEX4F y_divider; }; struct VL_CSC_FS_CONSTS diff --git a/src/libXvMC/surface.c b/src/libXvMC/surface.c index e4602d8204..5656895650 100644 --- a/src/libXvMC/surface.c +++ b/src/libXvMC/surface.c @@ -32,6 +32,34 @@ static enum VL_PICTURE PictureToVL(int xvmc_pic) return vl_pic; } +static enum VL_MC_TYPE MotionToVL(int xvmc_motion_type) +{ + enum VL_MC_TYPE vl_mc_type; + + switch (xvmc_motion_type) + { + case XVMC_PREDICTION_FRAME: + { + vl_mc_type = VL_FRAME_MC; + break; + } + case XVMC_PREDICTION_FIELD: + { + vl_mc_type = VL_FIELD_MC; + break; + } + case XVMC_PREDICTION_DUAL_PRIME: + { + vl_mc_type = VL_DUAL_PRIME_MC; + break; + } + default: + assert(0); + } + + return vl_mc_type; +} + Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) { struct VL_CONTEXT *vl_ctx; @@ -155,7 +183,7 @@ Status XvMCRenderSurface 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, + MotionToVL(macroblocks->macro_blocks[i].motion_type), &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, @@ -188,7 +216,7 @@ Status XvMCRenderSurface 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, + MotionToVL(macroblocks->macro_blocks[i].motion_type), &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, @@ -233,7 +261,7 @@ Status XvMCRenderSurface 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, + MotionToVL(macroblocks->macro_blocks[i].motion_type), 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, -- cgit v1.2.3 From 1c893fd513f5335a81dd72db70d64763634ea856 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 29 Jun 2008 20:52:58 -0400 Subject: g3dvl: Simplify shader code. --- src/gallium/state_trackers/g3dvl/Makefile | 2 +- src/gallium/state_trackers/g3dvl/vl_context.c | 2968 ++++---------------- src/gallium/state_trackers/g3dvl/vl_shader_build.c | 205 ++ src/gallium/state_trackers/g3dvl/vl_shader_build.h | 61 + 4 files changed, 890 insertions(+), 2346 deletions(-) create mode 100644 src/gallium/state_trackers/g3dvl/vl_shader_build.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_shader_build.h (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/Makefile b/src/gallium/state_trackers/g3dvl/Makefile index a0d85fbcc8..bd46d004e2 100644 --- a/src/gallium/state_trackers/g3dvl/Makefile +++ b/src/gallium/state_trackers/g3dvl/Makefile @@ -1,5 +1,5 @@ TARGET = libg3dvl.a -OBJECTS = vl_context.o vl_data.o vl_surface.o +OBJECTS = vl_context.o vl_data.o vl_surface.o vl_shader_build.o GALLIUMDIR = ../.. CFLAGS += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index d2b1ad7948..88da47c06a 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -9,6 +9,7 @@ #include #include #include +#include "vl_shader_build.h" #include "vl_data.h" static int vlInitIDCT(struct VL_CONTEXT *context) @@ -32,21 +33,11 @@ static int vlDestroyIDCT(struct VL_CONTEXT *context) 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, /* Luma texcoords */ - TGSI_SEMANTIC_GENERIC, /* Chroma texcoords */ - }; - 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; @@ -57,158 +48,71 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); ti = 3; - /* Declare inputs (pos, texcoords) */ - for (i = 0; i < num_attribs; i++) + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma 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 = 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 - ); + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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 - ); + /* + * decl c0 ; Scaling vector to scale unit rect to macroblock size + * decl c1 ; Translation vector to move macroblock into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 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 o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma texcoords + */ + for (i = 0; i < 3; 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 - ); + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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 - ); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 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 - ); + /* add o0, t0, c1 ; Translate rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 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) + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma texcoords to output + */ + for (i = 1; i < 3; ++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 - ); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 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 - ); + /* end */ + inst = vl_end(); + 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); - free(tokens); return 0; @@ -217,13 +121,11 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) 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; @@ -234,120 +136,61 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); ti = 3; - /* Declare inputs (texcoords) */ + /* + * decl i0 ; Texcoords for s0 + * decl i1 ; Texcoords for s1, s2 + */ 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 - ); + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + 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 - ); + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - /* Declare samplers */ + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + */ 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 - ); + decl = vl_decl_samplers(i, 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 + * 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 = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_OUTPUT, 0, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); 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 - ); + 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 - ); + /* end */ + inst = vl_end(); + 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); - free(tokens); return 0; @@ -356,30 +199,11 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) static int vlCreateVertexShaderFramePMC(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, /* Luma texcoords */ - TGSI_SEMANTIC_GENERIC /* Chroma texcoords */ - }; - const unsigned int output_semantic_names[4] = - { - TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ - TGSI_SEMANTIC_GENERIC, /* Chroma texcoords */ - TGSI_SEMANTIC_GENERIC /* Ref surface texcoords */ - }; - 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; @@ -390,179 +214,78 @@ static int vlCreateVertexShaderFramePMC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); ti = 3; - /* Declare inputs (pos, texcoords) */ - for (i = 0; i < num_input_attribs; i++) + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma 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 = 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 - ); + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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] unused - C[3] 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 = 3; - ti += tgsi_build_full_declaration - ( - &decl, - &tokens[ti], - header, - max_tokens - ti - ); + /* + * decl c0 ; Scaling vector to scale unit rect to macroblock size + * decl c1 ; Translation vector to move macroblock into position + * decl c2 ; Unused + * decl c3 ; Translation vector to move ref macroblock texcoords into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 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 o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma texcoords + * decl o3 ; Ref macroblock texcoords + */ + for (i = 0; i < 4; 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 - ); + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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 - ); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 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 - ); + /* add o0, t0, c1 ; Translate rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 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) + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma texcoords to output + */ + for (i = 1; i < 3; ++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 - ); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* add o3, t0, c3 ; 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 = 3; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* add o3, t0, c3 ; Translate rect into position on ref macroblock */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 3); + 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 - ); + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); vs.tokens = tokens; - context->states.mc.p_vs[0] = pipe->create_vs_state(pipe, &vs); - free(tokens); return 0; @@ -571,32 +294,11 @@ static int vlCreateVertexShaderFramePMC(struct VL_CONTEXT *context) static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) { const unsigned int max_tokens = 100; - const unsigned int num_input_attribs = 3; - const unsigned int num_output_attribs = 6; - const unsigned int input_semantic_names[3] = - { - TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ - TGSI_SEMANTIC_GENERIC /* Chroma texcoords */ - }; - const unsigned int output_semantic_names[6] = - { - TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ - TGSI_SEMANTIC_GENERIC, /* Chroma texcoords */ - TGSI_SEMANTIC_GENERIC, /* Top field surface texcoords */ - TGSI_SEMANTIC_GENERIC, /* Bottom field surface texcoords */ - TGSI_SEMANTIC_POSITION /* Pos */ - }; - const unsigned int input_semantic_indexes[3] = {0, 1, 2}; - const unsigned int output_semantic_indexes[6] = {0, 1, 2, 3, 4, 5}; - 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; @@ -607,34 +309,26 @@ static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); ti = 3; - /* Declare inputs (pos, texcoords) */ - for (i = 0; i < num_input_attribs; i++) + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma 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 = input_semantic_names[i]; - decl.Semantic.SemanticIndex = input_semantic_indexes[i]; - - decl.u.DeclarationRange.First = i; - decl.u.DeclarationRange.Last = i; + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration ( &decl, @@ -644,183 +338,70 @@ static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) ); } - /* 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] denormalizes pos components - C[3] translates the ref surface top field texcoords to the ref macroblock - C[4] translates the ref surface bottom field 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 = 4; - ti += tgsi_build_full_declaration - ( - &decl, - &tokens[ti], - header, - max_tokens - ti - ); + /* + * decl c0 ; Scaling vector to scale unit rect to macroblock size + * decl c1 ; Translation vector to move macroblock into position + * decl c2 ; Denorm coefficients + * decl c3 ; Translation vector to move top field ref macroblock texcoords into position + * decl c4 ; Translation vector to move bottom field ref macroblock texcoords into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 4); + 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 o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma texcoords + * decl o3 ; Top field ref macroblock texcoords + * decl o4 ; Bottom field ref macroblock texcoords + * decl o5 ; Denormalized vertex pos + */ + for (i = 0; i < 6; 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 - ); + decl = vl_decl_output((i == 0 || i == 5) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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 - ); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* add t1, 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_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = 1; - 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 - ); + /* add t1, t0, c1 ; Translate rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* mov o0, t1 ; Move vertex pos to output */ - 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 = 0; - inst.Instruction.NumSrcRegs = 1; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 1; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 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 + mov o1, i1 ; Move input luma texcoords to output + mov o2, i2 ; Move input chroma texcoords to output */ - for (i = 1; i < num_output_attribs - 1; ++i) + for (i = 1; i < 3; ++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 - ); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* add o3, t0, c3 ; Translate top field texcoords into position - add o4, t0, c4 ; Translate bottom field texcoords into position */ + /* add o3, t0, c3 ; Translate top field rect into position on ref macroblock + add o4, t0, c4 ; Translate bottom field rect into position on ref macroblock */ 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 + 3; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* mul o5, t1, c2 ; Denorm pos for fragment shader */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_MUL; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - inst.FullDstRegisters[0].DstRegister.Index = 5; - 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 = 2; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* mul o5, t1, c2 ; Denorm vertex pos */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 5, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 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 - ); + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); vs.tokens = tokens; - context->states.mc.p_vs[1] = pipe->create_vs_state(pipe, &vs); - free(tokens); return 0; @@ -829,13 +410,11 @@ static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) static int vlCreateFragmentShaderFramePMC(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; @@ -846,258 +425,101 @@ static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); ti = 3; - /* Declare inputs (texcoords) */ + /* + * decl i0 ; Texcoords for s0 + * decl i1 ; Texcoords for s1, s2 + * decl i2 ; Texcoords for s3 + */ 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 - ); + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + 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 - ); + /* + * decl c0 ; Multiplier to shift 9th bit of differential into place + * decl c1 ; Bias to get differential back to a signed value + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 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 - ); + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - /* Declare samplers */ + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for ref surface texture + */ 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 - ); + decl = vl_decl_samplers(i, 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 - */ + * tex2d t0.xw, i0, s0 ; Read texel from luma texture into .x and .w channels + * mov t1.x, t0.w ; Move 9th bit 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 9th bit 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 9th bit 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 = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); 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 - ); + 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 = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0); 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 - ); + 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 - ); + /* mul t1, t1, c0 ; Muliply 9th bit by multiplier to shift it into place */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 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 - ); + /* add t0, t0, t1 ; Add luma and chroma low and high parts to get normalized unsigned 9-bit values */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 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 - ); + /* sub t0, t0, c1 ; Subtract bias to get back signed values */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 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 - ); + /* tex2d t1, i2, s3 ; Read texel from ref macroblock */ + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 2, TGSI_FILE_SAMPLER, 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 - ); + /* add o0, t0, t1 ; Add ref and differential to form final output */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 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 - ); + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); fs.tokens = tokens; - context->states.mc.p_fs[0] = pipe->create_fs_state(pipe, &fs); - free(tokens); return 0; @@ -1106,13 +528,11 @@ static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) { const unsigned int max_tokens = 200; - 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; @@ -1123,399 +543,150 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); ti = 3; - /* Declare inputs (texcoords) - I[0] Luma texcoords - I[1] Chroma texcoords - I[2] Ref top field surface texcoords - I[3] Ref bottom field surface texcoords - I[4] Denormalized texel pos */ + /* + * decl i0 ; Texcoords for s0 + * decl i1 ; Texcoords for s1, s2 + * decl i2 ; Texcoords for s3 + * decl i3 ; Texcoords for s3 + * decl i4 ; Denormalized vertex pos + */ for (i = 0; i < 5; ++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 - ); + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + 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[1] is a bias to get differential back to -1,1 range - C[2] is constants 2 and 1/2 for Y%2 field selector */ - 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 - ); + /* + * decl c0 ; Multiplier to shift 9th bit of differential into place + * decl c1 ; Bias to get differential back to a signed value + * decl c2 ; Constants 1/2 & 2 in .x, .y channels for Y-mod-2 top/bottom field selection + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 2); + 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 - ); + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - /* Declare samplers */ + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for ref surface texture + */ 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 - ); + decl = vl_decl_samplers(i, 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 - */ + * tex2d t0.xw, i0, s0 ; Read texel from luma texture into .x and .w channels + * mov t1.x, t0.w ; Move 9th bit 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 9th bit 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 9th bit 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 = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); 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 - ); + 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 = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0); 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 - ); + 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 - ); + /* mul t1, t1, c0 ; Muliply 9th bit by multiplier to shift it into place */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 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 - ); + /* add t0, t0, t1 ; Add luma and chroma low and high parts to get normalized unsigned 9-bit values */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 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 - ); + /* sub t0, t0, c1 ; Subtract bias to get back signed values */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* tex2d t1, i2, s3 ; Read texel from ref macroblock top field - tex2d t2, i3, s3 ; Read texel from ref macroblock bottom field */ + /* tex2d t1, i2, s3 ; Read texel from ref macroblock top field + tex2d t2, i3, s3 ; Read texel from ref macroblock bottom field */ 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 = 3; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 2, TGSI_FILE_SAMPLER, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* XXX: Pos values off by 0.5 for rounding? */ - /* sub t4, i4.y, c2.x ; Sub 0.5 from position */ - 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 = 4; - inst.Instruction.NumSrcRegs = 2; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = 4; + /* XXX: Pos values off by 0.5? */ + /* sub t4, i4.y, c2.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 4, TGSI_FILE_INPUT, 2); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; - inst.FullSrcRegisters[1].SrcRegister.Index = 2; inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* mul t3, t4, c2.x ; Divide pos y coord by 2 (mul by 0.5) */ - 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 = 3; - inst.Instruction.NumSrcRegs = 2; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 4; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; - inst.FullSrcRegisters[1].SrcRegister.Index = 2; + /* mul t3, t4, c2.x ; Multiply pos Y-coord by 1/2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 2); inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* floor t3, t3 ; Get rid of fractional part */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_FLOOR; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = 3; - inst.Instruction.NumSrcRegs = 1; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 3; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* floor t3, t3 ; Get rid of fractional part */ + inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* mul t3, t3, c2.y ; Multiply by 2 */ - 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 = 3; - inst.Instruction.NumSrcRegs = 2; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 3; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; - inst.FullSrcRegisters[1].SrcRegister.Index = 2; + /* mul t3, t3, c2.y ; Multiply by 2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 2); inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* sub t3, t4, t3 ; Subtract from y to get y % 2 */ - 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 = 3; - inst.Instruction.NumSrcRegs = 2; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 4; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[1].SrcRegister.Index = 3; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* lerp t1, t3, t1, t2 */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_LERP; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = 1; - inst.Instruction.NumSrcRegs = 3; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 3; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[1].SrcRegister.Index = 1; - inst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[2].SrcRegister.Index = 2; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* TODO: Move to conditional tex fetch on t3 instead of lerp */ + /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + 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 - ); + /* add o0, t0, t1 ; Add ref and differential to form final output */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 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 - ); + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); fs.tokens = tokens; - context->states.mc.p_fs[1] = pipe->create_fs_state(pipe, &fs); - free(tokens); return 0; @@ -1524,31 +695,11 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) static int vlCreateVertexShaderFrameBMC(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; @@ -1559,185 +710,85 @@ static int vlCreateVertexShaderFrameBMC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); ti = 3; - /* Declare inputs (pos, texcoords) */ - for (i = 0; i < num_input_attribs; i++) + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma 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 = 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 - ); + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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] unused - C[3] translates the past surface texcoords to the ref macroblock - C[4] unused - C[5] 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 = 5; - ti += tgsi_build_full_declaration - ( - &decl, - &tokens[ti], - header, - max_tokens - ti - ); + /* + * decl c0 ; Scaling vector to scale unit rect to macroblock size + * decl c1 ; Translation vector to move macroblock into position + * decl c2 ; Unused + * decl c3 ; Translation vector to move past ref macroblock texcoords into position + * decl c4 ; Unused + * decl c5 ; Translation vector to move future ref macroblock texcoords into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 5); + 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 o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma texcoords + * decl o3 ; Past ref macroblock texcoords + * decl o4 ; Future ref macroblock texcoords + */ + for (i = 0; i < 5; 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 - ); + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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 - ); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o0, t0, c1 ; Translate rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 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) + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma texcoords to output + */ + for (i = 1; i < 3; ++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 - ); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* add o3, t0, c3 ; Translate past surface texcoords into position - add o4, t0, c5 ; Repeat for future surface texcoords */ + /* add o3, t0, c3 ; Translate rect into position on past ref macroblock + add o4, t0, c5 ; Translate rect into position on future ref macroblock */ 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 + 3; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i * 2 + 3); + 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 - ); + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); vs.tokens = tokens; - context->states.mc.b_vs[0] = pipe->create_vs_state(pipe, &vs); - free(tokens); return 0; @@ -1746,34 +797,11 @@ static int vlCreateVertexShaderFrameBMC(struct VL_CONTEXT *context) static int vlCreateVertexShaderFieldBMC(struct VL_CONTEXT *context) { const unsigned int max_tokens = 100; - const unsigned int num_input_attribs = 3; - const unsigned int num_output_attribs = 8; - const unsigned int input_semantic_names[3] = - { - TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ - TGSI_SEMANTIC_GENERIC /* Chroma texcoords */ - }; - const unsigned int output_semantic_names[8] = - { - TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC, /* Luma texcoords */ - TGSI_SEMANTIC_GENERIC, /* Chroma texcoords */ - TGSI_SEMANTIC_GENERIC, /* Top field past surface texcoords */ - TGSI_SEMANTIC_GENERIC, /* Bottom field past surface texcoords */ - TGSI_SEMANTIC_GENERIC, /* Top field future surface texcoords */ - TGSI_SEMANTIC_GENERIC, /* Bottom field future surface texcoords */ - TGSI_SEMANTIC_POSITION /* Pos */ - }; - const unsigned int input_semantic_indexes[3] = {0, 1, 2}; - const unsigned int output_semantic_indexes[8] = {0, 1, 2, 3, 4, 5, 6, 7}; - 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; @@ -1783,225 +811,102 @@ static int vlCreateVertexShaderFieldBMC(struct VL_CONTEXT *context) assert(context); - pipe = context->pipe; - + 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); ti = 3; - /* Declare inputs (pos, texcoords) */ - for (i = 0; i < num_input_attribs; i++) + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma 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 = 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 - ); + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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] denormalizes pos components - C[3] translates the past surface top field texcoords to the ref macroblock - C[4] translates the past surface bottom field texcoords to the ref macroblock - C[5] translates the future surface top field texcoords to the ref macroblock - C[6] translates the future surface bottom field 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 = 6; - ti += tgsi_build_full_declaration - ( - &decl, - &tokens[ti], - header, - max_tokens - ti - ); + /* + * decl c0 ; Scaling vector to scale unit rect to macroblock size + * decl c1 ; Translation vector to move macroblock into position + * decl c2 ; Denorm coefficients + * decl c3 ; Translation vector to move top field past ref macroblock texcoords into position + * decl c4 ; Translation vector to move bottom field past ref macroblock texcoords into position + * decl c5 ; Translation vector to move top field future ref macroblock texcoords into position + * decl c6 ; Translation vector to move bottom field future ref macroblock texcoords into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 6); + 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 o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma texcoords + * decl o3 ; Top field past ref macroblock texcoords + * decl o4 ; Bottom field past ref macroblock texcoords + * decl o5 ; Top field future ref macroblock texcoords + * decl o6 ; Bottom field future ref macroblock texcoords + * decl o7 ; Denormalized vertex pos + */ + for (i = 0; i < 8; 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 - ); + decl = vl_decl_output((i == 0 || i == 7) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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 - ); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* add t1, 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_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = 1; - 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 - ); + /* add t1, t0, c1 ; Translate rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* mov o0, t1 ; Move vertex pos to output */ - 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 = 0; - inst.Instruction.NumSrcRegs = 1; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 1; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 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) + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma texcoords to output + */ + for (i = 1; i < 3; ++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 - ); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* add o3, t0, c3 ; Translate top field past texcoords into position - add o4, t0, c4 ; Translate bottom field past texcoords into position - add o5, t0, c5 ; Translate top field past texcoords into position - add o6, t0, c6 ; Translate bottom field past texcoords into position */ + /* + * add o3, t0, c3 ; Translate top field rect into position on past ref macroblock + * add o4, t0, c4 ; Translate bottom field rect into position on past ref macroblock + * add o5, t0, c5 ; Translate top field rect into position on future ref macroblock + * add o6, t0, c6 ; Translate bottom field rect into position on future ref macroblock + */ for (i = 0; i < 4; ++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 + 3; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* mul o7, t1, c2 ; Denorm pos for fragment shader */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_MUL; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - inst.FullDstRegisters[0].DstRegister.Index = 7; - 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 = 2; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* mul o7, t1, c2 ; Denorm vertex pos */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 7, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 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 - ); + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); vs.tokens = tokens; - context->states.mc.b_vs[1] = pipe->create_vs_state(pipe, &vs); - free(tokens); return 0; @@ -2010,13 +915,11 @@ static int vlCreateVertexShaderFieldBMC(struct VL_CONTEXT *context) static int vlCreateFragmentShaderFrameBMC(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; @@ -2027,288 +930,118 @@ static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); ti = 3; - /* Declare inputs (texcoords) */ + /* + * decl i0 ; Texcoords for s0 + * decl i1 ; Texcoords for s1, s2 + * decl i2 ; Texcoords for s3 + * decl i3 ; Texcoords for s4 + */ 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 - ); + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + 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[1] is a bias to get differential back to -1,1 range - C[2] contains 0.5 in channel X for use as a weight to blend past and future samples */ - 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 - ); + /* + * decl c0 ; Multiplier to shift 9th bit of differential into place + * decl c1 ; Bias to get differential back to a signed value + * decl c2 ; Constant 1/2 in .x channel to use as weight to blend past and future texels + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 2); + 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 - ); + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - /* Declare samplers */ + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for past ref surface texture + * decl s4 ; Sampler for future ref surface texture + */ 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 - ); + decl = vl_decl_samplers(i, 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 - */ + * tex2d t0.xw, i0, s0 ; Read texel from luma texture into .x and .w channels + * mov t1.x, t0.w ; Move 9th bit 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 9th bit 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 9th bit 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 = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); 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 - ); + 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 = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0); 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 - ); + 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 - ); + /* mul t1, t1, c0 ; Muliply 9th bit by multiplier to shift it into place */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 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 - ); + /* add t0, t0, t1 ; Add luma and chroma low and high parts to get normalized unsigned 9-bit values */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 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 - ); + /* sub t0, t0, c1 ; Subtract bias to get back signed values */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 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 */ + /* + * tex2d t1, i2, s3 ; Read texel from past ref macroblock + * tex2d t2, i3, s4 ; Read texel from future ref 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 - ); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 2, TGSI_FILE_SAMPLER, i + 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } /* lerp t1, c2.x, t1, t2 ; Blend past and future texels */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_LERP; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = 1; - inst.Instruction.NumSrcRegs = 3; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_CONSTANT; - inst.FullSrcRegisters[0].SrcRegister.Index = 2; + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 2, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[1].SrcRegister.Index = 1; - inst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[2].SrcRegister.Index = 2; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + 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 - ); + /* add o0, t0, t1 ; Add past/future ref and differential to form final output */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 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 - ); + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); fs.tokens = tokens; - context->states.mc.b_fs[0] = pipe->create_fs_state(pipe, &fs); - free(tokens); return 0; @@ -2317,13 +1050,11 @@ static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) { const unsigned int max_tokens = 200; - 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; @@ -2334,471 +1065,179 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); ti = 3; - /* Declare inputs (texcoords) - I[0] Luma texcoords - I[1] Chroma texcoords - I[2] Past top field surface texcoords - I[3] Past bottom field surface texcoords - I[4] Future top field surface texcoords - I[5] Future bottom field surface texcoords - I[6] Denormalized texel pos */ + /* + * decl i0 ; Texcoords for s0 + * decl i1 ; Texcoords for s1, s2 + * decl i2 ; Texcoords for s3 + * decl i3 ; Texcoords for s3 + * decl i4 ; Texcoords for s4 + * decl i5 ; Texcoords for s4 + * decl i6 ; Denormalized vertex pos + */ for (i = 0; i < 7; ++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 - ); + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + 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[1] is a bias to get differential back to -1,1 range - C[2] is constants 2 and 1/2 for Y%2 field selector */ - 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 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 - ); + /* + * decl c0 ; Multiplier to shift 9th bit of differential into place + * decl c1 ; Bias to get differential back to a signed value + * decl c2 ; Constants 1/2 & 2 in .x, .y channels to use as weight to blend past and future texels + * ; and for Y-mod-2 top/bottom field selection + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 2); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - /* Declare samplers */ + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for past ref surface texture + * decl s4 ; Sampler for future ref surface texture + */ 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 - ); + decl = vl_decl_samplers(i, 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 - */ + * tex2d t0.xw, i0, s0 ; Read texel from luma texture into .x and .w channels + * mov t1.x, t0.w ; Move 9th bit 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 9th bit 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 9th bit 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 = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); 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 - ); + 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 = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0); 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 - ); + 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 - ); + /* mul t1, t1, c0 ; Muliply 9th bit by multiplier to shift it into place */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 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 - ); + /* add t0, t0, t1 ; Add luma and chroma low and high parts to get normalized unsigned 9-bit values */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 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 - ); + /* sub t0, t0, c1 ; Subtract bias to get back signed values */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* XXX: Pos values off by 0.5 for rounding? */ - /* sub t4, i6.y, c2.x ; Sub 0.5 from position */ - 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 = 4; - inst.Instruction.NumSrcRegs = 2; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = 6; + /* XXX: Pos values off by 0.5? */ + /* sub t4, i6.y, c2.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 6, TGSI_FILE_CONSTANT, 2); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; - inst.FullSrcRegisters[1].SrcRegister.Index = 2; inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* mul t3, t4, c2.x ; Divide pos y coord by 2 (mul by 0.5) */ - 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 = 3; - inst.Instruction.NumSrcRegs = 2; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 4; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; - inst.FullSrcRegisters[1].SrcRegister.Index = 2; + /* mul t3, t4, c2.x ; Multiply pos Y-coord by 1/2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 2); inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* floor t3, t3 ; Get rid of fractional part */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_FLOOR; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = 3; - inst.Instruction.NumSrcRegs = 1; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 3; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* floor t3, t3 ; Get rid of fractional part */ + inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* mul t3, t3, c2.y ; Multiply by 2 */ - 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 = 3; - inst.Instruction.NumSrcRegs = 2; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 3; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_CONSTANT; - inst.FullSrcRegisters[1].SrcRegister.Index = 2; + /* mul t3, t3, c2.y ; Multiply by 2 */ + inst = vl_inst3( TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 2); inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* sub t3, t4, t3 ; Subtract from y to get y % 2 */ - 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 = 3; - inst.Instruction.NumSrcRegs = 2; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 4; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[1].SrcRegister.Index = 3; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* tex2d t1, i2, s3 ; Read texel from past macroblock top field - tex2d t2, i3, s3 ; Read texel from past macroblock bottom field */ + /* + * tex2d t1, i2, s3 ; Read texel from past ref macroblock top field + * tex2d t2, i3, s3 ; Read texel from past ref macroblock bottom field + */ 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 = 3; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 2, TGSI_FILE_SAMPLER, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* lerp t1, t3, t1, t2 */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_LERP; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = 1; - inst.Instruction.NumSrcRegs = 3; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 3; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[1].SrcRegister.Index = 1; - inst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[2].SrcRegister.Index = 2; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* TODO: Move to conditional tex fetch on t3 instead of lerp */ + /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* tex2d t4, i4, s4 ; Read texel from future macroblock top field - tex2d t5, i5, s4 ; Read texel from future macroblock bottom field */ + /* + * tex2d t4, i4, s4 ; Read texel from future ref macroblock top field + * tex2d t5, i5, s4 ; Read texel from future ref macroblock bottom field + */ 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 + 4; - inst.Instruction.NumSrcRegs = 2; - inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = i + 4; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - inst.FullSrcRegisters[1].SrcRegister.Index = 4; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 4, TGSI_FILE_INPUT, i + 4, TGSI_FILE_SAMPLER, 4); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* lerp t2, t3, t4, t5 */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_LERP; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = 2; - inst.Instruction.NumSrcRegs = 3; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[0].SrcRegister.Index = 3; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[1].SrcRegister.Index = 4; - inst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[2].SrcRegister.Index = 5; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* TODO: Move to conditional tex fetch on t3 instead of lerp */ + /* lerp t2, t3, t4, t5 ; Choose between top and bottom fields based on Y % 2 */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 2, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 5); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* lerp t1, c2.x, t1, t2 */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_LERP; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - inst.FullDstRegisters[0].DstRegister.Index = 1; - inst.Instruction.NumSrcRegs = 3; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_CONSTANT; - inst.FullSrcRegisters[0].SrcRegister.Index = 2; + /* lerp t1, c2.x, t1, t2 ; Blend past and future texels */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 2, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[1].SrcRegister.Index = 1; - inst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; - inst.FullSrcRegisters[2].SrcRegister.Index = 2; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* add o0, t0, t1 ; 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 = 1; - ti += tgsi_build_full_instruction - ( - &inst, - &tokens[ti], - header, - max_tokens - ti - ); + /* add o0, t0, t1 ; Add past/future ref and differential to form final output */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 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 - ); + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); fs.tokens = tokens; - context->states.mc.b_fs[1] = pipe->create_fs_state(pipe, &fs); - free(tokens); return 0; @@ -2936,8 +1375,8 @@ static int vlInitMC(struct VL_CONTEXT *context) 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; + filters[3] = PIPE_TEX_FILTER_LINEAR; + filters[4] = PIPE_TEX_FILTER_LINEAR; for (i = 0; i < 5; ++i) { @@ -3037,16 +1476,11 @@ static int vlDestroyMC(struct VL_CONTEXT *context) 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; @@ -3057,101 +1491,54 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); ti = 3; - /* Declare inputs (pos, texcoords) */ - for (i = 0; i < num_attribs; i++) + /* + * decl i0 ; Vertex pos + * decl i1 ; Vertex 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 = 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 - ); + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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 o0 ; Vertex pos + * decl o1 ; Vertex texcoords + */ + for (i = 0; i < 2; 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 - ); + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, 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++) + /* + * mov o0, i0 ; Move pos in to pos out + * mov o1, i1 ; Move input texcoords to output + */ + for (i = 0; i < 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 - ); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 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 - ); + /* end */ + inst = vl_end(); + 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); - free(tokens); return 0; @@ -3160,13 +1547,11 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context) 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; @@ -3177,171 +1562,64 @@ static int vlCreateFragmentShaderCSC(struct VL_CONTEXT *context) 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); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, 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 - ); + /* decl i0 ; Texcoords for s0 */ + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR); + 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 - ); + /* + * decl c0 ; Bias vector for CSC + * decl c1-c4 ; CSC matrix c1-c4 + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 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 - ); + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 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 - ); + /* decl s0 ; Sampler for tex containing picture to display */ + decl = vl_decl_samplers(0, 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 - ); + /* tex2d t0, i0, s0 ; Read src pixel */ + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 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 - ); + /* sub t0, t0, c0 ; Subtract bias vector from pixel */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 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 */ + /* + * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix + * dp4 o0.y, t0, c2 + * dp4 o0.z, t0, c3 + * dp4 o0.w, t0, c4 ; XXX: Don't need 4th coefficient + */ 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 = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1); 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 - ); + 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 - ); + /* end */ + inst = vl_end(); + 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); - free(tokens); return 0; diff --git a/src/gallium/state_trackers/g3dvl/vl_shader_build.c b/src/gallium/state_trackers/g3dvl/vl_shader_build.c new file mode 100644 index 0000000000..fd9de7dab8 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_shader_build.c @@ -0,0 +1,205 @@ +#include "vl_shader_build.h" +#include +#include +#include + +struct tgsi_full_declaration vl_decl_input(unsigned int name, unsigned int index, unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = name; + decl.Semantic.SemanticIndex = index; + decl.u.DeclarationRange.First = first; + decl.u.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_declaration vl_decl_interpolated_input +( + unsigned int name, + unsigned int index, + unsigned int first, + unsigned int last, + int interpolation +) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + assert + ( + interpolation == TGSI_INTERPOLATE_CONSTANT || + interpolation == TGSI_INTERPOLATE_LINEAR || + interpolation == TGSI_INTERPOLATE_PERSPECTIVE + ); + + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = name; + decl.Semantic.SemanticIndex = index; + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = interpolation; + decl.u.DeclarationRange.First = first; + decl.u.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_declaration vl_decl_constants(unsigned int name, unsigned int index, unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl.Declaration.File = TGSI_FILE_CONSTANT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = name; + decl.Semantic.SemanticIndex = index; + decl.u.DeclarationRange.First = first; + decl.u.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int index, unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = name; + decl.Semantic.SemanticIndex = index; + decl.u.DeclarationRange.First = first; + decl.u.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = first; + decl.u.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_instruction vl_inst2 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src_file, + unsigned int src_index +) +{ + struct tgsi_full_instruction inst = tgsi_default_full_instruction(); + + inst.Instruction.Opcode = opcode; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = dst_file; + inst.FullDstRegisters[0].DstRegister.Index = dst_index; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = src_file; + inst.FullSrcRegisters[0].SrcRegister.Index = src_index; + + return inst; +} + +struct tgsi_full_instruction vl_inst3 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index +) +{ + struct tgsi_full_instruction inst = tgsi_default_full_instruction(); + + inst.Instruction.Opcode = opcode; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = dst_file; + inst.FullDstRegisters[0].DstRegister.Index = dst_index; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = src1_file; + inst.FullSrcRegisters[0].SrcRegister.Index = src1_index; + inst.FullSrcRegisters[1].SrcRegister.File = src2_file; + inst.FullSrcRegisters[1].SrcRegister.Index = src2_index; + + return inst; +} + +struct tgsi_full_instruction vl_tex +( + int tex, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index +) +{ + struct tgsi_full_instruction inst = tgsi_default_full_instruction(); + + inst.Instruction.Opcode = TGSI_OPCODE_TEX; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = dst_file; + inst.FullDstRegisters[0].DstRegister.Index = dst_index; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = tex; + inst.FullSrcRegisters[0].SrcRegister.File = src1_file; + inst.FullSrcRegisters[0].SrcRegister.Index = src1_index; + inst.FullSrcRegisters[1].SrcRegister.File = src2_file; + inst.FullSrcRegisters[1].SrcRegister.Index = src2_index; + + return inst; +} + +struct tgsi_full_instruction vl_inst4 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index, + enum tgsi_file_type src3_file, + unsigned int src3_index +) +{ + struct tgsi_full_instruction inst = tgsi_default_full_instruction(); + + inst.Instruction.Opcode = opcode; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = dst_file; + inst.FullDstRegisters[0].DstRegister.Index = dst_index; + inst.Instruction.NumSrcRegs = 3; + inst.FullSrcRegisters[0].SrcRegister.File = src1_file; + inst.FullSrcRegisters[0].SrcRegister.Index = src1_index; + inst.FullSrcRegisters[1].SrcRegister.File = src2_file; + inst.FullSrcRegisters[1].SrcRegister.Index = src2_index; + inst.FullSrcRegisters[2].SrcRegister.File = src3_file; + inst.FullSrcRegisters[2].SrcRegister.Index = src3_index; + + return inst; +} + +struct tgsi_full_instruction vl_end(void) +{ + struct tgsi_full_instruction inst = tgsi_default_full_instruction(); + + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + + return inst; +} + diff --git a/src/gallium/state_trackers/g3dvl/vl_shader_build.h b/src/gallium/state_trackers/g3dvl/vl_shader_build.h new file mode 100644 index 0000000000..9e64bbeeae --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_shader_build.h @@ -0,0 +1,61 @@ +#ifndef vl_shader_build_h +#define vl_shader_build_h + +#include + +struct tgsi_full_declaration vl_decl_input(unsigned int name, unsigned int index, unsigned int first, unsigned int last); +struct tgsi_full_declaration vl_decl_interpolated_input +( + unsigned int name, + unsigned int index, + unsigned int first, + unsigned int last, + int interpolation +); +struct tgsi_full_declaration vl_decl_constants(unsigned int name, unsigned int index, unsigned int first, unsigned int last); +struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int index, unsigned int first, unsigned int last); +struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int last); +struct tgsi_full_instruction vl_inst2 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src_file, + unsigned int src_index +); +struct tgsi_full_instruction vl_inst3 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index +); +struct tgsi_full_instruction vl_tex +( + int tex, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index +); +struct tgsi_full_instruction vl_inst4 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index, + enum tgsi_file_type src3_file, + unsigned int src3_index +); +struct tgsi_full_instruction vl_end(void); + +#endif + -- cgit v1.2.3 From 9833aec6cbd113d24277aa5da8625c1427d831ca Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 30 Jun 2008 19:26:22 -0400 Subject: g3dvl: Use block and stride instead of cpp and pitch. --- src/gallium/state_trackers/g3dvl/vl_context.c | 2 +- src/gallium/state_trackers/g3dvl/vl_shader_build.c | 23 ++++++++--------- src/gallium/state_trackers/g3dvl/vl_surface.c | 29 ++++++++++++---------- src/gallium/winsys/g3dvl/xsp_winsys.c | 15 ++++++++--- src/libXvMC/Makefile | 2 +- 5 files changed, 41 insertions(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 88da47c06a..bd8743dc9a 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -1407,7 +1407,7 @@ static int vlInitMC(struct VL_CONTEXT *context) template.height[0] = 8 * 4; template.depth[0] = 1; template.compressed = 0; - template.cpp = 2; + pf_get_block(template.format, &template.block); context->states.mc.textures[0] = pipe->screen->texture_create(pipe->screen, &template); diff --git a/src/gallium/state_trackers/g3dvl/vl_shader_build.c b/src/gallium/state_trackers/g3dvl/vl_shader_build.c index fd9de7dab8..365ad69725 100644 --- a/src/gallium/state_trackers/g3dvl/vl_shader_build.c +++ b/src/gallium/state_trackers/g3dvl/vl_shader_build.c @@ -11,8 +11,8 @@ struct tgsi_full_declaration vl_decl_input(unsigned int name, unsigned int index decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = name; decl.Semantic.SemanticIndex = index; - decl.u.DeclarationRange.First = first; - decl.u.DeclarationRange.Last = last; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; return decl; } @@ -39,10 +39,9 @@ struct tgsi_full_declaration vl_decl_interpolated_input decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = name; decl.Semantic.SemanticIndex = index; - decl.Declaration.Interpolate = 1; - decl.Interpolation.Interpolate = interpolation; - decl.u.DeclarationRange.First = first; - decl.u.DeclarationRange.Last = last; + decl.Declaration.Interpolate = interpolation;; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; return decl; } @@ -55,8 +54,8 @@ struct tgsi_full_declaration vl_decl_constants(unsigned int name, unsigned int i decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = name; decl.Semantic.SemanticIndex = index; - decl.u.DeclarationRange.First = first; - decl.u.DeclarationRange.Last = last; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; return decl; } @@ -69,8 +68,8 @@ struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int inde decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = name; decl.Semantic.SemanticIndex = index; - decl.u.DeclarationRange.First = first; - decl.u.DeclarationRange.Last = last; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; return decl; } @@ -81,8 +80,8 @@ struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int l decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.u.DeclarationRange.First = first; - decl.u.DeclarationRange.Last = last; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; return decl; } diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index d2220d7abf..68313cc750 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -98,6 +98,7 @@ static int vlGrabBlocks { struct pipe_surface *tex_surface; short *texels; + unsigned int tex_pitch; unsigned int tb, sb = 0; assert(context); @@ -111,6 +112,7 @@ static int vlGrabBlocks ); texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); + tex_pitch = tex_surface->stride / tex_surface->block.size; for (tb = 0; tb < 4; ++tb) { @@ -121,35 +123,35 @@ static int vlGrabBlocks vlGrabFrameCodedFullBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, - texels + tb * tex_surface->pitch * VL_BLOCK_HEIGHT, - tex_surface->pitch + texels + tb * tex_pitch * VL_BLOCK_HEIGHT, + tex_pitch ); else vlGrabFrameCodedDiffBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, - texels + tb * tex_surface->pitch * VL_BLOCK_HEIGHT, - tex_surface->pitch + texels + tb * tex_pitch * VL_BLOCK_HEIGHT, + tex_pitch ); else if (sample_type == VL_FULL_SAMPLE) vlGrabFieldCodedFullBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, - texels + (tb % 2) * tex_surface->pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_surface->pitch, - tex_surface->pitch + texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, + tex_pitch ); else vlGrabFieldCodedDiffBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, - texels + (tb % 2) * tex_surface->pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_surface->pitch, - tex_surface->pitch + texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, + tex_pitch ); ++sb; } else - vlGrabNoBlock(texels + tb * tex_surface->pitch * VL_BLOCK_HEIGHT, tex_surface->pitch); + vlGrabNoBlock(texels + tb * tex_pitch * VL_BLOCK_HEIGHT, tex_pitch); } pipe_surface_unmap(tex_surface); @@ -165,6 +167,7 @@ static int vlGrabBlocks ); texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); + tex_pitch = tex_surface->stride / tex_surface->block.size; if ((coded_block_pattern >> (1 - tb)) & 1) { @@ -173,20 +176,20 @@ static int vlGrabBlocks ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, texels, - tex_surface->pitch + tex_pitch ); else vlGrabFrameCodedDiffBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, texels, - tex_surface->pitch + tex_pitch ); ++sb; } else - vlGrabNoBlock(texels, tex_surface->pitch); + vlGrabNoBlock(texels, tex_pitch); pipe_surface_unmap(tex_surface); } @@ -223,7 +226,7 @@ int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface) template.height[0] = sfc->height; template.depth[0] = 1; template.compressed = 0; - template.cpp = 4; + pf_get_block(template.format, &template.block); template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; sfc->texture = pipe->screen->texture_create(pipe->screen, &template); diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index eb4c9085d6..d04c4be580 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -101,6 +101,12 @@ static struct pipe_surface* xsp_surface_alloc(struct pipe_winsys *pws) return surface; } +/* Borrowed from Mesa's xm_winsys */ +static unsigned int round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + static int xsp_surface_alloc_storage ( struct pipe_winsys *pws, @@ -120,10 +126,13 @@ static int xsp_surface_alloc_storage surface->width = width; surface->height = height; surface->format = format; - surface->cpp = pf_get_size(format); - surface->pitch = width; + pf_get_block(format, &surface->block); + surface->nblocksx = pf_get_nblocksx(&surface->block, width); + surface->nblocksy = pf_get_nblocksy(&surface->block, height); + surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); surface->usage = flags; - surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->pitch * surface->cpp * height); + /* XXX: Need to consider block dims? See xm_winsys.c */ + surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * height); return 0; } diff --git a/src/libXvMC/Makefile b/src/libXvMC/Makefile index b2f41e176d..4985ecd3e9 100644 --- a/src/libXvMC/Makefile +++ b/src/libXvMC/Makefile @@ -17,7 +17,7 @@ LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \ -L${GALLIUMDIR}/auxiliary/cso_cache \ -L${GALLIUMDIR}/auxiliary/util \ -L${GALLIUMDIR}/auxiliary/rtasm -LIBS += -lg3dvl -lsoftpipe -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lutil +LIBS += -lg3dvl -lsoftpipe -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lutil -lm ############################################# -- cgit v1.2.3 From 36488ed052a18f7eafef1d1c5c18b20ad508b2b7 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 3 Jul 2008 20:58:31 +0200 Subject: nv30: Emit framebuffer state using state objects --- src/gallium/drivers/nv30/nv30_context.h | 3 + src/gallium/drivers/nv30/nv30_state.c | 105 +-------------------------- src/gallium/drivers/nv30/nv30_state_emit.c | 111 ++++++++++++++++++++--------- src/gallium/drivers/nv30/nv30_state_fb.c | 35 ++------- src/gallium/drivers/nv30/nv30_vbo.c | 2 + 5 files changed, 92 insertions(+), 164 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index dce077b2b4..4a6c1d2f47 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -99,6 +99,7 @@ struct nv30_state { unsigned stipple_enabled; unsigned viewport_bypass; + uint64_t dirty; struct nouveau_stateobj *hw[NV30_STATE_MAX]; }; @@ -208,8 +209,10 @@ extern void nv30_fragprog_destroy(struct nv30_context *, extern void nv30_fragtex_bind(struct nv30_context *); /* nv30_state.c and friends */ +extern boolean nv30_state_validate(struct nv30_context *nv30); extern void nv30_emit_hw_state(struct nv30_context *nv30); extern void nv30_state_tex_update(struct nv30_context *nv30); +extern struct nv30_state_entry nv30_state_framebuffer; /* nv30_vbo.c */ extern boolean nv30_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index c1618041bb..3edfb0874d 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -565,110 +565,9 @@ 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]->stride; - if (zeta) { - pitch |= (zeta->stride << 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]->stride); - 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); + nv30->framebuffer = *fb; + nv30->dirty |= NV30_NEW_FB; } static void diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index eda2fd45f5..9a3954594a 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -1,10 +1,55 @@ #include "nv30_context.h" #include "nv30_state.h" +static struct nv30_state_entry *render_states[] = { + &nv30_state_framebuffer, + NULL +}; + +static void +nv30_state_do_validate(struct nv30_context *nv30, + struct nv30_state_entry **states) +{ + const struct pipe_framebuffer_state *fb = &nv30->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 nv30_state_entry *e = *states; + + if (nv30->dirty & e->dirty.pipe) { + if (e->validate(nv30)) { + nv30->state.dirty |= (1ULL << e->dirty.hw); + } + } + + states++; + } + +/* TODO: uncomment when finished converting + nv30->dirty = 0; +*/ +} + void nv30_emit_hw_state(struct nv30_context *nv30) { - int i; + struct nv30_state *state = &nv30->state; + unsigned i; + uint64 states; + + for (i = 0, states = state->dirty; states; i++) { + if (!(states & (1ULL << i))) + continue; + so_ref (state->hw[i], &nv30->screen->state[i]); + if (state->hw[i]) + so_emit(nv30->nvws, nv30->screen->state[i]); + states &= ~(1ULL << i); + } if (nv30->dirty & NV30_NEW_FRAGPROG) { nv30_fragprog_bind(nv30, nv30->fragprog.current); @@ -28,37 +73,7 @@ nv30_emit_hw_state(struct nv30_context *nv30) 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);*/ - } + so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]); /* Texture images, emitted in nv30_fragtex_build */ #if 0 @@ -83,3 +98,35 @@ nv30_emit_hw_state(struct nv30_context *nv30) NV34TCL_FP_ACTIVE_PROGRAM_DMA1); } +boolean +nv30_state_validate(struct nv30_context *nv30) +{ +#if 0 + boolean was_sw = nv30->fallback_swtnl ? TRUE : FALSE; + + if (nv30->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 ((nv30->fallback_swtnl & nv30->dirty) + != nv30->fallback_swtnl) + return FALSE; + + /* Attempt to go to hwtnl again */ + nv30->pipe.flush(&nv30->pipe, 0, NULL); + nv30->dirty |= (NV30_NEW_VIEWPORT | + NV30_NEW_VERTPROG | + NV30_NEW_ARRAYS); + nv30->render_mode = HW; + } +#endif + nv30_state_do_validate(nv30, render_states); +#if 0 + if (nv30->fallback_swtnl || nv30->fallback_swrast) + return FALSE; + + if (was_sw) + NOUVEAU_ERR("swtnl->hw\n"); +#endif + return TRUE; +} diff --git a/src/gallium/drivers/nv30/nv30_state_fb.c b/src/gallium/drivers/nv30/nv30_state_fb.c index a20df9f75d..d93e2bb5c8 100644 --- a/src/gallium/drivers/nv30/nv30_state_fb.c +++ b/src/gallium/drivers/nv30/nv30_state_fb.c @@ -4,7 +4,7 @@ static boolean nv30_state_framebuffer_validate(struct nv30_context *nv30) { struct pipe_framebuffer_state *fb = &nv30->framebuffer; - struct pipe_surface *rt[4], *zeta = NULL; + struct pipe_surface *rt[2], *zeta = NULL; uint32_t rt_enable, rt_format; int i, colour_format = 0, zeta_format = 0; struct nouveau_stateobj *so = so_new(64, 10); @@ -23,8 +23,7 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30) } } - if (rt_enable & (NV34TCL_RT_ENABLE_COLOR1 | NV34TCL_RT_ENABLE_COLOR2 | - NV34TCL_RT_ENABLE_COLOR3)) + if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) rt_enable |= NV34TCL_RT_ENABLE_MRT; if (fb->zsbuf) { @@ -86,31 +85,7 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30) NOUVEAU_BO_LOW, 0, 0); so_data (so, rt[1]->stride); } -/* - 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, @@ -119,8 +94,7 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30) 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);*/ + /* TODO: allocate LMA depth buffer */ } so_method(so, nv30->screen->rankine, NV34TCL_RT_ENABLE, 1); @@ -137,6 +111,9 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30) so_data (so, ((h - 1) << 16) | 0); so_method(so, nv30->screen->rankine, 0x1d88, 1); so_data (so, (1 << 12) | h); + /* Wonder why this is needed, context should all be set to zero on init */ + so_method(so, nv30->screen->rankine, NV34TCL_VIEWPORT_TX_ORIGIN, 1); + so_data (so, 0); so_ref(so, &nv30->state.hw[NV30_STATE_FB]); return TRUE; diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index 359e443bb1..d23164eb48 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -154,6 +154,8 @@ nv30_vbo_validate_state(struct nv30_context *nv30, { unsigned inputs; + nv30_state_validate(nv30); + nv30_emit_hw_state(nv30); if (nv30->dirty & NV30_NEW_ARRAYS) { -- cgit v1.2.3 From 52cf7a6c1ccc987859834b640a5ec0a62f84134a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 3 Jul 2008 21:11:07 +0200 Subject: nv30: Emit blend color state using state objects --- src/gallium/drivers/nv30/nv30_context.h | 1 + src/gallium/drivers/nv30/nv30_state.c | 7 ++----- src/gallium/drivers/nv30/nv30_state_emit.c | 1 + 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 4a6c1d2f47..57cc991cd7 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -212,6 +212,7 @@ extern void nv30_fragtex_bind(struct nv30_context *); extern boolean nv30_state_validate(struct nv30_context *nv30); extern void nv30_emit_hw_state(struct nv30_context *nv30); extern void nv30_state_tex_update(struct nv30_context *nv30); +extern struct nv30_state_entry nv30_state_blend_colour; extern struct nv30_state_entry nv30_state_framebuffer; /* nv30_vbo.c */ diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 3edfb0874d..e67a701809 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -531,11 +531,8 @@ nv30_set_blend_color(struct pipe_context *pipe, { 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)); + nv30->blend_colour = *bcol; + nv30->dirty |= NV30_NEW_BCOL; } static void diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 9a3954594a..541ad0da3e 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -3,6 +3,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_framebuffer, + &nv30_state_blend_colour, NULL }; -- cgit v1.2.3 From c0e9eb3b095c9769d3deacf4ad4470bd155acdcd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 3 Jul 2008 21:25:47 +0200 Subject: nv30: Emit blend state using state objects --- src/gallium/drivers/nv30/nv30_context.h | 6 +-- src/gallium/drivers/nv30/nv30_state.c | 84 +++++++++++++++-------------- src/gallium/drivers/nv30/nv30_state.h | 14 ----- src/gallium/drivers/nv30/nv30_state_blend.c | 2 +- src/gallium/drivers/nv30/nv30_state_emit.c | 1 + 5 files changed, 48 insertions(+), 59 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 57cc991cd7..eedebc91b2 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -87,8 +87,7 @@ struct nv30_zsa_state { struct nouveau_stateobj *so; }; -/* TODO: rename when removing the old state emitter */ -struct nv30_blend_state_new { +struct nv30_blend_state { struct pipe_blend_state pipe; struct nouveau_stateobj *so; }; @@ -125,7 +124,7 @@ struct nv30_context { unsigned vp_samplers; /* Context state */ - struct nv30_blend_state_new *blend; + struct nv30_blend_state *blend; struct pipe_blend_color blend_colour; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; @@ -212,6 +211,7 @@ extern void nv30_fragtex_bind(struct nv30_context *); extern boolean nv30_state_validate(struct nv30_context *nv30); extern void nv30_emit_hw_state(struct nv30_context *nv30); extern void nv30_state_tex_update(struct nv30_context *nv30); +extern struct nv30_state_entry nv30_state_blend; extern struct nv30_state_entry nv30_state_blend_colour; extern struct nv30_state_entry nv30_state_framebuffer; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index e67a701809..cf46dcef93 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -9,63 +9,65 @@ 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))); + struct nv30_context *nv30 = nv30_context(pipe); + struct nouveau_grobj *rankine = nv30->screen->rankine; + struct nv30_blend_state *bso = CALLOC(1, sizeof(*bso)); + struct nouveau_stateobj *so = so_new(16, 0); + + if (cso->blend_enable) { + so_method(so, rankine, NV34TCL_BLEND_FUNC_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, rankine, NV34TCL_BLEND_EQUATION, 1); + so_data (so, nvgl_blend_eqn(cso->alpha_func) << 16 | + nvgl_blend_eqn(cso->rgb_func)); + } else { + so_method(so, rankine, NV34TCL_BLEND_FUNC_ENABLE, 1); + so_data (so, 0); + } - cb->l_enable = cso->logicop_enable ? 1 : 0; - cb->l_op = nvgl_logicop_func(cso->logicop_func); + so_method(so, rankine, NV34TCL_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))); - 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)); + if (cso->logicop_enable) { + so_method(so, rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2); + so_data (so, 1); + so_data (so, nvgl_logicop_func(cso->logicop_func)); + } else { + so_method(so, rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 1); + so_data (so, 0); + } - cb->d_enable = cso->dither ? 1 : 0; + so_method(so, rankine, NV34TCL_DITHER_ENABLE, 1); + so_data (so, cso->dither ? 1 : 0); - return (void *)cb; + so_ref(so, &bso->so); + bso->pipe = *cso; + return (void *)bso; } 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); + nv30->blend = hwcso; + nv30->dirty |= NV30_NEW_BLEND; } static void nv30_blend_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + struct nv30_blend_state *bso = hwcso; + + so_ref(NULL, &bso->so); + FREE(bso); } diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h index 117520dd13..8489b7b796 100644 --- a/src/gallium/drivers/nv30/nv30_state.h +++ b/src/gallium/drivers/nv30/nv30_state.h @@ -3,20 +3,6 @@ #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; diff --git a/src/gallium/drivers/nv30/nv30_state_blend.c b/src/gallium/drivers/nv30/nv30_state_blend.c index a1b0100472..44d43e132a 100644 --- a/src/gallium/drivers/nv30/nv30_state_blend.c +++ b/src/gallium/drivers/nv30/nv30_state_blend.c @@ -7,7 +7,7 @@ nv30_state_blend_validate(struct nv30_context *nv30) return TRUE; } -struct nv30_state_entry nv30_state_blend_new = { +struct nv30_state_entry nv30_state_blend = { .validate = nv30_state_blend_validate, .dirty = { .pipe = NV30_NEW_BLEND, diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 541ad0da3e..492f411011 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -3,6 +3,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_framebuffer, + &nv30_state_blend, &nv30_state_blend_colour, NULL }; -- cgit v1.2.3 From 360f7a3e239553fc0e1aff3b38c06c2e3d0a698c Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 3 Jul 2008 21:48:18 +0200 Subject: nv30: Emit rasterizer state using state objects --- src/gallium/drivers/nv30/nv30_context.h | 6 +- src/gallium/drivers/nv30/nv30_state.c | 177 +++++++++++++++-------------- src/gallium/drivers/nv30/nv30_state.h | 23 ---- src/gallium/drivers/nv30/nv30_state_emit.c | 1 + 4 files changed, 98 insertions(+), 109 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index eedebc91b2..692d8dd523 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -76,8 +76,7 @@ enum nv30_state_index { #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 nv30_rasterizer_state { struct pipe_rasterizer_state pipe; struct nouveau_stateobj *so; }; @@ -124,11 +123,11 @@ struct nv30_context { unsigned vp_samplers; /* Context state */ + struct nv30_rasterizer_state *rasterizer; struct nv30_blend_state *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]; @@ -211,6 +210,7 @@ extern void nv30_fragtex_bind(struct nv30_context *); extern boolean nv30_state_validate(struct nv30_context *nv30); extern void nv30_emit_hw_state(struct nv30_context *nv30); extern void nv30_state_tex_update(struct nv30_context *nv30); +extern struct nv30_state_entry nv30_state_rasterizer; extern struct nv30_state_entry nv30_state_blend; extern struct nv30_state_entry nv30_state_blend_colour; extern struct nv30_state_entry nv30_state_framebuffer; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index cf46dcef93..8c7a902e28 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -275,123 +275,134 @@ static void * nv30_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { - struct nv30_rasterizer_state *rs; - int i; + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso)); + struct nouveau_stateobj *so = so_new(32, 0); + struct nouveau_grobj *rankine = nv30->screen->rankine; /*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; + so_method(so, rankine, NV34TCL_SHADE_MODEL, 1); + so_data (so, cso->flatshade ? NV34TCL_SHADE_MODEL_FLAT : + NV34TCL_SHADE_MODEL_SMOOTH); - rs->point_size = *(uint32_t*)&cso->point_size; + so_method(so, rankine, NV34TCL_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, rankine, NV34TCL_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); - rs->poly_smooth_en = cso->poly_smooth ? 1 : 0; - rs->poly_stipple_en = cso->poly_stipple_enable ? 1 : 0; + so_method(so, rankine, NV34TCL_POINT_SIZE, 1); + so_data (so, fui(cso->point_size)); + so_method(so, rankine, NV34TCL_POLYGON_MODE_FRONT, 6); 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); + 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, NV34TCL_CULL_FACE_FRONT); + break; + case PIPE_WINDING_CW: + so_data(so, NV34TCL_CULL_FACE_BACK); + break; + case PIPE_WINDING_BOTH: + so_data(so, NV34TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, NV34TCL_CULL_FACE_BACK); + break; + } + so_data(so, NV34TCL_FRONT_FACE_CCW); } 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); + 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, NV34TCL_CULL_FACE_BACK); + break; + case PIPE_WINDING_CW: + so_data(so, NV34TCL_CULL_FACE_FRONT); + break; + case PIPE_WINDING_BOTH: + so_data(so, NV34TCL_CULL_FACE_FRONT_AND_BACK); + break; + default: + so_data(so, NV34TCL_CULL_FACE_BACK); + break; + } + so_data(so, NV34TCL_FRONT_FACE_CW); } - - 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; + so_data(so, cso->poly_smooth ? 1 : 0); + so_data(so, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0); + + so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, cso->poly_stipple_enable ? 1 : 0); + + so_method(so, rankine, NV34TCL_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, rankine, NV34TCL_POLYGON_OFFSET_FACTOR, 2); + so_data (so, fui(cso->offset_scale)); + so_data (so, fui(cso->offset_units * 2)); } + so_method(so, rankine, NV34TCL_POINT_SPRITE, 1); if (cso->point_sprite) { - rs->point_sprite = (1 << 0); + unsigned psctl = (1 << 0), i; + for (i = 0; i < 8; i++) { if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE) - rs->point_sprite |= (1 << (8 + i)); + psctl |= (1 << (8 + i)); } + + so_data(so, psctl); } else { - rs->point_sprite = 0; + so_data(so, 0); } - return (void *)rs; + so_ref(so, &rsso->so); + rsso->pipe = *cso; + return (void *)rsso; } 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); + nv30->rasterizer = hwcso; + nv30->dirty |= NV30_NEW_RAST; + /*nv30->draw_dirty |= NV30_NEW_RAST;*/ } static void nv30_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + struct nv30_rasterizer_state *rsso = hwcso; + + so_ref(NULL, &rsso->so); + FREE(rsso); } static void diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h index 8489b7b796..b33075aceb 100644 --- a/src/gallium/drivers/nv30/nv30_state.h +++ b/src/gallium/drivers/nv30/nv30_state.h @@ -11,29 +11,6 @@ struct nv30_sampler_state { 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; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 492f411011..7d77adbfdf 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -3,6 +3,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_framebuffer, + &nv30_state_rasterizer, &nv30_state_blend, &nv30_state_blend_colour, NULL -- cgit v1.2.3 From c66f376e271427799f777c39bc9221df7c961f77 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 3 Jul 2008 22:10:53 +0200 Subject: nv30: Emit depth/stencil/alpha state using state objects --- src/gallium/drivers/nv30/nv30_context.h | 1 + src/gallium/drivers/nv30/nv30_state.c | 91 +++++++++++++++++------------- src/gallium/drivers/nv30/nv30_state.h | 30 ---------- src/gallium/drivers/nv30/nv30_state_emit.c | 1 + 4 files changed, 53 insertions(+), 70 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 692d8dd523..b8a26712a8 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -213,6 +213,7 @@ extern void nv30_state_tex_update(struct nv30_context *nv30); extern struct nv30_state_entry nv30_state_rasterizer; extern struct nv30_state_entry nv30_state_blend; extern struct nv30_state_entry nv30_state_blend_colour; +extern struct nv30_state_entry nv30_state_zsa; extern struct nv30_state_entry nv30_state_framebuffer; /* nv30_vbo.c */ diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 8c7a902e28..8121e62fb9 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -405,65 +405,76 @@ nv30_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) FREE(rsso); } -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; + struct nv30_context *nv30 = nv30_context(pipe); + struct nv30_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); + struct nouveau_stateobj *so = so_new(32, 0); + struct nouveau_grobj *rankine = nv30->screen->rankine; - nv30_translate_stencil(cso, 0, &hw->stencil.front); - nv30_translate_stencil(cso, 1, &hw->stencil.back); + so_method(so, rankine, NV34TCL_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, rankine, NV34TCL_ALPHA_FUNC_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, rankine, NV34TCL_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, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 1); + so_data (so, 0); + } - 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); + if (cso->stencil[1].enabled) { + so_method(so, rankine, NV34TCL_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, rankine, NV34TCL_STENCIL_BACK_ENABLE, 1); + so_data (so, 0); + } - return (void *)hw; + so_ref(so, &zsaso->so); + zsaso->pipe = *cso; + return (void *)zsaso; } 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); + nv30->zsa = hwcso; + nv30->dirty |= NV30_NEW_ZSA; } static void nv30_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + struct nv30_zsa_state *zsaso = hwcso; + + so_ref(NULL, &zsaso->so); + FREE(zsaso); } static void * diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h index b33075aceb..c65a937467 100644 --- a/src/gallium/drivers/nv30/nv30_state.h +++ b/src/gallium/drivers/nv30/nv30_state.h @@ -65,36 +65,6 @@ struct nv30_fragment_program { 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; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 7d77adbfdf..83bb3408a5 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -6,6 +6,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_rasterizer, &nv30_state_blend, &nv30_state_blend_colour, + &nv30_state_zsa, NULL }; -- cgit v1.2.3 From f1d24c1d27255e4ff5ba451e6d58558f9ccdc801 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 3 Jul 2008 22:18:38 +0200 Subject: nv30: Emit scissor state using state objects --- src/gallium/drivers/nv30/nv30_context.h | 1 + src/gallium/drivers/nv30/nv30_state.c | 5 ++--- src/gallium/drivers/nv30/nv30_state_emit.c | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index b8a26712a8..2a48903e32 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -211,6 +211,7 @@ extern boolean nv30_state_validate(struct nv30_context *nv30); extern void nv30_emit_hw_state(struct nv30_context *nv30); extern void nv30_state_tex_update(struct nv30_context *nv30); extern struct nv30_state_entry nv30_state_rasterizer; +extern struct nv30_state_entry nv30_state_scissor; extern struct nv30_state_entry nv30_state_blend; extern struct nv30_state_entry nv30_state_blend_colour; extern struct nv30_state_entry nv30_state_zsa; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 8121e62fb9..f2413a3372 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -607,9 +607,8 @@ nv30_set_scissor_state(struct pipe_context *pipe, { 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); + nv30->scissor = *s; + nv30->dirty |= NV30_NEW_SCISSOR; } static void diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 83bb3408a5..f45a340b5d 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -4,6 +4,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_framebuffer, &nv30_state_rasterizer, + &nv30_state_scissor, &nv30_state_blend, &nv30_state_blend_colour, &nv30_state_zsa, -- cgit v1.2.3 From e7e231a5116aed9f1ca685a297032a3e3e6a2433 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 3 Jul 2008 22:31:23 +0200 Subject: nv30: Emit polygon stipple state using state objects --- src/gallium/drivers/nv30/nv30_context.h | 10 +++++----- src/gallium/drivers/nv30/nv30_state.c | 4 ++-- src/gallium/drivers/nv30/nv30_state_emit.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 2a48903e32..ed7b0759ad 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -112,9 +112,6 @@ struct nv30_context { /* 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]; @@ -123,13 +120,15 @@ struct nv30_context { unsigned vp_samplers; /* Context state */ + unsigned dirty; + struct pipe_scissor_state scissor; + unsigned stipple[32]; struct nv30_rasterizer_state *rasterizer; + struct nv30_zsa_state *zsa; struct nv30_blend_state *blend; struct pipe_blend_color blend_colour; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; - struct nv30_zsa_state *zsa; - unsigned stipple[32]; uint32_t rt_enable; struct pipe_buffer *rt[2]; @@ -212,6 +211,7 @@ extern void nv30_emit_hw_state(struct nv30_context *nv30); extern void nv30_state_tex_update(struct nv30_context *nv30); extern struct nv30_state_entry nv30_state_rasterizer; extern struct nv30_state_entry nv30_state_scissor; +extern struct nv30_state_entry nv30_state_stipple; extern struct nv30_state_entry nv30_state_blend; extern struct nv30_state_entry nv30_state_blend_colour; extern struct nv30_state_entry nv30_state_zsa; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index f2413a3372..7109deae55 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -597,8 +597,8 @@ nv30_set_polygon_stipple(struct pipe_context *pipe, { struct nv30_context *nv30 = nv30_context(pipe); - BEGIN_RING(rankine, NV34TCL_POLYGON_STIPPLE_PATTERN(0), 32); - OUT_RINGp ((uint32_t *)stipple->stipple, 32); + memcpy(nv30->stipple, stipple->stipple, 4 * 32); + nv30->dirty |= NV30_NEW_STIPPLE; } static void diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index f45a340b5d..4f9079184d 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -5,6 +5,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_framebuffer, &nv30_state_rasterizer, &nv30_state_scissor, + &nv30_state_stipple, &nv30_state_blend, &nv30_state_blend_colour, &nv30_state_zsa, -- cgit v1.2.3 From 568b477b9c118e5ace831b8ecf1811da1c0961cd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 3 Jul 2008 22:42:30 +0200 Subject: nv30: Emit viewport state using state objects --- src/gallium/drivers/nv30/nv30_context.h | 1 + src/gallium/drivers/nv30/nv30_state.c | 12 +++--------- src/gallium/drivers/nv30/nv30_state_emit.c | 1 + 3 files changed, 5 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index ed7b0759ad..0ad1dc6f91 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -215,6 +215,7 @@ extern struct nv30_state_entry nv30_state_stipple; extern struct nv30_state_entry nv30_state_blend; extern struct nv30_state_entry nv30_state_blend_colour; extern struct nv30_state_entry nv30_state_zsa; +extern struct nv30_state_entry nv30_state_viewport; extern struct nv30_state_entry nv30_state_framebuffer; /* nv30_vbo.c */ diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 7109deae55..e65c4b215d 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -617,15 +617,9 @@ nv30_set_viewport_state(struct pipe_context *pipe, { 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]); + nv30->viewport = *vpt; + nv30->dirty |= NV30_NEW_VIEWPORT; + /*nv30->draw_dirty |= NV30_NEW_VIEWPORT;*/ } static void diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 4f9079184d..cb7f1a7c31 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -9,6 +9,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_blend, &nv30_state_blend_colour, &nv30_state_zsa, + &nv30_state_viewport, NULL }; -- cgit v1.2.3 From 6f56b527d866506a323feb19f9d8529d40034af2 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 3 Jul 2008 22:47:15 +0200 Subject: nv30: Reemit state when changing context --- src/gallium/drivers/nv30/nv30_state_emit.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index cb7f1a7c31..eca1f0652c 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -46,9 +46,19 @@ void nv30_emit_hw_state(struct nv30_context *nv30) { struct nv30_state *state = &nv30->state; + struct nv30_screen *screen = nv30->screen; unsigned i; uint64 states; + if (nv30->pctx_id != screen->cur_pctx) { + for (i = 0; i < NV30_STATE_MAX; i++) { + if (state->hw[i] && screen->state[i] != state->hw[i]) + state->dirty |= (1ULL << i); + } + + screen->cur_pctx = nv30->pctx_id; + } + for (i = 0, states = state->dirty; states; i++) { if (!(states & (1ULL << i))) continue; -- cgit v1.2.3 From f99643ca6ea3aa05a0b16dc5d99e11fa00185684 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 4 Jul 2008 18:53:44 +0200 Subject: nv30: Emit sampler state using state objects --- src/gallium/drivers/nv30/nv30_context.h | 3 +++ src/gallium/drivers/nv30/nv30_state.c | 42 +++++++++++++++++++++++++----- src/gallium/drivers/nv30/nv30_state_emit.c | 9 ++++++- 3 files changed, 46 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 0ad1dc6f91..5404685da2 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -96,6 +96,7 @@ struct nv30_state { unsigned scissor_enabled; unsigned stipple_enabled; unsigned viewport_bypass; + unsigned fp_samplers; uint64_t dirty; struct nouveau_stateobj *hw[NV30_STATE_MAX]; @@ -129,6 +130,8 @@ struct nv30_context { struct pipe_blend_color blend_colour; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; + unsigned nr_samplers; + unsigned nr_textures; uint32_t rt_enable; struct pipe_buffer *rt[2]; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index e65c4b215d..97becd2be3 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -1,6 +1,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "nv30_context.h" #include "nv30_state.h" @@ -116,7 +117,7 @@ nv30_sampler_state_create(struct pipe_context *pipe, struct nv30_sampler_state *ps; uint32_t filter = 0; - ps = malloc(sizeof(struct nv30_sampler_state)); + ps = MALLOC(sizeof(struct nv30_sampler_state)); ps->fmt = 0; if (!cso->normalized_coords) @@ -197,6 +198,19 @@ nv30_sampler_state_create(struct pipe_context *pipe, 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: @@ -242,20 +256,24 @@ 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); } + + for (unit = nr; unit < nv30->nr_samplers; unit++) { + nv30->tex_sampler[unit] = NULL; + nv30->dirty_samplers |= (1 << unit); + } + + nv30->nr_samplers = nr; + nv30->dirty |= NV30_NEW_SAMPLER; } static void nv30_sampler_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + FREE(hwcso); } static void @@ -266,9 +284,19 @@ nv30_set_sampler_texture(struct pipe_context *pipe, unsigned nr, unsigned unit; for (unit = 0; unit < nr; unit++) { - nv30->tex_miptree[unit] = (struct nv30_miptree *)miptree[unit]; + pipe_texture_reference((struct pipe_texture **) + &nv30->tex_miptree[unit], miptree[unit]); nv30->dirty_samplers |= (1 << unit); } + + for (unit = nr; unit < nv30->nr_textures; unit++) { + pipe_texture_reference((struct pipe_texture **) + &nv30->tex_miptree[unit], NULL); + nv30->dirty_samplers |= (1 << unit); + } + + nv30->nr_textures = nr; + nv30->dirty |= NV30_NEW_SAMPLER; } static void * diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index eca1f0652c..0ea7857197 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -47,7 +47,7 @@ nv30_emit_hw_state(struct nv30_context *nv30) { struct nv30_state *state = &nv30->state; struct nv30_screen *screen = nv30->screen; - unsigned i; + unsigned i, samplers; uint64 states; if (nv30->pctx_id != screen->cur_pctx) { @@ -91,6 +91,13 @@ nv30_emit_hw_state(struct nv30_context *nv30) nv30->dirty_samplers = 0; so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]); + for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { + if (!(samplers & (1 << i))) + continue; + so_emit_reloc_markers(nv30->nvws, + state->hw[NV30_STATE_FRAGTEX0+i]); + samplers &= ~(1ULL << i); + } /* Texture images, emitted in nv30_fragtex_build */ #if 0 -- cgit v1.2.3 From 49937b99855984dd01a431c026f9308b6c0dac4f Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Thu, 3 Jul 2008 20:05:32 -0400 Subject: g3dvl: Round surfaces up to POT, use src rect when outputting surfaces. --- src/gallium/state_trackers/g3dvl/Makefile | 2 +- src/gallium/state_trackers/g3dvl/vl_context.c | 48 +++++++++++++++++++++------ src/gallium/state_trackers/g3dvl/vl_context.h | 2 +- src/gallium/state_trackers/g3dvl/vl_surface.c | 29 +++++++++++++--- src/gallium/state_trackers/g3dvl/vl_types.h | 6 ++++ src/gallium/state_trackers/g3dvl/vl_util.c | 17 ++++++++++ src/gallium/state_trackers/g3dvl/vl_util.h | 7 ++++ 7 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 src/gallium/state_trackers/g3dvl/vl_util.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_util.h (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/Makefile b/src/gallium/state_trackers/g3dvl/Makefile index bd46d004e2..50e3c843b5 100644 --- a/src/gallium/state_trackers/g3dvl/Makefile +++ b/src/gallium/state_trackers/g3dvl/Makefile @@ -1,5 +1,5 @@ TARGET = libg3dvl.a -OBJECTS = vl_context.o vl_data.o vl_surface.o vl_shader_build.o +OBJECTS = vl_context.o vl_data.o vl_surface.o vl_shader_build.o vl_util.o GALLIUMDIR = ../.. CFLAGS += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index bd8743dc9a..58971bd7c7 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -11,6 +11,7 @@ #include #include "vl_shader_build.h" #include "vl_data.h" +#include "vl_util.h" static int vlInitIDCT(struct VL_CONTEXT *context) { @@ -1357,8 +1358,9 @@ static int vlInitMC(struct VL_CONTEXT *context) pipe = context->pipe; - context->states.mc.viewport.scale[0] = context->video_width; - context->states.mc.viewport.scale[1] = context->video_height; + /* For MC we render to textures, which are rounded up to nearest POT */ + context->states.mc.viewport.scale[0] = vlRoundUpPOT(context->video_width); + context->states.mc.viewport.scale[1] = vlRoundUpPOT(context->video_height); context->states.mc.viewport.scale[2] = 1; context->states.mc.viewport.scale[3] = 1; context->states.mc.viewport.translate[0] = 0; @@ -1512,6 +1514,13 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context) decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + + /* + * decl c0 ; Scaling vector to scale texcoord rect to source size + * decl c1 ; Translation vector to move texcoord rect into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* * decl o0 ; Vertex pos @@ -1522,16 +1531,18 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context) decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + + /* mov o0, i0 ; Move pos in to pos out */ + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_INPUT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mul t0, i1, c0 ; Scale unit texcoord rect to source size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 1, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* - * mov o0, i0 ; Move pos in to pos out - * mov o1, i1 ; Move input texcoords to output - */ - for (i = 0; i < 2; i++) - { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } + /* add o1, t0, c1 ; Translate texcoord rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* end */ inst = vl_end(); @@ -1693,6 +1704,19 @@ static int vlCreateDataBufsCSC(struct VL_CONTEXT *context) 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 vertex shader's constant buffer + Const buffer contains scaling and translation vectors + */ + context->states.csc.vs_const_buf.size = sizeof(struct VL_CSC_VS_CONSTS); + context->states.csc.vs_const_buf.buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + context->states.csc.vs_const_buf.size + ); + /* Create our fragment shader's constant buffer Const buffer contains the color conversion matrix and bias vectors @@ -1776,6 +1800,7 @@ static int vlDestroyCSC(struct VL_CONTEXT *context) 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.vs_const_buf.buffer); context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.csc.fs_const_buf.buffer); return 0; @@ -1986,6 +2011,7 @@ int vlEndRender(struct VL_CONTEXT *context) 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_VERTEX, 0, &context->states.csc.vs_const_buf); 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 index 8a12318073..9ebda21a1c 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.h +++ b/src/gallium/state_trackers/g3dvl/vl_context.h @@ -49,7 +49,7 @@ struct VL_CONTEXT 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; + struct pipe_constant_buffer vs_const_buf, fs_const_buf; } csc; } states; }; diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 68313cc750..13f7301f07 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -7,6 +7,7 @@ #include #include "vl_context.h" #include "vl_defs.h" +#include "vl_util.h" static int vlGrabFrameCodedFullBlock(short *src, short *dst, unsigned int dst_pitch) { @@ -194,9 +195,6 @@ static int vlGrabBlocks pipe_surface_unmap(tex_surface); } - /* XXX: Texture cache is not invalidated when texture contents change */ - context->pipe->flush(context->pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL); - return 0; } @@ -214,8 +212,8 @@ int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface) sfc = calloc(1, sizeof(struct VL_SURFACE)); sfc->context = context; - sfc->width = context->video_width; - sfc->height = context->video_height; + sfc->width = vlRoundUpPOT(context->video_width); + sfc->height = vlRoundUpPOT(context->video_height); sfc->format = context->video_format; memset(&template, 0, sizeof(struct pipe_texture)); @@ -227,6 +225,7 @@ int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface) template.depth[0] = 1; template.compressed = 0; pf_get_block(template.format, &template.block); + /* XXX: Needed? */ template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; sfc->texture = pipe->screen->texture_create(pipe->screen, &template); @@ -517,6 +516,7 @@ int vlPutSurface { unsigned int create_fb = 0; struct pipe_context *pipe; + struct VL_CSC_VS_CONSTS *vs_consts; assert(surface); @@ -568,9 +568,28 @@ int vlPutSurface vlEndRender(surface->context); + vs_consts = pipe->winsys->buffer_map + ( + pipe->winsys, + surface->context->states.csc.vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ); + + vs_consts->src_scale.x = srcw / (float)surface->width; + vs_consts->src_scale.y = srch / (float)surface->height; + vs_consts->src_scale.z = 1; + vs_consts->src_scale.w = 1; + vs_consts->src_trans.x = srcx / (float)surface->width; + vs_consts->src_trans.y = srcy / (float)surface->height; + vs_consts->src_trans.z = 0; + vs_consts->src_trans.w = 0; + + pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.csc.vs_const_buf.buffer); + 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); + /* XXX: Need to take destx, desty into consideration */ pipe->winsys->flush_frontbuffer ( pipe->winsys, diff --git a/src/gallium/state_trackers/g3dvl/vl_types.h b/src/gallium/state_trackers/g3dvl/vl_types.h index 97753699db..4d210c9e0a 100644 --- a/src/gallium/state_trackers/g3dvl/vl_types.h +++ b/src/gallium/state_trackers/g3dvl/vl_types.h @@ -75,6 +75,12 @@ struct VL_MC_FS_CONSTS struct VL_VERTEX4F y_divider; }; +struct VL_CSC_VS_CONSTS +{ + struct VL_VERTEX4F src_scale; + struct VL_VERTEX4F src_trans; +}; + struct VL_CSC_FS_CONSTS { struct VL_VERTEX4F bias; diff --git a/src/gallium/state_trackers/g3dvl/vl_util.c b/src/gallium/state_trackers/g3dvl/vl_util.c new file mode 100644 index 0000000000..2421ae2210 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_util.c @@ -0,0 +1,17 @@ +#include "vl_util.h" +#include + +unsigned int vlRoundUpPOT(unsigned int x) +{ + unsigned int i; + + assert(x > 0); + + --x; + + for (i = 1; i < sizeof(unsigned int) * 8; i <<= 1) + x |= x >> i; + + return x + 1; +} + diff --git a/src/gallium/state_trackers/g3dvl/vl_util.h b/src/gallium/state_trackers/g3dvl/vl_util.h new file mode 100644 index 0000000000..e4b72c4f87 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_util.h @@ -0,0 +1,7 @@ +#ifndef vl_util_h +#define vl_util_h + +unsigned int vlRoundUpPOT(unsigned int x); + +#endif + -- cgit v1.2.3 From 6235141fd2c7af21c2b41ca66f06abc3cb0bbc24 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 6 Jul 2008 22:04:29 -0400 Subject: g3dvl: IDCT part 1. Very basic IDCT support is in, performed CPU-side for now. --- src/gallium/state_trackers/g3dvl/vl_context.c | 241 +++++++++++++++++++++++++- src/gallium/state_trackers/g3dvl/vl_context.h | 10 ++ src/gallium/state_trackers/g3dvl/vl_surface.c | 136 ++++++++++++++- src/libXvMC/surface.c | 2 + 4 files changed, 381 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 58971bd7c7..1668ad1651 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -11,22 +11,262 @@ #include #include "vl_shader_build.h" #include "vl_data.h" +#include "vl_defs.h" #include "vl_util.h" +static int vlCreateVertexShaderFrameIDCT(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 50; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + 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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Vertex texcoords + */ + for (i = 0; i < 2; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl o0 ; Vertex pos + * decl o1 ; Vertex texcoords + */ + for (i = 0; i < 2; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * mov o0, i0 ; Move pos in to pos out + * mov o1, i1 ; Move texcoord in to texcoord out */ + for (i = 0; i < 2; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + //context->states.idct.frame_vs = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderFrameIDCT(struct VL_CONTEXT *context) +{ + const unsigned int max_tokens = 50; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + 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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* decl i0 ; Texcoords for s0 */ + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl s0 ; Sampler for tex containing picture to display */ + decl = vl_decl_samplers(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* tex2d t0, i0, s0 ; Read src pixel */ + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* sub t0, t0, c0 ; Subtract bias vector from pixel */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix + * dp4 o0.y, t0, c2 + * dp4 o0.z, t0, c3 + * dp4 o0.w, t0, c4 ; XXX: Don't need 4th coefficient + */ + for (i = 0; i < 4; ++i) + { + inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1); + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + //context->states.idct.frame_fs = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + static int vlInitIDCT(struct VL_CONTEXT *context) { + struct pipe_context *pipe; + struct pipe_sampler_state sampler; + struct pipe_texture template; + unsigned int i; + assert(context); + pipe = context->pipe; + + context->states.idct.viewport.scale[0] = VL_BLOCK_WIDTH; + context->states.idct.viewport.scale[1] = VL_BLOCK_HEIGHT; + context->states.idct.viewport.scale[2] = 1; + context->states.idct.viewport.scale[3] = 1; + context->states.idct.viewport.translate[0] = 0; + context->states.idct.viewport.translate[1] = 0; + context->states.idct.viewport.translate[2] = 0; + context->states.idct.viewport.translate[3] = 0; + + context->states.idct.render_target.width = VL_BLOCK_WIDTH; + context->states.idct.render_target.height = VL_BLOCK_HEIGHT; + context->states.idct.render_target.num_cbufs = 1; + context->states.idct.render_target.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_NEAREST; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + 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 = 0; + /*sampler.max_lod = ;*/ + /*sampler.border_color[i] = ;*/ + /*sampler.max_anisotropy = ;*/ + context->states.idct.sampler = 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; + template.depth[0] = 1; + template.compressed = 0; + pf_get_block(template.format, &template.block); + + context->states.idct.texture = pipe->screen->texture_create(pipe->screen, &template); + + template.format = PIPE_FORMAT_A8R8G8B8_UNORM; + template.width[0] = 16; + template.height[0] = 1; + context->states.idct.basis = pipe->screen->texture_create(pipe->screen, &template); + + for (i = 0; i < 2; ++i) + { + context->states.idct.vertex_bufs[i] = &context->states.csc.vertex_bufs[i]; + context->states.idct.vertex_buf_elems[i] = &context->states.csc.vertex_buf_elems[i]; + /* + context->states.idct.vertex_bufs[i].pitch = sizeof(struct VL_VERTEX2F); + context->states.idct.vertex_bufs[i].max_index = 3; + context->states.idct.vertex_bufs[i].buffer_offset = 0; + context->states.idct.vertex_bufs[i].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct VL_VERTEX2F) * 4 + ); + + context->states.idct.vertex_buf_elems[i].src_offset = 0; + context->states.idct.vertex_buf_elems[i].vertex_buffer_index = i; + context->states.idct.vertex_buf_elems[i].nr_components = 2; + context->states.idct.vertex_buf_elems[i].src_format = PIPE_FORMAT_R32G32_FLOAT; + */ + } + + vlCreateVertexShaderFrameIDCT(context); + vlCreateFragmentShaderFrameIDCT(context); return 0; } static int vlDestroyIDCT(struct VL_CONTEXT *context) { + //unsigned int i; + assert(context); + context->pipe->delete_sampler_state(context->pipe, context->states.idct.sampler); + + //for (i = 0; i < 2; ++i) + //context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.idct.vertex_bufs[i].buffer); + + pipe_texture_release(&context->states.idct.texture); + pipe_texture_release(&context->states.idct.basis); + + //context->pipe->delete_vs_state(context->pipe, context->states.idct.frame_vs); + //context->pipe->delete_fs_state(context->pipe, context->states.idct.frame_fs); + //context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.idct.vs_const_buf.buffer); + //context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.idct.fs_const_buf.buffer); return 0; } @@ -1271,7 +1511,6 @@ int vlCreateDataBufsMC(struct VL_CONTEXT *context) 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); diff --git a/src/gallium/state_trackers/g3dvl/vl_context.h b/src/gallium/state_trackers/g3dvl/vl_context.h index 9ebda21a1c..bff318854a 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.h +++ b/src/gallium/state_trackers/g3dvl/vl_context.h @@ -26,6 +26,16 @@ struct VL_CONTEXT struct { + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state render_target; + struct pipe_sampler_state *sampler; + struct pipe_texture *texture; + struct pipe_texture *basis; + struct pipe_shader_state *frame_vs; + struct pipe_shader_state *frame_fs; + struct pipe_vertex_buffer *vertex_bufs[2]; + struct pipe_vertex_element *vertex_buf_elems[2]; + //struct pipe_constant_buffer vs_const_buf, fs_const_buf; } idct; struct diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 13f7301f07..145ea32892 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -9,6 +9,59 @@ #include "vl_defs.h" #include "vl_util.h" +static int vlTransformBlock(short *src, short *dst, short bias) +{ + static const float basis[8][8] = + { + {0.3536, 0.4904, 0.4619, 0.4157, 0.3536, 0.2778, 0.1913, 0.0975}, + {0.3536, 0.4157, 0.1913, -0.0975, -0.3536, -0.4904, -0.4619, -0.2778}, + {0.3536, 0.2778, -0.1913, -0.4904, -0.3536, 0.0975, 0.4619, 0.4157}, + {0.3536, 0.0975, -0.4619, -0.2778, 0.3536, 0.4157, -0.1913, -0.4904}, + {0.3536, -0.0975, -0.4619, 0.2778, 0.3536, -0.4157, -0.1913, 0.4904}, + {0.3536, -0.2778, -0.1913, 0.4904, -0.3536, -0.0975, 0.4619, -0.4157}, + {0.3536, -0.4157, 0.1913, 0.0975, -0.3536, 0.4904, -0.4619, 0.2778}, + {0.3536, -0.4904, 0.4619, -0.4157, 0.3536, -0.2778, 0.1913, -0.0975} + }; + + unsigned int x, y; + short tmp[64]; + + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + tmp[y * VL_BLOCK_WIDTH + x] = (short) + ( + src[y * VL_BLOCK_WIDTH + 0] * basis[x][0] + + src[y * VL_BLOCK_WIDTH + 1] * basis[x][1] + + src[y * VL_BLOCK_WIDTH + 2] * basis[x][2] + + src[y * VL_BLOCK_WIDTH + 3] * basis[x][3] + + src[y * VL_BLOCK_WIDTH + 4] * basis[x][4] + + src[y * VL_BLOCK_WIDTH + 5] * basis[x][5] + + src[y * VL_BLOCK_WIDTH + 6] * basis[x][6] + + src[y * VL_BLOCK_WIDTH + 7] * basis[x][7] + ); + + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + { + dst[y * VL_BLOCK_WIDTH + x] = bias + (short) + ( + tmp[0 * VL_BLOCK_WIDTH + x] * basis[y][0] + + tmp[1 * VL_BLOCK_WIDTH + x] * basis[y][1] + + tmp[2 * VL_BLOCK_WIDTH + x] * basis[y][2] + + tmp[3 * VL_BLOCK_WIDTH + x] * basis[y][3] + + tmp[4 * VL_BLOCK_WIDTH + x] * basis[y][4] + + tmp[5 * VL_BLOCK_WIDTH + x] * basis[y][5] + + tmp[6 * VL_BLOCK_WIDTH + x] * basis[y][6] + + tmp[7 * VL_BLOCK_WIDTH + x] * basis[y][7] + ); + if (dst[y * VL_BLOCK_WIDTH + x] > 255) + dst[y * VL_BLOCK_WIDTH + x] = 255; + else if (bias > 0 && dst[y * VL_BLOCK_WIDTH + x] < 0) + dst[y * VL_BLOCK_WIDTH + x] = 0; + } + return 0; +} + static int vlGrabFrameCodedFullBlock(short *src, short *dst, unsigned int dst_pitch) { unsigned int y; @@ -102,6 +155,9 @@ static int vlGrabBlocks unsigned int tex_pitch; unsigned int tb, sb = 0; + const int do_idct = 1; + short temp_block[64]; + assert(context); assert(blocks); @@ -121,6 +177,17 @@ static int vlGrabBlocks { if (dct_type == VL_DCT_FRAME_CODED) if (sample_type == VL_FULL_SAMPLE) + if (do_idct) + { + vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 128); + vlGrabFrameCodedFullBlock + ( + temp_block, + texels + tb * tex_pitch * VL_BLOCK_HEIGHT, + tex_pitch + ); + } + else vlGrabFrameCodedFullBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, @@ -128,6 +195,17 @@ static int vlGrabBlocks tex_pitch ); else + if (do_idct) + { + vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 0); + vlGrabFrameCodedDiffBlock + ( + temp_block, + texels + tb * tex_pitch * VL_BLOCK_HEIGHT, + tex_pitch + ); + } + else vlGrabFrameCodedDiffBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, @@ -136,6 +214,17 @@ static int vlGrabBlocks ); else if (sample_type == VL_FULL_SAMPLE) + if (do_idct) + { + vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 128); + vlGrabFieldCodedFullBlock + ( + temp_block, + texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, + tex_pitch + ); + } + else vlGrabFieldCodedFullBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, @@ -143,6 +232,17 @@ static int vlGrabBlocks tex_pitch ); else + if (do_idct) + { + vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 0); + vlGrabFieldCodedDiffBlock + ( + temp_block, + texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, + tex_pitch + ); + } + else vlGrabFieldCodedDiffBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, @@ -173,6 +273,17 @@ static int vlGrabBlocks if ((coded_block_pattern >> (1 - tb)) & 1) { if (sample_type == VL_FULL_SAMPLE) + if (do_idct) + { + vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 128); + vlGrabFrameCodedFullBlock + ( + temp_block, + texels, + tex_pitch + ); + } + else vlGrabFrameCodedFullBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, @@ -180,6 +291,17 @@ static int vlGrabBlocks tex_pitch ); else + if (do_idct) + { + vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 0); + vlGrabFrameCodedDiffBlock + ( + temp_block, + texels, + tex_pitch + ); + } + else vlGrabFrameCodedDiffBlock ( blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, @@ -266,6 +388,8 @@ int vlRenderIMacroBlock if (picture_type != VL_FRAME_PICTURE) return 0; + vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_FULL_SAMPLE, blocks); + pipe = surface->context->pipe; vs_consts = pipe->winsys->buffer_map @@ -298,8 +422,6 @@ int vlRenderIMacroBlock pipe->bind_vs_state(pipe, surface->context->states.mc.i_vs); pipe->bind_fs_state(pipe, surface->context->states.mc.i_fs); - vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_FULL_SAMPLE, blocks); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); return 0; @@ -335,6 +457,8 @@ int vlRenderPMacroBlock if (mc_type != VL_FRAME_MC && mc_type != VL_FIELD_MC) return 0; + vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks); + pipe = surface->context->pipe; vs_consts = pipe->winsys->buffer_map @@ -390,8 +514,6 @@ int vlRenderPMacroBlock pipe->set_sampler_textures(pipe, 4, surface->context->states.mc.textures); pipe->bind_sampler_states(pipe, 4, (void**)surface->context->states.mc.samplers); - vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); return 0; @@ -428,6 +550,8 @@ int vlRenderBMacroBlock if (mc_type != VL_FRAME_MC && mc_type != VL_FIELD_MC) return 0; + vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks); + pipe = surface->context->pipe; vs_consts = pipe->winsys->buffer_map @@ -492,8 +616,6 @@ int vlRenderBMacroBlock pipe->set_sampler_textures(pipe, 5, surface->context->states.mc.textures); pipe->bind_sampler_states(pipe, 5, (void**)surface->context->states.mc.samplers); - vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); return 0; @@ -589,7 +711,7 @@ int vlPutSurface 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); - /* XXX: Need to take destx, desty into consideration */ + /* TODO: Need to take destx, desty into consideration */ pipe->winsys->flush_frontbuffer ( pipe->winsys, diff --git a/src/libXvMC/surface.c b/src/libXvMC/surface.c index 5656895650..a550114655 100644 --- a/src/libXvMC/surface.c +++ b/src/libXvMC/surface.c @@ -146,6 +146,8 @@ Status XvMCRenderSurface assert(flags == 0 || flags == XVMC_SECOND_FIELD); + /* TODO: Batch macroblocks by type (I,P,B) */ + for (i = first_macroblock; i < first_macroblock + num_macroblocks; ++i) if (macroblocks->macro_blocks[i].macroblock_type & XVMC_MB_TYPE_INTRA) vlRenderIMacroBlock -- cgit v1.2.3 From 52a68dd9eb1d347aa01ce09db9375793d0d0ceaf Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 8 Jul 2008 01:06:18 +0200 Subject: nv04. --- configs/default | 2 +- src/gallium/drivers/nouveau/nouveau_winsys.h | 6 + src/gallium/drivers/nv04/Makefile | 28 ++ src/gallium/drivers/nv04/nv04_clear.c | 12 + src/gallium/drivers/nv04/nv04_context.c | 107 ++++++ src/gallium/drivers/nv04/nv04_context.h | 142 ++++++++ src/gallium/drivers/nv04/nv04_fragprog.c | 22 ++ src/gallium/drivers/nv04/nv04_fragtex.c | 100 ++++++ src/gallium/drivers/nv04/nv04_miptree.c | 138 ++++++++ src/gallium/drivers/nv04/nv04_prim_vbuf.c | 312 +++++++++++++++++ src/gallium/drivers/nv04/nv04_screen.c | 216 ++++++++++++ src/gallium/drivers/nv04/nv04_screen.h | 25 ++ src/gallium/drivers/nv04/nv04_state.c | 494 +++++++++++++++++++++++++++ src/gallium/drivers/nv04/nv04_state.h | 71 ++++ src/gallium/drivers/nv04/nv04_state_emit.c | 156 +++++++++ src/gallium/drivers/nv04/nv04_surface.c | 65 ++++ src/gallium/drivers/nv04/nv04_vbo.c | 72 ++++ 17 files changed, 1967 insertions(+), 1 deletion(-) create mode 100644 src/gallium/drivers/nv04/Makefile create mode 100644 src/gallium/drivers/nv04/nv04_clear.c create mode 100644 src/gallium/drivers/nv04/nv04_context.c create mode 100644 src/gallium/drivers/nv04/nv04_context.h create mode 100644 src/gallium/drivers/nv04/nv04_fragprog.c create mode 100644 src/gallium/drivers/nv04/nv04_fragtex.c create mode 100644 src/gallium/drivers/nv04/nv04_miptree.c create mode 100644 src/gallium/drivers/nv04/nv04_prim_vbuf.c create mode 100644 src/gallium/drivers/nv04/nv04_screen.c create mode 100644 src/gallium/drivers/nv04/nv04_screen.h create mode 100644 src/gallium/drivers/nv04/nv04_state.c create mode 100644 src/gallium/drivers/nv04/nv04_state.h create mode 100644 src/gallium/drivers/nv04/nv04_state_emit.c create mode 100644 src/gallium/drivers/nv04/nv04_surface.c create mode 100644 src/gallium/drivers/nv04/nv04_vbo.c (limited to 'src/gallium') diff --git a/configs/default b/configs/default index a8d1fe6bec..c1bc5fb01d 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 nv10 nv30 nv40 nv50 failover +GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv04 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/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 13810460bf..48feeba309 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -57,6 +57,12 @@ struct nouveau_winsys { unsigned, unsigned, unsigned, unsigned, unsigned); }; +extern struct pipe_screen * +nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); + +extern struct pipe_context * +nv04_create(struct pipe_screen *, unsigned pctx_id); + extern struct pipe_screen * nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); diff --git a/src/gallium/drivers/nv04/Makefile b/src/gallium/drivers/nv04/Makefile new file mode 100644 index 0000000000..5ea51a2f42 --- /dev/null +++ b/src/gallium/drivers/nv04/Makefile @@ -0,0 +1,28 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = nv04 + +DRIVER_SOURCES = \ + nv04_clear.c \ + nv04_context.c \ + nv04_fragprog.c \ + nv04_fragtex.c \ + nv04_miptree.c \ + nv04_prim_vbuf.c \ + nv04_screen.c \ + nv04_state.c \ + nv04_state_emit.c \ + nv04_surface.c \ + nv04_vbo.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/nv04/nv04_clear.c b/src/gallium/drivers/nv04/nv04_clear.c new file mode 100644 index 0000000000..01cacd36fe --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_clear.c @@ -0,0 +1,12 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "nv04_context.h" + +void +nv04_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/nv04/nv04_context.c b/src/gallium/drivers/nv04/nv04_context.c new file mode 100644 index 0000000000..852a8edf5f --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_context.c @@ -0,0 +1,107 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv04_context.h" +#include "nv04_screen.h" + +static void +nv04_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + draw_flush(nv04->draw); + + FIRE_RING(fence); +} + +static void +nv04_destroy(struct pipe_context *pipe) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + if (nv04->draw) + draw_destroy(nv04->draw); + + FREE(nv04); +} + +static void +nv04_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +{ +} + +static boolean +nv04_init_hwctx(struct nv04_context *nv04) +{ + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_NOTIFY, 1); + OUT_RING(0); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_NOP, 1); + OUT_RING(0); + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING(0x40182800); +// OUT_RING(1<<20/*no cull*/); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1); +// OUT_RING(0x24|(1<<6)|(1<<8)); + OUT_RING(0x120001a4); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FORMAT, 1); + OUT_RING(0x332213a1); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FILTER, 1); + OUT_RING(0x11001010); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_COLORKEY, 1); + OUT_RING(0x0); +// BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 1); +// OUT_RING(SCREEN_OFFSET); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR, 1); + OUT_RING(0xff000000); + + + + FIRE_RING (NULL); + return TRUE; +} + +struct pipe_context * +nv04_create(struct pipe_screen *pscreen, unsigned pctx_id) +{ + struct nv04_screen *screen = nv04_screen(pscreen); + struct pipe_winsys *ws = pscreen->winsys; + struct nv04_context *nv04; + struct nouveau_winsys *nvws = screen->nvws; + + nv04 = CALLOC(1, sizeof(struct nv04_context)); + if (!nv04) + return NULL; + nv04->screen = screen; + nv04->pctx_id = pctx_id; + + nv04->nvws = nvws; + + nv04->pipe.winsys = ws; + nv04->pipe.screen = pscreen; + nv04->pipe.destroy = nv04_destroy; + nv04->pipe.set_edgeflags = nv04_set_edgeflags; + nv04->pipe.draw_arrays = nv04_draw_arrays; + nv04->pipe.draw_elements = nv04_draw_elements; + nv04->pipe.clear = nv04_clear; + nv04->pipe.flush = nv04_flush; + + nv04_init_surface_functions(nv04); + nv04_init_state_functions(nv04); + + nv04->draw = draw_create(); + assert(nv04->draw); + draw_wide_point_threshold(nv04->draw, 0.0); + draw_wide_line_threshold(nv04->draw, 0.0); + draw_enable_line_stipple(nv04->draw, FALSE); + draw_enable_point_sprites(nv04->draw, FALSE); + draw_set_rasterize_stage(nv04->draw, nv04_draw_vbuf_stage(nv04)); + + nv04_init_hwctx(nv04); + + return &nv04->pipe; +} + diff --git a/src/gallium/drivers/nv04/nv04_context.h b/src/gallium/drivers/nv04/nv04_context.h new file mode 100644 index 0000000000..5ba1d4ecdc --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_context.h @@ -0,0 +1,142 @@ +#ifndef __NV04_CONTEXT_H__ +#define __NV04_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 nv04_screen *ctx = nv04->screen +#include "nouveau/nouveau_push.h" + +#include "nv04_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); + +#include "nv04_screen.h" + +#define NV04_NEW_VERTPROG (1 << 1) +#define NV04_NEW_FRAGPROG (1 << 2) +#define NV04_NEW_BLEND (1 << 3) +#define NV04_NEW_RAST (1 << 4) +#define NV04_NEW_CONTROL (1 << 5) +#define NV04_NEW_VIEWPORT (1 << 6) +#define NV04_NEW_SAMPLER (1 << 7) + +struct nv04_context { + struct pipe_context pipe; + + struct nouveau_winsys *nvws; + struct nv04_screen *screen; + unsigned pctx_id; + + struct draw_context *draw; + + int chipset; + struct nouveau_notifier *sync; + + uint32_t dirty; + + struct nv04_blend_state *blend; + struct nv04_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + struct nv04_fragtex_state fragtex; + struct nv04_rasterizer_state *rast; + struct nv04_depth_stencil_alpha_state *dsa; + + struct nv04_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; + + struct { + struct pipe_buffer *buffer; + uint32_t format; + } tex[16]; + + unsigned vb_enable; + struct { + struct pipe_buffer *buffer; + unsigned delta; + } vb[16]; + + struct vertex_info vertex_info; + struct { + + struct nouveau_resource *exec_heap; + struct nouveau_resource *data_heap; + + struct nv04_vertex_program *active; + + struct nv04_vertex_program *current; + struct pipe_buffer *constant_buf; + } vertprog; + + struct { + struct nv04_fragment_program *active; + + struct nv04_fragment_program *current; + struct pipe_buffer *constant_buf; + } fragprog; + + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + unsigned num_vertex_buffers; + unsigned num_vertex_elements; + + struct pipe_viewport_state viewport; +}; + +static INLINE struct nv04_context * +nv04_context(struct pipe_context *pipe) +{ + return (struct nv04_context *)pipe; +} + +extern void nv04_init_state_functions(struct nv04_context *nv04); +extern void nv04_init_surface_functions(struct nv04_context *nv04); +extern void nv04_init_miptree_functions(struct pipe_screen *screen); + +/* nv04_clear.c */ +extern void nv04_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + +/* nv04_draw.c */ +extern struct draw_stage *nv04_draw_render_stage(struct nv04_context *nv04); + +/* nv04_fragprog.c */ +extern void nv04_fragprog_bind(struct nv04_context *, + struct nv04_fragment_program *); +extern void nv04_fragprog_destroy(struct nv04_context *, + struct nv04_fragment_program *); + +/* nv04_fragtex.c */ +extern void nv04_fragtex_bind(struct nv04_context *); + +/* nv04_prim_vbuf.c */ +struct draw_stage *nv04_draw_vbuf_stage( struct nv04_context *nv04 ); + +/* nv04_state.c and friends */ +extern void nv04_emit_hw_state(struct nv04_context *nv04); +extern void nv04_state_tex_update(struct nv04_context *nv04); + +/* nv04_vbo.c */ +extern boolean nv04_draw_arrays(struct pipe_context *, unsigned mode, + unsigned start, unsigned count); +extern boolean nv04_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/nv04/nv04_fragprog.c b/src/gallium/drivers/nv04/nv04_fragprog.c new file mode 100644 index 0000000000..11f4360ed8 --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_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 "nv04_context.h" + +void +nv04_fragprog_bind(struct nv04_context *nv04, struct nv04_fragment_program *fp) +{ +} + +void +nv04_fragprog_destroy(struct nv04_context *nv04, + struct nv04_fragment_program *fp) +{ +} + diff --git a/src/gallium/drivers/nv04/nv04_fragtex.c b/src/gallium/drivers/nv04/nv04_fragtex.c new file mode 100644 index 0000000000..3db673cd2c --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_fragtex.c @@ -0,0 +1,100 @@ +#include "nv04_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) \ +{ \ + PIPE_FORMAT_##m, \ + NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_##tf, \ +} + +struct nv04_texture_format { + uint pipe; + int format; +}; + +static struct nv04_texture_format +nv04_texture_formats[] = { + _(A8R8G8B8_UNORM, A8R8G8B8), + _(X8R8G8B8_UNORM, X8R8G8B8), + _(A1R5G5B5_UNORM, A1R5G5B5), + _(A4R4G4B4_UNORM, A4R4G4B4), + _(L8_UNORM, Y8 ), + _(A8_UNORM, Y8 ), +}; + +static uint32_t +nv04_fragtex_format(uint pipe_format) +{ + struct nv04_texture_format *tf = nv04_texture_formats; + char fs[128]; + int i; + + for (i=0; i< sizeof(nv04_texture_formats)/sizeof(nv04_texture_formats[0]); i++) { + if (tf->pipe == pipe_format) + return tf->format; + tf++; + } + + pf_sprint_name(fs, pipe_format); + NOUVEAU_ERR("unknown texture format %s\n", fs); + return 0; +} + + +static void +nv04_fragtex_build(struct nv04_context *nv04, int unit) +{ + struct nv04_miptree *nv04mt = nv04->tex_miptree[unit]; + struct pipe_texture *pt = &nv04mt->base; + + switch (pt->target) { + case PIPE_TEXTURE_2D: + break; + default: + NOUVEAU_ERR("Unknown target %d\n", pt->target); + return; + } + + nv04->fragtex.format = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_CORNER + | NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CORNER + | nv04_fragtex_format(pt->format) + | ( (pt->last_level + 1) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT ) + | ( log2i(pt->width[0]) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT ) + | ( log2i(pt->height[0]) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT ) + | NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE + | NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP_TO_EDGE + ; +} + + +void +nv04_fragtex_bind(struct nv04_context *nv04) +{ + nv04_fragtex_build(nv04, 0); +} + diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c new file mode 100644 index 0000000000..ab2d2386be --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -0,0 +1,138 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nv04_context.h" +#include "nv04_screen.h" + +static void +nv04_miptree_layout(struct nv04_miptree *nv04mt) +{ + struct pipe_texture *pt = &nv04mt->base; + uint width = pt->width[0], height = pt->height[0]; + uint offset = 0; + int nr_faces, l, f; + + nr_faces = 1; + + for (l = 0; l <= pt->last_level; l++) { + pt->width[l] = width; + pt->height[l] = height; + + pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); + + nv04mt->level[l].pitch = pt->width[0] * pt->block.size; + nv04mt->level[l].pitch = (nv04mt->level[l].pitch + 63) & ~63; + + nv04mt->level[l].image_offset = + CALLOC(nr_faces, sizeof(unsigned)); + + width = MAX2(1, width >> 1); + height = MAX2(1, height >> 1); + + } + + for (f = 0; f < nr_faces; f++) { + for (l = 0; l <= pt->last_level; l++) { + nv04mt->level[l].image_offset[f] = offset; + offset += nv04mt->level[l].pitch * pt->height[l]; + } + } + + nv04mt->total_size = offset; +} + +static struct pipe_texture * +nv04_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) +{ + struct pipe_winsys *ws = screen->winsys; + struct nv04_miptree *mt; + + mt = MALLOC(sizeof(struct nv04_miptree)); + if (!mt) + return NULL; + mt->base = *pt; + mt->base.refcount = 1; + mt->base.screen = screen; + + nv04_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 +nv04_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 nv04_miptree *nv04mt = (struct nv04_miptree *)mt; + int l; + + pipe_buffer_reference(ws, &nv04mt->buffer, NULL); + for (l = 0; l <= mt->last_level; l++) { + if (nv04mt->level[l].image_offset) + free(nv04mt->level[l].image_offset); + } + free(nv04mt); + } +} + +static struct pipe_surface * +nv04_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 nv04_miptree *nv04mt = (struct nv04_miptree *)pt; + struct pipe_surface *ps; + + ps = ws->surface_alloc(ws); + if (!ps) + return NULL; + pipe_buffer_reference(ws, &ps->buffer, nv04mt->buffer); + ps->format = pt->format; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->block = pt->block; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = nv04mt->level[level].pitch; + + if (pt->target == PIPE_TEXTURE_CUBE) { + ps->offset = nv04mt->level[level].image_offset[face]; + } else { + ps->offset = nv04mt->level[level].image_offset[0]; + } + + return ps; +} + +static void +nv04_miptree_surface_del(struct pipe_screen *pscreen, + struct pipe_surface **psurface) +{ +} + +void +nv04_init_miptree_functions(struct pipe_screen *pscreen) +{ + pscreen->texture_create = nv04_miptree_create; + pscreen->texture_release = nv04_miptree_release; + pscreen->get_tex_surface = nv04_miptree_surface_new; + pscreen->tex_surface_release = nv04_miptree_surface_del; +} + diff --git a/src/gallium/drivers/nv04/nv04_prim_vbuf.c b/src/gallium/drivers/nv04/nv04_prim_vbuf.c new file mode 100644 index 0000000000..daf28e81f5 --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_prim_vbuf.c @@ -0,0 +1,312 @@ + +// XXX this has to go somewhere else +#define NONINC_METHOD 0x40000000 + + +#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 "nv04_context.h" +#include "nv04_state.h" + +#define VERTEX_SIZE 40 +#define VERTEX_BUFFER_SIZE (4096*VERTEX_SIZE) // 4096 vertices of 40 bytes each + +/** + * Primitive renderer for nv04. + */ +struct nv04_vbuf_render { + struct vbuf_render base; + + struct nv04_context *nv04; + + /** Vertex buffer */ + unsigned char* buffer; + + /** Vertex size in bytes */ + unsigned vertex_size; + + /** Current primitive */ + unsigned prim; +}; + + +/** + * Basically a cast wrapper. + */ +static INLINE struct nv04_vbuf_render * +nv04_vbuf_render( struct vbuf_render *render ) +{ + assert(render); + return (struct nv04_vbuf_render *)render; +} + + +static const struct vertex_info * +nv04_vbuf_render_get_vertex_info( struct vbuf_render *render ) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + struct nv04_context *nv04 = nv04_render->nv04; + return &nv04->vertex_info; +} + + +static void * +nv04_vbuf_render_allocate_vertices( struct vbuf_render *render, + ushort vertex_size, + ushort nr_vertices ) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + + nv04_render->buffer = (unsigned char*) malloc(VERTEX_BUFFER_SIZE); + assert(!nv04_render->buffer); + + return nv04_render->buffer; +} + + +static boolean +nv04_vbuf_render_set_primitive( struct vbuf_render *render, + unsigned prim ) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + + if (prim <= PIPE_PRIM_LINE_STRIP) + return FALSE; + + nv04_render->prim = prim; + return TRUE; +} + +static INLINE void nv04_2triangles(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5) +{ + BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA),49); + OUT_RINGp(buffer + VERTEX_SIZE * v0,8); + OUT_RINGp(buffer + VERTEX_SIZE * v1,8); + OUT_RINGp(buffer + VERTEX_SIZE * v2,8); + OUT_RINGp(buffer + VERTEX_SIZE * v3,8); + OUT_RINGp(buffer + VERTEX_SIZE * v4,8); + OUT_RINGp(buffer + VERTEX_SIZE * v5,8); + OUT_RING(0xFEDCBA); +} + +static INLINE void nv04_1triangle(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2) +{ + BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD),25); + OUT_RINGp(buffer + VERTEX_SIZE * v0,8); + OUT_RINGp(buffer + VERTEX_SIZE * v1,8); + OUT_RINGp(buffer + VERTEX_SIZE * v2,8); + OUT_RING(0xFED); +} + +static INLINE void nv04_1quad(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3) +{ + BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC),33); + OUT_RINGp(buffer + VERTEX_SIZE * v0,8); + OUT_RINGp(buffer + VERTEX_SIZE * v1,8); + OUT_RINGp(buffer + VERTEX_SIZE * v2,8); + OUT_RINGp(buffer + VERTEX_SIZE * v3,8); + OUT_RING(0xFECEDC); +} + +static void nv04_vbuf_render_triangles_elts(struct nv04_vbuf_render * render, const ushort * indices, uint nr_indices) +{ + unsigned char* buffer = render->buffer; + struct nv04_context* nv04 = render->nv04; + int i; + + for( i=0; i< nr_indices-5; i+=6) + nv04_2triangles(nv04, + buffer, + indices[i+0], + indices[i+1], + indices[i+2], + indices[i+3], + indices[i+4], + indices[i+5] + ); + if (i != nr_indices) + { + nv04_1triangle(nv04, + buffer, + indices[i+0], + indices[i+1], + indices[i+2] + ); + i+=3; + } + if (i != nr_indices) + NOUVEAU_ERR("Houston, we have lost some vertices\n"); +} + +static void nv04_vbuf_render_tri_strip_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices) +{ + const uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC}; + unsigned char* buffer = render->buffer; + struct nv04_context* nv04 = render->nv04; + int i,j; + + for(i = 0; ibuffer; + struct nv04_context* nv04 = render->nv04; + int i,j; + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), 8); + OUT_RINGp(buffer + VERTEX_SIZE * indices[0], 8); + + for(i = 1; ibuffer; + struct nv04_context* nv04 = render->nv04; + int i; + + for(i = 0; i < nr_indices; i += 4) + nv04_1quad(nv04, + buffer, + indices[i+0], + indices[i+1], + indices[i+2], + indices[i+3] + ); +} + + +static void +nv04_vbuf_render_draw( struct vbuf_render *render, + const ushort *indices, + uint nr_indices) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + + // emit the indices + switch( nv04_render->prim ) + { + case PIPE_PRIM_TRIANGLES: + nv04_vbuf_render_triangles_elts(nv04_render, indices, nr_indices); + break; + case PIPE_PRIM_QUAD_STRIP: + case PIPE_PRIM_TRIANGLE_STRIP: + nv04_vbuf_render_tri_strip_elts(nv04_render, indices, nr_indices); + break; + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_POLYGON: + nv04_vbuf_render_tri_fan_elts(nv04_render, indices, nr_indices); + break; + case PIPE_PRIM_QUADS: + nv04_vbuf_render_quads_elts(nv04_render, indices, nr_indices); + break; + default: + NOUVEAU_ERR("You have to implement primitive %d, young padawan\n", nv04_render->prim); + break; + } +} + + +static void +nv04_vbuf_render_release_vertices( struct vbuf_render *render, + void *vertices, + unsigned vertex_size, + unsigned vertices_used ) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + + free(nv04_render->buffer); + nv04_render->buffer = NULL; +} + + +static void +nv04_vbuf_render_destroy( struct vbuf_render *render ) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + FREE(nv04_render); +} + + +/** + * Create a new primitive render. + */ +static struct vbuf_render * +nv04_vbuf_render_create( struct nv04_context *nv04 ) +{ + struct nv04_vbuf_render *nv04_render = CALLOC_STRUCT(nv04_vbuf_render); + + nv04_render->nv04 = nv04; + + nv04_render->base.max_vertex_buffer_bytes = VERTEX_BUFFER_SIZE; + nv04_render->base.max_indices = 65536; + nv04_render->base.get_vertex_info = nv04_vbuf_render_get_vertex_info; + nv04_render->base.allocate_vertices = nv04_vbuf_render_allocate_vertices; + nv04_render->base.set_primitive = nv04_vbuf_render_set_primitive; + nv04_render->base.draw = nv04_vbuf_render_draw; + nv04_render->base.release_vertices = nv04_vbuf_render_release_vertices; + nv04_render->base.destroy = nv04_vbuf_render_destroy; + + return &nv04_render->base; +} + + +/** + * Create a new primitive vbuf/render stage. + */ +struct draw_stage *nv04_draw_vbuf_stage( struct nv04_context *nv04 ) +{ + struct vbuf_render *render; + struct draw_stage *stage; + + render = nv04_vbuf_render_create(nv04); + if(!render) + return NULL; + + stage = draw_vbuf_stage( nv04->draw, render ); + if(!stage) { + render->destroy(render); + return NULL; + } + + return stage; +} diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c new file mode 100644 index 0000000000..9f34117b8c --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_screen.c @@ -0,0 +1,216 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv04_context.h" +#include "nv04_screen.h" + +static const char * +nv04_screen_get_name(struct pipe_screen *screen) +{ + struct nv04_screen *nv04screen = nv04_screen(screen); + struct nouveau_device *dev = nv04screen->nvws->channel->device; + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); + return buffer; +} + +static const char * +nv04_screen_get_vendor(struct pipe_screen *screen) +{ + return "nouveau"; +} + +static int +nv04_screen_get_param(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 1; + 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 0; + 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 10; + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 0; + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv04_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 0.0; + case PIPE_CAP_MAX_POINT_WIDTH: + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 0.0; + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 0.0; + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 0.0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0.0; + } +} + +static boolean +nv04_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_Z16_UNORM: + return TRUE; + default: + break; + } + break; + case PIPE_TEXTURE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_A8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static void * +nv04_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 +nv04_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) +{ + struct pipe_winsys *ws = screen->winsys; + + ws->buffer_unmap(ws, surface->buffer); +} + +static void +nv04_screen_destroy(struct pipe_screen *pscreen) +{ + struct nv04_screen *screen = nv04_screen(pscreen); + struct nouveau_winsys *nvws = screen->nvws; + + nvws->notifier_free(&screen->sync); + nvws->grobj_free(&screen->fahrenheit); + + FREE(pscreen); +} + +struct pipe_screen * +nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) +{ + struct nv04_screen *screen = CALLOC_STRUCT(nv04_screen); + unsigned fahrenheit_class = 0, sub3d_class = 0; + unsigned chipset = nvws->channel->device->chipset; + int ret; + + if (!screen) + return NULL; + screen->nvws = nvws; + + if (chipset>=0x20) { + fahrenheit_class = 0; + sub3d_class = 0; + } else if (chipset>=0x10) { + fahrenheit_class = NV10_DX5_TEXTURED_TRIANGLE; + sub3d_class = NV10_CONTEXT_SURFACES_3D; + } else { + fahrenheit_class=NV04_DX5_TEXTURED_TRIANGLE; + sub3d_class = NV04_CONTEXT_SURFACES_3D; + } + + if (!fahrenheit_class) { + NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", chipset); + return NULL; + } + + /* 3D object */ + ret = nvws->grobj_alloc(nvws, fahrenheit_class, &screen->fahrenheit); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return NULL; + } + + /* 3D surface object */ + ret = nvws->grobj_alloc(nvws, sub3d_class, &screen->context_surfaces_3d); + if (ret) { + NOUVEAU_ERR("Error creating 3D surface object: %d\n", ret); + return NULL; + } + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &screen->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv04_screen_destroy(&screen->pipe); + return NULL; + } + + screen->pipe.winsys = ws; + screen->pipe.destroy = nv04_screen_destroy; + + screen->pipe.get_name = nv04_screen_get_name; + screen->pipe.get_vendor = nv04_screen_get_vendor; + screen->pipe.get_param = nv04_screen_get_param; + screen->pipe.get_paramf = nv04_screen_get_paramf; + + screen->pipe.is_format_supported = nv04_screen_is_format_supported; + + screen->pipe.surface_map = nv04_surface_map; + screen->pipe.surface_unmap = nv04_surface_unmap; + + nv04_screen_init_miptree_functions(&screen->pipe); + + return &screen->pipe; +} + diff --git a/src/gallium/drivers/nv04/nv04_screen.h b/src/gallium/drivers/nv04/nv04_screen.h new file mode 100644 index 0000000000..99a49cdf7a --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_screen.h @@ -0,0 +1,25 @@ +#ifndef __NV04_SCREEN_H__ +#define __NV04_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv04_screen { + struct pipe_screen pipe; + + struct nouveau_winsys *nvws; + unsigned chipset; + + /* HW graphics objects */ + struct nouveau_grobj *fahrenheit; + struct nouveau_grobj *context_surfaces_3d; + struct nouveau_notifier *sync; + +}; + +static INLINE struct nv04_screen * +nv04_screen(struct pipe_screen *screen) +{ + return (struct nv04_screen *)screen; +} + +#endif diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c new file mode 100644 index 0000000000..39d7e8b42d --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_state.c @@ -0,0 +1,494 @@ +#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 "nv04_context.h" +#include "nv04_state.h" + +static void * +nv04_blend_state_create(struct pipe_context *pipe, + const struct pipe_blend_state *cso) +{ + struct nv04_blend_state *cb; + + cb = malloc(sizeof(struct nv04_blend_state)); + + cb->b_enable = cso->blend_enable ? 1 : 0; + cb->b_src = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | + (nvgl_blend_func(cso->rgb_src_factor))); + cb->b_dst = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) | + (nvgl_blend_func(cso->rgb_dst_factor))); + + + return (void *)cb; +} + +static void +nv04_blend_state_bind(struct pipe_context *pipe, void *blend) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + nv04->blend = (struct nv04_blend_state*)blend; + + nv04->dirty |= NV04_NEW_BLEND; +} + +static void +nv04_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 = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT; + break; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT; + break; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE; + break; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER; + break; + case PIPE_TEX_WRAP_CLAMP: + ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_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 = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP; + } + return ret >> NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT; +} + +static void * +nv04_sampler_state_create(struct pipe_context *pipe, + const struct pipe_sampler_state *cso) +{ + + struct nv04_sampler_state *ss; + uint32_t filter = 0; + + ss = malloc(sizeof(struct nv04_sampler_state)); + + ss->format = ((wrap_mode(cso->wrap_s) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT) | + (wrap_mode(cso->wrap_t) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT)); + + if (cso->max_anisotropy > 1.0) { + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE | NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE; + } + + switch (cso->mag_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + filter |= NV04_DX5_TEXTURED_TRIANGLE_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 |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR; + break; + } + break; + case PIPE_TEX_FILTER_NEAREST: + default: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST; + break; + } + break; + } + + ss->filter = filter; + + return (void *)ss; +} + +static void +nv04_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) +{ + struct nv04_context *nv04 = nv04_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nv04->sampler[unit] = sampler[unit]; + nv04->dirty_samplers |= (1 << unit); + } +} + +static void +nv04_sampler_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void +nv04_set_sampler_texture(struct pipe_context *pipe, unsigned nr, + struct pipe_texture **miptree) +{ + struct nv04_context *nv04 = nv04_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nv04->tex_miptree[unit] = (struct nv04_miptree *)miptree[unit]; + nv04->dirty_samplers |= (1 << unit); + } +} + +static void * +nv04_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + struct nv04_rasterizer_state *rs; + + /*XXX: ignored: + * scissor + * points/lines (no hw support, emulated with tris in gallium) + */ + rs = malloc(sizeof(struct nv04_rasterizer_state)); + + rs->blend = cso->flatshade ? NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT : NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; + + return (void *)rs; +} + +static void +nv04_rasterizer_state_bind(struct pipe_context *pipe, void *rast) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + nv04->rast = (struct nv04_rasterizer_state*)rast; + + draw_set_rasterizer_state(nv04->draw, (nv04->rast ? nv04->rast->templ : NULL)); + + nv04->dirty |= NV04_NEW_RAST | NV04_NEW_BLEND; +} + +static void +nv04_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static INLINE uint32_t nv04_compare_func(uint32_t f) +{ + switch ( f ) { + case PIPE_FUNC_NEVER: return 1; + case PIPE_FUNC_LESS: return 2; + case PIPE_FUNC_EQUAL: return 3; + case PIPE_FUNC_LEQUAL: return 4; + case PIPE_FUNC_GREATER: return 5; + case PIPE_FUNC_NOTEQUAL: return 6; + case PIPE_FUNC_GEQUAL: return 7; + case PIPE_FUNC_ALWAYS: return 8; + } + NOUVEAU_MSG("Unable to find the function\n"); + return 0; +} + +static void * +nv04_depth_stencil_alpha_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) +{ + struct nv04_depth_stencil_alpha_state *hw; + + hw = malloc(sizeof(struct nv04_depth_stencil_alpha_state)); + + hw->control = float_to_ubyte(cso->alpha.ref); + hw->control |= ( nv04_compare_func(cso->alpha.func) << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT ); + hw->control |= cso->alpha.enabled ? NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_TEST_ENABLE : 0; + hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ORIGIN; + hw->control |= cso->depth.enabled ? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE_SHIFT) : 0; + hw->control |= ( nv04_compare_func(cso->depth.func)<< NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT ); + hw->control |= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT; // no culling, handled by the draw module + hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; + hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE; + hw->control |= cso->depth.writemask ? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_WRITE_ENABLE_SHIFT) : 0; + hw->control |= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_SHIFT; // integer zbuffer format + + return (void *)hw; +} + +static void +nv04_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + nv04->dsa = hwcso; + nv04->dirty |= NV04_NEW_CONTROL; +} + +static void +nv04_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void * +nv04_vp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + return draw_create_vertex_shader(nv04->draw, templ); +} + +static void +nv04_vp_state_bind(struct pipe_context *pipe, void *shader) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + draw_bind_vertex_shader(nv04->draw, (struct draw_vertex_shader *) shader); + + nv04->dirty |= NV04_NEW_VERTPROG; +} + +static void +nv04_vp_state_delete(struct pipe_context *pipe, void *shader) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + draw_delete_vertex_shader(nv04->draw, (struct draw_vertex_shader *) shader); +} + +static void * +nv04_fp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv04_fragment_program *fp; + + fp = CALLOC(1, sizeof(struct nv04_fragment_program)); + fp->pipe = cso; + + return (void *)fp; +} + +static void +nv04_fp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct nv04_fragment_program *fp = hwcso; + + nv04->fragprog.current = fp; + nv04->dirty |= NV04_NEW_FRAGPROG; +} + +static void +nv04_fp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct nv04_fragment_program *fp = hwcso; + + nv04_fragprog_destroy(nv04, fp); + free(fp); +} + +static void +nv04_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *bcol) +{ +} + +static void +nv04_set_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *clip) +{ +} + +static void +nv04_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + const struct pipe_constant_buffer *buf ) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + if (shader == PIPE_SHADER_VERTEX) { + nv04->vertprog.constant_buf = buf->buffer; + nv04->dirty |= NV04_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nv04->fragprog.constant_buf = buf->buffer; + nv04->dirty |= NV04_NEW_FRAGPROG; + } +} + +static void +nv04_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct pipe_surface *rt, *zeta; + 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; + } + + switch (colour_format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case 0: + rt_format = 0x108; + break; + case PIPE_FORMAT_R5G6B5_UNORM: + rt_format = 0x103; + break; + default: + assert(0); + } + + BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); + OUT_RING(rt_format); + + /* FIXME pitches have to be aligned ! */ + BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2); + OUT_RING(rt->stride|(zeta->stride<<16)); + OUT_RELOCl(rt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + if (fb->zsbuf) { + BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); + OUT_RELOCl(zeta->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + } +} + +static void +nv04_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + NOUVEAU_ERR("line stipple hahaha\n"); +} + +static void +nv04_set_scissor_state(struct pipe_context *pipe, + const struct pipe_scissor_state *s) +{ +/* struct nv04_context *nv04 = nv04_context(pipe); + + // XXX + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_SCISSOR_HORIZ, 2); + OUT_RING (((s->maxx - s->minx) << 16) | s->minx); + OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/ +} + +static void +nv04_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *viewport) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + nv04->viewport = *viewport; + + draw_set_viewport_state(nv04->draw, &nv04->viewport); +} + +static void +nv04_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *buffers) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + draw_flush(nv04->draw); + + memcpy(nv04->vertex_buffer, buffers, count * sizeof(buffers[0])); + nv04->num_vertex_buffers = count; + + draw_set_vertex_buffers(nv04->draw, count, buffers); +} + +static void +nv04_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *elements) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + draw_flush(nv04->draw); + + nv04->num_vertex_elements = count; + draw_set_vertex_elements(nv04->draw, count, elements); +} + +void +nv04_init_state_functions(struct nv04_context *nv04) +{ + nv04->pipe.create_blend_state = nv04_blend_state_create; + nv04->pipe.bind_blend_state = nv04_blend_state_bind; + nv04->pipe.delete_blend_state = nv04_blend_state_delete; + + nv04->pipe.create_sampler_state = nv04_sampler_state_create; + nv04->pipe.bind_sampler_states = nv04_sampler_state_bind; + nv04->pipe.delete_sampler_state = nv04_sampler_state_delete; + nv04->pipe.set_sampler_textures = nv04_set_sampler_texture; + + nv04->pipe.create_rasterizer_state = nv04_rasterizer_state_create; + nv04->pipe.bind_rasterizer_state = nv04_rasterizer_state_bind; + nv04->pipe.delete_rasterizer_state = nv04_rasterizer_state_delete; + + nv04->pipe.create_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_create; + nv04->pipe.bind_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_bind; + nv04->pipe.delete_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_delete; + + nv04->pipe.create_vs_state = nv04_vp_state_create; + nv04->pipe.bind_vs_state = nv04_vp_state_bind; + nv04->pipe.delete_vs_state = nv04_vp_state_delete; + + nv04->pipe.create_fs_state = nv04_fp_state_create; + nv04->pipe.bind_fs_state = nv04_fp_state_bind; + nv04->pipe.delete_fs_state = nv04_fp_state_delete; + + nv04->pipe.set_blend_color = nv04_set_blend_color; + nv04->pipe.set_clip_state = nv04_set_clip_state; + nv04->pipe.set_constant_buffer = nv04_set_constant_buffer; + nv04->pipe.set_framebuffer_state = nv04_set_framebuffer_state; + nv04->pipe.set_polygon_stipple = nv04_set_polygon_stipple; + nv04->pipe.set_scissor_state = nv04_set_scissor_state; + nv04->pipe.set_viewport_state = nv04_set_viewport_state; + + nv04->pipe.set_vertex_buffers = nv04_set_vertex_buffers; + nv04->pipe.set_vertex_elements = nv04_set_vertex_elements; +} + diff --git a/src/gallium/drivers/nv04/nv04_state.h b/src/gallium/drivers/nv04/nv04_state.h new file mode 100644 index 0000000000..7487819c3a --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_state.h @@ -0,0 +1,71 @@ +#ifndef __NV04_STATE_H__ +#define __NV04_STATE_H__ + +#include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" + +struct nv04_blend_state { + uint32_t b_enable; + uint32_t b_src; + uint32_t b_dst; +}; + +struct nv04_fragtex_state { + uint32_t format; +}; + +struct nv04_sampler_state { + uint32_t filter; + uint32_t format; +}; + +struct nv04_depth_stencil_alpha_state { + uint32_t control; +}; + +struct nv04_rasterizer_state { + uint32_t blend; + + const struct pipe_rasterizer_state *templ; +}; + +struct nv04_miptree { + struct pipe_texture base; + + struct pipe_buffer *buffer; + uint total_size; + + struct { + uint pitch; + uint *image_offset; + } level[PIPE_MAX_TEXTURE_LEVELS]; +}; + +struct nv04_fragment_program_data { + unsigned offset; + unsigned index; +}; + +struct nv04_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 nv04_fragment_program_data *consts; + unsigned nr_consts; + + struct pipe_buffer *buffer; + + uint32_t fp_control; + uint32_t fp_reg_control; +}; + + + +#endif diff --git a/src/gallium/drivers/nv04/nv04_state_emit.c b/src/gallium/drivers/nv04/nv04_state_emit.c new file mode 100644 index 0000000000..0ad40a092e --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_state_emit.c @@ -0,0 +1,156 @@ +#include "nv04_context.h" +#include "nv04_state.h" + +static void nv04_vertex_layout(struct pipe_context* pipe) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct nv04_fragment_program *fp = nv04->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 (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); +} + +static uint32_t nv04_blend_func(uint32_t f) +{ + switch ( f ) { + case PIPE_BLENDFACTOR_ZERO: return 0x1; + case PIPE_BLENDFACTOR_ONE: return 0x2; + case PIPE_BLENDFACTOR_SRC_COLOR: return 0x3; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: return 0x4; + case PIPE_BLENDFACTOR_SRC_ALPHA: return 0x5; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return 0x6; + case PIPE_BLENDFACTOR_DST_ALPHA: return 0x7; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: return 0x8; + case PIPE_BLENDFACTOR_DST_COLOR: return 0x9; + case PIPE_BLENDFACTOR_INV_DST_COLOR: return 0xA; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return 0xB; + } + NOUVEAU_MSG("Unable to find the blend function 0x%x\n",f); + return 0; +} + +static void nv04_emit_control(struct nv04_context* nv04) +{ + uint32_t control = nv04->dsa->control; + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING(control); +} + +static void nv04_emit_blend(struct nv04_context* nv04) +{ + uint32_t blend; + + blend=0x4; // texture MODULATE_ALPHA + blend|=0x20; // alpha is MSB + blend|=(2<<6); // flat shading + blend|=(1<<8); // persp correct + blend|=(0<<16); // no fog + blend|=(nv04->blend->b_enable<<20); + blend|=(nv04_blend_func(nv04->blend->b_src)<<24); + blend|=(nv04_blend_func(nv04->blend->b_dst)<<28); + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1); + OUT_RING(blend); +} + +static void nv04_emit_sampler(struct nv04_context *nv04, int unit) +{ + struct nv04_miptree *nv04mt = nv04->tex_miptree[unit]; + struct pipe_texture *pt = &nv04mt->base; + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 3); + OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[unit]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); + OUT_RING(nv04->sampler[unit]->filter); +} + +void +nv04_emit_hw_state(struct nv04_context *nv04) +{ + int i; + + if (nv04->dirty & NV04_NEW_VERTPROG) { + //nv04_vertprog_bind(nv04, nv04->vertprog.current); + nv04->dirty &= ~NV04_NEW_VERTPROG; + } + + if (nv04->dirty & NV04_NEW_FRAGPROG) { + nv04_fragprog_bind(nv04, nv04->fragprog.current); + /*XXX: clear NV04_NEW_FRAGPROG if no new program uploaded */ + nv04->dirty_samplers |= (1<<10); + nv04->dirty_samplers = 0; + } + + if (nv04->dirty & NV04_NEW_CONTROL) { + nv04->dirty &= ~NV04_NEW_CONTROL; + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING(nv04->dsa->control); + } + + if (nv04->dirty & NV04_NEW_BLEND) { + nv04->dirty &= ~NV04_NEW_BLEND; + + nv04_emit_blend(nv04); + } + + if (nv04->dirty & NV04_NEW_SAMPLER) { + nv04->dirty &= ~NV04_NEW_SAMPLER; + + nv04_emit_sampler(nv04, 0); + } + + if (nv04->dirty & NV04_NEW_VIEWPORT) { + nv04->dirty &= ~NV04_NEW_VIEWPORT; +// nv04_state_emit_viewport(nv04); + } + + /* 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 nv04_vbo.c + */ + + /* Render target */ +/* BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2); + OUT_RING(rt->stride|(zeta->stride<<16)); + OUT_RELOCl(rt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + if (fb->zsbuf) { + BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); + OUT_RELOCl(zeta->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + }*/ + + /* Texture images */ + for (i = 0; i < 1; i++) { + if (!(nv04->fp_samplers & (1 << i))) + continue; + struct nv04_miptree *nv04mt = nv04->tex_miptree[i]; + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 2); + OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[i]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); + } +} + diff --git a/src/gallium/drivers/nv04/nv04_surface.c b/src/gallium/drivers/nv04/nv04_surface.c new file mode 100644 index 0000000000..b13ebf9f9b --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_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 "nv04_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 +nv04_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 nv04_context *nv04 = nv04_context(pipe); + struct nouveau_winsys *nvws = nv04->nvws; + + nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, + width, height); +} + +static void +nv04_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, + unsigned destx, unsigned desty, unsigned width, + unsigned height, unsigned value) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct nouveau_winsys *nvws = nv04->nvws; + + nvws->surface_fill(nvws, dest, destx, desty, width, height, value); +} + +void +nv04_init_surface_functions(struct nv04_context *nv04) +{ + nv04->pipe.surface_copy = nv04_surface_copy; + nv04->pipe.surface_fill = nv04_surface_fill; +} diff --git a/src/gallium/drivers/nv04/nv04_vbo.c b/src/gallium/drivers/nv04/nv04_vbo.c new file mode 100644 index 0000000000..fbfe0cf406 --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_vbo.c @@ -0,0 +1,72 @@ +#include "draw/draw_context.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "nv04_context.h" +#include "nv04_state.h" + +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_pushbuf.h" + +boolean nv04_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned prim, unsigned start, unsigned count) +{ + struct nv04_context *nv04 = nv04_context( pipe ); + struct draw_context *draw = nv04->draw; + unsigned i; + + /* + * Map vertex buffers + */ + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { + if (nv04->vertex_buffer[i].buffer) { + void *buf + = pipe->winsys->buffer_map(pipe->winsys, + nv04->vertex_buffer[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! */ + draw_arrays(nv04->draw, prim, start, count); + + /* + * unmap vertex/index buffers + */ + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { + if (nv04->vertex_buffer[i].buffer) { + pipe->winsys->buffer_unmap(pipe->winsys, nv04->vertex_buffer[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 nv04_draw_arrays( struct pipe_context *pipe, + unsigned prim, unsigned start, unsigned count) +{ + return nv04_draw_elements(pipe, NULL, 0, prim, start, count); +} + + + -- cgit v1.2.3 From 97646f10459dd743d9bfd091aec27b28b24222f2 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 8 Jul 2008 01:30:48 +0200 Subject: nv04: use BEGIN_RING_NI --- src/gallium/drivers/nv04/nv04_prim_vbuf.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv04/nv04_prim_vbuf.c b/src/gallium/drivers/nv04/nv04_prim_vbuf.c index daf28e81f5..80a4dbc311 100644 --- a/src/gallium/drivers/nv04/nv04_prim_vbuf.c +++ b/src/gallium/drivers/nv04/nv04_prim_vbuf.c @@ -1,8 +1,4 @@ -// XXX this has to go somewhere else -#define NONINC_METHOD 0x40000000 - - #include "draw/draw_vbuf.h" #include "pipe/p_debug.h" #include "pipe/p_util.h" @@ -160,7 +156,7 @@ static void nv04_vbuf_render_tri_strip_elts(struct nv04_vbuf_render* render, con for(j = 0; j Date: Tue, 8 Jul 2008 01:32:32 +0200 Subject: nv04: Hook the lib into the build. --- src/gallium/winsys/dri/nouveau/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/Makefile b/src/gallium/winsys/dri/nouveau/Makefile index f637b2cebf..be630ff6d1 100644 --- a/src/gallium/winsys/dri/nouveau/Makefile +++ b/src/gallium/winsys/dri/nouveau/Makefile @@ -8,6 +8,7 @@ MINIGLX_SOURCES = PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/nv04/libnv04.a \ $(TOP)/src/gallium/drivers/nv10/libnv10.a \ $(TOP)/src/gallium/drivers/nv30/libnv30.a \ $(TOP)/src/gallium/drivers/nv40/libnv40.a \ -- cgit v1.2.3 From 205101dafb0042ebeeab3dd50f549d8a3d3c08ce Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 8 Jul 2008 01:34:36 +0200 Subject: nv10: there are no 3D textures. --- src/gallium/drivers/nv10/nv10_miptree.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c index f1486a35df..9a68df2925 100644 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -11,7 +11,7 @@ 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 width = pt->width[0], height = pt->height[0]; uint offset = 0; int nr_faces, l, f; @@ -24,7 +24,6 @@ nv10_miptree_layout(struct nv10_miptree *nv10mt) for (l = 0; l <= pt->last_level; l++) { pt->width[l] = width; pt->height[l] = height; - pt->depth[l] = depth; pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); @@ -39,7 +38,6 @@ nv10_miptree_layout(struct nv10_miptree *nv10mt) width = MAX2(1, width >> 1); height = MAX2(1, height >> 1); - depth = MAX2(1, depth >> 1); } -- cgit v1.2.3 From 06d87b44cffef9e335b9a0e70fd2aec61fcd171b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 8 Jul 2008 12:51:29 +1000 Subject: nv50: make use of nouveau drm 0.0.11 to get 3d going --- src/gallium/drivers/nouveau/nouveau_bo.h | 2 + src/gallium/drivers/nouveau/nouveau_stateobj.h | 3 + src/gallium/drivers/nv50/nv50_state_validate.c | 6 +- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 16 +++ src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 1 + src/gallium/winsys/dri/nouveau/nouveau_screen.c | 2 +- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 12 ++ src/gallium/winsys/dri/nouveau/nv50_surface.c | 158 +++++++++++---------- 8 files changed, 120 insertions(+), 80 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_bo.h b/src/gallium/drivers/nouveau/nouveau_bo.h index 18020e9c65..65b138283c 100644 --- a/src/gallium/drivers/nouveau/nouveau_bo.h +++ b/src/gallium/drivers/nouveau/nouveau_bo.h @@ -35,6 +35,8 @@ #define NOUVEAU_BO_HIGH (1 << 7) #define NOUVEAU_BO_OR (1 << 8) #define NOUVEAU_BO_LOCAL (1 << 9) +#define NOUVEAU_BO_TILED (1 << 10) +#define NOUVEAU_BO_ZTILE (1 << 11) #define NOUVEAU_BO_DUMMY (1 << 31) struct nouveau_bo { diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index 78b2738070..998ec2d4ad 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -136,6 +136,9 @@ so_emit_reloc_markers(struct nouveau_winsys *nvws, struct nouveau_stateobj *so) struct nouveau_pushbuf *pb = nvws->channel->pushbuf; unsigned i; + if (!so) + return; + i = so->cur_reloc << 1; if (nvws->channel->pushbuf->remaining < i) nvws->push_flush(nvws, i, NULL); diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index cf5a071a8d..88ef685bb1 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -44,7 +44,7 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_data(so, 0xe6); break; } - so_data(so, 0x00000040); + so_data(so, 0x00000000); so_data(so, 0x00000000); so_method(so, tesla, 0x1224, 1); @@ -82,7 +82,7 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_data(so, 0x16); break; } - so_data(so, 0x00000040); + so_data(so, 0x00000000); so_data(so, 0x00000000); so_method(so, tesla, 0x1538, 1); @@ -265,7 +265,7 @@ scissor_uptodate: so_data (so, 0x2a712488); so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0xd0c05000); + so_data (so, 0xd0005000); so_data (so, 0x00300000); so_data (so, mt->base.width[0]); so_data (so, (mt->base.depth[0] << 16) | diff --git a/src/gallium/winsys/dri/nouveau/nouveau_bo.c b/src/gallium/winsys/dri/nouveau/nouveau_bo.c index 57f5b7d1ae..b5942994d9 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_bo.c @@ -182,6 +182,13 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, nvbo->drm.alignment = align; nvbo->refcount = 1; + if (flags & NOUVEAU_BO_TILED) { + nvbo->tiled = 1; + if (flags & NOUVEAU_BO_ZTILE) + nvbo->tiled |= 2; + flags &= ~NOUVEAU_BO_TILED; + } + ret = nouveau_bo_set_status(&nvbo->base, flags); if (ret) { free(nvbo); @@ -332,6 +339,12 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) else if (flags & NOUVEAU_BO_GART) new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); + + if (nvbo->tiled && flags) { + new_flags |= NOUVEAU_MEM_TILE; + if (nvbo->tiled & 2) + new_flags |= NOUVEAU_MEM_TILE_ZETA; + } if (new_flags) { ret = nouveau_mem_alloc(bo->device, bo->size, @@ -347,9 +360,12 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags) /* Copy old -> new */ /*XXX: use M2MF */ if (nvbo->sysmem || nvbo->map) { + struct nouveau_pushbuf_bo *pbo = nvbo->pending; + nvbo->pending = NULL; nouveau_bo_map(bo, NOUVEAU_BO_RD); memcpy(new_map, bo->map, bo->size); nouveau_bo_unmap(bo); + nvbo->pending = pbo; } /* Free old memory */ diff --git a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h index 5829f649cd..dcd6a5eb0a 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/dri/nouveau/nouveau_drmif.h @@ -259,6 +259,7 @@ struct nouveau_bo_priv { uint64_t offset; uint64_t flags; + int tiled; }; #define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) diff --git a/src/gallium/winsys/dri/nouveau/nouveau_screen.c b/src/gallium/winsys/dri/nouveau/nouveau_screen.c index b15ee7509c..df1fe7e69b 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_screen.c @@ -13,7 +13,7 @@ #include "nouveau_screen.h" #include "nouveau_swapbuffers.h" -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 #error nouveau_drm.h version does not match expected version #endif diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index ba5dd2eea4..765ea36f88 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -76,6 +76,18 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment, if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE) flags |= NOUVEAU_BO_GART; flags |= NOUVEAU_BO_VRAM; + + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + flags |= NOUVEAU_BO_TILED; + if (usage & NOUVEAU_BUFFER_USAGE_ZETA) + flags |= NOUVEAU_BO_ZTILE; + break; + default: + break; + } } if (usage & PIPE_BUFFER_USAGE_VERTEX) { diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c index cf76d76cf5..c8ab7f690f 100644 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c @@ -22,52 +22,70 @@ nv50_format(enum pipe_format format) } static int -nv50_surface_copy_prep(struct nouveau_context *nv, - struct pipe_surface *dst, struct pipe_surface *src) +nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) { struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - int surf_format; - - assert(src->format == dst->format); + struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; + int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; + int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); + + surf_format = nv50_format(surf->format); + if (surf_format < 0) + return 1; + + if (!nouveau_bo(bo)->tiled) { + BEGIN_RING(chan, eng2d, mthd, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, mthd + 0x14, 5); + OUT_RING (chan, surf->stride); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } else { + BEGIN_RING(chan, eng2d, mthd, 5); + OUT_RING (chan, surf_format); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, mthd + 0x18, 4); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } + +#if 0 + if (dst) { + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + } +#endif + + return 0; +} - surf_format = nv50_format(dst->format); - assert(surf_format >= 0); +static int +nv50_surface_copy_prep(struct nouveau_context *nv, + struct pipe_surface *dst, struct pipe_surface *src) +{ + int ret; - 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); + assert(src->format == dst->format); - 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->stride); - OUT_RING (chan, dst->width); - 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->width); - OUT_RING (chan, dst->height); + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; - 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->stride); - OUT_RING (chan, src->width); - 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); + ret = nv50_surface_set(nv, src, 0); + if (ret) + return ret; return 0; } @@ -79,17 +97,19 @@ nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - BEGIN_RING(chan, eng2d, 0x0110, 1); + BEGIN_RING(chan, eng2d, 0x088c, 1); OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12); + BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); OUT_RING (chan, dx); OUT_RING (chan, dy); OUT_RING (chan, w); OUT_RING (chan, h); + BEGIN_RING(chan, eng2d, 0x08c0, 4); OUT_RING (chan, 0); OUT_RING (chan, 1); OUT_RING (chan, 0); OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, 0x08d0, 4); OUT_RING (chan, 0); OUT_RING (chan, sx); OUT_RING (chan, 0); @@ -109,35 +129,15 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, { struct nouveau_channel *chan = nv->nvc->channel; struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - int surf_format, rect_format; - - surf_format = nv50_format(dst->format); - if (surf_format < 0) - return 1; + int rect_format, ret; rect_format = nv50_format(dst->format); 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->stride); - OUT_RING (chan, dst->width); - 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->width); - OUT_RING (chan, dst->height); + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; BEGIN_RING(chan, eng2d, 0x0580, 3); OUT_RING (chan, 4); @@ -151,27 +151,33 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, OUT_RING (chan, dy + h); FIRE_RING(chan); - return 0; } int nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc) { + struct nouveau_channel *chan = nvc->channel; + struct nouveau_grobj *eng2d = NULL; int ret; - ret = nouveau_grobj_alloc(nvc->channel, nvc->next_handle++, NV50_2D, - &nvc->Nv2D); + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d); 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); + nvc->Nv2D = eng2d; + + BIND_RING (chan, eng2d, nvc->next_subchannel++); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); + OUT_RING (chan, nvc->sync_notifier->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); + OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); + BEGIN_RING(chan, eng2d, 0x0290, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, 0x0888, 1); + OUT_RING (chan, 1); return 0; } -- cgit v1.2.3 From 28268f7b22905974a2cc3c099b1a842d20a7712a Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 8 Jul 2008 16:38:27 +0200 Subject: nv30: use native instructions. --- src/gallium/drivers/nv30/nv30_fragprog.c | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 54d6bea55f..740d3ab430 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -510,9 +510,7 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc, 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); + arith(fpc, sat, LRP, dst, mask, src[0], src[1], src[2]); break; case TGSI_OPCODE_MAD: arith(fpc, sat, MAD, dst, mask, src[0], src[1], src[2]); @@ -530,13 +528,7 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc, 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); + arith(fpc, sat, POW, dst, mask, src[0], src[1], none); break; case TGSI_OPCODE_RCP: arith(fpc, sat, RCP, dst, mask, src[0], none, none); @@ -545,20 +537,10 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc, 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])); + arith(fpc, 0, RFL, dst, mask, src[0], src[1], none); 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); + arith(fpc, sat, RSQ, dst, mask, abs(swz(src[0], X, X, X, X)), none, none); break; case TGSI_OPCODE_SCS: if (mask & MASK_X) { -- cgit v1.2.3 From 511693d00c5f8641375efd16e08289586d62e562 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 8 Jul 2008 20:06:57 +0200 Subject: nv04: use FREE/MALLOC like a good gallium boy should. --- src/gallium/drivers/nv04/nv04_miptree.c | 6 +++--- src/gallium/drivers/nv04/nv04_prim_vbuf.c | 2 +- src/gallium/drivers/nv04/nv04_state.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c index ab2d2386be..97f679731e 100644 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -62,7 +62,7 @@ nv04_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, mt->total_size); if (!mt->buffer) { - free(mt); + FREE(mt); return NULL; } @@ -83,9 +83,9 @@ nv04_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) pipe_buffer_reference(ws, &nv04mt->buffer, NULL); for (l = 0; l <= mt->last_level; l++) { if (nv04mt->level[l].image_offset) - free(nv04mt->level[l].image_offset); + FREE(nv04mt->level[l].image_offset); } - free(nv04mt); + FREE(nv04mt); } } diff --git a/src/gallium/drivers/nv04/nv04_prim_vbuf.c b/src/gallium/drivers/nv04/nv04_prim_vbuf.c index 80a4dbc311..d3963d1f59 100644 --- a/src/gallium/drivers/nv04/nv04_prim_vbuf.c +++ b/src/gallium/drivers/nv04/nv04_prim_vbuf.c @@ -57,7 +57,7 @@ nv04_vbuf_render_allocate_vertices( struct vbuf_render *render, { struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); - nv04_render->buffer = (unsigned char*) malloc(VERTEX_BUFFER_SIZE); + nv04_render->buffer = (unsigned char*) MALLOC(VERTEX_BUFFER_SIZE); assert(!nv04_render->buffer); return nv04_render->buffer; diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c index 39d7e8b42d..d618465a20 100644 --- a/src/gallium/drivers/nv04/nv04_state.c +++ b/src/gallium/drivers/nv04/nv04_state.c @@ -14,7 +14,7 @@ nv04_blend_state_create(struct pipe_context *pipe, { struct nv04_blend_state *cb; - cb = malloc(sizeof(struct nv04_blend_state)); + cb = MALLOC(sizeof(struct nv04_blend_state)); cb->b_enable = cso->blend_enable ? 1 : 0; cb->b_src = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | @@ -81,7 +81,7 @@ nv04_sampler_state_create(struct pipe_context *pipe, struct nv04_sampler_state *ss; uint32_t filter = 0; - ss = malloc(sizeof(struct nv04_sampler_state)); + ss = MALLOC(sizeof(struct nv04_sampler_state)); ss->format = ((wrap_mode(cso->wrap_s) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT) | (wrap_mode(cso->wrap_t) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT)); @@ -178,7 +178,7 @@ nv04_rasterizer_state_create(struct pipe_context *pipe, * scissor * points/lines (no hw support, emulated with tris in gallium) */ - rs = malloc(sizeof(struct nv04_rasterizer_state)); + rs = MALLOC(sizeof(struct nv04_rasterizer_state)); rs->blend = cso->flatshade ? NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT : NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; @@ -225,7 +225,7 @@ nv04_depth_stencil_alpha_state_create(struct pipe_context *pipe, { struct nv04_depth_stencil_alpha_state *hw; - hw = malloc(sizeof(struct nv04_depth_stencil_alpha_state)); + hw = MALLOC(sizeof(struct nv04_depth_stencil_alpha_state)); hw->control = float_to_ubyte(cso->alpha.ref); hw->control |= ( nv04_compare_func(cso->alpha.func) << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT ); -- cgit v1.2.3 From a62a738f3df054ef802f9ea7bc778d468fd0a4ba Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 8 Jul 2008 20:26:04 +0200 Subject: nv10: use the gallium alloc/free wrappers. --- src/gallium/drivers/nv10/nv10_state.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 11664fae2a..9b8b7801cd 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -14,7 +14,7 @@ nv10_blend_state_create(struct pipe_context *pipe, { struct nv10_blend_state *cb; - cb = malloc(sizeof(struct nv10_blend_state)); + 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) | @@ -88,7 +88,7 @@ nv10_sampler_state_create(struct pipe_context *pipe, struct nv10_sampler_state *ps; uint32_t filter = 0; - ps = malloc(sizeof(struct nv10_sampler_state)); + 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)); @@ -249,7 +249,7 @@ nv10_rasterizer_state_create(struct pipe_context *pipe, * multisample * offset_units / offset_scale */ - rs = malloc(sizeof(struct nv10_rasterizer_state)); + rs = MALLOC(sizeof(struct nv10_rasterizer_state)); rs->templ = cso; @@ -335,7 +335,7 @@ nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe, { struct nv10_depth_stencil_alpha_state *hw; - hw = malloc(sizeof(struct nv10_depth_stencil_alpha_state)); + 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; -- cgit v1.2.3 From 456550293a50d72c02ed5ec930c12899e7458a6f Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 9 Jul 2008 21:51:22 +0200 Subject: nv30: update nouveau_class.h --- src/gallium/drivers/nouveau/nouveau_class.h | 61 ++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index 3c29fa0d1b..4ec5062709 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -3759,8 +3759,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 @@ -3876,6 +3874,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_COLOR_B_SHIFT 0 +#define NV34TCL_BLEND_COLOR_B_MASK 0x000000ff +#define NV34TCL_BLEND_COLOR_G_SHIFT 8 +#define NV34TCL_BLEND_COLOR_G_MASK 0x0000ff00 +#define NV34TCL_BLEND_COLOR_R_SHIFT 16 +#define NV34TCL_BLEND_COLOR_R_MASK 0x00ff0000 +#define NV34TCL_BLEND_COLOR_A_SHIFT 24 +#define NV34TCL_BLEND_COLOR_A_MASK 0xff000000 #define NV34TCL_BLEND_EQUATION 0x00000320 #define NV34TCL_BLEND_EQUATION_FUNC_ADD 0x00008006 #define NV34TCL_BLEND_EQUATION_MIN 0x00008007 @@ -4338,6 +4344,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV34TCL_FRONT_FACE_CCW 0x00000901 #define NV34TCL_POLYGON_SMOOTH_ENABLE 0x00001838 #define NV34TCL_CULL_FACE_ENABLE 0x0000183c +#define NV34TCL_TX_PALETTE_OFFSET(x) (0x00001840+((x)*4)) +#define NV34TCL_TX_PALETTE_OFFSET__SIZE 0x00000004 #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)) @@ -4376,7 +4384,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_CUBIC (1 << 2) +#define NV34TCL_TX_FORMAT_NO_BORDER (1 << 3) #define NV34TCL_TX_FORMAT_DIMS_SHIFT 4 #define NV34TCL_TX_FORMAT_DIMS_MASK 0x000000f0 #define NV34TCL_TX_FORMAT_DIMS_1D 0x00000010 @@ -4389,6 +4398,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_R5G6B5 0x00000500 #define NV34TCL_TX_FORMAT_FORMAT_A8R8G8B8 0x00000600 #define NV34TCL_TX_FORMAT_FORMAT_X8R8G8B8 0x00000700 #define NV34TCL_TX_FORMAT_FORMAT_INDEX8 0x00000b00 @@ -4396,22 +4406,26 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_R5G6B5_RECT 0x00001100 #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_R8G8B8_RECT 0x00001e00 #define NV34TCL_TX_FORMAT_FORMAT_L8A8_RECT 0x00002000 #define NV34TCL_TX_FORMAT_FORMAT_A16 0x00003200 +#define NV34TCL_TX_FORMAT_FORMAT_HILO16 0x00003300 #define NV34TCL_TX_FORMAT_FORMAT_A16_RECT 0x00003500 +#define NV34TCL_TX_FORMAT_FORMAT_HILO16_RECT 0x00003600 +#define NV34TCL_TX_FORMAT_FORMAT_HILO8 0x00004400 +#define NV34TCL_TX_FORMAT_FORMAT_SIGNED_HILO8 0x00004500 +#define NV34TCL_TX_FORMAT_FORMAT_HILO8_RECT 0x00004600 +#define NV34TCL_TX_FORMAT_FORMAT_SIGNED_HILO8_RECT 0x00004700 #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_MIPMAP (1 << 19) #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 @@ -4428,12 +4442,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_MASK 0x00000f00 #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_EXPAND_NORMAL_SHIFT 12 +#define NV34TCL_TX_WRAP_EXPAND_NORMAL_MASK 0x0000f000 #define NV34TCL_TX_WRAP_R_SHIFT 16 #define NV34TCL_TX_WRAP_R_MASK 0x00ff0000 #define NV34TCL_TX_WRAP_R_REPEAT 0x00010000 @@ -4441,8 +4457,28 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_WRAP_RCOMP_SHIFT 28 +#define NV34TCL_TX_WRAP_RCOMP_MASK 0xf0000000 +#define NV34TCL_TX_WRAP_RCOMP_NEVER 0x00000000 +#define NV34TCL_TX_WRAP_RCOMP_GREATER 0x10000000 +#define NV34TCL_TX_WRAP_RCOMP_EQUAL 0x20000000 +#define NV34TCL_TX_WRAP_RCOMP_GEQUAL 0x30000000 +#define NV34TCL_TX_WRAP_RCOMP_LESS 0x40000000 +#define NV34TCL_TX_WRAP_RCOMP_NOTEQUAL 0x50000000 +#define NV34TCL_TX_WRAP_RCOMP_LEQUAL 0x60000000 +#define NV34TCL_TX_WRAP_RCOMP_ALWAYS 0x70000000 #define NV34TCL_TX_ENABLE(x) (0x00001a0c+((x)*32)) #define NV34TCL_TX_ENABLE__SIZE 0x00000004 +#define NV34TCL_TX_ENABLE_ANISO_SHIFT 4 +#define NV34TCL_TX_ENABLE_ANISO_MASK 0x00000030 +#define NV34TCL_TX_ENABLE_ANISO_NONE 0x00000000 +#define NV34TCL_TX_ENABLE_ANISO_2X 0x00000010 +#define NV34TCL_TX_ENABLE_ANISO_4X 0x00000020 +#define NV34TCL_TX_ENABLE_ANISO_8X 0x00000030 +#define NV34TCL_TX_ENABLE_MIPMAP_MAX_LOD_SHIFT 14 +#define NV34TCL_TX_ENABLE_MIPMAP_MAX_LOD_MASK 0x0003c000 +#define NV34TCL_TX_ENABLE_MIPMAP_MIN_LOD_SHIFT 26 +#define NV34TCL_TX_ENABLE_MIPMAP_MIN_LOD_MASK 0x3c000000 #define NV34TCL_TX_ENABLE_ENABLE (1 << 30) #define NV34TCL_TX_SWIZZLE(x) (0x00001a10+((x)*32)) #define NV34TCL_TX_SWIZZLE__SIZE 0x00000004 @@ -4494,6 +4530,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_LOD_BIAS_SHIFT 8 +#define NV34TCL_TX_FILTER_LOD_BIAS_MASK 0x00000f00 #define NV34TCL_TX_FILTER_MINIFY_SHIFT 16 #define NV34TCL_TX_FILTER_MINIFY_MASK 0x000f0000 #define NV34TCL_TX_FILTER_MINIFY_NEAREST 0x00010000 @@ -4539,6 +4577,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_MULTISAMPLE_CONTROL_ENABLE (1 << 0) +#define NV34TCL_MULTISAMPLE_CONTROL_SAMPLE_ALPHA_TO_COVERAGE (1 << 4) +#define NV34TCL_MULTISAMPLE_CONTROL_SAMPLE_ALPHA_TO_ONE (1 << 8) +#define NV34TCL_MULTISAMPLE_CONTROL_SAMPLE_COVERAGE_SHIFT 16 +#define NV34TCL_MULTISAMPLE_CONTROL_SAMPLE_COVERAGE_MASK 0xffff0000 #define NV34TCL_CLEAR_DEPTH_VALUE 0x00001d8c #define NV34TCL_CLEAR_COLOR_VALUE 0x00001d90 #define NV34TCL_CLEAR_COLOR_VALUE_B_SHIFT 0 -- cgit v1.2.3 From 7a838ef411d2f4716bdcbcad9f593541c43a2ce7 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 9 Jul 2008 22:03:59 +0200 Subject: nv30: Update defines from nouveau_class.h --- src/gallium/drivers/nv30/nv30_state.c | 46 ++++++++++++++--------------------- 1 file changed, 18 insertions(+), 28 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 97becd2be3..72b9515eb1 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -120,38 +120,28 @@ nv30_sampler_state_create(struct pipe_context *pipe, ps = MALLOC(sizeof(struct nv30_sampler_state)); ps->fmt = 0; + /* TODO: Not all RECTs formats have this bit set, bits 15-8 of format + are the tx format to use. We should store normalized coord flag + in sampler state structure, and set appropriate format in + nvxx_fragtex_build() + */ if (!cso->normalized_coords) - ps->fmt |= NV34TCL_TX_FORMAT_RECT; + ps->fmt |= (1<<14) /*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 >= 8.0) { + ps->en |= NV34TCL_TX_ENABLE_ANISO_8X; + } else + if (cso->max_anisotropy >= 4.0) { + ps->en |= NV34TCL_TX_ENABLE_ANISO_4X; + } else 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; - }*/ + ps->en |= NV34TCL_TX_ENABLE_ANISO_2X; } switch (cso->mag_img_filter) { @@ -198,7 +188,7 @@ nv30_sampler_state_create(struct pipe_context *pipe, ps->filt = filter; - /*{ + { float limit; limit = CLAMP(cso->lod_bias, -16.0, 15.0); @@ -209,9 +199,9 @@ nv30_sampler_state_create(struct pipe_context *pipe, 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) { + 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; @@ -240,7 +230,7 @@ nv30_sampler_state_create(struct pipe_context *pipe, default: break; } - }*/ + } ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) | (float_to_ubyte(cso->border_color[0]) << 16) | -- cgit v1.2.3 From 2fed964a27f208f69edc0b2d9a2d0b0717184ee5 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 9 Jul 2008 22:13:01 +0200 Subject: nv30: Update defines from nouveau_class.h --- src/gallium/drivers/nv30/nv30_fragtex.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index 47f3ff047d..92b3f93929 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -87,6 +87,7 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) struct nv30_texture_format *tf; 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 = nv30_fragtex_format(pt->format); if (!tf || !tf->defined) { @@ -99,20 +100,20 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) txf |= log2i(pt->width[0]) << 20; txf |= log2i(pt->height[0]) << 24; txf |= log2i(pt->depth[0]) << 28; - txf |= 8; + txf |= NV34TCL_TX_FORMAT_NO_BORDER; switch (pt->target) { -/* case PIPE_TEXTURE_CUBE: - txf |= NV34TCL_TEX_FORMAT_CUBIC;*/ + case PIPE_TEXTURE_CUBE: + txf |= NV34TCL_TX_FORMAT_CUBIC; /* fall-through */ case PIPE_TEXTURE_2D: - txf |= (2<<4); + txf |= NV34TCL_TX_FORMAT_DIMS_2D; break; case PIPE_TEXTURE_3D: - txf |= (3<<4); + txf |= NV34TCL_TX_FORMAT_DIMS_3D; break; case PIPE_TEXTURE_1D: - txf |= (1<<4); + txf |= NV34TCL_TX_FORMAT_DIMS_1D; break; default: NOUVEAU_ERR("Unknown target %d\n", pt->target); @@ -122,13 +123,13 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) 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_RELOCl(nv30mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW); + OUT_RELOCd(nv30mt->buffer,txf, tex_flags | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); OUT_RING (ps->wrap); - OUT_RING (0x40000000); /* enable */ + OUT_RING (NV34TCL_TX_ENABLE_ENABLE | ps->en); OUT_RING (txs); OUT_RING (ps->filt | 0x2000 /* magic */); - OUT_RING ((pt->width[0] << 16) | pt->height[0]); + OUT_RING ((pt->width[0] << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pt->height[0]); OUT_RING (ps->bcol); } -- cgit v1.2.3 From 225863aeb5f2dfe4980ae5887f5623ecb05e9ced Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 9 Jul 2008 23:23:39 +0200 Subject: nv30: min/max lod are used for mipmap, there is just enable bit in tx_format --- src/gallium/drivers/nv30/nv30_fragtex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index 92b3f93929..f253087c88 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -96,11 +96,11 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) } txf = tf->format << 8; - txf |= (pt->last_level + 1) << 16; + txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0); txf |= log2i(pt->width[0]) << 20; txf |= log2i(pt->height[0]) << 24; txf |= log2i(pt->depth[0]) << 28; - txf |= NV34TCL_TX_FORMAT_NO_BORDER; + txf |= NV34TCL_TX_FORMAT_NO_BORDER | 0x10000; switch (pt->target) { case PIPE_TEXTURE_CUBE: -- cgit v1.2.3 From 861629d1fd4a1d256c913470c33d9522e83d615d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 00:15:01 +1000 Subject: nv50: more "abuse" by using libc malloc etc.. --- src/gallium/drivers/nv50/nv50_context.c | 2 +- src/gallium/drivers/nv50/nv50_draw.c | 2 +- src/gallium/drivers/nv50/nv50_program.c | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index a225c4bf72..2494784a94 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -21,7 +21,7 @@ nv50_destroy(struct pipe_context *pipe) struct nv50_context *nv50 = (struct nv50_context *)pipe; draw_destroy(nv50->draw); - free(nv50); + FREE(nv50); } diff --git a/src/gallium/drivers/nv50/nv50_draw.c b/src/gallium/drivers/nv50/nv50_draw.c index d185d99950..2b0c0384a3 100644 --- a/src/gallium/drivers/nv50/nv50_draw.c +++ b/src/gallium/drivers/nv50/nv50_draw.c @@ -46,7 +46,7 @@ nv50_render_reset_stipple_counter(struct draw_stage *stage) static void nv50_render_destroy(struct draw_stage *stage) { - free(stage); + FREE(stage); } struct draw_stage * diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index cd6967b366..ff81719f03 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -180,8 +180,8 @@ kill_temp_temp(struct nv50_pc *pc) static int ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w) { - pc->immd_buf = realloc(pc->immd_buf, (pc->immd_nr + 1) * 4 * - sizeof(float)); + pc->immd_buf = REALLOC(pc->immd_buf, (pc->immd_nr * r * sizeof(float)), + (pc->immd_nr + 1) * 4 * sizeof(float)); pc->immd_buf[(pc->immd_nr * 4) + 0] = x; pc->immd_buf[(pc->immd_nr * 4) + 1] = y; pc->immd_buf[(pc->immd_nr * 4) + 2] = z; @@ -1276,7 +1276,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) } if (pc->temp_nr) { - pc->temp = calloc(pc->temp_nr * 4, sizeof(struct nv50_reg)); + pc->temp = CALLOC(pc->temp_nr * 4, sizeof(struct nv50_reg)); if (!pc->temp) goto out_err; @@ -1293,7 +1293,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) struct nv50_reg *iv = NULL; int aid = 0; - pc->attr = calloc(pc->attr_nr * 4, sizeof(struct nv50_reg)); + pc->attr = CALLOC(pc->attr_nr * 4, sizeof(struct nv50_reg)); if (!pc->attr) goto out_err; @@ -1339,7 +1339,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (pc->result_nr) { int rid = 0; - pc->result = calloc(pc->result_nr * 4, sizeof(struct nv50_reg)); + pc->result = CALLOC(pc->result_nr * 4, sizeof(struct nv50_reg)); if (!pc->result) goto out_err; @@ -1360,7 +1360,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (pc->param_nr) { int rid = 0; - pc->param = calloc(pc->param_nr * 4, sizeof(struct nv50_reg)); + pc->param = CALLOC(pc->param_nr * 4, sizeof(struct nv50_reg)); if (!pc->param) goto out_err; @@ -1376,7 +1376,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (pc->immd_nr) { int rid = pc->param_nr * 4; - pc->immd = calloc(pc->immd_nr * 4, sizeof(struct nv50_reg)); + pc->immd = CALLOC(pc->immd_nr * 4, sizeof(struct nv50_reg)); if (!pc->immd) goto out_err; -- cgit v1.2.3 From add89c78455f04654c3706d46e3d3e6b92b73b71 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 00:21:42 +1000 Subject: nouveau: update to latest object header --- src/gallium/drivers/nouveau/nouveau_class.h | 52 +++++++++++++++++++++-------- src/gallium/drivers/nv50/nv50_screen.c | 12 +++---- 2 files changed, 44 insertions(+), 20 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index 4ec5062709..18d8d3677d 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -1798,6 +1798,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_R5G6B5 0x00000280 #define NV10TCL_TX_FORMAT_FORMAT_A8R8G8B8 0x00000300 #define NV10TCL_TX_FORMAT_FORMAT_X8R8G8B8 0x00000380 #define NV10TCL_TX_FORMAT_FORMAT_INDEX8 0x00000580 @@ -1805,15 +1806,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_R5G6B5_RECT 0x00000880 #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_R8G8B8_RECT 0x00000f00 #define NV10TCL_TX_FORMAT_FORMAT_L8A8_RECT 0x00001000 #define NV10TCL_TX_FORMAT_FORMAT_A16 0x00001900 +#define NV10TCL_TX_FORMAT_FORMAT_HILO16 0x00001980 #define NV10TCL_TX_FORMAT_FORMAT_A16_RECT 0x00001a80 +#define NV10TCL_TX_FORMAT_FORMAT_HILO16_RECT 0x00001b00 +#define NV10TCL_TX_FORMAT_FORMAT_HILO8 0x00002200 +#define NV10TCL_TX_FORMAT_FORMAT_SIGNED_HILO8 0x00002280 +#define NV10TCL_TX_FORMAT_FORMAT_HILO8_RECT 0x00002300 +#define NV10TCL_TX_FORMAT_FORMAT_SIGNED_HILO8_RECT 0x00002380 #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 @@ -5486,18 +5494,23 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_DMA_UNK0(x) (0x00000184+((x)*4)) +#define NV50TCL_DMA_UNK0__SIZE 0x0000000b +#define NV50TCL_DMA_UNK1(x) (0x000001c0+((x)*4)) +#define NV50TCL_DMA_UNK1__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_FORMAT_32BPP 0x000000cf +#define NV50TCL_RT_FORMAT_24BPP 0x000000e6 +#define NV50TCL_RT_FORMAT_16BPP 0x000000e8 +#define NV50TCL_RT_FORMAT_8BPP 0x000000f3 +#define NV50TCL_RT_FORMAT_15BPP 0x000000f8 +#define NV50TCL_RT_TILE_UNK(x) (0x0000020c+((x)*32)) +#define NV50TCL_RT_TILE_UNK__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)) @@ -5602,9 +5615,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_CB_ADDR 0x00000f00 +#define NV50TCL_CB_ADDR_ID_SHIFT 8 +#define NV50TCL_CB_ADDR_ID_MASK 0xffffff00 +#define NV50TCL_CB_ADDR_BUFFER_SHIFT 0 +#define NV50TCL_CB_ADDR_BUFFER_MASK 0x000000ff +#define NV50TCL_CB_DATA(x) (0x00000f04+((x)*4)) +#define NV50TCL_CB_DATA__SIZE 0x00000010 #define NV50TCL_STENCIL_FRONT_FUNC_REF 0x00000f54 #define NV50TCL_STENCIL_FRONT_MASK 0x00000f58 #define NV50TCL_STENCIL_FRONT_FUNC_MASK 0x00000f5c @@ -5626,6 +5643,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50TCL_RT_HORIZ__SIZE 0x00000008 #define NV50TCL_RT_VERT(x) (0x00001244+((x)*8)) #define NV50TCL_RT_VERT__SIZE 0x00000008 +#define NV50TCL_CB_DEF_ADDRESS_HIGH 0x00001280 +#define NV50TCL_CB_DEF_ADDRESS_LOW 0x00001284 +#define NV50TCL_CB_DEF_SET 0x00001288 +#define NV50TCL_CB_DEF_SET_SIZE_SHIFT 0 +#define NV50TCL_CB_DEF_SET_SIZE_MASK 0x0000ffff +#define NV50TCL_CB_DEF_SET_BUFFER_SHIFT 16 +#define NV50TCL_CB_DEF_SET_BUFFER_MASK 0xffff0000 #define NV50TCL_DEPTH_TEST_ENABLE 0x000012cc #define NV50TCL_SHADE_MODEL 0x000012d4 #define NV50TCL_SHADE_MODEL_FLAT 0x00001d00 @@ -5779,12 +5803,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_TSC_ADDRESS_HIGH 0x0000155c +#define NV50TCL_TSC_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_TIC_ADDRESS_HIGH 0x00001574 +#define NV50TCL_TIC_ADDRESS_LOW 0x00001578 #define NV50TCL_STENCIL_FRONT_ENABLE 0x00001594 #define NV50TCL_STENCIL_FRONT_OP_FAIL 0x00001598 #define NV50TCL_STENCIL_FRONT_OP_FAIL_ZERO 0x00000000 diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 5b4c5f96ac..e4c09a99d8 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -189,13 +189,13 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) so_data (so, 1); 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_method(so, screen->tesla, NV50TCL_DMA_UNK0(0), + NV50TCL_DMA_UNK0__SIZE); + for (i = 0; i < NV50TCL_DMA_UNK0__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_method(so, screen->tesla, NV50TCL_DMA_UNK1(0), + NV50TCL_DMA_UNK1__SIZE); + for (i = 0; i < NV50TCL_DMA_UNK1__SIZE; i++) so_data(so, nvws->channel->vram->handle); so_method(so, screen->tesla, 0x121c, 1); so_data (so, 1); -- cgit v1.2.3 From 7a81ffa1154e6efd09fe91a944514a6f56369b4a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 01:53:28 +1000 Subject: nv50: get clear-scissor working --- src/gallium/drivers/nv50/nv50_context.h | 1 + src/gallium/drivers/nv50/nv50_state_validate.c | 44 ++++++++++++++++++++------ 2 files changed, 36 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 4ea01009fb..9b77fc1225 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -86,6 +86,7 @@ struct nv50_state { struct nouveau_stateobj *scissor; unsigned scissor_enabled; struct nouveau_stateobj *viewport; + unsigned viewport_bypass; struct nouveau_stateobj *tsc_upload; struct nouveau_stateobj *tic_upload; struct nouveau_stateobj *vertprog; diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 88ef685bb1..bd1f048f87 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -228,17 +228,43 @@ nv50_state_validate(struct nv50_context *nv50) scissor_uptodate: if (nv50->dirty & NV50_NEW_VIEWPORT) { - so = so_new(8, 0); - so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(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_UNK0(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])); + unsigned bypass; + + if (!nv50->rasterizer->pipe.bypass_clipping) + bypass = 0; + else + bypass = 1; + + if (nv50->state.viewport && + (bypass || !(nv50->dirty & NV50_NEW_VIEWPORT)) && + nv50->state.viewport_bypass == bypass) + goto viewport_uptodate; + nv50->state.viewport_bypass = bypass; + + so = so_new(12, 0); + if (!bypass) { + so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(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_UNK0(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_method(so, tesla, 0x192c, 1); + so_data (so, 1); + so_method(so, tesla, 0x0f90, 1); + so_data (so, 0); + } else { + so_method(so, tesla, 0x192c, 1); + so_data (so, 0); + so_method(so, tesla, 0x0f90, 1); + so_data (so, 1); + } + so_ref(so, &nv50->state.viewport); } +viewport_uptodate: if (nv50->dirty & NV50_NEW_SAMPLER) { int i; -- cgit v1.2.3 From 17e95de85250540c8e2448f138d81b7b055be511 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 02:01:23 +1000 Subject: nv50: enable GART usage for vertex buffers AKA "I can haz fast b0rk3d glxgears!!!" --- src/gallium/drivers/nv50/nv50_screen.c | 1 + src/gallium/drivers/nv50/nv50_vbo.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index e4c09a99d8..9f1fba6e42 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -90,6 +90,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; case NOUVEAU_CAP_HW_VTXBUF: + return 1; case NOUVEAU_CAP_HW_IDXBUF: return 0; default: diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index c16bfe3a93..0318b9b550 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -204,11 +204,11 @@ nv50_vbo_validate(struct nv50_context *nv50) so_method(vtxbuf, tesla, 0x900 + (i * 16), 3); so_data (vtxbuf, 0x20000000 | vb->pitch); so_reloc (vtxbuf, vb->buffer, vb->buffer_offset + - ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH, 0, 0); + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | + NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (vtxbuf, vb->buffer, vb->buffer_offset + - ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_LOW, 0, 0); + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | + NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); } so_ref (vtxfmt, &nv50->state.vtxfmt); -- cgit v1.2.3 From 857a3294a959015bf893241199f7fd7f7882a6ab Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 20:44:39 +1000 Subject: nv50: add license headers to .c files --- src/gallium/drivers/nv50/nv50_clear.c | 22 ++++++++++++ src/gallium/drivers/nv50/nv50_context.c | 22 ++++++++++++ src/gallium/drivers/nv50/nv50_draw.c | 22 ++++++++++++ src/gallium/drivers/nv50/nv50_miptree.c | 22 ++++++++++++ src/gallium/drivers/nv50/nv50_program.c | 22 ++++++++++++ src/gallium/drivers/nv50/nv50_query.c | 22 ++++++++++++ src/gallium/drivers/nv50/nv50_screen.c | 22 ++++++++++++ src/gallium/drivers/nv50/nv50_state.c | 22 ++++++++++++ src/gallium/drivers/nv50/nv50_state_validate.c | 22 ++++++++++++ src/gallium/drivers/nv50/nv50_surface.c | 46 +++++++++++--------------- src/gallium/drivers/nv50/nv50_vbo.c | 22 ++++++++++++ 11 files changed, 240 insertions(+), 26 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c index f35087b37e..fbc6cd09ce 100644 --- a/src/gallium/drivers/nv50/nv50_clear.c +++ b/src/gallium/drivers/nv50/nv50_clear.c @@ -1,3 +1,25 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 2494784a94..07987c7d02 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -1,3 +1,25 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include "draw/draw_context.h" #include "pipe/p_defines.h" #include "pipe/p_winsys.h" diff --git a/src/gallium/drivers/nv50/nv50_draw.c b/src/gallium/drivers/nv50/nv50_draw.c index 2b0c0384a3..4fd81bd27a 100644 --- a/src/gallium/drivers/nv50/nv50_draw.c +++ b/src/gallium/drivers/nv50/nv50_draw.c @@ -1,3 +1,25 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include "draw/draw_pipe.h" #include "pipe/p_util.h" diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index f936a1f0e2..8b61ca2a1f 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -1,3 +1,25 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index ff81719f03..2668acf299 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1,3 +1,25 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index d8c3491c2c..26bd90ccc5 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -1,3 +1,25 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include "pipe/p_context.h" #include "nv50_context.h" diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 9f1fba6e42..ec6d34e684 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -1,3 +1,25 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include "pipe/p_screen.h" #include "pipe/p_util.h" diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 743de089d6..5c364c4ddf 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -1,3 +1,25 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index bd1f048f87..5c75a242cc 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -1,3 +1,25 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include "nv50_context.h" #include "nouveau/nouveau_stateobj.h" diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index acd7b501ef..6229b63626 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -1,30 +1,24 @@ - -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * +/* + * Copyright 2008 Ben Skeggs + * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, 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. - * - **************************************************************************/ + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ #include "nv50_context.h" #include "pipe/p_defines.h" diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 0318b9b550..8e420ad172 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -1,3 +1,25 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include "pipe/p_context.h" #include "pipe/p_state.h" #include "pipe/p_util.h" -- cgit v1.2.3 From 62100692b8ad7fa868743c4698dac109beceaf7f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 20:49:06 +1000 Subject: nv50: split tic construction out into own file --- src/gallium/drivers/nv50/Makefile | 1 + src/gallium/drivers/nv50/nv50_context.h | 3 + src/gallium/drivers/nv50/nv50_state_validate.c | 27 +----- src/gallium/drivers/nv50/nv50_tex.c | 57 ++++++++++++ src/gallium/drivers/nv50/nv50_texture.h | 124 +++++++++++++++++++++++++ 5 files changed, 187 insertions(+), 25 deletions(-) create mode 100644 src/gallium/drivers/nv50/nv50_tex.c create mode 100644 src/gallium/drivers/nv50/nv50_texture.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile index 2cc6e9de28..be30400c03 100644 --- a/src/gallium/drivers/nv50/Makefile +++ b/src/gallium/drivers/nv50/Makefile @@ -14,6 +14,7 @@ DRIVER_SOURCES = \ nv50_state.c \ nv50_state_validate.c \ nv50_surface.c \ + nv50_tex.c \ nv50_vbo.c C_SOURCES = \ diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 9b77fc1225..cb51fb02eb 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -164,4 +164,7 @@ extern void nv50_program_destroy(struct nv50_context *nv50, struct nv50_program /* nv50_state_validate.c */ extern boolean nv50_state_validate(struct nv50_context *nv50); +/* nv50_tex.c */ +extern void nv50_tex_validate(struct nv50_context *); + #endif diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 5c75a242cc..8f9ee05acc 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -300,31 +300,8 @@ viewport_uptodate: so_ref(so, &nv50->state.tsc_upload); } - if (nv50->dirty & NV50_NEW_TEXTURE) { - int i; - - so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2); - so_method(so, tesla, 0x0f00, 1); - so_data (so, NV50_CB_TIC); - so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8); - for (i = 0; i < nv50->miptree_nr; i++) { - struct nv50_miptree *mt = nv50->miptree[i]; - - so_data (so, 0x2a712488); - so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0xd0005000); - so_data (so, 0x00300000); - so_data (so, mt->base.width[0]); - so_data (so, (mt->base.depth[0] << 16) | - mt->base.height[0]); - so_data (so, 0x03000000); - so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_HIGH, 0, 0); - } - - so_ref(so, &nv50->state.tic_upload); - } + if (nv50->dirty & NV50_NEW_TEXTURE) + nv50_tex_validate(nv50); if (nv50->dirty & NV50_NEW_ARRAYS) nv50_vbo_validate(nv50); diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c new file mode 100644 index 0000000000..581a9e2ffb --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -0,0 +1,57 @@ +/* + * Copyright 2008 Ben Skeggs + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "nv50_context.h" +#include "nv50_texture.h" + +#include "nouveau/nouveau_stateobj.h" + +void +nv50_tex_validate(struct nv50_context *nv50) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_stateobj *so; + int i; + + so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2); + so_method(so, tesla, 0x0f00, 1); + so_data (so, NV50_CB_TIC); + so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8); + for (i = 0; i < nv50->miptree_nr; i++) { + struct nv50_miptree *mt = nv50->miptree[i]; + + so_data (so, 0x2a712488); + so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0xd0005000); + so_data (so, 0x00300000); + so_data (so, mt->base.width[0]); + so_data (so, (mt->base.depth[0] << 16) | + mt->base.height[0]); + so_data (so, 0x03000000); + so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_HIGH, 0, 0); + } + + so_ref(so, &nv50->state.tic_upload); +} + diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h new file mode 100644 index 0000000000..c8fb282f21 --- /dev/null +++ b/src/gallium/drivers/nv50/nv50_texture.h @@ -0,0 +1,124 @@ +#ifndef __NV50_TEXTURE_H__ +#define __NV50_TEXTURE_H__ + +/* It'd be really nice to have these in nouveau_class.h generated by + * renouveau like the rest of the object header - but not sure it can + * handle non-object stuff nicely - need to look into it. + */ + +/* Texture image control block */ +#define NV50TIC_0_0_MAPA_MASK 0x38000000 +#define NV50TIC_0_0_MAPA_ZERO 0x00000000 +#define NV50TIC_0_0_MAPA_C0 0x10000000 +#define NV50TIC_0_0_MAPA_C1 0x18000000 +#define NV50TIC_0_0_MAPA_C2 0x20000000 +#define NV50TIC_0_0_MAPA_C3 0x28000000 +#define NV50TIC_0_0_MAPA_ONE 0x38000000 +#define NV50TIC_0_0_MAPR_MASK 0x07000000 +#define NV50TIC_0_0_MAPR_ZERO 0x00000000 +#define NV50TIC_0_0_MAPR_C0 0x02000000 +#define NV50TIC_0_0_MAPR_C1 0x03000000 +#define NV50TIC_0_0_MAPR_C2 0x04000000 +#define NV50TIC_0_0_MAPR_C3 0x05000000 +#define NV50TIC_0_0_MAPR_ONE 0x07000000 +#define NV50TIC_0_0_MAPG_MASK 0x00e00000 +#define NV50TIC_0_0_MAPG_ZERO 0x00000000 +#define NV50TIC_0_0_MAPG_C0 0x00400000 +#define NV50TIC_0_0_MAPG_C1 0x00600000 +#define NV50TIC_0_0_MAPG_C2 0x00800000 +#define NV50TIC_0_0_MAPG_C3 0x00a00000 +#define NV50TIC_0_0_MAPG_ONE 0x00e00000 +#define NV50TIC_0_0_MAPB_MASK 0x001c0000 +#define NV50TIC_0_0_MAPB_ZERO 0x00000000 +#define NV50TIC_0_0_MAPB_C0 0x00080000 +#define NV50TIC_0_0_MAPB_C1 0x000c0000 +#define NV50TIC_0_0_MAPB_C2 0x00100000 +#define NV50TIC_0_0_MAPB_C3 0x00140000 +#define NV50TIC_0_0_MAPB_ONE 0x001c0000 +#define NV50TIC_0_0_TYPEA_MASK 0x00038000 +#define NV50TIC_0_0_TYPEA_UNORM 0x00010000 +#define NV50TIC_0_0_TYPER_MASK 0x00007000 +#define NV50TIC_0_0_TYPER_UNORM 0x00002000 +#define NV50TIC_0_0_TYPEG_MASK 0x00000e00 +#define NV50TIC_0_0_TYPEG_UNORM 0x00000400 +#define NV50TIC_0_0_TYPEB_MASK 0x000001c0 +#define NV50TIC_0_0_TYPEB_UNORM 0x00000080 +#define NV50TIC_0_0_FMT_MASK 0x0000003c +#define NV50TIC_0_0_FMT_8_8_8_8 0x00000008 +#define NV50TIC_0_0_FMT_5_6_5 0x00000015 +#define NV50TIC_0_0_FMT_8_8 0x00000018 +#define NV50TIC_0_0_FMT_8 0x0000001d + +#define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff +#define NV50TIC_0_1_OFFSET_LOW_SHIFT 0 + +#define NV50TIC_0_2_UNKNOWN_MASK 0xffffffff + +#define NV50TIC_0_3_UNKNOWN_MASK 0xffffffff + +#define NV50TIC_0_4_WIDTH_MASK 0x0000ffff +#define NV50TIC_0_4_WIDTH_SHIFT 0 + +#define NV50TIC_0_5_DEPTH_MASK 0xffff0000 +#define NV50TIC_0_5_DEPTH_SHIFT 16 +#define NV50TIC_0_5_HEIGHT_MASK 0x0000ffff +#define NV50TIC_0_5_HEIGHT_SHIFT 0 + +#define NV50TIC_0_6_UNKNOWN_MASK 0xffffffff + +#define NV50TIC_0_7_OFFSET_HIGH_MASK 0xffffffff +#define NV50TIC_0_7_OFFSET_HIGH_SHIFT 0 + +/* Texture sampler control block */ +#define NV50TSC_1_0_WRAPS_MASK 0x00000007 +#define NV50TSC_1_0_WRAPS_REPEAT 0x00000000 +#define NV50TSC_1_0_WRAPS_MIRROR_REPEAT 0x00000001 +#define NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE 0x00000002 +#define NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER 0x00000003 +#define NV50TSC_1_0_WRAPS_CLAMP 0x00000004 +#define NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_EDGE 0x00000005 +#define NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_BORDER 0x00000006 +#define NV50TSC_1_0_WRAPS_MIRROR_CLAMP 0x00000007 +#define NV50TSC_1_0_WRAPT_MASK 0x00000038 +#define NV50TSC_1_0_WRAPT_REPEAT 0x00000000 +#define NV50TSC_1_0_WRAPT_MIRROR_REPEAT 0x00000008 +#define NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE 0x00000010 +#define NV50TSC_1_0_WRAPT_CLAMP_TO_BORDER 0x00000018 +#define NV50TSC_1_0_WRAPT_CLAMP 0x00000020 +#define NV50TSC_1_0_WRAPT_MIRROR_CLAMP_TO_EDGE 0x00000028 +#define NV50TSC_1_0_WRAPT_MIRROR_CLAMP_TO_BORDER 0x00000030 +#define NV50TSC_1_0_WRAPT_MIRROR_CLAMP 0x00000038 +#define NV50TSC_1_0_WRAPR_MASK 0x000001c0 +#define NV50TSC_1_0_WRAPR_REPEAT 0x00000000 +#define NV50TSC_1_0_WRAPR_MIRROR_REPEAT 0x00000040 +#define NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE 0x00000080 +#define NV50TSC_1_0_WRAPR_CLAMP_TO_BORDER 0x000000c0 +#define NV50TSC_1_0_WRAPR_CLAMP 0x00000100 +#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_EDGE 0x00000140 +#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_BORDER 0x00000180 +#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP 0x000001c0 + +#define NV50TSC_1_1_MAGF_MASK 0x00000003 +#define NV50TSC_1_1_MAGF_NEAREST 0x00000001 +#define NV50TSC_1_1_MAGF_LINEAR 0x00000002 +#define NV50TSC_1_1_MINF_MASK 0x00000030 +#define NV50TSC_1_1_MINF_NEAREST 0x00000010 +#define NV50TSC_1_1_MINF_LINEAR 0x00000020 +#define NV50TSC_1_1_MIPF_MASK 0x000000c0 +#define NV50TSC_1_1_MIPF_NONE 0x00000040 +#define NV50TSC_1_1_MIPF_NEAREST 0x00000080 +#define NV50TSC_1_1_MIPF_LINEAR 0x000000c0 + +#define NV50TSC_1_2_UNKNOWN_MASK 0xffffffff + +#define NV50TSC_1_3_UNKNOWN_MASK 0xffffffff + +#define NV50TSC_1_4_UNKNOWN_MASK 0xffffffff + +#define NV50TSC_1_5_UNKNOWN_MASK 0xffffffff + +#define NV50TSC_1_6_UNKNOWN_MASK 0xffffffff + +#define NV50TSC_1_7_UNKNOWN_MASK 0xffffffff + +#endif -- cgit v1.2.3 From 7c745de74997e859d7e2640092bda9ad900e28a9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 21:19:41 +1000 Subject: nv50: add some texture formats --- src/gallium/drivers/nv50/nv50_program.c | 2 + src/gallium/drivers/nv50/nv50_screen.c | 6 +++ src/gallium/drivers/nv50/nv50_tex.c | 93 ++++++++++++++++++++++++++++----- src/gallium/drivers/nv50/nv50_texture.h | 2 + 4 files changed, 90 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 2668acf299..0d3ddb8a59 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1701,6 +1701,8 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) if (p->buffer) pipe_buffer_reference(ws, &p->buffer, NULL); + nv50->screen->nvws->res_free(&p->data); + p->translated = 0; } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index ec6d34e684..bba5ca4d4e 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -51,7 +51,13 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, 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: return TRUE; default: break; diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 581a9e2ffb..fde3c97c05 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -25,6 +25,81 @@ #include "nouveau/nouveau_stateobj.h" +static int +nv50_tex_construct(struct nouveau_stateobj *so, struct nv50_miptree *mt) +{ + switch (mt->base.format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_8_8_8_8); + break; + case PIPE_FORMAT_A1R5G5B5_UNORM: + so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_1_5_5_5); + break; + case PIPE_FORMAT_A4R4G4B4_UNORM: + so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_4_4_4_4); + break; + case PIPE_FORMAT_R5G6B5_UNORM: + so_data(so, NV50TIC_0_0_MAPA_ONE | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_5_6_5); + break; + case PIPE_FORMAT_L8_UNORM: + so_data(so, NV50TIC_0_0_MAPA_ONE | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C0 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_8); + break; + case PIPE_FORMAT_A8_UNORM: + so_data(so, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_ZERO | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_ZERO | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_ZERO | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_8); + break; + case PIPE_FORMAT_I8_UNORM: + so_data(so, NV50TIC_0_0_MAPA_C0 | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C0 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_8); + break; + case PIPE_FORMAT_A8L8_UNORM: + so_data(so, NV50TIC_0_0_MAPA_C1 | NV50TIC_0_0_TYPEA_UNORM | + NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPG_C0 | NV50TIC_0_0_TYPEG_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_FMT_8_8); + break; + default: + return 1; + } + + so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0); + so_data (so, 0xd0005000); + so_data (so, 0x00300000); + so_data (so, mt->base.width[0]); + so_data (so, (mt->base.depth[0] << 16) | mt->base.height[0]); + so_data (so, 0x03000000); + so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0); + + return 0; +} + void nv50_tex_validate(struct nv50_context *nv50) { @@ -37,19 +112,11 @@ nv50_tex_validate(struct nv50_context *nv50) so_data (so, NV50_CB_TIC); so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8); for (i = 0; i < nv50->miptree_nr; i++) { - struct nv50_miptree *mt = nv50->miptree[i]; - - so_data (so, 0x2a712488); - so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_LOW, 0, 0); - so_data (so, 0xd0005000); - so_data (so, 0x00300000); - so_data (so, mt->base.width[0]); - so_data (so, (mt->base.depth[0] << 16) | - mt->base.height[0]); - so_data (so, 0x03000000); - so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_HIGH, 0, 0); + if (nv50_tex_construct(so, nv50->miptree[i])) { + NOUVEAU_ERR("failed tex validate\n"); + so_ref(NULL, &so); + return; + } } so_ref(so, &nv50->state.tic_upload); diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h index c8fb282f21..6861d67b4d 100644 --- a/src/gallium/drivers/nv50/nv50_texture.h +++ b/src/gallium/drivers/nv50/nv50_texture.h @@ -45,6 +45,8 @@ #define NV50TIC_0_0_TYPEB_UNORM 0x00000080 #define NV50TIC_0_0_FMT_MASK 0x0000003c #define NV50TIC_0_0_FMT_8_8_8_8 0x00000008 +#define NV50TIC_0_0_FMT_4_4_4_4 0x00000012 +#define NV50TIC_0_0_FMT_1_5_5_5 0x00000013 #define NV50TIC_0_0_FMT_5_6_5 0x00000015 #define NV50TIC_0_0_FMT_8_8 0x00000018 #define NV50TIC_0_0_FMT_8 0x0000001d -- cgit v1.2.3 From 866a68dbd1ec9c3a6100de6d50890ac5068247dc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 22:01:29 +1000 Subject: nv50: demagic tex filter / wrap mode --- src/gallium/drivers/nv50/nv50_state.c | 65 +++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 5c364c4ddf..c552a0b0aa 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -26,6 +26,7 @@ #include "pipe/p_inlines.h" #include "nv50_context.h" +#include "nv50_texture.h" #include "nouveau/nouveau_stateobj.h" @@ -104,14 +105,74 @@ nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso) FREE(bso); } +static INLINE unsigned +wrap_mode(unsigned wrap) +{ + switch (wrap) { + case PIPE_TEX_WRAP_REPEAT: + return NV50TSC_1_0_WRAPS_REPEAT; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + return NV50TSC_1_0_WRAPS_MIRROR_REPEAT; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER; + case PIPE_TEX_WRAP_CLAMP: + return NV50TSC_1_0_WRAPS_CLAMP; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + return NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_EDGE; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + return NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_BORDER; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + return NV50TSC_1_0_WRAPS_MIRROR_CLAMP; + default: + NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); + return NV50TSC_1_0_WRAPS_REPEAT; + } +} static void * nv50_sampler_state_create(struct pipe_context *pipe, const struct pipe_sampler_state *cso) { unsigned *tsc = CALLOC(8, sizeof(unsigned)); - tsc[0] = 0x00024080; - tsc[1] = 0x00000062; + tsc[0] = (0x00024000 | + (wrap_mode(cso->wrap_s) << 0) | + (wrap_mode(cso->wrap_t) << 3) | + (wrap_mode(cso->wrap_r) << 6)); + + switch (cso->mag_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + tsc[1] |= NV50TSC_1_1_MAGF_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + tsc[1] |= NV50TSC_1_1_MAGF_NEAREST; + break; + } + + switch (cso->min_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + tsc[1] |= NV50TSC_1_1_MINF_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + tsc[1] |= NV50TSC_1_1_MINF_NEAREST; + break; + } + + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_LINEAR: + tsc[1] |= NV50TSC_1_1_MIPF_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NEAREST: + tsc[1] |= NV50TSC_1_1_MIPF_NEAREST; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + tsc[1] |= NV50TSC_1_1_MIPF_NONE; + break; + } return (void *)tsc; } -- cgit v1.2.3 From 5180a668a7da627a40e024a2ed765458d5bac43e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 22:24:24 +1000 Subject: nouveau: winsys surface funcs deprecated, remove them --- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 30 ---------------------- 1 file changed, 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c index 765ea36f88..8a2870a2ff 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c @@ -25,33 +25,6 @@ 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) @@ -215,9 +188,6 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) 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; -- cgit v1.2.3 From 9b0add0be4a3ba7fc72779daf8361d8cd98d9f64 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 22:45:11 +1000 Subject: nv50: quick hack to get textures untiled on map, and tiled on unmap progs/fp/tri-tex is all good now rather than all scrambled :) --- src/gallium/drivers/nv50/nv50_context.h | 11 ++++++++++ src/gallium/drivers/nv50/nv50_miptree.c | 18 +++++++++++------ src/gallium/drivers/nv50/nv50_surface.c | 36 ++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index cb51fb02eb..1c069f1625 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -74,6 +74,17 @@ nv50_miptree(struct pipe_texture *pt) return (struct nv50_miptree *)pt; } +struct nv50_surface { + struct pipe_surface base; + struct pipe_buffer *untiled; +}; + +static INLINE struct nv50_surface * +nv50_surface(struct pipe_surface *pt) +{ + return (struct nv50_surface *)pt; +} + struct nv50_state { unsigned dirty; diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 8b61ca2a1f..a02ad41885 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -82,9 +82,14 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, { struct pipe_winsys *ws = pscreen->winsys; struct nv50_miptree *mt = nv50_miptree(pt); + struct nv50_surface *s; struct pipe_surface *ps; - ps = CALLOC_STRUCT(pipe_surface); + s = CALLOC_STRUCT(nv50_surface); + if (!s) + return NULL; + ps = &s->base; + ps->refcount = 1; ps->winsys = ws; ps->format = pt->format; @@ -109,14 +114,15 @@ nv50_miptree_surface_del(struct pipe_screen *pscreen, struct pipe_surface **psurface) { struct pipe_winsys *ws = pscreen->winsys; - struct pipe_surface *surf = *psurface; + struct pipe_surface *ps = *psurface; + struct nv50_surface *s = nv50_surface(ps); *psurface = NULL; - if (--surf->refcount <= 0) { - pipe_texture_reference(&surf->texture, NULL); - pipe_buffer_reference(ws, &surf->buffer, NULL); - FREE(surf); + if (--ps->refcount <= 0) { + pipe_texture_reference(&ps->texture, NULL); + pipe_buffer_reference(ws, &ps->buffer, NULL); + FREE(s); } } diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 6229b63626..8d3f1edcfe 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -52,25 +52,51 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, } static void * -nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, +nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *ps, unsigned flags ) { + struct nouveau_winsys *nvws = nv50_screen(screen)->nvws; struct pipe_winsys *ws = screen->winsys; + struct nv50_surface *s = nv50_surface(ps); + struct nv50_surface m = *s; void *map; - map = ws->buffer_map(ws, surface->buffer, flags); + if (!s->untiled) { + s->untiled = ws->buffer_create(ws, 0, 0, ps->buffer->size); + + m.base.buffer = s->untiled; + nvws->surface_copy(nvws, &m.base, 0, 0, &s->base, 0, 0, + ps->width, ps->height); + } + + /* Map original tiled surface to disallow it being validated while + * untiled mirror is mapped. + */ + ws->buffer_map(ws, ps->buffer, flags); + + map = ws->buffer_map(ws, s->untiled, flags); if (!map) return NULL; - return map + surface->offset; + return map; } static void -nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) +nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *ps) { + struct nouveau_winsys *nvws = nv50_screen(screen)->nvws; struct pipe_winsys *ws = screen->winsys; + struct nv50_surface *s = nv50_surface(ps); + struct nv50_surface m = *s; + + ws->buffer_unmap(ws, s->untiled); + ws->buffer_unmap(ws, ps->buffer); + + m.base.buffer = s->untiled; + nvws->surface_copy(nvws, &s->base, 0, 0, &m.base, 0, 0, + ps->width, ps->height); - ws->buffer_unmap(ws, surface->buffer); + pipe_buffer_reference(ws, &s->untiled, NULL); } void -- cgit v1.2.3 From 7c949fb2a2cd4e9b05efd4133e5ae8ea938934d8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 11 Jul 2008 22:48:11 +1000 Subject: nv50: obey do_flip in surface_copy() --- src/gallium/drivers/nv50/nv50_surface.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 8d3f1edcfe..a9daeee369 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -28,7 +28,7 @@ #include "util/p_tile.h" static void -nv50_surface_copy(struct pipe_context *pipe, unsigned flip, +nv50_surface_copy(struct pipe_context *pipe, boolean flip, struct pipe_surface *dest, unsigned destx, unsigned desty, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) @@ -36,8 +36,16 @@ nv50_surface_copy(struct pipe_context *pipe, unsigned flip, 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); + if (flip) { + 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 -- cgit v1.2.3 From 36ac2ade17a1b8f2c47d41945430983834b9ef01 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 11 Jul 2008 21:14:32 +0200 Subject: nv30: Update miptree to match latest changes --- src/gallium/drivers/nv30/nv30_miptree.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index ad0b257fe2..a0e488c09b 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -32,8 +32,8 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); if (swizzled) - pitch = pt->width[l]; - pitch = (pitch + 63) & ~63; + pitch = pt->nblocksx[l]; + pitch = align_int(pitch, 64); nv30mt->level[l].pitch = pitch * pt->block.size; nv30mt->level[l].image_offset = @@ -42,7 +42,6 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) width = MAX2(1, width >> 1); height = MAX2(1, height >> 1); depth = MAX2(1, depth >> 1); - } for (f = 0; f < nr_faces; f++) { @@ -111,17 +110,20 @@ nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, struct nv30_miptree *nv30mt = (struct nv30_miptree *)pt; struct pipe_surface *ps; - ps = ws->surface_alloc(ws); + ps = CALLOC_STRUCT(pipe_surface); if (!ps) return NULL; + pipe_texture_reference(&ps->texture, pt); pipe_buffer_reference(ws, &ps->buffer, nv30mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; + ps->block = pt->block; ps->nblocksx = pt->nblocksx[level]; ps->nblocksy = pt->nblocksy[level]; - ps->block = pt->block; ps->stride = nv30mt->level[level].pitch; + ps->usage = flags; + ps->status = PIPE_SURFACE_STATUS_DEFINED; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = nv30mt->level[level].image_offset[face]; @@ -139,6 +141,15 @@ static void nv30_miptree_surface_del(struct pipe_screen *pscreen, struct pipe_surface **psurface) { + struct pipe_surface *ps = *psurface; + + *psurface = NULL; + if (--ps->refcount > 0) + return; + + pipe_texture_reference(&ps->texture, NULL); + pipe_buffer_reference(pscreen->winsys, &ps->buffer, NULL); + FREE(ps); } void -- cgit v1.2.3 From 37a418b3b05db51aea0a1010bad8118b92e0e9d6 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 11 Jul 2008 21:31:24 +0200 Subject: nv30: split fragprog_prepare from fragprog_translate --- src/gallium/drivers/nv30/nv30_fragprog.c | 91 ++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 23 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 740d3ab430..7278bf5886 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -1,7 +1,6 @@ #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" @@ -650,30 +649,22 @@ nv30_fragprog_parse_decl_output(struct nv30_fpc *fpc, return TRUE; } -void -nv30_fragprog_translate(struct nv30_context *nv30, - struct nv30_fragment_program *fp) +static boolean +nv30_fragprog_prepare(struct nv30_fpc *fpc) { - 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; + struct tgsi_parse_context p; + /*int high_temp = -1, i;*/ - tgsi_parse_init(&parse, fp->pipe.tokens); + tgsi_parse_init(&p, fpc->fp->pipe.tokens); + while (!tgsi_parse_end_of_tokens(&p)) { + const union tgsi_full_token *tok = &p.FullToken; - while (!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { + tgsi_parse_token(&p); + switch(tok->Token.Type) { case TGSI_TOKEN_TYPE_DECLARATION: { const struct tgsi_full_declaration *fdec; - fdec = &parse.FullToken.FullDeclaration; + fdec = &p.FullToken.FullDeclaration; switch (fdec->Declaration.File) { case TGSI_FILE_INPUT: if (!nv30_fragprog_parse_decl_attrib(fpc, fdec)) @@ -683,6 +674,12 @@ nv30_fragprog_translate(struct nv30_context *nv30, if (!nv30_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; } @@ -692,17 +689,65 @@ nv30_fragprog_translate(struct nv30_context *nv30, { struct tgsi_full_immediate *imm; float vals[4]; - int i; - imm = &parse.FullToken.FullImmediate; + imm = &p.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; + 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 nv30_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; +} + +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; + + if (!nv30_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; -- cgit v1.2.3 From b327b064058aaab1debb1af08f4b9abe1385adc6 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 11 Jul 2008 22:06:12 +0200 Subject: nv30: split fragprog_upload from fragprog_bind --- src/gallium/drivers/nv30/nv30_fragprog.c | 57 ++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 7278bf5886..6af86e4f4f 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -783,6 +783,40 @@ out_err: FREE(fpc); } +static void +nv30_fragprog_upload(struct nv30_context *nv30, + struct nv30_fragment_program *fp) +{ + struct pipe_winsys *ws = nv30->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); +} + void nv30_fragprog_bind(struct nv30_context *nv30, struct nv30_fragment_program *fp) { @@ -818,28 +852,7 @@ nv30_fragprog_bind(struct nv30_context *nv30, struct nv30_fragment_program *fp) 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); + nv30_fragprog_upload(nv30, fp); fp->on_hw = TRUE; } -- cgit v1.2.3 From 5acbd0b0961089f9553adbe9b3d1341997ccb220 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 11 Jul 2008 22:42:42 +0200 Subject: nv30: Emit fragtex state using state objects --- src/gallium/drivers/nv30/nv30_context.h | 1 + src/gallium/drivers/nv30/nv30_fragtex.c | 82 +++++++++++++++++++----------- src/gallium/drivers/nv30/nv30_state_emit.c | 38 +++----------- 3 files changed, 59 insertions(+), 62 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 5404685da2..72f803c80a 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -220,6 +220,7 @@ extern struct nv30_state_entry nv30_state_blend_colour; extern struct nv30_state_entry nv30_state_zsa; extern struct nv30_state_entry nv30_state_viewport; extern struct nv30_state_entry nv30_state_framebuffer; +extern struct nv30_state_entry nv30_state_fragtex; /* nv30_vbo.c */ extern boolean nv30_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index f253087c88..abe77b51df 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -49,17 +49,17 @@ 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), + _(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), + _(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), {}, }; @@ -67,6 +67,7 @@ static struct nv30_texture_format * nv30_fragtex_format(uint pipe_format) { struct nv30_texture_format *tf = nv30_texture_formats; + char fs[128]; while (tf->defined) { if (tf->pipe == pipe_format) @@ -74,26 +75,27 @@ nv30_fragtex_format(uint pipe_format) tf++; } + pf_sprint_name(fs, pipe_format); + NOUVEAU_ERR("unknown texture format %s\n", fs); return NULL; } -static void +static struct nouveau_stateobj * 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? */ + 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 = nv30_fragtex_format(pt->format); - if (!tf || !tf->defined) { - NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format); - return; - } + if (!tf) + assert(0); txf = tf->format << 8; txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0); @@ -117,35 +119,45 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) break; default: NOUVEAU_ERR("Unknown target %d\n", pt->target); - return; + return NULL; } txs = tf->swizzle; - BEGIN_RING(rankine, NV34TCL_TX_OFFSET(unit), 8); - OUT_RELOCl(nv30mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW); - OUT_RELOCd(nv30mt->buffer,txf, tex_flags | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); - OUT_RING (ps->wrap); - OUT_RING (NV34TCL_TX_ENABLE_ENABLE | ps->en); - OUT_RING (txs); - OUT_RING (ps->filt | 0x2000 /* magic */); - OUT_RING ((pt->width[0] << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pt->height[0]); - OUT_RING (ps->bcol); + so = so_new(16, 2); + so_method(so, nv30->screen->rankine, NV34TCL_TX_OFFSET(unit), 8); + so_reloc (so, nv30mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0); + so_reloc (so, nv30mt->buffer, txf, tex_flags | NOUVEAU_BO_OR, + NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1); + so_data (so, ps->wrap); + so_data (so, NV34TCL_TX_ENABLE_ENABLE | ps->en); + so_data (so, txs); + so_data (so, ps->filt | 0x2000 /*voodoo*/); + so_data (so, (pt->width[0] << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | + pt->height[0]); + so_data (so, ps->bcol); + + return so; } -void -nv30_fragtex_bind(struct nv30_context *nv30) +static boolean +nv30_fragtex_validate(struct nv30_context *nv30) { - struct nv30_fragment_program *fp = nv30->fragprog.active; + struct nv30_fragment_program *fp = nv30->fragprog.current; + struct nv30_state *state = &nv30->state; + struct nouveau_stateobj *so; unsigned samplers, unit; - samplers = nv30->fp_samplers & ~fp->samplers; + samplers = state->fp_samplers & ~fp->samplers; while (samplers) { unit = ffs(samplers) - 1; samplers &= ~(1 << unit); - BEGIN_RING(rankine, NV34TCL_TX_ENABLE(unit), 1); - OUT_RING (0); + so = so_new(2, 0); + so_method(so, nv30->screen->rankine, NV34TCL_TX_ENABLE(unit), 1); + so_data (so, 0); + so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]); + state->dirty |= (1ULL << (NV30_STATE_FRAGTEX0 + unit)); } samplers = nv30->dirty_samplers & fp->samplers; @@ -153,9 +165,19 @@ nv30_fragtex_bind(struct nv30_context *nv30) unit = ffs(samplers) - 1; samplers &= ~(1 << unit); - nv30_fragtex_build(nv30, unit); + so = nv30_fragtex_build(nv30, unit); + so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]); + state->dirty |= (1ULL << (NV30_STATE_FRAGTEX0 + unit)); } - nv30->fp_samplers = fp->samplers; + nv30->state.fp_samplers = fp->samplers; + return FALSE; } +struct nv30_state_entry nv30_state_fragtex = { + .validate = nv30_fragtex_validate, + .dirty = { + .pipe = NV30_NEW_SAMPLER | NV30_NEW_FRAGPROG, + .hw = 0 + } +}; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 0ea7857197..cf10ddd4b6 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -6,6 +6,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_rasterizer, &nv30_state_scissor, &nv30_state_stipple, + &nv30_state_fragtex, &nv30_state_blend, &nv30_state_blend_colour, &nv30_state_zsa, @@ -59,6 +60,11 @@ nv30_emit_hw_state(struct nv30_context *nv30) screen->cur_pctx = nv30->pctx_id; } + if (nv30->dirty & NV30_NEW_FRAGPROG) { + nv30_fragprog_bind(nv30, nv30->fragprog.current); + /*XXX: clear NV30_NEW_FRAGPROG if no new program uploaded */ + } + for (i = 0, states = state->dirty; states; i++) { if (!(states & (1ULL << i))) continue; @@ -68,28 +74,11 @@ nv30_emit_hw_state(struct nv30_context *nv30) states &= ~(1ULL << 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; - so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { if (!(samplers & (1 << i))) @@ -99,21 +88,6 @@ nv30_emit_hw_state(struct nv30_context *nv30) samplers &= ~(1ULL << i); } - /* 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 | -- cgit v1.2.3 From c7086277546d065eb94ba8dbeca1620605f167ea Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 11 Jul 2008 23:17:47 +0200 Subject: nv30: Move constant buffers out of vert/frag prog structures --- src/gallium/drivers/nv30/nv30_context.h | 6 ++---- src/gallium/drivers/nv30/nv30_fragprog.c | 12 ++++++------ src/gallium/drivers/nv30/nv30_state.c | 5 +++-- src/gallium/drivers/nv30/nv30_vertprog.c | 18 ++++++++---------- 4 files changed, 19 insertions(+), 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 72f803c80a..c3c8b73309 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -124,6 +124,8 @@ struct nv30_context { unsigned dirty; struct pipe_scissor_state scissor; unsigned stipple[32]; + struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + unsigned constbuf_nr[PIPE_SHADER_TYPES]; struct nv30_rasterizer_state *rasterizer; struct nv30_zsa_state *zsa; struct nv30_blend_state *blend; @@ -150,16 +152,12 @@ struct nv30_context { 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]; diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 6af86e4f4f..b560455a02 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -820,6 +820,8 @@ nv30_fragprog_upload(struct nv30_context *nv30, void nv30_fragprog_bind(struct nv30_context *nv30, struct nv30_fragment_program *fp) { + struct pipe_buffer *constbuf = + nv30->constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_winsys *ws = nv30->pipe.winsys; int i; @@ -830,8 +832,9 @@ nv30_fragprog_bind(struct nv30_context *nv30, struct nv30_fragment_program *fp) } if (fp->nr_consts) { - float *map = ws->buffer_map(ws, nv30->fragprog.constant_buf, - PIPE_BUFFER_USAGE_CPU_READ); + float *map; + + map = ws->buffer_map(ws, constbuf, 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]; @@ -842,13 +845,10 @@ nv30_fragprog_bind(struct nv30_context *nv30, struct nv30_fragment_program *fp) memcpy(p, cb, 4 * sizeof(float)); fp->on_hw = 0; } - ws->buffer_unmap(ws, nv30->fragprog.constant_buf); + ws->buffer_unmap(ws, constbuf); } 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); diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 72b9515eb1..aec6fa2b15 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -589,12 +589,13 @@ nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, { struct nv30_context *nv30 = nv30_context(pipe); + nv30->constbuf[shader] = buf->buffer; + nv30->constbuf_nr[shader] = buf->size / (4 * sizeof(float)); + 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; } } diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 1b34d2e4b2..90756febd2 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -135,7 +135,7 @@ emit_src(struct nv30_vpc *vpc, uint32_t *hw, int pos, struct nv30_sreg src) /* * |VVV| - * d°.°b + * d�.�b * \u/ * */ @@ -641,9 +641,12 @@ 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; + struct pipe_buffer *constbuf; boolean upload_code = FALSE, upload_data = FALSE; int i; + constbuf = nv30->constbuf[PIPE_SHADER_VERTEX]; + /* Translate TGSI shader into hw bytecode */ if (!vp->translated) { nv30_vertprog_translate(nv30, vp); @@ -730,8 +733,8 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) if (vp->nr_consts) { float *map = NULL; - if (nv30->vertprog.constant_buf) { - map = ws->buffer_map(ws, nv30->vertprog.constant_buf, + if (constbuf) { + map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); } @@ -750,15 +753,10 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) 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); + if (constbuf) { + ws->buffer_unmap(ws, constbuf); } } -- cgit v1.2.3 From 2419a5fe3601851989506a11b0bd4e3cfb071035 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 00:19:15 +0200 Subject: nv30: Emit vertex program using state objects --- src/gallium/drivers/nv30/nv30_context.h | 11 ++------ src/gallium/drivers/nv30/nv30_state.c | 11 ++++---- src/gallium/drivers/nv30/nv30_state.h | 2 ++ src/gallium/drivers/nv30/nv30_state_emit.c | 6 +---- src/gallium/drivers/nv30/nv30_vbo.c | 2 +- src/gallium/drivers/nv30/nv30_vertprog.c | 40 +++++++++++++++++++++++------- 6 files changed, 42 insertions(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index c3c8b73309..5d7080a555 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -124,6 +124,7 @@ struct nv30_context { unsigned dirty; struct pipe_scissor_state scissor; unsigned stipple[32]; + struct nv30_vertex_program *vertprog; struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; unsigned constbuf_nr[PIPE_SHADER_TYPES]; struct nv30_rasterizer_state *rasterizer; @@ -150,11 +151,6 @@ struct nv30_context { unsigned delta; } vb[16]; - struct { - struct nv30_vertex_program *active; - struct nv30_vertex_program *current; - } vertprog; - struct { struct nv30_fragment_program *active; struct nv30_fragment_program *current; @@ -188,10 +184,6 @@ extern void nv30_screen_init_miptree_functions(struct pipe_screen *pscreen); 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 *); @@ -213,6 +205,7 @@ extern void nv30_state_tex_update(struct nv30_context *nv30); extern struct nv30_state_entry nv30_state_rasterizer; extern struct nv30_state_entry nv30_state_scissor; extern struct nv30_state_entry nv30_state_stipple; +extern struct nv30_state_entry nv30_state_vertprog; extern struct nv30_state_entry nv30_state_blend; extern struct nv30_state_entry nv30_state_blend_colour; extern struct nv30_state_entry nv30_state_zsa; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index aec6fa2b15..92695ce23c 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -499,10 +499,12 @@ static void * nv30_vp_state_create(struct pipe_context *pipe, const struct pipe_shader_state *cso) { + /*struct nv30_context *nv30 = nv30_context(pipe);*/ struct nv30_vertex_program *vp; vp = CALLOC(1, sizeof(struct nv30_vertex_program)); vp->pipe = *cso; + /*vp->draw = draw_create_vertex_shader(nv30->draw, &vp->pipe);*/ return (void *)vp; } @@ -511,14 +513,10 @@ 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->vertprog = hwcso; nv30->dirty |= NV30_NEW_VERTPROG; + /*nv30->draw_dirty |= NV30_NEW_VERTPROG;*/ } static void @@ -527,6 +525,7 @@ nv30_vp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv30_context *nv30 = nv30_context(pipe); struct nv30_vertex_program *vp = hwcso; + /*draw_delete_vertex_shader(nv30->draw, vp->draw);*/ nv30_vertprog_destroy(nv30, vp); FREE(vp); } diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h index c65a937467..a897bc5068 100644 --- a/src/gallium/drivers/nv30/nv30_state.h +++ b/src/gallium/drivers/nv30/nv30_state.h @@ -26,6 +26,7 @@ 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; @@ -39,6 +40,7 @@ struct nv30_vertex_program { uint32_t ir; uint32_t or; + struct nouveau_stateobj *so; }; struct nv30_fragment_program_data { diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index cf10ddd4b6..4ab62ddc01 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -7,6 +7,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_scissor, &nv30_state_stipple, &nv30_state_fragtex, + &nv30_state_vertprog, &nv30_state_blend, &nv30_state_blend_colour, &nv30_state_zsa, @@ -74,11 +75,6 @@ nv30_emit_hw_state(struct nv30_context *nv30) states &= ~(1ULL << i); } - if (nv30->dirty & NV30_NEW_VERTPROG) { - nv30_vertprog_bind(nv30, nv30->vertprog.current); - nv30->dirty &= ~NV30_NEW_VERTPROG; - } - so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { if (!(samplers & (1 << i))) diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index d23164eb48..8e4ee7a874 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -100,7 +100,7 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, int attrib, static void nv30_vbo_arrays_update(struct nv30_context *nv30) { - struct nv30_vertex_program *vp = nv30->vertprog.active; + struct nv30_vertex_program *vp = nv30->vertprog; uint32_t inputs, vtxfmt[16]; int hw, num_hw = 0; diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 90756febd2..65e0013205 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -563,7 +563,7 @@ nv30_vertprog_prepare(struct nv30_vpc *vpc) return TRUE; } -void +static void nv30_vertprog_translate(struct nv30_context *nv30, struct nv30_vertex_program *vp) { @@ -636,27 +636,31 @@ out_err: FREE(vpc); } -void -nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) +static boolean +nv30_vertprog_validate(struct nv30_context *nv30) { struct nouveau_winsys *nvws = nv30->nvws; struct pipe_winsys *ws = nv30->pipe.winsys; + struct nouveau_grobj *rankine = nv30->screen->rankine; + struct nv30_vertex_program *vp; struct pipe_buffer *constbuf; boolean upload_code = FALSE, upload_data = FALSE; int i; + vp = nv30->vertprog; constbuf = nv30->constbuf[PIPE_SHADER_VERTEX]; /* Translate TGSI shader into hw bytecode */ if (!vp->translated) { nv30_vertprog_translate(nv30, vp); if (!vp->translated) - assert(0); + return FALSE; } /* Allocate hw vtxprog exec slots */ if (!vp->exec) { struct nouveau_resource *heap = nv30->screen->vp_exec_heap; + struct nouveau_stateobj *so; uint vplen = vp->nr_insns; if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) { @@ -671,6 +675,15 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) assert(0); } + so = so_new(2, 0); + so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1); + so_data (so, vp->exec->start); + /* Add these, and you'll go 1/3 speed */ + /*so_method(so, rankine, NV34TCL_VP_ATTRIB_EN, 2); + so_data (so, vp->ir); + so_data (so, vp->or);*/ + so_ref(so, &vp->so); + upload_code = TRUE; } @@ -777,10 +790,12 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp) } } - BEGIN_RING(rankine, NV34TCL_VP_START_FROM_ID, 1); - OUT_RING (vp->exec->start); + if (vp->so != nv30->state.hw[NV30_STATE_VERTPROG]) { + so_ref(vp->so, &nv30->state.hw[NV30_STATE_VERTPROG]); + return TRUE; + } - nv30->vertprog.active = vp; + return FALSE; } void @@ -808,7 +823,14 @@ nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp) vp->data_start = 0; vp->data_start_min = 0; - /* vp->ir = vp->or = vp->clip_ctrl = 0; - so_ref(NULL, &vp->so); */ + vp->ir = vp->or = 0; + so_ref(NULL, &vp->so); } +struct nv30_state_entry nv30_state_vertprog = { + .validate = nv30_vertprog_validate, + .dirty = { + .pipe = NV30_NEW_VERTPROG /*| NV30_NEW_UCP*/, + .hw = NV30_STATE_VERTPROG, + } +}; -- cgit v1.2.3 From 58737dc87575625438d288fe2f816b6a9d2086f1 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 00:48:26 +0200 Subject: nv30: Emit fragment program using state objects --- src/gallium/drivers/nv30/nv30_context.h | 11 +---- src/gallium/drivers/nv30/nv30_fragprog.c | 65 +++++++++++++++++++++--------- src/gallium/drivers/nv30/nv30_fragtex.c | 2 +- src/gallium/drivers/nv30/nv30_state.c | 9 ++--- src/gallium/drivers/nv30/nv30_state.h | 3 ++ src/gallium/drivers/nv30/nv30_state_emit.c | 14 +------ 6 files changed, 56 insertions(+), 48 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 5d7080a555..0c900c5598 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -125,6 +125,7 @@ struct nv30_context { struct pipe_scissor_state scissor; unsigned stipple[32]; struct nv30_vertex_program *vertprog; + struct nv30_fragment_program *fragprog; struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; unsigned constbuf_nr[PIPE_SHADER_TYPES]; struct nv30_rasterizer_state *rasterizer; @@ -151,11 +152,6 @@ struct nv30_context { unsigned delta; } vb[16]; - struct { - struct nv30_fragment_program *active; - struct nv30_fragment_program *current; - } fragprog; - struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; }; @@ -188,10 +184,6 @@ 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 *); @@ -205,6 +197,7 @@ extern void nv30_state_tex_update(struct nv30_context *nv30); extern struct nv30_state_entry nv30_state_rasterizer; extern struct nv30_state_entry nv30_state_scissor; extern struct nv30_state_entry nv30_state_stipple; +extern struct nv30_state_entry nv30_state_fragprog; extern struct nv30_state_entry nv30_state_vertprog; extern struct nv30_state_entry nv30_state_blend; extern struct nv30_state_entry nv30_state_blend_colour; diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index b560455a02..06ed04cbfe 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -723,7 +723,7 @@ out_err: return FALSE; } -void +static void nv30_fragprog_translate(struct nv30_context *nv30, struct nv30_fragment_program *fp) { @@ -817,23 +817,46 @@ nv30_fragprog_upload(struct nv30_context *nv30, ws->buffer_unmap(ws, fp->buffer); } -void -nv30_fragprog_bind(struct nv30_context *nv30, struct nv30_fragment_program *fp) +static boolean +nv30_fragprog_validate(struct nv30_context *nv30) { + struct nv30_fragment_program *fp = nv30->fragprog; struct pipe_buffer *constbuf = nv30->constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_winsys *ws = nv30->pipe.winsys; + struct nouveau_stateobj *so; + boolean new_consts = FALSE; int i; + if (fp->translated) + goto update_constants; + + /*nv30->fallback_swrast &= ~NV30_NEW_FRAGPROG;*/ + nv30_fragprog_translate(nv30, fp); if (!fp->translated) { - nv30_fragprog_translate(nv30, fp); - if (!fp->translated) - assert(0); + /*nv30->fallback_swrast |= NV30_NEW_FRAGPROG;*/ + return FALSE; } + fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); + nv30_fragprog_upload(nv30, fp); + + so = so_new(4, 1); + so_method(so, nv30->screen->rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1); + so_reloc (so, fp->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); + so_method(so, nv30->screen->rankine, NV34TCL_FP_CONTROL, 1); + so_data (so, fp->fp_control); + /* FIXME: Add these, and you'll have big slowdown */ + /*so_method(so, nv30->screen->rankine, NV34TCL_FP_REG_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 nv30_fragment_program_data *fpd = &fp->consts[i]; @@ -843,25 +866,20 @@ nv30_fragprog_bind(struct nv30_context *nv30, struct nv30_fragment_program *fp) if (!memcmp(p, cb, 4 * sizeof(float))) continue; memcpy(p, cb, 4 * sizeof(float)); - fp->on_hw = 0; + new_consts = TRUE; } ws->buffer_unmap(ws, constbuf); - } - if (!fp->on_hw) { - if (!fp->buffer) - fp->buffer = ws->buffer_create(ws, 0x100, 0, - fp->insn_len * 4); - nv30_fragprog_upload(nv30, fp); - fp->on_hw = TRUE; + if (new_consts) + nv30_fragprog_upload(nv30, fp); } - 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); + if (new_consts || fp->so != nv30->state.hw[NV30_STATE_FRAGPROG]) { + so_ref(fp->so, &nv30->state.hw[NV30_STATE_FRAGPROG]); + return TRUE; + } - nv30->fragprog.active = fp; + return FALSE; } void @@ -872,3 +890,10 @@ nv30_fragprog_destroy(struct nv30_context *nv30, FREE(fp->insn); } +struct nv30_state_entry nv30_state_fragprog = { + .validate = nv30_fragprog_validate, + .dirty = { + .pipe = NV30_NEW_FRAGPROG, + .hw = NV30_STATE_FRAGPROG + } +}; diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index abe77b51df..8c5e88ea1d 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -143,7 +143,7 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) static boolean nv30_fragtex_validate(struct nv30_context *nv30) { - struct nv30_fragment_program *fp = nv30->fragprog.current; + struct nv30_fragment_program *fp = nv30->fragprog; struct nv30_state *state = &nv30->state; struct nouveau_stateobj *so; unsigned samplers, unit; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 92695ce23c..8dc16d361d 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -539,6 +539,8 @@ nv30_fp_state_create(struct pipe_context *pipe, fp = CALLOC(1, sizeof(struct nv30_fragment_program)); fp->pipe = *cso; + tgsi_scan_shader(fp->pipe.tokens, &fp->info); + return (void *)fp; } @@ -546,13 +548,8 @@ 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->fragprog = hwcso; nv30->dirty |= NV30_NEW_FRAGPROG; } diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h index a897bc5068..20c5176160 100644 --- a/src/gallium/drivers/nv30/nv30_state.h +++ b/src/gallium/drivers/nv30/nv30_state.h @@ -2,6 +2,7 @@ #define __NV30_STATE_H__ #include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" struct nv30_sampler_state { uint32_t fmt; @@ -50,6 +51,7 @@ struct nv30_fragment_program_data { struct nv30_fragment_program { struct pipe_shader_state pipe; + struct tgsi_shader_info info; boolean translated; boolean on_hw; @@ -65,6 +67,7 @@ struct nv30_fragment_program { uint32_t fp_control; uint32_t fp_reg_control; + struct nouveau_stateobj *so; }; struct nv30_miptree { diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 4ab62ddc01..c4ccc9422b 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -6,6 +6,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_rasterizer, &nv30_state_scissor, &nv30_state_stipple, + &nv30_state_fragprog, &nv30_state_fragtex, &nv30_state_vertprog, &nv30_state_blend, @@ -61,11 +62,6 @@ nv30_emit_hw_state(struct nv30_context *nv30) screen->cur_pctx = nv30->pctx_id; } - if (nv30->dirty & NV30_NEW_FRAGPROG) { - nv30_fragprog_bind(nv30, nv30->fragprog.current); - /*XXX: clear NV30_NEW_FRAGPROG if no new program uploaded */ - } - for (i = 0, states = state->dirty; states; i++) { if (!(states & (1ULL << i))) continue; @@ -83,13 +79,7 @@ nv30_emit_hw_state(struct nv30_context *nv30) state->hw[NV30_STATE_FRAGTEX0+i]); samplers &= ~(1ULL << i); } - - /* 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); + so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FRAGPROG]); } boolean -- cgit v1.2.3 From 740c93a08ce7f5fb43a0f4cd5a50d95459c8aa8e Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 00:48:44 +0200 Subject: nv30: Change comment about slowdown --- src/gallium/drivers/nv30/nv30_vertprog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 65e0013205..be6a327dad 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -678,7 +678,7 @@ nv30_vertprog_validate(struct nv30_context *nv30) so = so_new(2, 0); so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1); so_data (so, vp->exec->start); - /* Add these, and you'll go 1/3 speed */ + /* FIXME: Add these, and you'll have big slowdown */ /*so_method(so, rankine, NV34TCL_VP_ATTRIB_EN, 2); so_data (so, vp->ir); so_data (so, vp->or);*/ -- cgit v1.2.3 From b23e20a386729e75492069445bb924412dc29a0c Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 10:10:16 +0200 Subject: nv30: does not have vp_attrib/result --- src/gallium/drivers/nouveau/nouveau_class.h | 2 -- src/gallium/drivers/nv30/nv30_vertprog.c | 4 ---- 2 files changed, 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index 18d8d3677d..749fbf041e 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -4643,8 +4643,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index be6a327dad..39852ce983 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -678,10 +678,6 @@ nv30_vertprog_validate(struct nv30_context *nv30) so = so_new(2, 0); so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1); so_data (so, vp->exec->start); - /* FIXME: Add these, and you'll have big slowdown */ - /*so_method(so, rankine, NV34TCL_VP_ATTRIB_EN, 2); - so_data (so, vp->ir); - so_data (so, vp->or);*/ so_ref(so, &vp->so); upload_code = TRUE; -- cgit v1.2.3 From 9489de99802e635271c1ae84630fc02892af1699 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 10:13:58 +0200 Subject: nv30: was setting wrong register --- src/gallium/drivers/nv30/nv30_fragprog.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 06ed04cbfe..59e79d66f2 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -841,16 +841,15 @@ nv30_fragprog_validate(struct nv30_context *nv30) fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); nv30_fragprog_upload(nv30, fp); - so = so_new(4, 1); + so = so_new(6, 1); so_method(so, nv30->screen->rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1); so_reloc (so, fp->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); so_method(so, nv30->screen->rankine, NV34TCL_FP_CONTROL, 1); so_data (so, fp->fp_control); - /* FIXME: Add these, and you'll have big slowdown */ - /*so_method(so, nv30->screen->rankine, NV34TCL_FP_REG_CONTROL, 1); - so_data (so, fp->fp_control);*/ + so_method(so, nv30->screen->rankine, NV34TCL_FP_REG_CONTROL, 1); + so_data (so, fp->fp_reg_control); so_ref(so, &fp->so); update_constants: -- cgit v1.2.3 From 4ca346a8c0d0d4ea38705f8d3a3e5e690aa77daf Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 11:45:51 +0200 Subject: nv30: Rename state emission func --- src/gallium/drivers/nv30/nv30_context.h | 2 +- src/gallium/drivers/nv30/nv30_state_emit.c | 2 +- src/gallium/drivers/nv30/nv30_vbo.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 0c900c5598..c41cb29201 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -192,7 +192,7 @@ extern void nv30_fragtex_bind(struct nv30_context *); /* nv30_state.c and friends */ extern boolean nv30_state_validate(struct nv30_context *nv30); -extern void nv30_emit_hw_state(struct nv30_context *nv30); +extern void nv30_state_emit(struct nv30_context *nv30); extern void nv30_state_tex_update(struct nv30_context *nv30); extern struct nv30_state_entry nv30_state_rasterizer; extern struct nv30_state_entry nv30_state_scissor; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index c4ccc9422b..1e69a6a6e2 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -46,7 +46,7 @@ nv30_state_do_validate(struct nv30_context *nv30, } void -nv30_emit_hw_state(struct nv30_context *nv30) +nv30_state_emit(struct nv30_context *nv30) { struct nv30_state *state = &nv30->state; struct nv30_screen *screen = nv30->screen; diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index 8e4ee7a874..0f82adfee0 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -156,7 +156,7 @@ nv30_vbo_validate_state(struct nv30_context *nv30, nv30_state_validate(nv30); - nv30_emit_hw_state(nv30); + nv30_state_emit(nv30); if (nv30->dirty & NV30_NEW_ARRAYS) { nv30_vbo_arrays_update(nv30); -- cgit v1.2.3 From 3d0e18ff5fba368a66bf34d18d219bf9a2dfba90 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 11:53:10 +0200 Subject: nv30: Reorder, remove useless stuff --- src/gallium/drivers/nv30/nv30_context.h | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index c41cb29201..ef8c16bdbb 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -114,12 +114,6 @@ struct nv30_context { /* HW state derived from pipe states */ struct nv30_state state; - 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 */ unsigned dirty; struct pipe_scissor_state scissor; @@ -134,17 +128,11 @@ struct nv30_context { struct pipe_blend_color blend_colour; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; + struct nv30_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; + struct nv30_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; unsigned nr_samplers; unsigned nr_textures; - - uint32_t rt_enable; - struct pipe_buffer *rt[2]; - struct pipe_buffer *zeta; - - /*struct { - struct pipe_buffer *buffer; - uint32_t format; - } tex[16];*/ + unsigned dirty_samplers; unsigned vb_enable; struct { @@ -193,7 +181,6 @@ extern void nv30_fragtex_bind(struct nv30_context *); /* nv30_state.c and friends */ extern boolean nv30_state_validate(struct nv30_context *nv30); extern void nv30_state_emit(struct nv30_context *nv30); -extern void nv30_state_tex_update(struct nv30_context *nv30); extern struct nv30_state_entry nv30_state_rasterizer; extern struct nv30_state_entry nv30_state_scissor; extern struct nv30_state_entry nv30_state_stipple; -- cgit v1.2.3 From ac44f334e3492ab68eb310cfe43ed22206a042d8 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 12:24:37 +0200 Subject: nv30: Move edgeflag stuff --- src/gallium/drivers/nv30/nv30_context.c | 7 ------- src/gallium/drivers/nv30/nv30_context.h | 1 + src/gallium/drivers/nv30/nv30_state.c | 11 +++++++++++ 3 files changed, 12 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index b2d9d3f181..eefc614e5b 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -32,12 +32,6 @@ nv30_destroy(struct pipe_context *pipe) 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) { @@ -57,7 +51,6 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) 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; diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index ef8c16bdbb..2e7b62a69a 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -142,6 +142,7 @@ struct nv30_context { struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; + const unsigned *edgeflags; }; static INLINE struct nv30_context * diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 8dc16d361d..4fe1def74d 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -657,6 +657,16 @@ nv30_set_vertex_elements(struct pipe_context *pipe, unsigned count, nv30->dirty |= NV30_NEW_ARRAYS; } +static void +nv30_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + nv30->edgeflags = bitfield; + nv30->dirty |= NV30_NEW_ARRAYS; + /*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/ +} + void nv30_init_state_functions(struct nv30_context *nv30) { @@ -696,6 +706,7 @@ nv30_init_state_functions(struct nv30_context *nv30) nv30->pipe.set_scissor_state = nv30_set_scissor_state; nv30->pipe.set_viewport_state = nv30_set_viewport_state; + nv30->pipe.set_edgeflags = nv30_set_edgeflags; nv30->pipe.set_vertex_buffers = nv30_set_vertex_buffers; nv30->pipe.set_vertex_elements = nv30_set_vertex_elements; } -- cgit v1.2.3 From 12118fcd123992f48ce78629e79e9949b96cd525 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 13:16:47 +0200 Subject: nv30: Emit vertex buffer objects using state objects --- src/gallium/drivers/nv30/nv30_context.h | 14 +- src/gallium/drivers/nv30/nv30_screen.c | 2 +- src/gallium/drivers/nv30/nv30_state.c | 6 + src/gallium/drivers/nv30/nv30_state_emit.c | 8 +- src/gallium/drivers/nv30/nv30_vbo.c | 628 +++++++++++++++++------------ 5 files changed, 399 insertions(+), 259 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 2e7b62a69a..823b34a7c3 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -128,20 +128,17 @@ struct nv30_context { struct pipe_blend_color blend_colour; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; + struct pipe_buffer *idxbuf; + unsigned idxbuf_format; struct nv30_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct nv30_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; unsigned nr_samplers; unsigned nr_textures; unsigned dirty_samplers; - - unsigned vb_enable; - struct { - struct pipe_buffer *buffer; - unsigned delta; - } vb[16]; - - struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; + 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; }; @@ -193,6 +190,7 @@ extern struct nv30_state_entry nv30_state_zsa; extern struct nv30_state_entry nv30_state_viewport; extern struct nv30_state_entry nv30_state_framebuffer; extern struct nv30_state_entry nv30_state_fragtex; +extern struct nv30_state_entry nv30_state_vbo; /* nv30_vbo.c */ extern boolean nv30_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 9c57636989..de5590af14 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -57,7 +57,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param) return 13; case NOUVEAU_CAP_HW_VTXBUF: case NOUVEAU_CAP_HW_IDXBUF: - return 0; + return 1; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 4fe1def74d..4d6303ebc2 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -644,7 +644,10 @@ nv30_set_vertex_buffers(struct pipe_context *pipe, unsigned count, struct nv30_context *nv30 = nv30_context(pipe); memcpy(nv30->vtxbuf, vb, sizeof(*vb) * count); + nv30->vtxbuf_nr = count; + nv30->dirty |= NV30_NEW_ARRAYS; + /*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/ } static void @@ -654,7 +657,10 @@ nv30_set_vertex_elements(struct pipe_context *pipe, unsigned count, struct nv30_context *nv30 = nv30_context(pipe); memcpy(nv30->vtxelt, ve, sizeof(*ve) * count); + nv30->vtxelt_nr = count; + nv30->dirty |= NV30_NEW_ARRAYS; + /*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/ } static void diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 1e69a6a6e2..40fed621b2 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -13,6 +13,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_blend_colour, &nv30_state_zsa, &nv30_state_viewport, + &nv30_state_vbo, NULL }; @@ -39,10 +40,7 @@ nv30_state_do_validate(struct nv30_context *nv30, states++; } - -/* TODO: uncomment when finished converting nv30->dirty = 0; -*/ } void @@ -71,6 +69,8 @@ nv30_state_emit(struct nv30_context *nv30) states &= ~(1ULL << i); } + state->dirty = 0; + so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { if (!(samplers & (1 << i))) @@ -80,6 +80,8 @@ nv30_state_emit(struct nv30_context *nv30) samplers &= ~(1ULL << i); } so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FRAGPROG]); + if (state->hw[NV30_STATE_VTXBUF] /*&& nv30->render_mode == HW*/) + so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_VTXBUF]); } boolean diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index 0f82adfee0..d930557f6b 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -7,45 +7,119 @@ #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_pushbuf.h" +#include "nouveau/nouveau_util.h" + +#define FORCE_SWTNL 0 static INLINE int -nv30_vbo_ncomp(uint format) +nv30_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) { - int ncomp = 0; + 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 = NV34TCL_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 = NV34TCL_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 = NV34TCL_VTXFMT_TYPE_USHORT; + break; + default: + pf_sprint_name(fs, pipe); + NOUVEAU_ERR("Unknown format %s\n", fs); + return 1; + } - if (pf_size_x(format)) ncomp++; - if (pf_size_y(format)) ncomp++; - if (pf_size_z(format)) ncomp++; - if (pf_size_w(format)) ncomp++; + 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 ncomp; + return 0; } -static INLINE int -nv30_vbo_type(uint format) +static boolean +nv30_vbo_set_idxbuf(struct nv30_context *nv30, struct pipe_buffer *ib, + unsigned ib_size) { - switch (pf_type(format)) { - case PIPE_FORMAT_TYPE_FLOAT: - return NV34TCL_VTXFMT_TYPE_FLOAT; - case PIPE_FORMAT_TYPE_UNORM: - return NV34TCL_VTXFMT_TYPE_UBYTE; + struct pipe_screen *pscreen = &nv30->screen->pipe; + unsigned type; + + if (!ib) { + nv30->idxbuf = NULL; + nv30->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 = NV34TCL_IDXBUF_FORMAT_TYPE_U16; + break; + case 4: + type = NV34TCL_IDXBUF_FORMAT_TYPE_U32; + break; default: - NOUVEAU_ERR("Unknown format 0x%08x\n", format); - return NV34TCL_VTXFMT_TYPE_FLOAT; + return FALSE; } + + if (ib != nv30->idxbuf || + type != nv30->idxbuf_format) { + nv30->dirty |= NV30_NEW_ARRAYS; + nv30->idxbuf = ib; + nv30->idxbuf_format = type; + } + + return TRUE; } static boolean -nv30_vbo_static_attrib(struct nv30_context *nv30, int attrib, - struct pipe_vertex_element *ve, +nv30_vbo_static_attrib(struct nv30_context *nv30, struct nouveau_stateobj *so, + int attrib, struct pipe_vertex_element *ve, struct pipe_vertex_buffer *vb) { struct pipe_winsys *ws = nv30->pipe.winsys; - int type, ncomp; + struct nouveau_grobj *rankine = nv30->screen->rankine; + unsigned type, ncomp; void *map; - type = nv30_vbo_type(ve->src_format); - ncomp = nv30_vbo_ncomp(ve->src_format); + if (nv30_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; @@ -55,31 +129,28 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, int attrib, { 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]); + so_method(so, rankine, NV34TCL_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: - OUT_RINGf(v[0]); - OUT_RINGf(v[1]); - OUT_RINGf(v[2]); - OUT_RINGf(1.0); + so_method(so, rankine, NV34TCL_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: - OUT_RINGf(v[0]); - OUT_RINGf(v[1]); - OUT_RINGf(0.0); - OUT_RINGf(1.0); + so_method(so, rankine, NV34TCL_VTX_ATTR_2F_X(attrib), 2); + so_data (so, fui(v[0])); + so_data (so, fui(v[1])); break; case 1: - OUT_RINGf(v[0]); - OUT_RINGf(0.0); - OUT_RINGf(0.0); - OUT_RINGf(1.0); + so_method(so, rankine, NV34TCL_VTX_ATTR_1F(attrib), 1); + so_data (so, fui(v[0])); break; default: ws->buffer_unmap(ws, vb->buffer); @@ -97,209 +168,202 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, int attrib, return TRUE; } -static void -nv30_vbo_arrays_update(struct nv30_context *nv30) +boolean +nv30_draw_arrays(struct pipe_context *pipe, + unsigned mode, unsigned start, unsigned count) { - struct nv30_vertex_program *vp = nv30->vertprog; - uint32_t inputs, vtxfmt[16]; - int hw, num_hw = 0; - - nv30->vb_enable = 0; + struct nv30_context *nv30 = nv30_context(pipe); + struct nouveau_channel *chan = nv30->nvws->channel; + unsigned restart = 0; - inputs = vp->ir; - for (hw = 0; hw < 16 && inputs; hw++) { - if (inputs & (1 << hw)) { - num_hw = hw; - inputs &= ~(1 << hw); - } + nv30_vbo_set_idxbuf(nv30, NULL, 0); + if (FORCE_SWTNL || !nv30_state_validate(nv30)) { + /*return nv30_draw_elements_swtnl(pipe, NULL, 0, + mode, start, count);*/ + return FALSE; } - num_hw++; - inputs = vp->ir; - for (hw = 0; hw < num_hw; hw++) { - struct pipe_vertex_element *ve; - struct pipe_vertex_buffer *vb; + while (count) { + unsigned vc, nr; - if (!(inputs & (1 << hw))) { - vtxfmt[hw] = NV34TCL_VTXFMT_TYPE_FLOAT; + nv30_state_emit(nv30); + + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + mode, start, count, &restart); + if (!vc) { + FIRE_RING(NULL); continue; } - ve = &nv30->vtxelt[hw]; - vb = &nv30->vtxbuf[ve->vertex_buffer_index]; + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); - if (vb->pitch == 0) { - vtxfmt[hw] = NV34TCL_VTXFMT_TYPE_FLOAT; - if (nv30_vbo_static_attrib(nv30, hw, ve, vb) == TRUE) - continue; + nr = (vc & 0xff); + if (nr) { + BEGIN_RING(rankine, NV34TCL_VB_VERTEX_BATCH, 1); + OUT_RING (((nr - 1) << 24) | start); + start += nr; } - nv30->vb_enable |= (1 << hw); - nv30->vb[hw].delta = vb->buffer_offset + ve->src_offset; - nv30->vb[hw].buffer = vb->buffer; + nr = vc >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; + + nr -= push; - 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_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); + + count -= vc; + start = restart; } - BEGIN_RING(rankine, NV34TCL_VTXFMT(0), num_hw); - OUT_RINGp (vtxfmt, num_hw); + pipe->flush(pipe, 0, NULL); + return TRUE; } -static boolean -nv30_vbo_validate_state(struct nv30_context *nv30, - struct pipe_buffer *ib, unsigned ib_format) +static INLINE void +nv30_draw_elements_u08(struct nv30_context *nv30, void *ib, + unsigned mode, unsigned start, unsigned count) { - unsigned inputs; + struct nouveau_channel *chan = nv30->nvws->channel; - nv30_state_validate(nv30); + while (count) { + uint8_t *elts = (uint8_t *)ib + start; + unsigned vc, push, restart = 0; - nv30_state_emit(nv30); + nv30_state_emit(nv30); - if (nv30->dirty & NV30_NEW_ARRAYS) { - nv30_vbo_arrays_update(nv30); - nv30->dirty &= ~NV30_NEW_ARRAYS; - } + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2, + mode, start, count, &restart); + if (vc == 0) { + FIRE_RING(NULL); + continue; + } + count -= vc; - inputs = nv30->vb_enable; - while (inputs) { - unsigned a = ffs(inputs) - 1; + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); - inputs &= ~(1 << a); + if (vc & 1) { + BEGIN_RING(rankine, NV34TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; vc--; + } - 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); - } + while (vc) { + unsigned i; - 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); - } + push = MIN2(vc, 2047 * 2); - BEGIN_RING(rankine, 0x1710, 1); - OUT_RING (0); /* vtx cache flush */ + 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]); - return TRUE; -} + vc -= push; + elts += push; + } -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; + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (0); - ret = nv30_vbo_validate_state(nv30, NULL, 0); - if (!ret) { - NOUVEAU_ERR("state validate failed\n"); - return FALSE; + start = restart; } +} - 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; - } +static INLINE void +nv30_draw_elements_u16(struct nv30_context *nv30, void *ib, + unsigned mode, unsigned start, unsigned count) +{ + struct nouveau_channel *chan = nv30->nvws->channel; - nr = count >> 8; - while (nr) { - unsigned push = nr > 2047 ? 2047 : nr; + while (count) { + uint16_t *elts = (uint16_t *)ib + start; + unsigned vc, push, restart = 0; - nr -= push; + nv30_state_emit(nv30); - BEGIN_RING_NI(rankine, NV34TCL_VB_VERTEX_BATCH, push); - while (push--) { - OUT_RING(((0x100 - 1) << 24) | start); - start += 0x100; + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2, + mode, start, count, &restart); + if (vc == 0) { + FIRE_RING(NULL); + continue; } - } + count -= vc; - BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); - OUT_RING (0); + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); - pipe->flush(pipe, 0, NULL); - return TRUE; -} + if (vc & 1) { + BEGIN_RING(rankine, NV34TCL_VB_ELEMENT_U32, 1); + OUT_RING (elts[0]); + elts++; vc--; + } -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; + while (vc) { + unsigned i; - if (count & 1) { - BEGIN_RING(rankine, NV34TCL_VB_ELEMENT_U32, 1); - OUT_RING (elts[0]); - elts++; count--; - } + push = MIN2(vc, 2047 * 2); - 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]); - 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]); + vc -= push; + elts += push; + } + + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (0); - count -= push; - elts += push; + start = restart; } } static INLINE void -nv30_draw_elements_u16(struct nv30_context *nv30, void *ib, - unsigned start, unsigned count) +nv30_draw_elements_u32(struct nv30_context *nv30, void *ib, + unsigned mode, 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--; - } + struct nouveau_channel *chan = nv30->nvws->channel; while (count) { - push = MIN2(count, 2047 * 2); + uint32_t *elts = (uint32_t *)ib + start; + unsigned vc, push, restart = 0; - 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]); + nv30_state_emit(nv30); - count -= push; - elts += push; - } -} + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 5, 1, + mode, start, count, &restart); + if (vc == 0) { + FIRE_RING(NULL); + continue; + } + count -= vc; -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; + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); - while (count) { - push = MIN2(count, 2047); + while (vc) { + push = MIN2(vc, 2047); - BEGIN_RING_NI(rankine, NV34TCL_VB_ELEMENT_U32, push); - OUT_RINGp (elts, push); + BEGIN_RING_NI(rankine, NV34TCL_VB_ELEMENT_U32, push); + OUT_RINGp (elts, push); - count -= push; - elts += push; + vc -= push; + elts += push; + } + + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (0); + + start = restart; } } @@ -310,99 +374,82 @@ nv30_draw_elements_inline(struct pipe_context *pipe, { 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); + nv30_draw_elements_u08(nv30, map, mode, start, count); break; case 2: - nv30_draw_elements_u16(nv30, map, start, count); + nv30_draw_elements_u16(nv30, map, mode, start, count); break; case 4: - nv30_draw_elements_u32(nv30, map, start, count); + nv30_draw_elements_u32(nv30, map, mode, 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; - } + struct nouveau_channel *chan = nv30->nvws->channel; + unsigned restart = 0; - ret = nv30_vbo_validate_state(nv30, ib, type); - if (!ret) { - NOUVEAU_ERR("failed state validation\n"); - return FALSE; - } + while (count) { + unsigned nr, vc; - BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); - OUT_RING (nvgl_primitive(mode)); + nv30_state_emit(nv30); - nr = (count & 0xff); - if (nr) { - BEGIN_RING(rankine, NV34TCL_VB_INDEX_BATCH, 1); - OUT_RING (((nr - 1) << 24) | start); - start += nr; - } + vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + mode, start, count, &restart); + if (!vc) { + FIRE_RING(NULL); + continue; + } + + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (nvgl_primitive(mode)); + + nr = (vc & 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 = vc >> 8; + while (nr) { + unsigned push = nr > 2047 ? 2047 : nr; - nr -= push; + nr -= push; - BEGIN_RING_NI(rankine, NV34TCL_VB_INDEX_BATCH, push); - while (push--) { - OUT_RING(((0x100 - 1) << 24) | start); - start += 0x100; + 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); + BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1); + OUT_RING (0); + + count -= vc; + start = restart; + } return TRUE; } @@ -412,10 +459,19 @@ 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 */{ + struct nv30_context *nv30 = nv30_context(pipe); + boolean idxbuf; + + idxbuf = nv30_vbo_set_idxbuf(nv30, indexBuffer, indexSize); + if (FORCE_SWTNL || !nv30_state_validate(nv30)) { + /*return nv30_draw_elements_swtnl(pipe, NULL, 0, + mode, start, count);*/ + return FALSE; + } + + if (idxbuf) { + nv30_draw_elements_vbo(pipe, mode, start, count); + } else { nv30_draw_elements_inline(pipe, indexBuffer, indexSize, mode, start, count); } @@ -424,4 +480,82 @@ nv30_draw_elements(struct pipe_context *pipe, return TRUE; } +static boolean +nv30_vbo_validate(struct nv30_context *nv30) +{ + struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL; + struct nouveau_grobj *rankine = nv30->screen->rankine; + struct pipe_buffer *ib = nv30->idxbuf; + unsigned ib_format = nv30->idxbuf_format; + unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + int hw; + + if (nv30->edgeflags) { + /*nv30->fallback_swtnl |= NV30_NEW_ARRAYS;*/ + return FALSE; + } + + vtxbuf = so_new(20, 18); + so_method(vtxbuf, rankine, NV34TCL_VTXBUF_ADDRESS(0), nv30->vtxelt_nr); + vtxfmt = so_new(17, 0); + so_method(vtxfmt, rankine, NV34TCL_VTXFMT(0), nv30->vtxelt_nr); + for (hw = 0; hw < nv30->vtxelt_nr; hw++) { + struct pipe_vertex_element *ve; + struct pipe_vertex_buffer *vb; + unsigned type, ncomp; + + ve = &nv30->vtxelt[hw]; + vb = &nv30->vtxbuf[ve->vertex_buffer_index]; + + if (!vb->pitch) { + if (!sattr) + sattr = so_new(16 * 5, 0); + + if (nv30_vbo_static_attrib(nv30, sattr, hw, ve, vb)) { + so_data(vtxbuf, 0); + so_data(vtxfmt, NV34TCL_VTXFMT_TYPE_FLOAT); + continue; + } + } + + if (nv30_vbo_format_to_hw(ve->src_format, &type, &ncomp)) { + /*nv30->fallback_swtnl |= NV30_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, NV34TCL_VTXBUF_ADDRESS_DMA1); + so_data (vtxfmt, ((vb->pitch << NV34TCL_VTXFMT_STRIDE_SHIFT) | + (ncomp << NV34TCL_VTXFMT_SIZE_SHIFT) | type)); + } + + if (ib) { + so_method(vtxbuf, rankine, NV34TCL_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, NV34TCL_IDXBUF_FORMAT_DMA1); + } + + so_method(vtxbuf, rankine, 0x1710, 1); + so_data (vtxbuf, 0); + + so_ref(vtxbuf, &nv30->state.hw[NV30_STATE_VTXBUF]); + nv30->state.dirty |= (1ULL << NV30_STATE_VTXBUF); + so_ref(vtxfmt, &nv30->state.hw[NV30_STATE_VTXFMT]); + nv30->state.dirty |= (1ULL << NV30_STATE_VTXFMT); + so_ref(sattr, &nv30->state.hw[NV30_STATE_VTXATTR]); + nv30->state.dirty |= (1ULL << NV30_STATE_VTXATTR); + return FALSE; +} + +struct nv30_state_entry nv30_state_vbo = { + .validate = nv30_vbo_validate, + .dirty = { + .pipe = NV30_NEW_ARRAYS, + .hw = 0, + } +}; -- cgit v1.2.3 From a9863caefc9ed1ae098ea9033a82dbdc556edd30 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 13:59:01 +0200 Subject: nv30: do not shift texture format --- src/gallium/drivers/nv30/nv30_fragtex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index 8c5e88ea1d..4242f86f76 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -97,7 +97,7 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) if (!tf) assert(0); - txf = tf->format << 8; + txf = tf->format; txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0); txf |= log2i(pt->width[0]) << 20; txf |= log2i(pt->height[0]) << 24; -- cgit v1.2.3 From fa167eedeba601f3281655f779331ea9f4eaa5cf Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 13:59:24 +0200 Subject: nv30: update caps --- src/gallium/drivers/nv30/nv30_screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index de5590af14..54fc245bc6 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -32,7 +32,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return 16; case PIPE_CAP_NPOT_TEXTURES: - return 0; + return 1; case PIPE_CAP_TWO_SIDED_STENCIL: return 1; case PIPE_CAP_GLSL: @@ -75,7 +75,7 @@ nv30_screen_get_paramf(struct pipe_screen *pscreen, int param) case PIPE_CAP_MAX_POINT_WIDTH_AA: return 64.0; case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 16.0; + return 8.0; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 4.0; default: -- cgit v1.2.3 From 1d50e26f4afc0c7cdcd843a1336a90cdfc76765b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 12 Jul 2008 15:07:02 +0200 Subject: nv30: no npot textures --- src/gallium/drivers/nv30/nv30_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 54fc245bc6..b216a70318 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -32,7 +32,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return 16; case PIPE_CAP_NPOT_TEXTURES: - return 1; + return 0; case PIPE_CAP_TWO_SIDED_STENCIL: return 1; case PIPE_CAP_GLSL: -- cgit v1.2.3 From 8878d8d4b35c9550632f5684bdc97f3958bf43c5 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Thu, 10 Jul 2008 00:32:18 -0400 Subject: g3dvl: Minor SP winsys cleanup. --- src/gallium/winsys/g3dvl/xsp_winsys.c | 46 ++++++++++++++++++++++------------- src/libXvMC/block.c | 3 +-- 2 files changed, 30 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index d04c4be580..7c5c592fc7 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -62,6 +62,7 @@ static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, assert(buffer); xsp_buf->mapped_data = xsp_buf->data; + return xsp_buf->mapped_data; } @@ -131,8 +132,7 @@ static int xsp_surface_alloc_storage surface->nblocksy = pf_get_nblocksy(&surface->block, height); surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); surface->usage = flags; - /* XXX: Need to consider block dims? See xm_winsys.c */ - surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * height); + surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); return 0; } @@ -158,6 +158,29 @@ static void xsp_surface_release(struct pipe_winsys *pws, struct pipe_surface **s *surface = NULL; } +static void xsp_fence_reference(struct pipe_winsys *pws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence) +{ + assert(pws); + assert(ptr); + assert(fence); +} + +static int xsp_fence_signalled(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag) +{ + assert(pws); + assert(fence); + + return 0; +} + +static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag) +{ + assert(pws); + assert(fence); + + return 0; +} + static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) { struct xsp_pipe_winsys *xsp_winsys; @@ -196,22 +219,11 @@ static const char* xsp_get_name(struct pipe_winsys *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; @@ -226,6 +238,9 @@ struct pipe_context* create_pipe_context(Display *display) 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.fence_reference = xsp_fence_reference; + xsp_winsys->base.fence_signalled = xsp_fence_signalled; + xsp_winsys->base.fence_finish = xsp_fence_finish; xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer; xsp_winsys->base.get_name = xsp_get_name; xsp_winsys->display = display; @@ -253,12 +268,9 @@ struct pipe_context* create_pipe_context(Display *display) 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); + p_context = softpipe_create(p_screen, (struct pipe_winsys*)xsp_winsys, NULL); return p_context; } diff --git a/src/libXvMC/block.c b/src/libXvMC/block.c index b56348d464..deca305bdc 100644 --- a/src/libXvMC/block.c +++ b/src/libXvMC/block.c @@ -8,8 +8,7 @@ * 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. + * store them in 2 bytes in either case. */ #define BLOCK_SIZE (64 * 2) -- cgit v1.2.3 From c243573fafe8e83d4964535b201c499164d7c172 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 19 Jul 2008 16:22:56 -0400 Subject: g3dvl: Fix some memory leaks in the winsys. --- src/gallium/state_trackers/g3dvl/vl_context.c | 2 -- src/gallium/winsys/g3dvl/xsp_winsys.c | 26 +++++++++++++++++++++----- src/gallium/winsys/g3dvl/xsp_winsys.h | 1 + src/libXvMC/context.c | 5 ++++- 4 files changed, 26 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 1668ad1651..3d4ca7cf4e 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -2208,8 +2208,6 @@ int vlDestroyContext(struct VL_CONTEXT *context) vlDestroy(context); - context->pipe->destroy(context->pipe); - free(context); return 0; diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index 7c5c592fc7..c660c6e018 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -224,8 +224,8 @@ static const char* xsp_get_name(struct pipe_winsys *pws) struct pipe_context* create_pipe_context(Display *display) { struct xsp_pipe_winsys *xsp_winsys; - struct pipe_screen *p_screen; - struct pipe_context *p_context; + struct pipe_screen *screen; + struct pipe_context *pipe; assert(display); @@ -269,9 +269,25 @@ struct pipe_context* create_pipe_context(Display *display) XDestroyImage(template); } - p_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); - p_context = softpipe_create(p_screen, (struct pipe_winsys*)xsp_winsys, NULL); + screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); + pipe = softpipe_create(screen, (struct pipe_winsys*)xsp_winsys, NULL); - return p_context; + return pipe; +} + +int destroy_pipe_context(struct pipe_context *pipe) +{ + struct pipe_screen *screen; + struct pipe_winsys *winsys; + + assert(pipe); + + screen = pipe->screen; + winsys = pipe->winsys; + pipe->destroy(pipe); + screen->destroy(screen); + free(winsys); + + return 0; } diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.h b/src/gallium/winsys/g3dvl/xsp_winsys.h index 47a6ac6e25..cb163dc24d 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.h +++ b/src/gallium/winsys/g3dvl/xsp_winsys.h @@ -6,6 +6,7 @@ struct pipe_context; struct pipe_context* create_pipe_context(Display *display); +int destroy_pipe_context(struct pipe_context *pipe); #endif diff --git a/src/libXvMC/context.c b/src/libXvMC/context.c index c835a6acf7..e559002577 100644 --- a/src/libXvMC/context.c +++ b/src/libXvMC/context.c @@ -136,7 +136,8 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, i Status XvMCDestroyContext(Display *display, XvMCContext *context) { - struct VL_CONTEXT *vl_ctx; + struct VL_CONTEXT *vl_ctx; + struct pipe_context *pipe; assert(display); @@ -147,7 +148,9 @@ Status XvMCDestroyContext(Display *display, XvMCContext *context) assert(display == vl_ctx->display); + pipe = vl_ctx->pipe; vlDestroyContext(vl_ctx); + destroy_pipe_context(pipe); return Success; } -- cgit v1.2.3 From a3616067fee97f06fb52131ac13c39aeca6dc06a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 21 Jul 2008 19:05:55 +1000 Subject: nv50: add NV86 and NV94 to list of "supported" chips --- src/gallium/drivers/nv50/nv50_screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index bba5ca4d4e..2f3cf041d1 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -29,8 +29,8 @@ #include "nouveau/nouveau_stateobj.h" #define NV5X_GRCLASS5097_CHIPSETS 0x00000001 -#define NV8X_GRCLASS8297_CHIPSETS 0x00000010 -#define NV9X_GRCLASS8297_CHIPSETS 0x00000004 +#define NV8X_GRCLASS8297_CHIPSETS 0x00000050 +#define NV9X_GRCLASS8297_CHIPSETS 0x00000014 static boolean nv50_screen_is_format_supported(struct pipe_screen *pscreen, -- cgit v1.2.3 From 0c25ac52425e6d6eb037b99ab90f41b47e3f4491 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Tue, 22 Jul 2008 22:26:26 -0400 Subject: g3dvl: Add Nouveau winsys, libdriclient. Nouveau winsys is based on Mesa's Nouveau winsys and soft-links to most of it. The 'nouveau_context' and 'nouveau_screen' code contains most of the changes, 'nouveau_winsys_pipe', 'nouveau_swapbuffers' and 'nouveau_lock' contain some minor changes. The driclient library contains the DRI userland stuff, most of which was based on Mesa's DRI code. --- src/driclient/include/driclient.h | 98 ++++ src/driclient/include/xf86dri.h | 119 ++++ src/driclient/src/Makefile | 22 + src/driclient/src/XF86dri.c | 619 +++++++++++++++++++++ src/driclient/src/driclient.c | 292 ++++++++++ src/driclient/src/test | Bin 0 -> 68389 bytes src/driclient/src/test.c | 41 ++ src/driclient/src/xf86dri.h | 119 ++++ src/driclient/src/xf86dristr.h | 342 ++++++++++++ src/gallium/state_trackers/g3dvl/Makefile | 2 +- src/gallium/state_trackers/g3dvl/vl_context.c | 68 ++- src/gallium/state_trackers/g3dvl/vl_shader_build.c | 12 + src/gallium/state_trackers/g3dvl/vl_shader_build.h | 1 + src/gallium/state_trackers/g3dvl/vl_surface.c | 4 +- src/gallium/winsys/g3dvl/nouveau/Makefile | 46 ++ src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_context.c | 371 ++++++++++++ src/gallium/winsys/g3dvl/nouveau/nouveau_context.h | 105 ++++ src/gallium/winsys/g3dvl/nouveau/nouveau_device.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_local.h | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c | 92 +++ .../winsys/g3dvl/nouveau/nouveau_notifier.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c | 1 + .../winsys/g3dvl/nouveau/nouveau_resource.c | 1 + src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c | 88 +++ src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h | 24 + .../winsys/g3dvl/nouveau/nouveau_swapbuffers.c | 64 +++ .../winsys/g3dvl/nouveau/nouveau_swapbuffers.h | 10 + src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c | 1 + .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 261 +++++++++ .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.h | 1 + .../winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c | 1 + src/gallium/winsys/g3dvl/nouveau/nv04_surface.c | 1 + src/gallium/winsys/g3dvl/nouveau/nv50_surface.c | 1 + src/gallium/winsys/g3dvl/vl_winsys.h | 14 + src/gallium/winsys/g3dvl/xsp_winsys.c | 72 ++- src/gallium/winsys/g3dvl/xsp_winsys.h | 12 - src/libXvMC/Makefile | 19 +- src/libXvMC/context.c | 4 +- 46 files changed, 2896 insertions(+), 43 deletions(-) create mode 100644 src/driclient/include/driclient.h create mode 100644 src/driclient/include/xf86dri.h create mode 100644 src/driclient/src/Makefile create mode 100644 src/driclient/src/XF86dri.c create mode 100644 src/driclient/src/driclient.c create mode 100755 src/driclient/src/test create mode 100644 src/driclient/src/test.c create mode 100644 src/driclient/src/xf86dri.h create mode 100644 src/driclient/src/xf86dristr.h create mode 100644 src/gallium/winsys/g3dvl/nouveau/Makefile create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_context.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_context.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_device.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_local.h create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c create mode 100644 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h create mode 120000 src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nv04_surface.c create mode 120000 src/gallium/winsys/g3dvl/nouveau/nv50_surface.c create mode 100644 src/gallium/winsys/g3dvl/vl_winsys.h delete mode 100644 src/gallium/winsys/g3dvl/xsp_winsys.h (limited to 'src/gallium') diff --git a/src/driclient/include/driclient.h b/src/driclient/include/driclient.h new file mode 100644 index 0000000000..36438a9f79 --- /dev/null +++ b/src/driclient/include/driclient.h @@ -0,0 +1,98 @@ +#ifndef driclient_h +#define driclient_h + +#include +#include +#include +#include "xf86dri.h" + +/* TODO: Bring in DRI XML options */ + +typedef struct dri_version +{ + int major; + int minor; + int patch; +} dri_version_t; + +typedef struct dri_screen +{ + Display *display; + unsigned int num; + dri_version_t ddx, dri, drm; + int draw_lock_id; + int fd; + drm_sarea_t *sarea; + void *drawable_hash; + void *private; +} dri_screen_t; + +struct dri_context; + +typedef struct dri_drawable +{ + drm_drawable_t drm_drawable; + Drawable x_drawable; + unsigned int sarea_index; + unsigned int *sarea_stamp; + unsigned int last_sarea_stamp; + int x, y, w, h; + int back_x, back_y; + int num_cliprects, num_back_cliprects; + drm_clip_rect_t *cliprects, *back_cliprects; + dri_screen_t *dri_screen; + unsigned int refcount; + void *private; +} dri_drawable_t; + +typedef struct dri_context +{ + XID id; + drm_context_t drm_context; + dri_screen_t *dri_screen; + void *private; +} dri_context_t; + +typedef struct dri_framebuffer +{ + drm_handle_t drm_handle; + int base, size, stride; + int private_size; + void *private; +} dri_framebuffer_t; + +int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf); +int driDestroyScreen(dri_screen_t *dri_screen); +int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable); +int driUpdateDrawableInfo(dri_drawable_t *dri_drawable); +int driDestroyDrawable(dri_drawable_t *dri_drawable); +int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context); +int driDestroyContext(dri_context_t *dri_context); +int driCompareVersions(const dri_version_t *v1, const dri_version_t *v2); + +#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable) \ +do \ +{ \ + if (*(dri_drawable->sarea_stamp) != dri_drawable->last_sarea_stamp) \ + driUpdateDrawableInfo(dri_drawable); \ +} while (0) + +#define DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable) \ +do \ +{ \ + while (*(dri_drawable->sarea_stamp) != dri_drawable->last_sarea_stamp) \ + { \ + register unsigned int hwContext = dri_screen->sarea->lock.lock & \ + ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \ + DRM_UNLOCK(dri_screen->fd, &dri_screen->sarea->lock, hwContext); \ + \ + DRM_SPINLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id); \ + DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable); \ + DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id); \ + \ + DRM_LIGHT_LOCK(dri_screen->fd, &dri_screen->sarea->lock, hwContext); \ + } \ +} while (0) + +#endif + diff --git a/src/driclient/include/xf86dri.h b/src/driclient/include/xf86dri.h new file mode 100644 index 0000000000..baf80a7a9d --- /dev/null +++ b/src/driclient/include/xf86dri.h @@ -0,0 +1,119 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +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 PRECISION INSIGHT 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 xf86dri.h + * Protocol numbers and function prototypes for DRI X protocol. + * + * \author Kevin E. Martin + * \author Jens Owen + * \author Rickard E. (Rik) Faith + */ + +#ifndef _XF86DRI_H_ +#define _XF86DRI_H_ + +#include +#include + +#define X_XF86DRIQueryVersion 0 +#define X_XF86DRIQueryDirectRenderingCapable 1 +#define X_XF86DRIOpenConnection 2 +#define X_XF86DRICloseConnection 3 +#define X_XF86DRIGetClientDriverName 4 +#define X_XF86DRICreateContext 5 +#define X_XF86DRIDestroyContext 6 +#define X_XF86DRICreateDrawable 7 +#define X_XF86DRIDestroyDrawable 8 +#define X_XF86DRIGetDrawableInfo 9 +#define X_XF86DRIGetDeviceInfo 10 +#define X_XF86DRIAuthConnection 11 +#define X_XF86DRIOpenFullScreen 12 /* Deprecated */ +#define X_XF86DRICloseFullScreen 13 /* Deprecated */ + +#define XF86DRINumberEvents 0 + +#define XF86DRIClientNotLocal 0 +#define XF86DRIOperationNotSupported 1 +#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1) + +#ifndef _XF86DRI_SERVER_ + +_XFUNCPROTOBEGIN + +Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base ); + +Bool XF86DRIQueryVersion( Display *dpy, int *majorVersion, int *minorVersion, + int *patchVersion ); + +Bool XF86DRIQueryDirectRenderingCapable( Display *dpy, int screen, + Bool *isCapable ); + +Bool XF86DRIOpenConnection( Display *dpy, int screen, drm_handle_t *hSAREA, + char **busIDString ); + +Bool XF86DRIAuthConnection( Display *dpy, int screen, drm_magic_t magic ); + +Bool XF86DRICloseConnection( Display *dpy, int screen ); + +Bool XF86DRIGetClientDriverName( Display *dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName ); + +Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool XF86DRIDestroyContext( Display *dpy, int screen, + XID context_id ); + +Bool XF86DRICreateDrawable( Display *dpy, int screen, + Drawable drawable, drm_drawable_t *hHWDrawable ); + +Bool XF86DRIDestroyDrawable( Display *dpy, int screen, + Drawable drawable); + +Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t **pBackClipRects ); + +Bool XF86DRIGetDeviceInfo( Display *dpy, int screen, + drm_handle_t *hFrameBuffer, int *fbOrigin, int *fbSize, + int *fbStride, int *devPrivateSize, void **pDevPrivate ); + +_XFUNCPROTOEND + +#endif /* _XF86DRI_SERVER_ */ + +#endif /* _XF86DRI_H_ */ + diff --git a/src/driclient/src/Makefile b/src/driclient/src/Makefile new file mode 100644 index 0000000000..0fac552de5 --- /dev/null +++ b/src/driclient/src/Makefile @@ -0,0 +1,22 @@ +TARGET = libdriclient.a +OBJECTS = driclient.o XF86dri.o +DRMDIR ?= /usr + +CFLAGS += -g -Wall -fPIC -Werror -I../include -I${DRMDIR}/include -I${DRMDIR}/include/drm + +############################################# + +.PHONY = all clean + +all: ${TARGET} test + +${TARGET}: ${OBJECTS} + ar rcs $@ $^ + cp ${TARGET} ../lib + +test: test.o + $(CC) -L../lib -L${DRMDIR}/lib ${LDFLAGS} -o $@ $^ -ldriclient -lX11 -lXext -ldrm + +clean: + rm -rf ${OBJECTS} ${TARGET} test test.o + diff --git a/src/driclient/src/XF86dri.c b/src/driclient/src/XF86dri.c new file mode 100644 index 0000000000..9e359a9238 --- /dev/null +++ b/src/driclient/src/XF86dri.c @@ -0,0 +1,619 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +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 PRECISION INSIGHT 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Jens Owen + * Rickard E. (Rik) Faith + * + */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#define NEED_REPLIES +#include +#include +#include +#include "xf86dristr.h" + +static XExtensionInfo _xf86dri_info_data; +static XExtensionInfo *xf86dri_info = &_xf86dri_info_data; +static char xf86dri_extension_name[] = XF86DRINAME; + +#define XF86DRICheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xf86dri_extension_name, val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static int close_display(Display *dpy, XExtCodes *extCodes); +static /* const */ XExtensionHooks xf86dri_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info, + xf86dri_extension_name, + &xf86dri_extension_hooks, + 0, NULL) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info) + + +/***************************************************************************** + * * + * public XFree86-DRI Extension routines * + * * + *****************************************************************************/ + +#if 0 +#include +#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg); +#else +#define TRACE(msg) +#endif + +#define PUBLIC + +PUBLIC Bool XF86DRIQueryExtension (dpy, event_basep, error_basep) + Display *dpy; + int *event_basep, *error_basep; +{ + XExtDisplayInfo *info = find_display (dpy); + + TRACE("QueryExtension..."); + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + TRACE("QueryExtension... return True"); + return True; + } else { + TRACE("QueryExtension... return False"); + return False; + } +} + +PUBLIC Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion) + Display* dpy; + int* majorVersion; + int* minorVersion; + int* patchVersion; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIQueryVersionReply rep; + xXF86DRIQueryVersionReq *req; + + TRACE("QueryVersion..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryVersion; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return False"); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + *patchVersion = rep.patchVersion; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return True"); + return True; +} + +PUBLIC Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable) + Display* dpy; + int screen; + Bool* isCapable; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIQueryDirectRenderingCapableReply rep; + xXF86DRIQueryDirectRenderingCapableReq *req; + + TRACE("QueryDirectRenderingCapable..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIQueryDirectRenderingCapable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIQueryDirectRenderingCapable; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return False"); + return False; + } + *isCapable = rep.isCapable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return True"); + return True; +} + +PUBLIC Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString) + Display* dpy; + int screen; + drm_handle_t * hSAREA; + char **busIdString; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIOpenConnectionReply rep; + xXF86DRIOpenConnectionReq *req; + + TRACE("OpenConnection..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIOpenConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIOpenConnection; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + + *hSAREA = rep.hSAREALow; + if (sizeof(drm_handle_t) == 8) { + int shift = 32; /* var to prevent warning on next line */ + *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift; + } + + if (rep.length) { + if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) { + _XEatData(dpy, ((rep.busIdStringLength+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + _XReadPad(dpy, *busIdString, rep.busIdStringLength); + } else { + *busIdString = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return True"); + return True; +} + +PUBLIC Bool XF86DRIAuthConnection(dpy, screen, magic) + Display* dpy; + int screen; + drm_magic_t magic; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIAuthConnectionReq *req; + xXF86DRIAuthConnectionReply rep; + + TRACE("AuthConnection..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIAuthConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIAuthConnection; + req->screen = screen; + req->magic = magic; + rep.authenticated = 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return False"); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return True"); + return True; +} + +PUBLIC Bool XF86DRICloseConnection(dpy, screen) + Display* dpy; + int screen; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRICloseConnectionReq *req; + + TRACE("CloseConnection..."); + + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICloseConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICloseConnection; + req->screen = screen; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CloseConnection... return True"); + return True; +} + +PUBLIC Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, + ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName) + Display* dpy; + int screen; + int* ddxDriverMajorVersion; + int* ddxDriverMinorVersion; + int* ddxDriverPatchVersion; + char** clientDriverName; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIGetClientDriverNameReply rep; + xXF86DRIGetClientDriverNameReq *req; + + TRACE("GetClientDriverName..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetClientDriverName, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetClientDriverName; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + + *ddxDriverMajorVersion = rep.ddxDriverMajorVersion; + *ddxDriverMinorVersion = rep.ddxDriverMinorVersion; + *ddxDriverPatchVersion = rep.ddxDriverPatchVersion; + + if (rep.length) { + if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) { + _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength); + } else { + *clientDriverName = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return True"); + return True; +} + +PUBLIC Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context, + hHWContext) + Display* dpy; + int screen; + int configID; + XID* context; + drm_context_t * hHWContext; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRICreateContextReply rep; + xXF86DRICreateContextReq *req; + + TRACE("CreateContext..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateContext; + req->visual = configID; + req->screen = screen; + *context = XAllocID(dpy); + req->context = *context; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return False"); + return False; + } + *hHWContext = rep.hHWContext; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return True"); + return True; +} + +PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) + Display* dpy; + int screen; + Visual* visual; + XID* context; + drm_context_t * hHWContext; +{ + return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid, + context, hHWContext ); +} + +PUBLIC Bool XF86DRIDestroyContext( Display * ndpy, int screen, + XID context ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIDestroyContextReq *req; + + TRACE("DestroyContext..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyContext; + req->screen = screen; + req->context = context; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyContext... return True"); + return True; +} + +PUBLIC Bool XF86DRICreateDrawable( Display * ndpy, int screen, + Drawable drawable, drm_drawable_t * hHWDrawable ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xXF86DRICreateDrawableReply rep; + xXF86DRICreateDrawableReq *req; + + TRACE("CreateDrawable..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRICreateDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRICreateDrawable; + req->screen = screen; + req->drawable = drawable; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return False"); + return False; + } + *hHWDrawable = rep.hHWDrawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return True"); + return True; +} + +PUBLIC Bool XF86DRIDestroyDrawable( Display * ndpy, int screen, + Drawable drawable ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIDestroyDrawableReq *req; + + TRACE("DestroyDrawable..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIDestroyDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIDestroyDrawable; + req->screen = screen; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyDrawable... return True"); + return True; +} + +PUBLIC Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable, + unsigned int* index, unsigned int* stamp, + int* X, int* Y, int* W, int* H, + int* numClipRects, drm_clip_rect_t ** pClipRects, + int* backX, int* backY, + int* numBackClipRects, drm_clip_rect_t ** pBackClipRects ) +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIGetDrawableInfoReply rep; + xXF86DRIGetDrawableInfoReq *req; + int total_rects; + + TRACE("GetDrawableInfo..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDrawableInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDrawableInfo; + req->screen = screen; + req->drawable = drawable; + + if (!_XReply(dpy, (xReply *)&rep, 1, xFalse)) + { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } + *index = rep.drawableTableIndex; + *stamp = rep.drawableTableStamp; + *X = (int)rep.drawableX; + *Y = (int)rep.drawableY; + *W = (int)rep.drawableWidth; + *H = (int)rep.drawableHeight; + *numClipRects = rep.numClipRects; + total_rects = *numClipRects; + + *backX = rep.backX; + *backY = rep.backY; + *numBackClipRects = rep.numBackClipRects; + total_rects += *numBackClipRects; + +#if 0 + /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks + * backwards compatibility (Because of the >> 2 shift) but the fix + * enables multi-threaded apps to work. + */ + if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply) + + total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) { + _XEatData(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } +#endif + + if (*numClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numClipRects); + + *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1); + if (*pClipRects) + _XRead(dpy, (char*)*pClipRects, len); + } else { + *pClipRects = NULL; + } + + if (*numBackClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numBackClipRects); + + *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1); + if (*pBackClipRects) + _XRead(dpy, (char*)*pBackClipRects, len); + } else { + *pBackClipRects = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return True"); + return True; +} + +PUBLIC Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer, + fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate) + Display* dpy; + int screen; + drm_handle_t * hFrameBuffer; + int* fbOrigin; + int* fbSize; + int* fbStride; + int* devPrivateSize; + void** pDevPrivate; +{ + XExtDisplayInfo *info = find_display (dpy); + xXF86DRIGetDeviceInfoReply rep; + xXF86DRIGetDeviceInfoReq *req; + + TRACE("GetDeviceInfo..."); + XF86DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DRIGetDeviceInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_XF86DRIGetDeviceInfo; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + + *hFrameBuffer = rep.hFrameBufferLow; + if (sizeof(drm_handle_t) == 8) { + int shift = 32; /* var to prevent warning on next line */ + *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift; + } + + *fbOrigin = rep.framebufferOrigin; + *fbSize = rep.framebufferSize; + *fbStride = rep.framebufferStride; + *devPrivateSize = rep.devPrivateSize; + + if (rep.length) { + if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) { + _XEatData(dpy, ((rep.devPrivateSize+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize); + } else { + *pDevPrivate = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return True"); + return True; +} + +PUBLIC Bool XF86DRIOpenFullScreen(dpy, screen, drawable) + Display* dpy; + int screen; + Drawable drawable; +{ + /* This function and the underlying X protocol are deprecated. + */ + (void) dpy; + (void) screen; + (void) drawable; + return False; +} + +PUBLIC Bool XF86DRICloseFullScreen(dpy, screen, drawable) + Display* dpy; + int screen; + Drawable drawable; +{ + /* This function and the underlying X protocol are deprecated. + */ + (void) dpy; + (void) screen; + (void) drawable; + return True; +} + diff --git a/src/driclient/src/driclient.c b/src/driclient/src/driclient.c new file mode 100644 index 0000000000..7a7ca95702 --- /dev/null +++ b/src/driclient/src/driclient.c @@ -0,0 +1,292 @@ +#include "driclient.h" +#include +#include + +int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf) +{ + int evbase, errbase; + char *driver_name; + int newly_opened; + drm_magic_t magic; + drmVersionPtr drm_version; + drm_handle_t sarea_handle; + char *bus_id; + dri_screen_t *dri_scrn; + + assert(display); + assert(dri_screen); + + if (!XF86DRIQueryExtension(display, &evbase, &errbase)) + return 1; + + dri_scrn = calloc(1, sizeof(dri_screen_t)); + + if (!dri_scrn) + return 1; + + if (!XF86DRIQueryVersion(display, &dri_scrn->dri.major, &dri_scrn->dri.minor, &dri_scrn->dri.patch)) + goto free_screen; + + dri_scrn->display = display; + dri_scrn->num = screen; + dri_scrn->draw_lock_id = 1; + + if (!XF86DRIOpenConnection(display, screen, &sarea_handle, &bus_id)) + goto free_screen; + + dri_scrn->fd = -1; + dri_scrn->fd = drmOpenOnce(NULL, bus_id, &newly_opened); + XFree(bus_id); + + if (dri_scrn->fd < 0) + goto close_connection; + + if (drmGetMagic(dri_scrn->fd, &magic)) + goto close_drm; + + drm_version = drmGetVersion(dri_scrn->fd); + + if (!drm_version) + goto close_drm; + + dri_scrn->drm.major = drm_version->version_major; + dri_scrn->drm.minor = drm_version->version_minor; + dri_scrn->drm.patch = drm_version->version_patchlevel; + drmFreeVersion(drm_version); + + if (!XF86DRIAuthConnection(display, screen, magic)) + goto close_drm; + + if (!XF86DRIGetClientDriverName + ( + display, + screen, + &dri_scrn->ddx.major, + &dri_scrn->ddx.minor, + &dri_scrn->ddx.patch, + &driver_name + )) + goto close_drm; + + if (drmMap(dri_scrn->fd, sarea_handle, SAREA_MAX, (drmAddress)&dri_scrn->sarea)) + goto close_drm; + + dri_scrn->drawable_hash = drmHashCreate(); + + if (!dri_scrn->drawable_hash) + goto unmap_sarea; + + if (dri_framebuf) + { + if (!XF86DRIGetDeviceInfo + ( + display, + screen, &dri_framebuf->drm_handle, + &dri_framebuf->base, + &dri_framebuf->size, + &dri_framebuf->stride, + &dri_framebuf->private_size, + &dri_framebuf->private + )) + goto destroy_hash; + } + + *dri_screen = dri_scrn; + + return 0; + +destroy_hash: + drmHashDestroy(dri_scrn->drawable_hash); +unmap_sarea: + drmUnmap(dri_scrn->sarea, SAREA_MAX); +close_drm: + drmCloseOnce(dri_scrn->fd); +close_connection: + XF86DRICloseConnection(display, screen); +free_screen: + free(dri_scrn); + + return 1; +} + +int driDestroyScreen(dri_screen_t *dri_screen) +{ + assert(dri_screen); + + drmHashDestroy(dri_screen->drawable_hash); + drmUnmap(dri_screen->sarea, SAREA_MAX); + drmCloseOnce(dri_screen->fd); + XF86DRICloseConnection(dri_screen->display, dri_screen->num); + free(dri_screen); + + return 0; +} + +int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable) +{ + int evbase, errbase; + dri_drawable_t *dri_draw; + + assert(dri_screen); + assert(dri_drawable); + + if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase)) + return 1; + + if (!drmHashLookup(dri_screen->drawable_hash, drawable, (void**)dri_drawable)) + { + /* Found */ + (*dri_drawable)->refcount++; + return 0; + } + + dri_draw = calloc(1, sizeof(dri_drawable_t)); + + if (!dri_draw) + return 1; + + if (!XF86DRICreateDrawable(dri_screen->display, 0, drawable, &dri_draw->drm_drawable)) + { + free(dri_draw); + return 1; + } + + dri_draw->x_drawable = drawable; + dri_draw->sarea_index = 0; + dri_draw->sarea_stamp = NULL; + dri_draw->last_sarea_stamp = 0; + dri_draw->dri_screen = dri_screen; + dri_draw->refcount = 1; + + if (drmHashInsert(dri_screen->drawable_hash, drawable, dri_draw)) + { + XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable); + free(dri_draw); + return 1; + } + + /* + * XXX: Need this to initialize sarea pointer and other stuff in dri_drawable_t + * to be able to use the DRI_VALIDATE_DRAWABLE_INFO macro, but is it safe to + * call without any sync? + */ + if (driUpdateDrawableInfo(dri_draw)) + { + XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable); + free(dri_draw); + return 1; + } + + *dri_drawable = dri_draw; + + return 0; +} + +int driUpdateDrawableInfo(dri_drawable_t *dri_drawable) +{ + assert(dri_drawable); + + if (dri_drawable->cliprects) + XFree(dri_drawable->cliprects); + if (dri_drawable->back_cliprects) + XFree(dri_drawable->back_cliprects); + + DRM_SPINUNLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id); + + if (!XF86DRIGetDrawableInfo + ( + dri_drawable->dri_screen->display, + dri_drawable->dri_screen->num, + dri_drawable->x_drawable, + &dri_drawable->sarea_index, + &dri_drawable->last_sarea_stamp, + &dri_drawable->x, + &dri_drawable->y, + &dri_drawable->w, + &dri_drawable->h, + &dri_drawable->num_cliprects, + &dri_drawable->cliprects, + &dri_drawable->back_x, + &dri_drawable->back_y, + &dri_drawable->num_back_cliprects, + &dri_drawable->back_cliprects + )) + { + dri_drawable->sarea_stamp = &dri_drawable->last_sarea_stamp; + dri_drawable->num_cliprects = 0; + dri_drawable->cliprects = NULL; + dri_drawable->num_back_cliprects = 0; + dri_drawable->back_cliprects = 0; + + return 1; + } + else + dri_drawable->sarea_stamp = &dri_drawable->dri_screen->sarea->drawableTable[dri_drawable->sarea_index].stamp; + + DRM_SPINLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id); + + return 0; +} + +int driDestroyDrawable(dri_drawable_t *dri_drawable) +{ + assert(dri_drawable); + + if (--dri_drawable->refcount == 0) + { + if (dri_drawable->cliprects) + XFree(dri_drawable->cliprects); + if (dri_drawable->back_cliprects) + XFree(dri_drawable->back_cliprects); + drmHashDelete(dri_drawable->dri_screen->drawable_hash, dri_drawable->x_drawable); + XF86DRIDestroyDrawable(dri_drawable->dri_screen->display, dri_drawable->dri_screen->num, dri_drawable->x_drawable); + free(dri_drawable); + } + + return 0; +} + +int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context) +{ + int evbase, errbase; + dri_context_t *dri_ctx; + + assert(dri_screen); + assert(visual); + assert(dri_context); + + if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase)) + return 1; + + dri_ctx = calloc(1, sizeof(dri_context_t)); + + if (!dri_ctx) + return 1; + + if (!XF86DRICreateContext(dri_screen->display, dri_screen->num, visual, &dri_ctx->id, &dri_ctx->drm_context)) + { + free(dri_ctx); + return 1; + } + + dri_ctx->dri_screen = dri_screen; + *dri_context = dri_ctx; + + return 0; +} + +int driDestroyContext(dri_context_t *dri_context) +{ + assert(dri_context); + + XF86DRIDestroyContext(dri_context->dri_screen->display, dri_context->dri_screen->num, dri_context->id); + free(dri_context); + + return 0; +} + +int driCompareVersions(const dri_version_t *v1, const dri_version_t *v2) +{ + return (v1->major == v2->major) && (v1->minor == v2->minor) && (v1->patch == v2->patch); +} + diff --git a/src/driclient/src/test b/src/driclient/src/test new file mode 100755 index 0000000000..57cddf8e00 Binary files /dev/null and b/src/driclient/src/test differ diff --git a/src/driclient/src/test.c b/src/driclient/src/test.c new file mode 100644 index 0000000000..15f75d928b --- /dev/null +++ b/src/driclient/src/test.c @@ -0,0 +1,41 @@ +#include +#include +#include "driclient.h" + +int main(int argc, char **argv) +{ + Display *dpy; + Window root, window; + + dri_screen_t *screen; + dri_drawable_t *dri_drawable; + dri_context_t *context; + + dpy = XOpenDisplay(NULL); + root = XDefaultRootWindow(dpy); + window = XCreateSimpleWindow(dpy, root, 0, 0, 100, 100, 0, 0, 0); + + XSelectInput(dpy, window, 0); + XMapWindow(dpy, window); + XSync(dpy, 0); + + assert(driCreateScreen(dpy, 0, &screen, NULL) == 0); + assert(driCreateDrawable(screen, window, &dri_drawable) == 0); + assert(driCreateContext(screen, XDefaultVisual(dpy, 0), &context) == 0); + assert(driUpdateDrawableInfo(dri_drawable) == 0); + + DRI_VALIDATE_DRAWABLE_INFO(screen, dri_drawable); + + assert(drmGetLock(screen->fd, context->drm_context, 0) == 0); + assert(drmUnlock(screen->fd, context->drm_context) == 0); + + assert(driDestroyContext(context) == 0); + assert(driDestroyDrawable(dri_drawable) == 0); + assert(driDestroyScreen(screen) == 0); + + XDestroyWindow(dpy, window); + XCloseDisplay(dpy); + + return 0; +} + diff --git a/src/driclient/src/xf86dri.h b/src/driclient/src/xf86dri.h new file mode 100644 index 0000000000..baf80a7a9d --- /dev/null +++ b/src/driclient/src/xf86dri.h @@ -0,0 +1,119 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +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 PRECISION INSIGHT 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 xf86dri.h + * Protocol numbers and function prototypes for DRI X protocol. + * + * \author Kevin E. Martin + * \author Jens Owen + * \author Rickard E. (Rik) Faith + */ + +#ifndef _XF86DRI_H_ +#define _XF86DRI_H_ + +#include +#include + +#define X_XF86DRIQueryVersion 0 +#define X_XF86DRIQueryDirectRenderingCapable 1 +#define X_XF86DRIOpenConnection 2 +#define X_XF86DRICloseConnection 3 +#define X_XF86DRIGetClientDriverName 4 +#define X_XF86DRICreateContext 5 +#define X_XF86DRIDestroyContext 6 +#define X_XF86DRICreateDrawable 7 +#define X_XF86DRIDestroyDrawable 8 +#define X_XF86DRIGetDrawableInfo 9 +#define X_XF86DRIGetDeviceInfo 10 +#define X_XF86DRIAuthConnection 11 +#define X_XF86DRIOpenFullScreen 12 /* Deprecated */ +#define X_XF86DRICloseFullScreen 13 /* Deprecated */ + +#define XF86DRINumberEvents 0 + +#define XF86DRIClientNotLocal 0 +#define XF86DRIOperationNotSupported 1 +#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1) + +#ifndef _XF86DRI_SERVER_ + +_XFUNCPROTOBEGIN + +Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base ); + +Bool XF86DRIQueryVersion( Display *dpy, int *majorVersion, int *minorVersion, + int *patchVersion ); + +Bool XF86DRIQueryDirectRenderingCapable( Display *dpy, int screen, + Bool *isCapable ); + +Bool XF86DRIOpenConnection( Display *dpy, int screen, drm_handle_t *hSAREA, + char **busIDString ); + +Bool XF86DRIAuthConnection( Display *dpy, int screen, drm_magic_t magic ); + +Bool XF86DRICloseConnection( Display *dpy, int screen ); + +Bool XF86DRIGetClientDriverName( Display *dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName ); + +Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool XF86DRIDestroyContext( Display *dpy, int screen, + XID context_id ); + +Bool XF86DRICreateDrawable( Display *dpy, int screen, + Drawable drawable, drm_drawable_t *hHWDrawable ); + +Bool XF86DRIDestroyDrawable( Display *dpy, int screen, + Drawable drawable); + +Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t **pBackClipRects ); + +Bool XF86DRIGetDeviceInfo( Display *dpy, int screen, + drm_handle_t *hFrameBuffer, int *fbOrigin, int *fbSize, + int *fbStride, int *devPrivateSize, void **pDevPrivate ); + +_XFUNCPROTOEND + +#endif /* _XF86DRI_SERVER_ */ + +#endif /* _XF86DRI_H_ */ + diff --git a/src/driclient/src/xf86dristr.h b/src/driclient/src/xf86dristr.h new file mode 100644 index 0000000000..b834bd1a1a --- /dev/null +++ b/src/driclient/src/xf86dristr.h @@ -0,0 +1,342 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +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 PRECISION INSIGHT 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Jens Owen + * Rickard E. (Rik) Fiath + * + */ + +#ifndef _XF86DRISTR_H_ +#define _XF86DRISTR_H_ + +#include "xf86dri.h" + +#define XF86DRINAME "XFree86-DRI" + +/* The DRI version number. This was originally set to be the same of the + * XFree86 version number. However, this version is really indepedent of + * the XFree86 version. + * + * Version History: + * 4.0.0: Original + * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02 + * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02 + */ +#define XF86DRI_MAJOR_VERSION 4 +#define XF86DRI_MINOR_VERSION 1 +#define XF86DRI_PATCH_VERSION 0 + +typedef struct _XF86DRIQueryVersion { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIQueryVersion */ + CARD16 length B16; +} xXF86DRIQueryVersionReq; +#define sz_xXF86DRIQueryVersionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of DRI protocol */ + CARD16 minorVersion B16; /* minor version of DRI protocol */ + CARD32 patchVersion B32; /* patch version of DRI protocol */ + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIQueryVersionReply; +#define sz_xXF86DRIQueryVersionReply 32 + +typedef struct _XF86DRIQueryDirectRenderingCapable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIQueryDirectRenderingCapableReq; +#define sz_xXF86DRIQueryDirectRenderingCapableReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + BOOL isCapable; + BOOL pad2; + BOOL pad3; + BOOL pad4; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; + CARD32 pad9 B32; +} xXF86DRIQueryDirectRenderingCapableReply; +#define sz_xXF86DRIQueryDirectRenderingCapableReply 32 + +typedef struct _XF86DRIOpenConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIOpenConnectionReq; +#define sz_xXF86DRIOpenConnectionReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hSAREALow B32; + CARD32 hSAREAHigh B32; + CARD32 busIdStringLength B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xXF86DRIOpenConnectionReply; +#define sz_xXF86DRIOpenConnectionReply 32 + +typedef struct _XF86DRIAuthConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; + CARD32 magic B32; +} xXF86DRIAuthConnectionReq; +#define sz_xXF86DRIAuthConnectionReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 authenticated B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIAuthConnectionReply; +#define zx_xXF86DRIAuthConnectionReply 32 + +typedef struct _XF86DRICloseConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRICloseConnectionReq; +#define sz_xXF86DRICloseConnectionReq 8 + +typedef struct _XF86DRIGetClientDriverName { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetClientDriverName */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetClientDriverNameReq; +#define sz_xXF86DRIGetClientDriverNameReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 ddxDriverMajorVersion B32; + CARD32 ddxDriverMinorVersion B32; + CARD32 ddxDriverPatchVersion B32; + CARD32 clientDriverNameLength B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIGetClientDriverNameReply; +#define sz_xXF86DRIGetClientDriverNameReply 32 + +typedef struct _XF86DRICreateContext { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 visual B32; + CARD32 context B32; +} xXF86DRICreateContextReq; +#define sz_xXF86DRICreateContextReq 16 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWContext B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateContextReply; +#define sz_xXF86DRICreateContextReply 32 + +typedef struct _XF86DRIDestroyContext { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 context B32; +} xXF86DRIDestroyContextReq; +#define sz_xXF86DRIDestroyContextReq 12 + +typedef struct _XF86DRICreateDrawable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICreateDrawableReq; +#define sz_xXF86DRICreateDrawableReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWDrawable B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRICreateDrawableReply; +#define sz_xXF86DRICreateDrawableReply 32 + +typedef struct _XF86DRIDestroyDrawable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIDestroyDrawableReq; +#define sz_xXF86DRIDestroyDrawableReq 12 + +typedef struct _XF86DRIGetDrawableInfo { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDrawableInfo */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIGetDrawableInfoReq; +#define sz_xXF86DRIGetDrawableInfoReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 drawableTableIndex B32; + CARD32 drawableTableStamp B32; + INT16 drawableX B16; + INT16 drawableY B16; + INT16 drawableWidth B16; + INT16 drawableHeight B16; + CARD32 numClipRects B32; + INT16 backX B16; + INT16 backY B16; + CARD32 numBackClipRects B32; +} xXF86DRIGetDrawableInfoReply; + +#define sz_xXF86DRIGetDrawableInfoReply 36 + + +typedef struct _XF86DRIGetDeviceInfo { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDeviceInfo */ + CARD16 length B16; + CARD32 screen B32; +} xXF86DRIGetDeviceInfoReq; +#define sz_xXF86DRIGetDeviceInfoReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hFrameBufferLow B32; + CARD32 hFrameBufferHigh B32; + CARD32 framebufferOrigin B32; + CARD32 framebufferSize B32; + CARD32 framebufferStride B32; + CARD32 devPrivateSize B32; +} xXF86DRIGetDeviceInfoReply; +#define sz_xXF86DRIGetDeviceInfoReply 32 + +typedef struct _XF86DRIOpenFullScreen { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRIOpenFullScreenReq; +#define sz_xXF86DRIOpenFullScreenReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isFullScreen B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xXF86DRIOpenFullScreenReply; +#define sz_xXF86DRIOpenFullScreenReply 32 + +typedef struct _XF86DRICloseFullScreen { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xXF86DRICloseFullScreenReq; +#define sz_xXF86DRICloseFullScreenReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xXF86DRICloseFullScreenReply; +#define sz_xXF86DRICloseFullScreenReply 32 + + +#endif /* _XF86DRISTR_H_ */ diff --git a/src/gallium/state_trackers/g3dvl/Makefile b/src/gallium/state_trackers/g3dvl/Makefile index 50e3c843b5..c6a22cad4e 100644 --- a/src/gallium/state_trackers/g3dvl/Makefile +++ b/src/gallium/state_trackers/g3dvl/Makefile @@ -2,7 +2,7 @@ TARGET = libg3dvl.a OBJECTS = vl_context.o vl_data.o vl_surface.o vl_shader_build.o vl_util.o GALLIUMDIR = ../.. -CFLAGS += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary +CFLAGS += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary -I${GALLIUMDIR}/winsys/g3dvl ############################################# diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 3d4ca7cf4e..850a769376 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -330,6 +330,10 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -354,7 +358,7 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.i_vs = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -432,7 +436,7 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.i_fs = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } @@ -499,6 +503,10 @@ static int vlCreateVertexShaderFramePMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -527,7 +535,7 @@ static int vlCreateVertexShaderFramePMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.p_vs[0] = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -603,6 +611,10 @@ static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -643,7 +655,7 @@ static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.p_vs[1] = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -700,6 +712,10 @@ static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture @@ -761,7 +777,7 @@ static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.p_fs[0] = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } @@ -821,6 +837,10 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0-t4 */ + decl = vl_decl_temps(0, 4); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture @@ -928,7 +948,7 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.p_fs[1] = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } @@ -998,6 +1018,10 @@ static int vlCreateVertexShaderFrameBMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -1030,7 +1054,7 @@ static int vlCreateVertexShaderFrameBMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.b_vs[0] = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -1104,6 +1128,10 @@ static int vlCreateVertexShaderFieldBMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -1148,7 +1176,7 @@ static int vlCreateVertexShaderFieldBMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.b_vs[1] = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -1207,6 +1235,10 @@ static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0-t2 */ + decl = vl_decl_temps(0, 2); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture @@ -1283,7 +1315,7 @@ static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.b_fs[0] = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } @@ -1346,6 +1378,10 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0-t5 */ + decl = vl_decl_temps(0, 5); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture @@ -1479,7 +1515,7 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.b_fs[1] = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } @@ -1771,6 +1807,10 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* mov o0, i0 ; Move pos in to pos out */ inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_INPUT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -1789,7 +1829,7 @@ static int vlCreateVertexShaderCSC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.csc.vertex_shader = pipe->create_vs_state(pipe, &vs); - free(tokens); + //free(tokens); return 0; } @@ -1839,6 +1879,10 @@ static int vlCreateFragmentShaderCSC(struct VL_CONTEXT *context) decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl s0 ; Sampler for tex containing picture to display */ decl = vl_decl_samplers(0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1870,7 +1914,7 @@ static int vlCreateFragmentShaderCSC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.csc.fragment_shader = pipe->create_fs_state(pipe, &fs); - free(tokens); + //free(tokens); return 0; } diff --git a/src/gallium/state_trackers/g3dvl/vl_shader_build.c b/src/gallium/state_trackers/g3dvl/vl_shader_build.c index 365ad69725..1dc5be6fdb 100644 --- a/src/gallium/state_trackers/g3dvl/vl_shader_build.c +++ b/src/gallium/state_trackers/g3dvl/vl_shader_build.c @@ -74,6 +74,18 @@ struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int inde return decl; } +struct tgsi_full_declaration vl_decl_temps(unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + return decl; +} + struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int last) { struct tgsi_full_declaration decl = tgsi_default_full_declaration(); diff --git a/src/gallium/state_trackers/g3dvl/vl_shader_build.h b/src/gallium/state_trackers/g3dvl/vl_shader_build.h index 9e64bbeeae..878d7e2c45 100644 --- a/src/gallium/state_trackers/g3dvl/vl_shader_build.h +++ b/src/gallium/state_trackers/g3dvl/vl_shader_build.h @@ -14,6 +14,7 @@ struct tgsi_full_declaration vl_decl_interpolated_input ); struct tgsi_full_declaration vl_decl_constants(unsigned int name, unsigned int index, unsigned int first, unsigned int last); struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int index, unsigned int first, unsigned int last); +struct tgsi_full_declaration vl_decl_temps(unsigned int first, unsigned int last); struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int last); struct tgsi_full_instruction vl_inst2 ( diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 145ea32892..9b91ab4e22 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "vl_context.h" #include "vl_defs.h" #include "vl_util.h" @@ -711,12 +712,13 @@ int vlPutSurface 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); + bind_pipe_drawable(pipe, drawable); /* TODO: Need to take destx, desty into consideration */ pipe->winsys->flush_frontbuffer ( pipe->winsys, surface->context->states.csc.framebuffer.cbufs[0], - &drawable + pipe->priv ); vlBeginRender(surface->context); diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile new file mode 100644 index 0000000000..644ac083e6 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -0,0 +1,46 @@ +TARGET = libnouveau_dri.so +GALLIUMDIR = ../../.. +DRMDIR ?= /usr +DRIDIR = ../../../../driclient + +OBJECTS = nouveau_bo.o nouveau_fence.o nouveau_swapbuffers.o nouveau_channel.o \ + nouveau_grobj.o nouveau_context.o nouveau_winsys.o nouveau_lock.o \ + nouveau_winsys_pipe.o nouveau_device.o nouveau_notifier.o nouveau_dma.o \ + nouveau_pushbuf.o nouveau_resource.o nouveau_screen.o nv04_surface.o \ + nv50_surface.o #nouveau_winsys_softpipe.o + +CFLAGS += -g -Wall -Werror -fPIC \ + -I${GALLIUMDIR}/include \ + -I${GALLIUMDIR}/winsys/g3dvl \ + -I${DRMDIR}/include \ + -I${DRMDIR}/include/drm \ + -I${GALLIUMDIR}/drivers \ + -I${GALLIUMDIR}/auxiliary \ + -I${DRIDIR}/include + +LDFLAGS += -L${DRMDIR}/lib \ + -L${DRIDIR}/lib \ + -L${GALLIUMDIR}/auxiliary/draw \ + -L${GALLIUMDIR}/auxiliary/tgsi \ + -L${GALLIUMDIR}/auxiliary/translate \ + -L${GALLIUMDIR}/auxiliary/rtasm \ + -L${GALLIUMDIR}/auxiliary/cso_cache \ + -L${GALLIUMDIR}/drivers/nv10 \ + -L${GALLIUMDIR}/drivers/nv30 \ + -L${GALLIUMDIR}/drivers/nv40 \ + -L${GALLIUMDIR}/drivers/nv50 + +LIBS += -ldriclient -ldrm -lnv10 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm + +############################################# + +.PHONY = all clean + +all: ${TARGET} + +${TARGET}: ${OBJECTS} + $(CC) ${LDFLAGS} -shared -o $@ $^ ${LIBS} + +clean: + rm -rf ${OBJECTS} ${TARGET} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c new file mode 120000 index 0000000000..73ac4a4171 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_bo.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c new file mode 120000 index 0000000000..6c9b2c48d8 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_channel.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c new file mode 100644 index 0000000000..5e173c7672 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c @@ -0,0 +1,371 @@ +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_util.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 +*/ + +/* + * TODO: Re-examine dri_screen, dri_context, nouveau_screen, nouveau_context + * relationships, seems like there is a lot of room for simplification there. + */ + +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; +} + +int +nouveau_context_create(dri_context_t *dri_context) +{ + dri_screen_t *dri_screen = dri_context->dri_screen; + struct nouveau_screen *nv_screen = dri_screen->private; + struct nouveau_context *nv = CALLOC_STRUCT(nouveau_context); + struct pipe_context *pipe = NULL; + struct nouveau_channel_context *nvc = NULL; + struct nouveau_device *dev = nv_screen->device; + int i; + + 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 1; + } + + dri_context->private = (void*)nv; + nv->dri_context = dri_context; + nv->nv_screen = nv_screen; + + { + struct nouveau_device_priv *nvdev = nouveau_device(dev); + + nvdev->ctx = dri_context->drm_context; + nvdev->lock = (drmLock*)&dri_screen->sarea->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)); + if (nv_screen->front_cpp == 2) + fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; + else + fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; + pf_get_block(fb_surf->format, &fb_surf->block); + fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; + fb_surf->height = nv_screen->front_height; + fb_surf->stride = fb_surf->width * fb_surf->block.size; + fb_surf->refcount = 1; + fb_surf->buffer = &fb_buf->base; + + nv->frontbuffer = fb_surf; + } + + nvc = nv_screen->nvc; + + if (!nvc) { + nvc = nouveau_channel_context_create(dev); + if (!nvc) { + NOUVEAU_ERR("Failed initialising GPU context\n"); + return 1; + } + 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 1; + break; + default: + if (nouveau_surface_init_nv04(nv)) + return 1; + 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); + } + + /* XXX: nouveau_winsys_softpipe needs a mesa header removed before we can compile it. */ + /* + if (!pipe) { + NOUVEAU_MSG("Using softpipe\n"); + pipe = nouveau_create_softpipe(nv); + if (!pipe) { + NOUVEAU_ERR("Error creating pipe, bailing\n"); + return 1; + } + } + */ + if (!pipe) { + NOUVEAU_ERR("Error creating pipe, bailing\n"); + return 1; + } + + pipe->priv = nv; + + return 0; +} + +void +nouveau_context_destroy(dri_context_t *dri_context) +{ + struct nouveau_context *nv = dri_context->private; + struct nouveau_channel_context *nvc = nv->nvc; + + assert(nv); + + 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); +} + +int +nouveau_context_bind(struct nouveau_context *nv, dri_drawable_t *dri_drawable) +{ + assert(nv); + assert(dri_drawable); + + if (nv->dri_drawable != dri_drawable) + { + nv->dri_drawable = dri_drawable; + dri_drawable->private = nv; + } + + return 0; +} + +int +nouveau_context_unbind(struct nouveau_context *nv) +{ + assert(nv); + + nv->dri_drawable = NULL; + + return 0; +} + +/* Show starts here */ + +int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) +{ + struct nouveau_context *nv; + dri_drawable_t *dri_drawable; + + nv = pipe->priv; + + driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable); + + nouveau_context_bind(nv, dri_drawable); + + return 0; +} + +int unbind_pipe_drawable(struct pipe_context *pipe) +{ + nouveau_context_unbind(pipe->priv); + + return 0; +} + +struct pipe_context* create_pipe_context(Display *display, int screen) +{ + dri_screen_t *dri_screen; + dri_framebuffer_t dri_framebuf; + dri_context_t *dri_context; + struct nouveau_context *nv; + + driCreateScreen(display, screen, &dri_screen, &dri_framebuf); + driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context); + + nouveau_screen_create(dri_screen, &dri_framebuf); + nouveau_context_create(dri_context); + + nv = dri_context->private; + + return nv->nvc->pctx[nv->pctx_id]; +} + +int destroy_pipe_context(struct pipe_context *pipe) +{ + struct pipe_screen *screen; + struct pipe_winsys *winsys; + struct nouveau_context *nv; + dri_screen_t *dri_screen; + dri_context_t *dri_context; + + assert(pipe); + + screen = pipe->screen; + winsys = pipe->winsys; + nv = pipe->priv; + dri_context = nv->dri_context; + dri_screen = dri_context->dri_screen; + + pipe->destroy(pipe); + screen->destroy(screen); + free(winsys); + + nouveau_context_destroy(dri_context); + nouveau_screen_destroy(dri_screen); + driDestroyContext(dri_context); + driDestroyScreen(dri_screen); + + return 0; +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h new file mode 100644 index 0000000000..395a3ab790 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.h @@ -0,0 +1,105 @@ +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +/*#include "xmlconfig.h"*/ + +#include +#include "nouveau/nouveau_winsys.h" +#include "nouveau_drmif.h" +#include "nouveau_dma.h" + +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 { + /* DRI stuff */ + dri_context_t *dri_context; + dri_drawable_t *dri_drawable; + unsigned int last_stamp; + /*driOptionCache dri_option_cache;*/ + drm_context_t drm_context; + drmLock drm_lock; + int 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 int nouveau_context_create(dri_context_t *); +extern void nouveau_context_destroy(dri_context_t *); +extern int nouveau_context_bind(struct nouveau_context *, dri_drawable_t *); +extern int nouveau_context_unbind(struct nouveau_context *); + +#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/g3dvl/nouveau/nouveau_device.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c new file mode 120000 index 0000000000..47d52dafa8 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_device.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c new file mode 120000 index 0000000000..45078c964f --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_dma.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h new file mode 120000 index 0000000000..6b9ec77741 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_dma.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h new file mode 120000 index 0000000000..0e6c9fce35 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_dri.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h new file mode 120000 index 0000000000..473b7d4812 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_drmif.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c new file mode 120000 index 0000000000..ef1f0c6afe --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_fence.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c new file mode 120000 index 0000000000..428186544c --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_grobj.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h new file mode 120000 index 0000000000..6b878aad22 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_local.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c new file mode 100644 index 0000000000..375634bd05 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_lock.c @@ -0,0 +1,92 @@ +/************************************************************************** + * + * 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 +#include +#include "nouveau_context.h" +#include "nouveau_screen.h" + +static pthread_mutex_t lockMutex = PTHREAD_MUTEX_INITIALIZER; + +static void +nouveau_contended_lock(struct nouveau_context *nv, unsigned int flags) +{ + dri_drawable_t *dri_drawable = nv->dri_drawable; + dri_screen_t *dri_screen = nv->dri_context->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 (dri_drawable) + DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable); +} + +/* 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; + + pthread_mutex_lock(&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 = 1; +} + + +/* 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 = 0; + + DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); + + pthread_mutex_unlock(&lockMutex); +} diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c new file mode 120000 index 0000000000..3024a612a7 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_notifier.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c new file mode 120000 index 0000000000..dae31d9799 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_pushbuf.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c new file mode 120000 index 0000000000..e0d71e9d2b --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_resource.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c new file mode 100644 index 0000000000..0087ce0056 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c @@ -0,0 +1,88 @@ +#include "pipe/p_context.h" +#include "pipe/p_util.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 != 11 +#error nouveau_drm.h version does not match expected version +#endif + +/* +PUBLIC const char __driConfigOptions[] = +DRI_CONF_BEGIN +DRI_CONF_END; +static const GLuint __driNConfigOptions = 0; +*/ + +int +nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) +{ + /* XXX: Someone forgot to bump this? */ + static const dri_version_t ddx_expected = {0, 0, 10 /*NOUVEAU_DRM_HEADER_PATCHLEVEL*/}; + static const dri_version_t dri_expected = {4, 1, 0}; + static const dri_version_t drm_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; + + struct nouveau_dri *nv_dri = dri_framebuf->private; + struct nouveau_screen *nv_screen; + int ret; + + if (!driCompareVersions(&ddx_expected, &dri_screen->ddx)) + { + NOUVEAU_ERR("Unexpected DDX version.\n"); + return 1; + } + + if (!driCompareVersions(&drm_expected, &dri_screen->drm)) + { + NOUVEAU_ERR("Unexpected DRM version.\n"); + return 1; + } + + if (!driCompareVersions(&dri_expected, &dri_screen->dri)) + { + NOUVEAU_ERR("Unexpected DRI version.\n"); + return 1; + } + + if (dri_framebuf->private_size != sizeof(struct nouveau_dri)) { + NOUVEAU_ERR("DRI struct mismatch between DDX/DRI.\n"); + return 1; + } + + nv_screen = CALLOC_STRUCT(nouveau_screen); + if (!nv_screen) + return 1; + nv_screen->dri_screen = dri_screen; + dri_screen->private = (void*)nv_screen; + + /* + driParseOptionInfo(&nv_screen->option_cache, + __driConfigOptions, __driNConfigOptions); + */ + + if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, + dri_screen->fd, 0))) { + NOUVEAU_ERR("Failed opening nouveau device: %d.\n", ret); + return 1; + } + + 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 0; +} + +void +nouveau_screen_destroy(dri_screen_t *dri_screen) +{ + struct nouveau_screen *nv_screen = dri_screen->private; + + FREE(nv_screen); +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h new file mode 100644 index 0000000000..8a58bb7556 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.h @@ -0,0 +1,24 @@ +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +/* TODO: Investigate using DRI options for interesting things */ +/*#include "xmlconfig.h"*/ + +struct nouveau_screen { + dri_screen_t *dri_screen; + struct nouveau_device *device; + struct nouveau_channel_context *nvc; + + uint32_t front_offset; + uint32_t front_pitch; + uint32_t front_cpp; + uint32_t front_height; + + /*driOptionCache option_cache;*/ +}; + +int nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf); +void nouveau_screen_destroy(dri_screen_t *dri_screen); + +#endif + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c new file mode 100644 index 0000000000..7916c80615 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.c @@ -0,0 +1,64 @@ +#include "pipe/p_context.h" +#include "nouveau_context.h" +#include "nouveau_local.h" +#include "nouveau_screen.h" +#include "nouveau_swapbuffers.h" + +void +nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct nouveau_context *nv = dri_drawable->private; + drm_clip_rect_t *pbox; + int nbox, i; + + LOCK_HARDWARE(nv); + if (!dri_drawable->num_cliprects) { + UNLOCK_HARDWARE(nv); + return; + } + pbox = dri_drawable->cliprects; + nbox = dri_drawable->num_cliprects; + + 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 - dri_drawable->x; + sy = pbox->y1 - dri_drawable->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 != dri_drawable->last_sarea_stamp) + //nv->last_stamp = dri_drawable->last_sarea_stamp; +} + +void +nouveau_copy_sub_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, int x, int y, int w, int h) +{ + if (surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = x + w; + rect.y2 = y + h; + + nouveau_copy_buffer(dri_drawable, surf, &rect); + } +} + +void +nouveau_swap_buffers(dri_drawable_t *dri_drawable, struct pipe_surface *surf) +{ + if (surf) + nouveau_copy_buffer(dri_drawable, surf, NULL); +} + diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h new file mode 100644 index 0000000000..35e934adba --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_swapbuffers.h @@ -0,0 +1,10 @@ +#ifndef __NOUVEAU_SWAPBUFFERS_H__ +#define __NOUVEAU_SWAPBUFFERS_H__ + +extern void nouveau_copy_buffer(dri_drawable_t *, struct pipe_surface *, + const drm_clip_rect_t *); +extern void nouveau_copy_sub_buffer(dri_drawable_t *, struct pipe_surface *, + int x, int y, int w, int h); +extern void nouveau_swap_buffers(dri_drawable_t *, struct pipe_surface *); + +#endif diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c new file mode 120000 index 0000000000..43de49b98b --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_winsys.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c new file mode 100644 index 0000000000..b835bd5760 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -0,0 +1,261 @@ +#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; + dri_drawable_t *dri_drawable = nv->dri_drawable; + + nouveau_copy_buffer(dri_drawable, 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; +} + +/* Borrowed from Mesa's xm_winsys */ +static unsigned int +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +nouveau_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 = 256; + + assert(pws); + assert(surface); + + surface->width = width; + surface->height = height; + surface->format = format; + pf_get_block(format, &surface->block); + surface->nblocksx = pf_get_nblocksx(&surface->block, width); + surface->nblocksy = pf_get_nblocksy(&surface->block, height); + surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); + surface->usage = flags; + surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); + + return 0; +} + +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_alloc_storage = nouveau_surface_alloc_storage; + 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/g3dvl/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h new file mode 120000 index 0000000000..264716fef0 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_winsys_pipe.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c new file mode 120000 index 0000000000..83faccde96 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c @@ -0,0 +1 @@ +../../dri/nouveau/nouveau_winsys_softpipe.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c new file mode 120000 index 0000000000..e05f0671d6 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c @@ -0,0 +1 @@ +../../dri/nouveau/nv04_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c new file mode 120000 index 0000000000..3850748229 --- /dev/null +++ b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c @@ -0,0 +1 @@ +../../dri/nouveau/nv50_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h new file mode 100644 index 0000000000..c83db28dd9 --- /dev/null +++ b/src/gallium/winsys/g3dvl/vl_winsys.h @@ -0,0 +1,14 @@ +#ifndef vl_winsys_h +#define vl_winsys_h + +#include + +struct pipe_context; + +struct pipe_context* create_pipe_context(Display *display, int screen); +int destroy_pipe_context(struct pipe_context *pipe); +int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable); +int unbind_pipe_drawable(struct pipe_context *pipe); + +#endif + diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index c660c6e018..0100fe37bd 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -1,4 +1,4 @@ -#include "xsp_winsys.h" +#include "vl_winsys.h" #include #include #include @@ -11,10 +11,17 @@ struct xsp_pipe_winsys { struct pipe_winsys base; - Display *display; XImage fbimage; }; +struct xsp_context +{ + Display *display; + int screen; + Drawable drawable; + int drawable_bound; +}; + struct xsp_buffer { struct pipe_buffer base; @@ -183,13 +190,18 @@ static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *f static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) { - struct xsp_pipe_winsys *xsp_winsys; + struct xsp_pipe_winsys *xsp_winsys; + struct xsp_context *xsp_context; assert(pws); assert(surface); assert(context_private); xsp_winsys = (struct xsp_pipe_winsys*)pws; + xsp_context = (struct xsp_context*)context_private; + + if (!xsp_context->drawable_bound) + return; xsp_winsys->fbimage.width = surface->width; xsp_winsys->fbimage.height = surface->height; @@ -198,9 +210,9 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface * XPutImage ( - xsp_winsys->display, - *(Drawable*)context_private, - XDefaultGC(xsp_winsys->display, XDefaultScreen(xsp_winsys->display)), + xsp_context->display, + xsp_context->drawable, + XDefaultGC(xsp_context->display, xsp_context->screen), &xsp_winsys->fbimage, 0, 0, @@ -209,7 +221,7 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface * surface->width, surface->height ); - XFlush(xsp_winsys->display); + XFlush(xsp_context->display); pipe_surface_unmap(surface); } @@ -221,11 +233,37 @@ static const char* xsp_get_name(struct pipe_winsys *pws) /* Show starts here */ -struct pipe_context* create_pipe_context(Display *display) +int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) +{ + struct xsp_context *xsp_context; + + assert(pipe); + + xsp_context = pipe->priv; + xsp_context->drawable = drawable; + xsp_context->drawable_bound = 1; + + return 0; +} + +int unbind_pipe_drawable(struct pipe_context *pipe) +{ + struct xsp_context *xsp_context; + + assert(pipe); + + xsp_context = pipe->priv; + xsp_context->drawable_bound = 0; + + return 0; +} + +struct pipe_context* create_pipe_context(Display *display, int screen) { struct xsp_pipe_winsys *xsp_winsys; - struct pipe_screen *screen; - struct pipe_context *pipe; + struct xsp_context *xsp_context; + struct pipe_screen *sp_screen; + struct pipe_context *sp_pipe; assert(display); @@ -243,7 +281,6 @@ struct pipe_context* create_pipe_context(Display *display) xsp_winsys->base.fence_finish = xsp_fence_finish; 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, @@ -269,10 +306,16 @@ struct pipe_context* create_pipe_context(Display *display) XDestroyImage(template); } - screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); - pipe = softpipe_create(screen, (struct pipe_winsys*)xsp_winsys, NULL); + sp_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); + sp_pipe = softpipe_create(sp_screen, (struct pipe_winsys*)xsp_winsys, NULL); + + xsp_context = calloc(1, sizeof(struct xsp_context)); + xsp_context->display = display; + xsp_context->screen = screen; + + sp_pipe->priv = xsp_context; - return pipe; + return sp_pipe; } int destroy_pipe_context(struct pipe_context *pipe) @@ -284,6 +327,7 @@ int destroy_pipe_context(struct pipe_context *pipe) screen = pipe->screen; winsys = pipe->winsys; + free(pipe->priv); pipe->destroy(pipe); screen->destroy(screen); free(winsys); diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.h b/src/gallium/winsys/g3dvl/xsp_winsys.h deleted file mode 100644 index cb163dc24d..0000000000 --- a/src/gallium/winsys/g3dvl/xsp_winsys.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef xsp_winsys_h -#define xsp_winsys_h - -#include - -struct pipe_context; - -struct pipe_context* create_pipe_context(Display *display); -int destroy_pipe_context(struct pipe_context *pipe); - -#endif - diff --git a/src/libXvMC/Makefile b/src/libXvMC/Makefile index 4985ecd3e9..83fcfc523c 100644 --- a/src/libXvMC/Makefile +++ b/src/libXvMC/Makefile @@ -1,7 +1,12 @@ 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 + +OBJECTS = block.o surface.o context.o subpicture.o attributes.o + +ifeq (${DRIVER}, softpipe) +OBJECTS += ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o +endif CFLAGS += -g -fPIC -Wall -Werror \ -I${GALLIUMDIR}/state_trackers/g3dvl \ @@ -9,6 +14,8 @@ CFLAGS += -g -fPIC -Wall -Werror \ -I${GALLIUMDIR}/include \ -I${GALLIUMDIR}/auxiliary \ -I${GALLIUMDIR}/drivers + +ifeq (${DRIVER}, softpipe) LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \ -L${GALLIUMDIR}/drivers/softpipe \ -L${GALLIUMDIR}/auxiliary/tgsi \ @@ -17,7 +24,17 @@ LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \ -L${GALLIUMDIR}/auxiliary/cso_cache \ -L${GALLIUMDIR}/auxiliary/util \ -L${GALLIUMDIR}/auxiliary/rtasm +else +LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \ + -L${GALLIUMDIR}/winsys/g3dvl/nouveau \ + -L${GALLIUMDIR}/auxiliary/util +endif + +ifeq (${DRIVER}, softpipe) LIBS += -lg3dvl -lsoftpipe -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lutil -lm +else +LIBS += -lg3dvl -lnouveau_dri -lutil +endif ############################################# diff --git a/src/libXvMC/context.c b/src/libXvMC/context.c index 22eadc1889..59e1cb2b25 100644 --- a/src/libXvMC/context.c +++ b/src/libXvMC/context.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include static Status Validate(Display *display, XvPortID port, int surface_type_id, unsigned int width, unsigned int height, int flags, int *chroma_format) { @@ -117,7 +117,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, i if (ret != Success) return ret; - pipe = create_pipe_context(display); + pipe = create_pipe_context(display, XDefaultScreen(display)); assert(pipe); -- cgit v1.2.3 From 39793a262f055adf49e6bbd7b74728f744074e8e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 23 Jul 2008 14:14:55 +1000 Subject: nouveau: is_format_supported() interface changes --- src/gallium/drivers/nv04/nv04_screen.c | 15 ++++++--------- src/gallium/drivers/nv10/nv10_screen.c | 15 ++++++--------- src/gallium/drivers/nv30/nv30_screen.c | 15 ++++++--------- src/gallium/drivers/nv40/nv40_screen.c | 15 ++++++--------- src/gallium/drivers/nv50/nv50_screen.c | 13 +++++-------- 5 files changed, 29 insertions(+), 44 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c index 9f34117b8c..da09a3a5fe 100644 --- a/src/gallium/drivers/nv04/nv04_screen.c +++ b/src/gallium/drivers/nv04/nv04_screen.c @@ -79,10 +79,11 @@ nv04_screen_get_paramf(struct pipe_screen *screen, int param) static boolean nv04_screen_is_format_supported(struct pipe_screen *screen, - enum pipe_format format, uint type) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, unsigned geom_flags) { - switch (type) { - case PIPE_SURFACE: + if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: @@ -91,8 +92,7 @@ nv04_screen_is_format_supported(struct pipe_screen *screen, default: break; } - break; - case PIPE_TEXTURE: + } else { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_X8R8G8B8_UNORM: @@ -104,10 +104,7 @@ nv04_screen_is_format_supported(struct pipe_screen *screen, default: break; } - break; - default: - assert(0); - }; + } return FALSE; } diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index 67787d8e9c..403f7b98cd 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -82,10 +82,11 @@ nv10_screen_get_paramf(struct pipe_screen *screen, int param) static boolean nv10_screen_is_format_supported(struct pipe_screen *screen, - enum pipe_format format, uint type) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, unsigned geom_flags) { - switch (type) { - case PIPE_SURFACE: + if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: @@ -95,8 +96,7 @@ nv10_screen_is_format_supported(struct pipe_screen *screen, default: break; } - break; - case PIPE_TEXTURE: + } else { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: @@ -109,10 +109,7 @@ nv10_screen_is_format_supported(struct pipe_screen *screen, default: break; } - break; - default: - assert(0); - }; + } return FALSE; } diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index b216a70318..0ffcd77235 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -86,10 +86,11 @@ nv30_screen_get_paramf(struct pipe_screen *pscreen, int param) static boolean nv30_screen_surface_format_supported(struct pipe_screen *pscreen, - enum pipe_format format, uint type) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, unsigned geom_flags) { - switch (type) { - case PIPE_SURFACE: + if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: @@ -99,8 +100,7 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen, default: break; } - break; - case PIPE_TEXTURE: + } else { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: @@ -116,10 +116,7 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen, default: break; } - break; - default: - assert(0); - }; + } return FALSE; } diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index ed0215b486..3872c0a0c9 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -91,10 +91,11 @@ nv40_screen_get_paramf(struct pipe_screen *pscreen, int param) static boolean nv40_screen_surface_format_supported(struct pipe_screen *pscreen, - enum pipe_format format, uint type) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, unsigned geom_flags) { - switch (type) { - case PIPE_SURFACE: + if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: @@ -104,8 +105,7 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, default: break; } - break; - case PIPE_TEXTURE: + } else { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: @@ -125,10 +125,7 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, default: break; } - break; - default: - assert(0); - }; + } return FALSE; } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 2f3cf041d1..996b0b3e8f 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -34,10 +34,11 @@ static boolean nv50_screen_is_format_supported(struct pipe_screen *pscreen, - enum pipe_format format, uint type) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, unsigned geom_flags) { - switch (type) { - case PIPE_SURFACE: + if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: @@ -47,8 +48,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, default: break; } - break; - case PIPE_TEXTURE: + } else { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: @@ -62,9 +62,6 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, default: break; } - break; - default: - assert(0); } return FALSE; -- cgit v1.2.3 From b4d198e47704f3b79c5a61877846172ae9d4b4c0 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 23 Jul 2008 02:28:02 -0400 Subject: g3dvl: Minor fixes. --- src/driclient/include/driclient.h | 1 - src/driclient/src/.gitignore | 1 + src/driclient/src/Makefile | 1 + src/driclient/src/driclient.c | 5 --- src/driclient/src/test | Bin 68389 -> 0 bytes src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c | 42 ++++++++++++---------- 6 files changed, 25 insertions(+), 25 deletions(-) create mode 100644 src/driclient/src/.gitignore delete mode 100755 src/driclient/src/test (limited to 'src/gallium') diff --git a/src/driclient/include/driclient.h b/src/driclient/include/driclient.h index 36438a9f79..d391525039 100644 --- a/src/driclient/include/driclient.h +++ b/src/driclient/include/driclient.h @@ -68,7 +68,6 @@ int driUpdateDrawableInfo(dri_drawable_t *dri_drawable); int driDestroyDrawable(dri_drawable_t *dri_drawable); int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context); int driDestroyContext(dri_context_t *dri_context); -int driCompareVersions(const dri_version_t *v1, const dri_version_t *v2); #define DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable) \ do \ diff --git a/src/driclient/src/.gitignore b/src/driclient/src/.gitignore new file mode 100644 index 0000000000..9daeafb986 --- /dev/null +++ b/src/driclient/src/.gitignore @@ -0,0 +1 @@ +test diff --git a/src/driclient/src/Makefile b/src/driclient/src/Makefile index 0fac552de5..3c0fc28440 100644 --- a/src/driclient/src/Makefile +++ b/src/driclient/src/Makefile @@ -12,6 +12,7 @@ all: ${TARGET} test ${TARGET}: ${OBJECTS} ar rcs $@ $^ + if ! test -d ../lib; then mkdir ../lib; fi cp ${TARGET} ../lib test: test.o diff --git a/src/driclient/src/driclient.c b/src/driclient/src/driclient.c index 7a7ca95702..94d01aca4f 100644 --- a/src/driclient/src/driclient.c +++ b/src/driclient/src/driclient.c @@ -285,8 +285,3 @@ int driDestroyContext(dri_context_t *dri_context) return 0; } -int driCompareVersions(const dri_version_t *v1, const dri_version_t *v2) -{ - return (v1->major == v2->major) && (v1->minor == v2->minor) && (v1->patch == v2->patch); -} - diff --git a/src/driclient/src/test b/src/driclient/src/test deleted file mode 100755 index 57cddf8e00..0000000000 Binary files a/src/driclient/src/test and /dev/null differ diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c index 0087ce0056..daea3fff68 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c @@ -1,7 +1,7 @@ #include "pipe/p_context.h" #include "pipe/p_util.h" #include "nouveau_context.h" -#include "nouveau_drm.h" +#include #include "nouveau_dri.h" #include "nouveau_local.h" #include "nouveau_screen.h" @@ -18,40 +18,44 @@ DRI_CONF_END; static const GLuint __driNConfigOptions = 0; */ -int -nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) +int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_version_t *ddx) { - /* XXX: Someone forgot to bump this? */ - static const dri_version_t ddx_expected = {0, 0, 10 /*NOUVEAU_DRM_HEADER_PATCHLEVEL*/}; - static const dri_version_t dri_expected = {4, 1, 0}; + static const dri_version_t ddx_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; + static const dri_version_t dri_expected = {4, 0, 0}; static const dri_version_t drm_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; - struct nouveau_dri *nv_dri = dri_framebuf->private; - struct nouveau_screen *nv_screen; - int ret; + assert(dri); + assert(drm); + assert(ddx); - if (!driCompareVersions(&ddx_expected, &dri_screen->ddx)) + if (dri->major != dri_expected.major || dri->minor < dri_expected.minor) { - NOUVEAU_ERR("Unexpected DDX version.\n"); + NOUVEAU_ERR("Unexpected DRI version.\n"); return 1; } - - if (!driCompareVersions(&drm_expected, &dri_screen->drm)) + if (drm->major != drm_expected.major || drm->minor < drm_expected.minor) { NOUVEAU_ERR("Unexpected DRM version.\n"); return 1; } - - if (!driCompareVersions(&dri_expected, &dri_screen->dri)) + if (ddx->major != ddx_expected.major || ddx->minor < ddx_expected.minor) { - NOUVEAU_ERR("Unexpected DRI version.\n"); + NOUVEAU_ERR("Unexpected DDX version.\n"); return 1; } + + return 0; +} - if (dri_framebuf->private_size != sizeof(struct nouveau_dri)) { - NOUVEAU_ERR("DRI struct mismatch between DDX/DRI.\n"); +int +nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) +{ + struct nouveau_dri *nv_dri = dri_framebuf->private; + struct nouveau_screen *nv_screen; + int ret; + + if (nouveau_check_dri_drm_ddx(&dri_screen->dri, &dri_screen->drm, &dri_screen->ddx)) return 1; - } nv_screen = CALLOC_STRUCT(nouveau_screen); if (!nv_screen) -- cgit v1.2.3 From a8da04cb861b8f9caf3acd33f52f64621f0c15e2 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 23 Jul 2008 23:35:23 -0400 Subject: nv all: Copy shader tokens on create, free on delete. Must copy token stream on shader create, client is allowed to free their copy after creating the state object. --- src/gallium/drivers/nv04/nv04_state.c | 4 +++- src/gallium/drivers/nv04/nv04_state.h | 2 +- src/gallium/drivers/nv10/nv10_state.c | 4 +++- src/gallium/drivers/nv10/nv10_state.h | 2 +- src/gallium/drivers/nv30/nv30_state.c | 8 ++++++-- src/gallium/drivers/nv40/nv40_state.c | 8 ++++++-- src/gallium/drivers/nv50/nv50_state.c | 18 ++++++++++++------ src/gallium/state_trackers/g3dvl/vl_context.c | 20 ++++++++++---------- 8 files changed, 42 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c index d618465a20..7e71dee7b5 100644 --- a/src/gallium/drivers/nv04/nv04_state.c +++ b/src/gallium/drivers/nv04/nv04_state.c @@ -4,6 +4,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" #include "nv04_context.h" #include "nv04_state.h" @@ -291,7 +292,7 @@ nv04_fp_state_create(struct pipe_context *pipe, struct nv04_fragment_program *fp; fp = CALLOC(1, sizeof(struct nv04_fragment_program)); - fp->pipe = cso; + fp->pipe.tokens = tgsi_dup_tokens(cso->tokens); return (void *)fp; } @@ -313,6 +314,7 @@ nv04_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv04_fragment_program *fp = hwcso; nv04_fragprog_destroy(nv04, fp); + free((void*)fp->pipe.tokens); free(fp); } diff --git a/src/gallium/drivers/nv04/nv04_state.h b/src/gallium/drivers/nv04/nv04_state.h index 7487819c3a..39f7cd17b3 100644 --- a/src/gallium/drivers/nv04/nv04_state.h +++ b/src/gallium/drivers/nv04/nv04_state.h @@ -47,7 +47,7 @@ struct nv04_fragment_program_data { }; struct nv04_fragment_program { - const struct pipe_shader_state *pipe; + struct pipe_shader_state pipe; struct tgsi_shader_info info; boolean translated; diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 9b8b7801cd..43b9c32f12 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -4,6 +4,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" #include "nv10_context.h" #include "nv10_state.h" @@ -407,7 +408,7 @@ nv10_fp_state_create(struct pipe_context *pipe, struct nv10_fragment_program *fp; fp = CALLOC(1, sizeof(struct nv10_fragment_program)); - fp->pipe = cso; + fp->pipe.tokens = tgsi_dup_tokens(cso->tokens); tgsi_scan_shader(cso->tokens, &fp->info); @@ -431,6 +432,7 @@ nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv10_fragment_program *fp = hwcso; nv10_fragprog_destroy(nv10, fp); + FREE((void*)fp->pipe.tokens); FREE(fp); } diff --git a/src/gallium/drivers/nv10/nv10_state.h b/src/gallium/drivers/nv10/nv10_state.h index 3ca501d135..f1f9a12110 100644 --- a/src/gallium/drivers/nv10/nv10_state.h +++ b/src/gallium/drivers/nv10/nv10_state.h @@ -79,7 +79,7 @@ struct nv10_fragment_program_data { }; struct nv10_fragment_program { - const struct pipe_shader_state *pipe; + struct pipe_shader_state pipe; struct tgsi_shader_info info; boolean translated; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 4d6303ebc2..ba02413de5 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -3,6 +3,8 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "tgsi/util/tgsi_parse.h" + #include "nv30_context.h" #include "nv30_state.h" @@ -503,7 +505,7 @@ nv30_vp_state_create(struct pipe_context *pipe, struct nv30_vertex_program *vp; vp = CALLOC(1, sizeof(struct nv30_vertex_program)); - vp->pipe = *cso; + vp->pipe.tokens = tgsi_dup_tokens(cso->tokens); /*vp->draw = draw_create_vertex_shader(nv30->draw, &vp->pipe);*/ return (void *)vp; @@ -527,6 +529,7 @@ nv30_vp_state_delete(struct pipe_context *pipe, void *hwcso) /*draw_delete_vertex_shader(nv30->draw, vp->draw);*/ nv30_vertprog_destroy(nv30, vp); + FREE((void*)vp->pipe.tokens); FREE(vp); } @@ -537,7 +540,7 @@ nv30_fp_state_create(struct pipe_context *pipe, struct nv30_fragment_program *fp; fp = CALLOC(1, sizeof(struct nv30_fragment_program)); - fp->pipe = *cso; + fp->pipe.tokens = tgsi_dup_tokens(cso->tokens); tgsi_scan_shader(fp->pipe.tokens, &fp->info); @@ -560,6 +563,7 @@ nv30_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv30_fragment_program *fp = hwcso; nv30_fragprog_destroy(nv30, fp); + FREE((void*)fp->pipe.tokens); FREE(fp); } diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index afcf336a65..5d2c3ab881 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -5,6 +5,8 @@ #include "draw/draw_context.h" +#include "tgsi/util/tgsi_parse.h" + #include "nv40_context.h" #include "nv40_state.h" @@ -516,7 +518,7 @@ nv40_vp_state_create(struct pipe_context *pipe, struct nv40_vertex_program *vp; vp = CALLOC(1, sizeof(struct nv40_vertex_program)); - vp->pipe = *cso; + vp->pipe.tokens = tgsi_dup_tokens(cso->tokens); vp->draw = draw_create_vertex_shader(nv40->draw, &vp->pipe); return (void *)vp; @@ -540,6 +542,7 @@ nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso) draw_delete_vertex_shader(nv40->draw, vp->draw); nv40_vertprog_destroy(nv40, vp); + FREE((void*)vp->pipe.tokens); FREE(vp); } @@ -550,7 +553,7 @@ nv40_fp_state_create(struct pipe_context *pipe, struct nv40_fragment_program *fp; fp = CALLOC(1, sizeof(struct nv40_fragment_program)); - fp->pipe = *cso; + fp->pipe.tokens = tgsi_dup_tokens(cso->tokens); tgsi_scan_shader(fp->pipe.tokens, &fp->info); @@ -573,6 +576,7 @@ nv40_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv40_fragment_program *fp = hwcso; nv40_fragprog_destroy(nv40, fp); + FREE((void*)fp->pipe.tokens); FREE(fp); } diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index c552a0b0aa..731409bed4 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -25,6 +25,8 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "tgsi/util/tgsi_parse.h" + #include "nv50_context.h" #include "nv50_texture.h" @@ -438,7 +440,7 @@ nv50_vp_state_create(struct pipe_context *pipe, { struct nv50_program *p = CALLOC_STRUCT(nv50_program); - p->pipe = *cso; + p->pipe.tokens = tgsi_dup_tokens(cso->tokens); p->type = PIPE_SHADER_VERTEX; tgsi_scan_shader(p->pipe.tokens, &p->info); return (void *)p; @@ -457,9 +459,11 @@ static void nv50_vp_state_delete(struct pipe_context *pipe, void *hwcso) { struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_program *p = hwcso; - nv50_program_destroy(nv50, hwcso); - FREE(hwcso); + nv50_program_destroy(nv50, p); + FREE((void*)p->pipe.tokens); + FREE(p); } static void * @@ -468,7 +472,7 @@ nv50_fp_state_create(struct pipe_context *pipe, { struct nv50_program *p = CALLOC_STRUCT(nv50_program); - p->pipe = *cso; + p->pipe.tokens = tgsi_dup_tokens(cso->tokens); p->type = PIPE_SHADER_FRAGMENT; tgsi_scan_shader(p->pipe.tokens, &p->info); return (void *)p; @@ -487,9 +491,11 @@ static void nv50_fp_state_delete(struct pipe_context *pipe, void *hwcso) { struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_program *p = hwcso; - nv50_program_destroy(nv50, hwcso); - FREE(hwcso); + nv50_program_destroy(nv50, p); + FREE((void*)p->pipe.tokens); + FREE(p); } static void diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 850a769376..638900b3f4 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -358,7 +358,7 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.i_vs = pipe->create_vs_state(pipe, &vs); - //free(tokens); + free(tokens); return 0; } @@ -436,7 +436,7 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.i_fs = pipe->create_fs_state(pipe, &fs); - //free(tokens); + free(tokens); return 0; } @@ -535,7 +535,7 @@ static int vlCreateVertexShaderFramePMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.p_vs[0] = pipe->create_vs_state(pipe, &vs); - //free(tokens); + free(tokens); return 0; } @@ -655,7 +655,7 @@ static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.p_vs[1] = pipe->create_vs_state(pipe, &vs); - //free(tokens); + free(tokens); return 0; } @@ -777,7 +777,7 @@ static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.p_fs[0] = pipe->create_fs_state(pipe, &fs); - //free(tokens); + free(tokens); return 0; } @@ -948,7 +948,7 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.p_fs[1] = pipe->create_fs_state(pipe, &fs); - //free(tokens); + free(tokens); return 0; } @@ -1054,7 +1054,7 @@ static int vlCreateVertexShaderFrameBMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.b_vs[0] = pipe->create_vs_state(pipe, &vs); - //free(tokens); + free(tokens); return 0; } @@ -1176,7 +1176,7 @@ static int vlCreateVertexShaderFieldBMC(struct VL_CONTEXT *context) vs.tokens = tokens; context->states.mc.b_vs[1] = pipe->create_vs_state(pipe, &vs); - //free(tokens); + free(tokens); return 0; } @@ -1315,7 +1315,7 @@ static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.b_fs[0] = pipe->create_fs_state(pipe, &fs); - //free(tokens); + free(tokens); return 0; } @@ -1515,7 +1515,7 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) fs.tokens = tokens; context->states.mc.b_fs[1] = pipe->create_fs_state(pipe, &fs); - //free(tokens); + free(tokens); return 0; } -- cgit v1.2.3 From a17e6c046cd990f2ed4d0dfe9ed0a59bccd9aade Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 26 Jul 2008 16:51:09 -0400 Subject: g3dvl: Recursively build dependencies. Run `make` in src/libXvMC and everything should be built for Nouveau. Run `make DRIVER=softpipe` in src/libXvMC for SoftPipe. --- src/driclient/src/Makefile | 2 +- src/gallium/winsys/g3dvl/nouveau/Makefile | 2 ++ src/libXvMC/Makefile | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/driclient/src/Makefile b/src/driclient/src/Makefile index 3c0fc28440..89ffb84477 100644 --- a/src/driclient/src/Makefile +++ b/src/driclient/src/Makefile @@ -19,5 +19,5 @@ test: test.o $(CC) -L../lib -L${DRMDIR}/lib ${LDFLAGS} -o $@ $^ -ldriclient -lX11 -lXext -ldrm clean: - rm -rf ${OBJECTS} ${TARGET} test test.o + rm -rf ${OBJECTS} ${TARGET} ../lib/${TARGET} test test.o diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 644ac083e6..2861bd7db4 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -39,8 +39,10 @@ LIBS += -ldriclient -ldrm -lnv10 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate all: ${TARGET} ${TARGET}: ${OBJECTS} + cd ${DRIDIR}/src; ${MAKE} $(CC) ${LDFLAGS} -shared -o $@ $^ ${LIBS} clean: + cd ${DRIDIR}/src; ${MAKE} clean rm -rf ${OBJECTS} ${TARGET} diff --git a/src/libXvMC/Makefile b/src/libXvMC/Makefile index 83fcfc523c..c154e17dc3 100644 --- a/src/libXvMC/Makefile +++ b/src/libXvMC/Makefile @@ -42,9 +42,23 @@ endif all: ${TARGET} +ifeq (${DRIVER}, softpipe) +${TARGET}: ${OBJECTS} + cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE} + $(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ $^ ${LIBS} + +clean: + cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE} clean + rm -rf ${OBJECTS} ${TARGET} +else ${TARGET}: ${OBJECTS} + cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE} + cd ${GALLIUMDIR}/winsys/g3dvl/nouveau; ${MAKE} $(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ $^ ${LIBS} clean: + cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE} clean + cd ${GALLIUMDIR}/winsys/g3dvl/nouveau; ${MAKE} clean rm -rf ${OBJECTS} ${TARGET} +endif -- cgit v1.2.3 From 1d27b4bc0f291ec955e59b1ead943100d8a15505 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 30 Jul 2008 16:47:10 -0400 Subject: g3dvl: Use R16_SNORM instead of A8L8_UNORM for block rendering. --- src/gallium/state_trackers/g3dvl/vl_context.c | 248 ++++++++++++-------------- src/gallium/state_trackers/g3dvl/vl_data.c | 3 +- src/gallium/state_trackers/g3dvl/vl_surface.c | 178 ++++-------------- 3 files changed, 153 insertions(+), 276 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 638900b3f4..542ba996a7 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -365,7 +365,7 @@ static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) { - const unsigned int max_tokens = 50; + const unsigned int max_tokens = 100; struct pipe_context *pipe; struct pipe_shader_state fs; @@ -402,11 +402,19 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } + + /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* decl o0 ; Fragment color */ decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture @@ -419,16 +427,30 @@ static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) } /* - * 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 - */ + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i1, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_OUTPUT, 0, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* mul o0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* end */ inst = vl_end(); @@ -701,10 +723,7 @@ static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } - /* - * decl c0 ; Multiplier to shift 9th bit of differential into place - * decl c1 ; Bias to get differential back to a signed value - */ + /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -729,38 +748,29 @@ static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) } /* - * tex2d t0.xw, i0, s0 ; Read texel from luma texture into .x and .w channels - * mov t1.x, t0.w ; Move 9th bit 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 9th bit 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 9th bit from .w channel to .z + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i1, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); - inst.FullDstRegisters[0].DstRegister.WriteMask = (TGSI_WRITEMASK_X << i) | TGSI_WRITEMASK_W; + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - 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 9th bit by multiplier to shift it into place */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 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 normalized unsigned 9-bit values */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* sub t0, t0, c1 ; Subtract bias to get back signed values */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* tex2d t1, i2, s3 ; Read texel from ref macroblock */ @@ -826,11 +836,10 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) } /* - * decl c0 ; Multiplier to shift 9th bit of differential into place - * decl c1 ; Bias to get differential back to a signed value - * decl c2 ; Constants 1/2 & 2 in .x, .y channels for Y-mod-2 top/bottom field selection + * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm + * decl c1 ; Constants 1/2 & 2 in .x, .y channels for Y-mod-2 top/bottom field selection */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 2); + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* decl o0 ; Fragment color */ @@ -854,42 +863,35 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) } /* - * tex2d t0.xw, i0, s0 ; Read texel from luma texture into .x and .w channels - * mov t1.x, t0.w ; Move 9th bit 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 9th bit 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 9th bit from .w channel to .z + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i1, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); - inst.FullDstRegisters[0].DstRegister.WriteMask = (TGSI_WRITEMASK_X << i) | TGSI_WRITEMASK_W; + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - 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 9th bit by multiplier to shift it into place */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 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 normalized unsigned 9-bit values */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* sub t0, t0, c1 ; Subtract bias to get back signed values */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* tex2d t1, i2, s3 ; Read texel from ref macroblock top field - tex2d t2, i3, s3 ; Read texel from ref macroblock bottom field */ + /* + * tex2d t1, i2, s3 ; Read texel from ref macroblock top field + * tex2d t2, i3, s3 ; Read texel from ref macroblock bottom field + */ for (i = 0; i < 2; ++i) { inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 2, TGSI_FILE_SAMPLER, 3); @@ -897,8 +899,8 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) } /* XXX: Pos values off by 0.5? */ - /* sub t4, i4.y, c2.x ; Sub 0.5 from denormalized pos */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 4, TGSI_FILE_INPUT, 2); + /* sub t4, i4.y, c1.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 4, TGSI_FILE_CONSTANT, 1); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; @@ -909,8 +911,8 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* mul t3, t4, c2.x ; Multiply pos Y-coord by 1/2 */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 2); + /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1); inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; @@ -921,8 +923,8 @@ static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* mul t3, t3, c2.y ; Multiply by 2 */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 2); + /* mul t3, t3, c1.y ; Multiply by 2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1); inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; @@ -1224,11 +1226,10 @@ static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) } /* - * decl c0 ; Multiplier to shift 9th bit of differential into place - * decl c1 ; Bias to get differential back to a signed value - * decl c2 ; Constant 1/2 in .x channel to use as weight to blend past and future texels + * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm + * decl c1 ; Constant 1/2 in .x channel to use as weight to blend past and future texels */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 2); + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* decl o0 ; Fragment color */ @@ -1253,38 +1254,29 @@ static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) } /* - * tex2d t0.xw, i0, s0 ; Read texel from luma texture into .x and .w channels - * mov t1.x, t0.w ; Move 9th bit 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 9th bit 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 9th bit from .w channel to .z + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i1, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); - inst.FullDstRegisters[0].DstRegister.WriteMask = (TGSI_WRITEMASK_X << i) | TGSI_WRITEMASK_W; + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - 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 9th bit by multiplier to shift it into place */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 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 normalized unsigned 9-bit values */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* sub t0, t0, c1 ; Subtract bias to get back signed values */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* @@ -1297,8 +1289,8 @@ static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* lerp t1, c2.x, t1, t2 ; Blend past and future texels */ - inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 2, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; @@ -1366,12 +1358,11 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) } /* - * decl c0 ; Multiplier to shift 9th bit of differential into place - * decl c1 ; Bias to get differential back to a signed value - * decl c2 ; Constants 1/2 & 2 in .x, .y channels to use as weight to blend past and future texels + * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm + * decl c1 ; Constants 1/2 & 2 in .x, .y channels to use as weight to blend past and future texels * ; and for Y-mod-2 top/bottom field selection */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 2); + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* decl o0 ; Fragment color */ @@ -1396,43 +1387,34 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) } /* - * tex2d t0.xw, i0, s0 ; Read texel from luma texture into .x and .w channels - * mov t1.x, t0.w ; Move 9th bit 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 9th bit 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 9th bit from .w channel to .z + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i1, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); - inst.FullDstRegisters[0].DstRegister.WriteMask = (TGSI_WRITEMASK_X << i) | TGSI_WRITEMASK_W; + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - 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 9th bit by multiplier to shift it into place */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 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 normalized unsigned 9-bit values */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* sub t0, t0, c1 ; Subtract bias to get back signed values */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* XXX: Pos values off by 0.5? */ - /* sub t4, i6.y, c2.x ; Sub 0.5 from denormalized pos */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 6, TGSI_FILE_CONSTANT, 2); + /* sub t4, i6.y, c1.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 6, TGSI_FILE_CONSTANT, 1); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; @@ -1443,8 +1425,8 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* mul t3, t4, c2.x ; Multiply pos Y-coord by 1/2 */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 2); + /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1); inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; @@ -1455,8 +1437,8 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* mul t3, t3, c2.y ; Multiply by 2 */ - inst = vl_inst3( TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 2); + /* mul t3, t3, c1.y ; Multiply by 2 */ + inst = vl_inst3( TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1); inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; @@ -1497,8 +1479,8 @@ static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 2, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 5); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* lerp t1, c2.x, t1, t2 ; Blend past and future texels */ - inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 2, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; @@ -1678,7 +1660,7 @@ static int vlInitMC(struct VL_CONTEXT *context) memset(&template, 0, sizeof(struct pipe_texture)); template.target = PIPE_TEXTURE_2D; - template.format = PIPE_FORMAT_A8L8_UNORM; + template.format = PIPE_FORMAT_R16_SNORM; template.last_level = 0; template.width[0] = 8; template.height[0] = 8 * 4; diff --git a/src/gallium/state_trackers/g3dvl/vl_data.c b/src/gallium/state_trackers/g3dvl/vl_data.c index 7e6ee8ac12..0e5c8c77f9 100644 --- a/src/gallium/state_trackers/g3dvl/vl_data.c +++ b/src/gallium/state_trackers/g3dvl/vl_data.c @@ -86,8 +86,7 @@ const struct VL_TEXCOORD2F *vl_surface_texcoords = (const struct VL_TEXCOORD2F*) */ 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}, + {32767.0f / 255.0f, 32767.0f / 255.0f, 32767.0f / 255.0f, 0.0f}, {0.5f, 2.0f, 0.0f, 0.0f} }; diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 9b91ab4e22..6d4e14b95c 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -63,7 +63,7 @@ static int vlTransformBlock(short *src, short *dst, short bias) return 0; } -static int vlGrabFrameCodedFullBlock(short *src, short *dst, unsigned int dst_pitch) +static int vlGrabFrameCodedBlock(short *src, short *dst, unsigned int dst_pitch) { unsigned int y; @@ -78,18 +78,7 @@ static int vlGrabFrameCodedFullBlock(short *src, short *dst, unsigned int dst_pi return 0; } -static int vlGrabFrameCodedDiffBlock(short *src, short *dst, unsigned int dst_pitch) -{ - unsigned int x, y; - - for (y = 0; y < VL_BLOCK_HEIGHT; ++y) - for (x = 0; x < VL_BLOCK_WIDTH; ++x) - dst[y * dst_pitch + x] = src[y * VL_BLOCK_WIDTH + x] + 0x100; - - return 0; -} - -static int vlGrabFieldCodedFullBlock(short *src, short *dst, unsigned int dst_pitch) +static int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst_pitch) { unsigned int y; @@ -114,30 +103,17 @@ static int vlGrabFieldCodedFullBlock(short *src, short *dst, unsigned int dst_pi return 0; } -static int vlGrabFieldCodedDiffBlock(short *src, short *dst, unsigned int dst_pitch) -{ - unsigned int x, y; - - for (y = 0; y < VL_BLOCK_HEIGHT / 2; ++y) - for (x = 0; x < VL_BLOCK_WIDTH; ++x) - dst[y * dst_pitch * 2 + x] = src[y * VL_BLOCK_WIDTH + x] + 0x100; - - dst += VL_BLOCK_HEIGHT * dst_pitch; - - for (; y < VL_BLOCK_HEIGHT; ++y) - for (x = 0; x < VL_BLOCK_WIDTH; ++x) - dst[y * dst_pitch * 2 + x] = src[y * VL_BLOCK_WIDTH + x] + 0x100; - - return 0; -} - static int vlGrabNoBlock(short *dst, unsigned int dst_pitch) { - unsigned int x, y; + unsigned int y; for (y = 0; y < VL_BLOCK_HEIGHT; ++y) - for (x = 0; x < VL_BLOCK_WIDTH; ++x) - dst[y * dst_pitch + x] = 0x100; + memset + ( + dst + y * dst_pitch, + 0, + VL_BLOCK_WIDTH * 2 + ); return 0; } @@ -156,7 +132,6 @@ static int vlGrabBlocks unsigned int tex_pitch; unsigned int tb, sb = 0; - const int do_idct = 1; short temp_block[64]; assert(context); @@ -176,80 +151,26 @@ static int vlGrabBlocks { if ((coded_block_pattern >> (5 - tb)) & 1) { + if (sample_type == VL_FULL_SAMPLE) + vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 128); + else + vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 0); + if (dct_type == VL_DCT_FRAME_CODED) - if (sample_type == VL_FULL_SAMPLE) - if (do_idct) - { - vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 128); - vlGrabFrameCodedFullBlock - ( - temp_block, - texels + tb * tex_pitch * VL_BLOCK_HEIGHT, - tex_pitch - ); - } - else - vlGrabFrameCodedFullBlock - ( - blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, - texels + tb * tex_pitch * VL_BLOCK_HEIGHT, - tex_pitch - ); - else - if (do_idct) - { - vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 0); - vlGrabFrameCodedDiffBlock - ( - temp_block, - texels + tb * tex_pitch * VL_BLOCK_HEIGHT, - tex_pitch - ); - } - else - vlGrabFrameCodedDiffBlock - ( - blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, - texels + tb * tex_pitch * VL_BLOCK_HEIGHT, - tex_pitch - ); + vlGrabFrameCodedBlock + ( + temp_block, + texels + tb * tex_pitch * VL_BLOCK_HEIGHT, + tex_pitch + ); else - if (sample_type == VL_FULL_SAMPLE) - if (do_idct) - { - vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 128); - vlGrabFieldCodedFullBlock - ( - temp_block, - texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, - tex_pitch - ); - } - else - vlGrabFieldCodedFullBlock - ( - blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, - texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, - tex_pitch - ); - else - if (do_idct) - { - vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 0); - vlGrabFieldCodedDiffBlock - ( - temp_block, - texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, - tex_pitch - ); - } - else - vlGrabFieldCodedDiffBlock - ( - blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, - texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, - tex_pitch - ); + vlGrabFieldCodedBlock + ( + blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, + texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, + tex_pitch + ); + ++sb; } else @@ -272,43 +193,18 @@ static int vlGrabBlocks tex_pitch = tex_surface->stride / tex_surface->block.size; if ((coded_block_pattern >> (1 - tb)) & 1) - { + { if (sample_type == VL_FULL_SAMPLE) - if (do_idct) - { - vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 128); - vlGrabFrameCodedFullBlock - ( - temp_block, - texels, - tex_pitch - ); - } - else - vlGrabFrameCodedFullBlock - ( - blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, - texels, - tex_pitch - ); + vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 128); else - if (do_idct) - { - vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 0); - vlGrabFrameCodedDiffBlock - ( - temp_block, - texels, - tex_pitch - ); - } - else - vlGrabFrameCodedDiffBlock - ( - blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, - texels, - tex_pitch - ); + vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 0); + + vlGrabFrameCodedBlock + ( + temp_block, + texels, + tex_pitch + ); ++sb; } -- cgit v1.2.3 From a55ced56760f90fe84794b23c557050403d514b2 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 3 Aug 2008 17:20:48 -0400 Subject: nv40: Support for PIPE_FORMAT_R16_SNORM. --- src/gallium/drivers/nouveau/nouveau_class.h | 1 + src/gallium/drivers/nv40/nv40_fragtex.c | 36 ++++++++++++++++------------- src/gallium/drivers/nv40/nv40_screen.c | 3 ++- 3 files changed, 23 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h index 749fbf041e..c3d8d7539d 100644 --- a/src/gallium/drivers/nouveau/nouveau_class.h +++ b/src/gallium/drivers/nouveau/nouveau_class.h @@ -5194,6 +5194,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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_A16 0x00001400 #define NV40TCL_TEX_FORMAT_FORMAT_HILO8 0x00001800 #define NV40TCL_TEX_FORMAT_FORMAT_RGBA16F 0x00001a00 #define NV40TCL_TEX_FORMAT_FORMAT_RGBA32F 0x00001b00 diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index c79ea8becb..2d45c2545c 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -1,6 +1,6 @@ #include "nv40_context.h" -#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \ +#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw) \ { \ TRUE, \ PIPE_FORMAT_##m, \ @@ -9,6 +9,8 @@ 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), \ + ((NV40TCL_TEX_FILTER_SIGNED_RED*sx) | (NV40TCL_TEX_FILTER_SIGNED_GREEN*sy) | \ + (NV40TCL_TEX_FILTER_SIGNED_BLUE*sz) | (NV40TCL_TEX_FILTER_SIGNED_ALPHA*sw)) \ } struct nv40_texture_format { @@ -16,24 +18,26 @@ struct nv40_texture_format { uint pipe; int format; int swizzle; + int sign; }; 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), + _(A8R8G8B8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), + _(A1R5G5B5_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), + _(A4R4G4B4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), + _(R5G6B5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W, 0, 0, 0, 0), + _(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X, 0, 0, 0, 0), + _(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X, 0, 0, 0, 0), + _(R16_SNORM , A16 , ZERO, ZERO, S1, ONE, X, X, X, Y, 1, 1, 1, 1), + _(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X, 0, 0, 0, 0), + _(A8L8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y, 0, 0, 0, 0), + _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X, 0, 0, 0, 0), + _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X, 0, 0, 0, 0), + _(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W, 0, 0, 0, 0), + _(DXT1_RGBA , DXT1 , S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), + _(DXT3_RGBA , DXT3 , S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), + _(DXT5_RGBA , DXT5 , S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0), {}, }; @@ -113,7 +117,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) 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, ps->filt | tf->sign | 0x2000 /*voodoo*/); so_data (so, (pt->width[0] << NV40TCL_TEX_SIZE0_W_SHIFT) | pt->height[0]); so_data (so, ps->bcol); diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 3872c0a0c9..a63a6136c5 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -110,7 +110,8 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_R16_SNORM: case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: -- cgit v1.2.3 From 7fde9febd6f212494730ebef916fe25c95d30be9 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 3 Aug 2008 18:21:13 -0400 Subject: g3dvl: Temporarily disable IDCT. --- src/gallium/state_trackers/g3dvl/vl_context.c | 4 ++-- src/gallium/state_trackers/g3dvl/vl_surface.c | 30 +++++++++++++++------------ 2 files changed, 19 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 542ba996a7..d446d218a4 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -1625,8 +1625,8 @@ static int vlInitMC(struct VL_CONTEXT *context) 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.width = vlRoundUpPOT(context->video_width); + context->states.mc.render_target.height = vlRoundUpPOT(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.zsbuf = NULL; diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 6d4e14b95c..1386b1107c 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -10,6 +10,9 @@ #include "vl_defs.h" #include "vl_util.h" +/*#define DO_IDCT*/ + +#ifdef DO_IDCT static int vlTransformBlock(short *src, short *dst, short bias) { static const float basis[8][8] = @@ -62,6 +65,7 @@ static int vlTransformBlock(short *src, short *dst, short bias) } return 0; } +#endif static int vlGrabFrameCodedBlock(short *src, short *dst, unsigned int dst_pitch) { @@ -132,8 +136,6 @@ static int vlGrabBlocks unsigned int tex_pitch; unsigned int tb, sb = 0; - short temp_block[64]; - assert(context); assert(blocks); @@ -151,22 +153,23 @@ static int vlGrabBlocks { if ((coded_block_pattern >> (5 - tb)) & 1) { - if (sample_type == VL_FULL_SAMPLE) - vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 128); - else - vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 0); + short *cur_block = blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; + +#ifdef DO_IDCT + vlTransformBlock(cur_block, cur_block, sample_type == VL_FULL_SAMPLE ? 128 : 0); +#endif if (dct_type == VL_DCT_FRAME_CODED) vlGrabFrameCodedBlock ( - temp_block, + cur_block, texels + tb * tex_pitch * VL_BLOCK_HEIGHT, tex_pitch ); else vlGrabFieldCodedBlock ( - blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, + cur_block, texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, tex_pitch ); @@ -194,14 +197,15 @@ static int vlGrabBlocks if ((coded_block_pattern >> (1 - tb)) & 1) { - if (sample_type == VL_FULL_SAMPLE) - vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 128); - else - vlTransformBlock(blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT, temp_block, 0); + short *cur_block = blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; + +#ifdef DO_IDCT + vlTransformBlock(cur_block, cur_block, sample_type == VL_FULL_SAMPLE ? 128 : 0); +#endif vlGrabFrameCodedBlock ( - temp_block, + cur_block, texels, tex_pitch ); -- cgit v1.2.3 From fda01b584715c05696a0e6768fda669ef1eb5f3b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 7 Aug 2008 11:26:17 +1000 Subject: nouveau: fix build --- src/gallium/drivers/nv04/nv04_fragprog.c | 4 ++-- src/gallium/drivers/nv04/nv04_state.c | 2 +- src/gallium/drivers/nv04/nv04_state.h | 2 +- src/gallium/drivers/nv10/nv10_fragprog.c | 4 ++-- src/gallium/drivers/nv10/nv10_state.c | 2 +- src/gallium/drivers/nv10/nv10_state.h | 2 +- src/gallium/drivers/nv30/nv30_fragprog.c | 4 ++-- src/gallium/drivers/nv30/nv30_state.c | 2 +- src/gallium/drivers/nv30/nv30_state.h | 2 +- src/gallium/drivers/nv30/nv30_vertprog.c | 2 +- src/gallium/drivers/nv40/nv40_fragprog.c | 4 ++-- src/gallium/drivers/nv40/nv40_state.c | 2 +- src/gallium/drivers/nv40/nv40_state.h | 2 +- src/gallium/drivers/nv40/nv40_vertprog.c | 4 ++-- src/gallium/drivers/nv50/nv50_program.c | 4 ++-- src/gallium/drivers/nv50/nv50_program.h | 2 +- src/gallium/drivers/nv50/nv50_state.c | 2 +- 17 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv04/nv04_fragprog.c b/src/gallium/drivers/nv04/nv04_fragprog.c index 11f4360ed8..215974eec0 100644 --- a/src/gallium/drivers/nv04/nv04_fragprog.c +++ b/src/gallium/drivers/nv04/nv04_fragprog.c @@ -4,8 +4,8 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" #include "nv04_context.h" diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c index 7e71dee7b5..668d875671 100644 --- a/src/gallium/drivers/nv04/nv04_state.c +++ b/src/gallium/drivers/nv04/nv04_state.c @@ -4,7 +4,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #include "nv04_context.h" #include "nv04_state.h" diff --git a/src/gallium/drivers/nv04/nv04_state.h b/src/gallium/drivers/nv04/nv04_state.h index 39f7cd17b3..399f750dbe 100644 --- a/src/gallium/drivers/nv04/nv04_state.h +++ b/src/gallium/drivers/nv04/nv04_state.h @@ -2,7 +2,7 @@ #define __NV04_STATE_H__ #include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_scan.h" struct nv04_blend_state { uint32_t b_enable; diff --git a/src/gallium/drivers/nv10/nv10_fragprog.c b/src/gallium/drivers/nv10/nv10_fragprog.c index 2a63c8a704..137de9d53e 100644 --- a/src/gallium/drivers/nv10/nv10_fragprog.c +++ b/src/gallium/drivers/nv10/nv10_fragprog.c @@ -4,8 +4,8 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" #include "nv10_context.h" diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 43b9c32f12..f902fd54b6 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -4,7 +4,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #include "nv10_context.h" #include "nv10_state.h" diff --git a/src/gallium/drivers/nv10/nv10_state.h b/src/gallium/drivers/nv10/nv10_state.h index f1f9a12110..3a3fd0d4f4 100644 --- a/src/gallium/drivers/nv10/nv10_state.h +++ b/src/gallium/drivers/nv10/nv10_state.h @@ -2,7 +2,7 @@ #define __NV10_STATE_H__ #include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_scan.h" struct nv10_blend_state { uint32_t b_enable; diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 59e79d66f2..68058264e3 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -3,8 +3,8 @@ #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" #include "nv30_context.h" diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index ba02413de5..8d88d6c806 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -3,7 +3,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #include "nv30_context.h" #include "nv30_state.h" diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h index 20c5176160..e6f23bf166 100644 --- a/src/gallium/drivers/nv30/nv30_state.h +++ b/src/gallium/drivers/nv30/nv30_state.h @@ -2,7 +2,7 @@ #define __NV30_STATE_H__ #include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_scan.h" struct nv30_sampler_state { uint32_t fmt; diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 39852ce983..6c075cdb75 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -3,7 +3,7 @@ #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #include "nv30_context.h" #include "nv30_state.h" diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 428348c338..a361509e8f 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -3,8 +3,8 @@ #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" #include "nv40_context.h" diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 5d2c3ab881..63d0ecc915 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -5,7 +5,7 @@ #include "draw/draw_context.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #include "nv40_context.h" #include "nv40_state.h" diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index 2b4225deb2..8a9d8c8fdf 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -2,7 +2,7 @@ #define __NV40_STATE_H__ #include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_scan.h" struct nv40_sampler_state { uint32_t fmt; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 1e486a66ef..ff988e6a5f 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -3,8 +3,8 @@ #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" #include "nv40_context.h" #include "nv40_state.h" diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 0d3ddb8a59..d6fbdd1824 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -26,8 +26,8 @@ #include "pipe/p_inlines.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" #include "nv50_context.h" diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h index d643e8db21..78deed6a38 100644 --- a/src/gallium/drivers/nv50/nv50_program.h +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -2,7 +2,7 @@ #define __NV50_PROGRAM_H__ #include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_scan.h" struct nv50_program_exec { struct nv50_program_exec *next; diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 731409bed4..4055527d9f 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -25,7 +25,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #include "nv50_context.h" #include "nv50_texture.h" -- cgit v1.2.3 From ce8e846ffea8e1a11b8ae4ba05a7386e7c34cc9f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 7 Aug 2008 11:38:56 +1000 Subject: nv40/nv50: enable mirror wrap modes --- src/gallium/drivers/nv40/nv40_screen.c | 3 +++ src/gallium/drivers/nv50/nv50_screen.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index a63a6136c5..0e1df89ee8 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -57,6 +57,9 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) return 10; case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + return 1; case NOUVEAU_CAP_HW_VTXBUF: return 1; case NOUVEAU_CAP_HW_IDXBUF: diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 996b0b3e8f..ec43923929 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -114,6 +114,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) return 10; case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + return 1; case NOUVEAU_CAP_HW_VTXBUF: return 1; case NOUVEAU_CAP_HW_IDXBUF: -- cgit v1.2.3 From df4228deddea36b9d5b41ea395a216137e046205 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 11 Aug 2008 16:14:42 +1000 Subject: nouveau: pf_sprint_name -> pf_name --- src/gallium/drivers/nv04/nv04_fragtex.c | 4 +--- src/gallium/drivers/nv30/nv30_fragtex.c | 3 +-- src/gallium/drivers/nv30/nv30_vbo.c | 8 ++------ src/gallium/drivers/nv40/nv40_fragtex.c | 4 +--- src/gallium/drivers/nv40/nv40_vbo.c | 8 ++------ src/gallium/drivers/nv50/nv50_state_validate.c | 14 ++++---------- src/gallium/drivers/nv50/nv50_vbo.c | 5 ++--- 7 files changed, 13 insertions(+), 33 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv04/nv04_fragtex.c b/src/gallium/drivers/nv04/nv04_fragtex.c index 3db673cd2c..1b866aae19 100644 --- a/src/gallium/drivers/nv04/nv04_fragtex.c +++ b/src/gallium/drivers/nv04/nv04_fragtex.c @@ -51,7 +51,6 @@ static uint32_t nv04_fragtex_format(uint pipe_format) { struct nv04_texture_format *tf = nv04_texture_formats; - char fs[128]; int i; for (i=0; i< sizeof(nv04_texture_formats)/sizeof(nv04_texture_formats[0]); i++) { @@ -60,8 +59,7 @@ nv04_fragtex_format(uint pipe_format) tf++; } - pf_sprint_name(fs, pipe_format); - NOUVEAU_ERR("unknown texture format %s\n", fs); + NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format)); return 0; } diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index 4242f86f76..91246f5ca0 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -75,8 +75,7 @@ nv30_fragtex_format(uint pipe_format) tf++; } - pf_sprint_name(fs, pipe_format); - NOUVEAU_ERR("unknown texture format %s\n", fs); + NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format)); return NULL; } diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index d930557f6b..b1c73793bf 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -14,8 +14,6 @@ static INLINE int nv30_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: @@ -36,8 +34,7 @@ nv30_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) *fmt = NV34TCL_VTXFMT_TYPE_USHORT; break; default: - pf_sprint_name(fs, pipe); - NOUVEAU_ERR("Unknown format %s\n", fs); + NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe)); return 1; } @@ -63,8 +60,7 @@ nv30_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) *ncomp = 4; break; default: - pf_sprint_name(fs, pipe); - NOUVEAU_ERR("Unknown format %s\n", fs); + NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe)); return 1; } diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 2d45c2545c..566d5a8d5b 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -45,7 +45,6 @@ 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) @@ -53,8 +52,7 @@ nv40_fragtex_format(uint pipe_format) tf++; } - pf_sprint_name(fs, pipe_format); - NOUVEAU_ERR("unknown texture format %s\n", fs); + NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format)); return NULL; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 93669e6192..755d5586b7 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -14,8 +14,6 @@ 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: @@ -36,8 +34,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) *fmt = NV40TCL_VTXFMT_TYPE_USHORT; break; default: - pf_sprint_name(fs, pipe); - NOUVEAU_ERR("Unknown format %s\n", fs); + NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe)); return 1; } @@ -63,8 +60,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) *ncomp = 4; break; default: - pf_sprint_name(fs, pipe); - NOUVEAU_ERR("Unknown format %s\n", fs); + NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe)); return 1; } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 8f9ee05acc..198e25f448 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -58,11 +58,8 @@ nv50_state_validate_fb(struct nv50_context *nv50) 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); - } + NOUVEAU_ERR("AIIII unknown format %s\n", + pf_name(fb->cbufs[i]->format)); so_data(so, 0xe6); break; } @@ -96,11 +93,8 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_data(so, 0x15); break; default: - { - char fmt[128]; - pf_sprint_name(fmt, fb->zsbuf->format); - NOUVEAU_ERR("AIIII unknown format %s\n", fmt); - } + NOUVEAU_ERR("AIIII unknown format %s\n", + pf_name(fb->zsbuf->format)); so_data(so, 0x16); break; } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 8e420ad172..c94531723b 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -215,9 +215,8 @@ nv50_vbo_validate(struct nv50_context *nv50) break; default: { - char fmt[128]; - pf_sprint_name(fmt, ve->src_format); - NOUVEAU_ERR("invalid vbo format %s\n", fmt); + NOUVEAU_ERR("invalid vbo format %s\n", + pf_name(ve->src_format)); assert(0); return; } -- cgit v1.2.3 From dbec107c2549c00120ca6d67282f2a1a4bd8bdbd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 14 Aug 2008 00:22:49 +1000 Subject: nv30/nv40: KIL/KILP swapped meanings --- src/gallium/drivers/nv30/nv30_fragprog.c | 4 ++-- src/gallium/drivers/nv40/nv40_fragprog.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 68058264e3..d3693fdf56 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -494,10 +494,10 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc, case TGSI_OPCODE_FRC: arith(fpc, sat, FRC, dst, mask, src[0], none, none); break; - case TGSI_OPCODE_KIL: + case TGSI_OPCODE_KILP: arith(fpc, 0, KIL, none, 0, none, none, none); break; - case TGSI_OPCODE_KILP: + case TGSI_OPCODE_KIL: dst = nv30_sr(NV30SR_NONE, 0); dst.cc_update = 1; arith(fpc, 0, MOV, dst, MASK_ALL, src[0], none, none); diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index a361509e8f..91dcbebda0 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -533,10 +533,10 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc, case TGSI_OPCODE_FRC: arith(fpc, sat, FRC, dst, mask, src[0], none, none); break; - case TGSI_OPCODE_KIL: + case TGSI_OPCODE_KILP: arith(fpc, 0, KIL, none, 0, none, none, none); break; - case TGSI_OPCODE_KILP: + case TGSI_OPCODE_KIL: dst = nv40_sr(NV40SR_NONE, 0); dst.cc_update = 1; arith(fpc, 0, MOV, dst, MASK_ALL, src[0], none, none); -- cgit v1.2.3 From a7ea6bae4e618e28636909ac2db7783632bc81b8 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 14 Aug 2008 16:36:52 +0200 Subject: nv30: does not support mirror clamp, only mirror repeat --- src/gallium/drivers/nv30/nv30_screen.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 0ffcd77235..d5514c2aba 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -55,6 +55,10 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param) return 10; case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + return 0; + case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + return 1; case NOUVEAU_CAP_HW_VTXBUF: case NOUVEAU_CAP_HW_IDXBUF: return 1; -- cgit v1.2.3 From a145c107c12715105e14bb56b245eeb660cf433a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 14 Aug 2008 16:52:51 +0200 Subject: nv30: disable setting nv40 RECT bit, this is not the same on nv30, plus gallium does not support rectangle textures currently, only full POT or NPOT --- src/gallium/drivers/nv30/nv30_state.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 8d88d6c806..77b0c9e08b 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -127,8 +127,10 @@ nv30_sampler_state_create(struct pipe_context *pipe, in sampler state structure, and set appropriate format in nvxx_fragtex_build() */ - if (!cso->normalized_coords) - ps->fmt |= (1<<14) /*NV34TCL_TX_FORMAT_RECT*/; + /*NV34TCL_TX_FORMAT_RECT*/ + /*if (!cso->normalized_coords) { + ps->fmt |= (1<<14) ; + }*/ ps->wrap = ((wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) | (wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) | -- cgit v1.2.3 From d4c199d05691878bbc4c72a06d3042ef00ff38e0 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 14 Aug 2008 17:24:06 +0200 Subject: nv30: set mipmap min/max lod accordingly --- src/gallium/drivers/nv30/nv30_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 77b0c9e08b..eceb535315 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -199,10 +199,10 @@ nv30_sampler_state_create(struct pipe_context *pipe, 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; + ps->en |= (int)(limit) << 14 /*NV34TCL_TX_ENABLE_MIPMAP_MAX_LOD_SHIFT*/; limit = CLAMP(cso->min_lod, 0.0, 15.0); - ps->en |= (int)(limit * 256.0) << 19; + ps->en |= (int)(limit) << 26 /*NV34TCL_TX_ENABLE_MIPMAP_MIN_LOD_SHIFT*/; } if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { -- cgit v1.2.3 From fb2732ff056a83418a379b81c1e5da50675c41ac Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 9 Aug 2008 20:52:36 -0400 Subject: g3dvl: Merged tgsi/util and tgsi/exec moved some headers around. --- src/gallium/state_trackers/g3dvl/vl_context.c | 4 ++-- src/gallium/state_trackers/g3dvl/vl_shader_build.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index d446d218a4..5616de0ba4 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -7,8 +7,8 @@ #include #include #include -#include -#include +#include +#include #include "vl_shader_build.h" #include "vl_data.h" #include "vl_defs.h" diff --git a/src/gallium/state_trackers/g3dvl/vl_shader_build.c b/src/gallium/state_trackers/g3dvl/vl_shader_build.c index 1dc5be6fdb..5f30e23ff8 100644 --- a/src/gallium/state_trackers/g3dvl/vl_shader_build.c +++ b/src/gallium/state_trackers/g3dvl/vl_shader_build.c @@ -1,7 +1,7 @@ #include "vl_shader_build.h" #include -#include -#include +#include +#include struct tgsi_full_declaration vl_decl_input(unsigned int name, unsigned int index, unsigned int first, unsigned int last) { -- cgit v1.2.3 From 6858dd50c9b696c1c6044f5a403000f9d20b286b Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 16 Aug 2008 13:04:23 -0400 Subject: g3dvl: Modularized rendering, refactored to accommodate VAAPI, other APIs. --- src/gallium/state_trackers/g3dvl/Makefile | 4 +- src/gallium/state_trackers/g3dvl/vl_basic_csc.c | 694 ++++++ src/gallium/state_trackers/g3dvl/vl_basic_csc.h | 13 + src/gallium/state_trackers/g3dvl/vl_context.c | 2272 +------------------ src/gallium/state_trackers/g3dvl/vl_context.h | 118 +- src/gallium/state_trackers/g3dvl/vl_csc.h | 53 + src/gallium/state_trackers/g3dvl/vl_data.c | 130 +- src/gallium/state_trackers/g3dvl/vl_data.h | 19 +- src/gallium/state_trackers/g3dvl/vl_defs.h | 1 - src/gallium/state_trackers/g3dvl/vl_display.c | 48 + src/gallium/state_trackers/g3dvl/vl_display.h | 29 + src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c | 2315 ++++++++++++++++++++ src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.h | 18 + src/gallium/state_trackers/g3dvl/vl_render.h | 33 + src/gallium/state_trackers/g3dvl/vl_screen.c | 115 + src/gallium/state_trackers/g3dvl/vl_screen.h | 63 + src/gallium/state_trackers/g3dvl/vl_shader_build.c | 37 +- src/gallium/state_trackers/g3dvl/vl_shader_build.h | 1 - src/gallium/state_trackers/g3dvl/vl_surface.c | 671 +----- src/gallium/state_trackers/g3dvl/vl_surface.h | 91 +- src/gallium/state_trackers/g3dvl/vl_types.h | 124 +- src/gallium/state_trackers/g3dvl/vl_util.c | 9 +- src/gallium/state_trackers/g3dvl/vl_util.h | 1 - src/libXvMC/block.c | 47 +- src/libXvMC/context.c | 194 +- src/libXvMC/surface.c | 403 ++-- 26 files changed, 4061 insertions(+), 3442 deletions(-) create mode 100644 src/gallium/state_trackers/g3dvl/vl_basic_csc.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_basic_csc.h create mode 100644 src/gallium/state_trackers/g3dvl/vl_csc.h create mode 100644 src/gallium/state_trackers/g3dvl/vl_display.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_display.h create mode 100644 src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.h create mode 100644 src/gallium/state_trackers/g3dvl/vl_render.h create mode 100644 src/gallium/state_trackers/g3dvl/vl_screen.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_screen.h (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/Makefile b/src/gallium/state_trackers/g3dvl/Makefile index c6a22cad4e..9995c554ab 100644 --- a/src/gallium/state_trackers/g3dvl/Makefile +++ b/src/gallium/state_trackers/g3dvl/Makefile @@ -1,5 +1,6 @@ TARGET = libg3dvl.a -OBJECTS = vl_context.o vl_data.o vl_surface.o vl_shader_build.o vl_util.o +OBJECTS = vl_display.o vl_screen.o vl_context.o vl_surface.o vl_data.o vl_shader_build.o vl_util.o vl_basic_csc.o \ + vl_r16snorm_mc.o GALLIUMDIR = ../.. CFLAGS += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary -I${GALLIUMDIR}/winsys/g3dvl @@ -15,4 +16,3 @@ ${TARGET}: ${OBJECTS} clean: rm -rf ${OBJECTS} ${TARGET} - diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c new file mode 100644 index 0000000000..ea003a31d1 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c @@ -0,0 +1,694 @@ +#define VL_INTERNAL +#include "vl_basic_csc.h" +#include +#include +#include +#include +#include +#include +#include +#include "vl_csc.h" +#include "vl_surface.h" +#include "vl_shader_build.h" +#include "vl_types.h" + +struct vlVertexShaderConsts +{ + struct vlVertex4f src_scale; + struct vlVertex4f src_trans; +}; + +struct vlFragmentShaderConsts +{ + struct vlVertex4f bias; + float matrix[16]; +}; + +struct vlBasicCSC +{ + struct vlCSC base; + + struct pipe_context *pipe; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + void *sampler; + void *vertex_shader, *fragment_shader; + struct pipe_vertex_buffer vertex_bufs[2]; + struct pipe_vertex_element vertex_elems[2]; + struct pipe_constant_buffer vs_const_buf, fs_const_buf; +}; + +static int vlResizeFrameBuffer +( + struct vlCSC *csc, + unsigned int width, + unsigned int height +) +{ + struct vlBasicCSC *basic_csc; + struct pipe_context *pipe; + + assert(csc); + + basic_csc = (struct vlBasicCSC*)csc; + pipe = basic_csc->pipe; + + if (basic_csc->framebuffer.width == width && basic_csc->framebuffer.height == height) + return 0; + + if (basic_csc->framebuffer.cbufs[0]) + pipe->winsys->surface_release + ( + pipe->winsys, + &basic_csc->framebuffer.cbufs[0] + ); + + basic_csc->viewport.scale[0] = width; + basic_csc->viewport.scale[1] = height; + basic_csc->viewport.scale[2] = 1; + basic_csc->viewport.scale[3] = 1; + basic_csc->viewport.translate[0] = 0; + basic_csc->viewport.translate[1] = 0; + basic_csc->viewport.translate[2] = 0; + basic_csc->viewport.translate[3] = 0; + + basic_csc->framebuffer.width = width; + basic_csc->framebuffer.height = height; + basic_csc->framebuffer.cbufs[0] = pipe->winsys->surface_alloc(pipe->winsys); + pipe->winsys->surface_alloc_storage + ( + pipe->winsys, + basic_csc->framebuffer.cbufs[0], + width, + height, + PIPE_FORMAT_A8R8G8B8_UNORM, + /* XXX: SoftPipe doesn't change GPU usage to CPU like it does for textures */ + PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE, + 0 + ); + + return 0; +} + +static int vlBegin +( + struct vlCSC *csc +) +{ + struct vlBasicCSC *basic_csc; + struct pipe_context *pipe; + + assert(csc); + + basic_csc = (struct vlBasicCSC*)csc; + pipe = basic_csc->pipe; + + pipe->set_framebuffer_state(pipe, &basic_csc->framebuffer); + pipe->set_viewport_state(pipe, &basic_csc->viewport); + pipe->bind_sampler_states(pipe, 1, (void**)&basic_csc->sampler); + /* Source texture set in vlPutSurface() */ + pipe->bind_vs_state(pipe, basic_csc->vertex_shader); + pipe->bind_fs_state(pipe, basic_csc->fragment_shader); + pipe->set_vertex_buffers(pipe, 2, basic_csc->vertex_bufs); + pipe->set_vertex_elements(pipe, 2, basic_csc->vertex_elems); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &basic_csc->vs_const_buf); + pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &basic_csc->fs_const_buf); + + return 0; +} + +static int vlPutPictureCSC +( + struct vlCSC *csc, + struct vlSurface *surface, + int srcx, + int srcy, + int srcw, + int srch, + int destx, + int desty, + int destw, + int desth, + enum vlPictureType picture_type +) +{ + struct vlBasicCSC *basic_csc; + struct pipe_context *pipe; + struct vlVertexShaderConsts *vs_consts; + + assert(csc); + assert(surface); + + basic_csc = (struct vlBasicCSC*)csc; + pipe = basic_csc->pipe; + + vs_consts = pipe->winsys->buffer_map + ( + pipe->winsys, + basic_csc->vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ); + + vs_consts->src_scale.x = srcw / (float)surface->texture->width[0]; + vs_consts->src_scale.y = srch / (float)surface->texture->height[0]; + vs_consts->src_scale.z = 1; + vs_consts->src_scale.w = 1; + vs_consts->src_trans.x = srcx / (float)surface->texture->width[0]; + vs_consts->src_trans.y = srcy / (float)surface->texture->height[0]; + vs_consts->src_trans.z = 0; + vs_consts->src_trans.w = 0; + + pipe->winsys->buffer_unmap(pipe->winsys, basic_csc->vs_const_buf.buffer); + + pipe->set_sampler_textures(pipe, 1, &surface->texture); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); + + return 0; +} + +static int vlEnd +( + struct vlCSC *csc +) +{ + assert(csc); + + return 0; +} + +static struct pipe_surface* vlGetFrameBuffer +( + struct vlCSC *csc +) +{ + struct vlBasicCSC *basic_csc; + + assert(csc); + + basic_csc = (struct vlBasicCSC*)csc; + + return basic_csc->framebuffer.cbufs[0]; +} + +static int vlDestroy +( + struct vlCSC *csc +) +{ + struct vlBasicCSC *basic_csc; + struct pipe_context *pipe; + unsigned int i; + + assert(csc); + + basic_csc = (struct vlBasicCSC*)csc; + pipe = basic_csc->pipe; + + if (basic_csc->framebuffer.cbufs[0]) + pipe->winsys->surface_release + ( + pipe->winsys, + &basic_csc->framebuffer.cbufs[0] + ); + + pipe->delete_sampler_state(pipe, basic_csc->sampler); + pipe->delete_vs_state(pipe, basic_csc->vertex_shader); + pipe->delete_fs_state(pipe, basic_csc->fragment_shader); + + for (i = 0; i < 2; ++i) + pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->vertex_bufs[i].buffer); + + pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->vs_const_buf.buffer); + pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->fs_const_buf.buffer); + + free(basic_csc); + + return 0; +} + +/* + * Represents 2 triangles in a strip in normalized coords. + * Used to render the surface onto the frame buffer. + */ +static const struct vlVertex2f surface_verts[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. + * TODO: Duplicate these in the shader, no need to create a buffer. + */ +static const struct vlVertex2f *surface_texcoords = surface_verts; + +/* + * Identity color conversion constants, for debugging + */ +static const struct vlFragmentShaderConsts 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] + */ +static const struct vlFragmentShaderConsts bt_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] + */ +static const struct vlFragmentShaderConsts bt_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] + */ +static const struct vlFragmentShaderConsts bt_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 vlFragmentShaderConsts bt_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 + } +}; + +static int vlCreateVertexShader +( + struct vlBasicCSC *csc +) +{ + const unsigned int max_tokens = 50; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(context); + + pipe = csc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Vertex texcoords + */ + for (i = 0; i < 2; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling vector to scale texcoord rect to source size + * decl c1 ; Translation vector to move texcoord rect into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl o0 ; Vertex pos + * decl o1 ; Vertex texcoords + */ + for (i = 0; i < 2; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* mov o0, i0 ; Move pos in to pos out */ + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_INPUT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mul t0, i1, c0 ; Scale unit texcoord rect to source size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 1, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o1, t0, c1 ; Translate texcoord rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + csc->vertex_shader = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShader +( + struct vlBasicCSC *csc +) +{ + const unsigned int max_tokens = 50; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(context); + + pipe = csc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* decl i0 ; Texcoords for s0 */ + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl c0 ; Bias vector for CSC + * decl c1-c4 ; CSC matrix c1-c4 + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 4); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl s0 ; Sampler for tex containing picture to display */ + decl = vl_decl_samplers(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* tex2d t0, i0, s0 ; Read src pixel */ + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* sub t0, t0, c0 ; Subtract bias vector from pixel */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix + * dp4 o0.y, t0, c2 + * dp4 o0.z, t0, c3 + * dp4 o0.w, t0, c4 ; XXX: Don't need 4th coefficient + */ + for (i = 0; i < 4; ++i) + { + inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1); + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + csc->fragment_shader = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateDataBufs +( + struct vlBasicCSC *csc +) +{ + struct pipe_context *pipe; + + assert(csc); + + pipe = csc->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 + */ + csc->vertex_bufs[0].pitch = sizeof(struct vlVertex2f); + csc->vertex_bufs[0].max_index = 3; + csc->vertex_bufs[0].buffer_offset = 0; + csc->vertex_bufs[0].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vlVertex2f) * 4 + ); + + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, csc->vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + surface_verts, + sizeof(struct vlVertex2f) * 4 + ); + + pipe->winsys->buffer_unmap(pipe->winsys, csc->vertex_bufs[0].buffer); + + csc->vertex_elems[0].src_offset = 0; + csc->vertex_elems[0].vertex_buffer_index = 0; + csc->vertex_elems[0].nr_components = 2; + csc->vertex_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 + */ + csc->vertex_bufs[1].pitch = sizeof(struct vlVertex2f); + csc->vertex_bufs[1].max_index = 3; + csc->vertex_bufs[1].buffer_offset = 0; + csc->vertex_bufs[1].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vlVertex2f) * 4 + ); + + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, csc->vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + surface_texcoords, + sizeof(struct vlVertex2f) * 4 + ); + + pipe->winsys->buffer_unmap(pipe->winsys, csc->vertex_bufs[1].buffer); + + csc->vertex_elems[1].src_offset = 0; + csc->vertex_elems[1].vertex_buffer_index = 1; + csc->vertex_elems[1].nr_components = 2; + csc->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* + Create our vertex shader's constant buffer + Const buffer contains scaling and translation vectors + */ + csc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts); + csc->vs_const_buf.buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + csc->vs_const_buf.size + ); + + /* + Create our fragment shader's constant buffer + Const buffer contains the color conversion matrix and bias vectors + */ + csc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts); + csc->fs_const_buf.buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + 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, csc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + &bt_601, + sizeof(struct vlFragmentShaderConsts) + ); + + pipe->winsys->buffer_unmap(pipe->winsys, csc->fs_const_buf.buffer); + + return 0; +} + +static int vlInit +( + struct vlBasicCSC *csc +) +{ + struct pipe_context *pipe; + struct pipe_sampler_state sampler; + + assert(csc); + + pipe = csc->pipe; + + /* Delay creating the FB until vlPutSurface() so we know window size */ + csc->framebuffer.num_cbufs = 1; + csc->framebuffer.cbufs[0] = NULL; + 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 = ;*/ + csc->sampler = pipe->create_sampler_state(pipe, &sampler); + + vlCreateVertexShader(csc); + vlCreateFragmentShader(csc); + vlCreateDataBufs(csc); + + return 0; +} + +int vlCreateBasicCSC +( + struct pipe_context *pipe, + struct vlCSC **csc +) +{ + struct vlBasicCSC *basic_csc; + + assert(pipe); + assert(csc); + + basic_csc = calloc(1, sizeof(struct vlBasicCSC)); + + if (!basic_csc) + return 1; + + basic_csc->base.vlResizeFrameBuffer = &vlResizeFrameBuffer; + basic_csc->base.vlBegin = &vlBegin; + basic_csc->base.vlPutPicture = &vlPutPictureCSC; + basic_csc->base.vlEnd = &vlEnd; + basic_csc->base.vlGetFrameBuffer = &vlGetFrameBuffer; + basic_csc->base.vlDestroy = &vlDestroy; + basic_csc->pipe = pipe; + + vlInit(basic_csc); + + *csc = &basic_csc->base; + + return 0; +} diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.h b/src/gallium/state_trackers/g3dvl/vl_basic_csc.h new file mode 100644 index 0000000000..2e17f1d814 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_basic_csc.h @@ -0,0 +1,13 @@ +#ifndef vl_basic_csc_h +#define vl_basic_csc_h + +struct pipe_context; +struct vlCSC; + +int vlCreateBasicCSC +( + struct pipe_context *pipe, + struct vlCSC **csc +); + +#endif diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 5616de0ba4..56d360c05b 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -1,2088 +1,26 @@ +#define VL_INTERNAL #include "vl_context.h" #include #include #include -#include -#include #include -#include -#include -#include -#include -#include "vl_shader_build.h" -#include "vl_data.h" -#include "vl_defs.h" -#include "vl_util.h" +#include "vl_render.h" +#include "vl_r16snorm_mc.h" +#include "vl_csc.h" +#include "vl_basic_csc.h" -static int vlCreateVertexShaderFrameIDCT(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 50; - - struct pipe_context *pipe; - struct pipe_shader_state fs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); - - ti = 3; - - /* - * decl i0 ; Vertex pos - * decl i1 ; Vertex texcoords - */ - for (i = 0; i < 2; i++) - { - decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * decl o0 ; Vertex pos - * decl o1 ; Vertex texcoords - */ - for (i = 0; i < 2; i++) - { - decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * mov o0, i0 ; Move pos in to pos out - * mov o1, i1 ; Move texcoord in to texcoord out */ - for (i = 0; i < 2; ++i) - { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* end */ - inst = vl_end(); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - fs.tokens = tokens; - //context->states.idct.frame_vs = pipe->create_fs_state(pipe, &fs); - free(tokens); - - return 0; -} - -static int vlCreateFragmentShaderFrameIDCT(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 50; - - struct pipe_context *pipe; - struct pipe_shader_state fs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); - - ti = 3; - - /* decl i0 ; Texcoords for s0 */ - decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl o0 ; Fragment color */ - decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl s0 ; Sampler for tex containing picture to display */ - decl = vl_decl_samplers(0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* tex2d t0, i0, s0 ; Read src pixel */ - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* sub t0, t0, c0 ; Subtract bias vector from pixel */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix - * dp4 o0.y, t0, c2 - * dp4 o0.z, t0, c3 - * dp4 o0.w, t0, c4 ; XXX: Don't need 4th coefficient - */ - for (i = 0; i < 4; ++i) - { - inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1); - inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* end */ - inst = vl_end(); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - fs.tokens = tokens; - //context->states.idct.frame_fs = pipe->create_fs_state(pipe, &fs); - free(tokens); - - return 0; -} - -static int vlInitIDCT(struct VL_CONTEXT *context) -{ - struct pipe_context *pipe; - struct pipe_sampler_state sampler; - struct pipe_texture template; - unsigned int i; - - assert(context); - - pipe = context->pipe; - - context->states.idct.viewport.scale[0] = VL_BLOCK_WIDTH; - context->states.idct.viewport.scale[1] = VL_BLOCK_HEIGHT; - context->states.idct.viewport.scale[2] = 1; - context->states.idct.viewport.scale[3] = 1; - context->states.idct.viewport.translate[0] = 0; - context->states.idct.viewport.translate[1] = 0; - context->states.idct.viewport.translate[2] = 0; - context->states.idct.viewport.translate[3] = 0; - - context->states.idct.render_target.width = VL_BLOCK_WIDTH; - context->states.idct.render_target.height = VL_BLOCK_HEIGHT; - context->states.idct.render_target.num_cbufs = 1; - context->states.idct.render_target.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_NEAREST; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; - sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; - 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 = 0; - /*sampler.max_lod = ;*/ - /*sampler.border_color[i] = ;*/ - /*sampler.max_anisotropy = ;*/ - context->states.idct.sampler = 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; - template.depth[0] = 1; - template.compressed = 0; - pf_get_block(template.format, &template.block); - - context->states.idct.texture = pipe->screen->texture_create(pipe->screen, &template); - - template.format = PIPE_FORMAT_A8R8G8B8_UNORM; - template.width[0] = 16; - template.height[0] = 1; - - context->states.idct.basis = pipe->screen->texture_create(pipe->screen, &template); - - for (i = 0; i < 2; ++i) - { - context->states.idct.vertex_bufs[i] = &context->states.csc.vertex_bufs[i]; - context->states.idct.vertex_buf_elems[i] = &context->states.csc.vertex_buf_elems[i]; - /* - context->states.idct.vertex_bufs[i].pitch = sizeof(struct VL_VERTEX2F); - context->states.idct.vertex_bufs[i].max_index = 3; - context->states.idct.vertex_bufs[i].buffer_offset = 0; - context->states.idct.vertex_bufs[i].buffer = pipe->winsys->buffer_create - ( - pipe->winsys, - 1, - PIPE_BUFFER_USAGE_VERTEX, - sizeof(struct VL_VERTEX2F) * 4 - ); - - context->states.idct.vertex_buf_elems[i].src_offset = 0; - context->states.idct.vertex_buf_elems[i].vertex_buffer_index = i; - context->states.idct.vertex_buf_elems[i].nr_components = 2; - context->states.idct.vertex_buf_elems[i].src_format = PIPE_FORMAT_R32G32_FLOAT; - */ - } - - vlCreateVertexShaderFrameIDCT(context); - vlCreateFragmentShaderFrameIDCT(context); - - return 0; -} - -static int vlDestroyIDCT(struct VL_CONTEXT *context) -{ - //unsigned int i; - - assert(context); - - context->pipe->delete_sampler_state(context->pipe, context->states.idct.sampler); - - //for (i = 0; i < 2; ++i) - //context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.idct.vertex_bufs[i].buffer); - - pipe_texture_release(&context->states.idct.texture); - pipe_texture_release(&context->states.idct.basis); - - //context->pipe->delete_vs_state(context->pipe, context->states.idct.frame_vs); - //context->pipe->delete_fs_state(context->pipe, context->states.idct.frame_fs); - - //context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.idct.vs_const_buf.buffer); - //context->pipe->winsys->buffer_destroy(context->pipe->winsys, context->states.idct.fs_const_buf.buffer); - - return 0; -} - -static int vlCreateVertexShaderIMC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 50; - - struct pipe_context *pipe; - struct pipe_shader_state vs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); - - ti = 3; - - /* - * decl i0 ; Vertex pos - * decl i1 ; Luma texcoords - * decl i2 ; Chroma texcoords - */ - for (i = 0; i < 3; i++) - { - decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * decl c0 ; Scaling vector to scale unit rect to macroblock size - * decl c1 ; Translation vector to move macroblock into position - */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl o0 ; Vertex pos - * decl o1 ; Luma texcoords - * decl o2 ; Chroma texcoords - */ - for (i = 0; i < 3; i++) - { - decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* decl t0 */ - decl = vl_decl_temps(0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* add o0, t0, c1 ; Translate rect into position */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - * mov o1, i1 ; Move input luma texcoords to output - * mov o2, i2 ; Move input chroma texcoords to output - */ - for (i = 1; i < 3; ++i) - { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* end */ - inst = vl_end(); - 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); - free(tokens); - - return 0; -} - -static int vlCreateFragmentShaderIMC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 100; - - struct pipe_context *pipe; - struct pipe_shader_state fs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); - - ti = 3; - - /* - * decl i0 ; Texcoords for s0 - * decl i1 ; Texcoords for s1, s2 - */ - for (i = 0; i < 2; ++i) - { - decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl o0 ; Fragment color */ - decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl t0, t1 */ - decl = vl_decl_temps(0, 1); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl s0 ; Sampler for luma texture - * decl s1 ; Sampler for chroma Cb texture - * decl s2 ; Sampler for chroma Cr texture - */ - for (i = 0; i < 3; ++i) - { - decl = vl_decl_samplers(i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header,max_tokens - ti); - } - - /* - * tex2d t1, i0, s0 ; Read texel from luma texture - * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i1, s1 ; Read texel from chroma Cb texture - * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i1, s2 ; Read texel from chroma Cr texture - * mov t0.z, t1.x ; Move Cr sample into .z component - */ - for (i = 0; i < 3; ++i) - { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - } - - /* mul o0, t0, c0 ; Rescale texel to correct range */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* end */ - inst = vl_end(); - 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); - free(tokens); - - return 0; -} - -static int vlCreateVertexShaderFramePMC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 100; - - struct pipe_context *pipe; - struct pipe_shader_state vs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); - - ti = 3; - - /* - * decl i0 ; Vertex pos - * decl i1 ; Luma texcoords - * decl i2 ; Chroma texcoords - */ - for (i = 0; i < 3; i++) - { - decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * decl c0 ; Scaling vector to scale unit rect to macroblock size - * decl c1 ; Translation vector to move macroblock into position - * decl c2 ; Unused - * decl c3 ; Translation vector to move ref macroblock texcoords into position - */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 3); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl o0 ; Vertex pos - * decl o1 ; Luma texcoords - * decl o2 ; Chroma texcoords - * decl o3 ; Ref macroblock texcoords - */ - for (i = 0; i < 4; i++) - { - decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* decl t0 */ - decl = vl_decl_temps(0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* add o0, t0, c1 ; Translate rect into position */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - * mov o1, i1 ; Move input luma texcoords to output - * mov o2, i2 ; Move input chroma texcoords to output - */ - for (i = 1; i < 3; ++i) - { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* add o3, t0, c3 ; Translate rect into position on ref macroblock */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* end */ - inst = vl_end(); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - vs.tokens = tokens; - context->states.mc.p_vs[0] = pipe->create_vs_state(pipe, &vs); - free(tokens); - - return 0; -} - -static int vlCreateVertexShaderFieldPMC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 100; - - struct pipe_context *pipe; - struct pipe_shader_state vs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); - - ti = 3; - - /* - * decl i0 ; Vertex pos - * decl i1 ; Luma texcoords - * decl i2 ; Chroma texcoords - */ - for (i = 0; i < 3; i++) - { - decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration - ( - &decl, - &tokens[ti], - header, - max_tokens - ti - ); - } - - /* - * decl c0 ; Scaling vector to scale unit rect to macroblock size - * decl c1 ; Translation vector to move macroblock into position - * decl c2 ; Denorm coefficients - * decl c3 ; Translation vector to move top field ref macroblock texcoords into position - * decl c4 ; Translation vector to move bottom field ref macroblock texcoords into position - */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 4); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl o0 ; Vertex pos - * decl o1 ; Luma texcoords - * decl o2 ; Chroma texcoords - * decl o3 ; Top field ref macroblock texcoords - * decl o4 ; Bottom field ref macroblock texcoords - * decl o5 ; Denormalized vertex pos - */ - for (i = 0; i < 6; i++) - { - decl = vl_decl_output((i == 0 || i == 5) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* decl t0, t1 */ - decl = vl_decl_temps(0, 1); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* add t1, t0, c1 ; Translate rect into position */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* mov o0, t1 ; Move vertex pos to output */ - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - mov o1, i1 ; Move input luma texcoords to output - mov o2, i2 ; Move input chroma texcoords to output - */ - for (i = 1; i < 3; ++i) - { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* add o3, t0, c3 ; Translate top field rect into position on ref macroblock - add o4, t0, c4 ; Translate bottom field rect into position on ref macroblock */ - for (i = 0; i < 2; ++i) - { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* mul o5, t1, c2 ; Denorm vertex pos */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 5, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 2); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* end */ - inst = vl_end(); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - vs.tokens = tokens; - context->states.mc.p_vs[1] = pipe->create_vs_state(pipe, &vs); - free(tokens); - - return 0; -} - -static int vlCreateFragmentShaderFramePMC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 100; - - struct pipe_context *pipe; - struct pipe_shader_state fs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); - - ti = 3; - - /* - * decl i0 ; Texcoords for s0 - * decl i1 ; Texcoords for s1, s2 - * decl i2 ; Texcoords for s3 - */ - for (i = 0; i < 3; ++i) - { - decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl o0 ; Fragment color */ - decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl t0, t1 */ - decl = vl_decl_temps(0, 1); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl s0 ; Sampler for luma texture - * decl s1 ; Sampler for chroma Cb texture - * decl s2 ; Sampler for chroma Cr texture - * decl s3 ; Sampler for ref surface texture - */ - for (i = 0; i < 4; ++i) - { - decl = vl_decl_samplers(i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * tex2d t1, i0, s0 ; Read texel from luma texture - * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i1, s1 ; Read texel from chroma Cb texture - * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i1, s2 ; Read texel from chroma Cr texture - * mov t0.z, t1.x ; Move Cr sample into .z component - */ - for (i = 0; i < 3; ++i) - { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - } - - /* mul t0, t0, c0 ; Rescale texel to correct range */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* tex2d t1, i2, s3 ; Read texel from ref macroblock */ - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 2, TGSI_FILE_SAMPLER, 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 = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* end */ - inst = vl_end(); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - fs.tokens = tokens; - context->states.mc.p_fs[0] = pipe->create_fs_state(pipe, &fs); - free(tokens); - - return 0; -} - -static int vlCreateFragmentShaderFieldPMC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 200; - - struct pipe_context *pipe; - struct pipe_shader_state fs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); - - ti = 3; - - /* - * decl i0 ; Texcoords for s0 - * decl i1 ; Texcoords for s1, s2 - * decl i2 ; Texcoords for s3 - * decl i3 ; Texcoords for s3 - * decl i4 ; Denormalized vertex pos - */ - for (i = 0; i < 5; ++i) - { - decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm - * decl c1 ; Constants 1/2 & 2 in .x, .y channels for Y-mod-2 top/bottom field selection - */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl o0 ; Fragment color */ - decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl t0-t4 */ - decl = vl_decl_temps(0, 4); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl s0 ; Sampler for luma texture - * decl s1 ; Sampler for chroma Cb texture - * decl s2 ; Sampler for chroma Cr texture - * decl s3 ; Sampler for ref surface texture - */ - for (i = 0; i < 4; ++i) - { - decl = vl_decl_samplers(i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * tex2d t1, i0, s0 ; Read texel from luma texture - * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i1, s1 ; Read texel from chroma Cb texture - * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i1, s2 ; Read texel from chroma Cr texture - * mov t0.z, t1.x ; Move Cr sample into .z component - */ - for (i = 0; i < 3; ++i) - { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - } - - /* mul t0, t0, c0 ; Rescale texel to correct range */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - * tex2d t1, i2, s3 ; Read texel from ref macroblock top field - * tex2d t2, i3, s3 ; Read texel from ref macroblock bottom field - */ - for (i = 0; i < 2; ++i) - { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 2, TGSI_FILE_SAMPLER, 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* XXX: Pos values off by 0.5? */ - /* sub t4, i4.y, c1.x ; Sub 0.5 from denormalized pos */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 4, TGSI_FILE_CONSTANT, 1); - inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1); - inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* floor t3, t3 ; Get rid of fractional part */ - inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* mul t3, t3, c1.y ; Multiply by 2 */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1); - inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* TODO: Move to conditional tex fetch on t3 instead of lerp */ - /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */ - inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); - 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 = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* end */ - inst = vl_end(); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - fs.tokens = tokens; - context->states.mc.p_fs[1] = pipe->create_fs_state(pipe, &fs); - free(tokens); - - return 0; -} - -static int vlCreateVertexShaderFrameBMC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 100; - - struct pipe_context *pipe; - struct pipe_shader_state vs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); - - ti = 3; - - /* - * decl i0 ; Vertex pos - * decl i1 ; Luma texcoords - * decl i2 ; Chroma texcoords - */ - for (i = 0; i < 3; i++) - { - decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * decl c0 ; Scaling vector to scale unit rect to macroblock size - * decl c1 ; Translation vector to move macroblock into position - * decl c2 ; Unused - * decl c3 ; Translation vector to move past ref macroblock texcoords into position - * decl c4 ; Unused - * decl c5 ; Translation vector to move future ref macroblock texcoords into position - */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 5); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl o0 ; Vertex pos - * decl o1 ; Luma texcoords - * decl o2 ; Chroma texcoords - * decl o3 ; Past ref macroblock texcoords - * decl o4 ; Future ref macroblock texcoords - */ - for (i = 0; i < 5; i++) - { - decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* decl t0 */ - decl = vl_decl_temps(0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* add o0, t0, c1 ; Translate rect into position */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - * mov o1, i1 ; Move input luma texcoords to output - * mov o2, i2 ; Move input chroma texcoords to output - */ - for (i = 1; i < 3; ++i) - { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* add o3, t0, c3 ; Translate rect into position on past ref macroblock - add o4, t0, c5 ; Translate rect into position on future ref macroblock */ - for (i = 0; i < 2; ++i) - { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i * 2 + 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* end */ - inst = vl_end(); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - vs.tokens = tokens; - context->states.mc.b_vs[0] = pipe->create_vs_state(pipe, &vs); - free(tokens); - - return 0; -} - -static int vlCreateVertexShaderFieldBMC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 100; - - struct pipe_context *pipe; - struct pipe_shader_state vs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); - - ti = 3; - - /* - * decl i0 ; Vertex pos - * decl i1 ; Luma texcoords - * decl i2 ; Chroma texcoords - */ - for (i = 0; i < 3; i++) - { - decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * decl c0 ; Scaling vector to scale unit rect to macroblock size - * decl c1 ; Translation vector to move macroblock into position - * decl c2 ; Denorm coefficients - * decl c3 ; Translation vector to move top field past ref macroblock texcoords into position - * decl c4 ; Translation vector to move bottom field past ref macroblock texcoords into position - * decl c5 ; Translation vector to move top field future ref macroblock texcoords into position - * decl c6 ; Translation vector to move bottom field future ref macroblock texcoords into position - */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 6); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl o0 ; Vertex pos - * decl o1 ; Luma texcoords - * decl o2 ; Chroma texcoords - * decl o3 ; Top field past ref macroblock texcoords - * decl o4 ; Bottom field past ref macroblock texcoords - * decl o5 ; Top field future ref macroblock texcoords - * decl o6 ; Bottom field future ref macroblock texcoords - * decl o7 ; Denormalized vertex pos - */ - for (i = 0; i < 8; i++) - { - decl = vl_decl_output((i == 0 || i == 7) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* decl t0, t1 */ - decl = vl_decl_temps(0, 1); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* add t1, t0, c1 ; Translate rect into position */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* mov o0, t1 ; Move vertex pos to output */ - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - * mov o1, i1 ; Move input luma texcoords to output - * mov o2, i2 ; Move input chroma texcoords to output - */ - for (i = 1; i < 3; ++i) - { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* - * add o3, t0, c3 ; Translate top field rect into position on past ref macroblock - * add o4, t0, c4 ; Translate bottom field rect into position on past ref macroblock - * add o5, t0, c5 ; Translate top field rect into position on future ref macroblock - * add o6, t0, c6 ; Translate bottom field rect into position on future ref macroblock - */ - for (i = 0; i < 4; ++i) - { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* mul o7, t1, c2 ; Denorm vertex pos */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 7, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 2); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* end */ - inst = vl_end(); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - vs.tokens = tokens; - context->states.mc.b_vs[1] = pipe->create_vs_state(pipe, &vs); - free(tokens); - - return 0; -} - -static int vlCreateFragmentShaderFrameBMC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 100; - - struct pipe_context *pipe; - struct pipe_shader_state fs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); - - ti = 3; - - /* - * decl i0 ; Texcoords for s0 - * decl i1 ; Texcoords for s1, s2 - * decl i2 ; Texcoords for s3 - * decl i3 ; Texcoords for s4 - */ - for (i = 0; i < 4; ++i) - { - decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm - * decl c1 ; Constant 1/2 in .x channel to use as weight to blend past and future texels - */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl o0 ; Fragment color */ - decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl t0-t2 */ - decl = vl_decl_temps(0, 2); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl s0 ; Sampler for luma texture - * decl s1 ; Sampler for chroma Cb texture - * decl s2 ; Sampler for chroma Cr texture - * decl s3 ; Sampler for past ref surface texture - * decl s4 ; Sampler for future ref surface texture - */ - for (i = 0; i < 5; ++i) - { - decl = vl_decl_samplers(i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * tex2d t1, i0, s0 ; Read texel from luma texture - * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i1, s1 ; Read texel from chroma Cb texture - * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i1, s2 ; Read texel from chroma Cr texture - * mov t0.z, t1.x ; Move Cr sample into .z component - */ - for (i = 0; i < 3; ++i) - { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - } - - /* mul t0, t0, c0 ; Rescale texel to correct range */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - * tex2d t1, i2, s3 ; Read texel from past ref macroblock - * tex2d t2, i3, s4 ; Read texel from future ref macroblock - */ - for (i = 0; i < 2; ++i) - { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 2, TGSI_FILE_SAMPLER, i + 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */ - inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); - inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* add o0, t0, t1 ; Add past/future ref and differential to form final output */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* end */ - inst = vl_end(); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - fs.tokens = tokens; - context->states.mc.b_fs[0] = pipe->create_fs_state(pipe, &fs); - free(tokens); - - return 0; -} - -static int vlCreateFragmentShaderFieldBMC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 200; - - struct pipe_context *pipe; - struct pipe_shader_state fs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); - - ti = 3; - - /* - * decl i0 ; Texcoords for s0 - * decl i1 ; Texcoords for s1, s2 - * decl i2 ; Texcoords for s3 - * decl i3 ; Texcoords for s3 - * decl i4 ; Texcoords for s4 - * decl i5 ; Texcoords for s4 - * decl i6 ; Denormalized vertex pos - */ - for (i = 0; i < 7; ++i) - { - decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm - * decl c1 ; Constants 1/2 & 2 in .x, .y channels to use as weight to blend past and future texels - * ; and for Y-mod-2 top/bottom field selection - */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl o0 ; Fragment color */ - decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl t0-t5 */ - decl = vl_decl_temps(0, 5); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl s0 ; Sampler for luma texture - * decl s1 ; Sampler for chroma Cb texture - * decl s2 ; Sampler for chroma Cr texture - * decl s3 ; Sampler for past ref surface texture - * decl s4 ; Sampler for future ref surface texture - */ - for (i = 0; i < 5; ++i) - { - decl = vl_decl_samplers(i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * tex2d t1, i0, s0 ; Read texel from luma texture - * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i1, s1 ; Read texel from chroma Cb texture - * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i1, s2 ; Read texel from chroma Cr texture - * mov t0.z, t1.x ; Move Cr sample into .z component - */ - for (i = 0; i < 3; ++i) - { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - } - - /* mul t0, t0, c0 ; Rescale texel to correct range */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* XXX: Pos values off by 0.5? */ - /* sub t4, i6.y, c1.x ; Sub 0.5 from denormalized pos */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 6, TGSI_FILE_CONSTANT, 1); - inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1); - inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* floor t3, t3 ; Get rid of fractional part */ - inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* mul t3, t3, c1.y ; Multiply by 2 */ - inst = vl_inst3( TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1); - inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; - inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - * tex2d t1, i2, s3 ; Read texel from past ref macroblock top field - * tex2d t2, i3, s3 ; Read texel from past ref macroblock bottom field - */ - for (i = 0; i < 2; ++i) - { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 2, TGSI_FILE_SAMPLER, 3); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* TODO: Move to conditional tex fetch on t3 instead of lerp */ - /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */ - inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - * tex2d t4, i4, s4 ; Read texel from future ref macroblock top field - * tex2d t5, i5, s4 ; Read texel from future ref macroblock bottom field - */ - for (i = 0; i < 2; ++i) - { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 4, TGSI_FILE_INPUT, i + 4, TGSI_FILE_SAMPLER, 4); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* TODO: Move to conditional tex fetch on t3 instead of lerp */ - /* lerp t2, t3, t4, t5 ; Choose between top and bottom fields based on Y % 2 */ - inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 2, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 5); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */ - inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); - inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; - inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* add o0, t0, t1 ; Add past/future ref and differential to form final output */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* end */ - inst = vl_end(); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - fs.tokens = tokens; - context->states.mc.b_fs[1] = pipe->create_fs_state(pipe, &fs); - free(tokens); - - 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 */ - 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; - - /* For MC we render to textures, which are rounded up to nearest POT */ - context->states.mc.viewport.scale[0] = vlRoundUpPOT(context->video_width); - context->states.mc.viewport.scale[1] = vlRoundUpPOT(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 = vlRoundUpPOT(context->video_width); - context->states.mc.render_target.height = vlRoundUpPOT(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.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_LINEAR; - filters[4] = PIPE_TEX_FILTER_LINEAR; - - 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 = 0; - /*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_R16_SNORM; - template.last_level = 0; - template.width[0] = 8; - template.height[0] = 8 * 4; - template.depth[0] = 1; - template.compressed = 0; - pf_get_block(template.format, &template.block); - - 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); - vlCreateVertexShaderFramePMC(context); - vlCreateVertexShaderFieldPMC(context); - vlCreateFragmentShaderFramePMC(context); - vlCreateFragmentShaderFieldPMC(context); - vlCreateVertexShaderFrameBMC(context); - vlCreateVertexShaderFieldBMC(context); - vlCreateFragmentShaderFrameBMC(context); - vlCreateFragmentShaderFieldBMC(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); - - for (i = 0; i < 2; ++i) - { - context->pipe->delete_vs_state(context->pipe, context->states.mc.p_vs[i]); - context->pipe->delete_fs_state(context->pipe, context->states.mc.p_fs[i]); - context->pipe->delete_vs_state(context->pipe, context->states.mc.b_vs[i]); - context->pipe->delete_fs_state(context->pipe, context->states.mc.b_fs[i]); - } - - 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; - - struct pipe_context *pipe; - struct pipe_shader_state vs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); - - ti = 3; - - /* - * decl i0 ; Vertex pos - * decl i1 ; Vertex texcoords - */ - for (i = 0; i < 2; i++) - { - decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* - * decl c0 ; Scaling vector to scale texcoord rect to source size - * decl c1 ; Translation vector to move texcoord rect into position - */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl o0 ; Vertex pos - * decl o1 ; Vertex texcoords - */ - for (i = 0; i < 2; i++) - { - decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - } - - /* decl t0 */ - decl = vl_decl_temps(0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* mov o0, i0 ; Move pos in to pos out */ - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_INPUT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* mul t0, i1, c0 ; Scale unit texcoord rect to source size */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 1, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* add o1, t0, c1 ; Translate texcoord rect into position */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* end */ - inst = vl_end(); - 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); - //free(tokens); - - return 0; -} - -static int vlCreateFragmentShaderCSC(struct VL_CONTEXT *context) -{ - const unsigned int max_tokens = 50; - - struct pipe_context *pipe; - struct pipe_shader_state fs; - struct tgsi_token *tokens; - struct tgsi_header *header; - - 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 */ - *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); - - ti = 3; - - /* decl i0 ; Texcoords for s0 */ - decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* - * decl c0 ; Bias vector for CSC - * decl c1-c4 ; CSC matrix c1-c4 - */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 4); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl o0 ; Fragment color */ - decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl t0 */ - decl = vl_decl_temps(0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* decl s0 ; Sampler for tex containing picture to display */ - decl = vl_decl_samplers(0, 0); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - - /* tex2d t0, i0, s0 ; Read src pixel */ - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* sub t0, t0, c0 ; Subtract bias vector from pixel */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* - * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix - * dp4 o0.y, t0, c2 - * dp4 o0.z, t0, c3 - * dp4 o0.w, t0, c4 ; XXX: Don't need 4th coefficient - */ - for (i = 0; i < 4; ++i) - { - inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1); - inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } - - /* end */ - inst = vl_end(); - 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); - //free(tokens); - - 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 vertex shader's constant buffer - Const buffer contains scaling and translation vectors - */ - context->states.csc.vs_const_buf.size = sizeof(struct VL_CSC_VS_CONSTS); - context->states.csc.vs_const_buf.buffer = pipe->winsys->buffer_create - ( - pipe->winsys, - 1, - PIPE_BUFFER_USAGE_CONSTANT, - context->states.csc.vs_const_buf.size - ); - - /* - 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.vs_const_buf.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) +static int vlInitCommon(struct vlContext *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.flatshade_first = 0; rast.light_twoside = 0; @@ -2113,9 +51,9 @@ static int vlInitCommon(struct VL_CONTEXT *context) 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); - + context->raster = pipe->create_rasterizer_state(pipe, &rast); + pipe->bind_rasterizer_state(pipe, context->raster); + blend.blend_enable = 0; blend.rgb_func = PIPE_BLEND_ADD; blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; @@ -2128,9 +66,9 @@ static int vlInitCommon(struct VL_CONTEXT *context) /* 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); - + context->blend = pipe->create_blend_state(pipe, &blend); + pipe->bind_blend_state(pipe, context->blend); + dsa.depth.enabled = 0; dsa.depth.writemask = 0; dsa.depth.func = PIPE_FUNC_ALWAYS; @@ -2149,134 +87,122 @@ static int vlInitCommon(struct VL_CONTEXT *context) 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; -} + context->dsa = pipe->create_depth_stencil_alpha_state(pipe, &dsa); + pipe->bind_depth_stencil_alpha_state(pipe, context->dsa); -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) +int vlCreateContext +( + struct vlScreen *screen, + struct pipe_context *pipe, + unsigned int picture_width, + unsigned int picture_height, + enum vlFormat picture_format, + enum vlProfile profile, + enum vlEntryPoint entry_point, + struct vlContext **context +) { + struct vlContext *ctx; + + assert(screen); assert(context); - - vlInitCommon(context); - vlInitCSC(context); - vlInitMC(context); - vlInitIDCT(context); - + assert(pipe); + + ctx = calloc(1, sizeof(struct vlContext)); + + if (!ctx) + return 1; + + ctx->screen = screen; + ctx->pipe = pipe; + ctx->picture_width = picture_width; + ctx->picture_height = picture_height; + ctx->picture_format = picture_format; + ctx->profile = profile; + ctx->entry_point = entry_point; + + vlInitCommon(ctx); + + vlCreateR16SNormMC(pipe, picture_width, picture_height, picture_format, &ctx->render); + vlCreateBasicCSC(pipe, &ctx->csc); + + *context = ctx; + return 0; } -static int vlDestroy(struct VL_CONTEXT *context) +int vlDestroyContext +( + struct vlContext *context +) { assert(context); - + /* XXX: 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); - + + context->render->vlDestroy(context->render); + context->csc->vlDestroy(context->csc); + + context->pipe->delete_blend_state(context->pipe, context->blend); + context->pipe->delete_rasterizer_state(context->pipe, context->raster); + context->pipe->delete_depth_stencil_alpha_state(context->pipe, context->dsa); + + free(context); + return 0; } -int vlCreateContext +struct vlScreen* vlContextGetScreen ( - Display *display, - struct pipe_context *pipe, - unsigned int video_width, - unsigned int video_height, - enum VL_FORMAT video_format, - struct VL_CONTEXT **context + struct vlContext *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; + + return context->screen; } -int vlDestroyContext(struct VL_CONTEXT *context) +struct pipe_context* vlGetPipeContext +( + struct vlContext *context +) { assert(context); - - vlDestroy(context); - - free(context); - - return 0; + + return context->pipe; } -int vlBeginRender(struct VL_CONTEXT *context) +unsigned int vlGetPictureWidth +( + struct vlContext *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; + + return context->picture_width; } -int vlEndRender(struct VL_CONTEXT *context) +unsigned int vlGetPictureHeight +( + struct vlContext *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_VERTEX, 0, &context->states.csc.vs_const_buf); - pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &context->states.csc.fs_const_buf); - - return 0; + + return context->picture_height; } +enum vlFormat vlGetPictureFormat +( + struct vlContext *context +) +{ + assert(context); + + return context->picture_format; +} diff --git a/src/gallium/state_trackers/g3dvl/vl_context.h b/src/gallium/state_trackers/g3dvl/vl_context.h index bff318854a..3d14634c44 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.h +++ b/src/gallium/state_trackers/g3dvl/vl_context.h @@ -1,83 +1,73 @@ #ifndef vl_context_h #define vl_context_h -#include -#include #include "vl_types.h" struct pipe_context; -struct VL_CONTEXT +#ifdef VL_INTERNAL +struct vlRender; +struct vlCSC; + +struct vlContext { - Display *display; + struct vlScreen *screen; 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 - { - struct pipe_viewport_state viewport; - struct pipe_framebuffer_state render_target; - struct pipe_sampler_state *sampler; - struct pipe_texture *texture; - struct pipe_texture *basis; - struct pipe_shader_state *frame_vs; - struct pipe_shader_state *frame_fs; - struct pipe_vertex_buffer *vertex_bufs[2]; - struct pipe_vertex_element *vertex_buf_elems[2]; - //struct pipe_constant_buffer vs_const_buf, fs_const_buf; - } 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[2], *b_vs[2]; - struct pipe_shader_state *i_fs, *p_fs[2], *b_fs[2]; - 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 vs_const_buf, fs_const_buf; - } csc; - } states; + unsigned int picture_width; + unsigned int picture_height; + enum vlFormat picture_format; + enum vlProfile profile; + enum vlEntryPoint entry_point; + + void *raster; + void *dsa; + void *blend; + + struct vlRender *render; + struct vlCSC *csc; }; +#endif int vlCreateContext ( - Display *display, + struct vlScreen *screen, struct pipe_context *pipe, - unsigned int video_width, - unsigned int video_height, - enum VL_FORMAT video_format, - struct VL_CONTEXT **context + unsigned int picture_width, + unsigned int picture_height, + enum vlFormat picture_format, + enum vlProfile profile, + enum vlEntryPoint entry_point, + struct vlContext **context ); -int vlDestroyContext(struct VL_CONTEXT *context); +int vlDestroyContext +( + struct vlContext *context +); -int vlBeginRender(struct VL_CONTEXT *context); -int vlEndRender(struct VL_CONTEXT *context); +struct vlScreen* vlContextGetScreen +( + struct vlContext *context +); -#endif +struct pipe_context* vlGetPipeContext +( + struct vlContext *context +); +unsigned int vlGetPictureWidth +( + struct vlContext *context +); + +unsigned int vlGetPictureHeight +( + struct vlContext *context +); + +enum vlFormat vlGetPictureFormat +( + struct vlContext *context +); + +#endif diff --git a/src/gallium/state_trackers/g3dvl/vl_csc.h b/src/gallium/state_trackers/g3dvl/vl_csc.h new file mode 100644 index 0000000000..36417a2792 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_csc.h @@ -0,0 +1,53 @@ +#ifndef vl_csc_h +#define vl_csc_h + +#include "vl_types.h" + +struct pipe_surface; + +struct vlCSC +{ + int (*vlResizeFrameBuffer) + ( + struct vlCSC *csc, + unsigned int width, + unsigned int height + ); + + int (*vlBegin) + ( + struct vlCSC *csc + ); + + int (*vlPutPicture) + ( + struct vlCSC *csc, + struct vlSurface *surface, + int srcx, + int srcy, + int srcw, + int srch, + int destx, + int desty, + int destw, + int desth, + enum vlPictureType picture_type + ); + + int (*vlEnd) + ( + struct vlCSC *csc + ); + + struct pipe_surface* (*vlGetFrameBuffer) + ( + struct vlCSC *csc + ); + + int (*vlDestroy) + ( + struct vlCSC *csc + ); +}; + +#endif diff --git a/src/gallium/state_trackers/g3dvl/vl_data.c b/src/gallium/state_trackers/g3dvl/vl_data.c index 0e5c8c77f9..f2476dbf1e 100644 --- a/src/gallium/state_trackers/g3dvl/vl_data.c +++ b/src/gallium/state_trackers/g3dvl/vl_data.c @@ -6,17 +6,17 @@ * 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] = +const struct vlVertex2f macroblock_verts[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} }; @@ -26,17 +26,17 @@ const struct VL_VERTEX2F vl_mb_vertex_positions[24] = * 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] = +const struct vlVertex2f macroblock_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} }; @@ -45,7 +45,7 @@ const struct VL_TEXCOORD2F vl_luma_texcoords[24] = * 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; +const struct vlVertex2f *macroblock_chroma_420_texcoords = macroblock_verts; /* * Represents texcoords for the above for rendering 2 chroma blocks arranged @@ -53,30 +53,13 @@ const struct VL_TEXCOORD2F *vl_chroma_420_texcoords = (const struct VL_TEXCOORD2 * 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; +const struct vlVertex2f *macroblock_chroma_422_texcoords = macroblock_verts; /* * 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; +const struct vlVertex2f *macroblock_chroma_444_texcoords = macroblock_luma_texcoords; /* * Used when rendering P and B macroblocks, multiplier is applied to the A channel, @@ -84,97 +67,10 @@ const struct VL_TEXCOORD2F *vl_surface_texcoords = (const struct VL_TEXCOORD2F*) * get back the differential. The differential is then added to the samples from the * reference surface(s). */ +#if 0 const struct VL_MC_FS_CONSTS vl_mc_fs_consts = { {32767.0f / 255.0f, 32767.0f / 255.0f, 32767.0f / 255.0f, 0.0f}, {0.5f, 2.0f, 0.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 - } -}; - +#endif diff --git a/src/gallium/state_trackers/g3dvl/vl_data.h b/src/gallium/state_trackers/g3dvl/vl_data.h index 8f347273ad..f0de2e976c 100644 --- a/src/gallium/state_trackers/g3dvl/vl_data.h +++ b/src/gallium/state_trackers/g3dvl/vl_data.h @@ -3,15 +3,18 @@ #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; +/* TODO: Needs to be rolled into the appropriate stage */ -extern const struct VL_VERTEX2F vl_surface_vertex_positions[4]; -extern const struct VL_TEXCOORD2F *vl_surface_texcoords; +extern const struct vlVertex2f macroblock_verts[24]; +extern const struct vlVertex2f macroblock_luma_texcoords[24]; +extern const struct vlVertex2f *macroblock_chroma_420_texcoords; +extern const struct vlVertex2f *macroblock_chroma_422_texcoords; +extern const struct vlVertex2f *macroblock_chroma_444_texcoords; +extern const struct vlVertex2f surface_verts[4]; +extern const struct vlVertex2f *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; @@ -19,6 +22,6 @@ 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 index e668a7a10e..d612d02502 100644 --- a/src/gallium/state_trackers/g3dvl/vl_defs.h +++ b/src/gallium/state_trackers/g3dvl/vl_defs.h @@ -9,4 +9,3 @@ #define VL_MACROBLOCK_SIZE (VL_MACROBLOCK_WIDTH * VL_MACROBLOCK_HEIGHT) #endif - diff --git a/src/gallium/state_trackers/g3dvl/vl_display.c b/src/gallium/state_trackers/g3dvl/vl_display.c new file mode 100644 index 0000000000..af80faa7f5 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_display.c @@ -0,0 +1,48 @@ +#define VL_INTERNAL +#include "vl_display.h" +#include +#include + +int vlCreateDisplay +( + vlNativeDisplay native_display, + struct vlDisplay **display +) +{ + struct vlDisplay *dpy; + + assert(native_display); + assert(display); + + dpy = calloc(1, sizeof(struct vlDisplay)); + + if (!dpy) + return 1; + + dpy->native = native_display; + *display = dpy; + + return 0; +} + +int vlDestroyDisplay +( + struct vlDisplay *display +) +{ + assert(display); + + free(display); + + return 0; +} + +vlNativeDisplay vlGetNativeDisplay +( + struct vlDisplay *display +) +{ + assert(display); + + return display->native; +} diff --git a/src/gallium/state_trackers/g3dvl/vl_display.h b/src/gallium/state_trackers/g3dvl/vl_display.h new file mode 100644 index 0000000000..e11fd40799 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_display.h @@ -0,0 +1,29 @@ +#ifndef vl_display_h +#define vl_display_h + +#include "vl_types.h" + +#ifdef VL_INTERNAL +struct vlDisplay +{ + vlNativeDisplay native; +}; +#endif + +int vlCreateDisplay +( + vlNativeDisplay native_display, + struct vlDisplay **display +); + +int vlDestroyDisplay +( + struct vlDisplay *display +); + +vlNativeDisplay vlGetNativeDisplay +( + struct vlDisplay *display +); + +#endif diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c new file mode 100644 index 0000000000..4fae224431 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c @@ -0,0 +1,2315 @@ +#define VL_INTERNAL +#include "vl_r16snorm_mc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "vl_render.h" +#include "vl_shader_build.h" +#include "vl_surface.h" +#include "vl_util.h" +#include "vl_types.h" +#include "vl_defs.h" + +struct vlVertexShaderConsts +{ + /*struct vlVertex4f scale; + struct vlVertex4f denorm;*/ + struct vlVertex4f scale; + struct vlVertex4f mb_pos_trans; + struct vlVertex4f denorm; + struct + { + struct vlVertex4f top_field; + struct vlVertex4f bottom_field; + } mb_tc_trans[2]; +}; + +struct vlFragmentShaderConsts +{ + struct vlVertex4f multiplier; + struct vlVertex4f div; +}; + +struct vlR16SnormMC +{ + struct vlRender base; + + unsigned int video_width, video_height; + enum vlFormat video_format; + + struct pipe_context *pipe; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state render_target; + struct pipe_sampler_state *samplers[5]; + struct pipe_texture *textures[5]; + void *i_vs, *p_vs[2], *b_vs[2]; + void *i_fs, *p_fs[2], *b_fs[2]; + struct pipe_vertex_buffer vertex_bufs[3]; + struct pipe_vertex_element vertex_elems[3]; + struct pipe_constant_buffer vs_const_buf, fs_const_buf; +}; + +int vlBegin +( + struct vlRender *render +) +{ + struct vlR16SnormMC *mc; + struct pipe_context *pipe; + + assert(render); + + mc = (struct vlR16SnormMC*)render; + pipe = mc->pipe; + + /* Frame buffer set in vlRender*Macroblock() */ + /* Shaders, samplers, textures set in vlRender*Macroblock() */ + pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs); + pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + pipe->set_viewport_state(pipe, &mc->viewport); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &mc->vs_const_buf); + pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &mc->fs_const_buf); + + return 0; +} + +/*static int vlGrabMacroBlock +( + struct vlR16SnormMC *mc, + struct vlMpeg2MacroBlock *macroblock +) +{ + assert(mc); + assert(macroblock); + + + + return 0; +}*/ + +/*#define DO_IDCT*/ + +#ifdef DO_IDCT +static int vlTransformBlock(short *src, short *dst, short bias) +{ + static const float basis[8][8] = + { + {0.3536, 0.4904, 0.4619, 0.4157, 0.3536, 0.2778, 0.1913, 0.0975}, + {0.3536, 0.4157, 0.1913, -0.0975, -0.3536, -0.4904, -0.4619, -0.2778}, + {0.3536, 0.2778, -0.1913, -0.4904, -0.3536, 0.0975, 0.4619, 0.4157}, + {0.3536, 0.0975, -0.4619, -0.2778, 0.3536, 0.4157, -0.1913, -0.4904}, + {0.3536, -0.0975, -0.4619, 0.2778, 0.3536, -0.4157, -0.1913, 0.4904}, + {0.3536, -0.2778, -0.1913, 0.4904, -0.3536, -0.0975, 0.4619, -0.4157}, + {0.3536, -0.4157, 0.1913, 0.0975, -0.3536, 0.4904, -0.4619, 0.2778}, + {0.3536, -0.4904, 0.4619, -0.4157, 0.3536, -0.2778, 0.1913, -0.0975} + }; + + unsigned int x, y; + short tmp[64]; + + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + tmp[y * VL_BLOCK_WIDTH + x] = (short) + ( + src[y * VL_BLOCK_WIDTH + 0] * basis[x][0] + + src[y * VL_BLOCK_WIDTH + 1] * basis[x][1] + + src[y * VL_BLOCK_WIDTH + 2] * basis[x][2] + + src[y * VL_BLOCK_WIDTH + 3] * basis[x][3] + + src[y * VL_BLOCK_WIDTH + 4] * basis[x][4] + + src[y * VL_BLOCK_WIDTH + 5] * basis[x][5] + + src[y * VL_BLOCK_WIDTH + 6] * basis[x][6] + + src[y * VL_BLOCK_WIDTH + 7] * basis[x][7] + ); + + for (x = 0; x < VL_BLOCK_WIDTH; ++x) + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + { + dst[y * VL_BLOCK_WIDTH + x] = bias + (short) + ( + tmp[0 * VL_BLOCK_WIDTH + x] * basis[y][0] + + tmp[1 * VL_BLOCK_WIDTH + x] * basis[y][1] + + tmp[2 * VL_BLOCK_WIDTH + x] * basis[y][2] + + tmp[3 * VL_BLOCK_WIDTH + x] * basis[y][3] + + tmp[4 * VL_BLOCK_WIDTH + x] * basis[y][4] + + tmp[5 * VL_BLOCK_WIDTH + x] * basis[y][5] + + tmp[6 * VL_BLOCK_WIDTH + x] * basis[y][6] + + tmp[7 * VL_BLOCK_WIDTH + x] * basis[y][7] + ); + if (dst[y * VL_BLOCK_WIDTH + x] > 255) + dst[y * VL_BLOCK_WIDTH + x] = 255; + else if (bias > 0 && dst[y * VL_BLOCK_WIDTH + x] < 0) + dst[y * VL_BLOCK_WIDTH + x] = 0; + } + return 0; +} +#endif + +static int vlGrabFrameCodedBlock(short *src, short *dst, unsigned int dst_pitch) +{ + unsigned int y; + + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + memcpy + ( + dst + y * dst_pitch, + src + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + + return 0; +} + +static int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst_pitch) +{ + unsigned int y; + + for (y = 0; y < VL_BLOCK_HEIGHT / 2; ++y) + memcpy + ( + dst + y * dst_pitch * 2, + src + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + + dst += VL_BLOCK_HEIGHT * dst_pitch; + + for (; y < VL_BLOCK_HEIGHT; ++y) + memcpy + ( + dst + y * dst_pitch * 2, + src + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + + return 0; +} + +static int vlGrabNoBlock(short *dst, unsigned int dst_pitch) +{ + unsigned int y; + + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + memset + ( + dst + y * dst_pitch, + 0, + VL_BLOCK_WIDTH * 2 + ); + + return 0; +} + +enum vlSampleType +{ + vlSampleTypeFull, + vlSampleTypeDiff +}; + +static int vlGrabBlocks +( + struct vlR16SnormMC *mc, + unsigned int coded_block_pattern, + enum vlDCTType dct_type, + enum vlSampleType sample_type, + short *blocks +) +{ + struct pipe_surface *tex_surface; + short *texels; + unsigned int tex_pitch; + unsigned int tb, sb = 0; + + assert(mc); + assert(blocks); + + tex_surface = mc->pipe->screen->get_tex_surface + ( + mc->pipe->screen, + mc->textures[0], + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE + ); + + texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); + tex_pitch = tex_surface->stride / tex_surface->block.size; + + for (tb = 0; tb < 4; ++tb) + { + if ((coded_block_pattern >> (5 - tb)) & 1) + { + short *cur_block = blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; + +#ifdef DO_IDCT + vlTransformBlock(cur_block, cur_block, sample_type == vlSampleTypeFull ? 128 : 0); +#endif + + if (dct_type == vlDCTTypeFrameCoded) + vlGrabFrameCodedBlock + ( + cur_block, + texels + tb * tex_pitch * VL_BLOCK_HEIGHT, + tex_pitch + ); + else + vlGrabFieldCodedBlock + ( + cur_block, + texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, + tex_pitch + ); + + ++sb; + } + else + vlGrabNoBlock(texels + tb * tex_pitch * VL_BLOCK_HEIGHT, tex_pitch); + } + + pipe_surface_unmap(tex_surface); + + /* TODO: Implement 422, 444 */ + for (tb = 0; tb < 2; ++tb) + { + tex_surface = mc->pipe->screen->get_tex_surface + ( + mc->pipe->screen, + mc->textures[tb + 1], + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE + ); + + texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); + tex_pitch = tex_surface->stride / tex_surface->block.size; + + if ((coded_block_pattern >> (1 - tb)) & 1) + { + short *cur_block = blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; + +#ifdef DO_IDCT + vlTransformBlock(cur_block, cur_block, sample_type == vlSampleTypeFull ? 128 : 0); +#endif + + vlGrabFrameCodedBlock + ( + cur_block, + texels, + tex_pitch + ); + + ++sb; + } + else + vlGrabNoBlock(texels, tex_pitch); + + pipe_surface_unmap(tex_surface); + } + + return 0; +} + +int vlRenderIMacroBlock +( + struct vlR16SnormMC *mc, + enum vlPictureType picture_type, + enum vlFieldOrder field_order, + unsigned int mbx, + unsigned int mby, + unsigned int coded_block_pattern, + enum vlDCTType dct_type, + short *blocks, + struct vlSurface *surface +) +{ + struct pipe_context *pipe; + struct vlVertexShaderConsts *vs_consts; + + assert(blocks); + assert(surface); + + /* TODO: Implement interlaced rendering */ + if (picture_type != vlPictureTypeFrame) + return 0; + + vlGrabBlocks(mc, coded_block_pattern, dct_type, vlSampleTypeFull, blocks); + + pipe = mc->pipe; + + vs_consts = pipe->winsys->buffer_map + ( + pipe->winsys, + mc->vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ); + + vs_consts->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->texture->width[0]; + vs_consts->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->texture->height[0]; + vs_consts->scale.z = 1.0f; + vs_consts->scale.w = 1.0f; + vs_consts->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->texture->width[0]; + vs_consts->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->texture->height[0]; + vs_consts->mb_pos_trans.z = 0.0f; + vs_consts->mb_pos_trans.w = 0.0f; + + pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer); + + mc->render_target.cbufs[0] = pipe->screen->get_tex_surface + ( + pipe->screen, + surface->texture, + 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE + ); + pipe->set_framebuffer_state(pipe, &mc->render_target); + pipe->set_sampler_textures(pipe, 3, mc->textures); + pipe->bind_sampler_states(pipe, 3, (void**)mc->samplers); + pipe->bind_vs_state(pipe, mc->i_vs); + pipe->bind_fs_state(pipe, mc->i_fs); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); + + return 0; +} + +int vlRenderPMacroBlock +( + struct vlR16SnormMC *mc, + enum vlPictureType picture_type, + enum vlFieldOrder field_order, + unsigned int mbx, + unsigned int mby, + enum vlMotionType mc_type, + short top_x, + short top_y, + short bottom_x, + short bottom_y, + unsigned int coded_block_pattern, + enum vlDCTType dct_type, + short *blocks, + struct vlSurface *ref_surface, + struct vlSurface *surface +) +{ + struct pipe_context *pipe; + struct vlVertexShaderConsts *vs_consts; + + assert(motion_vectors); + assert(blocks); + assert(ref_surface); + assert(surface); + + /* TODO: Implement interlaced rendering */ + if (picture_type != vlPictureTypeFrame) + return 0; + /* TODO: Implement other MC types */ + if (mc_type != vlMotionTypeFrame && mc_type != vlMotionTypeField) + return 0; + + vlGrabBlocks(mc, coded_block_pattern, dct_type, vlSampleTypeDiff, blocks); + + pipe = mc->pipe; + + vs_consts = pipe->winsys->buffer_map + ( + pipe->winsys, + mc->vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ); + + vs_consts->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->texture->width[0]; + vs_consts->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->texture->height[0]; + vs_consts->scale.z = 1.0f; + vs_consts->scale.w = 1.0f; + vs_consts->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->texture->width[0]; + vs_consts->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->texture->height[0]; + vs_consts->mb_pos_trans.z = 0.0f; + vs_consts->mb_pos_trans.w = 0.0f; + vs_consts->mb_tc_trans[0].top_field.x = (mbx * VL_MACROBLOCK_WIDTH + top_x * 0.5f) / (float)surface->texture->width[0]; + vs_consts->mb_tc_trans[0].top_field.y = (mby * VL_MACROBLOCK_HEIGHT + top_y * 0.5f) / (float)surface->texture->height[0]; + vs_consts->mb_tc_trans[0].top_field.z = 0.0f; + vs_consts->mb_tc_trans[0].top_field.w = 0.0f; + + if (mc_type == vlMotionTypeField) + { + vs_consts->denorm.x = (float)surface->texture->width[0]; + vs_consts->denorm.y = (float)surface->texture->height[0]; + + vs_consts->mb_tc_trans[0].bottom_field.x = (mbx * VL_MACROBLOCK_WIDTH + bottom_x * 0.5f) / (float)surface->texture->width[0]; + vs_consts->mb_tc_trans[0].bottom_field.y = (mby * VL_MACROBLOCK_HEIGHT + bottom_y * 0.5f) / (float)surface->texture->height[0]; + vs_consts->mb_tc_trans[0].bottom_field.z = 0.0f; + vs_consts->mb_tc_trans[0].bottom_field.w = 0.0f; + + pipe->bind_vs_state(pipe, mc->p_vs[1]); + pipe->bind_fs_state(pipe, mc->p_fs[1]); + } + else + { + pipe->bind_vs_state(pipe, mc->p_vs[0]); + pipe->bind_fs_state(pipe, mc->p_fs[0]); + } + + pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer); + + mc->render_target.cbufs[0] = pipe->screen->get_tex_surface + ( + pipe->screen, + surface->texture, + 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE + ); + pipe->set_framebuffer_state(pipe, &mc->render_target); + + mc->textures[3] = ref_surface->texture; + pipe->set_sampler_textures(pipe, 4, mc->textures); + pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); + + return 0; +} + +int vlRenderBMacroBlock +( + struct vlR16SnormMC *mc, + enum vlPictureType picture_type, + enum vlFieldOrder field_order, + unsigned int mbx, + unsigned int mby, + enum vlMotionType mc_type, + short top_past_x, + short top_past_y, + short bottom_past_x, + short bottom_past_y, + short top_future_x, + short top_future_y, + short bottom_future_x, + short bottom_future_y, + unsigned int coded_block_pattern, + enum vlDCTType dct_type, + short *blocks, + struct vlSurface *past_surface, + struct vlSurface *future_surface, + struct vlSurface *surface +) +{ + struct pipe_context *pipe; + struct vlVertexShaderConsts *vs_consts; + + assert(motion_vectors); + assert(blocks); + assert(ref_surface); + assert(surface); + + /* TODO: Implement interlaced rendering */ + if (picture_type != vlPictureTypeFrame) + return 0; + /* TODO: Implement other MC types */ + if (mc_type != vlMotionTypeFrame && mc_type != vlMotionTypeField) + return 0; + + vlGrabBlocks(mc, coded_block_pattern, dct_type, vlSampleTypeDiff, blocks); + + pipe = mc->pipe; + + vs_consts = pipe->winsys->buffer_map + ( + pipe->winsys, + mc->vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ); + + vs_consts->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->texture->width[0]; + vs_consts->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->texture->height[0]; + vs_consts->scale.z = 1.0f; + vs_consts->scale.w = 1.0f; + vs_consts->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->texture->width[0]; + vs_consts->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->texture->height[0]; + vs_consts->mb_pos_trans.z = 0.0f; + vs_consts->mb_pos_trans.w = 0.0f; + vs_consts->mb_tc_trans[0].top_field.x = (mbx * VL_MACROBLOCK_WIDTH + top_past_x * 0.5f) / (float)surface->texture->width[0]; + vs_consts->mb_tc_trans[0].top_field.y = (mby * VL_MACROBLOCK_HEIGHT + top_past_y * 0.5f) / (float)surface->texture->height[0]; + vs_consts->mb_tc_trans[0].top_field.z = 0.0f; + vs_consts->mb_tc_trans[0].top_field.w = 0.0f; + vs_consts->mb_tc_trans[1].top_field.x = (mbx * VL_MACROBLOCK_WIDTH + top_future_x * 0.5f) / (float)surface->texture->width[0]; + vs_consts->mb_tc_trans[1].top_field.y = (mby * VL_MACROBLOCK_HEIGHT + top_future_y * 0.5f) / (float)surface->texture->height[0]; + vs_consts->mb_tc_trans[1].top_field.z = 0.0f; + vs_consts->mb_tc_trans[1].top_field.w = 0.0f; + + if (mc_type == vlMotionTypeField) + { + vs_consts->denorm.x = (float)surface->texture->width[0]; + vs_consts->denorm.y = (float)surface->texture->height[0]; + + vs_consts->mb_tc_trans[0].bottom_field.x = (mbx * VL_MACROBLOCK_WIDTH + bottom_past_x * 0.5f) / (float)surface->texture->width[0]; + vs_consts->mb_tc_trans[0].bottom_field.y = (mby * VL_MACROBLOCK_HEIGHT + bottom_past_y * 0.5f) / (float)surface->texture->height[0]; + vs_consts->mb_tc_trans[0].bottom_field.z = 0.0f; + vs_consts->mb_tc_trans[0].bottom_field.w = 0.0f; + vs_consts->mb_tc_trans[1].bottom_field.x = (mbx * VL_MACROBLOCK_WIDTH + bottom_future_x * 0.5f) / (float)surface->texture->width[0]; + vs_consts->mb_tc_trans[1].bottom_field.y = (mby * VL_MACROBLOCK_HEIGHT + bottom_future_y * 0.5f) / (float)surface->texture->height[0]; + vs_consts->mb_tc_trans[1].bottom_field.z = 0.0f; + vs_consts->mb_tc_trans[1].bottom_field.w = 0.0f; + + pipe->bind_vs_state(pipe, mc->b_vs[1]); + pipe->bind_fs_state(pipe, mc->b_fs[1]); + } + else + { + pipe->bind_vs_state(pipe, mc->b_vs[0]); + pipe->bind_fs_state(pipe, mc->b_fs[0]); + } + + pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer); + + mc->render_target.cbufs[0] = pipe->screen->get_tex_surface + ( + pipe->screen, + surface->texture, + 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE + ); + pipe->set_framebuffer_state(pipe, &mc->render_target); + + mc->textures[3] = past_surface->texture; + mc->textures[4] = future_surface->texture; + pipe->set_sampler_textures(pipe, 5, mc->textures); + pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); + + return 0; +} + +int vlRenderMacroBlocksMpeg2R16Snorm +( + struct vlRender *render, + struct vlMpeg2MacroBlockBatch *batch, + struct vlSurface *surface +) +{ + struct vlR16SnormMC *mc; + unsigned int i; + + assert(render); + + mc = (struct vlR16SnormMC*)render; + + /*for (i = 0; i < batch->num_macroblocks; ++i) + vlGrabMacroBlock(batch->macroblocks[i]);*/ + + for (i = 0; i < batch->num_macroblocks; ++i) + { + switch (batch->macroblocks[i].mb_type) + { + case vlMacroBlockTypeIntra: + { + vlRenderIMacroBlock + ( + mc, + batch->picture_type, + batch->field_order, + batch->macroblocks[i].mbx, + batch->macroblocks[i].mby, + batch->macroblocks[i].cbp, + batch->macroblocks[i].dct_type, + batch->macroblocks[i].blocks, + surface + ); + break; + } + case vlMacroBlockTypeFwdPredicted: + { + vlRenderPMacroBlock + ( + mc, + batch->picture_type, + batch->field_order, + batch->macroblocks[i].mbx, + batch->macroblocks[i].mby, + batch->macroblocks[i].mo_type, + batch->macroblocks[i].PMV[0][0][0], + batch->macroblocks[i].PMV[0][0][1], + batch->macroblocks[i].PMV[1][0][0], + batch->macroblocks[i].PMV[1][0][1], + batch->macroblocks[i].cbp, + batch->macroblocks[i].dct_type, + batch->macroblocks[i].blocks, + batch->past_surface, + surface + ); + break; + } + case vlMacroBlockTypeBkwdPredicted: + { + vlRenderPMacroBlock + ( + mc, + batch->picture_type, + batch->field_order, + batch->macroblocks[i].mbx, + batch->macroblocks[i].mby, + batch->macroblocks[i].mo_type, + batch->macroblocks[i].PMV[0][1][0], + batch->macroblocks[i].PMV[0][1][1], + batch->macroblocks[i].PMV[1][1][0], + batch->macroblocks[i].PMV[1][1][1], + batch->macroblocks[i].cbp, + batch->macroblocks[i].dct_type, + batch->macroblocks[i].blocks, + batch->future_surface, + surface + ); + break; + } + case vlMacroBlockTypeBiPredicted: + { + vlRenderBMacroBlock + ( + mc, + batch->picture_type, + batch->field_order, + batch->macroblocks[i].mbx, + batch->macroblocks[i].mby, + batch->macroblocks[i].mo_type, + batch->macroblocks[i].PMV[0][0][0], + batch->macroblocks[i].PMV[0][0][1], + batch->macroblocks[i].PMV[1][0][0], + batch->macroblocks[i].PMV[1][0][1], + batch->macroblocks[i].PMV[0][1][0], + batch->macroblocks[i].PMV[0][1][1], + batch->macroblocks[i].PMV[1][1][0], + batch->macroblocks[i].PMV[1][1][1], + batch->macroblocks[i].cbp, + batch->macroblocks[i].dct_type, + batch->macroblocks[i].blocks, + batch->past_surface, + batch->future_surface, + surface + ); + break; + } + default: + assert(0); + } + } + + return 0; +} + +int vlEnd +( + struct vlRender *render +) +{ + assert(render); + + return 0; +} + +int vlDestroy +( + struct vlRender *render +) +{ + struct vlR16SnormMC *mc; + struct pipe_context *pipe; + unsigned int i; + + assert(render); + + mc = (struct vlR16SnormMC*)render; + pipe = mc->pipe; + + for (i = 0; i < 5; ++i) + pipe->delete_sampler_state(pipe, mc->samplers[i]); + + for (i = 0; i < 3; ++i) + pipe->winsys->buffer_destroy(pipe->winsys, 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(&mc->textures[i]); + + pipe->delete_vs_state(pipe, mc->i_vs); + pipe->delete_fs_state(pipe, mc->i_fs); + + for (i = 0; i < 2; ++i) + { + pipe->delete_vs_state(pipe, mc->p_vs[i]); + pipe->delete_fs_state(pipe, mc->p_fs[i]); + pipe->delete_vs_state(pipe, mc->b_vs[i]); + pipe->delete_fs_state(pipe, mc->b_fs[i]); + } + + pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer); + pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer); + + free(mc); + + return 0; +} + +/* + * 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 vlVertex2f macroblock_verts[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 vlVertex2f macroblock_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 vlVertex2f *macroblock_chroma_420_texcoords = macroblock_verts; + +/* + * 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 vlVertex2f *macroblock_chroma_422_texcoords = macroblock_verts; + +/* + * Represents texcoords for the above for rendering 4 chroma blocks. + * Same case as 4 luma blocks. + */ +const struct vlVertex2f *macroblock_chroma_444_texcoords = macroblock_luma_texcoords; + +/* + * 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 vlFragmentShaderConsts fs_consts = +{ + {32767.0f / 255.0f, 32767.0f / 255.0f, 32767.0f / 255.0f, 0.0f}, + {0.5f, 2.0f, 0.0f, 0.0f} +}; + +static int vlCreateVertexShaderIMB +( + struct vlR16SnormMC *mc +) +{ + const unsigned int max_tokens = 50; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma texcoords + */ + for (i = 0; i < 3; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling vector to scale unit rect to macroblock size + * decl c1 ; Translation vector to move macroblock into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma texcoords + */ + for (i = 0; i < 3; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o0, t0, c1 ; Translate rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma texcoords to output + */ + for (i = 1; i < 3; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + mc->i_vs = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderIMB +( + struct vlR16SnormMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Texcoords for s0 + * decl i1 ; Texcoords for s1, s2 + */ + for (i = 0; i < 2; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + */ + for (i = 0; i < 3; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header,max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i1, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + } + + /* mul o0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + mc->i_fs = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFramePMB +( + struct vlR16SnormMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma texcoords + */ + for (i = 0; i < 3; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling vector to scale unit rect to macroblock size + * decl c1 ; Translation vector to move macroblock into position + * decl c2 ; Unused + * decl c3 ; Translation vector to move ref macroblock texcoords into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 3); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma texcoords + * decl o3 ; Ref macroblock texcoords + */ + for (i = 0; i < 4; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o0, t0, c1 ; Translate rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma texcoords to output + */ + for (i = 1; i < 3; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* add o3, t0, c3 ; Translate rect into position on ref macroblock */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + mc->p_vs[0] = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFieldPMB +( + struct vlR16SnormMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma texcoords + */ + for (i = 0; i < 3; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration + ( + &decl, + &tokens[ti], + header, + max_tokens - ti + ); + } + + /* + * decl c0 ; Scaling vector to scale unit rect to macroblock size + * decl c1 ; Translation vector to move macroblock into position + * decl c2 ; Denorm coefficients + * decl c3 ; Translation vector to move top field ref macroblock texcoords into position + * decl c4 ; Translation vector to move bottom field ref macroblock texcoords into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 4); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma texcoords + * decl o3 ; Top field ref macroblock texcoords + * decl o4 ; Bottom field ref macroblock texcoords + * decl o5 ; Denormalized vertex pos + */ + for (i = 0; i < 6; i++) + { + decl = vl_decl_output((i == 0 || i == 5) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add t1, t0, c1 ; Translate rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mov o0, t1 ; Move vertex pos to output */ + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + mov o1, i1 ; Move input luma texcoords to output + mov o2, i2 ; Move input chroma texcoords to output + */ + for (i = 1; i < 3; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* add o3, t0, c3 ; Translate top field rect into position on ref macroblock + add o4, t0, c4 ; Translate bottom field rect into position on ref macroblock */ + for (i = 0; i < 2; ++i) + { + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* mul o5, t1, c2 ; Denorm vertex pos */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 5, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 2); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + mc->p_vs[1] = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderFramePMB +( + struct vlR16SnormMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Texcoords for s0 + * decl i1 ; Texcoords for s1, s2 + * decl i2 ; Texcoords for s3 + */ + for (i = 0; i < 3; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for ref surface texture + */ + for (i = 0; i < 4; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i1, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + } + + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* tex2d t1, i2, s3 ; Read texel from ref macroblock */ + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 2, TGSI_FILE_SAMPLER, 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 = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + mc->p_fs[0] = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderFieldPMB +( + struct vlR16SnormMC *mc +) +{ + const unsigned int max_tokens = 200; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Texcoords for s0 + * decl i1 ; Texcoords for s1, s2 + * decl i2 ; Texcoords for s3 + * decl i3 ; Texcoords for s3 + * decl i4 ; Denormalized vertex pos + */ + for (i = 0; i < 5; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm + * decl c1 ; Constants 1/2 & 2 in .x, .y channels for Y-mod-2 top/bottom field selection + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0-t4 */ + decl = vl_decl_temps(0, 4); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for ref surface texture + */ + for (i = 0; i < 4; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i1, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + } + + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * tex2d t1, i2, s3 ; Read texel from ref macroblock top field + * tex2d t2, i3, s3 ; Read texel from ref macroblock bottom field + */ + for (i = 0; i < 2; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 2, TGSI_FILE_SAMPLER, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* XXX: Pos values off by 0.5? */ + /* sub t4, i4.y, c1.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 4, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* floor t3, t3 ; Get rid of fractional part */ + inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mul t3, t3, c1.y ; Multiply by 2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* TODO: Move to conditional tex fetch on t3 instead of lerp */ + /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + 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 = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + mc->p_fs[1] = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFrameBMB +( + struct vlR16SnormMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma texcoords + */ + for (i = 0; i < 3; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling vector to scale unit rect to macroblock size + * decl c1 ; Translation vector to move macroblock into position + * decl c2 ; Unused + * decl c3 ; Translation vector to move past ref macroblock texcoords into position + * decl c4 ; Unused + * decl c5 ; Translation vector to move future ref macroblock texcoords into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 5); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma texcoords + * decl o3 ; Past ref macroblock texcoords + * decl o4 ; Future ref macroblock texcoords + */ + for (i = 0; i < 5; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o0, t0, c1 ; Translate rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma texcoords to output + */ + for (i = 1; i < 3; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* add o3, t0, c3 ; Translate rect into position on past ref macroblock + add o4, t0, c5 ; Translate rect into position on future ref macroblock */ + for (i = 0; i < 2; ++i) + { + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i * 2 + 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + mc->b_vs[0] = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFieldBMB +( + struct vlR16SnormMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma texcoords + */ + for (i = 0; i < 3; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling vector to scale unit rect to macroblock size + * decl c1 ; Translation vector to move macroblock into position + * decl c2 ; Denorm coefficients + * decl c3 ; Translation vector to move top field past ref macroblock texcoords into position + * decl c4 ; Translation vector to move bottom field past ref macroblock texcoords into position + * decl c5 ; Translation vector to move top field future ref macroblock texcoords into position + * decl c6 ; Translation vector to move bottom field future ref macroblock texcoords into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 6); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma texcoords + * decl o3 ; Top field past ref macroblock texcoords + * decl o4 ; Bottom field past ref macroblock texcoords + * decl o5 ; Top field future ref macroblock texcoords + * decl o6 ; Bottom field future ref macroblock texcoords + * decl o7 ; Denormalized vertex pos + */ + for (i = 0; i < 8; i++) + { + decl = vl_decl_output((i == 0 || i == 7) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* mul t0, i0, c0 ; Scale unit rect to normalized MB size */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add t1, t0, c1 ; Translate rect into position */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mov o0, t1 ; Move vertex pos to output */ + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma texcoords to output + */ + for (i = 1; i < 3; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* + * add o3, t0, c3 ; Translate top field rect into position on past ref macroblock + * add o4, t0, c4 ; Translate bottom field rect into position on past ref macroblock + * add o5, t0, c5 ; Translate top field rect into position on future ref macroblock + * add o6, t0, c6 ; Translate bottom field rect into position on future ref macroblock + */ + for (i = 0; i < 4; ++i) + { + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 3, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* mul o7, t1, c2 ; Denorm vertex pos */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 7, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 2); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + mc->b_vs[1] = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderFrameBMB +( + struct vlR16SnormMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Texcoords for s0 + * decl i1 ; Texcoords for s1, s2 + * decl i2 ; Texcoords for s3 + * decl i3 ; Texcoords for s4 + */ + for (i = 0; i < 4; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm + * decl c1 ; Constant 1/2 in .x channel to use as weight to blend past and future texels + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0-t2 */ + decl = vl_decl_temps(0, 2); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for past ref surface texture + * decl s4 ; Sampler for future ref surface texture + */ + for (i = 0; i < 5; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i1, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + } + + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * tex2d t1, i2, s3 ; Read texel from past ref macroblock + * tex2d t2, i3, s4 ; Read texel from future ref macroblock + */ + for (i = 0; i < 2; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 2, TGSI_FILE_SAMPLER, i + 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o0, t0, t1 ; Add past/future ref and differential to form final output */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + mc->b_fs[0] = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderFieldBMB +( + struct vlR16SnormMC *mc +) +{ + const unsigned int max_tokens = 200; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Texcoords for s0 + * decl i1 ; Texcoords for s1, s2 + * decl i2 ; Texcoords for s3 + * decl i3 ; Texcoords for s3 + * decl i4 ; Texcoords for s4 + * decl i5 ; Texcoords for s4 + * decl i6 ; Denormalized vertex pos + */ + for (i = 0; i < 7; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm + * decl c1 ; Constants 1/2 & 2 in .x, .y channels to use as weight to blend past and future texels + * ; and for Y-mod-2 top/bottom field selection + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0-t5 */ + decl = vl_decl_temps(0, 5); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for past ref surface texture + * decl s4 ; Sampler for future ref surface texture + */ + for (i = 0; i < 5; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i1, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i > 0 ? 1 : 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + } + + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* XXX: Pos values off by 0.5? */ + /* sub t4, i6.y, c1.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 6, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* floor t3, t3 ; Get rid of fractional part */ + inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mul t3, t3, c1.y ; Multiply by 2 */ + inst = vl_inst3( TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * tex2d t1, i2, s3 ; Read texel from past ref macroblock top field + * tex2d t2, i3, s3 ; Read texel from past ref macroblock bottom field + */ + for (i = 0; i < 2; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 2, TGSI_FILE_SAMPLER, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* TODO: Move to conditional tex fetch on t3 instead of lerp */ + /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * tex2d t4, i4, s4 ; Read texel from future ref macroblock top field + * tex2d t5, i5, s4 ; Read texel from future ref macroblock bottom field + */ + for (i = 0; i < 2; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 4, TGSI_FILE_INPUT, i + 4, TGSI_FILE_SAMPLER, 4); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* TODO: Move to conditional tex fetch on t3 instead of lerp */ + /* lerp t2, t3, t4, t5 ; Choose between top and bottom fields based on Y % 2 */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 2, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 5); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o0, t0, t1 ; Add past/future ref and differential to form final output */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + mc->b_fs[1] = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +int vlCreateDataBufs +( + struct vlR16SnormMC *mc +) +{ + struct pipe_context *pipe; + unsigned int i; + + assert(mc); + + pipe = mc->pipe; + + /* Create our vertex buffer and vertex buffer element */ + mc->vertex_bufs[0].pitch = sizeof(struct vlVertex2f); + mc->vertex_bufs[0].max_index = 23; + mc->vertex_bufs[0].buffer_offset = 0; + mc->vertex_bufs[0].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vlVertex2f) * 24 + ); + + mc->vertex_elems[0].src_offset = 0; + mc->vertex_elems[0].vertex_buffer_index = 0; + mc->vertex_elems[0].nr_components = 2; + mc->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Create our texcoord buffers and texcoord buffer elements */ + for (i = 1; i < 3; ++i) + { + mc->vertex_bufs[i].pitch = sizeof(struct vlVertex2f); + mc->vertex_bufs[i].max_index = 23; + mc->vertex_bufs[i].buffer_offset = 0; + mc->vertex_bufs[i].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vlVertex2f) * 24 + ); + + mc->vertex_elems[i].src_offset = 0; + mc->vertex_elems[i].vertex_buffer_index = i; + mc->vertex_elems[i].nr_components = 2; + mc->vertex_elems[i].src_format = PIPE_FORMAT_R32G32_FLOAT; + } + + /* Fill buffers */ + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, mc->vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + macroblock_verts, + sizeof(struct vlVertex2f) * 24 + ); + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, mc->vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + macroblock_luma_texcoords, + sizeof(struct vlVertex2f) * 24 + ); + /* TODO: Accomodate 422, 444 */ + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, mc->vertex_bufs[2].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + macroblock_chroma_420_texcoords, + sizeof(struct vlVertex2f) * 24 + ); + + for (i = 0; i < 3; ++i) + pipe->winsys->buffer_unmap(pipe->winsys, mc->vertex_bufs[i].buffer); + + /* Create our constant buffer */ + mc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts); + mc->vs_const_buf.buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + mc->vs_const_buf.size + ); + + mc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts); + mc->fs_const_buf.buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + mc->fs_const_buf.size + ); + + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + &fs_consts, + sizeof(struct vlFragmentShaderConsts) + ); + + pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer); + + return 0; +} + +static int vlInit +( + struct vlR16SnormMC *mc +) +{ + struct pipe_context *pipe; + struct pipe_sampler_state sampler; + struct pipe_texture template; + unsigned int filters[5]; + unsigned int i; + + assert(mc); + + pipe = mc->pipe; + + /* For MC we render to textures, which are rounded up to nearest POT */ + mc->viewport.scale[0] = vlRoundUpPOT(mc->video_width); + mc->viewport.scale[1] = vlRoundUpPOT(mc->video_height); + mc->viewport.scale[2] = 1; + mc->viewport.scale[3] = 1; + mc->viewport.translate[0] = 0; + mc->viewport.translate[1] = 0; + mc->viewport.translate[2] = 0; + mc->viewport.translate[3] = 0; + + mc->render_target.width = vlRoundUpPOT(mc->video_width); + mc->render_target.height = vlRoundUpPOT(mc->video_height); + mc->render_target.num_cbufs = 1; + /* FB for MC stage is a vlSurface, set in vlSetRenderSurface() */ + mc->render_target.zsbuf = NULL; + + filters[0] = PIPE_TEX_FILTER_NEAREST; + filters[1] = mc->video_format == vlFormatYCbCr444 ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; + filters[2] = mc->video_format == vlFormatYCbCr444 ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; + filters[3] = PIPE_TEX_FILTER_LINEAR; + filters[4] = PIPE_TEX_FILTER_LINEAR; + + 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 = 0; + /*sampler.max_lod = ;*/ + /*sampler.border_color[i] = ;*/ + /*sampler.max_anisotropy = ;*/ + 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_R16_SNORM; + template.last_level = 0; + template.width[0] = 8; + template.height[0] = 8 * 4; + template.depth[0] = 1; + template.compressed = 0; + pf_get_block(template.format, &template.block); + + mc->textures[0] = pipe->screen->texture_create(pipe->screen, &template); + + if (mc->video_format == vlFormatYCbCr420) + template.height[0] = 8; + else if (mc->video_format == vlFormatYCbCr422) + template.height[0] = 8 * 2; + else if (mc->video_format == vlFormatYCbCr444) + template.height[0] = 8 * 4; + else + assert(0); + + mc->textures[1] = pipe->screen->texture_create(pipe->screen, &template); + mc->textures[2] = pipe->screen->texture_create(pipe->screen, &template); + + /* textures[3] & textures[4] are assigned from vlSurfaces for P and B macroblocks at render time */ + + vlCreateVertexShaderIMB(mc); + vlCreateFragmentShaderIMB(mc); + vlCreateVertexShaderFramePMB(mc); + vlCreateVertexShaderFieldPMB(mc); + vlCreateFragmentShaderFramePMB(mc); + vlCreateFragmentShaderFieldPMB(mc); + vlCreateVertexShaderFrameBMB(mc); + vlCreateVertexShaderFieldBMB(mc); + vlCreateFragmentShaderFrameBMB(mc); + vlCreateFragmentShaderFieldBMB(mc); + vlCreateDataBufs(mc); + + return 0; +} + +int vlCreateR16SNormMC +( + struct pipe_context *pipe, + unsigned int video_width, + unsigned int video_height, + enum vlFormat video_format, + struct vlRender **render +) +{ + struct vlR16SnormMC *mc; + + assert(pipe); + assert(render); + + mc = calloc(1, sizeof(struct vlR16SnormMC)); + + mc->base.vlBegin = &vlBegin; + mc->base.vlRenderMacroBlocksMpeg2 = &vlRenderMacroBlocksMpeg2R16Snorm; + mc->base.vlEnd = &vlEnd; + mc->base.vlDestroy = &vlDestroy; + mc->pipe = pipe; + mc->video_width = video_width; + mc->video_height = video_height; + + vlInit(mc); + + *render = &mc->base; + + return 0; +} diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.h b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.h new file mode 100644 index 0000000000..a6eecf05b6 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.h @@ -0,0 +1,18 @@ +#ifndef vl_mc_h +#define vl_mc_h + +#include "vl_types.h" + +struct pipe_context; +struct vlRender; + +int vlCreateR16SNormMC +( + struct pipe_context *pipe, + unsigned int video_width, + unsigned int video_height, + enum vlFormat video_format, + struct vlRender **render +); + +#endif diff --git a/src/gallium/state_trackers/g3dvl/vl_render.h b/src/gallium/state_trackers/g3dvl/vl_render.h new file mode 100644 index 0000000000..63016b5cbe --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_render.h @@ -0,0 +1,33 @@ +#ifndef vl_render_h +#define vl_render_h + +#include "vl_types.h" + +struct pipe_surface; + +struct vlRender +{ + int (*vlBegin) + ( + struct vlRender *render + ); + + int (*vlRenderMacroBlocksMpeg2) + ( + struct vlRender *render, + struct vlMpeg2MacroBlockBatch *batch, + struct vlSurface *surface + ); + + int (*vlEnd) + ( + struct vlRender *render + ); + + int (*vlDestroy) + ( + struct vlRender *render + ); +}; + +#endif diff --git a/src/gallium/state_trackers/g3dvl/vl_screen.c b/src/gallium/state_trackers/g3dvl/vl_screen.c new file mode 100644 index 0000000000..484f63b0d4 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_screen.c @@ -0,0 +1,115 @@ +#define VL_INTERNAL +#include "vl_screen.h" +#include +#include + +int vlCreateScreen +( + struct vlDisplay *display, + int screen, + struct pipe_screen *pscreen, + struct vlScreen **vl_screen +) +{ + struct vlScreen *scrn; + + assert(display); + assert(pscreen); + assert(vl_screen); + + scrn = calloc(1, sizeof(struct vlScreen)); + + if (!scrn) + return 1; + + scrn->display = display; + scrn->ordinal = screen; + scrn->pscreen = pscreen; + *vl_screen = scrn; + + return 0; +} + +int vlDestroyScreen +( + struct vlScreen *screen +) +{ + assert(screen); + + free(screen); + + return 0; +} + +struct vlDisplay* vlGetDisplay +( + struct vlScreen *screen +) +{ + assert(screen); + + return screen->display; +} + +struct pipe_screen* vlGetPipeScreen +( + struct vlScreen *screen +) +{ + assert(screen); + + return screen->pscreen; +} + +unsigned int vlGetMaxProfiles +( + struct vlScreen *screen +) +{ + assert(screen); + + return vlProfileCount; +} + +int vlQueryProfiles +( + struct vlScreen *screen, + enum vlProfile *profiles +) +{ + assert(screen); + assert(profiles); + + profiles[0] = vlProfileMpeg2Simple; + profiles[1] = vlProfileMpeg2Main; + + return 0; +} + +unsigned int vlGetMaxEntryPoints +( + struct vlScreen *screen +) +{ + assert(screen); + + return vlEntryPointCount; +} + +int vlQueryEntryPoints +( + struct vlScreen *screen, + enum vlProfile profile, + enum vlEntryPoint *entry_points +) +{ + assert(screen); + assert(entry_points); + + entry_points[0] = vlEntryPointIDCT; + entry_points[1] = vlEntryPointMC; + entry_points[2] = vlEntryPointCSC; + + return 0; +} diff --git a/src/gallium/state_trackers/g3dvl/vl_screen.h b/src/gallium/state_trackers/g3dvl/vl_screen.h new file mode 100644 index 0000000000..98f3d429b6 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_screen.h @@ -0,0 +1,63 @@ +#ifndef vl_screen_h +#define vl_screen_h + +#include "vl_types.h" + +struct pipe_screen; + +#ifdef VL_INTERNAL +struct vlScreen +{ + struct vlDisplay *display; + unsigned int ordinal; + struct pipe_screen *pscreen; +}; +#endif + +int vlCreateScreen +( + struct vlDisplay *display, + int screen, + struct pipe_screen *pscreen, + struct vlScreen **vl_screen +); + +int vlDestroyScreen +( + struct vlScreen *screen +); + +struct vlDisplay* vlGetDisplay +( + struct vlScreen *screen +); + +struct pipe_screen* vlGetPipeScreen +( + struct vlScreen *screen +); + +unsigned int vlGetMaxProfiles +( + struct vlScreen *screen +); + +int vlQueryProfiles +( + struct vlScreen *screen, + enum vlProfile *profiles +); + +unsigned int vlGetMaxEntryPoints +( + struct vlScreen *screen +); + +int vlQueryEntryPoints +( + struct vlScreen *screen, + enum vlProfile profile, + enum vlEntryPoint *entry_points +); + +#endif diff --git a/src/gallium/state_trackers/g3dvl/vl_shader_build.c b/src/gallium/state_trackers/g3dvl/vl_shader_build.c index 5f30e23ff8..51f1721a33 100644 --- a/src/gallium/state_trackers/g3dvl/vl_shader_build.c +++ b/src/gallium/state_trackers/g3dvl/vl_shader_build.c @@ -13,7 +13,7 @@ struct tgsi_full_declaration vl_decl_input(unsigned int name, unsigned int index decl.Semantic.SemanticIndex = index; decl.DeclarationRange.First = first; decl.DeclarationRange.Last = last; - + return decl; } @@ -27,7 +27,7 @@ struct tgsi_full_declaration vl_decl_interpolated_input ) { struct tgsi_full_declaration decl = tgsi_default_full_declaration(); - + assert ( interpolation == TGSI_INTERPOLATE_CONSTANT || @@ -42,21 +42,21 @@ struct tgsi_full_declaration vl_decl_interpolated_input decl.Declaration.Interpolate = interpolation;; decl.DeclarationRange.First = first; decl.DeclarationRange.Last = last; - + return decl; } struct tgsi_full_declaration vl_decl_constants(unsigned int name, unsigned int index, unsigned int first, unsigned int last) { struct tgsi_full_declaration decl = tgsi_default_full_declaration(); - + decl.Declaration.File = TGSI_FILE_CONSTANT; decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = name; decl.Semantic.SemanticIndex = index; decl.DeclarationRange.First = first; decl.DeclarationRange.Last = last; - + return decl; } @@ -70,7 +70,7 @@ struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int inde decl.Semantic.SemanticIndex = index; decl.DeclarationRange.First = first; decl.DeclarationRange.Last = last; - + return decl; } @@ -82,7 +82,7 @@ struct tgsi_full_declaration vl_decl_temps(unsigned int first, unsigned int last decl.Declaration.File = TGSI_FILE_TEMPORARY; decl.DeclarationRange.First = first; decl.DeclarationRange.Last = last; - + return decl; } @@ -94,7 +94,7 @@ struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int l decl.Declaration.File = TGSI_FILE_SAMPLER; decl.DeclarationRange.First = first; decl.DeclarationRange.Last = last; - + return decl; } @@ -108,7 +108,7 @@ struct tgsi_full_instruction vl_inst2 ) { struct tgsi_full_instruction inst = tgsi_default_full_instruction(); - + inst.Instruction.Opcode = opcode; inst.Instruction.NumDstRegs = 1; inst.FullDstRegisters[0].DstRegister.File = dst_file; @@ -116,7 +116,7 @@ struct tgsi_full_instruction vl_inst2 inst.Instruction.NumSrcRegs = 1; inst.FullSrcRegisters[0].SrcRegister.File = src_file; inst.FullSrcRegisters[0].SrcRegister.Index = src_index; - + return inst; } @@ -132,7 +132,7 @@ struct tgsi_full_instruction vl_inst3 ) { struct tgsi_full_instruction inst = tgsi_default_full_instruction(); - + inst.Instruction.Opcode = opcode; inst.Instruction.NumDstRegs = 1; inst.FullDstRegisters[0].DstRegister.File = dst_file; @@ -142,7 +142,7 @@ struct tgsi_full_instruction vl_inst3 inst.FullSrcRegisters[0].SrcRegister.Index = src1_index; inst.FullSrcRegisters[1].SrcRegister.File = src2_file; inst.FullSrcRegisters[1].SrcRegister.Index = src2_index; - + return inst; } @@ -158,7 +158,7 @@ struct tgsi_full_instruction vl_tex ) { struct tgsi_full_instruction inst = tgsi_default_full_instruction(); - + inst.Instruction.Opcode = TGSI_OPCODE_TEX; inst.Instruction.NumDstRegs = 1; inst.FullDstRegisters[0].DstRegister.File = dst_file; @@ -169,7 +169,7 @@ struct tgsi_full_instruction vl_tex inst.FullSrcRegisters[0].SrcRegister.Index = src1_index; inst.FullSrcRegisters[1].SrcRegister.File = src2_file; inst.FullSrcRegisters[1].SrcRegister.Index = src2_index; - + return inst; } @@ -187,7 +187,7 @@ struct tgsi_full_instruction vl_inst4 ) { struct tgsi_full_instruction inst = tgsi_default_full_instruction(); - + inst.Instruction.Opcode = opcode; inst.Instruction.NumDstRegs = 1; inst.FullDstRegisters[0].DstRegister.File = dst_file; @@ -199,18 +199,17 @@ struct tgsi_full_instruction vl_inst4 inst.FullSrcRegisters[1].SrcRegister.Index = src2_index; inst.FullSrcRegisters[2].SrcRegister.File = src3_file; inst.FullSrcRegisters[2].SrcRegister.Index = src3_index; - + return inst; } struct tgsi_full_instruction vl_end(void) { struct tgsi_full_instruction inst = tgsi_default_full_instruction(); - + inst.Instruction.Opcode = TGSI_OPCODE_END; inst.Instruction.NumDstRegs = 0; inst.Instruction.NumSrcRegs = 0; - + return inst; } - diff --git a/src/gallium/state_trackers/g3dvl/vl_shader_build.h b/src/gallium/state_trackers/g3dvl/vl_shader_build.h index 878d7e2c45..dc615cb156 100644 --- a/src/gallium/state_trackers/g3dvl/vl_shader_build.h +++ b/src/gallium/state_trackers/g3dvl/vl_shader_build.h @@ -59,4 +59,3 @@ struct tgsi_full_instruction vl_inst4 struct tgsi_full_instruction vl_end(void); #endif - diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 1386b1107c..ffc8122172 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -1,628 +1,177 @@ +#define VL_INTERNAL #include "vl_surface.h" #include #include -#include +#include +#include #include -#include #include #include +#include "vl_screen.h" #include "vl_context.h" -#include "vl_defs.h" +#include "vl_render.h" +#include "vl_csc.h" #include "vl_util.h" -/*#define DO_IDCT*/ - -#ifdef DO_IDCT -static int vlTransformBlock(short *src, short *dst, short bias) +int vlCreateSurface +( + struct vlScreen *screen, + unsigned int width, + unsigned int height, + enum vlFormat format, + struct vlSurface **surface +) { - static const float basis[8][8] = - { - {0.3536, 0.4904, 0.4619, 0.4157, 0.3536, 0.2778, 0.1913, 0.0975}, - {0.3536, 0.4157, 0.1913, -0.0975, -0.3536, -0.4904, -0.4619, -0.2778}, - {0.3536, 0.2778, -0.1913, -0.4904, -0.3536, 0.0975, 0.4619, 0.4157}, - {0.3536, 0.0975, -0.4619, -0.2778, 0.3536, 0.4157, -0.1913, -0.4904}, - {0.3536, -0.0975, -0.4619, 0.2778, 0.3536, -0.4157, -0.1913, 0.4904}, - {0.3536, -0.2778, -0.1913, 0.4904, -0.3536, -0.0975, 0.4619, -0.4157}, - {0.3536, -0.4157, 0.1913, 0.0975, -0.3536, 0.4904, -0.4619, 0.2778}, - {0.3536, -0.4904, 0.4619, -0.4157, 0.3536, -0.2778, 0.1913, -0.0975} - }; - - unsigned int x, y; - short tmp[64]; - - for (y = 0; y < VL_BLOCK_HEIGHT; ++y) - for (x = 0; x < VL_BLOCK_WIDTH; ++x) - tmp[y * VL_BLOCK_WIDTH + x] = (short) - ( - src[y * VL_BLOCK_WIDTH + 0] * basis[x][0] + - src[y * VL_BLOCK_WIDTH + 1] * basis[x][1] + - src[y * VL_BLOCK_WIDTH + 2] * basis[x][2] + - src[y * VL_BLOCK_WIDTH + 3] * basis[x][3] + - src[y * VL_BLOCK_WIDTH + 4] * basis[x][4] + - src[y * VL_BLOCK_WIDTH + 5] * basis[x][5] + - src[y * VL_BLOCK_WIDTH + 6] * basis[x][6] + - src[y * VL_BLOCK_WIDTH + 7] * basis[x][7] - ); - - for (x = 0; x < VL_BLOCK_WIDTH; ++x) - for (y = 0; y < VL_BLOCK_HEIGHT; ++y) - { - dst[y * VL_BLOCK_WIDTH + x] = bias + (short) - ( - tmp[0 * VL_BLOCK_WIDTH + x] * basis[y][0] + - tmp[1 * VL_BLOCK_WIDTH + x] * basis[y][1] + - tmp[2 * VL_BLOCK_WIDTH + x] * basis[y][2] + - tmp[3 * VL_BLOCK_WIDTH + x] * basis[y][3] + - tmp[4 * VL_BLOCK_WIDTH + x] * basis[y][4] + - tmp[5 * VL_BLOCK_WIDTH + x] * basis[y][5] + - tmp[6 * VL_BLOCK_WIDTH + x] * basis[y][6] + - tmp[7 * VL_BLOCK_WIDTH + x] * basis[y][7] - ); - if (dst[y * VL_BLOCK_WIDTH + x] > 255) - dst[y * VL_BLOCK_WIDTH + x] = 255; - else if (bias > 0 && dst[y * VL_BLOCK_WIDTH + x] < 0) - dst[y * VL_BLOCK_WIDTH + x] = 0; - } - return 0; -} -#endif + struct vlSurface *sfc; + struct pipe_texture template; -static int vlGrabFrameCodedBlock(short *src, short *dst, unsigned int dst_pitch) -{ - unsigned int y; - - for (y = 0; y < VL_BLOCK_HEIGHT; ++y) - memcpy - ( - dst + y * dst_pitch, - src + y * VL_BLOCK_WIDTH, - VL_BLOCK_WIDTH * 2 - ); - - return 0; -} + assert(screen); + assert(surface); -static int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst_pitch) -{ - unsigned int y; - - for (y = 0; y < VL_BLOCK_HEIGHT / 2; ++y) - memcpy - ( - dst + y * dst_pitch * 2, - src + y * VL_BLOCK_WIDTH, - VL_BLOCK_WIDTH * 2 - ); - - dst += VL_BLOCK_HEIGHT * dst_pitch; - - for (; y < VL_BLOCK_HEIGHT; ++y) - memcpy - ( - dst + y * dst_pitch * 2, - src + y * VL_BLOCK_WIDTH, - VL_BLOCK_WIDTH * 2 - ); - - return 0; -} + sfc = calloc(1, sizeof(struct vlSurface)); -static int vlGrabNoBlock(short *dst, unsigned int dst_pitch) -{ - unsigned int y; - - for (y = 0; y < VL_BLOCK_HEIGHT; ++y) - memset - ( - dst + y * dst_pitch, - 0, - VL_BLOCK_WIDTH * 2 - ); - - return 0; -} + if (!sfc) + return 1; -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 tex_pitch; - unsigned int tb, sb = 0; - - 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, PIPE_BUFFER_USAGE_CPU_WRITE); - tex_pitch = tex_surface->stride / tex_surface->block.size; - - for (tb = 0; tb < 4; ++tb) - { - if ((coded_block_pattern >> (5 - tb)) & 1) - { - short *cur_block = blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; - -#ifdef DO_IDCT - vlTransformBlock(cur_block, cur_block, sample_type == VL_FULL_SAMPLE ? 128 : 0); -#endif - - if (dct_type == VL_DCT_FRAME_CODED) - vlGrabFrameCodedBlock - ( - cur_block, - texels + tb * tex_pitch * VL_BLOCK_HEIGHT, - tex_pitch - ); - else - vlGrabFieldCodedBlock - ( - cur_block, - texels + (tb % 2) * tex_pitch * VL_BLOCK_HEIGHT + (tb / 2) * tex_pitch, - tex_pitch - ); - - ++sb; - } - else - vlGrabNoBlock(texels + tb * tex_pitch * VL_BLOCK_HEIGHT, tex_pitch); - } - - pipe_surface_unmap(tex_surface); - - /* TODO: Implement 422, 444 */ - for (tb = 0; tb < 2; ++tb) - { - tex_surface = context->pipe->screen->get_tex_surface - ( - context->pipe->screen, - context->states.mc.textures[tb + 1], - 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE - ); - - texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); - tex_pitch = tex_surface->stride / tex_surface->block.size; - - if ((coded_block_pattern >> (1 - tb)) & 1) - { - short *cur_block = blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; - -#ifdef DO_IDCT - vlTransformBlock(cur_block, cur_block, sample_type == VL_FULL_SAMPLE ? 128 : 0); -#endif - - vlGrabFrameCodedBlock - ( - cur_block, - texels, - tex_pitch - ); - - ++sb; - } - else - vlGrabNoBlock(texels, tex_pitch); - - pipe_surface_unmap(tex_surface); - } - - return 0; -} + sfc->screen = screen; + sfc->width = width; + sfc->height = height; + sfc->format = format; -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 = vlRoundUpPOT(context->video_width); - sfc->height = vlRoundUpPOT(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.width[0] = vlRoundUpPOT(sfc->width); + template.height[0] = vlRoundUpPOT(sfc->height); template.depth[0] = 1; template.compressed = 0; pf_get_block(template.format, &template.block); - /* XXX: Needed? */ template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; - - sfc->texture = pipe->screen->texture_create(pipe->screen, &template); - + + sfc->texture = vlGetPipeScreen(screen)->texture_create(vlGetPipeScreen(screen), &template); + *surface = sfc; - + return 0; } -int vlDestroySurface(struct VL_SURFACE *surface) +int vlDestroySurface +( + struct vlSurface *surface +) { assert(surface); + pipe_texture_release(&surface->texture); free(surface); - + return 0; } -int vlRenderIMacroBlock +int vlRenderMacroBlocksMpeg2 ( - 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 vlMpeg2MacroBlockBatch *batch, + struct vlSurface *surface ) { - struct pipe_context *pipe; - struct VL_MC_VS_CONSTS *vs_consts; - - assert(blocks); + assert(batch); assert(surface); - - /* TODO: Implement interlaced rendering */ - if (picture_type != VL_FRAME_PICTURE) - return 0; - - vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_FULL_SAMPLE, blocks); - - pipe = surface->context->pipe; - - vs_consts = pipe->winsys->buffer_map - ( - pipe->winsys, - surface->context->states.mc.vs_const_buf.buffer, - PIPE_BUFFER_USAGE_CPU_WRITE - ); - - vs_consts->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width; - vs_consts->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height; - vs_consts->scale.z = 1.0f; - vs_consts->scale.w = 1.0f; - vs_consts->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width; - vs_consts->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height; - vs_consts->mb_pos_trans.z = 0.0f; - vs_consts->mb_pos_trans.w = 0.0f; - - pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.mc.vs_const_buf.buffer); - - surface->context->states.mc.render_target.cbufs[0] = pipe->screen->get_tex_surface + + surface->context->render->vlBegin(surface->context->render); + + surface->context->render->vlRenderMacroBlocksMpeg2 ( - pipe->screen, - surface->texture, - 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE + surface->context->render, + batch, + surface ); - 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); - + + surface->context->render->vlEnd(surface->context->render); + return 0; } -int vlRenderPMacroBlock +int vlPutPicture ( - 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 vlSurface *surface, + vlNativeDrawable drawable, + int srcx, + int srcy, + int srcw, + int srch, + int destx, + int desty, + int destw, + int desth, + enum vlPictureType picture_type ) { + struct vlCSC *csc; struct pipe_context *pipe; - struct VL_MC_VS_CONSTS *vs_consts; - - assert(motion_vectors); - assert(blocks); - assert(ref_surface); + assert(surface); - - /* TODO: Implement interlaced rendering */ - if (picture_type != VL_FRAME_PICTURE) - return 0; - /* TODO: Implement other MC types */ - if (mc_type != VL_FRAME_MC && mc_type != VL_FIELD_MC) - return 0; - - vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks); - + assert(surface->context); + + csc = surface->context->csc; pipe = surface->context->pipe; - - vs_consts = pipe->winsys->buffer_map + + csc->vlResizeFrameBuffer(csc, destw, desth); + + csc->vlBegin(csc); + + csc->vlPutPicture ( - pipe->winsys, - surface->context->states.mc.vs_const_buf.buffer, - PIPE_BUFFER_USAGE_CPU_WRITE + csc, + surface, + srcx, + srcy, + srcw, + srch, + destx, + desty, + destw, + desth, + picture_type ); - - vs_consts->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width; - vs_consts->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height; - vs_consts->scale.z = 1.0f; - vs_consts->scale.w = 1.0f; - vs_consts->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width; - vs_consts->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height; - vs_consts->mb_pos_trans.z = 0.0f; - vs_consts->mb_pos_trans.w = 0.0f; - vs_consts->mb_tc_trans[0].top_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector->top_field.x * 0.5f) / (float)surface->width; - vs_consts->mb_tc_trans[0].top_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector->top_field.y * 0.5f) / (float)surface->height; - vs_consts->mb_tc_trans[0].top_field.z = 0.0f; - vs_consts->mb_tc_trans[0].top_field.w = 0.0f; - - if (mc_type == VL_FIELD_MC) - { - vs_consts->denorm.x = (float)surface->width; - vs_consts->denorm.y = (float)surface->height; - - vs_consts->mb_tc_trans[0].bottom_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector->bottom_field.x * 0.5f) / (float)surface->width; - vs_consts->mb_tc_trans[0].bottom_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector->bottom_field.y * 0.5f) / (float)surface->height; - vs_consts->mb_tc_trans[0].bottom_field.z = 0.0f; - vs_consts->mb_tc_trans[0].bottom_field.w = 0.0f; - - pipe->bind_vs_state(pipe, surface->context->states.mc.p_vs[1]); - pipe->bind_fs_state(pipe, surface->context->states.mc.p_fs[1]); - } - else - { - pipe->bind_vs_state(pipe, surface->context->states.mc.p_vs[0]); - pipe->bind_fs_state(pipe, surface->context->states.mc.p_fs[0]); - } - - pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.mc.vs_const_buf.buffer); - - surface->context->states.mc.render_target.cbufs[0] = pipe->screen->get_tex_surface + + csc->vlEnd(csc); + + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + bind_pipe_drawable(pipe, drawable); + /* TODO: Need to take destx, desty into consideration */ + pipe->winsys->flush_frontbuffer ( - pipe->screen, - surface->texture, - 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE + pipe->winsys, + csc->vlGetFrameBuffer(csc), + pipe->priv ); - 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->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); - + return 0; } -int vlRenderBMacroBlock +struct vlScreen* vlSurfaceGetScreen ( - 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 vlSurface *surface ) { - struct pipe_context *pipe; - struct VL_MC_VS_CONSTS *vs_consts; - - assert(motion_vectors); - assert(blocks); - assert(ref_surface); assert(surface); - - /* TODO: Implement interlaced rendering */ - if (picture_type != VL_FRAME_PICTURE) - return 0; - /* TODO: Implement other MC types */ - if (mc_type != VL_FRAME_MC && mc_type != VL_FIELD_MC) - return 0; - - vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks); - - pipe = surface->context->pipe; - - vs_consts = pipe->winsys->buffer_map - ( - pipe->winsys, - surface->context->states.mc.vs_const_buf.buffer, - PIPE_BUFFER_USAGE_CPU_WRITE - ); - - vs_consts->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width; - vs_consts->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height; - vs_consts->scale.z = 1.0f; - vs_consts->scale.w = 1.0f; - vs_consts->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width; - vs_consts->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height; - vs_consts->mb_pos_trans.z = 0.0f; - vs_consts->mb_pos_trans.w = 0.0f; - vs_consts->mb_tc_trans[0].top_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[0].top_field.x * 0.5f) / (float)surface->width; - vs_consts->mb_tc_trans[0].top_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[0].top_field.y * 0.5f) / (float)surface->height; - vs_consts->mb_tc_trans[0].top_field.z = 0.0f; - vs_consts->mb_tc_trans[0].top_field.w = 0.0f; - vs_consts->mb_tc_trans[1].top_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[1].top_field.x * 0.5f) / (float)surface->width; - vs_consts->mb_tc_trans[1].top_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[1].top_field.y * 0.5f) / (float)surface->height; - vs_consts->mb_tc_trans[1].top_field.z = 0.0f; - vs_consts->mb_tc_trans[1].top_field.w = 0.0f; - - if (mc_type == VL_FIELD_MC) - { - vs_consts->denorm.x = (float)surface->width; - vs_consts->denorm.y = (float)surface->height; - - vs_consts->mb_tc_trans[0].bottom_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[0].bottom_field.x * 0.5f) / (float)surface->width; - vs_consts->mb_tc_trans[0].bottom_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[0].bottom_field.y * 0.5f) / (float)surface->height; - vs_consts->mb_tc_trans[0].bottom_field.z = 0.0f; - vs_consts->mb_tc_trans[0].bottom_field.w = 0.0f; - vs_consts->mb_tc_trans[1].bottom_field.x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[1].bottom_field.x * 0.5f) / (float)surface->width; - vs_consts->mb_tc_trans[1].bottom_field.y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[1].bottom_field.y * 0.5f) / (float)surface->height; - vs_consts->mb_tc_trans[1].bottom_field.z = 0.0f; - vs_consts->mb_tc_trans[1].bottom_field.w = 0.0f; - - pipe->bind_vs_state(pipe, surface->context->states.mc.b_vs[1]); - pipe->bind_fs_state(pipe, surface->context->states.mc.b_fs[1]); - } - else - { - pipe->bind_vs_state(pipe, surface->context->states.mc.b_vs[0]); - pipe->bind_fs_state(pipe, surface->context->states.mc.b_fs[0]); - } - - pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.mc.vs_const_buf.buffer); - - surface->context->states.mc.render_target.cbufs[0] = pipe->screen->get_tex_surface - ( - pipe->screen, - surface->texture, - 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_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->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); - - return 0; + + return surface->screen; } -int vlPutSurface +struct vlContext* vlBindToContext ( - 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 + struct vlSurface *surface, + struct vlContext *context ) { - unsigned int create_fb = 0; - struct pipe_context *pipe; - struct VL_CSC_VS_CONSTS *vs_consts; - + struct vlContext *old; + 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, - /* XXX: SoftPipe doesn't change GPU usage to CPU like it does for textures */ - PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE, - 0 - ); - } - - vlEndRender(surface->context); - - vs_consts = pipe->winsys->buffer_map - ( - pipe->winsys, - surface->context->states.csc.vs_const_buf.buffer, - PIPE_BUFFER_USAGE_CPU_WRITE - ); - - vs_consts->src_scale.x = srcw / (float)surface->width; - vs_consts->src_scale.y = srch / (float)surface->height; - vs_consts->src_scale.z = 1; - vs_consts->src_scale.w = 1; - vs_consts->src_trans.x = srcx / (float)surface->width; - vs_consts->src_trans.y = srcy / (float)surface->height; - vs_consts->src_trans.z = 0; - vs_consts->src_trans.w = 0; - - pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.csc.vs_const_buf.buffer); - - 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); - bind_pipe_drawable(pipe, drawable); - /* TODO: Need to take destx, desty into consideration */ - pipe->winsys->flush_frontbuffer - ( - pipe->winsys, - surface->context->states.csc.framebuffer.cbufs[0], - pipe->priv - ); - - vlBeginRender(surface->context); - - return 0; -} + old = surface->context; + surface->context = context; + + return old; +} diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.h b/src/gallium/state_trackers/g3dvl/vl_surface.h index 9f56b77e1e..b975e131fa 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.h +++ b/src/gallium/state_trackers/g3dvl/vl_surface.h @@ -1,81 +1,66 @@ #ifndef vl_surface_h #define vl_surface_h -#include #include "vl_types.h" +#ifdef VL_INTERNAL struct pipe_texture; -struct VL_SURFACE +struct vlSurface { - struct VL_CONTEXT *context; + struct vlScreen *screen; + struct vlContext *context; unsigned int width; unsigned int height; - enum VL_FORMAT format; + enum vlFormat format; struct pipe_texture *texture; }; +#endif -int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface); +int vlCreateSurface +( + struct vlScreen *screen, + unsigned int width, + unsigned int height, + enum vlFormat format, + struct vlSurface **surface +); -int vlDestroySurface(struct VL_SURFACE *surface); +int vlDestroySurface +( + struct vlSurface *surface +); -int vlRenderIMacroBlock +int vlRenderMacroBlocksMpeg2 ( - 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 vlMpeg2MacroBlockBatch *batch, + struct vlSurface *surface ); -int vlRenderPMacroBlock +int vlPutPicture ( - 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 vlSurface *surface, + vlNativeDrawable drawable, + int srcx, + int srcy, + int srcw, + int srch, + int destx, + int desty, + int destw, + int desth, + enum vlPictureType picture_type ); -int vlRenderBMacroBlock +struct vlScreen* vlSurfaceGetScreen ( - 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 vlSurface *surface ); -int vlPutSurface +struct vlContext* vlBindToContext ( - 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 + struct vlSurface *surface, + struct vlContext *context ); #endif - diff --git a/src/gallium/state_trackers/g3dvl/vl_types.h b/src/gallium/state_trackers/g3dvl/vl_types.h index 4d210c9e0a..504ba8ac81 100644 --- a/src/gallium/state_trackers/g3dvl/vl_types.h +++ b/src/gallium/state_trackers/g3dvl/vl_types.h @@ -1,102 +1,106 @@ #ifndef vl_types_h #define vl_types_h -enum VL_FORMAT -{ - VL_FORMAT_YCBCR_420, - VL_FORMAT_YCBCR_422, - VL_FORMAT_YCBCR_444 -}; +#if 1 /*#ifdef X11*/ +#include -enum VL_PICTURE -{ - VL_TOP_FIELD, - VL_BOTTOM_FIELD, - VL_FRAME_PICTURE -}; +typedef Display* vlNativeDisplay; +typedef Drawable vlNativeDrawable; +#endif + +struct vlDisplay; +struct vlScreen; +struct vlContext; +struct vlSurface; -enum VL_FIELD_ORDER +enum vlProfile { - VL_FIELD_FIRST, - VL_FIELD_SECOND + vlProfileMpeg2Simple, + vlProfileMpeg2Main, + + vlProfileCount }; -enum VL_DCT_TYPE +enum vlEntryPoint { - VL_DCT_FIELD_CODED, - VL_DCT_FRAME_CODED + vlEntryPointIDCT, + vlEntryPointMC, + vlEntryPointCSC, + + vlEntryPointCount }; -enum VL_SAMPLE_TYPE +enum vlFormat { - VL_FULL_SAMPLE, - VL_DIFFERENCE_SAMPLE + vlFormatYCbCr420, + vlFormatYCbCr422, + vlFormatYCbCr444 }; -enum VL_MC_TYPE +enum vlPictureType { - VL_FIELD_MC, - VL_FRAME_MC, - VL_DUAL_PRIME_MC, - VL_16x8_MC = VL_FRAME_MC + vlPictureTypeTopField, + vlPictureTypeBottomField, + vlPictureTypeFrame }; -struct VL_VERTEX4F +enum vlMotionType { - float x, y, z, w; + vlMotionTypeField, + vlMotionTypeFrame, + vlMotionTypeDualPrime, + vlMotionType16x8 }; -struct VL_VERTEX2F +enum vlFieldOrder { - float x, y; + vlFieldOrderFirst, + vlFieldOrderSecond }; -struct VL_TEXCOORD2F +enum vlDCTType { - float s, t; + vlDCTTypeFrameCoded, + vlDCTTypeFieldCoded }; -struct VL_MC_VS_CONSTS +struct vlVertex2f { - struct VL_VERTEX4F scale; - struct VL_VERTEX4F mb_pos_trans; - struct VL_VERTEX4F denorm; - struct - { - struct VL_VERTEX4F top_field; - struct VL_VERTEX4F bottom_field; - } mb_tc_trans[2]; + float x, y; }; -struct VL_MC_FS_CONSTS +struct vlVertex4f { - struct VL_VERTEX4F multiplier; - struct VL_VERTEX4F bias; - struct VL_VERTEX4F y_divider; + float x, y, z, w; }; -struct VL_CSC_VS_CONSTS +enum vlMacroBlockType { - struct VL_VERTEX4F src_scale; - struct VL_VERTEX4F src_trans; + vlMacroBlockTypeIntra, + vlMacroBlockTypeFwdPredicted, + vlMacroBlockTypeBkwdPredicted, + vlMacroBlockTypeBiPredicted }; -struct VL_CSC_FS_CONSTS +struct vlMpeg2MacroBlock { - struct VL_VERTEX4F bias; - float matrix[16]; + unsigned int mbx, mby; + enum vlMacroBlockType mb_type; + enum vlMotionType mo_type; + enum vlDCTType dct_type; + int PMV[2][2][2]; + unsigned int cbp; + short *blocks; }; -struct VL_MOTION_VECTOR +struct vlMpeg2MacroBlockBatch { - struct - { - int x, y; - } top_field, bottom_field; + struct vlSurface *past_surface; + struct vlSurface *future_surface; + enum vlPictureType picture_type; + enum vlFieldOrder field_order; + unsigned int num_macroblocks; + struct vlMpeg2MacroBlock *macroblocks; }; -struct VL_CONTEXT; -struct VL_SURFACE; - #endif - diff --git a/src/gallium/state_trackers/g3dvl/vl_util.c b/src/gallium/state_trackers/g3dvl/vl_util.c index 2421ae2210..50aa9af66f 100644 --- a/src/gallium/state_trackers/g3dvl/vl_util.c +++ b/src/gallium/state_trackers/g3dvl/vl_util.c @@ -4,14 +4,13 @@ unsigned int vlRoundUpPOT(unsigned int x) { unsigned int i; - + assert(x > 0); - + --x; - + for (i = 1; i < sizeof(unsigned int) * 8; i <<= 1) x |= x >> i; - + return x + 1; } - diff --git a/src/gallium/state_trackers/g3dvl/vl_util.h b/src/gallium/state_trackers/g3dvl/vl_util.h index e4b72c4f87..bc98e79df4 100644 --- a/src/gallium/state_trackers/g3dvl/vl_util.h +++ b/src/gallium/state_trackers/g3dvl/vl_util.h @@ -4,4 +4,3 @@ unsigned int vlRoundUpPOT(unsigned int x); #endif - diff --git a/src/libXvMC/block.c b/src/libXvMC/block.c index deca305bdc..328b035576 100644 --- a/src/libXvMC/block.c +++ b/src/libXvMC/block.c @@ -2,83 +2,78 @@ #include #include #include +#include +#include #include -/* - * 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. - */ #define BLOCK_SIZE (64 * 2) Status XvMCCreateBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCBlockArray *blocks) { - struct vl_context *vl_ctx; - + struct vlContext *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); + assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx)))); 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; - + struct vlContext *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); - + assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx)))); + 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 index 9cf654d6bb..760e012d1a 100644 --- a/src/libXvMC/context.c +++ b/src/libXvMC/context.c @@ -1,10 +1,23 @@ #include #include #include +#include +#include +#include #include #include -static Status Validate(Display *display, XvPortID port, int surface_type_id, unsigned int width, unsigned int height, int flags, int *chroma_format) +static Status Validate +( + Display *display, + XvPortID port, + int surface_type_id, + unsigned int width, + unsigned int height, + int flags, + int *chroma_format, + int *mc_type +) { unsigned int found_port = 0; unsigned int found_surface = 0; @@ -14,13 +27,13 @@ static Status Validate(Display *display, XvPortID port, int surface_type_id, uns 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) { @@ -31,10 +44,10 @@ static Status Validate(Display *display, XvPortID port, int surface_type_id, uns 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) @@ -45,9 +58,10 @@ static Status Validate(Display *display, XvPortID port, int surface_type_id, uns max_width = surface_info[k].max_width; max_height = surface_info[k].max_height; *chroma_format = surface_info[k].chroma_format; + *mc_type = surface_info[k].mc_type; } } - + XFree(surface_info); } else @@ -58,9 +72,9 @@ static Status Validate(Display *display, XvPortID port, int surface_type_id, uns } } } - + XvFreeAdaptorInfo(adaptor_info); - + if (!found_port) return XvBadPort; if (!found_surface) @@ -69,60 +83,86 @@ static Status Validate(Display *display, XvPortID port, int surface_type_id, uns return BadValue; if (flags != XVMC_DIRECT && flags != 0) return BadValue; - + return Success; } -static enum VL_FORMAT FormatToVL(int xvmc_format) +static enum vlProfile ProfileToVL(int xvmc_profile) +{ + if (xvmc_profile & XVMC_MPEG_1) + assert(0); + else if (xvmc_profile & XVMC_MPEG_2) + return vlProfileMpeg2Main; + else if (xvmc_profile & XVMC_H263) + assert(0); + else if (xvmc_profile & XVMC_MPEG_4) + assert(0); + else + assert(0); + + return -1; +} + +static enum vlEntryPoint EntryToVL(int xvmc_entry) +{ + return xvmc_entry & XVMC_IDCT ? vlEntryPointIDCT : vlEntryPointMC; +} + +static enum vlFormat FormatToVL(int xvmc_format) { - enum VL_FORMAT vl_format; - switch (xvmc_format) { case XVMC_CHROMA_FORMAT_420: - { - vl_format = VL_FORMAT_YCBCR_420; - break; - } + return vlFormatYCbCr420; case XVMC_CHROMA_FORMAT_422: - { - vl_format = VL_FORMAT_YCBCR_422; - break; - } + return vlFormatYCbCr422; case XVMC_CHROMA_FORMAT_444: - { - vl_format = VL_FORMAT_YCBCR_444; - break; - } + return vlFormatYCbCr444; default: assert(0); } - - return vl_format; + + return -1; } Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context) { int chroma_format; + int mc_type; Status ret; - struct VL_CONTEXT *vl_ctx; + struct vlDisplay *vl_dpy; + struct vlScreen *vl_scrn; + struct vlContext *vl_ctx; struct pipe_context *pipe; - + assert(display); - + if (!context) return XvMCBadContext; - - ret = Validate(display, port, surface_type_id, width, height, flags, &chroma_format); + + ret = Validate(display, port, surface_type_id, width, height, flags, &chroma_format, &mc_type); if (ret != Success) return ret; - + + /* XXX: Assumes default screen, should check which screen port is on */ pipe = create_pipe_context(display, XDefaultScreen(display)); - + assert(pipe); - - vlCreateContext(display, pipe, width, height, FormatToVL(chroma_format), &vl_ctx); - + + vlCreateDisplay(display, &vl_dpy); + vlCreateScreen(vl_dpy, XDefaultScreen(display), pipe->screen, &vl_scrn); + vlCreateContext + ( + vl_scrn, + pipe, + width, + height, + FormatToVL(chroma_format), + ProfileToVL(mc_type), + EntryToVL(mc_type), + &vl_ctx + ); + context->context_id = XAllocID(display); context->surface_type_id = surface_type_id; context->width = width; @@ -130,89 +170,27 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, i context->flags = flags; context->port = port; context->privData = vl_ctx; - + return Success; } Status XvMCDestroyContext(Display *display, XvMCContext *context) { - struct VL_CONTEXT *vl_ctx; + struct vlContext *vl_ctx; struct pipe_context *pipe; - + assert(display); - + if (!context) return XvMCBadContext; - + vl_ctx = context->privData; - - assert(display == vl_ctx->display); - - pipe = vl_ctx->pipe; - vlDestroyContext(vl_ctx); - destroy_pipe_context(pipe); - - return Success; -} -/* XXX: The following are here temporarily, need to be implemented in the DDX driver */ -/* TODO: Figure out which of these need to be in DDX, which are better off in DDX, which can stay */ + assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx)))); -Bool XvMCQueryExtension(Display *display, int *event_base, int *err_base) -{ - *event_base = 0; - *err_base = 0; - - return True; -} + pipe = vlGetPipeContext(vl_ctx); + vlDestroyContext(vl_ctx); + destroy_pipe_context(pipe); -Status XvMCQueryVersion(Display *display, int *major, int *minor) -{ - *major = 1; - *minor = 0; - return Success; } - -XvMCSurfaceInfo* XvMCListSurfaceTypes(Display *display, XvPortID port, int *num) -{ - XvMCSurfaceInfo *surface_info = calloc(1, sizeof(XvMCSurfaceInfo)); - - *num = 1; - - surface_info->chroma_format = XVMC_CHROMA_FORMAT_420; - surface_info->max_width = 2048; - surface_info->max_height = 2048; - surface_info->subpicture_max_width = 2048; - surface_info->subpicture_max_height = 2048; - surface_info->mc_type = XVMC_IDCT | XVMC_MPEG_2; - surface_info->surface_type_id = 123; /* FIXME: XAllocID(display)*/; - surface_info->flags = XVMC_INTRA_UNSIGNED | XVMC_SUBPICTURE_INDEPENDENT_SCALING | XVMC_BACKEND_SUBPICTURE; - - return surface_info; -} - -XvImageFormatValues* XvMCListSubpictureTypes(Display* display, XvPortID port, int surface_type_id, int *count_return) -{ - XvImageFormatValues *image_formats = calloc(1, sizeof(XvImageFormatValues)); - - *count_return = 1; - - image_formats[0].id = 123; - image_formats[0].type = XvRGB; - image_formats[0].byte_order = LSBFirst; - image_formats[0].bits_per_pixel = 8; - image_formats[0].format = XvPacked; - image_formats[0].num_planes = 1; - image_formats[0].depth = 8; - image_formats[0].red_mask = 0x0000FF; - image_formats[0].green_mask = 0x00FF00; - image_formats[0].blue_mask = 0xFF0000; - image_formats[0].component_order[0] = 'R'; - image_formats[0].component_order[0] = 'G'; - image_formats[0].component_order[0] = 'B'; - image_formats[0].scanline_order = XvTopToBottom; - - return image_formats; -} - diff --git a/src/libXvMC/surface.c b/src/libXvMC/surface.c index 1c07220e84..038befc297 100644 --- a/src/libXvMC/surface.c +++ b/src/libXvMC/surface.c @@ -1,90 +1,96 @@ #include #include #include +#include +#include #include #include +#include -static enum VL_PICTURE PictureToVL(int xvmc_pic) +static enum vlMacroBlockType TypeToVL(int xvmc_mb_type) +{ + if (xvmc_mb_type & XVMC_MB_TYPE_INTRA) + return vlMacroBlockTypeIntra; + if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_FORWARD) + return vlMacroBlockTypeFwdPredicted; + if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_BACKWARD) + return vlMacroBlockTypeBkwdPredicted; + if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) + return vlMacroBlockTypeBiPredicted; + + assert(0); + + return -1; +} + +static enum vlPictureType PictureToVL(int xvmc_pic) { - enum VL_PICTURE vl_pic; - switch (xvmc_pic) { case XVMC_TOP_FIELD: - { - vl_pic = VL_TOP_FIELD; - break; - } + return vlPictureTypeTopField; case XVMC_BOTTOM_FIELD: - { - vl_pic = VL_BOTTOM_FIELD; - break; - } + return vlPictureTypeBottomField; case XVMC_FRAME_PICTURE: - { - vl_pic = VL_FRAME_PICTURE; - break; - } + return vlPictureTypeFrame; default: assert(0); } - - return vl_pic; + + return -1; } -static enum VL_MC_TYPE MotionToVL(int xvmc_motion_type) +static enum vlMotionType MotionToVL(int xvmc_motion_type) { - enum VL_MC_TYPE vl_mc_type; - switch (xvmc_motion_type) { case XVMC_PREDICTION_FRAME: - { - vl_mc_type = VL_FRAME_MC; - break; - } + return vlMotionTypeFrame; case XVMC_PREDICTION_FIELD: - { - vl_mc_type = VL_FIELD_MC; - break; - } + return vlMotionTypeField; case XVMC_PREDICTION_DUAL_PRIME: - { - vl_mc_type = VL_DUAL_PRIME_MC; - break; - } + return vlMotionTypeDualPrime; default: assert(0); } - - return vl_mc_type; + + return -1; } Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) { - struct VL_CONTEXT *vl_ctx; - struct VL_SURFACE *vl_sfc; - + struct vlContext *vl_ctx; + struct vlSurface *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); - + + assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx)))); + + vlCreateSurface + ( + vlContextGetScreen(vl_ctx), + context->width, + context->height, + vlGetPictureFormat(vl_ctx), + &vl_sfc + ); + + vlBindToContext(vl_sfc, vl_ctx); + 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; } @@ -103,19 +109,21 @@ Status XvMCRenderSurface 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; - + struct vlContext *vl_ctx; + struct vlSurface *target_vl_surface; + struct vlSurface *past_vl_surface; + struct vlSurface *future_vl_surface; + struct vlMpeg2MacroBlockBatch batch; + struct vlMpeg2MacroBlock vl_macroblocks[num_macroblocks]; + unsigned int i; + assert(display); - + if (!context) return XvMCBadContext; if (!target_surface) return XvMCBadSurface; - + if ( picture_structure != XVMC_TOP_FIELD && @@ -125,178 +133,94 @@ Status XvMCRenderSurface return BadValue; if (future_surface && !past_surface) return BadMatch; - + vl_ctx = context->privData; - - assert(display == vl_ctx->display); - + + assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx)))); + 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(context->context_id == target_surface->context_id); + assert(!past_surface || context->context_id == past_surface->context_id); + assert(!future_surface || context->context_id == future_surface->context_id); + 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); - - /* TODO: Batch macroblocks by type (I,P,B) */ - - 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, - MotionToVL(macroblocks->macro_blocks[i].motion_type), - &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, - MotionToVL(macroblocks->macro_blocks[i].motion_type), - &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, - MotionToVL(macroblocks->macro_blocks[i].motion_type), - 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"); - + + batch.past_surface = past_vl_surface; + batch.future_surface = future_vl_surface; + batch.picture_type = PictureToVL(picture_structure); + batch.field_order = flags & XVMC_SECOND_FIELD ? vlFieldOrderSecond : vlFieldOrderFirst; + batch.num_macroblocks = num_macroblocks; + batch.macroblocks = vl_macroblocks; + + for (i = 0; i < num_macroblocks; ++i) + { + unsigned int j = first_macroblock + i; + + unsigned int k, l, m; + + batch.macroblocks[i].mbx = macroblocks->macro_blocks[j].x; + batch.macroblocks[i].mby = macroblocks->macro_blocks[j].y; + batch.macroblocks[i].mb_type = TypeToVL(macroblocks->macro_blocks[j].macroblock_type); + if (batch.macroblocks[i].mb_type != vlMacroBlockTypeIntra) + batch.macroblocks[i].mo_type = MotionToVL(macroblocks->macro_blocks[j].motion_type); + batch.macroblocks[i].dct_type = macroblocks->macro_blocks[j].dct_type & XVMC_DCT_TYPE_FIELD ? vlDCTTypeFieldCoded : vlDCTTypeFrameCoded; + + for (k = 0; k < 2; ++k) + for (l = 0; l < 2; ++l) + for (m = 0; m < 2; ++m) + batch.macroblocks[i].PMV[k][l][m] = macroblocks->macro_blocks[j].PMV[k][l][m]; + + batch.macroblocks[i].cbp = macroblocks->macro_blocks[j].coded_block_pattern; + batch.macroblocks[i].blocks = blocks->blocks + (macroblocks->macro_blocks[j].index * 64); + } + + vlRenderMacroBlocksMpeg2(&batch, target_vl_surface); + return Success; } Status XvMCFlushSurface(Display *display, XvMCSurface *surface) { + struct vlSurface *vl_sfc; + assert(display); - + if (!surface) return XvMCBadSurface; - - /* TODO: Check display & surface match */ + + vl_sfc = surface->privData; + + assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc)))); + + /* TODO */ + return Success; } Status XvMCSyncSurface(Display *display, XvMCSurface *surface) { + struct vlSurface *vl_sfc; + assert(display); - + if (!surface) return XvMCBadSurface; - + + vl_sfc = surface->privData; + + assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc)))); + + /* TODO */ + return Success; } @@ -321,92 +245,85 @@ Status XvMCPutSurface unsigned int width, height; unsigned int border_width; unsigned int depth; - struct VL_SURFACE *vl_sfc; - + struct vlSurface *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)); - + + vlPutPicture(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; - + struct vlSurface *vl_sfc; + assert(display); - + if (!surface) return XvMCBadSurface; - + assert(status); - + vl_sfc = surface->privData; - vl_ctx = vl_sfc->context; - - assert(display == vl_ctx->display); - + + assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc)))); + /* TODO */ *status = 0; - + return Success; } Status XvMCDestroySurface(Display *display, XvMCSurface *surface) { - struct VL_CONTEXT *vl_ctx; - struct VL_SURFACE *vl_sfc; - + struct vlSurface *vl_sfc; + assert(display); - + if (!surface) return XvMCBadSurface; - + vl_sfc = surface->privData; - vl_ctx = vl_sfc->context; - - assert(display == vl_ctx->display); - + + assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc)))); + vlDestroySurface(vl_sfc); - + return Success; } Status XvMCHideSurface(Display *display, XvMCSurface *surface) { - struct VL_CONTEXT *vl_ctx; - struct VL_SURFACE *vl_sfc; - + struct vlSurface *vl_sfc; + assert(display); - + if (!surface) return XvMCBadSurface; - + vl_sfc = surface->privData; - vl_ctx = vl_sfc->context; - - assert(display == vl_ctx->display); - + + assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc)))); + /* No op, only for overlaid rendering */ - + return Success; } - -- cgit v1.2.3 From f90e50dff9e5cdbad6e9bb74c0aeaaaa82242b25 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 18 Aug 2008 03:00:25 +0200 Subject: nv30: add some opcodes. --- src/gallium/drivers/nv30/nv30_fragprog.c | 11 +++++++++++ src/gallium/drivers/nv30/nv30_vertprog.c | 6 ++++++ 2 files changed, 17 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index d3693fdf56..02f30ad9ba 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -526,6 +526,12 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc, 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: arith(fpc, sat, POW, dst, mask, src[0], src[1], none); break; @@ -557,6 +563,9 @@ nv30_fragprog_parse_instruction(struct nv30_fpc *fpc, 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_SLT: arith(fpc, sat, SLT, dst, mask, src[0], src[1], none); break; @@ -730,6 +739,8 @@ nv30_fragprog_translate(struct nv30_context *nv30, struct tgsi_parse_context parse; struct nv30_fpc *fpc = NULL; + tgsi_dump(fp->pipe.tokens,0); + fpc = CALLOC(1, sizeof(struct nv30_fpc)); if (!fpc) return; diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 6c075cdb75..72824559e8 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -4,6 +4,7 @@ #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_dump.h" #include "nv30_context.h" #include "nv30_state.h" @@ -457,6 +458,9 @@ nv30_vertprog_parse_instruction(struct nv30_vpc *vpc, case TGSI_OPCODE_SGE: arith(vpc, 0, OP_SGE, dst, mask, src[0], src[1], none); break; + case TGSI_OPCODE_SGT: + arith(vpc, 0, OP_SGT, 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; @@ -570,6 +574,8 @@ nv30_vertprog_translate(struct nv30_context *nv30, struct tgsi_parse_context parse; struct nv30_vpc *vpc = NULL; + tgsi_dump(vp->pipe.tokens,0); + vpc = CALLOC(1, sizeof(struct nv30_vpc)); if (!vpc) return; -- cgit v1.2.3 From 7f100d04ddacf9f6517c9aff1e2de5257eb77fb0 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 18 Aug 2008 00:04:29 -0400 Subject: g3dvl: Use rotating buffers to avoid waiting for map(). --- src/driclient/src/Makefile | 2 +- src/gallium/state_trackers/g3dvl/Makefile | 4 +- src/gallium/state_trackers/g3dvl/vl_data.c | 76 ----------------------- src/gallium/state_trackers/g3dvl/vl_data.h | 27 -------- src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c | 46 +++++++++----- src/gallium/winsys/g3dvl/nouveau/Makefile | 2 +- src/libXvMC/Makefile | 2 +- 7 files changed, 37 insertions(+), 122 deletions(-) delete mode 100644 src/gallium/state_trackers/g3dvl/vl_data.c delete mode 100644 src/gallium/state_trackers/g3dvl/vl_data.h (limited to 'src/gallium') diff --git a/src/driclient/src/Makefile b/src/driclient/src/Makefile index 89ffb84477..5d913ad5fa 100644 --- a/src/driclient/src/Makefile +++ b/src/driclient/src/Makefile @@ -2,7 +2,7 @@ TARGET = libdriclient.a OBJECTS = driclient.o XF86dri.o DRMDIR ?= /usr -CFLAGS += -g -Wall -fPIC -Werror -I../include -I${DRMDIR}/include -I${DRMDIR}/include/drm +CFLAGS += -g -Wall -fPIC -I../include -I${DRMDIR}/include -I${DRMDIR}/include/drm ############################################# diff --git a/src/gallium/state_trackers/g3dvl/Makefile b/src/gallium/state_trackers/g3dvl/Makefile index 9995c554ab..bd77c62bc5 100644 --- a/src/gallium/state_trackers/g3dvl/Makefile +++ b/src/gallium/state_trackers/g3dvl/Makefile @@ -1,9 +1,9 @@ TARGET = libg3dvl.a -OBJECTS = vl_display.o vl_screen.o vl_context.o vl_surface.o vl_data.o vl_shader_build.o vl_util.o vl_basic_csc.o \ +OBJECTS = vl_display.o vl_screen.o vl_context.o vl_surface.o vl_shader_build.o vl_util.o vl_basic_csc.o \ vl_r16snorm_mc.o GALLIUMDIR = ../.. -CFLAGS += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary -I${GALLIUMDIR}/winsys/g3dvl +CFLAGS += -g -Wall -fPIC -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary -I${GALLIUMDIR}/winsys/g3dvl ############################################# diff --git a/src/gallium/state_trackers/g3dvl/vl_data.c b/src/gallium/state_trackers/g3dvl/vl_data.c deleted file mode 100644 index f2476dbf1e..0000000000 --- a/src/gallium/state_trackers/g3dvl/vl_data.c +++ /dev/null @@ -1,76 +0,0 @@ -#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 vlVertex2f macroblock_verts[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 vlVertex2f macroblock_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 vlVertex2f *macroblock_chroma_420_texcoords = macroblock_verts; - -/* - * 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 vlVertex2f *macroblock_chroma_422_texcoords = macroblock_verts; - -/* - * Represents texcoords for the above for rendering 4 chroma blocks. - * Same case as 4 luma blocks. - */ -const struct vlVertex2f *macroblock_chroma_444_texcoords = macroblock_luma_texcoords; - -/* - * 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). - */ -#if 0 -const struct VL_MC_FS_CONSTS vl_mc_fs_consts = -{ - {32767.0f / 255.0f, 32767.0f / 255.0f, 32767.0f / 255.0f, 0.0f}, - {0.5f, 2.0f, 0.0f, 0.0f} -}; -#endif diff --git a/src/gallium/state_trackers/g3dvl/vl_data.h b/src/gallium/state_trackers/g3dvl/vl_data.h deleted file mode 100644 index f0de2e976c..0000000000 --- a/src/gallium/state_trackers/g3dvl/vl_data.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef vl_data_h -#define vl_data_h - -#include "vl_types.h" - -/* TODO: Needs to be rolled into the appropriate stage */ - -extern const struct vlVertex2f macroblock_verts[24]; -extern const struct vlVertex2f macroblock_luma_texcoords[24]; -extern const struct vlVertex2f *macroblock_chroma_420_texcoords; -extern const struct vlVertex2f *macroblock_chroma_422_texcoords; -extern const struct vlVertex2f *macroblock_chroma_444_texcoords; - -extern const struct vlVertex2f surface_verts[4]; -extern const struct vlVertex2f *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_r16snorm_mc.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c index 4fae224431..80b09a6d1d 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c @@ -15,6 +15,8 @@ #include "vl_types.h" #include "vl_defs.h" +#define NUM_BUFS 4 /* Number of rotating buffers to use */ + struct vlVertexShaderConsts { /*struct vlVertex4f scale; @@ -41,12 +43,13 @@ struct vlR16SnormMC unsigned int video_width, video_height; enum vlFormat video_format; + unsigned int cur_buf; struct pipe_context *pipe; struct pipe_viewport_state viewport; struct pipe_framebuffer_state render_target; struct pipe_sampler_state *samplers[5]; - struct pipe_texture *textures[5]; + struct pipe_texture *textures[NUM_BUFS][5]; void *i_vs, *p_vs[2], *b_vs[2]; void *i_fs, *p_fs[2], *b_fs[2]; struct pipe_vertex_buffer vertex_bufs[3]; @@ -230,7 +233,7 @@ static int vlGrabBlocks tex_surface = mc->pipe->screen->get_tex_surface ( mc->pipe->screen, - mc->textures[0], + mc->textures[mc->cur_buf % NUM_BUFS][0], 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE ); @@ -276,7 +279,7 @@ static int vlGrabBlocks tex_surface = mc->pipe->screen->get_tex_surface ( mc->pipe->screen, - mc->textures[tb + 1], + mc->textures[mc->cur_buf % NUM_BUFS][tb + 1], 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE ); @@ -361,12 +364,14 @@ int vlRenderIMacroBlock 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE ); pipe->set_framebuffer_state(pipe, &mc->render_target); - pipe->set_sampler_textures(pipe, 3, mc->textures); + pipe->set_sampler_textures(pipe, 3, mc->textures[mc->cur_buf % NUM_BUFS]); pipe->bind_sampler_states(pipe, 3, (void**)mc->samplers); pipe->bind_vs_state(pipe, mc->i_vs); pipe->bind_fs_state(pipe, mc->i_fs); pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); + + mc->cur_buf++; return 0; } @@ -458,11 +463,13 @@ int vlRenderPMacroBlock ); pipe->set_framebuffer_state(pipe, &mc->render_target); - mc->textures[3] = ref_surface->texture; - pipe->set_sampler_textures(pipe, 4, mc->textures); + mc->textures[mc->cur_buf % NUM_BUFS][3] = ref_surface->texture; + pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUFS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); + + mc->cur_buf++; return 0; } @@ -567,12 +574,14 @@ int vlRenderBMacroBlock ); pipe->set_framebuffer_state(pipe, &mc->render_target); - mc->textures[3] = past_surface->texture; - mc->textures[4] = future_surface->texture; - pipe->set_sampler_textures(pipe, 5, mc->textures); + mc->textures[mc->cur_buf % NUM_BUFS][3] = past_surface->texture; + mc->textures[mc->cur_buf % NUM_BUFS][4] = future_surface->texture; + pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUFS]); pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers); pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); + + mc->cur_buf++; return 0; } @@ -724,8 +733,12 @@ int vlDestroy pipe->winsys->buffer_destroy(pipe->winsys, 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(&mc->textures[i]); + for (i = 0; i < NUM_BUFS; ++i) + { + pipe_texture_release(&mc->textures[i][0]); + pipe_texture_release(&mc->textures[i][1]); + pipe_texture_release(&mc->textures[i][2]); + } pipe->delete_vs_state(pipe, mc->i_vs); pipe->delete_fs_state(pipe, mc->i_fs); @@ -2252,7 +2265,8 @@ static int vlInit template.compressed = 0; pf_get_block(template.format, &template.block); - mc->textures[0] = pipe->screen->texture_create(pipe->screen, &template); + for (i = 0; i < NUM_BUFS; ++i) + mc->textures[i][0] = pipe->screen->texture_create(pipe->screen, &template); if (mc->video_format == vlFormatYCbCr420) template.height[0] = 8; @@ -2263,8 +2277,11 @@ static int vlInit else assert(0); - mc->textures[1] = pipe->screen->texture_create(pipe->screen, &template); - mc->textures[2] = pipe->screen->texture_create(pipe->screen, &template); + for (i = 0; i < NUM_BUFS; ++i) + { + mc->textures[i][1] = pipe->screen->texture_create(pipe->screen, &template); + mc->textures[i][2] = pipe->screen->texture_create(pipe->screen, &template); + } /* textures[3] & textures[4] are assigned from vlSurfaces for P and B macroblocks at render time */ @@ -2306,6 +2323,7 @@ int vlCreateR16SNormMC mc->pipe = pipe; mc->video_width = video_width; mc->video_height = video_height; + mc->cur_buf = 0; vlInit(mc); diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 2861bd7db4..7fa29d2f5f 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -9,7 +9,7 @@ OBJECTS = nouveau_bo.o nouveau_fence.o nouveau_swapbuffers.o nouveau_channel.o nouveau_pushbuf.o nouveau_resource.o nouveau_screen.o nv04_surface.o \ nv50_surface.o #nouveau_winsys_softpipe.o -CFLAGS += -g -Wall -Werror -fPIC \ +CFLAGS += -g -Wall -fPIC \ -I${GALLIUMDIR}/include \ -I${GALLIUMDIR}/winsys/g3dvl \ -I${DRMDIR}/include \ diff --git a/src/libXvMC/Makefile b/src/libXvMC/Makefile index c154e17dc3..b72bb16efb 100644 --- a/src/libXvMC/Makefile +++ b/src/libXvMC/Makefile @@ -8,7 +8,7 @@ ifeq (${DRIVER}, softpipe) OBJECTS += ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o endif -CFLAGS += -g -fPIC -Wall -Werror \ +CFLAGS += -g -fPIC -Wall \ -I${GALLIUMDIR}/state_trackers/g3dvl \ -I${GALLIUMDIR}/winsys/g3dvl \ -I${GALLIUMDIR}/include \ -- cgit v1.2.3 From 4d9d192672508eaa9b2a70f84e933f11108bf09f Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Thu, 28 Aug 2008 23:25:13 -0400 Subject: g3dvl: Buffer the entire frame before rendering. --- src/gallium/state_trackers/g3dvl/Makefile | 2 +- src/gallium/state_trackers/g3dvl/vl_context.c | 4 +- src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c | 45 +- src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.h | 4 +- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 2341 ++++++++++++++++++++ .../state_trackers/g3dvl/vl_r16snorm_mc_buf.h | 18 + src/gallium/state_trackers/g3dvl/vl_render.h | 5 + src/gallium/state_trackers/g3dvl/vl_surface.c | 2 + 8 files changed, 2400 insertions(+), 21 deletions(-) create mode 100644 src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c create mode 100644 src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.h (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/Makefile b/src/gallium/state_trackers/g3dvl/Makefile index bd77c62bc5..4f7a953484 100644 --- a/src/gallium/state_trackers/g3dvl/Makefile +++ b/src/gallium/state_trackers/g3dvl/Makefile @@ -1,6 +1,6 @@ TARGET = libg3dvl.a OBJECTS = vl_display.o vl_screen.o vl_context.o vl_surface.o vl_shader_build.o vl_util.o vl_basic_csc.o \ - vl_r16snorm_mc.o + vl_r16snorm_mc.o vl_r16snorm_mc_buf.o GALLIUMDIR = ../.. CFLAGS += -g -Wall -fPIC -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary -I${GALLIUMDIR}/winsys/g3dvl diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 56d360c05b..fe107e406d 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -6,6 +6,7 @@ #include #include "vl_render.h" #include "vl_r16snorm_mc.h" +#include "vl_r16snorm_mc_buf.h" #include "vl_csc.h" #include "vl_basic_csc.h" @@ -126,7 +127,8 @@ int vlCreateContext vlInitCommon(ctx); - vlCreateR16SNormMC(pipe, picture_width, picture_height, picture_format, &ctx->render); + /*vlCreateR16SNormMC(pipe, picture_width, picture_height, picture_format, &ctx->render);*/ + vlCreateR16SNormBufferedMC(pipe, picture_width, picture_height, picture_format, &ctx->render); vlCreateBasicCSC(pipe, &ctx->csc); *context = ctx; diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c index 80b09a6d1d..3272220ef8 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.c @@ -57,7 +57,7 @@ struct vlR16SnormMC struct pipe_constant_buffer vs_const_buf, fs_const_buf; }; -int vlBegin +static int vlBegin ( struct vlRender *render ) @@ -312,7 +312,7 @@ static int vlGrabBlocks return 0; } -int vlRenderIMacroBlock +static int vlRenderIMacroBlock ( struct vlR16SnormMC *mc, enum vlPictureType picture_type, @@ -370,13 +370,13 @@ int vlRenderIMacroBlock pipe->bind_fs_state(pipe, mc->i_fs); pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); - + mc->cur_buf++; return 0; } -int vlRenderPMacroBlock +static int vlRenderPMacroBlock ( struct vlR16SnormMC *mc, enum vlPictureType picture_type, @@ -468,13 +468,13 @@ int vlRenderPMacroBlock pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); - + mc->cur_buf++; return 0; } -int vlRenderBMacroBlock +static int vlRenderBMacroBlock ( struct vlR16SnormMC *mc, enum vlPictureType picture_type, @@ -580,13 +580,13 @@ int vlRenderBMacroBlock pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers); pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24); - + mc->cur_buf++; return 0; } -int vlRenderMacroBlocksMpeg2R16Snorm +static int vlRenderMacroBlocksMpeg2R16Snorm ( struct vlRender *render, struct vlMpeg2MacroBlockBatch *batch, @@ -702,7 +702,17 @@ int vlRenderMacroBlocksMpeg2R16Snorm return 0; } -int vlEnd +static int vlEnd +( + struct vlRender *render +) +{ + assert(render); + + return 0; +} + +static int vlFlush ( struct vlRender *render ) @@ -712,7 +722,7 @@ int vlEnd return 0; } -int vlDestroy +static int vlDestroy ( struct vlRender *render ) @@ -765,7 +775,7 @@ int vlDestroy * Need to be scaled to cover mbW*mbH macroblock pixels and translated into * position on target surface. */ -const struct vlVertex2f macroblock_verts[24] = +static const struct vlVertex2f macroblock_verts[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}, @@ -785,7 +795,7 @@ const struct vlVertex2f macroblock_verts[24] = * 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 vlVertex2f macroblock_luma_texcoords[24] = +static const struct vlVertex2f macroblock_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}, @@ -804,7 +814,7 @@ const struct vlVertex2f macroblock_luma_texcoords[24] = * 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 vlVertex2f *macroblock_chroma_420_texcoords = macroblock_verts; +static const struct vlVertex2f *macroblock_chroma_420_texcoords = macroblock_verts; /* * Represents texcoords for the above for rendering 2 chroma blocks arranged @@ -812,13 +822,13 @@ const struct vlVertex2f *macroblock_chroma_420_texcoords = macroblock_verts; * 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 vlVertex2f *macroblock_chroma_422_texcoords = macroblock_verts; +static const struct vlVertex2f *macroblock_chroma_422_texcoords = macroblock_verts; /* * Represents texcoords for the above for rendering 4 chroma blocks. * Same case as 4 luma blocks. */ -const struct vlVertex2f *macroblock_chroma_444_texcoords = macroblock_luma_texcoords; +static const struct vlVertex2f *macroblock_chroma_444_texcoords = macroblock_luma_texcoords; /* * Used when rendering P and B macroblocks, multiplier is applied to the A channel, @@ -826,7 +836,7 @@ const struct vlVertex2f *macroblock_chroma_444_texcoords = macroblock_luma_texco * get back the differential. The differential is then added to the samples from the * reference surface(s). */ -const struct vlFragmentShaderConsts fs_consts = +static const struct vlFragmentShaderConsts fs_consts = { {32767.0f / 255.0f, 32767.0f / 255.0f, 32767.0f / 255.0f, 0.0f}, {0.5f, 2.0f, 0.0f, 0.0f} @@ -2093,7 +2103,7 @@ static int vlCreateFragmentShaderFieldBMB return 0; } -int vlCreateDataBufs +static int vlCreateDataBufs ( struct vlR16SnormMC *mc ) @@ -2319,6 +2329,7 @@ int vlCreateR16SNormMC mc->base.vlBegin = &vlBegin; mc->base.vlRenderMacroBlocksMpeg2 = &vlRenderMacroBlocksMpeg2R16Snorm; mc->base.vlEnd = &vlEnd; + mc->base.vlFlush = &vlFlush; mc->base.vlDestroy = &vlDestroy; mc->pipe = pipe; mc->video_width = video_width; diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.h b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.h index a6eecf05b6..9842926bf7 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.h +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc.h @@ -1,5 +1,5 @@ -#ifndef vl_mc_h -#define vl_mc_h +#ifndef vl_r16snorm_mc_h +#define vl_r16snorm_mc_h #include "vl_types.h" diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c new file mode 100644 index 0000000000..fc383cb8f6 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -0,0 +1,2341 @@ +#define VL_INTERNAL +#include "vl_r16snorm_mc_buf.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vl_render.h" +#include "vl_shader_build.h" +#include "vl_surface.h" +#include "vl_util.h" +#include "vl_types.h" +#include "vl_defs.h" + +#define NUM_BUF_SETS 4 /* Number of rotating buffer sets to use */ + +enum vlMacroBlockTypeEx +{ + vlMacroBlockExTypeIntra, + vlMacroBlockExTypeFwdPredictedFrame, + vlMacroBlockExTypeFwdPredictedField, + vlMacroBlockExTypeBkwdPredictedFrame, + vlMacroBlockExTypeBkwdPredictedField, + vlMacroBlockExTypeBiPredictedFrame, + vlMacroBlockExTypeBiPredictedField, + + vlNumMacroBlockExTypes +}; + +struct vlVertexShaderConsts +{ + struct vlVertex4f denorm; +}; + +struct vlFragmentShaderConsts +{ + struct vlVertex4f multiplier; + struct vlVertex4f div; +}; + +struct vlR16SnormBufferedMC +{ + struct vlRender base; + + unsigned int video_width, video_height; + enum vlFormat video_format; + + unsigned int cur_buf; + struct vlSurface *buffered_surface; + struct vlSurface *past_surface, *future_surface; + struct vlVertex2f surface_tex_inv_size; + unsigned int num_macroblocks[vlNumMacroBlockExTypes]; + unsigned int total_num_macroblocks; + + struct pipe_context *pipe; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state render_target; + struct pipe_sampler_state *samplers[5]; + struct pipe_texture *textures[NUM_BUF_SETS][5]; + void *i_vs, *p_vs[2], *b_vs[2]; + void *i_fs, *p_fs[2], *b_fs[2]; + struct pipe_vertex_buffer vertex_bufs[NUM_BUF_SETS][vlNumMacroBlockExTypes][3]; + struct pipe_vertex_element vertex_elems[5]; + struct pipe_constant_buffer vs_const_buf, fs_const_buf; +}; + +static int vlBegin +( + struct vlRender *render +) +{ + assert(render); + + return 0; +} + +static int vlGrabFrameCodedBlock(short *src, short *dst, unsigned int dst_pitch) +{ + unsigned int y; + + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + memcpy + ( + dst + y * dst_pitch, + src + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + + return 0; +} + +static int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst_pitch) +{ + unsigned int y; + + for (y = 0; y < VL_BLOCK_HEIGHT / 2; ++y) + memcpy + ( + dst + y * dst_pitch * 2, + src + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + + dst += VL_BLOCK_HEIGHT * dst_pitch; + + for (; y < VL_BLOCK_HEIGHT; ++y) + memcpy + ( + dst + y * dst_pitch * 2, + src + y * VL_BLOCK_WIDTH, + VL_BLOCK_WIDTH * 2 + ); + + return 0; +} + +static int vlGrabNoBlock(short *dst, unsigned int dst_pitch) +{ + unsigned int y; + + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) + memset + ( + dst + y * dst_pitch, + 0, + VL_BLOCK_WIDTH * 2 + ); + + return 0; +} + +static int vlGrabBlocks +( + struct vlR16SnormBufferedMC *mc, + unsigned int mbx, + unsigned int mby, + enum vlDCTType dct_type, + unsigned int coded_block_pattern, + short *blocks +) +{ + struct pipe_surface *tex_surface; + short *texels; + unsigned int tex_pitch; + unsigned int x, y, tb = 0, sb = 0; + unsigned int mbpx = mbx * VL_MACROBLOCK_WIDTH, mbpy = mby * VL_MACROBLOCK_HEIGHT; + + assert(mc); + assert(blocks); + + tex_surface = mc->pipe->screen->get_tex_surface + ( + mc->pipe->screen, + mc->textures[mc->cur_buf % NUM_BUF_SETS][0], + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE + ); + + texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); + tex_pitch = tex_surface->stride / tex_surface->block.size; + + texels += mbpy * tex_pitch + mbpx; + + for (y = 0; y < 2; ++y) + { + for (x = 0; x < 2; ++x, ++tb) + { + if ((coded_block_pattern >> (5 - tb)) & 1) + { + short *cur_block = blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; + + if (dct_type == vlDCTTypeFrameCoded) + { + vlGrabFrameCodedBlock + ( + cur_block, + texels + y * tex_pitch * VL_BLOCK_HEIGHT + x * VL_BLOCK_WIDTH, + tex_pitch + ); + } + else + { + vlGrabFieldCodedBlock + ( + cur_block, + texels + y * tex_pitch + x * VL_BLOCK_WIDTH, + tex_pitch + ); + } + + ++sb; + } + else + vlGrabNoBlock(texels + y * tex_pitch * VL_BLOCK_HEIGHT + x * VL_BLOCK_WIDTH, tex_pitch); + } + } + + pipe_surface_unmap(tex_surface); + + /* TODO: Implement 422, 444 */ + mbpx >>= 1; + mbpy >>= 1; + + for (tb = 0; tb < 2; ++tb) + { + tex_surface = mc->pipe->screen->get_tex_surface + ( + mc->pipe->screen, + mc->textures[mc->cur_buf % NUM_BUF_SETS][tb + 1], + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE + ); + + texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE); + tex_pitch = tex_surface->stride / tex_surface->block.size; + + texels += mbpy * tex_pitch + mbpx; + + if ((coded_block_pattern >> (1 - tb)) & 1) + { + short *cur_block = blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT; + + vlGrabFrameCodedBlock + ( + cur_block, + texels, + tex_pitch + ); + + ++sb; + } + else + vlGrabNoBlock(texels, tex_pitch); + + pipe_surface_unmap(tex_surface); + } + + return 0; +} + +#if 0 +static int vlGrabMacroBlock +( + struct vlR16SnormBufferedMC *mc, + struct vlMpeg2MacroBlock *macroblock +) +{ + const struct vlVertex2f unit = + { + mc->surface_tex_inv_size.x * VL_MACROBLOCK_WIDTH, + mc->surface_tex_inv_size.y * VL_MACROBLOCK_HEIGHT + }; + const struct vlVertex2f half = + { + mc->surface_tex_inv_size.x * (VL_MACROBLOCK_WIDTH / 2), + mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2) + }; + + struct vlVertex2f *vb; + enum vlMacroBlockTypeEx mb_type_ex; + struct vlVertex2f mo_vec[2]; + unsigned int i; + + assert(mc); + assert(macroblock); + + switch (macroblock->mb_type) + { + case vlMacroBlockTypeIntra: + { + mb_type_ex = vlMacroBlockExTypeIntra; + break; + } + case vlMacroBlockTypeFwdPredicted: + { + mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ? + vlMacroBlockExTypeFwdPredictedFrame : vlMacroBlockExTypeFwdPredictedField; + break; + } + case vlMacroBlockTypeBkwdPredicted: + { + mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ? + vlMacroBlockExTypeBkwdPredictedFrame : vlMacroBlockExTypeBkwdPredictedField; + break; + } + case vlMacroBlockTypeBiPredicted: + { + mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ? + vlMacroBlockExTypeBiPredictedFrame : vlMacroBlockExTypeBiPredictedField; + break; + } + default: + assert(0); + } + + switch (macroblock->mb_type) + { + case vlMacroBlockTypeBiPredicted: + { + vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map + ( + mc->pipe->winsys, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][2].buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ) + mc->num_macroblocks[mb_type_ex] * 2 * 24; + + mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y; + + if (macroblock->mo_type == vlMotionTypeFrame) + { + for (i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + } + } + else + { + mo_vec[1].x = macroblock->PMV[1][1][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[1].y = macroblock->PMV[1][1][1] * 0.5f * mc->surface_tex_inv_size.y; + + for (i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + vb[i + 1].x = mo_vec[1].x; + vb[i + 1].y = mo_vec[1].y; + } + } + + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][2].buffer); + + /* fall-through */ + } + case vlMacroBlockTypeFwdPredicted: + case vlMacroBlockTypeBkwdPredicted: + { + vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map + ( + mc->pipe->winsys, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][1].buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ) + mc->num_macroblocks[mb_type_ex] * 2 * 24; + + if (macroblock->mb_type == vlMacroBlockTypeBkwdPredicted) + { + mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y; + + if (macroblock->mo_type == vlMotionTypeField) + { + mo_vec[1].x = macroblock->PMV[1][1][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[1].y = macroblock->PMV[1][1][1] * 0.5f * mc->surface_tex_inv_size.y; + } + } + else + { + mo_vec[0].x = macroblock->PMV[0][0][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[0].y = macroblock->PMV[0][0][1] * 0.5f * mc->surface_tex_inv_size.y; + + if (macroblock->mo_type == vlMotionTypeField) + { + mo_vec[1].x = macroblock->PMV[1][0][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[1].y = macroblock->PMV[1][0][1] * 0.5f * mc->surface_tex_inv_size.y; + } + } + + if (macroblock->mo_type == vlMotionTypeFrame) + { + for (i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + } + } + else + { + for (i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + vb[i + 1].x = mo_vec[1].x; + vb[i + 1].y = mo_vec[1].y; + } + } + + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][1].buffer); + + /* fall-through */ + } + case vlMacroBlockTypeIntra: + { + vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map + ( + mc->pipe->winsys, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][0].buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ) + mc->num_macroblocks[mb_type_ex] * 24; + + vb[0].x = macroblock->mbx * unit.x; vb[0].y = macroblock->mby * unit.y; + vb[1].x = macroblock->mbx * unit.x; vb[1].y = macroblock->mby * unit.y + half.y; + vb[2].x = macroblock->mbx * unit.x + half.x; vb[2].y = macroblock->mby * unit.y; + + vb[3].x = macroblock->mbx * unit.x + half.x; vb[3].y = macroblock->mby * unit.y; + vb[4].x = macroblock->mbx * unit.x; vb[4].y = macroblock->mby * unit.y + half.y; + vb[5].x = macroblock->mbx * unit.x + half.x; vb[5].y = macroblock->mby * unit.y + half.y; + + vb[6].x = macroblock->mbx * unit.x + half.x; vb[6].y = macroblock->mby * unit.y; + vb[7].x = macroblock->mbx * unit.x + half.x; vb[7].y = macroblock->mby * unit.y + half.y; + vb[8].x = macroblock->mbx * unit.x + unit.x; vb[8].y = macroblock->mby * unit.y; + + vb[9].x = macroblock->mbx * unit.x + unit.x; vb[9].y = macroblock->mby * unit.y; + vb[10].x = macroblock->mbx * unit.x + half.x; vb[10].y = macroblock->mby * unit.y + half.y; + vb[11].x = macroblock->mbx * unit.x + unit.x; vb[11].y = macroblock->mby * unit.y + half.y; + + vb[12].x = macroblock->mbx * unit.x; vb[12].y = macroblock->mby * unit.y + half.y; + vb[13].x = macroblock->mbx * unit.x; vb[13].y = macroblock->mby * unit.y + unit.y; + vb[14].x = macroblock->mbx * unit.x + half.x; vb[14].y = macroblock->mby * unit.y + half.y; + + vb[15].x = macroblock->mbx * unit.x + half.x; vb[15].y = macroblock->mby * unit.y + half.y; + vb[16].x = macroblock->mbx * unit.x; vb[16].y = macroblock->mby * unit.y + unit.y; + vb[17].x = macroblock->mbx * unit.x + half.x; vb[17].y = macroblock->mby * unit.y + unit.y; + + vb[18].x = macroblock->mbx * unit.x + half.x; vb[18].y = macroblock->mby * unit.y + half.y; + vb[19].x = macroblock->mbx * unit.x + half.x; vb[19].y = macroblock->mby * unit.y + unit.y; + vb[20].x = macroblock->mbx * unit.x + unit.x; vb[20].y = macroblock->mby * unit.y + half.y; + + vb[21].x = macroblock->mbx * unit.x + unit.x; vb[21].y = macroblock->mby * unit.y + half.y; + vb[22].x = macroblock->mbx * unit.x + half.x; vb[22].y = macroblock->mby * unit.y + unit.y; + vb[23].x = macroblock->mbx * unit.x + unit.x; vb[23].y = macroblock->mby * unit.y + unit.y; + + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][0].buffer); + + break; + } + default: + assert(0); + } + + vlGrabBlocks + ( + mc, + macroblock->mbx, + macroblock->mby, + macroblock->dct_type, + macroblock->cbp, + macroblock->blocks + ); + + mc->num_macroblocks[mb_type_ex]++; + mc->total_num_macroblocks++; + + return 0; +} +#else +static int vlGrabMacroBlock +( + struct vlR16SnormBufferedMC *mc, + struct vlMpeg2MacroBlock *macroblock +) +{ + const struct vlVertex2f unit = + { + mc->surface_tex_inv_size.x * VL_MACROBLOCK_WIDTH, + mc->surface_tex_inv_size.y * VL_MACROBLOCK_HEIGHT + }; + const struct vlVertex2f half = + { + mc->surface_tex_inv_size.x * (VL_MACROBLOCK_WIDTH / 2), + mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2) + }; + + struct vlVertex2f *vb; + unsigned int mb_buf_id; + struct vlVertex2f mo_vec[2]; + unsigned int i; + + assert(mc); + assert(macroblock); + + switch (macroblock->mb_type) + { + case vlMacroBlockTypeIntra: + { + mb_buf_id = vlMacroBlockExTypeIntra; + break; + } + case vlMacroBlockTypeFwdPredicted: + { + mb_buf_id = macroblock->mo_type == vlMotionTypeFrame ? + vlMacroBlockExTypeFwdPredictedFrame : vlMacroBlockExTypeFwdPredictedField; + break; + } + case vlMacroBlockTypeBkwdPredicted: + { + mb_buf_id = macroblock->mo_type == vlMotionTypeFrame ? + vlMacroBlockExTypeBkwdPredictedFrame : vlMacroBlockExTypeBkwdPredictedField; + break; + } + case vlMacroBlockTypeBiPredicted: + { + mb_buf_id = macroblock->mo_type == vlMotionTypeFrame ? + vlMacroBlockExTypeBiPredictedFrame : vlMacroBlockExTypeBiPredictedField; + break; + } + default: + assert(0); + } + + vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map + ( + mc->pipe->winsys, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][0].buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ) + mc->num_macroblocks[mb_buf_id] * 24; + + vb[0].x = macroblock->mbx * unit.x; vb[0].y = macroblock->mby * unit.y; + vb[1].x = macroblock->mbx * unit.x; vb[1].y = macroblock->mby * unit.y + half.y; + vb[2].x = macroblock->mbx * unit.x + half.x; vb[2].y = macroblock->mby * unit.y; + + vb[3].x = macroblock->mbx * unit.x + half.x; vb[3].y = macroblock->mby * unit.y; + vb[4].x = macroblock->mbx * unit.x; vb[4].y = macroblock->mby * unit.y + half.y; + vb[5].x = macroblock->mbx * unit.x + half.x; vb[5].y = macroblock->mby * unit.y + half.y; + + vb[6].x = macroblock->mbx * unit.x + half.x; vb[6].y = macroblock->mby * unit.y; + vb[7].x = macroblock->mbx * unit.x + half.x; vb[7].y = macroblock->mby * unit.y + half.y; + vb[8].x = macroblock->mbx * unit.x + unit.x; vb[8].y = macroblock->mby * unit.y; + + vb[9].x = macroblock->mbx * unit.x + unit.x; vb[9].y = macroblock->mby * unit.y; + vb[10].x = macroblock->mbx * unit.x + half.x; vb[10].y = macroblock->mby * unit.y + half.y; + vb[11].x = macroblock->mbx * unit.x + unit.x; vb[11].y = macroblock->mby * unit.y + half.y; + + vb[12].x = macroblock->mbx * unit.x; vb[12].y = macroblock->mby * unit.y + half.y; + vb[13].x = macroblock->mbx * unit.x; vb[13].y = macroblock->mby * unit.y + unit.y; + vb[14].x = macroblock->mbx * unit.x + half.x; vb[14].y = macroblock->mby * unit.y + half.y; + + vb[15].x = macroblock->mbx * unit.x + half.x; vb[15].y = macroblock->mby * unit.y + half.y; + vb[16].x = macroblock->mbx * unit.x; vb[16].y = macroblock->mby * unit.y + unit.y; + vb[17].x = macroblock->mbx * unit.x + half.x; vb[17].y = macroblock->mby * unit.y + unit.y; + + vb[18].x = macroblock->mbx * unit.x + half.x; vb[18].y = macroblock->mby * unit.y + half.y; + vb[19].x = macroblock->mbx * unit.x + half.x; vb[19].y = macroblock->mby * unit.y + unit.y; + vb[20].x = macroblock->mbx * unit.x + unit.x; vb[20].y = macroblock->mby * unit.y + half.y; + + vb[21].x = macroblock->mbx * unit.x + unit.x; vb[21].y = macroblock->mby * unit.y + half.y; + vb[22].x = macroblock->mbx * unit.x + half.x; vb[22].y = macroblock->mby * unit.y + unit.y; + vb[23].x = macroblock->mbx * unit.x + unit.x; vb[23].y = macroblock->mby * unit.y + unit.y; + + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][0].buffer); + + if (macroblock->mb_type == vlMacroBlockTypeIntra) + { + vlGrabBlocks + ( + mc, + macroblock->mbx, + macroblock->mby, + macroblock->dct_type, + macroblock->cbp, + macroblock->blocks + ); + + mc->num_macroblocks[mb_buf_id]++; + mc->total_num_macroblocks++; + return 0; + } + + vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map + ( + mc->pipe->winsys, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][1].buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ) + mc->num_macroblocks[mb_buf_id] * 2 * 24; + + if (macroblock->mb_type == vlMacroBlockTypeFwdPredicted || macroblock->mb_type == vlMacroBlockTypeBiPredicted) + { + mo_vec[0].x = macroblock->PMV[0][0][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[0].y = macroblock->PMV[0][0][1] * 0.5f * mc->surface_tex_inv_size.y; + + if (macroblock->mo_type == vlMotionTypeField) + { + mo_vec[1].x = macroblock->PMV[1][0][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[1].y = macroblock->PMV[1][0][1] * 0.5f * mc->surface_tex_inv_size.y; + } + } + else + { + mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y; + + if (macroblock->mo_type == vlMotionTypeField) + { + mo_vec[1].x = macroblock->PMV[1][1][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[1].y = macroblock->PMV[1][1][1] * 0.5f * mc->surface_tex_inv_size.y; + } + } + + if (macroblock->mo_type == vlMotionTypeFrame) + { + for (i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + } + } + else + { + for (i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + vb[i + 1].x = mo_vec[1].x; + vb[i + 1].y = mo_vec[1].y; + } + } + + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][1].buffer); + + if (macroblock->mb_type != vlMacroBlockTypeBiPredicted) + { + vlGrabBlocks + ( + mc, + macroblock->mbx, + macroblock->mby, + macroblock->dct_type, + macroblock->cbp, + macroblock->blocks + ); + + mc->num_macroblocks[mb_buf_id]++; + mc->total_num_macroblocks++; + return 0; + } + + vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map + ( + mc->pipe->winsys, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][2].buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ) + mc->num_macroblocks[mb_buf_id] * 2 * 24; + + mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y; + + if (macroblock->mo_type == vlMotionTypeFrame) + { + for (i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + } + } + else + { + mo_vec[1].x = macroblock->PMV[1][1][0] * 0.5f * mc->surface_tex_inv_size.x; + mo_vec[1].y = macroblock->PMV[1][1][1] * 0.5f * mc->surface_tex_inv_size.y; + + for (i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + vb[i + 1].x = mo_vec[1].x; + vb[i + 1].y = mo_vec[1].y; + } + } + + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][2].buffer); + + vlGrabBlocks + ( + mc, + macroblock->mbx, + macroblock->mby, + macroblock->dct_type, + macroblock->cbp, + macroblock->blocks + ); + + mc->num_macroblocks[mb_buf_id]++; + mc->total_num_macroblocks++; + + return 0; +} +#endif + +static int vlFlush +( + struct vlRender *render +) +{ + struct vlR16SnormBufferedMC *mc; + struct pipe_context *pipe; + struct vlVertexShaderConsts *vs_consts; + + assert(mc); + + mc = (struct vlR16SnormBufferedMC*)render; + pipe = mc->pipe; + + mc->render_target.cbufs[0] = pipe->screen->get_tex_surface + ( + pipe->screen, + mc->buffered_surface->texture, + 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE + ); + + pipe->set_framebuffer_state(pipe, &mc->render_target); + pipe->set_viewport_state(pipe, &mc->viewport); + vs_consts = pipe->winsys->buffer_map + ( + pipe->winsys, + mc->vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE + ); + + vs_consts->denorm.x = mc->buffered_surface->texture->width[0]; + vs_consts->denorm.y = mc->buffered_surface->texture->height[0]; + + pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer); + pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &mc->fs_const_buf); + + if (mc->num_macroblocks[vlMacroBlockExTypeIntra] > 0) + { + pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeIntra]); + pipe->set_vertex_elements(pipe, 1, mc->vertex_elems); + pipe->set_sampler_textures(pipe, 3, mc->textures[mc->cur_buf % NUM_BUF_SETS]); + pipe->bind_sampler_states(pipe, 3, (void**)mc->samplers); + pipe->bind_vs_state(pipe, mc->i_vs); + pipe->bind_fs_state(pipe, mc->i_fs); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeIntra] * 24); + } + + if (mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0) + { + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeFwdPredictedFrame]); + pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; + pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); + pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); + pipe->bind_vs_state(pipe, mc->p_vs[0]); + pipe->bind_fs_state(pipe, mc->p_fs[0]); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24); + } + + if (mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0) + { + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeFwdPredictedField]); + pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; + pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); + pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); + pipe->bind_vs_state(pipe, mc->p_vs[1]); + pipe->bind_fs_state(pipe, mc->p_fs[1]); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24); + } + + if (mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0) + { + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBkwdPredictedFrame]); + pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture; + pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); + pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); + pipe->bind_vs_state(pipe, mc->p_vs[0]); + pipe->bind_fs_state(pipe, mc->p_fs[0]); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24); + } + + if (mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0) + { + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBkwdPredictedField]); + pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture; + pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); + pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); + pipe->bind_vs_state(pipe, mc->p_vs[1]); + pipe->bind_fs_state(pipe, mc->p_fs[1]); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24); + } + + if (mc->num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0) + { + pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBiPredictedFrame]); + pipe->set_vertex_elements(pipe, 5, mc->vertex_elems); + mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; + mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture; + pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]); + pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers); + pipe->bind_vs_state(pipe, mc->b_vs[0]); + pipe->bind_fs_state(pipe, mc->b_fs[0]); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24); + } + + if (mc->num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0) + { + pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBiPredictedField]); + pipe->set_vertex_elements(pipe, 5, mc->vertex_elems); + mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; + mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture; + pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]); + pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers); + pipe->bind_vs_state(pipe, mc->b_vs[1]); + pipe->bind_fs_state(pipe, mc->b_fs[1]); + + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24); + } + + memset(mc->num_macroblocks, 0, sizeof(unsigned int) * 7); + mc->total_num_macroblocks = 0; + + return 0; +} + +static int vlRenderMacroBlocksMpeg2R16SnormBuffered +( + struct vlRender *render, + struct vlMpeg2MacroBlockBatch *batch, + struct vlSurface *surface +) +{ + struct vlR16SnormBufferedMC *mc; + unsigned int i; + + assert(render); + + mc = (struct vlR16SnormBufferedMC*)render; + + if (mc->buffered_surface) + { + if + ( + mc->buffered_surface != surface /*|| + mc->past_surface != batch->past_surface || + mc->future_surface != batch->future_surface*/ + ) + { + vlFlush(&mc->base); + mc->buffered_surface = surface; + mc->past_surface = batch->past_surface; + mc->future_surface = batch->future_surface; + mc->surface_tex_inv_size.x = 1.0f / surface->texture->width[0]; + mc->surface_tex_inv_size.y = 1.0f / surface->texture->height[0]; + } + } + else + { + mc->buffered_surface = surface; + mc->past_surface = batch->past_surface; + mc->future_surface = batch->future_surface; + mc->surface_tex_inv_size.x = 1.0f / surface->texture->width[0]; + mc->surface_tex_inv_size.y = 1.0f / surface->texture->height[0]; + } + + for (i = 0; i < batch->num_macroblocks; ++i) + vlGrabMacroBlock(mc, &batch->macroblocks[i]); + + return 0; +} + +static int vlEnd +( + struct vlRender *render +) +{ + assert(render); + + return 0; +} + +static int vlDestroy +( + struct vlRender *render +) +{ + struct vlR16SnormBufferedMC *mc; + struct pipe_context *pipe; + unsigned int g, h, i; + + assert(render); + + mc = (struct vlR16SnormBufferedMC*)render; + pipe = mc->pipe; + + for (i = 0; i < 5; ++i) + pipe->delete_sampler_state(pipe, mc->samplers[i]); + + for (g = 0; g < NUM_BUF_SETS; ++g) + for (h = 0; h < 7; ++h) + for (i = 0; i < 3; ++i) + pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[g][h][i].buffer); + + /* Textures 3 & 4 are not created directly, no need to release them here */ + for (i = 0; i < NUM_BUF_SETS; ++i) + { + pipe_texture_release(&mc->textures[i][0]); + pipe_texture_release(&mc->textures[i][1]); + pipe_texture_release(&mc->textures[i][2]); + } + + pipe->delete_vs_state(pipe, mc->i_vs); + pipe->delete_fs_state(pipe, mc->i_fs); + + for (i = 0; i < 2; ++i) + { + pipe->delete_vs_state(pipe, mc->p_vs[i]); + pipe->delete_fs_state(pipe, mc->p_fs[i]); + pipe->delete_vs_state(pipe, mc->b_vs[i]); + pipe->delete_fs_state(pipe, mc->b_fs[i]); + } + + pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer); + pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer); + + free(mc); + + return 0; +} + +/* + * Muliplier renormalizes block samples from 16 bits to 12 bits. + * Divider is used when calculating Y % 2 for choosing top or bottom + * field for P or B macroblocks. + * TODO: Use immediates. + */ +static const struct vlFragmentShaderConsts fs_consts = +{ + {32767.0f / 255.0f, 32767.0f / 255.0f, 32767.0f / 255.0f, 0.0f}, + {0.5f, 2.0f, 0.0f, 0.0f} +}; + +static int vlCreateVertexShaderIMB +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int max_tokens = 50; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos, luma & chroma texcoords + */ + for (i = 0; i < 3; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma/chroma texcoords + */ + for (i = 0; i < 2; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * mov o0, i0 ; Move input vertex pos to output + * mov o1, i0 ; Move input luma/chroma texcoords to output + */ + for (i = 0; i < 2; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + mc->i_vs = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderIMB +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* decl i0 ; Luma/chroma texcoords */ + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + */ + for (i = 0; i < 3; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header,max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + } + + /* mul o0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + mc->i_fs = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFramePMB +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos, luma/chroma texcoords + * decl i1 ; Ref surface top field texcoords + * decl i2 ; Ref surface bottom field texcoords (unused, packed in the same stream) + */ + for (i = 0; i < 3; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma/chroma texcoords + * decl o2 ; Ref macroblock texcoords + */ + for (i = 0; i < 3; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * mov o0, i0 ; Move input vertex pos to output + * mov o1, i0 ; Move input luma/chroma texcoords to output + */ + for (i = 0; i < 2; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* add o2, i0, i1 ; Translate vertex pos by motion vec to form ref macroblock texcoords */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + mc->p_vs[0] = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFieldPMB +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos, luma/chroma texcoords + * decl i1 ; Ref surface top field texcoords + * decl i2 ; Ref surface bottom field texcoords + */ + for (i = 0; i < 3; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl c0 ; Texcoord denorm coefficients */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma/chroma texcoords + * decl o2 ; Top field ref macroblock texcoords + * decl o3 ; Bottom field ref macroblock texcoords + * decl o4 ; Denormalized vertex pos + */ + for (i = 0; i < 5; i++) + { + decl = vl_decl_output((i == 0 || i == 5) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * mov o0, i0 ; Move input vertex pos to output + * mov o1, i0 ; Move input luma/chroma texcoords to output + */ + for (i = 0; i < 3; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i == 0 ? 0 : i - 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* + * add o2, i0, i1 ; Translate vertex pos by motion vec to form top field macroblock texcoords + * add o3, i0, i2 ; Translate vertex pos by motion vec to form bottom field macroblock texcoords + */ + for (i = 0; i < 2; ++i) + { + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* mul o4, i0, c0 ; Denorm vertex pos */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 5, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + mc->p_vs[1] = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderFramePMB +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Texcoords for s0, s1, s2 + * decl i1 ; Texcoords for s3 + */ + for (i = 0; i < 2; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for ref surface texture + */ + for (i = 0; i < 4; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + } + + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* tex2d t1, i1, s3 ; Read texel from ref macroblock */ + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 1, TGSI_FILE_SAMPLER, 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 = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + mc->p_fs[0] = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderFieldPMB +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int max_tokens = 200; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Texcoords for s0, s1, s2 + * decl i1 ; Texcoords for s3 + * decl i2 ; Texcoords for s3 + * decl i3 ; Denormalized vertex pos + */ + for (i = 0; i < 4; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm + * decl c1 ; Constants 1/2 & 2 in .x, .y channels for Y-mod-2 top/bottom field selection + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0-t4 */ + decl = vl_decl_temps(0, 4); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for ref surface texture + */ + for (i = 0; i < 4; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + } + + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * tex2d t1, i1, s3 ; Read texel from ref macroblock top field + * tex2d t2, i2, s3 ; Read texel from ref macroblock bottom field + */ + for (i = 0; i < 2; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* XXX: Pos values off by 0.5? */ + /* sub t4, i3.y, c1.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 3, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* floor t3, t3 ; Get rid of fractional part */ + inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mul t3, t3, c1.y ; Multiply by 2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* TODO: Move to conditional tex fetch on t3 instead of lerp */ + /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + 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 = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + mc->p_fs[1] = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFrameBMB +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos, luma/chroma texcoords + * decl i1 ; First ref surface top field texcoords + * decl i2 ; First ref surface bottom field texcoords (unused, packed in the same stream) + * decl i3 ; Second ref surface top field texcoords + * decl i4 ; Second ref surface bottom field texcoords (unused, packed in the same stream) + */ + for (i = 0; i < 5; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma/chroma texcoords + * decl o2 ; First ref macroblock texcoords + * decl o3 ; Second ref macroblock texcoords + */ + for (i = 0; i < 4; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * mov o0, i0 ; Move input vertex pos to output + * mov o1, i0 ; Move input luma/chroma texcoords to output + */ + for (i = 0; i < 2; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* + * add o2, i0, i1 ; Translate vertex pos by motion vec to form first ref macroblock texcoords + * add o3, i0, i3 ; Translate vertex pos by motion vec to form second ref macroblock texcoords + */ + for (i = 0; i < 2; ++i) + { + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i * 2 + 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + mc->b_vs[0] = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateVertexShaderFieldBMB +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos, Luma/chroma texcoords + * decl i1 ; First ref surface top field texcoords + * decl i2 ; First ref surface bottom field texcoords + * decl i3 ; Second ref surface top field texcoords + * decl i4 ; Second ref surface bottom field texcoords + */ + for (i = 0; i < 5; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl c0 ; Denorm coefficients */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 6); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma/chroma texcoords + * decl o2 ; Top field past ref macroblock texcoords + * decl o3 ; Bottom field past ref macroblock texcoords + * decl o4 ; Top field future ref macroblock texcoords + * decl o5 ; Bottom field future ref macroblock texcoords + * decl o6 ; Denormalized vertex pos + */ + for (i = 0; i < 7; i++) + { + decl = vl_decl_output((i == 0 || i == 7) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * mov o0, i0 ; Move input vertex pos to output + * mov o1, i0 ; Move input luma/chroma texcoords to output + * mov o2, i1 ; Move past top field texcoords to output + * mov o3, i2 ; Move past bottom field texcoords to output + * mov o4, i3 ; Move future top field texcoords to output + * mov o5, i4 ; Move future bottom field texcoords to output + */ + for (i = 0; i < 6; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* + * add o2, i0, i1 ; Translate vertex pos by motion vec to form first top field macroblock texcoords + * add o3, i0, i2 ; Translate vertex pos by motion vec to form first bottom field macroblock texcoords + * add o4, i0, i3 ; Translate vertex pos by motion vec to form second top field macroblock texcoords + * add o5, i0, i4 ; Translate vertex pos by motion vec to form second bottom field macroblock texcoords + */ + for (i = 0; i < 4; ++i) + { + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* mul o6, i0, c0 ; Denorm vertex pos */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 6, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + vs.tokens = tokens; + mc->b_vs[1] = pipe->create_vs_state(pipe, &vs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderFrameBMB +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int max_tokens = 100; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Texcoords for s0, s1, s2 + * decl i1 ; Texcoords for s3 + * decl i2 ; Texcoords for s4 + */ + for (i = 0; i < 3; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm + * decl c1 ; Constant 1/2 in .x channel to use as weight to blend past and future texels + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0-t2 */ + decl = vl_decl_temps(0, 2); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for past ref surface texture + * decl s4 ; Sampler for future ref surface texture + */ + for (i = 0; i < 5; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + } + + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * tex2d t1, i1, s3 ; Read texel from past ref macroblock + * tex2d t2, i2, s4 ; Read texel from future ref macroblock + */ + for (i = 0; i < 2; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, i + 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o0, t0, t1 ; Add past/future ref and differential to form final output */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + mc->b_fs[0] = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateFragmentShaderFieldBMB +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int max_tokens = 200; + + struct pipe_context *pipe; + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned int ti; + unsigned int i; + + assert(mc); + + pipe = mc->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 */ + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Texcoords for s0, s1, s2 + * decl i1 ; Texcoords for s3 + * decl i2 ; Texcoords for s3 + * decl i3 ; Texcoords for s4 + * decl i4 ; Texcoords for s4 + * decl i5 ; Denormalized vertex pos + */ + for (i = 0; i < 6; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm + * decl c1 ; Constants 1/2 & 2 in .x, .y channels to use as weight to blend past and future texels + * ; and for Y-mod-2 top/bottom field selection + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0-t5 */ + decl = vl_decl_temps(0, 5); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for past ref surface texture + * decl s4 ; Sampler for future ref surface texture + */ + for (i = 0; i < 5; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + } + + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* XXX: Pos values off by 0.5? */ + /* sub t4, i5.y, c1.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 5, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* floor t3, t3 ; Get rid of fractional part */ + inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* mul t3, t3, c1.y ; Multiply by 2 */ + inst = vl_inst3( TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1); + inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * tex2d t1, i1, s3 ; Read texel from past ref macroblock top field + * tex2d t2, i2, s3 ; Read texel from past ref macroblock bottom field + */ + for (i = 0; i < 2; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* TODO: Move to conditional tex fetch on t3 instead of lerp */ + /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * tex2d t4, i3, s4 ; Read texel from future ref macroblock top field + * tex2d t5, i4, s4 ; Read texel from future ref macroblock bottom field + */ + for (i = 0; i < 2; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 4, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, 4); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* TODO: Move to conditional tex fetch on t3 instead of lerp */ + /* lerp t2, t3, t4, t5 ; Choose between top and bottom fields based on Y % 2 */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 2, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 5); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */ + inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o0, t0, t1 ; Add past/future ref and differential to form final output */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + fs.tokens = tokens; + mc->b_fs[1] = pipe->create_fs_state(pipe, &fs); + free(tokens); + + return 0; +} + +static int vlCreateDataBufs +( + struct vlR16SnormBufferedMC *mc +) +{ + const unsigned int mbw = align(mc->video_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH; + const unsigned int mbh = align(mc->video_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT; + const unsigned int num_mb_per_frame = mbw * mbh; + + struct pipe_context *pipe; + unsigned int g, h, i; + + assert(mc); + + pipe = mc->pipe; + + for (g = 0; g < NUM_BUF_SETS; ++g) + { + for (h = 0; h < 7; ++h) + { + /* Create our vertex buffer and vertex buffer element */ + mc->vertex_bufs[g][h][0].pitch = sizeof(struct vlVertex2f); + mc->vertex_bufs[g][h][0].max_index = 24 * num_mb_per_frame - 1; + mc->vertex_bufs[g][h][0].buffer_offset = 0; + mc->vertex_bufs[g][h][0].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vlVertex2f) * 24 * num_mb_per_frame + ); + } + } + + /* Position & block luma, block chroma texcoord element */ + mc->vertex_elems[0].src_offset = 0; + mc->vertex_elems[0].vertex_buffer_index = 0; + mc->vertex_elems[0].nr_components = 2; + mc->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; + + for (g = 0; g < NUM_BUF_SETS; ++g) + { + for (h = 0; h < 7; ++h) + { + for (i = 1; i < 3; ++i) + { + mc->vertex_bufs[g][h][i].pitch = sizeof(struct vlVertex2f) * 2; + mc->vertex_bufs[g][h][i].max_index = 24 * num_mb_per_frame - 1; + mc->vertex_bufs[g][h][i].buffer_offset = 0; + mc->vertex_bufs[g][h][i].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vlVertex2f) * 2 * 24 * num_mb_per_frame + ); + } + } + } + + /* First ref surface top field texcoord element */ + mc->vertex_elems[1].src_offset = 0; + mc->vertex_elems[1].vertex_buffer_index = 1; + mc->vertex_elems[1].nr_components = 2; + mc->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* First ref surface bottom field texcoord element */ + mc->vertex_elems[2].src_offset = sizeof(struct vlVertex2f); + mc->vertex_elems[2].vertex_buffer_index = 1; + mc->vertex_elems[2].nr_components = 2; + mc->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Second ref surface top field texcoord element */ + mc->vertex_elems[3].src_offset = 0; + mc->vertex_elems[3].vertex_buffer_index = 2; + mc->vertex_elems[3].nr_components = 2; + mc->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Second ref surface bottom field texcoord element */ + mc->vertex_elems[4].src_offset = sizeof(struct vlVertex2f); + mc->vertex_elems[4].vertex_buffer_index = 2; + mc->vertex_elems[4].nr_components = 2; + mc->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Create our constant buffer */ + mc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts); + mc->vs_const_buf.buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + mc->vs_const_buf.size + ); + + mc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts); + mc->fs_const_buf.buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + mc->fs_const_buf.size + ); + + memcpy + ( + pipe->winsys->buffer_map(pipe->winsys, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + &fs_consts, + sizeof(struct vlFragmentShaderConsts) + ); + + pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer); + + return 0; +} + +static int vlInit +( + struct vlR16SnormBufferedMC *mc +) +{ + struct pipe_context *pipe; + struct pipe_sampler_state sampler; + struct pipe_texture template; + unsigned int filters[5]; + unsigned int i; + + assert(mc); + + pipe = mc->pipe; + + /* For MC we render to textures, which are rounded up to nearest POT */ + mc->viewport.scale[0] = vlRoundUpPOT(mc->video_width); + mc->viewport.scale[1] = vlRoundUpPOT(mc->video_height); + mc->viewport.scale[2] = 1; + mc->viewport.scale[3] = 1; + mc->viewport.translate[0] = 0; + mc->viewport.translate[1] = 0; + mc->viewport.translate[2] = 0; + mc->viewport.translate[3] = 0; + + mc->render_target.width = vlRoundUpPOT(mc->video_width); + mc->render_target.height = vlRoundUpPOT(mc->video_height); + mc->render_target.num_cbufs = 1; + /* FB for MC stage is a vlSurface created by the user, set at render time */ + mc->render_target.zsbuf = NULL; + + filters[0] = PIPE_TEX_FILTER_NEAREST; + filters[1] = mc->video_format == vlFormatYCbCr444 ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; + filters[2] = mc->video_format == vlFormatYCbCr444 ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; + filters[3] = PIPE_TEX_FILTER_LINEAR; + filters[4] = PIPE_TEX_FILTER_LINEAR; + + 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 = 0; + /*sampler.max_lod = ;*/ + /*sampler.border_color[i] = ;*/ + /*sampler.max_anisotropy = ;*/ + 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_R16_SNORM; + template.last_level = 0; + template.width[0] = vlRoundUpPOT(mc->video_width); + template.height[0] = vlRoundUpPOT(mc->video_height); + template.depth[0] = 1; + template.compressed = 0; + pf_get_block(template.format, &template.block); + + for (i = 0; i < NUM_BUF_SETS; ++i) + mc->textures[i][0] = pipe->screen->texture_create(pipe->screen, &template); + + if (mc->video_format == vlFormatYCbCr420) + { + template.width[0] = vlRoundUpPOT(mc->video_width / 2); + template.height[0] = vlRoundUpPOT(mc->video_height / 2); + } + else if (mc->video_format == vlFormatYCbCr422) + template.height[0] = vlRoundUpPOT(mc->video_height / 2); + + for (i = 0; i < NUM_BUF_SETS; ++i) + { + mc->textures[i][1] = pipe->screen->texture_create(pipe->screen, &template); + mc->textures[i][2] = pipe->screen->texture_create(pipe->screen, &template); + } + + /* textures[3] & textures[4] are assigned from vlSurfaces for P and B macroblocks at render time */ + + vlCreateVertexShaderIMB(mc); + vlCreateFragmentShaderIMB(mc); + vlCreateVertexShaderFramePMB(mc); + vlCreateVertexShaderFieldPMB(mc); + vlCreateFragmentShaderFramePMB(mc); + vlCreateFragmentShaderFieldPMB(mc); + vlCreateVertexShaderFrameBMB(mc); + vlCreateVertexShaderFieldBMB(mc); + vlCreateFragmentShaderFrameBMB(mc); + vlCreateFragmentShaderFieldBMB(mc); + vlCreateDataBufs(mc); + + return 0; +} + +int vlCreateR16SNormBufferedMC +( + struct pipe_context *pipe, + unsigned int video_width, + unsigned int video_height, + enum vlFormat video_format, + struct vlRender **render +) +{ + struct vlR16SnormBufferedMC *mc; + + assert(pipe); + assert(render); + + mc = calloc(1, sizeof(struct vlR16SnormBufferedMC)); + + mc->base.vlBegin = &vlBegin; + mc->base.vlRenderMacroBlocksMpeg2 = &vlRenderMacroBlocksMpeg2R16SnormBuffered; + mc->base.vlEnd = &vlEnd; + mc->base.vlFlush = &vlFlush; + mc->base.vlDestroy = &vlDestroy; + mc->pipe = pipe; + mc->video_width = video_width; + mc->video_height = video_height; + + mc->cur_buf = 0; + mc->buffered_surface = NULL; + mc->past_surface = NULL; + mc->future_surface = NULL; + memset(mc->num_macroblocks, 0, sizeof(unsigned int) * 7); + mc->total_num_macroblocks = 0; + + vlInit(mc); + + *render = &mc->base; + + return 0; +} diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.h b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.h new file mode 100644 index 0000000000..30f67db3e7 --- /dev/null +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.h @@ -0,0 +1,18 @@ +#ifndef vl_r16snorm_mc_buf_h +#define vl_r16snorm_mc_buf_h + +#include "vl_types.h" + +struct pipe_context; +struct vlRender; + +int vlCreateR16SNormBufferedMC +( + struct pipe_context *pipe, + unsigned int video_width, + unsigned int video_height, + enum vlFormat video_format, + struct vlRender **render +); + +#endif diff --git a/src/gallium/state_trackers/g3dvl/vl_render.h b/src/gallium/state_trackers/g3dvl/vl_render.h index 63016b5cbe..166030b498 100644 --- a/src/gallium/state_trackers/g3dvl/vl_render.h +++ b/src/gallium/state_trackers/g3dvl/vl_render.h @@ -24,6 +24,11 @@ struct vlRender struct vlRender *render ); + int (*vlFlush) + ( + struct vlRender *render + ); + int (*vlDestroy) ( struct vlRender *render diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index ffc8122172..687fd1ec29 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -113,6 +113,8 @@ int vlPutPicture assert(surface); assert(surface->context); + surface->context->render->vlFlush(surface->context->render); + csc = surface->context->csc; pipe = surface->context->pipe; -- cgit v1.2.3 From 248831e741602450fa957d7f63b1ff1e1395c412 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 30 Aug 2008 22:30:03 +0200 Subject: nv30: activate fp texture units when needed, to get texturing --- src/gallium/drivers/nv30/nv30_state_emit.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 40fed621b2..9c96085408 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -71,6 +71,10 @@ nv30_state_emit(struct nv30_context *nv30) state->dirty = 0; + /* FIXME/TODO: Try to find a way to reemit only when changed */ + BEGIN_RING(rankine, NV34TCL_TX_UNITS_ENABLE, 1); + OUT_RING(state->fp_samplers); + so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { if (!(samplers & (1 << i))) -- cgit v1.2.3 From 0c47bd0374e533f614ca3013f429fc32946e5be7 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 31 Aug 2008 11:10:08 +0200 Subject: nv30: set fp samplers with fragprog generation --- src/gallium/drivers/nv30/nv30_fragprog.c | 4 +++- src/gallium/drivers/nv30/nv30_state_emit.c | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 02f30ad9ba..320ba3f4bf 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -852,7 +852,7 @@ nv30_fragprog_validate(struct nv30_context *nv30) fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); nv30_fragprog_upload(nv30, fp); - so = so_new(6, 1); + so = so_new(8, 1); so_method(so, nv30->screen->rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1); so_reloc (so, fp->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, @@ -861,6 +861,8 @@ nv30_fragprog_validate(struct nv30_context *nv30) so_data (so, fp->fp_control); so_method(so, nv30->screen->rankine, NV34TCL_FP_REG_CONTROL, 1); so_data (so, fp->fp_reg_control); + so_method(so, nv30->screen->rankine, NV34TCL_TX_UNITS_ENABLE, 1); + so_data (so, fp->samplers); so_ref(so, &fp->so); update_constants: diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index 9c96085408..40fed621b2 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -71,10 +71,6 @@ nv30_state_emit(struct nv30_context *nv30) state->dirty = 0; - /* FIXME/TODO: Try to find a way to reemit only when changed */ - BEGIN_RING(rankine, NV34TCL_TX_UNITS_ENABLE, 1); - OUT_RING(state->fp_samplers); - so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { if (!(samplers & (1 << i))) -- cgit v1.2.3 From e959c23a31c11f0bcc5775e6e0eb48c5c3d70cf3 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 29 Aug 2008 00:22:09 -0400 Subject: g3dvl: Re-enable buffer rotation, disable high quality 420->444 conversion. Using linear interpolation when upscaling the chroma blocks causes some discoloration around the edges. --- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 238 +-------------------- 1 file changed, 4 insertions(+), 234 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index fc383cb8f6..2d9558587c 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -241,7 +241,6 @@ static int vlGrabBlocks return 0; } -#if 0 static int vlGrabMacroBlock ( struct vlR16SnormBufferedMC *mc, @@ -456,237 +455,6 @@ static int vlGrabMacroBlock return 0; } -#else -static int vlGrabMacroBlock -( - struct vlR16SnormBufferedMC *mc, - struct vlMpeg2MacroBlock *macroblock -) -{ - const struct vlVertex2f unit = - { - mc->surface_tex_inv_size.x * VL_MACROBLOCK_WIDTH, - mc->surface_tex_inv_size.y * VL_MACROBLOCK_HEIGHT - }; - const struct vlVertex2f half = - { - mc->surface_tex_inv_size.x * (VL_MACROBLOCK_WIDTH / 2), - mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2) - }; - - struct vlVertex2f *vb; - unsigned int mb_buf_id; - struct vlVertex2f mo_vec[2]; - unsigned int i; - - assert(mc); - assert(macroblock); - - switch (macroblock->mb_type) - { - case vlMacroBlockTypeIntra: - { - mb_buf_id = vlMacroBlockExTypeIntra; - break; - } - case vlMacroBlockTypeFwdPredicted: - { - mb_buf_id = macroblock->mo_type == vlMotionTypeFrame ? - vlMacroBlockExTypeFwdPredictedFrame : vlMacroBlockExTypeFwdPredictedField; - break; - } - case vlMacroBlockTypeBkwdPredicted: - { - mb_buf_id = macroblock->mo_type == vlMotionTypeFrame ? - vlMacroBlockExTypeBkwdPredictedFrame : vlMacroBlockExTypeBkwdPredictedField; - break; - } - case vlMacroBlockTypeBiPredicted: - { - mb_buf_id = macroblock->mo_type == vlMotionTypeFrame ? - vlMacroBlockExTypeBiPredictedFrame : vlMacroBlockExTypeBiPredictedField; - break; - } - default: - assert(0); - } - - vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map - ( - mc->pipe->winsys, - mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][0].buffer, - PIPE_BUFFER_USAGE_CPU_WRITE - ) + mc->num_macroblocks[mb_buf_id] * 24; - - vb[0].x = macroblock->mbx * unit.x; vb[0].y = macroblock->mby * unit.y; - vb[1].x = macroblock->mbx * unit.x; vb[1].y = macroblock->mby * unit.y + half.y; - vb[2].x = macroblock->mbx * unit.x + half.x; vb[2].y = macroblock->mby * unit.y; - - vb[3].x = macroblock->mbx * unit.x + half.x; vb[3].y = macroblock->mby * unit.y; - vb[4].x = macroblock->mbx * unit.x; vb[4].y = macroblock->mby * unit.y + half.y; - vb[5].x = macroblock->mbx * unit.x + half.x; vb[5].y = macroblock->mby * unit.y + half.y; - - vb[6].x = macroblock->mbx * unit.x + half.x; vb[6].y = macroblock->mby * unit.y; - vb[7].x = macroblock->mbx * unit.x + half.x; vb[7].y = macroblock->mby * unit.y + half.y; - vb[8].x = macroblock->mbx * unit.x + unit.x; vb[8].y = macroblock->mby * unit.y; - - vb[9].x = macroblock->mbx * unit.x + unit.x; vb[9].y = macroblock->mby * unit.y; - vb[10].x = macroblock->mbx * unit.x + half.x; vb[10].y = macroblock->mby * unit.y + half.y; - vb[11].x = macroblock->mbx * unit.x + unit.x; vb[11].y = macroblock->mby * unit.y + half.y; - - vb[12].x = macroblock->mbx * unit.x; vb[12].y = macroblock->mby * unit.y + half.y; - vb[13].x = macroblock->mbx * unit.x; vb[13].y = macroblock->mby * unit.y + unit.y; - vb[14].x = macroblock->mbx * unit.x + half.x; vb[14].y = macroblock->mby * unit.y + half.y; - - vb[15].x = macroblock->mbx * unit.x + half.x; vb[15].y = macroblock->mby * unit.y + half.y; - vb[16].x = macroblock->mbx * unit.x; vb[16].y = macroblock->mby * unit.y + unit.y; - vb[17].x = macroblock->mbx * unit.x + half.x; vb[17].y = macroblock->mby * unit.y + unit.y; - - vb[18].x = macroblock->mbx * unit.x + half.x; vb[18].y = macroblock->mby * unit.y + half.y; - vb[19].x = macroblock->mbx * unit.x + half.x; vb[19].y = macroblock->mby * unit.y + unit.y; - vb[20].x = macroblock->mbx * unit.x + unit.x; vb[20].y = macroblock->mby * unit.y + half.y; - - vb[21].x = macroblock->mbx * unit.x + unit.x; vb[21].y = macroblock->mby * unit.y + half.y; - vb[22].x = macroblock->mbx * unit.x + half.x; vb[22].y = macroblock->mby * unit.y + unit.y; - vb[23].x = macroblock->mbx * unit.x + unit.x; vb[23].y = macroblock->mby * unit.y + unit.y; - - mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][0].buffer); - - if (macroblock->mb_type == vlMacroBlockTypeIntra) - { - vlGrabBlocks - ( - mc, - macroblock->mbx, - macroblock->mby, - macroblock->dct_type, - macroblock->cbp, - macroblock->blocks - ); - - mc->num_macroblocks[mb_buf_id]++; - mc->total_num_macroblocks++; - return 0; - } - - vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map - ( - mc->pipe->winsys, - mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][1].buffer, - PIPE_BUFFER_USAGE_CPU_WRITE - ) + mc->num_macroblocks[mb_buf_id] * 2 * 24; - - if (macroblock->mb_type == vlMacroBlockTypeFwdPredicted || macroblock->mb_type == vlMacroBlockTypeBiPredicted) - { - mo_vec[0].x = macroblock->PMV[0][0][0] * 0.5f * mc->surface_tex_inv_size.x; - mo_vec[0].y = macroblock->PMV[0][0][1] * 0.5f * mc->surface_tex_inv_size.y; - - if (macroblock->mo_type == vlMotionTypeField) - { - mo_vec[1].x = macroblock->PMV[1][0][0] * 0.5f * mc->surface_tex_inv_size.x; - mo_vec[1].y = macroblock->PMV[1][0][1] * 0.5f * mc->surface_tex_inv_size.y; - } - } - else - { - mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x; - mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y; - - if (macroblock->mo_type == vlMotionTypeField) - { - mo_vec[1].x = macroblock->PMV[1][1][0] * 0.5f * mc->surface_tex_inv_size.x; - mo_vec[1].y = macroblock->PMV[1][1][1] * 0.5f * mc->surface_tex_inv_size.y; - } - } - - if (macroblock->mo_type == vlMotionTypeFrame) - { - for (i = 0; i < 24 * 2; i += 2) - { - vb[i].x = mo_vec[0].x; - vb[i].y = mo_vec[0].y; - } - } - else - { - for (i = 0; i < 24 * 2; i += 2) - { - vb[i].x = mo_vec[0].x; - vb[i].y = mo_vec[0].y; - vb[i + 1].x = mo_vec[1].x; - vb[i + 1].y = mo_vec[1].y; - } - } - - mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][1].buffer); - - if (macroblock->mb_type != vlMacroBlockTypeBiPredicted) - { - vlGrabBlocks - ( - mc, - macroblock->mbx, - macroblock->mby, - macroblock->dct_type, - macroblock->cbp, - macroblock->blocks - ); - - mc->num_macroblocks[mb_buf_id]++; - mc->total_num_macroblocks++; - return 0; - } - - vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map - ( - mc->pipe->winsys, - mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][2].buffer, - PIPE_BUFFER_USAGE_CPU_WRITE - ) + mc->num_macroblocks[mb_buf_id] * 2 * 24; - - mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x; - mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y; - - if (macroblock->mo_type == vlMotionTypeFrame) - { - for (i = 0; i < 24 * 2; i += 2) - { - vb[i].x = mo_vec[0].x; - vb[i].y = mo_vec[0].y; - } - } - else - { - mo_vec[1].x = macroblock->PMV[1][1][0] * 0.5f * mc->surface_tex_inv_size.x; - mo_vec[1].y = macroblock->PMV[1][1][1] * 0.5f * mc->surface_tex_inv_size.y; - - for (i = 0; i < 24 * 2; i += 2) - { - vb[i].x = mo_vec[0].x; - vb[i].y = mo_vec[0].y; - vb[i + 1].x = mo_vec[1].x; - vb[i + 1].y = mo_vec[1].y; - } - } - - mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_buf_id][2].buffer); - - vlGrabBlocks - ( - mc, - macroblock->mbx, - macroblock->mby, - macroblock->dct_type, - macroblock->cbp, - macroblock->blocks - ); - - mc->num_macroblocks[mb_buf_id]++; - mc->total_num_macroblocks++; - - return 0; -} -#endif static int vlFlush ( @@ -818,6 +586,7 @@ static int vlFlush memset(mc->num_macroblocks, 0, sizeof(unsigned int) * 7); mc->total_num_macroblocks = 0; + mc->cur_buf++; return 0; } @@ -2231,8 +2000,9 @@ static int vlInit mc->render_target.zsbuf = NULL; filters[0] = PIPE_TEX_FILTER_NEAREST; - filters[1] = mc->video_format == vlFormatYCbCr444 ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; - filters[2] = mc->video_format == vlFormatYCbCr444 ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; + /* FIXME: Linear causes discoloration around block edges */ + filters[1] = /*mc->video_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/; + filters[2] = /*mc->video_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/; filters[3] = PIPE_TEX_FILTER_LINEAR; filters[4] = PIPE_TEX_FILTER_LINEAR; -- cgit v1.2.3 From 29f876cc90605ad7de1141443d3b242395eed5ee Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 30 Aug 2008 13:26:06 -0400 Subject: g3dvl: Inline hint for relatively small, frequently called functions. --- src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 2d9558587c..08aed4542e 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -79,7 +79,7 @@ static int vlBegin return 0; } -static int vlGrabFrameCodedBlock(short *src, short *dst, unsigned int dst_pitch) +static inline int vlGrabFrameCodedBlock(short *src, short *dst, unsigned int dst_pitch) { unsigned int y; @@ -94,7 +94,7 @@ static int vlGrabFrameCodedBlock(short *src, short *dst, unsigned int dst_pitch) return 0; } -static int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst_pitch) +static inline int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst_pitch) { unsigned int y; @@ -119,7 +119,7 @@ static int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst_pitch) return 0; } -static int vlGrabNoBlock(short *dst, unsigned int dst_pitch) +static inline int vlGrabNoBlock(short *dst, unsigned int dst_pitch) { unsigned int y; @@ -130,11 +130,11 @@ static int vlGrabNoBlock(short *dst, unsigned int dst_pitch) 0, VL_BLOCK_WIDTH * 2 ); - + return 0; } -static int vlGrabBlocks +static inline int vlGrabBlocks ( struct vlR16SnormBufferedMC *mc, unsigned int mbx, @@ -164,7 +164,7 @@ static int vlGrabBlocks tex_pitch = tex_surface->stride / tex_surface->block.size; texels += mbpy * tex_pitch + mbpx; - + for (y = 0; y < 2; ++y) { for (x = 0; x < 2; ++x, ++tb) @@ -241,7 +241,7 @@ static int vlGrabBlocks return 0; } -static int vlGrabMacroBlock +static inline int vlGrabMacroBlock ( struct vlR16SnormBufferedMC *mc, struct vlMpeg2MacroBlock *macroblock -- cgit v1.2.3 From 72bcb69459d336fe0c2cf9da57a9b98a933299ca Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 31 Aug 2008 01:01:51 -0400 Subject: g3dvl: Some clean ups. --- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 27 +++++++++++++--------- src/gallium/state_trackers/g3dvl/vl_types.h | 4 +++- 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 08aed4542e..900635228f 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -17,6 +17,15 @@ #include "vl_types.h" #include "vl_defs.h" +/* + * TODO: Dynamically determine number of buf sets to use, based on + * video size and available mem, since we can easily run out of memory + * for high res videos. + * Note: Destroying previous frame's buffers and creating new ones + * doesn't work, since the buffer are not actually destroyed until their + * fence is signalled, and if we render fast enough we will create faster + * than we destroy. + */ #define NUM_BUF_SETS 4 /* Number of rotating buffer sets to use */ enum vlMacroBlockTypeEx @@ -55,7 +64,6 @@ struct vlR16SnormBufferedMC struct vlSurface *past_surface, *future_surface; struct vlVertex2f surface_tex_inv_size; unsigned int num_macroblocks[vlNumMacroBlockExTypes]; - unsigned int total_num_macroblocks; struct pipe_context *pipe; struct pipe_viewport_state viewport; @@ -130,7 +138,7 @@ static inline int vlGrabNoBlock(short *dst, unsigned int dst_pitch) 0, VL_BLOCK_WIDTH * 2 ); - + return 0; } @@ -164,7 +172,7 @@ static inline int vlGrabBlocks tex_pitch = tex_surface->stride / tex_surface->block.size; texels += mbpy * tex_pitch + mbpx; - + for (y = 0; y < 2; ++y) { for (x = 0; x < 2; ++x, ++tb) @@ -451,7 +459,6 @@ static inline int vlGrabMacroBlock ); mc->num_macroblocks[mb_type_ex]++; - mc->total_num_macroblocks++; return 0; } @@ -584,8 +591,7 @@ static int vlFlush pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24); } - memset(mc->num_macroblocks, 0, sizeof(unsigned int) * 7); - mc->total_num_macroblocks = 0; + memset(mc->num_macroblocks, 0, sizeof(unsigned int) * vlNumMacroBlockExTypes); mc->cur_buf++; return 0; @@ -665,7 +671,7 @@ static int vlDestroy pipe->delete_sampler_state(pipe, mc->samplers[i]); for (g = 0; g < NUM_BUF_SETS; ++g) - for (h = 0; h < 7; ++h) + for (h = 0; h < vlNumMacroBlockExTypes; ++h) for (i = 0; i < 3; ++i) pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[g][h][i].buffer); @@ -1871,7 +1877,7 @@ static int vlCreateDataBufs for (g = 0; g < NUM_BUF_SETS; ++g) { - for (h = 0; h < 7; ++h) + for (h = 0; h < vlNumMacroBlockExTypes; ++h) { /* Create our vertex buffer and vertex buffer element */ mc->vertex_bufs[g][h][0].pitch = sizeof(struct vlVertex2f); @@ -1895,7 +1901,7 @@ static int vlCreateDataBufs for (g = 0; g < NUM_BUF_SETS; ++g) { - for (h = 0; h < 7; ++h) + for (h = 0; h < vlNumMacroBlockExTypes; ++h) { for (i = 1; i < 3; ++i) { @@ -2100,8 +2106,7 @@ int vlCreateR16SNormBufferedMC mc->buffered_surface = NULL; mc->past_surface = NULL; mc->future_surface = NULL; - memset(mc->num_macroblocks, 0, sizeof(unsigned int) * 7); - mc->total_num_macroblocks = 0; + memset(mc->num_macroblocks, 0, sizeof(unsigned int) * vlNumMacroBlockExTypes); vlInit(mc); diff --git a/src/gallium/state_trackers/g3dvl/vl_types.h b/src/gallium/state_trackers/g3dvl/vl_types.h index 504ba8ac81..b432bfde93 100644 --- a/src/gallium/state_trackers/g3dvl/vl_types.h +++ b/src/gallium/state_trackers/g3dvl/vl_types.h @@ -79,7 +79,9 @@ enum vlMacroBlockType vlMacroBlockTypeIntra, vlMacroBlockTypeFwdPredicted, vlMacroBlockTypeBkwdPredicted, - vlMacroBlockTypeBiPredicted + vlMacroBlockTypeBiPredicted, + + vlNumMacroBlockTypes }; struct vlMpeg2MacroBlock -- cgit v1.2.3 From ff1a5066513fc75fb0fbbe7fe8a3f1ff27fbf6d3 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 1 Sep 2008 20:13:50 -0400 Subject: g3dvl: Use one VB for all MBs, sort MBs at flush to determine placement. --- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 278 ++++++++++++--------- 1 file changed, 166 insertions(+), 112 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 900635228f..b3deab4656 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -63,7 +63,8 @@ struct vlR16SnormBufferedMC struct vlSurface *buffered_surface; struct vlSurface *past_surface, *future_surface; struct vlVertex2f surface_tex_inv_size; - unsigned int num_macroblocks[vlNumMacroBlockExTypes]; + unsigned int num_macroblocks; + struct vlMpeg2MacroBlock *macroblocks; struct pipe_context *pipe; struct pipe_viewport_state viewport; @@ -72,7 +73,7 @@ struct vlR16SnormBufferedMC struct pipe_texture *textures[NUM_BUF_SETS][5]; void *i_vs, *p_vs[2], *b_vs[2]; void *i_fs, *p_fs[2], *b_fs[2]; - struct pipe_vertex_buffer vertex_bufs[NUM_BUF_SETS][vlNumMacroBlockExTypes][3]; + struct pipe_vertex_buffer vertex_bufs[NUM_BUF_SETS][3]; struct pipe_vertex_element vertex_elems[5]; struct pipe_constant_buffer vs_const_buf, fs_const_buf; }; @@ -249,11 +250,77 @@ static inline int vlGrabBlocks return 0; } +static inline enum vlMacroBlockTypeEx vlGetMacroBlockTypeEx(struct vlMpeg2MacroBlock *mb) +{ + assert(mb); + + switch (mb->mb_type) + { + case vlMacroBlockTypeIntra: + return vlMacroBlockExTypeIntra; + case vlMacroBlockTypeFwdPredicted: + return mb->mo_type == vlMotionTypeFrame ? + vlMacroBlockExTypeFwdPredictedFrame : vlMacroBlockExTypeFwdPredictedField; + case vlMacroBlockTypeBkwdPredicted: + return mb->mo_type == vlMotionTypeFrame ? + vlMacroBlockExTypeBkwdPredictedFrame : vlMacroBlockExTypeBkwdPredictedField; + case vlMacroBlockTypeBiPredicted: + return mb->mo_type == vlMotionTypeFrame ? + vlMacroBlockExTypeBiPredictedFrame : vlMacroBlockExTypeBiPredictedField; + default: + assert(0); + } + + /* Unreachable */ + return -1; +} + static inline int vlGrabMacroBlock ( struct vlR16SnormBufferedMC *mc, struct vlMpeg2MacroBlock *macroblock ) +{ + assert(mc); + assert(macroblock); + + mc->macroblocks[mc->num_macroblocks].mbx = macroblock->mbx; + mc->macroblocks[mc->num_macroblocks].mby = macroblock->mby; + mc->macroblocks[mc->num_macroblocks].mb_type = macroblock->mb_type; + mc->macroblocks[mc->num_macroblocks].mo_type = macroblock->mo_type; + mc->macroblocks[mc->num_macroblocks].dct_type = macroblock->dct_type; + mc->macroblocks[mc->num_macroblocks].PMV[0][0][0] = macroblock->PMV[0][0][0]; + mc->macroblocks[mc->num_macroblocks].PMV[0][0][1] = macroblock->PMV[0][0][1]; + mc->macroblocks[mc->num_macroblocks].PMV[0][1][0] = macroblock->PMV[0][1][0]; + mc->macroblocks[mc->num_macroblocks].PMV[0][1][1] = macroblock->PMV[0][1][1]; + mc->macroblocks[mc->num_macroblocks].PMV[1][0][0] = macroblock->PMV[1][0][0]; + mc->macroblocks[mc->num_macroblocks].PMV[1][0][1] = macroblock->PMV[1][0][1]; + mc->macroblocks[mc->num_macroblocks].PMV[1][1][0] = macroblock->PMV[1][1][0]; + mc->macroblocks[mc->num_macroblocks].PMV[1][1][1] = macroblock->PMV[1][1][1]; + mc->macroblocks[mc->num_macroblocks].cbp = macroblock->cbp; + mc->macroblocks[mc->num_macroblocks].blocks = macroblock->blocks; + + vlGrabBlocks + ( + mc, + macroblock->mbx, + macroblock->mby, + macroblock->dct_type, + macroblock->cbp, + macroblock->blocks + ); + + mc->num_macroblocks++; + + return 0; +} + +static inline int vlGrabMacroBlockVB +( + struct vlR16SnormBufferedMC *mc, + struct vlMpeg2MacroBlock *macroblock, + unsigned int pos +) { const struct vlVertex2f unit = { @@ -267,42 +334,12 @@ static inline int vlGrabMacroBlock }; struct vlVertex2f *vb; - enum vlMacroBlockTypeEx mb_type_ex; struct vlVertex2f mo_vec[2]; unsigned int i; assert(mc); assert(macroblock); - switch (macroblock->mb_type) - { - case vlMacroBlockTypeIntra: - { - mb_type_ex = vlMacroBlockExTypeIntra; - break; - } - case vlMacroBlockTypeFwdPredicted: - { - mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ? - vlMacroBlockExTypeFwdPredictedFrame : vlMacroBlockExTypeFwdPredictedField; - break; - } - case vlMacroBlockTypeBkwdPredicted: - { - mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ? - vlMacroBlockExTypeBkwdPredictedFrame : vlMacroBlockExTypeBkwdPredictedField; - break; - } - case vlMacroBlockTypeBiPredicted: - { - mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ? - vlMacroBlockExTypeBiPredictedFrame : vlMacroBlockExTypeBiPredictedField; - break; - } - default: - assert(0); - } - switch (macroblock->mb_type) { case vlMacroBlockTypeBiPredicted: @@ -310,9 +347,9 @@ static inline int vlGrabMacroBlock vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map ( mc->pipe->winsys, - mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][2].buffer, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer, PIPE_BUFFER_USAGE_CPU_WRITE - ) + mc->num_macroblocks[mb_type_ex] * 2 * 24; + ) + pos * 2 * 24; mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x; mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y; @@ -339,7 +376,7 @@ static inline int vlGrabMacroBlock } } - mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][2].buffer); + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer); /* fall-through */ } @@ -349,9 +386,9 @@ static inline int vlGrabMacroBlock vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map ( mc->pipe->winsys, - mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][1].buffer, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE - ) + mc->num_macroblocks[mb_type_ex] * 2 * 24; + ) + pos * 2 * 24; if (macroblock->mb_type == vlMacroBlockTypeBkwdPredicted) { @@ -395,7 +432,7 @@ static inline int vlGrabMacroBlock } } - mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][1].buffer); + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer); /* fall-through */ } @@ -404,9 +441,9 @@ static inline int vlGrabMacroBlock vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map ( mc->pipe->winsys, - mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][0].buffer, + mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE - ) + mc->num_macroblocks[mb_type_ex] * 24; + ) + pos * 24; vb[0].x = macroblock->mbx * unit.x; vb[0].y = macroblock->mby * unit.y; vb[1].x = macroblock->mbx * unit.x; vb[1].y = macroblock->mby * unit.y + half.y; @@ -440,7 +477,7 @@ static inline int vlGrabMacroBlock vb[22].x = macroblock->mbx * unit.x + half.x; vb[22].y = macroblock->mby * unit.y + unit.y; vb[23].x = macroblock->mbx * unit.x + unit.x; vb[23].y = macroblock->mby * unit.y + unit.y; - mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][0].buffer); + mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer); break; } @@ -448,18 +485,6 @@ static inline int vlGrabMacroBlock assert(0); } - vlGrabBlocks - ( - mc, - macroblock->mbx, - macroblock->mby, - macroblock->dct_type, - macroblock->cbp, - macroblock->blocks - ); - - mc->num_macroblocks[mb_type_ex]++; - return 0; } @@ -471,12 +496,37 @@ static int vlFlush struct vlR16SnormBufferedMC *mc; struct pipe_context *pipe; struct vlVertexShaderConsts *vs_consts; + unsigned int num_macroblocks[vlNumMacroBlockExTypes] = {0}; + unsigned int offset[vlNumMacroBlockExTypes]; + unsigned int vb_start = 0; + unsigned int i; - assert(mc); + assert(render); mc = (struct vlR16SnormBufferedMC*)render; pipe = mc->pipe; + for (i = 0; i < mc->num_macroblocks; ++i) + { + enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]); + + num_macroblocks[mb_type_ex]++; + } + + offset[0] = 0; + + for (i = 1; i < vlNumMacroBlockExTypes; ++i) + offset[i] = offset[i - 1] + num_macroblocks[i - 1]; + + for (i = 0; i < mc->num_macroblocks; ++i) + { + enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]); + + vlGrabMacroBlockVB(mc, &mc->macroblocks[i], offset[mb_type_ex]); + + offset[mb_type_ex]++; + } + mc->render_target.cbufs[0] = pipe->screen->get_tex_surface ( pipe->screen, @@ -497,23 +547,25 @@ static int vlFlush vs_consts->denorm.y = mc->buffered_surface->texture->height[0]; pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer); + pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &mc->vs_const_buf); pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &mc->fs_const_buf); - if (mc->num_macroblocks[vlMacroBlockExTypeIntra] > 0) + if (num_macroblocks[vlMacroBlockExTypeIntra] > 0) { - pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeIntra]); + pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); pipe->set_vertex_elements(pipe, 1, mc->vertex_elems); pipe->set_sampler_textures(pipe, 3, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 3, (void**)mc->samplers); pipe->bind_vs_state(pipe, mc->i_vs); pipe->bind_fs_state(pipe, mc->i_fs); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeIntra] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeIntra] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeIntra] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0) + if (num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0) { - pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeFwdPredictedFrame]); + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); @@ -521,12 +573,13 @@ static int vlFlush pipe->bind_vs_state(pipe, mc->p_vs[0]); pipe->bind_fs_state(pipe, mc->p_fs[0]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0) + if (num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0) { - pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeFwdPredictedField]); + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); @@ -534,12 +587,13 @@ static int vlFlush pipe->bind_vs_state(pipe, mc->p_vs[1]); pipe->bind_fs_state(pipe, mc->p_fs[1]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0) + if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0) { - pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBkwdPredictedFrame]); + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); @@ -547,12 +601,13 @@ static int vlFlush pipe->bind_vs_state(pipe, mc->p_vs[0]); pipe->bind_fs_state(pipe, mc->p_fs[0]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0) + if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0) { - pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBkwdPredictedField]); + pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); @@ -560,12 +615,13 @@ static int vlFlush pipe->bind_vs_state(pipe, mc->p_vs[1]); pipe->bind_fs_state(pipe, mc->p_fs[1]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0) + if (num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0) { - pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBiPredictedFrame]); + pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); pipe->set_vertex_elements(pipe, 5, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture; @@ -574,12 +630,13 @@ static int vlFlush pipe->bind_vs_state(pipe, mc->b_vs[0]); pipe->bind_fs_state(pipe, mc->b_fs[0]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24; } - if (mc->num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0) + if (num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0) { - pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBiPredictedField]); + pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); pipe->set_vertex_elements(pipe, 5, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture; @@ -588,10 +645,11 @@ static int vlFlush pipe->bind_vs_state(pipe, mc->b_vs[1]); pipe->bind_fs_state(pipe, mc->b_fs[1]); - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24); + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24); + vb_start += num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24; } - memset(mc->num_macroblocks, 0, sizeof(unsigned int) * vlNumMacroBlockExTypes); + mc->num_macroblocks = 0; mc->cur_buf++; return 0; @@ -660,7 +718,7 @@ static int vlDestroy { struct vlR16SnormBufferedMC *mc; struct pipe_context *pipe; - unsigned int g, h, i; + unsigned int h, i; assert(render); @@ -670,10 +728,9 @@ static int vlDestroy for (i = 0; i < 5; ++i) pipe->delete_sampler_state(pipe, mc->samplers[i]); - for (g = 0; g < NUM_BUF_SETS; ++g) - for (h = 0; h < vlNumMacroBlockExTypes; ++h) + for (h = 0; h < NUM_BUF_SETS; ++h) for (i = 0; i < 3; ++i) - pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[g][h][i].buffer); + pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[h][i].buffer); /* Textures 3 & 4 are not created directly, no need to release them here */ for (i = 0; i < NUM_BUF_SETS; ++i) @@ -697,6 +754,7 @@ static int vlDestroy pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer); pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer); + free(mc->macroblocks); free(mc); return 0; @@ -1869,28 +1927,25 @@ static int vlCreateDataBufs const unsigned int num_mb_per_frame = mbw * mbh; struct pipe_context *pipe; - unsigned int g, h, i; + unsigned int h, i; assert(mc); pipe = mc->pipe; - for (g = 0; g < NUM_BUF_SETS; ++g) + for (h = 0; h < NUM_BUF_SETS; ++h) { - for (h = 0; h < vlNumMacroBlockExTypes; ++h) - { - /* Create our vertex buffer and vertex buffer element */ - mc->vertex_bufs[g][h][0].pitch = sizeof(struct vlVertex2f); - mc->vertex_bufs[g][h][0].max_index = 24 * num_mb_per_frame - 1; - mc->vertex_bufs[g][h][0].buffer_offset = 0; - mc->vertex_bufs[g][h][0].buffer = pipe->winsys->buffer_create - ( - pipe->winsys, - 1, - PIPE_BUFFER_USAGE_VERTEX, - sizeof(struct vlVertex2f) * 24 * num_mb_per_frame - ); - } + /* Create our vertex buffer and vertex buffer element */ + mc->vertex_bufs[h][0].pitch = sizeof(struct vlVertex2f); + mc->vertex_bufs[h][0].max_index = 24 * num_mb_per_frame - 1; + mc->vertex_bufs[h][0].buffer_offset = 0; + mc->vertex_bufs[h][0].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vlVertex2f) * 24 * num_mb_per_frame + ); } /* Position & block luma, block chroma texcoord element */ @@ -1899,23 +1954,20 @@ static int vlCreateDataBufs mc->vertex_elems[0].nr_components = 2; mc->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; - for (g = 0; g < NUM_BUF_SETS; ++g) + for (h = 0; h < NUM_BUF_SETS; ++h) { - for (h = 0; h < vlNumMacroBlockExTypes; ++h) + for (i = 1; i < 3; ++i) { - for (i = 1; i < 3; ++i) - { - mc->vertex_bufs[g][h][i].pitch = sizeof(struct vlVertex2f) * 2; - mc->vertex_bufs[g][h][i].max_index = 24 * num_mb_per_frame - 1; - mc->vertex_bufs[g][h][i].buffer_offset = 0; - mc->vertex_bufs[g][h][i].buffer = pipe->winsys->buffer_create - ( - pipe->winsys, - 1, - PIPE_BUFFER_USAGE_VERTEX, - sizeof(struct vlVertex2f) * 2 * 24 * num_mb_per_frame - ); - } + mc->vertex_bufs[h][i].pitch = sizeof(struct vlVertex2f) * 2; + mc->vertex_bufs[h][i].max_index = 24 * num_mb_per_frame - 1; + mc->vertex_bufs[h][i].buffer_offset = 0; + mc->vertex_bufs[h][i].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vlVertex2f) * 2 * 24 * num_mb_per_frame + ); } } @@ -1971,6 +2023,8 @@ static int vlCreateDataBufs pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer); + mc->macroblocks = malloc(sizeof(struct vlMpeg2MacroBlock) * num_mb_per_frame); + return 0; } @@ -2106,7 +2160,7 @@ int vlCreateR16SNormBufferedMC mc->buffered_surface = NULL; mc->past_surface = NULL; mc->future_surface = NULL; - memset(mc->num_macroblocks, 0, sizeof(unsigned int) * vlNumMacroBlockExTypes); + mc->num_macroblocks = 0; vlInit(mc); -- cgit v1.2.3 From 2ab5e69f16ed9e9b399ddd526f1370032d3d10a4 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 1 Sep 2008 20:22:41 -0400 Subject: g3dvl: Use consistent variable names. --- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 44 +++++++++++----------- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.h | 6 +-- 2 files changed, 25 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index b3deab4656..13c6fd5568 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -56,8 +56,8 @@ struct vlR16SnormBufferedMC { struct vlRender base; - unsigned int video_width, video_height; - enum vlFormat video_format; + unsigned int picture_width, picture_height; + enum vlFormat picture_format; unsigned int cur_buf; struct vlSurface *buffered_surface; @@ -1922,8 +1922,8 @@ static int vlCreateDataBufs struct vlR16SnormBufferedMC *mc ) { - const unsigned int mbw = align(mc->video_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH; - const unsigned int mbh = align(mc->video_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT; + const unsigned int mbw = align(mc->picture_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH; + const unsigned int mbh = align(mc->picture_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT; const unsigned int num_mb_per_frame = mbw * mbh; struct pipe_context *pipe; @@ -2044,8 +2044,8 @@ static int vlInit pipe = mc->pipe; /* For MC we render to textures, which are rounded up to nearest POT */ - mc->viewport.scale[0] = vlRoundUpPOT(mc->video_width); - mc->viewport.scale[1] = vlRoundUpPOT(mc->video_height); + mc->viewport.scale[0] = vlRoundUpPOT(mc->picture_width); + mc->viewport.scale[1] = vlRoundUpPOT(mc->picture_height); mc->viewport.scale[2] = 1; mc->viewport.scale[3] = 1; mc->viewport.translate[0] = 0; @@ -2053,16 +2053,16 @@ static int vlInit mc->viewport.translate[2] = 0; mc->viewport.translate[3] = 0; - mc->render_target.width = vlRoundUpPOT(mc->video_width); - mc->render_target.height = vlRoundUpPOT(mc->video_height); + mc->render_target.width = vlRoundUpPOT(mc->picture_width); + mc->render_target.height = vlRoundUpPOT(mc->picture_height); mc->render_target.num_cbufs = 1; /* FB for MC stage is a vlSurface created by the user, set at render time */ mc->render_target.zsbuf = NULL; filters[0] = PIPE_TEX_FILTER_NEAREST; /* FIXME: Linear causes discoloration around block edges */ - filters[1] = /*mc->video_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/; - filters[2] = /*mc->video_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/; + filters[1] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/; + filters[2] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/; filters[3] = PIPE_TEX_FILTER_LINEAR; filters[4] = PIPE_TEX_FILTER_LINEAR; @@ -2091,8 +2091,8 @@ static int vlInit template.target = PIPE_TEXTURE_2D; template.format = PIPE_FORMAT_R16_SNORM; template.last_level = 0; - template.width[0] = vlRoundUpPOT(mc->video_width); - template.height[0] = vlRoundUpPOT(mc->video_height); + template.width[0] = vlRoundUpPOT(mc->picture_width); + template.height[0] = vlRoundUpPOT(mc->picture_height); template.depth[0] = 1; template.compressed = 0; pf_get_block(template.format, &template.block); @@ -2100,13 +2100,13 @@ static int vlInit for (i = 0; i < NUM_BUF_SETS; ++i) mc->textures[i][0] = pipe->screen->texture_create(pipe->screen, &template); - if (mc->video_format == vlFormatYCbCr420) + if (mc->picture_format == vlFormatYCbCr420) { - template.width[0] = vlRoundUpPOT(mc->video_width / 2); - template.height[0] = vlRoundUpPOT(mc->video_height / 2); + template.width[0] = vlRoundUpPOT(mc->picture_width / 2); + template.height[0] = vlRoundUpPOT(mc->picture_height / 2); } - else if (mc->video_format == vlFormatYCbCr422) - template.height[0] = vlRoundUpPOT(mc->video_height / 2); + else if (mc->picture_format == vlFormatYCbCr422) + template.height[0] = vlRoundUpPOT(mc->picture_height / 2); for (i = 0; i < NUM_BUF_SETS; ++i) { @@ -2134,9 +2134,9 @@ static int vlInit int vlCreateR16SNormBufferedMC ( struct pipe_context *pipe, - unsigned int video_width, - unsigned int video_height, - enum vlFormat video_format, + unsigned int picture_width, + unsigned int picture_height, + enum vlFormat picture_format, struct vlRender **render ) { @@ -2153,8 +2153,8 @@ int vlCreateR16SNormBufferedMC mc->base.vlFlush = &vlFlush; mc->base.vlDestroy = &vlDestroy; mc->pipe = pipe; - mc->video_width = video_width; - mc->video_height = video_height; + mc->picture_width = picture_width; + mc->picture_height = picture_height; mc->cur_buf = 0; mc->buffered_surface = NULL; diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.h b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.h index 30f67db3e7..27177d64ca 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.h +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.h @@ -9,9 +9,9 @@ struct vlRender; int vlCreateR16SNormBufferedMC ( struct pipe_context *pipe, - unsigned int video_width, - unsigned int video_height, - enum vlFormat video_format, + unsigned int picture_width, + unsigned int picture_height, + enum vlFormat picture_format, struct vlRender **render ); -- cgit v1.2.3 From 72b90b7894afbcb39f72dc4d76cdea0678bf4bc3 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 1 Sep 2008 22:21:08 +0200 Subject: Intialize swizzled_surface object --- src/gallium/winsys/dri/nouveau/nv04_surface.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/nouveau/nv04_surface.c b/src/gallium/winsys/dri/nouveau/nv04_surface.c index 0085b1c345..8fa3d106c8 100644 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ b/src/gallium/winsys/dri/nouveau/nv04_surface.c @@ -276,6 +276,10 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) } BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); + OUT_RING (chan, nvc->channel->vram->handle); if (chipset < 0x10) { class = NV04_SCALED_IMAGE_FROM_MEMORY; -- cgit v1.2.3 From 7891efdac125185d216a8da8b044db0f06f34f0e Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 3 Sep 2008 11:50:38 -0400 Subject: g3dvl: Define block texcoords for each vertex instead of reusing pos. This is needed for zero-block optimization. --- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 243 +++++++++++---------- 1 file changed, 130 insertions(+), 113 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 13c6fd5568..4d778e7fe3 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -74,7 +74,7 @@ struct vlR16SnormBufferedMC void *i_vs, *p_vs[2], *b_vs[2]; void *i_fs, *p_fs[2], *b_fs[2]; struct pipe_vertex_buffer vertex_bufs[NUM_BUF_SETS][3]; - struct pipe_vertex_element vertex_elems[5]; + struct pipe_vertex_element vertex_elems[6]; struct pipe_constant_buffer vs_const_buf, fs_const_buf; }; @@ -443,39 +443,63 @@ static inline int vlGrabMacroBlockVB mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE - ) + pos * 24; + ) + pos * 2 * 24; vb[0].x = macroblock->mbx * unit.x; vb[0].y = macroblock->mby * unit.y; - vb[1].x = macroblock->mbx * unit.x; vb[1].y = macroblock->mby * unit.y + half.y; - vb[2].x = macroblock->mbx * unit.x + half.x; vb[2].y = macroblock->mby * unit.y; - - vb[3].x = macroblock->mbx * unit.x + half.x; vb[3].y = macroblock->mby * unit.y; - vb[4].x = macroblock->mbx * unit.x; vb[4].y = macroblock->mby * unit.y + half.y; - vb[5].x = macroblock->mbx * unit.x + half.x; vb[5].y = macroblock->mby * unit.y + half.y; + vb[1].x = macroblock->mbx * unit.x; vb[1].y = macroblock->mby * unit.y; + vb[2].x = macroblock->mbx * unit.x; vb[2].y = macroblock->mby * unit.y + half.y; + vb[3].x = macroblock->mbx * unit.x; vb[3].y = macroblock->mby * unit.y + half.y; + vb[4].x = macroblock->mbx * unit.x + half.x; vb[4].y = macroblock->mby * unit.y; + vb[5].x = macroblock->mbx * unit.x + half.x; vb[5].y = macroblock->mby * unit.y; vb[6].x = macroblock->mbx * unit.x + half.x; vb[6].y = macroblock->mby * unit.y; - vb[7].x = macroblock->mbx * unit.x + half.x; vb[7].y = macroblock->mby * unit.y + half.y; - vb[8].x = macroblock->mbx * unit.x + unit.x; vb[8].y = macroblock->mby * unit.y; - - vb[9].x = macroblock->mbx * unit.x + unit.x; vb[9].y = macroblock->mby * unit.y; + vb[7].x = macroblock->mbx * unit.x + half.x; vb[7].y = macroblock->mby * unit.y; + vb[8].x = macroblock->mbx * unit.x; vb[8].y = macroblock->mby * unit.y + half.y; + vb[9].x = macroblock->mbx * unit.x; vb[9].y = macroblock->mby * unit.y + half.y; vb[10].x = macroblock->mbx * unit.x + half.x; vb[10].y = macroblock->mby * unit.y + half.y; - vb[11].x = macroblock->mbx * unit.x + unit.x; vb[11].y = macroblock->mby * unit.y + half.y; + vb[11].x = macroblock->mbx * unit.x + half.x; vb[11].y = macroblock->mby * unit.y + half.y; - vb[12].x = macroblock->mbx * unit.x; vb[12].y = macroblock->mby * unit.y + half.y; - vb[13].x = macroblock->mbx * unit.x; vb[13].y = macroblock->mby * unit.y + unit.y; + vb[12].x = macroblock->mbx * unit.x + half.x; vb[12].y = macroblock->mby * unit.y; + vb[13].x = macroblock->mbx * unit.x + half.x; vb[13].y = macroblock->mby * unit.y; vb[14].x = macroblock->mbx * unit.x + half.x; vb[14].y = macroblock->mby * unit.y + half.y; - vb[15].x = macroblock->mbx * unit.x + half.x; vb[15].y = macroblock->mby * unit.y + half.y; - vb[16].x = macroblock->mbx * unit.x; vb[16].y = macroblock->mby * unit.y + unit.y; - vb[17].x = macroblock->mbx * unit.x + half.x; vb[17].y = macroblock->mby * unit.y + unit.y; - - vb[18].x = macroblock->mbx * unit.x + half.x; vb[18].y = macroblock->mby * unit.y + half.y; - vb[19].x = macroblock->mbx * unit.x + half.x; vb[19].y = macroblock->mby * unit.y + unit.y; - vb[20].x = macroblock->mbx * unit.x + unit.x; vb[20].y = macroblock->mby * unit.y + half.y; - - vb[21].x = macroblock->mbx * unit.x + unit.x; vb[21].y = macroblock->mby * unit.y + half.y; - vb[22].x = macroblock->mbx * unit.x + half.x; vb[22].y = macroblock->mby * unit.y + unit.y; - vb[23].x = macroblock->mbx * unit.x + unit.x; vb[23].y = macroblock->mby * unit.y + unit.y; + vb[16].x = macroblock->mbx * unit.x + unit.x; vb[16].y = macroblock->mby * unit.y; + vb[17].x = macroblock->mbx * unit.x + unit.x; vb[17].y = macroblock->mby * unit.y; + + vb[18].x = macroblock->mbx * unit.x + unit.x; vb[18].y = macroblock->mby * unit.y; + vb[19].x = macroblock->mbx * unit.x + unit.x; vb[19].y = macroblock->mby * unit.y; + vb[20].x = macroblock->mbx * unit.x + half.x; vb[20].y = macroblock->mby * unit.y + half.y; + vb[21].x = macroblock->mbx * unit.x + half.x; vb[21].y = macroblock->mby * unit.y + half.y; + vb[22].x = macroblock->mbx * unit.x + unit.x; vb[22].y = macroblock->mby * unit.y + half.y; + vb[23].x = macroblock->mbx * unit.x + unit.x; vb[23].y = macroblock->mby * unit.y + half.y; + + vb[24].x = macroblock->mbx * unit.x; vb[24].y = macroblock->mby * unit.y + half.y; + vb[25].x = macroblock->mbx * unit.x; vb[25].y = macroblock->mby * unit.y + half.y; + vb[26].x = macroblock->mbx * unit.x; vb[26].y = macroblock->mby * unit.y + unit.y; + vb[27].x = macroblock->mbx * unit.x; vb[27].y = macroblock->mby * unit.y + unit.y; + vb[28].x = macroblock->mbx * unit.x + half.x; vb[28].y = macroblock->mby * unit.y + half.y; + vb[29].x = macroblock->mbx * unit.x + half.x; vb[29].y = macroblock->mby * unit.y + half.y; + + vb[30].x = macroblock->mbx * unit.x + half.x; vb[30].y = macroblock->mby * unit.y + half.y; + vb[31].x = macroblock->mbx * unit.x + half.x; vb[31].y = macroblock->mby * unit.y + half.y; + vb[32].x = macroblock->mbx * unit.x; vb[32].y = macroblock->mby * unit.y + unit.y; + vb[33].x = macroblock->mbx * unit.x; vb[33].y = macroblock->mby * unit.y + unit.y; + vb[34].x = macroblock->mbx * unit.x + half.x; vb[34].y = macroblock->mby * unit.y + unit.y; + vb[35].x = macroblock->mbx * unit.x + half.x; vb[35].y = macroblock->mby * unit.y + unit.y; + + vb[36].x = macroblock->mbx * unit.x + half.x; vb[36].y = macroblock->mby * unit.y + half.y; + vb[37].x = macroblock->mbx * unit.x + half.x; vb[37].y = macroblock->mby * unit.y + half.y; + vb[38].x = macroblock->mbx * unit.x + half.x; vb[38].y = macroblock->mby * unit.y + unit.y; + vb[39].x = macroblock->mbx * unit.x + half.x; vb[39].y = macroblock->mby * unit.y + unit.y; + vb[40].x = macroblock->mbx * unit.x + unit.x; vb[40].y = macroblock->mby * unit.y + half.y; + vb[41].x = macroblock->mbx * unit.x + unit.x; vb[41].y = macroblock->mby * unit.y + half.y; + + vb[42].x = macroblock->mbx * unit.x + unit.x; vb[42].y = macroblock->mby * unit.y + half.y; + vb[43].x = macroblock->mbx * unit.x + unit.x; vb[43].y = macroblock->mby * unit.y + half.y; + vb[44].x = macroblock->mbx * unit.x + half.x; vb[44].y = macroblock->mby * unit.y + unit.y; + vb[45].x = macroblock->mbx * unit.x + half.x; vb[45].y = macroblock->mby * unit.y + unit.y; + vb[46].x = macroblock->mbx * unit.x + unit.x; vb[46].y = macroblock->mby * unit.y + unit.y; + vb[47].x = macroblock->mbx * unit.x + unit.x; vb[47].y = macroblock->mby * unit.y + unit.y; mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer); @@ -553,7 +577,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeIntra] > 0) { pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 1, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 2, mc->vertex_elems); pipe->set_sampler_textures(pipe, 3, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 3, (void**)mc->samplers); pipe->bind_vs_state(pipe, mc->i_vs); @@ -566,7 +590,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0) { pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 4, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); @@ -580,7 +604,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0) { pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 4, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); @@ -594,7 +618,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0) { pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 4, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); @@ -608,7 +632,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0) { pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 3, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 4, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); @@ -622,7 +646,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0) { pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 5, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]); @@ -637,7 +661,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0) { pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 5, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]); @@ -806,9 +830,10 @@ static int vlCreateVertexShaderIMB ti = 3; /* - * decl i0 ; Vertex pos, luma & chroma texcoords + * decl i0 ; Vertex pos + * decl i1 ; Luma/chroma texcoords */ - for (i = 0; i < 3; i++) + for (i = 0; i < 2; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -826,11 +851,11 @@ static int vlCreateVertexShaderIMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i0 ; Move input luma/chroma texcoords to output + * mov o1, i1 ; Move input luma/chroma texcoords to output */ for (i = 0; i < 2; ++i) { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -976,11 +1001,12 @@ static int vlCreateVertexShaderFramePMB ti = 3; /* - * decl i0 ; Vertex pos, luma/chroma texcoords - * decl i1 ; Ref surface top field texcoords - * decl i2 ; Ref surface bottom field texcoords (unused, packed in the same stream) + * decl i0 ; Vertex pos + * decl i1 ; Luma/chroma texcoords + * decl i2 ; Ref surface top field texcoords + * decl i3 ; Ref surface bottom field texcoords (unused, packed in the same stream) */ - for (i = 0; i < 3; i++) + for (i = 0; i < 4; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -999,16 +1025,16 @@ static int vlCreateVertexShaderFramePMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i0 ; Move input luma/chroma texcoords to output + * mov o1, i1 ; Move input luma/chroma texcoords to output */ for (i = 0; i < 2; ++i) { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* add o2, i0, i1 ; Translate vertex pos by motion vec to form ref macroblock texcoords */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, 1); + /* add o2, i0, i2 ; Translate vertex pos by motion vec to form ref macroblock texcoords */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, 2); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* end */ @@ -1057,10 +1083,11 @@ static int vlCreateVertexShaderFieldPMB /* * decl i0 ; Vertex pos, luma/chroma texcoords - * decl i1 ; Ref surface top field texcoords - * decl i2 ; Ref surface bottom field texcoords + * decl i1 ; Texcoord denorm coefficients + * decl i2 ; Ref surface top field texcoords + * decl i3 ; Ref surface bottom field texcoords */ - for (i = 0; i < 3; i++) + for (i = 0; i < 4; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1085,21 +1112,21 @@ static int vlCreateVertexShaderFieldPMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i0 ; Move input luma/chroma texcoords to output + * mov o1, i1 ; Move input luma/chroma texcoords to output */ - for (i = 0; i < 3; ++i) + for (i = 0; i < 2; ++i) { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i == 0 ? 0 : i - 1); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } /* - * add o2, i0, i1 ; Translate vertex pos by motion vec to form top field macroblock texcoords - * add o3, i0, i2 ; Translate vertex pos by motion vec to form bottom field macroblock texcoords + * add o2, i0, i2 ; Translate vertex pos by motion vec to form top field macroblock texcoords + * add o3, i0, i3 ; Translate vertex pos by motion vec to form bottom field macroblock texcoords */ for (i = 0; i < 2; ++i) { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 1); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 2); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -1430,12 +1457,13 @@ static int vlCreateVertexShaderFrameBMB /* * decl i0 ; Vertex pos, luma/chroma texcoords - * decl i1 ; First ref surface top field texcoords - * decl i2 ; First ref surface bottom field texcoords (unused, packed in the same stream) - * decl i3 ; Second ref surface top field texcoords - * decl i4 ; Second ref surface bottom field texcoords (unused, packed in the same stream) + * decl i1 ; Luma/chroma texcoords + * decl i2 ; First ref surface top field texcoords + * decl i3 ; First ref surface bottom field texcoords (unused, packed in the same stream) + * decl i4 ; Second ref surface top field texcoords + * decl i5 ; Second ref surface bottom field texcoords (unused, packed in the same stream) */ - for (i = 0; i < 5; i++) + for (i = 0; i < 6; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1455,21 +1483,21 @@ static int vlCreateVertexShaderFrameBMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i0 ; Move input luma/chroma texcoords to output + * mov o1, i1 ; Move input luma/chroma texcoords to output */ for (i = 0; i < 2; ++i) { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } /* - * add o2, i0, i1 ; Translate vertex pos by motion vec to form first ref macroblock texcoords - * add o3, i0, i3 ; Translate vertex pos by motion vec to form second ref macroblock texcoords + * add o2, i0, i2 ; Translate vertex pos by motion vec to form first ref macroblock texcoords + * add o3, i0, i4 ; Translate vertex pos by motion vec to form second ref macroblock texcoords */ for (i = 0; i < 2; ++i) { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i * 2 + 1); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, (i + 1) * 2); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -1519,12 +1547,13 @@ static int vlCreateVertexShaderFieldBMB /* * decl i0 ; Vertex pos, Luma/chroma texcoords - * decl i1 ; First ref surface top field texcoords - * decl i2 ; First ref surface bottom field texcoords - * decl i3 ; Second ref surface top field texcoords - * decl i4 ; Second ref surface bottom field texcoords + * decl i1 ; Luma/chroma texcoords + * decl i2 ; First ref surface top field texcoords + * decl i3 ; First ref surface bottom field texcoords + * decl i4 ; Second ref surface top field texcoords + * decl i5 ; Second ref surface bottom field texcoords */ - for (i = 0; i < 5; i++) + for (i = 0; i < 6; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1555,27 +1584,23 @@ static int vlCreateVertexShaderFieldBMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i0 ; Move input luma/chroma texcoords to output - * mov o2, i1 ; Move past top field texcoords to output - * mov o3, i2 ; Move past bottom field texcoords to output - * mov o4, i3 ; Move future top field texcoords to output - * mov o5, i4 ; Move future bottom field texcoords to output + * mov o1, i1 ; Move input luma/chroma texcoords to output */ - for (i = 0; i < 6; ++i) + for (i = 0; i < 2; ++i) { - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0); + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } /* - * add o2, i0, i1 ; Translate vertex pos by motion vec to form first top field macroblock texcoords - * add o3, i0, i2 ; Translate vertex pos by motion vec to form first bottom field macroblock texcoords - * add o4, i0, i3 ; Translate vertex pos by motion vec to form second top field macroblock texcoords - * add o5, i0, i4 ; Translate vertex pos by motion vec to form second bottom field macroblock texcoords + * add o2, i0, i2 ; Translate vertex pos by motion vec to form first top field macroblock texcoords + * add o3, i0, i3 ; Translate vertex pos by motion vec to form first bottom field macroblock texcoords + * add o4, i0, i4 ; Translate vertex pos by motion vec to form second top field macroblock texcoords + * add o5, i0, i5 ; Translate vertex pos by motion vec to form second bottom field macroblock texcoords */ for (i = 0; i < 4; ++i) { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 1); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 2); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -1933,30 +1958,10 @@ static int vlCreateDataBufs pipe = mc->pipe; + /* Create our vertex buffers */ for (h = 0; h < NUM_BUF_SETS; ++h) { - /* Create our vertex buffer and vertex buffer element */ - mc->vertex_bufs[h][0].pitch = sizeof(struct vlVertex2f); - mc->vertex_bufs[h][0].max_index = 24 * num_mb_per_frame - 1; - mc->vertex_bufs[h][0].buffer_offset = 0; - mc->vertex_bufs[h][0].buffer = pipe->winsys->buffer_create - ( - pipe->winsys, - 1, - PIPE_BUFFER_USAGE_VERTEX, - sizeof(struct vlVertex2f) * 24 * num_mb_per_frame - ); - } - - /* Position & block luma, block chroma texcoord element */ - mc->vertex_elems[0].src_offset = 0; - mc->vertex_elems[0].vertex_buffer_index = 0; - mc->vertex_elems[0].nr_components = 2; - mc->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; - - for (h = 0; h < NUM_BUF_SETS; ++h) - { - for (i = 1; i < 3; ++i) + for (i = 0; i < 3; ++i) { mc->vertex_bufs[h][i].pitch = sizeof(struct vlVertex2f) * 2; mc->vertex_bufs[h][i].max_index = 24 * num_mb_per_frame - 1; @@ -1971,30 +1976,42 @@ static int vlCreateDataBufs } } - /* First ref surface top field texcoord element */ - mc->vertex_elems[1].src_offset = 0; - mc->vertex_elems[1].vertex_buffer_index = 1; + /* Position element */ + mc->vertex_elems[0].src_offset = 0; + mc->vertex_elems[0].vertex_buffer_index = 0; + mc->vertex_elems[0].nr_components = 2; + mc->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Block luma, block chroma texcoord element */ + mc->vertex_elems[1].src_offset = sizeof(struct vlVertex2f); + mc->vertex_elems[1].vertex_buffer_index = 0; mc->vertex_elems[1].nr_components = 2; mc->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* First ref surface bottom field texcoord element */ - mc->vertex_elems[2].src_offset = sizeof(struct vlVertex2f); + /* First ref surface top field texcoord element */ + mc->vertex_elems[2].src_offset = 0; mc->vertex_elems[2].vertex_buffer_index = 1; mc->vertex_elems[2].nr_components = 2; mc->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* Second ref surface top field texcoord element */ - mc->vertex_elems[3].src_offset = 0; - mc->vertex_elems[3].vertex_buffer_index = 2; + /* First ref surface bottom field texcoord element */ + mc->vertex_elems[3].src_offset = sizeof(struct vlVertex2f); + mc->vertex_elems[3].vertex_buffer_index = 1; mc->vertex_elems[3].nr_components = 2; mc->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* Second ref surface bottom field texcoord element */ - mc->vertex_elems[4].src_offset = sizeof(struct vlVertex2f); + /* Second ref surface top field texcoord element */ + mc->vertex_elems[4].src_offset = 0; mc->vertex_elems[4].vertex_buffer_index = 2; mc->vertex_elems[4].nr_components = 2; mc->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT; + /* Second ref surface bottom field texcoord element */ + mc->vertex_elems[5].src_offset = sizeof(struct vlVertex2f); + mc->vertex_elems[5].vertex_buffer_index = 2; + mc->vertex_elems[5].nr_components = 2; + mc->vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT; + /* Create our constant buffer */ mc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts); mc->vs_const_buf.buffer = pipe->winsys->buffer_create -- cgit v1.2.3 From 0bfbe834d35946fe75eb991d03ed777e115f418d Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Thu, 4 Sep 2008 00:16:51 -0400 Subject: g3dvl: Define texcoords seperately for luma, Cb, Cr textures. Need to be able to address each texture separately to do zero-block. --- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 566 +++++++++++++-------- 1 file changed, 343 insertions(+), 223 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 4d778e7fe3..b5aa79cdb4 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -74,7 +74,7 @@ struct vlR16SnormBufferedMC void *i_vs, *p_vs[2], *b_vs[2]; void *i_fs, *p_fs[2], *b_fs[2]; struct pipe_vertex_buffer vertex_bufs[NUM_BUF_SETS][3]; - struct pipe_vertex_element vertex_elems[6]; + struct pipe_vertex_element vertex_elems[8]; struct pipe_constant_buffer vs_const_buf, fs_const_buf; }; @@ -315,6 +315,71 @@ static inline int vlGrabMacroBlock return 0; } +#define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zx, zy) \ + (vb)[0].pos.x = (mbx) * (unitx) + (ofsx); (vb)[0].pos.y = (mby) * (unity) + (ofsy); \ + (vb)[1].pos.x = (mbx) * (unitx) + (ofsx); (vb)[1].pos.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[2].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].pos.y = (mby) * (unity) + (ofsy); \ + (vb)[3].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].pos.y = (mby) * (unity) + (ofsy); \ + (vb)[4].pos.x = (mbx) * (unitx) + (ofsx); (vb)[4].pos.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[5].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].pos.y = (mby) * (unity) + (ofsy) + (hy); \ + \ + /*if ((cbp) & (lm)) \ + {*/ \ + (vb)[0].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].luma_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[1].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[2].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].luma_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[3].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].luma_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[4].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[5].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + /*} \ + else \ + { \ + (vb)[0].luma_tc.x = (zx); (vb)[0].luma_tc.y = (zy); \ + (vb)[1].luma_tc.x = (zx); (vb)[1].luma_tc.y = (zy) + (hy); \ + (vb)[2].luma_tc.x = (zx) + (hx); (vb)[2].luma_tc.y = (zy); \ + (vb)[3].luma_tc.x = (zx) + (hx); (vb)[3].luma_tc.y = (zy); \ + (vb)[4].luma_tc.x = (zx); (vb)[4].luma_tc.y = (zy) + (hy); \ + (vb)[5].luma_tc.x = ((zx) + (hx); (vb)[5].luma_tc.y = (zy) + (hy); \ + }*/ \ + \ + /*if ((cbp) & (cbm)) \ + {*/ \ + (vb)[0].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cb_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[1].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[2].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cb_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[3].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cb_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[4].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[5].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + /*} \ + else \ + { \ + (vb)[0].cb_tc.x = (zx); (vb)[0].cb_tc.y = (zy); \ + (vb)[1].cb_tc.x = (zx); (vb)[1].cb_tc.y = (zy) + (hy); \ + (vb)[2].cb_tc.x = (zx) + (hx); (vb)[2].cb_tc.y = (zy); \ + (vb)[3].cb_tc.x = (zx) + (hx); (vb)[3].cb_tc.y = (zy); \ + (vb)[4].cb_tc.x = (zx); (vb)[4].cb_tc.y = (zy) + (hy); \ + (vb)[5].cb_tc.x = ((zx) + (hx); (vb)[5].cb_tc.y = (zy) + (hy); \ + }*/ \ + \ + /*if ((cbp) & (crm)) \ + {*/ \ + (vb)[0].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cr_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[1].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[2].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cr_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[3].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cr_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[4].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[5].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + /*} \ + else \ + { \ + (vb)[0].cr_tc.x = (zx); (vb)[0].cb_tc.y = (zy); \ + (vb)[1].cr_tc.x = (zx); (vb)[1].cb_tc.y = (zy) + (hy); \ + (vb)[2].cr_tc.x = (zx) + (hx); (vb)[2].cb_tc.y = (zy); \ + (vb)[3].cr_tc.x = (zx) + (hx); (vb)[3].cb_tc.y = (zy); \ + (vb)[4].cr_tc.x = (zx); (vb)[4].cb_tc.y = (zy) + (hy); \ + (vb)[5].cr_tc.x = ((zx) + (hx); (vb)[5].cb_tc.y = (zy) + (hy); \ + }*/ + static inline int vlGrabMacroBlockVB ( struct vlR16SnormBufferedMC *mc, @@ -322,18 +387,6 @@ static inline int vlGrabMacroBlockVB unsigned int pos ) { - const struct vlVertex2f unit = - { - mc->surface_tex_inv_size.x * VL_MACROBLOCK_WIDTH, - mc->surface_tex_inv_size.y * VL_MACROBLOCK_HEIGHT - }; - const struct vlVertex2f half = - { - mc->surface_tex_inv_size.x * (VL_MACROBLOCK_WIDTH / 2), - mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2) - }; - - struct vlVertex2f *vb; struct vlVertex2f mo_vec[2]; unsigned int i; @@ -344,6 +397,8 @@ static inline int vlGrabMacroBlockVB { case vlMacroBlockTypeBiPredicted: { + struct vlVertex2f *vb; + vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map ( mc->pipe->winsys, @@ -383,6 +438,8 @@ static inline int vlGrabMacroBlockVB case vlMacroBlockTypeFwdPredicted: case vlMacroBlockTypeBkwdPredicted: { + struct vlVertex2f *vb; + vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map ( mc->pipe->winsys, @@ -438,68 +495,63 @@ static inline int vlGrabMacroBlockVB } case vlMacroBlockTypeIntra: { - vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map + const struct vlVertex2f unit = + { + mc->surface_tex_inv_size.x * VL_MACROBLOCK_WIDTH, + mc->surface_tex_inv_size.y * VL_MACROBLOCK_HEIGHT + }; + const struct vlVertex2f half = + { + mc->surface_tex_inv_size.x * (VL_MACROBLOCK_WIDTH / 2), + mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2) + }; + + struct vlMacroBlockVertexStream0 + { + struct vlVertex2f pos; + struct vlVertex2f luma_tc; + struct vlVertex2f cb_tc; + struct vlVertex2f cr_tc; + } *vb; + + vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map ( mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE - ) + pos * 2 * 24; + ) + pos * 24; - vb[0].x = macroblock->mbx * unit.x; vb[0].y = macroblock->mby * unit.y; - vb[1].x = macroblock->mbx * unit.x; vb[1].y = macroblock->mby * unit.y; - vb[2].x = macroblock->mbx * unit.x; vb[2].y = macroblock->mby * unit.y + half.y; - vb[3].x = macroblock->mbx * unit.x; vb[3].y = macroblock->mby * unit.y + half.y; - vb[4].x = macroblock->mbx * unit.x + half.x; vb[4].y = macroblock->mby * unit.y; - vb[5].x = macroblock->mbx * unit.x + half.x; vb[5].y = macroblock->mby * unit.y; - - vb[6].x = macroblock->mbx * unit.x + half.x; vb[6].y = macroblock->mby * unit.y; - vb[7].x = macroblock->mbx * unit.x + half.x; vb[7].y = macroblock->mby * unit.y; - vb[8].x = macroblock->mbx * unit.x; vb[8].y = macroblock->mby * unit.y + half.y; - vb[9].x = macroblock->mbx * unit.x; vb[9].y = macroblock->mby * unit.y + half.y; - vb[10].x = macroblock->mbx * unit.x + half.x; vb[10].y = macroblock->mby * unit.y + half.y; - vb[11].x = macroblock->mbx * unit.x + half.x; vb[11].y = macroblock->mby * unit.y + half.y; - - vb[12].x = macroblock->mbx * unit.x + half.x; vb[12].y = macroblock->mby * unit.y; - vb[13].x = macroblock->mbx * unit.x + half.x; vb[13].y = macroblock->mby * unit.y; - vb[14].x = macroblock->mbx * unit.x + half.x; vb[14].y = macroblock->mby * unit.y + half.y; - vb[15].x = macroblock->mbx * unit.x + half.x; vb[15].y = macroblock->mby * unit.y + half.y; - vb[16].x = macroblock->mbx * unit.x + unit.x; vb[16].y = macroblock->mby * unit.y; - vb[17].x = macroblock->mbx * unit.x + unit.x; vb[17].y = macroblock->mby * unit.y; - - vb[18].x = macroblock->mbx * unit.x + unit.x; vb[18].y = macroblock->mby * unit.y; - vb[19].x = macroblock->mbx * unit.x + unit.x; vb[19].y = macroblock->mby * unit.y; - vb[20].x = macroblock->mbx * unit.x + half.x; vb[20].y = macroblock->mby * unit.y + half.y; - vb[21].x = macroblock->mbx * unit.x + half.x; vb[21].y = macroblock->mby * unit.y + half.y; - vb[22].x = macroblock->mbx * unit.x + unit.x; vb[22].y = macroblock->mby * unit.y + half.y; - vb[23].x = macroblock->mbx * unit.x + unit.x; vb[23].y = macroblock->mby * unit.y + half.y; - - vb[24].x = macroblock->mbx * unit.x; vb[24].y = macroblock->mby * unit.y + half.y; - vb[25].x = macroblock->mbx * unit.x; vb[25].y = macroblock->mby * unit.y + half.y; - vb[26].x = macroblock->mbx * unit.x; vb[26].y = macroblock->mby * unit.y + unit.y; - vb[27].x = macroblock->mbx * unit.x; vb[27].y = macroblock->mby * unit.y + unit.y; - vb[28].x = macroblock->mbx * unit.x + half.x; vb[28].y = macroblock->mby * unit.y + half.y; - vb[29].x = macroblock->mbx * unit.x + half.x; vb[29].y = macroblock->mby * unit.y + half.y; - - vb[30].x = macroblock->mbx * unit.x + half.x; vb[30].y = macroblock->mby * unit.y + half.y; - vb[31].x = macroblock->mbx * unit.x + half.x; vb[31].y = macroblock->mby * unit.y + half.y; - vb[32].x = macroblock->mbx * unit.x; vb[32].y = macroblock->mby * unit.y + unit.y; - vb[33].x = macroblock->mbx * unit.x; vb[33].y = macroblock->mby * unit.y + unit.y; - vb[34].x = macroblock->mbx * unit.x + half.x; vb[34].y = macroblock->mby * unit.y + unit.y; - vb[35].x = macroblock->mbx * unit.x + half.x; vb[35].y = macroblock->mby * unit.y + unit.y; - - vb[36].x = macroblock->mbx * unit.x + half.x; vb[36].y = macroblock->mby * unit.y + half.y; - vb[37].x = macroblock->mbx * unit.x + half.x; vb[37].y = macroblock->mby * unit.y + half.y; - vb[38].x = macroblock->mbx * unit.x + half.x; vb[38].y = macroblock->mby * unit.y + unit.y; - vb[39].x = macroblock->mbx * unit.x + half.x; vb[39].y = macroblock->mby * unit.y + unit.y; - vb[40].x = macroblock->mbx * unit.x + unit.x; vb[40].y = macroblock->mby * unit.y + half.y; - vb[41].x = macroblock->mbx * unit.x + unit.x; vb[41].y = macroblock->mby * unit.y + half.y; - - vb[42].x = macroblock->mbx * unit.x + unit.x; vb[42].y = macroblock->mby * unit.y + half.y; - vb[43].x = macroblock->mbx * unit.x + unit.x; vb[43].y = macroblock->mby * unit.y + half.y; - vb[44].x = macroblock->mbx * unit.x + half.x; vb[44].y = macroblock->mby * unit.y + unit.y; - vb[45].x = macroblock->mbx * unit.x + half.x; vb[45].y = macroblock->mby * unit.y + unit.y; - vb[46].x = macroblock->mbx * unit.x + unit.x; vb[46].y = macroblock->mby * unit.y + unit.y; - vb[47].x = macroblock->mbx * unit.x + unit.x; vb[47].y = macroblock->mby * unit.y + unit.y; + SET_BLOCK + ( + vb, + macroblock->cbp, macroblock->mbx, macroblock->mby, + unit.x, unit.y, 0, 0, half.x, half.y, + 32, 2, 1, mc->zero_block.x, mc->zero_block.y + ); + + SET_BLOCK + ( + vb + 6, + macroblock->cbp, macroblock->mbx, macroblock->mby, + unit.x, unit.y, half.x, 0, half.x, half.y, + 16, 2, 1, mc->zero_block.x, mc->zero_block.y + ); + + SET_BLOCK + ( + vb + 12, + macroblock->cbp, macroblock->mbx, macroblock->mby, + unit.x, unit.y, 0, half.y, half.x, half.y, + 8, 2, 1, mc->zero_block.x, mc->zero_block.y + ); + + SET_BLOCK + ( + vb + 18, + macroblock->cbp, macroblock->mbx, macroblock->mby, + unit.x, unit.y, half.x, half.y, half.x, half.y, + 4, 2, 1, mc->zero_block.x, mc->zero_block.y + ); mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer); @@ -577,7 +629,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeIntra] > 0) { pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 2, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 4, mc->vertex_elems); pipe->set_sampler_textures(pipe, 3, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 3, (void**)mc->samplers); pipe->bind_vs_state(pipe, mc->i_vs); @@ -590,7 +642,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0) { pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 4, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); @@ -604,7 +656,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0) { pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 4, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); @@ -618,7 +670,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0) { pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 4, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); @@ -632,7 +684,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0) { pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 4, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]); pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers); @@ -646,7 +698,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0) { pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 8, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]); @@ -661,7 +713,7 @@ static int vlFlush if (num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0) { pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]); - pipe->set_vertex_elements(pipe, 6, mc->vertex_elems); + pipe->set_vertex_elements(pipe, 8, mc->vertex_elems); mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture; mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture; pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]); @@ -831,9 +883,11 @@ static int vlCreateVertexShaderIMB /* * decl i0 ; Vertex pos - * decl i1 ; Luma/chroma texcoords + * decl i1 ; Luma texcoords + * decl i2 ; Chroma Cb texcoords + * decl i3 ; Chroma Cr texcoords */ - for (i = 0; i < 2; i++) + for (i = 0; i < 4; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -841,9 +895,11 @@ static int vlCreateVertexShaderIMB /* * decl o0 ; Vertex pos - * decl o1 ; Luma/chroma texcoords + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords */ - for (i = 0; i < 2; i++) + for (i = 0; i < 4; i++) { decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -851,9 +907,11 @@ static int vlCreateVertexShaderIMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i1 ; Move input luma/chroma texcoords to output + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma Cb texcoords to output + * mov o3, i3 ; Move input chroma Cr texcoords to output */ - for (i = 0; i < 2; ++i) + for (i = 0; i < 4; ++i) { inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -903,9 +961,16 @@ static int vlCreateFragmentShaderIMB ti = 3; - /* decl i0 ; Luma/chroma texcoords */ - decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR); - ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + /* + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + */ + for (i = 0; i < 3; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); @@ -933,14 +998,14 @@ static int vlCreateFragmentShaderIMB /* * tex2d t1, i0, s0 ; Read texel from luma texture * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); @@ -1002,11 +1067,13 @@ static int vlCreateVertexShaderFramePMB /* * decl i0 ; Vertex pos - * decl i1 ; Luma/chroma texcoords - * decl i2 ; Ref surface top field texcoords - * decl i3 ; Ref surface bottom field texcoords (unused, packed in the same stream) + * decl i1 ; Luma texcoords + * decl i2 ; Chroma Cb texcoords + * decl i3 ; Chroma Cr texcoords + * decl i4 ; Ref surface top field texcoords + * decl i5 ; Ref surface bottom field texcoords (unused, packed in the same stream) */ - for (i = 0; i < 4; i++) + for (i = 0; i < 6; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1014,10 +1081,12 @@ static int vlCreateVertexShaderFramePMB /* * decl o0 ; Vertex pos - * decl o1 ; Luma/chroma texcoords - * decl o2 ; Ref macroblock texcoords + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords + * decl o4 ; Ref macroblock texcoords */ - for (i = 0; i < 3; i++) + for (i = 0; i < 5; i++) { decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1025,16 +1094,18 @@ static int vlCreateVertexShaderFramePMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i1 ; Move input luma/chroma texcoords to output + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma Cb texcoords to output + * mov o3, i3 ; Move input chroma Cr texcoords to output */ - for (i = 0; i < 2; ++i) + for (i = 0; i < 4; ++i) { inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* add o2, i0, i2 ; Translate vertex pos by motion vec to form ref macroblock texcoords */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, 2); + /* add o4, i0, i4 ; Translate vertex pos by motion vec to form ref macroblock texcoords */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, 4); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* end */ @@ -1082,12 +1153,14 @@ static int vlCreateVertexShaderFieldPMB ti = 3; /* - * decl i0 ; Vertex pos, luma/chroma texcoords - * decl i1 ; Texcoord denorm coefficients - * decl i2 ; Ref surface top field texcoords - * decl i3 ; Ref surface bottom field texcoords + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma Cb texcoords + * decl i3 ; Chroma Cr texcoords + * decl i4 ; Ref macroblock top field texcoords + * decl i5 ; Ref macroblock bottom field texcoords */ - for (i = 0; i < 4; i++) + for (i = 0; i < 6; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1099,39 +1172,43 @@ static int vlCreateVertexShaderFieldPMB /* * decl o0 ; Vertex pos - * decl o1 ; Luma/chroma texcoords - * decl o2 ; Top field ref macroblock texcoords - * decl o3 ; Bottom field ref macroblock texcoords - * decl o4 ; Denormalized vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords + * decl o4 ; Ref macroblock top field texcoords + * decl o5 ; Ref macroblock bottom field texcoords + * decl o6 ; Denormalized vertex pos */ - for (i = 0; i < 5; i++) + for (i = 0; i < 7; i++) { - decl = vl_decl_output((i == 0 || i == 5) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + decl = vl_decl_output((i == 0 || i == 6) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i1 ; Move input luma/chroma texcoords to output + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma Cb texcoords to output + * mov o3, i3 ; Move input chroma Cr texcoords to output */ - for (i = 0; i < 2; ++i) + for (i = 0; i < 4; ++i) { inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } /* - * add o2, i0, i2 ; Translate vertex pos by motion vec to form top field macroblock texcoords - * add o3, i0, i3 ; Translate vertex pos by motion vec to form bottom field macroblock texcoords + * add o4, i0, i4 ; Translate vertex pos by motion vec to form top field macroblock texcoords + * add o5, i0, i5 ; Translate vertex pos by motion vec to form bottom field macroblock texcoords */ for (i = 0; i < 2; ++i) { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 2); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 4); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* mul o4, i0, c0 ; Denorm vertex pos */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 5, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + /* mul o6, i0, c0 ; Denorm vertex pos */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 6, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* end */ @@ -1179,10 +1256,12 @@ static int vlCreateFragmentShaderFramePMB ti = 3; /* - * decl i0 ; Texcoords for s0, s1, s2 - * decl i1 ; Texcoords for s3 + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + * decl i3 ; Ref macroblock texcoords */ - for (i = 0; i < 2; ++i) + for (i = 0; i < 4; ++i) { decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1215,14 +1294,14 @@ static int vlCreateFragmentShaderFramePMB /* * tex2d t1, i0, s0 ; Read texel from luma texture * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); @@ -1238,8 +1317,8 @@ static int vlCreateFragmentShaderFramePMB inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* tex2d t1, i1, s3 ; Read texel from ref macroblock */ - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 1, TGSI_FILE_SAMPLER, 3); + /* tex2d t1, i3, s3 ; Read texel from ref macroblock */ + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 3, TGSI_FILE_SAMPLER, 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 */ @@ -1291,12 +1370,14 @@ static int vlCreateFragmentShaderFieldPMB ti = 3; /* - * decl i0 ; Texcoords for s0, s1, s2 - * decl i1 ; Texcoords for s3 - * decl i2 ; Texcoords for s3 - * decl i3 ; Denormalized vertex pos + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + * decl i3 ; Ref macroblock top field texcoords + * decl i4 ; Ref macroblock bottom field texcoords + * decl i5 ; Denormalized vertex pos */ - for (i = 0; i < 4; ++i) + for (i = 0; i < 6; ++i) { decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1332,14 +1413,14 @@ static int vlCreateFragmentShaderFieldPMB /* * tex2d t1, i0, s0 ; Read texel from luma texture * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); @@ -1356,18 +1437,18 @@ static int vlCreateFragmentShaderFieldPMB ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* - * tex2d t1, i1, s3 ; Read texel from ref macroblock top field - * tex2d t2, i2, s3 ; Read texel from ref macroblock bottom field + * tex2d t1, i3, s3 ; Read texel from ref macroblock top field + * tex2d t2, i4, s3 ; Read texel from ref macroblock bottom field */ for (i = 0; i < 2; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, 3); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, 3); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } /* XXX: Pos values off by 0.5? */ - /* sub t4, i3.y, c1.x ; Sub 0.5 from denormalized pos */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 3, TGSI_FILE_CONSTANT, 1); + /* sub t4, i5.y, c1.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 5, TGSI_FILE_CONSTANT, 1); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; @@ -1456,14 +1537,16 @@ static int vlCreateVertexShaderFrameBMB ti = 3; /* - * decl i0 ; Vertex pos, luma/chroma texcoords - * decl i1 ; Luma/chroma texcoords - * decl i2 ; First ref surface top field texcoords - * decl i3 ; First ref surface bottom field texcoords (unused, packed in the same stream) - * decl i4 ; Second ref surface top field texcoords - * decl i5 ; Second ref surface bottom field texcoords (unused, packed in the same stream) + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma Cb texcoords + * decl i3 ; Chroma Cr texcoords + * decl i4 ; First ref macroblock top field texcoords + * decl i5 ; First ref macroblock bottom field texcoords (unused, packed in the same stream) + * decl i6 ; Second ref macroblock top field texcoords + * decl i7 ; Second ref macroblock bottom field texcoords (unused, packed in the same stream) */ - for (i = 0; i < 6; i++) + for (i = 0; i < 8; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1471,11 +1554,13 @@ static int vlCreateVertexShaderFrameBMB /* * decl o0 ; Vertex pos - * decl o1 ; Luma/chroma texcoords - * decl o2 ; First ref macroblock texcoords - * decl o3 ; Second ref macroblock texcoords + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords + * decl o4 ; First ref macroblock texcoords + * decl o5 ; Second ref macroblock texcoords */ - for (i = 0; i < 4; i++) + for (i = 0; i < 6; i++) { decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1483,21 +1568,23 @@ static int vlCreateVertexShaderFrameBMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i1 ; Move input luma/chroma texcoords to output + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma Cb texcoords to output + * mov o3, i3 ; Move input chroma Cr texcoords to output */ - for (i = 0; i < 2; ++i) + for (i = 0; i < 4; ++i) { inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } /* - * add o2, i0, i2 ; Translate vertex pos by motion vec to form first ref macroblock texcoords - * add o3, i0, i4 ; Translate vertex pos by motion vec to form second ref macroblock texcoords + * add o4, i0, i4 ; Translate vertex pos by motion vec to form first ref macroblock texcoords + * add o5, i0, i6 ; Translate vertex pos by motion vec to form second ref macroblock texcoords */ for (i = 0; i < 2; ++i) { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, (i + 1) * 2); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, (i + 2) * 2); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -1546,14 +1633,16 @@ static int vlCreateVertexShaderFieldBMB ti = 3; /* - * decl i0 ; Vertex pos, Luma/chroma texcoords - * decl i1 ; Luma/chroma texcoords - * decl i2 ; First ref surface top field texcoords - * decl i3 ; First ref surface bottom field texcoords - * decl i4 ; Second ref surface top field texcoords - * decl i5 ; Second ref surface bottom field texcoords + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma Cb texcoords + * decl i3 ; Chroma Cr texcoords + * decl i4 ; First ref macroblock top field texcoords + * decl i5 ; First ref macroblock bottom field texcoords + * decl i6 ; Second ref macroblock top field texcoords + * decl i7 ; Second ref macroblock bottom field texcoords */ - for (i = 0; i < 6; i++) + for (i = 0; i < 8; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1565,16 +1654,18 @@ static int vlCreateVertexShaderFieldBMB /* * decl o0 ; Vertex pos - * decl o1 ; Luma/chroma texcoords - * decl o2 ; Top field past ref macroblock texcoords - * decl o3 ; Bottom field past ref macroblock texcoords - * decl o4 ; Top field future ref macroblock texcoords - * decl o5 ; Bottom field future ref macroblock texcoords - * decl o6 ; Denormalized vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords + * decl o4 ; First ref macroblock top field texcoords + * decl o5 ; First ref macroblock Bottom field texcoords + * decl o6 ; Second ref macroblock top field texcoords + * decl o7 ; Second ref macroblock Bottom field texcoords + * decl o8 ; Denormalized vertex pos */ - for (i = 0; i < 7; i++) + for (i = 0; i < 9; i++) { - decl = vl_decl_output((i == 0 || i == 7) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + decl = vl_decl_output((i == 0 || i == 8) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -1584,28 +1675,30 @@ static int vlCreateVertexShaderFieldBMB /* * mov o0, i0 ; Move input vertex pos to output - * mov o1, i1 ; Move input luma/chroma texcoords to output + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma Cb texcoords to output + * mov o3, i3 ; Move input chroma Cr texcoords to output */ - for (i = 0; i < 2; ++i) + for (i = 0; i < 4; ++i) { inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } /* - * add o2, i0, i2 ; Translate vertex pos by motion vec to form first top field macroblock texcoords - * add o3, i0, i3 ; Translate vertex pos by motion vec to form first bottom field macroblock texcoords - * add o4, i0, i4 ; Translate vertex pos by motion vec to form second top field macroblock texcoords - * add o5, i0, i5 ; Translate vertex pos by motion vec to form second bottom field macroblock texcoords + * add o4, i0, i4 ; Translate vertex pos by motion vec to form first top field macroblock texcoords + * add o5, i0, i5 ; Translate vertex pos by motion vec to form first bottom field macroblock texcoords + * add o6, i0, i6 ; Translate vertex pos by motion vec to form second top field macroblock texcoords + * add o7, i0, i7 ; Translate vertex pos by motion vec to form second bottom field macroblock texcoords */ for (i = 0; i < 4; ++i) { - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 2); + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 4); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } - /* mul o6, i0, c0 ; Denorm vertex pos */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 6, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); + /* mul o8, i0, c0 ; Denorm vertex pos */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 8, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* end */ @@ -1653,11 +1746,13 @@ static int vlCreateFragmentShaderFrameBMB ti = 3; /* - * decl i0 ; Texcoords for s0, s1, s2 - * decl i1 ; Texcoords for s3 - * decl i2 ; Texcoords for s4 + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + * decl i3 ; First ref macroblock texcoords + * decl i4 ; Second ref macroblock texcoords */ - for (i = 0; i < 3; ++i) + for (i = 0; i < 5; ++i) { decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1682,8 +1777,8 @@ static int vlCreateFragmentShaderFrameBMB * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture * decl s2 ; Sampler for chroma Cr texture - * decl s3 ; Sampler for past ref surface texture - * decl s4 ; Sampler for future ref surface texture + * decl s3 ; Sampler for first ref surface texture + * decl s4 ; Sampler for second ref surface texture */ for (i = 0; i < 5; ++i) { @@ -1694,14 +1789,14 @@ static int vlCreateFragmentShaderFrameBMB /* * tex2d t1, i0, s0 ; Read texel from luma texture * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); @@ -1718,12 +1813,12 @@ static int vlCreateFragmentShaderFrameBMB ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* - * tex2d t1, i1, s3 ; Read texel from past ref macroblock - * tex2d t2, i2, s4 ; Read texel from future ref macroblock + * tex2d t1, i3, s3 ; Read texel from first ref macroblock + * tex2d t2, i4, s4 ; Read texel from second ref macroblock */ for (i = 0; i < 2; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, i + 3); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, i + 3); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -1784,14 +1879,16 @@ static int vlCreateFragmentShaderFieldBMB ti = 3; /* - * decl i0 ; Texcoords for s0, s1, s2 - * decl i1 ; Texcoords for s3 - * decl i2 ; Texcoords for s3 - * decl i3 ; Texcoords for s4 - * decl i4 ; Texcoords for s4 - * decl i5 ; Denormalized vertex pos + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + * decl i3 ; First ref macroblock top field texcoords + * decl i4 ; First ref macroblock bottom field texcoords + * decl i5 ; Second ref macroblock top field texcoords + * decl i6 ; Second ref macroblock bottom field texcoords + * decl i7 ; Denormalized vertex pos */ - for (i = 0; i < 6; ++i) + for (i = 0; i < 8; ++i) { decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1817,8 +1914,8 @@ static int vlCreateFragmentShaderFieldBMB * decl s0 ; Sampler for luma texture * decl s1 ; Sampler for chroma Cb texture * decl s2 ; Sampler for chroma Cr texture - * decl s3 ; Sampler for past ref surface texture - * decl s4 ; Sampler for future ref surface texture + * decl s3 ; Sampler for first ref surface texture + * decl s4 ; Sampler for second ref surface texture */ for (i = 0; i < 5; ++i) { @@ -1829,14 +1926,14 @@ static int vlCreateFragmentShaderFieldBMB /* * tex2d t1, i0, s0 ; Read texel from luma texture * mov t0.x, t1.x ; Move luma sample into .x component - * tex2d t1, i0, s1 ; Read texel from chroma Cb texture + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture * mov t0.y, t1.x ; Move Cb sample into .y component - * tex2d t1, i0, s2 ; Read texel from chroma Cr texture + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ for (i = 0; i < 3; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); @@ -1853,8 +1950,8 @@ static int vlCreateFragmentShaderFieldBMB ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* XXX: Pos values off by 0.5? */ - /* sub t4, i5.y, c1.x ; Sub 0.5 from denormalized pos */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 5, TGSI_FILE_CONSTANT, 1); + /* sub t4, i7.y, c1.x ; Sub 0.5 from denormalized pos */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 7, TGSI_FILE_CONSTANT, 1); inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; @@ -1890,12 +1987,12 @@ static int vlCreateFragmentShaderFieldBMB ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* - * tex2d t1, i1, s3 ; Read texel from past ref macroblock top field - * tex2d t2, i2, s3 ; Read texel from past ref macroblock bottom field + * tex2d t1, i3, s3 ; Read texel from past ref macroblock top field + * tex2d t2, i4, s3 ; Read texel from past ref macroblock bottom field */ for (i = 0; i < 2; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, 3); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, 3); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -1905,12 +2002,12 @@ static int vlCreateFragmentShaderFieldBMB ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* - * tex2d t4, i3, s4 ; Read texel from future ref macroblock top field - * tex2d t5, i4, s4 ; Read texel from future ref macroblock bottom field + * tex2d t4, i5, s4 ; Read texel from future ref macroblock top field + * tex2d t5, i6, s4 ; Read texel from future ref macroblock bottom field */ for (i = 0; i < 2; ++i) { - inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 4, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, 4); + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 4, TGSI_FILE_INPUT, i + 5, TGSI_FILE_SAMPLER, 4); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -1961,7 +2058,18 @@ static int vlCreateDataBufs /* Create our vertex buffers */ for (h = 0; h < NUM_BUF_SETS; ++h) { - for (i = 0; i < 3; ++i) + mc->vertex_bufs[h][0].pitch = sizeof(struct vlVertex2f) * 4; + mc->vertex_bufs[h][0].max_index = 24 * num_mb_per_frame - 1; + mc->vertex_bufs[h][0].buffer_offset = 0; + mc->vertex_bufs[h][0].buffer = pipe->winsys->buffer_create + ( + pipe->winsys, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vlVertex2f) * 4 * 24 * num_mb_per_frame + ); + + for (i = 1; i < 3; ++i) { mc->vertex_bufs[h][i].pitch = sizeof(struct vlVertex2f) * 2; mc->vertex_bufs[h][i].max_index = 24 * num_mb_per_frame - 1; @@ -1982,36 +2090,48 @@ static int vlCreateDataBufs mc->vertex_elems[0].nr_components = 2; mc->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* Block luma, block chroma texcoord element */ + /* Luma, texcoord element */ mc->vertex_elems[1].src_offset = sizeof(struct vlVertex2f); mc->vertex_elems[1].vertex_buffer_index = 0; mc->vertex_elems[1].nr_components = 2; mc->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* First ref surface top field texcoord element */ - mc->vertex_elems[2].src_offset = 0; - mc->vertex_elems[2].vertex_buffer_index = 1; + /* Chroma Cr texcoord element */ + mc->vertex_elems[2].src_offset = sizeof(struct vlVertex2f) * 2; + mc->vertex_elems[2].vertex_buffer_index = 0; mc->vertex_elems[2].nr_components = 2; mc->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* First ref surface bottom field texcoord element */ - mc->vertex_elems[3].src_offset = sizeof(struct vlVertex2f); - mc->vertex_elems[3].vertex_buffer_index = 1; + /* Chroma Cb texcoord element */ + mc->vertex_elems[3].src_offset = sizeof(struct vlVertex2f) * 3; + mc->vertex_elems[3].vertex_buffer_index = 0; mc->vertex_elems[3].nr_components = 2; mc->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* Second ref surface top field texcoord element */ + /* First ref surface top field texcoord element */ mc->vertex_elems[4].src_offset = 0; - mc->vertex_elems[4].vertex_buffer_index = 2; + mc->vertex_elems[4].vertex_buffer_index = 1; mc->vertex_elems[4].nr_components = 2; mc->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT; - /* Second ref surface bottom field texcoord element */ + /* First ref surface bottom field texcoord element */ mc->vertex_elems[5].src_offset = sizeof(struct vlVertex2f); - mc->vertex_elems[5].vertex_buffer_index = 2; + mc->vertex_elems[5].vertex_buffer_index = 1; mc->vertex_elems[5].nr_components = 2; mc->vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT; + /* Second ref surface top field texcoord element */ + mc->vertex_elems[6].src_offset = 0; + mc->vertex_elems[6].vertex_buffer_index = 2; + mc->vertex_elems[6].nr_components = 2; + mc->vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Second ref surface bottom field texcoord element */ + mc->vertex_elems[7].src_offset = sizeof(struct vlVertex2f); + mc->vertex_elems[7].vertex_buffer_index = 2; + mc->vertex_elems[7].nr_components = 2; + mc->vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT; + /* Create our constant buffer */ mc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts); mc->vs_const_buf.buffer = pipe->winsys->buffer_create -- cgit v1.2.3 From 2f41095e04036654259bc2efc3324a92f32c8ca1 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Thu, 4 Sep 2008 04:10:43 -0400 Subject: g3dvl: Zero-block optimization. For blocks whose contents are derived completely from ref surfaces, don't bother zero-ing the corresponding block in the luma/chroma textures, except for the first such luma, chroma Cb, and chroma Cr each frame. All later zero blocks are textured from that first zero block. --- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 92 +++++++++++++--------- 1 file changed, 54 insertions(+), 38 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index b5aa79cdb4..93839e8aa9 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -63,6 +63,7 @@ struct vlR16SnormBufferedMC struct vlSurface *buffered_surface; struct vlSurface *past_surface, *future_surface; struct vlVertex2f surface_tex_inv_size; + struct vlVertex2f zero_block[3]; unsigned int num_macroblocks; struct vlMpeg2MacroBlock *macroblocks; @@ -203,8 +204,13 @@ static inline int vlGrabBlocks ++sb; } - else + else if (mc->zero_block[0].x < 0.0f) + { vlGrabNoBlock(texels + y * tex_pitch * VL_BLOCK_HEIGHT + x * VL_BLOCK_WIDTH, tex_pitch); + + mc->zero_block[0].x = (mbpx + x * 8) * mc->surface_tex_inv_size.x; + mc->zero_block[0].y = (mbpy + y * 8) * mc->surface_tex_inv_size.y; + } } } @@ -241,9 +247,14 @@ static inline int vlGrabBlocks ++sb; } - else + else if (mc->zero_block[tb + 1].x < 0.0f) + { vlGrabNoBlock(texels, tex_pitch); + mc->zero_block[tb + 1].x = (mbpx << 1) * mc->surface_tex_inv_size.x; + mc->zero_block[tb + 1].y = (mbpy << 1) * mc->surface_tex_inv_size.y; + } + pipe_surface_unmap(tex_surface); } @@ -315,7 +326,7 @@ static inline int vlGrabMacroBlock return 0; } -#define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zx, zy) \ +#define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zb) \ (vb)[0].pos.x = (mbx) * (unitx) + (ofsx); (vb)[0].pos.y = (mby) * (unity) + (ofsy); \ (vb)[1].pos.x = (mbx) * (unitx) + (ofsx); (vb)[1].pos.y = (mby) * (unity) + (ofsy) + (hy); \ (vb)[2].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].pos.y = (mby) * (unity) + (ofsy); \ @@ -323,62 +334,62 @@ static inline int vlGrabMacroBlock (vb)[4].pos.x = (mbx) * (unitx) + (ofsx); (vb)[4].pos.y = (mby) * (unity) + (ofsy) + (hy); \ (vb)[5].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].pos.y = (mby) * (unity) + (ofsy) + (hy); \ \ - /*if ((cbp) & (lm)) \ - {*/ \ + if ((cbp) & (lm)) \ + { \ (vb)[0].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].luma_tc.y = (mby) * (unity) + (ofsy); \ (vb)[1].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \ (vb)[2].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].luma_tc.y = (mby) * (unity) + (ofsy); \ (vb)[3].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].luma_tc.y = (mby) * (unity) + (ofsy); \ (vb)[4].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \ (vb)[5].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \ - /*} \ + } \ else \ { \ - (vb)[0].luma_tc.x = (zx); (vb)[0].luma_tc.y = (zy); \ - (vb)[1].luma_tc.x = (zx); (vb)[1].luma_tc.y = (zy) + (hy); \ - (vb)[2].luma_tc.x = (zx) + (hx); (vb)[2].luma_tc.y = (zy); \ - (vb)[3].luma_tc.x = (zx) + (hx); (vb)[3].luma_tc.y = (zy); \ - (vb)[4].luma_tc.x = (zx); (vb)[4].luma_tc.y = (zy) + (hy); \ - (vb)[5].luma_tc.x = ((zx) + (hx); (vb)[5].luma_tc.y = (zy) + (hy); \ - }*/ \ + (vb)[0].luma_tc.x = (zb)[0].x; (vb)[0].luma_tc.y = (zb)[0].y; \ + (vb)[1].luma_tc.x = (zb)[0].x; (vb)[1].luma_tc.y = (zb)[0].y + (hy); \ + (vb)[2].luma_tc.x = (zb)[0].x + (hx); (vb)[2].luma_tc.y = (zb)[0].y; \ + (vb)[3].luma_tc.x = (zb)[0].x + (hx); (vb)[3].luma_tc.y = (zb)[0].y; \ + (vb)[4].luma_tc.x = (zb)[0].x; (vb)[4].luma_tc.y = (zb)[0].y + (hy); \ + (vb)[5].luma_tc.x = (zb)[0].x + (hx); (vb)[5].luma_tc.y = (zb)[0].y + (hy); \ + } \ \ - /*if ((cbp) & (cbm)) \ - {*/ \ + if ((cbp) & (cbm)) \ + { \ (vb)[0].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cb_tc.y = (mby) * (unity) + (ofsy); \ (vb)[1].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \ (vb)[2].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cb_tc.y = (mby) * (unity) + (ofsy); \ (vb)[3].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cb_tc.y = (mby) * (unity) + (ofsy); \ (vb)[4].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \ (vb)[5].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \ - /*} \ + } \ else \ { \ - (vb)[0].cb_tc.x = (zx); (vb)[0].cb_tc.y = (zy); \ - (vb)[1].cb_tc.x = (zx); (vb)[1].cb_tc.y = (zy) + (hy); \ - (vb)[2].cb_tc.x = (zx) + (hx); (vb)[2].cb_tc.y = (zy); \ - (vb)[3].cb_tc.x = (zx) + (hx); (vb)[3].cb_tc.y = (zy); \ - (vb)[4].cb_tc.x = (zx); (vb)[4].cb_tc.y = (zy) + (hy); \ - (vb)[5].cb_tc.x = ((zx) + (hx); (vb)[5].cb_tc.y = (zy) + (hy); \ - }*/ \ + (vb)[0].cb_tc.x = (zb)[1].x; (vb)[0].cb_tc.y = (zb)[1].y; \ + (vb)[1].cb_tc.x = (zb)[1].x; (vb)[1].cb_tc.y = (zb)[1].y + (hy); \ + (vb)[2].cb_tc.x = (zb)[1].x + (hx); (vb)[2].cb_tc.y = (zb)[1].y; \ + (vb)[3].cb_tc.x = (zb)[1].x + (hx); (vb)[3].cb_tc.y = (zb)[1].y; \ + (vb)[4].cb_tc.x = (zb)[1].x; (vb)[4].cb_tc.y = (zb)[1].y + (hy); \ + (vb)[5].cb_tc.x = (zb)[1].x + (hx); (vb)[5].cb_tc.y = (zb)[1].y + (hy); \ + } \ \ - /*if ((cbp) & (crm)) \ - {*/ \ + if ((cbp) & (crm)) \ + { \ (vb)[0].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cr_tc.y = (mby) * (unity) + (ofsy); \ (vb)[1].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \ (vb)[2].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cr_tc.y = (mby) * (unity) + (ofsy); \ (vb)[3].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cr_tc.y = (mby) * (unity) + (ofsy); \ (vb)[4].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \ (vb)[5].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \ - /*} \ + } \ else \ { \ - (vb)[0].cr_tc.x = (zx); (vb)[0].cb_tc.y = (zy); \ - (vb)[1].cr_tc.x = (zx); (vb)[1].cb_tc.y = (zy) + (hy); \ - (vb)[2].cr_tc.x = (zx) + (hx); (vb)[2].cb_tc.y = (zy); \ - (vb)[3].cr_tc.x = (zx) + (hx); (vb)[3].cb_tc.y = (zy); \ - (vb)[4].cr_tc.x = (zx); (vb)[4].cb_tc.y = (zy) + (hy); \ - (vb)[5].cr_tc.x = ((zx) + (hx); (vb)[5].cb_tc.y = (zy) + (hy); \ - }*/ + (vb)[0].cr_tc.x = (zb)[2].x; (vb)[0].cr_tc.y = (zb)[2].y; \ + (vb)[1].cr_tc.x = (zb)[2].x; (vb)[1].cr_tc.y = (zb)[2].y + (hy); \ + (vb)[2].cr_tc.x = (zb)[2].x + (hx); (vb)[2].cr_tc.y = (zb)[2].y; \ + (vb)[3].cr_tc.x = (zb)[2].x + (hx); (vb)[3].cr_tc.y = (zb)[2].y; \ + (vb)[4].cr_tc.x = (zb)[2].x; (vb)[4].cr_tc.y = (zb)[2].y + (hy); \ + (vb)[5].cr_tc.x = (zb)[2].x + (hx); (vb)[5].cr_tc.y = (zb)[2].y + (hy); \ + } static inline int vlGrabMacroBlockVB ( @@ -526,7 +537,7 @@ static inline int vlGrabMacroBlockVB vb, macroblock->cbp, macroblock->mbx, macroblock->mby, unit.x, unit.y, 0, 0, half.x, half.y, - 32, 2, 1, mc->zero_block.x, mc->zero_block.y + 32, 2, 1, mc->zero_block ); SET_BLOCK @@ -534,7 +545,7 @@ static inline int vlGrabMacroBlockVB vb + 6, macroblock->cbp, macroblock->mbx, macroblock->mby, unit.x, unit.y, half.x, 0, half.x, half.y, - 16, 2, 1, mc->zero_block.x, mc->zero_block.y + 16, 2, 1, mc->zero_block ); SET_BLOCK @@ -542,7 +553,7 @@ static inline int vlGrabMacroBlockVB vb + 12, macroblock->cbp, macroblock->mbx, macroblock->mby, unit.x, unit.y, 0, half.y, half.x, half.y, - 8, 2, 1, mc->zero_block.x, mc->zero_block.y + 8, 2, 1, mc->zero_block ); SET_BLOCK @@ -550,7 +561,7 @@ static inline int vlGrabMacroBlockVB vb + 18, macroblock->cbp, macroblock->mbx, macroblock->mby, unit.x, unit.y, half.x, half.y, half.x, half.y, - 4, 2, 1, mc->zero_block.x, mc->zero_block.y + 4, 2, 1, mc->zero_block ); mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer); @@ -725,6 +736,8 @@ static int vlFlush vb_start += num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24; } + for (i = 0; i < 3; ++i) + mc->zero_block[i].x = -1.0f; mc->num_macroblocks = 0; mc->cur_buf++; @@ -2277,7 +2290,8 @@ int vlCreateR16SNormBufferedMC struct vlRender **render ) { - struct vlR16SnormBufferedMC *mc; + struct vlR16SnormBufferedMC *mc; + unsigned int i; assert(pipe); assert(render); @@ -2297,6 +2311,8 @@ int vlCreateR16SNormBufferedMC mc->buffered_surface = NULL; mc->past_surface = NULL; mc->future_surface = NULL; + for (i = 0; i < 3; ++i) + mc->zero_block[i].x = -1.0f; mc->num_macroblocks = 0; vlInit(mc); -- cgit v1.2.3 From f302fca5eb63e4bca8af5b35c585451486143e6a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 11 Sep 2008 06:41:18 +1000 Subject: nouveau: gallium directory structure changed again.. --- src/gallium/drivers/nouveau/nouveau_stateobj.h | 1 - src/gallium/drivers/nv04/nv04_context.c | 1 - src/gallium/drivers/nv04/nv04_context.h | 4 + src/gallium/drivers/nv04/nv04_fragprog.c | 1 - src/gallium/drivers/nv04/nv04_miptree.c | 6 +- src/gallium/drivers/nv04/nv04_prim_vbuf.c | 5 +- src/gallium/drivers/nv04/nv04_screen.c | 1 - src/gallium/drivers/nv04/nv04_state.c | 1 - src/gallium/drivers/nv04/nv04_surface.c | 3 +- src/gallium/drivers/nv04/nv04_vbo.c | 1 - src/gallium/drivers/nv10/nv10_context.c | 1 - src/gallium/drivers/nv10/nv10_context.h | 4 + src/gallium/drivers/nv10/nv10_fragprog.c | 1 - src/gallium/drivers/nv10/nv10_miptree.c | 6 +- src/gallium/drivers/nv10/nv10_prim_vbuf.c | 6 +- src/gallium/drivers/nv10/nv10_screen.c | 1 - src/gallium/drivers/nv10/nv10_state.c | 1 - src/gallium/drivers/nv10/nv10_state_emit.c | 2 - src/gallium/drivers/nv10/nv10_surface.c | 3 +- src/gallium/drivers/nv10/nv10_vbo.c | 1 - src/gallium/drivers/nv30/nv30_context.c | 1 - src/gallium/drivers/nv30/nv30_context.h | 4 + src/gallium/drivers/nv30/nv30_draw.c | 1 - src/gallium/drivers/nv30/nv30_miptree.c | 9 +- src/gallium/drivers/nv30/nv30_screen.c | 1 - src/gallium/drivers/nv30/nv30_state.c | 1 - src/gallium/drivers/nv30/nv30_surface.c | 4 +- src/gallium/drivers/nv30/nv30_vbo.c | 1 - src/gallium/drivers/nv40/nv40_context.c | 1 - src/gallium/drivers/nv40/nv40_context.h | 4 + src/gallium/drivers/nv40/nv40_draw.c | 3 +- src/gallium/drivers/nv40/nv40_miptree.c | 11 +- src/gallium/drivers/nv40/nv40_screen.c | 1 - src/gallium/drivers/nv40/nv40_state.c | 1 - src/gallium/drivers/nv40/nv40_surface.c | 4 +- src/gallium/drivers/nv40/nv40_vbo.c | 1 - src/gallium/drivers/nv50/nv50_context.c | 1 - src/gallium/drivers/nv50/nv50_context.h | 4 + src/gallium/drivers/nv50/nv50_draw.c | 1 - src/gallium/drivers/nv50/nv50_miptree.c | 12 +- src/gallium/drivers/nv50/nv50_screen.c | 1 - src/gallium/drivers/nv50/nv50_state.c | 1 - src/gallium/drivers/nv50/nv50_surface.c | 12 +- src/gallium/drivers/nv50/nv50_vbo.c | 1 - src/gallium/winsys/dri/nouveau/Makefile | 45 -- src/gallium/winsys/dri/nouveau/nouveau_bo.c | 470 --------------------- src/gallium/winsys/dri/nouveau/nouveau_channel.c | 126 ------ src/gallium/winsys/dri/nouveau/nouveau_context.c | 346 --------------- src/gallium/winsys/dri/nouveau/nouveau_context.h | 113 ----- src/gallium/winsys/dri/nouveau/nouveau_device.c | 159 ------- src/gallium/winsys/dri/nouveau/nouveau_dma.c | 219 ---------- src/gallium/winsys/dri/nouveau/nouveau_dma.h | 143 ------- src/gallium/winsys/dri/nouveau/nouveau_dri.h | 28 -- src/gallium/winsys/dri/nouveau/nouveau_drmif.h | 310 -------------- src/gallium/winsys/dri/nouveau/nouveau_fence.c | 214 ---------- src/gallium/winsys/dri/nouveau/nouveau_grobj.c | 107 ----- src/gallium/winsys/dri/nouveau/nouveau_local.h | 117 ----- src/gallium/winsys/dri/nouveau/nouveau_lock.c | 94 ----- src/gallium/winsys/dri/nouveau/nouveau_notifier.c | 137 ------ src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c | 271 ------------ src/gallium/winsys/dri/nouveau/nouveau_resource.c | 116 ----- src/gallium/winsys/dri/nouveau/nouveau_screen.c | 310 -------------- src/gallium/winsys/dri/nouveau/nouveau_screen.h | 20 - .../winsys/dri/nouveau/nouveau_swapbuffers.c | 86 ---- .../winsys/dri/nouveau/nouveau_swapbuffers.h | 10 - src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 158 ------- .../winsys/dri/nouveau/nouveau_winsys_pipe.c | 205 --------- .../winsys/dri/nouveau/nouveau_winsys_pipe.h | 34 -- .../winsys/dri/nouveau/nouveau_winsys_softpipe.c | 85 ---- src/gallium/winsys/dri/nouveau/nv04_surface.c | 314 -------------- src/gallium/winsys/dri/nouveau/nv50_surface.c | 194 --------- src/gallium/winsys/drm/nouveau/Makefile | 45 ++ src/gallium/winsys/drm/nouveau/nouveau_bo.c | 470 +++++++++++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_channel.c | 126 ++++++ src/gallium/winsys/drm/nouveau/nouveau_context.c | 346 +++++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_context.h | 113 +++++ src/gallium/winsys/drm/nouveau/nouveau_device.c | 159 +++++++ src/gallium/winsys/drm/nouveau/nouveau_dma.c | 219 ++++++++++ src/gallium/winsys/drm/nouveau/nouveau_dma.h | 143 +++++++ src/gallium/winsys/drm/nouveau/nouveau_dri.h | 28 ++ src/gallium/winsys/drm/nouveau/nouveau_drmif.h | 310 ++++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_fence.c | 214 ++++++++++ src/gallium/winsys/drm/nouveau/nouveau_grobj.c | 107 +++++ src/gallium/winsys/drm/nouveau/nouveau_local.h | 117 +++++ src/gallium/winsys/drm/nouveau/nouveau_lock.c | 94 +++++ src/gallium/winsys/drm/nouveau/nouveau_notifier.c | 137 ++++++ src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c | 271 ++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_resource.c | 116 +++++ src/gallium/winsys/drm/nouveau/nouveau_screen.c | 310 ++++++++++++++ src/gallium/winsys/drm/nouveau/nouveau_screen.h | 20 + .../winsys/drm/nouveau/nouveau_swapbuffers.c | 86 ++++ .../winsys/drm/nouveau/nouveau_swapbuffers.h | 10 + src/gallium/winsys/drm/nouveau/nouveau_winsys.c | 158 +++++++ .../winsys/drm/nouveau/nouveau_winsys_pipe.c | 206 +++++++++ .../winsys/drm/nouveau/nouveau_winsys_pipe.h | 34 ++ .../winsys/drm/nouveau/nouveau_winsys_softpipe.c | 85 ++++ src/gallium/winsys/drm/nouveau/nv04_surface.c | 314 ++++++++++++++ src/gallium/winsys/drm/nouveau/nv50_surface.c | 194 +++++++++ 98 files changed, 4487 insertions(+), 4507 deletions(-) delete mode 100644 src/gallium/winsys/dri/nouveau/Makefile delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_bo.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_channel.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_context.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_context.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_device.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dma.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dma.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_dri.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_drmif.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_fence.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_grobj.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_local.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_lock.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_notifier.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_resource.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_screen.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_screen.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h delete mode 100644 src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c delete mode 100644 src/gallium/winsys/dri/nouveau/nv04_surface.c delete mode 100644 src/gallium/winsys/dri/nouveau/nv50_surface.c create mode 100644 src/gallium/winsys/drm/nouveau/Makefile create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_bo.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_channel.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_context.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_context.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_device.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_dma.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_dma.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_dri.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_drmif.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_fence.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_grobj.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_local.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_lock.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_notifier.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_resource.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_screen.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_screen.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h create mode 100644 src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c create mode 100644 src/gallium/winsys/drm/nouveau/nv04_surface.c create mode 100644 src/gallium/winsys/drm/nouveau/nv50_surface.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index 998ec2d4ad..729988b095 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -1,7 +1,6 @@ #ifndef __NOUVEAU_STATEOBJ_H__ #define __NOUVEAU_STATEOBJ_H__ -#include "pipe/p_util.h" #include "pipe/p_debug.h" struct nouveau_stateobj_reloc { diff --git a/src/gallium/drivers/nv04/nv04_context.c b/src/gallium/drivers/nv04/nv04_context.c index 852a8edf5f..9f75253363 100644 --- a/src/gallium/drivers/nv04/nv04_context.c +++ b/src/gallium/drivers/nv04/nv04_context.c @@ -1,7 +1,6 @@ #include "draw/draw_context.h" #include "pipe/p_defines.h" #include "pipe/p_winsys.h" -#include "pipe/p_util.h" #include "nv04_context.h" #include "nv04_screen.h" diff --git a/src/gallium/drivers/nv04/nv04_context.h b/src/gallium/drivers/nv04/nv04_context.h index 5ba1d4ecdc..3e6a085270 100644 --- a/src/gallium/drivers/nv04/nv04_context.h +++ b/src/gallium/drivers/nv04/nv04_context.h @@ -4,6 +4,10 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "pipe/p_compiler.h" + +#include "util/u_memory.h" +#include "util/u_math.h" #include "draw/draw_vertex.h" diff --git a/src/gallium/drivers/nv04/nv04_fragprog.c b/src/gallium/drivers/nv04/nv04_fragprog.c index 215974eec0..8a2af41fe0 100644 --- a/src/gallium/drivers/nv04/nv04_fragprog.c +++ b/src/gallium/drivers/nv04/nv04_fragprog.c @@ -1,7 +1,6 @@ #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/tgsi_parse.h" diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c index 97f679731e..02f7d210e3 100644 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -1,6 +1,5 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "nv04_context.h" @@ -72,7 +71,6 @@ nv04_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) static void nv04_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) { - struct pipe_winsys *ws = screen->winsys; struct pipe_texture *mt = *pt; *pt = NULL; @@ -80,7 +78,7 @@ nv04_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) struct nv04_miptree *nv04mt = (struct nv04_miptree *)mt; int l; - pipe_buffer_reference(ws, &nv04mt->buffer, NULL); + pipe_buffer_reference(screen, &nv04mt->buffer, NULL); for (l = 0; l <= mt->last_level; l++) { if (nv04mt->level[l].image_offset) FREE(nv04mt->level[l].image_offset); @@ -101,7 +99,7 @@ nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps = ws->surface_alloc(ws); if (!ps) return NULL; - pipe_buffer_reference(ws, &ps->buffer, nv04mt->buffer); + pipe_buffer_reference(pscreen, &ps->buffer, nv04mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; diff --git a/src/gallium/drivers/nv04/nv04_prim_vbuf.c b/src/gallium/drivers/nv04/nv04_prim_vbuf.c index d3963d1f59..19979fff79 100644 --- a/src/gallium/drivers/nv04/nv04_prim_vbuf.c +++ b/src/gallium/drivers/nv04/nv04_prim_vbuf.c @@ -1,9 +1,10 @@ -#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 "pipe/p_compiler.h" + +#include "draw/draw_vbuf.h" #include "nv04_context.h" #include "nv04_state.h" diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c index da09a3a5fe..3966a29ffa 100644 --- a/src/gallium/drivers/nv04/nv04_screen.c +++ b/src/gallium/drivers/nv04/nv04_screen.c @@ -1,5 +1,4 @@ #include "pipe/p_screen.h" -#include "pipe/p_util.h" #include "nv04_context.h" #include "nv04_screen.h" diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c index 668d875671..ff1933b550 100644 --- a/src/gallium/drivers/nv04/nv04_state.c +++ b/src/gallium/drivers/nv04/nv04_state.c @@ -1,7 +1,6 @@ #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 "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/nv04/nv04_surface.c b/src/gallium/drivers/nv04/nv04_surface.c index b13ebf9f9b..57039483c6 100644 --- a/src/gallium/drivers/nv04/nv04_surface.c +++ b/src/gallium/drivers/nv04/nv04_surface.c @@ -28,10 +28,9 @@ #include "nv04_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" +#include "util/u_tile.h" static void nv04_surface_copy(struct pipe_context *pipe, unsigned do_flip, diff --git a/src/gallium/drivers/nv04/nv04_vbo.c b/src/gallium/drivers/nv04/nv04_vbo.c index fbfe0cf406..91f919d48e 100644 --- a/src/gallium/drivers/nv04/nv04_vbo.c +++ b/src/gallium/drivers/nv04/nv04_vbo.c @@ -1,7 +1,6 @@ #include "draw/draw_context.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "nv04_context.h" #include "nv04_state.h" diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c index 9fcd0b0fc3..e9b61daae7 100644 --- a/src/gallium/drivers/nv10/nv10_context.c +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -1,7 +1,6 @@ #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" diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index 2bdba53db8..f3b56de25a 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -4,6 +4,10 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "pipe/p_compiler.h" + +#include "util/u_memory.h" +#include "util/u_math.h" #include "draw/draw_vertex.h" diff --git a/src/gallium/drivers/nv10/nv10_fragprog.c b/src/gallium/drivers/nv10/nv10_fragprog.c index 137de9d53e..698db5a16a 100644 --- a/src/gallium/drivers/nv10/nv10_fragprog.c +++ b/src/gallium/drivers/nv10/nv10_fragprog.c @@ -1,7 +1,6 @@ #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/tgsi_parse.h" diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c index 9a68df2925..ad084e72b8 100644 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -1,6 +1,5 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "nv10_context.h" @@ -79,7 +78,6 @@ nv10_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) 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; @@ -87,7 +85,7 @@ nv10_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) struct nv10_miptree *nv10mt = (struct nv10_miptree *)mt; int l; - pipe_buffer_reference(ws, &nv10mt->buffer, NULL); + pipe_buffer_reference(screen, &nv10mt->buffer, NULL); for (l = 0; l <= mt->last_level; l++) { if (nv10mt->level[l].image_offset) FREE(nv10mt->level[l].image_offset); @@ -115,7 +113,7 @@ nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, ps = ws->surface_alloc(ws); if (!ps) return NULL; - pipe_buffer_reference(ws, &ps->buffer, nv10mt->buffer); + pipe_buffer_reference(screen, &ps->buffer, nv10mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c index 930536b946..62a8f6d89d 100644 --- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c +++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c @@ -38,15 +38,14 @@ */ -#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" +#include "draw/draw_vbuf.h" /** * Primitive renderer for nv10. @@ -180,10 +179,11 @@ nv10_vbuf_render_release_vertices( struct vbuf_render *render, struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); struct nv10_context *nv10 = nv10_render->nv10; struct pipe_winsys *winsys = nv10->pipe.winsys; + struct pipe_screen *pscreen = &nv10->screen->pipe; assert(nv10_render->buffer); winsys->buffer_unmap(winsys, nv10_render->buffer); - pipe_buffer_reference(winsys, &nv10_render->buffer, NULL); + pipe_buffer_reference(pscreen, &nv10_render->buffer, NULL); } diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index 403f7b98cd..27a9edf9bb 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -1,5 +1,4 @@ #include "pipe/p_screen.h" -#include "pipe/p_util.h" #include "nv10_context.h" #include "nv10_screen.h" diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index f902fd54b6..d2375aa2f6 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -1,7 +1,6 @@ #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 "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c index d21368d33f..46c7e1d753 100644 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -1,5 +1,3 @@ -#include "pipe/p_util.h" - #include "nv10_context.h" #include "nv10_state.h" diff --git a/src/gallium/drivers/nv10/nv10_surface.c b/src/gallium/drivers/nv10/nv10_surface.c index 2e230ebbec..875e4c5858 100644 --- a/src/gallium/drivers/nv10/nv10_surface.c +++ b/src/gallium/drivers/nv10/nv10_surface.c @@ -28,10 +28,9 @@ #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" +#include "util/u_tile.h" static void nv10_surface_copy(struct pipe_context *pipe, unsigned do_flip, diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c index f024f53420..d0e788ac03 100644 --- a/src/gallium/drivers/nv10/nv10_vbo.c +++ b/src/gallium/drivers/nv10/nv10_vbo.c @@ -1,7 +1,6 @@ #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" diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index eefc614e5b..2bff28aca9 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -1,7 +1,6 @@ #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" diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 823b34a7c3..b933769700 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -4,6 +4,10 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "pipe/p_compiler.h" + +#include "util/u_memory.h" +#include "util/u_math.h" #include "draw/draw_vertex.h" diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c index aeeaf58f20..74fc138c05 100644 --- a/src/gallium/drivers/nv30/nv30_draw.c +++ b/src/gallium/drivers/nv30/nv30_draw.c @@ -1,5 +1,4 @@ #include "draw/draw_pipe.h" -#include "pipe/p_util.h" #include "nv30_context.h" diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index a0e488c09b..5c4f4da948 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -1,6 +1,5 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "nv30_context.h" @@ -33,7 +32,7 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt) if (swizzled) pitch = pt->nblocksx[l]; - pitch = align_int(pitch, 64); + pitch = align(pitch, 64); nv30mt->level[l].pitch = pitch * pt->block.size; nv30mt->level[l].image_offset = @@ -84,7 +83,6 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) 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; @@ -92,7 +90,7 @@ nv30_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) struct nv30_miptree *nv30mt = (struct nv30_miptree *)mt; int l; - pipe_buffer_reference(ws, &nv30mt->buffer, NULL); + pipe_buffer_reference(pscreen, &nv30mt->buffer, NULL); for (l = 0; l <= mt->last_level; l++) { if (nv30mt->level[l].image_offset) FREE(nv30mt->level[l].image_offset); @@ -106,7 +104,6 @@ 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; @@ -114,7 +111,7 @@ nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, if (!ps) return NULL; pipe_texture_reference(&ps->texture, pt); - pipe_buffer_reference(ws, &ps->buffer, nv30mt->buffer); + pipe_buffer_reference(pscreen, &ps->buffer, nv30mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index d5514c2aba..a595e2eb22 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -1,5 +1,4 @@ #include "pipe/p_screen.h" -#include "pipe/p_util.h" #include "nv30_context.h" #include "nv30_screen.h" diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index eceb535315..fc66075c83 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -1,6 +1,5 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/nv30/nv30_surface.c b/src/gallium/drivers/nv30/nv30_surface.c index b22211ac86..36f4887750 100644 --- a/src/gallium/drivers/nv30/nv30_surface.c +++ b/src/gallium/drivers/nv30/nv30_surface.c @@ -28,10 +28,10 @@ #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" + +#include "util/u_tile.h" static void nv30_surface_copy(struct pipe_context *pipe, unsigned do_flip, diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index b1c73793bf..556f981d4a 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -1,6 +1,5 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "nv30_context.h" #include "nv30_state.h" diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index a40f14895f..cc63dd734b 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -1,7 +1,6 @@ #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" diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 8e60a81e68..adcfbdd85a 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -4,6 +4,10 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "pipe/p_compiler.h" + +#include "util/u_memory.h" +#include "util/u_math.h" #include "draw/draw_vertex.h" diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 2cf58e2950..8e56cdc2fe 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -1,6 +1,7 @@ -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" +#include "util/u_pack_color.h" + #include "draw/draw_context.h" #include "draw/draw_vertex.h" #include "draw/draw_pipe.h" diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 38e1a5f04c..6c54c37ef7 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -1,6 +1,5 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "nv40_context.h" @@ -33,7 +32,7 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) if (swizzled) pitch = pt->nblocksx[l]; - pitch = align_int(pitch, 64); + pitch = align(pitch, 64); nv40mt->level[l].pitch = pitch * pt->block.size; nv40mt->level[l].image_offset = @@ -84,7 +83,6 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) 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; @@ -92,7 +90,7 @@ nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) struct nv40_miptree *nv40mt = (struct nv40_miptree *)mt; int l; - pipe_buffer_reference(ws, &nv40mt->buffer, NULL); + pipe_buffer_reference(pscreen, &nv40mt->buffer, NULL); for (l = 0; l <= mt->last_level; l++) { if (nv40mt->level[l].image_offset) FREE(nv40mt->level[l].image_offset); @@ -106,7 +104,6 @@ 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; @@ -114,7 +111,7 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, if (!ps) return NULL; pipe_texture_reference(&ps->texture, pt); - pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer); + pipe_buffer_reference(pscreen, &ps->buffer, nv40mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; @@ -148,7 +145,7 @@ nv40_miptree_surface_del(struct pipe_screen *pscreen, return; pipe_texture_reference(&ps->texture, NULL); - pipe_buffer_reference(pscreen->winsys, &ps->buffer, NULL); + pipe_buffer_reference(pscreen, &ps->buffer, NULL); FREE(ps); } diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 0e1df89ee8..ada0238511 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -1,5 +1,4 @@ #include "pipe/p_screen.h" -#include "pipe/p_util.h" #include "nv40_context.h" #include "nv40_screen.h" diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 63d0ecc915..255c4b294d 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -1,6 +1,5 @@ #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" diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index 0916555d56..576af7c59e 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -28,10 +28,10 @@ #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" + +#include "util/u_tile.h" static void nv40_surface_copy(struct pipe_context *pipe, boolean do_flip, diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 755d5586b7..09f6e79d32 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -1,6 +1,5 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "nv40_context.h" #include "nv40_state.h" diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 07987c7d02..b02c53f209 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -23,7 +23,6 @@ #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" diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 1c069f1625..5d377f2d06 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -4,6 +4,10 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "pipe/p_compiler.h" + +#include "util/u_memory.h" +#include "util/u_math.h" #include "draw/draw_vertex.h" diff --git a/src/gallium/drivers/nv50/nv50_draw.c b/src/gallium/drivers/nv50/nv50_draw.c index 4fd81bd27a..2f6f607261 100644 --- a/src/gallium/drivers/nv50/nv50_draw.c +++ b/src/gallium/drivers/nv50/nv50_draw.c @@ -21,7 +21,6 @@ */ #include "draw/draw_pipe.h" -#include "pipe/p_util.h" #include "nv50_context.h" diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index a02ad41885..b0e8fe2f0b 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -22,7 +22,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "nv50_context.h" @@ -62,7 +61,6 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) static void nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) { - struct pipe_winsys *ws = pscreen->winsys; struct pipe_texture *pt = *ppt; *ppt = NULL; @@ -70,7 +68,7 @@ nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) if (--pt->refcount <= 0) { struct nv50_miptree *mt = nv50_miptree(pt); - pipe_buffer_reference(ws, &mt->buffer, NULL); + pipe_buffer_reference(pscreen, &mt->buffer, NULL); FREE(mt); } } @@ -80,7 +78,6 @@ 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 nv50_surface *s; struct pipe_surface *ps; @@ -91,7 +88,7 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps = &s->base; ps->refcount = 1; - ps->winsys = ws; + ps->winsys = pscreen->winsys; ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; @@ -104,7 +101,7 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->status = PIPE_SURFACE_STATUS_DEFINED; pipe_texture_reference(&ps->texture, pt); - pipe_buffer_reference(ws, &ps->buffer, mt->buffer); + pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer); return ps; } @@ -113,7 +110,6 @@ static void nv50_miptree_surface_del(struct pipe_screen *pscreen, struct pipe_surface **psurface) { - struct pipe_winsys *ws = pscreen->winsys; struct pipe_surface *ps = *psurface; struct nv50_surface *s = nv50_surface(ps); @@ -121,7 +117,7 @@ nv50_miptree_surface_del(struct pipe_screen *pscreen, if (--ps->refcount <= 0) { pipe_texture_reference(&ps->texture, NULL); - pipe_buffer_reference(ws, &ps->buffer, NULL); + pipe_buffer_reference(pscreen, &ps->buffer, NULL); FREE(s); } } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index ec43923929..b5aef7dadd 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -21,7 +21,6 @@ */ #include "pipe/p_screen.h" -#include "pipe/p_util.h" #include "nv50_context.h" #include "nv50_screen.h" diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 4055527d9f..95f9d408b5 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -22,7 +22,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index a9daeee369..5bf97d3a6b 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -22,10 +22,10 @@ #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" + +#include "util/u_tile.h" static void nv50_surface_copy(struct pipe_context *pipe, boolean flip, @@ -90,10 +90,10 @@ nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *ps, } static void -nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *ps) +nv50_surface_unmap(struct pipe_screen *pscreen, struct pipe_surface *ps) { - struct nouveau_winsys *nvws = nv50_screen(screen)->nvws; - struct pipe_winsys *ws = screen->winsys; + struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws; + struct pipe_winsys *ws = pscreen->winsys; struct nv50_surface *s = nv50_surface(ps); struct nv50_surface m = *s; @@ -104,7 +104,7 @@ nv50_surface_unmap(struct pipe_screen *screen, struct pipe_surface *ps) nvws->surface_copy(nvws, &s->base, 0, 0, &m.base, 0, 0, ps->width, ps->height); - pipe_buffer_reference(ws, &s->untiled, NULL); + pipe_buffer_reference(pscreen, &s->untiled, NULL); } void diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index c94531723b..584336682e 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -22,7 +22,6 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "nv50_context.h" diff --git a/src/gallium/winsys/dri/nouveau/Makefile b/src/gallium/winsys/dri/nouveau/Makefile deleted file mode 100644 index be630ff6d1..0000000000 --- a/src/gallium/winsys/dri/nouveau/Makefile +++ /dev/null @@ -1,45 +0,0 @@ - -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = nouveau_dri.so - -MINIGLX_SOURCES = - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/nv04/libnv04.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 deleted file mode 100644 index b5942994d9..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_bo.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * 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 -#include -#include -#include - -#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; - - if (flags & NOUVEAU_BO_TILED) { - nvbo->tiled = 1; - if (flags & NOUVEAU_BO_ZTILE) - nvbo->tiled |= 2; - flags &= ~NOUVEAU_BO_TILED; - } - - 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 (nvbo->tiled && flags) { - new_flags |= NOUVEAU_MEM_TILE; - if (nvbo->tiled & 2) - new_flags |= NOUVEAU_MEM_TILE_ZETA; - } - - 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) { - struct nouveau_pushbuf_bo *pbo = nvbo->pending; - nvbo->pending = NULL; - nouveau_bo_map(bo, NOUVEAU_BO_RD); - memcpy(new_map, bo->map, bo->size); - nouveau_bo_unmap(bo); - nvbo->pending = pbo; - } - - /* 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 deleted file mode 100644 index 3b4dcd1ecf..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_channel.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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 -#include -#include - -#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 deleted file mode 100644 index 74413c408f..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ /dev/null @@ -1,346 +0,0 @@ -#include "main/glheader.h" -#include "glapi/glthread.h" -#include -#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)); - if (nv_screen->front_cpp == 2) - fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; - else - fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; - pf_get_block(fb_surf->format, &fb_surf->block); - fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; - fb_surf->height = nv_screen->front_height; - fb_surf->stride = fb_surf->width * fb_surf->block.size; - 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 deleted file mode 100644 index 77e2147a2c..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.h +++ /dev/null @@ -1,113 +0,0 @@ -#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 deleted file mode 100644 index 0b452fcd02..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_device.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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 -#include -#include - -#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 deleted file mode 100644 index f8a8ba04f6..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_dma.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * 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 -#include -#include - -#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 deleted file mode 100644 index cfa6d26e82..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_dma.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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 -#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 deleted file mode 100644 index 1207c2d609..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_dri.h +++ /dev/null @@ -1,28 +0,0 @@ -#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 deleted file mode 100644 index dcd6a5eb0a..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_drmif.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * 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 -#include -#include - -#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; - int tiled; -}; -#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 deleted file mode 100644 index e7b0b4ff07..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_fence.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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 -#include -#include - -#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 deleted file mode 100644 index 51523897d5..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_grobj.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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 -#include - -#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 deleted file mode 100644 index e878a40803..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_local.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef __NOUVEAU_LOCAL_H__ -#define __NOUVEAU_LOCAL_H__ - -#include "pipe/p_compiler.h" -#include "nouveau_winsys_pipe.h" -#include - -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 deleted file mode 100644 index 9adb9ac854..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_lock.c +++ /dev/null @@ -1,94 +0,0 @@ -/************************************************************************** - * - * 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 - -#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 deleted file mode 100644 index 01e8f38440..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_notifier.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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 -#include - -#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 deleted file mode 100644 index 815046ba85..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_pushbuf.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * 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 -#include -#include - -#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 deleted file mode 100644 index 3bbcb5c45e..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_resource.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 -#include - -#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 deleted file mode 100644 index df1fe7e69b..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.c +++ /dev/null @@ -1,310 +0,0 @@ -#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 != 11 -#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 - }; - - uint8_t depth_bits_array[4] = { 0, 16, 24, 24 }; - uint8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; - uint8_t msaa_samples_array[1] = { 0 }; - - 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, - msaa_samples_array, 1, - 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, - msaa_samples_array, 1, - 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 deleted file mode 100644 index 388d6be9bb..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_screen.h +++ /dev/null @@ -1,20 +0,0 @@ -#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 deleted file mode 100644 index 70e0104e83..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c +++ /dev/null @@ -1,86 +0,0 @@ -#include "main/glheader.h" -#include "glapi/glthread.h" -#include - -#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 deleted file mode 100644 index 825d3da6da..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.h +++ /dev/null @@ -1,10 +0,0 @@ -#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 deleted file mode 100644 index 5eabbc8893..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ /dev/null @@ -1,158 +0,0 @@ -#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 deleted file mode 100644 index 8a2870a2ff..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c +++ /dev/null @@ -1,205 +0,0 @@ -#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_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; - - switch (dev->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - flags |= NOUVEAU_BO_TILED; - if (usage & NOUVEAU_BUFFER_USAGE_ZETA) - flags |= NOUVEAU_BO_ZTILE; - break; - default: - break; - } - } - - 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->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 deleted file mode 100644 index 6a03ac0d77..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.h +++ /dev/null @@ -1,34 +0,0 @@ -#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 deleted file mode 100644 index 704f6c7750..0000000000 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_softpipe.c +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#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 deleted file mode 100644 index 8fa3d106c8..0000000000 --- a/src/gallium/winsys/dri/nouveau/nv04_surface.c +++ /dev/null @@ -1,314 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_format.h" - -#include "nouveau_context.h" - -static INLINE int -nv04_surface_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; - case PIPE_FORMAT_R5G6B5_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; - default: - return -1; - } -} - -static INLINE int -nv04_rect_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; - case PIPE_FORMAT_R5G6B5_UNORM: - return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - 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->stride) + (dx * dst->block.size); - src_offset = src->offset + (sy * src->stride) + (sx * src->block.size); - - 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->stride); - OUT_RING (chan, dst->stride); - OUT_RING (chan, w * src->block.size); - OUT_RING (chan, count); - OUT_RING (chan, 0x0101); - OUT_RING (chan, 0); - - h -= count; - src_offset += src->stride * count; - dst_offset += dst->stride * 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->format != dst->format) - 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->format)) < 0) { - NOUVEAU_ERR("Bad surface format 0x%x\n", dst->format); - 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->stride << 16) | src->stride); - 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->format)) < 0) { - NOUVEAU_ERR("Bad format = %d\n", dst->format); - return 1; - } - - if ((gdirect_format = nv04_rect_format(dst->format)) < 0) { - NOUVEAU_ERR("Bad format = %d\n", dst->format); - 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->stride << 16) | dst->stride); - 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++); - BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); - OUT_RING (chan, nvc->channel->vram->handle); - - 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 deleted file mode 100644 index c8ab7f690f..0000000000 --- a/src/gallium/winsys/dri/nouveau/nv50_surface.c +++ /dev/null @@ -1,194 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_format.h" - -#include "nouveau_context.h" - -static INLINE int -nv50_format(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return NV50_2D_DST_FORMAT_32BPP; - case PIPE_FORMAT_X8R8G8B8_UNORM: - return NV50_2D_DST_FORMAT_24BPP; - case PIPE_FORMAT_R5G6B5_UNORM: - return NV50_2D_DST_FORMAT_16BPP; - case PIPE_FORMAT_A8_UNORM: - return NV50_2D_DST_FORMAT_8BPP; - default: - return -1; - } -} - -static int -nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) -{ - struct nouveau_channel *chan = nv->nvc->channel; - struct nouveau_grobj *eng2d = nv->nvc->Nv2D; - struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; - int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; - int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); - - surf_format = nv50_format(surf->format); - if (surf_format < 0) - return 1; - - if (!nouveau_bo(bo)->tiled) { - BEGIN_RING(chan, eng2d, mthd, 2); - OUT_RING (chan, surf_format); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, mthd + 0x14, 5); - OUT_RING (chan, surf->stride); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - OUT_RELOCh(chan, bo, surf->offset, flags); - OUT_RELOCl(chan, bo, surf->offset, flags); - } else { - BEGIN_RING(chan, eng2d, mthd, 5); - OUT_RING (chan, surf_format); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, mthd + 0x18, 4); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - OUT_RELOCh(chan, bo, surf->offset, flags); - OUT_RELOCl(chan, bo, surf->offset, flags); - } - -#if 0 - if (dst) { - BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, surf->width); - OUT_RING (chan, surf->height); - } -#endif - - return 0; -} - -static int -nv50_surface_copy_prep(struct nouveau_context *nv, - struct pipe_surface *dst, struct pipe_surface *src) -{ - int ret; - - assert(src->format == dst->format); - - ret = nv50_surface_set(nv, dst, 1); - if (ret) - return ret; - - ret = nv50_surface_set(nv, src, 0); - if (ret) - return ret; - - 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, 0x088c, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); - OUT_RING (chan, dx); - OUT_RING (chan, dy); - OUT_RING (chan, w); - OUT_RING (chan, h); - BEGIN_RING(chan, eng2d, 0x08c0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - BEGIN_RING(chan, eng2d, 0x08d0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, sx); - OUT_RING (chan, 0); - OUT_RING (chan, sy); -} - -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 rect_format, ret; - - rect_format = nv50_format(dst->format); - if (rect_format < 0) - return 1; - - ret = nv50_surface_set(nv, dst, 1); - if (ret) - return ret; - - 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) -{ - struct nouveau_channel *chan = nvc->channel; - struct nouveau_grobj *eng2d = NULL; - int ret; - - ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d); - if (ret) - return ret; - nvc->Nv2D = eng2d; - - BIND_RING (chan, eng2d, nvc->next_subchannel++); - BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); - OUT_RING (chan, nvc->sync_notifier->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); - OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); - BEGIN_RING(chan, eng2d, 0x0290, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, eng2d, 0x0888, 1); - OUT_RING (chan, 1); - - 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/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile new file mode 100644 index 0000000000..be630ff6d1 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/Makefile @@ -0,0 +1,45 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = nouveau_dri.so + +MINIGLX_SOURCES = + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/nv04/libnv04.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/drm/nouveau/nouveau_bo.c b/src/gallium/winsys/drm/nouveau/nouveau_bo.c new file mode 100644 index 0000000000..b5942994d9 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_bo.c @@ -0,0 +1,470 @@ +/* + * 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 +#include +#include +#include + +#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; + + if (flags & NOUVEAU_BO_TILED) { + nvbo->tiled = 1; + if (flags & NOUVEAU_BO_ZTILE) + nvbo->tiled |= 2; + flags &= ~NOUVEAU_BO_TILED; + } + + 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 (nvbo->tiled && flags) { + new_flags |= NOUVEAU_MEM_TILE; + if (nvbo->tiled & 2) + new_flags |= NOUVEAU_MEM_TILE_ZETA; + } + + 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) { + struct nouveau_pushbuf_bo *pbo = nvbo->pending; + nvbo->pending = NULL; + nouveau_bo_map(bo, NOUVEAU_BO_RD); + memcpy(new_map, bo->map, bo->size); + nouveau_bo_unmap(bo); + nvbo->pending = pbo; + } + + /* 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/drm/nouveau/nouveau_channel.c b/src/gallium/winsys/drm/nouveau/nouveau_channel.c new file mode 100644 index 0000000000..3b4dcd1ecf --- /dev/null +++ b/src/gallium/winsys/drm/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 +#include +#include + +#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/drm/nouveau/nouveau_context.c b/src/gallium/winsys/drm/nouveau/nouveau_context.c new file mode 100644 index 0000000000..74413c408f --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_context.c @@ -0,0 +1,346 @@ +#include "main/glheader.h" +#include "glapi/glthread.h" +#include +#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)); + if (nv_screen->front_cpp == 2) + fb_surf->format = PIPE_FORMAT_R5G6B5_UNORM; + else + fb_surf->format = PIPE_FORMAT_A8R8G8B8_UNORM; + pf_get_block(fb_surf->format, &fb_surf->block); + fb_surf->width = nv_screen->front_pitch / nv_screen->front_cpp; + fb_surf->height = nv_screen->front_height; + fb_surf->stride = fb_surf->width * fb_surf->block.size; + 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/drm/nouveau/nouveau_context.h b/src/gallium/winsys/drm/nouveau/nouveau_context.h new file mode 100644 index 0000000000..77e2147a2c --- /dev/null +++ b/src/gallium/winsys/drm/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/drm/nouveau/nouveau_device.c b/src/gallium/winsys/drm/nouveau/nouveau_device.c new file mode 100644 index 0000000000..0b452fcd02 --- /dev/null +++ b/src/gallium/winsys/drm/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 +#include +#include + +#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/drm/nouveau/nouveau_dma.c b/src/gallium/winsys/drm/nouveau/nouveau_dma.c new file mode 100644 index 0000000000..f8a8ba04f6 --- /dev/null +++ b/src/gallium/winsys/drm/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 +#include +#include + +#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/drm/nouveau/nouveau_dma.h b/src/gallium/winsys/drm/nouveau/nouveau_dma.h new file mode 100644 index 0000000000..cfa6d26e82 --- /dev/null +++ b/src/gallium/winsys/drm/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 +#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/drm/nouveau/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/nouveau_dri.h new file mode 100644 index 0000000000..1207c2d609 --- /dev/null +++ b/src/gallium/winsys/drm/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/drm/nouveau/nouveau_drmif.h b/src/gallium/winsys/drm/nouveau/nouveau_drmif.h new file mode 100644 index 0000000000..dcd6a5eb0a --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_drmif.h @@ -0,0 +1,310 @@ +/* + * 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 +#include +#include + +#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; + int tiled; +}; +#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/drm/nouveau/nouveau_fence.c b/src/gallium/winsys/drm/nouveau/nouveau_fence.c new file mode 100644 index 0000000000..e7b0b4ff07 --- /dev/null +++ b/src/gallium/winsys/drm/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 +#include +#include + +#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/drm/nouveau/nouveau_grobj.c b/src/gallium/winsys/drm/nouveau/nouveau_grobj.c new file mode 100644 index 0000000000..51523897d5 --- /dev/null +++ b/src/gallium/winsys/drm/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 +#include + +#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/drm/nouveau/nouveau_local.h b/src/gallium/winsys/drm/nouveau/nouveau_local.h new file mode 100644 index 0000000000..e878a40803 --- /dev/null +++ b/src/gallium/winsys/drm/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 + +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/drm/nouveau/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/nouveau_lock.c new file mode 100644 index 0000000000..9adb9ac854 --- /dev/null +++ b/src/gallium/winsys/drm/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 + +#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/drm/nouveau/nouveau_notifier.c b/src/gallium/winsys/drm/nouveau/nouveau_notifier.c new file mode 100644 index 0000000000..01e8f38440 --- /dev/null +++ b/src/gallium/winsys/drm/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 +#include + +#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/drm/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/drm/nouveau/nouveau_pushbuf.c new file mode 100644 index 0000000000..815046ba85 --- /dev/null +++ b/src/gallium/winsys/drm/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 +#include +#include + +#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/drm/nouveau/nouveau_resource.c b/src/gallium/winsys/drm/nouveau/nouveau_resource.c new file mode 100644 index 0000000000..3bbcb5c45e --- /dev/null +++ b/src/gallium/winsys/drm/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 +#include + +#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/drm/nouveau/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/nouveau_screen.c new file mode 100644 index 0000000000..df1fe7e69b --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_screen.c @@ -0,0 +1,310 @@ +#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 != 11 +#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 + }; + + uint8_t depth_bits_array[4] = { 0, 16, 24, 24 }; + uint8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; + uint8_t msaa_samples_array[1] = { 0 }; + + 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, + msaa_samples_array, 1, + 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, + msaa_samples_array, 1, + 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/drm/nouveau/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/nouveau_screen.h new file mode 100644 index 0000000000..388d6be9bb --- /dev/null +++ b/src/gallium/winsys/drm/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/drm/nouveau/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c new file mode 100644 index 0000000000..70e0104e83 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.c @@ -0,0 +1,86 @@ +#include "main/glheader.h" +#include "glapi/glthread.h" +#include + +#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/drm/nouveau/nouveau_swapbuffers.h b/src/gallium/winsys/drm/nouveau/nouveau_swapbuffers.h new file mode 100644 index 0000000000..825d3da6da --- /dev/null +++ b/src/gallium/winsys/drm/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/drm/nouveau/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c new file mode 100644 index 0000000000..0878840dcc --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c @@ -0,0 +1,158 @@ +#include "util/u_memory.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/drm/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c new file mode 100644 index 0000000000..5276806de6 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.c @@ -0,0 +1,206 @@ +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" + +#include "util/u_memory.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_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; + + switch (dev->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + flags |= NOUVEAU_BO_TILED; + if (usage & NOUVEAU_BUFFER_USAGE_ZETA) + flags |= NOUVEAU_BO_ZTILE; + break; + default: + break; + } + } + + 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->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/drm/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/nouveau_winsys_pipe.h new file mode 100644 index 0000000000..6a03ac0d77 --- /dev/null +++ b/src/gallium/winsys/drm/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/drm/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys_softpipe.c new file mode 100644 index 0000000000..704f6c7750 --- /dev/null +++ b/src/gallium/winsys/drm/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 + */ + +#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/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c new file mode 100644 index 0000000000..8fa3d106c8 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -0,0 +1,314 @@ +#include "pipe/p_context.h" +#include "pipe/p_format.h" + +#include "nouveau_context.h" + +static INLINE int +nv04_surface_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; + default: + return -1; + } +} + +static INLINE int +nv04_rect_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + 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->stride) + (dx * dst->block.size); + src_offset = src->offset + (sy * src->stride) + (sx * src->block.size); + + 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->stride); + OUT_RING (chan, dst->stride); + OUT_RING (chan, w * src->block.size); + OUT_RING (chan, count); + OUT_RING (chan, 0x0101); + OUT_RING (chan, 0); + + h -= count; + src_offset += src->stride * count; + dst_offset += dst->stride * 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->format != dst->format) + 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->format)) < 0) { + NOUVEAU_ERR("Bad surface format 0x%x\n", dst->format); + 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->stride << 16) | src->stride); + 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->format)) < 0) { + NOUVEAU_ERR("Bad format = %d\n", dst->format); + return 1; + } + + if ((gdirect_format = nv04_rect_format(dst->format)) < 0) { + NOUVEAU_ERR("Bad format = %d\n", dst->format); + 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->stride << 16) | dst->stride); + 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++); + BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_NOTIFY, 1); + OUT_RING (chan, nvc->sync_notifier->handle); + BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); + OUT_RING (chan, nvc->channel->vram->handle); + + 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/drm/nouveau/nv50_surface.c b/src/gallium/winsys/drm/nouveau/nv50_surface.c new file mode 100644 index 0000000000..c8ab7f690f --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/nv50_surface.c @@ -0,0 +1,194 @@ +#include "pipe/p_context.h" +#include "pipe/p_format.h" + +#include "nouveau_context.h" + +static INLINE int +nv50_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + return NV50_2D_DST_FORMAT_32BPP; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return NV50_2D_DST_FORMAT_24BPP; + case PIPE_FORMAT_R5G6B5_UNORM: + return NV50_2D_DST_FORMAT_16BPP; + case PIPE_FORMAT_A8_UNORM: + return NV50_2D_DST_FORMAT_8BPP; + default: + return -1; + } +} + +static int +nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct nouveau_grobj *eng2d = nv->nvc->Nv2D; + struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo; + int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; + int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); + + surf_format = nv50_format(surf->format); + if (surf_format < 0) + return 1; + + if (!nouveau_bo(bo)->tiled) { + BEGIN_RING(chan, eng2d, mthd, 2); + OUT_RING (chan, surf_format); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, mthd + 0x14, 5); + OUT_RING (chan, surf->stride); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } else { + BEGIN_RING(chan, eng2d, mthd, 5); + OUT_RING (chan, surf_format); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, mthd + 0x18, 4); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + OUT_RELOCh(chan, bo, surf->offset, flags); + OUT_RELOCl(chan, bo, surf->offset, flags); + } + +#if 0 + if (dst) { + BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, surf->width); + OUT_RING (chan, surf->height); + } +#endif + + return 0; +} + +static int +nv50_surface_copy_prep(struct nouveau_context *nv, + struct pipe_surface *dst, struct pipe_surface *src) +{ + int ret; + + assert(src->format == dst->format); + + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; + + ret = nv50_surface_set(nv, src, 0); + if (ret) + return ret; + + 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, 0x088c, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4); + OUT_RING (chan, dx); + OUT_RING (chan, dy); + OUT_RING (chan, w); + OUT_RING (chan, h); + BEGIN_RING(chan, eng2d, 0x08c0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + BEGIN_RING(chan, eng2d, 0x08d0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, sx); + OUT_RING (chan, 0); + OUT_RING (chan, sy); +} + +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 rect_format, ret; + + rect_format = nv50_format(dst->format); + if (rect_format < 0) + return 1; + + ret = nv50_surface_set(nv, dst, 1); + if (ret) + return ret; + + 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) +{ + struct nouveau_channel *chan = nvc->channel; + struct nouveau_grobj *eng2d = NULL; + int ret; + + ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d); + if (ret) + return ret; + nvc->Nv2D = eng2d; + + BIND_RING (chan, eng2d, nvc->next_subchannel++); + BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4); + OUT_RING (chan, nvc->sync_notifier->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1); + OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); + BEGIN_RING(chan, eng2d, 0x0290, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, eng2d, 0x0888, 1); + OUT_RING (chan, 1); + + 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; +} + -- cgit v1.2.3 From d64da83a2c21d17f2f0a6b9b4c8e90df0e993559 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 12 Sep 2008 23:51:39 +1000 Subject: nouveau: rework nouveau_screen for latest and greatest changes --- src/gallium/winsys/drm/nouveau/nouveau_screen.c | 267 ++++++++++-------------- 1 file changed, 110 insertions(+), 157 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/drm/nouveau/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/nouveau_screen.c index df1fe7e69b..9489645151 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_screen.c @@ -64,50 +64,6 @@ 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, @@ -162,149 +118,146 @@ nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv) 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, +static __DRIconfig ** +nouveau_fill_in_modes(__DRIscreenPrivate *psp, + unsigned pixel_bits, unsigned depth_bits, unsigned stencil_bits, GLboolean have_back_buffer) { - __GLcontextModes * modes; - __GLcontextModes * m; - unsigned num_modes; + __DRIconfig **configs; 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 }, - }; + GLenum fb_format; + GLenum fb_type; - /* 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 + GLX_NONE, GLX_SWAP_UNDEFINED_OML, }; - uint8_t depth_bits_array[4] = { 0, 16, 24, 24 }; - uint8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; - uint8_t msaa_samples_array[1] = { 0 }; - - 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, - msaa_samples_array, 1, - 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, - msaa_samples_array, 1, - GLX_DIRECT_COLOR)) { - fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__ ); + u_int8_t depth_bits_array[3]; + u_int8_t stencil_bits_array[3]; + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + if (depth_bits == 24) + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + + stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = + ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + if (pixel_bits == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + configs = driCreateConfigs(fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor); + if (configs == NULL) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__); return NULL; - } } - return modes; + return configs; } -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) + +static const __DRIconfig ** +nouveau_screen_create(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; + struct nouveau_dri *nv_dri = psp->pDevPriv; + struct nouveau_screen *nv_screen; 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; + int ret; if (!driCheckDriDdxDrmVersions2("nouveau", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { + &psp->dri_version, &dri_expected, + &psp->ddx_version, &ddx_expected, + &psp->drm_version, &drm_expected)) { return NULL; } - if (drm_expected.patch != drm_version->patch) { + if (drm_expected.patch != psp->drm_version.patch) { fprintf(stderr, "Incompatible DRM patch level.\n" "Expected: %d\n" "Current : %d\n", - drm_expected.patch, drm_version->patch); + drm_expected.patch, psp->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; + driInitExtensions(NULL, card_extensions, GL_FALSE); - *driver_modes = nouveau_fill_in_modes(nv_dri->bpp, - (nv_dri->bpp == 16) ? 16 : 24, - (nv_dri->bpp == 16) ? 0 : 8, - 1); + if (psp->devPrivSize != sizeof(struct nouveau_dri)) { + NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n"); + return GL_FALSE; + } - driInitExtensions(NULL, card_extensions, GL_FALSE); + nv_screen = CALLOC_STRUCT(nouveau_screen); + if (!nv_screen) + return GL_FALSE; + nv_screen->driScrnPriv = psp; + psp->private = (void *)nv_screen; + + driParseOptionInfo(&nv_screen->option_cache, + __driConfigOptions, __driNConfigOptions); + + if ((ret = nouveau_device_open_existing(&nv_screen->device, 0, + psp->fd, 0))) { + NOUVEAU_ERR("Failed opening nouveau device: %d\n", ret); + return GL_FALSE; + } - return (void *)psp; + 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 (const __DRIconfig **) + nouveau_fill_in_modes(psp, nv_dri->bpp, + (nv_dri->bpp == 16) ? 16 : 24, + (nv_dri->bpp == 16) ? 0 : 8, 1); } +static void +nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv) +{ + struct nouveau_screen *nv_screen = driScrnPriv->private; + + driScrnPriv->private = NULL; + FREE(nv_screen); +} + +const struct __DriverAPIRec +driDriverAPI = { + .InitScreen = 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, + .CopySubBuffer = nouveau_copy_sub_buffer, + + .InitScreen2 = NULL, /* one day, I promise! */ +}; + -- cgit v1.2.3 From 6b50fd27b85bc0d060ead13e6c656dd64c9a2978 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 8 Sep 2008 21:05:49 -0400 Subject: g3dvl: Clean up Makefile deps. --- src/driclient/src/Makefile | 8 +- src/driclient/src/test.c | 41 ---------- src/driclient/src/xf86dri.h | 119 ------------------------------ src/gallium/winsys/g3dvl/nouveau/Makefile | 9 ++- src/libXvMC/Makefile | 21 ++++-- 5 files changed, 22 insertions(+), 176 deletions(-) delete mode 100644 src/driclient/src/test.c delete mode 100644 src/driclient/src/xf86dri.h (limited to 'src/gallium') diff --git a/src/driclient/src/Makefile b/src/driclient/src/Makefile index 5d913ad5fa..34435a2086 100644 --- a/src/driclient/src/Makefile +++ b/src/driclient/src/Makefile @@ -8,16 +8,12 @@ CFLAGS += -g -Wall -fPIC -I../include -I${DRMDIR}/include -I${DRMDIR}/include/d .PHONY = all clean -all: ${TARGET} test +all: ${TARGET} ${TARGET}: ${OBJECTS} ar rcs $@ $^ if ! test -d ../lib; then mkdir ../lib; fi cp ${TARGET} ../lib -test: test.o - $(CC) -L../lib -L${DRMDIR}/lib ${LDFLAGS} -o $@ $^ -ldriclient -lX11 -lXext -ldrm - clean: - rm -rf ${OBJECTS} ${TARGET} ../lib/${TARGET} test test.o - + rm -rf ${OBJECTS} ${TARGET} ../lib/${TARGET} diff --git a/src/driclient/src/test.c b/src/driclient/src/test.c deleted file mode 100644 index 15f75d928b..0000000000 --- a/src/driclient/src/test.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include "driclient.h" - -int main(int argc, char **argv) -{ - Display *dpy; - Window root, window; - - dri_screen_t *screen; - dri_drawable_t *dri_drawable; - dri_context_t *context; - - dpy = XOpenDisplay(NULL); - root = XDefaultRootWindow(dpy); - window = XCreateSimpleWindow(dpy, root, 0, 0, 100, 100, 0, 0, 0); - - XSelectInput(dpy, window, 0); - XMapWindow(dpy, window); - XSync(dpy, 0); - - assert(driCreateScreen(dpy, 0, &screen, NULL) == 0); - assert(driCreateDrawable(screen, window, &dri_drawable) == 0); - assert(driCreateContext(screen, XDefaultVisual(dpy, 0), &context) == 0); - assert(driUpdateDrawableInfo(dri_drawable) == 0); - - DRI_VALIDATE_DRAWABLE_INFO(screen, dri_drawable); - - assert(drmGetLock(screen->fd, context->drm_context, 0) == 0); - assert(drmUnlock(screen->fd, context->drm_context) == 0); - - assert(driDestroyContext(context) == 0); - assert(driDestroyDrawable(dri_drawable) == 0); - assert(driDestroyScreen(screen) == 0); - - XDestroyWindow(dpy, window); - XCloseDisplay(dpy); - - return 0; -} - diff --git a/src/driclient/src/xf86dri.h b/src/driclient/src/xf86dri.h deleted file mode 100644 index baf80a7a9d..0000000000 --- a/src/driclient/src/xf86dri.h +++ /dev/null @@ -1,119 +0,0 @@ -/************************************************************************** - -Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. -Copyright 2000 VA Linux Systems, Inc. -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 PRECISION INSIGHT 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 xf86dri.h - * Protocol numbers and function prototypes for DRI X protocol. - * - * \author Kevin E. Martin - * \author Jens Owen - * \author Rickard E. (Rik) Faith - */ - -#ifndef _XF86DRI_H_ -#define _XF86DRI_H_ - -#include -#include - -#define X_XF86DRIQueryVersion 0 -#define X_XF86DRIQueryDirectRenderingCapable 1 -#define X_XF86DRIOpenConnection 2 -#define X_XF86DRICloseConnection 3 -#define X_XF86DRIGetClientDriverName 4 -#define X_XF86DRICreateContext 5 -#define X_XF86DRIDestroyContext 6 -#define X_XF86DRICreateDrawable 7 -#define X_XF86DRIDestroyDrawable 8 -#define X_XF86DRIGetDrawableInfo 9 -#define X_XF86DRIGetDeviceInfo 10 -#define X_XF86DRIAuthConnection 11 -#define X_XF86DRIOpenFullScreen 12 /* Deprecated */ -#define X_XF86DRICloseFullScreen 13 /* Deprecated */ - -#define XF86DRINumberEvents 0 - -#define XF86DRIClientNotLocal 0 -#define XF86DRIOperationNotSupported 1 -#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1) - -#ifndef _XF86DRI_SERVER_ - -_XFUNCPROTOBEGIN - -Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base ); - -Bool XF86DRIQueryVersion( Display *dpy, int *majorVersion, int *minorVersion, - int *patchVersion ); - -Bool XF86DRIQueryDirectRenderingCapable( Display *dpy, int screen, - Bool *isCapable ); - -Bool XF86DRIOpenConnection( Display *dpy, int screen, drm_handle_t *hSAREA, - char **busIDString ); - -Bool XF86DRIAuthConnection( Display *dpy, int screen, drm_magic_t magic ); - -Bool XF86DRICloseConnection( Display *dpy, int screen ); - -Bool XF86DRIGetClientDriverName( Display *dpy, int screen, - int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, - int *ddxDriverPatchVersion, char **clientDriverName ); - -Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual, - XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); - -Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID, - XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); - -Bool XF86DRIDestroyContext( Display *dpy, int screen, - XID context_id ); - -Bool XF86DRICreateDrawable( Display *dpy, int screen, - Drawable drawable, drm_drawable_t *hHWDrawable ); - -Bool XF86DRIDestroyDrawable( Display *dpy, int screen, - Drawable drawable); - -Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable, - unsigned int *index, unsigned int *stamp, - int *X, int *Y, int *W, int *H, - int *numClipRects, drm_clip_rect_t ** pClipRects, - int *backX, int *backY, - int *numBackClipRects, drm_clip_rect_t **pBackClipRects ); - -Bool XF86DRIGetDeviceInfo( Display *dpy, int screen, - drm_handle_t *hFrameBuffer, int *fbOrigin, int *fbSize, - int *fbStride, int *devPrivateSize, void **pDevPrivate ); - -_XFUNCPROTOEND - -#endif /* _XF86DRI_SERVER_ */ - -#endif /* _XF86DRI_H_ */ - diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 7fa29d2f5f..5d11bde322 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -34,15 +34,16 @@ LIBS += -ldriclient -ldrm -lnv10 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate ############################################# -.PHONY = all clean +.PHONY = all clean libdriclient all: ${TARGET} -${TARGET}: ${OBJECTS} +${TARGET}: ${OBJECTS} libdriclient + $(CC) ${LDFLAGS} -shared -o $@ ${OBJECTS} ${LIBS} + +libdriclient: cd ${DRIDIR}/src; ${MAKE} - $(CC) ${LDFLAGS} -shared -o $@ $^ ${LIBS} clean: cd ${DRIDIR}/src; ${MAKE} clean rm -rf ${OBJECTS} ${TARGET} - diff --git a/src/libXvMC/Makefile b/src/libXvMC/Makefile index b72bb16efb..8565d271c7 100644 --- a/src/libXvMC/Makefile +++ b/src/libXvMC/Makefile @@ -38,27 +38,36 @@ endif ############################################# -.PHONY = all clean +ifeq (${DRIVER}, softpipe) +.PHONY = all clean g3dvl +else +.PHONY = all clean g3dvl nouveau_winsys +endif all: ${TARGET} ifeq (${DRIVER}, softpipe) -${TARGET}: ${OBJECTS} +${TARGET}: g3dvl + $(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ ${OBJECTS} ${LIBS} + +g3dvl: cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE} - $(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ $^ ${LIBS} clean: cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE} clean rm -rf ${OBJECTS} ${TARGET} else -${TARGET}: ${OBJECTS} +${TARGET}: ${OBJECTS} g3dvl nouveau_winsys + $(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ ${OBJECTS} ${LIBS} + +g3dvl: cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE} + +nouveau_winsys: cd ${GALLIUMDIR}/winsys/g3dvl/nouveau; ${MAKE} - $(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ $^ ${LIBS} clean: cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE} clean cd ${GALLIUMDIR}/winsys/g3dvl/nouveau; ${MAKE} clean rm -rf ${OBJECTS} ${TARGET} endif - -- cgit v1.2.3 From 59f23e92e24b93eb48f4e0552dd8e397aefd1714 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 12 Sep 2008 13:22:43 -0400 Subject: g3dvl: Update softlinks to nouveau winsys files, related fixes. --- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_context.c | 37 ++++---- src/gallium/winsys/g3dvl/nouveau/nouveau_device.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_local.h | 2 +- .../winsys/g3dvl/nouveau/nouveau_notifier.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c | 2 +- .../winsys/g3dvl/nouveau/nouveau_resource.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c | 13 ++- src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c | 2 +- .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 11 +-- .../winsys/g3dvl/nouveau/nouveau_winsys_pipe.h | 2 +- .../winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nv04_surface.c | 2 +- src/gallium/winsys/g3dvl/nouveau/nv50_surface.c | 2 +- src/gallium/winsys/g3dvl/xsp_winsys.c | 105 ++++++++++----------- src/libXvMC/Makefile | 2 +- 24 files changed, 101 insertions(+), 105 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 93839e8aa9..cfbad08038 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -6,10 +6,10 @@ #include #include #include -#include #include #include #include +#include #include "vl_render.h" #include "vl_shader_build.h" #include "vl_surface.h" diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c index 73ac4a4171..1005282dd4 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_bo.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_bo.c \ No newline at end of file +../../drm/nouveau/nouveau_bo.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c index 6c9b2c48d8..5af8202950 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_channel.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_channel.c \ No newline at end of file +../../drm/nouveau/nouveau_channel.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c index 5e173c7672..06a61fcda3 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_context.c @@ -1,7 +1,7 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "nouveau_context.h" #include "nouveau_dri.h" @@ -150,7 +150,7 @@ nouveau_context_create(dri_context_t *dri_context) 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 * + 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; @@ -280,7 +280,7 @@ nouveau_context_bind(struct nouveau_context *nv, dri_drawable_t *dri_drawable) { assert(nv); assert(dri_drawable); - + if (nv->dri_drawable != dri_drawable) { nv->dri_drawable = dri_drawable; @@ -294,9 +294,9 @@ int nouveau_context_unbind(struct nouveau_context *nv) { assert(nv); - + nv->dri_drawable = NULL; - + return 0; } @@ -306,20 +306,20 @@ int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) { struct nouveau_context *nv; dri_drawable_t *dri_drawable; - + nv = pipe->priv; - + driCreateDrawable(nv->nv_screen->dri_screen, drawable, &dri_drawable); - + nouveau_context_bind(nv, dri_drawable); - + return 0; } int unbind_pipe_drawable(struct pipe_context *pipe) { nouveau_context_unbind(pipe->priv); - + return 0; } @@ -329,15 +329,15 @@ struct pipe_context* create_pipe_context(Display *display, int screen) dri_framebuffer_t dri_framebuf; dri_context_t *dri_context; struct nouveau_context *nv; - + driCreateScreen(display, screen, &dri_screen, &dri_framebuf); driCreateContext(dri_screen, XDefaultVisual(display, screen), &dri_context); - + nouveau_screen_create(dri_screen, &dri_framebuf); nouveau_context_create(dri_context); - + nv = dri_context->private; - + return nv->nvc->pctx[nv->pctx_id]; } @@ -348,15 +348,15 @@ int destroy_pipe_context(struct pipe_context *pipe) struct nouveau_context *nv; dri_screen_t *dri_screen; dri_context_t *dri_context; - + assert(pipe); - + screen = pipe->screen; winsys = pipe->winsys; nv = pipe->priv; dri_context = nv->dri_context; dri_screen = dri_context->dri_screen; - + pipe->destroy(pipe); screen->destroy(screen); free(winsys); @@ -365,7 +365,6 @@ int destroy_pipe_context(struct pipe_context *pipe) nouveau_screen_destroy(dri_screen); driDestroyContext(dri_context); driDestroyScreen(dri_screen); - + return 0; } - diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c index 47d52dafa8..63f1fa040c 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_device.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_device.c \ No newline at end of file +../../drm/nouveau/nouveau_device.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c index 45078c964f..cd0d32e537 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_dma.c \ No newline at end of file +../../drm/nouveau/nouveau_dma.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h index 6b9ec77741..e6c7d4bc96 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dma.h @@ -1 +1 @@ -../../dri/nouveau/nouveau_dma.h \ No newline at end of file +../../drm/nouveau/nouveau_dma.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h index 0e6c9fce35..c8f9dbdc3a 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_dri.h @@ -1 +1 @@ -../../dri/nouveau/nouveau_dri.h \ No newline at end of file +../../drm/nouveau/nouveau_dri.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h index 473b7d4812..27082c9d34 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_drmif.h @@ -1 +1 @@ -../../dri/nouveau/nouveau_drmif.h \ No newline at end of file +../../drm/nouveau/nouveau_drmif.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c index ef1f0c6afe..51a50527e6 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_fence.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_fence.c \ No newline at end of file +../../drm/nouveau/nouveau_fence.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c index 428186544c..db17c72e6d 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_grobj.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_grobj.c \ No newline at end of file +../../drm/nouveau/nouveau_grobj.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h index 6b878aad22..4e9d3042cb 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_local.h @@ -1 +1 @@ -../../dri/nouveau/nouveau_local.h \ No newline at end of file +../../drm/nouveau/nouveau_local.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c index 3024a612a7..703bc3ce4a 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_notifier.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_notifier.c \ No newline at end of file +../../drm/nouveau/nouveau_notifier.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c index dae31d9799..4ac137cada 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_pushbuf.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_pushbuf.c \ No newline at end of file +../../drm/nouveau/nouveau_pushbuf.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c index e0d71e9d2b..2241af328f 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_resource.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_resource.c \ No newline at end of file +../../drm/nouveau/nouveau_resource.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c index daea3fff68..f80d00050c 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_screen.c @@ -1,5 +1,5 @@ #include "pipe/p_context.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "nouveau_context.h" #include #include "nouveau_dri.h" @@ -23,11 +23,11 @@ int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_versio static const dri_version_t ddx_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; static const dri_version_t dri_expected = {4, 0, 0}; static const dri_version_t drm_expected = {0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL}; - + assert(dri); assert(drm); assert(ddx); - + if (dri->major != dri_expected.major || dri->minor < dri_expected.minor) { NOUVEAU_ERR("Unexpected DRI version.\n"); @@ -43,17 +43,17 @@ int nouveau_check_dri_drm_ddx(dri_version_t *dri, dri_version_t *drm, dri_versio NOUVEAU_ERR("Unexpected DDX version.\n"); return 1; } - + return 0; } int nouveau_screen_create(dri_screen_t *dri_screen, dri_framebuffer_t *dri_framebuf) -{ +{ struct nouveau_dri *nv_dri = dri_framebuf->private; struct nouveau_screen *nv_screen; int ret; - + if (nouveau_check_dri_drm_ddx(&dri_screen->dri, &dri_screen->drm, &dri_screen->ddx)) return 1; @@ -89,4 +89,3 @@ nouveau_screen_destroy(dri_screen_t *dri_screen) FREE(nv_screen); } - diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c index 43de49b98b..ce4052d557 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_winsys.c \ No newline at end of file +../../drm/nouveau/nouveau_winsys.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c index b835bd5760..5d5380c250 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -1,7 +1,7 @@ #include "pipe/p_winsys.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_memory.h" #include "nouveau_context.h" #include "nouveau_local.h" @@ -29,7 +29,7 @@ static struct pipe_surface * nouveau_surface_alloc(struct pipe_winsys *ws) { struct pipe_surface *surf; - + surf = CALLOC_STRUCT(pipe_surface); if (!surf) return NULL; @@ -59,10 +59,10 @@ nouveau_surface_alloc_storage ) { const unsigned int ALIGNMENT = 256; - + assert(pws); assert(surface); - + surface->width = width; surface->height = height; surface->format = format; @@ -72,7 +72,7 @@ nouveau_surface_alloc_storage surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); surface->usage = flags; surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); - + return 0; } @@ -258,4 +258,3 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv) return &nvpws->pws; } - diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h index 264716fef0..9d9460883e 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.h @@ -1 +1 @@ -../../dri/nouveau/nouveau_winsys_pipe.h \ No newline at end of file +../../drm/nouveau/nouveau_winsys_pipe.h \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c index 83faccde96..ec613ecbf6 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_softpipe.c @@ -1 +1 @@ -../../dri/nouveau/nouveau_winsys_softpipe.c \ No newline at end of file +../../drm/nouveau/nouveau_winsys_softpipe.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c index e05f0671d6..4455d8f924 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c +++ b/src/gallium/winsys/g3dvl/nouveau/nv04_surface.c @@ -1 +1 @@ -../../dri/nouveau/nv04_surface.c \ No newline at end of file +../../drm/nouveau/nv04_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c index 3850748229..19f102001e 120000 --- a/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c +++ b/src/gallium/winsys/g3dvl/nouveau/nv50_surface.c @@ -1 +1 @@ -../../dri/nouveau/nv50_surface.c \ No newline at end of file +../../drm/nouveau/nv50_surface.c \ No newline at end of file diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index 0100fe37bd..42e7841df8 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -2,8 +2,8 @@ #include #include #include -#include #include +#include #include /* pipe_winsys implementation */ @@ -33,79 +33,79 @@ struct xsp_buffer 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; } @@ -127,10 +127,10 @@ static int xsp_surface_alloc_storage ) { const unsigned int ALIGNMENT = 1; - + assert(pws); assert(surface); - + surface->width = width; surface->height = height; surface->format = format; @@ -140,28 +140,28 @@ static int xsp_surface_alloc_storage surface->stride = round_up(surface->nblocksx * surface->block.size, ALIGNMENT); surface->usage = flags; surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->stride * surface->nblocksy); - + 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; } @@ -176,7 +176,7 @@ static int xsp_fence_signalled(struct pipe_winsys *pws, struct pipe_fence_handle { assert(pws); assert(fence); - + return 0; } @@ -184,30 +184,30 @@ static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *f { assert(pws); assert(fence); - + return 0; } static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private) -{ +{ struct xsp_pipe_winsys *xsp_winsys; struct xsp_context *xsp_context; - + assert(pws); assert(surface); assert(context_private); - + xsp_winsys = (struct xsp_pipe_winsys*)pws; xsp_context = (struct xsp_context*)context_private; - + if (!xsp_context->drawable_bound) return; - + 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_context->display, @@ -236,25 +236,25 @@ static const char* xsp_get_name(struct pipe_winsys *pws) int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable) { struct xsp_context *xsp_context; - + assert(pipe); - + xsp_context = pipe->priv; xsp_context->drawable = drawable; xsp_context->drawable_bound = 1; - + return 0; } int unbind_pipe_drawable(struct pipe_context *pipe) { struct xsp_context *xsp_context; - + assert(pipe); - + xsp_context = pipe->priv; xsp_context->drawable_bound = 0; - + return 0; } @@ -264,9 +264,9 @@ struct pipe_context* create_pipe_context(Display *display, int screen) struct xsp_context *xsp_context; struct pipe_screen *sp_screen; struct pipe_context *sp_pipe; - + 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; @@ -281,7 +281,7 @@ struct pipe_context* create_pipe_context(Display *display, int screen) xsp_winsys->base.fence_finish = xsp_fence_finish; xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer; xsp_winsys->base.get_name = xsp_get_name; - + { /* XXX: Can't use the returned XImage* directly, since we don't have control over winsys destruction @@ -299,22 +299,22 @@ struct pipe_context* create_pipe_context(Display *display, int screen) 32, 0 ); - + memcpy(&xsp_winsys->fbimage, template, sizeof(XImage)); XInitImage(&xsp_winsys->fbimage); - + XDestroyImage(template); } - + sp_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys); sp_pipe = softpipe_create(sp_screen, (struct pipe_winsys*)xsp_winsys, NULL); - + xsp_context = calloc(1, sizeof(struct xsp_context)); xsp_context->display = display; xsp_context->screen = screen; - + sp_pipe->priv = xsp_context; - + return sp_pipe; } @@ -322,16 +322,15 @@ int destroy_pipe_context(struct pipe_context *pipe) { struct pipe_screen *screen; struct pipe_winsys *winsys; - + assert(pipe); - + screen = pipe->screen; winsys = pipe->winsys; free(pipe->priv); pipe->destroy(pipe); screen->destroy(screen); free(winsys); - + return 0; } - diff --git a/src/libXvMC/Makefile b/src/libXvMC/Makefile index 8565d271c7..4de26e9620 100644 --- a/src/libXvMC/Makefile +++ b/src/libXvMC/Makefile @@ -47,7 +47,7 @@ endif all: ${TARGET} ifeq (${DRIVER}, softpipe) -${TARGET}: g3dvl +${TARGET}: ${OBJECTS} g3dvl $(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ ${OBJECTS} ${LIBS} g3dvl: -- cgit v1.2.3 From 42a42dec3dbb5e150584b3d0b2e14e9b555a4ac1 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Tue, 9 Sep 2008 02:27:05 -0400 Subject: g3dvl: Fullscreen fixes. Respect src & dst coords during scaling, clear FB. --- src/gallium/state_trackers/g3dvl/vl_basic_csc.c | 83 ++++++++++++++----------- src/gallium/state_trackers/g3dvl/vl_surface.c | 4 +- src/gallium/state_trackers/g3dvl/vl_surface.h | 2 + src/libXvMC/surface.c | 2 +- 4 files changed, 54 insertions(+), 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c index ea003a31d1..9f9dafc8a9 100644 --- a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c +++ b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c @@ -14,6 +14,8 @@ struct vlVertexShaderConsts { + struct vlVertex4f dst_scale; + struct vlVertex4f dst_trans; struct vlVertex4f src_scale; struct vlVertex4f src_trans; }; @@ -87,6 +89,9 @@ static int vlResizeFrameBuffer 0 ); + /* Clear to black, in case video doesn't fill the entire window */ + pipe->clear(pipe, basic_csc->framebuffer.cbufs[0], 0); + return 0; } @@ -149,6 +154,15 @@ static int vlPutPictureCSC PIPE_BUFFER_USAGE_CPU_WRITE ); + vs_consts->dst_scale.x = destw / (float)basic_csc->framebuffer.cbufs[0]->width; + vs_consts->dst_scale.y = desth / (float)basic_csc->framebuffer.cbufs[0]->height; + vs_consts->dst_scale.z = 1; + vs_consts->dst_scale.w = 1; + vs_consts->dst_trans.x = destx / (float)basic_csc->framebuffer.cbufs[0]->width; + vs_consts->dst_trans.y = desty / (float)basic_csc->framebuffer.cbufs[0]->height; + vs_consts->dst_trans.z = 0; + vs_consts->dst_trans.w = 0; + vs_consts->src_scale.x = srcw / (float)surface->texture->width[0]; vs_consts->src_scale.y = srch / (float)surface->texture->height[0]; vs_consts->src_scale.z = 1; @@ -376,10 +390,12 @@ static int vlCreateVertexShader } /* - * decl c0 ; Scaling vector to scale texcoord rect to source size - * decl c1 ; Translation vector to move texcoord rect into position + * decl c0 ; Scaling vector to scale vertex pos rect to destination size + * decl c1 ; Translation vector to move vertex pos rect into position + * decl c2 ; Scaling vector to scale texcoord rect to source size + * decl c3 ; Translation vector to move texcoord rect into position */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 3); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* @@ -392,21 +408,19 @@ static int vlCreateVertexShader ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } - /* decl t0 */ - decl = vl_decl_temps(0, 0); + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - /* mov o0, i0 ; Move pos in to pos out */ - inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, 0, TGSI_FILE_INPUT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* mul t0, i1, c0 ; Scale unit texcoord rect to source size */ - inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 1, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - - /* add o1, t0, c1 ; Translate texcoord rect into position */ - inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 1, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 1); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + /* + * madd o0, i0, c0, c1 ; Scale and translate unit output rect to destination size and pos + * madd o1, i1, c2, c3 ; Scale and translate unit texcoord rect to source size and pos + */ + for (i = 0; i < 2; ++i) + { + inst = vl_inst4(TGSI_OPCODE_MADD, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i, TGSI_FILE_CONSTANT, i * 2, TGSI_FILE_CONSTANT, i * 2 + 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } /* end */ inst = vl_end(); @@ -487,9 +501,8 @@ static int vlCreateFragmentShader * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix * dp4 o0.y, t0, c2 * dp4 o0.z, t0, c3 - * dp4 o0.w, t0, c4 ; XXX: Don't need 4th coefficient */ - for (i = 0; i < 4; ++i) + for (i = 0; i < 3; ++i) { inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1); inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; @@ -519,11 +532,11 @@ static int vlCreateDataBufs pipe = csc->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 - */ + * 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 + */ csc->vertex_bufs[0].pitch = sizeof(struct vlVertex2f); csc->vertex_bufs[0].max_index = 3; csc->vertex_bufs[0].buffer_offset = 0; @@ -550,9 +563,9 @@ static int vlCreateDataBufs csc->vertex_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 - */ + * Create our texcoord buffer and texcoord buffer element + * Texcoord buffer contains the TCs for mapping the rendered surface to the 4 vertices + */ csc->vertex_bufs[1].pitch = sizeof(struct vlVertex2f); csc->vertex_bufs[1].max_index = 3; csc->vertex_bufs[1].buffer_offset = 0; @@ -579,9 +592,9 @@ static int vlCreateDataBufs csc->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; /* - Create our vertex shader's constant buffer - Const buffer contains scaling and translation vectors - */ + * Create our vertex shader's constant buffer + * Const buffer contains scaling and translation vectors + */ csc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts); csc->vs_const_buf.buffer = pipe->winsys->buffer_create ( @@ -592,9 +605,9 @@ static int vlCreateDataBufs ); /* - Create our fragment shader's constant buffer - Const buffer contains the color conversion matrix and bias vectors - */ + * Create our fragment shader's constant buffer + * Const buffer contains the color conversion matrix and bias vectors + */ csc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts); csc->fs_const_buf.buffer = pipe->winsys->buffer_create ( @@ -605,9 +618,9 @@ static int vlCreateDataBufs ); /* - TODO: Refactor this into a seperate function, - allow changing the CSC matrix at runtime to switch between regular & full versions - */ + * 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, csc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 687fd1ec29..07a9be2a99 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -104,6 +104,8 @@ int vlPutPicture int desty, int destw, int desth, + int drawable_w, + int drawable_h, enum vlPictureType picture_type ) { @@ -118,7 +120,7 @@ int vlPutPicture csc = surface->context->csc; pipe = surface->context->pipe; - csc->vlResizeFrameBuffer(csc, destw, desth); + csc->vlResizeFrameBuffer(csc, drawable_w, drawable_h); csc->vlBegin(csc); diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.h b/src/gallium/state_trackers/g3dvl/vl_surface.h index b975e131fa..3e05050345 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.h +++ b/src/gallium/state_trackers/g3dvl/vl_surface.h @@ -49,6 +49,8 @@ int vlPutPicture int desty, int destw, int desth, + int drawable_w, + int drawable_h, enum vlPictureType picture_type ); diff --git a/src/libXvMC/surface.c b/src/libXvMC/surface.c index 038befc297..b8459c03cf 100644 --- a/src/libXvMC/surface.c +++ b/src/libXvMC/surface.c @@ -266,7 +266,7 @@ Status XvMCPutSurface vl_sfc = surface->privData; - vlPutPicture(vl_sfc, drawable, srcx, srcy, srcw, srch, destx, desty, destw, desth, PictureToVL(flags)); + vlPutPicture(vl_sfc, drawable, srcx, srcy, srcw, srch, destx, desty, destw, desth, width, height, PictureToVL(flags)); return Success; } -- cgit v1.2.3 From f3f449a49136ae2fd2dc3cf62d2c24dd42505e7d Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Wed, 10 Sep 2008 19:37:56 -0400 Subject: g3dvl: Implement surface sync functions. --- .../state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 20 ++++---- src/gallium/state_trackers/g3dvl/vl_surface.c | 59 +++++++++++++++++++++- src/gallium/state_trackers/g3dvl/vl_surface.h | 30 ++++++++--- src/gallium/state_trackers/g3dvl/vl_types.h | 7 +++ src/libXvMC/surface.c | 31 ++++++++++-- 5 files changed, 123 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index cfbad08038..75d326b36e 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -591,6 +591,10 @@ static int vlFlush assert(render); mc = (struct vlR16SnormBufferedMC*)render; + + if (!mc->buffered_surface) + return 0; + pipe = mc->pipe; for (i = 0; i < mc->num_macroblocks; ++i) @@ -736,8 +740,12 @@ static int vlFlush vb_start += num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24; } + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &mc->buffered_surface->render_fence); + for (i = 0; i < 3; ++i) mc->zero_block[i].x = -1.0f; + + mc->buffered_surface = NULL; mc->num_macroblocks = 0; mc->cur_buf++; @@ -760,12 +768,7 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered if (mc->buffered_surface) { - if - ( - mc->buffered_surface != surface /*|| - mc->past_surface != batch->past_surface || - mc->future_surface != batch->future_surface*/ - ) + if (mc->buffered_surface != surface) { vlFlush(&mc->base); mc->buffered_surface = surface; @@ -1027,7 +1030,6 @@ static int vlCreateFragmentShaderIMB inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } /* mul o0, t0, c0 ; Rescale texel to correct range */ @@ -1323,7 +1325,6 @@ static int vlCreateFragmentShaderFramePMB inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } /* mul t0, t0, c0 ; Rescale texel to correct range */ @@ -1442,7 +1443,6 @@ static int vlCreateFragmentShaderFieldPMB inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } /* mul t0, t0, c0 ; Rescale texel to correct range */ @@ -1818,7 +1818,6 @@ static int vlCreateFragmentShaderFrameBMB inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } /* mul t0, t0, c0 ; Rescale texel to correct range */ @@ -1955,7 +1954,6 @@ static int vlCreateFragmentShaderFieldBMB inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - } /* mul t0, t0, c0 ; Rescale texel to correct range */ diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 07a9be2a99..6648133ef8 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -77,6 +77,7 @@ int vlRenderMacroBlocksMpeg2 { assert(batch); assert(surface); + assert(surface->context); surface->context->render->vlBegin(surface->context->render); @@ -141,9 +142,10 @@ int vlPutPicture csc->vlEnd(csc); - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &surface->disp_fence); + bind_pipe_drawable(pipe, drawable); - /* TODO: Need to take destx, desty into consideration */ + pipe->winsys->flush_frontbuffer ( pipe->winsys, @@ -154,6 +156,59 @@ int vlPutPicture return 0; } +int vlSurfaceGetStatus +( + struct vlSurface *surface, + enum vlResourceStatus *status +) +{ + assert(surface); + assert(surface->context); + assert(status); + + if (surface->render_fence && !surface->context->pipe->winsys->fence_signalled(surface->context->pipe->winsys, surface->render_fence, 0)) + { + *status = vlResourceStatusRendering; + return 0; + } + + if (surface->disp_fence && !surface->context->pipe->winsys->fence_signalled(surface->context->pipe->winsys, surface->disp_fence, 0)) + { + *status = vlResourceStatusDisplaying; + return 0; + } + + *status = vlResourceStatusFree; + return 0; +} + +int vlSurfaceFlush +( + struct vlSurface *surface +) +{ + assert(surface); + assert(surface->context); + + surface->context->render->vlFlush(surface->context->render); + + return 0; +} + +int vlSurfaceSync +( + struct vlSurface *surface +) +{ + assert(surface); + assert(surface->context); + assert(surface->render_fence); + + surface->context->pipe->winsys->fence_finish(surface->context->pipe->winsys, surface->render_fence, 0); + + return 0; +} + struct vlScreen* vlSurfaceGetScreen ( struct vlSurface *surface diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.h b/src/gallium/state_trackers/g3dvl/vl_surface.h index 3e05050345..133e1515ef 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.h +++ b/src/gallium/state_trackers/g3dvl/vl_surface.h @@ -8,12 +8,14 @@ struct pipe_texture; struct vlSurface { - struct vlScreen *screen; - struct vlContext *context; - unsigned int width; - unsigned int height; - enum vlFormat format; - struct pipe_texture *texture; + struct vlScreen *screen; + struct vlContext *context; + unsigned int width; + unsigned int height; + enum vlFormat format; + struct pipe_texture *texture; + struct pipe_fence_handle *render_fence; + struct pipe_fence_handle *disp_fence; }; #endif @@ -54,6 +56,22 @@ int vlPutPicture enum vlPictureType picture_type ); +int vlSurfaceGetStatus +( + struct vlSurface *surface, + enum vlResourceStatus *status +); + +int vlSurfaceFlush +( + struct vlSurface *surface +); + +int vlSurfaceSync +( + struct vlSurface *surface +); + struct vlScreen* vlSurfaceGetScreen ( struct vlSurface *surface diff --git a/src/gallium/state_trackers/g3dvl/vl_types.h b/src/gallium/state_trackers/g3dvl/vl_types.h index b432bfde93..274e1f7437 100644 --- a/src/gallium/state_trackers/g3dvl/vl_types.h +++ b/src/gallium/state_trackers/g3dvl/vl_types.h @@ -13,6 +13,13 @@ struct vlScreen; struct vlContext; struct vlSurface; +enum vlResourceStatus +{ + vlResourceStatusFree, + vlResourceStatusRendering, + vlResourceStatusDisplaying +}; + enum vlProfile { vlProfileMpeg2Simple, diff --git a/src/libXvMC/surface.c b/src/libXvMC/surface.c index b8459c03cf..a920da52f9 100644 --- a/src/libXvMC/surface.c +++ b/src/libXvMC/surface.c @@ -201,7 +201,7 @@ Status XvMCFlushSurface(Display *display, XvMCSurface *surface) assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc)))); - /* TODO */ + vlSurfaceFlush(vl_sfc); return Success; } @@ -219,7 +219,7 @@ Status XvMCSyncSurface(Display *display, XvMCSurface *surface) assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc)))); - /* TODO */ + vlSurfaceSync(vl_sfc); return Success; } @@ -273,7 +273,8 @@ Status XvMCPutSurface Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *status) { - struct vlSurface *vl_sfc; + struct vlSurface *vl_sfc; + enum vlResourceStatus res_status; assert(display); @@ -286,8 +287,28 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *status) assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc)))); - /* TODO */ - *status = 0; + vlSurfaceGetStatus(vl_sfc, &res_status); + + switch (res_status) + { + case vlResourceStatusFree: + { + *status = 0; + break; + } + case vlResourceStatusRendering: + { + *status = XVMC_RENDERING; + break; + } + case vlResourceStatusDisplaying: + { + *status = XVMC_DISPLAYING; + break; + } + default: + assert(0); + } return Success; } -- cgit v1.2.3 From 56c22687e139e8fede6f7ea4d524699364dda07c Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 12 Sep 2008 15:10:43 -0400 Subject: g3dvl: Use winsys_buffer_reference() instead of pipe_buffer_reference(). Old pipe_buffer_reference() renamed winsys_buffer_reference(), new pipe_buffer_reference() expects a screen. --- src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c | 2 +- src/gallium/winsys/g3dvl/xsp_winsys.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c index 5d5380c250..4f6ac9cad0 100644 --- a/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/g3dvl/nouveau/nouveau_winsys_pipe.c @@ -84,7 +84,7 @@ nouveau_surface_release(struct pipe_winsys *ws, struct pipe_surface **s) *s = NULL; if (--surf->refcount <= 0) { if (surf->buffer) - pipe_buffer_reference(ws, &surf->buffer, NULL); + winsys_buffer_reference(ws, &surf->buffer, NULL); free(surf); } } diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index 42e7841df8..68be2c2ea3 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -158,7 +158,7 @@ static void xsp_surface_release(struct pipe_winsys *pws, struct pipe_surface **s if (s->refcount == 0) { - pipe_buffer_reference(pws, &s->buffer, NULL); + winsys_buffer_reference(pws, &s->buffer, NULL); free(s); } -- cgit v1.2.3 From 3122f2bebe8d76568916b8cddff542f52466055e Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 13 Sep 2008 01:35:14 -0400 Subject: g3dvl: Fix field coded block copy. --- src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 18 ++++-------------- src/libXvMC/surface.c | 8 ++++---- 2 files changed, 8 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 75d326b36e..888f0040bf 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -108,17 +108,7 @@ static inline int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst { unsigned int y; - for (y = 0; y < VL_BLOCK_HEIGHT / 2; ++y) - memcpy - ( - dst + y * dst_pitch * 2, - src + y * VL_BLOCK_WIDTH, - VL_BLOCK_WIDTH * 2 - ); - - dst += VL_BLOCK_HEIGHT * dst_pitch; - - for (; y < VL_BLOCK_HEIGHT; ++y) + for (y = 0; y < VL_BLOCK_HEIGHT; ++y) memcpy ( dst + y * dst_pitch * 2, @@ -1181,7 +1171,7 @@ static int vlCreateVertexShaderFieldPMB ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } - /* decl c0 ; Texcoord denorm coefficients */ + /* decl c0 ; Render target dimensions */ decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -1661,8 +1651,8 @@ static int vlCreateVertexShaderFieldBMB ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } - /* decl c0 ; Denorm coefficients */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 6); + /* decl c0 ; Render target dimensions */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* diff --git a/src/libXvMC/surface.c b/src/libXvMC/surface.c index a920da52f9..6031b39d10 100644 --- a/src/libXvMC/surface.c +++ b/src/libXvMC/surface.c @@ -40,12 +40,12 @@ static enum vlPictureType PictureToVL(int xvmc_pic) return -1; } -static enum vlMotionType MotionToVL(int xvmc_motion_type) +static enum vlMotionType MotionToVL(int xvmc_motion_type, int xvmc_dct_type) { switch (xvmc_motion_type) { case XVMC_PREDICTION_FRAME: - return vlMotionTypeFrame; + return xvmc_dct_type == XVMC_DCT_TYPE_FIELD ? vlMotionType16x8 : vlMotionTypeFrame; case XVMC_PREDICTION_FIELD: return vlMotionTypeField; case XVMC_PREDICTION_DUAL_PRIME: @@ -171,8 +171,8 @@ Status XvMCRenderSurface batch.macroblocks[i].mby = macroblocks->macro_blocks[j].y; batch.macroblocks[i].mb_type = TypeToVL(macroblocks->macro_blocks[j].macroblock_type); if (batch.macroblocks[i].mb_type != vlMacroBlockTypeIntra) - batch.macroblocks[i].mo_type = MotionToVL(macroblocks->macro_blocks[j].motion_type); - batch.macroblocks[i].dct_type = macroblocks->macro_blocks[j].dct_type & XVMC_DCT_TYPE_FIELD ? vlDCTTypeFieldCoded : vlDCTTypeFrameCoded; + batch.macroblocks[i].mo_type = MotionToVL(macroblocks->macro_blocks[j].motion_type, macroblocks->macro_blocks[j].dct_type); + batch.macroblocks[i].dct_type = macroblocks->macro_blocks[j].dct_type == XVMC_DCT_TYPE_FIELD ? vlDCTTypeFieldCoded : vlDCTTypeFrameCoded; for (k = 0; k < 2; ++k) for (l = 0; l < 2; ++l) -- cgit v1.2.3 From 562b31195cc8140d3bd0ad7ed8532200e9df520a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 18 Sep 2008 13:15:55 +1000 Subject: nv50: hack surface alloc a bit for now --- src/gallium/drivers/nv50/nv50_miptree.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index b0e8fe2f0b..28a8bdc0fa 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -48,6 +48,8 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) } pitch = ((pt->width[0] + 63) & ~63) * pt->block.size; + /*XXX*/ + pitch *= 2; mt->buffer = ws->buffer_create(ws, 256, usage, pitch * pt->height[0]); if (!mt->buffer) { -- cgit v1.2.3 From ed0c308f39f7d7a5cb05571e37440469eacbd624 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 18 Sep 2008 13:39:52 +1000 Subject: nv50: use 3D engine clears, 2D engine doesn't understand zeta formats --- src/gallium/drivers/nv50/nv50_clear.c | 57 ++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c index fbc6cd09ce..a31a42d6b5 100644 --- a/src/gallium/drivers/nv50/nv50_clear.c +++ b/src/gallium/drivers/nv50/nv50_clear.c @@ -30,6 +30,61 @@ 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); + struct nv50_context *nv50 = nv50_context(pipe); + struct pipe_framebuffer_state fb, s_fb = nv50->framebuffer; + struct pipe_scissor_state sc, s_sc = nv50->scissor; + unsigned dirty = nv50->dirty; + + nv50->dirty = 0; + + if (ps->format == PIPE_FORMAT_Z24S8_UNORM || + ps->format == PIPE_FORMAT_Z16_UNORM) { + fb.num_cbufs = 0; + fb.zsbuf = ps; + } else { + fb.num_cbufs = 1; + fb.cbufs[0] = ps; + fb.zsbuf = NULL; + } + fb.width = ps->width; + fb.height = ps->height; + pipe->set_framebuffer_state(pipe, &fb); + + sc.minx = sc.miny = 0; + sc.maxx = fb.width; + sc.maxy = fb.height; + pipe->set_scissor_state(pipe, &sc); + + nv50_state_validate(nv50); + + switch (ps->format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + BEGIN_RING(tesla, 0x0d80, 4); + OUT_RINGf (ubyte_to_float((clearValue >> 16) & 0xff)); + OUT_RINGf (ubyte_to_float((clearValue >> 8) & 0xff)); + OUT_RINGf (ubyte_to_float((clearValue >> 0) & 0xff)); + OUT_RINGf (ubyte_to_float((clearValue >> 24) & 0xff)); + BEGIN_RING(tesla, 0x19d0, 1); + OUT_RING (0x3c); + break; + case PIPE_FORMAT_Z24S8_UNORM: + BEGIN_RING(tesla, 0x0d90, 1); + OUT_RINGf ((float)(clearValue >> 8) * (1.0 / 16777215.0)); + BEGIN_RING(tesla, 0x0da0, 1); + OUT_RING (clearValue & 0xff); + BEGIN_RING(tesla, 0x19d0, 1); + OUT_RING (0x03); + break; + default: + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, + clearValue); + break; + } + + pipe->set_framebuffer_state(pipe, &s_fb); + pipe->set_scissor_state(pipe, &s_sc); + nv50->dirty |= dirty; + ps->status = PIPE_SURFACE_STATUS_CLEAR; } + -- cgit v1.2.3 From 70071484d95bed8c2c932d1c79e20230bcdbc1dc Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 21 Sep 2008 14:02:30 +0200 Subject: nouveau: add flag for swizzled surface upload --- src/gallium/drivers/nouveau/nouveau_bo.h | 1 + src/gallium/drivers/nv30/nv30_fragtex.c | 34 ++++++++++++++++++-------------- 2 files changed, 20 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/nouveau_bo.h b/src/gallium/drivers/nouveau/nouveau_bo.h index 65b138283c..0ed3367815 100644 --- a/src/gallium/drivers/nouveau/nouveau_bo.h +++ b/src/gallium/drivers/nouveau/nouveau_bo.h @@ -37,6 +37,7 @@ #define NOUVEAU_BO_LOCAL (1 << 9) #define NOUVEAU_BO_TILED (1 << 10) #define NOUVEAU_BO_ZTILE (1 << 11) +#define NOUVEAU_BO_SWIZZLED (1 << 12) #define NOUVEAU_BO_DUMMY (1 << 31) struct nouveau_bo { diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index 91246f5ca0..9e6f746a42 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -26,7 +26,7 @@ static INLINE int log2i(int i) return r; } -#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \ +#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,swsurf) \ { \ TRUE, \ PIPE_FORMAT_##m, \ @@ -35,6 +35,7 @@ static INLINE int log2i(int i) 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), \ + swsurf \ } struct nv30_texture_format { @@ -42,24 +43,25 @@ struct nv30_texture_format { uint pipe; int format; int swizzle; + int swizzled_surface; }; 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), - _(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), + _(A8R8G8B8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W, 1), + _(A1R5G5B5_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W, 1), + _(A4R4G4B4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W, 1), + _(R5G6B5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W, 1), + _(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X, 1), + _(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X, 1), + _(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X, 1), + _(A8L8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y, 1), +// _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X, 0), +// _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X, 0), + _(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W, 0), + _(DXT1_RGBA , DXT1 , S1, S1, S1, S1, X, Y, Z, W, 0), + _(DXT3_RGBA , DXT3 , S1, S1, S1, S1, X, Y, Z, W, 0), + _(DXT5_RGBA , DXT5 , S1, S1, S1, S1, X, Y, Z, W, 0), {}, }; @@ -96,6 +98,8 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) if (!tf) assert(0); + tex_flags |= (tf->swizzled_surface ? NOUVEAU_BO_SWIZZLED : 0); + txf = tf->format; txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0); txf |= log2i(pt->width[0]) << 20; -- cgit v1.2.3 From da85a94d99cfbd8f094a475fb2272efb4e87b9a9 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 21 Sep 2008 14:12:04 +0200 Subject: nouveau: init scaled_image_from_memory object for swizzled surface upload --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index 8fa3d106c8..36c913a732 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -298,6 +298,22 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) } BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + OUT_RING (chan, nvc->channel->vram->handle); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); + OUT_RING (chan, nvc->NvSwzSurf); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_PATTERN, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_ROP, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_BETA1, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_BETA4, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); return 0; } -- cgit v1.2.3 From 2882a2db7a766c60bb231978ea829632438dd8a4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Sep 2008 12:06:56 +1000 Subject: nouveau: some small API changes --- src/gallium/winsys/drm/nouveau/nouveau_screen.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/drm/nouveau/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/nouveau_screen.c index 9489645151..c6d0c53588 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_screen.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_screen.c @@ -114,7 +114,7 @@ nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv) struct nouveau_framebuffer *nvfb; nvfb = (struct nouveau_framebuffer *)driDrawPriv->driverPrivate; - st_unreference_framebuffer(&nvfb->stfb); + st_unreference_framebuffer(nvfb->stfb); free(nvfb); } @@ -133,8 +133,9 @@ nouveau_fill_in_modes(__DRIscreenPrivate *psp, GLX_NONE, GLX_SWAP_UNDEFINED_OML, }; - u_int8_t depth_bits_array[3]; - u_int8_t stencil_bits_array[3]; + uint8_t depth_bits_array[3]; + uint8_t stencil_bits_array[3]; + uint8_t msaa_samples_array[1]; depth_bits_array[0] = 0; depth_bits_array[1] = depth_bits; @@ -148,9 +149,10 @@ nouveau_fill_in_modes(__DRIscreenPrivate *psp, stencil_bits_array[1] = 0; if (depth_bits == 24) stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + msaa_samples_array[0] = 0; + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; back_buffer_factor = (have_back_buffer) ? 3 : 1; @@ -167,7 +169,7 @@ nouveau_fill_in_modes(__DRIscreenPrivate *psp, configs = driCreateConfigs(fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor); + back_buffer_factor, msaa_samples_array, 1); if (configs == NULL) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); -- cgit v1.2.3 From 111b8f6dd9c97cd30979c8d5f56244e1e6ed60a2 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 22 Sep 2008 12:13:23 -0400 Subject: g3dvl: Bad semantic index in shader decl. --- src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 888f0040bf..62107803ac 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -974,7 +974,7 @@ static int vlCreateFragmentShaderIMB */ for (i = 0; i < 3; ++i) { - decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, i, i, TGSI_INTERPOLATE_LINEAR); + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -1186,7 +1186,7 @@ static int vlCreateVertexShaderFieldPMB */ for (i = 0; i < 7; i++) { - decl = vl_decl_output((i == 0 || i == 6) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -1668,7 +1668,7 @@ static int vlCreateVertexShaderFieldBMB */ for (i = 0; i < 9; i++) { - decl = vl_decl_output((i == 0 || i == 8) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } -- cgit v1.2.3 From d008fb178631aecacc07aeec66299748470fd8c7 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 22 Sep 2008 12:26:13 -0400 Subject: g3dvl: Ignore client flush requests unless entire frame is buffered. --- src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c | 10 ++++++++++ src/gallium/state_trackers/g3dvl/vl_surface.c | 1 + 2 files changed, 11 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c index 62107803ac..e7a070ef4d 100644 --- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c +++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c @@ -576,6 +576,9 @@ static int vlFlush unsigned int num_macroblocks[vlNumMacroBlockExTypes] = {0}; unsigned int offset[vlNumMacroBlockExTypes]; unsigned int vb_start = 0; + unsigned int mbw; + unsigned int mbh; + unsigned int num_mb_per_frame; unsigned int i; assert(render); @@ -585,6 +588,13 @@ static int vlFlush if (!mc->buffered_surface) return 0; + mbw = align(mc->picture_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH; + mbh = align(mc->picture_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT; + num_mb_per_frame = mbw * mbh; + + if (mc->num_macroblocks < num_mb_per_frame) + return 0; + pipe = mc->pipe; for (i = 0; i < mc->num_macroblocks; ++i) diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c index 6648133ef8..076bd40d41 100644 --- a/src/gallium/state_trackers/g3dvl/vl_surface.c +++ b/src/gallium/state_trackers/g3dvl/vl_surface.c @@ -179,6 +179,7 @@ int vlSurfaceGetStatus } *status = vlResourceStatusFree; + return 0; } -- cgit v1.2.3 From af59f767a03da4dd434a6d655e3d0bc05feb298a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 7 Oct 2008 21:47:45 +0200 Subject: nouveau: first draft of swizzle texture upload to vram --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 83 +++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index 36c913a732..5bf89e1952 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -3,6 +3,32 @@ #include "nouveau_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; +} + static INLINE int nv04_surface_format(enum pipe_format format) { @@ -81,6 +107,56 @@ nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy, OUT_RING (chan, ( h << 16) | w); } +static int +nv04_surface_copy_prep_swizzled(struct nouveau_context *nv, + struct pipe_surface *dst, + struct pipe_surface *src) +{ + struct nouveau_channel *chan = nv->nvc->channel; + + BEGIN_RING(chan, nv->nvc->NvSwzSurf, + NV04_SWIZZLED_SURFACE_FORMAT, 2); + /* FIXME: read destination format from somewhere */ + OUT_RING (chan, + NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8 + | (log2i(dst->width)<height)<buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 13); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + /* FIXME: read source format from somewhere */ + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING (chan, 0); + OUT_RING (chan, (src->height<<16) | src->width); + OUT_RING (chan, 0); + OUT_RING (chan, (src->height<<16) | src->width); + OUT_RING (chan, 1<<20); + OUT_RING (chan, 1<<20); + OUT_RING (chan, (src->height<<16) | src->width); + OUT_RING (chan, + src->stride + | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER + | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RING (chan, 0); + + BEGIN_RING(chan, 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; +} + static int nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, struct pipe_surface *src) @@ -91,6 +167,13 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, if (src->format != dst->format) return 1; + /* Setup transfer to swizzle the texture to vram if needed */ + /* FIXME/TODO: check proper limits of this operation */ + if (nouveau_buffer(dst->buffer)->bo->flags & NOUVEAU_BO_SWIZZLED) { + /* FIXME: Disable it for the moment */ + /*return nv04_surface_copy_prep_swizzled(nv, dst, src);*/ + } + /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback * to NV_MEMORY_TO_MEMORY_FORMAT in this case. */ -- cgit v1.2.3 From 3354e668f0d4eb7ad1d92607031c1fc2e785e8d1 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 17 Oct 2008 17:20:03 -0400 Subject: g3dvl: Get rid of state tracker unit tests, stale and not useful atm. --- src/gallium/state_trackers/g3dvl/tests/.gitignore | 6 - src/gallium/state_trackers/g3dvl/tests/Makefile | 45 ---- .../state_trackers/g3dvl/tests/test_b_rendering.c | 226 --------------------- .../state_trackers/g3dvl/tests/test_context.c | 22 -- .../state_trackers/g3dvl/tests/test_i_rendering.c | 137 ------------- .../state_trackers/g3dvl/tests/test_p_rendering.c | 214 ------------------- .../state_trackers/g3dvl/tests/test_pf_rendering.c | 214 ------------------- .../state_trackers/g3dvl/tests/test_surface.c | 26 --- 8 files changed, 890 deletions(-) delete mode 100644 src/gallium/state_trackers/g3dvl/tests/.gitignore delete mode 100644 src/gallium/state_trackers/g3dvl/tests/Makefile delete mode 100644 src/gallium/state_trackers/g3dvl/tests/test_b_rendering.c delete mode 100644 src/gallium/state_trackers/g3dvl/tests/test_context.c delete mode 100644 src/gallium/state_trackers/g3dvl/tests/test_i_rendering.c delete mode 100644 src/gallium/state_trackers/g3dvl/tests/test_p_rendering.c delete mode 100644 src/gallium/state_trackers/g3dvl/tests/test_pf_rendering.c delete mode 100644 src/gallium/state_trackers/g3dvl/tests/test_surface.c (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/g3dvl/tests/.gitignore b/src/gallium/state_trackers/g3dvl/tests/.gitignore deleted file mode 100644 index 9b1ec4e212..0000000000 --- a/src/gallium/state_trackers/g3dvl/tests/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -test_context -test_surface -test_i_rendering -test_p_rendering -test_pf_rendering -test_b_rendering diff --git a/src/gallium/state_trackers/g3dvl/tests/Makefile b/src/gallium/state_trackers/g3dvl/tests/Makefile deleted file mode 100644 index 45cefa2e57..0000000000 --- a/src/gallium/state_trackers/g3dvl/tests/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -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_pf_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_pf_rendering: test_pf_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_pf_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 deleted file mode 100644 index b78cc851ae..0000000000 --- a/src/gallium/state_trackers/g3dvl/tests/test_b_rendering.c +++ /dev/null @@ -1,226 +0,0 @@ -#include -#include -#include -#include -#include - -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 deleted file mode 100644 index 2002977ee2..0000000000 --- a/src/gallium/state_trackers/g3dvl/tests/test_context.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include - -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 deleted file mode 100644 index 1f96471130..0000000000 --- a/src/gallium/state_trackers/g3dvl/tests/test_i_rendering.c +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include -#include -#include -#include - -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 deleted file mode 100644 index 2203349784..0000000000 --- a/src/gallium/state_trackers/g3dvl/tests/test_p_rendering.c +++ /dev/null @@ -1,214 +0,0 @@ -#include -#include -#include -#include -#include - -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_pf_rendering.c b/src/gallium/state_trackers/g3dvl/tests/test_pf_rendering.c deleted file mode 100644 index 43586fc553..0000000000 --- a/src/gallium/state_trackers/g3dvl/tests/test_pf_rendering.c +++ /dev/null @@ -1,214 +0,0 @@ -#include -#include -#include -#include -#include - -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] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 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}, {32, 32} - }; - - 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_FIELD_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 deleted file mode 100644 index 4d1946396a..0000000000 --- a/src/gallium/state_trackers/g3dvl/tests/test_surface.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include - -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; -} - -- cgit v1.2.3 From 92674bc8889e10e580c630cf85c106fa6eb34d7b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 29 Oct 2008 18:12:48 +1100 Subject: nv40: rename some vars in texture layout code --- src/gallium/drivers/nv40/nv40_miptree.c | 52 +++++++++++++++++---------------- 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 6c54c37ef7..f8d4497bf7 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -5,9 +5,9 @@ #include "nv40_context.h" static void -nv40_miptree_layout(struct nv40_miptree *nv40mt) +nv40_miptree_layout(struct nv40_miptree *mt) { - struct pipe_texture *pt = &nv40mt->base; + struct pipe_texture *pt = &mt->base; boolean swizzled = FALSE; uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; uint offset = 0; @@ -34,8 +34,8 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) pitch = pt->nblocksx[l]; pitch = align(pitch, 64); - nv40mt->level[l].pitch = pitch * pt->block.size; - nv40mt->level[l].image_offset = + mt->level[l].pitch = pitch * pt->block.size; + mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); width = MAX2(1, width >> 1); @@ -45,12 +45,12 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt) 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]; + mt->level[l].image_offset[f] = offset; + offset += mt->level[l].pitch * pt->height[l]; } } - nv40mt->total_size = offset; + mt->total_size = offset; } static struct pipe_texture * @@ -81,22 +81,24 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) } static void -nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt) +nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt) { - struct pipe_texture *mt = *pt; + struct pipe_texture *pt = *ppt; + struct nv40_miptree *mt = (struct nv40_miptree *)pt; + int l; - *pt = NULL; - if (--mt->refcount <= 0) { - struct nv40_miptree *nv40mt = (struct nv40_miptree *)mt; - int l; + *ppt = NULL; + if (--pt->refcount) + return; - pipe_buffer_reference(pscreen, &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); + + pipe_buffer_reference(pscreen, &mt->buffer, NULL); + for (l = 0; l <= pt->last_level; l++) { + if (mt->level[l].image_offset) + FREE(mt->level[l].image_offset); } + + FREE(mt); } static struct pipe_surface * @@ -104,31 +106,31 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags) { - struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; + struct nv40_miptree *mt = (struct nv40_miptree *)pt; struct pipe_surface *ps; ps = CALLOC_STRUCT(pipe_surface); if (!ps) return NULL; pipe_texture_reference(&ps->texture, pt); - pipe_buffer_reference(pscreen, &ps->buffer, nv40mt->buffer); + pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; ps->block = pt->block; ps->nblocksx = pt->nblocksx[level]; ps->nblocksy = pt->nblocksy[level]; - ps->stride = nv40mt->level[level].pitch; + ps->stride = mt->level[level].pitch; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; if (pt->target == PIPE_TEXTURE_CUBE) { - ps->offset = nv40mt->level[level].image_offset[face]; + ps->offset = mt->level[level].image_offset[face]; } else if (pt->target == PIPE_TEXTURE_3D) { - ps->offset = nv40mt->level[level].image_offset[zslice]; + ps->offset = mt->level[level].image_offset[zslice]; } else { - ps->offset = nv40mt->level[level].image_offset[0]; + ps->offset = mt->level[level].image_offset[0]; } return ps; -- cgit v1.2.3 From 0344b0e32e397ebcc6ed236295eb9b6a06a0dae2 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 8 Nov 2008 17:04:45 +0200 Subject: Nouveau: start nv20 by copying the nv10 tree. Signed-off-by: Pekka Paalanen --- src/gallium/drivers/nv20/Makefile | 28 ++ src/gallium/drivers/nv20/nv10_clear.c | 12 + src/gallium/drivers/nv20/nv10_context.c | 296 +++++++++++++++ src/gallium/drivers/nv20/nv10_context.h | 153 ++++++++ src/gallium/drivers/nv20/nv10_fragprog.c | 21 ++ src/gallium/drivers/nv20/nv10_fragtex.c | 149 ++++++++ src/gallium/drivers/nv20/nv10_miptree.c | 147 ++++++++ src/gallium/drivers/nv20/nv10_prim_vbuf.c | 240 ++++++++++++ src/gallium/drivers/nv20/nv10_screen.c | 208 ++++++++++ src/gallium/drivers/nv20/nv10_screen.h | 22 ++ src/gallium/drivers/nv20/nv10_state.c | 588 +++++++++++++++++++++++++++++ src/gallium/drivers/nv20/nv10_state.h | 139 +++++++ src/gallium/drivers/nv20/nv10_state_emit.c | 303 +++++++++++++++ src/gallium/drivers/nv20/nv10_surface.c | 64 ++++ src/gallium/drivers/nv20/nv10_vbo.c | 77 ++++ 15 files changed, 2447 insertions(+) create mode 100644 src/gallium/drivers/nv20/Makefile create mode 100644 src/gallium/drivers/nv20/nv10_clear.c create mode 100644 src/gallium/drivers/nv20/nv10_context.c create mode 100644 src/gallium/drivers/nv20/nv10_context.h create mode 100644 src/gallium/drivers/nv20/nv10_fragprog.c create mode 100644 src/gallium/drivers/nv20/nv10_fragtex.c create mode 100644 src/gallium/drivers/nv20/nv10_miptree.c create mode 100644 src/gallium/drivers/nv20/nv10_prim_vbuf.c create mode 100644 src/gallium/drivers/nv20/nv10_screen.c create mode 100644 src/gallium/drivers/nv20/nv10_screen.h create mode 100644 src/gallium/drivers/nv20/nv10_state.c create mode 100644 src/gallium/drivers/nv20/nv10_state.h create mode 100644 src/gallium/drivers/nv20/nv10_state_emit.c create mode 100644 src/gallium/drivers/nv20/nv10_surface.c create mode 100644 src/gallium/drivers/nv20/nv10_vbo.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv20/Makefile b/src/gallium/drivers/nv20/Makefile new file mode 100644 index 0000000000..4ba7ce586d --- /dev/null +++ b/src/gallium/drivers/nv20/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/nv20/nv10_clear.c b/src/gallium/drivers/nv20/nv10_clear.c new file mode 100644 index 0000000000..be7e09cf4b --- /dev/null +++ b/src/gallium/drivers/nv20/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/nv20/nv10_context.c b/src/gallium/drivers/nv20/nv10_context.c new file mode 100644 index 0000000000..e9b61daae7 --- /dev/null +++ b/src/gallium/drivers/nv20/nv10_context.c @@ -0,0 +1,296 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.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/nv20/nv10_context.h b/src/gallium/drivers/nv20/nv10_context.h new file mode 100644 index 0000000000..f3b56de25a --- /dev/null +++ b/src/gallium/drivers/nv20/nv10_context.h @@ -0,0 +1,153 @@ +#ifndef __NV10_CONTEXT_H__ +#define __NV10_CONTEXT_H__ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_compiler.h" + +#include "util/u_memory.h" +#include "util/u_math.h" + +#include "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/nv20/nv10_fragprog.c b/src/gallium/drivers/nv20/nv10_fragprog.c new file mode 100644 index 0000000000..698db5a16a --- /dev/null +++ b/src/gallium/drivers/nv20/nv10_fragprog.c @@ -0,0 +1,21 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/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/nv20/nv10_fragtex.c b/src/gallium/drivers/nv20/nv10_fragtex.c new file mode 100644 index 0000000000..238634d0bb --- /dev/null +++ b/src/gallium/drivers/nv20/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/nv20/nv10_miptree.c b/src/gallium/drivers/nv20/nv10_miptree.c new file mode 100644 index 0000000000..ad084e72b8 --- /dev/null +++ b/src/gallium/drivers/nv20/nv10_miptree.c @@ -0,0 +1,147 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.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]; + 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->nblocksx[l] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); + + if (swizzled) + nv10mt->level[l].pitch = pt->nblocksx[l] * pt->block.size; + else + nv10mt->level[l].pitch = pt->nblocksx[0] * pt->block.size; + 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); + + } + + 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_texture *mt = *pt; + + *pt = NULL; + if (--mt->refcount <= 0) { + struct nv10_miptree *nv10mt = (struct nv10_miptree *)mt; + int l; + + pipe_buffer_reference(screen, &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(screen, &ps->buffer, nv10mt->buffer); + ps->format = pt->format; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->block = pt->block; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = nv10mt->level[level].pitch; + + 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/nv20/nv10_prim_vbuf.c b/src/gallium/drivers/nv20/nv10_prim_vbuf.c new file mode 100644 index 0000000000..62a8f6d89d --- /dev/null +++ b/src/gallium/drivers/nv20/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 + * \author Keith Whitwell + */ + + +#include "pipe/p_debug.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" + +#include "nv10_context.h" +#include "nv10_state.h" + +#include "draw/draw_vbuf.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; + struct pipe_screen *pscreen = &nv10->screen->pipe; + + assert(nv10_render->buffer); + winsys->buffer_unmap(winsys, nv10_render->buffer); + pipe_buffer_reference(pscreen, &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/nv20/nv10_screen.c b/src/gallium/drivers/nv20/nv10_screen.c new file mode 100644 index 0000000000..27a9edf9bb --- /dev/null +++ b/src/gallium/drivers/nv20/nv10_screen.c @@ -0,0 +1,208 @@ +#include "pipe/p_screen.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, + enum pipe_texture_target target, + unsigned tex_usage, unsigned geom_flags) +{ + if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { + 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; + } + } else { + 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; + } + } + + 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/nv20/nv10_screen.h b/src/gallium/drivers/nv20/nv10_screen.h new file mode 100644 index 0000000000..3f8750a13f --- /dev/null +++ b/src/gallium/drivers/nv20/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/nv20/nv10_state.c b/src/gallium/drivers/nv20/nv10_state.c new file mode 100644 index 0000000000..d2375aa2f6 --- /dev/null +++ b/src/gallium/drivers/nv20/nv10_state.c @@ -0,0 +1,588 @@ +#include "draw/draw_context.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/tgsi_parse.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.tokens = tgsi_dup_tokens(cso->tokens); + + 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((void*)fp->pipe.tokens); + 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/nv20/nv10_state.h b/src/gallium/drivers/nv20/nv10_state.h new file mode 100644 index 0000000000..3a3fd0d4f4 --- /dev/null +++ b/src/gallium/drivers/nv20/nv10_state.h @@ -0,0 +1,139 @@ +#ifndef __NV10_STATE_H__ +#define __NV10_STATE_H__ + +#include "pipe/p_state.h" +#include "tgsi/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 { + 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/nv20/nv10_state_emit.c b/src/gallium/drivers/nv20/nv10_state_emit.c new file mode 100644 index 0000000000..46c7e1d753 --- /dev/null +++ b/src/gallium/drivers/nv20/nv10_state_emit.c @@ -0,0 +1,303 @@ +#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->stride | (zeta->stride << 16)); + } else { + BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); + OUT_RING (rt->stride | (rt->stride << 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/nv20/nv10_surface.c b/src/gallium/drivers/nv20/nv10_surface.c new file mode 100644 index 0000000000..875e4c5858 --- /dev/null +++ b/src/gallium/drivers/nv20/nv10_surface.c @@ -0,0 +1,64 @@ + +/************************************************************************** + * + * 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_winsys.h" +#include "pipe/p_inlines.h" +#include "util/u_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/nv20/nv10_vbo.c b/src/gallium/drivers/nv20/nv10_vbo.c new file mode 100644 index 0000000000..d0e788ac03 --- /dev/null +++ b/src/gallium/drivers/nv20/nv10_vbo.c @@ -0,0 +1,77 @@ +#include "draw/draw_context.h" +#include "pipe/p_context.h" +#include "pipe/p_state.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); +} + + + -- cgit v1.2.3 From f910371b3736e7d09b82d42e0dd1295482817883 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 8 Nov 2008 17:09:16 +0200 Subject: Nouveau: copy nv30_vertprog.c to nv20. Signed-off-by: Pekka Paalanen --- src/gallium/drivers/nv20/nv30_vertprog.c | 838 +++++++++++++++++++++++++++++++ 1 file changed, 838 insertions(+) create mode 100644 src/gallium/drivers/nv20/nv30_vertprog.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv20/nv30_vertprog.c b/src/gallium/drivers/nv20/nv30_vertprog.c new file mode 100644 index 0000000000..72824559e8 --- /dev/null +++ b/src/gallium/drivers/nv20/nv30_vertprog.c @@ -0,0 +1,838 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_dump.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_SGT: + arith(vpc, 0, OP_SGT, 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; +} + +static void +nv30_vertprog_translate(struct nv30_context *nv30, + struct nv30_vertex_program *vp) +{ + struct tgsi_parse_context parse; + struct nv30_vpc *vpc = NULL; + + tgsi_dump(vp->pipe.tokens,0); + + 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); +} + +static boolean +nv30_vertprog_validate(struct nv30_context *nv30) +{ + struct nouveau_winsys *nvws = nv30->nvws; + struct pipe_winsys *ws = nv30->pipe.winsys; + struct nouveau_grobj *rankine = nv30->screen->rankine; + struct nv30_vertex_program *vp; + struct pipe_buffer *constbuf; + boolean upload_code = FALSE, upload_data = FALSE; + int i; + + vp = nv30->vertprog; + constbuf = nv30->constbuf[PIPE_SHADER_VERTEX]; + + /* Translate TGSI shader into hw bytecode */ + if (!vp->translated) { + nv30_vertprog_translate(nv30, vp); + if (!vp->translated) + return FALSE; + } + + /* Allocate hw vtxprog exec slots */ + if (!vp->exec) { + struct nouveau_resource *heap = nv30->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 nv30_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(2, 0); + so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1); + so_data (so, vp->exec->start); + so_ref(so, &vp->so); + + 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 (constbuf) { + map = ws->buffer_map(ws, constbuf, + 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 (constbuf) { + ws->buffer_unmap(ws, constbuf); + } + } + + /* 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); + } + } + + if (vp->so != nv30->state.hw[NV30_STATE_VERTPROG]) { + so_ref(vp->so, &nv30->state.hw[NV30_STATE_VERTPROG]); + return TRUE; + } + + return FALSE; +} + +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 = 0; + so_ref(NULL, &vp->so); +} + +struct nv30_state_entry nv30_state_vertprog = { + .validate = nv30_vertprog_validate, + .dirty = { + .pipe = NV30_NEW_VERTPROG /*| NV30_NEW_UCP*/, + .hw = NV30_STATE_VERTPROG, + } +}; -- cgit v1.2.3 From 83bb81856066101dff85fdebea32df55ed8de4c5 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 8 Nov 2008 17:20:19 +0200 Subject: Nouveau: Rename nv20/ files as nv20. Signed-off-by: Pekka Paalanen --- src/gallium/drivers/nv20/Makefile | 25 +- src/gallium/drivers/nv20/nv10_clear.c | 12 - src/gallium/drivers/nv20/nv10_context.c | 296 ---------- src/gallium/drivers/nv20/nv10_context.h | 153 ------ src/gallium/drivers/nv20/nv10_fragprog.c | 21 - src/gallium/drivers/nv20/nv10_fragtex.c | 149 ----- src/gallium/drivers/nv20/nv10_miptree.c | 147 ----- src/gallium/drivers/nv20/nv10_prim_vbuf.c | 240 --------- src/gallium/drivers/nv20/nv10_screen.c | 208 ------- src/gallium/drivers/nv20/nv10_screen.h | 22 - src/gallium/drivers/nv20/nv10_state.c | 588 -------------------- src/gallium/drivers/nv20/nv10_state.h | 139 ----- src/gallium/drivers/nv20/nv10_state_emit.c | 303 ----------- src/gallium/drivers/nv20/nv10_surface.c | 64 --- src/gallium/drivers/nv20/nv10_vbo.c | 77 --- src/gallium/drivers/nv20/nv20_clear.c | 12 + src/gallium/drivers/nv20/nv20_context.c | 296 ++++++++++ src/gallium/drivers/nv20/nv20_context.h | 153 ++++++ src/gallium/drivers/nv20/nv20_fragprog.c | 21 + src/gallium/drivers/nv20/nv20_fragtex.c | 149 +++++ src/gallium/drivers/nv20/nv20_miptree.c | 147 +++++ src/gallium/drivers/nv20/nv20_prim_vbuf.c | 240 +++++++++ src/gallium/drivers/nv20/nv20_screen.c | 208 +++++++ src/gallium/drivers/nv20/nv20_screen.h | 22 + src/gallium/drivers/nv20/nv20_state.c | 588 ++++++++++++++++++++ src/gallium/drivers/nv20/nv20_state.h | 139 +++++ src/gallium/drivers/nv20/nv20_state_emit.c | 303 +++++++++++ src/gallium/drivers/nv20/nv20_surface.c | 64 +++ src/gallium/drivers/nv20/nv20_vbo.c | 77 +++ src/gallium/drivers/nv20/nv20_vertprog.c | 838 +++++++++++++++++++++++++++++ src/gallium/drivers/nv20/nv30_vertprog.c | 838 ----------------------------- 31 files changed, 3270 insertions(+), 3269 deletions(-) delete mode 100644 src/gallium/drivers/nv20/nv10_clear.c delete mode 100644 src/gallium/drivers/nv20/nv10_context.c delete mode 100644 src/gallium/drivers/nv20/nv10_context.h delete mode 100644 src/gallium/drivers/nv20/nv10_fragprog.c delete mode 100644 src/gallium/drivers/nv20/nv10_fragtex.c delete mode 100644 src/gallium/drivers/nv20/nv10_miptree.c delete mode 100644 src/gallium/drivers/nv20/nv10_prim_vbuf.c delete mode 100644 src/gallium/drivers/nv20/nv10_screen.c delete mode 100644 src/gallium/drivers/nv20/nv10_screen.h delete mode 100644 src/gallium/drivers/nv20/nv10_state.c delete mode 100644 src/gallium/drivers/nv20/nv10_state.h delete mode 100644 src/gallium/drivers/nv20/nv10_state_emit.c delete mode 100644 src/gallium/drivers/nv20/nv10_surface.c delete mode 100644 src/gallium/drivers/nv20/nv10_vbo.c create mode 100644 src/gallium/drivers/nv20/nv20_clear.c create mode 100644 src/gallium/drivers/nv20/nv20_context.c create mode 100644 src/gallium/drivers/nv20/nv20_context.h create mode 100644 src/gallium/drivers/nv20/nv20_fragprog.c create mode 100644 src/gallium/drivers/nv20/nv20_fragtex.c create mode 100644 src/gallium/drivers/nv20/nv20_miptree.c create mode 100644 src/gallium/drivers/nv20/nv20_prim_vbuf.c create mode 100644 src/gallium/drivers/nv20/nv20_screen.c create mode 100644 src/gallium/drivers/nv20/nv20_screen.h create mode 100644 src/gallium/drivers/nv20/nv20_state.c create mode 100644 src/gallium/drivers/nv20/nv20_state.h create mode 100644 src/gallium/drivers/nv20/nv20_state_emit.c create mode 100644 src/gallium/drivers/nv20/nv20_surface.c create mode 100644 src/gallium/drivers/nv20/nv20_vbo.c create mode 100644 src/gallium/drivers/nv20/nv20_vertprog.c delete mode 100644 src/gallium/drivers/nv20/nv30_vertprog.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv20/Makefile b/src/gallium/drivers/nv20/Makefile index 4ba7ce586d..76aafbe8f0 100644 --- a/src/gallium/drivers/nv20/Makefile +++ b/src/gallium/drivers/nv20/Makefile @@ -1,20 +1,21 @@ TOP = ../../../.. include $(TOP)/configs/current -LIBNAME = nv10 +LIBNAME = nv20 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 + nv20_clear.c \ + nv20_context.c \ + nv20_fragprog.c \ + nv20_fragtex.c \ + nv20_miptree.c \ + nv20_prim_vbuf.c \ + nv20_screen.c \ + nv20_state.c \ + nv20_state_emit.c \ + nv20_surface.c \ + nv20_vbo.c \ + nv20_vertprog.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/gallium/drivers/nv20/nv10_clear.c b/src/gallium/drivers/nv20/nv10_clear.c deleted file mode 100644 index be7e09cf4b..0000000000 --- a/src/gallium/drivers/nv20/nv10_clear.c +++ /dev/null @@ -1,12 +0,0 @@ -#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/nv20/nv10_context.c b/src/gallium/drivers/nv20/nv10_context.c deleted file mode 100644 index e9b61daae7..0000000000 --- a/src/gallium/drivers/nv20/nv10_context.c +++ /dev/null @@ -1,296 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_winsys.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/nv20/nv10_context.h b/src/gallium/drivers/nv20/nv10_context.h deleted file mode 100644 index f3b56de25a..0000000000 --- a/src/gallium/drivers/nv20/nv10_context.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef __NV10_CONTEXT_H__ -#define __NV10_CONTEXT_H__ - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_compiler.h" - -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "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/nv20/nv10_fragprog.c b/src/gallium/drivers/nv20/nv10_fragprog.c deleted file mode 100644 index 698db5a16a..0000000000 --- a/src/gallium/drivers/nv20/nv10_fragprog.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/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/nv20/nv10_fragtex.c b/src/gallium/drivers/nv20/nv10_fragtex.c deleted file mode 100644 index 238634d0bb..0000000000 --- a/src/gallium/drivers/nv20/nv10_fragtex.c +++ /dev/null @@ -1,149 +0,0 @@ -#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/nv20/nv10_miptree.c b/src/gallium/drivers/nv20/nv10_miptree.c deleted file mode 100644 index ad084e72b8..0000000000 --- a/src/gallium/drivers/nv20/nv10_miptree.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "pipe/p_state.h" -#include "pipe/p_defines.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]; - 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->nblocksx[l] = pf_get_nblocksx(&pt->block, width); - pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); - - if (swizzled) - nv10mt->level[l].pitch = pt->nblocksx[l] * pt->block.size; - else - nv10mt->level[l].pitch = pt->nblocksx[0] * pt->block.size; - 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); - - } - - 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_texture *mt = *pt; - - *pt = NULL; - if (--mt->refcount <= 0) { - struct nv10_miptree *nv10mt = (struct nv10_miptree *)mt; - int l; - - pipe_buffer_reference(screen, &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(screen, &ps->buffer, nv10mt->buffer); - ps->format = pt->format; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->block = pt->block; - ps->nblocksx = pt->nblocksx[level]; - ps->nblocksy = pt->nblocksy[level]; - ps->stride = nv10mt->level[level].pitch; - - 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/nv20/nv10_prim_vbuf.c b/src/gallium/drivers/nv20/nv10_prim_vbuf.c deleted file mode 100644 index 62a8f6d89d..0000000000 --- a/src/gallium/drivers/nv20/nv10_prim_vbuf.c +++ /dev/null @@ -1,240 +0,0 @@ -/************************************************************************** - * - * 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 - * \author Keith Whitwell - */ - - -#include "pipe/p_debug.h" -#include "pipe/p_inlines.h" -#include "pipe/p_winsys.h" - -#include "nv10_context.h" -#include "nv10_state.h" - -#include "draw/draw_vbuf.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; - struct pipe_screen *pscreen = &nv10->screen->pipe; - - assert(nv10_render->buffer); - winsys->buffer_unmap(winsys, nv10_render->buffer); - pipe_buffer_reference(pscreen, &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/nv20/nv10_screen.c b/src/gallium/drivers/nv20/nv10_screen.c deleted file mode 100644 index 27a9edf9bb..0000000000 --- a/src/gallium/drivers/nv20/nv10_screen.c +++ /dev/null @@ -1,208 +0,0 @@ -#include "pipe/p_screen.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, - enum pipe_texture_target target, - unsigned tex_usage, unsigned geom_flags) -{ - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { - 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; - } - } else { - 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; - } - } - - 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/nv20/nv10_screen.h b/src/gallium/drivers/nv20/nv10_screen.h deleted file mode 100644 index 3f8750a13f..0000000000 --- a/src/gallium/drivers/nv20/nv10_screen.h +++ /dev/null @@ -1,22 +0,0 @@ -#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/nv20/nv10_state.c b/src/gallium/drivers/nv20/nv10_state.c deleted file mode 100644 index d2375aa2f6..0000000000 --- a/src/gallium/drivers/nv20/nv10_state.c +++ /dev/null @@ -1,588 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/tgsi_parse.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.tokens = tgsi_dup_tokens(cso->tokens); - - 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((void*)fp->pipe.tokens); - 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/nv20/nv10_state.h b/src/gallium/drivers/nv20/nv10_state.h deleted file mode 100644 index 3a3fd0d4f4..0000000000 --- a/src/gallium/drivers/nv20/nv10_state.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef __NV10_STATE_H__ -#define __NV10_STATE_H__ - -#include "pipe/p_state.h" -#include "tgsi/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 { - 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/nv20/nv10_state_emit.c b/src/gallium/drivers/nv20/nv10_state_emit.c deleted file mode 100644 index 46c7e1d753..0000000000 --- a/src/gallium/drivers/nv20/nv10_state_emit.c +++ /dev/null @@ -1,303 +0,0 @@ -#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->stride | (zeta->stride << 16)); - } else { - BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); - OUT_RING (rt->stride | (rt->stride << 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/nv20/nv10_surface.c b/src/gallium/drivers/nv20/nv10_surface.c deleted file mode 100644 index 875e4c5858..0000000000 --- a/src/gallium/drivers/nv20/nv10_surface.c +++ /dev/null @@ -1,64 +0,0 @@ - -/************************************************************************** - * - * 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_winsys.h" -#include "pipe/p_inlines.h" -#include "util/u_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/nv20/nv10_vbo.c b/src/gallium/drivers/nv20/nv10_vbo.c deleted file mode 100644 index d0e788ac03..0000000000 --- a/src/gallium/drivers/nv20/nv10_vbo.c +++ /dev/null @@ -1,77 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_context.h" -#include "pipe/p_state.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/nv20/nv20_clear.c b/src/gallium/drivers/nv20/nv20_clear.c new file mode 100644 index 0000000000..be7e09cf4b --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_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/nv20/nv20_context.c b/src/gallium/drivers/nv20/nv20_context.c new file mode 100644 index 0000000000..e9b61daae7 --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_context.c @@ -0,0 +1,296 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.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/nv20/nv20_context.h b/src/gallium/drivers/nv20/nv20_context.h new file mode 100644 index 0000000000..f3b56de25a --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_context.h @@ -0,0 +1,153 @@ +#ifndef __NV10_CONTEXT_H__ +#define __NV10_CONTEXT_H__ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_compiler.h" + +#include "util/u_memory.h" +#include "util/u_math.h" + +#include "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/nv20/nv20_fragprog.c b/src/gallium/drivers/nv20/nv20_fragprog.c new file mode 100644 index 0000000000..698db5a16a --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_fragprog.c @@ -0,0 +1,21 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/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/nv20/nv20_fragtex.c b/src/gallium/drivers/nv20/nv20_fragtex.c new file mode 100644 index 0000000000..238634d0bb --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_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/nv20/nv20_miptree.c b/src/gallium/drivers/nv20/nv20_miptree.c new file mode 100644 index 0000000000..ad084e72b8 --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_miptree.c @@ -0,0 +1,147 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.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]; + 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->nblocksx[l] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); + + if (swizzled) + nv10mt->level[l].pitch = pt->nblocksx[l] * pt->block.size; + else + nv10mt->level[l].pitch = pt->nblocksx[0] * pt->block.size; + 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); + + } + + 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_texture *mt = *pt; + + *pt = NULL; + if (--mt->refcount <= 0) { + struct nv10_miptree *nv10mt = (struct nv10_miptree *)mt; + int l; + + pipe_buffer_reference(screen, &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(screen, &ps->buffer, nv10mt->buffer); + ps->format = pt->format; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->block = pt->block; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = nv10mt->level[level].pitch; + + 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/nv20/nv20_prim_vbuf.c b/src/gallium/drivers/nv20/nv20_prim_vbuf.c new file mode 100644 index 0000000000..62a8f6d89d --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_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 + * \author Keith Whitwell + */ + + +#include "pipe/p_debug.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" + +#include "nv10_context.h" +#include "nv10_state.h" + +#include "draw/draw_vbuf.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; + struct pipe_screen *pscreen = &nv10->screen->pipe; + + assert(nv10_render->buffer); + winsys->buffer_unmap(winsys, nv10_render->buffer); + pipe_buffer_reference(pscreen, &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/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c new file mode 100644 index 0000000000..27a9edf9bb --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_screen.c @@ -0,0 +1,208 @@ +#include "pipe/p_screen.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, + enum pipe_texture_target target, + unsigned tex_usage, unsigned geom_flags) +{ + if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { + 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; + } + } else { + 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; + } + } + + 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/nv20/nv20_screen.h b/src/gallium/drivers/nv20/nv20_screen.h new file mode 100644 index 0000000000..3f8750a13f --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_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/nv20/nv20_state.c b/src/gallium/drivers/nv20/nv20_state.c new file mode 100644 index 0000000000..d2375aa2f6 --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_state.c @@ -0,0 +1,588 @@ +#include "draw/draw_context.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/tgsi_parse.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.tokens = tgsi_dup_tokens(cso->tokens); + + 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((void*)fp->pipe.tokens); + 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/nv20/nv20_state.h b/src/gallium/drivers/nv20/nv20_state.h new file mode 100644 index 0000000000..3a3fd0d4f4 --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_state.h @@ -0,0 +1,139 @@ +#ifndef __NV10_STATE_H__ +#define __NV10_STATE_H__ + +#include "pipe/p_state.h" +#include "tgsi/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 { + 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/nv20/nv20_state_emit.c b/src/gallium/drivers/nv20/nv20_state_emit.c new file mode 100644 index 0000000000..46c7e1d753 --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_state_emit.c @@ -0,0 +1,303 @@ +#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->stride | (zeta->stride << 16)); + } else { + BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); + OUT_RING (rt->stride | (rt->stride << 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/nv20/nv20_surface.c b/src/gallium/drivers/nv20/nv20_surface.c new file mode 100644 index 0000000000..875e4c5858 --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_surface.c @@ -0,0 +1,64 @@ + +/************************************************************************** + * + * 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_winsys.h" +#include "pipe/p_inlines.h" +#include "util/u_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/nv20/nv20_vbo.c b/src/gallium/drivers/nv20/nv20_vbo.c new file mode 100644 index 0000000000..d0e788ac03 --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_vbo.c @@ -0,0 +1,77 @@ +#include "draw/draw_context.h" +#include "pipe/p_context.h" +#include "pipe/p_state.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/nv20/nv20_vertprog.c b/src/gallium/drivers/nv20/nv20_vertprog.c new file mode 100644 index 0000000000..72824559e8 --- /dev/null +++ b/src/gallium/drivers/nv20/nv20_vertprog.c @@ -0,0 +1,838 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_dump.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_SGT: + arith(vpc, 0, OP_SGT, 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; +} + +static void +nv30_vertprog_translate(struct nv30_context *nv30, + struct nv30_vertex_program *vp) +{ + struct tgsi_parse_context parse; + struct nv30_vpc *vpc = NULL; + + tgsi_dump(vp->pipe.tokens,0); + + 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); +} + +static boolean +nv30_vertprog_validate(struct nv30_context *nv30) +{ + struct nouveau_winsys *nvws = nv30->nvws; + struct pipe_winsys *ws = nv30->pipe.winsys; + struct nouveau_grobj *rankine = nv30->screen->rankine; + struct nv30_vertex_program *vp; + struct pipe_buffer *constbuf; + boolean upload_code = FALSE, upload_data = FALSE; + int i; + + vp = nv30->vertprog; + constbuf = nv30->constbuf[PIPE_SHADER_VERTEX]; + + /* Translate TGSI shader into hw bytecode */ + if (!vp->translated) { + nv30_vertprog_translate(nv30, vp); + if (!vp->translated) + return FALSE; + } + + /* Allocate hw vtxprog exec slots */ + if (!vp->exec) { + struct nouveau_resource *heap = nv30->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 nv30_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(2, 0); + so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1); + so_data (so, vp->exec->start); + so_ref(so, &vp->so); + + 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 (constbuf) { + map = ws->buffer_map(ws, constbuf, + 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 (constbuf) { + ws->buffer_unmap(ws, constbuf); + } + } + + /* 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); + } + } + + if (vp->so != nv30->state.hw[NV30_STATE_VERTPROG]) { + so_ref(vp->so, &nv30->state.hw[NV30_STATE_VERTPROG]); + return TRUE; + } + + return FALSE; +} + +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 = 0; + so_ref(NULL, &vp->so); +} + +struct nv30_state_entry nv30_state_vertprog = { + .validate = nv30_vertprog_validate, + .dirty = { + .pipe = NV30_NEW_VERTPROG /*| NV30_NEW_UCP*/, + .hw = NV30_STATE_VERTPROG, + } +}; diff --git a/src/gallium/drivers/nv20/nv30_vertprog.c b/src/gallium/drivers/nv20/nv30_vertprog.c deleted file mode 100644 index 72824559e8..0000000000 --- a/src/gallium/drivers/nv20/nv30_vertprog.c +++ /dev/null @@ -1,838 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_dump.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_SGT: - arith(vpc, 0, OP_SGT, 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; -} - -static void -nv30_vertprog_translate(struct nv30_context *nv30, - struct nv30_vertex_program *vp) -{ - struct tgsi_parse_context parse; - struct nv30_vpc *vpc = NULL; - - tgsi_dump(vp->pipe.tokens,0); - - 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); -} - -static boolean -nv30_vertprog_validate(struct nv30_context *nv30) -{ - struct nouveau_winsys *nvws = nv30->nvws; - struct pipe_winsys *ws = nv30->pipe.winsys; - struct nouveau_grobj *rankine = nv30->screen->rankine; - struct nv30_vertex_program *vp; - struct pipe_buffer *constbuf; - boolean upload_code = FALSE, upload_data = FALSE; - int i; - - vp = nv30->vertprog; - constbuf = nv30->constbuf[PIPE_SHADER_VERTEX]; - - /* Translate TGSI shader into hw bytecode */ - if (!vp->translated) { - nv30_vertprog_translate(nv30, vp); - if (!vp->translated) - return FALSE; - } - - /* Allocate hw vtxprog exec slots */ - if (!vp->exec) { - struct nouveau_resource *heap = nv30->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 nv30_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(2, 0); - so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1); - so_data (so, vp->exec->start); - so_ref(so, &vp->so); - - 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 (constbuf) { - map = ws->buffer_map(ws, constbuf, - 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 (constbuf) { - ws->buffer_unmap(ws, constbuf); - } - } - - /* 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); - } - } - - if (vp->so != nv30->state.hw[NV30_STATE_VERTPROG]) { - so_ref(vp->so, &nv30->state.hw[NV30_STATE_VERTPROG]); - return TRUE; - } - - return FALSE; -} - -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 = 0; - so_ref(NULL, &vp->so); -} - -struct nv30_state_entry nv30_state_vertprog = { - .validate = nv30_vertprog_validate, - .dirty = { - .pipe = NV30_NEW_VERTPROG /*| NV30_NEW_UCP*/, - .hw = NV30_STATE_VERTPROG, - } -}; -- cgit v1.2.3 From b5a3c4272be1561646c8a104e4faae870f16ddee Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 8 Nov 2008 18:04:33 +0200 Subject: Nouveau: name replace for nv20. No functional changes, only changed function, struct, macro etc. names. nv10 -> nv20 nv30 -> nv20 celsius -> kelvin Did not touch fifo command macros. Don't try to build nv20_vertprog.c for now. Signed-off-by: Pekka Paalanen --- src/gallium/drivers/nv20/Makefile | 4 +- src/gallium/drivers/nv20/nv20_clear.c | 4 +- src/gallium/drivers/nv20/nv20_context.c | 194 ++++++++++----------- src/gallium/drivers/nv20/nv20_context.h | 104 +++++------ src/gallium/drivers/nv20/nv20_fragprog.c | 8 +- src/gallium/drivers/nv20/nv20_fragtex.c | 46 ++--- src/gallium/drivers/nv20/nv20_miptree.c | 68 ++++---- src/gallium/drivers/nv20/nv20_prim_vbuf.c | 132 +++++++------- src/gallium/drivers/nv20/nv20_screen.c | 54 +++--- src/gallium/drivers/nv20/nv20_screen.h | 14 +- src/gallium/drivers/nv20/nv20_state.c | 270 ++++++++++++++--------------- src/gallium/drivers/nv20/nv20_state.h | 30 ++-- src/gallium/drivers/nv20/nv20_state_emit.c | 200 ++++++++++----------- src/gallium/drivers/nv20/nv20_surface.c | 20 +-- src/gallium/drivers/nv20/nv20_vbo.c | 30 ++-- src/gallium/drivers/nv20/nv20_vertprog.c | 146 ++++++++-------- 16 files changed, 662 insertions(+), 662 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv20/Makefile b/src/gallium/drivers/nv20/Makefile index 76aafbe8f0..d777fd3d8b 100644 --- a/src/gallium/drivers/nv20/Makefile +++ b/src/gallium/drivers/nv20/Makefile @@ -14,8 +14,8 @@ DRIVER_SOURCES = \ nv20_state.c \ nv20_state_emit.c \ nv20_surface.c \ - nv20_vbo.c \ - nv20_vertprog.c + nv20_vbo.c +# nv20_vertprog.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/gallium/drivers/nv20/nv20_clear.c b/src/gallium/drivers/nv20/nv20_clear.c index be7e09cf4b..81b6f3e78a 100644 --- a/src/gallium/drivers/nv20/nv20_clear.c +++ b/src/gallium/drivers/nv20/nv20_clear.c @@ -2,10 +2,10 @@ #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "nv10_context.h" +#include "nv20_context.h" void -nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, +nv20_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/nv20/nv20_context.c b/src/gallium/drivers/nv20/nv20_context.c index e9b61daae7..2af5b0203e 100644 --- a/src/gallium/drivers/nv20/nv20_context.c +++ b/src/gallium/drivers/nv20/nv20_context.c @@ -2,101 +2,101 @@ #include "pipe/p_defines.h" #include "pipe/p_winsys.h" -#include "nv10_context.h" -#include "nv10_screen.h" +#include "nv20_context.h" +#include "nv20_screen.h" static void -nv10_flush(struct pipe_context *pipe, unsigned flags, +nv20_flush(struct pipe_context *pipe, unsigned flags, struct pipe_fence_handle **fence) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - draw_flush(nv10->draw); + draw_flush(nv20->draw); FIRE_RING(fence); } static void -nv10_destroy(struct pipe_context *pipe) +nv20_destroy(struct pipe_context *pipe) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - if (nv10->draw) - draw_destroy(nv10->draw); + if (nv20->draw) + draw_destroy(nv20->draw); - FREE(nv10); + FREE(nv20); } -static void nv10_init_hwctx(struct nv10_context *nv10) +static void nv20_init_hwctx(struct nv20_context *nv20) { - struct nv10_screen *screen = nv10->screen; + struct nv20_screen *screen = nv20->screen; struct nouveau_winsys *nvws = screen->nvws; int i; float projectionmatrix[16]; - BEGIN_RING(celsius, NV10TCL_DMA_NOTIFY, 1); + BEGIN_RING(kelvin, NV10TCL_DMA_NOTIFY, 1); OUT_RING (screen->sync->handle); - BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY0, 2); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, NV10TCL_DMA_IN_MEMORY2, 2); OUT_RING (nvws->channel->vram->handle); OUT_RING (nvws->channel->vram->handle); - BEGIN_RING(celsius, NV10TCL_NOP, 1); + BEGIN_RING(kelvin, NV10TCL_NOP, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 2); + BEGIN_RING(kelvin, NV10TCL_RT_HORIZ, 2); OUT_RING (0); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); + BEGIN_RING(kelvin, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); OUT_RING ((0x7ff<<16)|0x800); - BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1); + BEGIN_RING(kelvin, NV10TCL_VIEWPORT_CLIP_VERT(i), 1); OUT_RING (0); } - BEGIN_RING(celsius, 0x290, 1); + BEGIN_RING(kelvin, 0x290, 1); OUT_RING ((0x10<<16)|1); - BEGIN_RING(celsius, 0x3f4, 1); + BEGIN_RING(kelvin, 0x3f4, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_NOP, 1); + BEGIN_RING(kelvin, NV10TCL_NOP, 1); OUT_RING (0); - if (nv10->screen->celsius->grclass != NV10TCL) { + if (nv20->screen->kelvin->grclass != NV10TCL) { /* For nv11, nv17 */ - BEGIN_RING(celsius, 0x120, 3); + BEGIN_RING(kelvin, 0x120, 3); OUT_RING (0); OUT_RING (1); OUT_RING (2); - BEGIN_RING(celsius, NV10TCL_NOP, 1); + BEGIN_RING(kelvin, NV10TCL_NOP, 1); OUT_RING (0); } - BEGIN_RING(celsius, NV10TCL_NOP, 1); + BEGIN_RING(kelvin, NV10TCL_NOP, 1); OUT_RING (0); /* Set state */ - BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_FOG_ENABLE, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_ALPHA_FUNC_ENABLE, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); + BEGIN_RING(kelvin, NV10TCL_ALPHA_FUNC_FUNC, 2); OUT_RING (0x207); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_TX_ENABLE(0), 2); + BEGIN_RING(kelvin, NV10TCL_TX_ENABLE(0), 2); OUT_RING (0); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_RC_IN_ALPHA(0), 12); + BEGIN_RING(kelvin, NV10TCL_RC_IN_ALPHA(0), 12); OUT_RING (0x30141010); OUT_RING (0); OUT_RING (0x20040000); @@ -110,22 +110,22 @@ static void nv10_init_hwctx(struct nv10_context *nv10) OUT_RING (0x300e0300); OUT_RING (0x0c091c80); - BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_BLEND_FUNC_ENABLE, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 2); + BEGIN_RING(kelvin, NV10TCL_DITHER_ENABLE, 2); OUT_RING (1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_LINE_SMOOTH_ENABLE, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2); + BEGIN_RING(kelvin, NV10TCL_VERTEX_WEIGHT_ENABLE, 2); OUT_RING (0); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_SRC, 4); + BEGIN_RING(kelvin, NV10TCL_BLEND_FUNC_SRC, 4); OUT_RING (1); OUT_RING (0); OUT_RING (0); OUT_RING (0x8006); - BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 8); + BEGIN_RING(kelvin, NV10TCL_STENCIL_MASK, 8); OUT_RING (0xff); OUT_RING (0x207); OUT_RING (0); @@ -134,103 +134,103 @@ static void nv10_init_hwctx(struct nv10_context *nv10) OUT_RING (0x1e00); OUT_RING (0x1e00); OUT_RING (0x1d01); - BEGIN_RING(celsius, NV10TCL_NORMALIZE_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_NORMALIZE_ENABLE, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 2); + BEGIN_RING(kelvin, NV10TCL_FOG_ENABLE, 2); OUT_RING (0); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_LIGHT_MODEL, 1); + BEGIN_RING(kelvin, NV10TCL_LIGHT_MODEL, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_COLOR_CONTROL, 1); + BEGIN_RING(kelvin, NV10TCL_COLOR_CONTROL, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_ENABLED_LIGHTS, 1); + BEGIN_RING(kelvin, NV10TCL_ENABLED_LIGHTS, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + BEGIN_RING(kelvin, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); OUT_RING (0); OUT_RING (0); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 1); + BEGIN_RING(kelvin, NV10TCL_DEPTH_FUNC, 1); OUT_RING (0x201); - BEGIN_RING(celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_DEPTH_WRITE_ENABLE, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_DEPTH_TEST_ENABLE, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); + BEGIN_RING(kelvin, NV10TCL_POLYGON_OFFSET_FACTOR, 2); OUT_RING (0); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); + BEGIN_RING(kelvin, NV10TCL_POINT_SIZE, 1); OUT_RING (8); - BEGIN_RING(celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2); + BEGIN_RING(kelvin, NV10TCL_POINT_PARAMETERS_ENABLE, 2); OUT_RING (0); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_LINE_WIDTH, 1); + BEGIN_RING(kelvin, NV10TCL_LINE_WIDTH, 1); OUT_RING (8); - BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_LINE_SMOOTH_ENABLE, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + BEGIN_RING(kelvin, NV10TCL_POLYGON_MODE_FRONT, 2); OUT_RING (0x1b02); OUT_RING (0x1b02); - BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); + BEGIN_RING(kelvin, NV10TCL_CULL_FACE, 2); OUT_RING (0x405); OUT_RING (0x901); - BEGIN_RING(celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_CULL_FACE_ENABLE, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_CLIP_PLANE_ENABLE(0), 8); + BEGIN_RING(kelvin, NV10TCL_CLIP_PLANE_ENABLE(0), 8); for (i=0;i<8;i++) { OUT_RING (0); } - BEGIN_RING(celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, NV10TCL_NOP, 1); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_FOG_MODE, 2); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, NV10TCL_VIEW_MATRIX_ENABLE, 1); OUT_RING (6); - BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); + BEGIN_RING(kelvin, NV10TCL_COLOR_MASK, 1); OUT_RING (0x01010101); /* Set vertex component */ - BEGIN_RING(celsius, NV10TCL_VERTEX_COL_4F_R, 4); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, NV10TCL_VERTEX_COL2_3F_R, 3); OUT_RING (0); OUT_RING (0); OUT_RING (0); - BEGIN_RING(celsius, NV10TCL_VERTEX_NOR_3F_X, 3); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, NV10TCL_VERTEX_FOG_1F, 1); OUT_RINGf (0.0); - BEGIN_RING(celsius, NV10TCL_EDGEFLAG_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_EDGEFLAG_ENABLE, 1); OUT_RING (1); memset(projectionmatrix, 0, sizeof(projectionmatrix)); - BEGIN_RING(celsius, NV10TCL_PROJECTION_MATRIX(0), 16); + BEGIN_RING(kelvin, NV10TCL_PROJECTION_MATRIX(0), 16); projectionmatrix[0*4+0] = 1.0; projectionmatrix[1*4+1] = 1.0; projectionmatrix[2*4+2] = 1.0; @@ -239,11 +239,11 @@ static void nv10_init_hwctx(struct nv10_context *nv10) OUT_RINGf (projectionmatrix[i]); } - BEGIN_RING(celsius, NV10TCL_DEPTH_RANGE_NEAR, 2); + BEGIN_RING(kelvin, NV10TCL_DEPTH_RANGE_NEAR, 2); OUT_RING (0.0); OUT_RINGf (16777216.0); - BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4); + BEGIN_RING(kelvin, NV10TCL_VIEWPORT_SCALE_X, 4); OUT_RINGf (-2048.0); OUT_RINGf (-2048.0); OUT_RINGf (16777215.0 * 0.5); @@ -253,44 +253,44 @@ static void nv10_init_hwctx(struct nv10_context *nv10) } static void -nv10_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +nv20_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) { } struct pipe_context * -nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) +nv20_create(struct pipe_screen *pscreen, unsigned pctx_id) { - struct nv10_screen *screen = nv10_screen(pscreen); + struct nv20_screen *screen = nv20_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; - struct nv10_context *nv10; + struct nv20_context *nv20; struct nouveau_winsys *nvws = screen->nvws; - nv10 = CALLOC(1, sizeof(struct nv10_context)); - if (!nv10) + nv20 = CALLOC(1, sizeof(struct nv20_context)); + if (!nv20) return NULL; - nv10->screen = screen; - nv10->pctx_id = pctx_id; + nv20->screen = screen; + nv20->pctx_id = pctx_id; - nv10->nvws = nvws; + nv20->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; + nv20->pipe.winsys = ws; + nv20->pipe.screen = pscreen; + nv20->pipe.destroy = nv20_destroy; + nv20->pipe.set_edgeflags = nv20_set_edgeflags; + nv20->pipe.draw_arrays = nv20_draw_arrays; + nv20->pipe.draw_elements = nv20_draw_elements; + nv20->pipe.clear = nv20_clear; + nv20->pipe.flush = nv20_flush; - nv10_init_surface_functions(nv10); - nv10_init_state_functions(nv10); + nv20_init_surface_functions(nv20); + nv20_init_state_functions(nv20); - nv10->draw = draw_create(); - assert(nv10->draw); - draw_set_rasterize_stage(nv10->draw, nv10_draw_vbuf_stage(nv10)); + nv20->draw = draw_create(); + assert(nv20->draw); + draw_set_rasterize_stage(nv20->draw, nv20_draw_vbuf_stage(nv20)); - nv10_init_hwctx(nv10); + nv20_init_hwctx(nv20); - return &nv10->pipe; + return &nv20->pipe; } diff --git a/src/gallium/drivers/nv20/nv20_context.h b/src/gallium/drivers/nv20/nv20_context.h index f3b56de25a..8ad926db20 100644 --- a/src/gallium/drivers/nv20/nv20_context.h +++ b/src/gallium/drivers/nv20/nv20_context.h @@ -1,5 +1,5 @@ -#ifndef __NV10_CONTEXT_H__ -#define __NV10_CONTEXT_H__ +#ifndef __NV20_CONTEXT_H__ +#define __NV20_CONTEXT_H__ #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -15,42 +15,42 @@ #include "nouveau/nouveau_gldefs.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ - struct nv10_screen *ctx = nv10->screen + struct nv20_screen *ctx = nv20->screen #include "nouveau/nouveau_push.h" -#include "nv10_state.h" +#include "nv20_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) +#define NV20_NEW_VERTPROG (1 << 0) +#define NV20_NEW_FRAGPROG (1 << 1) +#define NV20_NEW_VTXARRAYS (1 << 2) +#define NV20_NEW_BLEND (1 << 3) +#define NV20_NEW_BLENDCOL (1 << 4) +#define NV20_NEW_RAST (1 << 5) +#define NV20_NEW_DSA (1 << 6) +#define NV20_NEW_VIEWPORT (1 << 7) +#define NV20_NEW_SCISSOR (1 << 8) +#define NV20_NEW_FRAMEBUFFER (1 << 9) -#include "nv10_screen.h" +#include "nv20_screen.h" -struct nv10_context { +struct nv20_context { struct pipe_context pipe; struct nouveau_winsys *nvws; - struct nv10_screen *screen; + struct nv20_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]; + struct nv20_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; + struct nv20_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; unsigned dirty_samplers; unsigned fp_samplers; unsigned vp_samplers; @@ -60,10 +60,10 @@ struct nv10_context { struct pipe_buffer *zeta; uint32_t lma_offset; - struct nv10_blend_state *blend; + struct nv20_blend_state *blend; struct pipe_blend_color *blend_color; - struct nv10_rasterizer_state *rast; - struct nv10_depth_stencil_alpha_state *dsa; + struct nv20_rasterizer_state *rast; + struct nv20_depth_stencil_alpha_state *dsa; struct pipe_viewport_state *viewport; struct pipe_scissor_state *scissor; struct pipe_framebuffer_state *framebuffer; @@ -90,15 +90,15 @@ struct nv10_context { struct nouveau_resource *exec_heap; struct nouveau_resource *data_heap; - struct nv10_vertex_program *active; + struct nv20_vertex_program *active; - struct nv10_vertex_program *current; + struct nv20_vertex_program *current; } vertprog; */ struct { - struct nv10_fragment_program *active; + struct nv20_fragment_program *active; - struct nv10_fragment_program *current; + struct nv20_fragment_program *current; struct pipe_buffer *constant_buf; } fragprog; @@ -106,45 +106,45 @@ struct nv10_context { struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; }; -static INLINE struct nv10_context * -nv10_context(struct pipe_context *pipe) +static INLINE struct nv20_context * +nv20_context(struct pipe_context *pipe) { - return (struct nv10_context *)pipe; + return (struct nv20_context *)pipe; } -extern void nv10_init_state_functions(struct nv10_context *nv10); -extern void nv10_init_surface_functions(struct nv10_context *nv10); +extern void nv20_init_state_functions(struct nv20_context *nv20); +extern void nv20_init_surface_functions(struct nv20_context *nv20); -extern void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen); +extern void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen); -/* nv10_clear.c */ -extern void nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, +/* nv20_clear.c */ +extern void nv20_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); +/* nv20_draw.c */ +extern struct draw_stage *nv20_draw_render_stage(struct nv20_context *nv20); -/* 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 *); +/* nv20_fragprog.c */ +extern void nv20_fragprog_bind(struct nv20_context *, + struct nv20_fragment_program *); +extern void nv20_fragprog_destroy(struct nv20_context *, + struct nv20_fragment_program *); -/* nv10_fragtex.c */ -extern void nv10_fragtex_bind(struct nv10_context *); +/* nv20_fragtex.c */ +extern void nv20_fragtex_bind(struct nv20_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); +/* nv20_prim_vbuf.c */ +struct draw_stage *nv20_draw_vbuf_stage( struct nv20_context *nv20 ); +extern void nv20_vtxbuf_bind(struct nv20_context* nv20); -/* 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); +/* nv20_state.c and friends */ +extern void nv20_emit_hw_state(struct nv20_context *nv20); +extern void nv20_state_tex_update(struct nv20_context *nv20); -/* nv10_vbo.c */ -extern boolean nv10_draw_arrays(struct pipe_context *, unsigned mode, +/* nv20_vbo.c */ +extern boolean nv20_draw_arrays(struct pipe_context *, unsigned mode, unsigned start, unsigned count); -extern boolean nv10_draw_elements( struct pipe_context *pipe, +extern boolean nv20_draw_elements( struct pipe_context *pipe, struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned prim, unsigned start, unsigned count); diff --git a/src/gallium/drivers/nv20/nv20_fragprog.c b/src/gallium/drivers/nv20/nv20_fragprog.c index 698db5a16a..4f496369dd 100644 --- a/src/gallium/drivers/nv20/nv20_fragprog.c +++ b/src/gallium/drivers/nv20/nv20_fragprog.c @@ -6,16 +6,16 @@ #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" -#include "nv10_context.h" +#include "nv20_context.h" void -nv10_fragprog_bind(struct nv10_context *nv10, struct nv10_fragment_program *fp) +nv20_fragprog_bind(struct nv20_context *nv20, struct nv20_fragment_program *fp) { } void -nv10_fragprog_destroy(struct nv10_context *nv10, - struct nv10_fragment_program *fp) +nv20_fragprog_destroy(struct nv20_context *nv20, + struct nv20_fragment_program *fp) { } diff --git a/src/gallium/drivers/nv20/nv20_fragtex.c b/src/gallium/drivers/nv20/nv20_fragtex.c index 238634d0bb..77c34897e2 100644 --- a/src/gallium/drivers/nv20/nv20_fragtex.c +++ b/src/gallium/drivers/nv20/nv20_fragtex.c @@ -1,4 +1,4 @@ -#include "nv10_context.h" +#include "nv20_context.h" static INLINE int log2i(int i) { @@ -33,14 +33,14 @@ static INLINE int log2i(int i) NV10TCL_TX_FORMAT_FORMAT_##tf, \ } -struct nv10_texture_format { +struct nv20_texture_format { boolean defined; uint pipe; int format; }; -static struct nv10_texture_format -nv10_texture_formats[] = { +static struct nv20_texture_format +nv20_texture_formats[] = { _(A8R8G8B8_UNORM, A8R8G8B8), _(A1R5G5B5_UNORM, A1R5G5B5), _(A4R4G4B4_UNORM, A4R4G4B4), @@ -54,10 +54,10 @@ nv10_texture_formats[] = { {}, }; -static struct nv10_texture_format * -nv10_fragtex_format(uint pipe_format) +static struct nv20_texture_format * +nv20_fragtex_format(uint pipe_format) { - struct nv10_texture_format *tf = nv10_texture_formats; + struct nv20_texture_format *tf = nv20_texture_formats; while (tf->defined) { if (tf->pipe == pipe_format) @@ -70,16 +70,16 @@ nv10_fragtex_format(uint pipe_format) static void -nv10_fragtex_build(struct nv10_context *nv10, int unit) +nv20_fragtex_build(struct nv20_context *nv20, 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; + struct nv20_sampler_state *ps = nv20->tex_sampler[unit]; + struct nv20_miptree *nv20mt = nv20->tex_miptree[unit]; + struct pipe_texture *pt = &nv20mt->base; + struct nv20_texture_format *tf; uint32_t txf, txs, txp; - tf = nv10_fragtex_format(pt->format); + tf = nv20_fragtex_format(pt->format); if (!tf || !tf->defined) { NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format); return; @@ -107,9 +107,9 @@ nv10_fragtex_build(struct nv10_context *nv10, int unit) 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*/); + BEGIN_RING(kelvin, NV10TCL_TX_OFFSET(unit), 8); + OUT_RELOCl(nv20mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCd(nv20mt->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); @@ -120,30 +120,30 @@ nv10_fragtex_build(struct nv10_context *nv10, int unit) } void -nv10_fragtex_bind(struct nv10_context *nv10) +nv20_fragtex_bind(struct nv20_context *nv20) { #if 0 - struct nv10_fragment_program *fp = nv10->fragprog.active; + struct nv20_fragment_program *fp = nv20->fragprog.active; unsigned samplers, unit; - samplers = nv10->fp_samplers & ~fp->samplers; + samplers = nv20->fp_samplers & ~fp->samplers; while (samplers) { unit = ffs(samplers) - 1; samplers &= ~(1 << unit); - BEGIN_RING(celsius, NV10TCL_TX_ENABLE(unit), 1); + BEGIN_RING(kelvin, NV10TCL_TX_ENABLE(unit), 1); OUT_RING (0); } - samplers = nv10->dirty_samplers & fp->samplers; + samplers = nv20->dirty_samplers & fp->samplers; while (samplers) { unit = ffs(samplers) - 1; samplers &= ~(1 << unit); - nv10_fragtex_build(nv10, unit); + nv20_fragtex_build(nv20, unit); } - nv10->fp_samplers = fp->samplers; + nv20->fp_samplers = fp->samplers; #endif } diff --git a/src/gallium/drivers/nv20/nv20_miptree.c b/src/gallium/drivers/nv20/nv20_miptree.c index ad084e72b8..dbfd779de9 100644 --- a/src/gallium/drivers/nv20/nv20_miptree.c +++ b/src/gallium/drivers/nv20/nv20_miptree.c @@ -2,13 +2,13 @@ #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "nv10_context.h" -#include "nv10_screen.h" +#include "nv20_context.h" +#include "nv20_screen.h" static void -nv10_miptree_layout(struct nv10_miptree *nv10mt) +nv20_miptree_layout(struct nv20_miptree *nv20mt) { - struct pipe_texture *pt = &nv10mt->base; + struct pipe_texture *pt = &nv20mt->base; boolean swizzled = FALSE; uint width = pt->width[0], height = pt->height[0]; uint offset = 0; @@ -27,12 +27,12 @@ nv10_miptree_layout(struct nv10_miptree *nv10mt) pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); if (swizzled) - nv10mt->level[l].pitch = pt->nblocksx[l] * pt->block.size; + nv20mt->level[l].pitch = pt->nblocksx[l] * pt->block.size; else - nv10mt->level[l].pitch = pt->nblocksx[0] * pt->block.size; - nv10mt->level[l].pitch = (nv10mt->level[l].pitch + 63) & ~63; + nv20mt->level[l].pitch = pt->nblocksx[0] * pt->block.size; + nv20mt->level[l].pitch = (nv20mt->level[l].pitch + 63) & ~63; - nv10mt->level[l].image_offset = + nv20mt->level[l].image_offset = CALLOC(nr_faces, sizeof(unsigned)); width = MAX2(1, width >> 1); @@ -42,28 +42,28 @@ nv10_miptree_layout(struct nv10_miptree *nv10mt) 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]; + nv20mt->level[l].image_offset[f] = offset; + offset += nv20mt->level[l].pitch * pt->height[l]; } } - nv10mt->total_size = offset; + nv20mt->total_size = offset; } static struct pipe_texture * -nv10_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) +nv20_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) { struct pipe_winsys *ws = screen->winsys; - struct nv10_miptree *mt; + struct nv20_miptree *mt; - mt = MALLOC(sizeof(struct nv10_miptree)); + mt = MALLOC(sizeof(struct nv20_miptree)); if (!mt) return NULL; mt->base = *pt; mt->base.refcount = 1; mt->base.screen = screen; - nv10_miptree_layout(mt); + nv20_miptree_layout(mt); mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, mt->total_size); @@ -76,72 +76,72 @@ nv10_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) } static void -nv10_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) +nv20_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) { struct pipe_texture *mt = *pt; *pt = NULL; if (--mt->refcount <= 0) { - struct nv10_miptree *nv10mt = (struct nv10_miptree *)mt; + struct nv20_miptree *nv20mt = (struct nv20_miptree *)mt; int l; - pipe_buffer_reference(screen, &nv10mt->buffer, NULL); + pipe_buffer_reference(screen, &nv20mt->buffer, NULL); for (l = 0; l <= mt->last_level; l++) { - if (nv10mt->level[l].image_offset) - FREE(nv10mt->level[l].image_offset); + if (nv20mt->level[l].image_offset) + FREE(nv20mt->level[l].image_offset); } - FREE(nv10mt); + FREE(nv20mt); } } static void -nv10_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, +nv20_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, +nv20_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 nv20_miptree *nv20mt = (struct nv20_miptree *)pt; struct pipe_surface *ps; ps = ws->surface_alloc(ws); if (!ps) return NULL; - pipe_buffer_reference(screen, &ps->buffer, nv10mt->buffer); + pipe_buffer_reference(screen, &ps->buffer, nv20mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; ps->height = pt->height[level]; ps->block = pt->block; ps->nblocksx = pt->nblocksx[level]; ps->nblocksy = pt->nblocksy[level]; - ps->stride = nv10mt->level[level].pitch; + ps->stride = nv20mt->level[level].pitch; if (pt->target == PIPE_TEXTURE_CUBE) { - ps->offset = nv10mt->level[level].image_offset[face]; + ps->offset = nv20mt->level[level].image_offset[face]; } else { - ps->offset = nv10mt->level[level].image_offset[0]; + ps->offset = nv20mt->level[level].image_offset[0]; } return ps; } static void -nv10_miptree_surface_release(struct pipe_screen *screen, +nv20_miptree_surface_release(struct pipe_screen *screen, struct pipe_surface **surface) { } -void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen) +void nv20_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; + pscreen->texture_create = nv20_miptree_create; + pscreen->texture_release = nv20_miptree_release; + pscreen->get_tex_surface = nv20_miptree_surface_get; + pscreen->tex_surface_release = nv20_miptree_surface_release; } diff --git a/src/gallium/drivers/nv20/nv20_prim_vbuf.c b/src/gallium/drivers/nv20/nv20_prim_vbuf.c index 62a8f6d89d..a51d657d27 100644 --- a/src/gallium/drivers/nv20/nv20_prim_vbuf.c +++ b/src/gallium/drivers/nv20/nv20_prim_vbuf.c @@ -42,18 +42,18 @@ #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "nv10_context.h" -#include "nv10_state.h" +#include "nv20_context.h" +#include "nv20_state.h" #include "draw/draw_vbuf.h" /** - * Primitive renderer for nv10. + * Primitive renderer for nv20. */ -struct nv10_vbuf_render { +struct nv20_vbuf_render { struct vbuf_render base; - struct nv10_context *nv10; + struct nv20_context *nv20; /** Vertex buffer */ struct pipe_buffer* buffer; @@ -66,13 +66,13 @@ struct nv10_vbuf_render { }; -void nv10_vtxbuf_bind( struct nv10_context* nv10 ) +void nv20_vtxbuf_bind( struct nv20_context* nv20 ) { 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); + BEGIN_RING(kelvin, NV10TCL_VERTEX_ARRAY_ATTRIB_OFFSET(i), 1); + OUT_RING(0/*nv20->vtxbuf*/); + BEGIN_RING(kelvin, NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT(i) ,1); OUT_RING(0/*XXX*/); } } @@ -80,75 +80,75 @@ void nv10_vtxbuf_bind( struct nv10_context* nv10 ) /** * Basically a cast wrapper. */ -static INLINE struct nv10_vbuf_render * -nv10_vbuf_render( struct vbuf_render *render ) +static INLINE struct nv20_vbuf_render * +nv20_vbuf_render( struct vbuf_render *render ) { assert(render); - return (struct nv10_vbuf_render *)render; + return (struct nv20_vbuf_render *)render; } static const struct vertex_info * -nv10_vbuf_render_get_vertex_info( struct vbuf_render *render ) +nv20_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; + struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); + struct nv20_context *nv20 = nv20_render->nv20; - nv10_emit_hw_state(nv10); + nv20_emit_hw_state(nv20); - return &nv10->vertex_info; + return &nv20->vertex_info; } static void * -nv10_vbuf_render_allocate_vertices( struct vbuf_render *render, +nv20_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; + struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); + struct nv20_context *nv20 = nv20_render->nv20; + struct pipe_winsys *winsys = nv20->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); + assert(!nv20_render->buffer); + nv20_render->buffer = winsys->buffer_create(winsys, 64, PIPE_BUFFER_USAGE_VERTEX, size); - nv10->dirty |= NV10_NEW_VTXARRAYS; + nv20->dirty |= NV20_NEW_VTXARRAYS; return winsys->buffer_map(winsys, - nv10_render->buffer, + nv20_render->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); } static void -nv10_vbuf_render_set_primitive( struct vbuf_render *render, +nv20_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; + struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); + nv20_render->hwprim = prim + 1; } static void -nv10_vbuf_render_draw( struct vbuf_render *render, +nv20_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; + struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); + struct nv20_context *nv20 = nv20_render->nv20; int push, i; - nv10_emit_hw_state(nv10); + nv20_emit_hw_state(nv20); - 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(kelvin, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1); + OUT_RELOCl(nv20_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); + BEGIN_RING(kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); + OUT_RING(nv20_render->hwprim); if (nr_indices & 1) { - BEGIN_RING(celsius, NV10TCL_VB_ELEMENT_U32, 1); + BEGIN_RING(kelvin, NV10TCL_VB_ELEMENT_U32, 1); OUT_RING (indices[0]); indices++; nr_indices--; } @@ -157,7 +157,7 @@ nv10_vbuf_render_draw( struct vbuf_render *render, // XXX too big/small ? check the size push = MIN2(nr_indices, 1200 * 2); - BEGIN_RING_NI(celsius, NV10TCL_VB_ELEMENT_U16, push >> 1); + BEGIN_RING_NI(kelvin, NV10TCL_VB_ELEMENT_U16, push >> 1); for (i = 0; i < push; i+=2) OUT_RING((indices[i+1] << 16) | indices[i]); @@ -165,33 +165,33 @@ nv10_vbuf_render_draw( struct vbuf_render *render, indices += push; } - BEGIN_RING(celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); + BEGIN_RING(kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); OUT_RING (0); } static void -nv10_vbuf_render_release_vertices( struct vbuf_render *render, +nv20_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; - struct pipe_screen *pscreen = &nv10->screen->pipe; - - assert(nv10_render->buffer); - winsys->buffer_unmap(winsys, nv10_render->buffer); - pipe_buffer_reference(pscreen, &nv10_render->buffer, NULL); + struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); + struct nv20_context *nv20 = nv20_render->nv20; + struct pipe_winsys *winsys = nv20->pipe.winsys; + struct pipe_screen *pscreen = &nv20->screen->pipe; + + assert(nv20_render->buffer); + winsys->buffer_unmap(winsys, nv20_render->buffer); + pipe_buffer_reference(pscreen, &nv20_render->buffer, NULL); } static void -nv10_vbuf_render_destroy( struct vbuf_render *render ) +nv20_vbuf_render_destroy( struct vbuf_render *render ) { - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - FREE(nv10_render); + struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); + FREE(nv20_render); } @@ -199,38 +199,38 @@ nv10_vbuf_render_destroy( struct vbuf_render *render ) * Create a new primitive render. */ static struct vbuf_render * -nv10_vbuf_render_create( struct nv10_context *nv10 ) +nv20_vbuf_render_create( struct nv20_context *nv20 ) { - struct nv10_vbuf_render *nv10_render = CALLOC_STRUCT(nv10_vbuf_render); + struct nv20_vbuf_render *nv20_render = CALLOC_STRUCT(nv20_vbuf_render); - nv10_render->nv10 = nv10; + nv20_render->nv20 = nv20; - 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; + nv20_render->base.max_vertex_buffer_bytes = 16*1024; + nv20_render->base.max_indices = 1024; + nv20_render->base.get_vertex_info = nv20_vbuf_render_get_vertex_info; + nv20_render->base.allocate_vertices = nv20_vbuf_render_allocate_vertices; + nv20_render->base.set_primitive = nv20_vbuf_render_set_primitive; + nv20_render->base.draw = nv20_vbuf_render_draw; + nv20_render->base.release_vertices = nv20_vbuf_render_release_vertices; + nv20_render->base.destroy = nv20_vbuf_render_destroy; - return &nv10_render->base; + return &nv20_render->base; } /** * Create a new primitive vbuf/render stage. */ -struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 ) +struct draw_stage *nv20_draw_vbuf_stage( struct nv20_context *nv20 ) { struct vbuf_render *render; struct draw_stage *stage; - render = nv10_vbuf_render_create(nv10); + render = nv20_vbuf_render_create(nv20); if(!render) return NULL; - stage = draw_vbuf_stage( nv10->draw, render ); + stage = draw_vbuf_stage( nv20->draw, render ); if(!stage) { render->destroy(render); return NULL; diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c index 27a9edf9bb..b7f5ea8512 100644 --- a/src/gallium/drivers/nv20/nv20_screen.c +++ b/src/gallium/drivers/nv20/nv20_screen.c @@ -1,13 +1,13 @@ #include "pipe/p_screen.h" -#include "nv10_context.h" -#include "nv10_screen.h" +#include "nv20_context.h" +#include "nv20_screen.h" static const char * -nv10_screen_get_name(struct pipe_screen *screen) +nv20_screen_get_name(struct pipe_screen *screen) { - struct nv10_screen *nv10screen = nv10_screen(screen); - struct nouveau_device *dev = nv10screen->nvws->channel->device; + struct nv20_screen *nv20screen = nv20_screen(screen); + struct nouveau_device *dev = nv20screen->nvws->channel->device; static char buffer[128]; snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); @@ -15,13 +15,13 @@ nv10_screen_get_name(struct pipe_screen *screen) } static const char * -nv10_screen_get_vendor(struct pipe_screen *screen) +nv20_screen_get_vendor(struct pipe_screen *screen) { return "nouveau"; } static int -nv10_screen_get_param(struct pipe_screen *screen, int param) +nv20_screen_get_param(struct pipe_screen *screen, int param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: @@ -60,7 +60,7 @@ nv10_screen_get_param(struct pipe_screen *screen, int param) } static float -nv10_screen_get_paramf(struct pipe_screen *screen, int param) +nv20_screen_get_paramf(struct pipe_screen *screen, int param) { switch (param) { case PIPE_CAP_MAX_LINE_WIDTH: @@ -80,7 +80,7 @@ nv10_screen_get_paramf(struct pipe_screen *screen, int param) } static boolean -nv10_screen_is_format_supported(struct pipe_screen *screen, +nv20_screen_is_format_supported(struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, unsigned tex_usage, unsigned geom_flags) @@ -114,7 +114,7 @@ nv10_screen_is_format_supported(struct pipe_screen *screen, } static void * -nv10_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, +nv20_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, unsigned flags ) { struct pipe_winsys *ws = screen->winsys; @@ -128,7 +128,7 @@ nv10_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, } static void -nv10_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) +nv20_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) { struct pipe_winsys *ws = screen->winsys; @@ -136,21 +136,21 @@ nv10_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) } static void -nv10_screen_destroy(struct pipe_screen *pscreen) +nv20_screen_destroy(struct pipe_screen *pscreen) { - struct nv10_screen *screen = nv10_screen(pscreen); + struct nv20_screen *screen = nv20_screen(pscreen); struct nouveau_winsys *nvws = screen->nvws; nvws->notifier_free(&screen->sync); - nvws->grobj_free(&screen->celsius); + nvws->grobj_free(&screen->kelvin); FREE(pscreen); } struct pipe_screen * -nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) +nv20_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) { - struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen); + struct nv20_screen *screen = CALLOC_STRUCT(nv20_screen); unsigned celsius_class; unsigned chipset = nvws->channel->device->chipset; int ret; @@ -174,7 +174,7 @@ nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) return NULL; } - ret = nvws->grobj_alloc(nvws, celsius_class, &screen->celsius); + ret = nvws->grobj_alloc(nvws, celsius_class, &screen->kelvin); if (ret) { NOUVEAU_ERR("Error creating 3D object: %d\n", ret); return FALSE; @@ -184,24 +184,24 @@ nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) ret = nvws->notifier_alloc(nvws, 1, &screen->sync); if (ret) { NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv10_screen_destroy(&screen->pipe); + nv20_screen_destroy(&screen->pipe); return NULL; } screen->pipe.winsys = ws; - screen->pipe.destroy = nv10_screen_destroy; + screen->pipe.destroy = nv20_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.get_name = nv20_screen_get_name; + screen->pipe.get_vendor = nv20_screen_get_vendor; + screen->pipe.get_param = nv20_screen_get_param; + screen->pipe.get_paramf = nv20_screen_get_paramf; - screen->pipe.is_format_supported = nv10_screen_is_format_supported; + screen->pipe.is_format_supported = nv20_screen_is_format_supported; - screen->pipe.surface_map = nv10_surface_map; - screen->pipe.surface_unmap = nv10_surface_unmap; + screen->pipe.surface_map = nv20_surface_map; + screen->pipe.surface_unmap = nv20_surface_unmap; - nv10_screen_init_miptree_functions(&screen->pipe); + nv20_screen_init_miptree_functions(&screen->pipe); return &screen->pipe; } diff --git a/src/gallium/drivers/nv20/nv20_screen.h b/src/gallium/drivers/nv20/nv20_screen.h index 3f8750a13f..8f2f2e341d 100644 --- a/src/gallium/drivers/nv20/nv20_screen.h +++ b/src/gallium/drivers/nv20/nv20_screen.h @@ -1,22 +1,22 @@ -#ifndef __NV10_SCREEN_H__ -#define __NV10_SCREEN_H__ +#ifndef __NV20_SCREEN_H__ +#define __NV20_SCREEN_H__ #include "pipe/p_screen.h" -struct nv10_screen { +struct nv20_screen { struct pipe_screen pipe; struct nouveau_winsys *nvws; /* HW graphics objects */ - struct nouveau_grobj *celsius; + struct nouveau_grobj *kelvin; struct nouveau_notifier *sync; }; -static INLINE struct nv10_screen * -nv10_screen(struct pipe_screen *screen) +static INLINE struct nv20_screen * +nv20_screen(struct pipe_screen *screen) { - return (struct nv10_screen *)screen; + return (struct nv20_screen *)screen; } #endif diff --git a/src/gallium/drivers/nv20/nv20_state.c b/src/gallium/drivers/nv20/nv20_state.c index d2375aa2f6..c3b87230b7 100644 --- a/src/gallium/drivers/nv20/nv20_state.c +++ b/src/gallium/drivers/nv20/nv20_state.c @@ -5,16 +5,16 @@ #include "tgsi/tgsi_parse.h" -#include "nv10_context.h" -#include "nv10_state.h" +#include "nv20_context.h" +#include "nv20_state.h" static void * -nv10_blend_state_create(struct pipe_context *pipe, +nv20_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) { - struct nv10_blend_state *cb; + struct nv20_blend_state *cb; - cb = MALLOC(sizeof(struct nv10_blend_state)); + cb = MALLOC(sizeof(struct nv20_blend_state)); cb->b_enable = cso->blend_enable ? 1 : 0; cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | @@ -33,17 +33,17 @@ nv10_blend_state_create(struct pipe_context *pipe, } static void -nv10_blend_state_bind(struct pipe_context *pipe, void *blend) +nv20_blend_state_bind(struct pipe_context *pipe, void *blend) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - nv10->blend = (struct nv10_blend_state*)blend; + nv20->blend = (struct nv20_blend_state*)blend; - nv10->dirty |= NV10_NEW_BLEND; + nv20->dirty |= NV20_NEW_BLEND; } static void -nv10_blend_state_delete(struct pipe_context *pipe, void *hwcso) +nv20_blend_state_delete(struct pipe_context *pipe, void *hwcso) { FREE(hwcso); } @@ -82,13 +82,13 @@ wrap_mode(unsigned wrap) { } static void * -nv10_sampler_state_create(struct pipe_context *pipe, +nv20_sampler_state_create(struct pipe_context *pipe, const struct pipe_sampler_state *cso) { - struct nv10_sampler_state *ps; + struct nv20_sampler_state *ps; uint32_t filter = 0; - ps = MALLOC(sizeof(struct nv10_sampler_state)); + ps = MALLOC(sizeof(struct nv20_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)); @@ -204,41 +204,41 @@ nv10_sampler_state_create(struct pipe_context *pipe, } static void -nv10_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) +nv20_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); unsigned unit; for (unit = 0; unit < nr; unit++) { - nv10->tex_sampler[unit] = sampler[unit]; - nv10->dirty_samplers |= (1 << unit); + nv20->tex_sampler[unit] = sampler[unit]; + nv20->dirty_samplers |= (1 << unit); } } static void -nv10_sampler_state_delete(struct pipe_context *pipe, void *hwcso) +nv20_sampler_state_delete(struct pipe_context *pipe, void *hwcso) { FREE(hwcso); } static void -nv10_set_sampler_texture(struct pipe_context *pipe, unsigned nr, +nv20_set_sampler_texture(struct pipe_context *pipe, unsigned nr, struct pipe_texture **miptree) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); unsigned unit; for (unit = 0; unit < nr; unit++) { - nv10->tex_miptree[unit] = (struct nv10_miptree *)miptree[unit]; - nv10->dirty_samplers |= (1 << unit); + nv20->tex_miptree[unit] = (struct nv20_miptree *)miptree[unit]; + nv20->dirty_samplers |= (1 << unit); } } static void * -nv10_rasterizer_state_create(struct pipe_context *pipe, +nv20_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { - struct nv10_rasterizer_state *rs; + struct nv20_rasterizer_state *rs; int i; /*XXX: ignored: @@ -249,7 +249,7 @@ nv10_rasterizer_state_create(struct pipe_context *pipe, * multisample * offset_units / offset_scale */ - rs = MALLOC(sizeof(struct nv10_rasterizer_state)); + rs = MALLOC(sizeof(struct nv20_rasterizer_state)); rs->templ = cso; @@ -312,30 +312,30 @@ nv10_rasterizer_state_create(struct pipe_context *pipe, } static void -nv10_rasterizer_state_bind(struct pipe_context *pipe, void *rast) +nv20_rasterizer_state_bind(struct pipe_context *pipe, void *rast) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - nv10->rast = (struct nv10_rasterizer_state*)rast; + nv20->rast = (struct nv20_rasterizer_state*)rast; - draw_set_rasterizer_state(nv10->draw, (nv10->rast ? nv10->rast->templ : NULL)); + draw_set_rasterizer_state(nv20->draw, (nv20->rast ? nv20->rast->templ : NULL)); - nv10->dirty |= NV10_NEW_RAST; + nv20->dirty |= NV20_NEW_RAST; } static void -nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +nv20_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) { FREE(hwcso); } static void * -nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe, +nv20_depth_stencil_alpha_state_create(struct pipe_context *pipe, const struct pipe_depth_stencil_alpha_state *cso) { - struct nv10_depth_stencil_alpha_state *hw; + struct nv20_depth_stencil_alpha_state *hw; - hw = MALLOC(sizeof(struct nv10_depth_stencil_alpha_state)); + hw = MALLOC(sizeof(struct nv20_depth_stencil_alpha_state)); hw->depth.func = nvgl_comparison_op(cso->depth.func); hw->depth.write_enable = cso->depth.writemask ? 1 : 0; @@ -358,55 +358,55 @@ nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe, } static void -nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa) +nv20_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - nv10->dsa = (struct nv10_depth_stencil_alpha_state*)dsa; + nv20->dsa = (struct nv20_depth_stencil_alpha_state*)dsa; - nv10->dirty |= NV10_NEW_DSA; + nv20->dirty |= NV20_NEW_DSA; } static void -nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +nv20_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) { FREE(hwcso); } static void * -nv10_vp_state_create(struct pipe_context *pipe, +nv20_vp_state_create(struct pipe_context *pipe, const struct pipe_shader_state *templ) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - return draw_create_vertex_shader(nv10->draw, templ); + return draw_create_vertex_shader(nv20->draw, templ); } static void -nv10_vp_state_bind(struct pipe_context *pipe, void *shader) +nv20_vp_state_bind(struct pipe_context *pipe, void *shader) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - draw_bind_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader); + draw_bind_vertex_shader(nv20->draw, (struct draw_vertex_shader *) shader); - nv10->dirty |= NV10_NEW_VERTPROG; + nv20->dirty |= NV20_NEW_VERTPROG; } static void -nv10_vp_state_delete(struct pipe_context *pipe, void *shader) +nv20_vp_state_delete(struct pipe_context *pipe, void *shader) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - draw_delete_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader); + draw_delete_vertex_shader(nv20->draw, (struct draw_vertex_shader *) shader); } static void * -nv10_fp_state_create(struct pipe_context *pipe, +nv20_fp_state_create(struct pipe_context *pipe, const struct pipe_shader_state *cso) { - struct nv10_fragment_program *fp; + struct nv20_fragment_program *fp; - fp = CALLOC(1, sizeof(struct nv10_fragment_program)); + fp = CALLOC(1, sizeof(struct nv20_fragment_program)); fp->pipe.tokens = tgsi_dup_tokens(cso->tokens); tgsi_scan_shader(cso->tokens, &fp->info); @@ -415,51 +415,51 @@ nv10_fp_state_create(struct pipe_context *pipe, } static void -nv10_fp_state_bind(struct pipe_context *pipe, void *hwcso) +nv20_fp_state_bind(struct pipe_context *pipe, void *hwcso) { - struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_fragment_program *fp = hwcso; + struct nv20_context *nv20 = nv20_context(pipe); + struct nv20_fragment_program *fp = hwcso; - nv10->fragprog.current = fp; - nv10->dirty |= NV10_NEW_FRAGPROG; + nv20->fragprog.current = fp; + nv20->dirty |= NV20_NEW_FRAGPROG; } static void -nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso) +nv20_fp_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_fragment_program *fp = hwcso; + struct nv20_context *nv20 = nv20_context(pipe); + struct nv20_fragment_program *fp = hwcso; - nv10_fragprog_destroy(nv10, fp); + nv20_fragprog_destroy(nv20, fp); FREE((void*)fp->pipe.tokens); FREE(fp); } static void -nv10_set_blend_color(struct pipe_context *pipe, +nv20_set_blend_color(struct pipe_context *pipe, const struct pipe_blend_color *bcol) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - nv10->blend_color = (struct pipe_blend_color*)bcol; + nv20->blend_color = (struct pipe_blend_color*)bcol; - nv10->dirty |= NV10_NEW_BLENDCOL; + nv20->dirty |= NV20_NEW_BLENDCOL; } static void -nv10_set_clip_state(struct pipe_context *pipe, +nv20_set_clip_state(struct pipe_context *pipe, const struct pipe_clip_state *clip) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - draw_set_clip_state(nv10->draw, clip); + draw_set_clip_state(nv20->draw, clip); } static void -nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, +nv20_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 nv20_context *nv20 = nv20_context(pipe); struct pipe_winsys *ws = pipe->winsys; assert(shader < PIPE_SHADER_TYPES); @@ -469,8 +469,8 @@ nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, 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] = + memcpy(nv20->constbuf[shader], mapped, buf->size); + nv20->constbuf_nr[shader] = buf->size / (4 * sizeof(float)); ws->buffer_unmap(ws, buf->buffer); } @@ -478,111 +478,111 @@ nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, } static void -nv10_set_framebuffer_state(struct pipe_context *pipe, +nv20_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - nv10->framebuffer = (struct pipe_framebuffer_state*)fb; + nv20->framebuffer = (struct pipe_framebuffer_state*)fb; - nv10->dirty |= NV10_NEW_FRAMEBUFFER; + nv20->dirty |= NV20_NEW_FRAMEBUFFER; } static void -nv10_set_polygon_stipple(struct pipe_context *pipe, +nv20_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, +nv20_set_scissor_state(struct pipe_context *pipe, const struct pipe_scissor_state *s) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - nv10->scissor = (struct pipe_scissor_state*)s; + nv20->scissor = (struct pipe_scissor_state*)s; - nv10->dirty |= NV10_NEW_SCISSOR; + nv20->dirty |= NV20_NEW_SCISSOR; } static void -nv10_set_viewport_state(struct pipe_context *pipe, +nv20_set_viewport_state(struct pipe_context *pipe, const struct pipe_viewport_state *vpt) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - nv10->viewport = (struct pipe_viewport_state*)vpt; + nv20->viewport = (struct pipe_viewport_state*)vpt; - draw_set_viewport_state(nv10->draw, nv10->viewport); + draw_set_viewport_state(nv20->draw, nv20->viewport); - nv10->dirty |= NV10_NEW_VIEWPORT; + nv20->dirty |= NV20_NEW_VIEWPORT; } static void -nv10_set_vertex_buffers(struct pipe_context *pipe, unsigned count, +nv20_set_vertex_buffers(struct pipe_context *pipe, unsigned count, const struct pipe_vertex_buffer *vb) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - memcpy(nv10->vtxbuf, vb, sizeof(*vb) * count); - nv10->dirty |= NV10_NEW_VTXARRAYS; + memcpy(nv20->vtxbuf, vb, sizeof(*vb) * count); + nv20->dirty |= NV20_NEW_VTXARRAYS; - draw_set_vertex_buffers(nv10->draw, count, vb); + draw_set_vertex_buffers(nv20->draw, count, vb); } static void -nv10_set_vertex_elements(struct pipe_context *pipe, unsigned count, +nv20_set_vertex_elements(struct pipe_context *pipe, unsigned count, const struct pipe_vertex_element *ve) { - struct nv10_context *nv10 = nv10_context(pipe); + struct nv20_context *nv20 = nv20_context(pipe); - memcpy(nv10->vtxelt, ve, sizeof(*ve) * count); - nv10->dirty |= NV10_NEW_VTXARRAYS; + memcpy(nv20->vtxelt, ve, sizeof(*ve) * count); + nv20->dirty |= NV20_NEW_VTXARRAYS; - draw_set_vertex_elements(nv10->draw, count, ve); + draw_set_vertex_elements(nv20->draw, count, ve); } void -nv10_init_state_functions(struct nv10_context *nv10) +nv20_init_state_functions(struct nv20_context *nv20) { - 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; + nv20->pipe.create_blend_state = nv20_blend_state_create; + nv20->pipe.bind_blend_state = nv20_blend_state_bind; + nv20->pipe.delete_blend_state = nv20_blend_state_delete; + + nv20->pipe.create_sampler_state = nv20_sampler_state_create; + nv20->pipe.bind_sampler_states = nv20_sampler_state_bind; + nv20->pipe.delete_sampler_state = nv20_sampler_state_delete; + nv20->pipe.set_sampler_textures = nv20_set_sampler_texture; + + nv20->pipe.create_rasterizer_state = nv20_rasterizer_state_create; + nv20->pipe.bind_rasterizer_state = nv20_rasterizer_state_bind; + nv20->pipe.delete_rasterizer_state = nv20_rasterizer_state_delete; + + nv20->pipe.create_depth_stencil_alpha_state = + nv20_depth_stencil_alpha_state_create; + nv20->pipe.bind_depth_stencil_alpha_state = + nv20_depth_stencil_alpha_state_bind; + nv20->pipe.delete_depth_stencil_alpha_state = + nv20_depth_stencil_alpha_state_delete; + + nv20->pipe.create_vs_state = nv20_vp_state_create; + nv20->pipe.bind_vs_state = nv20_vp_state_bind; + nv20->pipe.delete_vs_state = nv20_vp_state_delete; + + nv20->pipe.create_fs_state = nv20_fp_state_create; + nv20->pipe.bind_fs_state = nv20_fp_state_bind; + nv20->pipe.delete_fs_state = nv20_fp_state_delete; + + nv20->pipe.set_blend_color = nv20_set_blend_color; + nv20->pipe.set_clip_state = nv20_set_clip_state; + nv20->pipe.set_constant_buffer = nv20_set_constant_buffer; + nv20->pipe.set_framebuffer_state = nv20_set_framebuffer_state; + nv20->pipe.set_polygon_stipple = nv20_set_polygon_stipple; + nv20->pipe.set_scissor_state = nv20_set_scissor_state; + nv20->pipe.set_viewport_state = nv20_set_viewport_state; + + nv20->pipe.set_vertex_buffers = nv20_set_vertex_buffers; + nv20->pipe.set_vertex_elements = nv20_set_vertex_elements; } diff --git a/src/gallium/drivers/nv20/nv20_state.h b/src/gallium/drivers/nv20/nv20_state.h index 3a3fd0d4f4..34f402fdcb 100644 --- a/src/gallium/drivers/nv20/nv20_state.h +++ b/src/gallium/drivers/nv20/nv20_state.h @@ -1,10 +1,10 @@ -#ifndef __NV10_STATE_H__ -#define __NV10_STATE_H__ +#ifndef __NV20_STATE_H__ +#define __NV20_STATE_H__ #include "pipe/p_state.h" #include "tgsi/tgsi_scan.h" -struct nv10_blend_state { +struct nv20_blend_state { uint32_t b_enable; uint32_t b_srcfunc; uint32_t b_dstfunc; @@ -14,14 +14,14 @@ struct nv10_blend_state { uint32_t d_enable; }; -struct nv10_sampler_state { +struct nv20_sampler_state { uint32_t wrap; uint32_t en; uint32_t filt; uint32_t bcol; }; -struct nv10_rasterizer_state { +struct nv20_rasterizer_state { uint32_t shade_model; uint32_t line_width; @@ -43,24 +43,24 @@ struct nv10_rasterizer_state { const struct pipe_rasterizer_state *templ; }; -struct nv10_vertex_program_exec { +struct nv20_vertex_program_exec { uint32_t data[4]; boolean has_branch_offset; int const_index; }; -struct nv10_vertex_program_data { +struct nv20_vertex_program_data { int index; /* immediates == -1 */ float value[4]; }; -struct nv10_vertex_program { +struct nv20_vertex_program { const struct pipe_shader_state *pipe; boolean translated; - struct nv10_vertex_program_exec *insns; + struct nv20_vertex_program_exec *insns; unsigned nr_insns; - struct nv10_vertex_program_data *consts; + struct nv20_vertex_program_data *consts; unsigned nr_consts; struct nouveau_resource *exec; @@ -73,12 +73,12 @@ struct nv10_vertex_program { uint32_t or; }; -struct nv10_fragment_program_data { +struct nv20_fragment_program_data { unsigned offset; unsigned index; }; -struct nv10_fragment_program { +struct nv20_fragment_program { struct pipe_shader_state pipe; struct tgsi_shader_info info; @@ -89,7 +89,7 @@ struct nv10_fragment_program { uint32_t *insn; int insn_len; - struct nv10_fragment_program_data *consts; + struct nv20_fragment_program_data *consts; unsigned nr_consts; struct pipe_buffer *buffer; @@ -99,7 +99,7 @@ struct nv10_fragment_program { }; -struct nv10_depth_stencil_alpha_state { +struct nv20_depth_stencil_alpha_state { struct { uint32_t func; uint32_t write_enable; @@ -124,7 +124,7 @@ struct nv10_depth_stencil_alpha_state { } alpha; }; -struct nv10_miptree { +struct nv20_miptree { struct pipe_texture base; struct pipe_buffer *buffer; diff --git a/src/gallium/drivers/nv20/nv20_state_emit.c b/src/gallium/drivers/nv20/nv20_state_emit.c index 46c7e1d753..23029433f3 100644 --- a/src/gallium/drivers/nv20/nv20_state_emit.c +++ b/src/gallium/drivers/nv20/nv20_state_emit.c @@ -1,108 +1,108 @@ -#include "nv10_context.h" -#include "nv10_state.h" +#include "nv20_context.h" +#include "nv20_state.h" -static void nv10_state_emit_blend(struct nv10_context* nv10) +static void nv20_state_emit_blend(struct nv20_context* nv20) { - struct nv10_blend_state *b = nv10->blend; + struct nv20_blend_state *b = nv20->blend; - BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_DITHER_ENABLE, 1); OUT_RING (b->d_enable); - BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 3); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, NV10TCL_COLOR_MASK, 1); OUT_RING (b->c_mask); } -static void nv10_state_emit_blend_color(struct nv10_context* nv10) +static void nv20_state_emit_blend_color(struct nv20_context* nv20) { - struct pipe_blend_color *c = nv10->blend_color; + struct pipe_blend_color *c = nv20->blend_color; - BEGIN_RING(celsius, NV10TCL_BLEND_COLOR, 1); + BEGIN_RING(kelvin, 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) +static void nv20_state_emit_rast(struct nv20_context* nv20) { - struct nv10_rasterizer_state *r = nv10->rast; + struct nv20_rasterizer_state *r = nv20->rast; - BEGIN_RING(celsius, NV10TCL_SHADE_MODEL, 2); + BEGIN_RING(kelvin, NV10TCL_SHADE_MODEL, 2); OUT_RING (r->shade_model); OUT_RING (r->line_width); - BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); + BEGIN_RING(kelvin, NV10TCL_POINT_SIZE, 1); OUT_RING (r->point_size); - BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + BEGIN_RING(kelvin, NV10TCL_POLYGON_MODE_FRONT, 2); OUT_RING (r->poly_mode_front); OUT_RING (r->poly_mode_back); - BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); + BEGIN_RING(kelvin, NV10TCL_CULL_FACE, 2); OUT_RING (r->cull_face); OUT_RING (r->front_face); - BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, NV10TCL_CULL_FACE_ENABLE, 1); OUT_RING (r->cull_face_en); } -static void nv10_state_emit_dsa(struct nv10_context* nv10) +static void nv20_state_emit_dsa(struct nv20_context* nv20) { - struct nv10_depth_stencil_alpha_state *d = nv10->dsa; + struct nv20_depth_stencil_alpha_state *d = nv20->dsa; - BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 1); + BEGIN_RING(kelvin, NV10TCL_DEPTH_FUNC, 1); OUT_RING (d->depth.func); - BEGIN_RING(celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_DEPTH_WRITE_ENABLE, 1); OUT_RING (d->depth.write_enable); - BEGIN_RING(celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_DEPTH_TEST_ENABLE, 1); OUT_RING (d->depth.test_enable); #if 0 - BEGIN_RING(celsius, NV10TCL_STENCIL_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_STENCIL_ENABLE, 1); OUT_RING (d->stencil.enable); - BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 7); + BEGIN_RING(kelvin, NV10TCL_STENCIL_MASK, 7); OUT_RINGp ((uint32_t *)&(d->stencil.wmask), 7); #endif - BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + BEGIN_RING(kelvin, NV10TCL_ALPHA_FUNC_ENABLE, 1); OUT_RING (d->alpha.enabled); - BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_FUNC, 1); + BEGIN_RING(kelvin, NV10TCL_ALPHA_FUNC_FUNC, 1); OUT_RING (d->alpha.func); - BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_REF, 1); + BEGIN_RING(kelvin, NV10TCL_ALPHA_FUNC_REF, 1); OUT_RING (d->alpha.ref); } -static void nv10_state_emit_viewport(struct nv10_context* nv10) +static void nv20_state_emit_viewport(struct nv20_context* nv20) { } -static void nv10_state_emit_scissor(struct nv10_context* nv10) +static void nv20_state_emit_scissor(struct nv20_context* nv20) { // XXX this is so not working -/* struct pipe_scissor_state *s = nv10->scissor; - BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2); +/* struct pipe_scissor_state *s = nv20->scissor; + BEGIN_RING(kelvin, 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) +static void nv20_state_emit_framebuffer(struct nv20_context* nv20) { - struct pipe_framebuffer_state* fb = nv10->framebuffer; + struct pipe_framebuffer_state* fb = nv20->framebuffer; struct pipe_surface *rt, *zeta = NULL; uint32_t rt_format, w, h; int colour_format = 0, zeta_format = 0; @@ -140,32 +140,32 @@ static void nv10_state_emit_framebuffer(struct nv10_context* nv10) } if (zeta) { - BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); + BEGIN_RING(kelvin, NV10TCL_RT_PITCH, 1); OUT_RING (rt->stride | (zeta->stride << 16)); } else { - BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); + BEGIN_RING(kelvin, NV10TCL_RT_PITCH, 1); OUT_RING (rt->stride | (rt->stride << 16)); } - nv10->rt[0] = rt->buffer; + nv20->rt[0] = rt->buffer; if (zeta_format) { - nv10->zeta = zeta->buffer; + nv20->zeta = zeta->buffer; } - BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 3); + BEGIN_RING(kelvin, 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); + BEGIN_RING(kelvin, 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) +static void nv20_vertex_layout(struct nv20_context *nv20) { - struct nv10_fragment_program *fp = nv10->fragprog.current; + struct nv20_fragment_program *fp = nv20->fragprog.current; uint32_t src = 0; int i; struct vertex_info vinfo; @@ -193,108 +193,108 @@ static void nv10_vertex_layout(struct nv10_context *nv10) } void -nv10_emit_hw_state(struct nv10_context *nv10) +nv20_emit_hw_state(struct nv20_context *nv20) { int i; - if (nv10->dirty & NV10_NEW_VERTPROG) { - //nv10_vertprog_bind(nv10, nv10->vertprog.current); - nv10->dirty &= ~NV10_NEW_VERTPROG; + if (nv20->dirty & NV20_NEW_VERTPROG) { + //nv20_vertprog_bind(nv20, nv20->vertprog.current); + nv20->dirty &= ~NV20_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 (nv20->dirty & NV20_NEW_FRAGPROG) { + nv20_fragprog_bind(nv20, nv20->fragprog.current); + /*XXX: clear NV20_NEW_FRAGPROG if no new program uploaded */ + nv20->dirty_samplers |= (1<<10); + nv20->dirty_samplers = 0; } - if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) { - nv10_fragtex_bind(nv10); - nv10->dirty &= ~NV10_NEW_FRAGPROG; + if (nv20->dirty_samplers || (nv20->dirty & NV20_NEW_FRAGPROG)) { + nv20_fragtex_bind(nv20); + nv20->dirty &= ~NV20_NEW_FRAGPROG; } - if (nv10->dirty & NV10_NEW_VTXARRAYS) { - nv10->dirty &= ~NV10_NEW_VTXARRAYS; - nv10_vertex_layout(nv10); - nv10_vtxbuf_bind(nv10); + if (nv20->dirty & NV20_NEW_VTXARRAYS) { + nv20->dirty &= ~NV20_NEW_VTXARRAYS; + nv20_vertex_layout(nv20); + nv20_vtxbuf_bind(nv20); } - if (nv10->dirty & NV10_NEW_BLEND) { - nv10->dirty &= ~NV10_NEW_BLEND; - nv10_state_emit_blend(nv10); + if (nv20->dirty & NV20_NEW_BLEND) { + nv20->dirty &= ~NV20_NEW_BLEND; + nv20_state_emit_blend(nv20); } - if (nv10->dirty & NV10_NEW_BLENDCOL) { - nv10->dirty &= ~NV10_NEW_BLENDCOL; - nv10_state_emit_blend_color(nv10); + if (nv20->dirty & NV20_NEW_BLENDCOL) { + nv20->dirty &= ~NV20_NEW_BLENDCOL; + nv20_state_emit_blend_color(nv20); } - if (nv10->dirty & NV10_NEW_RAST) { - nv10->dirty &= ~NV10_NEW_RAST; - nv10_state_emit_rast(nv10); + if (nv20->dirty & NV20_NEW_RAST) { + nv20->dirty &= ~NV20_NEW_RAST; + nv20_state_emit_rast(nv20); } - if (nv10->dirty & NV10_NEW_DSA) { - nv10->dirty &= ~NV10_NEW_DSA; - nv10_state_emit_dsa(nv10); + if (nv20->dirty & NV20_NEW_DSA) { + nv20->dirty &= ~NV20_NEW_DSA; + nv20_state_emit_dsa(nv20); } - if (nv10->dirty & NV10_NEW_VIEWPORT) { - nv10->dirty &= ~NV10_NEW_VIEWPORT; - nv10_state_emit_viewport(nv10); + if (nv20->dirty & NV20_NEW_VIEWPORT) { + nv20->dirty &= ~NV20_NEW_VIEWPORT; + nv20_state_emit_viewport(nv20); } - if (nv10->dirty & NV10_NEW_SCISSOR) { - nv10->dirty &= ~NV10_NEW_SCISSOR; - nv10_state_emit_scissor(nv10); + if (nv20->dirty & NV20_NEW_SCISSOR) { + nv20->dirty &= ~NV20_NEW_SCISSOR; + nv20_state_emit_scissor(nv20); } - if (nv10->dirty & NV10_NEW_FRAMEBUFFER) { - nv10->dirty &= ~NV10_NEW_FRAMEBUFFER; - nv10_state_emit_framebuffer(nv10); + if (nv20->dirty & NV20_NEW_FRAMEBUFFER) { + nv20->dirty &= ~NV20_NEW_FRAMEBUFFER; + nv20_state_emit_framebuffer(nv20); } /* 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 + * at some point. Vertex arrays are emitted by nv20_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); +// BEGIN_RING(kelvin, NV10TCL_DMA_COLOR0, 1); +// OUT_RELOCo(nv20->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(kelvin, NV10TCL_COLOR_OFFSET, 1); + OUT_RELOCl(nv20->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - if (nv10->zeta) { + if (nv20->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); +// BEGIN_RING(kelvin, NV10TCL_DMA_ZETA, 1); +// OUT_RELOCo(nv20->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(kelvin, NV10TCL_ZETA_OFFSET, 1); + OUT_RELOCl(nv20->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);*/ +/* BEGIN_RING(kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1); + OUT_RELOCl(nv20->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); + BEGIN_RING(kelvin, NV10TCL_DMA_VTXBUF0, 1); + OUT_RELOCo(nv20->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(kelvin, NV10TCL_COLOR_OFFSET, 1); + OUT_RELOCl(nv20->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); /* Texture images */ for (i = 0; i < 2; i++) { - if (!(nv10->fp_samplers & (1 << i))) + if (!(nv20->fp_samplers & (1 << i))) continue; - BEGIN_RING(celsius, NV10TCL_TX_OFFSET(i), 1); - OUT_RELOCl(nv10->tex[i].buffer, 0, NOUVEAU_BO_VRAM | + BEGIN_RING(kelvin, NV10TCL_TX_OFFSET(i), 1); + OUT_RELOCl(nv20->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, + BEGIN_RING(kelvin, NV10TCL_TX_FORMAT(i), 1); + OUT_RELOCd(nv20->tex[i].buffer, nv20->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/nv20/nv20_surface.c b/src/gallium/drivers/nv20/nv20_surface.c index 875e4c5858..41b6d6ad35 100644 --- a/src/gallium/drivers/nv20/nv20_surface.c +++ b/src/gallium/drivers/nv20/nv20_surface.c @@ -26,39 +26,39 @@ * **************************************************************************/ -#include "nv10_context.h" +#include "nv20_context.h" #include "pipe/p_defines.h" #include "pipe/p_winsys.h" #include "pipe/p_inlines.h" #include "util/u_tile.h" static void -nv10_surface_copy(struct pipe_context *pipe, unsigned do_flip, +nv20_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; + struct nv20_context *nv20 = nv20_context(pipe); + struct nouveau_winsys *nvws = nv20->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, +nv20_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; + struct nv20_context *nv20 = nv20_context(pipe); + struct nouveau_winsys *nvws = nv20->nvws; nvws->surface_fill(nvws, dest, destx, desty, width, height, value); } void -nv10_init_surface_functions(struct nv10_context *nv10) +nv20_init_surface_functions(struct nv20_context *nv20) { - nv10->pipe.surface_copy = nv10_surface_copy; - nv10->pipe.surface_fill = nv10_surface_fill; + nv20->pipe.surface_copy = nv20_surface_copy; + nv20->pipe.surface_fill = nv20_surface_fill; } diff --git a/src/gallium/drivers/nv20/nv20_vbo.c b/src/gallium/drivers/nv20/nv20_vbo.c index d0e788ac03..4edc4efebd 100644 --- a/src/gallium/drivers/nv20/nv20_vbo.c +++ b/src/gallium/drivers/nv20/nv20_vbo.c @@ -2,31 +2,31 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "nv10_context.h" -#include "nv10_state.h" +#include "nv20_context.h" +#include "nv20_state.h" #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_pushbuf.h" -boolean nv10_draw_elements( struct pipe_context *pipe, +boolean nv20_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; + struct nv20_context *nv20 = nv20_context( pipe ); + struct draw_context *draw = nv20->draw; unsigned i; - nv10_emit_hw_state(nv10); + nv20_emit_hw_state(nv20); /* * Map vertex buffers */ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv10->vtxbuf[i].buffer) { + if (nv20->vtxbuf[i].buffer) { void *buf = pipe->winsys->buffer_map(pipe->winsys, - nv10->vtxbuf[i].buffer, + nv20->vtxbuf[i].buffer, PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_vertex_buffer(draw, i, buf); } @@ -44,18 +44,18 @@ boolean nv10_draw_elements( struct pipe_context *pipe, } draw_set_mapped_constant_buffer(draw, - nv10->constbuf[PIPE_SHADER_VERTEX], - nv10->constbuf_nr[PIPE_SHADER_VERTEX]); + nv20->constbuf[PIPE_SHADER_VERTEX], + nv20->constbuf_nr[PIPE_SHADER_VERTEX]); /* draw! */ - draw_arrays(nv10->draw, prim, start, count); + draw_arrays(nv20->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); + if (nv20->vtxbuf[i].buffer) { + pipe->winsys->buffer_unmap(pipe->winsys, nv20->vtxbuf[i].buffer); draw_set_mapped_vertex_buffer(draw, i, NULL); } } @@ -67,10 +67,10 @@ boolean nv10_draw_elements( struct pipe_context *pipe, return TRUE; } -boolean nv10_draw_arrays( struct pipe_context *pipe, +boolean nv20_draw_arrays( struct pipe_context *pipe, unsigned prim, unsigned start, unsigned count) { - return nv10_draw_elements(pipe, NULL, 0, prim, start, count); + return nv20_draw_elements(pipe, NULL, 0, prim, start, count); } diff --git a/src/gallium/drivers/nv20/nv20_vertprog.c b/src/gallium/drivers/nv20/nv20_vertprog.c index 72824559e8..a885fcd7a5 100644 --- a/src/gallium/drivers/nv20/nv20_vertprog.c +++ b/src/gallium/drivers/nv20/nv20_vertprog.c @@ -6,8 +6,8 @@ #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_dump.h" -#include "nv30_context.h" -#include "nv30_state.h" +#include "nv20_context.h" +#include "nv20_state.h" /* TODO (at least...): * 1. Indexed consts + ARL @@ -32,47 +32,47 @@ #define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W) #define DEF_SCALE 0 #define DEF_CTEST 0 -#include "nv30_shader.h" +#include "nv20_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 swz(s,x,y,z,w) nv20_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w) +#define neg(s) nv20_sr_neg((s)) +#define abs(s) nv20_sr_abs((s)) -struct nv30_vpc { - struct nv30_vertex_program *vp; +struct nv20_vpc { + struct nv20_vertex_program *vp; - struct nv30_vertex_program_exec *vpi; + struct nv20_vertex_program_exec *vpi; unsigned output_map[PIPE_MAX_SHADER_OUTPUTS]; int high_temp; int temp_temp_count; - struct nv30_sreg *imm; + struct nv20_sreg *imm; unsigned nr_imm; }; -static struct nv30_sreg -temp(struct nv30_vpc *vpc) +static struct nv20_sreg +temp(struct nv20_vpc *vpc) { int idx; idx = vpc->temp_temp_count++; idx += vpc->high_temp + 1; - return nv30_sr(NV30SR_TEMP, idx); + return nv20_sr(NV30SR_TEMP, idx); } -static struct nv30_sreg -constant(struct nv30_vpc *vpc, int pipe, float x, float y, float z, float w) +static struct nv20_sreg +constant(struct nv20_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; + struct nv20_vertex_program *vp = vpc->vp; + struct nv20_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); + return nv20_sr(NV30SR_CONST, idx); } } @@ -85,16 +85,16 @@ constant(struct nv30_vpc *vpc, int pipe, float x, float y, float z, float w) vpd->value[1] = y; vpd->value[2] = z; vpd->value[3] = w; - return nv30_sr(NV30SR_CONST, idx); + return nv20_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)) + nv20_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) +emit_src(struct nv20_vpc *vpc, uint32_t *hw, int pos, struct nv20_sreg src) { - struct nv30_vertex_program *vp = vpc->vp; + struct nv20_vertex_program *vp = vpc->vp; uint32_t sr = 0; switch (src.type) { @@ -163,9 +163,9 @@ emit_src(struct nv30_vpc *vpc, uint32_t *hw, int pos, struct nv30_sreg src) } static void -emit_dst(struct nv30_vpc *vpc, uint32_t *hw, int slot, struct nv30_sreg dst) +emit_dst(struct nv20_vpc *vpc, uint32_t *hw, int slot, struct nv20_sreg dst) { - struct nv30_vertex_program *vp = vpc->vp; + struct nv20_vertex_program *vp = vpc->vp; switch (dst.type) { case NV30SR_TEMP: @@ -205,12 +205,12 @@ emit_dst(struct nv30_vpc *vpc, uint32_t *hw, int slot, struct nv30_sreg dst) } 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) +nv20_vp_arith(struct nv20_vpc *vpc, int slot, int op, + struct nv20_sreg dst, int mask, + struct nv20_sreg s0, struct nv20_sreg s1, + struct nv20_sreg s2) { - struct nv30_vertex_program *vp = vpc->vp; + struct nv20_vertex_program *vp = vpc->vp; uint32_t *hw; vp->insns = realloc(vp->insns, ++vp->nr_insns * sizeof(*vpc->vpi)); @@ -248,13 +248,13 @@ nv30_vp_arith(struct nv30_vpc *vpc, int slot, int op, 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; +static INLINE struct nv20_sreg +tgsi_src(struct nv20_vpc *vpc, const struct tgsi_full_src_register *fsrc) { + struct nv20_sreg src; switch (fsrc->SrcRegister.File) { case TGSI_FILE_INPUT: - src = nv30_sr(NV30SR_INPUT, fsrc->SrcRegister.Index); + src = nv20_sr(NV30SR_INPUT, fsrc->SrcRegister.Index); break; case TGSI_FILE_CONSTANT: src = constant(vpc, fsrc->SrcRegister.Index, 0, 0, 0, 0); @@ -265,7 +265,7 @@ tgsi_src(struct nv30_vpc *vpc, const struct tgsi_full_src_register *fsrc) { 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); + src = nv20_sr(NV30SR_TEMP, fsrc->SrcRegister.Index); break; default: NOUVEAU_ERR("bad src file\n"); @@ -281,18 +281,18 @@ tgsi_src(struct nv30_vpc *vpc, const struct tgsi_full_src_register *fsrc) { return src; } -static INLINE struct nv30_sreg -tgsi_dst(struct nv30_vpc *vpc, const struct tgsi_full_dst_register *fdst) { - struct nv30_sreg dst; +static INLINE struct nv20_sreg +tgsi_dst(struct nv20_vpc *vpc, const struct tgsi_full_dst_register *fdst) { + struct nv20_sreg dst; switch (fdst->DstRegister.File) { case TGSI_FILE_OUTPUT: - dst = nv30_sr(NV30SR_OUTPUT, + dst = nv20_sr(NV30SR_OUTPUT, vpc->output_map[fdst->DstRegister.Index]); break; case TGSI_FILE_TEMPORARY: - dst = nv30_sr(NV30SR_TEMP, fdst->DstRegister.Index); + dst = nv20_sr(NV30SR_TEMP, fdst->DstRegister.Index); if (vpc->high_temp < dst.index) vpc->high_temp = dst.index; break; @@ -317,11 +317,11 @@ tgsi_mask(uint tgsi) } static boolean -nv30_vertprog_parse_instruction(struct nv30_vpc *vpc, +nv20_vertprog_parse_instruction(struct nv20_vpc *vpc, const struct tgsi_full_instruction *finst) { - struct nv30_sreg src[3], dst, tmp; - struct nv30_sreg none = nv30_sr(NV30SR_NONE, 0); + struct nv20_sreg src[3], dst, tmp; + struct nv20_sreg none = nv20_sr(NV30SR_NONE, 0); int mask; int ai = -1, ci = -1; int i; @@ -484,7 +484,7 @@ nv30_vertprog_parse_instruction(struct nv30_vpc *vpc, } static boolean -nv30_vertprog_parse_decl_output(struct nv30_vpc *vpc, +nv20_vertprog_parse_decl_output(struct nv20_vpc *vpc, const struct tgsi_full_declaration *fdec) { int hw; @@ -539,7 +539,7 @@ nv30_vertprog_parse_decl_output(struct nv30_vpc *vpc, } static boolean -nv30_vertprog_prepare(struct nv30_vpc *vpc) +nv20_vertprog_prepare(struct nv20_vpc *vpc) { struct tgsi_parse_context p; int nr_imm = 0; @@ -560,7 +560,7 @@ nv30_vertprog_prepare(struct nv30_vpc *vpc) tgsi_parse_free(&p); if (nr_imm) { - vpc->imm = CALLOC(nr_imm, sizeof(struct nv30_sreg)); + vpc->imm = CALLOC(nr_imm, sizeof(struct nv20_sreg)); assert(vpc->imm); } @@ -568,21 +568,21 @@ nv30_vertprog_prepare(struct nv30_vpc *vpc) } static void -nv30_vertprog_translate(struct nv30_context *nv30, - struct nv30_vertex_program *vp) +nv20_vertprog_translate(struct nv20_context *nv20, + struct nv20_vertex_program *vp) { struct tgsi_parse_context parse; - struct nv30_vpc *vpc = NULL; + struct nv20_vpc *vpc = NULL; tgsi_dump(vp->pipe.tokens,0); - vpc = CALLOC(1, sizeof(struct nv30_vpc)); + vpc = CALLOC(1, sizeof(struct nv20_vpc)); if (!vpc) return; vpc->vp = vp; vpc->high_temp = -1; - if (!nv30_vertprog_prepare(vpc)) { + if (!nv20_vertprog_prepare(vpc)) { FREE(vpc); return; } @@ -599,7 +599,7 @@ nv30_vertprog_translate(struct nv30_context *nv30, fdec = &parse.FullToken.FullDeclaration; switch (fdec->Declaration.File) { case TGSI_FILE_OUTPUT: - if (!nv30_vertprog_parse_decl_output(vpc, fdec)) + if (!nv20_vertprog_parse_decl_output(vpc, fdec)) goto out_err; break; default: @@ -626,7 +626,7 @@ nv30_vertprog_translate(struct nv30_context *nv30, { const struct tgsi_full_instruction *finst; finst = &parse.FullToken.FullInstruction; - if (!nv30_vertprog_parse_instruction(vpc, finst)) + if (!nv20_vertprog_parse_instruction(vpc, finst)) goto out_err; } break; @@ -643,35 +643,35 @@ out_err: } static boolean -nv30_vertprog_validate(struct nv30_context *nv30) +nv20_vertprog_validate(struct nv20_context *nv20) { - struct nouveau_winsys *nvws = nv30->nvws; - struct pipe_winsys *ws = nv30->pipe.winsys; - struct nouveau_grobj *rankine = nv30->screen->rankine; - struct nv30_vertex_program *vp; + struct nouveau_winsys *nvws = nv20->nvws; + struct pipe_winsys *ws = nv20->pipe.winsys; + struct nouveau_grobj *rankine = nv20->screen->rankine; + struct nv20_vertex_program *vp; struct pipe_buffer *constbuf; boolean upload_code = FALSE, upload_data = FALSE; int i; - vp = nv30->vertprog; - constbuf = nv30->constbuf[PIPE_SHADER_VERTEX]; + vp = nv20->vertprog; + constbuf = nv20->constbuf[PIPE_SHADER_VERTEX]; /* Translate TGSI shader into hw bytecode */ if (!vp->translated) { - nv30_vertprog_translate(nv30, vp); + nv20_vertprog_translate(nv20, vp); if (!vp->translated) return FALSE; } /* Allocate hw vtxprog exec slots */ if (!vp->exec) { - struct nouveau_resource *heap = nv30->screen->vp_exec_heap; + struct nouveau_resource *heap = nv20->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 nv30_vertex_program *evict; + struct nv20_vertex_program *evict; evict = heap->next->priv; nvws->res_free(&evict->exec); @@ -691,11 +691,11 @@ nv30_vertprog_validate(struct nv30_context *nv30) /* Allocate hw vtxprog const slots */ if (vp->nr_consts && !vp->data) { - struct nouveau_resource *heap = nv30->screen->vp_data_heap; + struct nouveau_resource *heap = nv20->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; + struct nv20_vertex_program *evict; evict = heap->next->priv; nvws->res_free(&evict->data); @@ -718,7 +718,7 @@ nv30_vertprog_validate(struct nv30_context *nv30) */ if (vp->exec_start != vp->exec->start) { for (i = 0; i < vp->nr_insns; i++) { - struct nv30_vertex_program_exec *vpi = &vp->insns[i]; + struct nv20_vertex_program_exec *vpi = &vp->insns[i]; if (vpi->has_branch_offset) { assert(0); @@ -730,7 +730,7 @@ nv30_vertprog_validate(struct nv30_context *nv30) 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]; + struct nv20_vertex_program_exec *vpi = &vp->insns[i]; if (vpi->const_index >= 0) { vpi->data[1] &= ~NV30_VP_INST_CONST_SRC_MASK; @@ -754,7 +754,7 @@ nv30_vertprog_validate(struct nv30_context *nv30) } for (i = 0; i < vp->nr_consts; i++) { - struct nv30_vertex_program_data *vpd = &vp->consts[i]; + struct nv20_vertex_program_data *vpd = &vp->consts[i]; if (vpd->index >= 0) { if (!upload_data && @@ -792,8 +792,8 @@ nv30_vertprog_validate(struct nv30_context *nv30) } } - if (vp->so != nv30->state.hw[NV30_STATE_VERTPROG]) { - so_ref(vp->so, &nv30->state.hw[NV30_STATE_VERTPROG]); + if (vp->so != nv20->state.hw[NV30_STATE_VERTPROG]) { + so_ref(vp->so, &nv20->state.hw[NV30_STATE_VERTPROG]); return TRUE; } @@ -801,9 +801,9 @@ nv30_vertprog_validate(struct nv30_context *nv30) } void -nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp) +nv20_vertprog_destroy(struct nv20_context *nv20, struct nv20_vertex_program *vp) { - struct nouveau_winsys *nvws = nv30->screen->nvws; + struct nouveau_winsys *nvws = nv20->screen->nvws; vp->translated = FALSE; @@ -829,8 +829,8 @@ nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp) so_ref(NULL, &vp->so); } -struct nv30_state_entry nv30_state_vertprog = { - .validate = nv30_vertprog_validate, +struct nv20_state_entry nv20_state_vertprog = { + .validate = nv20_vertprog_validate, .dirty = { .pipe = NV30_NEW_VERTPROG /*| NV30_NEW_UCP*/, .hw = NV30_STATE_VERTPROG, -- cgit v1.2.3 From 0da43322bbc6ead4eeb1b9fe079a33e0d57bece5 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 8 Nov 2008 18:32:33 +0200 Subject: Nouveau: build, link and use nv20. Signed-off-by: Pekka Paalanen --- configs/default | 2 +- src/gallium/drivers/nouveau/nouveau_winsys.h | 6 ++++++ src/gallium/winsys/drm/nouveau/Makefile | 1 + src/gallium/winsys/drm/nouveau/nouveau_winsys.c | 5 ++++- src/gallium/winsys/g3dvl/nouveau/Makefile | 3 ++- 5 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/configs/default b/configs/default index 6c123cc3c5..7ea27b48ce 100644 --- a/configs/default +++ b/configs/default @@ -76,7 +76,7 @@ EGL_DRIVERS_DIRS = demo # Gallium directories and GALLIUM_AUXILIARY_DIRS = draw translate cso_cache pipebuffer tgsi sct rtasm util GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) -GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv04 nv10 nv30 nv40 nv50 failover +GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv04 nv10 nv20 nv30 nv40 nv50 failover GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = xlib egl_xlib diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 48feeba309..a89b056244 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -69,6 +69,12 @@ 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 * +nv20_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); + +extern struct pipe_context * +nv20_create(struct pipe_screen *, unsigned pctx_id); + extern struct pipe_screen * nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile index be630ff6d1..81562ca78d 100644 --- a/src/gallium/winsys/drm/nouveau/Makefile +++ b/src/gallium/winsys/drm/nouveau/Makefile @@ -10,6 +10,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/nv04/libnv04.a \ $(TOP)/src/gallium/drivers/nv10/libnv10.a \ + $(TOP)/src/gallium/drivers/nv20/libnv20.a \ $(TOP)/src/gallium/drivers/nv30/libnv30.a \ $(TOP)/src/gallium/drivers/nv40/libnv40.a \ $(TOP)/src/gallium/drivers/nv50/libnv50.a diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c index 0878840dcc..364340e1d3 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c @@ -101,10 +101,13 @@ nouveau_pipe_create(struct nouveau_context *nv) switch (chipset & 0xf0) { case 0x10: - case 0x20: hws_create = nv10_screen_create; hw_create = nv10_create; break; + case 0x20: + hws_create = nv20_screen_create; + hw_create = nv20_create; + break; case 0x30: hws_create = nv30_screen_create; hw_create = nv30_create; diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 5d11bde322..ff43327778 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -26,11 +26,12 @@ LDFLAGS += -L${DRMDIR}/lib \ -L${GALLIUMDIR}/auxiliary/rtasm \ -L${GALLIUMDIR}/auxiliary/cso_cache \ -L${GALLIUMDIR}/drivers/nv10 \ + -L${GALLIUMDIR}/drivers/nv20 \ -L${GALLIUMDIR}/drivers/nv30 \ -L${GALLIUMDIR}/drivers/nv40 \ -L${GALLIUMDIR}/drivers/nv50 -LIBS += -ldriclient -ldrm -lnv10 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm +LIBS += -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm ############################################# -- cgit v1.2.3 From 903ae9d04eb7d0066c4ba1e30acb44630ca129f4 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 8 Nov 2008 19:07:04 +0200 Subject: Nouveau: update nv20 miptree according to nv40. glxinfo doesn't degfault anymore. Signed-off-by: Pekka Paalanen --- src/gallium/drivers/nv20/nv20_miptree.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv20/nv20_miptree.c b/src/gallium/drivers/nv20/nv20_miptree.c index dbfd779de9..b014f4c22e 100644 --- a/src/gallium/drivers/nv20/nv20_miptree.c +++ b/src/gallium/drivers/nv20/nv20_miptree.c @@ -94,25 +94,18 @@ nv20_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) } } -static void -nv20_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, - uint face, uint levels) -{ -} - - static struct pipe_surface * nv20_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 nv20_miptree *nv20mt = (struct nv20_miptree *)pt; struct pipe_surface *ps; - ps = ws->surface_alloc(ws); + ps = CALLOC_STRUCT(pipe_surface); if (!ps) return NULL; + pipe_texture_reference(&ps->texture, pt); pipe_buffer_reference(screen, &ps->buffer, nv20mt->buffer); ps->format = pt->format; ps->width = pt->width[level]; @@ -121,9 +114,14 @@ nv20_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, ps->nblocksx = pt->nblocksx[level]; ps->nblocksy = pt->nblocksy[level]; ps->stride = nv20mt->level[level].pitch; + ps->usage = flags; + ps->status = PIPE_SURFACE_STATUS_DEFINED; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = nv20mt->level[level].image_offset[face]; + } else + if (pt->target == PIPE_TEXTURE_3D) { + ps->offset = nv20mt->level[level].image_offset[zslice]; } else { ps->offset = nv20mt->level[level].image_offset[0]; } @@ -132,9 +130,18 @@ nv20_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, } static void -nv20_miptree_surface_release(struct pipe_screen *screen, - struct pipe_surface **surface) +nv20_miptree_surface_release(struct pipe_screen *pscreen, + struct pipe_surface **psurface) { + struct pipe_surface *ps = *psurface; + + *psurface = NULL; + if (--ps->refcount > 0) + return; + + pipe_texture_reference(&ps->texture, NULL); + pipe_buffer_reference(pscreen, &ps->buffer, NULL); + FREE(ps); } void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen) -- cgit v1.2.3 From 72ae2bd85624ae994709c0c4b5e0933002c61854 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sun, 9 Nov 2008 00:58:19 +0200 Subject: Nouveau: fix nv20_vertex_layout() The function should update nv20->vertex_info, and not just a local struct that's thrown away immediately. Fixes a SIGFPE due to vbuf->vertex_size = 0 in vbuf_alloc_vertices(). Signed-off-by: Pekka Paalanen --- src/gallium/drivers/nv20/nv20_state_emit.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv20/nv20_state_emit.c b/src/gallium/drivers/nv20/nv20_state_emit.c index 23029433f3..e8dd22925c 100644 --- a/src/gallium/drivers/nv20/nv20_state_emit.c +++ b/src/gallium/drivers/nv20/nv20_state_emit.c @@ -168,28 +168,28 @@ static void nv20_vertex_layout(struct nv20_context *nv20) struct nv20_fragment_program *fp = nv20->fragprog.current; uint32_t src = 0; int i; - struct vertex_info vinfo; + struct vertex_info *vinfo = &nv20->vertex_info; - memset(&vinfo, 0, sizeof(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++); + 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++); + 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++); + 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++); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); break; } } - draw_compute_vertex_size(&vinfo); + draw_compute_vertex_size(vinfo); } void -- cgit v1.2.3 From 66eacb3fed6bc1926e1925b164b7168a6e0a82d5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 10 Nov 2008 15:58:03 +1100 Subject: nouveau: pass object handle not pointer to GPU... --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index 5bf89e1952..d08955de71 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -386,7 +386,7 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); OUT_RING (chan, nvc->channel->vram->handle); BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); - OUT_RING (chan, nvc->NvSwzSurf); + OUT_RING (chan, nvc->NvSwzSurf->handle); BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_PATTERN, 1); OUT_RING (chan, 0); BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_ROP, 1); -- cgit v1.2.3 From e658950d4e6c0e5f8b09fa89718d358030885e08 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 10 Nov 2008 16:12:28 +1100 Subject: nv40: init pipe_surface correctly --- src/gallium/drivers/nv40/nv40_miptree.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index f8d4497bf7..f321b72149 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -123,6 +123,8 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->stride = mt->level[level].pitch; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; + ps->refcount = 1; + ps->winsys = pscreen->winsys; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = mt->level[level].image_offset[face]; -- cgit v1.2.3 From 1d6cba6572cc008760e9d4ff803b0b7e1420e41b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 10 Nov 2008 16:33:31 +1100 Subject: nouveau: remove previous hack around x86_64 breakage This hack now causes breakage *doh*. :) --- src/gallium/auxiliary/draw/draw_context.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b439bc4059..41a4cba1dd 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -64,10 +64,8 @@ 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; -- cgit v1.2.3 From 3086b1ecbe718d05bdf016e01cff9f5928c42e63 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Wed, 12 Nov 2008 22:37:01 +0200 Subject: nv04..nv30: fix pipe_surface init Signed-off-by: Pekka Paalanen --- src/gallium/drivers/nv04/nv04_miptree.c | 2 ++ src/gallium/drivers/nv10/nv10_miptree.c | 2 ++ src/gallium/drivers/nv20/nv20_miptree.c | 2 ++ src/gallium/drivers/nv30/nv30_miptree.c | 2 ++ 4 files changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c index 02f7d210e3..0cbb91e187 100644 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -109,6 +109,8 @@ nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->nblocksx = pt->nblocksx[level]; ps->nblocksy = pt->nblocksy[level]; ps->stride = nv04mt->level[level].pitch; + ps->refcount = 1; + ps->winsys = pscreen->winsys; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = nv04mt->level[level].image_offset[face]; diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c index ad084e72b8..943f9e21e9 100644 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -121,6 +121,8 @@ nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, ps->nblocksx = pt->nblocksx[level]; ps->nblocksy = pt->nblocksy[level]; ps->stride = nv10mt->level[level].pitch; + ps->refcount = 1; + ps->winsys = screen->winsys; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = nv10mt->level[level].image_offset[face]; diff --git a/src/gallium/drivers/nv20/nv20_miptree.c b/src/gallium/drivers/nv20/nv20_miptree.c index b014f4c22e..c6106d58c4 100644 --- a/src/gallium/drivers/nv20/nv20_miptree.c +++ b/src/gallium/drivers/nv20/nv20_miptree.c @@ -116,6 +116,8 @@ nv20_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, ps->stride = nv20mt->level[level].pitch; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; + ps->refcount = 1; + ps->winsys = screen->winsys; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = nv20mt->level[level].image_offset[face]; diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index 5c4f4da948..9124db03e8 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -121,6 +121,8 @@ nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->stride = nv30mt->level[level].pitch; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; + ps->refcount = 1; + ps->winsys = pscreen->winsys; if (pt->target == PIPE_TEXTURE_CUBE) { ps->offset = nv30mt->level[level].image_offset[face]; -- cgit v1.2.3