[resolved] GeometryInstance variable scope

I have a variable declared per RTgeometryinstance as follows:

// Device attribute program
rtDeclareVariable(int, sole_material, , ) = -1; /* sole material index to use for all triangles, or -1 to use per-triangles material index */

// Host
if (node->sole_material != -1)
	applyGeometryInstanceVariable1i(context, node->instance, "sole_material", node->sole_material);

This produces the following warning from OptiX:

PERF WARNING:     Variable "sole_material" used in program "_Z14mesh_attributev" (ATTRIBUTE) is declared at different scopes (Unknown, GeometryInstance).
PERF WARNING:     For best runtime performance, a variable should be declared at one scope only, and in the same order with other variables on that scope.

I have only declared the variable once in the host code and once in the device code, but I do have multiple geometry instances. Is there anything I can do the resolve the performance issue?

Furthermore, if I have a more complicated scene structure (RTgeometryinstances within RTgeometrygroups within RTgroups within a top-level RTgroup), then OptiX will not assign the correct sole_material value to each RTgeometryinstance. Instead, all of the instances will have whatever value I assigned to the first instance. I realize complex scene hierarchies are not recommended for performance reasons, but is there a reason that this fails?

1.) According to your code you declared the sole_material with a default value of -1 inside the attribute program. That would be at program scope. The default value has the least precedence and is only used if the same variable is not declared in any other scope.

The default value actually doesn’t appear in this table of variable scoping. Think of default values to be at the end of the table’s rows.
http://raytracing-docs.nvidia.com/optix_6.0/guide/index.html#programs#program-variable-scoping

Since you declared the variable per GeometryInstance on the host as well, the attribute program will source it from there instead of the default value at the program scope.
It’s slower to do these dynamic scope resolves in OptiX than when only declaring variables exactly at the scope where they are needed. That’s what the warning is about.

I would remove the -1 default value and make sure that each GeometryInstance gets the proper initialization.
That should remove the usage report warning and be potentially faster.

2.) I can’t say what is happening with your variables at the GeometryInstance scope. Assuming these GeometryInstances are not shared, that should just work. I’m using different variables per GeometryInstance all the time, except that I don’t have two levels of Group -> Group and no duplicate variables declared at the attribute program.

If the attribute program would just unconditionally calculate all attributes sourced in all any_hit and closest_hit programs which can be reached afterwards, the material index variable would then only need to be declared inside the any_hit and closest_hit programs and is always taken from the GeometryInstance scope.

Is it generally recommended not to add default values to rtDeclareVariable statements? I’m unsure on the overhead of declaring a variable that rarely changes versus using a default value.

This worked to remove the warning message, but it did not resolve the issue with incorrect variable assignment to different GeometryInstances.

The issue only occurs when there are two (or more) levels of Groups. This is also not new to OptiX 6. It goes back at least to OptiX 3.9.

It doesn’t seem to matter which program uses the variable. If I reference the GeometryInstance variable from within the closest hit program instead of the attribute program for a Group within a Group, I still get the same behavior.

It only comes in handy if you’re actually doing things which require different values at different scopes, if you really need to override values in the scope hierarchy.
I’m not using default values in my applications. All my OptiX variables are declared at exactly one scope.
Though I don’t know what the actual overhead is to look up the variables dynamically when they are declared in multiple scopes.

Could you please send a reproducer for that? Thanks.

I have sent a trace to the help email.

The issue with multiple levels of Groups turned out to be the result of a malformed tree in which all nodes were orphaned except the last one to be assigned. Fixing the tree formation solved the issue.

This sets a personal record for the longest it has taken me to track down a bug.