yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

venkataram-nvWarn when inout parameter is never written (#4777)20bd48659

master
4.4 KiB187 linesraw
1// trace-ray-inline.slang
2
3//TEST:CROSS_COMPILE:-target dxil-asm -stage compute -profile sm_6_5 -entry main -line-directive-mode none
4//TEST:SIMPLE(filecheck=CHECK):-target spirv-asm -stage compute -profile glsl_460+GL_EXT_ray_query -entry main -line-directive-mode none
5
6// CHECK: OpCapability RayQueryKHR
7// CHECK: OpExtension "SPV_KHR_ray_query"
8// CHECK: OpRayQueryInitializeKHR
9// CHECK: OpRayQueryProceedKHR
10// CHECK: OpRayQueryGetIntersectionTypeKHR
11// CHECK: OpRayQueryConfirmIntersectionKHR
12
13// The goal of this shader is to use all the main pieces
14// of functionality in DXR 1.1's `TraceRayInline` feature,
15// to ensure that they survive translation to HLSL.
16
17// In order to trace rays, we need an acceleration structure.
18//
19RaytracingAccelerationStructure myAccelerationStructure;
20
21// We also need to decide what to do with hits/misses.
22// The `TraceRayInline` approach eschews separate shader
23// stages for RT, and instead expects users to write
24// those operations as subroutines instead.
25//
26// We will mimic the style and naming of DXR 1.0 here
27// to try and make the parallels clear.
28//
29// We start with a ray "payload" type that will be
30// used for input/output on hit and miss shaders
31//
32
33struct MyRayPayload
34{
35	int value;
36};
37
38// The first and simplest shader is the miss shader.
39//
40void myMiss(inout MyRayPayload payload)
41{
42	payload.value = 0;
43}
44
45// Next, up is a closest hit shader for opaque triangles.
46//
47void myTriangleClosestHit(inout MyRayPayload payload)
48{
49	payload.value = 1;
50}
51
52// In order to support alpha testing, we need an any-hit
53// shader for triangles.
54//
55// In this case, the return value is used to specify
56// whether the hit should be accepted (true) or ignored (false).
57//
58bool myTriangleAnyHit(inout MyRayPayload payload)
59{
60    unmodified(payload);
61	return true;
62}
63
64// Procedural primitives are different than triangles
65// in that they need user-defined hit attributes.
66//
67struct MyProceduralHitAttrs { int value; }
68
69// Otherwise, the closest- and any-hit shaders
70// for procedural primitives are similar to those
71// for triangles.
72//
73void myProceduralClosestHit(inout MyRayPayload payload, MyProceduralHitAttrs attrs)
74{
75	payload.value = attrs.value;
76}
77bool myProceduralAnyHit(inout MyRayPayload payload)
78{
79    unmodified(payload);
80	return true;
81}
82
83// The new piece of the puzzle for procedural primitives
84// is the intersection shader, which should be able to
85// report zero or more intersections.
86//
87// For now we will only deal with the single-intersection
88// case.
89//
90bool myProceduralIntersection(inout float tHit, inout MyProceduralHitAttrs hitAttrs)
91{
92    unmodified(tHit);
93    unmodified(hitAttrs);
94	return true;
95}
96
97RWStructuredBuffer<int> resultBuffer;
98
99// In order to kick of tracing we need the properties of a ray
100// query to trace, so we will pipe those in via a constant buffer.
101//
102cbuffer C
103{
104	float3 origin;
105	float tMin;
106	float3 direction;
107	float tMax;
108	uint rayFlags;
109	uint instanceMask;
110	uint shouldStopAtFirstHit;
111}
112
113// The actual tracing is handled by a compute shader,
114// which here takes on the role of a ray generation shader.
115//
116void main(uint3 tid : SV_DispatchThreadID)
117{
118	uint index = tid.x;
119
120	RayQuery<RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES> query;
121	MyProceduralHitAttrs committedProceduralAttrs;
122
123	MyRayPayload payload = { -1 };
124	RayDesc ray = { origin, tMin, direction, tMax };
125	query.TraceRayInline(
126		myAccelerationStructure,
127		rayFlags,
128		instanceMask,
129		ray);
130
131
132	for(;;)
133	{
134		if(!query.Proceed()) break;
135
136		switch(query.CandidateType())
137		{
138		case CANDIDATE_PROCEDURAL_PRIMITIVE:
139			{
140				MyProceduralHitAttrs candidateProceduralAttrs = { 0 };
141				float tHit = 0.0f;
142				if(myProceduralIntersection(tHit, candidateProceduralAttrs))
143				{
144					if(myProceduralAnyHit(payload))
145					{
146						query.CommitProceduralPrimitiveHit(tHit);
147						committedProceduralAttrs = candidateProceduralAttrs;
148						if(shouldStopAtFirstHit != 0)
149							query.Abort();
150					}
151				}
152			}
153			break;
154
155		case CANDIDATE_NON_OPAQUE_TRIANGLE:
156			{
157				if(myTriangleAnyHit(payload))
158				{
159					query.CommitNonOpaqueTriangleHit();
160					if(shouldStopAtFirstHit != 0)
161						query.Abort();
162				}
163			}
164			break;
165
166		}
167
168
169	}
170
171	switch(query.CommittedStatus())
172	{
173	case COMMITTED_TRIANGLE_HIT:
174		myTriangleClosestHit(payload);
175		break;
176
177	case COMMITTED_PROCEDURAL_PRIMITIVE_HIT:
178		myProceduralClosestHit(payload, committedProceduralAttrs);
179		break;
180
181	case COMMITTED_NOTHING:
182		myMiss(payload);
183		break;
184	}
185
186    resultBuffer[index] = payload.value;
187}