Skip to content

Commit cd07435

Browse files
hzqstTheMostDiligent
authored andcommitted
SPIRVShaderResources: Add support for push constants (#733)
1 parent 4d99b90 commit cd07435

File tree

14 files changed

+915
-82
lines changed

14 files changed

+915
-82
lines changed

Graphics/ShaderTools/include/SPIRVShaderResources.hpp

Lines changed: 116 additions & 53 deletions
Large diffs are not rendered by default.

Graphics/ShaderTools/src/SPIRVShaderResources.cpp

Lines changed: 175 additions & 29 deletions
Large diffs are not rendered by default.

Tests/DiligentCoreTest/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ if(NOT WEBGPU_SUPPORTED)
2020
)
2121
endif()
2222

23+
if(NOT ${DILIGENT_USE_SPIRV_TOOLCHAIN} OR ${DILIGENT_NO_GLSLANG})
24+
list(REMOVE_ITEM SOURCE
25+
${CMAKE_CURRENT_SOURCE_DIR}/src/ShaderTools/SPIRVShaderResourcesTest.cpp
26+
)
27+
endif()
28+
2329
set_source_files_properties(${SHADERS} PROPERTIES VS_TOOL_OVERRIDE "None")
2430

2531
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Test for acceleration structures
2+
// GLSL ray gen shader for testing acceleration structure resource reflection
3+
#version 460
4+
#extension GL_EXT_ray_tracing : require
5+
6+
layout(set = 0, binding = 0) uniform accelerationStructureEXT g_AccelStruct;
7+
8+
layout(location = 0) rayPayloadEXT vec4 payload;
9+
10+
void main()
11+
{
12+
// Use traceRayEXT to ensure g_AccelStruct is actually used and not optimized away
13+
// This is the proper way to use acceleration structures in ray gen shaders
14+
const vec2 uv = vec2(gl_LaunchIDEXT.xy + 0.5) / vec2(gl_LaunchSizeEXT.xy);
15+
const vec3 origin = vec3(uv.x, 1.0 - uv.y, -1.0);
16+
const vec3 direction = vec3(0.0, 0.0, 1.0);
17+
18+
payload = vec4(0.0);
19+
traceRayEXT(g_AccelStruct, // acceleration structure (first parameter)
20+
gl_RayFlagsNoneEXT, // ray flags
21+
0xFF, // cullMask
22+
0, // sbtRecordOffset
23+
1, // sbtRecordStride
24+
0, // missIndex
25+
origin, // ray origin
26+
0.01, // ray min range
27+
direction, // ray direction
28+
10.0, // ray max range
29+
0); // payload location
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Test for atomic counters
2+
// GLSL fragment shader for testing atomic counter resource reflection
3+
// Note: Vulkan does not support atomic_uint (AtomicCounter storage class).
4+
// We use a storage buffer with atomic operations to simulate atomic counters.
5+
// However, this will be reflected as RWStorageBuffer, not AtomicCounter.
6+
#version 450
7+
8+
layout(binding = 0) coherent buffer AtomicCounterBuffer
9+
{
10+
uint counter;
11+
} g_AtomicCounter;
12+
13+
layout(location = 0) out vec4 FragColor;
14+
15+
void main()
16+
{
17+
// Increment atomic counter using atomicAdd
18+
// atomicAdd returns the value before the addition
19+
uint counterValue = atomicAdd(g_AtomicCounter.counter, 1u);
20+
21+
// Create a color based on counter value
22+
vec4 color = vec4(
23+
float(counterValue & 0xFFu) / 255.0,
24+
float((counterValue >> 8u) & 0xFFu) / 255.0,
25+
float((counterValue >> 16u) & 0xFFu) / 255.0,
26+
1.0
27+
);
28+
29+
FragColor = color;
30+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Test for input attachments (subpass inputs)
2+
// In HLSL, subpass inputs are declared using SubpassInput type with vk::input_attachment_index attribute
3+
[[vk::input_attachment_index(0)]]
4+
[[vk::binding(0)]]
5+
SubpassInput<float4> g_InputAttachment;
6+
7+
float4 main() : SV_Target
8+
{
9+
// Read from input attachment (subpass input)
10+
float4 color = g_InputAttachment.SubpassLoad();
11+
12+
// Process the input color
13+
return color * 2.0;
14+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Test for mixed resources to verify all resource types work together
2+
3+
struct BufferData
4+
{
5+
float4 data[4];
6+
};
7+
8+
// Uniform buffer
9+
cbuffer UniformBuff : register(b0)
10+
{
11+
float4x4 g_WorldViewProj;
12+
float4 g_MaterialParams;
13+
};
14+
15+
// Read-only structured buffer
16+
StructuredBuffer<BufferData> ROStorageBuff : register(t0);
17+
18+
// Read-write structured buffer
19+
RWStructuredBuffer<BufferData> RWStorageBuff : register(u0);
20+
21+
// Sampled texture
22+
Texture2D<float4> SampledTex : register(t1);
23+
24+
// Storage texture
25+
RWTexture2D<float4> StorageTex : register(u1);
26+
27+
// Sampler
28+
SamplerState Sampler : register(s0);
29+
30+
// Test for push constants
31+
struct PushConstants_t
32+
{
33+
float2 Offset;
34+
float Time;
35+
uint FrameCount;
36+
};
37+
38+
[[vk::push_constant]]
39+
cbuffer PushConstants
40+
{
41+
PushConstants_t g_PushConstants;
42+
};
43+
44+
float4 main() : SV_Target
45+
{
46+
// Use uniform buffer data
47+
float4 color = g_MaterialParams;
48+
49+
// Read from RO structured buffer
50+
color += ROStorageBuff[0].data[0];
51+
52+
// Write to RW structured buffer
53+
RWStorageBuff[1].data[1] = color * 2.0;
54+
55+
// Sample texture
56+
color += SampledTex.Sample(Sampler, float2(0.5, 0.5));
57+
58+
// Write to storage texture
59+
StorageTex[uint2(0, 0)] = color;
60+
61+
// Use push constant data
62+
color.xy += g_PushConstants.Offset;
63+
color.rgb *= sin(g_PushConstants.Time) * 0.5 + 0.5;
64+
65+
return color;
66+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Test for push constants
2+
struct PushConstants_t
3+
{
4+
float4x4 g_MVPMatrix;
5+
float4 g_Color;
6+
float2 g_Offset;
7+
float g_Scale;
8+
uint g_Padding;
9+
};
10+
11+
[[vk::push_constant]]
12+
cbuffer PushConstants
13+
{
14+
PushConstants_t g_PushConstants;
15+
};
16+
17+
float4 main() : SV_Target
18+
{
19+
// Use push constant data through the structure instance
20+
float4 result = g_PushConstants.g_Color * g_PushConstants.g_Scale;
21+
22+
// Apply offset to result (simplified example)
23+
result.xy += g_PushConstants.g_Offset;
24+
25+
return result;
26+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Test for storage buffers (structured buffers and byte address buffers)
2+
struct BufferData0
3+
{
4+
float4 data0;
5+
float4 data1;
6+
};
7+
8+
struct BufferData1
9+
{
10+
float4 data0;
11+
float4 data1;
12+
float4 data2;
13+
float4 data3;
14+
};
15+
16+
// Read-only structured buffer
17+
StructuredBuffer<BufferData0> g_ROBuffer : register(t0);
18+
19+
// Read-write structured buffer
20+
RWStructuredBuffer<BufferData1> g_RWBuffer : register(u0);
21+
22+
// Atomic counter buffers
23+
ByteAddressBuffer g_ROAtomicBuffer : register(t1);
24+
RWByteAddressBuffer g_RWAtomicBuffer : register(u1);
25+
26+
float4 main() : SV_Target
27+
{
28+
float4 result = float4(0.0, 0.0, 0.0, 0.0);
29+
30+
// Read from RO buffer
31+
result += g_ROBuffer[0].data0;
32+
result += g_ROBuffer[1].data1;
33+
34+
// Write to RW buffer
35+
g_RWBuffer[0].data0 = result;
36+
g_RWBuffer[1].data1 = result * 2.0;
37+
38+
// Atomic operations
39+
uint atomicValue = g_ROAtomicBuffer.Load(0);
40+
g_RWAtomicBuffer.Store(0, atomicValue + 1);
41+
42+
return result;
43+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Test for storage images (read-write textures)
2+
// Note: HLSL does not support RWTextureCube, so we only test 2D, 2DArray, and 3D storage images
3+
RWTexture2D<float4> g_RWImage2D : register(u0);
4+
RWTexture2DArray<float4> g_RWImage2DArray : register(u1);
5+
RWTexture3D<float4> g_RWImage3D : register(u2);
6+
7+
float4 main() : SV_Target
8+
{
9+
// Write to storage images
10+
g_RWImage2D[uint2(0, 0)] = float4(1.0, 0.0, 0.0, 1.0);
11+
g_RWImage2DArray[uint3(0, 0, 0)] = float4(0.0, 1.0, 0.0, 1.0);
12+
g_RWImage3D[uint3(0, 0, 0)] = float4(0.0, 0.0, 1.0, 1.0);
13+
14+
// Read back and combine
15+
float4 color = g_RWImage2D[uint2(0, 0)];
16+
color += g_RWImage2DArray[uint3(0, 0, 0)];
17+
color += g_RWImage3D[uint3(0, 0, 0)];
18+
19+
return color;
20+
}

0 commit comments

Comments
 (0)