Blender  V2.93
util_hash.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __UTIL_HASH_H__
18 #define __UTIL_HASH_H__
19 
20 #include "util/util_types.h"
21 
23 
24 /* ***** Jenkins Lookup3 Hash Functions ***** */
25 
26 /* Source: http://burtleburtle.net/bob/c/lookup3.c */
27 
28 #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
29 
30 #define mix(a, b, c) \
31  { \
32  a -= c; \
33  a ^= rot(c, 4); \
34  c += b; \
35  b -= a; \
36  b ^= rot(a, 6); \
37  a += c; \
38  c -= b; \
39  c ^= rot(b, 8); \
40  b += a; \
41  a -= c; \
42  a ^= rot(c, 16); \
43  c += b; \
44  b -= a; \
45  b ^= rot(a, 19); \
46  a += c; \
47  c -= b; \
48  c ^= rot(b, 4); \
49  b += a; \
50  } \
51  ((void)0)
52 
53 #define final(a, b, c) \
54  { \
55  c ^= b; \
56  c -= rot(b, 14); \
57  a ^= c; \
58  a -= rot(c, 11); \
59  b ^= a; \
60  b -= rot(a, 25); \
61  c ^= b; \
62  c -= rot(b, 16); \
63  a ^= c; \
64  a -= rot(c, 4); \
65  b ^= a; \
66  b -= rot(a, 14); \
67  c ^= b; \
68  c -= rot(b, 24); \
69  } \
70  ((void)0)
71 
73 {
74  uint a, b, c;
75  a = b = c = 0xdeadbeef + (1 << 2) + 13;
76 
77  a += kx;
78  final(a, b, c);
79 
80  return c;
81 }
82 
84 {
85  uint a, b, c;
86  a = b = c = 0xdeadbeef + (2 << 2) + 13;
87 
88  b += ky;
89  a += kx;
90  final(a, b, c);
91 
92  return c;
93 }
94 
96 {
97  uint a, b, c;
98  a = b = c = 0xdeadbeef + (3 << 2) + 13;
99 
100  c += kz;
101  b += ky;
102  a += kx;
103  final(a, b, c);
104 
105  return c;
106 }
107 
109 {
110  uint a, b, c;
111  a = b = c = 0xdeadbeef + (4 << 2) + 13;
112 
113  a += kx;
114  b += ky;
115  c += kz;
116  mix(a, b, c);
117 
118  a += kw;
119  final(a, b, c);
120 
121  return c;
122 }
123 
124 #undef rot
125 #undef final
126 #undef mix
127 
128 /* Hashing uint or uint[234] into a float in the range [0, 1]. */
129 
131 {
132  return (float)hash_uint(kx) / (float)0xFFFFFFFFu;
133 }
134 
136 {
137  return (float)hash_uint2(kx, ky) / (float)0xFFFFFFFFu;
138 }
139 
141 {
142  return (float)hash_uint3(kx, ky, kz) / (float)0xFFFFFFFFu;
143 }
144 
146 {
147  return (float)hash_uint4(kx, ky, kz, kw) / (float)0xFFFFFFFFu;
148 }
149 
150 /* Hashing float or float[234] into a float in the range [0, 1]. */
151 
153 {
155 }
156 
158 {
160 }
161 
163 {
165 }
166 
168 {
169  return hash_uint4_to_float(
171 }
172 
173 /* Hashing float[234] into float[234] of components in the range [0, 1]. */
174 
176 {
178 }
179 
181 {
183  hash_float4_to_float(make_float4(k.x, k.y, k.z, 1.0)),
184  hash_float4_to_float(make_float4(k.x, k.y, k.z, 2.0)));
185 }
186 
188 {
190  hash_float4_to_float(make_float4(k.w, k.x, k.y, k.z)),
191  hash_float4_to_float(make_float4(k.z, k.w, k.x, k.y)),
192  hash_float4_to_float(make_float4(k.y, k.z, k.w, k.x)));
193 }
194 
195 /* Hashing float or float[234] into float3 of components in range [0, 1]. */
196 
198 {
202 }
203 
205 {
207  hash_float3_to_float(make_float3(k.x, k.y, 1.0)),
208  hash_float3_to_float(make_float3(k.x, k.y, 2.0)));
209 }
210 
212 {
214  hash_float4_to_float(make_float4(k.z, k.x, k.w, k.y)),
215  hash_float4_to_float(make_float4(k.w, k.z, k.y, k.x)));
216 }
217 
218 /* SSE Versions Of Jenkins Lookup3 Hash Functions */
219 
220 #ifdef __KERNEL_SSE2__
221 # define rot(x, k) (((x) << (k)) | (srl(x, 32 - (k))))
222 
223 # define mix(a, b, c) \
224  { \
225  a -= c; \
226  a ^= rot(c, 4); \
227  c += b; \
228  b -= a; \
229  b ^= rot(a, 6); \
230  a += c; \
231  c -= b; \
232  c ^= rot(b, 8); \
233  b += a; \
234  a -= c; \
235  a ^= rot(c, 16); \
236  c += b; \
237  b -= a; \
238  b ^= rot(a, 19); \
239  a += c; \
240  c -= b; \
241  c ^= rot(b, 4); \
242  b += a; \
243  }
244 
245 # define final(a, b, c) \
246  { \
247  c ^= b; \
248  c -= rot(b, 14); \
249  a ^= c; \
250  a -= rot(c, 11); \
251  b ^= a; \
252  b -= rot(a, 25); \
253  c ^= b; \
254  c -= rot(b, 16); \
255  a ^= c; \
256  a -= rot(c, 4); \
257  b ^= a; \
258  b -= rot(a, 14); \
259  c ^= b; \
260  c -= rot(b, 24); \
261  }
262 
263 ccl_device_inline ssei hash_ssei(ssei kx)
264 {
265  ssei a, b, c;
266  a = b = c = ssei(0xdeadbeef + (1 << 2) + 13);
267 
268  a += kx;
269  final(a, b, c);
270 
271  return c;
272 }
273 
274 ccl_device_inline ssei hash_ssei2(ssei kx, ssei ky)
275 {
276  ssei a, b, c;
277  a = b = c = ssei(0xdeadbeef + (2 << 2) + 13);
278 
279  b += ky;
280  a += kx;
281  final(a, b, c);
282 
283  return c;
284 }
285 
286 ccl_device_inline ssei hash_ssei3(ssei kx, ssei ky, ssei kz)
287 {
288  ssei a, b, c;
289  a = b = c = ssei(0xdeadbeef + (3 << 2) + 13);
290 
291  c += kz;
292  b += ky;
293  a += kx;
294  final(a, b, c);
295 
296  return c;
297 }
298 
299 ccl_device_inline ssei hash_ssei4(ssei kx, ssei ky, ssei kz, ssei kw)
300 {
301  ssei a, b, c;
302  a = b = c = ssei(0xdeadbeef + (4 << 2) + 13);
303 
304  a += kx;
305  b += ky;
306  c += kz;
307  mix(a, b, c);
308 
309  a += kw;
310  final(a, b, c);
311 
312  return c;
313 }
314 
315 # if defined(__KERNEL_AVX__)
316 ccl_device_inline avxi hash_avxi(avxi kx)
317 {
318  avxi a, b, c;
319  a = b = c = avxi(0xdeadbeef + (1 << 2) + 13);
320 
321  a += kx;
322  final(a, b, c);
323 
324  return c;
325 }
326 
327 ccl_device_inline avxi hash_avxi2(avxi kx, avxi ky)
328 {
329  avxi a, b, c;
330  a = b = c = avxi(0xdeadbeef + (2 << 2) + 13);
331 
332  b += ky;
333  a += kx;
334  final(a, b, c);
335 
336  return c;
337 }
338 
339 ccl_device_inline avxi hash_avxi3(avxi kx, avxi ky, avxi kz)
340 {
341  avxi a, b, c;
342  a = b = c = avxi(0xdeadbeef + (3 << 2) + 13);
343 
344  c += kz;
345  b += ky;
346  a += kx;
347  final(a, b, c);
348 
349  return c;
350 }
351 
352 ccl_device_inline avxi hash_avxi4(avxi kx, avxi ky, avxi kz, avxi kw)
353 {
354  avxi a, b, c;
355  a = b = c = avxi(0xdeadbeef + (4 << 2) + 13);
356 
357  a += kx;
358  b += ky;
359  c += kz;
360  mix(a, b, c);
361 
362  a += kw;
363  final(a, b, c);
364 
365  return c;
366 }
367 # endif
368 
369 # undef rot
370 # undef final
371 # undef mix
372 
373 #endif
374 
375 #ifndef __KERNEL_GPU__
376 static inline uint hash_string(const char *str)
377 {
378  uint i = 0, c;
379 
380  while ((c = *str++))
381  i = i * 37 + c;
382 
383  return i;
384 }
385 #endif
386 
388 
389 #endif /* __UTIL_HASH_H__ */
typedef float(TangentPoint)[2]
unsigned int uint
Definition: BLI_sys_types.h:83
#define str(s)
#define ccl_device_inline
#define CCL_NAMESPACE_END
#define make_float2(x, y)
#define make_float4(x, y, z, w)
#define make_float3(x, y, z)
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
Definition: util_avxi.h:24
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
static uint hash_string(const char *str)
Definition: util_hash.h:376
ccl_device_inline uint hash_uint2(uint kx, uint ky)
Definition: util_hash.h:83
ccl_device_inline float hash_uint_to_float(uint kx)
Definition: util_hash.h:130
ccl_device_inline float3 hash_float_to_float3(float k)
Definition: util_hash.h:197
ccl_device_inline float3 hash_float4_to_float3(float4 k)
Definition: util_hash.h:211
ccl_device_inline float hash_float_to_float(float k)
Definition: util_hash.h:152
ccl_device_inline float3 hash_float2_to_float3(float2 k)
Definition: util_hash.h:204
ccl_device_inline float2 hash_float2_to_float2(float2 k)
Definition: util_hash.h:175
ccl_device_inline float hash_float2_to_float(float2 k)
Definition: util_hash.h:157
ccl_device_inline uint hash_uint3(uint kx, uint ky, uint kz)
Definition: util_hash.h:95
ccl_device_inline float hash_float4_to_float(float4 k)
Definition: util_hash.h:167
ccl_device_inline uint hash_uint4(uint kx, uint ky, uint kz, uint kw)
Definition: util_hash.h:108
ccl_device_inline float hash_uint4_to_float(uint kx, uint ky, uint kz, uint kw)
Definition: util_hash.h:145
ccl_device_inline float4 hash_float4_to_float4(float4 k)
Definition: util_hash.h:187
ccl_device_inline uint hash_uint(uint kx)
Definition: util_hash.h:72
ccl_device_inline float hash_uint2_to_float(uint kx, uint ky)
Definition: util_hash.h:135
ccl_device_inline float hash_float3_to_float(float3 k)
Definition: util_hash.h:162
ccl_device_inline float3 hash_float3_to_float3(float3 k)
Definition: util_hash.h:180
ccl_device_inline float hash_uint3_to_float(uint kx, uint ky, uint kz)
Definition: util_hash.h:140
#define mix(a, b, c)
Definition: util_hash.h:30
ccl_device_inline uint __float_as_uint(float f)
Definition: util_math.h:222