Skip to content

Commit f61a2ad

Browse files
Hydrogent: moved OIT resource management from HnBeginFrameTask to HnBeginOITPassTask
1 parent a634d7f commit f61a2ad

File tree

8 files changed

+140
-95
lines changed

8 files changed

+140
-95
lines changed

Hydrogent/interface/HnRenderPassState.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ class HnRenderPassState final : public pxr::HdRenderPassState
119119
{
120120
return m_ClearDepth;
121121
}
122+
bool GetUseReverseDepth() const
123+
{
124+
return GetDepthFunc() == pxr::HdCmpFuncGreater;
125+
}
122126

123127
static constexpr Uint32 ClearDepthBit = 1u << 31u;
124128

Hydrogent/interface/HnTokens.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ namespace USD
105105
(nearestMipmapNearest)
106106

107107
#define HN_RENDER_RESOURCE_TOKENS \
108+
(camera) \
108109
(cameraAttribsBuffer) \
109110
(lightAttribsBuffer) \
110111
(offscreenColorTarget) \

Hydrogent/interface/Tasks/HnBeginFrameTask.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ class HnBeginFrameTask final : public HnTask
162162
const float2& Jitter,
163163
bool& CameraTransformDirty,
164164
bool& LoadingAnimationActive);
165-
void BindOITResources(HnRenderDelegate* RenderDelegate);
166165

167166
private:
168167
std::unordered_map<pxr::TfToken, HnRenderPassState, pxr::TfToken::HashFunctor> m_RenderPassStates;
@@ -196,8 +195,6 @@ class HnBeginFrameTask final : public HnTask
196195
double m_CurrFrameTime = 0;
197196
double m_FallBackPsoUseStartTime = -1;
198197
double m_FallBackPsoUseEndTime = -1;
199-
200-
Uint32 m_BoundOITResourcesVersion = ~0u;
201198
};
202199

203200
} // namespace USD

Hydrogent/interface/Tasks/HnBeginOITPassTask.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,17 @@
2727
#pragma once
2828

2929
#include "HnTask.hpp"
30+
#include "../interface/HnRenderPassState.hpp"
3031

3132
namespace Diligent
3233
{
3334

3435
namespace USD
3536
{
3637

38+
struct HnFrameRenderTargets;
39+
class HnRenderDelegate;
40+
3741
struct HnBeginOITPassTaskParams
3842
{
3943
constexpr bool operator==(const HnBeginOITPassTaskParams& rhs) const
@@ -62,8 +66,17 @@ class HnBeginOITPassTask final : public HnTask
6266

6367
virtual void Execute(pxr::HdTaskContext* TaskCtx) override final;
6468

69+
private:
70+
void BindOITResources(HnRenderDelegate* RenderDelegate);
71+
6572
private:
6673
pxr::HdRenderIndex* m_RenderIndex = nullptr;
74+
75+
const HnFrameRenderTargets* m_FrameTargets = nullptr; // Set in Prepare()
76+
77+
HnRenderPassState m_RenderPassState;
78+
79+
Uint32 m_BoundOITResourcesVersion = ~0u;
6780
};
6881

6982
} // namespace USD

Hydrogent/src/HnRenderDelegate.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -769,8 +769,8 @@ void HnRenderDelegate::CommitResources(pxr::HdChangeTracker* tracker)
769769
const bool EnableOIT = m_USDRenderer->GetSettings().OITLayerCount > 0;
770770
if (EnableOIT)
771771
{
772-
// OIT resource version is made dirty by HnBeginFrameTask when the frame size changes.
773-
// OIT resources will be set in the SRB by HnBeginFrameTask::Execute().
772+
// OIT resource version is made dirty by HnBeginOITPassTask when the frame size changes.
773+
// OIT resources will be set in the SRB by HnBeginOITPassTask::Execute().
774774
if (m_OITResourcesVersion != m_RenderParam->GetAttribVersion(HnRenderParam::GlobalAttrib::OITResources))
775775
{
776776
m_OITResourcesVersion = m_RenderParam->MakeAttribDirty(HnRenderParam::GlobalAttrib::OITResources);

Hydrogent/src/Tasks/HnBeginFrameTask.cpp

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,6 @@ void HnBeginFrameTask::Sync(pxr::HdSceneDelegate* Delegate,
145145
m_Params.Formats.Depth,
146146
m_Params.UseReverseDepth);
147147

148-
const TEXTURE_FORMAT OITRTVFormats[] = {USD_Renderer::OITTailFmt};
149-
m_RenderPassStates[HnRenderResourceTokens->renderPass_OITLayers].Init(
150-
OITRTVFormats,
151-
_countof(OITRTVFormats),
152-
m_Params.Formats.Depth,
153-
m_Params.UseReverseDepth);
154-
155148
(*TaskCtx)[HnRenderResourceTokens->suspendSuperSampling] = pxr::VtValue{true};
156149
}
157150
}
@@ -172,9 +165,6 @@ void HnBeginFrameTask::PrepareRenderTargets(pxr::HdRenderIndex* RenderIndex,
172165

173166
HnRenderDelegate* RenderDelegate = static_cast<HnRenderDelegate*>(RenderIndex->GetRenderDelegate());
174167

175-
const bool FrameBufferResized = (m_FrameBufferWidth != FinalTargetDesc.Width ||
176-
m_FrameBufferHeight != FinalTargetDesc.Height);
177-
178168
m_FrameBufferWidth = FinalTargetDesc.Width;
179169
m_FrameBufferHeight = FinalTargetDesc.Height;
180170

@@ -255,22 +245,6 @@ void HnBeginFrameTask::PrepareRenderTargets(pxr::HdRenderIndex* RenderIndex,
255245
m_FrameRenderTargets.ClosestSelectedLocationRTV[1] = UpdateBrim(m_ClosestSelLocnTargetId[1], m_Params.Formats.ClosestSelectedLocation, "Closest selected location 1");
256246
m_FrameRenderTargets.JitteredFinalColorRTV = UpdateBrim(m_JitteredFinalColorTargetId, m_Params.Formats.JitteredColor, "Jittered final color");
257247

258-
const USD_Renderer& Renderer = *RenderDelegate->GetUSDRenderer();
259-
if (Renderer.GetSettings().OITLayerCount > 0)
260-
{
261-
if (FrameBufferResized)
262-
{
263-
m_FrameRenderTargets.OIT = {};
264-
}
265-
266-
if (!m_FrameRenderTargets.OIT)
267-
{
268-
m_FrameRenderTargets.OIT = Renderer.CreateOITResources(FinalTargetDesc.Width, FinalTargetDesc.Height);
269-
// Mark OIT resources dirty to make render delegate recreate main pass frame attribs SRB.
270-
static_cast<HnRenderParam*>(RenderDelegate->GetRenderParam())->MakeAttribDirty(HnRenderParam::GlobalAttrib::OITResources);
271-
}
272-
}
273-
274248
(*TaskCtx)[HnRenderResourceTokens->frameRenderTargets] = pxr::VtValue{&m_FrameRenderTargets};
275249

276250
// Set render pass render targets
@@ -306,21 +280,6 @@ void HnBeginFrameTask::PrepareRenderTargets(pxr::HdRenderIndex* RenderIndex,
306280
RPState->SetCamera(m_pCamera);
307281
}
308282

309-
if (Renderer.GetSettings().OITLayerCount > 0)
310-
{
311-
HnRenderPassState& RP_OITLayers = m_RenderPassStates[HnRenderResourceTokens->renderPass_OITLayers];
312-
313-
ITextureView* OITRTVs[] = {m_FrameRenderTargets.OIT.Tail->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET)};
314-
const float4 TailClearValue{
315-
0, // Layer counter
316-
0, // Unused
317-
0, // Unused
318-
1, // Total tail transmittance
319-
};
320-
RP_OITLayers.Begin(_countof(OITRTVs), OITRTVs, m_FrameRenderTargets.DepthDSV, &TailClearValue, 0, 0x01u);
321-
RP_OITLayers.SetCamera(m_pCamera);
322-
}
323-
324283
// Register render pass states in the task context
325284
for (auto& it : m_RenderPassStates)
326285
{
@@ -388,6 +347,7 @@ void HnBeginFrameTask::Prepare(pxr::HdTaskContext* TaskCtx,
388347
{
389348
LOG_ERROR_MESSAGE("Camera is not set at Id ", m_Params.CameraId);
390349
}
350+
(*TaskCtx)[HnRenderResourceTokens->camera] = pxr::VtValue{static_cast<const HnCamera*>(m_pCamera)};
391351
}
392352
else
393353
{
@@ -720,39 +680,6 @@ void HnBeginFrameTask::UpdateFrameConstants(IDeviceContext* pCtx,
720680
pCtx->TransitionResourceStates(static_cast<Uint32>(Barriers.size()), Barriers.data());
721681
}
722682

723-
void HnBeginFrameTask::BindOITResources(HnRenderDelegate* RenderDelegate)
724-
{
725-
HnRenderParam* RenderParam = static_cast<HnRenderParam*>(RenderDelegate->GetRenderParam());
726-
if (m_BoundOITResourcesVersion == RenderParam->GetAttribVersion(HnRenderParam::GlobalAttrib::OITResources))
727-
return;
728-
729-
if (!m_FrameRenderTargets.OIT)
730-
{
731-
UNEXPECTED("OIT resources are not initialized. This likely indicates that Prepare() has not been called.");
732-
return;
733-
}
734-
735-
USD_Renderer& Renderer = *RenderDelegate->GetUSDRenderer();
736-
if (IShaderResourceBinding* pFrameAttribsSRB = RenderDelegate->GetFrameAttribsSRB(HnRenderDelegate::FrameAttribsSRBType::Transparent))
737-
{
738-
Renderer.SetOITResources(pFrameAttribsSRB, m_FrameRenderTargets.OIT);
739-
m_BoundOITResourcesVersion = RenderParam->GetAttribVersion(HnRenderParam::GlobalAttrib::OITResources);
740-
}
741-
else
742-
{
743-
UNEXPECTED("Main pass frame attribs SRB is null");
744-
}
745-
746-
IDeviceContext* pCtx = RenderDelegate->GetDeviceContext();
747-
748-
StateTransitionDesc Barriers[] =
749-
{
750-
{m_FrameRenderTargets.OIT.Layers, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE, STATE_TRANSITION_FLAG_UPDATE_STATE},
751-
{m_FrameRenderTargets.OIT.Tail, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE, STATE_TRANSITION_FLAG_UPDATE_STATE},
752-
};
753-
pCtx->TransitionResourceStates(_countof(Barriers), Barriers);
754-
}
755-
756683
void HnBeginFrameTask::Execute(pxr::HdTaskContext* TaskCtx)
757684
{
758685
if (m_RenderIndex == nullptr)
@@ -768,11 +695,6 @@ void HnBeginFrameTask::Execute(pxr::HdTaskContext* TaskCtx)
768695

769696
ScopedDebugGroup DebugGroup{pCtx, "Begin Frame"};
770697

771-
if (Renderer.GetSettings().OITLayerCount > 0)
772-
{
773-
BindOITResources(RenderDelegate);
774-
}
775-
776698
// NB: we can't move the buffer update to Prepare() because we need TAA parameters
777699
// that are set by HnPostProcessTask::Prepare().
778700
if (IBuffer* pFrameAttribsCB = RenderDelegate->GetFrameAttribsCB())

Hydrogent/src/Tasks/HnBeginOITPassTask.cpp

Lines changed: 117 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
#include "ScopedDebugGroup.hpp"
3030
#include "HnTokens.hpp"
3131
#include "HnRenderPassState.hpp"
32+
#include "HnFrameRenderTargets.hpp"
33+
#include "HnCamera.hpp"
34+
#include "HnRenderParam.hpp"
3235

3336
namespace Diligent
3437
{
@@ -56,6 +59,111 @@ void HnBeginOITPassTask::Prepare(pxr::HdTaskContext* TaskCtx,
5659
pxr::HdRenderIndex* RenderIndex)
5760
{
5861
m_RenderIndex = RenderIndex;
62+
63+
HnFrameRenderTargets* FrameTargets = GetFrameRenderTargets(TaskCtx);
64+
if (FrameTargets == nullptr)
65+
{
66+
UNEXPECTED("Framebuffer targets are null");
67+
return;
68+
}
69+
m_FrameTargets = FrameTargets;
70+
71+
ITextureView* pColorRTV = FrameTargets->GBufferRTVs[HnFrameRenderTargets::GBUFFER_TARGET_SCENE_COLOR];
72+
if (pColorRTV == nullptr)
73+
{
74+
UNEXPECTED("Scene color target is null");
75+
return;
76+
}
77+
78+
const TextureDesc& ColorTargetDesc = pColorRTV->GetTexture()->GetDesc();
79+
if (FrameTargets->OIT)
80+
{
81+
const TextureDesc& OITDesc = FrameTargets->OIT.Tail->GetDesc();
82+
if (OITDesc.Width != ColorTargetDesc.Width || OITDesc.Height != ColorTargetDesc.Height)
83+
{
84+
FrameTargets->OIT = {};
85+
}
86+
}
87+
88+
HnRenderDelegate* RenderDelegate = static_cast<HnRenderDelegate*>(RenderIndex->GetRenderDelegate());
89+
90+
const USD_Renderer& Renderer = *RenderDelegate->GetUSDRenderer();
91+
VERIFY_EXPR(Renderer.GetSettings().OITLayerCount > 0);
92+
93+
if (!FrameTargets->OIT)
94+
{
95+
FrameTargets->OIT = Renderer.CreateOITResources(ColorTargetDesc.Width, ColorTargetDesc.Height);
96+
// Mark OIT resources dirty to make render delegate recreate transparent pass frame attribs SRB.
97+
// We will set the OIT resources in the SBR in Execute().
98+
static_cast<HnRenderParam*>(RenderDelegate->GetRenderParam())->MakeAttribDirty(HnRenderParam::GlobalAttrib::OITResources);
99+
}
100+
101+
bool UseReverseDepth = false;
102+
GetTaskContextData(TaskCtx, HnRenderResourceTokens->useReverseDepth, UseReverseDepth);
103+
104+
const TEXTURE_FORMAT DepthFormat = FrameTargets->DepthDSV->GetTexture()->GetDesc().Format;
105+
if (m_RenderPassState.GetDepthStencilFormat() != DepthFormat ||
106+
m_RenderPassState.GetUseReverseDepth() != UseReverseDepth)
107+
{
108+
const TEXTURE_FORMAT OITRTVFormats[] = {USD_Renderer::OITTailFmt};
109+
m_RenderPassState.Init(
110+
OITRTVFormats,
111+
_countof(OITRTVFormats),
112+
DepthFormat,
113+
UseReverseDepth);
114+
}
115+
116+
ITextureView* OITRTVs[] = {FrameTargets->OIT.Tail->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET)};
117+
const float4 TailClearValue{
118+
0, // Layer counter
119+
0, // Unused
120+
0, // Unused
121+
1, // Total tail transmittance
122+
};
123+
m_RenderPassState.Begin(_countof(OITRTVs), OITRTVs, FrameTargets->DepthDSV, &TailClearValue, 0, 0x01u);
124+
125+
const HnCamera* pCamera = nullptr;
126+
if (GetTaskContextData(TaskCtx, HnRenderResourceTokens->camera, pCamera))
127+
{
128+
m_RenderPassState.SetCamera(pCamera);
129+
}
130+
131+
(*TaskCtx)[HnRenderResourceTokens->renderPass_OITLayers] = pxr::VtValue{&m_RenderPassState};
132+
}
133+
134+
135+
void HnBeginOITPassTask::BindOITResources(HnRenderDelegate* RenderDelegate)
136+
{
137+
if (m_FrameTargets == nullptr)
138+
{
139+
UNEXPECTED("Frame targets are null. This likely indicates that Prepare() has not been called.");
140+
return;
141+
}
142+
143+
if (!m_FrameTargets->OIT)
144+
{
145+
UNEXPECTED("OIT resources are not initialized. This likely indicates that Prepare() has not been called.");
146+
return;
147+
}
148+
149+
USD_Renderer& Renderer = *RenderDelegate->GetUSDRenderer();
150+
if (IShaderResourceBinding* pFrameAttribsSRB = RenderDelegate->GetFrameAttribsSRB(HnRenderDelegate::FrameAttribsSRBType::Transparent))
151+
{
152+
Renderer.SetOITResources(pFrameAttribsSRB, m_FrameTargets->OIT);
153+
}
154+
else
155+
{
156+
UNEXPECTED("Main pass frame attribs SRB is null");
157+
}
158+
159+
IDeviceContext* pCtx = RenderDelegate->GetDeviceContext();
160+
161+
StateTransitionDesc Barriers[] =
162+
{
163+
{m_FrameTargets->OIT.Layers, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE, STATE_TRANSITION_FLAG_UPDATE_STATE},
164+
{m_FrameTargets->OIT.Tail, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE, STATE_TRANSITION_FLAG_UPDATE_STATE},
165+
};
166+
pCtx->TransitionResourceStates(_countof(Barriers), Barriers);
59167
}
60168

61169
void HnBeginOITPassTask::Execute(pxr::HdTaskContext* TaskCtx)
@@ -69,17 +177,17 @@ void HnBeginOITPassTask::Execute(pxr::HdTaskContext* TaskCtx)
69177
HnRenderDelegate* RenderDelegate = static_cast<HnRenderDelegate*>(m_RenderIndex->GetRenderDelegate());
70178
IDeviceContext* pCtx = RenderDelegate->GetDeviceContext();
71179

72-
ScopedDebugGroup DebugGroup{pCtx, "Begin OIT pass"};
73-
74-
if (HnRenderPassState* RP_OITLayers = GetRenderPassState(TaskCtx, HnRenderResourceTokens->renderPass_OITLayers))
180+
HnRenderParam* RenderParam = static_cast<HnRenderParam*>(RenderDelegate->GetRenderParam());
181+
if (m_BoundOITResourcesVersion != RenderParam->GetAttribVersion(HnRenderParam::GlobalAttrib::OITResources))
75182
{
76-
RP_OITLayers->SetFrameAttribsSRB(RenderDelegate->GetFrameAttribsSRB(HnRenderDelegate::FrameAttribsSRBType::OITLayers));
77-
RP_OITLayers->Commit(pCtx);
78-
}
79-
else
80-
{
81-
UNEXPECTED("OIT layers render pass state is not set in the task context");
183+
BindOITResources(RenderDelegate);
184+
m_BoundOITResourcesVersion = RenderParam->GetAttribVersion(HnRenderParam::GlobalAttrib::OITResources);
82185
}
186+
187+
ScopedDebugGroup DebugGroup{pCtx, "Begin OIT pass"};
188+
189+
m_RenderPassState.SetFrameAttribsSRB(RenderDelegate->GetFrameAttribsSRB(HnRenderDelegate::FrameAttribsSRBType::OITLayers));
190+
m_RenderPassState.Commit(pCtx);
83191
}
84192

85193
} // namespace USD

Hydrogent/src/Tasks/HnRenderRprimsTask.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 Diligent Graphics LLC
2+
* Copyright 2023-2025 Diligent Graphics LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -136,7 +136,7 @@ void HnRenderRprimsTask::Execute(pxr::HdTaskContext* TaskCtx)
136136
}
137137
else
138138
{
139-
UNEXPECTED("Render pass state is null. This likely indicates that HnBeginFrameTask was not been created or executed.");
139+
UNEXPECTED("Render pass state is null. This likely indicates that HnBeginFrameTask has not been created or executed.");
140140
}
141141
}
142142
}

0 commit comments

Comments
 (0)