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

997 lines
36 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Copyright (C) Microsoft Corporation, 2000.
//
// psutil.cpp
//
// Direct3D Reference Device - Pixel Shader Utilities
//
///////////////////////////////////////////////////////////////////////////////
#include "pch.cpp"
#pragma hdrstop
#define _ADDSTR( _Str ) {_snprintf( pStr, 256, "%s" _Str , pStr );}
#define _ADDSTRP( _Str, _Param ) {_snprintf( pStr, 256, "%s" _Str , pStr, _Param );}
//-----------------------------------------------------------------------------
//
// PixelShaderInstDisAsm - Generates instruction disassembly string for a single
// pixel shader instruction. String interface is similar to _snprintf.
//
//-----------------------------------------------------------------------------
int
PixelShaderInstDisAsm(
char* pStrRet, int StrSizeRet, DWORD* pShader, DWORD Flags )
{
UINT i,j;
DWORD* pToken = pShader;
// stage in local string, then copy
char pStr[256] = "";
DWORD Inst = *pToken++;
if( Inst & D3DSI_COISSUE )
{
_ADDSTR("+");
}
DWORD Opcode = (Inst & D3DSI_OPCODE_MASK);
DWORD DstParam = 0;
DWORD SrcParam[3];
DWORD SrcParamCount = 0;
if (*pToken & (1L<<31))
{
DstParam = *pToken++;
while (*pToken & (1L<<31))
{
SrcParam[SrcParamCount] = *pToken++;
SrcParamCount++;
}
}
switch (Opcode)
{
case D3DSIO_PHASE: _ADDSTR("phase"); break;
case D3DSIO_NOP: _ADDSTR("nop"); break;
case D3DSIO_MOV: _ADDSTR("mov"); break;
case D3DSIO_ADD: _ADDSTR("add"); break;
case D3DSIO_SUB: _ADDSTR("sub"); break;
case D3DSIO_MUL: _ADDSTR("mul"); break;
case D3DSIO_MAD: _ADDSTR("mad"); break;
case D3DSIO_LRP: _ADDSTR("lrp"); break;
case D3DSIO_CND: _ADDSTR("cnd"); break;
case D3DSIO_DP3: _ADDSTR("dp3"); break;
case D3DSIO_DEF: _ADDSTR("def"); break;
case D3DSIO_DP4: _ADDSTR("dp4"); break;
case D3DSIO_CMP: _ADDSTR("cmp"); break;
case D3DSIO_FRC: _ADDSTR("frc"); break;
case D3DSIO_BEM: _ADDSTR("bem"); break;
case D3DSIO_TEXCOORD : if(SrcParamCount)
_ADDSTR("texcrd")
else
_ADDSTR("texcoord");
break;
case D3DSIO_TEX : if(SrcParamCount)
_ADDSTR("texld")
else
_ADDSTR("tex");
break;
case D3DSIO_TEXKILL : _ADDSTR("texkill"); break;
case D3DSIO_TEXBEM_LEGACY:
case D3DSIO_TEXBEM : _ADDSTR("texbem"); break;
case D3DSIO_TEXBEML_LEGACY:
case D3DSIO_TEXBEML : _ADDSTR("texbeml"); break;
case D3DSIO_TEXREG2AR : _ADDSTR("texreg2ar"); break;
case D3DSIO_TEXREG2GB : _ADDSTR("texreg2gb"); break;
case D3DSIO_TEXM3x2PAD : _ADDSTR("texm3x2pad"); break;
case D3DSIO_TEXM3x2TEX : _ADDSTR("texm3x2tex"); break;
case D3DSIO_TEXM3x3PAD : _ADDSTR("texm3x3pad"); break;
case D3DSIO_TEXM3x3TEX : _ADDSTR("texm3x3tex"); break;
case D3DSIO_TEXM3x3SPEC : _ADDSTR("texm3x3spec"); break;
case D3DSIO_TEXM3x3VSPEC: _ADDSTR("texm3x3vspec"); break;
case D3DSIO_TEXM3x2DEPTH : _ADDSTR("texm3x2depth"); break;
case D3DSIO_TEXDP3 : _ADDSTR("texdp3"); break;
case D3DSIO_TEXREG2RGB : _ADDSTR("texreg2rgb"); break;
case D3DSIO_TEXDEPTH : _ADDSTR("texdepth"); break;
case D3DSIO_TEXDP3TEX : _ADDSTR("texdp3tex"); break;
case D3DSIO_TEXM3x3 : _ADDSTR("texm3x3"); break;
case D3DSIO_END : _ADDSTR("END"); break;
default:
_ASSERT(FALSE,"Attempt to disassemble unknown instruction!");
}
if (DstParam)
{
switch ( (DstParam & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT )
{
default:
case 0x0: break;
case 0x1: _ADDSTR("_x2"); break;
case 0x2: _ADDSTR("_x4"); break;
case 0x3: _ADDSTR("_x8"); break;
case 0xF: _ADDSTR("_d2"); break;
case 0xE: _ADDSTR("_d4"); break;
case 0xD: _ADDSTR("_d8"); break;
}
switch (DstParam & D3DSP_DSTMOD_MASK)
{
default:
case D3DSPDM_NONE: break;
case D3DSPDM_SATURATE: _ADDSTR("_sat"); break;
}
switch (DstParam & D3DSP_REGTYPE_MASK)
{
default:
case D3DSPR_TEMP: _ADDSTRP(" r%d", (DstParam & D3DSP_REGNUM_MASK) ); break;
case D3DSPR_TEXTURE: _ADDSTRP(" t%d", (DstParam & D3DSP_REGNUM_MASK) ); break;
case D3DSPR_CONST: _ADDSTRP(" c%d", (DstParam & D3DSP_REGNUM_MASK) ); break;
}
if (D3DSP_WRITEMASK_ALL != (DstParam & D3DSP_WRITEMASK_ALL))
{
_ADDSTR(".");
if (DstParam & D3DSP_WRITEMASK_0) _ADDSTR("r");
if (DstParam & D3DSP_WRITEMASK_1) _ADDSTR("g");
if (DstParam & D3DSP_WRITEMASK_2) _ADDSTR("b");
if (DstParam & D3DSP_WRITEMASK_3) _ADDSTR("a");
}
if( D3DSIO_DEF == Opcode )
{
for( i = 0; i < 4; i++ )
_ADDSTRP(", %f", (float)(*pToken++) );
goto EXIT;
}
}
for( i = 0; i < SrcParamCount; i++ )
{
_ADDSTR(",");
switch (SrcParam[i] & D3DSP_SRCMOD_MASK)
{
default:
case D3DSPSM_NONE: _ADDSTR(" "); break;
case D3DSPSM_NEG: _ADDSTR(" -"); break;
case D3DSPSM_BIAS: _ADDSTR(" "); break;
case D3DSPSM_BIASNEG: _ADDSTR(" -"); break;
case D3DSPSM_SIGN: _ADDSTR(" "); break;
case D3DSPSM_SIGNNEG: _ADDSTR(" -"); break;
case D3DSPSM_COMP: _ADDSTR(" 1-"); break;
case D3DSPSM_X2: _ADDSTR(" "); break;
case D3DSPSM_X2NEG: _ADDSTR(" -"); break;
}
switch (SrcParam[i] & D3DSP_REGTYPE_MASK)
{
case D3DSPR_TEMP: _ADDSTRP("r%d", (SrcParam[i] & D3DSP_REGNUM_MASK) ); break;
case D3DSPR_INPUT: _ADDSTRP("v%d", (SrcParam[i] & D3DSP_REGNUM_MASK) ); break;
case D3DSPR_CONST: _ADDSTRP("c%d", (SrcParam[i] & D3DSP_REGNUM_MASK) ); break;
case D3DSPR_TEXTURE: _ADDSTRP("t%d", (SrcParam[i] & D3DSP_REGNUM_MASK) ); break;
}
switch (SrcParam[i] & D3DSP_SRCMOD_MASK)
{
default:
case D3DSPSM_NONE: break;
case D3DSPSM_NEG: break;
case D3DSPSM_BIAS: _ADDSTR("_bias"); break;
case D3DSPSM_BIASNEG: _ADDSTR("_bias"); break;
case D3DSPSM_SIGN: _ADDSTR("_bx2"); break;
case D3DSPSM_SIGNNEG: _ADDSTR("_bx2"); break;
case D3DSPSM_COMP: break;
case D3DSPSM_X2: _ADDSTR("_x2"); break;
case D3DSPSM_X2NEG: _ADDSTR("_x2"); break;
case D3DSPSM_DZ: _ADDSTR("_db"); break;
case D3DSPSM_DW: _ADDSTR("_da"); break;
}
switch (SrcParam[i] & D3DVS_SWIZZLE_MASK)
{
case D3DSP_NOSWIZZLE: break;
case D3DSP_REPLICATEALPHA: _ADDSTR(".a"); break;
case D3DSP_REPLICATERED: _ADDSTR(".r"); break;
case D3DSP_REPLICATEGREEN: _ADDSTR(".g"); break;
case D3DSP_REPLICATEBLUE: _ADDSTR(".b"); break;
default:
_ADDSTR(".");
for(j = 0; j < 4; j++)
{
switch(((SrcParam[i] & D3DVS_SWIZZLE_MASK) >> (D3DVS_SWIZZLE_SHIFT + 2*j)) & 0x3)
{
case 0:
_ADDSTR("r");
break;
case 1:
_ADDSTR("g");
break;
case 2:
_ADDSTR("b");
break;
case 3:
_ADDSTR("a");
break;
}
}
break;
}
}
EXIT:
return _snprintf( pStrRet, StrSizeRet, "%s", pStr );
}
int
RDPSInstSrcDisAsm(
char* pStrRet, int StrSizeRet, RDPSRegister& SrcReg, BYTE Swizzle, BOOL bNegate, BOOL bForceShowFullSwizzle = FALSE )
{
// stage in local string, then copy
char pStr[256] = "";
UINT i;
BOOL bDoRegNum = TRUE;
if( bNegate )
_ADDSTR( "-" );
switch( SrcReg.GetRegType() )
{
case RDPSREG_INPUT:
_ADDSTR( "v" ); break;
case RDPSREG_TEMP:
_ADDSTR( "r" ); break;
case RDPSREG_CONST:
_ADDSTR( "c" ); break;
case RDPSREG_TEXTURE:
_ADDSTR( "t" ); break;
case RDPSREG_POSTMODSRC:
_ADDSTR( "postModSrc" ); break;
case RDPSREG_SCRATCH:
_ADDSTR( "scratch" ); break;
case RDPSREG_QUEUEDWRITE:
_ADDSTR( "queuedWrite" ); break;
case RDPSREG_ZERO:
_ADDSTR( "<0.0f>" ); bDoRegNum = FALSE; break;
case RDPSREG_ONE:
_ADDSTR( "<1.0f>" ); bDoRegNum = FALSE; break;
case RDPSREG_TWO:
_ADDSTR( "<2.0f>" ); bDoRegNum = FALSE; break;
default:
_ASSERT(FALSE,"RDPSInstSrcDisAsm - Unknown register type.");
break;
}
if( bDoRegNum )
{
_ADDSTRP("%d", SrcReg.GetRegNum() );
}
if( !bForceShowFullSwizzle )
{
switch( Swizzle )
{
case RDPS_NOSWIZZLE: break;
case RDPS_REPLICATERED: _ADDSTR( ".r" ); break;
case RDPS_REPLICATEGREEN: _ADDSTR( ".g" ); break;
case RDPS_REPLICATEBLUE: _ADDSTR( ".b" ); break;
case RDPS_REPLICATEALPHA: _ADDSTR( ".a" ); break;
default: bForceShowFullSwizzle = TRUE; break;
}
}
if( bForceShowFullSwizzle )
{
_ADDSTR( "." );
for( i=0; i<4; i++ )
{
switch( Swizzle & 0x3 )
{
case RDPS_SELECT_R: _ADDSTR("r"); break;
case RDPS_SELECT_G: _ADDSTR("g"); break;
case RDPS_SELECT_B: _ADDSTR("b"); break;
case RDPS_SELECT_A: _ADDSTR("a"); break;
}
Swizzle >>= 2;
}
}
return _snprintf( pStrRet, StrSizeRet, "%s", pStr );
}
int
RDPSInstDestDisAsm(
char* pStrRet, int StrSizeRet, RDPSRegister& DestReg, BYTE WriteMask )
{
// stage in local string, then copy
char pStr[256] = "";
switch( DestReg.GetRegType() )
{
case RDPSREG_TEMP:
_ADDSTR( "r" ); break;
case RDPSREG_TEXTURE:
_ADDSTR( "t" ); break;
case RDPSREG_POSTMODSRC:
_ADDSTR( "postModSrc" ); break;
case RDPSREG_SCRATCH:
_ADDSTR( "scratch" ); break;
case RDPSREG_QUEUEDWRITE:
_ADDSTR( "queuedWrite" ); break;
default:
_ASSERT(FALSE,"RDPSInstSrcDisAsm - Unknown or invalid destination register type.");
break;
}
_ADDSTRP("%d", DestReg.GetRegNum() );
if( 0 == WriteMask )
{
_ASSERT(FALSE,"RDPSInstSrcDisAsm - Invalid destination write mask (0).");
}
else if( RDPS_COMPONENTMASK_ALL != WriteMask )
{
_ADDSTR(".");
if( RDPS_COMPONENTMASK_0 & WriteMask )
{
_ADDSTR("r");
}
if( RDPS_COMPONENTMASK_1 & WriteMask )
{
_ADDSTR("g");
}
if( RDPS_COMPONENTMASK_2 & WriteMask )
{
_ADDSTR("b");
}
if( RDPS_COMPONENTMASK_3 & WriteMask )
{
_ADDSTR("a");
}
}
return _snprintf( pStrRet, StrSizeRet, "%s", pStr );
}
//-----------------------------------------------------------------------------
//
//
//-----------------------------------------------------------------------------
void
RDPSDisAsm(BYTE* pRDPSInstBuffer, ConstDef* pConstDefs, UINT cConstDefs, FLOAT fMaxPixelShaderValue, DWORD dwVersion)
{
#define _InstParam(__INST) (*(__INST##_PARAMS UNALIGNED64*)pRDPSInstBuffer)
#define _StepOverInst(__INST) pRDPSInstBuffer += sizeof(__INST##_PARAMS);
#define _DeclArgs(__INST) __INST##_PARAMS& Args = _InstParam(__INST);
// stage in local string, then copy
char pStr[256] = "";
char pTempStr[256] = "";
_ADDSTR("-----------------------------------------------------------------------------");
RDDebugPrintf( pStr ); *pStr = 0;
_ADDSTR("CreatePixelShader - Listing refrast's 'RISC' translation of pixel shader. ");
RDDebugPrintf( pStr ); *pStr = 0;
_ADDSTR(" Using MaxPixelShaderValue: ");
if( FLT_MAX == fMaxPixelShaderValue )
{
_ADDSTR("FLT_MAX");
}
else
{
_ADDSTRP("%f",fMaxPixelShaderValue);
}
RDDebugPrintf( pStr ); *pStr = 0;
_ADDSTR(" Pixel shader version: ");
_ADDSTRP("ps.%d", D3DSHADER_VERSION_MAJOR(dwVersion));
_ADDSTRP(".%d", D3DSHADER_VERSION_MINOR(dwVersion));
RDDebugPrintf( pStr ); *pStr = 0;
_ADDSTR("-----------------------------------------------------------------------------");
RDDebugPrintf( pStr ); *pStr = 0;
for( UINT i = 0; i < cConstDefs; i++ )
{
_ADDSTRP("def c%d, [",pConstDefs[i].RegNum);
_ADDSTRP("%f,",pConstDefs[i].f[0]);
_ADDSTRP("%f,",pConstDefs[i].f[1]);
_ADDSTRP("%f,",pConstDefs[i].f[2]);
_ADDSTRP("%f] (post-MaxPSVal-clamp shown)",pConstDefs[i].f[3]);
RDDebugPrintf( pStr ); *pStr = 0;
}
while(RDPSINST_END != _InstParam(RDPSINST_BASE).Inst)
{
#ifdef _IA64_
_ASSERT(0 == ((ULONG_PTR)pRDPSInstBuffer & 0x7), "RDPSDisAsm() - Misaligned instuction pointer!");
#endif
switch(_InstParam(RDPSINST_BASE).Inst)
{
case RDPSINST_EVAL:
{
_DeclArgs(RDPSINST_EVAL)
_ADDSTR("eval ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,RDPS_COMPONENTMASK_ALL);
_ADDSTRP("%s <-- ", pTempStr);
_ADDSTRP("CoordSet: %d, ", Args.uiCoordSet );
_ADDSTR("bIgnoreD3DTTFF_PROJECTED: ");
if( Args.bIgnoreD3DTTFF_PROJECTED )
{
_ADDSTR( "TRUE");
}
else
{
_ADDSTR( "FALSE");
}
_ADDSTR(", bClamp: ");
if( Args.bClamp )
{
_ADDSTR( "TRUE");
}
else
{
_ADDSTR( "FALSE");
}
}
_StepOverInst(RDPSINST_EVAL)
break;
case RDPSINST_SAMPLE:
{
_DeclArgs(RDPSINST_SAMPLE)
_ADDSTR("sample ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,RDPS_COMPONENTMASK_ALL); _ADDSTRP("%s <-- ", pTempStr);
_ADDSTRP("TexStage: %d, TexCoords: ", Args.uiStage);
RDPSInstSrcDisAsm(pTempStr,256,Args.CoordReg,RDPS_NOSWIZZLE,FALSE); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_SAMPLE)
break;
case RDPSINST_KILL:
{
_DeclArgs(RDPSINST_KILL)
_ADDSTR("kill ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,RDPS_COMPONENTMASK_ALL); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_KILL)
break;
case RDPSINST_BEM:
{
_DeclArgs(RDPSINST_BEM)
_ADDSTR("bem ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
_ADDSTRP("D3DTSS_BUMPENVMAT** Stage: %d", Args.uiStage);
}
_StepOverInst(RDPSINST_BEM)
break;
case RDPSINST_LUMINANCE:
{
_DeclArgs(RDPSINST_LUMINANCE)
_ADDSTR("luminance ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,RDPS_COMPONENTMASK_ALL); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
_ADDSTRP("D3DTSS_BUMPENVLSCALE/OFFSET Stage: %d", Args.uiStage);
}
_StepOverInst(RDPSINST_LUMINANCE)
break;
case RDPSINST_DEPTH:
{
_DeclArgs(RDPSINST_DEPTH)
_ADDSTR("depth ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,RDPS_COMPONENTMASK_ALL); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_DEPTH)
break;
case RDPSINST_SRCMOD:
{
_DeclArgs(RDPSINST_SRCMOD)
_ADDSTR("srcMod ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
if( Args.bComplement )
_ADDSTR("1-");
if( Args.bTimes2 )
_ADDSTR("2*");
if( Args.bTimes2 && Args.bBias )
_ADDSTR("(");
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,FALSE); _ADDSTRP("%s", pTempStr);
if( Args.bBias )
_ADDSTR("-0.5");
if( Args.bTimes2 && Args.bBias )
_ADDSTR(")");
_ADDSTR(", Clamp[");
if( -FLT_MAX == Args.fRangeMin )
{
_ADDSTR("-FLT_MAX,");
}
else
{
_ADDSTRP("%.0f,",Args.fRangeMin);
}
if( FLT_MAX == Args.fRangeMax )
{
_ADDSTR("FLT_MAX]");
}
else
{
_ADDSTRP("%.0f]",Args.fRangeMax);
}
}
_StepOverInst(RDPSINST_SRCMOD)
break;
case RDPSINST_SWIZZLE:
{
_DeclArgs(RDPSINST_SWIZZLE)
_ADDSTR("swizzle ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,Args.Swizzle,FALSE,TRUE); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_SWIZZLE)
break;
case RDPSINST_DSTMOD:
{
_DeclArgs(RDPSINST_DSTMOD)
_ADDSTR("dstMod ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.DstReg,RDPS_NOSWIZZLE,FALSE); _ADDSTRP("%s", pTempStr);
if( (1.0f == Args.fScale) ||
(2.0f == Args.fScale) ||
(4.0f == Args.fScale) ||
(8.0f == Args.fScale) )
{
_ADDSTRP("*%.0f",Args.fScale);
}
else if( (0.5f == Args.fScale) ||
(0.25f == Args.fScale) ||
(0.125f == Args.fScale) )
{
_ADDSTRP("/%.0f",1/Args.fScale);
}
else
_ASSERT(FALSE,"RDPSDisAsm - Unexpected dest shift.");
_ADDSTR(", Clamp[");
if( -FLT_MAX == Args.fRangeMin )
{
_ADDSTR("-FLT_MAX,");
}
else
{
if( Args.fRangeMin == ceil(Args.fRangeMin) )
{
_ADDSTRP("%.0f,",Args.fRangeMin);
}
else
{
_ADDSTRP("%.4f,",Args.fRangeMin);
}
}
if( FLT_MAX == Args.fRangeMax )
{
_ADDSTR("FLT_MAX]");
}
else
{
if( Args.fRangeMax == floor(Args.fRangeMax) )
{
_ADDSTRP("%.0f]",Args.fRangeMax);
}
else
{
_ADDSTRP("%.4f]",Args.fRangeMax);
}
}
}
_StepOverInst(RDPSINST_DSTMOD)
break;
case RDPSINST_MOV:
{
_DeclArgs(RDPSINST_MOV)
_ADDSTR("mov ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_MOV)
break;
case RDPSINST_RCP:
{
_DeclArgs(RDPSINST_RCP)
_ADDSTR("rcp ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_RCP)
break;
case RDPSINST_FRC:
{
_DeclArgs(RDPSINST_FRC)
_ADDSTR("frc ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_FRC)
break;
case RDPSINST_ADD:
{
_DeclArgs(RDPSINST_ADD)
_ADDSTR("add ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_ADD)
break;
case RDPSINST_SUB:
{
_DeclArgs(RDPSINST_SUB)
_ADDSTR("sub ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_SUB)
break;
case RDPSINST_MUL:
{
_DeclArgs(RDPSINST_MUL)
_ADDSTR("mul ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_MUL)
break;
case RDPSINST_DP3:
{
_DeclArgs(RDPSINST_DP3)
_ADDSTR("dp3 ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_DP3)
break;
case RDPSINST_DP4:
{
_DeclArgs(RDPSINST_DP4)
_ADDSTR("dp4 ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_DP4)
break;
case RDPSINST_MAD:
{
_DeclArgs(RDPSINST_MAD)
_ADDSTR("mad ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg2,RDPS_NOSWIZZLE,Args.bSrcReg2_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_MAD)
break;
case RDPSINST_LRP:
{
_DeclArgs(RDPSINST_LRP)
_ADDSTR("lrp ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg2,RDPS_NOSWIZZLE,Args.bSrcReg2_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_LRP)
break;
case RDPSINST_CND:
{
_DeclArgs(RDPSINST_LRP)
_ADDSTR("cnd ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg2,RDPS_NOSWIZZLE,Args.bSrcReg2_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_CND)
break;
case RDPSINST_CMP:
{
_DeclArgs(RDPSINST_CMP)
_ADDSTR("cmp ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg2,RDPS_NOSWIZZLE,Args.bSrcReg2_Negate); _ADDSTRP("%s", pTempStr);
}
_StepOverInst(RDPSINST_CMP)
break;
case RDPSINST_TEXCOVERAGE:
// don't bother to spew this (ref specific)
_StepOverInst(RDPSINST_TEXCOVERAGE)
break;
case RDPSINST_QUADLOOPBEGIN:
// don't bother to spew this
_StepOverInst(RDPSINST_QUADLOOPBEGIN)
break;
case RDPSINST_QUADLOOPEND:
// don't bother to spew this
_StepOverInst(RDPSINST_QUADLOOPEND)
break;
case RDPSINST_QUEUEWRITE:
{
_DeclArgs(RDPSINST_QUEUEWRITE)
_ADDSTR("queueWrite ");
RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s", pTempStr);
_StepOverInst(RDPSINST_QUEUEWRITE)
break;
}
case RDPSINST_FLUSHQUEUE:
_ADDSTR("flushQueue ");
_StepOverInst(RDPSINST_FLUSHQUEUE)
break;
case RDPSINST_NEXTD3DPSINST:
_ADDSTRP("------------------------------------------------- D3D PS Inst: '%s'",
_InstParam(RDPSINST_NEXTD3DPSINST).pInst->Text);
_StepOverInst(RDPSINST_NEXTD3DPSINST)
break;
default:
_ASSERT(FALSE,"RDPSDisAsm - Unrecognized refrast internal pixel shader instruction.");
break;
}
if( 0 != *pStr )
{
RDDebugPrintf( pStr );
*pStr = 0;
}
}
_ADDSTR("------------------------------------------------- End of pixel shader. ------");
RDDebugPrintf( pStr );
}
//-----------------------------------------------------------------------------
//
// UpdateLegacyPixelShader - Constructs pixel shader which performs all of
// the texture lookups, including bump mapping, for the legacy pixel shading
// model. Result of running this shader is the full set of texture lookups
// in the temporary registers, which are then blended with the pixel diffuse
// and specular colors using the legacy texture blend code.
//
//-----------------------------------------------------------------------------
// destination parameter token
#define D3DSPD( _RegFile, _Num ) (\
(1L<<31) | (D3DSPR_##_RegFile) |\
((_Num)&D3DSP_REGNUM_MASK) |\
(D3DSP_WRITEMASK_0|D3DSP_WRITEMASK_1|D3DSP_WRITEMASK_2|D3DSP_WRITEMASK_3) )
// source paramater token
#define D3DPSPS( _RegFile, _Num ) (\
(1L<<31) | ((_Num)&D3DSP_REGNUM_MASK) |\
D3DSP_NOSWIZZLE | (D3DSPR_##_RegFile) )
void
RefRast::UpdateLegacyPixelShader( void )
{
if (m_pLegacyPixelShader) delete m_pLegacyPixelShader;
m_pLegacyPixelShader = NULL;
DWORD Tokens[64];
DWORD* pToken = Tokens;
*pToken++ = D3DPS_VERSION(0xfe,0xfe);
BOOL bSkipNextStage = FALSE;
for ( int iStage=0; iStage<D3DHAL_TSS_MAXSTAGES; iStage++ )
{
if ( m_pRD->m_TextureStageState[iStage].m_dwVal[D3DTSS_COLOROP] == D3DTOP_DISABLE )
{
break;
}
if (bSkipNextStage) { bSkipNextStage = FALSE; continue; }
BOOL bIsBEM = ( m_pRD->m_TextureStageState[iStage].m_dwVal[D3DTSS_COLOROP] == D3DTOP_BUMPENVMAP );
BOOL bIsBEML = ( m_pRD->m_TextureStageState[iStage].m_dwVal[D3DTSS_COLOROP] == D3DTOP_BUMPENVMAPLUMINANCE );
if ( bIsBEM || bIsBEML )
{
// DX6/7 BEM(L) was set for stage with bump map (i.e. first of two), while DX8
// BEM(L) is set for a subsequent stage, so we have to set a 'standard' texture
// to this stage and BEM(L) for the next stage, then stop anything else from being
// set for the next stage
*pToken++ = D3DSIO_TEX;
*pToken++ = D3DSPD(TEXTURE, iStage);
*pToken++ = (bIsBEM) ? (D3DSIO_TEXBEM_LEGACY) : (D3DSIO_TEXBEML_LEGACY);
*pToken++ = D3DSPD(TEXTURE, iStage+1);
*pToken++ = D3DPSPS(TEXTURE, iStage);
bSkipNextStage = TRUE;
}
else
{
// simple lookup into 'iStage' texture register
*pToken++ = D3DSIO_TEX;
*pToken++ = D3DSPD(TEXTURE, iStage);
}
}
*pToken++ = D3DPS_END();
if ( pToken > (Tokens+2) )
{
m_pLegacyPixelShader = new RDPShader;
if (NULL == m_pLegacyPixelShader)
DPFERR("E_OUTOFMEMORY");
m_pLegacyPixelShader->Initialize( m_pRD, Tokens, 4*(pToken-Tokens), m_pRD->GetCaps8() );
}
if (m_pRD->m_pDbgMon) m_pRD->m_pDbgMon->StateChanged( D3DDM_SC_PSMODIFYSHADERS );
return;
}
//-----------------------------------------------------------------------------
//
// Pixel Shader DP2 Command Functions
//
//-----------------------------------------------------------------------------
HRESULT
RefDev::Dp2CreatePixelShader( DWORD handle, DWORD dwCodeSize, LPDWORD pCode )
{
HRESULT hr = S_OK;
HR_RET( m_PShaderHandleArray.Grow( handle ) );
//
// Validation sequence
//
#if DBG
_ASSERT( m_PShaderHandleArray[handle].m_tag == 0,
"A shader exists with the given handle, tag is non-zero" );
#endif
_ASSERT( m_PShaderHandleArray[handle].m_pShader == NULL,
"A shader exists with the given handle" );
RDPShader* pShader;
pShader = m_PShaderHandleArray[handle].m_pShader = new RDPShader;
if( pShader == NULL )
return E_OUTOFMEMORY;
hr = pShader->Initialize( this, pCode, dwCodeSize, GetCaps8() );
if( FAILED( hr ) )
{
delete pShader;
m_PShaderHandleArray[handle].m_pShader = NULL;
#if DBG
m_PShaderHandleArray[handle].m_tag = 0;
#endif
return hr;
}
#if DBG
// Everything successful, mark this handle as in use.
m_PShaderHandleArray[handle].m_tag = 1;
#endif
if (m_pDbgMon) m_pDbgMon->StateChanged( D3DDM_SC_PSMODIFYSHADERS );
return hr;
}
HRESULT
RefDev::Dp2DeletePixelShader(LPD3DHAL_DP2COMMAND pCmd)
{
HRESULT hr = S_OK;
LPD3DHAL_DP2PIXELSHADER pPS =
(LPD3DHAL_DP2PIXELSHADER)(pCmd + 1);
for( int i = 0; i < pCmd->wStateCount; i++ )
{
DWORD handle = pPS[i].dwHandle;
_ASSERT( m_PShaderHandleArray.IsValidIndex( handle ),
"DeletePixelShader: invalid shader handle" );
_ASSERT( m_PShaderHandleArray[handle].m_pShader,
"DeletePixelShader: invalid shader" );
delete m_PShaderHandleArray[handle].m_pShader;
m_PShaderHandleArray[handle].m_pShader = NULL;
#if DBG
m_PShaderHandleArray[handle].m_tag = 0;
#endif
if( handle == m_CurrentPShaderHandle )
{
m_CurrentPShaderHandle = 0;
m_dwRastFlags |= RDRF_PIXELSHADER_CHANGED;
}
}
if (m_pDbgMon) m_pDbgMon->StateChanged( D3DDM_SC_PSMODIFYSHADERS );
return hr;
}
HRESULT
RefDev::Dp2SetPixelShader(LPD3DHAL_DP2COMMAND pCmd)
{
HRESULT hr = S_OK;
RDPShader* pShader = NULL;
LPD3DHAL_DP2PIXELSHADER pPS =
(LPD3DHAL_DP2PIXELSHADER)(pCmd + 1);
// Just set the last Pixel Shader in this array
DWORD handle = pPS[pCmd->wStateCount-1].dwHandle;
if (handle)
{
if( !m_PShaderHandleArray.IsValidIndex( handle )
||
(m_PShaderHandleArray[handle].m_pShader == NULL) )
{
DPFERR( "Such a Pixel Shader has not been created" );
return E_INVALIDARG;
}
pShader = m_PShaderHandleArray[handle].m_pShader;
}
m_CurrentPShaderHandle = handle;
m_dwRastFlags |= RDRF_PIXELSHADER_CHANGED;
if( pShader )
{
for( UINT i = 0; i < pShader->m_cConstDefs; i++ )
{
// constant regs are duplicated for 4 pixel grid
for (UINT iP=0; iP<4; iP++)
{
// Consts from DEF instructions have already been clamped,
// so just copy them.
memcpy( m_Rast.m_ConstReg[pShader->m_pConstDefs[i].RegNum][iP],
pShader->m_pConstDefs[i].f, 4*sizeof(FLOAT) );
}
}
}
if (m_pDbgMon) m_pDbgMon->StateChanged( D3DDM_SC_PSSETSHADER );
return hr;
}
HRESULT
RefDev::Dp2SetPixelShaderConsts( DWORD StartReg, DWORD dwCount,
LPDWORD pData )
{
HRESULT hr = S_OK;
if ( (StartReg+dwCount) > RDPS_MAX_NUMCONSTREG )
{
DPFERR("start/count out of range in SetPixelShaderConstant");
return D3DERR_INVALIDCALL;
}
FLOAT* pfData = (FLOAT*)pData;
FLOAT fMin = -(GetCaps8()->MaxPixelShaderValue);
FLOAT fMax = (GetCaps8()->MaxPixelShaderValue);
UINT End = StartReg + dwCount;
for (UINT iR=StartReg; iR<End; iR++)
{
// clamp constants on input to range of values in pixel shaders
FLOAT fConst[4];
fConst[0] = MAX( fMin, MIN( fMax, *(pfData+0) ) );
fConst[1] = MAX( fMin, MIN( fMax, *(pfData+1) ) );
fConst[2] = MAX( fMin, MIN( fMax, *(pfData+2) ) );
fConst[3] = MAX( fMin, MIN( fMax, *(pfData+3) ) );
pfData += 4;
// constant regs are duplicated for 4 pixel grid
for (UINT iP=0; iP<4; iP++)
{
m_Rast.m_ConstReg[iR][iP][0] = fConst[0];
m_Rast.m_ConstReg[iR][iP][1] = fConst[1];
m_Rast.m_ConstReg[iR][iP][2] = fConst[2];
m_Rast.m_ConstReg[iR][iP][3] = fConst[3];
}
}
if (m_pDbgMon) m_pDbgMon->StateChanged( D3DDM_SC_PSCONSTANTS );
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// end