Skip to content

Commit 5e4bc0b

Browse files
HnRenderPass: correctly compute joints data range in structured mode
1 parent e9753f7 commit 5e4bc0b

File tree

1 file changed

+56
-21
lines changed

1 file changed

+56
-21
lines changed

Hydrogent/src/HnRenderPass.cpp

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,8 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c
407407
VERIFY_EXPR(pPrimitiveAttribsCB != nullptr);
408408
IBuffer* const pJointsCB = State.USDRenderer.GetJointsBuffer();
409409
const Uint32 MaxJointCount = State.RendererSettings.MaxJointCount;
410-
const Uint32 JointsDataRange = State.USDRenderer.GetJointsBufferSize();
411410
const bool PackMatrixRowMajor = State.RendererSettings.PackMatrixRowMajor;
412-
VERIFY_EXPR(pJointsCB != nullptr || JointsDataRange == 0);
411+
413412
const Uint32 JointsBufferOffsetAlignment = (State.RendererSettings.JointsBufferMode == USD_Renderer::JOINTS_BUFFER_MODE_UNIFORM) ?
414413
State.ConstantBufferOffsetAlignment :
415414
sizeof(float4x4);
@@ -422,11 +421,13 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c
422421
void* pMappedPrimitiveData = nullptr;
423422
Uint32 AttribsBufferOffset = 0;
424423

425-
void* pMappedJointsData = nullptr;
426-
Uint32 JointsBufferOffset = 0;
427-
Uint32 CurrJointsDataSize = 0;
428-
size_t XformsHash = 0;
429-
Uint32 JointCount = 0;
424+
void* pMappedJointsData = nullptr;
425+
Uint32 JointsBufferOffset = 0;
426+
Uint32 TotalJointsDataSize = 0;
427+
size_t XformsHash = 0;
428+
Uint32 JointCount = 0;
429+
Uint32 JointsDataRange = 0;
430+
Uint32 JointsDataSize = 0;
430431

431432
if (AttribsBuffDesc.Usage != USAGE_DYNAMIC)
432433
{
@@ -465,18 +466,21 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c
465466
m_PrimitiveAttribsData.data(), AttribsBufferOffset);
466467
AttribsBufferOffset = 0;
467468

468-
if (CurrJointsDataSize > 0)
469+
if (TotalJointsDataSize > 0)
469470
{
470-
VERIFY_EXPR(JointsBuffDesc.Usage == USAGE_DYNAMIC || CurrJointsDataSize <= m_JointsData.size());
471+
VERIFY_EXPR(JointsBuffDesc.Usage == USAGE_DYNAMIC || TotalJointsDataSize <= m_JointsData.size());
471472
UnmapOrUpdateBuffer(pJointsCB, JointsBuffDesc, pMappedJointsData,
472-
m_JointsData.data(), CurrJointsDataSize);
473+
m_JointsData.data(), TotalJointsDataSize);
473474
}
474-
JointsBufferOffset = 0;
475-
CurrJointsDataSize = 0;
475+
JointsBufferOffset = 0;
476+
TotalJointsDataSize = 0;
476477
// Reset the hash to force updating the joint transforms for the next draw item.
477478
// NB: we can't reuse the transforms at the existing offset because they may be
478479
// overwritten by the next draw item.
479-
XformsHash = 0;
480+
XformsHash = 0;
481+
JointCount = 0;
482+
JointsDataRange = 0;
483+
JointsDataSize = 0;
480484

481485
RenderPendingDrawItems(State);
482486
VERIFY_EXPR(m_PendingDrawItems.empty());
@@ -540,7 +544,39 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c
540544
// Restart batch when the joint transforms change
541545
MultiDrawCount = 0;
542546

543-
if (CurrJointsDataSize + JointsDataRange > JointsBuffDesc.Size)
547+
JointCount = std::min(static_cast<Uint32>(pSkinningData->Xforms->size()), MaxJointCount);
548+
JointsDataSize = State.USDRenderer.GetJointsDataSize(JointCount, PSOFlags);
549+
if (State.RendererSettings.JointsBufferMode == USD_Renderer::JOINTS_BUFFER_MODE_UNIFORM)
550+
{
551+
// RenderPBR.vsh
552+
//
553+
// struct SkinnigData
554+
// {
555+
// # if COMPUTE_MOTION_VECTORS
556+
// float4x4 Joints[MAX_JOINT_COUNT * 2];
557+
// # else
558+
// float4x4 Joints[MAX_JOINT_COUNT];
559+
// # endif
560+
// };
561+
//
562+
// Joints data range is the size of the entire structure with the maximum number of joints.
563+
JointsDataRange = State.USDRenderer.GetJointsDataSize(MaxJointCount, PSOFlags);
564+
}
565+
else if (State.RendererSettings.JointsBufferMode == USD_Renderer::JOINTS_BUFFER_MODE_STRUCTURED)
566+
{
567+
// RenderPBR.vsh
568+
//
569+
// StructuredBuffer<float4x4> g_JointTransforms;
570+
//
571+
// Joints data range is the size of the actual data.
572+
JointsDataRange = JointsDataSize;
573+
}
574+
else
575+
{
576+
UNEXPECTED("Unexpected joints buffer mode");
577+
}
578+
579+
if (TotalJointsDataSize + JointsDataRange > JointsBuffDesc.Size)
544580
{
545581
// There is not enough space for the new joint transforms.
546582
// Flush pending draws to start filling the joints buffer from the beginning.
@@ -617,11 +653,10 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c
617653
{
618654
if (pSkinningData->XformsHash != XformsHash)
619655
{
620-
VERIFY(CurrJointsDataSize + JointsDataRange <= JointsBuffDesc.Size,
656+
VERIFY(TotalJointsDataSize + JointsDataRange <= JointsBuffDesc.Size,
621657
"There must be enough space for the new joint transforms as we flush the pending draw if there is not enough space.");
622658

623-
JointsBufferOffset = CurrJointsDataSize;
624-
JointCount = std::min(static_cast<Uint32>(pSkinningData->Xforms->size()), MaxJointCount);
659+
JointsBufferOffset = TotalJointsDataSize;
625660

626661
void* pJointsData = GetBufferDataPtr(pJointsCB, JointsBuffDesc, pMappedJointsData, JointsBufferOffset, m_JointsData, JointsDataRange);
627662
if (pJointsData == nullptr)
@@ -633,10 +668,10 @@ HnRenderPass::EXECUTE_RESULT HnRenderPass::Execute(HnRenderPassState& RPState, c
633668
WriteSkinningAttribs.JointMatrices = reinterpret_cast<const float4x4*>(pSkinningData->Xforms->data());
634669
WriteSkinningAttribs.PrevJointMatrices = reinterpret_cast<const float4x4*>(PrevXforms->data());
635670

636-
void* pDataEnd = State.USDRenderer.WriteSkinningData(pJointsData, WriteSkinningAttribs);
637-
const Uint32 JointsDataSize = static_cast<Uint32>(reinterpret_cast<Uint8*>(pDataEnd) - reinterpret_cast<Uint8*>(pJointsData));
638-
VERIFY_EXPR(JointsDataSize == State.USDRenderer.GetJointsDataSize(JointCount, PSOFlags));
639-
CurrJointsDataSize = AlignUp(JointsBufferOffset + JointsDataSize, JointsBufferOffsetAlignment);
671+
void* pDataEnd = State.USDRenderer.WriteSkinningData(pJointsData, WriteSkinningAttribs);
672+
VERIFY_EXPR(JointsDataSize == static_cast<Uint32>(reinterpret_cast<Uint8*>(pDataEnd) - reinterpret_cast<Uint8*>(pJointsData)));
673+
(void)pDataEnd;
674+
TotalJointsDataSize = AlignUp(JointsBufferOffset + JointsDataSize, JointsBufferOffsetAlignment);
640675

641676
XformsHash = pSkinningData->XformsHash;
642677

0 commit comments

Comments
 (0)