diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-07-09 13:59:30 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-09 13:59:30 -0400 |
| commit | f52f5cd4a7b5b71617b949fc62a78abe8c4822b3 (patch) | |
| tree | 48f636f33e199b3508d779941c034f7be91debc4 /tests | |
| parent | 691ebae763e29327249735d67fbb231c75b17840 (diff) | |
WIP: slang to C++ code generation (#997)
* WIP: Emitting Cpp
* Added HLSLType instead of using IRInst - because they don't seem to be deduped.
* Removed need for lexer to take a String.
Added mechansim to lookup intrinsic functions on C++.
* A c/c++ cross compilation test.
* WIP Cpp output using cloning and slang types.
* More work to generate mul funcs.
* WIP: Outputting some simple C++.
* Expose findOrEmitHoistableInst to IRBuilder to aid cloning,
* Simplification for checking for BasicTypes.
Test infrastructure compiles output C++ code.
* Dot and mat/vec multiplication output.
* First pass at swizzling.
* First support for binary ops.
* Builtin binary and unary functions.
* Any and all.
* WIP adding support for other functions.
Added code to generate function signature.
* Add scalar functions to slang-cpp-prelude.h
* Support for most built in operations.
* Tested first ternary.
* Checking the emitting of corner cases functions - normalize, length, any, all, normalize, reflect.
* Check asfloat etc work.
* Fmod support.
* WIP Array handling in C++.
* First stage in being able to handl arbitrary type output for CLikeSourceEmitter
* Removed Handler/Emitter split - so can implement more easily complex type naming.
* Array passing by value first pass.
* Rename Array -> FixedArray
* Outputs structs in C++.
* Emit the thread config.
* Dimension -> TypeDimension
* SpecializedOperation -> SpecializedIntrinsic
Operation -> IntrinsicOp
Use shared impl of isNominalOp
Commented use of m_uniqueModule etc.
* Add code to test slang->cpp when compiled doesn't have errors. Does so by building shared library and exporting the entry point.
* Fix linux clang/gcc compile error about override not being specified.
* Make sure c-cross-compile is run on linux targets/smoke.
* Remove c-cross-compile.slang from smoke.
* Fix running tests/cross-compile/c-cross-compile.slang on Ubuntu 16.04
* Only add -std=c++11 for C++ source.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/cross-compile/c-cross-compile.slang | 107 | ||||
| -rw-r--r-- | tests/cross-compile/slang-cpp-prelude.h | 122 |
2 files changed, 229 insertions, 0 deletions
diff --git a/tests/cross-compile/c-cross-compile.slang b/tests/cross-compile/c-cross-compile.slang new file mode 100644 index 000000000..29078f0b6 --- /dev/null +++ b/tests/cross-compile/c-cross-compile.slang @@ -0,0 +1,107 @@ +//TEST:CPP_COMPILER_COMPILE: -profile cs_5_0 -entry computeMain -target cpp + +enum Color +{ + Red, + Green = 2, + Blue, +} + +int test(int val) +{ + Color c = Color.Red; + + if(val > 1) + { + c = Color.Green; + } + + if(c == Color.Red) + { + if(val & 1) + { + c = Color.Blue; + } + } + + switch(c) + { + case Color.Red: + val = 1; + break; + + case Color.Green: + val = 2; + break; + + case Color.Blue: + val = 3; + break; + + default: + val = -1; + break; + } + + return (val << 4) + int(c); +} + +float sum(float a[3]) +{ + float total = a[0]; + for (int i = 1; i < 3; ++i) + { + total += a[i]; + } + return total; +} + +struct Thing +{ + int a; + float b; +}; + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out +RWStructuredBuffer<int> outputBuffer; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + + Thing thing = { 10, -1.0 }; + + float array[3] = { thing.a, 2, 3}; + + float anotherArray[] = { 1, 2, 5 }; + + array[0] += anotherArray[1]; + + matrix<float, 2, 3> mat = { { sum(array), 1, 2 }, { 3, 4, 5} }; + vector<float, 2> vec = { float(tid + 1), float(tid + 2) }; + + + vector<float, 3> vec2 = max(sin(mul(vec, mat)), float3(1, 2, -1)); + vector<float, 3> vec3 = mul(vec, mat); + + float3 vec4 = lerp(vec2, vec3, float3(tid * (1.0f / 4), 1, 1)); + + float3 crossVec = normalize(cross(vec4, vec4)); + + vec2.x = fmod(crossVec.y, crossVec.x); + + vec2 = fmod(vec2, crossVec); + + vec2 += (-vec2.zyx) * 2 + crossVec * length(crossVec) + reflect(vec4, normalize(crossVec)); + + vector<bool, 3> z = vec2 > 0; + + int val = (int(tid) + (any(z) ? 1 : 0) + (all(z) ? 2 : 0)) % 100; + + val = asint(asfloat(asuint(asfloat(val)))); + + val = test(val); + + outputBuffer[tid] = val + int(dot(vec2, vec4)); +}
\ No newline at end of file diff --git a/tests/cross-compile/slang-cpp-prelude.h b/tests/cross-compile/slang-cpp-prelude.h new file mode 100644 index 000000000..f60fc8518 --- /dev/null +++ b/tests/cross-compile/slang-cpp-prelude.h @@ -0,0 +1,122 @@ + +#include <inttypes.h> +#include <math.h> +#include <inttypes.h> +#include <math.h> +#include <assert.h> +#include <stdlib.h> + +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +#if defined(_MSC_VER) +# define SLANG_SHARED_LIB_EXPORT __declspec(dllexport) +#else +# define SLANG_SHARED_LIB_EXPORT __attribute__((__visibility__("default"))) +//# define SLANG_SHARED_LIB_EXPORT __attribute__ ((dllexport)) __attribute__((__visibility__("default"))) +#endif + +#ifdef __cplusplus +# define SLANG_EXTERN_C extern "C" +#else +# define SLANG_EXTERN_C +#endif + +#define SLANG_EXPORT SLANG_EXTERN_C SLANG_SHARED_LIB_EXPORT + +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]; +}; + +template <typename T> +struct RWStructuredBuffer +{ + T& operator[](size_t index) const { return data[index]; } + + T* data; + size_t count; +}; + +// ----------------------------- F32 ----------------------------------------- + +union Union32 +{ + uint32_t u; + int32_t i; + float f; +}; + +// Helpers +float F32_calcSafeRadians(float radians) +{ + float a = radians * (1.0f / M_PI); + a = (a < 0.0f) ? (::ceilf(a) - a) : (a - ::floorf(a)); + return (a * M_PI); +} + +// Unary +float F32_ceil(float f) { return ::ceilf(f); } +float F32_floor(float f) { return ::floorf(f); } +float F32_sin(float f) { return ::sinf(F32_calcSafeRadians(f)); } +float F32_cos(float f) { return ::cosf(F32_calcSafeRadians(f)); } +float F32_tan(float f) { return ::tanf(f); } +float F32_asin(float f) { return ::asinf(f); } +float F32_acos(float f) { return ::acosf(f); } +float F32_atan(float f) { return ::atanf(f); } +float F32_log2(float f) { return ::log2f(f); } +float F32_exp2(float f) { return ::exp2f(f); } +float F32_exp(float f) { return ::expf(f); } +float F32_abs(float f) { return ::fabsf(f); } +float F32_trunc(float f) { return ::truncf(f); } +float F32_sqrt(float f) { return ::sqrtf(f); } +float F32_rsqrt(float f) { return 1.0f / F32_sqrt(f); } +float F32_rcp(float f) { return 1.0f / f; } +float F32_sign(float f) { return ( f == 0.0f) ? f : (( f < 0.0f) ? -1.0f : 1.0f); } +float F32_saturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } +float F32_frac(float f) { return f - F32_floor(f); } +float F32_radians(float f) { return f * 0.01745329222f; } + +// Binary +float F32_min(float a, float b) { return a < b ? a : b; } +float F32_max(float a, float b) { return a > b ? a : b; } +float F32_pow(float a, float b) { return ::powf(a, b); } +float F32_fmod(float a, float b) { return ::fmodf(a, b); } +float F32_step(float a, float b) { return float(a >= b); } +float F32_atan2(float a, float b) { return float(atan2(a, b)); } + +// Ternary +float F32_smoothstep(float min, float max, float x) { return x < min ? min : ((x > max) ? max : x / (max - min)); } +float F32_lerp(float x, float y, float s) { return x + s * (y - x); } +float F32_clamp(float x, float min, float max) { return ( x < min) ? min : ((x > max) ? max : x); } +void F32_sincos(float f, float& outSin, float& outCos) { outSin = F32_sin(f); outCos = F32_cos(f); } + +uint32_t F32_asuint(float f) { Union32 u; u.f = f; return u.u; } +int32_t F32_asint(float f) { Union32 u; u.f = f; return u.i; } + +// ----------------------------- I32 ----------------------------------------- + +int32_t I32_abs(int32_t f) { return (f < 0) ? -f : f; } + +int32_t I32_min(int32_t a, int32_t b) { return a < b ? a : b; } +int32_t I32_max(int32_t a, int32_t b) { return a > b ? a : b; } + +int32_t I32_clamp(int32_t x, int32_t min, int32_t max) { return ( x < min) ? min : ((x > max) ? max : x); } + +float I32_asfloat(int32_t x) { Union32 u; u.i = x; return u.f; } + +// ----------------------------- U32 ----------------------------------------- + +uint32_t U32_abs(uint32_t f) { return f; } + +uint32_t U32_min(uint32_t a, uint32_t b) { return a < b ? a : b; } +uint32_t U32_max(uint32_t a, uint32_t b) { return a > b ? a : b; } + +uint32_t U32_clamp(uint32_t x, uint32_t min, uint32_t max) { return ( x < min) ? min : ((x > max) ? max : x); } + +float U32_asfloat(uint32_t x) { Union32 u; u.u = x; return u.f; } |
