Trouble with Shader Binding Table for Raytracing

Hi NVIDIA,

after playing with raytracing for a bit i ran into some trouble with the shader binding table.

The first one is that i cannot get shaderRecordNV to work. I specified a hit group SBT stride of 48 for the hitShaderBindingStride parameter in the vkCmdTraceRaysNV call and populated the first 16 bytes of each record with the hit group handles. This works as expected, and correctly selects different shaders for different BLAS based on VkGeometryInstanceNV::instanceOffset in the TLAS. But as soon as i try to access any value in the 32 bytes of application data following the hit group handles, my program just freezes. This only happens if i actually access the memory in the shader (closest hit), and that shader is actually called (if the geometry for the shader that does the access is not hit, the program works).
The GLSL code for the closest hit shader looks like this:

#version 460 core
#extension GL_NV_ray_tracing : require

rayPayloadInNV vec4 payload;
hitAttributeNV vec2 baryCoord;

layout(shaderRecordNV) buffer SR
{
	float test;
};

void main()
{
    // Does not work
    payload = vec4(0.0, 0.5 + test, 0.0, 1.0);

// Does work
    // payload = vec4(0.0, 0.5, 0.0, 1.0);
}

The app works as long as the “+ test” is omitted.

The second is that the sbtRecordStride for the traceNV call in the shader does not work as stated in the spec. This parameter should adjust the way different geometries in BLAS index the SBT. In case each BLAS has only one geometry, this parameter should do nothing. Yet it affects my shader in a strange way. It seems like it is first divided by 16 (the low 4 bit are ignored in all my tests) and is then simply added to the index, not multiplying it with the geometry index (which for my BLAS should be 0). So sbtRecordStride / 16 acts like sbtRecordOffset, which makes no sense.

I hope someone from NVIDIA can help me with this, i can provide traces or source code in private if required.

Spec:
Win 7 x64
RTX 2070
Driver 417.42
LunarG 1.1.92.1

Regards

I have done a little test and bound the hit group shader binding table also to a readonly storage buffer in the closest hit shader. I then set the instanceCustomIndex to the same value as instanceOffset for every VkGeometryInstanceNV in the TLAS. If i access the SBT in the shader like that manually, i get the expected and correct result. The closest hit shader is:

#version 460 core
#extension GL_NV_ray_tracing : require

struct sbt_entry_t
{
	uint _pad0[4]; // Shader group handle size is 16 byte
	uint buf;
	uint _pad1[7]; // Pad to 48 byte, my hit group SBT stride
};

layout(set = 0, binding = 2, std430) readonly buffer SBT
{
	sbt_entry_t sbts[];
};

rayPayloadInNV vec4 payload;
hitAttributeNV vec2 baryCoord;

layout(shaderRecordNV) buffer SR
{
	uint buf;
};

void main()
{
	sbt_entry_t sbt = sbts[gl_InstanceCustomIndexNV];

	// This works
	payload = vec4(0.0, 0.5 + float(sbt.buf), 0.0, 1.0);

	// This does not work
	// payload = vec4(0.0, 0.5 + float(buf), 0.0, 1.0);
}

So my SBT is set up correctly, but shaderRecordNV does not work. Any help would be appreciated.

Regards

Found the error. Turns out there was a bug in glslang that emitted wrong SPIR-V code for shaderRecordNV layout. It was fixed just a few days ago, so anyone who rans into this problem, grab the newest master of glslang from github to compile your shaders and it should be fixed. It did for me.

Regards