diff options
| author | Yong He <yonghe@outlook.com> | 2020-07-03 12:37:17 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-03 12:37:17 -0700 |
| commit | ffd0b9c9b06a22d886c77d777d9aa0cd1298d363 (patch) | |
| tree | f94144c1c8cb5044f630ce839c37eecbe2bce20f | |
| parent | dfc9100bbd451a5752ed543a503e2574d3dcdaa5 (diff) | |
Emit pointers for CPU target. (#1418)
Co-authored-by: Yong He <yhe@nvidia.com>
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | prelude/slang-cpp-scalar-intrinsics.h | 28 | ||||
| -rw-r--r-- | prelude/slang-cpp-types.h | 354 | ||||
| -rw-r--r-- | prelude/slang-cuda-prelude.h | 40 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang | 60 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 127 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 93 | ||||
| -rw-r--r-- | source/slang/slang-emit-cpp.h | 1 | ||||
| -rw-r--r-- | tests/compute/pointer-emit.slang | 71 | ||||
| -rw-r--r-- | tests/compute/pointer-emit.slang.expected.txt | 4 |
11 files changed, 478 insertions, 306 deletions
diff --git a/.gitignore b/.gitignore index cf8a1ea5d..1471d0b6e 100644 --- a/.gitignore +++ b/.gitignore @@ -22,11 +22,14 @@ build.*/ *.expected.png *.actual.png *.actual.txt +*.slang-repro tests/**/*.exp tests/**/*.lib tests/**/*.dll tests/**/*.cpp +tests/**/*.slang-lib +tests/**/*.slang-module # Files generated by other shader compilers diff --git a/prelude/slang-cpp-scalar-intrinsics.h b/prelude/slang-cpp-scalar-intrinsics.h index 07945f1e0..54900c3a3 100644 --- a/prelude/slang-cpp-scalar-intrinsics.h +++ b/prelude/slang-cpp-scalar-intrinsics.h @@ -80,16 +80,16 @@ SLANG_FORCE_INLINE float F32_fmod(float a, float b) { return ::fmodf(a, b); } SLANG_FORCE_INLINE float F32_remainder(float a, float b) { return ::remainderf(a, b); } SLANG_FORCE_INLINE float F32_atan2(float a, float b) { return float(::atan2(a, b)); } -SLANG_FORCE_INLINE float F32_frexp(float x, float& e) +SLANG_FORCE_INLINE float F32_frexp(float x, float* e) { int ei; float m = ::frexpf(x, &ei); - e = float(ei); + *e = float(ei); return m; } -SLANG_FORCE_INLINE float F32_modf(float x, float& ip) +SLANG_FORCE_INLINE float F32_modf(float x, float* ip) { - return ::modff(x, &ip); + return ::modff(x, ip); } SLANG_FORCE_INLINE uint32_t F32_asuint(float f) { Union32 u; u.f = f; return u.u; } @@ -147,33 +147,33 @@ SLANG_FORCE_INLINE double F64_fmod(double a, double b) { return ::fmod(a, b); } SLANG_FORCE_INLINE double F64_remainder(double a, double b) { return ::remainder(a, b); } SLANG_FORCE_INLINE double F64_atan2(double a, double b) { return ::atan2(a, b); } -SLANG_FORCE_INLINE double F64_frexp(double x, double& e) +SLANG_FORCE_INLINE double F64_frexp(double x, double* e) { int ei; double m = ::frexp(x, &ei); - e = float(ei); + *e = float(ei); return m; } -SLANG_FORCE_INLINE double F64_modf(double x, double& ip) +SLANG_FORCE_INLINE double F64_modf(double x, double* ip) { - return ::modf(x, &ip); + return ::modf(x, ip); } -SLANG_FORCE_INLINE void F64_asuint(double d, uint32_t& low, uint32_t& hi) +SLANG_FORCE_INLINE void F64_asuint(double d, uint32_t* low, uint32_t* hi) { Union64 u; u.d = d; - low = uint32_t(u.u); - hi = uint32_t(u.u >> 32); + *low = uint32_t(u.u); + *hi = uint32_t(u.u >> 32); } -SLANG_FORCE_INLINE void F64_asint(double d, int32_t& low, int32_t& hi) +SLANG_FORCE_INLINE void F64_asint(double d, int32_t* low, int32_t* hi) { Union64 u; u.d = d; - low = int32_t(u.u); - hi = int32_t(u.u >> 32); + *low = int32_t(u.u); + *hi = int32_t(u.u >> 32); } // Ternary diff --git a/prelude/slang-cpp-types.h b/prelude/slang-cpp-types.h index 7e951fd63..3bff1873f 100644 --- a/prelude/slang-cpp-types.h +++ b/prelude/slang-cpp-types.h @@ -20,7 +20,7 @@ struct FixedArray { const T& operator[](size_t index) const { SLANG_PRELUDE_ASSERT(index < SIZE); return m_data[index]; } T& operator[](size_t index) { SLANG_PRELUDE_ASSERT(index < SIZE); return m_data[index]; } - + T m_data[SIZE]; }; @@ -31,7 +31,7 @@ struct Array { const T& operator[](size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; } T& operator[](size_t index) { SLANG_PRELUDE_ASSERT(index < count); return data[index]; } - + T* data; size_t count; }; @@ -99,7 +99,7 @@ struct RWStructuredBuffer { SLANG_FORCE_INLINE T& operator[](size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; } const T& Load(size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; } - void GetDimensions(uint32_t& outNumStructs, uint32_t& outStride) { outNumStructs = uint32_t(count); outStride = uint32_t(sizeof(T)); } + void GetDimensions(uint32_t* outNumStructs, uint32_t* outStride) { *outNumStructs = uint32_t(count); *outStride = uint32_t(sizeof(T)); } T* data; size_t count; @@ -110,7 +110,7 @@ struct StructuredBuffer { SLANG_FORCE_INLINE const T& operator[](size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; } const T& Load(size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; } - void GetDimensions(uint32_t& outNumStructs, uint32_t& outStride) { outNumStructs = uint32_t(count); outStride = uint32_t(sizeof(T)); } + void GetDimensions(uint32_t* outNumStructs, uint32_t* outStride) { *outNumStructs = uint32_t(count); *outStride = uint32_t(sizeof(T)); } T* data; size_t count; @@ -122,7 +122,7 @@ struct RWBuffer { SLANG_FORCE_INLINE T& operator[](size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; } const T& Load(size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; } - void GetDimensions(uint32_t& outCount) { outCount = uint32_t(count); } + void GetDimensions(uint32_t* outCount) { *outCount = uint32_t(count); } T* data; size_t count; @@ -133,7 +133,7 @@ struct Buffer { SLANG_FORCE_INLINE const T& operator[](size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; } const T& Load(size_t index) const { SLANG_PRELUDE_ASSERT(index < count); return data[index]; } - void GetDimensions(uint32_t& outCount) { outCount = uint32_t(count); } + void GetDimensions(uint32_t* outCount) { *outCount = uint32_t(count); } T* data; size_t count; @@ -142,7 +142,7 @@ struct Buffer // Missing Load(_In_ int Location, _Out_ uint Status); struct ByteAddressBuffer { - void GetDimensions(uint32_t& outDim) const { outDim = uint32_t(sizeInBytes); } + void GetDimensions(uint32_t* outDim) const { *outDim = uint32_t(sizeInBytes); } uint32_t Load(size_t index) const { SLANG_PRELUDE_ASSERT(index + 4 <= sizeInBytes && (index & 3) == 0); @@ -182,7 +182,7 @@ struct ByteAddressBuffer // Missing support for Load with status struct RWByteAddressBuffer { - void GetDimensions(uint32_t& outDim) const { outDim = uint32_t(sizeInBytes); } + void GetDimensions(uint32_t* outDim) const { *outDim = uint32_t(sizeInBytes); } uint32_t Load(size_t index) const { @@ -385,20 +385,20 @@ struct ITexture template <typename T> struct Texture1D { - void GetDimensions(uint32_t& outWidth) { outWidth = texture->GetDimensions().width; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t* outWidth) { *outWidth = texture->GetDimensions().width; } + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(float& outWidth) { outWidth = texture->GetDimensions().width; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outNumberOfLevels) + void GetDimensions(float* outWidth) { *outWidth = texture->GetDimensions().width; } + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outNumberOfLevels = dims.numberOfLevels; } T Load(const int2& loc) const { T out; texture->Load(&loc.x, &out); return out; } @@ -411,31 +411,31 @@ struct Texture1D template <typename T> struct Texture2D { - void GetDimensions(uint32_t& outWidth, uint32_t& outHeight) + void GetDimensions(uint32_t* outWidth, uint32_t* outHeight) { const auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; + *outWidth = dims.width; + *outHeight = dims.height; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outHeight, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outHeight, uint32_t* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(float& outWidth, float& outHeight) + void GetDimensions(float* outWidth, float* outHeight) { const auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; + *outWidth = dims.width; + *outHeight = dims.height; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outHeight, float& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outHeight, float* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outNumberOfLevels = dims.numberOfLevels; } T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out); return out; } @@ -448,35 +448,35 @@ struct Texture2D template <typename T> struct Texture3D { - void GetDimensions(uint32_t& outWidth, uint32_t& outHeight, uint32_t& outDepth) + void GetDimensions(uint32_t* outWidth, uint32_t* outHeight, uint32_t* outDepth) { const auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; - outDepth = dims.depth; + *outWidth = dims.width; + *outHeight = dims.height; + *outDepth = dims.depth; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outHeight, uint32_t& outDepth, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outHeight, uint32_t* outDepth, uint32_t* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outDepth = dims.depth; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outDepth = dims.depth; + *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(float& outWidth, float& outHeight, float& outDepth) + void GetDimensions(float* outWidth, float* outHeight, float* outDepth) { const auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; - outDepth = dims.depth; + *outWidth = dims.width; + *outHeight = dims.height; + *outDepth = dims.depth; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outHeight, float& outDepth, float& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outHeight, float* outDepth, float* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outDepth = dims.depth; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outDepth = dims.depth; + *outNumberOfLevels = dims.numberOfLevels; } T Load(const int4& loc) const { T out; texture->Load(&loc.x, &out); return out; } @@ -489,31 +489,31 @@ struct Texture3D template <typename T> struct TextureCube { - void GetDimensions(uint32_t& outWidth, uint32_t& outHeight) + void GetDimensions(uint32_t* outWidth, uint32_t* outHeight) { const auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; + *outWidth = dims.width; + *outHeight = dims.height; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outHeight, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outHeight, uint32_t* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(float& outWidth, float& outHeight) + void GetDimensions(float* outWidth, float* outHeight) { const auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; + *outWidth = dims.width; + *outHeight = dims.height; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outHeight, float& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outHeight, float* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outNumberOfLevels = dims.numberOfLevels; } T Sample(SamplerState samplerState, const float3& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } @@ -525,21 +525,21 @@ struct TextureCube template <typename T> struct Texture1DArray { - void GetDimensions(uint32_t& outWidth, uint32_t& outElements) { auto dims = texture->GetDimensions(); outWidth = dims.width; outElements = dims.arrayElementCount; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outElements, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t* outWidth, uint32_t* outElements) { auto dims = texture->GetDimensions(); *outWidth = dims.width; *outElements = dims.arrayElementCount; } + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outElements, uint32_t* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outNumberOfLevels = dims.numberOfLevels; - outElements = dims.arrayElementCount; + *outWidth = dims.width; + *outNumberOfLevels = dims.numberOfLevels; + *outElements = dims.arrayElementCount; } - void GetDimensions(float& outWidth, float& outElements) { auto dims = texture->GetDimensions(); outWidth = dims.width; outElements = dims.arrayElementCount; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outElements, float& outNumberOfLevels) + void GetDimensions(float* outWidth, float* outElements) { auto dims = texture->GetDimensions(); *outWidth = dims.width; *outElements = dims.arrayElementCount; } + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outElements, float* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outNumberOfLevels = dims.numberOfLevels; - outElements = dims.arrayElementCount; + *outWidth = dims.width; + *outNumberOfLevels = dims.numberOfLevels; + *outElements = dims.arrayElementCount; } T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out); return out; } @@ -552,36 +552,36 @@ struct Texture1DArray template <typename T> struct Texture2DArray { - void GetDimensions(uint32_t& outWidth, uint32_t& outHeight, uint32_t& outElements) + void GetDimensions(uint32_t* outWidth, uint32_t* outHeight, uint32_t* outElements) { auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outHeight, uint32_t& outElements, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outHeight, uint32_t* outElements, uint32_t* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; + *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(uint32_t& outWidth, float& outHeight, float& outElements) + void GetDimensions(uint32_t* outWidth, float* outHeight, float* outElements) { auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outHeight, float& outElements, float& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outHeight, float* outElements, float* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; + *outNumberOfLevels = dims.numberOfLevels; } T Load(const int4& loc) const { T out; texture->Load(&loc.x, &out); return out; } @@ -594,36 +594,36 @@ struct Texture2DArray template <typename T> struct TextureCubeArray { - void GetDimensions(uint32_t& outWidth, uint32_t& outHeight, uint32_t& outElements) + void GetDimensions(uint32_t* outWidth, uint32_t* outHeight, uint32_t* outElements) { auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outHeight, uint32_t& outElements, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outHeight, uint32_t* outElements, uint32_t* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; + *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(uint32_t& outWidth, float& outHeight, float& outElements) + void GetDimensions(uint32_t* outWidth, float* outHeight, float* outElements) { auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outHeight, float& outElements, float& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outHeight, float* outElements, float* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; + *outNumberOfLevels = dims.numberOfLevels; } T Sample(SamplerState samplerState, const float4& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } @@ -647,11 +647,11 @@ struct IRWTexture template <typename T> struct RWTexture1D { - void GetDimensions(uint32_t& outWidth) { outWidth = texture->GetDimensions().width; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); outWidth = dims.width; outNumberOfLevels = dims.numberOfLevels; } + void GetDimensions(uint32_t* outWidth) { *outWidth = texture->GetDimensions().width; } + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); *outWidth = dims.width; *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(float& outWidth) { outWidth = texture->GetDimensions().width; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); outWidth = dims.width; outNumberOfLevels = dims.numberOfLevels; } + void GetDimensions(float* outWidth) { *outWidth = texture->GetDimensions().width; } + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outNumberOfLevels) { auto dims = texture->GetDimensions(mipLevel); *outWidth = dims.width; *outNumberOfLevels = dims.numberOfLevels; } T Load(int32_t loc) const { T out; texture->Load(&loc, &out); return out; } T& operator[](uint32_t loc) { return *(T*)texture->refAt(&loc); } @@ -661,31 +661,31 @@ struct RWTexture1D template <typename T> struct RWTexture2D { - void GetDimensions(uint32_t& outWidth, uint32_t& outHeight) + void GetDimensions(uint32_t* outWidth, uint32_t* outHeight) { const auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; + *outWidth = dims.width; + *outHeight = dims.height; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outHeight, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outHeight, uint32_t* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(float& outWidth, float& outHeight) + void GetDimensions(float* outWidth, float* outHeight) { const auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; + *outWidth = dims.width; + *outHeight = dims.height; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outHeight, float& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outHeight, float* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outNumberOfLevels = dims.numberOfLevels; } T Load(const int2& loc) const { T out; texture->Load(&loc.x, &out); return out; } @@ -696,35 +696,35 @@ struct RWTexture2D template <typename T> struct RWTexture3D { - void GetDimensions(uint32_t& outWidth, uint32_t& outHeight, uint32_t& outDepth) + void GetDimensions(uint32_t* outWidth, uint32_t* outHeight, uint32_t* outDepth) { const auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; - outDepth = dims.depth; + *outWidth = dims.width; + *outHeight = dims.height; + *outDepth = dims.depth; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outHeight, uint32_t& outDepth, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outHeight, uint32_t* outDepth, uint32_t* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outDepth = dims.depth; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outDepth = dims.depth; + *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(float& outWidth, float& outHeight, float& outDepth) + void GetDimensions(float* outWidth, float* outHeight, float* outDepth) { const auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; - outDepth = dims.depth; + *outWidth = dims.width; + *outHeight = dims.height; + *outDepth = dims.depth; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outHeight, float& outDepth, float& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outHeight, float* outDepth, float* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outDepth = dims.depth; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outDepth = dims.depth; + *outNumberOfLevels = dims.numberOfLevels; } T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out); return out; } @@ -736,74 +736,76 @@ struct RWTexture3D template <typename T> struct RWTexture1DArray { - void GetDimensions(uint32_t& outWidth, uint32_t& outElements) + void GetDimensions(uint32_t* outWidth, uint32_t* outElements) { auto dims = texture->GetDimensions(); - outWidth = dims.width; - outElements = dims.arrayElementCount; + *outWidth = dims.width; + *outElements = dims.arrayElementCount; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outElements, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outElements, uint32_t* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outElements = dims.arrayElementCount; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outElements = dims.arrayElementCount; + *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(float& outWidth, float& outElements) + void GetDimensions(float* outWidth, float* outElements) { auto dims = texture->GetDimensions(); - outWidth = dims.width; - outElements = dims.arrayElementCount; + *outWidth = dims.width; + *outElements = dims.arrayElementCount; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outElements, float& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outElements, float* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outElements = dims.arrayElementCount; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outElements = dims.arrayElementCount; + *outNumberOfLevels = dims.numberOfLevels; } T Load(int2 loc) const { T out; texture->Load(&loc.x, &out); return out; } T& operator[](uint2 loc) { return *(T*)texture->refAt(&loc.x); } + IRWTexture* texture; }; template <typename T> struct RWTexture2DArray { - void GetDimensions(uint32_t& outWidth, uint32_t& outHeight, uint32_t& outElements) + void GetDimensions(uint32_t* outWidth, uint32_t* outHeight, uint32_t* outElements) { auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; } - void GetDimensions(uint32_t mipLevel, uint32_t& outWidth, uint32_t& outHeight, uint32_t& outElements, uint32_t& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, uint32_t* outWidth, uint32_t* outHeight, uint32_t* outElements, uint32_t* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; + *outNumberOfLevels = dims.numberOfLevels; } - void GetDimensions(float& outWidth, float& outHeight, float& outElements) + void GetDimensions(float* outWidth, float* outHeight, float* outElements) { auto dims = texture->GetDimensions(); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; } - void GetDimensions(uint32_t mipLevel, float& outWidth, float& outHeight, float& outElements, float& outNumberOfLevels) + void GetDimensions(uint32_t mipLevel, float* outWidth, float* outHeight, float* outElements, float* outNumberOfLevels) { const auto dims = texture->GetDimensions(mipLevel); - outWidth = dims.width; - outHeight = dims.height; - outElements = dims.arrayElementCount; - outNumberOfLevels = dims.numberOfLevels; + *outWidth = dims.width; + *outHeight = dims.height; + *outElements = dims.arrayElementCount; + *outNumberOfLevels = dims.numberOfLevels; } T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out); return out; } T& operator[](const uint3& loc) { return *(T*)texture->refAt(&loc.x); } + IRWTexture* texture; }; diff --git a/prelude/slang-cuda-prelude.h b/prelude/slang-cuda-prelude.h index eb676f03b..d0516b986 100644 --- a/prelude/slang-cuda-prelude.h +++ b/prelude/slang-cuda-prelude.h @@ -140,7 +140,7 @@ SLANG_CUDA_CALL float F32_floor(float f) { return ::floorf(f); } SLANG_CUDA_CALL float F32_round(float f) { return ::roundf(f); } SLANG_CUDA_CALL float F32_sin(float f) { return ::sinf(f); } SLANG_CUDA_CALL float F32_cos(float f) { return ::cosf(f); } -SLANG_CUDA_CALL void F32_sincos(float f, float& s, float& c) { ::sincosf(f, &s, &c); } +SLANG_CUDA_CALL void F32_sincos(float f, float* s, float* c) { ::sincosf(f, s, c); } SLANG_CUDA_CALL float F32_tan(float f) { return ::tanf(f); } SLANG_CUDA_CALL float F32_asin(float f) { return ::asinf(f); } SLANG_CUDA_CALL float F32_acos(float f) { return ::acosf(f); } @@ -172,16 +172,16 @@ SLANG_CUDA_CALL float F32_fmod(float a, float b) { return ::fmodf(a, b); } SLANG_CUDA_CALL float F32_remainder(float a, float b) { return ::remainderf(a, b); } SLANG_CUDA_CALL float F32_atan2(float a, float b) { return float(::atan2(a, b)); } -SLANG_CUDA_CALL float F32_frexp(float x, float& e) +SLANG_CUDA_CALL float F32_frexp(float x, float* e) { int ei; float m = ::frexpf(x, &ei); - e = ei; + *e = ei; return m; } -SLANG_CUDA_CALL float F32_modf(float x, float& ip) +SLANG_CUDA_CALL float F32_modf(float x, float* ip) { - return ::modff(x, &ip); + return ::modff(x, ip); } SLANG_CUDA_CALL uint32_t F32_asuint(float f) { Union32 u; u.f = f; return u.u; } @@ -199,7 +199,7 @@ SLANG_CUDA_CALL double F64_floor(double f) { return ::floor(f); } SLANG_CUDA_CALL double F64_round(double f) { return ::round(f); } SLANG_CUDA_CALL double F64_sin(double f) { return ::sin(f); } SLANG_CUDA_CALL double F64_cos(double f) { return ::cos(f); } -SLANG_CUDA_CALL void F64_sincos(double f, double& s, double& c) { ::sincos(f, &s, &c); } +SLANG_CUDA_CALL void F64_sincos(double f, double* s, double* c) { ::sincos(f, s, c); } SLANG_CUDA_CALL double F64_tan(double f) { return ::tan(f); } SLANG_CUDA_CALL double F64_asin(double f) { return ::asin(f); } SLANG_CUDA_CALL double F64_acos(double f) { return ::acos(f); } @@ -231,32 +231,32 @@ SLANG_CUDA_CALL double F64_fmod(double a, double b) { return ::fmod(a, b); } SLANG_CUDA_CALL double F64_remainder(double a, double b) { return ::remainder(a, b); } SLANG_CUDA_CALL double F64_atan2(double a, double b) { return ::atan2(a, b); } -SLANG_CUDA_CALL double F64_frexp(double x, double& e) +SLANG_CUDA_CALL double F64_frexp(double x, double* e) { int ei; double m = ::frexp(x, &ei); - e = ei; + *e = ei; return m; } -SLANG_CUDA_CALL double F64_modf(double x, double& ip) +SLANG_CUDA_CALL double F64_modf(double x, double* ip) { - return ::modf(x, &ip); + return ::modf(x, ip); } -SLANG_CUDA_CALL void F64_asuint(double d, uint32_t& low, uint32_t& hi) +SLANG_CUDA_CALL void F64_asuint(double d, uint32_t* low, uint32_t* hi) { Union64 u; u.d = d; - low = uint32_t(u.u); - hi = uint32_t(u.u >> 32); + *low = uint32_t(u.u); + *hi = uint32_t(u.u >> 32); } -SLANG_CUDA_CALL void F64_asint(double d, int32_t& low, int32_t& hi) +SLANG_CUDA_CALL void F64_asint(double d, int32_t* low, int32_t* hi) { Union64 u; u.d = d; - low = int32_t(u.u); - hi = int32_t(u.u >> 32); + *low = int32_t(u.u); + *hi = int32_t(u.u >> 32); } // Ternary @@ -338,7 +338,7 @@ struct RWStructuredBuffer { SLANG_CUDA_CALL T& operator[](size_t index) const { SLANG_CUDA_BOUND_CHECK(index, count); return data[index]; } SLANG_CUDA_CALL const T& Load(size_t index) const { SLANG_CUDA_BOUND_CHECK(index, count); return data[index]; } - SLANG_CUDA_CALL void GetDimensions(uint32_t& outNumStructs, uint32_t& outStride) { outNumStructs = uint32_t(count); outStride = uint32_t(sizeof(T)); } + SLANG_CUDA_CALL void GetDimensions(uint32_t* outNumStructs, uint32_t* outStride) { *outNumStructs = uint32_t(count); *outStride = uint32_t(sizeof(T)); } T* data; size_t count; @@ -349,7 +349,7 @@ struct StructuredBuffer { SLANG_CUDA_CALL const T& operator[](size_t index) const { SLANG_CUDA_BOUND_CHECK(index, count); return data[index]; } SLANG_CUDA_CALL const T& Load(size_t index) const { SLANG_CUDA_BOUND_CHECK(index, count); return data[index]; } - SLANG_CUDA_CALL void GetDimensions(uint32_t& outNumStructs, uint32_t& outStride) { outNumStructs = uint32_t(count); outStride = uint32_t(sizeof(T)); } + SLANG_CUDA_CALL void GetDimensions(uint32_t* outNumStructs, uint32_t* outStride) { *outNumStructs = uint32_t(count); *outStride = uint32_t(sizeof(T)); } T* data; size_t count; @@ -359,7 +359,7 @@ struct StructuredBuffer // Missing Load(_In_ int Location, _Out_ uint Status); struct ByteAddressBuffer { - SLANG_CUDA_CALL void GetDimensions(uint32_t& outDim) const { outDim = uint32_t(sizeInBytes); } + SLANG_CUDA_CALL void GetDimensions(uint32_t* outDim) const { *outDim = uint32_t(sizeInBytes); } SLANG_CUDA_CALL uint32_t Load(size_t index) const { SLANG_CUDA_BYTE_ADDRESS_BOUND_CHECK(index, 4, sizeInBytes); @@ -399,7 +399,7 @@ struct ByteAddressBuffer // Missing support for Load with status struct RWByteAddressBuffer { - SLANG_CUDA_CALL void GetDimensions(uint32_t& outDim) const { outDim = uint32_t(sizeInBytes); } + SLANG_CUDA_CALL void GetDimensions(uint32_t* outDim) const { *outDim = uint32_t(sizeInBytes); } SLANG_CUDA_CALL uint32_t Load(size_t index) const { diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index d8e6cfce3..8a7c3a010 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -1427,123 +1427,123 @@ void GroupMemoryBarrierWithGroupSync(); // Atomics __target_intrinsic(glsl, "$atomicAdd($A, $1)") -__target_intrinsic(cuda, "atomicAdd(&$0, $1)") +__target_intrinsic(cuda, "atomicAdd($0, $1)") void InterlockedAdd(__ref int dest, int value); __target_intrinsic(glsl, "$atomicAdd($A, $1)") -__target_intrinsic(cuda, "atomicAdd((uint*)&$0, $1)") +__target_intrinsic(cuda, "atomicAdd((uint*)$0, $1)") void InterlockedAdd(__ref uint dest, uint value); __target_intrinsic(glsl, "($2 = $atomicAdd($A, $1))") -__target_intrinsic(cuda, "($2 = atomicAdd(&$0, $1))") +__target_intrinsic(cuda, "(*$2 = atomicAdd($0, $1))") void InterlockedAdd(__ref int dest, int value, out int original_value); __target_intrinsic(glsl, "($2 = $atomicAdd($A, $1))") -__target_intrinsic(cuda, "($2 = (uint)atomicAdd((uint*)&$0, $1))") +__target_intrinsic(cuda, "(*$2 = (uint)atomicAdd((uint*)$0, $1))") void InterlockedAdd(__ref uint dest, uint value, out uint original_value); __target_intrinsic(glsl, "$atomicAnd($A, $1)") -__target_intrinsic(cuda, "atomicAnd(&$0, $1)") +__target_intrinsic(cuda, "atomicAnd($0, $1)") void InterlockedAnd(__ref int dest, int value); __target_intrinsic(glsl, "$atomicAnd($A, $1)") -__target_intrinsic(cuda, "atomicAnd((int*)&$0, $1)") +__target_intrinsic(cuda, "atomicAnd((int*)$0, $1)") void InterlockedAnd(__ref uint dest, uint value); __target_intrinsic(glsl, "($2 = $atomicAnd($A, $1))") -__target_intrinsic(cuda, "($2 = atomicAnd(&$0, $1))") +__target_intrinsic(cuda, "(*$2 = atomicAnd($0, $1))") void InterlockedAnd(__ref int dest, int value, out int original_value); __target_intrinsic(glsl, "($2 = $atomicAnd($A, $1))") -__target_intrinsic(cuda, "($2 = atomicAnd((int*)&$0, $1))") +__target_intrinsic(cuda, "(*$2 = atomicAnd((int*)$0, $1))") void InterlockedAnd(__ref uint dest, uint value, out uint original_value); __target_intrinsic(glsl, "($3 = $atomicCompSwap($A, $1, $2))") -__target_intrinsic(cuda, "($3 = atomicCAS(&$0, $1, $2))") +__target_intrinsic(cuda, "(*$3 = atomicCAS($0, $1, $2))") void InterlockedCompareExchange(__ref int dest, int compare_value, int value, out int original_value); __target_intrinsic(glsl, "($3 = $atomicCompSwap($A, $1, $2))") -__target_intrinsic(cuda, "($3 = (uint)atomicCAS((int*)&$0, $1, $2))") +__target_intrinsic(cuda, "(*$3 = (uint)atomicCAS((int*)$0, $1, $2))") void InterlockedCompareExchange(__ref uint dest, uint compare_value, uint value, out uint original_value); __target_intrinsic(glsl, "$atomicCompSwap($A, $1, $2)") -__target_intrinsic(cuda, "atomicCAS(&$0, $1, $2)") +__target_intrinsic(cuda, "atomicCAS($0, $1, $2)") void InterlockedCompareStore(__ref int dest, int compare_value, int value); __target_intrinsic(glsl, "$atomicCompSwap($A, $1, $2)") -__target_intrinsic(cuda, "atomicCAS((int*)&$0, $1, $2)") +__target_intrinsic(cuda, "atomicCAS((int*)$0, $1, $2)") void InterlockedCompareStore(__ref uint dest, uint compare_value, uint value); __target_intrinsic(glsl, "($2 = $atomicExchange($A, $1))") -__target_intrinsic(cuda, "($2 = atomicExch(&$0, $1))") +__target_intrinsic(cuda, "(*$2 = atomicExch($0, $1))") void InterlockedExchange(__ref int dest, int value, out int original_value); __target_intrinsic(glsl, "($2 = $atomicExchange($A, $1))") -__target_intrinsic(cuda, "($2 = (uint)atomicExch((int*)&$0, $1))") +__target_intrinsic(cuda, "(*$2 = (uint)atomicExch((int*)$0, $1))") void InterlockedExchange(__ref uint dest, uint value, out uint original_value); __target_intrinsic(glsl, "$atomicMax($A, $1)") -__target_intrinsic(cuda, "atomicMax(&$0, $1)") +__target_intrinsic(cuda, "atomicMax($0, $1)") void InterlockedMax(__ref int dest, int value); __target_intrinsic(glsl, "$atomicMax($A, $1)") -__target_intrinsic(cuda, "atomicMax((int*)&$0, $1)") +__target_intrinsic(cuda, "atomicMax((int*)$0, $1)") void InterlockedMax(__ref uint dest, uint value); __target_intrinsic(glsl, "($2 = $atomicMax($A, $1))") -__target_intrinsic(cuda, "($2 = atomicMax(&$0, $1))") +__target_intrinsic(cuda, "(*$2 = atomicMax($0, $1))") void InterlockedMax(__ref int dest, int value, out int original_value); __target_intrinsic(glsl, "($2 = $atomicMax($A, $1))") -__target_intrinsic(cuda, "($2 = (uint)atomicMax((int*)&$0, $1))") +__target_intrinsic(cuda, "(*$2 = (uint)atomicMax((int*)$0, $1))") void InterlockedMax(__ref uint dest, uint value, out uint original_value); __target_intrinsic(glsl, "$atomicMin($A, $1)") -__target_intrinsic(cuda, "atomicMin(&$0, $1)") +__target_intrinsic(cuda, "atomicMin($0, $1)") void InterlockedMin(__ref int dest, int value); __target_intrinsic(glsl, "$atomicMin($A, $1)") -__target_intrinsic(cuda, "atomicMin((int*)&$0, $1)") +__target_intrinsic(cuda, "atomicMin((int*)$0, $1)") void InterlockedMin(__ref uint dest, uint value); __target_intrinsic(glsl, "($2 = $atomicMin($A, $1))") -__target_intrinsic(cuda, "($2 = atomicMin(&$0, $1))") +__target_intrinsic(cuda, "(*$2 = atomicMin($0, $1))") void InterlockedMin(__ref int dest, int value, out int original_value); __target_intrinsic(glsl, "($2 = $atomicMin($A, $1))") -__target_intrinsic(cuda, "($2 = (uint)atomicMin((int*)&$0, $1))") +__target_intrinsic(cuda, "(*$2 = (uint)atomicMin((int*)$0, $1))") void InterlockedMin(__ref uint dest, uint value, out uint original_value); __target_intrinsic(glsl, "$atomicOr($A, $1)") -__target_intrinsic(cuda, "atomicOr(&$0, $1)") +__target_intrinsic(cuda, "atomicOr($0, $1)") void InterlockedOr(__ref int dest, int value); __target_intrinsic(glsl, "$atomicOr($A, $1)") -__target_intrinsic(cuda, "atomicOr((int*)&$0, $1)") +__target_intrinsic(cuda, "atomicOr((int*)$0, $1)") void InterlockedOr(__ref uint dest, uint value); __target_intrinsic(glsl, "($2 = $atomicOr($A, $1))") -__target_intrinsic(cuda, "($2 = atomicOr(&$0, $1))") +__target_intrinsic(cuda, "(*$2 = atomicOr($0, $1))") void InterlockedOr(__ref int dest, int value, out int original_value); __target_intrinsic(glsl, "($2 = $atomicOr($A, $1))") -__target_intrinsic(cuda, "($2 = (uint)atomicOr((int*)&$0, $1))") +__target_intrinsic(cuda, "(*$2 = (uint)atomicOr((int*)$0, $1))") void InterlockedOr(__ref uint dest, uint value, out uint original_value); __target_intrinsic(glsl, "$atomicXor($A, $1)") -__target_intrinsic(cuda, "atomicXor(&$0, $1)") +__target_intrinsic(cuda, "atomicXor($0, $1)") void InterlockedXor(__ref int dest, int value); __target_intrinsic(glsl, "$atomicXor($A, $1)") -__target_intrinsic(cuda, "atomicXor((int*)&$0, $1)") +__target_intrinsic(cuda, "atomicXor((int*)$0, $1)") void InterlockedXor(__ref uint dest, uint value); __target_intrinsic(glsl, "($2 = $atomicXor($A, $1))") -__target_intrinsic(cuda, "($2 = atomicXor(&$0, $1))") +__target_intrinsic(cuda, "(*$2 = atomicXor($0, $1))") void InterlockedXor(__ref int dest, int value, out int original_value); __target_intrinsic(glsl, "($2 = $atomicXor($A, $1))") -__target_intrinsic(cuda, "($2 = (uint)atomicXor((int*)&$0, $1))") +__target_intrinsic(cuda, "(*$2 = (uint)atomicXor((int*)$0, $1))") void InterlockedXor(__ref uint dest, uint value, out uint original_value); // Is floating-point value finite? diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index b1a664ade..2f0b0b035 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -969,10 +969,11 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst) type = arrayType->getElementType(); } - // Don't allow temporaries of pointer types to be created. + // Don't allow temporaries of pointer types to be created, + // if target langauge doesn't support pointers. if(as<IRPtrTypeBase>(type)) { - return true; + return !doesTargetSupportPtrTypes(); } // First we check for uniform parameter groups, @@ -1161,6 +1162,50 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst) return true; } +void CLikeSourceEmitter::emitDereferenceOperand(IRInst* inst, EmitOpInfo const& outerPrec) +{ + if (doesTargetSupportPtrTypes()) + { + // If `inst` is a variable, dereferencing it is equivalent to just + // emit its name. i.e. *&var ==> var. + // We apply this peep hole optimization here to reduce the clutter of + // resulting code. + if (inst->op == kIROp_Var) + { + m_writer->emit(getName(inst)); + return; + } + + auto dereferencePrec = EmitOpInfo::get(EmitOp::Prefix); + EmitOpInfo newOuterPrec = outerPrec; + bool needClose = maybeEmitParens(newOuterPrec, dereferencePrec); + m_writer->emit("*"); + emitOperand(inst, rightSide(newOuterPrec, dereferencePrec)); + maybeCloseParens(needClose); + } + else + { + emitOperand(inst, outerPrec); + } +} + +void CLikeSourceEmitter::emitVarExpr(IRInst* inst, EmitOpInfo const& outerPrec) +{ + if (doesTargetSupportPtrTypes()) + { + auto prec = getInfo(EmitOp::Prefix); + auto newOuterPrec = outerPrec; + bool needClose = maybeEmitParens(newOuterPrec, prec); + m_writer->emit("&"); + m_writer->emit(getName(inst)); + maybeCloseParens(needClose); + } + else + { + m_writer->emit(getName(inst)); + } +} + void CLikeSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPrec) { if( shouldFoldInstIntoUseSites(inst) ) @@ -1171,7 +1216,10 @@ void CLikeSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerP switch(inst->op) { - case 0: // nothing yet + case kIROp_Var: + case kIROp_GlobalVar: + emitVarExpr(inst, outerPrec); + break; default: m_writer->emit(getName(inst)); break; @@ -2019,18 +2067,35 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO IRFieldAddress* ii = (IRFieldAddress*) inst; - auto prec = getInfo(EmitOp::Postfix); - needClose = maybeEmitParens(outerPrec, prec); - - auto base = ii->getBase(); - emitOperand(base, leftSide(outerPrec, prec)); - m_writer->emit("."); - if(getSourceLanguage() == SourceLanguage::GLSL - && as<IRUniformParameterGroupType>(base->getDataType())) + if (doesTargetSupportPtrTypes()) { - m_writer->emit("_data."); + auto prec = getInfo(EmitOp::Prefix); + needClose = maybeEmitParens(outerPrec, prec); + m_writer->emit("&"); + outerPrec = rightSide(outerPrec, prec); + auto innerPrec = getInfo(EmitOp::Postfix); + bool innerNeedClose = maybeEmitParens(outerPrec, innerPrec); + auto base = ii->getBase(); + emitOperand(base, leftSide(outerPrec, innerPrec)); + m_writer->emit("->"); + m_writer->emit(getName(ii->getField())); + maybeCloseParens(innerNeedClose); + } + else + { + auto prec = getInfo(EmitOp::Postfix); + needClose = maybeEmitParens(outerPrec, prec); + + auto base = ii->getBase(); + emitOperand(base, leftSide(outerPrec, prec)); + m_writer->emit("."); + if(getSourceLanguage() == SourceLanguage::GLSL + && as<IRUniformParameterGroupType>(base->getDataType())) + { + m_writer->emit("_data."); + } + m_writer->emit(getName(ii->getField())); } - m_writer->emit(getName(ii->getField())); break; } @@ -2121,7 +2186,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO case kIROp_Load: { auto base = inst->getOperand(0); - emitOperand(base, outerPrec); + emitDereferenceOperand(base, outerPrec); if(getSourceLanguage() == SourceLanguage::GLSL && as<IRUniformParameterGroupType>(base->getDataType())) { @@ -2135,7 +2200,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO auto prec = getInfo(EmitOp::Assign); needClose = maybeEmitParens(outerPrec, prec); - emitOperand(inst->getOperand(0), leftSide(outerPrec, prec)); + emitDereferenceOperand(inst->getOperand(0), leftSide(outerPrec, prec)); m_writer->emit(" = "); emitOperand(inst->getOperand(1), rightSide(prec, outerPrec)); } @@ -2169,13 +2234,31 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO } else { - auto prec = getInfo(EmitOp::Postfix); - needClose = maybeEmitParens(outerPrec, prec); + if (inst->op == kIROp_getElementPtr && doesTargetSupportPtrTypes()) + { + const auto info = getInfo(EmitOp::Prefix); + needClose = maybeEmitParens(outerPrec, info); + m_writer->emit("&"); + auto rightSidePrec = rightSide(outerPrec, info); + auto postfixInfo = getInfo(EmitOp::Postfix); + bool rightSideNeedClose = maybeEmitParens(rightSidePrec, postfixInfo); + emitDereferenceOperand(inst->getOperand(0), leftSide(rightSidePrec, postfixInfo)); + m_writer->emit("["); + emitOperand(inst->getOperand(1), getInfo(EmitOp::General)); + m_writer->emit("]"); + maybeCloseParens(rightSideNeedClose); + break; + } + else + { + auto prec = getInfo(EmitOp::Postfix); + needClose = maybeEmitParens(outerPrec, prec); - emitOperand( inst->getOperand(0), leftSide(outerPrec, prec)); - m_writer->emit("["); - emitOperand(inst->getOperand(1), getInfo(EmitOp::General)); - m_writer->emit("]"); + emitOperand(inst->getOperand(0), leftSide(outerPrec, prec)); + m_writer->emit("["); + emitOperand(inst->getOperand(1), getInfo(EmitOp::General)); + m_writer->emit("]"); + } } break; @@ -2436,7 +2519,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst) auto ii = cast<IRSwizzledStore>(inst); - emitOperand(ii->getDest(), leftSide(subscriptOuter, subscriptPrec)); + emitDereferenceOperand(ii->getDest(), leftSide(subscriptOuter, subscriptPrec)); m_writer->emit("."); UInt elementCount = ii->getElementCount(); for (UInt ee = 0; ee < elementCount; ++ee) diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h index 453a8dbbf..c37a1514e 100644 --- a/source/slang/slang-emit-c-like.h +++ b/source/slang/slang-emit-c-like.h @@ -262,6 +262,7 @@ public: void emitParameterGroup(IRGlobalParam* varDecl, IRUniformParameterGroupType* type); void emitVar(IRVar* varDecl); + void emitDereferenceOperand(IRInst* inst, EmitOpInfo const& outerPrec); void emitGlobalVar(IRGlobalVar* varDecl); void emitGlobalParam(IRGlobalParam* varDecl); @@ -298,6 +299,7 @@ public: protected: + virtual bool doesTargetSupportPtrTypes() { return false; } virtual void emitLayoutSemanticsImpl(IRInst* inst, char const* uniformSemanticSpelling = "register") { SLANG_UNUSED(inst); SLANG_UNUSED(uniformSemanticSpelling); } virtual void emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type) = 0; virtual void emitEntryPointAttributesImpl(IRFunc* irFunc, IREntryPointDecoration* entryPointDecor) = 0; @@ -318,6 +320,7 @@ public: virtual void emitSimpleValueImpl(IRInst* inst); virtual void emitModuleImpl(IRModule* module); virtual void emitSimpleFuncImpl(IRFunc* func); + virtual void emitVarExpr(IRInst* inst, EmitOpInfo const& outerPrec); virtual void emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPrec); virtual void emitParamTypeImpl(IRType* type, String const& name); virtual void emitIntrinsicCallExprImpl(IRCall* inst, IRTargetIntrinsicDecoration* targetIntrinsic, EmitOpInfo const& inOuterPrec); diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 7f743d9e0..6b7fc46bf 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -398,10 +398,7 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S { auto ptrType = static_cast<IRPtrType*>(type); SLANG_RETURN_ON_FAIL(calcTypeName(ptrType->getValueType(), target, out)); - // TODO(JS): It seems although it says it is a pointer, it can actually be output as a reference - // not clear where the ptr aspect is there, as in the definition it is just 'out', implying out - // is somewhere converted to a ptr? - out << "&"; + out << "*"; return SLANG_OK; } case kIROp_RefType: @@ -577,14 +574,6 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S void CPPSourceEmitter::useType(IRType* type) { - if (type->op == kIROp_PtrType) - { - // TODO(JS): - // If it's a pointer type we ignore. We may want to strip but in practice it's - // probably not necessary. - return; - } - _getTypeName(type); } @@ -934,22 +923,26 @@ void CPPSourceEmitter::_emitGetAtDefinition(const UnownedStringSlice& funcName, IRType* srcType = funcType->getParamType(0); - for (Index i = 0; i < 2; ++i) + for (Index i = 0; i < 3; ++i) { UnownedStringSlice typePrefix = (i == 0) ? UnownedStringSlice::fromLiteral("const ") : UnownedStringSlice(); + bool lValue = (i != 2); emitFunctionPreambleImpl(nullptr); writer->emit(typePrefix); emitType(specOp->returnType); - m_writer->emit("& "); - + if (lValue) + m_writer->emit("*"); + writer->emit(" "); writer->emit(funcName); writer->emit("("); writer->emit(typePrefix); emitType(funcType->getParamType(0)); - writer->emit("& a, "); + if (lValue) + writer->emit("*"); + writer->emit(" a, "); emitType(funcType->getParamType(1)); writer->emit(" b)\n{\n"); @@ -962,8 +955,10 @@ void CPPSourceEmitter::_emitGetAtDefinition(const UnownedStringSlice& funcName, writer->emit("assert(b >= 0 && b < "); writer->emit(vecSize); writer->emit(");\n"); - - writer->emit("return (&a.x)[b];\n"); + if (lValue) + writer->emit("return (&a->x) + b;\n"); + else + writer->emit("return (&a.x)[b];\n"); } else if (auto matrixType = as<IRMatrixType>(srcType)) { @@ -974,7 +969,10 @@ void CPPSourceEmitter::_emitGetAtDefinition(const UnownedStringSlice& funcName, writer->emit(rowCount); writer->emit(");\n"); - writer->emit("return a.rows[b];\n"); + if (lValue) + writer->emit("return &(a->rows[b]);\n"); + else + writer->emit("return a.rows[b];\n"); } writer->dedent(); @@ -1566,7 +1564,7 @@ void CPPSourceEmitter::_emitInOutParamType(IRType* type, String const& name, IRT UnownedStringSlice slice = _getTypeName(valueType); m_writer->emit(slice); - m_writer->emit("& "); + m_writer->emit("* "); m_writer->emitName(nameAndLoc); } @@ -2095,21 +2093,39 @@ void CPPSourceEmitter::emitIntrinsicCallExprImpl( else { // The user is invoking a built-in subscript operator - auto prec = getInfo(EmitOp::Postfix); - needClose = maybeEmitParens(outerPrec, prec); - emitOperand(args[0].get(), leftSide(outerPrec, prec)); - m_writer->emit("["); - emitOperand(args[1].get(), getInfo(EmitOp::General)); - m_writer->emit("]"); + // Determine if we are calling the `ref` accessor: + // `ref` accessor returns a pointer of element type. + auto ptrType = as<IRPtrType>(inst->getFullType()); + auto resourceType = inst->getOperand(1)->getFullType(); + auto elementType = resourceType ? resourceType->getOperand(0) : nullptr; + bool isRef = ptrType && ptrType->getValueType() == elementType; + auto emitSubscript = [this, &args](EmitOpInfo _outerPrec) + { + auto prec = getInfo(EmitOp::Postfix); + bool needCloseSubscript = maybeEmitParens(_outerPrec, prec); + emitOperand(args[0].get(), leftSide(_outerPrec, prec)); + m_writer->emit("["); + emitOperand(args[1].get(), getInfo(EmitOp::General)); + m_writer->emit("]"); + maybeCloseParens(needCloseSubscript); + }; + + if (isRef) + { + auto prefixPrec = getInfo(EmitOp::Prefix); + needClose = maybeEmitParens(outerPrec, prefixPrec); + m_writer->emit("&"); + outerPrec = rightSide(outerPrec, prefixPrec); + } + emitSubscript(outerPrec); + maybeCloseParens(needClose); if (argCount == 3) { m_writer->emit(" = "); emitOperand(args[2].get(), getInfo(EmitOp::General)); } - - maybeCloseParens(needClose); } return; @@ -2358,19 +2374,6 @@ void CPPSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPre { // It's in UniformState m_writer->emit("("); - - switch (inst->getDataType()->op) - { - case kIROp_ParameterBlockType: - case kIROp_ConstantBufferType: - case kIROp_StructType: - { - m_writer->emit("*"); - break; - } - default: break; - } - m_writer->emit("uniformState->"); m_writer->emit(name); m_writer->emit(")"); @@ -2408,12 +2411,14 @@ void CPPSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPre } } } - - ; // Fall-thru + m_writer->emit(getName(inst)); + break; } + case kIROp_Var: case kIROp_GlobalVar: + emitVarExpr(inst, outerPrec); + break; default: - // GlobalVar should be fine as should just be a member of Context m_writer->emit(getName(inst)); break; } diff --git a/source/slang/slang-emit-cpp.h b/source/slang/slang-emit-cpp.h index 6f91444a3..c64b92b0f 100644 --- a/source/slang/slang-emit-cpp.h +++ b/source/slang/slang-emit-cpp.h @@ -63,6 +63,7 @@ public: protected: // Implement CLikeSourceEmitter interface + virtual bool doesTargetSupportPtrTypes() SLANG_OVERRIDE { return true; } virtual void emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type) SLANG_OVERRIDE; virtual void emitEntryPointAttributesImpl(IRFunc* irFunc, IREntryPointDecoration* entryPointDecor) SLANG_OVERRIDE; virtual void emitSimpleTypeImpl(IRType* type) SLANG_OVERRIDE; diff --git a/tests/compute/pointer-emit.slang b/tests/compute/pointer-emit.slang new file mode 100644 index 000000000..1c31103ae --- /dev/null +++ b/tests/compute/pointer-emit.slang @@ -0,0 +1,71 @@ +//TEST(compute):COMPARE_COMPUTE:-cpu +// Test emitting logic of pointer types. + + +struct Something +{ + int4 field0; + int field1; +}; + +struct ArrayType +{ + Something data[2]; +}; + +ArrayType getArray() +{ + ArrayType rs; + rs.data[0].field0 = int4(1,2,3,4); + rs.data[0].field1 = 1; + rs.data[1].field0 = int4(2,3,4,5); + rs.data[1].field1 = 2; + return rs; +} + +int inoutFunc(in out int param, + int[2] arrayParam, + out int[2] arrayOut, + Something s0, + out Something s1) +{ + int v = 1; + param = v + 1; + + arrayOut[0] = arrayParam[0]; + arrayOut[1] = arrayParam[1]; + + s1.field1 = s0.field1 + 1; + + return param; +} + +static int globalVar = 1; + +int test(int inVal) +{ + int p = inVal; + int t1[2] = {1, 2}; + int t2[2] = {0, 0}; + Something s, s_out; + s.field1 = -1; + s.field1 = s.field1 - 1; + s.field0[0] = 1; + int4 localVector = int4(1,2,3,4); + localVector.x = 2; + var array = getArray(); + return inoutFunc(p, t1, t2, s, s_out) + t2[0] + s_out.field1 + + s.field0[0] + localVector.x + array.data[1].field1 + globalVar; +} + +//TEST_INPUT:ubuffer(data=[0 1 2 3], stride=4):out,name=outputBuffer +RWStructuredBuffer<int> outputBuffer : register(u0); + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + int inVal = outputBuffer[tid]; + int outVal = test(inVal); + outputBuffer[tid] = outVal; +} diff --git a/tests/compute/pointer-emit.slang.expected.txt b/tests/compute/pointer-emit.slang.expected.txt new file mode 100644 index 000000000..e9eee2456 --- /dev/null +++ b/tests/compute/pointer-emit.slang.expected.txt @@ -0,0 +1,4 @@ +8 +8 +8 +8 |
