Can't get a buffer_reference to point to the right thing

Hi,

I’m having trouble working with buffer_reference with vulkan. I’m passing a buffer device address to my shader (a closest hit shader) through a uniform block but when I look at it with Nsight it doesn’t point to the right values.

Here’s my shader code

#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_EXT_scalar_block_layout : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
#extension GL_EXT_buffer_reference2 : require

layout(buffer_reference, scalar, std430) readonly buffer Indices
{
    uvec3 Index[];
};

layout(binding = 4, std140) uniform cb4
{
    Indices     indexBuffer;
};

layout(binding = 5, scalar, std430) readonly buffer RefIndex
{
    uvec3 data[];
};

I bound the buffer directly as well as RefIndex so I can compare the content in Nsight and it is not the same.

indexBuffer in the uniform block is given the returned value of vkGetBufferDeviceAddress of the same VkBuffer bound as RefIndex.

What am I missing ?

Edit : I have no warning/error from the debug layer. I’m using vulkan 1.2 on a rtx 3080 on windows 10.

One idea for you: GLSL_EXT_buffer_reference2 seems to imply that the reference type has a specific size. That wouldn’t be the case when the reference type contains an unsized array. In fact, the extension spec indicates one reason for its existance is to avoid doing what you’re doing:

If possible, you might want to pull the variable-length array one-level higher than the block you access via buffer_references. See materials and Material here:


Other related references:

Thanks for your reply,

If possible, you might want to pull the variable-length array one-level higher than the block you access via buffer_references. See materials and Material here

Do you mean something like this ?

layout(buffer_reference, scalar, std430) readonly buffer Indices
{
    uvec3 Index;
};

layout(binding = 4, std140) uniform cb4
{
    Indices     indexBuffer;
};

// ... 

Indices    indices      = Indices(obj.indexBuffer);
uvec3 triIndices        = indices[gl_PrimitiveID].Index;

That still doesn’t work and it NSight reads [7, 3155034112, 7] from the first index instead of [0, 1, 2]

I got the code following this tutorial
https ://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/#simplelighting/closesthit(raytrace.rchit))

Similar, yes. Though indexBuffer[i].Index would be closer to the example.

Also two other ideas for you. (I haven’t used this before, so you’re the expert.)

  1. Are you honoring the default buffer_reference_align of 16 with your packing (see the above quoted extension text)?
  2. In the buffer_reference decl, do the std430 qualifier and the scalar qualifier conflict?

By first, do you mean [0] or [1]? Is [0] correct?

I didn’t understand that I could specify the alignment using buffer_reference_align

Using this, I can access the correct indices without crashing and it turns out the Nsight view is buggy apparently since it doesn’t match the shader output if I output the indices I read.

layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer Indices
{
    uint Index;
};

Thanks a lot for your help

1 Like

Sure thing! And thanks for following up with your solution.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.