Skip to content

Commit

Permalink
Updating master with changes from the fix branch (#886)
Browse files Browse the repository at this point in the history
* Fixing testsuite issues using 21.02+ and supporting new and old light parameter naming conventions. (#881)

* Fixing testsuite issues using 21.02+ and supporting new and old light parameter naming conventions.

Fixes #880
Fixes #772

* Only call AiBegin/AiEnd in the delegate if no arnold session is active #884 (#885)

* Support render tags in the render delegate. (#883)

* Checking for render tags.
* Tracking render tags for shapes.
* Improving render tag tracking.
* Interrupt before disabling nodes.
* Renaming render tag handling functions and moving the core logic to a separate function.
* Tracking the point instancer's render tag.

Fixes #843

Co-authored-by: Sebastien Blaineau-Ortega <sebastien.blaineau.ortega@autodesk.com>
  • Loading branch information
sirpalee and sebastienblor authored Sep 20, 2021
1 parent 0b7bbe7 commit b50e929
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 30 deletions.
3 changes: 2 additions & 1 deletion render_delegate/render_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ inline void _WriteBucket(
const auto toStep = width * componentCount;
const auto fromStep = bucketWidth * bucketComponentCount;

const auto copyOp = [](const typename HdFormatType<FROM>::type& in) -> typename HdFormatType<TO>::type {
const auto copyOp = [](const typename HdFormatType<FROM>::type& in) -> typename HdFormatType<TO>::type
{
return _ConvertType<typename HdFormatType<TO>::type, typename HdFormatType<FROM>::type>(in);
};
const auto dataWidth = xe - xo;
Expand Down
52 changes: 43 additions & 9 deletions render_delegate/render_delegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,14 +349,17 @@ HdArnoldRenderDelegate::HdArnoldRenderDelegate(HdArnoldRenderContext context) :
{
_lightLinkingChanged.store(false, std::memory_order_release);
_id = SdfPath(TfToken(TfStringPrintf("/HdArnoldRenderDelegate_%p", this)));
if (AiUniverseIsActive()) {
TF_CODING_ERROR("There is already an active Arnold universe!");
}
// TODO(pal): We need to investigate if it's safe to set session to AI_SESSION_BATCH when rendering in husk for
// example. ie. is husk creating a separate render delegate for each frame, or syncs the changes?
AiBegin(AI_SESSION_INTERACTIVE);
_supportedRprimTypes = {
HdPrimTypeTokens->mesh, HdPrimTypeTokens->volume, HdPrimTypeTokens->points, HdPrimTypeTokens->basisCurves};

// We first need to check if arnold has already been initialized.
// If not, we need to call AiBegin, and the destructor on we'll call AiEnd
_isArnoldActive = AiUniverseIsActive();
if (!_isArnoldActive) {
// TODO(pal): We need to investigate if it's safe to set session to AI_SESSION_BATCH when rendering in husk for
// example. ie. is husk creating a separate render delegate for each frame, or syncs the changes?
AiBegin(AI_SESSION_INTERACTIVE);
}
_supportedRprimTypes = {HdPrimTypeTokens->mesh, HdPrimTypeTokens->volume, HdPrimTypeTokens->points,
HdPrimTypeTokens->basisCurves};
auto* shapeIter = AiUniverseGetNodeEntryIterator(AI_NODE_SHAPE);
while (!AiNodeEntryIteratorFinished(shapeIter)) {
const auto* nodeEntry = AiNodeEntryIteratorGetNext(shapeIter);
Expand Down Expand Up @@ -466,7 +469,10 @@ HdArnoldRenderDelegate::~HdArnoldRenderDelegate()
#endif
hdArnoldUninstallNodes();
AiUniverseDestroy(_universe);
AiEnd();
// We must end the arnold session, only if we created it during the constructor.
// Otherwise we could be destroying a session that is being used elsewhere
if (!_isArnoldActive)
AiEnd();
}

HdRenderParam* HdArnoldRenderDelegate::GetRenderParam() const { return _renderParam.get(); }
Expand Down Expand Up @@ -1214,4 +1220,32 @@ void HdArnoldRenderDelegate::UntrackShapeMaterials(const SdfPath& shape, const V
_shapeMaterialUntrackQueue.emplace(shape, materials);
}

void HdArnoldRenderDelegate::TrackRenderTag(AtNode* node, const TfToken& tag)
{
AiNodeSetDisabled(node, std::find(_renderTags.begin(), _renderTags.end(), tag) == _renderTags.end());
_renderTagTrackQueue.push({node, tag});
}

void HdArnoldRenderDelegate::UntrackRenderTag(AtNode* node) { _renderTagUntrackQueue.push(node); }

void HdArnoldRenderDelegate::SetRenderTags(const TfTokenVector& renderTags)
{
RenderTagTrackQueueElem renderTagRegister;
while (_renderTagTrackQueue.try_pop(renderTagRegister)) {
_renderTagMap[renderTagRegister.first] = renderTagRegister.second;
}
AtNode* node;
while (_renderTagUntrackQueue.try_pop(node)) {
_renderTagMap.erase(node);
}
if (renderTags != _renderTags) {
_renderTags = renderTags;
for (auto& elem : _renderTagMap) {
const auto disabled = std::find(_renderTags.begin(), _renderTags.end(), elem.second) == _renderTags.end();
AiNodeSetDisabled(elem.first, disabled);
}
_renderParam->Interrupt();
}
}

PXR_NAMESPACE_CLOSE_SCOPE
32 changes: 32 additions & 0 deletions render_delegate/render_delegate.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,25 @@ class HdArnoldRenderDelegate final : public HdRenderDelegate {
HDARNOLD_API
void UntrackShapeMaterials(const SdfPath& shape, const VtArray<SdfPath>& materials);

/// Registers a new shape and render tag.
///
/// @param node Pointer to the Arnold node.
/// @param tag Render tag of the node.
HDARNOLD_API
void TrackRenderTag(AtNode* node, const TfToken& tag);

/// Deregisters a shape from the render tag map.
///
/// @param node Pointer to the Arnold node.
HDARNOLD_API
void UntrackRenderTag(AtNode* node);

/// Sets render tags to display.
///
/// @param renderTags List of render tags to display.
HDARNOLD_API
void SetRenderTags(const TfTokenVector& renderTags);

private:
HdArnoldRenderDelegate(const HdArnoldRenderDelegate&) = delete;
HdArnoldRenderDelegate& operator=(const HdArnoldRenderDelegate&) = delete;
Expand Down Expand Up @@ -440,12 +459,24 @@ class HdArnoldRenderDelegate final : public HdRenderDelegate {
};
using ShapeMaterialChangesQueue = tbb::concurrent_queue<ShapeMaterialChange>;

TfTokenVector _renderTags; ///< List of current render tags.

MaterialChangesQueue _materialDirtyQueue; ///< Queue to track material terminal dirty events.
MaterialChangesQueue _materialRemovalQueue; ///< Queue to track material removal events.
ShapeMaterialChangesQueue _shapeMaterialTrackQueue; ///< Queue to track shape material assignment changes.
ShapeMaterialChangesQueue _shapeMaterialUntrackQueue; ///< Queue to untrack shape material assignment changes.
MaterialToShapeMap _materialToShapeMap; ///< Map to track dependencies between materials and shapes.

using RenderTagTrackQueueElem = std::pair<AtNode*, TfToken>;
/// Type to register shapes with render tags.
using RenderTagTrackQueue = tbb::concurrent_queue<RenderTagTrackQueueElem>;
/// Type to deregister shapes from the render tags map.
using RenderTagUntrackQueue = tbb::concurrent_queue<AtNode*>;
using RenderTagMap = std::unordered_map<AtNode*, TfToken>;
RenderTagMap _renderTagMap; ///< Map to track render tags for each shape.
RenderTagTrackQueue _renderTagTrackQueue; ///< Queue to track shapes with render tags.
RenderTagUntrackQueue _renderTagUntrackQueue; ///< Queue to untrack shapes from render tag map.

std::mutex _lightLinkingMutex; ///< Mutex to lock all light linking operations.
LightLinkingMap _lightLinks; ///< Light Link categories.
LightLinkingMap _shadowLinks; ///< Shadow Link categories.
Expand Down Expand Up @@ -474,6 +505,7 @@ class HdArnoldRenderDelegate final : public HdRenderDelegate {
HdArnoldRenderContext _context = HdArnoldRenderContext::Hydra;
int _verbosityLogFlags = AI_LOG_WARNINGS | AI_LOG_ERRORS;
bool _ignoreVerbosityLogFlags = false;
bool _isArnoldActive = false;
};

PXR_NAMESPACE_CLOSE_SCOPE
11 changes: 5 additions & 6 deletions render_delegate/render_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ HdArnoldRenderPass::~HdArnoldRenderPass()

void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassState, const TfTokenVector& renderTags)
{
TF_UNUSED(renderTags);
_renderDelegate->SetRenderTags(renderTags);
auto* renderParam = reinterpret_cast<HdArnoldRenderParam*>(_renderDelegate->GetRenderParam());
const auto dataWindow = _GetDataWindow(renderPassState);

Expand Down Expand Up @@ -806,11 +806,10 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt

// We skip an iteration step if the render delegate tells us to do so, this is the easiest way to force
// a sync step before calling the render function. Currently, this is used to trigger light linking updates.
const auto renderStatus = _renderDelegate->ShouldSkipIteration(
GetRenderIndex(), {AiNodeGetFlt(currentCamera, str::shutter_start),
AiNodeGetFlt(currentCamera, str::shutter_end)})
? HdArnoldRenderParam::Status::Converging
: renderParam->Render();
const auto shouldSkipIteration = _renderDelegate->ShouldSkipIteration(
GetRenderIndex(),
{AiNodeGetFlt(currentCamera, str::shutter_start), AiNodeGetFlt(currentCamera, str::shutter_end)});
const auto renderStatus = shouldSkipIteration ? HdArnoldRenderParam::Status::Converging : renderParam->Render();
_isConverged = renderStatus != HdArnoldRenderParam::Status::Converging;

// We need to set the converged status of the render buffers.
Expand Down
3 changes: 2 additions & 1 deletion render_delegate/rprim.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class HdArnoldRprim : public HydraType {
///
/// Frees the shape and all the ginstances created.
~HdArnoldRprim() override { _materialTracker.UntrackMaterials(_renderDelegate, HydraType::GetId()); }

/// Gets the Arnold Shape.
///
/// @return Reference to the Arnold Shape.
Expand Down Expand Up @@ -102,7 +103,7 @@ class HdArnoldRprim : public HydraType {
// We also force syncing of the parent instancers.
HdInstancer::_SyncInstancerAndParents(sceneDelegate->GetRenderIndex(), HydraType::GetInstancerId());
#endif
_shape.Sync(this, dirtyBits, _renderDelegate, sceneDelegate, param, force);
_shape.Sync(this, dirtyBits, sceneDelegate, param, force);
}
/// Checks if the visibility and sidedness has changed and applies it to the shape. Interrupts the rendering if
/// either has changed.
Expand Down
21 changes: 17 additions & 4 deletions render_delegate/shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ PXR_NAMESPACE_OPEN_SCOPE

HdArnoldShape::HdArnoldShape(
const AtString& shapeType, HdArnoldRenderDelegate* renderDelegate, const SdfPath& id, const int32_t primId)
: _renderDelegate(renderDelegate)
{
_shape = AiNode(renderDelegate->GetUniverse(), shapeType);
AiNodeSetStr(_shape, str::name, AtString(id.GetText()));
Expand All @@ -29,15 +30,17 @@ HdArnoldShape::HdArnoldShape(

HdArnoldShape::~HdArnoldShape()
{
_renderDelegate->UntrackRenderTag(_shape);
AiNodeDestroy(_shape);
if (_instancer != nullptr) {
_renderDelegate->UntrackRenderTag(_instancer);
AiNodeDestroy(_instancer);
}
}

void HdArnoldShape::Sync(
HdRprim* rprim, HdDirtyBits dirtyBits, HdArnoldRenderDelegate* renderDelegate, HdSceneDelegate* sceneDelegate,
HdArnoldRenderParamInterrupt& param, bool force)
HdRprim* rprim, HdDirtyBits dirtyBits, HdSceneDelegate* sceneDelegate, HdArnoldRenderParamInterrupt& param,
bool force)
{
auto& id = rprim->GetId();
if (HdChangeTracker::IsPrimIdDirty(dirtyBits, id)) {
Expand All @@ -46,9 +49,18 @@ void HdArnoldShape::Sync(
}
if (dirtyBits & HdChangeTracker::DirtyCategories) {
param.Interrupt();
renderDelegate->ApplyLightLinking(_shape, sceneDelegate->GetCategories(id));
_renderDelegate->ApplyLightLinking(_shape, sceneDelegate->GetCategories(id));
}
_SyncInstances(dirtyBits, renderDelegate, sceneDelegate, param, id, rprim->GetInstancerId(), force);
// If render tags are empty, we are displaying everything.
if (dirtyBits & HdChangeTracker::DirtyRenderTag) {
param.Interrupt();
const auto renderTag = sceneDelegate->GetRenderTag(id);
_renderDelegate->TrackRenderTag(_shape, renderTag);
if (_instancer != nullptr) {
_renderDelegate->TrackRenderTag(_instancer, renderTag);
}
}
_SyncInstances(dirtyBits, _renderDelegate, sceneDelegate, param, id, rprim->GetInstancerId(), force);
}

void HdArnoldShape::SetVisibility(uint8_t visibility)
Expand Down Expand Up @@ -102,6 +114,7 @@ void HdArnoldShape::_SyncInstances(
instancer->CalculateInstanceMatrices(id, instanceMatrices);
if (_instancer == nullptr) {
_instancer = AiNode(renderDelegate->GetUniverse(), str::instancer);
_renderDelegate->TrackRenderTag(_instancer, sceneDelegate->GetRenderTag(id));
std::stringstream ss;
ss << AiNodeGetName(_shape) << "_instancer";
AiNodeSetStr(_instancer, str::name, AtString(ss.str().c_str()));
Expand Down
22 changes: 16 additions & 6 deletions render_delegate/shape.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,24 @@ class HdArnoldShape {
///
/// @return Pointer to the Arnold Shape.
AtNode* GetShape() { return _shape; }

/// Gets the Arnold Shape.
///
/// @return Constant pointer to the Arnold Shape.
const AtNode* GetShape() const { return _shape; }

/// Syncs internal data and arnold state with hydra.
///
/// @param rprim Pointer to the Hydra render primitive.
/// @param dirtyBits Hydra dirty bits to sync.
/// @param sceneDelegate Pointer to the Hydra scene delegate.
/// @param param Reference to the HdArnold struct handling interrupt eents.
/// @param force Whether or not to force recreating instances.
HDARNOLD_API
void Sync(
HdRprim* rprim, HdDirtyBits dirtyBits, HdArnoldRenderDelegate* renderDelegate, HdSceneDelegate* sceneDelegate,
HdArnoldRenderParamInterrupt& param, bool force = false);
HdRprim* rprim, HdDirtyBits dirtyBits, HdSceneDelegate* sceneDelegate, HdArnoldRenderParamInterrupt& param,
bool force = false);

/// Sets the internal visibility parameter.
///
/// @param visibility New value for visibility.
Expand All @@ -83,7 +92,7 @@ class HdArnoldShape {
static HdDirtyBits GetInitialDirtyBitsMask()
{
return HdChangeTracker::DirtyInstancer | HdChangeTracker::DirtyInstanceIndex |
HdChangeTracker::DirtyCategories | HdChangeTracker::DirtyPrimID;
HdChangeTracker::DirtyCategories | HdChangeTracker::DirtyPrimID | HdChangeTracker::DirtyRenderTag;
}

protected:
Expand Down Expand Up @@ -113,9 +122,10 @@ class HdArnoldShape {
HDARNOLD_API
void _UpdateInstanceVisibility(HdArnoldRenderParamInterrupt& param);

AtNode* _instancer = nullptr; ///< Pointer to the Arnold Instancer.
AtNode* _shape; ///< Pointer to the Arnold Shape.
uint8_t _visibility = AI_RAY_ALL; ///< Visibility of the mesh.
HdArnoldRenderDelegate* _renderDelegate; ///< Pointer to the Arnold render delegate.
AtNode* _instancer = nullptr; ///< Pointer to the Arnold Instancer.
AtNode* _shape; ///< Pointer to the Arnold Shape.
uint8_t _visibility = AI_RAY_ALL; ///< Visibility of the mesh.
};

PXR_NAMESPACE_CLOSE_SCOPE
5 changes: 2 additions & 3 deletions render_delegate/volume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,8 @@ void HdArnoldVolume::Sync(
HdInstancer::_SyncInstancerAndParents(sceneDelegate->GetRenderIndex(), GetInstancerId());
#endif

_ForEachVolume([&](HdArnoldShape* shape) {
shape->Sync(this, *dirtyBits, _renderDelegate, sceneDelegate, param, transformDirtied);
});
_ForEachVolume(
[&](HdArnoldShape* shape) { shape->Sync(this, *dirtyBits, sceneDelegate, param, transformDirtied); });

*dirtyBits = HdChangeTracker::Clean;
}
Expand Down

0 comments on commit b50e929

Please sign in to comment.