+++ /dev/null
-//////////////////////////////////////////////////////////////////////////////\r
-//\r
-// Copyright (C) Microsoft Corporation. All Rights Reserved.\r
-//\r
-// File: EffectRuntime.cpp\r
-// Content: D3DX11 Effect runtime routines (performance critical)\r
-// These functions are expected to be called at high frequency\r
-// (when applying a pass).\r
-//\r
-//////////////////////////////////////////////////////////////////////////////\r
-\r
-#include "pchfx.h"\r
-\r
-namespace D3DX11Effects\r
-{\r
- // D3D11_KEEP_UNORDERED_ACCESS_VIEWS == (UINT)-1\r
- UINT g_pNegativeOnes[8] = { D3D11_KEEP_UNORDERED_ACCESS_VIEWS, D3D11_KEEP_UNORDERED_ACCESS_VIEWS, D3D11_KEEP_UNORDERED_ACCESS_VIEWS,\r
- D3D11_KEEP_UNORDERED_ACCESS_VIEWS, D3D11_KEEP_UNORDERED_ACCESS_VIEWS, D3D11_KEEP_UNORDERED_ACCESS_VIEWS,\r
- D3D11_KEEP_UNORDERED_ACCESS_VIEWS, D3D11_KEEP_UNORDERED_ACCESS_VIEWS };\r
-\r
-BOOL SBaseBlock::ApplyAssignments(CEffect *pEffect)\r
-{\r
- SAssignment *pAssignment = pAssignments;\r
- SAssignment *pLastAssn = pAssignments + AssignmentCount;\r
- BOOL bRecreate = FALSE;\r
-\r
- for(; pAssignment < pLastAssn; pAssignment++)\r
- {\r
- bRecreate |= pEffect->EvaluateAssignment(pAssignment);\r
- }\r
-\r
- return bRecreate;\r
-}\r
-\r
-void SPassBlock::ApplyPassAssignments()\r
-{\r
- SAssignment *pAssignment = pAssignments;\r
- SAssignment *pLastAssn = pAssignments + AssignmentCount;\r
-\r
- pEffect->IncrementTimer();\r
-\r
- for(; pAssignment < pLastAssn; pAssignment++)\r
- {\r
- pEffect->EvaluateAssignment(pAssignment);\r
- }\r
-}\r
-\r
-// Returns TRUE if the shader uses global interfaces (since these interfaces can be updated through SetClassInstance)\r
-BOOL SPassBlock::CheckShaderDependencies( SShaderBlock* pBlock )\r
-{\r
- if( pBlock->InterfaceDepCount > 0 )\r
- {\r
- D3DXASSERT( pBlock->InterfaceDepCount == 1 );\r
- for( UINT i=0; i < pBlock->pInterfaceDeps[0].Count; i++ )\r
- {\r
- SInterface* pInterfaceDep = pBlock->pInterfaceDeps[0].ppFXPointers[i];\r
- if( pInterfaceDep > pEffect->m_pInterfaces && pInterfaceDep < (pEffect->m_pInterfaces + pEffect->m_InterfaceCount) )\r
- {\r
- // This is a global interface pointer (as opposed to an SInterface created in a BindInterface call\r
- return TRUE;\r
- }\r
- }\r
- }\r
- return FALSE;\r
-}\r
-\r
-// Returns TRUE if the pass (and sets HasDependencies) if the pass sets objects whose backing stores can be updated\r
-BOOL SPassBlock::CheckDependencies()\r
-{\r
- if( HasDependencies )\r
- return TRUE;\r
-\r
- for( UINT i=0; i < AssignmentCount; i++ )\r
- {\r
- if( pAssignments[i].DependencyCount > 0 )\r
- return HasDependencies = TRUE;\r
- }\r
- if( BackingStore.pBlendBlock && BackingStore.pBlendBlock->AssignmentCount > 0 )\r
- {\r
- for( UINT i=0; i < BackingStore.pBlendBlock->AssignmentCount; i++ )\r
- {\r
- if( BackingStore.pBlendBlock->pAssignments[i].DependencyCount > 0 )\r
- return HasDependencies = TRUE;\r
- }\r
- }\r
- if( BackingStore.pDepthStencilBlock && BackingStore.pDepthStencilBlock->AssignmentCount > 0 )\r
- {\r
- for( UINT i=0; i < BackingStore.pDepthStencilBlock->AssignmentCount; i++ )\r
- {\r
- if( BackingStore.pDepthStencilBlock->pAssignments[i].DependencyCount > 0 )\r
- return HasDependencies = TRUE;\r
- }\r
- }\r
- if( BackingStore.pRasterizerBlock && BackingStore.pRasterizerBlock->AssignmentCount > 0 )\r
- {\r
- for( UINT i=0; i < BackingStore.pRasterizerBlock->AssignmentCount; i++ )\r
- {\r
- if( BackingStore.pRasterizerBlock->pAssignments[i].DependencyCount > 0 )\r
- return HasDependencies = TRUE;\r
- }\r
- }\r
- if( BackingStore.pVertexShaderBlock && CheckShaderDependencies( BackingStore.pVertexShaderBlock ) )\r
- {\r
- return HasDependencies = TRUE;\r
- }\r
- if( BackingStore.pGeometryShaderBlock && CheckShaderDependencies( BackingStore.pGeometryShaderBlock ) )\r
- {\r
- return HasDependencies = TRUE;\r
- }\r
- if( BackingStore.pPixelShaderBlock && CheckShaderDependencies( BackingStore.pPixelShaderBlock ) )\r
- {\r
- return HasDependencies = TRUE;\r
- }\r
- if( BackingStore.pHullShaderBlock && CheckShaderDependencies( BackingStore.pHullShaderBlock ) )\r
- {\r
- return HasDependencies = TRUE;\r
- }\r
- if( BackingStore.pDomainShaderBlock && CheckShaderDependencies( BackingStore.pDomainShaderBlock ) )\r
- {\r
- return HasDependencies = TRUE;\r
- }\r
- if( BackingStore.pComputeShaderBlock && CheckShaderDependencies( BackingStore.pComputeShaderBlock ) )\r
- {\r
- return HasDependencies = TRUE;\r
- }\r
-\r
- return HasDependencies;\r
-}\r
-\r
-\r
-// Update constant buffer contents if necessary\r
-D3DX11INLINE void CheckAndUpdateCB_FX(ID3D11DeviceContext *pContext, SConstantBuffer *pCB)\r
-{\r
- if (pCB->IsDirty && !pCB->IsNonUpdatable)\r
- {\r
- // CB out of date; rebuild it\r
- pContext->UpdateSubresource(pCB->pD3DObject, 0, NULL, pCB->pBackingStore, pCB->Size, pCB->Size);\r
- pCB->IsDirty = FALSE;\r
- }\r
-}\r
-\r
-\r
-// Set the shader and dependent state (SRVs, samplers, UAVs, interfaces)\r
-void CEffect::ApplyShaderBlock(SShaderBlock *pBlock)\r
-{\r
- UINT i;\r
-\r
- SD3DShaderVTable *pVT = pBlock->pVT;\r
-\r
- // Apply constant buffers first (tbuffers are done later)\r
- SShaderCBDependency *pCBDep = pBlock->pCBDeps;\r
- SShaderCBDependency *pLastCBDep = pBlock->pCBDeps + pBlock->CBDepCount;\r
-\r
- for (; pCBDep<pLastCBDep; pCBDep++)\r
- {\r
- D3DXASSERT(pCBDep->ppFXPointers);\r
-\r
- for (i = 0; i < pCBDep->Count; ++ i)\r
- {\r
- CheckAndUpdateCB_FX(m_pContext, (SConstantBuffer*)pCBDep->ppFXPointers[i]);\r
- }\r
-\r
- (m_pContext->*(pVT->pSetConstantBuffers))(pCBDep->StartIndex, pCBDep->Count, pCBDep->ppD3DObjects);\r
- }\r
-\r
- // Next, apply samplers\r
- SShaderSamplerDependency *pSampDep = pBlock->pSampDeps;\r
- SShaderSamplerDependency *pLastSampDep = pBlock->pSampDeps + pBlock->SampDepCount;\r
-\r
- for (; pSampDep<pLastSampDep; pSampDep++)\r
- {\r
- D3DXASSERT(pSampDep->ppFXPointers);\r
-\r
- for (i=0; i<pSampDep->Count; i++)\r
- {\r
- if ( ApplyRenderStateBlock(pSampDep->ppFXPointers[i]) )\r
- {\r
- // If the sampler was updated, its pointer will have changed\r
- pSampDep->ppD3DObjects[i] = pSampDep->ppFXPointers[i]->pD3DObject;\r
- }\r
- }\r
- (m_pContext->*(pVT->pSetSamplers))(pSampDep->StartIndex, pSampDep->Count, pSampDep->ppD3DObjects);\r
- }\r
- \r
- // Set the UAVs\r
- // UAV ranges were combined in EffectLoad. This code remains unchanged, however, so that ranges can be easily split\r
- D3DXASSERT( pBlock->UAVDepCount < 2 );\r
- if( pBlock->UAVDepCount > 0 )\r
- {\r
- SUnorderedAccessViewDependency *pUAVDep = pBlock->pUAVDeps;\r
- D3DXASSERT(pUAVDep->ppFXPointers);\r
-\r
- for (i=0; i<pUAVDep->Count; i++)\r
- {\r
- pUAVDep->ppD3DObjects[i] = pUAVDep->ppFXPointers[i]->pUnorderedAccessView;\r
- }\r
-\r
- if( EOT_ComputeShader5 == pBlock->GetShaderType() )\r
- {\r
- m_pContext->CSSetUnorderedAccessViews( pUAVDep->StartIndex, pUAVDep->Count, pUAVDep->ppD3DObjects, g_pNegativeOnes );\r
- }\r
- else\r
- {\r
- // This call could be combined with the call to set render targets if both exist in the pass\r
- m_pContext->OMSetRenderTargetsAndUnorderedAccessViews( D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, NULL, NULL, pUAVDep->StartIndex, pUAVDep->Count, pUAVDep->ppD3DObjects, g_pNegativeOnes );\r
- }\r
- }\r
-\r
- // TBuffers are funny:\r
- // We keep two references to them. One is in as a standard texture dep, and that gets used for all sets\r
- // The other is as a part of the TBufferDeps array, which tells us to rebuild the matching CBs.\r
- // These two refs could be rolled into one, but then we would have to predicate on each CB or each texture.\r
- SConstantBuffer **ppTB = pBlock->ppTbufDeps;\r
- SConstantBuffer **ppLastTB = ppTB + pBlock->TBufferDepCount;\r
-\r
- for (; ppTB<ppLastTB; ppTB++)\r
- {\r
- CheckAndUpdateCB_FX(m_pContext, (SConstantBuffer*)*ppTB);\r
- }\r
-\r
- // Set the textures\r
- SShaderResourceDependency *pResourceDep = pBlock->pResourceDeps;\r
- SShaderResourceDependency *pLastResourceDep = pBlock->pResourceDeps + pBlock->ResourceDepCount;\r
-\r
- for (; pResourceDep<pLastResourceDep; pResourceDep++)\r
- {\r
- D3DXASSERT(pResourceDep->ppFXPointers);\r
-\r
- for (i=0; i<pResourceDep->Count; i++)\r
- {\r
- pResourceDep->ppD3DObjects[i] = pResourceDep->ppFXPointers[i]->pShaderResource;\r
- }\r
-\r
- (m_pContext->*(pVT->pSetShaderResources))(pResourceDep->StartIndex, pResourceDep->Count, pResourceDep->ppD3DObjects);\r
- }\r
-\r
- // Update Interface dependencies\r
- UINT Interfaces = 0;\r
- ID3D11ClassInstance** ppClassInstances = NULL;\r
- D3DXASSERT( pBlock->InterfaceDepCount < 2 );\r
- if( pBlock->InterfaceDepCount > 0 )\r
- {\r
- SInterfaceDependency *pInterfaceDep = pBlock->pInterfaceDeps;\r
- D3DXASSERT(pInterfaceDep->ppFXPointers);\r
-\r
- ppClassInstances = pInterfaceDep->ppD3DObjects;\r
- Interfaces = pInterfaceDep->Count;\r
- for (i=0; i<pInterfaceDep->Count; i++)\r
- {\r
- SClassInstanceGlobalVariable* pCI = pInterfaceDep->ppFXPointers[i]->pClassInstance;\r
- if( pCI )\r
- {\r
- D3DXASSERT( pCI->pMemberData != NULL );\r
- pInterfaceDep->ppD3DObjects[i] = pCI->pMemberData->Data.pD3DClassInstance;\r
- }\r
- else\r
- {\r
- pInterfaceDep->ppD3DObjects[i] = NULL;\r
- }\r
- }\r
- }\r
-\r
- // Now set the shader\r
- (m_pContext->*(pVT->pSetShader))(pBlock->pD3DObject, ppClassInstances, Interfaces);\r
-}\r
-\r
-// Returns TRUE if the block D3D data was recreated\r
-BOOL CEffect::ApplyRenderStateBlock(SBaseBlock *pBlock)\r
-{\r
- if( pBlock->IsUserManaged )\r
- {\r
- return FALSE;\r
- }\r
-\r
- BOOL bRecreate = pBlock->ApplyAssignments(this);\r
-\r
- if (bRecreate)\r
- {\r
- switch (pBlock->BlockType)\r
- {\r
- case EBT_Sampler:\r
- {\r
- SSamplerBlock *pSBlock = pBlock->AsSampler();\r
-\r
- D3DXASSERT(NULL != pSBlock->pD3DObject);\r
- pSBlock->pD3DObject->Release();\r
-\r
- m_pDevice->CreateSamplerState( &pSBlock->BackingStore.SamplerDesc, &pSBlock->pD3DObject );\r
-\r
- }\r
- break;\r
-\r
- case EBT_DepthStencil:\r
- {\r
- SDepthStencilBlock *pDSBlock = pBlock->AsDepthStencil();\r
-\r
- D3DXASSERT(NULL != pDSBlock->pDSObject);\r
- SAFE_RELEASE( pDSBlock->pDSObject );\r
- if( SUCCEEDED( m_pDevice->CreateDepthStencilState( &pDSBlock->BackingStore, &pDSBlock->pDSObject ) ) )\r
- pDSBlock->IsValid = TRUE;\r
- else\r
- pDSBlock->IsValid = FALSE;\r
- }\r
- break;\r
- \r
- case EBT_Blend:\r
- {\r
- SBlendBlock *pBBlock = pBlock->AsBlend();\r
-\r
- D3DXASSERT(NULL != pBBlock->pBlendObject);\r
- SAFE_RELEASE( pBBlock->pBlendObject );\r
- if( SUCCEEDED( m_pDevice->CreateBlendState( &pBBlock->BackingStore, &pBBlock->pBlendObject ) ) )\r
- pBBlock->IsValid = TRUE;\r
- else\r
- pBBlock->IsValid = FALSE;\r
- }\r
- break;\r
-\r
- case EBT_Rasterizer:\r
- {\r
- SRasterizerBlock *pRBlock = pBlock->AsRasterizer();\r
-\r
- D3DXASSERT(NULL != pRBlock->pRasterizerObject);\r
-\r
- SAFE_RELEASE( pRBlock->pRasterizerObject );\r
- if( SUCCEEDED( m_pDevice->CreateRasterizerState( &pRBlock->BackingStore, &pRBlock->pRasterizerObject ) ) )\r
- pRBlock->IsValid = TRUE;\r
- else\r
- pRBlock->IsValid = FALSE;\r
- }\r
- break;\r
- \r
- default:\r
- D3DXASSERT(0);\r
- }\r
- }\r
-\r
- return bRecreate;\r
-}\r
-\r
-void CEffect::ValidateIndex(UINT Elements)\r
-{\r
- if (m_FXLIndex >= Elements)\r
- {\r
- DPF(0, "ID3DX11Effect: Overindexing variable array (size: %d, index: %d), using index = 0 instead", Elements, m_FXLIndex);\r
- m_FXLIndex = 0;\r
- }\r
-}\r
-\r
-// Returns TRUE if the assignment was changed\r
-BOOL CEffect::EvaluateAssignment(SAssignment *pAssignment)\r
-{\r
- BOOL bNeedUpdate = FALSE;\r
- SGlobalVariable *pVarDep0, *pVarDep1;\r
- \r
- switch (pAssignment->AssignmentType)\r
- {\r
- case ERAT_NumericVariable:\r
- D3DXASSERT(pAssignment->DependencyCount == 1);\r
- if (pAssignment->pDependencies[0].pVariable->LastModifiedTime >= pAssignment->LastRecomputedTime)\r
- {\r
- dwordMemcpy(pAssignment->Destination.pNumeric, pAssignment->Source.pNumeric, pAssignment->DataSize);\r
- bNeedUpdate = TRUE;\r
- }\r
- break;\r
-\r
- case ERAT_NumericVariableIndex:\r
- D3DXASSERT(pAssignment->DependencyCount == 2);\r
- pVarDep0 = pAssignment->pDependencies[0].pVariable;\r
- pVarDep1 = pAssignment->pDependencies[1].pVariable;\r
-\r
- if (pVarDep0->LastModifiedTime >= pAssignment->LastRecomputedTime)\r
- {\r
- m_FXLIndex = *pVarDep0->Data.pNumericDword;\r
-\r
- ValidateIndex(pVarDep1->pType->Elements);\r
-\r
- // Array index variable is dirty, update the pointer\r
- pAssignment->Source.pNumeric = pVarDep1->Data.pNumeric + pVarDep1->pType->Stride * m_FXLIndex;\r
- \r
- // Copy the new data\r
- dwordMemcpy(pAssignment->Destination.pNumeric, pAssignment->Source.pNumeric, pAssignment->DataSize);\r
- bNeedUpdate = TRUE;\r
- }\r
- else if (pVarDep1->LastModifiedTime >= pAssignment->LastRecomputedTime)\r
- {\r
- // Only the array variable is dirty, copy the new data\r
- dwordMemcpy(pAssignment->Destination.pNumeric, pAssignment->Source.pNumeric, pAssignment->DataSize);\r
- bNeedUpdate = TRUE;\r
- }\r
- break;\r
-\r
- case ERAT_ObjectVariableIndex:\r
- D3DXASSERT(pAssignment->DependencyCount == 1);\r
- pVarDep0 = pAssignment->pDependencies[0].pVariable;\r
- if (pVarDep0->LastModifiedTime >= pAssignment->LastRecomputedTime)\r
- {\r
- m_FXLIndex = *pVarDep0->Data.pNumericDword;\r
- ValidateIndex(pAssignment->MaxElements);\r
-\r
- // Array index variable is dirty, update the destination pointer\r
- *((void **)pAssignment->Destination.pGeneric) = pAssignment->Source.pNumeric +\r
- pAssignment->DataSize * m_FXLIndex;\r
- bNeedUpdate = TRUE;\r
- }\r
- break;\r
-\r
- default:\r
- //case ERAT_Constant: -- These are consumed and discarded\r
- //case ERAT_ObjectVariable: -- These are consumed and discarded\r
- //case ERAT_ObjectConstIndex: -- These are consumed and discarded\r
- //case ERAT_ObjectInlineShader: -- These are consumed and discarded\r
- //case ERAT_NumericConstIndex: -- ERAT_NumericVariable should be generated instead\r
- D3DXASSERT(0);\r
- break;\r
- }\r
- \r
- // Mark the assignment as not dirty\r
- pAssignment->LastRecomputedTime = m_LocalTimer;\r
-\r
- return bNeedUpdate;\r
-}\r
-\r
-// Returns FALSE if this shader has interface dependencies which are NULL (SetShader will fail).\r
-BOOL CEffect::ValidateShaderBlock( SShaderBlock* pBlock )\r
-{\r
- if( !pBlock->IsValid )\r
- return FALSE;\r
- if( pBlock->InterfaceDepCount > 0 )\r
- {\r
- D3DXASSERT( pBlock->InterfaceDepCount == 1 );\r
- for( UINT i=0; i < pBlock->pInterfaceDeps[0].Count; i++ )\r
- {\r
- SInterface* pInterfaceDep = pBlock->pInterfaceDeps[0].ppFXPointers[i];\r
- D3DXASSERT( pInterfaceDep != NULL );\r
- if( pInterfaceDep->pClassInstance == NULL )\r
- {\r
- return FALSE;\r
- }\r
- }\r
- }\r
- return TRUE;\r
-}\r
-\r
-// Returns FALSE if any state in the pass is invalid\r
-BOOL CEffect::ValidatePassBlock( SPassBlock* pBlock )\r
-{\r
- pBlock->ApplyPassAssignments();\r
-\r
- if (NULL != pBlock->BackingStore.pBlendBlock)\r
- {\r
- ApplyRenderStateBlock(pBlock->BackingStore.pBlendBlock);\r
- pBlock->BackingStore.pBlendState = pBlock->BackingStore.pBlendBlock->pBlendObject;\r
- if( !pBlock->BackingStore.pBlendBlock->IsValid )\r
- return FALSE;\r
- }\r
-\r
- if( NULL != pBlock->BackingStore.pDepthStencilBlock )\r
- {\r
- ApplyRenderStateBlock( pBlock->BackingStore.pDepthStencilBlock );\r
- pBlock->BackingStore.pDepthStencilState = pBlock->BackingStore.pDepthStencilBlock->pDSObject;\r
- if( !pBlock->BackingStore.pDepthStencilBlock->IsValid )\r
- return FALSE;\r
- }\r
-\r
- if( NULL != pBlock->BackingStore.pRasterizerBlock )\r
- {\r
- ApplyRenderStateBlock( pBlock->BackingStore.pRasterizerBlock );\r
- if( !pBlock->BackingStore.pRasterizerBlock->IsValid )\r
- return FALSE;\r
- }\r
-\r
- if( NULL != pBlock->BackingStore.pVertexShaderBlock && !ValidateShaderBlock(pBlock->BackingStore.pVertexShaderBlock) )\r
- return FALSE;\r
-\r
- if( NULL != pBlock->BackingStore.pGeometryShaderBlock && !ValidateShaderBlock(pBlock->BackingStore.pGeometryShaderBlock) )\r
- return FALSE;\r
-\r
- if( NULL != pBlock->BackingStore.pPixelShaderBlock )\r
- {\r
- if( !ValidateShaderBlock(pBlock->BackingStore.pPixelShaderBlock) )\r
- return FALSE;\r
- else if( pBlock->BackingStore.pPixelShaderBlock->UAVDepCount > 0 && \r
- pBlock->BackingStore.RenderTargetViewCount > pBlock->BackingStore.pPixelShaderBlock->pUAVDeps[0].StartIndex )\r
- {\r
- return FALSE;\r
- }\r
- }\r
-\r
- if( NULL != pBlock->BackingStore.pHullShaderBlock && !ValidateShaderBlock(pBlock->BackingStore.pHullShaderBlock) )\r
- return FALSE;\r
-\r
- if( NULL != pBlock->BackingStore.pDomainShaderBlock && !ValidateShaderBlock(pBlock->BackingStore.pDomainShaderBlock) )\r
- return FALSE;\r
-\r
- if( NULL != pBlock->BackingStore.pComputeShaderBlock && !ValidateShaderBlock(pBlock->BackingStore.pComputeShaderBlock) )\r
- return FALSE;\r
-\r
- return TRUE;\r
-}\r
-\r
-// Set all state defined in the pass\r
-void CEffect::ApplyPassBlock(SPassBlock *pBlock)\r
-{\r
- pBlock->ApplyPassAssignments();\r
-\r
- if (NULL != pBlock->BackingStore.pBlendBlock)\r
- {\r
- ApplyRenderStateBlock(pBlock->BackingStore.pBlendBlock);\r
-#ifdef FXDEBUG\r
- if( !pBlock->BackingStore.pBlendBlock->IsValid )\r
- DPF( 0, "Pass::Apply - warning: applying invalid BlendState." );\r
-#endif\r
- pBlock->BackingStore.pBlendState = pBlock->BackingStore.pBlendBlock->pBlendObject;\r
- m_pContext->OMSetBlendState(pBlock->BackingStore.pBlendState,\r
- pBlock->BackingStore.BlendFactor,\r
- pBlock->BackingStore.SampleMask);\r
- }\r
-\r
- if (NULL != pBlock->BackingStore.pDepthStencilBlock)\r
- {\r
- ApplyRenderStateBlock(pBlock->BackingStore.pDepthStencilBlock);\r
-#ifdef FXDEBUG\r
- if( !pBlock->BackingStore.pDepthStencilBlock->IsValid )\r
- DPF( 0, "Pass::Apply - warning: applying invalid DepthStencilState." );\r
-#endif\r
- pBlock->BackingStore.pDepthStencilState = pBlock->BackingStore.pDepthStencilBlock->pDSObject;\r
- m_pContext->OMSetDepthStencilState(pBlock->BackingStore.pDepthStencilState,\r
- pBlock->BackingStore.StencilRef);\r
- }\r
-\r
- if (NULL != pBlock->BackingStore.pRasterizerBlock)\r
- {\r
- ApplyRenderStateBlock(pBlock->BackingStore.pRasterizerBlock);\r
-#ifdef FXDEBUG\r
- if( !pBlock->BackingStore.pRasterizerBlock->IsValid )\r
- DPF( 0, "Pass::Apply - warning: applying invalid RasterizerState." );\r
-#endif\r
- m_pContext->RSSetState(pBlock->BackingStore.pRasterizerBlock->pRasterizerObject);\r
- }\r
-\r
- if (NULL != pBlock->BackingStore.pRenderTargetViews[0])\r
- {\r
- // Grab all render targets\r
- ID3D11RenderTargetView *pRTV[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];\r
-\r
- D3DXASSERT(pBlock->BackingStore.RenderTargetViewCount <= D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT);\r
- __analysis_assume(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT >= pBlock->BackingStore.RenderTargetViewCount);\r
-\r
- for (UINT i=0; i<pBlock->BackingStore.RenderTargetViewCount; i++)\r
- {\r
- pRTV[i] = pBlock->BackingStore.pRenderTargetViews[i]->pRenderTargetView;\r
- }\r
-\r
- // This call could be combined with the call to set PS UAVs if both exist in the pass\r
- m_pContext->OMSetRenderTargetsAndUnorderedAccessViews( pBlock->BackingStore.RenderTargetViewCount, pRTV, pBlock->BackingStore.pDepthStencilView->pDepthStencilView, 7, D3D11_KEEP_UNORDERED_ACCESS_VIEWS, NULL, NULL );\r
- }\r
-\r
- if (NULL != pBlock->BackingStore.pVertexShaderBlock)\r
- {\r
-#ifdef FXDEBUG\r
- if( !pBlock->BackingStore.pVertexShaderBlock->IsValid )\r
- DPF( 0, "Pass::Apply - warning: applying invalid vertex shader." );\r
-#endif\r
- ApplyShaderBlock(pBlock->BackingStore.pVertexShaderBlock);\r
- }\r
-\r
- if (NULL != pBlock->BackingStore.pPixelShaderBlock)\r
- {\r
-#ifdef FXDEBUG\r
- if( !pBlock->BackingStore.pPixelShaderBlock->IsValid )\r
- DPF( 0, "Pass::Apply - warning: applying invalid pixel shader." );\r
-#endif\r
- ApplyShaderBlock(pBlock->BackingStore.pPixelShaderBlock);\r
- }\r
-\r
- if (NULL != pBlock->BackingStore.pGeometryShaderBlock)\r
- {\r
-#ifdef FXDEBUG\r
- if( !pBlock->BackingStore.pGeometryShaderBlock->IsValid )\r
- DPF( 0, "Pass::Apply - warning: applying invalid geometry shader." );\r
-#endif\r
- ApplyShaderBlock(pBlock->BackingStore.pGeometryShaderBlock);\r
- }\r
-\r
- if (NULL != pBlock->BackingStore.pHullShaderBlock)\r
- {\r
-#ifdef FXDEBUG\r
- if( !pBlock->BackingStore.pHullShaderBlock->IsValid )\r
- DPF( 0, "Pass::Apply - warning: applying invalid hull shader." );\r
-#endif\r
- ApplyShaderBlock(pBlock->BackingStore.pHullShaderBlock);\r
- }\r
-\r
- if (NULL != pBlock->BackingStore.pDomainShaderBlock)\r
- {\r
-#ifdef FXDEBUG\r
- if( !pBlock->BackingStore.pDomainShaderBlock->IsValid )\r
- DPF( 0, "Pass::Apply - warning: applying invalid domain shader." );\r
-#endif\r
- ApplyShaderBlock(pBlock->BackingStore.pDomainShaderBlock);\r
- }\r
-\r
- if (NULL != pBlock->BackingStore.pComputeShaderBlock)\r
- {\r
-#ifdef FXDEBUG\r
- if( !pBlock->BackingStore.pComputeShaderBlock->IsValid )\r
- DPF( 0, "Pass::Apply - warning: applying invalid compute shader." );\r
-#endif\r
- ApplyShaderBlock(pBlock->BackingStore.pComputeShaderBlock);\r
- }\r
-}\r
-\r
-void CEffect::IncrementTimer()\r
-{\r
- m_LocalTimer++;\r
-\r
-#ifndef _WIN64\r
-#if _DEBUG && FXDEBUG\r
- if (m_LocalTimer > g_TimerRolloverCount)\r
- {\r
- DPF(0, "Rolling over timer (current time: %d, rollover cap: %d).", m_LocalTimer, g_TimerRolloverCount);\r
-#else // else !(_DEBUG && FXDEBUG)\r
- if (m_LocalTimer >= 0x80000000) // check to see if we've exceeded ~2 billion\r
- {\r
-#endif // _DEBUG && FXDEBUG\r
- HandleLocalTimerRollover();\r
-\r
- m_LocalTimer = 1;\r
- }\r
-#endif // _WIN64\r
-}\r
-\r
-// This function resets all timers, rendering all assignments dirty\r
-// This is clearly bad for performance, but should only happen every few billion ticks\r
-void CEffect::HandleLocalTimerRollover()\r
-{\r
- UINT i, j, k;\r
- \r
- // step 1: update variables\r
- for (i = 0; i < m_VariableCount; ++ i)\r
- {\r
- m_pVariables[i].LastModifiedTime = 0;\r
- }\r
-\r
- // step 2: update assignments on all blocks (pass, depth stencil, rasterizer, blend, sampler)\r
- for (UINT iGroup = 0; iGroup < m_GroupCount; ++ iGroup)\r
- {\r
- for (i = 0; i < m_pGroups[iGroup].TechniqueCount; ++ i)\r
- {\r
- for (j = 0; j < m_pGroups[iGroup].pTechniques[i].PassCount; ++ j)\r
- {\r
- for (k = 0; k < m_pGroups[iGroup].pTechniques[i].pPasses[j].AssignmentCount; ++ k)\r
- {\r
- m_pGroups[iGroup].pTechniques[i].pPasses[j].pAssignments[k].LastRecomputedTime = 0;\r
- }\r
- }\r
- }\r
- }\r
-\r
- for (i = 0; i < m_DepthStencilBlockCount; ++ i)\r
- {\r
- for (j = 0; j < m_pDepthStencilBlocks[i].AssignmentCount; ++ j)\r
- {\r
- m_pDepthStencilBlocks[i].pAssignments[j].LastRecomputedTime = 0;\r
- }\r
- }\r
-\r
- for (i = 0; i < m_RasterizerBlockCount; ++ i)\r
- {\r
- for (j = 0; j < m_pRasterizerBlocks[i].AssignmentCount; ++ j)\r
- {\r
- m_pRasterizerBlocks[i].pAssignments[j].LastRecomputedTime = 0;\r
- }\r
- }\r
-\r
- for (i = 0; i < m_BlendBlockCount; ++ i)\r
- {\r
- for (j = 0; j < m_pBlendBlocks[i].AssignmentCount; ++ j)\r
- {\r
- m_pBlendBlocks[i].pAssignments[j].LastRecomputedTime = 0;\r
- }\r
- }\r
-\r
- for (i = 0; i < m_SamplerBlockCount; ++ i)\r
- {\r
- for (j = 0; j < m_pSamplerBlocks[i].AssignmentCount; ++ j)\r
- {\r
- m_pSamplerBlocks[i].pAssignments[j].LastRecomputedTime = 0;\r
- }\r
- }\r
-}\r
-\r
-}\r