Skip to content

Commit 6b0c026

Browse files
committed
More WIP on vulkan traversal kernels
1 parent 75141bd commit 6b0c026

File tree

5 files changed

+231
-7
lines changed

5 files changed

+231
-7
lines changed

RadeonRays/src/kernels/CL/intersect_bvh2_bittrail.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ KERNEL void intersect_main(
420420
float3 const v3 = vertices[node.i2];
421421
// Calculate hit position
422422
float3 const p = r.o.xyz + r.d.xyz * t_max;
423-
// Calculte barycentric coordinates
423+
// Calculate barycentric coordinates
424424
float2 const uv = triangle_calculate_barycentrics(p, v1, v2, v3);
425425
// Update hit information
426426
hits[global_id].shape_id = node.shape_id;

RadeonRays/src/kernels/CL/intersect_bvh2_lds.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ KERNEL void intersect_main(
196196
const bvh_node node = nodes[closest_addr];
197197
const float3 p = myRay.o.xyz + closest_t * myRay.d.xyz;
198198

199-
// Calculte barycentric coordinates
199+
// Calculate barycentric coordinates
200200
const float2 uv = triangle_calculate_barycentrics(
201201
p,
202202
node.aabb_left_min_or_v0_and_addr_left.xyz,

RadeonRays/src/kernels/CL/intersect_bvh2_lds_fp16.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ KERNEL void intersect_main(
284284
const bvh_node node = nodes[closest_addr];
285285
const float3 p = myRay.o.xyz + closest_t * myRay.d.xyz;
286286

287-
// Calculte barycentric coordinates
287+
// Calculate barycentric coordinates
288288
const float2 uv = triangle_calculate_barycentrics(
289289
p,
290290
as_float3(node.aabb01_min_or_v0_and_addr0.xyz),

RadeonRays/src/kernels/CL/intersect_bvh2_short_stack.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ KERNEL void intersect_main(
433433
float3 const v3 = vertices[node.i2];
434434
// Calculate hit position
435435
float3 const p = r.o.xyz + r.d.xyz * t_max;
436-
// Calculte barycentric coordinates
436+
// Calculate barycentric coordinates
437437
float2 const uv = triangle_calculate_barycentrics(p, v1, v2, v3);
438438
// Update hit information
439439
hits[global_id].shape_id = node.shape_id;

RadeonRays/src/kernels/GLSL/bvh2.comp

Lines changed: 227 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ layout(std140, binding = 1) buffer restrict readonly RaysBlock
7171

7272
layout(std140, binding = 2) buffer restrict readonly NumraysBlock
7373
{
74-
int Numrays;
74+
uint Numrays;
7575
};
7676

7777
layout(std430, binding = 3) buffer StackBlock
7878
{
79-
int Stack[];
79+
uint Stack[];
8080
};
8181

8282
layout(std430, binding = 4) buffer restrict writeonly HitsBlock
@@ -86,15 +86,239 @@ layout(std430, binding = 4) buffer restrict writeonly HitsBlock
8686

8787
layout(std430, binding = 4) buffer restrict writeonly HitsResults
8888
{
89-
int Hitresults[];
89+
uint Hitresults[];
9090
};
9191

9292
layout(local_size_x = GROUP_SIZE, local_size_y = 1, local_size_z = 1) in;
9393

9494
shared uint lds_stack[GROUP_SIZE * LDS_STACK_SIZE];
9595

96+
float copysign(float a, float b)
97+
{
98+
return sign(b) >= 0.f ? a : -a;
99+
}
100+
101+
float mymin3(float a, float b, float c)
102+
{
103+
return min(c, min(a, b));
104+
}
105+
106+
float mymax3(float a, float b, float c)
107+
{
108+
return max(c, max(a, b));
109+
}
110+
111+
vec2 calculate_barycentrics(vec3 p, vec3 v1, vec3 v2, vec3 v3)
112+
{
113+
vec3 e1 = v2 - v1;
114+
vec3 e2 = v3 - v1;
115+
vec3 e = p - v1;
116+
float d00 = dot(e1, e1);
117+
float d01 = dot(e1, e2);
118+
float d11 = dot(e2, e2);
119+
float d20 = dot(e, e1);
120+
float d21 = dot(e, e2);
121+
float invdenom = 1.0 / (d00 * d11 - d01 * d01);
122+
float b1 = (d11 * d20 - d01 * d21) * invdenom;
123+
float b2 = (d00 * d21 - d01 * d20) * invdenom;
124+
return vec2(b1, b2);
125+
}
126+
127+
vec2 fast_intersect_aabb(
128+
vec3 pmin, vec3 pmax,
129+
vec3 invdir, vec3 oxinvdir,
130+
float t_max)
131+
{
132+
vec3 f = fma(pmax, invdir, oxinvdir);
133+
vec3 n = fma(pmin, invdir, oxinvdir);
134+
vec3 tmax = max(f, n);
135+
vec3 tmin = min(f, n);
136+
float t1 = min(mymin3(tmax.x, tmax.y, tmax.z), t_max);
137+
float t0 = max(mymax3(tmin.x, tmin.y, tmin.z), 0.0);
138+
return vec2(t0, t1);
139+
}
140+
141+
float fast_intersect_triangle(ray r, vec3 v1, vec3 v2, vec3 v3, float t_max)
142+
{
143+
vec3 e1 = v2 - v1;
144+
vec3 e2 = v3 - v1;
145+
vec3 s1 = cross(r.d.xyz, e2);
146+
float invd = 1.0 / dot(s1, e1);
147+
vec3 d = r.o.xyz - v1;
148+
float b1 = dot(d, s1) * invd;
149+
vec3 s2 = cross(d, e1);
150+
float b2 = dot(r.d.xyz, s2) * invd;
151+
float temp = dot(e2, s2) * invd;
152+
153+
if (b1 < 0.0 || b1 > 1.0 ||
154+
b2 < 0.0 || b1 + b2 > 1.0 ||
155+
temp < 0.0 || temp > t_max)
156+
{
157+
return t_max;
158+
}
159+
else
160+
{
161+
return temp;
162+
}
163+
}
164+
165+
vec3 safe_invdir(vec3 d)
166+
{
167+
float dirx = d.x;
168+
float diry = d.y;
169+
float dirz = d.z;
170+
float ooeps = 1e-5;
171+
vec3 invdir;
172+
invdir.x = 1.0 / (abs(dirx) > ooeps ? dirx : copysign(ooeps, dirx));
173+
invdir.y = 1.0 / (abs(diry) > ooeps ? diry : copysign(ooeps, diry));
174+
invdir.z = 1.0 / (abs(dirz) > ooeps ? dirz : copysign(ooeps, dirz));
175+
return invdir;
176+
}
177+
96178
void intersect_main()
97179
{
180+
uint index = gl_GlobalInvocationID.x;
181+
uint local_index = gl_LocalInvocationID.x;
182+
183+
// Handle only working subset
184+
if (index >= Numrays) return;
185+
186+
ray myRay = Rays[index]; // TODO: VK:- SC SPIR-V module not valid: OpStore Pointer <id> '136's type does not match Object <id> '137's type. (gboisse)
187+
vec3 invDir = safe_invdir(myRay.d.xyz);
188+
vec3 oxInvDir = -myRay.o.xyz * invDir;
189+
190+
// Intersection parametric distance
191+
float closest_t = myRay.o.w;
192+
193+
// Current node address
194+
uint addr = 0;
195+
// Current closest address
196+
uint closest_addr = INVALID_ADDR;
197+
198+
uint stack_bottom = STACK_SIZE * index;
199+
uint sptr = stack_bottom;
200+
uint lds_stack_bottom = local_index * LDS_STACK_SIZE;
201+
uint lds_sptr = lds_stack_bottom;
202+
203+
lds_stack[lds_sptr++] = INVALID_ADDR;
204+
205+
#if 0
206+
207+
while (addr != INVALID_ADDR)
208+
{
209+
BvhNode node = bvh[addr];
210+
211+
if (INTERNAL_NODE(node))
212+
{
213+
vec2 s0 = fast_intersect_aabb(
214+
node.aabb_left_min_or_v0,
215+
node.aabb_left_max_or_v1,
216+
invDir, oxInvDir, closest_t);
217+
vec2 s1 = fast_intersect_aabb(
218+
node.aabb_right_min_or_v2,
219+
node.aabb_right_max,
220+
invDir, oxInvDir, closest_t);
221+
222+
bool traverse_c0 = (s0.x <= s0.y);
223+
bool traverse_c1 = (s1.x <= s1.y);
224+
bool c1first = traverse_c1 && (s0.x > s1.x);
225+
226+
if (traverse_c0 || traverse_c1) {
227+
uint deferred = INVALID_ADDR;
228+
229+
if (c1first || !traverse_c0) {
230+
addr = node.addr_right;
231+
deferred = node.addr_left;
232+
}
233+
else {
234+
addr = node.addr_left;
235+
deferred = node.addr_right;
236+
}
237+
238+
if (traverse_c0 && traverse_c1) {
239+
if (lds_sptr - lds_stack_bottom >= LDS_STACK_SIZE) {
240+
for (int i = 1; i < LDS_STACK_SIZE; ++i) {
241+
stack[sptr + i] = lds_stack[lds_stack_bottom + i];
242+
}
243+
244+
sptr += LDS_STACK_SIZE;
245+
lds_sptr = lds_stack_bottom + 1;
246+
}
247+
248+
lds_stack[lds_sptr++] = deferred;
249+
}
250+
251+
continue;
252+
}
253+
}
254+
else {
255+
float t = fast_intersect_triangle(
256+
myRay,
257+
node.aabb_left_min_or_v0,
258+
node.aabb_left_max_or_v1,
259+
node.aabb_right_min_or_v2,
260+
closest_t);
261+
262+
if (t < closest_t) {
263+
closest_t = t;
264+
closest_addr = addr;
265+
}
266+
}
267+
268+
addr = lds_stack[--lds_sptr];
269+
270+
if (addr == INVALID_ADDR && sptr > stack_bottom) {
271+
sptr -= LDS_STACK_SIZE;
272+
for (int i = 1; i < LDS_STACK_SIZE; ++i) {
273+
lds_stack[lds_stack_bottom + i] = stack[sptr + i];
274+
}
275+
276+
lds_sptr = lds_stack_bottom + LDS_STACK_SIZE - 1;
277+
addr = lds_stack[lds_sptr];
278+
}
279+
}
280+
281+
#endif
282+
283+
#if 0
284+
// TODO: what, why?!? (gboisse)
285+
Intersection isect;
286+
isect.padding.x = 667;
287+
isect.padding.y = r.padding.x;
288+
isect.uvwt = vec4(0.0f, 0.0f, 0.0f, closest_t);
289+
290+
#if 0
291+
292+
// Check if we have found an intersection
293+
if (closest_addr != INVALID_ADDR)
294+
{
295+
// Calculate hit position
296+
BvhNode node = Nodes[closest_addr];
297+
vec3 p = myRay.o.xyz + closest_t * myRay.d.xyz;
298+
299+
// Calculate barycentric coordinates
300+
isect.uvwt.xy = calculate_barycentrics(
301+
p,
302+
node.aabb_left_min_or_v0,
303+
node.aabb_left_max_or_v1,
304+
node.aabb_right_min_or_v2
305+
);
306+
307+
// Update hit information
308+
hit.prim_id = node.prim_id;
309+
hit.shape_id = node.mesh_id;
310+
}
311+
else
312+
#endif
313+
{
314+
// Miss here
315+
isect.prim_id = -1;
316+
isect.shape_id = -1;
317+
}
318+
319+
// Write result to memory
320+
Hits[index] = isect;
321+
#endif
98322
}
99323

100324
void occluded_main()

0 commit comments

Comments
 (0)