Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1137 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
/*
** 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;
}
}
ASSERTOPENGL(w <= __GL_MAX_MAX_VIEWPORT,
"Too many pixels generated by clip\n");
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->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->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;
(GLubyte *) 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;
}
/************************************************************************/
// Special case where qw = 0 for the span
GLboolean FASTCALL __glTextureSpanZeroQW(__GLcontext *gc)
{
__GLcolor *cp;
GLint w;
w = gc->polygon.shader.length;
cp = gc->polygon.shader.colors;
while (--w >= 0) {
// No need to compute rho here - it is undefined for qw = 0
(*gc->procs.texture)(gc, cp, __glZero, __glZero, __glZero);
cp++;
}
return GL_FALSE;
}
GLboolean FASTCALL __glTextureSpan(__GLcontext *gc)
{
__GLcolor *cp;
__GLfloat s, t, qw;
GLint w;
qw = gc->polygon.shader.frag.qw;
if( qw == (__GLfloat) 0.0 ) {
return __glTextureSpanZeroQW( gc );
}
w = gc->polygon.shader.length;
s = gc->polygon.shader.frag.s;
t = gc->polygon.shader.frag.t;
cp = gc->polygon.shader.colors;
while (--w >= 0) {
__GLfloat sw, tw, rho, qwinv;
qwinv = __glOne / qw;
sw = s * qwinv;
tw = t * qwinv;
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;
cp++;
}
return GL_FALSE;
}
GLboolean FASTCALL __glTextureStippledSpan(__GLcontext *gc)
{
__GLstippleWord inMask, bit, *sp;
GLint count;
__GLcolor *cp;
__GLfloat s, t, qw;
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;
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, qwinv;
if( qw == (__GLfloat) 0.0 ) {
sw = tw = (__GLfloat) 0.0;
}
else {
qwinv = __glOne / qw;
sw = s * qwinv;
tw = t * qwinv;
}
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;
cp++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
}
return GL_FALSE;
}