#ifndef SLANG_PRELUDE_CPP_TYPES_H #define SLANG_PRELUDE_CPP_TYPES_H #include "../slang.h" #ifndef SLANG_PRELUDE_ASSERT # ifdef _DEBUG # define SLANG_PRELUDE_ASSERT(VALUE) assert(VALUE) # else # define SLANG_PRELUDE_ASSERT(VALUE) # endif #endif #ifdef SLANG_PRELUDE_NAMESPACE namespace SLANG_PRELUDE_NAMESPACE { #endif template 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]; }; // An array that has no specified size, becomes a 'Array'. This stores the size so it can potentially // do bounds checking. template 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; }; /* Constant buffers become a pointer to the contained type, so ConstantBuffer becomes T* in C++ code. */ template struct Vector; template struct Vector { T x; }; template struct Vector { T x, y; }; template struct Vector { T x, y, z; }; template struct Vector { T x, y, z, w; }; typedef Vector float2; typedef Vector float3; typedef Vector float4; typedef Vector int2; typedef Vector int3; typedef Vector int4; typedef Vector uint2; typedef Vector uint3; typedef Vector uint4; template struct Matrix { Vector rows[ROWS]; }; // We can just map `NonUniformResourceIndex` type directly to the index type on CPU, as CPU does not require // any special handling around such accesses. typedef size_t NonUniformResourceIndex; // ----------------------------- ResourceType ----------------------------------------- // https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-structuredbuffer-getdimensions // Missing Load(_In_ int Location, _Out_ uint Status); template 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)); } T* data; size_t count; }; template 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)); } T* data; size_t count; }; template 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); } T* data; size_t count; }; template 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); } 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 { SLANG_PRELUDE_ASSERT(index + 4 <= sizeInBytes && (index & 3) == 0); return data[index >> 2]; } uint2 Load2(size_t index) const { SLANG_PRELUDE_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 { SLANG_PRELUDE_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 { SLANG_PRELUDE_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]}; } template T Load(size_t offset) const { SLANG_PRELUDE_ASSERT(offset + sizeof(T) <= sizeInBytes && (offset & (alignof(T)-1)) == 0); return *(T const*)((char*)data + offset); } 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 { SLANG_PRELUDE_ASSERT(index + 4 <= sizeInBytes && (index & 3) == 0); return data[index >> 2]; } uint2 Load2(size_t index) const { SLANG_PRELUDE_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 { SLANG_PRELUDE_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 { SLANG_PRELUDE_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]}; } template T Load(size_t offset) const { SLANG_PRELUDE_ASSERT(offset + sizeof(T) <= sizeInBytes && (offset & (alignof(T)-1)) == 0); return *(T const*)((char*)data + offset); } void Store(size_t index, uint32_t v) const { SLANG_PRELUDE_ASSERT(index + 4 <= sizeInBytes && (index & 3) == 0); data[index >> 2] = v; } void Store2(size_t index, uint2 v) const { SLANG_PRELUDE_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 { SLANG_PRELUDE_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 { SLANG_PRELUDE_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; } template void Store(size_t offset, T const& value) const { SLANG_PRELUDE_ASSERT(offset + sizeof(T) <= sizeInBytes && (offset & (alignof(T)-1)) == 0); *(T*)((char*)data + offset) = value; } uint32_t* data; size_t sizeInBytes; //< Must be multiple of 4 }; struct ISamplerState; struct ISamplerComparisonState; struct SamplerState { ISamplerState* state; }; struct SamplerComparisonState { ISamplerComparisonState* state; }; // struct TextureDimensions { void reset() { shape = 0; width = height = depth = 0; numberOfLevels = 0; arrayElementCount = 0; } int getDimSizes(uint32_t outDims[4]) const { const auto baseShape = (shape & SLANG_RESOURCE_BASE_SHAPE_MASK); int count = 0; switch (baseShape) { case SLANG_TEXTURE_1D: { outDims[count++] = width; break; } case SLANG_TEXTURE_2D: { outDims[count++] = width; outDims[count++] = height; break; } case SLANG_TEXTURE_3D: { outDims[count++] = width; outDims[count++] = height; outDims[count++] = depth; break; } case SLANG_TEXTURE_CUBE: { outDims[count++] = width; outDims[count++] = height; outDims[count++] = 6; break; } } if (shape & SLANG_TEXTURE_ARRAY_FLAG) { outDims[count++] = arrayElementCount; } return count; } int getMIPDims(int outDims[3]) const { const auto baseShape = (shape & SLANG_RESOURCE_BASE_SHAPE_MASK); int count = 0; switch (baseShape) { case SLANG_TEXTURE_1D: { outDims[count++] = width; break; } case SLANG_TEXTURE_CUBE: case SLANG_TEXTURE_2D: { outDims[count++] = width; outDims[count++] = height; break; } case SLANG_TEXTURE_3D: { outDims[count++] = width; outDims[count++] = height; outDims[count++] = depth; break; } } return count; } int calcMaxMIPLevels() const { int dims[3]; const int dimCount = getMIPDims(dims); for (int count = 1; true; count++) { bool allOne = true; for (int i = 0; i < dimCount; ++i) { if (dims[i] > 1) { allOne = false; dims[i] >>= 1; } } if (allOne) { return count; } } } SlangResourceShape shape; uint32_t width, height, depth; uint32_t numberOfLevels; uint32_t arrayElementCount; ///< For array types, 0 otherwise }; // Texture struct ITexture { virtual TextureDimensions GetDimensions(int mipLevel = -1) = 0; virtual void Load(const int* v, void* out) = 0; virtual void Sample(SamplerState samplerState, const float* loc, void* out) = 0; virtual void SampleLevel(SamplerState samplerState, const float* loc, float level, void* out) = 0; }; template struct Texture1D { 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; } T Load(const int2& loc) const { T out; texture->Load(&loc.x, &out); return out; } T Sample(SamplerState samplerState, float loc) const { T out; texture->Sample(samplerState, &loc, &out); return out; } T SampleLevel(SamplerState samplerState, float loc, float level) { T out; texture->SampleLevel(samplerState, &loc, level, &out); return out; } ITexture* texture; }; template struct Texture2D { void GetDimensions(uint32_t& outWidth, uint32_t& outHeight) { const auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; } 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; } void GetDimensions(float& outWidth, float& outHeight) { const auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; } 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; } T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out); return out; } T Sample(SamplerState samplerState, const float2& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } T SampleLevel(SamplerState samplerState, const float2& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } ITexture* texture; }; template struct Texture3D { 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; } 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; } void GetDimensions(float& outWidth, float& outHeight, float& outDepth) { const auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; outDepth = dims.depth; } 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; } T Load(const int4& loc) const { T out; texture->Load(&loc.x, &out); return out; } T Sample(SamplerState samplerState, const float3& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } T SampleLevel(SamplerState samplerState, const float3& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } ITexture* texture; }; template struct TextureCube { void GetDimensions(uint32_t& outWidth, uint32_t& outHeight) { const auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; } 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; } void GetDimensions(float& outWidth, float& outHeight) { const auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; } 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; } T Sample(SamplerState samplerState, const float3& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } T SampleLevel(SamplerState samplerState, const float3& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } ITexture* texture; }; template 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) { auto dims = texture->GetDimensions(mipLevel); 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) { auto dims = texture->GetDimensions(mipLevel); outWidth = dims.width; outNumberOfLevels = dims.numberOfLevels; outElements = dims.arrayElementCount; } T Load(const int3& loc) const { T out; texture->Load(&loc.x, &out); return out; } T Sample(SamplerState samplerState, const float2& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } T SampleLevel(SamplerState samplerState, const float2& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } ITexture* texture; }; template struct Texture2DArray { void GetDimensions(uint32_t& outWidth, uint32_t& outHeight, uint32_t& outElements) { auto dims = texture->GetDimensions(); 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) { auto dims = texture->GetDimensions(mipLevel); outWidth = dims.width; outHeight = dims.height; outElements = dims.arrayElementCount; outNumberOfLevels = dims.numberOfLevels; } void GetDimensions(uint32_t& outWidth, float& outHeight, float& outElements) { auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; outElements = dims.arrayElementCount; } 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; } T Load(const int4& loc) const { T out; texture->Load(&loc.x, &out); return out; } T Sample(SamplerState samplerState, const float3& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } T SampleLevel(SamplerState samplerState, const float3& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } ITexture* texture; }; template struct TextureCubeArray { void GetDimensions(uint32_t& outWidth, uint32_t& outHeight, uint32_t& outElements) { auto dims = texture->GetDimensions(); 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) { auto dims = texture->GetDimensions(mipLevel); outWidth = dims.width; outHeight = dims.height; outElements = dims.arrayElementCount; outNumberOfLevels = dims.numberOfLevels; } void GetDimensions(uint32_t& outWidth, float& outHeight, float& outElements) { auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; outElements = dims.arrayElementCount; } 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; } T Sample(SamplerState samplerState, const float4& loc) const { T out; texture->Sample(samplerState, &loc.x, &out); return out; } T SampleLevel(SamplerState samplerState, const float4& loc, float level) { T out; texture->SampleLevel(samplerState, &loc.x, level, &out); return out; } ITexture* texture; }; /* !!!!!!!!!!!!!!!!!!!!!!!!!!! RWTexture !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ struct IRWTexture { virtual TextureDimensions GetDimensions(int mipLevel = -1) = 0; /// Load at specified location. virtual void Load(const int32_t* loc, void* out) = 0; /// Get the reference to the element at loc. virtual void* refAt(const uint32_t* loc) = 0; }; template 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(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); } IRWTexture* texture; }; template struct RWTexture2D { void GetDimensions(uint32_t& outWidth, uint32_t& outHeight) { const auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; } 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; } void GetDimensions(float& outWidth, float& outHeight) { const auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; } 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; } T Load(const int2& loc) const { T out; texture->Load(&loc.x, &out); return out; } T& operator[](const uint2& loc) { return *(T*)texture->refAt(&loc.x); } IRWTexture* texture; }; template struct RWTexture3D { 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; } 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; } void GetDimensions(float& outWidth, float& outHeight, float& outDepth) { const auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; outDepth = dims.depth; } 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; } 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; }; template struct RWTexture1DArray { 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) { const auto dims = texture->GetDimensions(mipLevel); outWidth = dims.width; outElements = dims.arrayElementCount; outNumberOfLevels = dims.numberOfLevels; } 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) { const auto dims = texture->GetDimensions(mipLevel); 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 struct RWTexture2DArray { void GetDimensions(uint32_t& outWidth, uint32_t& outHeight, uint32_t& outElements) { auto dims = texture->GetDimensions(); 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) { const auto dims = texture->GetDimensions(mipLevel); outWidth = dims.width; outHeight = dims.height; outElements = dims.arrayElementCount; outNumberOfLevels = dims.numberOfLevels; } void GetDimensions(float& outWidth, float& outHeight, float& outElements) { auto dims = texture->GetDimensions(); outWidth = dims.width; outHeight = dims.height; outElements = dims.arrayElementCount; } 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; } 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; }; /* Varying input for Compute */ /* Used when running a single thread */ struct ComputeThreadVaryingInput { uint3 groupID; uint3 groupThreadID; }; struct ComputeVaryingInput { uint3 startGroupID; ///< start groupID uint3 endGroupID; ///< Non inclusive end groupID }; /* Type that defines the uniform entry point params. The actual content of this type is dependent on the entry point parameters, and can be found via reflection or defined such that it matches the shader appropriately. */ struct UniformEntryPointParams; struct UniformState; typedef void(*ComputeThreadFunc)(ComputeThreadVaryingInput* varyingInput, UniformEntryPointParams* uniformEntryPointParams, UniformState* uniformState); typedef void(*ComputeFunc)(ComputeVaryingInput* varyingInput, UniformEntryPointParams* uniformEntryPointParams, UniformState* uniformState); #ifdef SLANG_PRELUDE_NAMESPACE } #endif #endif