Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1688 lines
38 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
/*
** Process the incoming span by calling all of the appropriate span procs.
*/
GLboolean FASTCALL __glProcessSpan(__GLcontext *gc)
{
GLint m, i;
m = gc->procs.span.m;
gc->polygon.shader.done = GL_FALSE;
for (i = 0; i < m; i++) {
if ((*gc->procs.span.spanFuncs[i])(gc)) {
i++;
break;
}
}
if (i != m && !gc->polygon.shader.done) {
for (; i<m; i++) {
if ((*gc->procs.span.stippledSpanFuncs[i])(gc)) {
break;
}
}
}
return GL_FALSE;
}
/*
** Process the incoming span by calling all of the appropriate span procs.
**
** This routine sets gc->polygon.shader.cfb to &gc->frontBuffer and then
** to &gc->backBuffer.
*/
GLboolean FASTCALL __glProcessReplicateSpan(__GLcontext *gc)
{
GLint n, m, i;
__GLcolor colors[__GL_MAX_MAX_VIEWPORT], *fcp, *tcp;
GLint w;
w = gc->polygon.shader.length;
n = gc->procs.span.n;
m = gc->procs.span.m;
gc->polygon.shader.done = GL_FALSE;
for (i = 0; i < n; i++) {
if ((*gc->procs.span.spanFuncs[i])(gc)) {
i++;
goto earlyStipple;
}
}
fcp = gc->polygon.shader.colors;
tcp = colors;
if (gc->modes.rgbMode) {
for (i = 0; i < w; i++) {
*tcp++ = *fcp++;
}
} else {
for (i = 0; i < w; i++) {
tcp->r = fcp->r;
fcp++;
tcp++;
}
}
ASSERTOPENGL (m == n + 1, "m != n+1, wrong spanProc will be chosen");
gc->polygon.shader.cfb = &gc->frontBuffer;
(*gc->frontBuffer.storeSpan)(gc);
// for (i = n; i < m; i++) {
// (*gc->procs.span.spanFuncs[i])(gc);
// }
fcp = colors;
tcp = gc->polygon.shader.colors;
if (gc->modes.rgbMode) {
for (i = 0; i < w; i++) {
*tcp++ = *fcp++;
}
} else {
for (i = 0; i < w; i++) {
tcp->r = fcp->r;
fcp++;
tcp++;
}
}
gc->polygon.shader.cfb = &gc->backBuffer;
(*gc->backBuffer.storeSpan)(gc);
// for (i = n; i < m; i++) {
// (*gc->procs.span.spanFuncs[i])(gc);
// }
return GL_FALSE;
earlyStipple:
if (gc->polygon.shader.done) return GL_FALSE;
for (; i < n; i++) {
if ((*gc->procs.span.stippledSpanFuncs[i])(gc)) {
return GL_FALSE;
}
}
fcp = gc->polygon.shader.colors;
tcp = colors;
if (gc->modes.rgbMode) {
for (i = 0; i < w; i++) {
*tcp++ = *fcp++;
}
} else {
for (i = 0; i < w; i++) {
tcp->r = fcp->r;
fcp++;
tcp++;
}
}
gc->polygon.shader.cfb = &gc->frontBuffer;
(*gc->frontBuffer.storeStippledSpan)(gc);
// for (i = n; i < m; i++) {
// (*gc->procs.span.stippledSpanFuncs[i])(gc);
// }
fcp = colors;
tcp = gc->polygon.shader.colors;
if (gc->modes.rgbMode) {
for (i = 0; i < w; i++) {
*tcp++ = *fcp++;
}
} else {
for (i = 0; i < w; i++) {
tcp->r = fcp->r;
fcp++;
tcp++;
}
}
gc->polygon.shader.cfb = &gc->backBuffer;
(*gc->backBuffer.storeStippledSpan)(gc);
// for (i = n; i < m; i++) {
// (*gc->procs.span.stippledSpanFuncs[i])(gc);
// }
return GL_FALSE;
}
/*
** Perform scissoring on the incoming span, advancing parameter
** values only if necessary.
**
** Returns GL_TRUE if span was entirely (or sometimes when partially) clipped,
** GL_FALSE otherwise.
*/
GLboolean FASTCALL __glClipSpan(__GLcontext *gc)
{
GLint clipX0, clipX1, delta;
GLint x, xr;
GLint w, w2;
GLboolean stippled;
w = gc->polygon.shader.length;
x = gc->polygon.shader.frag.x;
stippled = GL_FALSE;
clipX0 = gc->transform.clipX0;
clipX1 = gc->transform.clipX1;
xr = x + w;
if ((x < clipX0) || (xr > clipX1)) {
/*
** Span needs to be scissored in some fashion
*/
if ((xr <= clipX0) || (x >= clipX1)) {
/* Scissor out the entire span */
gc->polygon.shader.done = GL_TRUE;
return GL_TRUE;
}
if (xr > clipX1) {
/*
** Span is clipped by the right edge of the scissor. This is
** easy, we will simply reduce the width of this span!
*/
w = clipX1 - x;
}
if (x < clipX0) {
__GLstippleWord bit, outMask, *osp;
GLint count;
/*
** Span is clipped by the left edge of the scissor. This is hard.
** We have two choices.
**
** 1) We can stipple the first half of the span.
** 2) We can bump all of the iterator values.
**
** The problem with approach number 2 is that the routine
** which originally asks to have a span processed has assumed
** that the iterator values will not be munged. So, if we
** wanted to implement 2 (which would make this case faster),
** we would need to change that assumption, and make the higher
** routine shadow all of the iterator values, which would slow
** down all paths. This is probably not a good trade to speed
** this path up, since this path will only occur when the scissor
** region (or window) is smaller than the viewport, and this span
** happens to hit the left edge of the scissor region (or window).
**
** Therefore, we choose number 1.
*/
delta = clipX0 - x;
osp = gc->polygon.shader.stipplePat;
w2 = w;
while (w2) {
count = w2;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w2 -= count;
outMask = (__GLstippleWord) ~0;
bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
while (--count >= 0) {
if (delta > 0) {
delta--;
outMask &= ~bit;
}
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
*osp++ = outMask;
}
stippled = GL_TRUE;
}
}
assert(w <= __GL_MAX_MAX_VIEWPORT);
gc->polygon.shader.length = w;
return stippled;
}
/*
** Generate the polygon stipple for a span.
*/
GLboolean FASTCALL __glStippleSpan(__GLcontext *gc)
{
__GLstippleWord stipple;
__GLstippleWord *sp;
GLint count;
GLint shift;
GLint w;
w = gc->polygon.shader.length;
if (gc->constants.yInverted) {
stipple = gc->polygon.stipple[(gc->constants.height -
(gc->polygon.shader.frag.y - gc->constants.viewportYAdjust)-1)
& (__GL_STIPPLE_BITS-1)];
} else {
stipple = gc->polygon.stipple[gc->polygon.shader.frag.y &
(__GL_STIPPLE_BITS-1)];
}
shift = gc->polygon.shader.frag.x & (__GL_STIPPLE_BITS - 1);
#ifdef __GL_STIPPLE_MSB
stipple = (stipple << shift) | (stipple >> (__GL_STIPPLE_BITS - shift));
#else
stipple = (stipple >> shift) | (stipple << (__GL_STIPPLE_BITS - shift));
#endif
if (stipple == 0) {
/* No point in continuing */
gc->polygon.shader.done = GL_TRUE;
return GL_TRUE;
}
/* Replicate stipple word */
count = w;
sp = gc->polygon.shader.stipplePat;
while (count > 0) {
*sp++ = stipple;
count -= __GL_STIPPLE_BITS;
}
return GL_TRUE;
}
/*
** Generate the polygon stipple for a stippled span.
*/
GLboolean FASTCALL __glStippleStippledSpan(__GLcontext *gc)
{
__GLstippleWord stipple;
__GLstippleWord *sp;
GLint count;
GLint shift;
GLint w;
w = gc->polygon.shader.length;
if (gc->constants.yInverted) {
stipple = gc->polygon.stipple[(gc->constants.height -
(gc->polygon.shader.frag.y - gc->constants.viewportYAdjust)-1)
& (__GL_STIPPLE_BITS-1)];
} else {
stipple = gc->polygon.stipple[gc->polygon.shader.frag.y &
(__GL_STIPPLE_BITS-1)];
}
shift = gc->polygon.shader.frag.x & (__GL_STIPPLE_BITS - 1);
#ifdef __GL_STIPPLE_MSB
stipple = (stipple << shift) | (stipple >> (__GL_STIPPLE_BITS - shift));
#else
stipple = (stipple >> shift) | (stipple << (__GL_STIPPLE_BITS - shift));
#endif
if (stipple == 0) {
/* No point in continuing */
gc->polygon.shader.done = GL_TRUE;
return GL_TRUE;
}
/* Replicate stipple word */
count = w;
sp = gc->polygon.shader.stipplePat;
while (count > 0) {
*sp++ &= stipple;
count -= __GL_STIPPLE_BITS;
}
return GL_FALSE;
}
/************************************************************************/
/*
** Alpha test span uses a lookup table to do the alpha test function.
** Output a stipple with 1's where the test passed, and 0's where the
** test failed.
*/
GLboolean FASTCALL __glAlphaTestSpan(__GLcontext *gc)
{
GLubyte *atft;
GLint failed, count, ia;
__GLstippleWord bit, outMask, *osp;
__GLcolor *cp;
GLint maxAlpha;
GLint w;
w = gc->polygon.shader.length;
atft = &gc->frontBuffer.alphaTestFuncTable[0];
cp = gc->polygon.shader.colors;
maxAlpha = gc->constants.alphaTestSize - 1;
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) {
ia = (GLint)(gc->constants.alphaTableConv * cp->a);
if (ia < 0) ia = 0;
if (ia > maxAlpha) ia = maxAlpha;
if (!atft[ia]) {
/* Test failed */
outMask &= ~bit;
failed++;
}
cp++;
#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;
}
/*
** Stippled form of alpha test span that checks the stipple at each
** pixel and avoids the test where the stipple disallows it.
*/
GLboolean FASTCALL __glAlphaTestStippledSpan(__GLcontext *gc)
{
GLubyte *atft;
GLint count, ia, failed;
__GLstippleWord bit, inMask, outMask, *isp;
__GLcolor *cp;
GLint maxAlpha;
GLint w;
w = gc->polygon.shader.length;
isp = gc->polygon.shader.stipplePat;
atft = &gc->frontBuffer.alphaTestFuncTable[0];
cp = gc->polygon.shader.colors;
maxAlpha = gc->constants.alphaTestSize - 1;
failed = 0;
while (w) {
count = w;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w -= count;
inMask = *isp;
outMask = (__GLstippleWord) ~0;
bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
while (--count >= 0) {
if (inMask & bit) {
ia = (GLint)(gc->constants.alphaTableConv * cp->a);
if (ia < 0) ia = 0;
if (ia > maxAlpha) ia = maxAlpha;
if (!atft[ia]) {
/* Test failed */
outMask &= ~bit;
failed++;
}
} else failed++;
cp++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
*isp++ = outMask & inMask;
}
if (failed != gc->polygon.shader.length) {
/* Call next stippled span proc */
return GL_FALSE;
}
return GL_TRUE;
}
/************************************************************************/
/*
** Perform stencil testing. Apply test fail operation as we go.
** Generate a stipple with 1's where the test passed and 0's where the
** test failed.
*/
GLboolean FASTCALL __glStencilTestSpan(__GLcontext *gc)
{
__GLstencilCell *tft, *sfb, *fail, cell;
GLint count, failed;
__GLstippleWord bit, outMask, *osp;
GLint w;
w = gc->polygon.shader.length;
sfb = gc->polygon.shader.sbuf;
tft = gc->stencilBuffer.testFuncTable;
#ifdef NT
if (!tft)
return GL_FALSE;
#endif // NT
fail = gc->stencilBuffer.failOpTable;
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) {
cell = sfb[0];
/* test func table already anded cell values with mask */
if (!tft[cell]) {
/* Test failed */
outMask &= ~bit;
sfb[0] = fail[cell];
failed++;
}
sfb++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
*osp++ = outMask;
}
if (failed == 0) {
return GL_FALSE;
} else {
if (failed != gc->polygon.shader.length) {
/* Call next proc */
return GL_TRUE;
}
}
gc->polygon.shader.done = GL_TRUE;
return GL_TRUE;
}
/*
** Stippled form of stencil test.
*/
GLboolean FASTCALL __glStencilTestStippledSpan(__GLcontext *gc)
{
__GLstencilCell *tft, *sfb, *fail, cell;
GLint failed, count;
__GLstippleWord bit, inMask, outMask, *sp;
GLuint smask;
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
sfb = gc->polygon.shader.sbuf;
tft = gc->stencilBuffer.testFuncTable;
#ifdef NT
if (!tft)
return GL_FALSE;
#endif // NT
fail = gc->stencilBuffer.failOpTable;
smask = gc->state.stencil.mask;
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) {
cell = sfb[0];
if (!tft[cell & smask]) {
/* Test failed */
outMask &= ~bit;
sfb[0] = fail[cell];
failed++;
}
} else failed++;
sfb++;
#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 __glDepthTestSpan(__GLcontext *gc)
{
__GLzValue z, dzdx, *zfb;
GLint failed, count;
GLboolean (FASTCALL *testFunc)( __GLzValue, __GLzValue * );
GLint stride = gc->depthBuffer.buf.elementSize;
__GLstippleWord bit, outMask, *osp;
GLboolean writeEnabled, passed;
GLint w;
w = gc->polygon.shader.length;
zfb = gc->polygon.shader.zbuf;
testFunc = gc->procs.DTPixel;
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( (*testFunc)(z, zfb) == GL_FALSE ) {
outMask &= ~bit;
failed++;
}
z += dzdx;
(GLint) zfb += stride;
#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;
}
/*
** Stippled form of depth test span, when stenciling is disabled.
*/
GLboolean FASTCALL __glDepthTestStippledSpan(__GLcontext *gc)
{
__GLzValue z, dzdx, *zfb;
GLint failed, count;
GLboolean (FASTCALL *testFunc)( __GLzValue, __GLzValue * );
GLint stride = gc->depthBuffer.buf.elementSize;
__GLstippleWord bit, inMask, outMask, *sp;
GLboolean writeEnabled, passed;
GLint w;
sp = gc->polygon.shader.stipplePat;
w = gc->polygon.shader.length;
zfb = gc->polygon.shader.zbuf;
testFunc = gc->procs.DTPixel;
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( (*testFunc)(z, zfb) == GL_FALSE ) {
outMask &= ~bit;
failed++;
}
} else failed++;
z += dzdx;
(GLubyte *) zfb += stride;
#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 enabled.
*/
GLboolean FASTCALL __glDepthTestStencilSpan(__GLcontext *gc)
{
__GLstencilCell *sfb, *zPassOp, *zFailOp;
__GLzValue z, dzdx, *zfb;
GLint failed, count;
GLboolean (FASTCALL *testFunc)( __GLzValue, __GLzValue * );
GLint stride = gc->depthBuffer.buf.elementSize;
__GLstippleWord bit, outMask, *osp;
GLboolean writeEnabled, passed;
GLint w;
w = gc->polygon.shader.length;
zfb = gc->polygon.shader.zbuf;
sfb = gc->polygon.shader.sbuf;
zFailOp = gc->stencilBuffer.depthFailOpTable;
#ifdef NT
if (!zFailOp)
return GL_FALSE;
#endif // NT
zPassOp = gc->stencilBuffer.depthPassOpTable;
testFunc = gc->procs.DTPixel;
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( (*testFunc)(z, zfb) ) {
sfb[0] = zPassOp[sfb[0]];
} else {
sfb[0] = zFailOp[sfb[0]];
outMask &= ~bit;
failed++;
}
z += dzdx;
(GLubyte *) zfb += stride;
sfb++;
#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 __glDepthTestStencilStippledSpan(__GLcontext *gc)
{
__GLstencilCell *sfb, *zPassOp, *zFailOp;
__GLzValue z, dzdx, *zfb;
GLint failed, count;
GLboolean (FASTCALL *testFunc)( __GLzValue, __GLzValue * );
GLint stride = gc->depthBuffer.buf.elementSize;
__GLstippleWord bit, inMask, outMask, *sp;
GLboolean writeEnabled, passed;
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
zfb = gc->polygon.shader.zbuf;
sfb = gc->polygon.shader.sbuf;
testFunc = gc->procs.DTPixel;
zFailOp = gc->stencilBuffer.depthFailOpTable;
#ifdef NT
if (!zFailOp)
return GL_FALSE;
#endif // NT
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( (*testFunc)(z, zfb) ) {
sfb[0] = zPassOp[sfb[0]];
} else {
sfb[0] = zFailOp[sfb[0]];
outMask &= ~bit;
failed++;
}
} else failed++;
z += dzdx;
(GLubyte *) zfb += stride;
sfb++;
#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;
}
/*
** Apply stencil depth pass op when depth testing is off.
*/
GLboolean FASTCALL __glDepthPassSpan(__GLcontext *gc)
{
__GLstencilCell *sfb, *zPassOp;
GLint count;
GLint w;
w = gc->polygon.shader.length;
sfb = gc->polygon.shader.sbuf;
zPassOp = gc->stencilBuffer.depthPassOpTable;
#ifdef NT
if (!zPassOp)
return GL_FALSE;
#endif // NT
count = w;
while (--count >= 0) {
sfb[0] = zPassOp[sfb[0]];
sfb++;
}
return GL_FALSE;
}
/*
** Apply stencil depth pass op when depth testing is off.
*/
GLboolean FASTCALL __glDepthPassStippledSpan(__GLcontext *gc)
{
__GLstencilCell *sfb, *zPassOp;
GLint count;
__GLstippleWord bit, inMask, *sp;
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
sfb = gc->polygon.shader.sbuf;
zPassOp = gc->stencilBuffer.depthPassOpTable;
#ifdef NT
if (!zPassOp)
return GL_FALSE;
#endif // NT
while (w) {
count = w;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w -= count;
inMask = *sp++;
bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
while (--count >= 0) {
if (inMask & bit) {
sfb[0] = zPassOp[sfb[0]];
}
sfb++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
}
/* Call next proc */
return GL_FALSE;
}
/************************************************************************/
GLboolean FASTCALL __glShadeCISpan(__GLcontext *gc)
{
__GLcolor *cp;
__GLfloat r, drdx;
GLint w;
w = gc->polygon.shader.length;
r = gc->polygon.shader.frag.color.r;
drdx = gc->polygon.shader.drdx;
cp = gc->polygon.shader.colors;
while (--w >= 0) {
cp->r = r;
r += drdx;
cp++;
}
return GL_FALSE;
}
GLboolean FASTCALL __glShadeRGBASpan(__GLcontext *gc)
{
__GLcolor *cp;
__GLfloat r, g, b, a;
__GLfloat drdx, dgdx, dbdx, dadx;
GLint w;
w = gc->polygon.shader.length;
r = gc->polygon.shader.frag.color.r;
g = gc->polygon.shader.frag.color.g;
b = gc->polygon.shader.frag.color.b;
a = gc->polygon.shader.frag.color.a;
drdx = gc->polygon.shader.drdx;
dgdx = gc->polygon.shader.dgdx;
dbdx = gc->polygon.shader.dbdx;
dadx = gc->polygon.shader.dadx;
cp = gc->polygon.shader.colors;
while (--w >= 0) {
cp->r = r;
cp->g = g;
cp->b = b;
cp->a = a;
r += drdx;
g += dgdx;
b += dbdx;
a += dadx;
cp++;
}
return GL_FALSE;
}
GLboolean FASTCALL __glFlatCISpan(__GLcontext *gc)
{
__GLcolor *cp;
__GLfloat r;
GLint w;
w = gc->polygon.shader.length;
r = gc->polygon.shader.frag.color.r;
cp = gc->polygon.shader.colors;
while (--w >= 0) {
cp->r = r;
cp++;
}
return GL_FALSE;
}
GLboolean FASTCALL __glFlatRGBASpan(__GLcontext *gc)
{
__GLcolor *cp;
__GLfloat r, g, b, a;
GLint w;
w = gc->polygon.shader.length;
r = gc->polygon.shader.frag.color.r;
g = gc->polygon.shader.frag.color.g;
b = gc->polygon.shader.frag.color.b;
a = gc->polygon.shader.frag.color.a;
cp = gc->polygon.shader.colors;
while (--w >= 0) {
cp->r = r;
cp->g = g;
cp->b = b;
cp->a = a;
cp++;
}
return GL_FALSE;
}
/************************************************************************/
GLboolean FASTCALL __glTextureSpan(__GLcontext *gc)
{
__GLcolor *cp;
__GLfloat s, t, qw;
__GLfragment tfrag;/*XXX*/
GLint w;
w = gc->polygon.shader.length;
s = gc->polygon.shader.frag.s;
t = gc->polygon.shader.frag.t;
qw = gc->polygon.shader.frag.qw;
tfrag.x = gc->polygon.shader.frag.x;/*XXX*/
tfrag.y = gc->polygon.shader.frag.y;/*XXX*/
cp = gc->polygon.shader.colors;
while (--w >= 0) {
__GLfloat sw, tw, rho;
#ifdef NT
// XXX! (mf) could separate the loops for qw=0, qw!=0
if( qw == (__GLfloat) 0.0 ) {
sw = tw = (__GLfloat) 0.0;
}
else {
sw = s / qw;
tw = t / qw;
}
#else
sw = s / qw;
tw = t / qw;
#endif
rho = (*gc->procs.calcPolygonRho)(gc, &gc->polygon.shader,
s, t, qw);
(*gc->procs.texture)(gc, cp, sw, tw, rho);
s += gc->polygon.shader.dsdx;
t += gc->polygon.shader.dtdx;
qw += gc->polygon.shader.dqwdx;
tfrag.x++;
cp++;
}
return GL_FALSE;
}
GLboolean FASTCALL __glTextureStippledSpan(__GLcontext *gc)
{
__GLstippleWord inMask, bit, *sp;
GLint count;
__GLcolor *cp;
__GLfloat s, t, qw;
__GLfragment tfrag;/*XXX*/
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
s = gc->polygon.shader.frag.s;
t = gc->polygon.shader.frag.t;
qw = gc->polygon.shader.frag.qw;
tfrag.x = gc->polygon.shader.frag.x;/*XXX*/
tfrag.y = gc->polygon.shader.frag.y;/*XXX*/
cp = gc->polygon.shader.colors;
while (w) {
count = w;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w -= count;
inMask = *sp++;
bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
while (--count >= 0) {
if (inMask & bit) {
__GLfloat sw, tw, rho;
#ifdef NT
if( qw == (__GLfloat) 0.0 ) {
sw = tw = (__GLfloat) 0.0;
}
else {
sw = s / qw;
tw = t / qw;
}
#else
sw = s / qw;
tw = t / qw;
#endif
rho = (*gc->procs.calcPolygonRho)(gc, &gc->polygon.shader,
s, t, qw);
(*gc->procs.texture)(gc, cp, sw, tw, rho);
}
s += gc->polygon.shader.dsdx;
t += gc->polygon.shader.dtdx;
qw += gc->polygon.shader.dqwdx;
tfrag.x++;
cp++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
}
return GL_FALSE;
}
/************************************************************************/
#ifdef NT_DEADCODE_PICKSPAN
/*
** Dither CI span.
*/
GLboolean FASTCALL __glDitherCISpan(__GLcontext *gc)
{
__GLcolor *cp;
GLint ix, x, y, r, maxR, frac;
GLint w;
w = gc->polygon.shader.length;
x = gc->polygon.shader.frag.x;
y = gc->polygon.shader.frag.y;
maxR = (1 << gc->modes.indexBits) - 1;
cp = gc->polygon.shader.colors;
while (--w >= 0) {
ix = __GL_DITHER_INDEX(x, y);
frac = __glDitherTable[ix];
r = ((GLint) (cp->r * __GL_DITHER_PRECISION + __glHalf) + frac)
>> __GL_DITHER_BITS;
if (r > maxR) r = maxR;
cp->r = r;
cp++;
x++;
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
#ifdef NT_DEADCODE_PICKSPAN
/*
** Dither CI stippled span.
*/
GLboolean FASTCALL __glDitherCIStippledSpan(__GLcontext *gc)
{
__GLstippleWord bit, inMask, *sp;
__GLcolor *cp;
GLint count, ix, x, y, r, maxR, frac;
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
x = gc->polygon.shader.frag.x;
y = gc->polygon.shader.frag.y;
maxR = (1 << gc->modes.indexBits) - 1;
cp = gc->polygon.shader.colors;
while (w) {
count = w;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w -= count;
inMask = *sp++;
bit = __GL_STIPPLE_SHIFT(0);
while (--count >= 0) {
if (inMask & bit) {
ix = __GL_DITHER_INDEX(x, y);
frac = __glDitherTable[ix];
r = ((GLint) (cp->r * __GL_DITHER_PRECISION + __glHalf) + frac)
>> __GL_DITHER_BITS;
if (r > maxR) r = maxR;
cp->r = r;
}
cp++;
x++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
#ifdef NT_DEADCODE_PICKSPAN
/*
** Dither RGBA span. Only works if incoming colors have already been
** scaled into their destination format.
*/
GLboolean FASTCALL __glDitherRGBASpan(__GLcontext *gc)
{
__GLcolor *cp;
GLint ix, x, y, r, g, b, a, frac;
GLint maxR, maxG, maxB, maxA;
GLint w;
w = gc->polygon.shader.length;
x = gc->polygon.shader.frag.x;
y = gc->polygon.shader.frag.y;
maxR = gc->frontBuffer.iRedScale;
maxG = gc->frontBuffer.iGreenScale;
maxB = gc->frontBuffer.iBlueScale;
maxA = gc->frontBuffer.iAlphaScale;
cp = gc->polygon.shader.colors;
while (--w >= 0) {
ix = __GL_DITHER_INDEX(x, y);
/*
** Convert the color into integers, keeping 4 bits of fractional
** precision (and rounding up).
*/
frac = __glDitherTable[ix];
r = ((GLint) (cp->r * __GL_DITHER_PRECISION + __glHalf) + frac)
>> __GL_DITHER_BITS;
if (r > maxR) r = maxR;
cp->r = r;
g = ((GLint) (cp->g * __GL_DITHER_PRECISION + __glHalf) + frac)
>> __GL_DITHER_BITS;
if (g > maxG) g = maxG;
cp->g = g;
b = ((GLint) (cp->b * __GL_DITHER_PRECISION + __glHalf) + frac)
>> __GL_DITHER_BITS;
if (b > maxB) b = maxB;
cp->b = b;
a = ((GLint) (cp->a * __GL_DITHER_PRECISION + __glHalf) + frac)
>> __GL_DITHER_BITS;
if (a > maxA) a = maxA;
cp->a = a;
cp++;
x++;
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
#ifdef NT_DEADCODE_PICKSPAN
/*
** Dither RGBA stippled span. Only works if incoming colors have already
** been scaled into their destination format.
*/
GLboolean FASTCALL __glDitherRGBAStippledSpan(__GLcontext *gc)
{
__GLstippleWord bit, inMask, *sp;
__GLcolor *cp;
GLint count, ix, x, y, r, g, b, a, frac;
GLint maxR, maxG, maxB, maxA;
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
x = gc->polygon.shader.frag.x;
y = gc->polygon.shader.frag.y;
maxR = gc->frontBuffer.iRedScale;
maxG = gc->frontBuffer.iGreenScale;
maxB = gc->frontBuffer.iBlueScale;
maxA = gc->frontBuffer.iAlphaScale;
cp = gc->polygon.shader.colors;
while (w) {
count = w;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w -= count;
inMask = *sp++;
bit = __GL_STIPPLE_SHIFT(0);
while (--count >= 0) {
if (inMask & bit) {
ix = __GL_DITHER_INDEX(x, y);
/*
** Convert the color into integers, keeping 4 bits of
** fractional precision (and rounding up).
*/
frac = __glDitherTable[ix];
r = ((GLint) (cp->r * __GL_DITHER_PRECISION + __glHalf) + frac)
>> __GL_DITHER_BITS;
if (r > maxR) r = maxR;
cp->r = r;
g = ((GLint) (cp->g * __GL_DITHER_PRECISION + __glHalf) + frac)
>> __GL_DITHER_BITS;
if (g > maxG) g = maxG;
cp->g = g;
b = ((GLint) (cp->b * __GL_DITHER_PRECISION + __glHalf) + frac)
>> __GL_DITHER_BITS;
if (b > maxB) b = maxB;
cp->b = b;
a = ((GLint) (cp->a * __GL_DITHER_PRECISION + __glHalf) + frac)
>> __GL_DITHER_BITS;
if (a > maxA) a = maxA;
cp->a = a;
}
cp++;
x++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
#ifdef NT_DEADCODE_PICKSPAN
/*
** Round CI span.
*/
GLboolean __glRoundCISpan(__GLcontext *gc)
{
__GLcolor *cp;
GLint x, y, r, maxR;
GLint w;
w = gc->polygon.shader.length;
x = gc->polygon.shader.frag.x;
y = gc->polygon.shader.frag.y;
maxR = (1 << gc->modes.indexBits) - 1;
cp = gc->polygon.shader.colors;
while (--w >= 0) {
r = (GLint)(cp->r + __glHalf);
if (r > maxR) { r = maxR; }
cp->r = r;
cp++;
x++;
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
#ifdef NT_DEADCODE_PICKSPAN
/*
** Round CI stippled span.
*/
GLboolean FASTCALL __glRoundCIStippledSpan(__GLcontext *gc)
{
__GLstippleWord bit, inMask, *sp;
__GLcolor *cp;
GLint count, x, y, r, maxR;
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
x = gc->polygon.shader.frag.x;
y = gc->polygon.shader.frag.y;
maxR = (1 << gc->modes.indexBits) - 1;
cp = gc->polygon.shader.colors;
while (w) {
count = w;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w -= count;
inMask = *sp++;
bit = __GL_STIPPLE_SHIFT(0);
while (--count >= 0) {
if (inMask & bit) {
r = (GLint)(cp->r + __glHalf);
if (r > maxR) { r = maxR; }
cp->r = r;
}
cp++;
x++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
#ifdef NT_DEADCODE_PICKSPAN
/*
** Round RGBA span. Only works if incoming colors have already been
** scaled into their destination format.
*/
GLboolean FASTCALL __glRoundRGBASpan(__GLcontext *gc)
{
__GLcolor *cp;
GLint x, y, r, g, b, a;
GLint maxR, maxG, maxB, maxA;
GLint w;
w = gc->polygon.shader.length;
x = gc->polygon.shader.frag.x;
y = gc->polygon.shader.frag.y;
maxR = gc->frontBuffer.iRedScale;
maxG = gc->frontBuffer.iGreenScale;
maxB = gc->frontBuffer.iBlueScale;
maxA = gc->frontBuffer.iAlphaScale;
cp = gc->polygon.shader.colors;
while (--w >= 0) {
r = (GLint) (cp->r + __glHalf);
if (r > maxR) r = maxR;
cp->r = r;
g = (GLint) (cp->g + __glHalf);
if (g > maxG) g = maxG;
cp->g = g;
b = (GLint) (cp->b + __glHalf);
if (b > maxB) b = maxB;
cp->b = b;
a = (GLint) (cp->a + __glHalf);
if (a > maxA) a = maxA;
cp->a = a;
cp++;
x++;
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
#ifdef NT_DEADCODE_PICKSPAN
/*
** Round RGBA stippled span. Only works if incoming colors have already
** been scaled into their destination format.
*/
GLboolean FASTCALL __glRoundRGBAStippledSpan(__GLcontext *gc)
{
__GLstippleWord bit, inMask, *sp;
__GLcolor *cp;
GLint count, x, y, r, g, b, a;
GLint maxR, maxG, maxB, maxA;
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
x = gc->polygon.shader.frag.x;
y = gc->polygon.shader.frag.y;
maxR = gc->frontBuffer.iRedScale;
maxG = gc->frontBuffer.iGreenScale;
maxB = gc->frontBuffer.iBlueScale;
maxA = gc->frontBuffer.iAlphaScale;
cp = gc->polygon.shader.colors;
while (w) {
count = w;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w -= count;
inMask = *sp++;
bit = __GL_STIPPLE_SHIFT(0);
while (--count >= 0) {
if (inMask & bit) {
r = (GLint) (cp->r + __glHalf);
if (r > maxR) r = maxR;
cp->r = r;
g = (GLint) (cp->g + __glHalf);
if (g > maxG) g = maxG;
cp->g = g;
b = (GLint) (cp->b + __glHalf);
if (b > maxB) b = maxB;
cp->b = b;
a = (GLint) (cp->a + __glHalf);
if (a > maxA) a = maxA;
cp->a = a;
}
cp++;
x++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
/************************************************************************/
#ifdef NT_DEADCODE_PICKSPAN
GLboolean FASTCALL __glLogicOpSpan(__GLcontext *gc)
{
__GLcolor *cp, *fcp;
GLint x, y, color, fbcolor;
GLint w;
w = gc->polygon.shader.length;
cp = gc->polygon.shader.colors;
fcp = gc->polygon.shader.fbcolors;
y = gc->polygon.shader.frag.y;
x = gc->polygon.shader.frag.x;
while (--w >= 0) {
color = (GLint) cp->r;
fbcolor = (GLint) fcp->r;
switch (gc->state.raster.logicOp) {
case GL_CLEAR: color = 0; break;
case GL_AND: color = color & fbcolor; break;
case GL_AND_REVERSE: color = color & (~fbcolor); break;
case GL_COPY: color = color; break;
case GL_AND_INVERTED: color = (~color) & fbcolor; break;
case GL_NOOP: color = fbcolor; break;
case GL_XOR: color = color ^ fbcolor; break;
case GL_OR: color = color | fbcolor; break;
case GL_NOR: color = ~(color | fbcolor); break;
case GL_EQUIV: color = ~(color ^ fbcolor); break;
case GL_INVERT: color = ~fbcolor; break;
case GL_OR_REVERSE: color = color | (~fbcolor); break;
case GL_COPY_INVERTED: color = ~color; break;
case GL_OR_INVERTED: color = (~color) | fbcolor; break;
case GL_NAND: color = ~(color & fbcolor); break;
case GL_SET: color = ~0; break;
}
cp->r = color;
cp++;
fcp++;
x++;
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
#ifdef NT_DEADCODE_PICKSPAN
GLboolean FASTCALL __glLogicOpStippledSpan(__GLcontext *gc)
{
__GLstippleWord bit, inMask, *sp;
__GLcolor *cp, *fcp;
GLint count, x, y, color, fbcolor;
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
cp = gc->polygon.shader.colors;
fcp = gc->polygon.shader.fbcolors;
y = gc->polygon.shader.frag.y;
x = gc->polygon.shader.frag.x;
while (w) {
count = w;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w -= count;
inMask = *sp++;
bit = __GL_STIPPLE_SHIFT(0);
while (--count >= 0) {
if (inMask & bit) {
color = (GLint) cp->r;
fbcolor = (GLint) fcp->r;
switch (gc->state.raster.logicOp) {
case GL_CLEAR: color = 0; break;
case GL_AND: color = color & fbcolor; break;
case GL_AND_REVERSE: color = color & (~fbcolor); break;
case GL_COPY: color = color; break;
case GL_AND_INVERTED: color = (~color) & fbcolor; break;
case GL_NOOP: color = fbcolor; break;
case GL_XOR: color = color ^ fbcolor; break;
case GL_OR: color = color | fbcolor; break;
case GL_NOR: color = ~(color | fbcolor); break;
case GL_EQUIV: color = ~(color ^ fbcolor); break;
case GL_INVERT: color = ~fbcolor; break;
case GL_OR_REVERSE: color = color | (~fbcolor); break;
case GL_COPY_INVERTED: color = ~color; break;
case GL_OR_INVERTED: color = (~color) | fbcolor; break;
case GL_NAND: color = ~(color & fbcolor); break;
case GL_SET: color = ~0; break;
}
cp->r = color;
}
cp++;
fcp++;
x++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
/************************************************************************/
#ifdef NT_DEADCODE_PICKSPAN
GLboolean FASTCALL __glMaskRGBASpan(__GLcontext *gc)
{
__GLcolor *cp;
__GLcolor *fcp;
GLboolean rEnable, gEnable, bEnable, aEnable;
GLint w;
w = gc->polygon.shader.length;
rEnable = gc->state.raster.rMask;
gEnable = gc->state.raster.gMask;
bEnable = gc->state.raster.bMask;
aEnable = gc->state.raster.aMask;
cp = gc->polygon.shader.colors;
fcp = gc->polygon.shader.fbcolors;
while (--w >= 0) {
cp->r = rEnable ? cp->r : fcp->r;
cp->g = gEnable ? cp->g : fcp->g;
cp->b = bEnable ? cp->b : fcp->b;
cp->a = aEnable ? cp->a : fcp->a;
cp++;
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN
#ifdef NT_DEADCODE_PICKSPAN
GLboolean FASTCALL __glMaskCISpan(__GLcontext *gc)
{
__GLcolor *cp;
__GLcolor *fcp;
GLuint keepMask, changeMask, r, fr;
GLint w;
w = gc->polygon.shader.length;
changeMask = gc->state.raster.writeMask;
keepMask = __GL_MASK_INDEXI(gc, ~changeMask);
cp = gc->polygon.shader.colors;
fcp = gc->polygon.shader.fbcolors;
while (--w >= 0) {
r = (GLuint) cp->r;
fr = (GLuint) fcp->r;
cp->r = (r & changeMask) | (fr & keepMask);
cp++;
}
return GL_FALSE;
}
#endif // NT_DEADCODE_PICKSPAN