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