#ifndef SLANG_PRELUDE_CPP_TYPES_H #define SLANG_PRELUDE_CPP_TYPES_H #include "../slang.h" #ifdef SLANG_PRELUDE_NAMESPACE namespace SLANG_PRELUDE_NAMESPACE { #endif template struct FixedArray { const T& operator[](size_t index) const { assert(index < SIZE); return m_data[index]; } T& operator[](size_t index) { assert(index < SIZE); return m_data[index]; } T m_data[SIZE]; }; // Hmm... I guess a constant buffer should be unwrapped to be just a struct passed in /* template struct ConstantBuffer { }; */ 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]; }; // ----------------------------- 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 { 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 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 struct Texture2D { T Load(const int3& v) const { T out; texture->Load(v, &out); return out; } T Sample(SamplerState samplerState, const float2& v) const { T out; texture->Sample(samplerState, v, &out); return out; } ITexture2D* texture; }; /* Varying input for Compute */ struct ComputeVaryingInput { uint3 groupID; uint3 groupThreadID; }; #ifdef SLANG_PRELUDE_NAMESPACE } #endif #endif