You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1249 lines
44 KiB
1249 lines
44 KiB
/******************************Module*Header**********************************\
|
|
*
|
|
* *******************
|
|
* * D3D SAMPLE CODE *
|
|
* *******************
|
|
*
|
|
* Module Name: d3dsset.c
|
|
*
|
|
* Content: State set (block) management
|
|
*
|
|
* Copyright (c) 1999-2003 Microsoft Corporation. All rights reserved.
|
|
\*****************************************************************************/
|
|
#include "glint.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// This module implements an emulation mechanism for handling state blocks
|
|
// (which are a required feature of the DX7 DDI) for hardware that doesn't
|
|
// offer any silicon support of the feature. It works simply by recording the
|
|
// render states and texture stage states set during state block recording
|
|
// and then "plays" them back when execution of the stage state is requested.
|
|
// Internal data structures are interchangeable between an uncompressed
|
|
// version (for recording speed) and a compressed format (for memory
|
|
// efficiency) since it is anticipated some apps may request thousands of
|
|
// state blocks.
|
|
//
|
|
// The following symbols have to be replaced according to your perticular
|
|
// driver implementation:
|
|
// - HEAP_ALLOC
|
|
// - HEAP_FREE
|
|
// - DISPDBG
|
|
// - _D3D_ST_ProcessOneRenderState
|
|
// - _D3D_TXT_ParseTextureStageStates
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#if DX7_D3DSTATEBLOCKS
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// P3StateSetRec *__SB_FindStateSet
|
|
//
|
|
// Find a state identified by dwHandle starting from pRootSS.
|
|
// If not found, returns NULL.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
P3StateSetRec *__SB_FindStateSet(P3_D3DCONTEXT *pContext,
|
|
DWORD dwHandle)
|
|
{
|
|
if (dwHandle <= pContext->dwMaxSSIndex)
|
|
{
|
|
return pContext->pIndexTableSS[dwHandle - 1];
|
|
}
|
|
else
|
|
{
|
|
DISPDBG((DBGLVL,"State set %x not found (Max = %x)",
|
|
dwHandle, pContext->dwMaxSSIndex));
|
|
return NULL;
|
|
}
|
|
} // __SB_FindStateSet
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void __SB_DumpStateSet
|
|
//
|
|
// Dump info stored in a state set
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
#define ELEMS_IN_ARRAY(a) ((sizeof(a)/sizeof(a[0])))
|
|
|
|
void __SB_DumpStateSet(P3StateSetRec *pSSRec)
|
|
{
|
|
DWORD i,j;
|
|
|
|
DISPDBG((DBGLVL,"__SB_DumpStateSet %x, Id=%x dwSSFlags=%x",
|
|
pSSRec,pSSRec->dwHandle,pSSRec->dwSSFlags));
|
|
|
|
if (!(pSSRec->dwSSFlags & SB_COMPRESSED))
|
|
{
|
|
// uncompressed state set
|
|
|
|
// Dump render states values
|
|
for (i=0; i< MAX_STATE; i++)
|
|
{
|
|
DISPDBG((DBGLVL,"RS %x = %x",i, pSSRec->uc.RenderStates[i]));
|
|
}
|
|
|
|
// Dump TSS's values
|
|
for (j=0; j<= SB_MAX_STAGES; j++)
|
|
{
|
|
for (i=0; i<= D3DTSS_TEXTURETRANSFORMFLAGS; i++)
|
|
{
|
|
DISPDBG((DBGLVL,"TSS [%x] %x = %x",
|
|
j, i, pSSRec->uc.TssStates[j][i]));
|
|
}
|
|
}
|
|
|
|
// Dump RS bit masks
|
|
for (i=0; i< ELEMS_IN_ARRAY(pSSRec->uc.bStoredRS); i++)
|
|
{
|
|
DISPDBG((DBGLVL,"bStoredRS[%x] = %x",
|
|
i, pSSRec->uc.bStoredRS[i]));
|
|
}
|
|
|
|
// Dump TSS bit masks
|
|
for (j=0; j<= SB_MAX_STAGES; j++)
|
|
{
|
|
for (i=0; i< ELEMS_IN_ARRAY(pSSRec->uc.bStoredTSS[j]); i++)
|
|
{
|
|
DISPDBG((DBGLVL,"bStoredTSS[%x][%x] = %x",
|
|
j, i, pSSRec->uc.bStoredTSS[j][i]));
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// compressed state set
|
|
|
|
D3DHAL_DP2COMMAND *pDP2Cmd;
|
|
D3DHAL_DP2RENDERSTATE *pDP2RenderState;
|
|
D3DHAL_DP2TEXTURESTAGESTATE *pDP2TSState;
|
|
|
|
pDP2Cmd = pSSRec->cc.pDP2RenderState;
|
|
if (pDP2Cmd)
|
|
{
|
|
DISPDBG((DBGLVL,"dwNumRS =%x", pDP2Cmd->wStateCount));
|
|
pDP2RenderState = (D3DHAL_DP2RENDERSTATE *)(pDP2Cmd + 1);
|
|
for (i=0; i< pDP2Cmd->wStateCount; i++, pDP2RenderState++)
|
|
{
|
|
DISPDBG((DBGLVL,"RS %x = %x",
|
|
pDP2RenderState->RenderState,
|
|
pDP2RenderState->dwState));
|
|
}
|
|
|
|
}
|
|
|
|
pDP2Cmd = pSSRec->cc.pDP2TextureStageState;
|
|
if (pDP2Cmd)
|
|
{
|
|
DISPDBG((DBGLVL,"dwNumTSS=%x", pDP2Cmd->wStateCount));
|
|
pDP2TSState = (D3DHAL_DP2TEXTURESTAGESTATE *)(pDP2Cmd + 1);
|
|
for (i = 0; i < pDP2Cmd->wStateCount; i++, pDP2TSState++)
|
|
{
|
|
DISPDBG((DBGLVL,"TSS [%x] %x = %x",
|
|
pDP2TSState->wStage,
|
|
pDP2TSState->TSState,
|
|
pDP2TSState->dwValue));
|
|
}
|
|
}
|
|
}
|
|
|
|
} // __SB_DumpStateSet
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void __SB_AddStateSetIndexTableEntry
|
|
//
|
|
// Add an antry to the index table. If necessary, grow it.
|
|
//-----------------------------------------------------------------------------
|
|
void __SB_AddStateSetIndexTableEntry(P3_D3DCONTEXT* pContext,
|
|
DWORD dwNewHandle,
|
|
P3StateSetRec *pNewSSRec)
|
|
{
|
|
DWORD dwNewSize;
|
|
P3StateSetRec **pNewIndexTableSS;
|
|
|
|
// If the current list is not large enough, we'll have to grow a new one.
|
|
if (dwNewHandle > pContext->dwMaxSSIndex)
|
|
{
|
|
// New size of our index table
|
|
// (round up dwNewHandle in steps of SSPTRS_PERPAGE)
|
|
dwNewSize = ((dwNewHandle -1 + SSPTRS_PERPAGE) / SSPTRS_PERPAGE)
|
|
* SSPTRS_PERPAGE;
|
|
|
|
// we have to grow our list
|
|
pNewIndexTableSS = (P3StateSetRec **)
|
|
HEAP_ALLOC( FL_ZERO_MEMORY,
|
|
dwNewSize*sizeof(P3StateSetRec *),
|
|
ALLOC_TAG_DX(2));
|
|
|
|
if (!pNewIndexTableSS)
|
|
{
|
|
// we weren't able to grow the list so we will keep the old one
|
|
// and (sigh) forget about this state set since that is the
|
|
// safest thing to do. We will delete also the state set structure
|
|
// since no one will otherwise be able to find it later.
|
|
DISPDBG((ERRLVL,"Out of mem growing state set list,"
|
|
" droping current state set"));
|
|
HEAP_FREE(pNewSSRec);
|
|
return;
|
|
}
|
|
|
|
if (pContext->pIndexTableSS)
|
|
{
|
|
// if we already had a previous list, we must transfer its data
|
|
memcpy(pNewIndexTableSS,
|
|
pContext->pIndexTableSS,
|
|
pContext->dwMaxSSIndex*sizeof(P3StateSetRec *));
|
|
|
|
//and get rid of it
|
|
HEAP_FREE(pContext->pIndexTableSS);
|
|
}
|
|
|
|
// New index table data
|
|
pContext->pIndexTableSS = pNewIndexTableSS;
|
|
pContext->dwMaxSSIndex = dwNewSize;
|
|
}
|
|
|
|
// Store our state set pointer into our access list
|
|
pContext->pIndexTableSS[dwNewHandle - 1] = pNewSSRec;
|
|
|
|
} // __SB_AddStateSetIndexTableEntry
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// int __SB_GetCompressedSize
|
|
//
|
|
// Calculate the size of the compressed state set
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
int __SB_GetCompressedSize(P3_D3DCONTEXT* pContext,
|
|
P3StateSetRec* pUncompressedSS,
|
|
OffsetsCompSS* offsetSS)
|
|
{
|
|
DWORD dwSize;
|
|
DWORD dwCount;
|
|
int i, j;
|
|
|
|
// Calculate the size of fixed part
|
|
dwSize = sizeof(CompressedStateSet) + 2*sizeof(DWORD);
|
|
|
|
// Calculate size of the render states
|
|
dwCount = 0;
|
|
for (i = 0; i < MAX_STATE; i++)
|
|
{
|
|
if (IS_FLAG_SET(pUncompressedSS->uc.bStoredRS , i))
|
|
{
|
|
dwCount++;
|
|
}
|
|
}
|
|
if (dwCount)
|
|
{
|
|
offsetSS->dwOffDP2RenderState = dwSize;
|
|
dwSize += (sizeof(D3DHAL_DP2COMMAND) + dwCount * sizeof(D3DHAL_DP2RENDERSTATE));
|
|
}
|
|
|
|
// Calculate size of the texture stage states
|
|
dwCount = 0;
|
|
for (j = 0; j <= SB_MAX_STAGES; j++)
|
|
{
|
|
for (i = 0; i <= D3DTSS_TEXTURETRANSFORMFLAGS; i++)
|
|
{
|
|
if (IS_FLAG_SET(pUncompressedSS->uc.bStoredTSS[j] , i))
|
|
{
|
|
dwCount++;
|
|
}
|
|
}
|
|
}
|
|
if (dwCount)
|
|
{
|
|
offsetSS->dwOffDP2TextureStageState = dwSize;
|
|
dwSize += (sizeof(D3DHAL_DP2COMMAND) + dwCount * sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
|
|
}
|
|
|
|
// Calculate size of Viewport and ZRange
|
|
if (pUncompressedSS->uc.dwFlags & SB_VIEWPORT_CHANGED)
|
|
{
|
|
offsetSS->dwOffDP2Viewport = dwSize;
|
|
dwSize += (sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2VIEWPORTINFO));
|
|
}
|
|
|
|
if (pUncompressedSS->uc.dwFlags & SB_ZRANGE_CHANGED)
|
|
{
|
|
offsetSS->dwOffDP2ZRange = dwSize;
|
|
dwSize += (sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2ZRANGE));
|
|
}
|
|
|
|
#if DX8_DDI
|
|
if (pUncompressedSS->uc.dwFlags & SB_INDICES_CHANGED)
|
|
{
|
|
offsetSS->dwOffDP2SetIndices = dwSize;
|
|
dwSize += (sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETINDICES));
|
|
}
|
|
|
|
dwCount = 0;
|
|
for (i = 0; i < D3DVS_INPUTREG_MAX_V1_1; i++)
|
|
{
|
|
if (pUncompressedSS->uc.dwFlags & (SB_STREAMSRC_CHANGED << i))
|
|
{
|
|
dwCount++;
|
|
}
|
|
}
|
|
if (dwCount)
|
|
{
|
|
offsetSS->dwOffDP2SetStreamSources = dwSize;
|
|
dwSize += (sizeof(D3DHAL_DP2COMMAND) + dwCount * sizeof(D3DHAL_DP2SETSTREAMSOURCE));
|
|
}
|
|
#endif // DX8_DDI
|
|
|
|
#if DX7_SB_TNL
|
|
// TODO, Calculate size needed for lights, clip planes, material, transformation
|
|
#endif // DX7_SB_TNL
|
|
|
|
#if DX7_SB_TNL
|
|
// TODO, Calculate size needed for {V|P} shader constants
|
|
#endif // DX7_SB_TNL
|
|
|
|
#if DX8_DDI
|
|
if (pUncompressedSS->uc.dwFlags & SB_CUR_VS_CHANGED)
|
|
{
|
|
offsetSS->dwOffDP2SetVertexShader = dwSize;
|
|
dwSize += (sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2VERTEXSHADER));
|
|
}
|
|
#endif // DX8_DDI
|
|
|
|
return (dwSize);
|
|
} // __SB_GetCompressedSize
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void __SB_CompressStateSet
|
|
//
|
|
// Compress a state set so it uses the minimum necessary space. Since we expect
|
|
// some apps to make extensive use of state sets we want to keep things tidy.
|
|
// Returns address of new structure (ir old, if it wasn't compressed)
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
P3StateSetRec * __SB_CompressStateSet(P3_D3DCONTEXT* pContext,
|
|
P3StateSetRec *pUncompressedSS)
|
|
{
|
|
P3StateSetRec *pCompressedSS;
|
|
LPBYTE pTmp;
|
|
OffsetsCompSS offsetSS;
|
|
DWORD i, j, dwSize, dwCount;
|
|
D3DHAL_DP2COMMAND* pDP2Cmd;
|
|
|
|
// Initialize the offset structure
|
|
memset(&offsetSS, 0, sizeof(OffsetsCompSS));
|
|
|
|
// Create a new state set of just the right size we need
|
|
dwSize = __SB_GetCompressedSize(pContext, pUncompressedSS, &offsetSS);
|
|
|
|
if (dwSize >= pUncompressedSS->uc.dwSize)
|
|
{
|
|
// it is not efficient to compress, leave uncompressed !
|
|
pUncompressedSS->dwSSFlags &= (~SB_COMPRESSED);
|
|
return pUncompressedSS;
|
|
}
|
|
|
|
pTmp = HEAP_ALLOC(FL_ZERO_MEMORY, dwSize, ALLOC_TAG_DX(3));
|
|
if (! pTmp)
|
|
{
|
|
DISPDBG((ERRLVL,"Not enough memory left to compress D3D state set"));
|
|
pUncompressedSS->dwSSFlags &= (~SB_COMPRESSED);
|
|
return pUncompressedSS;
|
|
}
|
|
|
|
pCompressedSS = (P3StateSetRec *)pTmp;
|
|
|
|
// Adjust data in new compressed state set
|
|
pCompressedSS->dwSSFlags |= SB_COMPRESSED;
|
|
pCompressedSS->dwHandle = pUncompressedSS->dwHandle;
|
|
|
|
// Set up render state in the compressed state set
|
|
if (offsetSS.dwOffDP2RenderState)
|
|
{
|
|
D3DHAL_DP2RENDERSTATE* pDP2RS;
|
|
|
|
pDP2Cmd = (D3DHAL_DP2COMMAND *)(pTmp + offsetSS.dwOffDP2RenderState);
|
|
pCompressedSS->cc.pDP2RenderState = pDP2Cmd;
|
|
|
|
pDP2Cmd->bCommand = D3DDP2OP_RENDERSTATE;
|
|
pDP2RS = (D3DHAL_DP2RENDERSTATE *)(pDP2Cmd + 1);
|
|
|
|
for (i = 0; i < MAX_STATE; i++)
|
|
{
|
|
if (IS_FLAG_SET(pUncompressedSS->uc.bStoredRS , i))
|
|
{
|
|
pDP2RS->RenderState = i;
|
|
pDP2RS->dwState = pUncompressedSS->uc.RenderStates[i];
|
|
pDP2RS++;
|
|
}
|
|
}
|
|
|
|
pDP2Cmd->wStateCount = (WORD)(pDP2RS - ((D3DHAL_DP2RENDERSTATE *)(pDP2Cmd + 1)));
|
|
}
|
|
|
|
// Set up texture stage state in the compress state set
|
|
if (offsetSS.dwOffDP2TextureStageState)
|
|
{
|
|
D3DHAL_DP2TEXTURESTAGESTATE* pDP2TSS;
|
|
|
|
pDP2Cmd = (D3DHAL_DP2COMMAND *)(pTmp + offsetSS.dwOffDP2TextureStageState);
|
|
pCompressedSS->cc.pDP2TextureStageState = pDP2Cmd;
|
|
|
|
pDP2Cmd->bCommand = D3DDP2OP_TEXTURESTAGESTATE;
|
|
pDP2TSS = (D3DHAL_DP2TEXTURESTAGESTATE *)(pDP2Cmd + 1);
|
|
|
|
for (j = 0; j < SB_MAX_STAGES; j++)
|
|
{
|
|
for (i = 0; i <= D3DTSS_TEXTURETRANSFORMFLAGS; i++)
|
|
{
|
|
if (IS_FLAG_SET(pUncompressedSS->uc.bStoredTSS[j] , i))
|
|
{
|
|
pDP2TSS->wStage = (WORD)j;
|
|
pDP2TSS->TSState = (WORD)i;
|
|
pDP2TSS->dwValue = pUncompressedSS->uc.TssStates[j][i];
|
|
pDP2TSS++;
|
|
}
|
|
}
|
|
}
|
|
|
|
pDP2Cmd->wStateCount = (WORD)(pDP2TSS - ((D3DHAL_DP2TEXTURESTAGESTATE *)(pDP2Cmd + 1)));
|
|
}
|
|
|
|
// Set up the viewport and zrange in the compressed state set
|
|
if (offsetSS.dwOffDP2Viewport)
|
|
{
|
|
D3DHAL_DP2VIEWPORTINFO* pDP2ViewPort;
|
|
|
|
pDP2Cmd = (D3DHAL_DP2COMMAND *)(pTmp + offsetSS.dwOffDP2Viewport);
|
|
pCompressedSS->cc.pDP2Viewport = pDP2Cmd;
|
|
|
|
pDP2Cmd->bCommand = D3DDP2OP_VIEWPORTINFO;
|
|
pDP2ViewPort = (D3DHAL_DP2VIEWPORTINFO *)(pDP2Cmd + 1);
|
|
|
|
*pDP2ViewPort = pUncompressedSS->uc.viewport;
|
|
}
|
|
|
|
if (offsetSS.dwOffDP2ZRange)
|
|
{
|
|
D3DHAL_DP2ZRANGE* pDP2ZRange;
|
|
|
|
pDP2Cmd = (D3DHAL_DP2COMMAND *)(pTmp + offsetSS.dwOffDP2ZRange);
|
|
pCompressedSS->cc.pDP2ZRange = pDP2Cmd;
|
|
|
|
pDP2Cmd->bCommand = D3DDP2OP_ZRANGE;
|
|
pDP2ZRange = (D3DHAL_DP2ZRANGE *)(pDP2Cmd + 1);
|
|
|
|
*pDP2ZRange = pUncompressedSS->uc.zRange;
|
|
}
|
|
|
|
#if DX8_DDI
|
|
// Set up the vertex shader in the compressed state set
|
|
if (offsetSS.dwOffDP2SetIndices)
|
|
{
|
|
D3DHAL_DP2SETINDICES* pDP2SetIndices;
|
|
|
|
pDP2Cmd = (D3DHAL_DP2COMMAND *)(pTmp + offsetSS.dwOffDP2SetIndices);
|
|
pCompressedSS->cc.pDP2SetIndices = pDP2Cmd;
|
|
|
|
pDP2Cmd->bCommand = D3DDP2OP_SETINDICES;
|
|
pDP2SetIndices = (D3DHAL_DP2SETINDICES *)(pDP2Cmd + 1);
|
|
|
|
*pDP2SetIndices = pUncompressedSS->uc.vertexIndex;
|
|
|
|
pDP2Cmd->wStateCount = 1;
|
|
}
|
|
|
|
// Set up the vertex shader in the compressed state set
|
|
if (offsetSS.dwOffDP2SetStreamSources)
|
|
{
|
|
D3DHAL_DP2SETSTREAMSOURCE* pDP2SetStmSrc;
|
|
|
|
pDP2Cmd = (D3DHAL_DP2COMMAND *)(pTmp + offsetSS.dwOffDP2SetStreamSources);
|
|
pCompressedSS->cc.pDP2SetStreamSources = pDP2Cmd;
|
|
|
|
pDP2Cmd->bCommand = D3DDP2OP_SETSTREAMSOURCE;
|
|
pDP2SetStmSrc = (D3DHAL_DP2SETSTREAMSOURCE *)(pDP2Cmd + 1);
|
|
|
|
for (i = 0; i < D3DVS_INPUTREG_MAX_V1_1; i++)
|
|
{
|
|
if (pUncompressedSS->uc.dwFlags & (SB_STREAMSRC_CHANGED << i))
|
|
{
|
|
*pDP2SetStmSrc = pUncompressedSS->uc.streamSource[i];
|
|
pDP2SetStmSrc++;
|
|
}
|
|
}
|
|
|
|
pDP2Cmd->wPrimitiveCount = (WORD)(pDP2SetStmSrc - ((D3DHAL_DP2SETSTREAMSOURCE *)(pDP2Cmd + 1)) );
|
|
}
|
|
#endif // DX8_DDI
|
|
|
|
#if DX7_SB_TNL
|
|
// TODO, set up light, material, transform, clip plane
|
|
#endif // DX7_SB_TNL
|
|
|
|
#if DX8_SB_SHADERS
|
|
// TODO, set up shader constants
|
|
#endif // DX8_SB_SHADERS
|
|
|
|
#if DX8_DDI
|
|
// Set up the vertex shader in the compressed state set
|
|
if (offsetSS.dwOffDP2SetVertexShader)
|
|
{
|
|
D3DHAL_DP2VERTEXSHADER* pDP2SetVtxShader;
|
|
|
|
pDP2Cmd = (D3DHAL_DP2COMMAND *)(pTmp + offsetSS.dwOffDP2SetVertexShader);
|
|
pCompressedSS->cc.pDP2SetVertexShader = pDP2Cmd;
|
|
|
|
pDP2Cmd->bCommand = D3DDP2OP_SETVERTEXSHADER;
|
|
pDP2SetVtxShader = (D3DHAL_DP2VERTEXSHADER *)(pDP2Cmd + 1);
|
|
|
|
pDP2SetVtxShader->dwHandle = pUncompressedSS->uc.dwCurVertexShader;
|
|
}
|
|
#endif // DX8_DDI
|
|
|
|
// Get rid of the old(uncompressed) one
|
|
HEAP_FREE(pUncompressedSS);
|
|
return pCompressedSS;
|
|
|
|
} // __SB_CompressStateSet
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_DeleteAllStateSets
|
|
//
|
|
// Delete any remaining state sets for cleanup purpouses
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_DeleteAllStateSets(P3_D3DCONTEXT* pContext)
|
|
{
|
|
P3StateSetRec *pSSRec;
|
|
DWORD dwSSIndex;
|
|
|
|
DISPDBG((DBGLVL,"_D3D_SB_DeleteAllStateSets"));
|
|
|
|
if (pContext->pIndexTableSS)
|
|
{
|
|
for(dwSSIndex = 0; dwSSIndex < pContext->dwMaxSSIndex; dwSSIndex++)
|
|
{
|
|
if (pSSRec = pContext->pIndexTableSS[dwSSIndex])
|
|
{
|
|
HEAP_FREE(pSSRec);
|
|
}
|
|
}
|
|
|
|
// free fast index table
|
|
HEAP_FREE(pContext->pIndexTableSS);
|
|
}
|
|
|
|
} // _D3D_SB_DeleteAllStateSets
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_BeginStateSet
|
|
//
|
|
// Create a new state set identified by dwParam and start recording states
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_BeginStateSet(P3_D3DCONTEXT* pContext, DWORD dwParam)
|
|
{
|
|
DWORD dwSSSize;
|
|
P3StateSetRec *pSSRec;
|
|
|
|
DISPDBG((DBGLVL,"_D3D_SB_BeginStateSet dwParam=%08lx",dwParam));
|
|
|
|
// Calculate the maximum size of the state set
|
|
dwSSSize = sizeof(P3StateSetRec);
|
|
#if DX7_SB_TNL
|
|
// TODO, Size depends on number of lights, clip planes
|
|
#endif // DX7_SB_TNL
|
|
|
|
#if DX8_SB_SHADERS
|
|
// TODO, size depends on number of vertext/pixel shaders
|
|
#endif // DX8_SB_SHADERS
|
|
|
|
// Create a new state set
|
|
pSSRec = (P3StateSetRec *)HEAP_ALLOC(FL_ZERO_MEMORY,
|
|
dwSSSize,
|
|
ALLOC_TAG_DX(4));
|
|
if (!pSSRec)
|
|
{
|
|
DISPDBG((ERRLVL,"Run out of memory for additional state sets"));
|
|
return;
|
|
}
|
|
|
|
// Remember handle to current state set
|
|
pSSRec->dwHandle = dwParam;
|
|
pSSRec->dwSSFlags &= (~SB_COMPRESSED);
|
|
|
|
// Remember the size of the uncompressed state set
|
|
pSSRec->uc.dwSize = dwSSSize;
|
|
|
|
#if DX7_SB_TNL
|
|
// TODO, Set up pointers for data used for lights, clip planes
|
|
#endif // DX7_SB_TNL
|
|
|
|
#if DX8_SB_SHADERS
|
|
// TODO, Set up pointers for data used for {V|P} shader constants
|
|
#endif // DX8_SB_SHADERS
|
|
|
|
// Get pointer to current recording state set
|
|
pContext->pCurrSS = pSSRec;
|
|
|
|
// Start recording mode
|
|
pContext->bStateRecMode = TRUE;
|
|
|
|
} // _D3D_SB_BeginStateSet
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_EndStateSet
|
|
//
|
|
// stop recording states - revert to executing them.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_EndStateSet(P3_D3DCONTEXT* pContext)
|
|
{
|
|
DWORD dwHandle;
|
|
P3StateSetRec *pNewSSRec;
|
|
|
|
DISPDBG((DBGLVL,"_D3D_SB_EndStateSet"));
|
|
|
|
if (pContext->pCurrSS)
|
|
{
|
|
dwHandle = pContext->pCurrSS->dwHandle;
|
|
|
|
// compress the current state set
|
|
// Note: after being compressed the uncompressed version is free'd.
|
|
pNewSSRec = __SB_CompressStateSet(pContext, pContext->pCurrSS);
|
|
|
|
__SB_AddStateSetIndexTableEntry(pContext, dwHandle, pNewSSRec);
|
|
}
|
|
|
|
// No state set being currently recorded
|
|
pContext->pCurrSS = NULL;
|
|
|
|
// End recording mode
|
|
pContext->bStateRecMode = FALSE;
|
|
|
|
} // _D3D_SB_EndStateSet
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_DeleteStateSet
|
|
//
|
|
// Delete the recorder state ste identified by dwParam
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_DeleteStateSet(P3_D3DCONTEXT* pContext, DWORD dwParam)
|
|
{
|
|
P3StateSetRec *pSSRec;
|
|
DWORD i;
|
|
|
|
DISPDBG((DBGLVL,"_D3D_SB_DeleteStateSet dwParam=%08lx",dwParam));
|
|
|
|
if (pSSRec = __SB_FindStateSet(pContext, dwParam))
|
|
{
|
|
// Clear index table entry
|
|
pContext->pIndexTableSS[dwParam - 1] = NULL;
|
|
|
|
// Now delete the actual state set structure
|
|
HEAP_FREE(pSSRec);
|
|
}
|
|
|
|
} // _D3D_SB_DeleteStateSet
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_ExecuteStateSet
|
|
//
|
|
// Execute the render states and texture stage states of which a given
|
|
// state set is comprised. Distinguish between the compressed and
|
|
// uncomressed representations of records.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_ExecuteStateSet(P3_D3DCONTEXT* pContext, DWORD dwParam)
|
|
{
|
|
P3StateSetRec *pSSRec;
|
|
DWORD i,j;
|
|
|
|
DISPDBG((DBGLVL,"_D3D_SB_ExecuteStateSet dwParam=%08lx",dwParam));
|
|
|
|
if (pSSRec = __SB_FindStateSet(pContext, dwParam))
|
|
{
|
|
|
|
if (!(pSSRec->dwSSFlags & SB_COMPRESSED))
|
|
{
|
|
// uncompressed state set
|
|
|
|
// Execute any necessary render states
|
|
for (i=0; i< MAX_STATE; i++)
|
|
{
|
|
if (IS_FLAG_SET(pSSRec->uc.bStoredRS , i))
|
|
{
|
|
DWORD dwRSType, dwRSVal;
|
|
|
|
dwRSType = i;
|
|
dwRSVal = pSSRec->uc.RenderStates[dwRSType];
|
|
|
|
// Store the state in the context
|
|
pContext->RenderStates[dwRSType] = dwRSVal;
|
|
|
|
DISPDBG((DBGLVL,"_D3D_SB_ExecuteStateSet RS %x = %x",
|
|
dwRSType, dwRSVal));
|
|
|
|
// Process it
|
|
_D3D_ST_ProcessOneRenderState(pContext, dwRSType, dwRSVal);
|
|
|
|
}
|
|
}
|
|
|
|
// Execute any necessary TSS's
|
|
for (j=0; j<SB_MAX_STAGES; j++)
|
|
{
|
|
for (i=0; i<= D3DTSS_TEXTURETRANSFORMFLAGS; i++)
|
|
{
|
|
if (IS_FLAG_SET(pSSRec->uc.bStoredTSS[j] , i))
|
|
{
|
|
D3DHAL_DP2TEXTURESTAGESTATE dp2TSS;
|
|
|
|
dp2TSS.TSState = (WORD)i;
|
|
dp2TSS.wStage = (WORD)j;
|
|
dp2TSS.dwValue = pSSRec->uc.TssStates[j][i];
|
|
|
|
DISPDBG((DBGLVL,
|
|
"_D3D_SB_ExecuteStateSet TSS %x [%x] = %x",
|
|
dp2TSS.TSState,
|
|
dp2TSS.wStage,
|
|
dp2TSS.dwValue));
|
|
|
|
// If a state set is changed by _D3D_SB_CaptureStateSet(),
|
|
// then texture filter values in it are DX6 semantic, otherwise
|
|
// it is DX8
|
|
if (pSSRec->dwSSFlags & SB_VAL_CAPTURED)
|
|
{
|
|
_D3D_TXT_ParseTextureStageStates(pContext,
|
|
&dp2TSS,
|
|
1,
|
|
FALSE); //It is already DX6
|
|
}
|
|
else
|
|
{
|
|
_D3D_TXT_ParseTextureStageStates(pContext,
|
|
&dp2TSS,
|
|
1,
|
|
TRUE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Excute viewport info, z range
|
|
if (pSSRec->uc.dwFlags & SB_VIEWPORT_CHANGED)
|
|
{
|
|
_D3D_OP_Viewport(pContext, &pSSRec->uc.viewport);
|
|
}
|
|
|
|
if (pSSRec->uc.dwFlags & SB_ZRANGE_CHANGED)
|
|
{
|
|
_D3D_OP_ZRange(pContext, &pSSRec->uc.zRange);
|
|
}
|
|
|
|
#if DX8_DDI
|
|
// Excute vertex indices and stream sources
|
|
if (pSSRec->uc.dwFlags & SB_INDICES_CHANGED)
|
|
{
|
|
_D3D_OP_MStream_SetIndices(pContext,
|
|
pSSRec->uc.vertexIndex.dwVBHandle,
|
|
pSSRec->uc.vertexIndex.dwStride);
|
|
}
|
|
|
|
for (i = 0; i < D3DVS_INPUTREG_MAX_V1_1; i++)
|
|
{
|
|
if (pSSRec->uc.dwFlags & (SB_STREAMSRC_CHANGED << i))
|
|
{
|
|
_D3D_OP_MStream_SetSrc(pContext,
|
|
pSSRec->uc.streamSource[i].dwStream,
|
|
pSSRec->uc.streamSource[i].dwVBHandle,
|
|
pSSRec->uc.streamSource[i].dwStride);
|
|
}
|
|
}
|
|
#endif // DX8_DDI
|
|
|
|
#if DX7_SB_TNL
|
|
// TODO, Execute any necessary state for lights, materials,
|
|
// transforms, clip planes
|
|
#endif // DX7_SB_TNL
|
|
|
|
#if DX8_SB_SHADERS
|
|
// TODO, Execute any necessary set current shader and set shader
|
|
// constants pairs
|
|
#endif // DX8_SB_SHADERS
|
|
|
|
#if DX8_DDI
|
|
// Note : This should be done after setting shader constants, since
|
|
// current shader may have to be set before changing constants
|
|
if (pSSRec->uc.dwFlags & SB_CUR_VS_CHANGED)
|
|
{
|
|
_D3D_OP_VertexShader_Set(pContext,
|
|
pSSRec->uc.dwCurVertexShader);
|
|
}
|
|
#endif // DX8_DDI
|
|
}
|
|
else
|
|
{
|
|
// compressed state set
|
|
|
|
// Execute any necessary RS's
|
|
if (pSSRec->cc.pDP2RenderState)
|
|
{
|
|
|
|
DISPDBG((DBGLVL, "_D3D_SB_ExecuteStateSet RenderState"));
|
|
|
|
_D3D_ST_ProcessRenderStates(pContext,
|
|
pSSRec->cc.pDP2RenderState->wStateCount,
|
|
(LPD3DSTATE)(pSSRec->cc.pDP2RenderState + 1),
|
|
FALSE);
|
|
}
|
|
|
|
// Execute any necessary TSS's
|
|
if (pSSRec->cc.pDP2TextureStageState)
|
|
{
|
|
DISPDBG((DBGLVL,"_D3D_SB_ExecuteStateSet TSS"));
|
|
|
|
// If a state set is changed by _D3D_SB_CaptureStateSet(),
|
|
// then texture filter values in it are DX6 semantic, otherwise
|
|
// it is DX8
|
|
if (pSSRec->dwSSFlags & SB_VAL_CAPTURED)
|
|
{
|
|
_D3D_TXT_ParseTextureStageStates(pContext,
|
|
(D3DHAL_DP2TEXTURESTAGESTATE *)(pSSRec->cc.pDP2TextureStageState + 1),
|
|
pSSRec->cc.pDP2TextureStageState->wStateCount,
|
|
FALSE); // It is already DX6
|
|
}
|
|
else
|
|
{
|
|
_D3D_TXT_ParseTextureStageStates(pContext,
|
|
(D3DHAL_DP2TEXTURESTAGESTATE *)(pSSRec->cc.pDP2TextureStageState + 1),
|
|
pSSRec->cc.pDP2TextureStageState->wStateCount,
|
|
TRUE);
|
|
}
|
|
}
|
|
|
|
// execute viewport info, z range
|
|
if (pSSRec->cc.pDP2Viewport)
|
|
{
|
|
_D3D_OP_Viewport(pContext,
|
|
((D3DHAL_DP2VIEWPORTINFO *)(pSSRec->cc.pDP2Viewport + 1))
|
|
);
|
|
}
|
|
|
|
if (pSSRec->cc.pDP2ZRange)
|
|
{
|
|
_D3D_OP_ZRange(pContext,
|
|
((D3DHAL_DP2ZRANGE *)(pSSRec->cc.pDP2ZRange + 1))
|
|
);
|
|
}
|
|
|
|
#if DX8_DDI
|
|
// Execute vertex index, stream, shader
|
|
if (pSSRec->cc.pDP2SetIndices)
|
|
{
|
|
D3DHAL_DP2SETINDICES* pDP2SetIndices;
|
|
|
|
pDP2SetIndices = (D3DHAL_DP2SETINDICES *)(pSSRec->cc.pDP2SetIndices + 1);
|
|
|
|
_D3D_OP_MStream_SetIndices(pContext,
|
|
pDP2SetIndices->dwVBHandle,
|
|
pDP2SetIndices->dwStride);
|
|
}
|
|
|
|
if (pSSRec->cc.pDP2SetStreamSources)
|
|
{
|
|
D3DHAL_DP2SETSTREAMSOURCE *pDP2SetStmSrc;
|
|
|
|
DISPDBG((DBGLVL,"More than 1 stream (%d)",
|
|
pSSRec->cc.pDP2SetStreamSources->wStateCount));
|
|
|
|
pDP2SetStmSrc = (D3DHAL_DP2SETSTREAMSOURCE *)(pSSRec->cc.pDP2SetStreamSources + 1);
|
|
ASSERTDD(pDP2SetStmSrc->dwStream == 0, "Wrong vertex stream");
|
|
for (i = 0; i < pSSRec->cc.pDP2SetStreamSources->wStateCount; i++, pDP2SetStmSrc++)
|
|
{
|
|
_D3D_OP_MStream_SetSrc(pContext,
|
|
pDP2SetStmSrc->dwStream,
|
|
pDP2SetStmSrc->dwVBHandle,
|
|
pDP2SetStmSrc->dwStride);
|
|
}
|
|
}
|
|
#endif // DX8_DDI
|
|
|
|
#if DX7_SB_TNL
|
|
// TODO, Execute any necessary state for lights, materials,
|
|
// transforms, clip planes
|
|
#endif // DX7_SB_TNL
|
|
|
|
#if DX8_SB_SHADERS
|
|
// TODO, Execute any necessary state for setting {V|P} shader constants
|
|
#endif // DX8_SB_SHADERS
|
|
|
|
#if DX8_DDI
|
|
// Execute current pixel shader (legacy FVF code)
|
|
if (pSSRec->cc.pDP2SetVertexShader)
|
|
{
|
|
_D3D_OP_VertexShader_Set(pContext,
|
|
((D3DHAL_DP2VERTEXSHADER *)(pSSRec->cc.pDP2SetVertexShader + 1))->dwHandle);
|
|
}
|
|
#endif // DX8_DDI
|
|
}
|
|
}
|
|
|
|
} // _D3D_SB_ExecuteStateSet
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_CaptureStateSet
|
|
//
|
|
// Capture the render states and texture stage states of which a given
|
|
// state set is comprised. Distinguish between the compressed and
|
|
// uncomressed representations of records. This functionality allows the
|
|
// app to have a push/pop state feature.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_CaptureStateSet(P3_D3DCONTEXT* pContext, DWORD dwParam)
|
|
{
|
|
P3StateSetRec *pSSRec;
|
|
DWORD i, j;
|
|
|
|
DISPDBG((DBGLVL,"_D3D_SB_CaptureStateSet dwParam=%08lx",dwParam));
|
|
|
|
if (pSSRec = __SB_FindStateSet(pContext, dwParam))
|
|
{
|
|
// Mark it as having DX6 texture filter values instead of DX8,
|
|
// so that _D3D_SB_ExecuteStateSet() uses the FALSE for the
|
|
// bTranslateDX8FilterValueToDX6 of _D3D_TXT_ParseTextureStageStates()
|
|
pSSRec->dwSSFlags |= SB_VAL_CAPTURED;
|
|
|
|
// Actually capture the values
|
|
if (!(pSSRec->dwSSFlags & SB_COMPRESSED))
|
|
{
|
|
// uncompressed state set
|
|
|
|
// Capture any necessary render states
|
|
for (i=0; i< MAX_STATE; i++)
|
|
if (IS_FLAG_SET(pSSRec->uc.bStoredRS , i))
|
|
{
|
|
pSSRec->uc.RenderStates[i] = pContext->RenderStates[i];
|
|
}
|
|
|
|
// Capture any necessary TSS's
|
|
for (j=0; j<SB_MAX_STAGES; j++)
|
|
{
|
|
for (i=0; i<= D3DTSS_TEXTURETRANSFORMFLAGS; i++)
|
|
{
|
|
if (IS_FLAG_SET(pSSRec->uc.bStoredTSS[j] , i))
|
|
{
|
|
pSSRec->uc.TssStates[j][i] =
|
|
pContext->TextureStageState[j].m_dwVal[i];
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// Capture viewport info, z range
|
|
if (pSSRec->uc.dwFlags & SB_VIEWPORT_CHANGED)
|
|
{
|
|
pSSRec->uc.viewport = pContext->ViewportInfo;
|
|
}
|
|
|
|
if (pSSRec->uc.dwFlags & SB_ZRANGE_CHANGED)
|
|
{
|
|
pSSRec->uc.zRange = pContext->ZRange;
|
|
}
|
|
|
|
#if DX8_DDI
|
|
// Capture vertex indices and stream sources
|
|
if (pSSRec->uc.dwFlags & SB_INDICES_CHANGED)
|
|
{
|
|
pSSRec->uc.vertexIndex.dwVBHandle = pContext->dwIndexHandle;
|
|
pSSRec->uc.vertexIndex.dwStride = pContext->dwIndicesStride;
|
|
}
|
|
|
|
// Note : P3 supports only one stream
|
|
for (i = 0; i < D3DVS_INPUTREG_MAX_V1_1; i++)
|
|
{
|
|
ASSERTDD(i == 0, "Wrong vertex stream");
|
|
if (pSSRec->uc.dwFlags & (SB_STREAMSRC_CHANGED << i))
|
|
{
|
|
pSSRec->uc.streamSource[i].dwStream = 0;
|
|
pSSRec->uc.streamSource[i].dwVBHandle = pContext->dwVBHandle;
|
|
pSSRec->uc.streamSource[i].dwStride = pContext->dwVerticesStride;
|
|
}
|
|
}
|
|
#endif // DX8_DDI
|
|
|
|
#if DX7_SB_TNL
|
|
// TODO, Capture any necessary state for lights, materials,
|
|
// transforms, clip planes
|
|
#endif // DX7_SB_TNL
|
|
|
|
#if DX8_SB_SHADERS
|
|
// TODO, Capture any necessary state for {V|P} shader constants
|
|
#endif // DX8_SB_SHADERS
|
|
|
|
#if DX8_DDI
|
|
// Capture the current vertex shader
|
|
if (pSSRec->uc.dwFlags & SB_CUR_VS_CHANGED)
|
|
{
|
|
pSSRec->uc.dwCurVertexShader = pContext->dwVertexType;
|
|
}
|
|
#endif // DX8_DDI
|
|
}
|
|
else
|
|
{
|
|
// compressed state set
|
|
|
|
// Capture any necessary render states
|
|
if (pSSRec->cc.pDP2RenderState)
|
|
{
|
|
|
|
D3DHAL_DP2RENDERSTATE* pDP2RS;
|
|
pDP2RS = (D3DHAL_DP2RENDERSTATE *)(pSSRec->cc.pDP2RenderState + 1);
|
|
for (i = 0; i < pSSRec->cc.pDP2RenderState->wStateCount; i++, pDP2RS++)
|
|
{
|
|
pDP2RS->dwState = pContext->RenderStates[pDP2RS->RenderState];
|
|
}
|
|
}
|
|
|
|
// Capture any necessary TSS's
|
|
if (pSSRec->cc.pDP2TextureStageState)
|
|
{
|
|
D3DHAL_DP2TEXTURESTAGESTATE* pDP2TSS;
|
|
pDP2TSS = (D3DHAL_DP2TEXTURESTAGESTATE *)(pSSRec->cc.pDP2TextureStageState + 1);
|
|
|
|
for (i = 0; i < pSSRec->cc.pDP2TextureStageState->wStateCount; i++, pDP2TSS++)
|
|
{
|
|
pDP2TSS->dwValue = pContext->TextureStageState[pDP2TSS->wStage].m_dwVal[pDP2TSS->TSState];
|
|
}
|
|
}
|
|
|
|
// Capture viewport info, z range
|
|
|
|
if (pSSRec->cc.pDP2Viewport)
|
|
{
|
|
*((D3DHAL_DP2VIEWPORTINFO *)(pSSRec->cc.pDP2Viewport + 1)) = pContext->ViewportInfo;
|
|
}
|
|
|
|
if (pSSRec->cc.pDP2ZRange)
|
|
{
|
|
*((D3DHAL_DP2ZRANGE *)(pSSRec->cc.pDP2ZRange + 1)) = pContext->ZRange;
|
|
}
|
|
|
|
#if DX8_DDI
|
|
// Capture vertex index, stream, shader
|
|
if (pSSRec->cc.pDP2SetIndices)
|
|
{
|
|
D3DHAL_DP2SETINDICES* pDP2SetIndices;
|
|
pDP2SetIndices = (D3DHAL_DP2SETINDICES *)(pSSRec->cc.pDP2SetIndices + 1);
|
|
pDP2SetIndices->dwVBHandle = pContext->dwIndexHandle;
|
|
pDP2SetIndices->dwStride = pContext->dwIndicesStride; // 2 | 4
|
|
}
|
|
|
|
if (pSSRec->cc.pDP2SetStreamSources)
|
|
{
|
|
D3DHAL_DP2SETSTREAMSOURCE* pDP2SetStmSrc;
|
|
pDP2SetStmSrc = (D3DHAL_DP2SETSTREAMSOURCE *)(pSSRec->cc.pDP2SetStreamSources + 1);
|
|
pDP2SetStmSrc->dwStream = 0; // Only stream for permedia 3
|
|
pDP2SetStmSrc->dwVBHandle = pContext->dwVBHandle;
|
|
pDP2SetStmSrc->dwStride = pContext->dwVerticesStride;
|
|
}
|
|
#endif // DX8_DDI
|
|
|
|
#if DX7_SB_TNL
|
|
// TODO, Capture any necessary state for lights, materials,
|
|
// transforms, clip planes
|
|
#endif // DX7_SB_TNL
|
|
|
|
#if DX8_SB_SHADERS
|
|
// TODO, Capture any necessary state for {V|P} shader constants
|
|
#endif // DX8_SB_SHADERS
|
|
|
|
#if DX8_DDI
|
|
// Capture current vertex shader
|
|
if (pSSRec->cc.pDP2SetVertexShader)
|
|
{
|
|
D3DHAL_DP2VERTEXSHADER* pSetVtxShader;
|
|
pSetVtxShader = (D3DHAL_DP2VERTEXSHADER *)(pSSRec->cc.pDP2SetVertexShader + 1);
|
|
pSetVtxShader->dwHandle = pContext->dwVertexType;
|
|
}
|
|
#endif // DX8_DDI
|
|
}
|
|
}
|
|
|
|
} // _D3D_SB_CaptureStateSet
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Recording happens between BeginStateSet and EndStateSet calls so we
|
|
// never need to deal with recording into a compressed state set (since
|
|
// compression happens in EndStateSet)
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_RecordStateSetRS
|
|
//
|
|
// Record this render state into the current state set being recorded
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_RecordStateSetRS(P3_D3DCONTEXT* pContext,
|
|
DWORD dwRSType,
|
|
DWORD dwRSVal)
|
|
{
|
|
if (pContext->pCurrSS != NULL)
|
|
{
|
|
DISPDBG((DBGLVL,"Recording SB # %x : RS %x = %x",
|
|
pContext->pCurrSS->dwHandle,dwRSType,dwRSVal));
|
|
|
|
// Recording the state in an uncompressed stateblock
|
|
pContext->pCurrSS->uc.RenderStates[dwRSType] = dwRSVal;
|
|
FLAG_SET(pContext->pCurrSS->uc.bStoredRS, dwRSType);
|
|
}
|
|
} // _D3D_SB_RecordStateSetRS
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_RecordStateSetTSS
|
|
//
|
|
// Record this texture stage state into the current state set being recorded
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_RecordStateSetTSS(P3_D3DCONTEXT* pContext,
|
|
DWORD dwTSStage,
|
|
DWORD dwTSState,
|
|
DWORD dwTSVal)
|
|
{
|
|
if (pContext->pCurrSS != NULL)
|
|
{
|
|
DISPDBG((DBGLVL,"Recording SB # %x : TSS %x [%x] = %x",
|
|
pContext->pCurrSS->dwHandle,dwTSState, dwTSStage, dwTSVal));
|
|
|
|
// Recording the state in an uncompressed stateblock
|
|
pContext->pCurrSS->uc.TssStates[dwTSStage][dwTSState] = dwTSVal;
|
|
FLAG_SET(pContext->pCurrSS->uc.bStoredTSS[dwTSStage], dwTSState);
|
|
}
|
|
} // _D3D_SB_RecordStateSetTSS
|
|
|
|
#if DX8_MULTSTREAMS
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_Record_VertexShader_Set
|
|
//
|
|
// Record this vertex shader set code into the current state set being recorded
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_Record_VertexShader_Set(P3_D3DCONTEXT* pContext,
|
|
DWORD dwVtxShaderHandle)
|
|
{
|
|
if (pContext->pCurrSS != NULL)
|
|
{
|
|
ASSERTDD (!(pContext->pCurrSS->dwSSFlags & SB_COMPRESSED),
|
|
"ERROR : StateSet compressed");
|
|
|
|
pContext->pCurrSS->uc.dwCurVertexShader = dwVtxShaderHandle;
|
|
pContext->pCurrSS->uc.dwFlags |= SB_CUR_VS_CHANGED;
|
|
}
|
|
} // _D3D_SB_Record_VertexShader_Set
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_Record_MStream_SetSrc
|
|
//
|
|
// Record this stream src set code into the current state set being recorded
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_Record_MStream_SetSrc(P3_D3DCONTEXT* pContext,
|
|
DWORD dwStream,
|
|
DWORD dwVBHandle,
|
|
DWORD dwStride)
|
|
{
|
|
if (pContext->pCurrSS != NULL)
|
|
{
|
|
ASSERTDD (!(pContext->pCurrSS->dwSSFlags & SB_COMPRESSED),
|
|
"ERROR : StateSet compressed");
|
|
|
|
pContext->pCurrSS->uc.streamSource[dwStream].dwStream = dwStream;
|
|
pContext->pCurrSS->uc.streamSource[dwStream].dwVBHandle = dwVBHandle;
|
|
pContext->pCurrSS->uc.streamSource[dwStream].dwStride = dwStride;
|
|
|
|
pContext->pCurrSS->uc.dwFlags |= (SB_STREAMSRC_CHANGED << dwStream);
|
|
}
|
|
} // _D3D_SB_Record_MStream_SetSrc
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_Record_MStream_SetIndices
|
|
//
|
|
// Record this stream indices code into the current state set being recorded
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_Record_MStream_SetIndices(P3_D3DCONTEXT* pContext,
|
|
DWORD dwVBHandle,
|
|
DWORD dwStride)
|
|
{
|
|
if (pContext->pCurrSS != NULL)
|
|
{
|
|
ASSERTDD (!(pContext->pCurrSS->dwSSFlags & SB_COMPRESSED),
|
|
"ERROR : StateSet compressed");
|
|
|
|
pContext->pCurrSS->uc.vertexIndex.dwVBHandle = dwVBHandle;
|
|
pContext->pCurrSS->uc.vertexIndex.dwStride = dwStride;
|
|
pContext->pCurrSS->uc.dwFlags |= SB_INDICES_CHANGED;
|
|
}
|
|
} // _D3D_SB_Record_MStream_SetIndices
|
|
#endif // DX8_MULTSTREAMS
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_Record_Viewport
|
|
//
|
|
// Record this viewport info into the current state set being recorded
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _D3D_SB_Record_Viewport(P3_D3DCONTEXT* pContext,
|
|
D3DHAL_DP2VIEWPORTINFO* lpvp)
|
|
{
|
|
if (pContext->pCurrSS != NULL)
|
|
{
|
|
ASSERTDD (!(pContext->pCurrSS->dwSSFlags & SB_COMPRESSED),
|
|
"ERROR : StateSet compressed");
|
|
|
|
pContext->pCurrSS->uc.viewport = *lpvp;
|
|
pContext->pCurrSS->uc.dwFlags |= SB_VIEWPORT_CHANGED;
|
|
}
|
|
} // _D3D_SB_Record_Viewport
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// void _D3D_SB_Record_ZRange
|
|
//
|
|
// Record this z range info into the current state set being recorded
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID _D3D_SB_Record_ZRange(P3_D3DCONTEXT* pContext,
|
|
D3DHAL_DP2ZRANGE* lpzr)
|
|
{
|
|
if (pContext->pCurrSS != NULL)
|
|
{
|
|
ASSERTDD (!(pContext->pCurrSS->dwSSFlags & SB_COMPRESSED),
|
|
"ERROR : StateSet compressed");
|
|
|
|
pContext->pCurrSS->uc.zRange = *lpzr;
|
|
pContext->pCurrSS->uc.dwFlags |= SB_ZRANGE_CHANGED;
|
|
}
|
|
}
|
|
|
|
#endif //DX7_D3DSTATEBLOCKS
|