xref: /aosp_15_r20/external/mesa3d/src/intel/vulkan/grl/include/AABB3f.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 //
2 // Copyright (C) 2009-2021 Intel Corporation
3 //
4 // SPDX-License-Identifier: MIT
5 //
6 //
7 
8 #pragma once
9 
10 #include "GRLRTASCommon.h"
11 
12 #include "affinespace.h"
13 
14 #ifndef __OPENCL_VERSION__
15 #   include "stdio.h" //for printf
16 #endif
17 
18 GRL_NAMESPACE_BEGIN(GRL)
GRL_NAMESPACE_BEGIN(RTAS)19 GRL_NAMESPACE_BEGIN(RTAS)
20 
21 GRL_INLINE void AABB3f_init(struct AABB3f *aabb)
22 {
23     aabb->lower[0] = (float)(INFINITY);
24     aabb->lower[1] = (float)(INFINITY);
25     aabb->lower[2] = (float)(INFINITY);
26 
27     aabb->upper[0] = -(float)(INFINITY);
28     aabb->upper[1] = -(float)(INFINITY);
29     aabb->upper[2] = -(float)(INFINITY);
30 }
31 
AABB3f_load_lower(const struct AABB3f * aabb)32 GRL_INLINE float3 AABB3f_load_lower( const struct AABB3f* aabb )
33 {
34     float3 v = { aabb->lower[0], aabb->lower[1], aabb->lower[2] };
35     return v;
36 }
AABB3f_load_upper(const struct AABB3f * aabb)37 GRL_INLINE float3 AABB3f_load_upper( const struct AABB3f* aabb )
38 {
39     float3 v = { aabb->upper[0], aabb->upper[1], aabb->upper[2] };
40     return v;
41 }
42 
AABB3f_extend(struct AABB3f * aabb,const struct AABB3f * v)43 GRL_INLINE void AABB3f_extend(struct AABB3f *aabb, const struct AABB3f *v)
44 {
45     aabb->lower[0] = fmin(aabb->lower[0], v->lower[0]);
46     aabb->lower[1] = fmin(aabb->lower[1], v->lower[1]);
47     aabb->lower[2] = fmin(aabb->lower[2], v->lower[2]);
48     aabb->upper[0] = fmax(aabb->upper[0], v->upper[0]);
49     aabb->upper[1] = fmax(aabb->upper[1], v->upper[1]);
50     aabb->upper[2] = fmax(aabb->upper[2], v->upper[2]);
51 }
52 
AABB3f_intersect(struct AABB3f * aabb,struct AABB3f inters)53 GRL_INLINE void AABB3f_intersect(struct AABB3f* aabb, struct AABB3f inters)
54 {
55     aabb->upper[0] = fmin(inters.upper[0],aabb->upper[0]);
56     aabb->upper[1] = fmin(inters.upper[1],aabb->upper[1]);
57     aabb->upper[2] = fmin(inters.upper[2],aabb->upper[2]);
58     aabb->lower[0] = fmax(inters.lower[0],aabb->lower[0]);
59     aabb->lower[1] = fmax(inters.lower[1],aabb->lower[1]);
60     aabb->lower[2] = fmax(inters.lower[2],aabb->lower[2]);
61 }
62 
AABB3f_trim_upper(struct AABB3f * aabb,const float * upper)63 GRL_INLINE void AABB3f_trim_upper(struct AABB3f* aabb, const float* upper)
64 {
65     aabb->upper[0] = fmin(upper[0], aabb->upper[0]);
66     aabb->upper[1] = fmin(upper[1], aabb->upper[1]);
67     aabb->upper[2] = fmin(upper[2], aabb->upper[2]);
68 }
69 
AABB3f_set(struct AABB3f * aabb,float3 lower,float3 upper)70 GRL_INLINE void AABB3f_set( struct AABB3f* aabb, float3 lower, float3 upper )
71 {
72     aabb->lower[0] = lower.x ;
73     aabb->lower[1] = lower.y ;
74     aabb->lower[2] = lower.z ;
75     aabb->upper[0] = upper.x ;
76     aabb->upper[1] = upper.y ;
77     aabb->upper[2] = upper.z ;
78 }
79 
AABB3f_extend_point(struct AABB3f * aabb,const float3 p)80 inline void AABB3f_extend_point(struct AABB3f *aabb, const float3 p)
81 {
82     aabb->lower[0] = fmin(aabb->lower[0], p.x);
83     aabb->lower[1] = fmin(aabb->lower[1], p.y);
84     aabb->lower[2] = fmin(aabb->lower[2], p.z);
85     aabb->upper[0] = fmax(aabb->upper[0], p.x);
86     aabb->upper[1] = fmax(aabb->upper[1], p.y);
87     aabb->upper[2] = fmax(aabb->upper[2], p.z);
88 }
89 
AABB3f_extendlu(struct AABB3f * aabb,const float3 lower,const float3 upper)90 GRL_INLINE void AABB3f_extendlu(struct AABB3f *aabb, const float3 lower, const float3 upper)
91 {
92     aabb->lower[0] = fmin(aabb->lower[0], lower.x);
93     aabb->lower[1] = fmin(aabb->lower[1], lower.y);
94     aabb->lower[2] = fmin(aabb->lower[2], lower.z);
95     aabb->upper[0] = fmax(aabb->upper[0], upper.x);
96     aabb->upper[1] = fmax(aabb->upper[1], upper.y);
97     aabb->upper[2] = fmax(aabb->upper[2], upper.z);
98 }
99 
AABB3f_size(struct AABB3f * aabb)100 GRL_INLINE float3 AABB3f_size(struct AABB3f* aabb)
101 {
102     return AABB3f_load_upper(aabb) - AABB3f_load_lower(aabb);
103 }
104 
AABB3f_halfArea(struct AABB3f * aabb)105 GRL_INLINE float AABB3f_halfArea(struct AABB3f *aabb)
106 {
107     const float3 d = AABB3f_load_upper( aabb ) - AABB3f_load_lower( aabb );
108     return d.x* (d.y + d.z) + (d.y * d.z);
109 }
110 
halfArea_AABB3f(struct AABB3f * aabb)111 GRL_INLINE float halfArea_AABB3f(struct AABB3f *aabb) // TODO: Remove me
112 {
113     const float3 d = { aabb->upper[0] - aabb->lower[0], aabb->upper[1] - aabb->lower[1], aabb->upper[2] - aabb->lower[2] };
114     return fma(d.x, (d.y + d.z), d.y * d.z);
115 }
116 
AABB3f_set_lower(struct AABB3f * aabb,float3 lower)117 GRL_INLINE void AABB3f_set_lower(struct AABB3f* aabb, float3 lower)
118 {
119     aabb->lower[0] = lower.x;
120     aabb->lower[1] = lower.y;
121     aabb->lower[2] = lower.z;
122 }
123 
AABB3f_set_upper(struct AABB3f * aabb,float3 upper)124 GRL_INLINE void AABB3f_set_upper(struct AABB3f* aabb, float3 upper)
125 {
126     aabb->upper[0] = upper.x;
127     aabb->upper[1] = upper.y;
128     aabb->upper[2] = upper.z;
129 }
130 
conservativeExtent(float3 extent)131 GRL_INLINE float3 conservativeExtent(float3 extent)
132 {
133     const float v = FLT_EPSILON * fmax(extent.x, fmax(extent.y, extent.z));
134     float3 v3 = { v,v,v };
135     extent = extent + v3;
136     return extent;
137 }
138 
transform_aabb(float3 lower,float3 upper,const float * Transform)139 inline struct AABB3f GRL_OVERLOADABLE transform_aabb(float3 lower, float3 upper, const float* Transform)
140 {
141 #if 1
142     // We use an abs-matrix to transform the AABB extent vector, which is enough to compute the area
143     //     New AABB is center +- Extent.
144     //
145     // For derivation see:
146     //    https://zeux.io/2010/10/17/aabb-from-obb-with-component-wise-abs/
147     //
148 
149     float3 Center = (upper + lower) * 0.5f;
150     float3 Extent = (conservativeExtent(upper) - lower) * 0.5f;
151 
152     float cx = Center.x * Transform[0] + Center.y * Transform[1] + Center.z * Transform[2] + Transform[3];
153     float cy = Center.x * Transform[4] + Center.y * Transform[5] + Center.z * Transform[6] + Transform[7];
154     float cz = Center.x * Transform[8] + Center.y * Transform[9] + Center.z * Transform[10] + Transform[11];
155     float ex = Extent.x * fabs(Transform[0]) + Extent.y * fabs(Transform[1]) + Extent.z * fabs(Transform[2]);
156     float ey = Extent.x * fabs(Transform[4]) + Extent.y * fabs(Transform[5]) + Extent.z * fabs(Transform[6]);
157     float ez = Extent.x * fabs(Transform[8]) + Extent.y * fabs(Transform[9]) + Extent.z * fabs(Transform[10]);
158 
159     Center.x = cx; Center.y = cy;  Center.z = cz;
160     Extent.x = ex; Extent.y = ey;  Extent.z = ez;
161 
162     struct AABB3f box;
163     AABB3f_set_lower(&box, Center - Extent);
164     AABB3f_set_upper(&box, Center + Extent);
165     return box;
166 #else
167     struct AffineSpace3f xfm = AffineSpace3f_load_row_major(Transform);
168 
169     float3 plll = { lower.x, lower.y, lower.z };
170     float3 pllu = { lower.x, lower.y, upper.z };
171     float3 plul = { lower.x, upper.y, lower.z };
172     float3 pluu = { lower.x, upper.y, upper.z };
173     float3 pull = { upper.x, lower.y, lower.z };
174     float3 pulu = { upper.x, lower.y, upper.z };
175     float3 puul = { upper.x, upper.y, lower.z };
176     float3 puuu = { upper.x, upper.y, upper.z };
177     plll  = xfmPoint(xfm, plll) ;
178     pllu  = xfmPoint(xfm, pllu) ;
179     plul  = xfmPoint(xfm, plul) ;
180     pluu  = xfmPoint(xfm, pluu) ;
181     pull  = xfmPoint(xfm, pull) ;
182     pulu  = xfmPoint(xfm, pulu) ;
183     puul  = xfmPoint(xfm, puul) ;
184     puuu  = xfmPoint(xfm, puuu) ;
185 
186     float3 p1_min = fmin(plll, pull);
187     float3 p2_min = fmin(pllu, pulu);
188     float3 p3_min = fmin(plul, puul);
189     float3 p4_min = fmin(pluu, puuu);
190     float3 p1_max = fmax(plll, pull);
191     float3 p2_max = fmax(pllu, pulu);
192     float3 p3_max = fmax(plul, puul);
193     float3 p4_max = fmax(pluu, puuu);
194     p1_min = fmin(p1_min, p3_min);
195     p2_min = fmin(p2_min, p4_min);
196     p1_max = fmax(p1_max, p3_max);
197     p2_max = fmax(p2_max, p4_max);
198     p1_min = fmin(p1_min, p2_min);
199     p1_max = fmax(p1_max, p2_max);
200 
201     AABB3f out = {
202         {p1_min.x,p1_min.y,p1_min.z},
203         {p1_max.x,p1_max.y,p1_max.z}
204     };
205     return out;
206 #endif
207 }
208 
transform_aabb(struct AABB3f box,const float * Transform)209 GRL_INLINE struct AABB3f GRL_OVERLOADABLE transform_aabb(struct AABB3f box, const float* Transform)
210 {
211     float3 lower = { box.lower[0], box.lower[1], box.lower[2] };
212     float3 upper = { box.upper[0], box.upper[1], box.upper[2] };
213     return transform_aabb(lower, upper, Transform);
214 }
215 
AABB3f_transform(struct AffineSpace3f xfm,struct AABB3f in)216 GRL_INLINE struct AABB3f AABB3f_transform(struct AffineSpace3f xfm, struct AABB3f in)
217 {
218     struct AABB3f out;
219     float rmTransform[12];
220     load_row_major_from_AffineSpace3f(xfm, rmTransform);
221     out = transform_aabb(in, rmTransform);
222 
223     return out;
224 }
225 
AABB3f_isIn(struct AABB3f bigger,float3 contained)226 GRL_INLINE bool AABB3f_isIn(struct AABB3f bigger, float3 contained)
227 {
228     bool iscontained =
229         contained.x >= bigger.lower[0] &&
230         contained.y >= bigger.lower[1] &&
231         contained.z >= bigger.lower[2] &&
232         contained.x <= bigger.upper[0] &&
233         contained.y <= bigger.upper[1] &&
234         contained.z <= bigger.upper[2];
235 
236     return iscontained;
237 }
238 
AABB3f_isSubset(struct AABB3f bigger,struct AABB3f contained)239 GRL_INLINE bool AABB3f_isSubset(struct AABB3f bigger, struct AABB3f contained)
240 {
241     bool iscontained =
242         contained.lower[0] >= bigger.lower[0] &&
243         contained.lower[1] >= bigger.lower[1] &&
244         contained.lower[2] >= bigger.lower[2] &&
245         contained.upper[0] <= bigger.upper[0] &&
246         contained.upper[1] <= bigger.upper[1] &&
247         contained.upper[2] <= bigger.upper[2];
248 
249     return iscontained;
250 }
251 
AABB3f_is_degenerate(struct AABB3f * box)252 GRL_INLINE bool AABB3f_is_degenerate(struct AABB3f* box )
253 {
254     return box->lower[0] > box->upper[0] ||
255            box->lower[1] > box->upper[1] ||
256            box->lower[2] > box->upper[2];
257 }
258 
AABB3f_print(struct AABB3f * aabb)259 GRL_INLINE void AABB3f_print(struct AABB3f *aabb)
260 {
261     printf("AABB {\n");
262     printf("  lower = %f, %f, %f\n", aabb->lower[0], aabb->lower[1], aabb->lower[2]);
263     printf("  upper = %f, %f, %f\n", aabb->upper[0], aabb->upper[1], aabb->upper[2]);
264     printf("}\n");
265 }
266 
267 
268 
269 #ifdef __OPENCL_VERSION__
AABB3f_sub_group_shuffle(struct AABB3f * aabb,const uint slotID)270 GRL_INLINE struct AABB3f AABB3f_sub_group_shuffle(struct AABB3f *aabb, const uint slotID)
271 {
272     struct AABB3f bounds;
273     bounds.lower[0] = intel_sub_group_shuffle(aabb->lower[0], slotID);
274     bounds.lower[1] = intel_sub_group_shuffle(aabb->lower[1], slotID);
275     bounds.lower[2] = intel_sub_group_shuffle(aabb->lower[2], slotID);
276     bounds.upper[0] = intel_sub_group_shuffle(aabb->upper[0], slotID);
277     bounds.upper[1] = intel_sub_group_shuffle(aabb->upper[1], slotID);
278     bounds.upper[2] = intel_sub_group_shuffle(aabb->upper[2], slotID);
279     return bounds;
280 }
281 
AABB3f_sub_group_reduce(struct AABB3f * aabb)282 GRL_INLINE struct AABB3f AABB3f_sub_group_reduce(struct AABB3f *aabb)
283 {
284     struct AABB3f bounds;
285     bounds.lower[0] = sub_group_reduce_min(aabb->lower[0]);
286     bounds.lower[1] = sub_group_reduce_min(aabb->lower[1]);
287     bounds.lower[2] = sub_group_reduce_min(aabb->lower[2]);
288     bounds.upper[0] = sub_group_reduce_max(aabb->upper[0]);
289     bounds.upper[1] = sub_group_reduce_max(aabb->upper[1]);
290     bounds.upper[2] = sub_group_reduce_max(aabb->upper[2]);
291     return bounds;
292 }
293 
AABB3f_sub_group_scan_exclusive_min_max(struct AABB3f * aabb)294 GRL_INLINE struct AABB3f AABB3f_sub_group_scan_exclusive_min_max(struct AABB3f *aabb)
295 {
296     struct AABB3f bounds;
297     bounds.lower[0] = sub_group_scan_exclusive_min(aabb->lower[0]);
298     bounds.lower[1] = sub_group_scan_exclusive_min(aabb->lower[1]);
299     bounds.lower[2] = sub_group_scan_exclusive_min(aabb->lower[2]);
300     bounds.upper[0] = sub_group_scan_exclusive_max(aabb->upper[0]);
301     bounds.upper[1] = sub_group_scan_exclusive_max(aabb->upper[1]);
302     bounds.upper[2] = sub_group_scan_exclusive_max(aabb->upper[2]);
303     return bounds;
304 }
305 
AABB3f_sub_group_scan_inclusive_min_max(struct AABB3f * aabb)306 GRL_INLINE struct AABB3f AABB3f_sub_group_scan_inclusive_min_max(struct AABB3f *aabb)
307 {
308     struct AABB3f bounds;
309     bounds.lower[0] = sub_group_scan_inclusive_min(aabb->lower[0]);
310     bounds.lower[1] = sub_group_scan_inclusive_min(aabb->lower[1]);
311     bounds.lower[2] = sub_group_scan_inclusive_min(aabb->lower[2]);
312     bounds.upper[0] = sub_group_scan_inclusive_max(aabb->upper[0]);
313     bounds.upper[1] = sub_group_scan_inclusive_max(aabb->upper[1]);
314     bounds.upper[2] = sub_group_scan_inclusive_max(aabb->upper[2]);
315     return bounds;
316 }
317 
AABB3f_atomic_merge_local_nocheck(local struct AABB3f * aabb,const float4 lower,const float4 upper)318 GRL_INLINE void AABB3f_atomic_merge_local_nocheck(local struct AABB3f *aabb, const float4 lower, const float4 upper)
319 {
320     atomic_min((local float *)&aabb->lower + 0, lower.x);
321     atomic_min((local float *)&aabb->lower + 1, lower.y);
322     atomic_min((local float *)&aabb->lower + 2, lower.z);
323     atomic_max((local float *)&aabb->upper + 0, upper.x);
324     atomic_max((local float *)&aabb->upper + 1, upper.y);
325     atomic_max((local float *)&aabb->upper + 2, upper.z);
326 }
327 
328 
AABB3f_atomic_merge_global_lu(global struct AABB3f * aabb,const float3 lower,const float3 upper)329 GRL_INLINE void AABB3f_atomic_merge_global_lu( global struct AABB3f* aabb, const float3 lower, const float3 upper )
330 {
331     atomic_min( (global float*) & aabb->lower + 0, lower.x );
332     atomic_min( (global float*) & aabb->lower + 1, lower.y );
333     atomic_min( (global float*) & aabb->lower + 2, lower.z );
334     atomic_max( (global float*) & aabb->upper + 0, upper.x );
335     atomic_max( (global float*) & aabb->upper + 1, upper.y );
336     atomic_max( (global float*) & aabb->upper + 2, upper.z );
337 }
338 
AABB3f_atomic_merge_local_lu(local struct AABB3f * aabb,const float3 lower,const float3 upper)339 GRL_INLINE void AABB3f_atomic_merge_local_lu( local struct AABB3f* aabb, const float3 lower, const float3 upper )
340 {
341     atomic_min( (local float*) & aabb->lower + 0, lower.x );
342     atomic_min( (local float*) & aabb->lower + 1, lower.y );
343     atomic_min( (local float*) & aabb->lower + 2, lower.z );
344     atomic_max( (local float*) & aabb->upper + 0, upper.x );
345     atomic_max( (local float*) & aabb->upper + 1, upper.y );
346     atomic_max( (local float*) & aabb->upper + 2, upper.z );
347 }
348 
Uniform_AABB3f_atomic_merge_local_sub_group_lu(uniform local struct AABB3f * aabb,const float3 lower,const float3 upper)349 GRL_INLINE void Uniform_AABB3f_atomic_merge_local_sub_group_lu(uniform local struct AABB3f* aabb, const float3 lower, const float3 upper)
350 {
351     float lx = sub_group_reduce_min(lower.x);
352     float ly = sub_group_reduce_min(lower.y);
353     float lz = sub_group_reduce_min(lower.z);
354 
355     float ux = sub_group_reduce_max(upper.x);
356     float uy = sub_group_reduce_max(upper.y);
357     float uz = sub_group_reduce_max(upper.z);
358 
359     if (get_sub_group_local_id() == 0)
360     {
361         atomic_min((local float*) & aabb->lower + 0, lx);
362         atomic_min((local float*) & aabb->lower + 1, ly);
363         atomic_min((local float*) & aabb->lower + 2, lz);
364         atomic_max((local float*) & aabb->upper + 0, ux);
365         atomic_max((local float*) & aabb->upper + 1, uy);
366         atomic_max((local float*) & aabb->upper + 2, uz);
367     }
368 }
369 
AABB3f_atomic_merge_global_sub_group_lu(uniform global struct AABB3f * aabb,const float3 lower,const float3 upper)370 GRL_INLINE void AABB3f_atomic_merge_global_sub_group_lu(uniform global struct AABB3f* aabb, const float3 lower, const float3 upper)
371 {
372     uint lane = get_sub_group_local_id();
373     float l[3];
374     l[0] = sub_group_reduce_min(lower.x);
375     l[1] = sub_group_reduce_min(lower.y);
376     l[2] = sub_group_reduce_min(lower.z);
377     float u[3];
378     u[0] = sub_group_reduce_max(upper.x);
379     u[1] = sub_group_reduce_max(upper.y);
380     u[2] = sub_group_reduce_max(upper.z);
381 
382     if (lane < 3)
383     {
384         atomic_min((global float*)&aabb->lower + lane, l[lane]);
385         atomic_max((global float*)&aabb->upper + lane, u[lane]);
386     }
387 }
388 
AABB3f_atomic_merge_global(global struct AABB3f * aabb,struct AABB3f * other)389 GRL_INLINE void AABB3f_atomic_merge_global( global struct AABB3f* aabb, struct AABB3f* other )
390 {
391     float3 lower = AABB3f_load_lower( other );
392     float3 upper = AABB3f_load_upper( other );
393     atomic_min( (global float*) & aabb->lower + 0, lower.x );
394     atomic_min( (global float*) & aabb->lower + 1, lower.y );
395     atomic_min( (global float*) & aabb->lower + 2, lower.z );
396     atomic_max( (global float*) & aabb->upper + 0, upper.x );
397     atomic_max( (global float*) & aabb->upper + 1, upper.y );
398     atomic_max( (global float*) & aabb->upper + 2, upper.z );
399 }
400 
AABB3f_atomic_merge_localBB_nocheck(local struct AABB3f * aabb,struct AABB3f * bb)401 GRL_INLINE void AABB3f_atomic_merge_localBB_nocheck( local struct AABB3f* aabb, struct AABB3f* bb )
402 {
403     atomic_min( (local float*) & aabb->lower + 0, bb->lower[0] );
404     atomic_min( (local float*) & aabb->lower + 1, bb->lower[1] );
405     atomic_min( (local float*) & aabb->lower + 2, bb->lower[2] );
406     atomic_max( (local float*) & aabb->upper + 0, bb->upper[0] );
407     atomic_max( (local float*) & aabb->upper + 1, bb->upper[1] );
408     atomic_max( (local float*) & aabb->upper + 2, bb->upper[2] );
409 }
410 
AABB3f_atomic_merge_local(local struct AABB3f * aabb,const float4 lower,const float4 upper)411 GRL_INLINE void AABB3f_atomic_merge_local(local struct AABB3f *aabb, const float4 lower, const float4 upper)
412 {
413     if (lower.x < aabb->lower[0])
414         atomic_min((local float *)&aabb->lower + 0, lower.x);
415     if (lower.y < aabb->lower[1])
416         atomic_min((local float *)&aabb->lower + 1, lower.y);
417     if (lower.z < aabb->lower[2])
418         atomic_min((local float *)&aabb->lower + 2, lower.z);
419     if (upper.x > aabb->upper[0])
420         atomic_max((local float *)&aabb->upper + 0, upper.x);
421     if (upper.y > aabb->upper[1])
422         atomic_max((local float *)&aabb->upper + 1, upper.y);
423     if (upper.z > aabb->upper[2])
424         atomic_max((local float *)&aabb->upper + 2, upper.z);
425 }
426 
AABB3f_atomic_merge_global_local(global struct AABB3f * dest,local struct AABB3f * source)427 GRL_INLINE void AABB3f_atomic_merge_global_local(global struct AABB3f *dest, local struct AABB3f *source)
428 {
429     float3 l = AABB3f_load_lower(source);
430     float3 u = AABB3f_load_upper(source);
431     atomic_min((global float *)&dest->lower + 0, l.x );
432     atomic_min((global float *)&dest->lower + 1, l.y );
433     atomic_min((global float *)&dest->lower + 2, l.z );
434     atomic_max((global float *)&dest->upper + 0, u.x );
435     atomic_max((global float *)&dest->upper + 1, u.y );
436     atomic_max((global float *)&dest->upper + 2, u.z );
437 }
438 
439 
AABB3f_construct(float3 min,float3 max)440 struct AABB3f AABB3f_construct( float3 min, float3 max )
441 {
442     struct AABB3f bb;
443     bb.lower[0] = min.x; bb.lower[1] = min.y; bb.lower[2] = min.z;
444     bb.upper[0] = max.x; bb.upper[1] = max.y; bb.upper[2] = max.z;
445     return bb;
446 }
447 
AABB3f_select(struct AABB3f left,struct AABB3f right,int3 cond)448 struct AABB3f AABB3f_select( struct AABB3f left, struct AABB3f right, int3 cond )
449 {
450     float3 l = select( AABB3f_load_lower(&left), AABB3f_load_lower(&right), cond );
451     float3 u = select( AABB3f_load_upper(&left), AABB3f_load_upper(&right), cond );
452     return AABB3f_construct( l, u );
453 }
454 
455 #endif
456 
457 GRL_NAMESPACE_END(RTAS)
458 GRL_NAMESPACE_END(GRL)
459 
460