diff options
author | faith <faith> | 2000-01-09 17:12:27 +0000 |
---|---|---|
committer | faith <faith> | 2000-01-09 17:12:27 +0000 |
commit | b782d3c6ebe3bf5564f688a8fcbd4760aeada4f5 (patch) | |
tree | 0790e01e02d28cccf539dead5639edc79b6fe247 | |
parent | 8ba7897413c97980ded22d4bf5276fcab8c07b56 (diff) |
Get client-side CCE packets working via PIO
Bus mastering is still not working yet
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c | 2 | ||||
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h | 67 | ||||
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/r128/testdri.c | 721 |
3 files changed, 635 insertions, 155 deletions
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 0950b5503..3da419d25 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c @@ -244,7 +244,7 @@ static Bool R128DRIAgpInit(R128InfoPtr pR128, ScreenPtr pScreen) return FALSE; } - pR128->agpSize = 64 * 1024; /* FIXME -- arbitrary */ + pR128->agpSize = 16 * 1024; /* FIXME -- arbitrary */ if ((ret = drmAgpAlloc(pR128->drmFD, pR128->agpSize, &pR128->agpMemHandle)) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret); 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 e5b7889b2..28b92e1c2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h @@ -635,4 +635,71 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R128_SCALE_3D_CNTL 0x1a00 + /* Registers for CCE and Microcode Engine */ +#define R128_PM4_MICROCODE_ADDR 0x07d4 +#define R128_PM4_MICROCODE_RADDR 0x07d8 +#define R128_PM4_MICROCODE_DATAH 0x07dc +#define R128_PM4_MICROCODE_DATAL 0x07e0 + +#define R128_PM4_BUFFER_OFFSET 0x0700 +#define R128_PM4_BUFFER_CNTL 0x0704 +# define R128_PM4_NONPM4 (0 << 28) +# define R128_PM4_192_DWORD_CCE_BM (2 << 28) +#define R128_PM4_BUFFER_WM_CNTL 0x0708 +# define R128_WMA_SHIFT 0 +# define R128_WMB_SHIFT 8 +# define R128_WMC_SHIFT 16 +# define R128_WB_WM_SHIFT 24 +#define R128_PM4_BUFFER_DL_RPTR_ADDR 0x070c +#define R128_PM4_BUFFER_DL_RPTR 0x0710 +#define R128_PM4_BUFFER_DL_WPTR 0x0714 +# define R128_PM4_BUFFER_DL_DONE (1 << 31) +#define R128_PM4_STAT 0x07b8 +# define R128_PM4_FIFOCNT_MASK 0x0fff +# define R128_PM4_BUSY (1 << 16) +# define R128_PM4_GUI_ACTIVE (1 << 31) +#define R128_PM4_BUFFER_ADDR 0x07f0 +#define R128_PM4_MICRO_CNTL 0x07fc +# define R128_PM4_MICRO_FREERUN (1 << 30) +#define R128_PM4_FIFO_DATA_EVEN 0x1000 +#define R128_PM4_FIFO_DATA_ODD 0x1004 + + /* CCE packet types */ +#define R128_CCE_PACKET1 0x40000000 +#define R128_CCE_PACKET2 0x80000000 +#define R128_CCE_PACKET3_NOP 0xC0001000 +#define R128_CCE_PACKET3_PAINT 0xC0001100 +#define R128_CCE_PACKET3_BITBLT 0xC0001200 +#define R128_CCE_PACKET3_SMALLTEXT 0xC0001300 +#define R128_CCE_PACKET3_HOSTDATA_BLT 0xC0001400 +#define R128_CCE_PACKET3_POLYLINE 0xC0001500 +#define R128_CCE_PACKET3_SCALING 0xC0001600 +#define R128_CCE_PACKET3_TRANS_SCALING 0xC0001700 +#define R128_CCE_PACKET3_POLYSCANLINES 0xC0001800 +#define R128_CCE_PACKET3_NEXT_CHAR 0xC0001900 +#define R128_CCE_PACKET3_PAINT_MULTI 0xC0001A00 +#define R128_CCE_PACKET3_BITBLT_MULTI 0xC0001B00 +#define R128_CCE_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define R128_CCE_PACKET3_SET_SCISSORS 0xC0001E00 +#define R128_CCE_PACKET3_SET_MODE24BPP 0xC0001F00 +#define R128_CCE_PACKET3_CNTL_PAINT 0xC0009100 +#define R128_CCE_PACKET3_CNTL_BITBLT 0xC0009200 +#define R128_CCE_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define R128_CCE_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define R128_CCE_PACKET3_CNTL_POLYLINE 0xC0009500 +#define R128_CCE_PACKET3_CNTL_SCALING 0xC0009600 +#define R128_CCE_PACKET3_CNTL_TRANS_SCALING 0xC0009700 +#define R128_CCE_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define R128_CCE_PACKET3_CNTL_NEXT_CHAR 0xC0009900 +#define R128_CCE_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define R128_CCE_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define R128_CCE_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 +#define R128_CCE_PACKET3_3D_SAVE_CONTEXT 0xC0002000 +#define R128_CCE_PACKET3_3D_PLAY_CONTEXT 0xC0002100 +#define R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define R128_CCE_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500 +#define R128_CCE_PACKET3_LOAD_PALETTE 0xC0002C00 +#define R128_CCE_PACKET3_PURGE 0xC0002D00 +#define R128_CCE_PACKET3_NEXT_VERTEX_BUNDLE 0xC0002E00 + #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/testdri.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/testdri.c index f9037ef7a..6dd7319d9 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/r128/testdri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/testdri.c @@ -41,6 +41,51 @@ #include <xf86dri.h> #include <sarea.h> #include "r128_dri.h" +#include "r128_reg.h" + +#define R128_TIMEOUT 2000000 +#if 0 +#define R128_WATERMARK_L 16 +#define R128_WATERMARK_M 8 +#define R128_WATERMARK_N 8 +#define R128_WATERMARK_K 128 +#else +#define R128_WATERMARK_L 2 +#define R128_WATERMARK_M 1 +#define R128_WATERMARK_N 1 +#define R128_WATERMARK_K 1 +#endif + +#define R128TRACE(x) printf x + +static int attrib[] = { GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + None }; + +static struct { + int rop; + int pattern; +} R128_ROP[] = { + { R128_ROP3_ZERO, R128_ROP3_ZERO }, /* GXclear */ + { R128_ROP3_DSa, R128_ROP3_DPa }, /* Gxand */ + { R128_ROP3_SDna, R128_ROP3_PDna }, /* GXandReverse */ + { R128_ROP3_S, R128_ROP3_P }, /* GXcopy */ + { R128_ROP3_DSna, R128_ROP3_DPna }, /* GXandInverted */ + { R128_ROP3_D, R128_ROP3_D }, /* GXnoop */ + { R128_ROP3_DSx, R128_ROP3_DPx }, /* GXxor */ + { R128_ROP3_DSo, R128_ROP3_DPo }, /* GXor */ + { R128_ROP3_DSon, R128_ROP3_DPon }, /* GXnor */ + { R128_ROP3_DSxn, R128_ROP3_PDxn }, /* GXequiv */ + { R128_ROP3_Dn, R128_ROP3_Dn }, /* GXinvert */ + { R128_ROP3_SDno, R128_ROP3_PDno }, /* GXorReverse */ + { R128_ROP3_Sn, R128_ROP3_Pn }, /* GXcopyInverted */ + { R128_ROP3_DSno, R128_ROP3_DPno }, /* GXorInverted */ + { R128_ROP3_DSan, R128_ROP3_DPan }, /* GXnand */ + { R128_ROP3_ONE, R128_ROP3_ONE } /* GXset */ +}; static void usage(void) { @@ -66,6 +111,9 @@ typedef struct R128Client { int privSize; R128DRIPtr priv; drmMagic magic; + unsigned long agpStart; + unsigned long ringSize; + int cceFifoSize; /* Local information */ int fd; @@ -73,6 +121,13 @@ typedef struct R128Client { unsigned char *FB; unsigned char *SAREA; unsigned char *AGP; + Drawable drawable; + drmDrawable hHWDrawable; + XID context; + drmContext hHWContext; + int fifoSlots; + int cceFifoSlots; + int written; /* Write pointer -- needs to be in SAREA! */ } R128ClientRec, *R128ClientPtr; static void cv(long retval, long failure, const char *message) @@ -111,29 +166,502 @@ static void R128MapAllRegions(R128ClientPtr cr) R128MapRegion(cr->fd, p->agpHandle, p->agpSize, &cr->AGP); } -int main(int argc, char **argv) +/* Flush all dirty data in the Pixel Cache to memory. */ +static void R128EngineFlush(R128ClientPtr ct) +{ + unsigned char *R128MMIO = ct->REG; + int i; + + R128TRACE((" R128EngineFlush\n")); + OUTREGP(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, ~R128_PC_FLUSH_ALL); + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) break; + } +} + +static int INPLL(R128ClientPtr ct, int addr) +{ + unsigned char *R128MMIO = ct->REG; + + OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); + return INREG(R128_CLOCK_CNTL_DATA); +} + +/* Reset graphics card to known state. */ +static void R128EngineReset(R128ClientPtr cr) +{ + unsigned char *R128MMIO = cr->REG; + CARD32 clock_cntl_index; + CARD32 mclk_cntl; + CARD32 gen_reset_cntl; + + R128TRACE((" R128EngineReset\n")); + R128EngineFlush(cr); + + clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX); + mclk_cntl = INPLL(cr, R128_MCLK_CNTL); + + OUTPLL(R128_MCLK_CNTL, mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CPP); + + gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); + + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + + OUTPLL(R128_MCLK_CNTL, mclk_cntl); + OUTREG(R128_CLOCK_CNTL_INDEX, clock_cntl_index); + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl); +} + +#define R128WaitForFifo(cr, entries) \ +do { \ + if (cr->fifoSlots < entries) R128WaitForFifoFunction(cr, entries); \ + cr->fifoSlots -= entries; \ +} while (0) + +/* The FIFO has 64 slots. This routines waits until at least `entries' of + these slots are empty. */ +static void R128WaitForFifoFunction(R128ClientPtr cr, int entries) +{ + unsigned char *R128MMIO = cr->REG; + int i; + + R128TRACE((" R128WaitForFifoFunction(%d)\n", entries)); + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + cr->fifoSlots = INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK; + if (cr->fifoSlots >= entries) return; + } + R128TRACE(("FIFO time out: %ld entries, stat=0x%08lx, probe=0x%08lx\n", + INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK, + INREG(R128_GUI_STAT), + INREG(R128_GUI_PROBE))); + R128EngineReset(cr); + } +} + +#define R128CCEWaitForFifo(cr, entries) \ +do { \ + if (cr->cceFifoSlots < entries) R128WaitForFifoFunction(cr, entries); \ + cr->cceFifoSlots -= entries; \ +} while (0) + +/* The FIFO has 64 slots. This routines waits until at least `entries' of + these slots are empty. */ +static void R128CCEWaitForFifoFunction(R128ClientPtr cr, int entries) +{ + unsigned char *R128MMIO = cr->REG; + int i; + + R128TRACE((" R128CCEWaitForFifoFunction(%d)\n",entries)); + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + cr->cceFifoSlots = INREG(R128_PM4_STAT) & R128_GUI_FIFOCNT_MASK; + if (cr->cceFifoSlots >= entries) return; + } + R128TRACE(("CCE FIFO time out: %ld entries, stat=0x%08lx\n", + INREG(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK, + INREG(R128_PM4_STAT))); + R128EngineReset(cr); + } +} + +/* 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". */ +static void R128WaitForIdle(R128ClientPtr cr) +{ + unsigned char *R128MMIO = cr->REG; + int i; + + R128TRACE((" R128WaitForIdle\n")); + R128WaitForFifoFunction(cr, 64); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_GUI_STAT) & R128_GUI_ACTIVE)) { + R128EngineFlush(cr); + return; + } + } + R128TRACE(("Idle time out: %ld entries, stat=0x%08lx, probe=0x%08lx\n", + INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK, + INREG(R128_GUI_STAT), + INREG(R128_GUI_PROBE))); + R128EngineReset(cr); + } +} + +static void R128CCEWaitForIdle(R128ClientPtr cr) +{ + unsigned char *R128MMIO = cr->REG; + int i; + + R128TRACE((" R128CCEWaitForIdle\n")); + + R128CCEWaitForFifoFunction(cr, cr->cceFifoSize); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_PM4_STAT) + & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) { + R128EngineFlush(cr); + return; + } + } + R128TRACE(("CCE Idle time out: %ld entries, stat=0x%08lx\n", + INREG(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK, + INREG(R128_PM4_STAT))); + R128EngineReset(cr); + } +} + +static void R128MicroLoad(R128ClientPtr cr) +{ + unsigned char *R128MMIO = cr->REG; + int i; + /* This microcode is from the + cce/inc/cceutil.h file included in the + September 1999 R128ddk1_tar.Z that ATI + released to the public. */ + unsigned long R128Microcode[] = { + /* Tedz Special Microcode */ + 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, + 912273422, 11, 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, + 28, 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9, 30, 1, + 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656, 1, 15630, 1, 51200, + 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1, 15717, 1, 15718, 2, 43, 1, + 15936948, 1, 570480831, 1, 14715071, 12, 322123831, 1, 33953125, 12, 55, 1, + 33559908, 1, 15718, 2, 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, + 509952, 1, 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1, + 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1, 15975928, 1, + 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2, 268449859, 2, 10307, 12, + 176, 1, 15734, 1, 15735, 1, 15630, 1, 15631, 1, 5253120, 6, 3145810, 16, + 2150645232U, 1, 15864, 2, 82, 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, + 1, 7817, 1, 15729, 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, + 1, 16008, 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0, + 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1, 180224, 1, + 103824738, 2, 112, 2, 3145839, 0, 536885440, 1, 114880, 14, 125, 12, + 206975, 1, 33559995, 12, 198784, 0, 33570236, 1, 15803, 0, 15804, 3, + 294912, 1, 294912, 3, 442370, 1, 11544576, 0, 811612160, 1, 12593152, 1, + 11536384, 1, 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, + 14793, 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1, + 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1, 114880, 14, + 159, 12, 198784, 1, 1109409213, 12, 198783, 1, 1107312059, 12, 198784, 1, + 1109409212, 2, 162, 1, 1075854781, 1, 1073757627, 1, 1075854780, 1, 540672, + 1, 10485760, 6, 3145894, 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, + 0, 0, 256, 14, 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, + 1, 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1, 33560360, 1, + 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1, 409611, 9, 188, 0, + 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }; + + R128TRACE(("R128MicroLoad\n")); + R128WaitForIdle(cr); + + OUTREG(R128_PM4_MICROCODE_ADDR, 0); + for (i = 0; i < 256; i += 1) { + OUTREG(R128_PM4_MICROCODE_DATAH, R128Microcode[i*2]); + OUTREG(R128_PM4_MICROCODE_DATAL, R128Microcode[i*2 + 1]); + } +} + +/* Compute log base 2 of val. */ +static int R128Lg(int val) +{ + int bits; + + if (!val) return 1; + for (bits = 0; val >>= 1;) ++bits; + return bits; +} + +static void R128MicroInit(R128ClientPtr cr) +{ + unsigned char *R128MMIO = cr->REG; + volatile unsigned long addr; + + R128TRACE(("R128MicroInit\n")); + /* The manual (p. 2) says this address is + in VM space. I hope that means + "virtual" with respect to the AGP + aperture. */ + OUTREG(R128_PM4_BUFFER_OFFSET, cr->agpStart); /* address */ + OUTREG(R128_PM4_BUFFER_DL_WPTR, 0); /* index */ + OUTREG(R128_PM4_BUFFER_DL_RPTR, 0); /* index */ + /* It seems like DL_RPTR_ADDR should be an + address that is not in the ring buffer? + This should probably be in the SAREA, + and we should pass a physical address + here. */ + *(volatile long unsigned *)(cr->AGP + cr->agpStart + 8192) = 0; + OUTREG(R128_PM4_BUFFER_DL_RPTR_ADDR, cr->agpStart+8192); /* address */ + + /* Set watermark control */ + 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)); + + addr = INREG(R128_PM4_BUFFER_ADDR); /* Force read. Why? Because it's + in the manual... */ + R128TRACE((" BUFFER_ADDR = 0x%08lx\n", addr)); + + R128CCEWaitForIdle(cr); + R128TRACE((" Idle\n")); +} + +static void R128MicroStartBM(R128ClientPtr cr) +{ + unsigned char *R128MMIO = cr->REG; + volatile unsigned long addr; + + R128TRACE(("R128MicroStartBM\n")); + + R128WaitForIdle(cr); /* Wait for PIO FIFO to flush */ + + /* Set size of ring buffer */ + R128TRACE((" %ld QWORDS => %d bits\n", + cr->ringSize/8, R128Lg(cr->ringSize/8))); + OUTREG(R128_PM4_BUFFER_CNTL, (R128Lg(cr->ringSize/8) + | R128_PM4_192_DWORD_CCE_BM)); + addr = INREG(R128_PM4_BUFFER_ADDR); /* Force read. Why? Because it's + in the manual... */ + R128TRACE((" BUFFER_ADDR = 0x%08lx\n", addr)); + + OUTREG(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN); +} + +static void R128MicroStopBM(R128ClientPtr cr) { - int c; - int verbose_flag = 0; - R128ClientRec cr; - int eventBase; - int errorBase; - int majorVersion; - int minorVersion; - int patchVersion; - char *clientDriverName; - int ret; - Bool isDirect; + unsigned char *R128MMIO = cr->REG; + + R128TRACE(("R128MicroStopBM\n")); + + OUTREGP(R128_PM4_BUFFER_DL_WPTR, + R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE); + R128CCEWaitForIdle(cr); /* Wait for CCE FIFO to flush */ + OUTREG(R128_PM4_MICRO_CNTL, 0); + OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4); +} + +static void do_prim(R128ClientPtr cr, int loops, int wait, int method, + int x, int y, int width, int height) +{ + unsigned char *R128MMIO = cr->REG; + unsigned long *area = (unsigned long *)(cr->AGP + cr->written); + Display *display = cr->display; + Window w; + int drawing = 1; + int expose = 0; + GC gc; + GC gc2; + XEvent e; + KeySym sym; + int i; + XVisualInfo *visinfo; + int ret; + + if (!width || !height) { + printf("Illegal parameters: x = %d, y = %d, width = %d, height = %d\n", + x, y, width, height); + return; + } + + w = XCreateSimpleWindow(display, + DefaultRootWindow(display), + x, y, + width, height, + 0, + WhitePixel(display, DefaultScreen(display)), + WhitePixel(display, DefaultScreen(display))); + + gc = XCreateGC(display, w, 0, NULL); + XSetBackground(display, gc, BlackPixel(display, DefaultScreen(display))); + XSetForeground(display, gc, WhitePixel(display, DefaultScreen(display))); + XSetLineAttributes(display, gc, 1, LineSolid, CapRound, JoinRound); + + gc2 = XCreateGC(display, w, 0, NULL); + XSetBackground(display, gc2, WhitePixel(display, DefaultScreen(display))); + XSetForeground(display, gc2, BlackPixel(display, DefaultScreen(display))); + XSetLineAttributes(display, gc2, 1, LineSolid, CapRound, JoinRound); + + /* Initialize GL */ + if (!(visinfo = glXChooseVisual(cr->display, cr->screen, attrib))) { + printf("Error: couldn't get an RGB, Double-buffered visual\n"); + exit(1); + } + ret = XF86DRICreateDrawable(cr->display, cr->screen, (Drawable)w, + &cr->hHWDrawable); + printf("XF86DRICreateDrawable [%d]: %d\n", + ret, cr->hHWDrawable); + + ret = XF86DRICreateContext(cr->display, + cr->screen, + visinfo->visual, + &cr->context, + &cr->hHWContext); + printf("XF86DRICreateContext [%d]: %d\n", + ret, cr->hHWContext); + + /* Bring up window */ + XSelectInput(display, w, ExposureMask|KeyPressMask); + XMapWindow(display, w); + XSync(display, False); + fflush(stdout); - while ((c = getopt(argc, argv, "v" )) != EOF) + for (i = 0; !loops || i < loops; i++) { + if (XEventsQueued(display, QueuedAfterFlush)) { + XNextEvent(display, &e); + switch (e.type) { + case KeyPress: + sym = XKeycodeToKeysym(display, e.xkey.keycode, 0); + printf("Got `%c'\n", (char)sym); + switch (sym) { + case 'q': return; + case 'f': XFlush(display); break; + case 'd': + if (drawing) drawing = 0; + else ++drawing; + break; + } + break; + case Expose: + printf("Got expose\n"); /* so we can kill with xrefresh */ + if (++expose > 1) return; + break; + default: + printf("Got event\n"); + break; + } + } + if (drawing) { + int rect_x, rect_y, rect_w, rect_h; + int color; + + rect_x = (random() / (double)RAND_MAX) * width; + rect_y = (random() / (double)RAND_MAX) * height; + rect_w = (random() / (double)RAND_MAX) * width/2; + rect_h = (random() / (double)RAND_MAX) * height/2; + if (rect_x+rect_w > width) rect_w = width - rect_x; + if (rect_y+rect_h > height) rect_y = height - rect_y; + color = (random() / (double)RAND_MAX) * 16777216; + + switch (method) { + case 0: + XSetForeground(display, gc, color); + XFillRectangle(display, w, gc, rect_x, rect_y, rect_w, rect_h); + XFlush(display); + break; + case 1: + /* Make coordinates relative to origin */ + rect_x += x; + rect_y += y; + + DRM_LIGHT_LOCK(cr->fd, cr->SAREA, cr->hHWContext); + R128MicroStartBM(cr); + + /* Set first byte to type and size. This + packet has 4 words following the header, + so set the size to 3.*/ + *area++ = R128_CCE_PACKET3_CNTL_PAINT | (3 << 16); + *area++ = (R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | (6 << 8) /* GMC_DST_DATATYPE (6=32bpp) */ + | R128_ROP[3].pattern); + *area++ = color; + *area++ = rect_x | (rect_y << 16); + *area++ = (rect_x + rect_w) | ((rect_y + rect_h) << 16); + cr->written += 5 * 4; /* in bytes */ + OUTREG(R128_PM4_BUFFER_DL_WPTR, cr->written / 4); + + OUTREGP(R128_PM4_BUFFER_DL_WPTR, + R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE); + { + int i; + + for (i = 0; i < 10; i++) { + R128TRACE((" %lx %ld %ld %ld\n", + INREG(R128_PM4_BUFFER_DL_RPTR_ADDR), + *(volatile long unsigned *)(cr->AGP + + cr->agpStart + + 8192), + INREG(R128_PM4_BUFFER_DL_RPTR), + INREG(R128_PM4_BUFFER_DL_WPTR) & 0xffff)); + } + + for (i = 0; i < 6; i++) { + R128TRACE((" %d 0x%08lx\n", + i, + *(volatile long unsigned *)(cr->AGP + + i * 4))); + } + + for (i = 0; i < 10; i++) { + R128TRACE((" %lx %ld %ld %ld\n", + INREG(R128_PM4_BUFFER_DL_RPTR_ADDR), + *(volatile long unsigned *)(cr->AGP + + cr->agpStart + + 8192), + INREG(R128_PM4_BUFFER_DL_RPTR), + INREG(R128_PM4_BUFFER_DL_WPTR) & 0xffff)); + } + } + /* Bah, that's not working. try PIO */ + { + unsigned long *pt = (long unsigned *)cr->AGP; + + OUTREG(R128_PM4_FIFO_DATA_EVEN, *pt++); + OUTREG(R128_PM4_FIFO_DATA_ODD, *pt++); + OUTREG(R128_PM4_FIFO_DATA_EVEN, *pt++); + OUTREG(R128_PM4_FIFO_DATA_ODD, *pt++); + OUTREG(R128_PM4_FIFO_DATA_EVEN, *pt++); + OUTREG(R128_PM4_FIFO_DATA_ODD, R128_CCE_PACKET2); + } + R128MicroStopBM(cr); + DRM_UNLOCK(cr->fd, cr->SAREA, cr->hHWContext); + break; + } + } + if (wait) sleep(wait); + } +} + +int main(int argc, char **argv) +{ + int c; + int verbose_flag = 0; + R128ClientRec cr; + int eventBase; + int errorBase; + int majorVersion; + int minorVersion; + int patchVersion; + char *clientDriverName; + int ret; + Bool isDirect; + int loops = 1; + int wait = 10; + int method = 0; + + while ((c = getopt(argc, argv, "vl:w:m" )) != EOF) switch (c) { - case 'v': - ++verbose_flag; - break; - default: - usage(); - break; + case 'v': ++verbose_flag; break; + case 'l': loops = atoi(optarg); break; + case 'w': wait = atoi(optarg); break; + case 'm': ++method; break; + default: usage(); break; } cr.display = XOpenDisplay(NULL); @@ -205,142 +733,27 @@ int main(int argc, char **argv) R128MapAllRegions(&cr); -#if 0 - glintMapAllRegions(&XXXPrivate); - - if (primitive) { - do_prim(&XXXPrivate, primitive, - rect_x, rect_y, rect_width, rect_height, - delay_flag, verbose_flag, loops, - use_mx_flag, use_gamma_flag, - term_flag, init_flag, startup_delay, - dump_flag, dma_flags); - } else { - root = RootWindow( XXXPrivate.dpy, XXXPrivate.screen); - visinfo = glXChooseVisual( XXXPrivate.dpy, XXXPrivate.screen, attrib); - if (!visinfo) { - printf("Error: couldn't get an RGB, Double-buffered visual\n"); - exit(1); - } - - /* window attributes */ - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap( XXXPrivate.dpy, root, - visinfo->visual, AllocNone); - attr.event_mask = StructureNotifyMask | ExposureMask; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - - win = XCreateWindow( XXXPrivate.dpy, root, 0, 0, 70, 70, - 0, visinfo->depth, InputOutput, - visinfo->visual, mask, &attr ); - XXXPrivate.drawable = (Drawable)win; - return_val = XF86DRICreateDrawable(XXXPrivate.dpy, XXXPrivate.screen, - (Drawable)win, - &(XXXPrivate.hHWDrawable)); - printf("CreateDrawable: return_val=%d, hHWDrawable=%x\n", - return_val, XXXPrivate.hHWDrawable); - - ctx = glXCreateContext( XXXPrivate.dpy, visinfo, NULL, True ); - return_val = XF86DRICreateContext(XXXPrivate.dpy, XXXPrivate.screen, - visinfo->visual, - &(XXXPrivate.context), - &(XXXPrivate.hHWContext)); - printf("CreateContext: return_val=%d, hHWContext=%x\n", - return_val, XXXPrivate.hHWContext); - - XMapWindow( XXXPrivate.dpy, win ); - XSync(XXXPrivate.dpy, 1); - XXXPrivate.pClipRects = 0; - DRM_LIGHT_LOCK(XXXPrivate.fd,XXXPrivate.pSAREA,XXXPrivate.hHWContext); -#ifdef NOT_DONE - /* This references - *pXXXPriv->pDrawableEntry, which is - currently uninitialized. */ - XXX_VALIDATE_DRAWABLE_INFO(&XXXPrivate); -#else - /* Perhaps this is better? */ - XXXUpdateDrawableInfo(&XXXPrivate); -#endif - DRM_UNLOCK(XXXPrivate.fd,XXXPrivate.pSAREA,XXXPrivate.hHWContext); - XSync(XXXPrivate.dpy, 1); - - - XSelectInput(XXXPrivate.dpy, win, ExposureMask|KeyPressMask); - - do { - XNextEvent( XXXPrivate.dpy, &event ); - - switch (event.type) { - case Expose: - /* Here's what a typical software fall back would do */ - { - unsigned char *pFB = XXXPrivate.pFB; - int fbStride = XXXPrivate.fbStride; - XXXPrivPtr pXXXPriv = &XXXPrivate; - int numClipRects; - XF86DRIClipRectPtr pRect; - unsigned int *pPixel; - int winX, winY; - - - DRM_LIGHT_LOCK(pXXXPriv->fd,pXXXPriv->pSAREA,pXXXPriv->hHWContext); - XXX_VALIDATE_DRAWABLE_INFO(pXXXPriv); - - winX = pXXXPriv->X; winY=pXXXPriv->Y; - numClipRects = pXXXPriv->numClipRects; - printf("SWFallBack: numClipRects=%d\n", numClipRects); - pRect = pXXXPriv->pClipRects; - if (numClipRects) do { - - printf("SWFallBack: pRect: x1=%d, y1=%d, x2=%d, y2=%d\n", - pRect->x1, pRect->y1, pRect->x2, pRect->y2); - printf("\t winY=%d, winX=%d\n", winY, winX); - - /* do primitive - * we'll just touch inside corners of clip region - * - * Assume depth 32 - */ - pPixel = (unsigned int *)(pFB + - (pRect->y1)*fbStride + (pRect->x1)*4); - *pPixel = 0xffffff; - pPixel = (unsigned int *)(pFB + - (pRect->y1)*fbStride + (pRect->x2-1)*4); - *pPixel = 0xffffff; - pPixel = (unsigned int *)(pFB + - (pRect->y2-1)*fbStride + (pRect->x1)*4); - *pPixel = 0xffffff; - pPixel = (unsigned int *)(pFB + - (pRect->y2-1)*fbStride + (pRect->x2-1)*4); - *pPixel = 0xffffff; - - pRect++; - } while(--numClipRects); - - DRM_UNLOCK(pXXXPriv->fd,pXXXPriv->pSAREA,pXXXPriv->hHWContext); - } - break; - default: break; - } - } while (event.type != KeyPress); - - return_val = XF86DRIDestroyContext(XXXPrivate.dpy, - XXXPrivate.screen, - XXXPrivate.context); - printf("DestroyContext: return_val=%d\n", return_val); - glXDestroyContext( XXXPrivate.dpy, ctx); - - return_val = XF86DRIDestroyDrawable(XXXPrivate.dpy, - XXXPrivate.screen, - XXXPrivate.drawable); - printf("DestroyDrawable: return_val=%d\n", return_val); - XDestroyWindow( XXXPrivate.dpy, win); - } + /* FIXME: we'll hardcode 0 for everything + for now, but the server should pass the + offsets to the client. */ + cr.agpStart = 0; + cr.ringSize = 8 * 1024; + cr.cceFifoSize = 192; + cr.written = 0; + + DRM_LIGHT_LOCK(cr.fd, cr.SAREA, cr.hHWContext); + cr.fifoSlots = 0; /* Reset when we get lock */ + cr.cceFifoSlots = 0; + R128MicroLoad(&cr); + R128EngineReset(&cr); + R128MicroInit(&cr); + DRM_UNLOCK(cr.fd, cr.SAREA, cr.hHWContext); + + do_prim(&cr, loops, wait, method, 200, 200, 200, 200); - drmReturn = drmCloseSub(fd); - printf("drmClose(generic): drmReturn=%d\n", drmReturn); -#endif + /* Cleanup */ + ret = drmClose(cr.fd); + printf("drmClose [%d]\n", ret); ret = XF86DRICloseConnection(cr.display, cr.screen); printf("XF86DRICloseConnection [%d]\n", ret); |