Skip to content

Commit

Permalink
Hydrogent: implemented render pass state handling
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Oct 22, 2023
1 parent b46f0a6 commit 5867ed0
Show file tree
Hide file tree
Showing 13 changed files with 415 additions and 205 deletions.
1 change: 1 addition & 0 deletions Hydrogent/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ set(INCLUDE
)

set(INTERFACE
interface/HnTypes.hpp
interface/HnRenderer.hpp
)

Expand Down
8 changes: 5 additions & 3 deletions Hydrogent/include/HnRenderPass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ namespace USD

class HnMesh;
class HnMaterial;
class HnRenderPassState;

/// Hydra render pass implementation in Hydrogent.
class HnRenderPass final : public pxr::HdRenderPass
Expand All @@ -62,9 +63,10 @@ class HnRenderPass final : public pxr::HdRenderPass
private:
void UpdateDrawItems(const pxr::TfTokenVector& RenderTags);

void RenderMesh(IDeviceContext* pCtx,
const HnMesh& Mesh,
const HnMaterial& Material);
void RenderMesh(IDeviceContext* pCtx,
const HnRenderPassState& State,
const HnMesh& Mesh,
const HnMaterial& Material);

private:
std::shared_ptr<USD_Renderer> m_USDRenderer;
Expand Down
81 changes: 76 additions & 5 deletions Hydrogent/include/HnRenderPassState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@

#pragma once

#include <array>

#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RasterizerState.h"
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/BlendState.h"
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DepthStencilState.h"
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/PipelineState.h"
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"

#include "../interface/HnTypes.hpp"

#include "pxr/imaging/hd/types.h"
#include "pxr/imaging/hd/renderPassState.h"

Expand All @@ -51,24 +55,91 @@ class HnRenderPassState final : public pxr::HdRenderPassState

void Begin(IDeviceContext* pContext);

void SetColorFormat(TEXTURE_FORMAT ColorFormat)
void SetRTVFormat(Uint32 RT, TEXTURE_FORMAT Fmt)
{
m_ColorFormat = ColorFormat;
m_RTVFormats[RT] = Fmt;
}
void SetDepthFormat(TEXTURE_FORMAT DepthFormat)
{
m_DepthFormat = DepthFormat;
}
void SetNumRenderTargets(Uint32 NumRTs)
{
m_NumRenderTargets = NumRTs;
}

void SetRenderMode(HN_RENDER_MODE RenderMode)
{
m_RenderMode = RenderMode;
}
HN_RENDER_MODE GetRenderMode() const
{
return m_RenderMode;
}

void SetDebugView(int DebugView)
{
m_DebugView = DebugView;
}
int GetDebugView() const
{
return m_DebugView;
}

void SetOcclusionStrength(float OcclusionStrength)
{
m_OcclusionStrength = OcclusionStrength;
}
float GetOcclusionStrength() const
{
return m_OcclusionStrength;
}

void SetEmissionScale(float EmissionScale)
{
m_EmissionScale = EmissionScale;
}
float GetEmissionScale() const
{
return m_EmissionScale;
}

void SetIBLScale(float IBLScale)
{
m_IBLScale = IBLScale;
}
float GetIBLScale() const
{
return m_IBLScale;
}

void SetTransform(const float4x4& Transform)
{
m_Transform = Transform;
}
const float4x4& GetTransform() const
{
return m_Transform;
}

private:
RasterizerStateDesc GetRasterizerState() const;
DepthStencilStateDesc GetDepthStencilState() const;
BlendStateDesc GetBlendState() const;
GraphicsPipelineDesc GetGraphicsPipelineDesc() const;

private:
TEXTURE_FORMAT m_ColorFormat = TEX_FORMAT_UNKNOWN;
TEXTURE_FORMAT m_DepthFormat = TEX_FORMAT_UNKNOWN;
Uint32 m_NumRenderTargets = 0;
std::array<TEXTURE_FORMAT, MAX_RENDER_TARGETS> m_RTVFormats = {};
TEXTURE_FORMAT m_DepthFormat = TEX_FORMAT_UNKNOWN;

HN_RENDER_MODE m_RenderMode = HN_RENDER_MODE_SOLID;

int m_DebugView = 0;
float m_OcclusionStrength = 1;
float m_EmissionScale = 1;
float m_IBLScale = 1;

float4x4 m_Transform = float4x4::Identity();
};

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

virtual void LoadUSDStage(pxr::UsdStageRefPtr& Stage) override final;
virtual void Update() override final;
virtual void SetParams(const HnRenderParams& Params) override final;
virtual void Draw(IDeviceContext* pCtx, const HnDrawAttribs& Attribs) override final;
virtual void SetEnvironmentMap(IDeviceContext* pCtx, ITextureView* pEnvironmentMapSRV) override final;

Expand Down Expand Up @@ -124,6 +125,9 @@ class HnRendererImpl final : public ObjectBase<IHnRenderer>
RefCntAutoPtr<IShaderResourceBinding> SRB;
};
PostProcessState m_PostProcess;

HnRenderParams m_RenderParams;
bool m_RenderParamsChanged = true;
};

} // namespace USD
Expand Down
22 changes: 21 additions & 1 deletion Hydrogent/include/Tasks/HnSetupRenderingTask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <memory>

#include "HnTask.hpp"
#include "../interface/HnTypes.hpp"

namespace Diligent
{
Expand All @@ -42,12 +43,28 @@ struct HnSetupRenderingTaskParams
{
constexpr bool operator==(const HnSetupRenderingTaskParams& rhs) const
{
return true;
// clang-format off
return RenderMode == rhs.RenderMode &&
DebugView == rhs.DebugView &&
OcclusionStrength == rhs.OcclusionStrength &&
EmissionScale == rhs.EmissionScale &&
IBLScale == rhs.IBLScale &&
Transform == rhs.Transform;
// clang-format on
}
constexpr bool operator!=(const HnSetupRenderingTaskParams& rhs) const
{
return !(*this == rhs);
}

HN_RENDER_MODE RenderMode = HN_RENDER_MODE_SOLID;

int DebugView = 0;
float OcclusionStrength = 1;
float EmissionScale = 1;
float IBLScale = 1;

float4x4 Transform = float4x4::Identity();
};

/// Post processing task implementation in Hydrogent.
Expand All @@ -67,6 +84,9 @@ class HnSetupRenderingTask final : public HnTask

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

private:
void UpdateRenderPassState(const HnSetupRenderingTaskParams& Params);

private:
std::shared_ptr<HnRenderPassState> m_RenderPassState;
};
Expand Down
118 changes: 105 additions & 13 deletions Hydrogent/include/Tasks/HnTaskController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

#pragma once

#include <memory>
#include <unordered_map>
#include <vector>

Expand All @@ -40,7 +39,7 @@ namespace Diligent
namespace USD
{

struct HnRenderRprimsTaskParams;
struct HnSetupRenderingTaskParams;
struct HnPostProcessTaskParams;

/// Task controller implementation in Hydrogent.
Expand Down Expand Up @@ -84,17 +83,15 @@ class HnTaskController
/// Sets new collection for the render tasks.
void SetCollection(const pxr::HdRprimCollection& Collection);

/// Sets new params for the render tasks.
void SetRenderParams(const HnRenderRprimsTaskParams& Params);

/// Sets new params for the post-process task.
void SetPostProcessParams(const HnPostProcessTaskParams& Params);

/// Sets new render tags for the render tasks.
void SetRenderTags(const pxr::TfTokenVector& RenderTags);

/// Sets the parameter value
void SetParameter(const pxr::SdfPath& Id, const pxr::TfToken& ValueKey, pxr::VtValue Value);
void SetParameter(const pxr::SdfPath& TaskId, const pxr::TfToken& ValueKey, pxr::VtValue Value);

/// Sets the parameter value
template <typename ParamterType>
void SetParameter(const pxr::SdfPath& TaskId, const pxr::TfToken& ValueKey, ParamterType&& Value);

/// Creates a new render task.
/// \param [in] TaskId - The task ID that will be used to register the task in the render index.
Expand All @@ -114,6 +111,10 @@ class HnTaskController
TaskUID UID,
TaskParamsType&& Params);

template <typename TaskParamsType>
bool SetTaskParams(TaskUID UID,
TaskParamsType&& Params);

pxr::HdTaskSharedPtr GetTask(TaskUID UID) const;

void RemoveTask(TaskUID UID);
Expand All @@ -132,25 +133,96 @@ class HnTaskController
const pxr::SdfPath m_ControllerId;

// Custom delegate to pass parameters to the render tasks.
class TaskParamsDelegate;
std::unique_ptr<TaskParamsDelegate> m_ParamsDelegate;
class HnTaskController::TaskParamsDelegate final : public pxr::HdSceneDelegate
{
public:
TaskParamsDelegate(pxr::HdRenderIndex& Index,
const pxr::SdfPath& Id);
~TaskParamsDelegate() override final;

template <typename T>
void SetParameter(const pxr::SdfPath& Id, const pxr::TfToken& ValueKey, T&& Value)
{
m_ParamsCache[{Id, ValueKey}] = std::forward<T>(Value);
}

template <typename T>
T GetParameter(const pxr::SdfPath& Id, const pxr::TfToken& ValueKey) const
{
auto it = m_ParamsCache.find({Id, ValueKey});
if (it == m_ParamsCache.end())
{
UNEXPECTED("Parameter ", ValueKey, " is not set for ", Id);
return {};
}

VERIFY(it->second.IsHolding<T>(), "Unexpected parameter type");
return it->second.Get<T>();
}

virtual bool HasParameter(const pxr::SdfPath& Id, const pxr::TfToken& ValueKey) const;

virtual pxr::VtValue Get(const pxr::SdfPath& Id, const pxr::TfToken& ValueKey) override final;

virtual pxr::GfMatrix4d GetTransform(const pxr::SdfPath& Id) override final;

virtual pxr::VtValue GetLightParamValue(const pxr::SdfPath& Id, const pxr::TfToken& ParamName) override final;

virtual bool IsEnabled(const pxr::TfToken& Option) const override final;

virtual pxr::HdRenderBufferDescriptor GetRenderBufferDescriptor(const pxr::SdfPath& Id) override final;

virtual pxr::TfTokenVector GetTaskRenderTags(const pxr::SdfPath& TaskId) override final;

private:
struct ParamKey
{
const pxr::SdfPath Path;
const pxr::TfToken ValueKey;
const size_t Hash;

ParamKey(const pxr::SdfPath& _Path, const pxr::TfToken& _ValueKey);

bool operator==(const ParamKey& rhs) const
{
return Hash && rhs.Hash && Path == rhs.Path && ValueKey == rhs.ValueKey;
}

struct Hasher
{
size_t operator()(const ParamKey& Key) const
{
return Key.Hash;
}
};
};

std::unordered_map<ParamKey, pxr::VtValue, ParamKey::Hasher> m_ParamsCache;
};
TaskParamsDelegate m_ParamsDelegate;

std::unordered_map<TaskUID, pxr::SdfPath> m_TaskUIDs;

std::vector<TaskUID> m_DefaultTaskOrder;
std::vector<pxr::SdfPath> m_RenderTaskIds;
};

template <typename ParamterType>
void HnTaskController::SetParameter(const pxr::SdfPath& TaskId, const pxr::TfToken& ValueKey, ParamterType&& Value)
{
m_ParamsDelegate.SetParameter(TaskId, pxr::HdTokens->params, std::forward<TaskParamsType>(Params));
}

template <typename TaskType, typename TaskParamsType>
void HnTaskController::CreateTask(const pxr::SdfPath& TaskId,
TaskUID UID,
TaskParamsType&& Params)
{
m_RenderIndex.InsertTask<TaskType>(m_ParamsDelegate.get(), TaskId);
m_RenderIndex.InsertTask<TaskType>(&m_ParamsDelegate, TaskId);
auto it_inserted = m_TaskUIDs.emplace(UID, TaskId);
VERIFY(it_inserted.second, "Task with UID ", UID, " already exists: ", it_inserted.first->second.GetText());

m_ParamsDelegate->SetParameter(TaskId, pxr::HdTokens->params, std::forward<TaskParamsType>(Params));
m_ParamsDelegate.SetParameter(TaskId, pxr::HdTokens->params, std::forward<TaskParamsType>(Params));
m_DefaultTaskOrder.emplace_back(UID);
}

Expand All @@ -162,6 +234,26 @@ void HnTaskController::CreateTask(const pxr::TfToken& TaskId,
CreateTask<TaskType>(pxr::SdfPath{GetControllerId().AppendChild(TaskId)}, UID, std::forward<TaskParamsType>(Params));
}

template <typename TaskParamsType>
bool HnTaskController::SetTaskParams(TaskUID UID,
TaskParamsType&& Params)
{
const auto it = m_TaskUIDs.find(UID);
if (it == m_TaskUIDs.end())
return false;

const auto& TaskId = it->second;

TaskParamsType OldParams = m_ParamsDelegate.GetParameter<std::remove_reference<TaskParamsType>::type>(TaskId, pxr::HdTokens->params);
if (OldParams == Params)
return false;

m_ParamsDelegate.SetParameter(TaskId, pxr::HdTokens->params, std::forward<TaskParamsType>(Params));
m_RenderIndex.GetChangeTracker().MarkTaskDirty(TaskId, pxr::HdChangeTracker::DirtyParams);

return true;
}

} // namespace USD

} // namespace Diligent
Loading

0 comments on commit 5867ed0

Please sign in to comment.