I have multiple types of custom primitive with different intersection programs, some much simpler/quicker than others. For performance is it generally better practice to combine them all into a single GAS (when the scene graph permits) or to have a separate GAS for each type of custom primitive?
Thanks.
Hi @bdr,
For performance with today’s software & hardware, I’d guess it’s probably better to combine them. (Though to the degree that it’s realistic and easy enough to test, we always recommend trying it both ways and profiling.) I don’t think that building separate GASes will help reduce the divergence of intersection programs, unfortunately. And if you build separate GASes, then wherever they overlap, the ray has to traverse each one separately in the overlap region, which slows down the traversal time. If your separate GASes don’t overlap spatially, then traversal perf is probably not any worse with separate GASes, but in general I suspect there is mostly only risk associated with building separate GASes and no potential benefit.
–
David.
To be able to combine the custom primitives in a single GAS, you would need to have an über-intersection program which handles all these custom primitive types and for that you would need to decide which primitive index is what geometric type at runtime whereas individual intersection programs would know that.
So there would need to be some additional type identifier per primitive in your primitive attribute data and in case of completely different primitive attribute amounts per type, some way to access these accordingly (pointer casts for the win),
Then it’s just a question of how fast you can switch between the different intersection routines inside the intersection program handling these.
Not sure if that results in more or less code divergence than before when threads in a warp hit different primitive types. The traversal behavior would change, so the order of hit primitive types should be different.
You probably have primitive type identifier values already because that is normally used inside the optixReportIntersection hitKind’s lower 7 bits to indicate to the other program domains what custom primitive type has been hit, to be able to calculate the per primitive attributes when sharing hit programs among different primitive types.
If it helps with the acceleration structure traversal performance depends on the spatial distribution of your individual GAS before as David explained. Just benchmark it.
BTW, when merging everything into one GAS, try not to use the OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_GAS method but use OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING instead and put an instance acceleration structure (IAS) with an identity matrix on top if needed. That is fully hardware accelerated on RTX boards.
You should have an IAS already when using multiple GAS today.
Tracking primitive types is no problem, but do all custom primitives sharing a GAS need to have the same intersection program? The Programming Guide says, “All build inputs for a single build must agree on the build input type.” But I was thinking the intersection program could vary (by SBT entry) within a GAS if they are all custom primitive type.
I’ll definitely be keeping the IAS. I can’t merge everything, just some sets of geometry.
“All build inputs for a single build must agree on the build input type.”
That means that you cannot mix different geometric primitive types (e.g. built-in triangles and spheres) inside a single GAS.
With custom primitives you only provide the per primitive AABBs to the AS builder, so there is only one “type” of inputs, but you would need to handle the intersection of those.
Oh, I was assuming the goal was to handle all with a single Shader Binding Table entry.
If you use multiple different SBT hit records for different primitives via the sbtIndexOffsetBuffer then you can of course put different intersection programs into the different hit records.
In that case the differences would really only be multiple GAS with one SBT hit record each vs. a single GAS with multiple SBT hit records.
That’s an interesting experiment to do and should help when the AS overlaps are reduced due to the single GAS. Let us know how that goes.