summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/Imakefile8
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/mm.c262
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/mm.h101
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_cce.c53
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_cce.h67
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_ccevb.h48
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_clear.c186
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_context.c183
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_context.h165
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_dd.c75
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_depth.c15
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c537
-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.h16
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_lock.h18
-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.c160
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_screen.h79
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_span.c42
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_state.c845
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_state.h12
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_swap.c55
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tex.c1096
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tex.h7
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_texobj.h81
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tris.c121
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tris.h12
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h170
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_vb.c360
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_vb.h112
-rw-r--r--xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c260
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h27
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c43
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c464
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h50
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dripriv.h5
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c71
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h70
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h69
41 files changed, 5225 insertions, 1092 deletions
diff --git a/xc/lib/GL/mesa/src/drv/r128/Imakefile b/xc/lib/GL/mesa/src/drv/r128/Imakefile
index 6ca57a376..dd01c3ce2 100644
--- a/xc/lib/GL/mesa/src/drv/r128/Imakefile
+++ b/xc/lib/GL/mesa/src/drv/r128/Imakefile
@@ -25,10 +25,14 @@ MESA_INCLUDES = -I. -I.. -I../../include
INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
DRISRCS = r128_xmesa.c r128_cce.c r128_dd.c r128_state.c \
r128_span.c r128_depth.c r128_tex.c r128_clear.c \
- r128_swap.c r128_tris.c r128_vb.c
+ r128_swap.c r128_tris.c r128_vb.c r128_context.c \
+ r128_screen.c r128_pipeline.c r128_fastpath.c \
+ mm.c
DRIOBJS = r128_xmesa.o r128_cce.o r128_dd.o r128_state.o \
r128_span.o r128_depth.o r128_tex.o r128_clear.o \
- r128_swap.o r128_tris.o r128_vb.o
+ r128_swap.o r128_tris.o r128_vb.o r128_context.o \
+ r128_screen.o r128_pipeline.o r128_fastpath.o \
+ mm.o
SRCS = $(DRISRCS)
OBJS = $(DRIOBJS)
diff --git a/xc/lib/GL/mesa/src/drv/r128/mm.c b/xc/lib/GL/mesa/src/drv/r128/mm.c
new file mode 100644
index 000000000..00ad43a8c
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/mm.c
@@ -0,0 +1,262 @@
+/*
+ * GLX Hardware Device Driver common code
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mm.h"
+/* #include "hwlog.h" */
+
+#define ISFREE(bptr) ((bptr)->free)
+/* #define PRINTF(f,a...) hwMsg(1,f, ## a) */
+#define PRINTF(f,a...) fprintf(stderr, f, ## a)
+
+void mmDumpMemInfo( memHeap_t *heap )
+{
+ TMemBlock *p;
+
+ PRINTF("Memory heap %p:\n", heap);
+ if (heap == 0) {
+ PRINTF(" heap == 0\n");
+ } else {
+ p = (TMemBlock *)heap;
+ while (p) {
+ PRINTF(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
+ p->free ? '.':'U',
+ p->reserved ? 'R':'.');
+ p = p->next;
+ }
+ }
+ PRINTF("End of memory blocks\n");
+}
+
+memHeap_t *mmInit(int ofs,
+ int size)
+{
+ PMemBlock blocks;
+
+ if (size <= 0) {
+ return 0;
+ }
+ blocks = (TMemBlock *) calloc(1,sizeof(TMemBlock));
+ if (blocks) {
+ blocks->ofs = ofs;
+ blocks->size = size;
+ blocks->free = 1;
+ return (memHeap_t *)blocks;
+ } else
+ return 0;
+}
+
+/* Kludgey workaround for existing i810 server. Remove soon.
+ */
+memHeap_t *mmAddRange( memHeap_t *heap,
+ int ofs,
+ int size )
+{
+ PMemBlock blocks;
+ blocks = (TMemBlock *) calloc(2,sizeof(TMemBlock));
+ if (blocks) {
+ blocks[0].size = size;
+ blocks[0].free = 1;
+ blocks[0].ofs = ofs;
+ blocks[0].next = &blocks[1];
+
+ /* Discontinuity - stops JoinBlock from trying to join non-adjacent
+ * ranges.
+ */
+ blocks[1].size = 0;
+ blocks[1].free = 0;
+ blocks[1].ofs = ofs+size;
+ blocks[1].next = (PMemBlock) heap;
+ return (memHeap_t *)blocks;
+ }
+ else
+ return heap;
+}
+
+static TMemBlock* SliceBlock(TMemBlock *p,
+ int startofs, int size,
+ int reserved, int alignment)
+{
+ TMemBlock *newblock;
+
+ /* break left */
+ if (startofs > p->ofs) {
+ newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock));
+ newblock->ofs = startofs;
+ newblock->size = p->size - (startofs - p->ofs);
+ newblock->free = 1;
+ newblock->next = p->next;
+ p->size -= newblock->size;
+ p->next = newblock;
+ p = newblock;
+ }
+
+ /* break right */
+ if (size < p->size) {
+ newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock));
+ newblock->ofs = startofs + size;
+ newblock->size = p->size - size;
+ newblock->free = 1;
+ newblock->next = p->next;
+ p->size = size;
+ p->next = newblock;
+ }
+
+ /* p = middle block */
+ p->align = alignment;
+ p->free = 0;
+ p->reserved = reserved;
+ return p;
+}
+
+PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
+{
+ int mask,startofs,endofs;
+ TMemBlock *p;
+
+ if (!heap || align2 < 0 || size <= 0)
+ return NULL;
+ mask = (1 << align2)-1;
+ startofs = 0;
+ p = (TMemBlock *)heap;
+ while (p) {
+ if (ISFREE(p)) {
+ startofs = (p->ofs + mask) & ~mask;
+ if ( startofs < startSearch ) {
+ startofs = startSearch;
+ }
+ endofs = startofs+size;
+ if (endofs <= (p->ofs+p->size))
+ break;
+ }
+ p = p->next;
+ }
+ if (!p)
+ return NULL;
+ p = SliceBlock(p,startofs,size,0,mask+1);
+ p->heap = heap;
+ return p;
+}
+
+static __inline__ int Join2Blocks(TMemBlock *p)
+{
+ if (p->free && p->next && p->next->free) {
+ TMemBlock *q = p->next;
+ p->size += q->size;
+ p->next = q->next;
+ free(q);
+ return 1;
+ }
+ return 0;
+}
+
+int mmFreeMem(PMemBlock b)
+{
+ TMemBlock *p,*prev;
+
+ if (!b)
+ return 0;
+ if (!b->heap) {
+ fprintf(stderr, "no heap\n");
+ return -1;
+ }
+ p = b->heap;
+ prev = NULL;
+ while (p && p != b) {
+ prev = p;
+ p = p->next;
+ }
+ if (!p || p->free || p->reserved) {
+ if (!p)
+ fprintf(stderr, "block not found in heap\n");
+ else if (p->free)
+ fprintf(stderr, "block already free\n");
+ else
+ fprintf(stderr, "block is reserved\n");
+ return -1;
+ }
+ p->free = 1;
+ Join2Blocks(p);
+ if (prev)
+ Join2Blocks(prev);
+ return 0;
+}
+
+int mmReserveMem(memHeap_t *heap, int offset,int size)
+{
+ int endofs;
+ TMemBlock *p;
+
+ if (!heap || size <= 0)
+ return -1;
+ endofs = offset+size;
+ p = (TMemBlock *)heap;
+ while (p && p->ofs <= offset) {
+ if (ISFREE(p) && endofs <= (p->ofs+p->size)) {
+ SliceBlock(p,offset,size,1,1);
+ return 0;
+ }
+ p = p->next;
+ }
+ return -1;
+}
+
+int mmFreeReserved(memHeap_t *heap, int offset)
+{
+ TMemBlock *p,*prev;
+
+ if (!heap)
+ return -1;
+ p = (TMemBlock *)heap;
+ prev = NULL;
+ while (p && p->ofs != offset) {
+ prev = p;
+ p = p->next;
+ }
+ if (!p || !p->reserved)
+ return -1;
+ p->free = 1;
+ p->reserved = 0;
+ Join2Blocks(p);
+ if (prev)
+ Join2Blocks(prev);
+ return 0;
+}
+
+void mmDestroy(memHeap_t *heap)
+{
+ TMemBlock *p,*q;
+
+ if (!heap)
+ return;
+ p = (TMemBlock *)heap;
+ while (p) {
+ q = p->next;
+ free(p);
+ p = q;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/mm.h b/xc/lib/GL/mesa/src/drv/r128/mm.h
new file mode 100644
index 000000000..6fa6e8b69
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/mm.h
@@ -0,0 +1,101 @@
+/*
+ * GLX Hardware Device Driver common code
+ * Copyright (C) 1999 Keith Whitwell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef MM_INC
+#define MM_INC
+
+struct mem_block_t {
+ struct mem_block_t *next;
+ struct mem_block_t *heap;
+ int ofs,size;
+ int align;
+ int free:1;
+ int reserved:1;
+};
+typedef struct mem_block_t TMemBlock;
+typedef struct mem_block_t *PMemBlock;
+
+/* a heap is just the first block in a chain */
+typedef struct mem_block_t memHeap_t;
+
+static __inline__ int mmBlockSize(PMemBlock b)
+{ return b->size; }
+
+static __inline__ int mmOffset(PMemBlock b)
+{ return b->ofs; }
+
+static __inline__ void mmMarkReserved(PMemBlock b)
+{ b->reserved = 1; }
+
+/*
+ * input: total size in bytes
+ * return: a heap pointer if OK, NULL if error
+ */
+memHeap_t *mmInit( int ofs, int size );
+
+
+
+memHeap_t *mmAddRange( memHeap_t *heap,
+ int ofs,
+ int size );
+
+
+/*
+ * Allocate 'size' bytes with 2^align2 bytes alignment,
+ * restrict the search to free memory after 'startSearch'
+ * depth and back buffers should be in different 4mb banks
+ * to get better page hits if possible
+ * input: size = size of block
+ * align2 = 2^align2 bytes alignment
+ * startSearch = linear offset from start of heap to begin search
+ * return: pointer to the allocated block, 0 if error
+ */
+PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch );
+
+/*
+ * Free block starts at offset
+ * input: pointer to a block
+ * return: 0 if OK, -1 if error
+ */
+int mmFreeMem( PMemBlock b );
+
+/*
+ * Reserve 'size' bytes block start at offset
+ * This is used to prevent allocation of memory already used
+ * by the X server for the front buffer, pixmaps, and cursor
+ * input: size, offset
+ * output: 0 if OK, -1 if error
+ */
+int mmReserveMem( memHeap_t *heap, int offset,int size );
+int mmFreeReserved( memHeap_t *heap, int offset );
+
+/*
+ * destroy MM
+ */
+void mmDestroy( memHeap_t *mmInit );
+
+/* For debuging purpose. */
+void mmDumpMemInfo( memHeap_t *mmInit );
+
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_cce.c b/xc/lib/GL/mesa/src/drv/r128/r128_cce.c
index 9f9fec81c..63742fe78 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_cce.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_cce.c
@@ -38,6 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128_reg.h"
#include "r128_cce.h"
+/* FIXME: Requires access to secure registers */
static int INPLL(r128ScreenPtr pScrn, int addr)
{
unsigned char *R128MMIO = pScrn->mmio;
@@ -46,6 +47,7 @@ static int INPLL(r128ScreenPtr pScrn, int addr)
return INREG(R128_CLOCK_CNTL_DATA);
}
+/* FIXME: Requires access to secure registers */
void R128EngineFlush(r128ScreenPtr pScrn)
{
unsigned char *R128MMIO = pScrn->mmio;
@@ -57,6 +59,7 @@ void R128EngineFlush(r128ScreenPtr pScrn)
}
}
+/* FIXME: Requires access to secure registers */
void R128EngineReset(r128ScreenPtr pScrn)
{
unsigned char *R128MMIO = pScrn->mmio;
@@ -83,6 +86,8 @@ void R128EngineReset(r128ScreenPtr pScrn)
OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl);
}
+/* The FIFO has 64 slots. This routines waits until at least `entries'
+ of these slots are empty. */
void R128WaitForFifoFunction(r128ScreenPtr pScrn, int entries)
{
unsigned char *R128MMIO = pScrn->mmio;
@@ -100,6 +105,9 @@ void R128WaitForFifoFunction(r128ScreenPtr pScrn, int entries)
}
}
+/* Wait for the graphics engine to be completely idle: the FIFO has
+ drained, the Pixel Cache is flushed, and the engine is idle. This is
+ a standard "sync" function that will make the hardware quiescent. */
void R128WaitForIdle(r128ScreenPtr pScrn)
{
unsigned char *R128MMIO = pScrn->mmio;
@@ -120,6 +128,8 @@ void R128WaitForIdle(r128ScreenPtr pScrn)
}
}
+/* Wait for at least `entries' slots are free. The actual number of
+ slots available is stored in info->CCEFifoSize. */
void R128CCEWaitForFifoFunction(r128ScreenPtr pScrn, int entries)
{
unsigned char *R128MMIO = pScrn->mmio;
@@ -136,6 +146,8 @@ void R128CCEWaitForFifoFunction(r128ScreenPtr pScrn, int entries)
}
}
+/* Wait until the CCE is completely idle: the FIFO has drained and the
+ CCE is idle. */
void R128CCEWaitForIdle(r128ScreenPtr pScrn)
{
unsigned char *R128MMIO = pScrn->mmio;
@@ -157,28 +169,23 @@ void R128CCEWaitForIdle(r128ScreenPtr pScrn)
}
}
-/* NOTE: This function must be called before using the CCE */
-void R128CCEStart(r128ScreenPtr pScrn)
+/* Flush the CPU's write-combining cache */
+void R128FlushWCMemory(void)
{
- unsigned char *R128MMIO = pScrn->mmio;
-
- R128WaitForIdle(pScrn);
- OUTREG(R128_PM4_BUFFER_CNTL, pScrn->CCEMode);
- (void)INREG(R128_PM4_BUFFER_ADDR); /* as per the sample code */
- OUTREG(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN);
-}
-
-/* NOTE: This function must be called before using the standard MMIO
- mode for the X server. Also, this function is not (currently) called
- by the client-side DRI driver; rather, it is only called in the X
- server when the X server's context is swapped in. */
-void R128CCEEnd(r128ScreenPtr pScrn)
-{
- unsigned char *R128MMIO = pScrn->mmio;
-
- R128CCEWaitForIdle(pScrn);
- OUTREGP(R128_PM4_BUFFER_DL_WPTR,
- R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE);
- OUTREG(R128_PM4_MICRO_CNTL, 0);
- OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4);
+ int xchangeDummy;
+
+ /* FIXME: This should be in standard XFree86 assembly format */
+ __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 */);
}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_cce.h b/xc/lib/GL/mesa/src/drv/r128/r128_cce.h
index a1d426eb8..5da4fd348 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_cce.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_cce.h
@@ -37,24 +37,48 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
+#include "r128_dri.h"
+#include "r128_reg.h"
+
typedef union {
float f;
int i;
} floatTOint;
-#define R128_USE_CCE_PIO_MODE
-#ifdef R128_USE_CCE_PIO_MODE
+#if (R128_CCE_MODE == R128_PM4_192PIO) || \
+ (R128_CCE_MODE == R128_PM4_128PIO_64INDBM) || \
+ (R128_CCE_MODE == R128_PM4_64PIO_128INDBM) || \
+ (R128_CCE_MODE == R128_PM4_64PIO_64VCBM_64INDBM) || \
+ (R128_CCE_MODE == R128_PM4_64PIO_64VCPIO_64INDPIO)
+
+/* The ring buffer is in PIO mode */
+/* Start a sequence of CCE commands. This grabs the lock, and wait for
+ `n' entries to be free in the ring buffer. */
#define R128CCE_BEGIN(n) \
do { \
LOCK_HARDWARE(r128ctx); \
R128WaitForFifo(r128ctx->r128Screen, (n)); \
} while (0)
+
+/* End a sequence of CCE commands. This also releases the lock. */
+#define R128CCE_END() \
+ do { \
+ if (r128ctx->r128Screen->CCEFifoAddr != R128_PM4_FIFO_DATA_EVEN) { \
+ OUTREG(r128ctx->r128Screen->CCEFifoAddr, R128_CCE_PACKET2); \
+ r128ctx->r128Screen->CCEFifoAddr ^= 0x0004; \
+ } \
+ UNLOCK_HARDWARE(r128ctx); \
+ } while (0)
+
+/* Insert an integer value into the CCE ring buffer. */
#define R128CCE(v) \
do { \
OUTREG(r128ctx->r128Screen->CCEFifoAddr, (v)); \
r128ctx->r128Screen->CCEFifoAddr ^= 0x0004; \
} while (0)
+
+/* Insert an floating point value into the CCE ring buffer. */
#define R128CCEF(v) \
do { \
floatTOint fTi; \
@@ -62,23 +86,14 @@ typedef union {
OUTREG(r128ctx->r128Screen->CCEFifoAddr, fTi.i); \
r128ctx->r128Screen->CCEFifoAddr ^= 0x0004; \
} while (0)
-#define R128CCE_END() \
- do { \
- if (r128ctx->r128Screen->CCEFifoAddr != R128_PM4_FIFO_DATA_EVEN) { \
- OUTREG(r128ctx->r128Screen->CCEFifoAddr, R128_CCE_PACKET2); \
- r128ctx->r128Screen->CCEFifoAddr ^= 0x0004; \
- } \
- UNLOCK_HARDWARE(r128ctx); \
- } while (0)
-#define R128CCE_BEGIN_LOCKED(n) \
- do { \
- R128WaitForFifo(r128ctx->r128Screen, (n)); \
- } while (0)
+/* Wait for `n' entries to be free in the ring buffer, while locked. */
#define R128CCE_WAIT_LOCKED(n) \
do { \
R128WaitForFifo(r128ctx->r128Screen, (n)); \
} while (0)
+
+/* End a sequence of CCE commands, but do not releases the lock. */
#define R128CCE_END_LOCKED() \
do { \
if (r128ctx->r128Screen->CCEFifoAddr != R128_PM4_FIFO_DATA_EVEN) { \
@@ -89,12 +104,31 @@ typedef union {
#else
+/* The ring buffer is in BM mode */
+/* FIXME: Implement support for the ring buffer */
+
+/* Start a sequence of CCE commands. This grabs the lock, and wait for
+ `n' entries to be free in the ring buffer. */
#define R128CCE_BEGIN(n)
-#define R128CCE(v)
+
+/* End a sequence of CCE commands. This also releases the lock. */
#define R128CCE_END()
+/* Insert an integer value into the CCE ring buffer. */
+#define R128CCE(v)
+
+/* Insert an floating point value into the CCE ring buffer. */
+#define R128CCEF(v)
+
+/* Wait for `n' entries to be free in the ring buffer, while locked. */
+#define R128CCE_WAIT_LOCKED(n)
+
+/* End a sequence of CCE commands, but do not releases the lock. */
+#define R128CCE_END_LOCKED()
+
#endif
+/* 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))
@@ -125,8 +159,7 @@ extern void R128WaitForIdle(r128ScreenPtr pScrn);
extern void R128CCEWaitForFifoFunction(r128ScreenPtr pScrn, int entries);
extern void R128CCEWaitForIdle(r128ScreenPtr pScrn);
-extern void R128CCEStart(r128ScreenPtr pScrn);
-extern void R128CCEEnd(r128ScreenPtr pScrn);
+extern void R128FlushWCMemory(void);
#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..2a1d4e590
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_ccevb.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_CCEVB_H_
+#define _R128_CCEVB_H_
+
+#ifdef GLX_DIRECT_RENDERING
+
+typedef struct {
+ int start; /* in bytes from the beginning of AGP memory */
+ int count; /* in vertices */
+ int size; /* in vertices */
+ int done; /* VB has been sent to ring (FIXME) */
+} r128CCEVertBuf, *r128CCEVertBufPtr;
+
+#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
index 19aaaebfe..b10bb4629 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_clear.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_clear.c
@@ -39,106 +39,125 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128_lock.h"
#include "r128_reg.h"
#include "r128_cce.h"
+#include "r128_vb.h"
#include "r128_clear.h"
+/* Clear the depth buffer */
void r128ClearDepthBuffer(r128ContextPtr r128ctx, GLboolean all,
- GLint x, GLint y, GLint width, GLint height)
+ GLint cx, GLint cy, GLint cw, GLint ch)
{
- unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
- int dst_bpp;
- CARD32 write_mask;
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable;
+ int nc = dPriv->numClipRects;
+ XF86DRIClipRectPtr c = dPriv->pClipRects;
+ 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:
- dst_bpp = R128_GMC_DST_16BPP;
write_mask = 0x0000ffff;
+ dst_bpp = R128_GMC_DST_16BPP;
break;
case R128_Z_PIX_WIDTH_24:
- dst_bpp = R128_GMC_DST_24BPP;
write_mask = 0x00ffffff;
+ dst_bpp = R128_GMC_DST_24BPP;
break;
case R128_Z_PIX_WIDTH_32:
- dst_bpp = R128_GMC_DST_32BPP;
write_mask = 0xffffffff;
+ dst_bpp = R128_GMC_DST_32BPP;
break;
default: return;
}
- /* FIXME: save DP_WRITE_MASK or add to context???? */
- /* FIXME: use x, y, width, height */
+ cx += dPriv->x;
+ cy = dPriv->y + dPriv->h - cy - ch;
- R128CCE_BEGIN(11);
+ /* Flush any outstanding vertex buffers */
+ R128_FLUSH_VB(r128ctx);
+
+ LOCK_HARDWARE(r128ctx);
/* Set the write mask so that we _only_ clear the Z buffer */
+ R128CCE_WAIT_LOCKED(2);
R128CCE0(R128_CCE_PACKET0, R128_DP_WRITE_MASK, 0);
R128CCE(write_mask);
/* Temporarily disable Z and stencil buffer and texture mapping modes */
+ R128CCE_WAIT_LOCKED(2);
R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
R128CCE(r128ctx->regs.tex_cntl_c & ~(R128_Z_ENABLE |
R128_STENCIL_ENABLE |
R128_TEXMAP_ENABLE));
- R128CCE3(R128_CCE_PACKET3_CNTL_PAINT_MULTI, 3);
-#if 0
- /* FIXME: do we want to set R128_GMC_DST_PITCH_OFFSET_CNTL?
- This requires us to include the offset and pitch
- registers below, but this could be very useful since it
- means we don't have to add the depthX and depthY values
- to the drawable's x and y values. */
- R128CCE(R128_GMC_DST_PITCH_OFFSET_CNTL
- | 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?? */
-#else
- 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?? */
-#endif
- R128CCE(r128ctx->ClearDepth);
- R128CCE(((r128ctx->driDrawable->x + r128ctx->r128Screen->depthX)<< 16)
- | (r128ctx->driDrawable->y + r128ctx->r128Screen->depthY));
- R128CCE((r128ctx->driDrawable->w << 16) | r128ctx->driDrawable->h);
+ /* 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;
+
+ R128CCE_WAIT_LOCKED(5);
+ 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
- /* FIXME: if we include this, change CCE_BEGIN() above */
-
/* Set the write mask so that we _only_ clear the Z buffer */
- /* FIXME: should this be in the context? */
+ R128CCE_WAIT_LOCKED(2);
R128CCE0(R128_CCE_PACKET0, R128_DP_WRITE_MASK, 0);
R128CCE(0xffffffff);
/* Restore Z and stencil buffer and texture mapping modes */
+ R128CCE_WAIT_LOCKED(2);
R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
R128CCE(r128ctx->regs.tex_cntl_c);
#else
- /* FIXME: this should not be needed! */
+ /* 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;
- /* r128UpdateState(r128ctx); */
#endif
- R128CCE_END();
+ R128CCE_END_LOCKED();
+
+ UNLOCK_HARDWARE(r128ctx);
}
+/* Clear a color buffer */
void r128ClearColorBuffer(r128ContextPtr r128ctx, GLboolean all,
- GLint x, GLint y, GLint width, GLint height)
+ GLint cx, GLint cy, GLint cw, GLint ch)
{
- unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
- int dst_bpp;
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable;
+ int nc = dPriv->numClipRects;
+ XF86DRIClipRectPtr c = dPriv->pClipRects;
+ int dst_bpp;
switch (r128ctx->r128Screen->bpp) {
case 8:
@@ -157,44 +176,73 @@ void r128ClearColorBuffer(r128ContextPtr r128ctx, GLboolean all,
break;
}
- /* FIXME: use x, y, width, height */
+ cx += dPriv->x;
+ cy = dPriv->y + dPriv->h - cy - ch;
+
/* FIXME: use R128_GMC_DST_PITCH_OFFSET_CNTL to set to the back
buffer when we should be draing to the back buffer? */
- R128CCE_BEGIN(7);
+ /* Flush any outstanding vertex buffers */
+ R128_FLUSH_VB(r128ctx);
+
+ LOCK_HARDWARE(r128ctx);
/* Temporarily disable Z and stencil buffer and texture mapping modes */
+ R128CCE_WAIT_LOCKED(2);
R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
R128CCE(r128ctx->regs.tex_cntl_c & ~(R128_Z_ENABLE |
R128_STENCIL_ENABLE |
R128_TEXMAP_ENABLE));
- 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);
- /* FIXME: when not using the back buf, make sure clears go to front buf */
- R128CCE(((r128ctx->driDrawable->x + r128ctx->bufX)<< 16)
- | (r128ctx->driDrawable->y + r128ctx->bufY));
- R128CCE((r128ctx->driDrawable->w << 16) | r128ctx->driDrawable->h);
+ /* 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 += r128ctx->bufX;
+ y += r128ctx->bufY;
+
+ R128CCE_WAIT_LOCKED(5);
+ 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
- /* FIXME: if we include this, change CCE_BEGIN() above */
/* Restore Z and stencil buffer and texture mapping modes */
+ R128CCE_WAIT_LOCKED(2);
R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
R128CCE(r128ctx->regs.tex_cntl_c);
#else
- /* FIXME: this should not be needed! */
+ /* 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;
- /* r128UpdateState(r128ctx); */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALL_DIRTY;
#endif
- R128CCE_END();
+ R128CCE_END_LOCKED();
+
+ UNLOCK_HARDWARE(r128ctx);
}
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..e3983d214
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c
@@ -0,0 +1,183 @@
+/* $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_dd.h"
+#include "r128_state.h"
+#include "r128_span.h"
+#include "r128_depth.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 */
+r128ContextPtr r128CreateContext(GLvisual *glVisual,
+ XMesaContext c,
+ XMesaContext share_list)
+{
+ r128ContextPtr r128ctx;
+ GLcontext *shareCtx, *glCtx;
+
+ r128ctx = (r128ContextPtr)Xmalloc(sizeof(*r128ctx));
+ if (!r128ctx) return NULL;
+
+ if (share_list)
+ shareCtx = ((r128ContextPtr)(share_list->private))->glCtx;
+ else
+ shareCtx = NULL;
+
+ /* Initialize r128Context */
+ r128ctx->xmCtx = c;
+ r128ctx->glCtx = gl_create_context(glVisual,
+ shareCtx,
+ (void *)r128ctx,
+ GL_TRUE);
+ r128ctx->display = c->display;
+ r128ctx->driContext = c->driContextPriv;
+ r128ctx->driDrawable = NULL; /* Set by XMesaMakeCurrent */
+ r128ctx->dirty = R128_ALL_DIRTY;
+ r128ctx->dirty_context = R128_CTX_ALL_DIRTY;
+ r128ctx->needClip = GL_TRUE;
+ 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;
+ r128ctx->r128Screen =
+ (r128ScreenPtr)(c->driContextPriv->driScreenPriv->private);
+ r128ctx->SAREA =
+ (R128SAREAPrivPtr)((char *)c->driContextPriv->driScreenPriv->pSAREA +
+ sizeof(XF86DRISAREARec));
+
+ r128ctx->CurrentTexObj[0] = NULL;
+ r128ctx->CurrentTexObj[1] = NULL;
+ make_empty_list(&r128ctx->TexObjList);
+ make_empty_list(&r128ctx->SwappedOut);
+#if USE_AGP_TEXTURES
+ r128ctx->texHeap = mmInit(0, r128ctx->r128Screen->agpTexSize);
+#else
+ r128ctx->texHeap = mmInit(0, r128ctx->r128Screen->textureSize);
+#endif
+ r128ctx->lastTexAge = -1;
+
+ r128ctx->RenderIndex = -1;
+ r128ctx->useFastPath = GL_FALSE;
+
+ r128ctx->vb = NULL;
+
+ /* Initialize GLcontext */
+ glCtx = r128ctx->glCtx;
+
+ r128DDInitExtensions(glCtx);
+
+ r128DDInitDriverFuncs(glCtx);
+ r128DDInitStateFuncs(glCtx);
+ r128DDInitSpanFuncs(glCtx);
+ r128DDInitDepthFuncs(glCtx);
+ r128DDInitTextureFuncs(glCtx);
+
+ glCtx->Driver.TriangleCaps = (DD_TRI_CULL
+ | DD_TRI_LIGHT_TWOSIDE
+ | DD_TRI_OFFSET);
+ glCtx->TriangleCaps |= DD_CLIP_FOG_COORD;
+
+ /* 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);
+
+ return r128ctx;
+}
+
+/* Destroy the device specific context */
+void r128DestroyContext(r128ContextPtr r128ctx)
+{
+ if (r128ctx) {
+ r128TexObjPtr t, next_t;
+
+ foreach_s (t, next_t, &r128ctx->TexObjList)
+ 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) {
+ 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_ALL_DIRTY;
+ 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
index 3127223ef..1be2070b5 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_context.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h
@@ -37,17 +37,50 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
+#include "r128_sarea.h"
+#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_START_CCE 0x0002
-#define R128_UPDATE_CONTEXT 0x0004
-#define R128_UPDATE_CLIPRECTS 0x0008
+#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_ZSTENSTATE 0x0040
+#define R128_CTX_SCISSORS 0x0080
+#define R128_CTX_ALPHASTATE 0x0100
+#define R128_CTX_SETUPSTATE 0x0200
+#define R128_CTX_WIN_Z_POS 0x0400
+#define R128_CTX_FLUSH_PIX_CACHE 0x0800
+#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 scale_3d_cntl; /* 0x1a00 */
- CARD32 dst_pitch_offset_c; /* 0x1c80 */
+ CARD32 dst_pitch_offset_c; /* 0x1c80 */
CARD32 dp_gui_master_cntl;
CARD32 sc_top_left_c;
CARD32 sc_bottom_right_c;
@@ -62,80 +95,100 @@ typedef struct {
CARD32 prim_tex_cntl_c;
CARD32 prim_texture_combine_cntl_c;
CARD32 tex_size_pitch_c;
- CARD32 prim_tex_0_offset_c;
- CARD32 prim_tex_1_offset_c;
- CARD32 prim_tex_2_offset_c;
- CARD32 prim_tex_3_offset_c;
- CARD32 prim_tex_4_offset_c;
- CARD32 prim_tex_5_offset_c;
- CARD32 prim_tex_6_offset_c;
- CARD32 prim_tex_7_offset_c;
- CARD32 prim_tex_8_offset_c;
- CARD32 prim_tex_9_offset_c;
- CARD32 prim_tex_10_offset_c; /* 0x1ce4 */
-
- CARD32 sec_tex_cntl_c; /* 0x1d00 */
+ CARD32 prim_tex_offset[R128_TEX_MAXLEVELS]; /* 0x1ce4 */
+
+ CARD32 sec_tex_cntl_c; /* 0x1d00 */
CARD32 sec_tex_combine_cntl_c;
- CARD32 sec_tex_0_offset_c;
- CARD32 sec_tex_1_offset_c;
- CARD32 sec_tex_2_offset_c;
- CARD32 sec_tex_3_offset_c;
- CARD32 sec_tex_4_offset_c;
- CARD32 sec_tex_5_offset_c;
- CARD32 sec_tex_6_offset_c;
- CARD32 sec_tex_7_offset_c;
- CARD32 sec_tex_8_offset_c;
- CARD32 sec_tex_9_offset_c;
- CARD32 sec_tex_10_offset_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 plane_3d_mask_c; /* 0x1d44 */
+
+ CARD32 setup_cntl; /* 0x1bc4 */
- CARD32 setup_cntl; /* 0x1bc4 */
- CARD32 pm4_vc_fpu_setup; /* 0x071c */
+ CARD32 pm4_vc_fpu_setup; /* 0x071c */
- CARD32 fog_3d_table_start; /* 0x1810 */
+ CARD32 fog_3d_table_start; /* 0x1810 */
CARD32 fog_3d_table_end;
- CARD32 fog_3d_table_density; /* 0x181c */
+ CARD32 fog_3d_table_density; /* 0x181c */
- CARD32 window_xy_offset; /* 0x1bcc */
+ CARD32 window_xy_offset; /* 0x1bcc */
- CARD32 dp_write_mask; /* 0x16cc */
+ CARD32 dp_write_mask; /* 0x16cc */
+
+ CARD32 pc_gui_ctlstat; /* 0x1748 */
} r128ContextRegs;
typedef struct {
- XMesaContext xmCtx;
- GLcontext *glCtx;
- int dirty;
- int needClip;
-
- int RenderIndex;
- points_func PointsFunc;
- line_func LineFunc;
+ XMesaContext xmCtx; /* XMesa context */
+ GLcontext *glCtx; /* Mesa context */
+ int dirty; /* Hardware state to be updated */
+ int dirty_context; /* Context state to be updated */
+
+ int needClip; /* Primitives need to be clipped
+ to the window */
+
+ int SWonly; /* Force software-only rendering */
+ int SWfallbackDisable; /* Disable software fallbacks */
+
+
+ r128TexObjPtr CurrentTexObj[2]; /* Ptr to current texture
+ object associated with
+ each texture unit */
+ r128TexObj TexObjList; /* List of textures swapped in */
+ r128TexObj SwappedOut; /* List of textures swapped out */
+ memHeap_t *texHeap; /* Global heap of textures */
+ int lastTexAge; /* Last known global texture age */
+
+ 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 */
+
+ r128CCEVertBufPtr vb; /* VB currently being filled */
+
+ points_func PointsFunc; /* Current Points, Line, Triangle */
+ line_func LineFunc; /* and Quad rendering functions */
triangle_func TriangleFunc;
quad_func QuadFunc;
- CARD32 IndirectTriangles;
- CARD32 Fallback;
+ 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 */
- r128ContextRegs regs;
- CARD32 ClearColor;
- CARD32 ClearDepth;
+ int bufX; /* x-offset to current draw buffer */
+ int bufY; /* y-offset to current draw buffer */
- int bufX;
- int bufY;
+ R128SAREAPrivPtr SAREA; /* Pointer to SAREA private data */
- Display *display;
+ Display *display; /* X server display */
- __DRIcontextPrivate *driContext;
- __DRIdrawablePrivate *driDrawable;
+ __DRIcontextPrivate *driContext; /* DRI context */
+ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
- r128ScreenPtr r128Screen;
+ r128ScreenPtr r128Screen; /* Screen private DRI data */
} r128ContextRec, *r128ContextPtr;
-extern r128ContextPtr r128Context;
+#define R128_MESACTX(r128ctx) ((r128ctx)->glCtx)
+#define R128_DRIDRAWABLE(r128ctx) ((r128ctx)->driDrawable)
+#define R128_DRISCREEN(r128ctx) ((r128ctx)->r128Screen->driScreen)
+
+extern r128ContextPtr r128CreateContext(GLvisual *glVisual,
+ XMesaContext c,
+ XMesaContext share_list);
+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
index 04745d240..230205783 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c
@@ -37,8 +37,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128_cce.h"
#include "r128_clear.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)
{
@@ -55,6 +57,7 @@ static GLbitfield r128DDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
}
#if 0
+ /* FIXME: Add stencil support */
if (mask & GL_STENCIL_BUFFER_BIT) {
r128ClearStencilBuffer(r128ctx, all, x, y, width, height);
mask &= ~GL_STENCIL_BUFFER_BIT;
@@ -64,6 +67,7 @@ static GLbitfield r128DDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
return mask;
}
+/* Return the current color buffer size */
static void r128DDGetBufferSize(GLcontext *ctx, GLuint *width, GLuint *height)
{
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
@@ -72,6 +76,7 @@ static void r128DDGetBufferSize(GLcontext *ctx, GLuint *width, GLuint *height)
*height = r128ctx->driDrawable->h;
}
+/* Return various strings for glGetString() */
static const GLubyte *r128DDGetString(GLcontext *ctx, GLenum name)
{
switch (name) {
@@ -84,53 +89,75 @@ static const GLubyte *r128DDGetString(GLcontext *ctx, GLenum name)
}
}
+/* 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)
+{
+ R128_FLUSH_VB(R128_CONTEXT(ctx));
+}
+
+/* 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);
R128CCEWaitForIdle(r128ctx->r128Screen);
}
-static void r128DDFlush(GLcontext *ctx)
-{
- /* Nothing to do here since all commands are automatically flushed */
-}
-
+/* Return various parameters requested by Mesa */
static GLint r128DDGetParameteri(const GLcontext *ctx, GLint param)
{
switch (param) {
#if 0
- case DD_MAX_TEXTURE_SIZE:
- return 2048; /* FIXME ?? */
- case DD_MAX_TEXTURES:
- return 2; /* FIXME ?? */
- case DD_HAVE_HARDWARE_FOG:
- return 1; /* FIXME ?? */
+ /* FIXME: Support for these needs to be added to Mesa */
+ case DD_MAX_TEXTURE_SIZE: return 1024;
+ case DD_MAX_TEXTURES: return 2;
#endif
- default:
- return 0;
+#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.Clear = r128DDClear;
- ctx->Driver.GetBufferSize = r128DDGetBufferSize;
- ctx->Driver.GetString = r128DDGetString;
- ctx->Driver.Finish = r128DDFinish;
- ctx->Driver.Flush = r128DDFlush;
+ 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.Error = NULL;
+ ctx->Driver.GetParameteri = r128DDGetParameteri;
- ctx->Driver.DrawPixels = NULL;
- ctx->Driver.Bitmap = NULL;
+ ctx->Driver.DrawPixels = NULL;
+ ctx->Driver.Bitmap = NULL;
- ctx->Driver.RegisterVB = r128DDRegisterVB;
- ctx->Driver.UnregisterVB = r128DDUnregisterVB;
+ ctx->Driver.RegisterVB = r128DDRegisterVB;
+ ctx->Driver.UnregisterVB = r128DDUnregisterVB;
+ ctx->Driver.BuildPrecalcPipeline = r128DDBuildPrecalcPipeline;
}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_depth.c b/xc/lib/GL/mesa/src/drv/r128/r128_depth.c
index 0c4076058..589556b15 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_depth.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_depth.c
@@ -58,10 +58,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
volatile GLdepth *zptr; \
int i
+/* Return a pointer to the offset in the depth buffer at (x,y) */
#define DEPTH_ADDR(base, _x, _y) \
(GLdepth*)(zbase + _x * (r128scrn->bpp/8) + \
(height - _y) * r128scrn->fbStride)
+/* Test a span for a particular `_op_' comparison, and update the depth
+ buffer (if needed). */
#define DEPTH_TEST_SPAN(_op_) \
if (ctx->Depth.Mask) { /* Update Z buffer */ \
for (i = 0; i < n; i++, zptr++, m++) { \
@@ -86,6 +89,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
} \
}
+/* Test a list of pixels for a particular `_op_' comparison, and update
+ the depth buffer (if needed). */
#define DEPTH_TEST_PIXELS(_op_) \
if (ctx->Depth.Mask) { /* Update Z buffer */ \
for (i = 0; i < n; i++) { \
@@ -105,10 +110,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
} \
}
+/* Allocate a depth buffer */
static void r128DDAllocDepthBuffer(GLcontext *ctx)
{
}
+/* Update the depth buffer for a given span. This is only used for
+ software fallbacks. */
static GLuint r128DDDepthTestSpan(GLcontext *ctx,
GLuint n, GLint x, GLint y,
const GLdepth z[],
@@ -154,6 +162,8 @@ static GLuint r128DDDepthTestSpan(GLcontext *ctx,
return passed;
}
+/* Update the depth buffer for a given array of pixels. This is only
+ used for software fallbacks. */
static void r128DDDepthTestPixels(GLcontext *ctx,
GLuint n,
const GLint x[],
@@ -195,6 +205,8 @@ static void r128DDDepthTestPixels(GLcontext *ctx,
UNLOCK_HARDWARE(r128ctx);
}
+/* Return a span in the depth buffer as floats. This is only used for
+ software fallbacks. */
static void r128DDReadDepthSpanFloat(GLcontext *ctx,
GLuint n,
GLint x, GLint y, GLfloat depth[])
@@ -216,6 +228,8 @@ static void r128DDReadDepthSpanFloat(GLcontext *ctx,
UNLOCK_HARDWARE(r128ctx);
}
+/* Return a span in the depth buffer as ints. This is only used for
+ software fallbacks. */
static void r128DDReadDepthSpanInt(GLcontext *ctx,
GLuint n,
GLint x, GLint y, GLdepth depth[])
@@ -237,6 +251,7 @@ static void r128DDReadDepthSpanInt(GLcontext *ctx,
}
+/* Initialize the driver's depth functions */
void r128DDInitDepthFuncs(GLcontext *ctx)
{
ctx->Driver.AllocDepthBuffer = r128DDAllocDepthBuffer;
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..953f9d9a6
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c
@@ -0,0 +1,537 @@
+/* $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) r128DrawPoint(r128ctx, &vert[x].v, psize)
+#define LINE(x,y) r128DrawLine(r128ctx, &vert[x].v, &vert[y].v, lwidth)
+#define TRI(x,y,z) r128DrawTriangle(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] * (1.0 / 0x10000);
+ m[MAT_TZ] = mat->m[MAT_TZ] * (1.0 / 0x10000);
+
+#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] * (1.0 / 0x10000);
+ m[MAT_TZ] = mat->m[MAT_TZ] * (1.0 / 0x10000);
+
+#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
index 6cb43ae90..2140a7525 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_init.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_init.h
@@ -48,8 +48,20 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128_screen.h"
#include "r128_context.h"
-#define DEBUG
-#ifdef DEBUG
+/* 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 USE_FAST_PATH 1
+#define USE_VERTEX_BUFFERS 0
+#define USE_AGP_TEXTURES 0
+#define USE_RGB8_TEXTURES 0
+#define FLUSH_VB_ON_STATE_CHANGE 1
+
+
+#if DEBUG
#include <stdio.h>
#define R128_DEBUG(p) printf p
#endif
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h
index 2d80b0bbe..58bb33f47 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h
@@ -92,6 +92,8 @@ extern int prevLockLine;
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(CC->xmCtx); \
} \
@@ -116,16 +118,26 @@ extern int prevLockLine;
/* FIXME: The Rage128 has multiple clip rects -- optimize! */
#define BEGIN_CLIP_LOOP(CC) \
do { \
- __DRIdrawablePrivate *dPriv = CC->driDrawable; \
- int _nc = dPriv->numClipRects; \
+ __DRIdrawablePrivate *_dPriv = CC->driDrawable; \
+ int _nc = _dPriv->numClipRects; \
\
LOCK_HARDWARE(CC); \
while (_nc--) { \
if (CC->needClip) { \
- r128SetClipRect(CC, &dPriv->pClipRects[_nc]); \
+ r128SetClipRect(CC, &_dPriv->pClipRects[_nc]); \
}
+/* FIXME: Have the X server save/restore its own clip rect */
#define END_CLIP_LOOP(CC) \
+ if (CC->needClip) { \
+ /* FIXME: Move this to r128_state.c ?? */ \
+ unsigned char *R128MMIO = CC->r128Screen->mmio; \
+ R128CCE_WAIT_LOCKED(3); \
+ R128CCE0(R128_CCE_PACKET0, R128_SC_TOP_LEFT_C, 1); \
+ R128CCE(0x00000000); \
+ R128CCE(0x1fff1fff); \
+ R128CCE_END_LOCKED(); \
+ } \
} \
UNLOCK_HARDWARE(CC); \
} while (0)
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..32e72e97d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c
@@ -0,0 +1,160 @@
+/* $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_tris.h"
+#include "r128_vb.h"
+#include "r128_fastpath.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;
+
+ 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;
+ }
+
+ r128Screen->agpRgn.handle = r128DRIPriv->agpHandle;
+ r128Screen->agpRgn.size = r128DRIPriv->agpSize;
+ if (drmMap(sPriv->fd,
+ r128Screen->agpRgn.handle,
+ r128Screen->agpRgn.size,
+ (drmAddressPtr)&r128Screen->agp)) {
+ 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->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->textureX = r128DRIPriv->textureX;
+ r128Screen->textureY = r128DRIPriv->textureY;
+ r128Screen->textureSize = r128DRIPriv->textureSize;
+ r128Screen->log2TexGran = r128DRIPriv->log2TexGran;
+
+#if 0
+ /* FIXME: For testing only */
+ r128Screen->textureX = 0;
+ r128Screen->textureY = 8192;
+ r128Screen->textureSize = 4*1024*1024;
+ r128Screen->log2TexGran = 15;
+#endif
+
+#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->ringStart = r128DRIPriv->ringStart;
+ r128Screen->ringSize = r128DRIPriv->ringSize;
+ r128Screen->ringWritePtr = &r128DRIPriv->ringWrite;
+ r128Screen->ringReadPtr = (int *)(r128Screen->agp
+ + r128DRIPriv->ringReadOffset);
+
+ r128Screen->vbStart = r128DRIPriv->vbStart;
+ r128Screen->vbSize = r128DRIPriv->vbSize;
+
+ r128Screen->indStart = r128DRIPriv->indStart;
+ r128Screen->indSize = r128DRIPriv->indSize;
+
+ r128Screen->agpTexStart = r128DRIPriv->agpTexStart;
+ r128Screen->agpTexSize = r128DRIPriv->agpTexSize;
+ r128Screen->log2AGPTexGran = r128DRIPriv->log2AGPTexGran;
+
+ r128Screen->MMIOFifoSlots = 0;
+ r128Screen->CCEFifoSlots = 0;
+
+ r128Screen->CCEFifoAddr = R128_PM4_FIFO_DATA_EVEN;
+
+ 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;
+
+ drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
+ drmUnmap((drmAddress)r128Screen->agp, r128Screen->agpRgn.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
index bfbf4bc5f..07670331e 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h
@@ -38,54 +38,85 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
typedef struct {
- drmHandle handle;
- drmSize size;
+ drmHandle handle; /* Handle to the DRM region */
+ drmSize size; /* Size of the DRM region */
} r128RegionRec, *r128RegionPtr;
typedef struct {
+ /* FIXME: There needs to be two register regions. One to allow
+ read-only access to the block of non-FIFO'd GUI registers
+ (0x0000-0x0FFC), and one to allow read/write acces to the block
+ of FIFO'd GUI registers (0x1000-0x1FFC) */
+
+ /* MMIO register data */
r128RegionRec mmioRgn;
unsigned char *mmio;
+ /* AGP data */
r128RegionRec agpRgn;
unsigned char *agp;
- int deviceID;
-
- int width;
- int height;
- int depth;
- int bpp;
-
+ /* Frame buffer data */
unsigned char *fb;
unsigned long fbOffset;
int fbStride;
int fbSize;
- int fbX;
+ int CCEMode; /* CCE mode that server/clients use */
+ int CCEFifoSize; /* Size of the CCE command FIFO */
+
+ /* CCE ring buffer data */
+ unsigned long ringStart;
+ int ringSize;
+ /* FIXME: These should be in the
+ SAREA so that they can be
+ shared with other clients. */
+ int *ringWritePtr; /* Pointer to current write addr */
+ int *ringReadPtr; /* Pointer to current read addr */
+
+ /* CCE vertex buffer data */
+ unsigned long vbStart;
+ int vbSize;
+
+ /* CCE indirect buffer data */
+ unsigned long indStart;
+ int indSize;
+
+ /* CCE AGP Texture data */
+ unsigned long agpTexStart;
+ int agpTexSize;
+ int log2AGPTexGran;
+
+ /* 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 fbX; /* Start of frame buffer */
int fbY;
- int backX;
+ int backX; /* Start of shared back buffer */
int backY;
- int depthX;
+ int depthX; /* Start of shared depth buffer */
int depthY;
- int textureX;
+ int textureX; /* Start of textures in frame buffer */
int textureY;
int textureSize;
+ int log2TexGran;
- int CCEMode;
- int CCEFifoSize;
+ int MMIOFifoSlots; /* Free slots in the FIFO (64 max) */
+ int CCEFifoSlots; /* Free slots in the CCE FIFO */
- unsigned long ringStart;
- int ringSize;
- int *ringWritePtr;
- int *ringReadPtr;
-
- int MMIOFifoSlots;
- int CCEFifoSlots;
-
- int CCEFifoAddr;
+ int CCEFifoAddr; /* MMIO offset to write next CCE
+ value (only used when CCE is
+ in PIO mode). */
__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
index f6452b1b5..6338d0e54 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_span.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.c
@@ -42,60 +42,42 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128_cce.h"
#include "r128_span.h"
+/* Null functions for span functions not yet implemented */
+
static void r128DDWriteRGBASpan(const GLcontext *ctx,
GLuint n,
GLint x, GLint y,
const GLubyte rgba[][4],
- const GLubyte mask[])
-{
-}
-
+ const GLubyte mask[]) {}
static void r128DDWriteRGBSpan(const GLcontext *ctx,
GLuint n,
GLint x, GLint y,
const GLubyte rgb[][3],
- const GLubyte mask[])
-{
-}
-
+ const GLubyte mask[]) {}
static void r128DDWriteMonoRGBASpan(const GLcontext *ctx,
GLuint n,
GLint x, GLint y,
- const GLubyte mask[])
-{
-}
-
+ const GLubyte mask[]) {}
static void r128DDWriteRGBAPixels(const GLcontext *ctx,
GLuint n,
const GLint x[], const GLint y[],
const GLubyte rgba[][4],
- const GLubyte mask[])
-{
-}
-
+ const GLubyte mask[]) {}
static void r128DDWriteMonoRGBAPixels(const GLcontext *ctx,
GLuint n,
const GLint x[], const GLint y[],
- const GLubyte mask[])
-{
-}
-
+ const GLubyte mask[]) {}
static void r128DDReadRGBASpan(const GLcontext *ctx,
GLuint n,
GLint x, GLint y,
- GLubyte rgba[][4])
-{
-}
-
+ GLubyte rgba[][4]) {}
static void r128DDReadRGBAPixels(const GLcontext *ctx,
GLuint n,
const GLint x[], const GLint y[],
GLubyte rgba[][4],
- const GLubyte mask[])
-{
-}
+ const GLubyte mask[]) {}
-/* 16bpp span routines */
+/* 16bpp-specific span functions */
#define DBG 0
@@ -114,7 +96,7 @@ static void r128DDReadRGBAPixels(const GLcontext *ctx,
(r128ctx->bufY + dPriv->y) * pitch)
#define INIT_MONO_PIXEL(p) \
- GLushort p = R128_CONTEXT(ctx)->regs.constant_color_c;
+ GLushort p = R128_CONTEXT(ctx)->Color;
#define CLIPPIXEL(_x,_y) (_x >= minx && _x <= maxx && \
_y >= miny && _y <= maxy)
@@ -146,7 +128,6 @@ static void r128DDReadRGBAPixels(const GLcontext *ctx,
UNLOCK_HARDWARE(r128ctx);
-/* For 16 bit depth visuals */
#define Y_FLIP(_y) (height - _y)
#define WRITE_RGBA(_x, _y, r, g, b, a) \
*(GLushort *)(buf + (_x)*2 + (_y)*pitch) = ((((int)r & 0xf8) << 8) | \
@@ -168,6 +149,7 @@ static void r128DDReadRGBAPixels(const GLcontext *ctx,
#include "spantmp.h"
+/* Initialize the driver's span functions */
void r128DDInitSpanFuncs(GLcontext *ctx)
{
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.c b/xc/lib/GL/mesa/src/drv/r128/r128_state.c
index 8517960f9..55ab014a7 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_state.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c
@@ -42,69 +42,41 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128_cce.h"
#include "r128_tris.h"
#include "r128_vb.h"
+#include "r128_tex.h"
-#if 0
-/* FIXME: FOR TESTING A SIMPLE DRAWING FUNCTION */
-static void pfunc(GLcontext *ctx, GLuint first, GLuint last) {}
-static void lfunc(GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv) {}
-static void tfunc(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv)
-{
- r128ContextPtr r128ctx = R128_CONTEXT(ctx);
- unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
- float h = r128ctx->driDrawable->h;
-
- if (r128ctx->dirty) {
- R128_DEBUG(("Rendering with a dirty context: %08x\n", r128ctx->dirty));
- /* r128UpdateState(r128ctx); */
- }
-
- R128CCE_BEGIN(15);
- 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(ctx->VB->Win.data[v1][0]);
- R128CCEF(h-ctx->VB->Win.data[v1][1]);
- R128CCEF(ctx->VB->Win.data[v1][2]);
- R128CCE((ctx->VB->Color[0]->data[v1][2] << 0) |
- (ctx->VB->Color[0]->data[v1][1] << 8) |
- (ctx->VB->Color[0]->data[v1][0] << 16) |
- (ctx->VB->Color[0]->data[v1][3] << 24));
-
- R128CCEF(ctx->VB->Win.data[v2][0]);
- R128CCEF(h-ctx->VB->Win.data[v2][1]);
- R128CCEF(ctx->VB->Win.data[v2][2]);
- R128CCE((ctx->VB->Color[0]->data[v2][2] << 0) |
- (ctx->VB->Color[0]->data[v2][1] << 8) |
- (ctx->VB->Color[0]->data[v2][0] << 16) |
- (ctx->VB->Color[0]->data[v2][3] << 24));
-
- R128CCEF(ctx->VB->Win.data[v3][0]);
- R128CCEF(h-ctx->VB->Win.data[v3][1]);
- R128CCEF(ctx->VB->Win.data[v3][2]);
- R128CCE((ctx->VB->Color[0]->data[v3][2] << 0) |
- (ctx->VB->Color[0]->data[v3][1] << 8) |
- (ctx->VB->Color[0]->data[v3][0] << 16) |
- (ctx->VB->Color[0]->data[v3][3] << 24));
-
- R128CCE_END();
-}
-static void qfunc(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4, GLuint pv)
+CARD32 r128PackColor(GLuint d,
+ GLubyte r, GLubyte g, GLubyte b, GLubyte a)
{
- tfunc(ctx, v1, v2, v4, pv);
- tfunc(ctx, v2, v3, v4, pv);
-}
+ switch (d) {
+ case 8:
+ return (((r & 0xe0) >> 0) |
+ ((g & 0xe0) >> 3) |
+ ((b & 0xc0) >> 6) |
+ ((a & 0x00) >> 0));
+ case 15:
+ return (((r & 0xf8) << 7) |
+ ((g & 0xf8) << 2) |
+ ((b & 0xf8) >> 3) |
+ ((a & 0x80) << 8));
+ case 16:
+ return (((r & 0xf8) << 8) |
+ ((g & 0xfc) << 3) |
+ ((b & 0xf8) >> 3) |
+ ((a & 0x00) << 0));
+ case 24:
+ return (((r & 0xff) << 16) |
+ ((g & 0xff) << 8) |
+ ((b & 0xff) >> 0) |
+ ((a & 0x00) << 0));
+ case 32:
+ return (((r & 0xff) << 16) |
+ ((g & 0xff) << 8) |
+ ((b & 0xff) >> 0) |
+ ((a & 0xff) << 24));
+ }
-static void r128DDUpdateState(GLcontext *ctx)
-{
- ctx->Driver.PointsFunc = pfunc;
- ctx->Driver.LineFunc = lfunc;
- ctx->Driver.TriangleFunc = tfunc;
- ctx->Driver.QuadFunc = qfunc;
+ return 0;
}
-#else
#define INTERESTED (~(NEW_MODELVIEW | \
NEW_PROJECTION | \
@@ -133,7 +105,6 @@ static void r128DDUpdateState(GLcontext *ctx)
ctx->Driver.RectFunc = NULL;
}
}
-#endif
static void r128DDUpdateHWState(GLcontext *ctx)
{
@@ -141,7 +112,16 @@ static void r128DDUpdateHWState(GLcontext *ctx)
/* FIXME: state is being updated too often */
if (r128ctx->dirty)
- r128UpdateState(r128ctx);
+ 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 */
+ R128_FLUSH_VB(r128ctx);
}
static void r128DDClearColor(GLcontext *ctx,
@@ -149,10 +129,7 @@ static void r128DDClearColor(GLcontext *ctx,
{
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
- r128ctx->ClearColor = (((r >> 0) << 16) |
- ((g >> 0) << 8) |
- ((b >> 0) << 0) |
- ((a >> 0) << 24));
+ r128ctx->ClearColor = r128PackColor(32, r, g, b, a);
}
static void r128DDColor(GLcontext *ctx,
@@ -160,25 +137,19 @@ static void r128DDColor(GLcontext *ctx,
{
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
-#if 1
- r128ctx->regs.constant_color_c = (((r >> 3) << 11) |
- ((g >> 2) << 5) |
- ((b >> 3) << 0) |
- ((a >> 8) << 16));
-#else
- r128ctx->regs.constant_color_c = (((r >> 0) << 16) |
- ((g >> 0) << 8) |
- ((b >> 0) << 0) |
- ((a >> 0) << 24));
-#endif
+ r128ctx->Color = r128PackColor(r128ctx->r128Screen->depth, r, g, b, a);
}
-static GLboolean r128DDSetBuffer(GLcontext *ctx, GLenum mode )
+/* FIXME: After moving to Mesa 3.3, change this to SetReadBuffer and
+ SetDrawBuffer */
+static GLboolean r128DDSetBuffer(GLcontext *ctx, GLenum mode)
{
r128ContextPtr r128ctx = R128_CONTEXT(ctx);
- int found = GL_FALSE;
int x = r128ctx->driDrawable->x;
int y = r128ctx->driDrawable->y;
+ int found;
+
+ r128ctx->Fallback &= ~R128_FALLBACK_DRAW_BUFFER;
switch (mode) {
case GL_FRONT_LEFT:
@@ -191,11 +162,18 @@ static GLboolean r128DDSetBuffer(GLcontext *ctx, GLenum mode )
r128ctx->bufY = r128ctx->r128Screen->backY;
found = GL_TRUE;
break;
+ default:
+ r128ctx->Fallback |= R128_FALLBACK_DRAW_BUFFER;
+ found = GL_FALSE;
+ break;
}
x += r128ctx->bufX;
y += r128ctx->bufY;
+#if FLUSH_VB_ON_STATE_CHANGE
+ R128_FLUSH_VB(r128ctx);
+#endif
r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) |
(x << R128_WINDOW_X_SHIFT));
@@ -208,6 +186,9 @@ static GLboolean r128DDSetBuffer(GLcontext *ctx, GLenum mode )
(r128ctx->r128Screen->depthY -
r128ctx->bufY) *
r128ctx->r128Screen->fbStride);
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_WIN_Z_POS;
return found;
}
@@ -215,7 +196,9 @@ static GLboolean r128DDColorMask(GLcontext *ctx,
GLboolean r, GLboolean g,
GLboolean b, GLboolean a)
{
- /* FIXME??? */
+ /* FIXME: Implement this function. Make sure the fallbacks are
+ covered if they do not properly handle individual color channel
+ masking. */
return GL_TRUE;
}
@@ -242,10 +225,16 @@ static void r128DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
return;
}
- r128ctx->regs.misc_3d_state_cntl_reg = a;
+ if (r128ctx->regs.misc_3d_state_cntl_reg != a) {
+#if FLUSH_VB_ON_STATE_CHANGE
+ R128_FLUSH_VB(r128ctx);
+#endif
+ r128ctx->regs.misc_3d_state_cntl_reg = a;
- /* FIXME: Load into hardware now??? */
- r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ /* 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)
@@ -275,7 +264,9 @@ static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
case GL_SRC_ALPHA_SATURATE: b |= R128_ALPHA_BLEND_SRC_SRCALPHASAT;
break;
#if 0
- /* FIXME */
+ /* 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;
@@ -308,7 +299,9 @@ static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
case GL_ONE_MINUS_DST_ALPHA: b |= R128_ALPHA_BLEND_DST_INVDESTALPHA;
break;
#if 0
- /* FIXME */
+ /* 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;
@@ -323,10 +316,16 @@ static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
return;
}
- r128ctx->regs.misc_3d_state_cntl_reg = b;
+ if (r128ctx->regs.misc_3d_state_cntl_reg != b) {
+#if FLUSH_VB_ON_STATE_CHANGE
+ R128_FLUSH_VB(r128ctx);
+#endif
+ r128ctx->regs.misc_3d_state_cntl_reg = b;
- /* FIXME: Load into hardware now??? */
- r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALPHASTATE;
+ }
}
static void r128DDBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB,
@@ -346,16 +345,10 @@ 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:
- default:
- r128ctx->ClearDepth = d * 0xffffffff;
- break;
+ 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;
}
}
@@ -375,10 +368,16 @@ static void r128DDCullFace(GLcontext *ctx, GLenum mode)
default: return;
}
- r128ctx->regs.pm4_vc_fpu_setup = f;
+ if (r128ctx->regs.pm4_vc_fpu_setup != f) {
+#if FLUSH_VB_ON_STATE_CHANGE
+ R128_FLUSH_VB(r128ctx);
+#endif
+ r128ctx->regs.pm4_vc_fpu_setup = f;
- /* FIXME: Load into hardware now??? */
- r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_SETUPSTATE;
+ }
}
static void r128DDFrontFace(GLcontext *ctx, GLenum mode)
@@ -394,10 +393,16 @@ static void r128DDFrontFace(GLcontext *ctx, GLenum mode)
default: return;
}
- r128ctx->regs.pm4_vc_fpu_setup = f;
+ if (r128ctx->regs.pm4_vc_fpu_setup != f) {
+#if FLUSH_VB_ON_STATE_CHANGE
+ R128_FLUSH_VB(r128ctx);
+#endif
+ r128ctx->regs.pm4_vc_fpu_setup = f;
- /* FIXME: Load into hardware now??? */
- r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ /* FIXME: Load into hardware now??? */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_SETUPSTATE;
+ }
}
static void r128DDDepthFunc(GLcontext *ctx, GLenum func)
@@ -419,20 +424,36 @@ static void r128DDDepthFunc(GLcontext *ctx, GLenum func)
default: return;
}
- r128ctx->regs.z_sten_cntl_c = z;
+ if (r128ctx->regs.z_sten_cntl_c != z) {
+#if FLUSH_VB_ON_STATE_CHANGE
+ R128_FLUSH_VB(r128ctx);
+#endif
+ r128ctx->regs.z_sten_cntl_c = z;
- /* FIXME: Load into hardware now??? */
- r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ /* 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);
- if (flag) r128ctx->regs.tex_cntl_c |= R128_Z_WRITE_ENABLE;
- else r128ctx->regs.tex_cntl_c &= ~R128_Z_WRITE_ENABLE;
+ CARD32 t = r128ctx->regs.tex_cntl_c;
- /* FIXME: Load into hardware now??? */
- r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ if (flag) t |= R128_Z_WRITE_ENABLE;
+ else t &= ~R128_Z_WRITE_ENABLE;
+
+ if (r128ctx->regs.tex_cntl_c != t) {
+#if FLUSH_VB_ON_STATE_CHANGE
+ R128_FLUSH_VB(r128ctx);
+#endif
+ 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)
@@ -442,7 +463,6 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
CARD32 f = r128ctx->regs.pm4_vc_fpu_setup;
switch (cap) {
-#if 0
case GL_ALPHA_TEST:
if (state) t |= R128_ALPHA_TEST_ENABLE;
else t &= ~R128_ALPHA_TEST_ENABLE;
@@ -462,7 +482,6 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
case GL_CLIP_PLANE4:
case GL_CLIP_PLANE5:
case GL_COLOR_MATERIAL: return;
-#endif
case GL_CULL_FACE:
f &= ~(R128_BACKFACE_MASK | R128_FRONTFACE_MASK);
@@ -478,20 +497,21 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
}
break;
-#if 1
case GL_DEPTH_TEST:
if (state) t |= R128_Z_ENABLE;
else t &= ~R128_Z_ENABLE;
break;
-#endif
#if 0
+ /* FIXME */
case GL_DITHER: return;
+ /* FIXME */
case GL_FOG:
if (state) t |= R128_FOG_ENABLE;
else t &= ~R128_FOG_ENABLE;
break;
+#endif
case GL_LIGHT0:
case GL_LIGHT1:
@@ -531,15 +551,32 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
case GL_POLYGON_OFFSET_POINT:
case GL_POLYGON_OFFSET_LINE:
case GL_POLYGON_OFFSET_FILL:
+#if 0
+ /* FIXME: Are there others in Mesa 3.3 that we need to add? */
case GL_RESCALE_NORMAL_EXT:
+#endif
case GL_SCISSOR_TEST:
+#if 0
+ /* FIXME: Are there others in Mesa 3.3 that we need to add? */
case GL_SHARED_TEXTURE_PALETTE_EXT:
+#endif
case GL_STENCIL_TEST:
case GL_TEXTURE_1D: return;
case GL_TEXTURE_2D:
- if (state) t |= R128_TEXMAP_ENABLE;
- else t &= ~R128_TEXMAP_ENABLE;
+ switch (ctx->Texture.CurrentUnit) {
+ case 0:
+ if (state) t |= R128_TEXMAP_ENABLE;
+ else t &= ~R128_TEXMAP_ENABLE;
+ break;
+ case 1:
+ if (state) t |= R128_SEC_TEXMAP_ENABLE;
+ else t &= ~R128_SEC_TEXMAP_ENABLE;
+ break;
+ default:
+ return;
+ }
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
break;
case GL_TEXTURE_3D:
@@ -555,22 +592,29 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
case GL_INDEX_ARRAY:
case GL_TEXTURE_COORD_ARRAY:
case GL_EDGE_FLAG_ARRAY: return;
-#endif
default: return;
}
- if (t != r128ctx->regs.tex_cntl_c) {
+ if (r128ctx->regs.tex_cntl_c != t) {
+#if FLUSH_VB_ON_STATE_CHANGE
+ R128_FLUSH_VB(r128ctx);
+#endif
r128ctx->regs.tex_cntl_c = t;
/* FIXME: Load into hardware now??? */
- r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ENGINESTATE;
}
- if (f != r128ctx->regs.pm4_vc_fpu_setup) {
+ if (r128ctx->regs.pm4_vc_fpu_setup != f) {
+#if FLUSH_VB_ON_STATE_CHANGE
+ R128_FLUSH_VB(r128ctx);
+#endif
r128ctx->regs.pm4_vc_fpu_setup = f;
/* FIXME: Load into hardware now??? */
- r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_SETUPSTATE;
}
}
@@ -581,6 +625,7 @@ static void r128DDScissor(GLcontext *ctx,
/* FIXME */
}
+/* Initialize the driver's state functions */
void r128DDInitStateFuncs(GLcontext *ctx)
{
ctx->Driver.UpdateState = r128DDUpdateState;
@@ -606,7 +651,7 @@ void r128DDInitStateFuncs(GLcontext *ctx)
ctx->Driver.RenderVBCulledTab = NULL;
ctx->Driver.RenderVBRawTab = NULL;
- ctx->Driver.ReducedPrimitiveChange = NULL;
+ ctx->Driver.ReducedPrimitiveChange = r128DDReducedPrimitiveChange;
ctx->Driver.MultipassFunc = NULL;
ctx->Driver.AlphaFunc = r128DDAlphaFunc;
@@ -635,9 +680,11 @@ void r128DDInitStateFuncs(GLcontext *ctx)
ctx->Driver.Viewport = NULL;
}
+/* Initialize the context's hardware state */
void r128DDInitState(r128ContextPtr r128ctx)
{
- int dst_bpp, pitch;
+ int dst_bpp, depth_bpp, pitch, i;
+ CARD32 depthClear;
pitch = r128ctx->r128Screen->fbStride / r128ctx->r128Screen->bpp;
@@ -658,6 +705,33 @@ void r128DDInitState(r128ContextPtr r128ctx)
break;
}
+ switch (
+#if 0
+ /* FIXME: Figure out how to use 16bpp depth buffer in 32bpp mode */
+ r128ctx->glCtx->Visual->DepthBits
+#else
+ r128ctx->r128Screen->bpp
+#endif
+ ) {
+ 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:
+ /* FIXME: This is an error */
+ depthClear = 0x00000000;
+ depth_bpp = R128_Z_PIX_WIDTH_16;
+ break;
+ }
+
r128ctx->dirty = R128_CLEAN;
r128ctx->needClip = GL_FALSE;
@@ -679,37 +753,38 @@ void r128DDInitState(r128ContextPtr r128ctx)
}
r128ctx->ClearColor = 0x00000000;
- r128ctx->ClearDepth = 0x0000ffff; /* FIXME: init to requested depth */
+ r128ctx->ClearDepth = depthClear;
r128ctx->regs.scale_3d_cntl =
- R128_SCALE_DITHER_ERR_DIFF |
- R128_TEX_CACHE_SIZE_FULL |
- R128_DITHER_INIT_RESET |
- R128_SCALE_3D_TEXMAP_SHADE |
- R128_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 |
+ R128_SCALE_DITHER_ERR_DIFF |
+ R128_TEX_CACHE_SIZE_FULL |
+ R128_DITHER_INIT_RESET |
+ R128_SCALE_3D_TEXMAP_SHADE |
+ R128_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 |
R128_COMPOSITE_SHADOW_CMP_EQUAL |
- R128_TEX_MAP_ALPHA_IN_TEXTURE |
+ 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_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_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;
@@ -721,28 +796,29 @@ void r128DDInitState(r128ContextPtr r128ctx)
r128ctx->regs.z_pitch_c = pitch;
r128ctx->regs.z_sten_cntl_c =
- R128_Z_PIX_WIDTH_16 |
- R128_Z_TEST_LESS |
+ depth_bpp |
+ R128_Z_TEST_LESS |
R128_STENCIL_TEST_ALWAYS |
R128_STENCIL_S_FAIL_KEEP |
- R128_STENCIL_ZPASS_KEEP |
+ R128_STENCIL_ZPASS_KEEP |
R128_STENCIL_ZFAIL_KEEP;
r128ctx->regs.tex_cntl_c =
- R128_Z_WRITE_ENABLE |
- R128_SHADE_ENABLE |
+ R128_Z_WRITE_ENABLE |
+ R128_SHADE_ENABLE |
R128_ALPHA_IN_TEX_COMPLETE_A |
- R128_LIGHT_DIS |
- R128_ALPHA_LIGHT_DIS |
+ 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_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;
@@ -752,62 +828,44 @@ void r128DDInitState(r128ContextPtr r128ctx)
r128ctx->regs.prim_tex_cntl_c =
R128_MIN_BLEND_NEAREST |
R128_MAG_BLEND_NEAREST |
- R128_MIP_MAP_DISABLE |
- R128_TEX_CLAMP_S_WRAP |
+ 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_COMB_MODULATE |
+ R128_COLOR_FACTOR_TEX |
R128_INPUT_FACTOR_INT_COLOR |
- R128_COMB_ALPHA_COPY |
+ 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_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);
- r128ctx->regs.prim_tex_0_offset_c = 0x00000000;
- r128ctx->regs.prim_tex_1_offset_c = 0x00000000;
- r128ctx->regs.prim_tex_2_offset_c = 0x00000000;
- r128ctx->regs.prim_tex_3_offset_c = 0x00000000;
- r128ctx->regs.prim_tex_4_offset_c = 0x00000000;
- r128ctx->regs.prim_tex_5_offset_c = 0x00000000;
- r128ctx->regs.prim_tex_6_offset_c = 0x00000000;
- r128ctx->regs.prim_tex_7_offset_c = 0x00000000;
- r128ctx->regs.prim_tex_8_offset_c = 0x00000000;
- r128ctx->regs.prim_tex_9_offset_c = 0x00000000;
- r128ctx->regs.prim_tex_10_offset_c = 0x00000000;
+ 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_COMB_DIS |
+ R128_COLOR_FACTOR_TEX |
R128_INPUT_FACTOR_PREV_COLOR |
- R128_COMB_ALPHA_DIS |
- R128_ALPHA_FACTOR_TEX_ALPHA |
+ R128_COMB_ALPHA_DIS |
+ R128_ALPHA_FACTOR_TEX_ALPHA |
R128_INP_FACTOR_A_PREV_ALPHA;
- r128ctx->regs.sec_tex_0_offset_c = 0x00000000;
- r128ctx->regs.sec_tex_1_offset_c = 0x00000000;
- r128ctx->regs.sec_tex_2_offset_c = 0x00000000;
- r128ctx->regs.sec_tex_3_offset_c = 0x00000000;
- r128ctx->regs.sec_tex_4_offset_c = 0x00000000;
- r128ctx->regs.sec_tex_5_offset_c = 0x00000000;
- r128ctx->regs.sec_tex_6_offset_c = 0x00000000;
- r128ctx->regs.sec_tex_7_offset_c = 0x00000000;
- r128ctx->regs.sec_tex_8_offset_c = 0x00000000;
- r128ctx->regs.sec_tex_9_offset_c = 0x00000000;
- r128ctx->regs.sec_tex_10_offset_c = 0x00000000;
+ 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;
@@ -816,26 +874,32 @@ void r128DDInitState(r128ContextPtr r128ctx)
r128ctx->regs.plane_3d_mask_c = 0xffffffff;
r128ctx->regs.setup_cntl =
- R128_COLOR_GOURAUD |
- R128_PRIM_TYPE_TRI |
- R128_TEXTURE_ST_MULT_W |
- R128_STARTING_VERTEX_1 |
- R128_ENDING_VERTEX_3 |
+ 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_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_FPU_ROUND_TRUNCATE |
R128_WM_SEL_8DW;
r128ctx->regs.fog_3d_table_start = 0x00000000;
@@ -845,105 +909,209 @@ void r128DDInitState(r128ContextPtr r128ctx)
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;
}
-/* This is only called when we have the lock */
+/* 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)
{
unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+ int i;
+ int tex_size_pitch_done = GL_FALSE;
- R128CCE_BEGIN_LOCKED(2);
- R128CCE0(R128_CCE_PACKET0, R128_SCALE_3D_CNTL, 0);
- R128CCE(r128ctx->regs.scale_3d_cntl);
-
- R128CCE_WAIT_LOCKED(27);
- R128CCE0(R128_CCE_PACKET0, R128_DST_PITCH_OFFSET_C, 25);
- R128CCE(r128ctx->regs.dst_pitch_offset_c);
- R128CCE(r128ctx->regs.dp_gui_master_cntl);
- R128CCE(r128ctx->regs.sc_top_left_c);
- R128CCE(r128ctx->regs.sc_bottom_right_c);
- R128CCE(r128ctx->regs.z_offset_c);
- R128CCE(r128ctx->regs.z_pitch_c);
- R128CCE(r128ctx->regs.z_sten_cntl_c);
- R128CCE(r128ctx->regs.tex_cntl_c);
- R128CCE(r128ctx->regs.misc_3d_state_cntl_reg);
- R128CCE(r128ctx->regs.texture_clr_cmp_clr_c);
- R128CCE(r128ctx->regs.texture_clr_cmp_msk_c);
- R128CCE(r128ctx->regs.fog_color_c);
- R128CCE(r128ctx->regs.prim_tex_cntl_c);
- R128CCE(r128ctx->regs.prim_texture_combine_cntl_c);
- R128CCE(r128ctx->regs.tex_size_pitch_c);
- R128CCE(r128ctx->regs.prim_tex_0_offset_c);
- R128CCE(r128ctx->regs.prim_tex_1_offset_c);
- R128CCE(r128ctx->regs.prim_tex_2_offset_c);
- R128CCE(r128ctx->regs.prim_tex_3_offset_c);
- R128CCE(r128ctx->regs.prim_tex_4_offset_c);
- R128CCE(r128ctx->regs.prim_tex_5_offset_c);
- R128CCE(r128ctx->regs.prim_tex_6_offset_c);
- R128CCE(r128ctx->regs.prim_tex_7_offset_c);
- R128CCE(r128ctx->regs.prim_tex_8_offset_c);
- R128CCE(r128ctx->regs.prim_tex_9_offset_c);
- R128CCE(r128ctx->regs.prim_tex_10_offset_c);
-
- R128CCE_WAIT_LOCKED(19);
- R128CCE0(R128_CCE_PACKET0, R128_SEC_TEX_CNTL_C, 17);
- R128CCE(r128ctx->regs.sec_tex_cntl_c);
- R128CCE(r128ctx->regs.sec_tex_combine_cntl_c);
- R128CCE(r128ctx->regs.sec_tex_0_offset_c);
- R128CCE(r128ctx->regs.sec_tex_1_offset_c);
- R128CCE(r128ctx->regs.sec_tex_2_offset_c);
- R128CCE(r128ctx->regs.sec_tex_3_offset_c);
- R128CCE(r128ctx->regs.sec_tex_4_offset_c);
- R128CCE(r128ctx->regs.sec_tex_5_offset_c);
- R128CCE(r128ctx->regs.sec_tex_6_offset_c);
- R128CCE(r128ctx->regs.sec_tex_7_offset_c);
- R128CCE(r128ctx->regs.sec_tex_8_offset_c);
- R128CCE(r128ctx->regs.sec_tex_9_offset_c);
- R128CCE(r128ctx->regs.sec_tex_10_offset_c);
- R128CCE(r128ctx->regs.constant_color_c);
- R128CCE(r128ctx->regs.prim_texture_border_color_c);
- R128CCE(r128ctx->regs.sec_texture_border_color_c);
- R128CCE(r128ctx->regs.sten_ref_mask_c);
- R128CCE(r128ctx->regs.plane_3d_mask_c);
-
- R128CCE_WAIT_LOCKED(2);
- R128CCE0(R128_CCE_PACKET0, R128_SETUP_CNTL, 0);
- R128CCE(r128ctx->regs.setup_cntl);
-
- R128CCE_WAIT_LOCKED(2);
- R128CCE0(R128_CCE_PACKET0, R128_PM4_VC_FPU_SETUP, 0);
- R128CCE(r128ctx->regs.pm4_vc_fpu_setup);
+#if 0
+ r128ctx->dirty_context = R128_ALL_DIRTY;
+#endif
- R128CCE_WAIT_LOCKED(3);
- R128CCE0(R128_CCE_PACKET0, R128_FOG_3D_TABLE_START, 1);
- R128CCE(r128ctx->regs.fog_3d_table_start);
- R128CCE(r128ctx->regs.fog_3d_table_end);
+#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) R128CCEWaitForIdle(r128ctx->r128Screen);
+#endif
+
+#if !FLUSH_VB_ON_STATE_CHANGE
+ /* FIXME: It might make sense to do this here instead of flushing
+ immediately in each state setting routine. */
+ /* FIXME: Is this _really_ necessary? It slows down rendering, and
+ it seems like state changes shouldn't take effect until after the
+ VB has completed rendering. */
+ if (r128ctx->dirty_context) R128_FLUSH_VB(r128ctx);
+#endif
+
+ if (r128ctx->dirty_context & R128_CTX_MISC) {
+ R128CCE_WAIT_LOCKED(3);
+ R128CCE1(R128_CCE_PACKET1, R128_SCALE_3D_CNTL, R128_DP_WRITE_MASK);
+ R128CCE(r128ctx->regs.scale_3d_cntl);
+ R128CCE(r128ctx->regs.dp_write_mask);
+
+ R128CCE_WAIT_LOCKED(3);
+ R128CCE0(R128_CCE_PACKET0, R128_DST_PITCH_OFFSET_C, 1);
+ R128CCE(r128ctx->regs.dst_pitch_offset_c);
+ R128CCE(r128ctx->regs.dp_gui_master_cntl);
+
+ R128CCE_WAIT_LOCKED(3);
+ 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);
+
+ R128CCE_WAIT_LOCKED(3);
+ 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) {
+ R128CCE_WAIT_LOCKED(2);
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0);
+ R128CCE(r128ctx->regs.tex_cntl_c);
+ }
- R128CCE_WAIT_LOCKED(2);
- R128CCE0(R128_CCE_PACKET0, R128_FOG_3D_TABLE_DENSITY, 0);
- R128CCE(r128ctx->regs.fog_3d_table_density);
+ if (r128ctx->dirty_context & R128_CTX_TEX0STATE) {
+ R128CCE_WAIT_LOCKED(4+R128_TEX_MAXLEVELS);
+ 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]);
- R128CCE_WAIT_LOCKED(2);
- R128CCE0(R128_CCE_PACKET0, R128_WINDOW_XY_OFFSET, 0);
- R128CCE(r128ctx->regs.window_xy_offset);
+ R128CCE_WAIT_LOCKED(2);
+ R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEXTURE_BORDER_COLOR_C, 0);
+ R128CCE(r128ctx->regs.prim_texture_border_color_c);
- R128CCE_WAIT_LOCKED(2);
- R128CCE0(R128_CCE_PACKET0, R128_DP_WRITE_MASK, 0);
- R128CCE(r128ctx->regs.dp_write_mask);
+ tex_size_pitch_done = GL_TRUE;
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_TEX1STATE) {
+ if (!tex_size_pitch_done) {
+ R128CCE_WAIT_LOCKED(2);
+ R128CCE0(R128_CCE_PACKET0, R128_TEX_SIZE_PITCH_C, 0);
+ R128CCE(r128ctx->regs.tex_size_pitch_c);
+ }
+
+ R128CCE_WAIT_LOCKED(3+R128_TEX_MAXLEVELS);
+ 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]);
+
+ R128CCE_WAIT_LOCKED(2);
+ 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) {
+ R128CCE_WAIT_LOCKED(2);
+ R128CCE0(R128_CCE_PACKET0, R128_CONSTANT_COLOR_C, 0);
+ R128CCE(r128ctx->regs.constant_color_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_FOGSTATE) {
+ R128CCE_WAIT_LOCKED(3);
+ R128CCE0(R128_CCE_PACKET0, R128_FOG_3D_TABLE_START, 1);
+ R128CCE(r128ctx->regs.fog_3d_table_start);
+ R128CCE(r128ctx->regs.fog_3d_table_end);
+
+ R128CCE_WAIT_LOCKED(3);
+ 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_ZSTENSTATE) {
+ R128CCE_WAIT_LOCKED(2);
+ R128CCE0(R128_CCE_PACKET0, R128_Z_STEN_CNTL_C, 0);
+ R128CCE(r128ctx->regs.z_sten_cntl_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_SCISSORS) {
+ R128CCE_WAIT_LOCKED(3);
+ 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)) {
+ R128CCE_WAIT_LOCKED(2);
+ 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) {
+ R128CCE_WAIT_LOCKED(3);
+ 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) {
+ R128CCE_WAIT_LOCKED(2);
+ R128CCE0(R128_CCE_PACKET0, R128_WINDOW_XY_OFFSET, 0);
+ R128CCE(r128ctx->regs.window_xy_offset);
+
+ R128CCE_WAIT_LOCKED(3);
+ R128CCE0(R128_CCE_PACKET0, R128_Z_OFFSET_C, 1);
+ R128CCE(r128ctx->regs.z_offset_c);
+ R128CCE(r128ctx->regs.z_pitch_c);
+ }
+
+ if (r128ctx->dirty_context & R128_CTX_FLUSH_PIX_CACHE) {
+ R128CCE_WAIT_LOCKED(2);
+ R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0);
+ R128CCE(r128ctx->regs.pc_gui_ctlstat);
+ }
R128CCE_END_LOCKED();
+
+ /* 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;
}
-/* This is only called when we have the lock */
+/* Set a hardware clip rect for drawing to the current color buffer */
+/* NOTE: This function is only called while holding the hardware lock */
void r128SetClipRect(r128ContextPtr r128ctx, XF86DRIClipRectPtr pc)
{
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+
+ /* FIXME: Use the Rage 128's multiple clip rects */
+ R128CCE_WAIT_LOCKED(3);
+ R128CCE0(R128_CCE_PACKET0, R128_SC_TOP_LEFT_C, 1);
+ R128CCE(((pc->y1 + r128ctx->bufY) << 16)|(pc->x1 + r128ctx->bufX));
+ R128CCE(((pc->y2 + r128ctx->bufY - 1) << 16)|(pc->x2 + r128ctx->bufX - 1));
+ R128CCE_END_LOCKED();
}
-static void r128LoadCliprects(r128ContextPtr r128ctx)
+/* 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->bufX;
int y = r128ctx->driDrawable->y + r128ctx->bufY;
+#if 0
+ /* FIXME: This happens during a lock, but is it _really_ needed? */
+ R128_FLUSH_VB(r128ctx);
+#endif
r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) |
(x << R128_WINDOW_X_SHIFT));
@@ -956,24 +1124,109 @@ static void r128LoadCliprects(r128ContextPtr r128ctx)
(r128ctx->r128Screen->depthY -
r128ctx->bufY) *
r128ctx->r128Screen->fbStride);
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_WIN_Z_POS;
+
+ r128ctx->needClip = (r128ctx->driDrawable->numClipRects > 1);
}
-void r128UpdateState(r128ContextPtr r128ctx)
+/* Update the hardware state */
+/* NOTE: This function is only called while holding the hardware lock */
+static void r128UpdateHWStateLocked(r128ContextPtr r128ctx)
+{
+ r128ScreenPtr r128Screen = r128ctx->r128Screen;
+
+ if (r128ctx->dirty & R128_REQUIRE_QUIESCENCE)
+ R128WaitForIdle(r128Screen);
+
+ /* 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);
- r128UpdateStateLocked(r128ctx);
+ r128UpdateHWStateLocked(r128ctx);
UNLOCK_HARDWARE(r128ctx);
}
-/* This is only called when we have the lock */
-void r128UpdateStateLocked(r128ContextPtr r128ctx)
+/* Update the driver's state */
+/* NOTE: This function is only called while holding the hardware lock */
+void r128UpdateState(r128ContextPtr r128ctx, int winMoved)
{
- r128ScreenPtr r128Screen = r128ctx->r128Screen;
+ if (r128ctx->SAREA->ctxOwner != r128ctx->driContext->hHWContext) {
+ r128ctx->SAREA->ctxOwner = r128ctx->driContext->hHWContext;
+ r128ctx->dirty |= R128_ALL_DIRTY;
+ }
- if (r128ctx->dirty & R128_REQUIRE_QUIESCENCE) R128WaitForIdle(r128Screen);
- if (r128ctx->dirty & R128_START_CCE) R128CCEStart(r128Screen);
- if (r128ctx->dirty & R128_UPDATE_CLIPRECTS) r128LoadCliprects(r128ctx);
- if (r128ctx->dirty & R128_UPDATE_CONTEXT) r128LoadContext(r128ctx);
+ if (r128ctx->SAREA->texAge != r128ctx->lastTexAge) {
+#if USE_AGP_TEXTURES
+ int sz = 1 << r128ctx->r128Screen->log2AGPTexGran;
+#else
+ int sz = 1 << r128ctx->r128Screen->log2TexGran;
+#endif
+ int nr = 0;
+ int idx;
+
+ for (idx = r128ctx->SAREA->texList[R128_NR_TEX_REGIONS].prev;
+ idx != R128_NR_TEX_REGIONS && nr < R128_NR_TEX_REGIONS;
+ idx = r128ctx->SAREA->texList[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 USE_AGP_TEXTURES
+ if (idx * sz > r128ctx->r128Screen->agpTexSize) {
+#else
+ if (idx * sz > r128ctx->r128Screen->textureSize) {
+#endif
+ nr = R128_NR_TEX_REGIONS;
+ break;
+ }
- r128ctx->dirty = R128_CLEAN;
+ if (r128ctx->SAREA->texList[idx].age > r128ctx->lastTexAge)
+ r128TexturesGone(r128ctx, idx * sz, sz,
+ r128ctx->SAREA->texList[idx].in_use);
+ }
+
+ if (nr == R128_NR_TEX_REGIONS) {
+#if USE_AGP_TEXTURES
+ r128TexturesGone(r128ctx, 0, r128ctx->r128Screen->agpTexSize, 0);
+#else
+ r128TexturesGone(r128ctx, 0, r128ctx->r128Screen->textureSize, 0);
+#endif
+ r128ResetGlobalLRU(r128ctx);
+ }
+
+ r128ctx->dirty |= R128_UPDATE_TEX0IMAGES;
+ r128ctx->dirty |= R128_UPDATE_TEX1IMAGES;
+ r128ctx->lastTexAge = r128ctx->SAREA->texAge;
+ }
+
+ if (winMoved) { /* FIXME??: handle window moves */
+ r128ctx->dirty |= R128_UPDATE_WINPOS;
+ }
+
+ if (r128ctx->dirty) r128UpdateHWStateLocked(r128ctx);
}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.h b/xc/lib/GL/mesa/src/drv/r128/r128_state.h
index f604f6ca8..570d38f8e 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_state.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.h
@@ -37,13 +37,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
-extern void r128DDInitState(r128ContextPtr r128ctx);
-extern void r128DDInitStateFuncs(GLcontext *ctx);
+extern void r128DDInitState(r128ContextPtr r128ctx);
+extern void r128DDInitStateFuncs(GLcontext *ctx);
-extern void r128UpdateState(r128ContextPtr r128ctx);
-extern void r128UpdateStateLocked(r128ContextPtr r128ctx);
+extern void r128UpdateState(r128ContextPtr r128ctx, int winMoved);
+extern void r128UpdateHWState(r128ContextPtr r128ctx);
-extern void r128SetClipRect(r128ContextPtr r128ctx, XF86DRIClipRectPtr pc);
+extern void r128SetClipRect(r128ContextPtr r128ctx, XF86DRIClipRectPtr pc);
+extern CARD32 r128PackColor(GLuint d,
+ GLubyte r, GLubyte g, GLubyte b, GLubyte a);
#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
index 2f561a74d..27150d510 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_swap.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_swap.c
@@ -39,12 +39,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128_lock.h"
#include "r128_reg.h"
#include "r128_cce.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;
- int dst_bpp;
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+ __DRIdrawablePrivate *dPriv = r128ctx->driDrawable;
+ int nc = dPriv->numClipRects;
+ XF86DRIClipRectPtr c = dPriv->pClipRects;
+ int dst_bpp;
switch (r128ctx->r128Screen->bpp) {
case 8:
@@ -63,21 +68,39 @@ void r128SwapBuffers(r128ContextPtr r128ctx)
break;
}
- R128CCE_BEGIN(5);
+ /* Flush any outstanding vertex buffers */
+ R128_FLUSH_VB(r128ctx);
- 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(((r128ctx->driDrawable->x + r128ctx->r128Screen->backX)<< 16)
- | (r128ctx->driDrawable->y + r128ctx->r128Screen->backY));
- R128CCE((r128ctx->driDrawable->x << 16) | r128ctx->driDrawable->y);
- R128CCE((r128ctx->driDrawable->w << 16) | r128ctx->driDrawable->h);
+ LOCK_HARDWARE(r128ctx);
- r128ctx->dirty = R128_UPDATE_CONTEXT;
- /* r128UpdateState(r128ctx); */
+ /* 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;
- R128CCE_END();
+ fx += r128ctx->r128Screen->fbX;
+ fy += r128ctx->r128Screen->fbY;
+
+ R128CCE_WAIT_LOCKED(5);
+ 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);
+ }
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ALL_DIRTY;
+
+ R128CCE_END_LOCKED();
+
+ UNLOCK_HARDWARE(r128ctx);
}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
index 75b08e527..b61f9cdc1 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c
@@ -34,19 +34,1028 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#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;
+ CARD32 texFormat;
+ int log2Pitch, log2Height, log2Size, log2MinSize;
+ int pitch, totalSize, width;
+ int i;
+
+ image = tObj->Image[0];
+ if (!image) return NULL; /* ERROR!!! */
+
+ t = (r128TexObjPtr)calloc(1,sizeof(*t));
+ if (!t) return NULL; /* ERROR!!! */
+
+ 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;
+
+ pitch = image->Width;
+ t->internFormat = image->IntFormat;
+
+ switch (image->Format) {
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ case GL_RGB:
+ if (r128ctx->r128Screen->bpp == 16 &&
+ (t->internFormat == GL_RGB || t->internFormat == 3))
+ t->internFormat = GL_RGB5;
+
+ switch (t->internFormat) {
+ case GL_RGB5: pitch *= 2; texFormat = R128_DATATYPE_RGB565; break;
+ case 3:
+ case GL_RGB:
+#if USE_RGB8_TEXTURES
+ case GL_RGB8: pitch *= 3; texFormat = R128_DATATYPE_RGB888; break;
+#else
+ case GL_RGB8: pitch *= 4; texFormat = R128_DATATYPE_ARGB8888; break;
+#endif
+ default:
+ /* Format not supported */
+ free(t);
+ return NULL;
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_RGBA:
+ if (r128ctx->r128Screen->bpp == 16 &&
+ (t->internFormat == GL_RGBA || t->internFormat == 4))
+ t->internFormat = GL_RGBA4;
+
+ switch (t->internFormat) {
+ case GL_RGB5_A1: pitch *= 2; texFormat = R128_DATATYPE_ARGB1555; break;
+ case GL_RGBA4: pitch *= 2; texFormat = R128_DATATYPE_ARGB4444; break;
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA8: pitch *= 4; texFormat = R128_DATATYPE_ARGB8888; break;
+ default:
+ /* Format not supported */
+ free(t);
+ return NULL;
+ }
+ break;
+ case GL_COLOR_INDEX:
+ switch (t->internFormat) {
+ case 1:
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX8_EXT: texFormat = R128_DATATYPE_CI8; break;
+ default:
+ /* Format not supported */
+ free(t);
+ return NULL;
+ }
+ break;
+ default:
+ /* ERROR!!! */
+ free(t);
+ return NULL;
+ }
+
+ t->dirty_images = 0;
+ t->bound = 0;
+ t->tObj = tObj;
+
+ t->memBlock = NULL;
+ t->bufAddr = NULL;
+
+ totalSize = 0;
+ width = image->Width;
+ for (i = 0; i <= log2Size && tObj->Image[i]; i++) {
+ t->image[i].offset = totalSize;
+ t->image[i].width = width;
+ t->dirty_images |= 1 << i;
+ totalSize += tObj->Image[i]->Height * pitch;
+ pitch /= 2;
+ width /= 2;
+ }
+ log2MinSize = log2Size - i + 1;
+
+ t->totalSize = totalSize;
+
+ t->regs.tex_cntl = texFormat;
+ 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;
+ /* r128ctx->dirty |= R128_UPDATE_CONTEXT; */
+
+ 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);
+}
+
+/* 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 r128UploadTexLevel(r128TexObjPtr t, int level, int start)
+{
+ struct gl_texture_image *image;
+ int i, j, width;
+
+ if (level < 0 || level > R128_TEX_MAXLEVELS) return;
+ if (!(image = t->tObj->Image[level])) return;
+
+ width = t->image[level].width;
+
+ /* FIXME: Use HOSTDATA_BLT (type 3 packet) for texture uploads */
+ /* FIXME: Add the other texture formats that we support here */
+ switch (t->internFormat) {
+ case GL_RGB5:
+ {
+ CARD16 *dst = (CARD16 *)(t->image[level].offset + t->bufAddr + start);
+ CARD8 *src = (CARD8 *)image->Data;
+
+ for (j = 0; j < image->Height; j++) {
+ for (i = 0; i < width; i++) {
+ dst[i] = (((src[0] & 0xf8) << 8) |
+ ((src[1] & 0xfc) << 3) |
+ ((src[2] & 0xf8) >> 3));
+ src += 3;
+ }
+ dst += width;
+ }
+ break;
+ }
+ case 3:
+ case GL_RGB:
+ case GL_RGB8:
+ {
+#if USE_RGB8_TEXTURES
+ CARD8 *dst = (CARD8 *)(t->image[level].offset + t->bufAddr + start);
+ CARD8 *src = (CARD8 *)image->Data;
+
+ for (j = 0; j < image->Height; j++) {
+ for (i = 0; i < width; i++) {
+ *dst++ = src[0];
+ *dst++ = src[1];
+ *dst++ = src[2];
+ src += 3;
+ }
+ }
+#else
+ CARD32 *dst = (CARD32 *)(t->image[level].offset + t->bufAddr + start);
+ CARD8 *src = (CARD8 *)image->Data;
+
+ for (j = 0; j < image->Height; j++) {
+ for (i = 0; i < width; i++) {
+ dst[i] = ((src[0] << 16) |
+ (src[1] << 8) |
+ (src[2] << 0) |
+ (0xff << 24));
+ src += 3;
+ }
+ dst += width;
+ }
+#endif
+ break;
+ }
+ case GL_RGB5_A1:
+ {
+ CARD16 *dst = (CARD16 *)(t->image[level].offset + t->bufAddr + start);
+ CARD8 *src = (CARD8 *)image->Data;
+
+ for (j = 0; j < image->Height; j++) {
+ for (i = 0; i < width; i++) {
+ dst[i] = (((src[0] & 0xf8) << 7) |
+ ((src[1] & 0xf8) << 2) |
+ ((src[2] & 0xf8) >> 3) |
+ ((src[3] & 0x80) << 8));
+ src += 4;
+ }
+ dst += width;
+ }
+ break;
+ }
+ case GL_RGBA4:
+ {
+ CARD16 *dst = (CARD16 *)(t->image[level].offset + t->bufAddr + start);
+ CARD8 *src = (CARD8 *)image->Data;
+
+ for (j = 0; j < image->Height; j++) {
+ for (i = 0; i < width; i++) {
+ dst[i] = (((src[0] & 0xf0) << 4) |
+ ((src[1] & 0xf0) << 0) |
+ ((src[2] & 0xf0) >> 4) |
+ ((src[3] & 0xf0) << 8));
+ src += 4;
+ }
+ dst += width;
+ }
+ break;
+ }
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA8:
+ {
+ CARD32 *dst = (CARD32 *)(t->image[level].offset + t->bufAddr + start);
+ CARD8 *src = (CARD8 *)image->Data;
+
+ for (j = 0; j < image->Height; j++) {
+ for (i = 0; i < width; i++) {
+ dst[i] = ((src[0] << 16) |
+ (src[1] << 8) |
+ (src[2] << 0) |
+ (src[3] << 24));
+ src += 4;
+ }
+ dst += width;
+ }
+ break;
+ }
+ default:
+ return;
+ }
+}
+
+/* Reset the global texture LRU */
+/* NOTE: This function is only called while holding the hardware lock */
+void r128ResetGlobalLRU(r128ContextPtr r128ctx)
+{
+ R128TexRegion *list = r128ctx->SAREA->texList;
+#if USE_AGP_TEXTURES
+ int sz = 1 << r128ctx->r128Screen->log2AGPTexGran;
+#else
+ int sz = 1 << r128ctx->r128Screen->log2TexGran;
+#endif
+ 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.
+ */
+
+#if USE_AGP_TEXTURES
+ for (i = 0; (i+1) * sz <= r128ctx->r128Screen->agpTexSize; i++) {
+#else
+ for (i = 0; (i+1) * sz <= r128ctx->r128Screen->textureSize; i++) {
+#endif
+ 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->SAREA->texAge = 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)
+{
+ R128TexRegion *list = r128ctx->SAREA->texList;
+#if USE_AGP_TEXTURES
+ int log2sz = r128ctx->r128Screen->log2AGPTexGran;
+#else
+ int log2sz = r128ctx->r128Screen->log2TexGran;
+#endif
+
+ int start = t->memBlock->ofs >> log2sz;
+ int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz;
+ int i;
+
+ r128ctx->lastTexAge = ++r128ctx->SAREA->texAge;
+
+ /* Update our local LRU */
+ move_to_head(&r128ctx->TexObjList, t);
+
+ /* Update the global LRU */
+ for (i = start ; i <= end ; i++) {
+ list[i].in_use = 1;
+ list[i].age = r128ctx->lastTexAge;
+
+ /* 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 */
+void r128TexturesGone(r128ContextPtr r128ctx,
+ int offset, int size, int in_use)
+{
+ r128TexObjPtr t, tmp;
+
+ foreach_s (t, tmp, &r128ctx->TexObjList) {
+ 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, size, 0, offset);
+ insert_at_head(&r128ctx->TexObjList, t);
+ }
+}
+
+/* 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;
+
+ if (!t) return 0;
+
+ /* Do we need to eject LRU texture objects? */
+ if (!t->memBlock) {
+ while (1) {
+ /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */
+ t->memBlock = mmAllocMem(r128ctx->texHeap, t->totalSize, 12, 0);
+ if (t->memBlock) break;
+
+ if (r128ctx->TexObjList.prev->bound) {
+ fprintf(stderr,
+ "r128UploadTexImages: ran into bound texture\n");
+ return -1;
+ }
+ if (r128ctx->TexObjList.prev == &(r128ctx->TexObjList)) {
+ fprintf(stderr,
+ "r128UploadTexImages: upload texture failure, sz=%d\n",
+ t->totalSize);
+ return -1;
+ }
+
+ r128DestroyTexObj(r128ctx, r128ctx->TexObjList.prev);
+ }
+
+ /* FIXME: Allow both local and AGP textures to co-exist. */
+#if USE_AGP_TEXTURES
+ t->bufAddr = (unsigned char *)r128ctx->r128Screen->agpTexStart;
+#else
+ t->bufAddr = (unsigned char *)(r128ctx->r128Screen->textureY *
+ r128ctx->r128Screen->fbStride +
+ r128ctx->r128Screen->textureX *
+ (r128ctx->r128Screen->bpp/8));
+#endif
+ 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:
+ 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;
+ }
+#if USE_AGP_TEXTURES
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] |= 0x02000000;
+#endif
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX0STATE;
+ break;
+ case 2:
+ 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;
+ }
+#if USE_AGP_TEXTURES
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] |= 0x02000000;
+#endif
+ 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);
+
+ /* Wait for texturing to complete */
+ R128CCEWaitForIdle(r128ctx->r128Screen);
+
+ /* 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)) {
+#if USE_AGP_TEXTURES
+ r128UploadTexLevel(t, i, (int)r128ctx->r128Screen->agp);
+#else
+ r128UploadTexLevel(t, i, (int)r128ctx->r128Screen->fb);
+#endif
+ }
+
+ r128ctx->regs.tex_cntl_c |= R128_TEX_CACHE_FLUSH;
+
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_ENGINESTATE;
+
+ /* FIXME: r128ctx->regs.pc_gui_ctlstat = R128_PC_FLUSH_GUI; */
+ /* FIXME: r128ctx->dirty_context |= R128_CTX_FLUSH_PIX_CACHE; */
+ }
+
+ 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]) return;
+ if (!tObj->Complete) return;
+ if (!(ctx->Texture.Enabled & 0x0f)) 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;
+
+ /* 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 */
+ /* FIXME: This only works for GL_RGB and GL_RGBA right now */
+ /* FIXME: Handle GL_ALPHA, GL_LIMINANCE{_ALPHA} and GL_INTENSITY */
+ switch (ctx->Texture.Unit[0].EnvMode) {
+ case GL_REPLACE:
+ switch (tObj->Image[0]->Format) {
+ 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_RGBA:
+ 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_LUMINANCE:
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+ case GL_MODULATE:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGB:
+ 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_RGBA:
+ 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_LUMINANCE:
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+ case GL_DECAL:
+ switch (tObj->Image[0]->Format) {
+ 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_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_LUMINANCE:
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+ case GL_BLEND:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGB:
+ tex_combine_cntl = (R128_COMB_BLEND_PREV |
+ 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_RGBA:
+ tex_combine_cntl = (R128_COMB_BLEND_PREV |
+ 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_LUMINANCE:
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+ default:
+ return;
+ }
+
+ 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;
+ 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;
+ }
+#if USE_AGP_TEXTURES
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.prim_tex_offset[i] |= 0x02000000;
+#endif
+
+ /* Force loading the new state into the hardware */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX0STATE;
+}
+
+/* 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]) return;
+ if (!tObj->Complete) return;
+ if (!(ctx->Texture.Enabled & 0xf0)) 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;
+
+ /* 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 */
+ /* FIXME: This only works for GL_RBG and GL_RGBA right now */
+ /* FIXME: Handle GL_ALPHA, GL_LIMINANCE{_ALPHA} and GL_INTENSITY */
+ /* FIXME: Handle when no Tex0: i.e., !(ctx->Texture.Enabled & 0x0f) */
+ switch (ctx->Texture.Unit[1].EnvMode) {
+ case GL_REPLACE:
+ switch (tObj->Image[0]->Format) {
+ 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_RGBA:
+ 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_LUMINANCE:
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+ case GL_MODULATE:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGB:
+ 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_RGBA:
+ 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_LUMINANCE:
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+ case GL_DECAL:
+ switch (tObj->Image[0]->Format) {
+ 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_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_LUMINANCE:
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+ case GL_BLEND:
+ switch (tObj->Image[0]->Format) {
+ case GL_RGB:
+ tex_combine_cntl = (R128_COMB_BLEND_PREV |
+ 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_RGBA:
+ tex_combine_cntl = (R128_COMB_BLEND_PREV |
+ 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_LUMINANCE:
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+ default:
+ return;
+ }
+
+ 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;
+ 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;
+ }
+#if USE_AGP_TEXTURES
+ for (i = 0; i < R128_TEX_MAXLEVELS; i++)
+ r128ctx->regs.sec_tex_offset[i] |= 0x02000000;
+#endif
+
+ /* Force loading the new state into the hardware */
+ r128ctx->dirty |= R128_UPDATE_CONTEXT;
+ r128ctx->dirty_context |= R128_CTX_TEX1STATE;
+}
+
+/* Update the hardware texture state */
+/* NOTE: This function is only called while holding the hardware lock */
+void r128UpdateTextureState(r128ContextPtr r128ctx)
+{
+ /* 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 pname, const GLfloat *param)
{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit;
+ GLubyte c[4];
+ CARD32 col;
+
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ /* TexEnv modes are handled in UpdateTextureState */
+ R128_FLUSH_VB(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) {
+ R128_FLUSH_VB(r128ctx);
+ r128ctx->regs.constant_color_c = col;
+ 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 (target != GL_TEXTURE_2D) return;
+ if (level >= R128_TEX_MAXLEVELS) return;
+
+ t = (r128TexObjPtr)tObj->DriverData;
+ if (t) {
+ if (t->bound) R128_FLUSH_VB(r128ctx);
+
+ /* Destroy the old texture, and upload a new one. The actual
+ uploading of the texture image occurs in the UploadTexLevel
+ 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,
@@ -54,30 +1063,113 @@ static void r128DDTexSubImage(GLcontext *ctx, GLenum target,
GLint internalFormat,
const struct gl_texture_image *image)
{
+ r128ContextPtr r128ctx = R128_CONTEXT(ctx);
+ r128TexObjPtr t;
+
+ if (target != GL_TEXTURE_2D) return;
+ if (level >= R128_TEX_MAXLEVELS) return;
+
+ t = (r128TexObjPtr)tObj->DriverData;
+ if (t) {
+ if (t->bound) R128_FLUSH_VB(r128ctx);
+
+ /* Destroy the old texture, and upload a new one. The actual
+ uploading of the texture image occurs in the UploadTexLevel
+ function. */
+ r128DestroyTexObj(r128ctx, t);
+ tObj->DriverData = NULL;
+ r128ctx->dirty |= R128_UPDATE_TEXSTATE;
+ }
}
+/* 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) return;
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ if (t->bound) R128_FLUSH_VB(r128ctx);
+
+ r128SetTexFilter(t, tObj->MinFilter, tObj->MagFilter);
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ if (t->bound) R128_FLUSH_VB(r128ctx);
+
+ r128SetTexWrap(t, tObj->WrapS, tObj->WrapT);
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ if (t->bound) R128_FLUSH_VB(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);
+
+ R128_FLUSH_VB(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) {
+ R128_FLUSH_VB(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 *t)
+ struct gl_texture_object *tObj)
{
- return GL_TRUE;
+ r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData;
+
+ return t && t->memBlock;
}
+/* Initialize the driver's texture functions */
void r128DDInitTextureFuncs(GLcontext *ctx)
{
ctx->Driver.TexEnv = r128DDTexEnv;
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h
index 6543435a5..ff12f0a0d 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h
@@ -37,6 +37,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
+extern void r128ResetGlobalLRU(r128ContextPtr r128ctx);
+extern void r128TexturesGone(r128ContextPtr r128ctx,
+ int offset, int size, int in_use);
+extern int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t);
+extern void r128UpdateTextureState(r128ContextPtr r128ctx);
+extern void r128DestroyTexObj(r128ContextPtr r128ctx, r128TexObjPtr t);
+
extern void r128DDInitTextureFuncs(GLcontext *ctx);
#endif
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..6b94d90d5
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h
@@ -0,0 +1,81 @@
+/* $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_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 */
+} 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 */
+ 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 format used to store
+ texture on card */
+ 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
index 58e2b5980..26753de78 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c
@@ -48,24 +48,66 @@ 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 */
-static void r128DrawTriangle(r128ContextPtr r128ctx,
- r128_vertex *v0,
- r128_vertex *v1,
- r128_vertex *v2)
+/* Draw a triangle from the vertices in the vertex buffer */
+void r128DrawTriangle(r128ContextPtr r128ctx,
+ r128_vertex *v0,
+ r128_vertex *v1,
+ r128_vertex *v2)
{
+#if USE_VERTEX_BUFFERS
+ r128_vertex *vbptr = r128CCEAllocVBSpace(r128ctx, 3);
+
+ *vbptr++ = *v0;
+ *vbptr++ = *v1;
+ *vbptr++ = *v2;
+#else
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+
+ BEGIN_CLIP_LOOP(r128ctx);
+
+#if USE_RHW2
+ R128CCE_WAIT_LOCKED(36);
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 34);
+#else
+ R128CCE_WAIT_LOCKED(33);
+ 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_END_LOCKED();
+
+ END_CLIP_LOOP(r128ctx);
+#endif
}
-static void r128DrawLine(r128ContextPtr r128ctx,
- r128_vertex *tmp0, r128_vertex *tmp1,
- float width)
+/* Draw a line from the vertices in the vertex buffer */
+void r128DrawLine(r128ContextPtr r128ctx,
+ r128_vertex *tmp0, r128_vertex *tmp1,
+ float width)
{
}
-static void r128DrawPoint(r128ContextPtr r128ctx,
- r128_vertex *tmp, float sz)
+/* Draw a point from the vertices in the vertex buffer */
+void r128DrawPoint(r128ContextPtr r128ctx,
+ r128_vertex *tmp, float sz)
{
}
+#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"
@@ -74,12 +116,46 @@ static void r128DrawPoint(r128ContextPtr r128ctx,
#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);
@@ -92,25 +168,17 @@ void r128ChooseRenderState(GLcontext *ctx)
CARD32 shared = 0;
CARD32 fallback = R128_FALLBACK_BIT;
-#if 0
- shared = fallback; /* Make everything a fallback */
-#endif
-
-#if 0
- fallback = 0; /* Turn off all fallbacks */
-#endif
+ 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 1
if (flags & DD_POINT_SMOOTH) index |= fallback;
-#else
- if (flags & DD_POINT_SMOOTH) index |= R128_ANTIALIAS_BIT;
-#endif
if (flags & DD_POINT_ATTEN) index |= fallback;
r128ctx->RenderIndex = index;
@@ -118,12 +186,9 @@ void r128ChooseRenderState(GLcontext *ctx)
if (index & R128_FALLBACK_BIT)
r128ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
+ /* Setup LineFunc */
index = shared;
-#if 1
if (flags & DD_LINE_SMOOTH) index |= fallback;
-#else
- if (flags & DD_LINE_SMOOTH) index |= R128_ANTIALIAS_BIT;
-#endif
if (flags & DD_LINE_STIPPLE) index |= fallback;
r128ctx->RenderIndex |= index;
@@ -131,14 +196,16 @@ void r128ChooseRenderState(GLcontext *ctx)
if (index & R128_FALLBACK_BIT)
r128ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
+ /* Setup TriangleFunc and QuadFunc */
index = shared;
-#if 1
if (flags & DD_TRI_SMOOTH) index |= fallback;
+#if 1
+ if (flags & DD_TRI_OFFSET) index |= fallback;
+ if (flags & DD_TRI_LIGHT_TWOSIDE) index |= fallback;
#else
- if (flags & DD_TRI_SMOOTH) index |= R128_ANTIALIAS_BIT;
-#endif
if (flags & DD_TRI_OFFSET) index |= R128_OFFSET_BIT;
if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R128_TWOSIDE_BIT;
+#endif
if (flags & DD_TRI_UNFILLED) index |= fallback;
if (flags & DD_TRI_STIPPLE) index |= fallback;
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
index ba98eb3e7..91f30d80b 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h
@@ -37,6 +37,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#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
@@ -47,6 +49,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_SELECT_BIT 0x40
#define R128_POINT_PARAM_BIT 0x80 /* not needed? */
+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 sz);
+
extern void r128ChooseRenderState(GLcontext *ctx);
extern void r128TriangleFuncsInit(void);
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h
index ff0804c4e..5cd66a8cd 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h
@@ -33,9 +33,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined(TAG) || !defined(IND)
- this is an error;
+ 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)
@@ -101,60 +103,153 @@ static void TAG(triangle)(GLcontext *ctx,
}
#endif
- BEGIN_CLIP_LOOP(r128ctx);
+ if (r128ctx->regs.tex_cntl_c & (R128_TEXMAP_ENABLE |
+ R128_SEC_TEXMAP_ENABLE)) {
+ BEGIN_CLIP_LOOP(r128ctx);
- R128CCE_BEGIN_LOCKED(15);
- 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));
+#if USE_RHW2
+ R128CCE_WAIT_LOCKED(36);
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 34);
+#else
+ R128CCE_WAIT_LOCKED(33);
+ 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);
+ R128CCEF(v0->x);
+ R128CCEF(v0->y);
#if (IND & R128_OFFSET_BIT)
- R128CCEF(v0->z + offset);
+ R128CCEF(v0->z + offset);
#else
- R128CCEF(v0->z);
+ R128CCEF(v0->z);
#endif
+ R128CCEF(v0->rhw);
#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
- R128CCE(c0);
+ R128CCE(c0);
#else
- R128CCE(*(int *)&v0->dif_argb);
+ 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);
+ R128CCEF(v1->x);
+ R128CCEF(v1->y);
#if (IND & R128_OFFSET_BIT)
- R128CCEF(v1->z + offset);
+ R128CCEF(v1->z + offset);
#else
- R128CCEF(v1->z);
+ R128CCEF(v1->z);
#endif
+ R128CCEF(v1->rhw);
#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
- R128CCE(c1);
+ R128CCE(c1);
#else
- R128CCE(*(int *)&v1->dif_argb);
+ 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);
+ R128CCEF(v2->x);
+ R128CCEF(v2->y);
#if (IND & R128_OFFSET_BIT)
- R128CCEF(v2->z + offset);
+ R128CCEF(v2->z + offset);
#else
- R128CCEF(v2->z);
+ R128CCEF(v2->z);
#endif
+ R128CCEF(v2->rhw);
#if (IND & (R128_FLAT_BIT | R128_TWOSIDE_BIT))
- R128CCE(c2);
+ R128CCE(c2);
#else
- R128CCE(*(int *)&v2->dif_argb);
+ 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_END_LOCKED();
+ R128CCE_END_LOCKED();
- END_CLIP_LOOP(r128ctx);
+ END_CLIP_LOOP(r128ctx);
+ } else {
+ BEGIN_CLIP_LOOP(r128ctx);
+
+ R128CCE_WAIT_LOCKED(15);
+ 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_END_LOCKED();
+
+ END_CLIP_LOOP(r128ctx);
+ }
}
static void TAG(quad)(GLcontext *ctx,
@@ -167,15 +262,17 @@ static void TAG(quad)(GLcontext *ctx,
#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;
+ 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 =
@@ -190,6 +287,8 @@ static void TAG(line)(GLcontext *ctx,
END_CLIP_LOOP(r128ctx);
}
+/* 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)
{
@@ -199,10 +298,6 @@ static void TAG(points)(GLcontext *ctx,
GLfloat sz = ctx->Point.Size * 0.5;
int i;
- /* Culling is disabled automatically via. the
- * ctx->Driver.ReducedPrimitiveChange() callback.
- */
-
BEGIN_CLIP_LOOP(r128ctx);
for(i = first; i <= last; i++) {
@@ -217,6 +312,7 @@ static void TAG(points)(GLcontext *ctx,
#endif
+/* Initialize the table of primitives to render. */
static void TAG(init)(void)
{
tri_tab[IND] = TAG(triangle);
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c
index e3062a603..af271f50f 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c
@@ -36,20 +36,24 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#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.tu1 = tc0[i][0]; \
- v->v.tv1 = tc0[i][1]; \
+ v->v.tu0 = tc0[i][0]; \
+ v->v.tv0 = tc0[i][1]; \
} while (0)
#define TEX1 \
do { \
- v->v.tu2 = tc1[i][0]; \
- v->v.tv2 = tc1[i][1]; \
+ v->v.tu1 = tc1[i][0]; \
+ v->v.tv1 = tc1[i][1]; \
} while (0)
#define SPC \
@@ -75,6 +79,11 @@ do { \
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) { \
@@ -83,22 +92,32 @@ do { \
for (i = start; i < end; i++, v++) { \
float oow = 1.0 / tc[i][3]; \
v->v.rhw *= tc[i][3]; \
- v->v.tu1 *= oow; \
- v->v.tv1 *= oow; \
+ 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.tu2 *= oow; \
- v->v.tv2 *= oow; \
+ 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]; \
@@ -107,10 +126,21 @@ do { \
v->v.z = (1.0/0x10000) * 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 = (1.0/0x10000) * win[2]; \
+ v->v.rhw = win[3]; \
+} while (0)
+#endif
#define NOP
-#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,spec,fog) \
+/* 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); \
@@ -154,43 +184,56 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \
col; \
} \
tex0_4; \
+ tex1_4; \
}
-SETUPFUNC(rs_wt0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP)
-SETUPFUNC(rs_wt0t1, COORD, NOP, TEX0, TEX1, TEX0_4, NOP, NOP)
-SETUPFUNC(rs_wft0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, FOG)
-SETUPFUNC(rs_wft0t1, COORD, NOP, TEX0, TEX1, TEX0_4, NOP, FOG)
-SETUPFUNC(rs_wg, COORD, COL, NOP, NOP, NOP, NOP, NOP)
-SETUPFUNC(rs_wgs, COORD, COL, NOP, NOP, NOP, SPC, NOP)
-SETUPFUNC(rs_wgt0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP)
-SETUPFUNC(rs_wgt0t1, COORD, COL, TEX0, TEX1, TEX0_4, NOP, NOP)
-SETUPFUNC(rs_wgst0, COORD, COL, TEX0, NOP, TEX0_4, SPC, NOP)
-SETUPFUNC(rs_wgst0t1, COORD, COL, TEX0, TEX1, TEX0_4, SPC, NOP)
-SETUPFUNC(rs_wgf, COORD, COL, NOP, NOP, NOP, NOP, FOG)
-SETUPFUNC(rs_wgfs, COORD, COL, NOP, NOP, NOP, SPC, FOG)
-SETUPFUNC(rs_wgft0, COORD, COL, TEX0, NOP, TEX0_4, NOP, FOG)
-SETUPFUNC(rs_wgft0t1, COORD, COL, TEX0, TEX1, TEX0_4, NOP, FOG)
-SETUPFUNC(rs_wgfst0, COORD, COL, TEX0, NOP, TEX0_4, SPC, FOG)
-SETUPFUNC(rs_wgfst0t1, COORD, COL, TEX0, TEX1, TEX0_4, SPC, FOG)
-
-SETUPFUNC(rs_t0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP)
-SETUPFUNC(rs_t0t1, NOP, NOP, TEX0, TEX1, TEX0_4, NOP, NOP)
-SETUPFUNC(rs_f, NOP, NOP, NOP, NOP, NOP, NOP, FOG)
-SETUPFUNC(rs_ft0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, FOG)
-SETUPFUNC(rs_ft0t1, NOP, NOP, TEX0, TEX1, TEX0_4, NOP, FOG)
-SETUPFUNC(rs_g, NOP, COL, NOP, NOP, NOP, NOP, NOP)
-SETUPFUNC(rs_gs, NOP, COL, NOP, NOP, NOP, SPC, NOP)
-SETUPFUNC(rs_gt0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP)
-SETUPFUNC(rs_gt0t1, NOP, COL, TEX0, TEX1, TEX0_4, NOP, NOP)
-SETUPFUNC(rs_gst0, NOP, COL, TEX0, NOP, TEX0_4, SPC, NOP)
-SETUPFUNC(rs_gst0t1, NOP, COL, TEX0, TEX1, TEX0_4, SPC, NOP)
-SETUPFUNC(rs_gf, NOP, COL, NOP, NOP, NOP, NOP, FOG)
-SETUPFUNC(rs_gfs, NOP, COL, NOP, NOP, NOP, SPC, FOG)
-SETUPFUNC(rs_gft0, NOP, COL, TEX0, NOP, TEX0_4, NOP, FOG)
-SETUPFUNC(rs_gft0t1, NOP, COL, TEX0, TEX1, TEX0_4, NOP, FOG)
-SETUPFUNC(rs_gfst0, NOP, COL, TEX0, NOP, TEX0_4, SPC, FOG)
-SETUPFUNC(rs_gfst0t1, NOP, COL, TEX0, TEX1, TEX0_4, SPC, FOG)
+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)
{
@@ -200,6 +243,7 @@ static void rs_invalid(struct vertex_buffer *VB, GLuint start, GLuint end)
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;
@@ -208,64 +252,167 @@ void r128SetupInit(void)
/* 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)
{
- int funcindex = R128_WIN_BIT | R128_RGBA_BIT;
+ 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;
+ funcIndex &= ~R128_RGBA_BIT;
+ funcIndex |= R128_TEX0_BIT;
}
if (ctx->Texture.Enabled & 0xf0)
- funcindex |= R128_TEX1_BIT;
+ funcIndex |= R128_TEX1_BIT;
+ /* FIXME: Verify this works properly */
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- funcindex |= R128_SPEC_BIT;
+ funcIndex |= R128_SPEC_BIT;
if (ctx->FogMode == FOG_FRAGMENT)
- funcindex |= R128_FOG_BIT;
-
- ctx->Driver.RasterSetup = setup_func[funcindex];
+ 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 (new & VERT_FOG_COORD) index |= R128_FOG_BIT;
+
+ 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;
@@ -278,7 +425,7 @@ void r128DDRegisterVB(struct vertex_buffer *VB)
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,
@@ -287,7 +434,7 @@ void r128DDRegisterVB(struct vertex_buffer *VB)
fprintf(stderr, "Cannot allocate clipped elements! Exiting...\n");
exit(1);
}
-
+
free(VB->ClipMask);
VB->ClipMask = (GLubyte *)malloc(sizeof(GLubyte) * r128vb->size);
if (!VB->ClipMask) {
@@ -295,26 +442,115 @@ void r128DDRegisterVB(struct vertex_buffer *VB)
exit(1);
}
- r128vb->primitive = (GLuint *)malloc(sizeof(GLuint) * r128vb->size);
- r128vb->next_primitive = (GLuint *)malloc(sizeof(GLuint) * r128vb->size);
- if (!r128vb->primitive || !r128vb->next_primitive) {
- fprintf(stderr, "Cannot allocate primitive list! 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);
- if (r128vb->primitive) free(r128vb->primitive);
- if (r128vb->next_primitive) free(r128vb->next_primitive);
gl_vector1ui_free(&r128vb->clipped_elements);
free(r128vb);
VB->driver_data = 0;
}
}
+
+/* Get a new VB from the pool of vertex buffers in AGP space */
+static r128CCEVertBufPtr r128CCEGetNewVB(r128ContextPtr r128ctx)
+{
+#define R128_VB_SIZE 4096
+
+ /* FIXME: This only works for a single client right now!!! */
+ if (r128ctx->vb) {
+ r128ctx->vb->start += R128_VB_SIZE;
+ if (r128ctx->vb->start >
+ r128ctx->r128Screen->vbStart + r128ctx->r128Screen->vbSize)
+ r128ctx->vb->start = r128ctx->r128Screen->vbStart;
+ } else {
+ r128ctx->vb = (r128CCEVertBufPtr)malloc(sizeof(*r128ctx->vb));
+ r128ctx->vb->start = r128ctx->r128Screen->vbStart;
+ r128ctx->vb->size = R128_VB_SIZE/sizeof(r128_vertex);
+ }
+
+ r128ctx->vb->count = 0;
+ r128ctx->vb->done = GL_FALSE;
+
+ return r128ctx->vb;
+}
+
+/* Release a VB back to the pool of vertex buffers in AGP space */
+static void r128CCEReleaseVB(r128ContextPtr r128ctx)
+{
+ r128ctx->vb->done = GL_TRUE;
+}
+
+/* Reserve space in a VB to store `verts' vertices. 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, and reserve space in
+ the new VB for the `verts' vertices. */
+r128_vertex *r128CCEAllocVBSpace(r128ContextPtr r128ctx, int verts)
+{
+ r128_vertex *vbptr;
+ r128CCEVertBufPtr vb = r128ctx->vb;
+
+ if (!vb || vb->done) vb = r128CCEGetNewVB(r128ctx);
+
+ if (vb->count + verts > vb->size) {
+ r128CCEFlushVB(r128ctx);
+ vb = r128CCEGetNewVB(r128ctx);
+ }
+
+ vbptr = (r128_vertex *)(r128ctx->r128Screen->agp + vb->start) + vb->count;
+ vb->count += verts;
+ return vbptr;
+}
+
+/* Send a VB to the Rage 128 to be processed */
+void r128CCEFlushVB(r128ContextPtr r128ctx)
+{
+ unsigned char *R128MMIO = r128ctx->r128Screen->mmio;
+
+ if (!r128ctx->vb ||
+ !r128ctx->vb->count ||
+ r128ctx->vb->done) return;
+
+ /* Make sure vertices are in memory, and not stuck in the WC cache */
+ R128FlushWCMemory();
+
+ /* FIXME: The textures referenced in this VB cannot be removed until
+ after this buffer has been processed. ATI suggests loading new
+ textures via HOSTDATA command packets to solve this problem. */
+
+ /* FIXME: We need a way to detect if the VB is free or if it is
+ still in use. By waiting for idle, we know that the currently
+ processing buffer is complete, but waiting is slow. A better
+ solution is to use a counter that is stored in one of the
+ GUI_SCRATCH_REGs, which gets incremented after each VB is
+ processed. Also, we will need to associate the count value with
+ each VB in the pool of VBs -- this will need to be stored in the
+ SAREA. */
+
+#if 1
+ /* FIXME: Is this _really_ needed? */
+ R128CCEWaitForIdle(r128ctx->r128Screen);
+#endif
+
+ BEGIN_CLIP_LOOP(r128ctx);
+
+ R128CCE_WAIT_LOCKED(5);
+ R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM, 3);
+ R128CCE(r128ctx->vb->start);
+ R128CCE(r128ctx->vb->count);
+ R128CCE(R128_FULL_VERTEX_FORMAT);
+ R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST |
+ R128_CCE_VC_CNTL_PRIM_WALK_LIST |
+ (r128ctx->vb->count << R128_CCE_VC_CNTL_NUM_SHIFT));
+ R128CCE_END_LOCKED();
+
+ END_CLIP_LOOP(r128ctx);
+
+ r128CCEReleaseVB(r128ctx);
+}
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
index 96a560411..9b0a3f7c7 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h
@@ -37,6 +37,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
+#define USE_RHW2 0
+
+/* FIXME: This is endian-specific */
typedef struct {
GLubyte b;
GLubyte g;
@@ -45,34 +48,95 @@ typedef struct {
} r128Color;
typedef struct {
- GLfloat x, y, z;
- GLfloat rhw;
- r128Color dif_argb;
- r128Color spec_frgb;
- GLfloat tu1;
- GLfloat tv1;
- GLfloat tu2;
- GLfloat tv2;
- GLfloat rhw2;
+ 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 {
- GLvector1ui clipped_elements;
- r128VertexPtr verts;
- int last_vert;
- GLuint *primitive;
- GLuint *next_primitive;
- void *vert_store;
- GLuint size;
+ 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))
+#if USE_VERTEX_BUFFERS
+#define R128_FLUSH_VB(CC) \
+do { \
+ if ((CC)->vb) r128CCEFlushVB(CC); \
+} while (0)
+#else
+#define R128_FLUSH_VB(CC) (void)(CC)
+#endif
+
#define R128_SPEC_BIT 0x01
#define R128_FOG_BIT 0x02
#define R128_ALPHA_BIT 0x04 /* GL_BLEND, not used */
@@ -81,10 +145,18 @@ typedef struct {
#define R128_RGBA_BIT 0x20
#define R128_WIN_BIT 0x40
-extern void r128SetupInit(void);
-extern void r128ChooseRasterSetupFunc(GLcontext *ctx);
-extern void r128DDRegisterVB(struct vertex_buffer *VB);
-extern void r128DDUnregisterVB(struct vertex_buffer *VB);
+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);
+
+extern r128_vertex *r128CCEAllocVBSpace(r128ContextPtr r128ctx, int verts);
+extern void r128CCEFlushVB(r128ContextPtr r128ctx);
#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
index c0d1697c6..a337b6ea7 100644
--- a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c
+++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c
@@ -34,37 +34,26 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
-/* r128 DDX driver includes */
-#include "r128_dri.h"
-#include "r128_reg.h"
-
/* r128 Mesa driver includes */
#include "r128_init.h"
#include "r128_context.h"
#include "r128_xmesa.h"
-#include "r128_dd.h"
#include "r128_state.h"
-#include "r128_span.h"
-#include "r128_depth.h"
#include "r128_tex.h"
#include "r128_swap.h"
-#include "r128_tris.h"
-#include "r128_vb.h"
/* Mesa src includes */
#include "context.h"
-#if 0
-#include "vbxform.h"
-#include "matrix.h"
-#endif
+#include "simple_list.h"
#ifdef DEBUG_LOCKING
char *prevLockFile = NULL;
int prevLockLine = 0;
#endif
-r128ContextPtr r128Context = NULL;
+static r128ContextPtr r128Context = NULL;
+/* Count the number of bits set */
static int count_bits(unsigned int n)
{
int bits = 0;
@@ -76,100 +65,24 @@ static int count_bits(unsigned int n)
return bits;
}
+/* FIXME: */
+
+/* Initialize the driver specific screen private data */
GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv)
{
- r128ScreenPtr r128Screen;
- R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
-
- /* Allocate the private area */
- r128Screen = (r128ScreenPtr)Xmalloc(sizeof(*r128Screen));
- if (!r128Screen) return GL_FALSE;
-
- 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 GL_FALSE;
- }
-
- r128Screen->agpRgn.handle = r128DRIPriv->agpHandle;
- r128Screen->agpRgn.size = r128DRIPriv->agpSize;
- if (drmMap(sPriv->fd,
- r128Screen->agpRgn.handle,
- r128Screen->agpRgn.size,
- (drmAddressPtr)&r128Screen->agp)) {
- drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
- Xfree(r128Screen);
- return GL_FALSE;
- }
-
- r128Screen->deviceID = r128DRIPriv->deviceID;
-
- r128Screen->width = r128DRIPriv->width;
- r128Screen->height = r128DRIPriv->height;
- r128Screen->depth = r128DRIPriv->depth;
- r128Screen->bpp = r128DRIPriv->bpp;
-
- 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->textureX = r128DRIPriv->textureX;
- r128Screen->textureY = r128DRIPriv->textureY;
- r128Screen->textureSize = r128DRIPriv->textureSize;
-
-#if 0
- 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->ringStart = r128DRIPriv->ringStart;
- r128Screen->ringSize = r128DRIPriv->ringSize;
- r128Screen->ringWritePtr = &r128DRIPriv->ringWrite;
- r128Screen->ringReadPtr = (int *)(r128Screen->agp
- + r128DRIPriv->ringReadOffset);
-
- r128Screen->MMIOFifoSlots = 0;
- r128Screen->CCEFifoSlots = 0;
-
- r128Screen->CCEFifoAddr = R128_PM4_FIFO_DATA_EVEN;
-
- r128Screen->driScreen = sPriv;
-
- sPriv->private = (void *)r128Screen;
-
- r128TriangleFuncsInit();
- r128SetupInit();
+ sPriv->private = (void *)r128CreateScreen(sPriv);
+ if (!sPriv->private) return GL_FALSE;
return GL_TRUE;
}
+/* Reset the driver specific screen private data */
void XMesaResetDriver(__DRIscreenPrivate *sPriv)
{
- r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private;
-
- drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size);
- drmUnmap((drmAddress)r128Screen->agp, r128Screen->agpRgn.size);
-
- Xfree(r128Screen);
- sPriv->private = NULL;
+ r128DestroyScreen(sPriv);
}
+/* Create and initialize the Mesa and driver specific visual data */
XMesaVisual XMesaCreateVisual(XMesaDisplay *display,
XMesaVisualInfo visinfo,
GLboolean rgb_flag,
@@ -223,6 +136,7 @@ XMesaVisual XMesaCreateVisual(XMesaDisplay *display,
return v;
}
+/* Destroy the Mesa and driver specific visual data */
void XMesaDestroyVisual(XMesaVisual v)
{
Xfree(v->gl_visual);
@@ -230,91 +144,40 @@ void XMesaDestroyVisual(XMesaVisual v)
Xfree(v);
}
+/* Create and initialize the Mesa and driver specific context data */
XMesaContext XMesaCreateContext(XMesaVisual v, XMesaContext share_list,
__DRIcontextPrivate *driContextPriv)
{
XMesaContext c;
- r128ContextPtr r128ctx;
- GLcontext *shareCtx, *glCtx;
c = (XMesaContext)Xmalloc(sizeof(*c));
if (!c) {
return NULL;
}
- r128ctx = (r128ContextPtr)Xmalloc(sizeof(*r128ctx));
- if (!r128ctx) {
- Xfree(c);
- return NULL;
- }
-
/* Initialize XMesaContext */
c->display = v->display;
c->xm_visual = v;
c->xm_buffer = NULL; /* Set by MakeCurrent */
c->driContextPriv = driContextPriv;
- c->private = (void *)r128ctx;
-
- if (share_list)
- shareCtx = ((r128ContextPtr)(share_list->private))->glCtx;
- else
- shareCtx = NULL;
-
- /* Initialize r128Context */
- r128ctx->xmCtx = c;
- r128ctx->glCtx = gl_create_context(v->gl_visual,
- shareCtx,
- (void *)r128ctx,
- GL_TRUE);
- r128ctx->display = v->display;
- r128ctx->driContext = driContextPriv;
- r128ctx->driDrawable = NULL; /* Set by XMesaMakeCurrent */
- r128ctx->dirty = R128_ALL_DIRTY;
- r128ctx->needClip = GL_TRUE;
- r128ctx->r128Screen =
- (r128ScreenPtr)(driContextPriv->driScreenPriv->private);
-
- /* Initialize GLcontext */
- glCtx = r128ctx->glCtx;
-
- r128DDInitExtensions(glCtx);
-
- r128DDInitDriverFuncs(glCtx);
- r128DDInitStateFuncs(glCtx);
- r128DDInitSpanFuncs(glCtx);
- r128DDInitDepthFuncs(glCtx);
- r128DDInitTextureFuncs(glCtx);
-
-#if 1
- /* FIXME: Move to r128_tris.c */
- glCtx->Driver.TriangleCaps = (DD_TRI_CULL
- | DD_TRI_LIGHT_TWOSIDE
- | DD_TRI_OFFSET);
- glCtx->TriangleCaps |= DD_CLIP_FOG_COORD;
-
- if (glCtx->VB) r128DDRegisterVB(glCtx->VB);
-#endif
-
- r128DDInitState(r128ctx);
+ c->private = (void *)r128CreateContext(v->gl_visual, c, share_list);
+ if (!c->private) {
+ Xfree(c);
+ return NULL;
+ }
return c;
}
+/* Destroy the Mesa and driver specific context data */
void XMesaDestroyContext(XMesaContext c)
{
- r128ContextPtr r128ctx = (r128ContextPtr)c->private;
-
- if (r128ctx) {
- gl_destroy_context(r128ctx->glCtx);
- Xfree(r128ctx);
- c->private = NULL;
- }
-
- if (c->private == (void *)r128Context) {
- r128Context = NULL;
- }
+ if (c->private == (void *)r128Context) r128Context = NULL;
+ r128DestroyContext((r128ContextPtr)c->private);
+ Xfree(c);
}
+/* Create and initialize the Mesa and driver specific window buffer data */
XMesaBuffer XMesaCreateWindowBuffer(XMesaVisual v,
XMesaWindow w,
__DRIdrawablePrivate *driDrawPriv)
@@ -328,6 +191,7 @@ XMesaBuffer XMesaCreateWindowBuffer(XMesaVisual v,
return xm_buf;
}
+/* Create and initialize the Mesa and driver specific pixmap buffer data */
XMesaBuffer XMesaCreatePixmapBuffer(XMesaVisual v,
XMesaPixmap p,
XMesaColormap c,
@@ -342,12 +206,14 @@ XMesaBuffer XMesaCreatePixmapBuffer(XMesaVisual v,
return xm_buf;
}
+/* Destroy the Mesa and driver specific color buffer data */
void XMesaDestroyBuffer(XMesaBuffer b)
{
gl_destroy_framebuffer(b->gl_buffer);
Xfree(b);
}
+/* Copy the back color buffer to the front color buffer */
void XMesaSwapBuffers(XMesaBuffer b)
{
/*
@@ -356,36 +222,29 @@ void XMesaSwapBuffers(XMesaBuffer b)
*/
if (r128Context == NULL) return;
+ /* FIXME: Only swap buffers when a back buffer exists */
+
+ 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(XMesaContext c, XMesaBuffer b)
{
if (c) {
- r128ContextPtr oldCtx = r128Context;
-
- if (r128Context
- && c->private == (void *)r128Context
- && b->driDrawPriv == r128Context->driDrawable) return GL_TRUE;
-
- r128Context = (r128ContextPtr)c->private;
-
- if (oldCtx) {
- r128Context->dirty = R128_REQUIRE_QUIESCENCE | R128_START_CCE;
- if (oldCtx != r128Context)
- r128Context->dirty |= R128_UPDATE_CONTEXT;
- if (oldCtx->driDrawable != b->driDrawPriv)
- r128Context->dirty |= R128_UPDATE_CLIPRECTS;
- } else {
- r128Context->dirty = R128_ALL_DIRTY;
- }
+ if (r128Context &&
+ c->private == (void *)r128Context &&
+ b->driDrawPriv == R128_DRIDRAWABLE(r128Context))
+ return GL_TRUE;
- r128Context->driDrawable = b->driDrawPriv;
+ r128Context = r128MakeCurrent(r128Context, (r128ContextPtr)c->private,
+ b->driDrawPriv);
- gl_make_current(r128Context->glCtx, b->gl_buffer);
+ gl_make_current(R128_MESACTX(r128Context), b->gl_buffer);
- if (!r128Context->glCtx->Viewport.Width) {
- gl_Viewport(r128Context->glCtx, 0, 0,
+ if (!R128_MESACTX(r128Context)->Viewport.Width) {
+ gl_Viewport(R128_MESACTX(r128Context), 0, 0,
b->driDrawPriv->w, b->driDrawPriv->h);
}
} else {
@@ -396,29 +255,30 @@ GLboolean XMesaMakeCurrent(XMesaContext c, XMesaBuffer b)
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(XMesaContext c)
{
- r128ContextPtr r128ctx = (r128ContextPtr)c->private;
- __DRIdrawablePrivate *dPriv = r128ctx->driDrawable;
- __DRIscreenPrivate *sPriv = r128ctx->r128Screen->driScreen;
- int stamp = dPriv->lastStamp;
+ __DRIscreenPrivate *sPriv = R128_DRISCREEN((r128ContextPtr)c->private);
+ __DRIdrawablePrivate *dPriv = R128_DRIDRAWABLE((r128ContextPtr)c->private);
+ int stamp = dPriv->lastStamp;
- /*
- * The window might have moved, so we might need to get new
- * cliprects.
- *
- * NOTE: This releases and regrabs the hw lock, so all state
- * checking must be done *after* this call.
- */
- XMESA_VALIDATE_DRAWABLE_INFO(r128ctx->display, sPriv, dPriv);
-
- r128ctx->dirty |= R128_ALL_DIRTY; /* FIXME: Optimize this!! */
-
- if (stamp != dPriv->lastStamp) { /* FIXME??: handle window moves */
- r128ctx->dirty |= R128_UPDATE_CLIPRECTS;
- }
+ /* 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(c->display, sPriv, dPriv);
- if (r128ctx->dirty) r128UpdateStateLocked(r128ctx);
+ r128UpdateState((r128ContextPtr)c->private, (stamp != dPriv->lastStamp));
}
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
index 92e55c85b..71771f42f 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
@@ -219,14 +219,30 @@ typedef struct {
drmHandle agpHandle; /* Handle from drmAddMap */
unsigned char *AGP; /* Map */
- int CCEMode;
- int CCEFifoSize;
+ Bool CCEInUse; /* CCE is currently active */
+ int CCEMode; /* CCE mode that server/clients use */
+ int CCEFifoSize; /* Size of the CCE command FIFO */
+ /* CCE ring buffer data */
unsigned long ringStart;
int ringSize;
int ringWrite;
unsigned long ringReadOffset;
+ /* CCE vertex buffer data */
+ unsigned long vbStart;
+ int vbSize;
+
+ /* CCE indirect buffer data */
+ unsigned long indStart;
+ int indSize;
+
+ /* CCE AGP Texture data */
+ unsigned long agpTexStart;
+ int agpTexSize;
+ int log2AGPTexGran;
+
+ /* DRI screen private data */
int fbX;
int fbY;
int backX;
@@ -236,6 +252,7 @@ typedef struct {
int textureX;
int textureY;
int textureSize;
+ int log2TexGran;
#endif
} R128InfoRec, *R128InfoPtr;
@@ -256,13 +273,15 @@ extern void R128WaitForVerticalSync(ScrnInfoPtr pScrn);
extern Bool R128AccelInit(ScreenPtr pScreen);
extern Bool R128CursorInit(ScreenPtr pScreen);
+extern int R128MinBits(int val);
+
#ifdef XF86DRI
extern Bool R128DRIScreenInit(ScreenPtr pScreen);
extern void R128DRICloseScreen(ScreenPtr pScreen);
extern Bool R128DRIFinishScreenInit(ScreenPtr pScreen);
extern void R128DRICCEInitRingBuffer(ScrnInfoPtr pScrn);
-extern void R128LostContext(ScreenPtr pScreen);
-extern void R128SwapContextPrivate(ScreenPtr pScreen);
+extern void R128CCEStart(ScrnInfoPtr pScrn);
+extern void R128CCEStop(ScrnInfoPtr pScrn);
#endif
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c
index 36a2a1092..4db9ba44e 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c
@@ -969,16 +969,20 @@ static void R128EngineInit(ScrnInfoPtr pScrn)
R128WaitForIdle(pScrn);
}
-/* Initialize XAA for supported acceleration and also initialize the
- graphics hardware for acceleration. */
-Bool R128AccelInit(ScreenPtr pScreen)
+#if 0
+#ifdef XF86DRI
+ /* FIXME: When direct rendering is enabled, we should use the CCE to
+ draw 2D commands */
+static void R128CCEAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- XAAInfoRecPtr a;
+}
+#endif
+#endif
+
+static void R128MMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a)
+{
+ R128InfoPtr info = R128PTR(pScrn);
- if (!(a = info->accel = XAACreateInfoRec())) return FALSE;
-
a->Flags = (PIXMAP_CACHE
| OFFSCREEN_PIXMAPS
| LINEAR_FRAMEBUFFER);
@@ -1061,12 +1065,29 @@ Bool R128AccelInit(ScreenPtr pScreen)
| SCANLINE_PAD_DWORD
| SYNC_AFTER_IMAGE_WRITE);
#endif
-
- R128EngineInit(pScrn);
+}
+
+/* Initialize XAA for supported acceleration and also initialize the
+ graphics hardware for acceleration. */
+Bool R128AccelInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr info = R128PTR(pScrn);
+ XAAInfoRecPtr a;
+ if (!(a = info->accel = XAACreateInfoRec())) return FALSE;
+
+#if 0
#ifdef XF86DRI
- R128DRICCEInitRingBuffer(pScrn);
+ /* FIXME: When direct rendering is enabled, we should use the CCE to
+ draw 2D commands */
+ if (info->directRenderingEnabled) R128CCEAccelInit(pScrn, a);
+ else
+#endif
#endif
+ R128MMIOAccelInit(pScrn, a);
+
+ R128EngineInit(pScrn);
return XAAInit(pScreen, a);
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c
index 07d7f1bf3..d14f8c574 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c
@@ -71,9 +71,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86DDC.h"
/* DRI support */
-#if 0
-#include "GL/glxtokens.h"
-#endif
#include "GL/glxint.h"
#include "xf86drm.h"
#include "sarea.h"
@@ -81,6 +78,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86dri.h"
#include "dri.h"
#include "r128_dri.h"
+#include "r128_sarea.h"
#include "r128_dripriv.h"
/* Driver data structures */
@@ -100,6 +98,8 @@ do { \
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(ScrnInfoPtr pScrn, int entries)
{
R128InfoPtr info = R128PTR(pScrn);
@@ -115,6 +115,8 @@ static void R128CCEWaitForFifoFunction(ScrnInfoPtr pScrn, int entries)
}
}
+/* Wait until the CCE is completely idle: the FIFO has drained and the
+ CCE is idle. */
static void R128CCEWaitForIdle(ScrnInfoPtr pScrn)
{
R128InfoPtr info = R128PTR(pScrn);
@@ -135,7 +137,48 @@ static void R128CCEWaitForIdle(ScrnInfoPtr pScrn)
}
}
- /* FIXME: this routine is from tdfx */
+/* Start the CCE, but only if it is not already in use and the requested
+ mode is a CCE mode. The mode is stored in info->CCEMode. */
+void R128CCEStart(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ if (info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return;
+
+ R128WaitForIdle(pScrn);
+ OUTREG(R128_PM4_BUFFER_CNTL, info->CCEMode);
+ (void)INREG(R128_PM4_BUFFER_ADDR); /* as per the sample code */
+ OUTREG(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN);
+ info->CCEInUse = TRUE;
+}
+
+/* Stop the CCE, but only if it is in use and the requested mode is not
+ the non-CCE mode. This function also flushes any outstanding
+ requests before switching modes.*/
+void R128CCEStop(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ unsigned char *R128MMIO = info->MMIO;
+
+ if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return;
+
+ R128CCEWaitForIdle(pScrn);
+#if 0
+ /* FIXME: This is needed when we use the ring buffer to flush any
+ unfinished commands */
+ OUTREGP(R128_PM4_BUFFER_DL_WPTR,
+ R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE);
+#endif
+ OUTREG(R128_PM4_MICRO_CNTL, 0);
+ OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4);
+ info->CCEInUse = FALSE;
+}
+
+/* Initialize the visual configs that are supported by the hardware.
+ These are combined with the visual configs that the indirect
+ rendering core supports, and the intersection is exported to the
+ client. */
static Bool R128InitVisualConfigs(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -146,17 +189,15 @@ static Bool R128InitVisualConfigs(ScreenPtr pScreen)
R128ConfigPrivPtr *pR128ConfigPtrs = 0;
int i;
- switch (pScrn->bitsPerPixel) {
- case 8:
+ switch (pR128->pixel_code) {
+ case 8: /* 8bpp mode is not support */
+ case 15: /* FIXME */
+ case 24: /* FIXME */
+ return FALSE;
+
case 16:
- case 24:
- break;
case 32:
-#if 0
numConfigs = 4;
-#else
- numConfigs = 1;
-#endif
if (!(pConfigs
= (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig),
@@ -177,45 +218,55 @@ static Bool R128InitVisualConfigs(ScreenPtr pScreen)
return FALSE;
}
- for (i = 0; i < numConfigs; i++) pR128ConfigPtrs[i] = &pR128Configs[i];
-
- pConfigs[0].vid = -1;
- pConfigs[0].class = -1;
- pConfigs[0].rgba = TRUE;
- if (pScrn->depth == 16) {
- pConfigs[0].redSize = 5;
- pConfigs[0].greenSize = 6;
- pConfigs[0].blueSize = 5;
- pConfigs[0].redMask = 0x0000F800;
- pConfigs[0].greenMask = 0x000007E0;
- pConfigs[0].blueMask = 0x0000001F;
- } else {
- pConfigs[0].redSize = 8;
- pConfigs[0].greenSize = 8;
- pConfigs[0].blueSize = 8;
- pConfigs[0].redMask = 0x00FF0000;
- pConfigs[0].greenMask = 0x0000FF00;
- pConfigs[0].blueMask = 0x000000FF;
+ for (i = 0; i < numConfigs; i++) {
+ pR128ConfigPtrs[i] = &pR128Configs[i];
+
+ pConfigs[i].vid = -1;
+ pConfigs[i].class = -1;
+ pConfigs[i].rgba = TRUE;
+ if (pScrn->depth == 16) {
+ pConfigs[i].redSize = 5;
+ pConfigs[i].greenSize = 6;
+ pConfigs[i].blueSize = 5;
+ pConfigs[i].redMask = 0x0000F800;
+ pConfigs[i].greenMask = 0x000007E0;
+ pConfigs[i].blueMask = 0x0000001F;
+ } else {
+ pConfigs[i].redSize = 8;
+ pConfigs[i].greenSize = 8;
+ pConfigs[i].blueSize = 8;
+ pConfigs[i].redMask = 0x00FF0000;
+ pConfigs[i].greenMask = 0x0000FF00;
+ pConfigs[i].blueMask = 0x000000FF;
+ }
+ pConfigs[i].alphaMask = 0;
+ pConfigs[i].accumRedSize = 0;
+ pConfigs[i].accumGreenSize = 0;
+ pConfigs[i].accumBlueSize = 0;
+ pConfigs[i].accumAlphaSize = 0;
+ pConfigs[i].doubleBuffer = TRUE;
+ pConfigs[i].stereo = FALSE;
+ pConfigs[i].bufferSize = pScrn->depth;
+ pConfigs[i].depthSize = 16; /* FIXME: Support other depth */
+ pConfigs[i].stencilSize = 0; /* buffer depths with the new */
+ pConfigs[i].auxBuffers = 0; /* Mesa code. */
+ pConfigs[i].level = 0;
+ pConfigs[i].visualRating = 0;
+ pConfigs[i].transparentPixel = 0;
+ pConfigs[i].transparentRed = 0;
+ pConfigs[i].transparentGreen = 0;
+ pConfigs[i].transparentBlue = 0;
+ pConfigs[i].transparentAlpha = 0;
+ pConfigs[i].transparentIndex = 0;
}
- pConfigs[0].alphaMask = 0;
- pConfigs[0].accumRedSize = 0;
- pConfigs[0].accumGreenSize = 0;
- pConfigs[0].accumBlueSize = 0;
- pConfigs[0].accumAlphaSize = 0;
- pConfigs[0].doubleBuffer = TRUE;
- pConfigs[0].stereo = FALSE;
- pConfigs[0].bufferSize = pScrn->depth;
- pConfigs[0].depthSize = 16;
- pConfigs[0].stencilSize = 0;
- pConfigs[0].auxBuffers = 0;
- pConfigs[0].level = 0;
- pConfigs[0].visualRating = 0;
- pConfigs[0].transparentPixel = 0;
- pConfigs[0].transparentRed = 0;
- pConfigs[0].transparentGreen = 0;
- pConfigs[0].transparentBlue = 0;
- pConfigs[0].transparentAlpha = 0;
- pConfigs[0].transparentIndex = 0;
+
+ /* Turn off double buffer support for certain visuals */
+ pConfigs[1].doubleBuffer = FALSE;
+ pConfigs[3].doubleBuffer = FALSE;
+
+ /* Turn off depth buffer support for certain visuals */
+ pConfigs[2].depthSize = 0;
+ pConfigs[3].depthSize = 0;
break;
}
@@ -226,50 +277,83 @@ static Bool R128InitVisualConfigs(ScreenPtr pScreen)
return TRUE;
}
+/* Create the Rage 128-specific context information */
static Bool R128CreateContext(ScreenPtr pScreen, VisualPtr visual,
drmContext hwContext, void *pVisualConfigPriv,
DRIContextType contextStore)
{
+ /* Nothing yet */
return TRUE;
}
+/* Destroy the Rage 128-specific context information */
static void R128DestroyContext(ScreenPtr pScreen, drmContext hwContext,
DRIContextType contextStore)
{
+ /* Nothing yet */
}
-void R128LostContext(ScreenPtr pScreen)
+/* Called when the X server is woken up to allow the last client's
+ context to be saved and the X server's context to be loaded. This is
+ not necessary for the Rage 128 since the client detects when it's
+ context is not currently loaded and then load's it itself. Since the
+ registers to start and stop the CCE are privileged, only the X server
+ can start/stop the engine. */
+static void R128EnterServer(ScreenPtr pScreen)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+#if 1
+ /* FIXME: When the CCE is used for 2D drawing in the X server, we
+ will not need to stop/start the CCE when entering/leaving the X
+ server. */
+ R128CCEStop(pScrn);
+#else
+ R128CCEWaitForIdle(pScrn);
+#endif
}
-void R128SwapContextPrivate(ScreenPtr pScreen)
+/* Called when the X server goes to sleep to allow the X server's
+ context to be saved and the last client's context to be loaded. This
+ is not necessary for the Rage 128 since the client detects when it's
+ context is not currently loaded and then load's it itself. Since the
+ registers to start and stop the CCE are privileged, only the X server
+ can start/stop the engine. */
+static void R128LeaveServer(ScreenPtr pScreen)
{
+#if 1
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- unsigned char *R128MMIO = R128PTR(pScrn)->MMIO;
- R128CCEWaitForIdle(pScrn);
- OUTREGP(R128_PM4_BUFFER_DL_WPTR,
- R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE);
- OUTREG(R128_PM4_MICRO_CNTL, 0);
- OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4);
+ /* FIXME: When the CCE is used for 2D drawing in the X server, we
+ will not need to stop/start the CCE when entering/leaving the X
+ server. */
+ R128CCEStart(pScrn);
+#endif
}
+/* Contexts can be swapped by the X server if necessary. This callback
+ is currently only used to perform any functions necessary when
+ entering or leaving the X server, and in the future might not be
+ necessary. */
static void R128DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
DRIContextType oldContextType, void *oldContext,
DRIContextType newContextType, void *newContext)
{
if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) &&
(newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */
- R128SwapContextPrivate(pScreen);
+ R128EnterServer(pScreen);
}
if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) &&
(newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */
- R128LostContext(pScreen);
+ R128LeaveServer(pScreen);
}
}
+/* Initialize the state of the back and depth buffers. */
static void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
{
+#if 0
+ /* FIXME: This routine needs to have acceleration turned on */
ScreenPtr pScreen = pWin->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
R128InfoPtr pR128 = R128PTR(pScrn);
@@ -277,6 +361,8 @@ static void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
int nbox;
/* FIXME: Copy XAAPaintWindow() and use REGION_TRANSLATE() */
+ /* FIXME: Only initialize the back and depth buffers for contexts
+ that request them */
pbox = REGION_RECTS(prgn);
nbox = REGION_NUM_RECTS(prgn);
@@ -296,19 +382,28 @@ static void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
}
pR128->accel->NeedToSync = TRUE;
+#endif
}
+/* Copy the back and depth buffers when the X server moves a window. */
static void R128DRIMoveBuffers(WindowPtr pWin, DDXPointRec ptOldOrg,
RegionPtr prgnSrc, CARD32 index)
{
+ /* FIXME: This routine needs to have acceleration turned on */
/* FIXME: Copy XAACopyWindow() and use REGION_TRANSLATE() */
+ /* FIXME: Only initialize the back and depth buffers for contexts
+ that request them */
}
+/* Initialize the AGP state. Request memory for use in AGP space, and
+ initialize the Rage 128 registers to point to that memory. */
static Bool R128DRIAgpInit(R128InfoPtr pR128, ScreenPtr pScreen)
{
+ unsigned char *R128MMIO = pR128->MMIO;
unsigned long mode;
unsigned int vendor, device;
int ret;
+ unsigned long cntl;
if (drmAgpAcquire(pR128->drmFD) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not available\n");
@@ -319,11 +414,17 @@ static Bool R128DRIAgpInit(R128InfoPtr pR128, ScreenPtr pScreen)
not appropriate for this particular
combination of graphics card and AGP
chipset. */
-
+
mode = drmAgpGetMode(pR128->drmFD); /* Default mode */
vendor = drmAgpVendorId(pR128->drmFD);
device = drmAgpDeviceId(pR128->drmFD);
+#if 0
+ /* FIXME: This turns off AGP 2X mode */
+ /* FIXME: Make this configurable */
+ mode &= ~0x00000002;
+#endif
+
xf86DrvMsg(pScreen->myNum, X_INFO,
"[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
mode, vendor, device,
@@ -336,7 +437,8 @@ static Bool R128DRIAgpInit(R128InfoPtr pR128, ScreenPtr pScreen)
return FALSE;
}
- pR128->agpSize = 4 * 1024 * 1024; /* FIXME -- arbitrary */
+ /* FIXME: This size was chosen arbitrarily -- make it configurable */
+ pR128->agpSize = 8 * 1024 * 1024;
if ((ret = drmAgpAlloc(pR128->drmFD,
pR128->agpSize, &pR128->agpMemHandle)) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret);
@@ -347,7 +449,7 @@ static Bool R128DRIAgpInit(R128InfoPtr pR128, ScreenPtr pScreen)
"[agp] %d kB allocated with handle 0x%08x\n",
pR128->agpSize / 1024, pR128->agpMemHandle);
- pR128->agpOffset = 0; /* FIXME -- arbitrary */
+ pR128->agpOffset = 0;
if (drmAgpBind(pR128->drmFD, pR128->agpMemHandle, pR128->agpOffset) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not bind\n");
drmAgpFree(pR128->drmFD, pR128->agpMemHandle);
@@ -375,9 +477,35 @@ static Bool R128DRIAgpInit(R128InfoPtr pR128, ScreenPtr pScreen)
"[agp] Aperture mapped at 0x%08lx\n",
(unsigned long)pR128->AGP);
+ /* Initialize Rage 128's AGP registers */
+ cntl = INREG(R128_AGP_CNTL);
+ cntl &= ~R128_AGP_APER_SIZE_MASK;
+ switch (pR128->agpSize) {
+ case 256*1024*1024: cntl |= R128_AGP_APER_SIZE_256MB; break;
+ case 128*1024*1024: cntl |= R128_AGP_APER_SIZE_128MB; break;
+ case 64*1024*1024: cntl |= R128_AGP_APER_SIZE_64MB; break;
+ case 32*1024*1024: cntl |= R128_AGP_APER_SIZE_32MB; break;
+ case 16*1024*1024: cntl |= R128_AGP_APER_SIZE_16MB; break;
+ case 8*1024*1024: cntl |= R128_AGP_APER_SIZE_8MB; break;
+ case 4*1024*1024: cntl |= R128_AGP_APER_SIZE_4MB; break;
+ default:
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[agp] Illegal aperture size %d kB\n",
+ pR128->agpSize / 1024);
+ drmUnmap(pR128->AGP, pR128->agpSize);
+ pR128->AGP = NULL;
+ drmAgpFree(pR128->drmFD, pR128->agpMemHandle);
+ drmAgpRelease(pR128->drmFD);
+ return FALSE;
+ }
+ OUTREG(R128_AGP_BASE, pR128->agpHandle);
+ OUTREG(R128_AGP_CNTL, cntl);
+
return TRUE;
}
+/* Add a map for the MMIO registers that will be accessed by any
+ DRI-based clients. */
static Bool R128DRIMapInit(R128InfoPtr pR128, ScreenPtr pScreen)
{
/* Map registers */
@@ -392,12 +520,13 @@ static Bool R128DRIMapInit(R128InfoPtr pR128, ScreenPtr pScreen)
return TRUE;
}
+/* Load the microcode for the CCE */
static void R128DRILoadMicrocode(ScrnInfoPtr pScrn)
{
unsigned char *R128MMIO = R128PTR(pScrn)->MMIO;
int i;
unsigned long R128Microcode[] = {
- /* Tedz Special Microcode */
+ /* CCE microcode (from ATI) */
0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, 1617039951,
0, 774592877, 0, 1987540286, 0, 2307490946U, 0, 599558925, 0, 589505315, 0,
596487092, 0, 589505315, 1, 11544576, 1, 206848, 1, 311296, 1, 198656, 2,
@@ -444,26 +573,78 @@ static void R128DRILoadMicrocode(ScrnInfoPtr pScrn)
}
}
+/* Initialize the CCE state, and reserve space in AGP memory for the
+ ring, vertex, indirect buffers (if used by the current CCEMode.
+ Allow the rest of AGP memory to be used for textures. */
static void R128DRICCEInit(ScrnInfoPtr pScrn)
{
- R128InfoPtr info = R128PTR(pScrn);
+ R128InfoPtr info = R128PTR(pScrn);
+ int s, l;
+
+/* FIXME: These sizes ware chosen arbitrarily -- make them configurable */
+/* NOTE: These must be page aligned */
+#define RING_SIZE 1*1024*1024
+#define VERTBUF_SIZE 1*1024*1024
+#define INDBUF_SIZE 1*1024*1024
+
+ /* FIXME: Currently, the ring, vertex and indirect buffers all take
+ space, even when the CCEMode does not use them. Make the use of
+ AGP space configurable by only reserving space for the buffers
+ that are required for the current CCEMode. */
/* Initialize the CCE ring buffer data */
info->ringStart = 0;
- info->ringSize = 8192; /* FIXME */
+ info->ringSize = RING_SIZE;
info->ringWrite = 0;
- info->ringReadOffset = 8192; /* FIXME */
-
- info->CCEMode = R128_PM4_192_DWORD_CCE_PIO; /* FIXME */
- info->CCEFifoSize = 192; /* FIXME */
+ info->ringReadOffset = info->ringStart + info->ringSize + 4096;
+
+ /* Reserve space for the vertex buffer */
+ info->vbStart = info->ringReadOffset + 4096;
+ info->vbSize = VERTBUF_SIZE;
+
+ /* Reserve space for the indirect buffer */
+ info->indStart = info->vbStart + info->vbSize;
+ info->indSize = INDBUF_SIZE;
+
+ /* Reserve the rest for AGP textures */
+ info->agpTexStart = info->indStart + info->indSize;
+ s = (info->agpSize - info->agpTexStart);
+ l = R128MinBits((s-1) / R128_NR_TEX_REGIONS);
+ if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
+ info->agpTexSize = (s >> l) << l;
+ info->log2AGPTexGran = l;
+
+ /* Initialize the CCE ring buffer FIFO size */
+ info->CCEInUse = FALSE;
+ info->CCEMode = R128_CCE_MODE;
+ switch (info->CCEMode) {
+ case R128_PM4_NONPM4: info->CCEFifoSize = 0; break;
+ case R128_PM4_192PIO: info->CCEFifoSize = 192; break;
+ case R128_PM4_192BM: info->CCEFifoSize = 192; break;
+ case R128_PM4_128PIO_64INDBM: info->CCEFifoSize = 128; break;
+ case R128_PM4_128BM_64INDBM: info->CCEFifoSize = 128; break;
+ case R128_PM4_64PIO_128INDBM: info->CCEFifoSize = 64; break;
+ case R128_PM4_64BM_128INDBM: info->CCEFifoSize = 64; break;
+ case R128_PM4_64PIO_64VCBM_64INDBM: info->CCEFifoSize = 64; break;
+ case R128_PM4_64BM_64VCBM_64INDBM: info->CCEFifoSize = 64; break;
+ case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break;
+ }
}
+/* Initialize the ring buffer state for use in the X server and any
+ DRI-based clients. */
void R128DRICCEInitRingBuffer(ScrnInfoPtr pScrn)
{
R128InfoPtr info = R128PTR(pScrn);
unsigned char *R128MMIO = info->MMIO;
unsigned long addr;
+ /* FIXME: When we use the CCE for the X server, we should move this
+ function (and the support functions above) to r128_accel.c */
+
+ /* Initialize CCE data */
+ R128DRICCEInit(pScrn);
+
/* The manual (p. 2) says this address is
in "VM space". This means it's an
offset from the start of AGP space. */
@@ -476,42 +657,41 @@ void R128DRICCEInitRingBuffer(ScrnInfoPtr pScrn)
OUTREG(R128_PM4_BUFFER_DL_RPTR_ADDR, 0x00000000);
#else
/* DL_RPTR_ADDR is a physical address.
- This should probably be in the SAREA. */
+ This should be in the SAREA. */
*(volatile long unsigned *)(info->AGP + info->ringReadOffset) = 0;
OUTREG(R128_PM4_BUFFER_DL_RPTR_ADDR, (info->agpHandle
+ info->ringReadOffset));
#endif
/* Set watermark control */
-#if 1
- OUTREG(R128_PM4_BUFFER_WM_CNTL, 0x00000000);
-#else
OUTREG(R128_PM4_BUFFER_WM_CNTL,
((R128_WATERMARK_L/4) << R128_WMA_SHIFT)
| ((R128_WATERMARK_M/4) << R128_WMB_SHIFT)
| ((R128_WATERMARK_N/4) << R128_WMC_SHIFT)
| ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT));
-#endif
-#if 1
addr = INREG(R128_PM4_BUFFER_ADDR); /* Force read. Why? Because it's
in the examples... */
-#endif
R128CCEWaitForIdle(pScrn);
/* Turn on bus mastering */
-#if 1
- OUTREGP(R128_BUS_CNTL, R128_BUS_MASTER_DIS, ~R128_BUS_MASTER_DIS);
-#else
OUTREGP(R128_BUS_CNTL, 0, ~R128_BUS_MASTER_DIS);
-#endif
+#if 0
+ /* FIXME: If we use the CCE ring buffer for the X server, we need to
+ start the engine here for the X server. */
+#else
/* Make sure the CCE is off for the X server */
OUTREG(R128_PM4_MICRO_CNTL, 0);
OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4);
+#endif
}
+/* Initialize the screen-specific data structures for the DRI and the
+ Rage 128. This is the main entry point to the device-specific
+ initialization code. It calls device-independent DRI functions to
+ create the DRI data structures and initialize the DRI state. */
Bool R128DRIScreenInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -519,6 +699,21 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
DRIInfoPtr pDRIInfo;
R128DRIPtr pR128DRI;
+ switch (pR128->pixel_code) {
+ case 8:
+ /* These modes are not supported (yet). */
+ case 15:
+ case 24:
+ return FALSE;
+
+ /* Only 16 and 32 color depths are supports currently. */
+ case 16:
+ case 32:
+ break;
+ }
+
+ /* Create the DRI data structure, and fill it in before calling the
+ DRIScreenInit(). */
if (!(pDRIInfo = DRICreateInfoRec())) return FALSE;
pR128->pDRIInfo = pDRIInfo;
@@ -614,56 +809,25 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
/* Reset the Graphics Engine */
R128EngineReset(pScrn);
- /* Initialize CCE */
- R128DRICCEInit(pScrn);
-
return TRUE;
}
-void R128DRICloseScreen(ScreenPtr pScreen)
+/* Finish initializing the device-dependent DRI state, and call
+ DRIFinishScreenInit() to complete the device-independent DRI
+ initialization. */
+Bool R128DRIFinishScreenInit(ScreenPtr pScreen)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr pR128 = R128PTR(pScrn);
-
- /* De-allocate all AGP resources */
- if (pR128->AGP) {
- drmUnmap(pR128->AGP, pR128->agpSize);
- pR128->AGP = NULL;
- }
- if (pR128->agpMemHandle) {
- drmAgpUnbind(pR128->drmFD, pR128->agpMemHandle);
- drmAgpFree(pR128->drmFD, pR128->agpMemHandle);
- pR128->agpMemHandle = 0;
- drmAgpRelease(pR128->drmFD);
- }
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr pR128 = R128PTR(pScrn);
+ R128SAREAPrivPtr pSAREAPriv;
+ R128DRIPtr pR128DRI;
- DRICloseScreen(pScreen);
-
- if (pR128->pDRIInfo) {
- if (pR128->pDRIInfo->devPrivate) {
- xfree(pR128->pDRIInfo->devPrivate);
- pR128->pDRIInfo->devPrivate = NULL;
- }
- DRIDestroyInfoRec(pR128->pDRIInfo);
- pR128->pDRIInfo = NULL;
- }
- if (pR128->pVisualConfigs) {
- xfree(pR128->pVisualConfigs);
- pR128->pVisualConfigs = NULL;
- }
- if (pR128->pVisualConfigsPriv) {
- xfree(pR128->pVisualConfigsPriv);
- pR128->pVisualConfigsPriv = NULL;
- }
-}
+ pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScreen);
+ memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
+ R128DRICCEInitRingBuffer(pScrn);
+ /* FIXME: R128CCEStart(pScrn); */
-Bool R128DRIFinishScreenInit(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr pR128 = R128PTR(pScrn);
- R128DRIPtr pR128DRI;
-
pR128->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
/* pR128->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */
@@ -688,6 +852,7 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen)
pR128DRI->textureX = pR128->textureX;
pR128DRI->textureY = pR128->textureY;
pR128DRI->textureSize = pR128->textureSize;
+ pR128DRI->log2TexGran = pR128->log2TexGran;
pR128DRI->CCEMode = pR128->CCEMode;
pR128DRI->CCEFifoSize = pR128->CCEFifoSize;
@@ -697,7 +862,58 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen)
pR128DRI->ringWrite = pR128->ringWrite;
pR128DRI->ringReadOffset = pR128->ringReadOffset;
+ pR128DRI->vbStart = pR128->vbStart;
+ pR128DRI->vbSize = pR128->vbSize;
+
+ pR128DRI->indStart = pR128->indStart;
+ pR128DRI->indSize = pR128->indSize;
+
+ pR128DRI->agpTexStart = pR128->agpTexStart;
+ pR128DRI->agpTexSize = pR128->agpTexSize;
+ pR128DRI->log2AGPTexGran = pR128->log2AGPTexGran;
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%08lx %d\n",
pR128DRI->registerHandle, pR128DRI->registerSize);
return DRIFinishScreenInit(pScreen);
}
+
+/* The screen is being closed, so clean up any state and free any
+ resources used by the DRI. */
+void R128DRICloseScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ R128InfoPtr pR128 = R128PTR(pScrn);
+
+ /* De-allocate all AGP resources */
+ if (pR128->AGP) {
+ drmUnmap(pR128->AGP, pR128->agpSize);
+ pR128->AGP = NULL;
+ }
+ if (pR128->agpMemHandle) {
+ drmAgpUnbind(pR128->drmFD, pR128->agpMemHandle);
+ drmAgpFree(pR128->drmFD, pR128->agpMemHandle);
+ pR128->agpMemHandle = 0;
+ drmAgpRelease(pR128->drmFD);
+ }
+
+ /* De-allocate all DRI resources */
+ DRICloseScreen(pScreen);
+
+ /* De-allocate all DRI data structures */
+ if (pR128->pDRIInfo) {
+ if (pR128->pDRIInfo->devPrivate) {
+ xfree(pR128->pDRIInfo->devPrivate);
+ pR128->pDRIInfo->devPrivate = NULL;
+ }
+ DRIDestroyInfoRec(pR128->pDRIInfo);
+ pR128->pDRIInfo = NULL;
+ }
+ if (pR128->pVisualConfigs) {
+ xfree(pR128->pVisualConfigs);
+ pR128->pVisualConfigs = NULL;
+ }
+ if (pR128->pVisualConfigsPriv) {
+ xfree(pR128->pVisualConfigsPriv);
+ pR128->pVisualConfigsPriv = NULL;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h
index a443c060c..911cde1b5 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h
@@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* Authors:
- * Rickard E. Faith <faith@precisioninsight.com>
* Kevin E. Martin <kevin@precisioninsight.com>
+ * Rickard E. Faith <faith@precisioninsight.com>
*
*/
@@ -38,36 +38,62 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <xf86drm.h>
+/* The CCE will default to the following mode: */
+#define R128_CCE_MODE R128_PM4_64PIO_64VCBM_64INDBM
typedef struct {
+ /* FIXME: There needs to be two register regions. One to allow
+ read-only access to the block of non-FIFO'd GUI registers
+ (0x0000-0x0FFC), and one to allow read/write acces to the block
+ of FIFO'd GUI registers (0x1000-0x1FFC) */
+
+ /* MMIO register data */
drmHandle registerHandle;
drmSize registerSize;
+
+ /* AGP data */
drmHandle agpHandle;
drmSize agpSize;
- int deviceID;
- int width;
- int height;
- int depth;
- int bpp;
+ /* 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 display (8, 16, 24, 32) */
- int fbX;
+ int fbX; /* Start of frame buffer */
int fbY;
- int backX;
+ int backX; /* Start of shared back buffer */
int backY;
- int depthX;
+ int depthX; /* Start of shared depth buffer */
int depthY;
- int textureX;
+ int textureX; /* Start of texture data in frame buffer */
int textureY;
int textureSize;
+ int log2TexGran;
- int CCEMode;
- int CCEFifoSize;
+ int CCEMode; /* CCE mode that server/clients use */
+ int CCEFifoSize; /* Size of the CCE command FIFO */
+ /* CCE ring buffer data */
unsigned long ringStart;
int ringSize;
int ringWrite;
unsigned long ringReadOffset;
+
+ /* CCE vertex buffer data */
+ unsigned long vbStart;
+ int vbSize;
+
+ /* CCE indirect buffer data */
+ unsigned long indStart;
+ int indSize;
+
+ /* CCE AGP Texture data */
+ unsigned long agpTexStart;
+ int agpTexSize;
+ int log2AGPTexGran;
} R128DRIRec, *R128DRIPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dripriv.h
index 81c6f2ba8..acec5e269 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dripriv.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dripriv.h
@@ -51,9 +51,4 @@ typedef struct {
int dummy;
} R128DRIContextRec, *R128DRIContextPtr;
-typedef struct {
- /* Nothing here yet */
- int dummy;
-} R128SAREAPriv;
-
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
index 944034b1e..df6f0e1e5 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
@@ -109,6 +109,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "dri.h"
#include "r128_dri.h"
#include "r128_dripriv.h"
+#include "r128_sarea.h"
#endif
/* Driver data structures */
@@ -495,7 +496,7 @@ static void R128Unblank(ScrnInfoPtr pScrn)
}
/* Compute log base 2 of val. */
-static int R128MinBits(int val)
+int R128MinBits(int val)
{
int bits;
@@ -1111,6 +1112,12 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
R128TRACE(("R128ScreenInit %x %d\n", pScrn->memPhysBase, pScrn->fbOffset));
+#ifdef XF86DRI
+ /* Turn off the CCE for now. */
+ info->CCEInUse = FALSE;
+ info->CCEMode = R128_PM4_NONPM4;
+#endif
+
if (!R128MapMem(pScrn)) return FALSE;
pScrn->fbOffset = 0;
#ifdef XF86DRI
@@ -1138,8 +1145,6 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
call into the driver's InitGLXVisuals
call back. */
info->directRenderingEnabled = R128DRIScreenInit(pScreen);
- /* Force the initialization of the context */
- R128LostContext(pScreen);
#endif
@@ -1288,10 +1293,16 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
}
#ifdef XF86DRI
+ /* Allocate frame buffer space for the
+ shared back and depth buffers as well
+ as for local textures. */
if (info->directRenderingEnabled) {
FBAreaPtr fbarea;
+ int width_bytes = pScrn->displayWidth * info->pixel_bytes;
+ int maxy = info->FbMapSize / width_bytes;
+ int l;
- /* Back buffer setup */
+ /* Allocate the shared back buffer */
if ((fbarea = xf86AllocateOffscreenArea(pScreen,
pScrn->virtualX,
pScrn->virtualY,
@@ -1309,7 +1320,7 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
info->backY = -1;
}
- /* Depth buffer setup */
+ /* Allocate the shared depth buffer */
if ((fbarea = xf86AllocateOffscreenArea(pScreen,
pScrn->virtualX,
pScrn->virtualY,
@@ -1326,6 +1337,53 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
info->depthX = -1;
info->depthY = -1;
}
+
+ /* Allocate local texture space */
+ if (((maxy - MemBox.y2 - 1) * width_bytes) >
+ (pScrn->virtualX * pScrn->virtualY * 2 * info->pixel_bytes)) {
+ info->textureX = 0;
+ info->textureY = MemBox.y2 + 1;
+ info->textureSize = (maxy - MemBox.y2 - 1) * width_bytes;
+
+ l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS);
+ if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
+
+ info->log2TexGran = l;
+ info->textureSize = (info->textureSize >> l) << l;
+
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n",
+ info->textureSize/1024,
+ info->textureX, info->textureY,
+ pScrn->displayWidth, maxy);
+ } else if ((fbarea = xf86AllocateOffscreenArea(pScreen,
+ pScrn->virtualX,
+ pScrn->virtualY * 2,
+ 32,
+ NULL, NULL, NULL))) {
+ info->textureX = fbarea->box.x1;
+ info->textureY = fbarea->box.y1;
+ info->textureSize = ((fbarea->box.y2 - fbarea->box.y1) *
+ (fbarea->box.x2 - fbarea->box.x1) *
+ info->pixel_bytes);
+
+ l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS);
+ if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
+
+ info->log2TexGran = l;
+ info->textureSize = (info->textureSize >> l) << l;
+
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n",
+ info->textureSize/1024,
+ fbarea->box.x1, fbarea->box.y1,
+ fbarea->box.x2, fbarea->box.y2);
+ } else {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Unable to reserve texture space in frame buffer\n");
+ info->textureX = -1;
+ info->textureY = -1;
+ }
}
#endif
/* Hardware cursor setup */
@@ -1375,8 +1433,8 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
- /* DRI finalization */
#ifdef XF86DRI
+ /* DRI finalization */
if (info->directRenderingEnabled) {
/* Now that mi, cfb, drm and others have
done their thing, complete the DRI
@@ -2050,6 +2108,7 @@ static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen)
R128TRACE(("R128CloseScreen\n"));
#ifdef XF86DRI
+ /* Disable direct rendering */
if (info->directRenderingEnabled) {
R128DRICloseScreen(pScreen);
info->directRenderingEnabled = FALSE;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
index 50ed5b1d7..64c414a8d 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
@@ -108,6 +108,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_AGP_APER_OFFSET 0x0178
#define R128_AGP_BASE 0x0170
#define R128_AGP_CNTL 0x0174
+# define R128_AGP_APER_SIZE_256MB (0x00 << 0)
+# define R128_AGP_APER_SIZE_128MB (0x20 << 0)
+# define R128_AGP_APER_SIZE_64MB (0x30 << 0)
+# define R128_AGP_APER_SIZE_32MB (0x38 << 0)
+# define R128_AGP_APER_SIZE_16MB (0x3c << 0)
+# define R128_AGP_APER_SIZE_8MB (0x3e << 0)
+# define R128_AGP_APER_SIZE_4MB (0x3f << 0)
+# define R128_AGP_APER_SIZE_MASK (0x3f << 0)
#define R128_AGP_COMMAND 0x0f58 /* PCI */
#define R128_AGP_PLL_CNTL 0x0010 /* PLL */
#define R128_AGP_STATUS 0x0f54 /* PCI */
@@ -556,6 +564,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_PC_GUI_CTLSTAT 0x1748
#define R128_PC_GUI_MODE 0x1744
#define R128_PC_NGUI_CTLSTAT 0x0184
+# define R128_PC_FLUSH_GUI (3 << 0)
# define R128_PC_FLUSH_ALL 0x00ff
# define R128_PC_BUSY (1 << 31)
#define R128_PC_NGUI_MODE 0x0180
@@ -660,9 +669,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_PM4_BUFFER_OFFSET 0x0700
#define R128_PM4_BUFFER_CNTL 0x0704
-# define R128_PM4_NONPM4 (0 << 28)
-# define R128_PM4_192_DWORD_CCE_PIO (1 << 28)
-# define R128_PM4_192_DWORD_CCE_BM (2 << 28)
+# define R128_PM4_NONPM4 (0 << 28)
+# define R128_PM4_192PIO (1 << 28)
+# define R128_PM4_192BM (2 << 28)
+# define R128_PM4_128PIO_64INDBM (3 << 28)
+# define R128_PM4_128BM_64INDBM (4 << 28)
+# define R128_PM4_64PIO_128INDBM (5 << 28)
+# define R128_PM4_64BM_128INDBM (6 << 28)
+# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28)
+# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28)
+# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28)
#define R128_PM4_BUFFER_WM_CNTL 0x0708
# define R128_WMA_SHIFT 0
# define R128_WMB_SHIFT 8
@@ -810,6 +826,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_WINDOW_Y_SHIFT 4
# define R128_WINDOW_X_SHIFT 20
+#define R128_Z_OFFSET_C 0x1c90
+#define R128_Z_PITCH_C 0x1c94
#define R128_Z_STEN_CNTL_C 0x1c98
# define R128_Z_PIX_WIDTH_16 (0 << 1)
# define R128_Z_PIX_WIDTH_24 (1 << 1)
@@ -856,7 +874,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_STENCIL_ENABLE (1 << 3)
# define R128_SHADE_ENABLE (0 << 4)
# define R128_TEXMAP_ENABLE (1 << 4)
-# define R128_SECONDARY_TEX_ENABLE (1 << 5)
+# define R128_SEC_TEXMAP_ENABLE (1 << 5)
# define R128_FOG_ENABLE (1 << 7)
# define R128_DITHER_ENABLE (1 << 8)
# define R128_ALPHA_ENABLE (1 << 9)
@@ -918,7 +936,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_ALPHA_BLEND_DST_DESTCOLOR (8 << 20)
# define R128_ALPHA_BLEND_DST_INVDESTCOLOR (9 << 20)
# define R128_ALPHA_BLEND_DST_SRCALPHASAT (10 << 20)
-# define R128_ALPHA_BLEND_DST_MASK (15 << 16)
+# define R128_ALPHA_BLEND_DST_MASK (15 << 20)
# define R128_ALPHA_TEST_NEVER (0 << 24)
# define R128_ALPHA_TEST_LESS (1 << 24)
# define R128_ALPHA_TEST_LESSEQUAL (2 << 24)
@@ -941,18 +959,22 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_MIN_BLEND_MIPLINEAR (3 << 1)
# define R128_MIN_BLEND_LINEARMIPNEAREST (4 << 1)
# define R128_MIN_BLEND_LINEARMIPLINEAR (5 << 1)
+# define R128_MIN_BLEND_MASK (7 << 1)
# define R128_MAG_BLEND_NEAREST (0 << 4)
# define R128_MAG_BLEND_LINEAR (1 << 4)
+# define R128_MAG_BLEND_MASK (7 << 4)
# define R128_MIP_MAP_DISABLE (1 << 7)
# define R128_TEX_CLAMP_S_WRAP (0 << 8)
# define R128_TEX_CLAMP_S_MIRROR (1 << 8)
# define R128_TEX_CLAMP_S_CLAMP (2 << 8)
# define R128_TEX_CLAMP_S_BORDER_COLOR (3 << 8)
+# define R128_TEX_CLAMP_S_MASK (3 << 8)
# define R128_TEX_WRAP_S (1 << 10)
# define R128_TEX_CLAMP_T_WRAP (0 << 11)
# define R128_TEX_CLAMP_T_MIRROR (1 << 11)
# define R128_TEX_CLAMP_T_CLAMP (2 << 11)
# define R128_TEX_CLAMP_T_BORDER_COLOR (3 << 11)
+# define R128_TEX_CLAMP_T_MASK (3 << 11)
# define R128_TEX_WRAP_T (1 << 13)
# define R128_TEX_PERSPECTIVE_DISABLE (1 << 14)
# define R128_DATATYPE_VQ (0 << 16)
@@ -968,8 +990,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_DATATYPE_CI16 (10 << 16)
# define R128_DATATYPE_YUV422 (11 << 16)
# define R128_DATATYPE_YUV422_2 (12 << 16)
-# define R128_DATATYPE_AYUV444 (13 << 16)
-# define R128_DATATYPE_ARGB4444 (14 << 16)
+# define R128_DATATYPE_AYUV444 (14 << 16)
+# define R128_DATATYPE_ARGB4444 (15 << 16)
# define R128_PALLETE_EITHER (0 << 20)
# define R128_PALLETE_1 (1 << 20)
# define R128_PALLETE_2 (2 << 20)
@@ -993,14 +1015,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_COMB_BLEND_PREMULT_INV (13 << 0)
# define R128_COMB_ADD_SIGNED2X (14 << 0)
# define R128_COMB_BLEND_CONST_COLOR (15 << 0)
+# define R128_COMB_MASK (15 << 0)
# define R128_COLOR_FACTOR_TEX (4 << 4)
# define R128_COLOR_FACTOR_NTEX (5 << 4)
# define R128_COLOR_FACTOR_ALPHA (6 << 4)
# define R128_COLOR_FACTOR_NALPHA (7 << 4)
+# define R128_COLOR_FACTOR_MASK (15 << 4)
# define R128_INPUT_FACTOR_CONST_COLOR (2 << 10)
# define R128_INPUT_FACTOR_CONST_ALPHA (3 << 10)
# define R128_INPUT_FACTOR_INT_COLOR (4 << 10)
# define R128_INPUT_FACTOR_INT_ALPHA (5 << 10)
+# define R128_INPUT_FACTOR_MASK (15 << 10)
# define R128_COMB_ALPHA_DIS (0 << 14)
# define R128_COMB_ALPHA_COPY (1 << 14)
# define R128_COMB_ALPHA_COPY_INP (2 << 14)
@@ -1010,19 +1035,34 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_COMB_ALPHA_ADD (6 << 14)
# define R128_COMB_ALPHA_ADD_SIGNED (7 << 14)
# define R128_COMB_ALPHA_ADD_SIGNED2X (14 << 14)
+# define R128_COMB_ALPHA_MASK (15 << 14)
# define R128_ALPHA_FACTOR_TEX_ALPHA (6 << 18)
# define R128_ALPHA_FACTOR_NTEX_ALPHA (7 << 18)
+# define R128_ALPHA_FACTOR_MASK (15 << 18)
# define R128_INP_FACTOR_A_CONST_ALPHA (1 << 25)
# define R128_INP_FACTOR_A_INT_ALPHA (2 << 25)
+# define R128_INP_FACTOR_A_MASK (7 << 25)
#define R128_TEX_SIZE_PITCH_C 0x1cb8
-# define R128_TEX_PITCH_SHIFT 0
-# define R128_TEX_SIZE_SHIFT 4
-# define R128_TEX_HEIGHT_SHIFT 8
-# define R128_TEX_MIN_SIZE_SHIFT 12
-# define R128_SEC_TEX_PITCH_SHIFT 16
-# define R128_SEC_TEX_SIZE_SHIFT 20
-# define R128_SEC_TEX_HEIGHT_SHIFT 24
-# define R128_SEC_TEX_MIN_SIZE_SHIFT 28
+# define R128_TEX_PITCH_SHIFT 0
+# define R128_TEX_SIZE_SHIFT 4
+# define R128_TEX_HEIGHT_SHIFT 8
+# define R128_TEX_MIN_SIZE_SHIFT 12
+# define R128_SEC_TEX_PITCH_SHIFT 16
+# define R128_SEC_TEX_SIZE_SHIFT 20
+# define R128_SEC_TEX_HEIGHT_SHIFT 24
+# define R128_SEC_TEX_MIN_SIZE_SHIFT 28
+# define R128_TEX_PITCH_MASK (0x0f << 0)
+# define R128_TEX_SIZE_MASK (0x0f << 4)
+# define R128_TEX_HEIGHT_MASK (0x0f << 8)
+# define R128_TEX_MIN_SIZE_MASK (0x0f << 12)
+# define R128_SEC_TEX_PITCH_MASK (0x0f << 16)
+# define R128_SEC_TEX_SIZE_MASK (0x0f << 20)
+# define R128_SEC_TEX_HEIGHT_MASK (0x0f << 24)
+# define R128_SEC_TEX_MIN_SIZE_MASK (0x0f << 28)
+# define R128_TEX_SIZE_PITCH_SHIFT 0
+# define R128_SEC_TEX_SIZE_PITCH_SHIFT 16
+# define R128_TEX_SIZE_PITCH_MASK (0xffff << 0)
+# define R128_SEC_TEX_SIZE_PITCH_MASK (0xffff << 16)
#define R128_PRIM_TEX_0_OFFSET_C 0x1cbc
#define R128_PRIM_TEX_1_OFFSET_C 0x1cc0
#define R128_PRIM_TEX_2_OFFSET_C 0x1cc4
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h
new file mode 100644
index 000000000..2b835472e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h
@@ -0,0 +1,69 @@
+/* $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_SAREA_H_
+#define _R128_SAREA_H_
+
+/* Each region is a minimum of 64k, and there are at most 128 of them */
+#define R128_NR_TEX_REGIONS 128
+#define R128_LOG_TEX_GRANULARITY 16
+
+typedef struct {
+ unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char in_use; /* owned by a client, or free? */
+ int age; /* tracked by clients to update local LRU's */
+} R128TexRegion;
+
+typedef struct {
+ /* Maintain an LRU of contiguous regions of texture space. If you
+ * think you own a region of texture memory, and it has an age
+ * different to the one you set, then you are mistaken and it has
+ * been stolen by another client. If global texAge hasn't changed,
+ * there is no need to walk the list.
+ *
+ * These regions can be used as a proxy for the fine-grained texture
+ * information of other clients - by maintaining them in the same
+ * lru which is used to age their own textures, clients have an
+ * approximate lru for the whole of global texture space, and can
+ * make informed decisions as to which areas to kick out. There is
+ * no need to choose whether to kick out your own texture or someone
+ * else's - simply eject them all in LRU order.
+ */
+ R128TexRegion texList[R128_NR_TEX_REGIONS+1]; /* Last elt is sentinal */
+ int texAge; /* last time texture was uploaded */
+
+ int ctxOwner; /* last context to upload state */
+} R128SAREAPriv, *R128SAREAPrivPtr;
+
+#endif