mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1049 lines
28 KiB
1049 lines
28 KiB
/*
|
|
** Copyright 1991, 1992, 1993, Silicon Graphics, Inc.
|
|
** All Rights Reserved.
|
|
**
|
|
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
|
|
** the contents of this file may not be disclosed to third parties, copied or
|
|
** duplicated in any form, in whole or in part, without the prior written
|
|
** permission of Silicon Graphics, Inc.
|
|
**
|
|
** RESTRICTED RIGHTS LEGEND:
|
|
** Use, duplication or disclosure by the Government is subject to restrictions
|
|
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
|
|
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
|
|
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
|
|
** rights reserved under the Copyright Laws of the United States.
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#if DEAD_3DDDI
|
|
|
|
__GLzValue GenDrvReadZSpan(__GLdepthBuffer *fb, GLint x, GLint y, GLint cx)
|
|
{
|
|
GENDRVACCEL *pDrvAccel;
|
|
RXEXECUTE rxExecute;
|
|
RXREADRECT *prxReadRect;
|
|
RXCMD *prxCmd;
|
|
ULONG nBytes;
|
|
LONG i;
|
|
ULONG *pDest;
|
|
ULONG shiftVal;
|
|
ULONG maskVal;
|
|
|
|
pDrvAccel = ((__GLGENcontext *)fb->buf.gc)->pDrvAccel;
|
|
|
|
rxExecute.hrxRC = pDrvAccel->rxExecute.hrxRC;
|
|
rxExecute.hdc = pDrvAccel->rxExecute.hdc;
|
|
rxExecute.hrxMem = pDrvAccel->hrxMemZ;
|
|
rxExecute.pCmd = pDrvAccel->pZRWBase;
|
|
|
|
prxCmd = (RXCMD *)pDrvAccel->pZRWBase;
|
|
prxCmd->command = RXCMD_READ_RECT;
|
|
prxCmd->size = sizeof(RXREADRECT);
|
|
prxCmd->count = 1;
|
|
|
|
prxReadRect = (RXREADRECT *)(prxCmd + 1);
|
|
prxReadRect->sourceBuffer = RXREADRECT_Z;
|
|
prxReadRect->sourceX = x - fb->buf.gc->constants.viewportXAdjust;
|
|
prxReadRect->sourceY = y - fb->buf.gc->constants.viewportYAdjust;
|
|
prxReadRect->destRect.x = 0;
|
|
prxReadRect->destRect.y = 0;
|
|
prxReadRect->destRect.width = cx;
|
|
prxReadRect->destRect.height = 1;
|
|
prxReadRect->pitch = cx; // set to something reasonable...
|
|
|
|
pDrvAccel->rxExecute.cmdSize = sizeof(RXREADRECT) + sizeof(RXCMD);
|
|
if (!RxExecute(&rxExecute, 0))
|
|
{
|
|
WARNING("GenDrvReadZSpan failed\n");
|
|
}
|
|
|
|
pDest = (ULONG *)pDrvAccel->pShMemZ;
|
|
shiftVal = pDrvAccel->zShift;
|
|
maskVal = pDrvAccel->zBitMask;
|
|
|
|
if (pDrvAccel->pShMemZ == pDrvAccel->pZDrv) {
|
|
for (i = cx; i; i--, pDest++)
|
|
*pDest = (*pDest << shiftVal) & maskVal;
|
|
} else {
|
|
USHORT *pSrc = (USHORT *)pDrvAccel->pZDrv;
|
|
|
|
for (i = cx; i; i--)
|
|
*pDest++ = ((ULONG)*pSrc++ << shiftVal) & maskVal;
|
|
}
|
|
|
|
return *((__GLzValue *)pDrvAccel->pShMemZ);
|
|
}
|
|
|
|
|
|
void GenDrvWriteZSpan(__GLdepthBuffer *fb, GLint x, GLint y, GLint cx)
|
|
{
|
|
GENDRVACCEL *pDrvAccel;
|
|
RXEXECUTE rxExecute;
|
|
RXWRITERECT *prxWriteRect;
|
|
RXCMD *prxCmd;
|
|
ULONG nBytes;
|
|
ULONG *pSrc;
|
|
ULONG shiftVal;
|
|
|
|
pDrvAccel = ((__GLGENcontext *)fb->buf.gc)->pDrvAccel;
|
|
|
|
pSrc = (ULONG *)pDrvAccel->pShMemZ;
|
|
shiftVal = pDrvAccel->zShift;
|
|
|
|
if (pDrvAccel->pShMemZ == pDrvAccel->pZDrv) {
|
|
LONG i;
|
|
|
|
for (i = cx; i; i--, pSrc++)
|
|
*pSrc >>= shiftVal;
|
|
} else {
|
|
USHORT *pDest = (USHORT *)pDrvAccel->pZDrv;
|
|
LONG i;
|
|
|
|
for (i = cx; i; i--)
|
|
*pDest++ = (USHORT)(*pSrc++ >> shiftVal);
|
|
}
|
|
|
|
rxExecute.hrxRC = pDrvAccel->rxExecute.hrxRC;
|
|
rxExecute.hdc = pDrvAccel->rxExecute.hdc;
|
|
rxExecute.hrxMem = pDrvAccel->hrxMemZ;
|
|
rxExecute.pCmd = pDrvAccel->pZRWBase;
|
|
|
|
prxCmd = (RXCMD *)pDrvAccel->pZRWBase;
|
|
prxCmd->command = RXCMD_WRITE_RECT;
|
|
prxCmd->size = sizeof(RXREADRECT);
|
|
prxCmd->count = 1;
|
|
|
|
prxWriteRect = (RXWRITERECT *)(prxCmd + 1);
|
|
prxWriteRect->destBuffer = RXWRITERECT_Z;
|
|
prxWriteRect->sourceX = 0;
|
|
prxWriteRect->sourceY = 0;
|
|
prxWriteRect->destRect.x = x - fb->buf.gc->constants.viewportXAdjust;
|
|
prxWriteRect->destRect.y = y - fb->buf.gc->constants.viewportYAdjust;
|
|
prxWriteRect->destRect.width = cx;
|
|
prxWriteRect->destRect.height = 1;
|
|
prxWriteRect->pitch = cx; // set to something reasonable...
|
|
|
|
pDrvAccel->rxExecute.cmdSize = sizeof(RXWRITERECT) + sizeof(RXCMD);
|
|
if (!RxExecute(&rxExecute, 0))
|
|
{
|
|
WARNING("GenDrvWriteZSpan failed\n");
|
|
}
|
|
}
|
|
|
|
|
|
void GenDrvWriteZ(__GLdepthBuffer *fb, GLint x, GLint y, __GLzValue z)
|
|
{
|
|
GENDRVACCEL *pDrvAccel;
|
|
RXEXECUTE rxExecute;
|
|
RXWRITERECT *prxWriteRect;
|
|
RXCMD *prxCmd;
|
|
|
|
pDrvAccel = ((__GLGENcontext *)fb->buf.gc)->pDrvAccel;
|
|
|
|
if (pDrvAccel->pShMemZ == pDrvAccel->pZDrv)
|
|
*((ULONG *)pDrvAccel->pZDrv) = (ULONG)z >> pDrvAccel->zShift;
|
|
else
|
|
*((USHORT *)pDrvAccel->pZDrv) = (USHORT)(z >> pDrvAccel->zShift);
|
|
|
|
rxExecute.hrxRC = pDrvAccel->rxExecute.hrxRC;
|
|
rxExecute.hdc = pDrvAccel->rxExecute.hdc;
|
|
rxExecute.hrxMem = pDrvAccel->hrxMemZ;
|
|
rxExecute.pCmd = pDrvAccel->pZRWBase;
|
|
|
|
prxCmd = (RXCMD *)pDrvAccel->pZRWBase;
|
|
prxCmd->command = RXCMD_WRITE_RECT;
|
|
prxCmd->size = sizeof(RXREADRECT);
|
|
prxCmd->count = 1;
|
|
|
|
prxWriteRect = (RXWRITERECT *)(prxCmd + 1);
|
|
prxWriteRect->destBuffer = RXWRITERECT_Z;
|
|
prxWriteRect->sourceX = 0;
|
|
prxWriteRect->sourceY = 0;
|
|
prxWriteRect->destRect.x = x - fb->buf.gc->constants.viewportXAdjust;
|
|
prxWriteRect->destRect.y = y - fb->buf.gc->constants.viewportYAdjust;
|
|
prxWriteRect->destRect.width = 1;
|
|
prxWriteRect->destRect.height = 1;
|
|
prxWriteRect->pitch = 1; // set to something reasonable...
|
|
|
|
pDrvAccel->rxExecute.cmdSize = sizeof(RXWRITERECT) + sizeof(RXCMD);
|
|
if (!RxExecute(&rxExecute, 0))
|
|
{
|
|
WARNING("GenDrvWriteZSpan failed\n");
|
|
}
|
|
}
|
|
|
|
|
|
static __GLzValue FASTCALL Fetch(__GLdepthBuffer *fb, GLint x, GLint y)
|
|
{
|
|
return GenDrvReadZSpan(fb, x, y, 1);
|
|
}
|
|
|
|
static GLboolean StoreNEVER(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
return GL_FALSE;
|
|
}
|
|
|
|
static GLboolean StoreLESS(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
if ((z & fb->writeMask) < GenDrvReadZSpan(fb, x, y, 1)) {
|
|
GenDrvWriteZ(fb, x, y, z);
|
|
return GL_TRUE;
|
|
}
|
|
return GL_FALSE;
|
|
}
|
|
|
|
static GLboolean StoreEQUAL(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
if ((z & fb->writeMask) == GenDrvReadZSpan(fb, x, y, 1)) {
|
|
GenDrvWriteZ(fb, x, y, z);
|
|
return GL_TRUE;
|
|
}
|
|
return GL_FALSE;
|
|
}
|
|
|
|
static GLboolean StoreLEQUAL(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
if ((z & fb->writeMask) <= GenDrvReadZSpan(fb, x, y, 1)) {
|
|
GenDrvWriteZ(fb, x, y, z);
|
|
return GL_TRUE;
|
|
}
|
|
return GL_FALSE;
|
|
}
|
|
|
|
static GLboolean StoreGREATER(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
if ((z & fb->writeMask) > GenDrvReadZSpan(fb, x, y, 1)) {
|
|
GenDrvWriteZ(fb, x, y, z);
|
|
return GL_TRUE;
|
|
}
|
|
return GL_FALSE;
|
|
}
|
|
|
|
static GLboolean StoreNOTEQUAL(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
if ((z & fb->writeMask) != GenDrvReadZSpan(fb, x, y, 1)) {
|
|
GenDrvWriteZ(fb, x, y, z);
|
|
return GL_TRUE;
|
|
}
|
|
return GL_FALSE;
|
|
}
|
|
|
|
static GLboolean StoreGEQUAL(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
if ((z & fb->writeMask) >= GenDrvReadZSpan(fb, x, y, 1)) {
|
|
GenDrvWriteZ(fb, x, y, z);
|
|
return GL_TRUE;
|
|
}
|
|
return GL_FALSE;
|
|
}
|
|
|
|
static GLboolean StoreALWAYS(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
GenDrvWriteZ(fb, x, y, z);
|
|
return GL_TRUE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
|
|
static GLboolean StoreLESS_W(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
return (z & fb->writeMask) < GenDrvReadZSpan(fb, x, y, 1);
|
|
}
|
|
|
|
static GLboolean StoreEQUAL_W(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
return (z & fb->writeMask) == GenDrvReadZSpan(fb, x, y, 1);
|
|
}
|
|
|
|
static GLboolean StoreLEQUAL_W(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
return (z & fb->writeMask) <= GenDrvReadZSpan(fb, x, y, 1);
|
|
}
|
|
|
|
static GLboolean StoreGREATER_W(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
return (z & fb->writeMask) > GenDrvReadZSpan(fb, x, y, 1);
|
|
}
|
|
|
|
static GLboolean StoreNOTEQUAL_W(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
return (z & fb->writeMask) != GenDrvReadZSpan(fb, x, y, 1);
|
|
}
|
|
|
|
static GLboolean StoreGEQUAL_W(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
return (z & fb->writeMask) >= GenDrvReadZSpan(fb, x, y, 1);
|
|
}
|
|
|
|
static GLboolean StoreALWAYS_W(__GLdepthBuffer *fb,
|
|
GLint x, GLint y, __GLzValue z)
|
|
{
|
|
return GL_TRUE;
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
static GLboolean (*StoreProcs[16])(__GLdepthBuffer*, GLint, GLint, __GLzValue)
|
|
= {
|
|
StoreNEVER,
|
|
StoreLESS,
|
|
StoreEQUAL,
|
|
StoreLEQUAL,
|
|
StoreGREATER,
|
|
StoreNOTEQUAL,
|
|
StoreGEQUAL,
|
|
StoreALWAYS,
|
|
StoreNEVER,
|
|
StoreLESS_W,
|
|
StoreEQUAL_W,
|
|
StoreLEQUAL_W,
|
|
StoreGREATER_W,
|
|
StoreNOTEQUAL_W,
|
|
StoreGEQUAL_W,
|
|
StoreALWAYS_W
|
|
};
|
|
|
|
// Note: depthIndex param not used - for compatibility with Pick in so_depth.c
|
|
static void FASTCALL Pick(__GLcontext *gc, __GLdepthBuffer *fb, GLint depthIndex)
|
|
{
|
|
GLint ix = gc->state.depth.testFunc - GL_NEVER;
|
|
|
|
if (!gc->state.depth.writeEnable) {
|
|
ix += 8;
|
|
}
|
|
fb->store = StoreProcs[ix];
|
|
}
|
|
|
|
void FASTCALL GenDrvInitDepth(__GLcontext *gc, __GLdepthBuffer *fb)
|
|
{
|
|
GENDRVACCEL *pDrvAccel;
|
|
ULONG zDepth;
|
|
|
|
pDrvAccel = ((__GLGENcontext *)gc)->pDrvAccel;
|
|
zDepth = pDrvAccel->rxSurfaceInfo.zDepth;
|
|
|
|
fb->buf.elementSize = sizeof(__GLzValue);
|
|
fb->buf.gc = gc;
|
|
fb->scale = (__GLzValue) ~0;
|
|
fb->writeMask = ((__GLzValue)~0) << (32 - pDrvAccel->rxSurfaceInfo.zDepth);
|
|
fb->pick = Pick;
|
|
fb->clear = GenDrvClearDepth;
|
|
fb->store2 = StoreALWAYS;
|
|
fb->fetch = Fetch;
|
|
}
|
|
|
|
void FASTCALL GenDrvFreeDepth(__GLcontext *gc, __GLdepthBuffer *fb)
|
|
{
|
|
}
|
|
|
|
|
|
GLboolean FASTCALL GenDrvDepthTestLine(__GLcontext *gc)
|
|
{
|
|
__GLzValue z, dzdx;
|
|
GLint xLittle, xBig, yLittle, yBig;
|
|
GLint xStart, yStart;
|
|
GLint fraction, dfraction;
|
|
GLint failed, count;
|
|
__GLstippleWord bit, outMask, *osp;
|
|
GLboolean writeEnabled, passed;
|
|
GLint w;
|
|
|
|
w = gc->polygon.shader.length;
|
|
|
|
xBig = gc->line.options.xBig;
|
|
yBig = gc->line.options.yBig;
|
|
xLittle = gc->line.options.xLittle;
|
|
yLittle = gc->line.options.yLittle;
|
|
xStart = gc->line.options.xStart;
|
|
yStart = gc->line.options.yStart;
|
|
fraction = gc->line.options.fraction;
|
|
dfraction = gc->line.options.dfraction;
|
|
|
|
z = gc->polygon.shader.frag.z;
|
|
dzdx = gc->polygon.shader.dzdx;
|
|
writeEnabled = gc->state.depth.writeEnable;
|
|
osp = gc->polygon.shader.stipplePat;
|
|
failed = 0;
|
|
while (w) {
|
|
count = w;
|
|
if (count > __GL_STIPPLE_BITS) {
|
|
count = __GL_STIPPLE_BITS;
|
|
}
|
|
w -= count;
|
|
|
|
outMask = (__GLstippleWord)~0;
|
|
bit = (__GLstippleWord)__GL_STIPPLE_SHIFT(0);
|
|
while (--count >= 0) {
|
|
if (!(*gc->depthBuffer.store)(&gc->depthBuffer, xStart, yStart, z)) {
|
|
outMask &= ~bit;
|
|
failed++;
|
|
}
|
|
z += dzdx;
|
|
|
|
fraction += dfraction;
|
|
if (fraction < 0) {
|
|
fraction &= ~0x80000000;
|
|
xStart += xBig;
|
|
yStart += yBig;
|
|
} else {
|
|
xStart += xLittle;
|
|
yStart += yLittle;
|
|
}
|
|
#ifdef __GL_STIPPLE_MSB
|
|
bit >>= 1;
|
|
#else
|
|
bit <<= 1;
|
|
#endif
|
|
}
|
|
*osp++ = outMask;
|
|
}
|
|
|
|
if (failed == 0) {
|
|
/* Call next span proc */
|
|
return GL_FALSE;
|
|
} else {
|
|
if (failed != gc->polygon.shader.length) {
|
|
/* Call next stippled span proc */
|
|
return GL_TRUE;
|
|
}
|
|
}
|
|
gc->polygon.shader.done = GL_TRUE;
|
|
return GL_TRUE;
|
|
}
|
|
|
|
|
|
GLboolean FASTCALL GenDrvDepthTestStippledLine(__GLcontext *gc)
|
|
{
|
|
__GLzValue z, dzdx;
|
|
GLint xLittle, xBig, yLittle, yBig;
|
|
GLint xStart, yStart;
|
|
GLint fraction, dfraction;
|
|
GLint failed, count;
|
|
__GLstippleWord bit, inMask, outMask, *sp;
|
|
GLboolean writeEnabled, passed;
|
|
GLint w;
|
|
|
|
w = gc->polygon.shader.length;
|
|
sp = gc->polygon.shader.stipplePat;
|
|
xBig = gc->line.options.xBig;
|
|
yBig = gc->line.options.yBig;
|
|
xLittle = gc->line.options.xLittle;
|
|
yLittle = gc->line.options.yLittle;
|
|
xStart = gc->line.options.xStart;
|
|
yStart = gc->line.options.yStart;
|
|
fraction = gc->line.options.fraction;
|
|
dfraction = gc->line.options.dfraction;
|
|
|
|
z = gc->polygon.shader.frag.z;
|
|
dzdx = gc->polygon.shader.dzdx;
|
|
writeEnabled = gc->state.depth.writeEnable;
|
|
failed = 0;
|
|
while (w) {
|
|
count = w;
|
|
if (count > __GL_STIPPLE_BITS) {
|
|
count = __GL_STIPPLE_BITS;
|
|
}
|
|
w -= count;
|
|
|
|
inMask = *sp;
|
|
outMask = (__GLstippleWord)~0;
|
|
bit = (__GLstippleWord)__GL_STIPPLE_SHIFT(0);
|
|
while (--count >= 0) {
|
|
if (inMask & bit) {
|
|
if (!(*gc->depthBuffer.store)(&gc->depthBuffer, xStart, yStart, z)) {
|
|
outMask &= ~bit;
|
|
failed++;
|
|
}
|
|
} else failed++;
|
|
z += dzdx;
|
|
|
|
fraction += dfraction;
|
|
if (fraction < 0) {
|
|
fraction &= ~0x80000000;
|
|
fraction &= ~0x80000000;
|
|
xStart += xBig;
|
|
yStart += yBig;
|
|
} else {
|
|
xStart += xLittle;
|
|
yStart += yLittle;
|
|
}
|
|
#ifdef __GL_STIPPLE_MSB
|
|
bit >>= 1;
|
|
#else
|
|
bit <<= 1;
|
|
#endif
|
|
}
|
|
*sp++ = outMask & inMask;
|
|
}
|
|
|
|
if (failed != gc->polygon.shader.length) {
|
|
/* Call next proc */
|
|
return GL_FALSE;
|
|
}
|
|
return GL_TRUE;
|
|
}
|
|
|
|
GLboolean FASTCALL GenDrvDepthTestStencilLine(__GLcontext *gc)
|
|
{
|
|
__GLstencilCell *sfb, *zPassOp, *zFailOp;
|
|
GLint xLittle, xBig, yLittle, yBig;
|
|
GLint xStart, yStart;
|
|
GLint fraction, dfraction;
|
|
GLint dspLittle, dspBig;
|
|
__GLzValue z, dzdx;
|
|
GLint failed, count;
|
|
__GLstippleWord bit, outMask, *osp;
|
|
GLboolean writeEnabled, passed;
|
|
GLint w;
|
|
|
|
w = gc->polygon.shader.length;
|
|
|
|
xBig = gc->line.options.xBig;
|
|
yBig = gc->line.options.yBig;
|
|
xLittle = gc->line.options.xLittle;
|
|
yLittle = gc->line.options.yLittle;
|
|
xStart = gc->line.options.xStart;
|
|
yStart = gc->line.options.yStart;
|
|
fraction = gc->line.options.fraction;
|
|
dfraction = gc->line.options.dfraction;
|
|
|
|
sfb = __GL_STENCIL_ADDR(&gc->stencilBuffer, (__GLstencilCell*),
|
|
gc->line.options.xStart, gc->line.options.yStart);
|
|
dspLittle = xLittle + yLittle * gc->stencilBuffer.buf.outerWidth;
|
|
dspBig = xBig + yBig * gc->stencilBuffer.buf.outerWidth;
|
|
fraction = gc->line.options.fraction;
|
|
dfraction = gc->line.options.dfraction;
|
|
|
|
zFailOp = gc->stencilBuffer.depthFailOpTable;
|
|
zPassOp = gc->stencilBuffer.depthPassOpTable;
|
|
z = gc->polygon.shader.frag.z;
|
|
dzdx = gc->polygon.shader.dzdx;
|
|
writeEnabled = gc->state.depth.writeEnable;
|
|
osp = gc->polygon.shader.stipplePat;
|
|
failed = 0;
|
|
while (w) {
|
|
count = w;
|
|
if (count > __GL_STIPPLE_BITS) {
|
|
count = __GL_STIPPLE_BITS;
|
|
}
|
|
w -= count;
|
|
|
|
outMask = (__GLstippleWord)~0;
|
|
bit = (__GLstippleWord)__GL_STIPPLE_SHIFT(0);
|
|
while (--count >= 0) {
|
|
if (!(*gc->depthBuffer.store)(&gc->depthBuffer, xStart, yStart, z)) {
|
|
sfb[0] = zFailOp[sfb[0]];
|
|
outMask &= ~bit;
|
|
failed++;
|
|
} else {
|
|
sfb[0] = zPassOp[sfb[0]];
|
|
}
|
|
|
|
z += dzdx;
|
|
fraction += dfraction;
|
|
|
|
if (fraction < 0) {
|
|
fraction &= ~0x80000000;
|
|
sfb += dspBig;
|
|
xStart += xBig;
|
|
yStart += yBig;
|
|
} else {
|
|
sfb += dspLittle;
|
|
xStart += xLittle;
|
|
yStart += yLittle;
|
|
}
|
|
#ifdef __GL_STIPPLE_MSB
|
|
bit >>= 1;
|
|
#else
|
|
bit <<= 1;
|
|
#endif
|
|
}
|
|
*osp++ = outMask;
|
|
}
|
|
|
|
if (failed == 0) {
|
|
/* Call next span proc */
|
|
return GL_FALSE;
|
|
} else {
|
|
if (failed != gc->polygon.shader.length) {
|
|
/* Call next stippled span proc */
|
|
return GL_TRUE;
|
|
}
|
|
}
|
|
gc->polygon.shader.done = GL_TRUE;
|
|
return GL_TRUE;
|
|
}
|
|
|
|
GLboolean FASTCALL GenDrvDepthTestStencilStippledLine(__GLcontext *gc)
|
|
{
|
|
__GLstencilCell *sfb, *zPassOp, *zFailOp;
|
|
GLint xLittle, xBig, yLittle, yBig;
|
|
GLint xStart, yStart;
|
|
GLint fraction, dfraction;
|
|
GLint dspLittle, dspBig;
|
|
__GLzValue z, dzdx;
|
|
GLint failed, count;
|
|
__GLstippleWord bit, inMask, outMask, *sp;
|
|
GLboolean writeEnabled, passed;
|
|
GLint w;
|
|
|
|
w = gc->polygon.shader.length;
|
|
sp = gc->polygon.shader.stipplePat;
|
|
|
|
xBig = gc->line.options.xBig;
|
|
yBig = gc->line.options.yBig;
|
|
xLittle = gc->line.options.xLittle;
|
|
yLittle = gc->line.options.yLittle;
|
|
xStart = gc->line.options.xStart;
|
|
yStart = gc->line.options.yStart;
|
|
fraction = gc->line.options.fraction;
|
|
dfraction = gc->line.options.dfraction;
|
|
|
|
sfb = __GL_STENCIL_ADDR(&gc->stencilBuffer, (__GLstencilCell*),
|
|
gc->line.options.xStart, gc->line.options.yStart);
|
|
dspLittle = xLittle + yLittle * gc->stencilBuffer.buf.outerWidth;
|
|
dspBig = xBig + yBig * gc->stencilBuffer.buf.outerWidth;
|
|
fraction = gc->line.options.fraction;
|
|
dfraction = gc->line.options.dfraction;
|
|
|
|
zFailOp = gc->stencilBuffer.depthFailOpTable;
|
|
zPassOp = gc->stencilBuffer.depthPassOpTable;
|
|
z = gc->polygon.shader.frag.z;
|
|
dzdx = gc->polygon.shader.dzdx;
|
|
writeEnabled = gc->state.depth.writeEnable;
|
|
failed = 0;
|
|
while (w) {
|
|
count = w;
|
|
if (count > __GL_STIPPLE_BITS) {
|
|
count = __GL_STIPPLE_BITS;
|
|
}
|
|
w -= count;
|
|
|
|
inMask = *sp;
|
|
outMask = (__GLstippleWord)~0;
|
|
bit = (__GLstippleWord)__GL_STIPPLE_SHIFT(0);
|
|
while (--count >= 0) {
|
|
if (inMask & bit) {
|
|
if (!(*gc->depthBuffer.store)(&gc->depthBuffer, xStart, yStart, z)) {
|
|
sfb[0] = zFailOp[sfb[0]];
|
|
outMask &= ~bit;
|
|
failed++;
|
|
} else {
|
|
sfb[0] = zPassOp[sfb[0]];
|
|
}
|
|
} else failed++;
|
|
z += dzdx;
|
|
|
|
fraction += dfraction;
|
|
if (fraction < 0) {
|
|
fraction &= ~0x80000000;
|
|
sfb += dspBig;
|
|
xStart += xBig;
|
|
yStart += yBig;
|
|
} else {
|
|
sfb += dspLittle;
|
|
xStart += xLittle;
|
|
yStart += yLittle;
|
|
}
|
|
#ifdef __GL_STIPPLE_MSB
|
|
bit >>= 1;
|
|
#else
|
|
bit <<= 1;
|
|
#endif
|
|
}
|
|
*sp++ = outMask & inMask;
|
|
}
|
|
|
|
if (failed != gc->polygon.shader.length) {
|
|
/* Call next proc */
|
|
return GL_FALSE;
|
|
}
|
|
|
|
return GL_TRUE;
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
/*
|
|
** Depth test a span, when stenciling is disabled.
|
|
*/
|
|
GLboolean FASTCALL GenDrvDepthTestSpan(__GLcontext *gc)
|
|
{
|
|
__GLzValue z, dzdx, *zfb;
|
|
GLint failed, count, testFunc;
|
|
__GLstippleWord bit, outMask, *osp;
|
|
GLboolean writeEnabled, passed;
|
|
GLint w;
|
|
|
|
w = gc->polygon.shader.length;
|
|
|
|
GenDrvReadZSpan(&gc->depthBuffer, gc->polygon.shader.frag.x,
|
|
gc->polygon.shader.frag.y, w);
|
|
|
|
if (((__GLGENcontext *)gc)->pDrvAccel->softZSpanFuncPtr) {
|
|
GLboolean retVal;
|
|
|
|
gc->polygon.shader.zbuf = (__GLzValue *)((__GLGENcontext *)gc)->pDrvAccel->pShMemZ;
|
|
|
|
retVal =
|
|
(*((__GLGENcontext *)gc)->pDrvAccel->softZSpanFuncPtr)(gc);
|
|
|
|
if (gc->state.depth.writeEnable)
|
|
GenDrvWriteZSpan(&gc->depthBuffer, gc->polygon.shader.frag.x,
|
|
gc->polygon.shader.frag.y,
|
|
gc->polygon.shader.length);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
testFunc = gc->state.depth.testFunc & 0x7;
|
|
zfb = (__GLzValue *)((__GLGENcontext *)gc)->pDrvAccel->pShMemZ;
|
|
z = gc->polygon.shader.frag.z;
|
|
dzdx = gc->polygon.shader.dzdx;
|
|
writeEnabled = gc->state.depth.writeEnable;
|
|
osp = gc->polygon.shader.stipplePat;
|
|
failed = 0;
|
|
while (w) {
|
|
count = w;
|
|
if (count > __GL_STIPPLE_BITS) {
|
|
count = __GL_STIPPLE_BITS;
|
|
}
|
|
w -= count;
|
|
|
|
outMask = (__GLstippleWord)~0;
|
|
bit = (__GLstippleWord)__GL_STIPPLE_SHIFT(0);
|
|
while (--count >= 0) {
|
|
switch (testFunc) {
|
|
case (GL_NEVER & 0x7): passed = GL_FALSE; break;
|
|
case (GL_LESS & 0x7): passed = z < zfb[0]; break;
|
|
case (GL_EQUAL & 0x7): passed = z == zfb[0]; break;
|
|
case (GL_LEQUAL & 0x7): passed = z <= zfb[0]; break;
|
|
case (GL_GREATER & 0x7): passed = z > zfb[0]; break;
|
|
case (GL_NOTEQUAL & 0x7): passed = z != zfb[0]; break;
|
|
case (GL_GEQUAL & 0x7): passed = z >= zfb[0]; break;
|
|
case (GL_ALWAYS & 0x7): passed = GL_TRUE; break;
|
|
}
|
|
if (passed) {
|
|
if (writeEnabled) {
|
|
zfb[0] = z;
|
|
}
|
|
} else {
|
|
outMask &= ~bit;
|
|
failed++;
|
|
}
|
|
z += dzdx;
|
|
zfb++;
|
|
#ifdef __GL_STIPPLE_MSB
|
|
bit >>= 1;
|
|
#else
|
|
bit <<= 1;
|
|
#endif
|
|
}
|
|
*osp++ = outMask;
|
|
}
|
|
|
|
if (writeEnabled)
|
|
GenDrvWriteZSpan(&gc->depthBuffer, gc->polygon.shader.frag.x,
|
|
gc->polygon.shader.frag.y,
|
|
gc->polygon.shader.length);
|
|
|
|
|
|
if (failed == 0) {
|
|
/* Call next span proc */
|
|
return GL_FALSE;
|
|
} else {
|
|
if (failed != gc->polygon.shader.length) {
|
|
/* Call next stippled span proc */
|
|
return GL_TRUE;
|
|
}
|
|
}
|
|
gc->polygon.shader.done = GL_TRUE;
|
|
return GL_TRUE;
|
|
}
|
|
|
|
/*
|
|
** Stippled form of depth test span, when stenciling is disabled.
|
|
*/
|
|
GLboolean FASTCALL GenDrvDepthTestStippledSpan(__GLcontext *gc)
|
|
{
|
|
__GLzValue z, dzdx, *zfb;
|
|
GLint failed, count, testFunc;
|
|
__GLstippleWord bit, inMask, outMask, *sp;
|
|
GLboolean writeEnabled, passed;
|
|
GLint w;
|
|
|
|
sp = gc->polygon.shader.stipplePat;
|
|
w = gc->polygon.shader.length;
|
|
|
|
GenDrvReadZSpan(&gc->depthBuffer, gc->polygon.shader.frag.x,
|
|
gc->polygon.shader.frag.y, w);
|
|
|
|
testFunc = gc->state.depth.testFunc & 0x7;
|
|
zfb = (__GLzValue *)((__GLGENcontext *)gc)->pDrvAccel->pShMemZ;
|
|
z = gc->polygon.shader.frag.z;
|
|
dzdx = gc->polygon.shader.dzdx;
|
|
writeEnabled = gc->state.depth.writeEnable;
|
|
failed = 0;
|
|
while (w) {
|
|
count = w;
|
|
if (count > __GL_STIPPLE_BITS) {
|
|
count = __GL_STIPPLE_BITS;
|
|
}
|
|
w -= count;
|
|
|
|
inMask = *sp;
|
|
outMask = (__GLstippleWord)~0;
|
|
bit = (__GLstippleWord)__GL_STIPPLE_SHIFT(0);
|
|
while (--count >= 0) {
|
|
if (inMask & bit) {
|
|
switch (testFunc) {
|
|
case (GL_NEVER & 0x7): passed = GL_FALSE; break;
|
|
case (GL_LESS & 0x7): passed = z < zfb[0]; break;
|
|
case (GL_EQUAL & 0x7): passed = z == zfb[0]; break;
|
|
case (GL_LEQUAL & 0x7): passed = z <= zfb[0]; break;
|
|
case (GL_GREATER & 0x7): passed = z > zfb[0]; break;
|
|
case (GL_NOTEQUAL & 0x7): passed = z != zfb[0]; break;
|
|
case (GL_GEQUAL & 0x7): passed = z >= zfb[0]; break;
|
|
case (GL_ALWAYS & 0x7): passed = GL_TRUE; break;
|
|
}
|
|
if (passed) {
|
|
if (writeEnabled) {
|
|
zfb[0] = z;
|
|
}
|
|
} else {
|
|
outMask &= ~bit;
|
|
failed++;
|
|
}
|
|
} else failed++;
|
|
z += dzdx;
|
|
zfb++;
|
|
#ifdef __GL_STIPPLE_MSB
|
|
bit >>= 1;
|
|
#else
|
|
bit <<= 1;
|
|
#endif
|
|
}
|
|
*sp++ = outMask & inMask;
|
|
}
|
|
|
|
if (writeEnabled)
|
|
GenDrvWriteZSpan(&gc->depthBuffer, gc->polygon.shader.frag.x,
|
|
gc->polygon.shader.frag.y,
|
|
gc->polygon.shader.length);
|
|
|
|
if (failed != gc->polygon.shader.length) {
|
|
/* Call next proc */
|
|
return GL_FALSE;
|
|
}
|
|
return GL_TRUE;
|
|
}
|
|
|
|
/*
|
|
** Depth test a span when stenciling is enabled.
|
|
*/
|
|
GLboolean FASTCALL GenDrvDepthTestStencilSpan(__GLcontext *gc)
|
|
{
|
|
__GLstencilCell *sfb, *zPassOp, *zFailOp;
|
|
__GLzValue z, dzdx, *zfb;
|
|
GLint failed, count, testFunc;
|
|
__GLstippleWord bit, outMask, *osp;
|
|
GLboolean writeEnabled, passed;
|
|
GLint w;
|
|
|
|
w = gc->polygon.shader.length;
|
|
|
|
GenDrvReadZSpan(&gc->depthBuffer, gc->polygon.shader.frag.x,
|
|
gc->polygon.shader.frag.y, w);
|
|
|
|
testFunc = gc->state.depth.testFunc & 0x7;
|
|
zfb = (__GLzValue *)((__GLGENcontext *)gc)->pDrvAccel->pShMemZ;
|
|
sfb = gc->polygon.shader.sbuf;
|
|
zFailOp = gc->stencilBuffer.depthFailOpTable;
|
|
zPassOp = gc->stencilBuffer.depthPassOpTable;
|
|
z = gc->polygon.shader.frag.z;
|
|
dzdx = gc->polygon.shader.dzdx;
|
|
writeEnabled = gc->state.depth.writeEnable;
|
|
osp = gc->polygon.shader.stipplePat;
|
|
failed = 0;
|
|
while (w) {
|
|
count = w;
|
|
if (count > __GL_STIPPLE_BITS) {
|
|
count = __GL_STIPPLE_BITS;
|
|
}
|
|
w -= count;
|
|
|
|
outMask = (__GLstippleWord)~0;
|
|
bit = (__GLstippleWord)__GL_STIPPLE_SHIFT(0);
|
|
while (--count >= 0) {
|
|
switch (testFunc) {
|
|
case (GL_NEVER & 0x7): passed = GL_FALSE; break;
|
|
case (GL_LESS & 0x7): passed = z < zfb[0]; break;
|
|
case (GL_EQUAL & 0x7): passed = z == zfb[0]; break;
|
|
case (GL_LEQUAL & 0x7): passed = z <= zfb[0]; break;
|
|
case (GL_GREATER & 0x7): passed = z > zfb[0]; break;
|
|
case (GL_NOTEQUAL & 0x7): passed = z != zfb[0]; break;
|
|
case (GL_GEQUAL & 0x7): passed = z >= zfb[0]; break;
|
|
case (GL_ALWAYS & 0x7): passed = GL_TRUE; break;
|
|
}
|
|
if (passed) {
|
|
sfb[0] = zPassOp[sfb[0]];
|
|
if (writeEnabled) {
|
|
zfb[0] = z;
|
|
}
|
|
} else {
|
|
sfb[0] = zFailOp[sfb[0]];
|
|
outMask &= ~bit;
|
|
failed++;
|
|
}
|
|
z += dzdx;
|
|
zfb++;
|
|
sfb++;
|
|
#ifdef __GL_STIPPLE_MSB
|
|
bit >>= 1;
|
|
#else
|
|
bit <<= 1;
|
|
#endif
|
|
}
|
|
*osp++ = outMask;
|
|
}
|
|
|
|
if (writeEnabled)
|
|
GenDrvWriteZSpan(&gc->depthBuffer, gc->polygon.shader.frag.x,
|
|
gc->polygon.shader.frag.y,
|
|
gc->polygon.shader.length);
|
|
|
|
if (failed == 0) {
|
|
/* Call next span proc */
|
|
return GL_FALSE;
|
|
} else {
|
|
if (failed != gc->polygon.shader.length) {
|
|
/* Call next stippled span proc */
|
|
return GL_TRUE;
|
|
}
|
|
}
|
|
gc->polygon.shader.done = GL_TRUE;
|
|
return GL_TRUE;
|
|
}
|
|
|
|
GLboolean FASTCALL GenDrvDepthTestStencilStippledSpan(__GLcontext *gc)
|
|
{
|
|
__GLstencilCell *sfb, *zPassOp, *zFailOp;
|
|
__GLzValue z, dzdx, *zfb;
|
|
GLint failed, count, testFunc;
|
|
__GLstippleWord bit, inMask, outMask, *sp;
|
|
GLboolean writeEnabled, passed;
|
|
GLint w;
|
|
|
|
w = gc->polygon.shader.length;
|
|
sp = gc->polygon.shader.stipplePat;
|
|
|
|
GenDrvReadZSpan(&gc->depthBuffer, gc->polygon.shader.frag.x,
|
|
gc->polygon.shader.frag.y, w);
|
|
|
|
testFunc = gc->state.depth.testFunc & 0x7;
|
|
zfb = (__GLzValue *)((__GLGENcontext *)gc)->pDrvAccel->pShMemZ;
|
|
sfb = gc->polygon.shader.sbuf;
|
|
zFailOp = gc->stencilBuffer.depthFailOpTable;
|
|
zPassOp = gc->stencilBuffer.depthPassOpTable;
|
|
z = gc->polygon.shader.frag.z;
|
|
dzdx = gc->polygon.shader.dzdx;
|
|
writeEnabled = gc->state.depth.writeEnable;
|
|
failed = 0;
|
|
while (w) {
|
|
count = w;
|
|
if (count > __GL_STIPPLE_BITS) {
|
|
count = __GL_STIPPLE_BITS;
|
|
}
|
|
w -= count;
|
|
|
|
inMask = *sp;
|
|
outMask = (__GLstippleWord)~0;
|
|
bit = (__GLstippleWord)__GL_STIPPLE_SHIFT(0);
|
|
while (--count >= 0) {
|
|
if (inMask & bit) {
|
|
switch (testFunc) {
|
|
case (GL_NEVER & 0x7): passed = GL_FALSE; break;
|
|
case (GL_LESS & 0x7): passed = z < zfb[0]; break;
|
|
case (GL_EQUAL & 0x7): passed = z == zfb[0]; break;
|
|
case (GL_LEQUAL & 0x7): passed = z <= zfb[0]; break;
|
|
case (GL_GREATER & 0x7): passed = z > zfb[0]; break;
|
|
case (GL_NOTEQUAL & 0x7): passed = z != zfb[0]; break;
|
|
case (GL_GEQUAL & 0x7): passed = z >= zfb[0]; break;
|
|
case (GL_ALWAYS & 0x7): passed = GL_TRUE; break;
|
|
}
|
|
if (passed) {
|
|
sfb[0] = zPassOp[sfb[0]];
|
|
if (writeEnabled) {
|
|
zfb[0] = z;
|
|
}
|
|
} else {
|
|
sfb[0] = zFailOp[sfb[0]];
|
|
outMask &= ~bit;
|
|
failed++;
|
|
}
|
|
} else failed++;
|
|
z += dzdx;
|
|
zfb++;
|
|
sfb++;
|
|
#ifdef __GL_STIPPLE_MSB
|
|
bit >>= 1;
|
|
#else
|
|
bit <<= 1;
|
|
#endif
|
|
}
|
|
*sp++ = outMask & inMask;
|
|
}
|
|
|
|
if (writeEnabled)
|
|
GenDrvWriteZSpan(&gc->depthBuffer, gc->polygon.shader.frag.x,
|
|
gc->polygon.shader.frag.y,
|
|
gc->polygon.shader.length);
|
|
|
|
if (failed != gc->polygon.shader.length) {
|
|
/* Call next proc */
|
|
return GL_FALSE;
|
|
}
|
|
|
|
return GL_TRUE;
|
|
}
|
|
|
|
#ifndef _MCD_
|
|
// This is identical to the one in MCDDEPTH.C.
|
|
void FASTCALL __fastGenPickZStoreProc(__GLcontext *gc)
|
|
{
|
|
int index;
|
|
|
|
index = gc->state.depth.testFunc - GL_NEVER;
|
|
|
|
if( (gc->state.depth.writeEnable == GL_FALSE) ||
|
|
(gc->modes.depthBits == 0) )
|
|
index += 8;
|
|
|
|
if (gc->depthBuffer.buf.elementSize == 2)
|
|
index += 16; // 32-bit z fns in first 16 locations
|
|
|
|
GENACCEL(gc).__fastGenZStore = __glCDTPixel[index];
|
|
}
|
|
#endif
|
|
|
|
#endif
|