git.s-ol.nu ~forks/DiligentCore / ef1e1c0
Removed duplicate code from unbinding incompatible signatures logic in D3D11, GL and Vk assiduous 6 months ago
4 changed file(s) with 49 addition(s) and 78 deletion(s). Raw diff Collapse all Expand all
104104 class DeviceContextBase : public ObjectBase<typename EngineImplTraits::DeviceContextInterface>
105105 {
106106 public:
107 using BaseInterface = typename EngineImplTraits::DeviceContextInterface;
108 using TObjectBase = ObjectBase<BaseInterface>;
109 using DeviceImplType = typename EngineImplTraits::RenderDeviceImplType;
110 using BufferImplType = typename EngineImplTraits::BufferImplType;
111 using TextureImplType = typename EngineImplTraits::TextureImplType;
112 using PipelineStateImplType = typename EngineImplTraits::PipelineStateImplType;
113 using TextureViewImplType = typename EngineImplTraits::TextureViewImplType;
114 using QueryImplType = typename EngineImplTraits::QueryImplType;
115 using FramebufferImplType = typename EngineImplTraits::FramebufferImplType;
116 using RenderPassImplType = typename EngineImplTraits::RenderPassImplType;
117 using BottomLevelASType = typename EngineImplTraits::BottomLevelASImplType;
118 using TopLevelASType = typename EngineImplTraits::TopLevelASImplType;
107 using BaseInterface = typename EngineImplTraits::DeviceContextInterface;
108 using TObjectBase = ObjectBase<BaseInterface>;
109 using DeviceImplType = typename EngineImplTraits::RenderDeviceImplType;
110 using BufferImplType = typename EngineImplTraits::BufferImplType;
111 using TextureImplType = typename EngineImplTraits::TextureImplType;
112 using PipelineStateImplType = typename EngineImplTraits::PipelineStateImplType;
113 using ShaderResourceBindingImplType = typename EngineImplTraits::ShaderResourceBindingImplType;
114 using TextureViewImplType = typename EngineImplTraits::TextureViewImplType;
115 using QueryImplType = typename EngineImplTraits::QueryImplType;
116 using FramebufferImplType = typename EngineImplTraits::FramebufferImplType;
117 using RenderPassImplType = typename EngineImplTraits::RenderPassImplType;
118 using BottomLevelASType = typename EngineImplTraits::BottomLevelASImplType;
119 using TopLevelASType = typename EngineImplTraits::TopLevelASImplType;
119120
120121 /// \param pRefCounters - Reference counters object that controls the lifetime of this device context.
121122 /// \param pRenderDevice - Render device.
310311 bool DvpVerifyBufferState (const BufferImplType& Buffer, RESOURCE_STATE RequiredState, const char* OperationName) const;
311312 bool DvpVerifyBLASState (const BottomLevelASType& BLAS, RESOURCE_STATE RequiredState, const char* OperationName) const;
312313 bool DvpVerifyTLASState (const TopLevelASType& TLAS, RESOURCE_STATE RequiredState, const char* OperationName) const;
314
315 Uint32 DvpGetCompatibleSignatureCount(ShaderResourceBindingImplType* pBoundSRBs[])const;
313316 #else
314317 bool DvpVerifyDrawArguments (const DrawAttribs& Attribs)const {return true;}
315318 bool DvpVerifyDrawIndexedArguments (const DrawIndexedAttribs& Attribs)const {return true;}
21202123 return true;
21212124 }
21222125
2126 template <typename ImplementationTraits>
2127 Uint32 DeviceContextBase<ImplementationTraits>::DvpGetCompatibleSignatureCount(ShaderResourceBindingImplType* pBoundSRBs[]) const
2128 {
2129 VERIFY_EXPR(m_pPipelineState);
2130 const auto SignCount = m_pPipelineState->GetResourceSignatureCount();
2131
2132 Uint32 sign = 0;
2133 for (; sign < SignCount; ++sign)
2134 {
2135 const auto* pPSOSign = m_pPipelineState->GetResourceSignature(sign);
2136 const auto* pSRBSign = pBoundSRBs[sign] != nullptr ? pBoundSRBs[sign]->GetSignature() : nullptr;
2137
2138 if ((pPSOSign == nullptr || pPSOSign->IsEmpty()) != (pSRBSign == nullptr || pSRBSign->IsEmpty()))
2139 {
2140 // One signature is null or empty while the other is not - SRB is not compatible with the PSO.
2141 break;
2142 }
2143
2144 if (pPSOSign != nullptr && pSRBSign != nullptr && pPSOSign->IsIncompatibleWith(*pSRBSign))
2145 {
2146 // Signatures are incompatible
2147 break;
2148 }
2149 }
2150
2151 return sign;
2152 }
2153
21232154 #endif // DILIGENT_DEVELOPMENT
21242155
21252156 } // namespace Diligent
153153 }
154154
155155 #ifdef DILIGENT_DEVELOPMENT
156 // Find the first incompatible shader resource bindings
157 Uint32 sign = 0;
158 for (; sign < SignCount; ++sign)
159 {
160 const auto* pLayoutSign = m_pPipelineState->GetResourceSignature(sign);
161 const auto* pSRBSign = m_BindInfo.SRBs[sign] != nullptr ? m_BindInfo.SRBs[sign]->GetSignature() : nullptr;
162
163 if ((pLayoutSign == nullptr || pLayoutSign->GetTotalResourceCount() == 0) != (pSRBSign == nullptr || pSRBSign->GetTotalResourceCount() == 0))
164 {
165 // One signature is null or empty while the other is not - SRB is not compatible with the layout.
166 break;
167 }
168
169 if (pLayoutSign != nullptr && pSRBSign != nullptr && pLayoutSign->IsIncompatibleWith(*pSRBSign))
170 {
171 // Signatures are incompatible
172 break;
173 }
174 }
175
176156 // Unbind incompatible SRB and SRB with a higher binding index.
177157 // This is the same behavior that used in Vulkan backend.
178 for (; sign < SignCount; ++sign)
158 for (auto sign = DvpGetCompatibleSignatureCount(m_BindInfo.SRBs.data()); sign < SignCount; ++sign)
179159 {
180160 m_BindInfo.SRBs[sign] = nullptr;
181161 m_BindInfo.ClearStaleSRBBit(sign);
190170 /// Helper macro used to create an array of device context methods to
191171 /// set particular resource for every shader stage
192172 #define DEFINE_D3D11CTX_FUNC_POINTERS(ArrayName, FuncName) \
193 typedef decltype (&ID3D11DeviceContext::VS##FuncName) T##FuncName##Type; \
194 static const T##FuncName##Type ArrayName[] = \
195 { \
173 using T##FuncName##Type = decltype (&ID3D11DeviceContext::VS##FuncName); \
174 static const T##FuncName##Type ArrayName[] = \
175 { \
196176 &ID3D11DeviceContext::VS##FuncName, \
197177 &ID3D11DeviceContext::PS##FuncName, \
198178 &ID3D11DeviceContext::GS##FuncName, \
168168 }
169169
170170 #ifdef DILIGENT_DEVELOPMENT
171 // Find the first incompatible shader resource bindings
172 Uint32 sign = 0;
173 for (; sign < SignCount; ++sign)
174 {
175 const auto* pLayoutSign = m_pPipelineState->GetResourceSignature(sign);
176 const auto* pSRBSign = m_BindInfo.SRBs[sign] != nullptr ? m_BindInfo.SRBs[sign]->GetSignature() : nullptr;
177
178 if ((pLayoutSign == nullptr || pLayoutSign->GetTotalResourceCount() == 0) != (pSRBSign == nullptr || pSRBSign->GetTotalResourceCount() == 0))
179 {
180 // One signature is null or empty while the other is not - SRB is not compatible with the layout.
181 break;
182 }
183
184 if (pLayoutSign != nullptr && pSRBSign != nullptr && pLayoutSign->IsIncompatibleWith(*pSRBSign))
185 {
186 // Signatures are incompatible
187 break;
188 }
189 }
190
191171 // Unbind incompatible SRB and SRB with a higher binding index.
192172 // This is the same behavior that used in Vulkan backend.
193 for (; sign < SignCount; ++sign)
173 for (auto sign = DvpGetCompatibleSignatureCount(m_BindInfo.SRBs.data()); sign < SignCount; ++sign)
194174 {
195175 m_BindInfo.SRBs[sign] = nullptr;
196176 m_BindInfo.ClearStaleSRBBit(sign);
347347 // (14.2.2. Pipeline Layouts, clause 'Pipeline Layout Compatibility')
348348 // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#descriptorsets-compatibility
349349
350 // Find the first incompatible shader resource bindings
351 Uint32 sign = 0;
352 for (; sign < SignCount; ++sign)
353 {
354 const auto* pLayoutSign = pPipelineStateVk->GetResourceSignature(sign);
355 const auto* pSRBSign = BindInfo.SRBs[sign] != nullptr ? BindInfo.SRBs[sign]->GetSignature() : nullptr;
356
357 if ((pLayoutSign == nullptr || pLayoutSign->GetNumDescriptorSets() == 0) != (pSRBSign == nullptr || pSRBSign->GetNumDescriptorSets() == 0))
358 {
359 // One signature is null or empty while the other is not - SRB is not compatible with the layout.
360 break;
361 }
362
363 if (pLayoutSign != nullptr && pSRBSign != nullptr && pLayoutSign->IsIncompatibleWith(*pSRBSign))
364 {
365 // Signatures are incompatible
366 break;
367 }
368 }
369
370350 // Unbind incompatible shader resources
371351 // A consequence of layout compatibility is that when the implementation compiles a pipeline
372352 // layout and maps pipeline resources to implementation resources, the mechanism for set N
373353 // should only be a function of sets [0..N].
374 for (; sign < SignCount; ++sign)
354 for (auto sign = DvpGetCompatibleSignatureCount(BindInfo.SRBs.data()); sign < SignCount; ++sign)
375355 {
376356 BindInfo.SRBs[sign] = nullptr;
377357