|
|
/******************************Module*Header*******************************\
* Module Name: span_f.h * * * * This include file is used to generate various flavors of flat-shaded * * spans, or scanlines. The variations cover RGB/Color-indexed operation, * * dithering, and pixel-depth. Not your typical include file. * * * * Created: 24-Feb-1994 * * Author: Otto Berkes [ottob] * * * * Copyright (c) 1994 Microsoft Corporation * \**************************************************************************/
#undef STRING1
#undef STRING2
#undef STRING3
#undef STRING4
#if ZBUFFER
#define STRING1 __fastGenMask
#else
#define STRING1 __fastGen
#endif
#if RGBMODE
#define STRING2 RGB
#else
#define STRING2 CI
#endif
#if DITHER
#define STRING3 STRCAT2(BPP, Dith)
#else
#define STRING3 BPP
#endif
#define STRING4 FlatSpan
#undef OLDTEXTURE
#define OLDTEXTURE 0
void FASTCALL STRCAT4(STRING1, STRING2, STRING3, STRING4) (__GLGENcontext *gengc) { ULONG rAccum; ULONG rShift; #if RGBMODE
ULONG gAccum; ULONG bAccum; ULONG gShift; ULONG bShift; #endif
GENACCEL *pGenAccel; __GLcolorBuffer *cfb; BYTE *pPix;
#if (BPP == 8)
BYTE *pXlat; #elif (!RGBMODE)
ULONG *pXlat; #endif
#if DITHER
ULONG ditherShift; ULONG ditherRow; ULONG ditherVal; #endif
LONG count, cDith; ULONG color1;
#if DITHER
#if (RGBMODE) || (BPP > 8)
ULONG color2; ULONG color3; ULONG color4; #endif
#elif (BPP == 24)
ULONG color2; ULONG color3; #endif
pGenAccel = (GENACCEL *)(gengc->pPrivateArea); cfb = gengc->gc.polygon.shader.cfb;
// get color deltas and accumulators
rAccum = pGenAccel->spanValue.r; rShift = cfb->redShift; #if RGBMODE
gAccum = pGenAccel->spanValue.g; bAccum = pGenAccel->spanValue.b; gShift = cfb->greenShift; bShift = cfb->blueShift; #endif
// get address of destination
if (pGenAccel->flags & SURFACE_TYPE_DIB) { pPix = pGenAccel->pPix + gengc->gc.polygon.shader.frag.x * (BPP / 8); } else { pPix = gengc->ColorsBits; }
// set up pointer to translation table as needed
#if (BPP == 8)
pXlat = gengc->pajTranslateVector; #elif (!RGBMODE)
pXlat = (ULONG *)(gengc->pajTranslateVector + sizeof(DWORD)); #endif
cDith = ( gengc->gc.polygon.shader.length >= 4 ? 4 : gengc->gc.polygon.shader.length);
#if DITHER
ditherRow = Dither_4x4[gengc->gc.polygon.shader.frag.y & 0x3]; ditherShift = (gengc->gc.polygon.shader.frag.x & 0x3) << 3;
#if RGBMODE
ditherVal = ((ditherRow >> ditherShift) & 0xff) << 8; color1 = (((rAccum + ditherVal) >> 16) << rShift) | (((gAccum + ditherVal) >> 16) << gShift) | (((bAccum + ditherVal) >> 16) << bShift);
#if (BPP == 8)
color1 = *(pXlat + (color1 & 0xff)); #endif
if (--cDith) { ditherShift = (ditherShift + 8) & 0x18; ditherVal = ((ditherRow >> ditherShift) & 0xff) << 8; color2 = (((rAccum + ditherVal) >> 16) << rShift) | (((gAccum + ditherVal) >> 16) << gShift) | (((bAccum + ditherVal) >> 16) << bShift);
#if (BPP == 8)
color1 |= (*(pXlat + (color2 & 0xff))) << 8; #endif
if (--cDith) { ditherShift = (ditherShift + 8) & 0x18; ditherVal = ((ditherRow >> ditherShift) & 0xff) << 8; color3 = (((rAccum + ditherVal) >> 16) << rShift) | (((gAccum + ditherVal) >> 16) << gShift) | (((bAccum + ditherVal) >> 16) << bShift);
#if (BPP == 8)
color1 |= (*(pXlat + (color3 & 0xff))) << 16; #endif
if (--cDith) { ditherShift = (ditherShift + 8) & 0x18; ditherVal = ((ditherRow >> ditherShift) & 0xff) << 8; color4 = (((rAccum + ditherVal) >> 16) << rShift) | (((gAccum + ditherVal) >> 16) << gShift) | (((bAccum + ditherVal) >> 16) << bShift); #if (BPP == 8)
color1 |= (*(pXlat + (color4 & 0xff))) << 24; #endif
} } } #else //!RGBMODE
ditherVal = ((ditherRow >> ditherShift) & 0xff) << 8;
#if (BPP == 8)
color1 = *(pXlat + (((rAccum + ditherVal) >> 16) & 0xff)); #else
color1 = *(pXlat + (((rAccum + ditherVal) >> 16) & 0xfff)); #endif
if (--cDith) { ditherShift = (ditherShift + 8) & 0x18; ditherVal = ((ditherRow >> ditherShift) & 0xff) << 8;
#if (BPP == 8)
color1 |= (*(pXlat + (((rAccum + ditherVal) >> 16) & 0xff)) << 8); #else
color2 = *(pXlat + (((rAccum + ditherVal) >> 16) & 0xfff)); #endif
if (--cDith) { ditherShift = (ditherShift + 8) & 0x18; ditherVal = ((ditherRow >> ditherShift) & 0xff) << 8;
#if (BPP == 8)
color1 |= (*(pXlat + (((rAccum + ditherVal) >> 16) & 0xff)) << 16); #else
color3= *(pXlat + (((rAccum + ditherVal) >> 16) & 0xfff)); #endif
if (--cDith) { ditherShift = (ditherShift + 8) & 0x18; ditherVal = ((ditherRow >> ditherShift) & 0xff) << 8;
#if (BPP == 8)
color1 |= (*(pXlat + (((rAccum + ditherVal) >> 16) & 0xff)) << 24); #else
color4 = *(pXlat + (((rAccum + ditherVal) >> 16) & 0xfff)); #endif
} } } #endif //!RGBMODE
#else //!DITHER
#if RGBMODE
color1 = (((rAccum + 0x0800) >> 16) << rShift) | (((gAccum + 0x0800) >> 16) << gShift) | (((bAccum + 0x0800) >> 16) << bShift);
#if (BPP == 8)
color1 = *(pXlat + (color1 & 0xff)); #endif
#if (BPP == 16)
color1 = color1 | (color1 << 16); #elif (BPP == 24)
color2 = color1 >> 8; color3 = color1 >> 16; #endif
#else //!RGBMODE
#if (BPP == 8)
color1 = *(pXlat + (((rAccum + 0x0800) >> 16) & 0xff)); #else
color1 = *(pXlat + (((rAccum + 0x0800) >> 16) & 0xfff)); #endif
#if (BPP == 16)
color1 = color1 | (color1 << 16); #elif (BPP == 24)
color2 = color1 >> 8; color3 = color1 >> 16; #endif
#endif //!RGBMODE
#endif //!DITHER
#if (ZBUFFER)
if (pGenAccel->flags & GEN_FASTZBUFFER) { GLuint zAccum = gengc->gc.polygon.shader.frag.z; GLint zDelta = gengc->gc.polygon.shader.dzdx; PBYTE zbuf = (PBYTE)gengc->gc.polygon.shader.zbuf; count = gengc->gc.polygon.shader.length;
if (gengc->gc.modes.depthBits == 16) { #if DITHER
for (;;) { if ( ((__GLz16Value)(zAccum >> Z16_SHIFT)) <= *((__GLz16Value*)zbuf) ) { *((__GLz16Value*)zbuf) = ((__GLz16Value)(zAccum >> Z16_SHIFT));
#if (BPP == 8)
*pPix = (BYTE)color1; #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color1; #elif (BPP == 24)
*pPix = (BYTE)color1; *(pPix + 1) = (BYTE)(color1 >> 8); *(pPix + 2) = (BYTE)(color1 >> 16); #else
*((DWORD *)pPix) = color1; #endif
}
pPix += (BPP / 8); if (--count <= 0) break;
zAccum += zDelta; zbuf += 2; if ( ((__GLz16Value)(zAccum >> Z16_SHIFT)) <= *((__GLz16Value*)zbuf) ) { *((__GLz16Value*)zbuf) = ((__GLz16Value)(zAccum >> Z16_SHIFT));
#if (BPP == 8)
*pPix = (BYTE)(color1 >> 8); #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color2; #elif (BPP == 24)
*pPix = (BYTE)color2; *(pPix + 1) = (BYTE)(color2 >> 8); *(pPix + 2) = (BYTE)(color2 >> 16); #else
*((DWORD *)pPix) = color2; #endif
} pPix += (BPP / 8); if (--count <= 0) break;
zAccum += zDelta; zbuf += 2; if ( ((__GLz16Value)(zAccum >> Z16_SHIFT)) <= *((__GLz16Value*)zbuf) ) { *((__GLz16Value*)zbuf) = ((__GLz16Value)(zAccum >> Z16_SHIFT));
#if (BPP == 8)
*pPix = (BYTE)(color1 >> 16); #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color3; #elif (BPP == 24)
*pPix = (BYTE)color3; *(pPix + 1) = (BYTE)(color3 >> 8); *(pPix + 2) = (BYTE)(color3 >> 16); #else
*((DWORD *)pPix) = color3; #endif
} pPix += (BPP / 8); if (--count <= 0) break;
zAccum += zDelta; zbuf += 2; if ( ((__GLz16Value)(zAccum >> Z16_SHIFT)) <= *((__GLz16Value*)zbuf) ) { *((__GLz16Value*)zbuf) = ((__GLz16Value)(zAccum >> Z16_SHIFT));
#if (BPP == 8)
*pPix = (BYTE)(color1 >> 24); #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color4; #elif (BPP == 24)
*pPix = (BYTE)color4; *(pPix + 1) = (BYTE)(color4 >> 8); *(pPix + 2) = (BYTE)(color4 >> 16); #else
*((DWORD *)pPix) = color4; #endif
} pPix += (BPP / 8); if (--count <= 0) break;
zAccum += zDelta; zbuf += 2; } #else //!DITHER
for (; count; count--) { if ( ((__GLz16Value)(zAccum >> Z16_SHIFT)) <= *((__GLz16Value*)zbuf) ) { *((__GLz16Value*)zbuf) = ((__GLz16Value)(zAccum >> Z16_SHIFT));
#if (BPP == 8)
*pPix = (BYTE)color1; #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color1; #elif (BPP == 24)
*pPix = (BYTE)color1; *(pPix + 1) = (BYTE)color2; *(pPix + 2) = (BYTE)color3; #else
*((DWORD *)pPix) = color1; #endif //BPP
} zAccum += zDelta; zbuf +=2 ; pPix += (BPP / 8); } #endif //!DITHER
} else { #if DITHER
for (;;) { if ( zAccum <= *((GLuint*)zbuf) ) { *((GLuint*)zbuf) = zAccum;
#if (BPP == 8)
*pPix = (BYTE)color1; #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color1; #elif (BPP == 24)
*pPix = (BYTE)color1; *(pPix + 1) = (BYTE)(color1 >> 8); *(pPix + 2) = (BYTE)(color1 >> 16); #else
*((DWORD *)pPix) = color1; #endif
}
pPix += (BPP / 8); if (--count <= 0) break;
zbuf+=4; zAccum += zDelta; if ( zAccum <= *((GLuint*)zbuf) ) { *((GLuint*)zbuf) = zAccum;
#if (BPP == 8)
*pPix = (BYTE)(color1 >> 8); #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color2; #elif (BPP == 24)
*pPix = (BYTE)color2; *(pPix + 1) = (BYTE)(color2 >> 8); *(pPix + 2) = (BYTE)(color2 >> 16); #else
*((DWORD *)pPix) = color2; #endif
} pPix += (BPP / 8); if (--count <= 0) break;
zbuf+=4; zAccum += zDelta; if ( zAccum <= *((GLuint*)zbuf) ) { *((GLuint*)zbuf) = zAccum;
#if (BPP == 8)
*pPix = (BYTE)(color1 >> 16); #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color3; #elif (BPP == 24)
*pPix = (BYTE)color3; *(pPix + 1) = (BYTE)(color3 >> 8); *(pPix + 2) = (BYTE)(color3 >> 16); #else
*((DWORD *)pPix) = color3; #endif
} pPix += (BPP / 8); if (--count <= 0) break;
zbuf+=4; zAccum += zDelta; if ( zAccum <= *((GLuint*)zbuf) ) { *((GLuint*)zbuf) = zAccum;
#if (BPP == 8)
*pPix = (BYTE)(color1 >> 24); #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color4; #elif (BPP == 24)
*pPix = (BYTE)color4; *(pPix + 1) = (BYTE)(color4 >> 8); *(pPix + 2) = (BYTE)(color4 >> 16); #else
*((DWORD *)pPix) = color4; #endif
} pPix += (BPP / 8); if (--count <= 0) break; zAccum += zDelta; zbuf+=4; } #else //!DITHER
for (; count; count--) { if ( zAccum <= *((GLuint*)zbuf) ) { *((GLuint*)zbuf) = zAccum;
#if (BPP == 8)
*pPix = (BYTE)color1; #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color1; #elif (BPP == 24)
*pPix = (BYTE)color1; *(pPix + 1) = (BYTE)color2; *(pPix + 2) = (BYTE)color3; #else
*((DWORD *)pPix) = color1; #endif //BPP
} zbuf+=4; zAccum += zDelta; pPix += (BPP / 8); } #endif //!DITHER
} } else { // !FASTZBUFFER
LONG totalCount; ULONG *pMask = gengc->gc.polygon.shader.stipplePat;
for (totalCount = gengc->gc.polygon.shader.length; totalCount > 0; totalCount -= 32) { ULONG mask; ULONG maskTest;
if ((mask = *pMask++) == 0) { pPix += (32 * (BPP / 8)); continue; }
maskTest = 0x80000000;
if ((count = totalCount) > 32) count = 32;
#if DITHER
for (;;) { if (mask & maskTest) { #if (BPP == 8)
*pPix = (BYTE)color1; #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color1; #elif (BPP == 24)
*pPix = (BYTE)color1; *(pPix + 1) = (BYTE)(color1 >> 8); *(pPix + 2) = (BYTE)(color1 >> 16); #else
*((DWORD *)pPix) = color1; #endif
}
pPix += (BPP / 8); if (--count <= 0) break;
maskTest >>= 1; if (mask & maskTest) { #if (BPP == 8)
*pPix = (BYTE)(color1 >> 8); #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color2; #elif (BPP == 24)
*pPix = (BYTE)color2; *(pPix + 1) = (BYTE)(color2 >> 8); *(pPix + 2) = (BYTE)(color2 >> 16); #else
*((DWORD *)pPix) = color2; #endif
} pPix += (BPP / 8); if (--count <= 0) break;
maskTest >>= 1; if (mask & maskTest) { #if (BPP == 8)
*pPix = (BYTE)(color1 >> 16); #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color3; #elif (BPP == 24)
*pPix = (BYTE)color3; *(pPix + 1) = (BYTE)(color3 >> 8); *(pPix + 2) = (BYTE)(color3 >> 16); #else
*((DWORD *)pPix) = color3; #endif
} pPix += (BPP / 8); if (--count <= 0) break;
maskTest >>= 1; if (mask & maskTest) { #if (BPP == 8)
*pPix = (BYTE)(color1 >> 24); #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color4; #elif (BPP == 24)
*pPix = (BYTE)color4; *(pPix + 1) = (BYTE)(color4 >> 8); *(pPix + 2) = (BYTE)(color4 >> 16); #else
*((DWORD *)pPix) = color4; #endif
} pPix += (BPP / 8); if (--count <= 0) break; #if ZBUFFER
maskTest >>= 1; #else
zAccum += zDelta; zbuf++; #endif
} #else //!DITHER
#if (BPP == 8)
if (mask == 0xffffffff) { RtlFillMemory(pPix, count, color1); pPix += (32 * (BPP / 8)); continue; } #elif (BPP == 16)
if (mask == 0xffffffff) { LONG ddCount;
if ((ULONG_PTR)pPix & 0x2) { // get odd-start pixel
*((WORD *)pPix)++ = (WORD)color1; if (--count <= 0) return; }
if (ddCount = (count & (~1)) << 1) { // fill DWORDs
RtlFillMemoryUlong(pPix, ddCount, color1); pPix += ddCount; }
if (count & 1) // get odd-end pixel
*((WORD *)pPix)++ = (WORD)color1;
continue; } #elif (BPP == 24)
if (mask == 0xffffffff) { ULONG colorShr = color1 >> 8; LONG i;
for (i = 0; i < count; i++, pPix += 3) { *pPix = (BYTE)color1; *(pPix + 1) = (BYTE)color2; *(pPix + 2) = (BYTE)color3; } continue; } #elif (BPP == 32)
if (mask == 0xffffffff) { RtlFillMemoryUlong(pPix, count << 2, color1); pPix += (32 * (BPP / 8)); continue; } #endif //BPP
for (; count; count--) { if (mask & maskTest) { #if (BPP == 8)
*pPix = (BYTE)color1; #elif (BPP == 16)
*((WORD *)pPix) = (WORD)color1; #elif (BPP == 24)
*pPix = (BYTE)color1; *(pPix + 1) = (BYTE)color2; *(pPix + 2) = (BYTE)color3; #else
*((DWORD *)pPix) = color1; #endif //BPP
} maskTest >>= 1; pPix += (BPP / 8); } #endif //!DITHER
} } #else // !ZBUFFER
{ LONG totalCount = gengc->gc.polygon.shader.length; #if DITHER
#if (BPP == 8)
LONG i;
if (totalCount < 7) { *pPix++ = (BYTE)color1; if (--totalCount <= 0) return; *pPix++ = (BYTE)(color1 >> 8); if (--totalCount <= 0) return; *pPix++ = (BYTE)(color1 >> 16); if (--totalCount <= 0) return; *pPix++ = (BYTE)(color1 >> 24); if (--totalCount <= 0) return; *pPix++ = (BYTE)color1; if (--totalCount <= 0) return; *pPix = (BYTE)(color1 >> 8); return; }
if (i = (LONG)((ULONG_PTR)pPix & 0x3)) { i = ditherShift = (4 - i);
totalCount -= i;
if (i--) { *pPix++ = (BYTE)color1; if (i--) { *pPix++ = (BYTE)(color1 >> 8); if (i--) { *pPix++ = (BYTE)(color1 >> 16); } } }
// re-align the dither colors for DWORD boundaries
ditherShift <<= 3;
color1 = (color1 >> ditherShift) | (color1 << (32 - ditherShift)); }
RtlFillMemoryUlong(pPix, totalCount, color1); pPix += (totalCount & 0xfffffffc);
i = totalCount & 0x3;
if (i--) { *pPix++ = (BYTE)color1; if (i--) { *pPix++ = (BYTE)(color1 >> 8); if (i--) { *pPix++ = (BYTE)(color1 >> 16); } } }
return;
#elif (BPP == 16)
ULONG colorA, colorB; LONG i;
if (totalCount < 3) { *((WORD *)pPix)++ = (WORD)color1; if (--totalCount <= 0) return; *((WORD *)pPix)++ = (WORD)color2; return; }
if ((ULONG_PTR)pPix & 0x2) { totalCount--;
*((WORD *)pPix)++ = (WORD)color1;
colorA = color2 | (color3 << 16); colorB = color4 | (color1 << 16); } else { colorA = color1 | (color2 << 16); colorB = color3 | (color4 << 16); }
for (i = (totalCount >> 1);;) { *((DWORD *)pPix)++ = colorA; if (--i <= 0) { if (totalCount & 1) *((WORD *)pPix) = (WORD)colorB; return; } *((DWORD *)pPix)++ = colorB; if (--i <= 0) { if (totalCount & 1) *((WORD *)pPix) = (WORD)colorA; return; } }
#elif (BPP == 24)
for (;;pPix += 12) { *pPix = (BYTE)color1; *(pPix + 1) = (BYTE)(color1 >> 8); *(pPix + 2) = (BYTE)(color1 >> 16); if (--totalCount <= 0) return; *(pPix + 3) = (BYTE)color2; *(pPix + 4) = (BYTE)(color2 >> 8); *(pPix + 5) = (BYTE)(color2 >> 16); if (--totalCount <= 0) return; *(pPix + 6) = (BYTE)color3; *(pPix + 7) = (BYTE)(color3 >> 8); *(pPix + 8) = (BYTE)(color3 >> 16); if (--totalCount <= 0) return; *(pPix + 9) = (BYTE)color4; *(pPix + 10) = (BYTE)(color4 >> 8); *(pPix + 11) = (BYTE)(color4 >> 16); if (--totalCount <= 0) return; } #elif (BPP == 32)
for (;;pPix += 16) { *((DWORD *)pPix) = color1; if (--totalCount <= 0) return; *((DWORD *)(pPix + 4)) = color2; if (--totalCount <= 0) return; *((DWORD *)(pPix + 8)) = color3; if (--totalCount <= 0) return; *((DWORD *)(pPix + 12)) = color4; if (--totalCount <= 0) return; } #endif //BPP
#else //!DITHER
#if (BPP == 8)
RtlFillMemory(pPix, totalCount, color1); return; #elif (BPP == 16)
if ((ULONG_PTR)pPix & 0x2) { // get odd-start pixel
*((WORD *)pPix)++ = (WORD)color1; if (--totalCount <= 0) return; } if (count = (totalCount & (~1)) << 1) RtlFillMemoryUlong(pPix, count, color1); if (totalCount & 1) // get odd-end pixel
*((WORD *)(pPix + count)) = (WORD)color1; return; #elif (BPP == 24)
LONG i;
for (i = 0; i < totalCount; i++, pPix += 3) { *pPix = (BYTE)color1; *(pPix + 1) = (BYTE)(color2); *(pPix + 2) = (BYTE)(color3); } return; #elif (BPP == 32)
RtlFillMemoryUlong(pPix, totalCount << 2, color1); return; #endif //BPP
#endif //!DITHER
} #endif // !ZBUFFER
}
|