From 9cac1c9db72996134e408f0c21bbb6261c453d64 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 16 Dec 2024 11:23:13 +0700 Subject: [PATCH 01/42] moved math changes over --- include/nbl/builtin/hlsl/math/functions.hlsl | 553 +++++++++++++++++++ include/nbl/builtin/hlsl/tgmath.hlsl | 103 ++++ 2 files changed, 656 insertions(+) create mode 100644 include/nbl/builtin/hlsl/math/functions.hlsl create mode 100644 include/nbl/builtin/hlsl/tgmath.hlsl diff --git a/include/nbl/builtin/hlsl/math/functions.hlsl b/include/nbl/builtin/hlsl/math/functions.hlsl new file mode 100644 index 0000000000..87419517b8 --- /dev/null +++ b/include/nbl/builtin/hlsl/math/functions.hlsl @@ -0,0 +1,553 @@ +// Copyright (C) 2018-2023 - DevSH Graphics Programming Sp. z O.O. +// This file is part of the "Nabla Engine". +// For conditions of distribution and use, see copyright notice in nabla.h +#ifndef _NBL_BUILTIN_HLSL_MATH_FUNCTIONS_INCLUDED_ +#define _NBL_BUILTIN_HLSL_MATH_FUNCTIONS_INCLUDED_ + +#include "nbl/builtin/hlsl/cpp_compat.hlsl" +#include "nbl/builtin/hlsl/numbers.hlsl" +#include "nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" + +namespace nbl +{ +namespace hlsl +{ +namespace math +{ + +namespace impl +{ +template +struct lp_norm; + +// infinity case +template +struct lp_norm +{ + static scalar_type_t __call(const T v) + { + scalar_type_t retval = abs(v[0]); + for (int i = 1; i < rank::value; i++) + retval = max(abs(v[i]),retval); + return retval; + } +}; + +// TOOD: is this doing what it should be? +template +struct lp_norm +{ + static scalar_type_t __sum(const T v) + { + scalar_type_t retval = abs(v[0]); + for (int i = 1; i < rank::value; i++) + retval += abs(v[i]); + return retval; + } + + static scalar_type_t __call(const T v) + { + return __sum(v); + } +}; + +template +struct lp_norm +{ + static scalar_type_t __sum(const T v) + { + return dot(v, v); // TODO: wait for overloaded dot? + } + + static scalar_type_t __call(const T v) + { + return sqrt(__sum(v)); + } +}; + +// TODO: even/odd cases +} + +template0) +scalar_type_t lpNormPreroot(NBL_CONST_REF_ARG(T) v) +{ + return impl::lp_norm::__sum(v); +} + +template +scalar_type_t lpNorm(NBL_CONST_REF_ARG(T) v) +{ + return impl::lp_norm::__call(v); +} + + +template ) +vector reflect(vector I, vector N, T NdotI) +{ + return N * 2.0 * NdotI - I; +} + +template ) +vector reflect(vector I, vector N) +{ + T NdotI = dot(N, I); + return reflect(I, N, NdotI); +} + + +namespace impl +{ +template +struct orientedEtas; + +template<> +struct orientedEtas +{ + static bool __call(out float orientedEta, out float rcpOrientedEta, float NdotI, float eta) + { + const bool backside = NdotI < 0.0; + const float rcpEta = 1.0 / eta; + orientedEta = backside ? rcpEta : eta; + rcpOrientedEta = backside ? eta : rcpEta; + return backside; + } +}; + +template<> +struct orientedEtas +{ + static bool __call(out float3 orientedEta, out float3 rcpOrientedEta, float NdotI, float3 eta) + { + const bool backside = NdotI < 0.0; + const float3 rcpEta = (float3)1.0 / eta; + orientedEta = backside ? rcpEta:eta; + rcpOrientedEta = backside ? eta:rcpEta; + return backside; + } +}; +} + +template || is_vector_v) +bool getOrientedEtas(out T orientedEta, out T rcpOrientedEta, scalar_type_t NdotI, T eta) +{ + return impl::orientedEtas::__call(orientedEta, rcpOrientedEta, NdotI, eta); +} + + +namespace impl +{ +template +struct refract +{ + using this_t = refract; + using vector_type = vector; + + static this_t create(vector_type I, vector_type N, bool backside, T NdotI, T NdotI2, T rcpOrientedEta, T rcpOrientedEta2) + { + this_t retval; + retval.I = I; + retval.N = N; + retval.backside = backside; + retval.NdotI = NdotI; + retval.NdotI2 = NdotI2; + retval.rcpOrientedEta = rcpOrientedEta; + retval.rcpOrientedEta2 = rcpOrientedEta2; + return retval; + } + + static this_t create(vector_type I, vector_type N, T NdotI, T eta) + { + this_t retval; + retval.I = I; + retval.N = N; + T orientedEta; + retval.backside = getOrientedEtas(orientedEta, retval.rcpOrientedEta, NdotI, eta); + retval.NdotI = NdotI; + retval.NdotI2 = NdotI * NdotI; + retval.rcpOrientedEta2 = retval.rcpOrientedEta * retval.rcpOrientedEta; + return retval; + } + + static this_t create(vector_type I, vector_type N, T eta) + { + this_t retval; + retval.I = I; + retval.N = N; + retval.NdotI = dot(N, I); + T orientedEta; + retval.backside = getOrientedEtas(orientedEta, retval.rcpOrientedEta, retval.NdotI, eta); + retval.NdotI2 = retval.NdotI * retval.NdotI; + retval.rcpOrientedEta2 = retval.rcpOrientedEta * retval.rcpOrientedEta; + return retval; + } + + T computeNdotT() + { + T NdotT2 = rcpOrientedEta2 * NdotI2 + 1.0 - rcpOrientedEta2; + T absNdotT = sqrt(NdotT2); + return backside ? absNdotT : -(absNdotT); + } + + vector_type doRefract() + { + return N * (NdotI * rcpOrientedEta + computeNdotT()) - rcpOrientedEta * I; + } + + static vector_type doReflectRefract(bool _refract, vector_type _I, vector_type _N, T _NdotI, T _NdotTorR, T _rcpOrientedEta) + { + return _N * (_NdotI * (_refract ? _rcpOrientedEta : 1.0) + _NdotTorR) - _I * (_refract ? _rcpOrientedEta : 1.0); + } + + vector_type doReflectRefract(bool r) + { + const T NdotTorR = r ? computeNdotT() : NdotI; + return doReflectRefract(r, I, N, NdotI, NdotTorR, rcpOrientedEta); + } + + vector_type I; + vector_type N; + bool backside; + T NdotI; + T NdotI2; + T rcpOrientedEta; + T rcpOrientedEta2; +}; +} + +template) +vector refract(vector I, vector N, bool backside, T NdotI, T NdotI2, T rcpOrientedEta, T rcpOrientedEta2) +{ + impl::refract r = impl::refract::create(I, N, backside, NdotI, NdotI2, rcpOrientedEta, rcpOrientedEta2); + return r.doRefract(); +} + +template) +vector refract(vector I, vector N, T NdotI, T eta) +{ + impl::refract r = impl::refract::create(I, N, NdotI, eta); + return r.doRefract(); +} + +template) +vector refract(vector I, vector N, T eta) +{ + impl::refract r = impl::refract::create(I, N, eta); + return r.doRefract(); +} + +// I don't like exposing these next two +template) +vector reflectRefract_computeNdotT(bool backside, T NdotI2, T rcpOrientedEta2) +{ + impl::refract r; + r.NdotI2 = NdotI2; + r.rcpOrientedEta2 = rcpOrientedEta2; + r.backside = backside; + return r.computeNdotT(); +} + +template) +vector reflectRefract_impl(bool _refract, vector _I, vector _N, T _NdotI, T _NdotTorR, T _rcpOrientedEta) +{ + return impl::refract::doReflectRefract(_refract, _I, _N, _NdotI, _NdotTorR, _rcpOrientedEta); +} + +template) +vector reflectRefract(bool _refract, vector I, vector N, bool backside, T NdotI, T NdotI2, T rcpOrientedEta, T rcpOrientedEta2) +{ + impl::refract r = impl::refract::create(I, N, backside, NdotI, NdotI2, rcpOrientedEta, rcpOrientedEta2); + return r.doReflectRefract(_refract); +} + +template) +vector reflectRefract(bool _refract, vector I, vector N, T NdotI, T eta) +{ + impl::refract r = impl::refract::create(I, N, NdotI, eta); + return r.doReflectRefract(_refract); +} + + +// valid only for `theta` in [-PI,PI] +template ) +void sincos(T theta, out T s, out T c) +{ + c = cos(theta); + s = sqrt(1.0-c*c); + s = (theta < 0.0) ? -s : s; // TODO: test with XOR +} + +template ) +matrix frisvad(vector n) // TODO: confirm dimensions of matrix +{ + const float a = 1.0 / (1.0 + n.z); + const float b = -n.x * n.y * a; + return (n.z < -0.9999999) ? matrix(vector(0.0,-1.0,0.0), vector(-1.0,0.0,0.0)) : + matrix(vector(1.0-n.x*n.x*a, b, -n.x), vector(b, 1.0-n.y*n.y*a, -n.y)); +} + +bool partitionRandVariable(in float leftProb, inout float xi, out float rcpChoiceProb) +{ + NBL_CONSTEXPR float NEXT_ULP_AFTER_UNITY = asfloat(0x3f800001u); + const bool pickRight = xi >= leftProb * NEXT_ULP_AFTER_UNITY; + + // This is all 100% correct taking into account the above NEXT_ULP_AFTER_UNITY + xi -= pickRight ? leftProb : 0.0; + + rcpChoiceProb = 1.0 / (pickRight ? (1.0 - leftProb) : leftProb); + xi *= rcpChoiceProb; + + return pickRight; +} + + +// @ return abs(x) if cond==true, max(x,0.0) otherwise +template || is_vector_v) +T conditionalAbsOrMax(bool cond, T x, T limit); + +template <> +float conditionalAbsOrMax(bool cond, float x, float limit) +{ + const float condAbs = asfloat(asuint(x) & uint(cond ? 0x7fFFffFFu:0xffFFffFFu)); + return max(condAbs,limit); +} + +template <> +float2 conditionalAbsOrMax(bool cond, float2 x, float2 limit) +{ + const float2 condAbs = asfloat(asuint(x) & select(cond, (uint2)0x7fFFffFFu, (uint2)0xffFFffFFu)); + return max(condAbs,limit); +} + +template <> +float3 conditionalAbsOrMax(bool cond, float3 x, float3 limit) +{ + const float3 condAbs = asfloat(asuint(x) & select(cond, (uint3)0x7fFFffFFu, (uint3)0xffFFffFFu)); + return max(condAbs,limit); +} + +template <> +float4 conditionalAbsOrMax(bool cond, float4 x, float4 limit) +{ + const float4 condAbs = asfloat(asuint(x) & select(cond, (uint4)0x7fFFffFFu, (uint4)0xffFFffFFu)); + return max(condAbs,limit); +} + +namespace impl +{ +struct bitFields // need template? +{ + using this_t = bitFields; + + static this_t create(uint base, uint value, uint offset, uint count) + { + this_t retval; + retval.base = base; + retval.value = value; + retval.offset = offset; + retval.count = count; + return retval; + } + + uint __insert() + { + const uint shifted_masked_value = (value & ((0x1u << count) - 1u)) << offset; + const uint lo = base & ((0x1u << offset) - 1u); + const uint hi = base ^ lo; + return (hi << count) | shifted_masked_value | lo; + } + + uint __overwrite() + { + return spirv::bitFieldInsert(base, value, offset, count); + } + + uint base; + uint value; + uint offset; + uint count; +}; +} + +uint bitFieldOverwrite(uint base, uint value, uint offset, uint count) +{ + impl::bitFields b = impl::bitFields::create(base, value, offset, count); + return b.__overwrite(); +} + +uint bitFieldInsert(uint base, uint value, uint offset, uint count) +{ + impl::bitFields b = impl::bitFields::create(base, value, offset, count); + return b.__insert(); +} + +namespace impl +{ +struct trigonometry +{ + using this_t = trigonometry; + + static this_t create() + { + this_t retval; + retval.tmp0 = 0; + retval.tmp1 = 0; + retval.tmp2 = 0; + retval.tmp3 = 0; + retval.tmp4 = 0; + retval.tmp5 = 0; + return retval; + } + + static this_t create(float cosA, float cosB, float cosC, float sinA, float sinB, float sinC) + { + this_t retval; + retval.tmp0 = cosA; + retval.tmp1 = cosB; + retval.tmp2 = cosC; + retval.tmp3 = sinA; + retval.tmp4 = sinB; + retval.tmp5 = sinC; + return retval; + } + + float getArccosSumofABC_minus_PI() + { + const bool AltminusB = tmp0 < (-tmp1); + const float cosSumAB = tmp0 * tmp1 - tmp3 * tmp4; + const bool ABltminusC = cosSumAB < (-tmp2); + const bool ABltC = cosSumAB < tmp2; + // apply triple angle formula + const float absArccosSumABC = acos(clamp(cosSumAB * tmp2 - (tmp0 * tmp4 + tmp3 * tmp1) * tmp5, -1.f, 1.f)); + return ((AltminusB ? ABltC : ABltminusC) ? (-absArccosSumABC) : absArccosSumABC) + (AltminusB | ABltminusC ? numbers::pi : (-numbers::pi)); + } + + static void combineCosForSumOfAcos(float cosA, float cosB, float biasA, float biasB, out float out0, out float out1) + { + const float bias = biasA + biasB; + const float a = cosA; + const float b = cosB; + const bool reverse = abs(min(a, b)) > max(a, b); + const float c = a * b - sqrt((1.0f - a * a) * (1.0f - b * b)); + + if (reverse) + { + out0 = -c; + out1 = bias + numbers::pi; + } + else + { + out0 = c; + out1 = bias; + } + } + + float tmp0; + float tmp1; + float tmp2; + float tmp3; + float tmp4; + float tmp5; +}; +} + +float getArccosSumofABC_minus_PI(float cosA, float cosB, float cosC, float sinA, float sinB, float sinC) +{ + impl::trigonometry trig = impl::trigonometry::create(cosA, cosB, cosC, sinA, sinB, sinC); + return trig.getArccosSumofABC_minus_PI(); +} + +void combineCosForSumOfAcos(float cosA, float cosB, float biasA, float biasB, out float out0, out float out1) +{ + impl::trigonometry trig = impl::trigonometry::create(); + impl::trigonometry::combineCosForSumOfAcos(cosA, cosB, biasA, biasB, trig.tmp0, trig.tmp1); + out0 = trig.tmp0; + out1 = trig.tmp1; +} + +// returns acos(a) + acos(b) +float getSumofArccosAB(float cosA, float cosB) +{ + impl::trigonometry trig = impl::trigonometry::create(); + impl::trigonometry::combineCosForSumOfAcos(cosA, cosB, 0.0f, 0.0f, trig.tmp0, trig.tmp1); + return acos(trig.tmp0) + trig.tmp1; +} + +// returns acos(a) + acos(b) + acos(c) + acos(d) +float getSumofArccosABCD(float cosA, float cosB, float cosC, float cosD) +{ + impl::trigonometry trig = impl::trigonometry::create(); + impl::trigonometry::combineCosForSumOfAcos(cosA, cosB, 0.0f, 0.0f, trig.tmp0, trig.tmp1); + impl::trigonometry::combineCosForSumOfAcos(cosC, cosD, 0.0f, 0.0f, trig.tmp2, trig.tmp3); + impl::trigonometry::combineCosForSumOfAcos(trig.tmp0, trig.tmp2, trig.tmp1, trig.tmp3, trig.tmp4, trig.tmp5); + return acos(trig.tmp4) + trig.tmp5; +} + +namespace impl +{ +template +struct applyChainRule4D +{ + static matrix __call(matrix dFdG, matrix dGdR) + { + return mul(dFdG, dGdR); + } +}; + +template +struct applyChainRule3D : applyChainRule4D +{ + static vector __call(matrix dFdG, vector dGdR) + { + return mul(dFdG, dGdR); + } +}; + +template +struct applyChainRule2D : applyChainRule4D +{ + static vector __call(vector dFdG, T dGdR) + { + return mul(dFdG, dGdR); + } +}; + +template +struct applyChainRule1D : applyChainRule4D +{ + static T __call(T dFdG, T dGdR) + { + return dFdG * dGdR; + } +}; +} + +// possible to derive M,N,P automatically? +template && M>1 && N>1 && P>1) +matrix applyChainRule(matrix dFdG, matrix dGdR) +{ + return impl::applyChainRule4D::__call(dFdG, dGdR); +} + +template && M>1 && N>1) +vector applyChainRule(matrix dFdG, vector dGdR) +{ + return impl::applyChainRule3D::__call(dFdG, dGdR); +} + +template && M>1) +vector applyChainRule(vector dFdG, T dGdR) +{ + return impl::applyChainRule2D::__call(dFdG, dGdR); +} + +template) +T applyChainRule(T dFdG, T dGdR) +{ + return impl::applyChainRule1D::__call(dFdG, dGdR); +} + +} +} +} + +#endif diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl new file mode 100644 index 0000000000..80e06bda56 --- /dev/null +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -0,0 +1,103 @@ +// Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. +// This file is part of the "Nabla Engine". +// For conditions of distribution and use, see copyright notice in nabla.h +#ifndef _NBL_BUILTIN_HLSL_TGMATH_INCLUDED_ +#define _NBL_BUILTIN_HLSL_TGMATH_INCLUDED_ + +#include +// C++ headers +#ifndef __HLSL_VERSION +#include +#endif + +namespace nbl +{ +namespace hlsl +{ + +namespace impl +{ +template +struct erf; + +template<> +struct erf +{ + static float __call(float _x) + { + const float a1 = 0.254829592; + const float a2 = -0.284496736; + const float a3 = 1.421413741; + const float a4 = -1.453152027; + const float a5 = 1.061405429; + const float p = 0.3275911; + + float sign = sign(_x); + float x = abs(_x); + + float t = 1.0 / (1.0 + p*x); + float y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * exp(-x * x); + + return sign * y; + } +}; + + +template +struct erfInv; + +template<> +struct erfInv +{ + static float __call(float _x) + { + float x = clamp(_x, -0.99999, 0.99999); + float w = -log((1.0-x) * (1.0+x)); + float p; + if (w<5.0) + { + w -= 2.5; + p = 2.81022636e-08; + p = 3.43273939e-07 + p*w; + p = -3.5233877e-06 + p*w; + p = -4.39150654e-06 + p*w; + p = 0.00021858087 + p*w; + p = -0.00125372503 + p*w; + p = -0.00417768164 + p*w; + p = 0.246640727 + p*w; + p = 1.50140941 + p*w; + } + else + { + w = sqrt(w) - 3.0; + p = -0.000200214257; + p = 0.000100950558 + p*w; + p = 0.00134934322 + p*w; + p = -0.00367342844 + p*w; + p = 0.00573950773 + p*w; + p = -0.0076224613 + p*w; + p = 0.00943887047 + p*w; + p = 1.00167406 + p*w; + p = 2.83297682 + p*w; + } + return p*x; + } +}; +} + +template +T erf(T _x) +{ + return impl::erf::__call(_x); +} + +template +T erfInv(T _x) +{ + return impl::erfInv::__call(_x); +} + +} +} + +#endif From 8de3ce4426ab1600d7a8e561e943528552e4c312 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 16 Dec 2024 11:35:40 +0700 Subject: [PATCH 02/42] rsqrt not from stl --- include/nbl/builtin/hlsl/tgmath.hlsl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index 80e06bda56..fe2e65a71a 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -97,6 +97,17 @@ T erfInv(T _x) return impl::erfInv::__call(_x); } + +template +T rsqrt(T _x) +{ +#ifdef __HLSL_VERSION + return rsqrt(_x); +#else + return 1.0 / sqrt(_x); +#endif +} + } } From b33aaed81e3ee2b13984b718231104d7cabda097 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 16 Dec 2024 14:46:13 +0700 Subject: [PATCH 03/42] moved math funcs to tgmath --- .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 62 ------ include/nbl/builtin/hlsl/tgmath.hlsl | 176 +++++++++++------- 2 files changed, 106 insertions(+), 132 deletions(-) diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index 9f74d5f2e1..84228f4355 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -90,18 +90,6 @@ inline typename cpp_compat_intrinsics_impl::find_msb_return_type::type return cpp_compat_intrinsics_impl::find_msb_helper::findMSB(val); } -// TODO: some of the functions in this header should move to `tgmath` -template -inline T floor(NBL_CONST_REF_ARG(T) val) -{ -#ifdef __HLSL_VERSION - return spirv::floor(val); -#else - return glm::floor(val); -#endif - -} - // TODO: for clearer error messages, use concepts to ensure that input type is a square matrix // inverse not defined cause its implemented via hidden friend template @@ -114,12 +102,6 @@ inline matrix inverse(NBL_CONST_REF_ARG(matrix) m) #endif } -template -inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) -{ - return cpp_compat_intrinsics_impl::lerp_helper::lerp(x, y, a); -} - // transpose not defined cause its implemented via hidden friend template inline matrix transpose(NBL_CONST_REF_ARG(matrix) m) @@ -151,50 +133,6 @@ inline T max(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b) #endif } -template -inline FloatingPoint isnan(NBL_CONST_REF_ARG(FloatingPoint) val) -{ -#ifdef __HLSL_VERSION - return spirv::isNan(val); -#else - return std::isnan(val); -#endif -} - -template -inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) -{ -#ifdef __HLSL_VERSION - return spirv::isInf(val); -#else - return std::isinf(val); -#endif -} - -template -inline T exp2(NBL_CONST_REF_ARG(T) val) -{ -#ifdef __HLSL_VERSION - return spirv::exp2(val); -#else - return std::exp2(val); -#endif -} - -#define DEFINE_EXP2_SPECIALIZATION(TYPE)\ -template<>\ -inline TYPE exp2(NBL_CONST_REF_ARG(TYPE) val)\ -{\ - return _static_cast(1ull << val);\ -}\ - -DEFINE_EXP2_SPECIALIZATION(int16_t) -DEFINE_EXP2_SPECIALIZATION(int32_t) -DEFINE_EXP2_SPECIALIZATION(int64_t) -DEFINE_EXP2_SPECIALIZATION(uint16_t) -DEFINE_EXP2_SPECIALIZATION(uint32_t) -DEFINE_EXP2_SPECIALIZATION(uint64_t) - template inline FloatingPoint rsqrt(FloatingPoint x) { diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index fe2e65a71a..ae6989ed08 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -4,7 +4,7 @@ #ifndef _NBL_BUILTIN_HLSL_TGMATH_INCLUDED_ #define _NBL_BUILTIN_HLSL_TGMATH_INCLUDED_ -#include +#include // C++ headers #ifndef __HLSL_VERSION #include @@ -15,99 +15,135 @@ namespace nbl namespace hlsl { -namespace impl +template +inline FloatingPoint erf(FloatingPoint _x) { -template -struct erf; +#ifdef __HLSL_VERSION + const FloatingPoint a1 = 0.254829592; + const FloatingPoint a2 = -0.284496736; + const FloatingPoint a3 = 1.421413741; + const FloatingPoint a4 = -1.453152027; + const FloatingPoint a5 = 1.061405429; + const FloatingPoint p = 0.3275911; -template<> -struct erf + FloatingPoint sign = sign(_x); + FloatingPoint x = abs(_x); + + FloatingPoint t = 1.0 / (1.0 + p*x); + FloatingPoint y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * exp(-x * x); + + return sign * y; +#else + return std::erf(_x); +#endif +} + +template +inline FloatingPoint erfInv(FloatingPoint _x) { - static float __call(float _x) + FloatingPoint x = clamp(_x, -0.99999, 0.99999); +#ifdef __HLSL_VERSION + FloatingPoint w = -log((1.0-x) * (1.0+x)); +#else + FloatingPoint w = -std::log((1.0-x) * (1.0+x)); +#endif + FloatingPoint p; + if (w<5.0) { - const float a1 = 0.254829592; - const float a2 = -0.284496736; - const float a3 = 1.421413741; - const float a4 = -1.453152027; - const float a5 = 1.061405429; - const float p = 0.3275911; - - float sign = sign(_x); - float x = abs(_x); - - float t = 1.0 / (1.0 + p*x); - float y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * exp(-x * x); - - return sign * y; + w -= 2.5; + p = 2.81022636e-08; + p = 3.43273939e-07 + p*w; + p = -3.5233877e-06 + p*w; + p = -4.39150654e-06 + p*w; + p = 0.00021858087 + p*w; + p = -0.00125372503 + p*w; + p = -0.00417768164 + p*w; + p = 0.246640727 + p*w; + p = 1.50140941 + p*w; } -}; + else + { +#ifdef __HLSL_VERSION + w = sqrt(w) - 3.0; +#else + w = std::sqrt(w) - 3.0; +#endif + p = -0.000200214257; + p = 0.000100950558 + p*w; + p = 0.00134934322 + p*w; + p = -0.00367342844 + p*w; + p = 0.00573950773 + p*w; + p = -0.0076224613 + p*w; + p = 0.00943887047 + p*w; + p = 1.00167406 + p*w; + p = 2.83297682 + p*w; + } + return p*x; +} template -struct erfInv; - -template<> -struct erfInv +inline T floor(NBL_CONST_REF_ARG(T) val) { - static float __call(float _x) - { - float x = clamp(_x, -0.99999, 0.99999); - float w = -log((1.0-x) * (1.0+x)); - float p; - if (w<5.0) - { - w -= 2.5; - p = 2.81022636e-08; - p = 3.43273939e-07 + p*w; - p = -3.5233877e-06 + p*w; - p = -4.39150654e-06 + p*w; - p = 0.00021858087 + p*w; - p = -0.00125372503 + p*w; - p = -0.00417768164 + p*w; - p = 0.246640727 + p*w; - p = 1.50140941 + p*w; - } - else - { - w = sqrt(w) - 3.0; - p = -0.000200214257; - p = 0.000100950558 + p*w; - p = 0.00134934322 + p*w; - p = -0.00367342844 + p*w; - p = 0.00573950773 + p*w; - p = -0.0076224613 + p*w; - p = 0.00943887047 + p*w; - p = 1.00167406 + p*w; - p = 2.83297682 + p*w; - } - return p*x; - } -}; +#ifdef __HLSL_VERSION + return spirv::floor(val); +#else + return glm::floor(val); +#endif + } -template -T erf(T _x) +template +inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) { - return impl::erf::__call(_x); + return cpp_compat_intrinsics_impl::lerp_helper::lerp(x, y, a); } -template -T erfInv(T _x) +template +inline FloatingPoint isnan(NBL_CONST_REF_ARG(FloatingPoint) val) { - return impl::erfInv::__call(_x); +#ifdef __HLSL_VERSION + return spirv::isNan(val); +#else + return std::isnan(val); +#endif } +template +inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) +{ +#ifdef __HLSL_VERSION + return spirv::isInf(val); +#else + return std::isinf(val); +#endif +} -template -T rsqrt(T _x) +template +inline T exp2(NBL_CONST_REF_ARG(T) val) { #ifdef __HLSL_VERSION - return rsqrt(_x); + return spirv::exp2(val); #else - return 1.0 / sqrt(_x); + return std::exp2(val); #endif } +#define DEFINE_EXP2_SPECIALIZATION(TYPE)\ +template<>\ +inline TYPE exp2(NBL_CONST_REF_ARG(TYPE) val)\ +{\ + return _static_cast(1ull << val);\ +}\ + +DEFINE_EXP2_SPECIALIZATION(int16_t) +DEFINE_EXP2_SPECIALIZATION(int32_t) +DEFINE_EXP2_SPECIALIZATION(int64_t) +DEFINE_EXP2_SPECIALIZATION(uint16_t) +DEFINE_EXP2_SPECIALIZATION(uint32_t) +DEFINE_EXP2_SPECIALIZATION(uint64_t) + + } } From dda71b8317a2f57a6f0041cb92f743b243c53f29 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 16 Dec 2024 15:45:04 +0700 Subject: [PATCH 04/42] some needed math funcs --- include/nbl/builtin/hlsl/math/functions.hlsl | 50 ++++++++++----- include/nbl/builtin/hlsl/tgmath.hlsl | 66 ++++++++++++++++---- 2 files changed, 88 insertions(+), 28 deletions(-) diff --git a/include/nbl/builtin/hlsl/math/functions.hlsl b/include/nbl/builtin/hlsl/math/functions.hlsl index 87419517b8..8496c214b9 100644 --- a/include/nbl/builtin/hlsl/math/functions.hlsl +++ b/include/nbl/builtin/hlsl/math/functions.hlsl @@ -26,9 +26,9 @@ struct lp_norm { static scalar_type_t __call(const T v) { - scalar_type_t retval = abs(v[0]); + scalar_type_t retval = abs(v[0]); for (int i = 1; i < rank::value; i++) - retval = max(abs(v[i]),retval); + retval = max(abs(v[i]),retval); return retval; } }; @@ -39,9 +39,9 @@ struct lp_norm { static scalar_type_t __sum(const T v) { - scalar_type_t retval = abs(v[0]); + scalar_type_t retval = abs(v[0]); for (int i = 1; i < rank::value; i++) - retval += abs(v[i]); + retval += abs(v[i]); return retval; } @@ -61,7 +61,7 @@ struct lp_norm static scalar_type_t __call(const T v) { - return sqrt(__sum(v)); + return sqrt(__sum(v)); } }; @@ -184,7 +184,7 @@ struct refract T computeNdotT() { T NdotT2 = rcpOrientedEta2 * NdotI2 + 1.0 - rcpOrientedEta2; - T absNdotT = sqrt(NdotT2); + T absNdotT = sqrt(NdotT2); return backside ? absNdotT : -(absNdotT); } @@ -271,23 +271,28 @@ vector reflectRefract(bool _refract, vector I, vector N, T NdotI, template ) void sincos(T theta, out T s, out T c) { - c = cos(theta); - s = sqrt(1.0-c*c); + c = cos(theta); + s = sqrt(1.0-c*c); s = (theta < 0.0) ? -s : s; // TODO: test with XOR } template ) matrix frisvad(vector n) // TODO: confirm dimensions of matrix { - const float a = 1.0 / (1.0 + n.z); - const float b = -n.x * n.y * a; + const T a = 1.0 / (1.0 + n.z); + const T b = -n.x * n.y * a; return (n.z < -0.9999999) ? matrix(vector(0.0,-1.0,0.0), vector(-1.0,0.0,0.0)) : matrix(vector(1.0-n.x*n.x*a, b, -n.x), vector(b, 1.0-n.y*n.y*a, -n.y)); } bool partitionRandVariable(in float leftProb, inout float xi, out float rcpChoiceProb) { +#ifdef __HLSL_VERSION NBL_CONSTEXPR float NEXT_ULP_AFTER_UNITY = asfloat(0x3f800001u); +#else + NBL_CONSTEXPR uint32_t val = 0x3f800001u; + NBL_CONSTEXPR float32_t NEXT_ULP_AFTER_UNITY = reinterpret_cast( val ); +#endif const bool pickRight = xi >= leftProb * NEXT_ULP_AFTER_UNITY; // This is all 100% correct taking into account the above NEXT_ULP_AFTER_UNITY @@ -300,6 +305,8 @@ bool partitionRandVariable(in float leftProb, inout float xi, out float rcpChoic } +// TODO: make it work in C++, ignoring problem for now +#ifdef __HLSL_VERSION // @ return abs(x) if cond==true, max(x,0.0) otherwise template || is_vector_v) T conditionalAbsOrMax(bool cond, T x, T limit); @@ -331,6 +338,7 @@ float4 conditionalAbsOrMax(bool cond, float4 x, float4 limit) const float4 condAbs = asfloat(asuint(x) & select(cond, (uint4)0x7fFFffFFu, (uint4)0xffFFffFFu)); return max(condAbs,limit); } +#endif namespace impl { @@ -417,7 +425,7 @@ struct trigonometry const bool ABltminusC = cosSumAB < (-tmp2); const bool ABltC = cosSumAB < tmp2; // apply triple angle formula - const float absArccosSumABC = acos(clamp(cosSumAB * tmp2 - (tmp0 * tmp4 + tmp3 * tmp1) * tmp5, -1.f, 1.f)); + const float absArccosSumABC = acos(clamp(cosSumAB * tmp2 - (tmp0 * tmp4 + tmp3 * tmp1) * tmp5, -1.f, 1.f)); return ((AltminusB ? ABltC : ABltminusC) ? (-absArccosSumABC) : absArccosSumABC) + (AltminusB | ABltminusC ? numbers::pi : (-numbers::pi)); } @@ -426,8 +434,8 @@ struct trigonometry const float bias = biasA + biasB; const float a = cosA; const float b = cosB; - const bool reverse = abs(min(a, b)) > max(a, b); - const float c = a * b - sqrt((1.0f - a * a) * (1.0f - b * b)); + const bool reverse = abs(min(a, b)) > max(a, b); + const float c = a * b - sqrt((1.0f - a * a) * (1.0f - b * b)); if (reverse) { @@ -469,7 +477,7 @@ float getSumofArccosAB(float cosA, float cosB) { impl::trigonometry trig = impl::trigonometry::create(); impl::trigonometry::combineCosForSumOfAcos(cosA, cosB, 0.0f, 0.0f, trig.tmp0, trig.tmp1); - return acos(trig.tmp0) + trig.tmp1; + return acos(trig.tmp0) + trig.tmp1; } // returns acos(a) + acos(b) + acos(c) + acos(d) @@ -479,7 +487,7 @@ float getSumofArccosABCD(float cosA, float cosB, float cosC, float cosD) impl::trigonometry::combineCosForSumOfAcos(cosA, cosB, 0.0f, 0.0f, trig.tmp0, trig.tmp1); impl::trigonometry::combineCosForSumOfAcos(cosC, cosD, 0.0f, 0.0f, trig.tmp2, trig.tmp3); impl::trigonometry::combineCosForSumOfAcos(trig.tmp0, trig.tmp2, trig.tmp1, trig.tmp3, trig.tmp4, trig.tmp5); - return acos(trig.tmp4) + trig.tmp5; + return acos(trig.tmp4) + trig.tmp5; } namespace impl @@ -489,7 +497,11 @@ struct applyChainRule4D { static matrix __call(matrix dFdG, matrix dGdR) { +#ifdef __HLSL_VERSION return mul(dFdG, dGdR); +#else + return dFdG * dGdR; // glm +#endif } }; @@ -498,7 +510,11 @@ struct applyChainRule3D : applyChainRule4D { static vector __call(matrix dFdG, vector dGdR) { +#ifdef __HLSL_VERSION return mul(dFdG, dGdR); +#else + return dFdG * dGdR; // glm +#endif } }; @@ -507,7 +523,11 @@ struct applyChainRule2D : applyChainRule4D { static vector __call(vector dFdG, T dGdR) { +#ifdef __HLSL_VERSION return mul(dFdG, dGdR); +#else + return dFdG * dGdR; // glm +#endif } }; diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index ae6989ed08..360b470db9 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -7,6 +7,7 @@ #include // C++ headers #ifndef __HLSL_VERSION +#include #include #endif @@ -19,7 +20,7 @@ template inline FloatingPoint erf(FloatingPoint _x) { #ifdef __HLSL_VERSION - const FloatingPoint a1 = 0.254829592; + const FloatingPoint a1 = 0.254829592; const FloatingPoint a2 = -0.284496736; const FloatingPoint a3 = 1.421413741; const FloatingPoint a4 = -1.453152027; @@ -34,7 +35,7 @@ inline FloatingPoint erf(FloatingPoint _x) return sign * y; #else - return std::erf(_x); + return std::erf(_x); #endif } @@ -86,26 +87,26 @@ template inline T floor(NBL_CONST_REF_ARG(T) val) { #ifdef __HLSL_VERSION - return spirv::floor(val); + return spirv::floor(val); #else - return glm::floor(val); + return glm::floor(val); #endif - + } template inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) { - return cpp_compat_intrinsics_impl::lerp_helper::lerp(x, y, a); + return cpp_compat_intrinsics_impl::lerp_helper::lerp(x, y, a); } template inline FloatingPoint isnan(NBL_CONST_REF_ARG(FloatingPoint) val) { #ifdef __HLSL_VERSION - return spirv::isNan(val); + return spirv::isNan(val); #else - return std::isnan(val); + return std::isnan(val); #endif } @@ -113,9 +114,9 @@ template inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) { #ifdef __HLSL_VERSION - return spirv::isInf(val); + return spirv::isInf(val); #else - return std::isinf(val); + return std::isinf(val); #endif } @@ -123,9 +124,9 @@ template inline T exp2(NBL_CONST_REF_ARG(T) val) { #ifdef __HLSL_VERSION - return spirv::exp2(val); + return spirv::exp2(val); #else - return std::exp2(val); + return std::exp2(val); #endif } @@ -133,7 +134,7 @@ inline T exp2(NBL_CONST_REF_ARG(T) val) template<>\ inline TYPE exp2(NBL_CONST_REF_ARG(TYPE) val)\ {\ - return _static_cast(1ull << val);\ + return _static_cast(1ull << val);\ }\ DEFINE_EXP2_SPECIALIZATION(int16_t) @@ -143,6 +144,45 @@ DEFINE_EXP2_SPECIALIZATION(uint16_t) DEFINE_EXP2_SPECIALIZATION(uint32_t) DEFINE_EXP2_SPECIALIZATION(uint64_t) +template +inline T abs(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return abs(val); +#else + return std::abs(val); +#endif +} + +template +inline T sqrt(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return sqrt(val); +#else + return std::sqrt(val); +#endif +} + +template +inline T cos(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return cos(val); +#else + return std::cos(val); +#endif +} + +template +inline T acos(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return acos(val); +#else + return std::acos(val); +#endif +} } } From 0b46b67476174e76fb9f11704a3b6c812fea384c Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 16 Dec 2024 16:21:04 +0700 Subject: [PATCH 05/42] some more math funcs --- .../hlsl/spirv_intrinsics/glsl.std.450.hlsl | 12 ++++++ include/nbl/builtin/hlsl/tgmath.hlsl | 41 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl index 21d0bf2330..56bfe9a3c0 100644 --- a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl +++ b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl @@ -42,10 +42,22 @@ template [[vk::ext_instruction(GLSLstd450::GLSLstd450FindUMsb, "GLSL.std.450")]] vector findUMsb(vector value); +template +[[vk::ext_instruction(GLSLstd450::GLSLstd450Pow, "GLSL.std.450")]] +enable_if_t::value && !is_matrix_v, FloatingPoint> pow(FloatingPoint lhs, FloatingPoint rhs); + +template +[[vk::ext_instruction(GLSLstd450::GLSLstd450Exp, "GLSL.std.450")]] +enable_if_t::value && !is_matrix_v, FloatingPoint> exp(FloatingPoint val); + template [[vk::ext_instruction(GLSLstd450::GLSLstd450Exp2, "GLSL.std.450")]] enable_if_t::value && !is_matrix_v, FloatingPoint> exp2(FloatingPoint val); +template +[[vk::ext_instruction(GLSLstd450::GLSLstd450Log, "GLSL.std.450")]] +enable_if_t::value && !is_matrix_v, FloatingPoint> log(FloatingPoint val); + template [[vk::ext_instruction(GLSLstd450::GLSLstd450InverseSqrt, "GLSL.std.450")]] enable_if_t && !is_matrix_v, FloatingPoint> inverseSqrt(FloatingPoint val); diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index 360b470db9..770c3c07fb 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -4,6 +4,7 @@ #ifndef _NBL_BUILTIN_HLSL_TGMATH_INCLUDED_ #define _NBL_BUILTIN_HLSL_TGMATH_INCLUDED_ +#include #include // C++ headers #ifndef __HLSL_VERSION @@ -120,6 +121,26 @@ inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) #endif } +template +inline T pow(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y) +{ +#ifdef __HLSL_VERSION + return spirv::pow(x, y); +#else + return std::pow(x, y); +#endif +} + +template +inline T exp(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return spirv::exp(val); +#else + return std::exp(val); +#endif +} + template inline T exp2(NBL_CONST_REF_ARG(T) val) { @@ -144,6 +165,16 @@ DEFINE_EXP2_SPECIALIZATION(uint16_t) DEFINE_EXP2_SPECIALIZATION(uint32_t) DEFINE_EXP2_SPECIALIZATION(uint64_t) +template +inline T log(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return spirv::log(val); +#else + return std::log(val); +#endif +} + template inline T abs(NBL_CONST_REF_ARG(T) val) { @@ -164,6 +195,16 @@ inline T sqrt(NBL_CONST_REF_ARG(T) val) #endif } +template +inline T sin(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return sin(val); +#else + return std::sin(val); +#endif +} + template inline T cos(NBL_CONST_REF_ARG(T) val) { From a5d48dec715b981c2ab29ccc63b20deedc701774 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 17 Dec 2024 15:38:55 +0700 Subject: [PATCH 06/42] fixed cpp compat types --- include/nbl/builtin/hlsl/math/functions.hlsl | 58 ++++++++++---------- src/nbl/video/utilities/CComputeBlit.cpp | 1 + 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/include/nbl/builtin/hlsl/math/functions.hlsl b/include/nbl/builtin/hlsl/math/functions.hlsl index 8496c214b9..0c5d9fd613 100644 --- a/include/nbl/builtin/hlsl/math/functions.hlsl +++ b/include/nbl/builtin/hlsl/math/functions.hlsl @@ -103,7 +103,7 @@ struct orientedEtas; template<> struct orientedEtas { - static bool __call(out float orientedEta, out float rcpOrientedEta, float NdotI, float eta) + static bool __call(NBL_REF_ARG(float) orientedEta, NBL_REF_ARG(float) rcpOrientedEta, float NdotI, float eta) { const bool backside = NdotI < 0.0; const float rcpEta = 1.0 / eta; @@ -114,12 +114,12 @@ struct orientedEtas }; template<> -struct orientedEtas +struct orientedEtas { - static bool __call(out float3 orientedEta, out float3 rcpOrientedEta, float NdotI, float3 eta) + static bool __call(NBL_REF_ARG(float32_t3) orientedEta, NBL_REF_ARG(float32_t3) rcpOrientedEta, float NdotI, float32_t3 eta) { const bool backside = NdotI < 0.0; - const float3 rcpEta = (float3)1.0 / eta; + const float32_t3 rcpEta = (float32_t3)1.0 / eta; orientedEta = backside ? rcpEta:eta; rcpOrientedEta = backside ? eta:rcpEta; return backside; @@ -128,7 +128,7 @@ struct orientedEtas } template || is_vector_v) -bool getOrientedEtas(out T orientedEta, out T rcpOrientedEta, scalar_type_t NdotI, T eta) +bool getOrientedEtas(NBL_REF_ARG(T) orientedEta, NBL_REF_ARG(T) rcpOrientedEta, scalar_type_t NdotI, T eta) { return impl::orientedEtas::__call(orientedEta, rcpOrientedEta, NdotI, eta); } @@ -269,7 +269,7 @@ vector reflectRefract(bool _refract, vector I, vector N, T NdotI, // valid only for `theta` in [-PI,PI] template ) -void sincos(T theta, out T s, out T c) +void sincos(T theta, NBL_REF_ARG(T) s, NBL_REF_ARG(T) c) { c = cos(theta); s = sqrt(1.0-c*c); @@ -285,7 +285,7 @@ matrix frisvad(vector n) // TODO: confirm dimensions of matrix matrix(vector(1.0-n.x*n.x*a, b, -n.x), vector(b, 1.0-n.y*n.y*a, -n.y)); } -bool partitionRandVariable(in float leftProb, inout float xi, out float rcpChoiceProb) +bool partitionRandVariable(float leftProb, NBL_REF_ARG(float) xi, NBL_REF_ARG(float) rcpChoiceProb) { #ifdef __HLSL_VERSION NBL_CONSTEXPR float NEXT_ULP_AFTER_UNITY = asfloat(0x3f800001u); @@ -314,28 +314,28 @@ T conditionalAbsOrMax(bool cond, T x, T limit); template <> float conditionalAbsOrMax(bool cond, float x, float limit) { - const float condAbs = asfloat(asuint(x) & uint(cond ? 0x7fFFffFFu:0xffFFffFFu)); + const float condAbs = asfloat(asuint(x) & uint(cond ? 0x7fFFffFFu : 0xffFFffFFu)); return max(condAbs,limit); } template <> -float2 conditionalAbsOrMax(bool cond, float2 x, float2 limit) +float32_t2 conditionalAbsOrMax(bool cond, float32_t2 x, float32_t2 limit) { - const float2 condAbs = asfloat(asuint(x) & select(cond, (uint2)0x7fFFffFFu, (uint2)0xffFFffFFu)); + const float32_t2 condAbs = asfloat(asuint(x) & select(cond, (uint32_t2)0x7fFFffFFu, (uint32_t2)0xffFFffFFu)); return max(condAbs,limit); } template <> -float3 conditionalAbsOrMax(bool cond, float3 x, float3 limit) +float32_t3 conditionalAbsOrMax(bool cond, float32_t3 x, float32_t3 limit) { - const float3 condAbs = asfloat(asuint(x) & select(cond, (uint3)0x7fFFffFFu, (uint3)0xffFFffFFu)); + const float32_t3 condAbs = asfloat(asuint(x) & select(cond, (uint32_t3)0x7fFFffFFu, (uint32_t3)0xffFFffFFu)); return max(condAbs,limit); } template <> -float4 conditionalAbsOrMax(bool cond, float4 x, float4 limit) +float32_t4 conditionalAbsOrMax(bool cond, float32_t4 x, float32_t4 limit) { - const float4 condAbs = asfloat(asuint(x) & select(cond, (uint4)0x7fFFffFFu, (uint4)0xffFFffFFu)); + const float32_t4 condAbs = asfloat(asuint(x) & select(cond, (uint32_t4)0x7fFFffFFu, (uint32_t4)0xffFFffFFu)); return max(condAbs,limit); } #endif @@ -346,7 +346,7 @@ struct bitFields // need template? { using this_t = bitFields; - static this_t create(uint base, uint value, uint offset, uint count) + static this_t create(uint32_t base, uint32_t value, uint32_t offset, uint32_t count) { this_t retval; retval.base = base; @@ -356,33 +356,33 @@ struct bitFields // need template? return retval; } - uint __insert() + uint32_t __insert() { - const uint shifted_masked_value = (value & ((0x1u << count) - 1u)) << offset; - const uint lo = base & ((0x1u << offset) - 1u); - const uint hi = base ^ lo; + const uint32_t shifted_masked_value = (value & ((0x1u << count) - 1u)) << offset; + const uint32_t lo = base & ((0x1u << offset) - 1u); + const uint32_t hi = base ^ lo; return (hi << count) | shifted_masked_value | lo; } - uint __overwrite() + uint32_t __overwrite() { - return spirv::bitFieldInsert(base, value, offset, count); + return spirv::bitFieldInsert(base, value, offset, count); } - uint base; - uint value; - uint offset; - uint count; + uint32_t base; + uint32_t value; + uint32_t offset; + uint32_t count; }; } -uint bitFieldOverwrite(uint base, uint value, uint offset, uint count) +uint32_t bitFieldOverwrite(uint32_t base, uint32_t value, uint32_t offset, uint32_t count) { impl::bitFields b = impl::bitFields::create(base, value, offset, count); return b.__overwrite(); } -uint bitFieldInsert(uint base, uint value, uint offset, uint count) +uint32_t bitFieldInsert(uint32_t base, uint32_t value, uint32_t offset, uint32_t count) { impl::bitFields b = impl::bitFields::create(base, value, offset, count); return b.__insert(); @@ -429,7 +429,7 @@ struct trigonometry return ((AltminusB ? ABltC : ABltminusC) ? (-absArccosSumABC) : absArccosSumABC) + (AltminusB | ABltminusC ? numbers::pi : (-numbers::pi)); } - static void combineCosForSumOfAcos(float cosA, float cosB, float biasA, float biasB, out float out0, out float out1) + static void combineCosForSumOfAcos(float cosA, float cosB, float biasA, float biasB, NBL_REF_ARG(float) out0, NBL_REF_ARG(float) out1) { const float bias = biasA + biasB; const float a = cosA; @@ -464,7 +464,7 @@ float getArccosSumofABC_minus_PI(float cosA, float cosB, float cosC, float sinA, return trig.getArccosSumofABC_minus_PI(); } -void combineCosForSumOfAcos(float cosA, float cosB, float biasA, float biasB, out float out0, out float out1) +void combineCosForSumOfAcos(float cosA, float cosB, float biasA, float biasB, NBL_REF_ARG(float) out0, NBL_REF_ARG(float) out1) { impl::trigonometry trig = impl::trigonometry::create(); impl::trigonometry::combineCosForSumOfAcos(cosA, cosB, biasA, biasB, trig.tmp0, trig.tmp1); diff --git a/src/nbl/video/utilities/CComputeBlit.cpp b/src/nbl/video/utilities/CComputeBlit.cpp index 3d6c85cd74..cb8cb3e45b 100644 --- a/src/nbl/video/utilities/CComputeBlit.cpp +++ b/src/nbl/video/utilities/CComputeBlit.cpp @@ -1,5 +1,6 @@ #include "nbl/video/utilities/CComputeBlit.h" #include "nbl/builtin/hlsl/binding_info.hlsl" +#include "nbl/builtin/hlsl/tgmath.hlsl" using namespace nbl::core; using namespace nbl::hlsl; From 0064f57ff6e322263ebc88bfccaedad04d6b695c Mon Sep 17 00:00:00 2001 From: Przemek Date: Wed, 18 Dec 2024 12:32:17 +0100 Subject: [PATCH 07/42] Added ieee754.hlsl and improved intrinsics.hlsl --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 32 +++- .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 47 ++++-- .../nbl/builtin/hlsl/glsl_compat/core.hlsl | 3 +- include/nbl/builtin/hlsl/ieee754.hlsl | 137 ++++++++++++++++++ include/nbl/builtin/hlsl/ieee754/impl.hlsl | 43 ++++++ .../hlsl/spirv_intrinsics/glsl.std.450.hlsl | 4 +- include/nbl/builtin/hlsl/type_traits.hlsl | 27 ++++ 7 files changed, 277 insertions(+), 16 deletions(-) create mode 100644 include/nbl/builtin/hlsl/ieee754.hlsl create mode 100644 include/nbl/builtin/hlsl/ieee754/impl.hlsl diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 236544076b..fa39c09801 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -2,7 +2,10 @@ #define _NBL_BUILTIN_HLSL_CPP_COMPAT_IMPL_INTRINSICS_IMPL_INCLUDED_ #include +#include #include +#include +#include namespace nbl { @@ -20,7 +23,7 @@ struct dot_helper static array_get getter; scalar_type retval = getter(lhs, 0) * getter(rhs, 0); - static const uint32_t ArrayDim = sizeof(T) / sizeof(scalar_type); + static const uint32_t ArrayDim = vector_traits::Dimension; for (uint32_t i = 1; i < ArrayDim; ++i) retval = retval + getter(lhs, i) * getter(rhs, i); @@ -362,6 +365,33 @@ struct lerp_helper, vector > } }; +template +struct transpose_helper; + +template +struct transpose_helper > +{ + using transposed_t = typename matrix_traits >::transposed_type; + + static transposed_t transpose(NBL_CONST_REF_ARG(matrix) m) + { +#ifdef __HLSL_VERSION + return spirv::transpose(m); +#else + return reinterpret_cast(glm::transpose(reinterpret_cast::Base const&>(m))); +#endif + } +}; + +template +struct mul_helper +{ + static inline RhsT multiply(LhsT lhs, RhsT rhs) + { + return mul(lhs, rhs); + } +}; + } } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index 87e3f6712c..5af3310156 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -5,9 +5,9 @@ #include #include #include -#include -#include #include +#include +#include #ifndef __HLSL_VERSION #include @@ -121,14 +121,17 @@ inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG( } // transpose not defined cause its implemented via hidden friend -template -inline matrix transpose(NBL_CONST_REF_ARG(matrix) m) +template +inline typename matrix_traits::transposed_type transpose(NBL_CONST_REF_ARG(Matrix) m) { -#ifdef __HLSL_VERSION - return spirv::transpose(m); -#else - return reinterpret_cast&>(glm::transpose(reinterpret_cast::Base const&>(m))); -#endif + return cpp_compat_intrinsics_impl::transpose_helper::transpose(m); +} + +// TODO: concepts, to ensure that MatT is a matrix and VecT is a vector type +template +VecT mul(MatT mat, VecT vec) +{ + return cpp_compat_intrinsics_impl::mul_helper::multiply(mat, vec); } template @@ -151,8 +154,8 @@ inline T max(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b) #endif } -template -inline FloatingPoint isnan(NBL_CONST_REF_ARG(FloatingPoint) val) +template) +inline bool isnan(NBL_CONST_REF_ARG(FloatingPoint) val) { #ifdef __HLSL_VERSION return spirv::isNan(val); @@ -161,7 +164,17 @@ inline FloatingPoint isnan(NBL_CONST_REF_ARG(FloatingPoint) val) #endif } -template +template ) +inline bool isnan(Integer val) +{ + using AsUint = typename unsigned_integer_of_size::type; + using AsFloat = typename float_of_size::type; + + AsUint asUint = bit_cast(val); + return bool((ieee754::extractBiasedExponent(val) == ieee754::traits::specialValueExp) && (asUint & ieee754::traits::mantissaMask)); +} + +template) inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) { #ifdef __HLSL_VERSION @@ -171,6 +184,16 @@ inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) #endif } +template) +inline bool isinf(Integer val) +{ + using AsUint = typename unsigned_integer_of_size::type; + using AsFloat = typename float_of_size::type; + + AsUint tmp = bit_cast(val); + return (tmp & (~ieee754::traits::signMask)) == ieee754::traits::inf; +} + template inline T exp2(NBL_CONST_REF_ARG(T) val) { diff --git a/include/nbl/builtin/hlsl/glsl_compat/core.hlsl b/include/nbl/builtin/hlsl/glsl_compat/core.hlsl index 081e80e1a7..ecc4ef65f4 100644 --- a/include/nbl/builtin/hlsl/glsl_compat/core.hlsl +++ b/include/nbl/builtin/hlsl/glsl_compat/core.hlsl @@ -4,9 +4,10 @@ #ifndef _NBL_BUILTIN_HLSL_GLSL_COMPAT_CORE_INCLUDED_ #define _NBL_BUILTIN_HLSL_GLSL_COMPAT_CORE_INCLUDED_ -#include "nbl/builtin/hlsl/cpp_compat.hlsl" +#include "nbl/builtin/hlsl/cpp_compat/basic.h" #include "nbl/builtin/hlsl/spirv_intrinsics/core.hlsl" #include "nbl/builtin/hlsl/type_traits.hlsl" +#include "nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl" namespace nbl { diff --git a/include/nbl/builtin/hlsl/ieee754.hlsl b/include/nbl/builtin/hlsl/ieee754.hlsl new file mode 100644 index 0000000000..cbbc0b8abd --- /dev/null +++ b/include/nbl/builtin/hlsl/ieee754.hlsl @@ -0,0 +1,137 @@ +#ifndef _NBL_BUILTIN_HLSL_IEE754_HLSL_INCLUDED_ +#define _NBL_BUILTIN_HLSL_IEE754_HLSL_INCLUDED_ + +#include + +namespace nbl +{ +namespace hlsl +{ +namespace ieee754 +{ + +template +struct traits_base +{ + static_assert(is_same::value || is_same::value || is_same::value); + NBL_CONSTEXPR_STATIC_INLINE int16_t exponentBitCnt = int16_t(0xbeef); + NBL_CONSTEXPR_STATIC_INLINE int16_t mantissaBitCnt = int16_t(0xbeef); +}; + +template<> +struct traits_base +{ + NBL_CONSTEXPR_STATIC_INLINE int16_t exponentBitCnt = 5; + NBL_CONSTEXPR_STATIC_INLINE int16_t mantissaBitCnt = 10; +}; + +template<> +struct traits_base +{ + NBL_CONSTEXPR_STATIC_INLINE int16_t exponentBitCnt = 8; + NBL_CONSTEXPR_STATIC_INLINE int16_t mantissaBitCnt = 23; +}; + +template<> +struct traits_base +{ + NBL_CONSTEXPR_STATIC_INLINE int16_t exponentBitCnt = 11; + NBL_CONSTEXPR_STATIC_INLINE int16_t mantissaBitCnt = 52; +}; + +template +struct traits : traits_base +{ + //static_assert(is_same_v || is_same_v || is_same_v); + + using bit_rep_t = typename unsigned_integer_of_size::type; + using base_t = traits_base; + + NBL_CONSTEXPR_STATIC_INLINE bit_rep_t signMask = bit_rep_t(0x1ull) << (sizeof(Float) * 8 - 1); + NBL_CONSTEXPR_STATIC_INLINE bit_rep_t exponentMask = ((~bit_rep_t(0)) << base_t::mantissaBitCnt) ^ signMask; + NBL_CONSTEXPR_STATIC_INLINE bit_rep_t mantissaMask = (bit_rep_t(0x1u) << base_t::mantissaBitCnt) - 1; + NBL_CONSTEXPR_STATIC_INLINE int exponentBias = (int(0x1) << (base_t::exponentBitCnt - 1)) - 1; + NBL_CONSTEXPR_STATIC_INLINE bit_rep_t inf = exponentMask; + NBL_CONSTEXPR_STATIC_INLINE bit_rep_t specialValueExp = (1ull << base_t::exponentBitCnt) - 1; + NBL_CONSTEXPR_STATIC_INLINE bit_rep_t quietNaN = exponentMask | (1ull << (base_t::mantissaBitCnt - 1)); + NBL_CONSTEXPR_STATIC_INLINE bit_rep_t max = ((1ull << (sizeof(Float) * 8 - 1)) - 1) & (~(1ull << base_t::mantissaBitCnt)); + NBL_CONSTEXPR_STATIC_INLINE bit_rep_t min = 1ull << base_t::mantissaBitCnt; + NBL_CONSTEXPR_STATIC_INLINE int exponentMax = exponentBias; + NBL_CONSTEXPR_STATIC_INLINE int exponentMin = -(exponentBias - 1); +}; + +template +inline uint32_t extractBiasedExponent(T x) +{ + using AsUint = typename unsigned_integer_of_size::type; + return glsl::bitfieldExtract(ieee754::impl::bitCastToUintType(x), traits::type>::mantissaBitCnt, traits::type>::exponentBitCnt); +} + +template<> +inline uint32_t extractBiasedExponent(uint64_t x) +{ + uint64_t output = (x >> traits::mantissaBitCnt) & (traits::exponentMask >> traits::mantissaBitCnt); + return uint32_t(output); +} + +template<> +inline uint32_t extractBiasedExponent(float64_t x) +{ + return extractBiasedExponent(ieee754::impl::bitCastToUintType(x)); +} + +template +inline int extractExponent(T x) +{ + using AsFloat = typename float_of_size::type; + return int(extractBiasedExponent(x)) - traits::exponentBias; +} + +template +NBL_CONSTEXPR_INLINE_FUNC T replaceBiasedExponent(T x, typename unsigned_integer_of_size::type biasedExp) +{ + using AsFloat = typename float_of_size::type; + return impl::castBackToFloatType(glsl::bitfieldInsert(ieee754::impl::bitCastToUintType(x), biasedExp, traits::mantissaBitCnt, traits::exponentBitCnt)); +} + +// performs no overflow tests, returns x*exp2(n) +template +NBL_CONSTEXPR_INLINE_FUNC T fastMulExp2(T x, int n) +{ + return replaceBiasedExponent(x, extractBiasedExponent(x) + uint32_t(n)); +} + +template +NBL_CONSTEXPR_INLINE_FUNC typename unsigned_integer_of_size::type extractMantissa(T x) +{ + using AsUint = typename unsigned_integer_of_size::type; + return ieee754::impl::bitCastToUintType(x) & traits::type>::mantissaMask; +} + +template +NBL_CONSTEXPR_INLINE_FUNC typename unsigned_integer_of_size::type extractNormalizeMantissa(T x) +{ + using AsUint = typename unsigned_integer_of_size::type; + using AsFloat = typename float_of_size::type; + return extractMantissa(x) | (AsUint(1) << traits::mantissaBitCnt); +} + +template +NBL_CONSTEXPR_INLINE_FUNC typename unsigned_integer_of_size::type extractSign(T x) +{ + using AsFloat = typename float_of_size::type; + return (ieee754::impl::bitCastToUintType(x) & traits::signMask) >> ((sizeof(T) * 8) - 1); +} + +template +NBL_CONSTEXPR_INLINE_FUNC typename unsigned_integer_of_size::type extractSignPreserveBitPattern(T x) +{ + using AsFloat = typename float_of_size::type; + return ieee754::impl::bitCastToUintType(x) & traits::signMask; +} + +} +} +} + +#endif \ No newline at end of file diff --git a/include/nbl/builtin/hlsl/ieee754/impl.hlsl b/include/nbl/builtin/hlsl/ieee754/impl.hlsl new file mode 100644 index 0000000000..ad8a3f9228 --- /dev/null +++ b/include/nbl/builtin/hlsl/ieee754/impl.hlsl @@ -0,0 +1,43 @@ +#ifndef _NBL_BUILTIN_HLSL_IEE754_IMPL_HLSL_INCLUDED_ +#define _NBL_BUILTIN_HLSL_IEE754_IMPL_HLSL_INCLUDED_ + +#include +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace ieee754 +{ + +namespace impl +{ +template +NBL_CONSTEXPR_INLINE_FUNC unsigned_integer_of_size_t bitCastToUintType(T x) +{ + using AsUint = unsigned_integer_of_size_t; + return bit_cast(x); +} +// to avoid bit cast from uintN_t to uintN_t +template <> NBL_CONSTEXPR_INLINE_FUNC unsigned_integer_of_size_t<2> bitCastToUintType(uint16_t x) { return x; } +template <> NBL_CONSTEXPR_INLINE_FUNC unsigned_integer_of_size_t<4> bitCastToUintType(uint32_t x) { return x; } +template <> NBL_CONSTEXPR_INLINE_FUNC unsigned_integer_of_size_t<8> bitCastToUintType(uint64_t x) { return x; } + +template +NBL_CONSTEXPR_INLINE_FUNC T castBackToFloatType(T x) +{ + using AsFloat = typename float_of_size::type; + return bit_cast(x); +} +template<> NBL_CONSTEXPR_INLINE_FUNC uint16_t castBackToFloatType(uint16_t x) { return x; } +template<> NBL_CONSTEXPR_INLINE_FUNC uint32_t castBackToFloatType(uint32_t x) { return x; } +template<> NBL_CONSTEXPR_INLINE_FUNC uint64_t castBackToFloatType(uint64_t x) { return x; } +} + +} +} +} + +#endif \ No newline at end of file diff --git a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl index 21d0bf2330..ce3180f2b7 100644 --- a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl +++ b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl @@ -2,11 +2,11 @@ #define _NBL_BUILTIN_HLSL_SPIRV_INTRINSICS_GLSL_STD_450_INCLUDED_ #ifdef __HLSL_VERSION -#include +#include #include #include "spirv/unified1/GLSL.std.450.h" -namespace nbl +namespace nbl { namespace hlsl { diff --git a/include/nbl/builtin/hlsl/type_traits.hlsl b/include/nbl/builtin/hlsl/type_traits.hlsl index 31587cd028..4ae7cb6b9a 100644 --- a/include/nbl/builtin/hlsl/type_traits.hlsl +++ b/include/nbl/builtin/hlsl/type_traits.hlsl @@ -736,6 +736,33 @@ struct unsigned_integer_of_size<8> template using unsigned_integer_of_size_t = typename unsigned_integer_of_size::type; +template +struct float_of_size +{ + using type = void; +}; + +template<> +struct float_of_size<2> +{ + using type = float16_t; +}; + +template<> +struct float_of_size<4> +{ + using type = float32_t; +}; + +template<> +struct float_of_size<8> +{ + using type = float64_t; +}; + +template +using float_of_size_t = typename float_of_size::type; + } } From 28427b58dbde9895495eb79f70c28aa2a84b9bb6 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 19 Dec 2024 09:46:36 +0700 Subject: [PATCH 08/42] some cpp compat fixes --- examples_tests | 2 +- include/nbl/builtin/hlsl/math/functions.hlsl | 11 +++++++++-- include/nbl/builtin/hlsl/tgmath.hlsl | 14 +++++++------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/examples_tests b/examples_tests index 73ac5c8aaa..cf806b0561 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 73ac5c8aaabb4a33c46599de51ad2a5d5fff77cc +Subproject commit cf806b05617f73fdc9c5390dcb3b984683d72ba9 diff --git a/include/nbl/builtin/hlsl/math/functions.hlsl b/include/nbl/builtin/hlsl/math/functions.hlsl index 0c5d9fd613..b36cfcdfd3 100644 --- a/include/nbl/builtin/hlsl/math/functions.hlsl +++ b/include/nbl/builtin/hlsl/math/functions.hlsl @@ -290,8 +290,8 @@ bool partitionRandVariable(float leftProb, NBL_REF_ARG(float) xi, NBL_REF_ARG(fl #ifdef __HLSL_VERSION NBL_CONSTEXPR float NEXT_ULP_AFTER_UNITY = asfloat(0x3f800001u); #else - NBL_CONSTEXPR uint32_t val = 0x3f800001u; - NBL_CONSTEXPR float32_t NEXT_ULP_AFTER_UNITY = reinterpret_cast( val ); + uint32_t val = 0x3f800001u; + float32_t NEXT_ULP_AFTER_UNITY = reinterpret_cast( val ); #endif const bool pickRight = xi >= leftProb * NEXT_ULP_AFTER_UNITY; @@ -366,7 +366,14 @@ struct bitFields // need template? uint32_t __overwrite() { +#ifdef __HLSL_VERSION return spirv::bitFieldInsert(base, value, offset, count); +#else + // TODO: double check implementation + const uint32_t shifted_masked_value = ~(0xffffffffu << count) << offset; + base &= ~shifted_masked_value; + return base | (value << offset); +#endif } uint32_t base; diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index 770c3c07fb..e5706b2a9d 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -88,7 +88,7 @@ template inline T floor(NBL_CONST_REF_ARG(T) val) { #ifdef __HLSL_VERSION - return spirv::floor(val); + return spirv::floor(val); #else return glm::floor(val); #endif @@ -105,7 +105,7 @@ template inline FloatingPoint isnan(NBL_CONST_REF_ARG(FloatingPoint) val) { #ifdef __HLSL_VERSION - return spirv::isNan(val); + return spirv::isNan(val); #else return std::isnan(val); #endif @@ -115,7 +115,7 @@ template inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) { #ifdef __HLSL_VERSION - return spirv::isInf(val); + return spirv::isInf(val); #else return std::isinf(val); #endif @@ -125,7 +125,7 @@ template inline T pow(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y) { #ifdef __HLSL_VERSION - return spirv::pow(x, y); + return spirv::pow(x, y); #else return std::pow(x, y); #endif @@ -135,7 +135,7 @@ template inline T exp(NBL_CONST_REF_ARG(T) val) { #ifdef __HLSL_VERSION - return spirv::exp(val); + return spirv::exp(val); #else return std::exp(val); #endif @@ -145,7 +145,7 @@ template inline T exp2(NBL_CONST_REF_ARG(T) val) { #ifdef __HLSL_VERSION - return spirv::exp2(val); + return spirv::exp2(val); #else return std::exp2(val); #endif @@ -169,7 +169,7 @@ template inline T log(NBL_CONST_REF_ARG(T) val) { #ifdef __HLSL_VERSION - return spirv::log(val); + return spirv::log(val); #else return std::log(val); #endif From 86cabe485b0d10cd1070802cebda6c91ae07741f Mon Sep 17 00:00:00 2001 From: Przemek Date: Thu, 19 Dec 2024 19:47:05 +0100 Subject: [PATCH 09/42] Improved mul function --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 3 +- .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 26 ++------------- .../hlsl/matrix_utils/mul_output_t.hlsl | 33 +++++++++++++++++++ src/nbl/builtin/CMakeLists.txt | 2 ++ 4 files changed, 40 insertions(+), 24 deletions(-) create mode 100644 include/nbl/builtin/hlsl/matrix_utils/mul_output_t.hlsl diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index fa39c09801..adba8c0042 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -386,7 +387,7 @@ struct transpose_helper > template struct mul_helper { - static inline RhsT multiply(LhsT lhs, RhsT rhs) + static inline mul_output_t multiply(LhsT lhs, RhsT rhs) { return mul(lhs, rhs); } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index 5af3310156..acb9f41e63 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -128,10 +128,10 @@ inline typename matrix_traits::transposed_type transpose(NBL_CONST_REF_A } // TODO: concepts, to ensure that MatT is a matrix and VecT is a vector type -template -VecT mul(MatT mat, VecT vec) +template +mul_output_t mul(LhsT mat, RhsT vec) { - return cpp_compat_intrinsics_impl::mul_helper::multiply(mat, vec); + return cpp_compat_intrinsics_impl::mul_helper::multiply(mat, vec); } template @@ -164,16 +164,6 @@ inline bool isnan(NBL_CONST_REF_ARG(FloatingPoint) val) #endif } -template ) -inline bool isnan(Integer val) -{ - using AsUint = typename unsigned_integer_of_size::type; - using AsFloat = typename float_of_size::type; - - AsUint asUint = bit_cast(val); - return bool((ieee754::extractBiasedExponent(val) == ieee754::traits::specialValueExp) && (asUint & ieee754::traits::mantissaMask)); -} - template) inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) { @@ -184,16 +174,6 @@ inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) #endif } -template) -inline bool isinf(Integer val) -{ - using AsUint = typename unsigned_integer_of_size::type; - using AsFloat = typename float_of_size::type; - - AsUint tmp = bit_cast(val); - return (tmp & (~ieee754::traits::signMask)) == ieee754::traits::inf; -} - template inline T exp2(NBL_CONST_REF_ARG(T) val) { diff --git a/include/nbl/builtin/hlsl/matrix_utils/mul_output_t.hlsl b/include/nbl/builtin/hlsl/matrix_utils/mul_output_t.hlsl new file mode 100644 index 0000000000..1ca0ceb966 --- /dev/null +++ b/include/nbl/builtin/hlsl/matrix_utils/mul_output_t.hlsl @@ -0,0 +1,33 @@ +#ifndef _NBL_BUILTIN_HLSL_MATRIX_UTILS_MUL_OUTPUT_T_INCLUDED_ +#define _NBL_BUILTIN_HLSL_MATRIX_UTILS_MUL_OUTPUT_T_INCLUDED_ + +#include + +namespace nbl +{ +namespace hlsl +{ + +template +struct mul_output; + +template +struct mul_output, vector > +{ + using type = vector; +}; + +template +struct mul_output, matrix > +{ + using type = matrix; +}; + +//! type of matrix-matrix or matrix-vector multiplication +template +using mul_output_t = typename mul_output::type; + +} +} + +#endif \ No newline at end of file diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index 9ed799827a..9805bee063 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -214,6 +214,8 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/macros.h") # utility LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/array_accessors.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/vector_utils/vector_traits.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/matrix_utils.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/mul_output_t.hlsl") #spirv intrinsics LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/spirv_intrinsics/core.hlsl") From 0770eb9c33623bd0f2fe595499b6ebf6bb63487c Mon Sep 17 00:00:00 2001 From: Przemek Date: Thu, 19 Dec 2024 21:23:29 +0100 Subject: [PATCH 10/42] isinf and isnan workaround --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 15 +++++++++++++++ .../nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl | 11 ++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index adba8c0042..0e2aebb31d 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -7,6 +7,7 @@ #include #include #include +#include namespace nbl { @@ -393,6 +394,20 @@ struct mul_helper } }; +template&& hlsl::is_unsigned_v) +inline bool isnan_uint_impl(UnsignedInteger val) +{ + using AsFloat = typename float_of_size::type; + return bool((ieee754::extractBiasedExponent(val) == ieee754::traits::specialValueExp) && (val & ieee754::traits::mantissaMask)); +} + +template&& hlsl::is_unsigned_v) +inline bool isinf_uint_impl(UnsignedInteger val) +{ + using AsFloat = typename float_of_size::type; + return (val & (~ieee754::traits::signMask)) == ieee754::traits::inf; +} + } } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index acb9f41e63..721e81829e 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -7,7 +7,6 @@ #include #include #include -#include #ifndef __HLSL_VERSION #include @@ -160,7 +159,10 @@ inline bool isnan(NBL_CONST_REF_ARG(FloatingPoint) val) #ifdef __HLSL_VERSION return spirv::isNan(val); #else - return std::isnan(val); + // GCC and Clang will always return false with call to std::isnan when fast math is enabled, + // this implementation will always return appropriate output regardless is fas math is enabled or not + using AsUint = typename unsigned_integer_of_size::type; + return cpp_compat_intrinsics_impl::isnan_uint_impl(reinterpret_cast(val)); #endif } @@ -170,7 +172,10 @@ inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) #ifdef __HLSL_VERSION return spirv::isInf(val); #else - return std::isinf(val); + // GCC and Clang will always return false with call to std::isinf when fast math is enabled, + // this implementation will always return appropriate output regardless is fas math is enabled or not + using AsUint = typename unsigned_integer_of_size::type; + return cpp_compat_intrinsics_impl::isinf_uint_impl(reinterpret_cast(val)); #endif } From a517d220f945fb304b9ae6fa8c3ffe5556451577 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 20 Dec 2024 10:50:37 +0700 Subject: [PATCH 11/42] review changes --- include/nbl/builtin/hlsl/math/functions.hlsl | 134 +------------------ 1 file changed, 4 insertions(+), 130 deletions(-) diff --git a/include/nbl/builtin/hlsl/math/functions.hlsl b/include/nbl/builtin/hlsl/math/functions.hlsl index b36cfcdfd3..30bd11cecd 100644 --- a/include/nbl/builtin/hlsl/math/functions.hlsl +++ b/include/nbl/builtin/hlsl/math/functions.hlsl @@ -290,8 +290,7 @@ bool partitionRandVariable(float leftProb, NBL_REF_ARG(float) xi, NBL_REF_ARG(fl #ifdef __HLSL_VERSION NBL_CONSTEXPR float NEXT_ULP_AFTER_UNITY = asfloat(0x3f800001u); #else - uint32_t val = 0x3f800001u; - float32_t NEXT_ULP_AFTER_UNITY = reinterpret_cast( val ); + NBL_CONSTEXPR float32_t NEXT_ULP_AFTER_UNITY = bit_cast(0x3f800001u); #endif const bool pickRight = xi >= leftProb * NEXT_ULP_AFTER_UNITY; @@ -340,61 +339,6 @@ float32_t4 conditionalAbsOrMax(bool cond, float32_t4 x, float32_t4 l } #endif -namespace impl -{ -struct bitFields // need template? -{ - using this_t = bitFields; - - static this_t create(uint32_t base, uint32_t value, uint32_t offset, uint32_t count) - { - this_t retval; - retval.base = base; - retval.value = value; - retval.offset = offset; - retval.count = count; - return retval; - } - - uint32_t __insert() - { - const uint32_t shifted_masked_value = (value & ((0x1u << count) - 1u)) << offset; - const uint32_t lo = base & ((0x1u << offset) - 1u); - const uint32_t hi = base ^ lo; - return (hi << count) | shifted_masked_value | lo; - } - - uint32_t __overwrite() - { -#ifdef __HLSL_VERSION - return spirv::bitFieldInsert(base, value, offset, count); -#else - // TODO: double check implementation - const uint32_t shifted_masked_value = ~(0xffffffffu << count) << offset; - base &= ~shifted_masked_value; - return base | (value << offset); -#endif - } - - uint32_t base; - uint32_t value; - uint32_t offset; - uint32_t count; -}; -} - -uint32_t bitFieldOverwrite(uint32_t base, uint32_t value, uint32_t offset, uint32_t count) -{ - impl::bitFields b = impl::bitFields::create(base, value, offset, count); - return b.__overwrite(); -} - -uint32_t bitFieldInsert(uint32_t base, uint32_t value, uint32_t offset, uint32_t count) -{ - impl::bitFields b = impl::bitFields::create(base, value, offset, count); - return b.__insert(); -} - namespace impl { struct trigonometry @@ -497,80 +441,10 @@ float getSumofArccosABCD(float cosA, float cosB, float cosC, float cosD) return acos(trig.tmp4) + trig.tmp5; } -namespace impl -{ -template -struct applyChainRule4D -{ - static matrix __call(matrix dFdG, matrix dGdR) - { -#ifdef __HLSL_VERSION - return mul(dFdG, dGdR); -#else - return dFdG * dGdR; // glm -#endif - } -}; - -template -struct applyChainRule3D : applyChainRule4D -{ - static vector __call(matrix dFdG, vector dGdR) - { -#ifdef __HLSL_VERSION - return mul(dFdG, dGdR); -#else - return dFdG * dGdR; // glm -#endif - } -}; - -template -struct applyChainRule2D : applyChainRule4D -{ - static vector __call(vector dFdG, T dGdR) - { -#ifdef __HLSL_VERSION - return mul(dFdG, dGdR); -#else - return dFdG * dGdR; // glm -#endif - } -}; - -template -struct applyChainRule1D : applyChainRule4D -{ - static T __call(T dFdG, T dGdR) - { - return dFdG * dGdR; - } -}; -} - -// possible to derive M,N,P automatically? -template && M>1 && N>1 && P>1) -matrix applyChainRule(matrix dFdG, matrix dGdR) -{ - return impl::applyChainRule4D::__call(dFdG, dGdR); -} - -template && M>1 && N>1) -vector applyChainRule(matrix dFdG, vector dGdR) -{ - return impl::applyChainRule3D::__call(dFdG, dGdR); -} - -template && M>1) -vector applyChainRule(vector dFdG, T dGdR) -{ - return impl::applyChainRule2D::__call(dFdG, dGdR); -} - -template) -T applyChainRule(T dFdG, T dGdR) +template) +matrix applyChainRule(matrix dFdG, matrix dGdR) { - return impl::applyChainRule1D::__call(dFdG, dGdR); + return mul(dFdG,dGdR); } } From 911d8fca46da35214ee5eeaeab0c645e4cb4b5bf Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 20 Dec 2024 11:41:14 +0700 Subject: [PATCH 12/42] use templated glm methods --- include/nbl/builtin/hlsl/tgmath.hlsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index e5706b2a9d..de688d1148 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -90,7 +90,7 @@ inline T floor(NBL_CONST_REF_ARG(T) val) #ifdef __HLSL_VERSION return spirv::floor(val); #else - return glm::floor(val); + return glm::floor(val); #endif } @@ -181,7 +181,7 @@ inline T abs(NBL_CONST_REF_ARG(T) val) #ifdef __HLSL_VERSION return abs(val); #else - return std::abs(val); + return glm::abs(val); #endif } From 14e1010c4d384b2ba7571b263c850cd9c4d5b12f Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 20 Dec 2024 15:03:32 +0700 Subject: [PATCH 13/42] reverted changes, use glm --- examples_tests | 2 +- include/nbl/builtin/hlsl/tgmath.hlsl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples_tests b/examples_tests index cf806b0561..9212b655e1 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit cf806b05617f73fdc9c5390dcb3b984683d72ba9 +Subproject commit 9212b655e1bae175913f6b59b8af07b6bb307783 diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index de688d1148..6ed53ee7c5 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -90,7 +90,7 @@ inline T floor(NBL_CONST_REF_ARG(T) val) #ifdef __HLSL_VERSION return spirv::floor(val); #else - return glm::floor(val); + return glm::floor(val); #endif } @@ -181,7 +181,7 @@ inline T abs(NBL_CONST_REF_ARG(T) val) #ifdef __HLSL_VERSION return abs(val); #else - return glm::abs(val); + return glm::abs(val); #endif } From fb7b643850effb8d4aa97261dfb7db441dd13687 Mon Sep 17 00:00:00 2001 From: Przemek Date: Fri, 20 Dec 2024 11:41:57 +0100 Subject: [PATCH 14/42] Updated examples --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 73ac5c8aaa..cf806b0561 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 73ac5c8aaabb4a33c46599de51ad2a5d5fff77cc +Subproject commit cf806b05617f73fdc9c5390dcb3b984683d72ba9 From 845707c033d3a906f654a18e0f7f8783f46a0163 Mon Sep 17 00:00:00 2001 From: Przemek Date: Fri, 20 Dec 2024 11:49:55 +0100 Subject: [PATCH 15/42] Added tgmath.hlsl --- include/nbl/builtin/hlsl/tgmath.hlsl | 231 +++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 include/nbl/builtin/hlsl/tgmath.hlsl diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl new file mode 100644 index 0000000000..6ed53ee7c5 --- /dev/null +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -0,0 +1,231 @@ +// Copyright (C) 2022 - DevSH Graphics Programming Sp. z O.O. +// This file is part of the "Nabla Engine". +// For conditions of distribution and use, see copyright notice in nabla.h +#ifndef _NBL_BUILTIN_HLSL_TGMATH_INCLUDED_ +#define _NBL_BUILTIN_HLSL_TGMATH_INCLUDED_ + +#include +#include +// C++ headers +#ifndef __HLSL_VERSION +#include +#include +#endif + +namespace nbl +{ +namespace hlsl +{ + +template +inline FloatingPoint erf(FloatingPoint _x) +{ +#ifdef __HLSL_VERSION + const FloatingPoint a1 = 0.254829592; + const FloatingPoint a2 = -0.284496736; + const FloatingPoint a3 = 1.421413741; + const FloatingPoint a4 = -1.453152027; + const FloatingPoint a5 = 1.061405429; + const FloatingPoint p = 0.3275911; + + FloatingPoint sign = sign(_x); + FloatingPoint x = abs(_x); + + FloatingPoint t = 1.0 / (1.0 + p*x); + FloatingPoint y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * exp(-x * x); + + return sign * y; +#else + return std::erf(_x); +#endif +} + +template +inline FloatingPoint erfInv(FloatingPoint _x) +{ + FloatingPoint x = clamp(_x, -0.99999, 0.99999); +#ifdef __HLSL_VERSION + FloatingPoint w = -log((1.0-x) * (1.0+x)); +#else + FloatingPoint w = -std::log((1.0-x) * (1.0+x)); +#endif + FloatingPoint p; + if (w<5.0) + { + w -= 2.5; + p = 2.81022636e-08; + p = 3.43273939e-07 + p*w; + p = -3.5233877e-06 + p*w; + p = -4.39150654e-06 + p*w; + p = 0.00021858087 + p*w; + p = -0.00125372503 + p*w; + p = -0.00417768164 + p*w; + p = 0.246640727 + p*w; + p = 1.50140941 + p*w; + } + else + { +#ifdef __HLSL_VERSION + w = sqrt(w) - 3.0; +#else + w = std::sqrt(w) - 3.0; +#endif + p = -0.000200214257; + p = 0.000100950558 + p*w; + p = 0.00134934322 + p*w; + p = -0.00367342844 + p*w; + p = 0.00573950773 + p*w; + p = -0.0076224613 + p*w; + p = 0.00943887047 + p*w; + p = 1.00167406 + p*w; + p = 2.83297682 + p*w; + } + return p*x; +} + + +template +inline T floor(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return spirv::floor(val); +#else + return glm::floor(val); +#endif + +} + +template +inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) +{ + return cpp_compat_intrinsics_impl::lerp_helper::lerp(x, y, a); +} + +template +inline FloatingPoint isnan(NBL_CONST_REF_ARG(FloatingPoint) val) +{ +#ifdef __HLSL_VERSION + return spirv::isNan(val); +#else + return std::isnan(val); +#endif +} + +template +inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) +{ +#ifdef __HLSL_VERSION + return spirv::isInf(val); +#else + return std::isinf(val); +#endif +} + +template +inline T pow(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y) +{ +#ifdef __HLSL_VERSION + return spirv::pow(x, y); +#else + return std::pow(x, y); +#endif +} + +template +inline T exp(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return spirv::exp(val); +#else + return std::exp(val); +#endif +} + +template +inline T exp2(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return spirv::exp2(val); +#else + return std::exp2(val); +#endif +} + +#define DEFINE_EXP2_SPECIALIZATION(TYPE)\ +template<>\ +inline TYPE exp2(NBL_CONST_REF_ARG(TYPE) val)\ +{\ + return _static_cast(1ull << val);\ +}\ + +DEFINE_EXP2_SPECIALIZATION(int16_t) +DEFINE_EXP2_SPECIALIZATION(int32_t) +DEFINE_EXP2_SPECIALIZATION(int64_t) +DEFINE_EXP2_SPECIALIZATION(uint16_t) +DEFINE_EXP2_SPECIALIZATION(uint32_t) +DEFINE_EXP2_SPECIALIZATION(uint64_t) + +template +inline T log(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return spirv::log(val); +#else + return std::log(val); +#endif +} + +template +inline T abs(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return abs(val); +#else + return glm::abs(val); +#endif +} + +template +inline T sqrt(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return sqrt(val); +#else + return std::sqrt(val); +#endif +} + +template +inline T sin(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return sin(val); +#else + return std::sin(val); +#endif +} + +template +inline T cos(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return cos(val); +#else + return std::cos(val); +#endif +} + +template +inline T acos(NBL_CONST_REF_ARG(T) val) +{ +#ifdef __HLSL_VERSION + return acos(val); +#else + return std::acos(val); +#endif +} + +} +} + +#endif From 3f1db308c0bc8631c65a48341820fe24d972022d Mon Sep 17 00:00:00 2001 From: Przemek Date: Fri, 20 Dec 2024 14:28:00 +0100 Subject: [PATCH 16/42] Moved some functions to tgmath.hlsl --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 83 -------------- .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 68 ------------ .../nbl/builtin/hlsl/impl/tgmath_impl.hlsl | 104 ++++++++++++++++++ .../builtin/hlsl/math/equations/quartic.hlsl | 3 +- .../builtin/hlsl/spirv_intrinsics/core.hlsl | 2 +- include/nbl/builtin/hlsl/tgmath.hlsl | 51 ++++----- src/nbl/builtin/CMakeLists.txt | 2 + src/nbl/video/utilities/CComputeBlit.cpp | 1 + 8 files changed, 134 insertions(+), 180 deletions(-) create mode 100644 include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 0e2aebb31d..7fb9da1847 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -298,75 +298,6 @@ struct find_msb_return_type > template using find_lsb_return_type = find_msb_return_type; -template -struct lerp_helper; - -#ifdef __HLSL_VERSION -#define MIX_FUNCTION spirv::fMix -#else -#define MIX_FUNCTION glm::mix -#endif - -#define DEFINE_LERP_HELPER_COMMON_SPECIALIZATION(TYPE)\ -template<>\ -struct lerp_helper\ -{\ - static inline TYPE lerp(NBL_CONST_REF_ARG(TYPE) x, NBL_CONST_REF_ARG(TYPE) y, NBL_CONST_REF_ARG(TYPE) a)\ - {\ - return MIX_FUNCTION(x, y, a);\ - }\ -};\ -\ -template\ -struct lerp_helper, vector >\ -{\ - static inline vector lerp(NBL_CONST_REF_ARG(vector) x, NBL_CONST_REF_ARG(vector) y, NBL_CONST_REF_ARG(vector) a)\ - {\ - return MIX_FUNCTION(x, y, a);\ - }\ -};\ -\ -template\ -struct lerp_helper, TYPE>\ -{\ - static inline vector lerp(NBL_CONST_REF_ARG(vector) x, NBL_CONST_REF_ARG(vector) y, NBL_CONST_REF_ARG(TYPE) a)\ - {\ - return MIX_FUNCTION(x, y, a);\ - }\ -};\ - -DEFINE_LERP_HELPER_COMMON_SPECIALIZATION(float32_t) -DEFINE_LERP_HELPER_COMMON_SPECIALIZATION(float64_t) - -#undef DEFINE_LERP_HELPER_COMMON_SPECIALIZATION -#undef MIX_FUNCTION - -template -struct lerp_helper -{ - static inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(bool) a) - { - if (a) - return y; - else - return x; - } -}; - -template -struct lerp_helper, vector > -{ - using output_vec_t = vector; - - static inline output_vec_t lerp(NBL_CONST_REF_ARG(output_vec_t) x, NBL_CONST_REF_ARG(output_vec_t) y, NBL_CONST_REF_ARG(vector) a) - { - output_vec_t retval; - for (uint32_t i = 0; i < vector_traits::Dimension; i++) - retval[i] = a[i] ? y[i] : x[i]; - return retval; - } -}; - template struct transpose_helper; @@ -394,20 +325,6 @@ struct mul_helper } }; -template&& hlsl::is_unsigned_v) -inline bool isnan_uint_impl(UnsignedInteger val) -{ - using AsFloat = typename float_of_size::type; - return bool((ieee754::extractBiasedExponent(val) == ieee754::traits::specialValueExp) && (val & ieee754::traits::mantissaMask)); -} - -template&& hlsl::is_unsigned_v) -inline bool isinf_uint_impl(UnsignedInteger val) -{ - using AsFloat = typename float_of_size::type; - return (val & (~ieee754::traits::signMask)) == ieee754::traits::inf; -} - } } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index 721e81829e..57dc974946 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -89,18 +89,6 @@ inline typename cpp_compat_intrinsics_impl::find_msb_return_type::type return cpp_compat_intrinsics_impl::find_msb_helper::findMSB(val); } -// TODO: some of the functions in this header should move to `tgmath` -template -inline T floor(NBL_CONST_REF_ARG(T) val) -{ -#ifdef __HLSL_VERSION - return spirv::floor(val); -#else - return glm::floor(val); -#endif - -} - // TODO: for clearer error messages, use concepts to ensure that input type is a square matrix // inverse not defined cause its implemented via hidden friend template @@ -113,12 +101,6 @@ inline matrix inverse(NBL_CONST_REF_ARG(matrix) m) #endif } -template -inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) -{ - return cpp_compat_intrinsics_impl::lerp_helper::lerp(x, y, a); -} - // transpose not defined cause its implemented via hidden friend template inline typename matrix_traits::transposed_type transpose(NBL_CONST_REF_ARG(Matrix) m) @@ -153,56 +135,6 @@ inline T max(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b) #endif } -template) -inline bool isnan(NBL_CONST_REF_ARG(FloatingPoint) val) -{ -#ifdef __HLSL_VERSION - return spirv::isNan(val); -#else - // GCC and Clang will always return false with call to std::isnan when fast math is enabled, - // this implementation will always return appropriate output regardless is fas math is enabled or not - using AsUint = typename unsigned_integer_of_size::type; - return cpp_compat_intrinsics_impl::isnan_uint_impl(reinterpret_cast(val)); -#endif -} - -template) -inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) -{ -#ifdef __HLSL_VERSION - return spirv::isInf(val); -#else - // GCC and Clang will always return false with call to std::isinf when fast math is enabled, - // this implementation will always return appropriate output regardless is fas math is enabled or not - using AsUint = typename unsigned_integer_of_size::type; - return cpp_compat_intrinsics_impl::isinf_uint_impl(reinterpret_cast(val)); -#endif -} - -template -inline T exp2(NBL_CONST_REF_ARG(T) val) -{ -#ifdef __HLSL_VERSION - return spirv::exp2(val); -#else - return std::exp2(val); -#endif -} - -#define DEFINE_EXP2_SPECIALIZATION(TYPE)\ -template<>\ -inline TYPE exp2(NBL_CONST_REF_ARG(TYPE) val)\ -{\ - return _static_cast(1ull << val);\ -}\ - -DEFINE_EXP2_SPECIALIZATION(int16_t) -DEFINE_EXP2_SPECIALIZATION(int32_t) -DEFINE_EXP2_SPECIALIZATION(int64_t) -DEFINE_EXP2_SPECIALIZATION(uint16_t) -DEFINE_EXP2_SPECIALIZATION(uint32_t) -DEFINE_EXP2_SPECIALIZATION(uint64_t) - template inline FloatingPoint rsqrt(FloatingPoint x) { diff --git a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl new file mode 100644 index 0000000000..8ddcaf1d1a --- /dev/null +++ b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl @@ -0,0 +1,104 @@ +#ifndef _NBL_BUILTIN_HLSL_TGMATH_IMPL_INCLUDED_ +#define _NBL_BUILTIN_HLSL_TGMATH_IMPL_INCLUDED_ + +#include +#include +#include +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace tgmath_impl +{ + +template +struct lerp_helper; + +#ifdef __HLSL_VERSION +#define MIX_FUNCTION spirv::fMix +#else +#define MIX_FUNCTION glm::mix +#endif + +#define DEFINE_LERP_HELPER_COMMON_SPECIALIZATION(TYPE)\ +template<>\ +struct lerp_helper\ +{\ + static inline TYPE lerp(NBL_CONST_REF_ARG(TYPE) x, NBL_CONST_REF_ARG(TYPE) y, NBL_CONST_REF_ARG(TYPE) a)\ + {\ + return MIX_FUNCTION(x, y, a);\ + }\ +};\ +\ +template\ +struct lerp_helper, vector >\ +{\ + static inline vector lerp(NBL_CONST_REF_ARG(vector) x, NBL_CONST_REF_ARG(vector) y, NBL_CONST_REF_ARG(vector) a)\ + {\ + return MIX_FUNCTION(x, y, a);\ + }\ +};\ +\ +template\ +struct lerp_helper, TYPE>\ +{\ + static inline vector lerp(NBL_CONST_REF_ARG(vector) x, NBL_CONST_REF_ARG(vector) y, NBL_CONST_REF_ARG(TYPE) a)\ + {\ + return MIX_FUNCTION(x, y, a);\ + }\ +};\ + +DEFINE_LERP_HELPER_COMMON_SPECIALIZATION(float32_t) +DEFINE_LERP_HELPER_COMMON_SPECIALIZATION(float64_t) + +#undef DEFINE_LERP_HELPER_COMMON_SPECIALIZATION +#undef MIX_FUNCTION + +template +struct lerp_helper +{ + static inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(bool) a) + { + if (a) + return y; + else + return x; + } +}; + +template +struct lerp_helper, vector > +{ + using output_vec_t = vector; + + static inline output_vec_t lerp(NBL_CONST_REF_ARG(output_vec_t) x, NBL_CONST_REF_ARG(output_vec_t) y, NBL_CONST_REF_ARG(vector) a) + { + output_vec_t retval; + for (uint32_t i = 0; i < vector_traits::Dimension; i++) + retval[i] = a[i] ? y[i] : x[i]; + return retval; + } +}; + +template&& hlsl::is_unsigned_v) +inline bool isnan_uint_impl(UnsignedInteger val) +{ + using AsFloat = typename float_of_size::type; + return bool((ieee754::extractBiasedExponent(val) == ieee754::traits::specialValueExp) && (val & ieee754::traits::mantissaMask)); +} + +template&& hlsl::is_unsigned_v) +inline bool isinf_uint_impl(UnsignedInteger val) +{ + using AsFloat = typename float_of_size::type; + return (val & (~ieee754::traits::signMask)) == ieee754::traits::inf; +} + +} +} +} + +#endif \ No newline at end of file diff --git a/include/nbl/builtin/hlsl/math/equations/quartic.hlsl b/include/nbl/builtin/hlsl/math/equations/quartic.hlsl index b94de0afb5..f1b7acc162 100644 --- a/include/nbl/builtin/hlsl/math/equations/quartic.hlsl +++ b/include/nbl/builtin/hlsl/math/equations/quartic.hlsl @@ -7,6 +7,7 @@ #include #include +#include // TODO: Later include from correct hlsl header #ifndef nbl_hlsl_FLT_EPSILON @@ -88,7 +89,7 @@ namespace equations float_t3 cubic = Cubic::construct(1, -1.0 / 2 * p, -r, 1.0 / 2 * r * p - 1.0 / 8 * q * q).computeRoots(); /* ... and take the one real solution ... */ for (uint32_t i = 0; i < 3; i ++) - if (!isnan(cubic[i])) + if (!hlsl::isnan(cubic[i])) { z = cubic[i]; break; diff --git a/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl b/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl index 83208753d4..d96da12daa 100644 --- a/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl +++ b/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl @@ -244,7 +244,7 @@ enable_if_t, bool> isInf(FloatingPoint val); template [[vk::ext_instruction( spv::OpTranspose )]] -Matrix transpose(NBL_CONST_REF_ARG(Matrix) mat); +Matrix transpose(Matrix mat); } diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index 6ed53ee7c5..01a50d904b 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -5,7 +5,7 @@ #define _NBL_BUILTIN_HLSL_TGMATH_INCLUDED_ #include -#include +#include // C++ headers #ifndef __HLSL_VERSION #include @@ -83,7 +83,6 @@ inline FloatingPoint erfInv(FloatingPoint _x) return p*x; } - template inline T floor(NBL_CONST_REF_ARG(T) val) { @@ -98,26 +97,32 @@ inline T floor(NBL_CONST_REF_ARG(T) val) template inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) { - return cpp_compat_intrinsics_impl::lerp_helper::lerp(x, y, a); + return tgmath_impl::lerp_helper::lerp(x, y, a); } -template -inline FloatingPoint isnan(NBL_CONST_REF_ARG(FloatingPoint) val) +template) + inline bool isnan(NBL_CONST_REF_ARG(FloatingPoint) val) { #ifdef __HLSL_VERSION - return spirv::isNan(val); + return spirv::isNan(val); #else - return std::isnan(val); + // GCC and Clang will always return false with call to std::isnan when fast math is enabled, + // this implementation will always return appropriate output regardless is fas math is enabled or not + using AsUint = typename unsigned_integer_of_size::type; + return tgmath_impl::isnan_uint_impl(reinterpret_cast(val)); #endif } -template -inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) +template) + inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) { #ifdef __HLSL_VERSION - return spirv::isInf(val); + return spirv::isInf(val); #else - return std::isinf(val); + // GCC and Clang will always return false with call to std::isinf when fast math is enabled, + // this implementation will always return appropriate output regardless is fas math is enabled or not + using AsUint = typename unsigned_integer_of_size::type; + return tgmath_impl::isinf_uint_impl(reinterpret_cast(val)); #endif } @@ -141,29 +146,21 @@ inline T exp(NBL_CONST_REF_ARG(T) val) #endif } -template -inline T exp2(NBL_CONST_REF_ARG(T) val) +template) +inline FloatingPoint exp2(NBL_CONST_REF_ARG(FloatingPoint) val) { #ifdef __HLSL_VERSION - return spirv::exp2(val); + return spirv::exp2(val); #else return std::exp2(val); #endif } -#define DEFINE_EXP2_SPECIALIZATION(TYPE)\ -template<>\ -inline TYPE exp2(NBL_CONST_REF_ARG(TYPE) val)\ -{\ - return _static_cast(1ull << val);\ -}\ - -DEFINE_EXP2_SPECIALIZATION(int16_t) -DEFINE_EXP2_SPECIALIZATION(int32_t) -DEFINE_EXP2_SPECIALIZATION(int64_t) -DEFINE_EXP2_SPECIALIZATION(uint16_t) -DEFINE_EXP2_SPECIALIZATION(uint32_t) -DEFINE_EXP2_SPECIALIZATION(uint64_t) +template) +inline Integral exp2(NBL_CONST_REF_ARG(Integral) val) +{ + return _static_cast(1ull << val); +} template inline T log(NBL_CONST_REF_ARG(T) val) diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index 9805bee063..6c75267135 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -216,6 +216,8 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/array_accessors.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/vector_utils/vector_traits.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/matrix_utils.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/mul_output_t.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/tgmath.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/impl/tgmath_impl.hlsl") #spirv intrinsics LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/spirv_intrinsics/core.hlsl") diff --git a/src/nbl/video/utilities/CComputeBlit.cpp b/src/nbl/video/utilities/CComputeBlit.cpp index 3d6c85cd74..cb8cb3e45b 100644 --- a/src/nbl/video/utilities/CComputeBlit.cpp +++ b/src/nbl/video/utilities/CComputeBlit.cpp @@ -1,5 +1,6 @@ #include "nbl/video/utilities/CComputeBlit.h" #include "nbl/builtin/hlsl/binding_info.hlsl" +#include "nbl/builtin/hlsl/tgmath.hlsl" using namespace nbl::core; using namespace nbl::hlsl; From 7e1edae6c6898f0d5a36af0334801f5961787d2a Mon Sep 17 00:00:00 2001 From: Przemek Date: Fri, 20 Dec 2024 17:06:17 +0100 Subject: [PATCH 17/42] Updated examples --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 9212b655e1..32f959d5f9 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 9212b655e1bae175913f6b59b8af07b6bb307783 +Subproject commit 32f959d5f98d63e402dbbf2f65366078b67c77cc From 5fd393452e9a4d382605c9c9448c992a2d3f5f33 Mon Sep 17 00:00:00 2001 From: Przemek Date: Fri, 20 Dec 2024 17:32:05 +0100 Subject: [PATCH 18/42] Added constraints to the `floor` function --- include/nbl/builtin/hlsl/tgmath.hlsl | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index b0ea74d225..6331cfee82 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -6,6 +6,8 @@ #include #include +#include +#include // C++ headers #ifndef __HLSL_VERSION #include @@ -83,17 +85,31 @@ inline FloatingPoint erfInv(FloatingPoint _x) return p*x; } -template -inline T floor(NBL_CONST_REF_ARG(T) val) +template && hlsl::is_scalar_v) +inline Scalar floor(NBL_CONST_REF_ARG(Scalar) val) { #ifdef __HLSL_VERSION - return spirv::floor(val); + return spirv::floor(val); #else - return glm::floor(val); + return std::floor(val); #endif - } +template&& hlsl::is_vector_v) +inline Vector floor(NBL_CONST_REF_ARG(Vector) vec) +{ +#ifdef __HLSL_VERSION + return spirv::floor(vec); +#else + Vector output; + for (int32_t i = 0; i < hlsl::vector_traits::Dimension; ++i) + output[i] = std::floor(vec[i]); + + return output; +#endif +} + + template inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) { From 2f38f2a8d2fde50fbdb49732c2f05368f2ed68d4 Mon Sep 17 00:00:00 2001 From: Przemek Date: Fri, 20 Dec 2024 17:54:59 +0100 Subject: [PATCH 19/42] Refactor --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 52 +++++++++---------- .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 10 ++-- .../nbl/builtin/hlsl/impl/tgmath_impl.hlsl | 10 ++-- include/nbl/builtin/hlsl/tgmath.hlsl | 2 +- include/nbl/core/util/bitflag.h | 8 +-- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 7fb9da1847..7dc6c27845 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -20,7 +20,7 @@ struct dot_helper { using scalar_type = typename vector_traits::scalar_type; - static inline scalar_type dot_product(NBL_CONST_REF_ARG(T) lhs, NBL_CONST_REF_ARG(T) rhs) + static inline scalar_type __call(NBL_CONST_REF_ARG(T) lhs, NBL_CONST_REF_ARG(T) rhs) { static array_get getter; scalar_type retval = getter(lhs, 0) * getter(rhs, 0); @@ -40,7 +40,7 @@ struct dot_helper >\ using VectorType = vector;\ using ScalarType = typename vector_traits::scalar_type;\ \ - static inline ScalarType dot_product(NBL_CONST_REF_ARG(VectorType) lhs, NBL_CONST_REF_ARG(VectorType) rhs)\ + static inline ScalarType __call(NBL_CONST_REF_ARG(VectorType) lhs, NBL_CONST_REF_ARG(VectorType) rhs)\ {\ return RETURN_VALUE;\ }\ @@ -65,7 +65,7 @@ struct find_msb_helper; template<> struct find_msb_helper { - static int32_t findMSB(NBL_CONST_REF_ARG(uint32_t) val) + static int32_t __call(NBL_CONST_REF_ARG(uint32_t) val) { #ifdef __HLSL_VERSION return spirv::findUMsb(val); @@ -78,7 +78,7 @@ struct find_msb_helper template<> struct find_msb_helper { - static int32_t findMSB(NBL_CONST_REF_ARG(int32_t) val) + static int32_t __call(NBL_CONST_REF_ARG(int32_t) val) { #ifdef __HLSL_VERSION return spirv::findSMsb(val); @@ -92,9 +92,9 @@ struct find_msb_helper template<>\ struct find_msb_helper\ {\ - static int32_t findMSB(NBL_CONST_REF_ARG(INPUT_INTEGER_TYPE) val)\ + static int32_t __call(NBL_CONST_REF_ARG(INPUT_INTEGER_TYPE) val)\ {\ - return find_msb_helper::findMSB(val);\ + return find_msb_helper::__call(val);\ }\ };\ @@ -108,16 +108,16 @@ DEFINE_FIND_MSB_COMMON_SPECIALIZATION(uint8_t, uint32_t) template<> struct find_msb_helper { - static int32_t findMSB(NBL_CONST_REF_ARG(uint64_t) val) + static int32_t __call(NBL_CONST_REF_ARG(uint64_t) val) { #ifdef __HLSL_VERSION const uint32_t highBits = uint32_t(val >> 32); - const int32_t highMsb = find_msb_helper::findMSB(highBits); + const int32_t highMsb = find_msb_helper::__call(highBits); if (highMsb == -1) { const uint32_t lowBits = uint32_t(val); - const int32_t lowMsb = find_msb_helper::findMSB(lowBits); + const int32_t lowMsb = find_msb_helper::__call(lowBits); if (lowMsb == -1) return -1; @@ -134,7 +134,7 @@ struct find_msb_helper template struct find_msb_helper > { - static vector findMSB(NBL_CONST_REF_ARG(vector) val) + static vector __call(NBL_CONST_REF_ARG(vector) val) { #ifdef __HLSL_VERSION return spirv::findUMsb(val); @@ -147,7 +147,7 @@ struct find_msb_helper > template struct find_msb_helper > { - static vector findMSB(NBL_CONST_REF_ARG(vector) val) + static vector __call(NBL_CONST_REF_ARG(vector) val) { #ifdef __HLSL_VERSION return spirv::findSMsb(val); @@ -163,10 +163,10 @@ template requires std::is_enum_v struct find_msb_helper { - static int32_t findMSB(NBL_CONST_REF_ARG(EnumType) val) + static int32_t __call(NBL_CONST_REF_ARG(EnumType) val) { using underlying_t = std::underlying_type_t; - return find_msb_helper::findMSB(static_cast(val)); + return find_msb_helper::__call(static_cast(val)); } }; @@ -178,7 +178,7 @@ struct find_lsb_helper; template<> struct find_lsb_helper { - static int32_t findLSB(NBL_CONST_REF_ARG(int32_t) val) + static int32_t __call(NBL_CONST_REF_ARG(int32_t) val) { #ifdef __HLSL_VERSION return spirv::findILsb(val); @@ -191,7 +191,7 @@ struct find_lsb_helper template<> struct find_lsb_helper { - static int32_t findLSB(NBL_CONST_REF_ARG(uint32_t) val) + static int32_t __call(NBL_CONST_REF_ARG(uint32_t) val) { #ifdef __HLSL_VERSION return spirv::findILsb(val); @@ -205,9 +205,9 @@ struct find_lsb_helper template<>\ struct find_lsb_helper\ {\ - static int32_t findLSB(NBL_CONST_REF_ARG(INPUT_INTEGER_TYPE) val)\ + static int32_t __call(NBL_CONST_REF_ARG(INPUT_INTEGER_TYPE) val)\ {\ - return find_lsb_helper::findLSB(val);\ + return find_lsb_helper::__call(val);\ }\ };\ @@ -221,16 +221,16 @@ DEFINE_FIND_LSB_COMMON_SPECIALIZATION(uint8_t, uint32_t) template<> struct find_lsb_helper { - static int32_t findLSB(NBL_CONST_REF_ARG(uint64_t) val) + static int32_t __call(NBL_CONST_REF_ARG(uint64_t) val) { #ifdef __HLSL_VERSION const uint32_t lowBits = uint32_t(val); - const int32_t lowLsb = find_lsb_helper::findLSB(lowBits); + const int32_t lowLsb = find_lsb_helper::__call(lowBits); if (lowLsb == -1) { const uint32_t highBits = uint32_t(val >> 32); - const int32_t highLsb = find_lsb_helper::findLSB(highBits); + const int32_t highLsb = find_lsb_helper::__call(highBits); if (highLsb == -1) return -1; else @@ -247,7 +247,7 @@ struct find_lsb_helper template struct find_lsb_helper > { - static vector findLSB(NBL_CONST_REF_ARG(vector) val) + static vector __call(NBL_CONST_REF_ARG(vector) val) { #ifdef __HLSL_VERSION return spirv::findILsb(val); @@ -260,7 +260,7 @@ struct find_lsb_helper > template struct find_lsb_helper > { - static vector findLSB(NBL_CONST_REF_ARG(vector) val) + static vector __call(NBL_CONST_REF_ARG(vector) val) { #ifdef __HLSL_VERSION return spirv::findILsb(val); @@ -276,10 +276,10 @@ template requires std::is_enum_v struct find_lsb_helper { - static int32_t findLSB(NBL_CONST_REF_ARG(EnumType) val) + static int32_t __call(NBL_CONST_REF_ARG(EnumType) val) { using underlying_t = std::underlying_type_t; - return find_lsb_helper::findLSB(static_cast(val)); + return find_lsb_helper::__call(static_cast(val)); } }; @@ -306,7 +306,7 @@ struct transpose_helper > { using transposed_t = typename matrix_traits >::transposed_type; - static transposed_t transpose(NBL_CONST_REF_ARG(matrix) m) + static transposed_t __call(NBL_CONST_REF_ARG(matrix) m) { #ifdef __HLSL_VERSION return spirv::transpose(m); @@ -319,7 +319,7 @@ struct transpose_helper > template struct mul_helper { - static inline mul_output_t multiply(LhsT lhs, RhsT rhs) + static inline mul_output_t __call(LhsT lhs, RhsT rhs) { return mul(lhs, rhs); } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index 57dc974946..16801ecd7d 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -61,7 +61,7 @@ T clamp(NBL_CONST_REF_ARG(T) val, NBL_CONST_REF_ARG(T) min, NBL_CONST_REF_ARG(T) template typename vector_traits::scalar_type dot(NBL_CONST_REF_ARG(T) lhs, NBL_CONST_REF_ARG(T) rhs) { - return cpp_compat_intrinsics_impl::dot_helper::dot_product(lhs, rhs); + return cpp_compat_intrinsics_impl::dot_helper::__call(lhs, rhs); } // TODO: for clearer error messages, use concepts to ensure that input type is a square matrix @@ -80,13 +80,13 @@ inline T determinant(NBL_CONST_REF_ARG(matrix) m) template inline typename cpp_compat_intrinsics_impl::find_lsb_return_type::type findLSB(NBL_CONST_REF_ARG(Integer) val) { - return cpp_compat_intrinsics_impl::find_lsb_helper::findLSB(val); + return cpp_compat_intrinsics_impl::find_lsb_helper::__call(val); } template inline typename cpp_compat_intrinsics_impl::find_msb_return_type::type findMSB(NBL_CONST_REF_ARG(Integer) val) { - return cpp_compat_intrinsics_impl::find_msb_helper::findMSB(val); + return cpp_compat_intrinsics_impl::find_msb_helper::__call(val); } // TODO: for clearer error messages, use concepts to ensure that input type is a square matrix @@ -105,14 +105,14 @@ inline matrix inverse(NBL_CONST_REF_ARG(matrix) m) template inline typename matrix_traits::transposed_type transpose(NBL_CONST_REF_ARG(Matrix) m) { - return cpp_compat_intrinsics_impl::transpose_helper::transpose(m); + return cpp_compat_intrinsics_impl::transpose_helper::__call(m); } // TODO: concepts, to ensure that MatT is a matrix and VecT is a vector type template mul_output_t mul(LhsT mat, RhsT vec) { - return cpp_compat_intrinsics_impl::mul_helper::multiply(mat, vec); + return cpp_compat_intrinsics_impl::mul_helper::__call(mat, vec); } template diff --git a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl index 8ddcaf1d1a..8e337c7d13 100644 --- a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl +++ b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl @@ -27,7 +27,7 @@ struct lerp_helper; template<>\ struct lerp_helper\ {\ - static inline TYPE lerp(NBL_CONST_REF_ARG(TYPE) x, NBL_CONST_REF_ARG(TYPE) y, NBL_CONST_REF_ARG(TYPE) a)\ + static inline TYPE __call(NBL_CONST_REF_ARG(TYPE) x, NBL_CONST_REF_ARG(TYPE) y, NBL_CONST_REF_ARG(TYPE) a)\ {\ return MIX_FUNCTION(x, y, a);\ }\ @@ -36,7 +36,7 @@ struct lerp_helper\ template\ struct lerp_helper, vector >\ {\ - static inline vector lerp(NBL_CONST_REF_ARG(vector) x, NBL_CONST_REF_ARG(vector) y, NBL_CONST_REF_ARG(vector) a)\ + static inline vector __call(NBL_CONST_REF_ARG(vector) x, NBL_CONST_REF_ARG(vector) y, NBL_CONST_REF_ARG(vector) a)\ {\ return MIX_FUNCTION(x, y, a);\ }\ @@ -45,7 +45,7 @@ struct lerp_helper, vector >\ template\ struct lerp_helper, TYPE>\ {\ - static inline vector lerp(NBL_CONST_REF_ARG(vector) x, NBL_CONST_REF_ARG(vector) y, NBL_CONST_REF_ARG(TYPE) a)\ + static inline vector __call(NBL_CONST_REF_ARG(vector) x, NBL_CONST_REF_ARG(vector) y, NBL_CONST_REF_ARG(TYPE) a)\ {\ return MIX_FUNCTION(x, y, a);\ }\ @@ -60,7 +60,7 @@ DEFINE_LERP_HELPER_COMMON_SPECIALIZATION(float64_t) template struct lerp_helper { - static inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(bool) a) + static inline T __call(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(bool) a) { if (a) return y; @@ -74,7 +74,7 @@ struct lerp_helper, vector > { using output_vec_t = vector; - static inline output_vec_t lerp(NBL_CONST_REF_ARG(output_vec_t) x, NBL_CONST_REF_ARG(output_vec_t) y, NBL_CONST_REF_ARG(vector) a) + static inline output_vec_t __call(NBL_CONST_REF_ARG(output_vec_t) x, NBL_CONST_REF_ARG(output_vec_t) y, NBL_CONST_REF_ARG(vector) a) { output_vec_t retval; for (uint32_t i = 0; i < vector_traits::Dimension; i++) diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index 6331cfee82..fe4f066400 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -113,7 +113,7 @@ inline Vector floor(NBL_CONST_REF_ARG(Vector) vec) template inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) { - return tgmath_impl::lerp_helper::lerp(x, y, a); + return tgmath_impl::lerp_helper::__call(x, y, a); } template) diff --git a/include/nbl/core/util/bitflag.h b/include/nbl/core/util/bitflag.h index 209879966d..167b25e40d 100644 --- a/include/nbl/core/util/bitflag.h +++ b/include/nbl/core/util/bitflag.h @@ -59,18 +59,18 @@ namespace nbl::hlsl::cpp_compat_intrinsics_impl template struct find_lsb_helper> { - static int32_t findLSB(NBL_CONST_REF_ARG(core::bitflag) val) + static int32_t __call(NBL_CONST_REF_ARG(core::bitflag) val) { - return find_lsb_helper::findLSB(val.value); + return find_lsb_helper::__call(val.value); } }; template struct find_msb_helper> { - static int32_t findMSB(NBL_CONST_REF_ARG(core::bitflag) val) + static int32_t __call(NBL_CONST_REF_ARG(core::bitflag) val) { - return find_msb_helper::findMSB(val.value); + return find_msb_helper::__call(val.value); } }; } From 7e7305455ed5f8a91c860e8dc45f8c89a95abfb7 Mon Sep 17 00:00:00 2001 From: Przemek Date: Sat, 21 Dec 2024 13:58:51 +0100 Subject: [PATCH 20/42] Refactored the `floor` function --- .../nbl/builtin/hlsl/impl/tgmath_impl.hlsl | 44 +++++++++++++++++++ include/nbl/builtin/hlsl/tgmath.hlsl | 25 ++--------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl index 8e337c7d13..e2866644d2 100644 --- a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl +++ b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl @@ -97,6 +97,50 @@ inline bool isinf_uint_impl(UnsignedInteger val) return (val & (~ieee754::traits::signMask)) == ieee754::traits::inf; } +template +struct floor_helper; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v&& hlsl::is_scalar_v) +struct floor_helper) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) val) + { +#ifdef __HLSL_VERSION + return spirv::floor(val); +#else + return std::floor(val); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_vector_v) +struct floor_helper) > +{ + static Vector __call(NBL_CONST_REF_ARG(Vector) vec) + { +#ifdef __HLSL_VERSION + return spirv::floor(vec); +#else + Vector output; + using traits = hlsl::vector_traits; + for (uint32_t i = 0; i < traits::Dimension; ++i) + output[i] = floor(vec[i]); + return output; + + // TODO: cherry-pick array_getters + /*array_get getter; + array_set setter; + Vector output; + using traits = hlsl::vector_traits; + for (uint32_t i = 0; i < traits::Dimension; i++) + setter(output, floor_helper::__call(getter(vec, i)), i); + return output;*/ +#endif + } +}; + } } } diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index fe4f066400..477c37b815 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -85,31 +85,12 @@ inline FloatingPoint erfInv(FloatingPoint _x) return p*x; } -template && hlsl::is_scalar_v) -inline Scalar floor(NBL_CONST_REF_ARG(Scalar) val) +template +inline T floor(NBL_CONST_REF_ARG(T) val) { -#ifdef __HLSL_VERSION - return spirv::floor(val); -#else - return std::floor(val); -#endif + return tgmath_impl::floor_helper::__call(val); } -template&& hlsl::is_vector_v) -inline Vector floor(NBL_CONST_REF_ARG(Vector) vec) -{ -#ifdef __HLSL_VERSION - return spirv::floor(vec); -#else - Vector output; - for (int32_t i = 0; i < hlsl::vector_traits::Dimension; ++i) - output[i] = std::floor(vec[i]); - - return output; -#endif -} - - template inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) { From 0276f8e3e1b5d922da635edea44e8242d96b42e0 Mon Sep 17 00:00:00 2001 From: Przemek Date: Sat, 21 Dec 2024 16:17:18 +0100 Subject: [PATCH 21/42] `Floor` func improvement --- .../nbl/builtin/hlsl/impl/tgmath_impl.hlsl | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl index e2866644d2..665705b762 100644 --- a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl +++ b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl @@ -120,24 +120,15 @@ struct floor_helper) > { static Vector __call(NBL_CONST_REF_ARG(Vector) vec) { -#ifdef __HLSL_VERSION - return spirv::floor(vec); -#else - Vector output; using traits = hlsl::vector_traits; - for (uint32_t i = 0; i < traits::Dimension; ++i) - output[i] = floor(vec[i]); - return output; + array_get getter; + array_set setter; - // TODO: cherry-pick array_getters - /*array_get getter; - array_set setter; Vector output; - using traits = hlsl::vector_traits; - for (uint32_t i = 0; i < traits::Dimension; i++) - setter(output, floor_helper::__call(getter(vec, i)), i); - return output;*/ -#endif + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, floor_helper::__call(getter(vec, i))); + + return output; } }; From 147c08000f56b584bfec8d3e2161a7da79f50082 Mon Sep 17 00:00:00 2001 From: Przemek Date: Sat, 21 Dec 2024 20:46:48 +0100 Subject: [PATCH 22/42] Added negate and copy sign functions --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 37 ++++++++++++++++++- .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 5 +++ include/nbl/builtin/hlsl/ieee754.hlsl | 11 ++++++ .../builtin/hlsl/spirv_intrinsics/core.hlsl | 4 ++ include/nbl/builtin/hlsl/tgmath.hlsl | 2 +- 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 8e90bd7641..819b0e64e6 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -327,7 +327,7 @@ struct bitReverse_helper Vector output; using traits = hlsl::vector_traits; for (uint32_t i = 0; i < traits::Dimension; ++i) - output[i] = bitReverse_helper >::__call(vec[i]); + output[i] = bitReverse_helper::__call(vec[i]); return output; #endif } @@ -360,6 +360,41 @@ struct mul_helper } }; +template +struct negate_helper; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v && hlsl::is_scalar_v) +struct negate_helper && hlsl::is_scalar_v) > +{ + static inline FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) val) + { +#ifdef __HLSL_VERSION + return spirv::fNegate(val); +#else + return -val; +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_vector_v) +struct negate_helper && hlsl::is_vector_v) > +{ + static Vector __call(NBL_CONST_REF_ARG(Vector) vec) + { +#ifdef __HLSL_VERSION + return spirv::fNegate(vec); +#else + Vector output; + using traits = hlsl::vector_traits; + for (uint32_t i = 0; i < traits::Dimension; ++i) + output[i] = negate_helper::__call(vec[i]); + return output; +#endif + } +}; + } } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index efbf016c4b..55069ec822 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -152,6 +152,11 @@ inline Integer bitReverse(Integer val) return cpp_compat_intrinsics_impl::bitReverse_helper::__call(val); } +template +inline FloatingPoint negate(FloatingPoint val) +{ + return cpp_compat_intrinsics_impl::negate_helper::__call(val); +} } } diff --git a/include/nbl/builtin/hlsl/ieee754.hlsl b/include/nbl/builtin/hlsl/ieee754.hlsl index cbbc0b8abd..d969ffe3f6 100644 --- a/include/nbl/builtin/hlsl/ieee754.hlsl +++ b/include/nbl/builtin/hlsl/ieee754.hlsl @@ -130,6 +130,17 @@ NBL_CONSTEXPR_INLINE_FUNC typename unsigned_integer_of_size::type ext return ieee754::impl::bitCastToUintType(x) & traits::signMask; } +template && hlsl::is_scalar_v) +NBL_CONSTEXPR_INLINE_FUNC FloatingPoint copySign(FloatingPoint to, FloatingPoint from) +{ + using AsUint = typename unsigned_integer_of_size::type; + + const AsUint toAsUint = ieee754::impl::bitCastToUintType(to); + const AsUint fromAsUint = ieee754::impl::bitCastToUintType(from); + + return bit_cast(toAsUint | extractSignPreserveBitPattern(from)); +} + } } } diff --git a/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl b/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl index 66807a26d1..5f327e8bdb 100644 --- a/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl +++ b/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl @@ -246,6 +246,10 @@ template [[vk::ext_instruction( spv::OpTranspose )]] Matrix transpose(Matrix mat); +template +[[vk::ext_instruction(spv::OpFNegate)]] +enable_if_t, FloatingPoint> fNegate(FloatingPoint mat); + } #endif diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index 477c37b815..64c695d567 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -98,7 +98,7 @@ inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG( } template) - inline bool isnan(NBL_CONST_REF_ARG(FloatingPoint) val) +inline bool isnan(NBL_CONST_REF_ARG(FloatingPoint) val) { #ifdef __HLSL_VERSION return spirv::isNan(val); From a640976e8c914acdb4976eb893095a43dfc252c5 Mon Sep 17 00:00:00 2001 From: Przemek Date: Sat, 21 Dec 2024 21:00:17 +0100 Subject: [PATCH 23/42] Moved flipSign function to ieee754.hlsl --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 35 ------------------- .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 6 ---- include/nbl/builtin/hlsl/ieee754.hlsl | 10 ++++++ .../builtin/hlsl/spirv_intrinsics/core.hlsl | 4 --- 4 files changed, 10 insertions(+), 45 deletions(-) diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 819b0e64e6..2f7258e084 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -360,41 +360,6 @@ struct mul_helper } }; -template -struct negate_helper; - -template -NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v && hlsl::is_scalar_v) -struct negate_helper && hlsl::is_scalar_v) > -{ - static inline FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) val) - { -#ifdef __HLSL_VERSION - return spirv::fNegate(val); -#else - return -val; -#endif - } -}; - -template -NBL_PARTIAL_REQ_TOP(hlsl::is_vector_v) -struct negate_helper && hlsl::is_vector_v) > -{ - static Vector __call(NBL_CONST_REF_ARG(Vector) vec) - { -#ifdef __HLSL_VERSION - return spirv::fNegate(vec); -#else - Vector output; - using traits = hlsl::vector_traits; - for (uint32_t i = 0; i < traits::Dimension; ++i) - output[i] = negate_helper::__call(vec[i]); - return output; -#endif - } -}; - } } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index 55069ec822..c51ca256f0 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -152,12 +152,6 @@ inline Integer bitReverse(Integer val) return cpp_compat_intrinsics_impl::bitReverse_helper::__call(val); } -template -inline FloatingPoint negate(FloatingPoint val) -{ - return cpp_compat_intrinsics_impl::negate_helper::__call(val); -} - } } diff --git a/include/nbl/builtin/hlsl/ieee754.hlsl b/include/nbl/builtin/hlsl/ieee754.hlsl index d969ffe3f6..f2eb8b119e 100644 --- a/include/nbl/builtin/hlsl/ieee754.hlsl +++ b/include/nbl/builtin/hlsl/ieee754.hlsl @@ -141,6 +141,16 @@ NBL_CONSTEXPR_INLINE_FUNC FloatingPoint copySign(FloatingPoint to, FloatingPoint return bit_cast(toAsUint | extractSignPreserveBitPattern(from)); } +template && hlsl::is_scalar_v) +NBL_CONSTEXPR_INLINE_FUNC FloatingPoint flipSign(FloatingPoint val) +{ + using AsFloat = typename float_of_size::type; + using AsUint = typename unsigned_integer_of_size::type; + const AsUint asUint = ieee754::impl::bitCastToUintType(val); + + return bit_cast(asUint ^ ieee754::traits::signMask); +} + } } } diff --git a/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl b/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl index 5f327e8bdb..66807a26d1 100644 --- a/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl +++ b/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl @@ -246,10 +246,6 @@ template [[vk::ext_instruction( spv::OpTranspose )]] Matrix transpose(Matrix mat); -template -[[vk::ext_instruction(spv::OpFNegate)]] -enable_if_t, FloatingPoint> fNegate(FloatingPoint mat); - } #endif From 70f287017d5af496ab1cb809fd820a35956a1a27 Mon Sep 17 00:00:00 2001 From: Przemek Date: Mon, 23 Dec 2024 15:42:41 +0100 Subject: [PATCH 24/42] Fixed bitcount, added normalize --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 112 ++++++++++++++++++ .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 23 ++-- .../builtin/hlsl/spirv_intrinsics/core.hlsl | 4 + src/nbl/builtin/CMakeLists.txt | 2 +- 4 files changed, 125 insertions(+), 16 deletions(-) diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 2f7258e084..8defe9586a 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -9,6 +9,10 @@ #include #include +#ifndef __HLSL_VERSION +#include +#endif + namespace nbl { namespace hlsl @@ -360,6 +364,114 @@ struct mul_helper } }; +// TODO: some struct that with other functions, since more functions will need that.. +template +struct bitcount_output; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v && hlsl::is_scalar_v) +struct bitcount_output&& hlsl::is_scalar_v) > +{ + using type = int32_t; +}; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v && hlsl::is_vector_v) +struct bitcount_output && hlsl::is_vector_v) > +{ + using type = vector::Dimension>; +}; + +#ifndef __HLSL_VERSION +template +requires std::is_enum_v +struct bitcount_output) > +{ + using type = int32_t; +}; +#endif + +template +using bitcount_output_t = typename bitcount_output::type; + +template +struct bitCount_helper; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v&& hlsl::is_scalar_v) +struct bitCount_helper&& hlsl::is_scalar_v) > +{ + static bitcount_output_t __call(NBL_CONST_REF_ARG(Integer) val) + { +#ifdef __HLSL_VERSION + if (sizeof(Integer) == 8u) + { + uint32_t lowBits = uint32_t(val); + uint32_t highBits = uint32_t(uint64_t(val) >> 32u); + + return countbits(lowBits) + countbits(highBits); + } + + return spirv::bitCount(val); + +#else + using UnsignedInteger = typename hlsl::unsigned_integer_of_size_t; + constexpr int32_t BitCnt = sizeof(Integer) * 8u; + std::bitset bitset(static_cast(val)); + return bitset.count(); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v && hlsl::is_vector_v) +struct bitCount_helper && hlsl::is_vector_v) > +{ + static bitcount_output_t __call(NBL_CONST_REF_ARG(Vector) vec) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + Vector output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, bitCount_helper::__call(getter(vec, i))); + + return output; + } +}; + +#ifndef __HLSL_VERSION +template +requires std::is_enum_v +struct bitCount_helper +{ + using underlying_t = std::underlying_type_t; + + static bitcount_output_t __call(NBL_CONST_REF_ARG(EnumT) val) + { + return bitCount_helper::__call(reinterpret_cast(val)); + } +}; +#endif + +template +struct normalize_helper; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v && hlsl::is_vector_v) +struct normalize_helper && hlsl::is_vector_v) > +{ + static inline Vector __call(NBL_CONST_REF_ARG(Vector) vec) + { +#ifdef __HLSL_VERSION + return normalize(vec); +#else + return vec / std::sqrt(dot_helper::__call(vec, vec)); +#endif + } +}; + } } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index c51ca256f0..5102bd3e9f 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -20,22 +20,9 @@ namespace hlsl { template -inline int bitCount(NBL_CONST_REF_ARG(Integer) val) +inline cpp_compat_intrinsics_impl::bitcount_output_t bitCount(NBL_CONST_REF_ARG(Integer) val) { -#ifdef __HLSL_VERSION - if (sizeof(Integer) == 8u) - { - uint32_t lowBits = uint32_t(val); - uint32_t highBits = uint32_t(uint64_t(val) >> 32u); - - return countbits(lowBits) + countbits(highBits); - } - - return countbits(val); - -#else - return glm::bitCount(val); -#endif + return cpp_compat_intrinsics_impl::bitCount_helper::__call(val); } template @@ -58,6 +45,12 @@ T clamp(NBL_CONST_REF_ARG(T) val, NBL_CONST_REF_ARG(T) min, NBL_CONST_REF_ARG(T) #endif } +template +Vector normalize(NBL_CONST_REF_ARG(Vector) vec) +{ + return cpp_compat_intrinsics_impl::normalize_helper::__call(vec); +} + template typename vector_traits::scalar_type dot(NBL_CONST_REF_ARG(T) lhs, NBL_CONST_REF_ARG(T) rhs) { diff --git a/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl b/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl index 66807a26d1..1d57956465 100644 --- a/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl +++ b/include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl @@ -246,6 +246,10 @@ template [[vk::ext_instruction( spv::OpTranspose )]] Matrix transpose(Matrix mat); +template +[[vk::ext_instruction(spv::OpBitCount)]] +enable_if_t, Integral> bitCount(Integral mat); + } #endif diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index 6c75267135..72e8900666 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -214,7 +214,7 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/macros.h") # utility LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/array_accessors.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/vector_utils/vector_traits.hlsl") -LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/matrix_utils.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/matrix_traits.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/mul_output_t.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/tgmath.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/impl/tgmath_impl.hlsl") From 9dc8b4368e7b0336da5d0445ae6dd631b7e5aebb Mon Sep 17 00:00:00 2001 From: Przemek Date: Mon, 23 Dec 2024 16:56:13 +0100 Subject: [PATCH 25/42] Refactored `hlsl::cross` function --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 44 ++++++++++++++++++- .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 16 ++++--- .../hlsl/spirv_intrinsics/glsl.std.450.hlsl | 8 ++++ 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 8defe9586a..6b200acaff 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -63,6 +63,29 @@ DEFINE_BUILTIN_VECTOR_SPECIALIZATION(float64_t, BUILTIN_VECTOR_SPECIALIZATION_RE #undef BUILTIN_VECTOR_SPECIALIZATION_RET_VAL #undef DEFINE_BUILTIN_VECTOR_SPECIALIZATION +template +struct cross_helper; + +//! this specialization will work only with hlsl::vector type +template +NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v && hlsl::is_vector_v && (vector_traits::Dimension == 3)) +struct cross_helper&& hlsl::is_vector_v&& (vector_traits::Dimension == 3)) > +{ + static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) lhs, NBL_CONST_REF_ARG(FloatingPointVector) rhs) + { +#ifdef __HLSL_VERSION + return spirv::cross(lhs, rhs); +#else + FloatingPointVector output; + output.x = lhs[1] * rhs[2] - rhs[1] * lhs[2]; + output.y = lhs[2] * rhs[0] - rhs[2] * lhs[0]; + output.z = lhs[0] * rhs[1] - rhs[0] * lhs[1]; + + return output; +#endif + } +}; + template struct find_msb_helper; @@ -455,6 +478,23 @@ struct bitCount_helper }; #endif +template +struct length_helper; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v&& hlsl::is_vector_v) +struct length_helper&& hlsl::is_vector_v) > +{ + static inline typename vector_traits::scalar_type __call(NBL_CONST_REF_ARG(Vector) vec) + { +#ifdef __HLSL_VERSION + return spirv::length(vec); +#else + return std::sqrt(dot_helper::__call(vec, vec)); +#endif + } +}; + template struct normalize_helper; @@ -465,9 +505,9 @@ struct normalize_helper::__call(vec, vec)); + return vec / length_helper::__call(vec); #endif } }; diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index 5102bd3e9f..fbf4c07e81 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -25,14 +25,10 @@ inline cpp_compat_intrinsics_impl::bitcount_output_t bitCount(NBL_CONST return cpp_compat_intrinsics_impl::bitCount_helper::__call(val); } -template -vector cross(NBL_CONST_REF_ARG(vector) lhs, NBL_CONST_REF_ARG(vector) rhs) +template +FloatingPointVector cross(NBL_CONST_REF_ARG(FloatingPointVector) lhs, NBL_CONST_REF_ARG(FloatingPointVector) rhs) { -#ifdef __HLSL_VERSION - return spirv::cross(lhs, rhs); -#else - return glm::cross(lhs, rhs); -#endif + return cpp_compat_intrinsics_impl::cross_helper::__call(lhs, rhs); } template @@ -45,6 +41,12 @@ T clamp(NBL_CONST_REF_ARG(T) val, NBL_CONST_REF_ARG(T) min, NBL_CONST_REF_ARG(T) #endif } +template +typename vector_traits::scalar_type length(NBL_CONST_REF_ARG(Vector) vec) +{ + return cpp_compat_intrinsics_impl::length_helper::__call(vec); +} + template Vector normalize(NBL_CONST_REF_ARG(Vector) vec) { diff --git a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl index d4ca62f039..4fce3d4c0a 100644 --- a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl +++ b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl @@ -91,6 +91,14 @@ float32_t4 unpackSnorm4x8(uint32_t p); [[vk::ext_instruction(GLSLstd450UnpackUnorm4x8, "GLSL.std.450")]] float32_t4 unpackUnorm4x8(uint32_t p); +template +[[vk::ext_instruction(GLSLstd450Length, "GLSL.std.450")]] +enable_if_t&& is_vector_v, FloatingPointVector> length(FloatingPointVector vec); + +template +[[vk::ext_instruction(GLSLstd450Normalize, "GLSL.std.450")]] +enable_if_t && is_vector_v, FloatingPointVector> normalize(FloatingPointVector vec); + } } } From 677b17690fb6c6628481599600adde3057a947ed Mon Sep 17 00:00:00 2001 From: Przemek Date: Mon, 23 Dec 2024 19:23:23 +0100 Subject: [PATCH 26/42] Refactor --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 197 +++++++++++++++++- .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 29 ++- .../hlsl/spirv_intrinsics/glsl.std.450.hlsl | 31 +++ 3 files changed, 238 insertions(+), 19 deletions(-) diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 6b200acaff..3c5e46cb9f 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -68,8 +68,8 @@ struct cross_helper; //! this specialization will work only with hlsl::vector type template -NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v && hlsl::is_vector_v && (vector_traits::Dimension == 3)) -struct cross_helper&& hlsl::is_vector_v&& (vector_traits::Dimension == 3)) > +NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_vector_v && (vector_traits::Dimension == 3)) +struct cross_helper&& is_vector_v&& (vector_traits::Dimension == 3)) > { static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) lhs, NBL_CONST_REF_ARG(FloatingPointVector) rhs) { @@ -86,6 +86,69 @@ struct cross_helper +struct clamp_helper; + +template +NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_scalar_v) +struct clamp_helper && is_scalar_v) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) val, NBL_CONST_REF_ARG(FloatingPoint) min, NBL_CONST_REF_ARG(FloatingPoint) max) + { +#ifdef __HLSL_VERSION + return spirv::fClamp(val, min, max); +#else + return std::clamp(val, min, max); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_integral_v && !is_signed_v && is_scalar_v) +struct clamp_helper && !is_signed_v&& is_scalar_v) > +{ + static UnsignedInteger __call(NBL_CONST_REF_ARG(UnsignedInteger) val, NBL_CONST_REF_ARG(UnsignedInteger) min, NBL_CONST_REF_ARG(UnsignedInteger) max) + { +#ifdef __HLSL_VERSION + return spirv::uClamp(val, min, max); +#else + return std::clamp(val, min, max); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_integral_v && is_signed_v&& is_scalar_v) +struct clamp_helper&& is_signed_v&& is_scalar_v) > +{ + static Integer __call(NBL_CONST_REF_ARG(Integer) val, NBL_CONST_REF_ARG(Integer) min, NBL_CONST_REF_ARG(Integer) max) + { +#ifdef __HLSL_VERSION + return spirv::sClamp(val, min, max); +#else + return std::clamp(val, min, max); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v) +struct clamp_helper) > +{ + static Vector __call(NBL_CONST_REF_ARG(Vector) val, NBL_CONST_REF_ARG(typename vector_traits::scalar_type) min, NBL_CONST_REF_ARG(typename vector_traits::scalar_type) max) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + Vector output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, clamp_helper::__call(getter(val, i), min, max)); + + return output; + } +}; + template struct find_msb_helper; @@ -512,6 +575,136 @@ struct normalize_helper +struct min_helper; + +template +NBL_PARTIAL_REQ_TOP(is_floating_point_v&& is_scalar_v) +struct min_helper&& is_scalar_v) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) a, NBL_CONST_REF_ARG(FloatingPoint) b) + { +#ifdef __HLSL_VERSION + return spirv::fMin(a, b); +#else + return std::min(a, b); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_integral_v && !is_signed_v&& is_scalar_v) +struct min_helper && !is_signed_v&& is_scalar_v) > +{ + static UnsignedInteger __call(NBL_CONST_REF_ARG(UnsignedInteger) a, NBL_CONST_REF_ARG(UnsignedInteger) b) + { +#ifdef __HLSL_VERSION + return spirv::uMin(a, b); +#else + return std::min(a, b); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_integral_v&& is_signed_v&& is_scalar_v) +struct min_helper&& is_signed_v&& is_scalar_v) > +{ + static Integer __call(NBL_CONST_REF_ARG(Integer) a, NBL_CONST_REF_ARG(Integer) b) + { +#ifdef __HLSL_VERSION + return spirv::sMin(a, b); +#else + return std::min(a, b); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v) +struct min_helper) > +{ + static Vector __call(NBL_CONST_REF_ARG(Vector) a, NBL_CONST_REF_ARG(Vector) b) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + Vector output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, min_helper::__call(getter(a, i), getter(b, i))); + + return output; + } +}; + +// MAX + +template +struct max_helper; + +template +NBL_PARTIAL_REQ_TOP(is_floating_point_v&& is_scalar_v) +struct max_helper&& is_scalar_v) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) a, NBL_CONST_REF_ARG(FloatingPoint) b) + { +#ifdef __HLSL_VERSION + return spirv::fMax(a, b); +#else + return std::max(a, b); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_integral_v && !is_signed_v&& is_scalar_v) +struct max_helper && !is_signed_v&& is_scalar_v) > +{ + static UnsignedInteger __call(NBL_CONST_REF_ARG(UnsignedInteger) a, NBL_CONST_REF_ARG(UnsignedInteger) b) + { +#ifdef __HLSL_VERSION + return spirv::uMax(a, b); +#else + return std::max(a, b); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_integral_v&& is_signed_v&& is_scalar_v) +struct max_helper&& is_signed_v&& is_scalar_v) > +{ + static Integer __call(NBL_CONST_REF_ARG(Integer) a, NBL_CONST_REF_ARG(Integer) b) + { +#ifdef __HLSL_VERSION + return spirv::sMax(a, b); +#else + return std::max(a, b); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v) +struct max_helper) > +{ + static Vector __call(NBL_CONST_REF_ARG(Vector) a, NBL_CONST_REF_ARG(Vector) b) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + Vector output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, max_helper::__call(getter(a, i), getter(b, i))); + + return output; + } +}; + } } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index fbf4c07e81..65fbb1e4a3 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -31,14 +31,17 @@ FloatingPointVector cross(NBL_CONST_REF_ARG(FloatingPointVector) lhs, NBL_CONST_ return cpp_compat_intrinsics_impl::cross_helper::__call(lhs, rhs); } -template -T clamp(NBL_CONST_REF_ARG(T) val, NBL_CONST_REF_ARG(T) min, NBL_CONST_REF_ARG(T) max) +template +enable_if_t, Scalar> clamp(NBL_CONST_REF_ARG(Scalar) val, NBL_CONST_REF_ARG(Scalar) min, NBL_CONST_REF_ARG(Scalar) max) { -#ifdef __HLSL_VERSION - return clamp(val, min, max); -#else - return glm::clamp(val, min, max); -#endif + return cpp_compat_intrinsics_impl::clamp_helper::__call(val, min, max); +} + +// TODO: is_vector_v will be false for custom vector types, fix +template +enable_if_t, Vector> clamp(NBL_CONST_REF_ARG(Vector) val, NBL_CONST_REF_ARG(typename vector_traits::scalar_type) min, NBL_CONST_REF_ARG(typename vector_traits::scalar_type) max) +{ + return cpp_compat_intrinsics_impl::clamp_helper::__call(val, min, max); } template @@ -113,21 +116,13 @@ mul_output_t mul(LhsT mat, RhsT vec) template inline T min(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b) { -#ifdef __HLSL_VERSION - min(a, b); -#else - return glm::min(a, b); -#endif + return cpp_compat_intrinsics_impl::min_helper::__call(a, b); } template inline T max(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b) { -#ifdef __HLSL_VERSION - max(a, b); -#else - return glm::max(a, b); -#endif + return cpp_compat_intrinsics_impl::max_helper::__call(a, b); } template diff --git a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl index 4fce3d4c0a..dcbae448f0 100644 --- a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl +++ b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl @@ -99,6 +99,37 @@ template [[vk::ext_instruction(GLSLstd450Normalize, "GLSL.std.450")]] enable_if_t && is_vector_v, FloatingPointVector> normalize(FloatingPointVector vec); +// TODO: will not work for vectors, fix +template +[[vk::ext_instruction(GLSLstd450FClamp, "GLSL.std.450")]] +enable_if_t, FloatingPoint> fClamp(FloatingPoint val, FloatingPoint min, FloatingPoint max); +template +[[vk::ext_instruction(GLSLstd450UClamp, "GLSL.std.450")]] +enable_if_t && !is_signed_v, UnsignedInteger> uClamp(UnsignedInteger val, UnsignedInteger min, UnsignedInteger max); +template +[[vk::ext_instruction(GLSLstd450SClamp, "GLSL.std.450")]] +enable_if_t && is_signed_v, Integer> sClamp(Integer val, Integer min, Ingeger max); + +template +[[vk::ext_instruction(GLSLstd450FMin, "GLSL.std.450")]] +enable_if_t, FloatingPoint> fMin(FloatingPoint val); +template +[[vk::ext_instruction(GLSLstd450UMin, "GLSL.std.450")]] +enable_if_t && !is_signed_v, UnsignedInteger> uMin(UnsignedInteger val); +template +[[vk::ext_instruction(GLSLstd450SMin, "GLSL.std.450")]] +enable_if_t&& is_signed_v, Integer> sMin(Integer val); + +template +[[vk::ext_instruction(GLSLstd450FMax, "GLSL.std.450")]] +enable_if_t, FloatingPoint> fMax(FloatingPoint val); +template +[[vk::ext_instruction(GLSLstd450UMax, "GLSL.std.450")]] +enable_if_t && !is_signed_v, UnsignedInteger> uMax(UnsignedInteger val); +template +[[vk::ext_instruction(GLSLstd450SMax, "GLSL.std.450")]] +enable_if_t&& is_signed_v, Integer> sMax(Integer val); + } } } From 949a972af72c585c90f1c26cbcf9914aaafaf7c8 Mon Sep 17 00:00:00 2001 From: Przemek Date: Mon, 23 Dec 2024 19:27:38 +0100 Subject: [PATCH 27/42] fix --- include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl index dcbae448f0..f693424af6 100644 --- a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl +++ b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl @@ -108,7 +108,7 @@ template enable_if_t && !is_signed_v, UnsignedInteger> uClamp(UnsignedInteger val, UnsignedInteger min, UnsignedInteger max); template [[vk::ext_instruction(GLSLstd450SClamp, "GLSL.std.450")]] -enable_if_t && is_signed_v, Integer> sClamp(Integer val, Integer min, Ingeger max); +enable_if_t && is_signed_v, Integer> sClamp(Integer val, Integer min, Integer max); template [[vk::ext_instruction(GLSLstd450FMin, "GLSL.std.450")]] From 04f60abbbb3f5f0cfec5f5a77875d6cdf1eb1943 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 26 Dec 2024 11:19:46 +0700 Subject: [PATCH 28/42] fix refract functions --- include/nbl/builtin/hlsl/math/functions.hlsl | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/include/nbl/builtin/hlsl/math/functions.hlsl b/include/nbl/builtin/hlsl/math/functions.hlsl index 30bd11cecd..82aaca651e 100644 --- a/include/nbl/builtin/hlsl/math/functions.hlsl +++ b/include/nbl/builtin/hlsl/math/functions.hlsl @@ -84,7 +84,7 @@ scalar_type_t lpNorm(NBL_CONST_REF_ARG(T) v) template ) vector reflect(vector I, vector N, T NdotI) { - return N * 2.0 * NdotI - I; + return N * 2.0f * NdotI - I; } template ) @@ -217,29 +217,28 @@ struct refract template) vector refract(vector I, vector N, bool backside, T NdotI, T NdotI2, T rcpOrientedEta, T rcpOrientedEta2) { - impl::refract r = impl::refract::create(I, N, backside, NdotI, NdotI2, rcpOrientedEta, rcpOrientedEta2); + impl::refract r = impl::refract::create(I, N, backside, NdotI, NdotI2, rcpOrientedEta, rcpOrientedEta2); return r.doRefract(); } template) vector refract(vector I, vector N, T NdotI, T eta) { - impl::refract r = impl::refract::create(I, N, NdotI, eta); + impl::refract r = impl::refract::create(I, N, NdotI, eta); return r.doRefract(); } template) vector refract(vector I, vector N, T eta) { - impl::refract r = impl::refract::create(I, N, eta); + impl::refract r = impl::refract::create(I, N, eta); return r.doRefract(); } -// I don't like exposing these next two template) -vector reflectRefract_computeNdotT(bool backside, T NdotI2, T rcpOrientedEta2) +T reflectRefract_computeNdotT(bool backside, T NdotI2, T rcpOrientedEta2) { - impl::refract r; + impl::refract r; r.NdotI2 = NdotI2; r.rcpOrientedEta2 = rcpOrientedEta2; r.backside = backside; @@ -249,20 +248,20 @@ vector reflectRefract_computeNdotT(bool backside, T NdotI2, T rcpOrientedEt template) vector reflectRefract_impl(bool _refract, vector _I, vector _N, T _NdotI, T _NdotTorR, T _rcpOrientedEta) { - return impl::refract::doReflectRefract(_refract, _I, _N, _NdotI, _NdotTorR, _rcpOrientedEta); + return impl::refract::doReflectRefract(_refract, _I, _N, _NdotI, _NdotTorR, _rcpOrientedEta); } template) vector reflectRefract(bool _refract, vector I, vector N, bool backside, T NdotI, T NdotI2, T rcpOrientedEta, T rcpOrientedEta2) { - impl::refract r = impl::refract::create(I, N, backside, NdotI, NdotI2, rcpOrientedEta, rcpOrientedEta2); + impl::refract r = impl::refract::create(I, N, backside, NdotI, NdotI2, rcpOrientedEta, rcpOrientedEta2); return r.doReflectRefract(_refract); } template) vector reflectRefract(bool _refract, vector I, vector N, T NdotI, T eta) { - impl::refract r = impl::refract::create(I, N, NdotI, eta); + impl::refract r = impl::refract::create(I, N, NdotI, eta); return r.doReflectRefract(_refract); } From 6fecfa95e2d6145e43b52bf3ec86ac30c2aff157 Mon Sep 17 00:00:00 2001 From: Przemek Date: Sat, 28 Dec 2024 17:05:56 +0100 Subject: [PATCH 29/42] Now every tgmath function utilize helpers --- examples_tests | 2 +- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 76 +++++ .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 29 +- .../nbl/builtin/hlsl/impl/tgmath_impl.hlsl | 274 ++++++++++++++++++ include/nbl/builtin/hlsl/tgmath.hlsl | 101 +------ 5 files changed, 370 insertions(+), 112 deletions(-) diff --git a/examples_tests b/examples_tests index 32f959d5f9..e0bde55374 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 32f959d5f98d63e402dbbf2f65366078b67c77cc +Subproject commit e0bde553745a72d092d497ed9749510d1a21abe0 diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 3c5e46cb9f..8efca3b403 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -705,6 +705,82 @@ struct max_helper) > } }; +// DETERMINANT + +template +struct determinant_helper; + +template +NBL_PARTIAL_REQ_TOP(matrix_traits::Square) +struct determinant_helper::Square) > +{ + static typename matrix_traits::scalar_type __call(NBL_CONST_REF_ARG(SquareMatrix) mat) + { +#ifdef __HLSL_VERSION + spirv::determinant(mat); +#else + return glm::determinant(reinterpret_cast(mat)); +#endif + } +}; + +// INVERSE + +template +struct inverse_helper; + +template +NBL_PARTIAL_REQ_TOP(matrix_traits::Square) +struct inverse_helper::Square) > +{ + static SquareMatrix __call(NBL_CONST_REF_ARG(SquareMatrix) mat) + { +#ifdef __HLSL_VERSION + return spirv::matrixInverse(mat); +#else + return reinterpret_cast(glm::inverse(reinterpret_cast(mat))); +#endif + } +}; + +// RSQRT + +template +struct rsqrt_helper; + +template +NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_scalar_v) +struct rsqrt_helper && is_scalar_v) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { + // TODO: https://stackoverflow.com/a/62239778 +#ifdef __HLSL_VERSION + return spirv::inverseSqrt(x); +#else + return 1.0f / std::sqrt(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v && is_floating_point_v::scalar_type>) +struct rsqrt_helper&& is_floating_point_v::scalar_type>) > +{ + static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) x) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + FloatingPointVector output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, rsqrt_helper::__call(getter(x, i))); + + return output; + } +}; + } } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index 65fbb1e4a3..3a59400648 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -62,17 +62,12 @@ typename vector_traits::scalar_type dot(NBL_CONST_REF_ARG(T) lhs, NBL_CONST_R return cpp_compat_intrinsics_impl::dot_helper::__call(lhs, rhs); } -// TODO: for clearer error messages, use concepts to ensure that input type is a square matrix // determinant not defined cause its implemented via hidden friend // https://stackoverflow.com/questions/67459950/why-is-a-friend-function-not-treated-as-a-member-of-a-namespace-of-a-class-it-wa -template -inline T determinant(NBL_CONST_REF_ARG(matrix) m) +template +inline typename matrix_traits::scalar_type determinant(NBL_CONST_REF_ARG(Matrix) mat) { -#ifdef __HLSL_VERSION - spirv::determinant(m); -#else - return glm::determinant(reinterpret_cast::Base const&>(m)); -#endif + return cpp_compat_intrinsics_impl::determinant_helper::__call(mat); } template @@ -87,16 +82,11 @@ inline typename cpp_compat_intrinsics_impl::find_msb_return_type::type return cpp_compat_intrinsics_impl::find_msb_helper::__call(val); } -// TODO: for clearer error messages, use concepts to ensure that input type is a square matrix // inverse not defined cause its implemented via hidden friend -template -inline matrix inverse(NBL_CONST_REF_ARG(matrix) m) +template +inline Matrix inverse(NBL_CONST_REF_ARG(Matrix) mat) { -#ifdef __HLSL_VERSION - return spirv::matrixInverse(m); -#else - return reinterpret_cast&>(glm::inverse(reinterpret_cast::Base const&>(m))); -#endif + return cpp_compat_intrinsics_impl::inverse_helper::__call(mat); } // transpose not defined cause its implemented via hidden friend @@ -128,12 +118,7 @@ inline T max(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b) template inline FloatingPoint rsqrt(FloatingPoint x) { - // TODO: https://stackoverflow.com/a/62239778 -#ifdef __HLSL_VERSION - return spirv::inverseSqrt(x); -#else - return 1.0f / std::sqrt(x); -#endif + return cpp_compat_intrinsics_impl::rsqrt_helper::__call(x); } template diff --git a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl index 91706fb5a9..b2828ea684 100644 --- a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl +++ b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl @@ -132,6 +132,280 @@ struct floor_helper } }; +// ERF + +template +struct erf_helper; + +template +NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_scalar_v) +struct erf_helper&& is_scalar_v) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) _x) + { +#ifdef __HLSL_VERSION + const FloatingPoint a1 = 0.254829592; + const FloatingPoint a2 = -0.284496736; + const FloatingPoint a3 = 1.421413741; + const FloatingPoint a4 = -1.453152027; + const FloatingPoint a5 = 1.061405429; + const FloatingPoint p = 0.3275911; + + FloatingPoint sign = sign(_x); + FloatingPoint x = abs(_x); + + FloatingPoint t = 1.0 / (1.0 + p * x); + FloatingPoint y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * exp(-x * x); + + return sign * y; +#else + return std::erf(_x); +#endif + } +}; + +// ERFINV + +template +struct erfInv_helper; + +template +NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_scalar_v) +struct erfInv_helper && is_scalar_v) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) _x) + { + FloatingPoint x = clamp(_x, -0.99999, 0.99999); +#ifdef __HLSL_VERSION + FloatingPoint w = -log((1.0 - x) * (1.0 + x)); +#else + FloatingPoint w = -std::log((1.0 - x) * (1.0 + x)); +#endif + FloatingPoint p; + if (w < 5.0) + { + w -= 2.5; + p = 2.81022636e-08; + p = 3.43273939e-07 + p * w; + p = -3.5233877e-06 + p * w; + p = -4.39150654e-06 + p * w; + p = 0.00021858087 + p * w; + p = -0.00125372503 + p * w; + p = -0.00417768164 + p * w; + p = 0.246640727 + p * w; + p = 1.50140941 + p * w; + } + else + { +#ifdef __HLSL_VERSION + w = sqrt(w) - 3.0; +#else + w = std::sqrt(w) - 3.0; +#endif + p = -0.000200214257; + p = 0.000100950558 + p * w; + p = 0.00134934322 + p * w; + p = -0.00367342844 + p * w; + p = 0.00573950773 + p * w; + p = -0.0076224613 + p * w; + p = 0.00943887047 + p * w; + p = 1.00167406 + p * w; + p = 2.83297682 + p * w; + } + return p * x; + } +}; + +// POW + +template +struct pow_helper; + +template +NBL_PARTIAL_REQ_TOP(is_floating_point_v&& is_scalar_v && (sizeof(FloatingPoint) <= 4)) +struct pow_helper&& is_scalar_v && (sizeof(FloatingPoint) <= 4)) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x, NBL_CONST_REF_ARG(FloatingPoint) y) + { +#ifdef __HLSL_VERSION + return spirv::pow(x, y); +#else + return std::pow(x, y); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v&& is_floating_point_v::scalar_type>) +struct pow_helper&& is_floating_point_v::scalar_type>) > +{ + static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) x, NBL_CONST_REF_ARG(FloatingPointVector) y) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + FloatingPointVector output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, pow_helper::__call(getter(x, i), getter(y, i))); + + return output; + } +}; + +// EXP + +template +struct exp_helper; + +template +NBL_PARTIAL_REQ_TOP(is_floating_point_v&& is_scalar_v && (sizeof(FloatingPoint) <= 4)) +struct exp_helper&& is_scalar_v && (sizeof(FloatingPoint) <= 4)) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { +#ifdef __HLSL_VERSION + return spirv::exp(x); +#else + return std::exp(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v&& is_floating_point_v::scalar_type>) +struct exp_helper&& is_floating_point_v::scalar_type>) > +{ + static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) x) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + FloatingPointVector output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, exp_helper::__call(getter(x, i))); + + return output; + } +}; + +// EXP2 + +template +struct exp2_helper; + +template +NBL_PARTIAL_REQ_TOP(is_floating_point_v&& is_scalar_v && (sizeof(FloatingPoint) <= 4)) +struct exp2_helper && is_scalar_v && (sizeof(FloatingPoint) <= 4)) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { +#ifdef __HLSL_VERSION + return spirv::exp2(x); +#else + return std::exp2(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v && is_floating_point_v::scalar_type>) +struct exp2_helper && is_floating_point_v::scalar_type>) > +{ + static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) x) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + FloatingPointVector output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, exp2_helper::__call(getter(x, i))); + + return output; + } +}; + +template +NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v && hlsl::is_scalar_v) +struct exp2_helper && hlsl::is_scalar_v) > +{ + static Integral __call(NBL_CONST_REF_ARG(Integral) x) + { + return _static_cast(1ull << x); + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v && is_integral_v::scalar_type>) +struct exp2_helper&& is_integral_v::scalar_type>) > +{ + static Integral __call(NBL_CONST_REF_ARG(Integral) x) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + Integral output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, exp2_helper::__call(getter(x, i))); + + return output; + } +}; + +// LOG + +template +struct log_helper; + +template +NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_scalar_v && (sizeof(FloatingPoint) <= 4)) +struct log_helper && is_scalar_v && (sizeof(FloatingPoint) <= 4)) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { +#ifdef __HLSL_VERSION + return spirv::log(x); +#else + return std::log(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_same::value) +struct log_helper::value) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { +#ifdef __HLSL_VERSION + return log(x); +#else + return std::log(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v&& is_floating_point_v::scalar_type>) +struct log_helper&& is_floating_point_v::scalar_type>) > +{ + static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) x) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + FloatingPointVector output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, log_helper::__call(getter(x, i))); + + return output; + } +}; + } } } diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index 64c695d567..68568bd847 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -20,69 +20,15 @@ namespace hlsl { template -inline FloatingPoint erf(FloatingPoint _x) +inline FloatingPoint erf(FloatingPoint x) { -#ifdef __HLSL_VERSION - const FloatingPoint a1 = 0.254829592; - const FloatingPoint a2 = -0.284496736; - const FloatingPoint a3 = 1.421413741; - const FloatingPoint a4 = -1.453152027; - const FloatingPoint a5 = 1.061405429; - const FloatingPoint p = 0.3275911; - - FloatingPoint sign = sign(_x); - FloatingPoint x = abs(_x); - - FloatingPoint t = 1.0 / (1.0 + p*x); - FloatingPoint y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * exp(-x * x); - - return sign * y; -#else - return std::erf(_x); -#endif + return tgmath_impl::erf_helper::__call(x); } template -inline FloatingPoint erfInv(FloatingPoint _x) +inline FloatingPoint erfInv(FloatingPoint x) { - FloatingPoint x = clamp(_x, -0.99999, 0.99999); -#ifdef __HLSL_VERSION - FloatingPoint w = -log((1.0-x) * (1.0+x)); -#else - FloatingPoint w = -std::log((1.0-x) * (1.0+x)); -#endif - FloatingPoint p; - if (w<5.0) - { - w -= 2.5; - p = 2.81022636e-08; - p = 3.43273939e-07 + p*w; - p = -3.5233877e-06 + p*w; - p = -4.39150654e-06 + p*w; - p = 0.00021858087 + p*w; - p = -0.00125372503 + p*w; - p = -0.00417768164 + p*w; - p = 0.246640727 + p*w; - p = 1.50140941 + p*w; - } - else - { -#ifdef __HLSL_VERSION - w = sqrt(w) - 3.0; -#else - w = std::sqrt(w) - 3.0; -#endif - p = -0.000200214257; - p = 0.000100950558 + p*w; - p = 0.00134934322 + p*w; - p = -0.00367342844 + p*w; - p = 0.00573950773 + p*w; - p = -0.0076224613 + p*w; - p = 0.00943887047 + p*w; - p = 1.00167406 + p*w; - p = 2.83297682 + p*w; - } - return p*x; + return tgmath_impl::erfInv_helper::__call(x); } template @@ -126,49 +72,26 @@ template inline T pow(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y) { -#ifdef __HLSL_VERSION - return spirv::pow(x, y); -#else - return std::pow(x, y); -#endif + return tgmath_impl::pow_helper::__call(x, y); } template -inline T exp(NBL_CONST_REF_ARG(T) val) +inline T exp(NBL_CONST_REF_ARG(T) x) { -#ifdef __HLSL_VERSION - return spirv::exp(val); -#else - return std::exp(val); -#endif + return tgmath_impl::exp_helper::__call(x); } -template) -inline FloatingPoint exp2(NBL_CONST_REF_ARG(FloatingPoint) val) -{ -#ifdef __HLSL_VERSION - return spirv::exp2(val); -#else - return std::exp2(val); -#endif -} - - -template) -inline Integral exp2(NBL_CONST_REF_ARG(Integral) val) +template +inline T exp2(NBL_CONST_REF_ARG(T) x) { - return _static_cast(1ull << val); + return tgmath_impl::exp2_helper::__call(x); } template -inline T log(NBL_CONST_REF_ARG(T) val) +inline T log(NBL_CONST_REF_ARG(T) x) { -#ifdef __HLSL_VERSION - return spirv::log(val); -#else - return std::log(val); -#endif + return tgmath_impl::log_helper::__call(x); } template From 19c30e5aeabc4eb94acca0dcc8ccdd0906e409f6 Mon Sep 17 00:00:00 2001 From: Przemek Date: Mon, 30 Dec 2024 16:00:17 +0100 Subject: [PATCH 30/42] Fixed NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE --- include/nbl/builtin/hlsl/concepts.hlsl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/include/nbl/builtin/hlsl/concepts.hlsl b/include/nbl/builtin/hlsl/concepts.hlsl index 29660b8b45..a22a3bd571 100644 --- a/include/nbl/builtin/hlsl/concepts.hlsl +++ b/include/nbl/builtin/hlsl/concepts.hlsl @@ -68,7 +68,7 @@ concept NBL_CONCEPT_NAME = requires BOOST_PP_EXPR_IF(LOCAL_PARAM_COUNT,(BOOST_PP // #define NBL_IMPL_CONCEPT_REQ_TYPE(...) typename __VA_ARGS__; #define NBL_IMPL_CONCEPT_REQ_EXPR(...) __VA_ARGS__; -#define NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE(E,C,...) {E}; C; +#define NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE(E,C,...) {E}; C; // #define NBL_IMPL_CONCEPT (NBL_IMPL_CONCEPT_REQ_TYPE,NBL_IMPL_CONCEPT_REQ_EXPR,NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE) // @@ -118,9 +118,6 @@ concept any_of = (same_as || ...); template concept scalar = floating_point || integral; -template -concept vectorial = is_vector::value; - template concept matricial = is_matrix::value; @@ -153,7 +150,7 @@ concept matricial = is_matrix::value; // #define NBL_IMPL_CONCEPT_REQ_TYPE(...) ::nbl::hlsl::make_void_t #define NBL_IMPL_CONCEPT_REQ_EXPR(...) ::nbl::hlsl::make_void_t -#define NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE(E,C,...) ::nbl::hlsl::enable_if_t > +#define NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE(E,C,...) ::nbl::hlsl::enable_if_t > // #define NBL_IMPL_CONCEPT_SFINAE (NBL_IMPL_CONCEPT_REQ_TYPE,NBL_IMPL_CONCEPT_REQ_EXPR,NBL_IMPL_CONCEPT_REQ_EXPR_RET_TYPE) // From 2e56fc917dad103bcc6985c71fb1e6e0c7f3653a Mon Sep 17 00:00:00 2001 From: Przemek Date: Mon, 30 Dec 2024 16:01:00 +0100 Subject: [PATCH 31/42] Added Vector and Matrix concepts --- include/nbl/builtin/hlsl/concepts.hlsl | 3 -- include/nbl/builtin/hlsl/concepts/matrix.hlsl | 38 ++++++++++++++++++ include/nbl/builtin/hlsl/concepts/vector.hlsl | 39 +++++++++++++++++++ .../hlsl/matrix_utils/matrix_traits.hlsl | 13 ++++++- 4 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 include/nbl/builtin/hlsl/concepts/matrix.hlsl create mode 100644 include/nbl/builtin/hlsl/concepts/vector.hlsl diff --git a/include/nbl/builtin/hlsl/concepts.hlsl b/include/nbl/builtin/hlsl/concepts.hlsl index a22a3bd571..33450d2501 100644 --- a/include/nbl/builtin/hlsl/concepts.hlsl +++ b/include/nbl/builtin/hlsl/concepts.hlsl @@ -118,9 +118,6 @@ concept any_of = (same_as || ...); template concept scalar = floating_point || integral; -template -concept matricial = is_matrix::value; - #else diff --git a/include/nbl/builtin/hlsl/concepts/matrix.hlsl b/include/nbl/builtin/hlsl/concepts/matrix.hlsl new file mode 100644 index 0000000000..67fe597f80 --- /dev/null +++ b/include/nbl/builtin/hlsl/concepts/matrix.hlsl @@ -0,0 +1,38 @@ +// Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. +// This file is part of the "Nabla Engine". +// For conditions of distribution and use, see copyright notice in nabla.h +#ifndef _NBL_BUILTIN_HLSL_CONCEPTS_MATRIX_INCLUDED_ +#define _NBL_BUILTIN_HLSL_CONCEPTS_MATRIX_INCLUDED_ + + +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace concepts +{ + +template +NBL_BOOL_CONCEPT Matrix = is_matrix::value; + +#define NBL_CONCEPT_NAME Matricial +#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +#define NBL_CONCEPT_TPLT_PRM_NAMES (T) +NBL_CONCEPT_BEGIN(0) +NBL_CONCEPT_END( + ((NBL_CONCEPT_REQ_TYPE)(matrix_traits::scalar_type)) + ((NBL_CONCEPT_REQ_TYPE)(matrix_traits::row_type)) + ((NBL_CONCEPT_REQ_TYPE)(matrix_traits::transposed_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matrix_traits::RowCount), ::nbl::hlsl::is_integral_v)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matrix_traits::ColumnCount), ::nbl::hlsl::is_integral_v)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matrix_traits::Square), ::nbl::hlsl::is_same_v, bool)) +); +#include + +} +} +} +#endif \ No newline at end of file diff --git a/include/nbl/builtin/hlsl/concepts/vector.hlsl b/include/nbl/builtin/hlsl/concepts/vector.hlsl new file mode 100644 index 0000000000..9e239b4f35 --- /dev/null +++ b/include/nbl/builtin/hlsl/concepts/vector.hlsl @@ -0,0 +1,39 @@ +// Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. +// This file is part of the "Nabla Engine". +// For conditions of distribution and use, see copyright notice in nabla.h +#ifndef _NBL_BUILTIN_HLSL_CONCEPTS_VECTOR_INCLUDED_ +#define _NBL_BUILTIN_HLSL_CONCEPTS_VECTOR_INCLUDED_ + + +#include +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace concepts +{ + +template +NBL_BOOL_CONCEPT Vector = is_vector::value; + +// declare concept +#define NBL_CONCEPT_NAME Vectorial +#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +#define NBL_CONCEPT_TPLT_PRM_NAMES (T) + +NBL_CONCEPT_BEGIN(0) +NBL_CONCEPT_END +( + ((NBL_CONCEPT_REQ_TYPE)(vector_traits::scalar_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((vector_traits::Dimension), ::nbl::hlsl::is_integral_v)) +); + +#include + +} +} +} +#endif \ No newline at end of file diff --git a/include/nbl/builtin/hlsl/matrix_utils/matrix_traits.hlsl b/include/nbl/builtin/hlsl/matrix_utils/matrix_traits.hlsl index 1da0c7764d..85adcce6ae 100644 --- a/include/nbl/builtin/hlsl/matrix_utils/matrix_traits.hlsl +++ b/include/nbl/builtin/hlsl/matrix_utils/matrix_traits.hlsl @@ -25,10 +25,21 @@ struct matrix_traits > \ NBL_CONSTEXPR_STATIC_INLINE bool Square = RowCount == ColumnCount; \ }; +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(1, 2) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(1, 3) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(1, 4) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(2, 1) DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(2, 2) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(2, 3) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(2, 4) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(3, 1) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(3, 2) DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(3, 3) -DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(4, 4) DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(3, 4) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(4, 1) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(4, 2) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(4, 3) +DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(4, 4) #undef DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION From f99ad102efbbe7a28f7a3ad15c6cfbc5482dcc58 Mon Sep 17 00:00:00 2001 From: Przemek Date: Mon, 30 Dec 2024 17:56:50 +0100 Subject: [PATCH 32/42] Added `all` and `any` --- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 46 +++++++++++++++++++ .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 12 +++++ 2 files changed, 58 insertions(+) diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 8efca3b403..4dc27d9d9b 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -781,6 +781,52 @@ struct rsqrt_helper +struct all_helper; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v && is_same_v::scalar_type, bool>) +struct all_helper && is_same_v::scalar_type, bool>) > +{ + static bool __call(NBL_CONST_REF_ARG(BooleanVector) x) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + bool output = true; + for (uint32_t i = 0; i < traits::Dimension; ++i) + output = output && getter(x, i); + + return output; + } +}; + +// ANY + +template +struct any_helper; + +template +NBL_PARTIAL_REQ_TOP(is_vector_v&& is_same_v::scalar_type, bool>) +struct any_helper&& is_same_v::scalar_type, bool>) > +{ + static bool __call(NBL_CONST_REF_ARG(BooleanVector) x) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + bool output = false; + for (uint32_t i = 0; i < traits::Dimension; ++i) + output = output || getter(x, i); + + return output; + } +}; + } } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index eeda67f73c..6da1b8a317 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -128,6 +128,18 @@ inline Integer bitReverse(Integer val) return cpp_compat_intrinsics_impl::bitReverse_helper::__call(val); } +template +inline bool all(Vector vec) +{ + return cpp_compat_intrinsics_impl::all_helper::__call(vec); +} + +template +inline bool any(Vector vec) +{ + return cpp_compat_intrinsics_impl::any_helper::__call(vec); +} + } } From 9a8842db294e9d4803b63b2d294bccb923f8d4f2 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 3 Jan 2025 15:25:57 +0700 Subject: [PATCH 33/42] fix cmakelist duplicate entry, float literal --- include/nbl/builtin/hlsl/math/functions.hlsl | 2 +- src/nbl/builtin/CMakeLists.txt | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/nbl/builtin/hlsl/math/functions.hlsl b/include/nbl/builtin/hlsl/math/functions.hlsl index 82aaca651e..adb83c950c 100644 --- a/include/nbl/builtin/hlsl/math/functions.hlsl +++ b/include/nbl/builtin/hlsl/math/functions.hlsl @@ -195,7 +195,7 @@ struct refract static vector_type doReflectRefract(bool _refract, vector_type _I, vector_type _N, T _NdotI, T _NdotTorR, T _rcpOrientedEta) { - return _N * (_NdotI * (_refract ? _rcpOrientedEta : 1.0) + _NdotTorR) - _I * (_refract ? _rcpOrientedEta : 1.0); + return _N * (_NdotI * (_refract ? _rcpOrientedEta : 1.0f) + _NdotTorR) - _I * (_refract ? _rcpOrientedEta : 1.0f); } vector_type doReflectRefract(bool r) diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index 6781d14929..78809c5c1e 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -223,9 +223,7 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/portable/matrix_t.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/ieee754.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/ieee754/impl.hlsl") # utility -LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/tgmath.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/array_accessors.hlsl") -LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/matrix_traits.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/vector_utils/vector_traits.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/matrix_traits.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/matrix_utils/mul_output_t.hlsl") From 274e56fb3bb498666b210c8f6b2687ddadacabcc Mon Sep 17 00:00:00 2001 From: Przemek Date: Fri, 3 Jan 2025 18:19:35 +0100 Subject: [PATCH 34/42] Integrated concepts into tgmath.hlsl and intrinsics.hlsl --- include/nbl/builtin/hlsl/concepts.hlsl | 43 -- include/nbl/builtin/hlsl/concepts/core.hlsl | 97 ++++ include/nbl/builtin/hlsl/concepts/matrix.hlsl | 11 +- include/nbl/builtin/hlsl/concepts/vector.hlsl | 47 +- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 88 ++-- .../nbl/builtin/hlsl/emulated/vector_t.hlsl | 1 + .../nbl/builtin/hlsl/impl/tgmath_impl.hlsl | 490 +++++++++++++++--- .../builtin/hlsl/math/equations/quartic.hlsl | 2 +- include/nbl/builtin/hlsl/shapes/beziers.hlsl | 2 +- .../hlsl/spirv_intrinsics/glsl.std.450.hlsl | 23 + include/nbl/builtin/hlsl/tgmath.hlsl | 93 ++-- .../hlsl/vector_utils/vector_traits.hlsl | 20 +- 12 files changed, 688 insertions(+), 229 deletions(-) create mode 100644 include/nbl/builtin/hlsl/concepts/core.hlsl diff --git a/include/nbl/builtin/hlsl/concepts.hlsl b/include/nbl/builtin/hlsl/concepts.hlsl index 33450d2501..c057fb0aff 100644 --- a/include/nbl/builtin/hlsl/concepts.hlsl +++ b/include/nbl/builtin/hlsl/concepts.hlsl @@ -77,50 +77,8 @@ concept NBL_CONCEPT_NAME = requires BOOST_PP_EXPR_IF(LOCAL_PARAM_COUNT,(BOOST_PP #define NBL_CONCEPT_END(SEQ) BOOST_PP_SEQ_FOR_EACH_I(NBL_IMPL_CONCEPT_END_DEF, DUMMY, SEQ) \ } - -#include - -// Alias some of the std concepts in nbl. As this is C++20 only, we don't need to use -// the macros here. -template -concept same_as = std::same_as; - -template -concept derived_from = std::derived_from; - -template -concept convertible_to = std::convertible_to; - -template -concept assignable_from = std::assignable_from; - -template -concept common_with = std::common_with; - -template -concept integral = std::integral; - -template -concept signed_integral = std::signed_integral; - -template -concept unsigned_integral = std::unsigned_integral; - -template -concept floating_point = std::floating_point; - - -// Some other useful concepts. - -template -concept any_of = (same_as || ...); - -template -concept scalar = floating_point || integral; - #else - // to define a concept using `concept Name = SomeContexprBoolCondition;` #define NBL_BOOL_CONCEPT NBL_CONSTEXPR bool @@ -138,7 +96,6 @@ concept scalar = floating_point || integral; // condition, use instead of the closing `>` of a function template #define NBL_FUNC_REQUIRES(...) ,::nbl::hlsl::enable_if_t<(__VA_ARGS__),bool> = true> - // #define NBL_CONCEPT_BEGIN(LOCAL_PARAM_COUNT) namespace BOOST_PP_CAT(__concept__,NBL_CONCEPT_NAME) \ { diff --git a/include/nbl/builtin/hlsl/concepts/core.hlsl b/include/nbl/builtin/hlsl/concepts/core.hlsl new file mode 100644 index 0000000000..e02d3ecb72 --- /dev/null +++ b/include/nbl/builtin/hlsl/concepts/core.hlsl @@ -0,0 +1,97 @@ +// Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. +// This file is part of the "Nabla Engine". +// For conditions of distribution and use, see copyright notice in nabla.h +#ifndef _NBL_BUILTIN_HLSL_CONCEPTS_CORE_HLSL_INCLUDED_ +#define _NBL_BUILTIN_HLSL_CONCEPTS_CORE_HLSL_INCLUDED_ + + +#include +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace concepts +{ + +#ifdef __cpp_concepts // CPP + +#include + +// Alias some of the std concepts in nbl. As this is C++20 only, we don't need to use +// the macros here. +template +concept same_as = std::same_as; + +template +concept derived_from = std::derived_from; + +template +concept convertible_to = std::convertible_to; + +template +concept assignable_from = std::assignable_from; + +template +concept common_with = std::common_with; + +template +concept integral = std::integral; + +template +concept signed_integral = std::signed_integral; + +template +concept unsigned_integral = std::unsigned_integral; + +template +concept floating_point = std::floating_point; + +// Some other useful concepts. + +template +concept any_of = (same_as || ...); + +template +concept scalar = floating_point || integral; + +#elif defined(__HLSL_VERSION) // HLSL + +template +NBL_BOOL_CONCEPT same_as = is_same_v; + +// TODO: implement when hlsl::is_base_of is done +//#define NBL_CONCEPT_NAME derived_from +// ... + +// TODO: implement when hlsl::is_converible is done +//#define NBL_CONCEPT_NAME convertible_to +// ... + +// TODO? +//#define NBL_CONCEPT_NAME assignable_from + +// TODO? +//template +//concept common_with = std::common_with; + +template +NBL_BOOL_CONCEPT integral = nbl::hlsl::is_integral_v && nbl::hlsl::is_scalar_v; + +template +NBL_BOOL_CONCEPT signed_integral = nbl::hlsl::is_signed_v && nbl::hlsl::is_integral_v && nbl::hlsl::is_scalar_v; + +template +NBL_BOOL_CONCEPT unsigned_integral = !nbl::hlsl::is_signed_v && ::nbl::hlsl::is_integral_v && nbl::hlsl::is_scalar_v; + +template +NBL_BOOL_CONCEPT floating_point = nbl::hlsl::is_floating_point_v && nbl::hlsl::is_scalar_v; + +#endif + +} +} +} +#endif \ No newline at end of file diff --git a/include/nbl/builtin/hlsl/concepts/matrix.hlsl b/include/nbl/builtin/hlsl/concepts/matrix.hlsl index 67fe597f80..4d8b22dd88 100644 --- a/include/nbl/builtin/hlsl/concepts/matrix.hlsl +++ b/include/nbl/builtin/hlsl/concepts/matrix.hlsl @@ -1,8 +1,8 @@ // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h -#ifndef _NBL_BUILTIN_HLSL_CONCEPTS_MATRIX_INCLUDED_ -#define _NBL_BUILTIN_HLSL_CONCEPTS_MATRIX_INCLUDED_ +#ifndef _NBL_BUILTIN_HLSL_CONCEPTS_MATRIX_HLSL_INCLUDED_ +#define _NBL_BUILTIN_HLSL_CONCEPTS_MATRIX_HLSL_INCLUDED_ #include @@ -28,10 +28,15 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(matrix_traits::transposed_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matrix_traits::RowCount), ::nbl::hlsl::is_integral_v)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matrix_traits::ColumnCount), ::nbl::hlsl::is_integral_v)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matrix_traits::Square), ::nbl::hlsl::is_same_v, bool)) + // TODO: fix + //((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matrix_traits::Square), ::nbl::hlsl::is_same_v, bool)) ); #include +#undef NBL_CONCEPT_NAME +#undef NBL_CONCEPT_TPLT_PRM_KINDS +#undef NBL_CONCEPT_TPLT_PRM_NAMES + } } } diff --git a/include/nbl/builtin/hlsl/concepts/vector.hlsl b/include/nbl/builtin/hlsl/concepts/vector.hlsl index 9e239b4f35..86bd9833c5 100644 --- a/include/nbl/builtin/hlsl/concepts/vector.hlsl +++ b/include/nbl/builtin/hlsl/concepts/vector.hlsl @@ -1,11 +1,12 @@ // Copyright (C) 2024-2025 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h -#ifndef _NBL_BUILTIN_HLSL_CONCEPTS_VECTOR_INCLUDED_ -#define _NBL_BUILTIN_HLSL_CONCEPTS_VECTOR_INCLUDED_ +#ifndef _NBL_BUILTIN_HLSL_CONCEPTS_VECTOR_HLSL_INCLUDED_ +#define _NBL_BUILTIN_HLSL_CONCEPTS_VECTOR_HLSL_INCLUDED_ #include +#include #include #include @@ -16,23 +17,43 @@ namespace hlsl namespace concepts { +//! Concept for native vectors. template NBL_BOOL_CONCEPT Vector = is_vector::value; +template +NBL_BOOL_CONCEPT FloatingPointVector = concepts::Vector && concepts::floating_point::scalar_type>; +template +NBL_BOOL_CONCEPT IntVector = concepts::Vector && (is_integral_v::scalar_type>); +template +NBL_BOOL_CONCEPT SignedIntVector = concepts::Vector && concepts::signed_integral::scalar_type>; + +//! Concept for native vectors and vector like structs. +//! The only requirement for a structure to be Vectorial is that a correct template specialization of the `vector_traits` structure should be created for it. +//#define NBL_CONCEPT_NAME Vectorial +//#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +//#define NBL_CONCEPT_TPLT_PRM_NAMES (T) +// +//NBL_CONCEPT_BEGIN(0) +//NBL_CONCEPT_END +//( +// ((NBL_CONCEPT_REQ_TYPE)(vector_traits::scalar_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((vector_traits::Dimension), ::nbl::hlsl::is_integral_v)) +// // TODO: fix +// //((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((vector_traits::IsVector), ::nbl::hlsl::is_same_v, bool)) +//) && vector_traits::isVector; -// declare concept -#define NBL_CONCEPT_NAME Vectorial -#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -#define NBL_CONCEPT_TPLT_PRM_NAMES (T) - -NBL_CONCEPT_BEGIN(0) -NBL_CONCEPT_END -( - ((NBL_CONCEPT_REQ_TYPE)(vector_traits::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((vector_traits::Dimension), ::nbl::hlsl::is_integral_v)) -); +template +NBL_BOOL_CONCEPT Vectorial = vector_traits::IsVector; #include +template +NBL_BOOL_CONCEPT FloatingPointVectorial = concepts::Vectorial && concepts::floating_point::scalar_type>; +template +NBL_BOOL_CONCEPT IntVectorial = concepts::Vectorial && (is_integral_v::scalar_type>); +template +NBL_BOOL_CONCEPT SignedIntVectorial = concepts::Vectorial && concepts::signed_integral::scalar_type>; + } } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 4dc27d9d9b..cc2268eebd 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -8,6 +8,8 @@ #include #include #include +#include +#include #ifndef __HLSL_VERSION #include @@ -63,13 +65,15 @@ DEFINE_BUILTIN_VECTOR_SPECIALIZATION(float64_t, BUILTIN_VECTOR_SPECIALIZATION_RE #undef BUILTIN_VECTOR_SPECIALIZATION_RET_VAL #undef DEFINE_BUILTIN_VECTOR_SPECIALIZATION +// CROSS + template struct cross_helper; //! this specialization will work only with hlsl::vector type template -NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_vector_v && (vector_traits::Dimension == 3)) -struct cross_helper&& is_vector_v&& (vector_traits::Dimension == 3)) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointVector && (vector_traits::Dimension == 3)) +struct cross_helper && (vector_traits::Dimension == 3)) > { static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) lhs, NBL_CONST_REF_ARG(FloatingPointVector) rhs) { @@ -86,12 +90,14 @@ struct cross_helper struct clamp_helper; template -NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_scalar_v) -struct clamp_helper && is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::floating_point) +struct clamp_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) val, NBL_CONST_REF_ARG(FloatingPoint) min, NBL_CONST_REF_ARG(FloatingPoint) max) { @@ -104,8 +110,8 @@ struct clamp_helper -NBL_PARTIAL_REQ_TOP(is_integral_v && !is_signed_v && is_scalar_v) -struct clamp_helper && !is_signed_v&& is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::unsigned_integral) +struct clamp_helper) > { static UnsignedInteger __call(NBL_CONST_REF_ARG(UnsignedInteger) val, NBL_CONST_REF_ARG(UnsignedInteger) min, NBL_CONST_REF_ARG(UnsignedInteger) max) { @@ -118,8 +124,8 @@ struct clamp_helper -NBL_PARTIAL_REQ_TOP(is_integral_v && is_signed_v&& is_scalar_v) -struct clamp_helper&& is_signed_v&& is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::signed_integral) +struct clamp_helper) > { static Integer __call(NBL_CONST_REF_ARG(Integer) val, NBL_CONST_REF_ARG(Integer) min, NBL_CONST_REF_ARG(Integer) max) { @@ -149,6 +155,8 @@ struct clamp_helper) > } }; +// FIND_MSB + template struct find_msb_helper; @@ -262,6 +270,8 @@ struct find_msb_helper #endif +// FIND_LSB + template struct find_lsb_helper; @@ -388,12 +398,14 @@ struct find_msb_return_type > template using find_lsb_return_type = find_msb_return_type; +// BIT_REVERSE + template struct bitReverse_helper; template -NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v && hlsl::is_scalar_v) -struct bitReverse_helper&& hlsl::is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::signed_integral) +struct bitReverse_helper) > { static inline Integer __call(NBL_CONST_REF_ARG(Integer) val) { @@ -407,7 +419,7 @@ struct bitReverse_helper NBL_PARTIAL_REQ_TOP(hlsl::is_vector_v) -struct bitReverse_helper && hlsl::is_vector_v) > +struct bitReverse_helper) > { static Vector __call(NBL_CONST_REF_ARG(Vector) vec) { @@ -450,20 +462,22 @@ struct mul_helper } }; +// BITCOUNT + // TODO: some struct that with other functions, since more functions will need that.. template struct bitcount_output; template -NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v && hlsl::is_scalar_v) -struct bitcount_output&& hlsl::is_scalar_v) > +NBL_PARTIAL_REQ_TOP(is_integral_v) +struct bitcount_output) > { using type = int32_t; }; template -NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v && hlsl::is_vector_v) -struct bitcount_output && hlsl::is_vector_v) > +NBL_PARTIAL_REQ_TOP(concepts::IntVector) +struct bitcount_output) > { using type = vector::Dimension>; }; @@ -484,8 +498,8 @@ template struct bitCount_helper; template -NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v&& hlsl::is_scalar_v) -struct bitCount_helper&& hlsl::is_scalar_v) > +NBL_PARTIAL_REQ_TOP(is_integral_v) +struct bitCount_helper) > { static bitcount_output_t __call(NBL_CONST_REF_ARG(Integer) val) { @@ -510,8 +524,8 @@ struct bitCount_helper& }; template -NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v && hlsl::is_vector_v) -struct bitCount_helper && hlsl::is_vector_v) > +NBL_PARTIAL_REQ_TOP(concepts::IntVectorial) +struct bitCount_helper) > { static bitcount_output_t __call(NBL_CONST_REF_ARG(Vector) vec) { @@ -545,8 +559,8 @@ template struct length_helper; template -NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v&& hlsl::is_vector_v) -struct length_helper&& hlsl::is_vector_v) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointVector) +struct length_helper) > { static inline typename vector_traits::scalar_type __call(NBL_CONST_REF_ARG(Vector) vec) { @@ -562,8 +576,8 @@ template struct normalize_helper; template -NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v && hlsl::is_vector_v) -struct normalize_helper && hlsl::is_vector_v) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointVector) +struct normalize_helper) > { static inline Vector __call(NBL_CONST_REF_ARG(Vector) vec) { @@ -581,8 +595,8 @@ template struct min_helper; template -NBL_PARTIAL_REQ_TOP(is_floating_point_v&& is_scalar_v) -struct min_helper&& is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::floating_point) +struct min_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) a, NBL_CONST_REF_ARG(FloatingPoint) b) { @@ -595,8 +609,8 @@ struct min_helper -NBL_PARTIAL_REQ_TOP(is_integral_v && !is_signed_v&& is_scalar_v) -struct min_helper && !is_signed_v&& is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::unsigned_integral) +struct min_helper) > { static UnsignedInteger __call(NBL_CONST_REF_ARG(UnsignedInteger) a, NBL_CONST_REF_ARG(UnsignedInteger) b) { @@ -609,8 +623,8 @@ struct min_helper -NBL_PARTIAL_REQ_TOP(is_integral_v&& is_signed_v&& is_scalar_v) -struct min_helper&& is_signed_v&& is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::signed_integral) +struct min_helper) > { static Integer __call(NBL_CONST_REF_ARG(Integer) a, NBL_CONST_REF_ARG(Integer) b) { @@ -646,8 +660,8 @@ template struct max_helper; template -NBL_PARTIAL_REQ_TOP(is_floating_point_v&& is_scalar_v) -struct max_helper&& is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::floating_point) +struct max_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) a, NBL_CONST_REF_ARG(FloatingPoint) b) { @@ -688,8 +702,8 @@ struct max_helper&& is_signed }; template -NBL_PARTIAL_REQ_TOP(is_vector_v) -struct max_helper) > +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct max_helper) > { static Vector __call(NBL_CONST_REF_ARG(Vector) a, NBL_CONST_REF_ARG(Vector) b) { @@ -749,8 +763,8 @@ template struct rsqrt_helper; template -NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_scalar_v) -struct rsqrt_helper && is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::floating_point) +struct rsqrt_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -764,8 +778,8 @@ struct rsqrt_helper -NBL_PARTIAL_REQ_TOP(is_vector_v && is_floating_point_v::scalar_type>) -struct rsqrt_helper&& is_floating_point_v::scalar_type>) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointVectorial) +struct rsqrt_helper) > { static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) x) { diff --git a/include/nbl/builtin/hlsl/emulated/vector_t.hlsl b/include/nbl/builtin/hlsl/emulated/vector_t.hlsl index 68fe23f355..62df0502b1 100644 --- a/include/nbl/builtin/hlsl/emulated/vector_t.hlsl +++ b/include/nbl/builtin/hlsl/emulated/vector_t.hlsl @@ -412,6 +412,7 @@ struct vector_traits >\ {\ using scalar_type = T;\ NBL_CONSTEXPR_STATIC_INLINE uint32_t Dimension = DIMENSION;\ + NBL_CONSTEXPR_STATIC_INLINE bool IsVector = true;\ };\ DEFINE_SCALAR_OF_SPECIALIZATION(2) diff --git a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl index b2828ea684..485e524aa5 100644 --- a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl +++ b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -57,6 +58,8 @@ DEFINE_LERP_HELPER_COMMON_SPECIALIZATION(float64_t) #undef DEFINE_LERP_HELPER_COMMON_SPECIALIZATION #undef MIX_FUNCTION +// LERP + template struct lerp_helper { @@ -83,13 +86,57 @@ struct lerp_helper, vector > } }; -template&& hlsl::is_unsigned_v) +// ISNAN + +template && hlsl::is_unsigned_v) inline bool isnan_uint_impl(UnsignedInteger val) { using AsFloat = typename float_of_size::type; return bool((ieee754::extractBiasedExponent(val) == ieee754::traits::specialValueExp) && (val & ieee754::traits::mantissaMask)); } +template +struct isnan_helper; + +template +NBL_PARTIAL_REQ_TOP(concepts::floating_point) +struct isnan_helper) > +{ + static bool __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { +#ifdef __HLSL_VERSION + return spirv::isNan(x); +#else + // GCC and Clang will always return false with call to std::isnan when fast math is enabled, + // this implementation will always return appropriate output regardless is fas math is enabled or not + using AsUint = typename unsigned_integer_of_size::type; + return tgmath_impl::isnan_uint_impl(reinterpret_cast(x)); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct isnan_helper) > +{ + using output_t = vector::Dimension>; + + static output_t __call(NBL_CONST_REF_ARG(V) vec) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + output_t output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, isnan_helper::__call(getter(vec, i))); + + return output; + } +}; + +// ISINF + template&& hlsl::is_unsigned_v) inline bool isinf_uint_impl(UnsignedInteger val) { @@ -97,12 +144,54 @@ inline bool isinf_uint_impl(UnsignedInteger val) return (val & (~ieee754::traits::signMask)) == ieee754::traits::inf; } +template +struct isinf_helper; + +template +NBL_PARTIAL_REQ_TOP(concepts::floating_point) +struct isinf_helper) > +{ + static bool __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { +#ifdef __HLSL_VERSION + return spirv::isInf(x); +#else + // GCC and Clang will always return false with call to std::isinf when fast math is enabled, + // this implementation will always return appropriate output regardless is fas math is enabled or not + using AsUint = typename unsigned_integer_of_size::type; + return tgmath_impl::isinf_uint_impl(reinterpret_cast(x)); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct isinf_helper) > +{ + using output_t = vector::Dimension>; + + static output_t __call(NBL_CONST_REF_ARG(V) x) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + output_t output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, isinf_helper::__call(getter(x, i))); + + return output; + } +}; + +// FLOOR + template struct floor_helper; template NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v && hlsl::is_scalar_v) -struct floor_helper&& hlsl::is_scalar_v) > +struct floor_helper && hlsl::is_scalar_v) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) val) { @@ -114,17 +203,17 @@ struct floor_helper -NBL_PARTIAL_REQ_TOP(hlsl::is_floating_point_v && hlsl::is_vector_v) -struct floor_helper && hlsl::is_vector_v) > +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct floor_helper) > { - static Vector __call(NBL_CONST_REF_ARG(Vector) vec) + static V __call(NBL_CONST_REF_ARG(V) vec) { - using traits = hlsl::vector_traits; - array_get getter; - array_set setter; + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; - Vector output; + V output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, floor_helper::__call(getter(vec, i))); @@ -138,8 +227,8 @@ template struct erf_helper; template -NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_scalar_v) -struct erf_helper&& is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::floating_point) +struct erf_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) _x) { @@ -170,8 +259,8 @@ template struct erfInv_helper; template -NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_scalar_v) -struct erfInv_helper && is_scalar_v) > +NBL_PARTIAL_REQ_TOP(concepts::floating_point) +struct erfInv_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) _x) { @@ -222,8 +311,8 @@ template struct pow_helper; template -NBL_PARTIAL_REQ_TOP(is_floating_point_v&& is_scalar_v && (sizeof(FloatingPoint) <= 4)) -struct pow_helper&& is_scalar_v && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) +struct pow_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x, NBL_CONST_REF_ARG(FloatingPoint) y) { @@ -235,17 +324,31 @@ struct pow_helper -NBL_PARTIAL_REQ_TOP(is_vector_v&& is_floating_point_v::scalar_type>) -struct pow_helper&& is_floating_point_v::scalar_type>) > +template +NBL_PARTIAL_REQ_TOP(is_same::value) +struct pow_helper::value) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x, NBL_CONST_REF_ARG(Float64) y) + { +#ifdef __HLSL_VERSION + return pow(x, y); +#else + return std::pow(x, y); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct pow_helper) > { - static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) x, NBL_CONST_REF_ARG(FloatingPointVector) y) + static V __call(NBL_CONST_REF_ARG(V) x, NBL_CONST_REF_ARG(V) y) { - using traits = hlsl::vector_traits; - array_get getter; - array_set setter; + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; - FloatingPointVector output; + V output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, pow_helper::__call(getter(x, i), getter(y, i))); @@ -259,8 +362,8 @@ template struct exp_helper; template -NBL_PARTIAL_REQ_TOP(is_floating_point_v&& is_scalar_v && (sizeof(FloatingPoint) <= 4)) -struct exp_helper&& is_scalar_v && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) +struct exp_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -272,17 +375,31 @@ struct exp_helper -NBL_PARTIAL_REQ_TOP(is_vector_v&& is_floating_point_v::scalar_type>) -struct exp_helper&& is_floating_point_v::scalar_type>) > +template +NBL_PARTIAL_REQ_TOP(is_same::value) +struct exp_helper::value) > { - static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) x) + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) { - using traits = hlsl::vector_traits; - array_get getter; - array_set setter; +#ifdef __HLSL_VERSION + return exp(x); +#else + return std::exp(x); +#endif + } +}; - FloatingPointVector output; +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct exp_helper) > +{ + static V __call(NBL_CONST_REF_ARG(V) x) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + V output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, exp_helper::__call(getter(x, i))); @@ -296,8 +413,8 @@ template struct exp2_helper; template -NBL_PARTIAL_REQ_TOP(is_floating_point_v&& is_scalar_v && (sizeof(FloatingPoint) <= 4)) -struct exp2_helper && is_scalar_v && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) +struct exp2_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -309,21 +426,17 @@ struct exp2_helper -NBL_PARTIAL_REQ_TOP(is_vector_v && is_floating_point_v::scalar_type>) -struct exp2_helper && is_floating_point_v::scalar_type>) > +template +NBL_PARTIAL_REQ_TOP(is_same::value) +struct exp2_helper::value) > { - static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) x) + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) { - using traits = hlsl::vector_traits; - array_get getter; - array_set setter; - - FloatingPointVector output; - for (uint32_t i = 0; i < traits::Dimension; ++i) - setter(output, i, exp2_helper::__call(getter(x, i))); - - return output; +#ifdef __HLSL_VERSION + return exp2(x); +#else + return std::exp2(x); +#endif } }; @@ -337,19 +450,19 @@ struct exp2_helper && } }; -template -NBL_PARTIAL_REQ_TOP(is_vector_v && is_integral_v::scalar_type>) -struct exp2_helper&& is_integral_v::scalar_type>) > +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct exp2_helper) > { - static Integral __call(NBL_CONST_REF_ARG(Integral) x) + static V __call(NBL_CONST_REF_ARG(V) vec) { - using traits = hlsl::vector_traits; - array_get getter; - array_set setter; + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; - Integral output; + V output; for (uint32_t i = 0; i < traits::Dimension; ++i) - setter(output, i, exp2_helper::__call(getter(x, i))); + setter(output, i, exp2_helper::__call(getter(vec, i))); return output; } @@ -361,8 +474,8 @@ template struct log_helper; template -NBL_PARTIAL_REQ_TOP(is_floating_point_v && is_scalar_v && (sizeof(FloatingPoint) <= 4)) -struct log_helper && is_scalar_v && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) +struct log_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -388,17 +501,17 @@ struct log_helper::value } }; -template -NBL_PARTIAL_REQ_TOP(is_vector_v&& is_floating_point_v::scalar_type>) -struct log_helper&& is_floating_point_v::scalar_type>) > +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct log_helper) > { - static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) x) + static V __call(NBL_CONST_REF_ARG(V) x) { - using traits = hlsl::vector_traits; - array_get getter; - array_set setter; + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; - FloatingPointVector output; + V output; for (uint32_t i = 0; i < traits::Dimension; ++i) setter(output, i, log_helper::__call(getter(x, i))); @@ -406,6 +519,247 @@ struct log_helper +struct abs_helper; + +template +NBL_PARTIAL_REQ_TOP(concepts::floating_point) +struct abs_helper) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { +#ifdef __HLSL_VERSION + return spirv::fAbs(x); +#else + return std::abs(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_signed_v && is_integral_v && is_scalar_v) +struct abs_helper && is_integral_v && is_scalar_v) > +{ + static SignedInteger __call(NBL_CONST_REF_ARG(SignedInteger) x) + { +#ifdef __HLSL_VERSION + return spirv::sAbs(x); +#else + return std::abs(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct abs_helper) > +{ + static V __call(NBL_CONST_REF_ARG(V) vec) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + V output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, abs_helper::__call(getter(vec, i))); + + return output; + } +}; + +// SQRT + +template +struct sqrt_helper; + +template +NBL_PARTIAL_REQ_TOP(concepts::floating_point) +struct sqrt_helper) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { +#ifdef __HLSL_VERSION + return spirv::sqrt(x); +#else + return std::sqrt(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct sqrt_helper) > +{ + static V __call(NBL_CONST_REF_ARG(V) vec) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + V output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, sqrt_helper::__call(getter(vec, i))); + + return output; + } +}; + +// SIN + +template +struct sin_helper; + +template +NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) +struct sin_helper && (sizeof(FloatingPoint) <= 4)) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { +#ifdef __HLSL_VERSION + return spirv::sin(x); +#else + return std::sin(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_same::value) +struct sin_helper::value) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { +#ifdef __HLSL_VERSION + return sin(x); +#else + return std::sin(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct sin_helper) > +{ + static V __call(NBL_CONST_REF_ARG(V) vec) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + V output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, sin_helper::__call(getter(vec, i))); + + return output; + } +}; + +// COS + +template +struct cos_helper; + +template +NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) +struct cos_helper && (sizeof(FloatingPoint) <= 4)) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { +#ifdef __HLSL_VERSION + return spirv::cos(x); +#else + return std::cos(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_same::value) +struct cos_helper::value) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { +#ifdef __HLSL_VERSION + return cos(x); +#else + return std::cos(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct cos_helper) > +{ + static V __call(NBL_CONST_REF_ARG(V) vec) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + V output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, cos_helper::__call(getter(vec, i))); + + return output; + } +}; + +// ACOS + +template +struct acos_helper; + +template +NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) +struct acos_helper && (sizeof(FloatingPoint) <= 4)) > +{ + static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) + { +#ifdef __HLSL_VERSION + return spirv::acos(x); +#else + return std::acos(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(is_same::value) +struct acos_helper::value) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { +#ifdef __HLSL_VERSION + return acos(x); +#else + return std::acos(x); +#endif + } +}; + +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct acos_helper) > +{ + static V __call(NBL_CONST_REF_ARG(V) vec) + { + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + V output; + for (uint32_t i = 0; i < traits::Dimension; ++i) + setter(output, i, acos_helper::__call(getter(vec, i))); + + return output; + } +}; + } } } diff --git a/include/nbl/builtin/hlsl/math/equations/quartic.hlsl b/include/nbl/builtin/hlsl/math/equations/quartic.hlsl index 1214f80e7e..8ec658ef03 100644 --- a/include/nbl/builtin/hlsl/math/equations/quartic.hlsl +++ b/include/nbl/builtin/hlsl/math/equations/quartic.hlsl @@ -89,7 +89,7 @@ namespace equations float_t3 cubic = Cubic::construct(1, -1.0 / 2 * p, -r, 1.0 / 2 * r * p - 1.0 / 8 * q * q).computeRoots(); /* ... and take the one real solution ... */ for (uint32_t i = 0; i < 3; i ++) - if (!hlsl::isnan(cubic[i])) + if (!hlsl::isnan(cubic[i])) { z = cubic[i]; break; diff --git a/include/nbl/builtin/hlsl/shapes/beziers.hlsl b/include/nbl/builtin/hlsl/shapes/beziers.hlsl index d4ebe6d0d8..06f0b09efb 100644 --- a/include/nbl/builtin/hlsl/shapes/beziers.hlsl +++ b/include/nbl/builtin/hlsl/shapes/beziers.hlsl @@ -412,7 +412,7 @@ struct Quadratic // p'(1/2) = 2(C-A) // exponent so large it would wipe the mantissa on any relative operation - const float_t PARAMETER_THRESHOLD = exp2(24); + const float_t PARAMETER_THRESHOLD = exp2(24.0f); Candidates candidates; float_t2 Bdiv2 = B*0.5; diff --git a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl index 3a7a7e5115..a1617fd244 100644 --- a/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl +++ b/include/nbl/builtin/hlsl/spirv_intrinsics/glsl.std.450.hlsl @@ -57,6 +57,10 @@ template [[vk::ext_instruction(GLSLstd450::GLSLstd450Log, "GLSL.std.450")]] enable_if_t::value && !is_matrix_v, FloatingPoint> log(FloatingPoint val); +template +[[vk::ext_instruction(GLSLstd450::GLSLstd450Sqrt, "GLSL.std.450")]] +enable_if_t && !is_matrix_v, FloatingPoint> sqrt(FloatingPoint val); + template [[vk::ext_instruction(GLSLstd450::GLSLstd450InverseSqrt, "GLSL.std.450")]] enable_if_t && !is_matrix_v, FloatingPoint> inverseSqrt(FloatingPoint val); @@ -129,6 +133,25 @@ template [[vk::ext_instruction(GLSLstd450SMax, "GLSL.std.450")]] enable_if_t&& is_signed_v, Integer> sMax(Integer val); +template +[[vk::ext_instruction(GLSLstd450FAbs, "GLSL.std.450")]] +enable_if_t, FloatingPoint> fAbs(FloatingPoint val); +template +[[vk::ext_instruction(GLSLstd450SAbs, "GLSL.std.450")]] +enable_if_t && is_signed_v, Integer> sAbs(Integer val); + +template +[[vk::ext_instruction(GLSLstd450Sin, "GLSL.std.450")]] +enable_if_t && (sizeof(FloatingPoint) <= 4), FloatingPoint> sin(FloatingPoint val); + +template +[[vk::ext_instruction(GLSLstd450Cos, "GLSL.std.450")]] +enable_if_t && (sizeof(FloatingPoint) <= 4), FloatingPoint> cos(FloatingPoint val); + +template +[[vk::ext_instruction(GLSLstd450Acos, "GLSL.std.450")]] +enable_if_t && (sizeof(FloatingPoint) <= 4), FloatingPoint> acos(FloatingPoint val); + } } } diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index a226a191fa..0f9663fecf 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -11,6 +11,8 @@ #include #include #include +#include +#include // C++ headers #ifndef __HLSL_VERSION #include @@ -21,129 +23,108 @@ namespace nbl { namespace hlsl { -template +// TODO: will not work for emulated_float as an input because `concepts::floating_point` is only for native floats, fix every occurance +template) inline FloatingPoint erf(FloatingPoint x) { return tgmath_impl::erf_helper::__call(x); } -template +template) inline FloatingPoint erfInv(FloatingPoint x) { return tgmath_impl::erfInv_helper::__call(x); } -template +template || concepts::Vectorial) inline T floor(NBL_CONST_REF_ARG(T) val) { return tgmath_impl::floor_helper::__call(val); } -template +template || concepts::FloatingPointVectorial) && (concepts::floating_point || is_same_v)) inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) { return tgmath_impl::lerp_helper::__call(x, y, a); } -template) +template) inline bool isnan(NBL_CONST_REF_ARG(FloatingPoint) val) { -#ifdef __HLSL_VERSION - return spirv::isNan(val); -#else - // GCC and Clang will always return false with call to std::isnan when fast math is enabled, - // this implementation will always return appropriate output regardless is fas math is enabled or not - using AsUint = typename unsigned_integer_of_size::type; - return tgmath_impl::isnan_uint_impl(reinterpret_cast(val)); -#endif + return tgmath_impl::isnan_helper::__call(val); +} + +template) +inline vector::Dimension> isnan(NBL_CONST_REF_ARG(V) val) +{ + return tgmath_impl::isnan_helper::__call(val); } -template) +template) inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) { -#ifdef __HLSL_VERSION - return spirv::isInf(val); -#else - // GCC and Clang will always return false with call to std::isinf when fast math is enabled, - // this implementation will always return appropriate output regardless is fas math is enabled or not - using AsUint = typename unsigned_integer_of_size::type; - return tgmath_impl::isinf_uint_impl(reinterpret_cast(val)); -#endif + return tgmath_impl::isinf_helper::__call(val); } -template +template) +inline vector::Dimension> isinf(NBL_CONST_REF_ARG(V) val) +{ + return tgmath_impl::isinf_helper::__call(val); +} + +template || concepts::FloatingPointVectorial) inline T pow(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y) { return tgmath_impl::pow_helper::__call(x, y); } -template +template || concepts::FloatingPointVectorial) inline T exp(NBL_CONST_REF_ARG(T) x) { return tgmath_impl::exp_helper::__call(x); } -template +template || concepts::Vectorial) inline T exp2(NBL_CONST_REF_ARG(T) x) { return tgmath_impl::exp2_helper::__call(x); } -template +template || concepts::FloatingPointVectorial) inline T log(NBL_CONST_REF_ARG(T) x) { return tgmath_impl::log_helper::__call(x); } -template +template || concepts::signed_integral || concepts::FloatingPointVectorial || concepts::SignedIntVectorial) inline T abs(NBL_CONST_REF_ARG(T) val) { -#ifdef __HLSL_VERSION - return abs(val); -#else - return glm::abs(val); -#endif + return tgmath_impl::abs_helper::__call(val); } -template +template || concepts::Vectorial) inline T sqrt(NBL_CONST_REF_ARG(T) val) { -#ifdef __HLSL_VERSION - return sqrt(val); -#else - return std::sqrt(val); -#endif + return tgmath_impl::sqrt_helper::__call(val); } -template +template || concepts::Vectorial) inline T sin(NBL_CONST_REF_ARG(T) val) { -#ifdef __HLSL_VERSION - return sin(val); -#else - return std::sin(val); -#endif + return tgmath_impl::sin_helper::__call(val); } -template +template || concepts::Vectorial) inline T cos(NBL_CONST_REF_ARG(T) val) { -#ifdef __HLSL_VERSION - return cos(val); -#else - return std::cos(val); -#endif + return tgmath_impl::cos_helper::__call(val); } -template +template || concepts::Vectorial) inline T acos(NBL_CONST_REF_ARG(T) val) { -#ifdef __HLSL_VERSION - return acos(val); -#else - return std::acos(val); -#endif + return tgmath_impl::acos_helper::__call(val); } } diff --git a/include/nbl/builtin/hlsl/vector_utils/vector_traits.hlsl b/include/nbl/builtin/hlsl/vector_utils/vector_traits.hlsl index a4e54e6b3f..9aefc3b3d8 100644 --- a/include/nbl/builtin/hlsl/vector_utils/vector_traits.hlsl +++ b/include/nbl/builtin/hlsl/vector_utils/vector_traits.hlsl @@ -10,16 +10,22 @@ namespace hlsl // The whole purpose of this file is to enable the creation of partial specializations of the vector_traits for // custom types without introducing circular dependencies. -template -struct vector_traits; +template +struct vector_traits +{ + using scalar_type = T; + NBL_CONSTEXPR_STATIC_INLINE uint32_t Dimension = 1u; + NBL_CONSTEXPR_STATIC_INLINE bool IsVector = false; +}; // i choose to implement it this way because of this DXC bug: https://github.com/microsoft/DirectXShaderCom0piler/issues/7007 -#define DEFINE_VECTOR_TRAITS_TEMPLATE_SPECIALIZATION(DIMENSION) \ +#define DEFINE_VECTOR_TRAITS_TEMPLATE_SPECIALIZATION(DIMENSION)\ template \ -struct vector_traits > \ -{ \ - using scalar_type = T; \ - NBL_CONSTEXPR_STATIC_INLINE uint32_t Dimension = DIMENSION; \ +struct vector_traits >\ +{\ + using scalar_type = T;\ + NBL_CONSTEXPR_STATIC_INLINE uint32_t Dimension = DIMENSION;\ + NBL_CONSTEXPR_STATIC_INLINE bool IsVector = true;\ };\ DEFINE_VECTOR_TRAITS_TEMPLATE_SPECIALIZATION(2) From 6a2bcffb843531c20ba1021caba19e2522009587 Mon Sep 17 00:00:00 2001 From: Przemek Date: Fri, 3 Jan 2025 19:21:54 +0100 Subject: [PATCH 35/42] Added `FloatingPointLike` concept --- include/nbl/builtin/hlsl/concepts/core.hlsl | 13 +++++++++++ include/nbl/builtin/hlsl/concepts/vector.hlsl | 2 ++ .../nbl/builtin/hlsl/emulated/float64_t.hlsl | 13 +++++++++++ include/nbl/builtin/hlsl/tgmath.hlsl | 22 +++++++++---------- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/include/nbl/builtin/hlsl/concepts/core.hlsl b/include/nbl/builtin/hlsl/concepts/core.hlsl index e02d3ecb72..fd54362703 100644 --- a/include/nbl/builtin/hlsl/concepts/core.hlsl +++ b/include/nbl/builtin/hlsl/concepts/core.hlsl @@ -91,6 +91,19 @@ NBL_BOOL_CONCEPT floating_point = nbl::hlsl::is_floating_point_v && nbl::hlsl #endif +namespace impl +{ +template +struct IsEmulatingFloatingPointType +{ + static const bool value = false; +}; +} + +//! Floating point types are native floating point types or types that imitate native floating point types (for example emulated_float64_t) +template +NBL_BOOL_CONCEPT FloatingPointLike = (nbl::hlsl::is_floating_point_v && nbl::hlsl::is_scalar_v) || impl::IsEmulatingFloatingPointType::value; + } } } diff --git a/include/nbl/builtin/hlsl/concepts/vector.hlsl b/include/nbl/builtin/hlsl/concepts/vector.hlsl index 86bd9833c5..f8c46bffe8 100644 --- a/include/nbl/builtin/hlsl/concepts/vector.hlsl +++ b/include/nbl/builtin/hlsl/concepts/vector.hlsl @@ -50,6 +50,8 @@ NBL_BOOL_CONCEPT Vectorial = vector_traits::IsVector; template NBL_BOOL_CONCEPT FloatingPointVectorial = concepts::Vectorial && concepts::floating_point::scalar_type>; template +NBL_BOOL_CONCEPT FloatingPointLikeVectorial = concepts::Vectorial && concepts::FloatingPointLike::scalar_type>; +template NBL_BOOL_CONCEPT IntVectorial = concepts::Vectorial && (is_integral_v::scalar_type>); template NBL_BOOL_CONCEPT SignedIntVectorial = concepts::Vectorial && concepts::signed_integral::scalar_type>; diff --git a/include/nbl/builtin/hlsl/emulated/float64_t.hlsl b/include/nbl/builtin/hlsl/emulated/float64_t.hlsl index c94beaa063..15249f9265 100644 --- a/include/nbl/builtin/hlsl/emulated/float64_t.hlsl +++ b/include/nbl/builtin/hlsl/emulated/float64_t.hlsl @@ -2,6 +2,7 @@ #define _NBL_BUILTIN_HLSL_EMULATED_FLOAT64_T_HLSL_INCLUDED_ #include +#include namespace nbl { @@ -580,6 +581,18 @@ IMPLEMENT_IEEE754_FUNC_SPEC_FOR_EMULATED_F64_TYPE(emulated_float64_t); } +namespace concepts +{ +namespace impl +{ +template +struct IsEmulatingFloatingPointType > +{ + static const bool value = true; +}; +} +} + } } diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index 0f9663fecf..a617389c23 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -24,25 +24,25 @@ namespace nbl namespace hlsl { // TODO: will not work for emulated_float as an input because `concepts::floating_point` is only for native floats, fix every occurance -template) +template) inline FloatingPoint erf(FloatingPoint x) { return tgmath_impl::erf_helper::__call(x); } -template) +template) inline FloatingPoint erfInv(FloatingPoint x) { return tgmath_impl::erfInv_helper::__call(x); } -template || concepts::Vectorial) +template || concepts::Vectorial) inline T floor(NBL_CONST_REF_ARG(T) val) { return tgmath_impl::floor_helper::__call(val); } -template || concepts::FloatingPointVectorial) && (concepts::floating_point || is_same_v)) +template || concepts::FloatingPointLikeVectorial) && (concepts::floating_point || is_same_v)) inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) { return tgmath_impl::lerp_helper::__call(x, y, a); @@ -54,7 +54,7 @@ inline bool isnan(NBL_CONST_REF_ARG(FloatingPoint) val) return tgmath_impl::isnan_helper::__call(val); } -template) +template) inline vector::Dimension> isnan(NBL_CONST_REF_ARG(V) val) { return tgmath_impl::isnan_helper::__call(val); @@ -66,38 +66,38 @@ inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) return tgmath_impl::isinf_helper::__call(val); } -template) +template) inline vector::Dimension> isinf(NBL_CONST_REF_ARG(V) val) { return tgmath_impl::isinf_helper::__call(val); } -template || concepts::FloatingPointVectorial) +template || concepts::FloatingPointLikeVectorial) inline T pow(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y) { return tgmath_impl::pow_helper::__call(x, y); } -template || concepts::FloatingPointVectorial) +template || concepts::FloatingPointLikeVectorial) inline T exp(NBL_CONST_REF_ARG(T) x) { return tgmath_impl::exp_helper::__call(x); } -template || concepts::Vectorial) +template || concepts::Vectorial) inline T exp2(NBL_CONST_REF_ARG(T) x) { return tgmath_impl::exp2_helper::__call(x); } -template || concepts::FloatingPointVectorial) +template || concepts::FloatingPointLikeVectorial) inline T log(NBL_CONST_REF_ARG(T) x) { return tgmath_impl::log_helper::__call(x); } -template || concepts::signed_integral || concepts::FloatingPointVectorial || concepts::SignedIntVectorial) +template || concepts::signed_integral || concepts::FloatingPointLikeVectorial || concepts::SignedIntVectorial) inline T abs(NBL_CONST_REF_ARG(T) val) { return tgmath_impl::abs_helper::__call(val); From 9a44ce8137fd38b26e032abea10be9922a2b1296 Mon Sep 17 00:00:00 2001 From: Przemek Date: Tue, 7 Jan 2025 13:38:22 +0100 Subject: [PATCH 36/42] Refactored concepts --- include/nbl/builtin/hlsl/concepts/core.hlsl | 76 ++++++------------- include/nbl/builtin/hlsl/concepts/vector.hlsl | 10 +-- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 36 ++++----- .../nbl/builtin/hlsl/impl/tgmath_impl.hlsl | 52 ++++++------- include/nbl/builtin/hlsl/tgmath.hlsl | 30 ++++---- 5 files changed, 87 insertions(+), 117 deletions(-) diff --git a/include/nbl/builtin/hlsl/concepts/core.hlsl b/include/nbl/builtin/hlsl/concepts/core.hlsl index fd54362703..5f18e9225a 100644 --- a/include/nbl/builtin/hlsl/concepts/core.hlsl +++ b/include/nbl/builtin/hlsl/concepts/core.hlsl @@ -16,81 +16,51 @@ namespace hlsl namespace concepts { -#ifdef __cpp_concepts // CPP - -#include - -// Alias some of the std concepts in nbl. As this is C++20 only, we don't need to use -// the macros here. -template -concept same_as = std::same_as; - -template -concept derived_from = std::derived_from; - -template -concept convertible_to = std::convertible_to; - -template -concept assignable_from = std::assignable_from; +template +NBL_BOOL_CONCEPT same_as = is_same_v; -template -concept common_with = std::common_with; +template +NBL_BOOL_CONCEPT Integral = nbl::hlsl::is_integral_v; -template -concept integral = std::integral; +template +NBL_BOOL_CONCEPT SignedIntegral = nbl::hlsl::is_signed_v && nbl::hlsl::is_integral_v; -template -concept signed_integral = std::signed_integral; +template +NBL_BOOL_CONCEPT UnsignedIntegral = !nbl::hlsl::is_signed_v && ::nbl::hlsl::is_integral_v; -template -concept unsigned_integral = std::unsigned_integral; +template +NBL_BOOL_CONCEPT FloatingPoint = nbl::hlsl::is_floating_point_v; template -concept floating_point = std::floating_point; +NBL_BOOL_CONCEPT scalar = FloatingPoint || Integral; -// Some other useful concepts. - -template -concept any_of = (same_as || ...); +template +NBL_BOOL_CONCEPT IntegralScalar = nbl::hlsl::is_integral_v && nbl::hlsl::is_scalar_v; -template -concept scalar = floating_point || integral; +template +NBL_BOOL_CONCEPT SignedIntegralScalar = nbl::hlsl::is_signed_v && nbl::hlsl::is_integral_v && nbl::hlsl::is_scalar_v; -#elif defined(__HLSL_VERSION) // HLSL +template +NBL_BOOL_CONCEPT UnsignedIntegralScalar = !nbl::hlsl::is_signed_v && ::nbl::hlsl::is_integral_v && nbl::hlsl::is_scalar_v; -template -NBL_BOOL_CONCEPT same_as = is_same_v; +template +NBL_BOOL_CONCEPT FloatingPointScalar = nbl::hlsl::is_floating_point_v && nbl::hlsl::is_scalar_v; // TODO: implement when hlsl::is_base_of is done -//#define NBL_CONCEPT_NAME derived_from +//#define NBL_CONCEPT_NAME DerivedFrom // ... // TODO: implement when hlsl::is_converible is done -//#define NBL_CONCEPT_NAME convertible_to +//#define NBL_CONCEPT_NAME ConvertibleTo // ... // TODO? -//#define NBL_CONCEPT_NAME assignable_from +//#define NBL_CONCEPT_NAME AssignableFrom // TODO? //template //concept common_with = std::common_with; -template -NBL_BOOL_CONCEPT integral = nbl::hlsl::is_integral_v && nbl::hlsl::is_scalar_v; - -template -NBL_BOOL_CONCEPT signed_integral = nbl::hlsl::is_signed_v && nbl::hlsl::is_integral_v && nbl::hlsl::is_scalar_v; - -template -NBL_BOOL_CONCEPT unsigned_integral = !nbl::hlsl::is_signed_v && ::nbl::hlsl::is_integral_v && nbl::hlsl::is_scalar_v; - -template -NBL_BOOL_CONCEPT floating_point = nbl::hlsl::is_floating_point_v && nbl::hlsl::is_scalar_v; - -#endif - namespace impl { template @@ -102,7 +72,7 @@ struct IsEmulatingFloatingPointType //! Floating point types are native floating point types or types that imitate native floating point types (for example emulated_float64_t) template -NBL_BOOL_CONCEPT FloatingPointLike = (nbl::hlsl::is_floating_point_v && nbl::hlsl::is_scalar_v) || impl::IsEmulatingFloatingPointType::value; +NBL_BOOL_CONCEPT FloatingPointLikeScalar = (nbl::hlsl::is_floating_point_v && nbl::hlsl::is_scalar_v) || impl::IsEmulatingFloatingPointType::value; } } diff --git a/include/nbl/builtin/hlsl/concepts/vector.hlsl b/include/nbl/builtin/hlsl/concepts/vector.hlsl index f8c46bffe8..87608cd510 100644 --- a/include/nbl/builtin/hlsl/concepts/vector.hlsl +++ b/include/nbl/builtin/hlsl/concepts/vector.hlsl @@ -21,11 +21,11 @@ namespace concepts template NBL_BOOL_CONCEPT Vector = is_vector::value; template -NBL_BOOL_CONCEPT FloatingPointVector = concepts::Vector && concepts::floating_point::scalar_type>; +NBL_BOOL_CONCEPT FloatingPointVector = concepts::Vector && concepts::FloatingPointScalar::scalar_type>; template NBL_BOOL_CONCEPT IntVector = concepts::Vector && (is_integral_v::scalar_type>); template -NBL_BOOL_CONCEPT SignedIntVector = concepts::Vector && concepts::signed_integral::scalar_type>; +NBL_BOOL_CONCEPT SignedIntVector = concepts::Vector && concepts::SignedIntegralScalar::scalar_type>; //! Concept for native vectors and vector like structs. //! The only requirement for a structure to be Vectorial is that a correct template specialization of the `vector_traits` structure should be created for it. @@ -48,13 +48,13 @@ NBL_BOOL_CONCEPT Vectorial = vector_traits::IsVector; #include template -NBL_BOOL_CONCEPT FloatingPointVectorial = concepts::Vectorial && concepts::floating_point::scalar_type>; +NBL_BOOL_CONCEPT FloatingPointVectorial = concepts::Vectorial && concepts::FloatingPointScalar::scalar_type>; template -NBL_BOOL_CONCEPT FloatingPointLikeVectorial = concepts::Vectorial && concepts::FloatingPointLike::scalar_type>; +NBL_BOOL_CONCEPT FloatingPointLikeVectorial = concepts::Vectorial && concepts::FloatingPointLikeScalar::scalar_type>; template NBL_BOOL_CONCEPT IntVectorial = concepts::Vectorial && (is_integral_v::scalar_type>); template -NBL_BOOL_CONCEPT SignedIntVectorial = concepts::Vectorial && concepts::signed_integral::scalar_type>; +NBL_BOOL_CONCEPT SignedIntVectorial = concepts::Vectorial && concepts::SignedIntegralScalar::scalar_type>; } } diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index cc2268eebd..988286ed79 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -96,8 +96,8 @@ template struct clamp_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point) -struct clamp_helper) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct clamp_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) val, NBL_CONST_REF_ARG(FloatingPoint) min, NBL_CONST_REF_ARG(FloatingPoint) max) { @@ -110,8 +110,8 @@ struct clamp_helper -NBL_PARTIAL_REQ_TOP(concepts::unsigned_integral) -struct clamp_helper) > +NBL_PARTIAL_REQ_TOP(concepts::UnsignedIntegralScalar) +struct clamp_helper) > { static UnsignedInteger __call(NBL_CONST_REF_ARG(UnsignedInteger) val, NBL_CONST_REF_ARG(UnsignedInteger) min, NBL_CONST_REF_ARG(UnsignedInteger) max) { @@ -124,8 +124,8 @@ struct clamp_helper -NBL_PARTIAL_REQ_TOP(concepts::signed_integral) -struct clamp_helper) > +NBL_PARTIAL_REQ_TOP(concepts::SignedIntegralScalar) +struct clamp_helper) > { static Integer __call(NBL_CONST_REF_ARG(Integer) val, NBL_CONST_REF_ARG(Integer) min, NBL_CONST_REF_ARG(Integer) max) { @@ -404,8 +404,8 @@ template struct bitReverse_helper; template -NBL_PARTIAL_REQ_TOP(concepts::signed_integral) -struct bitReverse_helper) > +NBL_PARTIAL_REQ_TOP(concepts::SignedIntegralScalar) +struct bitReverse_helper) > { static inline Integer __call(NBL_CONST_REF_ARG(Integer) val) { @@ -595,8 +595,8 @@ template struct min_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point) -struct min_helper) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct min_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) a, NBL_CONST_REF_ARG(FloatingPoint) b) { @@ -609,8 +609,8 @@ struct min_helper -NBL_PARTIAL_REQ_TOP(concepts::unsigned_integral) -struct min_helper) > +NBL_PARTIAL_REQ_TOP(concepts::UnsignedIntegralScalar) +struct min_helper) > { static UnsignedInteger __call(NBL_CONST_REF_ARG(UnsignedInteger) a, NBL_CONST_REF_ARG(UnsignedInteger) b) { @@ -623,8 +623,8 @@ struct min_helper -NBL_PARTIAL_REQ_TOP(concepts::signed_integral) -struct min_helper) > +NBL_PARTIAL_REQ_TOP(concepts::SignedIntegralScalar) +struct min_helper) > { static Integer __call(NBL_CONST_REF_ARG(Integer) a, NBL_CONST_REF_ARG(Integer) b) { @@ -660,8 +660,8 @@ template struct max_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point) -struct max_helper) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct max_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) a, NBL_CONST_REF_ARG(FloatingPoint) b) { @@ -763,8 +763,8 @@ template struct rsqrt_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point) -struct rsqrt_helper) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct rsqrt_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { diff --git a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl index 485e524aa5..8f7e808add 100644 --- a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl +++ b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl @@ -99,8 +99,8 @@ template struct isnan_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point) -struct isnan_helper) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct isnan_helper) > { static bool __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -148,8 +148,8 @@ template struct isinf_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point) -struct isinf_helper) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct isinf_helper) > { static bool __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -227,8 +227,8 @@ template struct erf_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point) -struct erf_helper) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct erf_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) _x) { @@ -259,8 +259,8 @@ template struct erfInv_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point) -struct erfInv_helper) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct erfInv_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) _x) { @@ -311,8 +311,8 @@ template struct pow_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) -struct pow_helper && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar && (sizeof(FloatingPoint) <= 4)) +struct pow_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x, NBL_CONST_REF_ARG(FloatingPoint) y) { @@ -362,8 +362,8 @@ template struct exp_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) -struct exp_helper && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar && (sizeof(FloatingPoint) <= 4)) +struct exp_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -413,8 +413,8 @@ template struct exp2_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) -struct exp2_helper && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar && (sizeof(FloatingPoint) <= 4)) +struct exp2_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -474,8 +474,8 @@ template struct log_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) -struct log_helper && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar && (sizeof(FloatingPoint) <= 4)) +struct log_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -525,8 +525,8 @@ template struct abs_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point) -struct abs_helper) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct abs_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -576,8 +576,8 @@ template struct sqrt_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point) -struct sqrt_helper) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct sqrt_helper) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -613,8 +613,8 @@ template struct sin_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) -struct sin_helper && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar && (sizeof(FloatingPoint) <= 4)) +struct sin_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -664,8 +664,8 @@ template struct cos_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) -struct cos_helper && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar && (sizeof(FloatingPoint) <= 4)) +struct cos_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { @@ -715,8 +715,8 @@ template struct acos_helper; template -NBL_PARTIAL_REQ_TOP(concepts::floating_point && (sizeof(FloatingPoint) <= 4)) -struct acos_helper && (sizeof(FloatingPoint) <= 4)) > +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar && (sizeof(FloatingPoint) <= 4)) +struct acos_helper && (sizeof(FloatingPoint) <= 4)) > { static FloatingPoint __call(NBL_CONST_REF_ARG(FloatingPoint) x) { diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index a617389c23..fe17d16b97 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -24,31 +24,31 @@ namespace nbl namespace hlsl { // TODO: will not work for emulated_float as an input because `concepts::floating_point` is only for native floats, fix every occurance -template) +template) inline FloatingPoint erf(FloatingPoint x) { return tgmath_impl::erf_helper::__call(x); } -template) +template) inline FloatingPoint erfInv(FloatingPoint x) { return tgmath_impl::erfInv_helper::__call(x); } -template || concepts::Vectorial) +template || concepts::Vectorial) inline T floor(NBL_CONST_REF_ARG(T) val) { return tgmath_impl::floor_helper::__call(val); } -template || concepts::FloatingPointLikeVectorial) && (concepts::floating_point || is_same_v)) +template || concepts::FloatingPointLikeVectorial) && (concepts::FloatingPointLikeScalar || is_same_v)) inline T lerp(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y, NBL_CONST_REF_ARG(U) a) { return tgmath_impl::lerp_helper::__call(x, y, a); } -template) +template) inline bool isnan(NBL_CONST_REF_ARG(FloatingPoint) val) { return tgmath_impl::isnan_helper::__call(val); @@ -60,7 +60,7 @@ inline vector::Dimension> isnan(NBL_CONST_REF_ARG(V) val) return tgmath_impl::isnan_helper::__call(val); } -template) +template) inline FloatingPoint isinf(NBL_CONST_REF_ARG(FloatingPoint) val) { return tgmath_impl::isinf_helper::__call(val); @@ -72,56 +72,56 @@ inline vector::Dimension> isinf(NBL_CONST_REF_ARG(V) val) return tgmath_impl::isinf_helper::__call(val); } -template || concepts::FloatingPointLikeVectorial) +template || concepts::FloatingPointLikeVectorial) inline T pow(NBL_CONST_REF_ARG(T) x, NBL_CONST_REF_ARG(T) y) { return tgmath_impl::pow_helper::__call(x, y); } -template || concepts::FloatingPointLikeVectorial) +template || concepts::FloatingPointLikeVectorial) inline T exp(NBL_CONST_REF_ARG(T) x) { return tgmath_impl::exp_helper::__call(x); } -template || concepts::Vectorial) +template || concepts::Vectorial) inline T exp2(NBL_CONST_REF_ARG(T) x) { return tgmath_impl::exp2_helper::__call(x); } -template || concepts::FloatingPointLikeVectorial) +template || concepts::FloatingPointLikeVectorial) inline T log(NBL_CONST_REF_ARG(T) x) { return tgmath_impl::log_helper::__call(x); } -template || concepts::signed_integral || concepts::FloatingPointLikeVectorial || concepts::SignedIntVectorial) +template || concepts::SignedIntegral || concepts::FloatingPointLikeVectorial || concepts::SignedIntVectorial) inline T abs(NBL_CONST_REF_ARG(T) val) { return tgmath_impl::abs_helper::__call(val); } -template || concepts::Vectorial) +template || concepts::FloatingPointLikeVectorial) inline T sqrt(NBL_CONST_REF_ARG(T) val) { return tgmath_impl::sqrt_helper::__call(val); } -template || concepts::Vectorial) +template || concepts::FloatingPointLikeVectorial) inline T sin(NBL_CONST_REF_ARG(T) val) { return tgmath_impl::sin_helper::__call(val); } -template || concepts::Vectorial) +template || concepts::FloatingPointLikeVectorial) inline T cos(NBL_CONST_REF_ARG(T) val) { return tgmath_impl::cos_helper::__call(val); } -template || concepts::Vectorial) +template || concepts::FloatingPointLikeVectorial) inline T acos(NBL_CONST_REF_ARG(T) val) { return tgmath_impl::acos_helper::__call(val); From 5eb02f25c07b4aa05dea95278d79e92aedb9a3ae Mon Sep 17 00:00:00 2001 From: Przemek Date: Tue, 7 Jan 2025 13:50:13 +0100 Subject: [PATCH 37/42] Corrections --- include/nbl/builtin/hlsl/concepts/core.hlsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/nbl/builtin/hlsl/concepts/core.hlsl b/include/nbl/builtin/hlsl/concepts/core.hlsl index 5f18e9225a..7923cd5bb3 100644 --- a/include/nbl/builtin/hlsl/concepts/core.hlsl +++ b/include/nbl/builtin/hlsl/concepts/core.hlsl @@ -66,13 +66,13 @@ namespace impl template struct IsEmulatingFloatingPointType { - static const bool value = false; + static const bool value = nbl::hlsl::is_floating_point_v; }; } //! Floating point types are native floating point types or types that imitate native floating point types (for example emulated_float64_t) template -NBL_BOOL_CONCEPT FloatingPointLikeScalar = (nbl::hlsl::is_floating_point_v && nbl::hlsl::is_scalar_v) || impl::IsEmulatingFloatingPointType::value; +NBL_BOOL_CONCEPT FloatingPointLikeScalar = impl::IsEmulatingFloatingPointType::value; } } From 2fb8252e91363dd7d466a9336b0e892fcc1d993b Mon Sep 17 00:00:00 2001 From: Przemek Date: Wed, 8 Jan 2025 17:49:04 +0100 Subject: [PATCH 38/42] Removed float64_t partial specializations --- .../nbl/builtin/hlsl/impl/tgmath_impl.hlsl | 98 ------------------- 1 file changed, 98 deletions(-) diff --git a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl index 8f7e808add..64a89fafa5 100644 --- a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl +++ b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl @@ -324,20 +324,6 @@ struct pow_helper -NBL_PARTIAL_REQ_TOP(is_same::value) -struct pow_helper::value) > -{ - static Float64 __call(NBL_CONST_REF_ARG(Float64) x, NBL_CONST_REF_ARG(Float64) y) - { -#ifdef __HLSL_VERSION - return pow(x, y); -#else - return std::pow(x, y); -#endif - } -}; - template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct pow_helper) > @@ -375,20 +361,6 @@ struct exp_helper -NBL_PARTIAL_REQ_TOP(is_same::value) -struct exp_helper::value) > -{ - static Float64 __call(NBL_CONST_REF_ARG(Float64) x) - { -#ifdef __HLSL_VERSION - return exp(x); -#else - return std::exp(x); -#endif - } -}; - template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct exp_helper) > @@ -426,20 +398,6 @@ struct exp2_helper -NBL_PARTIAL_REQ_TOP(is_same::value) -struct exp2_helper::value) > -{ - static Float64 __call(NBL_CONST_REF_ARG(Float64) x) - { -#ifdef __HLSL_VERSION - return exp2(x); -#else - return std::exp2(x); -#endif - } -}; - template NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v && hlsl::is_scalar_v) struct exp2_helper && hlsl::is_scalar_v) > @@ -487,20 +445,6 @@ struct log_helper -NBL_PARTIAL_REQ_TOP(is_same::value) -struct log_helper::value) > -{ - static Float64 __call(NBL_CONST_REF_ARG(Float64) x) - { -#ifdef __HLSL_VERSION - return log(x); -#else - return std::log(x); -#endif - } -}; - template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct log_helper) > @@ -626,20 +570,6 @@ struct sin_helper -NBL_PARTIAL_REQ_TOP(is_same::value) -struct sin_helper::value) > -{ - static Float64 __call(NBL_CONST_REF_ARG(Float64) x) - { -#ifdef __HLSL_VERSION - return sin(x); -#else - return std::sin(x); -#endif - } -}; - template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct sin_helper) > @@ -677,20 +607,6 @@ struct cos_helper -NBL_PARTIAL_REQ_TOP(is_same::value) -struct cos_helper::value) > -{ - static Float64 __call(NBL_CONST_REF_ARG(Float64) x) - { -#ifdef __HLSL_VERSION - return cos(x); -#else - return std::cos(x); -#endif - } -}; - template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct cos_helper) > @@ -728,20 +644,6 @@ struct acos_helper -NBL_PARTIAL_REQ_TOP(is_same::value) -struct acos_helper::value) > -{ - static Float64 __call(NBL_CONST_REF_ARG(Float64) x) - { -#ifdef __HLSL_VERSION - return acos(x); -#else - return std::acos(x); -#endif - } -}; - template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct acos_helper) > From 96efff493faac5ae03fed1f0d588845cd9b41ae7 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 9 Jan 2025 16:22:22 +0700 Subject: [PATCH 39/42] fix frisvad mat, lp_norm loop --- include/nbl/builtin/hlsl/math/functions.hlsl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/nbl/builtin/hlsl/math/functions.hlsl b/include/nbl/builtin/hlsl/math/functions.hlsl index adb83c950c..a36c2027f8 100644 --- a/include/nbl/builtin/hlsl/math/functions.hlsl +++ b/include/nbl/builtin/hlsl/math/functions.hlsl @@ -27,7 +27,7 @@ struct lp_norm static scalar_type_t __call(const T v) { scalar_type_t retval = abs(v[0]); - for (int i = 1; i < rank::value; i++) + for (int i = 1; i < extent::value; i++) retval = max(abs(v[i]),retval); return retval; } @@ -40,7 +40,7 @@ struct lp_norm static scalar_type_t __sum(const T v) { scalar_type_t retval = abs(v[0]); - for (int i = 1; i < rank::value; i++) + for (int i = 1; i < extent::value; i++) retval += abs(v[i]); return retval; } @@ -276,7 +276,7 @@ void sincos(T theta, NBL_REF_ARG(T) s, NBL_REF_ARG(T) c) } template ) -matrix frisvad(vector n) // TODO: confirm dimensions of matrix +matrix frisvad(vector n) { const T a = 1.0 / (1.0 + n.z); const T b = -n.x * n.y * a; From 4c0536f434827f42e6f450ef9662ba4c186febb3 Mon Sep 17 00:00:00 2001 From: Przemek Date: Fri, 10 Jan 2025 15:53:48 +0100 Subject: [PATCH 40/42] Integrated concepts into intrinsics.hlsl functions and fixed some emulated_float64_t stuff --- include/nbl/builtin/hlsl/concepts/core.hlsl | 2 +- include/nbl/builtin/hlsl/concepts/matrix.hlsl | 20 +-- include/nbl/builtin/hlsl/concepts/vector.hlsl | 14 -- .../hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 122 ++++++++---------- .../builtin/hlsl/cpp_compat/intrinsics.hlsl | 88 ++++++++----- .../nbl/builtin/hlsl/emulated/float64_t.hlsl | 6 +- .../nbl/builtin/hlsl/emulated/matrix_t.hlsl | 36 +++++- .../nbl/builtin/hlsl/emulated/vector_t.hlsl | 7 +- .../nbl/builtin/hlsl/impl/tgmath_impl.hlsl | 88 +++++++++++++ .../hlsl/matrix_utils/matrix_traits.hlsl | 14 +- src/nbl/builtin/CMakeLists.txt | 5 +- 11 files changed, 262 insertions(+), 140 deletions(-) diff --git a/include/nbl/builtin/hlsl/concepts/core.hlsl b/include/nbl/builtin/hlsl/concepts/core.hlsl index 7923cd5bb3..4184600e60 100644 --- a/include/nbl/builtin/hlsl/concepts/core.hlsl +++ b/include/nbl/builtin/hlsl/concepts/core.hlsl @@ -32,7 +32,7 @@ template NBL_BOOL_CONCEPT FloatingPoint = nbl::hlsl::is_floating_point_v; template -NBL_BOOL_CONCEPT scalar = FloatingPoint || Integral; +NBL_BOOL_CONCEPT Scalar = nbl::hlsl::is_scalar_v; template NBL_BOOL_CONCEPT IntegralScalar = nbl::hlsl::is_integral_v && nbl::hlsl::is_scalar_v; diff --git a/include/nbl/builtin/hlsl/concepts/matrix.hlsl b/include/nbl/builtin/hlsl/concepts/matrix.hlsl index 4d8b22dd88..94659c823b 100644 --- a/include/nbl/builtin/hlsl/concepts/matrix.hlsl +++ b/include/nbl/builtin/hlsl/concepts/matrix.hlsl @@ -18,24 +18,8 @@ namespace concepts template NBL_BOOL_CONCEPT Matrix = is_matrix::value; -#define NBL_CONCEPT_NAME Matricial -#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -#define NBL_CONCEPT_TPLT_PRM_NAMES (T) -NBL_CONCEPT_BEGIN(0) -NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE)(matrix_traits::scalar_type)) - ((NBL_CONCEPT_REQ_TYPE)(matrix_traits::row_type)) - ((NBL_CONCEPT_REQ_TYPE)(matrix_traits::transposed_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matrix_traits::RowCount), ::nbl::hlsl::is_integral_v)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matrix_traits::ColumnCount), ::nbl::hlsl::is_integral_v)) - // TODO: fix - //((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matrix_traits::Square), ::nbl::hlsl::is_same_v, bool)) -); -#include - -#undef NBL_CONCEPT_NAME -#undef NBL_CONCEPT_TPLT_PRM_KINDS -#undef NBL_CONCEPT_TPLT_PRM_NAMES +template +NBL_BOOL_CONCEPT Matricial = matrix_traits::IsMatrix; } } diff --git a/include/nbl/builtin/hlsl/concepts/vector.hlsl b/include/nbl/builtin/hlsl/concepts/vector.hlsl index 87608cd510..edea37a183 100644 --- a/include/nbl/builtin/hlsl/concepts/vector.hlsl +++ b/include/nbl/builtin/hlsl/concepts/vector.hlsl @@ -28,20 +28,6 @@ template NBL_BOOL_CONCEPT SignedIntVector = concepts::Vector && concepts::SignedIntegralScalar::scalar_type>; //! Concept for native vectors and vector like structs. -//! The only requirement for a structure to be Vectorial is that a correct template specialization of the `vector_traits` structure should be created for it. -//#define NBL_CONCEPT_NAME Vectorial -//#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -//#define NBL_CONCEPT_TPLT_PRM_NAMES (T) -// -//NBL_CONCEPT_BEGIN(0) -//NBL_CONCEPT_END -//( -// ((NBL_CONCEPT_REQ_TYPE)(vector_traits::scalar_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((vector_traits::Dimension), ::nbl::hlsl::is_integral_v)) -// // TODO: fix -// //((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((vector_traits::IsVector), ::nbl::hlsl::is_same_v, bool)) -//) && vector_traits::isVector; - template NBL_BOOL_CONCEPT Vectorial = vector_traits::IsVector; diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index 988286ed79..d1e1a079f3 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -8,8 +8,9 @@ #include #include #include -#include +#include #include +#include #ifndef __HLSL_VERSION #include @@ -21,17 +22,24 @@ namespace hlsl { namespace cpp_compat_intrinsics_impl { -template -struct dot_helper + +// DOT + +template +struct dot_helper; + +template +NBL_PARTIAL_REQ_TOP(concepts::Vectorial) +struct dot_helper) > { - using scalar_type = typename vector_traits::scalar_type; + using scalar_type = typename vector_traits::scalar_type; + static const uint32_t ArrayDim = 3; // vector_traits::Dimension; - static inline scalar_type __call(NBL_CONST_REF_ARG(T) lhs, NBL_CONST_REF_ARG(T) rhs) + static inline scalar_type __call(NBL_CONST_REF_ARG(Vectorial) lhs, NBL_CONST_REF_ARG(Vectorial) rhs) { - static array_get getter; - scalar_type retval = getter(lhs, 0) * getter(rhs, 0); + static array_get getter; - static const uint32_t ArrayDim = vector_traits::Dimension; + scalar_type retval = getter(lhs, 0) * getter(rhs, 0); for (uint32_t i = 1; i < ArrayDim; ++i) retval = retval + getter(lhs, i) * getter(rhs, i); @@ -39,51 +47,29 @@ struct dot_helper } }; -#define DEFINE_BUILTIN_VECTOR_SPECIALIZATION(FLOAT_TYPE, RETURN_VALUE)\ -template\ -struct dot_helper >\ -{\ - using VectorType = vector;\ - using ScalarType = typename vector_traits::scalar_type;\ -\ - static inline ScalarType __call(NBL_CONST_REF_ARG(VectorType) lhs, NBL_CONST_REF_ARG(VectorType) rhs)\ - {\ - return RETURN_VALUE;\ - }\ -};\ - -#ifdef __HLSL_VERSION -#define BUILTIN_VECTOR_SPECIALIZATION_RET_VAL dot(lhs, rhs) -#else -#define BUILTIN_VECTOR_SPECIALIZATION_RET_VAL glm::dot(lhs, rhs) -#endif - -DEFINE_BUILTIN_VECTOR_SPECIALIZATION(float16_t, BUILTIN_VECTOR_SPECIALIZATION_RET_VAL) -DEFINE_BUILTIN_VECTOR_SPECIALIZATION(float32_t, BUILTIN_VECTOR_SPECIALIZATION_RET_VAL) -DEFINE_BUILTIN_VECTOR_SPECIALIZATION(float64_t, BUILTIN_VECTOR_SPECIALIZATION_RET_VAL) - -#undef BUILTIN_VECTOR_SPECIALIZATION_RET_VAL -#undef DEFINE_BUILTIN_VECTOR_SPECIALIZATION - // CROSS template struct cross_helper; -//! this specialization will work only with hlsl::vector type -template -NBL_PARTIAL_REQ_TOP(concepts::FloatingPointVector && (vector_traits::Dimension == 3)) -struct cross_helper && (vector_traits::Dimension == 3)) > +template +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointLikeVectorial && (vector_traits::Dimension == 3)) +struct cross_helper && (vector_traits::Dimension == 3)) > { - static FloatingPointVector __call(NBL_CONST_REF_ARG(FloatingPointVector) lhs, NBL_CONST_REF_ARG(FloatingPointVector) rhs) + static FloatingPointLikeVectorial __call(NBL_CONST_REF_ARG(FloatingPointLikeVectorial) lhs, NBL_CONST_REF_ARG(FloatingPointLikeVectorial) rhs) { #ifdef __HLSL_VERSION - return spirv::cross(lhs, rhs); + if(hlsl::is_vector_v) + return spirv::cross(lhs, rhs); #else - FloatingPointVector output; - output.x = lhs[1] * rhs[2] - rhs[1] * lhs[2]; - output.y = lhs[2] * rhs[0] - rhs[2] * lhs[0]; - output.z = lhs[0] * rhs[1] - rhs[0] * lhs[1]; + using traits = hlsl::vector_traits; + array_get getter; + array_set setter; + + FloatingPointLikeVectorial output; + setter(output, 0, getter(lhs, 1) * getter(rhs, 2) - getter(rhs, 1) * getter(lhs, 2)); + setter(output, 1, getter(lhs, 2) * getter(rhs, 0) - getter(rhs, 2) * getter(lhs, 0)); + setter(output, 2, getter(lhs, 0) * getter(rhs, 1) - getter(rhs, 0) * getter(lhs, 1)); return output; #endif @@ -157,7 +143,7 @@ struct clamp_helper) > // FIND_MSB -template +template struct find_msb_helper; template<> @@ -272,7 +258,7 @@ struct find_msb_helper // FIND_LSB -template +template struct find_lsb_helper; template<> @@ -435,26 +421,31 @@ struct bitReverse_helper) } }; -template +template struct transpose_helper; -template -struct transpose_helper > +template +NBL_PARTIAL_REQ_TOP(concepts::Matrix) +struct transpose_helper) > { - using transposed_t = typename matrix_traits >::transposed_type; + using transposed_t = typename matrix_traits::transposed_type; - static transposed_t __call(NBL_CONST_REF_ARG(matrix) m) + static transposed_t __call(NBL_CONST_REF_ARG(Matrix) m) { #ifdef __HLSL_VERSION return spirv::transpose(m); #else - return reinterpret_cast(glm::transpose(reinterpret_cast::Base const&>(m))); + return reinterpret_cast(glm::transpose(reinterpret_cast(m))); #endif } }; +template +struct mul_helper; + template -struct mul_helper +NBL_PARTIAL_REQ_TOP(concepts::Matrix && (concepts::Matrix || concepts::Vector)) +struct mul_helper && (concepts::Matrix || concepts::Vector)) > { static inline mul_output_t __call(LhsT lhs, RhsT rhs) { @@ -498,8 +489,8 @@ template struct bitCount_helper; template -NBL_PARTIAL_REQ_TOP(is_integral_v) -struct bitCount_helper) > +NBL_PARTIAL_REQ_TOP(concepts::IntegralScalar) +struct bitCount_helper) > { static bitcount_output_t __call(NBL_CONST_REF_ARG(Integer) val) { @@ -513,7 +504,6 @@ struct bitCount_helper) > } return spirv::bitCount(val); - #else using UnsignedInteger = typename hlsl::unsigned_integer_of_size_t; constexpr int32_t BitCnt = sizeof(Integer) * 8u; @@ -555,6 +545,7 @@ struct bitCount_helper }; #endif +// TODO: length_helper partial specialization for emulated_float64_t template struct length_helper; @@ -567,7 +558,7 @@ struct length_helper::__call(vec, vec)); + return std::sqrt(length_helper::__call(vec, vec)); #endif } }; @@ -575,16 +566,17 @@ struct length_helper struct normalize_helper; -template -NBL_PARTIAL_REQ_TOP(concepts::FloatingPointVector) -struct normalize_helper) > +template +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointLikeVectorial) +struct normalize_helper) > { - static inline Vector __call(NBL_CONST_REF_ARG(Vector) vec) + static inline Vectorial __call(NBL_CONST_REF_ARG(Vectorial) vec) { #ifdef __HLSL_VERSION - return spirv::normalize(vec); + if(is_vector_v) + return spirv::normalize(vec); #else - return vec / length_helper::__call(vec); + return vec / length_helper::__call(vec); #endif } }; @@ -744,8 +736,8 @@ template struct inverse_helper; template -NBL_PARTIAL_REQ_TOP(matrix_traits::Square) -struct inverse_helper::Square) > +NBL_PARTIAL_REQ_TOP(concepts::Matrix && matrix_traits::Square) +struct inverse_helper && matrix_traits::Square) > { static SquareMatrix __call(NBL_CONST_REF_ARG(SquareMatrix) mat) { diff --git a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl index 6da1b8a317..3c4138a45b 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #ifndef __HLSL_VERSION #include @@ -20,121 +23,140 @@ namespace nbl namespace hlsl { -template +#ifdef __HLSL_VERSION +template) +#else +template || std::is_enum_v) +#endif inline cpp_compat_intrinsics_impl::bitcount_output_t bitCount(NBL_CONST_REF_ARG(Integer) val) { return cpp_compat_intrinsics_impl::bitCount_helper::__call(val); } -template -FloatingPointVector cross(NBL_CONST_REF_ARG(FloatingPointVector) lhs, NBL_CONST_REF_ARG(FloatingPointVector) rhs) +template) +FloatingPointVectorial cross(NBL_CONST_REF_ARG(FloatingPointVectorial) lhs, NBL_CONST_REF_ARG(FloatingPointVectorial) rhs) { - return cpp_compat_intrinsics_impl::cross_helper::__call(lhs, rhs); + return cpp_compat_intrinsics_impl::cross_helper::__call(lhs, rhs); } -template -enable_if_t, Scalar> clamp(NBL_CONST_REF_ARG(Scalar) val, NBL_CONST_REF_ARG(Scalar) min, NBL_CONST_REF_ARG(Scalar) max) +template) +Scalar clamp(NBL_CONST_REF_ARG(Scalar) val, NBL_CONST_REF_ARG(Scalar) min, NBL_CONST_REF_ARG(Scalar) max) { return cpp_compat_intrinsics_impl::clamp_helper::__call(val, min, max); } -// TODO: is_vector_v will be false for custom vector types, fix -template -enable_if_t, Vector> clamp(NBL_CONST_REF_ARG(Vector) val, NBL_CONST_REF_ARG(typename vector_traits::scalar_type) min, NBL_CONST_REF_ARG(typename vector_traits::scalar_type) max) +template) +Vectorial clamp(NBL_CONST_REF_ARG(Vectorial) val, NBL_CONST_REF_ARG(typename vector_traits::scalar_type) min, NBL_CONST_REF_ARG(typename vector_traits::scalar_type) max) { - return cpp_compat_intrinsics_impl::clamp_helper::__call(val, min, max); + return cpp_compat_intrinsics_impl::clamp_helper::__call(val, min, max); } -template -typename vector_traits::scalar_type length(NBL_CONST_REF_ARG(Vector) vec) +template) +typename vector_traits::scalar_type length(NBL_CONST_REF_ARG(FloatingPointVectorial) vec) { - return cpp_compat_intrinsics_impl::length_helper::__call(vec); + return cpp_compat_intrinsics_impl::length_helper::__call(vec); } -template -Vector normalize(NBL_CONST_REF_ARG(Vector) vec) +template) +FloatingPointVectorial normalize(NBL_CONST_REF_ARG(FloatingPointVectorial) vec) { - return cpp_compat_intrinsics_impl::normalize_helper::__call(vec); + return cpp_compat_intrinsics_impl::normalize_helper::__call(vec); } -template -typename vector_traits::scalar_type dot(NBL_CONST_REF_ARG(T) lhs, NBL_CONST_REF_ARG(T) rhs) +template) +typename vector_traits::scalar_type dot(NBL_CONST_REF_ARG(Vectorial) lhs, NBL_CONST_REF_ARG(Vectorial) rhs) { - return cpp_compat_intrinsics_impl::dot_helper::__call(lhs, rhs); + return cpp_compat_intrinsics_impl::dot_helper::__call(lhs, rhs); } // determinant not defined cause its implemented via hidden friend // https://stackoverflow.com/questions/67459950/why-is-a-friend-function-not-treated-as-a-member-of-a-namespace-of-a-class-it-wa -template +template && matrix_traits::Square) inline typename matrix_traits::scalar_type determinant(NBL_CONST_REF_ARG(Matrix) mat) { return cpp_compat_intrinsics_impl::determinant_helper::__call(mat); } +#ifdef __HLSL_VERSION +template +inline typename cpp_compat_intrinsics_impl::find_lsb_return_type::type findLSB(NBL_CONST_REF_ARG(Integer) val) +{ + return cpp_compat_intrinsics_impl::find_lsb_helper::__call(val); +} +#else +// TODO: no concepts because then it wouldn't work for core::bitflag, find solution template inline typename cpp_compat_intrinsics_impl::find_lsb_return_type::type findLSB(NBL_CONST_REF_ARG(Integer) val) { return cpp_compat_intrinsics_impl::find_lsb_helper::__call(val); } +#endif +#ifdef __HLSL_VERSION +template) +inline typename cpp_compat_intrinsics_impl::find_msb_return_type::type findMSB(NBL_CONST_REF_ARG(Integer) val) +{ + return cpp_compat_intrinsics_impl::find_msb_helper::__call(val); +} +#else +// TODO: no concepts because then it wouldn't work for core::bitflag, find solution template inline typename cpp_compat_intrinsics_impl::find_msb_return_type::type findMSB(NBL_CONST_REF_ARG(Integer) val) { return cpp_compat_intrinsics_impl::find_msb_helper::__call(val); } - +#endif // inverse not defined cause its implemented via hidden friend -template +template && matrix_traits::Square) inline Matrix inverse(NBL_CONST_REF_ARG(Matrix) mat) { return cpp_compat_intrinsics_impl::inverse_helper::__call(mat); } // transpose not defined cause its implemented via hidden friend -template +template) inline typename matrix_traits::transposed_type transpose(NBL_CONST_REF_ARG(Matrix) m) { return cpp_compat_intrinsics_impl::transpose_helper::__call(m); } -// TODO: concepts, to ensure that MatT is a matrix and VecT is a vector type -template -mul_output_t mul(LhsT mat, RhsT vec) +template && (concepts::Matricial || concepts::Vectorial)) +mul_output_t mul(LhsT lhs, RhsT rhs) { - return cpp_compat_intrinsics_impl::mul_helper::__call(mat, vec); + return cpp_compat_intrinsics_impl::mul_helper::__call(lhs, rhs); } -template +template || concepts::Scalar || concepts::Vectorial) inline T min(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b) { return cpp_compat_intrinsics_impl::min_helper::__call(a, b); } -template +template || concepts::Scalar || concepts::Vectorial) inline T max(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) b) { return cpp_compat_intrinsics_impl::max_helper::__call(a, b); } -template +template || concepts::FloatingPointLikeVectorial) inline FloatingPoint rsqrt(FloatingPoint x) { return cpp_compat_intrinsics_impl::rsqrt_helper::__call(x); } -template +template) inline Integer bitReverse(Integer val) { return cpp_compat_intrinsics_impl::bitReverse_helper::__call(val); } -template +template) inline bool all(Vector vec) { return cpp_compat_intrinsics_impl::all_helper::__call(vec); } -template +template) inline bool any(Vector vec) { return cpp_compat_intrinsics_impl::any_helper::__call(vec); diff --git a/include/nbl/builtin/hlsl/emulated/float64_t.hlsl b/include/nbl/builtin/hlsl/emulated/float64_t.hlsl index 15249f9265..94ae039eb4 100644 --- a/include/nbl/builtin/hlsl/emulated/float64_t.hlsl +++ b/include/nbl/builtin/hlsl/emulated/float64_t.hlsl @@ -517,13 +517,13 @@ struct static_cast_helper,void if (exponent < 0) return 0; - uint64_t unsignedOutput = ieee754::extractMantissa(v.data) & 1ull << ieee754::traits::mantissaBitCnt; + uint64_t unsignedOutput = ieee754::extractMantissa(v.data) | 1ull << ieee754::traits::mantissaBitCnt; const int shiftAmount = exponent - int(ieee754::traits::mantissaBitCnt); if (shiftAmount < 0) - unsignedOutput <<= -shiftAmount; + unsignedOutput >>= -shiftAmount; else - unsignedOutput >>= shiftAmount; + unsignedOutput <<= shiftAmount; if (is_signed::value) { diff --git a/include/nbl/builtin/hlsl/emulated/matrix_t.hlsl b/include/nbl/builtin/hlsl/emulated/matrix_t.hlsl index e697e5ee5f..7e9842a7f7 100644 --- a/include/nbl/builtin/hlsl/emulated/matrix_t.hlsl +++ b/include/nbl/builtin/hlsl/emulated/matrix_t.hlsl @@ -54,11 +54,12 @@ template \ struct matrix_traits > \ { \ using scalar_type = T; \ - using row_type = vector; \ + using row_type = emulated_vector_t; \ using transposed_type = emulated_matrix; \ NBL_CONSTEXPR_STATIC_INLINE uint32_t RowCount = ROW_COUNT; \ NBL_CONSTEXPR_STATIC_INLINE uint32_t ColumnCount = COLUMN_COUNT; \ NBL_CONSTEXPR_STATIC_INLINE bool Square = RowCount == ColumnCount; \ + NBL_CONSTEXPR_STATIC_INLINE bool IsMatrix = true; \ }; DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(2, 2) @@ -68,6 +69,12 @@ DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(3, 4) #undef DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION +template +struct mul_output, emulated_matrix > +{ + using type = emulated_matrix; +}; + template struct mul_output, emulated_vector_t > { @@ -87,6 +94,33 @@ struct transpose_helper > } }; +template +struct mul_helper, emulated_matrix > +{ + using LhsT = emulated_matrix; + using RhsT = emulated_matrix; + using OutputT = typename mul_output::type; + + static inline OutputT __call(LhsT lhs, RhsT rhs) + { + typename matrix_traits::transposed_type rhsTransposed = rhs.getTransposed(); + const uint32_t outputRowCount = matrix_traits::RowCount; + const uint32_t outputColumnCount = matrix_traits::ColumnCount; + using OutputVecType = typename matrix_traits::row_type; + + nbl::hlsl::array_set::scalar_type> setter; + + OutputT output; + for (int r = 0; r < outputRowCount; ++r) + { + for (int c = 0; c < outputColumnCount; ++c) + setter(output.rows[r], c, dot(lhs.rows[r], rhsTransposed.rows[c])); + } + + return output; + } +}; + template struct mul_helper, emulated_vector_t > { diff --git a/include/nbl/builtin/hlsl/emulated/vector_t.hlsl b/include/nbl/builtin/hlsl/emulated/vector_t.hlsl index 62df0502b1..0053008aa4 100644 --- a/include/nbl/builtin/hlsl/emulated/vector_t.hlsl +++ b/include/nbl/builtin/hlsl/emulated/vector_t.hlsl @@ -472,9 +472,12 @@ struct static_cast_helper, emulated_vector_t getter; + array_set setter; + OutputVecType output; - output.x = _static_cast(vec.x); - output.y = _static_cast(vec.y); + for (int i = 0; i < N; ++i) + setter(output, i, _static_cast(getter(vec, i))); return output; } diff --git a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl index 64a89fafa5..5d07a87c42 100644 --- a/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl +++ b/include/nbl/builtin/hlsl/impl/tgmath_impl.hlsl @@ -324,6 +324,19 @@ struct pow_helper +NBL_PARTIAL_REQ_TOP(is_same_v) +struct pow_helper) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { + return std::pow(x); + } +}; +#endif + template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct pow_helper) > @@ -361,6 +374,19 @@ struct exp_helper +NBL_PARTIAL_REQ_TOP(is_same_v) +struct exp_helper) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { + return std::exp(x); + } +}; +#endif + template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct exp_helper) > @@ -398,6 +424,18 @@ struct exp2_helper +NBL_PARTIAL_REQ_TOP(is_same_v) +struct exp2_helper) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { + return std::exp2(x); + } +}; +#endif + template NBL_PARTIAL_REQ_TOP(hlsl::is_integral_v && hlsl::is_scalar_v) struct exp2_helper && hlsl::is_scalar_v) > @@ -445,6 +483,18 @@ struct log_helper +NBL_PARTIAL_REQ_TOP(is_same_v) +struct log_helper) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { + return std::log(x); + } +}; +#endif + template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct log_helper) > @@ -588,6 +638,19 @@ struct sin_helper) > } }; + +#ifndef __HLSL_VERSION +template +NBL_PARTIAL_REQ_TOP(is_same_v) +struct sin_helper) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { + return std::sin(x); + } +}; +#endif + // COS template @@ -607,6 +670,19 @@ struct cos_helper +NBL_PARTIAL_REQ_TOP(is_same_v) +struct cos_helper) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { + return std::cos(x); + } +}; +#endif + template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct cos_helper) > @@ -644,6 +720,18 @@ struct acos_helper +NBL_PARTIAL_REQ_TOP(is_same_v) +struct acos_helper) > +{ + static Float64 __call(NBL_CONST_REF_ARG(Float64) x) + { + return std::acos(x); + } +}; +#endif + template NBL_PARTIAL_REQ_TOP(concepts::Vectorial) struct acos_helper) > diff --git a/include/nbl/builtin/hlsl/matrix_utils/matrix_traits.hlsl b/include/nbl/builtin/hlsl/matrix_utils/matrix_traits.hlsl index 85adcce6ae..f9c031c8e7 100644 --- a/include/nbl/builtin/hlsl/matrix_utils/matrix_traits.hlsl +++ b/include/nbl/builtin/hlsl/matrix_utils/matrix_traits.hlsl @@ -9,8 +9,17 @@ namespace nbl namespace hlsl { -template -struct matrix_traits; +template +struct matrix_traits +{ + using scalar_type = T; + using row_type = void; + using transposed_type = void; + NBL_CONSTEXPR_STATIC_INLINE uint32_t RowCount = 1; + NBL_CONSTEXPR_STATIC_INLINE uint32_t ColumnCount = 1; + NBL_CONSTEXPR_STATIC_INLINE bool Square = false; + NBL_CONSTEXPR_STATIC_INLINE bool IsMatrix = false; +}; // i choose to implement it this way because of this DXC bug: https://github.com/microsoft/DirectXShaderCompiler/issues/7007 #define DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(ROW_COUNT, COLUMN_COUNT) \ @@ -23,6 +32,7 @@ struct matrix_traits > \ NBL_CONSTEXPR_STATIC_INLINE uint32_t RowCount = ROW_COUNT; \ NBL_CONSTEXPR_STATIC_INLINE uint32_t ColumnCount = COLUMN_COUNT; \ NBL_CONSTEXPR_STATIC_INLINE bool Square = RowCount == ColumnCount; \ + NBL_CONSTEXPR_STATIC_INLINE bool IsMatrix = true; \ }; DEFINE_MATRIX_TRAITS_TEMPLATE_SPECIALIZATION(1, 2) diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index 78809c5c1e..fee4386340 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -346,7 +346,10 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/memory_accessor.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/enums.hlsl") # LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/binding_info.hlsl") -# +#concepts +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/concepts/core.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/concepts/matrix.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/concepts/vector.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/concepts/__end.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/concepts/accessors/anisotropically_sampled.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/concepts/accessors/loadable_image.hlsl") From 18c32575b32d67b9160b8ddcacb7a6e36b3b135a Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 14 Jan 2025 10:10:44 +0700 Subject: [PATCH 41/42] removed dupe xoroshiro.hlsl --- include/nbl/builtin/random/xoroshiro.hlsl | 76 ----------------------- src/nbl/builtin/CMakeLists.txt | 1 + 2 files changed, 1 insertion(+), 76 deletions(-) delete mode 100644 include/nbl/builtin/random/xoroshiro.hlsl diff --git a/include/nbl/builtin/random/xoroshiro.hlsl b/include/nbl/builtin/random/xoroshiro.hlsl deleted file mode 100644 index fa917980e4..0000000000 --- a/include/nbl/builtin/random/xoroshiro.hlsl +++ /dev/null @@ -1,76 +0,0 @@ - -// Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O. -// This file is part of the "Nabla Engine". -// For conditions of distribution and use, see copyright notice in nabla.h - -#ifndef _NBL_BUILTIN_GLSL_RANDOM_XOROSHIRO_HLSL_INCLUDED_ -#define _NBL_BUILTIN_GLSL_RANDOM_XOROSHIRO_HLSL_INCLUDED_ - -//#include - -// TODO[Przemek]: include functions.hlsl instead -uint32_t rotl(NBL_CONST_REF_ARG(uint32_t) x, NBL_CONST_REF_ARG(uint32_t) k) -{ - return (x<>(32u-k)); -} - -namespace nbl -{ -namespace hlsl -{ - -typedef uint2 xoroshiro64star_state_t; -typedef uint2 xoroshiro64starstar_state_t; - -namespace impl -{ - uint2 xoroshiro64_state_advance(uint2 state) - { - state[1] ^= state[0]; - state[0] = rotl(state[0], 26u) ^ state[1] ^ (state[1]<<9u); // a, b - state[1] = rotl(state[1], 13u); // c - - return state; - } -} - -struct Xoroshriro64Star -{ - static Xoroshriro64Star construct(xoroshiro64star_state_t initialState) - { - return { initialState }; - } - - uint32_t operator()() - { - const uint32_t result = state[0]*0x9E3779BBu; - state = impl::xoroshiro64_state_advance(state); - - return result; - } - - xoroshiro64star_state_t state; -}; - -struct Xoroshriro64StarStar -{ - static Xoroshriro64StarStar construct(xoroshiro64starstar_state_t initialState) - { - return { initialState }; - } - - uint32_t operator()() - { - const uint32_t result = rotl(state[0]*0x9E3779BBu,5u)*5u; - state = impl::xoroshiro64_state_advance(state); - - return result; - } - - xoroshiro64starstar_state_t state; -}; - -} -} - -#endif \ No newline at end of file diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index fee4386340..484be0e0fa 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -286,6 +286,7 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/format.hlsl") #linear algebra LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/math/linalg/fast_affine.hlsl") # TODO: rename `equations` to `polynomials` probably +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/math/functions.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/math/geometry.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/math/equations/quadratic.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/math/equations/cubic.hlsl") From c0531fbec17e08f0e29d1e6d5f42da39432d1616 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 14 Jan 2025 13:53:20 +0700 Subject: [PATCH 42/42] fix length_helper --- include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl index d1e1a079f3..45762653af 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/impl/intrinsics_impl.hlsl @@ -558,7 +558,7 @@ struct length_helper::__call(vec, vec)); + return std::sqrt(dot_helper::__call(vec, vec)); #endif } };