/*==========================================================================; * * Copyright (C) 1995-2000 Microsoft Corporation. All Rights Reserved. * * File: vstream.h * Content: Direct3D Vertex Streams header * * ***************************************************************************/ #ifndef _VSTREAM_H #define _VSTREAM_H //--------------------------------------------------------------------- // Constants //--------------------------------------------------------------------- const DWORD RD_MAX_NUMELEMENTS = 16; const DWORD RD_MAX_NUMSTREAMS = RD_MAX_NUMELEMENTS; const DWORD RDVSD_STREAMTESS = RD_MAX_NUMSTREAMS; const DWORD RD_MAX_SHADERINSTSTRING = 128; const DWORD RD_MAX_SHADERTOKENSPERINST = 32; //--------------------------------------------------------------------- // macros for parsing Declaration Token Array // TRUE, if shader handle is DX7 FVF code //--------------------------------------------------------------------- #define RDVSD_ISLEGACY(ShaderHandle) !(ShaderHandle & D3DFVF_RESERVED0) enum RDVSD_DATALOAD { RDVSD_LOADREGISTER = 0, RDVSD_SKIP }; #define RDVSD_GETTOKENTYPE(token) \ ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) #define RDVSD_ISSTREAMTESS(token) \ ((token & D3DVSD_STREAMTESSMASK) >> D3DVSD_STREAMTESSSHIFT) #define RDVSD_GETDATALOADTYPE(token) \ ((token & D3DVSD_DATALOADTYPEMASK) >> D3DVSD_DATALOADTYPESHIFT) #define RDVSD_GETDATATYPE(token) \ ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT) #define RDVSD_GETSKIPCOUNT(token) \ ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT) #define RDVSD_GETSTREAMNUMBER(token) \ ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT) #define RDVSD_GETVERTEXREG(token) \ ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT) #define RDVSD_GETVERTEXREGIN(token) \ ((token & D3DVSD_VERTEXREGINMASK) >> D3DVSD_VERTEXREGINSHIFT) #define RDVSD_GETCONSTCOUNT(token) \ ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT) #define RDVSD_GETCONSTADDRESS(token) \ ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT) #define RDVSD_GETCONSTRS(token) \ ((token & D3DVSD_CONSTRSMASK) >> D3DVSD_CONSTRSSHIFT) #define RDVSD_GETEXTCOUNT(token) \ ((token & D3DVSD_EXTCOUNTMASK) >> D3DVSD_EXTCOUNTSHIFT) #define RDVSD_GETEXTINFO(token) \ ((token & D3DVSD_EXTINFOMASK) >> D3DVSD_EXTINFOSHIFT) //--------------------------------------------------------------------- // // RDVElement: Describes a vertex element // //--------------------------------------------------------------------- // Function pointer that copies a vertex element into the 4-float vector. typedef void (*PFN_RDCOPYELEMENT)(LPVOID pInputStream, RDVECTOR4* pVertexRegister); class RDVElement { public: RDVElement() { memset( this, 0, sizeof( RDVElement ) ); } // Pointer to a function to convert input vertex element data type to // the RDVECTOR4 PFN_RDCOPYELEMENT m_pfnCopy; DWORD m_dwToken; // The token that described this vertex element. DWORD m_dwRegister; // Input register index DWORD m_dwDataType; // Data type and dimension DWORD m_dwStreamIndex; // API stream index DWORD m_dwOffset; // Offset in the input stream in bytes // // Tesselator support // BOOL m_bIsTessGen; // Is this vertex element generated by // tesselator DWORD m_dwRegisterIn; // Tesselator Input register index DWORD m_dwStreamIndexIn;// API stream index for m_dwRegisterIn DWORD m_dwOffsetIn; // Offset for m_dwRegisterIn in bytes }; //--------------------------------------------------------------------- // // RDVConstantData: Constant data that is used by a shader // //--------------------------------------------------------------------- class RDVConstantData: public RDListEntry { public: RDVConstantData() {m_pData = NULL; m_dwCount = 0;} ~RDVConstantData() {delete m_pData;} DWORD m_dwCount; // Number of 4*DWORDs to load DWORD m_dwAddress; // Start constant register DWORD* m_pData; // Data. Multiple of 4*DWORD }; //----------------------------------------------------------------------------- // // RDVStream: Class representing the vertex stream. // //----------------------------------------------------------------------------- class RDVStream { public: RDVStream() { m_pData = NULL; m_pSavedData = NULL; m_dwHandle = 0; m_dwNumVertices = 0; m_dwSize = 0; } // Stream memory. LPBYTE m_pData; // Temporary pointer LPBYTE m_pSavedData; // Vertex buffer handle DWORD m_dwHandle; // Vertex (or index) stride in bytes DWORD m_dwStride; // Max number of vertices (or indices in case of index buffer) the buffer // can store DWORD m_dwNumVertices; // Buffer size in bytes DWORD m_dwSize; // Output array for a tessellator GArrayT m_TessOut; }; //----------------------------------------------------------------------------- // // RDIStream: Class representing the current Index stream // //----------------------------------------------------------------------------- class RDIStream: public RDVStream { public: RDIStream() { m_dwFlags = 0; } DWORD m_dwFlags; // User passed flags }; //--------------------------------------------------------------------- // // RDVStreamDecl: // // Describes a stream, used by a declaration // //--------------------------------------------------------------------- class RDVStreamDecl { public: RDVStreamDecl(); // Parses declaration. // For fixed-function pipeline computes FVF and FVF2 (used to record // texture presence) HRESULT Parse(DWORD ** ppToken, BOOL bFixedFunction, BOOL bStreamTess, UINT64* pqwFVF, UINT64* pqwFVF2, DWORD* pdwNumBetas); HRESULT MakeVElementArray( UINT64 qwFVF ); RDVElement m_Elements[RD_MAX_NUMELEMENTS]; // Vertex elements in the // stream. DWORD m_dwNumElements; // Number of elements to use DWORD m_dwStride; // Vertex size in bytes DWORD m_dwStreamIndex; // Index to device streams BOOL m_bIsStreamTess; // Is it a tesselator stream ? }; //--------------------------------------------------------------------- // // RDVShaderInst: // The object representing each shader instruction. Used for // debugging, since the reference implementation directly interprets // the raw token stream during vshader execution. //----------------------------------------------------------------------------- class RDVShaderInst { public: char m_String[RD_MAX_SHADERINSTSTRING]; DWORD m_Tokens[RD_MAX_SHADERTOKENSPERINST]; DWORD* m_pComment; DWORD m_CommentSize; }; //--------------------------------------------------------------------- // // RDVShaderCode: // The object representing the compiled shader code. // In the reference implementation, there is really no compiling // happening. The compile phase consists of: // 1) Validating the the code. // 2) Computing the output FVF. // 3) Saving the original bits for later interpretation. // In the execution phase (in the RefVM) these saved bits are // interpreted. //----------------------------------------------------------------------------- class RDVShaderCode { public: RDVShaderCode() { memset( this, 0, sizeof( this ) ); } ~RDVShaderCode(){ delete m_pRawBits; if (m_pInst) delete m_pInst; } inline UINT GetInstructionCount( void ) { return m_InstCount; } LPDWORD m_pRawBits; // Raw code bits DWORD m_dwSize; // Number of DWORDs UINT m_InstCount; // Instruction count (for debug monitor) RDVShaderInst* m_pInst; // Instruction array (for debug monitor) // Output FVF for this shaders UINT64 m_qwFVFOut; }; //--------------------------------------------------------------------- // // RDVDeclaration: // The object representing the parsed and compiled declaration. //----------------------------------------------------------------------------- class RDVDeclaration { public: RDVDeclaration() { memset( this, 0, sizeof( RDVDeclaration ) ); } ~RDVDeclaration(); HRESULT Parse( DWORD * decl, BOOL bFixedFunction ); HRESULT MakeVElementArray( UINT64 qwFVF ); // List of streams, which are used by the declaration // The additional one is used for the Tesselator stream. RDVStreamDecl m_StreamArray[RD_MAX_NUMSTREAMS + 1]; // Number of active streams DWORD m_dwNumActiveStreams; // Corresponding FVF for fixed-function pipeline // This is OR of all streams input FVF UINT64 m_qwInputFVF; // Constant data that should be loaded when shader becomes active RDVConstantData* m_pConstants; // The description of all vertex elements to be loaded into input // registers. The array is built by going through active streams and // elements inside each stream RDVElement m_VertexElements[RD_MAX_NUMELEMENTS]; // Number of used members of m_VertexElements DWORD m_dwNumElements; // Stride computed for the implicit tesselator stream DWORD m_dwStreamTessStride; }; //----------------------------------------------------------------------------- // // RDVShader: Vertex Shader Class // //----------------------------------------------------------------------------- class RDVShader { public: RDVShader(); ~RDVShader(); HRESULT Initialize(DWORD* lpdwDeclaration, DWORD* lpdwFunction); RDVDeclaration m_Declaration; RDVShaderCode* m_pCode; inline BOOL IsFixedFunction() { return (m_pCode == NULL); } }; typedef RDVShader *PRDVSHADER; #endif _VSTREAM_H