summaryrefslogtreecommitdiffstats
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
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.
-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
-rw-r--r--slang.h21
-rw-r--r--source/core/slang-test-tool-util.cpp45
-rw-r--r--source/core/slang-test-tool-util.h3
-rw-r--r--source/slang/slang-check.cpp10
-rw-r--r--source/slang/slang-compiler.cpp85
-rw-r--r--source/slang/slang-compiler.h19
-rw-r--r--source/slang/slang-emit-cpp.cpp2
-rw-r--r--source/slang/slang-emit.cpp25
-rw-r--r--source/slang/slang-options.cpp2
-rw-r--r--source/slang/slang.cpp16
-rw-r--r--source/slangc/main.cpp1
-rw-r--r--tests/compute/slang-cpp-prelude.h826
-rw-r--r--tests/cross-compile/c-cross-compile.slang2
-rw-r--r--tests/cross-compile/slang-cpp-prelude.h824
-rw-r--r--tools/render-test/render-test-main.cpp7
-rw-r--r--tools/slang-test/slang-test-main.cpp52
-rw-r--r--tools/slang-test/test-context.cpp1
20 files changed, 572 insertions, 1788 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
+
+
diff --git a/slang.h b/slang.h
index 0df93ece7..6a6ddd0d0 100644
--- a/slang.h
+++ b/slang.h
@@ -517,6 +517,7 @@ extern "C"
SLANG_EXECUTABLE, ///< Executable (for hosting CPU/OS)
SLANG_SHARED_LIBRARY, ///< A shared library/Dll (for hosting CPU/OS)
SLANG_HOST_CALLABLE, ///< A CPU target that makes the compiled code available to be run immediately
+ SLANG_TARGET_COUNT_OF,
};
/* A "container format" describes the way that the outputs
@@ -2647,13 +2648,27 @@ namespace slang
virtual SLANG_NO_THROW SlangProfileID SLANG_MCALL findProfile(
char const* name) = 0;
- /** Set the path that pass through (aka back end compilers) will
- be looked from. For back ends that are dlls/shared libraries, it will mean the path will
+ /** Set the path that downstream compilers (aka back end compilers) will
+ be looked from.
+ @param passThrough Identifies the downstream compiler
+ @param path The path to find the downstream compiler (shared library/dll/executable)
+
+ For back ends that are dlls/shared libraries, it will mean the path will
be prefixed with the path when calls are made out to ISlangSharedLibraryLoader.
For executables - it will look for executables along the path */
- virtual void SLANG_MCALL setPassThroughPath(
+ virtual SLANG_NO_THROW void SLANG_MCALL setDownstreamCompilerPath(
SlangPassThrough passThrough,
char const* path) = 0;
+
+ /** Set the 'prelude' for generated code for a 'downstream compiler'.
+ @param passThrough The downstream compiler for generated code that will have the prelude applied to it.
+ @param preludeText The text added pre-pended verbatim before the generated source
+
+ That for pass-through usage, prelude is not pre-pended, preludes are for code generation only.
+ */
+ virtual SLANG_NO_THROW void SLANG_MCALL setDownstreamCompilerPrelude(
+ SlangPassThrough passThrough,
+ const char* preludeText) = 0;
};
#define SLANG_UUID_IGlobalSession { 0xc140b5fd, 0xc78, 0x452e, { 0xba, 0x7c, 0x1a, 0x1e, 0x70, 0xc7, 0xf7, 0x1c } };
diff --git a/source/core/slang-test-tool-util.cpp b/source/core/slang-test-tool-util.cpp
index 20ba2fc47..9bf404e5e 100644
--- a/source/core/slang-test-tool-util.cpp
+++ b/source/core/slang-test-tool-util.cpp
@@ -1,6 +1,11 @@
#include "slang-test-tool-util.h"
+#include "../../slang-com-helper.h"
+
+#include "slang-io.h"
+#include "slang-string-util.h"
+
namespace Slang
{
@@ -32,6 +37,46 @@ namespace Slang
}
}
+/* static */SlangResult TestToolUtil::setSessionDefaultPrelude(const char* exePath, slang::IGlobalSession* session)
+{
+ // Set the prelude to a path
+ String canonicalPath;
+ if (SLANG_SUCCEEDED(Path::getCanonical(exePath, canonicalPath)))
+ {
+ // Get the directory
+ canonicalPath = Path::getParentDirectory(canonicalPath);
+
+ String path = Path::combine(canonicalPath, "../../../prelude/slang-cpp-prelude.h");
+ if (SLANG_SUCCEEDED(Path::getCanonical(path, canonicalPath)))
+ {
+ // Use forward slashes, to avoid escaping the path
+ canonicalPath = StringUtil::calcCharReplaced(canonicalPath, '\\', '/');
+
+ // It must exist!
+ if (!File::exists(canonicalPath))
+ {
+ SLANG_ASSERT(!"Couldn't find the prelude relative to the executable");
+ return SLANG_FAIL;
+ }
+
+ StringBuilder prelude;
+ prelude << "#include \"" << canonicalPath << "\"\n\n";
+ const SlangPassThrough downstreamCompilers[] = {
+ SLANG_PASS_THROUGH_CLANG, ///< Clang C/C++ compiler
+ SLANG_PASS_THROUGH_VISUAL_STUDIO, ///< Visual studio C/C++ compiler
+ SLANG_PASS_THROUGH_GCC, ///< GCC C/C++ compiler
+ SLANG_PASS_THROUGH_GENERIC_C_CPP,
+ };
+ for (auto downstreamCompiler : downstreamCompilers)
+ {
+ session->setDownstreamCompilerPrelude(downstreamCompiler, prelude.getBuffer());
+ }
+ }
+ }
+
+ return SLANG_OK;
+}
+
}
diff --git a/source/core/slang-test-tool-util.h b/source/core/slang-test-tool-util.h
index a5d7541ec..9df2a6d6a 100644
--- a/source/core/slang-test-tool-util.h
+++ b/source/core/slang-test-tool-util.h
@@ -46,6 +46,9 @@ struct TestToolUtil
/// Given a slang result, returns a return code that can be returned from an executable
static ToolReturnCode getReturnCode(SlangResult res);
+
+ /// Sets the default preludes on the session based on the executable path
+ static SlangResult setSessionDefaultPrelude(const char* exePath, slang::IGlobalSession* session);
};
} // namespace Slang
diff --git a/source/slang/slang-check.cpp b/source/slang/slang-check.cpp
index 464dafcd9..33fc10e45 100644
--- a/source/slang/slang-check.cpp
+++ b/source/slang/slang-check.cpp
@@ -364,9 +364,9 @@ namespace Slang
StringBuilder builder;
PassThroughMode passThrough = _toPassThroughMode(type);
- if (passThrough != PassThroughMode::None && m_passThroughPaths[int(passThrough)].getLength() > 0)
+ if (passThrough != PassThroughMode::None && m_downstreamCompilerPaths[int(passThrough)].getLength() > 0)
{
- Path::combineIntoBuilder(m_passThroughPaths[int(passThrough)].getUnownedSlice(), UnownedStringSlice(libName), builder);
+ Path::combineIntoBuilder(m_downstreamCompilerPaths[int(passThrough)].getUnownedSlice(), UnownedStringSlice(libName), builder);
libName = builder.getBuffer();
}
@@ -424,9 +424,9 @@ namespace Slang
typedef CPPCompiler::CompilerType CompilerType;
CPPCompilerUtil::InitializeSetDesc desc;
- desc.paths[int(CompilerType::GCC)] = m_passThroughPaths[int(PassThroughMode::Gcc)];
- desc.paths[int(CompilerType::Clang)] = m_passThroughPaths[int(PassThroughMode::Clang)];
- desc.paths[int(CompilerType::VisualStudio)] = m_passThroughPaths[int(PassThroughMode::VisualStudio)];
+ desc.paths[int(CompilerType::GCC)] = m_downstreamCompilerPaths[int(PassThroughMode::Gcc)];
+ desc.paths[int(CompilerType::Clang)] = m_downstreamCompilerPaths[int(PassThroughMode::Clang)];
+ desc.paths[int(CompilerType::VisualStudio)] = m_downstreamCompilerPaths[int(PassThroughMode::VisualStudio)];
CPPCompilerUtil::initializeSet(desc, cppCompilerSet);
}
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 75cd61bf9..07e2b66fe 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -474,7 +474,7 @@ namespace Slang
return SLANG_E_NOT_IMPLEMENTED;
}
- static PassThroughMode _getExternalCompilerRequiredForTarget(CodeGenTarget target)
+ PassThroughMode getDownstreamCompilerRequiredForTarget(CodeGenTarget target)
{
switch (target)
{
@@ -530,9 +530,22 @@ namespace Slang
return PassThroughMode::None;
}
+ PassThroughMode getPassThroughModeForCPPCompiler(CPPCompiler::CompilerType type)
+ {
+ typedef CPPCompiler::CompilerType CompilerType;
+
+ switch (type)
+ {
+ case CompilerType::VisualStudio: return PassThroughMode::VisualStudio;
+ case CompilerType::GCC: return PassThroughMode::Gcc;
+ case CompilerType::Clang: return PassThroughMode::Clang;
+ default: return PassThroughMode::None;
+ }
+ }
+
SlangResult checkCompileTargetSupport(Session* session, CodeGenTarget target)
{
- const PassThroughMode mode = _getExternalCompilerRequiredForTarget(target);
+ const PassThroughMode mode = getDownstreamCompilerRequiredForTarget(target);
return (mode != PassThroughMode::None) ?
checkExternalCompilerSupport(session, mode) :
SLANG_OK;
@@ -561,21 +574,6 @@ namespace Slang
return translationUnit;
}
- static TranslationUnitRequest* _getTranslationUnit(
- EndToEndCompileRequest* endToEndReq,
- Int entryPointIndex)
- {
- // If there isn't an end-to-end compile going on,
- // there can be no pass-through.
- //
- if (!endToEndReq) return nullptr;
-
- auto frontEndReq = endToEndReq->getFrontEndReq();
- auto entryPointReq = frontEndReq->getEntryPointReq(entryPointIndex);
- auto translationUnit = entryPointReq->getTranslationUnit();
- return translationUnit;
- }
-
static void _appendEscapedPath(const UnownedStringSlice& path, StringBuilder& outBuilder)
{
for (auto c : path)
@@ -1316,28 +1314,6 @@ SlangResult dissassembleDXILUsingDXC(
}
else
{
- // TODO(JS): This is a hack for two reasons
- // * That we just inject the source path for C/C++ include paths if we find the file
- // * We should access the files through the ISlangFileSystem
-
- translationUnit = _getTranslationUnit(endToEndReq, entryPointIndex);
-
- const auto& sourceFiles = translationUnit->getSourceFiles();
- if (sourceFiles.getCount() == 1)
- {
- const SourceFile* sourceFile = sourceFiles[0];
- const PathInfo& pathInfo = sourceFile->getPathInfo();
- if (pathInfo.type == PathInfo::Type::FoundPath || pathInfo.type == PathInfo::Type::Normal || pathInfo.type == PathInfo::Type::FromString)
- {
- String canonicalPath;
- if (File::exists(pathInfo.foundPath) && SLANG_SUCCEEDED(Path::getCanonical(pathInfo.foundPath, canonicalPath)))
- {
- String sourceDir = Path::getParentDirectory(canonicalPath);
- includePaths.add(sourceDir);
- }
- }
- }
-
rawSource = emitCPPForEntryPoint(
slangRequest,
entryPoint,
@@ -1477,37 +1453,6 @@ SlangResult dissassembleDXILUsingDXC(
}
}
- // TODO(JS): HACK! We need to include the prelude from somewhere, but where? The generated output
- // is sitting in some temp directory.
- // So here, we search all the 'sourceFiles', and try their paths for plausibility, and take the first
- {
- auto frontEndReq = endToEndReq->getFrontEndReq();
- auto entryPointReq = frontEndReq->getEntryPointReq(entryPointIndex);
- auto translationUnit = entryPointReq->getTranslationUnit();
-
- for (SourceFile* sourceFile : translationUnit->m_sourceFiles)
- {
- const auto& pathInfo = sourceFile->getPathInfo();
-
- if (pathInfo.type == PathInfo::Type::FoundPath ||
- pathInfo.type == PathInfo::Type::Normal)
- {
- String originalSourceDirectory = Path::getParentDirectory(pathInfo.foundPath);
-
- if (originalSourceDirectory.getLength() && File::exists(originalSourceDirectory))
- {
- // We can't use this path directly, so make canonical so it is absolute
- StringBuilder canonicalPath;
- if (SLANG_SUCCEEDED(Path::getCanonical(originalSourceDirectory, canonicalPath)))
- {
- options.includePaths.add(canonicalPath.ProduceString());
- break;
- }
- }
- }
- }
- }
-
// Compile
CPPCompiler::Output output;
SLANG_RETURN_ON_FAIL(compiler->compile(options, output));
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index ce01e5ea3..a6be59c76 100644
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -62,6 +62,7 @@ namespace Slang
Executable = SLANG_EXECUTABLE,
SharedLibrary = SLANG_SHARED_LIBRARY,
HostCallable = SLANG_HOST_CALLABLE,
+ CountOf = SLANG_TARGET_COUNT_OF,
};
CodeGenTarget calcCodeGenTargetFromName(const UnownedStringSlice& name);
@@ -1057,6 +1058,13 @@ namespace Slang
///
ComPtr<ISlangBlob> createRawBlob(void const* data, size_t size);
+
+ /// Given a target returns the required downstream compiler
+ PassThroughMode getDownstreamCompilerRequiredForTarget(CodeGenTarget target);
+
+ PassThroughMode getPassThroughModeForCPPCompiler(CPPCompiler::CompilerType type);
+
+
/// A context for loading and re-using code modules.
class Linkage : public RefObject, public slang::ISession
{
@@ -1791,10 +1799,13 @@ namespace Slang
SLANG_NO_THROW SlangProfileID SLANG_MCALL findProfile(
char const* name) override;
- SLANG_NO_THROW void SLANG_MCALL setPassThroughPath(
+ SLANG_NO_THROW void SLANG_MCALL setDownstreamCompilerPath(
SlangPassThrough passThrough,
char const* path) override;
+ SLANG_NO_THROW void SLANG_MCALL setDownstreamCompilerPrelude(
+ SlangPassThrough inPassThrough,
+ char const* prelude) override;
enum class SharedLibraryFuncType
{
@@ -1928,6 +1939,9 @@ namespace Slang
SlangFuncPtr getSharedLibraryFunc(SharedLibraryFuncType type, DiagnosticSink* sink);
+ /// Get the downstream compiler prelude
+ const String& getDownstreamCompilerPrelude(PassThroughMode mode) { return m_downstreamCompilerPreludes[int(mode)]; }
+
/// Finds out what compilers are present and caches the result
CPPCompilerSet* requireCPPCompilerSet();
@@ -1943,7 +1957,8 @@ namespace Slang
/// Linkage used for all built-in (stdlib) code.
RefPtr<Linkage> m_builtinLinkage;
- String m_passThroughPaths[int(PassThroughMode::CountOf)]; ///< Paths for each pass through
+ String m_downstreamCompilerPaths[int(PassThroughMode::CountOf)]; ///< Paths for each pass through
+ String m_downstreamCompilerPreludes[int(PassThroughMode::CountOf)]; ///< Prelude for each type of target
};
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 0228955dc..dc9ab23cc 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -2213,8 +2213,6 @@ void CPPSourceEmitter::emitPreprocessorDirectivesImpl()
writer->emit("\n");
- writer->emit("#include <slang-cpp-prelude.h>\n\n");
-
// Emit the type definitions
for (const auto& keyValue : m_typeNameMap)
{
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 205f8ee0e..5a4e8300a 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -540,6 +540,31 @@ String emitEntryPoint(
// Now that we've emitted the code for all the declarations in the file,
// it is time to stitch together the final output.
+ {
+ Session* session = compileRequest->getSession();
+
+ // Get the downstream compiler needed for final target
+ PassThroughMode passThru = getDownstreamCompilerRequiredForTarget(targetRequest->target);
+
+ // If generic CPP work out what compiler will actually be used
+ if (passThru == PassThroughMode::GenericCCpp)
+ {
+ CPPCompilerSet* compilerSet = session->requireCPPCompilerSet();
+ CPPCompiler* compiler = compilerSet->getDefaultCompiler();
+ if (compiler)
+ {
+ passThru = getPassThroughModeForCPPCompiler(compiler->getDesc().type);
+ }
+ }
+
+ // If there is a prelude emit it
+ const auto& prelude = compileRequest->getSession()->getDownstreamCompilerPrelude(passThru);
+ if (prelude.getLength() > 0)
+ {
+ sourceWriter.emit(prelude.getUnownedSlice());
+ }
+ }
+
// There may be global-scope modifiers that we should emit now
sourceEmitter->emitPreprocessorDirectives();
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index c07ace929..a55322d31 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -824,7 +824,7 @@ struct OptionsParser
SlangPassThrough passThrough = SLANG_PASS_THROUGH_NONE;
if (SLANG_SUCCEEDED(_parsePassThrough(slice.getUnownedSlice(), passThrough)))
{
- session->setPassThroughPath(passThrough, name.getBuffer());
+ session->setDownstreamCompilerPath(passThrough, name.getBuffer());
continue;
}
}
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index eef0dff6f..601312def 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -146,14 +146,14 @@ SLANG_NO_THROW SlangProfileID SLANG_MCALL Session::findProfile(
return Slang::Profile::LookUp(name).raw;
}
-SLANG_NO_THROW void SLANG_MCALL Session::setPassThroughPath(
+SLANG_NO_THROW void SLANG_MCALL Session::setDownstreamCompilerPath(
SlangPassThrough inPassThrough,
char const* path)
{
PassThroughMode passThrough = PassThroughMode(inPassThrough);
SLANG_ASSERT(int(passThrough) > int(PassThroughMode::None) && int(passThrough) < int(PassThroughMode::CountOf));
- if (m_passThroughPaths[int(passThrough)] != path)
+ if (m_downstreamCompilerPaths[int(passThrough)] != path)
{
// If it's changed we should unload any shared libraries that use it
switch (passThrough)
@@ -187,10 +187,20 @@ SLANG_NO_THROW void SLANG_MCALL Session::setPassThroughPath(
}
// Set the path
- m_passThroughPaths[int(passThrough)] = path;
+ m_downstreamCompilerPaths[int(passThrough)] = path;
}
}
+SLANG_NO_THROW void SLANG_MCALL Session::setDownstreamCompilerPrelude(
+ SlangPassThrough inPassThrough,
+ char const* prelude)
+{
+ PassThroughMode passThrough = PassThroughMode(inPassThrough);
+ SLANG_ASSERT(int(passThrough) > int(PassThroughMode::None) && int(passThrough) < int(PassThroughMode::CountOf));
+
+ m_downstreamCompilerPreludes[int(passThrough)] = prelude;
+}
+
struct IncludeHandlerImpl : IncludeHandler
{
Linkage* linkage;
diff --git a/source/slangc/main.cpp b/source/slangc/main.cpp
index ddeb315e1..da9a21b7a 100644
--- a/source/slangc/main.cpp
+++ b/source/slangc/main.cpp
@@ -81,6 +81,7 @@ int MAIN(int argc, char** argv)
SlangResult res;
{
SlangSession* session = spCreateSession(nullptr);
+ TestToolUtil::setSessionDefaultPrelude(argv[0], session);
auto stdWriters = StdWriters::initDefaultSingleton();
diff --git a/tests/compute/slang-cpp-prelude.h b/tests/compute/slang-cpp-prelude.h
deleted file mode 100644
index f1d6919f0..000000000
--- a/tests/compute/slang-cpp-prelude.h
+++ /dev/null
@@ -1,826 +0,0 @@
-#ifndef SLANG_CPP_PRELUDE_H
-#define SLANG_CPP_PRELUDE_H
-
-/* --------------- START From slang.h ----------------- */
-
-#ifndef SLANG_COMPILER
-# define SLANG_COMPILER
-
-/*
-Compiler defines, see http://sourceforge.net/p/predef/wiki/Compilers/
-NOTE that SLANG_VC holds the compiler version - not just 1 or 0
-*/
-# if defined(_MSC_VER)
-# if _MSC_VER >= 1900
-# define SLANG_VC 14
-# elif _MSC_VER >= 1800
-# define SLANG_VC 12
-# elif _MSC_VER >= 1700
-# define SLANG_VC 11
-# elif _MSC_VER >= 1600
-# define SLANG_VC 10
-# elif _MSC_VER >= 1500
-# define SLANG_VC 9
-# else
-# error "unknown version of Visual C++ compiler"
-# endif
-# elif defined(__clang__)
-# define SLANG_CLANG 1
-# elif defined(__SNC__)
-# define SLANG_SNC 1
-# elif defined(__ghs__)
-# define SLANG_GHS 1
-# elif defined(__GNUC__) /* note: __clang__, __SNC__, or __ghs__ imply __GNUC__ */
-# define SLANG_GCC 1
-# else
-# error "unknown compiler"
-# endif
-/*
-Any compilers not detected by the above logic are now now explicitly zeroed out.
-*/
-# ifndef SLANG_VC
-# define SLANG_VC 0
-# endif
-# ifndef SLANG_CLANG
-# define SLANG_CLANG 0
-# endif
-# ifndef SLANG_SNC
-# define SLANG_SNC 0
-# endif
-# ifndef SLANG_GHS
-# define SLANG_GHS 0
-# endif
-# ifndef SLANG_GCC
-# define SLANG_GCC 0
-# endif
-#endif /* SLANG_COMPILER */
-
-/*
-The following section attempts to detect the target platform being compiled for.
-
-If an application defines `SLANG_PLATFORM` before including this header,
-they take responsibility for setting any compiler-dependent macros
-used later in the file.
-
-Most applications should not need to touch this section.
-*/
-#ifndef SLANG_PLATFORM
-# define SLANG_PLATFORM
-/**
-Operating system defines, see http://sourceforge.net/p/predef/wiki/OperatingSystems/
-*/
-# if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_PARTITION_APP
-# define SLANG_WINRT 1 /* Windows Runtime, either on Windows RT or Windows 8 */
-# elif defined(XBOXONE)
-# define SLANG_XBOXONE 1
-# elif defined(_WIN64) /* note: XBOXONE implies _WIN64 */
-# define SLANG_WIN64 1
-# elif defined(_M_PPC)
-# define SLANG_X360 1
-# elif defined(_WIN32) /* note: _M_PPC implies _WIN32 */
-# define SLANG_WIN32 1
-# elif defined(__ANDROID__)
-# define SLANG_ANDROID 1
-# elif defined(__linux__) || defined(__CYGWIN__) /* note: __ANDROID__ implies __linux__ */
-# define SLANG_LINUX 1
-# elif defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
-# define SLANG_IOS 1
-# elif defined(__APPLE__)
-# define SLANG_OSX 1
-# elif defined(__CELLOS_LV2__)
-# define SLANG_PS3 1
-# elif defined(__ORBIS__)
-# define SLANG_PS4 1
-# elif defined(__SNC__) && defined(__arm__)
-# define SLANG_PSP2 1
-# elif defined(__ghs__)
-# define SLANG_WIIU 1
-# else
-# error "unknown target platform"
-# endif
-/*
-Any platforms not detected by the above logic are now now explicitly zeroed out.
-*/
-# ifndef SLANG_WINRT
-# define SLANG_WINRT 0
-# endif
-# ifndef SLANG_XBOXONE
-# define SLANG_XBOXONE 0
-# endif
-# ifndef SLANG_WIN64
-# define SLANG_WIN64 0
-# endif
-# ifndef SLANG_X360
-# define SLANG_X360 0
-# endif
-# ifndef SLANG_WIN32
-# define SLANG_WIN32 0
-# endif
-# ifndef SLANG_ANDROID
-# define SLANG_ANDROID 0
-# endif
-# ifndef SLANG_LINUX
-# define SLANG_LINUX 0
-# endif
-# ifndef SLANG_IOS
-# define SLANG_IOS 0
-# endif
-# ifndef SLANG_OSX
-# define SLANG_OSX 0
-# endif
-# ifndef SLANG_PS3
-# define SLANG_PS3 0
-# endif
-# ifndef SLANG_PS4
-# define SLANG_PS4 0
-# endif
-# ifndef SLANG_PSP2
-# define SLANG_PSP2 0
-# endif
-# ifndef SLANG_WIIU
-# define SLANG_WIIU 0
-# endif
-#endif /* SLANG_PLATFORM */
-
-/* Shorthands for "families" of compilers/platforms */
-#define SLANG_GCC_FAMILY (SLANG_CLANG || SLANG_SNC || SLANG_GHS || SLANG_GCC)
-#define SLANG_WINDOWS_FAMILY (SLANG_WINRT || SLANG_WIN32 || SLANG_WIN64)
-#define SLANG_MICROSOFT_FAMILY (SLANG_XBOXONE || SLANG_X360 || SLANG_WINDOWS_FAMILY)
-#define SLANG_LINUX_FAMILY (SLANG_LINUX || SLANG_ANDROID)
-#define SLANG_APPLE_FAMILY (SLANG_IOS || SLANG_OSX) /* equivalent to #if __APPLE__ */
-#define SLANG_UNIX_FAMILY (SLANG_LINUX_FAMILY || SLANG_APPLE_FAMILY) /* shortcut for unix/posix platforms */
-
-/* Macro for declaring if a method is no throw. Should be set before the return parameter. */
-#ifndef SLANG_NO_THROW
-# if SLANG_WINDOWS_FAMILY && !defined(SLANG_DISABLE_EXCEPTIONS)
-# define SLANG_NO_THROW __declspec(nothrow)
-# endif
-#endif
-#ifndef SLANG_NO_THROW
-# define SLANG_NO_THROW
-#endif
-
-/* The `SLANG_STDCALL` and `SLANG_MCALL` defines are used to set the calling
-convention for interface methods.
-*/
-#ifndef SLANG_STDCALL
-# if SLANG_MICROSOFT_FAMILY
-# define SLANG_STDCALL __stdcall
-# else
-# define SLANG_STDCALL
-# endif
-#endif
-#ifndef SLANG_MCALL
-# define SLANG_MCALL SLANG_STDCALL
-#endif
-
-
-#if !defined(SLANG_STATIC) && !defined(SLANG_STATIC)
- #define SLANG_DYNAMIC
-#endif
-
-#if defined(_MSC_VER)
-# define SLANG_DLL_EXPORT __declspec(dllexport)
-#else
-# define SLANG_DLL_EXPORT __attribute__((__visibility__("default")))
-#endif
-
-#if defined(SLANG_DYNAMIC)
-# if defined(_MSC_VER)
-# ifdef SLANG_DYNAMIC_EXPORT
-# define SLANG_API SLANG_DLL_EXPORT
-# else
-# define SLANG_API __declspec(dllimport)
-# endif
-# else
- // TODO: need to consider compiler capabilities
-//# ifdef SLANG_DYNAMIC_EXPORT
-# define SLANG_API SLANG_DLL_EXPORT
-//# endif
-# endif
-#endif
-
-#ifndef SLANG_API
-# define SLANG_API
-#endif
-
-// GCC Specific
-#if SLANG_GCC_FAMILY
-// This doesn't work on clang - because the typedef is seen as multiply defined, use the line numbered version defined later
-# if !defined(__clang__) && (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__ORBIS__))
-# define SLANG_COMPILE_TIME_ASSERT(exp) typedef char SlangCompileTimeAssert_Dummy[(exp) ? 1 : -1] __attribute__((unused))
-# endif
-
-# define SLANG_NO_INLINE __attribute__((noinline))
-# define SLANG_FORCE_INLINE inline __attribute__((always_inline))
-# define SLANG_BREAKPOINT(id) __builtin_trap();
-# define SLANG_ALIGN_OF(T) __alignof__(T)
-
-// Use this macro instead of offsetof, because gcc produces warning if offsetof is used on a
-// non POD type, even though it produces the correct result
-# define SLANG_OFFSET_OF(T, ELEMENT) (size_t(&((T*)1)->ELEMENT) - 1)
-#endif // SLANG_GCC_FAMILY
-
-// Microsoft VC specific
-#if SLANG_MICROSOFT_FAMILY
-# define SLANG_NO_INLINE __declspec(noinline)
-# define SLANG_FORCE_INLINE __forceinline
-# define SLANG_BREAKPOINT(id) __debugbreak();
-# define SLANG_ALIGN_OF(T) __alignof(T)
-
-# define SLANG_INT64(x) (x##i64)
-# define SLANG_UINT64(x) (x##ui64)
-#endif // SLANG_MICROSOFT_FAMILY
-
-#ifndef SLANG_FORCE_INLINE
-# define SLANG_FORCE_INLINE inline
-#endif
-#ifndef SLANG_NO_INLINE
-# define SLANG_NO_INLINE
-#endif
-
-#ifndef SLANG_COMPILE_TIME_ASSERT
-# define SLANG_COMPILE_TIME_ASSERT(exp) typedef char SLANG_CONCAT(SlangCompileTimeAssert,__LINE__)[(exp) ? 1 : -1]
-#endif
-
-#ifndef SLANG_OFFSET_OF
-# define SLANG_OFFSET_OF(X, Y) offsetof(X, Y)
-#endif
-
-#ifndef SLANG_BREAKPOINT
-// Make it crash with a write to 0!
-# define SLANG_BREAKPOINT(id) (*((int*)0) = int(id));
-#endif
-
-// Use for getting the amount of members of a standard C array.
-#define SLANG_COUNT_OF(x) (sizeof(x)/sizeof(x[0]))
-/// SLANG_INLINE exists to have a way to inline consistent with SLANG_ALWAYS_INLINE
-#define SLANG_INLINE inline
-
-// Other defines
-#define SLANG_STRINGIZE_HELPER(X) #X
-#define SLANG_STRINGIZE(X) SLANG_STRINGIZE_HELPER(X)
-
-#define SLANG_CONCAT_HELPER(X, Y) X##Y
-#define SLANG_CONCAT(X, Y) SLANG_CONCAT_HELPER(X, Y)
-
-#ifndef SLANG_UNUSED
-# define SLANG_UNUSED(v) (void)v;
-#endif
-
-// Used for doing constant literals
-#ifndef SLANG_INT64
-# define SLANG_INT64(x) (x##ll)
-#endif
-#ifndef SLANG_UINT64
-# define SLANG_UINT64(x) (x##ull)
-#endif
-
-
-#ifdef __cplusplus
-# define SLANG_EXTERN_C extern "C"
-#else
-# define SLANG_EXTERN_C
-#endif
-
-#ifdef __cplusplus
-// C++ specific macros
-// Clang
-#if SLANG_CLANG
-# if (__clang_major__*10 + __clang_minor__) >= 33
-# define SLANG_HAS_MOVE_SEMANTICS 1
-# define SLANG_HAS_ENUM_CLASS 1
-# define SLANG_OVERRIDE override
-# endif
-// Gcc
-#elif SLANG_GCC_FAMILY
-// Check for C++11
-# if (__cplusplus >= 201103L)
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
-# define SLANG_HAS_MOVE_SEMANTICS 1
-# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
-# define SLANG_HAS_ENUM_CLASS 1
-# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407
-# define SLANG_OVERRIDE override
-# endif
-# endif
-# endif // SLANG_GCC_FAMILY
-
-// Visual Studio
-
-# if SLANG_VC
-// C4481: nonstandard extension used: override specifier 'override'
-# if _MSC_VER < 1700
-# pragma warning(disable : 4481)
-# endif
-# define SLANG_OVERRIDE override
-# if _MSC_VER >= 1600
-# define SLANG_HAS_MOVE_SEMANTICS 1
-# endif
-# if _MSC_VER >= 1700
-# define SLANG_HAS_ENUM_CLASS 1
-# endif
-
-# endif // SLANG_VC
-
-// Set non set
-# ifndef SLANG_OVERRIDE
-# define SLANG_OVERRIDE
-# endif
-# ifndef SLANG_HAS_ENUM_CLASS
-# define SLANG_HAS_ENUM_CLASS 0
-# endif
-# ifndef SLANG_HAS_MOVE_SEMANTICS
-# define SLANG_HAS_MOVE_SEMANTICS 0
-# endif
-
-#endif // __cplusplus
-
-/* Macros for detecting processor */
-#if defined(_M_ARM) || defined(__ARM_EABI__)
-// This is special case for nVidia tegra
-# define SLANG_PROCESSOR_ARM 1
-#elif defined(__i386__) || defined(_M_IX86)
-# define SLANG_PROCESSOR_X86 1
-#elif defined(_M_AMD64) || defined(_M_X64) || defined(__amd64) || defined(__x86_64)
-# define SLANG_PROCESSOR_X86_64 1
-#elif defined(_PPC_) || defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC)
-# if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || defined(__64BIT__) || defined(_LP64) || defined(__LP64__)
-# define SLANG_PROCESSOR_POWER_PC_64 1
-# else
-# define SLANG_PROCESSOR_POWER_PC 1
-# endif
-#elif defined(__arm__)
-# define SLANG_PROCESSOR_ARM 1
-#elif defined(__aarch64__)
-# define SLANG_PROCESSOR_ARM_64 1
-#endif
-
-#ifndef SLANG_PROCESSOR_ARM
-# define SLANG_PROCESSOR_ARM 0
-#endif
-
-#ifndef SLANG_PROCESSOR_ARM_64
-# define SLANG_PROCESSOR_ARM_64 0
-#endif
-
-#ifndef SLANG_PROCESSOR_X86
-# define SLANG_PROCESSOR_X86 0
-#endif
-
-#ifndef SLANG_PROCESSOR_X86_64
-# define SLANG_PROCESSOR_X86_64 0
-#endif
-
-#ifndef SLANG_PROCESSOR_POWER_PC
-# define SLANG_PROCESSOR_POWER_PC 0
-#endif
-
-#ifndef SLANG_PROCESSOR_POWER_PC_64
-# define SLANG_PROCESSOR_POWER_PC_64 0
-#endif
-
-// Processor families
-
-#define SLANG_PROCESSOR_FAMILY_X86 (SLANG_PROCESSOR_X86_64 | SLANG_PROCESSOR_X86)
-#define SLANG_PROCESSOR_FAMILY_ARM (SLANG_PROCESSOR_ARM | SLANG_PROCESSOR_ARM_64)
-#define SLANG_PROCESSOR_FAMILY_POWER_PC (SLANG_PROCESSOR_POWER_PC_64 | SLANG_PROCESSOR_POWER_PC)
-
-// Pointer size
-#define SLANG_PTR_IS_64 (SLANG_PROCESSOR_ARM_64 | SLANG_PROCESSOR_X86_64 | SLANG_PROCESSOR_POWER_PC_64)
-#define SLANG_PTR_IS_32 (SLANG_PTR_IS_64 ^ 1)
-
-// Processor features
-#if SLANG_PROCESSOR_FAMILY_X86
-# define SLANG_LITTLE_ENDIAN 1
-# define SLANG_UNALIGNED_ACCESS 1
-#elif SLANG_PROCESSOR_FAMILY_ARM
-# if defined(__ARMEB__)
-# define SLANG_BIG_ENDIAN 1
-# else
-# define SLANG_LITTLE_ENDIAN 1
-# endif
-#elif SLANG_PROCESSOR_FAMILY_POWER_PC
-# define SLANG_BIG_ENDIAN 1
-#endif
-
-#ifndef SLANG_LITTLE_ENDIAN
-# define SLANG_LITTLE_ENDIAN 0
-#endif
-
-#ifndef SLANG_BIG_ENDIAN
-# define SLANG_BIG_ENDIAN 0
-#endif
-
-#ifndef SLANG_UNALIGNED_ACCESS
-# define SLANG_UNALIGNED_ACCESS 0
-#endif
-
-// One endianess must be set
-#if ((SLANG_BIG_ENDIAN | SLANG_LITTLE_ENDIAN) == 0)
-# error "Couldn't determine endianess"
-#endif
-
-#ifndef SLANG_NO_INTTYPES
-#include <inttypes.h>
-#endif // ! SLANG_NO_INTTYPES
-
-#ifndef SLANG_NO_STDDEF
-#include <stddef.h>
-#endif // ! SLANG_NO_STDDEF
-
-/* --------------- END From slang.h ----------------- */
-
-// TODO(JS): Hack! Output C++ code from slang can copy unitialized variables.
-#if SLANG_VC
-# pragma warning(disable : 4700)
-#endif
-
-#include <math.h>
-#include <assert.h>
-#include <stdlib.h>
-
-#ifndef SLANG_PRELUDE_PI
-# define SLANG_PRELUDE_PI 3.14159265358979323846
-#endif
-
-#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
-
-#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;
-};
-
-/* Varing input for Compute */
-
-struct ComputeVaryingInput
-{
- uint3 groupID;
- uint3 groupThreadID;
-};
-
-// ----------------------------- 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/tests/cross-compile/c-cross-compile.slang b/tests/cross-compile/c-cross-compile.slang
index 646ba3445..e03f4484a 100644
--- a/tests/cross-compile/c-cross-compile.slang
+++ b/tests/cross-compile/c-cross-compile.slang
@@ -1,4 +1,4 @@
-//TEST:CPP_COMPILER_COMPILE: -profile cs_5_0 -entry computeMain -target cpp
+//TEST:CPP_COMPILER_COMPILE: -profile cs_5_0 -entry computeMain -target callable
enum Color
{
diff --git a/tests/cross-compile/slang-cpp-prelude.h b/tests/cross-compile/slang-cpp-prelude.h
deleted file mode 100644
index f32504920..000000000
--- a/tests/cross-compile/slang-cpp-prelude.h
+++ /dev/null
@@ -1,824 +0,0 @@
-#ifndef SLANG_CPP_PRELUDE_H
-#define SLANG_CPP_PRELUDE_H
-
-/* --------------- START From slang.h ----------------- */
-
-#ifndef SLANG_COMPILER
-# define SLANG_COMPILER
-
-/*
-Compiler defines, see http://sourceforge.net/p/predef/wiki/Compilers/
-NOTE that SLANG_VC holds the compiler version - not just 1 or 0
-*/
-# if defined(_MSC_VER)
-# if _MSC_VER >= 1900
-# define SLANG_VC 14
-# elif _MSC_VER >= 1800
-# define SLANG_VC 12
-# elif _MSC_VER >= 1700
-# define SLANG_VC 11
-# elif _MSC_VER >= 1600
-# define SLANG_VC 10
-# elif _MSC_VER >= 1500
-# define SLANG_VC 9
-# else
-# error "unknown version of Visual C++ compiler"
-# endif
-# elif defined(__clang__)
-# define SLANG_CLANG 1
-# elif defined(__SNC__)
-# define SLANG_SNC 1
-# elif defined(__ghs__)
-# define SLANG_GHS 1
-# elif defined(__GNUC__) /* note: __clang__, __SNC__, or __ghs__ imply __GNUC__ */
-# define SLANG_GCC 1
-# else
-# error "unknown compiler"
-# endif
-/*
-Any compilers not detected by the above logic are now now explicitly zeroed out.
-*/
-# ifndef SLANG_VC
-# define SLANG_VC 0
-# endif
-# ifndef SLANG_CLANG
-# define SLANG_CLANG 0
-# endif
-# ifndef SLANG_SNC
-# define SLANG_SNC 0
-# endif
-# ifndef SLANG_GHS
-# define SLANG_GHS 0
-# endif
-# ifndef SLANG_GCC
-# define SLANG_GCC 0
-# endif
-#endif /* SLANG_COMPILER */
-
-/*
-The following section attempts to detect the target platform being compiled for.
-
-If an application defines `SLANG_PLATFORM` before including this header,
-they take responsibility for setting any compiler-dependent macros
-used later in the file.
-
-Most applications should not need to touch this section.
-*/
-#ifndef SLANG_PLATFORM
-# define SLANG_PLATFORM
-/**
-Operating system defines, see http://sourceforge.net/p/predef/wiki/OperatingSystems/
-*/
-# if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_PARTITION_APP
-# define SLANG_WINRT 1 /* Windows Runtime, either on Windows RT or Windows 8 */
-# elif defined(XBOXONE)
-# define SLANG_XBOXONE 1
-# elif defined(_WIN64) /* note: XBOXONE implies _WIN64 */
-# define SLANG_WIN64 1
-# elif defined(_M_PPC)
-# define SLANG_X360 1
-# elif defined(_WIN32) /* note: _M_PPC implies _WIN32 */
-# define SLANG_WIN32 1
-# elif defined(__ANDROID__)
-# define SLANG_ANDROID 1
-# elif defined(__linux__) || defined(__CYGWIN__) /* note: __ANDROID__ implies __linux__ */
-# define SLANG_LINUX 1
-# elif defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
-# define SLANG_IOS 1
-# elif defined(__APPLE__)
-# define SLANG_OSX 1
-# elif defined(__CELLOS_LV2__)
-# define SLANG_PS3 1
-# elif defined(__ORBIS__)
-# define SLANG_PS4 1
-# elif defined(__SNC__) && defined(__arm__)
-# define SLANG_PSP2 1
-# elif defined(__ghs__)
-# define SLANG_WIIU 1
-# else
-# error "unknown target platform"
-# endif
-/*
-Any platforms not detected by the above logic are now now explicitly zeroed out.
-*/
-# ifndef SLANG_WINRT
-# define SLANG_WINRT 0
-# endif
-# ifndef SLANG_XBOXONE
-# define SLANG_XBOXONE 0
-# endif
-# ifndef SLANG_WIN64
-# define SLANG_WIN64 0
-# endif
-# ifndef SLANG_X360
-# define SLANG_X360 0
-# endif
-# ifndef SLANG_WIN32
-# define SLANG_WIN32 0
-# endif
-# ifndef SLANG_ANDROID
-# define SLANG_ANDROID 0
-# endif
-# ifndef SLANG_LINUX
-# define SLANG_LINUX 0
-# endif
-# ifndef SLANG_IOS
-# define SLANG_IOS 0
-# endif
-# ifndef SLANG_OSX
-# define SLANG_OSX 0
-# endif
-# ifndef SLANG_PS3
-# define SLANG_PS3 0
-# endif
-# ifndef SLANG_PS4
-# define SLANG_PS4 0
-# endif
-# ifndef SLANG_PSP2
-# define SLANG_PSP2 0
-# endif
-# ifndef SLANG_WIIU
-# define SLANG_WIIU 0
-# endif
-#endif /* SLANG_PLATFORM */
-
-/* Shorthands for "families" of compilers/platforms */
-#define SLANG_GCC_FAMILY (SLANG_CLANG || SLANG_SNC || SLANG_GHS || SLANG_GCC)
-#define SLANG_WINDOWS_FAMILY (SLANG_WINRT || SLANG_WIN32 || SLANG_WIN64)
-#define SLANG_MICROSOFT_FAMILY (SLANG_XBOXONE || SLANG_X360 || SLANG_WINDOWS_FAMILY)
-#define SLANG_LINUX_FAMILY (SLANG_LINUX || SLANG_ANDROID)
-#define SLANG_APPLE_FAMILY (SLANG_IOS || SLANG_OSX) /* equivalent to #if __APPLE__ */
-#define SLANG_UNIX_FAMILY (SLANG_LINUX_FAMILY || SLANG_APPLE_FAMILY) /* shortcut for unix/posix platforms */
-
-/* Macro for declaring if a method is no throw. Should be set before the return parameter. */
-#ifndef SLANG_NO_THROW
-# if SLANG_WINDOWS_FAMILY && !defined(SLANG_DISABLE_EXCEPTIONS)
-# define SLANG_NO_THROW __declspec(nothrow)
-# endif
-#endif
-#ifndef SLANG_NO_THROW
-# define SLANG_NO_THROW
-#endif
-
-/* The `SLANG_STDCALL` and `SLANG_MCALL` defines are used to set the calling
-convention for interface methods.
-*/
-#ifndef SLANG_STDCALL
-# if SLANG_MICROSOFT_FAMILY
-# define SLANG_STDCALL __stdcall
-# else
-# define SLANG_STDCALL
-# endif
-#endif
-#ifndef SLANG_MCALL
-# define SLANG_MCALL SLANG_STDCALL
-#endif
-
-
-#if !defined(SLANG_STATIC) && !defined(SLANG_STATIC)
- #define SLANG_DYNAMIC
-#endif
-
-#if defined(_MSC_VER)
-# define SLANG_DLL_EXPORT __declspec(dllexport)
-#else
-# define SLANG_DLL_EXPORT __attribute__((__visibility__("default")))
-#endif
-
-#if defined(SLANG_DYNAMIC)
-# if defined(_MSC_VER)
-# ifdef SLANG_DYNAMIC_EXPORT
-# define SLANG_API SLANG_DLL_EXPORT
-# else
-# define SLANG_API __declspec(dllimport)
-# endif
-# else
- // TODO: need to consider compiler capabilities
-//# ifdef SLANG_DYNAMIC_EXPORT
-# define SLANG_API SLANG_DLL_EXPORT
-//# endif
-# endif
-#endif
-
-#ifndef SLANG_API
-# define SLANG_API
-#endif
-
-// GCC Specific
-#if SLANG_GCC_FAMILY
-// This doesn't work on clang - because the typedef is seen as multiply defined, use the line numbered version defined later
-# if !defined(__clang__) && (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__ORBIS__))
-# define SLANG_COMPILE_TIME_ASSERT(exp) typedef char SlangCompileTimeAssert_Dummy[(exp) ? 1 : -1] __attribute__((unused))
-# endif
-
-# define SLANG_NO_INLINE __attribute__((noinline))
-# define SLANG_FORCE_INLINE inline __attribute__((always_inline))
-# define SLANG_BREAKPOINT(id) __builtin_trap();
-# define SLANG_ALIGN_OF(T) __alignof__(T)
-
-// Use this macro instead of offsetof, because gcc produces warning if offsetof is used on a
-// non POD type, even though it produces the correct result
-# define SLANG_OFFSET_OF(T, ELEMENT) (size_t(&((T*)1)->ELEMENT) - 1)
-#endif // SLANG_GCC_FAMILY
-
-// Microsoft VC specific
-#if SLANG_MICROSOFT_FAMILY
-# define SLANG_NO_INLINE __declspec(noinline)
-# define SLANG_FORCE_INLINE __forceinline
-# define SLANG_BREAKPOINT(id) __debugbreak();
-# define SLANG_ALIGN_OF(T) __alignof(T)
-
-# define SLANG_INT64(x) (x##i64)
-# define SLANG_UINT64(x) (x##ui64)
-#endif // SLANG_MICROSOFT_FAMILY
-
-#ifndef SLANG_FORCE_INLINE
-# define SLANG_FORCE_INLINE inline
-#endif
-#ifndef SLANG_NO_INLINE
-# define SLANG_NO_INLINE
-#endif
-
-#ifndef SLANG_COMPILE_TIME_ASSERT
-# define SLANG_COMPILE_TIME_ASSERT(exp) typedef char SLANG_CONCAT(SlangCompileTimeAssert,__LINE__)[(exp) ? 1 : -1]
-#endif
-
-#ifndef SLANG_OFFSET_OF
-# define SLANG_OFFSET_OF(X, Y) offsetof(X, Y)
-#endif
-
-#ifndef SLANG_BREAKPOINT
-// Make it crash with a write to 0!
-# define SLANG_BREAKPOINT(id) (*((int*)0) = int(id));
-#endif
-
-// Use for getting the amount of members of a standard C array.
-#define SLANG_COUNT_OF(x) (sizeof(x)/sizeof(x[0]))
-/// SLANG_INLINE exists to have a way to inline consistent with SLANG_ALWAYS_INLINE
-#define SLANG_INLINE inline
-
-// Other defines
-#define SLANG_STRINGIZE_HELPER(X) #X
-#define SLANG_STRINGIZE(X) SLANG_STRINGIZE_HELPER(X)
-
-#define SLANG_CONCAT_HELPER(X, Y) X##Y
-#define SLANG_CONCAT(X, Y) SLANG_CONCAT_HELPER(X, Y)
-
-#ifndef SLANG_UNUSED
-# define SLANG_UNUSED(v) (void)v;
-#endif
-
-// Used for doing constant literals
-#ifndef SLANG_INT64
-# define SLANG_INT64(x) (x##ll)
-#endif
-#ifndef SLANG_UINT64
-# define SLANG_UINT64(x) (x##ull)
-#endif
-
-
-#ifdef __cplusplus
-# define SLANG_EXTERN_C extern "C"
-#else
-# define SLANG_EXTERN_C
-#endif
-
-#ifdef __cplusplus
-// C++ specific macros
-// Clang
-#if SLANG_CLANG
-# if (__clang_major__*10 + __clang_minor__) >= 33
-# define SLANG_HAS_MOVE_SEMANTICS 1
-# define SLANG_HAS_ENUM_CLASS 1
-# define SLANG_OVERRIDE override
-# endif
-// Gcc
-#elif SLANG_GCC_FAMILY
-// Check for C++11
-# if (__cplusplus >= 201103L)
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
-# define SLANG_HAS_MOVE_SEMANTICS 1
-# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
-# define SLANG_HAS_ENUM_CLASS 1
-# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407
-# define SLANG_OVERRIDE override
-# endif
-# endif
-# endif // SLANG_GCC_FAMILY
-
-// Visual Studio
-
-# if SLANG_VC
-// C4481: nonstandard extension used: override specifier 'override'
-# if _MSC_VER < 1700
-# pragma warning(disable : 4481)
-# endif
-# define SLANG_OVERRIDE override
-# if _MSC_VER >= 1600
-# define SLANG_HAS_MOVE_SEMANTICS 1
-# endif
-# if _MSC_VER >= 1700
-# define SLANG_HAS_ENUM_CLASS 1
-# endif
-
-# endif // SLANG_VC
-
-// Set non set
-# ifndef SLANG_OVERRIDE
-# define SLANG_OVERRIDE
-# endif
-# ifndef SLANG_HAS_ENUM_CLASS
-# define SLANG_HAS_ENUM_CLASS 0
-# endif
-# ifndef SLANG_HAS_MOVE_SEMANTICS
-# define SLANG_HAS_MOVE_SEMANTICS 0
-# endif
-
-#endif // __cplusplus
-
-/* Macros for detecting processor */
-#if defined(_M_ARM) || defined(__ARM_EABI__)
-// This is special case for nVidia tegra
-# define SLANG_PROCESSOR_ARM 1
-#elif defined(__i386__) || defined(_M_IX86)
-# define SLANG_PROCESSOR_X86 1
-#elif defined(_M_AMD64) || defined(_M_X64) || defined(__amd64) || defined(__x86_64)
-# define SLANG_PROCESSOR_X86_64 1
-#elif defined(_PPC_) || defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC)
-# if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || defined(__64BIT__) || defined(_LP64) || defined(__LP64__)
-# define SLANG_PROCESSOR_POWER_PC_64 1
-# else
-# define SLANG_PROCESSOR_POWER_PC 1
-# endif
-#elif defined(__arm__)
-# define SLANG_PROCESSOR_ARM 1
-#elif defined(__aarch64__)
-# define SLANG_PROCESSOR_ARM_64 1
-#endif
-
-#ifndef SLANG_PROCESSOR_ARM
-# define SLANG_PROCESSOR_ARM 0
-#endif
-
-#ifndef SLANG_PROCESSOR_ARM_64
-# define SLANG_PROCESSOR_ARM_64 0
-#endif
-
-#ifndef SLANG_PROCESSOR_X86
-# define SLANG_PROCESSOR_X86 0
-#endif
-
-#ifndef SLANG_PROCESSOR_X86_64
-# define SLANG_PROCESSOR_X86_64 0
-#endif
-
-#ifndef SLANG_PROCESSOR_POWER_PC
-# define SLANG_PROCESSOR_POWER_PC 0
-#endif
-
-#ifndef SLANG_PROCESSOR_POWER_PC_64
-# define SLANG_PROCESSOR_POWER_PC_64 0
-#endif
-
-// Processor families
-
-#define SLANG_PROCESSOR_FAMILY_X86 (SLANG_PROCESSOR_X86_64 | SLANG_PROCESSOR_X86)
-#define SLANG_PROCESSOR_FAMILY_ARM (SLANG_PROCESSOR_ARM | SLANG_PROCESSOR_ARM_64)
-#define SLANG_PROCESSOR_FAMILY_POWER_PC (SLANG_PROCESSOR_POWER_PC_64 | SLANG_PROCESSOR_POWER_PC)
-
-// Pointer size
-#define SLANG_PTR_IS_64 (SLANG_PROCESSOR_ARM_64 | SLANG_PROCESSOR_X86_64 | SLANG_PROCESSOR_POWER_PC_64)
-#define SLANG_PTR_IS_32 (SLANG_PTR_IS_64 ^ 1)
-
-// Processor features
-#if SLANG_PROCESSOR_FAMILY_X86
-# define SLANG_LITTLE_ENDIAN 1
-# define SLANG_UNALIGNED_ACCESS 1
-#elif SLANG_PROCESSOR_FAMILY_ARM
-# if defined(__ARMEB__)
-# define SLANG_BIG_ENDIAN 1
-# else
-# define SLANG_LITTLE_ENDIAN 1
-# endif
-#elif SLANG_PROCESSOR_FAMILY_POWER_PC
-# define SLANG_BIG_ENDIAN 1
-#endif
-
-#ifndef SLANG_LITTLE_ENDIAN
-# define SLANG_LITTLE_ENDIAN 0
-#endif
-
-#ifndef SLANG_BIG_ENDIAN
-# define SLANG_BIG_ENDIAN 0
-#endif
-
-#ifndef SLANG_UNALIGNED_ACCESS
-# define SLANG_UNALIGNED_ACCESS 0
-#endif
-
-// One endianess must be set
-#if ((SLANG_BIG_ENDIAN | SLANG_LITTLE_ENDIAN) == 0)
-# error "Couldn't determine endianess"
-#endif
-
-#ifndef SLANG_NO_INTTYPES
-#include <inttypes.h>
-#endif // ! SLANG_NO_INTTYPES
-
-#ifndef SLANG_NO_STDDEF
-#include <stddef.h>
-#endif // ! SLANG_NO_STDDEF
-
-/* --------------- END From slang.h ----------------- */
-
-// TODO(JS): Hack! Output C++ code from slang can copy unitialized variables.
-#if SLANG_VC
-# pragma warning(disable : 4700)
-#endif
-
-#include <math.h>
-#include <assert.h>
-#include <stdlib.h>
-
-#ifndef SLANG_PRELUDE_PI
-# define SLANG_PRELUDE_PI 3.14159265358979323846
-#endif
-
-#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
-
-#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;
-};
-
-/* Varing input for Compute */
-
-struct ComputeVaryingInput
-{
- uint3 groupID;
- uint3 groupThreadID;
-};
-
-// ----------------------------- 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; }
-
-// ----------------------------- 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; }
-
-#ifdef SLANG_PRELUDE_NAMESPACE
-}
-#endif
-
-#endif
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index 91230b9d0..e8170be40 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -13,13 +13,14 @@
#include "shader-renderer-util.h"
+#include "../source/core/slang-io.h"
+
#include "shader-input-layout.h"
#include <stdio.h>
#include <stdlib.h>
-// TODO(JS): We need to put the prelude into a better place
#define SLANG_PRELUDE_NAMESPACE CPPPrelude
-#include "../../tests/cross-compile/slang-cpp-prelude.h"
+#include "../../prelude/slang-cpp-types.h"
#include "../../source/core/slang-test-tool-util.h"
#include "../../source/core/slang-memory-arena.h"
@@ -1059,6 +1060,8 @@ int main(int argc, char** argv)
using namespace Slang;
SlangSession* session = spCreateSession(nullptr);
+ TestToolUtil::setSessionDefaultPrelude(argv[0], session);
+
auto stdWriters = StdWriters::initDefaultSingleton();
SlangResult res = innerMain(stdWriters, session, argc, argv);
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index 63e2456d9..ff80c7ec0 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -32,7 +32,7 @@ using namespace Slang;
#include <stdarg.h>
#define SLANG_PRELUDE_NAMESPACE CPPPrelude
-#include "../../tests/cross-compile/slang-cpp-prelude.h"
+#include "../../prelude/slang-cpp-types.h"
// Options for a particular test
struct TestOptions
@@ -1388,54 +1388,6 @@ static TestResult runCPPCompilerCompile(TestContext* context, TestInput& input)
return TestResult::Fail;
}
- String modulePath = _calcModulePath(input);
-
- // Find the target
- UnownedStringSlice targetExt = UnownedStringSlice::fromLiteral("c");
- Index index = cmdLine.findArgIndex(UnownedStringSlice::fromLiteral("-target"));
- if (index >= 0 && index + 1 < cmdLine.getArgCount())
- {
- targetExt = cmdLine.m_args[index + 1].value.getUnownedSlice();
- }
-
- // If output was C/C++ we should try compiling
- if (targetExt == "c" || targetExt == "cpp")
- {
- CPPCompiler::CompileOptions options;
- options.sourceType = (targetExt == "c") ? CPPCompiler::SourceType::C : CPPCompiler::SourceType::CPP;
-
- options.includePaths.add("tests/cross-compile");
-
- String actualOutput = exeRes.standardOutput;
-
- // Create a filename to write this out to
- String cppSource = modulePath + "." + targetExt;
- Slang::File::writeAllText(cppSource, actualOutput);
-
- // Okay we can now try compiling
-
- // Compile this source
- options.sourceFiles.add(cppSource);
- options.modulePath = modulePath;
- options.targetType = CPPCompiler::TargetType::SharedLibrary;
-
- CPPCompiler::Output output;
- if (SLANG_FAILED(compiler->compile(options, output)))
- {
- return TestResult::Fail;
- }
-
- if (output.getCountByType(CPPCompiler::Diagnostic::Type::Error) > 0)
- {
- return TestResult::Fail;
- }
- }
- else
- {
- // Can only be callable
- SLANG_ASSERT(targetExt == "callable" || targetExt == "host-callable");
- }
-
return TestResult::Pass;
}
@@ -2853,6 +2805,8 @@ SlangResult innerMain(int argc, char** argv)
TestContext context;
SLANG_RETURN_ON_FAIL(SLANG_FAILED(context.init()))
+ TestToolUtil::setSessionDefaultPrelude(argv[0], context.getSession());
+
auto& categorySet = context.categorySet;
// Set up our test categories here
diff --git a/tools/slang-test/test-context.cpp b/tools/slang-test/test-context.cpp
index 5da998f03..fe9bdbc0e 100644
--- a/tools/slang-test/test-context.cpp
+++ b/tools/slang-test/test-context.cpp
@@ -21,6 +21,7 @@ Result TestContext::init()
{
return SLANG_FAIL;
}
+
return SLANG_OK;
}