# RPrims with enabled then disabled render purposes are stilled "sync'ed"

**URL:** <https://forum.aousd.org/t/rprims-with-enabled-then-disabled-render-purposes-are-stilled-synced/1514>\
**Category:** Hydra\
**Created:** [May 15, 2024, 1:20pm UTC](https://forum.aousd.org/t/rprims-with-enabled-then-disabled-render-purposes-are-stilled-synced/1514 "2024-05-15T13:20:53Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![deboisj](https://avatars.discourse-cdn.com/v4/letter/d/d78d45/32.png) [@deboisj](https://forum.aousd.org/u/deboisj)\
**Post date:** [May 15, 2024, 1:20pm UTC](https://forum.aousd.org/t/rprims-with-enabled-then-disabled-render-purposes-are-stilled-synced/1514/1 "2024-05-15T13:20:53Z")

</div>

Hello,

I am working on a render delegate, where I first noticed this issue. But then also saw that it happens in Storm/USDVIEW (tried in different versions, including 0.24.05)

Consider this scenario :

The USD render purposes, when loaded, seem to linger if toggled off. For example consider this scenario, in USDVIEW :

- A scene with vertex animation, there is a `proxy` mesh and a heavy `render` mesh.
- Loaded in USD view, initially only the proxy mesh is displayed → High FPS.
- Turn OFF the proxy purpose + Turn ON render purpose → lower FPS / higher memory usage, as expected.
- But now… toggle back to proxies → Still low FPS

In my delegate, I see that the mesh ::Sync() is still called for the render mesh even if the render purpose is not wanted, with the obvious performance implications.

I found several issues that seem related :

> [@Display purposes not being properly updated in 22.03+](https://forum.aousd.org/t/display-purposes-not-being-properly-updated-in-22-03/925):
>
> Hey everyone, Josh from Weta Digital here slightly_smiling_face We are currently in the middle of updating the Hydra render delegate of our real time renderer from 21.08 to 23.08, and one thing that sticked out is how display purposes are not properly respected anymore following the API updates that happened in 21.11/22.03. Adding support for tracking of the task render tags version in the HdRenderPass was apparently not enough. From my print debugging, I can draw a couple of observations,…

> <https://github.com/PixarAnimationStudios/OpenUSD/issues/1597>
>
> \### Description of Issue
> UsdImagingDelegate filters calls to execute by the cur…rent purpose, so that only rprims whose purpose is displayed are synchronized. The same is not true for sprims. During execute all sprims are synchronized, which is a performance problem for Vp2RenderDelegate (and UsdView), because sprims which are not necessary to draw the current view are synchronized & the cost of that synchronization can be high (loading textures).
> 
> Part of the problem is that purpose is ignored while populating the scene. Rprims which will not be sync'd are created, and when they are created the sprims associated with them are also created. Those sprims \_will\_ get synchronized and consume significant time during loading.
> 
> I thought that perhaps the populate step could be made purpose-aware, which would prevent unnecessary rprims from being created, which in turn would prevent unnecessary sprims from being created.
> 
> One possible workaround would be to use either the excludedPrimPaths or invisedPrimPaths parameters of UsdImagingDelegate::Populate(). This would possibly work, but there would be complications because both of these parameters exclude the children of the given path, and purpose is not necessarily inherited by children.
> 
> If you can provide any advice for minimizing the overhead of syncing unused sprims it would be very much appreciated.
> 
> You can easily reproduce this with the ALab scene in UsdView. Configure your UsdView to display none of the USD purposes and then load ALab. It takes me around 40s for this operation to complete. The time mostly goes into allocating and loading textures. MayaUSD has a similar issue.
> 
> This issue was originally logged against MayaUSD as https://github.com/Autodesk/maya-usd/issues/1624, and my investigation into that issue has lead me to log this issue vs. USD.
> 
> \### Steps to Reproduce
> 1. Load a scene with many textures in Vp2RenderDelegate or UsdView, and profile the loading step. I tested ALab and it takes me around 40s to load in MayaUSD or in UsdView. In both cases nearly all the execution time is spent on texture loading.
> 
> \### System Information (OS, Hardware)
> Windows 10
> Nvidia RTX A6000
> 
> \### Package Versions
> USD version 0.21.05
> Maya & MayaUSD from Maya's Beta site, but I believe this is reproducible with any Maya version.
> 
> \### Build Flags

> <https://github.com/PixarAnimationStudios/OpenUSD/issues/801>
>
> \### Description of Issue
> When using Embree, once a display purpose has been ena…bled, disabling the purpose does not stop it from being rendered in the viewport.
> 
> \### Steps to Reproduce
> 1. Load the following into usdview:
> \`\`\`#usda 1.0
> def Xform "test"
> {
> def Sphere "sphere"
> {
> double3 xformOp:translate = (0, 0, 0)
> uniform token\[\] xformOpOrder = \["xformOp:translate"\]
> uniform token purpose = "render"
> }
> def Cube "box"
> {
> double3 xformOp:translate = (3, 0, 0)
> uniform token\[\] xformOpOrder = \["xformOp:translate"\]
> uniform token purpose = "proxy"
> }
> }
> \`\`\`
> 2. Enable Embree rendering
> 3. Toggle on and off render and proxy display purposes. Note that once a purpose has been enabled, it does not stop rendering, even when disabled. The prim bounding box does seem to update, but it's GL rendered.
> 
> Switching back to GL rendering, the behaviour is correct.
> 
> \### System Information (OS, Hardware)
> Linux, Centos 7
> 
> \### Package Versions
> USD 19.01

A seemingly relevant quote :

> Note that the design of purpose in hydra is to:  
> (1) Create a prim the first time its purpose is included in a draw call.  
> (2) Only update prims (via Sync) when their purpose is included in a draw call.  
> (3) Never delete prims based on purpose.

→ This is not what I am seeing, I am still getting the Sync() call in my render delegate even if the purpose if off. And I guess it is the same in storm, as the performance does not get back to normal when toggling “render” off.

Is there a bug here?

Another interesting one :

> I got our delegate to work but it is rather kludgy. It looks like Sync() is only called on rprims that should now be visible when the set changes, so I had that turn on any that are turned off. And RenderPass also tracks the RenderTags being passed to it, and if any tags are removed it goes through all the rprims and turns off (using a delegate-specific api) any that have that removed purpose. There is no need for RenderPass to turn anything on, Hydra is at least partially doing the right thing.
> 
> I recommend that Hydra destroy the rprims with the wrong purpose, as this would return the index to the same state it would be if created initially with that purpose set.
> 
> Further tests show that the new RenderTags are not sent to RenderPass until after Sync() is called on all the prims, so checking against them is useless. I will have to rely on the fact that Sync() is only called on objects that should be visible. This is going to limit what patches can be done, it does look like calling Finalize (and probably destroying) the unwanted prims is the only solution that will continue to work with code that works with the current version.

I am not entirely clear on everything mentionned here, but it sounds like perhaps there is indeed an issue, and hydra should be doing more, but that some solution can be done at the delegate level - right now I have some hack that exits the Sync() early if the purpose of the prim is not in use. But this sounds a bit better, although am not sure exactly how that would work - could someone expand a bit on this, is there code I could look at? I had tried to manually remove the rprims from the delegate when the purpose is toggled off, but that led to other issues, where when toggling back on the purpose, they would not get re-added properly…

I will keep digging around in the meantime,

Thanks alot!

---

<div class="post-metadata">

**Author:** ![ashum](https://avatars.discourse-cdn.com/v4/letter/a/bbe5ce/32.png) [@ashum](https://forum.aousd.org/u/ashum)\
**Post date:** [May 22, 2025, 8:30pm UTC](https://forum.aousd.org/t/rprims-with-enabled-then-disabled-render-purposes-are-stilled-synced/1514/2 "2025-05-22T20:30:23Z")

</div>

Hey,  
I’ve encountered similar behaviour

> <https://github.com/PixarAnimationStudios/OpenUSD/issues/3605>
>
> Hi,
> In https://github.com/PixarAnimationStudios/OpenUSD/blob/dev/pxr/imaging/hd/…dirtyList.cpp#L141 the render purpose tags stay dirty even when thir visibility is set to off.
> To reproduce the issue:
> Open usdView with no display purpose tags selected in View/"Display Purpose". Then toggle the render display purpose tag. Then toggle it again to turn it off. Observe the render display purpose tag still present.
> 
> This causes the following issue to happen: 
> When the render tag is present UpdateForTime and Get functions are called on the frame change. This is not needed and causes computations from procedural adapters that do computations to provide the data.
> To observe the redundant calls:
> Open usdView with no display purpose tags selected in View/"Display Purpose". Toggle the frame and observe the UpdateForTime NOT being called for the mesh prim adapter. Then toggle the render display purpose tag. Toggle the frame and observe the UpdateForTime being called for the mesh prim adapter. Then toggle it again to turn it off. Toggle the frame and observe the UpdateForTime being called for the mesh prim adapter.

I think the issue comes from the fact that once the render purpose tag is set to be visible it is always tracked after that.

---

<div class="post-metadata">

**Author:** ![deboisj](https://avatars.discourse-cdn.com/v4/letter/d/d78d45/32.png) [@deboisj](https://forum.aousd.org/u/deboisj)\
**Post date:** [May 22, 2025, 10:01pm UTC](https://forum.aousd.org/t/rprims-with-enabled-then-disabled-render-purposes-are-stilled-synced/1514/3 "2025-05-22T22:01:44Z")

</div>

For what it’s worth I ended up keeping track of the “active” render purposes myself to skip synchronization of rprims when not needed.
