From a1fa37645550a41ae44431c303ea3e1e85dddf81 Mon Sep 17 00:00:00 2001 From: Cassandra Beckley Date: Thu, 17 Oct 2024 11:01:38 -0700 Subject: [PATCH 1/3] [202x] Propose adding vk::SampledTexture* types This proposal adds a set of `vk::SampledTexture*` types to represent SPIR-V's sampled image types. The intent is to replace and deprecate the `[[vk::combinedImageSampler]]` annotation. I have created this with the extension template with the intent of using the fast-track process, as this is a platform-specific feature that is already supported by all Vulkan hardware and drivers, and it does not change any existing language behavior. --- proposals/NNNN-vk-sampled-texture.md | 174 +++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 proposals/NNNN-vk-sampled-texture.md diff --git a/proposals/NNNN-vk-sampled-texture.md b/proposals/NNNN-vk-sampled-texture.md new file mode 100644 index 00000000..aa9737ce --- /dev/null +++ b/proposals/NNNN-vk-sampled-texture.md @@ -0,0 +1,174 @@ + + +# Vulkan Sampled Textures + +* Proposal: [NNNN](NNNN-vk-sampled-texture.md) +* Author(s): [Cassandra Beckley](https://github.com/cassiebeckley) +* Sponsor: [Steven Perron](https://github.com/s-perron) and TBD +* Status: **Under Consideration** +* Required Version: HLSL 202x + + +## Introduction + +We propose a new set of `vk::SampledTexture*` texture types representing +Vulkan's combined image sampler types (`OpTypeSampledImage`). + +## Motivation + +The [existing annotation](https://github.com/microsoft/DirectXShaderCompiler/wiki/Vulkan-combined-image-sampler-type) +for combined image samplers (`[[vk::combinedImageSampler]]`) was designed with +the explicit goal of avoiding defining new HLSL types and functions. This was +intended to minimize the number of changes to the frontend needed to implement +the feature. However, it is verbose and confusing for users, and we do not +intend to implement it in upstream Clang. + +## High-level description + +The `vk::SampledTexture*` types will have the same interface and methods as the +existing `Texture*` types, with the exception that the methods will not take a +sampler state argument. + +Consider this example pixel shader which uses a texture: + +``` +Texture2D tex0 : register(t0); +SamplerState s : register(s0); + +float4 main(float2 uv: TEXCOORD) : SV_Target { + return tex0.Sample(s, uv); +} +``` + +Using the proposed types, this could be rewritten to use a combined image +sampler: + +``` +vk::SampledTexture2D tex0 : register(t0); + +float4 main(float2 uv: TEXCOORD) : SV_Target { + return tex0.Sample(uv); +} +``` + +This is simpler and a more accurate representation of the underlying interface +than using the existing annotation, which looks like: + +``` +[[vk::combinedImageSampler]] +Texture2D tex0 : register(t0); +[[vk::combinedImageSampler]] +SamplerState s : register(s0); + +float4 main(float2 uv: TEXCOORD) : SV_Target { + return tex0.Sample(s, uv); +} +``` + +## Detailed design + +### HLSL Additions + +The following resource types will be added: + +| HLSL Object | Type Parameters | +|---------------------------|-----------------------------------| +| `SampledTexture1D` | _type_ | +| `SampledTexture1DArray` | _type_ | +| `SampledTexture2D` | _type_ | +| `SampledTexture2DArray` | _type_ | +| `SampledTexture2DMS` | _type_, uint _samples_ | +| `SampledTexture2DMSArray` | _type_, uint _samples_ | +| `SampledTexture3D` | _type_ | +| `SampledTextureCUBE` | _type_ | +| `SampledTextureCUBEArray` | _type_ | + +As with the `Texture*` types, the _type_ parameter may be omitted, in which +it will default to `float4`. Values of these types may be assigned to specific +registers or annotated with the Vulkan binding annotations. + +The following builtin methods will be defined for these types: + +* `CalculateLevelOfDetail` +* `CalculateLevelOfDetailUnclamped` +* `Gather` +* `GetDimensions` +* `GetSamplePosition` +* `Load` +* `Sample` +* `SampleBias` +* `SampleCmp` +* `SampleCmpLevelZero` +* `SampleGrad` +* `SampleLevel` + +They will have the same interface as the corresponding methods for the +`Texture*` types, with the exception that they will not take a `SamplerState` +or `SamplerComparisonState` argument. (SPIR-V does not have separate sampler +types for comparison operations, and the combined sampler will be sufficient +for all methods listed). + +### Interchange Format Additions + +This proposal exists to better represent an existing feature of SPIR-V, and no +changes to the specification will be required. Since this is a Vulkan-specific +feature scoped to the `vk` namescape, no changes to the DXIL format or DXIL +lowering will be required. + +The `vk::SampledTexture*` types will be lowered to SPIR-V `OpTypeSampledImage` +type declarations, with an _Image Type_ operand which will be the `OpTypeImage` +produced by lowering the equivalent `Texture*` type. + +The builtin methods will be lowered to the same instructions as the equivalent +methods for `Texture*` types. SPIR-V instructions which operate on images take +these images in one of two formats: either an `OpTypeImage`, for instructions +which do not require a sampler, or an `OpTypeSampledImage`, for instructions +which do. For instructions which require an `OpTypeImage`, we can obtain such +a value by passing the `OpTypeSampledImage` value to the `OpImage` instruction. + +### Diagnostic Changes + +The `vk::SampledTexture*` types and builtin methods should provide the same +diagnostics as the corresponding `Texture*` types. + +#### Validation Changes + +No additional changes to the SPIR-V validator will be required. + +### Runtime Additions + +No runtime additions or information are required. + +#### Device Capability + +`OpTypeSampledImage` is a core feature of SPIR-V, and part of Vulkan since 1.0. +It should be supported by all existing Vulkan hardware. No changes to either +drivers or hardware will be needed. + +## Testing + +The existing tests for the SPIR-V lowering of `Texture*` types can be expanded +to ensure that `vk::SampledTexture` types exhibit the same behavior, in all +cases. + +## Alternatives considered + +We considered using a `vk::Sampled` template that would take a texture as a +template parameter. For example, `vk::Sampled >`. We decided against +this as it would require additional validation that the template parameter is a +texture type, and because HLSL has an existing convention for resource types to +have additional behavior by prepending information to the type name – for +example, `Buffer` to `RWBuffer` and `RWStructuredBuffer`. + +We also considered using inline SPIR-V for implementation; however, doing so +would require the ability to assign an HLSL-defined class an HLSL register +and/or Vulkan location binding, and then use that register for a member +variable of the class holding the low-level inline SPIR-V representation. We +decided that such a mechanism would be too general, as new resource types in +HLSL are rare and users should not have the ability to create them themselves. + + From 70af79c2dcf5e55049be3e06adb39ecdd16c5002 Mon Sep 17 00:00:00 2001 From: Cassandra Beckley Date: Thu, 17 Oct 2024 12:24:20 -0700 Subject: [PATCH 2/3] Refinements --- proposals/NNNN-vk-sampled-texture.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/proposals/NNNN-vk-sampled-texture.md b/proposals/NNNN-vk-sampled-texture.md index aa9737ce..3e5c1ed3 100644 --- a/proposals/NNNN-vk-sampled-texture.md +++ b/proposals/NNNN-vk-sampled-texture.md @@ -24,8 +24,9 @@ The [existing annotation](https://github.com/microsoft/DirectXShaderCompiler/wik for combined image samplers (`[[vk::combinedImageSampler]]`) was designed with the explicit goal of avoiding defining new HLSL types and functions. This was intended to minimize the number of changes to the frontend needed to implement -the feature. However, it is verbose and confusing for users, and we do not -intend to implement it in upstream Clang. +the feature. However, it is verbose, confusing for users, and requires a +backend pass to pair up textures and samplers which is prone to subtle errors. +We do not intend to implement it in upstream Clang. ## High-level description @@ -73,7 +74,7 @@ float4 main(float2 uv: TEXCOORD) : SV_Target { ### HLSL Additions -The following resource types will be added: +The following resource types will be added to the `vk` namespace: | HLSL Object | Type Parameters | |---------------------------|-----------------------------------| @@ -130,6 +131,9 @@ which do not require a sampler, or an `OpTypeSampledImage`, for instructions which do. For instructions which require an `OpTypeImage`, we can obtain such a value by passing the `OpTypeSampledImage` value to the `OpImage` instruction. +We will likely represent these types in LLVM IR for upstream Clang by the +addition of a new "sampled" attribute for the resource type. + ### Diagnostic Changes The `vk::SampledTexture*` types and builtin methods should provide the same From 08814149108d1541f9f5e944e92b9ea23fc14aad Mon Sep 17 00:00:00 2001 From: Cassandra Beckley Date: Thu, 17 Oct 2024 13:04:49 -0700 Subject: [PATCH 3/3] Mention portability --- proposals/NNNN-vk-sampled-texture.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/proposals/NNNN-vk-sampled-texture.md b/proposals/NNNN-vk-sampled-texture.md index 3e5c1ed3..e5c20f5c 100644 --- a/proposals/NNNN-vk-sampled-texture.md +++ b/proposals/NNNN-vk-sampled-texture.md @@ -36,7 +36,7 @@ sampler state argument. Consider this example pixel shader which uses a texture: -``` +```hlsl Texture2D tex0 : register(t0); SamplerState s : register(s0); @@ -48,7 +48,7 @@ float4 main(float2 uv: TEXCOORD) : SV_Target { Using the proposed types, this could be rewritten to use a combined image sampler: -``` +```hlsl vk::SampledTexture2D tex0 : register(t0); float4 main(float2 uv: TEXCOORD) : SV_Target { @@ -59,7 +59,7 @@ float4 main(float2 uv: TEXCOORD) : SV_Target { This is simpler and a more accurate representation of the underlying interface than using the existing annotation, which looks like: -``` +```hlsl [[vk::combinedImageSampler]] Texture2D tex0 : register(t0); [[vk::combinedImageSampler]] @@ -70,6 +70,12 @@ float4 main(float2 uv: TEXCOORD) : SV_Target { } ``` +A benefit of the `[[vk::combinedImageSampler]]` annotation is the ability to +use the same code to represent a combined image sampler in Vulkan and a +separate texture and sampler in DirectX. The new types will only be usable with +Vulkan, but a similar effect can be produced by checking for the existence of +the `__spirv__` macro. + ## Detailed design ### HLSL Additions