From e6f3127b9c487bb51d1e100a701db581335d521c Mon Sep 17 00:00:00 2001 From: "ADS\\blaines" Date: Tue, 31 Jan 2023 10:01:34 +0100 Subject: [PATCH] Imagers only updates in the render delegate #1320 --- common/constant_strings.h | 1 + render_delegate/node_graph.cpp | 22 ++++++++++++++++++++-- render_delegate/node_graph.h | 8 ++++++++ render_delegate/render_delegate.cpp | 7 +++++-- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/common/constant_strings.h b/common/constant_strings.h index 98eab334cf..f2338f96dc 100644 --- a/common/constant_strings.h +++ b/common/constant_strings.h @@ -389,6 +389,7 @@ ASTR(region_min_y); ASTR(render_device); ASTR(render_settings); ASTR(repeat); +ASTR(request_imager_update); ASTR(rotation); ASTR(roughness); ASTR(scale); diff --git a/render_delegate/node_graph.cpp b/render_delegate/node_graph.cpp index dfeb4c950a..d4a5d602cb 100644 --- a/render_delegate/node_graph.cpp +++ b/render_delegate/node_graph.cpp @@ -447,7 +447,11 @@ void HdArnoldNodeGraph::Sync(HdSceneDelegate* sceneDelegate, HdRenderParam* rend auto value = sceneDelegate->GetMaterialResource(GetId()); auto nodeGraphChanged = false; if (value.IsHolding()) { - param.Interrupt(); + + // If this nodeGraph is an imager graph, and it's been modified, we don't want + // to stop the render (#1320) + if (!_isImagerGraph) + param.Interrupt(); // Mark all nodes as unused before any translation happens. SetNodesUnused(); const auto& map = value.UncheckedGet(); @@ -457,7 +461,10 @@ void HdArnoldNodeGraph::Sync(HdSceneDelegate* sceneDelegate, HdRenderParam* rend } // No need to interrupt earlier as we don't know if there is a valid network passed to the function or // not. - param.Interrupt(); + + // As above, we don't interrupt if this is an imager graph + if (!_isImagerGraph) + param.Interrupt(); // We are remapping the preview surface nodes to ones that are supported // in Arnold. This way we can keep the export code untouched, // and handle connection / node exports separately. @@ -478,6 +485,12 @@ void HdArnoldNodeGraph::Sync(HdSceneDelegate* sceneDelegate, HdRenderParam* rend } } ClearUnusedNodes(); + // If this is an imager graph, we need to tell Arnold that the imagers were updated. + // This will trigger only the computation of the imager graph, without necessarily + // restarting a render (#1320) + if (_isImagerGraph) { + AiRenderSetHintBool(_renderDelegate->GetRenderSession(), str::request_imager_update, true); + } } // We only mark the material dirty if one of the terminals have changed, but ignore the initial sync, because we // expect Hydra to do the initial assignment correctly. @@ -582,6 +595,7 @@ AtNode* HdArnoldNodeGraph::ReadMaterialNetwork(const HdMaterialNetwork& network) if (AiNodeEntryGetType(AiNodeGetNodeEntry(inputNode)) == AI_NODE_DRIVER) { // imagers are chained with the input parameter AiNodeSetPtr(outputNode, str::input, inputNode); + _isImagerGraph = true; } else { // Arnold shader nodes can only have one output... but you can connect to sub components of them. // USD doesn't yet have component connections / swizzling, but it's nodes can have multiple @@ -849,6 +863,10 @@ const HdArnoldNodeGraph* HdArnoldNodeGraph::GetNodeGraph(HdRenderIndex* renderIn return reinterpret_cast(renderIndex->GetSprim(HdPrimTypeTokens->material, id)); } +void HdArnoldNodeGraph::SetImagerGraph() +{ + _isImagerGraph = true; +} PXR_NAMESPACE_CLOSE_SCOPE diff --git a/render_delegate/node_graph.h b/render_delegate/node_graph.h index 65d4f02223..d2f913160a 100644 --- a/render_delegate/node_graph.h +++ b/render_delegate/node_graph.h @@ -121,6 +121,13 @@ class HdArnoldNodeGraph : public HdMaterial { /// @return Pointer to the requested HdArnoldNodeGraph HDARNOLD_API static const HdArnoldNodeGraph* GetNodeGraph(HdRenderIndex* renderIndex, const SdfPath& id); + + /// Notify this node graph that it's meant to be used as an imager graph. + /// In this case, when an interactive change happens, we don't want to restart + /// a full render, but instead we directly update the arnold imagers and then + /// notify Arnold that the imagers were updated (#1320) + HDARNOLD_API + void SetImagerGraph(); protected: /// Utility struct to store translated nodes. @@ -281,6 +288,7 @@ class HdArnoldNodeGraph : public HdMaterial { ArnoldNodeGraph _nodeGraph; ///< Storing arnold shaders for terminals. HdArnoldRenderDelegate* _renderDelegate; ///< Pointer to the Render Delegate. bool _wasSyncedOnce = false; ///< Whether or not the material has been synced at least once. + bool _isImagerGraph = false; ///< Whether or not this is an imager graph }; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/render_delegate/render_delegate.cpp b/render_delegate/render_delegate.cpp index 1af3a7ae78..61d1039422 100644 --- a/render_delegate/render_delegate.cpp +++ b/render_delegate/render_delegate.cpp @@ -1483,9 +1483,12 @@ std::vector HdArnoldRenderDelegate::GetAovShaders(HdRenderIndex* render AtNode* HdArnoldRenderDelegate::GetImager(HdRenderIndex* renderIndex) { - const HdArnoldNodeGraph *nodeGraph = HdArnoldNodeGraph::GetNodeGraph(renderIndex, _imager); - if (nodeGraph) + HdArnoldNodeGraph *nodeGraph = (HdArnoldNodeGraph *)HdArnoldNodeGraph::GetNodeGraph(renderIndex, _imager); + if (nodeGraph) { + // Notify this nodeGraph that it's being used as an imager graph + nodeGraph->SetImagerGraph(); return nodeGraph->GetTerminal(str::t_input); + } return nullptr; }