Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2446 lines
124 KiB

/******************************Module*Header**********************************\
*
* *******************
* * GDI SAMPLE CODE *
* *******************
*
* Module Name: pxrx.c
*
* Content: Permedia3 code.
*
* Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#include "precomp.h"
#include "glint.h"
#include "pxrx.h"
#if DBG
ULONG inPxRxContextSwitch = FALSE;
#endif
#define TEST_MINIMUM_FIFO_SPACE(min, str) do { ; } while(0)
extern GAPFNstripFunc gapfnStripPXRX[];
// table to determine which logicops use a source colour/pixel
const DWORD LogicOpReadSrc[] = {
0, /* 00 */
1, /* 01 */
1, /* 02 */
1, /* 03 */
1, /* 04 */
0, /* 05 */
1, /* 06 */
1, /* 07 */
1, /* 08 */
1, /* 09 */
0, /* 10 */
1, /* 11 */
1, /* 12 */
1, /* 13 */
1, /* 14 */
0, /* 15 */
};
const ULONG render2D_NativeBlt[16] = {
/* 0: 0 clear */ __RENDER2D_SPANS,
/* 1: S & D AND */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 2: S & ~D AND reverse */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 3: S COPY */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 4: ~S & D AND inverted */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 5: D no op */ __RENDER2D_SPANS,
/* 6: S ^ D XOR */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 7: S | D OR */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 8: ~(S | D) NOR */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 9: ~(S ^ D) equiv */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 10: ~D invert */ __RENDER2D_SPANS,
/* 11: S | ~D OR reverse */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 12: ~S copy invert */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 13: ~S | D OR invert */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 14: ~(S & D) NAND */ __RENDER2D_SPANS | __RENDER2D_FBSRCREAD,
/* 15: 1 set */ __RENDER2D_SPANS,
};
const ULONG render2D_FillSolid[16] = {
/* 0: 0 clear */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 1: S & D AND */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 2: S & ~D AND reverse */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 3: S COPY */ __RENDER2D_INCX | __RENDER2D_INCY,
/* 4: ~S & D AND inverted */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 5: D no op */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 6: S ^ D XOR */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 7: S | D OR */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 8: ~(S | D) NOR */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 9: ~(S ^ D) equiv */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 10: ~D invert */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 11: S | ~D OR reverse */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 12: ~S copy invert */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 13: ~S | D OR invert */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 14: ~(S & D) NAND */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
/* 15: 1 set */ __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS,
};
const ULONG config2D_FillColour[16] = {
/* 0: 0 clear */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 0),
/* 1: S & D AND */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 1) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 2: S & ~D AND reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 2) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 3: S COPY */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 4: ~S & D AND inverted */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 4) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 5: D no op */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 5) | __CONFIG2D_FBDESTREAD,
/* 6: S ^ D XOR */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 6) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 7: S | D OR */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 7) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 8: ~(S | D) NOR */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 8) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 9: ~(S ^ D) equiv */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 9) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 10: ~D invert */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(10) | __CONFIG2D_FBDESTREAD,
/* 11: S | ~D OR reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(11) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 12: ~S copy invert */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(12) | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 13: ~S | D OR invert */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(13) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 14: ~(S & D) NAND */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(14) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 15: 1 set */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(15),
};
const ULONG config2D_FillColour32bpp[16] = {
/* 0: 0 clear */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 0),
/* 1: S & D AND */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 1) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 2: S & ~D AND reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 2) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 3: S COPY */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_USERSCISSOR | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 4: ~S & D AND inverted */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 4) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 5: D no op */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 5) | __CONFIG2D_FBDESTREAD,
/* 6: S ^ D XOR */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 6) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 7: S | D OR */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 7) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 8: ~(S | D) NOR */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 8) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 9: ~(S ^ D) equiv */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 9) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 10: ~D invert */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(10) | __CONFIG2D_FBDESTREAD,
/* 11: S | ~D OR reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(11) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 12: ~S copy invert */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(12) | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 13: ~S | D OR invert */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(13) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 14: ~(S & D) NAND */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(14) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 15: 1 set */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(15),
};
const ULONG config2D_FillColourDual[16] = {
/* 0: 0 clear */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 0),
/* 1: S & D AND */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 1) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 2: S & ~D AND reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 2) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 3: S COPY */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 3) | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 4: ~S & D AND inverted */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 4) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 5: D no op */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 5) | __CONFIG2D_FBDESTREAD,
/* 6: S ^ D XOR */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 6) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 7: S | D OR */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 7) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 8: ~(S | D) NOR */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 8) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 9: ~(S ^ D) equiv */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE( 9) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 10: ~D invert */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(10) | __CONFIG2D_FBDESTREAD,
/* 11: S | ~D OR reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(11) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 12: ~S copy invert */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(12) | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 13: ~S | D OR invert */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(13) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 14: ~(S & D) NAND */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(14) | __CONFIG2D_FBDESTREAD | __CONFIG2D_EXTERNALSRC | __CONFIG2D_LUTENABLE,
/* 15: 1 set */ __CONFIG2D_FBWRITE | __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(15),
};
const ULONG config2D_FillSolid[16] = {
/* 0: 0 clear */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 0),
/* 1: S & D AND */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 1) | __CONFIG2D_FBDESTREAD,
/* 2: S & ~D AND reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 2) | __CONFIG2D_FBDESTREAD,
/* 3: S COPY */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC,
/* 4: ~S & D AND inverted */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 4) | __CONFIG2D_FBDESTREAD,
/* 5: D no op */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 5) | __CONFIG2D_FBDESTREAD,
/* 6: S ^ D XOR */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 6) | __CONFIG2D_FBDESTREAD,
/* 7: S | D OR */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 7) | __CONFIG2D_FBDESTREAD,
/* 8: ~(S | D) NOR */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 8) | __CONFIG2D_FBDESTREAD,
/* 9: ~(S ^ D) equiv */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 9) | __CONFIG2D_FBDESTREAD,
/* 10: ~D invert */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(10) | __CONFIG2D_FBDESTREAD,
/* 11: S | ~D OR reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(11) | __CONFIG2D_FBDESTREAD,
/* 12: ~S copy invert */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(12),
/* 13: ~S | D OR invert */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(13) | __CONFIG2D_FBDESTREAD,
/* 14: ~(S & D) NAND */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(14) | __CONFIG2D_FBDESTREAD,
/* 15: 1 set */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(15),
};
const ULONG config2D_FillSolidVariableSpans[16] = {
/* 0: 0 clear */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 0),
/* 1: S & D AND */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 1) | __CONFIG2D_FBDESTREAD,
/* 2: S & ~D AND reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 2) | __CONFIG2D_FBDESTREAD,
/* 3: S COPY */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 3),
/* 4: ~S & D AND inverted */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 4) | __CONFIG2D_FBDESTREAD,
/* 5: D no op */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 5) | __CONFIG2D_FBDESTREAD,
/* 6: S ^ D XOR */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 6) | __CONFIG2D_FBDESTREAD,
/* 7: S | D OR */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 7) | __CONFIG2D_FBDESTREAD,
/* 8: ~(S | D) NOR */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 8) | __CONFIG2D_FBDESTREAD,
/* 9: ~(S ^ D) equiv */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 9) | __CONFIG2D_FBDESTREAD,
/* 10: ~D invert */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(10) | __CONFIG2D_FBDESTREAD,
/* 11: S | ~D OR reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(11) | __CONFIG2D_FBDESTREAD,
/* 12: ~S copy invert */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(12),
/* 13: ~S | D OR invert */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(13) | __CONFIG2D_FBDESTREAD,
/* 14: ~(S & D) NAND */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(14) | __CONFIG2D_FBDESTREAD,
/* 15: 1 set */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(15),
};
const ULONG config2D_FillSolid32bpp[16] = {
/* 0: 0 clear */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 0),
/* 1: S & D AND */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 1) | __CONFIG2D_FBDESTREAD,
/* 2: S & ~D AND reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 2) | __CONFIG2D_FBDESTREAD,
/* 3: S COPY */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_USERSCISSOR,
/* 4: ~S & D AND inverted */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 4) | __CONFIG2D_FBDESTREAD,
/* 5: D no op */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 5) | __CONFIG2D_FBDESTREAD,
/* 6: S ^ D XOR */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 6) | __CONFIG2D_FBDESTREAD,
/* 7: S | D OR */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 7) | __CONFIG2D_FBDESTREAD,
/* 8: ~(S | D) NOR */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 8) | __CONFIG2D_FBDESTREAD,
/* 9: ~(S ^ D) equiv */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE( 9) | __CONFIG2D_FBDESTREAD,
/* 10: ~D invert */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(10) | __CONFIG2D_FBDESTREAD,
/* 11: S | ~D OR reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(11) | __CONFIG2D_FBDESTREAD,
/* 12: ~S copy invert */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(12),
/* 13: ~S | D OR invert */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(13) | __CONFIG2D_FBDESTREAD,
/* 14: ~(S & D) NAND */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(14) | __CONFIG2D_FBDESTREAD,
/* 15: 1 set */ __CONFIG2D_FBWRITE | __CONFIG2D_CONSTANTSRC | __CONFIG2D_LOGOP_FORE(15),
};
const ULONG config2D_NativeBlt[16] = {
/* 0: 0 clear */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE( 0),
/* 1: S & D AND */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE( 1) | __CONFIG2D_FBDESTREAD,
/* 2: S & ~D AND reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE( 2) | __CONFIG2D_FBDESTREAD,
/* 3: S COPY */ __CONFIG2D_FBWRITE,
/* 4: ~S & D AND inverted */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE( 4) | __CONFIG2D_FBDESTREAD,
/* 5: D no op */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE( 5) | __CONFIG2D_FBDESTREAD,
/* 6: S ^ D XOR */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE( 6) | __CONFIG2D_FBDESTREAD,
/* 7: S | D OR */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE( 7) | __CONFIG2D_FBDESTREAD,
/* 8: ~(S | D) NOR */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE( 8) | __CONFIG2D_FBDESTREAD,
/* 9: ~(S ^ D) equiv */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE( 9) | __CONFIG2D_FBDESTREAD,
/* 10: ~D invert */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE(10) | __CONFIG2D_FBDESTREAD,
/* 11: S | ~D OR reverse */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE(11) | __CONFIG2D_FBDESTREAD,
/* 12: ~S copy invert */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE(12),
/* 13: ~S | D OR invert */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE(13) | __CONFIG2D_FBDESTREAD,
/* 14: ~(S & D) NAND */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE(14) | __CONFIG2D_FBDESTREAD,
/* 15: 1 set */ __CONFIG2D_FBWRITE | __CONFIG2D_LOGOP_FORE(15),
};
typedef struct Tag_Data_TAG {
ULONG tag;
ULONG data;
} Tag_Data;
Tag_Data DefaultContext_P3[] = {
{ __GlintTagFilterMode, 0x00000000 }, // [0x180]
// { __GlintTagAStart, 0x00000000 }, // [0x0F9]
// { __GlintTagBStart, 0x00000000 }, // [0x0F6]
// { __GlintTagFStart, 0x00000000 }, // [0x0D4]
// { __GlintTagGStart, 0x00000000 }, // [0x0F3]
{ __GlintTagAlphaBlendAlphaMode, __PERMEDIA_DISABLE }, // [0x5F5]
{ __GlintTagAlphaBlendColorMode, __PERMEDIA_DISABLE }, // [0x5F4]
{ __GlintTagAlphaDestColor, 0xFFFFFFFF }, // [0x5F1]
{ __GlintTagAlphaSourceColor, 0xFFFFFFFF }, // [0x5F0]
{ __GlintTagAlphaTestMode, __PERMEDIA_DISABLE }, // [0x100]
{ __GlintTagAntialiasMode, __PERMEDIA_DISABLE }, // [0x101]
{ __GlintTagAreaStippleMode, __PERMEDIA_DISABLE }, // [0x034]
{ __GlintTagColor, 0xFFFFFFFF }, // [0x0FE]
{ __GlintTagColorDDAMode, __PERMEDIA_DISABLE }, // [0x0FC]
{ __GlintTagConstantColor, 0xFFFFFFFF }, // [0x0FD]
// { __GlintTagBasePageOfWorkingSet, 0x00000000 }, // [0x699]
{ __GlintTagBitMaskPattern, 0xFFFFFFFF }, // [0x00D]
// { __GlintTagBorderColor0, 0x00000000 }, // [0x095]
// { __GlintTagBorderColor1, 0x00000000 }, // [0x09F]
{ __GlintTagChromaFailColor, 0x00000000 }, // [0x5F3]
{ __GlintTagChromaPassColor, 0xFFFFFFFF }, // [0x5F2]
{ __GlintTagChromaTestMode, __PERMEDIA_DISABLE }, // [0x1E3]
{ __PXRXTagChromaLower, 0x00000000 }, // [0x1E2]
{ __PXRXTagChromaUpper, 0xFFFFFFFF }, // [0x1E1]
// { __GlintTagD3DAlphaTestMode, 0x00000000 }, // [0x5F8]
{ __DeltaTagDeltaMode, (1 << 19) }, // [0x260]
// { __DeltaTagDeltaControl, (1 << 11) }, // [0x26A] // P3, R3 & P4 Only
// { __GlintTagDeltaTexture01, 0x00000000 }, // [0x28B]
// { __GlintTagDeltaTexture11, 0x00000000 }, // [0x28C]
// { __GlintTagDeltaTexture21, 0x00000000 }, // [0x28D]
// { __GlintTagDeltaTexture31, 0x00000000 }, // [0x28E]
{ __DeltaTagXBias, P3_LINES_BIAS_P }, // [0x290]
{ __DeltaTagYBias, P3_LINES_BIAS_P }, // [0x291]
{ __GlintTagDepth, 0x00000000 }, // [0x135]
{ __GlintTagDepthMode, __PERMEDIA_DISABLE }, // [0x134]
{ __GlintTagDitherMode, __PERMEDIA_DISABLE },// ??? 0x00000403, // [0x103]
// { __GlintTagEndOfFeedback, 0x00000000 }, // [0x1FF]
// { __GlintTagFBBlockColor, 0x00000000 }, // [0x159]
// { __GlintTagFBBlockColor0, 0x00000000 }, // [0x60C]
// { __GlintTagFBBlockColor1, 0x00000000 }, // [0x60D]
// { __GlintTagFBBlockColor2, 0x00000000 }, // [0x60E]
// { __GlintTagFBBlockColor3, 0x00000000 }, // [0x60F]
// { __GlintTagFBBlockColorBack, 0x00000000 }, // [0x614]
// { __GlintTagFBBlockColorBack0, 0x00000000 }, // [0x610]
// { __GlintTagFBBlockColorBack1, 0x00000000 }, // [0x611]
// { __GlintTagFBBlockColorBack2, 0x00000000 }, // [0x612]
// { __GlintTagFBBlockColorBack3, 0x00000000 }, // [0x613]
// { __GlintTagFBBlockColorBackExt, 0x00000000 }, // [0x61D]
// { __GlintTagFBBlockColorBackL, 0x00000000 }, // [0x18C]
// { __GlintTagFBBlockColorBackU, 0x00000000 }, // [0x18B]
// { __GlintTagFBBlockColorExt, 0x00000000 }, // [0x61C]
// { __GlintTagFBBlockColorL, 0x00000000 }, // [0x18E]
// { __GlintTagFBBlockColorU, 0x00000000 }, // [0x18D]
// { __GlintTagFBColor, 0x00000000 }, // [0x153]
// { __GlintTagFBData, 0x00000000 }, // [0x154]
// { __GlintTagFBDestReadEnables, 0x00000000 }, // [0x5DD]
{ __GlintTagFBSoftwareWriteMask, 0xFFFFFFFF }, // [0x104]
{ __GlintTagFBSourceData, 0x00000000 }, // [0x155]
// { __GlintTagFBWriteMaskExt, 0x00000000 }, // [0x61E]
// { __GlintTagFastBlockLimits, 0x00000000 }, // [0x026]
// { __GlintTagFastClearDepth, 0x00000000 }, // [0x13C]
// { __GlintTagFeedbackX, 0x00000000 }, // [0x1F1]
// { __GlintTagFeedbackY, 0x00000000 }, // [0x1F2]
// { __GlintTagFlushSpan, 0x00000000 }, // [0x00C]
{ __GlintTagFogColor, 0xFFFFFFFF }, // [0x0D3]
{ __GlintTagFogMode, 0x00000001 }, // [0x0D2]
{ __GlintTagGIDMode, __PERMEDIA_DISABLE }, // [0x6A7]
// { __GlintTagGlyphData, 0x00000000 }, // [0x6CC]
// { __GlintTagGlyphPosition, 0x00000000 }, // [0x6C1]
// { __GlintTagHeadPhysicalPageAllocation0, 0x00000000 }, // [0x690]
// { __GlintTagHeadPhysicalPageAllocation1, 0x00000000 }, // [0x691]
// { __GlintTagHeadPhysicalPageAllocation2, 0x00000000 }, // [0x692]
// { __GlintTagHeadPhysicalPageAllocation3, 0x00000000 }, // [0x693]
// { __GlintTagInvalidateCache, 0x00000000 }, // [0x66B]
// { __GlintTagKdBStart, 0x00000000 }, // [0x1A6]
// { __GlintTagKdGStart, 0x00000000 }, // [0x1A3]
// { __GlintTagKdRStart, 0x00000000 }, // [0x1A0]
// { __GlintTagKsBStart, 0x00000000 }, // [0x196]
// { __GlintTagKsGStart, 0x00000000 }, // [0x193]
// { __GlintTagKsRStart, 0x00000000 }, // [0x190]
// { __GlintTagLBCancelWrite, 0x00000000 }, // [0x13D] // Obsoleted !!! ??? !!!
// { __GlintTagLBClearDataL, 0x00000000 }, // [0x6AA]
// { __GlintTagLBClearDataU, 0x00000000 }, // [0x6AB]
// { __GlintTagLBDepth, 0x00000000 }, // [0x116]
// { __GlintTagLBDestReadBufferAddr, 0x005FF000 }, // [0x6A2] ???
// { __GlintTagLBDestReadBufferOffset, 0x00000000 }, // [0x6A3]
// { __GlintTagLBDestReadEnables, 0x00000000 }, // [0x6A1]
// { __GlintTagLBReadFormat, 0x0C4C0420 }, // [0x111] ???
// { __GlintTagLBReadMode, 0x00000000 }, // [0x110] // Obsoleted !!! ??? !!!
// { __GlintTagLBSourceData, 0x00000000 }, // [0x114]
// { __GlintTagLBSourceOffset, 0x00000000 }, // [0x112]
// { __GlintTagLBSourceReadBufferAddr, 0x005FF000 }, // [0x6A5] ???
// { __GlintTagLBSourceReadBufferOffset, 0x00000000 }, // [0x6A6]
// { __GlintTagLBStencil, 0x00000000 }, // [0x115]
// { __GlintTagLBWindowBase, 0x00000000 }, // [0x117]
// { __GlintTagLBWindowOffset, 0x00000000 }, // [0x11F]
// { __GlintTagLBWriteBufferAddr, 0x005FF000 }, // [0x6A8] ???
// { __GlintTagLBWriteBufferOffset, 0x00000000 }, // [0x6A9]
// { __GlintTagLBWriteFormat, 0x0C4C0420 }, // [0x119] ???
// { __GlintTagLUTIndex, 0x00000000 }, // [0x098]
// { __GlintTagLUTData, 0x00000000 }, // [0x099]
// { __GlintTagLUTAddress, 0x00000000 }, // [0x09A]
// { __GlintTagLUTTransfer, 0x00000000 }, // [0x09B]
{ __GlintTagLineStippleMode, __PERMEDIA_DISABLE }, // [0x035]
// { __GlintTagLoadLineStippleCounters, 0x00000000 }, // [0x036]
// { __GlintTagLOD, 0x00000000 }, // [0x07A]
{ __GlintTagLOD1, 0x00000000 }, // [0x089]
{ __GlintTagLodRange0, 0x00C00000 }, // [0x669]
{ __GlintTagLodRange1, 0x00C00000 }, // [0x66A]
{ __GlintTagLogicalOpMode, __PERMEDIA_DISABLE }, // [0x105]
// { __GlintTagLogicalTexturePageTableAddr, 0x00000000 }, // [0x69A]
// { __GlintTagLogicalTexturePageTableLength, 0x00000000 }, // [0x69B]
// { __GlintTagMaxHitRegion, 0x00000000 }, // [0x186]
// { __GlintTagMaxRegion, 0x00000000 }, // [0x183]
// { __GlintTagMergeSpanData, 0x00000000 }, // [0x5E7]
// { __GlintTagMinHitRegion, 0x00000000 }, // [0x185]
// { __GlintTagMinRegion, 0x00000000 }, // [0x182]
// { __GlintTagPCIWindowBase0, 0x00000000 }, // [0x5E8]
// { __GlintTagPCIWindowBase1, 0x00000000 }, // [0x5E9]
// { __GlintTagPCIWindowBase2, 0x00000000 }, // [0x5EA]
// { __GlintTagPCIWindowBase3, 0x00000000 }, // [0x5EB]
// { __GlintTagPCIWindowBase4, 0x00000000 }, // [0x5EC]
// { __GlintTagPCIWindowBase5, 0x00000000 }, // [0x5ED]
// { __GlintTagPCIWindowBase6, 0x00000000 }, // [0x5EE]
// { __GlintTagPCIWindowBase7, 0x00000000 }, // [0x5EF]
// { __GlintTagPacked4Pixels, 0x00000000 }, // [0x6CD]
// { __GlintTagPhysicalPageAllocationTableAddr,0x00000000 }, // [0x698]
// { __GlintTagPickResult, 0x00000000 }, // [0x187]
// { __GlintTagPointTable0, 0x00000000 }, // [0x010]
// { __GlintTagPointTable1, 0x00000000 }, // [0x011]
// { __GlintTagPointTable2, 0x00000000 }, // [0x012]
// { __GlintTagPointTable3, 0x00000000 }, // [0x013]
// { __GlintTagPrepareToRender, 0x00000000 }, // [0x021]
// { __GlintTagProvokingVertex, 0x00000000 }, // [0x267]
// { __GlintTagQ1Start, 0x00000000 }, // [0x086]
// { __GlintTagRLCount, 0x00000000 }, // [0x6CF]
// { __GlintTagRLData, 0x00000000 }, // [0x6CE]
// { __GlintTagRLEMask, 0x00000000 }, // [0x189]
// { __GlintTagRStart, 0x00000000 }, // [0x0F0]
{ __GlintTagRasterizerMode, // [0x014]
(1 << 0) | // mirror bitmasks
(3 << 7) | // byteswap bitmasks ABCD => DCBA
(1 << 18) }, // YLimits enabled
// { __GlintTagRectangleOrigin, 0x00000000 }, // [0x6C0]
{ __GlintTagRenderPatchOffset, 0x00000000 }, // [0x6C2]
// { __GlintTagRepeatLine, 0x00000000 }, // [0x265]
// { __GlintTagRepeatTriangle, 0x00000000 }, // [0x262]
// { __GlintTagResetPickResult, 0x00000000 }, // [0x184]
{ __GlintTagRouterMode, 0x00000000 }, // [0x108]
// { __GlintTagS1Start, 0x00000000 }, // [0x080]
// { __GlintTagSaveLineStippleCounters, 0x00000000 }, // [0x038]
// { __GlintTagScanlineOwnership, 0x00000000 }, // [0x016]
{ __GlintTagScissorMaxXY, 0x7FFF7FFF }, // [0x032]
// { __GlintTagScissorMinXY, 0x00000000 }, // [0x031]
{ __GlintTagScissorMode, __PERMEDIA_DISABLE }, // [0x030]
// { __GlintTagSetLogicalTexturePage, 0x00000000 }, // [0x66C]
{ __GlintTagSizeOfFramebuffer, 0x00080000 }, // [0x615]
// { __GlintTagStartXDom, 0x00000000 }, // [0x000]
// { __GlintTagStartXSub, 0x00000000 }, // [0x002]
// { __GlintTagStartY, 0x00000000 }, // [0x004]
{ __GlintTagStatisticMode, 0x00000000 }, // [0x181]
// { __GlintTagStencil, 0x00000000 }, // [0x133]
{ __GlintTagStencilData, 0x00FFFFFF }, // [0x132]
{ __GlintTagStencilMode, 0x00040000 }, // [0x131] ???
// { __GlintTagSuspendUntilFrameBlank, 0x00000000 }, // [0x18F]
// { __GlintTagSync, 0x00000000 }, // [0x188]
// { __GlintTagT1Start, 0x00000000 }, // [0x083]
// { __GlintTagTailPhysicalPageAllocation0, 0x00000000 }, // [0x694]
// { __GlintTagTailPhysicalPageAllocation1, 0x00000000 }, // [0x695]
// { __GlintTagTailPhysicalPageAllocation2, 0x00000000 }, // [0x696]
// { __GlintTagTailPhysicalPageAllocation3, 0x00000000 }, // [0x697]
{ __PXRXTagTextureApplicationMode, __PERMEDIA_DISABLE }, // [0x0D0]
{ __GlintTagQStart, 0x00000000 }, // [0x077]
{ __GlintTagSStart, 0x00000000 }, // [0x071]
{ __GlintTagTStart, 0x00000000 }, // [0x074]
// { __GlintTagTextureCacheControl, 0x00000000 }, // [0x092]
// { __GlintTagTextureChromaLower0, 0x00000000 }, // [0x09E]
// { __GlintTagTextureChromaLower1, 0x00000000 }, // [0x0C1]
// { __GlintTagTextureChromaUpper0, 0x00000000 }, // [0x09D]
// { __GlintTagTextureChromaUpper1, 0x00000000 }, // [0x0C0]
{ __GlintTagTextureCompositeAlphaMode0, 0x00008000 }, // [0x662] ???
{ __GlintTagTextureCompositeAlphaMode1, 0x00008000 }, // [0x664] ???
{ __GlintTagTextureCompositeColorMode0, __PERMEDIA_DISABLE }, // [0x661]
{ __GlintTagTextureCompositeColorMode1, 0x00008000 }, // [0x663] ???
{ __GlintTagTextureCompositeFactor0, 0xFFFFFFFF }, // [0x665] ???
{ __GlintTagTextureCompositeFactor1, 0xFFFFFFFF }, // [0x666] ???
{ __GlintTagTextureCompositeMode, 0x00000000 }, // [0x660]
{ __PXRXTagTextureCoordMode, __PERMEDIA_ENABLE | // [0x070]
(1 << 1) | // SWrap repeat
(1 << 3) | // TWrap repeat
(1 << 17) }, // texture map type == 2D
// { __GlintTagTextureData, 0x00000000 }, // [0x11D]
// { __GlintTagTextureDownloadOffset, 0x00000000 }, // [0x11E]
{ __GlintTagTextureEnvColor, 0xFFFFFFFF }, // [0x0D1]
{ __GlintTagTextureFilterMode, __PERMEDIA_DISABLE }, // [0x09C]
// { __GlintTagTextureFormat, 0x00000000 }, // [0x091]
{ __GlintTagTextureIndexMode0, __PERMEDIA_ENABLE | // [0x667]
(10 << 1) | // texture map log2(width) == log2(1024)
(10 << 5) | // texture map log2(height) == log2(1024)
(1 << 10) | // UWrap repeat
(1 << 12) | // VWrap repeat
(1 << 14) | // texture map type == 2D
(1 << 21) }, // nearest neighbour bias = 0
{ __GlintTagTextureIndexMode1, 0x00200000 }, // [0x668] ???
{ __GlintTagTextureLODBiasS, 0x00000000 }, // [0x08A] ???
{ __GlintTagTextureLODBiasT, 0x00000000 }, // [0x08B] ???
// { __GlintTagTextureLODScale, 0x00000000 }, // [0x268]
// { __GlintTagTextureLODScale1, 0x00000000 }, // [0x269]
// { __GlintTagTextureMapWidth0, 0x00000000 }, // [0x683]
// { __GlintTagTextureMapWidth1, 0x00000000 }, // [0x684]
// { __GlintTagTextureReadMode, 0x00000000 }, // [0x090]
{ __GlintTagTextureReadMode0, __PERMEDIA_ENABLE | // [0x680]
(7 << 25) | // byteswap: HGFEDCBA
(1 << 28) }, // mirror bitmap
{ __GlintTagTextureReadMode1, 0x00000400 }, // [0x681] ???
// { __GlintTagTouchLogicalPage, 0x00000000 }, // [0x66E]
// { __GlintTagUpdateLineStippleCounters, 0x00000000 }, // [0x037]
// { __GlintTagUpdateLogicalTextureInfo, 0x00000000 }, // [0x66D]
// { __GlintTagV0FloatA, 0x00000000 }, // [0x238]
// { __GlintTagV0FloatB, 0x00000000 }, // [0x237]
// { __GlintTagV0FloatF, 0x00000000 }, // [0x239]
// { __GlintTagV0FloatG, 0x00000000 }, // [0x236]
// { __GlintTagV0FloatKdB, 0x00000000 }, // [0x20F]
// { __GlintTagV0FloatKdG, 0x00000000 }, // [0x20E]
// { __GlintTagV0FloatKdR, 0x00000000 }, // [0x20D]
// { __GlintTagV0FloatKsB, 0x00000000 }, // [0x20C]
// { __GlintTagV0FloatKsG, 0x00000000 }, // [0x20B]
// { __GlintTagV0FloatKsR, 0x00000000 }, // [0x20A]
// { __GlintTagV0FloatPackedColour, 0x00000000 }, // [0x23E]
// { __GlintTagV0FloatPackedSpecularFog, 0x00000000 }, // [0x23F]
// { __GlintTagV0FloatQ, 0x00000000 }, // [0x232]
// { __GlintTagV0FloatQ1, 0x00000000 }, // [0x202]
// { __GlintTagV0FloatR, 0x00000000 }, // [0x235]
// { __GlintTagV0FloatS, 0x00000000 }, // [0x230]
// { __GlintTagV0FloatS1, 0x00000000 }, // [0x200]
// { __GlintTagV0FloatT, 0x00000000 }, // [0x231]
// { __GlintTagV0FloatT1, 0x00000000 }, // [0x201]
// { __GlintTagV0FloatX, 0x00000000 }, // [0x23A]
// { __GlintTagV0FloatY, 0x00000000 }, // [0x23B]
// { __GlintTagV0FloatZ, 0x00000000 }, // [0x23C]
// { __GlintTagV0Reserved0, 0x00000000 }, // [0x203]
// { __GlintTagV0Reserved1, 0x00000000 }, // [0x204]
// { __GlintTagV0Reserved2, 0x00000000 }, // [0x205]
// { __GlintTagV0Reserved3, 0x00000000 }, // [0x206]
// { __GlintTagV0Reserved4, 0x00000000 }, // [0x207]
// { __GlintTagV0Reserved5, 0x00000000 }, // [0x208]
// { __GlintTagV0Reserved6, 0x00000000 }, // [0x209]
// { __GlintTagV0Reserved7, 0x00000000 }, // [0x233]
// { __GlintTagV0Reserved8, 0x00000000 }, // [0x234]
// { __GlintTagV1FloatA, 0x00000000 }, // [0x248]
// { __GlintTagV1FloatB, 0x00000000 }, // [0x247]
// { __GlintTagV1FloatF, 0x00000000 }, // [0x249]
// { __GlintTagV1FloatG, 0x00000000 }, // [0x246]
// { __GlintTagV1FloatKdB, 0x00000000 }, // [0x21F]
// { __GlintTagV1FloatKdG, 0x00000000 }, // [0x21E]
// { __GlintTagV1FloatKdR, 0x00000000 }, // [0x21D]
// { __GlintTagV1FloatKsB, 0x00000000 }, // [0x21C]
// { __GlintTagV1FloatKsG, 0x00000000 }, // [0x21B]
// { __GlintTagV1FloatKsR, 0x00000000 }, // [0x21A]
// { __GlintTagV1FloatPackedColour, 0x00000000 }, // [0x24E]
// { __GlintTagV1FloatPackedSpecularFog, 0x00000000 }, // [0x24F]
// { __GlintTagV1FloatQ, 0x00000000 }, // [0x242]
// { __GlintTagV1FloatQ1, 0x00000000 }, // [0x212]
// { __GlintTagV1FloatR, 0x00000000 }, // [0x245]
// { __GlintTagV1FloatS, 0x00000000 }, // [0x240]
// { __GlintTagV1FloatS1, 0x00000000 }, // [0x210]
// { __GlintTagV1FloatT, 0x00000000 }, // [0x241]
// { __GlintTagV1FloatT1, 0x00000000 }, // [0x211]
// { __GlintTagV1FloatX, 0x00000000 }, // [0x24A]
// { __GlintTagV1FloatY, 0x00000000 }, // [0x24B]
// { __GlintTagV1FloatZ, 0x00000000 }, // [0x24C]
// { __GlintTagV1Reserved0, 0x00000000 }, // [0x213]
// { __GlintTagV1Reserved1, 0x00000000 }, // [0x214]
// { __GlintTagV1Reserved2, 0x00000000 }, // [0x215]
// { __GlintTagV1Reserved3, 0x00000000 }, // [0x216]
// { __GlintTagV1Reserved4, 0x00000000 }, // [0x217]
// { __GlintTagV1Reserved5, 0x00000000 }, // [0x218]
// { __GlintTagV1Reserved6, 0x00000000 }, // [0x219]
// { __GlintTagV1Reserved7, 0x00000000 }, // [0x243]
// { __GlintTagV1Reserved8, 0x00000000 }, // [0x244]
// { __GlintTagV2FloatA, 0x00000000 }, // [0x258]
// { __GlintTagV2FloatB, 0x00000000 }, // [0x257]
// { __GlintTagV2FloatF, 0x00000000 }, // [0x259]
// { __GlintTagV2FloatG, 0x00000000 }, // [0x256]
// { __GlintTagV2FloatKdB, 0x00000000 }, // [0x22F]
// { __GlintTagV2FloatKdG, 0x00000000 }, // [0x22E]
// { __GlintTagV2FloatKdR, 0x00000000 }, // [0x22D]
// { __GlintTagV2FloatKsB, 0x00000000 }, // [0x22C]
// { __GlintTagV2FloatKsG, 0x00000000 }, // [0x22B]
// { __GlintTagV2FloatKsR, 0x00000000 }, // [0x22A]
// { __GlintTagV2FloatPackedColour, 0x00000000 }, // [0x25E]
// { __GlintTagV2FloatPackedSpecularFog, 0x00000000 }, // [0x25F]
// { __GlintTagV2FloatQ, 0x00000000 }, // [0x252]
// { __GlintTagV2FloatQ1, 0x00000000 }, // [0x222]
// { __GlintTagV2FloatR, 0x00000000 }, // [0x255]
// { __GlintTagV2FloatS, 0x00000000 }, // [0x250]
// { __GlintTagV2FloatS1, 0x00000000 }, // [0x220]
// { __GlintTagV2FloatT, 0x00000000 }, // [0x251]
// { __GlintTagV2FloatT1, 0x00000000 }, // [0x221]
// { __GlintTagV2FloatX, 0x00000000 }, // [0x25A]
// { __GlintTagV2FloatY, 0x00000000 }, // [0x25B]
// { __GlintTagV2FloatZ, 0x00000000 }, // [0x25C]
// { __GlintTagV2Reserved0, 0x00000000 }, // [0x223]
// { __GlintTagV2Reserved1, 0x00000000 }, // [0x224]
// { __GlintTagV2Reserved2, 0x00000000 }, // [0x225]
// { __GlintTagV2Reserved3, 0x00000000 }, // [0x226]
// { __GlintTagV2Reserved4, 0x00000000 }, // [0x227]
// { __GlintTagV2Reserved5, 0x00000000 }, // [0x228]
// { __GlintTagV2Reserved6, 0x00000000 }, // [0x229]
// { __GlintTagV2Reserved7, 0x00000000 }, // [0x253]
// { __GlintTagV2Reserved8, 0x00000000 }, // [0x254]
// { __GlintTagVTGAddress, 0x00000000 }, // [0x616]
// { __GlintTagVTGData, 0x00000000 }, // [0x617]
// { __GlintTagWaitForCompletion, 0x00000000 }, // [0x017]
{ __GlintTagWindow, 0x00000000 }, // [0x130]
{ __GlintTagWindowOrigin, 0x00000000 }, // [0x039]
// { __GlintTagXBias, 0x00000000 }, // [0x290]
// { __GlintTagYBias, 0x00000000 }, // [0x291]
{ __GlintTagYLimits, 0x7FFF0000 }, // [0x015] // Allow y values from 0 to 32767
{ __PXRXTagYUVMode, __PERMEDIA_DISABLE }, // [0x1E0]
// { __GlintTagZFogBias, 0x00000000 }, // [0x0D7]
// { __GlintTagZStartL, 0x00000000 }, // [0x137]
// { __GlintTagZStartU, 0x00000000 }, // [0x136]
// { __GlintTagdAdx, 0x00000000 }, // [0x0FA]
// { __GlintTagdAdyDom, 0x00000000 }, // [0x0FB]
// { __GlintTagdBdx, 0x00000000 }, // [0x0F7]
// { __GlintTagdBdyDom, 0x00000000 }, // [0x0F8]
// { __GlintTagdFdx, 0x00000000 }, // [0x0D5]
// { __GlintTagdFdyDom, 0x00000000 }, // [0x0D6]
// { __GlintTagdGdx, 0x00000000 }, // [0x0F4]
// { __GlintTagdGdyDom, 0x00000000 }, // [0x0F5]
// { __GlintTagdKdBdx, 0x00000000 }, // [0x1A7]
// { __GlintTagdKdBdyDom, 0x00000000 }, // [0x1A8]
// { __GlintTagdKdGdx, 0x00000000 }, // [0x1A4]
// { __GlintTagdKdGdyDom, 0x00000000 }, // [0x1A5]
// { __GlintTagdKdRdx, 0x00000000 }, // [0x1A1]
// { __GlintTagdKdRdyDom, 0x00000000 }, // [0x1A2]
// { __GlintTagdKsBdx, 0x00000000 }, // [0x197]
// { __GlintTagdKsBdyDom, 0x00000000 }, // [0x198]
// { __GlintTagdKsGdx, 0x00000000 }, // [0x194]
// { __GlintTagdKsGdyDom, 0x00000000 }, // [0x195]
// { __GlintTagdKsRdx, 0x00000000 }, // [0x191]
// { __GlintTagdKsRdyDom, 0x00000000 }, // [0x192]
// { __GlintTagdQ1dx, 0x00000000 }, // [0x087]
// { __GlintTagdQ1dyDom, 0x00000000 }, // [0x088]
{ __GlintTagdQdx, 0x00000000 }, // [0x078]
{ __GlintTagdQdy, 0x00000000 }, // [0x07D]
{ __GlintTagdQdyDom, 0x00000000 }, // [0x079]
// { __GlintTagdRdx, 0x00000000 }, // [0x0F1]
// { __GlintTagdRdyDom, 0x00000000 }, // [0x0F2]
// { __GlintTagdS1dx, 0x00000000 }, // [0x081]
// { __GlintTagdS1dyDom, 0x00000000 }, // [0x082]
{ __GlintTagdSdx, 1 << (32 - 10) }, // [0x072]
{ __GlintTagdSdy, 0x00000000 }, // [0x07B]
{ __GlintTagdSdyDom, 0x00000000 }, // [0x073]
// { __GlintTagdT1dx, 0x00000000 }, // [0x084]
// { __GlintTagdT1dyDom, 0x00000000 }, // [0x085]
{ __GlintTagdTdx, 0x00000000 }, // [0x075]
{ __GlintTagdTdy, 0x00000000 }, // [0x07C]
{ __GlintTagdTdyDom, 1 << (32 - 10) }, // [0x076]
{ __GlintTagdXDom, 0 }, // [0x001]
{ __GlintTagdXSub, 0 }, // [0x003]
{ __GlintTagdY, INTtoFIXED(1) }, // [0x005]
// { __GlintTagdZdxL, 0x00000000 }, // [0x139]
// { __GlintTagdZdxU, 0x00000000 }, // [0x138]
// { __GlintTagdZdyDomL, 0x00000000 }, // [0x13B]
// { __GlintTagdZdyDomU, 0x00000000 }, // [0x13A]
{ __GlintTagLBDestReadMode, 0x00000000 }, // [0x6A0]
{ __GlintTagLBSourceReadMode, 0x00000000 }, // [0x6A4]
{ __GlintTagLBWriteMode, 0x00000000 }, // [0x118]
};
DWORD NUM_P3_CTXT_TAGS = (sizeof(DefaultContext_P3) / sizeof(DefaultContext_P3[0]));
void pxrxSetupDualWrites_Patching( PPDEV ppdev ) {
ULONG bypass = 0;
GLINT_DECL;
DISPDBG((7, "pxrxSetupDualWrites_Patching entered"));
__RENDER2D_OP_PATCHORDER = 0;
glintInfo->fbWriteModeSingleWrite = 1;
glintInfo->fbWriteModeDualWrite = 1 | (1 << 4) | (1 << 12) | (1 << 13);
glintInfo->fbWriteModeSingleWriteStereo = 1 | (1 << 4) | (1 << 12) | (1 << 15);
glintInfo->fbWriteModeDualWriteStereo = 1 | (1 << 4) | (1 << 12) | (1 << 13) | (1 << 14) | (1 << 15);
if( glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_FRONT ) {
DISPDBG((7, "pxrxSetupDualWrites_Patching: Enabling front buffer patching"));
__RENDER2D_OP_PATCHORDER = __RENDER2D_OP_PATCHORDER_PATCHED;
glintInfo->fbWriteModeSingleWrite |= (1 << 16) | (1 << 18) | (1 << 20) | (1 << 22);
glintInfo->fbWriteModeDualWrite |= (1 << 16);
glintInfo->fbWriteModeSingleWriteStereo |= (1 << 16) | (1 << 18) | (1 << 20) | (1 << 22);
glintInfo->fbWriteModeDualWriteStereo |= (1 << 16) | (1 << 20);
}
bypass |= ppdev->cPelSize << 5;
if( ppdev->cxMemory <= 1024 )
bypass |= (0 << 7);
else if( ppdev->cxMemory <= 2048 )
bypass |= (1 << 7);
else if( ppdev->cxMemory <= 4096 )
bypass |= (2 << 7);
else if( ppdev->cxMemory <= 8192 )
bypass |= (3 << 7);
if( glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_BACK ) {
DISPDBG((7, "pxrxSetupDualWrites_Patching: Enabling back buffer patching"));
__RENDER2D_OP_PATCHORDER = __RENDER2D_OP_PATCHORDER_PATCHED;
glintInfo->fbWriteModeDualWrite |= (1 << 18);
glintInfo->fbWriteModeDualWriteStereo |= (1 << 18) | (1 << 22);
}
if( glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_FRONT ) {
if( glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_BACK ) {
// Patched front and back:
bypass |= (1 << 2);
// We need to do very odd things with a non power of 2 stride :-(.
// if( ppdev->cxMemory > 8192 )
if( ppdev->cxMemory != 1024 )
glintInfo->GdiCantAccessFramebuffer = TRUE; // bypass 'effective stride' is too big
} else {
// Patched front only:
glintInfo->GdiCantAccessFramebuffer = TRUE;
}
} else {
if( glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_BACK ) {
// Patched back only:
glintInfo->GdiCantAccessFramebuffer = TRUE;
} else {
// Linear front and back:
}
}
if( glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITE ) {
DISPDBG((7, "pxrxSetupDualWrites_Patching: Enabling dual writes"));
if( glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITE )
glintInfo->fbWriteMode = glintInfo->fbWriteModeDualWriteStereo;
else
glintInfo->fbWriteMode = glintInfo->fbWriteModeDualWrite;
glintInfo->pxrxFlags |= PXRX_FLAGS_DUAL_WRITING;
glintInfo->fbWriteOffset[1] = glintInfo->backBufferXY;
glintInfo->fbWriteOffset[2] = glintInfo->backRightBufferXY;
} else {
DISPDBG((7, "pxrxSetupDualWrites_Patching: Disabling dual writes"));
if( glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITE )
glintInfo->fbWriteMode = glintInfo->fbWriteModeSingleWriteStereo;
else
glintInfo->fbWriteMode = glintInfo->fbWriteModeSingleWrite;
glintInfo->pxrxFlags &= ~PXRX_FLAGS_DUAL_WRITING;
glintInfo->fbWriteOffset[1] = 0x00000000;
glintInfo->fbWriteOffset[2] = 0x00000000;
}
if( glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITE ) {
DISPDBG((7, "pxrxSetupDualWrites_Patching: Enabling stereo writes"));
glintInfo->pxrxFlags |= PXRX_FLAGS_STEREO_WRITING;
glintInfo->fbWriteOffset[3] = glintInfo->frontRightBufferXY;
}
else {
DISPDBG((7, "pxrxSetupDualWrites_Patching: Disabling stereo writes"));
glintInfo->pxrxFlags &= ~PXRX_FLAGS_STEREO_WRITING;
glintInfo->fbWriteOffset[3] = 0x00000000;
}
if( (glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITE) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITE) ) {
// Unfortunately, the bypass requires the back buffer to be aligned on a
// (power of 2) * 1MB boundary. So for the time being, just pretend we
// can't actually dual write through it.
// Also, we can't set the bypass up to read from the back buffer. So when
// OGL has page flipped so that the back buffer is now the current buffer
// any logic-ops will get source data from the wrong location :-(.
glintInfo->GdiCantAccessFramebuffer = TRUE;
/*{
ULONG size = (ppdev->cxMemory * (glintInfo->backBufferXY >> 16)) + (glintInfo->backBufferXY & 0xFFFF);
int i;
size <<= ppdev->cPelSize;
size >>= 20;
for( i = 0; i <= 7; i++ )
if( size & (1 << i) )
break;
if( i < 0 )
glintInfo->GdiCantAccessFramebuffer = TRUE;
else
bypass |= (i << 7);
}*/
}
//@@BEGIN_DDKSPLIT
// if( GLINT_P3R3 ) {
//@@END_DDKSPLIT
switch( ppdev->cPelSize ) {
case GLINTDEPTH32:
if( (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_FRONT) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_BACK) ) {
ppdev->pgfnFillSolid = p3r3FillSolidVariableSpans;
ppdev->pgfnFillPatColor = p3r3FillPatColorVariableSpans;
ppdev->pgfnFillPatMono = p3r3FillPatMonoVariableSpans;
} else {
ppdev->pgfnFillSolid = p3r3FillSolid32bpp;
ppdev->pgfnFillPatColor = p3r3FillPatColor32bpp;
ppdev->pgfnFillPatMono = p3r3FillPatMono32bpp;
}
break;
case GLINTDEPTH8:
if( (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_FRONT) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_BACK) ) {
ppdev->pgfnFillPatMono = p3r3FillPatMonoVariableSpans;
} else {
ppdev->pgfnFillPatMono = pxrxFillPatMono;
}
break;
}
//@@BEGIN_DDKSPLIT
// }
//@@END_DDKSPLIT
if( (glintInfo->pxrxFlags & (PXRX_FLAGS_PATCHING_FRONT | PXRX_FLAGS_PATCHING_BACK)) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITE) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITE) ||
glintInfo->GdiCantAccessFramebuffer ||
((ppdev->cPelSize != GLINTDEPTH16) && (ppdev->cPelSize != GLINTDEPTH32)) )
{
ppdev->pgfnCopyXfer8bppLge = pxrxCopyXfer8bppLge;
ppdev->pgfnCopyXfer8bpp = pxrxCopyXfer8bppLge;
} else {
ppdev->pgfnCopyXfer8bppLge = pxrxCopyXfer8bppLge;
ppdev->pgfnCopyXfer8bpp = vGlintCopyBltBypassDownloadXlate8bpp;
}
WRITE_GLINT_CTRL_REG( PXRXByAperture2Stride, ppdev->cxMemory );
WRITE_GLINT_CTRL_REG( PXRXByAperture2Mode, bypass );
glintInfo->pxrxByDMAReadMode = bypass;
if(ppdev->flCaps & CAPS_USE_AGP_DMA)
glintInfo->pxrxByDMAReadMode |= PXRX_BYPASS_READ_DMA_AGP_BIT;
WRITE_GLINT_CTRL_REG( PXRXByDMAReadMode, glintInfo->pxrxByDMAReadMode );
WRITE_GLINT_CTRL_REG( PXRXByDMAReadStride, ppdev->cxMemory );
DISPDBG((7, "pxrxSetupDualWrites_Patching exited"));
}
void pxrxRestore2DContext( PPDEV ppdev, BOOL switchingIn ) {
ULONG i, f, b;
ULONG enableFlags;
GLINT_DECL;
#if DBG
inPxRxContextSwitch = TRUE;
#endif
DISPDBG((7, "pxrxRestore2DContext entered"));
if( switchingIn ) {
// Switching in to 2D...
gi_pxrxDMA.NTbuff = 0;
gi_pxrxDMA.NTptr = gi_pxrxDMA.DMAaddrL[gi_pxrxDMA.NTbuff];
gi_pxrxDMA.P3at = gi_pxrxDMA.NTptr;
gi_pxrxDMA.NTdone = gi_pxrxDMA.NTptr;
#if PXRX_DMA_BUFFER_CHECK
glintInfo->NTwait = gi_pxrxDMA.NTptr;
#endif
CHECK_PXRX_DMA_VALIDITY( CHECK_SWITCH, 0 );
pxrxSetupDualWrites_Patching( ppdev );
DISPDBG((8, "pxrxRestore2DContext: restoring core registers"));
WAIT_PXRX_DMA_TAGS( NUM_P3_CTXT_TAGS );
for( i = 0; i < NUM_P3_CTXT_TAGS; i++ )
QUEUE_PXRX_DMA_TAG( DefaultContext_P3[i].tag, DefaultContext_P3[i].data );
if( glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITE ) {
f = (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_FRONT) ? 1 : 0;
b = (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_BACK ) ? 1 : 0;
} else
f = b = (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_FRONT) ? 1 : 0;
WAIT_PXRX_DMA_TAGS( 40 );
QUEUE_PXRX_DMA_TAG( __DeltaTagDeltaControl, (1 << 11) );
QUEUE_PXRX_DMA_TAG( __GlintTagPixelSize, 2 - ppdev->cPelSize ); // [0x018]
QUEUE_PXRX_DMA_TAG( __GlintTagForegroundColor, glintInfo->foregroundColour ); // [0x618]
QUEUE_PXRX_DMA_TAG( __GlintTagBackgroundColor, glintInfo->backgroundColour ); // [0x619]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferAddr0, glintInfo->fbDestAddr[0] ); // [0x5D0]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferAddr1, glintInfo->fbDestAddr[1] ); // [0x5D1]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferAddr2, glintInfo->fbDestAddr[2] ); // [0x5D2]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferAddr3, glintInfo->fbDestAddr[3] ); // [0x5D3]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferOffset0, glintInfo->fbDestOffset[0] ); // [0x5D4]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferOffset1, glintInfo->fbDestOffset[1] ); // [0x5D5]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferOffset2, glintInfo->fbDestOffset[2] ); // [0x5D6]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferOffset3, glintInfo->fbDestOffset[3] ); // [0x5D7]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferWidth0, glintInfo->fbDestWidth[0] ); // [0x5D8]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferWidth1, glintInfo->fbDestWidth[1] ); // [0x5D9]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferWidth2, glintInfo->fbDestWidth[2] ); // [0x5DA]
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadBufferWidth3, glintInfo->fbDestWidth[3] ); // [0x5DB]
QUEUE_PXRX_DMA_TAG( __GlintTagFBSourceReadBufferAddr, glintInfo->fbSourceAddr ); // [0x5E1]
QUEUE_PXRX_DMA_TAG( __GlintTagFBSourceReadBufferOffset, glintInfo->fbSourceOffset ); // [0x5E2]
QUEUE_PXRX_DMA_TAG( __GlintTagFBSourceReadBufferWidth, glintInfo->fbSourceWidth ); // [0x5E3]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferAddr0, glintInfo->fbWriteAddr[0] ); // [0x600]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferAddr1, glintInfo->fbWriteAddr[1] ); // [0x601]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferAddr2, glintInfo->fbWriteAddr[2] ); // [0x602]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferAddr3, glintInfo->fbWriteAddr[3] ); // [0x603]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferOffset0, glintInfo->fbWriteOffset[0] ); // [0x604]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferOffset1, glintInfo->fbWriteOffset[1] ); // [0x605]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferOffset2, glintInfo->fbWriteOffset[2] ); // [0x606]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferOffset3, glintInfo->fbWriteOffset[3] ); // [0x607]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferWidth0, glintInfo->fbWriteWidth[0] ); // [0x608]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferWidth1, glintInfo->fbWriteWidth[1] ); // [0x609]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferWidth2, glintInfo->fbWriteWidth[2] ); // [0x60A]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteBufferWidth3, glintInfo->fbWriteWidth[3] ); // [0x60B]
QUEUE_PXRX_DMA_TAG( __GlintTagFBWriteMode, glintInfo->fbWriteMode ); // [0x157]
QUEUE_PXRX_DMA_TAG( __GlintTagFBHardwareWriteMask, glintInfo->DefaultWriteMask ); // [0x158]
glintInfo->WriteMask = glintInfo->DefaultWriteMask;
QUEUE_PXRX_DMA_TAG( __GlintTagFBDestReadMode, glintInfo->fbDestMode); // [0x5DC]
QUEUE_PXRX_DMA_TAG( __GlintTagFBSourceReadMode, (1 << 0) | (1 << 1) | (f << 8) ); // [0x5E0]
QUEUE_PXRX_DMA_TAG( __GlintTagScreenSize, MAKEDWORD_XY(ppdev->cxScreen, ppdev->cyScreen) ); // [0x033]
QUEUE_PXRX_DMA_TAG( __GlintTagLUTMode, glintInfo->lutMode ); // [0x66F]
QUEUE_PXRX_DMA_TAG( __GlintTagConfig2D, glintInfo->config2D ); // [0x6C3]
SEND_PXRX_DMA_FORCE;
//wait for host in id to come out.
SYNC_WITH_GLINT;
// Invalidate some caches:
ppdev->PalLUTType = LUTCACHE_INVALID;
RtlZeroMemory( &ppdev->abeMono, sizeof(ppdev->abeMono) );
DISPDBG((7, "pxrxRestore2DContext: restoring control registers"));
if( (ppdev->sendPXRXdmaBatch != ppdev->sendPXRXdmaForce) && INTERRUPTS_ENABLED ) {
gi_pxrxDMA.scheme = glintInfo->usePXRXdma;
glintInfo->pInterruptCommandBlock->Control |= PXRX_SEND_ON_VBLANK_ENABLED;
READ_GLINT_CTRL_REG ( IntEnable, enableFlags );
WRITE_GLINT_CTRL_REG( IntEnable, enableFlags | INTR_ENABLE_VBLANK );
} else
gi_pxrxDMA.scheme = USE_PXRX_DMA_NONE;
} else {
// Switching out of 2D...
if( INTERRUPTS_ENABLED )
glintInfo->pInterruptCommandBlock->Control &= ~PXRX_SEND_ON_VBLANK_ENABLED;
}
#if DBG
inPxRxContextSwitch = FALSE;
#endif
DISPDBG((7, "pxrxRestore2DContext exited"));
}
VOID pxrxSetupFunctionPointers( PPDEV ppdev )
{
ULONG ul;
GLINT_DECL;
switch( glintInfo->usePXRXdma ) {
case USE_PXRX_DMA_FIFO:
ppdev->sendPXRXdmaForce = sendPXRXdmaFIFO;
ppdev->sendPXRXdmaQuery = sendPXRXdmaFIFO;
ppdev->sendPXRXdmaBatch = sendPXRXdmaFIFO;
ppdev->switchPXRXdmaBuffer = switchPXRXdmaBufferFIFO;
ppdev->waitPXRXdmaCompletedBuffer = waitPXRXdmaCompletedBufferFIFO;
break;
default:
DISPDBG((ERRLVL,"Unknown PXRX dma scheme!"));
}
if( !INTERRUPTS_ENABLED )
ppdev->sendPXRXdmaBatch = ppdev->sendPXRXdmaQuery = ppdev->sendPXRXdmaForce;
ppdev->pgfnCopyBltCopyROP = pxrxCopyBltNative;
ppdev->pgfnCopyBltNative = pxrxCopyBltNative;
ppdev->pgfnCopyBlt = pxrxCopyBltNative;
ppdev->pgfnFillSolid = pxrxFillSolid;
ppdev->pgfnFillPatMono = pxrxFillPatMono;
ppdev->pgfnFillPatColor = pxrxFillPatColor;
ppdev->pgfnXfer1bpp = pxrxXfer1bpp;
ppdev->pgfnXfer4bpp = pxrxXfer4bpp;
ppdev->pgfnXfer8bpp = pxrxXfer8bpp;
// ppdev->pgfnXfer16bpp = pxrxXfer16bpp;
// ppdev->pgfnXfer24bpp = pxrxXfer24bpp;
ppdev->pgfnXferImage = pxrxXferImage;
ppdev->pgfnMaskCopyBlt = pxrxMaskCopyBlt;
ppdev->pgfnPatRealize = pxrxPatRealize;
ppdev->pgfnMonoOffset = pxrxMonoOffset;
ppdev->pgfnFillPolygon = bGlintFastFillPolygon;
ppdev->pgfnDrawLine = pxrxDrawLine;
ppdev->pgfnIntegerLine = pxrxIntegerLine;
ppdev->pgfnContinueLine = pxrxContinueLine;
ppdev->pgfnInitStrips = pxrxInitStrips;
ppdev->pgfnResetStrips = pxrxResetStrips;
ppdev->pgfnRepNibbles = pxrxRepNibbles;
ppdev->pgfnUpload = pxrxFifoUpload;
// add any depth-specific function overrides here
switch( ppdev->cPelSize )
{
case GLINTDEPTH32:
ppdev->pgfnFillSolid = p3r3FillSolid32bpp;
ppdev->pgfnFillPatColor = p3r3FillPatColor32bpp;
ppdev->pgfnFillPatMono = p3r3FillPatMono32bpp;
break;
case GLINTDEPTH16:
// this specialization seems to give the same
// performance as the generic color pattern fill
//ppdev->pgfnFillPatColor = p3r3FillPatColor16bpp;
break;
case GLINTDEPTH8:
ppdev->pgfnFillSolid = p3r3FillSolidVariableSpans;
ppdev->pgfnFillPatColor = p3r3FillPatColorVariableSpans;
break;
}
ppdev->pgfnCopyXferImage = NULL;
ppdev->pgfnCopyXfer24bpp = pxrxCopyXfer24bpp;
ppdev->pgfnCopyXfer4bpp = NULL;
if( (glintInfo->pxrxFlags & (PXRX_FLAGS_PATCHING_FRONT | PXRX_FLAGS_PATCHING_BACK)) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITE) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITE) ||
glintInfo->GdiCantAccessFramebuffer ||
((ppdev->cPelSize != GLINTDEPTH16) && (ppdev->cPelSize !=
GLINTDEPTH32)) )
{
ppdev->pgfnCopyXfer8bppLge = pxrxCopyXfer8bppLge;
ppdev->pgfnCopyXfer8bpp = pxrxCopyXfer8bppLge;
} else {
ppdev->pgfnCopyXfer8bppLge = pxrxCopyXfer8bppLge;
ppdev->pgfnCopyXfer8bpp = vGlintCopyBltBypassDownloadXlate8bpp;
}
ppdev->gapfnStrip = &gapfnStripPXRX[0];
}
VOID pxrxCopyBltNative( PPDEV ppdev, RECTL *pRect, LONG count, DWORD logicOp, POINTL *pptlSrc, RECTL *pRectDst )
{
ULONG config2D, render2D;
int dx, dy;
GLINT_DECL;
DISPDBG((7, "pxrxCopyBltNative: (%d, %d) => (%d,%d -> %d,%d) x %d, logicOp = %d, offset = (%d, %d)",
pptlSrc->x, pptlSrc->y, pRectDst->left, pRectDst->top, pRectDst->right, pRectDst->bottom,
count, logicOp, ppdev->xyOffsetDst & 0xffff, ppdev->xyOffsetDst >> 16));
ASSERTDD(count > 0, "Can't handle zero rectangles");
ASSERTDD(logicOp <= 15, "Weird hardware Rop");
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 7 + 3 );
config2D = config2D_NativeBlt[logicOp];
render2D = render2D_NativeBlt[logicOp] | __RENDER2D_OP_PATCHORDER;
if( LogicopReadDest[logicOp] )
SET_READ_BUFFERS;
dx = pptlSrc->x - pRectDst->left;
dy = pptlSrc->y - pRectDst->top;
if(ppdev->DstPixelOrigin == ppdev->SrcPixelOrigin)
{
if( dy >= 0 )
render2D |= __RENDER2D_INCY;
if( dx >= 0 )
render2D |= __RENDER2D_INCX;
// source and dest are part of the same surface
if( (dy == 0) && (dx > -64) && (dx < 64) )
config2D |= __CONFIG2D_FBBLOCKING;
}
LOAD_FBSOURCE_ADDR( ppdev->SrcPixelOrigin );
LOAD_FBSOURCE_OFFSET_XY( dx + ppdev->xOffset, dy + (ppdev->xyOffsetSrc >> 16) );
LOAD_FBSOURCE_WIDTH( ppdev->SrcPixelDelta );
LOAD_CONFIG2D( config2D );
DISPDBG((8, "offset: (%d, %d) -> (%d, %d), d = (%d, %d), %cve X, %cve Y", pptlSrc->x, pptlSrc->y, pRectDst->left, pRectDst->top,
dx, dy, (render2D & __RENDER2D_INCX) ? '+' : '-', (render2D & __RENDER2D_INCY) ? '+' : '-'));
while( 1 ) {
render2D &= ~(__RENDER2D_WIDTH_MASK | __RENDER2D_HEIGHT_MASK);
render2D |= __RENDER2D_WIDTH(pRect->right - pRect->left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top);
DISPDBG((8, "dest rect: (%d, %d -> %d, %d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
QUEUE_PXRX_DMA_INDEX2( __GlintTagFillRectanglePosition, __GlintTagFillRender2D );
QUEUE_PXRX_DMA_DWORD( MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_DWORD( render2D );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
if( !(--count) )
break;
++pRect;
WAIT_PXRX_DMA_DWORDS( 3 );
}
SEND_PXRX_DMA_BATCH;
}
VOID pxrxFillSolid( PPDEV ppdev, LONG count, RECTL *pRect, ULONG logicOp, ULONG bgLogicOp, RBRUSH_COLOR rbc, POINTL *pptlBrush )
{
DWORD config2D, render2D;
ULONG ulColor = rbc.iSolidColor;
GLINT_DECL;
DISPDBG((7, "pxrxFillSolid: %d rects, logicOp = %d, colour = 0x%08X", count, logicOp, rbc.iSolidColor));
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 5 + 2 );
config2D = config2D_FillSolid[logicOp];
render2D = render2D_FillSolid[logicOp] | __RENDER2D_OP_PATCHORDER;
if( LogicopReadDest[logicOp] )
SET_READ_BUFFERS;
LOAD_FOREGROUNDCOLOUR( ulColor );
LOAD_CONFIG2D( config2D );
while( 1 ) {
DISPDBG((8, "rect: (%d, %d) to (%d, %d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
render2D &= ~(__RENDER2D_WIDTH_MASK | __RENDER2D_HEIGHT_MASK);
render2D |= __RENDER2D_WIDTH(pRect->right - pRect->left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top);
QUEUE_PXRX_DMA_TAG( __GlintTagRectanglePosition, MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_TAG( __GlintTagRender2D, render2D );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
if( !(--count) )
break;
++pRect;
WAIT_PXRX_DMA_TAGS( 2 );
}
SEND_PXRX_DMA_BATCH;
}
VOID p3r3FillSolidVariableSpans( PPDEV ppdev, LONG count, RECTL *pRect, ULONG logicOp, ULONG bgLogicOp, RBRUSH_COLOR rbc, POINTL *pptlBrush )
{
DWORD config2D, render2D;
ULONG ulColor = rbc.iSolidColor;
GLINT_DECL;
DISPDBG((7, "p3r3FillSolidVariableSpans: %d rects, logicOp = %d, colour = 0x%08X", count, logicOp, rbc.iSolidColor));
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 5 + 2 );
config2D = config2D_FillSolidVariableSpans[logicOp];
render2D = __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS | __RENDER2D_OP_PATCHORDER;
if( LogicopReadDest[logicOp] )
SET_READ_BUFFERS;
LOAD_FOREGROUNDCOLOUR( ulColor );
LOAD_CONFIG2D( config2D );
while( 1 ) {
DISPDBG((8, "rect: (%d, %d) to (%d, %d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
render2D &= ~(__RENDER2D_WIDTH_MASK | __RENDER2D_HEIGHT_MASK);
render2D |= __RENDER2D_WIDTH(pRect->right - pRect->left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top);
QUEUE_PXRX_DMA_TAG( __GlintTagRectanglePosition, MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_TAG( __GlintTagRender2D, render2D );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
if( !(--count) )
break;
++pRect;
WAIT_PXRX_DMA_TAGS( 2 );
}
SEND_PXRX_DMA_BATCH;
}
VOID p3r3FillSolid32bpp( PPDEV ppdev, LONG count, RECTL *pRect, ULONG logicOp, ULONG bgLogicOp, RBRUSH_COLOR rbc, POINTL *pptlBrush )
{
DWORD config2D, render2D;
ULONG ulColor = rbc.iSolidColor, left;
GLINT_DECL;
config2D = config2D_FillSolid32bpp[logicOp];
render2D = render2D_FillSolid[logicOp] | __RENDER2D_OP_PATCHORDER;
if(OFFSCREEN_LIN_DST(ppdev) && (config2D & __CONFIG2D_USERSCISSOR))
{
// When filling linear DFBs we can't use the scissor and align to a 32 pixel boundary in x because
// the coords aren't aligned to a scanline boundary in x. NB. Rectangular DFBs coords in x are always
// relative to the start of a scanline so the scissor alignment works.
p3r3FillSolidVariableSpans(ppdev, count, pRect, logicOp, bgLogicOp, rbc, pptlBrush);
return;
}
DISPDBG((7, "p3r3FillSolid32bpp: %d rects, logicOp = %d, colour = 0x%08X", count, logicOp, rbc.iSolidColor));
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 5 + 2 );
if( LogicopReadDest[logicOp] )
SET_READ_BUFFERS;
LOAD_FOREGROUNDCOLOUR( ulColor );
LOAD_CONFIG2D( config2D );
if( config2D & __CONFIG2D_USERSCISSOR ) {
while( 1 ) {
left = pRect->left & ~31;
DISPDBG((8, "rect: (%d:%d, %d) to (%d, %d)", pRect->left, left, pRect->top, pRect->right, pRect->bottom));
render2D &= ~(__RENDER2D_WIDTH_MASK | __RENDER2D_HEIGHT_MASK);
render2D |= __RENDER2D_WIDTH(pRect->right - left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top);
QUEUE_PXRX_DMA_INDEX3( __GlintTagFillScissorMinXY, __GlintTagFillRectanglePosition, __GlintTagFillRender2D );
QUEUE_PXRX_DMA_DWORD( MAKEDWORD_XY(pRect->left , 0) );
QUEUE_PXRX_DMA_DWORD( MAKEDWORD_XY(left, pRect->top) );
QUEUE_PXRX_DMA_DWORD( render2D );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
if( !(--count) )
break;
++pRect;
WAIT_PXRX_DMA_DWORDS( 5 );
}
} else {
while( 1 ) {
DISPDBG((8, "rect: (%d, %d) to (%d, %d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
render2D &= ~(__RENDER2D_WIDTH_MASK | __RENDER2D_HEIGHT_MASK);
render2D |= __RENDER2D_WIDTH(pRect->right - pRect->left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top);
QUEUE_PXRX_DMA_TAG( __GlintTagRectanglePosition, MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_TAG( __GlintTagRender2D, render2D );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
if( !(--count) )
break;
++pRect;
WAIT_PXRX_DMA_TAGS( 2 );
}
}
SEND_PXRX_DMA_BATCH;
}
VOID pxrxFillPatMono( PPDEV ppdev, LONG count, RECTL *pRect, ULONG fgLogicOp, ULONG bgLogicOp, RBRUSH_COLOR rbc, POINTL *pptlBrush )
{
BRUSHENTRY *pbe;
ULONG fgColor, bgColor;
DWORD config2D, render2D;
LONG c;
GLINT_DECL;
DISPDBG((7, "pxrxFillPatMono: %d rects. fgLogicOp = %d, bgLogicop %d", count, fgLogicOp, bgLogicOp));
// if anything has changed with the brush we must re-realize it. If the brush
// has been kicked out of the area stipple unit we must fully realize it. If
// only the alignment has changed we can simply update the alignment for the
// stipple.
//
pbe = rbc.prb->apbe;
if( (pbe == NULL) || (pbe->prbVerify != rbc.prb) ) {
DISPDBG((8, "full brush realise"));
(*ppdev->pgfnPatRealize)(ppdev, rbc.prb, pptlBrush);
}
else if( (rbc.prb->ptlBrushOrg.x != pptlBrush->x) ||
(rbc.prb->ptlBrushOrg.y != pptlBrush->y) ) {
DISPDBG((8, "changing brush offset"));
(*ppdev->pgfnMonoOffset)(ppdev, rbc.prb, pptlBrush);
}
fgColor = rbc.prb->ulForeColor;
bgColor = rbc.prb->ulBackColor;
DISPDBG((8, "fgColor 0x%x, bgColor 0x%x", fgColor, bgColor));
// we get some common operations which are really noops. we can save
// lots of time by cutting these out. As this happens a lot for masking
// operations it's worth doing.
if( ((fgLogicOp == __GLINT_LOGICOP_AND) && (fgColor == ppdev->ulWhite))
|| ((fgLogicOp == __GLINT_LOGICOP_OR ) && (fgColor == 0))
|| ((fgLogicOp == __GLINT_LOGICOP_XOR) && (fgColor == 0)) )
fgLogicOp = __GLINT_LOGICOP_NOOP;
// same for background
if( ((bgLogicOp == __GLINT_LOGICOP_AND) && (bgColor == ppdev->ulWhite))
|| ((bgLogicOp == __GLINT_LOGICOP_OR ) && (bgColor == 0))
|| ((bgLogicOp == __GLINT_LOGICOP_XOR) && (bgColor == 0)) )
bgLogicOp = __GLINT_LOGICOP_NOOP;
if( (fgLogicOp == __GLINT_LOGICOP_NOOP) && (bgLogicOp == __GLINT_LOGICOP_NOOP) ) {
DISPDBG((8, "both ops are no-op so lets quit now"));
return;
}
config2D = __CONFIG2D_CONSTANTSRC | __CONFIG2D_FBWRITE;
render2D = __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_AREASTIPPLE | __RENDER2D_OP_PATCHORDER;
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 9 + 2 );
if( (fgLogicOp != __GLINT_LOGICOP_COPY) || (bgLogicOp != __GLINT_LOGICOP_NOOP) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITING) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITING) ) {
config2D |= __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(fgLogicOp) | __CONFIG2D_LOGOP_BACK(bgLogicOp);
render2D |= __RENDER2D_SPANS;
} else {
LOAD_FBWRITE_ADDR( 1, ppdev->DstPixelOrigin );
LOAD_FBWRITE_WIDTH( 1, ppdev->DstPixelDelta );
LOAD_FBWRITE_OFFSET( 1, ppdev->xyOffsetDst );
}
if( LogicopReadDest[fgLogicOp] || LogicopReadDest[bgLogicOp] ) {
config2D |= __CONFIG2D_FBDESTREAD;
SET_READ_BUFFERS;
}
if( LogicOpReadSrc[fgLogicOp] )
LOAD_FOREGROUNDCOLOUR( fgColor );
if( LogicOpReadSrc[bgLogicOp] )
LOAD_BACKGROUNDCOLOUR( bgColor );
LOAD_CONFIG2D( config2D );
c = count;
while( TRUE ) {
DISPDBG((8, "mono pattern fill to rect (%d,%d) to (%d,%d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
QUEUE_PXRX_DMA_TAG( __GlintTagRectanglePosition, MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_TAG( __GlintTagRender2D, render2D | __RENDER2D_WIDTH(pRect->right - pRect->left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top) );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
if (--c == 0)
break;
pRect++;
WAIT_PXRX_DMA_TAGS( 2 );
}
SEND_PXRX_DMA_BATCH;
DISPDBG((7, "pxrxFillPatMono returning"));
}
VOID p3r3FillPatMonoVariableSpans( PPDEV ppdev, LONG count, RECTL *pRect, ULONG fgLogicOp, ULONG bgLogicOp, RBRUSH_COLOR rbc, POINTL *pptlBrush )
{
BRUSHENTRY *pbe;
ULONG fgColor, bgColor;
DWORD config2D, render2D;
LONG c;
GLINT_DECL;
DISPDBG((7, "p3r3FillPatMonoVariableSpans: %d rects. fgLogicOp = %d, bgLogicop %d", count, fgLogicOp, bgLogicOp));
// if anything has changed with the brush we must re-realize it. If the brush
// has been kicked out of the area stipple unit we must fully realize it. If
// only the alignment has changed we can simply update the alignment for the
// stipple.
//
pbe = rbc.prb->apbe;
if( (pbe == NULL) || (pbe->prbVerify != rbc.prb) ) {
DISPDBG((8, "full brush realise"));
(*ppdev->pgfnPatRealize)(ppdev, rbc.prb, pptlBrush);
}
else if( (rbc.prb->ptlBrushOrg.x != pptlBrush->x) ||
(rbc.prb->ptlBrushOrg.y != pptlBrush->y) ) {
DISPDBG((8, "changing brush offset"));
(*ppdev->pgfnMonoOffset)(ppdev, rbc.prb, pptlBrush);
}
fgColor = rbc.prb->ulForeColor;
bgColor = rbc.prb->ulBackColor;
DISPDBG((8, "fgColor 0x%x, bgColor 0x%x", fgColor, bgColor));
// we get some common operations which are really noops. we can save
// lots of time by cutting these out. As this happens a lot for masking
// operations it's worth doing.
if( ((fgLogicOp == __GLINT_LOGICOP_AND) && (fgColor == ppdev->ulWhite))
|| ((fgLogicOp == __GLINT_LOGICOP_OR ) && (fgColor == 0))
|| ((fgLogicOp == __GLINT_LOGICOP_XOR) && (fgColor == 0)) )
fgLogicOp = __GLINT_LOGICOP_NOOP;
// same for background
if( ((bgLogicOp == __GLINT_LOGICOP_AND) && (bgColor == ppdev->ulWhite))
|| ((bgLogicOp == __GLINT_LOGICOP_OR ) && (bgColor == 0))
|| ((bgLogicOp == __GLINT_LOGICOP_XOR) && (bgColor == 0)) )
bgLogicOp = __GLINT_LOGICOP_NOOP;
if( (fgLogicOp == __GLINT_LOGICOP_NOOP) && (bgLogicOp == __GLINT_LOGICOP_NOOP) ) {
DISPDBG((8, "both ops are no-op so lets quit now"));
return;
}
config2D = __CONFIG2D_CONSTANTSRC | __CONFIG2D_FBWRITE;
render2D = __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS | __RENDER2D_AREASTIPPLE | __RENDER2D_OP_PATCHORDER;
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 7 + 2 );
config2D |= __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(fgLogicOp) | __CONFIG2D_LOGOP_BACK(bgLogicOp);
if( LogicopReadDest[fgLogicOp] || LogicopReadDest[bgLogicOp] ) {
config2D |= __CONFIG2D_FBDESTREAD;
SET_READ_BUFFERS;
}
if( LogicOpReadSrc[fgLogicOp] )
LOAD_FOREGROUNDCOLOUR( fgColor );
if( LogicOpReadSrc[bgLogicOp] )
LOAD_BACKGROUNDCOLOUR( bgColor );
LOAD_CONFIG2D( config2D );
c = count;
while( TRUE ) {
DISPDBG((8, "mono pattern fill to rect (%d,%d) to (%d,%d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
QUEUE_PXRX_DMA_TAG( __GlintTagRectanglePosition, MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_TAG( __GlintTagRender2D, render2D | __RENDER2D_WIDTH(pRect->right - pRect->left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top) );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
if (--c == 0)
break;
pRect++;
WAIT_PXRX_DMA_TAGS( 2 );
}
SEND_PXRX_DMA_BATCH;
DISPDBG((7, "p3r3FillPatMonoVariableSpans returning"));
}
VOID p3r3FillPatMono32bpp( PPDEV ppdev, LONG count, RECTL *pRect, ULONG fgLogicOp, ULONG bgLogicOp, RBRUSH_COLOR rbc, POINTL *pptlBrush )
{
BRUSHENTRY *pbe;
ULONG fgColor, bgColor;
DWORD config2D, render2D;
LONG c, left;
GLINT_DECL;
DISPDBG((7, "p3r3FillPatMono32bpp: %d rects. fgLogicOp = %d, bgLogicop %d", count, fgLogicOp, bgLogicOp));
// if anything has changed with the brush we must re-realize it. If the brush
// has been kicked out of the area stipple unit we must fully realize it. If
// only the alignment has changed we can simply update the alignment for the
// stipple.
//
pbe = rbc.prb->apbe;
if( (pbe == NULL) || (pbe->prbVerify != rbc.prb) ) {
DISPDBG((8, "full brush realise"));
(*ppdev->pgfnPatRealize)(ppdev, rbc.prb, pptlBrush);
}
else if( (rbc.prb->ptlBrushOrg.x != pptlBrush->x) ||
(rbc.prb->ptlBrushOrg.y != pptlBrush->y) ) {
DISPDBG((8, "changing brush offset"));
(*ppdev->pgfnMonoOffset)(ppdev, rbc.prb, pptlBrush);
}
fgColor = rbc.prb->ulForeColor;
bgColor = rbc.prb->ulBackColor;
DISPDBG((8, "fgColor 0x%x, bgColor 0x%x", fgColor, bgColor));
// we get some common operations which are really noops. we can save
// lots of time by cutting these out. As this happens a lot for masking
// operations it's worth doing.
if( ((fgLogicOp == __GLINT_LOGICOP_AND) && (fgColor == ppdev->ulWhite))
|| ((fgLogicOp == __GLINT_LOGICOP_OR ) && (fgColor == 0))
|| ((fgLogicOp == __GLINT_LOGICOP_XOR) && (fgColor == 0)) )
fgLogicOp = __GLINT_LOGICOP_NOOP;
// same for background
if( ((bgLogicOp == __GLINT_LOGICOP_AND) && (bgColor == ppdev->ulWhite))
|| ((bgLogicOp == __GLINT_LOGICOP_OR ) && (bgColor == 0))
|| ((bgLogicOp == __GLINT_LOGICOP_XOR) && (bgColor == 0)) )
bgLogicOp = __GLINT_LOGICOP_NOOP;
if( (fgLogicOp == __GLINT_LOGICOP_NOOP) && (bgLogicOp == __GLINT_LOGICOP_NOOP) ) {
DISPDBG((8, "both ops are no-op so lets quit now"));
return;
}
config2D = __CONFIG2D_CONSTANTSRC | __CONFIG2D_FBWRITE;
render2D = __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_AREASTIPPLE | __RENDER2D_OP_PATCHORDER;
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 9 + 3 );
if( (fgLogicOp != __GLINT_LOGICOP_COPY) || (bgLogicOp != __GLINT_LOGICOP_NOOP) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITING) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITING) ||
OFFSCREEN_LIN_DST(ppdev)) {
config2D |= __CONFIG2D_OPAQUESPANS | __CONFIG2D_LOGOP_FORE(fgLogicOp) | __CONFIG2D_LOGOP_BACK(bgLogicOp);
render2D |= __RENDER2D_SPANS;
} else {
config2D |= __CONFIG2D_USERSCISSOR;
LOAD_FBWRITE_ADDR( 1, ppdev->DstPixelOrigin );
LOAD_FBWRITE_WIDTH( 1, ppdev->DstPixelDelta );
LOAD_FBWRITE_OFFSET( 1, ppdev->xyOffsetDst );
}
if( LogicopReadDest[fgLogicOp] || LogicopReadDest[bgLogicOp] ) {
config2D |= __CONFIG2D_FBDESTREAD;
SET_READ_BUFFERS;
}
if( LogicOpReadSrc[fgLogicOp] )
LOAD_FOREGROUNDCOLOUR( fgColor );
if( LogicOpReadSrc[bgLogicOp] )
LOAD_BACKGROUNDCOLOUR( bgColor );
LOAD_CONFIG2D( config2D );
c = count;
if( config2D & __CONFIG2D_USERSCISSOR ) {
while( TRUE ) {
left = pRect->left & ~31;
DISPDBG((8, "rect: (%d:%d, %d) to (%d, %d)", pRect->left, left, pRect->top, pRect->right, pRect->bottom));
QUEUE_PXRX_DMA_INDEX3( __GlintTagFillScissorMinXY, __GlintTagFillRectanglePosition, __GlintTagFillRender2D );
QUEUE_PXRX_DMA_DWORD( MAKEDWORD_XY(pRect->left , 0) );
QUEUE_PXRX_DMA_DWORD( MAKEDWORD_XY(left, pRect->top) );
QUEUE_PXRX_DMA_DWORD( render2D | __RENDER2D_WIDTH(pRect->right - left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top) );
if (--c == 0)
break;
pRect++;
WAIT_PXRX_DMA_DWORDS( 5 );
}
} else {
while( TRUE ) {
DISPDBG((8, "mono pattern fill to rect (%d,%d) to (%d,%d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
QUEUE_PXRX_DMA_TAG( __GlintTagRectanglePosition, MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_TAG( __GlintTagRender2D, render2D | __RENDER2D_WIDTH(pRect->right - pRect->left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top) );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
if (--c == 0)
break;
pRect++;
WAIT_PXRX_DMA_TAGS( 2 );
}
}
SEND_PXRX_DMA_BATCH;
DISPDBG((7, "p3r3FillPatMono32bpp returning"));
}
/*
8 Bpp:
orgmodeCopy = 3;
orgmodeLogic = 3;
lmodeCopy = (1 << 27);
lmodeLogic = (1 << 27);
15 Bpp:
16 Bpp:
32 Bpp:
orgmodeCopy = 1;
orgmodeLogic = 3;
lmodeCopy = (1 << 27);
lmodeLogic = (1 << 27);
ULONG orgmodeCopy = 1, orgmodeLogic = 3;
ULONG lmodeCopy = (1 << 27), lmodeLogic = (1 << 27);
ULONG orgmode;
ULONG lmode;
*/
VOID pxrxFillPatColor( PPDEV ppdev, LONG count, RECTL *pRect, ULONG logicOp, ULONG bgLogicOp, RBRUSH_COLOR rbc, POINTL *pptlBrush ) {
BRUSHENTRY *pbe;
DWORD config2D, render2D;
LONG index = 0, i;
ULONG *pulBrush;
ULONG cRows, cCols;
POINTL brushOrg;
GLINT_DECL;
DISPDBG((7, "pxrxFillPatColor: %d rects, logicOp = %d, brush = 0x%08X", count, logicOp, rbc.prb));
// Determine the brush origin:
brushOrg = *pptlBrush;
if( (logicOp == __GLINT_LOGICOP_COPY) && (ppdev->cPelSize != 0) )
brushOrg.x += (8 - (ppdev->xyOffsetDst & 0xFFFF)) & 7;
// If anything has changed with the brush we must re-realize it.
pbe = rbc.prb->apbe;
if( (ppdev->PalLUTType != LUTCACHE_BRUSH) || (pbe == NULL) || (pbe->prbVerify != rbc.prb) ) {
DISPDBG((8, "realising brush"));
(*ppdev->pgfnPatRealize)(ppdev, rbc.prb, &brushOrg);
} else
if( (rbc.prb->ptlBrushOrg.x != brushOrg.x) || (rbc.prb->ptlBrushOrg.y != brushOrg.y) ||
(rbc.prb->patternBase != ((glintInfo->lutMode >> 18) & 255)) ) {
ULONG lutMode = glintInfo->lutMode;
DISPDBG((8, "resetting LUTMode"));
rbc.prb->ptlBrushOrg.x = brushOrg.x;
rbc.prb->ptlBrushOrg.y = brushOrg.y;
DISPDBG((8, "setting new LUT brush origin to (%d, %d)", rbc.prb->ptlBrushOrg.x & 7, rbc.prb->ptlBrushOrg.y & 7));
lutMode &= ~((7 << 8) | (7 << 12) | (7 << 15) | (255 << 18) | (1 << 26) | (1 << 27));
lutMode |= (1 << 27) | (1 << 8) | (rbc.prb->patternBase << 18) |
(((8 - rbc.prb->ptlBrushOrg.x) & 7) << 12) | (((8 - rbc.prb->ptlBrushOrg.y) & 7) << 15);
WAIT_PXRX_DMA_TAGS( 1 );
LOAD_LUTMODE( lutMode );
} else {
// we're cached already!
DISPDBG((7, "pxrxFillPatColor: reusing LUT for brush @ %d, origin = (%d,%d)", rbc.prb->patternBase, rbc.prb->ptlBrushOrg.x & 7, rbc.prb->ptlBrushOrg.y & 7));
}
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 5 + 2 );
if( (glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITING) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITING) ) {
config2D = config2D_FillColourDual[logicOp];
render2D = __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS | __RENDER2D_OP_PATCHORDER; // render2D_FillSolidDual[logicOp]
if( LogicopReadDest[logicOp] )
SET_READ_BUFFERS;
} else {
config2D = config2D_FillColour[logicOp];
render2D = render2D_FillSolid[logicOp] | __RENDER2D_OP_PATCHORDER;
if( LogicopReadDest[logicOp] ) {
SET_READ_BUFFERS;
}
else if( logicOp == __GLINT_LOGICOP_COPY ) {
LOAD_FBWRITE_ADDR( 1, ppdev->DstPixelOrigin );
LOAD_FBWRITE_WIDTH( 1, ppdev->DstPixelDelta );
LOAD_FBWRITE_OFFSET( 1, ppdev->xyOffsetDst );
}
}
LOAD_CONFIG2D( config2D );
while( 1 ) {
DISPDBG((8, "rect: (%d, %d) to (%d, %d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
render2D &= ~(__RENDER2D_WIDTH_MASK | __RENDER2D_HEIGHT_MASK);
render2D |= __RENDER2D_WIDTH(pRect->right - pRect->left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top);
QUEUE_PXRX_DMA_TAG( __GlintTagRectanglePosition, MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_TAG( __GlintTagRender2D, render2D );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
WAIT_PXRX_DMA_TAGS( 2 );
if( !(--count) )
break;
++pRect;
}
// Invalidate the foreground/background colours 'cos the LUT has just corrupted them!
WAIT_PXRX_DMA_TAGS( 2 );
QUEUE_PXRX_DMA_TAG( __GlintTagForegroundColor, glintInfo->foregroundColour );
QUEUE_PXRX_DMA_TAG( __GlintTagBackgroundColor, glintInfo->backgroundColour );
SEND_PXRX_DMA_BATCH;
}
VOID p3r3FillPatColorVariableSpans( PPDEV ppdev, LONG count, RECTL *pRect, ULONG logicOp, ULONG bgLogicOp, RBRUSH_COLOR rbc, POINTL *pptlBrush ) {
BRUSHENTRY *pbe;
DWORD config2D, render2D;
LONG index = 0, i;
ULONG *pulBrush;
ULONG cRows, cCols;
POINTL brushOrg;
GLINT_DECL;
DISPDBG((7, "p3r3FillPatColorVariableSpans: %d rects, logicOp = %d, brush = 0x%08X", count, logicOp, rbc.prb));
// Determine the brush origin:
brushOrg = *pptlBrush;
if( (logicOp == __GLINT_LOGICOP_COPY) && (ppdev->cPelSize != 0) )
brushOrg.x += (8 - (ppdev->xyOffsetDst & 0xFFFF)) & 7;
// If anything has changed with the brush we must re-realize it.
pbe = rbc.prb->apbe;
if( (ppdev->PalLUTType != LUTCACHE_BRUSH) || (pbe == NULL) || (pbe->prbVerify != rbc.prb) ) {
DISPDBG((8, "realising brush"));
(*ppdev->pgfnPatRealize)(ppdev, rbc.prb, &brushOrg);
} else
if( (rbc.prb->ptlBrushOrg.x != brushOrg.x) || (rbc.prb->ptlBrushOrg.y != brushOrg.y) ||
(rbc.prb->patternBase != ((glintInfo->lutMode >> 18) & 255)) ) {
ULONG lutMode = glintInfo->lutMode;
DISPDBG((8, "resetting LUTMode"));
rbc.prb->ptlBrushOrg.x = brushOrg.x;
rbc.prb->ptlBrushOrg.y = brushOrg.y;
DISPDBG((8, "setting new LUT brush origin to (%d, %d)", rbc.prb->ptlBrushOrg.x & 7, rbc.prb->ptlBrushOrg.y & 7));
lutMode &= ~((7 << 8) | (7 << 12) | (7 << 15) | (255 << 18) | (1 << 26) | (1 << 27));
lutMode |= (1 << 27) | (1 << 8) | (rbc.prb->patternBase << 18) |
(((8 - rbc.prb->ptlBrushOrg.x) & 7) << 12) | (((8 - rbc.prb->ptlBrushOrg.y) & 7) << 15);
WAIT_PXRX_DMA_TAGS( 1 );
LOAD_LUTMODE( lutMode );
} else {
// we're cached already!
DISPDBG((7, "p3r3FillPatColorVariableSpans: reusing LUT for brush @ %d, origin = (%d,%d)", rbc.prb->patternBase, rbc.prb->ptlBrushOrg.x & 7, rbc.prb->ptlBrushOrg.y & 7));
}
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 5 + 2 );
config2D = config2D_FillColourDual[logicOp];
render2D = __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS | __RENDER2D_OP_PATCHORDER;
if( LogicopReadDest[logicOp] )
SET_READ_BUFFERS;
LOAD_CONFIG2D( config2D );
while( 1 ) {
DISPDBG((8, "rect: (%d, %d) to (%d, %d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
render2D &= ~(__RENDER2D_WIDTH_MASK | __RENDER2D_HEIGHT_MASK);
render2D |= __RENDER2D_WIDTH(pRect->right - pRect->left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top);
QUEUE_PXRX_DMA_TAG( __GlintTagRectanglePosition, MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_TAG( __GlintTagRender2D, render2D );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
WAIT_PXRX_DMA_TAGS( 2 );
if( !(--count) )
break;
++pRect;
}
// Invalidate the foreground/background colours 'cos the LUT has just corrupted them!
WAIT_PXRX_DMA_TAGS( 2 );
QUEUE_PXRX_DMA_TAG( __GlintTagForegroundColor, glintInfo->foregroundColour );
QUEUE_PXRX_DMA_TAG( __GlintTagBackgroundColor, glintInfo->backgroundColour );
SEND_PXRX_DMA_BATCH;
}
VOID pxrxCacheBrush16bpp(PDEV *ppdev, RBRUSH_COLOR rbc, POINTL *pbrushOrg)
{
BRUSHENTRY *pbe;
GLINT_DECL;
// If anything has changed with the brush we must re-realize it.
pbe = rbc.prb->apbe;
if( (ppdev->PalLUTType != LUTCACHE_BRUSH) || (pbe == NULL) || (pbe->prbVerify != rbc.prb) ) {
DISPDBG((8, "pxrxCacheBrush16bpp: realising brush"));
ppdev->pgfnPatRealize(ppdev, rbc.prb, pbrushOrg);
} else
if( (rbc.prb->ptlBrushOrg.x != pbrushOrg->x) || (rbc.prb->ptlBrushOrg.y != pbrushOrg->y) ||
(rbc.prb->patternBase != ((glintInfo->lutMode >> 18) & 255)) ) {
ULONG lutMode = glintInfo->lutMode;
DISPDBG((8, "pxrxCacheBrush16bpp: resetting LUTMode"));
rbc.prb->ptlBrushOrg.x = pbrushOrg->x;
rbc.prb->ptlBrushOrg.y = pbrushOrg->y;
DISPDBG((8, "pxrxCacheBrush16bpp: setting new LUT brush origin to (%d, %d)", rbc.prb->ptlBrushOrg.x & 7, rbc.prb->ptlBrushOrg.y & 7));
lutMode &= ~((7 << 8) | (7 << 12) | (7 << 15) | (255 << 18) | (1 << 26) | (1 << 27));
lutMode |= (1 << 27) | (1 << 8) | (rbc.prb->patternBase << 18) |
(((8 - rbc.prb->ptlBrushOrg.x) & 7) << 12) | (((8 - rbc.prb->ptlBrushOrg.y) & 7) << 15);
WAIT_PXRX_DMA_TAGS( 1 );
LOAD_LUTMODE( lutMode );
} else {
// we're cached already!
DISPDBG((7, "pxrxCacheBrush16bpp: reusing LUT for brush @ %d, origin = (%d,%d)", rbc.prb->patternBase, rbc.prb->ptlBrushOrg.x & 7, rbc.prb->ptlBrushOrg.y & 7));
}
}
VOID p3r3FillPatColor16bpp( PPDEV ppdev, LONG count, RECTL *pRect, ULONG logicOp, ULONG bgLogicOp, RBRUSH_COLOR rbc, POINTL *pptlBrush ) {
DWORD config2D, render2D;
LONG cx, cy, i;
POINTL brushOrg;
BOOL bCoreInitialized = FALSE;
BOOL bBypassInitialized = FALSE;
GLINT_DECL;
DISPDBG((7, "pxrxFillPatColor16bpp: %d rects, logicOp = %d, brush = 0x%08X", count, logicOp, rbc.prb));
// Determine the brush origin:
brushOrg = *pptlBrush;
if( (logicOp == __GLINT_LOGICOP_COPY) && (ppdev->cPelSize != 0) )
brushOrg.x += (8 - (ppdev->xyOffsetDst & 0xFFFF)) & 7;
while( 1 ) {
cx = pRect->right - pRect->left;
cy = pRect->bottom - pRect->top;
// render through core
if(!bCoreInitialized) {
pxrxCacheBrush16bpp(ppdev, rbc, &brushOrg);
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 5 + 2 );
if( (glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITING) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITING) ) {
config2D = config2D_FillColourDual[logicOp];
render2D = __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS | __RENDER2D_OP_PATCHORDER; // render2D_FillSolidDual[logicOp]
if( LogicopReadDest[logicOp] )
SET_READ_BUFFERS;
} else {
config2D = config2D_FillColour[logicOp];
render2D = render2D_FillSolid[logicOp] | __RENDER2D_OP_PATCHORDER;
if( LogicopReadDest[logicOp] ) {
SET_READ_BUFFERS;
}
else if( logicOp == __GLINT_LOGICOP_COPY ) {
LOAD_FBWRITE_ADDR( 1, ppdev->DstPixelOrigin );
LOAD_FBWRITE_WIDTH( 1, ppdev->DstPixelDelta );
LOAD_FBWRITE_OFFSET( 1, ppdev->xyOffsetDst );
}
}
LOAD_CONFIG2D( config2D );
bCoreInitialized = TRUE;
}
render2D &= ~(__RENDER2D_WIDTH_MASK | __RENDER2D_HEIGHT_MASK);
render2D |= __RENDER2D_WIDTH(pRect->right - pRect->left) | __RENDER2D_HEIGHT(pRect->bottom - pRect->top);
QUEUE_PXRX_DMA_TAG( __GlintTagRectanglePosition, MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_TAG( __GlintTagRender2D, render2D );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
WAIT_PXRX_DMA_TAGS( 2 );
if( !(--count) )
break;
++pRect;
}
// Invalidate the foreground/background colours 'cos the LUT has just corrupted them!
WAIT_PXRX_DMA_TAGS( 2 );
QUEUE_PXRX_DMA_TAG( __GlintTagForegroundColor, glintInfo->foregroundColour );
QUEUE_PXRX_DMA_TAG( __GlintTagBackgroundColor, glintInfo->backgroundColour );
SEND_PXRX_DMA_BATCH;
}
VOID pxrxCacheBrush32bpp(PDEV *ppdev, RBRUSH_COLOR rbc, POINTL *pbrushOrg)
{
BRUSHENTRY *pbe;
GLINT_DECL;
// If anything has changed with the brush we must re-realize it.
pbe = rbc.prb->apbe;
if( (ppdev->PalLUTType != LUTCACHE_BRUSH) || (pbe == NULL) || (pbe->prbVerify != rbc.prb) ) {
DISPDBG((8, "pxrxCacheBrush32bpp: realising brush"));
ppdev->pgfnPatRealize(ppdev, rbc.prb, pbrushOrg);
} else
if( (rbc.prb->ptlBrushOrg.x != pbrushOrg->x) || (rbc.prb->ptlBrushOrg.y != pbrushOrg->y) ||
(rbc.prb->patternBase != ((glintInfo->lutMode >> 18) & 255)) ) {
ULONG lutMode = glintInfo->lutMode;
DISPDBG((8, "pxrxCacheBrush32bpp: resetting LUTMode"));
rbc.prb->ptlBrushOrg.x = pbrushOrg->x;
rbc.prb->ptlBrushOrg.y = pbrushOrg->y;
DISPDBG((8, "pxrxCacheBrush32bpp: setting new LUT brush origin to (%d, %d)", rbc.prb->ptlBrushOrg.x & 7, rbc.prb->ptlBrushOrg.y & 7));
lutMode &= ~((7 << 8) | (7 << 12) | (7 << 15) | (255 << 18) | (1 << 26) | (1 << 27));
lutMode |= (1 << 27) | (1 << 8) | (rbc.prb->patternBase << 18) |
(((8 - rbc.prb->ptlBrushOrg.x) & 7) << 12) | (((8 - rbc.prb->ptlBrushOrg.y) & 7) << 15);
WAIT_PXRX_DMA_TAGS( 1 );
LOAD_LUTMODE( lutMode );
} else {
// we're cached already!
DISPDBG((7, "pxrxCacheBrush32bpp: reusing LUT for brush @ %d, origin = (%d, %d)", rbc.prb->patternBase, rbc.prb->ptlBrushOrg.x & 7, rbc.prb->ptlBrushOrg.y & 7));
}
}
VOID p3r3FillPatColor32bpp( PPDEV ppdev, LONG count, RECTL *pRect, ULONG logicOp, ULONG bgLogicOp, RBRUSH_COLOR rbc, POINTL *pptlBrush ) {
POINTL brushOrg;
DWORD config2D, render2D;
LONG cx, cy, i, left;
BOOL bCoreInitialized = FALSE;
BOOL bBypassInitialized = FALSE;
GLINT_DECL;
// Determine the brush origin:
brushOrg = *pptlBrush;
DISPDBG((7, "p3r3FillPatColor32bpp: %d rects, logicOp = %d, brush = 0x%08X", count, logicOp, rbc.prb));
while( 1 ) {
cx = pRect->right - pRect->left;
cy = pRect->bottom - pRect->top;
// render through core
if(!bCoreInitialized) {
pxrxCacheBrush32bpp(ppdev, rbc, &brushOrg);
SET_WRITE_BUFFERS;
WAIT_PXRX_DMA_TAGS( 5 + 2 );
if( (glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITING) ||
(glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITING) ||
OFFSCREEN_LIN_DST(ppdev)) {
config2D = config2D_FillColourDual[logicOp];
render2D = __RENDER2D_INCX | __RENDER2D_INCY | __RENDER2D_SPANS | __RENDER2D_OP_PATCHORDER; // render2D_FillSolidDual[logicOp]
if( LogicopReadDest[logicOp] )
SET_READ_BUFFERS;
} else {
config2D = config2D_FillColour32bpp[logicOp];
render2D = render2D_FillSolid[logicOp] | __RENDER2D_OP_PATCHORDER;
if( LogicopReadDest[logicOp] ) {
SET_READ_BUFFERS;
}
else if( logicOp == __GLINT_LOGICOP_COPY ) {
LOAD_FBWRITE_ADDR( 1, ppdev->DstPixelOrigin );
LOAD_FBWRITE_WIDTH( 1, ppdev->DstPixelDelta );
LOAD_FBWRITE_OFFSET( 1, ppdev->xyOffsetDst );
}
}
LOAD_CONFIG2D( config2D );
bCoreInitialized = TRUE;
if( config2D & __CONFIG2D_USERSCISSOR ) {
left = pRect->left & ~31;
DISPDBG((8, "p3r3FillPatColor32bpp: scissor core fill (%d:%d, %d) to (%d, %d)", pRect->left, left, pRect->top, pRect->right, pRect->bottom));
render2D &= ~(__RENDER2D_WIDTH_MASK | __RENDER2D_HEIGHT_MASK);
render2D |= __RENDER2D_WIDTH(pRect->right - left) | __RENDER2D_HEIGHT(cy);
QUEUE_PXRX_DMA_INDEX3( __GlintTagFillScissorMinXY, __GlintTagFillRectanglePosition, __GlintTagFillRender2D );
QUEUE_PXRX_DMA_DWORD( MAKEDWORD_XY(pRect->left , 0) );
QUEUE_PXRX_DMA_DWORD( MAKEDWORD_XY(left, pRect->top) );
QUEUE_PXRX_DMA_DWORD( render2D );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
WAIT_PXRX_DMA_DWORDS( 5 );
} else {
DISPDBG((8, "p3r3FillPatColor32bpp: core fill (%d, %d) to (%d, %d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
render2D &= ~(__RENDER2D_WIDTH_MASK | __RENDER2D_HEIGHT_MASK);
render2D |= __RENDER2D_WIDTH(cx) | __RENDER2D_HEIGHT(cy);
QUEUE_PXRX_DMA_TAG( __GlintTagRectanglePosition, MAKEDWORD_XY(pRect->left, pRect->top) );
QUEUE_PXRX_DMA_TAG( __GlintTagRender2D, render2D );
FLUSH_PXRX_PATCHED_RENDER2D(pRect->left, pRect->right);
WAIT_PXRX_DMA_TAGS( 2 );
}
}
if( !(--count) )
break;
++pRect;
}
// Invalidate the foreground/background colours 'cos the LUT has just corrupted them!
WAIT_PXRX_DMA_TAGS( 2 );
QUEUE_PXRX_DMA_TAG( __GlintTagForegroundColor, glintInfo->foregroundColour );
QUEUE_PXRX_DMA_TAG( __GlintTagBackgroundColor, glintInfo->backgroundColour );
SEND_PXRX_DMA_BATCH;
}
VOID pxrxMaskCopyBlt( PPDEV ppdev, RECTL *a, LONG b, SURFOBJ *c, POINTL *d, ULONG e, ULONG f, POINTL *g, RECTL *h ) {
DISPDBG((ERRLVL,"pxrxMaskCopyBlt was called"));
}
VOID pxrxPatRealize( PPDEV ppdev, RBRUSH *prb, POINTL *pptlBrush )
{
BRUSHENTRY *pbe;
LONG iBrushCache;
LONG i;
DWORD *pSrc;
GLINT_DECL;
DISPDBG((7, "pxrxPatRealize started"));
pbe = prb->apbe;
if( prb->fl & RBRUSH_2COLOR ) {
if( (pbe == NULL) || (pbe->prbVerify != prb) ) {
// mono brushes are realized into the area stipple unit. For this we
// have a set of special BRUSHENTRYs, one for each board.
DISPDBG((8, "loading mono brush into cache"));
pbe = &ppdev->abeMono;
pbe->prbVerify = prb;
prb->apbe = pbe;
}
} else {
if( ppdev->PalLUTType != LUTCACHE_BRUSH ) {
// Someone has hijacked the LUT so we need to invalidate it:
ppdev->PalLUTType = LUTCACHE_BRUSH;
for( i = 0; i < MAX_P3_BRUSHES; i++ )
ppdev->abeP3[i].prbVerify = NULL;
}
if( (pbe == NULL) || (pbe->prbVerify != prb) ) {
// colourbrushes are realized into the LUT unit table.
DISPDBG((8, "loading colour brush into cache"));
iBrushCache = ppdev->iBrushCacheP3;
pbe = &ppdev->abeP3[iBrushCache];
// Update our links:
pbe->prbVerify = prb;
prb->apbe = pbe;
prb->patternBase = iBrushCache * (256 / MAX_P3_BRUSHES); // Should be related to colour depth ???
DISPDBG((8, "new cache entry allocated for color brush @ entry %d", prb->patternBase));
iBrushCache++;
if( iBrushCache >= MAX_P3_BRUSHES )
iBrushCache = 0;
ppdev->iBrushCacheP3 = iBrushCache;
}
}
pSrc = &prb->aulPattern[0];
// we're going to load mono patterns into the area stipple and set the
// start offset to the brush origin. WARNING: we assume that we are
// running little endian. I believe this is always true for NT.
if( prb->fl & RBRUSH_2COLOR ) {
// this function loads the stipple offset into the hardware. We also call
// this function on its own if the brush is realized but its offset changes.
// In that case we don't have to go through a complete realize again.
(*ppdev->pgfnMonoOffset)(ppdev, prb, pptlBrush);
DISPDBG((8, "area stipple pattern:"));
WAIT_PXRX_DMA_DWORDS( 9 );
QUEUE_PXRX_DMA_INC( __GlintTagAreaStipplePattern0, 8 );
QUEUE_PXRX_DMA_BUFF( pSrc, 8 );
SEND_PXRX_DMA_BATCH;
//for( i = 0; i < 8; ++i, ++pSrc ) {
// DISPDBG((8, "\t0x%08x", *pSrc));
//}
DISPDBG((7, "area stipple downloaded. pxrxPatRealize done"));
return;
} else {
ULONG lutMode;
prb->ptlBrushOrg.x = pptlBrush->x;
prb->ptlBrushOrg.y = pptlBrush->y;
lutMode = (1 << 27) | (1 << 8) | (prb->patternBase << 18) | // SpanOp = 8x8 brush, pattern base, x-offset, y-offset
(((8 - prb->ptlBrushOrg.x) & 7) << 12) | (((8 - prb->ptlBrushOrg.y) & 7) << 15);
DISPDBG((8, "setting new LUT brush origin to (%d, %d) @ %d", prb->ptlBrushOrg.x & 7, prb->ptlBrushOrg.y & 7, prb->patternBase));
switch( ppdev->cPelSize ) {
case 0: // 8 bpp
DISPDBG((8, "LUT pattern (8bpp, 8x8):"));
WAIT_PXRX_DMA_DWORDS( 4 + 17 );
LOAD_LUTMODE( lutMode );
QUEUE_PXRX_DMA_TAG( __PXRXTagLUTIndex, prb->patternBase );
QUEUE_PXRX_DMA_HOLD( __PXRXTagLUTData, 8 * 2 );
QUEUE_PXRX_DMA_BUFF( pSrc, 8 * 2 );
//for( i = 0; i < 8; ++i ) {
// DISPDBG((8, "\t0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x",
// pSrc[0] & 0xFF, (pSrc[0] >> 8) & 0xFF, (pSrc[0] >> 16) & 0xFF, (pSrc[0] >> 24) & 0xFF,
// pSrc[1] & 0xFF, (pSrc[1] >> 8) & 0xFF, (pSrc[2] >> 16) & 0xFF, (pSrc[3] >> 24) & 0xFF));
// pSrc += 2;
//}
SEND_PXRX_DMA_BATCH;
DISPDBG((7, "LUT downloaded. pxrxPatRealize done"));
return;
case 1: // 16 bpp
DISPDBG((8, "LUT pattern (16bpp, 8x8):"));
WAIT_PXRX_DMA_DWORDS( 4 + 33 );
LOAD_LUTMODE( lutMode );
QUEUE_PXRX_DMA_TAG( __PXRXTagLUTIndex, prb->patternBase );
QUEUE_PXRX_DMA_HOLD( __PXRXTagLUTData, 8 * 4 );
QUEUE_PXRX_DMA_BUFF( pSrc, 8 * 4 );
//for( i = 0; i < 8; ++i ) {
// DISPDBG((8, "\t0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x",
// pSrc[0] & 0xFFFF, pSrc[0] >> 16, pSrc[1] & 0xFFFF, pSrc[1] >> 16,
// pSrc[2] & 0xFFFF, pSrc[2] >> 16, pSrc[3] & 0xFFFF, pSrc[3] >> 16));
// pSrc += 4;
//}
SEND_PXRX_DMA_BATCH;
DISPDBG((7, "LUT downloaded. pxrxPatRealize done"));
return;
case 2: // 32 bpp
DISPDBG((8, "LUT pattern (32bpp, 8x8):"));
WAIT_PXRX_DMA_DWORDS( 4 + 65 );
LOAD_LUTMODE( lutMode );
QUEUE_PXRX_DMA_TAG( __PXRXTagLUTIndex, prb->patternBase );
QUEUE_PXRX_DMA_HOLD( __PXRXTagLUTData, 8 * 8 );
QUEUE_PXRX_DMA_BUFF( pSrc, 8 * 8 );
//for( i = 0; i < 8; ++i ) {
// DISPDBG((8, "\t0x%06x, 0x%06x, 0x%06x, 0x%06x, 0x%06x, 0x%06x, 0x%06x, 0x%06x",
// pSrc[0], pSrc[1], pSrc[2], pSrc[3], pSrc[4], pSrc[5], pSrc[6], pSrc[7]));
// pSrc += 8;
//}
SEND_PXRX_DMA_BATCH;
DISPDBG((7, "LUT downloaded. pxrxPatRealize done"));
return;
}
}
DISPDBG((-1, "pxrxPatRealize: Failed to realize brush!"));
}
VOID pxrxMonoOffset( PPDEV ppdev, RBRUSH *prb, POINTL *pptlBrush )
{
DWORD mode;
GLINT_DECL;
DISPDBG((7, "pxrxMonoOffset started"));
// construct the AreaStippleMode value. It contains the pattern size,
// the offset for the brush origin and the enable bit. Remember the
// offset so we can later check if it changes and update the hardware.
// Remember the mode so we can do a mirrored stipple easily.
prb->ptlBrushOrg.x = pptlBrush->x;
prb->ptlBrushOrg.y = pptlBrush->y;
mode = __PERMEDIA_ENABLE |
AREA_STIPPLE_XSEL(__GLINT_AREA_STIPPLE_32_PIXEL_PATTERN) |
AREA_STIPPLE_YSEL(__GLINT_AREA_STIPPLE_8_PIXEL_PATTERN) |
AREA_STIPPLE_MIRROR_X |
AREA_STIPPLE_XOFF(8 - (prb->ptlBrushOrg.x & 7)) |
AREA_STIPPLE_YOFF(8 - (prb->ptlBrushOrg.y & 7));
if( glintInfo->config2D & __CONFIG2D_OPAQUESPANS )
mode |= (1 << 20);
prb->areaStippleMode = mode;
DISPDBG((8, "setting new area stipple offset to %d, %d",
8 - (prb->ptlBrushOrg.x & 7),
8 - (prb->ptlBrushOrg.y & 7)));
WAIT_PXRX_DMA_TAGS( 1 );
QUEUE_PXRX_DMA_TAG( __GlintTagAreaStippleMode, mode );
// SEND_PXRX_DMA_BATCH;
DISPDBG((7, "pxrxMonoOffset done"));
}
VOID pxrxRepNibbles( PPDEV ppdev, RECTL *a, CLIPOBJ *b ) {
DISPDBG((ERRLVL,"pxrxRepNibbles was called"));
}
#if PXRX_DMA_BUFFER_CHECK
void checkPXRXdmaValidBuffer( PPDEV ppdev, GlintDataPtr glintInfo, ULONG type, ULONG count ) {
ULONG *ptr, origCount = count, failure = FALSE;
if(!inPxRxContextSwitch && (*ppdev->pCurrentCtxt != glintInfo->ddCtxtId))
{
DISPDBG((-1000, "CHECK_PXRX_DMA_VALIDITY: ERROR - not in 2D context!!!" ));
return;
}
ASSERTDD( (gi_pxrxDMA.NTbuff == 0) || (gi_pxrxDMA.NTbuff == 1), "CHECK_PXRX_DMA_VALIDITY failed for NTbuff!");
/*
0k - 16k = 16k = protection zone 0 pxrxDMA.bufferBase
16k - 56k = 40k = buffer 0 (40k) gi_pxrxDMA.DMAaddrL[0]
56k - 72k = 16k = protection zone 1 gi_pxrxDMA.DMAaddrEndL[0]
72k - 112k = 40k = buffer 1 gi_pxrxDMA.DMAaddrL[1]
112k - 128k = 16k = protection zone 2 gi_pxrxDMA.DMAaddrEndL[1]
pxrxDMA.bufferTop
*/
// DISPDBG((-1, "0x%08X - 0x%08X = 0x%08X ?=? 0x%08X", gi_pxrxDMA.DMAaddrL[0], pxrxDMA_bufferBase , (gi_pxrxDMA.DMAaddrL[0] - pxrxDMA_bufferBase ), PXRX_DMA_BUFFER_CHECK_SIZE));
// DISPDBG((-1, "0x%08X - 0x%08X = 0x%08X ?=? 0x%08X", gi_pxrxDMA.DMAaddrL[1], gi_pxrxDMA.DMAaddrEndL[0], (gi_pxrxDMA.DMAaddrL[1] - gi_pxrxDMA.DMAaddrEndL[0]), PXRX_DMA_BUFFER_CHECK_SIZE));
// DISPDBG((-1, "0x%08X - 0x%08X = 0x%08X ?=? 0x%08X", pxrxDMA_bufferTop , gi_pxrxDMA.DMAaddrEndL[1], ( pxrxDMA_bufferTop - gi_pxrxDMA.DMAaddrEndL[1]), PXRX_DMA_BUFFER_CHECK_SIZE));
// start0 - base == bufferSize
if( (gi_pxrxDMA.DMAaddrL[0] - glintInfo->pxrxDMA_bufferBase) != (PXRX_DMA_BUFFER_CHECK_SIZE) ) {
DISPDBG((-1000, "CHECK_BUFF failed on protection zone 0's size! (%d vs %d)",
gi_pxrxDMA.DMAaddrL[0] - glintInfo->pxrxDMA_bufferBase, PXRX_DMA_BUFFER_CHECK_SIZE));
DebugBreak();
}
// start1 - end0 == bufferSize
if( (gi_pxrxDMA.DMAaddrL[1] - gi_pxrxDMA.DMAaddrEndL[0]) != (PXRX_DMA_BUFFER_CHECK_SIZE) ) {
DISPDBG((-1000, "CHECK_BUFF failed on protection zone 1's size! (%d vs %d)",
gi_pxrxDMA.DMAaddrL[1] - gi_pxrxDMA.DMAaddrEndL[0], PXRX_DMA_BUFFER_CHECK_SIZE));
DebugBreak();
}
// top - end1 == bufferSize
if( (glintInfo->pxrxDMA_bufferTop - gi_pxrxDMA.DMAaddrEndL[1]) != (PXRX_DMA_BUFFER_CHECK_SIZE) ) {
DISPDBG((-1000, "CHECK_BUFF failed on protection zone 2's size! (%d vs %d)",
glintInfo->pxrxDMA_bufferTop - gi_pxrxDMA.DMAaddrEndL[1], PXRX_DMA_BUFFER_CHECK_SIZE));
DebugBreak();
}
// end0 - start0 == end1 - start1
if( (gi_pxrxDMA.DMAaddrEndL[0] - gi_pxrxDMA.DMAaddrL[0]) != (gi_pxrxDMA.DMAaddrEndL[1] - gi_pxrxDMA.DMAaddrL[1]) ) {
DISPDBG((-1000, "CHECK_BUFF failed on buffer sizes! (%d vs %d)",
gi_pxrxDMA.DMAaddrEndL[0] - gi_pxrxDMA.DMAaddrL[0], gi_pxrxDMA.DMAaddrEndL[1] - gi_pxrxDMA.DMAaddrL[1]));
DebugBreak();
}
// (start0 <= NTptr <= end0) || (start1 <= NTptr <= end1)
if( ((gi_pxrxDMA.NTptr < gi_pxrxDMA.DMAaddrL[0]) || (gi_pxrxDMA.NTptr > gi_pxrxDMA.DMAaddrEndL[0])) &&
((gi_pxrxDMA.NTptr < gi_pxrxDMA.DMAaddrL[1]) || (gi_pxrxDMA.NTptr > gi_pxrxDMA.DMAaddrEndL[1])) ) {
DISPDBG((-1000, "CHECK_BUFF failed for NTptr!"));
DISPDBG((-1000, " 0x%08X: (0x%08X:0x%08X) or (0x%08X:0x%08X)", gi_pxrxDMA.NTptr,
gi_pxrxDMA.DMAaddrL[0], gi_pxrxDMA.DMAaddrEndL[0],
gi_pxrxDMA.DMAaddrL[1], gi_pxrxDMA.DMAaddrEndL[1]));
DebugBreak();
} else {
// startCurrent <= NTptr <= endCurrent
if( (gi_pxrxDMA.NTptr < gi_pxrxDMA.DMAaddrL[gi_pxrxDMA.NTbuff]) ||
(gi_pxrxDMA.NTptr > gi_pxrxDMA.DMAaddrEndL[gi_pxrxDMA.NTbuff]) ) {
DISPDBG((-1000, "CHECK_BUFF failed for NTptr II!"));
DISPDBG((-1000, " 0x%08X <= 0x%08X <= 0x%08X",
gi_pxrxDMA.DMAaddrL[gi_pxrxDMA.NTbuff], gi_pxrxDMA.NTptr,
gi_pxrxDMA.DMAaddrEndL[gi_pxrxDMA.NTbuff]));
DebugBreak();
}
}
// (start0 <= P3ptr <= end0) || (start1 <= P3ptr <= end1)
if( ((gi_pxrxDMA.P3at < gi_pxrxDMA.DMAaddrL[0]) && (gi_pxrxDMA.P3at > gi_pxrxDMA.DMAaddrEndL[0])) &&
((gi_pxrxDMA.P3at < gi_pxrxDMA.DMAaddrL[1]) && (gi_pxrxDMA.P3at > gi_pxrxDMA.DMAaddrEndL[1])) ) {
DISPDBG((-1000, "CHECK_BUFF failed for P3at!"));
DISPDBG((-1000, " 0x%08X: (0x%08X:0x%08X) or (0x%08X:0x%08X)", gi_pxrxDMA.P3at,
gi_pxrxDMA.DMAaddrL[0], gi_pxrxDMA.DMAaddrEndL[0],
gi_pxrxDMA.DMAaddrL[1], gi_pxrxDMA.DMAaddrEndL[1]));
DebugBreak();
}
// P3at <= NTptr (if in the same buffer)
if( (gi_pxrxDMA.P3at >= gi_pxrxDMA.DMAaddrL[gi_pxrxDMA.NTbuff]) && (gi_pxrxDMA.P3at <= gi_pxrxDMA.DMAaddrEndL[gi_pxrxDMA.NTbuff]) ) {
if( gi_pxrxDMA.P3at > gi_pxrxDMA.NTptr ) {
DISPDBG((-1000, "CHECK_BUFF failed for P3at vs NTptr! (0x%08X <= 0x%08X)", gi_pxrxDMA.P3at, gi_pxrxDMA.NTptr));
DebugBreak();
}
}
// NTptr <= NTwait
if( gi_pxrxDMA.NTptr > glintInfo->NTwait ) {
DISPDBG((-1000, "CHECK_BUFF failed for NTptr vs NTwait! (0x%08X <= 0x%08X)", gi_pxrxDMA.NTptr, glintInfo->NTwait));
DebugBreak();
}
//@@BEGIN_DDKSPLIT
//AZN
// Here we have a FI AV when glintInfo->pxrxDMA_bufferBase != NULL but points
// to invalid memory!
//@@END_DDKSPLIT
// Protection zone 0: should be filled with (addr & 0x0FFFFFF0)
for( ptr = glintInfo->pxrxDMA_bufferBase; ptr < gi_pxrxDMA.DMAaddrL[0]; ptr++ ) {
ASSERTDBG(*ptr == (((ULONG_PTR) ptr) & 0x0FFFFFF0), (-1000,
"CHECK_BUFF failed on protection zone 0: 0x%08X vs 0x%08X!",
((ULONG_PTR) ptr) & 0x0FFFFFF0, *ptr));
//if( ptr > glintInfo->pxrxDMA_bufferBase + 40 ) break;
}
// Protection zone 1: should be filled with (addr & 0x0FFFFFF0)
for( ptr = gi_pxrxDMA.DMAaddrEndL[0]; ptr < gi_pxrxDMA.DMAaddrL[1]; ptr++ ) {
ASSERTDBG(*ptr == (((ULONG_PTR) ptr) & 0x0FFFFFF0), (-1000,
"CHECK_BUFF failed on protection zone 1: 0x%08X vs 0x%08X!",
((ULONG_PTR) ptr) & 0x0FFFFFF0, *ptr));
//if( ptr > gi_pxrxDMA.DMAaddrEndL[0] + 40 ) break;
}
// Protection zone 2: should be filled with (addr & 0x0FFFFFF0)
for( ptr = gi_pxrxDMA.DMAaddrEndL[1]; ptr < glintInfo->pxrxDMA_bufferTop; ptr++ ) {
ASSERTDBG(*ptr == (((ULONG_PTR) ptr) & 0x0FFFFFF0), (-1000,
"CHECK_BUFF failed on protection zone 2: 0x%08X vs 0x%08X!",
((ULONG_PTR) ptr) & 0x0FFFFFF0, *ptr));
//if( ptr > gi_pxrxDMA.DMAaddrEndL[1] + 40 ) break;
}
switch( type ) {
case CHECK_QUEUE:
// Check that each dword contains 0x12345678:
while( count-- ) {
ptr = gi_pxrxDMA.NTptr + count;
if( *ptr != 0x12345678 ) {
DISPDBG((-1000, "CHECK_QUEUE failed: 0x%08X vs 0x12345678 @ 0x%08X!", *ptr, ptr));
failure = TRUE;
}
}
break;
case CHECK_WAIT:
// Check that each dword contains its address...
// Then replace it with 0x12345678:
while( count-- ) {
ptr = gi_pxrxDMA.NTptr + count;
if( (*ptr != (ULONG_PTR) ptr) && (*ptr != 0x12345678) ) {
DISPDBG((-1000, "CHECK_WAIT failed: 0x%08X vs 0x%08X @ 0x%08X!",
*ptr, (ULONG_PTR) ptr, ptr));
failure = TRUE;
}
*ptr = 0x12345678;
}
break;
case CHECK_SEND:
// Check that each dword contains neither its address nor 0x12345678:
for( ptr = (ULONG *) gi_pxrxDMA.P3at; ptr < gi_pxrxDMA.NTptr; ptr++ ) {
if( *ptr == (ULONG_PTR) ptr ) {
DISPDBG((-1000, "CHECK_SEND failed I: 0x%08X is 0x%08X!", ptr, *ptr));
failure = TRUE;
}
if( *ptr == 0x12345678 ) {
DISPDBG((-1000, "CHECK_SEND failed II: 0x%08X is 0x%08X!", ptr, *ptr));
failure = TRUE;
}
}
for( ptr = gi_pxrxDMA.NTptr; ptr < gi_pxrxDMA.DMAaddrEndL[gi_pxrxDMA.NTbuff]; ptr++ ) {
if( (*ptr != (ULONG_PTR) ptr) && (*ptr != 0x12345678) ) {
DISPDBG((-1000, "CHECK_SEND failed III: 0x%08X vs 0x%08X/0x12345678 @ 0x%08X!", *ptr,
(ULONG_PTR) ptr, ptr));
failure = TRUE;
}
if( ptr > (gi_pxrxDMA.NTptr + 4) )
break;
}
break;
case CHECK_SWITCH:
// Fill each dword with its address:
for( ptr = gi_pxrxDMA.DMAaddrL[gi_pxrxDMA.NTbuff]; ptr < gi_pxrxDMA.DMAaddrEndL[gi_pxrxDMA.NTbuff]; ptr++ )
*ptr = PtrToUlong(ptr);
break;
}
if( failure ) {
DISPDBG((-1000, "Check failed, count = %d", origCount));
DebugBreak();
}
}
#endif
/*******************************************************/
/*** Assorted versions of the SEND_PXRX_DMA 'macro' ***/
/*** For use with the FAKE_DMA flag to test that DMA ***/
/*** will actually work on all combinations of P3, ***/
/*** Gamma, & buggy motherboards! ***/
/*******************************************************/
/*******************/
/*** FIFO Access ***/
void sendPXRXdmaFIFO( PPDEV ppdev, GlintDataPtr glintInfo ) {
LONG count;
ULONG *NTptr = gi_pxrxDMA.NTptr;
ULONG *P3at = (ULONG *) gi_pxrxDMA.P3at;
CHECK_PXRX_DMA_VALIDITY( CHECK_SEND, 0 );
count = (DWORD)(NTptr - P3at);
DISPDBG((DBGLVL, "SEND_PXRX_DMA:fifo() %d dwords @ %d:0x%08X -> 0x%08X", count, gi_pxrxDMA.NTbuff, P3at, NTptr));
if( count > 0) {
volatile ULONG *dst;
ULONG *src, space;
DISPDBG((DBGLVL, "Sending FIFO tags (0x%08X x %d)", P3at, count));
src = P3at;
while( count > 0 ) {
GET_INPUT_FIFO_SPACE( space );
// Don't exceed real FIFO size
space = min (space, glintInfo->MaxInFifoEntries);
dst = (ULONG *) glintInfo->regs.InFIFOInterface;
while( space-- && count-- ) {
MEMORY_BARRIER();
WRITE_FAST_ULONG( dst, *src );
MEMORY_BARRIER();
dst++;
src++;
}
}
}
GLINT_CORE_BUSY;
gi_pxrxDMA.NTdone = NTptr;
gi_pxrxDMA.P3at = NTptr;
DISPDBG((DBGLVL, "Sent PXRX DMA"));
}
void switchPXRXdmaBufferFIFO( PPDEV ppdev, GlintDataPtr glintInfo ) {
TEMP_MACRO_VARS;
DISPDBG((DBGLVL, "SWITCH_PXRX_DMA_BUFFER() from %d:0x%08X", gi_pxrxDMA.NTbuff, gi_pxrxDMA.NTptr));
/* Close the old buffer and post it */
SEND_PXRX_DMA_FORCE;
/* Switch to the new buffer */
gi_pxrxDMA.NTbuff = !gi_pxrxDMA.NTbuff;
/* Ensure that the new buffer is empty */
//WAIT_PXRX_DMA_COMPLETED_BUFFER; // Not needed when running through FIFOs.
/* Start using the new buffer */
gi_pxrxDMA.NTptr = gi_pxrxDMA.DMAaddrL[gi_pxrxDMA.NTbuff];
gi_pxrxDMA.P3at = gi_pxrxDMA.NTptr;
#if PXRX_DMA_BUFFER_CHECK
glintInfo->NTwait = gi_pxrxDMA.NTptr;
#endif
DISPDBG((DBGLVL, "SWITCH_PXRX_DMA_BUFFER() to %d:0x%08X", gi_pxrxDMA.NTbuff, gi_pxrxDMA.NTptr));
CHECK_PXRX_DMA_VALIDITY( CHECK_SWITCH, 0 );
}
void waitPXRXdmaCompletedBufferFIFO( PPDEV ppdev, GlintDataPtr glintInfo ) {
ASSERTDD(FALSE,"waitPXRXdmaCompletedBufferFIFO was called!");
}