Keep getting [ 2][ ERROR]: Validation mode caught builtin exception OPTIX_EXCEPTION_CODE_BUILTIN_IS_MISMATCH

I am trying to make an optix program that implements a single type of ray (each buildinput has one SBT record), and three different primitive types that use different intersection shaders, but the same hit function. The program is intended to track the trajectory of rays of light propagating through translucent custom capsule shapes (linear curves), spheres, and triangular meshes.

The scene is built in this hierarchy:

And the Shader binding table is built with the hitgroup functions in order of custom primitive, sphere, then triangles.

Also the sbt-instance-offset is already set to 0 in all primitives.

Here is the full error message:

(19475, 0, 0) error: mismatch between builtin IS shader and build input
call location: No line information available for this exception.
(19475, 0, 0) transform list of size 0:
[ 2][ ERROR]: Validation mode caught builtin exception OPTIX_EXCEPTION_CODE_BUILTIN_IS_MISMATCH
Error recording resource event on user stream (CUDA error string: unspecified launch failure, CUDA error code: 719)
[ 4][ DISK CACHE]: Closed database: “/var/tmp/OptixCache_aidenlewis/optix7cache.db”
[ 4][ DISK CACHE]: Cache data size: “35.7 MiB”
[ 2][ ERROR]: Error releasing namedConstant’s internal resources (CUDA error string: unspecified launch failure, CUDA error code: 719)
Error synching on OptixPipeline event (CUDA error string: unspecified launch failure, CUDA error code: 719)
Error destroying OptixPipeline event (CUDA error string: unspecified launch failure, CUDA error code: 719)
Failed to destroy launch resources (CUDA error string: unspecified launch failure, CUDA error code: 719)
Error de-initializing device (CUDA error string: unspecified launch failure, CUDA error code: 719)
A runtime error occured.
An Optix runtime error occurred:
‘Error during validation mode run’
at (mcx_context.cpp:820)

error: mismatch between builtin IS shader and build input
Validation mode caught builtin exception OPTIX_EXCEPTION_CODE_BUILTIN_IS_MISMATCH

That means you used the wrong intersection shader for a built-in primitive, resp. the wrong SBT hit record.

I’m assuming you used OptixBuildInputCustomPrimitiveArray for GAS 1 and 5, OptixBuildInputSphereArray for GAS 2 and 6, OptixBuildInputTriangleArray for GAS 3 and 7.

Then Shader Binding Table (SBT) hit record entries for the GAS 1 and 5 must use a custom intersection program you implemented, GAS 2 and 6 must use the built-in sphere intersection program you get with optixBuiltinISModuleGet(), and GAS 3 and 7 must not have any intersection program inside the SBT hit record.

Also the sbt-instance-offset is already set to 0 in all primitives.

Please clarify what you mean with that.
There is a per primitive SBT index offset you can set inside the build inputs via the sbtIndexOffsetPointer/SizeInBytre/Stride fields which isn’t required when a GAS has only one SBT record.

Then there is the OptixInstance::sbtOffset field which is filling the sbt-instance-offset of the SBT index calculation formula inside the OptiX Programming Guide chapter 7.3

If you set that to zero for all instances in your scene, that would be your error.
You need to set that to the (base) SBT hit record index the assigned GAS traversable handle should use.
(“base index” because when using multiple contiguous SBT records per GAS, the OptixInstance sbtOffset is a prefix sum over all previous SBT indices in an IAS.)

So assuming you have 6 SBT hit records, one per GAS, then the six OptixInstance::sbtOffsets in your two IAS would need to be set to values 0 to 5.

You didn’t explain how you’re using the two different IAS. There might be other ways to setup the pipeline and SBT.

When sharing hit programs among different primitive types, use the optixGetHitKind function inside the hit programs to identify what primitive type has been hit to evaluate the respective intersection attributes.

Don’t forget to enable the primitive types the pipeline should support inside the OptixPipelineCompileOptions::usesPrimitiveTypeFlags.

(19475, 0, 0) transform list of size 0:

I’m not sure where this comes from. With a two level (IAS->GAS) hierarchy, there is always exactly one entry inside the transform list, the OptixInstance transform matrix.
Make sure you have your OptixPipelineCompileOptions.traversableGraphFlags set to OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING when each of your IAS is the top-level traversable handle of your scene.

If I do not set SBT stride offsets and sbt stride, then according to the formula the sbt-geometry-acceleration-structure-index should not play a role, correct?

sbt-index =
sbt-instance-offset
+ (sbt-geometry-acceleration-structure-index * sbt-stride-from-trace-call)
+ sbt-offset-from-trace-call

I also tried setting the sbt-instance-offset under instances to 0, 1, 2, 0, 1, 2, for the geometry acceleration structures in the picture, trying to use one shader binding table record for each pair of GAS. Is this not possible/should I be using 6 SBT records?

EDIT: I found an extra line duplicating my triangle GAS, which I have deleted. Now SBT record indexing seems to be working fine, thanks.

FOLLOW UP QUESTION: what would be the hit type id numbers returned for intersections of the built in spheres and triangles be?

FOLLOW UP QUESTION: what would be the hit type id numbers returned for intersections of the built in spheres and triangles be?

Hi @AidenLewis, I’m guessing Detlef meant to point you towards optixGetPrimitiveType(), which has constants defined for spheres & triangles, as well as the various built-in curve types. The older function optixGetHitKind() is now considered legacy and doesn’t distinguish between spheres and triangles. We now recommend using the device functions optixGetPrimitiveType(), optixIsFrontFaceHit(), and optixIsBackFaceHit() be used to replace any existing calls to optixGetHitKind().


David.