Skip to content

Commit 67c2de7

Browse files
HnRenderPass: batch joint data uploads
1 parent 4f4b83d commit 67c2de7

File tree

6 files changed

+350
-190
lines changed

6 files changed

+350
-190
lines changed

Hydrogent/include/Computations/HnSkinningComputation.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class HnSkinningComputation final : public HnExtComputationImpl
5959
static bool IsCompatible(const HnExtComputation& Owner);
6060

6161
const pxr::VtMatrix4fArray& GetXforms() const { return m_Xforms[m_CurrXformsIdx]; }
62-
const pxr::VtMatrix4fArray& GetLastFrameXforms() const { return m_Xforms[1 - m_CurrXformsIdx]; }
62+
const pxr::VtMatrix4fArray& GetPrevFrameXforms(Uint32 FrameNumber) const;
6363
size_t GetXformsHash() const { return m_XformsHash; }
6464

6565
const float4x4& GetPrimWorldToLocal() const { return m_PrimWorldToLocal; }
@@ -75,6 +75,8 @@ class HnSkinningComputation final : public HnExtComputationImpl
7575
float4x4 m_PrimWorldToLocal = float4x4::Identity();
7676
float4x4 m_SkelLocalToWorld = float4x4::Identity();
7777
float4x4 m_SkelLocalToPrimLocal = float4x4::Identity();
78+
79+
Uint32 m_LastXformSyncFrameNumber = 0;
7880
};
7981

8082
} // namespace USD

Hydrogent/interface/HnMesh.hpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ namespace USD
5656
{
5757

5858
class HnRenderDelegate;
59-
class HnExtComputation;
59+
class HnSkinningComputation;
6060

6161
/// Hydra mesh implementation in Hydrogent.
6262
class HnMesh final : public pxr::HdMesh
@@ -112,12 +112,11 @@ class HnMesh final : public pxr::HdMesh
112112

113113
struct Skinning
114114
{
115-
const pxr::VtMatrix4fArray* Xforms = nullptr;
116-
const pxr::VtMatrix4fArray* LastFrameXforms = nullptr;
117-
size_t XformsHash = 0;
118-
float4x4 GeomBindXform = float4x4::Identity();
115+
const HnSkinningComputation* Computation = nullptr;
119116

120-
explicit operator bool() const { return Xforms != nullptr; }
117+
float4x4 GeomBindXform = float4x4::Identity();
118+
119+
explicit operator bool() const { return Computation != nullptr; }
121120
};
122121
};
123122

Hydrogent/interface/HnRenderPass.hpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ namespace USD
4747
class HnDrawItem;
4848
class HnRenderPassState;
4949
class HnMaterial;
50+
class HnSkinningComputation;
5051

5152
struct HnRenderPassParams
5253
{
@@ -165,17 +166,27 @@ class HnRenderPass final : public pxr::HdRenderPass
165166

166167
PBR_Renderer::PSO_FLAGS PSOFlags = PBR_Renderer::PSO_FLAG_NONE;
167168

168-
const pxr::VtMatrix4fArray* PrevXforms = nullptr;
169-
float4x4 PrevTransform = float4x4::Identity();
169+
float4x4 PrevTransform = float4x4::Identity();
170170

171171
// Primitive attributes shader data size computed from the value of PSOFlags.
172172
// Note: unshaded (aka wireframe/point) rendering modes don't use any textures, so the shader data
173173
// is smaller than that for the shaded mode.
174-
Uint32 ShaderAttribsDataSize = 0;
174+
Uint16 ShaderAttribsDataSize = 0;
175175

176176
// Primitive attributes buffer range used to set the cbPrimitiveAttribs buffer
177177
// in the material's SRB.
178-
Uint32 PrimitiveAttribsBufferRange = 0;
178+
Uint16 PrimitiveAttribsBufferRange = 0;
179+
180+
// Joints data index in m_DrawItemJoints.
181+
// Mutiple draw items can share the same joints data.
182+
//
183+
// Draw Items [ 0 ][ 0 ][ -1 ][ 1 ][ 1 ]
184+
// | | | |
185+
// |.----' .-----------'------'
186+
// V V
187+
// Joints Data [ ][ ]
188+
//
189+
Uint32 JointsIdx = ~0u;
179190

180191
IBuffer* IndexBuffer = nullptr;
181192

@@ -190,9 +201,11 @@ class HnRenderPass final : public pxr::HdRenderPass
190201
};
191202

192203
void UpdateDrawList(const pxr::TfTokenVector& RenderTags);
204+
void UpdateDrawListJoints(HnRenderDelegate& RenderDelegate);
193205
void UpdateDrawListGPUResources(RenderState& State);
194206
void UpdateDrawListItemGPUResources(DrawListItem& ListItem, RenderState& State, DRAW_LIST_ITEM_DIRTY_FLAGS DirtyFlags);
195207

208+
void WriteJointsDataBatch(RenderState& State, Uint32 BatchIdx, PBR_Renderer::PSO_FLAGS PSOFlags);
196209
void RenderPendingDrawItems(RenderState& State);
197210

198211
GraphicsPipelineDesc GetGraphicsDesc(const HnRenderPassState& RPState, bool UseStripTopology) const;
@@ -226,6 +239,24 @@ class HnRenderPass final : public pxr::HdRenderPass
226239
// Rendering order of the draw list items sorted by the PSO.
227240
std::vector<Uint32> m_RenderOrder;
228241

242+
struct DrawItemJointsData
243+
{
244+
Uint32 BatchIdx = ~0u;
245+
Uint32 BufferOffset = ~0u;
246+
Uint32 JointCount = 0;
247+
Uint32 FirstJoint = 0;
248+
Uint32 DataSize = 0;
249+
250+
const HnSkinningComputation* SkinComp = nullptr;
251+
252+
constexpr operator bool() const noexcept
253+
{
254+
return BatchIdx != ~0u;
255+
}
256+
};
257+
std::vector<DrawItemJointsData> m_DrawItemJoints;
258+
size_t m_CurrDrawItemJointIdx = 0;
259+
229260
// Scratch space to prepare data for the primitive attributes buffer.
230261
std::vector<Uint8> m_PrimitiveAttribsData;
231262

Hydrogent/src/Computations/HnSkinningComputation.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "Computations/HnSkinningComputation.hpp"
2828
#include "HnExtComputation.hpp"
2929
#include "HnTokens.hpp"
30+
#include "HnRenderParam.hpp"
3031
#include "DebugUtilities.hpp"
3132
#include "GfTypeConversions.hpp"
3233
#include "HnRenderDelegate.hpp"
@@ -74,17 +75,15 @@ void HnSkinningComputation::Sync(pxr::HdSceneDelegate* SceneDelegate,
7475
pxr::VtValue SkinningXformsVal = SceneDelegate->GetExtComputationInput(Id, HnSkinningComputationPrivateTokens->skinningXforms);
7576
if (SkinningXformsVal.IsHolding<pxr::VtMatrix4fArray>())
7677
{
77-
pxr::VtMatrix4fArray& LastXforms = m_Xforms[m_CurrXformsIdx];
7878
VERIFY_EXPR(m_Xforms.size() == 2);
7979
m_CurrXformsIdx = 1 - m_CurrXformsIdx;
8080
pxr::VtMatrix4fArray& Xforms = m_Xforms[m_CurrXformsIdx];
8181

82-
Xforms = SkinningXformsVal.UncheckedGet<pxr::VtMatrix4fArray>();
83-
if (LastXforms.empty())
84-
LastXforms = Xforms;
85-
82+
Xforms = SkinningXformsVal.UncheckedGet<pxr::VtMatrix4fArray>();
8683
m_XformsHash = pxr::TfHash{}(Xforms);
8784

85+
m_LastXformSyncFrameNumber = static_cast<const HnRenderParam*>(RenderParam)->GetFrameNumber();
86+
8887
const HnRenderDelegate* RenderDelegate = static_cast<const HnRenderDelegate*>(SceneDelegate->GetRenderIndex().GetRenderDelegate());
8988
const USD_Renderer& USDRenderer = *RenderDelegate->GetUSDRenderer();
9089
const Uint32 MaxJointCount = USDRenderer.GetSettings().MaxJointCount;
@@ -151,6 +150,22 @@ bool HnSkinningComputation::IsCompatible(const HnExtComputation& Owner)
151150
return Outputs.size() == 1 && Outputs[0].name == HnSkinningComputationPrivateTokens->skinnedPoints;
152151
}
153152

153+
const pxr::VtMatrix4fArray& HnSkinningComputation::GetPrevFrameXforms(Uint32 FrameNumber) const
154+
{
155+
// Frame number is incremented by HnBeginFrameTask after all computations have been synced.
156+
if (FrameNumber == m_LastXformSyncFrameNumber + 1)
157+
{
158+
const pxr::VtMatrix4fArray& PrevXforms = m_Xforms[1 - m_CurrXformsIdx];
159+
return !PrevXforms.empty() ? PrevXforms : m_Xforms[m_CurrXformsIdx];
160+
}
161+
else
162+
{
163+
// Skinning xforms have not been updated for the current frame, so
164+
// they are the same as the previous frame.
165+
return m_Xforms[m_CurrXformsIdx];
166+
}
167+
}
168+
154169
} // namespace USD
155170

156171
} // namespace Diligent

Hydrogent/src/HnMesh.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -915,9 +915,7 @@ void HnMesh::UpdateSkinningPrimvars(pxr::HdSceneDelegate&
915915

916916
if (const HnSkinningComputation* SkinningCompImpl = SkinningComp->GetImpl<HnSkinningComputation>())
917917
{
918-
SkinningData.Xforms = &SkinningCompImpl->GetXforms();
919-
SkinningData.LastFrameXforms = &SkinningCompImpl->GetLastFrameXforms();
920-
SkinningData.XformsHash = SkinningCompImpl->GetXformsHash();
918+
SkinningData.Computation = SkinningCompImpl;
921919

922920
const float4x4& SkelLocalToPrimLocal = SkinningCompImpl->GetSkelLocalToPrimLocal();
923921
if (SkelLocalToPrimLocal != m_SkelLocalToPrimLocal)

0 commit comments

Comments
 (0)