--- /dev/null
+# 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)
+
--- /dev/null
+/* $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__ */
--- /dev/null
+/*
+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__ */
--- /dev/null
+/* $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
--- /dev/null
+#ifndef R200_SANITY_H
+#define R200_SANITY_H
+
+extern int r200SanityCmdBuffer(r200ContextPtr rmesa,
+ int nbox, drm_clip_rect_t * boxes);
+
+#endif
--- /dev/null
+/* $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
--- /dev/null
+/* $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
--- /dev/null
+/* $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__ */
--- /dev/null
+/*
+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);
+ }
+}
+
--- /dev/null
+/*
+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__ */
--- /dev/null
+/*
+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);
+ }
+}
--- /dev/null
+/*
+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__ */
--- /dev/null
+/*
+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;
+}
--- /dev/null
+/*
+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__ */
--- /dev/null
+/*
+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__ */
--- /dev/null
+#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
--- /dev/null
+/*
+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;
+}
+
--- /dev/null
+/*
+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__ */
--- /dev/null
+/*
+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;
+}
+
--- /dev/null
+/*
+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__ */
--- /dev/null
+/*
+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);
+}
--- /dev/null
+/*
+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__ */
--- /dev/null
+/*
+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;
+}
--- /dev/null
+/*
+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__ */
--- /dev/null
+/*
+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;
+}
--- /dev/null
+/*
+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__ */
--- /dev/null
+/*
+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;
+}
--- /dev/null
+/*
+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