UsdImaging delegate, odd resync / dirty bits?


I noticed two strange (at least to me) behaviors of the UsdImaging delegate, in what gets resync or dirtied when modified.
I tried creating a simpler repro file, but I was only able for the material issue (1, below)… apologies. Both can happen in the ALAB scene (USD ALab Open Source Scene - Animal Logic)

  1. Materials that are descendants of xformable prims are flagged dirty (HdMaterial::DirtyResource) when an ancestor prim is moved. I can imagine some cases where a material may rely on the position in space of the prim it is bound to…still this seems strange. If I move the top level prim of a stage, it means all materials in the scene are dirtied every time.

  2. Adding an xformOp can cause a full resync of a subtree :
    I am moving prims around in the alab scene from a DCC, to do this, I am appending a matrixOp to the stack of the prim I am moving (unless i can reuse on op already there). The action of adding that xformOp causes a full resync of that subree, ouch. Modifying the value of the transformOp does not. I tried reproducing this in a simple scene, couldnt, so I am probably missing a variable here… The prim in question is an instance (even though there is only a single instance for that prototype). This means that in my render delegate, the rprim is recreated from scratch. Tried to trace a bit what happens on the USD side to cause this resync, but went a bit over my head…

Here is a simple script to reproduce both issues :

from pxr import Usd, UsdGeom, Gf

alabFile = "D:/Models/USD/alab-v2.0.0/ALab/entry.usda"

stage = Usd.Stage.Open(alabFile)

# Material issue : 
oscil = stage.GetPrimAtPath("/root/alab_set01/lab_workbench01_0001/workbench01/benchtop03/electronics_oscilloscope01_0001")
oscilXform = UsdGeom.Xformable(oscil)
oscilXform.AddTranslateOp(opSuffix='test').Set(Gf.Vec3d(10., 0., 0.))

# Resync issue, causes rprim in the subtree to be recreated from scratch in the render delegate...
roof = stage.GetPrimAtPath("/root/alab_set01/lab_structure01_0001/structure_roof_0001")
rootXform = UsdGeom.Xformable(roof)

Those case can hurt in terms of performance (expecially the resync), so I would like to understand better what happens (and why).

Thanks alot!

I can’t comment on the why without spelunking, but yes, UsdImagingDelegate does suffer from over-invalidation in part due to complexities/limitations of the Hydra 1.0 architecture.
Could you repeat your experiments with the stage scene index (set USDIMAGINGGL_ENGINE_ENABLE_SCENE_INDEX = 1) and report back, please?
We hope that the new architecture allows fine-grained invalidation, although the semantics of USD instancing are quite complicated, and it is possible that there is some conservative invalidation.

Thanks for the answer, sorry for the delay.

I can’t use USDIMAGINGGL_ENGINE_ENABLE_SCENE_INDEX as I am not using the GL engine. We have our own engine implementation. I guess this means I need to try moving to an implementation using scene indices. That was on the todo list anyway…

It will probably take me some time to get this prioritized, but I will report back when I attempt this.

I guess looking at difference in implementation here (scene delegate VS scene indices) will be the best way to go about it… OpenUSD/pxr/usdImaging/usdImagingGL/engine.h at f941bce34505c88eaf32dc79f36eab2659b2b1ee · PixarAnimationStudios/OpenUSD · GitHub