From 6b6f45b7ac71ea0e6880ab41c4c7915467e333de Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 19 Oct 2023 09:17:38 -0700 Subject: [PATCH] HnTaskController: reworked task managing to allow the application define its own tasks --- Hydrogent/include/Tasks/HnTaskController.hpp | 51 +++++--- Hydrogent/src/Tasks/HnTaskController.cpp | 127 ++++++++++++------- 2 files changed, 114 insertions(+), 64 deletions(-) diff --git a/Hydrogent/include/Tasks/HnTaskController.hpp b/Hydrogent/include/Tasks/HnTaskController.hpp index 3af498c8..9d9f0300 100644 --- a/Hydrogent/include/Tasks/HnTaskController.hpp +++ b/Hydrogent/include/Tasks/HnTaskController.hpp @@ -27,10 +27,12 @@ #pragma once #include -#include +#include #include "Tasks/HnTask.hpp" +#include "DebugUtilities.hpp" + namespace Diligent { @@ -44,6 +46,13 @@ struct HnPostProcessTaskParams; class HnTaskController { public: + using TaskUID = uint64_t; + static constexpr TaskUID TaskUID_RenderDefault = 0x287af907f3a740a0; + static constexpr TaskUID TaskUID_RenderMasked = 0xf5290fec47594711; + static constexpr TaskUID TaskUID_RenderAdditive = 0x37d45531106c4c52; + static constexpr TaskUID TaskUID_RenderTranslucent = 0xa015c7e45941407e; + static constexpr TaskUID TaskUID_PostProcess = 0x1f5367e65d034500; + HnTaskController(pxr::HdRenderIndex& RenderIndex, const pxr::SdfPath& ControllerId); @@ -54,7 +63,7 @@ class HnTaskController const pxr::SdfPath& GetControllerId() const { return m_ControllerId; } - const pxr::HdTaskSharedPtrVector GetRenderingTasks() const; + const pxr::HdTaskSharedPtrVector GetTasks(const std::vector* TaskOrder = nullptr) const; /// Sets new collection for the render tasks. void SetCollection(const pxr::HdRprimCollection& Collection); @@ -68,21 +77,22 @@ class HnTaskController /// Sets new render tags for the render tasks. void SetRenderTags(const pxr::TfTokenVector& RenderTags); - enum TASK_ID - { - TASK_ID_RENDER_DEFAULT, - TASK_ID_RENDER_MASKED, - TASK_ID_RENDER_ADDITIVE, - TASK_ID_RENDER_TRANSLUCENT, - TASK_ID_POST_PROCESS, - TASK_ID_COUNT - }; - pxr::HdTaskSharedPtr GetTask(TASK_ID idx) const; + /// Sets the parameter value + void SetParameter(const pxr::SdfPath& Id, const pxr::TfToken& ValueKey, pxr::VtValue Value); + + template + void CreateTask(const pxr::SdfPath& TaskId, + TaskUID UID); + + pxr::HdTaskSharedPtr GetTask(TaskUID UID) const; + + void RemoveTask(TaskUID UID); private: pxr::SdfPath GetRenderTaskId(const pxr::TfToken& MaterialTag) const; - pxr::SdfPath CreateRenderTask(const pxr::TfToken& MaterialTag); - pxr::SdfPath CreatePostProcessTask(); + + void CreateRenderTask(const pxr::TfToken& MaterialTag, TaskUID UID); + void CreatePostProcessTask(); private: pxr::HdRenderIndex& m_RenderIndex; @@ -92,9 +102,20 @@ class HnTaskController class TaskParamsDelegate; std::unique_ptr m_ParamsDelegate; - std::array m_TaskIds; + std::unordered_map m_TaskIds; + + std::vector m_DefaultTaskOrder; }; +template +void HnTaskController::CreateTask(const pxr::SdfPath& TaskId, + TaskUID UID) +{ + m_RenderIndex.InsertTask(m_ParamsDelegate.get(), TaskId); + auto it_inserted = m_TaskIds.emplace(UID, TaskId); + VERIFY(!it_inserted.second, "Task with UID ", UID, " already exists: ", it_inserted.first->second.GetText()); +} + } // namespace USD } // namespace Diligent diff --git a/Hydrogent/src/Tasks/HnTaskController.cpp b/Hydrogent/src/Tasks/HnTaskController.cpp index f0d06585..27577a17 100644 --- a/Hydrogent/src/Tasks/HnTaskController.cpp +++ b/Hydrogent/src/Tasks/HnTaskController.cpp @@ -27,6 +27,7 @@ #include "Tasks/HnTaskController.hpp" #include +#include #include "Tasks/HnRenderTask.hpp" #include "Tasks/HnPostProcessTask.hpp" @@ -53,11 +54,11 @@ TF_DEFINE_PRIVATE_TOKENS( ); // clang-format on -static constexpr std::array RenderTaskIds = { - HnTaskController::TASK_ID_RENDER_DEFAULT, - HnTaskController::TASK_ID_RENDER_MASKED, - HnTaskController::TASK_ID_RENDER_ADDITIVE, - HnTaskController::TASK_ID_RENDER_TRANSLUCENT, +static constexpr std::array RenderTaskUIDs = { + HnTaskController::TaskUID_RenderDefault, + HnTaskController::TaskUID_RenderMasked, + HnTaskController::TaskUID_RenderAdditive, + HnTaskController::TaskUID_RenderTranslucent, }; } // namespace @@ -75,9 +76,9 @@ class HnTaskController::TaskParamsDelegate final : public pxr::HdSceneDelegate } template - void SetParameter(const pxr::SdfPath& Id, const TfToken& ValueKey, const T& Value) + void SetParameter(const pxr::SdfPath& Id, const pxr::TfToken& ValueKey, T&& Value) { - m_ParamsCache[{Id, ValueKey}] = Value; + m_ParamsCache[{Id, ValueKey}] = std::forward(Value); } template @@ -173,30 +174,49 @@ HnTaskController::HnTaskController(pxr::HdRenderIndex& RenderIndex, m_ControllerId{ControllerId}, m_ParamsDelegate{std::make_unique(RenderIndex, ControllerId)} { - m_TaskIds[TASK_ID_RENDER_DEFAULT] = CreateRenderTask(HnMaterialTagTokens->defaultTag); - m_TaskIds[TASK_ID_RENDER_MASKED] = CreateRenderTask(HnMaterialTagTokens->masked); - m_TaskIds[TASK_ID_RENDER_ADDITIVE] = CreateRenderTask(HnMaterialTagTokens->additive); - m_TaskIds[TASK_ID_RENDER_TRANSLUCENT] = CreateRenderTask(HnMaterialTagTokens->translucent); + CreateRenderTask(HnMaterialTagTokens->defaultTag, TaskUID_RenderDefault); + CreateRenderTask(HnMaterialTagTokens->masked, TaskUID_RenderMasked); + CreateRenderTask(HnMaterialTagTokens->additive, TaskUID_RenderAdditive); + CreateRenderTask(HnMaterialTagTokens->translucent, TaskUID_RenderTranslucent); - m_TaskIds[TASK_ID_POST_PROCESS] = CreatePostProcessTask(); + CreatePostProcessTask(); + + m_DefaultTaskOrder = + { + TaskUID_RenderDefault, + TaskUID_RenderMasked, + TaskUID_RenderAdditive, + TaskUID_RenderTranslucent, + TaskUID_PostProcess, + }; } HnTaskController::~HnTaskController() { // Remove all tasks from the render index - for (const auto& Id : m_TaskIds) + for (const auto& it : m_TaskIds) { - if (!Id.IsEmpty()) - { - m_RenderIndex.RemoveTask(Id); - } + m_RenderIndex.RemoveTask(it.second); } + m_TaskIds.clear(); +} + +pxr::HdTaskSharedPtr HnTaskController::GetTask(TaskUID UID) const +{ + auto it = m_TaskIds.find(UID); + return it == m_TaskIds.end() ? + m_RenderIndex.GetTask(it->second) : + nullptr; } -pxr::HdTaskSharedPtr HnTaskController::GetTask(TASK_ID idx) const +void HnTaskController::RemoveTask(TaskUID UID) { - const auto& TaskId = m_TaskIds[idx]; - return !TaskId.IsEmpty() ? m_RenderIndex.GetTask(TaskId) : nullptr; + auto it = m_TaskIds.find(UID); + if (it == m_TaskIds.end()) + return; + + m_RenderIndex.RemoveTask(it->second); + m_TaskIds.erase(it); } pxr::SdfPath HnTaskController::GetRenderTaskId(const pxr::TfToken& MaterialTag) const @@ -206,12 +226,17 @@ pxr::SdfPath HnTaskController::GetRenderTaskId(const pxr::TfToken& MaterialTag) return GetControllerId().AppendChild(TfToken{Id}); } -pxr::SdfPath HnTaskController::CreateRenderTask(const pxr::TfToken& MaterialTag) +void HnTaskController::SetParameter(const pxr::SdfPath& Id, const TfToken& ValueKey, pxr::VtValue Value) +{ + m_ParamsDelegate->SetParameter(Id, ValueKey, std::move(Value)); +} + +void HnTaskController::CreateRenderTask(const pxr::TfToken& MaterialTag, TaskUID UID) { const pxr::SdfPath RenderTaskId = GetRenderTaskId(MaterialTag); // Note that we pass the delegate to the scene index. This delegate will be passed // to the task's Sync() method. - m_RenderIndex.InsertTask(m_ParamsDelegate.get(), RenderTaskId); + CreateTask(RenderTaskId, UID); HnRenderTaskParams TaskParams; @@ -228,34 +253,30 @@ pxr::SdfPath HnTaskController::CreateRenderTask(const pxr::TfToken& MaterialTag) m_ParamsDelegate->SetParameter(RenderTaskId, pxr::HdTokens->params, TaskParams); m_ParamsDelegate->SetParameter(RenderTaskId, pxr::HdTokens->collection, Collection); m_ParamsDelegate->SetParameter(RenderTaskId, pxr::HdTokens->renderTags, RenderTags); - - return RenderTaskId; } -pxr::SdfPath HnTaskController::CreatePostProcessTask() +void HnTaskController::CreatePostProcessTask() { const pxr::SdfPath PostProcessTaskId = GetControllerId().AppendChild(HnTaskControllerTokens->postProcessTask); - m_RenderIndex.InsertTask(m_ParamsDelegate.get(), PostProcessTaskId); + CreateTask(PostProcessTaskId, TaskUID_PostProcess); HnPostProcessTaskParams TaskParams; m_ParamsDelegate->SetParameter(PostProcessTaskId, pxr::HdTokens->params, TaskParams); - - return PostProcessTaskId; } -const pxr::HdTaskSharedPtrVector HnTaskController::GetRenderingTasks() const +const pxr::HdTaskSharedPtrVector HnTaskController::GetTasks(const std::vector* TaskOrder) const { + if (TaskOrder == nullptr) + TaskOrder = &m_DefaultTaskOrder; + pxr::HdTaskSharedPtrVector Tasks; - for (auto idx : {TASK_ID_RENDER_DEFAULT, - TASK_ID_RENDER_MASKED, - TASK_ID_RENDER_ADDITIVE, - TASK_ID_RENDER_TRANSLUCENT, - TASK_ID_POST_PROCESS}) + for (auto UID : *TaskOrder) { - if (!m_TaskIds[idx].IsEmpty()) - { - Tasks.push_back(m_RenderIndex.GetTask(m_TaskIds[idx])); - } + auto it = m_TaskIds.find(UID); + if (it == m_TaskIds.end()) + continue; + + Tasks.push_back(m_RenderIndex.GetTask(it->second)); } return Tasks; @@ -264,12 +285,14 @@ const pxr::HdTaskSharedPtrVector HnTaskController::GetRenderingTasks() const void HnTaskController::SetCollection(const pxr::HdRprimCollection& Collection) { pxr::HdRprimCollection NewCollection = Collection; - for (const auto idx : RenderTaskIds) + for (const auto UID : RenderTaskUIDs) { - const auto& TaskId = m_TaskIds[idx]; - if (TaskId.IsEmpty()) + auto it = m_TaskIds.find(UID); + if (it == m_TaskIds.end()) continue; + const auto& TaskId = it->second; + pxr::HdRprimCollection OldCollection = m_ParamsDelegate->GetParameter(TaskId, pxr::HdTokens->collection); const pxr::TfToken& OldMaterialTag = OldCollection.GetMaterialTag(); @@ -285,12 +308,14 @@ void HnTaskController::SetCollection(const pxr::HdRprimCollection& Collection) void HnTaskController::SetRenderParams(const HnRenderTaskParams& Params) { - for (const auto idx : RenderTaskIds) + for (const auto UID : RenderTaskUIDs) { - const auto& TaskId = m_TaskIds[idx]; - if (TaskId.IsEmpty()) + auto it = m_TaskIds.find(UID); + if (it == m_TaskIds.end()) continue; + const auto& TaskId = it->second; + HnRenderTaskParams OldParams = m_ParamsDelegate->GetParameter(TaskId, pxr::HdTokens->params); if (OldParams == Params) continue; @@ -302,10 +327,12 @@ void HnTaskController::SetRenderParams(const HnRenderTaskParams& Params) void HnTaskController::SetPostProcessParams(const HnPostProcessTaskParams& Params) { - const auto& TaskId = m_TaskIds[TASK_ID_POST_PROCESS]; - if (TaskId.IsEmpty()) + const auto it = m_TaskIds.find(TaskUID_PostProcess); + if (it == m_TaskIds.end()) return; + const auto& TaskId = it->second; + HnPostProcessTaskParams OldParams = m_ParamsDelegate->GetParameter(TaskId, pxr::HdTokens->params); if (OldParams == Params) return; @@ -316,12 +343,14 @@ void HnTaskController::SetPostProcessParams(const HnPostProcessTaskParams& Param void HnTaskController::SetRenderTags(const pxr::TfTokenVector& RenderTags) { - for (const auto idx : RenderTaskIds) + for (const auto UID : RenderTaskUIDs) { - const auto& TaskId = m_TaskIds[idx]; - if (TaskId.IsEmpty()) + auto it = m_TaskIds.find(UID); + if (it == m_TaskIds.end()) continue; + const auto& TaskId = it->second; + pxr::TfTokenVector OldRenderTags = m_ParamsDelegate->GetParameter(TaskId, pxr::HdTokens->renderTags); if (OldRenderTags == RenderTags) continue;