|
|
///////////////////////////////////////////////////////////////////////////////
//
// primfns.cpp
//
// Copyright (C) Microsoft Corporation, 1998.
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.cpp"
#pragma hdrstop
//----------------------------------------------------------------------------
//
// Wrap functions
//
//----------------------------------------------------------------------------
HRESULT WrapDp2SetViewport( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetViewport(pCmd); }
HRESULT WrapDp2SetWRange ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetWRange(pCmd); }
HRESULT WrapDp2SetZRange ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetZRange(pCmd); }
HRESULT WrapDp2SetRenderStates( RefDev *pRefDev, DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates ) { return pRefDev->Dp2SetRenderStates(dwFvf, pCmd, lpdwRuntimeRStates); }
HRESULT WrapDp2SetTextureStageState( RefDev *pRefDev, DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetTextureStageState(dwFvf, pCmd); }
HRESULT WrapDp2SetMaterial ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetMaterial(pCmd); }
HRESULT WrapDp2SetLight( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd, LPDWORD pdwStride ) { return pRefDev->Dp2SetLight(pCmd, pdwStride); }
HRESULT WrapDp2CreateLight ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2CreateLight(pCmd); }
HRESULT WrapDp2SetTransform( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetTransform(pCmd); }
HRESULT WrapDp2MultiplyTransform( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2MultiplyTransform(pCmd); }
HRESULT WrapDp2SetExtention( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetExtention(pCmd); }
HRESULT WrapDp2SetClipPlane( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetClipPlane(pCmd); }
HRESULT WrapDp2SetVertexShader( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetVertexShader( pCmd ); }
HRESULT WrapDp2SetVertexShaderConsts( RefDev *pRefDev, DWORD StartReg, DWORD dwCount, LPDWORD pData ) { return pRefDev->Dp2SetVertexShaderConsts( StartReg, dwCount, pData ); }
HRESULT WrapDp2SetPixelShader( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetPixelShader( pCmd ); }
HRESULT WrapDp2SetPixelShaderConsts( RefDev *pRefDev, DWORD StartReg, DWORD dwCount, LPDWORD pData ) { return pRefDev->Dp2SetPixelShaderConsts( StartReg, dwCount, pData ); }
HRESULT WrapDp2SetStreamSource( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetStreamSource( pCmd ); }
HRESULT WrapDp2SetIndices( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2SetIndices( pCmd ); }
HRESULT WrapDp2RecViewport( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecViewport(pCmd); }
HRESULT WrapDp2RecWRange ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecWRange(pCmd); }
HRESULT WrapDp2RecZRange ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecZRange(pCmd); }
HRESULT WrapDp2RecRenderStates( RefDev *pRefDev, DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates ) { return pRefDev->Dp2RecRenderStates(dwFvf, pCmd, lpdwRuntimeRStates); }
HRESULT WrapDp2RecTextureStageState( RefDev *pRefDev, DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecTextureStageState(dwFvf, pCmd); }
HRESULT WrapDp2RecMaterial ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecMaterial(pCmd); }
HRESULT WrapDp2RecSetLight ( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd, LPDWORD pdwStride) { return pRefDev->Dp2RecSetLight(pCmd, pdwStride); }
HRESULT WrapDp2RecCreateLight( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecCreateLight(pCmd); }
HRESULT WrapDp2RecTransform( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecTransform(pCmd); }
HRESULT WrapDp2RecExtention( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecExtention(pCmd); }
HRESULT WrapDp2RecClipPlane( RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecClipPlane(pCmd); }
HRESULT WrapDp2RecSetVertexShader( RefDev* pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecSetVertexShader( pCmd ); }
HRESULT WrapDp2RecSetVertexShaderConsts( RefDev* pRefDev, DWORD StartReg, DWORD dwCount, LPDWORD pData ) { return pRefDev->Dp2RecSetVertexShaderConsts( StartReg, dwCount, pData ); }
HRESULT WrapDp2RecSetPixelShader( RefDev* pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecSetPixelShader( pCmd ); }
HRESULT WrapDp2RecSetPixelShaderConsts( RefDev* pRefDev, DWORD StartReg, DWORD dwCount, LPDWORD pData ) { return pRefDev->Dp2RecSetPixelShaderConsts( StartReg, dwCount, pData ); }
HRESULT WrapDp2RecSetStreamSource( RefDev* pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecSetStreamSource( pCmd ); }
HRESULT WrapDp2RecSetIndices( RefDev* pRefDev, LPD3DHAL_DP2COMMAND pCmd ) { return pRefDev->Dp2RecSetIndices( pCmd ); }
static RD_STATESETFUNCTIONTBL StateRecFunctions = { sizeof(RD_STATESETFUNCTIONTBL), WrapDp2RecRenderStates, WrapDp2RecTextureStageState, WrapDp2RecViewport, WrapDp2RecWRange, WrapDp2RecMaterial, WrapDp2RecZRange, WrapDp2RecSetLight, WrapDp2RecCreateLight, WrapDp2RecTransform, WrapDp2RecExtention, WrapDp2RecClipPlane, WrapDp2RecSetVertexShader, WrapDp2RecSetVertexShaderConsts, WrapDp2RecSetPixelShader, WrapDp2RecSetPixelShaderConsts, WrapDp2RecSetStreamSource, WrapDp2RecSetIndices };
static RD_STATESETFUNCTIONTBL StateSetFunctions = { sizeof(RD_STATESETFUNCTIONTBL), WrapDp2SetRenderStates, WrapDp2SetTextureStageState, WrapDp2SetViewport, WrapDp2SetWRange, WrapDp2SetMaterial, WrapDp2SetZRange, WrapDp2SetLight, WrapDp2CreateLight, WrapDp2SetTransform, WrapDp2SetExtention, WrapDp2SetClipPlane, WrapDp2SetVertexShader, WrapDp2SetVertexShaderConsts, WrapDp2SetPixelShader, WrapDp2SetPixelShaderConsts, WrapDp2SetStreamSource, WrapDp2SetIndices, WrapDp2MultiplyTransform };
//----------------------------------------------------------------------------
//
// RefDev methods
//
//----------------------------------------------------------------------------
void RefDev::StoreLastPixelState(BOOL bStore) { if( bStore ) { m_LastState = GetRS()[D3DRENDERSTATE_LASTPIXEL]; SetRenderState(D3DRENDERSTATE_LASTPIXEL, 0); } else { SetRenderState(D3DRENDERSTATE_LASTPIXEL, m_LastState); } }
void RefDev::SetRecStateFunctions(void) { pStateSetFuncTbl = &StateRecFunctions; }
void RefDev::SetSetStateFunctions(void) { pStateSetFuncTbl = &StateSetFunctions; }
HRESULT RefDev::Dp2SetRenderStates(DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates ) { WORD wStateCount = pCmd->wStateCount; INT i; HRESULT hr = D3D_OK;
D3DHAL_DP2RENDERSTATE *pRenderState = (D3DHAL_DP2RENDERSTATE *)(pCmd + 1);
for (i = 0; i < (INT)wStateCount; i++, pRenderState++) { UINT32 type = (UINT32) pRenderState->RenderState;
// Check for overrides
if( IS_OVERRIDE(type) ) { UINT32 override = GET_OVERRIDE(type);
if( pRenderState->dwState ) STATESET_SET(m_renderstate_override, override); else STATESET_CLEAR(m_renderstate_override, override); continue; }
if( STATESET_ISSET(m_renderstate_override, type) ) continue;
// Set the runtime copy (if necessary)
if( NULL != lpdwRuntimeRStates ) { lpdwRuntimeRStates[pRenderState->RenderState] = pRenderState->dwState; }
// Set the state
SetRenderState(pRenderState->RenderState, pRenderState->dwState); }
return hr; }
HRESULT RefDev::Dp2SetTextureStageState( DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd ) { WORD wStateCount = pCmd->wStateCount; INT i; HRESULT hr = D3D_OK;
D3DHAL_DP2TEXTURESTAGESTATE *pTexStageState = (D3DHAL_DP2TEXTURESTAGESTATE *)(pCmd + 1);
for (i = 0; i < (INT)wStateCount; i++, pTexStageState++) { SetTextureStageState( pTexStageState->wStage, pTexStageState->TSState, pTexStageState->dwValue ); }
return hr; }
HRESULT RefDev::Dp2SetViewport(LPD3DHAL_DP2COMMAND pCmd) { LPD3DHAL_DP2VIEWPORTINFO pVpt;
// Keep only the last viewport notification
pVpt = (D3DHAL_DP2VIEWPORTINFO *)(pCmd + 1) + (pCmd->wStateCount - 1);
// Update T&L viewport state
D3DVIEWPORT7& vp = m_Clipper.m_Viewport;
vp.dwX = pVpt->dwX; vp.dwY = pVpt->dwY; vp.dwWidth = pVpt->dwWidth; vp.dwHeight = pVpt->dwHeight; m_Clipper.m_dwFlags |= RefClipper::RCLIP_DIRTY_VIEWRECT;
// get render target; update it; put it back
RDRenderTarget *pRendTgt = this->GetRenderTarget(); pRendTgt->m_Clip.left = pVpt->dwX; pRendTgt->m_Clip.top = pVpt->dwY; pRendTgt->m_Clip.right = pVpt->dwX + pVpt->dwWidth - 1; pRendTgt->m_Clip.bottom = pVpt->dwY + pVpt->dwHeight - 1; SetRenderTarget( pRendTgt ); return D3D_OK; }
HRESULT RefDev::Dp2SetWRange(LPD3DHAL_DP2COMMAND pCmd) { LPD3DHAL_DP2WINFO pWInfo;
// Keep only the last viewport notification
pWInfo = (D3DHAL_DP2WINFO *)(pCmd + 1) + (pCmd->wStateCount - 1);
// get render target; update it; put it back
RDRenderTarget *pRendTgt = this->GetRenderTarget(); pRendTgt->m_fWRange[0] = pWInfo->dvWNear; pRendTgt->m_fWRange[1] = pWInfo->dvWFar; this->SetRenderTarget( pRendTgt ); return D3D_OK; }
HRESULT RefDev::Dp2SetZRange(LPD3DHAL_DP2COMMAND pCmd) { LPD3DHAL_DP2ZRANGE pZRange;
// Keep only the last viewport notification
pZRange = (D3DHAL_DP2ZRANGE *)(pCmd + 1) + (pCmd->wStateCount - 1);
// Update T&L viewport state
D3DVIEWPORT7& vp = m_Clipper.m_Viewport;
vp.dvMinZ = pZRange->dvMinZ; vp.dvMaxZ = pZRange->dvMaxZ; m_Clipper.m_dwFlags |= RefClipper::RCLIP_DIRTY_ZRANGE;
return D3D_OK; }
HRESULT RefDev::Dp2SetMaterial(LPD3DHAL_DP2COMMAND pCmd) { LPD3DHAL_DP2SETMATERIAL pSetMat;
// Keep only the last material notification
pSetMat = (D3DHAL_DP2SETMATERIAL *)(pCmd + 1) + (pCmd->wStateCount - 1);
m_RefVP.m_Material = *(D3DMATERIAL7 *)pSetMat; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_MATERIAL;
return D3D_OK; }
HRESULT RefDev::Dp2CreateLight(LPD3DHAL_DP2COMMAND pCmd) { WORD wNumCreateLight = pCmd->wStateCount; LPD3DHAL_DP2CREATELIGHT pCreateLight = (LPD3DHAL_DP2CREATELIGHT)(pCmd + 1); HRESULT hr = D3D_OK;
for (int i = 0; i < wNumCreateLight; i++, pCreateLight++) { HR_RET(m_RefVP.GrowLightArray( pCreateLight->dwIndex ) ); }
return hr; }
HRESULT RefDev::Dp2SetLight(LPD3DHAL_DP2COMMAND pCmd, LPDWORD pdwStride) {
HRESULT hr = D3D_OK; WORD wNumSetLight = pCmd->wStateCount; _ASSERT( pdwStride != NULL, "pdwStride is Null" ); *pdwStride = sizeof(D3DHAL_DP2COMMAND); LPD3DHAL_DP2SETLIGHT pSetLight = (LPD3DHAL_DP2SETLIGHT)(pCmd + 1); D3DLIGHT7 *pLightData = NULL;
for (int i = 0; i < wNumSetLight; i++) { DWORD dwStride = sizeof(D3DHAL_DP2SETLIGHT); DWORD dwIndex = pSetLight->dwIndex;
// Assert that create was not called here
_ASSERTf( m_RefVP.m_LightArray.IsValidIndex( dwIndex ), ( "Create was not called prior to the SetLight for light %d", dwIndex ));
switch (pSetLight->dwDataType) { case D3DHAL_SETLIGHT_ENABLE: m_RefVP.LightEnable( dwIndex, TRUE ); break; case D3DHAL_SETLIGHT_DISABLE: m_RefVP.LightEnable( dwIndex, FALSE ); break; case D3DHAL_SETLIGHT_DATA: pLightData = (D3DLIGHT7 *)((LPBYTE)pSetLight + dwStride); dwStride += sizeof(D3DLIGHT7); HR_RET(m_RefVP.SetLightData( pSetLight->dwIndex, pLightData)); break; default: DPFERR( "Unknown SetLight command" ); hr = DDERR_INVALIDPARAMS; }
*pdwStride += dwStride; // Update the command buffer pointer
pSetLight = (D3DHAL_DP2SETLIGHT *)((LPBYTE)pSetLight + dwStride); }
return hr; }
static D3DMATRIX matIdent = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f };
HRESULT RefDev::Dp2SetTransform(LPD3DHAL_DP2COMMAND pCmd) { WORD wNumXfrms = pCmd->wStateCount; D3DHAL_DP2SETTRANSFORM *pSetXfrm = (D3DHAL_DP2SETTRANSFORM*)(pCmd + 1);
for (int i = 0; i < (int) wNumXfrms; i++, pSetXfrm++) { D3DMATRIX* pMat = &pSetXfrm->matrix; DWORD xfrmType = (DWORD)pSetXfrm->xfrmType; if ((DWORD)xfrmType >= RD_WORLDMATRIXBASE && (DWORD)xfrmType < (RD_WORLDMATRIXBASE + RD_MAX_WORLD_MATRICES)) { // World matrix is set
UINT index = (DWORD)xfrmType - RD_WORLDMATRIXBASE; memcpy(&(m_RefVP.m_xfmWorld[index]), pMat, sizeof(D3DMATRIX)); switch (index) { case 0: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDXFM; break; case 1: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD1XFM; break; case 2: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD2XFM; break; case 3: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD3XFM; break; default: // m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDNXFM;
break; } } else { switch( xfrmType ) { case D3DTRANSFORMSTATE_WORLD_DX7: memcpy(&(m_RefVP.m_xfmWorld[0]), pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDXFM; break; case D3DTRANSFORMSTATE_VIEW: memcpy(&m_RefVP.m_xfmView, pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_VIEWXFM; break; case D3DTRANSFORMSTATE_PROJECTION: memcpy(&m_RefVP.m_xfmProj, pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_PROJXFM; break; case D3DTRANSFORMSTATE_WORLD1_DX7: memcpy(&(m_RefVP.m_xfmWorld[1]), pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD1XFM; break; case D3DTRANSFORMSTATE_WORLD2_DX7: memcpy(&(m_RefVP.m_xfmWorld[2]), pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD2XFM; break; case D3DTRANSFORMSTATE_WORLD3_DX7: memcpy(&(m_RefVP.m_xfmWorld[3]), pMat, sizeof(D3DMATRIX)); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD3XFM; break; case D3DTRANSFORMSTATE_TEXTURE0: case D3DTRANSFORMSTATE_TEXTURE1: case D3DTRANSFORMSTATE_TEXTURE2: case D3DTRANSFORMSTATE_TEXTURE3: case D3DTRANSFORMSTATE_TEXTURE4: case D3DTRANSFORMSTATE_TEXTURE5: case D3DTRANSFORMSTATE_TEXTURE6: case D3DTRANSFORMSTATE_TEXTURE7: memcpy( &(m_RefVP.m_xfmTex[xfrmType - D3DTRANSFORMSTATE_TEXTURE0]), pMat, sizeof(D3DMATRIX) ); break; default: DPFERR( "Ignoring unknown transform type" ); } } }
return D3D_OK; }
extern void MatrixProduct(D3DMATRIX *result, D3DMATRIX *a, D3DMATRIX *b);
HRESULT RefDev::Dp2MultiplyTransform(LPD3DHAL_DP2COMMAND pCmd) { WORD wNumXfrms = pCmd->wStateCount; D3DHAL_DP2MULTIPLYTRANSFORM *pSetXfrm = (D3DHAL_DP2MULTIPLYTRANSFORM*)(pCmd + 1);
for (int i = 0; i < (int) wNumXfrms; i++, pSetXfrm++) { D3DMATRIX* pMat = &pSetXfrm->matrix; DWORD xfrmType = (DWORD)pSetXfrm->xfrmType; if ((DWORD)xfrmType >= RD_WORLDMATRIXBASE && (DWORD)xfrmType < (RD_WORLDMATRIXBASE + RD_MAX_WORLD_MATRICES)) { // World matrix is set
UINT index = (DWORD)xfrmType - RD_WORLDMATRIXBASE; MatrixProduct(&(m_RefVP.m_xfmWorld[index]), pMat, &(m_RefVP.m_xfmWorld[index])); switch (index) { case 0: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDXFM; break; case 1: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD1XFM; break; case 2: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD2XFM; break; case 3: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD3XFM; break; default: // m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDNXFM;
break; } } else { switch( xfrmType ) { case D3DTRANSFORMSTATE_WORLD_DX7: MatrixProduct(&(m_RefVP.m_xfmWorld[0]), pMat, &(m_RefVP.m_xfmWorld[0])); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLDXFM; break; case D3DTRANSFORMSTATE_VIEW: MatrixProduct(&m_RefVP.m_xfmView, pMat, &m_RefVP.m_xfmView); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_VIEWXFM; break; case D3DTRANSFORMSTATE_PROJECTION: MatrixProduct(&m_RefVP.m_xfmProj, pMat, &m_RefVP.m_xfmProj); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_PROJXFM; break; case D3DTRANSFORMSTATE_WORLD1_DX7: MatrixProduct(&(m_RefVP.m_xfmWorld[1]), pMat, &(m_RefVP.m_xfmWorld[1])); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD1XFM; break; case D3DTRANSFORMSTATE_WORLD2_DX7: MatrixProduct(&(m_RefVP.m_xfmWorld[2]), pMat, &(m_RefVP.m_xfmWorld[2])); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD2XFM; break; case D3DTRANSFORMSTATE_WORLD3_DX7: MatrixProduct(&(m_RefVP.m_xfmWorld[3]), pMat, &(m_RefVP.m_xfmWorld[3])); m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_WORLD3XFM; break; case D3DTRANSFORMSTATE_TEXTURE0: case D3DTRANSFORMSTATE_TEXTURE1: case D3DTRANSFORMSTATE_TEXTURE2: case D3DTRANSFORMSTATE_TEXTURE3: case D3DTRANSFORMSTATE_TEXTURE4: case D3DTRANSFORMSTATE_TEXTURE5: case D3DTRANSFORMSTATE_TEXTURE6: case D3DTRANSFORMSTATE_TEXTURE7: MatrixProduct( &(m_RefVP.m_xfmTex[xfrmType - D3DTRANSFORMSTATE_TEXTURE0]), pMat, &(m_RefVP.m_xfmTex[xfrmType - D3DTRANSFORMSTATE_TEXTURE0]) ); break; default: DPFERR( "Ignoring unknown transform type" ); } } }
return D3D_OK; }
HRESULT RefDev::Dp2SetClipPlane(LPD3DHAL_DP2COMMAND pCmd) { WORD wNumClipPlanes = pCmd->wStateCount; LPD3DHAL_DP2SETCLIPPLANE pSetClipPlane = (LPD3DHAL_DP2SETCLIPPLANE)(pCmd + 1);
for (int i = 0; i < (int) wNumClipPlanes; i++, pSetClipPlane++) { _ASSERTf( pSetClipPlane->dwIndex < RD_MAX_USER_CLIPPLANES, ("Refrast does not support %d clip planes", pSetClipPlane->dwIndex ) );
memcpy( &(m_Clipper.m_userClipPlanes[pSetClipPlane->dwIndex]), pSetClipPlane->plane, sizeof(RDVECTOR4) ); } return D3D_OK; }
HRESULT RefDev::Dp2SetExtention(LPD3DHAL_DP2COMMAND pCmd) { return D3D_OK; }
HRESULT RefDev::Dp2RecRenderStates(DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates ) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2RENDERSTATE);
return RecordStates((PUINT8)pCmd, dwSize); }
HRESULT RefDev::Dp2RecTextureStageState(DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd ) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2TEXTURESTAGESTATE);
return RecordStates((PUINT8)pCmd, dwSize); }
HRESULT RefDev::Dp2RecViewport(LPD3DHAL_DP2COMMAND pCmd) { return RecordLastState(pCmd, sizeof(D3DHAL_DP2VIEWPORTINFO)); }
HRESULT RefDev::Dp2RecWRange(LPD3DHAL_DP2COMMAND pCmd) { return RecordLastState(pCmd, sizeof(D3DHAL_DP2WINFO)); }
HRESULT RefDev::Dp2RecZRange(LPD3DHAL_DP2COMMAND pCmd) { return RecordLastState(pCmd, sizeof(D3DHAL_DP2ZRANGE)); }
HRESULT RefDev::Dp2RecMaterial(LPD3DHAL_DP2COMMAND pCmd) { return RecordLastState(pCmd, sizeof(D3DHAL_DP2SETMATERIAL)); }
HRESULT RefDev::Dp2RecCreateLight(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2CREATELIGHT);
return RecordStates((PUINT8)pCmd, dwSize); }
HRESULT RefDev::Dp2RecSetLight(LPD3DHAL_DP2COMMAND pCmd, LPDWORD pdwStride) { WORD wNumSetLight = pCmd->wStateCount; _ASSERT(pdwStride != NULL, "pdwStride is NULL" ); *pdwStride = sizeof(D3DHAL_DP2COMMAND); LPD3DHAL_DP2SETLIGHT pSetLight = (LPD3DHAL_DP2SETLIGHT)(pCmd + 1);
for (int i = 0; i < wNumSetLight; i++) { DWORD dwStride = sizeof(D3DHAL_DP2SETLIGHT);
switch (pSetLight->dwDataType) { case D3DHAL_SETLIGHT_ENABLE: break; case D3DHAL_SETLIGHT_DISABLE: break; case D3DHAL_SETLIGHT_DATA: dwStride += sizeof(D3DLIGHT7); break; }
*pdwStride += dwStride; // Update the command buffer pointer
pSetLight = (D3DHAL_DP2SETLIGHT *)((LPBYTE)pSetLight + dwStride); }
return RecordStates((PUINT8)pCmd, *pdwStride); }
HRESULT RefDev::Dp2RecTransform(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2SETTRANSFORM);
return RecordStates((PUINT8)pCmd, dwSize); }
HRESULT RefDev::Dp2RecExtention(LPD3DHAL_DP2COMMAND pCmd) { return D3D_OK; }
HRESULT RefDev::Dp2RecClipPlane(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2SETCLIPPLANE);
return RecordStates((PUINT8)pCmd, dwSize); }
HRESULT RefDev::Dp2RecSetVertexShader(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2VERTEXSHADER);
return RecordStates((PUINT8)pCmd, dwSize); }
HRESULT RefDev::Dp2RecSetVertexShaderConsts( DWORD StartReg, DWORD dwCount, LPDWORD pData ) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + dwCount*4*sizeof(float);
LPBYTE pBytes = new BYTE[dwSize]; if( pBytes == NULL ) return DDERR_OUTOFMEMORY; LPD3DHAL_DP2COMMAND pCmd = (LPD3DHAL_DP2COMMAND)pBytes; LPD3DHAL_DP2SETVERTEXSHADERCONST pSVC = (LPD3DHAL_DP2SETVERTEXSHADERCONST)(pCmd + 1); LPDWORD pStuff = (LPDWORD)(pSVC + 1);
// Set up pCmd
pCmd->bCommand = D3DDP2OP_SETVERTEXSHADERCONST; pCmd->wStateCount = 1;
// Set up pSVC
pSVC->dwRegister = StartReg; pSVC->dwCount = dwCount;
// Copy the data
memcpy( pStuff, pData, dwCount*4*sizeof(float));
HRESULT hr = RecordStates(pBytes, dwSize); delete [] pBytes; return hr; }
HRESULT RefDev::Dp2RecSetPixelShader(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2PIXELSHADER);
return RecordStates((PUINT8)pCmd, dwSize); }
HRESULT RefDev::Dp2RecSetPixelShaderConsts( DWORD StartReg, DWORD dwCount, LPDWORD pData ) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + dwCount*4*sizeof(float);
LPBYTE pBytes = new BYTE[dwSize]; if( pBytes == NULL ) return DDERR_OUTOFMEMORY; LPD3DHAL_DP2COMMAND pCmd = (LPD3DHAL_DP2COMMAND)pBytes; LPD3DHAL_DP2SETPIXELSHADERCONST pSVC = (LPD3DHAL_DP2SETPIXELSHADERCONST)(pCmd + 1); LPDWORD pStuff = (LPDWORD)(pSVC + 1);
// Set up pCmd
pCmd->bCommand = D3DDP2OP_SETPIXELSHADERCONST; pCmd->wStateCount = 1;
// Set up pSVC
pSVC->dwRegister = StartReg; pSVC->dwCount = dwCount;
// Copy the data
memcpy( pStuff, pData, dwCount*4*sizeof(float));
HRESULT hr = RecordStates(pBytes, dwSize); delete [] pBytes; return hr; }
HRESULT RefDev::Dp2RecSetStreamSource(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2SETSTREAMSOURCE);
return RecordStates((PUINT8)pCmd, dwSize); }
HRESULT RefDev::Dp2RecSetIndices(LPD3DHAL_DP2COMMAND pCmd) { DWORD dwSize = sizeof(D3DHAL_DP2COMMAND) + pCmd->wStateCount * sizeof(D3DHAL_DP2SETINDICES);
return RecordStates((PUINT8)pCmd, dwSize); }
//-----------------------------------------------------------------------------
//
// RecordStates - This function copies the state data into the internal stateset
// buffer. It assumes that the current state set has already been properly set
// up in BeginStateSet().
//
//-----------------------------------------------------------------------------
HRESULT RefDev::RecordStates(PUINT8 pData, DWORD dwSize) { HRESULT ret; LPStateSetData pCurStateSets = m_pStateSets.CurrentItem(); DWORD dwCurIdx = pCurStateSets->CurrentIndex();
// Check if the buffer has enough space
if( (ret = pCurStateSets->CheckAndGrow(dwCurIdx + dwSize, RD_STATESET_GROWDELTA)) != D3D_OK ) { return ret; } // Copy the data and update the ptr.
PUINT8 pDest = (PUINT8)&((*pCurStateSets)[dwCurIdx]); memcpy(pDest, pData, dwSize); pCurStateSets->SetCurrentIndex(dwCurIdx + dwSize);
return D3D_OK; }
HRESULT RefDev::RecordLastState(LPD3DHAL_DP2COMMAND pCmd, DWORD dwUnitSize) { _ASSERT(pCmd->wStateCount != 0, "Number of states to record is zero" ); if( pCmd->wStateCount == 1 ) { return RecordStates((PUINT8)pCmd, sizeof(D3DHAL_DP2COMMAND) + dwUnitSize); } else { HRESULT ret; WORD wCount = pCmd->wStateCount; pCmd->wStateCount = 1; ret = RecordStates((PUINT8)pCmd, sizeof(D3DHAL_DP2COMMAND)); if( ret != D3D_OK ) { return ret; } ret = RecordStates((PUINT8)(pCmd + 1) + dwUnitSize * (wCount - 1), dwUnitSize); if( ret != D3D_OK ) { return ret; } pCmd->wStateCount = wCount; return D3D_OK; } }
HRESULT RefDev::BeginStateSet(DWORD dwHandle) { HRESULT ret;
// Grow the array if no more space left
if( (ret = m_pStateSets.CheckAndGrow(dwHandle)) != D3D_OK ) { return ret; }
_ASSERT(m_pStateSets[dwHandle] == NULL, "pStateSets array is NULL" );
// Create the new StateSet
LPStateSetData pNewStateSet = new StateSetData; if( pNewStateSet == NULL ) { return DDERR_OUTOFMEMORY; }
m_pStateSets.SetCurrentIndex(dwHandle); m_pStateSets.SetCurrentItem(pNewStateSet);
// Switch to record mode
SetRecStateFunctions();
return D3D_OK; }
HRESULT RefDev::EndStateSet(void) { // Switch to execute mode
SetSetStateFunctions();
return D3D_OK; }
HRESULT RefDev::ExecuteStateSet(DWORD dwHandle) { HRESULT ret;
if( (ret = m_pStateSets.CheckRange(dwHandle)) != D3D_OK ) { return ret; }
LPStateSetData pStateSet = m_pStateSets[dwHandle];
if( pStateSet == NULL ) { return DDERR_INVALIDPARAMS; }
LPD3DHAL_DP2COMMAND pCmd = (LPD3DHAL_DP2COMMAND)&((*pStateSet)[0]); UINT_PTR CmdBoundary = (UINT_PTR)pCmd + pStateSet->CurrentIndex();
// Loop through the data, update render states
for (;;) { ret = DrawPrimitives2( NULL, (UINT16)0, (DWORD)0, 0, &pCmd, NULL ); if( ret != D3D_OK ) { return ret; } if( (UINT_PTR)pCmd >= CmdBoundary ) break; }
return D3D_OK; }
HRESULT RefDev::DeleteStateSet(DWORD dwHandle) { HRESULT ret;
if( (ret = m_pStateSets.CheckRange(dwHandle)) != D3D_OK ) { return ret; }
if( m_pStateSets[dwHandle] != NULL ) { delete m_pStateSets[dwHandle]; m_pStateSets[dwHandle] = NULL; }
return D3D_OK; }
HRESULT RefDev::CaptureStateSet(DWORD dwHandle) { HRESULT ret;
if( (ret = m_pStateSets.CheckRange(dwHandle)) != D3D_OK ) { return ret; }
LPStateSetData pStateSet = m_pStateSets[dwHandle];
if( pStateSet == NULL ) { return DDERR_INVALIDPARAMS; }
BYTE *p = &((*pStateSet)[0]); UINT_PTR pEnd = (UINT_PTR)(p + pStateSet->CurrentIndex());
while((UINT_PTR)p < pEnd) { LPD3DHAL_DP2COMMAND pCmd = (LPD3DHAL_DP2COMMAND)p; p += sizeof(D3DHAL_DP2COMMAND); switch(pCmd->bCommand) { case D3DDP2OP_RENDERSTATE: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2RENDERSTATE pData = (LPD3DHAL_DP2RENDERSTATE)p; pData->dwState = GetRS()[pData->RenderState]; p += sizeof(D3DHAL_DP2RENDERSTATE); } break; } case D3DDP2OP_SETLIGHT: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETLIGHT pData = (LPD3DHAL_DP2SETLIGHT)p; p += sizeof(D3DHAL_DP2SETLIGHT); if( !m_RefVP.m_LightArray.IsValidIndex( pData->dwIndex ) ) { DPFERR( "The light index in capture is invalid\n" ); return D3DERR_INVALIDCALL; } switch (pData->dwDataType) { case D3DHAL_SETLIGHT_ENABLE: if(!m_RefVP.m_LightArray[pData->dwIndex].IsEnabled()) pData->dwDataType = D3DHAL_SETLIGHT_DISABLE; break; case D3DHAL_SETLIGHT_DISABLE: if(m_RefVP.m_LightArray[pData->dwIndex].IsEnabled()) pData->dwDataType = D3DHAL_SETLIGHT_ENABLE; break; case D3DHAL_SETLIGHT_DATA: m_RefVP.m_LightArray[pData->dwIndex].GetLight((LPD3DLIGHT7)p); p += sizeof(D3DLIGHT7); break; } } break; } case D3DDP2OP_SETMATERIAL: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETMATERIAL pData = (LPD3DHAL_DP2SETMATERIAL)p; *pData = m_RefVP.m_Material; p += sizeof(D3DHAL_DP2SETMATERIAL); } break; } case D3DDP2OP_SETTRANSFORM: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETTRANSFORM pData = (LPD3DHAL_DP2SETTRANSFORM)p; switch(pData->xfrmType) { case D3DTRANSFORMSTATE_WORLD: pData->matrix = m_RefVP.m_xfmWorld[0]; break; case D3DTRANSFORMSTATE_WORLD1: pData->matrix = m_RefVP.m_xfmWorld[1]; break; case D3DTRANSFORMSTATE_WORLD2: pData->matrix = m_RefVP.m_xfmWorld[2]; break; case D3DTRANSFORMSTATE_WORLD3: pData->matrix = m_RefVP.m_xfmWorld[3]; break; case D3DTRANSFORMSTATE_VIEW: pData->matrix = m_RefVP.m_xfmView; break; case D3DTRANSFORMSTATE_PROJECTION: pData->matrix = m_RefVP.m_xfmProj; break; case D3DTRANSFORMSTATE_TEXTURE0: case D3DTRANSFORMSTATE_TEXTURE1: case D3DTRANSFORMSTATE_TEXTURE2: case D3DTRANSFORMSTATE_TEXTURE3: case D3DTRANSFORMSTATE_TEXTURE4: case D3DTRANSFORMSTATE_TEXTURE5: case D3DTRANSFORMSTATE_TEXTURE6: case D3DTRANSFORMSTATE_TEXTURE7: pData->matrix = m_RefVP.m_xfmTex[pData->xfrmType - D3DTRANSFORMSTATE_TEXTURE0]; break; default: if( ((DWORD)pData->xfrmType >= RD_WORLDMATRIXBASE) && ((DWORD)pData->xfrmType < (RD_WORLDMATRIXBASE + RD_MAX_WORLD_MATRICES)) ) { pData->matrix = m_RefVP.m_xfmWorld[ (DWORD)pData->xfrmType - RD_WORLDMATRIXBASE]; } else { DPFERR( "Ignoring unknown transform type" ); return D3DERR_INVALIDCALL; } break; } p += sizeof(D3DHAL_DP2SETTRANSFORM); } break; } case D3DDP2OP_TEXTURESTAGESTATE: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p; pData->dwValue = m_TextureStageState[pData->wStage].m_dwVal[pData->TSState]; p += sizeof(D3DHAL_DP2TEXTURESTAGESTATE); } break; } case D3DDP2OP_VIEWPORTINFO: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { D3DVIEWPORT7 viewport; LPD3DHAL_DP2VIEWPORTINFO lpVwpData = (LPD3DHAL_DP2VIEWPORTINFO)p; D3DVIEWPORT7& vp = m_Clipper.m_Viewport;
lpVwpData->dwX = vp.dwX; lpVwpData->dwY = vp.dwY; lpVwpData->dwWidth = vp.dwWidth; lpVwpData->dwHeight = vp.dwHeight; p += sizeof(D3DHAL_DP2VIEWPORTINFO); } break; } case D3DDP2OP_ZRANGE: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2ZRANGE pData = (LPD3DHAL_DP2ZRANGE)p; D3DVIEWPORT7& vp = m_Clipper.m_Viewport; pData->dvMinZ = vp.dvMinZ; pData->dvMaxZ = vp.dvMaxZ; p += sizeof(D3DHAL_DP2ZRANGE); } break; } case D3DDP2OP_SETCLIPPLANE: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETCLIPPLANE pData = (LPD3DHAL_DP2SETCLIPPLANE)p; *((RDVECTOR4 *)pData->plane) = m_Clipper.m_userClipPlanes[pData->dwIndex]; p += sizeof(D3DHAL_DP2SETCLIPPLANE); } break; } case D3DDP2OP_SETVERTEXSHADER: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2VERTEXSHADER pData = (LPD3DHAL_DP2VERTEXSHADER)p; pData->dwHandle = m_CurrentVShaderHandle; p += sizeof(D3DHAL_DP2VERTEXSHADER); } break; } case D3DDP2OP_SETVERTEXSHADERCONST: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETVERTEXSHADERCONST pData = (LPD3DHAL_DP2SETVERTEXSHADERCONST)p; m_RefVM.GetData( D3DSPR_CONST, pData->dwRegister, pData->dwCount, (LPVOID)(pData+1) ); p += (sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + (pData->dwCount<<4)); } break; } case D3DDP2OP_SETSTREAMSOURCE: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETSTREAMSOURCE pData = (LPD3DHAL_DP2SETSTREAMSOURCE)p; pData->dwVBHandle = m_VStream[pData->dwStream].m_dwHandle; pData->dwStride = m_VStream[pData->dwStream].m_dwStride; p += sizeof(D3DHAL_DP2SETSTREAMSOURCE); } break; } case D3DDP2OP_SETINDICES: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETINDICES pData = (LPD3DHAL_DP2SETINDICES)p; pData->dwVBHandle = m_IndexStream.m_dwHandle; pData->dwStride = m_IndexStream.m_dwStride; p += sizeof(D3DHAL_DP2SETINDICES); } break; } case D3DDP2OP_SETPIXELSHADER: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2PIXELSHADER pData = (LPD3DHAL_DP2PIXELSHADER)p; pData->dwHandle = m_CurrentPShaderHandle; p += sizeof(D3DHAL_DP2PIXELSHADER); } break; } case D3DDP2OP_SETPIXELSHADERCONST: { for(DWORD i = 0; i < (DWORD)pCmd->wStateCount; ++i) { LPD3DHAL_DP2SETPIXELSHADERCONST pData = (LPD3DHAL_DP2SETPIXELSHADERCONST)p; FLOAT* pfData = (FLOAT*)(pData+1); for (UINT iR=pData->dwRegister; iR<pData->dwCount; iR++) { *(pfData+0) = m_Rast.m_ConstReg[iR][0][0]; *(pfData+1) = m_Rast.m_ConstReg[iR][0][1]; *(pfData+2) = m_Rast.m_ConstReg[iR][0][2]; *(pfData+3) = m_Rast.m_ConstReg[iR][0][3]; pfData += 4; } p += (sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + (pData->dwCount<<4)); } break; } default: _ASSERT(FALSE, "Ununderstood DP2 command in Capture"); } }
return D3D_OK; }
HRESULT RefDev::CreateStateSet(DWORD dwHandle, D3DSTATEBLOCKTYPE sbType) { HRESULT hr = S_OK;
// This DDI should be called only for drivers > DX7
// and only for those which support TLHals.
// It is called only when the device created is a pure-device
// We need to add filtering code in DX9 to make the DDI emulation
// work.
_ASSERT( m_dwDDIType > RDDDI_DX8HAL, "This DDI should be called only" " for DX8TL\n" );
// Begin a new stateset
if( FAILED( hr = BeginStateSet( dwHandle ) ) ) { DPFERR( "CreateStateSet: Begin failed\n" ); return hr; }
switch( sbType ) { case D3DSBT_VERTEXSTATE: hr = RecordVertexState( dwHandle ); if( FAILED( hr ) ) { DPFERR( "RecordVertexState failed\n" ); } break; case D3DSBT_PIXELSTATE: hr = RecordPixelState( dwHandle ); if( FAILED( hr ) ) { DPFERR( "RecordPixelState failed\n" ); } break; case D3DSBT_ALL: hr = RecordAllState( dwHandle ); if( FAILED( hr ) ) { DPFERR( "RecordAllState failed\n" ); } break; default: DPFERR( "Unknown StateBlock type for Creation\n" ); hr = D3DERR_INVALIDCALL; }
EndStateSet(); return hr; }
HRESULT RefDev::RecordAllState( DWORD dwHandle ) { DWORD data_size = 0; DWORD i = 0; DWORD j = 0; GArrayT<BYTE> data; LPD3DHAL_DP2COMMAND pCmd = NULL; HRESULT hr = S_OK; static D3DRENDERSTATETYPE rstates[] = { 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_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_NORMALIZENORMALS, D3DRENDERSTATE_LOCALVIEWER, D3DRENDERSTATE_EMISSIVEMATERIALSOURCE, D3DRENDERSTATE_AMBIENTMATERIALSOURCE, D3DRENDERSTATE_DIFFUSEMATERIALSOURCE, D3DRENDERSTATE_SPECULARMATERIALSOURCE, D3DRENDERSTATE_VERTEXBLEND, D3DRENDERSTATE_CLIPPLANEENABLE, D3DRS_SOFTWAREVERTEXPROCESSING, D3DRS_POINTSIZE, D3DRS_POINTSIZE_MIN, D3DRS_POINTSPRITEENABLE, D3DRS_POINTSCALEENABLE, D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, D3DRS_POINTSCALE_C, D3DRS_MULTISAMPLEANTIALIAS, D3DRS_MULTISAMPLEMASK, D3DRS_PATCHEDGESTYLE, D3DRS_PATCHSEGMENTS, D3DRS_POINTSIZE_MAX, D3DRS_INDEXEDVERTEXBLENDENABLE, D3DRS_COLORWRITEENABLE, D3DRS_TWEENFACTOR, D3DRS_BLENDOP, }; static D3DTEXTURESTAGESTATETYPE tsstates[] = { D3DTSS_COLOROP, D3DTSS_COLORARG1, D3DTSS_COLORARG2, D3DTSS_ALPHAOP, D3DTSS_ALPHAARG1, D3DTSS_ALPHAARG2, D3DTSS_BUMPENVMAT00, D3DTSS_BUMPENVMAT01, D3DTSS_BUMPENVMAT10, D3DTSS_BUMPENVMAT11, D3DTSS_TEXCOORDINDEX, D3DTSS_ADDRESSU, D3DTSS_ADDRESSV, D3DTSS_BORDERCOLOR, D3DTSS_MAGFILTER, D3DTSS_MINFILTER, D3DTSS_MIPFILTER, D3DTSS_MIPMAPLODBIAS, D3DTSS_MAXMIPLEVEL, D3DTSS_MAXANISOTROPY, D3DTSS_BUMPENVLSCALE, D3DTSS_BUMPENVLOFFSET, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTSS_ADDRESSW, D3DTSS_COLORARG0, D3DTSS_ALPHAARG0, D3DTSS_RESULTARG, };
//
// !!! Dont Capture vertex streams !!!
// !!! Dont Capture index streams !!!
// !!! Dont Capture textures !!!
//
//
// Capture render-states
//
const UINT16 uiRStates = sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2RENDERSTATE) * uiRStates; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = uiRStates; pCmd->bCommand = D3DDP2OP_RENDERSTATE; D3DHAL_DP2RENDERSTATE* pRS = (D3DHAL_DP2RENDERSTATE*)(pCmd + 1); for( i = 0; i < uiRStates; ++i) { pRS->RenderState = rstates[i]; pRS->dwState = GetRS()[rstates[i]]; pRS++; } HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture texture-stage-states
//
const UINT16 uiTSStates = sizeof(tsstates)/sizeof(D3DTEXTURESTAGESTATETYPE); data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2TEXTURESTAGESTATE) * uiTSStates * D3DHAL_TSS_MAXSTAGES; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = uiTSStates * D3DHAL_TSS_MAXSTAGES; pCmd->bCommand = D3DDP2OP_TEXTURESTAGESTATE; D3DHAL_DP2TEXTURESTAGESTATE* pTSS = (D3DHAL_DP2TEXTURESTAGESTATE*)(pCmd+1); for ( i = 0; i < D3DHAL_TSS_MAXSTAGES; i++ ) { for( DWORD j = 0; j < uiTSStates; ++j) { pTSS->wStage = i; pTSS->TSState = tsstates[j]; pTSS->dwValue = GetTSS( i )[tsstates[j]]; pTSS++; } } HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture viewport
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2VIEWPORTINFO); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_VIEWPORTINFO; D3DHAL_DP2VIEWPORTINFO* pVP = (D3DHAL_DP2VIEWPORTINFO*)(pCmd+1); pVP->dwX = m_Clipper.m_Viewport.dwX; pVP->dwY = m_Clipper.m_Viewport.dwY; pVP->dwWidth = m_Clipper.m_Viewport.dwWidth; pVP->dwHeight = m_Clipper.m_Viewport.dwHeight; HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2ZRANGE); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_ZRANGE; D3DHAL_DP2ZRANGE* pZR = (D3DHAL_DP2ZRANGE*)(pCmd+1); D3DVIEWPORT7& vp = m_Clipper.m_Viewport; pZR->dvMinZ = m_Clipper.m_Viewport.dvMinZ; pZR->dvMaxZ = m_Clipper.m_Viewport.dvMaxZ; HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture transforms
//
// All the world-matrices, view, projection and the texture matrices
// (one per stage)
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETTRANSFORM) * (RD_MAX_WORLD_MATRICES + D3DHAL_TSS_MAXSTAGES + 2); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = RD_MAX_WORLD_MATRICES + D3DHAL_TSS_MAXSTAGES + 2; pCmd->bCommand = D3DDP2OP_SETTRANSFORM; D3DHAL_DP2SETTRANSFORM* pST = (D3DHAL_DP2SETTRANSFORM*)(pCmd+1); for( i = 0; i < RD_MAX_WORLD_MATRICES; i++ ) { pST->xfrmType = (D3DTRANSFORMSTATETYPE)(RD_WORLDMATRIXBASE + i); pST->matrix = m_RefVP.m_xfmWorld[i]; pST++; } // View Matrix
pST->xfrmType = D3DTRANSFORMSTATE_VIEW; pST->matrix = m_RefVP.m_xfmView; pST++; // Projection Matrix
pST->xfrmType = D3DTRANSFORMSTATE_PROJECTION; pST->matrix = m_RefVP.m_xfmProj; pST++; // Texture Matrices
for( i = 0; i < D3DHAL_TSS_MAXSTAGES; i++ ) { pST->xfrmType = (D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0 + i); pST->matrix = m_RefVP.m_xfmTex[i]; pST++; } HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture clip-planes
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETCLIPPLANE) * RD_MAX_USER_CLIPPLANES; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = RD_MAX_USER_CLIPPLANES; pCmd->bCommand = D3DDP2OP_SETCLIPPLANE; D3DHAL_DP2SETCLIPPLANE* pSCP = (D3DHAL_DP2SETCLIPPLANE*)(pCmd+1); for( i = 0; i < RD_MAX_USER_CLIPPLANES; i++ ) { pSCP->dwIndex = i; for( j=0; j<4; j++ ) pSCP->plane[j] = m_Clipper.m_userClipPlanes[i].v[j]; pSCP++; } HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture material
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETMATERIAL); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETMATERIAL; D3DHAL_DP2SETMATERIAL* pSM = (D3DHAL_DP2SETMATERIAL*)(pCmd+1); *pSM = m_RefVP.m_Material; HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture lights
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DLIGHT7) + sizeof(D3DHAL_DP2SETLIGHT)*2; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 2; pCmd->bCommand = D3DDP2OP_SETLIGHT; D3DHAL_DP2SETLIGHT* pSL = (D3DHAL_DP2SETLIGHT *)(pCmd + 1); D3DHAL_DP2SETLIGHT* pSL2 = pSL + 1; pSL2->dwDataType = D3DHAL_SETLIGHT_DATA; for( i = 0; i < m_RefVP.m_LightArray.GetSize(); i++ ) { if( m_RefVP.m_LightArray[i].IsRefered() ) { pSL2->dwIndex = pSL->dwIndex = i; if( m_RefVP.m_LightArray[i].IsEnabled() ) { pSL->dwDataType = D3DHAL_SETLIGHT_ENABLE; } else { pSL->dwDataType = D3DHAL_SETLIGHT_DISABLE; }
m_RefVP.m_LightArray[i].GetLight((D3DLIGHT7*)(pSL2 + 1)); HR_RET(RecordStates( (PUINT8)pCmd, data_size )); } }
//
// Capture current vertex shader
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2VERTEXSHADER); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETVERTEXSHADER; D3DHAL_DP2VERTEXSHADER* pVS = (D3DHAL_DP2VERTEXSHADER*)(pCmd+1); pVS->dwHandle = m_CurrentVShaderHandle; HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture current pixel shader
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2PIXELSHADER); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETPIXELSHADER; D3DHAL_DP2PIXELSHADER* pPS = (D3DHAL_DP2PIXELSHADER*)(pCmd+1); pPS->dwHandle = m_CurrentPShaderHandle; HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture vertex shader constants
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + (RD_MAX_NUMCONSTREG << 4); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETVERTEXSHADERCONST; D3DHAL_DP2SETVERTEXSHADERCONST* pVSC = (D3DHAL_DP2SETVERTEXSHADERCONST*)(pCmd+1); pVSC->dwRegister = 0; pVSC->dwCount = RD_MAX_NUMCONSTREG; m_RefVM.GetData( D3DSPR_CONST, pVSC->dwRegister, pVSC->dwCount, (LPVOID)(pVSC+1) ); HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture pixel shader constants
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + (RDPS_MAX_NUMCONSTREG << 4); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETPIXELSHADERCONST; D3DHAL_DP2SETPIXELSHADERCONST* pPSC = (D3DHAL_DP2SETPIXELSHADERCONST*)(pCmd+1); pPSC->dwRegister = 0; pPSC->dwCount = RDPS_MAX_NUMCONSTREG; FLOAT* pfData = (FLOAT*)(pPSC+1); for (UINT iR=pPSC->dwRegister; iR<pPSC->dwCount; iR++) { *(pfData+0) = m_Rast.m_ConstReg[iR][0][0]; *(pfData+1) = m_Rast.m_ConstReg[iR][0][1]; *(pfData+2) = m_Rast.m_ConstReg[iR][0][2]; *(pfData+3) = m_Rast.m_ConstReg[iR][0][3]; pfData += 4; } HR_RET(RecordStates( (PUINT8)pCmd, data_size )); return hr; }
HRESULT RefDev::RecordVertexState( DWORD dwHandle ) { DWORD data_size = 0; DWORD i = 0; DWORD j = 0; GArrayT<BYTE> data; LPD3DHAL_DP2COMMAND pCmd = NULL; HRESULT hr = S_OK; static D3DRENDERSTATETYPE rstates[] = { 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_NORMALIZENORMALS, D3DRENDERSTATE_LOCALVIEWER, D3DRENDERSTATE_EMISSIVEMATERIALSOURCE, D3DRENDERSTATE_AMBIENTMATERIALSOURCE, D3DRENDERSTATE_DIFFUSEMATERIALSOURCE, D3DRENDERSTATE_SPECULARMATERIALSOURCE, D3DRENDERSTATE_VERTEXBLEND, D3DRENDERSTATE_CLIPPLANEENABLE, D3DRS_SOFTWAREVERTEXPROCESSING, D3DRS_POINTSIZE, D3DRS_POINTSIZE_MIN, D3DRS_POINTSPRITEENABLE, D3DRS_POINTSCALEENABLE, D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, D3DRS_POINTSCALE_C, D3DRS_MULTISAMPLEANTIALIAS, D3DRS_MULTISAMPLEMASK, D3DRS_PATCHEDGESTYLE, D3DRS_PATCHSEGMENTS, D3DRS_POINTSIZE_MAX, D3DRS_INDEXEDVERTEXBLENDENABLE, D3DRS_TWEENFACTOR, }; static D3DTEXTURESTAGESTATETYPE tsstates[] = { D3DTSS_TEXCOORDINDEX, D3DTSS_TEXTURETRANSFORMFLAGS };
//
// Capture render-states
//
const UINT16 uiRStates = sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2RENDERSTATE) * uiRStates; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = uiRStates; pCmd->bCommand = D3DDP2OP_RENDERSTATE; D3DHAL_DP2RENDERSTATE* pRS = (D3DHAL_DP2RENDERSTATE*)(pCmd + 1); for( i = 0; i < uiRStates; ++i) { pRS->RenderState = rstates[i]; pRS->dwState = GetRS()[rstates[i]]; pRS++; } HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture texture-stage-states
//
const UINT16 uiTSStates = sizeof(tsstates)/sizeof(D3DTEXTURESTAGESTATETYPE); data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2TEXTURESTAGESTATE) * uiTSStates * D3DHAL_TSS_MAXSTAGES; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = uiTSStates * D3DHAL_TSS_MAXSTAGES; pCmd->bCommand = D3DDP2OP_TEXTURESTAGESTATE; D3DHAL_DP2TEXTURESTAGESTATE* pTSS = (D3DHAL_DP2TEXTURESTAGESTATE*)(pCmd+1); for ( i = 0; i < D3DHAL_TSS_MAXSTAGES; i++ ) { for( DWORD j = 0; j < uiTSStates; ++j) { pTSS->wStage = i; pTSS->TSState = tsstates[j]; pTSS->dwValue = GetTSS( i )[tsstates[j]]; pTSS++; } } HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture lights
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DLIGHT7) + sizeof(D3DHAL_DP2SETLIGHT)*2; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 2; pCmd->bCommand = D3DDP2OP_SETLIGHT; D3DHAL_DP2SETLIGHT* pSL = (D3DHAL_DP2SETLIGHT *)(pCmd + 1); D3DHAL_DP2SETLIGHT* pSL2 = pSL + 1; pSL2->dwDataType = D3DHAL_SETLIGHT_DATA; for( i = 0; i < m_RefVP.m_LightArray.GetSize(); i++ ) { if( m_RefVP.m_LightArray[i].IsRefered() ) { pSL2->dwIndex = pSL->dwIndex = i; if( m_RefVP.m_LightArray[i].IsEnabled() ) { pSL->dwDataType = D3DHAL_SETLIGHT_ENABLE; } else { pSL->dwDataType = D3DHAL_SETLIGHT_DISABLE; }
m_RefVP.m_LightArray[i].GetLight((D3DLIGHT7*)(pSL2 + 1)); HR_RET(RecordStates( (PUINT8)pCmd, data_size )); } }
//
// Capture vertex shader constants
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + (RD_MAX_NUMCONSTREG << 4); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETVERTEXSHADERCONST; D3DHAL_DP2SETVERTEXSHADERCONST* pVSC = (D3DHAL_DP2SETVERTEXSHADERCONST*)(pCmd+1); pVSC->dwRegister = 0; pVSC->dwCount = RD_MAX_NUMCONSTREG; m_RefVM.GetData( D3DSPR_CONST, pVSC->dwRegister, pVSC->dwCount, (LPVOID)(pVSC+1) ); HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture current vertex shader
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2VERTEXSHADER); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETVERTEXSHADER; D3DHAL_DP2VERTEXSHADER* pVS = (D3DHAL_DP2VERTEXSHADER*)(pCmd+1); pVS->dwHandle = m_CurrentVShaderHandle; HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
return hr; }
HRESULT RefDev::RecordPixelState( DWORD dwHandle ) { DWORD data_size = 0; DWORD i = 0; DWORD j = 0; GArrayT<BYTE> data; LPD3DHAL_DP2COMMAND pCmd = NULL; HRESULT hr = S_OK;
static D3DRENDERSTATETYPE rstates[] = { 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_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, D3DRS_COLORWRITEENABLE, D3DRS_BLENDOP, }; static D3DTEXTURESTAGESTATETYPE tsstates[] = { D3DTSS_COLOROP, D3DTSS_COLORARG1, D3DTSS_COLORARG2, D3DTSS_ALPHAOP, D3DTSS_ALPHAARG1, D3DTSS_ALPHAARG2, D3DTSS_BUMPENVMAT00, D3DTSS_BUMPENVMAT01, D3DTSS_BUMPENVMAT10, D3DTSS_BUMPENVMAT11, D3DTSS_TEXCOORDINDEX, D3DTSS_ADDRESSU, D3DTSS_ADDRESSV, D3DTSS_BORDERCOLOR, D3DTSS_MAGFILTER, D3DTSS_MINFILTER, D3DTSS_MIPFILTER, D3DTSS_MIPMAPLODBIAS, D3DTSS_MAXMIPLEVEL, D3DTSS_MAXANISOTROPY, D3DTSS_BUMPENVLSCALE, D3DTSS_BUMPENVLOFFSET, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTSS_ADDRESSW, D3DTSS_COLORARG0, D3DTSS_ALPHAARG0, D3DTSS_RESULTARG, };
//
// Capture render-states
//
const UINT16 uiRStates = sizeof(rstates)/sizeof(D3DRENDERSTATETYPE); data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2RENDERSTATE) * uiRStates; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = uiRStates; pCmd->bCommand = D3DDP2OP_RENDERSTATE; D3DHAL_DP2RENDERSTATE* pRS = (D3DHAL_DP2RENDERSTATE*)(pCmd + 1); for( i = 0; i < uiRStates; ++i) { pRS->RenderState = rstates[i]; pRS->dwState = GetRS()[rstates[i]]; pRS++; } HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture texture-stage-states
//
const UINT16 uiTSStates = sizeof(tsstates)/sizeof(D3DTEXTURESTAGESTATETYPE); data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2TEXTURESTAGESTATE) * uiTSStates * D3DHAL_TSS_MAXSTAGES; HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = uiTSStates * D3DHAL_TSS_MAXSTAGES; pCmd->bCommand = D3DDP2OP_TEXTURESTAGESTATE; D3DHAL_DP2TEXTURESTAGESTATE* pTSS = (D3DHAL_DP2TEXTURESTAGESTATE*)(pCmd+1); for ( i = 0; i < D3DHAL_TSS_MAXSTAGES; i++ ) { for( DWORD j = 0; j < uiTSStates; ++j) { pTSS->wStage = i; pTSS->TSState = tsstates[j]; pTSS->dwValue = GetTSS( i )[tsstates[j]]; pTSS++; } } HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture pixel shader constants
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + (RDPS_MAX_NUMCONSTREG << 4); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETPIXELSHADERCONST; D3DHAL_DP2SETPIXELSHADERCONST* pPSC = (D3DHAL_DP2SETPIXELSHADERCONST*)(pCmd+1); pPSC->dwRegister = 0; pPSC->dwCount = RDPS_MAX_NUMCONSTREG; FLOAT* pfData = (FLOAT*)(pPSC+1); for (UINT iR=pPSC->dwRegister; iR<pPSC->dwCount; iR++) { *(pfData+0) = m_Rast.m_ConstReg[iR][0][0]; *(pfData+1) = m_Rast.m_ConstReg[iR][0][1]; *(pfData+2) = m_Rast.m_ConstReg[iR][0][2]; *(pfData+3) = m_Rast.m_ConstReg[iR][0][3]; pfData += 4; } HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
//
// Capture current pixel shader
//
data_size = sizeof(D3DHAL_DP2COMMAND) + sizeof(D3DHAL_DP2PIXELSHADER); HR_RET(data.Grow( data_size )); pCmd = (LPD3DHAL_DP2COMMAND)&(data[0]); pCmd->wPrimitiveCount = 1; pCmd->bCommand = D3DDP2OP_SETPIXELSHADER; D3DHAL_DP2PIXELSHADER* pPS = (D3DHAL_DP2PIXELSHADER*)(pCmd+1); pPS->dwHandle = m_CurrentPShaderHandle; HR_RET(RecordStates( (PUINT8)pCmd, data_size ));
return hr; }
//-----------------------------------------------------------------------------
//
// SetRenderState -
//
//-----------------------------------------------------------------------------
void RefDev::SetRenderState( DWORD dwState, DWORD dwValue ) { // check for range before continuing
if( dwState >= D3DHAL_MAX_RSTATES ) { return; }
// set value in internal object
m_dwRenderState[dwState] = dwValue;
// do special validation work for some render states
switch ( dwState ) {
case D3DRENDERSTATE_ZENABLE: if( dwValue ) m_Clipper.m_dwFlags |= RefClipper::RCLIP_Z_ENABLE; else m_Clipper.m_dwFlags &= ~RefClipper::RCLIP_Z_ENABLE; break; case D3DRENDERSTATE_LIGHTING: if( dwValue ) m_RefVP.m_dwTLState |= RDPV_DOLIGHTING; else m_RefVP.m_dwTLState &= ~RDPV_DOLIGHTING; break; case D3DRS_INDEXEDVERTEXBLENDENABLE: if( dwValue ) m_RefVP.m_dwTLState |= RDPV_DOINDEXEDVERTEXBLEND; else m_RefVP.m_dwTLState &= ~RDPV_DOINDEXEDVERTEXBLEND; break; case D3DRENDERSTATE_CLIPPING: if( dwValue ) m_RefVP.m_dwTLState |= RDPV_DOCLIPPING; else m_RefVP.m_dwTLState &= ~RDPV_DOCLIPPING; break; case D3DRENDERSTATE_SHADEMODE: { if( dwValue == D3DSHADE_FLAT ) m_Clipper.m_dwFlags |= RefClipper::RCLIP_DO_FLATSHADING; else m_Clipper.m_dwFlags &= ~RefClipper::RCLIP_DO_FLATSHADING; } break; case D3DRENDERSTATE_FILLMODE: { if( dwValue == D3DFILL_WIREFRAME ) m_Clipper.m_dwFlags |= RefClipper::RCLIP_DO_WIREFRAME; else m_Clipper.m_dwFlags &= ~RefClipper::RCLIP_DO_WIREFRAME; } break; case D3DRENDERSTATE_NORMALIZENORMALS: { if( dwValue ) m_RefVP.m_dwTLState |= RDPV_NORMALIZENORMALS; else m_RefVP.m_dwTLState &= ~RDPV_NORMALIZENORMALS; } break; case D3DRENDERSTATE_LOCALVIEWER: { if( dwValue ) m_RefVP.m_dwTLState |= RDPV_LOCALVIEWER; else m_RefVP.m_dwTLState &= ~RDPV_LOCALVIEWER; } break; case D3DRENDERSTATE_SPECULARENABLE: { if( dwValue ) m_RefVP.m_dwTLState |= RDPV_DOSPECULAR; else m_RefVP.m_dwTLState &= ~RDPV_DOSPECULAR; } break; case D3DRENDERSTATE_COLORVERTEX: case D3DRENDERSTATE_AMBIENTMATERIALSOURCE: case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE: case D3DRENDERSTATE_SPECULARMATERIALSOURCE: case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE: m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_COLORVTX; break; case D3DRENDERSTATE_FOGCOLOR: { m_RefVP.m_lighting.fog_color = (D3DCOLOR) dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_FOG; } break; case D3DRENDERSTATE_FOGTABLESTART: { m_RefVP.m_lighting.fog_start = *(D3DVALUE*)&dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_FOG; } break; case D3DRENDERSTATE_FOGTABLEEND: { m_RefVP.m_lighting.fog_end = *(D3DVALUE*)&dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_FOG; } break; case D3DRENDERSTATE_FOGTABLEDENSITY: { m_RefVP.m_lighting.fog_density = *(D3DVALUE*)&dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_FOG; } break; case D3DRENDERSTATE_FOGVERTEXMODE: { m_RefVP.m_lighting.fog_mode = (int) dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_FOG; } break; case D3DRENDERSTATE_AMBIENT: { m_RefVP.m_lighting.ambient_red = D3DVAL(RGBA_GETRED(dwValue))/D3DVALUE(255); m_RefVP.m_lighting.ambient_green = D3DVAL(RGBA_GETGREEN(dwValue))/D3DVALUE(255); m_RefVP.m_lighting.ambient_blue = D3DVAL(RGBA_GETBLUE(dwValue))/D3DVALUE(255); m_RefVP.m_lighting.ambient_save = dwValue; m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_MATERIAL; } break; //
// map legacy texture to multi-texture stage 0
//
case D3DRENDERSTATE_TEXTUREMAPBLEND: // map legacy blending state to texture stage 0
MapLegacyTextureBlend(); break;
// map legacy modes with one-to-one mappings to texture stage 0
case D3DRENDERSTATE_TEXTUREADDRESS: // not available in DX8 headers
// m_TextureStageState[0].m_dwVal[D3DTSS_ADDRESS] =
m_TextureStageState[0].m_dwVal[D3DTSS_ADDRESSU] = m_TextureStageState[0].m_dwVal[D3DTSS_ADDRESSV] = dwValue; break; case D3DRENDERSTATE_TEXTUREADDRESSU: m_TextureStageState[0].m_dwVal[D3DTSS_ADDRESSU] = dwValue; break; case D3DRENDERSTATE_TEXTUREADDRESSV: m_TextureStageState[0].m_dwVal[D3DTSS_ADDRESSV] = dwValue; break; case D3DRENDERSTATE_MIPMAPLODBIAS: m_TextureStageState[0].m_dwVal[D3DTSS_MIPMAPLODBIAS] = dwValue; break; case D3DRENDERSTATE_BORDERCOLOR: m_TextureStageState[0].m_dwVal[D3DTSS_BORDERCOLOR] = dwValue; break; case D3DRENDERSTATE_ANISOTROPY: m_TextureStageState[0].m_dwVal[D3DTSS_MAXANISOTROPY] = dwValue; // fall thru to update filter state
case D3DRENDERSTATE_TEXTUREMAG: case D3DRENDERSTATE_TEXTUREMIN: // map legacy filtering/sampling state to texture stage 0
MapLegacyTextureFilter(); break;
case D3DRENDERSTATE_TEXTUREHANDLE: // map thru to set handle for first stage
SetTextureStageState( 0, D3DTSS_TEXTUREMAP, dwValue ); break;
//
// map legacy WRAPU/V state through to controls for tex coord 0
//
case D3DRENDERSTATE_WRAPU: m_dwRenderState[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_U; m_dwRenderState[D3DRENDERSTATE_WRAP0] |= ((dwValue) ? D3DWRAP_U : 0); break; case D3DRENDERSTATE_WRAPV: m_dwRenderState[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_V; m_dwRenderState[D3DRENDERSTATE_WRAP0] |= ((dwValue) ? D3DWRAP_V : 0); break;
case D3DRS_MULTISAMPLEANTIALIAS: case D3DRS_MULTISAMPLEMASK: m_dwRastFlags |= RDRF_MULTISAMPLE_CHANGED; break;
//
// Scene Capture
//
case D3DRENDERSTATE_SCENECAPTURE: if( dwValue ) SceneCapture(D3DHAL_SCENE_CAPTURE_START); else SceneCapture(D3DHAL_SCENE_CAPTURE_END); break;
case D3DRS_POINTSIZE: m_RefVP.m_fPointSize = m_fRenderState[dwState]; break;
case D3DRS_POINTSCALE_A: m_RefVP.m_fPointAttA = m_fRenderState[dwState]; break;
case D3DRS_POINTSCALE_B: m_RefVP.m_fPointAttB = m_fRenderState[dwState]; break;
case D3DRS_POINTSCALE_C: m_RefVP.m_fPointAttC = m_fRenderState[dwState]; break;
case D3DRS_POINTSIZE_MIN: m_RefVP.m_fPointSizeMin = m_fRenderState[dwState]; break;
case D3DRS_POINTSIZE_MAX: m_RefVP.m_fPointSizeMax = min(RD_MAX_POINT_SIZE, m_fRenderState[dwState]); break;
case D3DRS_TWEENFACTOR: m_RefVP.m_fTweenFactor = m_fRenderState[dwState]; break;
//
// HOSurface DDI only renderstate
//
case D3DRS_DELETERTPATCH: if(dwValue < m_HOSCoeffs.GetSize()) { RDHOCoeffs &coeffs = m_HOSCoeffs[dwValue]; delete[] coeffs.m_pNumSegs; coeffs.m_pNumSegs = 0; for(unsigned i = 0; i < RD_MAX_NUMSTREAMS; ++i) { delete[] coeffs.m_pData[i]; coeffs.m_pData[i] = 0; } } } }
HRESULT RefDev::Dp2SetRenderTarget(LPD3DHAL_DP2COMMAND pCmd) { LPD3DHAL_DP2SETRENDERTARGET pSRTData; HRESULT hr;
// Get new data by ignoring all but the last structure
pSRTData = (D3DHAL_DP2SETRENDERTARGET*)(pCmd + 1) + (pCmd->wStateCount - 1);
// set 'changed' flags
m_dwRastFlags = RDRF_MULTISAMPLE_CHANGED| RDRF_PIXELSHADER_CHANGED| RDRF_LEGACYPIXELSHADER_CHANGED| RDRF_TEXTURESTAGESTATE_CHANGED;
return GetRenderTarget()->Initialize( m_pDDLcl, pSRTData->hRenderTarget, pSRTData->hZBuffer ); }
HRESULT RefDev::Dp2CreateVertexShader( DWORD handle, DWORD dwDeclSize, LPDWORD pDecl, DWORD dwCodeSize, LPDWORD pCode ) { HRESULT hr = S_OK;
HR_RET( m_VShaderHandleArray.Grow( handle ) );
//
// Validation sequence
//
#if DBG
_ASSERT( m_VShaderHandleArray[handle].m_tag == 0, "A shader exists with the given handle, tag is non-zero" ); #endif
_ASSERT( pDecl, "A declaration should exist" ); _ASSERT( dwDeclSize, "A declaration size should be non-zero" ); _ASSERT( m_VShaderHandleArray[handle].m_pShader == NULL, "A shader exists with the given handle" );
RDVShader* pShader = m_VShaderHandleArray[handle].m_pShader = new RDVShader;
if( pShader == NULL ) return E_OUTOFMEMORY;
//
// Parse the declaration
//
if( FAILED( hr = pShader->m_Declaration.Parse( pDecl, !(BOOL)dwCodeSize ) ) ) { DPFERR( "Vertex Shader declaration parsing failed" ); goto error_ret; }
//
// Now compile the shader code if any of it is given
//
if( dwCodeSize ) { pShader->m_pCode = m_RefVM.CompileCode( dwCodeSize, pCode ); if( pShader->m_pCode == NULL ) { DPFERR( "Vertex Shader Code compilation failed" ); hr = E_FAIL; goto error_ret; } }
#if DBG
// Everything successful, mark this handle as in use.
m_VShaderHandleArray[handle].m_tag = 1; #endif
return S_OK;
error_ret: delete pShader; m_VShaderHandleArray[handle].m_pShader = NULL; #if DBG
m_VShaderHandleArray[handle].m_tag = 0; #endif
return hr; }
HRESULT RefDev::Dp2DeleteVertexShader(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK;
LPD3DHAL_DP2VERTEXSHADER pVS = (LPD3DHAL_DP2VERTEXSHADER)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { DWORD handle = pVS[i].dwHandle;
_ASSERT( m_VShaderHandleArray.IsValidIndex( handle ), "Such a shader does not exist" );
_ASSERT( m_VShaderHandleArray[handle].m_pShader, "Such a shader does not exist" );
delete m_VShaderHandleArray[handle].m_pShader; m_VShaderHandleArray[handle].m_pShader = NULL; #if DBG
m_VShaderHandleArray[handle].m_tag = 0; #endif
if( handle == m_CurrentVShaderHandle ) { m_CurrentVShaderHandle = 0; m_pCurrentVShader = NULL; } } return hr; }
HRESULT RefDev::Dp2SetVertexShader(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK;
LPD3DHAL_DP2VERTEXSHADER pVS = (LPD3DHAL_DP2VERTEXSHADER)(pCmd + 1);
// Just set the last Vertex Shader in this array
DWORD handle = pVS[pCmd->wStateCount-1].dwHandle;
//
// Zero is a special handle that tells the driver to
// invalidate the currently set shader.
//
if( handle == 0 ) { m_pCurrentVShader = NULL; m_CurrentVShaderHandle = handle; return hr; }
if( RDVSD_ISLEGACY(handle) ) { // Make it parse the FVF and build the VertexElement array
hr = m_FVFShader.m_Declaration.MakeVElementArray( handle ); if( FAILED( hr ) ) { DPFERR( "MakeVElementArray failed" ); return hr; }
m_pCurrentVShader = &m_FVFShader; } else {
if( !m_VShaderHandleArray.IsValidIndex( handle ) || (m_VShaderHandleArray[handle].m_pShader == NULL) ) { DPFERR( "Such a Vertex Shader has not been created" ); return E_INVALIDARG; } m_pCurrentVShader = m_VShaderHandleArray[handle].m_pShader;
// Save the tesselator stride computed at parsing time.
// This feature is only available when using a Declaration.
m_VStream[RDVSD_STREAMTESS].m_dwStride = m_pCurrentVShader->m_Declaration.m_dwStreamTessStride;
}
if( m_pCurrentVShader->m_pCode ) { hr = m_RefVM.SetActiveShaderCode( m_pCurrentVShader->m_pCode ); if( FAILED( hr ) ) { DPFERR( "SetActiveShaderCode failed" ); return hr; }
RDVConstantData* pConst = m_pCurrentVShader->m_Declaration.m_pConstants; while( pConst ) { hr = m_RefVM.SetData( D3DSPR_CONST, pConst->m_dwAddress, pConst->m_dwCount, pConst->m_pData ); if( FAILED( hr ) ) { DPFERR( "SetVMData failed" ); return hr; } pConst = static_cast<RDVConstantData *>(pConst->m_pNext); } }
m_CurrentVShaderHandle = handle; if( m_pCurrentVShader->m_Declaration.m_qwInputFVF != m_RefVP.m_qwFVFIn ) { m_RefVP.m_dwDirtyFlags |= RDPV_DIRTY_COLORVTX; } m_RefVP.m_qwFVFIn = m_pCurrentVShader->m_Declaration.m_qwInputFVF;
return hr; }
HRESULT RefDev::Dp2SetVertexShaderConsts( DWORD StartReg, DWORD dwCount, LPDWORD pData ) { HRESULT hr = m_RefVM.SetData( D3DSPR_CONST, StartReg, dwCount, pData ); return hr; }
HRESULT RefDev::Dp2SetStreamSource(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK;
LPD3DHAL_DP2SETSTREAMSOURCE pSSS = (LPD3DHAL_DP2SETSTREAMSOURCE)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { RDVStream& Stream = m_VStream[pSSS[i].dwStream];
// NULL handle means that the StreamSource should be unset.
if( pSSS[i].dwVBHandle == 0 ) { Stream.m_pData = NULL; Stream.m_dwStride = 0; Stream.m_dwHandle = 0; } else {
// Check if the handle has a valid vertexbuffer
RDSurface* pSurf = g_SurfMgr.GetSurfFromList(m_pDDLcl, pSSS[i].dwVBHandle); if( (pSurf == NULL) || (pSurf->GetSurfaceType() != RR_ST_VERTEXBUFFER) ) { DPFERR( "Invalid VB Handle passed in SetStreamSource" ); return E_INVALIDARG; }
RDVertexBuffer* pVB = static_cast<RDVertexBuffer *>(pSurf); Stream.m_pData = pVB->GetBits(); Stream.m_dwStride = pSSS[i].dwStride; Stream.m_dwHandle = pSSS[i].dwVBHandle; } } return hr; }
HRESULT RefDev::Dp2SetStreamSourceUM( LPD3DHAL_DP2COMMAND pCmd, PUINT8 pUMVtx ) { HRESULT hr = S_OK; // Get new data by ignoring all but the last structure
D3DHAL_DP2SETSTREAMSOURCEUM* pSSUM = (D3DHAL_DP2SETSTREAMSOURCEUM*)(pCmd + 1) + (pCmd->wStateCount - 1);
// Access only the Zero'th stream
m_VStream[pSSUM->dwStream].m_pData = pUMVtx; m_VStream[pSSUM->dwStream].m_dwStride = pSSUM->dwStride; m_VStream[pSSUM->dwStream].m_dwHandle = 0;
return hr; }
HRESULT RefDev::Dp2SetIndices(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; // Get new data by ignoring all but the last structure
D3DHAL_DP2SETINDICES* pSI = (D3DHAL_DP2SETINDICES*)(pCmd + 1) + (pCmd->wStateCount - 1);
// NULL handle means that the StreamSource should be unset.
if( pSI->dwVBHandle == 0 ) { m_IndexStream.m_pData = NULL; m_IndexStream.m_dwStride = 0; m_IndexStream.m_dwHandle = 0; } else { // Check if the handle has a valid vertexbuffer
RDSurface* pSurf = g_SurfMgr.GetSurfFromList(m_pDDLcl, pSI->dwVBHandle); if( (pSurf == NULL) || (pSurf->GetSurfaceType() != RR_ST_VERTEXBUFFER) ) { DPFERR( "Invalid VB Handle passed in SetIndices" ); return E_INVALIDARG; } RDVertexBuffer* pVB = static_cast<RDVertexBuffer *>(pSurf); m_IndexStream.m_pData = pVB->GetBits(); m_IndexStream.m_dwStride = pSI->dwStride; m_IndexStream.m_dwHandle = pSI->dwVBHandle; }
return hr; }
HRESULT RefDev::Dp2DrawPrimitive(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK;
//
// Validation
//
_ASSERT( m_CurrentVShaderHandle, "No vertex shader currently bound" );
LPD3DHAL_DP2DRAWPRIMITIVE pDP = (LPD3DHAL_DP2DRAWPRIMITIVE)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { if( FAILED( hr = DrawDX8Prim( &(pDP[i]) ) ) ) return hr; } return hr; }
HRESULT RefDev::Dp2DrawPrimitive2(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK;
//
// Validation
//
_ASSERT( m_CurrentVShaderHandle, "No vertex shader currently bound" );
LPD3DHAL_DP2DRAWPRIMITIVE2 pDP = (LPD3DHAL_DP2DRAWPRIMITIVE2)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { if( FAILED( hr = DrawDX8Prim2( &(pDP[i]) ) ) ) return hr; } return hr; }
HRESULT RefDev::Dp2DrawIndexedPrimitive(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; //
// Validation
//
_ASSERT( m_CurrentVShaderHandle, "No vertex shader currently bound" );
LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE pDIP = (LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { if( FAILED( hr = DrawDX8IndexedPrim( &(pDIP[i]) ) ) ) return hr; } return hr; }
HRESULT RefDev::Dp2DrawIndexedPrimitive2(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; //
// Validation
//
_ASSERT( m_CurrentVShaderHandle, "No vertex shader currently bound" );
LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE2 pDIP = (LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE2)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { if( FAILED( hr = DrawDX8IndexedPrim2( &(pDIP[i]) ) ) ) return hr; } return hr; }
HRESULT RefDev::Dp2DrawClippedTriFan(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; //
// Validation
//
_ASSERT( m_CurrentVShaderHandle, "No vertex shader currently bound" );
LPD3DHAL_CLIPPEDTRIANGLEFAN pDIP = (LPD3DHAL_CLIPPEDTRIANGLEFAN)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { if( FAILED( hr = DrawDX8ClippedTriFan( &(pDIP[i]) ) ) ) return hr; } return hr; }
HRESULT RefDev::Dp2SetPalette(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; LPD3DHAL_DP2SETPALETTE pSP = (LPD3DHAL_DP2SETPALETTE)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { HR_RET( m_PaletteHandleArray.Grow( pSP->dwPaletteHandle ) ); if( m_PaletteHandleArray[pSP->dwPaletteHandle].m_pPal == NULL ) { m_PaletteHandleArray[pSP->dwPaletteHandle].m_pPal = new RDPalette; } RDPalette* pPal = m_PaletteHandleArray[pSP->dwPaletteHandle].m_pPal; pPal->m_dwFlags = (pSP->dwPaletteFlags & DDRAWIPAL_ALPHA) ? RDPalette::RDPAL_ALPHAINPALETTE : 0; RDSurface2D* pSurf = (RDSurface2D *)g_SurfMgr.GetSurfFromList( m_pDDLcl, pSP->dwSurfaceHandle ); if( pSurf == NULL ) return E_FAIL; if( (pSurf->GetSurfaceType() & RR_ST_TEXTURE) == 0 ) { DPFERR( "Setting palette to a non-texture\n" ); return E_FAIL; } pSurf->SetPalette( pPal ); } return hr; }
HRESULT RefDev::Dp2UpdatePalette(LPD3DHAL_DP2UPDATEPALETTE pUP, PALETTEENTRY* pPalData) { HRESULT hr = S_OK; HR_RET( m_PaletteHandleArray.Grow( pUP->dwPaletteHandle ) ); if( m_PaletteHandleArray[pUP->dwPaletteHandle].m_pPal == NULL ) { m_PaletteHandleArray[pUP->dwPaletteHandle].m_pPal = new RDPalette; } RDPalette* pPal = m_PaletteHandleArray[pUP->dwPaletteHandle].m_pPal; HR_RET( pPal->Update( pUP->wStartIndex, pUP->wNumEntries, pPalData ) ); return hr; }
HRESULT RefDev::Dp2SetTexLod(LPD3DHAL_DP2COMMAND pCmd) { HRESULT hr = S_OK; LPD3DHAL_DP2SETTEXLOD pSTL = (LPD3DHAL_DP2SETTEXLOD)(pCmd + 1); for( int i = 0; i < pCmd->wStateCount; i++ ) { RDSurface2D* pSurf = (RDSurface2D *)g_SurfMgr.GetSurfFromList( m_pDDLcl, pSTL->dwDDSurface ); if( pSurf == NULL ) return E_FAIL; if( (pSurf->GetSurfaceType() & RR_ST_TEXTURE) == 0 ) { DPFERR( "Setting LOD to a non-texture\n" ); return E_FAIL; } HR_RET(pSurf->SetLod( pSTL->dwLOD )); } return hr; }
|