|
|
/******************************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!"); }
|