Merge branch 'gallium-0.2-radeon' into gallium-0.2
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Fri, 6 Feb 2009 21:34:04 +0000 (13:34 -0800)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Fri, 6 Feb 2009 21:34:04 +0000 (13:34 -0800)
42 files changed:
SConstruct
configs/autoconf.in
configs/default
configure.ac
src/gallium/drivers/r300/Makefile [new file with mode: 0644]
src/gallium/drivers/r300/SConscript [new file with mode: 0644]
src/gallium/drivers/r300/r300_chipset.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_chipset.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_clear.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_clear.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_context.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_context.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_cs.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_cs_inlines.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_emit.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_emit.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_flush.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_flush.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_reg.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_screen.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_screen.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_state.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_state_shader.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_state_shader.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_surface.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_surface.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_swtcl_emit.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_texture.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_texture.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_winsys.h [new file with mode: 0644]
src/gallium/winsys/drm/radeon/Makefile [new file with mode: 0644]
src/gallium/winsys/drm/radeon/SConscript [new file with mode: 0644]
src/gallium/winsys/drm/radeon/radeon_buffer.c [new file with mode: 0644]
src/gallium/winsys/drm/radeon/radeon_buffer.h [new file with mode: 0644]
src/gallium/winsys/drm/radeon/radeon_context.c [new file with mode: 0644]
src/gallium/winsys/drm/radeon/radeon_context.h [new file with mode: 0644]
src/gallium/winsys/drm/radeon/radeon_r300.c [new file with mode: 0644]
src/gallium/winsys/drm/radeon/radeon_r300.h [new file with mode: 0644]
src/gallium/winsys/drm/radeon/radeon_screen.c [new file with mode: 0644]
src/gallium/winsys/drm/radeon/radeon_screen.h [new file with mode: 0644]
src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.c [new file with mode: 0644]
src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.h [new file with mode: 0644]

index 88cdffa5048f747a970bdc3fd6ae394eae41bcb0..a22b9483da04dd9c649d17e0f31ef70646144484 100644 (file)
@@ -46,9 +46,9 @@ common.AddOptions(opts)
 opts.Add(ListOption('statetrackers', 'state trackers to build', default_statetrackers,
                      ['mesa', 'python']))
 opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers,
-                     ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace']))
+                     ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300']))
 opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys,
-                     ['xlib', 'intel', 'gdi'])) 
+                     ['xlib', 'intel', 'gdi', 'amd']))
 
 opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0')))
 
index 4a89716ab601bb67843f55946d3c0bca326422ad..a8970f7d652f72f8b1519a4799d5e25c0e312821 100644 (file)
@@ -55,11 +55,17 @@ LIB_DIR = @LIB_DIR@
 SRC_DIRS = @SRC_DIRS@
 GLU_DIRS = @GLU_DIRS@
 DRIVER_DIRS = @DRIVER_DIRS@
+GALLIUM_AUXILIARY_DIRS = @GALLIUM_AUXILIARY_DIRS@
+GALLIUM_DRIVER_DIRS = @GALLIUM_DRIVER_DIRS@
+GALLIUM_WINSYS_DIRS = @GALLIUM_WINSYS_DIRS@ 
+GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a)
+GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a)
+
 # Which subdirs under $(TOP)/progs/ to enter:
 PROGRAM_DIRS = @PROGRAM_DIRS@
 
 # Driver specific build vars
-DRI_DIRS = @DRI_DIRS@
+#DRI_DIRS = @DRI_DIRS@ 
 WINDOW_SYSTEM = @WINDOW_SYSTEM@
 USING_EGL = @USING_EGL@
 
index 13bda58f1887ca175097597e292708d9c2cb0c5d..cda9a5b03704f66c4c6757f675b573a31dcd5c07 100644 (file)
@@ -91,7 +91,7 @@ EGL_DRIVERS_DIRS = demo
 # Gallium directories and 
 GALLIUM_AUXILIARY_DIRS = draw translate cso_cache pipebuffer tgsi sct rtasm util indices
 GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a)
-GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv04 nv10 nv20 nv30 nv40 nv50 failover trace
+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
 
index 33c107266a2fffe90b4c7bc85dd9e2801f8e955c..8ddf5e31a7616c201f7eb071db72ec6a28183e35 100644 (file)
@@ -291,7 +291,7 @@ if test "x$enable_asm" = xyes; then
 
     case "$asm_arch" in
     x86)
-        ASM_FLAGS="-DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM"
+        dnl ASM_FLAGS="-DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM"
         ASM_SOURCES='$(X86_SOURCES)'
         ASM_API='$(X86_API)'
         AC_MSG_RESULT([yes, x86])
@@ -389,17 +389,22 @@ esac
 dnl
 dnl Driver specific build directories
 dnl
-SRC_DIRS="mesa"
+SRC_DIRS="mesa gallium egl gallium/winsys"
 GLU_DIRS="sgi"
 WINDOW_SYSTEM=""
+GALLIUM_WINSYS_DIRS=""
+GALLIUM_AUXILIARY_DIRS="draw translate cso_cache pipebuffer tgsi sct rtasm util"
+GALLIUM_DRIVER_DIRS="softpipe failover"
 case "$mesa_driver" in
 xlib)
     DRIVER_DIRS="x11"
     ;;
 dri)
     SRC_DIRS="glx/x11 $SRC_DIRS"
-    DRIVER_DIRS="dri"
+    DRIVER_DIRS=""
     WINDOW_SYSTEM="dri"
+    GALLIUM_WINSYS_DIRS="drm $GALLIUM_WINSYS_DIRS"
+    GALLIUM_DRIVER_DIRS="$GALLIUM_DRIVER_DIRS i915simple i965simple nv04 nv10 nv20 nv30 nv40 nv50"
     ;;
 osmesa)
     DRIVER_DIRS="osmesa"
@@ -409,6 +414,9 @@ AC_SUBST([SRC_DIRS])
 AC_SUBST([GLU_DIRS])
 AC_SUBST([DRIVER_DIRS])
 AC_SUBST([WINDOW_SYSTEM])
+AC_SUBST([GALLIUM_WINSYS_DIRS])
+AC_SUBST([GALLIUM_DRIVER_DIRS])
+AC_SUBST([GALLIUM_AUXILIARY_DIRS])
 
 dnl
 dnl User supplied program configuration
@@ -656,10 +664,10 @@ if test "$mesa_driver" = dri; then
     case "$host_os" in
     linux*)
         DEFINES="$DEFINES -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER"
-        DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING -DHAVE_ALIAS"
         if test "x$driglx_direct" = xyes; then
             DEFINES="$DEFINES -DGLX_DIRECT_RENDERING"
         fi
+        DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING -DHAVE_ALIAS"
 
         case "$host_cpu" in
         x86_64)
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
new file mode 100644 (file)
index 0000000..e83d943
--- /dev/null
@@ -0,0 +1,21 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = r300
+
+C_SOURCES = \
+       r300_chipset.c \
+       r300_clear.c \
+       r300_context.c \
+       r300_emit.c \
+       r300_flush.c \
+       r300_screen.c \
+       r300_state.c \
+       r300_state_shader.c \
+       r300_surface.c \
+       r300_swtcl_emit.c \
+       r300_texture.c
+
+include ../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript
new file mode 100644 (file)
index 0000000..18684c3
--- /dev/null
@@ -0,0 +1,17 @@
+Import('*')
+
+env = env.Clone()
+
+r300 = env.ConvenienceLibrary(
+       target = 'r300',
+       source = [
+               'r300_blit.c',
+               'r300_clear.c',
+               'r300_context.c',
+               'r300_screen.c',
+               'r300_state.c',
+               'r300_surface.c',
+       ])
+
+Export('r300')
+
diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
new file mode 100644 (file)
index 0000000..7def624
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "r300_chipset.h"
+#include "pipe/p_debug.h"
+
+/* r300_chipset: A file all to itself for deducing the various properties of
+ * Radeons. */
+
+/* Parse a PCI ID and fill an r300_capabilities struct with information. */
+void r300_parse_chipset(struct r300_capabilities* caps)
+{
+    /* Reasonable defaults */
+    caps->has_tcl = TRUE;
+    caps->is_r500 = FALSE;
+    caps->num_vert_fpus = 4;
+
+
+    /* Note: These are not ordered by PCI ID. I leave that task to GCC,
+     * which will perform the ordering while collating jump tables. Instead,
+     * I've tried to group them according to capabilities and age. */
+    switch (caps->pci_id) {
+        case 0x4144:
+            caps->family = CHIP_FAMILY_R300;
+            break;
+
+        case 0x4145:
+        case 0x4146:
+        case 0x4147:
+        case 0x4E44:
+        case 0x4E45:
+        case 0x4E46:
+        case 0x4E47:
+            caps->family = CHIP_FAMILY_R300;
+            break;
+
+        case 0x4150:
+        case 0x4151:
+        case 0x4152:
+        case 0x4153:
+        case 0x4154:
+        case 0x4155:
+        case 0x4156:
+        case 0x4E50:
+        case 0x4E51:
+        case 0x4E52:
+        case 0x4E53:
+        case 0x4E54:
+        case 0x4E56:
+            caps->family = CHIP_FAMILY_RV350;
+            break;
+
+        case 0x4148:
+        case 0x4149:
+        case 0x414A:
+        case 0x414B:
+        case 0x4E48:
+        case 0x4E49:
+        case 0x4E4B:
+            caps->family = CHIP_FAMILY_R350;
+            break;
+
+        case 0x4E4A:
+            caps->family = CHIP_FAMILY_R360;
+            break;
+
+        case 0x5460:
+        case 0x5462:
+        case 0x5464:
+        case 0x5B60:
+        case 0x5B62:
+        case 0x5B63:
+        case 0x5B64:
+        case 0x5B65:
+            caps->family = CHIP_FAMILY_RV370;
+            break;
+
+        case 0x3150:
+        case 0x3152:
+        case 0x3154:
+        case 0x3E50:
+        case 0x3E54:
+            caps->family = CHIP_FAMILY_RV380;
+            break;
+
+        case 0x4A48:
+        case 0x4A49:
+        case 0x4A4A:
+        case 0x4A4B:
+        case 0x4A4C:
+        case 0x4A4D:
+        case 0x4A4E:
+        case 0x4A4F:
+        case 0x4A50:
+        case 0x4A54:
+            caps->family = CHIP_FAMILY_R420;
+            caps->num_vert_fpus = 6;
+            break;
+
+        case 0x5548:
+        case 0x5549:
+        case 0x554A:
+        case 0x554B:
+        case 0x5550:
+        case 0x5551:
+        case 0x5552:
+        case 0x5554:
+        case 0x5D57:
+            caps->family = CHIP_FAMILY_R423;
+            caps->num_vert_fpus = 6;
+            break;
+
+        case 0x554C:
+        case 0x554D:
+        case 0x554E:
+        case 0x554F:
+        case 0x5D48:
+        case 0x5D49:
+        case 0x5D4A:
+            caps->family = CHIP_FAMILY_R430;
+            caps->num_vert_fpus = 6;
+            break;
+
+        case 0x5D4C:
+        case 0x5D4D:
+        case 0x5D4E:
+        case 0x5D4F:
+        case 0x5D50:
+        case 0x5D52:
+            caps->family = CHIP_FAMILY_R480;
+            caps->num_vert_fpus = 6;
+            break;
+
+        case 0x4B49:
+        case 0x4B4A:
+        case 0x4B4B:
+        case 0x4B4C:
+            caps->family = CHIP_FAMILY_R481;
+            caps->num_vert_fpus = 6;
+            break;
+
+        case 0x5E4C:
+        case 0x5E4F:
+        case 0x564A:
+        case 0x564B:
+        case 0x564F:
+        case 0x5652:
+        case 0x5653:
+        case 0x5657:
+        case 0x5E48:
+        case 0x5E4A:
+        case 0x5E4B:
+        case 0x5E4D:
+            caps->family = CHIP_FAMILY_RV410;
+            caps->num_vert_fpus = 6;
+            break;
+
+        case 0x5954:
+        case 0x5955:
+            caps->family = CHIP_FAMILY_RS480;
+            caps->has_tcl = FALSE;
+            break;
+
+        case 0x5974:
+        case 0x5975:
+            caps->family = CHIP_FAMILY_RS482;
+            caps->has_tcl = FALSE;
+            break;
+
+        case 0x5A41:
+        case 0x5A42:
+            caps->family = CHIP_FAMILY_RS400;
+            caps->has_tcl = FALSE;
+            break;
+
+        case 0x5A61:
+        case 0x5A62:
+            caps->family = CHIP_FAMILY_RC410;
+            caps->has_tcl = FALSE;
+            break;
+
+        case 0x791E:
+        case 0x791F:
+            caps->family = CHIP_FAMILY_RS690;
+            caps->has_tcl = FALSE;
+            break;
+
+        case 0x796C:
+        case 0x796D:
+        case 0x796E:
+        case 0x796F:
+            caps->family = CHIP_FAMILY_RS740;
+            caps->has_tcl = FALSE;
+            break;
+
+        case 0x7100:
+        case 0x7101:
+        case 0x7102:
+        case 0x7103:
+        case 0x7104:
+        case 0x7105:
+        case 0x7106:
+        case 0x7108:
+        case 0x7109:
+        case 0x710A:
+        case 0x710B:
+        case 0x710C:
+        case 0x710E:
+        case 0x710F:
+            caps->family = CHIP_FAMILY_R520;
+            caps->num_vert_fpus = 8;
+            caps->is_r500 = TRUE;
+            break;
+
+        case 0x7140:
+        case 0x7141:
+        case 0x7142:
+        case 0x7143:
+        case 0x7144:
+        case 0x7145:
+        case 0x7146:
+        case 0x7147:
+        case 0x7149:
+        case 0x714A:
+        case 0x714B:
+        case 0x714C:
+        case 0x714D:
+        case 0x714E:
+        case 0x714F:
+        case 0x7151:
+        case 0x7152:
+        case 0x7153:
+        case 0x715E:
+        case 0x715F:
+        case 0x7180:
+        case 0x7181:
+        case 0x7183:
+        case 0x7186:
+        case 0x7187:
+        case 0x7188:
+        case 0x718A:
+        case 0x718B:
+        case 0x718C:
+        case 0x718D:
+        case 0x718F:
+        case 0x7193:
+        case 0x7196:
+        case 0x719B:
+        case 0x719F:
+        case 0x7200:
+        case 0x7210:
+        case 0x7211:
+            caps->family = CHIP_FAMILY_RV515;
+            caps->num_vert_fpus = 2;
+            caps->is_r500 = TRUE;
+            break;
+
+        case 0x71C0:
+        case 0x71C1:
+        case 0x71C2:
+        case 0x71C3:
+        case 0x71C4:
+        case 0x71C5:
+        case 0x71C6:
+        case 0x71C7:
+        case 0x71CD:
+        case 0x71CE:
+        case 0x71D2:
+        case 0x71D4:
+        case 0x71D5:
+        case 0x71D6:
+        case 0x71DA:
+        case 0x71DE:
+            caps->family = CHIP_FAMILY_RV530;
+            caps->num_vert_fpus = 5;
+            caps->is_r500 = TRUE;
+            break;
+
+        case 0x7240:
+        case 0x7243:
+        case 0x7244:
+        case 0x7245:
+        case 0x7246:
+        case 0x7247:
+        case 0x7248:
+        case 0x7249:
+        case 0x724A:
+        case 0x724B:
+        case 0x724C:
+        case 0x724D:
+        case 0x724E:
+        case 0x724F:
+        case 0x7284:
+            caps->family = CHIP_FAMILY_R580;
+            caps->num_vert_fpus = 8;
+            caps->is_r500 = TRUE;
+            break;
+
+        case 0x7280:
+            caps->family = CHIP_FAMILY_RV570;
+            caps->num_vert_fpus = 5;
+            caps->is_r500 = TRUE;
+            break;
+
+        case 0x7281:
+        case 0x7283:
+        case 0x7287:
+        case 0x7288:
+        case 0x7289:
+        case 0x728B:
+        case 0x728C:
+        case 0x7290:
+        case 0x7291:
+        case 0x7293:
+        case 0x7297:
+            caps->family = CHIP_FAMILY_RV560;
+            caps->num_vert_fpus = 5;
+            caps->is_r500 = TRUE;
+            break;
+
+        default:
+            debug_printf("r300: Warning: Unknown chipset 0x%x\n",
+                caps->pci_id);
+            break;
+    }
+
+    /* Force off TCL for now */
+    caps->has_tcl = FALSE;
+}
diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h
new file mode 100644 (file)
index 0000000..a9cd372
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 R300_CHIPSET_H
+#define R300_CHIPSET_H
+
+#include "pipe/p_compiler.h"
+
+/* Structure containing all the possible information about a specific Radeon
+ * in the R3xx, R4xx, and R5xx families. */
+struct r300_capabilities {
+    /* PCI ID */
+    uint32_t pci_id;
+    /* Chipset family */
+    int family;
+    /* The number of vertex floating-point units */
+    int num_vert_fpus;
+    /* The number of fragment pipes */
+    int num_frag_pipes;
+    /* Whether or not TCL is physically present */
+    boolean has_tcl;
+    /* Whether or not this is an RV515 or newer; R500s have many differences
+     * that require extra consideration, compared to their R3xx cousins:
+     * - Extra bit of width and height on texture sizes
+     * - Blend color is split across two registers
+     * - Universal Shader (US) block used for fragment shaders */
+    boolean is_r500;
+};
+
+/* Enumerations for legibility and telling which card we're running on. */
+enum {
+    CHIP_FAMILY_R300 = 0,
+    CHIP_FAMILY_R350,
+    CHIP_FAMILY_R360,
+    CHIP_FAMILY_RV350,
+    CHIP_FAMILY_RV370,
+    CHIP_FAMILY_RV380,
+    CHIP_FAMILY_R420,
+    CHIP_FAMILY_R423,
+    CHIP_FAMILY_R430,
+    CHIP_FAMILY_R480,
+    CHIP_FAMILY_R481,
+    CHIP_FAMILY_RV410,
+    CHIP_FAMILY_RS400,
+    CHIP_FAMILY_RC410,
+    CHIP_FAMILY_RS480,
+    CHIP_FAMILY_RS482,
+    CHIP_FAMILY_RS690,
+    CHIP_FAMILY_RS740,
+    CHIP_FAMILY_RV515,
+    CHIP_FAMILY_R520,
+    CHIP_FAMILY_RV530,
+    CHIP_FAMILY_R580,
+    CHIP_FAMILY_RV560,
+    CHIP_FAMILY_RV570
+};
+
+void r300_parse_chipset(struct r300_capabilities* caps);
+
+#endif /* R300_CHIPSET_H */
diff --git a/src/gallium/drivers/r300/r300_clear.c b/src/gallium/drivers/r300/r300_clear.c
new file mode 100644 (file)
index 0000000..fd28437
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "r300_clear.h"
+
+/* This gets its own file because Intel's is in its own file.
+ * I assume there's a good reason. */
+void r300_clear(struct pipe_context* pipe,
+                struct pipe_surface* ps,
+                unsigned color)
+{
+    pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color);
+    ps->status = PIPE_SURFACE_STATUS_DEFINED;
+}
\ No newline at end of file
diff --git a/src/gallium/drivers/r300/r300_clear.h b/src/gallium/drivers/r300/r300_clear.h
new file mode 100644 (file)
index 0000000..e24a069
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "pipe/p_context.h"
+
+void r300_clear(struct pipe_context* pipe,
+                struct pipe_surface* ps,
+                unsigned color);
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
new file mode 100644 (file)
index 0000000..7b605ae
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "r300_context.h"
+
+static void r300_destroy_context(struct pipe_context* context) {
+    struct r300_context* r300 = r300_context(context);
+
+    draw_destroy(r300->draw);
+
+    FREE(r300->blend_color_state);
+    FREE(r300->scissor_state);
+    FREE(r300);
+}
+
+struct pipe_context* r300_create_context(struct pipe_screen* screen,
+                                         struct pipe_winsys* winsys,
+                                         struct r300_winsys* r300_winsys)
+{
+    struct r300_context* r300 = CALLOC_STRUCT(r300_context);
+
+    if (!r300)
+        return NULL;
+
+    r300->winsys = r300_winsys;
+    r300->context.winsys = winsys;
+    r300->context.screen = r300_create_screen(winsys, r300_winsys);
+
+    r300->context.destroy = r300_destroy_context;
+
+    r300->context.clear = r300_clear;
+
+    r300->draw = draw_create();
+    /*XXX draw_set_rasterize_stage(r300->draw, r300_draw_swtcl_stage(r300));*/
+
+    r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);
+    r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);
+
+    r300_init_flush_functions(r300);
+
+    r300_init_surface_functions(r300);
+
+    r300_init_state_functions(r300);
+
+    r300->dirty_state = R300_NEW_KITCHEN_SINK;
+    r300->dirty_hw++;
+
+    return &r300->context;
+}
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
new file mode 100644 (file)
index 0000000..fb91c17
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 R300_CONTEXT_H
+#define R300_CONTEXT_H
+
+#include "draw/draw_context.h"
+#include "pipe/p_context.h"
+#include "tgsi/tgsi_scan.h"
+#include "util/u_memory.h"
+
+#include "r300_clear.h"
+#include "r300_screen.h"
+#include "r300_winsys.h"
+
+struct r300_blend_state {
+    uint32_t blend_control;       /* R300_RB3D_CBLEND: 0x4e04 */
+    uint32_t alpha_blend_control; /* R300_RB3D_ABLEND: 0x4e08 */
+    uint32_t rop;                 /* R300_RB3D_ROPCNTL: 0x4e18 */
+    uint32_t dither;              /* R300_RB3D_DITHER_CTL: 0x4e50 */
+};
+
+struct r300_blend_color_state {
+    /* RV515 and earlier */
+    uint32_t blend_color;            /* R300_RB3D_BLEND_COLOR: 0x4e10 */
+    /* R520 and newer */
+    uint32_t blend_color_red_alpha;  /* R500_RB3D_CONSTANT_COLOR_AR: 0x4ef8 */
+    uint32_t blend_color_green_blue; /* R500_RB3D_CONSTANT_COLOR_GB: 0x4efc */
+};
+
+struct r300_dsa_state {
+    uint32_t alpha_function;    /* R300_FG_ALPHA_FUNC: 0x4bd4 */
+    uint32_t alpha_reference;   /* R500_FG_ALPHA_VALUE: 0x4be0 */
+    uint32_t z_buffer_control;  /* R300_ZB_CNTL: 0x4f00 */
+    uint32_t z_stencil_control; /* R300_ZB_ZSTENCILCNTL: 0x4f04 */
+    uint32_t stencil_ref_mask;  /* R300_ZB_STENCILREFMASK: 0x4f08 */
+    uint32_t z_buffer_top;      /* R300_ZB_ZTOP: 0x4f14 */
+    uint32_t stencil_ref_bf;    /* R500_ZB_STENCILREFMASK_BF: 0x4fd4 */
+};
+
+struct r300_rs_state {
+    uint32_t vap_control_status;    /* R300_VAP_CNTL_STATUS: 0x2140 */
+    uint32_t point_size;            /* R300_GA_POINT_SIZE: 0x421c */
+    uint32_t line_control;          /* R300_GA_LINE_CNTL: 0x4234 */
+    uint32_t depth_scale_front;  /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */
+    uint32_t depth_offset_front;/* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */
+    uint32_t depth_scale_back;    /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */
+    uint32_t depth_offset_back;  /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */
+    uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */
+    uint32_t cull_mode;             /* R300_SU_CULL_MODE: 0x42b8 */
+    uint32_t line_stipple_config;   /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */
+    uint32_t line_stipple_value;    /* R300_GA_LINE_STIPPLE_VALUE: 0x4260 */
+};
+
+struct r300_sampler_state {
+    uint32_t filter0;      /* R300_TX_FILTER0: 0x4400 */
+    uint32_t filter1;      /* R300_TX_FILTER1: 0x4440 */
+    uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */
+};
+
+struct r300_scissor_state {
+    uint32_t scissor_top_left;     /* R300_SC_SCISSORS_TL: 0x43e0 */
+    uint32_t scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
+};
+
+struct r300_texture_state {
+};
+
+#define R300_NEW_BLEND           0x000001
+#define R300_NEW_BLEND_COLOR     0x000002
+#define R300_NEW_DSA             0x000004
+#define R300_NEW_FRAMEBUFFERS    0x000008
+#define R300_NEW_FRAGMENT_SHADER 0x000010
+#define R300_NEW_RASTERIZER      0x000020
+#define R300_NEW_SAMPLER         0x000040
+#define R300_NEW_SCISSOR         0x004000
+#define R300_NEW_TEXTURE         0x008000
+#define R300_NEW_VERTEX_SHADER   0x800000
+#define R300_NEW_KITCHEN_SINK    0xffffff
+
+/* The next several objects are not pure Radeon state; they inherit from
+ * various Gallium classes. */
+
+struct r3xx_fragment_shader {
+    /* Parent class */
+    struct pipe_shader_state state;
+    struct tgsi_shader_info info;
+
+    /* Has this shader been translated yet? */
+    boolean translated;
+};
+
+struct r300_fragment_shader {
+    /* Parent class */
+    struct r3xx_fragment_shader shader;
+};
+
+struct r500_fragment_shader {
+    /* Parent class */
+    struct r3xx_fragment_shader shader;
+};
+
+struct r300_texture {
+    /* Parent class */
+    struct pipe_texture tex;
+
+    /* Offsets into the buffer. */
+    unsigned offset[PIPE_MAX_TEXTURE_LEVELS];
+
+    /* Total size of this texture, in bytes. */
+    unsigned size;
+
+    /* Pipe buffer backing this texture. */
+    struct pipe_buffer* buffer;
+};
+
+struct r300_context {
+    /* Parent class */
+    struct pipe_context context;
+
+    /* The interface to the windowing system, etc. */
+    struct r300_winsys* winsys;
+    /* Draw module. Used mostly for SW TCL. */
+    struct draw_context* draw;
+
+    /* Various CSO state objects. */
+    /* Blend state. */
+    struct r300_blend_state* blend_state;
+    /* Blend color state. */
+    struct r300_blend_color_state* blend_color_state;
+    /* Depth, stencil, and alpha state. */
+    struct r300_dsa_state* dsa_state;
+    /* Fragment shader. */
+    struct r3xx_fragment_shader* fs;
+    /* Framebuffer state. We currently don't need our own version of this. */
+    struct pipe_framebuffer_state framebuffer_state;
+    /* Rasterizer state. */
+    struct r300_rs_state* rs_state;
+    /* Sampler states. */
+    struct r300_sampler_state* sampler_states[8];
+    int sampler_count;
+    /* Scissor state. */
+    struct r300_scissor_state* scissor_state;
+    /* Texture states. */
+    struct r300_texture* textures[8];
+    struct r300_texture_state* texture_states[8];
+    int texture_count;
+    /* Bitmask of dirty state objects. */
+    uint32_t dirty_state;
+    /* Flag indicating whether or not the HW is dirty. */
+    uint32_t dirty_hw;
+};
+
+/* Convenience cast wrapper. */
+static struct r300_context* r300_context(struct pipe_context* context) {
+    return (struct r300_context*)context;
+}
+
+/* Context initialization. */
+void r300_init_state_functions(struct r300_context* r300);
+void r300_init_surface_functions(struct r300_context* r300);
+
+struct pipe_context* r300_create_context(struct pipe_screen* screen,
+                                         struct pipe_winsys* winsys,
+                                         struct r300_winsys* r300_winsys);
+
+#endif /* R300_CONTEXT_H */
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
new file mode 100644 (file)
index 0000000..385b61a
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 R300_CS_H
+#define R300_CS_H
+
+#include "r300_reg.h"
+#include "r300_winsys.h"
+
+/* Pack a 32-bit float into a dword. */
+static uint32_t pack_float_32(float f)
+{
+    union {
+        float f;
+        uint32_t u;
+    } u;
+
+    u.f = f;
+    return u.u;
+}
+
+/* Yes, I know macros are ugly. However, they are much prettier than the code
+ * that they neatly hide away, and don't have the cost of function setup,so
+ * we're going to use them. */
+
+#define MAX_CS_SIZE 64 * 1024 / 4
+
+/* XXX stolen from radeon_drm.h */
+#define RADEON_GEM_DOMAIN_CPU  0x1
+#define RADEON_GEM_DOMAIN_GTT  0x2
+#define RADEON_GEM_DOMAIN_VRAM 0x4
+
+/* XXX stolen from radeon_reg.h */
+#define RADEON_CP_PACKET0 0x0
+
+#define CP_PACKET0(register, count) \
+    (RADEON_CP_PACKET0 | ((count) << 16) | ((register) >> 2))
+
+#define CP_PACKET3(op, count) \
+    (RADEON_CP_PACKET3 | (op) | ((count) << 16))
+
+#define CS_LOCALS(context) \
+    struct r300_winsys* cs_winsys = context->winsys; \
+    struct radeon_cs* cs = cs_winsys->cs; \
+    int cs_count = 0;
+
+#define CHECK_CS(size) \
+    cs_winsys->check_cs(cs, (size))
+
+#define BEGIN_CS(size) do { \
+    CHECK_CS(size); \
+    debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \
+        size, __FUNCTION__, __FILE__, __LINE__); \
+    cs_winsys->begin_cs(cs, (size), __FILE__, __FUNCTION__, __LINE__); \
+    cs_count = size; \
+} while (0)
+
+#define OUT_CS(value) do { \
+    cs_winsys->write_cs_dword(cs, (value)); \
+    cs_count--; \
+} while (0)
+
+#define OUT_CS_32F(value) do { \
+    cs_winsys->write_cs_dword(cs, pack_float_32(value)); \
+    cs_count--; \
+} while (0)
+
+#define OUT_CS_REG(register, value) do { \
+    debug_printf("r300: writing 0x%08X to register 0x%04X\n", \
+        value, register); \
+    assert(register); \
+    OUT_CS(CP_PACKET0(register, 0)); \
+    OUT_CS(value); \
+} while (0)
+
+/* Note: This expects count to be the number of registers,
+ * not the actual packet0 count! */
+#define OUT_CS_REG_SEQ(register, count) do { \
+    debug_printf("r300: writing register sequence of %d to 0x%04X\n", \
+        count, register); \
+    assert(register); \
+    OUT_CS(CP_PACKET0(register, ((count) - 1))); \
+} while (0)
+
+#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \
+    debug_printf("r300: writing relocation for buffer %p, offset %d\n", \
+        bo, offset); \
+    assert(bo); \
+    OUT_CS(offset); \
+    cs_winsys->write_cs_reloc(cs, bo, rd, wd, flags); \
+    cs_count -= 2; \
+} while (0)
+
+#define END_CS do { \
+    debug_printf("r300: END_CS in %s (%s:%d)\n", __FUNCTION__, __FILE__, \
+        __LINE__); \
+    if (cs_count != 0) \
+        debug_printf("r300: Warning: cs_count off by %d\n", cs_count); \
+    cs_winsys->end_cs(cs, __FILE__, __FUNCTION__, __LINE__); \
+} while (0)
+
+#define FLUSH_CS do { \
+    debug_printf("r300: FLUSH_CS in %s (%s:%d)\n", __FUNCTION__, __FILE__, \
+        __LINE__); \
+    cs_winsys->flush_cs(cs); \
+} while (0)
+
+#include "r300_cs_inlines.h"
+
+#endif /* R300_CS_H */
diff --git a/src/gallium/drivers/r300/r300_cs_inlines.h b/src/gallium/drivers/r300/r300_cs_inlines.h
new file mode 100644 (file)
index 0000000..71e6623
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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. */
+
+/* r300_cs_inlines: This is just a handful of useful inlines for sending
+ * (very) common instructions to the CS buffer. Should only be included from
+ * r300_cs.h, probably. */
+
+#ifdef R300_CS_H
+
+#define R300_PACIFY do { \
+    OUT_CS_REG(R300_SC_SCREENDOOR, 0x0); \
+    OUT_CS_REG(RADEON_WAIT_UNTIL, (1 << 15) | (1 << 17) | \
+        (1 << 18) | (1 << 31)); \
+    OUT_CS_REG(R300_SC_SCREENDOOR, 0xffffff); \
+} while (0)
+
+
+#endif /* R300_CS_H */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
new file mode 100644 (file)
index 0000000..c71b8d0
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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. */
+
+/* r300_emit: Functions for emitting state. */
+
+#include "r300_emit.h"
+
+void r300_emit_blend_state(struct r300_context* r300,
+                           struct r300_blend_state* blend)
+{
+    CS_LOCALS(r300);
+    BEGIN_CS(7);
+    OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 2);
+    OUT_CS(blend->blend_control);
+    OUT_CS(blend->alpha_blend_control);
+    OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop);
+    OUT_CS_REG(R300_RB3D_DITHER_CTL, blend->dither);
+    END_CS;
+}
+
+void r300_emit_blend_color_state(struct r300_context* r300,
+                                 struct r300_blend_color_state* bc)
+{
+    struct r300_screen* r300screen =
+        (struct r300_screen*)r300->context.screen;
+    CS_LOCALS(r300);
+    if (r300screen->caps->is_r500) {
+        BEGIN_CS(3);
+        OUT_CS_REG_SEQ(R500_RB3D_CONSTANT_COLOR_AR, 2);
+        OUT_CS(bc->blend_color_red_alpha);
+        OUT_CS(bc->blend_color_green_blue);
+        END_CS;
+    } else {
+        BEGIN_CS(2);
+        OUT_CS_REG(R300_RB3D_BLEND_COLOR, bc->blend_color);
+        END_CS;
+    }
+}
+
+void r300_emit_dsa_state(struct r300_context* r300,
+                           struct r300_dsa_state* dsa)
+{
+    struct r300_screen* r300screen =
+        (struct r300_screen*)r300->context.screen;
+    CS_LOCALS(r300);
+    BEGIN_CS(r300screen->caps->is_r500 ? 8 : 8);
+    OUT_CS_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function);
+    /* XXX figure out the r300 counterpart for this */
+    if (r300screen->caps->is_r500) {
+        /* OUT_CS_REG(R500_FG_ALPHA_VALUE, dsa->alpha_reference); */
+    }
+    OUT_CS_REG_SEQ(R300_ZB_CNTL, 3);
+    OUT_CS(dsa->z_buffer_control);
+    OUT_CS(dsa->z_stencil_control);
+    OUT_CS(dsa->stencil_ref_mask);
+    OUT_CS_REG(R300_ZB_ZTOP, dsa->z_buffer_top);
+    if (r300screen->caps->is_r500) {
+        /* OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf); */
+    }
+    END_CS;
+}
+
+/* XXX add pitch, stride, z/stencil buf */
+void r300_emit_fb_state(struct r300_context* r300,
+                        struct pipe_framebuffer_state* fb)
+{
+    CS_LOCALS(r300);
+    int i;
+
+    BEGIN_CS((3 * fb->nr_cbufs) + 6);
+    for (i = 0; i < fb->nr_cbufs; i++) {
+        OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
+        OUT_CS_RELOC(fb->cbufs[i]->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+    }
+    R300_PACIFY;
+    END_CS;
+}
+
+void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs)
+{
+    struct r300_screen* r300screen =
+        (struct r300_screen*)r300->context.screen;
+    CS_LOCALS(r300);
+    BEGIN_CS(14);
+    OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status);
+    OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 6);
+    OUT_CS(rs->depth_scale_front);
+    OUT_CS(rs->depth_offset_front);
+    OUT_CS(rs->depth_scale_back);
+    OUT_CS(rs->depth_offset_back);
+    OUT_CS(rs->polygon_offset_enable);
+    OUT_CS(rs->cull_mode);
+    OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config);
+    OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, rs->line_stipple_value);
+    END_CS;
+}
+
+static void r300_emit_dirty_state(struct r300_context* r300)
+{
+    struct r300_screen* r300screen =
+        (struct r300_screen*)r300->context.screen;
+    CS_LOCALS(r300);
+
+    if (!(r300->dirty_state) && !(r300->dirty_hw)) {
+        return;
+    }
+
+    /* XXX check size */
+
+    if (r300->dirty_state & R300_NEW_BLEND) {
+        r300_emit_blend_state(r300, r300->blend_state);
+    }
+
+    if (r300->dirty_state & R300_NEW_BLEND_COLOR) {
+        r300_emit_blend_color_state(r300, r300->blend_color_state);
+    }
+
+    if (r300->dirty_state & R300_NEW_DSA) {
+        r300_emit_dsa_state(r300, r300->dsa_state);
+    }
+
+    if (r300->dirty_state & R300_NEW_RASTERIZER) {
+        r300_emit_rs_state(r300, r300->rs_state);
+    }
+
+    if (r300->dirty_state & R300_NEW_SCISSOR) {
+        struct r300_scissor_state* scissor = r300->scissor_state;
+        /* XXX next two are contiguous regs */
+        OUT_CS_REG(R300_SC_SCISSORS_TL, scissor->scissor_top_left);
+        OUT_CS_REG(R300_SC_SCISSORS_BR, scissor->scissor_bottom_right);
+    }
+
+    r300->dirty_state = 0;
+}
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
new file mode 100644 (file)
index 0000000..b6e6938
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "r300_context.h"
+#include "r300_cs.h"
+#include "r300_screen.h"
+
+void r300_emit_blend_state(struct r300_context* r300,
+                           struct r300_blend_state* blend);
+
+void r300_emit_blend_color_state(struct r300_context* r300,
+                                 struct r300_blend_color_state* bc);
+
+void r300_emit_dsa_state(struct r300_context* r300,
+                         struct r300_dsa_state* dsa);
+
+void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs);
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
new file mode 100644 (file)
index 0000000..3766f0a
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "r300_flush.h"
+
+static void r300_flush(struct pipe_context* pipe,
+                       unsigned flags,
+                       struct pipe_fence_handle** fence)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    CS_LOCALS(r300);
+
+    if (r300->dirty_hw) {
+        FLUSH_CS;
+        r300->dirty_state = R300_NEW_KITCHEN_SINK;
+        r300->dirty_hw = 0;
+    }
+}
+
+void r300_init_flush_functions(struct r300_context* r300)
+{
+    r300->context.flush = r300_flush;
+}
diff --git a/src/gallium/drivers/r300/r300_flush.h b/src/gallium/drivers/r300/r300_flush.h
new file mode 100644 (file)
index 0000000..a1b224b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 R300_FLUSH_H
+#define R300_FLUSH_H
+
+#include "pipe/p_context.h"
+
+#include "r300_context.h"
+#include "r300_cs.h"
+
+void r300_init_flush_functions(struct r300_context* r300);
+
+#endif /* R300_FLUSH_H */
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
new file mode 100644 (file)
index 0000000..dbd0cc2
--- /dev/null
@@ -0,0 +1,3290 @@
+/**************************************************************************
+
+Copyright (C) 2004-2005 Nicolai Haehnle et al.
+
+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
+on 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
+THE AUTHOR(S) AND/OR THEIR 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.
+
+**************************************************************************/
+
+/* *INDENT-OFF* */
+
+#ifndef _R300_REG_H
+#define _R300_REG_H
+
+#define R300_MC_INIT_MISC_LAT_TIMER    0x180
+#      define R300_MC_MISC__MC_CPR_INIT_LAT_SHIFT      0
+#      define R300_MC_MISC__MC_VF_INIT_LAT_SHIFT       4
+#      define R300_MC_MISC__MC_DISP0R_INIT_LAT_SHIFT   8
+#      define R300_MC_MISC__MC_DISP1R_INIT_LAT_SHIFT   12
+#      define R300_MC_MISC__MC_FIXED_INIT_LAT_SHIFT    16
+#      define R300_MC_MISC__MC_E2R_INIT_LAT_SHIFT      20
+#      define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT    24
+#      define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT    28
+
+
+#define R300_MC_INIT_GFX_LAT_TIMER     0x154
+#      define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT    0
+#      define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT    4
+#      define R300_MC_MISC__MC_G3D2R_INIT_LAT_SHIFT    8
+#      define R300_MC_MISC__MC_G3D3R_INIT_LAT_SHIFT    12
+#      define R300_MC_MISC__MC_TX0R_INIT_LAT_SHIFT     16
+#      define R300_MC_MISC__MC_TX1R_INIT_LAT_SHIFT     20
+#      define R300_MC_MISC__MC_GLOBR_INIT_LAT_SHIFT    24
+#      define R300_MC_MISC__MC_GLOBW_FULL_LAT_SHIFT    28
+
+/*
+ * This file contains registers and constants for the R300. They have been
+ * found mostly by examining command buffers captured using glxtest, as well
+ * as by extrapolating some known registers and constants from the R200.
+ * I am fairly certain that they are correct unless stated otherwise
+ * in comments.
+ */
+
+#define R300_SE_VPORT_XSCALE                0x1D98
+#define R300_SE_VPORT_XOFFSET               0x1D9C
+#define R300_SE_VPORT_YSCALE                0x1DA0
+#define R300_SE_VPORT_YOFFSET               0x1DA4
+#define R300_SE_VPORT_ZSCALE                0x1DA8
+#define R300_SE_VPORT_ZOFFSET               0x1DAC
+
+
+/*
+ * Vertex Array Processing (VAP) Control
+ */
+#define R300_VAP_CNTL  0x2080
+#       define R300_PVS_NUM_SLOTS_SHIFT                 0
+#       define R300_PVS_NUM_CNTLRS_SHIFT                4
+#       define R300_PVS_NUM_FPUS_SHIFT                  8
+#       define R300_VF_MAX_VTX_NUM_SHIFT                18
+#       define R300_GL_CLIP_SPACE_DEF                   (0 << 22)
+#       define R300_DX_CLIP_SPACE_DEF                   (1 << 22)
+#       define R500_TCL_STATE_OPTIMIZATION              (1 << 23)
+
+/* This register is written directly and also starts data section
+ * in many 3d CP_PACKET3's
+ */
+#define R300_VAP_VF_CNTL       0x2084
+#      define  R300_VAP_VF_CNTL__PRIM_TYPE__SHIFT              0
+#      define  R300_VAP_VF_CNTL__PRIM_NONE                     (0<<0)
+#      define  R300_VAP_VF_CNTL__PRIM_POINTS                   (1<<0)
+#      define  R300_VAP_VF_CNTL__PRIM_LINES                    (2<<0)
+#      define  R300_VAP_VF_CNTL__PRIM_LINE_STRIP               (3<<0)
+#      define  R300_VAP_VF_CNTL__PRIM_TRIANGLES                (4<<0)
+#      define  R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN             (5<<0)
+#      define  R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP           (6<<0)
+#      define  R300_VAP_VF_CNTL__PRIM_LINE_LOOP                (12<<0)
+#      define  R300_VAP_VF_CNTL__PRIM_QUADS                    (13<<0)
+#      define  R300_VAP_VF_CNTL__PRIM_QUAD_STRIP               (14<<0)
+#      define  R300_VAP_VF_CNTL__PRIM_POLYGON                  (15<<0)
+
+#      define  R300_VAP_VF_CNTL__PRIM_WALK__SHIFT              4
+       /* State based - direct writes to registers trigger vertex
+           generation */
+#      define  R300_VAP_VF_CNTL__PRIM_WALK_STATE_BASED         (0<<4)
+#      define  R300_VAP_VF_CNTL__PRIM_WALK_INDICES             (1<<4)
+#      define  R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST         (2<<4)
+#      define  R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED     (3<<4)
+
+       /* I don't think I saw these three used.. */
+#      define  R300_VAP_VF_CNTL__COLOR_ORDER__SHIFT            6
+#      define  R300_VAP_VF_CNTL__TCL_OUTPUT_CTL_ENA__SHIFT     9
+#      define  R300_VAP_VF_CNTL__PROG_STREAM_ENA__SHIFT        10
+
+       /* index size - when not set the indices are assumed to be 16 bit */
+#      define  R300_VAP_VF_CNTL__INDEX_SIZE_32bit              (1<<11)
+       /* number of vertices */
+#      define  R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT           16
+
+#define R500_VAP_INDEX_OFFSET              0x208c
+
+#define R300_VAP_OUTPUT_VTX_FMT_0           0x2090
+#       define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT     (1<<0)
+#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT (1<<1)
+#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2)
+#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3)
+#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4)
+#       define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16)
+
+#define R300_VAP_OUTPUT_VTX_FMT_1           0x2094
+       /* each of the following is 3 bits wide, specifies number
+          of components */
+#       define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
+#       define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3
+#       define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6
+#       define R300_VAP_OUTPUT_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9
+#       define R300_VAP_OUTPUT_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12
+#       define R300_VAP_OUTPUT_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15
+#       define R300_VAP_OUTPUT_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18
+#       define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21
+#      define R300_VAP_OUTPUT_VTX_FMT_1__NOT_PRESENT  0
+#      define R300_VAP_OUTPUT_VTX_FMT_1__1_COMPONENT  1
+#      define R300_VAP_OUTPUT_VTX_FMT_1__2_COMPONENTS 2
+#      define R300_VAP_OUTPUT_VTX_FMT_1__3_COMPONENTS 3
+#      define R300_VAP_OUTPUT_VTX_FMT_1__4_COMPONENTS 4
+
+#define R300_SE_VTE_CNTL                  0x20b0
+#      define     R300_VPORT_X_SCALE_ENA                (1 << 0)
+#      define     R300_VPORT_X_OFFSET_ENA               (1 << 1)
+#      define     R300_VPORT_Y_SCALE_ENA                (1 << 2)
+#      define     R300_VPORT_Y_OFFSET_ENA               (1 << 3)
+#      define     R300_VPORT_Z_SCALE_ENA                (1 << 4)
+#      define     R300_VPORT_Z_OFFSET_ENA               (1 << 5)
+#      define     R300_VTX_XY_FMT                       (1 << 8)
+#      define     R300_VTX_Z_FMT                        (1 << 9)
+#      define     R300_VTX_W0_FMT                       (1 << 10)
+#      define     R300_SERIAL_PROC_ENA                  (1 << 11)
+
+#define R300_VAP_VTX_SIZE               0x20b4
+
+/* BEGIN: Vertex data assembly - lots of uncertainties */
+
+/* gap */
+
+/* Maximum Vertex Indx Clamp */
+#define R300_VAP_VF_MAX_VTX_INDX         0x2134
+/* Minimum Vertex Indx Clamp */
+#define R300_VAP_VF_MIN_VTX_INDX         0x2138
+
+/** Vertex assembler/processor control status */
+#define R300_VAP_CNTL_STATUS              0x2140
+/* No swap at all (default) */
+#      define R300_VC_NO_SWAP                  (0 << 0)
+/* 16-bit swap: 0xAABBCCDD becomes 0xBBAADDCC */
+#      define R300_VC_16BIT_SWAP               (1 << 0)
+/* 32-bit swap: 0xAABBCCDD becomes 0xDDCCBBAA */
+#      define R300_VC_32BIT_SWAP               (2 << 0)
+/* Half-dword swap: 0xAABBCCDD becomes 0xCCDDAABB */
+#      define R300_VC_HALF_DWORD_SWAP          (3 << 0)
+/* The TCL engine will not be used (as it is logically or even physically removed) */
+#      define R300_VAP_TCL_BYPASS              (1 << 8)
+/* Read only flag if TCL engine is busy. */
+#      define R300_VAP_PVS_BUSY                (1 << 11)
+/* TODO: gap for MAX_MPS */
+/* Read only flag if the vertex store is busy. */
+#      define R300_VAP_VS_BUSY                 (1 << 24)
+/* Read only flag if the reciprocal engine is busy. */
+#      define R300_VAP_RCP_BUSY                (1 << 25)
+/* Read only flag if the viewport transform engine is busy. */
+#      define R300_VAP_VTE_BUSY                (1 << 26)
+/* Read only flag if the memory interface unit is busy. */
+#      define R300_VAP_MUI_BUSY                (1 << 27)
+/* Read only flag if the vertex cache is busy. */
+#      define R300_VAP_VC_BUSY                 (1 << 28)
+/* Read only flag if the vertex fetcher is busy. */
+#      define R300_VAP_VF_BUSY                 (1 << 29)
+/* Read only flag if the register pipeline is busy. */
+#      define R300_VAP_REGPIPE_BUSY            (1 << 30)
+/* Read only flag if the VAP engine is busy. */
+#      define R300_VAP_VAP_BUSY                (1 << 31)
+
+/* gap */
+
+/* Where do we get our vertex data?
+ *
+ * Vertex data either comes either from immediate mode registers or from
+ * vertex arrays.
+ * There appears to be no mixed mode (though we can force the pitch of
+ * vertex arrays to 0, effectively reusing the same element over and over
+ * again).
+ *
+ * Immediate mode is controlled by the INPUT_CNTL registers. I am not sure
+ * if these registers influence vertex array processing.
+ *
+ * Vertex arrays are controlled via the 3D_LOAD_VBPNTR packet3.
+ *
+ * In both cases, vertex attributes are then passed through INPUT_ROUTE.
+ *
+ * Beginning with INPUT_ROUTE_0_0 is a list of WORDs that route vertex data
+ * into the vertex processor's input registers.
+ * The first word routes the first input, the second word the second, etc.
+ * The corresponding input is routed into the register with the given index.
+ * The list is ended by a word with INPUT_ROUTE_END set.
+ *
+ * Always set COMPONENTS_4 in immediate mode.
+ */
+
+#define R300_VAP_PROG_STREAM_CNTL_0                     0x2150
+#       define R300_DATA_TYPE_0_SHIFT                   0
+#       define R300_DATA_TYPE_FLOAT_1                   0
+#       define R300_DATA_TYPE_FLOAT_2                   1
+#       define R300_DATA_TYPE_FLOAT_3                   2
+#       define R300_DATA_TYPE_FLOAT_4                   3
+#       define R300_DATA_TYPE_BYTE                      4
+#       define R300_DATA_TYPE_D3DCOLOR                  5
+#       define R300_DATA_TYPE_SHORT_2                   6
+#       define R300_DATA_TYPE_SHORT_4                   7
+#       define R300_DATA_TYPE_VECTOR_3_TTT              8
+#       define R300_DATA_TYPE_VECTOR_3_EET              9
+#       define R300_SKIP_DWORDS_SHIFT                   4
+#       define R300_DST_VEC_LOC_SHIFT                   8
+#       define R300_LAST_VEC                            (1 << 13)
+#       define R300_SIGNED                              (1 << 14)
+#       define R300_NORMALIZE                           (1 << 15)
+#       define R300_DATA_TYPE_1_SHIFT                   16
+#define R300_VAP_PROG_STREAM_CNTL_1                     0x2154
+#define R300_VAP_PROG_STREAM_CNTL_2                     0x2158
+#define R300_VAP_PROG_STREAM_CNTL_3                     0x215C
+#define R300_VAP_PROG_STREAM_CNTL_4                     0x2160
+#define R300_VAP_PROG_STREAM_CNTL_5                     0x2164
+#define R300_VAP_PROG_STREAM_CNTL_6                     0x2168
+#define R300_VAP_PROG_STREAM_CNTL_7                     0x216C
+/* gap */
+
+/* Notes:
+ *  - always set up to produce at least two attributes:
+ *    if vertex program uses only position, fglrx will set normal, too
+ *  - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal.
+ */
+#define R300_VAP_VTX_STATE_CNTL               0x2180
+#       define R300_COLOR_0_ASSEMBLY_SHIFT    0
+#       define R300_SEL_COLOR                 0
+#       define R300_SEL_USER_COLOR_0          1
+#       define R300_SEL_USER_COLOR_1          2
+#       define R300_COLOR_1_ASSEMBLY_SHIFT    2
+#       define R300_COLOR_2_ASSEMBLY_SHIFT    4
+#       define R300_COLOR_3_ASSEMBLY_SHIFT    6
+#       define R300_COLOR_4_ASSEMBLY_SHIFT    8
+#       define R300_COLOR_5_ASSEMBLY_SHIFT    10
+#       define R300_COLOR_6_ASSEMBLY_SHIFT    12
+#       define R300_COLOR_7_ASSEMBLY_SHIFT    14
+#       define R300_UPDATE_USER_COLOR_0_ENA   (1 << 16)
+
+/*
+ * Each bit in this field applies to the corresponding vector in the VSM
+ * memory (i.e. Bit 0 applies to VECTOR_0 (POSITION), etc.). If the bit
+ * is set, then the corresponding 4-Dword Vector is output into the Vertex Stream.
+ */
+#define R300_VAP_VSM_VTX_ASSM               0x2184
+#       define R300_INPUT_CNTL_POS               0x00000001
+#       define R300_INPUT_CNTL_NORMAL            0x00000002
+#       define R300_INPUT_CNTL_COLOR             0x00000004
+#       define R300_INPUT_CNTL_TC0               0x00000400
+#       define R300_INPUT_CNTL_TC1               0x00000800
+#       define R300_INPUT_CNTL_TC2               0x00001000 /* GUESS */
+#       define R300_INPUT_CNTL_TC3               0x00002000 /* GUESS */
+#       define R300_INPUT_CNTL_TC4               0x00004000 /* GUESS */
+#       define R300_INPUT_CNTL_TC5               0x00008000 /* GUESS */
+#       define R300_INPUT_CNTL_TC6               0x00010000 /* GUESS */
+#       define R300_INPUT_CNTL_TC7               0x00020000 /* GUESS */
+
+/* Programmable Stream Control Signed Normalize Control */
+#define R300_VAP_PSC_SGN_NORM_CNTL         0x21dc
+#      define SGN_NORM_ZERO                 0
+#      define SGN_NORM_ZERO_CLAMP_MINUS_ONE 1
+#      define SGN_NORM_NO_ZERO              2
+
+/* gap */
+
+/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0
+ * are set to a swizzling bit pattern, other words are 0.
+ *
+ * In immediate mode, the pattern is always set to xyzw. In vertex array
+ * mode, the swizzling pattern is e.g. used to set zw components in texture
+ * coordinates with only tweo components.
+ */
+#define R300_VAP_PROG_STREAM_CNTL_EXT_0                 0x21e0
+#       define R300_SWIZZLE0_SHIFT                      0
+#       define R300_SWIZZLE_SELECT_X_SHIFT              0
+#       define R300_SWIZZLE_SELECT_Y_SHIFT              3
+#       define R300_SWIZZLE_SELECT_Z_SHIFT              6
+#       define R300_SWIZZLE_SELECT_W_SHIFT              9
+
+#       define R300_SWIZZLE_SELECT_X                    0
+#       define R300_SWIZZLE_SELECT_Y                    1
+#       define R300_SWIZZLE_SELECT_Z                    2
+#       define R300_SWIZZLE_SELECT_W                    3
+#       define R300_SWIZZLE_SELECT_FP_ZERO              4
+#       define R300_SWIZZLE_SELECT_FP_ONE               5
+/* alternate forms for r300_emit.c */
+#       define R300_INPUT_ROUTE_SELECT_X    0
+#       define R300_INPUT_ROUTE_SELECT_Y    1
+#       define R300_INPUT_ROUTE_SELECT_Z    2
+#       define R300_INPUT_ROUTE_SELECT_W    3
+#       define R300_INPUT_ROUTE_SELECT_ZERO 4
+#       define R300_INPUT_ROUTE_SELECT_ONE  5
+
+#       define R300_WRITE_ENA_SHIFT                     12
+#       define R300_WRITE_ENA_X                         1
+#       define R300_WRITE_ENA_Y                         2
+#       define R300_WRITE_ENA_Z                         4
+#       define R300_WRITE_ENA_W                         8
+#       define R300_SWIZZLE1_SHIFT                      16
+#define R300_VAP_PROG_STREAM_CNTL_EXT_1                 0x21e4
+#define R300_VAP_PROG_STREAM_CNTL_EXT_2                 0x21e8
+#define R300_VAP_PROG_STREAM_CNTL_EXT_3                 0x21ec
+#define R300_VAP_PROG_STREAM_CNTL_EXT_4                 0x21f0
+#define R300_VAP_PROG_STREAM_CNTL_EXT_5                 0x21f4
+#define R300_VAP_PROG_STREAM_CNTL_EXT_6                 0x21f8
+#define R300_VAP_PROG_STREAM_CNTL_EXT_7                 0x21fc
+
+/* END: Vertex data assembly */
+
+/* gap */
+
+/* BEGIN: Upload vertex program and data */
+
+/*
+ * The programmable vertex shader unit has a memory bank of unknown size
+ * that can be written to in 16 byte units by writing the address into
+ * UPLOAD_ADDRESS, followed by data in UPLOAD_DATA (multiples of 4 DWORDs).
+ *
+ * Pointers into the memory bank are always in multiples of 16 bytes.
+ *
+ * The memory bank is divided into areas with fixed meaning.
+ *
+ * Starting at address UPLOAD_PROGRAM: Vertex program instructions.
+ * Native limits reported by drivers from ATI suggest size 256 (i.e. 4KB),
+ * whereas the difference between known addresses suggests size 512.
+ *
+ * Starting at address UPLOAD_PARAMETERS: Vertex program parameters.
+ * Native reported limits and the VPI layout suggest size 256, whereas
+ * difference between known addresses suggests size 512.
+ *
+ * At address UPLOAD_POINTSIZE is a vector (0, 0, ps, 0), where ps is the
+ * floating point pointsize. The exact purpose of this state is uncertain,
+ * as there is also the R300_RE_POINTSIZE register.
+ *
+ * Multiple vertex programs and parameter sets can be loaded at once,
+ * which could explain the size discrepancy.
+ */
+#define R300_VAP_PVS_VECTOR_INDX_REG         0x2200
+#       define R300_PVS_CODE_START           0
+#       define R300_MAX_PVS_CODE_LINES       256
+#       define R500_MAX_PVS_CODE_LINES       1024
+#       define R300_PVS_CONST_START          512
+#       define R500_PVS_CONST_START          1024
+#       define R300_MAX_PVS_CONST_VECS       256
+#       define R500_MAX_PVS_CONST_VECS       1024
+#       define R300_PVS_UCP_START            1024
+#       define R500_PVS_UCP_START            1536
+#       define R300_POINT_VPORT_SCALE_OFFSET 1030
+#       define R500_POINT_VPORT_SCALE_OFFSET 1542
+#       define R300_POINT_GEN_TEX_OFFSET     1031
+#       define R500_POINT_GEN_TEX_OFFSET     1543
+
+/*
+ * These are obsolete defines form r300_context.h, but they might give some
+ * clues when investigating the addresses further...
+ */
+#if 0
+#define VSF_DEST_PROGRAM        0x0
+#define VSF_DEST_MATRIX0        0x200
+#define VSF_DEST_MATRIX1        0x204
+#define VSF_DEST_MATRIX2        0x208
+#define VSF_DEST_VECTOR0        0x20c
+#define VSF_DEST_VECTOR1        0x20d
+#define VSF_DEST_UNKNOWN1       0x400
+#define VSF_DEST_UNKNOWN2       0x406
+#endif
+
+/* gap */
+
+#define R300_VAP_PVS_UPLOAD_DATA            0x2208
+
+/* END: Upload vertex program and data */
+
+/* gap */
+
+/* I do not know the purpose of this register. However, I do know that
+ * it is set to 221C_CLEAR for clear operations and to 221C_NORMAL
+ * for normal rendering.
+ *
+ * 2007-11-05: This register is the user clip plane control register, but there
+ * also seems to be a rendering mode control; the NORMAL/CLEAR defines.
+ *
+ * See bug #9871. http://bugs.freedesktop.org/attachment.cgi?id=10672&action=view
+ */
+#define R300_VAP_CLIP_CNTL                       0x221C
+#       define R300_VAP_UCP_ENABLE_0             (1 << 0)
+#       define R300_VAP_UCP_ENABLE_1             (1 << 1)
+#       define R300_VAP_UCP_ENABLE_2             (1 << 2)
+#       define R300_VAP_UCP_ENABLE_3             (1 << 3)
+#       define R300_VAP_UCP_ENABLE_4             (1 << 4)
+#       define R300_VAP_UCP_ENABLE_5             (1 << 5)
+#       define R300_PS_UCP_MODE_DIST_COP         (0 << 14)
+#       define R300_PS_UCP_MODE_RADIUS_COP       (1 << 14)
+#       define R300_PS_UCP_MODE_RADIUS_COP_CLIP  (2 << 14)
+#       define R300_PS_UCP_MODE_CLIP_AS_TRIFAN   (3 << 14)
+#       define R300_CLIP_DISABLE                 (1 << 16)
+#       define R300_UCP_CULL_ONLY_ENABLE         (1 << 17)
+#       define R300_BOUNDARY_EDGE_FLAG_ENABLE    (1 << 18)
+#       define R500_COLOR2_IS_TEXTURE            (1 << 20)
+#       define R500_COLOR3_IS_TEXTURE            (1 << 21)
+
+/* These seem to be per-pixel and per-vertex X and Y clipping planes. The first
+ * plane is per-pixel and the second plane is per-vertex.
+ *
+ * This was determined by experimentation alone but I believe it is correct.
+ *
+ * These registers are called X_QUAD0_1_FL to X_QUAD0_4_FL by glxtest.
+ */
+#define R300_VAP_GB_VERT_CLIP_ADJ                   0x2220
+#define R300_VAP_GB_VERT_DISC_ADJ                   0x2224
+#define R300_VAP_GB_HORZ_CLIP_ADJ                   0x2228
+#define R300_VAP_GB_HORZ_DISC_ADJ                   0x222c
+
+/* gap */
+
+/* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between
+ * rendering commands and overwriting vertex program parameters.
+ * Therefore, I suspect writing zero to 0x2284 synchronizes the engine and
+ * avoids bugs caused by still running shaders reading bad data from memory.
+ */
+#define R300_VAP_PVS_STATE_FLUSH_REG        0x2284
+
+/* This register is used to define the number of core clocks to wait for a
+ * vertex to be received by the VAP input controller (while the primitive
+ * path is backed up) before forcing any accumulated vertices to be submitted
+ * to the vertex processing path.
+ */
+#define VAP_PVS_VTX_TIMEOUT_REG             0x2288
+#       define R300_2288_R300                    0x00750000 /* -- nh */
+#       define R300_2288_RV350                   0x0000FFFF /* -- Vladimir */
+
+/* gap */
+
+/* Addresses are relative to the vertex program instruction area of the
+ * memory bank. PROGRAM_END points to the last instruction of the active
+ * program
+ *
+ * The meaning of the two UNKNOWN fields is obviously not known. However,
+ * experiments so far have shown that both *must* point to an instruction
+ * inside the vertex program, otherwise the GPU locks up.
+ *
+ * fglrx usually sets CNTL_3_UNKNOWN to the end of the program and
+ * R300_PVS_CNTL_1_POS_END_SHIFT points to instruction where last write to
+ * position takes place.
+ *
+ * Most likely this is used to ignore rest of the program in cases
+ * where group of verts arent visible. For some reason this "section"
+ * is sometimes accepted other instruction that have no relationship with
+ * position calculations.
+ */
+#define R300_VAP_PVS_CODE_CNTL_0            0x22D0
+#       define R300_PVS_FIRST_INST_SHIFT         0
+#       define R300_PVS_XYZW_VALID_INST_SHIFT    10
+#       define R300_PVS_LAST_INST_SHIFT          20
+/* Addresses are relative the the vertex program parameters area. */
+#define R300_VAP_PVS_CONST_CNTL             0x22D4
+#       define R300_PVS_CONST_BASE_OFFSET_SHIFT  0
+#       define R300_PVS_MAX_CONST_ADDR_SHIFT     16
+#define R300_VAP_PVS_CODE_CNTL_1           0x22D8
+#       define R300_PVS_LAST_VTX_SRC_INST_SHIFT  0
+#define R300_VAP_PVS_FLOW_CNTL_OPC          0x22DC
+
+/* The entire range from 0x2300 to 0x2AC inclusive seems to be used for
+ * immediate vertices
+ */
+#define R300_VAP_VTX_COLOR_R                0x2464
+#define R300_VAP_VTX_COLOR_G                0x2468
+#define R300_VAP_VTX_COLOR_B                0x246C
+#define R300_VAP_VTX_POS_0_X_1              0x2490 /* used for glVertex2*() */
+#define R300_VAP_VTX_POS_0_Y_1              0x2494
+#define R300_VAP_VTX_COLOR_PKD              0x249C /* RGBA */
+#define R300_VAP_VTX_POS_0_X_2              0x24A0 /* used for glVertex3*() */
+#define R300_VAP_VTX_POS_0_Y_2              0x24A4
+#define R300_VAP_VTX_POS_0_Z_2              0x24A8
+/* write 0 to indicate end of packet? */
+#define R300_VAP_VTX_END_OF_PKT             0x24AC
+
+/* gap */
+
+/* These are values from r300_reg/r300_reg.h - they are known to be correct
+ * and are here so we can use one register file instead of several
+ * - Vladimir
+ */
+#define R300_GB_VAP_RASTER_VTX_FMT_0   0x4000
+#      define R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT        (1<<0)
+#      define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT    (1<<1)
+#      define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_1_PRESENT    (1<<2)
+#      define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_2_PRESENT    (1<<3)
+#      define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_3_PRESENT    (1<<4)
+#      define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_SPACE        (0xf<<5)
+#      define R300_GB_VAP_RASTER_VTX_FMT_0__PT_SIZE_PRESENT    (0x1<<16)
+
+#define R300_GB_VAP_RASTER_VTX_FMT_1   0x4004
+       /* each of the following is 3 bits wide, specifies number
+          of components */
+#      define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT       0
+#      define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT       3
+#      define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT       6
+#      define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT       9
+#      define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT       12
+#      define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT       15
+#      define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT       18
+#      define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT       21
+
+/* UNK30 seems to enables point to quad transformation on textures
+ * (or something closely related to that).
+ * This bit is rather fatal at the time being due to lackings at pixel
+ * shader side
+ * Specifies top of Raster pipe specific enable controls.
+ */
+#define R300_GB_ENABLE 0x4008
+#      define R300_GB_POINT_STUFF_DISABLE     (0 << 0)
+#      define R300_GB_POINT_STUFF_ENABLE      (1 << 0) /* Specifies if points will have stuffed texture coordinates. */
+#      define R300_GB_LINE_STUFF_DISABLE      (0 << 1)
+#      define R300_GB_LINE_STUFF_ENABLE       (1 << 1) /* Specifies if lines will have stuffed texture coordinates. */
+#      define R300_GB_TRIANGLE_STUFF_DISABLE  (0 << 2)
+#      define R300_GB_TRIANGLE_STUFF_ENABLE   (1 << 2) /* Specifies if triangles will have stuffed texture coordinates. */
+#      define R300_GB_STENCIL_AUTO_DISABLE    (0 << 4)
+#      define R300_GB_STENCIL_AUTO_ENABLE     (1 << 4) /* Enable stencil auto inc/dec based on triangle cw/ccw, force into dzy low bit. */
+#      define R300_GB_STENCIL_AUTO_FORCE      (2 << 4) /* Force 0 into dzy low bit. */
+
+       /* each of the following is 2 bits wide */
+#define R300_GB_TEX_REPLICATE  0 /* Replicate VAP source texture coordinates (S,T,[R,Q]). */
+#define R300_GB_TEX_ST         1 /* Stuff with source texture coordinates (S,T). */
+#define R300_GB_TEX_STR                2 /* Stuff with source texture coordinates (S,T,R). */
+#      define R300_GB_TEX0_SOURCE_SHIFT        16
+#      define R300_GB_TEX1_SOURCE_SHIFT        18
+#      define R300_GB_TEX2_SOURCE_SHIFT        20
+#      define R300_GB_TEX3_SOURCE_SHIFT        22
+#      define R300_GB_TEX4_SOURCE_SHIFT        24
+#      define R300_GB_TEX5_SOURCE_SHIFT        26
+#      define R300_GB_TEX6_SOURCE_SHIFT        28
+#      define R300_GB_TEX7_SOURCE_SHIFT        30
+
+/* MSPOS - positions for multisample antialiasing (?) */
+#define R300_GB_MSPOS0                           0x4010
+       /* shifts - each of the fields is 4 bits */
+#      define R300_GB_MSPOS0__MS_X0_SHIFT      0
+#      define R300_GB_MSPOS0__MS_Y0_SHIFT      4
+#      define R300_GB_MSPOS0__MS_X1_SHIFT      8
+#      define R300_GB_MSPOS0__MS_Y1_SHIFT      12
+#      define R300_GB_MSPOS0__MS_X2_SHIFT      16
+#      define R300_GB_MSPOS0__MS_Y2_SHIFT      20
+#      define R300_GB_MSPOS0__MSBD0_Y          24
+#      define R300_GB_MSPOS0__MSBD0_X          28
+
+#define R300_GB_MSPOS1                           0x4014
+#      define R300_GB_MSPOS1__MS_X3_SHIFT      0
+#      define R300_GB_MSPOS1__MS_Y3_SHIFT      4
+#      define R300_GB_MSPOS1__MS_X4_SHIFT      8
+#      define R300_GB_MSPOS1__MS_Y4_SHIFT      12
+#      define R300_GB_MSPOS1__MS_X5_SHIFT      16
+#      define R300_GB_MSPOS1__MS_Y5_SHIFT      20
+#      define R300_GB_MSPOS1__MSBD1            24
+
+/* Specifies the graphics pipeline configuration for rasterization. */
+#define R300_GB_TILE_CONFIG                      0x4018
+#      define R300_GB_TILE_DISABLE             (0 << 0)
+#      define R300_GB_TILE_ENABLE              (1 << 0)
+#      define R300_GB_TILE_PIPE_COUNT_RV300    (0 << 1) /* RV350 (1 pipe, 1 ctx) */
+#      define R300_GB_TILE_PIPE_COUNT_R300     (3 << 1) /* R300 (2 pipes, 1 ctx) */
+#      define R300_GB_TILE_PIPE_COUNT_R420_3P  (6 << 1) /* R420-3P (3 pipes, 1 ctx) */
+#      define R300_GB_TILE_PIPE_COUNT_R420     (7 << 1) /* R420 (4 pipes, 1 ctx) */
+#      define R300_GB_TILE_SIZE_8              (0 << 4)
+#      define R300_GB_TILE_SIZE_16             (1 << 4)
+#      define R300_GB_TILE_SIZE_32             (2 << 4)
+#      define R300_GB_SUPER_SIZE_1             (0 << 6)
+#      define R300_GB_SUPER_SIZE_2             (1 << 6)
+#      define R300_GB_SUPER_SIZE_4             (2 << 6)
+#      define R300_GB_SUPER_SIZE_8             (3 << 6)
+#      define R300_GB_SUPER_SIZE_16            (4 << 6)
+#      define R300_GB_SUPER_SIZE_32            (5 << 6)
+#      define R300_GB_SUPER_SIZE_64            (6 << 6)
+#      define R300_GB_SUPER_SIZE_128           (7 << 6)
+#      define R300_GB_SUPER_X_SHIFT            9       /* 3 bits wide */
+#      define R300_GB_SUPER_Y_SHIFT            12      /* 3 bits wide */
+#      define R300_GB_SUPER_TILE_A             (0 << 15)
+#      define R300_GB_SUPER_TILE_B             (1 << 15)
+#      define R300_GB_SUBPIXEL_1_12            (0 << 16)
+#      define R300_GB_SUBPIXEL_1_16            (1 << 16)
+#      define GB_TILE_CONFIG_QUADS_PER_RAS_4   (0 << 17)
+#      define GB_TILE_CONFIG_QUADS_PER_RAS_8   (1 << 17)
+#      define GB_TILE_CONFIG_QUADS_PER_RAS_16  (2 << 17)
+#      define GB_TILE_CONFIG_QUADS_PER_RAS_32  (3 << 17)
+#      define GB_TILE_CONFIG_BB_SCAN_INTERCEPT (0 << 19)
+#      define GB_TILE_CONFIG_BB_SCAN_BOUND_BOX (1 << 19)
+#      define GB_TILE_CONFIG_ALT_SCAN_EN_LR    (0 << 20)
+#      define GB_TILE_CONFIG_ALT_SCAN_EN_LRL   (1 << 20)
+#      define GB_TILE_CONFIG_ALT_OFFSET        (0 << 21)
+#      define GB_TILE_CONFIG_SUBPRECISION      (0 << 22)
+#      define GB_TILE_CONFIG_ALT_TILING_DEF    (0 << 23)
+#      define GB_TILE_CONFIG_ALT_TILING_3_2    (1 << 23)
+#      define GB_TILE_CONFIG_Z_EXTENDED_24_1   (0 << 24)
+#      define GB_TILE_CONFIG_Z_EXTENDED_S25_1  (1 << 24)
+
+/* Specifies the sizes of the various FIFO`s in the sc/rs/us. This register must be the first one written */
+#define R300_GB_FIFO_SIZE      0x4024
+       /* each of the following is 2 bits wide */
+#define R300_GB_FIFO_SIZE_32   0
+#define R300_GB_FIFO_SIZE_64   1
+#define R300_GB_FIFO_SIZE_128  2
+#define R300_GB_FIFO_SIZE_256  3
+#      define R300_SC_IFIFO_SIZE_SHIFT 0
+#      define R300_SC_TZFIFO_SIZE_SHIFT        2
+#      define R300_SC_BFIFO_SIZE_SHIFT 4
+
+#      define R300_US_OFIFO_SIZE_SHIFT 12
+#      define R300_US_WFIFO_SIZE_SHIFT 14
+       /* the following use the same constants as above, but meaning is
+          is times 2 (i.e. instead of 32 words it means 64 */
+#      define R300_RS_TFIFO_SIZE_SHIFT 6
+#      define R300_RS_CFIFO_SIZE_SHIFT 8
+#      define R300_US_RAM_SIZE_SHIFT           10
+       /* watermarks, 3 bits wide */
+#      define R300_RS_HIGHWATER_COL_SHIFT      16
+#      define R300_RS_HIGHWATER_TEX_SHIFT      19
+#      define R300_OFIFO_HIGHWATER_SHIFT       22      /* two bits only */
+#      define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT       24
+
+#define GB_Z_PEQ_CONFIG                          0x4028
+#      define GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_4_4    (0 << 0)
+#      define GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8    (1 << 0)
+
+/* Specifies various polygon specific selects (fog, depth, perspective). */
+#define R300_GB_SELECT                           0x401c
+#      define R300_GB_FOG_SELECT_C0A           (0 << 0)
+#      define R300_GB_FOG_SELECT_C1A           (1 << 0)
+#      define R300_GB_FOG_SELECT_C2A           (2 << 0)
+#      define R300_GB_FOG_SELECT_C3A           (3 << 0)
+#      define R300_GB_FOG_SELECT_1_1_W         (4 << 0)
+#      define R300_GB_FOG_SELECT_Z             (5 << 0)
+#      define R300_GB_DEPTH_SELECT_Z           (0 << 3)
+#      define R300_GB_DEPTH_SELECT_1_1_W       (1 << 3)
+#      define R300_GB_W_SELECT_1_W             (0 << 4)
+#      define R300_GB_W_SELECT_1               (1 << 4)
+#      define R300_GB_FOG_STUFF_DISABLE        (0 << 5)
+#      define R300_GB_FOG_STUFF_ENABLE         (1 << 5)
+#      define R300_GB_FOG_STUFF_TEX_SHIFT      6
+#      define R300_GB_FOG_STUFF_TEX_MASK       0x000003c0
+#      define R300_GB_FOG_STUFF_COMP_SHIFT     10
+#      define R300_GB_FOG_STUFF_COMP_MASK      0x00000c00
+
+/* Specifies the graphics pipeline configuration for antialiasing. */
+#define R300_GB_AA_CONFIG                         0x4020
+#      define GB_AA_CONFIG_AA_DISABLE           (0 << 0)
+#      define GB_AA_CONFIG_AA_ENABLE            (1 << 0)
+#      define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2  (0 << 1)
+#      define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_3  (1 << 1)
+#      define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4  (2 << 1)
+#      define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6  (3 << 1)
+
+/* Selects which of 4 pipes are active. */
+#define GB_PIPE_SELECT                           0x402c
+#      define GB_PIPE_SELECT_PIPE0_ID_SHIFT  0
+#      define GB_PIPE_SELECT_PIPE1_ID_SHIFT  2
+#      define GB_PIPE_SELECT_PIPE2_ID_SHIFT  4
+#      define GB_PIPE_SELECT_PIPE3_ID_SHIFT  6
+#      define GB_PIPE_SELECT_PIPE_MASK_SHIFT 8
+#      define GB_PIPE_SELECT_MAX_PIPE        12
+#      define GB_PIPE_SELECT_BAD_PIPES       14
+#      define GB_PIPE_SELECT_CONFIG_PIPES    18
+
+
+/* Specifies the sizes of the various FIFO`s in the sc/rs. */
+#define GB_FIFO_SIZE1                            0x4070
+/* High water mark for SC input fifo */
+#      define GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_SHIFT 0
+#      define GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_MASK  0x0000003f
+/* High water mark for SC input fifo (B) */
+#      define GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_SHIFT 6
+#      define GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_MASK  0x00000fc0
+/* High water mark for RS colors' fifo */
+#      define GB_FIFO_SIZE1_SC_HIGHWATER_COL_SHIFT   12
+#      define GB_FIFO_SIZE1_SC_HIGHWATER_COL_MASK    0x0003f000
+/* High water mark for RS textures' fifo */
+#      define GB_FIFO_SIZE1_SC_HIGHWATER_TEX_SHIFT   18
+#      define GB_FIFO_SIZE1_SC_HIGHWATER_TEX_MASK    0x00fc0000
+
+/* This table specifies the source location and format for up to 16 texture
+ * addresses (i[0]:i[15]) and four colors (c[0]:c[3])
+ */
+#define R500_RS_IP_0                                   0x4074
+#define R500_RS_IP_1                                   0x4078
+#define R500_RS_IP_2                                   0x407C
+#define R500_RS_IP_3                                   0x4080
+#define R500_RS_IP_4                                   0x4084
+#define R500_RS_IP_5                                   0x4088
+#define R500_RS_IP_6                                   0x408C
+#define R500_RS_IP_7                                   0x4090
+#define R500_RS_IP_8                                   0x4094
+#define R500_RS_IP_9                                   0x4098
+#define R500_RS_IP_10                                  0x409C
+#define R500_RS_IP_11                                  0x40A0
+#define R500_RS_IP_12                                  0x40A4
+#define R500_RS_IP_13                                  0x40A8
+#define R500_RS_IP_14                                  0x40AC
+#define R500_RS_IP_15                                  0x40B0
+#define R500_RS_IP_PTR_K0                               62
+#define R500_RS_IP_PTR_K1                               63
+#define R500_RS_IP_TEX_PTR_S_SHIFT                     0
+#define R500_RS_IP_TEX_PTR_T_SHIFT                     6
+#define R500_RS_IP_TEX_PTR_R_SHIFT                     12
+#define R500_RS_IP_TEX_PTR_Q_SHIFT                     18
+#define R500_RS_IP_COL_PTR_SHIFT                       24
+#define R500_RS_IP_COL_FMT_SHIFT                       27
+#      define R500_RS_COL_PTR(x)                       (x << 24)
+#       define R500_RS_COL_FMT(x)                       (x << 27)
+/* gap */
+#define R500_RS_IP_OFFSET_DIS                          (0 << 31)
+#define R500_RS_IP_OFFSET_EN                           (1 << 31)
+
+/* gap */
+
+/* Zero to flush caches. */
+#define R300_TX_INVALTAGS                   0x4100
+#define R300_TX_FLUSH                       0x0
+
+/* The upper enable bits are guessed, based on fglrx reported limits. */
+#define R300_TX_ENABLE                      0x4104
+#       define R300_TX_ENABLE_0                  (1 << 0)
+#       define R300_TX_ENABLE_1                  (1 << 1)
+#       define R300_TX_ENABLE_2                  (1 << 2)
+#       define R300_TX_ENABLE_3                  (1 << 3)
+#       define R300_TX_ENABLE_4                  (1 << 4)
+#       define R300_TX_ENABLE_5                  (1 << 5)
+#       define R300_TX_ENABLE_6                  (1 << 6)
+#       define R300_TX_ENABLE_7                  (1 << 7)
+#       define R300_TX_ENABLE_8                  (1 << 8)
+#       define R300_TX_ENABLE_9                  (1 << 9)
+#       define R300_TX_ENABLE_10                 (1 << 10)
+#       define R300_TX_ENABLE_11                 (1 << 11)
+#       define R300_TX_ENABLE_12                 (1 << 12)
+#       define R300_TX_ENABLE_13                 (1 << 13)
+#       define R300_TX_ENABLE_14                 (1 << 14)
+#       define R300_TX_ENABLE_15                 (1 << 15)
+
+#define R500_TX_FILTER_4                   0x4110
+#      define R500_TX_WEIGHT_1_SHIFT            (0)
+#      define R500_TX_WEIGHT_0_SHIFT            (11)
+#      define R500_TX_WEIGHT_PAIR               (1<<22)
+#      define R500_TX_PHASE_SHIFT               (23)
+#      define R500_TX_DIRECTION_HORIZONTAL      (0<<27)
+#      define R500_TX_DIRECTION_VERITCAL        (1<<27)
+
+/* S Texture Coordinate of Vertex 0 for Point texture stuffing (LLC) */
+#define R300_GA_POINT_S0                              0x4200
+
+/* T Texture Coordinate of Vertex 0 for Point texture stuffing (LLC) */
+#define R300_GA_POINT_T0                              0x4204
+
+/* S Texture Coordinate of Vertex 2 for Point texture stuffing (URC) */
+#define R300_GA_POINT_S1                              0x4208
+
+/* T Texture Coordinate of Vertex 2 for Point texture stuffing (URC) */
+#define R300_GA_POINT_T1                              0x420c
+
+/* Specifies amount to shift integer position of vertex (screen space) before
+ * converting to float for triangle stipple.
+ */
+#define R300_GA_TRIANGLE_STIPPLE            0x4214
+#      define R300_GA_TRIANGLE_STIPPLE_X_SHIFT_SHIFT 0
+#      define R300_GA_TRIANGLE_STIPPLE_X_SHIFT_MASK  0x0000000f
+#      define R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT 16
+#      define R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_MASK  0x000f0000
+
+/* The pointsize is given in multiples of 6. The pointsize can be enormous:
+ * Clear() renders a single point that fills the entire framebuffer.
+ * 1/2 Height of point; fixed (16.0), subpixel format (1/12 or 1/16, even if in
+ * 8b precision).
+ */
+#define R300_GA_POINT_SIZE                   0x421C
+#       define R300_POINTSIZE_Y_SHIFT         0
+#       define R300_POINTSIZE_Y_MASK          0x0000ffff
+#       define R300_POINTSIZE_X_SHIFT         16
+#       define R300_POINTSIZE_X_MASK          0xffff0000
+#       define R300_POINTSIZE_MAX             (R300_POINTSIZE_Y_MASK / 6)
+
+/* Blue fill color */
+#define R500_GA_FILL_R                                0x4220
+
+/* Blue fill color */
+#define R500_GA_FILL_G                                0x4224
+
+/* Blue fill color */
+#define R500_GA_FILL_B                                0x4228
+
+/* Alpha fill color */
+#define R500_GA_FILL_A                                0x422c
+
+
+/* Specifies maximum and minimum point & sprite sizes for per vertex size
+ * specification. The lower part (15:0) is MIN and (31:16) is max.
+ */
+#define R300_GA_POINT_MINMAX                0x4230
+#       define R300_GA_POINT_MINMAX_MIN_SHIFT          0
+#       define R300_GA_POINT_MINMAX_MIN_MASK           (0xFFFF << 0)
+#       define R300_GA_POINT_MINMAX_MAX_SHIFT          16
+#       define R300_GA_POINT_MINMAX_MAX_MASK           (0xFFFF << 16)
+
+/* 1/2 width of line, in subpixels (1/12 or 1/16 only, even in 8b
+ * subprecision); (16.0) fixed format.
+ *
+ * The line width is given in multiples of 6.
+ * In default mode lines are classified as vertical lines.
+ * HO: horizontal
+ * VE: vertical or horizontal
+ * HO & VE: no classification
+ */
+#define R300_GA_LINE_CNTL                             0x4234
+#       define R300_GA_LINE_CNTL_WIDTH_SHIFT       0
+#       define R300_GA_LINE_CNTL_WIDTH_MASK        0x0000ffff
+#      define R300_GA_LINE_CNTL_END_TYPE_HOR      (0 << 16)
+#      define R300_GA_LINE_CNTL_END_TYPE_VER      (1 << 16)
+#      define R300_GA_LINE_CNTL_END_TYPE_SQR      (2 << 16) /* horizontal or vertical depending upon slope */
+#      define R300_GA_LINE_CNTL_END_TYPE_COMP     (3 << 16) /* Computed (perpendicular to slope) */
+#      define R500_GA_LINE_CNTL_SORT_NO           (0 << 18)
+#      define R500_GA_LINE_CNTL_SORT_MINX_MINY    (1 << 18)
+/** TODO: looks wrong */
+#       define R300_LINESIZE_MAX              (R300_GA_LINE_CNTL_WIDTH_MASK / 6)
+/** TODO: looks wrong */
+#       define R300_LINE_CNT_HO               (1 << 16)
+/** TODO: looks wrong */
+#       define R300_LINE_CNT_VE               (1 << 17)
+
+/* Line Stipple configuration information. */
+#define R300_GA_LINE_STIPPLE_CONFIG                   0x4238
+#      define R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_NO     (0 << 0)
+#      define R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE   (1 << 0)
+#      define R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_PACKET (2 << 0)
+#      define R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_SHIFT 2
+#      define R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK  0xfffffffc
+
+/* Used to load US instructions and constants */
+#define R500_GA_US_VECTOR_INDEX               0x4250
+#      define R500_GA_US_VECTOR_INDEX_SHIFT       0
+#      define R500_GA_US_VECTOR_INDEX_MASK        0x000000ff
+#      define R500_GA_US_VECTOR_INDEX_TYPE_INSTR  (0 << 16)
+#      define R500_GA_US_VECTOR_INDEX_TYPE_CONST  (1 << 16)
+#      define R500_GA_US_VECTOR_INDEX_CLAMP_NO    (0 << 17)
+#      define R500_GA_US_VECTOR_INDEX_CLAMP_CONST (1 << 17)
+
+/* Data register for loading US instructions and constants */
+#define R500_GA_US_VECTOR_DATA                0x4254
+
+/* Specifies color properties and mappings of textures. */
+#define R500_GA_COLOR_CONTROL_PS3                     0x4258
+#      define R500_TEX0_SHADING_PS3_SOLID       (0 << 0)
+#      define R500_TEX0_SHADING_PS3_FLAT        (1 << 0)
+#      define R500_TEX0_SHADING_PS3_GOURAUD     (2 << 0)
+#      define R500_TEX1_SHADING_PS3_SOLID       (0 << 2)
+#      define R500_TEX1_SHADING_PS3_FLAT        (1 << 2)
+#      define R500_TEX1_SHADING_PS3_GOURAUD     (2 << 2)
+#      define R500_TEX2_SHADING_PS3_SOLID       (0 << 4)
+#      define R500_TEX2_SHADING_PS3_FLAT        (1 << 4)
+#      define R500_TEX2_SHADING_PS3_GOURAUD     (2 << 4)
+#      define R500_TEX3_SHADING_PS3_SOLID       (0 << 6)
+#      define R500_TEX3_SHADING_PS3_FLAT        (1 << 6)
+#      define R500_TEX3_SHADING_PS3_GOURAUD     (2 << 6)
+#      define R500_TEX4_SHADING_PS3_SOLID       (0 << 8)
+#      define R500_TEX4_SHADING_PS3_FLAT        (1 << 8)
+#      define R500_TEX4_SHADING_PS3_GOURAUD     (2 << 8)
+#      define R500_TEX5_SHADING_PS3_SOLID       (0 << 10)
+#      define R500_TEX5_SHADING_PS3_FLAT        (1 << 10)
+#      define R500_TEX5_SHADING_PS3_GOURAUD     (2 << 10)
+#      define R500_TEX6_SHADING_PS3_SOLID       (0 << 12)
+#      define R500_TEX6_SHADING_PS3_FLAT        (1 << 12)
+#      define R500_TEX6_SHADING_PS3_GOURAUD     (2 << 12)
+#      define R500_TEX7_SHADING_PS3_SOLID       (0 << 14)
+#      define R500_TEX7_SHADING_PS3_FLAT        (1 << 14)
+#      define R500_TEX7_SHADING_PS3_GOURAUD     (2 << 14)
+#      define R500_TEX8_SHADING_PS3_SOLID       (0 << 16)
+#      define R500_TEX8_SHADING_PS3_FLAT        (1 << 16)
+#      define R500_TEX8_SHADING_PS3_GOURAUD     (2 << 16)
+#      define R500_TEX9_SHADING_PS3_SOLID       (0 << 18)
+#      define R500_TEX9_SHADING_PS3_FLAT        (1 << 18)
+#      define R500_TEX9_SHADING_PS3_GOURAUD     (2 << 18)
+#      define R500_TEX10_SHADING_PS3_SOLID      (0 << 20)
+#      define R500_TEX10_SHADING_PS3_FLAT       (1 << 20)
+#      define R500_TEX10_SHADING_PS3_GOURAUD    (2 << 20)
+#      define R500_COLOR0_TEX_OVERRIDE_NO       (0 << 22)
+#      define R500_COLOR0_TEX_OVERRIDE_TEX_0    (1 << 22)
+#      define R500_COLOR0_TEX_OVERRIDE_TEX_1    (2 << 22)
+#      define R500_COLOR0_TEX_OVERRIDE_TEX_2    (3 << 22)
+#      define R500_COLOR0_TEX_OVERRIDE_TEX_3    (4 << 22)
+#      define R500_COLOR0_TEX_OVERRIDE_TEX_4    (5 << 22)
+#      define R500_COLOR0_TEX_OVERRIDE_TEX_5    (6 << 22)
+#      define R500_COLOR0_TEX_OVERRIDE_TEX_6    (7 << 22)
+#      define R500_COLOR0_TEX_OVERRIDE_TEX_7    (8 << 22)
+#      define R500_COLOR0_TEX_OVERRIDE_TEX_8_C2 (9 << 22)
+#      define R500_COLOR0_TEX_OVERRIDE_TEX_9_C3 (10 << 22)
+#      define R500_COLOR1_TEX_OVERRIDE_NO       (0 << 26)
+#      define R500_COLOR1_TEX_OVERRIDE_TEX_0    (1 << 26)
+#      define R500_COLOR1_TEX_OVERRIDE_TEX_1    (2 << 26)
+#      define R500_COLOR1_TEX_OVERRIDE_TEX_2    (3 << 26)
+#      define R500_COLOR1_TEX_OVERRIDE_TEX_3    (4 << 26)
+#      define R500_COLOR1_TEX_OVERRIDE_TEX_4    (5 << 26)
+#      define R500_COLOR1_TEX_OVERRIDE_TEX_5    (6 << 26)
+#      define R500_COLOR1_TEX_OVERRIDE_TEX_6    (7 << 26)
+#      define R500_COLOR1_TEX_OVERRIDE_TEX_7    (8 << 26)
+#      define R500_COLOR1_TEX_OVERRIDE_TEX_8_C2 (9 << 26)
+#      define R500_COLOR1_TEX_OVERRIDE_TEX_9_C3 (10 << 26)
+
+/* Returns idle status of various G3D block, captured when GA_IDLE written or
+ * when hard or soft reset asserted.
+ */
+#define R500_GA_IDLE                                  0x425c
+#      define R500_GA_IDLE_PIPE3_Z_IDLE  (0 << 0)
+#      define R500_GA_IDLE_PIPE2_Z_IDLE  (0 << 1)
+#      define R500_GA_IDLE_PIPE3_CD_IDLE (0 << 2)
+#      define R500_GA_IDLE_PIPE2_CD_IDLE (0 << 3)
+#      define R500_GA_IDLE_PIPE3_FG_IDLE (0 << 4)
+#      define R500_GA_IDLE_PIPE2_FG_IDLE (0 << 5)
+#      define R500_GA_IDLE_PIPE3_US_IDLE (0 << 6)
+#      define R500_GA_IDLE_PIPE2_US_IDLE (0 << 7)
+#      define R500_GA_IDLE_PIPE3_SC_IDLE (0 << 8)
+#      define R500_GA_IDLE_PIPE2_SC_IDLE (0 << 9)
+#      define R500_GA_IDLE_PIPE3_RS_IDLE (0 << 10)
+#      define R500_GA_IDLE_PIPE2_RS_IDLE (0 << 11)
+#      define R500_GA_IDLE_PIPE1_Z_IDLE  (0 << 12)
+#      define R500_GA_IDLE_PIPE0_Z_IDLE  (0 << 13)
+#      define R500_GA_IDLE_PIPE1_CD_IDLE (0 << 14)
+#      define R500_GA_IDLE_PIPE0_CD_IDLE (0 << 15)
+#      define R500_GA_IDLE_PIPE1_FG_IDLE (0 << 16)
+#      define R500_GA_IDLE_PIPE0_FG_IDLE (0 << 17)
+#      define R500_GA_IDLE_PIPE1_US_IDLE (0 << 18)
+#      define R500_GA_IDLE_PIPE0_US_IDLE (0 << 19)
+#      define R500_GA_IDLE_PIPE1_SC_IDLE (0 << 20)
+#      define R500_GA_IDLE_PIPE0_SC_IDLE (0 << 21)
+#      define R500_GA_IDLE_PIPE1_RS_IDLE (0 << 22)
+#      define R500_GA_IDLE_PIPE0_RS_IDLE (0 << 23)
+#      define R500_GA_IDLE_SU_IDLE       (0 << 24)
+#      define R500_GA_IDLE_GA_IDLE       (0 << 25)
+#      define R500_GA_IDLE_GA_UNIT2_IDLE (0 << 26)
+
+/* Current value of stipple accumulator. */
+#define R300_GA_LINE_STIPPLE_VALUE            0x4260
+
+/* S Texture Coordinate Value for Vertex 0 of Line (stuff textures -- i.e. AA) */
+#define R300_GA_LINE_S0                               0x4264
+/* S Texture Coordinate Value for Vertex 1 of Lines (V2 of parallelogram -- stuff textures -- i.e. AA) */
+#define R300_GA_LINE_S1                               0x4268
+
+/* GA Input fifo high water marks */
+#define R500_GA_FIFO_CNTL                             0x4270
+#      define R500_GA_FIFO_CNTL_VERTEX_FIFO_MASK   0x00000007
+#      define R500_GA_FIFO_CNTL_VERTEX_FIFO_SHIFT  0
+#      define R500_GA_FIFO_CNTL_VERTEX_INDEX_MASK  0x00000038
+#      define R500_GA_FIFO_CNTL_VERTEX_INDEX_SHIFT 3
+#      define R500_GA_FIFO_CNTL_VERTEX_REG_MASK    0x00003fc0
+#      define R500_GA_FIFO_CNTL_VERTEX_REG_SHIFT   6
+
+/* GA enhance/tweaks */
+#define R300_GA_ENHANCE                               0x4274
+#      define R300_GA_ENHANCE_DEADLOCK_CNTL_NO_EFFECT   (0 << 0)
+#      define R300_GA_ENHANCE_DEADLOCK_CNTL_PREVENT_TCL (1 << 0) /* Prevents TCL interface from deadlocking on GA side. */
+#      define R300_GA_ENHANCE_FASTSYNC_CNTL_NO_EFFECT   (0 << 1)
+#      define R300_GA_ENHANCE_FASTSYNC_CNTL_ENABLE      (1 << 1) /* Enables high-performance register/primitive switching. */
+#      define R500_GA_ENHANCE_REG_READWRITE_NO_EFFECT   (0 << 2) /* R520+ only */
+#      define R500_GA_ENHANCE_REG_READWRITE_ENABLE      (1 << 2) /* R520+ only, Enables GA support of simultaneous register reads and writes. */
+#      define R500_GA_ENHANCE_REG_NOSTALL_NO_EFFECT     (0 << 3)
+#      define R500_GA_ENHANCE_REG_NOSTALL_ENABLE        (1 << 3) /* Enables GA support of no-stall reads for register read back. */
+
+#define R300_GA_COLOR_CONTROL                   0x4278
+#      define R300_GA_COLOR_CONTROL_RGB0_SHADING_SOLID      (0 << 0)
+#      define R300_GA_COLOR_CONTROL_RGB0_SHADING_FLAT       (1 << 0)
+#      define R300_GA_COLOR_CONTROL_RGB0_SHADING_GOURAUD    (2 << 0)
+#      define R300_GA_COLOR_CONTROL_ALPHA0_SHADING_SOLID    (0 << 2)
+#      define R300_GA_COLOR_CONTROL_ALPHA0_SHADING_FLAT     (1 << 2)
+#      define R300_GA_COLOR_CONTROL_ALPHA0_SHADING_GOURAUD  (2 << 2)
+#      define R300_GA_COLOR_CONTROL_RGB1_SHADING_SOLID      (0 << 4)
+#      define R300_GA_COLOR_CONTROL_RGB1_SHADING_FLAT       (1 << 4)
+#      define R300_GA_COLOR_CONTROL_RGB1_SHADING_GOURAUD    (2 << 4)
+#      define R300_GA_COLOR_CONTROL_ALPHA1_SHADING_SOLID    (0 << 6)
+#      define R300_GA_COLOR_CONTROL_ALPHA1_SHADING_FLAT     (1 << 6)
+#      define R300_GA_COLOR_CONTROL_ALPHA1_SHADING_GOURAUD  (2 << 6)
+#      define R300_GA_COLOR_CONTROL_RGB2_SHADING_SOLID      (0 << 8)
+#      define R300_GA_COLOR_CONTROL_RGB2_SHADING_FLAT       (1 << 8)
+#      define R300_GA_COLOR_CONTROL_RGB2_SHADING_GOURAUD    (2 << 8)
+#      define R300_GA_COLOR_CONTROL_ALPHA2_SHADING_SOLID    (0 << 10)
+#      define R300_GA_COLOR_CONTROL_ALPHA2_SHADING_FLAT     (1 << 10)
+#      define R300_GA_COLOR_CONTROL_ALPHA2_SHADING_GOURAUD  (2 << 10)
+#      define R300_GA_COLOR_CONTROL_RGB3_SHADING_SOLID      (0 << 12)
+#      define R300_GA_COLOR_CONTROL_RGB3_SHADING_FLAT       (1 << 12)
+#      define R300_GA_COLOR_CONTROL_RGB3_SHADING_GOURAUD    (2 << 12)
+#      define R300_GA_COLOR_CONTROL_ALPHA3_SHADING_SOLID    (0 << 14)
+#      define R300_GA_COLOR_CONTROL_ALPHA3_SHADING_FLAT     (1 << 14)
+#      define R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD  (2 << 14)
+#      define R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_FIRST  (0 << 16)
+#      define R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_SECOND (1 << 16)
+#      define R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_THIRD  (2 << 16)
+#      define R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST   (3 << 16)
+
+/** TODO: might be candidate for removal */
+#      define R300_RE_SHADE_MODEL_SMOOTH     ( \
+       R300_GA_COLOR_CONTROL_RGB0_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA0_SHADING_GOURAUD | \
+       R300_GA_COLOR_CONTROL_RGB1_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA1_SHADING_GOURAUD | \
+       R300_GA_COLOR_CONTROL_RGB2_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA2_SHADING_GOURAUD | \
+       R300_GA_COLOR_CONTROL_RGB3_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD | \
+       R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST )
+/** TODO: might be candidate for removal, the GOURAUD stuff also looks buggy to me */
+#      define R300_RE_SHADE_MODEL_FLAT     ( \
+       R300_GA_COLOR_CONTROL_RGB0_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA0_SHADING_FLAT | \
+       R300_GA_COLOR_CONTROL_RGB1_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA1_SHADING_GOURAUD | \
+       R300_GA_COLOR_CONTROL_RGB2_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA2_SHADING_FLAT | \
+       R300_GA_COLOR_CONTROL_RGB3_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD | \
+       R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST )
+
+/* Specifies red & green components of fill color -- S312 format -- Backwards comp. */
+#define R300_GA_SOLID_RG                         0x427c
+#      define GA_SOLID_RG_COLOR_GREEN_SHIFT 0
+#      define GA_SOLID_RG_COLOR_GREEN_MASK  0x0000ffff
+#      define GA_SOLID_RG_COLOR_RED_SHIFT   16
+#      define GA_SOLID_RG_COLOR_RED_MASK    0xffff0000
+/* Specifies blue & alpha components of fill color -- S312 format -- Backwards comp. */
+#define R300_GA_SOLID_BA                         0x4280
+#      define GA_SOLID_BA_COLOR_ALPHA_SHIFT 0
+#      define GA_SOLID_BA_COLOR_ALPHA_MASK  0x0000ffff
+#      define GA_SOLID_BA_COLOR_BLUE_SHIFT  16
+#      define GA_SOLID_BA_COLOR_BLUE_MASK   0xffff0000
+
+/* Polygon Mode
+ * Dangerous
+ */
+#define R300_GA_POLY_MODE                             0x4288
+#      define R300_GA_POLY_MODE_DISABLE           (0 << 0)
+#      define R300_GA_POLY_MODE_DUAL              (1 << 0) /* send 2 sets of 3 polys with specified poly type */
+/* reserved */
+#      define R300_GA_POLY_MODE_FRONT_PTYPE_POINT (0 << 4)
+#      define R300_GA_POLY_MODE_FRONT_PTYPE_LINE  (1 << 4)
+#      define R300_GA_POLY_MODE_FRONT_PTYPE_TRI   (2 << 4)
+/* reserved */
+#      define R300_GA_POLY_MODE_BACK_PTYPE_POINT  (0 << 7)
+#      define R300_GA_POLY_MODE_BACK_PTYPE_LINE   (1 << 7)
+#      define R300_GA_POLY_MODE_BACK_PTYPE_TRI    (2 << 7)
+/* reserved */
+
+/* Specifies the rouding mode for geometry & color SPFP to FP conversions. */
+#define R300_GA_ROUND_MODE                            0x428c
+#      define R300_GA_ROUND_MODE_GEOMETRY_ROUND_TRUNC   (0 << 0)
+#      define R300_GA_ROUND_MODE_GEOMETRY_ROUND_NEAREST (1 << 0)
+#      define R300_GA_ROUND_MODE_COLOR_ROUND_TRUNC      (0 << 2)
+#      define R300_GA_ROUND_MODE_COLOR_ROUND_NEAREST    (1 << 2)
+#      define R300_GA_ROUND_MODE_RGB_CLAMP_RGB          (0 << 4)
+#      define R300_GA_ROUND_MODE_RGB_CLAMP_FP20         (1 << 4)
+#      define R300_GA_ROUND_MODE_ALPHA_CLAMP_RGB        (0 << 5)
+#      define R300_GA_ROUND_MODE_ALPHA_CLAMP_FP20       (1 << 5)
+#      define R500_GA_ROUND_MODE_GEOMETRY_MASK_SHIFT    6
+#      define R500_GA_ROUND_MODE_GEOMETRY_MASK_MASK     0x000003c0
+
+/* Specifies x & y offsets for vertex data after conversion to FP.
+ * Offsets are in S15 format (subpixels -- 1/12 or 1/16, even in 8b
+ * subprecision).
+ */
+#define R300_GA_OFFSET                                0x4290
+#      define R300_GA_OFFSET_X_OFFSET_SHIFT 0
+#      define R300_GA_OFFSET_X_OFFSET_MASK  0x0000ffff
+#      define R300_GA_OFFSET_Y_OFFSET_SHIFT 16
+#      define R300_GA_OFFSET_Y_OFFSET_MASK  0xffff0000
+
+/* Specifies the scale to apply to fog. */
+#define R300_GA_FOG_SCALE                     0x4294
+/* Specifies the offset to apply to fog. */
+#define R300_GA_FOG_OFFSET                    0x4298
+/* Specifies number of cycles to assert reset, and also causes RB3D soft reset to assert. */
+#define R300_GA_SOFT_RESET                    0x429c
+
+/* Not sure why there are duplicate of factor and constant values.
+ * My best guess so far is that there are seperate zbiases for test and write.
+ * Ordering might be wrong.
+ * Some of the tests indicate that fgl has a fallback implementation of zbias
+ * via pixel shaders.
+ */
+#define R300_SU_TEX_WRAP                      0x42A0
+#define R300_SU_POLY_OFFSET_FRONT_SCALE       0x42A4
+#define R300_SU_POLY_OFFSET_FRONT_OFFSET      0x42A8
+#define R300_SU_POLY_OFFSET_BACK_SCALE        0x42AC
+#define R300_SU_POLY_OFFSET_BACK_OFFSET       0x42B0
+
+/* This register needs to be set to (1<<1) for RV350 to correctly
+ * perform depth test (see --vb-triangles in r300_demo)
+ * Don't know about other chips. - Vladimir
+ * This is set to 3 when GL_POLYGON_OFFSET_FILL is on.
+ * My guess is that there are two bits for each zbias primitive
+ * (FILL, LINE, POINT).
+ *  One to enable depth test and one for depth write.
+ * Yet this doesnt explain why depth writes work ...
+ */
+#define R300_SU_POLY_OFFSET_ENABLE            0x42B4
+#      define R300_FRONT_ENABLE               (1 << 0)
+#      define R300_BACK_ENABLE                (1 << 1)
+#      define R300_PARA_ENABLE                (1 << 2)
+
+#define R300_SU_CULL_MODE                      0x42B8
+#       define R300_CULL_FRONT                   (1 << 0)
+#       define R300_CULL_BACK                    (1 << 1)
+#       define R300_FRONT_FACE_CCW               (0 << 2)
+#       define R300_FRONT_FACE_CW                (1 << 2)
+
+/* SU Depth Scale value */
+#define R300_SU_DEPTH_SCALE                 0x42c0
+/* SU Depth Offset value */
+#define R300_SU_DEPTH_OFFSET                0x42c4
+
+
+/* BEGIN: Rasterization / Interpolators - many guesses */
+
+/*
+ * TC_CNT is the number of incoming texture coordinate sets (i.e. it depends
+ * on the vertex program, *not* the fragment program)
+ */
+#define R300_RS_COUNT                      0x4300
+#       define R300_IT_COUNT_SHIFT               0
+#       define R300_IT_COUNT_MASK                0x0000007f
+#       define R300_IC_COUNT_SHIFT               7
+#       define R300_IC_COUNT_MASK                0x00000780
+#       define R300_W_ADDR_SHIFT                 12
+#       define R300_W_ADDR_MASK                  0x0003f000
+#       define R300_HIRES_DIS                    (0 << 18)
+#       define R300_HIRES_EN                     (1 << 18)
+
+#define R300_RS_INST_COUNT                       0x4304
+#       define R300_RS_INST_COUNT_SHIFT          0
+#       define R300_RS_INST_COUNT_MASK           0x0000000f
+#       define R300_RS_TX_OFFSET_SHIFT           5
+#      define R300_RS_TX_OFFSET_MASK            0x000000e0
+
+/* gap */
+
+/* Only used for texture coordinates.
+ * Use the source field to route texture coordinate input from the
+ * vertex program to the desired interpolator. Note that the source
+ * field is relative to the outputs the vertex program *actually*
+ * writes. If a vertex program only writes texcoord[1], this will
+ * be source index 0.
+ * Set INTERP_USED on all interpolators that produce data used by
+ * the fragment program. INTERP_USED looks like a swizzling mask,
+ * but I haven't seen it used that way.
+ *
+ * Note: The _UNKNOWN constants are always set in their respective
+ * register. I don't know if this is necessary.
+ */
+#define R300_RS_IP_0                                   0x4310
+#define R300_RS_IP_1                                   0x4314
+#define R300_RS_IP_2                                   0x4318
+#define R300_RS_IP_3                                   0x431C
+#       define R300_RS_INTERP_SRC_SHIFT          2 /* TODO: check for removal */
+#       define R300_RS_INTERP_SRC_MASK           (7 << 2) /* TODO: check for removal */
+#      define R300_RS_TEX_PTR(x)                       (x << 0)
+#      define R300_RS_COL_PTR(x)                       (x << 6)
+#      define R300_RS_COL_FMT(x)                       (x << 9)
+#      define R300_RS_COL_FMT_RGBA                     0
+#      define R300_RS_COL_FMT_RGB0                     1
+#      define R300_RS_COL_FMT_RGB1                     2
+#      define R300_RS_COL_FMT_000A                     4
+#      define R300_RS_COL_FMT_0000                     5
+#      define R300_RS_COL_FMT_0001                     6
+#      define R300_RS_COL_FMT_111A                     8
+#      define R300_RS_COL_FMT_1110                     9
+#      define R300_RS_COL_FMT_1111                     10
+#      define R300_RS_SEL_S(x)                         (x << 13)
+#      define R300_RS_SEL_T(x)                         (x << 16)
+#      define R300_RS_SEL_R(x)                         (x << 19)
+#      define R300_RS_SEL_Q(x)                         (x << 22)
+#      define R300_RS_SEL_C0                           0
+#      define R300_RS_SEL_C1                           1
+#      define R300_RS_SEL_C2                           2
+#      define R300_RS_SEL_C3                           3
+#      define R300_RS_SEL_K0                           4
+#      define R300_RS_SEL_K1                           5
+
+
+/*  */
+#define R500_RS_INST_0                                 0x4320
+#define R500_RS_INST_1                                 0x4324
+#define R500_RS_INST_2                                 0x4328
+#define R500_RS_INST_3                                 0x432c
+#define R500_RS_INST_4                                 0x4330
+#define R500_RS_INST_5                                 0x4334
+#define R500_RS_INST_6                                 0x4338
+#define R500_RS_INST_7                                 0x433c
+#define R500_RS_INST_8                                 0x4340
+#define R500_RS_INST_9                                 0x4344
+#define R500_RS_INST_10                                        0x4348
+#define R500_RS_INST_11                                        0x434c
+#define R500_RS_INST_12                                        0x4350
+#define R500_RS_INST_13                                        0x4354
+#define R500_RS_INST_14                                        0x4358
+#define R500_RS_INST_15                                        0x435c
+#define R500_RS_INST_TEX_ID_SHIFT                      0
+#define R500_RS_INST_TEX_CN_WRITE                      (1 << 4)
+#define R500_RS_INST_TEX_ADDR_SHIFT                    5
+#define R500_RS_INST_COL_ID_SHIFT                      12
+#define R500_RS_INST_COL_CN_NO_WRITE                   (0 << 16)
+#define R500_RS_INST_COL_CN_WRITE                      (1 << 16)
+#define R500_RS_INST_COL_CN_WRITE_FBUFFER              (2 << 16)
+#define R500_RS_INST_COL_CN_WRITE_BACKFACE             (3 << 16)
+#define R500_RS_INST_COL_ADDR_SHIFT                    18
+#define R500_RS_INST_TEX_ADJ                           (1 << 25)
+#define R500_RS_INST_W_CN                              (1 << 26)
+
+/* These DWORDs control how vertex data is routed into fragment program
+ * registers, after interpolators.
+ */
+#define R300_RS_INST_0                     0x4330
+#define R300_RS_INST_1                     0x4334
+#define R300_RS_INST_2                     0x4338
+#define R300_RS_INST_3                     0x433C
+#define R300_RS_INST_4                     0x4340
+#define R300_RS_INST_5                     0x4344
+#define R300_RS_INST_6                     0x4348
+#define R300_RS_INST_7                     0x434C
+#      define R300_RS_INST_TEX_ID(x)           ((x) << 0)
+#      define R300_RS_INST_TEX_CN_WRITE        (1 << 3)
+#      define R300_RS_INST_TEX_ADDR_SHIFT      6
+#      define R300_RS_INST_COL_ID(x)           ((x) << 11)
+#      define R300_RS_INST_COL_CN_WRITE        (1 << 14)
+#      define R300_RS_INST_COL_ADDR_SHIFT      17
+#      define R300_RS_INST_TEX_ADJ             (1 << 22)
+#      define R300_RS_COL_BIAS_UNUSED_SHIFT    23
+
+/* END: Rasterization / Interpolators - many guesses */
+
+/* Hierarchical Z Enable */
+#define R300_SC_HYPERZ                   0x43a4
+#      define R300_SC_HYPERZ_DISABLE     (0 << 0)
+#      define R300_SC_HYPERZ_ENABLE      (1 << 0)
+#      define R300_SC_HYPERZ_MIN         (0 << 1)
+#      define R300_SC_HYPERZ_MAX         (1 << 1)
+#      define R300_SC_HYPERZ_ADJ_256     (0 << 2)
+#      define R300_SC_HYPERZ_ADJ_128     (1 << 2)
+#      define R300_SC_HYPERZ_ADJ_64      (2 << 2)
+#      define R300_SC_HYPERZ_ADJ_32      (3 << 2)
+#      define R300_SC_HYPERZ_ADJ_16      (4 << 2)
+#      define R300_SC_HYPERZ_ADJ_8       (5 << 2)
+#      define R300_SC_HYPERZ_ADJ_4       (6 << 2)
+#      define R300_SC_HYPERZ_ADJ_2       (7 << 2)
+#      define R300_SC_HYPERZ_HZ_Z0MIN_NO (0 << 5)
+#      define R300_SC_HYPERZ_HZ_Z0MIN    (1 << 5)
+#      define R300_SC_HYPERZ_HZ_Z0MAX_NO (0 << 6)
+#      define R300_SC_HYPERZ_HZ_Z0MAX    (1 << 6)
+
+#define R300_SC_EDGERULE                 0x43a8
+
+/* BEGIN: Scissors and cliprects */
+
+/* There are four clipping rectangles. Their corner coordinates are inclusive.
+ * Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending
+ * on whether the pixel is inside cliprects 0-3, respectively. For example,
+ * if a pixel is inside cliprects 0 and 1, but outside 2 and 3, it is assigned
+ * the number 3 (binary 0011).
+ * Iff the bit corresponding to the pixel's number in RE_CLIPRECT_CNTL is set,
+ * the pixel is rasterized.
+ *
+ * In addition to this, there is a scissors rectangle. Only pixels inside the
+ * scissors rectangle are drawn. (coordinates are inclusive)
+ *
+ * For some reason, the top-left corner of the framebuffer is at (1440, 1440)
+ * for the purpose of clipping and scissors.
+ */
+#define R300_SC_CLIPRECT_TL_0               0x43B0
+#define R300_SC_CLIPRECT_BR_0               0x43B4
+#define R300_SC_CLIPRECT_TL_1               0x43B8
+#define R300_SC_CLIPRECT_BR_1               0x43BC
+#define R300_SC_CLIPRECT_TL_2               0x43C0
+#define R300_SC_CLIPRECT_BR_2               0x43C4
+#define R300_SC_CLIPRECT_TL_3               0x43C8
+#define R300_SC_CLIPRECT_BR_3               0x43CC
+#       define R300_CLIPRECT_OFFSET              1440
+#       define R300_CLIPRECT_MASK                0x1FFF
+#       define R300_CLIPRECT_X_SHIFT             0
+#       define R300_CLIPRECT_X_MASK              (0x1FFF << 0)
+#       define R300_CLIPRECT_Y_SHIFT             13
+#       define R300_CLIPRECT_Y_MASK              (0x1FFF << 13)
+#define R300_SC_CLIP_RULE                   0x43D0
+#       define R300_CLIP_OUT                     (1 << 0)
+#       define R300_CLIP_0                       (1 << 1)
+#       define R300_CLIP_1                       (1 << 2)
+#       define R300_CLIP_10                      (1 << 3)
+#       define R300_CLIP_2                       (1 << 4)
+#       define R300_CLIP_20                      (1 << 5)
+#       define R300_CLIP_21                      (1 << 6)
+#       define R300_CLIP_210                     (1 << 7)
+#       define R300_CLIP_3                       (1 << 8)
+#       define R300_CLIP_30                      (1 << 9)
+#       define R300_CLIP_31                      (1 << 10)
+#       define R300_CLIP_310                     (1 << 11)
+#       define R300_CLIP_32                      (1 << 12)
+#       define R300_CLIP_320                     (1 << 13)
+#       define R300_CLIP_321                     (1 << 14)
+#       define R300_CLIP_3210                    (1 << 15)
+
+/* gap */
+
+#define R300_SC_SCISSORS_TL                 0x43E0
+#define R300_SC_SCISSORS_BR                 0x43E4
+#       define R300_SCISSORS_OFFSET              1440
+#       define R300_SCISSORS_X_SHIFT             0
+#       define R300_SCISSORS_X_MASK              (0x1FFF << 0)
+#       define R300_SCISSORS_Y_SHIFT             13
+#       define R300_SCISSORS_Y_MASK              (0x1FFF << 13)
+
+/* Screen door sample mask */
+#define R300_SC_SCREENDOOR                 0x43e8
+
+/* END: Scissors and cliprects */
+
+/* BEGIN: Texture specification */
+
+/*
+ * The texture specification dwords are grouped by meaning and not by texture
+ * unit. This means that e.g. the offset for texture image unit N is found in
+ * register TX_OFFSET_0 + (4*N)
+ */
+#define R300_TX_FILTER0_0                        0x4400
+#define R300_TX_FILTER0_1                        0x4404
+#define R300_TX_FILTER0_2                        0x4408
+#define R300_TX_FILTER0_3                        0x440c
+#define R300_TX_FILTER0_4                        0x4410
+#define R300_TX_FILTER0_5                        0x4414
+#define R300_TX_FILTER0_6                        0x4418
+#define R300_TX_FILTER0_7                        0x441c
+#define R300_TX_FILTER0_8                        0x4420
+#define R300_TX_FILTER0_9                        0x4424
+#define R300_TX_FILTER0_10                       0x4428
+#define R300_TX_FILTER0_11                       0x442c
+#define R300_TX_FILTER0_12                       0x4430
+#define R300_TX_FILTER0_13                       0x4434
+#define R300_TX_FILTER0_14                       0x4438
+#define R300_TX_FILTER0_15                       0x443c
+#       define R300_TX_REPEAT                    0
+#       define R300_TX_MIRRORED                  1
+#       define R300_TX_CLAMP_TO_EDGE             2
+#      define R300_TX_MIRROR_ONCE_TO_EDGE       3
+#       define R300_TX_CLAMP                     4
+#      define R300_TX_MIRROR_ONCE               5
+#       define R300_TX_CLAMP_TO_BORDER           6
+#      define R300_TX_MIRROR_ONCE_TO_BORDER     7
+#       define R300_TX_WRAP_S_SHIFT              0
+#       define R300_TX_WRAP_S_MASK               (7 << 0)
+#       define R300_TX_WRAP_T_SHIFT              3
+#       define R300_TX_WRAP_T_MASK               (7 << 3)
+#       define R300_TX_WRAP_R_SHIFT              6
+#       define R300_TX_WRAP_R_MASK               (7 << 6)
+#      define R300_TX_MAG_FILTER_4              (0 << 9)
+#       define R300_TX_MAG_FILTER_NEAREST        (1 << 9)
+#       define R300_TX_MAG_FILTER_LINEAR         (2 << 9)
+#       define R300_TX_MAG_FILTER_ANISO          (3 << 9)
+#       define R300_TX_MAG_FILTER_MASK           (3 << 9)
+#       define R300_TX_MIN_FILTER_NEAREST        (1 << 11)
+#       define R300_TX_MIN_FILTER_LINEAR         (2 << 11)
+#      define R300_TX_MIN_FILTER_ANISO          (3 << 11)
+#      define R300_TX_MIN_FILTER_MASK           (3 << 11)
+#      define R300_TX_MIN_FILTER_MIP_NONE       (0 << 13)
+#      define R300_TX_MIN_FILTER_MIP_NEAREST    (1 << 13)
+#      define R300_TX_MIN_FILTER_MIP_LINEAR     (2 << 13)
+#      define R300_TX_MIN_FILTER_MIP_MASK       (3 << 13)
+#      define R300_TX_MAX_ANISO_1_TO_1          (0 << 21)
+#      define R300_TX_MAX_ANISO_2_TO_1          (1 << 21)
+#      define R300_TX_MAX_ANISO_4_TO_1          (2 << 21)
+#      define R300_TX_MAX_ANISO_8_TO_1          (3 << 21)
+#      define R300_TX_MAX_ANISO_16_TO_1         (4 << 21)
+#      define R300_TX_MAX_ANISO_MASK            (7 << 21)
+
+#define R300_TX_FILTER1_0                      0x4440
+#      define R300_CHROMA_KEY_MODE_DISABLE    0
+#      define R300_CHROMA_KEY_FORCE           1
+#      define R300_CHROMA_KEY_BLEND           2
+#      define R300_MC_ROUND_NORMAL            (0<<2)
+#      define R300_MC_ROUND_MPEG4             (1<<2)
+#      define R300_LOD_BIAS_SHIFT             3
+#      define R300_LOD_BIAS_MASK              0x1ff8
+#      define R300_EDGE_ANISO_EDGE_DIAG       (0<<13)
+#      define R300_EDGE_ANISO_EDGE_ONLY       (1<<13)
+#      define R300_MC_COORD_TRUNCATE_DISABLE  (0<<14)
+#      define R300_MC_COORD_TRUNCATE_MPEG     (1<<14)
+#      define R300_TX_TRI_PERF_0_8            (0<<15)
+#      define R300_TX_TRI_PERF_1_8            (1<<15)
+#      define R300_TX_TRI_PERF_1_4            (2<<15)
+#      define R300_TX_TRI_PERF_3_8            (3<<15)
+#      define R300_ANISO_THRESHOLD_MASK       (7<<17)
+
+#      define R500_MACRO_SWITCH               (1<<22)
+#      define R500_BORDER_FIX                 (1<<31)
+
+#define R300_TX_SIZE_0                      0x4480
+#       define R300_TX_WIDTHMASK_SHIFT           0
+#       define R300_TX_WIDTHMASK_MASK            (2047 << 0)
+#       define R300_TX_HEIGHTMASK_SHIFT          11
+#       define R300_TX_HEIGHTMASK_MASK           (2047 << 11)
+#      define R300_TX_DEPTHMASK_SHIFT           22
+#      define R300_TX_DEPTHMASK_MASK            (0xf << 22)
+#       define R300_TX_MAX_MIP_LEVEL_SHIFT       26
+#       define R300_TX_MAX_MIP_LEVEL_MASK        (0xf << 26)
+#       define R300_TX_SIZE_PROJECTED            (1<<30)
+#       define R300_TX_SIZE_TXPITCH_EN           (1<<31)
+#define R300_TX_FORMAT_0                    0x44C0
+       /* The interpretation of the format word by Wladimir van der Laan */
+       /* The X, Y, Z and W refer to the layout of the components.
+          They are given meanings as R, G, B and Alpha by the swizzle
+          specification */
+#      define R300_TX_FORMAT_X8                    0x0
+#      define R500_TX_FORMAT_X1                    0x0 // bit set in format 2
+#      define R300_TX_FORMAT_X16                   0x1
+#      define R500_TX_FORMAT_X1_REV                0x0 // bit set in format 2
+#      define R300_TX_FORMAT_Y4X4                  0x2
+#      define R300_TX_FORMAT_Y8X8                  0x3
+#      define R300_TX_FORMAT_Y16X16                0x4
+#      define R300_TX_FORMAT_Z3Y3X2                0x5
+#      define R300_TX_FORMAT_Z5Y6X5                0x6
+#      define R300_TX_FORMAT_Z6Y5X5                0x7
+#      define R300_TX_FORMAT_Z11Y11X10             0x8
+#      define R300_TX_FORMAT_Z10Y11X11             0x9
+#      define R300_TX_FORMAT_W4Z4Y4X4              0xA
+#      define R300_TX_FORMAT_W1Z5Y5X5              0xB
+#      define R300_TX_FORMAT_W8Z8Y8X8              0xC
+#      define R300_TX_FORMAT_W2Z10Y10X10           0xD
+#      define R300_TX_FORMAT_W16Z16Y16X16          0xE
+#      define R300_TX_FORMAT_DXT1                  0xF
+#      define R300_TX_FORMAT_DXT3                  0x10
+#      define R300_TX_FORMAT_DXT5                  0x11
+#      define R300_TX_FORMAT_D3DMFT_CxV8U8         0x12     /* no swizzle */
+#      define R300_TX_FORMAT_A8R8G8B8              0x13     /* no swizzle */
+#      define R300_TX_FORMAT_B8G8_B8G8             0x14     /* no swizzle */
+#      define R300_TX_FORMAT_G8R8_G8B8             0x15     /* no swizzle */
+
+       /* These two values are wrong, but they're the only values that
+        * produce any even vaguely correct results.  Can r300 only do 16-bit
+        * depth textures?
+        */
+#      define R300_TX_FORMAT_X24_Y8                0x1e
+#      define R300_TX_FORMAT_X32                   0x1e
+
+       /* 0x16 - some 16 bit green format.. ?? */
+#      define R300_TX_FORMAT_3D                   (1 << 25)
+#      define R300_TX_FORMAT_CUBIC_MAP            (2 << 25)
+
+       /* gap */
+       /* Floating point formats */
+       /* Note - hardware supports both 16 and 32 bit floating point */
+#      define R300_TX_FORMAT_FL_I16                0x18
+#      define R300_TX_FORMAT_FL_I16A16             0x19
+#      define R300_TX_FORMAT_FL_R16G16B16A16       0x1A
+#      define R300_TX_FORMAT_FL_I32                0x1B
+#      define R300_TX_FORMAT_FL_I32A32             0x1C
+#      define R300_TX_FORMAT_FL_R32G32B32A32       0x1D
+       /* alpha modes, convenience mostly */
+       /* if you have alpha, pick constant appropriate to the
+          number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */
+#      define R300_TX_FORMAT_ALPHA_1CH             0x000
+#      define R300_TX_FORMAT_ALPHA_2CH             0x200
+#      define R300_TX_FORMAT_ALPHA_4CH             0x600
+#      define R300_TX_FORMAT_ALPHA_NONE            0xA00
+       /* Swizzling */
+       /* constants */
+#      define R300_TX_FORMAT_X         0
+#      define R300_TX_FORMAT_Y         1
+#      define R300_TX_FORMAT_Z         2
+#      define R300_TX_FORMAT_W         3
+#      define R300_TX_FORMAT_ZERO      4
+#      define R300_TX_FORMAT_ONE       5
+       /* 2.0*Z, everything above 1.0 is set to 0.0 */
+#      define R300_TX_FORMAT_CUT_Z     6
+       /* 2.0*W, everything above 1.0 is set to 0.0 */
+#      define R300_TX_FORMAT_CUT_W     7
+
+#      define R300_TX_FORMAT_B_SHIFT   18
+#      define R300_TX_FORMAT_G_SHIFT   15
+#      define R300_TX_FORMAT_R_SHIFT   12
+#      define R300_TX_FORMAT_A_SHIFT   9
+       /* Convenience macro to take care of layout and swizzling */
+#      define R300_EASY_TX_FORMAT(B, G, R, A, FMT)     (               \
+               ((R300_TX_FORMAT_##B)<<R300_TX_FORMAT_B_SHIFT)          \
+               | ((R300_TX_FORMAT_##G)<<R300_TX_FORMAT_G_SHIFT)        \
+               | ((R300_TX_FORMAT_##R)<<R300_TX_FORMAT_R_SHIFT)        \
+               | ((R300_TX_FORMAT_##A)<<R300_TX_FORMAT_A_SHIFT)        \
+               | (R300_TX_FORMAT_##FMT)                                \
+               )
+       /* These can be ORed with result of R300_EASY_TX_FORMAT()
+          We don't really know what they do. Take values from a
+           constant color ? */
+#      define R300_TX_FORMAT_CONST_X           (1<<5)
+#      define R300_TX_FORMAT_CONST_Y           (2<<5)
+#      define R300_TX_FORMAT_CONST_Z           (4<<5)
+#      define R300_TX_FORMAT_CONST_W           (8<<5)
+
+#      define R300_TX_FORMAT_YUV_MODE          0x00800000
+
+#define R300_TX_FORMAT2_0                  0x4500 /* obvious missing in gap */
+#       define R300_TX_PITCHMASK_SHIFT           0
+#       define R300_TX_PITCHMASK_MASK            (2047 << 0)
+#      define R500_TXFORMAT_MSB                 (1 << 14)
+#      define R500_TXWIDTH_BIT11                (1 << 15)
+#      define R500_TXHEIGHT_BIT11               (1 << 16)
+#      define R500_POW2FIX2FLT                  (1 << 17)
+#      define R500_SEL_FILTER4_TC0              (0 << 18)
+#      define R500_SEL_FILTER4_TC1              (1 << 18)
+#      define R500_SEL_FILTER4_TC2              (2 << 18)
+#      define R500_SEL_FILTER4_TC3              (3 << 18)
+
+#define R300_TX_OFFSET_0                    0x4540
+#define R300_TX_OFFSET_1                    0x4544
+#define R300_TX_OFFSET_2                    0x4548
+#define R300_TX_OFFSET_3                    0x454C
+#define R300_TX_OFFSET_4                    0x4550
+#define R300_TX_OFFSET_5                    0x4554
+#define R300_TX_OFFSET_6                    0x4558
+#define R300_TX_OFFSET_7                    0x455C
+       /* BEGIN: Guess from R200 */
+#       define R300_TXO_ENDIAN_NO_SWAP           (0 << 0)
+#       define R300_TXO_ENDIAN_BYTE_SWAP         (1 << 0)
+#       define R300_TXO_ENDIAN_WORD_SWAP         (2 << 0)
+#       define R300_TXO_ENDIAN_HALFDW_SWAP       (3 << 0)
+#       define R300_TXO_MACRO_TILE               (1 << 2)
+#       define R300_TXO_MICRO_TILE_LINEAR        (0 << 3)
+#       define R300_TXO_MICRO_TILE               (1 << 3)
+#       define R300_TXO_MICRO_TILE_SQUARE        (2 << 3)
+#       define R300_TXO_OFFSET_MASK              0xffffffe0
+#       define R300_TXO_OFFSET_SHIFT             5
+       /* END: Guess from R200 */
+
+/* 32 bit chroma key */
+#define R300_TX_CHROMA_KEY_0                      0x4580
+#define R300_TX_CHROMA_KEY_1                      0x4584
+#define R300_TX_CHROMA_KEY_2                      0x4588
+#define R300_TX_CHROMA_KEY_3                      0x458c
+#define R300_TX_CHROMA_KEY_4                      0x4590
+#define R300_TX_CHROMA_KEY_5                      0x4594
+#define R300_TX_CHROMA_KEY_6                      0x4598
+#define R300_TX_CHROMA_KEY_7                      0x459c
+#define R300_TX_CHROMA_KEY_8                      0x45a0
+#define R300_TX_CHROMA_KEY_9                      0x45a4
+#define R300_TX_CHROMA_KEY_10                     0x45a8
+#define R300_TX_CHROMA_KEY_11                     0x45ac
+#define R300_TX_CHROMA_KEY_12                     0x45b0
+#define R300_TX_CHROMA_KEY_13                     0x45b4
+#define R300_TX_CHROMA_KEY_14                     0x45b8
+#define R300_TX_CHROMA_KEY_15                     0x45bc
+/* ff00ff00 == { 0, 1.0, 0, 1.0 } */
+
+/* Border Color */
+#define R300_TX_BORDER_COLOR_0              0x45c0
+#define R300_TX_BORDER_COLOR_1              0x45c4
+#define R300_TX_BORDER_COLOR_2              0x45c8
+#define R300_TX_BORDER_COLOR_3              0x45cc
+#define R300_TX_BORDER_COLOR_4              0x45d0
+#define R300_TX_BORDER_COLOR_5              0x45d4
+#define R300_TX_BORDER_COLOR_6              0x45d8
+#define R300_TX_BORDER_COLOR_7              0x45dc
+#define R300_TX_BORDER_COLOR_8              0x45e0
+#define R300_TX_BORDER_COLOR_9              0x45e4
+#define R300_TX_BORDER_COLOR_10             0x45e8
+#define R300_TX_BORDER_COLOR_11             0x45ec
+#define R300_TX_BORDER_COLOR_12             0x45f0
+#define R300_TX_BORDER_COLOR_13             0x45f4
+#define R300_TX_BORDER_COLOR_14             0x45f8
+#define R300_TX_BORDER_COLOR_15             0x45fc
+
+
+/* END: Texture specification */
+
+/* BEGIN: Fragment program instruction set */
+
+/* Fragment programs are written directly into register space.
+ * There are separate instruction streams for texture instructions and ALU
+ * instructions.
+ * In order to synchronize these streams, the program is divided into up
+ * to 4 nodes. Each node begins with a number of TEX operations, followed
+ * by a number of ALU operations.
+ * The first node can have zero TEX ops, all subsequent nodes must have at
+ * least
+ * one TEX ops.
+ * All nodes must have at least one ALU op.
+ *
+ * The index of the last node is stored in PFS_CNTL_0: A value of 0 means
+ * 1 node, a value of 3 means 4 nodes.
+ * The total amount of instructions is defined in PFS_CNTL_2. The offsets are
+ * offsets into the respective instruction streams, while *_END points to the
+ * last instruction relative to this offset.
+ */
+#define R300_US_CONFIG                      0x4600
+#       define R300_PFS_CNTL_LAST_NODES_SHIFT    0
+#       define R300_PFS_CNTL_LAST_NODES_MASK     (3 << 0)
+#       define R300_PFS_CNTL_FIRST_NODE_HAS_TEX  (1 << 3)
+#define R300_US_PIXSIZE                     0x4604
+/* There is an unshifted value here which has so far always been equal to the
+ * index of the highest used temporary register.
+ */
+#define R300_US_CODE_OFFSET                 0x4608
+#       define R300_PFS_CNTL_ALU_OFFSET_SHIFT    0
+#       define R300_PFS_CNTL_ALU_OFFSET_MASK     (63 << 0)
+#       define R300_PFS_CNTL_ALU_END_SHIFT       6
+#       define R300_PFS_CNTL_ALU_END_MASK        (63 << 6)
+#       define R300_PFS_CNTL_TEX_OFFSET_SHIFT    13
+#       define R300_PFS_CNTL_TEX_OFFSET_MASK     (31 << 13)
+#       define R300_PFS_CNTL_TEX_END_SHIFT       18
+#       define R300_PFS_CNTL_TEX_END_MASK        (31 << 18)
+
+/* gap */
+
+/* Nodes are stored backwards. The last active node is always stored in
+ * PFS_NODE_3.
+ * Example: In a 2-node program, NODE_0 and NODE_1 are set to 0. The
+ * first node is stored in NODE_2, the second node is stored in NODE_3.
+ *
+ * Offsets are relative to the master offset from PFS_CNTL_2.
+ */
+#define R300_US_CODE_ADDR_0                 0x4610
+#define R300_US_CODE_ADDR_1                 0x4614
+#define R300_US_CODE_ADDR_2                 0x4618
+#define R300_US_CODE_ADDR_3                 0x461C
+#       define R300_ALU_START_SHIFT         0
+#       define R300_ALU_START_MASK          (63 << 0)
+#       define R300_ALU_SIZE_SHIFT          6
+#       define R300_ALU_SIZE_MASK           (63 << 6)
+#       define R300_TEX_START_SHIFT         12
+#       define R300_TEX_START_MASK          (31 << 12)
+#       define R300_TEX_SIZE_SHIFT          17
+#       define R300_TEX_SIZE_MASK           (31 << 17)
+#      define R300_RGBA_OUT                (1 << 22)
+#      define R300_W_OUT                   (1 << 23)
+
+/* TEX
+ * As far as I can tell, texture instructions cannot write into output
+ * registers directly. A subsequent ALU instruction is always necessary,
+ * even if it's just MAD o0, r0, 1, 0
+ */
+#define R300_US_TEX_INST_0                  0x4620
+#      define R300_SRC_ADDR_SHIFT          0
+#      define R300_SRC_ADDR_MASK           (31 << 0)
+#      define R300_DST_ADDR_SHIFT          6
+#      define R300_DST_ADDR_MASK           (31 << 6)
+#      define R300_TEX_ID_SHIFT            11
+#       define R300_TEX_ID_MASK             (15 << 11)
+#      define R300_TEX_INST_SHIFT              15
+#              define R300_TEX_OP_NOP          0
+#              define R300_TEX_OP_LD           1
+#              define R300_TEX_OP_KIL          2
+#              define R300_TEX_OP_TXP          3
+#              define R300_TEX_OP_TXB          4
+#      define R300_TEX_INST_MASK               (7 << 15)
+
+/* Output format from the unfied shader */
+#define R300_US_OUT_FMT_0                   0x46A4
+#      define R300_US_OUT_FMT_C4_8         (0 << 0)
+#      define R300_US_OUT_FMT_C4_10        (1 << 0)
+#      define R300_US_OUT_FMT_C4_10_GAMMA  (2 << 0)
+#      define R300_US_OUT_FMT_C_16         (3 << 0)
+#      define R300_US_OUT_FMT_C2_16        (4 << 0)
+#      define R300_US_OUT_FMT_C4_16        (5 << 0)
+#      define R300_US_OUT_FMT_C_16_MPEG    (6 << 0)
+#      define R300_US_OUT_FMT_C2_16_MPEG   (7 << 0)
+#      define R300_US_OUT_FMT_C2_4         (8 << 0)
+#      define R300_US_OUT_FMT_C_3_3_2      (9 << 0)
+#      define R300_US_OUT_FMT_C_6_5_6      (10 << 0)
+#      define R300_US_OUT_FMT_C_11_11_10   (11 << 0)
+#      define R300_US_OUT_FMT_C_10_11_11   (12 << 0)
+#      define R300_US_OUT_FMT_C_2_10_10_10 (13 << 0)
+/* reserved */
+#      define R300_US_OUT_FMT_UNUSED       (15 << 0)
+#      define R300_US_OUT_FMT_C_16_FP      (16 << 0)
+#      define R300_US_OUT_FMT_C2_16_FP     (17 << 0)
+#      define R300_US_OUT_FMT_C4_16_FP     (18 << 0)
+#      define R300_US_OUT_FMT_C_32_FP      (19 << 0)
+#      define R300_US_OUT_FMT_C2_32_FP     (20 << 0)
+#      define R300_US_OUT_FMT_C4_32_FP     (21 << 0)
+#   define R300_C0_SEL_A                               (0 << 8)
+#   define R300_C0_SEL_R                               (1 << 8)
+#   define R300_C0_SEL_G                               (2 << 8)
+#   define R300_C0_SEL_B                               (3 << 8)
+#   define R300_C1_SEL_A                               (0 << 10)
+#   define R300_C1_SEL_R                               (1 << 10)
+#   define R300_C1_SEL_G                               (2 << 10)
+#   define R300_C1_SEL_B                               (3 << 10)
+#   define R300_C2_SEL_A                               (0 << 12)
+#   define R300_C2_SEL_R                               (1 << 12)
+#   define R300_C2_SEL_G                               (2 << 12)
+#   define R300_C2_SEL_B                               (3 << 12)
+#   define R300_C3_SEL_A                               (0 << 14)
+#   define R300_C3_SEL_R                               (1 << 14)
+#   define R300_C3_SEL_G                               (2 << 14)
+#   define R300_C3_SEL_B                               (3 << 14)
+#   define R300_OUT_SIGN(x)                            (x << 16)
+
+/* ALU
+ * The ALU instructions register blocks are enumerated according to the order
+ * in which fglrx. I assume there is space for 64 instructions, since
+ * each block has space for a maximum of 64 DWORDs, and this matches reported
+ * native limits.
+ *
+ * The basic functional block seems to be one MAD for each color and alpha,
+ * and an adder that adds all components after the MUL.
+ *  - ADD, MUL, MAD etc.: use MAD with appropriate neutral operands
+ *  - DP4: Use OUTC_DP4, OUTA_DP4
+ *  - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands
+ *  - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands
+ *  - CMPH: If ARG2 > 0.5, return ARG0, else return ARG1
+ *  - CMP: If ARG2 < 0, return ARG1, else return ARG0
+ *  - FLR: use FRC+MAD
+ *  - XPD: use MAD+MAD
+ *  - SGE, SLT: use MAD+CMP
+ *  - RSQ: use ABS modifier for argument
+ *  - Use OUTC_REPL_ALPHA to write results of an alpha-only operation
+ *    (e.g. RCP) into color register
+ *  - apparently, there's no quick DST operation
+ *  - fglrx set FPI2_UNKNOWN_31 on a "MAD fragment.color, tmp0, tmp1, tmp2"
+ *  - fglrx set FPI2_UNKNOWN_31 on a "MAX r2, r1, c0"
+ *  - fglrx once set FPI0_UNKNOWN_31 on a "FRC r1, r1"
+ *
+ * Operand selection
+ * First stage selects three sources from the available registers and
+ * constant parameters. This is defined in INSTR1 (color) and INSTR3 (alpha).
+ * fglrx sorts the three source fields: Registers before constants,
+ * lower indices before higher indices; I do not know whether this is
+ * necessary.
+ *
+ * fglrx fills unused sources with "read constant 0"
+ * According to specs, you cannot select more than two different constants.
+ *
+ * Second stage selects the operands from the sources. This is defined in
+ * INSTR0 (color) and INSTR2 (alpha). You can also select the special constants
+ * zero and one.
+ * Swizzling and negation happens in this stage, as well.
+ *
+ * Important: Color and alpha seem to be mostly separate, i.e. their sources
+ * selection appears to be fully independent (the register storage is probably
+ * physically split into a color and an alpha section).
+ * However (because of the apparent physical split), there is some interaction
+ * WRT swizzling. If, for example, you want to load an R component into an
+ * Alpha operand, this R component is taken from a *color* source, not from
+ * an alpha source. The corresponding register doesn't even have to appear in
+ * the alpha sources list. (I hope this all makes sense to you)
+ *
+ * Destination selection
+ * The destination register index is in FPI1 (color) and FPI3 (alpha)
+ * together with enable bits.
+ * There are separate enable bits for writing into temporary registers
+ * (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_*
+ * /DSTA_OUTPUT). You can write to both at once, or not write at all (the
+ * same index must be used for both).
+ *
+ * Note: There is a special form for LRP
+ *  - Argument order is the same as in ARB_fragment_program.
+ *  - Operation is MAD
+ *  - ARG1 is set to ARGC_SRC1C_LRP/ARGC_SRC1A_LRP
+ *  - Set FPI0/FPI2_SPECIAL_LRP
+ * Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD
+ */
+#define R300_US_ALU_RGB_ADDR_0                   0x46C0
+#       define R300_ALU_SRC0C_SHIFT             0
+#       define R300_ALU_SRC0C_MASK              (31 << 0)
+#       define R300_ALU_SRC0C_CONST             (1 << 5)
+#       define R300_ALU_SRC1C_SHIFT             6
+#       define R300_ALU_SRC1C_MASK              (31 << 6)
+#       define R300_ALU_SRC1C_CONST             (1 << 11)
+#       define R300_ALU_SRC2C_SHIFT             12
+#       define R300_ALU_SRC2C_MASK              (31 << 12)
+#       define R300_ALU_SRC2C_CONST             (1 << 17)
+#       define R300_ALU_SRC_MASK                0x0003ffff
+#       define R300_ALU_DSTC_SHIFT              18
+#       define R300_ALU_DSTC_MASK               (31 << 18)
+#              define R300_ALU_DSTC_REG_MASK_SHIFT     23
+#       define R300_ALU_DSTC_REG_X              (1 << 23)
+#       define R300_ALU_DSTC_REG_Y              (1 << 24)
+#       define R300_ALU_DSTC_REG_Z              (1 << 25)
+#              define R300_ALU_DSTC_OUTPUT_MASK_SHIFT  26
+#       define R300_ALU_DSTC_OUTPUT_X           (1 << 26)
+#       define R300_ALU_DSTC_OUTPUT_Y           (1 << 27)
+#       define R300_ALU_DSTC_OUTPUT_Z           (1 << 28)
+
+#define R300_US_ALU_ALPHA_ADDR_0                 0x47C0
+#       define R300_ALU_SRC0A_SHIFT             0
+#       define R300_ALU_SRC0A_MASK              (31 << 0)
+#       define R300_ALU_SRC0A_CONST             (1 << 5)
+#       define R300_ALU_SRC1A_SHIFT             6
+#       define R300_ALU_SRC1A_MASK              (31 << 6)
+#       define R300_ALU_SRC1A_CONST             (1 << 11)
+#       define R300_ALU_SRC2A_SHIFT             12
+#       define R300_ALU_SRC2A_MASK              (31 << 12)
+#       define R300_ALU_SRC2A_CONST             (1 << 17)
+#       define R300_ALU_SRC_MASK                0x0003ffff
+#       define R300_ALU_DSTA_SHIFT              18
+#       define R300_ALU_DSTA_MASK               (31 << 18)
+#       define R300_ALU_DSTA_REG                (1 << 23)
+#       define R300_ALU_DSTA_OUTPUT             (1 << 24)
+#              define R300_ALU_DSTA_DEPTH              (1 << 27)
+
+#define R300_US_ALU_RGB_INST_0                   0x48C0
+#       define R300_ALU_ARGC_SRC0C_XYZ          0
+#       define R300_ALU_ARGC_SRC0C_XXX          1
+#       define R300_ALU_ARGC_SRC0C_YYY          2
+#       define R300_ALU_ARGC_SRC0C_ZZZ          3
+#       define R300_ALU_ARGC_SRC1C_XYZ          4
+#       define R300_ALU_ARGC_SRC1C_XXX          5
+#       define R300_ALU_ARGC_SRC1C_YYY          6
+#       define R300_ALU_ARGC_SRC1C_ZZZ          7
+#       define R300_ALU_ARGC_SRC2C_XYZ          8
+#       define R300_ALU_ARGC_SRC2C_XXX          9
+#       define R300_ALU_ARGC_SRC2C_YYY          10
+#       define R300_ALU_ARGC_SRC2C_ZZZ          11
+#       define R300_ALU_ARGC_SRC0A              12
+#       define R300_ALU_ARGC_SRC1A              13
+#       define R300_ALU_ARGC_SRC2A              14
+#       define R300_ALU_ARGC_SRCP_XYZ           15
+#       define R300_ALU_ARGC_SRCP_XXX           16
+#       define R300_ALU_ARGC_SRCP_YYY           17
+#       define R300_ALU_ARGC_SRCP_ZZZ           18
+#       define R300_ALU_ARGC_SRCP_WWW           19
+#       define R300_ALU_ARGC_ZERO               20
+#       define R300_ALU_ARGC_ONE                21
+#       define R300_ALU_ARGC_HALF               22
+#       define R300_ALU_ARGC_SRC0C_YZX          23
+#       define R300_ALU_ARGC_SRC1C_YZX          24
+#       define R300_ALU_ARGC_SRC2C_YZX          25
+#       define R300_ALU_ARGC_SRC0C_ZXY          26
+#       define R300_ALU_ARGC_SRC1C_ZXY          27
+#       define R300_ALU_ARGC_SRC2C_ZXY          28
+#       define R300_ALU_ARGC_SRC0CA_WZY         29
+#       define R300_ALU_ARGC_SRC1CA_WZY         30
+#       define R300_ALU_ARGC_SRC2CA_WZY         31
+
+#       define R300_ALU_ARG0C_SHIFT             0
+#       define R300_ALU_ARG0C_MASK              (31 << 0)
+#       define R300_ALU_ARG0C_NOP               (0 << 5)
+#       define R300_ALU_ARG0C_NEG               (1 << 5)
+#       define R300_ALU_ARG0C_ABS               (2 << 5)
+#       define R300_ALU_ARG0C_NAB               (3 << 5)
+#       define R300_ALU_ARG1C_SHIFT             7
+#       define R300_ALU_ARG1C_MASK              (31 << 7)
+#       define R300_ALU_ARG1C_NOP               (0 << 12)
+#       define R300_ALU_ARG1C_NEG               (1 << 12)
+#       define R300_ALU_ARG1C_ABS               (2 << 12)
+#       define R300_ALU_ARG1C_NAB               (3 << 12)
+#       define R300_ALU_ARG2C_SHIFT             14
+#       define R300_ALU_ARG2C_MASK              (31 << 14)
+#       define R300_ALU_ARG2C_NOP               (0 << 19)
+#       define R300_ALU_ARG2C_NEG               (1 << 19)
+#       define R300_ALU_ARG2C_ABS               (2 << 19)
+#       define R300_ALU_ARG2C_NAB               (3 << 19)
+#       define R300_ALU_SRCP_1_MINUS_2_SRC0     (0 << 21)
+#       define R300_ALU_SRCP_SRC1_MINUS_SRC0    (1 << 21)
+#       define R300_ALU_SRCP_SRC1_PLUS_SRC0     (2 << 21)
+#       define R300_ALU_SRCP_1_MINUS_SRC0       (3 << 21)
+
+#       define R300_ALU_OUTC_MAD                (0 << 23)
+#       define R300_ALU_OUTC_DP3                (1 << 23)
+#       define R300_ALU_OUTC_DP4                (2 << 23)
+#       define R300_ALU_OUTC_D2A                (3 << 23)
+#       define R300_ALU_OUTC_MIN                (4 << 23)
+#       define R300_ALU_OUTC_MAX                (5 << 23)
+#       define R300_ALU_OUTC_CMPH               (7 << 23)
+#       define R300_ALU_OUTC_CMP                (8 << 23)
+#       define R300_ALU_OUTC_FRC                (9 << 23)
+#       define R300_ALU_OUTC_REPL_ALPHA         (10 << 23)
+
+#       define R300_ALU_OUTC_MOD_NOP            (0 << 27)
+#       define R300_ALU_OUTC_MOD_MUL2           (1 << 27)
+#       define R300_ALU_OUTC_MOD_MUL4           (2 << 27)
+#       define R300_ALU_OUTC_MOD_MUL8           (3 << 27)
+#       define R300_ALU_OUTC_MOD_DIV2           (4 << 27)
+#       define R300_ALU_OUTC_MOD_DIV4           (5 << 27)
+#       define R300_ALU_OUTC_MOD_DIV8           (6 << 27)
+
+#       define R300_ALU_OUTC_CLAMP              (1 << 30)
+#       define R300_ALU_INSERT_NOP              (1 << 31)
+
+#define R300_US_ALU_ALPHA_INST_0                 0x49C0
+#       define R300_ALU_ARGA_SRC0C_X            0
+#       define R300_ALU_ARGA_SRC0C_Y            1
+#       define R300_ALU_ARGA_SRC0C_Z            2
+#       define R300_ALU_ARGA_SRC1C_X            3
+#       define R300_ALU_ARGA_SRC1C_Y            4
+#       define R300_ALU_ARGA_SRC1C_Z            5
+#       define R300_ALU_ARGA_SRC2C_X            6
+#       define R300_ALU_ARGA_SRC2C_Y            7
+#       define R300_ALU_ARGA_SRC2C_Z            8
+#       define R300_ALU_ARGA_SRC0A              9
+#       define R300_ALU_ARGA_SRC1A              10
+#       define R300_ALU_ARGA_SRC2A              11
+#       define R300_ALU_ARGA_SRCP_X             12
+#       define R300_ALU_ARGA_SRCP_Y             13
+#       define R300_ALU_ARGA_SRCP_Z             14
+#       define R300_ALU_ARGA_SRCP_W             15
+
+#       define R300_ALU_ARGA_ZERO               16
+#       define R300_ALU_ARGA_ONE                17
+#       define R300_ALU_ARGA_HALF               18
+#       define R300_ALU_ARG0A_SHIFT             0
+#       define R300_ALU_ARG0A_MASK              (31 << 0)
+#       define R300_ALU_ARG0A_NOP               (0 << 5)
+#       define R300_ALU_ARG0A_NEG               (1 << 5)
+#      define R300_ALU_ARG0A_ABS                (2 << 5)
+#      define R300_ALU_ARG0A_NAB                (3 << 5)
+#       define R300_ALU_ARG1A_SHIFT             7
+#       define R300_ALU_ARG1A_MASK              (31 << 7)
+#       define R300_ALU_ARG1A_NOP               (0 << 12)
+#       define R300_ALU_ARG1A_NEG               (1 << 12)
+#      define R300_ALU_ARG1A_ABS                (2 << 12)
+#      define R300_ALU_ARG1A_NAB                (3 << 12)
+#       define R300_ALU_ARG2A_SHIFT             14
+#       define R300_ALU_ARG2A_MASK              (31 << 14)
+#       define R300_ALU_ARG2A_NOP               (0 << 19)
+#       define R300_ALU_ARG2A_NEG               (1 << 19)
+#      define R300_ALU_ARG2A_ABS                (2 << 19)
+#      define R300_ALU_ARG2A_NAB                (3 << 19)
+#       define R300_ALU_SRCP_1_MINUS_2_SRC0     (0 << 21)
+#       define R300_ALU_SRCP_SRC1_MINUS_SRC0    (1 << 21)
+#       define R300_ALU_SRCP_SRC1_PLUS_SRC0     (2 << 21)
+#       define R300_ALU_SRCP_1_MINUS_SRC0       (3 << 21)
+
+#       define R300_ALU_OUTA_MAD                (0 << 23)
+#       define R300_ALU_OUTA_DP4                (1 << 23)
+#       define R300_ALU_OUTA_MIN                (2 << 23)
+#       define R300_ALU_OUTA_MAX                (3 << 23)
+#       define R300_ALU_OUTA_CND                (5 << 23)
+#       define R300_ALU_OUTA_CMP                (6 << 23)
+#       define R300_ALU_OUTA_FRC                (7 << 23)
+#       define R300_ALU_OUTA_EX2                (8 << 23)
+#       define R300_ALU_OUTA_LG2                (9 << 23)
+#       define R300_ALU_OUTA_RCP                (10 << 23)
+#       define R300_ALU_OUTA_RSQ                (11 << 23)
+
+#       define R300_ALU_OUTA_MOD_NOP            (0 << 27)
+#       define R300_ALU_OUTA_MOD_MUL2           (1 << 27)
+#       define R300_ALU_OUTA_MOD_MUL4           (2 << 27)
+#       define R300_ALU_OUTA_MOD_MUL8           (3 << 27)
+#       define R300_ALU_OUTA_MOD_DIV2           (4 << 27)
+#       define R300_ALU_OUTA_MOD_DIV4           (5 << 27)
+#       define R300_ALU_OUTA_MOD_DIV8           (6 << 27)
+
+#       define R300_ALU_OUTA_CLAMP              (1 << 30)
+/* END: Fragment program instruction set */
+
+/* Fog: Fog Blending Enable */
+#define R300_FG_FOG_BLEND                             0x4bc0
+#       define R300_FG_FOG_BLEND_DISABLE              (0 << 0)
+#       define R300_FG_FOG_BLEND_ENABLE               (1 << 0)
+#      define R300_FG_FOG_BLEND_FN_LINEAR            (0 << 1)
+#      define R300_FG_FOG_BLEND_FN_EXP               (1 << 1)
+#      define R300_FG_FOG_BLEND_FN_EXP2              (2 << 1)
+#      define R300_FG_FOG_BLEND_FN_CONSTANT          (3 << 1)
+#      define R300_FG_FOG_BLEND_FN_MASK              (3 << 1)
+
+/* Fog: Red Component of Fog Color */
+#define R300_FG_FOG_COLOR_R                           0x4bc8
+/* Fog: Green Component of Fog Color */
+#define R300_FG_FOG_COLOR_G                           0x4bcc
+/* Fog: Blue Component of Fog Color */
+#define R300_FG_FOG_COLOR_B                           0x4bd0
+#      define R300_FG_FOG_COLOR_MASK 0x000003ff
+
+/* Fog: Constant Factor for Fog Blending */
+#define R300_FG_FOG_FACTOR                            0x4bc4
+#      define FG_FOG_FACTOR_MASK 0x000003ff
+
+/* Fog: Alpha function */
+#define R300_FG_ALPHA_FUNC                            0x4bd4
+#       define R300_FG_ALPHA_FUNC_VAL_MASK               0x000000ff
+#       define R300_FG_ALPHA_FUNC_NEVER                     (0 << 8)
+#       define R300_FG_ALPHA_FUNC_LESS                      (1 << 8)
+#       define R300_FG_ALPHA_FUNC_EQUAL                     (2 << 8)
+#       define R300_FG_ALPHA_FUNC_LE                        (3 << 8)
+#       define R300_FG_ALPHA_FUNC_GREATER                   (4 << 8)
+#       define R300_FG_ALPHA_FUNC_NOTEQUAL                  (5 << 8)
+#       define R300_FG_ALPHA_FUNC_GE                        (6 << 8)
+#       define R300_FG_ALPHA_FUNC_ALWAYS                    (7 << 8)
+#       define R300_ALPHA_TEST_OP_MASK                      (7 << 8)
+#       define R300_FG_ALPHA_FUNC_DISABLE                   (0 << 11)
+#       define R300_FG_ALPHA_FUNC_ENABLE                    (1 << 11)
+
+#       define R500_FG_ALPHA_FUNC_10BIT                     (0 << 12)
+#       define R500_FG_ALPHA_FUNC_8BIT                      (1 << 12)
+
+#       define R300_FG_ALPHA_FUNC_MASK_DISABLE              (0 << 16)
+#       define R300_FG_ALPHA_FUNC_MASK_ENABLE               (1 << 16)
+#       define R300_FG_ALPHA_FUNC_CFG_2_OF_4                (0 << 17)
+#       define R300_FG_ALPHA_FUNC_CFG_3_OF_6                (1 << 17)
+
+#       define R300_FG_ALPHA_FUNC_DITH_DISABLE              (0 << 20)
+#       define R300_FG_ALPHA_FUNC_DITH_ENABLE               (1 << 20)
+
+#       define R500_FG_ALPHA_FUNC_OFFSET_DISABLE            (0 << 24)
+#       define R500_FG_ALPHA_FUNC_OFFSET_ENABLE             (1 << 24) /* Not supported in R520 */
+#       define R500_FG_ALPHA_FUNC_DISC_ZERO_MASK_DISABLE    (0 << 25)
+#       define R500_FG_ALPHA_FUNC_DISC_ZERO_MASK_ENABLE     (1 << 25)
+
+#       define R500_FG_ALPHA_FUNC_FP16_DISABLE              (0 << 28)
+#       define R500_FG_ALPHA_FUNC_FP16_ENABLE               (1 << 28)
+
+
+/* Fog: Where does the depth come from? */
+#define R300_FG_DEPTH_SRC                  0x4bd8
+#      define R300_FG_DEPTH_SRC_SCAN   (0 << 0)
+#      define R300_FG_DEPTH_SRC_SHADER (1 << 0)
+
+/* Fog: Alpha Compare Value */
+#define R500_FG_ALPHA_VALUE                0x4be0
+#      define R500_FG_ALPHA_VALUE_MASK 0x0000ffff
+
+/* gap */
+
+/* Fragment program parameters in 7.16 floating point */
+#define R300_PFS_PARAM_0_X                  0x4C00
+#define R300_PFS_PARAM_0_Y                  0x4C04
+#define R300_PFS_PARAM_0_Z                  0x4C08
+#define R300_PFS_PARAM_0_W                  0x4C0C
+/* last consts */
+#define R300_PFS_PARAM_31_X                 0x4DF0
+#define R300_PFS_PARAM_31_Y                 0x4DF4
+#define R300_PFS_PARAM_31_Z                 0x4DF8
+#define R300_PFS_PARAM_31_W                 0x4DFC
+
+/* Unpipelined. */
+#define R300_RB3D_CCTL                      0x4e00
+#      define R300_RB3D_CCTL_NUM_MULTIWRITES_1_BUFFER                (0 << 5)
+#      define R300_RB3D_CCTL_NUM_MULTIWRITES_2_BUFFERS               (1 << 5)
+#      define R300_RB3D_CCTL_NUM_MULTIWRITES_3_BUFFERS               (2 << 5)
+#      define R300_RB3D_CCTL_NUM_MULTIWRITES_4_BUFFERS               (3 << 5)
+#      define R300_RB3D_CCTL_CLRCMP_FLIPE_DISABLE                    (0 << 7)
+#      define R300_RB3D_CCTL_CLRCMP_FLIPE_ENABLE                     (1 << 7)
+#      define R300_RB3D_CCTL_AA_COMPRESSION_DISABLE                  (0 << 9)
+#      define R300_RB3D_CCTL_AA_COMPRESSION_ENABLE                   (1 << 9)
+#      define R300_RB3D_CCTL_CMASK_DISABLE                           (0 << 10)
+#      define R300_RB3D_CCTL_CMASK_ENABLE                            (1 << 10)
+/* reserved */
+#      define R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_DISABLE  (0 << 12)
+#      define R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_ENABLE   (1 << 12)
+#      define R300_RB3D_CCTL_WRITE_COMPRESSION_ENABLE                (0 << 13)
+#      define R300_RB3D_CCTL_WRITE_COMPRESSION_DISABLE               (1 << 13)
+#      define R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_DISABLE  (0 << 14)
+#      define R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE   (1 << 14)
+
+
+/* Notes:
+ * - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in
+ *   the application
+ * - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND
+ *    are set to the same
+ *   function (both registers are always set up completely in any case)
+ * - Most blend flags are simply copied from R200 and not tested yet
+ */
+#define R300_RB3D_CBLEND                    0x4E04
+#define R300_RB3D_ABLEND                    0x4E08
+/* the following only appear in CBLEND */
+#       define R300_ALPHA_BLEND_ENABLE         (1 << 0)
+#       define R300_SEPARATE_ALPHA_ENABLE      (1 << 1)
+#       define R300_READ_ENABLE                (1 << 2)
+#       define R300_DISCARD_SRC_PIXELS_DIS     (0 << 3)
+#       define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0     (1 << 3)
+#       define R300_DISCARD_SRC_PIXELS_SRC_COLOR_0     (2 << 3)
+#       define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_0     (3 << 3)
+#       define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_1     (4 << 3)
+#       define R300_DISCARD_SRC_PIXELS_SRC_COLOR_1     (5 << 3)
+#       define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_1     (6 << 3)
+
+/* the following are shared between CBLEND and ABLEND */
+#       define R300_FCN_MASK                         (3  << 12)
+#       define R300_COMB_FCN_ADD_CLAMP               (0  << 12)
+#       define R300_COMB_FCN_ADD_NOCLAMP             (1  << 12)
+#       define R300_COMB_FCN_SUB_CLAMP               (2  << 12)
+#       define R300_COMB_FCN_SUB_NOCLAMP             (3  << 12)
+#       define R300_COMB_FCN_MIN                     (4  << 12)
+#       define R300_COMB_FCN_MAX                     (5  << 12)
+#       define R300_COMB_FCN_RSUB_CLAMP              (6  << 12)
+#       define R300_COMB_FCN_RSUB_NOCLAMP            (7  << 12)
+#       define R300_BLEND_GL_ZERO                    (32)
+#       define R300_BLEND_GL_ONE                     (33)
+#       define R300_BLEND_GL_SRC_COLOR               (34)
+#       define R300_BLEND_GL_ONE_MINUS_SRC_COLOR     (35)
+#       define R300_BLEND_GL_DST_COLOR               (36)
+#       define R300_BLEND_GL_ONE_MINUS_DST_COLOR     (37)
+#       define R300_BLEND_GL_SRC_ALPHA               (38)
+#       define R300_BLEND_GL_ONE_MINUS_SRC_ALPHA     (39)
+#       define R300_BLEND_GL_DST_ALPHA               (40)
+#       define R300_BLEND_GL_ONE_MINUS_DST_ALPHA     (41)
+#       define R300_BLEND_GL_SRC_ALPHA_SATURATE      (42)
+#       define R300_BLEND_GL_CONST_COLOR             (43)
+#       define R300_BLEND_GL_ONE_MINUS_CONST_COLOR   (44)
+#       define R300_BLEND_GL_CONST_ALPHA             (45)
+#       define R300_BLEND_GL_ONE_MINUS_CONST_ALPHA   (46)
+#       define R300_BLEND_MASK                       (63)
+#       define R300_SRC_BLEND_SHIFT                  (16)
+#       define R300_DST_BLEND_SHIFT                  (24)
+
+/* Constant color used by the blender. Pipelined through the blender.
+ * Note: For R520, this field is ignored, use RB3D_CONSTANT_COLOR_GB__BLUE,
+ * RB3D_CONSTANT_COLOR_GB__GREEN, etc. instead.
+ */
+#define R300_RB3D_BLEND_COLOR               0x4E10
+
+
+/* 3D Color Channel Mask. If all the channels used in the current color format
+ * are disabled, then the cb will discard all the incoming quads. Pipelined
+ * through the blender.
+ */
+#define RB3D_COLOR_CHANNEL_MASK                  0x4E0C
+#      define RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0  (1 << 0)
+#      define RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 (1 << 1)
+#      define RB3D_COLOR_CHANNEL_MASK_RED_MASK0   (1 << 2)
+#      define RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 (1 << 3)
+#      define RB3D_COLOR_CHANNEL_MASK_BLUE_MASK1  (1 << 4)
+#      define RB3D_COLOR_CHANNEL_MASK_GREEN_MASK1 (1 << 5)
+#      define RB3D_COLOR_CHANNEL_MASK_RED_MASK1   (1 << 6)
+#      define RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK1 (1 << 7)
+#      define RB3D_COLOR_CHANNEL_MASK_BLUE_MASK2  (1 << 8)
+#      define RB3D_COLOR_CHANNEL_MASK_GREEN_MASK2 (1 << 9)
+#      define RB3D_COLOR_CHANNEL_MASK_RED_MASK2   (1 << 10)
+#      define RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK2 (1 << 11)
+#      define RB3D_COLOR_CHANNEL_MASK_BLUE_MASK3  (1 << 12)
+#      define RB3D_COLOR_CHANNEL_MASK_GREEN_MASK3 (1 << 13)
+#      define RB3D_COLOR_CHANNEL_MASK_RED_MASK3   (1 << 14)
+#      define RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK3 (1 << 15)
+
+/* Clear color that is used when the color mask is set to 00. Unpipelined.
+ * Program this register with a 32-bit value in ARGB8888 or ARGB2101010
+ * formats, ignoring the fields.
+ */
+#define RB3D_COLOR_CLEAR_VALUE                   0x4e14
+
+/* gap */
+
+/* Color Compare Color. Stalls the 2d/3d datapath until it is idle. */
+#define RB3D_CLRCMP_CLR                     0x4e20
+
+/* Color Compare Mask. Stalls the 2d/3d datapath until it is idle. */
+#define RB3D_CLRCMP_MSK                     0x4e24
+
+/* Color Buffer Address Offset of multibuffer 0. Unpipelined. */
+#define R300_RB3D_COLOROFFSET0              0x4E28
+#       define R300_COLOROFFSET_MASK             0xFFFFFFE0
+/* Color Buffer Address Offset of multibuffer 1. Unpipelined. */
+#define R300_RB3D_COLOROFFSET1              0x4E2C
+/* Color Buffer Address Offset of multibuffer 2. Unpipelined. */
+#define R300_RB3D_COLOROFFSET2              0x4E30
+/* Color Buffer Address Offset of multibuffer 3. Unpipelined. */
+#define R300_RB3D_COLOROFFSET3              0x4E34
+
+/* Color buffer format and tiling control for all the multibuffers and the
+ * pitch of multibuffer 0 to 3. Unpipelined. The cache must be empty before any
+ * of the registers are changed.
+ *
+ * Bit 16: Larger tiles
+ * Bit 17: 4x2 tiles
+ * Bit 18: Extremely weird tile like, but some pixels duplicated?
+ */
+#define R300_RB3D_COLORPITCH0               0x4E38
+#       define R300_COLORPITCH_MASK              0x00003FFE
+#       define R300_COLOR_TILE_DISABLE            (0 << 16)
+#       define R300_COLOR_TILE_ENABLE             (1 << 16)
+#       define R300_COLOR_MICROTILE_DISABLE       (0 << 17)
+#       define R300_COLOR_MICROTILE_ENABLE        (1 << 17)
+#       define R300_COLOR_MICROTILE_ENABLE_SQUARE (2 << 17) /* Only available in 16-bit */
+#       define R300_COLOR_ENDIAN_NO_SWAP          (0 << 19)
+#       define R300_COLOR_ENDIAN_WORD_SWAP        (1 << 19)
+#       define R300_COLOR_ENDIAN_DWORD_SWAP       (2 << 19)
+#       define R300_COLOR_ENDIAN_HALF_DWORD_SWAP  (3 << 19)
+#      define R500_COLOR_FORMAT_ARGB10101010     (0 << 21)
+#      define R500_COLOR_FORMAT_UV1010           (1 << 21)
+#      define R500_COLOR_FORMAT_CI8              (2 << 21) /* 2D only */
+#      define R300_COLOR_FORMAT_ARGB1555         (3 << 21)
+#       define R300_COLOR_FORMAT_RGB565           (4 << 21)
+#       define R500_COLOR_FORMAT_ARGB2101010      (5 << 21)
+#       define R300_COLOR_FORMAT_ARGB8888         (6 << 21)
+#       define R300_COLOR_FORMAT_ARGB32323232     (7 << 21)
+/* reserved */
+#       define R300_COLOR_FORMAT_I8               (9 << 21)
+#       define R300_COLOR_FORMAT_ARGB16161616     (10 << 21)
+#       define R300_COLOR_FORMAT_VYUY             (11 << 21)
+#       define R300_COLOR_FORMAT_YVYU             (12 << 21)
+#       define R300_COLOR_FORMAT_UV88             (13 << 21)
+#       define R500_COLOR_FORMAT_I10              (14 << 21)
+#       define R300_COLOR_FORMAT_ARGB4444         (15 << 21)
+#define R300_RB3D_COLORPITCH1               0x4E3C
+#define R300_RB3D_COLORPITCH2               0x4E40
+#define R300_RB3D_COLORPITCH3               0x4E44
+
+/* gap */
+
+/* Destination Color Buffer Cache Control/Status. If the cb is in e2 mode, then
+ * a flush or free will not occur upon a write to this register, but a sync
+ * will be immediately sent if one is requested. If both DC_FLUSH and DC_FREE
+ * are zero but DC_FINISH is one, then a sync will be sent immediately -- the
+ * cb will not wait for all the previous operations to complete before sending
+ * the sync. Unpipelined except when DC_FINISH and DC_FREE are both set to
+ * zero.
+ *
+ * Set to 0A before 3D operations, set to 02 afterwards.
+ */
+#define R300_RB3D_DSTCACHE_CTLSTAT               0x4e4c
+#      define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_NO_EFFECT         (0 << 0)
+#      define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_NO_EFFECT_1       (1 << 0)
+#      define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D    (2 << 0)
+#      define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D_1  (3 << 0)
+#      define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_NO_EFFECT          (0 << 2)
+#      define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_NO_EFFECT_1        (1 << 2)
+#      define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS       (2 << 2)
+#      define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS_1     (3 << 2)
+#      define R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_NO_SIGNAL        (0 << 4)
+#      define R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_SIGNAL           (1 << 4)
+
+#define R300_RB3D_DITHER_CTL 0x4E50
+#      define R300_RB3D_DITHER_CTL_DITHER_MODE_TRUNCATE         (0 << 0)
+#      define R300_RB3D_DITHER_CTL_DITHER_MODE_ROUND            (1 << 0)
+#      define R300_RB3D_DITHER_CTL_DITHER_MODE_LUT              (2 << 0)
+/* reserved */
+#      define R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_TRUNCATE   (0 << 2)
+#      define R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_ROUND      (1 << 2)
+#      define R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT        (2 << 2)
+/* reserved */
+
+/* Resolve buffer destination address. The cache must be empty before changing
+ * this register if the cb is in resolve mode. Unpipelined
+ */
+#define R300_RB3D_AARESOLVE_OFFSET        0x4e80
+#      define R300_RB3D_AARESOLVE_OFFSET_SHIFT 5
+#      define R300_RB3D_AARESOLVE_OFFSET_MASK 0xffffffe0 /* At least according to the calculations of Christoph Brill */
+
+/* Resolve Buffer Pitch and Tiling Control. The cache must be empty before
+ * changing this register if the cb is in resolve mode. Unpipelined
+ */
+#define R300_RB3D_AARESOLVE_PITCH         0x4e84
+#      define R300_RB3D_AARESOLVE_PITCH_SHIFT 1
+#      define R300_RB3D_AARESOLVE_PITCH_MASK  0x00003ffe /* At least according to the calculations of Christoph Brill */
+
+/* Resolve Buffer Control. Unpipelined */
+#define R300_RB3D_AARESOLVE_CTL           0x4e88
+#      define R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_NORMAL   (0 << 0)
+#      define R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE  (1 << 0)
+#      define R300_RB3D_AARESOLVE_CTL_AARESOLVE_GAMMA_10      (0 << 1)
+#      define R300_RB3D_AARESOLVE_CTL_AARESOLVE_GAMMA_22      (1 << 1)
+#      define R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_SAMPLE0 (0 << 2)
+#      define R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE (1 << 2)
+
+
+/* Discard src pixels less than or equal to threshold. */
+#define R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4ea0
+/* Discard src pixels greater than or equal to threshold. */
+#define R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4ea4
+#      define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_BLUE_SHIFT 0
+#      define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_BLUE_MASK 0x000000ff
+#      define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_GREEN_SHIFT 8
+#      define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_GREEN_MASK 0x0000ff00
+#      define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_RED_SHIFT 16
+#      define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_RED_MASK 0x00ff0000
+#      define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_ALPHA_SHIFT 24
+#      define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_ALPHA_MASK 0xff000000
+
+/* 3D ROP Control. Stalls the 2d/3d datapath until it is idle. */
+#define R300_RB3D_ROPCNTL                             0x4e18
+#      define R300_RB3D_ROPCNTL_ROP_ENABLE            0x00000004
+#      define R300_RB3D_ROPCNTL_ROP_MASK              (15 << 8)
+#      define R300_RB3D_ROPCNTL_ROP_SHIFT             8
+
+/* Color Compare Flip. Stalls the 2d/3d datapath until it is idle. */
+#define R300_RB3D_CLRCMP_FLIPE                        0x4e1c
+
+/* Sets the fifo sizes */
+#define R500_RB3D_FIFO_SIZE                           0x4ef4
+#      define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_FULL   (0 << 0)
+#      define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_HALF   (1 << 0)
+#      define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_QUATER (2 << 0)
+#      define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_EIGTHS (3 << 0)
+
+/* Constant color used by the blender. Pipelined through the blender. */
+#define R500_RB3D_CONSTANT_COLOR_AR                   0x4ef8
+#      define R500_RB3D_CONSTANT_COLOR_AR_RED_MASK    0x0000ffff
+#      define R500_RB3D_CONSTANT_COLOR_AR_RED_SHIFT   0
+#      define R500_RB3D_CONSTANT_COLOR_AR_ALPHA_MASK  0xffff0000
+#      define R500_RB3D_CONSTANT_COLOR_AR_ALPHA_SHIFT 16
+
+/* Constant color used by the blender. Pipelined through the blender. */
+#define R500_RB3D_CONSTANT_COLOR_GB                   0x4efc
+#      define R500_RB3D_CONSTANT_COLOR_AR_BLUE_MASK   0x0000ffff
+#      define R500_RB3D_CONSTANT_COLOR_AR_BLUE_SHIFT  0
+#      define R500_RB3D_CONSTANT_COLOR_AR_GREEN_MASK  0xffff0000
+#      define R500_RB3D_CONSTANT_COLOR_AR_GREEN_SHIFT 16
+
+/* gap */
+/* There seems to be no "write only" setting, so use Z-test = ALWAYS
+ * for this.
+ * Bit (1<<8) is the "test" bit. so plain write is 6  - vd
+ */
+#define R300_ZB_CNTL                             0x4F00
+#      define R300_STENCIL_ENABLE               (1 << 0)
+#      define R300_Z_ENABLE                     (1 << 1)
+#      define R300_Z_WRITE_ENABLE               (1 << 2)
+#      define R300_Z_SIGNED_COMPARE             (1 << 3)
+#      define R300_STENCIL_FRONT_BACK           (1 << 4)
+
+#define R300_ZB_ZSTENCILCNTL                   0x4f04
+       /* functions */
+#      define R300_ZS_NEVER                    0
+#      define R300_ZS_LESS                     1
+#      define R300_ZS_LEQUAL                   2
+#      define R300_ZS_EQUAL                    3
+#      define R300_ZS_GEQUAL                   4
+#      define R300_ZS_GREATER                  5
+#      define R300_ZS_NOTEQUAL                 6
+#      define R300_ZS_ALWAYS                   7
+#       define R300_ZS_MASK                     7
+       /* operations */
+#      define R300_ZS_KEEP                     0
+#      define R300_ZS_ZERO                     1
+#      define R300_ZS_REPLACE                  2
+#      define R300_ZS_INCR                     3
+#      define R300_ZS_DECR                     4
+#      define R300_ZS_INVERT                   5
+#      define R300_ZS_INCR_WRAP                6
+#      define R300_ZS_DECR_WRAP                7
+#      define R300_Z_FUNC_SHIFT                0
+       /* front and back refer to operations done for front
+          and back faces, i.e. separate stencil function support */
+#      define R300_S_FRONT_FUNC_SHIFT          3
+#      define R300_S_FRONT_SFAIL_OP_SHIFT      6
+#      define R300_S_FRONT_ZPASS_OP_SHIFT      9
+#      define R300_S_FRONT_ZFAIL_OP_SHIFT      12
+#      define R300_S_BACK_FUNC_SHIFT           15
+#      define R300_S_BACK_SFAIL_OP_SHIFT       18
+#      define R300_S_BACK_ZPASS_OP_SHIFT       21
+#      define R300_S_BACK_ZFAIL_OP_SHIFT       24
+
+#define R300_ZB_STENCILREFMASK                        0x4f08
+#      define R300_STENCILREF_SHIFT       0
+#      define R300_STENCILREF_MASK        0x000000ff
+#      define R300_STENCILMASK_SHIFT      8
+#      define R300_STENCILMASK_MASK       0x0000ff00
+#      define R300_STENCILWRITEMASK_SHIFT 16
+#      define R300_STENCILWRITEMASK_MASK  0x00ff0000
+
+/* gap */
+
+#define R300_ZB_FORMAT                             0x4f10
+#      define R300_DEPTHFORMAT_16BIT_INT_Z   (0 << 0)
+#      define R300_DEPTHFORMAT_16BIT_13E3    (1 << 0)
+#      define R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL   (2 << 0)
+/* reserved up to (15 << 0) */
+#      define R300_INVERT_13E3_LEADING_ONES  (0 << 4)
+#      define R300_INVERT_13E3_LEADING_ZEROS (1 << 4)
+
+#define R300_ZB_ZTOP                             0x4F14
+#      define R300_ZTOP_DISABLE                 (0 << 0)
+#      define R300_ZTOP_ENABLE                  (1 << 0)
+
+/* gap */
+
+#define R300_ZB_ZCACHE_CTLSTAT            0x4f18
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_NO_EFFECT      (0 << 0)
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0)
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT       (0 << 1)
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE            (1 << 1)
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE            (0 << 31)
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY            (1 << 31)
+
+#define R300_ZB_BW_CNTL                     0x4f1c
+#      define R300_HIZ_DISABLE                              (0 << 0)
+#      define R300_HIZ_ENABLE                               (1 << 0)
+#      define R300_HIZ_MIN                                  (0 << 1)
+#      define R300_HIZ_MAX                                  (1 << 1)
+#      define R300_FAST_FILL_DISABLE                        (0 << 2)
+#      define R300_FAST_FILL_ENABLE                         (1 << 2)
+#      define R300_RD_COMP_DISABLE                          (0 << 3)
+#      define R300_RD_COMP_ENABLE                           (1 << 3)
+#      define R300_WR_COMP_DISABLE                          (0 << 4)
+#      define R300_WR_COMP_ENABLE                           (1 << 4)
+#      define R300_ZB_CB_CLEAR_RMW                          (0 << 5)
+#      define R300_ZB_CB_CLEAR_CACHE_LINEAR                 (1 << 5)
+#      define R300_FORCE_COMPRESSED_STENCIL_VALUE_DISABLE   (0 << 6)
+#      define R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE    (1 << 6)
+
+#      define R500_ZEQUAL_OPTIMIZE_ENABLE                   (0 << 7)
+#      define R500_ZEQUAL_OPTIMIZE_DISABLE                  (1 << 7)
+#      define R500_SEQUAL_OPTIMIZE_ENABLE                   (0 << 8)
+#      define R500_SEQUAL_OPTIMIZE_DISABLE                  (1 << 8)
+
+#      define R500_BMASK_ENABLE                             (0 << 10)
+#      define R500_BMASK_DISABLE                            (1 << 10)
+#      define R500_HIZ_EQUAL_REJECT_DISABLE                 (0 << 11)
+#      define R500_HIZ_EQUAL_REJECT_ENABLE                  (1 << 11)
+#      define R500_HIZ_FP_EXP_BITS_DISABLE                  (0 << 12)
+#      define R500_HIZ_FP_EXP_BITS_1                        (1 << 12)
+#      define R500_HIZ_FP_EXP_BITS_2                        (2 << 12)
+#      define R500_HIZ_FP_EXP_BITS_3                        (3 << 12)
+#      define R500_HIZ_FP_EXP_BITS_4                        (4 << 12)
+#      define R500_HIZ_FP_EXP_BITS_5                        (5 << 12)
+#      define R500_HIZ_FP_INVERT_LEADING_ONES               (0 << 15)
+#      define R500_HIZ_FP_INVERT_LEADING_ZEROS              (1 << 15)
+#      define R500_TILE_OVERWRITE_RECOMPRESSION_ENABLE      (0 << 16)
+#      define R500_TILE_OVERWRITE_RECOMPRESSION_DISABLE     (1 << 16)
+#      define R500_CONTIGUOUS_6XAA_SAMPLES_ENABLE           (0 << 17)
+#      define R500_CONTIGUOUS_6XAA_SAMPLES_DISABLE          (1 << 17)
+#      define R500_PEQ_PACKING_DISABLE                      (0 << 18)
+#      define R500_PEQ_PACKING_ENABLE                       (1 << 18)
+#      define R500_COVERED_PTR_MASKING_DISABLE              (0 << 18)
+#      define R500_COVERED_PTR_MASKING_ENABLE               (1 << 18)
+
+
+/* gap */
+
+/* Z Buffer Address Offset.
+ * Bits 31 to 5 are used for aligned Z buffer address offset for macro tiles.
+ */
+#define R300_ZB_DEPTHOFFSET               0x4f20
+
+/* Z Buffer Pitch and Endian Control */
+#define R300_ZB_DEPTHPITCH                0x4f24
+#       define R300_DEPTHPITCH_MASK              0x00003FFC
+#       define R300_DEPTHMACROTILE_DISABLE      (0 << 16)
+#       define R300_DEPTHMACROTILE_ENABLE       (1 << 16)
+#       define R300_DEPTHMICROTILE_LINEAR       (0 << 17)
+#       define R300_DEPTHMICROTILE_TILED        (1 << 17)
+#       define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17)
+#       define R300_DEPTHENDIAN_NO_SWAP         (0 << 18)
+#       define R300_DEPTHENDIAN_WORD_SWAP       (1 << 18)
+#       define R300_DEPTHENDIAN_DWORD_SWAP      (2 << 18)
+#       define R300_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18)
+
+/* Z Buffer Clear Value */
+#define R300_ZB_DEPTHCLEARVALUE                  0x4f28
+
+/* Hierarchical Z Memory Offset */
+#define R300_ZB_HIZ_OFFSET                       0x4f44
+
+/* Hierarchical Z Write Index */
+#define R300_ZB_HIZ_WRINDEX                      0x4f48
+
+/* Hierarchical Z Data */
+#define R300_ZB_HIZ_DWORD                        0x4f4c
+
+/* Hierarchical Z Read Index */
+#define R300_ZB_HIZ_RDINDEX                      0x4f50
+
+/* Hierarchical Z Pitch */
+#define R300_ZB_HIZ_PITCH                        0x4f54
+
+/* Z Buffer Z Pass Counter Data */
+#define R300_ZB_ZPASS_DATA                       0x4f58
+
+/* Z Buffer Z Pass Counter Address */
+#define R300_ZB_ZPASS_ADDR                       0x4f5c
+
+/* Depth buffer X and Y coordinate offset */
+#define R300_ZB_DEPTHXY_OFFSET                   0x4f60
+#      define R300_DEPTHX_OFFSET_SHIFT  1
+#      define R300_DEPTHX_OFFSET_MASK   0x000007FE
+#      define R300_DEPTHY_OFFSET_SHIFT  17
+#      define R300_DEPTHY_OFFSET_MASK   0x07FE0000
+
+/* Sets the fifo sizes */
+#define R500_ZB_FIFO_SIZE                        0x4fd0
+#      define R500_OP_FIFO_SIZE_FULL   (0 << 0)
+#      define R500_OP_FIFO_SIZE_HALF   (1 << 0)
+#      define R500_OP_FIFO_SIZE_QUATER (2 << 0)
+#      define R500_OP_FIFO_SIZE_EIGTHS (4 << 0)
+
+/* Stencil Reference Value and Mask for backfacing quads */
+/* R300_ZB_STENCILREFMASK handles front face */
+#define R500_ZB_STENCILREFMASK_BF                0x4fd4
+#      define R500_STENCILREF_SHIFT       0
+#      define R500_STENCILREF_MASK        0x000000ff
+#      define R500_STENCILMASK_SHIFT      8
+#      define R500_STENCILMASK_MASK       0x0000ff00
+#      define R500_STENCILWRITEMASK_SHIFT 16
+#      define R500_STENCILWRITEMASK_MASK  0x00ff0000
+
+/**
+ * \defgroup R3XX_R5XX_PROGRAMMABLE_VERTEX_SHADER_DESCRIPTION R3XX-R5XX PROGRAMMABLE VERTEX SHADER DESCRIPTION
+ *
+ * The PVS_DST_MATH_INST is used to identify whether the instruction is a Vector
+ * Engine instruction or a Math Engine instruction.
+ */
+
+/*\{*/
+
+enum {
+       /* R3XX */
+       VECTOR_NO_OP                    = 0,
+       VE_DOT_PRODUCT                  = 1,
+       VE_MULTIPLY                     = 2,
+       VE_ADD                          = 3,
+       VE_MULTIPLY_ADD                 = 4,
+       VE_DISTANCE_VECTOR              = 5,
+       VE_FRACTION                     = 6,
+       VE_MAXIMUM                      = 7,
+       VE_MINIMUM                      = 8,
+       VE_SET_GREATER_THAN_EQUAL       = 9,
+       VE_SET_LESS_THAN                = 10,
+       VE_MULTIPLYX2_ADD               = 11,
+       VE_MULTIPLY_CLAMP               = 12,
+       VE_FLT2FIX_DX                   = 13,
+       VE_FLT2FIX_DX_RND               = 14,
+       /* R5XX */
+       VE_PRED_SET_EQ_PUSH             = 15,
+       VE_PRED_SET_GT_PUSH             = 16,
+       VE_PRED_SET_GTE_PUSH            = 17,
+       VE_PRED_SET_NEQ_PUSH            = 18,
+       VE_COND_WRITE_EQ                = 19,
+       VE_COND_WRITE_GT                = 20,
+       VE_COND_WRITE_GTE               = 21,
+       VE_COND_WRITE_NEQ               = 22,
+       VE_COND_MUX_EQ                  = 23,
+       VE_COND_MUX_GT                  = 24,
+       VE_COND_MUX_GTE                 = 25,
+       VE_SET_GREATER_THAN             = 26,
+       VE_SET_EQUAL                    = 27,
+       VE_SET_NOT_EQUAL                = 28,
+};
+
+enum {
+       /* R3XX */
+       MATH_NO_OP                      = 0,
+       ME_EXP_BASE2_DX                 = 1,
+       ME_LOG_BASE2_DX                 = 2,
+       ME_EXP_BASEE_FF                 = 3,
+       ME_LIGHT_COEFF_DX               = 4,
+       ME_POWER_FUNC_FF                = 5,
+       ME_RECIP_DX                     = 6,
+       ME_RECIP_FF                     = 7,
+       ME_RECIP_SQRT_DX                = 8,
+       ME_RECIP_SQRT_FF                = 9,
+       ME_MULTIPLY                     = 10,
+       ME_EXP_BASE2_FULL_DX            = 11,
+       ME_LOG_BASE2_FULL_DX            = 12,
+       ME_POWER_FUNC_FF_CLAMP_B        = 13,
+       ME_POWER_FUNC_FF_CLAMP_B1       = 14,
+       ME_POWER_FUNC_FF_CLAMP_01       = 15,
+       ME_SIN                          = 16,
+       ME_COS                          = 17,
+       /* R5XX */
+       ME_LOG_BASE2_IEEE               = 18,
+       ME_RECIP_IEEE                   = 19,
+       ME_RECIP_SQRT_IEEE              = 20,
+       ME_PRED_SET_EQ                  = 21,
+       ME_PRED_SET_GT                  = 22,
+       ME_PRED_SET_GTE                 = 23,
+       ME_PRED_SET_NEQ                 = 24,
+       ME_PRED_SET_CLR                 = 25,
+       ME_PRED_SET_INV                 = 26,
+       ME_PRED_SET_POP                 = 27,
+       ME_PRED_SET_RESTORE             = 28,
+};
+
+enum {
+       /* R3XX */
+       PVS_MACRO_OP_2CLK_MADD          = 0,
+       PVS_MACRO_OP_2CLK_M2X_ADD       = 1,
+};
+
+enum {
+       PVS_SRC_REG_TEMPORARY           = 0,    /* Intermediate Storage */
+       PVS_SRC_REG_INPUT               = 1,    /* Input Vertex Storage */
+       PVS_SRC_REG_CONSTANT            = 2,    /* Constant State Storage */
+       PVS_SRC_REG_ALT_TEMPORARY       = 3,    /* Alternate Intermediate Storage */
+};
+
+enum {
+       PVS_DST_REG_TEMPORARY           = 0,    /* Intermediate Storage */
+       PVS_DST_REG_A0                  = 1,    /* Address Register Storage */
+       PVS_DST_REG_OUT                 = 2,    /* Output Memory. Used for all outputs */
+       PVS_DST_REG_OUT_REPL_X          = 3,    /* Output Memory & Replicate X to all channels */
+       PVS_DST_REG_ALT_TEMPORARY       = 4,    /* Alternate Intermediate Storage */
+       PVS_DST_REG_INPUT               = 5,    /* Output Memory & Replicate X to all channels */
+};
+
+enum {
+       PVS_SRC_SELECT_X                = 0,    /* Select X Component */
+       PVS_SRC_SELECT_Y                = 1,    /* Select Y Component */
+       PVS_SRC_SELECT_Z                = 2,    /* Select Z Component */
+       PVS_SRC_SELECT_W                = 3,    /* Select W Component */
+       PVS_SRC_SELECT_FORCE_0          = 4,    /* Force Component to 0.0 */
+       PVS_SRC_SELECT_FORCE_1          = 5,    /* Force Component to 1.0 */
+};
+
+/* PVS Opcode & Destination Operand Description */
+
+enum {
+       PVS_DST_OPCODE_MASK             = 0x3f,
+       PVS_DST_OPCODE_SHIFT            = 0,
+       PVS_DST_MATH_INST_MASK          = 0x1,
+       PVS_DST_MATH_INST_SHIFT         = 6,
+       PVS_DST_MACRO_INST_MASK         = 0x1,
+       PVS_DST_MACRO_INST_SHIFT        = 7,
+       PVS_DST_REG_TYPE_MASK           = 0xf,
+       PVS_DST_REG_TYPE_SHIFT          = 8,
+       PVS_DST_ADDR_MODE_1_MASK        = 0x1,
+       PVS_DST_ADDR_MODE_1_SHIFT       = 12,
+       PVS_DST_OFFSET_MASK             = 0x7f,
+       PVS_DST_OFFSET_SHIFT            = 13,
+       PVS_DST_WE_X_MASK               = 0x1,
+       PVS_DST_WE_X_SHIFT              = 20,
+       PVS_DST_WE_Y_MASK               = 0x1,
+       PVS_DST_WE_Y_SHIFT              = 21,
+       PVS_DST_WE_Z_MASK               = 0x1,
+       PVS_DST_WE_Z_SHIFT              = 22,
+       PVS_DST_WE_W_MASK               = 0x1,
+       PVS_DST_WE_W_SHIFT              = 23,
+       PVS_DST_VE_SAT_MASK             = 0x1,
+       PVS_DST_VE_SAT_SHIFT            = 24,
+       PVS_DST_ME_SAT_MASK             = 0x1,
+       PVS_DST_ME_SAT_SHIFT            = 25,
+       PVS_DST_PRED_ENABLE_MASK        = 0x1,
+       PVS_DST_PRED_ENABLE_SHIFT       = 26,
+       PVS_DST_PRED_SENSE_MASK         = 0x1,
+       PVS_DST_PRED_SENSE_SHIFT        = 27,
+       PVS_DST_DUAL_MATH_OP_MASK       = 0x3,
+       PVS_DST_DUAL_MATH_OP_SHIFT      = 27,
+       PVS_DST_ADDR_SEL_MASK           = 0x3,
+       PVS_DST_ADDR_SEL_SHIFT          = 29,
+       PVS_DST_ADDR_MODE_0_MASK        = 0x1,
+       PVS_DST_ADDR_MODE_0_SHIFT       = 31,
+};
+
+/* PVS Source Operand Description */
+
+enum {
+       PVS_SRC_REG_TYPE_MASK           = 0x3,
+       PVS_SRC_REG_TYPE_SHIFT          = 0,
+       SPARE_0_MASK                    = 0x1,
+       SPARE_0_SHIFT                   = 2,
+       PVS_SRC_ABS_XYZW_MASK           = 0x1,
+       PVS_SRC_ABS_XYZW_SHIFT          = 3,
+       PVS_SRC_ADDR_MODE_0_MASK        = 0x1,
+       PVS_SRC_ADDR_MODE_0_SHIFT       = 4,
+       PVS_SRC_OFFSET_MASK             = 0xff,
+       PVS_SRC_OFFSET_SHIFT            = 5,
+       PVS_SRC_SWIZZLE_X_MASK          = 0x7,
+       PVS_SRC_SWIZZLE_X_SHIFT         = 13,
+       PVS_SRC_SWIZZLE_Y_MASK          = 0x7,
+       PVS_SRC_SWIZZLE_Y_SHIFT         = 16,
+       PVS_SRC_SWIZZLE_Z_MASK          = 0x7,
+       PVS_SRC_SWIZZLE_Z_SHIFT         = 19,
+       PVS_SRC_SWIZZLE_W_MASK          = 0x7,
+       PVS_SRC_SWIZZLE_W_SHIFT         = 22,
+       PVS_SRC_MODIFIER_X_MASK         = 0x1,
+       PVS_SRC_MODIFIER_X_SHIFT        = 25,
+       PVS_SRC_MODIFIER_Y_MASK         = 0x1,
+       PVS_SRC_MODIFIER_Y_SHIFT        = 26,
+       PVS_SRC_MODIFIER_Z_MASK         = 0x1,
+       PVS_SRC_MODIFIER_Z_SHIFT        = 27,
+       PVS_SRC_MODIFIER_W_MASK         = 0x1,
+       PVS_SRC_MODIFIER_W_SHIFT        = 28,
+       PVS_SRC_ADDR_SEL_MASK           = 0x3,
+       PVS_SRC_ADDR_SEL_SHIFT          = 29,
+       PVS_SRC_ADDR_MODE_1_MASK        = 0x0,
+       PVS_SRC_ADDR_MODE_1_SHIFT       = 32,
+};
+
+/*\}*/
+
+/* BEGIN: Packet 3 commands */
+
+/* A primitive emission dword. */
+#define R300_PRIM_TYPE_NONE                     (0 << 0)
+#define R300_PRIM_TYPE_POINT                    (1 << 0)
+#define R300_PRIM_TYPE_LINE                     (2 << 0)
+#define R300_PRIM_TYPE_LINE_STRIP               (3 << 0)
+#define R300_PRIM_TYPE_TRI_LIST                 (4 << 0)
+#define R300_PRIM_TYPE_TRI_FAN                  (5 << 0)
+#define R300_PRIM_TYPE_TRI_STRIP                (6 << 0)
+#define R300_PRIM_TYPE_TRI_TYPE2                (7 << 0)
+#define R300_PRIM_TYPE_RECT_LIST                (8 << 0)
+#define R300_PRIM_TYPE_3VRT_POINT_LIST          (9 << 0)
+#define R300_PRIM_TYPE_3VRT_LINE_LIST           (10 << 0)
+       /* GUESS (based on r200) */
+#define R300_PRIM_TYPE_POINT_SPRITES            (11 << 0)
+#define R300_PRIM_TYPE_LINE_LOOP                (12 << 0)
+#define R300_PRIM_TYPE_QUADS                    (13 << 0)
+#define R300_PRIM_TYPE_QUAD_STRIP               (14 << 0)
+#define R300_PRIM_TYPE_POLYGON                  (15 << 0)
+#define R300_PRIM_TYPE_MASK                     0xF
+#define R300_PRIM_WALK_IND                      (1 << 4)
+#define R300_PRIM_WALK_LIST                     (2 << 4)
+#define R300_PRIM_WALK_RING                     (3 << 4)
+#define R300_PRIM_WALK_MASK                     (3 << 4)
+       /* GUESS (based on r200) */
+#define R300_PRIM_COLOR_ORDER_BGRA              (0 << 6)
+#define R300_PRIM_COLOR_ORDER_RGBA              (1 << 6)
+#define R300_PRIM_NUM_VERTICES_SHIFT            16
+#define R300_PRIM_NUM_VERTICES_MASK             0xffff
+
+
+
+/*
+ * The R500 unified shader (US) registers come in banks of 512 each, one
+ * for each instruction slot in the shader.  You can't touch them directly.
+ * R500_US_VECTOR_INDEX() sets the base instruction to modify; successive
+ * writes to R500_GA_US_VECTOR_DATA autoincrement the index after the
+ * instruction is fully specified.
+ */
+#define R500_US_ALU_ALPHA_INST_0                       0xa800
+#   define R500_ALPHA_OP_MAD                           0
+#   define R500_ALPHA_OP_DP                            1
+#   define R500_ALPHA_OP_MIN                           2
+#   define R500_ALPHA_OP_MAX                           3
+/* #define R500_ALPHA_OP_RESERVED                      4 */
+#   define R500_ALPHA_OP_CND                           5
+#   define R500_ALPHA_OP_CMP                           6
+#   define R500_ALPHA_OP_FRC                           7
+#   define R500_ALPHA_OP_EX2                           8
+#   define R500_ALPHA_OP_LN2                           9
+#   define R500_ALPHA_OP_RCP                           10
+#   define R500_ALPHA_OP_RSQ                           11
+#   define R500_ALPHA_OP_SIN                           12
+#   define R500_ALPHA_OP_COS                           13
+#   define R500_ALPHA_OP_MDH                           14
+#   define R500_ALPHA_OP_MDV                           15
+#   define R500_ALPHA_ADDRD(x)                         (x << 4)
+#   define R500_ALPHA_ADDRD_REL                                (1 << 11)
+#  define R500_ALPHA_SEL_A_SHIFT                       12
+#   define R500_ALPHA_SEL_A_SRC0                       (0 << 12)
+#   define R500_ALPHA_SEL_A_SRC1                       (1 << 12)
+#   define R500_ALPHA_SEL_A_SRC2                       (2 << 12)
+#   define R500_ALPHA_SEL_A_SRCP                       (3 << 12)
+#   define R500_ALPHA_SWIZ_A_R                         (0 << 14)
+#   define R500_ALPHA_SWIZ_A_G                         (1 << 14)
+#   define R500_ALPHA_SWIZ_A_B                         (2 << 14)
+#   define R500_ALPHA_SWIZ_A_A                         (3 << 14)
+#   define R500_ALPHA_SWIZ_A_0                         (4 << 14)
+#   define R500_ALPHA_SWIZ_A_HALF                      (5 << 14)
+#   define R500_ALPHA_SWIZ_A_1                         (6 << 14)
+/* #define R500_ALPHA_SWIZ_A_UNUSED                    (7 << 14) */
+#   define R500_ALPHA_MOD_A_NOP                                (0 << 17)
+#   define R500_ALPHA_MOD_A_NEG                                (1 << 17)
+#   define R500_ALPHA_MOD_A_ABS                                (2 << 17)
+#   define R500_ALPHA_MOD_A_NAB                                (3 << 17)
+#  define R500_ALPHA_SEL_B_SHIFT                       19
+#   define R500_ALPHA_SEL_B_SRC0                       (0 << 19)
+#   define R500_ALPHA_SEL_B_SRC1                       (1 << 19)
+#   define R500_ALPHA_SEL_B_SRC2                       (2 << 19)
+#   define R500_ALPHA_SEL_B_SRCP                       (3 << 19)
+#   define R500_ALPHA_SWIZ_B_R                         (0 << 21)
+#   define R500_ALPHA_SWIZ_B_G                         (1 << 21)
+#   define R500_ALPHA_SWIZ_B_B                         (2 << 21)
+#   define R500_ALPHA_SWIZ_B_A                         (3 << 21)
+#   define R500_ALPHA_SWIZ_B_0                         (4 << 21)
+#   define R500_ALPHA_SWIZ_B_HALF                      (5 << 21)
+#   define R500_ALPHA_SWIZ_B_1                         (6 << 21)
+/* #define R500_ALPHA_SWIZ_B_UNUSED                    (7 << 21) */
+#   define R500_ALPHA_MOD_B_NOP                                (0 << 24)
+#   define R500_ALPHA_MOD_B_NEG                                (1 << 24)
+#   define R500_ALPHA_MOD_B_ABS                                (2 << 24)
+#   define R500_ALPHA_MOD_B_NAB                                (3 << 24)
+#   define R500_ALPHA_OMOD_IDENTITY                    (0 << 26)
+#   define R500_ALPHA_OMOD_MUL_2                       (1 << 26)
+#   define R500_ALPHA_OMOD_MUL_4                       (2 << 26)
+#   define R500_ALPHA_OMOD_MUL_8                       (3 << 26)
+#   define R500_ALPHA_OMOD_DIV_2                       (4 << 26)
+#   define R500_ALPHA_OMOD_DIV_4                       (5 << 26)
+#   define R500_ALPHA_OMOD_DIV_8                       (6 << 26)
+#   define R500_ALPHA_OMOD_DISABLE                     (7 << 26)
+#   define R500_ALPHA_TARGET(x)                                (x << 29)
+#   define R500_ALPHA_W_OMASK                          (1 << 31)
+#define R500_US_ALU_ALPHA_ADDR_0                       0x9800
+#   define R500_ALPHA_ADDR0(x)                         (x << 0)
+#   define R500_ALPHA_ADDR0_CONST                      (1 << 8)
+#   define R500_ALPHA_ADDR0_REL                                (1 << 9)
+#   define R500_ALPHA_ADDR1(x)                         (x << 10)
+#   define R500_ALPHA_ADDR1_CONST                      (1 << 18)
+#   define R500_ALPHA_ADDR1_REL                                (1 << 19)
+#   define R500_ALPHA_ADDR2(x)                         (x << 20)
+#   define R500_ALPHA_ADDR2_CONST                      (1 << 28)
+#   define R500_ALPHA_ADDR2_REL                                (1 << 29)
+#   define R500_ALPHA_SRCP_OP_1_MINUS_2A0              (0 << 30)
+#   define R500_ALPHA_SRCP_OP_A1_MINUS_A0              (1 << 30)
+#   define R500_ALPHA_SRCP_OP_A1_PLUS_A0               (2 << 30)
+#   define R500_ALPHA_SRCP_OP_1_MINUS_A0               (3 << 30)
+#define R500_US_ALU_RGBA_INST_0                                0xb000
+#   define R500_ALU_RGBA_OP_MAD                                (0 << 0)
+#   define R500_ALU_RGBA_OP_DP3                                (1 << 0)
+#   define R500_ALU_RGBA_OP_DP4                                (2 << 0)
+#   define R500_ALU_RGBA_OP_D2A                                (3 << 0)
+#   define R500_ALU_RGBA_OP_MIN                                (4 << 0)
+#   define R500_ALU_RGBA_OP_MAX                                (5 << 0)
+/* #define R500_ALU_RGBA_OP_RESERVED                   (6 << 0) */
+#   define R500_ALU_RGBA_OP_CND                                (7 << 0)
+#   define R500_ALU_RGBA_OP_CMP                                (8 << 0)
+#   define R500_ALU_RGBA_OP_FRC                                (9 << 0)
+#   define R500_ALU_RGBA_OP_SOP                                (10 << 0)
+#   define R500_ALU_RGBA_OP_MDH                                (11 << 0)
+#   define R500_ALU_RGBA_OP_MDV                                (12 << 0)
+#   define R500_ALU_RGBA_ADDRD(x)                      (x << 4)
+#   define R500_ALU_RGBA_ADDRD_REL                     (1 << 11)
+#  define R500_ALU_RGBA_SEL_C_SHIFT                    12
+#   define R500_ALU_RGBA_SEL_C_SRC0                    (0 << 12)
+#   define R500_ALU_RGBA_SEL_C_SRC1                    (1 << 12)
+#   define R500_ALU_RGBA_SEL_C_SRC2                    (2 << 12)
+#   define R500_ALU_RGBA_SEL_C_SRCP                    (3 << 12)
+#   define R500_ALU_RGBA_R_SWIZ_R                      (0 << 14)
+#   define R500_ALU_RGBA_R_SWIZ_G                      (1 << 14)
+#   define R500_ALU_RGBA_R_SWIZ_B                      (2 << 14)
+#   define R500_ALU_RGBA_R_SWIZ_A                      (3 << 14)
+#   define R500_ALU_RGBA_R_SWIZ_0                      (4 << 14)
+#   define R500_ALU_RGBA_R_SWIZ_HALF                   (5 << 14)
+#   define R500_ALU_RGBA_R_SWIZ_1                      (6 << 14)
+/* #define R500_ALU_RGBA_R_SWIZ_UNUSED                 (7 << 14) */
+#   define R500_ALU_RGBA_G_SWIZ_R                      (0 << 17)
+#   define R500_ALU_RGBA_G_SWIZ_G                      (1 << 17)
+#   define R500_ALU_RGBA_G_SWIZ_B                      (2 << 17)
+#   define R500_ALU_RGBA_G_SWIZ_A                      (3 << 17)
+#   define R500_ALU_RGBA_G_SWIZ_0                      (4 << 17)
+#   define R500_ALU_RGBA_G_SWIZ_HALF                   (5 << 17)
+#   define R500_ALU_RGBA_G_SWIZ_1                      (6 << 17)
+/* #define R500_ALU_RGBA_G_SWIZ_UNUSED                 (7 << 17) */
+#   define R500_ALU_RGBA_B_SWIZ_R                      (0 << 20)
+#   define R500_ALU_RGBA_B_SWIZ_G                      (1 << 20)
+#   define R500_ALU_RGBA_B_SWIZ_B                      (2 << 20)
+#   define R500_ALU_RGBA_B_SWIZ_A                      (3 << 20)
+#   define R500_ALU_RGBA_B_SWIZ_0                      (4 << 20)
+#   define R500_ALU_RGBA_B_SWIZ_HALF                   (5 << 20)
+#   define R500_ALU_RGBA_B_SWIZ_1                      (6 << 20)
+/* #define R500_ALU_RGBA_B_SWIZ_UNUSED                 (7 << 20) */
+#   define R500_ALU_RGBA_MOD_C_NOP                     (0 << 23)
+#   define R500_ALU_RGBA_MOD_C_NEG                     (1 << 23)
+#   define R500_ALU_RGBA_MOD_C_ABS                     (2 << 23)
+#   define R500_ALU_RGBA_MOD_C_NAB                     (3 << 23)
+#  define R500_ALU_RGBA_ALPHA_SEL_C_SHIFT              25
+#   define R500_ALU_RGBA_ALPHA_SEL_C_SRC0              (0 << 25)
+#   define R500_ALU_RGBA_ALPHA_SEL_C_SRC1              (1 << 25)
+#   define R500_ALU_RGBA_ALPHA_SEL_C_SRC2              (2 << 25)
+#   define R500_ALU_RGBA_ALPHA_SEL_C_SRCP              (3 << 25)
+#   define R500_ALU_RGBA_A_SWIZ_R                      (0 << 27)
+#   define R500_ALU_RGBA_A_SWIZ_G                      (1 << 27)
+#   define R500_ALU_RGBA_A_SWIZ_B                      (2 << 27)
+#   define R500_ALU_RGBA_A_SWIZ_A                      (3 << 27)
+#   define R500_ALU_RGBA_A_SWIZ_0                      (4 << 27)
+#   define R500_ALU_RGBA_A_SWIZ_HALF                   (5 << 27)
+#   define R500_ALU_RGBA_A_SWIZ_1                      (6 << 27)
+/* #define R500_ALU_RGBA_A_SWIZ_UNUSED                 (7 << 27) */
+#   define R500_ALU_RGBA_ALPHA_MOD_C_NOP               (0 << 30)
+#   define R500_ALU_RGBA_ALPHA_MOD_C_NEG               (1 << 30)
+#   define R500_ALU_RGBA_ALPHA_MOD_C_ABS               (2 << 30)
+#   define R500_ALU_RGBA_ALPHA_MOD_C_NAB               (3 << 30)
+#define R500_US_ALU_RGB_INST_0                         0xa000
+#  define R500_ALU_RGB_SEL_A_SHIFT                     0
+#   define R500_ALU_RGB_SEL_A_SRC0                     (0 << 0)
+#   define R500_ALU_RGB_SEL_A_SRC1                     (1 << 0)
+#   define R500_ALU_RGB_SEL_A_SRC2                     (2 << 0)
+#   define R500_ALU_RGB_SEL_A_SRCP                     (3 << 0)
+#   define R500_ALU_RGB_R_SWIZ_A_R                     (0 << 2)
+#   define R500_ALU_RGB_R_SWIZ_A_G                     (1 << 2)
+#   define R500_ALU_RGB_R_SWIZ_A_B                     (2 << 2)
+#   define R500_ALU_RGB_R_SWIZ_A_A                     (3 << 2)
+#   define R500_ALU_RGB_R_SWIZ_A_0                     (4 << 2)
+#   define R500_ALU_RGB_R_SWIZ_A_HALF                  (5 << 2)
+#   define R500_ALU_RGB_R_SWIZ_A_1                     (6 << 2)
+/* #define R500_ALU_RGB_R_SWIZ_A_UNUSED                        (7 << 2) */
+#   define R500_ALU_RGB_G_SWIZ_A_R                     (0 << 5)
+#   define R500_ALU_RGB_G_SWIZ_A_G                     (1 << 5)
+#   define R500_ALU_RGB_G_SWIZ_A_B                     (2 << 5)
+#   define R500_ALU_RGB_G_SWIZ_A_A                     (3 << 5)
+#   define R500_ALU_RGB_G_SWIZ_A_0                     (4 << 5)
+#   define R500_ALU_RGB_G_SWIZ_A_HALF                  (5 << 5)
+#   define R500_ALU_RGB_G_SWIZ_A_1                     (6 << 5)
+/* #define R500_ALU_RGB_G_SWIZ_A_UNUSED                        (7 << 5) */
+#   define R500_ALU_RGB_B_SWIZ_A_R                     (0 << 8)
+#   define R500_ALU_RGB_B_SWIZ_A_G                     (1 << 8)
+#   define R500_ALU_RGB_B_SWIZ_A_B                     (2 << 8)
+#   define R500_ALU_RGB_B_SWIZ_A_A                     (3 << 8)
+#   define R500_ALU_RGB_B_SWIZ_A_0                     (4 << 8)
+#   define R500_ALU_RGB_B_SWIZ_A_HALF                  (5 << 8)
+#   define R500_ALU_RGB_B_SWIZ_A_1                     (6 << 8)
+/* #define R500_ALU_RGB_B_SWIZ_A_UNUSED                        (7 << 8) */
+#   define R500_ALU_RGB_MOD_A_NOP                      (0 << 11)
+#   define R500_ALU_RGB_MOD_A_NEG                      (1 << 11)
+#   define R500_ALU_RGB_MOD_A_ABS                      (2 << 11)
+#   define R500_ALU_RGB_MOD_A_NAB                      (3 << 11)
+#  define R500_ALU_RGB_SEL_B_SHIFT                     13
+#   define R500_ALU_RGB_SEL_B_SRC0                     (0 << 13)
+#   define R500_ALU_RGB_SEL_B_SRC1                     (1 << 13)
+#   define R500_ALU_RGB_SEL_B_SRC2                     (2 << 13)
+#   define R500_ALU_RGB_SEL_B_SRCP                     (3 << 13)
+#   define R500_ALU_RGB_R_SWIZ_B_R                     (0 << 15)
+#   define R500_ALU_RGB_R_SWIZ_B_G                     (1 << 15)
+#   define R500_ALU_RGB_R_SWIZ_B_B                     (2 << 15)
+#   define R500_ALU_RGB_R_SWIZ_B_A                     (3 << 15)
+#   define R500_ALU_RGB_R_SWIZ_B_0                     (4 << 15)
+#   define R500_ALU_RGB_R_SWIZ_B_HALF                  (5 << 15)
+#   define R500_ALU_RGB_R_SWIZ_B_1                     (6 << 15)
+/* #define R500_ALU_RGB_R_SWIZ_B_UNUSED                        (7 << 15) */
+#   define R500_ALU_RGB_G_SWIZ_B_R                     (0 << 18)
+#   define R500_ALU_RGB_G_SWIZ_B_G                     (1 << 18)
+#   define R500_ALU_RGB_G_SWIZ_B_B                     (2 << 18)
+#   define R500_ALU_RGB_G_SWIZ_B_A                     (3 << 18)
+#   define R500_ALU_RGB_G_SWIZ_B_0                     (4 << 18)
+#   define R500_ALU_RGB_G_SWIZ_B_HALF                  (5 << 18)
+#   define R500_ALU_RGB_G_SWIZ_B_1                     (6 << 18)
+/* #define R500_ALU_RGB_G_SWIZ_B_UNUSED                        (7 << 18) */
+#   define R500_ALU_RGB_B_SWIZ_B_R                     (0 << 21)
+#   define R500_ALU_RGB_B_SWIZ_B_G                     (1 << 21)
+#   define R500_ALU_RGB_B_SWIZ_B_B                     (2 << 21)
+#   define R500_ALU_RGB_B_SWIZ_B_A                     (3 << 21)
+#   define R500_ALU_RGB_B_SWIZ_B_0                     (4 << 21)
+#   define R500_ALU_RGB_B_SWIZ_B_HALF                  (5 << 21)
+#   define R500_ALU_RGB_B_SWIZ_B_1                     (6 << 21)
+/* #define R500_ALU_RGB_B_SWIZ_B_UNUSED                        (7 << 21) */
+#   define R500_ALU_RGB_MOD_B_NOP                      (0 << 24)
+#   define R500_ALU_RGB_MOD_B_NEG                      (1 << 24)
+#   define R500_ALU_RGB_MOD_B_ABS                      (2 << 24)
+#   define R500_ALU_RGB_MOD_B_NAB                      (3 << 24)
+#   define R500_ALU_RGB_OMOD_IDENTITY                  (0 << 26)
+#   define R500_ALU_RGB_OMOD_MUL_2                     (1 << 26)
+#   define R500_ALU_RGB_OMOD_MUL_4                     (2 << 26)
+#   define R500_ALU_RGB_OMOD_MUL_8                     (3 << 26)
+#   define R500_ALU_RGB_OMOD_DIV_2                     (4 << 26)
+#   define R500_ALU_RGB_OMOD_DIV_4                     (5 << 26)
+#   define R500_ALU_RGB_OMOD_DIV_8                     (6 << 26)
+#   define R500_ALU_RGB_OMOD_DISABLE                   (7 << 26)
+#   define R500_ALU_RGB_TARGET(x)                      (x << 29)
+#   define R500_ALU_RGB_WMASK                          (1 << 31)
+#define R500_US_ALU_RGB_ADDR_0                         0x9000
+#   define R500_RGB_ADDR0(x)                           (x << 0)
+#   define R500_RGB_ADDR0_CONST                                (1 << 8)
+#   define R500_RGB_ADDR0_REL                          (1 << 9)
+#   define R500_RGB_ADDR1(x)                           (x << 10)
+#   define R500_RGB_ADDR1_CONST                                (1 << 18)
+#   define R500_RGB_ADDR1_REL                          (1 << 19)
+#   define R500_RGB_ADDR2(x)                           (x << 20)
+#   define R500_RGB_ADDR2_CONST                                (1 << 28)
+#   define R500_RGB_ADDR2_REL                          (1 << 29)
+#   define R500_RGB_SRCP_OP_1_MINUS_2RGB0              (0 << 30)
+#   define R500_RGB_SRCP_OP_RGB1_MINUS_RGB0            (1 << 30)
+#   define R500_RGB_SRCP_OP_RGB1_PLUS_RGB0             (2 << 30)
+#   define R500_RGB_SRCP_OP_1_MINUS_RGB0               (3 << 30)
+#define R500_US_CMN_INST_0                             0xb800
+#  define R500_INST_TYPE_MASK                          (3 << 0)
+#   define R500_INST_TYPE_ALU                          (0 << 0)
+#   define R500_INST_TYPE_OUT                          (1 << 0)
+#   define R500_INST_TYPE_FC                           (2 << 0)
+#   define R500_INST_TYPE_TEX                          (3 << 0)
+#   define R500_INST_TEX_SEM_WAIT                      (1 << 2)
+#   define R500_INST_RGB_PRED_SEL_NONE                 (0 << 3)
+#   define R500_INST_RGB_PRED_SEL_RGBA                 (1 << 3)
+#   define R500_INST_RGB_PRED_SEL_RRRR                 (2 << 3)
+#   define R500_INST_RGB_PRED_SEL_GGGG                 (3 << 3)
+#   define R500_INST_RGB_PRED_SEL_BBBB                 (4 << 3)
+#   define R500_INST_RGB_PRED_SEL_AAAA                 (5 << 3)
+#   define R500_INST_RGB_PRED_INV                      (1 << 6)
+#   define R500_INST_WRITE_INACTIVE                    (1 << 7)
+#   define R500_INST_LAST                              (1 << 8)
+#   define R500_INST_NOP                               (1 << 9)
+#   define R500_INST_ALU_WAIT                          (1 << 10)
+#   define R500_INST_RGB_WMASK_R                       (1 << 11)
+#   define R500_INST_RGB_WMASK_G                       (1 << 12)
+#   define R500_INST_RGB_WMASK_B                       (1 << 13)
+#   define R500_INST_ALPHA_WMASK                       (1 << 14)
+#   define R500_INST_RGB_OMASK_R                       (1 << 15)
+#   define R500_INST_RGB_OMASK_G                       (1 << 16)
+#   define R500_INST_RGB_OMASK_B                       (1 << 17)
+#   define R500_INST_ALPHA_OMASK                       (1 << 18)
+#   define R500_INST_RGB_CLAMP                         (1 << 19)
+#   define R500_INST_ALPHA_CLAMP                       (1 << 20)
+#   define R500_INST_ALU_RESULT_SEL                    (1 << 21)
+#   define R500_INST_ALPHA_PRED_INV                    (1 << 22)
+#   define R500_INST_ALU_RESULT_OP_EQ                  (0 << 23)
+#   define R500_INST_ALU_RESULT_OP_LT                  (1 << 23)
+#   define R500_INST_ALU_RESULT_OP_GE                  (2 << 23)
+#   define R500_INST_ALU_RESULT_OP_NE                  (3 << 23)
+#   define R500_INST_ALPHA_PRED_SEL_NONE               (0 << 25)
+#   define R500_INST_ALPHA_PRED_SEL_RGBA               (1 << 25)
+#   define R500_INST_ALPHA_PRED_SEL_RRRR               (2 << 25)
+#   define R500_INST_ALPHA_PRED_SEL_GGGG               (3 << 25)
+#   define R500_INST_ALPHA_PRED_SEL_BBBB               (4 << 25)
+#   define R500_INST_ALPHA_PRED_SEL_AAAA               (5 << 25)
+/* XXX next four are kind of guessed */
+#   define R500_INST_STAT_WE_R                         (1 << 28)
+#   define R500_INST_STAT_WE_G                         (1 << 29)
+#   define R500_INST_STAT_WE_B                         (1 << 30)
+#   define R500_INST_STAT_WE_A                         (1 << 31)
+
+/* note that these are 8 bit lengths, despite the offsets, at least for R500 */
+#define R500_US_CODE_ADDR                              0x4630
+#   define R500_US_CODE_START_ADDR(x)                  (x << 0)
+#   define R500_US_CODE_END_ADDR(x)                    (x << 16)
+#define R500_US_CODE_OFFSET                            0x4638
+#   define R500_US_CODE_OFFSET_ADDR(x)                 (x << 0)
+#define R500_US_CODE_RANGE                             0x4634
+#   define R500_US_CODE_RANGE_ADDR(x)                  (x << 0)
+#   define R500_US_CODE_RANGE_SIZE(x)                  (x << 16)
+#define R500_US_CONFIG                                 0x4600
+#   define R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO                (1 << 1)
+#define R500_US_FC_ADDR_0                              0xa000
+#   define R500_FC_BOOL_ADDR(x)                                (x << 0)
+#   define R500_FC_INT_ADDR(x)                         (x << 8)
+#   define R500_FC_JUMP_ADDR(x)                                (x << 16)
+#   define R500_FC_JUMP_GLOBAL                         (1 << 31)
+#define R500_US_FC_BOOL_CONST                          0x4620
+#   define R500_FC_KBOOL(x)                            (x)
+#define R500_US_FC_CTRL                                        0x4624
+#   define R500_FC_TEST_EN                             (1 << 30)
+#   define R500_FC_FULL_FC_EN                          (1 << 31)
+#define R500_US_FC_INST_0                              0x9800
+#   define R500_FC_OP_JUMP                             (0 << 0)
+#   define R500_FC_OP_LOOP                             (1 << 0)
+#   define R500_FC_OP_ENDLOOP                          (2 << 0)
+#   define R500_FC_OP_REP                              (3 << 0)
+#   define R500_FC_OP_ENDREP                           (4 << 0)
+#   define R500_FC_OP_BREAKLOOP                                (5 << 0)
+#   define R500_FC_OP_BREAKREP                         (6 << 0)
+#   define R500_FC_OP_CONTINUE                         (7 << 0)
+#   define R500_FC_B_ELSE                              (1 << 4)
+#   define R500_FC_JUMP_ANY                            (1 << 5)
+#   define R500_FC_A_OP_NONE                           (0 << 6)
+#   define R500_FC_A_OP_POP                            (1 << 6)
+#   define R500_FC_A_OP_PUSH                           (2 << 6)
+#   define R500_FC_JUMP_FUNC(x)                                (x << 8)
+#   define R500_FC_B_POP_CNT(x)                                (x << 16)
+#   define R500_FC_B_OP0_NONE                          (0 << 24)
+#   define R500_FC_B_OP0_DECR                          (1 << 24)
+#   define R500_FC_B_OP0_INCR                          (2 << 24)
+#   define R500_FC_B_OP1_DECR                          (0 << 26)
+#   define R500_FC_B_OP1_NONE                          (1 << 26)
+#   define R500_FC_B_OP1_INCR                          (2 << 26)
+#   define R500_FC_IGNORE_UNCOVERED                    (1 << 28)
+#define R500_US_FC_INT_CONST_0                         0x4c00
+#   define R500_FC_INT_CONST_KR(x)                     (x << 0)
+#   define R500_FC_INT_CONST_KG(x)                     (x << 8)
+#   define R500_FC_INT_CONST_KB(x)                     (x << 16)
+/* _0 through _15 */
+#define R500_US_FORMAT0_0                              0x4640
+#   define R500_FORMAT_TXWIDTH(x)                      (x << 0)
+#   define R500_FORMAT_TXHEIGHT(x)                     (x << 11)
+#   define R500_FORMAT_TXDEPTH(x)                      (x << 22)
+/* _0 through _3 */
+#define R500_US_OUT_FMT_0                              0x46A4
+#   define R500_OUT_FMT_C4_8                           (0 << 0)
+#   define R500_OUT_FMT_C4_10                          (1 << 0)
+#   define R500_OUT_FMT_C4_10_GAMMA                    (2 << 0)
+#   define R500_OUT_FMT_C_16                           (3 << 0)
+#   define R500_OUT_FMT_C2_16                          (4 << 0)
+#   define R500_OUT_FMT_C4_16                          (5 << 0)
+#   define R500_OUT_FMT_C_16_MPEG                      (6 << 0)
+#   define R500_OUT_FMT_C2_16_MPEG                     (7 << 0)
+#   define R500_OUT_FMT_C2_4                           (8 << 0)
+#   define R500_OUT_FMT_C_3_3_2                                (9 << 0)
+#   define R500_OUT_FMT_C_6_5_6                                (10 << 0)
+#   define R500_OUT_FMT_C_11_11_10                     (11 << 0)
+#   define R500_OUT_FMT_C_10_11_11                     (12 << 0)
+#   define R500_OUT_FMT_C_2_10_10_10                   (13 << 0)
+/* #define R500_OUT_FMT_RESERVED                       (14 << 0) */
+#   define R500_OUT_FMT_UNUSED                         (15 << 0)
+#   define R500_OUT_FMT_C_16_FP                                (16 << 0)
+#   define R500_OUT_FMT_C2_16_FP                       (17 << 0)
+#   define R500_OUT_FMT_C4_16_FP                       (18 << 0)
+#   define R500_OUT_FMT_C_32_FP                                (19 << 0)
+#   define R500_OUT_FMT_C2_32_FP                       (20 << 0)
+#   define R500_OUT_FMT_C4_32_FP                       (21 << 0)
+#   define R500_C0_SEL_A                               (0 << 8)
+#   define R500_C0_SEL_R                               (1 << 8)
+#   define R500_C0_SEL_G                               (2 << 8)
+#   define R500_C0_SEL_B                               (3 << 8)
+#   define R500_C1_SEL_A                               (0 << 10)
+#   define R500_C1_SEL_R                               (1 << 10)
+#   define R500_C1_SEL_G                               (2 << 10)
+#   define R500_C1_SEL_B                               (3 << 10)
+#   define R500_C2_SEL_A                               (0 << 12)
+#   define R500_C2_SEL_R                               (1 << 12)
+#   define R500_C2_SEL_G                               (2 << 12)
+#   define R500_C2_SEL_B                               (3 << 12)
+#   define R500_C3_SEL_A                               (0 << 14)
+#   define R500_C3_SEL_R                               (1 << 14)
+#   define R500_C3_SEL_G                               (2 << 14)
+#   define R500_C3_SEL_B                               (3 << 14)
+#   define R500_OUT_SIGN(x)                            (x << 16)
+#   define R500_ROUND_ADJ                              (1 << 20)
+#define R500_US_PIXSIZE                                        0x4604
+#   define R500_PIX_SIZE(x)                            (x)
+#define R500_US_TEX_ADDR_0                             0x9800
+#   define R500_TEX_SRC_ADDR(x)                                (x << 0)
+#   define R500_TEX_SRC_ADDR_REL                       (1 << 7)
+#   define R500_TEX_SRC_S_SWIZ_R                       (0 << 8)
+#   define R500_TEX_SRC_S_SWIZ_G                       (1 << 8)
+#   define R500_TEX_SRC_S_SWIZ_B                       (2 << 8)
+#   define R500_TEX_SRC_S_SWIZ_A                       (3 << 8)
+#   define R500_TEX_SRC_T_SWIZ_R                       (0 << 10)
+#   define R500_TEX_SRC_T_SWIZ_G                       (1 << 10)
+#   define R500_TEX_SRC_T_SWIZ_B                       (2 << 10)
+#   define R500_TEX_SRC_T_SWIZ_A                       (3 << 10)
+#   define R500_TEX_SRC_R_SWIZ_R                       (0 << 12)
+#   define R500_TEX_SRC_R_SWIZ_G                       (1 << 12)
+#   define R500_TEX_SRC_R_SWIZ_B                       (2 << 12)
+#   define R500_TEX_SRC_R_SWIZ_A                       (3 << 12)
+#   define R500_TEX_SRC_Q_SWIZ_R                       (0 << 14)
+#   define R500_TEX_SRC_Q_SWIZ_G                       (1 << 14)
+#   define R500_TEX_SRC_Q_SWIZ_B                       (2 << 14)
+#   define R500_TEX_SRC_Q_SWIZ_A                       (3 << 14)
+#   define R500_TEX_DST_ADDR(x)                                (x << 16)
+#   define R500_TEX_DST_ADDR_REL                       (1 << 23)
+#   define R500_TEX_DST_R_SWIZ_R                       (0 << 24)
+#   define R500_TEX_DST_R_SWIZ_G                       (1 << 24)
+#   define R500_TEX_DST_R_SWIZ_B                       (2 << 24)
+#   define R500_TEX_DST_R_SWIZ_A                       (3 << 24)
+#   define R500_TEX_DST_G_SWIZ_R                       (0 << 26)
+#   define R500_TEX_DST_G_SWIZ_G                       (1 << 26)
+#   define R500_TEX_DST_G_SWIZ_B                       (2 << 26)
+#   define R500_TEX_DST_G_SWIZ_A                       (3 << 26)
+#   define R500_TEX_DST_B_SWIZ_R                       (0 << 28)
+#   define R500_TEX_DST_B_SWIZ_G                       (1 << 28)
+#   define R500_TEX_DST_B_SWIZ_B                       (2 << 28)
+#   define R500_TEX_DST_B_SWIZ_A                       (3 << 28)
+#   define R500_TEX_DST_A_SWIZ_R                       (0 << 30)
+#   define R500_TEX_DST_A_SWIZ_G                       (1 << 30)
+#   define R500_TEX_DST_A_SWIZ_B                       (2 << 30)
+#   define R500_TEX_DST_A_SWIZ_A                       (3 << 30)
+#define R500_US_TEX_ADDR_DXDY_0                                0xa000
+#   define R500_DX_ADDR(x)                             (x << 0)
+#   define R500_DX_ADDR_REL                            (1 << 7)
+#   define R500_DX_S_SWIZ_R                            (0 << 8)
+#   define R500_DX_S_SWIZ_G                            (1 << 8)
+#   define R500_DX_S_SWIZ_B                            (2 << 8)
+#   define R500_DX_S_SWIZ_A                            (3 << 8)
+#   define R500_DX_T_SWIZ_R                            (0 << 10)
+#   define R500_DX_T_SWIZ_G                            (1 << 10)
+#   define R500_DX_T_SWIZ_B                            (2 << 10)
+#   define R500_DX_T_SWIZ_A                            (3 << 10)
+#   define R500_DX_R_SWIZ_R                            (0 << 12)
+#   define R500_DX_R_SWIZ_G                            (1 << 12)
+#   define R500_DX_R_SWIZ_B                            (2 << 12)
+#   define R500_DX_R_SWIZ_A                            (3 << 12)
+#   define R500_DX_Q_SWIZ_R                            (0 << 14)
+#   define R500_DX_Q_SWIZ_G                            (1 << 14)
+#   define R500_DX_Q_SWIZ_B                            (2 << 14)
+#   define R500_DX_Q_SWIZ_A                            (3 << 14)
+#   define R500_DY_ADDR(x)                             (x << 16)
+#   define R500_DY_ADDR_REL                            (1 << 17)
+#   define R500_DY_S_SWIZ_R                            (0 << 24)
+#   define R500_DY_S_SWIZ_G                            (1 << 24)
+#   define R500_DY_S_SWIZ_B                            (2 << 24)
+#   define R500_DY_S_SWIZ_A                            (3 << 24)
+#   define R500_DY_T_SWIZ_R                            (0 << 26)
+#   define R500_DY_T_SWIZ_G                            (1 << 26)
+#   define R500_DY_T_SWIZ_B                            (2 << 26)
+#   define R500_DY_T_SWIZ_A                            (3 << 26)
+#   define R500_DY_R_SWIZ_R                            (0 << 28)
+#   define R500_DY_R_SWIZ_G                            (1 << 28)
+#   define R500_DY_R_SWIZ_B                            (2 << 28)
+#   define R500_DY_R_SWIZ_A                            (3 << 28)
+#   define R500_DY_Q_SWIZ_R                            (0 << 30)
+#   define R500_DY_Q_SWIZ_G                            (1 << 30)
+#   define R500_DY_Q_SWIZ_B                            (2 << 30)
+#   define R500_DY_Q_SWIZ_A                            (3 << 30)
+#define R500_US_TEX_INST_0                             0x9000
+#   define R500_TEX_ID(x)                              (x << 16)
+#   define R500_TEX_INST_NOP                           (0 << 22)
+#   define R500_TEX_INST_LD                            (1 << 22)
+#   define R500_TEX_INST_TEXKILL                       (2 << 22)
+#   define R500_TEX_INST_PROJ                          (3 << 22)
+#   define R500_TEX_INST_LODBIAS                       (4 << 22)
+#   define R500_TEX_INST_LOD                           (5 << 22)
+#   define R500_TEX_INST_DXDY                          (6 << 22)
+#   define R500_TEX_SEM_ACQUIRE                                (1 << 25)
+#   define R500_TEX_IGNORE_UNCOVERED                   (1 << 26)
+#   define R500_TEX_UNSCALED                           (1 << 27)
+#define R300_US_W_FMT                                  0x46b4
+#   define R300_W_FMT_W0                               (0 << 0)
+#   define R300_W_FMT_W24                              (1 << 0)
+#   define R300_W_FMT_W24FP                            (2 << 0)
+#   define R300_W_SRC_US                               (0 << 2)
+#   define R300_W_SRC_RAS                              (1 << 2)
+
+
+/* Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR.
+ * Two parameter dwords:
+ * 0. VAP_VTX_FMT: The first parameter is not written to hardware
+ * 1. VAP_VF_CTL: The second parameter is a standard primitive emission dword.
+ */
+#define R300_PACKET3_3D_DRAW_VBUF           0x00002800
+
+/* Draw a primitive from immediate vertices in this packet
+ * Up to 16382 dwords:
+ * 0. VAP_VTX_FMT: The first parameter is not written to hardware
+ * 1. VAP_VF_CTL: The second parameter is a standard primitive emission dword.
+ * 2 to end: Up to 16380 dwords of vertex data.
+ */
+#define R300_PACKET3_3D_DRAW_IMMD           0x00002900
+
+/* Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR and
+ * immediate vertices in this packet
+ * Up to 16382 dwords:
+ * 0. VAP_VTX_FMT: The first parameter is not written to hardware
+ * 1. VAP_VF_CTL: The second parameter is a standard primitive emission dword.
+ * 2 to end: Up to 16380 dwords of vertex data.
+ */
+#define R300_PACKET3_3D_DRAW_INDX           0x00002A00
+
+
+/* Specify the full set of vertex arrays as (address, stride).
+ * The first parameter is the number of vertex arrays specified.
+ * The rest of the command is a variable length list of blocks, where
+ * each block is three dwords long and specifies two arrays.
+ * The first dword of a block is split into two words, the lower significant
+ * word refers to the first array, the more significant word to the second
+ * array in the block.
+ * The low byte of each word contains the size of an array entry in dwords,
+ * the high byte contains the stride of the array.
+ * The second dword of a block contains the pointer to the first array,
+ * the third dword of a block contains the pointer to the second array.
+ * Note that if the total number of arrays is odd, the third dword of
+ * the last block is omitted.
+ */
+#define R300_PACKET3_3D_LOAD_VBPNTR         0x00002F00
+
+#define R300_PACKET3_INDX_BUFFER            0x00003300
+#    define R300_EB_UNK1_SHIFT                      24
+#    define R300_EB_UNK1                    (0x80<<24)
+#    define R300_EB_UNK2                        0x0810
+
+/* Same as R300_PACKET3_3D_DRAW_VBUF but without VAP_VTX_FMT */
+#define R300_PACKET3_3D_DRAW_VBUF_2         0x00003400
+/* Same as R300_PACKET3_3D_DRAW_IMMD but without VAP_VTX_FMT */
+#define R300_PACKET3_3D_DRAW_IMMD_2         0x00003500
+/* Same as R300_PACKET3_3D_DRAW_INDX but without VAP_VTX_FMT */
+#define R300_PACKET3_3D_DRAW_INDX_2         0x00003600
+
+/* Clears a portion of hierachical Z RAM
+ * 3 dword parameters
+ * 0. START
+ * 1. COUNT: 13:0 (max is 0x3FFF)
+ * 2. CLEAR_VALUE: Value to write into HIZ RAM.
+ */
+#define R300_PACKET3_3D_CLEAR_HIZ           0x00003700
+
+/* Draws a set of primitives using vertex buffers pointed by the state data.
+ * At least 2 Parameters:
+ * 0. VAP_VF_CNTL: The first parameter is a standard primitive emission dword.
+ * 2 to end: Data or indices (see other 3D_DRAW_* packets for details)
+ */
+#define R300_PACKET3_3D_DRAW_128            0x00003900
+
+/* END: Packet 3 commands */
+
+
+/* Color formats for 2d packets
+ */
+#define R300_CP_COLOR_FORMAT_CI8       2
+#define R300_CP_COLOR_FORMAT_ARGB1555  3
+#define R300_CP_COLOR_FORMAT_RGB565    4
+#define R300_CP_COLOR_FORMAT_ARGB8888  6
+#define R300_CP_COLOR_FORMAT_RGB332    7
+#define R300_CP_COLOR_FORMAT_RGB8      9
+#define R300_CP_COLOR_FORMAT_ARGB4444  15
+
+/*
+ * CP type-3 packets
+ */
+#define R300_CP_CMD_BITBLT_MULTI       0xC0009B00
+
+/* XXX Corbin's stuff from radeon and r200 */
+
+#define RADEON_WAIT_UNTIL                   0x1720
+#       define RADEON_WAIT_CRTC_PFLIP       (1 << 0)
+#       define RADEON_WAIT_2D_IDLECLEAN     (1 << 16)
+#       define RADEON_WAIT_3D_IDLECLEAN     (1 << 17)
+#       define RADEON_WAIT_HOST_IDLECLEAN   (1 << 18)
+
+#define RADEON_CP_PACKET3                           0xC0000000
+
+#define R200_3D_DRAW_IMMD_2      0xC0003500
+
+#endif /* _R300_REG_H */
+
+/* *INDENT-ON* */
+
+/* vim: set foldenable foldmarker=\\{,\\} foldmethod=marker : */
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
new file mode 100644 (file)
index 0000000..fd916fa
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "r300_screen.h"
+
+/* Return the identifier behind whom the brave coders responsible for this
+ * amalgamation of code, sweat, and duct tape, routinely obscure their names.
+ *
+ * ...I should have just put "Corbin Simpson", but I'm not that cool.
+ *
+ * (Or egotistical. Yet.) */
+static const char* r300_get_vendor(struct pipe_screen* pscreen)
+{
+    return "X.Org R300 Project";
+}
+
+static const char* chip_families[] = {
+    "R300",
+    "R350",
+    "R360",
+    "RV350",
+    "RV370",
+    "RV380",
+    "R420",
+    "R423",
+    "R430",
+    "R480",
+    "R481",
+    "RV410",
+    "RS400",
+    "RC410",
+    "RS480",
+    "RS482",
+    "RS690",
+    "RS740",
+    "RV515",
+    "R520",
+    "RV530",
+    "R580",
+    "RV560",
+    "RV570"
+};
+
+static const char* r300_get_name(struct pipe_screen* pscreen)
+{
+    struct r300_screen* r300screen = r300_screen(pscreen);
+
+    return chip_families[r300screen->caps->family];
+}
+
+static int r300_get_param(struct pipe_screen* pscreen, int param)
+{
+    struct r300_screen* r300screen = r300_screen(pscreen);
+
+    switch (param) {
+        /* XXX cases marked "IN THEORY" are possible on the hardware,
+         * but haven't been implemented yet. */
+        case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+            /* XXX I'm told this goes up to 16 */
+            return 8;
+        case PIPE_CAP_NPOT_TEXTURES:
+            /* IN THEORY */
+            return 0;
+        case PIPE_CAP_TWO_SIDED_STENCIL:
+            if (r300screen->caps->is_r500) {
+                return 1;
+            } else {
+                return 0;
+            }
+            return 0;
+        case PIPE_CAP_GLSL:
+            /* IN THEORY */
+            return 0;
+        case PIPE_CAP_S3TC:
+            /* IN THEORY */
+            return 0;
+        case PIPE_CAP_ANISOTROPIC_FILTER:
+            /* IN THEORY */
+            return 0;
+        case PIPE_CAP_POINT_SPRITE:
+            /* IN THEORY */
+            return 0;
+        case PIPE_CAP_MAX_RENDER_TARGETS:
+            /* XXX 4 eventually */
+            return 1;
+        case PIPE_CAP_OCCLUSION_QUERY:
+            /* IN THEORY */
+            return 0;
+        case PIPE_CAP_TEXTURE_SHADOW_MAP:
+            /* IN THEORY */
+            return 0;
+        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+            if (r300screen->caps->is_r500) {
+                /* 13 == 4096x4096 */
+                return 13;
+            } else {
+                /* 12 == 2048x2048 */
+                return 12;
+            }
+        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+            /* So, technically, the limit is the same as above, but some math
+             * shows why this is silly. Assuming RGBA, 4cpp, we can see that
+             * 4096*4096*4096 = 64.0 GiB exactly, so it's not exactly
+             * practical. However, if at some point a game really wants this,
+             * then we can remove this limit. */
+            if (r300screen->caps->is_r500) {
+                /* 9 == 256x256x256 */
+                return 9;
+            } else {
+                /* 8 == 128*128*128 */
+                return 8;
+            }
+        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+            if (r300screen->caps->is_r500) {
+                /* 13 == 4096x4096 */
+                return 13;
+            } else {
+                /* 12 == 2048x2048 */
+                return 12;
+            }
+        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
+            return 1;
+        case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
+            return 1;
+        case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+            /* XXX guessing */
+            return 2;
+        default:
+            debug_printf("r300: Implementation error: Bad param %d\n",
+                param);
+            return 0;
+    }
+}
+
+static float r300_get_paramf(struct pipe_screen* pscreen, int param)
+{
+    switch (param) {
+        case PIPE_CAP_MAX_LINE_WIDTH:
+        case PIPE_CAP_MAX_LINE_WIDTH_AA:
+            /* XXX this is the biggest thing that will fit in that register.
+            * Perhaps the actual rendering limits are less? */
+            return 10922.0f;
+        case PIPE_CAP_MAX_POINT_WIDTH:
+        case PIPE_CAP_MAX_POINT_WIDTH_AA:
+            /* XXX this is the biggest thing that will fit in that register.
+             * Perhaps the actual rendering limits are less? */
+            return 10922.0f;
+        case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+            return 16.0f;
+        case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+            return 16.0f;
+        default:
+            debug_printf("r300: Implementation error: Bad paramf %d\n",
+                param);
+            return 0.0f;
+    }
+}
+
+/* XXX moar formats */
+static boolean check_tex_2d_format(enum pipe_format format)
+{
+    switch (format) {
+        case PIPE_FORMAT_A8R8G8B8_UNORM:
+        case PIPE_FORMAT_I8_UNORM:
+            return TRUE;
+        default:
+            debug_printf("r300: Warning: Got unknown format: %s, in %s\n",
+                pf_name(format), __FUNCTION__);
+            break;
+    }
+
+    return FALSE;
+}
+
+/* XXX moar targets */
+static boolean r300_is_format_supported(struct pipe_screen* pscreen,
+                                        enum pipe_format format,
+                                        enum pipe_texture_target target,
+                                        unsigned tex_usage,
+                                        unsigned geom_flags)
+{
+    switch (target) {
+        case PIPE_TEXTURE_2D:
+            return check_tex_2d_format(format);
+        default:
+            debug_printf("r300: Warning: Got unknown format target: %d\n",
+                format);
+            break;
+    }
+
+    return FALSE;
+}
+
+static void* r300_surface_map(struct pipe_screen* screen,
+                              struct pipe_surface* surface,
+                              unsigned flags)
+{
+    char* map = pipe_buffer_map(screen, surface->buffer, flags);
+
+    if (!map) {
+        return NULL;
+    }
+
+    return map + surface->offset;
+}
+
+static void r300_surface_unmap(struct pipe_screen* screen,
+                               struct pipe_surface* surface)
+{
+    pipe_buffer_unmap(screen, surface->buffer);
+}
+
+static void r300_destroy_screen(struct pipe_screen* pscreen)
+{
+    struct r300_screen* r300screen = r300_screen(pscreen);
+
+    FREE(r300screen->caps);
+    FREE(r300screen);
+}
+
+struct pipe_screen* r300_create_screen(struct pipe_winsys* winsys,
+                                       struct r300_winsys* r300_winsys)
+{
+    struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen);
+    struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities);
+
+    if (!r300screen || !caps)
+        return NULL;
+
+    caps->pci_id = r300_winsys->pci_id;
+    caps->num_frag_pipes = r300_winsys->gb_pipes;
+
+    r300_parse_chipset(caps);
+
+    r300screen->caps = caps;
+    r300screen->screen.winsys = winsys;
+    r300screen->screen.destroy = r300_destroy_screen;
+    r300screen->screen.get_name = r300_get_name;
+    r300screen->screen.get_vendor = r300_get_vendor;
+    r300screen->screen.get_param = r300_get_param;
+    r300screen->screen.get_paramf = r300_get_paramf;
+    r300screen->screen.is_format_supported = r300_is_format_supported;
+    r300screen->screen.surface_map = r300_surface_map;
+    r300screen->screen.surface_unmap = r300_surface_unmap;
+
+    r300_init_screen_texture_functions(&r300screen->screen);
+    u_simple_screen_init(&r300screen->screen);
+
+    return &r300screen->screen;
+}
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
new file mode 100644 (file)
index 0000000..2e25f61
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 R300_SCREEN_H
+#define R300_SCREEN_H
+
+#include "pipe/p_inlines.h"
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+#include "util/u_simple_screen.h"
+
+#include "r300_chipset.h"
+#include "r300_texture.h"
+#include "r300_winsys.h"
+
+struct r300_screen {
+    /* Parent class */
+    struct pipe_screen screen;
+
+    /* Chipset capabilities */
+    struct r300_capabilities* caps;
+};
+
+/* Convenience cast wrapper. */
+static struct r300_screen* r300_screen(struct pipe_screen* screen) {
+    return (struct r300_screen*)screen;
+}
+
+/* Creates a new r300 screen. */
+struct pipe_screen* r300_create_screen(struct pipe_winsys* winsys,
+                                       struct r300_winsys* r300_winsys);
+
+#endif /* R300_SCREEN_H */
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
new file mode 100644 (file)
index 0000000..9392d72
--- /dev/null
@@ -0,0 +1,826 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "util/u_math.h"
+#include "util/u_pack_color.h"
+#include "pipe/p_debug.h"
+
+#include "r300_context.h"
+#include "r300_reg.h"
+
+/* r300_state: Functions used to intialize state context by translating
+ * Gallium state objects into semi-native r300 state objects.
+ *
+ * XXX break this file up into pieces if it gets too big! */
+
+/* Pack a float into a dword. */
+static uint32_t pack_float_32(float f)
+{
+    union {
+        float f;
+        uint32_t u;
+    } u;
+
+    u.f = f;
+    return u.u;
+}
+
+static uint32_t translate_blend_function(int blend_func) {
+    switch (blend_func) {
+        case PIPE_BLEND_ADD:
+            return R300_COMB_FCN_ADD_CLAMP;
+        case PIPE_BLEND_SUBTRACT:
+            return R300_COMB_FCN_SUB_CLAMP;
+        case PIPE_BLEND_REVERSE_SUBTRACT:
+            return R300_COMB_FCN_RSUB_CLAMP;
+        case PIPE_BLEND_MIN:
+            return R300_COMB_FCN_MIN;
+        case PIPE_BLEND_MAX:
+            return R300_COMB_FCN_MAX;
+        default:
+            debug_printf("r300: Unknown blend function %d\n", blend_func);
+            break;
+    }
+    return 0;
+}
+
+/* XXX we can also offer the D3D versions of some of these... */
+static uint32_t translate_blend_factor(int blend_fact) {
+    switch (blend_fact) {
+        case PIPE_BLENDFACTOR_ONE:
+            return R300_BLEND_GL_ONE;
+        case PIPE_BLENDFACTOR_SRC_COLOR:
+            return R300_BLEND_GL_SRC_COLOR;
+        case PIPE_BLENDFACTOR_SRC_ALPHA:
+            return R300_BLEND_GL_SRC_ALPHA;
+        case PIPE_BLENDFACTOR_DST_ALPHA:
+            return R300_BLEND_GL_DST_ALPHA;
+        case PIPE_BLENDFACTOR_DST_COLOR:
+            return R300_BLEND_GL_DST_COLOR;
+        case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+            return R300_BLEND_GL_SRC_ALPHA_SATURATE;
+        case PIPE_BLENDFACTOR_CONST_COLOR:
+            return R300_BLEND_GL_CONST_COLOR;
+        case PIPE_BLENDFACTOR_CONST_ALPHA:
+            return R300_BLEND_GL_CONST_ALPHA;
+        /* XXX WTF are these?
+        case PIPE_BLENDFACTOR_SRC1_COLOR:
+        case PIPE_BLENDFACTOR_SRC1_ALPHA: */
+        case PIPE_BLENDFACTOR_ZERO:
+            return R300_BLEND_GL_ZERO;
+        case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+            return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
+        case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+            return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
+        case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+            return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
+        case PIPE_BLENDFACTOR_INV_DST_COLOR:
+            return R300_BLEND_GL_ONE_MINUS_DST_COLOR;
+        case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+            return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
+        case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+            return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
+        /* XXX see above
+        case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+        case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */
+        default:
+            debug_printf("r300: Unknown blend factor %d\n", blend_fact);
+            break;
+    }
+    return 0;
+}
+
+/* Create a new blend state based on the CSO blend state.
+ *
+ * This encompasses alpha blending, logic/raster ops, and blend dithering. */
+static void* r300_create_blend_state(struct pipe_context* pipe,
+                                     const struct pipe_blend_state* state)
+{
+    struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state);
+
+    if (state->blend_enable) {
+        /* XXX for now, always do separate alpha...
+         * is it faster to do it with one reg? */
+        blend->blend_control = R300_ALPHA_BLEND_ENABLE |
+                R300_SEPARATE_ALPHA_ENABLE |
+                R300_READ_ENABLE |
+                translate_blend_function(state->rgb_func) |
+                (translate_blend_factor(state->rgb_src_factor) <<
+                    R300_SRC_BLEND_SHIFT) |
+                (translate_blend_factor(state->rgb_dst_factor) <<
+                    R300_DST_BLEND_SHIFT);
+        blend->alpha_blend_control =
+                translate_blend_function(state->alpha_func) |
+                (translate_blend_factor(state->alpha_src_factor) <<
+                    R300_SRC_BLEND_SHIFT) |
+                (translate_blend_factor(state->alpha_dst_factor) <<
+                    R300_DST_BLEND_SHIFT);
+    }
+
+    /* PIPE_LOGICOP_* don't need to be translated, fortunately. */
+    /* XXX are logicops still allowed if blending's disabled?
+     * Does Gallium take care of it for us? */
+    if (state->logicop_enable) {
+        blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE |
+                (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;
+    }
+
+    if (state->dither) {
+        blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT |
+                R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT;
+    }
+
+    return (void*)blend;
+}
+
+/* Bind blend state. */
+static void r300_bind_blend_state(struct pipe_context* pipe,
+                                  void* state)
+{
+    struct r300_context* r300 = r300_context(pipe);
+
+    r300->blend_state = (struct r300_blend_state*)state;
+    r300->dirty_state |= R300_NEW_BLEND;
+}
+
+/* Free blend state. */
+static void r300_delete_blend_state(struct pipe_context* pipe,
+                                    void* state)
+{
+    FREE(state);
+}
+
+/* Set blend color.
+ * Setup both R300 and R500 registers, figure out later which one to write. */
+static void r300_set_blend_color(struct pipe_context* pipe,
+                                 const struct pipe_blend_color* color)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    uint32_t r, g, b, a;
+    ubyte ur, ug, ub, ua;
+
+    r = util_iround(color->color[0] * 1023.0f);
+    g = util_iround(color->color[1] * 1023.0f);
+    b = util_iround(color->color[2] * 1023.0f);
+    a = util_iround(color->color[3] * 1023.0f);
+
+    ur = float_to_ubyte(color->color[0]);
+    ug = float_to_ubyte(color->color[1]);
+    ub = float_to_ubyte(color->color[2]);
+    ua = float_to_ubyte(color->color[3]);
+
+    r300->blend_color_state->blend_color = (a << 24) | (r << 16) | (g << 8) | b;
+
+    r300->blend_color_state->blend_color_red_alpha = ur | (ua << 16);
+    r300->blend_color_state->blend_color_green_blue = ub | (ug << 16);
+
+    r300->dirty_state |= R300_NEW_BLEND_COLOR;
+}
+
+static void r300_set_clip_state(struct pipe_context* pipe,
+                                const struct pipe_clip_state* state)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    /* XXX Draw */
+    draw_flush(r300->draw);
+    draw_set_clip_state(r300->draw, state);
+}
+
+static void
+    r300_set_constant_buffer(struct pipe_context* pipe,
+                             uint shader, uint index,
+                             const struct pipe_constant_buffer* buffer)
+{
+    /* XXX */
+}
+
+static uint32_t translate_depth_stencil_function(int zs_func) {
+    switch (zs_func) {
+        case PIPE_FUNC_NEVER:
+            return R300_ZS_NEVER;
+        case PIPE_FUNC_LESS:
+            return R300_ZS_LESS;
+        case PIPE_FUNC_EQUAL:
+            return R300_ZS_EQUAL;
+        case PIPE_FUNC_LEQUAL:
+            return R300_ZS_LEQUAL;
+        case PIPE_FUNC_GREATER:
+            return R300_ZS_GREATER;
+        case PIPE_FUNC_NOTEQUAL:
+            return R300_ZS_NOTEQUAL;
+        case PIPE_FUNC_GEQUAL:
+            return R300_ZS_GEQUAL;
+        case PIPE_FUNC_ALWAYS:
+            return R300_ZS_ALWAYS;
+        default:
+            debug_printf("r300: Unknown depth/stencil function %d\n",
+                zs_func);
+            break;
+    }
+    return 0;
+}
+
+static uint32_t translate_stencil_op(int s_op) {
+    switch (s_op) {
+        case PIPE_STENCIL_OP_KEEP:
+            return R300_ZS_KEEP;
+        case PIPE_STENCIL_OP_ZERO:
+            return R300_ZS_ZERO;
+        case PIPE_STENCIL_OP_REPLACE:
+            return R300_ZS_REPLACE;
+        case PIPE_STENCIL_OP_INCR:
+            return R300_ZS_INCR;
+        case PIPE_STENCIL_OP_DECR:
+            return R300_ZS_DECR;
+        case PIPE_STENCIL_OP_INCR_WRAP:
+            return R300_ZS_INCR_WRAP;
+        case PIPE_STENCIL_OP_DECR_WRAP:
+            return R300_ZS_DECR_WRAP;
+        case PIPE_STENCIL_OP_INVERT:
+            return R300_ZS_INVERT;
+        default:
+            debug_printf("r300: Unknown stencil op %d", s_op);
+            break;
+    }
+    return 0;
+}
+
+static uint32_t translate_alpha_function(int alpha_func) {
+    switch (alpha_func) {
+        case PIPE_FUNC_NEVER:
+            return R300_FG_ALPHA_FUNC_NEVER;
+        case PIPE_FUNC_LESS:
+            return R300_FG_ALPHA_FUNC_LESS;
+        case PIPE_FUNC_EQUAL:
+            return R300_FG_ALPHA_FUNC_EQUAL;
+        case PIPE_FUNC_LEQUAL:
+            return R300_FG_ALPHA_FUNC_LE;
+        case PIPE_FUNC_GREATER:
+            return R300_FG_ALPHA_FUNC_GREATER;
+        case PIPE_FUNC_NOTEQUAL:
+            return R300_FG_ALPHA_FUNC_NOTEQUAL;
+        case PIPE_FUNC_GEQUAL:
+            return R300_FG_ALPHA_FUNC_GE;
+        case PIPE_FUNC_ALWAYS:
+            return R300_FG_ALPHA_FUNC_ALWAYS;
+        default:
+            debug_printf("r300: Unknown alpha function %d", alpha_func);
+            break;
+    }
+    return 0;
+}
+
+/* Create a new depth, stencil, and alpha state based on the CSO dsa state.
+ *
+ * This contains the depth buffer, stencil buffer, alpha test, and such.
+ * On the Radeon, depth and stencil buffer setup are intertwined, which is
+ * the reason for some of the strange-looking assignments across registers. */
+static void*
+        r300_create_dsa_state(struct pipe_context* pipe,
+                              const struct pipe_depth_stencil_alpha_state* state)
+{
+    struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
+
+    /* Depth test setup. */
+    if (state->depth.enabled) {
+        dsa->z_buffer_control |= R300_Z_ENABLE;
+
+        if (state->depth.writemask) {
+            dsa->z_buffer_control |= R300_Z_WRITE_ENABLE;
+        }
+
+        dsa->z_stencil_control |=
+            (translate_depth_stencil_function(state->depth.func) <<
+                R300_Z_FUNC_SHIFT);
+    }
+
+    /* Stencil buffer setup. */
+    if (state->stencil[0].enabled) {
+        dsa->z_buffer_control |= R300_STENCIL_ENABLE;
+        dsa->z_stencil_control |=
+                (translate_depth_stencil_function(state->stencil[0].func) <<
+                    R300_S_FRONT_FUNC_SHIFT) |
+                (translate_stencil_op(state->stencil[0].fail_op) <<
+                    R300_S_FRONT_SFAIL_OP_SHIFT) |
+                (translate_stencil_op(state->stencil[0].zpass_op) <<
+                    R300_S_FRONT_ZPASS_OP_SHIFT) |
+                (translate_stencil_op(state->stencil[0].zfail_op) <<
+                    R300_S_FRONT_ZFAIL_OP_SHIFT);
+
+        dsa->stencil_ref_mask = (state->stencil[0].ref_value) |
+                (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) |
+                (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT);
+
+        if (state->stencil[1].enabled) {
+            dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
+            dsa->z_stencil_control |=
+                (translate_depth_stencil_function(state->stencil[1].func) <<
+                    R300_S_BACK_FUNC_SHIFT) |
+                (translate_stencil_op(state->stencil[1].fail_op) <<
+                    R300_S_BACK_SFAIL_OP_SHIFT) |
+                (translate_stencil_op(state->stencil[1].zpass_op) <<
+                    R300_S_BACK_ZPASS_OP_SHIFT) |
+                (translate_stencil_op(state->stencil[1].zfail_op) <<
+                    R300_S_BACK_ZFAIL_OP_SHIFT);
+
+            dsa->stencil_ref_bf = (state->stencil[1].ref_value) |
+                (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) |
+                (state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT);
+        }
+    }
+
+    /* Alpha test setup. */
+    if (state->alpha.enabled) {
+        dsa->alpha_function = translate_alpha_function(state->alpha.func) |
+            R300_FG_ALPHA_FUNC_ENABLE;
+        dsa->alpha_reference = CLAMP(state->alpha.ref_value * 1023.0f,
+                                     0, 1023);
+    } else {
+        dsa->z_buffer_top = R300_ZTOP_ENABLE;
+    }
+
+    return (void*)dsa;
+}
+
+/* Bind DSA state. */
+static void r300_bind_dsa_state(struct pipe_context* pipe,
+                                void* state)
+{
+    struct r300_context* r300 = r300_context(pipe);
+
+    r300->dsa_state = (struct r300_dsa_state*)state;
+    r300->dirty_state |= R300_NEW_DSA;
+}
+
+/* Free DSA state. */
+static void r300_delete_dsa_state(struct pipe_context* pipe,
+                                  void* state)
+{
+    FREE(state);
+}
+
+static void r300_set_edgeflags(struct pipe_context* pipe,
+                               const unsigned* bitfield)
+{
+    /* XXX you know it's bad when i915 has this blank too */
+}
+
+static void
+    r300_set_framebuffer_state(struct pipe_context* pipe,
+                               const struct pipe_framebuffer_state* state)
+{
+    struct r300_context* r300 = r300_context(pipe);
+
+    draw_flush(r300->draw);
+
+    r300->framebuffer_state = *state;
+
+    r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
+}
+
+/* Create fragment shader state. */
+static void* r300_create_fs_state(struct pipe_context* pipe,
+                                  const struct pipe_shader_state* shader)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    struct r3xx_fragment_shader* fs = NULL;
+
+    if (r300_screen(r300->context.screen)->caps->is_r500) {
+        fs =
+            (struct r3xx_fragment_shader*)CALLOC_STRUCT(r500_fragment_shader);
+    } else {
+        fs =
+            (struct r3xx_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);
+    }
+
+    /* Copy state directly into shader. */
+    fs->state = *shader;
+
+    return (void*)fs;
+}
+
+/* Bind fragment shader state. */
+static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader;
+
+    if (!fs->translated) {
+        if (r300_screen(r300->context.screen)->caps->is_r500) {
+            r500_translate_shader(r300, fs);
+        } else {
+            r300_translate_shader(r300, fs);
+        }
+    }
+
+    r300->fs = fs;
+
+    r300->dirty_state |= R300_NEW_FRAGMENT_SHADER;
+}
+
+/* Delete fragment shader state. */
+static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
+{
+    FREE(shader);
+}
+
+static void r300_set_polygon_stipple(struct pipe_context* pipe,
+                                     const struct pipe_poly_stipple* state)
+{
+    /* XXX */
+}
+
+static INLINE int pack_float_16_6x(float f) {
+    return ((int)(f * 6.0) & 0xffff);
+}
+
+/* Create a new rasterizer state based on the CSO rasterizer state.
+ *
+ * This is a very large chunk of state, and covers most of the graphics
+ * backend (GB), geometry assembly (GA), and setup unit (SU) blocks.
+ *
+ * In a not entirely unironic sidenote, this state has nearly nothing to do
+ * with the actual block on the Radeon called the rasterizer (RS). */
+static void* r300_create_rs_state(struct pipe_context* pipe,
+                                  const struct pipe_rasterizer_state* state)
+{
+    struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
+
+    /* XXX this is part of HW TCL */
+    /* XXX endian control */
+    rs->vap_control_status = R300_VAP_TCL_BYPASS;
+
+    rs->point_size = pack_float_16_6x(state->point_size) |
+        (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT);
+
+    rs->line_control = pack_float_16_6x(state->line_width) |
+        R300_GA_LINE_CNTL_END_TYPE_COMP;
+
+    /* Radeons don't think in "CW/CCW", they think in "front/back". */
+    if (state->front_winding == PIPE_WINDING_CW) {
+        rs->cull_mode = R300_FRONT_FACE_CW;
+
+        if (state->offset_cw) {
+            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
+        }
+        if (state->offset_ccw) {
+            rs->polygon_offset_enable |= R300_BACK_ENABLE;
+        }
+    } else {
+        rs->cull_mode = R300_FRONT_FACE_CCW;
+
+        if (state->offset_ccw) {
+            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
+        }
+        if (state->offset_cw) {
+            rs->polygon_offset_enable |= R300_BACK_ENABLE;
+        }
+    }
+    if (state->front_winding & state->cull_mode) {
+        rs->cull_mode |= R300_CULL_FRONT;
+    }
+    if (~(state->front_winding) & state->cull_mode) {
+        rs->cull_mode |= R300_CULL_BACK;
+    }
+
+    if (rs->polygon_offset_enable) {
+        rs->depth_offset_front = rs->depth_offset_back =
+                pack_float_32(state->offset_units);
+        rs->depth_scale_front = rs->depth_scale_back =
+                pack_float_32(state->offset_scale);
+    }
+
+    if (state->line_stipple_enable) {
+        rs->line_stipple_config =
+            R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE |
+            (pack_float_32((float)state->line_stipple_factor) &
+                R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK);
+        /* XXX this might need to be scaled up */
+        rs->line_stipple_value = state->line_stipple_pattern;
+    }
+
+    return (void*)rs;
+}
+
+/* Bind rasterizer state. */
+static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
+{
+    struct r300_context* r300 = r300_context(pipe);
+
+    r300->rs_state = (struct r300_rs_state*)state;
+    r300->dirty_state |= R300_NEW_RASTERIZER;
+}
+
+/* Free rasterizer state. */
+static void r300_delete_rs_state(struct pipe_context* pipe, void* state)
+{
+    FREE(state);
+}
+
+static uint32_t translate_wrap(int wrap) {
+    switch (wrap) {
+        case PIPE_TEX_WRAP_REPEAT:
+            return R300_TX_REPEAT;
+        case PIPE_TEX_WRAP_CLAMP:
+            return R300_TX_CLAMP;
+        case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+            return R300_TX_CLAMP_TO_EDGE;
+        case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+            return R300_TX_CLAMP_TO_BORDER;
+        case PIPE_TEX_WRAP_MIRROR_REPEAT:
+            return R300_TX_REPEAT | R300_TX_MIRRORED;
+        case PIPE_TEX_WRAP_MIRROR_CLAMP:
+            return R300_TX_CLAMP | R300_TX_MIRRORED;
+        case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
+            return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
+        case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+            return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
+        default:
+            debug_printf("r300: Unknown texture wrap %d", wrap);
+            return 0;
+    }
+}
+
+static uint32_t translate_tex_filters(int min, int mag, int mip) {
+    uint32_t retval = 0;
+    switch (min) {
+        case PIPE_TEX_FILTER_NEAREST:
+            retval |= R300_TX_MIN_FILTER_NEAREST;
+        case PIPE_TEX_FILTER_LINEAR:
+            retval |= R300_TX_MIN_FILTER_LINEAR;
+        case PIPE_TEX_FILTER_ANISO:
+            retval |= R300_TX_MIN_FILTER_ANISO;
+        default:
+            debug_printf("r300: Unknown texture filter %d", min);
+            break;
+    }
+    switch (mag) {
+        case PIPE_TEX_FILTER_NEAREST:
+            retval |= R300_TX_MAG_FILTER_NEAREST;
+        case PIPE_TEX_FILTER_LINEAR:
+            retval |= R300_TX_MAG_FILTER_LINEAR;
+        case PIPE_TEX_FILTER_ANISO:
+            retval |= R300_TX_MAG_FILTER_ANISO;
+        default:
+            debug_printf("r300: Unknown texture filter %d", mag);
+            break;
+    }
+    switch (mip) {
+        case PIPE_TEX_MIPFILTER_NONE:
+            retval |= R300_TX_MIN_FILTER_MIP_NONE;
+        case PIPE_TEX_MIPFILTER_NEAREST:
+            retval |= R300_TX_MIN_FILTER_MIP_NEAREST;
+        case PIPE_TEX_MIPFILTER_LINEAR:
+            retval |= R300_TX_MIN_FILTER_MIP_LINEAR;
+        default:
+            debug_printf("r300: Unknown texture filter %d", mip);
+            break;
+    }
+
+    return retval;
+}
+
+static uint32_t anisotropy(float max_aniso) {
+    if (max_aniso >= 16.0f) {
+        return R300_TX_MAX_ANISO_16_TO_1;
+    } else if (max_aniso >= 8.0f) {
+        return R300_TX_MAX_ANISO_8_TO_1;
+    } else if (max_aniso >= 4.0f) {
+        return R300_TX_MAX_ANISO_4_TO_1;
+    } else if (max_aniso >= 2.0f) {
+        return R300_TX_MAX_ANISO_2_TO_1;
+    } else {
+        return R300_TX_MAX_ANISO_1_TO_1;
+    }
+}
+
+static void*
+        r300_create_sampler_state(struct pipe_context* pipe,
+                                  const struct pipe_sampler_state* state)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
+    int lod_bias;
+
+    sampler->filter0 |=
+        (translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) |
+        (translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) |
+        (translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT);
+
+    sampler->filter0 |= translate_tex_filters(state->min_img_filter,
+                                              state->mag_img_filter,
+                                              state->min_mip_filter);
+
+    lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1);
+
+    sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT;
+
+    sampler->filter1 |= anisotropy(state->max_anisotropy);
+
+    util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM,
+                    &sampler->border_color);
+
+    /* R500-specific fixups and optimizations */
+    if (r300_screen(r300->context.screen)->caps->is_r500) {
+        sampler->filter1 |= R500_BORDER_FIX;
+    }
+
+    return (void*)sampler;
+}
+
+static void r300_bind_sampler_states(struct pipe_context* pipe,
+                                     unsigned count,
+                                     void** states)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    int i;
+
+    if (count > 8) {
+        return;
+    }
+
+    for (i = 0; i < count; i++) {
+        if (r300->sampler_states[i] != states[i]) {
+            r300->sampler_states[i] = (struct r300_sampler_state*)states[i];
+            r300->dirty_state |= (R300_NEW_SAMPLER << i);
+        }
+    }
+
+    r300->sampler_count = count;
+}
+
+static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)
+{
+    FREE(state);
+}
+
+static void r300_set_sampler_textures(struct pipe_context* pipe,
+                                      unsigned count,
+                                      struct pipe_texture** texture)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    int i;
+
+    /* XXX magic num */
+    if (count > 8) {
+        return;
+    }
+
+    for (i = 0; i < count; i++) {
+        if (r300->textures[i] != (struct r300_texture*)texture[i]) {
+            pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
+                texture[i]);
+            r300->dirty_state |= (R300_NEW_TEXTURE << i);
+        }
+    }
+
+    for (i = count; i < 8; i++) {
+        if (r300->textures[i]) {
+            pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
+                NULL);
+            r300->dirty_state |= (R300_NEW_TEXTURE << i);
+        }
+    }
+
+    r300->texture_count = count;
+}
+
+static void r300_set_scissor_state(struct pipe_context* pipe,
+                                   const struct pipe_scissor_state* state)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    draw_flush(r300->draw);
+
+    uint32_t left, top, right, bottom;
+
+    /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in
+     * both directions for all values, and can only be 13 bits wide. Why?
+     * We may never know. */
+    left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff;
+    top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff;
+    right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff;
+    bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff;
+
+    r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) |
+            (top << R300_SCISSORS_Y_SHIFT);
+    r300->scissor_state->scissor_bottom_right =
+        (right << R300_SCISSORS_X_SHIFT) | (bottom << R300_SCISSORS_Y_SHIFT);
+
+    r300->dirty_state |= R300_NEW_SCISSOR;
+}
+
+static void r300_set_viewport_state(struct pipe_context* pipe,
+                                    const struct pipe_viewport_state* state)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    /* XXX handing this off to Draw for now */
+    draw_set_viewport_state(r300->draw, state);
+}
+
+static void r300_set_vertex_buffers(struct pipe_context* pipe,
+                                    unsigned count,
+                                    const struct pipe_vertex_buffer* buffers)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    /* XXX Draw */
+    draw_flush(r300->draw);
+    draw_set_vertex_buffers(r300->draw, count, buffers);
+}
+
+static void r300_set_vertex_elements(struct pipe_context* pipe,
+                                    unsigned count,
+                                    const struct pipe_vertex_element* elements)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    /* XXX Draw */
+    draw_flush(r300->draw);
+    draw_set_vertex_elements(r300->draw, count, elements);
+}
+
+static void* r300_create_vs_state(struct pipe_context* pipe,
+                                  const struct pipe_shader_state* state)
+{
+    struct r300_context* context = r300_context(pipe);
+    /* XXX handing this off to Draw for now */
+    return draw_create_vertex_shader(context->draw, state);
+}
+
+static void r300_bind_vs_state(struct pipe_context* pipe, void* state) {
+    struct r300_context* context = r300_context(pipe);
+    /* XXX handing this off to Draw for now */
+    draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
+}
+
+static void r300_delete_vs_state(struct pipe_context* pipe, void* state)
+{
+    struct r300_context* context = r300_context(pipe);
+    /* XXX handing this off to Draw for now */
+    draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
+}
+
+void r300_init_state_functions(struct r300_context* r300)
+{
+    r300->context.create_blend_state = r300_create_blend_state;
+    r300->context.bind_blend_state = r300_bind_blend_state;
+    r300->context.delete_blend_state = r300_delete_blend_state;
+
+    r300->context.set_blend_color = r300_set_blend_color;
+
+    r300->context.set_clip_state = r300_set_clip_state;
+
+    r300->context.set_constant_buffer = r300_set_constant_buffer;
+
+    r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state;
+    r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state;
+    r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state;
+
+    r300->context.set_edgeflags = r300_set_edgeflags;
+
+    r300->context.set_framebuffer_state = r300_set_framebuffer_state;
+
+    r300->context.create_fs_state = r300_create_fs_state;
+    r300->context.bind_fs_state = r300_bind_fs_state;
+    r300->context.delete_fs_state = r300_delete_fs_state;
+
+    r300->context.set_polygon_stipple = r300_set_polygon_stipple;
+
+    r300->context.create_rasterizer_state = r300_create_rs_state;
+    r300->context.bind_rasterizer_state = r300_bind_rs_state;
+    r300->context.delete_rasterizer_state = r300_delete_rs_state;
+
+    r300->context.create_sampler_state = r300_create_sampler_state;
+    r300->context.bind_sampler_states = r300_bind_sampler_states;
+    r300->context.delete_sampler_state = r300_delete_sampler_state;
+
+    r300->context.set_sampler_textures = r300_set_sampler_textures;
+
+    r300->context.set_scissor_state = r300_set_scissor_state;
+
+    r300->context.set_viewport_state = r300_set_viewport_state;
+
+    r300->context.set_vertex_buffers = r300_set_vertex_buffers;
+    r300->context.set_vertex_elements = r300_set_vertex_elements;
+
+    r300->context.create_vs_state = r300_create_vs_state;
+    r300->context.bind_vs_state = r300_bind_vs_state;
+    r300->context.delete_vs_state = r300_delete_vs_state;
+}
diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c
new file mode 100644 (file)
index 0000000..e871721
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "r300_state_shader.h"
+
+void r300_translate_shader(struct r300_context* r300,
+                           struct r300_fragment_shader* fs)
+{
+}
+
+void r500_translate_shader(struct r300_context* r300,
+                           struct r500_fragment_shader* fs)
+{
+}
diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h
new file mode 100644 (file)
index 0000000..a20bd42
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 R300_STATE_SHADER_H
+#define R300_STATE_SHADER_H
+
+#include "r300_context.h"
+#include "r300_screen.h"
+
+void r300_translate_shader(struct r300_context* r300,
+                           struct r300_fragment_shader* fs);
+
+void r500_translate_shader(struct r300_context* r300,
+                           struct r500_fragment_shader* fs);
+
+#endif /* R300_STATE_SHADER_H */
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c
new file mode 100644 (file)
index 0000000..1ed4a4e
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "r300_surface.h"
+
+/* Provides pipe_context's "surface_fill". Commonly used for clearing
+ * buffers. */
+static void r300_surface_fill(struct pipe_context* pipe,
+                              struct pipe_surface* dest,
+                              unsigned x, unsigned y,
+                              unsigned w, unsigned h,
+                              unsigned color)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    CS_LOCALS(r300);
+    struct r300_capabilities* caps = ((struct r300_screen*)pipe->screen)->caps;
+    int i;
+    float r, g, b, a;
+    r = (float)((color >> 16) & 0xff) / 255.0f;
+    g = (float)((color >>  8) & 0xff) / 255.0f;
+    b = (float)((color >>  0) & 0xff) / 255.0f;
+    debug_printf("r300: Filling surface %p at (%d,%d),"
+        " dimensions %dx%d (stride %d), color 0x%x\n",
+        dest, x, y, w, h, dest->stride, color);
+
+    /* Fallback? */
+    if (0) {
+        debug_printf("r300: Falling back on surface clear...");
+        void* map = pipe->screen->surface_map(pipe->screen, dest,
+            PIPE_BUFFER_USAGE_CPU_WRITE);
+        pipe_fill_rect(map, &dest->block, &dest->stride, x, y, w, h, color);
+        pipe->screen->surface_unmap(pipe->screen, dest);
+        return;
+    }
+
+BEGIN_CS((caps->is_r500) ? 309 : 280);
+R300_PACIFY;
+OUT_CS_REG(R300_TX_INVALTAGS, 0x0);
+R300_PACIFY;
+/* Flush PVS. */
+OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
+
+OUT_CS_REG(R300_SE_VTE_CNTL, R300_VPORT_X_SCALE_ENA |
+    R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
+    R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
+    R300_VPORT_Z_OFFSET_ENA | R300_VTX_W0_FMT);
+/* Vertex size. */
+OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8);
+/* Max and min vertex index clamp. */
+OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, 0xFFFFFF);
+OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0x0);
+/* XXX endian */
+OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VC_NO_SWAP);
+OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, 0x0);
+/* XXX magic number not in r300_reg */
+OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0xAAAAAAAA);
+OUT_CS_REG(R300_VAP_CLIP_CNTL, 0x0);
+OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
+OUT_CS_32F(1.0);
+OUT_CS_32F(1.0);
+OUT_CS_32F(1.0);
+OUT_CS_32F(1.0);
+/* XXX is this too long? */
+OUT_CS_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xFFFF);
+OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
+    R300_GB_LINE_STUFF_ENABLE | R300_GB_TRIANGLE_STUFF_ENABLE);
+/* XXX more magic numbers */
+OUT_CS_REG(R300_GB_MSPOS0, 0x66666666);
+OUT_CS_REG(R300_GB_MSPOS1, 0x66666666);
+/* XXX why doesn't classic Mesa write the number of pipes, too? */
+OUT_CS_REG(R300_GB_TILE_CONFIG, R300_GB_TILE_ENABLE | R300_GB_TILE_SIZE_16);
+OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W);
+OUT_CS_REG(R300_GB_AA_CONFIG, 0x0);
+/* XXX point tex stuffing */
+OUT_CS_REG_SEQ(R300_GA_POINT_S0, 1);
+OUT_CS_32F(0.0);
+OUT_CS_REG_SEQ(R300_GA_POINT_S1, 1);
+OUT_CS_32F(1.0);
+OUT_CS_REG(R300_GA_TRIANGLE_STIPPLE, 0x5 |
+    (0x5 << R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT));
+/* XXX should this be related to the actual point size? */
+OUT_CS_REG(R300_GA_POINT_MINMAX, 0x6 |
+    (0x1800 << R300_GA_POINT_MINMAX_MAX_SHIFT));
+/* XXX this big chunk should be refactored into rs_state */
+OUT_CS_REG(R300_GA_LINE_CNTL, 0x00030006);
+OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, 0x3BAAAAAB);
+OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, 0x00000000);
+OUT_CS_REG(R300_GA_LINE_S0, 0x00000000);
+OUT_CS_REG(R300_GA_LINE_S1, 0x3F800000);
+OUT_CS_REG(R300_GA_ENHANCE, 0x00000002);
+OUT_CS_REG(R300_GA_COLOR_CONTROL, 0x0003AAAA);
+OUT_CS_REG(R300_GA_SOLID_RG, 0x00000000);
+OUT_CS_REG(R300_GA_SOLID_BA, 0x00000000);
+OUT_CS_REG(R300_GA_POLY_MODE, 0x00000000);
+OUT_CS_REG(R300_GA_ROUND_MODE, 0x00000001);
+OUT_CS_REG(R300_GA_OFFSET, 0x00000000);
+OUT_CS_REG(R300_GA_FOG_SCALE, 0x3DBF1412);
+OUT_CS_REG(R300_GA_FOG_OFFSET, 0x00000000);
+OUT_CS_REG(R300_SU_TEX_WRAP, 0x00000000);
+OUT_CS_REG(R300_SU_POLY_OFFSET_FRONT_SCALE, 0x00000000);
+OUT_CS_REG(R300_SU_POLY_OFFSET_FRONT_OFFSET, 0x00000000);
+OUT_CS_REG(R300_SU_POLY_OFFSET_BACK_SCALE, 0x00000000);
+OUT_CS_REG(R300_SU_POLY_OFFSET_BACK_OFFSET, 0x00000000);
+OUT_CS_REG(R300_SU_POLY_OFFSET_ENABLE, 0x00000000);
+OUT_CS_REG(R300_SU_CULL_MODE, 0x00000000);
+OUT_CS_REG(R300_SU_DEPTH_SCALE, 0x4B7FFFFF);
+OUT_CS_REG(R300_SU_DEPTH_OFFSET, 0x00000000);
+OUT_CS_REG(R300_SC_HYPERZ, 0x0000001C);
+OUT_CS_REG(R300_SC_EDGERULE, 0x2DA49525);
+OUT_CS_REG(R300_SC_SCREENDOOR, 0x00FFFFFF);
+OUT_CS_REG(R300_FG_FOG_BLEND, 0x00000002);
+OUT_CS_REG(R300_FG_FOG_COLOR_R, 0x00000000);
+OUT_CS_REG(R300_FG_FOG_COLOR_G, 0x00000000);
+OUT_CS_REG(R300_FG_FOG_COLOR_B, 0x00000000);
+OUT_CS_REG(R300_FG_DEPTH_SRC, 0x00000000);
+OUT_CS_REG(R300_FG_DEPTH_SRC, 0x00000000);
+OUT_CS_REG(R300_RB3D_CCTL, 0x00000000);
+OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0x0000000F);
+
+/* XXX: Oh the wonderful unknown */
+OUT_CS_REG_SEQ(0x4E54, 8);
+for (i = 0; i < 8; i++)
+    OUT_CS(0x00000000);
+OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0x00000000);
+OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x00000000);
+OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFFFFFFFF);
+OUT_CS_REG(R300_ZB_FORMAT, 0x00000002);
+OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, 0x00000003);
+OUT_CS_REG(R300_ZB_BW_CNTL, 0x00000000);
+OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000);
+OUT_CS_REG(0x4F30, 0x00000000);
+OUT_CS_REG(0x4F34, 0x00000000);
+OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000);
+OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000);
+R300_PACIFY;
+OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, 0x21030003);
+OUT_CS_REG(R300_FG_FOG_BLEND, 0x00000000);
+OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, 0xF688F688);
+OUT_CS_REG(R300_VAP_VTX_STATE_CNTL, 0x1);
+OUT_CS_REG(R300_VAP_VSM_VTX_ASSM, 0x405);
+OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F);
+OUT_CS_REG(R300_VAP_VTX_SIZE, 0x00000008);
+OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0xAAAAAAAA);
+OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, 0x00000003);
+OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x00000000);
+OUT_CS_REG(R300_TX_ENABLE, 0x0);
+/* XXX viewport setup */
+OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
+OUT_CS_32F(1.0);
+OUT_CS_32F((float)x);
+OUT_CS_32F(1.0);
+OUT_CS_32F((float)y);
+OUT_CS_32F(1.0);
+OUT_CS_32F(0.0);
+
+OUT_CS_REG(R300_VAP_CLIP_CNTL, 0x0001C000);
+OUT_CS_REG(R300_GA_POINT_SIZE, ((h * 6) & R300_POINTSIZE_Y_MASK) |
+    ((w * 6) << R300_POINTSIZE_X_SHIFT));
+
+/* XXX RS block and fp setup */
+if (caps->is_r500) {
+    OUT_CS_REG_SEQ(R500_RS_IP_0, 8);
+    for (i = 0; i < 8; i++) {
+        /* I like the operator macros more than the shift macros... */
+        OUT_CS((R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
+            (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) |
+            (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
+            (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT));
+    }
+    /* XXX */
+    OUT_CS_REG_SEQ(R300_RS_COUNT, 2);
+    OUT_CS((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN);
+    OUT_CS(0x0);
+    OUT_CS_REG(R500_RS_INST_0, R500_RS_INST_COL_CN_WRITE);
+
+    OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
+    OUT_CS_REG(R500_US_PIXSIZE, 0x00000000);
+    OUT_CS_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) |
+        R500_US_CODE_END_ADDR(1));
+    OUT_CS_REG(R500_US_CODE_RANGE, R500_US_CODE_RANGE_ADDR(0) |
+        R500_US_CODE_RANGE_SIZE(1));
+    OUT_CS_REG(R500_US_CODE_OFFSET, R500_US_CODE_OFFSET_ADDR(0));
+    R300_PACIFY;
+    OUT_CS_REG(R500_GA_US_VECTOR_INDEX,
+        0 | R500_GA_US_VECTOR_INDEX_TYPE_INSTR);
+    OUT_CS_REG(R500_GA_US_VECTOR_DATA,
+        R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
+        R500_INST_RGB_OMASK_R | R500_INST_RGB_OMASK_G | R500_INST_RGB_OMASK_B |
+        R500_INST_ALPHA_OMASK | R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP);
+    OUT_CS_REG(R500_GA_US_VECTOR_DATA,
+        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
+        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST);
+    OUT_CS_REG(R500_GA_US_VECTOR_DATA,
+        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
+        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST);
+    OUT_CS_REG(R500_GA_US_VECTOR_DATA,
+        R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
+        R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
+        R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
+        R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B);
+    OUT_CS_REG(R500_GA_US_VECTOR_DATA,
+        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A);
+    OUT_CS_REG(R500_GA_US_VECTOR_DATA,
+        R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
+        R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
+        R500_ALU_RGBA_A_SWIZ_0);
+} else {
+    OUT_CS_REG_SEQ(R300_RS_IP_0, 8);
+    for (i = 0; i < 8; i++) {
+        OUT_CS(R300_RS_SEL_T(R300_RS_SEL_K0) |
+            R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1));
+    }
+    /* XXX */
+    OUT_CS_REG_SEQ(R300_RS_COUNT, 2);
+    OUT_CS((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN);
+    OUT_CS(1);
+    OUT_CS_REG(R300_RS_INST_0, R300_RS_INST_COL_CN_WRITE);
+
+    /* XXX magic numbers */
+    OUT_CS_REG(R300_US_CONFIG, 0);
+    OUT_CS_REG(R300_US_PIXSIZE, 2);
+    OUT_CS_REG(R300_US_CODE_OFFSET, 0x0);
+    OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0);
+    OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0);
+    OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0);
+    OUT_CS_REG(R300_US_CODE_ADDR_3, 0x400000);
+    OUT_CS_REG(R300_US_ALU_RGB_INST_0, 0x50A80);
+    OUT_CS_REG(R300_US_ALU_RGB_ADDR_0, 0x1C000000);
+    OUT_CS_REG(R300_US_ALU_ALPHA_INST_0, 0x40889);
+    OUT_CS_REG(R300_US_ALU_ALPHA_ADDR_0, 0x1000000);
+    OUT_CS_REG_SEQ(R300_US_OUT_FMT_0, 4);
+    OUT_CS(R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A);
+    OUT_CS(R300_US_OUT_FMT_UNUSED);
+    OUT_CS(R300_US_OUT_FMT_UNUSED);
+    OUT_CS(R300_US_OUT_FMT_UNUSED);
+    OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W0);
+}
+/* XXX these magic numbers should be explained when
+ * this becomes a cached state object */
+OUT_CS_REG(R300_VAP_CNTL, 0xA | (0x5 << R300_PVS_NUM_CNTLRS_SHIFT) |
+    (caps->num_vert_fpus << R300_PVS_NUM_FPUS_SHIFT));
+OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, 0x00100000);
+OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 0x00000000);
+OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, 0x00000001);
+R300_PACIFY;
+/* XXX translate these back into normal instructions */
+OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x1);
+OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0x0);
+OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xF00203);
+OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xD10001);
+OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x1248001);
+OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x0);
+OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xF02203);
+OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xD10021);
+OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x1248021);
+OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x0);
+R300_PACIFY;
+END_CS;
+
+r300_emit_blend_state(r300, &blend_clear_state);
+r300_emit_blend_color_state(r300, &blend_color_clear_state);
+r300_emit_dsa_state(r300, &dsa_clear_state);
+
+BEGIN_CS(36);
+R300_PACIFY;
+/* Flush colorbuffer and blend caches. */
+OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
+    R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D |
+    R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_SIGNAL);
+OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
+    R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
+    R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
+
+OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1);
+OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+/* XXX this should not be so rigid and it still doesn't work right */
+OUT_CS_REG(R300_RB3D_COLORPITCH0, (dest->stride >> 2) | R300_COLOR_FORMAT_ARGB8888);
+OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0x0000000F);
+/* XXX Packet3 */
+OUT_CS(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8));
+OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
+(1 << R300_PRIM_NUM_VERTICES_SHIFT));
+OUT_CS_32F(w / 2.0);
+OUT_CS_32F(h / 2.0);
+/* XXX this should be the depth value to clear to */
+OUT_CS_32F(1.0);
+OUT_CS_32F(1.0);
+OUT_CS_32F(r);
+OUT_CS_32F(g);
+OUT_CS_32F(b);
+OUT_CS_32F(1.0);
+
+/* XXX figure out why this is 0xA and not 0x2 */
+OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
+/* XXX OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
+    R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
+    R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); */
+R300_PACIFY;
+
+END_CS;
+FLUSH_CS;
+
+    r300->dirty_state = R300_NEW_KITCHEN_SINK;
+}
+
+void r300_init_surface_functions(struct r300_context* r300)
+{
+    r300->context.surface_fill = r300_surface_fill;
+}
diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h
new file mode 100644 (file)
index 0000000..e1d5311
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 R300_SURFACE_H
+#define R300_SURFACE_H
+
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
+
+#include "util/u_rect.h"
+
+#include "r300_context.h"
+#include "r300_cs.h"
+#include "r300_emit.h"
+
+const struct r300_blend_state blend_clear_state = {
+    .blend_control = 0x0,
+    .alpha_blend_control = 0x0,
+    .rop = 0x0,
+    .dither = 0x0,
+};
+
+const struct r300_blend_color_state blend_color_clear_state = {
+    .blend_color = 0x0,
+    .blend_color_red_alpha = 0x0,
+    .blend_color_green_blue = 0x0,
+};
+
+const struct r300_dsa_state dsa_clear_state = {
+    .alpha_function = 0x0,
+    .alpha_reference = 0x0,
+    .z_buffer_control = 0x0,
+    .z_stencil_control = 0x0,
+    .stencil_ref_mask = R300_STENCILWRITEMASK_MASK,
+    .z_buffer_top = R300_ZTOP_ENABLE,
+    .stencil_ref_bf = 0x0,
+};
+
+#endif /* R300_SURFACE_H */
diff --git a/src/gallium/drivers/r300/r300_swtcl_emit.c b/src/gallium/drivers/r300/r300_swtcl_emit.c
new file mode 100644 (file)
index 0000000..f6e98d2
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "draw/draw_pipe.h"
+#include "util/u_memory.h"
+
+#include "r300_cs.h"
+#include "r300_context.h"
+#include "r300_reg.h"
+
+/* r300_swtcl_emit: Primitive vertex emission using an immediate
+ * vertex buffer and no HW TCL. */
+
+struct swtcl_stage {
+    /* Parent class */
+    struct draw_stage draw;
+
+    struct r300_context* r300;
+};
+
+static INLINE struct swtcl_stage* swtcl_stage(struct draw_stage* draw) {
+    return (struct swtcl_stage*)draw;
+}
+
+static void r300_emit_vertex(struct r300_context* r300,
+                             const struct vertex_header* vertex)
+{
+    /* XXX */
+}
+
+static INLINE void r300_emit_prim(struct draw_stage* draw,
+                                  struct prim_header* prim,
+                                  unsigned hwprim,
+                                  unsigned count)
+{
+    struct r300_context* r300 = swtcl_stage(draw)->r300;
+    CS_LOCALS(r300);
+    int i;
+
+    r300_emit_dirty_state(r300);
+
+    /* XXX should be count * vtx size */
+    BEGIN_CS(2 + count + 6);
+    OUT_CS(CP_PACKET3(R200_3D_DRAW_IMMD_2, count));
+    OUT_CS(hwprim | R300_PRIM_WALK_RING |
+        (count << R300_PRIM_NUM_VERTICES_SHIFT));
+
+    for (i = 0; i < count; i++) {
+        r300_emit_vertex(r300, prim->v[i]);
+    }
+    R300_PACIFY;
+    END_CS;
+}
+
+/* Just as an aside...
+ *
+ * Radeons can do many more primitives:
+ * - Line strip
+ * - Triangle fan
+ * - Triangle strip
+ * - Line loop
+ * - Quads
+ * - Quad strip
+ * - Polygons
+ *
+ * The following were just the only ones in Draw. */
+
+static void r300_emit_point(struct draw_stage* draw, struct prim_header* prim)
+{
+    r300_emit_prim(draw, prim, R300_PRIM_TYPE_POINT, 1);
+}
+
+static void r300_emit_line(struct draw_stage* draw, struct prim_header* prim)
+{
+    r300_emit_prim(draw, prim, R300_PRIM_TYPE_LINE, 2);
+}
+
+static void r300_emit_tri(struct draw_stage* draw, struct prim_header* prim)
+{
+    r300_emit_prim(draw, prim, R300_PRIM_TYPE_TRI_LIST, 3);
+}
+
+static void r300_swtcl_flush(struct draw_stage* draw, unsigned flags)
+{
+}
+
+static void r300_reset_stipple(struct draw_stage* draw)
+{
+    /* XXX */
+}
+
+static void r300_swtcl_destroy(struct draw_stage* draw)
+{
+    FREE(draw);
+}
+
+struct draw_stage* r300_draw_swtcl_stage(struct r300_context* r300)
+{
+    struct swtcl_stage* swtcl = CALLOC_STRUCT(swtcl_stage);
+
+    swtcl->r300 = r300;
+    swtcl->draw.point = r300_emit_point;
+    swtcl->draw.line = r300_emit_line;
+    swtcl->draw.tri = r300_emit_tri;
+    swtcl->draw.flush = r300_swtcl_flush;
+    swtcl->draw.reset_stipple_counter = r300_reset_stipple;
+    swtcl->draw.destroy = r300_swtcl_destroy;
+
+    return &swtcl->draw;
+}
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
new file mode 100644 (file)
index 0000000..f9ad14f
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "r300_texture.h"
+
+static int minify(int i)
+{
+    return MAX2(1, i >> 1);
+}
+
+static void r300_setup_miptree(struct r300_texture* tex)
+{
+    struct pipe_texture* base = &tex->tex;
+    int stride, size, offset;
+
+    for (int i = 0; i <= base->last_level; i++) {
+        if (i > 0) {
+            base->width[i] = minify(base->width[i-1]);
+            base->height[i] = minify(base->height[i-1]);
+            base->depth[i] = minify(base->depth[i-1]);
+        }
+
+        base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]);
+        base->nblocksy[i] = pf_get_nblocksy(&base->block, base->width[i]);
+
+        /* Radeons enjoy things in multiples of 32. */
+        /* XXX NPOT -> 64, not 32 */
+        stride = (base->nblocksx[i] * base->block.size + 63) & ~63;
+        size = stride * base->nblocksy[i] * base->depth[i];
+
+        /* XXX 64 for NPOT */
+        tex->offset[i] = (tex->size + 63) & ~63;
+        tex->size = tex->offset[i] + size;
+    }
+}
+
+/* Create a new texture. */
+static struct pipe_texture*
+    r300_texture_create(struct pipe_screen* screen,
+                        const struct pipe_texture* template)
+{
+    /* XXX struct r300_screen* r300screen = r300_screen(screen); */
+
+    struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
+
+    if (!tex) {
+        return NULL;
+    }
+
+    tex->tex = *template;
+    tex->tex.refcount = 1;
+    tex->tex.screen = screen;
+
+    r300_setup_miptree(tex);
+
+    tex->buffer = screen->buffer_create(screen, 63,
+                                        PIPE_BUFFER_USAGE_PIXEL,
+                                        tex->size);
+
+    if (!tex->buffer) {
+        FREE(tex);
+        return NULL;
+    }
+
+    return (struct pipe_texture*)tex;
+}
+
+static void r300_texture_release(struct pipe_screen* screen,
+                                 struct pipe_texture** texture)
+{
+    if (!*texture) {
+        return;
+    }
+
+    (*texture)->refcount--;
+
+    if ((*texture)->refcount <= 0) {
+        struct r300_texture* tex = (struct r300_texture*)*texture;
+
+        pipe_buffer_reference(screen, &tex->buffer, NULL);
+
+        FREE(tex);
+    }
+
+    *texture = NULL;
+}
+
+static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
+                                                 struct pipe_texture* texture,
+                                                 unsigned face,
+                                                 unsigned level,
+                                                 unsigned zslice,
+                                                 unsigned flags)
+{
+    struct r300_texture* tex = (struct r300_texture*)texture;
+    struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface);
+    unsigned offset;
+
+    /* XXX this is certainly dependent on tex target */
+    offset = tex->offset[level];
+
+    if (surface) {
+        surface->refcount = 1;
+        pipe_texture_reference(&surface->texture, texture);
+        pipe_buffer_reference(screen, &surface->buffer, tex->buffer);
+        surface->format = texture->format;
+        surface->width = texture->width[level];
+        surface->height = texture->height[level];
+        surface->block = texture->block;
+        surface->nblocksx = texture->nblocksx[level];
+        surface->nblocksy = texture->nblocksy[level];
+        /* XXX save the actual stride instead plz kthnxbai */
+        surface->stride =
+            (texture->nblocksx[level] * texture->block.size + 63) & ~63;
+        surface->offset = offset;
+        surface->usage = flags;
+        surface->status = PIPE_SURFACE_STATUS_DEFINED;
+    }
+
+    return surface;
+}
+
+static void r300_tex_surface_release(struct pipe_screen* screen,
+                                     struct pipe_surface** surface)
+{
+    struct pipe_surface* s = *surface;
+
+    s->refcount--;
+
+    if (s->refcount <= 0) {
+        pipe_texture_reference(&s->texture, NULL);
+        pipe_buffer_reference(screen, &s->buffer, NULL);
+        FREE(s);
+    }
+
+    *surface = NULL;
+}
+
+static struct pipe_texture*
+    r300_texture_blanket(struct pipe_screen* screen,
+                         const struct pipe_texture* base,
+                         const unsigned* stride,
+                         struct pipe_buffer* buffer)
+{
+    struct r300_texture* tex;
+
+    if (base->target != PIPE_TEXTURE_2D ||
+        base->last_level != 0 ||
+        base->depth[0] != 1) {
+        return NULL;
+    }
+
+    tex = CALLOC_STRUCT(r300_texture);
+    if (!tex) {
+        return NULL;
+    }
+
+    tex->tex = *base;
+    tex->tex.refcount = 1;
+    tex->tex.screen = screen;
+
+    /* XXX tex->stride = *stride; */
+
+    pipe_buffer_reference(screen, &tex->buffer, buffer);
+
+    return (struct pipe_texture*)tex;
+}
+
+void r300_init_screen_texture_functions(struct pipe_screen* screen)
+{
+    screen->texture_create = r300_texture_create;
+    screen->texture_release = r300_texture_release;
+    screen->get_tex_surface = r300_get_tex_surface;
+    screen->tex_surface_release = r300_tex_surface_release;
+    screen->texture_blanket = r300_texture_blanket;
+}
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
new file mode 100644 (file)
index 0000000..7964229
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 R300_TEXTURE_H
+#define R300_TEXTURE_H
+
+#include "pipe/p_screen.h"
+
+#include "util/u_math.h"
+
+#include "r300_context.h"
+
+void r300_init_screen_texture_functions(struct pipe_screen* screen);
+
+#endif /* R300_TEXTURE_H */
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
new file mode 100644 (file)
index 0000000..5a3a212
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 R300_WINSYS_H
+#define R300_WINSYS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The public interface header for the r300 pipe driver.
+ * Any winsys hosting this pipe needs to implement r300_winsys and then
+ * call r300_create_context to start things. */
+
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+
+struct radeon_cs;
+
+struct r300_winsys {
+
+    /* PCI ID */
+    uint32_t pci_id;
+
+    /* GB pipe count */
+    uint32_t gb_pipes;
+
+    /* CS object. This is very much like Intel's batchbuffer.
+     * Fill it full of dwords and relocs and then submit.
+     * Repeat as needed. */
+    /* Note: Unlike Mesa's version of this, we don't keep a copy of the CSM
+     * that was used to create this CS. Is this a good idea? */
+    /* Note: The pipe driver doesn't know how to use this. This is purely
+     * for the winsys. */
+    struct radeon_cs* cs;
+
+    /* Check to see if there's room for commands. */
+    boolean (*check_cs)(struct radeon_cs* cs, int size);
+
+    /* Start a command emit. */
+    void (*begin_cs)(struct radeon_cs* cs,
+           int size,
+           const char* file,
+           const char* function,
+           int line);
+
+    /* Write a dword to the command buffer. */
+    void (*write_cs_dword)(struct radeon_cs* cs, uint32_t dword);
+
+    /* Write a relocated dword to the command buffer. */
+    void (*write_cs_reloc)(struct radeon_cs* cs,
+           struct pipe_buffer* bo,
+           uint32_t rd,
+           uint32_t wd,
+           uint32_t flags);
+
+    /* Finish a command emit. */
+    void (*end_cs)(struct radeon_cs* cs,
+           const char* file,
+           const char* function,
+           int line);
+
+    /* Flush the CS. */
+    void (*flush_cs)(struct radeon_cs* cs);
+};
+
+struct pipe_context* r300_create_context(struct pipe_screen* screen,
+                                         struct pipe_winsys* winsys,
+                                         struct r300_winsys* r300_winsys);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* R300_WINSYS_H */
diff --git a/src/gallium/winsys/drm/radeon/Makefile b/src/gallium/winsys/drm/radeon/Makefile
new file mode 100644 (file)
index 0000000..dca1e32
--- /dev/null
@@ -0,0 +1,32 @@
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = radeon_dri.so
+
+MINIGLX_SOURCES =
+
+PIPE_DRIVERS = \
+       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+       $(TOP)/src/gallium/drivers/r300/libr300.a
+
+DRIVER_SOURCES = \
+       radeon_buffer.c \
+       radeon_context.c \
+       radeon_r300.c \
+       radeon_screen.c \
+       radeon_winsys_softpipe.c
+
+C_SOURCES = \
+       $(COMMON_GALLIUM_SOURCES) \
+       $(DRIVER_SOURCES)
+
+ASM_SOURCES = 
+
+DRIVER_DEFINES = -I../../../drivers/r300
+
+include ../Makefile.template
+
+DRI_LIB_DEPS += -ldrm_radeon
+
+symlinks:
diff --git a/src/gallium/winsys/drm/radeon/SConscript b/src/gallium/winsys/drm/radeon/SConscript
new file mode 100644 (file)
index 0000000..2435211
--- /dev/null
@@ -0,0 +1,29 @@
+Import('*')
+
+if 'mesa' in env['statetrackers']:
+
+       env = drienv.Clone()
+
+       DRIVER_SOURCES = [
+               'radeon_buffer.c',
+               'radeon_context.c',
+               'radeon_screen.c',
+               'radeon_winsys_softpipe.c',
+       ]
+
+       sources = \
+               COMMON_GALLIUM_SOURCES + \
+               DRIVER_SOURCES
+
+       drivers = [
+               softpipe,
+               r300
+       ]
+
+       # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+       env.SharedLibrary(
+               target ='radeon_dri.so',
+               source = sources,
+               LIBS = drivers + mesa + auxiliaries + env['LIBS'],
+       )
+
diff --git a/src/gallium/winsys/drm/radeon/radeon_buffer.c b/src/gallium/winsys/drm/radeon/radeon_buffer.c
new file mode 100644 (file)
index 0000000..259a505
--- /dev/null
@@ -0,0 +1,239 @@
+/* 
+ * Copyright © 2008 Jérôme Glisse
+ * 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:
+ *      Jérôme Glisse <glisse@freedesktop.org>
+ */
+#include <stdio.h>
+#include "dri_util.h"
+#include "state_tracker/st_public.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+#include "radeon_buffer.h"
+#include "radeon_screen.h"
+#include "radeon_context.h"
+#include "radeon_bo.h"
+#include "radeon_drm.h"
+
+static const char *radeon_get_name(struct pipe_winsys *ws)
+{
+    return "RADEON/DRI2";
+}
+
+static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
+                                             unsigned alignment,
+                                             unsigned usage,
+                                             unsigned size)
+{
+    struct radeon_pipe_winsys *radeon_ws = (struct radeon_pipe_winsys *)ws;
+    struct radeon_pipe_buffer *radeon_buffer;
+    uint32_t domain;
+
+    radeon_buffer = calloc(1, sizeof(*radeon_buffer));
+    if (radeon_buffer == NULL) {
+        return NULL;
+    }
+    radeon_buffer->base.refcount = 1;
+    radeon_buffer->base.alignment = alignment;
+    radeon_buffer->base.usage = usage;
+    radeon_buffer->base.size = size;
+
+    domain = 0;
+
+    if (usage & PIPE_BUFFER_USAGE_PIXEL) {
+        domain |= RADEON_GEM_DOMAIN_VRAM;
+    }
+    if (usage & PIPE_BUFFER_USAGE_VERTEX) {
+        domain |= RADEON_GEM_DOMAIN_GTT;
+    }
+
+    if (usage & PIPE_BUFFER_USAGE_INDEX) {
+        domain |= RADEON_GEM_DOMAIN_GTT;
+    }
+    radeon_buffer->bo = radeon_bo_open(radeon_ws->radeon_screen->bom, 0,
+                                    size, alignment, domain, 0);
+    if (radeon_buffer->bo == NULL) {
+        free(radeon_buffer);
+    }
+    return &radeon_buffer->base;
+}
+
+static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws,
+                                                  void *ptr,
+                                                  unsigned bytes)
+{
+    struct radeon_pipe_buffer *radeon_buffer;
+
+    radeon_buffer = (struct radeon_pipe_buffer*)radeon_buffer_create(ws, 0, 0, bytes);
+    if (radeon_buffer == NULL) {
+        return NULL;
+    }
+    radeon_bo_map(radeon_buffer->bo, 1);
+    memcpy(radeon_buffer->bo->ptr, ptr, bytes);
+    radeon_bo_unmap(radeon_buffer->bo);
+    return &radeon_buffer->base;
+}
+
+static void radeon_buffer_del(struct pipe_winsys *ws, struct pipe_buffer *buffer)
+{
+    struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer;
+
+    radeon_bo_unref(radeon_buffer->bo);
+    free(radeon_buffer);
+}
+
+static void *radeon_buffer_map(struct pipe_winsys *ws,
+                            struct pipe_buffer *buffer,
+                            unsigned flags)
+{
+    struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer;
+    int write = 0;
+
+    if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
+        write = 1;
+    }
+    if (radeon_bo_map(radeon_buffer->bo, write))
+        return NULL;
+    return radeon_buffer->bo->ptr;
+}
+
+static void radeon_buffer_unmap(struct pipe_winsys *ws, struct pipe_buffer *buffer)
+{
+    struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer;
+
+    radeon_bo_unmap(radeon_buffer->bo);
+}
+
+static void radeon_fence_reference(struct pipe_winsys *ws,
+                                struct pipe_fence_handle **ptr,
+                                struct pipe_fence_handle *pfence)
+{
+}
+
+static int radeon_fence_signalled(struct pipe_winsys *ws,
+                               struct pipe_fence_handle *pfence,
+                               unsigned flag)
+{
+    return 1;
+}
+
+static int radeon_fence_finish(struct pipe_winsys *ws,
+                            struct pipe_fence_handle *pfence,
+                            unsigned flag)
+{
+    return 0;
+}
+
+static void radeon_flush_frontbuffer(struct pipe_winsys *pipe_winsys,
+                                  struct pipe_surface *pipe_surface,
+                                  void *context_private)
+{
+    /* TODO: call dri2CopyRegion */
+}
+
+struct pipe_winsys *radeon_pipe_winsys(struct radeon_screen *radeon_screen)
+{
+    struct radeon_pipe_winsys *radeon_ws;
+
+    radeon_ws = calloc(1, sizeof(struct radeon_pipe_winsys));
+    if (radeon_ws == NULL) {
+        return NULL;
+    }
+    radeon_ws->radeon_screen = radeon_screen;
+
+    radeon_ws->winsys.flush_frontbuffer = radeon_flush_frontbuffer;
+
+    radeon_ws->winsys.buffer_create = radeon_buffer_create;
+    radeon_ws->winsys.buffer_destroy = radeon_buffer_del;
+    radeon_ws->winsys.user_buffer_create = radeon_buffer_user_create;
+    radeon_ws->winsys.buffer_map = radeon_buffer_map;
+    radeon_ws->winsys.buffer_unmap = radeon_buffer_unmap;
+
+    radeon_ws->winsys.fence_reference = radeon_fence_reference;
+    radeon_ws->winsys.fence_signalled = radeon_fence_signalled;
+    radeon_ws->winsys.fence_finish = radeon_fence_finish;
+
+    radeon_ws->winsys.get_name = radeon_get_name;
+
+    return &radeon_ws->winsys;
+}
+
+static struct pipe_buffer *radeon_buffer_from_handle(struct radeon_screen *radeon_screen,
+                                                  uint32_t handle)
+{
+    struct radeon_pipe_buffer *radeon_buffer;
+    struct radeon_bo *bo = NULL;
+
+    bo = radeon_bo_open(radeon_screen->bom, handle, 0, 0, 0, 0);
+    if (bo == NULL) {
+        return NULL;
+    }
+    radeon_buffer = calloc(1, sizeof(struct radeon_pipe_buffer));
+    if (radeon_buffer == NULL) {
+        radeon_bo_unref(bo);
+        return NULL;
+    }
+    radeon_buffer->base.refcount = 1;
+    radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL;
+    radeon_buffer->bo = bo;
+    return &radeon_buffer->base;
+}
+
+struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context,
+                                             uint32_t handle,
+                                             enum pipe_format format,
+                                             int w, int h, int pitch)
+{
+    struct pipe_screen *pipe_screen = radeon_context->pipe_screen;
+    struct pipe_winsys *pipe_winsys = radeon_context->pipe_winsys;
+    struct pipe_texture tmpl;
+    struct pipe_surface *ps;
+    struct pipe_texture *pt;
+    struct pipe_buffer *pb;
+
+    pb = radeon_buffer_from_handle(radeon_context->radeon_screen, handle);
+    if (pb == NULL) {
+        return NULL;
+    }
+    memset(&tmpl, 0, sizeof(tmpl));
+    tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+    tmpl.target = PIPE_TEXTURE_2D;
+    tmpl.width[0] = w;
+    tmpl.height[0] = h;
+    tmpl.depth[0] = 1;
+    tmpl.format = format;
+    pf_get_block(tmpl.format, &tmpl.block);
+    tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w);
+    tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h);
+
+    pt = pipe_screen->texture_blanket(pipe_screen, &tmpl, &pitch, pb);
+    if (pt == NULL) {
+        pipe_buffer_reference(pipe_screen, &pb, NULL);
+    }
+    ps = pipe_screen->get_tex_surface(pipe_screen, pt, 0, 0, 0,
+                                      PIPE_BUFFER_USAGE_GPU_WRITE);
+    return ps;
+}
diff --git a/src/gallium/winsys/drm/radeon/radeon_buffer.h b/src/gallium/winsys/drm/radeon/radeon_buffer.h
new file mode 100644 (file)
index 0000000..c626c20
--- /dev/null
@@ -0,0 +1,54 @@
+/* 
+ * Copyright © 2008 Jérôme Glisse
+ * 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:
+ *      Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef RADEON_BUFFER_H
+#define RADEON_BUFFER_H
+
+#include "pipe/internal/p_winsys_screen.h"
+#include "radeon_screen.h"
+#include "radeon_context.h"
+#include "radeon_bo.h"
+
+struct radeon_pipe_buffer {
+    struct pipe_buffer  base;
+    struct radeon_bo    *bo;
+};
+
+struct radeon_pipe_winsys {
+    struct pipe_winsys      winsys;
+    struct radeon_screen       *radeon_screen;
+};
+
+struct pipe_winsys *radeon_pipe_winsys(struct radeon_screen *radeon_screen);
+struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context,
+                                             uint32_t handle,
+                                             enum pipe_format format,
+                                             int w, int h, int pitch);
+
+#endif
diff --git a/src/gallium/winsys/drm/radeon/radeon_context.c b/src/gallium/winsys/drm/radeon/radeon_context.c
new file mode 100644 (file)
index 0000000..a9d1577
--- /dev/null
@@ -0,0 +1,306 @@
+/* 
+ * Copyright © 2008 Jérôme Glisse
+ * 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:
+ *      Jérôme Glisse <glisse@freedesktop.org>
+ */
+#include <stdio.h>
+#include "dri_util.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+#include "state_tracker/st_public.h"
+#include "state_tracker/st_context.h"
+#include "radeon_screen.h"
+#include "radeon_context.h"
+#include "radeon_buffer.h"
+#include "radeon_winsys_softpipe.h"
+
+#define need_GL_ARB_fragment_program
+#define need_GL_ARB_multisample
+#define need_GL_ARB_point_parameters
+#define need_GL_ARB_shader_objects
+#define need_GL_ARB_texture_compression
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_ARB_vertex_program
+#define need_GL_ARB_vertex_shader
+#define need_GL_EXT_blend_color
+#define need_GL_EXT_blend_equation_separate
+#define need_GL_EXT_blend_func_separate
+#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_cull_vertex
+#define need_GL_EXT_compiled_vertex_array
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_framebuffer_object
+#define need_GL_EXT_multi_draw_arrays
+#define need_GL_EXT_secondary_color
+#define need_GL_VERSION_2_0
+#define need_GL_VERSION_2_1
+#include "extension_helper.h"
+
+/**
+ * Extension strings exported by the radeon driver.
+ */
+const struct dri_extension radeon_card_extensions[] = {
+   {"GL_ARB_multitexture", NULL},
+   {"GL_ARB_texture_border_clamp", NULL},
+   {"GL_ARB_texture_rectangle", NULL},
+   {"GL_ARB_pixel_buffer_object", NULL},
+   {"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_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
+   {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
+   {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions},
+   {"GL_EXT_blend_color", GL_EXT_blend_color_functions},
+   {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
+   {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
+   {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
+   {"GL_EXT_blend_subtract", NULL},
+   {"GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions},
+   {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
+   {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
+   {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
+   {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
+   {"GL_EXT_packed_depth_stencil", NULL},
+   {"GL_EXT_pixel_buffer_object", NULL},
+   {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
+   {"GL_EXT_stencil_wrap", NULL},
+   {NULL, NULL}
+};
+
+static void radeon_update_renderbuffers(__DRIcontext *dri_context,
+                                     __DRIdrawable *dri_drawable)
+{
+    struct radeon_framebuffer *radeon_fb;
+    struct radeon_context *radeon_context;
+    unsigned attachments[10];
+    __DRIbuffer *buffers;
+    __DRIscreen *screen;
+    int i, count;
+
+    radeon_context = dri_context->driverPrivate;
+    screen = dri_drawable->driScreenPriv;
+    radeon_fb = dri_drawable->driverPrivate;
+    for (count = 0, i = 0; count < 6; count++) {
+        if (radeon_fb->attachments & (1 << count)) {
+            attachments[i++] = count;
+        }
+    }
+
+    buffers = (*screen->dri2.loader->getBuffers)(dri_drawable,
+                                                 &dri_drawable->w,
+                                                 &dri_drawable->h,
+                                                 attachments,
+                                                 i,
+                                                 &count,
+                                                 dri_drawable->loaderPrivate);
+    if (buffers == NULL) {
+        return;
+    }
+
+    /* set one cliprect to cover the whole dri_drawable */
+    dri_drawable->x = 0;
+    dri_drawable->y = 0;
+    dri_drawable->backX = 0;
+    dri_drawable->backY = 0;
+    dri_drawable->numClipRects = 1;
+    dri_drawable->pClipRects[0].x1 = 0;
+    dri_drawable->pClipRects[0].y1 = 0;
+    dri_drawable->pClipRects[0].x2 = dri_drawable->w;
+    dri_drawable->pClipRects[0].y2 = dri_drawable->h;
+    dri_drawable->numBackClipRects = 1;
+    dri_drawable->pBackClipRects[0].x1 = 0;
+    dri_drawable->pBackClipRects[0].y1 = 0;
+    dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
+    dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
+
+    for (i = 0; i < count; i++) {
+        struct pipe_surface *ps;
+        enum pipe_format format = 0;
+        int index = 0;
+
+        switch (buffers[i].attachment) {
+        case __DRI_BUFFER_FRONT_LEFT:
+            index = ST_SURFACE_FRONT_LEFT;
+            switch (buffers[i].cpp) {
+            case 4:
+                format = PIPE_FORMAT_A8R8G8B8_UNORM;
+                break;
+            case 2:
+                format = PIPE_FORMAT_R5G6B5_UNORM;
+                break;
+            default:
+                /* FIXME: error */
+                return;
+            }
+            break;
+        case __DRI_BUFFER_BACK_LEFT:
+            index = ST_SURFACE_BACK_LEFT;
+            switch (buffers[i].cpp) {
+            case 4:
+                format = PIPE_FORMAT_A8R8G8B8_UNORM;
+                break;
+            case 2:
+                format = PIPE_FORMAT_R5G6B5_UNORM;
+                break;
+            default:
+                /* FIXME: error */
+                return;
+            }
+            break;
+        case __DRI_BUFFER_STENCIL:
+        case __DRI_BUFFER_DEPTH:
+            index = ST_SURFACE_DEPTH;
+            switch (buffers[i].cpp) {
+            case 4:
+                format = PIPE_FORMAT_Z24S8_UNORM;
+                break;
+            case 2:
+                format = PIPE_FORMAT_Z16_UNORM;
+                break;
+            default:
+                /* FIXME: error */
+                return;
+            }
+            break;
+        case __DRI_BUFFER_ACCUM:
+        default:
+            fprintf(stderr,
+                    "unhandled buffer attach event, attacment type %d\n",
+                    buffers[i].attachment);
+            return;
+        }
+
+        ps = radeon_surface_from_handle(radeon_context,
+                                     buffers[i].name,
+                                     format,
+                                     dri_drawable->w,
+                                     dri_drawable->h,
+                                     buffers[i].pitch);
+        assert(ps);
+        st_set_framebuffer_surface(radeon_fb->st_framebuffer, index, ps);
+    }
+    st_resize_framebuffer(radeon_fb->st_framebuffer,
+                          dri_drawable->w,
+                          dri_drawable->h);
+}
+
+GLboolean radeon_context_create(const __GLcontextModes *visual,
+                             __DRIcontextPrivate *dri_context,
+                             void *shared_context)
+{
+    __DRIscreenPrivate *dri_screen;
+    struct radeon_context *radeon_context;
+    struct radeon_screen *radeon_screen;
+    struct pipe_context *pipe;
+    struct st_context *shared_st_context = NULL;
+
+    dri_context->driverPrivate = NULL;
+    radeon_context = calloc(1, sizeof(struct radeon_context));
+    if (radeon_context == NULL) {
+        return GL_FALSE;
+    }
+
+    if (shared_context) {
+        shared_st_context = ((struct radeon_context*)shared_context)->st_context;
+    }
+
+    dri_screen = dri_context->driScreenPriv;
+    radeon_screen = dri_screen->private;
+    radeon_context->dri_screen = dri_screen;
+    radeon_context->radeon_screen = radeon_screen;
+    radeon_context->drm_fd = dri_screen->fd;
+
+    radeon_context->pipe_winsys = radeon_pipe_winsys(radeon_screen);
+    if (radeon_context->pipe_winsys == NULL) {
+        free(radeon_context);
+        return GL_FALSE;
+    }
+
+    if (!getenv("RADEON_SOFTPIPE")) {
+        fprintf(stderr, "Creating r300 context...\n");
+        pipe =
+            r300_create_context(NULL,
+                                radeon_context->pipe_winsys,
+                                radeon_create_r300_winsys(radeon_context->drm_fd));
+        radeon_context->pipe_screen = pipe->screen;
+    } else {
+        pipe = radeon_create_softpipe(radeon_context);
+    }
+    radeon_context->st_context = st_create_context(pipe, visual,
+                                                shared_st_context);
+    driInitExtensions(radeon_context->st_context->ctx,
+                      radeon_card_extensions, GL_TRUE);
+    dri_context->driverPrivate = radeon_context;
+    return GL_TRUE;
+}
+
+void radeon_context_destroy(__DRIcontextPrivate *dri_context)
+{
+    struct radeon_context *radeon_context;
+
+    radeon_context = dri_context->driverPrivate;
+    st_finish(radeon_context->st_context);
+    st_destroy_context(radeon_context->st_context);
+    free(radeon_context);
+}
+
+GLboolean radeon_context_bind(__DRIcontextPrivate *dri_context,
+                           __DRIdrawablePrivate *dri_drawable,
+                           __DRIdrawablePrivate *dri_readable)
+{
+    struct radeon_framebuffer *drawable;
+    struct radeon_framebuffer *readable;
+    struct radeon_context *radeon_context;
+
+    if (dri_context == NULL) {
+        st_make_current(NULL, NULL, NULL);
+        return GL_TRUE;
+    }
+
+    radeon_context = dri_context->driverPrivate;
+    drawable = dri_drawable->driverPrivate;
+    readable = dri_readable->driverPrivate;
+    st_make_current(radeon_context->st_context,
+                    drawable->st_framebuffer,
+                    readable->st_framebuffer);
+
+    radeon_update_renderbuffers(dri_context, dri_drawable);
+    if (dri_drawable != dri_readable) {
+        radeon_update_renderbuffers(dri_context, dri_readable);
+    }
+    return GL_TRUE;
+}
+
+GLboolean radeon_context_unbind(__DRIcontextPrivate *dri_context)
+{
+    struct radeon_context *radeon_context;
+
+    radeon_context = dri_context->driverPrivate;
+    st_flush(radeon_context->st_context, PIPE_FLUSH_RENDER_CACHE, NULL);
+    return GL_TRUE;
+}
diff --git a/src/gallium/winsys/drm/radeon/radeon_context.h b/src/gallium/winsys/drm/radeon/radeon_context.h
new file mode 100644 (file)
index 0000000..d7222b4
--- /dev/null
@@ -0,0 +1,70 @@
+/* 
+ * Copyright © 2008 Jérôme Glisse
+ * 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:
+ *      Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef RADEON_CONTEXT_H
+#define RADEON_CONTEXT_H
+
+#include "dri_util.h"
+#include "state_tracker/st_public.h"
+#include "state_tracker/st_context.h"
+#include "radeon_screen.h"
+
+#include "radeon_r300.h"
+
+struct radeon_framebuffer {
+    struct st_framebuffer   *st_framebuffer;
+    unsigned                attachments;
+};
+
+struct radeon_context {
+    /* st */
+    struct st_context       *st_context;
+    /* pipe */
+    struct pipe_screen      *pipe_screen;
+    struct pipe_winsys      *pipe_winsys;
+    /* DRI */
+    __DRIscreenPrivate      *dri_screen;
+    __DRIdrawablePrivate    *dri_drawable;
+    __DRIdrawablePrivate    *dri_readable;
+    /* DRM */
+    int                     drm_fd;
+   /* RADEON */
+    struct radeon_screen       *radeon_screen;
+};
+
+GLboolean radeon_context_create(const __GLcontextModes*,
+                             __DRIcontextPrivate*,
+                             void*);
+void radeon_context_destroy(__DRIcontextPrivate*);
+GLboolean radeon_context_bind(__DRIcontextPrivate*,
+                           __DRIdrawablePrivate*,
+                           __DRIdrawablePrivate*);
+GLboolean radeon_context_unbind(__DRIcontextPrivate*);
+
+#endif
diff --git a/src/gallium/winsys/drm/radeon/radeon_r300.c b/src/gallium/winsys/drm/radeon/radeon_r300.c
new file mode 100644 (file)
index 0000000..8fe2375
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "radeon_r300.h"
+
+static boolean radeon_r300_check_cs(struct radeon_cs* cs, int size)
+{
+    /* XXX check size here, lazy ass! */
+    return TRUE;
+}
+
+static void radeon_r300_write_cs_reloc(struct radeon_cs* cs,
+                                    struct pipe_buffer* pbuffer,
+                                    uint32_t rd,
+                                    uint32_t wd,
+                                    uint32_t flags)
+{
+    radeon_cs_write_reloc(cs, ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags);
+}
+
+static void radeon_r300_flush_cs(struct radeon_cs* cs)
+{
+    radeon_cs_emit(cs);
+    radeon_cs_erase(cs);
+}
+
+/* Helper function to do the ioctls needed for setup and init. */
+static void do_ioctls(struct r300_winsys* winsys, int fd)
+{
+    drm_radeon_getparam_t gp;
+    uint32_t target;
+    int retval;
+
+    /* XXX is this cast safe? */
+    gp.value = (int*)&target;
+
+    /* First, get PCI ID */
+    gp.param = RADEON_PARAM_DEVICE_ID;
+    retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get PCI ID, error number %d",
+                __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->pci_id = target;
+
+    /* Then, get the number of pixel pipes */
+    gp.param = RADEON_PARAM_NUM_GB_PIPES;
+    retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get GB pipe count, error number %d",
+                __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->gb_pipes = target;
+
+}
+
+struct r300_winsys* radeon_create_r300_winsys(int fd)
+{
+    struct r300_winsys* winsys = calloc(1, sizeof(struct r300_winsys));
+
+    do_ioctls(winsys, fd);
+
+    struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd);
+
+    winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4);
+
+    winsys->check_cs = radeon_r300_check_cs;
+    winsys->begin_cs = radeon_cs_begin;
+    winsys->write_cs_dword = radeon_cs_write_dword;
+    winsys->write_cs_reloc = radeon_r300_write_cs_reloc;
+    winsys->end_cs = radeon_cs_end;
+    winsys->flush_cs = radeon_r300_flush_cs;
+
+    return winsys;
+}
diff --git a/src/gallium/winsys/drm/radeon/radeon_r300.h b/src/gallium/winsys/drm/radeon/radeon_r300.h
new file mode 100644 (file)
index 0000000..8ed95a3
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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. */
+
+/* XXX WTF is this! I shouldn't have to include those first three! FUCK! */
+#include <stdint.h>
+#include <stdlib.h>
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_cs.h"
+
+#include "r300_winsys.h"
+
+#include "radeon_buffer.h"
+
+struct r300_winsys* radeon_create_r300_winsys(int fd);
diff --git a/src/gallium/winsys/drm/radeon/radeon_screen.c b/src/gallium/winsys/drm/radeon/radeon_screen.c
new file mode 100644 (file)
index 0000000..e31caff
--- /dev/null
@@ -0,0 +1,288 @@
+/* 
+ * Copyright © 2008 Jérôme Glisse
+ * 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:
+ *      Jérôme Glisse <glisse@freedesktop.org>
+ */
+#include <stdio.h>
+#include "pipe/p_screen.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "state_tracker/st_public.h"
+#include "state_tracker/st_context.h"
+#include "utils.h"
+#include "xf86drm.h"
+#include "drm.h"
+#include "dri_util.h"
+#include "radeon_screen.h"
+#include "radeon_context.h"
+#include "radeon_buffer.h"
+#include "radeon_bo.h"
+#include "radeon_bo_gem.h"
+#include "radeon_drm.h"
+
+extern const struct dri_extension radeon_card_extensions[];
+
+static const __DRIextension *radeon_screen_extensions[] = {
+    &driReadDrawableExtension,
+    &driCopySubBufferExtension.base,
+    &driSwapControlExtension.base,
+    &driFrameTrackingExtension.base,
+    &driMediaStreamCounterExtension.base,
+    NULL
+};
+
+static __DRIconfig **radeon_fill_in_modes(unsigned pixel_bits,
+                                       unsigned depth_bits,
+                                       GLboolean have_back_buffer)
+{
+    __DRIconfig **configs;
+    unsigned depth_buffer_factor;
+    unsigned back_buffer_factor;
+    unsigned num_modes;
+    GLenum fb_format;
+    GLenum fb_type;
+    uint8_t depth_bits_array[3];
+    uint8_t stencil_bits_array[3];
+    uint8_t msaa_samples_array[1];
+    /* TODO: pageflipping ? */
+    static const GLenum back_buffer_modes[] = {
+        GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
+    };
+
+    stencil_bits_array[0] = 0;
+    stencil_bits_array[1] = 0;
+    if (depth_bits == 24) {
+        stencil_bits_array[2] = 8;
+        num_modes = 3;
+    }
+
+    depth_bits_array[0] = 0;
+    depth_bits_array[1] = depth_bits;
+    depth_bits_array[2] = depth_bits;
+    depth_buffer_factor = (depth_bits == 24) ? 3 : 2;
+
+    back_buffer_factor = (have_back_buffer) ? 3 : 1;
+
+    msaa_samples_array[0] = 0;
+
+    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 = (__DRIconfig **)driCreateConfigs(fb_format,
+                                               fb_type,
+                                               depth_bits_array,
+                                               stencil_bits_array,
+                                               depth_buffer_factor,
+                                               back_buffer_modes,
+                                               back_buffer_factor,
+                                               msaa_samples_array,
+                                               1);
+    if (configs == NULL) {
+        fprintf(stderr, "[%s:%u] Error creating FBConfig!\n",
+                __FILE__, __LINE__);
+        return NULL;
+    }
+    return configs;
+}
+
+static void radeon_screen_destroy(__DRIscreenPrivate *dri_screen)
+{
+     struct radeon_screen *radeon_screen = (struct radeon_screen*)dri_screen->private;
+
+     radeon_bo_manager_gem_dtor(radeon_screen->bom); 
+     dri_screen = NULL;
+     free(radeon_screen);
+}
+
+static const __DRIconfig **radeon_screen_init(__DRIscreenPrivate *dri_screen)
+{
+    struct radeon_screen *radeon_screen;
+
+    /* Calling driInitExtensions here, with a NULL context pointer,
+     * does not actually enable the extensions.  It just makes sure
+     * that all the dispatch offsets for all the extensions that
+     * *might* be enables are known.  This is needed because the
+     * dispatch offsets need to be known when _mesa_context_create is
+     * called, but we can't enable the extensions until we have a
+     * context pointer.
+     *
+     * Hello chicken.  Hello egg.  How are you two today?
+     */
+    driInitExtensions(NULL, radeon_card_extensions, GL_FALSE);
+
+    radeon_screen = calloc(1, sizeof(struct radeon_screen));
+    if (radeon_screen == NULL) {
+        fprintf(stderr, "\nERROR!  Allocating private area failed\n");
+        return NULL;
+    }
+    dri_screen->private = (void*)radeon_screen;
+    dri_screen->extensions = radeon_screen_extensions;
+    radeon_screen->dri_screen = dri_screen;
+
+    radeon_screen->bom = radeon_bo_manager_gem_ctor(dri_screen->fd);
+    if (radeon_screen->bom == NULL) {
+        radeon_screen_destroy(dri_screen);
+        return NULL;
+    }
+
+    return driConcatConfigs(radeon_fill_in_modes(16, 16, 1),
+                            radeon_fill_in_modes(32, 24, 1));
+}
+
+static boolean radeon_buffer_create(__DRIscreenPrivate *dri_screen,
+                                 __DRIdrawablePrivate *dri_drawable,
+                                 const __GLcontextModes *visual,
+                                 boolean is_pixmap)
+{
+    if (is_pixmap) {
+        /* TODO: implement ? */
+        return GL_FALSE;
+    } else {
+        enum pipe_format color_format, depth_format, stencil_format;
+        struct radeon_framebuffer *radeon_fb;
+
+        radeon_fb = calloc(1, sizeof(struct radeon_framebuffer));
+        if (radeon_fb == NULL) {
+            return GL_FALSE;
+        }
+
+        switch (visual->redBits) {
+        case 5:
+            color_format = PIPE_FORMAT_R5G6B5_UNORM;
+            break;
+        default:
+            color_format = PIPE_FORMAT_A8R8G8B8_UNORM;
+            break;
+        }
+
+        switch (visual->depthBits) {
+        case 24:
+            depth_format = PIPE_FORMAT_S8Z24_UNORM;
+            break;
+        case 16:
+            depth_format = PIPE_FORMAT_Z16_UNORM;
+            break;
+        default:
+            depth_format = PIPE_FORMAT_NONE;
+            break;
+        }
+
+        switch (visual->stencilBits) {
+        case 8:
+            /* force depth format */
+            depth_format = PIPE_FORMAT_S8Z24_UNORM;
+            stencil_format = PIPE_FORMAT_S8Z24_UNORM;
+            break;
+        default:
+            stencil_format = PIPE_FORMAT_NONE;
+            break;
+        }
+
+        radeon_fb->st_framebuffer = st_create_framebuffer(visual,
+                                                       color_format,
+                                                       depth_format,
+                                                       stencil_format,
+                                                       dri_drawable->w,
+                                                       dri_drawable->h,
+                                                       (void*)radeon_fb);
+        if (radeon_fb->st_framebuffer == NULL) {
+            free(radeon_fb);
+            return GL_FALSE;
+        }
+        dri_drawable->driverPrivate = (void *) radeon_fb;
+
+        radeon_fb->attachments = (1 << __DRI_BUFFER_FRONT_LEFT);
+        if (visual->doubleBufferMode) {
+            radeon_fb->attachments |= (1 << __DRI_BUFFER_BACK_LEFT);
+        }
+        if (visual->depthBits || visual->stencilBits) {
+            radeon_fb->attachments |= (1 << __DRI_BUFFER_DEPTH);
+        }
+
+        return GL_TRUE;
+    }
+}
+
+static void radeon_buffer_destroy(__DRIdrawablePrivate * dri_drawable)
+{
+   struct radeon_framebuffer *radeon_fb;
+   
+   radeon_fb = dri_drawable->driverPrivate;
+   assert(radeon_fb->st_framebuffer);
+   st_unreference_framebuffer(radeon_fb->st_framebuffer);
+   free(radeon_fb);
+}
+
+static void radeon_swap_buffers(__DRIdrawablePrivate *dri_drawable)
+{
+    struct radeon_framebuffer *radeon_fb;
+    struct pipe_surface *back_surf = NULL;
+
+    radeon_fb = dri_drawable->driverPrivate;
+    assert(radeon_fb);
+    assert(radeon_fb->st_framebuffer);
+
+    st_get_framebuffer_surface(radeon_fb->st_framebuffer,
+                               ST_SURFACE_BACK_LEFT,
+                               &back_surf);
+    if (back_surf) {
+        st_notify_swapbuffers(radeon_fb->st_framebuffer);
+        /* TODO: do we want to do anythings ? */
+        st_notify_swapbuffers_complete(radeon_fb->st_framebuffer);
+    }
+}
+
+/**
+ * Called via glXCopySubBufferMESA() to copy a subrect of the back
+ * buffer to the front buffer/screen.
+ */
+static void radeon_copy_sub_buffer(__DRIdrawablePrivate *dri_drawable,
+                         int x, int y, int w, int h)
+{
+    /* TODO: ... */
+}
+
+const struct __DriverAPIRec driDriverAPI = {
+    .InitScreen           = NULL,
+    .DestroyScreen        = radeon_screen_destroy,
+    .CreateContext        = radeon_context_create,
+    .DestroyContext       = radeon_context_destroy,
+    .CreateBuffer         = radeon_buffer_create,
+    .DestroyBuffer        = radeon_buffer_destroy,
+    .SwapBuffers          = radeon_swap_buffers,
+    .MakeCurrent          = radeon_context_bind,
+    .UnbindContext        = radeon_context_unbind,
+    .CopySubBuffer        = radeon_copy_sub_buffer,
+    .InitScreen2          = radeon_screen_init,
+};
diff --git a/src/gallium/winsys/drm/radeon/radeon_screen.h b/src/gallium/winsys/drm/radeon/radeon_screen.h
new file mode 100644 (file)
index 0000000..01b7fa6
--- /dev/null
@@ -0,0 +1,41 @@
+/* 
+ * Copyright © 2008 Jérôme Glisse
+ * 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:
+ *      Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef RADEON_SCREEN_H
+#define RADEON_SCREEN_H
+
+#include "dri_util.h"
+#include "radeon_bo.h"
+
+struct radeon_screen {
+    __DRIscreenPrivate          *dri_screen;
+    struct radeon_bo_manager    *bom;
+};
+
+#endif
diff --git a/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.c b/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.c
new file mode 100644 (file)
index 0000000..8402e1f
--- /dev/null
@@ -0,0 +1,77 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * 
+ **************************************************************************/
+/*
+ * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ */
+#include <stdio.h>
+#include "imports.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_format.h"
+#include "softpipe/sp_winsys.h"
+#include "radeon_context.h"
+#include "radeon_winsys_softpipe.h"
+
+struct radeon_softpipe_winsys {
+    struct softpipe_winsys  sp_winsys;
+    struct radeon_context      *radeon_context;
+};
+
+/**
+ * Return list of surface formats supported by this driver.
+ */
+static boolean radeon_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 *radeon_create_softpipe(struct radeon_context *radeon_context)
+{
+    struct radeon_softpipe_winsys *radeon_sp_ws;
+    struct pipe_screen *pipe_screen;
+
+    pipe_screen = softpipe_create_screen(radeon_context->pipe_winsys);
+
+    radeon_sp_ws = CALLOC_STRUCT(radeon_softpipe_winsys);
+    if (radeon_sp_ws == NULL) {
+        return NULL;
+    }
+    radeon_context->pipe_screen = pipe_screen;
+    radeon_sp_ws->radeon_context = radeon_context;
+    radeon_sp_ws->sp_winsys.is_format_supported = radeon_is_format_supported;
+    return softpipe_create(pipe_screen,
+                           radeon_context->pipe_winsys,
+                           &radeon_sp_ws->sp_winsys);
+}
diff --git a/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.h b/src/gallium/winsys/drm/radeon/radeon_winsys_softpipe.h
new file mode 100644 (file)
index 0000000..519eab7
--- /dev/null
@@ -0,0 +1,37 @@
+/* 
+ * Copyright © 2008 Jérôme Glisse
+ * 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:
+ *      Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef RADEON_WINSYS_SOFTPIPE_H
+#define RADEON_WINSYS_SOFTPIPE_H
+
+#include "radeon_context.h"
+
+struct pipe_context *radeon_create_softpipe(struct radeon_context *radeon_context);
+
+#endif