diff options
| -rw-r--r-- | docs/cuda-target.md | 2 | ||||
| -rw-r--r-- | prelude/slang-cpp-types.h | 414 | ||||
| -rw-r--r-- | source/slang/core.meta.slang | 7 | ||||
| -rw-r--r-- | tests/compute/texture-get-dimensions.slang | 106 | ||||
| -rw-r--r-- | tests/compute/texture-get-dimensions.slang.expected.txt | 8 | ||||
| -rw-r--r-- | tests/diagnostics/bad-operator-call.slang.expected | 76 | ||||
| -rw-r--r-- | tools/render-test/cpu-compute-util.cpp | 103 |
7 files changed, 650 insertions, 66 deletions
diff --git a/docs/cuda-target.md b/docs/cuda-target.md index f79bf14c3..c41858bd4 100644 --- a/docs/cuda-target.md +++ b/docs/cuda-target.md @@ -219,6 +219,8 @@ Some features are not available because they cannot be mapped with appropriate b * Not all Wave intrinsics are supported * There is not complete support for all methods on 'objects' like textures etc. * Does not currently support combined 'TextureSampler'. A Texture behaves equivalently to a TextureSampler and Samplers are ignored. +* Half type is not currently supported +* GetDimensions is not available on any Texture type currently - as there doesn't appear to be a CUDA equivalent Language aspects ================ diff --git a/prelude/slang-cpp-types.h b/prelude/slang-cpp-types.h index c7421bc0b..415d7f941 100644 --- a/prelude/slang-cpp-types.h +++ b/prelude/slang-cpp-types.h @@ -226,10 +226,116 @@ 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; @@ -238,6 +344,22 @@ 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) + { + 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; } @@ -248,6 +370,33 @@ struct Texture1D template <typename T> 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; } @@ -258,6 +407,37 @@ struct Texture2D template <typename T> 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; } @@ -268,6 +448,33 @@ struct Texture3D template <typename T> 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; } @@ -277,6 +484,23 @@ 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) + { + 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; } @@ -287,6 +511,38 @@ struct Texture1DArray template <typename T> 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; } @@ -297,6 +553,38 @@ struct Texture2DArray template <typename T> 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; } @@ -307,6 +595,8 @@ struct TextureCubeArray 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. @@ -316,6 +606,12 @@ 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(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; @@ -324,6 +620,33 @@ struct RWTexture1D template <typename T> 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; @@ -332,14 +655,73 @@ struct RWTexture2D template <typename T> 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 <typename T> 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; @@ -348,12 +730,42 @@ struct RWTexture1DArray template <typename T> 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 */ diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 6c1163adc..2b43206a3 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -707,7 +707,12 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) switch(baseShape) { case TextureFlavor::Shape::Shape1D: - sb << "($" << aa++ << opStr << "))"; + sb << "($" << aa++ << opStr << ")"; + if (isArray) + { + sb << ".x"; + } + sb << ")"; cc = 1; break; diff --git a/tests/compute/texture-get-dimensions.slang b/tests/compute/texture-get-dimensions.slang new file mode 100644 index 000000000..67c1fddc8 --- /dev/null +++ b/tests/compute/texture-get-dimensions.slang @@ -0,0 +1,106 @@ +//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -profile cs_6_0 -use-dxil +// TODO(JS): Doesn't work on vk currently, because createTextureView not implemented on vk renderer +//DISABLE_TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute +// TODO(JS): Doesn't work on CUDA as there aren't any CUDA functions to get dimensions. +//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute + +//TEST_INPUT: Texture1D(size=4, content = one):name t1D +Texture1D<float> t1D; +//TEST_INPUT: Texture2D(size=8, content = one):name t2D +Texture2D<float> t2D; +//TEST_INPUT: Texture3D(size=2, content = one):name t3D +Texture3D<float> t3D; +//TEST_INPUT: TextureCube(size=16, content = one):name tCube +TextureCube<float> tCube; + +//TEST_INPUT: Texture1D(size=2, content = one, arrayLength=2):name t1DArray +Texture1DArray<float> t1DArray; +//TEST_INPUT: Texture2D(size=4, content = one, arrayLength=3):name t2DArray +Texture2DArray<float> t2DArray; +//TEST_INPUT: TextureCube(size=16, content = one, arrayLength=1):name tCubeArray +TextureCubeArray<float> tCubeArray; + +//TEST_INPUT: Sampler:name samplerState +SamplerState samplerState; + +//TEST_INPUT: ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):out,name outputBuffer +RWStructuredBuffer<float> outputBuffer; + +[numthreads(8, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + int idx = dispatchThreadID.x; + + uint mipWidth = 0; + uint mipHeight = 0; + uint mipDepth = 0; + uint mipCount = 1; + uint elementCount = 0; + + uint width = 0; + uint height = 0; + uint depth = 0; + + switch (idx) + { + case 0: + { + t1D.GetDimensions(width); + t1D.GetDimensions(0, mipWidth, mipCount); + break; + } + case 1: + { + t2D.GetDimensions(width, height); + t2D.GetDimensions(0, mipWidth, mipHeight, mipCount); + break; + } + case 2: + { + t3D.GetDimensions(width, height, depth); + t3D.GetDimensions(0, mipWidth, mipHeight, mipDepth, mipCount); + break; + } + case 3: + { + tCube.GetDimensions(width, height); + tCube.GetDimensions(0, mipWidth, mipHeight, mipCount); + break; + } + case 4: + { + t1DArray.GetDimensions(width, elementCount); + t1DArray.GetDimensions(0, mipWidth, elementCount, mipCount); + break; + } + case 5: + { + t2DArray.GetDimensions(width, height, elementCount); + t2DArray.GetDimensions(0, mipWidth, mipHeight, elementCount, mipCount); + break; + } + case 6: + { + tCubeArray.GetDimensions(width, height, elementCount); + tCubeArray.GetDimensions(0, mipWidth, mipHeight, elementCount, mipCount); + break; + } + } + + width = (mipWidth != width) ? ~0 : width; + height = (mipHeight != height) ? ~0 : height; + depth = (mipDepth != depth) ? ~0 : depth; + + // Only depth or element count can be set + if (depth == 0 && elementCount > 0) + { + depth = elementCount; + } + + uint val = ((0xff & width) << 24) | ((0xff & height) << 16) | ((0xff & depth) << 8) | (mipCount); + + outputBuffer[idx] = val; +} diff --git a/tests/compute/texture-get-dimensions.slang.expected.txt b/tests/compute/texture-get-dimensions.slang.expected.txt new file mode 100644 index 000000000..3b060b4ae --- /dev/null +++ b/tests/compute/texture-get-dimensions.slang.expected.txt @@ -0,0 +1,8 @@ +4C800000 +4D008000 +4C008080 +4D808000 +4C000080 +4C808060 +4D808008 +3F800000 diff --git a/tests/diagnostics/bad-operator-call.slang.expected b/tests/diagnostics/bad-operator-call.slang.expected index f41fdf7c0..fd85fdbfc 100644 --- a/tests/diagnostics/bad-operator-call.slang.expected +++ b/tests/diagnostics/bad-operator-call.slang.expected @@ -1,51 +1,51 @@ result code = -1 standard error = { tests/diagnostics/bad-operator-call.slang(17): error 39999: no overload for '+=' applicable to arguments of type (int, S) -core.meta.slang(1756): note 39999: candidate: func +=<T, R:int, C:int>(matrix<T,R,C>, T) -> matrix<T,R,C> -core.meta.slang(1748): note 39999: candidate: func +=<T, R:int, C:int>(matrix<T,R,C>, matrix<T,R,C>) -> matrix<T,R,C> -core.meta.slang(1740): note 39999: candidate: func +=<T, N:int>(vector<T,N>, T) -> vector<T,N> -core.meta.slang(1732): note 39999: candidate: func +=<T, N:int>(vector<T,N>, vector<T,N>) -> vector<T,N> -core.meta.slang(1724): note 39999: candidate: func +=<T>(T, T) -> T +core.meta.slang(1745): note 39999: candidate: func +=<T, R:int, C:int>(matrix<T,R,C>, T) -> matrix<T,R,C> +core.meta.slang(1737): note 39999: candidate: func +=<T, R:int, C:int>(matrix<T,R,C>, matrix<T,R,C>) -> matrix<T,R,C> +core.meta.slang(1729): note 39999: candidate: func +=<T, N:int>(vector<T,N>, T) -> vector<T,N> +core.meta.slang(1721): note 39999: candidate: func +=<T, N:int>(vector<T,N>, vector<T,N>) -> vector<T,N> +core.meta.slang(1713): note 39999: candidate: func +=<T>(T, T) -> T tests/diagnostics/bad-operator-call.slang(19): error 39999: no overload for '+' applicable to arguments of type (int, S) -core.meta.slang(1646): note 39999: candidate: func +(uint64_t, uint64_t) -> uint64_t -core.meta.slang(1639): note 39999: candidate: func +(uint, uint) -> uint -core.meta.slang(1632): note 39999: candidate: func +(uint16_t, uint16_t) -> uint16_t -core.meta.slang(1625): note 39999: candidate: func +(uint8_t, uint8_t) -> uint8_t -core.meta.slang(1618): note 39999: candidate: func +(double, double) -> double -core.meta.slang(1611): note 39999: candidate: func +(float, float) -> float -core.meta.slang(1604): note 39999: candidate: func +(half, half) -> half -core.meta.slang(1597): note 39999: candidate: func +(int64_t, int64_t) -> int64_t -core.meta.slang(1590): note 39999: candidate: func +(int, int) -> int -core.meta.slang(1583): note 39999: candidate: func +(int16_t, int16_t) -> int16_t +core.meta.slang(1635): note 39999: candidate: func +(uint64_t, uint64_t) -> uint64_t +core.meta.slang(1628): note 39999: candidate: func +(uint, uint) -> uint +core.meta.slang(1621): note 39999: candidate: func +(uint16_t, uint16_t) -> uint16_t +core.meta.slang(1614): note 39999: candidate: func +(uint8_t, uint8_t) -> uint8_t +core.meta.slang(1607): note 39999: candidate: func +(double, double) -> double +core.meta.slang(1600): note 39999: candidate: func +(float, float) -> float +core.meta.slang(1593): note 39999: candidate: func +(half, half) -> half +core.meta.slang(1586): note 39999: candidate: func +(int64_t, int64_t) -> int64_t +core.meta.slang(1579): note 39999: candidate: func +(int, int) -> int +core.meta.slang(1572): note 39999: candidate: func +(int16_t, int16_t) -> int16_t tests/diagnostics/bad-operator-call.slang(19): note 39999: 1 more overload candidates tests/diagnostics/bad-operator-call.slang(21): error 39999: no overload for '~' applicable to arguments of type (S) -slang-stdlib.cpp(1638): note 39999: candidate: func ~(uint64_t) -> uint64_t -slang-stdlib.cpp(1635): note 39999: candidate: func ~(uint) -> uint -slang-stdlib.cpp(1632): note 39999: candidate: func ~(uint16_t) -> uint16_t -slang-stdlib.cpp(1629): note 39999: candidate: func ~(uint8_t) -> uint8_t -slang-stdlib.cpp(1626): note 39999: candidate: func ~(int64_t) -> int64_t -slang-stdlib.cpp(1623): note 39999: candidate: func ~(int) -> int -slang-stdlib.cpp(1620): note 39999: candidate: func ~(int16_t) -> int16_t -slang-stdlib.cpp(1617): note 39999: candidate: func ~(int8_t) -> int8_t +slang-stdlib.cpp(1646): note 39999: candidate: func ~(uint64_t) -> uint64_t +slang-stdlib.cpp(1643): note 39999: candidate: func ~(uint) -> uint +slang-stdlib.cpp(1640): note 39999: candidate: func ~(uint16_t) -> uint16_t +slang-stdlib.cpp(1637): note 39999: candidate: func ~(uint8_t) -> uint8_t +slang-stdlib.cpp(1634): note 39999: candidate: func ~(int64_t) -> int64_t +slang-stdlib.cpp(1631): note 39999: candidate: func ~(int) -> int +slang-stdlib.cpp(1628): note 39999: candidate: func ~(int16_t) -> int16_t +slang-stdlib.cpp(1625): note 39999: candidate: func ~(int8_t) -> int8_t tests/diagnostics/bad-operator-call.slang(26): error 30047: argument passed to parameter '0' must be l-value. tests/diagnostics/bad-operator-call.slang(26): note 30048: argument was implicitly cast from 'int' to 'vector<int,4>', and Slang does not support using an implicit cast as an l-value tests/diagnostics/bad-operator-call.slang(30): error 39999: no overload for '+=' applicable to arguments of type (vector<float,3>, vector<int,4>) -core.meta.slang(1756): note 39999: candidate: func +=<T, R:int, C:int>(matrix<T,R,C>, T) -> matrix<T,R,C> -core.meta.slang(1748): note 39999: candidate: func +=<T, R:int, C:int>(matrix<T,R,C>, matrix<T,R,C>) -> matrix<T,R,C> -core.meta.slang(1740): note 39999: candidate: func +=<T, N:int>(vector<T,N>, T) -> vector<T,N> -core.meta.slang(1732): note 39999: candidate: func +=<T, N:int>(vector<T,N>, vector<T,N>) -> vector<T,N> -core.meta.slang(1724): note 39999: candidate: func +=<T>(T, T) -> T +core.meta.slang(1745): note 39999: candidate: func +=<T, R:int, C:int>(matrix<T,R,C>, T) -> matrix<T,R,C> +core.meta.slang(1737): note 39999: candidate: func +=<T, R:int, C:int>(matrix<T,R,C>, matrix<T,R,C>) -> matrix<T,R,C> +core.meta.slang(1729): note 39999: candidate: func +=<T, N:int>(vector<T,N>, T) -> vector<T,N> +core.meta.slang(1721): note 39999: candidate: func +=<T, N:int>(vector<T,N>, vector<T,N>) -> vector<T,N> +core.meta.slang(1713): note 39999: candidate: func +=<T>(T, T) -> T tests/diagnostics/bad-operator-call.slang(32): error 39999: no overload for '+' applicable to arguments of type (vector<int,4>, vector<float,3>) -core.meta.slang(1651): note 39999: candidate: func +<4>(vector<uint64_t,4>, uint64_t) -> vector<uint64_t,4> -core.meta.slang(1649): note 39999: candidate: func +<3>(uint64_t, vector<uint64_t,3>) -> vector<uint64_t,3> -core.meta.slang(1646): note 39999: candidate: func +(uint64_t, uint64_t) -> uint64_t -core.meta.slang(1644): note 39999: candidate: func +<4>(vector<uint,4>, uint) -> vector<uint,4> -core.meta.slang(1642): note 39999: candidate: func +<3>(uint, vector<uint,3>) -> vector<uint,3> -core.meta.slang(1639): note 39999: candidate: func +(uint, uint) -> uint -core.meta.slang(1637): note 39999: candidate: func +<4>(vector<uint16_t,4>, uint16_t) -> vector<uint16_t,4> -core.meta.slang(1635): note 39999: candidate: func +<3>(uint16_t, vector<uint16_t,3>) -> vector<uint16_t,3> -core.meta.slang(1632): note 39999: candidate: func +(uint16_t, uint16_t) -> uint16_t -core.meta.slang(1630): note 39999: candidate: func +<4>(vector<uint8_t,4>, uint8_t) -> vector<uint8_t,4> +core.meta.slang(1640): note 39999: candidate: func +<4>(vector<uint64_t,4>, uint64_t) -> vector<uint64_t,4> +core.meta.slang(1638): note 39999: candidate: func +<3>(uint64_t, vector<uint64_t,3>) -> vector<uint64_t,3> +core.meta.slang(1635): note 39999: candidate: func +(uint64_t, uint64_t) -> uint64_t +core.meta.slang(1633): note 39999: candidate: func +<4>(vector<uint,4>, uint) -> vector<uint,4> +core.meta.slang(1631): note 39999: candidate: func +<3>(uint, vector<uint,3>) -> vector<uint,3> +core.meta.slang(1628): note 39999: candidate: func +(uint, uint) -> uint +core.meta.slang(1626): note 39999: candidate: func +<4>(vector<uint16_t,4>, uint16_t) -> vector<uint16_t,4> +core.meta.slang(1624): note 39999: candidate: func +<3>(uint16_t, vector<uint16_t,3>) -> vector<uint16_t,3> +core.meta.slang(1621): note 39999: candidate: func +(uint16_t, uint16_t) -> uint16_t +core.meta.slang(1619): note 39999: candidate: func +<4>(vector<uint8_t,4>, uint8_t) -> vector<uint8_t,4> tests/diagnostics/bad-operator-call.slang(32): note 39999: 23 more overload candidates } standard output = { diff --git a/tools/render-test/cpu-compute-util.cpp b/tools/render-test/cpu-compute-util.cpp index ea3927621..2ea74052f 100644 --- a/tools/render-test/cpu-compute-util.cpp +++ b/tools/render-test/cpu-compute-util.cpp @@ -15,10 +15,41 @@ namespace renderer_test { using namespace Slang; +static void _fixMipSize(uint32_t& ioDim, int mipLevel) +{ + uint32_t dim = ioDim; + if (dim > 0) + { + dim >>= mipLevel; + dim = (dim == 0) ? 1 : dim; + ioDim = dim; + } +} + +CPPPrelude::TextureDimensions _calcMipDims(int mipLevel, const CPPPrelude::TextureDimensions& inDims) +{ + if (mipLevel > 0 && mipLevel < int(inDims.numberOfLevels)) + { + CPPPrelude::TextureDimensions dims(inDims); + _fixMipSize(dims.width, mipLevel); + _fixMipSize(dims.height, mipLevel); + _fixMipSize(dims.depth, mipLevel); + return dims; + } + else + { + return inDims; + } +} + template <int COUNT> struct ValueTexture : public CPUComputeUtil::Resource, public CPPPrelude::ITexture { // ITexture interface + virtual CPPPrelude::TextureDimensions GetDimensions(int mipLevel) SLANG_OVERRIDE + { + return _calcMipDims(mipLevel, m_dims); + } virtual void Load(const int32_t* loc, void* out) SLANG_OVERRIDE { _set(out); @@ -32,8 +63,9 @@ struct ValueTexture : public CPUComputeUtil::Resource, public CPPPrelude::ITextu _set(out); } - ValueTexture(float value) : - m_value(value) + ValueTexture(const CPPPrelude::TextureDimensions& dims, float value) : + m_value(value), + m_dims(dims) { m_interface = static_cast<CPPPrelude::ITexture*>(this); } @@ -48,6 +80,7 @@ struct ValueTexture : public CPUComputeUtil::Resource, public CPPPrelude::ITextu } float m_value; + CPPPrelude::TextureDimensions m_dims; }; class FloatTextureData @@ -162,27 +195,40 @@ public: struct FloatRWTexture : public CPUComputeUtil::Resource, public CPPPrelude::IRWTexture { // IRWTexture + virtual CPPPrelude::TextureDimensions GetDimensions(int mipLevel) SLANG_OVERRIDE + { + return _calcMipDims(mipLevel, m_dims); + } virtual void Load(const int32_t* loc, void* out) SLANG_OVERRIDE { m_data.getAt((const uint32_t*)loc, (float*)out); } virtual void* refAt(const uint32_t* loc) SLANG_OVERRIDE { return m_data.getAt(loc); } - FloatRWTexture(int elementCount, int dimsCount, const uint32_t* dims, float initialValue) + FloatRWTexture(int elementCount, const CPPPrelude::TextureDimensions& inDims, float initialValue): + m_dims(inDims) { - m_data.init(elementCount, dimsCount, dims); + uint32_t dimSizes[4]; + int dimSizesCount = inDims.getDimSizes(dimSizes); + + m_data.init(elementCount, dimSizesCount, dimSizes); m_data.setValue(initialValue); m_interface = static_cast<CPPPrelude::IRWTexture*>(this); } FloatTextureData m_data; + CPPPrelude::TextureDimensions m_dims; }; -static int _calcDims(const InputTextureDesc& desc, slang::TypeLayoutReflection* typeLayout, uint32_t outDims[4]) +static int _calcDims(const InputTextureDesc& desc, slang::TypeLayoutReflection* typeLayout, CPPPrelude::TextureDimensions& outDims) { + outDims.reset(); + const auto kind = typeLayout->getKind(); SLANG_ASSERT(kind == slang::TypeReflection::Kind::Resource); auto type = typeLayout->getType(); auto shape = type->getResourceShape(); + outDims.shape = shape; + const uint32_t size = uint32_t(desc.size); const auto baseShape = (shape & SLANG_RESOURCE_BASE_SHAPE_MASK); @@ -192,48 +238,52 @@ static int _calcDims(const InputTextureDesc& desc, slang::TypeLayoutReflection* { case SLANG_TEXTURE_1D: { - outDims[dimsCount++] = size; + outDims.width = size; break; } case SLANG_TEXTURE_2D: { - outDims[dimsCount++] = size; - outDims[dimsCount++] = size; + outDims.width = size; + outDims.height = size; break; } case SLANG_TEXTURE_3D: { - outDims[dimsCount++] = size; - outDims[dimsCount++] = size; - outDims[dimsCount++] = size; + outDims.width = size; + outDims.height = size; + outDims.depth = size; break; } case SLANG_TEXTURE_CUBE: { - outDims[dimsCount++] = size; - outDims[dimsCount++] = size; - outDims[dimsCount++] = 6; + outDims.width = size; + outDims.height = size; break; } } if (shape & SLANG_TEXTURE_ARRAY_FLAG) { - uint32_t arrayLength = uint32_t(desc.arrayLength); - outDims[dimsCount++] = arrayLength; + outDims.arrayElementCount = uint32_t(desc.arrayLength); } + int maxMipCount = outDims.calcMaxMIPLevels(); + SLANG_ASSERT(desc.mipMapCount <= maxMipCount); + + outDims.numberOfLevels = (desc.mipMapCount == 0) ? uint32_t(maxMipCount) : uint32_t(desc.mipMapCount); + return dimsCount; } -static CPUComputeUtil::Resource* _newReadTexture(int elemCount, SlangResourceShape shape, float initialValue) + +static CPUComputeUtil::Resource* _newReadTexture(int elemCount, const CPPPrelude::TextureDimensions& dims, float initialValue) { switch (elemCount) { - case 1: return new ValueTexture<1>(initialValue); - case 2: return new ValueTexture<2>(initialValue); - case 3: return new ValueTexture<3>(initialValue); - case 4: return new ValueTexture<4>(initialValue); + case 1: return new ValueTexture<1>(dims, initialValue); + case 2: return new ValueTexture<2>(dims, initialValue); + case 3: return new ValueTexture<3>(dims, initialValue); + case 4: return new ValueTexture<4>(dims, initialValue); default: break; } return nullptr; @@ -270,12 +320,13 @@ static SlangResult _newTexture(const InputTextureDesc& desc, slang::TypeLayoutRe default: break; } + CPPPrelude::TextureDimensions dims; + _calcDims(desc, typeLayout, dims); + // These need a different style of texture if can be written to if (access == SLANG_RESOURCE_ACCESS_READ_WRITE) { - uint32_t dims[4]; - const int dimsCount = _calcDims(desc, typeLayout, dims); - + switch (shape) { case SLANG_TEXTURE_1D: @@ -285,14 +336,14 @@ static SlangResult _newTexture(const InputTextureDesc& desc, slang::TypeLayoutRe case SLANG_TEXTURE_1D_ARRAY: case SLANG_TEXTURE_2D_ARRAY: { - outResource = new FloatRWTexture(elemCount, dimsCount, dims, initialValue); + outResource = new FloatRWTexture(elemCount, dims, initialValue); return SLANG_OK; } } } else { - outResource = _newReadTexture(elemCount, shape, initialValue); + outResource = _newReadTexture(elemCount, dims, initialValue); return outResource ? SLANG_OK : SLANG_FAIL; } |
