summaryrefslogtreecommitdiff
path: root/xc/lib/GL/mesa/src/drv
diff options
context:
space:
mode:
Diffstat (limited to 'xc/lib/GL/mesa/src/drv')
-rw-r--r--xc/lib/GL/mesa/src/drv/Imakefile4
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/Imakefile325
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_cce.c389
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_cce.h142
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h224
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_clear.c248
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_clear.h47
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_context.c203
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_context.h219
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_dd.c182
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_dd.h44
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c551
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h48
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h155
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_init.h92
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_lock.h134
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_mesa.h43
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c126
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h43
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_screen.c258
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_screen.h129
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_span.c329
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_span.h44
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_state.c1309
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_state.h50
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_swap.c125
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_swap.h43
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tex.c1852
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tex.h82
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_texobj.h87
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tris.c548
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tris.h76
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h327
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_vb.c470
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_vb.h150
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c257
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h44
37 files changed, 9399 insertions, 0 deletions
diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile
index 306bf16dc..ed30e7196 100644
--- a/xc/lib/GL/mesa/src/drv/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/Imakefile
@@ -22,6 +22,9 @@ DRIVER += common mga
#if GlxBuiltInI810
DRIVER += common i810
#endif
+#if GlxBuiltInR128
+DRIVER += r128
+#endif
SUBDIRS = $(DRIVER)
#else
@@ -32,6 +35,7 @@ SUBDIRS += tdfx
SUBDIRS += common
SUBDIRS += mga
SUBDIRS += i810
+SUBDIRS += r128
#endif
MakeSubdirs($(SUBDIRS))
diff --git a/xc/lib/GL/mesa/src/drv/r128/Imakefile b/xc/lib/GL/mesa/src/drv/r128/Imakefile
new file mode 100644
index 000000000..dd9d92305
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/Imakefile
@@ -0,0 +1,325 @@
+XCOMM $XFree86$
+
+#include <Threads.tmpl>
+
+#define DoNormalLib NormalLibGlx
+#define DoSharedLib SharedLibGlx
+#define DoExtraLib SharedLibGlx
+#define DoDebugLib DebugLibGlx
+#define DoProfileLib ProfileLibGlx
+
+#if Malloc0ReturnsNull
+ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
+#endif
+
+#if BuildXF86DRI
+ DRI_DEFINES = GlxDefines -DDRIVERTS
+ DRI_INCLUDES = -I../../../../dri \
+ -I../../../../glx \
+ -I../../../dri \
+ -I$(TOP)/include \
+ -I$(TOP)/include/GL \
+ -I$(XF86OSSRC) \
+ -I$(XF86COMSRC) \
+ -I$(SERVERSRC)/GL/dri \
+ -I$(XF86DRIVERSRC)/r128 \
+ -I../../../include \
+ -I../.. \
+ -I../../X \
+ -I../common
+#endif
+
+LinkSourceFile(mm.c, ../common)
+LinkSourceFile(mm.h, ../common)
+LinkSourceFile(hwlog.c, ../common)
+LinkSourceFile(hwlog.h, ../common)
+
+MESA_INCLUDES = -I. -I.. -I../../include
+
+ DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES)
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
+
+ R128SRCS = r128_cce.c \
+ r128_clear.c \
+ r128_context.c \
+ r128_dd.c \
+ r128_fastpath.c \
+ r128_pipeline.c \
+ r128_screen.c \
+ r128_span.c \
+ r128_state.c \
+ r128_swap.c \
+ r128_tex.c \
+ r128_tris.c \
+ r128_vb.c \
+ r128_xmesa.c
+
+ R128OBJS = r128_cce.o \
+ r128_clear.o \
+ r128_context.o \
+ r128_dd.o \
+ r128_fastpath.o \
+ r128_pipeline.o \
+ r128_screen.o \
+ r128_span.o \
+ r128_state.o \
+ r128_swap.o \
+ r128_tex.o \
+ r128_tris.o \
+ r128_vb.o \
+ r128_xmesa.o
+
+#if !GlxUseBuiltInDRIDriver
+ DRISRCS = ../../../dri/dri_mesa.c \
+ ../../../../dri/dri_tmm.c
+
+ DRIOBJS = ../../../dri/dri_mesa.o \
+ ../../../../dri/dri_tmm.o
+
+ DRMSRCS = ../../../../dri/drm/xf86drm.c \
+ ../../../../dri/drm/xf86drmHash.c \
+ ../../../../dri/drm/xf86drmRandom.c \
+ ../../../../dri/drm/xf86drmSL.c \
+ ../../../../dri/drm/xf86drmR128.c
+
+ DRMOBJS = ../../../../dri/drm/xf86drm.o \
+ ../../../../dri/drm/xf86drmHash.o \
+ ../../../../dri/drm/xf86drmRandom.o \
+ ../../../../dri/drm/xf86drmSL.o \
+ ../../../../dri/drm/xf86drmR128.o
+
+ MESASRCS = ../../aatriangle.c \
+ ../../accum.c \
+ ../../alpha.c \
+ ../../alphabuf.c \
+ ../../attrib.c \
+ ../../bbox.c \
+ ../../bitmap.c \
+ ../../blend.c \
+ ../../buffers.c \
+ ../../clip.c \
+ ../../colortab.c \
+ ../../config.c \
+ ../../context.c \
+ ../../copypix.c \
+ ../../cva.c \
+ ../../debug_xform.c \
+ ../../depth.c \
+ ../../dlist.c \
+ ../../drawpix.c \
+ ../../enable.c \
+ ../../enums.c \
+ ../../eval.c \
+ ../../extensions.c \
+ ../../feedback.c \
+ ../../fog.c \
+ ../../get.c \
+ ../../glapi.c \
+ ../../glapinoop.c \
+ ../../glthread.c \
+ ../../hash.c \
+ ../../image.c \
+ ../../imaging.c \
+ ../../light.c \
+ ../../lines.c \
+ ../../logic.c \
+ ../../masking.c \
+ ../../matrix.c \
+ ../../mem.c \
+ ../../mmath.c \
+ ../../pb.c \
+ ../../pipeline.c \
+ ../../pixel.c \
+ ../../pixeltex.c \
+ ../../points.c \
+ ../../polygon.c \
+ ../../quads.c \
+ ../../rastpos.c \
+ ../../readpix.c \
+ ../../rect.c \
+ ../../scissor.c \
+ ../../shade.c \
+ ../../span.c \
+ ../../stages.c \
+ ../../state.c \
+ ../../stencil.c \
+ ../../teximage.c \
+ ../../texobj.c \
+ ../../texstate.c \
+ ../../texture.c \
+ ../../texutil.c \
+ ../../translate.c \
+ ../../triangle.c \
+ ../../varray.c \
+ ../../vb.c \
+ ../../vbcull.c \
+ ../../vbfill.c \
+ ../../vbindirect.c \
+ ../../vbrender.c \
+ ../../vbxform.c \
+ ../../vector.c \
+ ../../vertices.c \
+ ../../winpos.c \
+ ../../xform.c \
+ ../../zoom.c \
+ ../../X86/common_x86.c
+
+ MESAOBJS = ../../aatriangle.o \
+ ../../accum.o \
+ ../../alpha.o \
+ ../../alphabuf.o \
+ ../../attrib.o \
+ ../../bbox.o \
+ ../../bitmap.o \
+ ../../blend.o \
+ ../../buffers.o \
+ ../../clip.o \
+ ../../colortab.o \
+ ../../config.o \
+ ../../context.o \
+ ../../copypix.o \
+ ../../cva.o \
+ ../../debug_xform.o \
+ ../../depth.o \
+ ../../dlist.o \
+ ../../drawpix.o \
+ ../../enable.o \
+ ../../enums.o \
+ ../../eval.o \
+ ../../extensions.o \
+ ../../feedback.o \
+ ../../fog.o \
+ ../../get.o \
+ ../../hash.o \
+ ../../hint.o \
+ ../../image.o \
+ ../../imaging.o \
+ ../../light.o \
+ ../../lines.o \
+ ../../logic.o \
+ ../../masking.o \
+ ../../matrix.o \
+ ../../mem.o \
+ ../../mmath.o \
+ ../../pb.o \
+ ../../pipeline.o \
+ ../../pixel.o \
+ ../../pixeltex.o \
+ ../../points.o \
+ ../../polygon.o \
+ ../../quads.o \
+ ../../rastpos.o \
+ ../../readpix.o \
+ ../../rect.o \
+ ../../scissor.o \
+ ../../shade.o \
+ ../../span.o \
+ ../../stages.o \
+ ../../state.o \
+ ../../stencil.o \
+ ../../teximage.o \
+ ../../texobj.o \
+ ../../texstate.o \
+ ../../texture.o \
+ ../../texutil.o \
+ ../../translate.o \
+ ../../triangle.o \
+ ../../varray.o \
+ ../../vb.o \
+ ../../vbcull.o \
+ ../../vbfill.o \
+ ../../vbindirect.o \
+ ../../vbrender.o \
+ ../../vbxform.o \
+ ../../vector.o \
+ ../../vertices.o \
+ ../../winpos.o \
+ ../../xform.o \
+ ../../zoom.o
+
+#ifdef i386Architecture
+ X86_SRCS = ../../X86/x86.c \
+ ../../X86/x86a.S \
+ ../../X86/common_x86.c \
+ ../../X86/common_x86asm.S \
+ ../../X86/vertex.S
+
+ X86_OBJS = ../../X86/x86.o \
+ ../../X86/x86a.o \
+ ../../X86/common_x86.o \
+ ../../X86/common_x86asm.o \
+ ../../X86/vertex.o
+
+ MMX_SRCS = ../../X86/mmx_blend.S
+
+ MMX_OBJS = ../../X86/mmx_blend.o
+
+XCOMM Disabling 3Dnow code for the time being.
+#if 0
+ 3DNOW_SRCS = ../../X86/3dnow.c \
+ ../../X86/3dnow_norm_raw.S \
+ ../../X86/3dnow_xform_masked1.S \
+ ../../X86/3dnow_xform_masked2.S \
+ ../../X86/3dnow_xform_masked3.S \
+ ../../X86/3dnow_xform_masked4.S \
+ ../../X86/3dnow_xform_raw1.S \
+ ../../X86/3dnow_xform_raw2.S \
+ ../../X86/3dnow_xform_raw3.S \
+ ../../X86/3dnow_xform_raw4.S \
+ ../../X86/vertex_3dnow.S
+
+ 3DNOW_OBJS = ../../X86/3dnow.o \
+ ../../X86/3dnow_norm_raw.o \
+ ../../X86/3dnow_xform_masked1.o \
+ ../../X86/3dnow_xform_masked2.o \
+ ../../X86/3dnow_xform_masked3.o \
+ ../../X86/3dnow_xform_masked4.o \
+ ../../X86/3dnow_xform_raw1.o \
+ ../../X86/3dnow_xform_raw2.o \
+ ../../X86/3dnow_xform_raw3.o \
+ ../../X86/3dnow_xform_raw4.o \
+ ../../X86/vertex_3dnow.o
+#endif
+
+#endif
+#endif
+
+ ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS)
+ ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS)
+
+ COMMONSRCS = mm.c hwlog.c
+ COMMONOBJS = mm.o hwlog.o
+
+ SRCS = $(DRISRCS) $(DRMSRCS) $(MESASRCS) $(ASMSRCS) \
+ $(COMMONSRCS) $(R128SRCS)
+ OBJS = $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) $(ASMOBJS) \
+ $(COMMONOBJS) $(R128OBJS)
+
+REQUIREDLIBS += -lm
+#if !GlxBuiltInMga
+REQUIREDLIBS += -L../../../.. -lGL
+#endif
+
+#if !GlxUseBuiltInDRIDriver
+#undef DoNormalLib NormalLibGlx
+#undef DoExtraLib SharedLibGlx
+#undef DoDebugLib DebugLibGlx
+#undef DoProfileLib ProfileLibGlx
+#endif
+
+#include <Library.tmpl>
+
+LibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+NormalLintTarget($(SRCS))
+
+#if !GlxUseBuiltInDRIDriver
+LIBNAME = r128_dri.so
+ALL_OBJS = $(OBJS)
+ALL_DEPS = DONE
+SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
+InstallDynamicModule($(LIBNAME),$(MODULEDIR)/dri,.)
+#endif
+
+DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_cce.c b/xc/lib/GL/mesa/src/drv/r128/r128_cce.c
new file mode 100644
index 000000000..e949dd37c
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_cce.c
@@ -0,0 +1,389 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+
+#if USE_USER_SPACE_RING
+
+#define USE_IOCTLS 0
+#define DO_SECURITY_CHECK 1
+#define R128_TIMEOUT 2000000
+
+#if DEBUG
+static void r128RingStatus(r128ScreenPtr pScrn)
+{
+ unsigned char *R128MMIO = pScrn->mmio;
+
+ R128_DEBUG(("GUI_STAT = 0x%08x\n",
+ (unsigned int)INREG(R128_GUI_STAT)));
+ R128_DEBUG(("PM4_STAT = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_STAT)));
+ R128_DEBUG(("PM4_BUFFER_DL_WPTR = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_BUFFER_DL_WPTR)));
+ R128_DEBUG(("PM4_BUFFER_DL_RPTR = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_BUFFER_DL_RPTR)));
+ R128_DEBUG(("ringWrite = 0x%08x\n", pScrn->SAREA->ringWrite));
+ R128_DEBUG(("*ringReadPtr = 0x%08x\n", *pScrn->ringReadPtr));
+}
+#endif
+
+/* FIXME: Requires access to secure registers */
+static int INPLL(r128ScreenPtr pScrn, int addr)
+{
+ unsigned char *R128MMIO = pScrn->mmio;
+
+ OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f);
+ return INREG(R128_CLOCK_CNTL_DATA);
+}
+
+/* FIXME: Requires access to secure registers */
+static void r128EngineFlush(r128ScreenPtr pScrn)
+{
+ unsigned char *R128MMIO = pScrn->mmio;
+ int i;
+
+ OUTREGP(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, ~R128_PC_FLUSH_ALL);
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ if (!(INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) break;
+ }
+}
+
+/* FIXME: Requires access to secure registers */
+static void r128EngineReset(r128ScreenPtr pScrn)
+{
+#if USE_IOCTLS
+#if DEBUG
+ r128RingStatus(pScrn);
+#endif
+
+ (void)drmR128EngineReset(pScrn->driScreen->fd);
+#else
+ unsigned char *R128MMIO = pScrn->mmio;
+ CARD32 clock_cntl_index;
+ CARD32 mclk_cntl;
+ CARD32 gen_reset_cntl;
+
+#if DEBUG
+ r128RingStatus(pScrn);
+#endif
+
+ r128EngineFlush(pScrn);
+
+ clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);
+ mclk_cntl = INPLL(pScrn, R128_MCLK_CNTL);
+
+ OUTPLL(R128_MCLK_CNTL, mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CPP);
+
+ gen_reset_cntl = INREG(R128_GEN_RESET_CNTL);
+
+ OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);
+ INREG(R128_GEN_RESET_CNTL);
+ OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI);
+ INREG(R128_GEN_RESET_CNTL);
+
+ OUTPLL(R128_MCLK_CNTL, mclk_cntl);
+ OUTREG(R128_CLOCK_CNTL_INDEX, clock_cntl_index);
+ OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl);
+
+ /* Reset the ring buffer status */
+ if (R128CCE_USE_RING_BUFFER(pScrn->CCEMode)) {
+ OUTREG(R128_PM4_BUFFER_DL_WPTR, 0);
+ OUTREG(R128_PM4_BUFFER_DL_RPTR, 0);
+ pScrn->SAREA->ringWrite = 0;
+ *pScrn->ringReadPtr = 0;
+ }
+#endif
+ fprintf(stderr, "Error: Rage 128 timed out... exiting\n");
+ exit(-1);
+}
+
+#define r128CCEWaitForFifo(pScrn, entries) \
+do { \
+ if (pScrn->CCEFifoSlots < entries) \
+ r128CCEWaitForFifoFunction(pScrn, entries); \
+ pScrn->CCEFifoSlots -= entries; \
+} while (0)
+
+/* Wait for at least `entries' slots are free. The actual number of
+ slots available is stored in info->CCEFifoSize. */
+static void r128CCEWaitForFifoFunction(r128ScreenPtr pScrn, int entries)
+{
+ unsigned char *R128MMIO = pScrn->mmio;
+ int i;
+
+ for (;;) {
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ pScrn->CCEFifoSlots = INREG(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK;
+ if (pScrn->CCEFifoSlots >= entries) return;
+ }
+ R128_DEBUG(("Reseting Engine: PM4_STAT = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_STAT)));
+ r128EngineReset(pScrn);
+ }
+}
+
+/* Wait until the CCE is completely idle: the FIFO has drained and the
+ CCE is idle. */
+void r128CCEWaitForIdle(r128ScreenPtr pScrn)
+{
+#if USE_IOCTLS
+ if (drmR128WaitForIdle(pScrn->driScreen->fd) < 0) {
+ fprintf(stderr, "Error: Rage 128 timed out... exiting\n");
+ exit(-1);
+ }
+#else
+ unsigned char *R128MMIO = pScrn->mmio;
+ int i;
+
+ if (R128CCE_USE_RING_BUFFER(pScrn->CCEMode)) {
+ OUTREGP(R128_PM4_BUFFER_DL_WPTR,
+ R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE);
+
+ for (;;) {
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ if (*pScrn->ringReadPtr == pScrn->SAREA->ringWrite) {
+ int pm4stat = INREG(R128_PM4_STAT);
+ if ((pm4stat & R128_PM4_FIFOCNT_MASK) == pScrn->CCEFifoSize
+ && !(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE)))
+ return;
+ }
+ }
+ R128_DEBUG(("Reseting Engine: PM4_STAT = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_STAT)));
+ r128EngineReset(pScrn);
+ }
+ } else {
+ r128CCEWaitForFifoFunction(pScrn, pScrn->CCEFifoSize);
+
+ for (;;) {
+ for (i = 0; i < R128_TIMEOUT; i++) {
+ if (!(INREG(R128_PM4_STAT)
+ & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) {
+ r128EngineFlush(pScrn);
+ return;
+ }
+ }
+ R128_DEBUG(("Reseting Engine: PM4_STAT = 0x%08x\n",
+ (unsigned int)INREG(R128_PM4_STAT)));
+ r128EngineReset(pScrn);
+ }
+ }
+#endif
+}
+
+/* Send a packet to the CCE via the PIO registers */
+static void r128CCESubmitPacketPIO(r128ContextPtr r128ctx,
+ CARD32 *buf, int count)
+{
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+#if DO_SECURITY_CHECK
+ CARD32 tmp = 0;
+ int psize = 0;
+ int writing = 1;
+ int addr = R128_PM4_FIFO_DATA_EVEN;
+#endif
+
+#if DO_SECURITY_CHECK
+ while (count > 0) {
+ tmp = *buf++;
+ if (!psize) {
+ writing = 1;
+
+ if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ }
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <=
+ (0x1004 << 9)) {
+ if ((tmp & R128_CCE_PACKET1_REG1_MASK) !=
+ (R128_PM4_VC_FPU_SETUP << 9)) {
+ writing = 0;
+ }
+ }
+ psize = 3;
+ } else {
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ }
+ }
+ psize--;
+
+ if (writing) {
+ r128CCEWaitForFifo(r128ctx->r128Screen, 1);
+ OUTREG(addr, tmp);
+ addr ^= 0x0004;
+ }
+
+ count--;
+ }
+
+ if (addr == R128_PM4_FIFO_DATA_ODD) {
+ r128CCEWaitForFifo(r128ctx->r128Screen, 1);
+ OUTREG(addr, R128_CCE_PACKET2);
+ }
+#else
+ while (count > 1) {
+ r128CCEWaitForFifo(r128ctx->r128Screen, 2);
+ OUTREG(R128_PM4_FIFO_DATA_EVEN, *buf++);
+ OUTREG(R128_PM4_FIFO_DATA_ODD, *buf++);
+ count -= 2;
+ }
+
+ if (count) {
+ r128CCEWaitForFifo(r128ctx->r128Screen, 2);
+ OUTREG(R128_PM4_FIFO_DATA_EVEN, *buf);
+ OUTREG(R128_PM4_FIFO_DATA_ODD, R128_CCE_PACKET2);
+ }
+#endif
+}
+
+/* Send a packet to the CCE via the ring */
+static void r128CCESubmitPacketRing(r128ContextPtr r128ctx,
+ CARD32 *buf, int count)
+{
+ r128ScreenPtr r128scrn = r128ctx->r128Screen;
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+ int ringWrite = r128scrn->SAREA->ringWrite;
+ int *ringWritePtr = r128scrn->ringStartPtr + ringWrite;
+ int timeout;
+#if DO_SECURITY_CHECK
+ CARD32 tmp = 0;
+ int psize = 0;
+ int writing = 1;
+#endif
+
+ if (count > r128scrn->ringEntries) {
+ /* FIXME */
+ return;
+ }
+
+ while (count > 0) {
+#if DO_SECURITY_CHECK
+ tmp = *buf++;
+ if (!psize) {
+ writing = 1;
+
+ if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET0_REG_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ }
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) {
+ if ((tmp & R128_CCE_PACKET1_REG0_MASK) !=
+ (R128_PM4_VC_FPU_SETUP >> 2)) {
+ writing = 0;
+ }
+ } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <=
+ (0x1004 << 9)) {
+ if ((tmp & R128_CCE_PACKET1_REG1_MASK) !=
+ (R128_PM4_VC_FPU_SETUP << 9)) {
+ writing = 0;
+ }
+ }
+ psize = 3;
+ } else {
+ psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
+ }
+ }
+ psize--;
+
+ if (writing) {
+ ringWrite++;
+ *ringWritePtr++ = tmp;
+ }
+#else
+ ringWrite++;
+ *ringWritePtr++ = *buf++;
+#endif
+ if (ringWrite >= r128scrn->ringEntries) {
+ ringWrite = 0;
+ ringWritePtr = r128scrn->ringStartPtr;
+ }
+ timeout = 0;
+ while (ringWrite == *r128scrn->ringReadPtr) {
+ (void)INREG(R128_PM4_BUFFER_DL_RPTR);
+ if (timeout++ >= R128_TIMEOUT) r128EngineReset(r128scrn);
+ }
+
+ count--;
+ }
+
+ if (ringWrite < 32) {
+ memcpy(r128scrn->ringEndPtr,
+ r128scrn->ringStartPtr,
+ ringWrite * sizeof(int));
+ }
+
+ r128scrn->SAREA->ringWrite = ringWrite;
+ OUTREG(R128_PM4_BUFFER_DL_WPTR, ringWrite);
+}
+
+void r128CCESubmitPackets(r128ContextPtr r128ctx, CARD32 *buf, int count)
+{
+#if USE_IOCTLS
+ if (drmR128SubmitPackets(r128ctx->r128Screen->driScreen->fd,
+ r128ctx->CCEbuf, r128ctx->CCEcount,
+ 0) < 0) {
+ r128EngineReset(r128ctx->r128Screen);
+ fprintf(stderr, "Error: Illegal CCE packet... exiting\n");
+ exit(-1);
+ }
+#else
+ if (R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode))
+ r128CCESubmitPacketRing(r128ctx, buf, count);
+ else
+ r128CCESubmitPacketPIO(r128ctx, buf, count);
+#endif
+}
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_cce.h b/xc/lib/GL/mesa/src/drv/r128/r128_cce.h
new file mode 100644
index 000000000..162686cb7
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_cce.h
@@ -0,0 +1,142 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_CCE_H_
+#define _R128_CCE_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r128_dri.h"
+#include "r128_reg.h"
+
+#include "xf86drmR128.h"
+
+typedef union {
+ float f;
+ int i;
+} floatTOint;
+
+#define R128_DEFAULT_TOTAL_CCE_TIMEOUT 1000000 /* usecs */
+
+/* Insert an integer value into the CCE ring buffer. */
+#define R128CCE(v) \
+ do { \
+ r128ctx->CCEbuf[r128ctx->CCEcount] = (v); \
+ r128ctx->CCEcount++; \
+ } while (0)
+
+/* Insert an floating point value into the CCE ring buffer. */
+#define R128CCEF(v) \
+ do { \
+ floatTOint fTi; \
+ fTi.f = (v); \
+ r128ctx->CCEbuf[r128ctx->CCEcount] = fTi.i; \
+ r128ctx->CCEcount++; \
+ } while (0)
+
+#if USE_USER_SPACE_RING
+
+#define R128CCE_SUBMIT_PACKETS() \
+ do { \
+ r128CCESubmitPackets(r128ctx, r128ctx->CCEbuf, r128ctx->CCEcount); \
+ r128ctx->CCEcount = 0; \
+ } while (0)
+
+#define R128CCE_WAIT_FOR_IDLE(r128ctx) \
+ r128CCEWaitForIdle(r128ctx->r128Screen)
+
+#else /* if !USE_USER_SPACE_RING */
+
+#define R128CCE_SUBMIT_PACKETS() \
+ do { \
+ CARD32 *_buf; \
+ int _c = r128ctx->CCEcount; \
+ int _fd = r128ctx->r128Screen->driScreen->fd; \
+ int _to = 0; \
+ int _ret; \
+ \
+ do { \
+ _buf = r128ctx->CCEbuf + (r128ctx->CCEcount - _c); \
+ _ret = drmR128SubmitPackets(_fd, _buf, &_c, 0); \
+ } while (_ret < 0 && _ret == -EBUSY && _to++ < r128ctx->CCEtimeout); \
+ if (_ret < 0) { \
+ (void)drmR128EngineReset(_fd); \
+ fprintf(stderr, "Error: Could not submit packet... exiting\n"); \
+ exit(-1); \
+ } \
+ r128ctx->CCEcount = 0; \
+ } while (0)
+
+#define R128CCE_WAIT_FOR_IDLE(r128ctx) \
+ do { \
+ int _fd = r128ctx->r128Screen->driScreen->fd; \
+ int _to = 0; \
+ int _ret; \
+ \
+ (void)drmR128EngineFlush(_fd); \
+ do { \
+ _ret = drmR128CCEWaitForIdle(_fd); \
+ } while (_ret < 0 && _ret == -EBUSY && _to++ < r128ctx->CCEtimeout); \
+ if (_ret < 0) { \
+ (void)drmR128EngineReset(_fd); \
+ fprintf(stderr, "Error: Rage 128 timed out... exiting\n"); \
+ exit(-1); \
+ } \
+ } while (0)
+
+#endif
+
+#define R128CCE_WAIT_FOR_IDLE_LOCK(r128ctx) \
+ do { \
+ LOCK_HARDWARE(r128ctx); \
+ R128CCE_WAIT_FOR_IDLE(r128ctx); \
+ UNLOCK_HARDWARE(r128ctx); \
+ } while (0)
+
+
+/* Insert a type-[0123] packet header into the ring buffer */
+#define R128CCE0(p,r,n) R128CCE((p) | ((n) << 16) | ((r) >> 2))
+#define R128CCE1(p,r1,r2) R128CCE((p) | (((r2) >> 2) << 11) | ((r1) >> 2))
+#define R128CCE2(p) R128CCE((p))
+#define R128CCE3(p,n) R128CCE((p) | ((n) << 16))
+
+
+#if USE_USER_SPACE_RING
+extern void r128CCEWaitForIdle(r128ScreenPtr pScrn);
+extern void r128CCESubmitPackets(r128ContextPtr r128ctx,
+ CARD32 *buf, int count);
+#endif
+
+#endif
+#endif /* _R128_CCE_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h b/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h
new file mode 100644
index 000000000..2084b8672
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h
@@ -0,0 +1,224 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_CCEVB_H_
+#define _R128_CCEVB_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "xf86drmR128.h"
+
+typedef struct {
+ CARD32 *buf; /* Pointer to current VB */
+ int index; /* Index of current VB */
+ int start; /* in bytes from the beginning of the VB map */
+ int size; /* in vertices */
+ int count; /* in vertices */
+ drmR128PrimType prim; /* Primitive type for vertices in VB */
+ int done; /* VB has been sent to ring */
+} r128CCEVertBuf, *r128CCEVertBufPtr;
+
+
+
+/* Flush the CPU's write-combining cache */
+/* FIXME: This code is both processor and compiler specific */
+#define R128_FLUSH_WC_MEMORY() \
+ do { \
+ int xchangeDummy; \
+ \
+ __asm__ volatile("push %%eax ;" \
+ "xchg %%eax, %0 ;" \
+ "pop %%eax" : : "m" (xchangeDummy)); \
+ __asm__ volatile("push %%eax ;" \
+ "push %%ebx ;" \
+ "push %%ecx ;" \
+ "push %%edx ;" \
+ "movl $0,%%eax ;" \
+ "cpuid ;" \
+ "pop %%edx ;" \
+ "pop %%ecx ;" \
+ "pop %%ebx ;" \
+ "pop %%eax" : /* no outputs */ : /* no inputs */); \
+ } while (0)
+
+
+/* Get a new VB from the pool of vertex buffers in AGP space */
+/* NOTE: By default the primitive type for a VB is set to individual tris */
+#define R128CCE_GET_NEW_VB(r128ctx) \
+ do { \
+ r128CCEVertBufPtr vb = &r128ctx->vb; \
+ int to = 0; \
+ int fd = r128ctx->r128Screen->driScreen->fd; \
+ int num; \
+ int index; \
+ int size; \
+ \
+ vb->buf = NULL; \
+ \
+ LOCK_HARDWARE(r128ctx); \
+ while (!vb->buf && to++ < r128ctx->CCEtimeout) { \
+ /* Ask the kernel a new vertex buffer */ \
+ num = drmR128GetVertexBuffers(fd, 1, &index, &size); \
+ \
+ if (num > 0) { \
+ vb->buf = (CARD32 *)(r128ctx->r128Screen-> \
+ vbBufs->list[index].address); \
+ vb->index = index; \
+ vb->start = index*r128ctx->r128Screen->vbBufSize; \
+ vb->size = size/sizeof(r128_vertex); \
+ vb->count = 0; \
+ vb->prim = DRM_R128_PRIM_TRI_LIST; \
+ vb->done = GL_FALSE; \
+ } \
+ } \
+ UNLOCK_HARDWARE(r128ctx); \
+ \
+ if (!vb->buf) { \
+ (void)drmR128EngineReset(fd); \
+ fprintf(stderr, "Error: Could not get new VB... exiting\n"); \
+ exit(-1); \
+ } \
+ } while (0)
+
+/* Submit a VB to the hardware for processing */
+/* NOTE: This macro is only called while holding the hardware lock */
+#define R128CCE_SUBMIT_VB(r128ctx) \
+ do { \
+ int index = r128ctx->vb.index; \
+ int size = r128ctx->vb.count; \
+ int fd = r128ctx->r128Screen->driScreen->fd; \
+ int to = 0; \
+ int ret; \
+ CARD32 prim; \
+ \
+ switch (r128ctx->vb.prim) { \
+ case DRM_R128_PRIM_NONE: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_NONE; \
+ break; \
+ case DRM_R128_PRIM_POINT: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_POINT; \
+ break; \
+ case DRM_R128_PRIM_LINE: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_LINE; \
+ break; \
+ case DRM_R128_PRIM_POLY_LINE: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE; \
+ break; \
+ case DRM_R128_PRIM_TRI_LIST: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST; \
+ break; \
+ case DRM_R128_PRIM_TRI_FAN: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN; \
+ break; \
+ case DRM_R128_PRIM_TRI_STRIP: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP; \
+ break; \
+ case DRM_R128_PRIM_TRI_TYPE2: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2; \
+ break; \
+ default: \
+ prim = R128_CCE_VC_CNTL_PRIM_TYPE_NONE; \
+ break; \
+ } \
+ \
+ /* Send the vertex buffer to the hardware */ \
+ BEGIN_CLIP_LOOP(r128ctx); \
+ \
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3); \
+ R128CCE(r128ctx->r128Screen->vbOffset + r128ctx->vb.start); \
+ R128CCE(r128ctx->vb.count); \
+ R128CCE(R128_FULL_VERTEX_FORMAT); \
+ R128CCE(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | \
+ (r128ctx->vb.count << R128_CCE_VC_CNTL_NUM_SHIFT)); \
+ R128CCE_SUBMIT_PACKETS(); \
+ \
+ END_CLIP_LOOP(r128ctx); \
+ \
+ /* Tell the kernel to release the vertex buffer */ \
+ do { \
+ ret = drmR128FlushVertexBuffers(fd, 1, &index, &size, \
+ r128ctx->vb.prim); \
+ } while (ret < 0 && ret == -EBUSY && to++ < r128ctx->CCEtimeout); \
+ if (ret < 0) { \
+ (void)drmR128EngineReset(fd); \
+ fprintf(stderr, "Error: Could not flush VB... exiting\n"); \
+ exit(-1); \
+ } \
+ \
+ r128ctx->vb.done = GL_TRUE; \
+ } while (0)
+
+/* Flush the vertex buffer (assuming we already hold the lock) */
+#define R128CCE_FLUSH_VB(r128ctx) \
+ do { \
+ if (r128ctx->vb.count && !r128ctx->vb.done) { \
+ /* FIXME: Is this _really_ needed? */ \
+ if (!R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode)) \
+ R128CCE_WAIT_FOR_IDLE(r128ctx); \
+ \
+ R128CCE_SUBMIT_VB(r128ctx); \
+ } \
+ } while (0)
+
+/* Flush the vertex buffer */
+#define R128CCE_FLUSH_VB_LOCK(r128ctx) \
+ do { \
+ LOCK_HARDWARE(r128ctx); \
+ R128CCE_FLUSH_VB(r128ctx); \
+ UNLOCK_HARDWARE(r128ctx); \
+ } while (0)
+
+/* Reserve space in a VB to store `n' vertices, and set the pointer `p'
+ to point to the next vertex in the current VB. If adding these
+ vertices to the VB would exceed the size of the VB, then flush the
+ current VB, get a new one from the pool of VBs, reserve space in the
+ new VB for the `n' vertices, and set the pointer `p' to point to the
+ first vertex in the new VB. */
+#define R128CCE_ALLOC_VB_SPACE(r128ctx, p, n) \
+ do { \
+ r128CCEVertBufPtr vb = &r128ctx->vb; \
+ \
+ if (vb->done) R128CCE_GET_NEW_VB(r128ctx); \
+ \
+ if (vb->count + (n) > vb->size) { \
+ R128CCE_FLUSH_VB_LOCK(r128ctx); \
+ R128CCE_GET_NEW_VB(r128ctx); \
+ } \
+ \
+ (p) = (r128_vertex *)vb->buf + vb->count; \
+ vb->count += (n); \
+ } while (0)
+
+#endif
+#endif /* _R128_CCEVB_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_clear.c b/xc/lib/GL/mesa/src/drv/r128/r128_clear.c
new file mode 100644
index 000000000..9ab0581b0
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_clear.c
@@ -0,0 +1,248 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_state.h"
+#include "r128_vb.h"
+#include "r128_clear.h"
+
+/* Clear the depth buffer */
+void r128ClearDepthBuffer(r128ContextPtr r128ctx, GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch)
+{
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable;
+ int nc;
+ XF86DRIClipRectPtr c;
+ int dst_bpp;
+ CARD32 write_mask;
+
+ if (!(r128ctx->regs.tex_cntl_c & R128_Z_WRITE_ENABLE)) return;
+
+ switch (r128ctx->regs.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK) {
+ case R128_Z_PIX_WIDTH_16:
+ write_mask = 0x0000ffff;
+ dst_bpp = R128_GMC_DST_16BPP;
+ break;
+ case R128_Z_PIX_WIDTH_24:
+ write_mask = 0x00ffffff;
+ dst_bpp = R128_GMC_DST_32BPP;
+ break;
+ case R128_Z_PIX_WIDTH_32:
+ write_mask = 0xffffffff;
+ dst_bpp = R128_GMC_DST_32BPP;
+ break;
+ default: return;
+ }
+
+ cx += dPriv->x;
+ cy = dPriv->y + dPriv->h - cy - ch;
+
+ LOCK_HARDWARE(r128ctx);
+
+ /* Flush any outstanding vertex buffers */
+ R128CCE_FLUSH_VB(r128ctx);
+
+ /* Init the clip rects here in case they changed during the
+ LOCK_HARDWARE macro */
+ c = dPriv->pClipRects;
+ nc = dPriv->numClipRects;
+
+ /* Set the write mask so that we _only_ clear the Z buffer */
+ R128CCE0(R128_CCE_PACKET0, R128_DP_WRITE_MASK, 0);
+ R128CCE(write_mask);
+
+ /* Temporarily disable Z and stencil buffer and texture mapping modes */
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c & ~(R128_Z_ENABLE |
+ R128_STENCIL_ENABLE |
+ R128_TEXMAP_ENABLE));
+
+ /* Cycle through the clip rects */
+ while (nc--) {
+ int x = c[nc].x1;
+ int y = c[nc].y1;
+ int w = c[nc].x2 - x;
+ int h = c[nc].y2 - y;
+
+ if (!all) {
+ if (x < cx) w -= cx - x, x = cx;
+ if (y < cy) h -= cy - y, y = cy;
+
+ if (x + w > cx + cw) w = cx + cw - x;
+ if (y + h > cy + ch) h = cy + ch - y;
+
+ if (w <= 0 || h <= 0) continue;
+ }
+
+ x += r128ctx->r128Screen->depthX;
+ y += r128ctx->r128Screen->depthY;
+
+ R128CCE3(R128_CCE_PACKET3_CNTL_PAINT_MULTI, 3);
+ R128CCE(R128_GMC_BRUSH_SOLID_COLOR
+ | dst_bpp
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_ROP3_P
+ | R128_GMC_3D_FCN_EN /* FIXME?? */
+ | R128_GMC_CLR_CMP_CNTL_DIS /* FIXME?? */
+ | R128_AUX_CLIP_DIS /* FIXME?? */
+ | R128_GMC_WR_MSK_DIS); /* FIXME?? */
+ R128CCE(r128ctx->ClearDepth);
+ R128CCE((x << 16) | y);
+ R128CCE((w << 16) | h);
+ }
+
+#if 0
+ /* Set the write mask so that we _only_ clear the Z buffer */
+ R128CCE0(R128_CCE_PACKET0, R128_DP_WRITE_MASK, 0);
+ R128CCE(0xffffffff);
+
+ /* Restore Z and stencil buffer and texture mapping modes */
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c);
+#else
+ /* FIXME: We should be able to optimize this by restoring only the
+ registers that change (above) */
+ /* NOTE: The restore of TEX_CNTL_C and R128_DP_WRITE_MASK is handled by
+ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALL_DIRTY;
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+/* Clear a color buffer */
+void r128ClearColorBuffer(r128ContextPtr r128ctx, GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch,
+ GLint drawX, GLint drawY)
+{
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable;
+ int nc;
+ XF86DRIClipRectPtr c;
+ int dst_bpp;
+
+ switch (r128ctx->r128Screen->bpp) {
+ case 8:
+ dst_bpp = R128_GMC_DST_8BPP_CI;
+ break;
+ case 16:
+ if (r128ctx->r128Screen->depth == 15) dst_bpp = R128_GMC_DST_15BPP;
+ else dst_bpp = R128_GMC_DST_16BPP;
+ break;
+ case 24:
+ dst_bpp = R128_GMC_DST_24BPP;
+ break;
+ case 32:
+ default:
+ dst_bpp = R128_GMC_DST_32BPP;
+ break;
+ }
+
+ cx += dPriv->x;
+ cy = dPriv->y + dPriv->h - cy - ch;
+
+ LOCK_HARDWARE(r128ctx);
+
+ /* Flush any outstanding vertex buffers */
+ R128CCE_FLUSH_VB(r128ctx);
+
+ /* Init the clip rects here in case they changed during the
+ LOCK_HARDWARE macro */
+ c = dPriv->pClipRects;
+ nc = dPriv->numClipRects;
+
+ /* Temporarily disable Z and stencil buffer and texture mapping modes */
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c & ~(R128_Z_ENABLE |
+ R128_STENCIL_ENABLE |
+ R128_TEXMAP_ENABLE));
+
+ /* Cycle through the clip rects */
+ while (nc--) {
+ int x = c[nc].x1;
+ int y = c[nc].y1;
+ int w = c[nc].x2 - x;
+ int h = c[nc].y2 - y;
+
+ if (!all) {
+ if (x < cx) w -= cx - x, x = cx;
+ if (y < cy) h -= cy - y, y = cy;
+
+ if (x + w > cx + cw) w = cx + cw - x;
+ if (y + h > cy + ch) h = cy + ch - h;
+
+ if (w <= 0 || h <= 0) continue;
+ }
+
+ x += drawX;
+ y += drawY;
+
+ R128CCE3(R128_CCE_PACKET3_CNTL_PAINT_MULTI, 3);
+ R128CCE(R128_GMC_BRUSH_SOLID_COLOR
+ | dst_bpp
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_ROP3_P
+ | R128_GMC_3D_FCN_EN /* FIXME?? */
+ | R128_GMC_CLR_CMP_CNTL_DIS /* FIXME?? */
+ | R128_AUX_CLIP_DIS); /* FIXME?? */
+ R128CCE(r128ctx->ClearColor);
+ R128CCE((x << 16) | y);
+ R128CCE((w << 16) | h);
+ }
+
+#if 0
+ /* Restore Z and stencil buffer and texture mapping modes */
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c);
+#else
+ /* FIXME: We should be able to optimize this by restoring only the
+ registers that change (above) */
+ /* NOTE: The restore of TEX_CNTL_C is handled by
+ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALL_DIRTY;
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ UNLOCK_HARDWARE(r128ctx);
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_clear.h b/xc/lib/GL/mesa/src/drv/r128/r128_clear.h
new file mode 100644
index 000000000..7018b05b4
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_clear.h
@@ -0,0 +1,47 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_CLEAR_H_
+#define _R128_CLEAR_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128ClearDepthBuffer(r128ContextPtr r128ctx, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height);
+extern void r128ClearColorBuffer(r128ContextPtr r128ctx, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height,
+ GLint drawX, GLint drawY);
+
+#endif
+#endif /* _R128_CLEAR_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.c b/xc/lib/GL/mesa/src/drv/r128/r128_context.c
new file mode 100644
index 000000000..01573f559
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c
@@ -0,0 +1,203 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include <stdlib.h>
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_cce.h"
+#include "r128_dd.h"
+#include "r128_state.h"
+#include "r128_span.h"
+#include "r128_tex.h"
+#include "r128_vb.h"
+#include "r128_pipeline.h"
+
+#include "context.h"
+#include "simple_list.h"
+
+/* Create the device specific context */
+GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual,
+ __DRIcontextPrivate *driContextPriv)
+{
+ r128ContextPtr r128ctx;
+ r128ScreenPtr r128scrn;
+ GLcontext *glCtx = driContextPriv->mesaContext;
+ int i;
+ char *v;
+
+ r128ctx = (r128ContextPtr)Xmalloc(sizeof(*r128ctx));
+ if (!r128ctx) return GL_FALSE;
+
+ /* Initialize r128Context */
+ r128ctx->glCtx = glCtx;
+ r128ctx->display = dpy;
+ r128ctx->driContext = driContextPriv;
+ r128ctx->driDrawable = NULL; /* Set by XMesaMakeCurrent */
+
+ if (getenv("LIBGL_SOFTWARE_RENDERING"))
+ r128ctx->SWonly = GL_TRUE;
+ else
+ r128ctx->SWonly = GL_FALSE;
+ if (getenv("LIBGL_NO_SOFTWARE_FALLBACKS"))
+ r128ctx->SWfallbackDisable = GL_TRUE;
+ else
+ r128ctx->SWfallbackDisable = GL_FALSE;
+ r128scrn = r128ctx->r128Screen =
+ (r128ScreenPtr)(driContextPriv->driScreenPriv->private);
+
+ r128ctx->CurrentTexObj[0] = NULL;
+ r128ctx->CurrentTexObj[1] = NULL;
+ make_empty_list(&r128ctx->SwappedOut);
+ for (i = 0; i < r128scrn->NRTexHeaps; i++) {
+ make_empty_list(&r128ctx->TexObjList[i]);
+ r128ctx->texHeap[i] = mmInit(0, r128scrn->texSize[i]);
+ r128ctx->lastTexAge[i] = -1;
+ }
+
+ r128ctx->lastSwapAge = 0;
+
+ r128ctx->useFastPath = GL_FALSE;
+
+ r128ctx->vb.start = 0;
+ r128ctx->vb.count = 0;
+ r128ctx->vb.size = 0;
+ r128ctx->vb.index = 0;
+ r128ctx->vb.buf = NULL;
+ r128ctx->vb.done = GL_TRUE;
+
+ if (r128scrn->IsPCI || getenv("LIBGL_DISABLE_VERTEX_BUFFERS"))
+ r128ctx->disableVB = GL_TRUE;
+ else
+ r128ctx->disableVB = GL_FALSE;
+
+ r128ctx->CCEbuf = (CARD32 *)malloc(sizeof(*r128ctx->CCEbuf) *
+ r128scrn->ringEntries);
+ r128ctx->CCEcount = 0;
+
+ if ((v = getenv("LIBGL_CCE_TIMEOUT")))
+ r128ctx->CCEtimeout = strtoul(v, NULL, 10);
+ else
+ r128ctx->CCEtimeout = (R128_DEFAULT_TOTAL_CCE_TIMEOUT /
+ R128_DEFAULT_CCE_TIMEOUT);
+ if (r128ctx->CCEtimeout <= 0) r128ctx->CCEtimeout = 1;
+
+ /* Initialize GLcontext */
+ glCtx->DriverCtx = (void *)r128ctx;
+
+ r128DDInitExtensions(glCtx);
+
+ r128DDInitDriverFuncs(glCtx);
+ r128DDInitStateFuncs(glCtx);
+ r128DDInitSpanFuncs(glCtx);
+ r128DDInitTextureFuncs(glCtx);
+
+ glCtx->Driver.TriangleCaps = (DD_TRI_CULL
+ | DD_TRI_LIGHT_TWOSIDE
+ | DD_TRI_OFFSET);
+#if 0
+ /* FIXME */
+ glCtx->TriangleCaps |= DD_CLIP_FOG_COORD;
+#endif
+
+ /* Reset Mesa's current 2D texture pointers to the driver's textures */
+ glCtx->Shared->DefaultD[2][0].DriverData = NULL;
+ glCtx->Shared->DefaultD[2][1].DriverData = NULL;
+
+ /* If Mesa has current a vertex buffer, make sure the driver's VB
+ data is up to date */
+ if (glCtx->VB) r128DDRegisterVB(glCtx->VB);
+
+ /* Register the fast path */
+ if (glCtx->NrPipelineStages)
+ glCtx->NrPipelineStages =
+ r128RegisterPipelineStages(glCtx->PipelineStage,
+ glCtx->PipelineStage,
+ glCtx->NrPipelineStages);
+
+ r128DDInitState(r128ctx);
+
+ driContextPriv->driverPrivate = (void *)r128ctx;
+
+ return GL_TRUE;
+}
+
+/* Destroy the device specific context */
+void r128DestroyContext(r128ContextPtr r128ctx)
+{
+ if (r128ctx) {
+ r128TexObjPtr t, next_t;
+ int i;
+
+ free(r128ctx->CCEbuf);
+
+ for (i = 0; i < r128ctx->r128Screen->NRTexHeaps; i++) {
+ foreach_s (t, next_t, &r128ctx->TexObjList[i])
+ r128DestroyTexObj(r128ctx, t);
+ }
+
+ foreach_s (t, next_t, &r128ctx->SwappedOut)
+ r128DestroyTexObj(r128ctx, t);
+
+ gl_destroy_context(r128ctx->glCtx);
+ Xfree(r128ctx);
+ }
+}
+
+/* Load the device specific context into the hardware. The actual
+ setting of the hardware state is done in the r128UpdateHWState(). */
+r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx,
+ r128ContextPtr newCtx,
+ __DRIdrawablePrivate *dPriv)
+{
+ if (oldCtx) {
+ if (!R128CCE_USE_RING_BUFFER(newCtx->r128Screen->CCEMode))
+ newCtx->dirty |= R128_REQUIRE_QUIESCENCE;
+ if (oldCtx != newCtx) {
+ newCtx->dirty |= R128_UPDATE_CONTEXT;
+ newCtx->dirty_context |= R128_CTX_ALL_DIRTY;
+ }
+ if (oldCtx->driDrawable != dPriv)
+ newCtx->dirty |= R128_UPDATE_WINPOS;
+ } else {
+ newCtx->dirty |= R128_UPDATE_CONTEXT;
+ newCtx->dirty_context |= R128_CTX_ALL_DIRTY;
+ }
+
+ newCtx->driDrawable = dPriv;
+
+ return newCtx;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.h b/xc/lib/GL/mesa/src/drv/r128/r128_context.h
new file mode 100644
index 000000000..189a22cbe
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h
@@ -0,0 +1,219 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_CONTEXT_H_
+#define _R128_CONTEXT_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r128_texobj.h"
+#include "r128_fastpath.h"
+#include "r128_ccevb.h"
+
+/* Flags for what needs to be updated before a new primitive is rendered */
+#define R128_CLEAN 0x0000
+#define R128_REQUIRE_QUIESCENCE 0x0001
+#define R128_UPDATE_CONTEXT 0x0002
+#define R128_UPDATE_WINPOS 0x0004
+#define R128_UPDATE_TEX0IMAGES 0x0008
+#define R128_UPDATE_TEX1IMAGES 0x0010
+#define R128_UPDATE_TEXSTATE 0x0020
+#define R128_ALL_DIRTY 0xffff
+
+/* Flags for what context state needs to be updated */
+#define R128_CTX_CLEAN 0x0000
+#define R128_CTX_MISC 0x0001
+#define R128_CTX_ENGINESTATE 0x0002
+#define R128_CTX_TEX0STATE 0x0004
+#define R128_CTX_TEX1STATE 0x0008
+#define R128_CTX_TEXENVSTATE 0x0010
+#define R128_CTX_FOGSTATE 0x0020
+#define R128_CTX_FOGTABLE 0x0040
+#define R128_CTX_ZSTENSTATE 0x0080
+#define R128_CTX_SCISSORS 0x0100
+#define R128_CTX_ALPHASTATE 0x0200
+#define R128_CTX_SETUPSTATE 0x0400
+#define R128_CTX_WIN_Z_POS 0x0800
+#define R128_CTX_FLUSH_PIX_CACHE 0x1000
+#define R128_CTX_ALL_DIRTY 0xffff
+
+/* Flags for software fallback cases */
+#define R128_FALLBACK_TEXTURE 0x0001
+#define R128_FALLBACK_DRAW_BUFFER 0x0002
+#define R128_FALLBACK_READ_BUFFER 0x0004
+#define R128_FALLBACK_COLORMASK 0x0008
+#define R128_FALLBACK_STIPPLE 0x0010
+
+/* NOTE: The groups below need to be kept together so that a single
+ memcpy can be used to transfer data to the ring buffer */
+typedef struct {
+ CARD32 scale_3d_cntl; /* 0x1a00 */
+
+ CARD32 aux_sc_cntl; /* 0x1660 */
+ CARD32 aux1_sc_left;
+ CARD32 aux1_sc_right;
+ CARD32 aux1_sc_top;
+ CARD32 aux1_sc_bottom;
+ CARD32 aux2_sc_left;
+ CARD32 aux2_sc_right;
+ CARD32 aux2_sc_top;
+ CARD32 aux2_sc_bottom;
+ CARD32 aux3_sc_left;
+ CARD32 aux3_sc_right;
+ CARD32 aux3_sc_top;
+ CARD32 aux3_sc_bottom; /* 0x1690 */
+
+ CARD32 dst_pitch_offset_c; /* 0x1c80 */
+ CARD32 dp_gui_master_cntl;
+ CARD32 sc_top_left_c;
+ CARD32 sc_bottom_right_c;
+ CARD32 z_offset_c;
+ CARD32 z_pitch_c;
+ CARD32 z_sten_cntl_c;
+ CARD32 tex_cntl_c;
+ CARD32 misc_3d_state_cntl_reg;
+ CARD32 texture_clr_cmp_clr_c;
+ CARD32 texture_clr_cmp_msk_c;
+ CARD32 fog_color_c;
+ CARD32 prim_tex_cntl_c;
+ CARD32 prim_texture_combine_cntl_c;
+ CARD32 tex_size_pitch_c;
+ CARD32 prim_tex_offset[R128_TEX_MAXLEVELS]; /* 0x1ce4 */
+
+ CARD32 sec_tex_cntl_c; /* 0x1d00 */
+ CARD32 sec_tex_combine_cntl_c;
+ CARD32 sec_tex_offset[R128_TEX_MAXLEVELS];
+ CARD32 constant_color_c;
+ CARD32 prim_texture_border_color_c;
+ CARD32 sec_texture_border_color_c;
+ CARD32 sten_ref_mask_c;
+ CARD32 plane_3d_mask_c; /* 0x1d44 */
+
+ CARD32 setup_cntl; /* 0x1bc4 */
+
+ CARD32 pm4_vc_fpu_setup; /* 0x071c */
+
+ CARD32 fog_3d_table_start; /* 0x1810 */
+ CARD32 fog_3d_table_end;
+ CARD32 fog_3d_table_density; /* 0x181c */
+
+ CARD32 window_xy_offset; /* 0x1bcc */
+
+ CARD32 dp_write_mask; /* 0x16cc */
+
+ CARD32 pc_gui_ctlstat; /* 0x1748 */
+} r128ContextRegs;
+
+typedef struct {
+ GLcontext *glCtx; /* Mesa context */
+ int dirty; /* Hardware state to be updated */
+ int dirty_context; /* Context state to be updated */
+
+ int SWonly; /* Force software-only rendering */
+ int SWfallbackDisable; /* Disable software fallbacks */
+
+ r128TexObjPtr CurrentTexObj[2]; /* Ptr to current texture
+ object associated with
+ each texture unit */
+ /* List of tex swapped in per heap*/
+ r128TexObj TexObjList[R128_NR_TEX_HEAPS];
+ r128TexObj SwappedOut; /* List of textures swapped out */
+ memHeap_t *texHeap[R128_NR_TEX_HEAPS]; /* Global tex heaps */
+ /* Last known global tex heap ages */
+ int lastTexAge[R128_NR_TEX_HEAPS];
+
+ CARD32 lastSwapAge; /* Last known swap age */
+
+ GLenum FogMode; /* Current fog equation */
+
+ int Scissor;
+ XF86DRIClipRectRec ScissorRect; /* Current software scissor */
+
+ int useFastPath; /* Currently using Fast Path code */
+ int SetupIndex; /* Raster setup function index */
+ int SetupDone; /* Partial raster setup done? */
+ int RenderIndex; /* Render state function index */
+ r128InterpFunc interp; /* Current vert interp function */
+
+ r128CCEVertBuf vb; /* VB currently being filled */
+ int disableVB; /* Disable the use of vertex buffers */
+
+ points_func PointsFunc; /* Current Points, Line, Triangle */
+ line_func LineFunc; /* and Quad rendering functions */
+ triangle_func TriangleFunc;
+ quad_func QuadFunc;
+
+ CARD32 IndirectTriangles; /* Flags for point, line,
+ tri and quad software
+ fallbacks */
+ CARD32 Fallback; /* Need software fallback */
+
+ r128ContextRegs regs; /* Hardware state */
+ CARD32 Color; /* Current draw color */
+ CARD32 ClearColor; /* Color used to clear color buffer */
+ CARD32 ClearDepth; /* Value used to clear depth buffer */
+
+ int drawX; /* x-offset to current draw buffer */
+ int drawY; /* y-offset to current draw buffer */
+
+ int readX; /* x-offset to current read buffer */
+ int readY; /* y-offset to current read buffer */
+
+ CARD32 *CCEbuf; /* buffer to submit to CCE */
+ int CCEcount; /* number of dwords in CCEbuf */
+
+ int CCEtimeout; /* number of times to loop
+ before exiting */
+
+ Display *display; /* X server display */
+
+ __DRIcontextPrivate *driContext; /* DRI context */
+ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
+
+ r128ScreenPtr r128Screen; /* Screen private DRI data */
+} r128ContextRec, *r128ContextPtr;
+
+#define R128_MESACTX(r128ctx) ((r128ctx)->glCtx)
+#define R128_DRIDRAWABLE(r128ctx) ((r128ctx)->driDrawable)
+#define R128_DRISCREEN(r128ctx) ((r128ctx)->r128Screen->driScreen)
+
+extern GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual,
+ __DRIcontextPrivate *driContextPriv);
+extern void r128DestroyContext(r128ContextPtr r128ctx);
+extern r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx,
+ r128ContextPtr newCtx,
+ __DRIdrawablePrivate *dPriv);
+
+#endif
+#endif /* _R128_CONTEXT_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
new file mode 100644
index 000000000..0ed7ae471
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
@@ -0,0 +1,182 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_cce.h"
+#include "r128_clear.h"
+#include "r128_state.h"
+#include "r128_vb.h"
+#include "r128_pipeline.h"
+#include "r128_dd.h"
+
+/* Driver entry point for clearing color and ancillary buffers */
+static GLbitfield r128DDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ if (r128ctx->SWonly) {
+ /* FIXME: Provide software fallback for this case?? */
+ }
+
+ if (mask & DD_FRONT_LEFT_BIT) {
+ r128ClearColorBuffer(r128ctx, all, x, y, width, height,
+ r128ctx->r128Screen->fbX,
+ r128ctx->r128Screen->fbY);
+ mask &= ~DD_FRONT_LEFT_BIT;
+ }
+
+ if (mask & DD_BACK_LEFT_BIT) {
+ r128ClearColorBuffer(r128ctx, all, x, y, width, height,
+ r128ctx->r128Screen->backX,
+ r128ctx->r128Screen->backY);
+ mask &= ~DD_BACK_LEFT_BIT;
+ }
+
+ if (mask & DD_DEPTH_BIT) {
+ r128ClearDepthBuffer(r128ctx, all, x, y, width, height);
+ mask &= ~DD_DEPTH_BIT;
+ }
+
+#if 0
+ /* FIXME: Add stencil support */
+ if (mask & DD_STENCIL_BIT) {
+ r128ClearStencilBuffer(r128ctx, all, x, y, width, height);
+ mask &= ~DD_STENCIL_BIT;
+ }
+#endif
+
+ return mask;
+}
+
+/* Return the current color buffer size */
+static void r128DDGetBufferSize(GLcontext *ctx, GLuint *width, GLuint *height)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ *width = r128ctx->driDrawable->w;
+ *height = r128ctx->driDrawable->h;
+}
+
+/* Return various strings for glGetString() */
+static const GLubyte *r128DDGetString(GLcontext *ctx, GLenum name)
+{
+ switch (name) {
+ case GL_VENDOR:
+ return (GLubyte *)"Precision Insight, Inc.";
+ case GL_RENDERER:
+ return (GLubyte *)"Mesa DRI Rage128 20000320";
+ default:
+ return NULL;
+ }
+}
+
+/* Send all commands to the hardware. If vertex buffers or indirect
+ buffers are in use, then we need to make sure they are sent to the
+ hardware. All commands that are normally sent to the ring are
+ already considered `flushed'. */
+static void r128DDFlush(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+}
+
+/* Make sure all commands have been sent to the hardware and have
+ completed processing. */
+static void r128DDFinish(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ r128DDFlush(ctx);
+ R128CCE_WAIT_FOR_IDLE_LOCK(r128ctx);
+}
+
+/* Return various parameters requested by Mesa */
+static GLint r128DDGetParameteri(const GLcontext *ctx, GLint param)
+{
+ switch (param) {
+#if 0
+ /* FIXME: Support for these needs to be added to Mesa */
+ case DD_MAX_TEXTURE_SIZE: return 1024;
+ case DD_MAX_TEXTURES: return 2;
+#endif
+#if 0
+ case DD_HAVE_HARDWARE_FOG: return 1; /* FIXME: Add HW fog support */
+#endif
+ default: return 0;
+ }
+}
+
+/* Initialize the extensions supported by this driver */
+void r128DDInitExtensions(GLcontext *ctx)
+{
+ /* FIXME: Are there other extensions to enable/disable??? */
+ gl_extensions_disable(ctx, "GL_EXT_shared_texture_palette");
+ gl_extensions_disable(ctx, "GL_EXT_paletted_texture");
+ gl_extensions_disable(ctx, "GL_EXT_point_parameters");
+ gl_extensions_disable(ctx, "ARB_imaging");
+ gl_extensions_disable(ctx, "GL_EXT_blend_minmax");
+ gl_extensions_disable(ctx, "GL_EXT_blend_logic_op");
+ gl_extensions_disable(ctx, "GL_EXT_blend_subtract");
+ gl_extensions_disable(ctx, "GL_INGR_blend_func_separate");
+
+ if (getenv("LIBGL_NO_MULTITEXTURE"))
+ gl_extensions_disable(ctx, "GL_ARB_multitexture");
+}
+
+/* Initialize the driver's misc functions */
+void r128DDInitDriverFuncs(GLcontext *ctx)
+{
+ ctx->Driver.Clear = r128DDClear;
+
+ ctx->Driver.GetBufferSize = r128DDGetBufferSize;
+ ctx->Driver.GetString = r128DDGetString;
+ ctx->Driver.Finish = r128DDFinish;
+ ctx->Driver.Flush = r128DDFlush;
+
+ ctx->Driver.Error = NULL;
+ ctx->Driver.GetParameteri = r128DDGetParameteri;
+
+ ctx->Driver.DrawPixels = NULL;
+ ctx->Driver.Bitmap = NULL;
+
+ ctx->Driver.RegisterVB = r128DDRegisterVB;
+ ctx->Driver.UnregisterVB = r128DDUnregisterVB;
+ ctx->Driver.BuildPrecalcPipeline = r128DDBuildPrecalcPipeline;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h
new file mode 100644
index 000000000..91aa02586
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h
@@ -0,0 +1,44 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_DD_H_
+#define _R128_DD_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128DDInitExtensions(GLcontext *ctx);
+extern void r128DDInitDriverFuncs(GLcontext *ctx);
+
+#endif
+#endif /* _R128_DD_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c
new file mode 100644
index 000000000..330e5a23d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c
@@ -0,0 +1,551 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_state.h"
+#include "r128_vb.h"
+#include "r128_tris.h"
+#include "r128_fastpath.h"
+
+#include "mmath.h"
+#include "cva.h"
+#include "vertices.h"
+
+/* FIXME: These routines were copied from the i810 driver, and were only
+ slightly modified for the Rage 128. They still need to be optmizied
+ and cleaned up. Also, support for USE_RHW2 needs to be added. */
+
+typedef struct r128_fast_table {
+ r128BuildVerticesFunc build_vertices;
+ r128InterpFunc interp;
+} r128FastPathTable;
+
+#define POINT(x) r128DrawPointVB(r128ctx, &vert[x].v, psize)
+#define LINE(x,y) r128DrawLineVB(r128ctx, &vert[x].v, &vert[y].v, lwidth)
+#define TRI(x,y,z) r128DrawTriangleVB(r128ctx, &vert[x].v, &vert[y].v, &vert[z].v)
+
+/* Direct, and no clipping required. The clip funcs have not been
+ written yet, so this is only useful for the fast path. */
+#define RENDER_POINTS(start, count) \
+do { \
+ GLuint e; \
+ for (e = start; e <= count; e++) \
+ POINT(elt[e]); \
+} while (0)
+
+#define RENDER_LINE(i1, i) \
+do { \
+ GLuint e1 = elt[i1], e = elt[i]; \
+ LINE(e1, e); \
+} while (0)
+
+#define RENDER_TRI(i2, i1, i, pv, parity) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ if (parity) { \
+ GLuint tmp = e2; \
+ e2 = e1; \
+ e1 = tmp; \
+ } \
+ TRI(e2, e1, e); \
+} while (0)
+
+#define RENDER_QUAD(i3, i2, i1, i, pv) \
+do { \
+ GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ TRI(e3, e2, e); \
+ TRI(e2, e1, e); \
+} while (0)
+
+#define LOCAL_VARS \
+ r128VertexPtr vert = R128_DRIVER_DATA(VB)->verts; \
+ const GLuint *elt = VB->EltPtr->data; \
+ GLcontext *ctx = VB->ctx; \
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx); \
+ const GLfloat lwidth = ctx->Line.Width; \
+ const GLfloat psize = ctx->Point.Size; \
+ (void) lwidth; (void)psize; (void) vert;
+
+#define TAG(x) x##_r128_smooth_indirect
+#include "render_tmp.h"
+
+
+
+#define NEGATIVE(f) (f < 0)
+#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
+#define LINTERP(T, A, B) ((A) + (T) * ((B) - (A)))
+
+
+#define INTERP_RGBA(t, out, a, b) \
+do { \
+ int i; \
+ for (i = 0; i < 4; i++) { \
+ GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \
+ GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \
+ GLfloat fo = LINTERP(t, fa, fb); \
+ FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \
+ } \
+} while (0)
+
+
+#define CLIP(SGN, V, PLANE) \
+do { \
+ if (mask & PLANE) { \
+ GLuint *indata = inlist[in]; \
+ GLuint *outdata = inlist[in ^= 1]; \
+ GLuint nr = n; \
+ GLfloat *J = verts[indata[nr-1]].f; \
+ GLfloat dpJ = (SGN J[V]) + J[3]; \
+ \
+ inlist[0] = vlist1; \
+ for (i = n = 0 ; i < nr ; i++) { \
+ GLuint elt_i = indata[i]; \
+ GLfloat *I = verts[elt_i].f; \
+ GLfloat dpI = (SGN I[V]) + I[3]; \
+ \
+ if (DIFFERENT_SIGNS(dpI, dpJ)) { \
+ GLfloat *O = verts[next_vert].f; \
+ GLfloat t, *in, *out; \
+ \
+ if (NEGATIVE(dpI)) { \
+ t = dpI / (dpI - dpJ); \
+ in = I; \
+ out = J; \
+ } else { \
+ t = dpJ / (dpJ - dpI); \
+ in = J; \
+ out = I; \
+ } \
+ \
+ interp(t, O, in, out); \
+ \
+ clipmask[next_vert] = 0; \
+ outdata[n++] = next_vert++; \
+ } \
+ \
+ clipmask[elt_i] |= PLANE; /* don't set up */ \
+ \
+ if (!NEGATIVE(dpI)) { \
+ outdata[n++] = elt_i; \
+ clipmask[elt_i] &= ~PLANE; /* set up after all */ \
+ } \
+ \
+ J = I; \
+ dpJ = dpI; \
+ } \
+ \
+ if (n < 3) return; \
+ } \
+} while (0)
+
+#define LINE_CLIP(x,y,z,w,PLANE) \
+do { \
+ if (mask & PLANE) { \
+ GLfloat dpI = DOT4V(I,x,y,z,w); \
+ GLfloat dpJ = DOT4V(J,x,y,z,w); \
+ \
+ if (DIFFERENT_SIGNS(dpI, dpJ)) { \
+ GLfloat *O = verts[next_vert].f; \
+ GLfloat t = dpI / (dpI - dpJ); \
+ \
+ interp(t, O, I, J); \
+ \
+ clipmask[next_vert] = 0; \
+ \
+ if (NEGATIVE(dpI)) { \
+ clipmask[elts[0]] |= PLANE; \
+ I = O; \
+ elts[0] = next_vert++; \
+ } else { \
+ clipmask[elts[1]] |= PLANE; \
+ J = O; \
+ elts[1] = next_vert++; \
+ } \
+ } else if (NEGATIVE(dpI)) return; \
+ } \
+} while (0)
+
+
+static void r128TriClip(GLuint **p_elts,
+ r128Vertex *verts,
+ GLubyte *clipmask,
+ GLuint *p_next_vert,
+ GLubyte mask,
+ r128InterpFunc interp)
+{
+ GLuint *elts = *p_elts;
+ GLuint next_vert = *p_next_vert;
+ GLuint in = 0;
+ GLuint n = 3;
+ GLuint vlist1[VB_MAX_CLIPPED_VERTS];
+ GLuint vlist2[VB_MAX_CLIPPED_VERTS];
+ GLuint *inlist[2];
+ GLuint *out;
+ GLuint i;
+
+ inlist[0] = elts;
+ inlist[1] = vlist2;
+
+ CLIP(-,0,CLIP_RIGHT_BIT);
+ CLIP(+,0,CLIP_LEFT_BIT);
+ CLIP(-,1,CLIP_TOP_BIT);
+ CLIP(+,1,CLIP_BOTTOM_BIT);
+ CLIP(-,2,CLIP_FAR_BIT);
+ CLIP(+,2,CLIP_NEAR_BIT);
+
+ /* Convert the planar polygon to a list of triangles */
+ out = inlist[in];
+
+ for (i = 2 ; i < n ; i++) {
+ elts[0] = out[0];
+ elts[1] = out[i-1];
+ elts[2] = out[i];
+ elts += 3;
+ }
+
+ *p_next_vert = next_vert;
+ *p_elts = elts;
+}
+
+
+static void r128LineClip(GLuint **p_elts,
+ r128Vertex *verts,
+ GLubyte *clipmask,
+ GLuint *p_next_vert,
+ GLubyte mask,
+ r128InterpFunc interp)
+{
+ GLuint *elts = *p_elts;
+ GLfloat *I = verts[elts[0]].f;
+ GLfloat *J = verts[elts[1]].f;
+ GLuint next_vert = *p_next_vert;
+
+ LINE_CLIP(1,0,0,-1,CLIP_LEFT_BIT);
+ LINE_CLIP(-1,0,0,1,CLIP_RIGHT_BIT);
+ LINE_CLIP(0,1,0,-1,CLIP_TOP_BIT);
+ LINE_CLIP(0,-1,0,1,CLIP_BOTTOM_BIT);
+ LINE_CLIP(0,0,1,-1,CLIP_FAR_BIT);
+ LINE_CLIP(0,0,-1,1,CLIP_NEAR_BIT);
+
+ *p_next_vert = next_vert;
+ *p_elts += 2;
+}
+
+
+
+#define CLIP_POINT(e) \
+do { \
+ if (mask[e]) *out++ = e; \
+} while (0)
+
+#define CLIP_LINE(e1, e0) \
+do { \
+ GLubyte ormask = mask[e0] | mask[e1]; \
+ out[0] = e1; \
+ out[1] = e0; \
+ out += 2; \
+ if (ormask) { \
+ out-=2; \
+ if (!(mask[e0] & mask[e1])) { \
+ r128LineClip(&out, verts, mask, &next_vert, ormask, interp); \
+ } \
+ } \
+} while (0)
+
+#define CLIP_TRIANGLE(e2, e1, e0) \
+do { \
+ GLubyte ormask; \
+ out[0] = e2; \
+ out[1] = e1; \
+ out[2] = e0; \
+ out += 3; \
+ ormask = mask[e2] | mask[e1] | mask[e0]; \
+ if (ormask) { \
+ out -= 3; \
+ if (!(mask[e2] & mask[e1] & mask[e0])) { \
+ r128TriClip(&out, verts, mask, &next_vert, ormask, interp); \
+ } \
+ } \
+} while (0)
+
+
+
+/* Build a table of functions to clip each primitive type. These
+ * produce a list of elements in the appropriate 'reduced' primitive,
+ * ie (points, lines, triangles) containing all the clipped and
+ * unclipped primitives from the original list.
+ */
+#define LOCAL_VARS \
+ r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); \
+ r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); \
+ GLuint *elt = VB->EltPtr->data; \
+ r128Vertex *verts = r128VB->verts; \
+ GLuint next_vert = r128VB->last_vert; \
+ GLuint *out = r128VB->clipped_elements.data; \
+ GLubyte *mask = VB->ClipMask; \
+ r128InterpFunc interp = r128ctx->interp; \
+ (void) interp; (void) verts;
+
+#define POSTFIX \
+ r128VB->clipped_elements.count = out - r128VB->clipped_elements.data; \
+ r128VB->last_vert = next_vert;
+
+
+#define INIT(x)
+
+#define RENDER_POINTS(start, count) \
+do { \
+ GLuint i; \
+ for (i = start; i < count; i++) \
+ CLIP_POINT(elt[i]); \
+} while (0)
+
+#define RENDER_LINE(i1, i0) \
+do { \
+ CLIP_LINE(elt[i1], elt[i0]); \
+} while (0)
+
+#define RENDER_TRI(i2, i1, i0, pv, parity) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \
+ if (parity) e2 = elt[i1], e1 = elt[i2]; \
+ CLIP_TRIANGLE(e2, e1, e0); \
+} while (0)
+
+#define RENDER_QUAD(i3, i2, i1, i0, pv) \
+do { \
+ CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \
+ CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0]); \
+} while (0)
+
+#define TAG(x) r128_clip_##x##_elt
+#include "render_tmp.h"
+
+
+/* Pack rgba and/or texture into the remaining half of a 32 byte vertex.
+ */
+#define CLIP_UBYTE_COLOR 4
+#define CLIP_UBYTE_B 0
+#define CLIP_UBYTE_G 1
+#define CLIP_UBYTE_R 2
+#define CLIP_UBYTE_A 3
+#define CLIP_S0 6
+#define CLIP_T0 7
+#define CLIP_S1 8
+#define CLIP_T1 9
+
+#define TYPE (0)
+#define TAG(x) x
+#include "r128_fasttmp.h"
+
+#define TYPE (R128_RGBA_BIT)
+#define TAG(x) x##_RGBA
+#include "r128_fasttmp.h"
+
+#define TYPE (R128_TEX0_BIT)
+#define TAG(x) x##_TEX0
+#include "r128_fasttmp.h"
+
+#define TYPE (R128_RGBA_BIT | R128_TEX0_BIT)
+#define TAG(x) x##_RGBA_TEX0
+#include "r128_fasttmp.h"
+
+#define TYPE (R128_RGBA_BIT | R128_TEX0_BIT | R128_TEX1_BIT)
+#define TAG(x) x##_RGBA_TEX0_TEX1
+#include "r128_fasttmp.h"
+
+/* This one *could* get away with sneaking TEX1 into the color and
+ * specular slots, thus fitting inside a cache line. Would be even
+ * better to switch to a smaller vertex.
+ */
+#define TYPE (R128_TEX0_BIT | R128_TEX1_BIT)
+#define TAG(x) x##_TEX0_TEX1
+#include "r128_fasttmp.h"
+
+
+
+/* Render elements directly from original list of vertices. */
+static void r128RenderElementsDirect(struct vertex_buffer *VB)
+{
+ GLcontext *ctx = VB->ctx;
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ GLenum prim = ctx->CVA.elt_mode;
+ GLuint nr = VB->EltPtr->count;
+ render_func func = render_tab_r128_smooth_indirect[prim];
+ GLuint p = 0;
+
+ if (r128ctx->dirty) r128UpdateHWState(r128ctx);
+
+ do {
+ func(VB, 0, nr, 0);
+ } while (ctx->Driver.MultipassFunc &&
+ ctx->Driver.MultipassFunc(VB, ++p));
+}
+
+/* Project vertices from clip to device space */
+static void r128ProjectVertices(struct vertex_buffer *VB)
+{
+ GLcontext *ctx = VB->ctx;
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB);
+ GLfloat m[16];
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX];
+ m[MAT_SY] = -mat->m[MAT_SY];
+ m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h;
+ m[MAT_SZ] = mat->m[MAT_SZ];
+ m[MAT_TZ] = mat->m[MAT_TZ];
+
+ switch (ctx->Visual->DepthBits) {
+ case 16: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
+ case 24: m[MAT_SZ] /= 16777216.0; m[MAT_TZ] /= 16777216.0; break;
+ case 32: m[MAT_SZ] /= 4294967296.0; m[MAT_TZ] /= 4294967296.0; break;
+ default: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
+ }
+
+#if USE_RHW2
+ /* FIXME: Handle RHW2?? */
+ gl_project_v16(r128VB->verts[VB->CopyStart].f,
+ r128VB->verts[r128VB->last_vert].f,
+ m,
+ 16 * 4);
+#else
+ gl_project_v16(r128VB->verts[VB->CopyStart].f,
+ r128VB->verts[r128VB->last_vert].f,
+ m,
+ 16 * 4);
+#endif
+}
+
+/* Project clipped vertices from clip to device space */
+static void r128ProjectClippedVertices(struct vertex_buffer *VB)
+{
+ GLcontext *ctx = VB->ctx;
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB);
+ GLfloat m[16];
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX];
+ m[MAT_SY] = -mat->m[MAT_SY];
+ m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h;
+ m[MAT_SZ] = mat->m[MAT_SZ];
+ m[MAT_TZ] = mat->m[MAT_TZ];
+
+ switch (ctx->Visual->DepthBits) {
+ case 16: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
+ case 24: m[MAT_SZ] /= 16777216.0; m[MAT_TZ] /= 16777216.0; break;
+ case 32: m[MAT_SZ] /= 4294967296.0; m[MAT_TZ] /= 4294967296.0; break;
+ default: m[MAT_SZ] /= 65536.0; m[MAT_TZ] /= 65536.0; break;
+ }
+
+#if USE_RHW2
+ /* FIXME: Handle RHW2?? */
+ gl_project_clipped_v16(r128VB->verts[VB->CopyStart].f,
+ r128VB->verts[r128VB->last_vert].f,
+ m,
+ 16 * 4,
+ VB->ClipMask + VB->CopyStart);
+#else
+ gl_project_clipped_v16(r128VB->verts[VB->CopyStart].f,
+ r128VB->verts[r128VB->last_vert].f,
+ m,
+ 16 * 4,
+ VB->ClipMask + VB->CopyStart);
+#endif
+}
+
+static r128FastPathTable r128FastTab[0x80];
+
+/* Initialize the table of fast path support functions */
+void r128FastPathInit(void)
+{
+ r128_clip_render_init_elt();
+ render_init_r128_smooth_indirect();
+
+ r128_init_fastpath(&r128FastTab[0]);
+ r128_init_fastpath_RGBA(&r128FastTab[R128_RGBA_BIT]);
+ r128_init_fastpath_TEX0(&r128FastTab[R128_TEX0_BIT]);
+ r128_init_fastpath_RGBA_TEX0(&r128FastTab[R128_RGBA_BIT|R128_TEX0_BIT]);
+ r128_init_fastpath_TEX0_TEX1(&r128FastTab[R128_TEX0_BIT|R128_TEX1_BIT]);
+ r128_init_fastpath_RGBA_TEX0_TEX1(&r128FastTab[R128_RGBA_BIT|R128_TEX0_BIT|
+ R128_TEX1_BIT]);
+}
+
+#define VALID_SETUP (R128_RGBA_BIT | R128_TEX0_BIT | R128_TEX1_BIT)
+
+void r128FastPath(struct vertex_buffer *VB)
+{
+ GLcontext *ctx = VB->ctx;
+ GLenum prim = ctx->CVA.elt_mode;
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128FastPathTable *tab = &r128FastTab[r128ctx->SetupIndex & VALID_SETUP];
+ GLuint do_cliptest = 1;
+
+ gl_prepare_arrays_cva(VB); /* still need this */
+
+ /* Reserve enough space for the pathological case */
+ if (VB->EltPtr->count * 12 > R128_DRIVER_DATA(VB)->size) {
+ r128ResizeVB(VB, VB->EltPtr->count * 12);
+ do_cliptest = 1;
+ }
+
+ tab->build_vertices(VB, do_cliptest); /* object->clip space */
+
+ if (r128ctx->dirty) r128UpdateHWState(r128ctx);
+
+ if (VB->ClipOrMask) {
+ if (!VB->ClipAndMask) {
+ render_func *clip = r128_clip_render_tab_elt;
+
+ r128ctx->interp = tab->interp;
+ clip[prim](VB, 0, VB->EltPtr->count, 0); /* build new elts */
+ ctx->CVA.elt_mode = gl_reduce_prim[prim];
+ VB->EltPtr = &(R128_DRIVER_DATA(VB)->clipped_elements);
+ r128ProjectClippedVertices(VB); /* clip->device space */
+ r128RenderElementsDirect(VB); /* render using new list */
+ }
+ } else {
+ r128ProjectVertices(VB); /* clip->device space */
+ r128RenderElementsDirect(VB); /* render using orig list */
+ }
+
+ /* This indicates that there is no cached data to reuse */
+ VB->pipeline->data_valid = 0;
+ VB->pipeline->new_state = 0;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h
new file mode 100644
index 000000000..47bb92049
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.h
@@ -0,0 +1,48 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_FASTPATH_H_
+#define _R128_FASTPATH_H_
+
+typedef void (*r128BuildVerticesFunc)(struct vertex_buffer *VB,
+ GLuint do_cliptest);
+typedef void (*r128InterpFunc)(GLfloat t,
+ GLfloat *result,
+ const GLfloat *in,
+ const GLfloat *out);
+
+extern void r128FastPathInit(void);
+extern void r128FastPath(struct vertex_buffer *VB);
+
+#endif /* _R128_FASTPATH_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h
new file mode 100644
index 000000000..e76dd52b4
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h
@@ -0,0 +1,155 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+/* FIXME: These routines were copied from the i810 driver, and were only
+ slightly modified for the Rage 128. They still need to be optmizied
+ and cleaned up. Also, support for USE_RHW2 needs to be added. */
+
+/* The first part of setup is applied to all vertices, clipped or
+ * unclipped. This data w!ill be used for clipping, and then all
+ * vertices with a zero clipmask will be projected to device space.
+ *
+ * This could be split into several loops, but - it seems that the
+ * large stride of the fxVertices makes cache issues the big
+ * performance factor, and that multiple loops mean multiple cache
+ * misses....
+ */
+static void TAG(r128_setup_full)(struct vertex_buffer *VB, GLuint do_cliptest)
+{
+ GLcontext *ctx = VB->ctx;
+ r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB);
+ const GLfloat *m = ctx->ModelProjectMatrix.m;
+ GLuint start = VB->CopyStart;
+ GLuint count = VB->Count;
+ GLuint i;
+
+ gl_xform_points3_v16_general(r128VB->verts[start].f,
+ m,
+ VB->ObjPtr->start,
+ VB->ObjPtr->stride,
+ count - start);
+
+ if (do_cliptest) {
+ VB->ClipAndMask = ~0;
+ VB->ClipOrMask = 0;
+ gl_cliptest_points4_v16(r128VB->verts[start].f,
+ r128VB->verts[count].f,
+ &(VB->ClipOrMask),
+ &(VB->ClipAndMask),
+ VB->ClipMask + start);
+ }
+
+ /* These branches are all resolved at compile time. Hopefully all
+ * the pointers are valid addresses even when not enabled.
+ */
+ if (TYPE) {
+ GLubyte *color = VB->ColorPtr->start;
+ GLfloat *tex0_data = VB->TexCoordPtr[0]->start;
+ GLfloat *tex1_data = VB->TexCoordPtr[1]->start;
+
+ GLuint color_stride = VB->ColorPtr->stride;
+ GLuint tex0_stride = VB->TexCoordPtr[0]->stride;
+ GLuint tex1_stride = VB->TexCoordPtr[1]->stride;
+
+ GLfloat *f = r128VB->verts[start].f;
+
+ for (i = start ; i < count ; i++, f += 16) {
+ if (TYPE & R128_RGBA_BIT) {
+ GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR];
+ GLubyte *col = color; color += color_stride;
+ b[CLIP_UBYTE_R] = col[0];
+ b[CLIP_UBYTE_G] = col[1];
+ b[CLIP_UBYTE_B] = col[2];
+ b[CLIP_UBYTE_A] = col[3];
+ }
+ if (TYPE & R128_TEX0_BIT) {
+ f[CLIP_S0] = tex0_data[0];
+ f[CLIP_T0] = tex0_data[1];
+ STRIDE_F(tex0_data, tex0_stride);
+ }
+ if (TYPE & R128_TEX1_BIT) {
+ f[CLIP_S1] = tex1_data[0];
+ f[CLIP_T1] = tex1_data[1];
+ STRIDE_F(tex1_data, tex1_stride);
+ }
+ }
+ }
+
+ r128VB->clipped_elements.count = start;
+ r128VB->last_vert = count;
+}
+
+
+/* Changed to just put the interp func instead of the whole clip
+ * routine into the header. Less code and better chance of doing some
+ * of this stuff in assembly.
+ */
+static void TAG(r128_interp_vert)(GLfloat t,
+ GLfloat *O,
+ const GLfloat *I,
+ const GLfloat *J)
+{
+ O[0] = LINTERP(t, I[0], J[0]);
+ O[1] = LINTERP(t, I[1], J[1]);
+ O[2] = LINTERP(t, I[2], J[2]);
+ O[3] = LINTERP(t, I[3], J[3]);
+
+ if (TYPE & R128_RGBA_BIT) {
+ INTERP_RGBA(t,
+ ((GLubyte *)&(O[4])),
+ ((GLubyte *)&(I[4])),
+ ((GLubyte *)&(J[4])));
+ }
+
+ if (TYPE & R128_TEX0_BIT) {
+ O[6] = LINTERP(t, I[6], J[6]);
+ O[7] = LINTERP(t, I[7], J[7]);
+ }
+
+ if (TYPE & R128_TEX1_BIT) {
+ O[8] = LINTERP(t, I[8], J[8]);
+ O[9] = LINTERP(t, I[9], J[9]);
+ }
+}
+
+
+static void TAG(r128_init_fastpath)(r128FastPathTable *tab)
+{
+ tab->build_vertices = TAG(r128_setup_full);
+ tab->interp = TAG(r128_interp_vert);
+}
+
+#undef TYPE
+#undef TAG
+#undef SIZE
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_init.h b/xc/lib/GL/mesa/src/drv/r128/r128_init.h
new file mode 100644
index 000000000..fcaf70a51
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_init.h
@@ -0,0 +1,92 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_INIT_H_
+#define _R128_INIT_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <X11/Xlibint.h>
+
+#include "types.h"
+#include "xf86drm.h"
+#include "dri_tmm.h"
+#include "dri_mesaint.h"
+
+#include "r128_screen.h"
+#include "r128_context.h"
+
+/* NOTE: The vertex buffer code is currently unstable because of the
+ switches between CCE and MMIO mode in the X server. Fixing the X
+ server to use the CCE should fix this problem. So, for now, it is
+ recommended that you do not use it. */
+
+#define DEBUG 1
+#define DEBUG_LOCKING 1
+#define USE_FAST_PATH 1
+#define USE_USER_SPACE_RING 0
+
+
+#if DEBUG
+
+#include <stdio.h>
+#define R128_DEBUG(p) \
+ do { \
+ printf p ; \
+ fflush(stdout); \
+ } while (0)
+
+extern int R128_DEBUG_FLAGS;
+
+#define DEBUG_VERBOSE_2D 0x0001
+#define DEBUG_VERBOSE_CCE 0x0008
+#define DEBUG_VERBOSE_OUTREG 0x0010
+#define DEBUG_ALWAYS_SYNC 0x0040
+#define DEBUG_VERBOSE_MSG 0x0080
+#define DEBUG_NO_OUTRING 0x0100
+#define DEBUG_NO_OUTREG 0x0200
+#define DEBUG_VERBOSE_API 0x0400
+#define DEBUG_VALIDATE_RING 0x0800
+#define DEBUG_VERBOSE_LRU 0x1000
+#define DEBUG_VERBOSE_DRI 0x2000
+#define DEBUG_VERBOSE_IOCTL 0x4000
+
+#else
+
+#define R128_DEBUG_FLAGS 0
+
+#endif
+
+#endif
+#endif /* _R128_INIT_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h
new file mode 100644
index 000000000..7fd81f807
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h
@@ -0,0 +1,134 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_LOCK_H_
+#define _R128_LOCK_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+/* Turn DEBUG_LOCKING on to find locking conflicts (see r128_init.h) */
+#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 using the current context */
+#define LOCK_HARDWARE(CC) \
+ do { \
+ char __ret = 0; \
+ __DRIcontextPrivate *cPriv = CC->driContext; \
+ __DRIscreenPrivate *sPriv = CC->r128Screen->driScreen; \
+ \
+ DEBUG_CHECK_LOCK(); \
+ DRM_CAS(&sPriv->pSAREA->lock, cPriv->hHWContext, \
+ DRM_LOCK_HELD|cPriv->hHWContext, __ret); \
+ if (__ret) { \
+ /* We lost the context, so we need to request the lock from \
+ the kernel and update our state. */ \
+ drmGetLock(sPriv->fd, cPriv->hHWContext, 0); \
+ XMesaUpdateState(cPriv); \
+ } \
+ DEBUG_LOCK(); \
+ } while (0)
+
+/* Unlock the hardware using the current context */
+#define UNLOCK_HARDWARE(CC) \
+ do { \
+ __DRIcontextPrivate *cPriv = CC->driContext; \
+ __DRIscreenPrivate *sPriv = CC->r128Screen->driScreen; \
+ \
+ DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, cPriv->hHWContext); \
+ DEBUG_RESET(); \
+ } while (0)
+
+/*
+ * This pair of macros makes a loop over the drawing operations, so it
+ * is not self contained and does not have the nice single statement
+ * semantics of most macros.
+ */
+#define BEGIN_CLIP_LOOP(CC) \
+ do { \
+ __DRIdrawablePrivate *_dPriv = CC->driDrawable; \
+ XF86DRIClipRectPtr _pc = _dPriv->pClipRects; \
+ int _nc, _sc; \
+ \
+ for (_nc = _dPriv->numClipRects; _nc > 0; _nc -= 3, _pc += 3) { \
+ _sc = (_nc <= 3) ? _nc : 3; \
+ r128SetClipRects(CC, _pc, _sc)
+
+/* FIXME: This should be a function call to turn off aux clipping */
+#define END_CLIP_LOOP(CC) \
+ R128CCE0(R128_CCE_PACKET0, R128_AUX_SC_CNTL, 0); \
+ R128CCE(0x00000000); \
+ R128CCE_SUBMIT_PACKETS(); \
+ } \
+ } while (0)
+
+#endif
+#endif /* _R128_LOCK_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_mesa.h b/xc/lib/GL/mesa/src/drv/r128/r128_mesa.h
new file mode 100644
index 000000000..3a697b466
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_mesa.h
@@ -0,0 +1,43 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_MESA_H_
+#define _R128_MESA_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#define R128_CONTEXT(ctx) ((r128ContextPtr)(ctx->DriverCtx))
+
+#endif
+#endif /* _R128_MESA_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c
new file mode 100644
index 000000000..55487ffcd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c
@@ -0,0 +1,126 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_vb.h"
+#include "r128_fastpath.h"
+#include "r128_pipeline.h"
+
+#include "types.h"
+
+static struct gl_pipeline_stage r128FastStage = {
+ "R128 Fast Path",
+ (PIPE_OP_VERT_XFORM |
+ PIPE_OP_RAST_SETUP_0 |
+ PIPE_OP_RAST_SETUP_1 |
+ PIPE_OP_RENDER),
+ PIPE_PRECALC,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ r128FastPath
+};
+
+/* Build the PRECALC pipeline with our stage, if possible. Otherwise,
+ return GL_FALSE */
+GLboolean r128DDBuildPrecalcPipeline(GLcontext *ctx)
+{
+#if USE_FAST_PATH
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ struct gl_pipeline *pipe = &ctx->CVA.pre;
+
+ if (r128ctx->RenderIndex == 0 &&
+ !(ctx->Enabled & (TEXTURE0_3D |
+ TEXTURE1_3D |
+ ENABLE_TEXMAT0 |
+ ENABLE_TEXMAT1 |
+ ENABLE_TEXGEN0 |
+ ENABLE_TEXGEN1 |
+ ENABLE_USERCLIP |
+ ENABLE_LIGHT |
+ ENABLE_FOG)) &&
+ (ctx->Array.Flags & (VERT_OBJ_234 |
+ VERT_TEX0_4 |
+ VERT_TEX1_4 |
+ VERT_ELT)) == (VERT_OBJ_23 |
+ VERT_ELT)) {
+ pipe->stages[0] = &r128FastStage;
+ pipe->stages[1] = 0;
+ pipe->new_inputs = ctx->RenderFlags & VERT_DATA;
+ pipe->ops = pipe->stages[0]->ops;
+
+ r128ctx->useFastPath = GL_TRUE;
+ return GL_TRUE;
+ }
+
+ if (r128ctx->useFastPath) {
+ r128ctx->useFastPath = GL_FALSE;
+
+ ctx->CVA.VB->ClipOrMask = 0;
+ ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS;
+ ctx->Array.NewArrayState |= ctx->Array.Summary;
+ }
+#endif
+
+ return GL_FALSE;
+}
+
+/* Register the pipeline with our stages included */
+GLuint r128RegisterPipelineStages(struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr)
+{
+#if USE_FAST_PATH
+ int i;
+
+ for (i = 0; i < nr; i++) {
+ out[i] = in[i];
+ switch (in[i].ops) {
+ case PIPE_OP_RAST_SETUP_0:
+ out[i].cva_state_change = (NEW_LIGHTING |
+ NEW_TEXTURING |
+ NEW_RASTER_OPS);
+ out[i].state_change = ~0;
+ out[i].check = r128CheckPartialRasterSetup;
+ out[i].run = r128PartialRasterSetup;
+ break;
+
+ case PIPE_OP_RAST_SETUP_0|PIPE_OP_RAST_SETUP_1:
+ out[i].run = r128DoRasterSetup;
+ break;
+ }
+ }
+#endif
+
+ return nr;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h
new file mode 100644
index 000000000..280e6b943
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h
@@ -0,0 +1,43 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_PIPELINE_H_
+#define _R128_PIPELINE_H_
+
+extern GLboolean r128DDBuildPrecalcPipeline(GLcontext *ctx);
+extern GLuint r128RegisterPipelineStages(struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr);
+
+#endif /* _R128_PIPELINE_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c
new file mode 100644
index 000000000..b385271f4
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c
@@ -0,0 +1,258 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_dri.h"
+#include "r128_reg.h"
+
+#include "r128_init.h"
+#include "r128_context.h"
+#include "r128_xmesa.h"
+#include "r128_cce.h"
+#include "r128_tris.h"
+#include "r128_vb.h"
+#include "r128_fastpath.h"
+
+#include <sys/mman.h>
+
+/* Create the device specific screen private data struct */
+r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv)
+{
+ r128ScreenPtr r128Screen;
+ R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
+
+ /* Allocate the private area */
+ r128Screen = (r128ScreenPtr)Xmalloc(sizeof(*r128Screen));
+ if (!r128Screen) return NULL;
+
+ /* This is first since which regions we map depends on whether or
+ not we are using a PCI card */
+ r128Screen->IsPCI = r128DRIPriv->IsPCI;
+
+ r128Screen->mmioRgn.handle = r128DRIPriv->registerHandle;
+ r128Screen->mmioRgn.size = r128DRIPriv->registerSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->mmioRgn.handle,
+ r128Screen->mmioRgn.size,
+ (drmAddressPtr)&r128Screen->mmio)) {
+ Xfree(r128Screen);
+ return NULL;
+ }
+
+ if (!r128Screen->IsPCI) {
+ r128Screen->ringRgn.handle = r128DRIPriv->ringHandle;
+ r128Screen->ringRgn.size = r128DRIPriv->ringMapSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->ringRgn.handle,
+ r128Screen->ringRgn.size,
+ (drmAddressPtr)&r128Screen->ring)) {
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+
+ r128Screen->ringReadRgn.handle = r128DRIPriv->ringReadPtrHandle;
+ r128Screen->ringReadRgn.size = r128DRIPriv->ringReadMapSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->ringReadRgn.handle,
+ r128Screen->ringReadRgn.size,
+ (drmAddressPtr)&r128Screen->ringReadPtr)) {
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+
+ r128Screen->vbRgn.handle = r128DRIPriv->vbHandle;
+ r128Screen->vbRgn.size = r128DRIPriv->vbMapSize;
+ r128Screen->vbOffset = r128DRIPriv->vbOffset;
+ if (drmMap(sPriv->fd,
+ r128Screen->vbRgn.handle,
+ r128Screen->vbRgn.size,
+ (drmAddressPtr)&r128Screen->vb)) {
+ drmUnmap((drmAddress)r128Screen->ringReadPtr,
+ r128Screen->ringReadRgn.size);
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+ r128Screen->vbOffset = r128DRIPriv->vbOffset;
+ r128Screen->vbBufSize = r128DRIPriv->vbBufSize;
+
+ r128Screen->indRgn.handle = r128DRIPriv->indHandle;
+ r128Screen->indRgn.size = r128DRIPriv->indMapSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->indRgn.handle,
+ r128Screen->indRgn.size,
+ (drmAddressPtr)&r128Screen->ind)) {
+ drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size);
+ drmUnmap((drmAddress)r128Screen->ringReadPtr,
+ r128Screen->ringReadRgn.size);
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+
+ r128Screen->agpTexRgn.handle = r128DRIPriv->agpTexHandle;
+ r128Screen->agpTexRgn.size = r128DRIPriv->agpTexMapSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->agpTexRgn.handle,
+ r128Screen->agpTexRgn.size,
+ (drmAddressPtr)&r128Screen->agpTex)) {
+ drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size);
+ drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size);
+ drmUnmap((drmAddress)r128Screen->ringReadPtr,
+ r128Screen->ringReadRgn.size);
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+ r128Screen->agpTexOffset = r128DRIPriv->agpTexOffset;
+
+ if (!(r128Screen->vbBufs = drmMapBufs(sPriv->fd))) {
+ drmUnmap((drmAddress)r128Screen->agpTex,
+ r128Screen->agpTexRgn.size);
+ drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size);
+ drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size);
+ drmUnmap((drmAddress)r128Screen->ringReadPtr,
+ r128Screen->ringReadRgn.size);
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ Xfree(r128Screen);
+ return NULL;
+ }
+ }
+
+ r128Screen->deviceID = r128DRIPriv->deviceID;
+
+ r128Screen->width = r128DRIPriv->width;
+ r128Screen->height = r128DRIPriv->height;
+ r128Screen->depth = r128DRIPriv->depth;
+ r128Screen->bpp = r128DRIPriv->bpp;
+ r128Screen->pixel_code = (r128Screen->bpp != 16 ?
+ r128Screen->bpp :
+ r128Screen->depth);
+
+ r128Screen->fb = sPriv->pFB;
+ r128Screen->fbOffset = sPriv->fbOrigin;
+ r128Screen->fbStride = sPriv->fbStride;
+ r128Screen->fbSize = sPriv->fbSize;
+
+ r128Screen->fbX = r128DRIPriv->fbX;
+ r128Screen->fbY = r128DRIPriv->fbY;
+ r128Screen->backX = r128DRIPriv->backX;
+ r128Screen->backY = r128DRIPriv->backY;
+ r128Screen->depthX = r128DRIPriv->depthX;
+ r128Screen->depthY = r128DRIPriv->depthY;
+
+ r128Screen->texOffset[R128_LOCAL_TEX_HEAP] = (r128DRIPriv->textureY *
+ r128Screen->fbStride +
+ r128DRIPriv->textureX *
+ (r128Screen->bpp/8));
+ r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureSize;
+ r128Screen->log2TexGran[R128_LOCAL_TEX_HEAP] = r128DRIPriv->log2TexGran;
+
+ if (r128Screen->IsPCI) {
+ r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0;
+ r128Screen->texSize[R128_AGP_TEX_HEAP] = 0;
+ r128Screen->log2TexGran[R128_AGP_TEX_HEAP] = 0;
+ r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS-1;
+ } else {
+ r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0;
+ r128Screen->texSize[R128_AGP_TEX_HEAP] =
+ r128DRIPriv->agpTexMapSize;
+ r128Screen->log2TexGran[R128_AGP_TEX_HEAP] =
+ r128DRIPriv->log2AGPTexGran;
+ r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS;
+ }
+
+#if 1
+ /* FIXME: For testing only */
+ if (getenv("LIBGL_SHOW_BUFFERS")) {
+ r128Screen->backX = 0;
+ r128Screen->backY = r128DRIPriv->height/2;
+ r128Screen->depthX = r128DRIPriv->width/2;
+ r128Screen->depthY = r128DRIPriv->height/2;
+ }
+#endif
+
+ r128Screen->CCEMode = r128DRIPriv->CCEMode;
+ r128Screen->CCEFifoSize = r128DRIPriv->CCEFifoSize;
+
+ r128Screen->ringEntries = r128DRIPriv->ringSize/sizeof(CARD32);
+ if (!r128Screen->IsPCI) {
+ r128Screen->ringStartPtr = (int *)r128Screen->ring;
+ r128Screen->ringEndPtr = (int *)(r128Screen->ring
+ + r128DRIPriv->ringSize);
+ }
+
+ r128Screen->MMIOFifoSlots = 0;
+ r128Screen->CCEFifoSlots = 0;
+
+ r128Screen->CCEFifoAddr = R128_PM4_FIFO_DATA_EVEN;
+
+ r128Screen->SAREA = (R128SAREAPrivPtr)((char *)sPriv->pSAREA +
+ sizeof(XF86DRISAREARec));
+
+ r128Screen->driScreen = sPriv;
+
+ r128FastPathInit();
+ r128TriangleFuncsInit();
+ r128SetupInit();
+
+ return r128Screen;
+}
+
+/* Destroy the device specific screen private data struct */
+void r128DestroyScreen(__DRIscreenPrivate *sPriv)
+{
+ r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private;
+
+ if (!r128Screen->IsPCI) {
+ drmUnmapBufs(r128Screen->vbBufs);
+
+ drmUnmap((drmAddress)r128Screen->agpTex, r128Screen->agpTexRgn.size);
+ drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size);
+ drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size);
+ drmUnmap((drmAddress)r128Screen->ringReadPtr,
+ r128Screen->ringReadRgn.size);
+ drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size);
+ }
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+
+ Xfree(r128Screen);
+ sPriv->private = NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h
new file mode 100644
index 000000000..02deb64e9
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h
@@ -0,0 +1,129 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_SCREEN_H_
+#define _R128_SCREEN_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r128_sarea.h"
+
+typedef struct {
+ drmHandle handle; /* Handle to the DRM region */
+ drmSize size; /* Size of the DRM region */
+} r128RegionRec, *r128RegionPtr;
+
+typedef struct {
+ /* MMIO register data */
+ r128RegionRec mmioRgn;
+ unsigned char *mmio;
+
+ /* CCE ring buffer data */
+ r128RegionRec ringRgn;
+ unsigned char *ring;
+
+ /* CCE ring read pointer data */
+ r128RegionRec ringReadRgn;
+
+ /* CCE vertex buffer data */
+ r128RegionRec vbRgn;
+ unsigned char *vb;
+ int vbOffset;
+ int vbBufSize;
+ drmBufMapPtr vbBufs;
+
+ /* CCE indirect buffer data */
+ r128RegionRec indRgn;
+ unsigned char *ind;
+
+ /* CCE AGP Texture data */
+ r128RegionRec agpTexRgn;
+ unsigned char *agpTex;
+ int agpTexOffset;
+
+ /* Frame buffer data */
+ unsigned char *fb;
+ unsigned long fbOffset;
+ int fbStride;
+ int fbSize;
+
+ int IsPCI; /* Current card is a PCI card */
+
+ int CCEMode; /* CCE mode that server/clients use */
+ int CCEFifoSize; /* Size of the CCE command FIFO */
+
+ /* CCE ring buffer data */
+ int ringEntries;
+
+ volatile int *ringReadPtr; /* Pointer to current read addr */
+ int *ringStartPtr; /* Pointer to end of ring buffer */
+ int *ringEndPtr; /* Pointer to end of ring buffer */
+
+ /* DRI screen private data */
+ int deviceID; /* PCI device ID */
+ int width; /* Width in pixels of display */
+ int height; /* Height in scanlines of display */
+ int depth; /* Depth of display (8, 15, 16, 24) */
+ int bpp; /* Bit depth of disp (8, 16, 24, 32) */
+ int pixel_code; /* 8, 15, 16, 24, 32 */
+
+ int fbX; /* Start of frame buffer */
+ int fbY;
+ int backX; /* Start of shared back buffer */
+ int backY;
+ int depthX; /* Start of shared depth buffer */
+ int depthY;
+
+ /* Shared texture data */
+ int NRTexHeaps;
+ int texOffset[R128_NR_TEX_HEAPS];
+ int texSize[R128_NR_TEX_HEAPS];
+ int log2TexGran[R128_NR_TEX_HEAPS];
+
+ int MMIOFifoSlots; /* Free slots in the FIFO (64 max) */
+ int CCEFifoSlots; /* Free slots in the CCE FIFO */
+
+ int CCEFifoAddr; /* MMIO offset to write next CCE
+ value (only used when CCE is
+ in PIO mode). */
+ R128SAREAPrivPtr SAREA; /* Pointer to SAREA private data */
+
+ __DRIscreenPrivate *driScreen;
+} r128ScreenRec, *r128ScreenPtr;
+
+r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv);
+void r128DestroyScreen(__DRIscreenPrivate *sPriv);
+
+#endif
+#endif /* _R128_SCREEN_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.c b/xc/lib/GL/mesa/src/drv/r128/r128_span.c
new file mode 100644
index 000000000..b5d1774fd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.c
@@ -0,0 +1,329 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Keith Whitwell <keith@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_state.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_span.h"
+
+#define DBG 0
+
+#define LOCAL_VARS \
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx); \
+ r128ScreenPtr r128scrn = r128ctx->r128Screen; \
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \
+ GLuint pitch = r128scrn->fbStride; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(r128scrn->fb + \
+ (r128ctx->drawX + dPriv->x) * (r128scrn->bpp/8) + \
+ (r128ctx->drawY + dPriv->y) * pitch); \
+ char *read_buf = (char *)(r128scrn->fb + \
+ (r128ctx->readX + dPriv->x) * (r128scrn->bpp/8)+\
+ (r128ctx->readY + dPriv->y) * pitch); \
+ GLushort p; \
+ (void) read_buf; (void) buf; (void) p
+
+#define LOCAL_DEPTH_VARS \
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx); \
+ r128ScreenPtr r128scrn = r128ctx->r128Screen; \
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \
+ GLuint pitch = r128scrn->fbStride; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(r128scrn->fb + \
+ (r128scrn->depthX + dPriv->x) * (r128scrn->bpp/8) + \
+ (r128scrn->depthY + dPriv->y) * pitch); \
+ (void) buf
+
+#define INIT_MONO_PIXEL(p) \
+ p = R128_CONTEXT(ctx)->Color
+
+#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), _x1 = minx; \
+ if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx) + 1; \
+ }
+
+#define Y_FLIP(_y) (height - _y - 1)
+
+
+#define HW_LOCK() \
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx); \
+ LOCK_HARDWARE(r128ctx); \
+ R128CCE_WAIT_FOR_IDLE(r128ctx);
+
+#define HW_CLIPLOOP() \
+ do { \
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \
+ 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() \
+ UNLOCK_HARDWARE(r128ctx)
+
+
+
+/* 16 bit, RGB565 color spanline and pixel functions */
+#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; \
+ rgba[1] = (p >> 3) & 0xfc; \
+ rgba[2] = (p << 3) & 0xf8; \
+ rgba[3] = 0xff; \
+ } while (0)
+
+#define TAG(x) r128##x##_RGB565
+#include "spantmp.h"
+
+
+
+/* 15 bit, ARGB1555 color spanline and pixel functions */
+#define WRITE_RGBA(_x, _y, r, g, b, a) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
+ ((g & 0xf8) << 2) | \
+ ((b & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
+
+#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 >> 7) & 0xf8; \
+ rgba[1] = (p >> 2) & 0xf8; \
+ rgba[2] = (p << 3) & 0xf8; \
+ rgba[3] = (p & 0x8000) ? 0xff : 0; \
+ } while (0)
+
+#define TAG(x) r128##x##_ARGB1555
+#include "spantmp.h"
+
+
+
+/* 16 bit depthbuffer functions */
+#define WRITE_DEPTH(_x, _y, d) \
+ *(GLdepth *)(buf + _x*2 + _y*pitch) = d
+
+#define READ_DEPTH(d, _x, _y) \
+ d = *(GLdepth *)(buf + _x*2 + _y*pitch)
+
+#define TAG(x) r128##x##_16
+#include "depthtmp.h"
+
+
+
+/* 24 bit, RGB888 color spanline and pixel functions */
+#define WRITE_RGBA(_x, _y, r, g, b, a) \
+ *(GLuint *)(buf + _x*3 + _y*pitch) = ((r << 16) | \
+ (g << 8) | \
+ (b << 0))
+
+#define WRITE_PIXEL(_x, _y, p) \
+ *(GLuint *)(buf + _x*3 + _y*pitch) = p
+
+#define READ_RGBA(rgba, _x, _y) \
+ do { \
+ GLuint p = *(GLuint *)(read_buf + _x*3 + _y*pitch); \
+ rgba[0] = (p >> 16) & 0xff; \
+ rgba[1] = (p >> 8) & 0xff; \
+ rgba[2] = (p >> 0) & 0xff; \
+ rgba[3] = 0xff; \
+ } while (0)
+
+#define TAG(x) r128##x##_RGB888
+#include "spantmp.h"
+
+
+
+/* 24 bit depthbuffer functions */
+#define WRITE_DEPTH(_x, _y, d) \
+ *(GLdepth *)(buf + _x*3 + _y*pitch) = d
+
+#define READ_DEPTH(d, _x, _y) \
+ d = *(GLdepth *)(buf + _x*3 + _y*pitch)
+
+#define TAG(x) r128##x##_24
+#include "depthtmp.h"
+
+
+
+/* 32 bit, ARGB8888 color spanline and pixel functions */
+#define WRITE_RGBA(_x, _y, r, g, b, a) \
+ *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \
+ (g << 8) | \
+ (b << 0) | \
+ (a << 24) )
+
+#define WRITE_PIXEL(_x, _y, p) \
+ *(GLuint *)(buf + _x*4 + _y*pitch) = p
+
+#define READ_RGBA(rgba, _x, _y) \
+ do { \
+ GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
+ 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) r128##x##_ARGB8888
+#include "spantmp.h"
+
+
+
+/* 32 bit depthbuffer functions */
+#define WRITE_DEPTH(_x, _y, d) \
+ *(GLdepth *)(buf + _x*4 + _y*pitch) = d
+
+#define READ_DEPTH(d, _x, _y) \
+ d = *(GLdepth *)(buf + _x*4 + _y*pitch)
+
+#define TAG(x) r128##x##_32
+#include "depthtmp.h"
+
+
+
+void r128DDInitSpanFuncs(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ switch (r128ctx->r128Screen->pixel_code) {
+ case 8: /* Color Index mode not supported */
+ break;
+
+ case 15:
+ ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB1555;
+ ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB1555;
+ ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB1555;
+ ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_ARGB1555;
+ ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB1555;
+ ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_ARGB1555;
+ ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_ARGB1555;
+
+ ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16;
+ ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16;
+ ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_16;
+ ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_16;
+ break;
+
+ case 16:
+ ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB565;
+ ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB565;
+ ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB565;
+ ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_RGB565;
+ ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB565;
+ ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_RGB565;
+ ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB565;
+
+ ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16;
+ ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16;
+ ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_16;
+ ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_16;
+ break;
+
+ case 24:
+ ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB888;
+ ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB888;
+ ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB888;
+ ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_RGB888;
+ ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB888;
+ ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_RGB888;
+ ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB888;
+
+ ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_24;
+ ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_24;
+ ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_24;
+ ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_24;
+ break;
+
+ case 32:
+ ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB8888;
+ ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB8888;
+ ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB8888;
+ ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_ARGB8888;
+ ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB8888;
+ ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_ARGB8888;
+ ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_ARGB8888;
+
+ ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_32;
+ ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_32;
+ ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_32;
+ ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_32;
+ break;
+
+ default:
+ break;
+ }
+
+ ctx->Driver.WriteCI8Span = NULL;
+ ctx->Driver.WriteCI32Span = NULL;
+ ctx->Driver.WriteMonoCISpan = NULL;
+ ctx->Driver.WriteCI32Pixels = NULL;
+ ctx->Driver.WriteMonoCIPixels = NULL;
+ ctx->Driver.ReadCI32Span = NULL;
+ ctx->Driver.ReadCI32Pixels = NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.h b/xc/lib/GL/mesa/src/drv/r128/r128_span.h
new file mode 100644
index 000000000..f83a4da9f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.h
@@ -0,0 +1,44 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_SPAN_H_
+#define _R128_SPAN_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128DDInitSpanFuncs(GLcontext *ctx);
+
+#endif
+#endif /* _R128_SPAN_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.c b/xc/lib/GL/mesa/src/drv/r128/r128_state.c
new file mode 100644
index 000000000..3d1ceaa24
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c
@@ -0,0 +1,1309 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_state.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_tris.h"
+#include "r128_vb.h"
+#include "r128_tex.h"
+
+#include "mmath.h"
+
+#define INTERESTED (~(NEW_MODELVIEW | \
+ NEW_PROJECTION | \
+ NEW_TEXTURE_MATRIX | \
+ NEW_USER_CLIP | \
+ NEW_CLIENT_STATE | \
+ NEW_TEXTURE_ENABLE))
+
+static void r128DDUpdateState(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, "r128DDUpdateState(%p)\n", ctx);
+ }
+
+ if (ctx->NewState & INTERESTED) {
+ r128ChooseRenderState(ctx);
+ r128ChooseRasterSetupFunc(ctx);
+ }
+
+ if (!r128ctx->Fallback) {
+ ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+ ctx->IndirectTriangles |= r128ctx->IndirectTriangles;
+
+ ctx->Driver.PointsFunc = r128ctx->PointsFunc;
+ ctx->Driver.LineFunc = r128ctx->LineFunc;
+ ctx->Driver.TriangleFunc = r128ctx->TriangleFunc;
+ ctx->Driver.QuadFunc = r128ctx->QuadFunc;
+ ctx->Driver.RectFunc = NULL;
+ }
+}
+
+static void r128DDUpdateHWState(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ /* FIXME: state is being updated too often */
+ if (r128ctx->dirty)
+ r128UpdateHWState(r128ctx);
+}
+
+static void r128DDReducedPrimitiveChange(GLcontext *ctx, GLenum prim)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ /* FIXME: Also need to flush between tris and tristrips/fans when we
+ support them directly */
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+}
+
+static void r128DDClearColor(GLcontext *ctx,
+ GLubyte r, GLubyte g, GLubyte b, GLubyte a)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ r128ctx->ClearColor = r128PackColor(r128ctx->r128Screen->depth,
+ r, g, b, a);
+}
+
+static void r128DDColor(GLcontext *ctx,
+ GLubyte r, GLubyte g, GLubyte b, GLubyte a)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ r128ctx->Color = r128PackColor(r128ctx->r128Screen->depth, r, g, b, a);
+}
+
+static GLboolean r128DDSetDrawBuffer(GLcontext *ctx, GLenum mode)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ int x = r128ctx->driDrawable->x;
+ int y = r128ctx->driDrawable->y;
+ int found;
+
+ r128ctx->Fallback &= ~R128_FALLBACK_DRAW_BUFFER;
+
+ switch (mode) {
+ case GL_FRONT_LEFT:
+ r128ctx->drawX = r128ctx->r128Screen->fbX;
+ r128ctx->drawY = r128ctx->r128Screen->fbY;
+ found = GL_TRUE;
+ break;
+ case GL_BACK_LEFT:
+ r128ctx->drawX = r128ctx->r128Screen->backX;
+ r128ctx->drawY = r128ctx->r128Screen->backY;
+ found = GL_TRUE;
+ break;
+ default:
+ r128ctx->Fallback |= R128_FALLBACK_DRAW_BUFFER;
+ found = GL_FALSE;
+ break;
+ }
+
+ x += r128ctx->drawX;
+ y += r128ctx->drawY;
+
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) |
+ (x << R128_WINDOW_X_SHIFT));
+
+ /* Recalculate the Z buffer offset since we might be drawing to the
+ back buffer and window_xy_offset affects both color buffer and
+ depth drawing */
+ r128ctx->regs.z_offset_c = ((r128ctx->r128Screen->depthX -
+ r128ctx->drawX) *
+ (r128ctx->r128Screen->bpp/8) +
+ (r128ctx->r128Screen->depthY -
+ r128ctx->drawY) *
+ r128ctx->r128Screen->fbStride);
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_WIN_Z_POS;
+ return found;
+}
+
+static void r128DDSetReadBuffer(GLcontext *ctx,
+ GLframebuffer *colorBuffer,
+ GLenum mode)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ r128ctx->Fallback &= ~R128_FALLBACK_READ_BUFFER;
+
+ switch (mode) {
+ case GL_FRONT_LEFT:
+ r128ctx->readX = r128ctx->r128Screen->fbX;
+ r128ctx->readY = r128ctx->r128Screen->fbY;
+ break;
+ case GL_BACK_LEFT:
+ r128ctx->readX = r128ctx->r128Screen->backX;
+ r128ctx->readY = r128ctx->r128Screen->backY;
+ break;
+ default:
+ r128ctx->Fallback |= R128_FALLBACK_READ_BUFFER;
+ break;
+ }
+}
+
+static GLboolean r128DDColorMask(GLcontext *ctx,
+ GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ GLuint mask = r128PackColor(r128ctx->r128Screen->pixel_code,
+ ctx->Color.ColorMask[RCOMP],
+ ctx->Color.ColorMask[GCOMP],
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP]);
+
+ if (r128ctx->regs.plane_3d_mask_c != mask) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.plane_3d_mask_c = mask;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_MISC;
+ }
+
+ return GL_TRUE;
+}
+
+static void r128DDDither(GLcontext *ctx, GLboolean enable)
+{
+}
+
+static void r128DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 a = r128ctx->regs.misc_3d_state_cntl_reg;
+
+ a &= ~(R128_ALPHA_TEST_MASK | R128_REF_ALPHA_MASK);
+ a |= ctx->Color.AlphaRef & R128_REF_ALPHA_MASK;
+
+ switch (func) {
+ case GL_NEVER: a |= R128_ALPHA_TEST_NEVER; break;
+ case GL_LESS: a |= R128_ALPHA_TEST_LESS; break;
+ case GL_LEQUAL: a |= R128_ALPHA_TEST_LESSEQUAL; break;
+ case GL_EQUAL: a |= R128_ALPHA_TEST_EQUAL; break;
+ case GL_GEQUAL: a |= R128_ALPHA_TEST_GREATEREQUAL; break;
+ case GL_GREATER: a |= R128_ALPHA_TEST_GREATER; break;
+ case GL_NOTEQUAL: a |= R128_ALPHA_TEST_NEQUAL; break;
+ case GL_ALWAYS: a |= R128_ALPHA_TEST_ALWAYS;
+ break;
+ default:
+ /* ERROR!!! */
+ return;
+ }
+
+ if (r128ctx->regs.misc_3d_state_cntl_reg != a) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.misc_3d_state_cntl_reg = a;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALPHASTATE;
+ }
+}
+
+static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 b = r128ctx->regs.misc_3d_state_cntl_reg;
+
+ b &= ~(R128_ALPHA_BLEND_SRC_MASK | R128_ALPHA_BLEND_DST_MASK);
+
+ switch (sfactor) {
+ case GL_ZERO: b |= R128_ALPHA_BLEND_SRC_ZERO;
+ break;
+ case GL_ONE: b |= R128_ALPHA_BLEND_SRC_ONE;
+ break;
+ case GL_DST_COLOR: b |= R128_ALPHA_BLEND_SRC_DESTCOLOR;
+ break;
+ case GL_ONE_MINUS_DST_COLOR: b |= R128_ALPHA_BLEND_SRC_INVDESTCOLOR;
+ break;
+ case GL_SRC_ALPHA: b |= R128_ALPHA_BLEND_SRC_SRCALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA: b |= R128_ALPHA_BLEND_SRC_INVSRCALPHA;
+ break;
+ case GL_DST_ALPHA: b |= R128_ALPHA_BLEND_SRC_DESTALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA: b |= R128_ALPHA_BLEND_SRC_INVDESTALPHA;
+ break;
+ case GL_SRC_ALPHA_SATURATE: b |= R128_ALPHA_BLEND_SRC_SRCALPHASAT;
+ break;
+#if 0
+ /* FIXME: These are not supported directly by the Rage 128.
+ They could be emulated using something like the TexEnv
+ modes. */
+ case GL_CONSTANT_COLOR: b |= 0;
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR: b |= 0;
+ break;
+ case GL_CONSTANT_ALPHA: b |= 0;
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA: b |= 0;
+ break;
+#endif
+ default:
+ /* ERROR!!! */
+ return;
+ }
+
+ switch (dfactor) {
+ case GL_ZERO: b |= R128_ALPHA_BLEND_DST_ZERO;
+ break;
+ case GL_ONE: b |= R128_ALPHA_BLEND_DST_ONE;
+ break;
+ case GL_SRC_COLOR: b |= R128_ALPHA_BLEND_DST_SRCCOLOR;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR: b |= R128_ALPHA_BLEND_DST_INVSRCCOLOR;
+ break;
+ case GL_SRC_ALPHA: b |= R128_ALPHA_BLEND_DST_SRCALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA: b |= R128_ALPHA_BLEND_DST_INVSRCALPHA;
+ break;
+ case GL_DST_ALPHA: b |= R128_ALPHA_BLEND_DST_DESTALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA: b |= R128_ALPHA_BLEND_DST_INVDESTALPHA;
+ break;
+#if 0
+ /* FIXME: These are not supported directly by the Rage 128.
+ They could be emulated using something like the TexEnv
+ modes. */
+ case GL_CONSTANT_COLOR: b |= 0;
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR: b |= 0;
+ break;
+ case GL_CONSTANT_ALPHA: b |= 0;
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA: b |= 0;
+ break;
+#endif
+ default:
+ /* ERROR!!! */
+ return;
+ }
+
+ if (r128ctx->regs.misc_3d_state_cntl_reg != b) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.misc_3d_state_cntl_reg = b;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALPHASTATE;
+ }
+}
+
+static void r128DDBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB,
+ GLenum dfactorRGB, GLenum sfactorA,
+ GLenum dfactorA)
+{
+ if (sfactorRGB != sfactorA || dfactorRGB != dfactorA) {
+ /* ERROR!!! */
+ return;
+ }
+
+ r128DDBlendFunc(ctx, sfactorRGB, dfactorRGB);
+}
+
+static void r128DDClearDepth(GLcontext *ctx, GLclampd d)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ switch (r128ctx->regs.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK) {
+ case R128_Z_PIX_WIDTH_16: r128ctx->ClearDepth = d * 0x0000ffff; break;
+ case R128_Z_PIX_WIDTH_24: r128ctx->ClearDepth = d * 0x00ffffff; break;
+ case R128_Z_PIX_WIDTH_32: r128ctx->ClearDepth = d * 0xffffffff; break;
+ default: return;
+ }
+}
+
+static void r128DDCullFace(GLcontext *ctx, GLenum mode)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 f = r128ctx->regs.pm4_vc_fpu_setup;
+
+ if (!ctx->Polygon.CullFlag) return;
+
+ f &= ~(R128_BACKFACE_MASK | R128_FRONTFACE_MASK);
+
+ switch (mode) {
+ case GL_FRONT: f |= R128_BACKFACE_SOLID; break;
+ case GL_BACK: f |= R128_FRONTFACE_SOLID; break;
+ case GL_FRONT_AND_BACK: break;
+ default: return;
+ }
+
+ if (r128ctx->regs.pm4_vc_fpu_setup != f) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.pm4_vc_fpu_setup = f;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_SETUPSTATE;
+ }
+}
+
+static void r128DDFrontFace(GLcontext *ctx, GLenum mode)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 f = r128ctx->regs.pm4_vc_fpu_setup;
+
+ f &= ~R128_FRONT_DIR_MASK;
+
+ switch (mode) {
+ case GL_CW: f |= R128_FRONT_DIR_CW; break;
+ case GL_CCW: f |= R128_FRONT_DIR_CCW; break;
+ default: return;
+ }
+
+ if (r128ctx->regs.pm4_vc_fpu_setup != f) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.pm4_vc_fpu_setup = f;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_SETUPSTATE;
+ }
+}
+
+static void r128DDDepthFunc(GLcontext *ctx, GLenum func)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 z = r128ctx->regs.z_sten_cntl_c;
+
+ z &= ~R128_Z_TEST_MASK;
+
+ switch (func) {
+ case GL_NEVER: z |= R128_Z_TEST_NEVER; break;
+ case GL_LESS: z |= R128_Z_TEST_LESS; break;
+ case GL_LEQUAL: z |= R128_Z_TEST_LESSEQUAL; break;
+ case GL_EQUAL: z |= R128_Z_TEST_EQUAL; break;
+ case GL_GEQUAL: z |= R128_Z_TEST_GREATEREQUAL; break;
+ case GL_GREATER: z |= R128_Z_TEST_GREATER; break;
+ case GL_NOTEQUAL: z |= R128_Z_TEST_NEQUAL; break;
+ case GL_ALWAYS: z |= R128_Z_TEST_ALWAYS; break;
+ default: return;
+ }
+
+ if (r128ctx->regs.z_sten_cntl_c != z) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.z_sten_cntl_c = z;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ZSTENSTATE;
+ }
+}
+
+static void r128DDDepthMask(GLcontext *ctx, GLboolean flag)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 t = r128ctx->regs.tex_cntl_c;
+
+ if (flag) t |= R128_Z_WRITE_ENABLE;
+ else t &= ~R128_Z_WRITE_ENABLE;
+
+ if (r128ctx->regs.tex_cntl_c != t) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.tex_cntl_c = t;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ENGINESTATE;
+ }
+}
+
+static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ CARD32 t = r128ctx->regs.tex_cntl_c;
+ CARD32 f = r128ctx->regs.pm4_vc_fpu_setup;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, "r128DDEnable( %p, 0x%x = %s )\n",
+ ctx, cap, state ? "GL_TRUE" : "GL_FALSE");
+ }
+
+ switch (cap) {
+ case GL_ALPHA_TEST:
+ if (state) t |= R128_ALPHA_TEST_ENABLE;
+ else t &= ~R128_ALPHA_TEST_ENABLE;
+ break;
+
+ case GL_AUTO_NORMAL: return;
+
+ case GL_BLEND:
+ if (state) t |= R128_ALPHA_ENABLE;
+ else t &= ~R128_ALPHA_ENABLE;
+ break;
+
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ case GL_COLOR_MATERIAL: return;
+
+ case GL_CULL_FACE:
+ f &= ~(R128_BACKFACE_MASK | R128_FRONTFACE_MASK);
+ if (state) {
+ switch (ctx->Polygon.CullFaceMode) {
+ case GL_FRONT: f |= R128_BACKFACE_SOLID; break;
+ case GL_BACK: f |= R128_FRONTFACE_SOLID; break;
+ case GL_FRONT_AND_BACK: break;
+ default: return;
+ }
+ } else {
+ f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID;
+ }
+ break;
+
+ case GL_DEPTH_TEST:
+ if (state) t |= R128_Z_ENABLE;
+ else t &= ~R128_Z_ENABLE;
+ break;
+
+ case GL_DITHER:
+ if (state) t |= R128_DITHER_ENABLE;
+ else t &= ~R128_DITHER_ENABLE;
+ break;
+
+ case GL_FOG:
+ if (state) t |= R128_FOG_ENABLE;
+ else t &= ~R128_FOG_ENABLE;
+ break;
+
+ case GL_LIGHT0:
+ case GL_LIGHT1:
+ case GL_LIGHT2:
+ case GL_LIGHT3:
+ case GL_LIGHT4:
+ case GL_LIGHT5:
+ case GL_LIGHT6:
+ case GL_LIGHT7:
+ case GL_LIGHTING:
+ case GL_LINE_SMOOTH:
+ case GL_LINE_STIPPLE:
+ case GL_INDEX_LOGIC_OP:
+ case GL_COLOR_LOGIC_OP:
+ case GL_MAP1_COLOR_4:
+ case GL_MAP1_INDEX:
+ case GL_MAP1_NORMAL:
+ case GL_MAP1_TEXTURE_COORD_1:
+ case GL_MAP1_TEXTURE_COORD_2:
+ case GL_MAP1_TEXTURE_COORD_3:
+ case GL_MAP1_TEXTURE_COORD_4:
+ case GL_MAP1_VERTEX_3:
+ case GL_MAP1_VERTEX_4:
+ case GL_MAP2_COLOR_4:
+ case GL_MAP2_INDEX:
+ case GL_MAP2_NORMAL:
+ case GL_MAP2_TEXTURE_COORD_1:
+ case GL_MAP2_TEXTURE_COORD_2:
+ case GL_MAP2_TEXTURE_COORD_3:
+ case GL_MAP2_TEXTURE_COORD_4:
+ case GL_MAP2_VERTEX_3:
+ case GL_MAP2_VERTEX_4:
+ case GL_NORMALIZE:
+ case GL_POINT_SMOOTH:
+ case GL_POLYGON_SMOOTH:
+ case GL_POLYGON_STIPPLE:
+ case GL_POLYGON_OFFSET_POINT:
+ case GL_POLYGON_OFFSET_LINE:
+ case GL_POLYGON_OFFSET_FILL:
+ case GL_RESCALE_NORMAL_EXT: return;
+
+ case GL_SCISSOR_TEST:
+ /* FIXME: Hook up the software scissor */
+#if 0
+ r128ctx->Scissor = state;
+#endif
+ break;
+
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ case GL_STENCIL_TEST: return;
+
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ /* This is handled in r128UpdateTex[01]State() */
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+ break;
+
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_GEN_Q:
+ case GL_TEXTURE_GEN_R:
+ case GL_TEXTURE_GEN_S:
+ case GL_TEXTURE_GEN_T: return;
+
+ /* Client state */
+ case GL_VERTEX_ARRAY:
+ case GL_NORMAL_ARRAY:
+ case GL_COLOR_ARRAY:
+ case GL_INDEX_ARRAY:
+ case GL_TEXTURE_COORD_ARRAY:
+ case GL_EDGE_FLAG_ARRAY: return;
+
+ default: return;
+ }
+
+ if (r128ctx->regs.tex_cntl_c != t) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.tex_cntl_c = t;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ENGINESTATE;
+ }
+ if (r128ctx->regs.pm4_vc_fpu_setup != f) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.pm4_vc_fpu_setup = f;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_SETUPSTATE;
+ }
+
+}
+
+static void r128DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ GLubyte c[4];
+ CARD32 col;
+ floatTOint fog;
+ GLenum mode;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, "r128DDFogfv(%p, 0x%x)\n", ctx, pname);
+ }
+
+ switch (pname) {
+ case GL_FOG_MODE:
+ mode = (GLenum)(GLint)*param;
+ if (r128ctx->FogMode != mode) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->FogMode = mode;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_FOGTABLE;
+ }
+ break;
+
+ case GL_FOG_DENSITY:
+ fog.f = *param;
+ if (r128ctx->regs.fog_3d_table_density != fog.i) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.fog_3d_table_density = fog.i;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_FOGSTATE;
+ }
+ break;
+
+ case GL_FOG_START:
+ fog.f = *param;
+ if (r128ctx->regs.fog_3d_table_start != fog.i) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.fog_3d_table_start = fog.i;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_FOGSTATE;
+ }
+ break;
+
+ case GL_FOG_END:
+ fog.f = *param;
+ if (r128ctx->regs.fog_3d_table_end != fog.i) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.fog_3d_table_end = fog.i;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_FOGSTATE;
+ }
+ break;
+
+ case GL_FOG_COLOR:
+ FLOAT_RGBA_TO_UBYTE_RGBA(c, ctx->Fog.Color);
+ col = r128PackColor(32, c[0], c[1], c[2], c[3]);
+ if (r128ctx->regs.fog_color_c != col) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.fog_color_c = col;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_FOGSTATE;
+ }
+ break;
+
+ default:
+ return;
+ }
+}
+
+static void r128DDScissor(GLcontext *ctx,
+ GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ r128ctx->ScissorRect.x1 = x;
+ r128ctx->ScissorRect.y1 = r128ctx->driDrawable->h - (y + h);
+ r128ctx->ScissorRect.x2 = x + w;
+ r128ctx->ScissorRect.y2 = r128ctx->driDrawable->h - y;
+}
+
+/* Initialize the driver's state functions */
+void r128DDInitStateFuncs(GLcontext *ctx)
+{
+ ctx->Driver.UpdateState = r128DDUpdateState;
+
+ ctx->Driver.ClearIndex = NULL;
+ ctx->Driver.ClearColor = r128DDClearColor;
+ ctx->Driver.Index = NULL;
+ ctx->Driver.Color = r128DDColor;
+ ctx->Driver.SetDrawBuffer = r128DDSetDrawBuffer;
+ ctx->Driver.SetReadBuffer = r128DDSetReadBuffer;
+
+ ctx->Driver.IndexMask = NULL;
+ ctx->Driver.ColorMask = r128DDColorMask;
+ ctx->Driver.LogicOp = NULL;
+ ctx->Driver.Dither = r128DDDither;
+
+ ctx->Driver.NearFar = NULL;
+
+ ctx->Driver.RenderStart = r128DDUpdateHWState;
+ ctx->Driver.RenderFinish = NULL;
+ ctx->Driver.RasterSetup = NULL;
+
+ ctx->Driver.RenderVBClippedTab = NULL;
+ ctx->Driver.RenderVBCulledTab = NULL;
+ ctx->Driver.RenderVBRawTab = NULL;
+
+ ctx->Driver.ReducedPrimitiveChange = r128DDReducedPrimitiveChange;
+ ctx->Driver.MultipassFunc = NULL;
+
+ ctx->Driver.AlphaFunc = r128DDAlphaFunc;
+ ctx->Driver.BlendEquation = NULL;
+ ctx->Driver.BlendFunc = r128DDBlendFunc;
+ ctx->Driver.BlendFuncSeparate = r128DDBlendFuncSeparate;
+ ctx->Driver.ClearDepth = r128DDClearDepth;
+ ctx->Driver.CullFace = r128DDCullFace;
+ ctx->Driver.FrontFace = r128DDFrontFace;
+ ctx->Driver.DepthFunc = r128DDDepthFunc;
+ ctx->Driver.DepthMask = r128DDDepthMask;
+ ctx->Driver.DepthRange = NULL;
+ ctx->Driver.Enable = r128DDEnable;
+ ctx->Driver.Fogfv = r128DDFogfv;
+ ctx->Driver.Hint = NULL;
+ ctx->Driver.Lightfv = NULL;
+ ctx->Driver.LightModelfv = NULL;
+ ctx->Driver.PolygonMode = NULL;
+ ctx->Driver.Scissor = r128DDScissor;
+ ctx->Driver.ShadeModel = NULL;
+ ctx->Driver.ClearStencil = NULL;
+ ctx->Driver.StencilFunc = NULL;
+ ctx->Driver.StencilMask = NULL;
+ ctx->Driver.StencilOp = NULL;
+ ctx->Driver.Viewport = NULL;
+}
+
+/* Initialize the context's hardware state */
+void r128DDInitState(r128ContextPtr r128ctx)
+{
+ int dst_bpp, depth_bpp, pitch, i;
+ CARD32 depthClear;
+
+ pitch = r128ctx->r128Screen->fbStride / r128ctx->r128Screen->bpp;
+
+ switch (r128ctx->r128Screen->pixel_code) {
+ case 8: dst_bpp = R128_GMC_DST_8BPP_CI; break;
+ case 15: dst_bpp = R128_GMC_DST_15BPP; break;
+ case 16: dst_bpp = R128_GMC_DST_16BPP; break;
+ case 24: dst_bpp = R128_GMC_DST_24BPP; break;
+ case 32: dst_bpp = R128_GMC_DST_32BPP; break;
+ default:
+ fprintf(stderr, "Error: Unsupported pixel depth %d... exiting\n",
+ r128ctx->r128Screen->pixel_code);
+ exit(-1);
+ }
+
+ /* FIXME: Figure out how to use 16bpp depth buffer in 32bpp mode */
+ switch (r128ctx->glCtx->Visual->DepthBits) {
+ case 16: depthClear = 0x0000ffff; depth_bpp = R128_Z_PIX_WIDTH_16; break;
+ case 24: depthClear = 0x00ffffff; depth_bpp = R128_Z_PIX_WIDTH_24; break;
+ case 32: depthClear = 0xffffffff; depth_bpp = R128_Z_PIX_WIDTH_32; break;
+ default:
+ fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
+ r128ctx->r128Screen->bpp);
+ exit(-1);
+ break;
+ }
+
+ r128ctx->dirty = R128_ALL_DIRTY;
+ r128ctx->dirty_context = R128_CTX_ALL_DIRTY;
+
+ r128ctx->RenderIndex = R128_FALLBACK_BIT;
+ r128ctx->PointsFunc = NULL;
+ r128ctx->LineFunc = NULL;
+ r128ctx->TriangleFunc = NULL;
+ r128ctx->QuadFunc = NULL;
+
+ r128ctx->IndirectTriangles = 0;
+ r128ctx->Fallback = 0;
+
+ if (r128ctx->glCtx->Visual->DBflag) {
+ r128ctx->drawX = r128ctx->r128Screen->backX;
+ r128ctx->drawY = r128ctx->r128Screen->backY;
+ r128ctx->readX = r128ctx->r128Screen->backX;
+ r128ctx->readY = r128ctx->r128Screen->backY;
+ } else {
+ r128ctx->drawX = r128ctx->r128Screen->fbX;
+ r128ctx->drawY = r128ctx->r128Screen->fbY;
+ r128ctx->readX = r128ctx->r128Screen->fbX;
+ r128ctx->readY = r128ctx->r128Screen->fbY;
+ }
+
+ r128ctx->ClearColor = 0x00000000;
+ r128ctx->ClearDepth = depthClear;
+
+ r128ctx->regs.scale_3d_cntl =
+ R128_SCALE_DITHER_TABLE |
+ R128_TEX_CACHE_SIZE_FULL |
+ R128_DITHER_INIT_RESET |
+ R128_SCALE_3D_TEXMAP_SHADE |
+ R128_SCALE_PIX_REPLICATE |
+ /* R128_TEX_CACHE_SPLIT | */
+ R128_ALPHA_COMB_ADD_CLAMP |
+ R128_FOG_TABLE |
+ R128_ALPHA_BLEND_SRC_ONE |
+ R128_ALPHA_BLEND_DST_ZERO |
+ R128_ALPHA_TEST_ALWAYS |
+ R128_COMPOSITE_SHADOW_CMP_EQUAL |
+ R128_TEX_MAP_ALPHA_IN_TEXTURE |
+ R128_TEX_CACHE_LINE_SIZE_8QW;
+
+ r128ctx->regs.dst_pitch_offset_c = pitch << R128_PITCH_SHIFT;
+
+ r128ctx->regs.dp_gui_master_cntl =
+ R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_DST_CLIPPING |
+ R128_GMC_BRUSH_SOLID_COLOR |
+ dst_bpp |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_GMC_BYTE_MSB_TO_LSB |
+ R128_GMC_CONVERSION_TEMP_6500 |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_MEMORY |
+ R128_GMC_3D_FCN_EN |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_AUX_CLIP_DIS |
+ R128_GMC_WR_MSK_DIS;
+
+ r128ctx->regs.sc_top_left_c = 0x00000000;
+ r128ctx->regs.sc_bottom_right_c = 0x1fff1fff;
+
+ r128ctx->regs.aux_sc_cntl = 0x00000000;
+
+ r128ctx->regs.aux1_sc_left = 0x00000000;
+ r128ctx->regs.aux1_sc_right = 0x00001fff;
+ r128ctx->regs.aux1_sc_top = 0x00000000;
+ r128ctx->regs.aux1_sc_bottom = 0x00001fff;
+
+ r128ctx->regs.aux2_sc_left = 0x00000000;
+ r128ctx->regs.aux2_sc_right = 0x00001fff;
+ r128ctx->regs.aux2_sc_top = 0x00000000;
+ r128ctx->regs.aux2_sc_bottom = 0x00001fff;
+
+ r128ctx->regs.aux3_sc_left = 0x00000000;
+ r128ctx->regs.aux3_sc_right = 0x00001fff;
+ r128ctx->regs.aux3_sc_top = 0x00000000;
+ r128ctx->regs.aux3_sc_bottom = 0x00001fff;
+
+ r128ctx->regs.z_offset_c = (r128ctx->r128Screen->depthX *
+ (r128ctx->r128Screen->bpp/8) +
+ r128ctx->r128Screen->depthY *
+ r128ctx->r128Screen->fbStride);
+ r128ctx->regs.z_pitch_c = pitch;
+
+ r128ctx->regs.z_sten_cntl_c =
+ depth_bpp |
+ R128_Z_TEST_LESS |
+ R128_STENCIL_TEST_ALWAYS |
+ R128_STENCIL_S_FAIL_KEEP |
+ R128_STENCIL_ZPASS_KEEP |
+ R128_STENCIL_ZFAIL_KEEP;
+
+ r128ctx->regs.tex_cntl_c =
+ R128_Z_WRITE_ENABLE |
+ R128_SHADE_ENABLE |
+ R128_DITHER_ENABLE |
+ R128_ALPHA_IN_TEX_COMPLETE_A |
+ R128_LIGHT_DIS |
+ R128_ALPHA_LIGHT_DIS |
+ R128_TEX_CACHE_FLUSH |
+ (0x0f << R128_LOD_BIAS_SHIFT);
+
+ r128ctx->regs.misc_3d_state_cntl_reg =
+ R128_MISC_SCALE_3D_TEXMAP_SHADE |
+ R128_MISC_SCALE_PIX_REPLICATE |
+ R128_ALPHA_COMB_ADD_CLAMP |
+ R128_FOG_TABLE |
+ R128_ALPHA_BLEND_SRC_ONE |
+ R128_ALPHA_BLEND_DST_ZERO |
+ R128_ALPHA_TEST_ALWAYS;
+
+ r128ctx->regs.texture_clr_cmp_clr_c = 0x00000000;
+ r128ctx->regs.texture_clr_cmp_msk_c = 0xffffffff;
+
+ r128ctx->regs.prim_tex_cntl_c =
+ R128_MIN_BLEND_NEAREST |
+ R128_MAG_BLEND_NEAREST |
+ R128_MIP_MAP_DISABLE |
+ R128_TEX_CLAMP_S_WRAP |
+ R128_TEX_CLAMP_T_WRAP;
+
+ r128ctx->regs.prim_texture_combine_cntl_c =
+ R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA;
+
+ r128ctx->regs.tex_size_pitch_c =
+ (0 << R128_TEX_PITCH_SHIFT) |
+ (0 << R128_TEX_SIZE_SHIFT) |
+ (0 << R128_TEX_HEIGHT_SHIFT) |
+ (0 << R128_TEX_MIN_SIZE_SHIFT) |
+ (0 << R128_SEC_TEX_PITCH_SHIFT) |
+ (0 << R128_SEC_TEX_SIZE_SHIFT) |
+ (0 << R128_SEC_TEX_HEIGHT_SHIFT) |
+ (0 << R128_SEC_TEX_MIN_SIZE_SHIFT);
+
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] = 0x00000000;
+
+ r128ctx->regs.sec_tex_cntl_c =
+ R128_SEC_SELECT_PRIM_ST;
+
+ r128ctx->regs.sec_tex_combine_cntl_c =
+ R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA;
+
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] = 0x00000000;
+
+ r128ctx->regs.constant_color_c = 0x00ffffff;
+ r128ctx->regs.prim_texture_border_color_c = 0x00ffffff;
+ r128ctx->regs.sec_texture_border_color_c = 0x00ffffff;
+ r128ctx->regs.sten_ref_mask_c = 0xffff0000;
+ r128ctx->regs.plane_3d_mask_c = 0xffffffff;
+
+ r128ctx->regs.setup_cntl =
+ R128_COLOR_GOURAUD |
+ R128_PRIM_TYPE_TRI |
+#if 1
+ /* FIXME: Let r128 multiply? */
+ R128_TEXTURE_ST_MULT_W |
+#else
+ /* FIXME: Or, pre multiply? */
+ R128_TEXTURE_ST_DIRECT |
+#endif
+ R128_STARTING_VERTEX_1 |
+ R128_ENDING_VERTEX_3 |
+ R128_SU_POLY_LINE_NOT_LAST |
+ R128_SUB_PIX_4BITS;
+
+ r128ctx->regs.pm4_vc_fpu_setup =
+ R128_FRONT_DIR_CCW |
+ R128_BACKFACE_SOLID |
+ R128_FRONTFACE_SOLID |
+ R128_FPU_COLOR_GOURAUD |
+ R128_FPU_SUB_PIX_4BITS |
+ R128_FPU_MODE_3D |
+ R128_TRAP_BITS_DISABLE |
+ R128_XFACTOR_2 |
+ R128_YFACTOR_2 |
+ R128_FLAT_SHADE_VERTEX_OGL |
+ R128_FPU_ROUND_TRUNCATE |
+ R128_WM_SEL_8DW;
+
+ r128ctx->FogMode = GL_EXP;
+ r128ctx->regs.fog_color_c = 0x00808080;
+ r128ctx->regs.fog_3d_table_start = 0x00000000;
+ r128ctx->regs.fog_3d_table_end = 0xffffffff;
+ r128ctx->regs.fog_3d_table_density = 0x00000000;
+
+ r128ctx->regs.window_xy_offset = 0x00000000;
+
+ r128ctx->regs.dp_write_mask = 0xffffffff;
+
+ r128ctx->regs.pc_gui_ctlstat = R128_PC_FLUSH_GUI;
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALL_DIRTY;
+}
+
+/* Upload the fog table for the current fog mode */
+static void r128UploadFogTable(r128ContextPtr r128ctx)
+{
+ int i;
+
+ R128CCE0(R128_CCE_PACKET0, R128_FOG_TABLE_INDEX, 0);
+ R128CCE(0x00000000);
+
+ R128CCE0(R128_CCE_PACKET0_ONE_REG_WR, R128_FOG_TABLE_DATA, 255);
+
+ switch (r128ctx->FogMode) {
+ case GL_LINEAR:
+ for (i = 0; i < 256; i++) {
+ R128CCE(255 - i);
+ }
+ break;
+ case GL_EXP:
+ for (i = 0; i < 256; i++) {
+ R128CCE(255 - FLOAT_TO_UBYTE(exp(i - 255)));
+ }
+ break;
+ case GL_EXP2:
+ for (i = 0; i < 256; i++) {
+ R128CCE(255 - FLOAT_TO_UBYTE(exp((i - 255) * (i - 255))));
+ }
+ break;
+ }
+}
+
+/* Load the current context's state into the hardware */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128LoadContext(r128ContextPtr r128ctx)
+{
+ int i;
+ int tex_size_pitch_done = GL_FALSE;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, "r128LoadContext(%p)\n", r128ctx->glCtx);
+ }
+
+#if 0
+ r128ctx->dirty_context = R128_CTX_ALL_DIRTY;
+#endif
+
+#if 1
+ /* FIXME: Why do these need to be updated even when they don't change? */
+ r128ctx->dirty_context |= (R128_CTX_MISC |
+ R128_CTX_ENGINESTATE |
+ R128_CTX_ALPHASTATE);
+#endif
+
+#if 1
+ /* FIXME: Is this _really_ needed? */
+ if (r128ctx->dirty_context)
+ if (!R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode))
+ R128CCE_WAIT_FOR_IDLE(r128ctx);
+#endif
+
+ if (r128ctx->dirty_context & R128_CTX_MISC) {
+ R128CCE1(R128_CCE_PACKET1, R128_SCALE_3D_CNTL, R128_DP_WRITE_MASK);
+ R128CCE(r128ctx->regs.scale_3d_cntl);
+ R128CCE(r128ctx->regs.dp_write_mask);
+
+ R128CCE0(R128_CCE_PACKET0, R128_DST_PITCH_OFFSET_C, 1);
+ R128CCE(r128ctx->regs.dst_pitch_offset_c);
+ R128CCE(r128ctx->regs.dp_gui_master_cntl);
+
+ R128CCE0(R128_CCE_PACKET0, R128_TEXTURE_CLR_CMP_CLR_C, 1);
+ R128CCE(r128ctx->regs.texture_clr_cmp_clr_c);
+ R128CCE(r128ctx->regs.texture_clr_cmp_msk_c);
+
+ R128CCE0(R128_CCE_PACKET0, R128_STEN_REF_MASK_C, 1);
+ R128CCE(r128ctx->regs.sten_ref_mask_c);
+ R128CCE(r128ctx->regs.plane_3d_mask_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_ENGINESTATE) {
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_TEX0STATE) {
+ R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEX_CNTL_C, 2+R128_TEX_MAXLEVELS);
+ R128CCE(r128ctx->regs.prim_tex_cntl_c);
+ R128CCE(r128ctx->regs.prim_texture_combine_cntl_c);
+ R128CCE(r128ctx->regs.tex_size_pitch_c);
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ R128CCE(r128ctx->regs.prim_tex_offset[i]);
+
+ R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEXTURE_BORDER_COLOR_C, 0);
+ R128CCE(r128ctx->regs.prim_texture_border_color_c);
+
+ tex_size_pitch_done = GL_TRUE;
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_TEX1STATE) {
+ if (!tex_size_pitch_done) {
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_SIZE_PITCH_C, 0);
+ R128CCE(r128ctx->regs.tex_size_pitch_c);
+ }
+
+ R128CCE0(R128_CCE_PACKET0, R128_SEC_TEX_CNTL_C, 1+R128_TEX_MAXLEVELS);
+ R128CCE(r128ctx->regs.sec_tex_cntl_c);
+ R128CCE(r128ctx->regs.sec_tex_combine_cntl_c);
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ R128CCE(r128ctx->regs.sec_tex_offset[i]);
+
+ R128CCE0(R128_CCE_PACKET0, R128_SEC_TEXTURE_BORDER_COLOR_C, 0);
+ R128CCE(r128ctx->regs.sec_texture_border_color_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_TEXENVSTATE) {
+ R128CCE0(R128_CCE_PACKET0, R128_CONSTANT_COLOR_C, 0);
+ R128CCE(r128ctx->regs.constant_color_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_FOGSTATE) {
+ R128CCE0(R128_CCE_PACKET0, R128_FOG_3D_TABLE_START, 1);
+ R128CCE(r128ctx->regs.fog_3d_table_start);
+ R128CCE(r128ctx->regs.fog_3d_table_end);
+
+ R128CCE1(R128_CCE_PACKET1,
+ R128_FOG_COLOR_C, R128_FOG_3D_TABLE_DENSITY);
+ R128CCE(r128ctx->regs.fog_color_c);
+ R128CCE(r128ctx->regs.fog_3d_table_density);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_FOGTABLE) {
+ r128UploadFogTable(r128ctx);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_ZSTENSTATE) {
+ R128CCE0(R128_CCE_PACKET0, R128_Z_STEN_CNTL_C, 0);
+ R128CCE(r128ctx->regs.z_sten_cntl_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_SCISSORS) {
+ R128CCE0(R128_CCE_PACKET0, R128_SC_TOP_LEFT_C, 1);
+ R128CCE(r128ctx->regs.sc_top_left_c);
+ R128CCE(r128ctx->regs.sc_bottom_right_c);
+ }
+
+ if (r128ctx->dirty_context & (R128_CTX_ALPHASTATE |
+ R128_CTX_FOGSTATE)) {
+ R128CCE0(R128_CCE_PACKET0, R128_MISC_3D_STATE_CNTL_REG, 0);
+ R128CCE(r128ctx->regs.misc_3d_state_cntl_reg);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_SETUPSTATE) {
+ R128CCE1(R128_CCE_PACKET1, R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP);
+ R128CCE(r128ctx->regs.setup_cntl);
+ R128CCE(r128ctx->regs.pm4_vc_fpu_setup);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_WIN_Z_POS) {
+ R128CCE0(R128_CCE_PACKET0, R128_WINDOW_XY_OFFSET, 0);
+ R128CCE(r128ctx->regs.window_xy_offset);
+
+ R128CCE0(R128_CCE_PACKET0, R128_Z_OFFSET_C, 1);
+ R128CCE(r128ctx->regs.z_offset_c);
+ R128CCE(r128ctx->regs.z_pitch_c);
+ }
+
+#if 0
+ if (r128ctx->dirty_context & R128_CTX_FLUSH_PIX_CACHE) {
+ R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0);
+ R128CCE(r128ctx->regs.pc_gui_ctlstat);
+ }
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ /* Turn off the texture cache flushing */
+ r128ctx->regs.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
+
+ /* Turn off the pixel cache flushing */
+ r128ctx->regs.pc_gui_ctlstat &= ~R128_PC_FLUSH_ALL;
+
+ r128ctx->dirty_context = R128_CTX_CLEAN;
+}
+
+/* Set the hardware clip rects for drawing to the current color buffer */
+/* NOTE: This function is only called while holding the hardware lock */
+void r128SetClipRects(r128ContextPtr r128ctx,
+ XF86DRIClipRectPtr pc, int nc)
+{
+ if (!pc) return;
+
+ /* Clear any previous auxiliary scissors */
+ r128ctx->regs.aux_sc_cntl = 0x00000000;
+
+ switch (nc) {
+ case 3:
+ R128CCE0(R128_CCE_PACKET0, R128_AUX3_SC_LEFT, 3);
+ R128CCE(pc[2].x1 + r128ctx->drawX);
+ R128CCE(pc[2].x2-1 + r128ctx->drawX);
+ R128CCE(pc[2].y1 + r128ctx->drawY);
+ R128CCE(pc[2].y2-1 + r128ctx->drawY);
+
+ r128ctx->regs.aux_sc_cntl |= R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR;
+
+ case 2:
+ R128CCE0(R128_CCE_PACKET0, R128_AUX2_SC_LEFT, 3);
+ R128CCE(pc[1].x1 + r128ctx->drawX);
+ R128CCE(pc[1].x2-1 + r128ctx->drawX);
+ R128CCE(pc[1].y1 + r128ctx->drawY);
+ R128CCE(pc[1].y2-1 + r128ctx->drawY);
+
+ r128ctx->regs.aux_sc_cntl |= R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR;
+
+ case 1:
+ R128CCE0(R128_CCE_PACKET0, R128_AUX1_SC_LEFT, 3);
+ R128CCE(pc[0].x1 + r128ctx->drawX);
+ R128CCE(pc[0].x2-1 + r128ctx->drawX);
+ R128CCE(pc[0].y1 + r128ctx->drawY);
+ R128CCE(pc[0].y2-1 + r128ctx->drawY);
+
+ r128ctx->regs.aux_sc_cntl |= R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR;
+ break;
+
+ default:
+ return;
+ }
+
+ R128CCE0(R128_CCE_PACKET0, R128_AUX_SC_CNTL, 0);
+ R128CCE(r128ctx->regs.aux_sc_cntl);
+
+ R128CCE_SUBMIT_PACKETS();
+}
+
+/* Update the driver's notion of the window position */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateWindowPosition(r128ContextPtr r128ctx)
+{
+ int x = r128ctx->driDrawable->x + r128ctx->drawX;
+ int y = r128ctx->driDrawable->y + r128ctx->drawY;
+
+#if 0
+ /* FIXME: Is this _really_ needed? */
+ R128CCE_FLUSH_VB(r128ctx);
+#endif
+ r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) |
+ (x << R128_WINDOW_X_SHIFT));
+
+ /* Recalculate the Z buffer offset since we might be drawing to the
+ back buffer and window_xy_offset affects both color buffer and
+ depth drawing */
+ r128ctx->regs.z_offset_c = ((r128ctx->r128Screen->depthX -
+ r128ctx->drawX) *
+ (r128ctx->r128Screen->bpp/8) +
+ (r128ctx->r128Screen->depthY -
+ r128ctx->drawY) *
+ r128ctx->r128Screen->fbStride);
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_WIN_Z_POS;
+}
+
+/* Update the hardware state */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateHWStateLocked(r128ContextPtr r128ctx)
+{
+ if (r128ctx->dirty & R128_REQUIRE_QUIESCENCE)
+ R128CCE_WAIT_FOR_IDLE(r128ctx);
+
+ /* Update any state that might have changed recently */
+
+ /* Update the clip rects */
+ if (r128ctx->dirty & R128_UPDATE_WINPOS)
+ r128UpdateWindowPosition(r128ctx);
+
+ /* Update texture state and then upload the images */
+ /* Note: Texture images can only be updated after the state has been set */
+ if (r128ctx->dirty & R128_UPDATE_TEXSTATE)
+ r128UpdateTextureState(r128ctx);
+ if (r128ctx->dirty & R128_UPDATE_TEX0IMAGES)
+ r128UploadTexImages(r128ctx, r128ctx->CurrentTexObj[0]);
+ if (r128ctx->dirty & R128_UPDATE_TEX1IMAGES)
+ r128UploadTexImages(r128ctx, r128ctx->CurrentTexObj[1]);
+
+ /* Load the state into the hardware */
+ /* Note: This must be done after all other state has been set */
+ if (r128ctx->dirty & R128_UPDATE_CONTEXT)
+ r128LoadContext(r128ctx);
+
+ r128ctx->dirty = R128_CLEAN;
+}
+
+/* Update the hardware state */
+void r128UpdateHWState(r128ContextPtr r128ctx)
+{
+ LOCK_HARDWARE(r128ctx);
+ r128UpdateHWStateLocked(r128ctx);
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+/* Update the driver's state */
+/* NOTE: This function is only called while holding the hardware lock */
+void r128UpdateState(r128ContextPtr r128ctx, int winMoved)
+{
+ R128SAREAPrivPtr sarea = r128ctx->r128Screen->SAREA;
+ int i;
+
+ if (sarea->ctxOwner != r128ctx->driContext->hHWContext) {
+ sarea->ctxOwner = r128ctx->driContext->hHWContext;
+ r128ctx->dirty_context = R128_CTX_ALL_DIRTY;
+ r128LoadContext(r128ctx);
+ }
+
+ for (i = 0; i < r128ctx->r128Screen->NRTexHeaps; i++)
+ r128AgeTextures(r128ctx, i);
+
+ if (winMoved) r128ctx->dirty |= R128_UPDATE_WINPOS;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.h b/xc/lib/GL/mesa/src/drv/r128/r128_state.h
new file mode 100644
index 000000000..f847452f0
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.h
@@ -0,0 +1,50 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_STATE_H_
+#define _R128_STATE_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128DDInitState(r128ContextPtr r128ctx);
+extern void r128DDInitStateFuncs(GLcontext *ctx);
+
+extern void r128UpdateState(r128ContextPtr r128ctx, int winMoved);
+extern void r128UpdateHWState(r128ContextPtr r128ctx);
+
+extern void r128SetClipRects(r128ContextPtr r128ctx,
+ XF86DRIClipRectPtr pc, int nc);
+
+#endif
+#endif /* _R128_STATE_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_swap.c b/xc/lib/GL/mesa/src/drv/r128/r128_swap.c
new file mode 100644
index 000000000..6b347023d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_swap.c
@@ -0,0 +1,125 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_state.h"
+#include "r128_vb.h"
+#include "r128_swap.h"
+
+/* Copy the back color buffer to the front color buffer */
+void r128SwapBuffers(r128ContextPtr r128ctx)
+{
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable;
+ int nc;
+ XF86DRIClipRectPtr c;
+ int dst_bpp;
+ CARD32 swapAge;
+
+ if (r128ctx->SWonly) {
+ /* FIXME: Provide software fallback for this case?? */
+ }
+
+ switch (r128ctx->r128Screen->bpp) {
+ case 8:
+ dst_bpp = R128_GMC_DST_8BPP_CI;
+ break;
+ case 16:
+ if (r128ctx->r128Screen->depth == 15) dst_bpp = R128_GMC_DST_15BPP;
+ else dst_bpp = R128_GMC_DST_16BPP;
+ break;
+ case 24:
+ dst_bpp = R128_GMC_DST_24BPP;
+ break;
+ case 32:
+ default:
+ dst_bpp = R128_GMC_DST_32BPP;
+ break;
+ }
+
+ LOCK_HARDWARE(r128ctx);
+
+ /* Flush any outstanding vertex buffers */
+ R128CCE_FLUSH_VB(r128ctx);
+
+ /* Throttle the frame rate -- only allow one pending swap buffers
+ request at a time */
+ while (r128ctx->lastSwapAge > (swapAge = INREG(R128_SWAP_AGE_REG)));
+
+ /* Init the clip rects here in case they changed during the
+ LOCK_HARDWARE macro */
+ c = dPriv->pClipRects;
+ nc = dPriv->numClipRects;
+
+ /* Cycle through the clip rects */
+ while (nc--) {
+ int fx = c[nc].x1;
+ int fy = c[nc].y1;
+ int fw = c[nc].x2 - fx;
+ int fh = c[nc].y2 - fy;
+ int bx = fx + r128ctx->r128Screen->backX;
+ int by = fy + r128ctx->r128Screen->backY;
+
+ fx += r128ctx->r128Screen->fbX;
+ fy += r128ctx->r128Screen->fbY;
+
+ R128CCE3(R128_CCE_PACKET3_CNTL_BITBLT_MULTI, 3);
+ R128CCE(R128_GMC_BRUSH_NONE
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_DP_SRC_SOURCE_MEMORY
+ | dst_bpp
+ | R128_ROP3_S);
+ R128CCE((bx << 16) | by);
+ R128CCE((fx << 16) | fy);
+ R128CCE((fw << 16) | fh);
+ }
+
+ ++swapAge;
+ R128CCE0(R128_CCE_PACKET0, R128_SWAP_AGE_REG, 0);
+ R128CCE(swapAge);
+ r128ctx->lastSwapAge = swapAge;
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALL_DIRTY;
+
+ R128CCE_SUBMIT_PACKETS();
+
+ UNLOCK_HARDWARE(r128ctx);
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_swap.h b/xc/lib/GL/mesa/src/drv/r128/r128_swap.h
new file mode 100644
index 000000000..32851041c
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_swap.h
@@ -0,0 +1,43 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_SWAP_H_
+#define _R128_SWAP_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128SwapBuffers(r128ContextPtr r128ctx);
+
+#endif
+#endif /* _R128_SWAP_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
new file mode 100644
index 000000000..6a82a527e
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
@@ -0,0 +1,1852 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_state.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_vb.h"
+#include "r128_tex.h"
+
+#include "mmath.h"
+#include "simple_list.h"
+
+static void r128SetTexWrap(r128TexObjPtr t, GLenum srwap, GLenum twrap);
+static void r128SetTexFilter(r128TexObjPtr t, GLenum minf, GLenum magf);
+static void r128SetTexBorderColor(r128TexObjPtr t, GLubyte c[4]);
+
+/* Allocate and initialize hardware state associated with texture `t' */
+/* NOTE: This function is only called while holding the hardware lock */
+static r128TexObjPtr r128CreateTexObj(r128ContextPtr r128ctx,
+ struct gl_texture_object *tObj)
+{
+ r128TexObjPtr t;
+ struct gl_texture_image *image;
+ int log2Pitch, log2Height, log2Size, log2MinSize;
+ int totalSize;
+ int i;
+
+ image = tObj->Image[0];
+ if (!image) return NULL; /* ERROR!!! */
+
+ t = (r128TexObjPtr)calloc(1,sizeof(*t));
+ if (!t) return NULL; /* ERROR!!! */
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API)
+ fprintf(stderr, "r128CreateTexObj(%p)\n", tObj);
+
+ switch (image->Format) {
+ case GL_RGBA:
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ if (r128ctx->r128Screen->bpp == 32) {
+ t->texelBytes = 4;
+ t->textureFormat = R128_DATATYPE_ARGB8888;
+ } else {
+ t->texelBytes = 2;
+ t->textureFormat = R128_DATATYPE_ARGB4444;
+ }
+ break;
+
+ case GL_RGB:
+ if (r128ctx->r128Screen->bpp == 32) {
+ t->texelBytes = 4;
+ t->textureFormat = R128_DATATYPE_ARGB8888;
+ } else {
+ t->texelBytes = 2;
+ t->textureFormat = R128_DATATYPE_RGB565;
+ }
+ break;
+
+ case GL_LUMINANCE:
+ if (r128ctx->r128Screen->bpp == 32) {
+ t->texelBytes = 4;
+ t->textureFormat = R128_DATATYPE_ARGB8888;
+ } else {
+ t->texelBytes = 2;
+ /* Use this to get true greys */
+ t->textureFormat = R128_DATATYPE_ARGB1555;
+ }
+ break;
+
+ case GL_COLOR_INDEX:
+ t->texelBytes = 1;
+ t->textureFormat = R128_DATATYPE_CI8;
+ break;
+
+ default:
+ /* ERROR!!! */
+ fprintf(stderr, "r128CreateTexObj: bad image->Format\n");
+ free(t);
+ return NULL;
+ }
+
+ /* Calculate dimensions in log domain */
+ for (i = 1, log2Height = 0; i < image->Height; i *= 2) log2Height++;
+ for (i = 1, log2Pitch = 0; i < image->Width; i *= 2) log2Pitch++;
+ if (image->Width > image->Height) log2Size = log2Pitch;
+ else log2Size = log2Height;
+
+ t->dirty_images = 0;
+
+ /* Calculate mipmap offsets and dimensions */
+ totalSize = 0;
+ for (i = 0; i <= log2Size && tObj->Image[i]; i++) {
+ t->image[i].offset = totalSize;
+ t->image[i].width = tObj->Image[i]->Width;
+ t->image[i].height = tObj->Image[i]->Height;
+ t->dirty_images |= 1 << i;
+ totalSize += (tObj->Image[i]->Height *
+ tObj->Image[i]->Width *
+ t->texelBytes);
+
+ /* Offsets must be 32-byte aligned for host data blits */
+ totalSize = (totalSize + 31) & ~31;
+ }
+ log2MinSize = log2Size - i + 1;
+
+ t->totalSize = totalSize;
+ t->internFormat = image->IntFormat;
+
+ t->bound = 0;
+ t->heap = 0; /* This is set in r128UploadTexImages */
+ t->tObj = tObj;
+
+ t->memBlock = NULL;
+ t->bufAddr = NULL;
+
+ t->regs.tex_cntl = t->textureFormat;
+ t->regs.size_pitch = ((log2Pitch << R128_TEX_PITCH_SHIFT) |
+ (log2Size << R128_TEX_SIZE_SHIFT) |
+ (log2Height << R128_TEX_HEIGHT_SHIFT) |
+ (log2MinSize << R128_TEX_MIN_SIZE_SHIFT));
+ t->regs.border_color = 0x00000000;
+
+ if (log2MinSize == log2Size ||
+ log2MinSize != 0)
+ t->regs.tex_cntl |= R128_MIP_MAP_DISABLE;
+
+ r128SetTexWrap(t, tObj->WrapS, tObj->WrapT);
+ r128SetTexFilter(t, tObj->MinFilter, tObj->MagFilter);
+ r128SetTexBorderColor(t, tObj->BorderColor);
+
+ tObj->DriverData = t;
+
+ make_empty_list(t);
+
+ return t;
+}
+
+/* Destroy hardware state associated with texture `t' */
+/* NOTE: This function can be called while holding the hardware lock and
+ while not holding the lock*/
+void r128DestroyTexObj(r128ContextPtr r128ctx, r128TexObjPtr t)
+{
+ if (!t) return;
+
+ if (t->memBlock) {
+ mmFreeMem(t->memBlock);
+ t->memBlock = NULL;
+ }
+
+ if (t->tObj) t->tObj->DriverData = NULL;
+ if (t->bound) r128ctx->CurrentTexObj[t->bound-1] = NULL;
+
+ remove_from_list(t);
+ free(t);
+}
+
+/* Keep track of swapped out texture objects */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128SwapOutTexObj(r128ContextPtr r128ctx, r128TexObjPtr t)
+{
+ if (t->memBlock) {
+ mmFreeMem(t->memBlock);
+ t->memBlock = NULL;
+ }
+
+ t->dirty_images = ~0;
+ move_to_tail(&r128ctx->SwappedOut, t);
+}
+
+/* Print out debugging information about texture LRU */
+void r128PrintLocalLRU(r128ContextPtr r128ctx, int heap)
+{
+ r128TexObjPtr t;
+ int sz = 1 << (r128ctx->r128Screen->log2TexGran[heap]);
+
+ foreach(t, &r128ctx->TexObjList[heap]) {
+ if (!t->tObj) {
+ fprintf(stderr, "Placeholder %d at 0x%x sz 0x%x\n",
+ t->memBlock->ofs / sz,
+ t->memBlock->ofs,
+ t->memBlock->size);
+ } else {
+ fprintf(stderr, "Texture (bound %d) at 0x%x sz 0x%x\n",
+ t->bound,
+ t->memBlock->ofs,
+ t->memBlock->size);
+ }
+ }
+}
+
+void r128PrintGlobalLRU(r128ContextPtr r128ctx, int heap)
+{
+ R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap];
+ int i, j;
+
+ for (i = 0, j = R128_NR_TEX_REGIONS ; i < R128_NR_TEX_REGIONS ; i++) {
+ fprintf(stderr, "list[%d] age %d next %d prev %d\n",
+ j, list[j].age, list[j].next, list[j].prev);
+ j = list[j].next;
+ if (j == R128_NR_TEX_REGIONS) break;
+ }
+
+ if (j != R128_NR_TEX_REGIONS) {
+ fprintf(stderr, "Loop detected in global LRU\n");
+ }
+}
+
+/* Reset the global texture LRU */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128ResetGlobalLRU(r128ContextPtr r128ctx, int heap)
+{
+ R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap];
+ int log2sz = 1 << r128ctx->r128Screen->log2TexGran[heap];
+ int i;
+
+ /*
+ * (Re)initialize the global circular LRU list. The last element in
+ * the array (R128_NR_TEX_REGIONS) is the sentinal. Keeping it at
+ * the end of the array allows it to be addressed rationally when
+ * looking up objects at a particular location in texture memory.
+ */
+
+ for (i = 0; (i+1) * log2sz <= r128ctx->r128Screen->texSize[heap]; i++) {
+ list[i].prev = i-1;
+ list[i].next = i+1;
+ list[i].age = 0;
+ }
+
+ i--;
+ list[0].prev = R128_NR_TEX_REGIONS;
+ list[i].prev = i-1;
+ list[i].next = R128_NR_TEX_REGIONS;
+ list[R128_NR_TEX_REGIONS].prev = i;
+ list[R128_NR_TEX_REGIONS].next = 0;
+ r128ctx->r128Screen->SAREA->texAge[heap] = 0;
+}
+
+/* Update the local and glock texture LRUs */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateTexLRU(r128ContextPtr r128ctx, r128TexObjPtr t)
+{
+ int heap = t->heap;
+ R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap];
+ int log2sz = r128ctx->r128Screen->log2TexGran[heap];
+
+ int start = t->memBlock->ofs >> log2sz;
+ int end = (t->memBlock->ofs + t->memBlock->size-1) >> log2sz;
+ int i;
+
+ r128ctx->lastTexAge[heap] = ++r128ctx->r128Screen->SAREA->texAge[heap];
+
+ /* Update our local LRU */
+ move_to_head(&r128ctx->TexObjList[heap], t);
+
+ /* Update the global LRU */
+ for (i = start ; i <= end ; i++) {
+ list[i].in_use = 1;
+ list[i].age = r128ctx->lastTexAge[heap];
+
+ /* remove_from_list(i) */
+ list[(CARD32)list[i].next].prev = list[i].prev;
+ list[(CARD32)list[i].prev].next = list[i].next;
+
+ /* insert_at_head(list, i) */
+ list[i].prev = R128_NR_TEX_REGIONS;
+ list[i].next = list[R128_NR_TEX_REGIONS].next;
+ list[(CARD32)list[R128_NR_TEX_REGIONS].next].prev = i;
+ list[R128_NR_TEX_REGIONS].next = i;
+ }
+}
+
+/* Update our notion of what textures have been changed since we last
+ held the lock. This pertains to both our local textures and the
+ textures belonging to other clients. Keep track of other client's
+ textures by pushing a placeholder texture onto the LRU list -- these
+ are denoted by (tObj == NULL). */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128TexturesGone(r128ContextPtr r128ctx, int heap,
+ int offset, int size, int in_use)
+{
+ r128TexObjPtr t, tmp;
+
+ foreach_s (t, tmp, &r128ctx->TexObjList[heap]) {
+ if (t->memBlock->ofs >= offset + size ||
+ t->memBlock->ofs + t->memBlock->size <= offset)
+ continue;
+
+ /* It overlaps - kick it out. Need to hold onto the currently
+ bound objects, however. */
+ if (t->bound) r128SwapOutTexObj(r128ctx, t);
+ else r128DestroyTexObj(r128ctx, t);
+ }
+
+ if (in_use) {
+ t = (r128TexObjPtr) calloc(1,sizeof(*t));
+ if (!t) return;
+
+ t->memBlock = mmAllocMem(r128ctx->texHeap[heap], size, 0, offset);
+ insert_at_head(&r128ctx->TexObjList[heap], t);
+ }
+}
+
+/* Update our client's shared texture state. If another client has
+ modified a region in which we have textures, then we need to figure
+ out which of our textures has been removed, and update our global
+ LRU. */
+void r128AgeTextures(r128ContextPtr r128ctx, int heap)
+{
+ R128SAREAPrivPtr sarea = r128ctx->r128Screen->SAREA;
+
+ if (sarea->texAge[heap] != r128ctx->lastTexAge[heap]) {
+ int log2sz = 1 << r128ctx->r128Screen->log2TexGran[heap];
+ int nr = 0;
+ int idx;
+
+ for (idx = sarea->texList[heap][R128_NR_TEX_REGIONS].prev;
+ idx != R128_NR_TEX_REGIONS && nr < R128_NR_TEX_REGIONS;
+ idx = sarea->texList[heap][idx].prev, nr++) {
+
+ /* If switching texturing schemes, then the SAREA might not
+ have been properly cleared, so we need to reset the
+ global texture LRU. */
+ if (idx * log2sz > r128ctx->r128Screen->texSize[heap]) {
+ nr = R128_NR_TEX_REGIONS;
+ break;
+ }
+
+ if (sarea->texList[heap][idx].age > r128ctx->lastTexAge[heap])
+ r128TexturesGone(r128ctx, heap, idx * log2sz, log2sz,
+ sarea->texList[heap][idx].in_use);
+ }
+
+ if (nr == R128_NR_TEX_REGIONS) {
+ r128TexturesGone(r128ctx, heap,
+ 0, r128ctx->r128Screen->texSize[heap], 0);
+ r128ResetGlobalLRU(r128ctx, heap);
+ }
+
+ r128ctx->dirty |= R128_UPDATE_TEX0IMAGES;
+ r128ctx->dirty |= R128_UPDATE_TEX1IMAGES;
+ r128ctx->lastTexAge[heap] = sarea->texAge[heap];
+ }
+}
+
+/* Convert a block of Mesa-formatted texture to an 8bpp hardware format */
+static void r128ConvertTexture8bpp(r128ContextPtr r128ctx,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height,
+ int pitch)
+{
+ CARD8 *src;
+ CARD32 pix;
+ int i, j;
+
+ switch (image->Format) {
+ case GL_RGB:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
+ for (j = width >> 2; j; j--) {
+ pix = ((R128PACKCOLOR332( src[0], src[1], src[2]) ) |
+ (R128PACKCOLOR332( src[3], src[4], src[5]) << 8) |
+ (R128PACKCOLOR332( src[6], src[7], src[8]) << 16) |
+ (R128PACKCOLOR332( src[9], src[10], src[11]) << 24));
+ R128CCE(pix);
+ src += 12;
+ }
+ }
+ break;
+
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width >> 2; j; j--) {
+ pix = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+ R128CCE(pix);
+ src += 4;
+ }
+ }
+ break;
+
+ default:
+ fprintf(stderr, "r128ConvertTexture8bpp: unsupported format 0x%x\n",
+ image->Format);
+ }
+}
+
+/* Convert a block of Mesa-formatted texture to a 16bpp hardware format */
+static void r128ConvertTexture16bpp(r128ContextPtr r128ctx,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height,
+ int pitch)
+{
+ CARD8 *src;
+ CARD32 pix;
+ int i, j;
+
+ switch (image->Format) {
+ case GL_RGB:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
+ for (j = width >> 1; j; j--) {
+ pix = ((R128PACKCOLOR565(src[0], src[1], src[2]) ) |
+ (R128PACKCOLOR565(src[3], src[4], src[5]) << 16));
+ R128CCE(pix);
+ src += 6;
+ }
+ }
+ break;
+
+ case GL_RGBA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4;
+ for (j = width >> 1; j; j--) {
+ pix =
+ ((R128PACKCOLOR4444(src[0], src[1], src[2], src[3]) ) |
+ (R128PACKCOLOR4444(src[4], src[5], src[6], src[7])<<16));
+ R128CCE(pix);
+ src += 8;
+ }
+ }
+ break;
+
+ case GL_ALPHA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width >> 1; j; j--) {
+ pix = ((R128PACKCOLOR4444(0xff, 0xff, 0xff, src[0]) ) |
+ (R128PACKCOLOR4444(0xff, 0xff, 0xff, src[1]) << 16));
+ R128CCE(pix);
+ src += 2;
+ }
+ }
+ break;
+
+ case GL_LUMINANCE:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width >> 1; j; j--) {
+ pix = ((R128PACKCOLOR1555(src[0], src[0], src[0], 0xff) ) |
+ (R128PACKCOLOR1555(src[1], src[1], src[1], 0xff)<<16));
+ R128CCE(pix);
+ src += 2;
+ }
+ }
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2;
+ for (j = width >> 1; j; j--) {
+ pix =
+ ((R128PACKCOLOR4444(src[0], src[0], src[0], src[1]) ) |
+ (R128PACKCOLOR4444(src[2], src[2], src[2], src[3])<<16));
+ R128CCE(pix);
+ src += 4;
+ }
+ }
+ break;
+
+ case GL_INTENSITY:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width >> 1; j; j--) {
+ pix =
+ ((R128PACKCOLOR4444(src[0], src[0], src[0], src[0]) ) |
+ (R128PACKCOLOR4444(src[1], src[1], src[1], src[1])<<16));
+ R128CCE(pix);
+ src += 2;
+ }
+ }
+ break;
+
+ default:
+ fprintf(stderr, "r128ConvertTexture16bpp: unsupported format 0x%x\n",
+ image->Format);
+ }
+}
+
+/* Convert a block of Mesa-formatted texture to a 32bpp hardware format */
+static void r128ConvertTexture32bpp(r128ContextPtr r128ctx,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height,
+ int pitch)
+{
+ CARD8 *src;
+ CARD32 pix;
+ int i, j;
+
+ switch (image->Format) {
+ case GL_RGB:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
+ for (j = width; j; j--) {
+ pix = R128PACKCOLOR8888(src[0], src[1], src[2], 0xff);
+ R128CCE(pix);
+ src += 3;
+ }
+ }
+ break;
+
+ case GL_RGBA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4;
+ for (j = width; j; j--) {
+ pix = R128PACKCOLOR8888(src[0], src[1], src[2], src[3]);
+ R128CCE(pix);
+ src += 4;
+ }
+ }
+ break;
+
+ case GL_ALPHA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width; j; j--) {
+ pix = R128PACKCOLOR8888(0xff, 0xff, 0xff, src[0]);
+ R128CCE(pix);
+ src += 1;
+ }
+ }
+ break;
+
+ case GL_LUMINANCE:
+ for (i = 0 ; i < height ; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width; j; j--) {
+ pix = R128PACKCOLOR8888(src[0], src[0], src[0], 0xff);
+ R128CCE(pix);
+ src += 1;
+ }
+ }
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2;
+ for (j = width; j; j-- ) {
+ pix = R128PACKCOLOR8888(src[0], src[0], src[0], src[1]);
+ R128CCE(pix);
+ src += 2;
+ }
+ }
+ break;
+
+ case GL_INTENSITY:
+ for (i = 0; i < height; i++) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for (j = width; j; j--) {
+ pix = R128PACKCOLOR8888(src[0], src[0], src[0], src[0]);
+ R128CCE(pix);
+ src += 1;
+ }
+ }
+ break;
+
+ default:
+ fprintf(stderr, "r128ConvertTexture32bpp: unsupported format 0x%x\n",
+ image->Format);
+ }
+}
+
+/* Upload the texture image associated with texture `t' at level `level'
+ at the address relative to `start'. */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UploadSubImage(r128ContextPtr r128ctx,
+ r128TexObjPtr t, int level,
+ int x, int y, int width, int height)
+{
+ struct gl_texture_image *image;
+ int texelsPerDword = 0;
+ int imageWidth, imageHeight;
+ int remaining, rows;
+ int format, pitch, dwords;
+ CARD32 offset;
+
+ /* Ensure we have a valid texture to upload */
+ if (level < 0 || level > R128_TEX_MAXLEVELS) return;
+ if (!(image = t->tObj->Image[level])) return;
+
+ /* FIXME: support RGB888 (i.e., 24bpp) textures? */
+ switch (t->texelBytes) {
+ case 1: texelsPerDword = 4; break;
+ case 2: texelsPerDword = 2; break;
+ case 4: texelsPerDword = 1; break;
+ }
+
+ imageWidth = image->Width;
+ imageHeight = image->Height;
+
+ format = t->textureFormat >> 16;
+
+ /* The texel upload routines have a minimum width, so force the size
+ if needed */
+ if (imageWidth < texelsPerDword) {
+ int factor;
+
+ factor = texelsPerDword / imageWidth;
+ imageWidth = texelsPerDword;
+ imageHeight /= factor;
+ if (imageHeight == 0) {
+ /* In this case, the texel converter will actually walk a
+ texel or two off the end of the image, but normal malloc
+ alignment should prevent it from ever causing a fault. */
+ imageHeight = 1;
+ }
+ }
+
+ /* We can't upload to a pitch less than 8 texels so we will need to
+ linearly upload all modified rows for textures smaller than this.
+ This makes the x/y/width/height different for the blitter and the
+ texture walker. */
+ if (imageWidth >= 8) {
+ /* The texture walker and the blitter look identical */
+ pitch = imageWidth >> 3;
+ } else {
+ int factor;
+ int y2;
+ int start, end;
+
+ start = (y * imageWidth) & ~7;
+ end = (y + height) * imageWidth;
+
+ if (end - start < 8) {
+ /* Handle the case where the total number of texels uploaded
+ is < 8 */
+ x = 0;
+ y = start / 8;
+ width = end - start;
+ height = 1;
+ } else {
+ /* Upload some number of full 8 texel blit rows */
+ factor = 8 / imageWidth;
+
+ y2 = y + height - 1;
+ y /= factor;
+ y2 /= factor;
+
+ x = 0;
+ width = 8;
+ height = y2 - y + 1;
+ }
+
+ /* Fixed pitch of 8 */
+ pitch = 1;
+ }
+
+ dwords = width * height / texelsPerDword;
+ offset = (CARD32)(t->bufAddr + t->image[level].offset);
+
+ /* Fix offset for AGP textures */
+ if (t->heap == R128_AGP_TEX_HEAP)
+ offset += R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, "r128UploadSubImage: %d,%d of %d,%d at %d,%d\n",
+ width, height, image->Width, image->Height, x, y);
+ fprintf(stderr, " blit ofs: 0x%08x pitch: 0x%x dwords: %d "
+ "level: %d format: %x\n",
+ (int)offset, pitch, dwords, level, format);
+ }
+
+#define R128_MAX_BLIT_DWORDS 8192
+ /* Subdivide the texture if required */
+ if (dwords < R128_MAX_BLIT_DWORDS) {
+ rows = height;
+ } else {
+ rows = (R128_MAX_BLIT_DWORDS * texelsPerDword) / (2 * width);
+ }
+
+ /* Flush the pixel cache, and mark the contents as Read Invalid */
+ R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0);
+ R128CCE(r128ctx->regs.pc_gui_ctlstat |
+ R128_PC_RI_GUI |
+ R128_PC_FLUSH_GUI);
+ R128CCE_SUBMIT_PACKETS();
+
+ /* Build the CCE host data blit header */
+ R128CCE3(R128_CCE_PACKET3_CNTL_HOSTDATA_BLT, 0);
+
+ /* DP_GUI_MASTER_CNTL */
+ R128CCE(R128_GMC_DST_PITCH_OFFSET_CNTL |
+ R128_GMC_BRUSH_NONE |
+ (format << 8) |
+ R128_GMC_SRC_DATATYPE_COLOR |
+ R128_ROP3_S |
+ R128_DP_SRC_SOURCE_HOST_DATA |
+ R128_GMC_CLR_CMP_CNTL_DIS |
+ R128_AUX_CLIP_DIS |
+ R128_GMC_WR_MSK_DIS );
+
+ /* DST_OFFSET_PITCH - fixed at the moment until we get better ring
+ control */
+ R128CCE((pitch << 21) | (offset>>5));
+
+ /* FRGD_COLOR, BKGD_COLOR */
+ R128CCE(0xffffffff);
+ R128CCE(0xffffffff);
+
+ for (remaining = height; remaining > 0; remaining -= rows, y += rows) {
+ height = (remaining >= rows) ? rows : remaining;
+ dwords = width * height / texelsPerDword;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) {
+ fprintf(stderr, " blitting: %d,%d at %d,%d - %d dwords\n",
+ width, height, x, y, dwords);
+ }
+
+ r128ctx->CCEbuf[0] &= ~R128_CCE_PACKET_COUNT_MASK;
+ r128ctx->CCEbuf[0] |= (dwords + 6) << 16;
+
+ /* Blit coords, size */
+ R128CCE((y << 16) | x);
+ R128CCE((height << 16) | width);
+ R128CCE(dwords);
+
+ /* Actually do the texture conversion */
+ switch (t->texelBytes) {
+ case 1:
+ r128ConvertTexture8bpp(r128ctx, image,
+ x, y, width, height, width);
+ break;
+ case 2:
+ r128ConvertTexture16bpp(r128ctx, image,
+ x, y, width, height, width);
+ break;
+ case 4:
+ r128ConvertTexture32bpp(r128ctx,
+ image, x, y, width, height, width);
+ break;
+ }
+
+ /* Flush the pixel cache */
+ R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0 );
+ R128CCE(r128ctx->regs.pc_gui_ctlstat | R128_PC_FLUSH_GUI);
+
+ /* Save the partial blit header */
+ R128CCE_SUBMIT_PACKETS();
+ r128ctx->CCEcount = 5;
+ }
+
+ /* Clean up CCE ring buffer */
+ r128ctx->CCEcount = 0;
+}
+
+/* Upload the texture images associated with texture `t'. This might
+ require removing our own and/or other client's texture objects to
+ make room for these images. */
+/* NOTE: This function is only called while holding the hardware lock */
+int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t)
+{
+ int i;
+ int minLevel;
+ int maxLevel;
+ int heap;
+
+ if (!t) return 0;
+
+ /* Choose the heap appropriately */
+ heap = t->heap = R128_LOCAL_TEX_HEAP;
+ if (!r128ctx->r128Screen->IsPCI &&
+ t->totalSize > r128ctx->r128Screen->texSize[heap])
+ heap = t->heap = R128_AGP_TEX_HEAP;
+
+ /* Do we need to eject LRU texture objects? */
+ if (!t->memBlock) {
+ /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */
+ t->memBlock = mmAllocMem(r128ctx->texHeap[heap], t->totalSize, 12, 0);
+
+ /* Try AGP before kicking anything out of local mem */
+ if (!t->memBlock && heap == R128_LOCAL_TEX_HEAP) {
+ t->memBlock = mmAllocMem(r128ctx->texHeap[R128_AGP_TEX_HEAP],
+ t->totalSize, 12, 0);
+
+ if (t->memBlock) heap = t->heap = R128_AGP_TEX_HEAP;
+ }
+
+ /* Kick out textures until the requested texture fits */
+ while (!t->memBlock) {
+ if (r128ctx->TexObjList[heap].prev->bound) {
+ fprintf(stderr,
+ "r128UploadTexImages: ran into bound texture\n");
+ return -1;
+ }
+ if (r128ctx->TexObjList[heap].prev ==
+ &(r128ctx->TexObjList[heap])) {
+ if (r128ctx->r128Screen->IsPCI) {
+ fprintf(stderr, "r128UploadTexImages: upload texture "
+ "failure on local texture heaps, sz=%d\n",
+ t->totalSize);
+ return -1;
+ } else if (heap == R128_LOCAL_TEX_HEAP) {
+ heap = t->heap = R128_AGP_TEX_HEAP;
+ continue;
+ } else {
+ fprintf(stderr, "r128UploadTexImages: upload texture "
+ "failure on both local and AGP texture heaps, "
+ "sz=%d\n",
+ t->totalSize);
+ return -1;
+ }
+ }
+
+ r128DestroyTexObj(r128ctx, r128ctx->TexObjList[heap].prev);
+
+ t->memBlock = mmAllocMem(r128ctx->texHeap[heap],
+ t->totalSize, 12, 0);
+ }
+
+ /* Set the base offset of the texture image */
+ t->bufAddr = (unsigned char *)r128ctx->r128Screen->texOffset[heap];
+ t->bufAddr += t->memBlock->ofs;
+
+ maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >>
+ R128_TEX_SIZE_SHIFT);
+ minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >>
+ R128_TEX_MIN_SIZE_SHIFT);
+
+ /* Update the hardware's texture image addresses */
+ switch (t->bound) {
+ case 1:
+ /* Set texture offsets */
+ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) {
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] = (CARD32)t->bufAddr;
+ } else {
+ for (i = maxLevel; i >= minLevel; i--)
+ r128ctx->regs.prim_tex_offset[i] =
+ t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
+ }
+ /* Fix AGP texture offsets */
+ if (heap == R128_AGP_TEX_HEAP)
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] +=
+ R128_AGP_TEX_OFFSET +
+ r128ctx->r128Screen->agpTexOffset;
+ /* Force loading the new state into the hardware */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX0STATE;
+ break;
+
+ case 2:
+ /* Set texture offsets */
+ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) {
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] = (CARD32)t->bufAddr;
+ } else {
+ for (i = maxLevel; i >= minLevel; i--)
+ r128ctx->regs.sec_tex_offset[i] =
+ t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
+ }
+ /* Fix AGP texture offsets */
+ if (heap == R128_AGP_TEX_HEAP)
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] +=
+ R128_AGP_TEX_OFFSET +
+ r128ctx->r128Screen->agpTexOffset;
+ /* Force loading the new state into the hardware */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX1STATE;
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
+ /* Let the world know we've used this memory recently */
+ r128UpdateTexLRU(r128ctx, t);
+
+ /* Upload any images that are new */
+ if (t->dirty_images) {
+ int num_levels = (((t->regs.size_pitch & R128_TEX_SIZE_MASK) >>
+ R128_TEX_SIZE_SHIFT) -
+ ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >>
+ R128_TEX_MIN_SIZE_SHIFT));
+
+ for (i = 0; i <= num_levels; i++) {
+ if (t->dirty_images & (1<<i)) {
+ r128UploadSubImage(r128ctx, t, i, 0, 0,
+ t->image[i].width, t->image[i].height);
+ }
+ }
+
+ r128ctx->regs.tex_cntl_c |= R128_TEX_CACHE_FLUSH;
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ENGINESTATE;
+ }
+
+ t->dirty_images = 0;
+ return 0;
+}
+
+/* Update the hardware state for texture unit 0 */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateTex0State(r128ContextPtr r128ctx)
+{
+ GLcontext *ctx = r128ctx->glCtx;
+ r128TexObjPtr t;
+ struct gl_texture_object *tObj;
+ int i;
+ CARD32 tex_size_pitch, tex_combine_cntl;
+
+ /* Only update the hardware texture state if the texture is current,
+ complete and enabled. */
+ if (!(tObj = ctx->Texture.Unit[0].Current)) return;
+ if ((tObj != ctx->Texture.Unit[0].CurrentD[2]) &&
+ (tObj != ctx->Texture.Unit[0].CurrentD[1])) return;
+ if (!tObj->Complete) return;
+
+ /* If neither tex0 nor tex1 is enabled, then disable tex0. However,
+ if tex1 is enabled but tex0 is disabled, then we need to enable
+ tex0 and have it to copy the input (see how tex_combine_cntl is
+ setup below). */
+ if (!(ctx->Texture.Enabled & (ENABLE_TEX0 | ENABLE_TEX1))) {
+ r128ctx->regs.tex_cntl_c &= ~R128_TEXMAP_ENABLE;
+ return;
+ }
+
+ /* If this is the first time the texture has been used, then create
+ a new texture object for it. */
+ t = tObj->DriverData;
+ if (!t) t = r128CreateTexObj(r128ctx, tObj);
+ if (!t) return;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API)
+ fprintf(stderr, "r128UpdateTex0State(%p, 0x%08x)\n",
+ tObj, (int)t->dirty_images);
+
+ /* Force any texture images to be loaded into the hardware */
+ if (t->dirty_images) r128ctx->dirty |= R128_UPDATE_TEX0IMAGES;
+
+ /* Bind texture to texture 0 unit */
+ r128ctx->CurrentTexObj[0] = t;
+ t->bound = 1;
+
+ if (t->memBlock) r128UpdateTexLRU(r128ctx, t);
+
+ /* Set the texture environment state */
+ switch (ctx->Texture.Unit[0].EnvMode) {
+ case GL_REPLACE:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_BLEND:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ switch (r128ctx->regs.constant_color_c &
+ R128_CONSTANT_COLOR_MASK) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ switch (r128ctx->regs.constant_color_c &
+ R128_CONSTANT_COLOR_MASK) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_INTENSITY:
+ switch (r128ctx->regs.constant_color_c &
+ R128_CONSTANT_COLOR_MASK) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_NTEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_MODULATE:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_DECAL:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ tex_combine_cntl = (R128_COMB_BLEND_TEXTURE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_RGB:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ /* Undefined behaviour - just copy the input */
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_ADD:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_ADD |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_ADD |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ /* If tex0 is disabled, then make sure it just copies the input */
+ if (!(ctx->Texture.Enabled & ENABLE_TEX0))
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_INT_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_INT_ALPHA);
+
+ /* Enable tex0 */
+ r128ctx->regs.tex_cntl_c |= R128_TEXMAP_ENABLE;
+
+ tex_size_pitch = r128ctx->regs.tex_size_pitch_c;
+ tex_size_pitch &= ~R128_TEX_SIZE_PITCH_MASK;
+ tex_size_pitch |= t->regs.size_pitch << R128_TEX_SIZE_PITCH_SHIFT;
+
+ /* Set the primary texture state in r128ctx->regs */
+ r128ctx->regs.prim_tex_cntl_c = t->regs.tex_cntl;
+ r128ctx->regs.prim_texture_combine_cntl_c = tex_combine_cntl;
+ r128ctx->regs.tex_size_pitch_c = tex_size_pitch;
+ r128ctx->regs.prim_texture_border_color_c = t->regs.border_color;
+
+ /* Set texture offsets */
+ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) {
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] = (CARD32)t->bufAddr;
+ } else {
+ int maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >>
+ R128_TEX_SIZE_SHIFT);
+ int minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >>
+ R128_TEX_MIN_SIZE_SHIFT);
+ for (i = maxLevel; i >= minLevel; i--)
+ r128ctx->regs.prim_tex_offset[i] =
+ t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
+ }
+ /* Fix AGP texture offsets */
+ if (t->heap == R128_AGP_TEX_HEAP)
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] +=
+ R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset;
+
+ /* Force loading the new state into the hardware */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX0STATE | R128_CTX_ENGINESTATE;
+}
+
+/* Update the hardware state for texture unit 1 */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateTex1State(r128ContextPtr r128ctx)
+{
+ GLcontext *ctx = r128ctx->glCtx;
+ r128TexObjPtr t;
+ struct gl_texture_object *tObj;
+ int i;
+ CARD32 tex_size_pitch, tex_combine_cntl, tex_cntl;
+
+ /* Only update the hardware texture state if the texture is current,
+ complete and enabled. */
+ if (!(tObj = ctx->Texture.Unit[1].Current)) return;
+ if ((tObj != ctx->Texture.Unit[1].CurrentD[2]) &&
+ (tObj != ctx->Texture.Unit[1].CurrentD[1])) return;
+ if (!tObj->Complete) return;
+
+ /* If tex1 is not enabled, then disable it */
+ if (!(ctx->Texture.Enabled & ENABLE_TEX1)) {
+ r128ctx->regs.tex_cntl_c &= ~R128_SEC_TEXMAP_ENABLE;
+ return;
+ }
+
+ /* If this is the first time the texture has been used, then create
+ a new texture object for it. */
+ t = tObj->DriverData;
+ if (!t) t = r128CreateTexObj(r128ctx, tObj);
+ if (!t) return;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API)
+ fprintf(stderr, "r128UpdateTex1State(%p, 0x%08x)\n",
+ tObj, (int)t->dirty_images);
+
+ /* Force any texture images to be loaded into the hardware */
+ if (t->dirty_images) r128ctx->dirty |= R128_UPDATE_TEX1IMAGES;
+
+ /* Bind texture to texture 1 unit */
+ r128ctx->CurrentTexObj[1] = t;
+ t->bound = 2;
+
+ if (t->memBlock) r128UpdateTexLRU(r128ctx, t);
+
+ /* Set the texture environment state */
+ switch (ctx->Texture.Unit[1].EnvMode) {
+ case GL_REPLACE:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_BLEND:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ switch ( r128ctx->regs.constant_color_c & R128_CONSTANT_COLOR_MASK ) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ switch (r128ctx->regs.constant_color_c &
+ R128_CONSTANT_COLOR_MASK) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA );
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA );
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_INTENSITY:
+ switch (r128ctx->regs.constant_color_c &
+ R128_CONSTANT_COLOR_MASK) {
+ case R128_CONSTANT_COLOR_ZERO:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_NTEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_NTEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case R128_CONSTANT_COLOR_ONE:
+ default:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ r128ctx->Fallback |= R128_FALLBACK_TEXTURE;
+ break;
+ }
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_MODULATE:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_DECAL:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ tex_combine_cntl = (R128_COMB_BLEND_TEXTURE |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_RGB:
+ tex_combine_cntl = (R128_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ /* Undefined behaviour - just copy the input */
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_ADD:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGBA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ tex_combine_cntl = (R128_COMB_ADD |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_RGB:
+ case GL_LUMINANCE:
+ tex_combine_cntl = (R128_COMB_ADD |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_COPY_INP |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_ALPHA:
+ tex_combine_cntl = (R128_COMB_COPY_INP |
+ R128_COLOR_FACTOR_TEX |
+ R128_INPUT_FACTOR_PREV_COLOR |
+ R128_COMB_ALPHA_MODULATE |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_INP_FACTOR_A_PREV_ALPHA);
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ /* Enable tex1 */
+ r128ctx->regs.tex_cntl_c |= R128_SEC_TEXMAP_ENABLE;
+
+ tex_size_pitch = r128ctx->regs.tex_size_pitch_c;
+ tex_size_pitch &= ~R128_SEC_TEX_SIZE_PITCH_MASK;
+ tex_size_pitch |= t->regs.size_pitch << R128_SEC_TEX_SIZE_PITCH_SHIFT;
+
+ tex_cntl = t->regs.tex_cntl | R128_SEC_SELECT_SEC_ST;
+
+ /* Set the secondary texture state in r128ctx->regs */
+ r128ctx->regs.sec_tex_cntl_c = tex_cntl;
+ r128ctx->regs.sec_tex_combine_cntl_c = tex_combine_cntl;
+ r128ctx->regs.tex_size_pitch_c = tex_size_pitch;
+ r128ctx->regs.sec_texture_border_color_c = t->regs.border_color;
+
+ /* Set texture offsets */
+ if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) {
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] = (CARD32)t->bufAddr;
+ } else {
+ int maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >>
+ R128_TEX_SIZE_SHIFT);
+ int minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >>
+ R128_TEX_MIN_SIZE_SHIFT);
+ for (i = maxLevel; i >= minLevel; i--)
+ r128ctx->regs.sec_tex_offset[i] =
+ t->image[maxLevel-i].offset + (CARD32)t->bufAddr;
+ }
+ /* Fix AGP texture offsets */
+ if (t->heap == R128_AGP_TEX_HEAP)
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] +=
+ R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset;
+
+ /* Force loading the new state into the hardware */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX1STATE | R128_CTX_ENGINESTATE;
+}
+
+/* Update the hardware texture state */
+/* NOTE: This function is only called while holding the hardware lock */
+void r128UpdateTextureState(r128ContextPtr r128ctx)
+{
+ /* Clear the GL_BLEND texturing fallback */
+ r128ctx->Fallback &= ~R128_FALLBACK_TEXTURE;
+
+ /* Unbind any currently bound textures */
+ if (r128ctx->CurrentTexObj[0]) r128ctx->CurrentTexObj[0]->bound = 0;
+ if (r128ctx->CurrentTexObj[1]) r128ctx->CurrentTexObj[1]->bound = 0;
+ r128ctx->CurrentTexObj[0] = NULL;
+ r128ctx->CurrentTexObj[1] = NULL;
+
+ /* Update the texture unit 0/1 state */
+ r128UpdateTex0State(r128ctx);
+ r128UpdateTex1State(r128ctx);
+}
+
+/* Set the texture wrap mode */
+static void r128SetTexWrap(r128TexObjPtr t, GLenum swrap, GLenum twrap)
+{
+ t->regs.tex_cntl &= ~(R128_TEX_CLAMP_S_MASK | R128_TEX_CLAMP_T_MASK);
+
+ switch (swrap) {
+ case GL_CLAMP: t->regs.tex_cntl |= R128_TEX_CLAMP_S_CLAMP; break;
+ case GL_REPEAT: t->regs.tex_cntl |= R128_TEX_CLAMP_S_WRAP; break;
+ default: /* ERROR!! */ return;
+ }
+
+ switch (twrap) {
+ case GL_CLAMP: t->regs.tex_cntl |= R128_TEX_CLAMP_T_CLAMP; break;
+ case GL_REPEAT: t->regs.tex_cntl |= R128_TEX_CLAMP_T_WRAP; break;
+ default: /* ERROR!! */ return;
+ }
+}
+
+/* Set the texture filter mode */
+static void r128SetTexFilter(r128TexObjPtr t, GLenum minf, GLenum magf)
+{
+ t->regs.tex_cntl &= ~(R128_MIN_BLEND_MASK | R128_MAG_BLEND_MASK);
+
+ switch (minf) {
+ case GL_NEAREST:
+ t->regs.tex_cntl |= R128_MIN_BLEND_NEAREST;
+ break;
+ case GL_LINEAR:
+ t->regs.tex_cntl |= R128_MIN_BLEND_LINEAR;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ t->regs.tex_cntl |= R128_MIN_BLEND_MIPNEAREST;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ t->regs.tex_cntl |= R128_MIN_BLEND_LINEARMIPNEAREST;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ t->regs.tex_cntl |= R128_MIN_BLEND_MIPLINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ t->regs.tex_cntl |= R128_MIN_BLEND_LINEARMIPLINEAR;
+ break;
+ default: /* ERROR!! */ return;
+ }
+
+ switch (magf) {
+ case GL_NEAREST:
+ t->regs.tex_cntl |= R128_MAG_BLEND_NEAREST;
+ break;
+ case GL_LINEAR:
+ t->regs.tex_cntl |= R128_MAG_BLEND_LINEAR;
+ break;
+ }
+}
+
+/* Set the texture border color */
+static void r128SetTexBorderColor(r128TexObjPtr t, GLubyte c[4])
+{
+ t->regs.border_color = r128PackColor(32, c[0], c[1], c[2], c[3]);
+}
+
+/* Set the texture environment state */
+static void r128DDTexEnv(GLcontext *ctx, GLenum target, GLenum pname,
+ const GLfloat *param)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit;
+ GLubyte c[4];
+ CARD32 col;
+
+ /* FIXME: Add texture LOD bias extension */
+
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ /* TexEnv modes are handled in UpdateTextureState */
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ FLOAT_RGBA_TO_UBYTE_RGBA(texUnit->EnvColor, c);
+ col = r128PackColor(32, c[0], c[1], c[2], c[3]);
+ if (r128ctx->regs.constant_color_c != col) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128ctx->regs.constant_color_c = col;
+
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEXENVSTATE;
+ }
+ break;
+ default:
+ return;
+ }
+}
+
+/* Upload a new texture image */
+static void r128DDTexImage(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint internalFormat,
+ const struct gl_texture_image *image)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128TexObjPtr t;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API)
+ fprintf(stderr, "r128DDTexImage(%p, level %d)\n", tObj, level);
+
+ if ((target != GL_TEXTURE_2D) && (target != GL_TEXTURE_1D)) return;
+ if (level >= R128_TEX_MAXLEVELS) return;
+
+ t = (r128TexObjPtr)tObj->DriverData;
+ if (t) {
+ if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+
+ /* Destroy the old texture, and upload a new one. The actual
+ uploading of the texture image occurs in the UploadSubImage
+ function. */
+ r128DestroyTexObj(r128ctx, t);
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+ }
+}
+
+/* Upload a new texture sub-image */
+static void r128DDTexSubImage(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLint internalFormat,
+ const struct gl_texture_image *image)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128TexObjPtr t;
+
+ if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API)
+ fprintf(stderr, "r128DDTexSubImage(%p, level %d) "
+ "size: %d,%d of %d,%d\n",
+ tObj, level, width, height, image->Width, image->Height);
+
+ if ((target != GL_TEXTURE_2D) && (target != GL_TEXTURE_1D)) return;
+ if (level >= R128_TEX_MAXLEVELS) return;
+
+ t = (r128TexObjPtr)tObj->DriverData;
+ if (t) {
+ if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+
+ LOCK_HARDWARE(r128ctx);
+ r128UploadSubImage(r128ctx, t, level,
+ xoffset, yoffset, width, height);
+ UNLOCK_HARDWARE(r128ctx);
+
+ /* Update the context state */
+ r128ctx->regs.tex_cntl_c |= R128_TEX_CACHE_FLUSH;
+
+ r128ctx->dirty |= (R128_UPDATE_CONTEXT |
+ R128_UPDATE_TEXSTATE);
+ r128ctx->dirty_context |= (R128_CTX_ENGINESTATE |
+ R128_CTX_TEX0STATE |
+ R128_CTX_TEX1STATE);
+ }
+}
+
+/* Set the texture parameter state */
+static void r128DDTexParameter(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData;
+
+ if (!t) return;
+ if ((target != GL_TEXTURE_2D) && (target != GL_TEXTURE_1D)) return;
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128SetTexFilter(t, tObj->MinFilter, tObj->MagFilter);
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128SetTexWrap(t, tObj->WrapS, tObj->WrapT);
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ if (t->bound) R128CCE_FLUSH_VB_LOCK(r128ctx);
+ r128SetTexBorderColor(t, tObj->BorderColor);
+ break;
+
+ default:
+ return;
+ }
+
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+}
+
+/* Bind a texture to the currently active texture unit */
+static void r128DDBindTexture(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+
+ /* Unbind the old texture */
+ if (r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit]) {
+ r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0;
+ r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit] = NULL;
+ }
+
+ /* The actualy binding occurs in the Tex[01]UpdateState function */
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+}
+
+/* Remove texture from AGP/local texture memory */
+static void r128DDDeleteTexture(GLcontext *ctx,
+ struct gl_texture_object *tObj)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData;
+
+ if (t) {
+ if (t->bound) {
+ R128CCE_FLUSH_VB_LOCK(r128ctx);
+
+ r128ctx->CurrentTexObj[t->bound-1] = 0;
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+ }
+
+ r128DestroyTexObj(r128ctx, t);
+ tObj->DriverData = NULL;
+ }
+}
+
+/* Determine if a texture is currently residing in either AGP/local
+ texture memory */
+static GLboolean r128DDIsTextureResident(GLcontext *ctx,
+ struct gl_texture_object *tObj)
+{
+ r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData;
+
+ return t && t->memBlock;
+}
+
+/* Initialize the driver's texture functions */
+void r128DDInitTextureFuncs(GLcontext *ctx)
+{
+ ctx->Driver.TexEnv = r128DDTexEnv;
+ ctx->Driver.TexImage = r128DDTexImage;
+ ctx->Driver.TexSubImage = r128DDTexSubImage;
+ ctx->Driver.TexParameter = r128DDTexParameter;
+ ctx->Driver.BindTexture = r128DDBindTexture;
+ ctx->Driver.DeleteTexture = r128DDDeleteTexture;
+ ctx->Driver.UpdateTexturePalette = NULL;
+ ctx->Driver.ActiveTexture = NULL;
+ ctx->Driver.IsTextureResident = r128DDIsTextureResident;
+ ctx->Driver.PrioritizeTexture = NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h
new file mode 100644
index 000000000..20893110c
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h
@@ -0,0 +1,82 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_TEX_H_
+#define _R128_TEX_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void r128AgeTextures(r128ContextPtr r128ctx, int heap);
+extern int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t);
+extern void r128UpdateTextureState(r128ContextPtr r128ctx);
+extern void r128DestroyTexObj(r128ContextPtr r128ctx, r128TexObjPtr t);
+
+extern void r128DDInitTextureFuncs(GLcontext *ctx);
+
+#define R128PACKCOLOR332(r, g, b) \
+ (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
+
+#define R128PACKCOLOR1555(r, g, b, a) \
+ ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
+
+#define R128PACKCOLOR565(r, g, b) \
+ ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define R128PACKCOLOR888(r, g, b) \
+ (((r) << 16) | ((g) << 8) | (b))
+
+#define R128PACKCOLOR8888(r, g, b, a) \
+ (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+#define R128PACKCOLOR4444(r, g, b, a) \
+ ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+
+static __inline__ CARD32 r128PackColor(GLuint depth,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a)
+{
+ switch (depth) {
+ case 8: return R128PACKCOLOR332(r, g, b);
+ case 15: return R128PACKCOLOR1555(r, g, b, a);
+ case 16: return R128PACKCOLOR565(r, g, b);
+ case 24: return R128PACKCOLOR888(r, g, b);
+ case 32: return R128PACKCOLOR8888(r, g, b, a);
+ default: return 0;
+ }
+}
+
+#endif
+#endif /* _R128_TEX_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h
new file mode 100644
index 000000000..588b768ed
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h
@@ -0,0 +1,87 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Gareth Hughes <gareth@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_TEXOBJ_H_
+#define _R128_TEXOBJ_H_
+
+#include "mm.h"
+
+#define R128_TEX_MAXLEVELS 11
+
+/* Setup registers for each texture */
+typedef struct {
+ CARD32 tex_cntl;
+ CARD32 size_pitch;
+ CARD32 border_color;
+} r128TextureRegs;
+
+/* Individual texture image information */
+typedef struct {
+ int offset; /* Offset into locally shared texture space (i.e.,
+ relative to bufAddr (below) */
+ int width; /* Width of texture image */
+ int height; /* Height of texture image */
+} r128TexImage;
+
+typedef struct r128_tex_obj r128TexObj, *r128TexObjPtr;
+
+/* Texture object in locally shared texture space */
+struct r128_tex_obj {
+ r128TexObjPtr next, prev;
+
+ struct gl_texture_object *tObj; /* Mesa texture object */
+
+ PMemBlock memBlock; /* Memory block containing texture */
+ unsigned char *bufAddr; /* Offset to start of locally
+ shared texture block */
+
+ CARD32 dirty_images; /* Flags for whether or not
+ images need to be uploaded to
+ local or AGP texture space */
+ int bound; /* Texture unit currently bound to */
+ int heap; /* Texture heap currently stored in */
+ r128TexImage image[R128_TEX_MAXLEVELS]; /* Image data for all
+ mipmap levels */
+ int totalSize; /* Total size of the texture
+ including all mipmap levels */
+ int internFormat; /* Internal GL format used to store
+ texture on card */
+ int textureFormat; /* Actual hardware format */
+ int texelBytes; /* Number of bytes per texel */
+
+ r128TextureRegs regs; /* Setup regs for texture */
+};
+
+#endif /* _R128_TEXOBJ_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
new file mode 100644
index 000000000..1c1b45daf
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
@@ -0,0 +1,548 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_vb.h"
+#include "r128_tris.h"
+#include "r128_state.h"
+
+static triangle_func tri_tab[0x40]; /* only 0x20 actually used */
+static quad_func quad_tab[0x40]; /* only 0x20 actually used */
+static line_func line_tab[0x40]; /* less than 0x20 used */
+static points_func points_tab[0x40]; /* less than 0x20 used */
+
+/* Draw a triangle from the vertices in the vertex buffer */
+void r128DrawTriangleVB(r128ContextPtr r128ctx,
+ r128_vertex *v0,
+ r128_vertex *v1,
+ r128_vertex *v2)
+{
+ r128_vertex *vbptr;
+
+ if (r128ctx->disableVB) {
+ r128DrawTriangle(r128ctx, v0, v1, v2);
+ return;
+ }
+
+ R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3);
+
+ *vbptr++ = *v0;
+ *vbptr++ = *v1;
+ *vbptr++ = *v2;
+}
+
+/* Draw a triangle */
+void r128DrawTriangle(r128ContextPtr r128ctx,
+ r128_vertex *v0,
+ r128_vertex *v1,
+ r128_vertex *v2)
+{
+ LOCK_HARDWARE(r128ctx);
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 34);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 31);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (3 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCE_SEND_VERTEX(v0);
+ R128CCE_SEND_VERTEX(v1);
+ R128CCE_SEND_VERTEX(v2);
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+/* Draw a line from the vertices in the vertex buffer */
+void r128DrawLineVB(r128ContextPtr r128ctx,
+ r128_vertex *v0, r128_vertex *v1,
+ float width)
+{
+ float dx, dy, ix, iy;
+ r128_vertex *vbptr;
+
+ /* FIXME: Use r128's line primitive for width 1 lines */
+ if (r128ctx->disableVB) {
+ r128DrawLine(r128ctx, v0, v1, width);
+ return;
+ }
+
+ R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3);
+
+ dx = v0->x - v1->x;
+ dy = v0->y - v1->y;
+
+ ix = width * 0.5; iy = 0;
+ if (dx*dx > dy*dy) {
+ iy = ix; ix = 0;
+ }
+
+ *vbptr = *v0; vbptr->x = v0->x - ix; vbptr->y = v0->y - iy;
+ *++vbptr = *v1; vbptr->x = v1->x + ix; vbptr->y = v1->y + iy;
+ *++vbptr = *v0; vbptr->x = v0->x + ix; vbptr->y = v0->y + iy;
+ *++vbptr = *v0; vbptr->x = v0->x - ix; vbptr->y = v0->y - iy;
+ *++vbptr = *v1; vbptr->x = v1->x - ix; vbptr->y = v1->y - iy;
+ *++vbptr = *v1; vbptr->x = v1->x + ix; vbptr->y = v1->y + iy;
+}
+
+/* Draw a line */
+void r128DrawLine(r128ContextPtr r128ctx,
+ r128_vertex *v0, r128_vertex *v1,
+ float width)
+{
+ LOCK_HARDWARE(r128ctx);
+ if (width != 1) {
+ float dx, dy, ix, iy;
+
+ dx = v0->x - v1->x;
+ dy = v0->y - v1->y;
+
+ ix = width * 0.5; iy = 0;
+ if (dx*dx > dy*dy) {
+ iy = ix; ix = 0;
+ }
+
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 67);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 61);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (6 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCEF(v0->x - ix);
+ R128CCEF(v0->y - iy);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v1->x + ix);
+ R128CCEF(v1->y + iy);
+ R128CCEF(v1->z);
+ R128CCEF(v1->rhw);
+ R128CCE(*(int *)&v1->dif_argb);
+ R128CCE(*(int *)&v1->spec_frgb);
+ R128CCEF(v1->tu0);
+ R128CCEF(v1->tv0);
+ R128CCEF(v1->tu1);
+ R128CCEF(v1->tv1);
+#if USE_RHW2
+ R128CCEF(v1->rhw2);
+#endif
+
+ R128CCEF(v0->x + ix);
+ R128CCEF(v0->y + iy);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x - ix);
+ R128CCEF(v0->y - iy);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v1->x - ix);
+ R128CCEF(v1->y - iy);
+ R128CCEF(v1->z);
+ R128CCEF(v1->rhw);
+ R128CCE(*(int *)&v1->dif_argb);
+ R128CCE(*(int *)&v1->spec_frgb);
+ R128CCEF(v1->tu0);
+ R128CCEF(v1->tv0);
+ R128CCEF(v1->tu1);
+ R128CCEF(v1->tv1);
+#if USE_RHW2
+ R128CCEF(v1->rhw2);
+#endif
+
+ R128CCEF(v1->x + ix);
+ R128CCEF(v1->y + iy);
+ R128CCEF(v1->z);
+ R128CCEF(v1->rhw);
+ R128CCE(*(int *)&v1->dif_argb);
+ R128CCE(*(int *)&v1->spec_frgb);
+ R128CCEF(v1->tu0);
+ R128CCEF(v1->tv0);
+ R128CCEF(v1->tu1);
+ R128CCEF(v1->tv1);
+#if USE_RHW2
+ R128CCEF(v1->rhw2);
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ } else {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 23);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 21);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_LINE |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (2 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCE_SEND_VERTEX(v0);
+ R128CCE_SEND_VERTEX(v1);
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ }
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+/* Draw a point from the vertices in the vertex buffer */
+void r128DrawPointVB(r128ContextPtr r128ctx,
+ r128_vertex *v0, float size)
+{
+ r128_vertex *vbptr;
+
+ /* FIXME: Use r128's point primitive for diameter 1 points */
+ if (r128ctx->disableVB) {
+ r128DrawPoint(r128ctx, v0, size);
+ return;
+ }
+
+ R128CCE_ALLOC_VB_SPACE(r128ctx, vbptr, 3);
+
+ *vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y - size;
+ *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y - size;
+ *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y + size;
+ *++vbptr = *v0; vbptr->x = v0->x + size; vbptr->y = v0->y + size;
+ *++vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y + size;
+ *++vbptr = *v0; vbptr->x = v0->x - size; vbptr->y = v0->y - size;
+}
+
+/* Draw a point */
+void r128DrawPoint(r128ContextPtr r128ctx,
+ r128_vertex *v0, float size)
+{
+ LOCK_HARDWARE(r128ctx);
+ if (size != 0.5) {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 67);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 61);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (6 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCEF(v0->x - size);
+ R128CCEF(v0->y - size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x + size);
+ R128CCEF(v0->y - size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x + size);
+ R128CCEF(v0->y + size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x + size);
+ R128CCEF(v0->y + size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x - size);
+ R128CCEF(v0->y + size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v0->x - size);
+ R128CCEF(v0->y - size);
+ R128CCEF(v0->z);
+ R128CCEF(v0->rhw);
+ R128CCE(*(int *)&v0->dif_argb);
+ R128CCE(*(int *)&v0->spec_frgb);
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ } else {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 12);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 11);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_POINT |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (1 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCE_SEND_VERTEX(v0);
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ }
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+#define R128_COLOR(to, from) \
+do { \
+ (to)[0] = (from)[2]; \
+ (to)[1] = (from)[1]; \
+ (to)[2] = (from)[0]; \
+ (to)[3] = (from)[3]; \
+} while (0)
+
+#define IND (0)
+#define TAG(x) x
+#include "r128_tritmp.h"
+
+#define IND (R128_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "r128_tritmp.h"
+
+#define IND (R128_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "r128_tritmp.h"
+
+#define IND (R128_OFFSET_BIT | R128_FLAT_BIT)
+#define TAG(x) x##_offset_flat
+#include "r128_tritmp.h"
+
+#define IND (R128_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "r128_tritmp.h"
+
+#define IND (R128_TWOSIDE_BIT | R128_FLAT_BIT)
+#define TAG(x) x##_twoside_flat
+#include "r128_tritmp.h"
+
+#define IND (R128_TWOSIDE_BIT | R128_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "r128_tritmp.h"
+
+#define IND (R128_TWOSIDE_BIT | R128_OFFSET_BIT | R128_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_flat
+#include "r128_tritmp.h"
+
+/* Initialize the table of points, line and triangle drawing functions */
+void r128TriangleFuncsInit(void)
+{
+ init();
+ init_flat();
+ init_offset();
+ init_offset_flat();
+ init_twoside();
+ init_twoside_flat();
+ init_twoside_offset();
+ init_twoside_offset_flat();
+}
+
+/* Setup the Point, Line, Triangle and Quad functions based on the
+ current rendering state. Wherever possible, use the hardware to
+ render the primitive. Otherwise, fallback to software rendering. */
+void r128ChooseRenderState(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ GLuint flags = ctx->TriangleCaps;
+
+ if (r128ctx->Fallback) return;
+
+ if (r128ctx->SWonly) {
+ r128ctx->IndirectTriangles = DD_SW_RASTERIZE;
+ r128ctx->PointsFunc = NULL;
+ r128ctx->LineFunc = NULL;
+ r128ctx->TriangleFunc = NULL;
+ r128ctx->QuadFunc = NULL;
+ return;
+ } else {
+ r128ctx->IndirectTriangles = 0;
+ }
+
+ if (flags) {
+ CARD32 index = 0;
+ CARD32 shared = 0;
+ CARD32 fallback = R128_FALLBACK_BIT;
+
+ if (r128ctx->SWfallbackDisable) fallback = 0; /* No fallbacks */
+ if (r128ctx->SWonly) shared = fallback; /* Everything's a fallback */
+
+ if (flags & DD_FLATSHADE) shared |= R128_FLAT_BIT;
+ if (flags & DD_MULTIDRAW) shared |= fallback;
+ if (flags & DD_SELECT) shared |= R128_FALLBACK_BIT;
+ if (flags & DD_FEEDBACK) shared |= R128_FALLBACK_BIT;
+
+ /* Setup PointFunc */
+ index = shared;
+ if (flags & DD_POINT_SMOOTH) index |= fallback;
+ if (flags & DD_POINT_ATTEN) index |= fallback;
+
+ r128ctx->RenderIndex = index;
+ r128ctx->PointsFunc = points_tab[index];
+ if (index & R128_FALLBACK_BIT)
+ r128ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
+
+ /* Setup LineFunc */
+ index = shared;
+ if (flags & DD_LINE_SMOOTH) index |= fallback;
+ if (flags & DD_LINE_STIPPLE) index |= fallback;
+
+ r128ctx->RenderIndex |= index;
+ r128ctx->LineFunc = line_tab[index];
+ if (index & R128_FALLBACK_BIT)
+ r128ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
+
+ /* Setup TriangleFunc and QuadFunc */
+ index = shared;
+ if (flags & DD_TRI_SMOOTH) index |= fallback;
+ if (flags & DD_TRI_OFFSET) index |= R128_OFFSET_BIT;
+ if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R128_TWOSIDE_BIT;
+ if (flags & DD_TRI_UNFILLED) index |= fallback;
+ if (flags & DD_TRI_STIPPLE) index |= fallback;
+
+ r128ctx->RenderIndex |= index;
+ r128ctx->TriangleFunc = tri_tab[index];
+ r128ctx->QuadFunc = quad_tab[index];
+ if (index & R128_FALLBACK_BIT)
+ r128ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE |
+ DD_QUAD_SW_RASTERIZE);
+ } else if (r128ctx->RenderIndex) {
+ r128ctx->RenderIndex = 0;
+ r128ctx->PointsFunc = points_tab[0];
+ r128ctx->LineFunc = line_tab[0];
+ r128ctx->TriangleFunc = tri_tab[0];
+ r128ctx->QuadFunc = quad_tab[0];
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
new file mode 100644
index 000000000..0980f2791
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
@@ -0,0 +1,76 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_TRIS_H_
+#define _R128_TRIS_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "r128_vb.h"
+
+#define R128_ANTIALIAS_BIT 0x00 /* ignored for now, no fallback */
+#define R128_FLAT_BIT 0x01
+#define R128_OFFSET_BIT 0x02
+#define R128_TWOSIDE_BIT 0x04
+#define R128_NODRAW_BIT 0x08
+#define R128_FALLBACK_BIT 0x10
+#define R128_FEEDBACK_BIT 0x20
+#define R128_SELECT_BIT 0x40
+#define R128_POINT_PARAM_BIT 0x80 /* not needed? */
+
+extern void r128DrawTriangleVB(r128ContextPtr r128ctx,
+ r128_vertex *v0,
+ r128_vertex *v1,
+ r128_vertex *v2);
+extern void r128DrawLineVB(r128ContextPtr r128ctx,
+ r128_vertex *tmp0, r128_vertex *tmp1,
+ float width);
+extern void r128DrawPointVB(r128ContextPtr r128ctx,
+ r128_vertex *tmp, float size);
+
+extern void r128DrawTriangle(r128ContextPtr r128ctx,
+ r128_vertex *v0,
+ r128_vertex *v1,
+ r128_vertex *v2);
+extern void r128DrawLine(r128ContextPtr r128ctx,
+ r128_vertex *tmp0, r128_vertex *tmp1,
+ float width);
+extern void r128DrawPoint(r128ContextPtr r128ctx,
+ r128_vertex *tmp, float size);
+
+extern void r128ChooseRenderState(GLcontext *ctx);
+extern void r128TriangleFuncsInit(void);
+
+#endif
+#endif /* _R128_TRIS_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h
new file mode 100644
index 000000000..833bd832a
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h
@@ -0,0 +1,327 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#if !defined(TAG) || !defined(IND)
+ this is an error
+#endif
+
+/* Draw a single triangle. Note that the device-dependent vertex data
+ might need to be changed based on the render state. */
+static void TAG(triangle)(GLcontext *ctx,
+ GLuint e0, GLuint e1, GLuint e2,
+ GLuint pv)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ struct vertex_buffer *VB = ctx->VB;
+ r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts;
+ const r128_vertex *v0 = &r128verts[e0].v;
+ const r128_vertex *v1 = &r128verts[e1].v;
+ const r128_vertex *v2 = &r128verts[e2].v;
+
+#if (IND & R128_OFFSET_BIT)
+ GLfloat offset;
+#endif
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ int c0 = *(int *)&r128verts[pv].v.dif_argb;
+ int c1 = c0;
+ int c2 = c0;
+#endif
+
+#if (IND & R128_OFFSET_BIT)
+ switch (ctx->Visual->DepthBits) {
+ case 16: offset = ctx->Polygon.OffsetUnits / 65536.0; break;
+ case 24: offset = ctx->Polygon.OffsetUnits / 16777216.0; break;
+ case 32: offset = ctx->Polygon.OffsetUnits / 4294967296.0; break;
+ default: offset = ctx->Polygon.OffsetUnits / 65536.0; break;
+ }
+#endif
+
+#if (IND & (R128_TWOSIDE_BIT | R128_OFFSET_BIT))
+ {
+ GLfloat ex = v0->x - v2->x;
+ GLfloat ey = v0->y - v2->y;
+ GLfloat fx = v1->x - v2->x;
+ GLfloat fy = v1->y - v2->y;
+ GLfloat c = ex*fy - ey*fx;
+
+#if (IND & R128_TWOSIDE_BIT)
+ {
+ GLuint facing = (c > 0.0) ^ ctx->Polygon.FrontBit;
+ GLubyte (*vbcolor)[4] = VB->Color[facing]->data;
+ if (IND & R128_FLAT_BIT) {
+ R128_COLOR((char *)&c0, vbcolor[pv]);
+ c2 = c1 = c0;
+ } else {
+ R128_COLOR((char *)&c0, vbcolor[e0]);
+ R128_COLOR((char *)&c1, vbcolor[e1]);
+ R128_COLOR((char *)&c2, vbcolor[e2]);
+ }
+ }
+#endif
+
+#if (IND & R128_OFFSET_BIT)
+ {
+ if (c * c > 1e-16) {
+ GLfloat factor = ctx->Polygon.OffsetFactor;
+ GLfloat ez = v0->z - v2->z;
+ GLfloat fz = v1->z - v2->z;
+ GLfloat a = ey*fz - ez*fy;
+ GLfloat b = ez*fx - ex*fz;
+ GLfloat ic = 1.0 / c;
+ GLfloat ac = a * ic;
+ GLfloat bc = b * ic;
+ if (ac < 0.0f) ac = -ac;
+ if (bc < 0.0f) bc = -bc;
+ offset += MAX2(ac, bc) * factor;
+ }
+ }
+#endif
+ }
+#endif
+
+ LOCK_HARDWARE(r128ctx);
+ if (r128ctx->regs.tex_cntl_c & (R128_TEXMAP_ENABLE |
+ R128_SEC_TEXMAP_ENABLE)) {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 34);
+#else
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 31);
+#endif
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (3 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCEF(v0->x);
+ R128CCEF(v0->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v0->z + offset);
+#else
+ R128CCEF(v0->z);
+#endif
+ R128CCEF(v0->rhw);
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c0);
+#else
+ R128CCE(*(int *)&v0->dif_argb);
+#endif
+ R128CCE(*(int *)&v0->spec_frgb);
+
+ R128CCEF(v0->tu0);
+ R128CCEF(v0->tv0);
+ R128CCEF(v0->tu1);
+ R128CCEF(v0->tv1);
+#if USE_RHW2
+ R128CCEF(v0->rhw2);
+#endif
+
+ R128CCEF(v1->x);
+ R128CCEF(v1->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v1->z + offset);
+#else
+ R128CCEF(v1->z);
+#endif
+ R128CCEF(v1->rhw);
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c1);
+#else
+ R128CCE(*(int *)&v1->dif_argb);
+#endif
+ R128CCE(*(int *)&v1->spec_frgb);
+
+ R128CCEF(v1->tu0);
+ R128CCEF(v1->tv0);
+ R128CCEF(v1->tu1);
+ R128CCEF(v1->tv1);
+#if USE_RHW2
+ R128CCEF(v1->rhw2);
+#endif
+
+ R128CCEF(v2->x);
+ R128CCEF(v2->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v2->z + offset);
+#else
+ R128CCEF(v2->z);
+#endif
+ R128CCEF(v2->rhw);
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c2);
+#else
+ R128CCE(*(int *)&v2->dif_argb);
+#endif
+ R128CCE(*(int *)&v2->spec_frgb);
+
+ R128CCEF(v2->tu0);
+ R128CCEF(v2->tv0);
+ R128CCEF(v2->tu1);
+ R128CCEF(v2->tv1);
+#if USE_RHW2
+ R128CCEF(v2->rhw2);
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ } else {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 13);
+ R128CCE(R128_CCE_VC_FRMT_DIFFUSE_ARGB);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_RING |
+ (3 << R128_CCE_VC_CNTL_NUM_SHIFT));
+
+ R128CCEF(v0->x);
+ R128CCEF(v0->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v0->z + offset);
+#else
+ R128CCEF(v0->z);
+#endif
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c0);
+#else
+ R128CCE(*(int *)&v0->dif_argb);
+#endif
+
+ R128CCEF(v1->x);
+ R128CCEF(v1->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v1->z + offset);
+#else
+ R128CCEF(v1->z);
+#endif
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c1);
+#else
+ R128CCE(*(int *)&v1->dif_argb);
+#endif
+
+ R128CCEF(v2->x);
+ R128CCEF(v2->y);
+#if (IND & R128_OFFSET_BIT)
+ R128CCEF(v2->z + offset);
+#else
+ R128CCEF(v2->z);
+#endif
+
+#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
+ R128CCE(c2);
+#else
+ R128CCE(*(int *)&v2->dif_argb);
+#endif
+
+ R128CCE_SUBMIT_PACKETS();
+
+ END_CLIP_LOOP(r128ctx);
+ }
+ UNLOCK_HARDWARE(r128ctx);
+}
+
+static void TAG(quad)(GLcontext *ctx,
+ GLuint v0, GLuint v1, GLuint v2, GLuint v3,
+ GLuint pv)
+{
+ TAG(triangle)(ctx, v0, v1, v3, pv);
+ TAG(triangle)(ctx, v1, v2, v3, pv);
+}
+
+#if ((IND & ~R128_FLAT_BIT) == 0)
+
+/* Draw a single line. Note that the device-dependent vertex data might
+ need to be changed based on the render state. */
+static void TAG(line)(GLcontext *ctx,
+ GLuint v0, GLuint v1,
+ GLuint pv)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128VertexPtr r128verts = R128_DRIVER_DATA(ctx->VB)->verts;
+ r128_vertex tmp0 = r128verts[v0].v;
+ r128_vertex tmp1 = r128verts[v1].v;
+ float width = ctx->Line.Width;
+
+ if (IND & R128_FLAT_BIT) {
+ *(int *)&tmp1.dif_argb =
+ *(int *)&tmp0.dif_argb =
+ *(int *)&r128verts[pv].v.dif_argb;
+ }
+
+ r128DrawLine(r128ctx, &tmp0, &tmp1, width);
+}
+
+/* Draw a set of points. Note that the device-dependent vertex data
+ might need to be changed based on the render state. */
+static void TAG(points)(GLcontext *ctx,
+ GLuint first, GLuint last)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ struct vertex_buffer *VB = ctx->VB;
+ r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts;
+ GLfloat size = ctx->Point.Size * 0.5;
+ int i;
+
+ for(i = first; i <= last; i++) {
+ if(VB->ClipMask[i] == 0) {
+ r128_vertex *tmp = &r128verts[i].v;
+ r128DrawPoint(r128ctx, tmp, size);
+ }
+ }
+}
+
+#endif
+
+/* Initialize the table of primitives to render. */
+static void TAG(init)(void)
+{
+ tri_tab[IND] = TAG(triangle);
+ quad_tab[IND] = TAG(quad);
+
+#if ((IND & ~R128_FLAT_BIT) == 0)
+ line_tab[IND] = TAG(line);
+ points_tab[IND] = TAG(points);
+#endif
+}
+
+#undef IND
+#undef TAG
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c
new file mode 100644
index 000000000..f14ec21bd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c
@@ -0,0 +1,470 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#include "r128_init.h"
+#include "r128_mesa.h"
+#include "r128_xmesa.h"
+#include "r128_context.h"
+#include "r128_lock.h"
+#include "r128_reg.h"
+#include "r128_cce.h"
+#include "r128_state.h"
+#include "r128_vb.h"
+
+#include "stages.h"
+
+#define TEX0 \
+do { \
+ v->v.tu0 = tc0[i][0]; \
+ v->v.tv0 = tc0[i][1]; \
+} while (0)
+
+#define TEX1 \
+do { \
+ v->v.tu1 = tc1[i][0]; \
+ v->v.tv1 = tc1[i][1]; \
+} while (0)
+
+#define SPC \
+do { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->v.spec_frgb.r = spec[0]; \
+ v->v.spec_frgb.g = spec[1]; \
+ v->v.spec_frgb.b = spec[2]; \
+} while (0)
+
+#define FOG \
+do { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->v.spec_frgb.a = spec[3]; \
+} while (0)
+
+#define COL \
+do { \
+ GLubyte *col = &(VB->Color[0]->data[i][0]); \
+ v->v.dif_argb.a = col[3]; \
+ v->v.dif_argb.r = col[0]; \
+ v->v.dif_argb.g = col[1]; \
+ v->v.dif_argb.b = col[2]; \
+} while (0)
+
+#if 1
+/* FIXME: These are handled by the Rage 128 */
+#define TEX0_4
+#define TEX1_4
+#else
+#define TEX0_4 \
+do { \
+ if (VB->TexCoordPtr[0]->size == 4) { \
+ GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \
+ v = &(R128_DRIVER_DATA(VB)->verts[start]); \
+ for (i = start; i < end; i++, v++) { \
+ float oow = 1.0 / tc[i][3]; \
+ v->v.rhw *= tc[i][3]; \
+ v->v.tu0 *= oow; \
+ v->v.tv0 *= oow; \
+ } \
+ } \
+} while (0)
+
+#if USE_RHW2
+#define TEX1_4 \
+do { \
+ if (VB->TexCoordPtr[1]->size == 4) { \
+ GLfloat (*tc)[4] = VB->TexCoordPtr[1]->data; \
+ v = &(R128_DRIVER_DATA(VB)->verts[start]); \
+ for (i = start; i < end; i++, v++) { \
+ float oow = 1.0 / tc[i][3]; \
+ v->v.rhw2 *= tc[i][3]; \
+ v->v.tu1 *= oow; \
+ v->v.tv1 *= oow; \
+ } \
+ } \
+} while (0)
+#else
+#define TEX1_4
+#endif
+#endif
+
+#if USE_RHW2
+#define COORD \
+do { \
+ GLfloat *win = VB->Win.data[i]; \
+ v->v.x = win[0]; \
+ v->v.y = r128height - win[1]; \
+ v->v.z = scale * win[2]; \
+ v->v.rhw = v->v.rhw2 = win[3]; \
+} while (0)
+#else
+#define COORD \
+do { \
+ GLfloat *win = VB->Win.data[i]; \
+ v->v.x = win[0]; \
+ v->v.y = r128height - win[1]; \
+ v->v.z = scale * win[2]; \
+ v->v.rhw = win[3]; \
+} while (0)
+#endif
+
+#define NOP
+
+/* Setup the r128 vertex buffer entries */
+#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,spec,fog) \
+static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \
+{ \
+ r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); \
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \
+ r128VertexPtr v; \
+ GLfloat (*tc0)[4]; \
+ GLfloat (*tc1)[4]; \
+ GLfloat r128height = dPriv->h; \
+ GLfloat scale; \
+ int i; \
+ \
+ (void) r128height; (void) r128ctx; \
+ \
+ gl_import_client_data(VB, VB->ctx->RenderFlags, \
+ (VB->ClipOrMask \
+ ? VEC_WRITABLE | VEC_GOOD_STRIDE \
+ : VEC_GOOD_STRIDE)); \
+ \
+ switch (VB->ctx->Visual->DepthBits) { \
+ case 16: scale = 1.0 / 65536.0; break; \
+ case 24: scale = 1.0 / 16777216.0; break; \
+ case 32: scale = 1.0 / 4294967296.0; break; \
+ default: scale = 1.0 / 65536.0; break; \
+ } \
+ \
+ tc0 = VB->TexCoordPtr[0]->data; \
+ tc1 = VB->TexCoordPtr[1]->data; \
+ \
+ v = &(R128_DRIVER_DATA(VB)->verts[start]); \
+ \
+ if (VB->ClipOrMask == 0) \
+ for (i = start; i < end; i++, v++) { \
+ win; \
+ col; \
+ spec; \
+ fog; \
+ tex0; \
+ tex1; \
+ } \
+ else \
+ for (i = start; i < end; i++, v++) { \
+ if (VB->ClipMask[i] == 0) { \
+ win; \
+ spec; \
+ fog; \
+ tex0; \
+ tex1; \
+ } \
+ col; \
+ } \
+ tex0_4; \
+ tex1_4; \
+}
+
+
+SETUPFUNC(rs_wt0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_wt1, COORD, NOP, NOP, TEX1, NOP, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_wt0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_wft0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_wft1, COORD, NOP, NOP, TEX1, NOP, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_wft0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_wg, COORD, COL, NOP, NOP, NOP, NOP, NOP, NOP)
+SETUPFUNC(rs_wgs, COORD, COL, NOP, NOP, NOP, NOP, SPC, NOP)
+SETUPFUNC(rs_wgt0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_wgt1, COORD, COL, NOP, TEX1, NOP, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_wgt0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_wgst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP)
+SETUPFUNC(rs_wgst1, COORD, COL, NOP, TEX1, NOP, TEX1_4, SPC, NOP)
+SETUPFUNC(rs_wgst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP)
+SETUPFUNC(rs_wgf, COORD, COL, NOP, NOP, NOP, NOP, NOP, FOG)
+SETUPFUNC(rs_wgfs, COORD, COL, NOP, NOP, NOP, NOP, SPC, FOG)
+SETUPFUNC(rs_wgft0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_wgft1, COORD, COL, NOP, TEX1, NOP, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_wgft0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_wgfst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG)
+SETUPFUNC(rs_wgfst1 , COORD, COL, NOP, TEX1, NOP, TEX1_4, SPC, FOG)
+SETUPFUNC(rs_wgfst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG)
+
+SETUPFUNC(rs_t0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_t1, NOP, NOP, NOP, TEX1, NOP, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_t0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_f, NOP, NOP, NOP, NOP, NOP, NOP, NOP, FOG)
+SETUPFUNC(rs_ft0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_ft1, NOP, NOP, NOP, TEX1, NOP, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_ft0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_g, NOP, COL, NOP, NOP, NOP, NOP, NOP, NOP)
+SETUPFUNC(rs_gs, NOP, COL, NOP, NOP, NOP, NOP, SPC, NOP)
+SETUPFUNC(rs_gt0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_gt1, NOP, COL, NOP, TEX1, NOP, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_gt0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_gst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP)
+SETUPFUNC(rs_gst1, NOP, COL, NOP, TEX1, NOP, TEX1_4, SPC, NOP)
+SETUPFUNC(rs_gst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP)
+SETUPFUNC(rs_gf, NOP, COL, NOP, NOP, NOP, NOP, NOP, FOG)
+SETUPFUNC(rs_gfs, NOP, COL, NOP, NOP, NOP, NOP, SPC, FOG)
+SETUPFUNC(rs_gft0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_gft1, NOP, COL, NOP, TEX1, NOP, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_gft0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_gfst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG)
+SETUPFUNC(rs_gfst1, NOP, COL, NOP, TEX1, NOP, TEX1_4, SPC, FOG)
+SETUPFUNC(rs_gfst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG)
+
+static void rs_invalid(struct vertex_buffer *VB, GLuint start, GLuint end)
+{
+ fprintf(stderr, "r128RasterSetup(): invalid setup function\n");
+}
+
+typedef void (*setupFunc)(struct vertex_buffer *, GLuint, GLuint);
+static setupFunc setup_func[0x80];
+
+/* Initialize the table of vertex buffer setup functions */
+void r128SetupInit(void)
+{
+ int i;
+
+ for (i = 0; i < 0x80; i++) setup_func[i] = rs_invalid;
+
+ /* Funcs to build vertices from scratch */
+ setup_func[R128_WIN_BIT|R128_TEX0_BIT] = rs_wt0;
+ setup_func[R128_WIN_BIT|R128_TEX1_BIT] = rs_wt1;
+ setup_func[R128_WIN_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wt0t1;
+ setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_wft0;
+ setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_wft1;
+ setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wft0t1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT] = rs_wg;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT] = rs_wgs;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX0_BIT] = rs_wgt0;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX1_BIT] = rs_wgt1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgt0t1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_wgst0;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_wgst1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgst0t1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT] = rs_wgf;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT] = rs_wgfs;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_wgft0;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_wgft1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgft0t1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_wgfst0;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_wgfst1;
+ setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgfst0t1;
+
+ /* Funcs to repair vertices */
+ setup_func[R128_TEX0_BIT] = rs_t0;
+ setup_func[R128_TEX1_BIT] = rs_t1;
+ setup_func[R128_TEX0_BIT|R128_TEX1_BIT] = rs_t0t1;
+ setup_func[R128_FOG_BIT] = rs_f;
+ setup_func[R128_FOG_BIT|R128_TEX0_BIT] = rs_ft0;
+ setup_func[R128_FOG_BIT|R128_TEX1_BIT] = rs_ft1;
+ setup_func[R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_ft0t1;
+ setup_func[R128_RGBA_BIT] = rs_g;
+ setup_func[R128_RGBA_BIT|R128_SPEC_BIT] = rs_gs;
+ setup_func[R128_RGBA_BIT|R128_TEX0_BIT] = rs_gt0;
+ setup_func[R128_RGBA_BIT|R128_TEX1_BIT] = rs_gt1;
+ setup_func[R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gt0t1;
+ setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_gst0;
+ setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_gst1;
+ setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gst0t1;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT] = rs_gf;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT] = rs_gfs;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_gft0;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_gft1;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gft0t1;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_gfst0;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_gfst1;
+ setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gfst0t1;
+}
+
+/* Initialize the vertex buffer setup functions based on the current
+ rendering state */
+void r128ChooseRasterSetupFunc(GLcontext *ctx)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ int funcIndex = R128_WIN_BIT | R128_RGBA_BIT;
+
+ if (ctx->Texture.Enabled & 0xf) {
+ if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE)
+ funcIndex &= ~R128_RGBA_BIT;
+ funcIndex |= R128_TEX0_BIT;
+ }
+
+ if (ctx->Texture.Enabled & 0xf0)
+ funcIndex |= R128_TEX1_BIT;
+
+ /* FIXME: Verify this works properly */
+ if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ funcIndex |= R128_SPEC_BIT;
+
+ if (ctx->FogMode == FOG_FRAGMENT)
+ funcIndex |= R128_FOG_BIT;
+
+ r128ctx->SetupIndex = funcIndex;
+ ctx->Driver.RasterSetup = setup_func[funcIndex];
+}
+
+/* Check to see if any updates of the vertex buffer entries are needed */
+void r128CheckPartialRasterSetup(GLcontext *ctx,
+ struct gl_pipeline_stage *s)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ int tmp = r128ctx->SetupDone;
+
+ s->type = 0;
+ r128ctx->SetupDone = GL_FALSE;
+
+ if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0) return;
+ if (ctx->IndirectTriangles) return;
+
+ r128ctx->SetupDone = tmp;
+}
+
+/* Update the vertex buffer entries, if necessary */
+void r128PartialRasterSetup(struct vertex_buffer *VB)
+{
+ r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx);
+ int new = VB->pipeline->new_outputs;
+ int available = VB->pipeline->outputs;
+ int index = 0;
+
+ if (new & VERT_WIN) {
+ new = available;
+ index |= R128_WIN_BIT | R128_FOG_BIT;
+ }
+
+ if (new & VERT_RGBA) index |= R128_RGBA_BIT | R128_SPEC_BIT;
+ if (new & VERT_TEX0_ANY) index |= R128_TEX0_BIT;
+ if (new & VERT_TEX1_ANY) index |= R128_TEX1_BIT;
+#if 0
+ /* FIXME */
+ if (new & VERT_FOG_COORD) index |= R128_FOG_BIT;
+#endif
+
+ r128ctx->SetupDone &= ~index;
+ index &= r128ctx->SetupIndex;
+ r128ctx->SetupDone |= index;
+
+ if (index) setup_func[index & ~R128_ALPHA_BIT](VB, VB->Start, VB->Count);
+}
+
+/* Perform the raster setup for the fast path, if using CVA */
+void r128DoRasterSetup(struct vertex_buffer *VB)
+{
+ GLcontext *ctx = VB->ctx;
+
+ if (VB->Type == VB_CVA_PRECALC) r128PartialRasterSetup(VB);
+ else if (ctx->Driver.RasterSetup) ctx->Driver.RasterSetup(VB,
+ VB->CopyStart,
+ VB->Count);
+}
+
+/* Resize an existing vertex buffer */
+void r128ResizeVB(struct vertex_buffer *VB, GLuint size)
+{
+ r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB);
+
+ while (r128vb->size < size)
+ r128vb->size *= 2;
+
+ free(r128vb->vert_store);
+ r128vb->vert_store = malloc(sizeof(r128Vertex) * r128vb->size + 31);
+ if (!r128vb->vert_store) {
+ fprintf(stderr, "Cannot allocate vertex store! Exiting...\n");
+ exit(1);
+ }
+
+ r128vb->verts = (r128VertexPtr)(((CARD32)r128vb->vert_store + 31) & ~31);
+
+ gl_vector1ui_free(&r128vb->clipped_elements);
+ gl_vector1ui_alloc(&r128vb->clipped_elements,
+ VEC_WRITABLE, r128vb->size, 32);
+ if (!r128vb->clipped_elements.start) {
+ fprintf(stderr, "Cannot allocate clipped elements! Exiting...\n");
+ exit(1);
+ }
+
+ free(VB->ClipMask);
+ VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * r128vb->size);
+ if (!VB->ClipMask) {
+ fprintf(stderr, "Cannot allocate clipmask! Exiting...\n");
+ exit(1);
+ }
+}
+
+/* Create a new device-dependent vertex buffer */
+void r128DDRegisterVB(struct vertex_buffer *VB)
+{
+ r128VertexBufferPtr r128vb;
+
+ r128vb = (r128VertexBufferPtr)calloc(1, sizeof(*r128vb));
+
+ r128vb->size = VB->Size * 2;
+ r128vb->vert_store = malloc(sizeof(r128Vertex) * r128vb->size + 31);
+ if (!r128vb->vert_store) {
+ fprintf(stderr, "Cannot allocate vertex store! Exiting...\n");
+ exit(1);
+ }
+
+ r128vb->verts = (r128VertexPtr)(((CARD32)r128vb->vert_store + 31) & ~31);
+
+ gl_vector1ui_alloc(&r128vb->clipped_elements,
+ VEC_WRITABLE, r128vb->size, 32);
+ if (!r128vb->clipped_elements.start) {
+ fprintf(stderr, "Cannot allocate clipped elements! Exiting...\n");
+ exit(1);
+ }
+
+ free(VB->ClipMask);
+ VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * r128vb->size);
+ if (!VB->ClipMask) {
+ fprintf(stderr, "Cannot allocate clipmask! Exiting...\n");
+ exit(1);
+ }
+
+ VB->driver_data = r128vb;
+}
+
+/* Destroy a device-dependent vertex buffer */
+void r128DDUnregisterVB(struct vertex_buffer *VB)
+{
+ r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB);
+
+ if (r128vb) {
+ if (r128vb->vert_store) free(r128vb->vert_store);
+ gl_vector1ui_free(&r128vb->clipped_elements);
+ free(r128vb);
+ VB->driver_data = 0;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
new file mode 100644
index 000000000..4f7c11d7f
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
@@ -0,0 +1,150 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_VB_H_
+#define _R128_VB_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+#define USE_RHW2 0
+
+/* FIXME: This is endian-specific */
+typedef struct {
+ GLubyte b;
+ GLubyte g;
+ GLubyte r;
+ GLubyte a;
+} r128Color;
+
+typedef struct {
+ GLfloat x, y, z; /* Coordinates in screen space */
+ GLfloat rhw; /* Reciprocal homogeneous w */
+ r128Color dif_argb; /* Diffuse color */
+ r128Color spec_frgb; /* Specular color (alpha is fog) */
+ GLfloat tu0, tv0; /* Texture 0 coordinates */
+ GLfloat tu1, tv1; /* Texture 1 coordinates */
+#if USE_RHW2
+ GLfloat rhw2; /* Reciprocal homogeneous w */
+#endif
+} r128_vertex;
+
+#if USE_RHW2
+/* Format of vertices in r128_vertex struct */
+#define R128_FULL_VERTEX_FORMAT \
+ R128_CCE_VC_FRMT_RHW | \
+ R128_CCE_VC_FRMT_DIFFUSE_ARGB | \
+ R128_CCE_VC_FRMT_SPEC_FRGB | \
+ R128_CCE_VC_FRMT_S_T | \
+ R128_CCE_VC_FRMT_S2_T2 | \
+ R128_CCE_VC_FRMT_RHW2
+
+/* Send a single vertex to the ring buffer */
+#define R128CCE_SEND_VERTEX(v) \
+ do { \
+ R128CCEF((v)->x); \
+ R128CCEF((v)->y); \
+ R128CCEF((v)->z); \
+ R128CCEF((v)->rhw); \
+ R128CCE(*(int *)&(v)->dif_argb); \
+ R128CCE(*(int *)&(v)->spec_frgb); \
+ R128CCEF((v)->tu0); \
+ R128CCEF((v)->tv0); \
+ R128CCEF((v)->tu1); \
+ R128CCEF((v)->tv1); \
+ R128CCEF((v)->rhw2); \
+ } while (0)
+
+#else /* !USE_RHW2 */
+
+/* Format of vertices in r128_vertex struct */
+#define R128_FULL_VERTEX_FORMAT \
+ R128_CCE_VC_FRMT_RHW | \
+ R128_CCE_VC_FRMT_DIFFUSE_ARGB | \
+ R128_CCE_VC_FRMT_SPEC_FRGB | \
+ R128_CCE_VC_FRMT_S_T | \
+ R128_CCE_VC_FRMT_S2_T2
+
+/* Send a single vertex to the ring buffer */
+#define R128CCE_SEND_VERTEX(v) \
+ do { \
+ R128CCEF((v)->x); \
+ R128CCEF((v)->y); \
+ R128CCEF((v)->z); \
+ R128CCEF((v)->rhw); \
+ R128CCE(*(int *)&(v)->dif_argb); \
+ R128CCE(*(int *)&(v)->spec_frgb); \
+ R128CCEF((v)->tu0); \
+ R128CCEF((v)->tv0); \
+ R128CCEF((v)->tu1); \
+ R128CCEF((v)->tv1); \
+ } while (0)
+#endif
+
+/* FIXME: We currently only have assembly for 16-stride vertices */
+typedef union {
+ r128_vertex v;
+ float f[16];
+} r128Vertex, *r128VertexPtr;
+
+/* Vertex buffer for use when on the fast path */
+typedef struct {
+ GLuint size; /* Number of vertices in store */
+ void *vert_store; /* Storage for vertex buffer */
+ r128VertexPtr verts; /* Aligned start of verts in storage */
+ int last_vert; /* Index of last vertex used */
+ GLvector1ui clipped_elements; /* List of clipped elements */
+} *r128VertexBufferPtr;
+
+#define R128_DRIVER_DATA(vb) ((r128VertexBufferPtr)((vb)->driver_data))
+
+#define R128_SPEC_BIT 0x01
+#define R128_FOG_BIT 0x02
+#define R128_ALPHA_BIT 0x04 /* GL_BLEND, not used */
+#define R128_TEX1_BIT 0x08
+#define R128_TEX0_BIT 0x10
+#define R128_RGBA_BIT 0x20
+#define R128_WIN_BIT 0x40
+
+extern void r128SetupInit(void);
+extern void r128ChooseRasterSetupFunc(GLcontext *ctx);
+extern void r128CheckPartialRasterSetup(GLcontext *ctx,
+ struct gl_pipeline_stage *s);
+extern void r128PartialRasterSetup(struct vertex_buffer *VB);
+extern void r128DoRasterSetup(struct vertex_buffer *VB);
+extern void r128ResizeVB(struct vertex_buffer *VB, GLuint size);
+extern void r128DDRegisterVB(struct vertex_buffer *VB);
+extern void r128DDUnregisterVB(struct vertex_buffer *VB);
+
+#endif
+#endif /* _R128_VB_H_ */
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c
new file mode 100644
index 000000000..60d528813
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c
@@ -0,0 +1,257 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifdef GLX_DIRECT_RENDERING
+
+/* r128 Mesa driver includes */
+#include "r128_init.h"
+#include "r128_context.h"
+#include "r128_xmesa.h"
+#include "r128_state.h"
+#include "r128_tex.h"
+#include "r128_swap.h"
+
+/* Mesa src includes */
+#include "context.h"
+#include "simple_list.h"
+#include "mmath.h"
+
+#ifndef R128_DEBUG_FLAGS
+int R128_DEBUG_FLAGS = (0
+#if 0
+ | DEBUG_ALWAYS_SYNC
+ | DEBUG_VERBOSE_CCE
+ | DEBUG_VERBOSE_OUTREG
+ | DEBUG_VERBOSE_MSG
+ | DEBUG_NO_OUTRING
+ | DEBUG_NO_OUTREG
+ | DEBUG_VERBOSE_API
+ | DEBUG_VERBOSE_2D
+ | DEBUG_VERBOSE_DRI
+ | DEBUG_VALIDATE_RING
+ | DEBUG_VERBOSE_IOCTL
+#endif
+ );
+#endif
+
+#if DEBUG_LOCKING
+char *prevLockFile = NULL;
+int prevLockLine = 0;
+#endif
+
+static r128ContextPtr r128Context = NULL;
+
+
+/* Initialize the driver specific screen private data */
+GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
+{
+ sPriv->private = (void *)r128CreateScreen(sPriv);
+ if (!sPriv->private) {
+ r128DestroyScreen(sPriv);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/* Reset the driver specific screen private data */
+void XMesaResetDriver(__DRIscreenPrivate *sPriv)
+{
+ r128DestroyScreen(sPriv);
+}
+
+/* Create and initialize the Mesa and driver specific visual data */
+GLvisual *XMesaCreateVisual(Display *dpy,
+ __DRIscreenPrivate *driScrnPriv,
+ const XVisualInfo *visinfo,
+ const __GLXvisualConfig *config)
+{
+ /* Drivers may change the args to _mesa_create_visual() in order to
+ * setup special visuals.
+ */
+ return _mesa_create_visual(config->rgba,
+ config->doubleBuffer,
+ config->stereo,
+ _mesa_bitcount(visinfo->red_mask),
+ _mesa_bitcount(visinfo->green_mask),
+ _mesa_bitcount(visinfo->blue_mask),
+ config->alphaSize,
+ 0, /* index bits */
+ config->depthSize,
+ config->stencilSize,
+ config->accumRedSize,
+ config->accumGreenSize,
+ config->accumBlueSize,
+ config->accumAlphaSize,
+ 0 /* num samples */);
+}
+
+/* Create and initialize the Mesa and driver specific context data */
+GLboolean XMesaCreateContext(Display *dpy, GLvisual *mesaVis,
+ __DRIcontextPrivate *driContextPriv)
+{
+ return r128CreateContext(dpy, mesaVis, driContextPriv);
+}
+
+/* Destroy the Mesa and driver specific context data */
+void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+ r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate;
+
+ if (r128ctx == (void *)r128Context) r128Context = NULL;
+ r128DestroyContext(r128ctx);
+}
+
+/* Create and initialize the Mesa and driver specific pixmap buffer data */
+GLframebuffer *XMesaCreateWindowBuffer(Display *dpy,
+ __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ GLvisual *mesaVis)
+{
+ return gl_create_framebuffer(mesaVis,
+ GL_FALSE, /* software depth buffer? */
+ mesaVis->StencilBits > 0,
+ mesaVis->AccumRedBits > 0,
+ mesaVis->AlphaBits > 0
+ );
+}
+
+/* Create and initialize the Mesa and driver specific pixmap buffer data */
+GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy,
+ __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ GLvisual *mesaVis)
+{
+#if 0
+ /* Different drivers may have different combinations of hardware and
+ * software ancillary buffers.
+ */
+ return gl_create_framebuffer(mesaVis,
+ GL_FALSE, /* software depth buffer? */
+ mesaVis->StencilBits > 0,
+ mesaVis->AccumRedBits > 0,
+ mesaVis->AlphaBits > 0);
+#else
+ return NULL; /* not implemented yet */
+#endif
+}
+
+/* Copy the back color buffer to the front color buffer */
+void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv)
+{
+ /* FIXME: This assumes buffer is currently bound to a context. This
+ needs to be able to swap buffers when not currently bound. Also,
+ this needs to swap according to buffer, and NOT according to
+ context! */
+ if (r128Context == NULL) return;
+
+ /* Only swap buffers when a back buffer exists */
+ if (R128_MESACTX(r128Context)->Visual->DBflag) {
+ FLUSH_VB(R128_MESACTX(r128Context), "swap buffers");
+ r128SwapBuffers(r128Context);
+ }
+}
+
+/* Force the context `c' to be the current context and associate with it
+ buffer `b' */
+GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv)
+{
+ if (driContextPriv) {
+ r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate;
+
+ if (r128Context &&
+ r128ctx == (void *)r128Context &&
+ driDrawPriv == R128_DRIDRAWABLE(r128Context))
+ return GL_TRUE;
+
+ r128Context = r128MakeCurrent(r128Context, r128ctx, driDrawPriv);
+
+ gl_make_current2(R128_MESACTX(r128Context),
+ driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer);
+
+ if (!R128_MESACTX(r128Context)->Viewport.Width) {
+ gl_Viewport(R128_MESACTX(r128Context), 0, 0,
+ driDrawPriv->w, driDrawPriv->h);
+ }
+ } else {
+ gl_make_current(0,0);
+ r128Context = NULL;
+ }
+
+ return GL_TRUE;
+}
+
+/* Force the context `c' to be unbound from its buffer */
+GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv)
+{
+ return GL_TRUE;
+}
+
+/* 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. */
+/* NOTE: This routine is only called while holding the hardware lock. */
+void XMesaUpdateState(__DRIcontextPrivate *driContextPriv)
+{
+ r128ContextPtr r128ctx = driContextPriv->driverPrivate;
+ __DRIscreenPrivate *sPriv = R128_DRISCREEN(r128ctx);
+ __DRIdrawablePrivate *dPriv = R128_DRIDRAWABLE(r128ctx);
+ int stamp = dPriv->lastStamp;
+
+ /* 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. */
+ XMESA_VALIDATE_DRAWABLE_INFO(r128ctx->display, sPriv, dPriv);
+
+ r128UpdateState(r128ctx, (stamp != dPriv->lastStamp));
+}
+
+/* This function is called by libGL.so as soon as libGL.so is loaded.
+ * This is where we'd register new extension functions with the dispatcher.
+ */
+void __driRegisterExtensions(void)
+{
+}
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h
new file mode 100644
index 000000000..ca6fc127b
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.h
@@ -0,0 +1,44 @@
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
+ Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifndef _R128_XMESA_H_
+#define _R128_XMESA_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void XMesaUpdateState(__DRIcontextPrivate *driContextPriv);
+extern void __driRegisterExtensions(void);
+
+#endif
+#endif /* _R128_XMESA_H_ */