Renderer Configuration#
The renderer owns ovrtx’s GPU resources, runtime stage, stream-ordered work queue, and rendering pipeline. Create one renderer before loading USD or stepping RenderProducts.
Creating a Renderer#
# Create the Renderer and load a USD layer into it
print("Creating renderer. The first run of the application will take some time as shaders are compiled and cached...", file=sys.stderr)
renderer = ovrtx.Renderer()
print("Renderer created.", file=sys.stderr)
Configuration entries are passed through RendererConfig:
config = ovrtx.RendererConfig(
sync_mode=True,
log_file_path=str(output_dir / "config-test.log"),
log_level="info",
)
renderer = ovrtx.Renderer(config=config)
assert any(component > 0 for component in renderer.version)
assert renderer.config.sync_mode is True
assert renderer.config.log_level == "info"
assert renderer.config.log_file_path == str(output_dir / "config-test.log")
// Create the renderer, optionally providing configuration settings.
// In this case we need no configuration.
ovrtx_config_t config {};
std::cerr << "Creating renderer. The first run of the application will take some time as shaders are compiled and cached..." << std::endl;
result = ovrtx_create_renderer(&config, &renderer);
if (check_and_print_error(result, "create_renderer")) {
return 1;
}
std::cerr << "Renderer created." << std::endl;
Version and config-entry setup use ovrtx_config_t:
uint32_t major = 0;
uint32_t minor = 0;
uint32_t patch = 0;
ovrtx_get_version(&major, &minor, &patch);
ovrtx_config_entry_t entries[] = {
ovrtx_config_entry_log_level(ovx_str("info")),
ovrtx_config_entry_sync_mode(true),
};
ovrtx_config_t config{entries, 2};
ovrtx_renderer_t* configured_renderer = nullptr;
ovrtx_result_t create_result = ovrtx_create_renderer(&config, &configured_renderer);
ASSERT_API_SUCCESS(create_result.status);
ASSERT_NE(configured_renderer, nullptr);
ovrtx_destroy_renderer(configured_renderer);
Configuration Entries#
Common configuration entries include:
|
Description |
|---|---|
|
Write renderer logs to a file. |
|
Set log verbosity. |
|
Point to a custom binary package root. |
|
Keep shared graphics resources alive after the last renderer. |
|
Restrict renderer-level CUDA-visible devices. |
|
Select the Vulkan backend where supported. |
Config-entry helper |
Description |
|---|---|
Write renderer logs to a file. |
|
Set log verbosity. |
|
Point to a custom binary package root. |
|
Keep shared graphics resources alive after the last renderer. |
|
Restrict renderer-level CUDA-visible devices. |
|
Select the Vulkan backend where supported. |
Renderer-level active_cuda_gpus must be compatible with any per-RenderProduct
deviceIds allow-list. See RenderProduct Device Pinning.
Runtime Package Layout#
With dynamic linking, ovrtx expects the binary package bin layout to stay
together next to libovrtx-dynamic.so or ovrtx-dynamic.dll. The runtime
package includes directories such as cache, library, libs, mdl,
plugins, rendering-data, and usd_plugins.
Set binary_package_root_path only when static linking ovrtx or when a custom
deployment layout separates the loader library from the package directories.
Multi-Renderer Processes#
For processes that create and destroy multiple renderers, initialize ovrtx once up front when using the C API, then shut it down once all renderers are gone.
ovrtx_config_entry_t ovrtx_config_entries[] = {
ovrtx_config_entry_selection_outline_enabled(true),
ovrtx_config_entry_selection_outline_width(4),
ovrtx_config_entry_selection_fill_mode(OVRTX_SELECTION_FILL_MODE_GROUP_FILL_COLOR),
};
ovrtx_config_t ovrtx_config = {};
ovrtx_config.entries = ovrtx_config_entries;
ovrtx_config.entry_count =
sizeof(ovrtx_config_entries) / sizeof(ovrtx_config_entries[0]);
ovrtx_result_t result = ovrtx_create_renderer(&ovrtx_config, &renderer);
if (check_and_print_error(result, "create_renderer")) {
return 1;
}
if (!configure_selection_style(renderer)) {
ovrtx_destroy_renderer(renderer);
return 1;
}
On Linux headless systems, repeatedly creating and destroying renderers can
force shared graphics resources to unload and reload. If that causes native
driver crashes, configure keep_system_alive=True and initialize ovrtx before
creating renderers. If the issue persists, set
VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING=1 in the process environment.
Cleanup#
Python releases renderer resources when the Renderer object is destroyed.
In C, cleanup is explicit:
// Unmap output
ovrtx_cuda_sync_t no_sync = {};
result = ovrtx_unmap_render_var_output(
renderer, rendered_output.map_handle, no_sync);
if (check_and_print_error(result, "unmap_render_var_output")) {
ovrtx_destroy_results(renderer, step_result_handle);
ovrtx_destroy_renderer(renderer);
return 1;
}
// Clean up resources (ovrtx will warn if results are leaked)
result = ovrtx_destroy_results(renderer, step_result_handle);
result = ovrtx_destroy_renderer(renderer);
if (check_and_print_error(result, "destroy_renderer")) {
return 1;
}