diff --git a/source/blender/gpu/GPU_shader_shared_utils.hh b/source/blender/gpu/GPU_shader_shared_utils.hh index 5fe801e44e1..244d877c57e 100644 --- a/source/blender/gpu/GPU_shader_shared_utils.hh +++ b/source/blender/gpu/GPU_shader_shared_utils.hh @@ -28,7 +28,9 @@ * NOTE: You can use bool type using bool32_t a int boolean type matching the GLSL type. */ -#ifdef GPU_SHADER +#ifdef GLSL_CPP_STUBS +/* Do nothing. */ +#elif defined(GPU_SHADER) /* Silence macros when compiling for shaders. */ # define BLI_STATIC_ASSERT(cond, msg) # define BLI_STATIC_ASSERT_ALIGN(type_, align_) diff --git a/source/blender/gpu/shaders/gpu_glsl_cpp_stubs.hh b/source/blender/gpu/shaders/gpu_glsl_cpp_stubs.hh new file mode 100644 index 00000000000..7be05bcaf47 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_glsl_cpp_stubs.hh @@ -0,0 +1,787 @@ +/* SPDX-FileCopyrightText: 2024 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** + * GLSL to C++ stubs. + * + * The goal of this header is to make the GLSL source file compile using a modern C++ compiler. + * This allows for linting and IDE functionalities to work. + * + * This file can be included inside any GLSL file to make the GLSL syntax to work. Then your IDE + * must to be configured to associate .glsl files to C++ so that the C++ linter does the analysis. + * + * This is why the implementation of each function is not needed. However, we make sure that type + * casting is always explicit. This is because implicit casts are not always supported on all + * implementations. + * + * Float types are set to double to accept float literals without trailing f and avoid casting + * issues. + * + * Some of the features of GLSL are omitted by design. They are either: + * - not needed (e.g. per component matrix multiplication) + * - against our code-style (e.g. stpq swizzle) + * - unsupported by our Metal Shading Language layer (e.g. mixed vector-scalar matrix constructor). + * + * IMPORTANT: Please ask the module team if you need some feature that are not listed in this file. + */ + +#pragma once + +#include + +/* -------------------------------------------------------------------- */ +/** \name Vector Types + * \{ */ + +template struct VecBase {}; + +template struct VecOp { + using VecT = VecBase; + + T &operator[](int) {} + + VecT operator+() const {} + VecT operator-() const {} + + VecT operator+(VecT) const {} + VecT operator-(VecT) const {} + VecT operator/(VecT) const {} + VecT operator*(VecT) const {} + + VecT operator+=(VecT) const {} + VecT operator-=(VecT) const {} + VecT operator/=(VecT) const {} + VecT operator*=(VecT) const {} + + VecT operator+(T) const {} + VecT operator-(T) const {} + VecT operator/(T) const {} + VecT operator*(T) const {} + + VecT operator+=(T) const {} + VecT operator-=(T) const {} + VecT operator/=(T) const {} + VecT operator*=(T) const {} + + friend VecT operator+(T, VecT) {} + friend VecT operator-(T, VecT) {} + friend VecT operator/(T, VecT) {} + friend VecT operator*(T, VecT) {} + +#define INT_OP \ + template> * = nullptr> + + INT_OP VecT operator%(VecT) const {} + INT_OP VecT operator&(VecT) const {} + INT_OP VecT operator|(VecT) const {} + INT_OP VecT operator^(VecT) const {} + + INT_OP VecT operator%=(VecT) const {} + INT_OP VecT operator&=(VecT) const {} + INT_OP VecT operator|=(VecT) const {} + INT_OP VecT operator^=(VecT) const {} + + INT_OP VecT operator%(T) const {} + INT_OP VecT operator&(T) const {} + INT_OP VecT operator|(T) const {} + INT_OP VecT operator^(T) const {} + + INT_OP VecT operator%=(T) const {} + INT_OP VecT operator&=(T) const {} + INT_OP VecT operator|=(T) const {} + INT_OP VecT operator^=(T) const {} + + INT_OP friend VecT operator%(T, VecT) {} + INT_OP friend VecT operator&(T, VecT) {} + INT_OP friend VecT operator|(T, VecT) {} + INT_OP friend VecT operator^(T, VecT) {} + +#undef INT_OP +}; + +template struct VecSwizzle2 { + static VecBase &xx, &xy, &yx, &yy; + static VecBase &xxx, &xxy, &xyx, &xyy, &yxx, &yxy, &yyx, &yyy; + static VecBase &xxxx, &xxxy, &xxyx, &xxyy, &xyxx, &xyxy, &xyyx, &xyyy, &yxxx, &yxxy, &yxyx, + &yxyy, &yyxx, &yyxy, &yyyx, &yyyy; +}; + +template struct ColSwizzle2 { + static VecBase &rr, &rg, &gr, ≫ + static VecBase &rrr, &rrg, &rgr, &rgg, &grr, &grg, &ggr, ⋙ + static VecBase &rrrr, &rrrg, &rrgr, &rrgg, &rgrr, &rgrg, &rggr, &rggg, &grrr, &grrg, &grgr, + &grgg, &ggrr, &ggrg, &gggr, &gggg; +}; + +template struct VecSwizzle3 : VecSwizzle2 { + static VecBase &xz, &yz, &zx, &zy, &zz, &zw; + static VecBase &xxz, &xyz, &xzx, &xzy, &xzz, &yxz, &yyz, &yzx, &yzy, &yzz, &zxx, &zxy, + &zxz, &zyx, &zyy, &zyz, &zzx, &zzy, &zzz; + static VecBase &xxxz, &xxyz, &xxzx, &xxzy, &xxzz, &xyxz, &xyyz, &xyzx, &xyzy, &xyzz, &xzxx, + &xzxy, &xzxz, &xzyx, &xzyy, &xzyz, &xzzx, &xzzy, &xzzz, &yxxz, &yxyz, &yxzx, &yxzy, &yxzz, + &yyxz, &yyyz, &yyzx, &yyzy, &yyzz, &yzxx, &yzxy, &yzxz, &yzyx, &yzyy, &yzyz, &yzzx, &yzzy, + &yzzz, &zxxx, &zxxy, &zxxz, &zxyx, &zxyy, &zxyz, &zxzx, &zxzy, &zxzz, &zyxx, &zyxy, &zyxz, + &zyyx, &zyyy, &zyyz, &zyzx, &zyzy, &zyzz, &zzxx, &zzxy, &zzxz, &zzyx, &zzyy, &zzyz, &zzzx, + &zzzy, &zzzz; +}; + +template struct ColSwizzle3 : ColSwizzle2 { + static VecBase &rb, &gb, &br, &bg, &bb, &bw; + static VecBase &rrb, &rgb, &rbr, &rbg, &rbb, &grb, &ggb, &gbr, &gbg, &gbb, &brr, &brg, + &brb, &bgr, &bgg, &bgb, &bbr, &bbg, &bbb; + static VecBase &rrrb, &rrgb, &rrbr, &rrbg, &rrbb, &rgrb, &rggb, &rgbr, &rgbg, &rgbb, &rbrr, + &rbrg, &rbrb, &rbgr, &rbgg, &rbgb, &rbbr, &rbbg, &rbbb, &grrb, &grgb, &grbr, &grbg, &grbb, + &ggrb, &gggb, &ggbr, &ggbg, &ggbb, &gbrr, &gbrg, &gbrb, &gbgr, &gbgg, &gbgb, &gbbr, &gbbg, + &gbbb, &brrr, &brrg, &brrb, &brgr, &brgg, &brgb, &brbr, &brbg, &brbb, &bgrr, &bgrg, &bgrb, + &bggr, &bggg, &bggb, &bgbr, &bgbg, &bgbb, &bbrr, &bbrg, &bbrb, &bbgr, &bbgg, &bbgb, &bbbr, + &bbbg, &bbbb; +}; + +template struct VecSwizzle4 : VecSwizzle3 { + static VecBase &xw, &yw, &wx, &wy, &wz, &ww; + static VecBase &xxw, &xyw, &xzw, &xwx, &xwy, &xwz, &xww, &yxw, &yyw, &yzw, &ywx, &ywy, + &ywz, &yww, &zxw, &zyw, &zzw, &zwx, &zwy, &zwz, &zww, &wxx, &wxy, &wxz, &wxw, &wyx, &wyy, + &wyz, &wyw, &wzx, &wzy, &wzz, &wzw, &wwx, &wwy, &wwz, &www; + static VecBase &xxxw, &xxyw, &xxzw, &xxwx, &xxwy, &xxwz, &xxww, &xyxw, &xyyw, &xyzw, &xywx, + &xywy, &xywz, &xyww, &xzxw, &xzyw, &xzzw, &xzwx, &xzwy, &xzwz, &xzww, &xwxx, &xwxy, &xwxz, + &xwxw, &xwyx, &xwyy, &xwyz, &xwyw, &xwzx, &xwzy, &xwzz, &xwzw, &xwwx, &xwwy, &xwwz, &xwww, + &yxxw, &yxyw, &yxzw, &yxwx, &yxwy, &yxwz, &yxww, &yyxw, &yyyw, &yyzw, &yywx, &yywy, &yywz, + &yyww, &yzxw, &yzyw, &yzzw, &yzwx, &yzwy, &yzwz, &yzww, &ywxx, &ywxy, &ywxz, &ywxw, &ywyx, + &ywyy, &ywyz, &ywyw, &ywzx, &ywzy, &ywzz, &ywzw, &ywwx, &ywwy, &ywwz, &ywww, &zxxw, &zxyw, + &zxzw, &zxwx, &zxwy, &zxwz, &zxww, &zyxw, &zyyw, &zyzw, &zywx, &zywy, &zywz, &zyww, &zzxw, + &zzyw, &zzzw, &zzwx, &zzwy, &zzwz, &zzww, &zwxx, &zwxy, &zwxz, &zwxw, &zwyx, &zwyy, &zwyz, + &zwyw, &zwzx, &zwzy, &zwzz, &zwzw, &zwwx, &zwwy, &zwwz, &zwww, &wxxx, &wxxy, &wxxz, &wxxw, + &wxyx, &wxyy, &wxyz, &wxyw, &wxzx, &wxzy, &wxzz, &wxzw, &wxwx, &wxwy, &wxwz, &wxww, &wyxx, + &wyxy, &wyxz, &wyxw, &wyyx, &wyyy, &wyyz, &wyyw, &wyzx, &wyzy, &wyzz, &wyzw, &wywx, &wywy, + &wywz, &wyww, &wzxx, &wzxy, &wzxz, &wzxw, &wzyx, &wzyy, &wzyz, &wzyw, &wzzx, &wzzy, &wzzz, + &wzzw, &wzwx, &wzwy, &wzwz, &wzww, &wwxx, &wwxy, &wwxz, &wwxw, &wwyx, &wwyy, &wwyz, &wwyw, + &wwzx, &wwzy, &wwzz, &wwzw, &wwwx, &wwwy, &wwwz, &wwww; +}; + +template struct ColSwizzle4 : ColSwizzle3 { + static VecBase &ra, &ga, &ar, &ag, &ab, &aa; + static VecBase &rra, &rga, &rba, &rar, &rag, &rab, &raa, &gra, &gga, &gba, &gar, &gag, + &gab, &gaa, &bra, &bga, &bba, &bar, &bag, &bab, &baa, &arr, &arg, &arb, &ara, &agr, &agg, + &agb, &aga, &abr, &abg, &abb, &aba, &aar, &aag, &aab, &aaa; + static VecBase &rrra, &rrga, &rrba, &rrar, &rrag, &rrab, &rraa, &rgra, &rgga, &rgba, &rgar, + &rgag, &rgab, &rgaa, &rbra, &rbga, &rbba, &rbar, &rbag, &rbab, &rbaa, &rarr, &rarg, &rarb, + &rara, &ragr, &ragg, &ragb, &raga, &rabr, &rabg, &rabb, &raba, &raar, &raag, &raab, &raaa, + &grra, &grga, &grba, &grar, &grag, &grab, &graa, &ggra, &ggga, &ggba, &ggar, &ggag, &ggab, + &ggaa, &gbra, &gbga, &gbba, &gbar, &gbag, &gbab, &gbaa, &garr, &garg, &garb, &gara, &gagr, + &gagg, &gagb, &gaga, &gabr, &gabg, &gabb, &gaba, &gaar, &gaag, &gaab, &gaaa, &brra, &brga, + &brba, &brar, &brag, &brab, &braa, &bgra, &bgga, &bgba, &bgar, &bgag, &bgab, &bgaa, &bbra, + &bbga, &bbba, &bbar, &bbag, &bbab, &bbaa, &barr, &barg, &barb, &bara, &bagr, &bagg, &bagb, + &baga, &babr, &babg, &babb, &baba, &baar, &baag, &baab, &baaa, &arrr, &arrg, &arrb, &arra, + &argr, &argg, &argb, &arga, &arbr, &arbg, &arbb, &arba, &arar, &arag, &arab, &araa, &agrr, + &agrg, &agrb, &agra, &aggr, &aggg, &aggb, &agga, &agbr, &agbg, &agbb, &agba, &agar, &agag, + &agab, &agaa, &abrr, &abrg, &abrb, &abra, &abgr, &abgg, &abgb, &abga, &abbr, &abbg, &abbb, + &abba, &abar, &abag, &abab, &abaa, &aarr, &aarg, &aarb, &aara, &aagr, &aagg, &aagb, &aaga, + &aabr, &aabg, &aabb, &aaba, &aaar, &aaag, &aaab, &aaaa; +}; + +template struct VecBase : VecOp, VecSwizzle2, ColSwizzle2 { + T x, y; + T r, g; + + VecBase() = default; + template explicit VecBase(VecBase) {} + explicit VecBase(T) {} + explicit VecBase(T, T) {} +}; + +template struct VecBase : VecOp, VecSwizzle3, ColSwizzle3 { + T x, y, z; + T r, g, b; + + VecBase() = default; + template explicit VecBase(VecBase) {} + explicit VecBase(T) {} + explicit VecBase(T, T, T) {} + explicit VecBase(VecBase, T) {} + explicit VecBase(T, VecBase) {} +}; + +template struct VecBase : VecOp, VecSwizzle4, ColSwizzle4 { + T x, y, z, w; + T r, g, b, a; + + VecBase() = default; + template explicit VecBase(VecBase) {} + explicit VecBase(T) {} + explicit VecBase(T, T, T, T) {} + explicit VecBase(VecBase, T, T) {} + explicit VecBase(T, VecBase, T) {} + explicit VecBase(T, T, VecBase) {} + explicit VecBase(VecBase, VecBase) {} + explicit VecBase(VecBase, T) {} + explicit VecBase(T, VecBase) {} +}; + +/* Boolean vectors do not have operators and are not convertible from other types. */ + +template<> struct VecBase : VecSwizzle2 { + bool x, y; + + VecBase() = default; + explicit VecBase(bool) {} + explicit VecBase(bool, bool) {} +}; + +template<> struct VecBase : VecSwizzle3 { + bool x, y, z; + + VecBase() = default; + explicit VecBase(bool) {} + explicit VecBase(bool, bool, bool) {} + explicit VecBase(VecBase, bool) {} + explicit VecBase(bool, VecBase) {} +}; + +template<> struct VecBase : VecSwizzle4 { + bool x, y, z, w; + + VecBase() = default; + explicit VecBase(bool) {} + explicit VecBase(bool, bool, bool, bool) {} + explicit VecBase(VecBase, bool, bool) {} + explicit VecBase(bool, VecBase, bool) {} + explicit VecBase(bool, bool, VecBase) {} + explicit VecBase(VecBase, VecBase) {} + explicit VecBase(VecBase, bool) {} + explicit VecBase(bool, VecBase) {} +}; + +using uint = unsigned int; + +using float2 = VecBase; +using float3 = VecBase; +using float4 = VecBase; + +using uint2 = VecBase; +using uint3 = VecBase; +using uint4 = VecBase; + +using int2 = VecBase; +using int3 = VecBase; +using int4 = VecBase; + +using bool2 = VecBase; +using bool3 = VecBase; +using bool4 = VecBase; + +using vec2 = float2; +using vec3 = float3; +using vec4 = float4; + +using ivec2 = int2; +using ivec3 = int3; +using ivec4 = int4; + +using uvec2 = uint2; +using uvec3 = uint3; +using uvec4 = uint4; + +using bvec2 = bool2; +using bvec3 = bool3; +using bvec4 = bool4; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Matrix Types + * \{ */ + +template struct MatBase {}; + +template struct MatOp { + using MatT = MatBase; + using ColT = VecBase; + using RowT = VecBase; + + ColT &operator[](int) {} + + MatT operator*(MatT) const {} + + friend ColT operator*(RowT, MatT) {} + friend RowT operator*(MatT, ColT) {} +}; + +template struct MatBase<2, R> : MatOp<2, R> { + using T = double; + using ColT = VecBase; + ColT x, y; + + MatBase() = default; + explicit MatBase(T) {} + explicit MatBase(T, T, T, T) {} + explicit MatBase(ColT, ColT) {} + template explicit MatBase(const MatBase &) {} +}; + +template struct MatBase<3, R> : MatOp<3, R> { + using T = double; + using ColT = VecBase; + ColT x, y, z; + + MatBase() = default; + explicit MatBase(T) {} + explicit MatBase(T, T, T, T, T, T, T, T, T) {} + explicit MatBase(ColT, ColT, ColT) {} + template explicit MatBase(const MatBase &) {} +}; + +template struct MatBase<4, R> : MatOp<4, R> { + using T = double; + using ColT = VecBase; + ColT x, y, z, w; + + MatBase() = default; + explicit MatBase(T) {} + explicit MatBase(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) {} + explicit MatBase(ColT, ColT, ColT, ColT) {} + template explicit MatBase(const MatBase &) {} +}; + +using float2x2 = MatBase<2, 2>; +using float2x3 = MatBase<2, 3>; +using float2x4 = MatBase<2, 4>; +using float3x2 = MatBase<3, 2>; +using float3x3 = MatBase<3, 3>; +using float3x4 = MatBase<3, 4>; +using float4x2 = MatBase<4, 2>; +using float4x3 = MatBase<4, 3>; +using float4x4 = MatBase<4, 4>; + +using mat2x2 = float2x2; +using mat2x3 = float2x3; +using mat2x4 = float2x4; +using mat3x2 = float3x2; +using mat3x3 = float3x3; +using mat3x4 = float3x4; +using mat4x2 = float4x2; +using mat4x3 = float4x3; +using mat4x4 = float4x4; + +using mat2 = float2x2; +using mat3 = float3x3; +using mat4 = float4x4; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Sampler Types + * \{ */ + +template struct SamplerBase { + static constexpr int coord_dim = Dimensions + int(Cube) + int(Array); + static constexpr int deriv_dim = Dimensions + int(Cube); + static constexpr int extent_dim = Dimensions + int(Array); + + using int_coord_type = VecBase; + using flt_coord_type = VecBase; + using derivative_type = VecBase; + using data_vec_type = VecBase; + using size_vec_type = VecBase; +}; + +#define TEX_TEMPLATE \ + template + +TEX_TEMPLATE SizeVec textureSize(T, int) {} +TEX_TEMPLATE DataVec texelFetch(T, IntCoord, int) {} +TEX_TEMPLATE DataVec texelFetchOffset(T, IntCoord, int, IntCoord) {} +TEX_TEMPLATE DataVec texture(T, FltCoord, double bias = 0.0) {} +TEX_TEMPLATE DataVec textureGather(T, FltCoord) {} +TEX_TEMPLATE DataVec textureGrad(T, FltCoord, DerivVec, DerivVec) {} +TEX_TEMPLATE DataVec textureLod(T, FltCoord, double) {} + +#undef TEX_TEMPLATE + +using sampler1D = SamplerBase; +using sampler2D = SamplerBase; +using sampler3D = SamplerBase; +using isampler1D = SamplerBase; +using isampler2D = SamplerBase; +using isampler3D = SamplerBase; +using usampler1D = SamplerBase; +using usampler2D = SamplerBase; +using usampler3D = SamplerBase; + +using sampler1DArray = SamplerBase; +using sampler2DArray = SamplerBase; +using isampler1DArray = SamplerBase; +using isampler2DArray = SamplerBase; +using usampler1DArray = SamplerBase; +using usampler2DArray = SamplerBase; + +using samplerCube = SamplerBase; +using isamplerCube = SamplerBase; +using usamplerCube = SamplerBase; + +using samplerCubeArray = SamplerBase; +using isamplerCubeArray = SamplerBase; +using usamplerCubeArray = SamplerBase; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Image Types + * \{ */ + +template struct ImageBase { + static constexpr int coord_dim = Dimensions + int(Array); + + using int_coord_type = VecBase; + using data_vec_type = VecBase; + using size_vec_type = VecBase; +}; + +#define IMG_TEMPLATE \ + template + +IMG_TEMPLATE SizeVec imageSize(const T &) {} +IMG_TEMPLATE DataVec imageLoad(const T &, IntCoord) {} +IMG_TEMPLATE void imageStore(T &, IntCoord, DataVec) {} +IMG_TEMPLATE void imageFence(T &) {} +/* Cannot write to a read only image. */ +IMG_TEMPLATE void imageStore(const T &, IntCoord, DataVec) = delete; +IMG_TEMPLATE void imageFence(const T &) = delete; + +#define imageLoadFast imageLoad +#define imageStoreFast imageStore + +IMG_TEMPLATE uint imageAtomicAdd(T &, IntCoord, uint) {} +IMG_TEMPLATE uint imageAtomicMin(T &, IntCoord, uint) {} +IMG_TEMPLATE uint imageAtomicMax(T &, IntCoord, uint) {} +IMG_TEMPLATE uint imageAtomicAnd(T &, IntCoord, uint) {} +IMG_TEMPLATE uint imageAtomicXor(T &, IntCoord, uint) {} +IMG_TEMPLATE uint imageAtomicExchange(T &, IntCoord, uint) {} +IMG_TEMPLATE uint imageAtomicCompSwap(T &, IntCoord, uint, uint) {} +/* Cannot write to a read only image. */ +IMG_TEMPLATE uint imageAtomicAdd(const T &, IntCoord, uint) = delete; +IMG_TEMPLATE uint imageAtomicMin(const T &, IntCoord, uint) = delete; +IMG_TEMPLATE uint imageAtomicMax(const T &, IntCoord, uint) = delete; +IMG_TEMPLATE uint imageAtomicAnd(const T &, IntCoord, uint) = delete; +IMG_TEMPLATE uint imageAtomicXor(const T &, IntCoord, uint) = delete; +IMG_TEMPLATE uint imageAtomicExchange(const T &, IntCoord, uint) = delete; +IMG_TEMPLATE uint imageAtomicCompSwap(const T &, IntCoord, uint, uint) = delete; + +#undef IMG_TEMPLATE + +using image1D = ImageBase; +using image2D = ImageBase; +using image3D = ImageBase; +using iimage1D = ImageBase; +using iimage2D = ImageBase; +using iimage3D = ImageBase; +using uimage1D = ImageBase; +using uimage2D = ImageBase; +using uimage3D = ImageBase; + +using image1DArray = ImageBase; +using image2DArray = ImageBase; +using iimage1DArray = ImageBase; +using iimage2DArray = ImageBase; +using uimage1DArray = ImageBase; +using uimage2DArray = ImageBase; + +/* Forbid Cube and cube arrays. Bind them as 3D textures instead. */ + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Builtin Functions + * \{ */ + +/* Some compilers complain about lack of return values. Keep it short. */ +#define RET \ + { \ + return {}; \ + } + +template VecBase greaterThan(VecBase, VecBase) RET; +template VecBase lessThan(VecBase, VecBase) RET; +template VecBase lessThanEqual(VecBase, VecBase) RET; +template VecBase greaterThanEqual(VecBase, VecBase) RET; +template VecBase equal(VecBase, VecBase) RET; +template VecBase notEqual(VecBase, VecBase) RET; +template bool any(VecBase) RET; +template bool all(VecBase) RET; +/* `not` is a C++ keyword that aliases the `!` operator. Simply overload it. */ +template VecBase operator!(VecBase) RET; + +template VecBase bitCount(VecBase) RET; +template VecBase bitCount(VecBase) RET; +template VecBase bitfieldExtract(VecBase, int, int) RET; +template VecBase bitfieldExtract(VecBase, int, int) RET; +template VecBase bitfieldInsert(VecBase, VecBase, int, int) RET; +template VecBase bitfieldInsert(VecBase, VecBase, int, int) RET; +template VecBase bitfieldReverse(VecBase) RET; +template VecBase bitfieldReverse(VecBase) RET; +int bitCount(int) RET; +int bitCount(uint) RET; +int bitfieldExtract(int) RET; +int bitfieldExtract(uint) RET; +int bitfieldInsert(int) RET; +int bitfieldInsert(uint) RET; +int bitfieldReverse(int) RET; +int bitfieldReverse(uint) RET; + +template VecBase findLSB(VecBase) RET; +template VecBase findLSB(VecBase) RET; +template VecBase findMSB(VecBase) RET; +template VecBase findMSB(VecBase) RET; +int findMSB(int) RET; +int findMSB(uint) RET; + +/* Math Functions. */ +template T abs(T) RET; +template T clamp(T, T, T) RET; +template T max(T, T) RET; +template T min(T, T) RET; +template T sign(T) RET; +template T clamp(T, U, U) RET; +template T max(T, U) RET; +template T min(T, U) RET; +/* TODO(fclem): These should be restricted to floats. */ +template T ceil(T) RET; +template T exp(T) RET; +template T exp2(T) RET; +template T floor(T) RET; +template T fma(T, T, T) RET; +template T fract(T) RET; +template T frexp(T, T) RET; +template T inversesqrt(T) RET; +template T isinf(T) RET; +template T isnan(T) RET; +template T log(T) RET; +template T log2(T) RET; +template T mod(T, double); +template T mod(T, T); +template T modf(T, T); +template T pow(T, T) RET; +template T round(T) RET; +template T smoothstep(T, T, T) RET; +template T sqrt(T) RET; +template T step(T) RET; +template T trunc(T) RET; +template T ldexp(T, U) RET; + +template T acos(T) RET; +template T acosh(T) RET; +template T asin(T) RET; +template T asinh(T) RET; +template T atan(T, T) RET; +template T atan(T) RET; +template T atanh(T) RET; +template T cos(T) RET; +template T cosh(T) RET; +template T sin(T) RET; +template T sinh(T) RET; +template T tan(T) RET; +template T tanh(T) RET; + +template T degrees(T) RET; +template T radians(T) RET; + +/* Declared explicitely to avoid type errors. */ +double mix(double, double, double) RET; +template VecBase mix(VecBase, VecBase, double) RET; +template VecBase mix(VecBase, VecBase, VecBase) RET; + +#define select(A, B, C) mix(A, B, C) + +VecBase cross(VecBase, VecBase) RET; +template float dot(VecBase, VecBase) RET; +template float distance(VecBase, VecBase) RET; +template float length(VecBase) RET; +template VecBase normalize(VecBase) RET; + +template VecBase floatBitsToInt(VecBase) RET; +template VecBase floatBitsToUint(VecBase) RET; +template VecBase intBitsToFloat(VecBase) RET; +template VecBase uintBitsToFloat(VecBase) RET; +int floatBitsToInt(double) RET; +uint floatBitsToUint(double) RET; +double intBitsToFloat(int) RET; +double uintBitsToFloat(uint) RET; + +namespace gl_FragmentShader { +/* Derivative functions. */ +template T dFdx(T) RET; +template T dFdy(T) RET; +template T fwidth(T) RET; +} // namespace gl_FragmentShader + +/* Geometric functions. */ +template float faceforward(VecBase, VecBase, VecBase) RET; +template float reflect(VecBase, VecBase) RET; +template float refract(VecBase, VecBase, double) RET; + +/* Atomic operations. */ +int atomicAdd(int &, int) RET; +int atomicAnd(int &, int) RET; +int atomicOr(int &, int) RET; +int atomicXor(int &, int) RET; +int atomicMin(int &, int) RET; +int atomicMax(int &, int) RET; +int atomicExchange(int &, int) RET; +int atomicCompSwap(int &, int, int) RET; +uint atomicAdd(uint &, uint) RET; +uint atomicAnd(uint &, uint) RET; +uint atomicOr(uint &, uint) RET; +uint atomicXor(uint &, uint) RET; +uint atomicMin(uint &, uint) RET; +uint atomicMax(uint &, uint) RET; +uint atomicExchange(uint &, uint) RET; +uint atomicCompSwap(uint &, uint, uint) RET; + +/* Packing functions. */ +uint packHalf2x16(float2) RET; +uint packUnorm2x16(float2) RET; +uint packSnorm2x16(float2) RET; +uint packUnorm4x8(float4) RET; +uint packSnorm4x8(float4) RET; +float2 unpackHalf2x16(uint) RET; +float2 unpackUnorm2x16(uint) RET; +float2 unpackSnorm2x16(uint) RET; +float4 unpackUnorm4x8(uint) RET; +float4 unpackSnorm4x8(uint) RET; + +/* Matrices functions. */ +template float determinant(MatBase) RET; +template MatBase inverse(MatBase) RET; +template MatBase transpose(MatBase) RET; + +/* TODO(fclem): Should be in a lib instead of being impemented by each backend. */ +bool is_zero(vec2) RET; +bool is_zero(vec3) RET; +bool is_zero(vec4) RET; + +#undef RET + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Special Variables + * \{ */ + +namespace gl_VertexShader { + +const int gl_VertexID = 0; +const int gl_InstanceID = 0; +const int gl_BaseVertex = 0; +const int gl_BaseInstance = 0; +float4 gl_Position = float4(0); +double gl_PointSize = 0; +float gl_ClipDistance[6] = {0}; +int gpu_Layer = 0; +int gpu_ViewportIndex = 0; + +} // namespace gl_VertexShader + +namespace gl_FragmentShader { + +const float4 gl_FragCoord = float4(0); +const bool gl_FrontFacing = true; +const float2 gl_PointCoord = float2(0); +const int gl_PrimitiveID = 0; +float gl_FragDepth = 0; +const float gl_ClipDistance[6] = {0}; +const int gpu_Layer = 0; +const int gpu_ViewportIndex = 0; + +} // namespace gl_FragmentShader + +namespace gl_ComputeShader { + +const uint3 gl_NumWorkGroups; +constexpr uint3 gl_WorkGroupSize; +const uint3 gl_WorkGroupID; +const uint3 gl_LocalInvocationID; +const uint3 gl_GlobalInvocationID; +const uint gl_LocalInvocationIndex; + +} // namespace gl_ComputeShader + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Keywords + * \{ */ + +/* Note: Cannot easily mutate them. Pass every by copy for now. */ + +/* Pass argument by reference. */ +#define inout +/* Pass argument by reference but only write to it. Its initial value is undefined. */ +#define out +/* Pass argument by copy (default). */ +#define in + +/* Discards the output of the current fragment shader invocation and halts its execution. */ +#define discard + +/* Decorate a variable in global scope that is common to all threads in a threadgroup. */ +#define shared + +namespace gl_ComputeShader { +void barrier() {} +void memoryBarrier() {} +void memoryBarrierShared() {} +void memoryBarrierImage() {} +void memoryBarrierBuffer() {} +void groupMemoryBarrier() {} +} // namespace gl_ComputeShader + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Compatibility + * \{ */ + +/* Array syntax compatibility. */ +/* clang-format off */ +#define float_array(...) { __VA_ARGS__ } +#define float2_array(...) { __VA_ARGS__ } +#define float3_array(...) { __VA_ARGS__ } +#define float4_array(...) { __VA_ARGS__ } +#define int_array(...) { __VA_ARGS__ } +#define int2_array(...) { __VA_ARGS__ } +#define int3_array(...) { __VA_ARGS__ } +#define int4_array(...) { __VA_ARGS__ } +#define uint_array(...) { __VA_ARGS__ } +#define uint2_array(...) { __VA_ARGS__ } +#define uint3_array(...) { __VA_ARGS__ } +#define uint4_array(...) { __VA_ARGS__ } +#define bool_array(...) { __VA_ARGS__ } +#define bool2_array(...) { __VA_ARGS__ } +#define bool3_array(...) { __VA_ARGS__ } +#define bool4_array(...) { __VA_ARGS__ } +/* clang-format on */ + +/** \} */ + +#define GLSL_CPP_STUBS + +/* Include all shader shared files to that custom type definitions are available when create infos + * macros are included. Include them here so that only including this file is needed. */ +#include "GPU_shader_shared.hh" +#include "draw_common_shader_shared.hh" +#include "draw_shader_shared.hh" +#include "eevee_shader_shared.hh" +#include "overlay_shader_shared.h" +#include "select_shader_shared.hh" +#include "workbench_shader_shared.h" + +/* TODO(fclem): Include all create infos here so that they don't need to be individually included + * inside shaders. */ diff --git a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl index f605da8baa5..961fb63ad30 100644 --- a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl +++ b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl @@ -2529,3 +2529,23 @@ mat3x4 MAT3x4(mat2 m) #define MAT2 MAT2x2 #define MAT3 MAT3x3 #define MAT4 MAT4x4 + +/* Array syntax compatibility. */ +/* clang-format off */ +#define float_array(...) { __VA_ARGS__ } +#define float2_array(...) { __VA_ARGS__ } +#define float3_array(...) { __VA_ARGS__ } +#define float4_array(...) { __VA_ARGS__ } +#define int_array(...) { __VA_ARGS__ } +#define int2_array(...) { __VA_ARGS__ } +#define int3_array(...) { __VA_ARGS__ } +#define int4_array(...) { __VA_ARGS__ } +#define uint_array(...) { __VA_ARGS__ } +#define uint2_array(...) { __VA_ARGS__ } +#define uint3_array(...) { __VA_ARGS__ } +#define uint4_array(...) { __VA_ARGS__ } +#define bool_array(...) { __VA_ARGS__ } +#define bool2_array(...) { __VA_ARGS__ } +#define bool3_array(...) { __VA_ARGS__ } +#define bool4_array(...) { __VA_ARGS__ } +/* clang-format on */ diff --git a/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl b/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl index 29413d63605..9f10b4ba88d 100644 --- a/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl +++ b/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl @@ -103,3 +103,21 @@ bool is_zero(vec4 A) { return all(equal(A, vec4(0.0))); } + +/* Array syntax compatibility. */ +#define float_array float[] +#define float2_array vec2[] +#define float3_array vec3[] +#define float4_array vec4[] +#define int_array int[] +#define int2_array int2[] +#define int3_array int3[] +#define int4_array int4[] +#define uint_array uint[] +#define uint2_array uint2[] +#define uint3_array uint3[] +#define uint4_array uint4[] +#define bool_array bool[] +#define bool2_array bool2[] +#define bool3_array bool3[] +#define bool4_array bool4[]