Initial revision
authorNicolai Haehnle <prefect_@gmx.net>
Tue, 28 Sep 2004 10:59:23 +0000 (10:59 +0000)
committerNicolai Haehnle <prefect_@gmx.net>
Tue, 28 Sep 2004 10:59:23 +0000 (10:59 +0000)
28 files changed:
src/mesa/drivers/dri/r300/Makefile [new file with mode: 0644]
src/mesa/drivers/dri/r300/r200_context.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r200_ioctl.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r200_reg.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r200_sanity.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r200_state.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r200_tcl.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r200_tex.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_cmdbuf.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_cmdbuf.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_context.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_context.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_ioctl.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_ioctl.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_program.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_reg.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_state.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_state.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/radeon_context.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/radeon_context.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/radeon_ioctl.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/radeon_ioctl.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/radeon_lock.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/radeon_lock.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/radeon_screen.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/radeon_screen.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/radeon_span.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/radeon_span.h [new file with mode: 0644]

diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
new file mode 100644 (file)
index 0000000..3cad8c0
--- /dev/null
@@ -0,0 +1,72 @@
+# src/mesa/drivers/dri/r300/Makefile
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = r300_dri.so
+DEFINES += -DCOMPILE_R300
+
+MINIGLX_SOURCES = server/radeon_dri.c
+
+COMMON_SOURCES = \
+       ../../common/driverfuncs.c \
+       ../common/mm.c \
+       ../common/utils.c \
+       ../common/texmem.c \
+       ../common/vblank.c \
+       ../common/xmlconfig.c \
+       ../common/dri_util.c \
+       ../common/glcontextmodes.c
+
+DRIVER_SOURCES = \
+                radeon_screen.c \
+                radeon_context.c \
+                radeon_ioctl.c \
+                radeon_lock.c \
+                radeon_span.c \
+                \
+                r300_context.c \
+                r300_ioctl.c \
+                r300_cmdbuf.c \
+                r300_state.c \
+                \
+                r200_context.c \
+                r200_ioctl.c \
+                r200_state.c \
+                r200_state_init.c \
+                r200_cmdbuf.c \
+                r200_pixel.c \
+                r200_tex.c \
+                r200_texmem.c \
+                r200_texstate.c \
+                r200_tcl.c \
+                r200_swtcl.c \
+                r200_maos.c \
+                r200_sanity.c \
+                r200_vtxfmt.c \
+                r200_vtxfmt_c.c \
+                r200_vtxfmt_sse.c \
+                r200_vtxfmt_x86.c
+
+C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
+
+X86_SOURCES = r200_vtxtmp_x86.S
+
+SYMLINKS = \
+       server/radeon_dri.c \
+       server/radeon_dri.h \
+       server/radeon.h \
+       server/radeon_macros.h \
+       server/radeon_reg.h
+
+##### TARGETS #####
+
+
+include ../Makefile.template
+
+$(SYMLINKS):
+       mkdir -p server
+       for i in $(SYMLINKS) ; do rm -f $$i && test -f ../radeon/$$i && ln -s ../../radeon/$$i $$i ; done
+
+symlinks: $(SYMLINKS)
+
diff --git a/src/mesa/drivers/dri/r300/r200_context.h b/src/mesa/drivers/dri/r300/r200_context.h
new file mode 100644 (file)
index 0000000..b5ba1f9
--- /dev/null
@@ -0,0 +1,840 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef __R200_CONTEXT_H__
+#define __R200_CONTEXT_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "tnl/t_vertex.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "dri_util.h"
+#include "texmem.h"
+
+#include "macros.h"
+#include "mtypes.h"
+#include "colormac.h"
+#include "r200_reg.h"
+#include "radeon_context.h"
+
+#define ENABLE_HW_3D_TEXTURE 1 /* XXX this is temporary! */
+
+struct r200_context;
+typedef struct r200_context r200ContextRec;
+typedef struct r200_context *r200ContextPtr;
+
+#include "mm.h"
+
+/* The blit width for texture uploads
+ */
+#define BLIT_WIDTH_BYTES 1024
+
+/* Use the templated vertex format:
+ */
+#define COLOR_IS_RGBA
+#define TAG(x) r200##x
+#include "tnl_dd/t_dd_vertex.h"
+#undef TAG
+
+typedef void (*r200_tri_func) (r200ContextPtr,
+                              r200Vertex *, r200Vertex *, r200Vertex *);
+
+typedef void (*r200_line_func) (r200ContextPtr, r200Vertex *, r200Vertex *);
+
+typedef void (*r200_point_func) (r200ContextPtr, r200Vertex *);
+
+struct r200_depthbuffer_state {
+       GLfloat scale;
+};
+
+struct r200_scissor_state {
+       drm_clip_rect_t rect;
+       GLboolean enabled;
+
+       GLuint numClipRects;    /* Cliprects active */
+       GLuint numAllocedClipRects;     /* Cliprects available */
+       drm_clip_rect_t *pClipRects;
+};
+
+struct r200_stencilbuffer_state {
+       GLboolean hwBuffer;
+       GLuint clear;           /* rb3d_stencilrefmask value */
+};
+
+struct r200_stipple_state {
+       GLuint mask[32];
+};
+
+#define TEX_0   0x1
+#define TEX_1   0x2
+#define TEX_2  0x4
+#define TEX_3  0x8
+#define TEX_4  0x10
+#define TEX_5  0x20
+#define TEX_ALL 0x3f
+
+typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr;
+
+/* Texture object in locally shared texture space.
+ */
+struct r200_tex_obj {
+       driTextureObject base;
+
+       GLuint bufAddr;         /* Offset to start of locally
+                                  shared texture block */
+
+       GLuint dirty_state;     /* Flags (1 per texunit) for
+                                  whether or not this texobj
+                                  has dirty hardware state
+                                  (pp_*) that needs to be
+                                  brought into the
+                                  texunit. */
+
+       drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS];
+       /* Six, for the cube faces */
+
+       GLuint pp_txfilter;     /* hardware register values */
+       GLuint pp_txformat;
+       GLuint pp_txformat_x;
+       GLuint pp_txoffset;     /* Image location in texmem.
+                                  All cube faces follow. */
+       GLuint pp_txsize;       /* npot only */
+       GLuint pp_txpitch;      /* npot only */
+       GLuint pp_border_color;
+       GLuint pp_cubic_faces;  /* cube face 1,2,3,4 log2 sizes */
+
+       GLboolean border_fallback;
+};
+
+struct r200_texture_env_state {
+       r200TexObjPtr texobj;
+       GLenum format;
+       GLenum envMode;
+};
+
+#define R200_MAX_TEXTURE_UNITS 6
+
+struct r200_texture_state {
+       struct r200_texture_env_state unit[R200_MAX_TEXTURE_UNITS];
+};
+
+struct r200_state_atom {
+       struct r200_state_atom *next, *prev;
+       const char *name;       /* for debug */
+       int cmd_size;           /* size in bytes */
+       GLuint idx;
+       int *cmd;               /* one or more cmd's */
+       int *lastcmd;           /* one or more cmd's */
+       int *savedcmd;          /* one or more cmd's */
+       GLboolean dirty;
+        GLboolean(*check) (GLcontext *, int);  /* is this state active? */
+};
+
+/* Trying to keep these relatively short as the variables are becoming
+ * extravagently long.  Drop the driver name prefix off the front of
+ * everything - I think we know which driver we're in by now, and keep the
+ * prefix to 3 letters unless absolutely impossible.
+ */
+
+#define CTX_CMD_0             0
+#define CTX_PP_MISC           1
+#define CTX_PP_FOG_COLOR      2
+#define CTX_RE_SOLID_COLOR    3
+#define CTX_RB3D_BLENDCNTL    4
+#define CTX_RB3D_DEPTHOFFSET  5
+#define CTX_RB3D_DEPTHPITCH   6
+#define CTX_RB3D_ZSTENCILCNTL 7
+#define CTX_CMD_1             8
+#define CTX_PP_CNTL           9
+#define CTX_RB3D_CNTL         10
+#define CTX_RB3D_COLOROFFSET  11
+#define CTX_CMD_2             12       /* why */
+#define CTX_RB3D_COLORPITCH   13       /* why */
+#define CTX_STATE_SIZE_OLDDRM 14
+#define CTX_CMD_3             14
+#define CTX_RB3D_BLENDCOLOR   15
+#define CTX_RB3D_ABLENDCNTL   16
+#define CTX_RB3D_CBLENDCNTL   17
+#define CTX_STATE_SIZE_NEWDRM 18
+
+#define SET_CMD_0               0
+#define SET_SE_CNTL             1
+#define SET_RE_CNTL             2      /* replace se_coord_fmt */
+#define SET_STATE_SIZE          3
+
+#define VTE_CMD_0               0
+#define VTE_SE_VTE_CNTL         1
+#define VTE_STATE_SIZE          2
+
+#define LIN_CMD_0               0
+#define LIN_RE_LINE_PATTERN     1
+#define LIN_RE_LINE_STATE       2
+#define LIN_CMD_1               3
+#define LIN_SE_LINE_WIDTH       4
+#define LIN_STATE_SIZE          5
+
+#define MSK_CMD_0               0
+#define MSK_RB3D_STENCILREFMASK 1
+#define MSK_RB3D_ROPCNTL        2
+#define MSK_RB3D_PLANEMASK      3
+#define MSK_STATE_SIZE          4
+
+#define VPT_CMD_0           0
+#define VPT_SE_VPORT_XSCALE          1
+#define VPT_SE_VPORT_XOFFSET         2
+#define VPT_SE_VPORT_YSCALE          3
+#define VPT_SE_VPORT_YOFFSET         4
+#define VPT_SE_VPORT_ZSCALE          5
+#define VPT_SE_VPORT_ZOFFSET         6
+#define VPT_STATE_SIZE      7
+
+#define ZBS_CMD_0               0
+#define ZBS_SE_ZBIAS_FACTOR     1
+#define ZBS_SE_ZBIAS_CONSTANT   2
+#define ZBS_STATE_SIZE          3
+
+#define MSC_CMD_0               0
+#define MSC_RE_MISC             1
+#define MSC_STATE_SIZE          2
+
+#define TAM_CMD_0               0
+#define TAM_DEBUG3              1
+#define TAM_STATE_SIZE          2
+
+#define TEX_CMD_0                   0
+#define TEX_PP_TXFILTER             1  /*2c00 */
+#define TEX_PP_TXFORMAT             2  /*2c04 */
+#define TEX_PP_TXFORMAT_X           3  /*2c08 */
+#define TEX_PP_TXSIZE               4  /*2c0c */
+#define TEX_PP_TXPITCH              5  /*2c10 */
+#define TEX_PP_BORDER_COLOR         6  /*2c14 */
+#define TEX_CMD_1                   7
+#define TEX_PP_TXOFFSET             8  /*2d00 */
+#define TEX_STATE_SIZE              9
+
+#define CUBE_CMD_0                  0  /* 1 register follows */
+#define CUBE_PP_CUBIC_FACES         1  /* 0x2c18 */
+#define CUBE_CMD_1                  2  /* 5 registers follow */
+#define CUBE_PP_CUBIC_OFFSET_F1     3  /* 0x2d04 */
+#define CUBE_PP_CUBIC_OFFSET_F2     4  /* 0x2d08 */
+#define CUBE_PP_CUBIC_OFFSET_F3     5  /* 0x2d0c */
+#define CUBE_PP_CUBIC_OFFSET_F4     6  /* 0x2d10 */
+#define CUBE_PP_CUBIC_OFFSET_F5     7  /* 0x2d14 */
+#define CUBE_STATE_SIZE             8
+
+#define PIX_CMD_0                   0
+#define PIX_PP_TXCBLEND             1
+#define PIX_PP_TXCBLEND2            2
+#define PIX_PP_TXABLEND             3
+#define PIX_PP_TXABLEND2            4
+#define PIX_STATE_SIZE              5
+
+#define TF_CMD_0                    0
+#define TF_TFACTOR_0                1
+#define TF_TFACTOR_1                2
+#define TF_TFACTOR_2                3
+#define TF_TFACTOR_3                4
+#define TF_TFACTOR_4                5
+#define TF_TFACTOR_5                6
+#define TF_STATE_SIZE               7
+
+#define TCL_CMD_0                 0
+#define TCL_LIGHT_MODEL_CTL_0     1
+#define TCL_LIGHT_MODEL_CTL_1     2
+#define TCL_PER_LIGHT_CTL_0       3
+#define TCL_PER_LIGHT_CTL_1       4
+#define TCL_PER_LIGHT_CTL_2       5
+#define TCL_PER_LIGHT_CTL_3       6
+#define TCL_CMD_1                 7
+#define TCL_UCP_VERT_BLEND_CTL    8
+#define TCL_STATE_SIZE            9
+
+#define MSL_CMD_0                     0
+#define MSL_MATRIX_SELECT_0           1
+#define MSL_MATRIX_SELECT_1           2
+#define MSL_MATRIX_SELECT_2           3
+#define MSL_MATRIX_SELECT_3           4
+#define MSL_MATRIX_SELECT_4           5
+#define MSL_STATE_SIZE                6
+
+#define TCG_CMD_0                 0
+#define TCG_TEX_PROC_CTL_2            1
+#define TCG_TEX_PROC_CTL_3            2
+#define TCG_TEX_PROC_CTL_0            3
+#define TCG_TEX_PROC_CTL_1            4
+#define TCG_TEX_CYL_WRAP_CTL      5
+#define TCG_STATE_SIZE            6
+
+#define MTL_CMD_0            0
+#define MTL_EMMISSIVE_RED    1
+#define MTL_EMMISSIVE_GREEN  2
+#define MTL_EMMISSIVE_BLUE   3
+#define MTL_EMMISSIVE_ALPHA  4
+#define MTL_AMBIENT_RED      5
+#define MTL_AMBIENT_GREEN    6
+#define MTL_AMBIENT_BLUE     7
+#define MTL_AMBIENT_ALPHA    8
+#define MTL_DIFFUSE_RED      9
+#define MTL_DIFFUSE_GREEN    10
+#define MTL_DIFFUSE_BLUE     11
+#define MTL_DIFFUSE_ALPHA    12
+#define MTL_SPECULAR_RED     13
+#define MTL_SPECULAR_GREEN   14
+#define MTL_SPECULAR_BLUE    15
+#define MTL_SPECULAR_ALPHA   16
+#define MTL_CMD_1            17
+#define MTL_SHININESS        18
+#define MTL_STATE_SIZE       19
+
+#define VAP_CMD_0                   0
+#define VAP_SE_VAP_CNTL             1
+#define VAP_STATE_SIZE              2
+
+/* Replaces a lot of packet info from radeon
+ */
+#define VTX_CMD_0                   0
+#define VTX_VTXFMT_0            1
+#define VTX_VTXFMT_1            2
+#define VTX_TCL_OUTPUT_VTXFMT_0 3
+#define VTX_TCL_OUTPUT_VTXFMT_1 4
+#define VTX_CMD_1               5
+#define VTX_TCL_OUTPUT_COMPSEL  6
+#define VTX_CMD_2               7
+#define VTX_STATE_CNTL          8
+#define VTX_STATE_SIZE          9
+
+#define VTX_COLOR(v,n)   (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\
+                         R200_VTX_COLOR_MASK)
+
+/**
+ * Given the \c R200_SE_VTX_FMT_1 for the current vertex state, determine
+ * how many components are in texture coordinate \c n.
+ */
+#define VTX_TEXn_COUNT(v,n)   (((v) >> (3 * n)) & 0x07)
+
+#define MAT_CMD_0              0
+#define MAT_ELT_0              1
+#define MAT_STATE_SIZE         17
+
+#define GRD_CMD_0                  0
+#define GRD_VERT_GUARD_CLIP_ADJ    1
+#define GRD_VERT_GUARD_DISCARD_ADJ 2
+#define GRD_HORZ_GUARD_CLIP_ADJ    3
+#define GRD_HORZ_GUARD_DISCARD_ADJ 4
+#define GRD_STATE_SIZE             5
+
+/* position changes frequently when lighting in modelpos - separate
+ * out to new state item?
+ */
+#define LIT_CMD_0                  0
+#define LIT_AMBIENT_RED            1
+#define LIT_AMBIENT_GREEN          2
+#define LIT_AMBIENT_BLUE           3
+#define LIT_AMBIENT_ALPHA          4
+#define LIT_DIFFUSE_RED            5
+#define LIT_DIFFUSE_GREEN          6
+#define LIT_DIFFUSE_BLUE           7
+#define LIT_DIFFUSE_ALPHA          8
+#define LIT_SPECULAR_RED           9
+#define LIT_SPECULAR_GREEN         10
+#define LIT_SPECULAR_BLUE          11
+#define LIT_SPECULAR_ALPHA         12
+#define LIT_POSITION_X             13
+#define LIT_POSITION_Y             14
+#define LIT_POSITION_Z             15
+#define LIT_POSITION_W             16
+#define LIT_DIRECTION_X            17
+#define LIT_DIRECTION_Y            18
+#define LIT_DIRECTION_Z            19
+#define LIT_DIRECTION_W            20
+#define LIT_ATTEN_QUADRATIC        21
+#define LIT_ATTEN_LINEAR           22
+#define LIT_ATTEN_CONST            23
+#define LIT_ATTEN_XXX              24
+#define LIT_CMD_1                  25
+#define LIT_SPOT_DCD               26
+#define LIT_SPOT_DCM               27
+#define LIT_SPOT_EXPONENT          28
+#define LIT_SPOT_CUTOFF            29
+#define LIT_SPECULAR_THRESH        30
+#define LIT_RANGE_CUTOFF           31  /* ? */
+#define LIT_ATTEN_CONST_INV        32
+#define LIT_STATE_SIZE             33
+
+/* Fog
+ */
+#define FOG_CMD_0      0
+#define FOG_R          1
+#define FOG_C          2
+#define FOG_D          3
+#define FOG_PAD        4
+#define FOG_STATE_SIZE 5
+
+/* UCP
+ */
+#define UCP_CMD_0      0
+#define UCP_X          1
+#define UCP_Y          2
+#define UCP_Z          3
+#define UCP_W          4
+#define UCP_STATE_SIZE 5
+
+/* GLT - Global ambient
+ */
+#define GLT_CMD_0      0
+#define GLT_RED        1
+#define GLT_GREEN      2
+#define GLT_BLUE       3
+#define GLT_ALPHA      4
+#define GLT_STATE_SIZE 5
+
+/* EYE
+ */
+#define EYE_CMD_0          0
+#define EYE_X              1
+#define EYE_Y              2
+#define EYE_Z              3
+#define EYE_RESCALE_FACTOR 4
+#define EYE_STATE_SIZE     5
+
+/* CST - constant state
+ */
+#define CST_CMD_0                             0
+#define CST_PP_CNTL_X                         1
+#define CST_CMD_1                             2
+#define CST_RB3D_DEPTHXY_OFFSET               3
+#define CST_CMD_2                             4
+#define CST_RE_AUX_SCISSOR_CNTL               5
+#define CST_CMD_3                             6
+#define CST_RE_SCISSOR_TL_0                   7
+#define CST_RE_SCISSOR_BR_0                   8
+#define CST_CMD_4                             9
+#define CST_SE_VAP_CNTL_STATUS                10
+#define CST_CMD_5                             11
+#define CST_RE_POINTSIZE                      12
+#define CST_CMD_6                             13
+#define CST_SE_TCL_INPUT_VTX_0                14
+#define CST_SE_TCL_INPUT_VTX_1                15
+#define CST_SE_TCL_INPUT_VTX_2                16
+#define CST_SE_TCL_INPUT_VTX_3                17
+#define CST_STATE_SIZE                        18
+
+struct r200_hw_state {
+       /* Head of the linked list of state atoms. */
+       struct r200_state_atom atomlist;
+
+       /* Hardware state, stored as cmdbuf commands:
+        *   -- Need to doublebuffer for
+        *           - reviving state after loss of context
+        *           - eliding noop statechange loops? (except line stipple count)
+        */
+       struct r200_state_atom ctx;
+       struct r200_state_atom set;
+       struct r200_state_atom vte;
+       struct r200_state_atom lin;
+       struct r200_state_atom msk;
+       struct r200_state_atom vpt;
+       struct r200_state_atom vap;
+       struct r200_state_atom vtx;
+       struct r200_state_atom tcl;
+       struct r200_state_atom msl;
+       struct r200_state_atom tcg;
+       struct r200_state_atom msc;
+       struct r200_state_atom cst;
+       struct r200_state_atom tam;
+       struct r200_state_atom tf;
+       struct r200_state_atom tex[6];
+       struct r200_state_atom cube[6];
+       struct r200_state_atom zbs;
+       struct r200_state_atom mtl[2];
+       struct r200_state_atom mat[9];
+       struct r200_state_atom lit[8];  /* includes vec, scl commands */
+       struct r200_state_atom ucp[6];
+       struct r200_state_atom pix[6];  /* pixshader stages */
+       struct r200_state_atom eye;     /* eye pos */
+       struct r200_state_atom grd;     /* guard band clipping */
+       struct r200_state_atom fog;
+       struct r200_state_atom glt;
+
+       int max_state_size;     /* Number of bytes necessary for a full state emit. */
+       GLboolean is_dirty, all_dirty;
+};
+
+struct r200_colorbuffer_state {
+       int roundEnable;
+};
+
+struct r200_state {
+       /* Derived state for internal purposes:
+        */
+       struct r200_colorbuffer_state color;
+       struct r200_depthbuffer_state depth;
+       struct r200_scissor_state scissor;
+       struct r200_stencilbuffer_state stencil;
+       struct r200_stipple_state stipple;
+       struct r200_texture_state texture;
+};
+
+/* Need refcounting on dma buffers:
+ */
+struct r200_dma_buffer {
+       int refcount;           /* the number of retained regions in buf */
+       drmBufPtr buf;
+};
+
+#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset +               \
+                       (rvb)->address - rmesa->dma.buf0_address +      \
+                       (rvb)->start)
+
+/* A retained region, eg vertices for indexed vertices.
+ */
+struct r200_dma_region {
+       struct r200_dma_buffer *buf;
+       char *address;          /* == buf->address */
+       int start, end, ptr;    /* offsets from start of buf */
+       int aos_start;
+       int aos_stride;
+       int aos_size;
+};
+
+struct r200_dma {
+       /* Active dma region.  Allocations for vertices and retained
+        * regions come from here.  Also used for emitting random vertices,
+        * these may be flushed by calling flush_current();
+        */
+       struct r200_dma_region current;
+
+       void (*flush) (r200ContextPtr);
+
+       char *buf0_address;     /* start of buf[0], for index calcs */
+       GLuint nr_released_bufs;        /* flush after so many buffers released */
+};
+
+#define R200_CMD_BUF_SZ  (8*1024)
+
+struct r200_store {
+       GLuint statenr;
+       GLuint primnr;
+       char cmd_buf[R200_CMD_BUF_SZ];
+       int cmd_used;
+       int elts_start;
+};
+
+/* r200_tcl.c
+ */
+struct r200_tcl_info {
+       GLuint vertex_format;
+       GLint last_offset;
+       GLuint hw_primitive;
+
+       struct r200_dma_region *aos_components[8];
+       GLuint nr_aos_components;
+
+       GLuint *Elts;
+
+       struct r200_dma_region indexed_verts;
+       struct r200_dma_region obj;
+       struct r200_dma_region rgba;
+       struct r200_dma_region spec;
+       struct r200_dma_region fog;
+       struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS];
+       struct r200_dma_region norm;
+};
+
+/* r200_swtcl.c
+ */
+struct r200_swtcl_info {
+       GLuint RenderIndex;
+
+   /**
+    * Size of a hardware vertex.  This is calculated when \c ::vertex_attrs is
+    * installed in the Mesa state vector.
+    */
+       GLuint vertex_size;
+
+   /**
+    * Attributes instructing the Mesa TCL pipeline where / how to put vertex
+    * data in the hardware buffer.
+    */
+       struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
+
+   /**
+    * Number of elements of \c ::vertex_attrs that are actually used.
+    */
+       GLuint vertex_attr_count;
+
+   /**
+    * Cached pointer to the buffer where Mesa will store vertex data.
+    */
+       GLubyte *verts;
+
+       /* Fallback rasterization functions
+        */
+       r200_point_func draw_point;
+       r200_line_func draw_line;
+       r200_tri_func draw_tri;
+
+       GLuint hw_primitive;
+       GLenum render_primitive;
+       GLuint numverts;
+
+   /**
+    * Offset of the 4UB color data within a hardware (swtcl) vertex.
+    */
+       GLuint coloroffset;
+
+   /**
+    * Offset of the 3UB specular color data within a hardware (swtcl) vertex.
+    */
+       GLuint specoffset;
+
+   /**
+    * Should Mesa project vertex data or will the hardware do it?
+    */
+       GLboolean needproj;
+
+       struct r200_dma_region indexed_verts;
+};
+
+struct r200_ioctl {
+       GLuint vertex_offset;
+       GLuint vertex_size;
+};
+
+#define R200_MAX_PRIMS 64
+
+/* Want to keep a cache of these around.  Each is parameterized by
+ * only a single value which has only a small range.  Only expect a
+ * few, so just rescan the list each time?
+ */
+struct dynfn {
+       struct dynfn *next, *prev;
+       int key[2];
+       char *code;
+};
+
+struct dfn_lists {
+       struct dynfn Vertex2f;
+       struct dynfn Vertex2fv;
+       struct dynfn Vertex3f;
+       struct dynfn Vertex3fv;
+       struct dynfn Color4ub;
+       struct dynfn Color4ubv;
+       struct dynfn Color3ub;
+       struct dynfn Color3ubv;
+       struct dynfn Color4f;
+       struct dynfn Color4fv;
+       struct dynfn Color3f;
+       struct dynfn Color3fv;
+       struct dynfn SecondaryColor3ubEXT;
+       struct dynfn SecondaryColor3ubvEXT;
+       struct dynfn SecondaryColor3fEXT;
+       struct dynfn SecondaryColor3fvEXT;
+       struct dynfn Normal3f;
+       struct dynfn Normal3fv;
+       struct dynfn TexCoord3f;
+       struct dynfn TexCoord3fv;
+       struct dynfn TexCoord2f;
+       struct dynfn TexCoord2fv;
+       struct dynfn TexCoord1f;
+       struct dynfn TexCoord1fv;
+       struct dynfn MultiTexCoord3fARB;
+       struct dynfn MultiTexCoord3fvARB;
+       struct dynfn MultiTexCoord2fARB;
+       struct dynfn MultiTexCoord2fvARB;
+       struct dynfn MultiTexCoord1fARB;
+       struct dynfn MultiTexCoord1fvARB;
+};
+
+struct dfn_generators {
+       struct dynfn *(*Vertex2f) (GLcontext *, const int *);
+       struct dynfn *(*Vertex2fv) (GLcontext *, const int *);
+       struct dynfn *(*Vertex3f) (GLcontext *, const int *);
+       struct dynfn *(*Vertex3fv) (GLcontext *, const int *);
+       struct dynfn *(*Color4ub) (GLcontext *, const int *);
+       struct dynfn *(*Color4ubv) (GLcontext *, const int *);
+       struct dynfn *(*Color3ub) (GLcontext *, const int *);
+       struct dynfn *(*Color3ubv) (GLcontext *, const int *);
+       struct dynfn *(*Color4f) (GLcontext *, const int *);
+       struct dynfn *(*Color4fv) (GLcontext *, const int *);
+       struct dynfn *(*Color3f) (GLcontext *, const int *);
+       struct dynfn *(*Color3fv) (GLcontext *, const int *);
+       struct dynfn *(*SecondaryColor3ubEXT) (GLcontext *, const int *);
+       struct dynfn *(*SecondaryColor3ubvEXT) (GLcontext *, const int *);
+       struct dynfn *(*SecondaryColor3fEXT) (GLcontext *, const int *);
+       struct dynfn *(*SecondaryColor3fvEXT) (GLcontext *, const int *);
+       struct dynfn *(*Normal3f) (GLcontext *, const int *);
+       struct dynfn *(*Normal3fv) (GLcontext *, const int *);
+       struct dynfn *(*TexCoord3f) (GLcontext *, const int *);
+       struct dynfn *(*TexCoord3fv) (GLcontext *, const int *);
+       struct dynfn *(*TexCoord2f) (GLcontext *, const int *);
+       struct dynfn *(*TexCoord2fv) (GLcontext *, const int *);
+       struct dynfn *(*TexCoord1f) (GLcontext *, const int *);
+       struct dynfn *(*TexCoord1fv) (GLcontext *, const int *);
+       struct dynfn *(*MultiTexCoord3fARB) (GLcontext *, const int *);
+       struct dynfn *(*MultiTexCoord3fvARB) (GLcontext *, const int *);
+       struct dynfn *(*MultiTexCoord2fARB) (GLcontext *, const int *);
+       struct dynfn *(*MultiTexCoord2fvARB) (GLcontext *, const int *);
+       struct dynfn *(*MultiTexCoord1fARB) (GLcontext *, const int *);
+       struct dynfn *(*MultiTexCoord1fvARB) (GLcontext *, const int *);
+};
+
+struct r200_prim {
+       GLuint start;
+       GLuint end;
+       GLuint prim;
+};
+
+   /* A maximum total of 29 elements per vertex:  3 floats for position, 3
+    * floats for normal, 4 floats for color, 4 bytes for secondary color,
+    * 3 floats for each texture unit (18 floats total).
+    *
+    * we maybe need add. 4 to prevent segfault if someone specifies
+    * GL_TEXTURE6/GL_TEXTURE7 (esp. for the codegen-path) (FIXME: )
+    *
+    * The position data is never actually stored here, so 3 elements could be
+    * trimmed out of the buffer.
+    */
+
+#define R200_MAX_VERTEX_SIZE ((3*6)+11)
+
+struct r200_vbinfo {
+       GLint counter, initial_counter;
+       GLint *dmaptr;
+       void (*notify) (void);
+       GLint vertex_size;
+
+       union {
+               float f;
+               int i;
+               r200_color_t color;
+       } vertex[R200_MAX_VERTEX_SIZE];
+
+       GLfloat *normalptr;
+       GLfloat *floatcolorptr;
+       r200_color_t *colorptr;
+       GLfloat *floatspecptr;
+       r200_color_t *specptr;
+       GLfloat *texcoordptr[8];        /* 6 (TMU) + 2 for r200_vtxfmt_c.c when GL_TEXTURE6/7 */
+
+       GLenum *prim;           /* &ctx->Driver.CurrentExecPrimitive */
+       GLuint primflags;
+       GLboolean enabled;      /* *_NO_VTXFMT / *_NO_TCL env vars */
+       GLboolean installed;
+       GLboolean fell_back;
+       GLboolean recheck;
+       GLint nrverts;
+       GLuint vtxfmt_0, vtxfmt_1;
+
+       GLuint installed_vertex_format;
+       GLuint installed_color_3f_sz;
+
+       struct r200_prim primlist[R200_MAX_PRIMS];
+       int nrprims;
+
+       struct dfn_lists dfn_cache;
+       struct dfn_generators codegen;
+       GLvertexformat vtxfmt;
+};
+
+/**
+ * R200 context structure.
+ */
+struct r200_context {
+       struct radeon_context radeon; /* parent class, must be first */
+
+       /* Driver and hardware state management
+        */
+       struct r200_hw_state hw;
+       struct r200_state state;
+
+       /* Texture object bookkeeping
+        */
+       unsigned nr_heaps;
+       driTexHeap *texture_heaps[R200_NR_TEX_HEAPS];
+       driTextureObject swapped;
+       int texture_depth;
+       float initialMaxAnisotropy;
+
+       /* Rasterization and vertex state:
+        */
+       GLuint NewGLState;
+
+       /* Vertex buffers
+        */
+       struct r200_ioctl ioctl;
+       struct r200_dma dma;
+       struct r200_store store;
+       GLboolean save_on_next_unlock;
+
+       /* Clientdata textures;
+        */
+       GLuint prefer_gart_client_texturing;
+
+       /* TCL stuff
+        */
+       GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS];
+       GLboolean recheck_texgen[R200_MAX_TEXTURE_UNITS];
+       GLboolean TexGenNeedNormals[R200_MAX_TEXTURE_UNITS];
+       GLuint TexMatEnabled;
+       GLuint TexMatCompSel;
+       GLuint TexGenEnabled;
+       GLuint TexGenInputs;
+       GLuint TexGenCompSel;
+       GLmatrix tmpmat;
+
+       /* r200_tcl.c
+        */
+       struct r200_tcl_info tcl;
+
+       /* r200_swtcl.c
+        */
+       struct r200_swtcl_info swtcl;
+
+       /* r200_vtxfmt.c
+        */
+       struct r200_vbinfo vb;
+};
+
+#define R200_CONTEXT(ctx)              ((r200ContextPtr)(ctx->DriverCtx))
+
+extern void r200DestroyContext(__DRIcontextPrivate * driContextPriv);
+extern GLboolean r200CreateContext(const __GLcontextModes * glVisual,
+                                  __DRIcontextPrivate * driContextPriv,
+                                  void *sharedContextPrivate);
+
+#endif
+#endif                         /* __R200_CONTEXT_H__ */
diff --git a/src/mesa/drivers/dri/r300/r200_ioctl.h b/src/mesa/drivers/dri/r300/r200_ioctl.h
new file mode 100644 (file)
index 0000000..db7bd76
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef __R200_IOCTL_H__
+#define __R200_IOCTL_H__
+
+#include "simple_list.h"
+#include "radeon_dri.h"
+#include "radeon_lock.h"
+
+#include "xf86drm.h"
+#include "drm.h"
+#include "r200_context.h"
+#include "radeon_drm.h"
+
+extern void r200EmitState(r200ContextPtr rmesa);
+extern void r200EmitVertexAOS(r200ContextPtr rmesa,
+                             GLuint vertex_size, GLuint offset);
+
+extern void r200EmitVbufPrim(r200ContextPtr rmesa,
+                            GLuint primitive, GLuint vertex_nr);
+
+extern void r200FlushElts(r200ContextPtr rmesa);
+
+extern GLushort *r200AllocEltsOpenEnded(r200ContextPtr rmesa,
+                                       GLuint primitive, GLuint min_nr);
+
+extern void r200EmitAOS(r200ContextPtr rmesa,
+                       struct r200_dma_region **regions,
+                       GLuint n, GLuint offset);
+
+extern void r200EmitBlit(r200ContextPtr rmesa,
+                        GLuint color_fmt,
+                        GLuint src_pitch,
+                        GLuint src_offset,
+                        GLuint dst_pitch,
+                        GLuint dst_offset,
+                        GLint srcx, GLint srcy,
+                        GLint dstx, GLint dsty, GLuint w, GLuint h);
+
+extern void r200EmitWait(r200ContextPtr rmesa, GLuint flags);
+
+extern void r200FlushCmdBuf(r200ContextPtr rmesa, const char *);
+extern int r200FlushCmdBufLocked(r200ContextPtr rmesa, const char *caller);
+extern void r200Flush(GLcontext * ctx);
+
+extern void r200RefillCurrentDmaRegion(r200ContextPtr rmesa);
+
+extern void r200AllocDmaRegion(r200ContextPtr rmesa,
+                              struct r200_dma_region *region,
+                              int bytes, int alignment);
+
+extern void r200AllocDmaRegionVerts(r200ContextPtr rmesa,
+                                   struct r200_dma_region *region,
+                                   int numverts, int vertsize, int alignment);
+
+extern void r200ReleaseDmaRegion(r200ContextPtr rmesa,
+                                struct r200_dma_region *region,
+                                const char *caller);
+
+extern void r200WaitForVBlank(r200ContextPtr rmesa);
+extern void r200InitIoctlFuncs(struct dd_function_table *functions);
+
+extern void *r200AllocateMemoryMESA(__DRInativeDisplay * dpy, int scrn,
+                                   GLsizei size, GLfloat readfreq,
+                                   GLfloat writefreq, GLfloat priority);
+extern void r200FreeMemoryMESA(__DRInativeDisplay * dpy, int scrn,
+                              GLvoid * pointer);
+extern GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn,
+                                     const GLvoid * pointer);
+
+extern GLboolean r200IsGartMemory(r200ContextPtr rmesa, const GLvoid * pointer,
+                                 GLint size);
+
+extern GLuint r200GartOffsetFromVirtual(r200ContextPtr rmesa,
+                                       const GLvoid * pointer);
+
+void r200SaveHwState(r200ContextPtr radeon);
+void r200SetUpAtomList(r200ContextPtr rmesa);
+
+/* ================================================================
+ * Helper macros:
+ */
+
+/* Close off the last primitive, if it exists.
+ */
+#define R200_NEWPRIM( rmesa )                  \
+do {                                           \
+   if ( rmesa->dma.flush )                     \
+      rmesa->dma.flush( rmesa );       \
+} while (0)
+
+/* Can accomodate several state changes and primitive changes without
+ * actually firing the buffer.
+ */
+#define R200_STATECHANGE( rmesa, ATOM )                        \
+do {                                                           \
+   R200_NEWPRIM( rmesa );                                      \
+   rmesa->hw.ATOM.dirty = GL_TRUE;                             \
+   rmesa->hw.is_dirty = GL_TRUE;                               \
+} while (0)
+
+#define R200_DB_STATE( ATOM )                          \
+   memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \
+          rmesa->hw.ATOM.cmd_size * 4)
+
+static __inline int R200_DB_STATECHANGE(r200ContextPtr rmesa,
+                                       struct r200_state_atom *atom)
+{
+       if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size * 4)) {
+               int *tmp;
+               R200_NEWPRIM(rmesa);
+               atom->dirty = GL_TRUE;
+               rmesa->hw.is_dirty = GL_TRUE;
+               tmp = atom->cmd;
+               atom->cmd = atom->lastcmd;
+               atom->lastcmd = tmp;
+               return 1;
+       } else
+               return 0;
+}
+
+/* Fire the buffered vertices no matter what.
+ */
+#define R200_FIREVERTICES( r200 )                      \
+do {                                                   \
+   if ( (r200)->store.cmd_used || (r200)->dma.flush ) {        \
+      radeonFlush( (r200)->radeon.glCtx );             \
+   }                                                   \
+} while (0)
+
+/* Command lengths.  Note that any time you ensure ELTS_BUFSZ or VBUF_BUFSZ
+ * are available, you will also be adding an rmesa->state.max_state_size because
+ * r200EmitState is called from within r200EmitVbufPrim and r200FlushElts.
+ */
+#define AOS_BUFSZ(nr)  ((3 + ((nr / 2) * 3) + ((nr & 1) * 2)) * sizeof(int))
+#define VERT_AOS_BUFSZ (5 * sizeof(int))
+#define ELTS_BUFSZ(nr) (12 + nr * 2)
+#define VBUF_BUFSZ     (3 * sizeof(int))
+
+/* Ensure that a minimum amount of space is available in the command buffer.
+ * This is used to ensure atomicity of state updates with the rendering requests
+ * that rely on them.
+ *
+ * An alternative would be to implement a "soft lock" such that when the buffer
+ * wraps at an inopportune time, we grab the lock, flush the current buffer,
+ * and hang on to the lock until the critical section is finished and we flush
+ * the buffer again and unlock.
+ */
+static __inline void r200EnsureCmdBufSpace(r200ContextPtr rmesa, int bytes)
+{
+       if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ)
+               r200FlushCmdBuf(rmesa, __FUNCTION__);
+       assert(bytes <= R200_CMD_BUF_SZ);
+}
+
+/* Alloc space in the command buffer
+ */
+static __inline char *r200AllocCmdBuf(r200ContextPtr rmesa,
+                                     int bytes, const char *where)
+{
+       char *head;
+
+       if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ)
+               r200FlushCmdBuf(rmesa, where);
+
+       head = rmesa->store.cmd_buf + rmesa->store.cmd_used;
+       rmesa->store.cmd_used += bytes;
+       assert(rmesa->store.cmd_used <= R200_CMD_BUF_SZ);
+       return head;
+}
+
+#endif                         /* __R200_IOCTL_H__ */
diff --git a/src/mesa/drivers/dri/r300/r200_reg.h b/src/mesa/drivers/dri/r300/r200_reg.h
new file mode 100644 (file)
index 0000000..1336e96
--- /dev/null
@@ -0,0 +1,1423 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_reg.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef _R200_REG_H_
+#define _R200_REG_H_
+
+#define R200_PP_MISC                      0x1c14
+#define     R200_REF_ALPHA_MASK        0x000000ff
+#define     R200_ALPHA_TEST_FAIL       (0 << 8)
+#define     R200_ALPHA_TEST_LESS       (1 << 8)
+#define     R200_ALPHA_TEST_LEQUAL     (2 << 8)
+#define     R200_ALPHA_TEST_EQUAL      (3 << 8)
+#define     R200_ALPHA_TEST_GEQUAL     (4 << 8)
+#define     R200_ALPHA_TEST_GREATER    (5 << 8)
+#define     R200_ALPHA_TEST_NEQUAL     (6 << 8)
+#define     R200_ALPHA_TEST_PASS       (7 << 8)
+#define     R200_ALPHA_TEST_OP_MASK    (7 << 8)
+#define     R200_CHROMA_FUNC_FAIL      (0 << 16)
+#define     R200_CHROMA_FUNC_PASS      (1 << 16)
+#define     R200_CHROMA_FUNC_NEQUAL    (2 << 16)
+#define     R200_CHROMA_FUNC_EQUAL     (3 << 16)
+#define     R200_CHROMA_KEY_NEAREST    (0 << 18)
+#define     R200_CHROMA_KEY_ZERO       (1 << 18)
+#define     R200_RIGHT_HAND_CUBE_D3D   (0 << 24)
+#define     R200_RIGHT_HAND_CUBE_OGL   (1 << 24)
+#define R200_PP_FOG_COLOR                 0x1c18
+#define     R200_FOG_COLOR_MASK        0x00ffffff
+#define     R200_FOG_VERTEX            (0 << 24)
+#define     R200_FOG_TABLE             (1 << 24)
+#define     R200_FOG_USE_DEPTH         (0 << 25)
+#define     R200_FOG_USE_W             (1 << 25)
+#define     R200_FOG_USE_DIFFUSE_ALPHA (2 << 25)
+#define     R200_FOG_USE_SPEC_ALPHA    (3 << 25)
+#define     R200_FOG_USE_VTX_FOG       (4 << 25)
+#define     R200_FOG_USE_MASK          (7 << 25)
+#define R200_RE_SOLID_COLOR               0x1c1c
+#define R200_RB3D_BLENDCNTL               0x1c20
+#define     R200_COMB_FCN_MASK                    (7  << 12)
+#define     R200_COMB_FCN_ADD_CLAMP               (0  << 12)
+#define     R200_COMB_FCN_ADD_NOCLAMP             (1  << 12)
+#define     R200_COMB_FCN_SUB_CLAMP               (2  << 12)
+#define     R200_COMB_FCN_SUB_NOCLAMP             (3  << 12)
+#define     R200_COMB_FCN_MIN                     (4  << 12)
+#define     R200_COMB_FCN_MAX                     (5  << 12)
+#define     R200_COMB_FCN_RSUB_CLAMP              (6  << 12)
+#define     R200_COMB_FCN_RSUB_NOCLAMP            (7  << 12)
+#define       R200_BLEND_GL_ZERO                  (32)
+#define       R200_BLEND_GL_ONE                   (33)
+#define       R200_BLEND_GL_SRC_COLOR             (34)
+#define       R200_BLEND_GL_ONE_MINUS_SRC_COLOR   (35)
+#define       R200_BLEND_GL_DST_COLOR             (36)
+#define       R200_BLEND_GL_ONE_MINUS_DST_COLOR   (37)
+#define       R200_BLEND_GL_SRC_ALPHA             (38)
+#define       R200_BLEND_GL_ONE_MINUS_SRC_ALPHA   (39)
+#define       R200_BLEND_GL_DST_ALPHA             (40)
+#define       R200_BLEND_GL_ONE_MINUS_DST_ALPHA   (41)
+#define       R200_BLEND_GL_SRC_ALPHA_SATURATE    (42) /* src factor only */
+#define       R200_BLEND_GL_CONST_COLOR           (43)
+#define       R200_BLEND_GL_ONE_MINUS_CONST_COLOR (44)
+#define       R200_BLEND_GL_CONST_ALPHA           (45)
+#define       R200_BLEND_GL_ONE_MINUS_CONST_ALPHA (46)
+#define       R200_BLEND_MASK                     (63)
+#define     R200_SRC_BLEND_SHIFT                  (16)
+#define     R200_DST_BLEND_SHIFT                  (24)
+#define R200_RB3D_DEPTHOFFSET             0x1c24
+#define R200_RB3D_DEPTHPITCH              0x1c28
+#define     R200_DEPTHPITCH_MASK         0x00001ff8
+#define     R200_DEPTH_ENDIAN_NO_SWAP    (0 << 18)
+#define     R200_DEPTH_ENDIAN_WORD_SWAP  (1 << 18)
+#define     R200_DEPTH_ENDIAN_DWORD_SWAP (2 << 18)
+#define R200_RB3D_ZSTENCILCNTL            0x1c2c
+#define     R200_DEPTH_FORMAT_MASK          (0xf << 0)
+#define     R200_DEPTH_FORMAT_16BIT_INT_Z   (0  <<  0)
+#define     R200_DEPTH_FORMAT_24BIT_INT_Z   (2  <<  0)
+#define     R200_DEPTH_FORMAT_24BIT_FLOAT_Z (3  <<  0)
+#define     R200_DEPTH_FORMAT_32BIT_INT_Z   (4  <<  0)
+#define     R200_DEPTH_FORMAT_32BIT_FLOAT_Z (5  <<  0)
+#define     R200_DEPTH_FORMAT_24BIT_FLOAT_W (9  <<  0)
+#define     R200_DEPTH_FORMAT_32BIT_FLOAT_W (11 <<  0)
+#define     R200_Z_TEST_NEVER               (0  <<  4)
+#define     R200_Z_TEST_LESS                (1  <<  4)
+#define     R200_Z_TEST_LEQUAL              (2  <<  4)
+#define     R200_Z_TEST_EQUAL               (3  <<  4)
+#define     R200_Z_TEST_GEQUAL              (4  <<  4)
+#define     R200_Z_TEST_GREATER             (5  <<  4)
+#define     R200_Z_TEST_NEQUAL              (6  <<  4)
+#define     R200_Z_TEST_ALWAYS              (7  <<  4)
+#define     R200_Z_TEST_MASK                (7  <<  4)
+#define     R200_STENCIL_TEST_NEVER         (0  << 12)
+#define     R200_STENCIL_TEST_LESS          (1  << 12)
+#define     R200_STENCIL_TEST_LEQUAL        (2  << 12)
+#define     R200_STENCIL_TEST_EQUAL         (3  << 12)
+#define     R200_STENCIL_TEST_GEQUAL        (4  << 12)
+#define     R200_STENCIL_TEST_GREATER       (5  << 12)
+#define     R200_STENCIL_TEST_NEQUAL        (6  << 12)
+#define     R200_STENCIL_TEST_ALWAYS        (7  << 12)
+#define     R200_STENCIL_TEST_MASK          (0x7 << 12)
+#define     R200_STENCIL_FAIL_KEEP          (0  << 16)
+#define     R200_STENCIL_FAIL_ZERO          (1  << 16)
+#define     R200_STENCIL_FAIL_REPLACE       (2  << 16)
+#define     R200_STENCIL_FAIL_INC           (3  << 16)
+#define     R200_STENCIL_FAIL_DEC           (4  << 16)
+#define     R200_STENCIL_FAIL_INVERT        (5  << 16)
+#define     R200_STENCIL_FAIL_INC_WRAP      (6  << 16)
+#define     R200_STENCIL_FAIL_DEC_WRAP      (7  << 16)
+#define     R200_STENCIL_FAIL_MASK          (0x7 << 16)
+#define     R200_STENCIL_ZPASS_KEEP         (0  << 20)
+#define     R200_STENCIL_ZPASS_ZERO         (1  << 20)
+#define     R200_STENCIL_ZPASS_REPLACE      (2  << 20)
+#define     R200_STENCIL_ZPASS_INC          (3  << 20)
+#define     R200_STENCIL_ZPASS_DEC          (4  << 20)
+#define     R200_STENCIL_ZPASS_INVERT       (5  << 20)
+#define     R200_STENCIL_ZPASS_INC_WRAP     (6  << 20)
+#define     R200_STENCIL_ZPASS_DEC_WRAP     (7  << 20)
+#define     R200_STENCIL_ZPASS_MASK         (0x7 << 20)
+#define     R200_STENCIL_ZFAIL_KEEP         (0  << 24)
+#define     R200_STENCIL_ZFAIL_ZERO         (1  << 24)
+#define     R200_STENCIL_ZFAIL_REPLACE      (2  << 24)
+#define     R200_STENCIL_ZFAIL_INC          (3  << 24)
+#define     R200_STENCIL_ZFAIL_DEC          (4  << 24)
+#define     R200_STENCIL_ZFAIL_INVERT       (5  << 24)
+#define     R200_STENCIL_ZFAIL_INC_WRAP     (6  << 24)
+#define     R200_STENCIL_ZFAIL_DEC_WRAP     (7  << 24)
+#define     R200_STENCIL_ZFAIL_MASK         (0x7 << 24)
+#define     R200_Z_WRITE_ENABLE             (1  << 30)
+/*gap*/
+#define R200_PP_CNTL                      0x1c38
+#define     R200_TEX_0_ENABLE                         0x00000010
+#define     R200_TEX_1_ENABLE                         0x00000020
+#define     R200_TEX_2_ENABLE                         0x00000040
+#define     R200_TEX_3_ENABLE                         0x00000080
+#define     R200_TEX_4_ENABLE                         0x00000100
+#define     R200_TEX_5_ENABLE                         0x00000200
+#define     R200_TEX_ENABLE_MASK                      0x000003f0
+#define     R200_FILTER_ROUND_MODE_MASK               0x00000400
+#define     R200_TEX_BLEND_7_ENABLE                   0x00000800
+#define     R200_TEX_BLEND_0_ENABLE                   0x00001000
+#define     R200_TEX_BLEND_1_ENABLE                   0x00002000
+#define     R200_TEX_BLEND_2_ENABLE                   0x00004000
+#define     R200_TEX_BLEND_3_ENABLE                   0x00008000
+#define     R200_TEX_BLEND_4_ENABLE                   0x00010000
+#define     R200_TEX_BLEND_5_ENABLE                   0x00020000
+#define     R200_TEX_BLEND_6_ENABLE                   0x00040000
+#define     R200_MULTI_PASS_ENABLE                    0x00080000
+#define     R200_SPECULAR_ENABLE                      0x00200000
+#define     R200_FOG_ENABLE                           0x00400000
+#define     R200_ALPHA_TEST_ENABLE                    0x00800000
+#define     R200_ANTI_ALIAS_NONE                       0x00000000
+#define     R200_ANTI_ALIAS_LINE                       0x01000000
+#define     R200_ANTI_ALIAS_POLY                       0x02000000
+#define     R200_ANTI_ALIAS_MASK                       0x03000000
+#define R200_RB3D_CNTL                    0x1c3c
+#define     R200_ALPHA_BLEND_ENABLE       (1  <<  0)
+#define     R200_PLANE_MASK_ENABLE        (1  <<  1)
+#define     R200_DITHER_ENABLE            (1  <<  2)
+#define     R200_ROUND_ENABLE             (1  <<  3)
+#define     R200_SCALE_DITHER_ENABLE      (1  <<  4)
+#define     R200_DITHER_INIT              (1  <<  5)
+#define     R200_ROP_ENABLE               (1  <<  6)
+#define     R200_STENCIL_ENABLE           (1  <<  7)
+#define     R200_Z_ENABLE                 (1  <<  8)
+#define     R200_DEPTH_XZ_OFFEST_ENABLE   (1  <<  9)
+#define     R200_COLOR_FORMAT_ARGB1555    (3  << 10)
+#define     R200_COLOR_FORMAT_RGB565      (4  << 10)
+#define     R200_COLOR_FORMAT_ARGB8888    (6  << 10)
+#define     R200_COLOR_FORMAT_RGB332      (7  << 10)
+#define     R200_COLOR_FORMAT_Y8          (8  << 10)
+#define     R200_COLOR_FORMAT_RGB8        (9  << 10)
+#define     R200_COLOR_FORMAT_YUV422_VYUY (11 << 10)
+#define     R200_COLOR_FORMAT_YUV422_YVYU (12 << 10)
+#define     R200_COLOR_FORMAT_aYUV444     (14 << 10)
+#define     R200_COLOR_FORMAT_ARGB4444    (15 << 10)
+#define     R200_CLRCMP_FLIP_ENABLE       (1  << 14)
+#define     R200_SEPARATE_ALPHA_ENABLE    (1  << 16)
+#define R200_RB3D_COLOROFFSET             0x1c40
+#define     R200_COLOROFFSET_MASK      0xfffffff0
+#define R200_RE_WIDTH_HEIGHT              0x1c44
+#define     R200_RE_WIDTH_SHIFT        0
+#define     R200_RE_HEIGHT_SHIFT       16
+#define R200_RB3D_COLORPITCH              0x1c48
+#define     R200_COLORPITCH_MASK         0x000001ff8
+#define     R200_COLOR_ENDIAN_NO_SWAP    (0 << 18)
+#define     R200_COLOR_ENDIAN_WORD_SWAP  (1 << 18)
+#define     R200_COLOR_ENDIAN_DWORD_SWAP (2 << 18)
+#define R200_SE_CNTL                      0x1c4c
+#define     R200_FFACE_CULL_CW          (0 <<  0)
+#define     R200_FFACE_CULL_CCW         (1 <<  0)
+#define     R200_FFACE_CULL_DIR_MASK    (1 <<  0)
+#define     R200_BFACE_CULL             (0 <<  1)
+#define     R200_BFACE_SOLID            (3 <<  1)
+#define     R200_FFACE_CULL             (0 <<  3)
+#define     R200_FFACE_SOLID            (3 <<  3)
+#define     R200_FFACE_CULL_MASK        (3 <<  3)
+#define     R200_FLAT_SHADE_VTX_0       (0 <<  6)
+#define     R200_FLAT_SHADE_VTX_1       (1 <<  6)
+#define     R200_FLAT_SHADE_VTX_2       (2 <<  6)
+#define     R200_FLAT_SHADE_VTX_LAST    (3 <<  6)
+#define     R200_DIFFUSE_SHADE_SOLID    (0 <<  8)
+#define     R200_DIFFUSE_SHADE_FLAT     (1 <<  8)
+#define     R200_DIFFUSE_SHADE_GOURAUD  (2 <<  8)
+#define     R200_DIFFUSE_SHADE_MASK     (3 <<  8)
+#define     R200_ALPHA_SHADE_SOLID      (0 << 10)
+#define     R200_ALPHA_SHADE_FLAT       (1 << 10)
+#define     R200_ALPHA_SHADE_GOURAUD    (2 << 10)
+#define     R200_ALPHA_SHADE_MASK       (3 << 10)
+#define     R200_SPECULAR_SHADE_SOLID   (0 << 12)
+#define     R200_SPECULAR_SHADE_FLAT    (1 << 12)
+#define     R200_SPECULAR_SHADE_GOURAUD (2 << 12)
+#define     R200_SPECULAR_SHADE_MASK    (3 << 12)
+#define     R200_FOG_SHADE_SOLID        (0 << 14)
+#define     R200_FOG_SHADE_FLAT         (1 << 14)
+#define     R200_FOG_SHADE_GOURAUD      (2 << 14)
+#define     R200_FOG_SHADE_MASK         (3 << 14)
+#define     R200_ZBIAS_ENABLE_POINT     (1 << 16)
+#define     R200_ZBIAS_ENABLE_LINE      (1 << 17)
+#define     R200_ZBIAS_ENABLE_TRI       (1 << 18)
+#define     R200_WIDELINE_ENABLE        (1 << 20)
+#define     R200_VTX_PIX_CENTER_D3D     (0 << 27)
+#define     R200_VTX_PIX_CENTER_OGL     (1 << 27)
+#define     R200_ROUND_MODE_TRUNC       (0 << 28)
+#define     R200_ROUND_MODE_ROUND       (1 << 28)
+#define     R200_ROUND_MODE_ROUND_EVEN  (2 << 28)
+#define     R200_ROUND_MODE_ROUND_ODD   (3 << 28)
+#define     R200_ROUND_PREC_16TH_PIX    (0 << 30)
+#define     R200_ROUND_PREC_8TH_PIX     (1 << 30)
+#define     R200_ROUND_PREC_4TH_PIX     (2 << 30)
+#define     R200_ROUND_PREC_HALF_PIX    (3 << 30)
+#define R200_RE_CNTL                      0x1c50
+#define     R200_STIPPLE_ENABLE                     0x1
+#define     R200_SCISSOR_ENABLE                     0x2
+#define     R200_PATTERN_ENABLE                     0x4
+#define     R200_PERSPECTIVE_ENABLE                 0x8
+#define     R200_POINT_SMOOTH                       0x20
+#define     R200_VTX_STQ0_D3D                       0x00010000
+#define     R200_VTX_STQ1_D3D                       0x00040000
+#define     R200_VTX_STQ2_D3D                       0x00100000
+#define     R200_VTX_STQ3_D3D                       0x00400000
+#define     R200_VTX_STQ4_D3D                       0x01000000
+#define     R200_VTX_STQ5_D3D                       0x04000000
+/* gap */
+#define R200_RE_STIPPLE_ADDR              0x1cc8
+#define R200_RE_STIPPLE_DATA              0x1ccc
+#define R200_RE_LINE_PATTERN              0x1cd0
+#define     R200_LINE_PATTERN_MASK             0x0000ffff
+#define     R200_LINE_REPEAT_COUNT_SHIFT       16
+#define     R200_LINE_PATTERN_START_SHIFT      24
+#define     R200_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28)
+#define     R200_LINE_PATTERN_BIG_BIT_ORDER    (1 << 28)
+#define     R200_LINE_PATTERN_AUTO_RESET       (1 << 29)
+#define R200_RE_LINE_STATE                0x1cd4
+#define     R200_LINE_CURRENT_PTR_SHIFT       0
+#define     R200_LINE_CURRENT_COUNT_SHIFT     8
+#define R200_RE_SCISSOR_TL_0              0x1cd8
+#define R200_RE_SCISSOR_BR_0              0x1cdc
+#define R200_RE_SCISSOR_TL_1              0x1ce0
+#define R200_RE_SCISSOR_BR_1              0x1ce4
+#define R200_RE_SCISSOR_TL_2              0x1ce8
+#define R200_RE_SCISSOR_BR_2              0x1cec
+/* gap */
+#define R200_RB3D_DEPTHXY_OFFSET          0x1d60
+#define     R200_DEPTHX_SHIFT  0
+#define     R200_DEPTHY_SHIFT  16
+/* gap */
+#define R200_RB3D_STENCILREFMASK          0x1d7c
+#define     R200_STENCIL_REF_SHIFT           0
+#define     R200_STENCIL_REF_MASK            (0xff << 0)
+#define     R200_STENCIL_MASK_SHIFT          16
+#define     R200_STENCIL_VALUE_MASK          (0xff << 16)
+#define     R200_STENCIL_WRITEMASK_SHIFT     24
+#define     R200_STENCIL_WRITE_MASK          (0xff << 24)
+#define R200_RB3D_ROPCNTL                 0x1d80
+#define     R200_ROP_MASK                    (15 << 8)
+#define     R200_ROP_CLEAR                   (0  << 8)
+#define     R200_ROP_NOR                     (1  << 8)
+#define     R200_ROP_AND_INVERTED            (2  << 8)
+#define     R200_ROP_COPY_INVERTED           (3  << 8)
+#define     R200_ROP_AND_REVERSE             (4  << 8)
+#define     R200_ROP_INVERT                  (5  << 8)
+#define     R200_ROP_XOR                     (6  << 8)
+#define     R200_ROP_NAND                    (7  << 8)
+#define     R200_ROP_AND                     (8  << 8)
+#define     R200_ROP_EQUIV                   (9  << 8)
+#define     R200_ROP_NOOP                    (10 << 8)
+#define     R200_ROP_OR_INVERTED             (11 << 8)
+#define     R200_ROP_COPY                    (12 << 8)
+#define     R200_ROP_OR_REVERSE              (13 << 8)
+#define     R200_ROP_OR                      (14 << 8)
+#define     R200_ROP_SET                     (15 << 8)
+#define R200_RB3D_PLANEMASK               0x1d84
+/* gap */
+#define R200_SE_VPORT_XSCALE              0x1d98
+#define R200_SE_VPORT_XOFFSET             0x1d9c
+#define R200_SE_VPORT_YSCALE              0x1da0
+#define R200_SE_VPORT_YOFFSET             0x1da4
+#define R200_SE_VPORT_ZSCALE              0x1da8
+#define R200_SE_VPORT_ZOFFSET             0x1dac
+#define R200_SE_ZBIAS_FACTOR              0x1db0
+#define R200_SE_ZBIAS_CONSTANT            0x1db4
+#define R200_SE_LINE_WIDTH                0x1db8
+#define            R200_LINE_WIDTH_SHIFT                   0x00000000
+#define            R200_MINPOINTSIZE_SHIFT                 0x00000010
+/* gap */
+#define R200_SE_VAP_CNTL                           0x2080
+#define     R200_VAP_TCL_ENABLE                       0x00000001
+#define     R200_VAP_SINGLE_BUF_STATE_ENABLE          0x00000010
+#define     R200_VAP_FORCE_W_TO_ONE                   0x00010000
+#define     R200_VAP_D3D_TEX_DEFAULT                  0x00020000
+#define     R200_VAP_VF_MAX_VTX_NUM__SHIFT            18
+#define     R200_VAP_DX_CLIP_SPACE_DEF                0x00400000
+#define R200_SE_VF_CNTL                           0x2084
+#define     R200_VF_PRIM_NONE                         0x00000000
+#define     R200_VF_PRIM_POINTS                       0x00000001
+#define     R200_VF_PRIM_LINES                        0x00000002
+#define     R200_VF_PRIM_LINE_STRIP                   0x00000003
+#define     R200_VF_PRIM_TRIANGLES                    0x00000004
+#define     R200_VF_PRIM_TRIANGLE_FAN                 0x00000005
+#define     R200_VF_PRIM_TRIANGLE_STRIP               0x00000006
+#define     R200_VF_PRIM_RECT_LIST                    0x00000008
+#define     R200_VF_PRIM_3VRT_POINTS                  0x00000009
+#define     R200_VF_PRIM_3VRT_LINES                   0x0000000a
+#define     R200_VF_PRIM_POINT_SPRITES                0x0000000b
+#define     R200_VF_PRIM_LINE_LOOP                    0x0000000c
+#define     R200_VF_PRIM_QUADS                        0x0000000d
+#define     R200_VF_PRIM_QUAD_STRIP                   0x0000000e
+#define     R200_VF_PRIM_POLYGON                      0x0000000f
+#define     R200_VF_PRIM_MASK                         0x0000000f
+#define     R200_VF_PRIM_WALK_IND                     0x00000010
+#define     R200_VF_PRIM_WALK_LIST                    0x00000020
+#define     R200_VF_PRIM_WALK_RING                    0x00000030
+#define     R200_VF_PRIM_WALK_MASK                    0x00000030
+#define     R200_VF_COLOR_ORDER_RGBA                  0x00000040
+#define     R200_VF_TCL_OUTPUT_VTX_ENABLE             0x00000200
+#define     R200_VF_INDEX_SZ_4                        0x00000800
+#define     R200_VF_VERTEX_NUMBER_MASK                0xffff0000
+#define     R200_VF_VERTEX_NUMBER_SHIFT               16
+#define R200_SE_VTX_FMT_0                 0x2088
+#define     R200_VTX_XY                     0  /* always have xy */
+#define     R200_VTX_Z0                     (1<<0)
+#define     R200_VTX_W0                     (1<<1)
+#define     R200_VTX_WEIGHT_COUNT_SHIFT     (2)
+#define     R200_VTX_PV_MATRIX_SEL          (1<<5)
+#define     R200_VTX_N0                     (1<<6)
+#define     R200_VTX_POINT_SIZE             (1<<7)
+#define     R200_VTX_DISCRETE_FOG           (1<<8)
+#define     R200_VTX_SHININESS_0            (1<<9)
+#define     R200_VTX_SHININESS_1            (1<<10)
+#define       R200_VTX_COLOR_NOT_PRESENT      0
+#define       R200_VTX_PK_RGBA          1
+#define       R200_VTX_FP_RGB           2
+#define       R200_VTX_FP_RGBA          3
+#define       R200_VTX_COLOR_MASK             3
+#define     R200_VTX_COLOR_0_SHIFT          11
+#define     R200_VTX_COLOR_1_SHIFT          13
+#define     R200_VTX_COLOR_2_SHIFT          15
+#define     R200_VTX_COLOR_3_SHIFT          17
+#define     R200_VTX_COLOR_4_SHIFT          19
+#define     R200_VTX_COLOR_5_SHIFT          21
+#define     R200_VTX_COLOR_6_SHIFT          23
+#define     R200_VTX_COLOR_7_SHIFT          25
+#define     R200_VTX_XY1                    (1<<28)
+#define     R200_VTX_Z1                     (1<<29)
+#define     R200_VTX_W1                     (1<<30)
+#define     R200_VTX_N1                     (1<<31)
+#define R200_SE_VTX_FMT_1                 0x208c
+#define     R200_VTX_TEX0_COMP_CNT_SHIFT        0
+#define     R200_VTX_TEX1_COMP_CNT_SHIFT        3
+#define     R200_VTX_TEX2_COMP_CNT_SHIFT        6
+#define     R200_VTX_TEX3_COMP_CNT_SHIFT        9
+#define     R200_VTX_TEX4_COMP_CNT_SHIFT        12
+#define     R200_VTX_TEX5_COMP_CNT_SHIFT        15
+#define R200_SE_TCL_OUTPUT_VTX_FMT_0      0x2090
+#define R200_SE_TCL_OUTPUT_VTX_FMT_1      0x2094
+/* gap */
+#define R200_SE_VTE_CNTL                  0x20b0
+#define     R200_VPORT_X_SCALE_ENA                0x00000001
+#define     R200_VPORT_X_OFFSET_ENA               0x00000002
+#define     R200_VPORT_Y_SCALE_ENA                0x00000004
+#define     R200_VPORT_Y_OFFSET_ENA               0x00000008
+#define     R200_VPORT_Z_SCALE_ENA                0x00000010
+#define     R200_VPORT_Z_OFFSET_ENA               0x00000020
+#define     R200_VTX_XY_FMT                       0x00000100
+#define     R200_VTX_Z_FMT                        0x00000200
+#define     R200_VTX_W0_FMT                       0x00000400
+#define     R200_VTX_W0_NORMALIZE                 0x00000800
+#define     R200_VTX_ST_DENORMALIZED              0x00001000
+/* gap */
+#define R200_SE_VTX_NUM_ARRAYS            0x20c0
+#define R200_SE_VTX_AOS_ATTR01            0x20c4
+#define R200_SE_VTX_AOS_ADDR0             0x20c8
+#define R200_SE_VTX_AOS_ADDR1             0x20cc
+#define R200_SE_VTX_AOS_ATTR23            0x20d0
+#define R200_SE_VTX_AOS_ADDR2             0x20d4
+#define R200_SE_VTX_AOS_ADDR3             0x20d8
+#define R200_SE_VTX_AOS_ATTR45            0x20dc
+#define R200_SE_VTX_AOS_ADDR4             0x20e0
+#define R200_SE_VTX_AOS_ADDR5             0x20e4
+#define R200_SE_VTX_AOS_ATTR67            0x20e8
+#define R200_SE_VTX_AOS_ADDR6             0x20ec
+#define R200_SE_VTX_AOS_ADDR7             0x20f0
+#define R200_SE_VTX_AOS_ATTR89            0x20f4
+#define R200_SE_VTX_AOS_ADDR8             0x20f8
+#define R200_SE_VTX_AOS_ADDR9             0x20fc
+#define R200_SE_VTX_AOS_ATTR1011          0x2100
+#define R200_SE_VTX_AOS_ADDR10            0x2104
+#define R200_SE_VTX_AOS_ADDR11            0x2108
+#define R200_SE_VF_MAX_VTX_INDX           0x210c
+#define R200_SE_VF_MIN_VTX_INDX           0x2110
+/* gap */
+#define R200_SE_VAP_CNTL_STATUS           0x2140
+#define     R200_VC_NO_SWAP                  (0 << 0)
+#define     R200_VC_16BIT_SWAP               (1 << 0)
+#define     R200_VC_32BIT_SWAP               (2 << 0)
+/* gap */
+#define R200_SE_VTX_STATE_CNTL                     0x2180
+#define     R200_VSC_COLOR_0_ASSEMBLY_CNTL_SHIFT    0x00000000
+#define     R200_VSC_COLOR_1_ASSEMBLY_CNTL_SHIFT    0x00000002
+#define     R200_VSC_COLOR_2_ASSEMBLY_CNTL_SHIFT    0x00000004
+#define     R200_VSC_COLOR_3_ASSEMBLY_CNTL_SHIFT    0x00000006
+#define     R200_VSC_COLOR_4_ASSEMBLY_CNTL_SHIFT    0x00000008
+#define     R200_VSC_COLOR_5_ASSEMBLY_CNTL_SHIFT    0x0000000a
+#define     R200_VSC_COLOR_6_ASSEMBLY_CNTL_SHIFT    0x0000000c
+#define     R200_VSC_COLOR_7_ASSEMBLY_CNTL_SHIFT    0x0000000e
+#define     R200_VSC_UPDATE_USER_COLOR_0_ENABLE    0x00010000
+#define     R200_VSC_UPDATE_USER_COLOR_1_ENABLE    0x00020000
+/* gap */
+#define R200_SE_TCL_VECTOR_INDX_REG                0x2200
+#define R200_SE_TCL_VECTOR_DATA_REG                0x2204
+#define R200_SE_TCL_SCALAR_INDX_REG                0x2208
+#define R200_SE_TCL_SCALAR_DATA_REG                0x220c
+/* gap */
+#define R200_SE_TCL_MATRIX_SEL_0                   0x2230
+#define     R200_MODELVIEW_0_SHIFT           (0)
+#define     R200_MODELVIEW_1_SHIFT           (8)
+#define     R200_MODELVIEW_2_SHIFT           (16)
+#define     R200_MODELVIEW_3_SHIFT           (24)
+#define R200_SE_TCL_MATRIX_SEL_1                   0x2234
+#define     R200_IT_MODELVIEW_0_SHIFT        (0)
+#define     R200_IT_MODELVIEW_1_SHIFT        (8)
+#define     R200_IT_MODELVIEW_2_SHIFT        (16)
+#define     R200_IT_MODELVIEW_3_SHIFT        (24)
+#define R200_SE_TCL_MATRIX_SEL_2                   0x2238
+#define     R200_MODELPROJECT_0_SHIFT         (0)
+#define     R200_MODELPROJECT_1_SHIFT         (8)
+#define     R200_MODELPROJECT_2_SHIFT         (16)
+#define     R200_MODELPROJECT_3_SHIFT         (24)
+#define R200_SE_TCL_MATRIX_SEL_3                   0x223c
+#define     R200_TEXMAT_0_SHIFT    0
+#define     R200_TEXMAT_1_SHIFT    8
+#define     R200_TEXMAT_2_SHIFT    16
+#define     R200_TEXMAT_3_SHIFT    24
+#define R200_SE_TCL_MATRIX_SEL_4                   0x2240
+#define     R200_TEXMAT_4_SHIFT    0
+#define     R200_TEXMAT_5_SHIFT    8
+/* gap */
+#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL     0x2250
+#define     R200_OUTPUT_XYZW                    (1<<0)
+#define     R200_OUTPUT_COLOR_0                 (1<<8)
+#define     R200_OUTPUT_COLOR_1                 (1<<9)
+#define     R200_OUTPUT_TEX_0                   (1<<16)
+#define     R200_OUTPUT_TEX_1                   (1<<17)
+#define     R200_OUTPUT_TEX_2                   (1<<18)
+#define     R200_OUTPUT_TEX_3                   (1<<19)
+#define     R200_OUTPUT_TEX_4                   (1<<20)
+#define     R200_OUTPUT_TEX_5                   (1<<21)
+#define     R200_OUTPUT_TEX_MASK                (0x3f<<16)
+#define     R200_OUTPUT_DISCRETE_FOG            (1<<24)
+#define     R200_OUTPUT_PT_SIZE                 (1<<25)
+#define     R200_FORCE_INORDER_PROC             (1<<31)
+#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0  0x2254
+#define            R200_VERTEX_POSITION_ADDR__SHIFT     0x00000000
+#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_1  0x2258
+#define            R200_VTX_COLOR_0_ADDR__SHIFT         0x00000000
+#define            R200_VTX_COLOR_1_ADDR__SHIFT         0x00000008
+#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_2  0x225c
+#define            R200_VTX_TEX_0_ADDR__SHIFT           0x00000000
+#define            R200_VTX_TEX_1_ADDR__SHIFT           0x00000008
+#define            R200_VTX_TEX_2_ADDR__SHIFT           0x00000010
+#define            R200_VTX_TEX_3_ADDR__SHIFT           0x00000018
+#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_3  0x2260
+#define            R200_VTX_TEX_4_ADDR__SHIFT           0x00000000
+#define            R200_VTX_TEX_5_ADDR__SHIFT           0x00000008
+
+/* gap */
+#define R200_SE_TCL_LIGHT_MODEL_CTL_0       0x2268
+#define     R200_LIGHTING_ENABLE                (1<<0)
+#define     R200_LIGHT_IN_MODELSPACE            (1<<1)
+#define     R200_LOCAL_VIEWER                   (1<<2)
+#define     R200_NORMALIZE_NORMALS              (1<<3)
+#define     R200_RESCALE_NORMALS                (1<<4)
+#define     R200_SPECULAR_LIGHTS                (1<<5)
+#define     R200_DIFFUSE_SPECULAR_COMBINE       (1<<6)
+#define     R200_LIGHT_ALPHA                    (1<<7)
+#define     R200_LOCAL_LIGHT_VEC_GL             (1<<8)
+#define     R200_LIGHT_NO_NORMAL_AMBIENT_ONLY   (1<<9)
+#define     R200_LIGHT_TWOSIDE                  (1<<10)
+#define     R200_FRONT_SHININESS_SOURCE_SHIFT       (0xb)
+#define     R200_BACK_SHININESS_SOURCE_SHIFT        (0xd)
+#define       R200_LM0_SOURCE_MATERIAL_0           (0)
+#define       R200_LM0_SOURCE_MATERIAL_1           (1)
+#define       R200_LM0_SOURCE_VERTEX_SHININESS_0   (2)
+#define       R200_LM0_SOURCE_VERTEX_SHININESS_1   (3)
+#define R200_SE_TCL_LIGHT_MODEL_CTL_1       0x226c
+#define       R200_LM1_SOURCE_LIGHT_PREMULT        (0)
+#define       R200_LM1_SOURCE_MATERIAL_0           (1)
+#define       R200_LM1_SOURCE_VERTEX_COLOR_0       (2)
+#define       R200_LM1_SOURCE_VERTEX_COLOR_1       (3)
+#define       R200_LM1_SOURCE_VERTEX_COLOR_2       (4)
+#define       R200_LM1_SOURCE_VERTEX_COLOR_3       (5)
+#define       R200_LM1_SOURCE_VERTEX_COLOR_4       (6)
+#define       R200_LM1_SOURCE_VERTEX_COLOR_5       (7)
+#define       R200_LM1_SOURCE_VERTEX_COLOR_6       (8)
+#define       R200_LM1_SOURCE_VERTEX_COLOR_7       (9)
+#define       R200_LM1_SOURCE_MATERIAL_1           (0xf)
+#define     R200_FRONT_EMISSIVE_SOURCE_SHIFT        (0)
+#define     R200_FRONT_AMBIENT_SOURCE_SHIFT         (4)
+#define     R200_FRONT_DIFFUSE_SOURCE_SHIFT         (8)
+#define     R200_FRONT_SPECULAR_SOURCE_SHIFT        (12)
+#define     R200_BACK_EMISSIVE_SOURCE_SHIFT         (16)
+#define     R200_BACK_AMBIENT_SOURCE_SHIFT          (20)
+#define     R200_BACK_DIFFUSE_SOURCE_SHIFT          (24)
+#define     R200_BACK_SPECULAR_SOURCE_SHIFT         (28)
+#define R200_SE_TCL_PER_LIGHT_CTL_0       0x2270
+#define     R200_LIGHT_0_ENABLE                    (1<<0)
+#define     R200_LIGHT_0_ENABLE_AMBIENT            (1<<1)
+#define     R200_LIGHT_0_ENABLE_SPECULAR           (1<<2)
+#define     R200_LIGHT_0_IS_LOCAL                  (1<<3)
+#define     R200_LIGHT_0_IS_SPOT                   (1<<4)
+#define     R200_LIGHT_0_DUAL_CONE                 (1<<5)
+#define     R200_LIGHT_0_ENABLE_RANGE_ATTEN        (1<<6)
+#define     R200_LIGHT_0_CONSTANT_RANGE_ATTEN      (1<<7)
+#define     R200_LIGHT_1_ENABLE                    (1<<16)
+#define     R200_LIGHT_1_ENABLE_AMBIENT            (1<<17)
+#define     R200_LIGHT_1_ENABLE_SPECULAR           (1<<18)
+#define     R200_LIGHT_1_IS_LOCAL                  (1<<19)
+#define     R200_LIGHT_1_IS_SPOT                   (1<<20)
+#define     R200_LIGHT_1_DUAL_CONE                 (1<<21)
+#define     R200_LIGHT_1_ENABLE_RANGE_ATTEN        (1<<22)
+#define     R200_LIGHT_1_CONSTANT_RANGE_ATTEN      (1<<23)
+#define     R200_LIGHT_0_SHIFT                   (0)
+#define     R200_LIGHT_1_SHIFT                   (16)
+#define R200_SE_TCL_PER_LIGHT_CTL_1       0x2274
+#define     R200_LIGHT_2_SHIFT                   (0)
+#define     R200_LIGHT_3_SHIFT                   (16)
+#define R200_SE_TCL_PER_LIGHT_CTL_2       0x2278
+#define     R200_LIGHT_4_SHIFT                   (0)
+#define     R200_LIGHT_5_SHIFT                   (16)
+#define R200_SE_TCL_PER_LIGHT_CTL_3       0x227c
+#define     R200_LIGHT_6_SHIFT                   (0)
+#define     R200_LIGHT_7_SHIFT                   (16)
+/* gap */
+#define R200_SE_TCL_TEX_PROC_CTL_2        0x22a8
+#define     R200_TEXGEN_0_COMP_MASK_SHIFT        (0)
+#define     R200_TEXGEN_1_COMP_MASK_SHIFT        (4)
+#define     R200_TEXGEN_2_COMP_MASK_SHIFT        (8)
+#define     R200_TEXGEN_3_COMP_MASK_SHIFT        (12)
+#define     R200_TEXGEN_4_COMP_MASK_SHIFT        (16)
+#define     R200_TEXGEN_5_COMP_MASK_SHIFT        (20)
+#define R200_SE_TCL_TEX_PROC_CTL_3        0x22ac
+#define     R200_TEXGEN_0_INPUT_TEX_SHIFT        (0)
+#define     R200_TEXGEN_1_INPUT_TEX_SHIFT        (4)
+#define     R200_TEXGEN_2_INPUT_TEX_SHIFT        (8)
+#define     R200_TEXGEN_3_INPUT_TEX_SHIFT        (12)
+#define     R200_TEXGEN_4_INPUT_TEX_SHIFT        (16)
+#define     R200_TEXGEN_5_INPUT_TEX_SHIFT        (20)
+#define R200_SE_TCL_TEX_PROC_CTL_0        0x22b0
+#define     R200_TEXGEN_TEXMAT_0_ENABLE         (1<<0)
+#define     R200_TEXGEN_TEXMAT_1_ENABLE         (1<<1)
+#define     R200_TEXGEN_TEXMAT_2_ENABLE         (1<<2)
+#define     R200_TEXGEN_TEXMAT_3_ENABLE         (1<<3)
+#define     R200_TEXGEN_TEXMAT_4_ENABLE         (1<<4)
+#define     R200_TEXGEN_TEXMAT_5_ENABLE         (1<<5)
+#define     R200_TEXMAT_0_ENABLE                (1<<8)
+#define     R200_TEXMAT_1_ENABLE                (1<<9)
+#define     R200_TEXMAT_2_ENABLE                (1<<10)
+#define     R200_TEXMAT_3_ENABLE                (1<<11)
+#define     R200_TEXMAT_4_ENABLE                (1<<12)
+#define     R200_TEXMAT_5_ENABLE                (1<<13)
+#define     R200_TEXGEN_FORCE_W_TO_ONE          (1<<16)
+#define R200_SE_TCL_TEX_PROC_CTL_1        0x22b4
+#define       R200_TEXGEN_INPUT_MASK           (0xf)
+#define       R200_TEXGEN_INPUT_TEXCOORD_0     (0)
+#define       R200_TEXGEN_INPUT_TEXCOORD_1     (1)
+#define       R200_TEXGEN_INPUT_TEXCOORD_2     (2)
+#define       R200_TEXGEN_INPUT_TEXCOORD_3     (3)
+#define       R200_TEXGEN_INPUT_TEXCOORD_4     (4)
+#define       R200_TEXGEN_INPUT_TEXCOORD_5     (5)
+#define       R200_TEXGEN_INPUT_OBJ            (8)
+#define       R200_TEXGEN_INPUT_EYE            (9)
+#define       R200_TEXGEN_INPUT_EYE_NORMAL     (0xa)
+#define       R200_TEXGEN_INPUT_EYE_REFLECT    (0xb)
+#define       R200_TEXGEN_INPUT_SPHERE         (0xd)
+#define     R200_TEXGEN_0_INPUT_SHIFT        (0)
+#define     R200_TEXGEN_1_INPUT_SHIFT        (4)
+#define     R200_TEXGEN_2_INPUT_SHIFT        (8)
+#define     R200_TEXGEN_3_INPUT_SHIFT        (12)
+#define     R200_TEXGEN_4_INPUT_SHIFT        (16)
+#define     R200_TEXGEN_5_INPUT_SHIFT        (20)
+#define R200_SE_TC_TEX_CYL_WRAP_CTL       0x22b8
+/* gap */
+#define R200_SE_TCL_UCP_VERT_BLEND_CTL    0x22c0
+#define     R200_UCP_IN_CLIP_SPACE              (1<<0)
+#define     R200_UCP_IN_MODEL_SPACE             (1<<1)
+#define     R200_UCP_ENABLE_0                   (1<<2)
+#define     R200_UCP_ENABLE_1                   (1<<3)
+#define     R200_UCP_ENABLE_2                   (1<<4)
+#define     R200_UCP_ENABLE_3                   (1<<5)
+#define     R200_UCP_ENABLE_4                   (1<<6)
+#define     R200_UCP_ENABLE_5                   (1<<7)
+#define     R200_TCL_FOG_MASK                   (3<<8)
+#define     R200_TCL_FOG_DISABLE                (0<<8)
+#define     R200_TCL_FOG_EXP                    (1<<8)
+#define     R200_TCL_FOG_EXP2                   (2<<8)
+#define     R200_TCL_FOG_LINEAR                 (3<<8)
+#define     R200_RNG_BASED_FOG                  (1<<10)
+#define     R200_CLIP_DISABLE                   (1<<11)
+#define     R200_CULL_FRONT_IS_CW               (0<<28)
+#define     R200_CULL_FRONT_IS_CCW              (1<<28)
+#define     R200_CULL_FRONT                     (1<<29)
+#define     R200_CULL_BACK                      (1<<30)
+#define R200_SE_TCL_POINT_SPRITE_CNTL     0x22c4
+/* gap */
+#define R200_SE_VTX_ST_POS_0_X_4                   0x2300
+#define R200_SE_VTX_ST_POS_0_Y_4                   0x2304
+#define R200_SE_VTX_ST_POS_0_Z_4                   0x2308
+#define R200_SE_VTX_ST_POS_0_W_4                   0x230c
+#define R200_SE_VTX_ST_NORM_0_X                    0x2310
+#define R200_SE_VTX_ST_NORM_0_Y                    0x2314
+#define R200_SE_VTX_ST_NORM_0_Z                    0x2318
+#define R200_SE_VTX_ST_PVMS                        0x231c
+#define R200_SE_VTX_ST_CLR_0_R                     0x2320
+#define R200_SE_VTX_ST_CLR_0_G                     0x2324
+#define R200_SE_VTX_ST_CLR_0_B                     0x2328
+#define R200_SE_VTX_ST_CLR_0_A                     0x232c
+#define R200_SE_VTX_ST_CLR_1_R                     0x2330
+#define R200_SE_VTX_ST_CLR_1_G                     0x2334
+#define R200_SE_VTX_ST_CLR_1_B                     0x2338
+#define R200_SE_VTX_ST_CLR_1_A                     0x233c
+#define R200_SE_VTX_ST_CLR_2_R                     0x2340
+#define R200_SE_VTX_ST_CLR_2_G                     0x2344
+#define R200_SE_VTX_ST_CLR_2_B                     0x2348
+#define R200_SE_VTX_ST_CLR_2_A                     0x234c
+#define R200_SE_VTX_ST_CLR_3_R                     0x2350
+#define R200_SE_VTX_ST_CLR_3_G                     0x2354
+#define R200_SE_VTX_ST_CLR_3_B                     0x2358
+#define R200_SE_VTX_ST_CLR_3_A                     0x235c
+#define R200_SE_VTX_ST_CLR_4_R                     0x2360
+#define R200_SE_VTX_ST_CLR_4_G                     0x2364
+#define R200_SE_VTX_ST_CLR_4_B                     0x2368
+#define R200_SE_VTX_ST_CLR_4_A                     0x236c
+#define R200_SE_VTX_ST_CLR_5_R                     0x2370
+#define R200_SE_VTX_ST_CLR_5_G                     0x2374
+#define R200_SE_VTX_ST_CLR_5_B                     0x2378
+#define R200_SE_VTX_ST_CLR_5_A                     0x237c
+#define R200_SE_VTX_ST_CLR_6_R                     0x2380
+#define R200_SE_VTX_ST_CLR_6_G                     0x2384
+#define R200_SE_VTX_ST_CLR_6_B                     0x2388
+#define R200_SE_VTX_ST_CLR_6_A                     0x238c
+#define R200_SE_VTX_ST_CLR_7_R                     0x2390
+#define R200_SE_VTX_ST_CLR_7_G                     0x2394
+#define R200_SE_VTX_ST_CLR_7_B                     0x2398
+#define R200_SE_VTX_ST_CLR_7_A                     0x239c
+#define R200_SE_VTX_ST_TEX_0_S                     0x23a0
+#define R200_SE_VTX_ST_TEX_0_T                     0x23a4
+#define R200_SE_VTX_ST_TEX_0_R                     0x23a8
+#define R200_SE_VTX_ST_TEX_0_Q                     0x23ac
+#define R200_SE_VTX_ST_TEX_1_S                     0x23b0
+#define R200_SE_VTX_ST_TEX_1_T                     0x23b4
+#define R200_SE_VTX_ST_TEX_1_R                     0x23b8
+#define R200_SE_VTX_ST_TEX_1_Q                     0x23bc
+#define R200_SE_VTX_ST_TEX_2_S                     0x23c0
+#define R200_SE_VTX_ST_TEX_2_T                     0x23c4
+#define R200_SE_VTX_ST_TEX_2_R                     0x23c8
+#define R200_SE_VTX_ST_TEX_2_Q                     0x23cc
+#define R200_SE_VTX_ST_TEX_3_S                     0x23d0
+#define R200_SE_VTX_ST_TEX_3_T                     0x23d4
+#define R200_SE_VTX_ST_TEX_3_R                     0x23d8
+#define R200_SE_VTX_ST_TEX_3_Q                     0x23dc
+#define R200_SE_VTX_ST_TEX_4_S                     0x23e0
+#define R200_SE_VTX_ST_TEX_4_T                     0x23e4
+#define R200_SE_VTX_ST_TEX_4_R                     0x23e8
+#define R200_SE_VTX_ST_TEX_4_Q                     0x23ec
+#define R200_SE_VTX_ST_TEX_5_S                     0x23f0
+#define R200_SE_VTX_ST_TEX_5_T                     0x23f4
+#define R200_SE_VTX_ST_TEX_5_R                     0x23f8
+#define R200_SE_VTX_ST_TEX_5_Q                     0x23fc
+#define R200_SE_VTX_ST_PNT_SPRT_SZ                 0x2400
+#define R200_SE_VTX_ST_DISC_FOG                    0x2404
+#define R200_SE_VTX_ST_SHININESS_0                 0x2408
+#define R200_SE_VTX_ST_SHININESS_1                 0x240c
+#define R200_SE_VTX_ST_BLND_WT_0                   0x2410
+#define R200_SE_VTX_ST_BLND_WT_1                   0x2414
+#define R200_SE_VTX_ST_BLND_WT_2                   0x2418
+#define R200_SE_VTX_ST_BLND_WT_3                   0x241c
+#define R200_SE_VTX_ST_POS_1_X                     0x2420
+#define R200_SE_VTX_ST_POS_1_Y                     0x2424
+#define R200_SE_VTX_ST_POS_1_Z                     0x2428
+#define R200_SE_VTX_ST_POS_1_W                     0x242c
+#define R200_SE_VTX_ST_NORM_1_X                    0x2430
+#define R200_SE_VTX_ST_NORM_1_Y                    0x2434
+#define R200_SE_VTX_ST_NORM_1_Z                    0x2438
+#define R200_SE_VTX_ST_USR_CLR_0_R                 0x2440
+#define R200_SE_VTX_ST_USR_CLR_0_G                 0x2444
+#define R200_SE_VTX_ST_USR_CLR_0_B                 0x2448
+#define R200_SE_VTX_ST_USR_CLR_0_A                 0x244c
+#define R200_SE_VTX_ST_USR_CLR_1_R                 0x2450
+#define R200_SE_VTX_ST_USR_CLR_1_G                 0x2454
+#define R200_SE_VTX_ST_USR_CLR_1_B                 0x2458
+#define R200_SE_VTX_ST_USR_CLR_1_A                 0x245c
+#define R200_SE_VTX_ST_CLR_0_PKD                   0x2460
+#define R200_SE_VTX_ST_CLR_1_PKD                   0x2464
+#define R200_SE_VTX_ST_CLR_2_PKD                   0x2468
+#define R200_SE_VTX_ST_CLR_3_PKD                   0x246c
+#define R200_SE_VTX_ST_CLR_4_PKD                   0x2470
+#define R200_SE_VTX_ST_CLR_5_PKD                   0x2474
+#define R200_SE_VTX_ST_CLR_6_PKD                   0x2478
+#define R200_SE_VTX_ST_CLR_7_PKD                   0x247c
+#define R200_SE_VTX_ST_POS_0_X_2                   0x2480
+#define R200_SE_VTX_ST_POS_0_Y_2                   0x2484
+#define R200_SE_VTX_ST_PAR_CLR_LD                  0x2488
+#define R200_SE_VTX_ST_USR_CLR_PKD                 0x248c
+#define R200_SE_VTX_ST_POS_0_X_3                   0x2490
+#define R200_SE_VTX_ST_POS_0_Y_3                   0x2494
+#define R200_SE_VTX_ST_POS_0_Z_3                   0x2498
+#define R200_SE_VTX_ST_END_OF_PKT                  0x249c
+/* gap */
+#define R200_RE_POINTSIZE                          0x2648
+#define     R200_POINTSIZE_SHIFT                       0
+#define     R200_MAXPOINTSIZE_SHIFT                    16
+/* gap */
+#define R200_RE_TOP_LEFT                  0x26c0
+#define     R200_RE_LEFT_SHIFT         0
+#define     R200_RE_TOP_SHIFT          16
+#define R200_RE_MISC                      0x26c4
+#define     R200_STIPPLE_COORD_MASK           0x1f
+#define     R200_STIPPLE_X_OFFSET_SHIFT       0
+#define     R200_STIPPLE_X_OFFSET_MASK        (0x1f << 0)
+#define     R200_STIPPLE_Y_OFFSET_SHIFT       8
+#define     R200_STIPPLE_Y_OFFSET_MASK        (0x1f << 8)
+#define     R200_STIPPLE_LITTLE_BIT_ORDER     (0 << 16)
+#define     R200_STIPPLE_BIG_BIT_ORDER        (1 << 16)
+/* gap */
+#define R200_RE_AUX_SCISSOR_CNTL                   0x26f0
+#define     R200_EXCLUSIVE_SCISSOR_0      0x01000000
+#define     R200_EXCLUSIVE_SCISSOR_1      0x02000000
+#define     R200_EXCLUSIVE_SCISSOR_2      0x04000000
+#define     R200_SCISSOR_ENABLE_0         0x10000000
+#define     R200_SCISSOR_ENABLE_1         0x20000000
+#define     R200_SCISSOR_ENABLE_2         0x40000000
+/* gap */
+#define R200_PP_TXFILTER_0                0x2c00
+#define     R200_MAG_FILTER_NEAREST                   (0  <<  0)
+#define     R200_MAG_FILTER_LINEAR                    (1  <<  0)
+#define     R200_MAG_FILTER_MASK                      (1  <<  0)
+#define     R200_MIN_FILTER_NEAREST                   (0  <<  1)
+#define     R200_MIN_FILTER_LINEAR                    (1  <<  1)
+#define     R200_MIN_FILTER_NEAREST_MIP_NEAREST       (2  <<  1)
+#define     R200_MIN_FILTER_NEAREST_MIP_LINEAR        (3  <<  1)
+#define     R200_MIN_FILTER_LINEAR_MIP_NEAREST        (6  <<  1)
+#define     R200_MIN_FILTER_LINEAR_MIP_LINEAR         (7  <<  1)
+#define     R200_MIN_FILTER_ANISO_NEAREST             (8  <<  1)
+#define     R200_MIN_FILTER_ANISO_LINEAR              (9  <<  1)
+#define     R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 <<  1)
+#define     R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR  (11 <<  1)
+#define     R200_MIN_FILTER_MASK                      (15 <<  1)
+#define     R200_MAX_ANISO_1_TO_1                     (0  <<  5)
+#define     R200_MAX_ANISO_2_TO_1                     (1  <<  5)
+#define     R200_MAX_ANISO_4_TO_1                     (2  <<  5)
+#define     R200_MAX_ANISO_8_TO_1                     (3  <<  5)
+#define     R200_MAX_ANISO_16_TO_1                    (4  <<  5)
+#define     R200_MAX_ANISO_MASK                       (7  <<  5)
+#define     R200_MAX_MIP_LEVEL_MASK                   (0x0f << 16)
+#define     R200_MAX_MIP_LEVEL_SHIFT                  16
+#define     R200_YUV_TO_RGB                           (1  << 20)
+#define     R200_YUV_TEMPERATURE_COOL                 (0  << 21)
+#define     R200_YUV_TEMPERATURE_HOT                  (1  << 21)
+#define     R200_YUV_TEMPERATURE_MASK                 (1  << 21)
+#define     R200_WRAPEN_S                             (1  << 22)
+#define     R200_CLAMP_S_WRAP                         (0  << 23)
+#define     R200_CLAMP_S_MIRROR                       (1  << 23)
+#define     R200_CLAMP_S_CLAMP_LAST                   (2  << 23)
+#define     R200_CLAMP_S_MIRROR_CLAMP_LAST            (3  << 23)
+#define     R200_CLAMP_S_CLAMP_BORDER                 (4  << 23)
+#define     R200_CLAMP_S_MIRROR_CLAMP_BORDER          (5  << 23)
+#define     R200_CLAMP_S_CLAMP_GL                     (6  << 23)
+#define     R200_CLAMP_S_MIRROR_CLAMP_GL              (7  << 23)
+#define     R200_CLAMP_S_MASK                         (7  << 23)
+#define     R200_WRAPEN_T                             (1  << 26)
+#define     R200_CLAMP_T_WRAP                         (0  << 27)
+#define     R200_CLAMP_T_MIRROR                       (1  << 27)
+#define     R200_CLAMP_T_CLAMP_LAST                   (2  << 27)
+#define     R200_CLAMP_T_MIRROR_CLAMP_LAST            (3  << 27)
+#define     R200_CLAMP_T_CLAMP_BORDER                 (4  << 27)
+#define     R200_CLAMP_T_MIRROR_CLAMP_BORDER          (5  << 27)
+#define     R200_CLAMP_T_CLAMP_GL                     (6  << 27)
+#define     R200_CLAMP_T_MIRROR_CLAMP_GL              (7  << 27)
+#define     R200_CLAMP_T_MASK                         (7  << 27)
+#define     R200_KILL_LT_ZERO                         (1  << 30)
+#define     R200_BORDER_MODE_OGL                      (0  << 31)
+#define     R200_BORDER_MODE_D3D                      (1  << 31)
+#define R200_PP_TXFORMAT_0                0x2c04
+#define     R200_TXFORMAT_I8                 (0  <<  0)
+#define     R200_TXFORMAT_AI88               (1  <<  0)
+#define     R200_TXFORMAT_RGB332             (2  <<  0)
+#define     R200_TXFORMAT_ARGB1555           (3  <<  0)
+#define     R200_TXFORMAT_RGB565             (4  <<  0)
+#define     R200_TXFORMAT_ARGB4444           (5  <<  0)
+#define     R200_TXFORMAT_ARGB8888           (6  <<  0)
+#define     R200_TXFORMAT_RGBA8888           (7  <<  0)
+#define     R200_TXFORMAT_Y8                 (8  <<  0)
+#define     R200_TXFORMAT_AVYU4444           (9  <<  0)
+#define     R200_TXFORMAT_VYUY422            (10  <<  0)
+#define     R200_TXFORMAT_YVYU422            (11  <<  0)
+#define     R200_TXFORMAT_DXT1               (12  <<  0)
+#define     R200_TXFORMAT_DXT23              (14  <<  0)
+#define     R200_TXFORMAT_DXT45              (15  <<  0)
+#define     R200_TXFORMAT_FORMAT_MASK        (31 <<  0)
+#define     R200_TXFORMAT_FORMAT_SHIFT       0
+#define     R200_TXFORMAT_ALPHA_IN_MAP       (1  <<  6)
+#define     R200_TXFORMAT_NON_POWER2         (1  <<  7)
+#define     R200_TXFORMAT_WIDTH_MASK         (15 <<  8)
+#define     R200_TXFORMAT_WIDTH_SHIFT        8
+#define     R200_TXFORMAT_HEIGHT_MASK        (15 << 12)
+#define     R200_TXFORMAT_HEIGHT_SHIFT       12
+#define     R200_TXFORMAT_F5_WIDTH_MASK      (15 << 16)        /* cube face 5 */
+#define     R200_TXFORMAT_F5_WIDTH_SHIFT     16
+#define     R200_TXFORMAT_F5_HEIGHT_MASK     (15 << 20)
+#define     R200_TXFORMAT_F5_HEIGHT_SHIFT    20
+#define     R200_TXFORMAT_ST_ROUTE_STQ0      (0  << 24)
+#define     R200_TXFORMAT_ST_ROUTE_STQ1      (1  << 24)
+#define     R200_TXFORMAT_ST_ROUTE_STQ2      (2  << 24)
+#define     R200_TXFORMAT_ST_ROUTE_STQ3      (3  << 24)
+#define     R200_TXFORMAT_ST_ROUTE_STQ4      (4  << 24)
+#define     R200_TXFORMAT_ST_ROUTE_STQ5      (5  << 24)
+#define     R200_TXFORMAT_ST_ROUTE_MASK      (7  << 24)
+#define     R200_TXFORMAT_ST_ROUTE_SHIFT     24
+#define     R200_TXFORMAT_ALPHA_MASK_ENABLE  (1  << 28)
+#define     R200_TXFORMAT_CHROMA_KEY_ENABLE  (1  << 29)
+#define     R200_TXFORMAT_CUBIC_MAP_ENABLE   (1  << 30)
+#define R200_PP_TXFORMAT_X_0              0x2c08
+#define     R200_DEPTH_LOG2_MASK                      (0xf << 0)
+#define     R200_DEPTH_LOG2_SHIFT                     0
+#define     R200_VOLUME_FILTER_SHIFT                  4
+#define     R200_VOLUME_FILTER_MASK                   (1 << 4)
+#define     R200_VOLUME_FILTER_NEAREST                (0 << 4)
+#define     R200_VOLUME_FILTER_LINEAR                 (1 << 4)
+#define     R200_WRAPEN_Q                             (1  << 8)
+#define     R200_CLAMP_Q_WRAP                         (0  << 9)
+#define     R200_CLAMP_Q_MIRROR                       (1  << 9)
+#define     R200_CLAMP_Q_CLAMP_LAST                   (2  << 9)
+#define     R200_CLAMP_Q_MIRROR_CLAMP_LAST            (3  << 9)
+#define     R200_CLAMP_Q_CLAMP_BORDER                 (4  << 9)
+#define     R200_CLAMP_Q_MIRROR_CLAMP_BORDER          (5  << 9)
+#define     R200_CLAMP_Q_CLAMP_GL                     (6  << 9)
+#define     R200_CLAMP_Q_MIRROR_CLAMP_GL              (7  << 9)
+#define     R200_CLAMP_Q_MASK                         (7  << 9)
+#define     R200_MIN_MIP_LEVEL_MASK                   (0xff << 12)
+#define     R200_MIN_MIP_LEVEL_SHIFT                  12
+#define     R200_TEXCOORD_NONPROJ                     (0  << 16)
+#define     R200_TEXCOORD_CUBIC_ENV                   (1  << 16)
+#define     R200_TEXCOORD_VOLUME                      (2  << 16)
+#define     R200_TEXCOORD_PROJ                        (3  << 16)
+#define     R200_TEXCOORD_DEPTH                       (4  << 16)
+#define     R200_TEXCOORD_1D_PROJ                     (5  << 16)
+#define     R200_TEXCOORD_1D                          (6  << 16)
+#define     R200_TEXCOORD_ZERO                        (7  << 16)
+#define     R200_TEXCOORD_MASK                        (7  << 16)
+#define     R200_LOD_BIAS_MASK                        (0xfff80000)
+#define     R200_LOD_BIAS_SHIFT                       19
+#define R200_PP_TXSIZE_0                  0x2c0c       /* NPOT only */
+#define R200_PP_TXPITCH_0                 0x2c10       /* NPOT only */
+#define R200_PP_BORDER_COLOR_0            0x2c14
+#define R200_PP_CUBIC_FACES_0             0x2c18
+#define     R200_FACE_WIDTH_1_SHIFT                   0
+#define     R200_FACE_HEIGHT_1_SHIFT                  4
+#define     R200_FACE_WIDTH_1_MASK                   (0xf << 0)
+#define     R200_FACE_HEIGHT_1_MASK                  (0xf << 4)
+#define     R200_FACE_WIDTH_2_SHIFT                   8
+#define     R200_FACE_HEIGHT_2_SHIFT                 12
+#define     R200_FACE_WIDTH_2_MASK                   (0xf << 8)
+#define     R200_FACE_HEIGHT_2_MASK                  (0xf << 12)
+#define     R200_FACE_WIDTH_3_SHIFT                  16
+#define     R200_FACE_HEIGHT_3_SHIFT                 20
+#define     R200_FACE_WIDTH_3_MASK                   (0xf << 16)
+#define     R200_FACE_HEIGHT_3_MASK                  (0xf << 20)
+#define     R200_FACE_WIDTH_4_SHIFT                  24
+#define     R200_FACE_HEIGHT_4_SHIFT                 28
+#define     R200_FACE_WIDTH_4_MASK                   (0xf << 24)
+#define     R200_FACE_HEIGHT_4_MASK                  (0xf << 28)
+#define R200_PP_TXFILTER_1                0x2c20
+#define R200_PP_TXFORMAT_1                0x2c24
+#define R200_PP_TXFORMAT_X_1              0x2c28
+#define R200_PP_TXSIZE_1                  0x2c2c
+#define R200_PP_TXPITCH_1                 0x2c30
+#define R200_PP_BORDER_COLOR_1            0x2c34
+#define R200_PP_CUBIC_FACES_1             0x2c38
+#define R200_PP_TXFILTER_2                0x2c40
+#define R200_PP_TXFORMAT_2                0x2c44
+#define R200_PP_TXSIZE_2                  0x2c4c
+#define R200_PP_TXFORMAT_X_2              0x2c48
+#define R200_PP_TXPITCH_2                 0x2c50
+#define R200_PP_BORDER_COLOR_2            0x2c54
+#define R200_PP_CUBIC_FACES_2             0x2c58
+#define R200_PP_TXFILTER_3                0x2c60
+#define R200_PP_TXFORMAT_3                0x2c64
+#define R200_PP_TXSIZE_3                  0x2c6c
+#define R200_PP_TXFORMAT_X_3              0x2c68
+#define R200_PP_TXPITCH_3                 0x2c70
+#define R200_PP_BORDER_COLOR_3            0x2c74
+#define R200_PP_CUBIC_FACES_3             0x2c78
+#define R200_PP_TXFILTER_4                0x2c80
+#define R200_PP_TXFORMAT_4                0x2c84
+#define R200_PP_TXSIZE_4                  0x2c8c
+#define R200_PP_TXFORMAT_X_4              0x2c88
+#define R200_PP_TXPITCH_4                 0x2c90
+#define R200_PP_BORDER_COLOR_4            0x2c94
+#define R200_PP_CUBIC_FACES_4             0x2c98
+#define R200_PP_TXFILTER_5                0x2ca0
+#define R200_PP_TXFORMAT_5                0x2ca4
+#define R200_PP_TXSIZE_5                  0x2cac
+#define R200_PP_TXFORMAT_X_5              0x2ca8
+#define R200_PP_TXPITCH_5                 0x2cb0
+#define R200_PP_BORDER_COLOR_5            0x2cb4
+#define R200_PP_CUBIC_FACES_5             0x2cb8
+/* gap */
+#define R200_PP_CNTL_X             0x2cc4
+/* gap */
+#define R200_PP_TXOFFSET_0                0x2d00
+#define     R200_TXO_ENDIAN_NO_SWAP     (0 << 0)
+#define     R200_TXO_ENDIAN_BYTE_SWAP   (1 << 0)
+#define     R200_TXO_ENDIAN_WORD_SWAP   (2 << 0)
+#define     R200_TXO_ENDIAN_HALFDW_SWAP (3 << 0)
+#define     R200_TXO_OFFSET_MASK        0xffffffe0
+#define     R200_TXO_OFFSET_SHIFT       5
+#define R200_PP_CUBIC_OFFSET_F1_0         0x2d04
+#define R200_PP_CUBIC_OFFSET_F2_0         0x2d08
+#define R200_PP_CUBIC_OFFSET_F3_0         0x2d0c
+#define R200_PP_CUBIC_OFFSET_F4_0         0x2d10
+#define R200_PP_CUBIC_OFFSET_F5_0         0x2d14
+#define R200_PP_TXOFFSET_1                0x2d18
+#define R200_PP_CUBIC_OFFSET_F1_1         0x2d1c
+#define R200_PP_CUBIC_OFFSET_F2_1         0x2d20
+#define R200_PP_CUBIC_OFFSET_F3_1         0x2d24
+#define R200_PP_CUBIC_OFFSET_F4_1         0x2d28
+#define R200_PP_CUBIC_OFFSET_F5_1         0x2d2c
+#define R200_PP_TXOFFSET_2                0x2d30
+#define R200_PP_CUBIC_OFFSET_F1_2         0x2d34
+#define R200_PP_CUBIC_OFFSET_F2_2         0x2d38
+#define R200_PP_CUBIC_OFFSET_F3_2         0x2d3c
+#define R200_PP_CUBIC_OFFSET_F4_2         0x2d40
+#define R200_PP_CUBIC_OFFSET_F5_2         0x2d44
+#define R200_PP_TXOFFSET_3                0x2d48
+#define R200_PP_CUBIC_OFFSET_F1_3         0x2d4c
+#define R200_PP_CUBIC_OFFSET_F2_3         0x2d50
+#define R200_PP_CUBIC_OFFSET_F3_3         0x2d54
+#define R200_PP_CUBIC_OFFSET_F4_3         0x2d58
+#define R200_PP_CUBIC_OFFSET_F5_3         0x2d5c
+#define R200_PP_TXOFFSET_4                0x2d60
+#define R200_PP_CUBIC_OFFSET_F1_4         0x2d64
+#define R200_PP_CUBIC_OFFSET_F2_4         0x2d68
+#define R200_PP_CUBIC_OFFSET_F3_4         0x2d6c
+#define R200_PP_CUBIC_OFFSET_F4_4         0x2d70
+#define R200_PP_CUBIC_OFFSET_F5_4         0x2d74
+#define R200_PP_TXOFFSET_5                0x2d78
+#define R200_PP_CUBIC_OFFSET_F1_5         0x2d7c
+#define R200_PP_CUBIC_OFFSET_F2_5         0x2d80
+#define R200_PP_CUBIC_OFFSET_F3_5         0x2d84
+#define R200_PP_CUBIC_OFFSET_F4_5         0x2d88
+#define R200_PP_CUBIC_OFFSET_F5_5         0x2d8c
+/* gap */
+#define R200_PP_TAM_DEBUG3                0x2d9c
+/* gap */
+#define R200_PP_TFACTOR_0                 0x2ee0
+#define R200_PP_TFACTOR_1                 0x2ee4
+#define R200_PP_TFACTOR_2                 0x2ee8
+#define R200_PP_TFACTOR_3                 0x2eec
+#define R200_PP_TFACTOR_4                 0x2ef0
+#define R200_PP_TFACTOR_5                 0x2ef4
+/* gap */
+#define R200_PP_TXCBLEND_0                0x2f00
+#define     R200_TXC_ARG_A_ZERO                (0)
+#define     R200_TXC_ARG_A_CURRENT_COLOR       (2)
+#define     R200_TXC_ARG_A_CURRENT_ALPHA       (3)
+#define     R200_TXC_ARG_A_DIFFUSE_COLOR       (4)
+#define     R200_TXC_ARG_A_DIFFUSE_ALPHA       (5)
+#define     R200_TXC_ARG_A_SPECULAR_COLOR      (6)
+#define     R200_TXC_ARG_A_SPECULAR_ALPHA      (7)
+#define     R200_TXC_ARG_A_TFACTOR_COLOR       (8)
+#define     R200_TXC_ARG_A_TFACTOR_ALPHA       (9)
+#define     R200_TXC_ARG_A_R0_COLOR            (10)
+#define     R200_TXC_ARG_A_R0_ALPHA            (11)
+#define     R200_TXC_ARG_A_R1_COLOR            (12)
+#define     R200_TXC_ARG_A_R1_ALPHA            (13)
+#define     R200_TXC_ARG_A_R2_COLOR            (14)
+#define     R200_TXC_ARG_A_R2_ALPHA            (15)
+#define     R200_TXC_ARG_A_R3_COLOR            (16)
+#define     R200_TXC_ARG_A_R3_ALPHA            (17)
+#define     R200_TXC_ARG_A_R4_COLOR            (18)
+#define     R200_TXC_ARG_A_R4_ALPHA            (19)
+#define     R200_TXC_ARG_A_R5_COLOR            (20)
+#define     R200_TXC_ARG_A_R5_ALPHA            (21)
+#define     R200_TXC_ARG_A_TFACTOR1_COLOR      (26)
+#define     R200_TXC_ARG_A_TFACTOR1_ALPHA      (27)
+#define     R200_TXC_ARG_A_MASK                        (31 << 0)
+#define     R200_TXC_ARG_A_SHIFT                       0
+#define     R200_TXC_ARG_B_ZERO                (0<<5)
+#define     R200_TXC_ARG_B_CURRENT_COLOR       (2<<5)
+#define     R200_TXC_ARG_B_CURRENT_ALPHA       (3<<5)
+#define     R200_TXC_ARG_B_DIFFUSE_COLOR       (4<<5)
+#define     R200_TXC_ARG_B_DIFFUSE_ALPHA       (5<<5)
+#define     R200_TXC_ARG_B_SPECULAR_COLOR      (6<<5)
+#define     R200_TXC_ARG_B_SPECULAR_ALPHA      (7<<5)
+#define     R200_TXC_ARG_B_TFACTOR_COLOR       (8<<5)
+#define     R200_TXC_ARG_B_TFACTOR_ALPHA       (9<<5)
+#define     R200_TXC_ARG_B_R0_COLOR            (10<<5)
+#define     R200_TXC_ARG_B_R0_ALPHA            (11<<5)
+#define     R200_TXC_ARG_B_R1_COLOR            (12<<5)
+#define     R200_TXC_ARG_B_R1_ALPHA            (13<<5)
+#define     R200_TXC_ARG_B_R2_COLOR            (14<<5)
+#define     R200_TXC_ARG_B_R2_ALPHA            (15<<5)
+#define     R200_TXC_ARG_B_R3_COLOR            (16<<5)
+#define     R200_TXC_ARG_B_R3_ALPHA            (17<<5)
+#define     R200_TXC_ARG_B_R4_COLOR            (18<<5)
+#define     R200_TXC_ARG_B_R4_ALPHA            (19<<5)
+#define     R200_TXC_ARG_B_R5_COLOR            (20<<5)
+#define     R200_TXC_ARG_B_R5_ALPHA            (21<<5)
+#define     R200_TXC_ARG_B_TFACTOR1_COLOR      (26<<5)
+#define     R200_TXC_ARG_B_TFACTOR1_ALPHA      (27<<5)
+#define     R200_TXC_ARG_B_MASK                        (31 << 5)
+#define     R200_TXC_ARG_B_SHIFT                       5
+#define     R200_TXC_ARG_C_ZERO                (0<<10)
+#define     R200_TXC_ARG_C_CURRENT_COLOR       (2<<10)
+#define     R200_TXC_ARG_C_CURRENT_ALPHA       (3<<10)
+#define     R200_TXC_ARG_C_DIFFUSE_COLOR       (4<<10)
+#define     R200_TXC_ARG_C_DIFFUSE_ALPHA       (5<<10)
+#define     R200_TXC_ARG_C_SPECULAR_COLOR      (6<<10)
+#define     R200_TXC_ARG_C_SPECULAR_ALPHA      (7<<10)
+#define     R200_TXC_ARG_C_TFACTOR_COLOR       (8<<10)
+#define     R200_TXC_ARG_C_TFACTOR_ALPHA       (9<<10)
+#define     R200_TXC_ARG_C_R0_COLOR            (10<<10)
+#define     R200_TXC_ARG_C_R0_ALPHA            (11<<10)
+#define     R200_TXC_ARG_C_R1_COLOR            (12<<10)
+#define     R200_TXC_ARG_C_R1_ALPHA            (13<<10)
+#define     R200_TXC_ARG_C_R2_COLOR            (14<<10)
+#define     R200_TXC_ARG_C_R2_ALPHA            (15<<10)
+#define     R200_TXC_ARG_C_R3_COLOR            (16<<10)
+#define     R200_TXC_ARG_C_R3_ALPHA            (17<<10)
+#define     R200_TXC_ARG_C_R4_COLOR            (18<<10)
+#define     R200_TXC_ARG_C_R4_ALPHA            (19<<10)
+#define     R200_TXC_ARG_C_R5_COLOR            (20<<10)
+#define     R200_TXC_ARG_C_R5_ALPHA            (21<<10)
+#define     R200_TXC_ARG_C_TFACTOR1_COLOR      (26<<10)
+#define     R200_TXC_ARG_C_TFACTOR1_ALPHA      (27<<10)
+#define     R200_TXC_ARG_C_MASK                        (31 << 10)
+#define     R200_TXC_ARG_C_SHIFT                       10
+#define     R200_TXC_COMP_ARG_A                    (1 << 16)
+#define     R200_TXC_COMP_ARG_A_SHIFT              (16)
+#define     R200_TXC_BIAS_ARG_A                    (1 << 17)
+#define     R200_TXC_SCALE_ARG_A                   (1 << 18)
+#define     R200_TXC_NEG_ARG_A                     (1 << 19)
+#define     R200_TXC_COMP_ARG_B                    (1 << 20)
+#define     R200_TXC_COMP_ARG_B_SHIFT              (20)
+#define     R200_TXC_BIAS_ARG_B                    (1 << 21)
+#define     R200_TXC_SCALE_ARG_B                   (1 << 22)
+#define     R200_TXC_NEG_ARG_B                     (1 << 23)
+#define     R200_TXC_COMP_ARG_C                    (1 << 24)
+#define     R200_TXC_COMP_ARG_C_SHIFT              (24)
+#define     R200_TXC_BIAS_ARG_C                    (1 << 25)
+#define     R200_TXC_SCALE_ARG_C                   (1 << 26)
+#define     R200_TXC_NEG_ARG_C                     (1 << 27)
+#define     R200_TXC_OP_MADD                        (0 << 28)
+#define     R200_TXC_OP_CND0                       (2 << 28)
+#define     R200_TXC_OP_LERP                       (3 << 28)
+#define     R200_TXC_OP_DOT3                       (4 << 28)
+#define     R200_TXC_OP_DOT4                       (5 << 28)
+#define     R200_TXC_OP_CONDITIONAL                (6 << 28)
+#define     R200_TXC_OP_DOT2_ADD                   (7 << 28)
+#define     R200_TXC_OP_MASK                       (7 << 28)
+#define R200_PP_TXCBLEND2_0                0x2f04
+#define     R200_TXC_TFACTOR_SEL_SHIFT             0
+#define     R200_TXC_TFACTOR_SEL_MASK              0x7
+#define     R200_TXC_TFACTOR1_SEL_SHIFT            4
+#define     R200_TXC_TFACTOR1_SEL_MASK             (0x7 << 4)
+#define     R200_TXC_SCALE_SHIFT                   8
+#define     R200_TXC_SCALE_MASK                    (7 << 8)
+#define     R200_TXC_SCALE_1X                      (0 << 8)
+#define     R200_TXC_SCALE_2X                      (1 << 8)
+#define     R200_TXC_SCALE_4X                      (2 << 8)
+#define     R200_TXC_SCALE_8X                      (3 << 8)
+#define     R200_TXC_SCALE_INV2                    (5 << 8)
+#define     R200_TXC_SCALE_INV4                    (6 << 8)
+#define     R200_TXC_SCALE_INV8                    (7 << 8)
+#define     R200_TXC_CLAMP_SHIFT                   12
+#define     R200_TXC_CLAMP_MASK                    (3 << 12)
+#define     R200_TXC_CLAMP_WRAP                    (0 << 12)
+#define     R200_TXC_CLAMP_0_1                     (1 << 12)
+#define     R200_TXC_CLAMP_8_8                     (2 << 12)
+#define     R200_TXC_OUTPUT_REG_MASK               (7 << 16)
+#define     R200_TXC_OUTPUT_REG_NONE               (0 << 16)
+#define     R200_TXC_OUTPUT_REG_R0                 (1 << 16)
+#define     R200_TXC_OUTPUT_REG_R1                 (2 << 16)
+#define     R200_TXC_OUTPUT_REG_R2                 (3 << 16)
+#define     R200_TXC_OUTPUT_REG_R3                 (4 << 16)
+#define     R200_TXC_OUTPUT_REG_R4                 (5 << 16)
+#define     R200_TXC_OUTPUT_REG_R5                 (6 << 16)
+#define     R200_TXC_OUTPUT_MASK_MASK              (7 << 20)
+#define     R200_TXC_OUTPUT_MASK_RGB               (0 << 20)
+#define     R200_TXC_OUTPUT_MASK_RG                (1 << 20)
+#define     R200_TXC_OUTPUT_MASK_RB                (2 << 20)
+#define     R200_TXC_OUTPUT_MASK_R                 (3 << 20)
+#define     R200_TXC_OUTPUT_MASK_GB                (4 << 20)
+#define     R200_TXC_OUTPUT_MASK_G                 (5 << 20)
+#define     R200_TXC_OUTPUT_MASK_B                 (6 << 20)
+#define     R200_TXC_OUTPUT_MASK_NONE              (7 << 20)
+#define     R200_TXC_REPL_NORMAL                   0
+#define     R200_TXC_REPL_RED                      1
+#define     R200_TXC_REPL_GREEN                    2
+#define     R200_TXC_REPL_BLUE                     3
+#define     R200_TXC_REPL_ARG_A_SHIFT              26
+#define     R200_TXC_REPL_ARG_A_MASK               (3 << 26)
+#define     R200_TXC_REPL_ARG_B_SHIFT              28
+#define     R200_TXC_REPL_ARG_B_MASK               (3 << 28)
+#define     R200_TXC_REPL_ARG_C_SHIFT              30
+#define     R200_TXC_REPL_ARG_C_MASK               (3 << 30)
+#define R200_PP_TXABLEND_0                0x2f08
+#define     R200_TXA_ARG_A_ZERO              (0)
+#define     R200_TXA_ARG_A_CURRENT_ALPHA     (2)       /* guess */
+#define     R200_TXA_ARG_A_CURRENT_BLUE      (3)       /* guess */
+#define     R200_TXA_ARG_A_DIFFUSE_ALPHA     (4)
+#define     R200_TXA_ARG_A_DIFFUSE_BLUE      (5)
+#define     R200_TXA_ARG_A_SPECULAR_ALPHA    (6)
+#define     R200_TXA_ARG_A_SPECULAR_BLUE     (7)
+#define     R200_TXA_ARG_A_TFACTOR_ALPHA     (8)
+#define     R200_TXA_ARG_A_TFACTOR_BLUE      (9)
+#define     R200_TXA_ARG_A_R0_ALPHA          (10)
+#define     R200_TXA_ARG_A_R0_BLUE           (11)
+#define     R200_TXA_ARG_A_R1_ALPHA          (12)
+#define     R200_TXA_ARG_A_R1_BLUE           (13)
+#define     R200_TXA_ARG_A_R2_ALPHA          (14)
+#define     R200_TXA_ARG_A_R2_BLUE           (15)
+#define     R200_TXA_ARG_A_R3_ALPHA          (16)
+#define     R200_TXA_ARG_A_R3_BLUE           (17)
+#define     R200_TXA_ARG_A_R4_ALPHA          (18)
+#define     R200_TXA_ARG_A_R4_BLUE           (19)
+#define     R200_TXA_ARG_A_R5_ALPHA          (20)
+#define     R200_TXA_ARG_A_R5_BLUE           (21)
+#define     R200_TXA_ARG_A_TFACTOR1_ALPHA    (26)
+#define     R200_TXA_ARG_A_TFACTOR1_BLUE     (27)
+#define     R200_TXA_ARG_A_MASK                        (31 << 0)
+#define     R200_TXA_ARG_A_SHIFT                       0
+#define     R200_TXA_ARG_B_ZERO              (0<<5)
+#define     R200_TXA_ARG_B_CURRENT_ALPHA     (2<<5)    /* guess */
+#define     R200_TXA_ARG_B_CURRENT_BLUE      (3<<5)    /* guess */
+#define     R200_TXA_ARG_B_DIFFUSE_ALPHA     (4<<5)
+#define     R200_TXA_ARG_B_DIFFUSE_BLUE      (5<<5)
+#define     R200_TXA_ARG_B_SPECULAR_ALPHA    (6<<5)
+#define     R200_TXA_ARG_B_SPECULAR_BLUE     (7<<5)
+#define     R200_TXA_ARG_B_TFACTOR_ALPHA     (8<<5)
+#define     R200_TXA_ARG_B_TFACTOR_BLUE      (9<<5)
+#define     R200_TXA_ARG_B_R0_ALPHA          (10<<5)
+#define     R200_TXA_ARG_B_R0_BLUE           (11<<5)
+#define     R200_TXA_ARG_B_R1_ALPHA          (12<<5)
+#define     R200_TXA_ARG_B_R1_BLUE           (13<<5)
+#define     R200_TXA_ARG_B_R2_ALPHA          (14<<5)
+#define     R200_TXA_ARG_B_R2_BLUE           (15<<5)
+#define     R200_TXA_ARG_B_R3_ALPHA          (16<<5)
+#define     R200_TXA_ARG_B_R3_BLUE           (17<<5)
+#define     R200_TXA_ARG_B_R4_ALPHA          (18<<5)
+#define     R200_TXA_ARG_B_R4_BLUE           (19<<5)
+#define     R200_TXA_ARG_B_R5_ALPHA          (20<<5)
+#define     R200_TXA_ARG_B_R5_BLUE           (21<<5)
+#define     R200_TXA_ARG_B_TFACTOR1_ALPHA    (26<<5)
+#define     R200_TXA_ARG_B_TFACTOR1_BLUE     (27<<5)
+#define     R200_TXA_ARG_B_MASK                        (31 << 5)
+#define     R200_TXA_ARG_B_SHIFT                       5
+#define     R200_TXA_ARG_C_ZERO              (0<<10)
+#define     R200_TXA_ARG_C_CURRENT_ALPHA     (2<<10)   /* guess */
+#define     R200_TXA_ARG_C_CURRENT_BLUE      (3<<10)   /* guess */
+#define     R200_TXA_ARG_C_DIFFUSE_ALPHA     (4<<10)
+#define     R200_TXA_ARG_C_DIFFUSE_BLUE      (5<<10)
+#define     R200_TXA_ARG_C_SPECULAR_ALPHA    (6<<10)
+#define     R200_TXA_ARG_C_SPECULAR_BLUE     (7<<10)
+#define     R200_TXA_ARG_C_TFACTOR_ALPHA     (8<<10)
+#define     R200_TXA_ARG_C_TFACTOR_BLUE      (9<<10)
+#define     R200_TXA_ARG_C_R0_ALPHA          (10<<10)
+#define     R200_TXA_ARG_C_R0_BLUE           (11<<10)
+#define     R200_TXA_ARG_C_R1_ALPHA          (12<<10)
+#define     R200_TXA_ARG_C_R1_BLUE           (13<<10)
+#define     R200_TXA_ARG_C_R2_ALPHA          (14<<10)
+#define     R200_TXA_ARG_C_R2_BLUE           (15<<10)
+#define     R200_TXA_ARG_C_R3_ALPHA          (16<<10)
+#define     R200_TXA_ARG_C_R3_BLUE           (17<<10)
+#define     R200_TXA_ARG_C_R4_ALPHA          (18<<10)
+#define     R200_TXA_ARG_C_R4_BLUE           (19<<10)
+#define     R200_TXA_ARG_C_R5_ALPHA          (20<<10)
+#define     R200_TXA_ARG_C_R5_BLUE           (21<<10)
+#define     R200_TXA_ARG_C_TFACTOR1_ALPHA    (26<<10)
+#define     R200_TXA_ARG_C_TFACTOR1_BLUE     (27<<10)
+#define     R200_TXA_ARG_C_MASK                        (31 << 10)
+#define     R200_TXA_ARG_C_SHIFT                       10
+#define     R200_TXA_COMP_ARG_A                    (1 << 16)
+#define     R200_TXA_COMP_ARG_A_SHIFT              (16)
+#define     R200_TXA_BIAS_ARG_A                    (1 << 17)
+#define     R200_TXA_SCALE_ARG_A                   (1 << 18)
+#define     R200_TXA_NEG_ARG_A                     (1 << 19)
+#define     R200_TXA_COMP_ARG_B                    (1 << 20)
+#define     R200_TXA_COMP_ARG_B_SHIFT              (20)
+#define     R200_TXA_BIAS_ARG_B                    (1 << 21)
+#define     R200_TXA_SCALE_ARG_B                   (1 << 22)
+#define     R200_TXA_NEG_ARG_B                     (1 << 23)
+#define     R200_TXA_COMP_ARG_C                    (1 << 24)
+#define     R200_TXA_COMP_ARG_C_SHIFT              (24)
+#define     R200_TXA_BIAS_ARG_C                    (1 << 25)
+#define     R200_TXA_SCALE_ARG_C                   (1 << 26)
+#define     R200_TXA_NEG_ARG_C                     (1 << 27)
+#define     R200_TXA_OP_MADD                       (0 << 28)
+#define     R200_TXA_OP_CND0                       (2 << 28)
+#define     R200_TXA_OP_LERP                       (3 << 28)
+#define     R200_TXA_OP_CONDITIONAL                (6 << 28)
+#define     R200_TXA_OP_MASK                       (7 << 28)
+#define R200_PP_TXABLEND2_0                0x2f0c
+#define     R200_TXA_TFACTOR_SEL_SHIFT             0
+#define     R200_TXA_TFACTOR_SEL_MASK              0x7
+#define     R200_TXA_TFACTOR1_SEL_SHIFT            4
+#define     R200_TXA_TFACTOR1_SEL_MASK             (0x7 << 4)
+#define     R200_TXA_SCALE_SHIFT                   8
+#define     R200_TXA_SCALE_MASK                    (7 << 8)
+#define     R200_TXA_SCALE_1X                      (0 << 8)
+#define     R200_TXA_SCALE_2X                      (1 << 8)
+#define     R200_TXA_SCALE_4X                      (2 << 8)
+#define     R200_TXA_SCALE_8X                      (3 << 8)
+#define     R200_TXA_SCALE_INV2                    (5 << 8)
+#define     R200_TXA_SCALE_INV4                    (6 << 8)
+#define     R200_TXA_SCALE_INV8                    (7 << 8)
+#define     R200_TXA_CLAMP_SHIFT                   12
+#define     R200_TXA_CLAMP_MASK                    (3 << 12)
+#define     R200_TXA_CLAMP_WRAP                    (0 << 12)
+#define     R200_TXA_CLAMP_0_1                     (1 << 12)
+#define     R200_TXA_CLAMP_8_8                     (2 << 12)
+#define     R200_TXA_OUTPUT_REG_MASK               (7 << 16)
+#define     R200_TXA_OUTPUT_REG_NONE               (0 << 16)
+#define     R200_TXA_OUTPUT_REG_R0                 (1 << 16)
+#define     R200_TXA_OUTPUT_REG_R1                 (2 << 16)
+#define     R200_TXA_OUTPUT_REG_R2                 (3 << 16)
+#define     R200_TXA_OUTPUT_REG_R3                 (4 << 16)
+#define     R200_TXA_OUTPUT_REG_R4                 (5 << 16)
+#define     R200_TXA_OUTPUT_REG_R5                 (6 << 16)
+#define     R200_TXA_DOT_ALPHA                     (1 << 20)
+#define     R200_TXA_REPL_NORMAL                   0
+#define     R200_TXA_REPL_RED                      1
+#define     R200_TXA_REPL_GREEN                    2
+#define     R200_TXA_REPL_ARG_A_SHIFT              26
+#define     R200_TXA_REPL_ARG_A_MASK               (3 << 26)
+#define     R200_TXA_REPL_ARG_B_SHIFT              28
+#define     R200_TXA_REPL_ARG_B_MASK               (3 << 28)
+#define     R200_TXA_REPL_ARG_C_SHIFT              30
+#define     R200_TXA_REPL_ARG_C_MASK               (3 << 30)
+#define R200_PP_TXCBLEND_1                0x2f10
+#define R200_PP_TXCBLEND2_1               0x2f14
+#define R200_PP_TXABLEND_1                0x2f18
+#define R200_PP_TXABLEND2_1               0x2f1c
+#define R200_PP_TXCBLEND_2                0x2f20
+#define R200_PP_TXCBLEND2_2               0x2f24
+#define R200_PP_TXABLEND_2                0x2f28
+#define R200_PP_TXABLEND2_2               0x2f2c
+#define R200_PP_TXCBLEND_3                0x2f30
+#define R200_PP_TXCBLEND2_3               0x2f34
+#define R200_PP_TXABLEND_3                0x2f38
+#define R200_PP_TXABLEND2_3               0x2f3c
+#define R200_PP_TXCBLEND_4                0x2f40
+#define R200_PP_TXCBLEND2_4               0x2f44
+#define R200_PP_TXABLEND_4                0x2f48
+#define R200_PP_TXABLEND2_4               0x2f4c
+#define R200_PP_TXCBLEND_5                0x2f50
+#define R200_PP_TXCBLEND2_5               0x2f54
+#define R200_PP_TXABLEND_5                0x2f58
+#define R200_PP_TXABLEND2_5               0x2f5c
+#define R200_PP_TXCBLEND_6                0x2f60
+#define R200_PP_TXCBLEND2_6               0x2f64
+#define R200_PP_TXABLEND_6                0x2f68
+#define R200_PP_TXABLEND2_6               0x2f6c
+#define R200_PP_TXCBLEND_7                0x2f70
+#define R200_PP_TXCBLEND2_7               0x2f74
+#define R200_PP_TXABLEND_7                0x2f78
+#define R200_PP_TXABLEND2_7               0x2f7c
+/* gap */
+#define R200_RB3D_BLENDCOLOR               0x3218      /* ARGB 8888 */
+#define R200_RB3D_ABLENDCNTL               0x321C      /* see BLENDCTL */
+#define R200_RB3D_CBLENDCNTL               0x3220      /* see BLENDCTL */
+
+/*
+ * Offsets in TCL vector state.  NOTE: Hardwiring matrix positions.
+ * Multiple contexts could collaberate to eliminate state bouncing.
+ */
+#define R200_VS_LIGHT_AMBIENT_ADDR          0x00000028
+#define R200_VS_LIGHT_DIFFUSE_ADDR          0x00000030
+#define R200_VS_LIGHT_SPECULAR_ADDR         0x00000038
+#define R200_VS_LIGHT_DIRPOS_ADDR           0x00000040
+#define R200_VS_LIGHT_HWVSPOT_ADDR          0x00000048
+#define R200_VS_LIGHT_ATTENUATION_ADDR      0x00000050
+#define R200_VS_SPOT_DUAL_CONE              0x00000058
+#define R200_VS_GLOBAL_AMBIENT_ADDR         0x0000005C
+#define R200_VS_FOG_PARAM_ADDR              0x0000005D
+#define R200_VS_EYE_VECTOR_ADDR             0x0000005E
+#define R200_VS_UCP_ADDR                    0x00000060
+#define R200_VS_PNT_SPRITE_VPORT_SCALE      0x00000068
+#define R200_VS_MATRIX_0_MV                 0x00000080
+#define R200_VS_MATRIX_1_INV_MV                    0x00000084
+#define R200_VS_MATRIX_2_MVP               0x00000088
+#define R200_VS_MATRIX_3_TEX0              0x0000008C
+#define R200_VS_MATRIX_4_TEX1              0x00000090
+#define R200_VS_MATRIX_5_TEX2              0x00000094
+#define R200_VS_MATRIX_6_TEX3              0x00000098
+#define R200_VS_MATRIX_7_TEX4              0x0000009C
+#define R200_VS_MATRIX_8_TEX5              0x000000A0
+#define R200_VS_MAT_0_EMISS                 0x000000B0
+#define R200_VS_MAT_0_AMB                   0x000000B1
+#define R200_VS_MAT_0_DIF                   0x000000B2
+#define R200_VS_MAT_0_SPEC                  0x000000B3
+#define R200_VS_MAT_1_EMISS                 0x000000B4
+#define R200_VS_MAT_1_AMB                   0x000000B5
+#define R200_VS_MAT_1_DIF                   0x000000B6
+#define R200_VS_MAT_1_SPEC                  0x000000B7
+#define R200_VS_EYE2CLIP_MTX                0x000000B8
+#define R200_VS_PNT_SPRITE_ATT_CONST        0x000000BC
+#define R200_VS_PNT_SPRITE_EYE_IN_MODEL     0x000000BD
+#define R200_VS_PNT_SPRITE_CLAMP            0x000000BE
+#define R200_VS_MAX                         0x000001C0
+
+/*
+ * Offsets in TCL scalar state
+ */
+#define R200_SS_LIGHT_DCD_ADDR              0x00000000
+#define R200_SS_LIGHT_DCM_ADDR              0x00000008
+#define R200_SS_LIGHT_SPOT_EXPONENT_ADDR    0x00000010
+#define R200_SS_LIGHT_SPOT_CUTOFF_ADDR      0x00000018
+#define R200_SS_LIGHT_SPECULAR_THRESH_ADDR  0x00000020
+#define R200_SS_LIGHT_RANGE_CUTOFF_SQRD     0x00000028
+#define R200_SS_LIGHT_RANGE_ATT_CONST       0x00000030
+#define R200_SS_VERT_GUARD_CLIP_ADJ_ADDR    0x00000080
+#define R200_SS_VERT_GUARD_DISCARD_ADJ_ADDR 0x00000081
+#define R200_SS_HORZ_GUARD_CLIP_ADJ_ADDR    0x00000082
+#define R200_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 0x00000083
+#define R200_SS_MAT_0_SHININESS             0x00000100
+#define R200_SS_MAT_1_SHININESS             0x00000101
+
+/*
+ * Matrix indices
+ */
+#define R200_MTX_MV                        0
+#define R200_MTX_IMV                       1
+#define R200_MTX_MVP                       2
+#define R200_MTX_TEX0                      3
+#define R200_MTX_TEX1                      4
+#define R200_MTX_TEX2                      5
+#define R200_MTX_TEX3                      6
+#define R200_MTX_TEX4                      7
+#define R200_MTX_TEX5                      8
+
+/* Color formats for 2d packets
+ */
+#define R200_CP_COLOR_FORMAT_CI8       2
+#define R200_CP_COLOR_FORMAT_ARGB1555  3
+#define R200_CP_COLOR_FORMAT_RGB565    4
+#define R200_CP_COLOR_FORMAT_ARGB8888  6
+#define R200_CP_COLOR_FORMAT_RGB332    7
+#define R200_CP_COLOR_FORMAT_RGB8      9
+#define R200_CP_COLOR_FORMAT_ARGB4444  15
+
+/*
+ * CP type-3 packets
+ */
+#define R200_CP_CMD_NOP                 0xC0001000
+#define R200_CP_CMD_NEXT_CHAR           0xC0001900
+#define R200_CP_CMD_PLY_NEXTSCAN        0xC0001D00
+#define R200_CP_CMD_SET_SCISSORS        0xC0001E00
+#define R200_CP_CMD_LOAD_MICROCODE      0xC0002400
+#define R200_CP_CMD_WAIT_FOR_IDLE       0xC0002600
+#define R200_CP_CMD_3D_DRAW_VBUF        0xC0002800
+#define R200_CP_CMD_3D_DRAW_IMMD        0xC0002900
+#define R200_CP_CMD_3D_DRAW_INDX        0xC0002A00
+#define R200_CP_CMD_LOAD_PALETTE        0xC0002C00
+#define R200_CP_CMD_3D_LOAD_VBPNTR      0xC0002F00
+#define R200_CP_CMD_INDX_BUFFER         0xC0003300
+#define R200_CP_CMD_3D_DRAW_VBUF_2      0xC0003400
+#define R200_CP_CMD_3D_DRAW_IMMD_2      0xC0003500
+#define R200_CP_CMD_3D_DRAW_INDX_2      0xC0003600
+#define R200_CP_CMD_PAINT              0xC0009100
+#define R200_CP_CMD_BITBLT             0xC0009200
+#define R200_CP_CMD_SMALLTEXT          0xC0009300
+#define R200_CP_CMD_HOSTDATA_BLT       0xC0009400
+#define R200_CP_CMD_POLYLINE           0xC0009500
+#define R200_CP_CMD_POLYSCANLINES      0xC0009800
+#define R200_CP_CMD_PAINT_MULTI                0xC0009A00
+#define R200_CP_CMD_BITBLT_MULTI       0xC0009B00
+#define R200_CP_CMD_TRANS_BITBLT       0xC0009C00
+
+#endif
diff --git a/src/mesa/drivers/dri/r300/r200_sanity.h b/src/mesa/drivers/dri/r300/r200_sanity.h
new file mode 100644 (file)
index 0000000..30852b4
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef R200_SANITY_H
+#define R200_SANITY_H
+
+extern int r200SanityCmdBuffer(r200ContextPtr rmesa,
+                              int nbox, drm_clip_rect_t * boxes);
+
+#endif
diff --git a/src/mesa/drivers/dri/r300/r200_state.h b/src/mesa/drivers/dri/r300/r200_state.h
new file mode 100644 (file)
index 0000000..50bb51a
--- /dev/null
@@ -0,0 +1,61 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_state.h,v 1.2 2002/11/05 17:46:08 tsi Exp $ */
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef __R200_STATE_H__
+#define __R200_STATE_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r200_context.h"
+
+extern void r200InitState(r200ContextPtr rmesa);
+extern void r200InitStateFuncs(struct dd_function_table *functions);
+extern void r200InitTnlFuncs(GLcontext * ctx);
+
+extern void r200UpdateMaterial(GLcontext * ctx);
+
+extern void r200SetCliprects(r200ContextPtr rmesa, GLenum mode);
+extern void r200RecalcScissorRects(r200ContextPtr rmesa);
+extern void r200UpdateViewportOffset(GLcontext * ctx);
+extern void r200UpdateWindow(GLcontext * ctx);
+
+extern void r200ValidateState(GLcontext * ctx);
+
+extern void r200PrintDirty(r200ContextPtr rmesa, const char *msg);
+
+extern void r200LightingSpaceChange(GLcontext * ctx);
+
+#endif
+#endif
diff --git a/src/mesa/drivers/dri/r300/r200_tcl.h b/src/mesa/drivers/dri/r300/r200_tcl.h
new file mode 100644 (file)
index 0000000..4528cf1
--- /dev/null
@@ -0,0 +1,50 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_tcl.h,v 1.2 2002/12/16 16:18:55 dawes Exp $ */
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef __R200_TCL_H__
+#define __R200_TCL_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r200_context.h"
+
+extern void r200TclPrimitive(GLcontext * ctx, GLenum prim, int hw_prim);
+extern void r200EmitEltPrimitive(GLcontext * ctx, GLuint first, GLuint last,
+                                GLuint flags);
+extern void r200EmitPrimitive(GLcontext * ctx, GLuint first, GLuint last,
+                             GLuint flags);
+
+#endif
+#endif
diff --git a/src/mesa/drivers/dri/r300/r200_tex.h b/src/mesa/drivers/dri/r300/r200_tex.h
new file mode 100644 (file)
index 0000000..bc0dbc3
--- /dev/null
@@ -0,0 +1,51 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_tex.h,v 1.1 2002/10/30 12:51:53 alanh Exp $ */
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef __R200_TEX_H__
+#define __R200_TEX_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r200UpdateTextureState(GLcontext * ctx);
+
+extern int r200UploadTexImages(r200ContextPtr rmesa, r200TexObjPtr t,
+                              GLuint face);
+
+extern void r200DestroyTexObj(r200ContextPtr rmesa, r200TexObjPtr t);
+
+extern void r200InitTextureFuncs(struct dd_function_table *functions);
+
+#endif
+#endif                         /* __R200_TEX_H__ */
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
new file mode 100644 (file)
index 0000000..7c51e10
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+#include "glheader.h"
+#include "state.h"
+#include "imports.h"
+#include "macros.h"
+#include "context.h"
+#include "swrast/swrast.h"
+#include "simple_list.h"
+
+#include "drm.h"
+#include "radeon_drm.h"
+
+#include "radeon_ioctl.h"
+#include "r300_context.h"
+#include "r300_ioctl.h"
+#include "r300_reg.h"
+#include "r300_cmdbuf.h"
+
+
+/**
+ * Send the current command buffer via ioctl to the hardware.
+ */
+int r300FlushCmdBuf(r300ContextPtr r300, const char* caller)
+{
+       int ret;
+       int i;
+       drm_radeon_cmd_buffer_t cmd;
+       int start;
+
+       if (r300->radeon.lost_context)
+               start = 0;
+       else
+               start = r300->cmdbuf.count_reemit;
+
+       if (RADEON_DEBUG & DEBUG_IOCTL) {
+               fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
+
+               if (RADEON_DEBUG & DEBUG_VERBOSE)
+                       for (i = start; i < r300->cmdbuf.count_used; ++i)
+                               fprintf(stderr, "%d: %08x\n", i,
+                                       r300->cmdbuf.cmd_buf[i]);
+       }
+
+       LOCK_HARDWARE(&r300->radeon);
+
+       cmd.buf = (char*)(r300->cmdbuf.cmd_buf + start);
+       cmd.bufsz = (r300->cmdbuf.count_used - start) * 4;
+
+#if 0 // TODO: scissors
+       if (rmesa->state.scissor.enabled) {
+               cmd.nbox = rmesa->state.scissor.numClipRects;
+               cmd.boxes = (drm_clip_rect_t *) rmesa->state.scissor.pClipRects;
+       } else {
+#endif
+               cmd.nbox = r300->radeon.numClipRects;
+               cmd.boxes = (drm_clip_rect_t *) r300->radeon.pClipRects;
+#if 0
+       }
+#endif
+
+       ret = drmCommandWrite(r300->radeon.dri.fd,
+                             DRM_RADEON_CMDBUF, &cmd, sizeof(cmd));
+       if (ret) {
+               UNLOCK_HARDWARE(&r300->radeon);
+               fprintf(stderr, "drmCommandWrite: %d\n", ret);
+               exit(-1);
+       }
+
+       if (RADEON_DEBUG & DEBUG_SYNC) {
+               fprintf(stderr, "Syncing in %s\n\n", __FUNCTION__);
+               radeonWaitForIdleLocked(&r300->radeon);
+       }
+
+       UNLOCK_HARDWARE(&r300->radeon);
+
+       r300->cmdbuf.count_used = 0;
+       r300->cmdbuf.count_reemit = 0;
+
+       return ret;
+}
+
+
+static void print_state_atom(struct r300_state_atom *state, int dwords)
+{
+       int i;
+
+       fprintf(stderr, "  emit %s/%d/%d\n", state->name, dwords, state->cmd_size);
+
+       if (RADEON_DEBUG & DEBUG_VERBOSE)
+               for (i = 0; i < dwords; i++)
+                       fprintf(stderr, "      %s[%d]: %08X\n", state->name, i,
+                               state->cmd[i]);
+}
+
+/**
+ * Emit all atoms with a dirty field equal to dirty.
+ *
+ * The caller must have ensured that there is enough space in the command
+ * buffer.
+ */
+static __inline__ void r300DoEmitState(r300ContextPtr r300, GLboolean dirty)
+{
+       struct r300_state_atom* atom;
+       uint32_t* dest;
+
+       dest = r300->cmdbuf.cmd_buf + r300->cmdbuf.count_used;
+
+       if (RADEON_DEBUG & DEBUG_STATE) {
+               foreach(atom, &r300->hw.atomlist) {
+                       if ((atom->dirty || r300->hw.all_dirty) == dirty) {
+                               int dwords = (*atom->check)(r300, atom);
+
+                               if (dwords)
+                                       print_state_atom(atom, dwords);
+                               else
+                                       fprintf(stderr, "  skip state %s\n",
+                                               atom->name);
+                       }
+               }
+       }
+
+       foreach(atom, &r300->hw.atomlist) {
+               if ((atom->dirty || r300->hw.all_dirty) == dirty) {
+                       int dwords = (*atom->check)(r300, atom);
+
+                       if (dwords) {
+                               memcpy(dest, atom->cmd, dwords*4);
+                               dest += dwords;
+                               r300->cmdbuf.count_used += dwords;
+                               atom->dirty = GL_FALSE;
+                       }
+               }
+       }
+}
+
+
+/**
+ * Copy dirty hardware state atoms into the command buffer.
+ *
+ * We also copy out clean state if we're at the start of a buffer. That makes
+ * it easy to recover from lost contexts.
+ */
+void r300EmitState(r300ContextPtr r300)
+{
+       if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_PRIMS))
+               fprintf(stderr, "%s\n", __FUNCTION__);
+
+       if (r300->cmdbuf.count_used && !r300->hw.is_dirty && !r300->hw.all_dirty)
+               return;
+
+       /* To avoid going across the entire set of states multiple times, just check
+        * for enough space for the case of emitting all state, and inline the
+        * r300AllocCmdBuf code here without all the checks.
+        */
+       r300EnsureCmdBufSpace(r300, r300->hw.max_state_size, __FUNCTION__);
+
+       if (!r300->cmdbuf.count_used) {
+               if (RADEON_DEBUG & DEBUG_STATE)
+                       fprintf(stderr, "Begin reemit state\n");
+
+               r300DoEmitState(r300, GL_FALSE);
+               r300->cmdbuf.count_reemit = r300->cmdbuf.count_used;
+       }
+
+       if (RADEON_DEBUG & DEBUG_STATE)
+               fprintf(stderr, "Begin dirty state\n");
+
+       r300DoEmitState(r300, GL_TRUE);
+
+       assert(r300->cmdbuf.count_used < r300->cmdbuf.size);
+
+       r300->hw.is_dirty = GL_FALSE;
+       r300->hw.all_dirty = GL_FALSE;
+}
+
+
+static __inline__ uint32_t cmducs(int reg, int count)
+{
+       drm_r300_cmd_header_t cmd;
+
+       cmd.unchecked_state.cmd_type = R300_CMD_UNCHECKED_STATE;
+       cmd.unchecked_state.count = count;
+       cmd.unchecked_state.reghi = ((unsigned int)reg & 0xFF00) >> 8;
+       cmd.unchecked_state.reglo = ((unsigned int)reg & 0x00FF);
+
+       return cmd.u;
+}
+
+static __inline__ uint32_t cmdvpu(int addr, int count)
+{
+       drm_r300_cmd_header_t cmd;
+
+       cmd.vpu.cmd_type = R300_CMD_VPU;
+       cmd.vpu.count = count;
+       cmd.vpu.adrhi = ((unsigned int)addr & 0xFF00) >> 8;
+       cmd.vpu.adrlo = ((unsigned int)addr & 0x00FF);
+
+       return cmd.u;
+}
+
+#define CHECK( NM, COUNT )                             \
+static int check_##NM( r300ContextPtr r300,            \
+                       struct r300_state_atom* atom )  \
+{                                                      \
+   (void) atom;        (void) r300;                            \
+   return (COUNT);                                     \
+}
+
+#define ucscount(ptr) (((drm_r300_cmd_header_t*)(ptr))->unchecked_state.count)
+#define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
+
+CHECK( always, atom->cmd_size )
+CHECK( never, 0 )
+CHECK( variable, ucscount(atom->cmd) ? (1 + ucscount(atom->cmd)) : 0 )
+CHECK( vpu, vpucount(atom->cmd) ? (1 + vpucount(atom->cmd)*4) : 0 )
+
+#undef ucscount
+
+#define ALLOC_STATE( ATOM, CHK, SZ, NM, IDX )                          \
+   do {                                                                        \
+      r300->hw.ATOM.cmd_size = SZ;                                     \
+      r300->hw.ATOM.cmd = (uint32_t*)CALLOC(SZ * sizeof(uint32_t));    \
+      r300->hw.ATOM.name = NM;                                         \
+      r300->hw.ATOM.idx = IDX;                                         \
+      r300->hw.ATOM.check = check_##CHK;                               \
+      r300->hw.ATOM.dirty = GL_FALSE;                                  \
+      r300->hw.max_state_size += SZ;                                   \
+   } while (0)
+
+
+/**
+ * Allocate memory for the command buffer and initialize the state atom
+ * list. Note that the initial hardware state is set by r300InitState().
+ */
+void r300InitCmdBuf(r300ContextPtr r300)
+{
+       int size;
+
+       r300->hw.max_state_size = 0;
+
+       /* Initialize state atoms */
+       ALLOC_STATE( vpt, always, R300_VPT_CMDSIZE, "vpt", 0 );
+               r300->hw.vpt.cmd[R300_VPT_CMD_0] = cmducs(R300_SE_VPORT_XSCALE, 6);
+       ALLOC_STATE( unk2080, always, 2, "unk2080", 0 );
+               r300->hw.unk2080.cmd[0] = cmducs(0x2080, 1);
+       ALLOC_STATE( ovf, always, R300_OVF_CMDSIZE, "ovf", 0 );
+               r300->hw.ovf.cmd[R300_OVF_CMD_0] = cmducs(R300_VAP_OUTPUT_VTX_FMT_0, 2);
+       ALLOC_STATE( unk20B0, always, 3, "unk20B0", 0 );
+               r300->hw.unk20B0.cmd[0] = cmducs(0x20B0, 2);
+       ALLOC_STATE( unk2134, always, 3, "unk2134", 0 );
+               r300->hw.unk2134.cmd[0] = cmducs(0x2134, 2);
+       ALLOC_STATE( unk2140, always, 2, "unk2140", 0 );
+               r300->hw.unk2140.cmd[0] = cmducs(0x2140, 1);
+       ALLOC_STATE( vir[0], variable, R300_VIR_CMDSIZE, "vir/0", 0 );
+               r300->hw.vir[0].cmd[R300_VIR_CMD_0] = cmducs(R300_VAP_INPUT_ROUTE_0_0, 1);
+       ALLOC_STATE( vir[1], variable, R300_VIR_CMDSIZE, "vir/1", 1 );
+               r300->hw.vir[1].cmd[R300_VIR_CMD_0] = cmducs(R300_VAP_INPUT_ROUTE_1_0, 1);
+       ALLOC_STATE( vic, always, R300_VIC_CMDSIZE, "vic", 0 );
+               r300->hw.vic.cmd[R300_VIC_CMD_0] = cmducs(R300_VAP_INPUT_CNTL_0, 2);
+       ALLOC_STATE( unk21DC, always, 2, "unk21DC", 0 );
+               r300->hw.unk21DC.cmd[0] = cmducs(0x21DC, 1);
+       ALLOC_STATE( unk221C, always, 2, "unk221C", 0 );
+               r300->hw.unk221C.cmd[0] = cmducs(0x221C, 1);
+       ALLOC_STATE( unk2220, always, 5, "unk2220", 0 );
+               r300->hw.unk2220.cmd[0] = cmducs(0x2220, 4);
+       ALLOC_STATE( unk2288, always, 2, "unk2288", 0 );
+               r300->hw.unk2288.cmd[0] = cmducs(0x2288, 1);
+       ALLOC_STATE( pvs, always, R300_PVS_CMDSIZE, "pvs", 0 );
+               r300->hw.pvs.cmd[R300_PVS_CMD_0] = cmducs(R300_VAP_PVS_CNTL_1, 3);
+       ALLOC_STATE( unk4008, always, 2, "unk4008", 0 );
+               r300->hw.unk4008.cmd[0] = cmducs(0x4008, 1);
+       ALLOC_STATE( unk4010, always, 6, "unk4010", 0 );
+               r300->hw.unk4010.cmd[0] = cmducs(0x4010, 5);
+       ALLOC_STATE( txe, always, R300_TXE_CMDSIZE, "txe", 0 );
+               r300->hw.txe.cmd[R300_TXE_CMD_0] = cmducs(R300_TX_ENABLE, 1);
+       ALLOC_STATE( unk4200, always, 5, "unk4200", 0 );
+               r300->hw.unk4200.cmd[0] = cmducs(0x4200, 4);
+       ALLOC_STATE( unk4214, always, 2, "unk4214", 0 );
+               r300->hw.unk4214.cmd[0] = cmducs(0x4214, 1);
+       ALLOC_STATE( unk4230, always, 4, "unk4230", 0 );
+               r300->hw.unk4230.cmd[0] = cmducs(0x4230, 3);
+       ALLOC_STATE( unk4260, always, 4, "unk4260", 0 );
+               r300->hw.unk4260.cmd[0] = cmducs(0x4260, 3);
+       ALLOC_STATE( unk4274, always, 5, "unk4274", 0 );
+               r300->hw.unk4274.cmd[0] = cmducs(0x4274, 4);
+       ALLOC_STATE( unk4288, always, 6, "unk4288", 0 );
+               r300->hw.unk4288.cmd[0] = cmducs(0x4288, 5);
+       ALLOC_STATE( unk42A0, always, 2, "unk42A0", 0 );
+               r300->hw.unk42A0.cmd[0] = cmducs(0x42A0, 1);
+       ALLOC_STATE( unk42B4, always, 3, "unk42B4", 0 );
+               r300->hw.unk42B4.cmd[0] = cmducs(0x42B4, 2);
+       ALLOC_STATE( unk42C0, always, 3, "unk42C0", 0 );
+               r300->hw.unk42C0.cmd[0] = cmducs(0x42C0, 2);
+       ALLOC_STATE( rc, always, R300_RC_CMDSIZE, "rc", 0 );
+               r300->hw.rc.cmd[R300_RC_CMD_0] = cmducs(R300_RS_CNTL_0, 2);
+       ALLOC_STATE( ri, always, R300_RI_CMDSIZE, "ri", 0 );
+               r300->hw.ri.cmd[R300_RI_CMD_0] = cmducs(R300_RS_INTERP_0, 8);
+       ALLOC_STATE( rr, variable, R300_RR_CMDSIZE, "rr", 0 );
+               r300->hw.rr.cmd[R300_RR_CMD_0] = cmducs(R300_RS_ROUTE_0, 1);
+       ALLOC_STATE( unk43A4, always, 3, "unk43A4", 0 );
+               r300->hw.unk43A4.cmd[0] = cmducs(0x43A4, 2);
+       ALLOC_STATE( unk43E0, always, 4, "unk43E0", 0 );
+               r300->hw.unk43E0.cmd[0] = cmducs(0x43E0, 3);
+       ALLOC_STATE( fp, always, R300_FP_CMDSIZE, "fp", 0 );
+               r300->hw.fp.cmd[R300_FP_CMD_0] = cmducs(R300_PFS_CNTL_0, 3);
+               r300->hw.fp.cmd[R300_FP_CMD_1] = cmducs(R300_PFS_NODE_0, 4);
+       ALLOC_STATE( unk46A4, always, 6, "unk46A4", 0 );
+               r300->hw.unk46A4.cmd[0] = cmducs(0x46A4, 5);
+       ALLOC_STATE( fpi[0], variable, R300_FPI_CMDSIZE, "fpi/0", 0 );
+               r300->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmducs(R300_PFS_INSTR0_0, 1);
+       ALLOC_STATE( fpi[1], variable, R300_FPI_CMDSIZE, "fpi/1", 1 );
+               r300->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmducs(R300_PFS_INSTR1_0, 1);
+       ALLOC_STATE( fpi[2], variable, R300_FPI_CMDSIZE, "fpi/2", 2 );
+               r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmducs(R300_PFS_INSTR2_0, 1);
+       ALLOC_STATE( fpi[3], variable, R300_FPI_CMDSIZE, "fpi/3", 3 );
+               r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmducs(R300_PFS_INSTR3_0, 1);
+       ALLOC_STATE( unk4BC0, always, 2, "unk4BC0", 0 );
+               r300->hw.unk4BC0.cmd[0] = cmducs(0x4BC0, 1);
+       ALLOC_STATE( unk4BC8, always, 4, "unk4BC8", 0 );
+               r300->hw.unk4BC8.cmd[0] = cmducs(0x4BC8, 3);
+       ALLOC_STATE( at, always, R300_AT_CMDSIZE, "at", 0 );
+               r300->hw.at.cmd[R300_AT_CMD_0] = cmducs(R300_PP_ALPHA_TEST, 1);
+       ALLOC_STATE( unk4BD8, always, 2, "unk4BD8", 0 );
+               r300->hw.unk4BD8.cmd[0] = cmducs(0x4BD8, 1);
+       ALLOC_STATE( unk4E00, always, 2, "unk4E00", 0 );
+               r300->hw.unk4E00.cmd[0] = cmducs(0x4E00, 1);
+       ALLOC_STATE( bld, always, R300_BLD_CMDSIZE, "bld", 0 );
+               r300->hw.bld.cmd[R300_BLD_CMD_0] = cmducs(R300_RB3D_CBLEND, 2);
+       ALLOC_STATE( cmk, always, R300_CMK_CMDSIZE, "cmk", 0 );
+               r300->hw.cmk.cmd[R300_CMK_CMD_0] = cmducs(R300_RB3D_COLORMASK, 1);
+       ALLOC_STATE( unk4E10, always, 4, "unk4E10", 0 );
+               r300->hw.unk4E10.cmd[0] = cmducs(0x4E10, 3);
+       ALLOC_STATE( cb, always, R300_CB_CMDSIZE, "cb", 0 );
+               r300->hw.cb.cmd[R300_CB_CMD_0] = cmducs(R300_RB3D_COLOROFFSET0, 1);
+               r300->hw.cb.cmd[R300_CB_CMD_1] = cmducs(R300_RB3D_COLORPITCH0, 1);
+       ALLOC_STATE( unk4E50, always, 10, "unk4E50", 0 );
+               r300->hw.unk4E50.cmd[0] = cmducs(0x4E50, 9);
+       ALLOC_STATE( unk4E88, always, 2, "unk4E88", 0 );
+               r300->hw.unk4E88.cmd[0] = cmducs(0x4E88, 1);
+       ALLOC_STATE( zc, always, R300_ZC_CMDSIZE, "zc", 0 );
+               r300->hw.zc.cmd[R300_ZC_CMD_0] = cmducs(R300_RB3D_ZCNTL_0, 2);
+       ALLOC_STATE( unk4F08, always, 6, "unk4F08", 0 );
+               r300->hw.unk4F08.cmd[0] = cmducs(0x4F08, 5);
+       ALLOC_STATE( zb, always, R300_ZB_CMDSIZE, "zb", 0 );
+               r300->hw.zb.cmd[R300_ZB_CMD_0] = cmducs(R300_RB3D_DEPTHOFFSET, 2);
+       ALLOC_STATE( unk4F28, always, 2, "unk4F28", 0 );
+               r300->hw.unk4F28.cmd[0] = cmducs(0x4F28, 1);
+       ALLOC_STATE( unk4F30, always, 3, "unk4F30", 0 );
+               r300->hw.unk4F30.cmd[0] = cmducs(0x4F30, 2);
+       ALLOC_STATE( unk4F44, always, 2, "unk4F44", 0 );
+               r300->hw.unk4F44.cmd[0] = cmducs(0x4F44, 1);
+       ALLOC_STATE( unk4F54, always, 2, "unk4F54", 0 );
+               r300->hw.unk4F54.cmd[0] = cmducs(0x4F54, 1);
+
+       ALLOC_STATE( vpi, vpu, R300_VPI_CMDSIZE, "vpi", 0 );
+               r300->hw.vpi.cmd[R300_VPI_CMD_0] = cmdvpu(R300_PVS_UPLOAD_PROGRAM, 0);
+       ALLOC_STATE( vpp, vpu, R300_VPP_CMDSIZE, "vpp", 0 );
+               r300->hw.vpp.cmd[R300_VPP_CMD_0] = cmdvpu(R300_PVS_UPLOAD_PARAMETERS, 0);
+
+       /* Setup the atom linked list */
+       make_empty_list(&r300->hw.atomlist);
+       r300->hw.atomlist.name = "atom-list";
+
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.vpt);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2080);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.ovf);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk20B0);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2134);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2140);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.vir[0]);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.vir[1]);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.vic);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk21DC);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk221C);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2220);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk2288);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.pvs);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4008);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4010);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.txe);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4200);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4214);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4230);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4260);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4274);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4288);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42A0);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42B4);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42C0);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.rc);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.ri);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.rr);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk43A4);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk43E0);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.fp);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk46A4);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[0]);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[1]);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[2]);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[3]);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BC0);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BC8);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.at);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BD8);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4E00);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.bld);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.cmk);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4E10);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.cb);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4E50);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4E88);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.zc);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F08);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.zb);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F28);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F30);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F44);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4F54);
+
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.vpi);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.vpp);
+
+       r300->hw.is_dirty = GL_TRUE;
+       r300->hw.all_dirty = GL_TRUE;
+
+       /* Initialize command buffer */
+       size = 256 * driQueryOptioni(&r300->radeon.optionCache, "command_buffer_size");
+       if (size < 2*r300->hw.max_state_size)
+               size = 2*r300->hw.max_state_size;
+
+       if (RADEON_DEBUG & DEBUG_IOCTL)
+               fprintf(stderr,
+                       "Allocating %d bytes command buffer (max state is %d bytes)\n",
+                       size*4, r300->hw.max_state_size*4);
+
+       r300->cmdbuf.size = size;
+       r300->cmdbuf.cmd_buf = (uint32_t*)CALLOC(size*4);
+       r300->cmdbuf.count_used = 0;
+       r300->cmdbuf.count_reemit = 0;
+}
+
+
+/**
+ * Destroy the command buffer and state atoms.
+ */
+void r300DestroyCmdBuf(r300ContextPtr r300)
+{
+       struct r300_state_atom* atom;
+
+       FREE(r300->cmdbuf.cmd_buf);
+
+       foreach(atom, &r300->hw.atomlist) {
+               FREE(atom->cmd);
+       }
+}
+
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
new file mode 100644 (file)
index 0000000..3227725
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+#ifndef __R300_CMDBUF_H__
+#define __R300_CMDBUF_H__
+
+#include "r300_context.h"
+
+
+extern int r300FlushCmdBuf(r300ContextPtr r300, const char* caller);
+
+extern void r300EmitState(r300ContextPtr r300);
+
+extern void r300InitCmdBuf(r300ContextPtr r300);
+extern void r300DestroyCmdBuf(r300ContextPtr r300);
+
+
+/**
+ * Make sure that enough space is available in the command buffer
+ * by flushing if necessary.
+ */
+static __inline__ void r300EnsureCmdBufSpace(r300ContextPtr r300,
+                                            int dwords, const char* caller)
+{
+       assert(dwords < r300->cmdbuf.size);
+
+       if (r300->cmdbuf.count_used + dwords > r300->cmdbuf.size)
+               r300FlushCmdBuf(r300, caller);
+}
+
+
+/**
+ * Allocate the given number of dwords in the command buffer and return
+ * a pointer to the allocated area.
+ * When necessary, these functions cause a flush. r300AllocCmdBuf() also
+ * causes state reemission after a flush. This is necessary to ensure
+ * correct hardware state after an unlock.
+ */
+static __inline__ uint32_t* r300RawAllocCmdBuf(r300ContextPtr r300,
+                                              int dwords, const char* caller)
+{
+       uint32_t* ptr;
+
+       r300EnsureCmdBufSpace(r300, dwords, caller);
+
+       ptr = &r300->cmdbuf.cmd_buf[r300->cmdbuf.count_used];
+       r300->cmdbuf.count_used += dwords;
+       return ptr;
+}
+
+static __inline__ uint32_t* r300AllocCmdBuf(r300ContextPtr r300,
+                                           int dwords, const char* caller)
+{
+       uint32_t* ptr;
+
+       r300EnsureCmdBufSpace(r300, dwords, caller);
+
+       if (!r300->cmdbuf.count_used) {
+               if (RADEON_DEBUG & DEBUG_IOCTL)
+                       fprintf(stderr, "Reemit state after flush (from %s)\n",
+                               caller);
+               r300EmitState(r300);
+       }
+
+       ptr = &r300->cmdbuf.cmd_buf[r300->cmdbuf.count_used];
+       r300->cmdbuf.count_used += dwords;
+       return ptr;
+}
+
+
+#endif /* __R300_CMDBUF_H__ */
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
new file mode 100644 (file)
index 0000000..3604b11
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ *   Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+#include "glheader.h"
+#include "api_arrayelt.h"
+#include "context.h"
+#include "simple_list.h"
+#include "imports.h"
+#include "matrix.h"
+#include "extensions.h"
+#include "state.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "array_cache/acache.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_pipeline.h"
+
+#include "drivers/common/driverfuncs.h"
+
+#include "radeon_ioctl.h"
+#include "radeon_span.h"
+#include "r300_context.h"
+#include "r300_cmdbuf.h"
+#include "r300_state.h"
+#include "r300_ioctl.h"
+
+#include "vblank.h"
+#include "utils.h"
+#include "xmlpool.h"           /* for symbolic values of enum-type options */
+
+
+/* Extension strings exported by the R300 driver.
+ */
+static const char *const card_extensions[] = {
+       "GL_ARB_multisample",
+       "GL_ARB_multitexture",
+       "GL_ARB_texture_border_clamp",
+       "GL_ARB_texture_compression",
+       "GL_ARB_texture_cube_map",
+       "GL_ARB_texture_env_add",
+       "GL_ARB_texture_env_combine",
+       "GL_ARB_texture_env_dot3",
+       "GL_ARB_texture_mirrored_repeat",
+       "GL_ARB_vertex_buffer_object",
+       "GL_ARB_vertex_program",
+       "GL_EXT_blend_equation_separate",
+       "GL_EXT_blend_func_separate",
+       "GL_EXT_blend_minmax",
+       "GL_EXT_blend_subtract",
+       "GL_EXT_secondary_color",
+       "GL_EXT_stencil_wrap",
+       "GL_EXT_texture_edge_clamp",
+       "GL_EXT_texture_env_combine",
+       "GL_EXT_texture_env_dot3",
+       "GL_EXT_texture_filter_anisotropic",
+       "GL_EXT_texture_lod_bias",
+       "GL_EXT_texture_mirror_clamp",
+       "GL_EXT_texture_rectangle",
+       "GL_ATI_texture_env_combine3",
+       "GL_ATI_texture_mirror_once",
+       "GL_MESA_pack_invert",
+       "GL_MESA_ycbcr_texture",
+       "GL_NV_blend_square",
+       "GL_NV_vertex_program",
+       "GL_SGIS_generate_mipmap",
+       NULL
+};
+
+//extern const struct tnl_pipeline_stage _r300_render_stage;
+//extern const struct tnl_pipeline_stage _r300_tcl_stage;
+
+static const struct tnl_pipeline_stage *r300_pipeline[] = {
+
+       /* Try and go straight to t&l
+        */
+       //&_r200_tcl_stage,
+
+       /* Catch any t&l fallbacks
+        */
+       &_tnl_vertex_transform_stage,
+       &_tnl_normal_transform_stage,
+       &_tnl_lighting_stage,
+       &_tnl_fog_coordinate_stage,
+       &_tnl_texgen_stage,
+       &_tnl_texture_transform_stage,
+       &_tnl_vertex_program_stage,
+
+       /* Try again to go to tcl?
+        *     - no good for asymmetric-twoside (do with multipass)
+        *     - no good for asymmetric-unfilled (do with multipass)
+        *     - good for material
+        *     - good for texgen
+        *     - need to manipulate a bit of state
+        *
+        * - worth it/not worth it?
+        */
+
+       /* Else do them here.
+        */
+       //&_r300_render_stage,
+       &_tnl_render_stage,     /* FALLBACK  */
+       0,
+};
+
+
+/* Create the device specific rendering context.
+ */
+GLboolean r300CreateContext(const __GLcontextModes * glVisual,
+                           __DRIcontextPrivate * driContextPriv,
+                           void *sharedContextPrivate)
+{
+       __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+       radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
+       struct dd_function_table functions;
+       r300ContextPtr r300;
+       GLcontext *ctx;
+       int i;
+       int tcl_mode;
+
+       assert(glVisual);
+       assert(driContextPriv);
+       assert(screen);
+
+       /* Allocate the R300 context */
+       r300 = (r300ContextPtr) CALLOC(sizeof(*r300));
+       if (!r300)
+               return GL_FALSE;
+
+       /* Parse configuration files.
+        * Do this here so that initialMaxAnisotropy is set before we create
+        * the default textures.
+        */
+       driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache,
+                           screen->driScreen->myNum, "r300");
+
+       /* Init default driver functions then plug in our R300-specific functions
+        * (the texture functions are especially important)
+        */
+       _mesa_init_driver_functions(&functions);
+       r300InitIoctlFuncs(&functions);
+       //r200InitStateFuncs(&functions);
+       //r200InitTextureFuncs(&functions);
+
+       if (!radeonInitContext(&r300->radeon, &functions,
+                              glVisual, driContextPriv, sharedContextPrivate)) {
+               FREE(r300);
+               return GL_FALSE;
+       }
+
+       /* Init r300 context data */
+
+       /* Set the maximum texture size small enough that we can guarentee that
+        * all texture units can bind a maximal texture and have them both in
+        * texturable memory at once.
+        */
+
+       ctx = r300->radeon.glCtx;
+       ctx->Const.MaxTextureImageUnits = driQueryOptioni(&r300->radeon.optionCache,
+                                                    "texture_image_units");
+       ctx->Const.MaxTextureCoordUnits = driQueryOptioni(&r300->radeon.optionCache,
+                                                    "texture_coord_units");
+       ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits,
+                                         ctx->Const.MaxTextureCoordUnits);
+       ctx->Const.MaxTextureMaxAnisotropy = 16.0;
+
+       /* No wide points.
+        */
+       ctx->Const.MinPointSize = 1.0;
+       ctx->Const.MinPointSizeAA = 1.0;
+       ctx->Const.MaxPointSize = 1.0;
+       ctx->Const.MaxPointSizeAA = 1.0;
+
+       ctx->Const.MinLineWidth = 1.0;
+       ctx->Const.MinLineWidthAA = 1.0;
+       ctx->Const.MaxLineWidth = 1.0;
+       ctx->Const.MaxLineWidthAA = 1.0;
+
+       /* Initialize the software rasterizer and helper modules.
+        */
+       _swrast_CreateContext(ctx);
+       _ac_CreateContext(ctx);
+       _tnl_CreateContext(ctx);
+       _swsetup_CreateContext(ctx);
+       _ae_create_context(ctx);
+
+#if 0
+       /* Install the customized pipeline:
+        */
+       _tnl_destroy_pipeline(ctx);
+       _tnl_install_pipeline(ctx, r200_pipeline);
+       ctx->Driver.FlushVertices = r200FlushVertices;
+#endif
+
+       /* Try and keep materials and vertices separate:
+        */
+       _tnl_isolate_materials(ctx, GL_TRUE);
+
+       /* Configure swrast and TNL to match hardware characteristics:
+        */
+       _swrast_allow_pixel_fog(ctx, GL_FALSE);
+       _swrast_allow_vertex_fog(ctx, GL_TRUE);
+       _tnl_allow_pixel_fog(ctx, GL_FALSE);
+       _tnl_allow_vertex_fog(ctx, GL_TRUE);
+
+       driInitExtensions(ctx, card_extensions, GL_TRUE);
+
+       radeonInitSpanFuncs(ctx);
+       r300InitCmdBuf(r300);
+       r300InitState(r300);
+#if 0
+       /* plug in a few more device driver functions */
+       /* XXX these should really go right after _mesa_init_driver_functions() */
+       r200InitPixelFuncs(ctx);
+       r200InitTnlFuncs(ctx);
+       r200InitSwtcl(ctx);
+#endif
+       TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
+
+       tcl_mode = driQueryOptioni(&r300->radeon.optionCache, "tcl_mode");
+       if (1 ||
+           driQueryOptionb(&r300->radeon.optionCache, "no_rast")) {
+               fprintf(stderr, "disabling 3D acceleration\n");
+               FALLBACK(&r300->radeon, RADEON_FALLBACK_DISABLE, 1);
+       }
+       if (tcl_mode == DRI_CONF_TCL_SW ||
+           !(r300->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
+               if (r300->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) {
+                       r300->radeon.radeonScreen->chipset &= ~RADEON_CHIPSET_TCL;
+                       fprintf(stderr, "Disabling HW TCL support\n");
+               }
+               TCL_FALLBACK(r300->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
+       }
+
+       return GL_TRUE;
+}
+
+/* Destroy the device specific context.
+ */
+void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
+{
+       GET_CURRENT_CONTEXT(ctx);
+       r300ContextPtr r300 = (r300ContextPtr) driContextPriv->driverPrivate;
+       radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
+
+       /* check if we're deleting the currently bound context */
+       if (&r300->radeon == current) {
+               radeonFlush(r300->radeon.glCtx);
+               _mesa_make_current2(NULL, NULL, NULL);
+       }
+
+       /* Free r300 context resources */
+       assert(r300);           /* should never be null */
+
+       if (r300) {
+               GLboolean release_texture_heaps;
+
+               release_texture_heaps = (r300->radeon.glCtx->Shared->RefCount == 1);
+               _swsetup_DestroyContext(r300->radeon.glCtx);
+               _tnl_DestroyContext(r300->radeon.glCtx);
+               _ac_DestroyContext(r300->radeon.glCtx);
+               _swrast_DestroyContext(r300->radeon.glCtx);
+
+               r300DestroyCmdBuf(r300);
+
+               /* free the Mesa context */
+               r300->radeon.glCtx->DriverCtx = NULL;
+               _mesa_destroy_context(r300->radeon.glCtx);
+
+               /* free the option cache */
+               driDestroyOptionCache(&r300->radeon.optionCache);
+
+               FREE(r300);
+       }
+}
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
new file mode 100644 (file)
index 0000000..b8523b6
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ *   Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+#ifndef __R300_CONTEXT_H__
+#define __R300_CONTEXT_H__
+
+#include "tnl/t_vertex.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "dri_util.h"
+#include "texmem.h"
+
+#include "macros.h"
+#include "mtypes.h"
+#include "colormac.h"
+#include "radeon_context.h"
+
+struct r300_context;
+typedef struct r300_context r300ContextRec;
+typedef struct r300_context *r300ContextPtr;
+
+#include "radeon_lock.h"
+#include "mm.h"
+
+
+static __inline__ uint32_t r300PackFloat32(float fl)
+{
+       union { float fl; uint32_t u; } u;
+
+       u.fl = fl;
+       return u.u;
+}
+
+/**
+ * A block of hardware state.
+ *
+ * When check returns non-zero, the returned number of dwords must be
+ * copied verbatim into the command buffer in order to update a state atom
+ * when it is dirty.
+ */
+struct r300_state_atom {
+       struct r300_state_atom *next, *prev;
+       const char* name;       /* for debug */
+       int cmd_size;           /* maximum size in dwords */
+       GLuint idx;             /* index in an array (e.g. textures) */
+       uint32_t* cmd;
+       GLboolean dirty;
+
+       int (*check)(r300ContextPtr, struct r300_state_atom* atom);
+};
+
+
+#define R300_VPT_CMD_0         0
+#define R300_VPT_XSCALE                1
+#define R300_VPT_XOFFSET       2
+#define R300_VPT_YSCALE                3
+#define R300_VPT_YOFFSET       4
+#define R300_VPT_ZSCALE                5
+#define R300_VPT_ZOFFSET       6
+#define R300_VPT_CMDSIZE       7
+
+#define R300_OVF_CMD_0         0
+#define R300_OVF_FMT_0         1
+#define R300_OVF_FMT_1         2
+#define R300_OVF_CMDSIZE       3
+
+#define R300_VIR_CMD_0         0 /* vir is variable size (at least 1) */
+#define R300_VIR_CNTL_0                1
+#define R300_VIR_CNTL_1                2
+#define R300_VIR_CNTL_2                3
+#define R300_VIR_CNTL_3                4
+#define R300_VIR_CNTL_4                5
+#define R300_VIR_CNTL_5                6
+#define R300_VIR_CNTL_6                7
+#define R300_VIR_CNTL_7                8
+#define R300_VIR_CMDSIZE       9
+
+#define R300_VIC_CMD_0         0
+#define R300_VIC_CNTL_0                1
+#define R300_VIC_CNTL_1                2
+#define R300_VIC_CMDSIZE       3
+
+#define R300_PVS_CMD_0         0
+#define R300_PVS_CNTL_1                1
+#define R300_PVS_CNTL_2                2
+#define R300_PVS_CNTL_3                3
+#define R300_PVS_CMDSIZE       4
+
+#define R300_TXE_CMD_0         0
+#define R300_TXE_ENABLE                1
+#define R300_TXE_CMDSIZE       2
+
+#define R300_RC_CMD_0          0
+#define R300_RC_CNTL_0         1
+#define R300_RC_CNTL_1         2
+#define R300_RC_CMDSIZE                3
+
+#define R300_RI_CMD_0          0
+#define R300_RI_INTERP_0       1
+#define R300_RI_INTERP_1       2
+#define R300_RI_INTERP_2       3
+#define R300_RI_INTERP_3       4
+#define R300_RI_INTERP_4       5
+#define R300_RI_INTERP_5       6
+#define R300_RI_INTERP_6       7
+#define R300_RI_INTERP_7       8
+#define R300_RI_CMDSIZE                9
+
+#define R300_RR_CMD_0          0 /* rr is variable size (at least 1) */
+#define R300_RR_ROUTE_0                1
+#define R300_RR_ROUTE_1                2
+#define R300_RR_ROUTE_2                3
+#define R300_RR_ROUTE_3                4
+#define R300_RR_ROUTE_4                5
+#define R300_RR_ROUTE_5                6
+#define R300_RR_ROUTE_6                7
+#define R300_RR_ROUTE_7                8
+#define R300_RR_CMDSIZE                9
+
+#define R300_FP_CMD_0          0
+#define R300_FP_CNTL0          1
+#define R300_FP_CNTL1          2
+#define R300_FP_CNTL2          3
+#define R300_FP_CMD_1          4
+#define R300_FP_NODE0          5
+#define R300_FP_NODE1          6
+#define R300_FP_NODE2          7
+#define R300_FP_NODE3          8
+#define R300_FP_CMDSIZE                9
+
+#define R300_FPI_CMD_0         0
+#define R300_FPI_INSTR_0       1
+#define R300_FPI_CMDSIZE       65
+
+#define R300_AT_CMD_0          0
+#define R300_AT_ALPHA_TEST     1
+#define R300_AT_CMDSIZE                2
+
+#define R300_BLD_CMD_0         0
+#define R300_BLD_CBLEND                1
+#define R300_BLD_ABLEND                2
+#define R300_BLD_CMDSIZE       3
+
+#define R300_CMK_CMD_0         0
+#define R300_CMK_COLORMASK     1
+#define R300_CMK_CMDSIZE       2
+
+#define R300_CB_CMD_0          0
+#define R300_CB_OFFSET         1
+#define R300_CB_CMD_1          2
+#define R300_CB_PITCH          3
+#define R300_CB_CMDSIZE                4
+
+#define R300_ZC_CMD_0          0
+#define R300_ZC_CNTL_0         1
+#define R300_ZC_CNTL_1         2
+#define R300_ZC_CMDSIZE                3
+
+#define R300_ZB_CMD_0          0
+#define R300_ZB_OFFSET         1
+#define R300_ZB_PITCH          2
+#define R300_ZB_CMDSIZE                3
+
+#define R300_VPI_CMD_0         0
+#define R300_VPI_INSTR_0       1
+#define R300_VPI_CMDSIZE       1025 /* 256 16 byte instructions */
+
+#define R300_VPP_CMD_0         0
+#define R300_VPP_PARAM_0       1
+#define R300_VPP_CMDSIZE       1025 /* 256 4-component parameters */
+
+/**
+ * Cache for hardware register state.
+ */
+struct r300_hw_state {
+       struct r300_state_atom atomlist;
+
+       GLboolean       is_dirty;
+       GLboolean       all_dirty;
+       int             max_state_size; /* in dwords */
+
+       struct r300_state_atom vpt;     /* viewport (1D98) */
+       struct r300_state_atom unk2080; /* (2080) */
+       struct r300_state_atom ovf;     /* output vertex format (2090) */
+       struct r300_state_atom unk20B0; /* (20B0) */
+       struct r300_state_atom unk2134; /* (2134) */
+       struct r300_state_atom unk2140; /* (2140) */
+       struct r300_state_atom vir[2];  /* vap input route (2150/21E0) */
+       struct r300_state_atom vic;     /* vap input control (2180) */
+       struct r300_state_atom unk21DC; /* (21DC) */
+       struct r300_state_atom unk221C; /* (221C) */
+       struct r300_state_atom unk2220; /* (2220) */
+       struct r300_state_atom unk2288; /* (2288) */
+       struct r300_state_atom pvs;     /* pvs_cntl (22D0) */
+       struct r300_state_atom unk4008; /* (4008) */
+       struct r300_state_atom unk4010; /* (4010) */
+       struct r300_state_atom txe;     /* tex enable (4104) */
+       struct r300_state_atom unk4200; /* (4200) */
+       struct r300_state_atom unk4214; /* (4214) */
+       // what about UNKNOWN_421C? (see r300_reg.h)
+       struct r300_state_atom unk4230; /* (4230) */
+       struct r300_state_atom unk4260; /* (4260) */
+       struct r300_state_atom unk4274; /* (4274) */
+       struct r300_state_atom unk4288; /* (4288) */
+       struct r300_state_atom unk42A0; /* (42A0) */
+       struct r300_state_atom unk42B4; /* (42B4) */
+       struct r300_state_atom unk42C0; /* (42C0) */
+       struct r300_state_atom rc;      /* rs control (4300) */
+       struct r300_state_atom ri;      /* rs interpolators (4310) */
+       struct r300_state_atom rr;      /* rs route (4330) */
+       struct r300_state_atom unk43A4; /* (43A4) */
+       struct r300_state_atom unk43E0; /* (43E0) */
+       struct r300_state_atom fp;      /* fragment program cntl + nodes (4600) */
+       struct r300_state_atom unk46A4; /* (46A4) */
+       struct r300_state_atom fpi[4];  /* fp instructions (46C0/47C0/48C0/49C0) */
+       struct r300_state_atom unk4BC0; /* (4BC0) */
+       struct r300_state_atom unk4BC8; /* (4BC8) */
+       struct r300_state_atom at;      /* alpha test (4BD4) */
+       struct r300_state_atom unk4BD8; /* (4BD8) */
+       struct r300_state_atom unk4E00; /* (4E00) */
+       struct r300_state_atom bld;     /* blending (4E04) */
+       struct r300_state_atom cmk;     /* colormask (4E0C) */
+       struct r300_state_atom unk4E10; /* (4E10) */
+       struct r300_state_atom cb;      /* colorbuffer (4E28) */
+       struct r300_state_atom unk4E50; /* (4E50) */
+       struct r300_state_atom unk4E88; /* (4E88) */
+       struct r300_state_atom zc;      /* z control (4F00) */
+       struct r300_state_atom unk4F08; /* (4F08) */
+       struct r300_state_atom zb;      /* z buffer (4F20) */
+       struct r300_state_atom unk4F28; /* (4F28) */
+       struct r300_state_atom unk4F30; /* (4F30) */
+       struct r300_state_atom unk4F44; /* (4F44) */
+       struct r300_state_atom unk4F54; /* (4F54) */
+
+       struct r300_state_atom vpi;     /* vp instructions */
+       struct r300_state_atom vpp;     /* vp parameters */
+};
+
+
+/**
+ * This structure holds the command buffer while it is being constructed.
+ *
+ * The first batch of commands in the buffer is always the state that needs
+ * to be re-emitted when the context is lost. This batch can be skipped
+ * otherwise.
+ */
+struct r300_cmdbuf {
+       int             size;           /* DWORDs allocated for buffer */
+       uint32_t*       cmd_buf;
+       int             count_used;     /* DWORDs filled so far */
+       int             count_reemit;   /* size of re-emission batch */
+};
+
+
+/**
+ * State cache
+ */
+struct r300_state {
+};
+
+
+/**
+ * R300 context structure.
+ */
+struct r300_context {
+       struct radeon_context radeon; /* parent class, must be first */
+
+       struct r300_hw_state hw;
+       struct r300_cmdbuf cmdbuf;
+       struct r300_state state;
+};
+
+#define R300_CONTEXT(ctx)              ((r300ContextPtr)(ctx->DriverCtx))
+
+extern void r300DestroyContext(__DRIcontextPrivate * driContextPriv);
+extern GLboolean r300CreateContext(const __GLcontextModes * glVisual,
+                                  __DRIcontextPrivate * driContextPriv,
+                                  void *sharedContextPrivate);
+
+#endif                         /* __R300_CONTEXT_H__ */
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
new file mode 100644 (file)
index 0000000..a59b1ef
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ *   Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+#include <sched.h>
+#include <errno.h>
+
+#include "glheader.h"
+#include "imports.h"
+#include "macros.h"
+#include "context.h"
+#include "swrast/swrast.h"
+
+#include "r300_context.h"
+#include "radeon_ioctl.h"
+#include "r300_ioctl.h"
+#include "r300_cmdbuf.h"
+#include "r300_state.h"
+#include "r300_program.h"
+#include "radeon_reg.h"
+
+#include "vblank.h"
+
+
+static void r300ClearColorBuffer(r300ContextPtr r300, int buffer)
+{
+       GLcontext* ctx = r300->radeon.glCtx;
+       __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+       int i;
+       GLuint cboffset, cbpitch;
+       drm_r300_cmd_header_t* cmd;
+
+       if (RADEON_DEBUG & DEBUG_IOCTL)
+               fprintf(stderr, "%s: %s buffer\n", __FUNCTION__,
+                       buffer ? "back" : "front");
+
+       if (buffer) {
+               cboffset = r300->radeon.radeonScreen->backOffset;
+               cbpitch = r300->radeon.radeonScreen->backPitch;
+       } else {
+               cboffset = r300->radeon.radeonScreen->frontOffset;
+               cbpitch = r300->radeon.radeonScreen->frontPitch;
+       }
+       cboffset = r300->radeon.radeonScreen->fbLocation;
+
+       R300_STATECHANGE(r300, vpt);
+       r300->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(1.0);
+       r300->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(dPriv->x);
+       r300->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(1.0);
+       r300->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(dPriv->y);
+       r300->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(1.0);
+       r300->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(0.0);
+
+       R300_STATECHANGE(r300, cb);
+       r300->hw.cb.cmd[R300_CB_OFFSET] = cboffset;
+       r300->hw.cb.cmd[R300_CB_PITCH] = cbpitch | R300_COLOR_UNKNOWN_22_23;
+
+       R300_STATECHANGE(r300, unk221C);
+       r300->hw.unk221C.cmd[1] = R300_221C_CLEAR;
+
+       R300_STATECHANGE(r300, ri);
+       for(i = 1; i <= 8; ++i)
+               r300->hw.ri.cmd[i] = R300_RS_INTERP_USED;
+
+       R300_STATECHANGE(r300, rr);
+       ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
+       r300->hw.rr.cmd[1] = 0x00004000;
+
+       R300_STATECHANGE(r300, fp);
+       r300->hw.fp.cmd[R300_FP_CNTL0] = 0; /* 1 pass, no textures */
+       r300->hw.fp.cmd[R300_FP_CNTL1] = 0; /* no temporaries */
+       r300->hw.fp.cmd[R300_FP_CNTL2] = 0; /* no offset, one ALU instr */
+       r300->hw.fp.cmd[R300_FP_NODE0] = 0;
+       r300->hw.fp.cmd[R300_FP_NODE1] = 0;
+       r300->hw.fp.cmd[R300_FP_NODE2] = 0;
+       r300->hw.fp.cmd[R300_FP_NODE3] = R300_PFS_NODE_LAST_NODE;
+
+       R300_STATECHANGE(r300, fpi[0]);
+       R300_STATECHANGE(r300, fpi[1]);
+       R300_STATECHANGE(r300, fpi[2]);
+       R300_STATECHANGE(r300, fpi[3]);
+       ((drm_r300_cmd_header_t*)r300->hw.fpi[0].cmd)->unchecked_state.count = 1;
+       ((drm_r300_cmd_header_t*)r300->hw.fpi[1].cmd)->unchecked_state.count = 1;
+       ((drm_r300_cmd_header_t*)r300->hw.fpi[2].cmd)->unchecked_state.count = 1;
+       ((drm_r300_cmd_header_t*)r300->hw.fpi[3].cmd)->unchecked_state.count = 1;
+
+       /* MOV o0, t0 */
+       r300->hw.fpi[0].cmd[1] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO));
+       r300->hw.fpi[1].cmd[1] = FP_SELC(0,NO,XYZ,FP_TMP(0),0,0);
+       r300->hw.fpi[2].cmd[1] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO));
+       r300->hw.fpi[3].cmd[1] = FP_SELA(0,NO,W,FP_TMP(0),0,0);
+
+       R300_STATECHANGE(r300, pvs);
+       r300->hw.pvs.cmd[R300_PVS_CNTL_1] =
+               (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) |
+               (0 << R300_PVS_CNTL_1_UNKNOWN_SHIFT) |
+               (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
+       r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0; /* no parameters */
+       r300->hw.pvs.cmd[R300_PVS_CNTL_3] =
+               (1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT);
+
+       R300_STATECHANGE(r300, vpi);
+       ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->unchecked_state.count = 8;
+
+       /* MOV o0, i0; */
+       r300->hw.vpi.cmd[1] = VP_OUT(ADD,OUT,0,XYZW);
+       r300->hw.vpi.cmd[2] = VP_IN(IN,0);
+       r300->hw.vpi.cmd[3] = VP_ZERO();
+       r300->hw.vpi.cmd[4] = 0;
+
+       /* MOV o1, i1; */
+       r300->hw.vpi.cmd[5] = VP_OUT(ADD,OUT,1,XYZW);
+       r300->hw.vpi.cmd[6] = VP_IN(IN,1);
+       r300->hw.vpi.cmd[7] = VP_ZERO();
+       r300->hw.vpi.cmd[8] = 0;
+
+       /* Make sure we have enough space */
+       r300EnsureCmdBufSpace(r300, r300->hw.max_state_size + 9, __FUNCTION__);
+
+       r300EmitState(r300);
+
+       cmd = (drm_r300_cmd_header_t*)r300AllocCmdBuf(r300, 9, __FUNCTION__);
+       cmd[0].packet3.cmd_type = R300_CMD_PACKET3;
+       cmd[0].packet3.packet = R300_CMD_PACKET3_CLEAR;
+       cmd[1].u = r300PackFloat32(dPriv->w / 2.0); /* my guess is as good as yours */
+       cmd[2].u = r300PackFloat32(dPriv->h / 2.0);
+       cmd[3].u = r300PackFloat32(0.0);
+       cmd[4].u = r300PackFloat32(1.0);
+       cmd[5].u = r300PackFloat32(ctx->Color.ClearColor[0]);
+       cmd[6].u = r300PackFloat32(ctx->Color.ClearColor[1]);
+       cmd[7].u = r300PackFloat32(ctx->Color.ClearColor[2]);
+       cmd[8].u = r300PackFloat32(ctx->Color.ClearColor[3]);
+}
+
+
+/**
+ * Buffer clear
+ */
+static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all,
+                     GLint cx, GLint cy, GLint cw, GLint ch)
+{
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
+       __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+       int flags = 0;
+       int swapped;
+
+       if (RADEON_DEBUG & DEBUG_IOCTL)
+               fprintf(stderr, "%s:  all=%d cx=%d cy=%d cw=%d ch=%d\n",
+                       __FUNCTION__, all, cx, cy, cw, ch);
+
+       {
+               LOCK_HARDWARE(&r300->radeon);
+               UNLOCK_HARDWARE(&r300->radeon);
+               if (dPriv->numClipRects == 0)
+                       return;
+       }
+
+       if (mask & DD_FRONT_LEFT_BIT) {
+               flags |= DD_FRONT_LEFT_BIT;
+               mask &= ~DD_FRONT_LEFT_BIT;
+       }
+
+       if (mask & DD_BACK_LEFT_BIT) {
+               flags |= DD_BACK_LEFT_BIT;
+               mask &= ~DD_BACK_LEFT_BIT;
+       }
+
+       if (mask) {
+               if (RADEON_DEBUG & DEBUG_FALLBACKS)
+                       fprintf(stderr, "%s: swrast clear, mask: %x\n",
+                               __FUNCTION__, mask);
+               _swrast_Clear(ctx, mask, all, cx, cy, cw, ch);
+       }
+
+       swapped = r300->radeon.doPageFlip && (r300->radeon.sarea->pfCurrentPage == 1);
+
+       if (flags & DD_FRONT_LEFT_BIT)
+               r300ClearColorBuffer(r300, swapped);
+
+       if (flags & DD_BACK_LEFT_BIT)
+               r300ClearColorBuffer(r300, swapped ^ 1);
+
+       /* Recalculate the hardware set. This could be done more efficiently,
+        * but do keep it like this for now.
+        */
+       r300ResetHwState(r300);
+}
+
+void r300Flush(GLcontext * ctx)
+{
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
+
+       if (RADEON_DEBUG & DEBUG_IOCTL)
+               fprintf(stderr, "%s\n", __FUNCTION__);
+
+       if (r300->cmdbuf.count_used > r300->cmdbuf.count_reemit)
+               r300FlushCmdBuf(r300, __FUNCTION__);
+}
+
+void r300InitIoctlFuncs(struct dd_function_table *functions)
+{
+       functions->Clear = r300Clear;
+       functions->Finish = radeonFinish;
+       functions->Flush = r300Flush;
+}
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.h b/src/mesa/drivers/dri/r300/r300_ioctl.h
new file mode 100644 (file)
index 0000000..26ca07c
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ *   Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+#ifndef __R300_IOCTL_H__
+#define __R300_IOCTL_H__
+
+extern void r300Flush(GLcontext * ctx);
+extern void r300InitIoctlFuncs(struct dd_function_table *functions);
+
+#endif                         /* __R300_IOCTL_H__ */
diff --git a/src/mesa/drivers/dri/r300/r300_program.h b/src/mesa/drivers/dri/r300/r300_program.h
new file mode 100644 (file)
index 0000000..b78ac17
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+Copyright (C) 2004 Nicolai Haehnle.  All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+#ifndef __R300_PROGRAM_H__
+#define __R300_PROGRAM_H__
+
+#include "r300_reg.h"
+
+/**
+ * Vertex program helper macros
+ */
+
+/* Produce out dword */
+#define VP_OUTCLASS_TMP                R300_VPI_OUT_REG_CLASS_TEMPORARY
+#define VP_OUTCLASS_OUT                R300_VPI_OUT_REG_CLASS_RESULT
+
+#define VP_OUTMASK_X   R300_VPI_OUT_WRITE_X
+#define VP_OUTMASK_Y   R300_VPI_OUT_WRITE_Y
+#define VP_OUTMASK_Z   R300_VPI_OUT_WRITE_Z
+#define VP_OUTMASK_W   R300_VPI_OUT_WRITE_W
+#define VP_OUTMASK_XY  (VP_OUTMASK_X|VP_OUTMASK_Y)
+#define VP_OUTMASK_XZ  (VP_OUTMASK_X|VP_OUTMASK_Z)
+#define VP_OUTMASK_XW  (VP_OUTMASK_X|VP_OUTMASK_W)
+#define VP_OUTMASK_XYZ (VP_OUTMASK_XY|VP_OUTMASK_Z)
+#define VP_OUTMASK_XYW (VP_OUTMASK_XY|VP_OUTMASK_W)
+#define VP_OUTMASK_XZW (VP_OUTMASK_XZ|VP_OUTMASK_W)
+#define VP_OUTMASK_XYZW        (VP_OUTMASK_XYZ|VP_OUTMASK_W)
+#define VP_OUTMASK_YZ  (VP_OUTMASK_Y|VP_OUTMASK_Z)
+#define VP_OUTMASK_YW  (VP_OUTMASK_Y|VP_OUTMASK_W)
+#define VP_OUTMASK_YZW (VP_OUTMASK_YZ|VP_OUTMASK_W)
+#define VP_OUTMASK_ZW  (VP_OUTMASK_Z|VP_OUTMASK_W)
+
+#define VP_OUT(instr,outclass,outidx,outmask) \
+       (R300_VPI_OUT_OP_##instr |                              \
+       ((outidx) << R300_VPI_OUT_REG_INDEX_SHIFT) |            \
+       VP_OUTCLASS_##outclass |                                \
+       VP_OUTMASK_##outmask)
+
+/* Produce in dword */
+#define VP_INCLASS_TMP         R300_VPI_IN_REG_CLASS_TEMPORARY
+#define VP_INCLASS_IN          R300_VPI_IN_REG_CLASS_ATTRIBUTE
+#define VP_INCLASS_CONST       R300_VPI_IN_REG_CLASS_PARAMETER
+
+#define VP_IN(class,idx) \
+       (((idx) << R300_VPI_IN_REG_INDEX_SHIFT) |               \
+       VP_INCLASS_##class |                                    \
+       (R300_VPI_IN_SELECT_X << R300_VPI_IN_X_SHIFT) |         \
+       (R300_VPI_IN_SELECT_Y << R300_VPI_IN_Y_SHIFT) |         \
+       (R300_VPI_IN_SELECT_Z << R300_VPI_IN_Z_SHIFT) |         \
+       (R300_VPI_IN_SELECT_W << R300_VPI_IN_W_SHIFT))
+#define VP_ZERO() \
+       ((R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_X_SHIFT) |     \
+       (R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_Y_SHIFT) |      \
+       (R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_Z_SHIFT) |      \
+       (R300_VPI_IN_SELECT_ZERO << R300_VPI_IN_W_SHIFT))
+#define VP_ONE() \
+       ((R300_VPI_IN_SELECT_ONE << R300_VPI_IN_X_SHIFT) |      \
+       (R300_VPI_IN_SELECT_ONE << R300_VPI_IN_Y_SHIFT) |       \
+       (R300_VPI_IN_SELECT_ONE << R300_VPI_IN_Z_SHIFT) |       \
+       (R300_VPI_IN_SELECT_ONE << R300_VPI_IN_W_SHIFT))
+
+#define VP_NEG(in,comp)                ((in) ^ (R300_VPI_IN_NEG_##comp))
+#define VP_NEGALL(in,comp)     VP_NEG(VP_NEG(VP_NEG(VP_NEG((in),X),Y),Z),W)
+
+/**
+ * Fragment program helper macros
+ */
+
+/* Produce unshifted source selectors */
+#define FP_TMP(idx) (idx)
+#define FP_CONST(idx) ((idx) | (1 << 5))
+
+/* Produce source/dest selector dword */
+#define FP_SELC_MASK_NO                0
+#define FP_SELC_MASK_X         1
+#define FP_SELC_MASK_Y         2
+#define FP_SELC_MASK_XY                3
+#define FP_SELC_MASK_Z         4
+#define FP_SELC_MASK_XZ                5
+#define FP_SELC_MASK_YZ                6
+#define FP_SELC_MASK_XYZ       7
+
+#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \
+       (((destidx) << R300_FPI1_DSTC_SHIFT) |          \
+        (FP_SELC_MASK_##regmask << 23) |               \
+        (FP_SELC_MASK_##outmask << 26) |               \
+        ((src0) << R300_FPI1_SRC0C_SHIFT) |            \
+        ((src1) << R300_FPI1_SRC1C_SHIFT) |            \
+        ((src2) << R300_FPI1_SRC2C_SHIFT))
+
+#define FP_SELA_MASK_NO                0
+#define FP_SELA_MASK_W         1
+
+#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \
+       (((destidx) << R300_FPI3_DSTA_SHIFT) |          \
+        (FP_SELA_MASK_##regmask << 23) |               \
+        (FP_SELA_MASK_##outmask << 24) |               \
+        ((src0) << R300_FPI3_SRC0A_SHIFT) |            \
+        ((src1) << R300_FPI3_SRC1A_SHIFT) |            \
+        ((src2) << R300_FPI3_SRC2A_SHIFT))
+
+/* Produce unshifted argument selectors */
+#define FP_ARGC(source)        R300_FPI0_ARGC_##source
+#define FP_ARGA(source) R300_FPI2_ARGA_##source
+#define FP_ABS(arg) ((arg) | (1 << 6))
+#define FP_NEG(arg) ((arg) ^ (1 << 5))
+
+/* Produce instruction dword */
+#define FP_INSTRC(opcode,arg0,arg1,arg2) \
+       (R300_FPI0_OUTC_##opcode |              \
+       ((arg0) << R300_FPI0_ARG0C_SHIFT) |     \
+       ((arg1) << R300_FPI0_ARG1C_SHIFT) |     \
+       ((arg2) << R300_FPI0_ARG2C_SHIFT))
+
+#define FP_INSTRA(opcode,arg0,arg1,arg2) \
+       (R300_FPI2_OUTA_##opcode |              \
+       ((arg0) << R300_FPI2_ARG0A_SHIFT) |     \
+       ((arg1) << R300_FPI2_ARG1A_SHIFT) |     \
+       ((arg2) << R300_FPI2_ARG2A_SHIFT))
+
+#endif /* __R300_PROGRAM_H__ */
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
new file mode 100644 (file)
index 0000000..90c5158
--- /dev/null
@@ -0,0 +1,847 @@
+#ifndef _R300_REG_H
+#define _R300_REG_H
+
+/*
+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
+
+
+// BEGIN: Wild guesses
+#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_PRESENT   (1<<1)
+#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) // GUESS
+#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) // GUESS
+#       define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) // GUESS
+#       define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) // GUESS
+
+#define R300_VAP_OUTPUT_VTX_FMT_1           0x2094
+#       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
+// END
+
+// BEGIN: Vertex data assembly - lots of uncertainties
+/* 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_INPUT_ROUTE_0_0            0x2150
+#       define R300_INPUT_ROUTE_COMPONENTS_1     (0 << 0)
+#       define R300_INPUT_ROUTE_COMPONENTS_2     (1 << 0)
+#       define R300_INPUT_ROUTE_COMPONENTS_3     (2 << 0)
+#       define R300_INPUT_ROUTE_COMPONENTS_4     (3 << 0)
+#       define R300_INPUT_ROUTE_COMPONENTS_RGBA  (4 << 0) // GUESS
+#       define R300_VAP_INPUT_ROUTE_IDX_SHIFT    8
+#       define R300_VAP_INPUT_ROUTE_IDX_MASK     (31 << 8) // GUESS
+#       define R300_VAP_INPUT_ROUTE_END          (1 << 13)
+#       define R300_INPUT_ROUTE_IMMEDIATE_MODE   (0 << 14) // GUESS
+#       define R300_INPUT_ROUTE_FLOAT            (1 << 14) // GUESS
+#       define R300_INPUT_ROUTE_UNSIGNED_BYTE    (2 << 14) // GUESS
+#       define R300_INPUT_ROUTE_FLOAT_COLOR      (3 << 14) // GUESS
+#define R300_VAP_INPUT_ROUTE_0_1            0x2154
+#define R300_VAP_INPUT_ROUTE_0_2            0x2158
+#define R300_VAP_INPUT_ROUTE_0_3            0x215C
+
+/* 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_INPUT_CNTL_0               0x2180
+#       define R300_INPUT_CNTL_0_COLOR           0x00000001
+#define R300_VAP_INPUT_CNTL_1               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
+
+/* 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_INPUT_ROUTE_1_0            0x21E0
+#       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_INPUT_ROUTE_SELECT_MASK 7
+#       define R300_INPUT_ROUTE_X_SHIFT          0
+#       define R300_INPUT_ROUTE_Y_SHIFT          3
+#       define R300_INPUT_ROUTE_Z_SHIFT          6
+#       define R300_INPUT_ROUTE_W_SHIFT          9
+#       define R300_INPUT_ROUTE_ENABLE           (15 << 12)
+#define R300_VAP_INPUT_ROUTE_1_1            0x21E4
+#define R300_VAP_INPUT_ROUTE_1_2            0x21E8
+#define R300_VAP_INPUT_ROUTE_1_3            0x21EC
+
+// END
+
+/* 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.
+//
+// Multiple vertex programs and parameter sets can be loaded at once,
+// which could explain the size discrepancy.
+#define R300_VAP_PVS_UPLOAD_ADDRESS         0x2200
+#       define R300_PVS_UPLOAD_PROGRAM           0x00000000
+#       define R300_PVS_UPLOAD_PARAMETERS        0x00000200
+#       define R300_PVS_UPLOAD_UNKNOWN           0x00000400
+/* gap */
+#define R300_VAP_PVS_UPLOAD_DATA            0x2208
+// END
+
+/* 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.
+#define R300_VAP_UNKNOWN_221C               0x221C
+#       define R300_221C_NORMAL                  0x00000000
+#       define R300_221C_CLEAR                   0x0001C000
+
+/* 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_WAITIDLE               0x2284 // GUESS
+
+// Absolutely no clue what this register is about.
+#define R300_VAP_UNKNOWN_2288               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
+// CNTL_1_UNKNOWN somewhere in the middle, but the criteria are not clear.
+#define R300_VAP_PVS_CNTL_1                 0x22D0
+#       define R300_PVS_CNTL_1_PROGRAM_START_SHIFT   0
+#       define R300_PVS_CNTL_1_UNKNOWN_SHIFT         10
+#       define R300_PVS_CNTL_1_PROGRAM_END_SHIFT     20
+// Addresses are relative the the vertex program parameters area.
+#define R300_VAP_PVS_CNTL_2                 0x22D4
+#       define R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0
+#       define R300_PVS_CNTL_2_PARAM_COUNT_SHIFT  16
+#define R300_VAP_PVS_CNTL_3               0x22D8
+#       define R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT 10
+
+// 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
+#define R300_VAP_VTX_END_OF_PKT             0x24AC // write 0 to indicate end of packet?
+
+/* gap */
+// BEGIN: !unverified!
+#define R300_GB_TILE_CONFIG                 0x4018
+#define R300_GB_TILE_ENABLE                      (1 << 0)
+#define R300_GB_TILE_PIPE_COUNT_R300             (0 << 1)
+#define R300_GB_TILE_PIPE_COUNT_RV300            (3 << 1)
+#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)
+// END
+
+/* gap */
+// 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)
+
+// No idea what the purpose is, but it is set to 421C_CLEAR just before
+// issuing the clear command and then reset to 421C_NORMAL afterwards.
+#define R300_UNKNOWN_421C                   0x421C
+#       define R300_421C_NORMAL                  0x00060006
+#       define R300_421C_CLEAR                   0x0F000B40
+
+// BEGIN: Rasterization / Interpolators - many guesses
+// So far, 0_UNKOWN_7 has always been set.
+// 0_UNKNOWN_18 has always been set except for clear operations.
+// 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_CNTL_0                      0x4300
+#       define R300_RS_CNTL_TC_CNT_SHIFT         2
+#       define R300_RS_CNTL_TC_CNT_MASK          (7 << 2)
+#       define R300_RS_CNTL_0_UNKNOWN_7          (1 << 7)
+#       define R300_RS_CNTL_0_UNKNOWN_18         (1 << 18)
+// Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n register.
+#define R300_RS_CNTL_1                      0x4304
+
+/* gap */
+// Only used for texture coordinates (color seems to be always interpolated).
+// 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_INTERP_0                    0x4310
+#define R300_RS_INTERP_1                    0x4314
+#       define R300_RS_INTERP_1_UNKNOWN          0x40
+#define R300_RS_INTERP_2                    0x4318
+#       define R300_RS_INTERP_2_UNKNOWN          0x80
+#define R300_RS_INTERP_3                    0x431C
+#       define R300_RS_INTERP_3_UNKNOWN          0xC0
+#define R300_RS_INTERP_4                    0x4320
+#define R300_RS_INTERP_5                    0x4324
+#define R300_RS_INTERP_6                    0x4328
+#define R300_RS_INTERP_7                    0x432C
+#       define R300_RS_INTERP_SRC_SHIFT          2
+#       define R300_RS_INTERP_SRC_MASK           (7 << 2)
+#       define R300_RS_INTERP_USED               0x00D10000
+
+// These DWORDs control how vertex data is routed into fragment program
+// registers, after interpolators.
+#define R300_RS_ROUTE_0                     0x4330
+#define R300_RS_ROUTE_1                     0x4334
+#define R300_RS_ROUTE_2                     0x4338
+#define R300_RS_ROUTE_3                     0x433C // GUESS
+#define R300_RS_ROUTE_4                     0x4340 // GUESS
+#define R300_RS_ROUTE_5                     0x4344 // GUESS
+#define R300_RS_ROUTE_6                     0x4348 // GUESS
+#define R300_RS_ROUTE_7                     0x434C // GUESS
+#       define R300_RS_ROUTE_SOURCE_INTERP_0     0
+#       define R300_RS_ROUTE_SOURCE_INTERP_1     1
+#       define R300_RS_ROUTE_SOURCE_INTERP_2     2
+#       define R300_RS_ROUTE_SOURCE_INTERP_3     3
+#       define R300_RS_ROUTE_SOURCE_INTERP_4     4
+#       define R300_RS_ROUTE_SOURCE_INTERP_5     5 // GUESS
+#       define R300_RS_ROUTE_SOURCE_INTERP_6     6 // GUESS
+#       define R300_RS_ROUTE_SOURCE_INTERP_7     7 // GUESS
+#       define R300_RS_ROUTE_ENABLE              (1 << 3) // GUESS
+#       define R300_RS_ROUTE_DEST_SHIFT          6
+#       define R300_RS_ROUTE_DEST_MASK           (31 << 6) // GUESS
+
+// Special handling for color: When the fragment program uses color,
+// the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the
+// color register index.
+#       define R300_RS_ROUTE_0_COLOR             (1 << 14)
+#       define R300_RS_ROUTE_0_COLOR_DEST_SHIFT  (1 << 17)
+#       define R300_RS_ROUTE_0_COLOR_DEST_MASK   (31 << 6) // GUESS
+// END
+
+// 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_FILTER_0                    0x4400
+#       define R300_TX_REPEAT                    0
+#       define R300_TX_CLAMP_TO_EDGE             1
+#       define R300_TX_CLAMP                     2
+#       define R300_TX_CLAMP_TO_BORDER           3
+
+#       define R300_TX_WRAP_S_SHIFT              1
+#       define R300_TX_WRAP_S_MASK               (3 << 1)
+#       define R300_TX_WRAP_T_SHIFT              4
+#       define R300_TX_WRAP_T_MASK               (3 << 4)
+#       define R300_TX_MAG_FILTER_NEAREST        (1 << 9)
+#       define R300_TX_MAG_FILTER_LINEAR         (2 << 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_UNK1_0                      0x4440
+#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_SIZE_SHIFT                26 // largest of width, height
+#       define R300_TX_SIZE_MASK                 (15 << 26)
+#define R300_TX_FORMAT_0                    0x44C0
+#define R300_TX_OFFSET_0                    0x4540
+// 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_OFFSET_MASK              0xffffffe0
+#       define R300_TXO_OFFSET_SHIFT             5
+// END
+#define R300_TX_UNK4_0                      0x4580
+#define R300_TX_UNK5_0                      0x45C0
+// END
+
+// 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_PFS_CNTL_0                     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_PFS_CNTL_1                     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_PFS_CNTL_2                     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 << 0)
+#       define R300_PFS_CNTL_TEX_OFFSET_SHIFT    12
+#       define R300_PFS_CNTL_TEX_OFFSET_MASK     (31 << 12) // GUESS
+#       define R300_PFS_CNTL_TEX_END_SHIFT       18
+#       define R300_PFS_CNTL_TEX_END_MASK        (31 << 18) // GUESS
+
+/* 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.
+// LAST_NODE is set for the last node, and only for the last node.
+#define R300_PFS_NODE_0                     0x4610
+#define R300_PFS_NODE_1                     0x4614
+#define R300_PFS_NODE_2                     0x4618
+#define R300_PFS_NODE_3                     0x461C
+#       define R300_PFS_NODE_ALU_OFFSET_SHIFT    0
+#       define R300_PFS_NODE_ALU_OFFSET_MASK     (63 << 0)
+#       define R300_PFS_NODE_ALU_END_SHIFT       6
+#       define R300_PFS_NODE_ALU_END_MASK        (63 << 6)
+#       define R300_PFS_NODE_TEX_OFFSET_SHIFT    12
+#       define R300_PFS_NODE_TEX_OFFSET_MASK     (31 << 12)
+#       define R300_PFS_NODE_TEX_END_SHIFT       17
+#       define R300_PFS_NODE_TEX_END_MASK        (31 << 17)
+#       define R300_PFS_NODE_LAST_NODE           (1 << 22)
+
+// 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_PFS_TEXI_0                     0x4620
+#       define R300_FPITX_SRC_SHIFT              0
+#       define R300_FPITX_SRC_MASK               (31 << 0)
+#       define R300_FPITX_SRC_CONST              (1 << 5) // GUESS
+#       define R300_FPITX_DST_SHIFT              6
+#       define R300_FPITX_DST_MASK               (31 << 6)
+#       define R300_FPITX_IMAGE_SHIFT            11
+#       define R300_FPITX_IMAGE_MASK             (15 << 11) // GUESS based on layout and native limits
+
+// 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
+//  - 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 alll 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_PFS_INSTR1_0                   0x46C0
+#       define R300_FPI1_SRC0C_SHIFT             0
+#       define R300_FPI1_SRC0C_MASK              (31 << 0)
+#       define R300_FPI1_SRC0C_CONST             (1 << 5)
+#       define R300_FPI1_SRC1C_SHIFT             6
+#       define R300_FPI1_SRC1C_MASK              (31 << 6)
+#       define R300_FPI1_SRC1C_CONST             (1 << 11)
+#       define R300_FPI1_SRC2C_SHIFT             12
+#       define R300_FPI1_SRC2C_MASK              (31 << 12)
+#       define R300_FPI1_SRC2C_CONST             (1 << 17)
+#       define R300_FPI1_DSTC_SHIFT              18
+#       define R300_FPI1_DSTC_MASK               (31 << 18)
+#       define R300_FPI1_DSTC_REG_X              (1 << 23)
+#       define R300_FPI1_DSTC_REG_Y              (1 << 24)
+#       define R300_FPI1_DSTC_REG_Z              (1 << 25)
+#       define R300_FPI1_DSTC_OUTPUT_X           (1 << 26)
+#       define R300_FPI1_DSTC_OUTPUT_Y           (1 << 27)
+#       define R300_FPI1_DSTC_OUTPUT_Z           (1 << 28)
+
+#define R300_PFS_INSTR3_0                   0x47C0
+#       define R300_FPI3_SRC0A_SHIFT             0
+#       define R300_FPI3_SRC0A_MASK              (31 << 0)
+#       define R300_FPI3_SRC0A_CONST             (1 << 5)
+#       define R300_FPI3_SRC1A_SHIFT             6
+#       define R300_FPI3_SRC1A_MASK              (31 << 6)
+#       define R300_FPI3_SRC1A_CONST             (1 << 11)
+#       define R300_FPI3_SRC2A_SHIFT             12
+#       define R300_FPI3_SRC2A_MASK              (31 << 12)
+#       define R300_FPI3_SRC2A_CONST             (1 << 17)
+#       define R300_FPI3_DSTA_SHIFT              18
+#       define R300_FPI3_DSTA_MASK               (31 << 18)
+#       define R300_FPI3_DSTA_REG                (1 << 23)
+#       define R300_FPI3_DSTA_OUTPUT             (1 << 24)
+
+#define R300_PFS_INSTR0_0                   0x48C0
+#       define R300_FPI0_ARGC_SRC0C_XYZ          0
+#       define R300_FPI0_ARGC_SRC0C_XXX          1
+#       define R300_FPI0_ARGC_SRC0C_YYY          2
+#       define R300_FPI0_ARGC_SRC0C_ZZZ          3
+#       define R300_FPI0_ARGC_SRC1C_XYZ          4
+#       define R300_FPI0_ARGC_SRC1C_XXX          5
+#       define R300_FPI0_ARGC_SRC1C_YYY          6
+#       define R300_FPI0_ARGC_SRC1C_ZZZ          7
+#       define R300_FPI0_ARGC_SRC2C_XYZ          8
+#       define R300_FPI0_ARGC_SRC2C_XXX          9
+#       define R300_FPI0_ARGC_SRC2C_YYY          10
+#       define R300_FPI0_ARGC_SRC2C_ZZZ          11
+#       define R300_FPI0_ARGC_SRC0A              12
+#       define R300_FPI0_ARGC_SRC1A              13
+#       define R300_FPI0_ARGC_SRC2A              14
+#       define R300_FPI0_ARGC_SRC1C_LRP          15
+#       define R300_FPI0_ARGC_ZERO               20
+#       define R300_FPI0_ARGC_ONE                21
+#       define R300_FPI0_ARGC_HALF               22 // GUESS
+#       define R300_FPI0_ARGC_SRC0C_YZX          23
+#       define R300_FPI0_ARGC_SRC1C_YZX          24
+#       define R300_FPI0_ARGC_SRC2C_YZX          25
+#       define R300_FPI0_ARGC_SRC0C_ZXY          26
+#       define R300_FPI0_ARGC_SRC1C_ZXY          27
+#       define R300_FPI0_ARGC_SRC2C_ZXY          28
+#       define R300_FPI0_ARGC_SRC0CA_WZY         29
+#       define R300_FPI0_ARGC_SRC1CA_WZY         30
+#       define R300_FPI0_ARGC_SRC2CA_WZY         31
+
+#       define R300_FPI0_ARG0C_SHIFT             0
+#       define R300_FPI0_ARG0C_MASK              (31 << 0)
+#       define R300_FPI0_ARG0C_NEG               (1 << 5)
+#       define R300_FPI0_ARG0C_ABS               (1 << 6)
+#       define R300_FPI0_ARG1C_SHIFT             7
+#       define R300_FPI0_ARG1C_MASK              (31 << 7)
+#       define R300_FPI0_ARG1C_NEG               (1 << 12)
+#       define R300_FPI0_ARG1C_ABS               (1 << 13)
+#       define R300_FPI0_ARG2C_SHIFT             14
+#       define R300_FPI0_ARG2C_MASK              (31 << 14)
+#       define R300_FPI0_ARG2C_NEG               (1 << 19)
+#       define R300_FPI0_ARG2C_ABS               (1 << 20)
+#       define R300_FPI0_SPECIAL_LRP             (1 << 21)
+#       define R300_FPI0_OUTC_MAD                (0 << 23)
+#       define R300_FPI0_OUTC_DP3                (1 << 23)
+#       define R300_FPI0_OUTC_DP4                (2 << 23)
+#       define R300_FPI0_OUTC_MIN                (4 << 23)
+#       define R300_FPI0_OUTC_MAX                (5 << 23)
+#       define R300_FPI0_OUTC_CMP                (8 << 23)
+#       define R300_FPI0_OUTC_FRC                (9 << 23)
+#       define R300_FPI0_OUTC_REPL_ALPHA         (10 << 23)
+#       define R300_FPI0_OUTC_SAT                (1 << 30)
+#       define R300_FPI0_UNKNOWN_31              (1 << 31)
+
+#define R300_PFS_INSTR2_0                   0x49C0
+#       define R300_FPI2_ARGA_SRC0C_X            0
+#       define R300_FPI2_ARGA_SRC0C_Y            1
+#       define R300_FPI2_ARGA_SRC0C_Z            2
+#       define R300_FPI2_ARGA_SRC1C_X            3
+#       define R300_FPI2_ARGA_SRC1C_Y            4
+#       define R300_FPI2_ARGA_SRC1C_Z            5
+#       define R300_FPI2_ARGA_SRC2C_X            6
+#       define R300_FPI2_ARGA_SRC2C_Y            7
+#       define R300_FPI2_ARGA_SRC2C_Z            8
+#       define R300_FPI2_ARGA_SRC0A              9
+#       define R300_FPI2_ARGA_SRC1A              10
+#       define R300_FPI2_ARGA_SRC2A              11
+#       define R300_FPI2_ARGA_SRC1A_LRP          15
+#       define R300_FPI2_ARGA_ZERO               16
+#       define R300_FPI2_ARGA_ONE                17
+#       define R300_FPI2_ARGA_HALF               18 // GUESS
+
+#       define R300_FPI2_ARG0A_SHIFT             0
+#       define R300_FPI2_ARG0A_MASK              (31 << 0)
+#       define R300_FPI2_ARG0A_NEG               (1 << 5)
+#       define R300_FPI2_ARG1A_SHIFT             7
+#       define R300_FPI2_ARG1A_MASK              (31 << 7)
+#       define R300_FPI2_ARG1A_NEG               (1 << 12)
+#       define R300_FPI2_ARG2A_SHIFT             14
+#       define R300_FPI2_AEG2A_MASK              (31 << 14)
+#       define R300_FPI2_ARG2A_NEG               (1 << 19)
+#       define R300_FPI2_SPECIAL_LRP             (1 << 21)
+#       define R300_FPI2_OUTA_MAD                (0 << 23)
+#       define R300_FPI2_OUTA_DP4                (1 << 23)
+#       define R300_RPI2_OUTA_MIN                (2 << 23)
+#       define R300_RPI2_OUTA_MAX                (3 << 23)
+#       define R300_FPI2_OUTA_CMP                (6 << 23)
+#       define R300_FPI2_OUTA_FRC                (7 << 23)
+#       define R300_FPI2_OUTA_EX2                (8 << 23)
+#       define R300_FPI2_OUTA_LG2                (9 << 23)
+#       define R300_FPI2_OUTA_RCP                (10 << 23)
+#       define R300_FPI2_OUTA_RSQ                (11 << 23)
+#       define R300_FPI2_OUTA_SAT                (1 << 30)
+#       define R300_FPI2_UNKNOWN_31              (1 << 31)
+// END
+
+/* gap */
+#define R300_PP_ALPHA_TEST                  0x4BD4
+#       define R300_REF_ALPHA_MASK               0x000000ff
+#       define R300_ALPHA_TEST_FAIL              (0 << 8)
+#       define R300_ALPHA_TEST_LESS              (1 << 8)
+#       define R300_ALPHA_TEST_LEQUAL            (2 << 8)
+#       define R300_ALPHA_TEST_EQUAL             (3 << 8)
+#       define R300_ALPHA_TEST_GEQUAL            (4 << 8)
+#       define R300_ALPHA_TEST_GREATER           (5 << 8)
+#       define R300_ALPHA_TEST_NEQUAL            (6 << 8)
+#       define R300_ALPHA_TEST_PASS              (7 << 8)
+#       define R300_ALPHA_TEST_OP_MASK           (7 << 8)
+#       define R300_ALPHA_TEST_ENABLE            (1 << 11)
+
+/* 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
+// GUESS: PARAM_31 is last, based on native limits reported by fglrx
+#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
+
+// 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_BLEND_ENABLE                     (1 << 0)
+#       define R300_BLEND_UNKNOWN                    (3 << 1)
+#       define R300_BLEND_NO_SEPARATE                (1 << 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_SRC_BLEND_GL_ZERO                (32 << 16)
+#       define R300_SRC_BLEND_GL_ONE                 (33 << 16)
+#       define R300_SRC_BLEND_GL_SRC_COLOR           (34 << 16)
+#       define R300_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16)
+#       define R300_SRC_BLEND_GL_DST_COLOR           (36 << 16)
+#       define R300_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16)
+#       define R300_SRC_BLEND_GL_SRC_ALPHA           (38 << 16)
+#       define R300_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16)
+#       define R300_SRC_BLEND_GL_DST_ALPHA           (40 << 16)
+#       define R300_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16)
+#       define R300_SRC_BLEND_GL_SRC_ALPHA_SATURATE  (42 << 16)
+#       define R300_SRC_BLEND_MASK                   (63 << 16)
+#       define R300_DST_BLEND_GL_ZERO                (32 << 24)
+#       define R300_DST_BLEND_GL_ONE                 (33 << 24)
+#       define R300_DST_BLEND_GL_SRC_COLOR           (34 << 24)
+#       define R300_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24)
+#       define R300_DST_BLEND_GL_DST_COLOR           (36 << 24)
+#       define R300_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24)
+#       define R300_DST_BLEND_GL_SRC_ALPHA           (38 << 24)
+#       define R300_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24)
+#       define R300_DST_BLEND_GL_DST_ALPHA           (40 << 24)
+#       define R300_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24)
+#       define R300_DST_BLEND_MASK                   (63 << 24)
+#define R300_RB3D_COLORMASK                 0x4E0C
+#       define R300_COLORMASK0_B                 (1<<0)
+#       define R300_COLORMASK0_G                 (1<<1)
+#       define R300_COLORMASK0_R                 (1<<2)
+#       define R300_COLORMASK0_A                 (1<<3)
+
+/* gap */
+#define R300_RB3D_COLOROFFSET0              0x4E28
+#       define R300_COLOROFFSET_MASK             0xFFFFFFF0 // GUESS
+#define R300_RB3D_COLOROFFSET1              0x4E2C // GUESS
+#define R300_RB3D_COLOROFFSET2              0x4E30 // GUESS
+#define R300_RB3D_COLOROFFSET3              0x4E34 // GUESS
+/* gap */
+// 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              0x00001FF8 // GUESS
+#       define R300_COLOR_TILE_ENABLE            (1 << 16) // GUESS
+#       define R300_COLOR_MICROTILE_ENABLE       (1 << 17) // GUESS
+#       define R300_COLOR_ENDIAN_NO_SWAP         (0 << 18) // GUESS
+#       define R300_COLOR_ENDIAN_WORD_SWAP       (1 << 18) // GUESS
+#       define R300_COLOR_ENDIAN_DWORD_SWAP      (2 << 18) // GUESS
+#       define R300_COLOR_UNKNOWN_22_23          (3 << 22) // GUESS: Format?
+#define R300_RB3D_COLORPITCH1               0x4E3C // GUESS
+#define R300_RB3D_COLORPITCH2               0x4E40 // GUESS
+#define R300_RB3D_COLORPITCH3               0x4E44 // GUESS
+
+/* gap */
+// Guess by Vladimir.
+// Set to 0A before 3D operations, set to 02 afterwards.
+#define R300_RB3D_DSTCACHE_CTLSTAT          0x4E4C
+#       define R300_RB3D_DSTCACHE_02             0x00000002
+#       define R300_RB3D_DSTCACHE_0A             0x0000000A
+
+/* gap */
+// There seems to be no "write only" setting, so use Z-test = ALWAYS for this.
+#define R300_RB3D_ZCNTL_0                   0x4F00
+#       define R300_RB3D_Z_DISABLED_1            0x00000010 // GUESS
+#       define R300_RB3D_Z_DISABLED_2            0x00000014 // GUESS
+#       define R300_RB3D_Z_TEST                  0x00000012
+#       define R300_RB3D_Z_TEST_AND_WRITE        0x00000016
+#define R300_RB3D_ZCNTL_1                   0x4F04
+#       define R300_RB3D_Z_TEST_NEVER            (0 << 0) // GUESS (based on R200)
+#       define R300_RB3D_Z_TEST_LESS             (1 << 0)
+#       define R300_RB3D_Z_TEST_LEQUAL           (2 << 0)
+#       define R300_RB3D_Z_TEST_EQUAL            (3 << 0) // GUESS
+#       define R300_RB3D_Z_TEST_GEQUAL           (4 << 0) // GUESS
+#       define R300_RB3D_Z_TEST_GREATER          (5 << 0) // GUESS
+#       define R300_RB3D_Z_TEST_NEQUAL           (6 << 0)
+#       define R300_RB3D_Z_TEST_ALWAYS           (7 << 0)
+#       define R300_RB3D_Z_TEST_MASK             (7 << 0)
+/* gap */
+#define R300_RB3D_DEPTHOFFSET               0x4F20
+#define R300_RB3D_DEPTHPITCH                0x4F24
+#       define R300_DEPTHPITCH_MASK              0x00001FF8 // GUESS
+#       define R300_DEPTH_TILE_ENABLE            (1 << 16) // GUESS
+#       define R300_DEPTH_MICROTILE_ENABLE       (1 << 17) // GUESS
+#       define R300_DEPTH_ENDIAN_NO_SWAP         (0 << 18) // GUESS
+#       define R300_DEPTH_ENDIAN_WORD_SWAP       (1 << 18) // GUESS
+#       define R300_DEPTH_ENDIAN_DWORD_SWAP      (2 << 18) // GUESS
+
+// BEGIN: Vertex program instruction set
+// Every instruction is four dwords long:
+//  DWORD 0: output and opcode
+//  DWORD 1: first argument
+//  DWORD 2: second argument
+//  DWORD 3: third argument
+//
+// Notes:
+//  - ABS r, a is implemented as MAX r, a, -a
+//  - MOV is implemented as ADD to zero
+//  - XPD is implemented as MUL + MAD
+//  - FLR is implemented as FRC + ADD
+//  - apparently, fglrx tries to schedule instructions so that there is at least
+//    one instruction between the write to a temporary and the first read
+//    from said temporary; however, violations of this scheduling are allowed
+//  - register indices seem to be unrelated with OpenGL aliasing to conventional state
+//  - only one attribute and one parameter can be loaded at a time; however, the
+//    same attribute/parameter can be used for more than one argument
+//  - the second software argument for POW is the third hardware argument (no idea why)
+//  - MAD with only temporaries as input seems to use VPI_OUT_SELECT_MAD_2
+//
+// There is some magic surrounding LIT:
+//  The single argument is replicated across all three inputs, but swizzled:
+//   First argument: xyzy
+//   Second argument: xyzx
+//   Third argument: xyzw
+//  Whenever the result is used later in the fragment program, fglrx forces x and w
+//  to be 1.0 in the input selection; I don't know whether this is strictly necessary
+#define R300_VPI_OUT_OP_DOT                     (1 << 0)
+#define R300_VPI_OUT_OP_MUL                     (2 << 0)
+#define R300_VPI_OUT_OP_ADD                     (3 << 0)
+#define R300_VPI_OUT_OP_MAD                     (4 << 0)
+#define R300_VPI_OUT_OP_FRC                     (6 << 0)
+#define R300_VPI_OUT_OP_MAX                     (7 << 0)
+#define R300_VPI_OUT_OP_MIN                     (8 << 0)
+#define R300_VPI_OUT_OP_SGE                     (9 << 0)
+#define R300_VPI_OUT_OP_SLT                     (10 << 0)
+#define R300_VPI_OUT_OP_EXP                     (65 << 0)
+#define R300_VPI_OUT_OP_LOG                     (66 << 0)
+#define R300_VPI_OUT_OP_LIT                     (68 << 0)
+#define R300_VPI_OUT_OP_POW                     (69 << 0)
+#define R300_VPI_OUT_OP_RCP                     (70 << 0)
+#define R300_VPI_OUT_OP_RSQ                     (72 << 0)
+#define R300_VPI_OUT_OP_EX2                     (75 << 0)
+#define R300_VPI_OUT_OP_LG2                     (76 << 0)
+#define R300_VPI_OUT_OP_MAD_2                   (128 << 0)
+
+#define R300_VPI_OUT_REG_CLASS_TEMPORARY        (0 << 8)
+#define R300_VPI_OUT_REG_CLASS_RESULT           (2 << 8)
+#define R300_VPI_OUT_REG_CLASS_MASK             (31 << 8)
+
+#define R300_VPI_OUT_REG_INDEX_SHIFT            13
+#define R300_VPI_OUT_REG_INDEX_MASK             (31 << 13) // GUESS based on fglrx native limits
+
+#define R300_VPI_OUT_WRITE_X                    (1 << 20)
+#define R300_VPI_OUT_WRITE_Y                    (1 << 21)
+#define R300_VPI_OUT_WRITE_Z                    (1 << 22)
+#define R300_VPI_OUT_WRITE_W                    (1 << 23)
+
+#define R300_VPI_IN_REG_CLASS_TEMPORARY         (0 << 0)
+#define R300_VPI_IN_REG_CLASS_ATTRIBUTE         (1 << 0)
+#define R300_VPI_IN_REG_CLASS_PARAMETER         (2 << 0)
+#define R300_VPI_IN_REG_CLASS_NONE              (9 << 0)
+#define R300_VPI_IN_REG_CLASS_MASK              (31 << 0) // GUESS
+
+#define R300_VPI_IN_REG_INDEX_SHIFT             5
+#define R300_VPI_IN_REG_INDEX_MASK              (255 << 5) // GUESS based on fglrx native limits
+
+// The R300 can select components from the input register arbitrarily.
+// Use the following constants, shifted by the component shift you
+// want to select
+#define R300_VPI_IN_SELECT_X    0
+#define R300_VPI_IN_SELECT_Y    1
+#define R300_VPI_IN_SELECT_Z    2
+#define R300_VPI_IN_SELECT_W    3
+#define R300_VPI_IN_SELECT_ZERO 4
+#define R300_VPI_IN_SELECT_ONE  5
+#define R300_VPI_IN_SELECT_MASK 7
+
+#define R300_VPI_IN_X_SHIFT                     13
+#define R300_VPI_IN_Y_SHIFT                     16
+#define R300_VPI_IN_Z_SHIFT                     19
+#define R300_VPI_IN_W_SHIFT                     22
+
+#define R300_VPI_IN_NEG_X                       (1 << 25)
+#define R300_VPI_IN_NEG_Y                       (1 << 26)
+#define R300_VPI_IN_NEG_Z                       (1 << 27)
+#define R300_VPI_IN_NEG_W                       (1 << 28)
+// END
+
+#endif // _R300_REG_H
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
new file mode 100644 (file)
index 0000000..e1cb31d
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.
+Copyright (C) 2004 Nicolai Haehnle.
+All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+#include "glheader.h"
+#include "state.h"
+#include "imports.h"
+#include "macros.h"
+#include "context.h"
+#include "dd.h"
+#include "simple_list.h"
+
+#include "api_arrayelt.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "array_cache/acache.h"
+#include "tnl/tnl.h"
+
+#include "radeon_ioctl.h"
+#include "r300_context.h"
+#include "r300_ioctl.h"
+#include "r300_state.h"
+#include "r300_reg.h"
+#include "r300_program.h"
+
+
+/**
+ * Called by Mesa after an internal state update.
+ */
+static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
+{
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
+
+       _swrast_InvalidateState(ctx, new_state);
+       _swsetup_InvalidateState(ctx, new_state);
+       _ac_InvalidateState(ctx, new_state);
+       _tnl_InvalidateState(ctx, new_state);
+       _ae_invalidate_state(ctx, new_state);
+
+       /* Go inefficiency! */
+       r300ResetHwState(r300);
+}
+
+
+/**
+ * Completely recalculates hardware state based on the Mesa state.
+ */
+void r300ResetHwState(r300ContextPtr r300)
+{
+       int i;
+
+       if (RADEON_DEBUG & DEBUG_STATE)
+               fprintf(stderr, "%s\n", __FUNCTION__);
+
+       {
+               __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+               GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
+               GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
+               const GLfloat *v = r300->radeon.glCtx->Viewport._WindowMap.m;
+
+               r300->hw.vpt.cmd[R300_VPT_XSCALE] =
+                       r300PackFloat32(v[MAT_SX]);
+               r300->hw.vpt.cmd[R300_VPT_XOFFSET] =
+                       r300PackFloat32(v[MAT_TX] + xoffset);
+               r300->hw.vpt.cmd[R300_VPT_YSCALE] =
+                       r300PackFloat32(-v[MAT_SY]);
+               r300->hw.vpt.cmd[R300_VPT_YOFFSET] =
+                       r300PackFloat32(-v[MAT_TY] + yoffset);
+               r300->hw.vpt.cmd[R300_VPT_YSCALE] =
+                       r300PackFloat32(v[MAT_SZ]);
+               r300->hw.vpt.cmd[R300_VPT_YOFFSET] =
+                       r300PackFloat32(v[MAT_TZ]);
+       }
+
+//BEGIN: TODO
+       r300->hw.unk2080.cmd[1] = 0x0030045A;
+
+       r300->hw.ovf.cmd[R300_OVF_FMT_0] = 0x00000003;
+       r300->hw.ovf.cmd[R300_OVF_FMT_1] = 0x00000000;
+
+       r300->hw.unk20B0.cmd[1] = 0x0000040A;
+       r300->hw.unk20B0.cmd[2] = 0x00000008;
+
+       r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
+       r300->hw.unk2134.cmd[2] = 0x00000000;
+
+       r300->hw.unk2140.cmd[1] = 0x00000000;
+
+       ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
+       r300->hw.vir[0].cmd[1] = 0x21030003;
+
+       ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = 1;
+       r300->hw.vir[1].cmd[1] = 0xF688F688;
+
+       r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001;
+       r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405;
+
+       r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA;
+
+       r300->hw.unk221C.cmd[1] = R300_221C_NORMAL;
+
+       r300->hw.unk2220.cmd[1] = r300PackFloat32(1.0);
+       r300->hw.unk2220.cmd[2] = r300PackFloat32(1.0);
+       r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0);
+       r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0);
+
+       if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
+               r300->hw.unk2288.cmd[1] = R300_2288_R300;
+       else
+               r300->hw.unk2288.cmd[1] = R300_2288_RV350;
+
+       r300->hw.pvs.cmd[R300_PVS_CNTL_1] = 0;
+       r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0;
+       r300->hw.pvs.cmd[R300_PVS_CNTL_3] = 0;
+
+       r300->hw.unk4008.cmd[1] = 0x00000007;
+
+       r300->hw.unk4010.cmd[1] = 0x66666666;
+       r300->hw.unk4010.cmd[2] = 0x06666666;
+       if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R300)
+               r300->hw.unk4010.cmd[3] = 0x00000017;
+       else
+               r300->hw.unk4010.cmd[3] = 0x00000011;
+       r300->hw.unk4010.cmd[4] = 0x00000000;
+       r300->hw.unk4010.cmd[5] = 0x00000000;
+
+       r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
+
+       r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0);
+       r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0);
+       r300->hw.unk4200.cmd[3] = r300PackFloat32(1.0);
+       r300->hw.unk4200.cmd[4] = r300PackFloat32(1.0);
+
+       r300->hw.unk4214.cmd[1] = 0x00050005;
+
+       r300->hw.unk4230.cmd[1] = 0x01800000;
+       r300->hw.unk4230.cmd[2] = 0x00020006;
+       r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0);
+
+       r300->hw.unk4260.cmd[1] = 0;
+       r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
+       r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0);
+
+       r300->hw.unk4274.cmd[1] = 0x00000002;
+       r300->hw.unk4274.cmd[2] = 0x0003AAAA;
+       r300->hw.unk4274.cmd[3] = 0x00000000;
+       r300->hw.unk4274.cmd[4] = 0x00000000;
+
+       r300->hw.unk4288.cmd[1] = 0x00000000;
+       r300->hw.unk4288.cmd[2] = 0x00000001;
+       r300->hw.unk4288.cmd[3] = 0x00000000;
+       r300->hw.unk4288.cmd[4] = 0x00000000;
+       r300->hw.unk4288.cmd[5] = 0x00000000;
+
+       r300->hw.unk42A0.cmd[1] = 0x00000000;
+
+       r300->hw.unk42B4.cmd[1] = 0x00000000;
+       r300->hw.unk42B4.cmd[2] = 0x00000000;
+
+       r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
+       r300->hw.unk42C0.cmd[2] = 0x00000000;
+
+       r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7;
+       r300->hw.rc.cmd[2] = 0;
+
+       for(i = 1; i <= 8; ++i)
+               r300->hw.ri.cmd[i] = 0;
+
+       ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1;
+       for(i = 1; i <= 8; ++i)
+               r300->hw.rr.cmd[1] = 0;
+
+       r300->hw.unk43A4.cmd[1] = 0x0000001C;
+       r300->hw.unk43A4.cmd[2] = 0x2DA49525;
+
+       r300->hw.unk43E0.cmd[1] = 0x00000000;
+       r300->hw.unk43E0.cmd[2] = 0x03FFFFFF;
+       r300->hw.unk43E0.cmd[3] = 0x00FFFFFF;
+
+       r300->hw.fp.cmd[R300_FP_CNTL0] = 0;
+       r300->hw.fp.cmd[R300_FP_CNTL1] = 0;
+       r300->hw.fp.cmd[R300_FP_CNTL2] = 0;
+       r300->hw.fp.cmd[R300_FP_NODE0] = 0;
+       r300->hw.fp.cmd[R300_FP_NODE1] = 0;
+       r300->hw.fp.cmd[R300_FP_NODE2] = 0;
+       r300->hw.fp.cmd[R300_FP_NODE3] = 0;
+
+       r300->hw.unk46A4.cmd[1] = 0x00001B01;
+       r300->hw.unk46A4.cmd[2] = 0x00001B0F;
+       r300->hw.unk46A4.cmd[3] = 0x00001B0F;
+       r300->hw.unk46A4.cmd[4] = 0x00001B0F;
+       r300->hw.unk46A4.cmd[5] = 0x00000001;
+
+       for(i = 1; i <= 64; ++i) {
+               /* create NOP instructions */
+               r300->hw.fpi[0].cmd[i] = FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO));
+               r300->hw.fpi[1].cmd[i] = FP_SELC(0,XYZ,NO,FP_TMP(0),0,0);
+               r300->hw.fpi[2].cmd[i] = FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO));
+               r300->hw.fpi[3].cmd[i] = FP_SELA(0,W,NO,FP_TMP(0),0,0);
+       }
+
+       r300->hw.unk4BC0.cmd[1] = 0;
+
+       r300->hw.unk4BC8.cmd[1] = 0;
+       r300->hw.unk4BC8.cmd[2] = 0;
+       r300->hw.unk4BC8.cmd[3] = 0;
+
+       r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
+
+       r300->hw.unk4BD8.cmd[1] = 0;
+
+       r300->hw.unk4E00.cmd[1] = 0;
+
+       r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
+       r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
+
+       r300->hw.cmk.cmd[R300_CMK_COLORMASK] = 0xF;
+
+       r300->hw.unk4E10.cmd[1] = 0;
+       r300->hw.unk4E10.cmd[2] = 0;
+       r300->hw.unk4E10.cmd[3] = 0;
+
+       r300->hw.cb.cmd[R300_CB_OFFSET] =
+               r300->radeon.radeonScreen->backOffset +
+               r300->radeon.radeonScreen->fbLocation;
+       r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.radeonScreen->backPitch
+               | R300_COLOR_UNKNOWN_22_23;
+
+       r300->hw.unk4E50.cmd[1] = 0;
+       r300->hw.unk4E50.cmd[2] = 0;
+       r300->hw.unk4E50.cmd[3] = 0;
+       r300->hw.unk4E50.cmd[4] = 0;
+       r300->hw.unk4E50.cmd[5] = 0;
+       r300->hw.unk4E50.cmd[6] = 0;
+       r300->hw.unk4E50.cmd[7] = 0;
+       r300->hw.unk4E50.cmd[8] = 0;
+       r300->hw.unk4E50.cmd[9] = 0;
+
+       r300->hw.unk4E88.cmd[1] = 0;
+
+       r300->hw.zc.cmd[R300_ZC_CNTL_0] = 0;
+       r300->hw.zc.cmd[R300_ZC_CNTL_1] = 0;
+
+       r300->hw.unk4F08.cmd[1] = 0x00FFFF00;
+       r300->hw.unk4F08.cmd[2] = 0x00000002;
+       r300->hw.unk4F08.cmd[3] = 0x00000000;
+       r300->hw.unk4F08.cmd[4] = 0x00000003;
+       r300->hw.unk4F08.cmd[5] = 0x00000000;
+
+       r300->hw.zb.cmd[R300_ZB_OFFSET] =
+               r300->radeon.radeonScreen->depthOffset +
+               r300->radeon.radeonScreen->fbLocation;
+       r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
+
+       r300->hw.unk4F28.cmd[1] = 0;
+
+       r300->hw.unk4F30.cmd[1] = 0;
+       r300->hw.unk4F30.cmd[2] = 0;
+
+       r300->hw.unk4F44.cmd[1] = 0;
+
+       r300->hw.unk4F54.cmd[1] = 0;
+
+       ((drm_r300_cmd_header_t*)r300->hw.vpi.cmd)->vpu.count = 0;
+       for(i = 1; i < R300_VPI_CMDSIZE; i += 4) {
+               /* MOV t0, t0 */
+               r300->hw.vpi.cmd[i+0] = VP_OUT(ADD,TMP,0,XYZW);
+               r300->hw.vpi.cmd[i+1] = VP_IN(TMP,0);
+               r300->hw.vpi.cmd[i+2] = VP_ZERO();
+               r300->hw.vpi.cmd[i+3] = VP_ZERO();
+       }
+
+       ((drm_r300_cmd_header_t*)r300->hw.vpp.cmd)->vpu.count = 0;
+       for(i = 1; i < R300_VPP_CMDSIZE; ++i)
+               r300->hw.vpp.cmd[i] = 0;
+//END: TODO
+
+       r300->hw.all_dirty = GL_TRUE;
+}
+
+
+/**
+ * Calculate initial hardware state and register state functions.
+ * Assumes that the command buffer and state atoms have been
+ * initialized already.
+ */
+void r300InitState(r300ContextPtr r300)
+{
+       struct dd_function_table* functions;
+
+       r300ResetHwState(r300);
+
+       /* Setup state functions */
+       functions = &r300->radeon.glCtx->Driver;
+       functions->UpdateState = r300InvalidateState;
+}
+
diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h
new file mode 100644 (file)
index 0000000..59d76e3
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+#ifndef __R300_STATE_H__
+#define __R300_STATE_H__
+
+#include "r300_context.h"
+
+#define R300_STATECHANGE(r300, atom) \
+       do {                                            \
+               r300->hw.atom.dirty = GL_TRUE;          \
+               r300->hw.is_dirty = GL_TRUE;            \
+       } while(0)
+
+extern void r300ResetHwState(r300ContextPtr r300);
+extern void r300InitState(r300ContextPtr r300);
+
+#endif /* __R300_STATE_H__ */
diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c
new file mode 100644 (file)
index 0000000..d04045d
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/**
+ * \file radeon_context.c
+ * Common context initialization.
+ *
+ * \author Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include <dlfcn.h>
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "state.h"
+#include "matrix.h"
+
+#include "drivers/common/driverfuncs.h"
+#include "swrast/swrast.h"
+
+#include "radeon_screen.h"
+#include "r200_context.h"
+#include "radeon_ioctl.h"
+#include "radeon_macros.h"
+#include "radeon_reg.h"
+#include "r200_state.h"
+
+#include "utils.h"
+#include "vblank.h"
+#include "xmlpool.h"           /* for symbolic values of enum-type options */
+
+#define DRIVER_DATE "20040924"
+
+
+/* Return various strings for glGetString().
+ */
+static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       static char buffer[128];
+
+       switch (name) {
+       case GL_VENDOR:
+               return (GLubyte *) "Tungsten Graphics, Inc.";
+
+       case GL_RENDERER:
+       {
+               unsigned offset;
+               GLuint agp_mode = radeon->radeonScreen->IsPCI ? 0 :
+                       radeon->radeonScreen->AGPMode;
+               const char* chipname;
+
+               if (IS_FAMILY_R300(radeon))
+                       chipname = "R300";
+               else
+                       chipname = "R200";
+
+               offset = driGetRendererString(buffer, chipname, DRIVER_DATE,
+                                             agp_mode);
+
+               sprintf(&buffer[offset], " %sTCL",
+                       !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
+                       ? "" : "NO-");
+
+               return (GLubyte *) buffer;
+       }
+
+       default:
+               return NULL;
+       }
+}
+
+
+/* Return the width and height of the given buffer.
+ */
+static void radeonGetBufferSize(GLframebuffer * buffer,
+                               GLuint * width, GLuint * height)
+{
+       GET_CURRENT_CONTEXT(ctx);
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       LOCK_HARDWARE(radeon);
+       *width = radeon->dri.drawable->w;
+       *height = radeon->dri.drawable->h;
+       UNLOCK_HARDWARE(radeon);
+}
+
+
+/* Initialize the driver's misc functions.
+ */
+static void radeonInitDriverFuncs(struct dd_function_table *functions)
+{
+       functions->GetBufferSize = radeonGetBufferSize;
+       functions->ResizeBuffers = _swrast_alloc_buffers;
+       functions->GetString = radeonGetString;
+}
+
+
+static int get_ust_nop(int64_t * ust)
+{
+       *ust = 1;
+       return 0;
+}
+
+/**
+ * Create and initialize all common fields of the context,
+ * including the Mesa context itself.
+ */
+GLboolean radeonInitContext(radeonContextPtr radeon,
+                           struct dd_function_table* functions,
+                           const __GLcontextModes * glVisual,
+                           __DRIcontextPrivate * driContextPriv,
+                           void *sharedContextPrivate)
+{
+       __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+       radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
+       GLcontext* ctx;
+       GLcontext* shareCtx;
+       int fthrottle_mode;
+
+       /* Fill in additional standard functions. */
+       radeonInitDriverFuncs(functions);
+
+       /* Allocate and initialize the Mesa context */
+       if (sharedContextPrivate)
+               shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx;
+       else
+               shareCtx = NULL;
+       radeon->glCtx = _mesa_create_context(glVisual, shareCtx,
+                                           functions, (void *)radeon);
+       if (!radeon->glCtx)
+               return GL_FALSE;
+
+       ctx = radeon->glCtx;
+       driContextPriv->driverPrivate = radeon;
+
+       /* DRI fields */
+       radeon->dri.context = driContextPriv;
+       radeon->dri.screen = sPriv;
+       radeon->dri.drawable = NULL;    /* Set by XMesaMakeCurrent */
+       radeon->dri.hwContext = driContextPriv->hHWContext;
+       radeon->dri.hwLock = &sPriv->pSAREA->lock;
+       radeon->dri.fd = sPriv->fd;
+       radeon->dri.drmMinor = sPriv->drmMinor;
+
+       radeon->radeonScreen = screen;
+       radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA +
+                                              screen->sarea_priv_offset);
+
+       /* Setup IRQs */
+       fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
+       radeon->iw.irq_seq = -1;
+       radeon->irqsEmitted = 0;
+       radeon->do_irqs = (radeon->dri.drmMinor >= 6 &&
+                         fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
+                         radeon->radeonScreen->irq);
+
+       radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
+
+       if (!radeon->do_irqs)
+               fprintf(stderr,
+                       "IRQ's not enabled, falling back to %s: %d %d %d\n",
+                       radeon->do_usleeps ? "usleeps" : "busy waits",
+                       radeon->dri.drmMinor,
+                       fthrottle_mode, radeon->radeonScreen->irq);
+
+       radeon->vblank_flags = (radeon->radeonScreen->irq != 0)
+           ? driGetDefaultVBlankFlags(&radeon->optionCache) : VBLANK_FLAG_NO_IRQ;
+
+       radeon->get_ust =
+           (PFNGLXGETUSTPROC) glXGetProcAddress((const GLubyte *)
+                                                "__glXGetUST");
+       if (radeon->get_ust == NULL) {
+               radeon->get_ust = get_ust_nop;
+       }
+       (*radeon->get_ust) (&radeon->swap_ust);
+
+       return GL_TRUE;
+}
+
+
+/**
+ * Swap front and back buffer.
+ */
+void radeonSwapBuffers(__DRIdrawablePrivate * dPriv)
+{
+       if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+               radeonContextPtr radeon;
+               GLcontext *ctx;
+
+               radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
+               ctx = radeon->glCtx;
+
+               if (ctx->Visual.doubleBufferMode) {
+                       _mesa_notifySwapBuffers(ctx);   /* flush pending rendering comands */
+                       if (radeon->doPageFlip) {
+                               radeonPageFlip(dPriv);
+                       } else {
+                               radeonCopyBuffer(dPriv);
+                       }
+               }
+       } else {
+               /* XXX this shouldn't be an error but we can't handle it for now */
+               _mesa_problem(NULL, "%s: drawable has no context!",
+                             __FUNCTION__);
+       }
+}
+
+
+/* Force the context `c' to be the current context and associate with it
+ * buffer `b'.
+ */
+GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
+                           __DRIdrawablePrivate * driDrawPriv,
+                           __DRIdrawablePrivate * driReadPriv)
+{
+       if (driContextPriv) {
+               radeonContextPtr radeon =
+                       (radeonContextPtr) driContextPriv->driverPrivate;
+
+               if (RADEON_DEBUG & DEBUG_DRI)
+                       fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
+                               radeon->glCtx);
+
+               if (radeon->dri.drawable != driDrawPriv) {
+                       driDrawableInitVBlank(driDrawPriv,
+                                             radeon->vblank_flags);
+                       radeon->dri.drawable = driDrawPriv;
+
+                       if (IS_FAMILY_R200(radeon)) {
+                               r200UpdateWindow(radeon->glCtx);
+                               r200UpdateViewportOffset(radeon->glCtx);
+                       }
+               }
+
+               _mesa_make_current2(radeon->glCtx,
+                                   (GLframebuffer *) driDrawPriv->
+                                   driverPrivate,
+                                   (GLframebuffer *) driReadPriv->
+                                   driverPrivate);
+
+               if (!radeon->glCtx->Viewport.Width) {
+                       _mesa_set_viewport(radeon->glCtx, 0, 0,
+                                          driDrawPriv->w, driDrawPriv->h);
+               }
+
+               _mesa_update_state(radeon->glCtx);
+
+               if (IS_FAMILY_R200(radeon))
+                       r200ValidateState(radeon->glCtx);
+
+       } else {
+               if (RADEON_DEBUG & DEBUG_DRI)
+                       fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
+               _mesa_make_current(0, 0);
+       }
+
+       if (RADEON_DEBUG & DEBUG_DRI)
+               fprintf(stderr, "End %s\n", __FUNCTION__);
+       return GL_TRUE;
+}
+
+/* Force the context `c' to be unbound from its buffer.
+ */
+GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
+{
+       radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
+
+       if (RADEON_DEBUG & DEBUG_DRI)
+               fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
+                       radeon->glCtx);
+
+       return GL_TRUE;
+}
+
diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h
new file mode 100644 (file)
index 0000000..d51cf4c
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ *   Nicolai Haehnle <prefect_@gmx.net>
+ */
+
+#ifndef __RADEON_CONTEXT_H__
+#define __RADEON_CONTEXT_H__
+
+#include "mtypes.h"
+#include "radeon_screen.h"
+#include "drm.h"
+#include "dri_util.h"
+
+struct radeon_context;
+typedef struct radeon_context radeonContextRec;
+typedef struct radeon_context* radeonContextPtr;
+
+static __inline GLuint radeonPackColor(GLuint cpp,
+                                    GLubyte r, GLubyte g, GLubyte b, GLubyte a)
+{
+       switch (cpp) {
+       case 2:
+               return PACK_COLOR_565(r, g, b);
+       case 4:
+               return PACK_COLOR_8888(a, r, g, b);
+       default:
+               return 0;
+       }
+}
+
+
+/* Rasterizing fallbacks */
+/* See correponding strings in r200_swtcl.c */
+#define RADEON_FALLBACK_TEXTURE                0x01
+#define RADEON_FALLBACK_DRAW_BUFFER    0x02
+#define RADEON_FALLBACK_STENCIL                0x04
+#define RADEON_FALLBACK_RENDER_MODE    0x08
+#define RADEON_FALLBACK_BLEND_EQ       0x10
+#define RADEON_FALLBACK_BLEND_FUNC     0x20
+#define RADEON_FALLBACK_DISABLE                0x40
+#define RADEON_FALLBACK_BORDER_MODE    0x80
+
+extern void radeonFallback(GLcontext * ctx, GLuint bit, GLboolean mode);
+
+#define FALLBACK( radeon, bit, mode ) do {                     \
+   if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n",       \
+                    __FUNCTION__, bit, mode );                 \
+   radeonFallback( (radeon)->glCtx, bit, mode );               \
+} while (0)
+
+
+/* TCL fallbacks */
+extern void radeonTclFallback(GLcontext * ctx, GLuint bit, GLboolean mode);
+
+#define RADEON_TCL_FALLBACK_RASTER             0x0001  /* rasterization */
+#define RADEON_TCL_FALLBACK_UNFILLED           0x0002  /* unfilled tris */
+#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE      0x0004  /* twoside tris */
+#define RADEON_TCL_FALLBACK_MATERIAL           0x0008  /* material in vb */
+#define RADEON_TCL_FALLBACK_TEXGEN_0           0x0010  /* texgen, unit 0 */
+#define RADEON_TCL_FALLBACK_TEXGEN_1           0x0020  /* texgen, unit 1 */
+#define RADEON_TCL_FALLBACK_TEXGEN_2           0x0040  /* texgen, unit 2 */
+#define RADEON_TCL_FALLBACK_TEXGEN_3           0x0080  /* texgen, unit 3 */
+#define RADEON_TCL_FALLBACK_TEXGEN_4           0x0100  /* texgen, unit 4 */
+#define RADEON_TCL_FALLBACK_TEXGEN_5           0x0200  /* texgen, unit 5 */
+#define RADEON_TCL_FALLBACK_TCL_DISABLE                0x0400  /* user disable */
+#define RADEON_TCL_FALLBACK_BITMAP             0x0800  /* draw bitmap with points */
+#define RADEON_TCL_FALLBACK_VERTEX_PROGRAM     0x1000  /* vertex program active */
+
+#define TCL_FALLBACK( ctx, bit, mode ) radeonTclFallback( ctx, bit, mode )
+
+
+struct radeon_dri_mirror {
+       __DRIcontextPrivate *context;   /* DRI context */
+       __DRIscreenPrivate *screen;     /* DRI screen */
+       __DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */
+
+       drm_context_t hwContext;
+       drm_hw_lock_t *hwLock;
+       int fd;
+       int drmMinor;
+};
+
+/**
+ * Derived state for internal purposes.
+ */
+struct radeon_colorbuffer_state {
+       GLuint clear;
+       GLint drawOffset, drawPitch;
+};
+
+struct radeon_pixel_state {
+       GLint readOffset, readPitch;
+};
+
+struct radeon_state {
+       struct radeon_colorbuffer_state color;
+       struct radeon_pixel_state pixel;
+};
+
+/**
+ * Common per-context variables shared by R200 and R300.
+ * R200- and R300-specific code "derive" their own context from this
+ * structure.
+ */
+struct radeon_context {
+       GLcontext *glCtx;               /* Mesa context */
+       radeonScreenPtr radeonScreen;   /* Screen private DRI data */
+
+       /* Fallback state */
+       GLuint Fallback;
+       GLuint TclFallback;
+
+       /* Page flipping */
+       GLuint doPageFlip;
+
+       /* Drawable, cliprect and scissor information */
+       GLuint numClipRects;    /* Cliprects for the draw buffer */
+       drm_clip_rect_t *pClipRects;
+       unsigned int lastStamp;
+       GLboolean lost_context;
+       drm_radeon_sarea_t *sarea;      /* Private SAREA data */
+
+       /* Mirrors of some DRI state */
+       struct radeon_dri_mirror dri;
+
+       /* Busy waiting */
+       GLuint do_usleeps;
+       GLuint do_irqs;
+       GLuint irqsEmitted;
+       drm_radeon_irq_wait_t iw;
+
+       /* VBI / buffer swap */
+       GLuint vbl_seq;
+       GLuint vblank_flags;
+
+       int64_t swap_ust;
+       int64_t swap_missed_ust;
+
+       GLuint swap_count;
+       GLuint swap_missed_count;
+
+       PFNGLXGETUSTPROC get_ust;
+
+       /* Derived state */
+       struct radeon_state state;
+
+       /* Configuration cache
+        */
+       driOptionCache optionCache;
+};
+
+#define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx))
+
+extern void radeonSwapBuffers(__DRIdrawablePrivate * dPriv);
+extern GLboolean radeonInitContext(radeonContextPtr radeon,
+                                  struct dd_function_table* functions,
+                                  const __GLcontextModes * glVisual,
+                                  __DRIcontextPrivate * driContextPriv,
+                                  void *sharedContextPrivate);
+extern GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
+                                  __DRIdrawablePrivate * driDrawPriv,
+                                  __DRIdrawablePrivate * driReadPriv);
+extern GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv);
+
+/* ================================================================
+ * Debugging:
+ */
+#define DO_DEBUG               1
+
+#if DO_DEBUG
+extern int RADEON_DEBUG;
+#else
+#define RADEON_DEBUG           0
+#endif
+
+#define DEBUG_TEXTURE  0x0001
+#define DEBUG_STATE    0x0002
+#define DEBUG_IOCTL    0x0004
+#define DEBUG_PRIMS    0x0008
+#define DEBUG_VERTS    0x0010
+#define DEBUG_FALLBACKS        0x0020
+#define DEBUG_VFMT     0x0040
+#define DEBUG_CODEGEN  0x0080
+#define DEBUG_VERBOSE  0x0100
+#define DEBUG_DRI       0x0200
+#define DEBUG_DMA       0x0400
+#define DEBUG_SANITY    0x0800
+#define DEBUG_SYNC      0x1000
+#define DEBUG_PIXEL     0x2000
+#define DEBUG_MEMORY    0x4000
+
+#endif /* __RADEON_CONTEXT_H__ */
diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.c b/src/mesa/drivers/dri/r300/radeon_ioctl.c
new file mode 100644 (file)
index 0000000..0caf445
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include <sched.h>
+#include <errno.h>
+
+#include "glheader.h"
+#include "imports.h"
+#include "macros.h"
+#include "context.h"
+#include "swrast/swrast.h"
+
+#include "r200_context.h"
+#include "r200_state.h"
+#include "radeon_ioctl.h"
+#include "r200_ioctl.h"
+#include "r300_ioctl.h"
+#include "r200_tcl.h"
+#include "r200_sanity.h"
+#include "radeon_reg.h"
+
+#include "vblank.h"
+
+static void radeonWaitForIdle(radeonContextPtr radeon);
+
+/* ================================================================
+ * SwapBuffers with client-side throttling
+ */
+
+static uint32_t radeonGetLastFrame(radeonContextPtr radeon)
+{
+       drm_radeon_getparam_t gp;
+       int ret;
+       uint32_t frame;
+
+       gp.param = RADEON_PARAM_LAST_FRAME;
+       gp.value = (int *)&frame;
+       ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM,
+                                 &gp, sizeof(gp));
+       if (ret) {
+               fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__,
+                       ret);
+               exit(1);
+       }
+
+       return frame;
+}
+
+static void radeonEmitIrqLocked(radeonContextPtr radeon)
+{
+       drm_radeon_irq_emit_t ie;
+       int ret;
+
+       ie.irq_seq = &radeon->iw.irq_seq;
+       ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_IRQ_EMIT,
+                                 &ie, sizeof(ie));
+       if (ret) {
+               fprintf(stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__,
+                       ret);
+               exit(1);
+       }
+}
+
+static void radeonWaitIrq(radeonContextPtr radeon)
+{
+       int ret;
+
+       do {
+               ret = drmCommandWrite(radeon->dri.fd, DRM_RADEON_IRQ_WAIT,
+                                     &radeon->iw, sizeof(radeon->iw));
+       } while (ret && (errno == EINTR || errno == EAGAIN));
+
+       if (ret) {
+               fprintf(stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__,
+                       ret);
+               exit(1);
+       }
+}
+
+static void radeonWaitForFrameCompletion(radeonContextPtr radeon)
+{
+       drm_radeon_sarea_t *sarea = radeon->sarea;
+
+       if (radeon->do_irqs) {
+               if (radeonGetLastFrame(radeon) < sarea->last_frame) {
+                       if (!radeon->irqsEmitted) {
+                               while (radeonGetLastFrame(radeon) <
+                                      sarea->last_frame) ;
+                       } else {
+                               UNLOCK_HARDWARE(radeon);
+                               radeonWaitIrq(radeon);
+                               LOCK_HARDWARE(radeon);
+                       }
+                       radeon->irqsEmitted = 10;
+               }
+
+               if (radeon->irqsEmitted) {
+                       radeonEmitIrqLocked(radeon);
+                       radeon->irqsEmitted--;
+               }
+       } else {
+               while (radeonGetLastFrame(radeon) < sarea->last_frame) {
+                       UNLOCK_HARDWARE(radeon);
+                       if (radeon->do_usleeps)
+                               DO_USLEEP(1);
+                       LOCK_HARDWARE(radeon);
+               }
+       }
+}
+
+/* Copy the back color buffer to the front color buffer.
+ */
+void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
+{
+       radeonContextPtr radeon;
+       GLint nbox, i, ret;
+       GLboolean missed_target;
+       int64_t ust;
+
+       assert(dPriv);
+       assert(dPriv->driContextPriv);
+       assert(dPriv->driContextPriv->driverPrivate);
+
+       radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
+
+       if (RADEON_DEBUG & DEBUG_IOCTL) {
+               fprintf(stderr, "\n%s( %p )\n\n", __FUNCTION__,
+                       (void *)radeon->glCtx);
+       }
+
+       if (IS_FAMILY_R200(radeon))
+               R200_FIREVERTICES((r200ContextPtr)radeon);
+
+       LOCK_HARDWARE(radeon);
+
+       /* Throttle the frame rate -- only allow one pending swap buffers
+        * request at a time.
+        */
+       radeonWaitForFrameCompletion(radeon);
+       UNLOCK_HARDWARE(radeon);
+       driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
+                        &missed_target);
+       LOCK_HARDWARE(radeon);
+
+       nbox = dPriv->numClipRects;     /* must be in locked region */
+
+       for (i = 0; i < nbox;) {
+               GLint nr = MIN2(i + RADEON_NR_SAREA_CLIPRECTS, nbox);
+               drm_clip_rect_t *box = dPriv->pClipRects;
+               drm_clip_rect_t *b = radeon->sarea->boxes;
+               GLint n = 0;
+
+               for (; i < nr; i++) {
+                       *b++ = box[i];
+                       n++;
+               }
+               radeon->sarea->nbox = n;
+
+               ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_SWAP);
+
+               if (ret) {
+                       fprintf(stderr, "DRM_R200_SWAP_BUFFERS: return = %d\n",
+                               ret);
+                       UNLOCK_HARDWARE(radeon);
+                       exit(1);
+               }
+       }
+
+       UNLOCK_HARDWARE(radeon);
+
+       if (IS_FAMILY_R200(radeon))
+               ((r200ContextPtr)radeon)->hw.all_dirty = GL_TRUE;
+
+       radeon->swap_count++;
+       (*radeon->get_ust) (&ust);
+       if (missed_target) {
+               radeon->swap_missed_count++;
+               radeon->swap_missed_ust = ust - radeon->swap_ust;
+       }
+
+       radeon->swap_ust = ust;
+
+       sched_yield();
+}
+
+void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
+{
+       radeonContextPtr radeon;
+       GLint ret;
+       GLboolean missed_target;
+
+       assert(dPriv);
+       assert(dPriv->driContextPriv);
+       assert(dPriv->driContextPriv->driverPrivate);
+
+       radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
+
+       if (RADEON_DEBUG & DEBUG_IOCTL) {
+               fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
+                       radeon->sarea->pfCurrentPage);
+       }
+
+       if (IS_FAMILY_R200(radeon))
+               R200_FIREVERTICES((r200ContextPtr)radeon);
+       LOCK_HARDWARE(radeon);
+
+       if (!dPriv->numClipRects) {
+               UNLOCK_HARDWARE(radeon);
+               usleep(10000);  /* throttle invisible client 10ms */
+               return;
+       }
+
+       /* Need to do this for the perf box placement:
+        */
+       {
+               drm_clip_rect_t *box = dPriv->pClipRects;
+               drm_clip_rect_t *b = radeon->sarea->boxes;
+               b[0] = box[0];
+               radeon->sarea->nbox = 1;
+       }
+
+       /* Throttle the frame rate -- only allow a few pending swap buffers
+        * request at a time.
+        */
+       radeonWaitForFrameCompletion(radeon);
+       UNLOCK_HARDWARE(radeon);
+       driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
+                        &missed_target);
+       if (missed_target) {
+               radeon->swap_missed_count++;
+               (void)(*radeon->get_ust) (&radeon->swap_missed_ust);
+       }
+       LOCK_HARDWARE(radeon);
+
+       ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_FLIP);
+
+       UNLOCK_HARDWARE(radeon);
+
+       if (ret) {
+               fprintf(stderr, "DRM_RADEON_FLIP: return = %d\n", ret);
+               exit(1);
+       }
+
+       radeon->swap_count++;
+       (void)(*radeon->get_ust) (&radeon->swap_ust);
+
+       if (radeon->sarea->pfCurrentPage == 1) {
+               radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset;
+               radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch;
+       } else {
+               radeon->state.color.drawOffset = radeon->radeonScreen->backOffset;
+               radeon->state.color.drawPitch = radeon->radeonScreen->backPitch;
+       }
+
+       if (IS_FAMILY_R200(radeon)) {
+               r200ContextPtr r200 = (r200ContextPtr)radeon;
+
+               R200_STATECHANGE(r200, ctx);
+               r200->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = radeon->state.color.drawOffset
+                       + radeon->radeonScreen->fbLocation;
+               r200->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = radeon->state.color.drawPitch;
+       }
+}
+
+void radeonWaitForIdleLocked(radeonContextPtr radeon)
+{
+       int ret;
+       int i = 0;
+
+       do {
+               ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_CP_IDLE);
+               if (ret)
+                       DO_USLEEP(1);
+       } while (ret && ++i < 100);
+
+       if (ret < 0) {
+               UNLOCK_HARDWARE(radeon);
+               fprintf(stderr, "Error: R200 timed out... exiting\n");
+               exit(-1);
+       }
+}
+
+static void radeonWaitForIdle(radeonContextPtr radeon)
+{
+       LOCK_HARDWARE(radeon);
+       radeonWaitForIdleLocked(radeon);
+       UNLOCK_HARDWARE(radeon);
+}
+
+void radeonFlush(GLcontext * ctx)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       if (IS_FAMILY_R300(radeon))
+               r300Flush(ctx);
+       else
+               r200Flush(ctx);
+}
+
+
+/* Make sure all commands have been sent to the hardware and have
+ * completed processing.
+ */
+void radeonFinish(GLcontext * ctx)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       radeonFlush(ctx);
+
+       if (radeon->do_irqs) {
+               LOCK_HARDWARE(radeon);
+               radeonEmitIrqLocked(radeon);
+               UNLOCK_HARDWARE(radeon);
+               radeonWaitIrq(radeon);
+       } else
+               radeonWaitForIdle(radeon);
+}
diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.h b/src/mesa/drivers/dri/r300/radeon_ioctl.h
new file mode 100644 (file)
index 0000000..7c19325
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef __RADEON_IOCTL_H__
+#define __RADEON_IOCTL_H__
+
+#include "simple_list.h"
+#include "radeon_dri.h"
+#include "radeon_lock.h"
+
+#include "xf86drm.h"
+#include "drm.h"
+#include "r200_context.h"
+#include "radeon_drm.h"
+
+extern void radeonCopyBuffer(const __DRIdrawablePrivate * drawable);
+extern void radeonPageFlip(const __DRIdrawablePrivate * drawable);
+extern void radeonFlush(GLcontext * ctx);
+extern void radeonFinish(GLcontext * ctx);
+extern void radeonWaitForIdleLocked(radeonContextPtr radeon);
+
+#endif                         /* __RADEON_IOCTL_H__ */
diff --git a/src/mesa/drivers/dri/r300/radeon_lock.c b/src/mesa/drivers/dri/r300/radeon_lock.c
new file mode 100644 (file)
index 0000000..b5fb20d
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+#include <string.h>
+
+#include "r200_context.h"
+#include "radeon_lock.h"
+#include "r200_tex.h"
+#include "r200_state.h"
+#include "radeon_ioctl.h"
+
+#if DEBUG_LOCKING
+char *prevLockFile = NULL;
+int prevLockLine = 0;
+#endif
+
+/* Turn on/off page flipping according to the flags in the sarea:
+ */
+static void radeonUpdatePageFlipping(radeonContextPtr radeon)
+{
+       int use_back;
+
+       radeon->doPageFlip = radeon->sarea->pfState;
+
+       use_back = (radeon->glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT);
+       use_back ^= (radeon->sarea->pfCurrentPage == 1);
+
+       if (use_back) {
+               radeon->state.color.drawOffset = radeon->radeonScreen->backOffset;
+               radeon->state.color.drawPitch = radeon->radeonScreen->backPitch;
+       } else {
+               radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset;
+               radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch;
+       }
+}
+
+/**
+ * Called by radeonGetLock() after the lock has been obtained.
+ */
+static void r200RegainedLock(r200ContextPtr r200)
+{
+       __DRIdrawablePrivate *dPriv = r200->radeon.dri.drawable;
+       __DRIscreenPrivate *sPriv = r200->radeon.dri.screen;
+       int i;
+
+       if (r200->radeon.lastStamp != dPriv->lastStamp) {
+               radeonUpdatePageFlipping(&r200->radeon);
+               R200_STATECHANGE(r200, ctx);
+               r200->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] =
+                       r200->radeon.state.color.drawOffset
+                       + r200->radeon.radeonScreen->fbLocation;
+               r200->hw.ctx.cmd[CTX_RB3D_COLORPITCH] =
+                       r200->radeon.state.color.drawPitch;
+
+               if (r200->radeon.glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT)
+                       r200SetCliprects(r200, GL_BACK_LEFT);
+               else
+                       r200SetCliprects(r200, GL_FRONT_LEFT);
+               r200UpdateViewportOffset(r200->radeon.glCtx);
+               r200->radeon.lastStamp = dPriv->lastStamp;
+       }
+
+       for (i = 0; i < r200->nr_heaps; i++) {
+               DRI_AGE_TEXTURES(r200->texture_heaps[i]);
+       }
+}
+
+static void r300RegainedLock(radeonContextPtr radeon)
+{
+       __DRIdrawablePrivate *dPriv = radeon->dri.drawable;
+       __DRIscreenPrivate *sPriv = radeon->dri.screen;
+       int i;
+
+       if (radeon->lastStamp != dPriv->lastStamp) {
+               radeonUpdatePageFlipping(radeon);
+
+#if 0
+               if (radeon->glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT)
+                       r200SetCliprects(r200, GL_BACK_LEFT);
+               else
+                       r200SetCliprects(r200, GL_FRONT_LEFT);
+               r200UpdateViewportOffset(r200->radeon.glCtx);
+#endif
+               radeon->lastStamp = dPriv->lastStamp;
+       }
+
+#if 0
+       for (i = 0; i < r200->nr_heaps; i++) {
+               DRI_AGE_TEXTURES(r200->texture_heaps[i]);
+       }
+#endif
+}
+
+/* Update the hardware state.  This is called if another context has
+ * grabbed the hardware lock, which includes the X server.  This
+ * function also updates the driver's window state after the X server
+ * moves, resizes or restacks a window -- the change will be reflected
+ * in the drawable position and clip rects.  Since the X server grabs
+ * the hardware lock when it changes the window state, this routine will
+ * automatically be called after such a change.
+ */
+void radeonGetLock(radeonContextPtr radeon, GLuint flags)
+{
+       __DRIdrawablePrivate *dPriv = radeon->dri.drawable;
+       __DRIscreenPrivate *sPriv = radeon->dri.screen;
+       drm_radeon_sarea_t *sarea = radeon->sarea;
+
+       drmGetLock(radeon->dri.fd, radeon->dri.hwContext, flags);
+
+       /* The window might have moved, so we might need to get new clip
+        * rects.
+        *
+        * NOTE: This releases and regrabs the hw lock to allow the X server
+        * to respond to the DRI protocol request for new drawable info.
+        * Since the hardware state depends on having the latest drawable
+        * clip rects, all state checking must be done _after_ this call.
+        */
+       DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+
+       if (sarea->ctx_owner != radeon->dri.hwContext)
+               sarea->ctx_owner = radeon->dri.hwContext;
+
+       if (IS_FAMILY_R300(radeon))
+               r300RegainedLock(radeon);
+       else
+               r200RegainedLock((r200ContextPtr)radeon);
+
+       radeon->lost_context = GL_TRUE;
+}
diff --git a/src/mesa/drivers/dri/r300/radeon_lock.h b/src/mesa/drivers/dri/r300/radeon_lock.h
new file mode 100644 (file)
index 0000000..3359d78
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef __RADEON_LOCK_H__
+#define __RADEON_LOCK_H__
+
+#include "r200_ioctl.h"
+
+extern void radeonGetLock(radeonContextPtr radeon, GLuint flags);
+
+/* Turn DEBUG_LOCKING on to find locking conflicts.
+ */
+#define DEBUG_LOCKING  0
+
+#if DEBUG_LOCKING
+extern char *prevLockFile;
+extern int prevLockLine;
+
+#define DEBUG_LOCK()                                                   \
+   do {                                                                        \
+      prevLockFile = (__FILE__);                                       \
+      prevLockLine = (__LINE__);                                       \
+   } while (0)
+
+#define DEBUG_RESET()                                                  \
+   do {                                                                        \
+      prevLockFile = 0;                                                        \
+      prevLockLine = 0;                                                        \
+   } while (0)
+
+#define DEBUG_CHECK_LOCK()                                             \
+   do {                                                                        \
+      if ( prevLockFile ) {                                            \
+        fprintf( stderr,                                               \
+                 "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n",    \
+                 prevLockFile, prevLockLine, __FILE__, __LINE__ );     \
+        exit( 1 );                                                     \
+      }                                                                        \
+   } while (0)
+
+#else
+
+#define DEBUG_LOCK()
+#define DEBUG_RESET()
+#define DEBUG_CHECK_LOCK()
+
+#endif
+
+/*
+ * !!! We may want to separate locks from locks with validation.  This
+ * could be used to improve performance for those things commands that
+ * do not do any drawing !!!
+ */
+
+/* Lock the hardware and validate our state.
+ */
+#define LOCK_HARDWARE( radeon )                                                \
+       do {                                                            \
+               char __ret = 0;                                         \
+               DEBUG_CHECK_LOCK();                                     \
+               DRM_CAS( (radeon)->dri.hwLock, (radeon)->dri.hwContext, \
+                       (DRM_LOCK_HELD | (radeon)->dri.hwContext), __ret ); \
+               if ( __ret )                                            \
+                       radeonGetLock( (radeon), 0 );                   \
+               DEBUG_LOCK();                                           \
+       } while (0)
+
+#define UNLOCK_HARDWARE( radeon )                                      \
+       do {                                                            \
+               DRM_UNLOCK( (radeon)->dri.fd,                           \
+                       (radeon)->dri.hwLock,                           \
+                       (radeon)->dri.hwContext );                      \
+               DEBUG_RESET();                                          \
+               if (IS_FAMILY_R200((radeon))) {                         \
+                       r200ContextPtr __r200 = (r200ContextPtr)(radeon); \
+                       if (__r200->save_on_next_unlock)                \
+                               r200SaveHwState( __r200 );              \
+                       __r200->save_on_next_unlock = GL_FALSE;         \
+               }                                                       \
+       } while (0)
+
+#endif                         /* __RADEON_LOCK_H__ */
diff --git a/src/mesa/drivers/dri/r300/radeon_screen.c b/src/mesa/drivers/dri/r300/radeon_screen.c
new file mode 100644 (file)
index 0000000..557f3a3
--- /dev/null
@@ -0,0 +1,817 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/**
+ * \file radeon_screen.c
+ * Screen initialization functions for the R200 driver.
+ *
+ * \author Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include <dlfcn.h>
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+
+#define STANDALONE_MMIO
+#include "radeon_screen.h"
+#include "r200_context.h"
+#include "r300_context.h"
+#include "radeon_ioctl.h"
+#include "r200_ioctl.h"
+#include "radeon_macros.h"
+#include "radeon_reg.h"
+
+#include "utils.h"
+#include "vblank.h"
+#include "GL/internal/dri_interface.h"
+
+/* R200 configuration
+ */
+#include "xmlpool.h"
+
+const char __driR200ConfigOptions[] =
+DRI_CONF_BEGIN
+       DRI_CONF_SECTION_PERFORMANCE
+               DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
+               DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
+               DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
+               DRI_CONF_MAX_TEXTURE_UNITS(4, 2, 6)
+       DRI_CONF_SECTION_END
+       DRI_CONF_SECTION_QUALITY
+               DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
+               DRI_CONF_DEF_MAX_ANISOTROPY(1.0, "1.0,2.0,4.0,8.0,16.0")
+               DRI_CONF_NO_NEG_LOD_BIAS(false)
+               DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
+               DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
+               DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
+       DRI_CONF_SECTION_END
+       DRI_CONF_SECTION_DEBUG
+               DRI_CONF_NO_RAST(false)
+       DRI_CONF_SECTION_END
+       DRI_CONF_SECTION_SOFTWARE
+               DRI_CONF_ARB_VERTEX_PROGRAM(true)
+               DRI_CONF_NV_VERTEX_PROGRAM(false)
+       DRI_CONF_SECTION_END
+DRI_CONF_END;
+static const GLuint __driR200NConfigOptions = 13;
+
+/* TODO: integrate these into xmlpool.h! */
+#define DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(def,min,max) \
+DRI_CONF_OPT_BEGIN_V(texture_image_units,int,def, # min ":" # max ) \
+        DRI_CONF_DESC(en,"Number of texture image units") \
+        DRI_CONF_DESC(de,"Anzahl der Textureinheiten") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_MAX_TEXTURE_COORD_UNITS(def,min,max) \
+DRI_CONF_OPT_BEGIN_V(texture_coord_units,int,def, # min ":" # max ) \
+        DRI_CONF_DESC(en,"Number of texture coordinate units") \
+        DRI_CONF_DESC(de,"Anzahl der Texturkoordinateneinheiten") \
+DRI_CONF_OPT_END
+
+#define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \
+DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \
+        DRI_CONF_DESC(en,"Size of command buffer (in KB)") \
+        DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \
+DRI_CONF_OPT_END
+
+
+const char __driR300ConfigOptions[] =
+DRI_CONF_BEGIN
+       DRI_CONF_SECTION_PERFORMANCE
+               DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
+               DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
+               DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
+               DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(16, 2, 16)
+               DRI_CONF_MAX_TEXTURE_COORD_UNITS(8, 2, 8)
+               DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
+       DRI_CONF_SECTION_END
+       DRI_CONF_SECTION_QUALITY
+               DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
+               DRI_CONF_DEF_MAX_ANISOTROPY(1.0, "1.0,2.0,4.0,8.0,16.0")
+               DRI_CONF_NO_NEG_LOD_BIAS(false)
+               DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
+               DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
+               DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
+       DRI_CONF_SECTION_END
+       DRI_CONF_SECTION_DEBUG
+               DRI_CONF_NO_RAST(false)
+       DRI_CONF_SECTION_END
+DRI_CONF_END;
+static const GLuint __driR300NConfigOptions = 13;
+
+
+#ifndef RADEON_DEBUG
+int RADEON_DEBUG = 0;
+#endif
+
+static const struct dri_debug_control debug_control[] = {
+       {"fall", DEBUG_FALLBACKS},
+       {"tex", DEBUG_TEXTURE},
+       {"ioctl", DEBUG_IOCTL},
+       {"prim", DEBUG_PRIMS},
+       {"vert", DEBUG_VERTS},
+       {"state", DEBUG_STATE},
+       {"code", DEBUG_CODEGEN},
+       {"vfmt", DEBUG_VFMT},
+       {"vtxf", DEBUG_VFMT},
+       {"verb", DEBUG_VERBOSE},
+       {"dri", DEBUG_DRI},
+       {"dma", DEBUG_DMA},
+       {"san", DEBUG_SANITY},
+       {"sync", DEBUG_SYNC},
+       {"pix", DEBUG_PIXEL},
+       {"mem", DEBUG_MEMORY},
+       {NULL, 0}
+};
+
+#if 1
+/* Including xf86PciInfo.h introduces a bunch of errors...
+ */
+#define PCI_CHIP_R200_QD       0x5144  /* why do they have r200 names? */
+#define PCI_CHIP_R200_QE       0x5145  /* Those are all standard radeons */
+#define PCI_CHIP_R200_QF       0x5146
+#define PCI_CHIP_R200_QG       0x5147
+#define PCI_CHIP_R200_QY       0x5159
+#define PCI_CHIP_R200_QZ       0x515A
+#define PCI_CHIP_R200_LW       0x4C57
+#define PCI_CHIP_R200_LY       0x4C59
+#define PCI_CHIP_R200_LZ       0x4C5A
+#define PCI_CHIP_RV200_QW      0x5157  /* Radeon 7500 - not an R200 at all */
+#define PCI_CHIP_RV200_QX       0x5158
+#define PCI_CHIP_RS100_4136     0x4136 /* IGP RS100, RS200, RS250 are not R200 */
+#define PCI_CHIP_RS200_4137     0x4137
+#define PCI_CHIP_RS250_4237     0x4237
+#define PCI_CHIP_RS100_4336     0x4336
+#define PCI_CHIP_RS200_4337     0x4337
+#define PCI_CHIP_RS250_4437     0x4437
+#define PCI_CHIP_RS300_5834     0x5834 /* All RS300's are R200 */
+#define PCI_CHIP_RS300_5835     0x5835
+#define PCI_CHIP_RS300_5836     0x5836
+#define PCI_CHIP_RS300_5837     0x5837
+#define PCI_CHIP_R200_BB        0x4242 /* r200 (non-derived) start */
+#define PCI_CHIP_R200_BC        0x4243
+#define PCI_CHIP_R200_QH        0x5148
+#define PCI_CHIP_R200_QI        0x5149
+#define PCI_CHIP_R200_QJ        0x514A
+#define PCI_CHIP_R200_QK        0x514B
+#define PCI_CHIP_R200_QL        0x514C
+#define PCI_CHIP_R200_QM        0x514D
+#define PCI_CHIP_R200_QN        0x514E
+#define PCI_CHIP_R200_QO        0x514F /* r200 (non-derived) end */
+/* are the R200 Qh (0x5168) and following needed too? They are not in xf86PciInfo.h
+   but in the pci database. Maybe just secondary ports or something ? */
+
+#define PCI_CHIP_R300_AD               0x4144
+#define PCI_CHIP_R300_AE               0x4145
+#define PCI_CHIP_R300_AF               0x4146
+#define PCI_CHIP_R300_AG               0x4147
+#define PCI_CHIP_RV350_AP               0x4150
+#define PCI_CHIP_RV350_NP               0x4E50
+#define PCI_CHIP_R300_ND               0x4E44
+#define PCI_CHIP_R300_NE               0x4E45
+#define PCI_CHIP_R300_NF               0x4E46
+#define PCI_CHIP_R300_NG               0x4E47
+#define PCI_CHIP_R350_NH                0x4E48
+#endif
+
+#ifdef USE_NEW_INTERFACE
+static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
+#endif                         /* USE_NEW_INTERFACE */
+
+static radeonScreenPtr __radeonScreen;
+
+static int getSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo);
+
+#ifdef USE_NEW_INTERFACE
+static __GLcontextModes *radeonFillInModes(unsigned pixel_bits,
+                                        unsigned depth_bits,
+                                        unsigned stencil_bits,
+                                        GLboolean have_back_buffer)
+{
+       __GLcontextModes *modes;
+       __GLcontextModes *m;
+       unsigned num_modes;
+       unsigned depth_buffer_factor;
+       unsigned back_buffer_factor;
+       GLenum fb_format;
+       GLenum fb_type;
+
+       /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
+        * enough to add support.  Basically, if a context is created with an
+        * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
+        * will never be used.
+        */
+       static const GLenum back_buffer_modes[] = {
+               GLX_NONE, GLX_SWAP_UNDEFINED_OML        /*, GLX_SWAP_COPY_OML */
+       };
+
+       uint8_t depth_bits_array[2];
+       uint8_t stencil_bits_array[2];
+
+       depth_bits_array[0] = depth_bits;
+       depth_bits_array[1] = depth_bits;
+
+       /* Just like with the accumulation buffer, always provide some modes
+        * with a stencil buffer.  It will be a sw fallback, but some apps won't
+        * care about that.
+        */
+       stencil_bits_array[0] = 0;
+       stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
+
+       depth_buffer_factor = ((depth_bits != 0)
+                              || (stencil_bits != 0)) ? 2 : 1;
+       back_buffer_factor = (have_back_buffer) ? 2 : 1;
+
+       num_modes = depth_buffer_factor * back_buffer_factor * 4;
+
+       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;
+       }
+
+       modes = (*create_context_modes) (num_modes, sizeof(__GLcontextModes));
+       m = modes;
+       if (!driFillInModes(&m, fb_format, fb_type,
+                           depth_bits_array, stencil_bits_array,
+                           depth_buffer_factor, back_buffer_modes,
+                           back_buffer_factor, GLX_TRUE_COLOR)) {
+               fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+                       __LINE__);
+               return NULL;
+       }
+
+       if (!driFillInModes(&m, fb_format, fb_type,
+                           depth_bits_array, stencil_bits_array,
+                           depth_buffer_factor, back_buffer_modes,
+                           back_buffer_factor, GLX_DIRECT_COLOR)) {
+               fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+                       __LINE__);
+               return NULL;
+       }
+
+       /* Mark the visual as slow if there are "fake" stencil bits.
+        */
+       for (m = modes; m != NULL; m = m->next) {
+               if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
+                       m->visualRating = GLX_SLOW_CONFIG;
+               }
+       }
+
+       return modes;
+}
+#endif                         /* USE_NEW_INTERFACE */
+
+/* Create the device specific screen private data struct.
+ */
+static radeonScreenPtr radeonCreateScreen(__DRIscreenPrivate * sPriv)
+{
+       radeonScreenPtr screen;
+       RADEONDRIPtr dri_priv = (RADEONDRIPtr) sPriv->pDevPriv;
+       unsigned char *RADEONMMIO;
+
+       /* Allocate the private area */
+       screen = (radeonScreenPtr) CALLOC(sizeof(*screen));
+       if (!screen) {
+               __driUtilMessage
+                   ("%s: Could not allocate memory for screen structure",
+                    __FUNCTION__);
+               return NULL;
+       }
+
+#if DO_DEBUG
+       RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control);
+#endif
+
+       /* Get family and potential quirks from the PCI device ID.
+        */
+       switch (dri_priv->deviceID) {
+       case PCI_CHIP_R200_QD:
+       case PCI_CHIP_R200_QE:
+       case PCI_CHIP_R200_QF:
+       case PCI_CHIP_R200_QG:
+       case PCI_CHIP_R200_QY:
+       case PCI_CHIP_R200_QZ:
+       case PCI_CHIP_RV200_QW:
+       case PCI_CHIP_RV200_QX:
+       case PCI_CHIP_R200_LW:
+       case PCI_CHIP_R200_LY:
+       case PCI_CHIP_R200_LZ:
+       case PCI_CHIP_RS100_4136:
+       case PCI_CHIP_RS200_4137:
+       case PCI_CHIP_RS250_4237:
+       case PCI_CHIP_RS100_4336:
+       case PCI_CHIP_RS200_4337:
+       case PCI_CHIP_RS250_4437:
+               __driUtilMessage("radeonCreateScreen(): Device isn't an r200!\n");
+               FREE(screen);
+               return NULL;
+
+       case PCI_CHIP_RS300_5834:
+       case PCI_CHIP_RS300_5835:
+       case PCI_CHIP_RS300_5836:
+       case PCI_CHIP_RS300_5837:
+               screen->chipset = RADEON_CHIP_UNREAL_R200;
+               break;
+
+       case PCI_CHIP_R200_BB:
+       case PCI_CHIP_R200_BC:
+       case PCI_CHIP_R200_QH:
+       case PCI_CHIP_R200_QI:
+       case PCI_CHIP_R200_QJ:
+       case PCI_CHIP_R200_QK:
+       case PCI_CHIP_R200_QL:
+       case PCI_CHIP_R200_QM:
+       case PCI_CHIP_R200_QN:
+       case PCI_CHIP_R200_QO:
+               screen->chipset = RADEON_CHIP_REAL_R200 | RADEON_CHIPSET_TCL;
+               break;
+
+       /* TODO: Check all those chips for the exact flags required.
+        */
+       case PCI_CHIP_R300_AD:
+       case PCI_CHIP_R300_AE:
+       case PCI_CHIP_R300_AF:
+       case PCI_CHIP_R300_AG:
+       case PCI_CHIP_RV350_AP:
+       case PCI_CHIP_RV350_NP:
+               screen->chipset = RADEON_CHIP_RV350;
+               break;
+
+       case PCI_CHIP_R300_ND: /* confirmed -- nh */
+       case PCI_CHIP_R300_NE:
+       case PCI_CHIP_R300_NF:
+       case PCI_CHIP_R300_NG:
+       case PCI_CHIP_R350_NH:
+               screen->chipset = RADEON_CHIP_R300;
+               break;
+
+       default:
+               fprintf(stderr,
+                       "Unknown device ID %04X, please report. Assuming plain R300.\n",
+                       dri_priv->deviceID);
+               screen->chipset = RADEON_CHIP_R300;
+       }
+
+       /* Parse configuration */
+       if (GET_CHIP(screen) >= RADEON_CHIP_R300) {
+               driParseOptionInfo(&screen->optionCache,
+                               __driR300ConfigOptions, __driR300NConfigOptions);
+       } else {
+               driParseOptionInfo(&screen->optionCache,
+                               __driR200ConfigOptions, __driR200NConfigOptions);
+       }
+
+       /* This is first since which regions we map depends on whether or
+        * not we are using a PCI card.
+        */
+       screen->IsPCI = dri_priv->IsPCI;
+
+       {
+               int ret;
+               drm_radeon_getparam_t gp;
+
+               gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
+               gp.value = &screen->gart_buffer_offset;
+
+               ret = drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
+                                         &gp, sizeof(gp));
+               if (ret) {
+                       FREE(screen);
+                       fprintf(stderr,
+                               "drmRadeonGetParam (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n",
+                               ret);
+                       return NULL;
+               }
+
+               if (sPriv->drmMinor >= 6) {
+                       gp.param = RADEON_PARAM_GART_BASE;
+                       gp.value = &screen->gart_base;
+
+                       ret =
+                           drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
+                                               &gp, sizeof(gp));
+                       if (ret) {
+                               FREE(screen);
+                               fprintf(stderr,
+                                       "drmR200GetParam (RADEON_PARAM_GART_BASE): %d\n",
+                                       ret);
+                               return NULL;
+                       }
+
+                       gp.param = RADEON_PARAM_IRQ_NR;
+                       gp.value = &screen->irq;
+
+                       ret =
+                           drmCommandWriteRead(sPriv->fd, DRM_RADEON_GETPARAM,
+                                               &gp, sizeof(gp));
+                       if (ret) {
+                               FREE(screen);
+                               fprintf(stderr,
+                                       "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n",
+                                       ret);
+                               return NULL;
+                       }
+
+                       /* Check if kernel module is new enough to support cube maps */
+                       screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7);
+                       /* Check if kernel module is new enough to support blend color and
+                          separate blend functions/equations */
+                       screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
+
+               }
+       }
+
+       screen->mmio.handle = dri_priv->registerHandle;
+       screen->mmio.size = dri_priv->registerSize;
+       if (drmMap(sPriv->fd,
+                  screen->mmio.handle, screen->mmio.size, &screen->mmio.map)) {
+               FREE(screen);
+               __driUtilMessage("%s: drmMap failed\n", __FUNCTION__);
+               return NULL;
+       }
+
+       RADEONMMIO = screen->mmio.map;
+
+       screen->status.handle = dri_priv->statusHandle;
+       screen->status.size = dri_priv->statusSize;
+       if (drmMap(sPriv->fd,
+                  screen->status.handle,
+                  screen->status.size, &screen->status.map)) {
+               drmUnmap(screen->mmio.map, screen->mmio.size);
+               FREE(screen);
+               __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__);
+               return NULL;
+       }
+       screen->scratch = (__volatile__ uint32_t *)
+           ((GLubyte *) screen->status.map + RADEON_SCRATCH_REG_OFFSET);
+
+       screen->buffers = drmMapBufs(sPriv->fd);
+       if (!screen->buffers) {
+               drmUnmap(screen->status.map, screen->status.size);
+               drmUnmap(screen->mmio.map, screen->mmio.size);
+               FREE(screen);
+               __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__);
+               return NULL;
+       }
+
+       if (dri_priv->gartTexHandle && dri_priv->gartTexMapSize) {
+
+               screen->gartTextures.handle = dri_priv->gartTexHandle;
+               screen->gartTextures.size = dri_priv->gartTexMapSize;
+               if (drmMap(sPriv->fd,
+                          screen->gartTextures.handle,
+                          screen->gartTextures.size,
+                          (drmAddressPtr) & screen->gartTextures.map)) {
+                       drmUnmapBufs(screen->buffers);
+                       drmUnmap(screen->status.map, screen->status.size);
+                       drmUnmap(screen->mmio.map, screen->mmio.size);
+                       FREE(screen);
+                       __driUtilMessage
+                           ("%s: drmMAP failed for GART texture area\n",
+                            __FUNCTION__);
+                       return NULL;
+               }
+
+               screen->gart_texture_offset =
+                   dri_priv->gartTexOffset +
+                   (screen->IsPCI ? INREG(RADEON_AIC_LO_ADDR)
+                    : ((INREG(RADEON_MC_AGP_LOCATION) & 0x0ffffU) << 16));
+       }
+
+       screen->cpp = dri_priv->bpp / 8;
+       screen->AGPMode = dri_priv->AGPMode;
+
+       screen->fbLocation = (INREG(RADEON_MC_FB_LOCATION) & 0xffff) << 16;
+
+       if (sPriv->drmMinor >= 10) {
+               drm_radeon_setparam_t sp;
+
+               sp.param = RADEON_SETPARAM_FB_LOCATION;
+               sp.value = screen->fbLocation;
+
+               drmCommandWrite(sPriv->fd, DRM_RADEON_SETPARAM,
+                               &sp, sizeof(sp));
+       }
+
+       screen->frontOffset = dri_priv->frontOffset;
+       screen->frontPitch = dri_priv->frontPitch;
+       screen->backOffset = dri_priv->backOffset;
+       screen->backPitch = dri_priv->backPitch;
+       screen->depthOffset = dri_priv->depthOffset;
+       screen->depthPitch = dri_priv->depthPitch;
+
+       screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
+           + screen->fbLocation;
+       screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
+       screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
+           dri_priv->log2TexGran;
+
+       if (!screen->gartTextures.map) {
+               screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
+               screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
+               screen->texSize[RADEON_GART_TEX_HEAP] = 0;
+               screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
+       } else {
+               screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
+               screen->texOffset[RADEON_GART_TEX_HEAP] =
+                   screen->gart_texture_offset;
+               screen->texSize[RADEON_GART_TEX_HEAP] =
+                   dri_priv->gartTexMapSize;
+               screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
+                   dri_priv->log2GARTTexGran;
+       }
+
+       screen->driScreen = sPriv;
+       screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
+
+       if (driCompareGLXAPIVersion(20030813) >= 0) {
+               PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
+                   (PFNGLXSCRENABLEEXTENSIONPROC)
+                   glXGetProcAddress((const GLubyte *)
+                                     "__glXScrEnableExtension");
+               void *const psc = sPriv->psc->screenConfigs;
+
+               if (glx_enable_extension != NULL) {
+                       if (screen->irq != 0) {
+                               (*glx_enable_extension) (psc,
+                                                        "GLX_SGI_swap_control");
+                               (*glx_enable_extension) (psc,
+                                                        "GLX_SGI_video_sync");
+                               (*glx_enable_extension) (psc,
+                                                        "GLX_MESA_swap_control");
+                       }
+
+                       (*glx_enable_extension) (psc,
+                                                "GLX_MESA_swap_frame_usage");
+
+                       if (driCompareGLXAPIVersion(20030818) >= 0) {
+                               sPriv->psc->allocateMemory =
+                                   (void *)r200AllocateMemoryMESA;
+                               sPriv->psc->freeMemory =
+                                   (void *)r200FreeMemoryMESA;
+                               sPriv->psc->memoryOffset =
+                                   (void *)r200GetMemoryOffsetMESA;
+
+                               (*glx_enable_extension) (psc,
+                                                        "GLX_MESA_allocate_memory");
+                       }
+
+                       if (driCompareGLXAPIVersion(20030915) >= 0) {
+                               (*glx_enable_extension) (psc,
+                                                        "GLX_SGIX_fbconfig");
+                               (*glx_enable_extension) (psc,
+                                                        "GLX_OML_swap_method");
+                       }
+               }
+       }
+       return screen;
+}
+
+/* Destroy the device specific screen private data struct.
+ */
+static void radeonDestroyScreen(__DRIscreenPrivate * sPriv)
+{
+       radeonScreenPtr screen = (radeonScreenPtr) sPriv->private;
+
+       if (!screen)
+               return;
+
+       if (screen->gartTextures.map) {
+               drmUnmap(screen->gartTextures.map, screen->gartTextures.size);
+       }
+       drmUnmapBufs(screen->buffers);
+       drmUnmap(screen->status.map, screen->status.size);
+       drmUnmap(screen->mmio.map, screen->mmio.size);
+
+       /* free all option information */
+       driDestroyOptionInfo(&screen->optionCache);
+
+       FREE(screen);
+       sPriv->private = NULL;
+}
+
+/* Initialize the driver specific screen private data.
+ */
+static GLboolean radeonInitDriver(__DRIscreenPrivate * sPriv)
+{
+       __radeonScreen = radeonCreateScreen(sPriv);
+
+       sPriv->private = (void *)__radeonScreen;
+
+       return sPriv->private ? GL_TRUE : GL_FALSE;
+}
+
+/**
+ * Create and initialize the Mesa and driver specific pixmap buffer
+ * data.
+ *
+ * \todo This function (and its interface) will need to be updated to support
+ * pbuffers.
+ */
+static GLboolean
+radeonCreateBuffer(__DRIscreenPrivate * driScrnPriv,
+                  __DRIdrawablePrivate * driDrawPriv,
+                  const __GLcontextModes * mesaVis, GLboolean isPixmap)
+{
+       if (isPixmap) {
+               return GL_FALSE;        /* not implemented */
+       } else {
+               const GLboolean swDepth = GL_FALSE;
+               const GLboolean swAlpha = GL_FALSE;
+               const GLboolean swAccum = mesaVis->accumRedBits > 0;
+               const GLboolean swStencil = mesaVis->stencilBits > 0 &&
+                   mesaVis->depthBits != 24;
+               driDrawPriv->driverPrivate = (void *)
+                   _mesa_create_framebuffer(mesaVis,
+                                            swDepth,
+                                            swStencil, swAccum, swAlpha);
+               return (driDrawPriv->driverPrivate != NULL);
+       }
+}
+
+static void radeonDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
+{
+       _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->
+                                                    driverPrivate));
+}
+
+
+/**
+ * Choose the appropriate CreateContext function based on the chipset.
+ */
+static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
+                                    __DRIcontextPrivate * driContextPriv,
+                                    void *sharedContextPriv)
+{
+       __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+       radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
+       int chip = GET_CHIP(screen);
+
+       if (chip >= RADEON_CHIP_R300)
+               return r300CreateContext(glVisual, driContextPriv, sharedContextPriv);
+       else
+               return r200CreateContext(glVisual, driContextPriv, sharedContextPriv);
+}
+
+
+/**
+ * Choose the appropriate DestroyContext function based on the chipset.
+ */
+static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv)
+{
+       radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
+       int chip = GET_CHIP(radeon->radeonScreen);
+
+       if (chip >= RADEON_CHIP_R300)
+               return r300DestroyContext(driContextPriv);
+       else
+               return r200DestroyContext(driContextPriv);
+}
+
+
+static const struct __DriverAPIRec radeonAPI = {
+       .InitDriver = radeonInitDriver,
+       .DestroyScreen = radeonDestroyScreen,
+       .CreateContext = radeonCreateContext,
+       .DestroyContext = radeonDestroyContext,
+       .CreateBuffer = radeonCreateBuffer,
+       .DestroyBuffer = radeonDestroyBuffer,
+       .SwapBuffers = radeonSwapBuffers,
+       .MakeCurrent = radeonMakeCurrent,
+       .UnbindContext = radeonUnbindContext,
+       .GetSwapInfo = getSwapInfo,
+       .GetMSC = driGetMSC32,
+       .WaitForMSC = driWaitForMSC32,
+       .WaitForSBC = NULL,
+       .SwapBuffersMSC = NULL
+};
+
+/*
+ * This is the bootstrap function for the driver.
+ * The __driCreateScreen name is the symbol that libGL.so fetches.
+ * Return:  pointer to a __DRIscreenPrivate.
+ *
+ */
+#if !defined(DRI_NEW_INTERFACE_ONLY)
+void *__driCreateScreen(Display * dpy, int scrn, __DRIscreen * psc,
+                       int numConfigs, __GLXvisualConfig * config)
+{
+       __DRIscreenPrivate *psp;
+       psp =
+           __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI);
+       return (void *)psp;
+}
+#endif                         /* !defined(DRI_NEW_INTERFACE_ONLY) */
+
+/**
+ * This is the bootstrap function for the driver.  libGL supplies all of the
+ * requisite information about the system, and the driver initializes itself.
+ * This routine also fills in the linked list pointed to by \c driver_modes
+ * with the \c __GLcontextModes that the driver can support for windows or
+ * pbuffers.
+ *
+ * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
+ *         failure.
+ */
+#ifdef USE_NEW_INTERFACE
+void *__driCreateNewScreen(__DRInativeDisplay * dpy, int scrn,
+                          __DRIscreen * psc, const __GLcontextModes * modes,
+                          const __DRIversion * ddx_version,
+                          const __DRIversion * dri_version,
+                          const __DRIversion * drm_version,
+                          const __DRIframebuffer * frame_buffer,
+                          drmAddress pSAREA, int fd, int internal_api_version,
+                          __GLcontextModes ** driver_modes)
+{
+       __DRIscreenPrivate *psp;
+       static const __DRIversion ddx_expected = { 4, 0, 0 };
+       static const __DRIversion dri_expected = { 4, 0, 0 };
+       static const __DRIversion drm_expected = { 1, 11, 1 };
+
+       if (!driCheckDriDdxDrmVersions2("R300",
+                                       dri_version, &dri_expected,
+                                       ddx_version, &ddx_expected,
+                                       drm_version, &drm_expected)) {
+               return NULL;
+       }
+
+       psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
+                                      ddx_version, dri_version, drm_version,
+                                      frame_buffer, pSAREA, fd,
+                                      internal_api_version, &radeonAPI);
+       if (psp != NULL) {
+               create_context_modes = (PFNGLXCREATECONTEXTMODES)
+                   glXGetProcAddress((const GLubyte *)
+                                     "__glXCreateContextModes");
+               if (create_context_modes != NULL) {
+                       RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
+                       *driver_modes = radeonFillInModes(dri_priv->bpp,
+                                                       (dri_priv->bpp ==
+                                                        16) ? 16 : 24,
+                                                       (dri_priv->bpp ==
+                                                        16) ? 0 : 8,
+                                                       (dri_priv->backOffset !=
+                                                        dri_priv->
+                                                        depthOffset));
+               }
+       }
+
+       return (void *)psp;
+}
+#endif                         /* USE_NEW_INTERFACE */
+
+/**
+ * Get information about previous buffer swaps.
+ */
+static int getSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
+{
+       radeonContextPtr radeon;
+
+       if ((dPriv == NULL) || (dPriv->driContextPriv == NULL)
+           || (dPriv->driContextPriv->driverPrivate == NULL)
+           || (sInfo == NULL)) {
+               return -1;
+       }
+
+       radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
+       sInfo->swap_count = radeon->swap_count;
+       sInfo->swap_ust = radeon->swap_ust;
+       sInfo->swap_missed_count = radeon->swap_missed_count;
+
+       sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
+           ? driCalculateSwapUsage(dPriv, 0, radeon->swap_missed_ust)
+           : 0.0;
+
+       return 0;
+}
diff --git a/src/mesa/drivers/dri/r300/radeon_screen.h b/src/mesa/drivers/dri/r300/radeon_screen.h
new file mode 100644 (file)
index 0000000..a1a0191
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef __RADEON_SCREEN_H__
+#define __RADEON_SCREEN_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "xf86drm.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "dri_util.h"
+#include "xmlconfig.h"
+
+typedef struct {
+       drm_handle_t handle;    /* Handle to the DRM region */
+       drmSize size;           /* Size of the DRM region */
+       drmAddress map;         /* Mapping of the DRM region */
+} radeonRegionRec, *radeonRegionPtr;
+
+/* chipset features */
+#define RADEON_CHIP_UNREAL_R200                0
+#define RADEON_CHIP_REAL_R200          1
+#define RADEON_CHIP_R300               2
+#define RADEON_CHIP_RV350              3
+#define RADEON_CHIP_MASK               0x0f
+
+#define RADEON_CHIPSET_TCL             (1 << 8)
+
+#define GET_CHIP(screen) ((screen)->chipset & RADEON_CHIP_MASK)
+#define IS_FAMILY_R200(radeon) (GET_CHIP((radeon)->radeonScreen) < RADEON_CHIP_R300)
+#define IS_FAMILY_R300(radeon) (GET_CHIP((radeon)->radeonScreen) >= RADEON_CHIP_R300)
+
+#define R200_NR_TEX_HEAPS 2
+
+typedef struct {
+       int chipset;
+       int cpp;
+       int IsPCI;              /* Current card is a PCI card */
+       int AGPMode;
+       unsigned int irq;       /* IRQ number (0 means none) */
+
+       unsigned int fbLocation;
+       unsigned int frontOffset;
+       unsigned int frontPitch;
+       unsigned int backOffset;
+       unsigned int backPitch;
+
+       unsigned int depthOffset;
+       unsigned int depthPitch;
+
+       /* Shared texture data */
+       int numTexHeaps;
+       int texOffset[R200_NR_TEX_HEAPS];
+       int texSize[R200_NR_TEX_HEAPS];
+       int logTexGranularity[R200_NR_TEX_HEAPS];
+
+       radeonRegionRec mmio;
+       radeonRegionRec status;
+       radeonRegionRec gartTextures;
+
+       drmBufMapPtr buffers;
+
+       __volatile__ int32_t *scratch;
+
+       __DRIscreenPrivate *driScreen;
+       unsigned int sarea_priv_offset;
+       unsigned int gart_buffer_offset;        /* offset in card memory space */
+       unsigned int gart_texture_offset;       /* offset in card memory space */
+       unsigned int gart_base;
+
+       GLboolean drmSupportsCubeMaps;  /* need radeon kernel module >=1.7 */
+       GLboolean drmSupportsBlendColor;        /* need radeon kernel module >= 1.11 */
+
+       /* Configuration cache with default values for all contexts */
+       driOptionCache optionCache;
+} radeonScreenRec, *radeonScreenPtr;
+
+#endif
+#endif                         /* __RADEON_SCREEN_H__ */
diff --git a/src/mesa/drivers/dri/r300/radeon_span.c b/src/mesa/drivers/dri/r300/radeon_span.c
new file mode 100644 (file)
index 0000000..9046320
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "swrast/swrast.h"
+#include "colormac.h"
+
+#include "r200_context.h"
+#include "radeon_ioctl.h"
+#include "r300_ioctl.h"
+#include "radeon_span.h"
+
+#define DBG 0
+
+#define LOCAL_VARS                                                     \
+   radeonContextPtr radeon = RADEON_CONTEXT(ctx);                      \
+   radeonScreenPtr radeonScreen = radeon->radeonScreen;                        \
+   __DRIscreenPrivate *sPriv = radeon->dri.screen;                     \
+   __DRIdrawablePrivate *dPriv = radeon->dri.drawable;                 \
+   GLuint pitch = radeonScreen->frontPitch * radeonScreen->cpp;                \
+   GLuint height = dPriv->h;                                           \
+   char *buf = (char *)(sPriv->pFB +                                   \
+                       radeon->state.color.drawOffset +                \
+                       (dPriv->x * radeonScreen->cpp) +                \
+                       (dPriv->y * pitch));                            \
+   char *read_buf = (char *)(sPriv->pFB +                              \
+                            radeon->state.pixel.readOffset +           \
+                            (dPriv->x * radeonScreen->cpp) +           \
+                            (dPriv->y * pitch));                       \
+   GLuint p;                                                           \
+   (void) read_buf; (void) buf; (void) p
+
+#define LOCAL_DEPTH_VARS                                               \
+   radeonContextPtr radeon = RADEON_CONTEXT(ctx);                      \
+   radeonScreenPtr radeonScreen = radeon->radeonScreen;                        \
+   __DRIscreenPrivate *sPriv = radeon->dri.screen;                     \
+   __DRIdrawablePrivate *dPriv = radeon->dri.drawable;                 \
+   GLuint height = dPriv->h;                                           \
+   GLuint xo = dPriv->x;                                               \
+   GLuint yo = dPriv->y;                                               \
+   char *buf = (char *)(sPriv->pFB + radeon->radeonScreen->depthOffset);       \
+   GLuint pitch = radeon->radeonScreen->depthPitch;                    \
+   (void) buf; (void) pitch
+
+#define LOCAL_STENCIL_VARS     LOCAL_DEPTH_VARS
+
+#define CLIPPIXEL( _x, _y )                                            \
+   ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))
+
+#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i )                           \
+   if ( _y < miny || _y >= maxy ) {                                    \
+      _n1 = 0, _x1 = x;                                                        \
+   } else {                                                            \
+      _n1 = _n;                                                                \
+      _x1 = _x;                                                                \
+      if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
+      if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx);                        \
+   }
+
+#define Y_FLIP( _y )           (height - _y - 1)
+
+#define HW_LOCK()
+
+#define HW_CLIPLOOP()                                                  \
+   do {                                                                        \
+      __DRIdrawablePrivate *dPriv = radeon->dri.drawable;              \
+      int _nc = dPriv->numClipRects;                                   \
+                                                                       \
+      while ( _nc-- ) {                                                        \
+        int minx = dPriv->pClipRects[_nc].x1 - dPriv->x;               \
+        int miny = dPriv->pClipRects[_nc].y1 - dPriv->y;               \
+        int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x;               \
+        int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
+
+#define HW_ENDCLIPLOOP()                                               \
+      }                                                                        \
+   } while (0)
+
+#define HW_UNLOCK()
+
+/* ================================================================
+ * Color buffer
+ */
+
+/* 16 bit, RGB565 color spanline and pixel functions
+ */
+#define INIT_MONO_PIXEL(p, color) \
+  p = PACK_COLOR_565( color[0], color[1], color[2] )
+
+#define WRITE_RGBA( _x, _y, r, g, b, a )                               \
+   *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) |    \
+                                          (((int)g & 0xfc) << 3) |     \
+                                          (((int)b & 0xf8) >> 3))
+
+#define WRITE_PIXEL( _x, _y, p )                                       \
+   *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y )                                      \
+   do {                                                                        \
+      GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch);          \
+      rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8;                                \
+      rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc;                                \
+      rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;                                \
+      rgba[3] = 0xff;                                                  \
+   } while (0)
+
+#define TAG(x) radeon##x##_RGB565
+#include "spantmp.h"
+
+/* 32 bit, ARGB8888 color spanline and pixel functions
+ */
+#undef INIT_MONO_PIXEL
+#define INIT_MONO_PIXEL(p, color) \
+  p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] )
+
+#define WRITE_RGBA( _x, _y, r, g, b, a )                       \
+do {                                                           \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = ((b <<  0) |           \
+                                        (g <<  8) |            \
+                                        (r << 16) |            \
+                                        (a << 24) );           \
+} while (0)
+
+#define WRITE_PIXEL( _x, _y, p )                       \
+do {                                                   \
+   *(GLuint *)(buf + _x*4 + _y*pitch) = p;             \
+} while (0)
+
+#define READ_RGBA( rgba, _x, _y )                              \
+do {                                                           \
+   volatile GLuint *ptr = (volatile GLuint *)(read_buf + _x*4 + _y*pitch); \
+   GLuint p = *ptr;                                    \
+   rgba[0] = (p >> 16) & 0xff;                                 \
+   rgba[1] = (p >>  8) & 0xff;                                 \
+   rgba[2] = (p >>  0) & 0xff;                                 \
+   rgba[3] = (p >> 24) & 0xff;                                 \
+} while (0)
+
+#define TAG(x) radeon##x##_ARGB8888
+#include "spantmp.h"
+
+/* ================================================================
+ * Depth buffer
+ */
+
+/* The Radeon family has depth tiling on all the time, so we have to convert
+ * the x,y coordinates into the memory bus address (mba) in the same
+ * manner as the engine.  In each case, the linear block address (ba)
+ * is calculated, and then wired with x and y to produce the final
+ * memory address.
+ */
+
+#define BIT(x,b) ((x & (1<<b))>>b)
+static GLuint radeon_mba_z32(radeonContextPtr radeon, GLint x, GLint y)
+{
+       GLuint pitch = radeon->radeonScreen->depthPitch;
+       GLuint b =
+           ((y & 0x3FF) >> 4) * ((pitch & 0xFFF) >> 5) + ((x & 0x3FF) >> 5);
+       GLuint a =
+           (BIT(x, 0) << 2) | (BIT(y, 0) << 3) | (BIT(x, 1) << 4) | (BIT(y, 1)
+                                                                     << 5) |
+           (BIT(x, 3) << 6) | (BIT(x, 4) << 7) | (BIT(x, 2) << 8) | (BIT(y, 2)
+                                                                     << 9) |
+           (BIT(y, 3) << 10) |
+           (((pitch & 0x20) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y, 4)))) << 11) |
+           ((b >> 1) << 12);
+       return a;
+}
+
+static GLuint radeon_mba_z16(radeonContextPtr radeon, GLint x, GLint y)
+{
+       GLuint pitch = radeon->radeonScreen->depthPitch;
+       GLuint b =
+           ((y & 0x3FF) >> 4) * ((pitch & 0xFFF) >> 6) + ((x & 0x3FF) >> 6);
+       GLuint a =
+           (BIT(x, 0) << 1) | (BIT(y, 0) << 2) | (BIT(x, 1) << 3) | (BIT(y, 1)
+                                                                     << 4) |
+           (BIT(x, 2) << 5) | (BIT(x, 4) << 6) | (BIT(x, 5) << 7) | (BIT(x, 3)
+                                                                     << 8) |
+           (BIT(y, 2) << 9) | (BIT(y, 3) << 10) |
+           (((pitch & 0x40) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y, 4)))) << 11) |
+           ((b >> 1) << 12);
+       return a;
+}
+
+
+/* 16-bit depth buffer functions
+ */
+#define WRITE_DEPTH( _x, _y, d )                                       \
+   *(GLushort *)(buf + radeon_mba_z16( radeon, _x + xo, _y + yo )) = d;
+
+#define READ_DEPTH( d, _x, _y )                                                \
+   d = *(GLushort *)(buf + radeon_mba_z16( radeon, _x + xo, _y + yo ));
+
+#define TAG(x) radeon##x##_16_TILE
+#include "depthtmp.h"
+
+/* 24 bit depth, 8 bit stencil depthbuffer functions
+ */
+#define WRITE_DEPTH( _x, _y, d )                                       \
+do {                                                                   \
+   GLuint offset = radeon_mba_z32( radeon, _x + xo, _y + yo );         \
+   GLuint tmp = *(GLuint *)(buf + offset);                             \
+   tmp &= 0xff000000;                                                  \
+   tmp |= ((d) & 0x00ffffff);                                          \
+   *(GLuint *)(buf + offset) = tmp;                                    \
+} while (0)
+
+#define READ_DEPTH( d, _x, _y )                                                \
+   d = *(GLuint *)(buf + radeon_mba_z32( radeon, _x + xo,              \
+                                        _y + yo )) & 0x00ffffff;
+
+#define TAG(x) radeon##x##_24_8_TILE
+#include "depthtmp.h"
+
+/* 16-bit depth buffer functions
+ */
+#define WRITE_DEPTH( _x, _y, d )                                       \
+   *(GLushort *)(buf + (_x + xo)*2 + (_y + yo)*pitch ) = d;
+
+#define READ_DEPTH( d, _x, _y )                                                \
+   d = *(GLushort *)(buf + (_x + xo)*2 + (_y + yo)*pitch );
+
+#define TAG(x) radeon##x##_16_LINEAR
+#include "depthtmp.h"
+
+/* 24 bit depth, 8 bit stencil depthbuffer functions
+ */
+#define WRITE_DEPTH( _x, _y, d )                                       \
+do {                                                                   \
+   GLuint offset = (_x + xo)*4 + (_y + yo)*pitch;                      \
+   GLuint tmp = *(GLuint *)(buf + offset);                             \
+   tmp &= 0xff000000;                                                  \
+   tmp |= ((d) & 0x00ffffff);                                          \
+   *(GLuint *)(buf + offset) = tmp;                                    \
+} while (0)
+
+#define READ_DEPTH( d, _x, _y )                                                \
+   d = *(GLuint *)(buf + (_x + xo)*4 + (_y + yo)*pitch) & 0x00ffffff;
+
+#define TAG(x) radeon##x##_24_8_LINEAR
+#include "depthtmp.h"
+
+/* ================================================================
+ * Stencil buffer
+ */
+
+/* 24 bit depth, 8 bit stencil depthbuffer functions
+ */
+#define WRITE_STENCIL( _x, _y, d )                                     \
+do {                                                                   \
+   GLuint offset = radeon_mba_z32( radeon, _x + xo, _y + yo );         \
+   GLuint tmp = *(GLuint *)(buf + offset);                             \
+   tmp &= 0x00ffffff;                                                  \
+   tmp |= (((d) & 0xff) << 24);                                                \
+   *(GLuint *)(buf + offset) = tmp;                                    \
+} while (0)
+
+#define READ_STENCIL( d, _x, _y )                                      \
+do {                                                                   \
+   GLuint offset = radeon_mba_z32( radeon, _x + xo, _y + yo );         \
+   GLuint tmp = *(GLuint *)(buf + offset);                             \
+   tmp &= 0xff000000;                                                  \
+   d = tmp >> 24;                                                      \
+} while (0)
+
+#define TAG(x) radeon##x##_24_8_TILE
+#include "stenciltmp.h"
+
+/* 24 bit depth, 8 bit stencil depthbuffer functions
+ */
+#define WRITE_STENCIL( _x, _y, d )                                     \
+do {                                                                   \
+   GLuint offset = (_x + xo)*4 + (_y + yo)*pitch;                      \
+   GLuint tmp = *(GLuint *)(buf + offset);                             \
+   tmp &= 0x00ffffff;                                                  \
+   tmp |= (((d) & 0xff) << 24);                                                \
+   *(GLuint *)(buf + offset) = tmp;                                    \
+} while (0)
+
+#define READ_STENCIL( d, _x, _y )                                      \
+do {                                                                   \
+   GLuint offset = (_x + xo)*4 + (_y + yo)*pitch;                      \
+   GLuint tmp = *(GLuint *)(buf + offset);                             \
+   tmp &= 0xff000000;                                                  \
+   d = tmp >> 24;                                                      \
+} while (0)
+
+#define TAG(x) radeon##x##_24_8_LINEAR
+#include "stenciltmp.h"
+
+/*
+ * This function is called to specify which buffer to read and write
+ * for software rasterization (swrast) fallbacks.  This doesn't necessarily
+ * correspond to glDrawBuffer() or glReadBuffer() calls.
+ */
+static void radeonSetBuffer(GLcontext * ctx,
+                         GLframebuffer * colorBuffer, GLuint bufferBit)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       switch (bufferBit) {
+       case DD_FRONT_LEFT_BIT:
+               if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) {
+                       radeon->state.pixel.readOffset =
+                           radeon->radeonScreen->backOffset;
+                       radeon->state.pixel.readPitch =
+                           radeon->radeonScreen->backPitch;
+                       radeon->state.color.drawOffset =
+                           radeon->radeonScreen->backOffset;
+                       radeon->state.color.drawPitch =
+                           radeon->radeonScreen->backPitch;
+               } else {
+                       radeon->state.pixel.readOffset =
+                           radeon->radeonScreen->frontOffset;
+                       radeon->state.pixel.readPitch =
+                           radeon->radeonScreen->frontPitch;
+                       radeon->state.color.drawOffset =
+                           radeon->radeonScreen->frontOffset;
+                       radeon->state.color.drawPitch =
+                           radeon->radeonScreen->frontPitch;
+               }
+               break;
+       case DD_BACK_LEFT_BIT:
+               if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) {
+                       radeon->state.pixel.readOffset =
+                           radeon->radeonScreen->frontOffset;
+                       radeon->state.pixel.readPitch =
+                           radeon->radeonScreen->frontPitch;
+                       radeon->state.color.drawOffset =
+                           radeon->radeonScreen->frontOffset;
+                       radeon->state.color.drawPitch =
+                           radeon->radeonScreen->frontPitch;
+               } else {
+                       radeon->state.pixel.readOffset =
+                           radeon->radeonScreen->backOffset;
+                       radeon->state.pixel.readPitch =
+                           radeon->radeonScreen->backPitch;
+                       radeon->state.color.drawOffset =
+                           radeon->radeonScreen->backOffset;
+                       radeon->state.color.drawPitch =
+                           radeon->radeonScreen->backPitch;
+               }
+               break;
+       default:
+               _mesa_problem(ctx, "Bad bufferBit in %s", __FUNCTION__);
+               break;
+       }
+}
+
+/* Move locking out to get reasonable span performance (10x better
+ * than doing this in HW_LOCK above).  WaitForIdle() is the main
+ * culprit.
+ */
+
+static void radeonSpanRenderStart(GLcontext * ctx)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       if (IS_FAMILY_R200(radeon))
+               R200_FIREVERTICES((r200ContextPtr)radeon);
+       else
+               r300Flush(ctx);
+
+       LOCK_HARDWARE(radeon);
+       radeonWaitForIdleLocked(radeon);
+
+       /* Read & rewrite the first pixel in the frame buffer.  This should
+        * be a noop, right?  In fact without this conform fails as reading
+        * from the framebuffer sometimes produces old results -- the
+        * on-card read cache gets mixed up and doesn't notice that the
+        * framebuffer has been updated.
+        *
+        * In the worst case this is buggy too as p might get the wrong
+        * value first time, so really need a hidden pixel somewhere for this.
+        */
+       {
+               int p;
+               volatile int *read_buf =
+                   (volatile int *)(radeon->dri.screen->pFB +
+                                    radeon->state.pixel.readOffset);
+               p = *read_buf;
+               *read_buf = p;
+       }
+}
+
+static void radeonSpanRenderFinish(GLcontext * ctx)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       _swrast_flush(ctx);
+       UNLOCK_HARDWARE(radeon);
+}
+
+void radeonInitSpanFuncs(GLcontext * ctx)
+{
+       r200ContextPtr rmesa = R200_CONTEXT(ctx);
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       struct swrast_device_driver *swdd =
+           _swrast_GetDeviceDriverReference(ctx);
+
+       swdd->SetBuffer = radeonSetBuffer;
+
+       switch (radeon->radeonScreen->cpp) {
+       case 2:
+               swdd->WriteRGBASpan = radeonWriteRGBASpan_RGB565;
+               swdd->WriteRGBSpan = radeonWriteRGBSpan_RGB565;
+               swdd->WriteMonoRGBASpan = radeonWriteMonoRGBASpan_RGB565;
+               swdd->WriteRGBAPixels = radeonWriteRGBAPixels_RGB565;
+               swdd->WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_RGB565;
+               swdd->ReadRGBASpan = radeonReadRGBASpan_RGB565;
+               swdd->ReadRGBAPixels = radeonReadRGBAPixels_RGB565;
+               break;
+
+       case 4:
+               swdd->WriteRGBASpan = radeonWriteRGBASpan_ARGB8888;
+               swdd->WriteRGBSpan = radeonWriteRGBSpan_ARGB8888;
+               swdd->WriteMonoRGBASpan = radeonWriteMonoRGBASpan_ARGB8888;
+               swdd->WriteRGBAPixels = radeonWriteRGBAPixels_ARGB8888;
+               swdd->WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_ARGB8888;
+               swdd->ReadRGBASpan = radeonReadRGBASpan_ARGB8888;
+               swdd->ReadRGBAPixels = radeonReadRGBAPixels_ARGB8888;
+               break;
+
+       default:
+               break;
+       }
+
+       if (IS_FAMILY_R300(radeon))
+       {
+               switch (radeon->glCtx->Visual.depthBits) {
+               case 16:
+                       swdd->ReadDepthSpan = radeonReadDepthSpan_16_LINEAR;
+                       swdd->WriteDepthSpan = radeonWriteDepthSpan_16_LINEAR;
+                       swdd->WriteMonoDepthSpan = radeonWriteMonoDepthSpan_16_LINEAR;
+                       swdd->ReadDepthPixels = radeonReadDepthPixels_16_LINEAR;
+                       swdd->WriteDepthPixels = radeonWriteDepthPixels_16_LINEAR;
+                       break;
+
+               case 24:
+                       swdd->ReadDepthSpan = radeonReadDepthSpan_24_8_LINEAR;
+                       swdd->WriteDepthSpan = radeonWriteDepthSpan_24_8_LINEAR;
+                       swdd->WriteMonoDepthSpan = radeonWriteMonoDepthSpan_24_8_LINEAR;
+                       swdd->ReadDepthPixels = radeonReadDepthPixels_24_8_LINEAR;
+                       swdd->WriteDepthPixels = radeonWriteDepthPixels_24_8_LINEAR;
+
+                       swdd->ReadStencilSpan = radeonReadStencilSpan_24_8_LINEAR;
+                       swdd->WriteStencilSpan = radeonWriteStencilSpan_24_8_LINEAR;
+                       swdd->ReadStencilPixels = radeonReadStencilPixels_24_8_LINEAR;
+                       swdd->WriteStencilPixels = radeonWriteStencilPixels_24_8_LINEAR;
+                       break;
+
+               default:
+                       break;
+               }
+       }
+       else
+       {
+               switch (radeon->glCtx->Visual.depthBits) {
+               case 16:
+                       swdd->ReadDepthSpan = radeonReadDepthSpan_16_TILE;
+                       swdd->WriteDepthSpan = radeonWriteDepthSpan_16_TILE;
+                       swdd->WriteMonoDepthSpan = radeonWriteMonoDepthSpan_16_TILE;
+                       swdd->ReadDepthPixels = radeonReadDepthPixels_16_TILE;
+                       swdd->WriteDepthPixels = radeonWriteDepthPixels_16_TILE;
+                       break;
+
+               case 24:
+                       swdd->ReadDepthSpan = radeonReadDepthSpan_24_8_TILE;
+                       swdd->WriteDepthSpan = radeonWriteDepthSpan_24_8_TILE;
+                       swdd->WriteMonoDepthSpan = radeonWriteMonoDepthSpan_24_8_TILE;
+                       swdd->ReadDepthPixels = radeonReadDepthPixels_24_8_TILE;
+                       swdd->WriteDepthPixels = radeonWriteDepthPixels_24_8_TILE;
+
+                       swdd->ReadStencilSpan = radeonReadStencilSpan_24_8_TILE;
+                       swdd->WriteStencilSpan = radeonWriteStencilSpan_24_8_TILE;
+                       swdd->ReadStencilPixels = radeonReadStencilPixels_24_8_TILE;
+                       swdd->WriteStencilPixels = radeonWriteStencilPixels_24_8_TILE;
+                       break;
+
+               default:
+                       break;
+               }
+       }
+
+       swdd->SpanRenderStart = radeonSpanRenderStart;
+       swdd->SpanRenderFinish = radeonSpanRenderFinish;
+}
diff --git a/src/mesa/drivers/dri/r300/radeon_span.h b/src/mesa/drivers/dri/r300/radeon_span.h
new file mode 100644 (file)
index 0000000..e6a0f98
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
+
+The Weather Channel (TM) funded Tungsten Graphics to develop the
+initial release of the Radeon 8500 driver under the XFree86 license.
+This notice must be preserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef __RADEON_SPAN_H__
+#define __RADEON_SPAN_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void radeonInitSpanFuncs(GLcontext * ctx);
+
+#endif
+#endif