summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-08-08 17:23:03 -0400
committerGitHub <noreply@github.com>2019-08-08 17:23:03 -0400
commit41247c3942210df33b9e3dd733eafb23573a4f2f (patch)
treea49a88e680078bd379fe183cf826d49d7f935737 /tests
parentc1cc93dd962a6db6c839341f11d2654cf0e62e37 (diff)
WIP: Preliminary Slang -> C++ code generation (#1009)
* Expanded prelude for some other resource types. Disable C++ output for ParameterGroup. * WIP: Layout for CPU. * Fixes to CPU layout. * WIP: The uniform is output, but the variable definition is not. * WIP: Entry point parameters to global scope in C++. Handling of resource types (in so far as outputting) * Some discussion of ABI and different input types. * WIP: More C++ support around resource types. * WIP: Split up variables into different structures on emit. * WIP: Emitting C++ with wrapping up of 'Context' * WIP: C++ code has access to semantic values. Wrap in struct so can use method calls to pass shared state. Disable legalizeResourceTypes and legalizeExistentialTypeLayout * Fix structured buffer layout for CPU. * Remove testing/handling of global uniforms on CPU path. Typo fix. Changed CPU tests to use new CPU calling convention. * Check globals are working. Initalize context to zero globals. * Order the global parameters for C++ ouput by their layout. Note - that layout isn't quite working correctly because the StructuredBuffer<int> the int seems to be consuming uniform space. * Work around for reflection not having all data needed for layout ordering for C++ code. * Output constant buffers as pointers. * Entry point parameters accessed through pointer to struct. * WIP: Layout for CPU is reasonable for test case. * Only output 'f' after float literal if type marks as a float. * Cast construction works on C++. * Made IntrinsicOp::ConvertConstruct to make intent clearer. * C++ handling construction from scalar. Handle access of a scalar with .x. Check default initialization. * Comment about need for split of kIROp_construct. Release build works. * Added support from constructVectorFromScalar to C/C++ target. * Handling of in/out in C/C++. * First pass documentation CPU support. * Improvements to C++/C slang code generation documentation. * Small doc change to include need for mechansim to specify cpp compiler path. * Better handling of swizzling - allow swizzling a scalar into a vector.
Diffstat (limited to 'tests')
-rw-r--r--tests/cross-compile/c-cross-compile.slang4
-rw-r--r--tests/cross-compile/cpp-execute-simple.slang8
-rw-r--r--tests/cross-compile/cpp-execute.slang7
-rw-r--r--tests/cross-compile/cpp-resource-reflection.slang42
-rw-r--r--tests/cross-compile/cpp-resource-reflection.slang.expected163
-rw-r--r--tests/cross-compile/cpp-resource.slang53
-rw-r--r--tests/cross-compile/slang-cpp-prelude.h625
7 files changed, 883 insertions, 19 deletions
diff --git a/tests/cross-compile/c-cross-compile.slang b/tests/cross-compile/c-cross-compile.slang
index 29078f0b6..646ba3445 100644
--- a/tests/cross-compile/c-cross-compile.slang
+++ b/tests/cross-compile/c-cross-compile.slang
@@ -65,6 +65,9 @@ struct Thing
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out
RWStructuredBuffer<int> outputBuffer;
+RWStructuredBuffer<int> outputBuffer2;
+
+
[numthreads(4, 1, 1)]
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
{
@@ -104,4 +107,5 @@ void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
val = test(val);
outputBuffer[tid] = val + int(dot(vec2, vec4));
+ outputBuffer2[tid] = int(tid);
} \ No newline at end of file
diff --git a/tests/cross-compile/cpp-execute-simple.slang b/tests/cross-compile/cpp-execute-simple.slang
index 74a3ec634..72c77b653 100644
--- a/tests/cross-compile/cpp-execute-simple.slang
+++ b/tests/cross-compile/cpp-execute-simple.slang
@@ -1,10 +1,12 @@
//TEST:CPU_EXECUTE: -profile cs_5_0 -entry computeMain -target sharedlib
+//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,
-//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out
- RWStructuredBuffer<int> outputBuffer)
+ uint3 dispatchThreadID : SV_DispatchThreadID)
{
uint tid = dispatchThreadID.x;
diff --git a/tests/cross-compile/cpp-execute.slang b/tests/cross-compile/cpp-execute.slang
index 1c90c8dd2..2700aa49f 100644
--- a/tests/cross-compile/cpp-execute.slang
+++ b/tests/cross-compile/cpp-execute.slang
@@ -62,11 +62,12 @@ struct Thing
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,
-//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out
- RWStructuredBuffer<int> outputBuffer)
+ uint3 dispatchThreadID : SV_DispatchThreadID)
{
uint tid = dispatchThreadID.x;
diff --git a/tests/cross-compile/cpp-resource-reflection.slang b/tests/cross-compile/cpp-resource-reflection.slang
new file mode 100644
index 000000000..122e7b4de
--- /dev/null
+++ b/tests/cross-compile/cpp-resource-reflection.slang
@@ -0,0 +1,42 @@
+//TEST:REFLECTION: -profile cs_5_0 -entry computeMain -target cpp
+
+
+struct Thing
+{
+ int a;
+ float b;
+ float c;
+};
+
+static int value;
+
+// Don't use parameter block for now
+//ParameterBlock<AnotherThing> s_paramBlock;
+
+ConstantBuffer<Thing> thing3;
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out
+RWStructuredBuffer<int> outputBuffer;
+
+Texture2D<float> tex;
+SamplerState sampler;
+
+[numthreads(4, 1, 1)]
+void computeMain(
+ uint3 dispatchThreadID : SV_DispatchThreadID,
+ uniform Thing thing,
+ uniform Thing thing2)
+{
+ uint tid = dispatchThreadID.x;
+
+ // TODO(JS): Doesn't emit correctly on c++ becomes...
+ // Vector<float, 2> loc_0 = Vector<float, 2>{Vector<uint32_t, 2>{dispatchThreadID_0.x, dispatchThreadID_0.y}} * 0.50000000000000000000f;
+ //float2 loc = dispatchThreadID.xy * 0.5f;
+
+ float2 loc = float2(dispatchThreadID.x * 0.5f, dispatchThreadID.y * 0.5f);
+
+ float v = tex.Load(int3(tid, tid, 0));
+ float s = tex.Sample(sampler, loc);
+
+ outputBuffer[tid] = int(tid * tid) + thing.a + thing3.a + int(v + s) + value; // + thing.a;
+} \ No newline at end of file
diff --git a/tests/cross-compile/cpp-resource-reflection.slang.expected b/tests/cross-compile/cpp-resource-reflection.slang.expected
new file mode 100644
index 000000000..a0e5241f0
--- /dev/null
+++ b/tests/cross-compile/cpp-resource-reflection.slang.expected
@@ -0,0 +1,163 @@
+result code = 0
+standard error = {
+}
+standard output = {
+{
+ "parameters": [
+ {
+ "name": "thing3",
+ "binding": {"kind": "uniform", "offset": 0, "size": 8},
+ "type": {
+ "kind": "constantBuffer",
+ "elementType": {
+ "kind": "struct",
+ "name": "Thing",
+ "fields": [
+ {
+ "name": "a",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "int32"
+ },
+ "binding": {"kind": "uniform", "offset": 0, "size": 4}
+ },
+ {
+ "name": "b",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "float32"
+ },
+ "binding": {"kind": "uniform", "offset": 4, "size": 4}
+ },
+ {
+ "name": "c",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "float32"
+ },
+ "binding": {"kind": "uniform", "offset": 8, "size": 4}
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "outputBuffer",
+ "binding": {"kind": "uniform", "offset": 8, "size": 16},
+ "type": {
+ "kind": "resource",
+ "baseShape": "structuredBuffer",
+ "access": "readWrite",
+ "resultType": {
+ "kind": "scalar",
+ "scalarType": "int32"
+ }
+ }
+ },
+ {
+ "name": "tex",
+ "binding": {"kind": "uniform", "offset": 24, "size": 8},
+ "type": {
+ "kind": "resource",
+ "baseShape": "texture2D"
+ }
+ },
+ {
+ "name": "sampler",
+ "binding": {"kind": "uniform", "offset": 32, "size": 8},
+ "type": {
+ "kind": "samplerState"
+ }
+ }
+ ],
+ "entryPoints": [
+ {
+ "name": "computeMain",
+ "stage:": "compute",
+ "parameters": [
+ {
+ "name": "dispatchThreadID",
+ "semanticName": "SV_DISPATCHTHREADID",
+ "type": {
+ "kind": "vector",
+ "elementCount": 3,
+ "elementType": {
+ "kind": "scalar",
+ "scalarType": "uint32"
+ }
+ }
+ },
+ {
+ "name": "thing",
+ "binding": {"kind": "uniform", "offset": 0, "size": 12},
+ "type": {
+ "kind": "struct",
+ "name": "Thing",
+ "fields": [
+ {
+ "name": "a",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "int32"
+ },
+ "binding": {"kind": "uniform", "offset": 0, "size": 4}
+ },
+ {
+ "name": "b",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "float32"
+ },
+ "binding": {"kind": "uniform", "offset": 4, "size": 4}
+ },
+ {
+ "name": "c",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "float32"
+ },
+ "binding": {"kind": "uniform", "offset": 8, "size": 4}
+ }
+ ]
+ }
+ },
+ {
+ "name": "thing2",
+ "binding": {"kind": "uniform", "offset": 12, "size": 12},
+ "type": {
+ "kind": "struct",
+ "name": "Thing",
+ "fields": [
+ {
+ "name": "a",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "int32"
+ },
+ "binding": {"kind": "uniform", "offset": 0, "size": 4}
+ },
+ {
+ "name": "b",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "float32"
+ },
+ "binding": {"kind": "uniform", "offset": 4, "size": 4}
+ },
+ {
+ "name": "c",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "float32"
+ },
+ "binding": {"kind": "uniform", "offset": 8, "size": 4}
+ }
+ ]
+ }
+ }
+ ],
+ "threadGroupSize": [4, 1, 1]
+ }
+ ]
+}
+}
diff --git a/tests/cross-compile/cpp-resource.slang b/tests/cross-compile/cpp-resource.slang
new file mode 100644
index 000000000..f443249ad
--- /dev/null
+++ b/tests/cross-compile/cpp-resource.slang
@@ -0,0 +1,53 @@
+//TEST:CPP_COMPILER_COMPILE: -profile cs_5_0 -entry computeMain -target cpp
+
+struct Thing
+{
+ int a;
+ float b;
+};
+
+static int value;
+
+// Don't use parameter block for now
+//ParameterBlock<AnotherThing> s_paramBlock;
+
+ConstantBuffer<Thing> thing3;
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out
+RWStructuredBuffer<int> outputBuffer;
+
+Texture2D<float> tex;
+SamplerState sampler;
+
+void doSomething(int a, inout float3 v[2])
+{
+ v[0] = float3(float(a));
+ v[1] = float3(float(a + 1));
+}
+
+[numthreads(4, 1, 1)]
+void computeMain(
+ uint3 dispatchThreadID : SV_DispatchThreadID,
+ uniform Thing thing,
+ uniform Thing thing2)
+{
+ uint tid = dispatchThreadID.x;
+
+ int2 fromScalar = tid.x;
+ uint2 another = {};
+
+ float2 loc = dispatchThreadID.xy * 0.5f;
+
+ float v = tex.Load(int3(tid, tid, 0));
+ float s = tex.Sample(sampler, loc);
+
+ // This should promote the 0.0 into a float2,
+ float l = tex.Sample(sampler, 0.0);
+
+ float3 m = float(3).xxx;
+
+ float3 arr[2] = { float3(3), float3(4) };
+ doSomething(int(tid), arr);
+
+ outputBuffer[tid] = int(tid * tid) + thing.a + thing3.a + int(v + s) + value + fromScalar.y + int(another.y) + int(m.x) + int(l) + int(arr[0].y); // + thing.a;
+} \ No newline at end of file
diff --git a/tests/cross-compile/slang-cpp-prelude.h b/tests/cross-compile/slang-cpp-prelude.h
index f2635eb2c..612e04a0b 100644
--- a/tests/cross-compile/slang-cpp-prelude.h
+++ b/tests/cross-compile/slang-cpp-prelude.h
@@ -1,17 +1,442 @@
#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>
-#include <math.h>
-#include <inttypes.h>
+#endif // ! SLANG_NO_INTTYPES
+
+#ifndef SLANG_NO_STDDEF
+#include <stddef.h>
+#endif // ! SLANG_NO_STDDEF
+
+/* --------------- END From slang.h ----------------- */
+
#include <math.h>
#include <assert.h>
#include <stdlib.h>
-#ifndef SLANG_FORCE_INLINE
-# define SLANG_FORCE_INLINE inline
-#endif
-
#ifndef SLANG_PRELUDE_PI
# define SLANG_PRELUDE_PI 3.14159265358979323846
#endif
@@ -35,6 +460,7 @@
namespace SLANG_PRELUDE_NAMESPACE {
#endif
+
template <typename T, size_t SIZE>
struct FixedArray
{
@@ -44,14 +470,12 @@ struct FixedArray
T m_data[SIZE];
};
-template <typename T>
-struct RWStructuredBuffer
+
+// Hmm... I guess a constant buffer should be unwrapped to be just a struct passed in
+/* template <typename T>
+struct ConstantBuffer
{
- T& operator[](size_t index) const { return data[index]; }
-
- T* data;
- size_t count;
-};
+}; */
template <typename T, int COUNT>
struct Vector;
@@ -80,12 +504,187 @@ 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