summaryrefslogtreecommitdiffstats
path: root/prelude
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-08-20 09:43:59 -0400
committerGitHub <noreply@github.com>2019-08-20 09:43:59 -0400
commit7258ef4ddebd021208a019f6ee73edcda57a88f7 (patch)
tree30cccf48c8f03e59e48a2d265e05494238fe758d /prelude
parent3e78e4654cdf9556869325f2ed2da517f252d879 (diff)
User defined downstream compiler prelude (#1028)
* Added setDownstreamCompilerPrelude Renamed setPassThroughPath to setDownstreamCompilerPath. Fixed tests. Added prelude directory & code to TestToolUtil to setup default preludes for testing/command line apis. * Fix merge problem * Remove hacks to make prelude work by adding a search path as no longer needed with 'user prelude'. * Split up prelude into scalar intrinsics, and types. Use slang.h for main header. slang-cpp-prelude.h can now just include what it needs (relative to prelude directory) and define the few remaining things/work arounds. * Fix typo.
Diffstat (limited to 'prelude')
-rw-r--r--prelude/slang-cpp-prelude.h33
-rw-r--r--prelude/slang-cpp-scalar-intrinsics.h147
-rw-r--r--prelude/slang-cpp-types.h239
3 files changed, 419 insertions, 0 deletions
diff --git a/prelude/slang-cpp-prelude.h b/prelude/slang-cpp-prelude.h
new file mode 100644
index 000000000..15d200d2f
--- /dev/null
+++ b/prelude/slang-cpp-prelude.h
@@ -0,0 +1,33 @@
+#ifndef SLANG_CPP_PRELUDE_H
+#define SLANG_CPP_PRELUDE_H
+
+#include "../slang.h"
+
+#include <math.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#if defined(_MSC_VER)
+# define SLANG_PRELUDE_SHARED_LIB_EXPORT __declspec(dllexport)
+#else
+# define SLANG_PRELUDE_SHARED_LIB_EXPORT __attribute__((__visibility__("default")))
+//# define SLANG_PRELUDE_SHARED_LIB_EXPORT __attribute__ ((dllexport)) __attribute__((__visibility__("default")))
+#endif
+
+#ifdef __cplusplus
+# define SLANG_PRELUDE_EXTERN_C extern "C"
+#else
+# define SLANG_PRELUDE_EXTERN_C
+#endif
+
+#define SLANG_PRELUDE_EXPORT SLANG_PRELUDE_EXTERN_C SLANG_PRELUDE_SHARED_LIB_EXPORT
+
+#include "slang-cpp-types.h"
+#include "slang-cpp-scalar-intrinsics.h"
+
+// TODO(JS): Hack! Output C++ code from slang can copy uninitialized variables.
+#if SLANG_VC
+# pragma warning(disable : 4700)
+#endif
+
+#endif
diff --git a/prelude/slang-cpp-scalar-intrinsics.h b/prelude/slang-cpp-scalar-intrinsics.h
new file mode 100644
index 000000000..217a79e02
--- /dev/null
+++ b/prelude/slang-cpp-scalar-intrinsics.h
@@ -0,0 +1,147 @@
+#ifndef SLANG_PRELUDE_SCALAR_INTRINSICS_H
+#define SLANG_PRELUDE_SCALAR_INTRINSICS_H
+
+#include "../slang.h"
+
+#ifdef SLANG_PRELUDE_NAMESPACE
+namespace SLANG_PRELUDE_NAMESPACE {
+#endif
+
+#ifndef SLANG_PRELUDE_PI
+# define SLANG_PRELUDE_PI 3.14159265358979323846
+#endif
+
+// ----------------------------- F32 -----------------------------------------
+
+union Union32
+{
+ uint32_t u;
+ int32_t i;
+ float f;
+};
+
+// Helpers
+SLANG_FORCE_INLINE float F32_calcSafeRadians(float radians)
+{
+ float a = radians * (1.0f / float(SLANG_PRELUDE_PI));
+ a = (a < 0.0f) ? (::ceilf(a) - a) : (a - ::floorf(a));
+ return (a * float(SLANG_PRELUDE_PI));
+}
+
+// Unary
+SLANG_FORCE_INLINE float F32_ceil(float f) { return ::ceilf(f); }
+SLANG_FORCE_INLINE float F32_floor(float f) { return ::floorf(f); }
+SLANG_FORCE_INLINE float F32_sin(float f) { return ::sinf(F32_calcSafeRadians(f)); }
+SLANG_FORCE_INLINE float F32_cos(float f) { return ::cosf(F32_calcSafeRadians(f)); }
+SLANG_FORCE_INLINE float F32_tan(float f) { return ::tanf(f); }
+SLANG_FORCE_INLINE float F32_asin(float f) { return ::asinf(f); }
+SLANG_FORCE_INLINE float F32_acos(float f) { return ::acosf(f); }
+SLANG_FORCE_INLINE float F32_atan(float f) { return ::atanf(f); }
+SLANG_FORCE_INLINE float F32_log2(float f) { return ::log2f(f); }
+SLANG_FORCE_INLINE float F32_exp2(float f) { return ::exp2f(f); }
+SLANG_FORCE_INLINE float F32_exp(float f) { return ::expf(f); }
+SLANG_FORCE_INLINE float F32_abs(float f) { return ::fabsf(f); }
+SLANG_FORCE_INLINE float F32_trunc(float f) { return ::truncf(f); }
+SLANG_FORCE_INLINE float F32_sqrt(float f) { return ::sqrtf(f); }
+SLANG_FORCE_INLINE float F32_rsqrt(float f) { return 1.0f / F32_sqrt(f); }
+SLANG_FORCE_INLINE float F32_rcp(float f) { return 1.0f / f; }
+SLANG_FORCE_INLINE float F32_sign(float f) { return ( f == 0.0f) ? f : (( f < 0.0f) ? -1.0f : 1.0f); }
+SLANG_FORCE_INLINE float F32_saturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
+SLANG_FORCE_INLINE float F32_frac(float f) { return f - F32_floor(f); }
+SLANG_FORCE_INLINE float F32_radians(float f) { return f * 0.01745329222f; }
+
+// Binary
+SLANG_FORCE_INLINE float F32_min(float a, float b) { return a < b ? a : b; }
+SLANG_FORCE_INLINE float F32_max(float a, float b) { return a > b ? a : b; }
+SLANG_FORCE_INLINE float F32_pow(float a, float b) { return ::powf(a, b); }
+SLANG_FORCE_INLINE float F32_fmod(float a, float b) { return ::fmodf(a, b); }
+SLANG_FORCE_INLINE float F32_step(float a, float b) { return float(a >= b); }
+SLANG_FORCE_INLINE float F32_atan2(float a, float b) { return float(atan2(a, b)); }
+
+// Ternary
+SLANG_FORCE_INLINE float F32_smoothstep(float min, float max, float x) { return x < min ? min : ((x > max) ? max : x / (max - min)); }
+SLANG_FORCE_INLINE float F32_lerp(float x, float y, float s) { return x + s * (y - x); }
+SLANG_FORCE_INLINE float F32_clamp(float x, float min, float max) { return ( x < min) ? min : ((x > max) ? max : x); }
+SLANG_FORCE_INLINE void F32_sincos(float f, float& outSin, float& outCos) { outSin = F32_sin(f); outCos = F32_cos(f); }
+
+SLANG_FORCE_INLINE uint32_t F32_asuint(float f) { Union32 u; u.f = f; return u.u; }
+SLANG_FORCE_INLINE int32_t F32_asint(float f) { Union32 u; u.f = f; return u.i; }
+
+// ----------------------------- F64 -----------------------------------------
+
+SLANG_FORCE_INLINE double F64_calcSafeRadians(double radians)
+{
+ double a = radians * (1.0 / SLANG_PRELUDE_PI);
+ a = (a < 0.0) ? (::ceil(a) - a) : (a - ::floor(a));
+ return (a * SLANG_PRELUDE_PI);
+}
+
+// Unary
+SLANG_FORCE_INLINE double F64_ceil(double f) { return ::ceil(f); }
+SLANG_FORCE_INLINE double F64_floor(double f) { return ::floor(f); }
+SLANG_FORCE_INLINE double F64_sin(double f) { return ::sin(F64_calcSafeRadians(f)); }
+SLANG_FORCE_INLINE double F64_cos(double f) { return ::cos(F64_calcSafeRadians(f)); }
+SLANG_FORCE_INLINE double F64_tan(double f) { return ::tan(f); }
+SLANG_FORCE_INLINE double F64_asin(double f) { return ::asin(f); }
+SLANG_FORCE_INLINE double F64_acos(double f) { return ::acos(f); }
+SLANG_FORCE_INLINE double F64_atan(double f) { return ::atan(f); }
+SLANG_FORCE_INLINE double F64_log2(double f) { return ::log2(f); }
+SLANG_FORCE_INLINE double F64_exp2(double f) { return ::exp2(f); }
+SLANG_FORCE_INLINE double F64_exp(double f) { return ::exp(f); }
+SLANG_FORCE_INLINE double F64_abs(double f) { return ::fabs(f); }
+SLANG_FORCE_INLINE double F64_trunc(double f) { return ::trunc(f); }
+SLANG_FORCE_INLINE double F64_sqrt(double f) { return ::sqrt(f); }
+SLANG_FORCE_INLINE double F64_rsqrt(double f) { return 1.0 / F64_sqrt(f); }
+SLANG_FORCE_INLINE double F64_rcp(double f) { return 1.0 / f; }
+SLANG_FORCE_INLINE double F64_sign(double f) { return (f == 0.0) ? f : ((f < 0.0) ? -1.0 : 1.0); }
+SLANG_FORCE_INLINE double F64_saturate(double f) { return (f < 0.0) ? 0.0 : (f > 1.0) ? 1.0 : f; }
+SLANG_FORCE_INLINE double F64_frac(double f) { return f - F64_floor(f); }
+SLANG_FORCE_INLINE double F64_radians(double f) { return f * 0.01745329222; }
+
+// Binary
+SLANG_FORCE_INLINE double F64_min(double a, double b) { return a < b ? a : b; }
+SLANG_FORCE_INLINE double F64_max(double a, double b) { return a > b ? a : b; }
+SLANG_FORCE_INLINE double F64_pow(double a, double b) { return ::pow(a, b); }
+SLANG_FORCE_INLINE double F64_fmod(double a, double b) { return ::fmod(a, b); }
+SLANG_FORCE_INLINE double F64_step(double a, double b) { return double(a >= b); }
+SLANG_FORCE_INLINE double F64_atan2(double a, double b) { return atan2(a, b); }
+
+// Ternary
+SLANG_FORCE_INLINE double F64_smoothstep(double min, double max, double x) { return x < min ? min : ((x > max) ? max : x / (max - min)); }
+SLANG_FORCE_INLINE double F64_lerp(double x, double y, double s) { return x + s * (y - x); }
+SLANG_FORCE_INLINE double F64_clamp(double x, double min, double max) { return (x < min) ? min : ((x > max) ? max : x); }
+SLANG_FORCE_INLINE void F64_sincos(double f, double& outSin, double& outCos) { outSin = F64_sin(f); outCos = F64_cos(f); }
+
+// TODO!
+//uint32_t F64_asuint(float f);
+//int32_t F64_asint(float f);
+
+// ----------------------------- I32 -----------------------------------------
+
+SLANG_FORCE_INLINE int32_t I32_abs(int32_t f) { return (f < 0) ? -f : f; }
+
+SLANG_FORCE_INLINE int32_t I32_min(int32_t a, int32_t b) { return a < b ? a : b; }
+SLANG_FORCE_INLINE int32_t I32_max(int32_t a, int32_t b) { return a > b ? a : b; }
+
+SLANG_FORCE_INLINE int32_t I32_clamp(int32_t x, int32_t min, int32_t max) { return ( x < min) ? min : ((x > max) ? max : x); }
+
+SLANG_FORCE_INLINE float I32_asfloat(int32_t x) { Union32 u; u.i = x; return u.f; }
+SLANG_FORCE_INLINE uint32_t I32_asuint(int32_t x) { return uint32_t(x); }
+
+// ----------------------------- U32 -----------------------------------------
+
+SLANG_FORCE_INLINE uint32_t U32_abs(uint32_t f) { return f; }
+
+SLANG_FORCE_INLINE uint32_t U32_min(uint32_t a, uint32_t b) { return a < b ? a : b; }
+SLANG_FORCE_INLINE uint32_t U32_max(uint32_t a, uint32_t b) { return a > b ? a : b; }
+
+SLANG_FORCE_INLINE uint32_t U32_clamp(uint32_t x, uint32_t min, uint32_t max) { return ( x < min) ? min : ((x > max) ? max : x); }
+
+SLANG_FORCE_INLINE float U32_asfloat(uint32_t x) { Union32 u; u.u = x; return u.f; }
+SLANG_FORCE_INLINE uint32_t U32_asint(int32_t x) { return uint32_t(x); }
+
+#ifdef SLANG_PRELUDE_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/prelude/slang-cpp-types.h b/prelude/slang-cpp-types.h
new file mode 100644
index 000000000..20e28a16f
--- /dev/null
+++ b/prelude/slang-cpp-types.h
@@ -0,0 +1,239 @@
+#ifndef SLANG_PRELUDE_CPP_TYPES_H
+#define SLANG_PRELUDE_CPP_TYPES_H
+
+#include "../slang.h"
+
+#ifdef SLANG_PRELUDE_NAMESPACE
+namespace SLANG_PRELUDE_NAMESPACE {
+#endif
+
+template <typename T, size_t SIZE>
+struct FixedArray
+{
+ const T& operator[](size_t index) const { assert(index < SIZE); return m_data[index]; }
+ T& operator[](size_t index) { assert(index < SIZE); return m_data[index]; }
+
+ T m_data[SIZE];
+};
+
+
+// Hmm... I guess a constant buffer should be unwrapped to be just a struct passed in
+/* template <typename T>
+struct ConstantBuffer
+{
+}; */
+
+template <typename T, int COUNT>
+struct Vector;
+
+template <typename T>
+struct Vector<T, 1>
+{
+ T x;
+};
+
+template <typename T>
+struct Vector<T, 2>
+{
+ T x, y;
+};
+
+template <typename T>
+struct Vector<T, 3>
+{
+ T x, y, z;
+};
+
+template <typename T>
+struct Vector<T, 4>
+{
+ T x, y, z, w;
+};
+
+
+typedef Vector<float, 2> float2;
+typedef Vector<float, 3> float3;
+typedef Vector<float, 4> float4;
+
+typedef Vector<int32_t, 2> int2;
+typedef Vector<int32_t, 3> int3;
+typedef Vector<int32_t, 4> int4;
+
+typedef Vector<uint32_t, 2> uint2;
+typedef Vector<uint32_t, 3> uint3;
+typedef Vector<uint32_t, 4> uint4;
+
+template <typename T, int ROWS, int COLS>
+struct Matrix
+{
+ Vector<T, COLS> rows[ROWS];
+};
+
+// ----------------------------- ResourceType -----------------------------------------
+
+// https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-structuredbuffer-getdimensions
+// Missing Load(_In_ int Location, _Out_ uint Status);
+
+template <typename T>
+struct RWStructuredBuffer
+{
+ T& operator[](size_t index) const { assert(index < count); return data[index]; }
+ const T& Load(size_t index) const { assert(index < count); return data[index]; }
+ void GetDimensions(uint32_t& outNumStructs, uint32_t& outStride) { outNumStructs = uint32_t(count); outStride = uint32_t(sizeof(T)); }
+
+ T* data;
+ size_t count;
+};
+
+template <typename T>
+struct StructuredBuffer
+{
+ const T& operator[](size_t index) const { assert(index < count); return data[index]; }
+ const T& Load(size_t index) const { assert(index < count); return data[index]; }
+ void GetDimensions(uint32_t& outNumStructs, uint32_t& outStride) { outNumStructs = uint32_t(count); outStride = uint32_t(sizeof(T)); }
+
+ T* data;
+ size_t count;
+};
+
+// Missing Load(_In_ int Location, _Out_ uint Status);
+struct ByteAddressBuffer
+{
+ void GetDimensions(uint32_t& outDim) const { outDim = uint32_t(sizeInBytes); }
+ uint32_t Load(size_t index) const
+ {
+ assert(index + 4 <= sizeInBytes && (index & 3) == 0);
+ return data[index >> 2];
+ }
+ uint2 Load2(size_t index) const
+ {
+ assert(index + 8 <= sizeInBytes && (index & 3) == 0);
+ const size_t dataIdx = index >> 2;
+ return uint2{data[dataIdx], data[dataIdx + 1]};
+ }
+ uint3 Load3(size_t index) const
+ {
+ assert(index + 12 <= sizeInBytes && (index & 3) == 0);
+ const size_t dataIdx = index >> 2;
+ return uint3{data[dataIdx], data[dataIdx + 1], data[dataIdx + 2]};
+ }
+ uint4 Load4(size_t index) const
+ {
+ assert(index + 16 <= sizeInBytes && (index & 3) == 0);
+ const size_t dataIdx = index >> 2;
+ return uint4{data[dataIdx], data[dataIdx + 1], data[dataIdx + 2], data[dataIdx + 3]};
+ }
+
+ const uint32_t* data;
+ size_t sizeInBytes; //< Must be multiple of 4
+};
+
+// https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-rwbyteaddressbuffer
+// Missing support for Atomic operations
+// Missing support for Load with status
+struct RWByteAddressBuffer
+{
+ void GetDimensions(uint32_t& outDim) const { outDim = uint32_t(sizeInBytes); }
+
+ uint32_t Load(size_t index) const
+ {
+ assert(index + 4 <= sizeInBytes && (index & 3) == 0);
+ return data[index >> 2];
+ }
+ uint2 Load2(size_t index) const
+ {
+ assert(index + 8 <= sizeInBytes && (index & 3) == 0);
+ const size_t dataIdx = index >> 2;
+ return uint2{data[dataIdx], data[dataIdx + 1]};
+ }
+ uint3 Load3(size_t index) const
+ {
+ assert(index + 12 <= sizeInBytes && (index & 3) == 0);
+ const size_t dataIdx = index >> 2;
+ return uint3{data[dataIdx], data[dataIdx + 1], data[dataIdx + 2]};
+ }
+ uint4 Load4(size_t index) const
+ {
+ assert(index + 16 <= sizeInBytes && (index & 3) == 0);
+ const size_t dataIdx = index >> 2;
+ return uint4{data[dataIdx], data[dataIdx + 1], data[dataIdx + 2], data[dataIdx + 3]};
+ }
+
+ void Store(size_t index, uint32_t v) const
+ {
+ assert(index + 4 <= sizeInBytes && (index & 3) == 0);
+ data[index >> 2] = v;
+ }
+ void Store2(size_t index, uint2 v) const
+ {
+ assert(index + 8 <= sizeInBytes && (index & 3) == 0);
+ const size_t dataIdx = index >> 2;
+ data[dataIdx + 0] = v.x;
+ data[dataIdx + 1] = v.y;
+ }
+ void Store3(size_t index, uint3 v) const
+ {
+ assert(index + 12 <= sizeInBytes && (index & 3) == 0);
+ const size_t dataIdx = index >> 2;
+ data[dataIdx + 0] = v.x;
+ data[dataIdx + 1] = v.y;
+ data[dataIdx + 2] = v.z;
+ }
+ void Store4(size_t index, uint4 v) const
+ {
+ assert(index + 16 <= sizeInBytes && (index & 3) == 0);
+ const size_t dataIdx = index >> 2;
+ data[dataIdx + 0] = v.x;
+ data[dataIdx + 1] = v.y;
+ data[dataIdx + 2] = v.z;
+ data[dataIdx + 3] = v.w;
+ }
+
+ uint32_t* data;
+ size_t sizeInBytes; //< Must be multiple of 4
+};
+
+struct ISamplerState;
+struct ISamplerComparisonState;
+
+struct SamplerState
+{
+ ISamplerState* state;
+};
+
+struct SamplerComparisonState
+{
+ ISamplerComparisonState* state;
+};
+
+// Texture
+
+struct ITexture2D
+{
+ virtual void Load(const int3& v, void* out) = 0;
+ virtual void Sample(SamplerState samplerState, const float2& loc, void* out) = 0;
+};
+
+template <typename T>
+struct Texture2D
+{
+ T Load(const int3& v) const { T out; texture->Load(v, &out); return out; }
+ T Sample(SamplerState samplerState, const float2& v) const { T out; texture->Sample(samplerState, v, &out); return out; }
+
+ ITexture2D* texture;
+};
+
+/* Varying input for Compute */
+struct ComputeVaryingInput
+{
+ uint3 groupID;
+ uint3 groupThreadID;
+};
+
+#ifdef SLANG_PRELUDE_NAMESPACE
+}
+#endif
+
+#endif
+
+