windows-nt/Source/XPSP1/NT/multimedia/opengl/server/inc/span.h
2020-09-26 16:20:57 +08:00

399 lines
12 KiB
C

/******************************Module*Header*******************************\
* Module Name: span.h
*
* This include file is used to generate various flavors of textured and
* shaded spans, or scanlines.
*
* 14-Oct-1994 mikeke Combined span_t.h and span_s.h to share common
* code. Speeded things up a little. Had a little
* fun with the C preprocessor.
* 11-April-1994 Otto Berkes [ottob] Created
*
* Copyright (c) 1994 Microsoft Corporation
\**************************************************************************/
#undef STRING1
#undef STRING2
#undef STRING3
#undef STRING4
#if GENERIC
void FASTCALL __fastGenSpan
#else
#if ZBUFFER
#define STRING1 __fastGenMask
#else
#define STRING1 __fastGen
#endif
#if TEXTURE
#if SHADE
#define STRING2 Tex
#else
#define STRING2 TexDecal
#endif
#elif RGBMODE
#define STRING2 RGB
#else
#define STRING2 CI
#endif
#if DITHER
#define STRING3 STRCAT2(COLORFORMAT, Dith)
#else
#define STRING3 COLORFORMAT
#endif
#define STRING4 Span
void FASTCALL STRCAT4(STRING1, STRING2, STRING3, STRING4)
#endif
(__GLGENcontext *gengc)
{
#if (SHADE) || !(RGBMODE) || (TEXTURE && DITHER)
ULONG rAccum;
LONG rDelta;
#if RGBMODE
ULONG gAccum;
ULONG bAccum;
LONG gDelta;
LONG bDelta;
#endif
#endif
#if TEXTURE
LONG sAccum;
LONG tAccum;
LONG sDelta;
LONG tDelta;
ULONG tShift;
ULONG sMask, tMask;
#endif
ULONG rShift;
ULONG rBits;
#if RGBMODE
ULONG gShift;
ULONG gBits;
ULONG bShift;
ULONG bBits;
#endif
BYTE *pPix;
BYTE *texAddr;
BYTE *texBits;
LONG count;
LONG totalCount;
#if DITHER
PDWORD pdither;
#if (BPP == 24) || (GENERIC)
DWORD iDither;
#endif
#endif
#if (BPP == 8) || (GENERIC)
BYTE *pXlat;
#elif (!RGBMODE)
ULONG *pXlat;
#endif
#if GENERIC
DWORD flags = GENACCEL(gengc).flags;
DWORD bpp = GENACCEL(gengc).bpp;
#endif
#if GENERIC
if (flags & GEN_TEXTURE)
#endif
#if TEXTURE
{
__GLtexture *tex = ((__GLcontext *)gengc)->texture.currentTexture;
sMask = GENACCEL(gengc).sMask;
tMask = GENACCEL(gengc).tMask;
tShift = GENACCEL(gengc).tShift;
sDelta = GENACCEL(gengc).spanDelta.s;
tDelta = GENACCEL(gengc).spanDelta.t;
sAccum = GENACCEL(gengc).spanValue.s;
tAccum = GENACCEL(gengc).spanValue.t;
#if !(SHADE) && !(DITHER) && ((BPP == 8) || (BPP == 16))
texAddr = (BYTE *)GENACCEL(gengc).texImageReplace;
#else
texAddr = (BYTE *)GENACCEL(gengc).texImage;
#endif
}
#endif
// get color deltas and accumulators
#ifndef RSHIFT
rShift = gengc->gsurf.pfd.cRedShift;
rBits = gengc->gsurf.pfd.cRedBits;
#if RGBMODE
gShift = gengc->gsurf.pfd.cGreenShift;
gBits = gengc->gsurf.pfd.cGreenBits;
bShift = gengc->gsurf.pfd.cBlueShift;
bBits = gengc->gsurf.pfd.cBlueBits;
#endif
#endif
#if (GENERIC)
if (!(flags & GEN_SHADE) &&
(flags & (GEN_TEXTURE | GEN_DITHER)) == (GEN_TEXTURE | GEN_DITHER)) {
rAccum = (GENACCEL(gengc).spanValue.r >> rBits) & 0xff00;
gAccum = (GENACCEL(gengc).spanValue.g >> gBits) & 0xff00;
bAccum = (GENACCEL(gengc).spanValue.b >> bBits) & 0xff00;
rDelta = 0;
gDelta = 0;
bDelta = 0;
} else {
rAccum = GENACCEL(gengc).spanValue.r;
gAccum = GENACCEL(gengc).spanValue.g;
bAccum = GENACCEL(gengc).spanValue.b;
rDelta = GENACCEL(gengc).spanDelta.r;
gDelta = GENACCEL(gengc).spanDelta.g;
bDelta = GENACCEL(gengc).spanDelta.b;
}
#else
#if !(SHADE) && (TEXTURE) && (DITHER)
#ifndef RSHIFT
rAccum = (GENACCEL(gengc).spanValue.r >> rBits) & 0xff00;
gAccum = (GENACCEL(gengc).spanValue.g >> gBits) & 0xff00;
bAccum = (GENACCEL(gengc).spanValue.b >> bBits) & 0xff00;
#else
rAccum = (GENACCEL(gengc).spanValue.r >> RBITS) & 0xff00;
gAccum = (GENACCEL(gengc).spanValue.g >> GBITS) & 0xff00;
bAccum = (GENACCEL(gengc).spanValue.b >> BBITS) & 0xff00;
#endif
#else
#if (SHADE) || !(RGBMODE)
rAccum = GENACCEL(gengc).spanValue.r;
#if RGBMODE
gAccum = GENACCEL(gengc).spanValue.g;
bAccum = GENACCEL(gengc).spanValue.b;
#endif
#endif
#endif
#if (SHADE) || !(RGBMODE)
rDelta = GENACCEL(gengc).spanDelta.r;
#if RGBMODE
gDelta = GENACCEL(gengc).spanDelta.g;
bDelta = GENACCEL(gengc).spanDelta.b;
#endif
#endif
#endif
// get address of destination
if (GENACCEL(gengc).flags & SURFACE_TYPE_DIB) {
pPix = GENACCEL(gengc).pPix +
gengc->gc.polygon.shader.frag.x * (BPP / 8);
} else {
pPix = gengc->ColorsBits;
}
// set up pointer to translation table as needed
#if GENERIC
if ((bpp != 8) && (!(flags & GEN_RGBMODE))) {
pXlat = gengc->pajTranslateVector + sizeof(DWORD);
}
#else
#if (BPP == 8)
// No need to set up xlat vector
#elif (!RGBMODE)
pXlat = (ULONG *)(gengc->pajTranslateVector + sizeof(DWORD));
#endif
#endif
#if GENERIC
if (GENACCEL(gengc).flags & GEN_DITHER) {
// LATER !!! mikeke
// fix this so the destination is always aligned with the x value
// !!! make sure this is correct in generic case
// look at flat it assumes alignment
//
if (GENACCEL(gengc).flags & GEN_TEXTURE)
pdither = ditherTexture;
else
pdither = ditherShade;
pdither += (gengc->gc.polygon.shader.frag.y & 0x3) * 8;
iDither = gengc->gc.polygon.shader.frag.x & 0x3;
} else {
// LATER !!! mikeke
// add these outside of the loop
if (!(GENACCEL(gengc).flags & GEN_TEXTURE)) {
rAccum += 0x0800;
gAccum += 0x0800;
bAccum += 0x0800;
}
//pdither = 0;
}
#else
#if DITHER
// LATER !!! mikeke
// fix this so the destination is always aligned with the x value
// !!! make sure this is correct in generic case
// look at flat it assumes alignment
//
#if (BPP == 24)
pdither = (gengc->gc.polygon.shader.frag.y & 0x3) * 8
#if (TEXTURE)
+ ditherTexture
#else
+ ditherShade
#endif
;
iDither = gengc->gc.polygon.shader.frag.x & 0x3;
#else
pdither = (gengc->gc.polygon.shader.frag.y & 0x3) * 8
#if (TEXTURE)
+ ditherTexture
#else
+ ditherShade
#endif
+ ((
(gengc->gc.polygon.shader.frag.x & 0x3)
- (((ULONG_PTR)pPix / (BPP / 8)) & 0x3)
) & 0x3 );
#endif
#else
// LATER !!! mikeke
// add these outside of the loop
#if !(RGBMODE)
rAccum += 0x0800;
#else //RGBMODE
#if (TEXTURE) && !(GENERIC)
#else //!TEXTURE
rAccum += 0x0800;
gAccum += 0x0800;
bAccum += 0x0800;
#endif //TEXTURE
#endif //RGBMODE
#endif
#endif
#if GENERIC
{
ULONG *pMask;
pMask = gengc->gc.polygon.shader.stipplePat;
for (totalCount = gengc->gc.polygon.shader.length;
totalCount > 0; totalCount -= 32
) {
ULONG maskTest;
ULONG mask = *pMask++;
if (mask == 0) {
#if (SHADE) || !(RGBMODE)
rAccum += (rDelta << 5);
#if RGBMODE
gAccum += (gDelta << 5);
bAccum += (bDelta << 5);
#endif
#endif
#if TEXTURE
sAccum += (sDelta << 5);
tAccum += (tDelta << 5);
#endif
//iDither = (iDither + 32) & 0x3;
pPix += (32 * (BPP / 8));
} else {
maskTest = 0x80000000;
if ((count = totalCount) > 32)
count = 32;
for (; count; count--, maskTest >>= 1) {
if (mask & maskTest) {
#include "spangen.h"
}
#include "span3.h"
}
}
}
}
#elif ZBUFFER
{
GLuint zAccum = gengc->gc.polygon.shader.frag.z;
GLint zDelta = gengc->gc.polygon.shader.dzdx;
PBYTE zbuf = (PBYTE)gengc->gc.polygon.shader.zbuf;
if (GENACCEL(gengc).flags & GEN_LESS) {
if (gengc->gc.modes.depthBits == 16) {
for (count = gengc->gc.polygon.shader.length;;) {
if ( ((__GLz16Value)(zAccum >> Z16_SHIFT)) < *((__GLz16Value*)zbuf) ) {
*((__GLz16Value*)zbuf) = ((__GLz16Value)(zAccum >> Z16_SHIFT));
#include "span2.h"
}
if (--count == 0)
return;
zbuf += 2;
zAccum += zDelta;
#include "span3.h"
}
} else {
for (count = gengc->gc.polygon.shader.length;;) {
if ( zAccum < *((GLuint*)zbuf) ) {
*((GLuint*)zbuf) = zAccum;
#include "span2.h"
}
if (--count == 0)
return;
zbuf += 4;
zAccum += zDelta;
#include "span3.h"
}
}
} else {
if (gengc->gc.modes.depthBits == 16) {
for (count = gengc->gc.polygon.shader.length;;) {
if ( ((__GLz16Value)(zAccum >> Z16_SHIFT)) <= *((__GLz16Value*)zbuf) ) {
*((__GLz16Value*)zbuf) = ((__GLz16Value)(zAccum >> Z16_SHIFT));
#include "span2.h"
}
if (--count == 0)
return;
zbuf += 2;
zAccum += zDelta;
#include "span3.h"
}
} else {
for (count = gengc->gc.polygon.shader.length;;) {
if ( zAccum <= *((GLuint*)zbuf) ) {
*((GLuint*)zbuf) = zAccum;
#include "span2.h"
}
if (--count == 0)
return;
zbuf += 4;
zAccum += zDelta;
#include "span3.h"
}
}
}
}
#else
for (count = gengc->gc.polygon.shader.length;;) {
#include "span2.h"
if (--count == 0)
return;
#include "span3.h"
}
#endif
}
#undef ditherVal