Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/instance_stack.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "rtcore.h"
7
8
namespace embree {
9
namespace instance_id_stack {
10
11
static_assert(RTC_MAX_INSTANCE_LEVEL_COUNT > 0,
12
"RTC_MAX_INSTANCE_LEVEL_COUNT must be greater than 0.");
13
14
/*******************************************************************************
15
* Instance ID stack manipulation.
16
* This is used from the instance intersector.
17
******************************************************************************/
18
19
/*
20
* Push an instance to the stack.
21
*/
22
template<typename Context>
23
RTC_FORCEINLINE bool push(Context context,
24
unsigned instanceId,
25
unsigned instancePrimId)
26
{
27
#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1
28
const bool spaceAvailable = context->instStackSize < RTC_MAX_INSTANCE_LEVEL_COUNT;
29
/* We assert here because instances are silently dropped when the stack is full.
30
This might be quite hard to find in production. */
31
assert(spaceAvailable);
32
if (likely(spaceAvailable)) {
33
context->instID[context->instStackSize] = instanceId;
34
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
35
context->instPrimID[context->instStackSize] = instancePrimId;
36
#endif
37
context->instStackSize++;
38
}
39
return spaceAvailable;
40
#else
41
const bool spaceAvailable = (context->instID[0] == RTC_INVALID_GEOMETRY_ID);
42
assert(spaceAvailable);
43
if (likely(spaceAvailable)) {
44
context->instID[0] = instanceId;
45
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
46
context->instPrimID[0] = instancePrimId;
47
#endif
48
}
49
return spaceAvailable;
50
#endif
51
}
52
53
/*
54
* Pop the last instance pushed to the stack.
55
* Do not call on an empty stack.
56
*/
57
template<typename Context>
58
RTC_FORCEINLINE void pop(Context context)
59
{
60
assert(context);
61
#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1
62
assert(context->instStackSize > 0);
63
--context->instStackSize;
64
context->instID[context->instStackSize] = RTC_INVALID_GEOMETRY_ID;
65
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
66
context->instPrimID[context->instStackSize] = RTC_INVALID_GEOMETRY_ID;
67
#endif
68
#else
69
assert(context->instID[0] != RTC_INVALID_GEOMETRY_ID);
70
context->instID[0] = RTC_INVALID_GEOMETRY_ID;
71
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
72
context->instPrimID[0] = RTC_INVALID_GEOMETRY_ID;
73
#endif
74
#endif
75
}
76
77
78
/* Push an instance to the stack. Used for point queries*/
79
RTC_FORCEINLINE bool push(RTCPointQueryContext* context,
80
unsigned int instanceId,
81
unsigned int instancePrimId,
82
AffineSpace3fa const& w2i,
83
AffineSpace3fa const& i2w)
84
{
85
assert(context);
86
const size_t stackSize = context->instStackSize;
87
assert(stackSize < RTC_MAX_INSTANCE_LEVEL_COUNT);
88
context->instID[stackSize] = instanceId;
89
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
90
context->instPrimID[stackSize] = instancePrimId;
91
#endif
92
93
AffineSpace3fa_store_unaligned(w2i,(AffineSpace3fa*)context->world2inst[stackSize]);
94
AffineSpace3fa_store_unaligned(i2w,(AffineSpace3fa*)context->inst2world[stackSize]);
95
96
#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1
97
if (unlikely(stackSize > 0))
98
{
99
const AffineSpace3fa world2inst = AffineSpace3fa_load_unaligned((AffineSpace3fa*)context->world2inst[stackSize ])
100
* AffineSpace3fa_load_unaligned((AffineSpace3fa*)context->world2inst[stackSize-1]);
101
const AffineSpace3fa inst2world = AffineSpace3fa_load_unaligned((AffineSpace3fa*)context->inst2world[stackSize-1])
102
* AffineSpace3fa_load_unaligned((AffineSpace3fa*)context->inst2world[stackSize ]);
103
AffineSpace3fa_store_unaligned(world2inst,(AffineSpace3fa*)context->world2inst[stackSize]);
104
AffineSpace3fa_store_unaligned(inst2world,(AffineSpace3fa*)context->inst2world[stackSize]);
105
}
106
#endif
107
context->instStackSize++;
108
return true;
109
}
110
111
template<>
112
RTC_FORCEINLINE void pop(RTCPointQueryContext* context)
113
{
114
assert(context);
115
#if RTC_MAX_INSTANCE_LEVEL_COUNT > 1
116
assert(context->instStackSize > 0);
117
#else
118
assert(context->instID[0] != RTC_INVALID_GEOMETRY_ID);
119
#endif
120
--context->instStackSize;
121
context->instID[context->instStackSize] = RTC_INVALID_GEOMETRY_ID;
122
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
123
context->instPrimID[context->instStackSize] = RTC_INVALID_GEOMETRY_ID;
124
#endif
125
}
126
127
/*
128
* Optimized instance id stack copy.
129
* The copy() functions will either copy full
130
* stacks or copy only until the last valid element has been copied, depending
131
* on RTC_MAX_INSTANCE_LEVEL_COUNT.
132
*/
133
RTC_FORCEINLINE void copy_UU(const unsigned* src, unsigned* tgt)
134
{
135
#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
136
tgt[0] = src[0];
137
138
#else
139
for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
140
tgt[l] = src[l];
141
if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
142
if (src[l] == RTC_INVALID_GEOMETRY_ID)
143
break;
144
}
145
#endif
146
}
147
148
RTC_FORCEINLINE void copy_UU(const RTCRayQueryContext* context, const unsigned* src, unsigned* tgt)
149
{
150
#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
151
tgt[0] = src[0];
152
153
#else
154
155
unsigned int depth = context->instStackSize;
156
157
for (unsigned l = 0; l < depth; ++l)
158
tgt[l] = src[l];
159
160
for (unsigned l = depth; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l)
161
tgt[l] = RTC_INVALID_GEOMETRY_ID;
162
163
#endif
164
}
165
166
template <int K>
167
RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt)
168
{
169
#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
170
tgt[0] = src[0];
171
172
#else
173
for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
174
tgt[l] = src[l];
175
if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
176
if (src[l] == RTC_INVALID_GEOMETRY_ID)
177
break;
178
}
179
#endif
180
}
181
182
template <int K>
183
RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, size_t j)
184
{
185
#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
186
tgt[0][j] = src[0];
187
188
#else
189
for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
190
tgt[l][j] = src[l];
191
if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
192
if (src[l] == RTC_INVALID_GEOMETRY_ID)
193
break;
194
}
195
#endif
196
}
197
198
template <int K>
199
RTC_FORCEINLINE void copy_UV(const unsigned* src, vuint<K>* tgt, const vbool<K>& mask)
200
{
201
#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
202
vuint<K>::store(mask, tgt, src[0]);
203
204
#else
205
for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
206
vuint<K>::store(mask, tgt + l, src[l]);
207
if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
208
if (src[l] == RTC_INVALID_GEOMETRY_ID)
209
break;
210
}
211
#endif
212
}
213
214
template <int K>
215
RTC_FORCEINLINE void copy_VU(const vuint<K>* src, unsigned* tgt, size_t i)
216
{
217
#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
218
tgt[0] = src[0][i];
219
220
#else
221
for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
222
tgt[l] = src[l][i];
223
if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
224
if (src[l][i] == RTC_INVALID_GEOMETRY_ID)
225
break;
226
}
227
#endif
228
}
229
230
template <int K>
231
RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, size_t i, size_t j)
232
{
233
#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
234
tgt[0][j] = src[0][i];
235
236
#else
237
for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
238
tgt[l][j] = src[l][i];
239
if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4)
240
if (src[l][i] == RTC_INVALID_GEOMETRY_ID)
241
break;
242
}
243
#endif
244
}
245
246
template <int K>
247
RTC_FORCEINLINE void copy_VV(const vuint<K>* src, vuint<K>* tgt, const vbool<K>& mask)
248
{
249
#if (RTC_MAX_INSTANCE_LEVEL_COUNT == 1)
250
vuint<K>::store(mask, tgt, src[0]);
251
252
#else
253
vbool<K> done = !mask;
254
for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) {
255
vuint<K>::store(mask, tgt + l, src[l]);
256
if (RTC_MAX_INSTANCE_LEVEL_COUNT > 4) {
257
done |= src[l] == RTC_INVALID_GEOMETRY_ID;
258
if (all(done)) break;
259
}
260
}
261
#endif
262
}
263
264
} // namespace instance_id_stack
265
} // namespace embree
266
267