* Replace license text in headers with SPDX identifiers. * Remove specific license info from outdated readme.txt, instead leave details to the source files. * Add list of SPDX license identifiers used, and corresponding license texts. * Update copyright dates while we're at it. Ref D14069, T95597
377 lines
7.1 KiB
C
377 lines
7.1 KiB
C
/* SPDX-License-Identifier: Apache-2.0
|
|
* Copyright 2011-2022 Blender Foundation */
|
|
|
|
#ifndef __UTIL_HASH_H__
|
|
#define __UTIL_HASH_H__
|
|
|
|
#include "util/types.h"
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
/* ***** Jenkins Lookup3 Hash Functions ***** */
|
|
|
|
/* Source: http://burtleburtle.net/bob/c/lookup3.c */
|
|
|
|
#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
|
|
|
|
#define mix(a, b, c) \
|
|
{ \
|
|
a -= c; \
|
|
a ^= rot(c, 4); \
|
|
c += b; \
|
|
b -= a; \
|
|
b ^= rot(a, 6); \
|
|
a += c; \
|
|
c -= b; \
|
|
c ^= rot(b, 8); \
|
|
b += a; \
|
|
a -= c; \
|
|
a ^= rot(c, 16); \
|
|
c += b; \
|
|
b -= a; \
|
|
b ^= rot(a, 19); \
|
|
a += c; \
|
|
c -= b; \
|
|
c ^= rot(b, 4); \
|
|
b += a; \
|
|
} \
|
|
((void)0)
|
|
|
|
#define final(a, b, c) \
|
|
{ \
|
|
c ^= b; \
|
|
c -= rot(b, 14); \
|
|
a ^= c; \
|
|
a -= rot(c, 11); \
|
|
b ^= a; \
|
|
b -= rot(a, 25); \
|
|
c ^= b; \
|
|
c -= rot(b, 16); \
|
|
a ^= c; \
|
|
a -= rot(c, 4); \
|
|
b ^= a; \
|
|
b -= rot(a, 14); \
|
|
c ^= b; \
|
|
c -= rot(b, 24); \
|
|
} \
|
|
((void)0)
|
|
|
|
ccl_device_inline uint hash_uint(uint kx)
|
|
{
|
|
uint a, b, c;
|
|
a = b = c = 0xdeadbeef + (1 << 2) + 13;
|
|
|
|
a += kx;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
ccl_device_inline uint hash_uint2(uint kx, uint ky)
|
|
{
|
|
uint a, b, c;
|
|
a = b = c = 0xdeadbeef + (2 << 2) + 13;
|
|
|
|
b += ky;
|
|
a += kx;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
ccl_device_inline uint hash_uint3(uint kx, uint ky, uint kz)
|
|
{
|
|
uint a, b, c;
|
|
a = b = c = 0xdeadbeef + (3 << 2) + 13;
|
|
|
|
c += kz;
|
|
b += ky;
|
|
a += kx;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
ccl_device_inline uint hash_uint4(uint kx, uint ky, uint kz, uint kw)
|
|
{
|
|
uint a, b, c;
|
|
a = b = c = 0xdeadbeef + (4 << 2) + 13;
|
|
|
|
a += kx;
|
|
b += ky;
|
|
c += kz;
|
|
mix(a, b, c);
|
|
|
|
a += kw;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
#undef rot
|
|
#undef final
|
|
#undef mix
|
|
|
|
/* Hashing uint or uint[234] into a float in the range [0, 1]. */
|
|
|
|
ccl_device_inline float hash_uint_to_float(uint kx)
|
|
{
|
|
return (float)hash_uint(kx) / (float)0xFFFFFFFFu;
|
|
}
|
|
|
|
ccl_device_inline float hash_uint2_to_float(uint kx, uint ky)
|
|
{
|
|
return (float)hash_uint2(kx, ky) / (float)0xFFFFFFFFu;
|
|
}
|
|
|
|
ccl_device_inline float hash_uint3_to_float(uint kx, uint ky, uint kz)
|
|
{
|
|
return (float)hash_uint3(kx, ky, kz) / (float)0xFFFFFFFFu;
|
|
}
|
|
|
|
ccl_device_inline float hash_uint4_to_float(uint kx, uint ky, uint kz, uint kw)
|
|
{
|
|
return (float)hash_uint4(kx, ky, kz, kw) / (float)0xFFFFFFFFu;
|
|
}
|
|
|
|
/* Hashing float or float[234] into a float in the range [0, 1]. */
|
|
|
|
ccl_device_inline float hash_float_to_float(float k)
|
|
{
|
|
return hash_uint_to_float(__float_as_uint(k));
|
|
}
|
|
|
|
ccl_device_inline float hash_float2_to_float(float2 k)
|
|
{
|
|
return hash_uint2_to_float(__float_as_uint(k.x), __float_as_uint(k.y));
|
|
}
|
|
|
|
ccl_device_inline float hash_float3_to_float(float3 k)
|
|
{
|
|
return hash_uint3_to_float(__float_as_uint(k.x), __float_as_uint(k.y), __float_as_uint(k.z));
|
|
}
|
|
|
|
ccl_device_inline float hash_float4_to_float(float4 k)
|
|
{
|
|
return hash_uint4_to_float(
|
|
__float_as_uint(k.x), __float_as_uint(k.y), __float_as_uint(k.z), __float_as_uint(k.w));
|
|
}
|
|
|
|
/* Hashing float[234] into float[234] of components in the range [0, 1]. */
|
|
|
|
ccl_device_inline float2 hash_float2_to_float2(float2 k)
|
|
{
|
|
return make_float2(hash_float2_to_float(k), hash_float3_to_float(make_float3(k.x, k.y, 1.0)));
|
|
}
|
|
|
|
ccl_device_inline float3 hash_float3_to_float3(float3 k)
|
|
{
|
|
return make_float3(hash_float3_to_float(k),
|
|
hash_float4_to_float(make_float4(k.x, k.y, k.z, 1.0)),
|
|
hash_float4_to_float(make_float4(k.x, k.y, k.z, 2.0)));
|
|
}
|
|
|
|
ccl_device_inline float4 hash_float4_to_float4(float4 k)
|
|
{
|
|
return make_float4(hash_float4_to_float(k),
|
|
hash_float4_to_float(make_float4(k.w, k.x, k.y, k.z)),
|
|
hash_float4_to_float(make_float4(k.z, k.w, k.x, k.y)),
|
|
hash_float4_to_float(make_float4(k.y, k.z, k.w, k.x)));
|
|
}
|
|
|
|
/* Hashing float or float[234] into float3 of components in range [0, 1]. */
|
|
|
|
ccl_device_inline float3 hash_float_to_float3(float k)
|
|
{
|
|
return make_float3(hash_float_to_float(k),
|
|
hash_float2_to_float(make_float2(k, 1.0)),
|
|
hash_float2_to_float(make_float2(k, 2.0)));
|
|
}
|
|
|
|
ccl_device_inline float3 hash_float2_to_float3(float2 k)
|
|
{
|
|
return make_float3(hash_float2_to_float(k),
|
|
hash_float3_to_float(make_float3(k.x, k.y, 1.0)),
|
|
hash_float3_to_float(make_float3(k.x, k.y, 2.0)));
|
|
}
|
|
|
|
ccl_device_inline float3 hash_float4_to_float3(float4 k)
|
|
{
|
|
return make_float3(hash_float4_to_float(k),
|
|
hash_float4_to_float(make_float4(k.z, k.x, k.w, k.y)),
|
|
hash_float4_to_float(make_float4(k.w, k.z, k.y, k.x)));
|
|
}
|
|
|
|
/* SSE Versions Of Jenkins Lookup3 Hash Functions */
|
|
|
|
#ifdef __KERNEL_SSE2__
|
|
# define rot(x, k) (((x) << (k)) | (srl(x, 32 - (k))))
|
|
|
|
# define mix(a, b, c) \
|
|
{ \
|
|
a -= c; \
|
|
a ^= rot(c, 4); \
|
|
c += b; \
|
|
b -= a; \
|
|
b ^= rot(a, 6); \
|
|
a += c; \
|
|
c -= b; \
|
|
c ^= rot(b, 8); \
|
|
b += a; \
|
|
a -= c; \
|
|
a ^= rot(c, 16); \
|
|
c += b; \
|
|
b -= a; \
|
|
b ^= rot(a, 19); \
|
|
a += c; \
|
|
c -= b; \
|
|
c ^= rot(b, 4); \
|
|
b += a; \
|
|
}
|
|
|
|
# define final(a, b, c) \
|
|
{ \
|
|
c ^= b; \
|
|
c -= rot(b, 14); \
|
|
a ^= c; \
|
|
a -= rot(c, 11); \
|
|
b ^= a; \
|
|
b -= rot(a, 25); \
|
|
c ^= b; \
|
|
c -= rot(b, 16); \
|
|
a ^= c; \
|
|
a -= rot(c, 4); \
|
|
b ^= a; \
|
|
b -= rot(a, 14); \
|
|
c ^= b; \
|
|
c -= rot(b, 24); \
|
|
}
|
|
|
|
ccl_device_inline ssei hash_ssei(ssei kx)
|
|
{
|
|
ssei a, b, c;
|
|
a = b = c = ssei(0xdeadbeef + (1 << 2) + 13);
|
|
|
|
a += kx;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
ccl_device_inline ssei hash_ssei2(ssei kx, ssei ky)
|
|
{
|
|
ssei a, b, c;
|
|
a = b = c = ssei(0xdeadbeef + (2 << 2) + 13);
|
|
|
|
b += ky;
|
|
a += kx;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
ccl_device_inline ssei hash_ssei3(ssei kx, ssei ky, ssei kz)
|
|
{
|
|
ssei a, b, c;
|
|
a = b = c = ssei(0xdeadbeef + (3 << 2) + 13);
|
|
|
|
c += kz;
|
|
b += ky;
|
|
a += kx;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
ccl_device_inline ssei hash_ssei4(ssei kx, ssei ky, ssei kz, ssei kw)
|
|
{
|
|
ssei a, b, c;
|
|
a = b = c = ssei(0xdeadbeef + (4 << 2) + 13);
|
|
|
|
a += kx;
|
|
b += ky;
|
|
c += kz;
|
|
mix(a, b, c);
|
|
|
|
a += kw;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
# if defined(__KERNEL_AVX__)
|
|
ccl_device_inline avxi hash_avxi(avxi kx)
|
|
{
|
|
avxi a, b, c;
|
|
a = b = c = avxi(0xdeadbeef + (1 << 2) + 13);
|
|
|
|
a += kx;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
ccl_device_inline avxi hash_avxi2(avxi kx, avxi ky)
|
|
{
|
|
avxi a, b, c;
|
|
a = b = c = avxi(0xdeadbeef + (2 << 2) + 13);
|
|
|
|
b += ky;
|
|
a += kx;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
ccl_device_inline avxi hash_avxi3(avxi kx, avxi ky, avxi kz)
|
|
{
|
|
avxi a, b, c;
|
|
a = b = c = avxi(0xdeadbeef + (3 << 2) + 13);
|
|
|
|
c += kz;
|
|
b += ky;
|
|
a += kx;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
|
|
ccl_device_inline avxi hash_avxi4(avxi kx, avxi ky, avxi kz, avxi kw)
|
|
{
|
|
avxi a, b, c;
|
|
a = b = c = avxi(0xdeadbeef + (4 << 2) + 13);
|
|
|
|
a += kx;
|
|
b += ky;
|
|
c += kz;
|
|
mix(a, b, c);
|
|
|
|
a += kw;
|
|
final(a, b, c);
|
|
|
|
return c;
|
|
}
|
|
# endif
|
|
|
|
# undef rot
|
|
# undef final
|
|
# undef mix
|
|
|
|
#endif
|
|
|
|
#ifndef __KERNEL_GPU__
|
|
static inline uint hash_string(const char *str)
|
|
{
|
|
uint i = 0, c;
|
|
|
|
while ((c = *str++))
|
|
i = i * 37 + c;
|
|
|
|
return i;
|
|
}
|
|
#endif
|
|
|
|
CCL_NAMESPACE_END
|
|
|
|
#endif /* __UTIL_HASH_H__ */
|