Skip to content

Commit

Permalink
Hydrogent: added off-screen render target initialization as Bprims
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Oct 22, 2023
1 parent 730d7a2 commit 133c563
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 38 deletions.
14 changes: 11 additions & 3 deletions Hydrogent/include/HnRenderBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ class HnRenderDelegate;
class HnRenderBuffer final : public pxr::HdRenderBuffer
{
public:
HnRenderBuffer(const pxr::SdfPath& Id);
HnRenderBuffer(const pxr::SdfPath& Id, const HnRenderDelegate* RnederDelegate);
HnRenderBuffer(const pxr::SdfPath& Id, ITexture* pTexture);
HnRenderBuffer(const pxr::SdfPath& Id, ITextureView* pTarget);

~HnRenderBuffer() override;

// Allocate a buffer. Can be called from Sync(), or directly.
Expand Down Expand Up @@ -99,13 +101,19 @@ class HnRenderBuffer final : public pxr::HdRenderBuffer
// other parts of Hydra, such as a HdTask to get access to this resource.
virtual pxr::VtValue GetResource(bool MultiSampled) const override final;

void SetTarget(ITextureView* pTarget);

void ReleaseTarget();

ITextureView* GetTarget() const { return m_pTarget; }

protected:
// Deallocate the buffer, freeing any owned resources.
virtual void _Deallocate() override final;

private:
RefCntAutoPtr<ITexture> m_pTexture;
const HnRenderDelegate* const m_RenderDelegate = nullptr;
RefCntAutoPtr<ITextureView> m_pTarget;
const HnRenderDelegate* m_RenderDelegate = nullptr;
};

} // namespace USD
Expand Down
2 changes: 2 additions & 0 deletions Hydrogent/include/HnRenderDelegate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ class HnRenderDelegate final : public pxr::HdRenderDelegate
std::unordered_map<pxr::SdfPath, std::shared_ptr<HnMaterial>, pxr::SdfPath::Hash> m_Materials;
std::unordered_map<pxr::SdfPath, std::shared_ptr<HnMesh>, pxr::SdfPath::Hash> m_Meshes;
std::unordered_map<Uint32, pxr::SdfPath> m_MeshUIDToPrimId;

std::unordered_map<pxr::HdBprim*, std::unique_ptr<pxr::HdBprim>> m_BPrims;
};

} // namespace USD
Expand Down
2 changes: 2 additions & 0 deletions Hydrogent/include/HnRendererImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ class HnRendererImpl final : public ObjectBase<IHnRenderer>

HnRenderParams m_RenderParams;
bool m_RenderParamsChanged = true;

pxr::SdfPath m_FinalColorTargetId;
};

} // namespace USD
Expand Down
10 changes: 10 additions & 0 deletions Hydrogent/include/HnTokens.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ namespace USD
(linearMipmapNearest) \
(nearestMipmapLinear) \
(nearestMipmapNearest)

#define HN_RENDER_RESOURCE_TOKENS \
(cameraAttribsBuffer) \
(lightAttribsBuffer) \
(offscreenColorTarget) \
(finalColorTarget) \
(meshIdTarget) \
(depthBuffer)

// clang-format on

using TfToken = pxr::TfToken;
Expand All @@ -108,6 +117,7 @@ TF_DECLARE_PUBLIC_TOKENS(HnMaterialTagTokens, HN_MATERIAL_TAG_TOKENS);
TF_DECLARE_PUBLIC_TOKENS(HnSdrMetadataTokens, HN_SDR_METADATA_TOKENS);
TF_DECLARE_PUBLIC_TOKENS(HnTextureTokens, HN_TEXTURE_TOKENS);
TF_DECLARE_PUBLIC_TOKENS(HnTokens, HN_TOKENS);
TF_DECLARE_PUBLIC_TOKENS(HnRenderResourceTokens, HN_RENDER_RESOURCE_TOKENS);

} // namespace USD

Expand Down
11 changes: 10 additions & 1 deletion Hydrogent/include/Tasks/HnSetupRenderingTask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ struct HnSetupRenderingTaskParams
StencilFailOp == rhs.StencilFailOp &&
StencilZFailOp == rhs.StencilZFailOp &&
StencilZPassOp == rhs.StencilZPassOp &&
StencilEnabled == rhs.StencilEnabled;
StencilEnabled == rhs.StencilEnabled &&
FinalColorTargetId == rhs.FinalColorTargetId;
// clang-format on
}
constexpr bool operator!=(const HnSetupRenderingTaskParams& rhs) const
Expand Down Expand Up @@ -106,6 +107,8 @@ struct HnSetupRenderingTaskParams
pxr::HdStencilOp StencilZFailOp = pxr::HdStencilOpKeep;
pxr::HdStencilOp StencilZPassOp = pxr::HdStencilOpKeep;
bool StencilEnabled = false;

pxr::SdfPath FinalColorTargetId;
};

/// Post processing task implementation in Hydrogent.
Expand All @@ -127,9 +130,15 @@ class HnSetupRenderingTask final : public HnTask

private:
void UpdateRenderPassState(const HnSetupRenderingTaskParams& Params);
void PrepareRenderTargets(pxr::HdRenderIndex* RenderIndex, pxr::HdTaskContext* TaskCtx, ITextureView* pFinalColorRTV);

private:
std::shared_ptr<HnRenderPassState> m_RenderPassState;

pxr::SdfPath m_FinalColorTargetId;
pxr::SdfPath m_OffscreenColorTargetId;
pxr::SdfPath m_MeshIdTargetId;
pxr::SdfPath m_DepthBufferId;
};

} // namespace USD
Expand Down
79 changes: 57 additions & 22 deletions Hydrogent/src/HnRenderBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,20 @@ namespace Diligent
namespace USD
{

HnRenderBuffer::HnRenderBuffer(const pxr::SdfPath& Id) :
pxr::HdRenderBuffer{Id}
{
}

HnRenderBuffer::HnRenderBuffer(const pxr::SdfPath& Id, const HnRenderDelegate* RnederDelegate) :
pxr::HdRenderBuffer{Id},
m_RenderDelegate{RnederDelegate}
{
}

HnRenderBuffer::HnRenderBuffer(const pxr::SdfPath& Id, ITexture* pTexture) :
HnRenderBuffer::HnRenderBuffer(const pxr::SdfPath& Id, ITextureView* pTarget) :
pxr::HdRenderBuffer{Id},
m_pTexture{pTexture}
m_pTarget{pTarget}
{
}

Expand All @@ -57,6 +62,9 @@ bool HnRenderBuffer::Allocate(const pxr::GfVec3i& Dimensions,
pxr::HdFormat Format,
bool MultiSampled)
{
if (!(Dimensions[0] > 0 && Dimensions[1] > 0 && Format != pxr::HdFormatInvalid))
return false;

if (m_RenderDelegate == nullptr)
{
UNEXPECTED("Texture cannot be allocated without render delegate");
Expand All @@ -73,52 +81,69 @@ bool HnRenderBuffer::Allocate(const pxr::GfVec3i& Dimensions,
TexDesc.MipLevels = 1;
TexDesc.Format = HdFormatToTextureFormat(Format);

const auto FmtAttribs = GetTextureFormatAttribs(TexDesc.Format);
if (FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH || FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL)
TexDesc.BindFlags = BIND_DEPTH_STENCIL;
else
TexDesc.BindFlags = BIND_RENDER_TARGET;
TexDesc.BindFlags |= BIND_SHADER_RESOURCE;
const auto IsDepth = GetTextureFormatAttribs(TexDesc.Format).IsDepthStencil();
TexDesc.BindFlags = (IsDepth ? BIND_DEPTH_STENCIL : BIND_RENDER_TARGET) | BIND_SHADER_RESOURCE;

TexDesc.Usage = USAGE_DEFAULT;
TexDesc.SampleCount = MultiSampled ? 4 : 1;

if (m_pTexture && m_pTexture->GetDesc() == TexDesc)
if (m_pTarget && m_pTarget->GetTexture()->GetDesc() == TexDesc)
return true;

m_pTexture.Release();
auto* pDevice = static_cast<const HnRenderDelegate*>(m_RenderDelegate)->GetDevice();
pDevice->CreateTexture(TexDesc, nullptr, &m_pTexture);
VERIFY(m_pTexture, "Failed to create render buffer texture ", Name);
m_pTarget.Release();
auto* const pDevice = static_cast<const HnRenderDelegate*>(m_RenderDelegate)->GetDevice();

RefCntAutoPtr<ITexture> pTexture;
pDevice->CreateTexture(TexDesc, nullptr, &pTexture);
if (!pTexture)
{
UNEXPECTED("Failed to create render buffer texture ", Name);
return false;
}

m_pTarget = pTexture->GetDefaultView(IsDepth ? TEXTURE_VIEW_DEPTH_STENCIL : TEXTURE_VIEW_RENDER_TARGET);
VERIFY(m_pTarget, "Failed to get default view for render buffer texture ", Name);

return m_pTexture != nullptr;
return m_pTarget != nullptr;
}

unsigned int HnRenderBuffer::GetWidth() const
{
return m_pTexture ? m_pTexture->GetDesc().GetWidth() : 0;
if (!m_pTarget)
return 0;

const auto MipLevelProps = GetMipLevelProperties(m_pTarget->GetTexture()->GetDesc(), m_pTarget->GetDesc().MostDetailedMip);
return MipLevelProps.LogicalWidth;
}

unsigned int HnRenderBuffer::GetHeight() const
{
return m_pTexture ? m_pTexture->GetDesc().GetHeight() : 0;
if (!m_pTarget)
return 0;

const auto MipLevelProps = GetMipLevelProperties(m_pTarget->GetTexture()->GetDesc(), m_pTarget->GetDesc().MostDetailedMip);
return MipLevelProps.LogicalHeight;
}

unsigned int HnRenderBuffer::GetDepth() const
{
return m_pTexture ? m_pTexture->GetDesc().GetDepth() : 0;
if (!m_pTarget)
return 0;

const auto MipLevelProps = GetMipLevelProperties(m_pTarget->GetTexture()->GetDesc(), m_pTarget->GetDesc().MostDetailedMip);
return MipLevelProps.Depth;
}

pxr::HdFormat HnRenderBuffer::GetFormat() const
{
return m_pTexture ?
TextureFormatToHdFormat(m_pTexture->GetDesc().Format) :
return m_pTarget ?
TextureFormatToHdFormat(m_pTarget->GetDesc().Format) :
pxr::HdFormatInvalid;
}

bool HnRenderBuffer::IsMultiSampled() const
{
return m_pTexture ? m_pTexture->GetDesc().SampleCount > 1 : false;
return m_pTarget ? m_pTarget->GetTexture()->GetDesc().SampleCount > 1 : false;
}

void* HnRenderBuffer::Map()
Expand Down Expand Up @@ -147,12 +172,22 @@ bool HnRenderBuffer::IsConverged() const

pxr::VtValue HnRenderBuffer::GetResource(bool MultiSampled) const
{
return m_pTexture ? pxr::VtValue{m_pTexture.RawPtr()} : pxr::VtValue{};
return m_pTarget ? pxr::VtValue{m_pTarget.RawPtr()} : pxr::VtValue{};
}

void HnRenderBuffer::_Deallocate()
{
m_pTexture.Release();
m_pTarget.Release();
}

void HnRenderBuffer::SetTarget(ITextureView* pTarget)
{
m_pTarget = pTarget;
}

void HnRenderBuffer::ReleaseTarget()
{
m_pTarget.Release();
}

} // namespace USD
Expand Down
10 changes: 10 additions & 0 deletions Hydrogent/src/HnRenderDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "HnRenderPass.hpp"
#include "DebugUtilities.hpp"
#include "USD_Renderer.hpp"
#include "HnRenderBuffer.hpp"

#include "pxr/imaging/hd/material.h"

Expand Down Expand Up @@ -58,6 +59,7 @@ const pxr::TfTokenVector HnRenderDelegate::SupportedSPrimTypes =

const pxr::TfTokenVector HnRenderDelegate::SupportedBPrimTypes =
{
pxr::HdPrimTypeTokens->renderBuffer
};
// clang-format on

Expand Down Expand Up @@ -190,6 +192,13 @@ void HnRenderDelegate::DestroySprim(pxr::HdSprim* sprim)
pxr::HdBprim* HnRenderDelegate::CreateBprim(pxr::TfToken const& typeId,
pxr::SdfPath const& bprimId)
{
if (typeId == pxr::HdPrimTypeTokens->renderBuffer)
{
auto RenderBuffer = std::make_unique<HnRenderBuffer>(bprimId);
auto* BPrim = RenderBuffer.get();
m_BPrims.emplace(BPrim, std::move(RenderBuffer));
return BPrim;
}
return nullptr;
}

Expand All @@ -200,6 +209,7 @@ pxr::HdBprim* HnRenderDelegate::CreateFallbackBprim(pxr::TfToken const& typeId)

void HnRenderDelegate::DestroyBprim(pxr::HdBprim* bprim)
{
m_BPrims.erase(bprim);
}

void HnRenderDelegate::CommitResources(pxr::HdChangeTracker* tracker)
Expand Down
32 changes: 22 additions & 10 deletions Hydrogent/src/HnRendererImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@
#include "MapHelper.hpp"
#include "CommonlyUsedStates.h"
#include "HnShaderSourceFactory.hpp"
#include "HnRenderBuffer.hpp"

#include "pxr/imaging/hd/task.h"
#include "pxr/imaging/hd/tokens.h"
#include "pxr/imaging/hd/renderPass.h"

namespace Diligent
Expand Down Expand Up @@ -110,6 +112,9 @@ void HnRendererImpl::LoadUSDStage(pxr::UsdStageRefPtr& Stage)

const pxr::SdfPath TaskControllerId = SceneDelegateId.AppendChild(pxr::TfToken{"_HnTaskController_"});
m_TaskController = std::make_unique<HnTaskController>(*m_RenderIndex, TaskControllerId);

m_FinalColorTargetId = SceneDelegateId.AppendChild(pxr::TfToken{"_HnFinalColorTarget_"});
m_RenderIndex->InsertBprim(pxr::HdPrimTypeTokens->renderBuffer, m_ImagingDelegate.get(), m_FinalColorTargetId);
}

void HnRendererImpl::SetParams(const HnRenderParams& Params)
Expand All @@ -126,16 +131,17 @@ void HnRendererImpl::Update()
if (m_RenderParamsChanged)
{
HnSetupRenderingTaskParams Params;
Params.ColorFormat = ColorBufferFormat;
Params.MeshIdFormat = MeshIdFormat;
Params.DepthFormat = DepthFormat;
Params.RenderMode = m_RenderParams.RenderMode;
Params.FrontFaceCCW = m_RenderParams.FrontFaceCCW;
Params.DebugView = m_RenderParams.DebugView;
Params.OcclusionStrength = m_RenderParams.OcclusionStrength;
Params.EmissionScale = m_RenderParams.EmissionScale;
Params.IBLScale = m_RenderParams.IBLScale;
Params.Transform = m_RenderParams.Transform;
Params.ColorFormat = ColorBufferFormat;
Params.MeshIdFormat = MeshIdFormat;
Params.DepthFormat = DepthFormat;
Params.RenderMode = m_RenderParams.RenderMode;
Params.FrontFaceCCW = m_RenderParams.FrontFaceCCW;
Params.DebugView = m_RenderParams.DebugView;
Params.OcclusionStrength = m_RenderParams.OcclusionStrength;
Params.EmissionScale = m_RenderParams.EmissionScale;
Params.IBLScale = m_RenderParams.IBLScale;
Params.Transform = m_RenderParams.Transform;
Params.FinalColorTargetId = m_FinalColorTargetId;
m_TaskController->SetTaskParams(HnTaskController::TaskUID_SetupRendering, Params);

m_RenderParamsChanged = false;
Expand Down Expand Up @@ -246,6 +252,10 @@ void HnRendererImpl::Draw(IDeviceContext* pCtx, const HnDrawAttribs& Attribs)
if (!m_RenderDelegate)
return;

auto* FinalColorTarget = static_cast<HnRenderBuffer*>(m_RenderIndex->GetBprim(pxr::HdPrimTypeTokens->renderBuffer, m_FinalColorTargetId));
VERIFY_EXPR(FinalColorTarget != nullptr);
FinalColorTarget->SetTarget(Attribs.pDstRTV);

PrepareRenderTargets(Attribs.pDstRTV);
PreparePostProcess(Attribs.pDstRTV->GetDesc().Format);

Expand All @@ -266,6 +276,8 @@ void HnRendererImpl::Draw(IDeviceContext* pCtx, const HnDrawAttribs& Attribs)
pxr::HdTaskSharedPtrVector tasks = m_TaskController->GetTasks();
m_Engine.Execute(&m_ImagingDelegate->GetRenderIndex(), &tasks);

FinalColorTarget->ReleaseTarget();

PerformPostProcess(pCtx, Attribs);
}

Expand Down
1 change: 1 addition & 0 deletions Hydrogent/src/HnTokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ TF_DEFINE_PUBLIC_TOKENS(HnMaterialTagTokens, HN_MATERIAL_TAG_TOKENS);
TF_DEFINE_PUBLIC_TOKENS(HnSdrMetadataTokens, HN_SDR_METADATA_TOKENS);
TF_DEFINE_PUBLIC_TOKENS(HnTextureTokens, HN_TEXTURE_TOKENS);
TF_DEFINE_PUBLIC_TOKENS(HnTokens, HN_TOKENS);
TF_DEFINE_PUBLIC_TOKENS(HnRenderResourceTokens, HN_RENDER_RESOURCE_TOKENS);

} // namespace USD

Expand Down
Loading

0 comments on commit 133c563

Please sign in to comment.