-
Notifications
You must be signed in to change notification settings - Fork 381
Closed
Description
Issue Description
The code below produces probably incorrect spirv. Vulkan pipeline creation fails, spirv-val produces following output:
error: line 100: Indexes passed to OpAccessChain must be of type integer.
%321 = OpAccessChain %_ptr_Function_uint %320 %316
Reproducer Code
static const uint MAX_NESTED_VOLUMES = 4;
static const int MATERIAL_LAYERS_MAX = 10;
struct MaterialFlags
{
static const uint32_t HAS_SCATTERING_VOLUME = 1 << 20;
};
struct Material
{
uint32_t flags = 0;
uint32_t layerCount = 0;
uint32_t layers[MATERIAL_LAYERS_MAX];
bool HasFlag(uint32_t mask)
{
return (flags & mask) != 0;
}
IVolume GetVolume()
{
if (HasFlag(MaterialFlags::HAS_SCATTERING_VOLUME)) {
return ScatteringVolume(PhaseFunction());
}
else {
return EmptyVolume();
}
}
};
[[vk::binding(1, 3)]]
StructuredBuffer<Material> materials;
struct PhaseFunction
{
void GenerateSample(uint channelIndex, float2 rnd, inout float3 sampleDirection, out float pdf)
{
sampleDirection = {};
pdf = {};
}
}
interface IVolume
{
void Integrate(float3 rayOrigin, float3 intersection, float4 rnd, inout float3 rayDirection, inout float tHit,
inout float3 throughput);
}
struct EmptyVolume : IVolume
{
float3 dummy1 = 0;
void Integrate(float3 rayOrigin, float3 intersection, float4 rnd, inout float3 rayDirection, inout float tHit,
inout float3 throughput)
{
}
}
struct ScatteringVolume : IVolume
{
PhaseFunction phase;
__init(PhaseFunction phase)
{
this.phase = phase;
}
void Integrate(float3 rayOrigin, float3 intersection, float4 rnd, inout float3 rayDirection, inout float tHit,
inout float3 throughput)
{
let rayDirectionBeforeScatter = rayDirection;
float phasePdf;
phase.GenerateSample(0, rnd.zw, rayDirection, phasePdf);
tHit = 0;
}
}
struct Payload
{
float2 _padding;
float tHit;
int volumeStackIndex;
uint volumeStack[MAX_NESTED_VOLUMES];
IVolume GetVolume()
{
if (volumeStackIndex == -1)
return EmptyVolume();
uint mid = volumeStack[volumeStackIndex];
return materials[mid].GetVolume();
}
}
[shader("closesthit")]
void main(inout Payload payload, in BuiltInTriangleIntersectionAttributes attr)
{
float3 throughput = 1;
IVolume volume = payload.GetVolume();
float3 o = {};
volume.Integrate(WorldRayOrigin(), {}, {}, o, payload.tHit, throughput);
}
compiled with
slangc.exe -entry main test.slang -o test.spv
Expected Behavior
The code should compile and pass spirv-val.
Environment
- Slang Version 2025.18 up to 2025.22.1 (2025.17.3 and older worked fine)