windows-nt/Source/XPSP1/NT/multimedia/directx/dxg/d3d8/shval/valbase.hpp

229 lines
9.3 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) Microsoft Corporation, 2000.
//
// valbase.hpp
//
// Direct3D Reference Device - Vertex/PixelShader validation common infrastructure
//
///////////////////////////////////////////////////////////////////////////////
#ifndef __VALBASE_HPP__
#define __VALBASE_HPP__
#define NUM_COMPONENTS_IN_REGISTER 4
#define SHADER_INSTRUCTION_MAX_PARAMS 4
#define SHADER_INSTRUCTION_MAX_SRCPARAMS (SHADER_INSTRUCTION_MAX_PARAMS - 1)
typedef enum _SPEW_TYPE
{
SPEW_INSTRUCTION_ERROR,
SPEW_INSTRUCTION_WARNING,
SPEW_GLOBAL_ERROR,
SPEW_GLOBAL_WARNING
} SPEW_TYPE;
typedef enum _SHADER_VALIDATOR_FLAGS
{
SHADER_VALIDATOR_LOG_ERRORS = 0x1,
SHADER_VALIDATOR_OPTIMIZE_WRITEMASKS = 0x2
} SHADER_VALIDATOR_FLAGS;
typedef enum _DSTSHIFT
{
DSTSHIFT_NONE = 0x0,
DSTSHIFT_X2 = 0x1,
DSTSHIFT_X4 = 0x2,
DSTSHIFT_X8 = 0x3,
DSTSHIFT_D2 = 0xF,
DSTSHIFT_D4 = 0xE,
DSTSHIFT_D8 = 0xD
} DSTSHIFT;
const DWORD COMPONENT_MASKS[4] = {D3DSP_WRITEMASK_0, D3DSP_WRITEMASK_1, D3DSP_WRITEMASK_2, D3DSP_WRITEMASK_3};
//-----------------------------------------------------------------------------
// DSTPARAM - part of CBaseInstruction
//-----------------------------------------------------------------------------
class DSTPARAM
{
public:
DSTPARAM();
BOOL m_bParamUsed; // Does instruction have dest param?
UINT m_RegNum;
DWORD m_WriteMask; // writemasks (D3DSP_WRITEMASK_*)
D3DSHADER_PARAM_DSTMOD_TYPE m_DstMod; // D3DSPDM_NONE, D3DSPDM_SATURATE (PShader)
DSTSHIFT m_DstShift; // _x2, _x4, etc. (PShader)
D3DSHADER_PARAM_REGISTER_TYPE m_RegType; // _TEMP, _ADDRESS, etc.
DWORD m_ComponentReadMask; // Which components instruction needs to read
// This seems strage, but in ps.2.0 there are some ops
// that have one parameter (dest), but they read from it, and write back to it.
};
//-----------------------------------------------------------------------------
// SRCPARAM - part of CBaseInstruction
//-----------------------------------------------------------------------------
class SRCPARAM
{
public:
SRCPARAM();
BOOL m_bParamUsed; // Does instruction have this src param?
UINT m_RegNum;
DWORD m_SwizzleShift; // D3DVS_*_*, or D3DSP_NOSWIZZLE/
// D3DSP_REPLICATERED/GREEN/BLUE/ALPHA
D3DVS_ADDRESSMODE_TYPE m_AddressMode; // D3DVS_ADDRMODE_ABSOLUTE / _RELATIVE (VShader)
DWORD m_RelativeAddrComponent; // One of D3DSP_WRITEMASK_0, 1, 2, or 3. (VShader)
D3DSHADER_PARAM_SRCMOD_TYPE m_SrcMod; // _NEG, _BIAS, etc.
D3DSHADER_PARAM_REGISTER_TYPE m_RegType; // _TEMP, _CONST, etc.
DWORD m_ComponentReadMask; // Which components instruction needs to read
};
//-----------------------------------------------------------------------------
// CBaseInstruction
//-----------------------------------------------------------------------------
class CBaseInstruction
{
public:
CBaseInstruction(CBaseInstruction* pPrevInst); // Append to linked list
void SetSpewFileNameAndLineNumber(const char* pFileName, const DWORD* pLineNumber);
char* MakeInstructionLocatorString();
virtual void CalculateComponentReadMasks(DWORD dwVersion) = 0; // which components to each source read?
// Instruction Description
D3DSHADER_INSTRUCTION_OPCODE_TYPE m_Type;
UINT m_DstParamCount;
UINT m_SrcParamCount;
CBaseInstruction* m_pPrevInst;
CBaseInstruction* m_pNextInst;
const DWORD* m_pSpewLineNumber; // points to line number embedded in shader by assembler (if present)
const char* m_pSpewFileName; // points to file name embedded in shader (if present)
UINT m_SpewInstructionCount; // only used for spew, not for any limit checking
// Destination Parameter Description
DSTPARAM m_DstParam;
// Source Parameters
SRCPARAM m_SrcParam[SHADER_INSTRUCTION_MAX_SRCPARAMS];
};
//-----------------------------------------------------------------------------
// CAccessHistoryNode
//-----------------------------------------------------------------------------
class CAccessHistoryNode
{
public:
CAccessHistoryNode(CAccessHistoryNode* pPreviousAccess,
CAccessHistoryNode* pPreviousWriter,
CAccessHistoryNode* pPreviousReader,
CBaseInstruction* pInst,
BOOL bWrite );
CAccessHistoryNode* m_pPreviousAccess;
CAccessHistoryNode* m_pNextAccess;
CAccessHistoryNode* m_pPreviousWriter;
CAccessHistoryNode* m_pPreviousReader;
CBaseInstruction* m_pInst;
BOOL m_bWrite;
BOOL m_bRead;
};
//-----------------------------------------------------------------------------
// CAccessHistory
//-----------------------------------------------------------------------------
class CAccessHistory
{
public:
CAccessHistory();
~CAccessHistory();
CAccessHistoryNode* m_pFirstAccess;
CAccessHistoryNode* m_pMostRecentAccess;
CAccessHistoryNode* m_pMostRecentWriter;
CAccessHistoryNode* m_pMostRecentReader;
BOOL m_bPreShaderInitialized;
BOOL NewAccess(CBaseInstruction* pInst, BOOL bWrite );
BOOL InsertReadBeforeWrite(CAccessHistoryNode* pWriteNode, CBaseInstruction* pInst);
};
//-----------------------------------------------------------------------------
// CRegisterFile
//-----------------------------------------------------------------------------
class CRegisterFile
{
UINT m_NumRegisters;
BOOL m_bWritable;
UINT m_NumReadPorts;
BOOL m_bInitOk;
public:
CRegisterFile(UINT NumRegisters, BOOL bWritable, UINT NumReadPorts, BOOL bPreShaderInitialized );
~CRegisterFile();
inline UINT GetNumRegs() {return m_NumRegisters;};
inline BOOL IsWritable() {return m_bWritable;};
inline UINT GetNumReadPorts() {return m_NumReadPorts;};
inline BOOL InitOk() {return m_bInitOk;};
CAccessHistory* m_pAccessHistory[NUM_COMPONENTS_IN_REGISTER];
};
//-----------------------------------------------------------------------------
// CBaseShaderValidator
//-----------------------------------------------------------------------------
class CBaseShaderValidator
{
protected:
BOOL m_bBaseInitOk;
DWORD m_Version;
UINT m_SpewInstructionCount; // only used for spew, not for any limit checking
CBaseInstruction* m_pInstructionList;
const DWORD* m_pCurrToken;
HRESULT m_ReturnCode;
BOOL m_bSeenAllInstructions;
DWORD m_ErrorCount;
CErrorLog* m_pLog;
CBaseInstruction* m_pCurrInst;
const D3DCAPS8* m_pCaps; // can be NULL if not provided.
const DWORD* m_pLatestSpewLineNumber; // points to latest line number sent in comment from D3DX Assembler
const char* m_pLatestSpewFileName; // points to latest file name sent in comment from D3DX Assembler
// m_bSrcParamError needed by Rule_SrcInitialized (in both vshader and pshader)
BOOL m_bSrcParamError[SHADER_INSTRUCTION_MAX_SRCPARAMS];
virtual BOOL DecodeNextInstruction() = 0;
void DecodeDstParam( DSTPARAM* pDstParam, DWORD Token );
void DecodeSrcParam( SRCPARAM* pSrcParam, DWORD Token );
virtual BOOL InitValidation() = 0;
void ValidateShader();
virtual BOOL ApplyPerInstructionRules() = 0;
virtual void ApplyPostInstructionsRules() = 0;
virtual CBaseInstruction* AllocateNewInstruction(CBaseInstruction* pPrevInst) = 0;
void ParseCommentForAssemblerMessages(const DWORD* pComment);
void Spew( SPEW_TYPE SpewType,
CBaseInstruction* pInst /* can be NULL */,
const char* pszFormat, ... );
char* MakeAffectedComponentsText( DWORD ComponentMask,
BOOL bColorLabels = TRUE,
BOOL bPositionLabels = TRUE);
public:
CBaseShaderValidator( const DWORD* pCode, const D3DCAPS8* pCaps, DWORD Flags );
~CBaseShaderValidator();
DWORD GetRequiredLogBufferSize()
{
if( m_pLog )
return m_pLog->GetRequiredLogBufferSize();
else
return 0;
}
void WriteLogToBuffer( char* pBuffer )
{
if( m_pLog ) m_pLog->WriteLogToBuffer( pBuffer );
}
HRESULT GetStatus() { return m_ReturnCode; };
};
#endif //__VALBASE_HPP__