@@ -693,45 +693,58 @@ class HnMaterialSRBCache : public ObjectBase<IObject>
693693 return it->second ;
694694 }
695695
696- void UpdateMaterialAttribsBufferRange (const IShaderResourceBinding* pSRB, Uint32 Range)
697- {
698- std::lock_guard<std::mutex> Lock{m_MaterialAttribsBufferRangeMtx};
699-
700- auto & SRBRange = m_MaterialAttribsBufferRange[pSRB];
701- SRBRange = std::max (SRBRange, Range);
702- }
703-
704- Uint32 GetMaterialAttribsBufferRange (const IShaderResourceBinding* pSRB) const
705- {
706- std::lock_guard<std::mutex> Lock{m_MaterialAttribsBufferRangeMtx};
707-
708- auto it = m_MaterialAttribsBufferRange.find (pSRB);
709- VERIFY (it != m_MaterialAttribsBufferRange.end (), " SRB is not found in the cache" );
710- return it != m_MaterialAttribsBufferRange.end () ? it->second : 0 ;
711- }
712-
713696 Uint32 AllocateBufferOffset (Uint32 Size, Uint32 Alignment, Uint32 MaxAttribsDataSize)
714697 {
715698 std::lock_guard<std::mutex> Lock{m_CurrBufferOffsetMtx};
716699
717- const Uint32 Offset = AlignUp (m_CurrBufferOffset, Alignment);
718- m_CurrBufferOffset = Offset + Size;
700+ const Uint32 Offset = AlignUp (m_CurrBufferOffset, Alignment);
701+ m_CurrBufferOffset = Offset + Size;
702+ // Reserve enough space for the maximum possible attribs data size.
719703 m_RequiredBufferSize = AlignUp (Offset + MaxAttribsDataSize, Alignment);
720704 return Offset;
721705 }
722706
723- IBuffer* UpdateMaterialAttribsBuffer (IRenderDevice* pDevice, IDeviceContext* pContext)
707+ IBuffer* PrepareMaterialAttribsBuffer (IRenderDevice* pDevice, IDeviceContext* pContext)
724708 {
725709 if (m_RequiredBufferSize > m_MaterialAttribsBuffer.GetDesc ().Size )
726710 {
727- m_MaterialAttribsBuffer.Resize (pDevice, pContext, m_RequiredBufferSize);
711+ m_MaterialAttribsData.resize (m_RequiredBufferSize);
712+ return m_MaterialAttribsBuffer.Resize (pDevice, pContext, m_RequiredBufferSize);
713+ }
714+ else
715+ {
716+ return m_MaterialAttribsBuffer.GetBuffer ();
717+ }
718+ }
719+
720+ void UpdateMaterialAttribsData (Uint32 Offset, Uint32 Size, const GLTF_PBR_Renderer::PBRMaterialShaderAttribsData AttribsData)
721+ {
722+ if (Offset + Size > m_MaterialAttribsData.size ())
723+ {
724+ UNEXPECTED (" Offset + Size (" , Offset + Size, " ) exceeds the size of the material attribs data buffer (" , m_MaterialAttribsData.size (), " )" );
725+ return ;
728726 }
729- return m_MaterialAttribsBuffer.GetBuffer ();
727+ void * pEnd = GLTF_PBR_Renderer::WritePBRMaterialShaderAttribs (&m_MaterialAttribsData[Offset], AttribsData);
728+ VERIFY_EXPR (static_cast <Uint32>(reinterpret_cast <const Uint8*>(pEnd) - &m_MaterialAttribsData[Offset]) == Size);
729+ (void )pEnd;
730+ m_DirtyRangeStart = std::min (m_DirtyRangeStart, Offset);
731+ m_DirtyRangeEnd = std::max (m_DirtyRangeEnd, Offset + Size);
730732 }
731733
732- IBuffer* GetMaterialAttribsBuffer () const
734+ IBuffer* CommitUpdates (IRenderDevice* pDevice, IDeviceContext* pContext)
733735 {
734- return m_MaterialAttribsBuffer.GetBuffer ();
736+ IBuffer* pBuffer = m_MaterialAttribsBuffer.GetBuffer ();
737+ if (m_DirtyRangeStart < m_DirtyRangeEnd)
738+ {
739+ if (pDevice->GetDeviceInfo ().Type == RENDER_DEVICE_TYPE_D3D11)
740+ {
741+ // Direct3D11 for unknown reason does not support partial constant buffer updates
742+ m_DirtyRangeStart = 0 ;
743+ m_DirtyRangeEnd = m_MaterialAttribsData.size ();
744+ }
745+ pContext->UpdateBuffer (pBuffer, m_DirtyRangeStart, m_DirtyRangeEnd - m_DirtyRangeStart, &m_MaterialAttribsData[m_DirtyRangeStart], RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
746+ }
747+ return pBuffer;
735748 }
736749
737750 Uint32 GetMaterialAttribsBufferVersion () const
@@ -758,15 +771,14 @@ class HnMaterialSRBCache : public ObjectBase<IObject>
758771
759772 std::unordered_map<ShaderTextureIndexingIdType, const StaticShaderTextureIdsArrayType&> m_IdToIndexing;
760773
761- // A mapping from the SRB to the maximum buffer range required by a material that uses the SRB.
762- mutable std::mutex m_MaterialAttribsBufferRangeMtx;
763- std::unordered_map<const IShaderResourceBinding*, Uint32> m_MaterialAttribsBufferRange;
764-
765774 std::mutex m_CurrBufferOffsetMtx;
766775 Uint32 m_CurrBufferOffset = 0 ;
767776 Uint32 m_RequiredBufferSize = 0 ;
768777
769- DynamicBuffer m_MaterialAttribsBuffer;
778+ DynamicBuffer m_MaterialAttribsBuffer;
779+ std::vector<Uint8> m_MaterialAttribsData;
780+ Uint32 m_DirtyRangeStart = 0 ;
781+ Uint32 m_DirtyRangeEnd = 0 ;
770782};
771783
772784void HnMaterial::AllocateBufferSpace (HnRenderDelegate& RenderDelegate)
@@ -907,24 +919,17 @@ bool HnMaterial::UpdateSRB(HnRenderDelegate& RenderDelegate)
907919
908920 RefCntAutoPtr<HnMaterialSRBCache> SRBCache{RenderDelegate.GetMaterialSRBCache (), IID_HnMaterialSRBCache};
909921 VERIFY_EXPR (SRBCache);
922+ IBuffer* pMaterialAttribsBuffer = SRBCache->PrepareMaterialAttribsBuffer (RenderDelegate.GetDevice (), RenderDelegate.GetDeviceContext ());
910923
911924 if (m_GPUDataDirty.load ())
912925 {
913- IDeviceContext* pContext = RenderDelegate.GetDeviceContext ();
914- IBuffer* pMaterialAttribsBuffer = SRBCache->UpdateMaterialAttribsBuffer (RenderDelegate.GetDevice (), pContext);
915926 VERIFY_EXPR (m_PSOFlags == HnRenderPass::GetMaterialPSOFlags (*this ));
916-
917- GLTF_PBR_Renderer::PBRMaterialShaderAttribsData AttribsData{
918- m_PSOFlags,
919- UsdRenderer.GetSettings ().TextureAttribIndices ,
920- m_MaterialData,
921- };
922- std::vector<Uint8> MaterialAttribsData (m_PBRMaterialAttribsSize);
923- void * pEnd = GLTF_PBR_Renderer::WritePBRMaterialShaderAttribs (MaterialAttribsData.data (), AttribsData);
924- VERIFY_EXPR (static_cast <size_t >(reinterpret_cast <const Uint8*>(pEnd) - MaterialAttribsData.data ()) == m_PBRMaterialAttribsSize);
925-
926- pContext->UpdateBuffer (pMaterialAttribsBuffer, m_PBRMaterialAttribsBufferOffset, m_PBRMaterialAttribsSize, MaterialAttribsData.data (), RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
927-
927+ SRBCache->UpdateMaterialAttribsData (m_PBRMaterialAttribsBufferOffset, m_PBRMaterialAttribsSize,
928+ {
929+ m_PSOFlags,
930+ UsdRenderer.GetSettings ().TextureAttribIndices ,
931+ m_MaterialData,
932+ });
928933 m_GPUDataDirty.store (false );
929934 }
930935
@@ -936,12 +941,11 @@ bool HnMaterial::UpdateSRB(HnRenderDelegate& RenderDelegate)
936941 m_MaterialAttribsBufferVersion != MaterialAttribsBufferVersion)
937942 {
938943 m_SRB.Release ();
939- m_PrimitiveAttribsVar = nullptr ;
940- m_MaterialAttribsVar = nullptr ;
941- m_JointTransformsVar = nullptr ;
942- m_PBRMaterialAttribsBufferRange = 0 ;
943- m_TexRegistryStorageVersion = TexStorageVersion;
944- m_MaterialAttribsBufferVersion = MaterialAttribsBufferVersion;
944+ m_PrimitiveAttribsVar = nullptr ;
945+ m_MaterialAttribsVar = nullptr ;
946+ m_JointTransformsVar = nullptr ;
947+ m_TexRegistryStorageVersion = TexStorageVersion;
948+ m_MaterialAttribsBufferVersion = MaterialAttribsBufferVersion;
945949 }
946950
947951 if (m_SRB)
@@ -1232,9 +1236,15 @@ bool HnMaterial::UpdateSRB(HnRenderDelegate& RenderDelegate)
12321236
12331237 if (m_SRB)
12341238 {
1235- const PBR_Renderer::PSO_FLAGS PSOFlags = HnRenderPass::GetMaterialPSOFlags (*this );
1236- const Uint32 PBRMaterialAttribsSize = UsdRenderer.GetPBRMaterialAttribsSize (PSOFlags);
1237- SRBCache->UpdateMaterialAttribsBufferRange (m_SRB, PBRMaterialAttribsSize);
1239+ m_MaterialAttribsVar = m_SRB->GetVariableByName (SHADER_TYPE_PIXEL, " cbMaterialAttribs" );
1240+ VERIFY_EXPR (m_MaterialAttribsVar != nullptr );
1241+ if (m_MaterialAttribsVar->Get () == nullptr )
1242+ {
1243+ // Bind maximum possible buffer range
1244+ const Uint32 PBRMaterialAttribsMaxSize = UsdRenderer.GetPBRMaterialAttribsSize (PBR_Renderer::PSO_FLAG_ALL);
1245+ m_MaterialAttribsVar->SetBufferRange (pMaterialAttribsBuffer, 0 , PBRMaterialAttribsMaxSize);
1246+ }
1247+
12381248 m_JointTransformsVar = m_SRB->GetVariableByName (SHADER_TYPE_VERTEX, UsdRenderer.GetJointTransformsVarName ());
12391249 VERIFY_EXPR (m_JointTransformsVar != nullptr || RendererSettings.MaxJointCount == 0 );
12401250
@@ -1244,7 +1254,10 @@ bool HnMaterial::UpdateSRB(HnRenderDelegate& RenderDelegate)
12441254
12451255 m_PrimitiveAttribsVar = m_SRB->GetVariableByName (SHADER_TYPE_PIXEL, " cbPrimitiveAttribs" );
12461256 VERIFY_EXPR (m_PrimitiveAttribsVar != nullptr );
1247- m_PrimitiveAttribsVar->SetBufferRange (UsdRenderer.GetPBRPrimitiveAttribsCB (), 0 , m_PBRPrimitiveAttribsBufferRange);
1257+ if (m_PrimitiveAttribsVar->Get () == nullptr )
1258+ {
1259+ m_PrimitiveAttribsVar->SetBufferRange (UsdRenderer.GetPBRPrimitiveAttribsCB (), 0 , m_PBRPrimitiveAttribsBufferRange);
1260+ }
12481261 }
12491262 else
12501263 {
@@ -1254,30 +1267,15 @@ bool HnMaterial::UpdateSRB(HnRenderDelegate& RenderDelegate)
12541267 return true ;
12551268}
12561269
1257- void HnMaterial::BindMaterialAttribsBuffer (HnRenderDelegate& RenderDelegate)
1270+ void HnMaterial::CommitCacheResources (HnRenderDelegate& RenderDelegate)
12581271{
1259- if (!m_SRB || m_MaterialAttribsVar != nullptr )
1260- return ;
1261-
1262- m_MaterialAttribsVar = m_SRB->GetVariableByName (SHADER_TYPE_PIXEL, " cbMaterialAttribs" );
1263- if (m_MaterialAttribsVar == nullptr )
1264- {
1265- UNEXPECTED (" Failed to find 'cbMaterialAttribs' variable in the shader resource binding." );
1266- return ;
1267- }
1268-
12691272 RefCntAutoPtr<HnMaterialSRBCache> SRBCache{RenderDelegate.GetMaterialSRBCache (), IID_HnMaterialSRBCache};
12701273 VERIFY_EXPR (SRBCache);
12711274
1272- m_PBRMaterialAttribsBufferRange = SRBCache->GetMaterialAttribsBufferRange (m_SRB);
1273- VERIFY (m_PBRMaterialAttribsBufferRange != 0 ,
1274- " PBRMaterialAttribsBufferRange is zero, which indicates the SRB was not found in the cache. This appears to be a bug." );
1275-
1276- // Check if the buffer has already been set by another material that uses the same SRB
1277- if (m_MaterialAttribsVar->Get () == nullptr )
1278- {
1279- m_MaterialAttribsVar->SetBufferRange (SRBCache->GetMaterialAttribsBuffer (), 0 , m_PBRMaterialAttribsBufferRange);
1280- }
1275+ IDeviceContext* pContext = RenderDelegate.GetDeviceContext ();
1276+ IBuffer* pBuffer = SRBCache->CommitUpdates (RenderDelegate.GetDevice (), pContext);
1277+ StateTransitionDesc Barrier{pBuffer, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_CONSTANT_BUFFER, STATE_TRANSITION_FLAG_UPDATE_STATE};
1278+ pContext->TransitionResourceStates (1 , &Barrier);
12811279}
12821280
12831281} // namespace USD
0 commit comments