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