Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1195 lines
47 KiB

/*==========================================================================;
*
* Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
*
* File: stateset.cpp
* Content: State sets handling
*
***************************************************************************/
#include "pch.cpp"
#pragma hdrstop
//=====================================================================
// CStateSets interface
//
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::CStateSets"
CStateSets::CStateSets(): m_GrowSize(10)
{
m_dwMaxSets = 0;
m_dwCurrentHandle = __INVALIDHANDLE;
m_pStateSets = NULL;
// Init handle factory
m_SetHandles.Init(m_GrowSize, m_GrowSize);
m_SetHandles.CreateNewHandle(); // Reserve handle 0
m_DeviceHandles.Init(m_GrowSize, m_GrowSize);
m_DeviceHandles.CreateNewHandle(); // Reserve handle 0
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::~CStateSets"
CStateSets::~CStateSets()
{
delete [] m_pStateSets;
m_SetHandles.ReleaseHandle(0);
m_DeviceHandles.ReleaseHandle(0);
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::Init"
HRESULT CStateSets::Init(DWORD dwFlags)
{
m_dwFlags = dwFlags;
return D3D_OK;
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::StartNewSet"
HRESULT CStateSets::StartNewSet()
{
m_dwCurrentHandle = m_SetHandles.CreateNewHandle();
if (m_dwCurrentHandle == __INVALIDHANDLE)
return DDERR_OUTOFMEMORY;
if (m_dwCurrentHandle >= m_dwMaxSets)
{
// Time to grow the array
CStateSet *pNew = new CStateSet[m_dwMaxSets + m_GrowSize];
if (pNew == NULL)
{
m_SetHandles.ReleaseHandle(m_dwCurrentHandle);
return DDERR_OUTOFMEMORY;
}
for (DWORD i=0; i < m_dwMaxSets; i++)
pNew[i] = m_pStateSets[i];
delete [] m_pStateSets;
m_pStateSets = pNew;
m_dwMaxSets += m_GrowSize;
}
m_BufferSet.m_FEOnlyBuffer.Reset();
m_BufferSet.m_DriverBuffer.Reset();
m_pCurrentStateSet = &m_BufferSet;
return D3D_OK;
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::EndSet"
void CStateSets::EndSet()
{
m_pStateSets[m_dwCurrentHandle] = *m_pCurrentStateSet;
m_pCurrentStateSet = &m_pStateSets[m_dwCurrentHandle];
m_pCurrentStateSet->m_dwStateSetFlags |= __STATESET_INITIALIZED;
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::DeleteStateSet"
void CStateSets::DeleteStateSet(LPDIRECT3DDEVICEI pDevI, DWORD dwHandle)
{
if (dwHandle >= m_dwMaxSets)
{
D3D_ERR("State block handle is greater than available number of blocks");
throw D3DERR_INVALIDSTATEBLOCK;
}
CStateSet *pStateSet = &m_pStateSets[dwHandle];
if (!(pStateSet->m_dwStateSetFlags & __STATESET_INITIALIZED))
{
D3D_ERR("State block is not initialized");
throw D3DERR_INVALIDSTATEBLOCK;
}
// Pass delete instruction to the driver only if there was some data recorded
if (pStateSet->m_DriverBuffer.m_dwCurrentSize > 0)
InsertStateSetOp(pDevI, D3DHAL_STATESETDELETE, pStateSet->m_dwDeviceHandle, (D3DSTATEBLOCKTYPE)0);
Cleanup(dwHandle);
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::Cleanup"
void CStateSets::Cleanup(DWORD dwHandle)
{
CStateSet &pStateSet = m_pStateSets[dwHandle];
m_SetHandles.ReleaseHandle(dwHandle);
if (pStateSet.m_dwDeviceHandle != __INVALIDHANDLE)
m_DeviceHandles.ReleaseHandle(pStateSet.m_dwDeviceHandle);
pStateSet.Release();
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::Capture"
void CStateSets::Capture(LPDIRECT3DDEVICEI pDevI, DWORD dwHandle)
{
if (dwHandle >= m_dwMaxSets)
{
D3D_ERR("Invalid state block handle");
throw D3DERR_INVALIDSTATEBLOCK;
}
CStateSet *pStateSet = &m_pStateSets[dwHandle];
if (!(pStateSet->m_dwStateSetFlags & __STATESET_INITIALIZED))
{
D3D_ERR("State block not initialized");
throw D3DERR_INVALIDSTATEBLOCK;
}
pStateSet->Capture(pDevI, TRUE);
if (pStateSet->m_DriverBuffer.m_dwCurrentSize > 0)
{
pStateSet->Capture(pDevI, FALSE);
InsertStateSetOp(pDevI, D3DHAL_STATESETCAPTURE, pStateSet->m_dwDeviceHandle, (D3DSTATEBLOCKTYPE)0);
}
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::CreatePredefined"
void CStateSets::CreatePredefined(LPDIRECT3DDEVICEI pDevI, D3DSTATEBLOCKTYPE sbt)
{
static D3DRENDERSTATETYPE ALLrstates[] =
{
D3DRENDERSTATE_TEXTUREPERSPECTIVE,
D3DRENDERSTATE_ANTIALIAS,
D3DRENDERSTATE_SPECULARENABLE,
D3DRENDERSTATE_ZENABLE,
D3DRENDERSTATE_FILLMODE,
D3DRENDERSTATE_SHADEMODE,
D3DRENDERSTATE_LINEPATTERN,
D3DRENDERSTATE_ZWRITEENABLE,
D3DRENDERSTATE_ALPHATESTENABLE,
D3DRENDERSTATE_LASTPIXEL,
D3DRENDERSTATE_SRCBLEND,
D3DRENDERSTATE_DESTBLEND,
D3DRENDERSTATE_CULLMODE,
D3DRENDERSTATE_ZFUNC,
D3DRENDERSTATE_ALPHAREF,
D3DRENDERSTATE_ALPHAFUNC,
D3DRENDERSTATE_DITHERENABLE,
D3DRENDERSTATE_FOGENABLE,
D3DRENDERSTATE_STIPPLEDALPHA,
D3DRENDERSTATE_FOGCOLOR,
D3DRENDERSTATE_FOGTABLEMODE,
D3DRENDERSTATE_FOGSTART,
D3DRENDERSTATE_FOGEND,
D3DRENDERSTATE_FOGDENSITY,
D3DRENDERSTATE_EDGEANTIALIAS,
D3DRENDERSTATE_COLORKEYENABLE,
D3DRENDERSTATE_ALPHABLENDENABLE,
D3DRENDERSTATE_ZBIAS,
D3DRENDERSTATE_RANGEFOGENABLE,
D3DRENDERSTATE_STENCILENABLE,
D3DRENDERSTATE_STENCILFAIL,
D3DRENDERSTATE_STENCILZFAIL,
D3DRENDERSTATE_STENCILPASS,
D3DRENDERSTATE_STENCILFUNC,
D3DRENDERSTATE_STENCILREF,
D3DRENDERSTATE_STENCILMASK,
D3DRENDERSTATE_STENCILWRITEMASK,
D3DRENDERSTATE_TEXTUREFACTOR,
D3DRENDERSTATE_WRAP0,
D3DRENDERSTATE_WRAP1,
D3DRENDERSTATE_WRAP2,
D3DRENDERSTATE_WRAP3,
D3DRENDERSTATE_WRAP4,
D3DRENDERSTATE_WRAP5,
D3DRENDERSTATE_WRAP6,
D3DRENDERSTATE_WRAP7,
D3DRENDERSTATE_AMBIENT,
D3DRENDERSTATE_COLORVERTEX,
D3DRENDERSTATE_FOGVERTEXMODE,
D3DRENDERSTATE_CLIPPING,
D3DRENDERSTATE_LIGHTING,
D3DRENDERSTATE_EXTENTS,
D3DRENDERSTATE_NORMALIZENORMALS,
D3DRENDERSTATE_LOCALVIEWER,
D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,
D3DRENDERSTATE_AMBIENTMATERIALSOURCE,
D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,
D3DRENDERSTATE_SPECULARMATERIALSOURCE,
D3DRENDERSTATE_VERTEXBLEND,
D3DRENDERSTATE_CLIPPLANEENABLE,
D3DRENDERSTATE_COLORKEYBLENDENABLE
};
static D3DTEXTURESTAGESTATETYPE ALLtsstates[] =
{
D3DTSS_COLOROP,
D3DTSS_COLORARG1,
D3DTSS_COLORARG2,
D3DTSS_ALPHAOP,
D3DTSS_ALPHAARG1,
D3DTSS_ALPHAARG2,
D3DTSS_BUMPENVMAT00,
D3DTSS_BUMPENVMAT01,
D3DTSS_BUMPENVMAT10,
D3DTSS_BUMPENVMAT11,
D3DTSS_TEXCOORDINDEX,
D3DTSS_ADDRESS,
D3DTSS_ADDRESSU,
D3DTSS_ADDRESSV,
D3DTSS_BORDERCOLOR,
D3DTSS_MAGFILTER,
D3DTSS_MINFILTER,
D3DTSS_MIPFILTER,
D3DTSS_MIPMAPLODBIAS,
D3DTSS_MAXMIPLEVEL,
D3DTSS_MAXANISOTROPY,
D3DTSS_BUMPENVLSCALE,
D3DTSS_BUMPENVLOFFSET,
D3DTSS_TEXTURETRANSFORMFLAGS
};
static D3DRENDERSTATETYPE PIXELrstates[] =
{
D3DRENDERSTATE_TEXTUREPERSPECTIVE,
D3DRENDERSTATE_ANTIALIAS,
D3DRENDERSTATE_ZENABLE,
D3DRENDERSTATE_FILLMODE,
D3DRENDERSTATE_SHADEMODE,
D3DRENDERSTATE_LINEPATTERN,
D3DRENDERSTATE_ZWRITEENABLE,
D3DRENDERSTATE_ALPHATESTENABLE,
D3DRENDERSTATE_LASTPIXEL,
D3DRENDERSTATE_SRCBLEND,
D3DRENDERSTATE_DESTBLEND,
D3DRENDERSTATE_ZFUNC,
D3DRENDERSTATE_ALPHAREF,
D3DRENDERSTATE_ALPHAFUNC,
D3DRENDERSTATE_DITHERENABLE,
D3DRENDERSTATE_STIPPLEDALPHA,
D3DRENDERSTATE_FOGSTART,
D3DRENDERSTATE_FOGEND,
D3DRENDERSTATE_FOGDENSITY,
D3DRENDERSTATE_EDGEANTIALIAS,
D3DRENDERSTATE_COLORKEYENABLE,
D3DRENDERSTATE_ALPHABLENDENABLE,
D3DRENDERSTATE_ZBIAS,
D3DRENDERSTATE_STENCILENABLE,
D3DRENDERSTATE_STENCILFAIL,
D3DRENDERSTATE_STENCILZFAIL,
D3DRENDERSTATE_STENCILPASS,
D3DRENDERSTATE_STENCILFUNC,
D3DRENDERSTATE_STENCILREF,
D3DRENDERSTATE_STENCILMASK,
D3DRENDERSTATE_STENCILWRITEMASK,
D3DRENDERSTATE_TEXTUREFACTOR,
D3DRENDERSTATE_WRAP0,
D3DRENDERSTATE_WRAP1,
D3DRENDERSTATE_WRAP2,
D3DRENDERSTATE_WRAP3,
D3DRENDERSTATE_WRAP4,
D3DRENDERSTATE_WRAP5,
D3DRENDERSTATE_WRAP6,
D3DRENDERSTATE_WRAP7,
D3DRENDERSTATE_COLORKEYBLENDENABLE
};
static D3DTEXTURESTAGESTATETYPE PIXELtsstates[] =
{
D3DTSS_COLOROP,
D3DTSS_COLORARG1,
D3DTSS_COLORARG2,
D3DTSS_ALPHAOP,
D3DTSS_ALPHAARG1,
D3DTSS_ALPHAARG2,
D3DTSS_BUMPENVMAT00,
D3DTSS_BUMPENVMAT01,
D3DTSS_BUMPENVMAT10,
D3DTSS_BUMPENVMAT11,
D3DTSS_TEXCOORDINDEX,
D3DTSS_ADDRESS,
D3DTSS_ADDRESSU,
D3DTSS_ADDRESSV,
D3DTSS_BORDERCOLOR,
D3DTSS_MAGFILTER,
D3DTSS_MINFILTER,
D3DTSS_MIPFILTER,
D3DTSS_MIPMAPLODBIAS,
D3DTSS_MAXMIPLEVEL,
D3DTSS_MAXANISOTROPY,
D3DTSS_BUMPENVLSCALE,
D3DTSS_BUMPENVLOFFSET,
D3DTSS_TEXTURETRANSFORMFLAGS
};
static D3DRENDERSTATETYPE VERTEXrstates[] =
{
D3DRENDERSTATE_SHADEMODE,
D3DRENDERSTATE_SPECULARENABLE,
D3DRENDERSTATE_CULLMODE,
D3DRENDERSTATE_FOGENABLE,
D3DRENDERSTATE_FOGCOLOR,
D3DRENDERSTATE_FOGTABLEMODE,
D3DRENDERSTATE_FOGSTART,
D3DRENDERSTATE_FOGEND,
D3DRENDERSTATE_FOGDENSITY,
D3DRENDERSTATE_RANGEFOGENABLE,
D3DRENDERSTATE_AMBIENT,
D3DRENDERSTATE_COLORVERTEX,
D3DRENDERSTATE_FOGVERTEXMODE,
D3DRENDERSTATE_CLIPPING,
D3DRENDERSTATE_LIGHTING,
D3DRENDERSTATE_EXTENTS,
D3DRENDERSTATE_NORMALIZENORMALS,
D3DRENDERSTATE_LOCALVIEWER,
D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,
D3DRENDERSTATE_AMBIENTMATERIALSOURCE,
D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,
D3DRENDERSTATE_SPECULARMATERIALSOURCE,
D3DRENDERSTATE_VERTEXBLEND,
D3DRENDERSTATE_CLIPPLANEENABLE
};
static D3DTEXTURESTAGESTATETYPE VERTEXtsstates[] =
{
D3DTSS_TEXCOORDINDEX,
D3DTSS_TEXTURETRANSFORMFLAGS
};
DWORD i;
switch(sbt)
{
case (D3DSTATEBLOCKTYPE)0:
break;
case D3DSBT_ALL:
for(i = 0; i < sizeof(ALLrstates) / sizeof(D3DRENDERSTATETYPE); ++i)
InsertRenderState(ALLrstates[i], pDevI->rstates[ALLrstates[i]], pDevI->CanHandleRenderState(ALLrstates[i]));
for (i = 0; i < pDevI->dwMaxTextureBlendStages; i++)
for(DWORD j = 0; j < sizeof(ALLtsstates) / sizeof(D3DTEXTURESTAGESTATETYPE); ++j)
InsertTextureStageState(i, ALLtsstates[j], pDevI->tsstates[i][ALLtsstates[j]]);
// Capture textures
for (i = 0; i < pDevI->dwMaxTextureBlendStages; i++)
{
LPDIRECTDRAWSURFACE7 pTexture;
if (pDevI->lpD3DMappedTexI[i])
{
if(pDevI->lpD3DMappedTexI[i]->D3DManaged())
pTexture = pDevI->lpD3DMappedTexI[i]->lpDDSSys;
else
pTexture = pDevI->lpD3DMappedTexI[i]->lpDDS;
}
else
{
pTexture = NULL;
}
InsertTexture(i, pTexture);
}
// Capture current viewport
InsertViewport(&pDevI->m_Viewport);
// Capture current transforms
InsertTransform(D3DTRANSFORMSTATE_WORLD, (LPD3DMATRIX)&pDevI->transform.world[0]);
InsertTransform(D3DTRANSFORMSTATE_VIEW, (LPD3DMATRIX)&pDevI->transform.view);
InsertTransform(D3DTRANSFORMSTATE_PROJECTION, (LPD3DMATRIX)&pDevI->transform.proj);
InsertTransform(D3DTRANSFORMSTATE_WORLD1, (LPD3DMATRIX)&pDevI->transform.world[1]);
InsertTransform(D3DTRANSFORMSTATE_WORLD2, (LPD3DMATRIX)&pDevI->transform.world[2]);
InsertTransform(D3DTRANSFORMSTATE_WORLD3, (LPD3DMATRIX)&pDevI->transform.world[3]);
for (i = 0; i < pDevI->dwMaxTextureBlendStages; i++)
{
InsertTransform((D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0 + i), (LPD3DMATRIX)&pDevI->mTexture[i]);
}
// Capture current clip-planes
for (i = 0; i < pDevI->transform.dwMaxUserClipPlanes; i++)
{
InsertClipPlane(i, (LPD3DVALUE)&pDevI->transform.userClipPlane[i]);
}
// Capture current material
InsertMaterial(&pDevI->lighting.material);
// Capture current lights
for (i = 0; i < pDevI->m_dwNumLights; i++)
{
if(pDevI->m_pLights[i].Valid())
{
InsertLight(i, &pDevI->m_pLights[i].m_Light);
if(pDevI->m_pLights[i].Enabled())
{
InsertLightEnable(i, TRUE);
}
else
{
InsertLightEnable(i, FALSE);
}
}
}
break;
case D3DSBT_PIXELSTATE:
for(i = 0; i < sizeof(PIXELrstates) / sizeof(D3DRENDERSTATETYPE); ++i)
InsertRenderState(PIXELrstates[i], pDevI->rstates[PIXELrstates[i]], pDevI->CanHandleRenderState(PIXELrstates[i]));
for (i = 0; i < pDevI->dwMaxTextureBlendStages; i++)
for(DWORD j = 0; j < sizeof(PIXELtsstates) / sizeof(D3DTEXTURESTAGESTATETYPE); ++j)
InsertTextureStageState(i, PIXELtsstates[j], pDevI->tsstates[i][PIXELtsstates[j]]);
break;
case D3DSBT_VERTEXSTATE:
for(i = 0; i < sizeof(VERTEXrstates) / sizeof(D3DRENDERSTATETYPE); ++i)
InsertRenderState(VERTEXrstates[i], pDevI->rstates[VERTEXrstates[i]], pDevI->CanHandleRenderState(VERTEXrstates[i]));
for (i = 0; i < pDevI->dwMaxTextureBlendStages; i++)
for(DWORD j = 0; j < sizeof(VERTEXtsstates) / sizeof(D3DTEXTURESTAGESTATETYPE); ++j)
InsertTextureStageState(i, VERTEXtsstates[j], pDevI->tsstates[i][VERTEXtsstates[j]]);
// Capture current light enables
for (i = 0; i < pDevI->m_dwNumLights; i++)
{
if(pDevI->m_pLights[i].Valid())
{
if(pDevI->m_pLights[i].Enabled())
{
InsertLightEnable(i, TRUE);
}
else
{
InsertLightEnable(i, FALSE);
}
}
}
break;
default:
throw DDERR_INVALIDPARAMS;
}
}
//---------------------------------------------------------------------
// Allocates device handle if necessary
// And returns information of the device buffer
//
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::GetDeviceBufferInfo"
void CStateSets::GetDeviceBufferInfo(DWORD* dwStateSetHandle,
LPVOID *pBuffer,
DWORD* dwBufferSize)
{
if (m_pCurrentStateSet->m_DriverBuffer.m_dwCurrentSize != 0)
{
// Allocate a handle for the device
m_pCurrentStateSet->m_dwDeviceHandle = m_DeviceHandles.CreateNewHandle();
if (m_pCurrentStateSet->m_dwDeviceHandle == __INVALIDHANDLE)
{
D3D_ERR("Cannot allocate device handle for a state block");
throw DDERR_OUTOFMEMORY;
}
}
*dwStateSetHandle = m_pCurrentStateSet->m_dwDeviceHandle;
*pBuffer = (LPVOID)m_pCurrentStateSet->m_DriverBuffer.m_pBuffer;
*dwBufferSize = m_pCurrentStateSet->m_DriverBuffer.m_dwCurrentSize;
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::InsertRenderState"
void CStateSets::InsertRenderState(D3DRENDERSTATETYPE state, DWORD dwValue,
BOOL bDriverCanHandle)
{
struct
{
D3DRENDERSTATETYPE state;
DWORD dwValue;
} data = {state, dwValue};
m_pCurrentStateSet->InsertCommand(D3DDP2OP_RENDERSTATE,
&data, sizeof(data),
m_dwFlags & D3DFE_STATESETS && bDriverCanHandle);
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::InsertLight"
void CStateSets::InsertLight(DWORD dwLightIndex, LPD3DLIGHT7 pData)
{
struct
{
D3DHAL_DP2SETLIGHT header;
D3DLIGHT7 light;
} data;
data.header.dwIndex = dwLightIndex;
data.header.dwDataType = D3DHAL_SETLIGHT_DATA;
data.light= *pData;
m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETLIGHT, &data, sizeof(data),
m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::InsertLightEnable"
void CStateSets::InsertLightEnable(DWORD dwLightIndex, BOOL bEnable)
{
D3DHAL_DP2SETLIGHT data;
data.dwIndex = dwLightIndex;
if (bEnable)
data.dwDataType = D3DHAL_SETLIGHT_ENABLE;
else
data.dwDataType = D3DHAL_SETLIGHT_DISABLE;
m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETLIGHT, &data, sizeof(data),
m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::InsertViewport"
void CStateSets::InsertViewport(LPD3DVIEWPORT7 lpVwpData)
{
D3DHAL_DP2VIEWPORTINFO data2;
data2.dwX = lpVwpData->dwX;
data2.dwY = lpVwpData->dwY;
data2.dwWidth = lpVwpData->dwWidth;
data2.dwHeight = lpVwpData->dwHeight;
m_pCurrentStateSet->InsertCommand(D3DDP2OP_VIEWPORTINFO, &data2, sizeof(data2),
m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
D3DHAL_DP2ZRANGE data1;
data1.dvMinZ = lpVwpData->dvMinZ;
data1.dvMaxZ = lpVwpData->dvMaxZ;
m_pCurrentStateSet->InsertCommand(D3DDP2OP_ZRANGE, &data1, sizeof(data1),
m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
m_pCurrentStateSet->ResetCurrentCommand();
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::InsertMaterial"
void CStateSets::InsertMaterial(LPD3DMATERIAL7 pData)
{
m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETMATERIAL,
pData, sizeof(D3DMATERIAL7),
m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
m_pCurrentStateSet->ResetCurrentCommand();
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::InsertClipPlane"
void CStateSets::InsertClipPlane(DWORD dwPlaneIndex, D3DVALUE* pPlaneEquation)
{
D3DHAL_DP2SETCLIPPLANE data;
data.dwIndex = dwPlaneIndex;
data.plane[0] = pPlaneEquation[0];
data.plane[1] = pPlaneEquation[1];
data.plane[2] = pPlaneEquation[2];
data.plane[3] = pPlaneEquation[3];
m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETCLIPPLANE,
&data, sizeof(data),
m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::InsertTransform"
void CStateSets::InsertTransform(D3DTRANSFORMSTATETYPE state, LPD3DMATRIX lpMat)
{
D3DHAL_DP2SETTRANSFORM data;
data.xfrmType = state;
data.matrix = *lpMat;
m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETTRANSFORM,
&data, sizeof(data),
m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::InsertTextureStageState"
void CStateSets::InsertTextureStageState(DWORD dwStage,
D3DTEXTURESTAGESTATETYPE type,
DWORD dwValue)
{
D3DHAL_DP2TEXTURESTAGESTATE data = {(WORD)dwStage, type, dwValue};
m_pCurrentStateSet->InsertCommand(D3DDP2OP_TEXTURESTAGESTATE,
&data, sizeof(data),
m_dwFlags & D3DFE_STATESETS);
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::InsertTexture"
void CStateSets::InsertTexture(DWORD dwStage, LPDIRECTDRAWSURFACE7 pTex)
{
D3DHAL_DP2FRONTENDDATA data = {(WORD)dwStage, (LPVOID)pTex};
// Only the front-end will parse this instruction
m_pCurrentStateSet->InsertCommand((D3DHAL_DP2OPERATION)D3DDP2OP_FRONTENDDATA, &data, sizeof(data), FALSE);
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSets::Execute"
void CStateSets::Execute(LPDIRECT3DDEVICEI pDevI, DWORD dwHandle)
{
#if DBG
if (dwHandle >= m_dwMaxSets)
{
D3D_ERR("Invalid state block handle");
throw D3DERR_INVALIDSTATEBLOCK;
}
#endif
CStateSet *pStateSet = &m_pStateSets[dwHandle];
#if DBG
if (!(pStateSet->m_dwStateSetFlags & __STATESET_INITIALIZED))
{
D3D_ERR("State block not initialized");
throw D3DERR_INVALIDSTATEBLOCK;
}
#endif
// Parse recorded data first
pStateSet->Execute(pDevI, TRUE);
// If the hardware buffer is not empty, we pass recorded data to it
if (pStateSet->m_DriverBuffer.m_dwCurrentSize > 0)
{
pStateSet->Execute(pDevI, FALSE);
InsertStateSetOp(pDevI, D3DHAL_STATESETEXECUTE, pStateSet->m_dwDeviceHandle, (D3DSTATEBLOCKTYPE)0);
}
}
//=====================================================================
// CStateSet interface
//
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSet::Release"
HRESULT CStateSet::Release()
{
if (!(m_dwStateSetFlags & __STATESET_INITIALIZED))
return D3DERR_INVALIDSTATEBLOCK;
m_dwStateSetFlags &= ~__STATESET_INITIALIZED;
m_FEOnlyBuffer.Reset();
m_DriverBuffer.Reset();
return D3D_OK;
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSet::InsertCommand"
void CStateSet::InsertCommand(D3DHAL_DP2OPERATION op, LPVOID pData,
DWORD dwDataSize,
BOOL bDriverCanHandle)
{
if (op == D3DDP2OP_TEXTURESTAGESTATE ||
(op == D3DDP2OP_RENDERSTATE &&
((LPD3DHAL_DP2RENDERSTATE)pData)->RenderState >= D3DRENDERSTATE_WRAP0 &&
((LPD3DHAL_DP2RENDERSTATE)pData)->RenderState <= D3DRENDERSTATE_WRAP7))
{
m_dwStateSetFlags |= __STATESET_NEEDCHECKREMAPPING;
}
if (bDriverCanHandle)
m_DriverBuffer.InsertCommand(op, pData, dwDataSize);
else
m_FEOnlyBuffer.InsertCommand(op, pData, dwDataSize);
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSet::Execute"
void CStateSet::Execute(LPDIRECT3DDEVICEI pDevI, BOOL bFrontEndBuffer)
{
DWORD *p;
DWORD dwSize;
DWORD *pEnd;
try
{
// Texture stages could be re-mapped during texture transform processing.
// Before we set new values we have to restore original ones
if (pDevI->dwDeviceFlags & D3DDEV_REMAPTEXTUREINDICES &&
m_dwStateSetFlags & __STATESET_NEEDCHECKREMAPPING)
{
RestoreTextureStages(pDevI);
pDevI->ForceFVFRecompute();
}
if (bFrontEndBuffer)
{
p = (DWORD*)m_FEOnlyBuffer.m_pBuffer;
dwSize = m_FEOnlyBuffer.m_dwCurrentSize;
}
else
{
p = (DWORD*)m_DriverBuffer.m_pBuffer;
dwSize = m_DriverBuffer.m_dwCurrentSize;
pDevI->dwFEFlags |= D3DFE_EXECUTESTATEMODE;
}
pEnd = (DWORD*)((BYTE*)p + dwSize);
while (p < pEnd)
{
LPD3DHAL_DP2COMMAND pCommand = (LPD3DHAL_DP2COMMAND)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
switch ((D3DHAL_DP2OPERATION)pCommand->bCommand)
{
case D3DDP2OP_RENDERSTATE:
{
if(pDevI->dwFEFlags & D3DFE_EXECUTESTATEMODE)
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
D3DRENDERSTATETYPE dwState = (D3DRENDERSTATETYPE)*p++;
DWORD dwValue = *p++;
if (pDevI->rstates[dwState] != dwValue)
{
if (!(pDevI->rsVec[dwState >> D3D_RSVEC_SHIFT] & (1ul << (dwState & D3D_RSVEC_MASK))))
{ // Fast path. We do not need any processing done in UpdateInternalState other than updating rstates array
pDevI->rstates[dwState] = dwValue;
}
else
{
pDevI->UpdateInternalState(dwState, dwValue);
}
}
else
{
D3D_WARN(4,"Ignoring redundant SetRenderState");
}
}
}
else
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
D3DRENDERSTATETYPE dwState = (D3DRENDERSTATETYPE)*p++;
DWORD dwValue = *p++;
if (pDevI->rstates[dwState] != dwValue)
{
if (!(pDevI->rsVec[dwState >> D3D_RSVEC_SHIFT] & (1ul << (dwState & D3D_RSVEC_MASK))))
{ // Fast path. We do not need any processing done in UpdateInternalState other than updating rstates array
pDevI->rstates[dwState] = dwValue;
HRESULT ret = pDevI->SetRenderStateI(dwState, dwValue);
if(ret != D3D_OK)
throw ret;
}
else
{
pDevI->UpdateInternalState(dwState, dwValue);
if (pDevI->CanHandleRenderState(dwState))
{
HRESULT ret = pDevI->SetRenderStateI(dwState, dwValue);
if(ret != D3D_OK)
throw ret;
}
}
}
else
{
D3D_WARN(4,"Ignoring redundant SetRenderState");
}
}
}
break;
}
case D3DDP2OP_SETLIGHT:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2SETLIGHT pData = (LPD3DHAL_DP2SETLIGHT)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETLIGHT));
switch (pData->dwDataType)
{
case D3DHAL_SETLIGHT_ENABLE:
pDevI->LightEnableI( pData->dwIndex, TRUE );
break;
case D3DHAL_SETLIGHT_DISABLE:
pDevI->LightEnableI( pData->dwIndex, FALSE );
break;
case D3DHAL_SETLIGHT_DATA:
pDevI->SetLightI(pData->dwIndex, (D3DLIGHT7 *)p);
p = (LPDWORD)((LPBYTE)p + sizeof(D3DLIGHT7));
break;
}
}
break;
}
case D3DDP2OP_SETMATERIAL:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2SETMATERIAL pData = (LPD3DHAL_DP2SETMATERIAL)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETMATERIAL));
pDevI->SetMaterialI(pData);
}
break;
}
case D3DDP2OP_SETTRANSFORM:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
D3DHAL_DP2SETTRANSFORM *pData = (D3DHAL_DP2SETTRANSFORM*)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETTRANSFORM));
pDevI->SetTransformI(pData->xfrmType, &pData->matrix);
}
break;
}
case D3DDP2OP_TEXTURESTAGESTATE:
{
if (pDevI->dwFEFlags & D3DFE_EXECUTESTATEMODE)
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
DWORD dwStage = pData->wStage;
DWORD dwState = pData->TSState;
DWORD dwValue = pData->dwValue;
if (pDevI->tsstates[dwStage][dwState] != dwValue)
{
// Fast path. We do not need any processing done in UpdateInternalTSS other than updating tsstates array
if (pDevI->NeedInternalTSSUpdate(dwState))
pDevI->UpdateInternalTextureStageState(dwStage, (D3DTEXTURESTAGESTATETYPE)dwState, dwValue);
else
pDevI->tsstates[dwStage][dwState] = dwValue;
}
else
{
D3D_WARN(4,"Ignoring redundant SetTextureStageState");
}
}
}
else
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
DWORD dwStage = pData->wStage;
DWORD dwState = pData->TSState;
DWORD dwValue = pData->dwValue;
if (pDevI->tsstates[dwStage][dwState] != dwValue)
{
// Fast path. We do not need any processing done in UpdateInternalTSS other than updating tsstates array
if (pDevI->NeedInternalTSSUpdate(dwState))
{
if(pDevI->UpdateInternalTextureStageState(dwStage, (D3DTEXTURESTAGESTATETYPE)dwState, dwValue))
continue;
}
else
{
pDevI->tsstates[dwStage][dwState] = dwValue;
}
if (dwStage >= pDevI->dwMaxTextureBlendStages)
continue;
HRESULT ret = pDevI->SetTSSI(dwStage, (D3DTEXTURESTAGESTATETYPE)dwState, dwValue);
if(ret != D3D_OK)
throw ret;
}
else
{
D3D_WARN(4,"Ignoring redundant SetTextureStageState");
}
}
}
break;
}
case D3DDP2OP_FRONTENDDATA:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2FRONTENDDATA pData = (LPD3DHAL_DP2FRONTENDDATA)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FRONTENDDATA));
HRESULT ret = pDevI->SetTexture(pData->wStage, (LPDIRECTDRAWSURFACE7)pData->pTexture);
if (ret != D3D_OK)
throw ret;
}
break;
}
case D3DDP2OP_VIEWPORTINFO:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
D3DVIEWPORT7 viewport;
LPD3DHAL_DP2VIEWPORTINFO lpVwpData = (LPD3DHAL_DP2VIEWPORTINFO)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2VIEWPORTINFO));
viewport.dwX = lpVwpData->dwX;
viewport.dwY = lpVwpData->dwY;
viewport.dwWidth = lpVwpData->dwWidth;
viewport.dwHeight = lpVwpData->dwHeight;
// The next command has to be D3DDP2OP_ZRANGE
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
LPD3DHAL_DP2ZRANGE pData = (LPD3DHAL_DP2ZRANGE)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2ZRANGE));
viewport.dvMinZ = pData->dvMinZ;
viewport.dvMaxZ = pData->dvMaxZ;
pDevI->SetViewportI(&viewport);
}
break;
}
case D3DDP2OP_SETCLIPPLANE:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
D3DHAL_DP2SETCLIPPLANE *pData = (D3DHAL_DP2SETCLIPPLANE*)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETCLIPPLANE));
pDevI->SetClipPlaneI(pData->dwIndex, pData->plane);
}
break;
}
#ifdef DBG
default:
DDASSERT(FALSE);
#endif
}
}
pDevI->dwFEFlags &= ~D3DFE_EXECUTESTATEMODE;
}
catch(HRESULT ret)
{
pDevI->dwFEFlags &= ~D3DFE_EXECUTESTATEMODE;
throw ret;
}
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSet::Capture"
void CStateSet::Capture(LPDIRECT3DDEVICEI pDevI, BOOL bFrontEndBuffer)
{
DWORD *p;
DWORD dwSize;
DWORD *pEnd;
if (bFrontEndBuffer)
{
p = (DWORD*)m_FEOnlyBuffer.m_pBuffer;
dwSize = m_FEOnlyBuffer.m_dwCurrentSize;
}
else
{
p = (DWORD*)m_DriverBuffer.m_pBuffer;
dwSize = m_DriverBuffer.m_dwCurrentSize;
}
pEnd = (DWORD*)((BYTE*)p + dwSize);
while (p < pEnd)
{
LPD3DHAL_DP2COMMAND pCommand = (LPD3DHAL_DP2COMMAND)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
switch ((D3DHAL_DP2OPERATION)pCommand->bCommand)
{
case D3DDP2OP_RENDERSTATE:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
const D3DRENDERSTATETYPE state = (D3DRENDERSTATETYPE)*p++;
*p++ = pDevI->rstates[state];
}
break;
}
case D3DDP2OP_SETLIGHT:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2SETLIGHT pData = (LPD3DHAL_DP2SETLIGHT)p;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETLIGHT));
if(pData->dwIndex >= pDevI->m_dwNumLights)
{
D3D_ERR("Unable to capture light state (light not set?)");
throw D3DERR_LIGHT_SET_FAILED;
}
switch (pData->dwDataType)
{
case D3DHAL_SETLIGHT_ENABLE:
if(!pDevI->m_pLights[pData->dwIndex].Enabled())
pData->dwDataType = D3DHAL_SETLIGHT_DISABLE;
break;
case D3DHAL_SETLIGHT_DISABLE:
if(pDevI->m_pLights[pData->dwIndex].Enabled())
pData->dwDataType = D3DHAL_SETLIGHT_ENABLE;
break;
case D3DHAL_SETLIGHT_DATA:
*((LPD3DLIGHT7)p) = pDevI->m_pLights[pData->dwIndex].m_Light;
p = (LPDWORD)((LPBYTE)p + sizeof(D3DLIGHT7));
break;
}
}
break;
}
case D3DDP2OP_SETMATERIAL:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2SETMATERIAL pData = (LPD3DHAL_DP2SETMATERIAL)p;
*pData = pDevI->lighting.material;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETMATERIAL));
}
break;
}
case D3DDP2OP_SETTRANSFORM:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2SETTRANSFORM pData = (LPD3DHAL_DP2SETTRANSFORM)p;
switch(pData->xfrmType)
{
case D3DTRANSFORMSTATE_WORLD:
pData->matrix = *((LPD3DMATRIX)&pDevI->transform.world[0]);
break;
case D3DTRANSFORMSTATE_WORLD1:
pData->matrix = *((LPD3DMATRIX)&pDevI->transform.world[1]);
break;
case D3DTRANSFORMSTATE_WORLD2:
pData->matrix = *((LPD3DMATRIX)&pDevI->transform.world[2]);
break;
case D3DTRANSFORMSTATE_WORLD3:
pData->matrix = *((LPD3DMATRIX)&pDevI->transform.world[3]);
break;
case D3DTRANSFORMSTATE_VIEW:
pData->matrix = *((LPD3DMATRIX)&pDevI->transform.view);
break;
case D3DTRANSFORMSTATE_PROJECTION:
pData->matrix = *((LPD3DMATRIX)&pDevI->transform.proj);
break;
case D3DTRANSFORMSTATE_TEXTURE0:
pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[0]);
break;
case D3DTRANSFORMSTATE_TEXTURE1:
pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[1]);
break;
case D3DTRANSFORMSTATE_TEXTURE2:
pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[2]);
break;
case D3DTRANSFORMSTATE_TEXTURE3:
pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[3]);
break;
case D3DTRANSFORMSTATE_TEXTURE4:
pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[4]);
break;
case D3DTRANSFORMSTATE_TEXTURE5:
pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[5]);
break;
case D3DTRANSFORMSTATE_TEXTURE6:
pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[6]);
break;
case D3DTRANSFORMSTATE_TEXTURE7:
pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[7]);
break;
}
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETTRANSFORM));
}
break;
}
case D3DDP2OP_TEXTURESTAGESTATE:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p;
pData->dwValue = pDevI->tsstates[pData->wStage][pData->TSState];
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
}
break;
}
case D3DDP2OP_FRONTENDDATA:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2FRONTENDDATA pData = (LPD3DHAL_DP2FRONTENDDATA)p;
if (pDevI->lpD3DMappedTexI[pData->wStage])
{
if(pDevI->lpD3DMappedTexI[pData->wStage]->D3DManaged())
pData->pTexture = pDevI->lpD3DMappedTexI[pData->wStage]->lpDDSSys;
else
pData->pTexture = pDevI->lpD3DMappedTexI[pData->wStage]->lpDDS;
}
else
{
pData->pTexture = NULL;
}
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FRONTENDDATA));
}
break;
}
case D3DDP2OP_VIEWPORTINFO:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
D3DVIEWPORT7 viewport;
LPD3DHAL_DP2VIEWPORTINFO lpVwpData = (LPD3DHAL_DP2VIEWPORTINFO)p;
lpVwpData->dwX = pDevI->m_Viewport.dwX;
lpVwpData->dwY = pDevI->m_Viewport.dwY;
lpVwpData->dwWidth = pDevI->m_Viewport.dwWidth;
lpVwpData->dwHeight = pDevI->m_Viewport.dwHeight;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2VIEWPORTINFO));
// The next command has to be D3DDP2OP_ZRANGE
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
LPD3DHAL_DP2ZRANGE pData = (LPD3DHAL_DP2ZRANGE)p;
pData->dvMinZ = pDevI->m_Viewport.dvMinZ;
pData->dvMaxZ = pDevI->m_Viewport.dvMaxZ;
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2ZRANGE));
}
break;
}
case D3DDP2OP_SETCLIPPLANE:
{
for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
{
LPD3DHAL_DP2SETCLIPPLANE pData = (LPD3DHAL_DP2SETCLIPPLANE)p;
*((LPD3DVECTORH)pData->plane) = pDevI->transform.userClipPlane[pData->dwIndex];
p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETCLIPPLANE));
}
break;
}
#ifdef DBG
default:
DDASSERT(FALSE);
#endif
}
}
}
//=====================================================================
// CStateSetBuffer interface
//
#undef DPF_MODNAME
#define DPF_MODNAME "CStateSetBuffer::InsertCommand"
void CStateSetBuffer::InsertCommand(D3DHAL_DP2OPERATION op, LPVOID pData, DWORD dwDataSize)
{
const DWORD GROWSIZE = 1024;
if (m_pDP2CurrCommand != 0 && m_pDP2CurrCommand->bCommand == op)
{
if (dwDataSize + m_dwCurrentSize <= m_dwBufferSize)
{
++m_pDP2CurrCommand->wStateCount;
memcpy(m_pBuffer + m_dwCurrentSize, pData, dwDataSize);
m_dwCurrentSize += dwDataSize;
return;
}
}
// Check for space
if (sizeof(D3DHAL_DP2COMMAND) + dwDataSize + m_dwCurrentSize > m_dwBufferSize)
{
// We need to grow the buffer
DWORD dwNewBufferSize = max(m_dwBufferSize + GROWSIZE, sizeof(D3DHAL_DP2COMMAND) + dwDataSize + m_dwCurrentSize);
BYTE *pTmp = new BYTE[dwNewBufferSize];
if (pTmp == NULL)
{
D3D_ERR("Not enough memory to create state block buffer");
throw DDERR_OUTOFMEMORY;
}
if (m_pBuffer)
{
memcpy(pTmp, m_pBuffer, m_dwCurrentSize);
delete [] m_pBuffer;
}
m_pBuffer = pTmp;
m_dwBufferSize = dwNewBufferSize;
}
// Add new instruction
m_pDP2CurrCommand = (LPD3DHAL_DP2COMMAND)(m_pBuffer + m_dwCurrentSize);
m_pDP2CurrCommand->bCommand = op;
m_pDP2CurrCommand->bReserved = 0;
m_pDP2CurrCommand->wStateCount = 1;
m_dwCurrentSize += sizeof(D3DHAL_DP2COMMAND);
memcpy(m_pBuffer + m_dwCurrentSize, pData, dwDataSize);
m_dwCurrentSize += dwDataSize;
return;
}
//=====================================================================
void InsertStateSetOp(LPDIRECT3DDEVICEI pDevI, DWORD dwOperation, DWORD dwParam, D3DSTATEBLOCKTYPE sbt)
{
CDirect3DDeviceIDP2 *device = static_cast<CDirect3DDeviceIDP2*>(pDevI);
LPD3DHAL_DP2STATESET pData;
pData = (LPD3DHAL_DP2STATESET)device->GetHalBufferPointer(D3DDP2OP_STATESET, sizeof(*pData));
pData->dwOperation = dwOperation;
pData->dwParam = dwParam;
pData->sbType = sbt;
}