diff options
| -rw-r--r-- | docs/target-compatibility.md | 10 | ||||
| -rw-r--r-- | prelude/slang-cpp-types.h | 141 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang | 21 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang | 43 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang | 5 |
5 files changed, 220 insertions, 0 deletions
diff --git a/docs/target-compatibility.md b/docs/target-compatibility.md index 898a59fd3..e4c4a8496 100644 --- a/docs/target-compatibility.md +++ b/docs/target-compatibility.md @@ -39,6 +39,7 @@ Items with ^ means there is some discussion about support later in the document | `[unroll]` | Yes | Yes | Yes ^ | Yes | Limited + | Atomics | Yes | Yes | Yes | Yes | No + | Atomics on RWBuffer | Yes | Yes | Yes | No | No + +| Sampler Feedback | No | Yes | No + | No | Yes ^ ## Half Type @@ -169,3 +170,12 @@ For VK the GLSL output from Slang seems plausible, but VK binding fails in tests On CUDA RWBuffer becomes CUsurfObject, which is a 'texture' type and does not support atomics. On the CPU atomics are not supported, but will be in the future. + +## Sampler Feedback + +The HLSL [sampler feedback feature](https://microsoft.github.io/DirectX-Specs/d3d/SamplerFeedback.html) is available for DirectX12. The features requires shader model 6.5 and therefore a version of [DXC](https://github.com/Microsoft/DirectXShaderCompiler) that supports that model or higher. The Shader Model 6.5 requirement also means only DXIL binary format is supported. + +There doesn't not appear to be a similar feature available in Vulkan yet, but when it is available support should be addeed. + +For CPU targets there is the IFeedbackTexture interface that requires an implemention for use. Slang does not currently include CPU implementations for texture types. + diff --git a/prelude/slang-cpp-types.h b/prelude/slang-cpp-types.h index 42af9fe61..fd5a9a813 100644 --- a/prelude/slang-cpp-types.h +++ b/prelude/slang-cpp-types.h @@ -377,6 +377,10 @@ struct TextureDimensions uint32_t arrayElementCount; ///< For array types, 0 otherwise }; + + + + // Texture struct ITexture @@ -814,6 +818,143 @@ struct RWTexture2DArray IRWTexture* texture; }; +// FeedbackTexture + +struct FeedbackType {}; +struct SAMPLER_FEEDBACK_MIN_MIP : FeedbackType {}; +struct SAMPLER_FEEDBACK_MIP_REGION_USED : FeedbackType {}; + +struct IFeedbackTexture +{ + virtual TextureDimensions GetDimensions(int mipLevel = -1) = 0; + + // Note here we pass the optional clamp parameter as a pointer. Passing nullptr means no clamp. + // This was preferred over having two function definitions, and having to differentiate their names + virtual void WriteSamplerFeedback(ITexture* tex, SamplerState samp, const float* location, const float* clamp = nullptr) = 0; + virtual void WriteSamplerFeedbackBias(ITexture* tex, SamplerState samp, const float* location, float bias, const float* clamp = nullptr) = 0; + virtual void WriteSamplerFeedbackGrad(ITexture* tex, SamplerState samp, const float* location, const float* ddx, const float* ddy, const float* clamp = nullptr) = 0; + + virtual void WriteSamplerFeedbackLevel(ITexture* tex, SamplerState samp, const float* location, float lod) = 0; +}; + +template <typename T> +struct FeedbackTexture2D +{ + 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; + } + + template <typename S> + void WriteSamplerFeedback(Texture2D<S> tex, SamplerState samp, float2 location, float clamp) { texture->WriteSamplerFeedback(tex.texture, samp, &location.x, &clamp); } + + template <typename S> + void WriteSamplerFeedbackBias(Texture2D<S> tex, SamplerState samp, float2 location, float bias, float clamp) { texture->WriteSamplerFeedbackBias(tex.texture, samp, &location.x, bias, &clamp); } + + template <typename S> + void WriteSamplerFeedbackGrad(Texture2D<S> tex, SamplerState samp, float2 location, float2 ddx, float2 ddy, float clamp) { texture->WriteSamplerFeedbackGrad(tex.texture, samp, &location.x, &ddx.x, &ddy.x, &clamp); } + + // Level + + template <typename S> + void WriteSamplerFeedbackLevel(Texture2D<S> tex, SamplerState samp, float2 location, float lod) { texture->WriteSamplerFeedbackLevel(tex.texture, samp, &location.x, lod); } + + // Without Clamp + template <typename S> + void WriteSamplerFeedback(Texture2D<S> tex, SamplerState samp, float2 location) { texture->WriteSamplerFeedback(tex.texture, samp, &location.x); } + + template <typename S> + void WriteSamplerFeedbackBias(Texture2D<S> tex, SamplerState samp, float2 location, float bias) { texture->WriteSamplerFeedbackBias(tex.texture, samp, &location.x, bias); } + + template <typename S> + void WriteSamplerFeedbackGrad(Texture2D<S> tex, SamplerState samp, float2 location, float2 ddx, float2 ddy) { texture->WriteSamplerFeedbackGrad(tex.texture, samp, &location.x, &ddx.x, &ddy.x); } + + IFeedbackTexture* texture; +}; + +template <typename T> +struct FeedbackTexture2DArray +{ + 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; + } + + template <typename S> + void WriteSamplerFeedback(Texture2DArray<S> texArray, SamplerState samp, float3 location, float clamp) { texture->WriteSamplerFeedback(texArray.texture, samp, &location.x, &clamp); } + + template <typename S> + void WriteSamplerFeedbackBias(Texture2DArray<S> texArray, SamplerState samp, float3 location, float bias, float clamp) { texture->WriteSamplerFeedbackBias(texArray.texture, samp, &location.x, bias, &clamp); } + + template <typename S> + void WriteSamplerFeedbackGrad(Texture2DArray<S> texArray, SamplerState samp, float3 location, float3 ddx, float3 ddy, float clamp) { texture->WriteSamplerFeedbackGrad(texArray.texture, samp, &location.x, &ddx.x, &ddy.x, &clamp); } + + // Level + template <typename S> + void WriteSamplerFeedbackLevel(Texture2DArray<S> texArray, SamplerState samp, float3 location, float lod) { texture->WriteSamplerFeedbackLevel(texArray.texture, samp, &location.x, lod); } + + // Without Clamp + + template <typename S> + void WriteSamplerFeedback(Texture2DArray<S> texArray, SamplerState samp, float3 location) { texture->WriteSamplerFeedback(texArray.texture, samp, &location.x); } + + template <typename S> + void WriteSamplerFeedbackBias(Texture2DArray<S> texArray, SamplerState samp, float3 location, float bias) { texture->WriteSamplerFeedbackBias(texArray.texture, samp, &location.x, bias); } + + template <typename S> + void WriteSamplerFeedbackGrad(Texture2DArray<S> texArray, SamplerState samp, float3 location, float3 ddx, float3 ddy) { texture->WriteSamplerFeedbackGrad(texArray.texture, samp, &location.x, &ddx.x, &ddy.x); } + + IFeedbackTexture* texture; +}; + /* Varying input for Compute */ /* Used when running a single thread */ diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index b2748c50d..01fb17851 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -4024,6 +4024,18 @@ __magic_type(Texture, $(feedbackTexture2DFlavor)) __intrinsic_type($(kIROp_TextureType + (feedbackTexture2DFlavor << kIROpMeta_OtherShift))) struct FeedbackTexture2D<T : __BuiltinSamplerFeedbackType> { + __target_intrinsic(hlsl) + void GetDimensions(out uint width, out uint height); + + __target_intrinsic(hlsl) + void GetDimensions(uint mipLevel, out uint width, out uint height, out uint numberOfLevels); + + __target_intrinsic(hlsl) + void GetDimensions(out float width,out float height); + + __target_intrinsic(hlsl) + void GetDimensions(uint mipLevel, out float width,out float height, out float numberOfLevels); + // With Clamp __target_intrinsic(hlsl, "($0).WriteSamplerFeedback($1, $2, $3, $4)") @@ -4058,6 +4070,15 @@ __magic_type(Texture, $(feedbackTexture2DArrayFlavor)) __intrinsic_type($(kIROp_TextureType + (feedbackTexture2DArrayFlavor << kIROpMeta_OtherShift))) struct FeedbackTexture2DArray<T : __BuiltinSamplerFeedbackType> { + __target_intrinsic(hlsl) + void GetDimensions(out uint width,out uint height, out uint elements); + __target_intrinsic(hlsl) + void GetDimensions(uint mipLevel, out uint width,out uint height, out uint elements, out uint numberOfLevels); + __target_intrinsic(hlsl) + void GetDimensions(out float width,out float height, out float elements); + __target_intrinsic(hlsl) + void GetDimensions(uint mipLevel, out float width,out float height, out float elements, out float numberOfLevels); + // With Clamp __target_intrinsic(hlsl, "($0).WriteSamplerFeedback($1, $2, $3, $4)") diff --git a/tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang b/tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang new file mode 100644 index 000000000..c5fd93ca4 --- /dev/null +++ b/tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang @@ -0,0 +1,43 @@ +//TEST:COMPILE: -entry computeMain -stage compute -target dll tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang + +// Not available on non PS shader +// dx.op.writeSamplerFeedback WriteSamplerFeedback +// dx.op.writeSamplerFeedbackBias WriteSamplerFeedbackBias + +FeedbackTexture2D<SAMPLER_FEEDBACK_MIN_MIP> feedbackMinMip; +FeedbackTexture2D<SAMPLER_FEEDBACK_MIP_REGION_USED> feedbackMipRegionUsed; +FeedbackTexture2DArray<SAMPLER_FEEDBACK_MIN_MIP> feedbackMinMipArray; +FeedbackTexture2DArray<SAMPLER_FEEDBACK_MIP_REGION_USED> feebackMipRegionUsedArray; + +Texture2D<float> tex2D; +Texture2DArray<float> tex2DArray; +SamplerState samp; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + float2 coords2D = float2(1, 2) * dispatchThreadID.x; + float3 coords2DArray = float3(1, 2, 3) * dispatchThreadID.x; + + float clamp = 4; + float bias = 0.5F; + float lod = 6; + float2 ddx = float2(1.0F / 32, 2.0F / 32); + float2 ddy = float2(3.0F / 32, 4.0F / 32); + + uint width, height, elements, mipLevels; + feedbackMinMip.GetDimensions(width, height); + feedbackMinMipArray.GetDimensions(width, height, elements); + + feedbackMinMip.GetDimensions(0, width, height, mipLevels); + feedbackMinMipArray.GetDimensions(0, width, height, elements, mipLevels); + + + feedbackMinMip.WriteSamplerFeedbackGrad(tex2D, samp, coords2D, ddx, ddy, clamp); + + // Level + feedbackMinMip.WriteSamplerFeedbackLevel(tex2D, samp, coords2D, lod); + + // No Clamp + feedbackMinMip.WriteSamplerFeedbackGrad(tex2D, samp, coords2D, ddx, ddy); +} diff --git a/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang b/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang index 9e707b229..3b9497e5e 100644 --- a/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang +++ b/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang @@ -20,6 +20,11 @@ float4 main() : SV_Target float lod = 6; float2 ddx = float2(1.0F / 32, 2.0F / 32); float2 ddy = float2(3.0F / 32, 4.0F / 32); + + uint width, height, elements; + feedbackMinMip.GetDimensions(width, height); + + feedbackMinMipArray.GetDimensions(width, height, elements); // Clamped feedbackMinMip.WriteSamplerFeedback(tex2D, samp, coords2D, clamp); |
