Blender V4.3
device/hiprt/common.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#ifdef __HIPRT__
6
7struct RayPayload {
10 uint visibility;
11 int prim_type;
12 float ray_time;
13};
14
15struct ShadowPayload {
18 uint visibility;
19 int prim_type;
20 float ray_time;
21 int in_state;
22 uint max_hits;
23 uint num_hits;
24 uint *r_num_recorded_hits;
25 float *r_throughput;
26};
27
28struct LocalPayload {
31 int prim_type;
32 float ray_time;
33 int local_object;
34 uint max_hits;
35 uint *lcg_state;
36 LocalIntersection *local_isect;
37};
38
39# define SET_HIPRT_RAY(RAY_RT, RAY) \
40 RAY_RT.direction = RAY->D; \
41 RAY_RT.origin = RAY->P; \
42 RAY_RT.maxT = RAY->tmax; \
43 RAY_RT.minT = RAY->tmin;
44
45# if defined(HIPRT_SHARED_STACK)
46# define GET_TRAVERSAL_STACK() \
47 Stack stack(kg->global_stack_buffer, kg->shared_stack); \
48 Instance_Stack instance_stack;
49# else
50# define GET_TRAVERSAL_STACK()
51# endif
52
53# ifdef HIPRT_SHARED_STACK
54# define GET_TRAVERSAL_ANY_HIT(FUNCTION_TABLE, RAY_TYPE, RAY_TIME) \
55 hiprtSceneTraversalAnyHitCustomStack<Stack, Instance_Stack> traversal( \
56 (hiprtScene)kernel_data.device_bvh, \
57 ray_hip, \
58 stack, \
59 instance_stack, \
60 visibility, \
61 hiprtTraversalHintDefault, \
62 &payload, \
63 kernel_params.FUNCTION_TABLE, \
64 RAY_TYPE, \
65 RAY_TIME);
66
67# define GET_TRAVERSAL_CLOSEST_HIT(FUNCTION_TABLE, RAY_TYPE, RAY_TIME) \
68 hiprtSceneTraversalClosestCustomStack<Stack, Instance_Stack> traversal( \
69 (hiprtScene)kernel_data.device_bvh, \
70 ray_hip, \
71 stack, \
72 instance_stack, \
73 visibility, \
74 hiprtTraversalHintDefault, \
75 &payload, \
76 kernel_params.FUNCTION_TABLE, \
77 RAY_TYPE, \
78 RAY_TIME);
79# else
80# define GET_TRAVERSAL_ANY_HIT(FUNCTION_TABLE) \
81 hiprtSceneTraversalAnyHit traversal(kernel_data.device_bvh, \
82 ray_hip, \
83 visibility, \
84 FUNCTION_TABLE, \
85 hiprtTraversalHintDefault, \
86 &payload);
87# define GET_TRAVERSAL_CLOSEST_HIT(FUNCTION_TABLE) \
88 hiprtSceneTraversalClosest traversal(kernel_data.device_bvh, \
89 ray_hip, \
90 visibility, \
91 FUNCTION_TABLE, \
92 hiprtTraversalHintDefault, \
93 &payload);
94# endif
95
96ccl_device_inline void set_intersect_point(KernelGlobals kg,
97 hiprtHit &hit,
99{
100 int prim_offset = 0;
101 int object_id = kernel_data_fetch(user_instance_id, hit.instanceID);
102 prim_offset = kernel_data_fetch(object_prim_offset, object_id);
103 isect->type = kernel_data_fetch(objects, object_id).primitive_type;
104
105 isect->t = hit.t;
106 isect->prim = hit.primID + prim_offset;
107 isect->object = object_id;
108 isect->u = hit.uv.x;
109 isect->v = hit.uv.y;
110}
111
112// custom intersection functions
113
114ccl_device_inline bool curve_custom_intersect(const hiprtRay &ray,
115 const void *userPtr,
116 void *payload,
117 hiprtHit &hit)
118
119{
120 Intersection isect;
121 RayPayload *local_payload = (RayPayload *)payload;
122 // could also cast shadow payload to get the elements needed to do the intersection
123 // no need to write a separate function for shadow intersection
124
125 KernelGlobals kg = local_payload->kg;
126
127 int object_id = kernel_data_fetch(user_instance_id, hit.instanceID);
128 int2 data_offset = kernel_data_fetch(custom_prim_info_offset, object_id);
129 // data_offset.x: where the data (prim id, type )for the geometry of the current object begins
130 // the prim_id that is in hiprtHit hit is local to the partciular geometry so we add the above
131 // ofstream
132 // to map prim id in hiprtHit to the one compatible to what next stage expects
133
134 // data_offset.y: the offset that has to be added to a local primitive to get the global
135 // primitive id = kernel_data_fetch(object_prim_offset, object_id);
136
137 int prim_offset = data_offset.y;
138
139 int curve_index = kernel_data_fetch(custom_prim_info, hit.primID + data_offset.x).x;
140 int key_value = kernel_data_fetch(custom_prim_info, hit.primID + data_offset.x).y;
141
142# ifdef __SHADOW_LINKING__
143 if (intersection_skip_shadow_link(nullptr, local_payload->self, object_id)) {
144 /* Ignore hit - continue traversal */
145 return false;
146 }
147# endif
148
149 if (intersection_skip_self_shadow(local_payload->self, object_id, curve_index + prim_offset))
150 return false;
151
152 float ray_time = local_payload->ray_time;
153
154 if ((key_value & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
155
156 int time_offset = kernel_data_fetch(prim_time_offset, object_id);
157 float2 prims_time = kernel_data_fetch(prims_time, hit.primID + time_offset);
158
159 if (ray_time < prims_time.x || ray_time > prims_time.y) {
160 return false;
161 }
162 }
163
164 bool b_hit = curve_intersect(kg,
165 &isect,
166 ray.origin,
167 ray.direction,
168 ray.minT,
169 ray.maxT,
170 object_id,
171 curve_index + prim_offset,
172 ray_time,
173 key_value);
174 if (b_hit) {
175 hit.uv.x = isect.u;
176 hit.uv.y = isect.v;
177 hit.t = isect.t;
178 hit.primID = isect.prim;
179 local_payload->prim_type = isect.type; // packed_curve_type;
180 }
181 return b_hit;
182}
183
184ccl_device_inline bool motion_triangle_custom_intersect(const hiprtRay &ray,
185 const void *userPtr,
186 void *payload,
187 hiprtHit &hit)
188{
189 RayPayload *local_payload = (RayPayload *)payload;
190 KernelGlobals kg = local_payload->kg;
191 int object_id = kernel_data_fetch(user_instance_id, hit.instanceID);
192 int2 data_offset = kernel_data_fetch(custom_prim_info_offset, object_id);
193 int prim_offset = kernel_data_fetch(object_prim_offset, object_id);
194
195 int prim_id_local = kernel_data_fetch(custom_prim_info, hit.primID + data_offset.x).x;
196 int prim_id_global = prim_id_local + prim_offset;
197
198 if (intersection_skip_self_shadow(local_payload->self, object_id, prim_id_global))
199 return false;
200
201 Intersection isect;
202
203 bool b_hit = motion_triangle_intersect(kg,
204 &isect,
205 ray.origin,
206 ray.direction,
207 ray.minT,
208 ray.maxT,
209 local_payload->ray_time,
210 local_payload->visibility,
211 object_id,
212 prim_id_global,
213 hit.instanceID);
214
215 if (b_hit) {
216 hit.uv.x = isect.u;
217 hit.uv.y = isect.v;
218 hit.t = isect.t;
219 hit.primID = isect.prim;
220 local_payload->prim_type = isect.type;
221 }
222 return b_hit;
223}
224
225ccl_device_inline bool motion_triangle_custom_local_intersect(const hiprtRay &ray,
226 const void *userPtr,
227 void *payload,
228 hiprtHit &hit)
229{
230# ifdef __OBJECT_MOTION__
231 LocalPayload *local_payload = (LocalPayload *)payload;
232 KernelGlobals kg = local_payload->kg;
233 int object_id = local_payload->local_object;
234
235 int prim_offset = kernel_data_fetch(object_prim_offset, object_id);
236 int2 data_offset = kernel_data_fetch(custom_prim_info_offset, object_id);
237
238 int prim_id_local = kernel_data_fetch(custom_prim_info, hit.primID + data_offset.x).x;
239 int prim_id_global = prim_id_local + prim_offset;
240
241 if (intersection_skip_self_local(local_payload->self, prim_id_global))
242 return false;
243
244 LocalIntersection *local_isect = local_payload->local_isect;
245
246 bool b_hit = motion_triangle_intersect_local(kg,
247 local_isect,
248 ray.origin,
249 ray.direction,
250 local_payload->ray_time,
251 object_id,
252 prim_id_global,
253 prim_id_local,
254 ray.minT,
255 ray.maxT,
256 local_payload->lcg_state,
257 local_payload->max_hits);
258
259 if (b_hit) {
260 local_payload->prim_type = PRIMITIVE_MOTION_TRIANGLE;
261 }
262 return b_hit;
263# else
264 return false;
265# endif
266}
267
268ccl_device_inline bool motion_triangle_custom_volume_intersect(const hiprtRay &ray,
269 const void *userPtr,
270 void *payload,
271 hiprtHit &hit)
272{
273# ifdef __OBJECT_MOTION__
274 RayPayload *local_payload = (RayPayload *)payload;
275 KernelGlobals kg = local_payload->kg;
276 int object_id = kernel_data_fetch(user_instance_id, hit.instanceID);
277 int object_flag = kernel_data_fetch(object_flag, object_id);
278
279 if (!(object_flag & SD_OBJECT_HAS_VOLUME))
280 return false;
281
282 int2 data_offset = kernel_data_fetch(custom_prim_info_offset, object_id);
283 int prim_offset = kernel_data_fetch(object_prim_offset, object_id);
284
285 int prim_id_local = kernel_data_fetch(custom_prim_info, hit.primID + data_offset.x).x;
286 int prim_id_global = prim_id_local + prim_offset;
287
288 if (intersection_skip_self_shadow(local_payload->self, object_id, prim_id_global))
289 return false;
290
291 Intersection isect;
292
293 bool b_hit = motion_triangle_intersect(kg,
294 &isect,
295 ray.origin,
296 ray.direction,
297 ray.minT,
298 ray.maxT,
299 local_payload->ray_time,
300 local_payload->visibility,
301 object_id,
302 prim_id_global,
303 prim_id_local);
304
305 if (b_hit) {
306 hit.uv.x = isect.u;
307 hit.uv.y = isect.v;
308 hit.t = isect.t;
309 hit.primID = isect.prim;
310 local_payload->prim_type = isect.type;
311 }
312 return b_hit;
313# else
314 return false;
315# endif
316}
317
318ccl_device_inline bool point_custom_intersect(const hiprtRay &ray,
319 const void *userPtr,
320 void *payload,
321 hiprtHit &hit)
322{
323 /* Point cloud intersections are currently disabled to decrease register pressure in the ray
324 * tracing kernels. This increases the number of in-flight ray traversal waves, and fixes the
325 * performance regression reported in #127464 */
326# if defined(__POINTCLOUD__) && 0
327 RayPayload *local_payload = (RayPayload *)payload;
328 KernelGlobals kg = local_payload->kg;
329 int object_id = kernel_data_fetch(user_instance_id, hit.instanceID);
330
331 int2 data_offset = kernel_data_fetch(custom_prim_info_offset, object_id);
332 int prim_offset = kernel_data_fetch(object_prim_offset, object_id);
333
334 int2 prim_info = kernel_data_fetch(custom_prim_info, hit.primID + data_offset.x);
335 int prim_id_local = prim_info.x;
336 int prim_id_global = prim_id_local + prim_offset;
337
338 int type = prim_info.y;
339
340# ifdef __SHADOW_LINKING__
341 if (intersection_skip_shadow_link(nullptr, local_payload->self, object_id)) {
342 /* Ignore hit - continue traversal */
343 return false;
344 }
345# endif
346
347 if (intersection_skip_self_shadow(local_payload->self, object_id, prim_id_global))
348 return false;
349
350 float ray_time = local_payload->ray_time;
351
352 if ((type & PRIMITIVE_MOTION_POINT) && kernel_data.bvh.use_bvh_steps) {
353
354 int time_offset = kernel_data_fetch(prim_time_offset, object_id);
355 float2 prims_time = kernel_data_fetch(prims_time, hit.primID + time_offset);
356
357 if (ray_time < prims_time.x || ray_time > prims_time.y) {
358 return false;
359 }
360 }
361
362 Intersection isect;
363
364 bool b_hit = point_intersect(kg,
365 &isect,
366 ray.origin,
367 ray.direction,
368 ray.minT,
369 ray.maxT,
370 object_id,
371 prim_id_global,
372 ray_time,
373 type);
374
375 if (b_hit) {
376 hit.uv.x = isect.u;
377 hit.uv.y = isect.v;
378 hit.t = isect.t;
379 hit.primID = isect.prim;
380 local_payload->prim_type = isect.type;
381 }
382 return b_hit;
383# else
384 return false;
385# endif
386}
387
388// intersection filters
389
390ccl_device_inline bool closest_intersection_filter(const hiprtRay &ray,
391 const void *data,
392 void *user_data,
393 const hiprtHit &hit)
394{
395 RayPayload *payload = (RayPayload *)user_data;
396 int object_id = kernel_data_fetch(user_instance_id, hit.instanceID);
397 int prim_offset = kernel_data_fetch(object_prim_offset, object_id);
398 int prim = hit.primID + prim_offset;
399
400# ifdef __SHADOW_LINKING__
401 if (intersection_skip_shadow_link(nullptr, payload->self, object_id)) {
402 /* Ignore hit - continue traversal */
403 return true;
404 }
405# endif
406
407 if (intersection_skip_self_shadow(payload->self, object_id, prim)) {
408 /* Ignore hit - continue traversal */
409 return true;
410 }
411
412 return false;
413}
414
415ccl_device_inline bool shadow_intersection_filter(const hiprtRay &ray,
416 const void *data,
417 void *user_data,
418 const hiprtHit &hit)
419
420{
421 ShadowPayload *payload = (ShadowPayload *)user_data;
422
423 uint num_hits = payload->num_hits;
424 uint num_recorded_hits = *(payload->r_num_recorded_hits);
425 uint max_hits = payload->max_hits;
426 int state = payload->in_state;
427 KernelGlobals kg = payload->kg;
428 RaySelfPrimitives self = payload->self;
429
430 int object = kernel_data_fetch(user_instance_id, hit.instanceID);
431 int prim_offset = kernel_data_fetch(object_prim_offset, object);
432 int prim = hit.primID + prim_offset;
433
434 float ray_tmax = hit.t;
435
436# ifdef __SHADOW_LINKING__
437 if (intersection_skip_shadow_link(nullptr, self, object)) {
438 /* Ignore hit - continue traversal */
439 return true;
440 }
441# endif
442
443# ifdef __VISIBILITY_FLAG__
444
445 if ((kernel_data_fetch(objects, object).visibility & payload->visibility) == 0) {
446 return true; // no hit - continue traversal
447 }
448# endif
449
450 if (intersection_skip_self_shadow(self, object, prim)) {
451 return true; // no hit -continue traversal
452 }
453
454 float u = hit.uv.x;
455 float v = hit.uv.y;
456 int type = kernel_data_fetch(objects, object).primitive_type;
457
458# ifndef __TRANSPARENT_SHADOWS__
459
460 return false;
461
462# else
463
464 if (num_hits >= max_hits ||
466 {
467 return false;
468 }
469
470 uint record_index = num_recorded_hits;
471
472 num_hits += 1;
473 num_recorded_hits += 1;
474 payload->num_hits = num_hits;
475 *(payload->r_num_recorded_hits) = num_recorded_hits;
476
477 const uint max_record_hits = min(max_hits, INTEGRATOR_SHADOW_ISECT_SIZE);
478 if (record_index >= max_record_hits) {
479 float max_recorded_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, t);
480 uint max_recorded_hit = 0;
481
482 for (int i = 1; i < max_record_hits; i++) {
483 const float isect_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, i, t);
484 if (isect_t > max_recorded_t) {
485 max_recorded_t = isect_t;
486 max_recorded_hit = i;
487 }
488 }
489
490 if (ray_tmax >= max_recorded_t) {
491
492 return true;
493 }
494
495 record_index = max_recorded_hit;
496 }
497
498 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, u) = u;
499 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, v) = v;
500 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, t) = ray_tmax;
501 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, prim) = prim;
502 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, object) = object;
503 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, type) = type;
504 return true;
505
506# endif /* __TRANSPARENT_SHADOWS__ */
507}
508
509ccl_device_inline bool shadow_intersection_filter_curves(const hiprtRay &ray,
510 const void *data,
511 void *user_data,
512 const hiprtHit &hit)
513
514{
515 ShadowPayload *payload = (ShadowPayload *)user_data;
516
517 uint num_hits = payload->num_hits;
518 uint num_recorded_hits = *(payload->r_num_recorded_hits);
519 uint max_hits = payload->max_hits;
520 KernelGlobals kg = payload->kg;
521 RaySelfPrimitives self = payload->self;
522
523 int object = kernel_data_fetch(user_instance_id, hit.instanceID);
524 int prim = hit.primID;
525
526 float ray_tmax = hit.t;
527
528# ifdef __SHADOW_LINKING__
529 /* It doesn't seem like this is necessary. */
530 if (intersection_skip_shadow_link(nullptr, self, object)) {
531 /* Ignore hit - continue traversal */
532 return true;
533 }
534# endif
535
536# ifdef __VISIBILITY_FLAG__
537
538 if ((kernel_data_fetch(objects, object).visibility & payload->visibility) == 0) {
539 return true; // no hit - continue traversal
540 }
541# endif
542
543 if (intersection_skip_self_shadow(self, object, prim)) {
544 return true; // no hit -continue traversal
545 }
546
547 float u = hit.uv.x;
548 float v = hit.uv.y;
549
550 if (u == 0.0f || u == 1.0f) {
551 // continue traversal
552 return true;
553 }
554
555 int type = payload->prim_type;
556
557# ifndef __TRANSPARENT_SHADOWS__
558
559 return false;
560
561# else
562
563 if (num_hits >= max_hits ||
565 {
566 return false;
567 }
568
569 float throughput = *payload->r_throughput;
570 throughput *= intersection_curve_shadow_transparency(kg, object, prim, type, u);
571 *payload->r_throughput = throughput;
572 payload->num_hits += 1;
573
574 if (throughput < CURVE_SHADOW_TRANSPARENCY_CUTOFF) {
575 return false;
576 }
577
578 return true;
579
580# endif /* __TRANSPARENT_SHADOWS__ */
581}
582
583ccl_device_inline bool local_intersection_filter(const hiprtRay &ray,
584 const void *data,
585 void *user_data,
586 const hiprtHit &hit)
587{
588# ifdef __BVH_LOCAL__
589 LocalPayload *payload = (LocalPayload *)user_data;
590 KernelGlobals kg = payload->kg;
591 int object_id = payload->local_object;
592 int prim_offset = kernel_data_fetch(object_prim_offset, object_id);
593 int prim = hit.primID + prim_offset;
594# ifndef __RAY_OFFSET__
595 if (intersection_skip_self_local(payload->self, prim)) {
596 return true; // continue search
597 }
598# endif
599 uint max_hits = payload->max_hits;
600 if (max_hits == 0) {
601 return false; // stop search
602 }
603 int hit_index = 0;
604 if (payload->lcg_state) {
605 for (int i = min(max_hits, payload->local_isect->num_hits) - 1; i >= 0; --i) {
606 if (hit.t == payload->local_isect->hits[i].t) {
607 return true; // continue search
608 }
609 }
610 hit_index = payload->local_isect->num_hits++;
611 if (payload->local_isect->num_hits > max_hits) {
612 hit_index = lcg_step_uint(payload->lcg_state) % payload->local_isect->num_hits;
613 if (hit_index >= max_hits) {
614 return true; // continue search
615 }
616 }
617 }
618 else {
619 if (payload->local_isect->num_hits && hit.t > payload->local_isect->hits[0].t) {
620 return true;
621 }
622 payload->local_isect->num_hits = 1;
623 }
624 Intersection *isect = &payload->local_isect->hits[hit_index];
625 isect->t = hit.t;
626 isect->prim = prim;
627 isect->object = object_id;
628 isect->type = PRIMITIVE_TRIANGLE; // kernel_data_fetch(__objects, object_id).primitive_type;
629
630 isect->u = hit.uv.x;
631 isect->v = hit.uv.y;
632
633 payload->local_isect->Ng[hit_index] = hit.normal;
634
635 return true;
636
637# endif
638}
639
640ccl_device_inline bool volume_intersection_filter(const hiprtRay &ray,
641 const void *data,
642 void *user_data,
643 const hiprtHit &hit)
644{
645 RayPayload *payload = (RayPayload *)user_data;
646 int object_id = kernel_data_fetch(user_instance_id, hit.instanceID);
647 int prim_offset = kernel_data_fetch(object_prim_offset, object_id);
648 int prim = hit.primID + prim_offset;
649 int object_flag = kernel_data_fetch(object_flag, object_id);
650
651 if (intersection_skip_self(payload->self, object_id, prim))
652 return true;
653 else if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0)
654 return true;
655 else
656 return false;
657}
658
659HIPRT_DEVICE bool intersectFunc(uint geomType,
660 uint rayType,
661 const hiprtFuncTableHeader &tableHeader,
662 const hiprtRay &ray,
663 void *payload,
664 hiprtHit &hit)
665{
666 const uint index = tableHeader.numGeomTypes * rayType + geomType;
667 const void *data = tableHeader.funcDataSets[index].filterFuncData;
668 switch (index) {
671 return curve_custom_intersect(ray, data, payload, hit);
674 return motion_triangle_custom_intersect(ray, data, payload, hit);
676 return motion_triangle_custom_local_intersect(ray, data, payload, hit);
678 return motion_triangle_custom_volume_intersect(ray, data, payload, hit);
681 return point_custom_intersect(ray, data, payload, hit);
682 default:
683 break;
684 }
685 return false;
686}
687
688HIPRT_DEVICE bool filterFunc(uint geomType,
689 uint rayType,
690 const hiprtFuncTableHeader &tableHeader,
691 const hiprtRay &ray,
692 void *payload,
693 const hiprtHit &hit)
694{
695 const uint index = tableHeader.numGeomTypes * rayType + geomType;
696 const void *data = tableHeader.funcDataSets[index].intersectFuncData;
697 switch (index) {
699 return closest_intersection_filter(ray, data, payload, hit);
701 return shadow_intersection_filter_curves(ray, data, payload, hit);
705 return shadow_intersection_filter(ray, data, payload, hit);
708 return local_intersection_filter(ray, data, payload, hit);
711 return volume_intersection_filter(ray, data, payload, hit);
712 default:
713 break;
714 }
715
716 return false;
717}
718
719#endif
unsigned int uint
ATTR_WARN_UNUSED_RESULT const BMVert * v
PyObject * self
ccl_device_forceinline int intersection_get_shader_flags(KernelGlobals kg, const int prim, const int type)
ccl_device_inline bool intersection_skip_self_local(ccl_ray_data const RaySelfPrimitives &self, const int prim)
ccl_device_inline bool intersection_skip_self(ccl_ray_data const RaySelfPrimitives &self, const int object, const int prim)
ccl_device_inline bool intersection_skip_shadow_link(KernelGlobals kg, ccl_ray_data const RaySelfPrimitives &self, const int isect_object)
#define CURVE_SHADOW_TRANSPARENCY_CUTOFF
ccl_device_inline float intersection_curve_shadow_transparency(KernelGlobals kg, const int object, const int prim, const int type, const float u)
ccl_device_inline bool intersection_skip_self_shadow(ccl_ray_data const RaySelfPrimitives &self, const int object, const int prim)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_private
#define ccl_device_inline
@ Motion_Triangle_Filter_Volume
@ Motion_Triangle_Filter_Local
@ Triangle_Filter_Closest
@ Curve_Filter_Shadow
@ Motion_Triangle_Filter_Shadow
@ Point_Filter_Shadow
@ Triangle_Filter_Local
@ Triangle_Filter_Volume
@ Triangle_Filter_Shadow
@ Motion_Triangle_Intersect_Shadow
@ Curve_Intersect_Function
@ Motion_Triangle_Intersect_Function
@ Point_Intersect_Shadow
@ Curve_Intersect_Shadow
@ Point_Intersect_Function
@ Motion_Triangle_Intersect_Volume
@ Motion_Triangle_Intersect_Local
#define NULL
@ SD_HAS_TRANSPARENT_SHADOW
@ PRIMITIVE_MOTION
@ PRIMITIVE_MOTION_TRIANGLE
@ PRIMITIVE_TRIANGLE
@ PRIMITIVE_MOTION_POINT
#define INTEGRATOR_SHADOW_ISECT_SIZE
@ SD_OBJECT_HAS_VOLUME
CCL_NAMESPACE_BEGIN ccl_device uint lcg_step_uint(T rng)
Definition lcg.h:14
static ulong state[N]
ccl_device_inline bool motion_triangle_intersect(KernelGlobals kg, ccl_private Intersection *isect, float3 P, float3 dir, float tmin, float tmax, float time, uint visibility, int object, int prim, int prim_addr)
#define min(a, b)
Definition sort.c:32
#define INTEGRATOR_STATE_ARRAY_WRITE(state, nested_struct, array_index, member)
Definition state.h:240
#define INTEGRATOR_STATE_ARRAY(state, nested_struct, array_index, member)
Definition state.h:238
float y
int x
Definition types_int2.h:15
int y
Definition types_int2.h:15