windows-nt/Source/XPSP1/NT/multimedia/directx/dxg/ref8/rast/refrast.cpp
2020-09-26 16:20:57 +08:00

462 lines
15 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Copyright (C) Microsoft Corporation, 2000.
//
// refrast.cpp
//
// Direct3D Reference Device - rasterizer miscellaneous
//
///////////////////////////////////////////////////////////////////////////////
#include "pch.cpp"
#pragma hdrstop
///////////////////////////////////////////////////////////////////////////////
// //
// RDColor //
// //
///////////////////////////////////////////////////////////////////////////////
void
RDColor::ConvertFrom( RDSurfaceFormat Type, const char* pSurfaceBits )
{
UINT16 u16BITS;
UINT8 u8BITS;
switch (Type)
{
default:
case RD_SF_NULL: return;
case RD_SF_B8G8R8A8: *this = *((UINT32*)pSurfaceBits); break;
case RD_SF_B8G8R8X8: *this = *((UINT32*)pSurfaceBits); A = 1.F; break;
case RD_SF_B5G6R5:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>>(6+5)) & 0x001F)/31.f;
G = ((u16BITS>> 5) & 0x003F)/63.f;
B = ((u16BITS ) & 0x001F)/31.f;
A = 1.F;
break;
case RD_SF_B5G5R5X1:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>>(5+5)) & 0x001F)/31.f;
G = ((u16BITS>> 5) & 0x001F)/31.f;
B = ((u16BITS ) & 0x001F)/31.f;
A = 1.F;
break;
case RD_SF_B5G5R5A1:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>>(5+5)) & 0x001F)/31.f;
G = ((u16BITS>> 5) & 0x001F)/31.f;
B = ((u16BITS ) & 0x001F)/31.f;
A = ( u16BITS & 0x8000 ) ? 1.f : 0.f;
break;
case RD_SF_B4G4R4A4:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>> (4+4)) & 0x000F)/15.f;
G = ((u16BITS>> (4)) & 0x000F)/15.f;
B = ((u16BITS ) & 0x000F)/15.f;
A = ((u16BITS>>(4+4+4)) & 0x000F)/15.f;
break;
case RD_SF_B4G4R4X4:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>>(4+4)) & 0x000F)/15.f;
G = ((u16BITS>> (4)) & 0x000F)/15.f;
B = ((u16BITS ) & 0x000F)/15.f;
A = 1.f;
break;
case RD_SF_B8G8R8:
R = *((UINT8*)pSurfaceBits+2)/255.f;
G = *((UINT8*)pSurfaceBits+1)/255.f;
B = *((UINT8*)pSurfaceBits+0)/255.f;
A = 1.F;
break;
case RD_SF_L8:
R = G = B = *((UINT8*)pSurfaceBits)/255.f;
A = 1.F;
break;
case RD_SF_L8A8:
u16BITS = *((UINT16*)pSurfaceBits);
R = G = B = (UINT8)(0xff & u16BITS)/255.f;
A = (UINT8)(0xff & (u16BITS >> 8))/255.f;
break;
case RD_SF_A8:
R = G = B = 0.f;
A = *((UINT8*)pSurfaceBits)/255.f;
break;
case RD_SF_B2G3R3:
u8BITS = *((UINT8*)pSurfaceBits);
R = ((u8BITS>>(3+2)) & 0x07)/7.f;
G = ((u8BITS>> 2) & 0x07)/7.f;
B = ((u8BITS ) & 0x03)/3.f;
A = 1.F;
break;
case RD_SF_L4A4:
u16BITS = *((UINT8*)pSurfaceBits);
R = G = B = (u16BITS & 0x0f)/15.f;
A = ((u16BITS>>4) & 0x0f)/15.f;
break;
case RD_SF_B2G3R3A8:
u16BITS = *((UINT16*)pSurfaceBits);
R = ((u16BITS>>(3+2)) & 0x07)/7.f;
G = ((u16BITS>> 2) & 0x07)/7.f;
B = ((u16BITS ) & 0x03)/3.f;
A = (UINT8)(0xff & (u16BITS >> 8))/255.f;
break;
case RD_SF_U8V8:
{
INT8 iDU = *(( INT8*)pSurfaceBits+0);
INT8 iDV = *(( INT8*)pSurfaceBits+1);
R = CLAMP_SIGNED8(iDU); // fDU
G = CLAMP_SIGNED8(iDV); // fDV
B = 1.0F; // fL
A = 1.F;
}
break;
case RD_SF_U16V16:
{
INT16 iDU = *(( INT16*)pSurfaceBits+0);
INT16 iDV = *(( INT16*)pSurfaceBits+1);
R = CLAMP_SIGNED16(iDU); // fDU
G = CLAMP_SIGNED16(iDV); // fDV
B = 1.0f; // 1.0 here is intentional
A = 1.0f;
}
break;
case RD_SF_U5V5L6:
{
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
INT8 iDU = (INT8)(u16BITS & 0x1f);
INT8 iDV = (INT8)((u16BITS>>5) & 0x1f);
UINT8 uL = (UINT8)(u16BITS >> 10);
R = CLAMP_SIGNED5(iDU); // fDU
G = CLAMP_SIGNED5(iDV); // fDV
// the unsigned uL is normalized with 2^N - 1, since this is the
// largest representable value
B = (FLOAT)uL * (1.0F/63.0F); // fL
A = 1.0f;
}
break;
case RD_SF_U8V8L8X8:
{
INT8 iDU = *(( INT8*)pSurfaceBits+0);
INT8 iDV = *(( INT8*)pSurfaceBits+1);
UINT8 uL = *((UINT8*)pSurfaceBits+2);
R = CLAMP_SIGNED8(iDU); // fDU
G = CLAMP_SIGNED8(iDV); // fDV
// the unsigned uL is normalized with 2^N - 1, since this is the
// largest representable value
B = (FLOAT)uL * (1.0F/255.0F); // fL
A = 1.0f;
}
break;
case RD_SF_U8V8W8Q8:
{
INT8 iDU = *(( INT8*)pSurfaceBits+0);
INT8 iDV = *(( INT8*)pSurfaceBits+1);
INT8 iDW = *(( INT8*)pSurfaceBits+2);
INT8 iDQ = *(( INT8*)pSurfaceBits+3);
// signed values are normalized with 2^(N-1), since -2^(N-1) can
// be exactly expressed in N bits
R = CLAMP_SIGNED8(iDU); // fDU
G = CLAMP_SIGNED8(iDV); // fDV
B = CLAMP_SIGNED8(iDW); // fDW
A = CLAMP_SIGNED8(iDQ); // fDQ
}
break;
case RD_SF_U10V11W11:
{
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
INT16 iDU = (INT16)((u32BITS>>(0 )) & 0x3FF);
INT16 iDV = (INT16)((u32BITS>>(10 )) & 0x7FF);
INT16 iDW = (INT16)((u32BITS>>(10+11)) & 0x7FF);
// signed values are normalized with 2^(N-1), since -2^(N-1) can
// be exactly expressed in N bits
R = CLAMP_SIGNED10(iDU); // fDU
G = CLAMP_SIGNED11(iDV); // fDV
B = CLAMP_SIGNED11(iDW); // fDW
A = 1.0f;
}
break;
case RD_SF_R10G10B10A2:
{
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
R = ((u32BITS>>(0 )) & 0x3FF)/1023.f;
G = ((u32BITS>>(10 )) & 0x3FF)/1023.f;
B = ((u32BITS>>(10+10)) & 0x3FF)/1023.f;
A = ((u32BITS>>(10+10+10)) & 0x3)/3.f;
}
break;
case RD_SF_R8G8B8A8:
{
R = *(( UINT8*)pSurfaceBits+0)/255.f;
G = *(( UINT8*)pSurfaceBits+1)/255.f;
B = *(( UINT8*)pSurfaceBits+2)/255.f;
A = *(( UINT8*)pSurfaceBits+3)/255.f;
}
break;
case RD_SF_R8G8B8X8:
{
R = *(( UINT8*)pSurfaceBits+0)/255.f;
G = *(( UINT8*)pSurfaceBits+1)/255.f;
B = *(( UINT8*)pSurfaceBits+2)/255.f;
A = 1.f;
}
break;
case RD_SF_R16G16:
{
R = *(( UINT16*)pSurfaceBits+0)/65535.f;
G = *(( UINT16*)pSurfaceBits+1)/65535.f;
B = 1.0f; // 1.0 here is intentional
A = 1.0f;
}
break;
case RD_SF_U11V11W10:
{
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
INT16 iDU = (INT16)((u32BITS>>(0 )) & 0x7FF);
INT16 iDV = (INT16)((u32BITS>>(11 )) & 0x7FF);
INT16 iDW = (INT16)((u32BITS>>(11+11)) & 0x3FF);
// signed values are normalized with 2^(N-1), since -2^(N-1) can
// be exactly expressed in N bits
R = CLAMP_SIGNED11(iDU); // fDU
G = CLAMP_SIGNED11(iDV); // fDV
B = CLAMP_SIGNED10(iDW); // fDW
A = 1.0f;
}
break;
case RD_SF_U10V10W10A2:
{
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
INT16 iDU = (INT16)((u32BITS>>(0 )) & 0x3FF);
INT16 iDV = (INT16)((u32BITS>>(10 )) & 0x3FF);
INT16 iDW = (INT16)((u32BITS>>(10+10)) & 0x3FF);
// signed values are normalized with 2^(N-1), since -2^(N-1) can
// be exactly expressed in N bits
R = CLAMP_SIGNED10(iDU); // fDU
G = CLAMP_SIGNED10(iDV); // fDV
B = CLAMP_SIGNED10(iDW); // fDW
// Note: The A component is treated as an unsigned component
A = ((u32BITS>>(10+10+10)) & 0x3)/3.f;
}
break;
case RD_SF_U8V8X8A8:
{
INT8 iU = *(( INT8*)pSurfaceBits+0);
INT8 iV = *(( INT8*)pSurfaceBits+1);
// signed values are normalized with 2^(N-1), since -2^(N-1) can
// be exactly expressed in N bits
R = CLAMP_SIGNED8(iU);
G = CLAMP_SIGNED8(iV);
B = 1.0f;
// Note: The A component is treated as unsigned
A = *(( INT8*)pSurfaceBits+3)/255.f;
}
break;
case RD_SF_U8V8X8L8:
{
INT8 iU = *(( INT8*)pSurfaceBits+0);
INT8 iV = *(( INT8*)pSurfaceBits+1);
INT8 iL = *(( INT8*)pSurfaceBits+3);
// signed values are normalized with 2^(N-1), since -2^(N-1) can
// be exactly expressed in N bits
R = CLAMP_SIGNED8(iU);
G = CLAMP_SIGNED8(iV);
B = CLAMP_SIGNED8(iL);
A = 1.0f;
}
break;
// shadow map texture formats (read only, not needed for ConvertTo)
case RD_SF_Z16S0:
{
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)u16BITS * (1.0F/(FLOAT)0xffff);
B = 0.0F;
A = 1.0f;
}
break;
case RD_SF_Z24S8:
case RD_SF_Z24X8:
case RD_SF_Z24X4S4:
{
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)(u32BITS>>8) * (1.0F/(FLOAT)0xffffff);
B = 0.0F;
A = 1.0f;
}
break;
case RD_SF_S8Z24:
case RD_SF_X8Z24:
case RD_SF_X4S4Z24:
{
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)(u32BITS&0x00ffffff) * (1.0F/(FLOAT)0xffffff);
B = 0.0F;
A = 1.0f;
}
break;
case RD_SF_Z15S1:
{
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)(u16BITS>>1) * (1.0F/(FLOAT)0x7fff);
B = 0.0F;
A = 1.0f;
}
break;
case RD_SF_S1Z15:
{
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)(u16BITS&0x7fff) * (1.0F/(FLOAT)0x7fff);
B = 0.0F;
A = 1.0f;
}
break;
case RD_SF_Z32S0:
{
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
R = 0.0F;
G = (FLOAT)u32BITS * (1.0F/(FLOAT)0xffffffff);
B = 0.0F;
A = 1.0f;
}
break;
}
}
// Convert surface type format to RDColor
void
RDColor::ConvertTo( RDSurfaceFormat Type, float fRoundOffset, char* pSurfaceBits ) const
{
int iR, iG, iB, iA;
switch (Type)
{
case RD_SF_B8G8R8A8:
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+3) = (UINT8)((FLOAT)A * 255. + fRoundOffset);
break;
case RD_SF_B8G8R8X8:
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+3) = 0x00;
break;
case RD_SF_B8G8R8:
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
break;
case RD_SF_B4G4R4A4:
iA = (FLOAT)A * 15. + fRoundOffset;
iR = (FLOAT)R * 15. + fRoundOffset;
iG = (FLOAT)G * 15. + fRoundOffset;
iB = (FLOAT)B * 15. + fRoundOffset;
*((UINT16*)pSurfaceBits) = (iA<<12) | (iR<<8) | (iG<<4) | iB;
break;
case RD_SF_B4G4R4X4:
iR = (FLOAT)R * 15. + fRoundOffset;
iG = (FLOAT)G * 15. + fRoundOffset;
iB = (FLOAT)B * 15. + fRoundOffset;
*((UINT16*)pSurfaceBits) = (0x00<<12) | (iR<<8) | (iG<<4) | iB;
break;
case RD_SF_B5G6R5:
iR = (FLOAT)R * 31. + fRoundOffset; // apply rounding bias then truncate
iG = (FLOAT)G * 63. + fRoundOffset;
iB = (FLOAT)B * 31. + fRoundOffset;
*((UINT16*)pSurfaceBits) = (iR<<11) | (iG<<5) | iB;
break;
case RD_SF_B5G5R5A1:
iA = (FLOAT)A * 1. + fRoundOffset;
iR = (FLOAT)R * 31. + fRoundOffset;
iG = (FLOAT)G * 31. + fRoundOffset;
iB = (FLOAT)B * 31. + fRoundOffset;
*((UINT16*)pSurfaceBits) = (iA<<15) | (iR<<10) | (iG<<5) | iB;
break;
case RD_SF_B5G5R5X1:
iR = (FLOAT)R * 31. + fRoundOffset;
iG = (FLOAT)G * 31. + fRoundOffset;
iB = (FLOAT)B * 31. + fRoundOffset;
*((UINT16*)pSurfaceBits) = (iR<<10) | (iG<<5) | iB;
break;
case RD_SF_B2G3R3:
iR = (FLOAT)R * 7. + fRoundOffset;
iG = (FLOAT)G * 7. + fRoundOffset;
iB = (FLOAT)B * 3. + fRoundOffset;
*((UINT8*)pSurfaceBits) = (iR<<5) | (iG<<2) | iB;
break;
case RD_SF_B2G3R3A8:
iA = (FLOAT)A * 255. + fRoundOffset;
iR = (FLOAT)R * 7. + fRoundOffset;
iG = (FLOAT)G * 7. + fRoundOffset;
iB = (FLOAT)B * 3. + fRoundOffset;
*((UINT16*)pSurfaceBits) = (iA<<8) | (iR<<5) | (iG<<2) | iB;
break;
case RD_SF_R10G10B10A2:
iR = (FLOAT)R * 1023.f + fRoundOffset;
iG = (FLOAT)G * 1023.f + fRoundOffset;
iB = (FLOAT)B * 1023.f + fRoundOffset;
iA = (FLOAT)A * 3.f + fRoundOffset;
*((UINT32*)pSurfaceBits) = (iA<<(10+10+10)) | (iB<<(10+10)) | (iG<<10) | iR;
break;
case RD_SF_R8G8B8A8:
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+3) = (UINT8)((FLOAT)A * 255. + fRoundOffset);
break;
case RD_SF_R8G8B8X8:
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
*((UINT8*)pSurfaceBits+3) = 0x00;
break;
}
}
///////////////////////////////////////////////////////////////////////////////
// end