Skip to content

Use a single display driver for all AOVs in the render delegate #2286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [usd#2264](https://github.com/Autodesk/arnold-usd/issues/2264) - Skip translation of invisible primitives in the render delegate
- [usd#2277](https://github.com/Autodesk/arnold-usd/issues/2277) - Ensure child nodes are properly destroyed in the hydra procedural
- [usd#2276](https://github.com/Autodesk/arnold-usd/issues/2276) - Improve default interactive FPS settings in the render delegate
- [usd#2284](https://github.com/Autodesk/arnold-usd/issues/2284) - Use a single display driver in the render delegate
- [usd#2231](https://github.com/Autodesk/arnold-usd/issues/2231) - Fix velocity motion blur coherence when there is varying number of instances
- [usd#2285](https://github.com/Autodesk/arnold-usd/issues/2285) - Use point instancer angular velocity in the render delegate
- [usd#2287](https://github.com/Autodesk/arnold-usd/issues/2287) - Fix mismatch in default value for GI_transmission_depth between USD and Hydra
Expand Down
2 changes: 2 additions & 0 deletions libs/common/constant_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ ASTR(bottom);
ASTR(box_filter);
ASTR(bucket_scanning);
ASTR(bucket_size);
ASTR(buffer_names);
ASTR(buffer_pointers);
ASTR(cache_id);
ASTR(camera);
ASTR(cast_shadows);
Expand Down
1 change: 0 additions & 1 deletion libs/render_delegate/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
set(SRC
nodes/driver_aov.cpp
nodes/driver_main.cpp
nodes/nodes.cpp

Expand Down
1 change: 0 additions & 1 deletion libs/render_delegate/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ source_files = [
'shape.cpp',
'utils.cpp',
'volume.cpp',
os.path.join('nodes', 'driver_aov.cpp'),
os.path.join('nodes', 'driver_main.cpp'),
os.path.join('nodes', 'nodes.cpp'),
]
Expand Down
119 changes: 0 additions & 119 deletions libs/render_delegate/nodes/driver_aov.cpp

This file was deleted.

49 changes: 47 additions & 2 deletions libs/render_delegate/nodes/driver_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@ PXR_NAMESPACE_OPEN_SCOPE

AI_DRIVER_NODE_EXPORT_METHODS(HdArnoldDriverMainMtd);

HdFormat _GetFormatFromArnoldType(const int arnoldType)
{
if (arnoldType == AI_TYPE_RGBA) {
return HdFormatFloat32Vec4;
} else if (arnoldType == AI_TYPE_RGB || arnoldType == AI_TYPE_VECTOR) {
return HdFormatFloat32Vec3;
} else if (arnoldType == AI_TYPE_VECTOR2) {
return HdFormatFloat32Vec2;
} else if (arnoldType == AI_TYPE_FLOAT) {
return HdFormatFloat32;
} else if (arnoldType == AI_TYPE_INT) {
return HdFormatInt32;
} else {
return HdFormatUNorm8;
}
}


namespace {
const char* supportedExtensions[] = {nullptr};

Expand All @@ -55,6 +73,11 @@ node_parameters
AiParameterPtr(str::color_pointer, nullptr);
AiParameterPtr(str::depth_pointer, nullptr);
AiParameterPtr(str::id_pointer, nullptr);
AiParameterArray(str::buffer_names, AiArray(0, 0, AI_TYPE_STRING));
AiParameterArray(str::buffer_pointers, AiArray(0, 0, AI_TYPE_POINTER));
AiMetaDataSetBool(nentry, NULL, "parallel_driver_needs_bucket", true);
AiMetaDataSetBool(nentry, NULL, "parallel_driver_prepare_bucket", true);
AiMetaDataSetBool(nentry, NULL, "parallel_driver_write_bucket", true);
}

node_initialize
Expand Down Expand Up @@ -88,13 +111,30 @@ node_update
if (data->regionMinY == defaultValue)
data->regionMinY = 0;

// This driver might have an array of names & pointers, that we will use
// to create a buffers map. It will return us the appropriate buffer for each AOV name
AtArray *buffer_names = AiNodeGetArray(node, str::buffer_names);
AtArray *buffer_pointers = AiNodeGetArray(node, str::buffer_pointers);
unsigned int buffer_names_count = buffer_names ? AiArrayGetNumElements(buffer_names) : 0;
unsigned int buffer_pointers_count = buffer_pointers ? AiArrayGetNumElements(buffer_pointers) : 0;
unsigned int buffer_count = AiMin(buffer_names_count, buffer_pointers_count);
data->buffers.clear();
for (unsigned int i = 0; i < buffer_count; ++i) {
AtString buffer_name = AiArrayGetStr(buffer_names, i);
HdArnoldRenderBuffer *buffer_pointer = (HdArnoldRenderBuffer*)AiArrayGetPtr(buffer_pointers, i);
if (buffer_pointer != nullptr && !buffer_name.empty()) {
data->buffers[buffer_name] = buffer_pointer;
}
}
}

node_finish {}

driver_supports_pixel_type
{
return pixel_type == AI_TYPE_RGBA || pixel_type == AI_TYPE_VECTOR || pixel_type == AI_TYPE_INT;
return pixel_type == AI_TYPE_RGBA || pixel_type == AI_TYPE_RGB || pixel_type == AI_TYPE_VECTOR ||
pixel_type == AI_TYPE_VECTOR2 || pixel_type == AI_TYPE_FLOAT || pixel_type == AI_TYPE_INT;

}

driver_extension { return supportedExtensions; }
Expand Down Expand Up @@ -126,7 +166,12 @@ driver_process_bucket
return outputName == name;
};
while (AiOutputIteratorGetNext(iterator, &outputName, &pixelType, &bucketData)) {
if (pixelType == AI_TYPE_VECTOR && checkOutputName(str::P)) {

auto it = driverData->buffers.find(outputName);
if (it != driverData->buffers.end()) {
it->second->WriteBucket(
bucket_xo - driverData->regionMinX, bucket_yo - driverData->regionMinY, bucket_size_x, bucket_size_y, _GetFormatFromArnoldType(pixelType), bucketData);
} else if (pixelType == AI_TYPE_VECTOR && checkOutputName(str::P)) {
positionData = bucketData;
} else if (pixelType == AI_TYPE_INT && checkOutputName(str::hydraPrimId)) {
if (driverData->idBuffer) {
Expand Down
2 changes: 0 additions & 2 deletions libs/render_delegate/nodes/nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
PXR_NAMESPACE_OPEN_SCOPE

extern const AtNodeMethods* HdArnoldDriverMainMtd;
extern const AtNodeMethods* HdArnoldDriverAOVMtd;

namespace {
struct NodeDefinition {
Expand All @@ -53,7 +52,6 @@ using BuiltInNodes = std::vector<NodeDefinition>;
const auto builtInNodes = []() -> const BuiltInNodes& {
static const BuiltInNodes ret{
{AI_NODE_DRIVER, AI_TYPE_UNDEFINED, str::HdArnoldDriverMain, HdArnoldDriverMainMtd},
{AI_NODE_DRIVER, AI_TYPE_UNDEFINED, str::HdArnoldDriverAOV, HdArnoldDriverAOVMtd},
};
return ret;
};
Expand Down
3 changes: 3 additions & 0 deletions libs/render_delegate/nodes/nodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ struct DriverMainData {
// Local storage for the color buffer.
std::vector<AtRGBA> colors[AI_MAX_THREADS];

// Map of buffers per AOV name
std::unordered_map<AtString, HdArnoldRenderBuffer*, AtStringHash> buffers;

// Store the region Min so that we apply an offset when negative
// pixel coordinates are needed for overscan
int regionMinX = 0;
Expand Down
1 change: 0 additions & 1 deletion libs/render_delegate/render_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ class HdArnoldRenderBuffer : public HdRenderBuffer {
struct BufferDefinition {
HdAovSettingsMap settings; ///< Filter and AOV settings for the Render Buffer.
HdArnoldRenderBuffer* buffer = nullptr; ///< HdArnoldRenderBuffer pointer.
AtNode* driver = nullptr; ///< Arnold driver.
AtNode* filter = nullptr; ///< Arnold filter.
AtNode* writer = nullptr; ///< Arnold AOV write node for primvar AOVs.
AtNode* reader = nullptr; ///< Arnold user data reader for primvar AOVs.
Expand Down
33 changes: 16 additions & 17 deletions libs/render_delegate/render_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,9 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt
const auto* mainDriverName = AiNodeGetName(_mainDriver);
int bufferIndex = 0;
int filterIndex = 0;
std::vector<AtString> buffer_names;
std::vector<void*> buffer_pointers;

for (const auto& binding : aovBindings) {
auto& buffer = _renderBuffers[binding.aovName];
// Sadly we only get a raw pointer here, so we have to expect hydra not clearing up render buffers
Expand Down Expand Up @@ -730,16 +733,7 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt
format = TfToken(it->second.UncheckedGet<std::string>());
}

// Creating a separate driver for each aov.
AtString driverNameStr = _renderDelegate->GetLocalNodeName(
AtString{TfStringPrintf("HdArnoldRenderPass_aov_driver_%d", ++bufferIndex).c_str()});

buffer.driver = _renderDelegate->CreateArnoldNode(str::HdArnoldDriverAOV,
driverNameStr);

AiNodeSetPtr(buffer.driver, str::aov_pointer, buffer.buffer);

// const auto arnoldTypes = _GetArnoldAOVTypeFromTokenType(format);
// const auto arnoldTypes = _GetArnoldAOVTypeFromTokenType(format);
const ArnoldAOVTypes arnoldTypes = GetArnoldTypesFromFormatToken(format);

const char* aovName = nullptr;
Expand Down Expand Up @@ -786,18 +780,26 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt
if (binding.aovName == str::t_crypto_asset ||
binding.aovName == str::t_crypto_material ||
binding.aovName == str::t_crypto_object)
_renderDelegate->RegisterCryptomatteDriver(driverNameStr);
_renderDelegate->RegisterCryptomatteDriver(AtString(mainDriverName));

buffer_pointers.push_back((void*)buffer.buffer);
buffer_names.push_back(AtString(aovName));

output = AtString{
TfStringPrintf(
"%s %s %s %s", aovName, arnoldTypes.outputString, filterName, AiNodeGetName(buffer.driver))
"%s %s %s %s", aovName, arnoldTypes.outputString, filterName, mainDriverName)
.c_str()};

AiNodeSetPtr(buffer.driver, str::input, imager);

}
outputs.push_back(output);
}
if (buffer_names.empty() || buffer_names.size() != buffer_pointers.size()) {
AiNodeResetParameter(_mainDriver, str::buffer_names);
AiNodeResetParameter(_mainDriver, str::buffer_pointers);
} else {
AiNodeSetArray(_mainDriver, str::buffer_names, AiArrayConvert(buffer_names.size(), 1, AI_TYPE_STRING, &buffer_names[0]));
AiNodeSetArray(_mainDriver, str::buffer_pointers, AiArrayConvert(buffer_pointers.size(), 1, AI_TYPE_POINTER, &buffer_pointers[0]));
}
// We haven't initialized the custom products yet.
// At the moment this won't work if delegate render products are set interactively, as this is only meant to
// override the output driver for batch renders. In Solaris,
Expand Down Expand Up @@ -1035,9 +1037,6 @@ void HdArnoldRenderPass::_ClearRenderBuffers()
if (buffer.second.filter != nullptr) {
_renderDelegate->DestroyArnoldNode(buffer.second.filter);
}
if (buffer.second.driver != nullptr) {
_renderDelegate->DestroyArnoldNode(buffer.second.driver);
}
if (buffer.second.writer != nullptr) {
_renderDelegate->DestroyArnoldNode(buffer.second.writer);
}
Expand Down