diff options
| author | Yong He <yonghe@outlook.com> | 2024-04-17 22:14:34 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-17 22:14:34 -0700 |
| commit | 5dd27a26da9b6b6191f3b1eba0f38f85714c1ae3 (patch) | |
| tree | 2a596911523b003746e2cfda2847ffd02d332ef3 /source | |
| parent | 355a8d8f923ef67f11092ae706b50d028b09f9ad (diff) | |
Support combined texture sampler when targeting HLSL. (#3963)
* Support combined texture sampler when targeting HLSL.
* Fix glsl intrinsics.
* Update source/slang/slang-ir-lower-combined-texture-sampler.cpp
Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com>
* Update source/slang/slang-ir-lower-combined-texture-sampler.cpp
Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com>
* Update source/slang/slang-ir-lower-combined-texture-sampler.cpp
Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com>
* Fix.,
* Enhance test.
* Remove unused field.
* Fix indentation
---------
Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com>
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/glsl.meta.slang | 108 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang | 219 | ||||
| -rw-r--r-- | source/slang/slang-emit.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-combined-texture-sampler.cpp | 205 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-combined-texture-sampler.h | 15 | ||||
| -rw-r--r-- | source/slang/slang-ir.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-parameter-binding.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-type-layout.cpp | 63 | ||||
| -rw-r--r-- | source/slang/slang-type-layout.h | 19 |
10 files changed, 470 insertions, 175 deletions
diff --git a/source/slang/glsl.meta.slang b/source/slang/glsl.meta.slang index 54f62308f..e2c1d25bd 100644 --- a/source/slang/glsl.meta.slang +++ b/source/slang/glsl.meta.slang @@ -1419,7 +1419,7 @@ public ivec3 textureSize(Sampler2DMSArray<vector<T,N>,sampleCount> sampler) // textureQueryLod // ------------------- -__generic<T, let isArray:int, let sampleCount:int, let isShadow:int, let format:int> +__generic<T:IFloat, let isArray:int, let sampleCount:int, let isShadow:int, let format:int> [ForceInline] public vec2 textureQueryLod(__TextureImpl< T, @@ -1439,7 +1439,7 @@ public vec2 textureQueryLod(__TextureImpl< ); } -__generic<T, Shape: __ITextureShape, let isArray:int, let sampleCount:int, let isShadow:int, let format:int> +__generic<T:IFloat, Shape: __ITextureShape, let isArray:int, let sampleCount:int, let isShadow:int, let format:int> [ForceInline] public vec2 textureQueryLod(__TextureImpl<T, Shape, @@ -1620,21 +1620,21 @@ public int textureSamples(Sampler2DMSArray<vector<T,N>,sampleCount> sampler) // texture // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> texture(Sampler1D<vector<T,N>> sampler, float p) { return __vectorReshape<4>(sampler.Sample(p)); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> texture(Sampler1D<vector<T,N>> sampler, float p, constexpr float bias) { return __vectorReshape<4>(sampler.SampleBias(p, bias)); } -__generic<T:__BuiltinArithmeticType, let N:int, Shape: __ITextureShape, let isArray:int, let sampleCount:int, let format:int> +__generic<T:__BuiltinFloatingPointType, let N:int, Shape: __ITextureShape, let isArray:int, let sampleCount:int, let format:int> [ForceInline] public vector<T,4> texture(__TextureImpl< vector<T,N>, @@ -1651,7 +1651,7 @@ public vector<T,4> texture(__TextureImpl< return __vectorReshape<4>(sampler.Sample(p)); } -__generic<T:__BuiltinArithmeticType, let N:int, Shape: __ITextureShape, let isArray:int, let sampleCount:int, let format:int> +__generic<T:__BuiltinFloatingPointType, let N:int, Shape: __ITextureShape, let isArray:int, let sampleCount:int, let format:int> [ForceInline] public vector<T,4> texture(__TextureImpl< vector<T,N>, @@ -1736,70 +1736,70 @@ public float texture(samplerCubeArrayShadow sampler, vec4 p, float compare) // textureProj // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProj(Sampler1D<vector<T,N>> sampler, vec2 p) { return texture(sampler, p.x / p.y); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProj(Sampler1D<vector<T,N>> sampler, vec2 p, float bias) { return texture(sampler, p.x / p.y, bias); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProj(Sampler1D<vector<T,N>> sampler, vec4 p) { return texture(sampler, p.x / p.w); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProj(Sampler1D<vector<T,N>> sampler, vec4 p, float bias) { return texture(sampler, p.x / p.w, bias); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProj(Sampler2D<vector<T,N>> sampler, vec3 p) { return texture(sampler, p.xy / p.z); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProj(Sampler2D<vector<T,N>> sampler, vec3 p, float bias) { return texture(sampler, p.xy / p.z, bias); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProj(Sampler2D<vector<T,N>> sampler, vec4 p) { return texture(sampler, p.xy / p.w); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProj(Sampler2D<vector<T,N>> sampler, vec4 p, float bias) { return texture(sampler, p.xy / p.w, bias); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProj(Sampler3D<vector<T,N>> sampler, vec4 p) { return texture(sampler, p.xyz / p.w); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProj(Sampler3D<vector<T,N>> sampler, vec4 p, float bias) { @@ -1834,14 +1834,14 @@ public float textureProj(sampler2DShadow sampler, vec4 p, float bias) // textureLod // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureLod(Sampler1D<vector<T,N>> sampler, float p, float lod) { return __vectorReshape<4>(sampler.SampleLevel(p, lod)); } -__generic<T:__BuiltinArithmeticType, let N:int, Shape: __ITextureShape, let isArray:int, let sampleCount:int, let format:int> +__generic<T:__BuiltinFloatingPointType, let N:int, Shape: __ITextureShape, let isArray:int, let sampleCount:int, let format:int> [ForceInline] public vector<T,4> textureLod(__TextureImpl< vector<T,N>, @@ -1883,21 +1883,21 @@ public float textureLod(sampler1DArrayShadow sampler, vec3 p, float lod) // textureOffset // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureOffset(Sampler1D<vector<T,N>> sampler, float p, constexpr int offset, float bias = 0.0) { return __vectorReshape<4>(sampler.SampleBias(p, bias, offset)); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureOffset(Sampler2D<vector<T,N>> sampler, vec2 p, constexpr ivec2 offset, float bias = 0.0) { return __vectorReshape<4>(sampler.SampleBias(p, bias, offset)); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureOffset(Sampler3D<vector<T,N>> sampler, vec3 p, constexpr ivec3 offset, float bias = 0.0) { @@ -1918,14 +1918,14 @@ public float textureOffset(sampler1DShadow sampler, vec3 p, constexpr int offset return sampler.SampleCmp(p.x, p.z, offset); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureOffset(Sampler1DArray<vector<T,N>> sampler, vec2 p, constexpr int offset, float bias = 0.0) { return __vectorReshape<4>(sampler.SampleBias(p, bias, offset)); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureOffset(Sampler2DArray<vector<T,N>> sampler, vec3 p, constexpr ivec2 offset, float bias = 0.0) { @@ -2060,35 +2060,35 @@ public vector<T,4> texelFetchOffset(Sampler2DRect<vector<T,N>> sampler, ivec2 p, // textureProjOffset // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjOffset(Sampler1D<vector<T,N>> sampler, vec2 p, constexpr int offset, float bias = 0.0) { return textureOffset(sampler, p.x / p.y, offset, bias); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjOffset(Sampler1D<vector<T,N>> sampler, vec4 p, constexpr int offset, float bias = 0.0) { return textureOffset(sampler, p.x / p.w, offset, bias); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjOffset(Sampler2D<vector<T,N>> sampler, vec3 p, constexpr ivec2 offset, float bias = 0.0) { return textureOffset(sampler, p.xy / p.z, offset, bias); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjOffset(Sampler2D<vector<T,N>> sampler, vec4 p, constexpr ivec2 offset, float bias = 0.0) { return textureOffset(sampler, p.xy / p.w, offset, bias); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjOffset(Sampler3D<vector<T,N>> sampler, vec4 p, constexpr ivec3 offset, float bias = 0.0) { @@ -2111,14 +2111,14 @@ public float textureProjOffset(sampler2DShadow sampler, vec4 p, constexpr ivec2 // textureLodOffset // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureLodOffset(Sampler1D<vector<T,N>> sampler, float p, float lod, constexpr int offset) { return __vectorReshape<4>(sampler.SampleLevel(p, lod, offset)); } -__generic<T:__BuiltinArithmeticType, let N:int, Shape:__ITextureShape, let isArray:int, let sampleCount:int, let format:int> +__generic<T:__BuiltinFloatingPointType, let N:int, Shape:__ITextureShape, let isArray:int, let sampleCount:int, let format:int> [ForceInline] public vector<T,4> textureLodOffset(__TextureImpl< vector<T,N>, @@ -2160,35 +2160,35 @@ public float textureLodOffset(sampler1DArrayShadow sampler, vec3 p, float lod, c // textureProjLod // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjLod(Sampler1D<vector<T,N>> sampler, vec2 p, float lod) { return textureLod(sampler, p.x / p.y, lod); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjLod(Sampler1D<vector<T,N>> sampler, vec4 p, float lod) { return textureLod(sampler, p.x / p.w, lod); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjLod(Sampler2D<vector<T,N>> sampler, vec3 p, float lod) { return textureLod(sampler, p.xy / p.z, lod); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjLod(Sampler2D<vector<T,N>> sampler, vec4 p, float lod) { return textureLod(sampler, p.xy / p.w, lod); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjLod(Sampler3D<vector<T,N>> sampler, vec4 p, float lod) { @@ -2211,35 +2211,35 @@ public float textureProjLod(sampler2DShadow sampler, vec4 p, float lod) // textureProjLodOffset // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjLodOffset(Sampler1D<vector<T,N>> sampler, vec2 p, float lod, constexpr int offset) { return textureLodOffset(sampler, p.x / p.y, lod, offset); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjLodOffset(Sampler1D<vector<T,N>> sampler, vec4 p, float lod, constexpr int offset) { return textureLodOffset(sampler, p.x / p.w, lod, offset); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjLodOffset(Sampler2D<vector<T,N>> sampler, vec3 p, float lod, constexpr ivec2 offset) { return textureLodOffset(sampler, p.xy / p.z, lod, offset); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjLodOffset(Sampler2D<vector<T,N>> sampler, vec4 p, float lod, constexpr ivec2 offset) { return textureLodOffset(sampler, p.xy / p.w, lod, offset); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjLodOffset(Sampler3D<vector<T,N>> sampler, vec4 p, float lod, constexpr ivec3 offset) { @@ -2262,14 +2262,14 @@ public float textureProjLodOffset(sampler2DShadow sampler, vec4 p, float lod, co // textureGrad // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureGrad(Sampler1D<vector<T,N>> sampler, float p, float dPdx, float dPdy) { return __vectorReshape<4>(sampler.SampleGrad(p, dPdx, dPdy)); } -__generic<T:__BuiltinArithmeticType, let N:int, Shape:__ITextureShape, let isArray:int, let sampleCount:int, let format:int> +__generic<T:__BuiltinFloatingPointType, let N:int, Shape:__ITextureShape, let isArray:int, let sampleCount:int, let format:int> [ForceInline] public vector<T,4> textureGrad(__TextureImpl< vector<T,N>, @@ -2325,14 +2325,14 @@ public float textureGrad(sampler2DArrayShadow sampler, vec4 p, vec2 dPdx, vec2 d // textureGradOffset // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureGradOffset(Sampler1D<vector<T,N>> sampler, float p, float dPdx, float dPdy, constexpr int offset) { return __vectorReshape<4>(sampler.SampleGrad(p, dPdx, dPdy, offset)); } -__generic<T:__BuiltinArithmeticType, let N:int, Shape:__ITextureShape, let isArray:int, let sampleCount:int, let format:int> +__generic<T:__BuiltinFloatingPointType, let N:int, Shape:__ITextureShape, let isArray:int, let sampleCount:int, let format:int> [ForceInline] public vector<T,4> textureGradOffset(__TextureImpl< vector<T,N>, @@ -2381,35 +2381,35 @@ public float textureGradOffset(sampler2DArrayShadow sampler, vec4 p, vec2 dPdx, // textureProjGrad // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjGrad(Sampler1D<vector<T,N>> sampler, vec2 p, float dPdx, float dPdy) { return textureGrad(sampler, p.x / p.y, dPdx, dPdy); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjGrad(Sampler1D<vector<T,N>> sampler, vec4 p, float dPdx, float dPdy) { return textureGrad(sampler, p.x / p.w, dPdx, dPdy); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjGrad(Sampler2D<vector<T,N>> sampler, vec3 p, vec2 dPdx, vec2 dPdy) { return textureGrad(sampler, p.xy / p.z, dPdx, dPdy); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjGrad(Sampler2D<vector<T,N>> sampler, vec4 p, vec2 dPdx, vec2 dPdy) { return textureGrad(sampler, p.xy / p.w, dPdx, dPdy); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjGrad(Sampler3D<vector<T,N>> sampler, vec4 p, vec3 dPdx, vec3 dPdy) { @@ -2432,35 +2432,35 @@ public float textureProjGrad(sampler2DShadow sampler, vec4 p, vec2 dPdx, vec2 dP // textureProjGradOffset // ------------------- -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjGradOffset(Sampler1D<vector<T,N>> sampler, vec2 p, float dPdx, float dPdy, constexpr int offset) { return textureGradOffset(sampler, p.x / p.y, dPdx, dPdy, offset); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjGradOffset(Sampler1D<vector<T,N>> sampler, vec4 p, float dPdx, float dPdy, constexpr int offset) { return textureGradOffset(sampler, p.x / p.w, dPdx, dPdy, offset); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjGradOffset(Sampler2D<vector<T,N>> sampler, vec3 p, vec2 dPdx, vec2 dPdy, constexpr ivec2 offset) { return textureGradOffset(sampler, p.xy / p.z, dPdx, dPdy, offset); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjGradOffset(Sampler2D<vector<T,N>> sampler, vec4 p, vec2 dPdx, vec2 dPdy, constexpr ivec2 offset) { return textureGradOffset(sampler, p.xy / p.w, dPdx, dPdy, offset); } -__generic<T:__BuiltinArithmeticType, let N:int> +__generic<T:__BuiltinFloatingPointType, let N:int> [ForceInline] public vector<T,4> textureProjGradOffset(Sampler3D<vector<T,N>> sampler, vec4 p, vec3 dPdx, vec3 dPdy, constexpr ivec3 offset) { diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 9683da4a3..7905042d7 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -209,14 +209,92 @@ struct __TextureImpl<T, Shape: __ITextureShape, let isArray:int, let isMS:int, l { } + // Combined texture sampler specific functions -__generic<T, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let isShadow:int, let format:int> + +__target_intrinsic(glsl, "texture($0, $1)") +float __glsl_texture<TSampler, TCoord>(TSampler s, TCoord value); + +__target_intrinsic(glsl, "texture($0, $1)") +float __glsl_texture_1d_shadow<TSampler, TCoord>(TSampler s, TCoord value); + +__target_intrinsic(glsl, "texture($0, $1, $2)") +float __glsl_texture_3d_array_shadow<TSampler, TCoord>(TSampler s, TCoord value, float compare); + +__glsl_extension(GL_EXT_texture_shadow_lod) + __target_intrinsic(glsl, "textureOffset($0, $1, $2)") +float __glsl_texture_offset<TSampler, TCoord, TOffset>( TSampler s, TCoord value, constexpr TOffset offset); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureOffset($0, $1, $2)") +float __glsl_texture_offset_1d_shadow<TSampler, TCoord, TOffset>(TSampler s, TCoord value, constexpr TOffset offset); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureLod($0, $1, 0)") +float __glsl_texture_level_zero<TSampler, TCoord>(TSampler s, TCoord value); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureLod($0, $1, 0)") +float __glsl_texture_level_zero_1d_shadow<TSampler, TCoord>(TSampler s, TCoord value); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureLodOffset($0, $1, 0, $2)") +float __glsl_texture_offset_level_zero<TSampler, TCoord, TOffset>(TSampler s, TCoord value, constexpr TOffset offset); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureLodOffset($0, $1, 0, $2)") +float __glsl_texture_offset_level_zero_1d_shadow<TSampler, TCoord, TOffset>(TSampler s, TCoord value, constexpr TOffset offset); + +__target_intrinsic(glsl, "texture($p, $2)") +float __glsl_texture<TTexture, TCoord>(TTexture t, SamplerComparisonState s, TCoord value); + +__target_intrinsic(glsl, "texture($p, $2)") +float __glsl_texture_1d_shadow<TTexture, TCoord>(TTexture t, SamplerComparisonState s, TCoord value); + +__target_intrinsic(glsl, "texture($p, $2, $3)") +float __glsl_texture_3d_array_shadow<TTexture, TCoord>(TTexture t, SamplerComparisonState s, TCoord value, float compare); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureOffset($p, $2, $3)") +float __glsl_texture_offset<TTexture, TCoord, TOffset>(TTexture t,SamplerComparisonState s, TCoord value, constexpr TOffset offset); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureOffset($p, $2, $3)") +float __glsl_texture_offset_1d_shadow<TTexture, TCoord, TOffset>(TTexture t,SamplerComparisonState s, TCoord value, constexpr TOffset offset); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureLod($p, $2, 0)") +float __glsl_texture_level_zero<TTexture, TCoord>(TTexture t,SamplerComparisonState s, TCoord value); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureLod($p, $2, 0)") +float __glsl_texture_level_zero_1d_shadow<TTexture, TCoord>(TTexture t,SamplerComparisonState s, TCoord value); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureLodOffset($p, $2, 0, $3)") +float __glsl_texture_offset_level_zero<TTexture, TCoord, TOffset>(TTexture t,SamplerComparisonState s, TCoord value, constexpr TOffset offset); + +__glsl_extension(GL_EXT_texture_shadow_lod) +__target_intrinsic(glsl, "textureLodOffset($p, $2, 0, $3)") +float __glsl_texture_offset_level_zero_1d_shadow<TTexture, TCoord, TOffset>(TTexture t,SamplerComparisonState s, TCoord value, constexpr TOffset offset); + + +__generic<T:IFloat, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let isShadow:int, let format:int> extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { static const int access = 0; typealias TextureCoord = vector<float, Shape.dimensions>; + __intrinsic_op($(kIROp_CombinedTextureSamplerGetTexture)) + __TextureImpl<T, Shape, isArray, isMS, sampleCount, 0, isShadow, 0, format> __getTexture(); + + __intrinsic_op($(kIROp_CombinedTextureSamplerGetSampler)) + SamplerState __getSampler(); + + __intrinsic_op($(kIROp_CombinedTextureSamplerGetSampler)) + SamplerComparisonState __getComparisonSampler(); + [ForceInline] [__readNone] float CalculateLevelOfDetail(TextureCoord location) @@ -224,7 +302,9 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> __target_switch { case hlsl: - __intrinsic_asm "CalculateLevelOfDetail"; + { + return __getTexture().CalculateLevelOfDetail(__getSampler(), location); + } case glsl: __intrinsic_asm "textureQueryLod($0, $1).x"; case spirv: @@ -242,7 +322,9 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> __target_switch { case hlsl: - __intrinsic_asm "CalculateLevelOfDetailUnclamped"; + { + return __getTexture().CalculateLevelOfDetailUnclamped(__getSampler(), location); + } case glsl: __intrinsic_asm "textureQueryLod($0, $1).y"; case spirv: @@ -252,39 +334,6 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> }).y; } } - - __target_intrinsic(glsl, "texture($0, $1)") - float __glsl_texture(vector<float, Shape.dimensions+isArray+1> value); - - __target_intrinsic(glsl, "texture($0, $1)") - float __glsl_texture_1d_shadow(vector<float, Shape.dimensions+isArray+2> value); - - __target_intrinsic(glsl, "texture($0, $1, $2)") - float __glsl_texture_3d_array_shadow(vector<float, Shape.dimensions+isArray> value, float compare); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureOffset($0, $1, $2)") - float __glsl_texture_offset(vector<float, Shape.dimensions+isArray+1> value, constexpr vector<int, Shape.planeDimensions> offset); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureOffset($0, $1, $2)") - float __glsl_texture_offset_1d_shadow(vector<float, Shape.dimensions+isArray+2> value, constexpr vector<int, Shape.planeDimensions> offset); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureLod($0, $1, 0)") - float __glsl_texture_level_zero(vector<float, Shape.dimensions+isArray+1> value); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureLod($0, $1, 0)") - float __glsl_texture_level_zero_1d_shadow(vector<float, Shape.dimensions+isArray+2> value); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureLodOffset($0, $1, 0, $2)") - float __glsl_texture_offset_level_zero(vector<float, Shape.dimensions+isArray+1> value, constexpr vector<int, Shape.planeDimensions> offset); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureLodOffset($0, $1, 0, $2)") - float __glsl_texture_offset_level_zero_1d_shadow(vector<float, Shape.dimensions+isArray+2> value, constexpr vector<int, Shape.planeDimensions> offset); [__readNone] T Sample(vector<float, Shape.dimensions+isArray> location) @@ -293,7 +342,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { case cpp: case hlsl: - __intrinsic_asm ".Sample"; + return __getTexture().Sample(__getSampler(), location); case glsl: __intrinsic_asm "$ctexture($0, $1)$z"; case cuda: @@ -342,7 +391,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { case cpp: case hlsl: - __intrinsic_asm ".Sample"; + return __getTexture().Sample(__getSampler(), location, offset, clamp); case glsl: __intrinsic_asm "$ctextureOffsetClampARB($0, $1, $2, $3)$z"; case spirv: @@ -370,7 +419,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { case cpp: case hlsl: - __intrinsic_asm ".SampleBias"; + return __getTexture().SampleBias(__getSampler(), location, bias); case glsl: __intrinsic_asm "$ctexture($0, $1, $2)$z"; case spirv: @@ -390,7 +439,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { case cpp: case hlsl: - __intrinsic_asm ".SampleBias"; + return __getTexture().SampleBias(__getSampler(), location, bias, offset); case glsl: __intrinsic_asm "$ctextureOffset($0, $1, $3, $2)$z"; case spirv: @@ -411,18 +460,18 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> case glsl: if (Shape.dimensions == 1 && isArray == 0) { - return __glsl_texture_1d_shadow(__makeVector(__makeVector(location, 0.0), compareValue)); + return __glsl_texture_1d_shadow(this, __makeVector(__makeVector(location, 0.0), compareValue)); } else if (Shape.dimensions == 3 && isArray == 1) { - return __glsl_texture_3d_array_shadow(location, compareValue); + return __glsl_texture_3d_array_shadow(this, location, compareValue); } else { - return __glsl_texture(__makeVector(location, compareValue)); + return __glsl_texture(this, __makeVector(location, compareValue)); } case hlsl: - __intrinsic_asm ".SampleCmp"; + return __getTexture().SampleCmp(__getComparisonSampler(), location, compareValue); case spirv: return spirv_asm { @@ -440,14 +489,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> case glsl: if (Shape.dimensions == 1 && isArray == 0) { - return __glsl_texture_level_zero_1d_shadow(__makeVector(__makeVector(location, 0.0), compareValue)); + return __glsl_texture_level_zero_1d_shadow(this, __makeVector(__makeVector(location, 0.0), compareValue)); } else { - return __glsl_texture_level_zero(__makeVector(location, compareValue)); + return __glsl_texture_level_zero(this, __makeVector(location, compareValue)); } case hlsl: - __intrinsic_asm ".SampleCmpLevelZero"; + return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue); case spirv: const float zeroFloat = 0.0f; return spirv_asm @@ -466,14 +515,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> case glsl: if (Shape.dimensions == 1 && isArray == 0) { - return __glsl_texture_offset_1d_shadow(__makeVector(__makeVector(location, 0.0), compareValue), offset); + return __glsl_texture_offset_1d_shadow(this, __makeVector(__makeVector(location, 0.0), compareValue), offset); } else { - return __glsl_texture_offset(__makeVector(location, compareValue), offset); + return __glsl_texture_offset(this, __makeVector(location, compareValue), offset); } case hlsl: - __intrinsic_asm ".SampleCmp"; + return __getTexture().SampleCmp(__getComparisonSampler(), location, compareValue, offset); case spirv: return spirv_asm { @@ -491,14 +540,14 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> case glsl: if (Shape.dimensions == 1 && isArray == 0) { - return __glsl_texture_offset_level_zero_1d_shadow(__makeVector(__makeVector(location,0.0), compareValue), offset); + return __glsl_texture_offset_level_zero_1d_shadow(this, __makeVector(__makeVector(location,0.0), compareValue), offset); } else { - return __glsl_texture_offset_level_zero(__makeVector(location, compareValue), offset); + return __glsl_texture_offset_level_zero(this, __makeVector(location, compareValue), offset); } case hlsl: - __intrinsic_asm ".SampleCmpLevelZero"; + return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue, offset); case spirv: const float zeroFloat = 0.0f; return spirv_asm @@ -515,7 +564,8 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { case cpp: case hlsl: - __intrinsic_asm ".SampleGrad"; + return __getTexture().SampleGrad(__getSampler(), location, gradX, gradY); + case glsl: __intrinsic_asm "$ctextureGrad($0, $1, $2, $3)$z"; case spirv: @@ -534,7 +584,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { case cpp: case hlsl: - __intrinsic_asm ".SampleGrad"; + return __getTexture().SampleGrad(__getSampler(), location, gradX, gradY, offset); case glsl: __intrinsic_asm "$ctextureGradOffset($0, $1, $2, $3, $4)$z"; case spirv: @@ -554,7 +604,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { case cpp: case hlsl: - __intrinsic_asm ".SampleGrad"; + return __getTexture().SampleGrad(__getSampler(), location, gradX, gradY, offset, lodClamp); case glsl: __intrinsic_asm "$ctextureGradOffsetClampARB($0, $1, $2, $3, $4, $5)$z"; case spirv: @@ -574,7 +624,7 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { case cpp: case hlsl: - __intrinsic_asm ".SampleLevel"; + return __getTexture().SampleLevel(__getSampler(), location, level); case glsl: __intrinsic_asm "$ctextureLod($0, $1, $2)$z"; case cuda: @@ -624,7 +674,8 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format> { case cpp: case hlsl: - __intrinsic_asm ".SampleLevel"; + return __getTexture().SampleLevel(__getSampler(), location, level, offset); + case glsl: __intrinsic_asm "$ctextureLodOffset($0, $1, $2, $3)$z"; case spirv: @@ -678,40 +729,6 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,access,isShadow,0,forma }).y; } } - - __target_intrinsic(glsl, "texture($p, $2)") - float __glsl_texture(SamplerComparisonState s, vector<float, Shape.dimensions+isArray+1> value); - - __target_intrinsic(glsl, "texture($p, $2)") - float __glsl_texture_1d_shadow(SamplerComparisonState s, vector<float, Shape.dimensions+isArray+2> value); - - __target_intrinsic(glsl, "texture($p, $2, $3)") - float __glsl_texture_3d_array_shadow(SamplerComparisonState s, vector<float, Shape.dimensions+isArray> value, float compare); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureOffset($p, $2, $3)") - float __glsl_texture_offset(SamplerComparisonState s, vector<float, Shape.dimensions+isArray+1> value, constexpr vector<int, Shape.planeDimensions> offset); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureOffset($p, $2, $3)") - float __glsl_texture_offset_1d_shadow(SamplerComparisonState s, vector<float, Shape.dimensions+isArray+2> value, constexpr vector<int, Shape.planeDimensions> offset); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureLod($p, $2, 0)") - float __glsl_texture_level_zero(SamplerComparisonState s, vector<float, Shape.dimensions+isArray+1> value); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureLod($p, $2, 0)") - float __glsl_texture_level_zero_1d_shadow(SamplerComparisonState s, vector<float, Shape.dimensions+isArray+2> value); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureLodOffset($p, $2, 0, $3)") - float __glsl_texture_offset_level_zero(SamplerComparisonState s, vector<float, Shape.dimensions+isArray+1> value, constexpr vector<int, Shape.planeDimensions> offset); - - __glsl_extension(GL_EXT_texture_shadow_lod) - __target_intrinsic(glsl, "textureLodOffset($p, $2, 0, $3)") - float __glsl_texture_offset_level_zero_1d_shadow(SamplerComparisonState s, vector<float, Shape.dimensions+isArray+2> value, constexpr vector<int, Shape.planeDimensions> offset); - } __generic<T:IFloat, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let isShadow:int, let format:int> @@ -866,15 +883,15 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> case glsl: if (Shape.dimensions == 1 && isArray == 0) { - return __glsl_texture_1d_shadow(s, __makeVector(__makeVector(location, 0.0), compareValue)); + return __glsl_texture_1d_shadow(this, s, __makeVector(__makeVector(location, 0.0), compareValue)); } else if (Shape.dimensions == 3 && isArray == 1) { - return __glsl_texture_3d_array_shadow(s, location, compareValue); + return __glsl_texture_3d_array_shadow(this, s, location, compareValue); } else { - return __glsl_texture(s, __makeVector(location,compareValue)); + return __glsl_texture(this, s, __makeVector(location,compareValue)); } case hlsl: __intrinsic_asm ".SampleCmp"; @@ -895,11 +912,11 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> case glsl: if (Shape.dimensions == 1 && isArray == 0) { - return __glsl_texture_level_zero_1d_shadow(s, __makeVector(__makeVector(location, 0.0), compareValue)); + return __glsl_texture_level_zero_1d_shadow(this, s, __makeVector(__makeVector(location, 0.0), compareValue)); } else { - return __glsl_texture_level_zero(s, __makeVector(location,compareValue)); + return __glsl_texture_level_zero(this, s, __makeVector(location,compareValue)); } case hlsl: __intrinsic_asm ".SampleCmpLevelZero"; @@ -921,11 +938,11 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> case glsl: if (Shape.dimensions == 1 && isArray == 0) { - return __glsl_texture_offset_1d_shadow(s, __makeVector(__makeVector(location, 0.0), compareValue), offset); + return __glsl_texture_offset_1d_shadow(this, s, __makeVector(__makeVector(location, 0.0), compareValue), offset); } else { - return __glsl_texture_offset(s, __makeVector(location,compareValue), offset); + return __glsl_texture_offset(this, s, __makeVector(location,compareValue), offset); } case hlsl: __intrinsic_asm ".SampleCmp"; @@ -946,11 +963,11 @@ extension __TextureImpl<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> case glsl: if (Shape.dimensions == 1 && isArray == 0) { - return __glsl_texture_offset_level_zero_1d_shadow(s, __makeVector(__makeVector(location,0.0),compareValue), offset); + return __glsl_texture_offset_level_zero_1d_shadow(this, s, __makeVector(__makeVector(location,0.0),compareValue), offset); } else { - return __glsl_texture_offset_level_zero(s, __makeVector(location,compareValue), offset); + return __glsl_texture_offset_level_zero(this, s, __makeVector(location,compareValue), offset); } case hlsl: __intrinsic_asm ".SampleCmpLevelZero"; diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 633d17345..c00c7bfc3 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -45,6 +45,7 @@ #include "slang-ir-lower-result-type.h" #include "slang-ir-lower-optional-type.h" #include "slang-ir-lower-bit-cast.h" +#include "slang-ir-lower-combined-texture-sampler.h" #include "slang-ir-lower-l-value-cast.h" #include "slang-ir-lower-size-of.h" #include "slang-ir-lower-reinterpret.h" @@ -545,6 +546,11 @@ Result linkAndOptimizeIR( lowerAppendConsumeStructuredBuffers(targetProgram, irModule, sink); } + if (target == CodeGenTarget::HLSL || ArtifactDescUtil::isCpuLikeTarget(artifactDesc)) + { + lowerCombinedTextureSamplers(irModule, sink); + } + addUserTypeHintDecorations(irModule); // We don't need the legalize pass for C/C++ based types diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index 5acb22674..2612d2ac7 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -345,6 +345,8 @@ INST(GetOptionalValue, getOptionalValue, 1, 0) INST(OptionalHasValue, optionalHasValue, 1, 0) INST(MakeOptionalValue, makeOptionalValue, 1, 0) INST(MakeOptionalNone, makeOptionalNone, 1, 0) +INST(CombinedTextureSamplerGetTexture, CombinedTextureSamplerGetTexture, 1, 0) +INST(CombinedTextureSamplerGetSampler, CombinedTextureSamplerGetSampler, 1, 0) INST(Call, call, 1, 0) INST(RTTIObject, rtti_object, 0, 0) diff --git a/source/slang/slang-ir-lower-combined-texture-sampler.cpp b/source/slang/slang-ir-lower-combined-texture-sampler.cpp new file mode 100644 index 000000000..b6f65c933 --- /dev/null +++ b/source/slang/slang-ir-lower-combined-texture-sampler.cpp @@ -0,0 +1,205 @@ +#include "slang-ir-lower-combined-texture-sampler.h" + +#include "slang-ir-insts.h" +#include "slang-ir-util.h" +#include "slang-ir-layout.h" + +namespace Slang +{ + struct LoweredCombinedSamplerStructInfo + { + IRStructKey* texture; + IRStructKey* sampler; + IRStructType* type; + IRType* samplerType; + IRType* textureType; + IRTypeLayout* typeLayout; + }; + + struct LowerCombinedSamplerContext + { + Dictionary<IRType*, LoweredCombinedSamplerStructInfo> mapTypeToLoweredInfo; + + LoweredCombinedSamplerStructInfo lowerCombinedTextureSamplerType(IRTextureTypeBase* textureType) + { + if (auto loweredInfo = mapTypeToLoweredInfo.tryGetValue(textureType)) + return *loweredInfo; + LoweredCombinedSamplerStructInfo info; + IRBuilder builder(textureType); + builder.setInsertBefore(textureType); + auto structType = builder.createStructType(); + StringBuilder sb; + getTypeNameHint(sb, textureType); + builder.addNameHintDecoration(structType, sb.getUnownedSlice()); + info.sampler = builder.createStructKey(); + builder.addNameHintDecoration(info.sampler, toSlice("sampler")); + info.texture = builder.createStructKey(); + builder.addNameHintDecoration(info.texture, toSlice("texture")); + info.type = structType; + + bool isMutable = getIntVal(textureType->getAccessInst()) == kStdlibResourceAccessReadOnly ? false : true; + + info.textureType = builder.getTextureType(textureType->getElementType(), + textureType->getShapeInst(), + textureType->getIsArrayInst(), + textureType->getIsMultisampleInst(), + textureType->getSampleCountInst(), + textureType->getAccessInst(), + textureType->getIsShadowInst(), + builder.getIntValue(builder.getIntType(), 0), + textureType->getFormatInst()); + builder.createStructField(structType, info.texture, info.textureType); + + if (getIntVal(textureType->getIsShadowInst()) != 0) + info.samplerType = builder.getType(kIROp_SamplerComparisonStateType); + else + info.samplerType = builder.getType(kIROp_SamplerStateType); + builder.createStructField(structType, info.sampler, info.samplerType); + + // Type layout. + + auto textureResourceKind = isMutable ? LayoutResourceKind::UnorderedAccess : LayoutResourceKind::ShaderResource; + IRTypeLayout::Builder textureTypeLayoutBuilder(&builder); + textureTypeLayoutBuilder.addResourceUsage( + textureResourceKind, + LayoutSize(1)); + auto textureTypeLayout = textureTypeLayoutBuilder.build(); + + IRTypeLayout::Builder samplerTypeLayoutBuilder(&builder); + samplerTypeLayoutBuilder.addResourceUsage( + LayoutResourceKind::SamplerState, + LayoutSize(1)); + auto samplerTypeLayout = samplerTypeLayoutBuilder.build(); + + IRVarLayout::Builder textureVarLayoutBuilder(&builder, textureTypeLayout); + textureVarLayoutBuilder.findOrAddResourceInfo(textureResourceKind)->offset = 0; + auto textureVarLayout = textureVarLayoutBuilder.build(); + + IRVarLayout::Builder samplerVarLayoutBuilder(&builder, samplerTypeLayout); + samplerVarLayoutBuilder.findOrAddResourceInfo(LayoutResourceKind::SamplerState)->offset = 0; + auto samplerVarLayout = samplerVarLayoutBuilder.build(); + + IRStructTypeLayout::Builder layoutBuilder(&builder); + layoutBuilder.addField(info.texture, textureVarLayout); + layoutBuilder.addField(info.sampler, samplerVarLayout); + info.typeLayout = layoutBuilder.build(); + builder.addLayoutDecoration(structType, info.typeLayout); + + mapTypeToLoweredInfo.add(textureType, info); + return info; + } + }; + + void lowerCombinedTextureSamplers( + IRModule* module, + DiagnosticSink* sink) + { + SLANG_UNUSED(sink); + + LowerCombinedSamplerContext context; + + // Lower combined texture sampler type into a struct type. + for (auto globalInst : module->getGlobalInsts()) + { + auto textureType = as<IRTextureTypeBase>(globalInst); + if (!textureType || getIntVal(textureType->getIsCombinedInst()) == 0) + continue; + auto typeInfo = context.lowerCombinedTextureSamplerType(textureType); + + for (auto use = textureType->firstUse; use; use = use->nextUse) + { + auto typeUser = use->getUser(); + if (use != &typeUser->typeUse) + continue; + + auto layoutDecor = typeUser->findDecoration<IRLayoutDecoration>(); + if (!layoutDecor) + continue; + // Replace the original VarLayout with the new StructTypeVarLayout. + auto varLayout = as<IRVarLayout>(layoutDecor->getLayout()); + if (!varLayout) + continue; + IRBuilder subBuilder(typeUser); + IRVarLayout::Builder newVarLayoutBuilder(&subBuilder, typeInfo.typeLayout); + newVarLayoutBuilder.cloneEverythingButOffsetsFrom(varLayout); + IRVarOffsetAttr* resOffsetAttr = nullptr; + IRVarOffsetAttr* descriptorTableSlotOffsetAttr = nullptr; + + for (auto offsetAttr : varLayout->getOffsetAttrs()) + { + if (offsetAttr->getResourceKind() == LayoutResourceKind::UnorderedAccess || + offsetAttr->getResourceKind() == LayoutResourceKind::ShaderResource) + resOffsetAttr = offsetAttr; + else if (offsetAttr->getResourceKind() == LayoutResourceKind::DescriptorTableSlot) + descriptorTableSlotOffsetAttr = offsetAttr; + auto info = newVarLayoutBuilder.findOrAddResourceInfo(offsetAttr->getResourceKind()); + info->offset = offsetAttr->getOffset(); + info->space = offsetAttr->getSpace(); + info->kind = offsetAttr->getResourceKind(); + } + // If the user provided an layout offset for the texture but not for descriptor table slot, then + // we use the texture offset for the descriptor table slot offset. + if (resOffsetAttr && !descriptorTableSlotOffsetAttr) + { + auto info = newVarLayoutBuilder.findOrAddResourceInfo(LayoutResourceKind::DescriptorTableSlot); + info->offset = resOffsetAttr->getOffset(); + info->space = resOffsetAttr->getSpace(); + info->kind = LayoutResourceKind::DescriptorTableSlot; + } + auto newVarLayout = newVarLayoutBuilder.build(); + subBuilder.addLayoutDecoration(typeUser, newVarLayout); + varLayout->removeAndDeallocate(); + } + } + + // If no combined texture sampler type exist in the IR module, + // we can exit now. + if (context.mapTypeToLoweredInfo.getCount() == 0) + return; + + // We need to process all insts in the module, and replace + // CombinedTextureSamplerGetTexture and CombinedTextureSamplerGetSampler into + // FieldExtracts. + IRBuilder builder(module); + for (auto globalInst : module->getGlobalInsts()) + { + auto func = as<IRFunc>(getGenericReturnVal(globalInst)); + if (!func) + continue; + for (auto block : func->getBlocks()) + { + IRInst* nextInst = nullptr; + for (auto inst = block->getFirstInst(); inst; inst = nextInst) + { + nextInst = inst->getNextInst(); + switch (inst->getOp()) + { + case kIROp_CombinedTextureSamplerGetTexture: + case kIROp_CombinedTextureSamplerGetSampler: + { + auto combinedSamplerType = inst->getOperand(0)->getDataType(); + auto loweredInfo = context.mapTypeToLoweredInfo.tryGetValue(combinedSamplerType); + if (!loweredInfo) + continue; + builder.setInsertBefore(inst); + auto fieldExtract = builder.emitFieldExtract(inst->getFullType(), inst->getOperand(0), + inst->getOp() == kIROp_CombinedTextureSamplerGetSampler ? loweredInfo->sampler : loweredInfo->texture); + inst->replaceUsesWith(fieldExtract); + inst->removeAndDeallocate(); + } + break; + } + } + } + } + + // Replace all other type use with the lowered struct type. + for (auto typeInfo : context.mapTypeToLoweredInfo) + { + auto loweredInfo = typeInfo.second; + typeInfo.first->replaceUsesWith(loweredInfo.type); + typeInfo.first->removeAndDeallocate(); + } + } + +} diff --git a/source/slang/slang-ir-lower-combined-texture-sampler.h b/source/slang/slang-ir-lower-combined-texture-sampler.h new file mode 100644 index 000000000..ccd448786 --- /dev/null +++ b/source/slang/slang-ir-lower-combined-texture-sampler.h @@ -0,0 +1,15 @@ +#pragma once + +#include "slang-ir.h" + +namespace Slang +{ + struct IRModule; + class DiagnosticSink; + + // Lower combined texture sampler types to structs. + void lowerCombinedTextureSamplers( + IRModule* module, + DiagnosticSink* sink + ); +} diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index 2dfbde2cc..3a6dc667b 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -8056,6 +8056,8 @@ namespace Slang case kIROp_StructuredBufferLoad: case kIROp_RWStructuredBufferLoad: case kIROp_RWStructuredBufferGetElementPtr: + case kIROp_CombinedTextureSamplerGetSampler: + case kIROp_CombinedTextureSamplerGetTexture: case kIROp_Load: // We are ignoring the possibility of loads from bad addresses, or `volatile` loads case kIROp_LoadReverseGradient: case kIROp_ReverseGradientDiffPairRef: diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp index 516b9eb44..f702efb94 100644 --- a/source/slang/slang-parameter-binding.cpp +++ b/source/slang/slang-parameter-binding.cpp @@ -2642,7 +2642,8 @@ static ParameterBindingAndKindInfo _allocateConstantBufferBinding( auto layoutInfo = context->getRulesFamily() ->getConstantBufferRules(context->getTargetRequest()->getOptionSet()) - ->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context->layoutContext.objectLayoutOptions); + ->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context->layoutContext.objectLayoutOptions) + .getSimple(); ParameterBindingAndKindInfo info; info.kind = layoutInfo.kind; @@ -2662,7 +2663,8 @@ static ParameterBindingAndKindInfo _assignConstantBufferBinding( auto layoutInfo = context->getRulesFamily() ->getConstantBufferRules(context->getTargetRequest()->getOptionSet()) - ->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context->layoutContext.objectLayoutOptions); + ->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context->layoutContext.objectLayoutOptions) + .getSimple(); const Index count = Index(layoutInfo.size.getFiniteValue()); diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index e79c51256..a350226c8 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -741,7 +741,7 @@ static LayoutResourceKind _getHLSLLayoutResourceKind(ShaderParameterKind kind) struct GLSLObjectLayoutRulesImpl : ObjectLayoutRulesImpl { - virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& options) override + virtual ObjectLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& options) override { int slotCount = 1; @@ -778,7 +778,7 @@ GLSLObjectLayoutRulesImpl kGLSLObjectLayoutRulesImpl; struct GLSLPushConstantBufferObjectLayoutRulesImpl : GLSLObjectLayoutRulesImpl { - virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind /*kind*/, const Options& /* options */) override + virtual ObjectLayoutInfo GetObjectLayout(ShaderParameterKind /*kind*/, const Options& /* options */) override { // Special-case the layout for a constant-buffer, because we don't // want it to allocate a descriptor-table slot @@ -789,7 +789,7 @@ GLSLPushConstantBufferObjectLayoutRulesImpl kGLSLPushConstantBufferObjectLayoutR struct GLSLShaderRecordConstantBufferObjectLayoutRulesImpl : GLSLObjectLayoutRulesImpl { - virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind /*kind*/, const Options& /* options */) override + virtual ObjectLayoutInfo GetObjectLayout(ShaderParameterKind /*kind*/, const Options& /* options */) override { // Special-case the layout for a constant-buffer, because we don't // want it to allocate a descriptor-table slot @@ -800,7 +800,7 @@ GLSLShaderRecordConstantBufferObjectLayoutRulesImpl kGLSLShaderRecordConstantBuf struct HLSLObjectLayoutRulesImpl : ObjectLayoutRulesImpl { - virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& /* options */) override + virtual ObjectLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& /* options */) override { switch( kind ) { @@ -828,7 +828,19 @@ struct HLSLObjectLayoutRulesImpl : ObjectLayoutRulesImpl return SimpleLayoutInfo(LayoutResourceKind::InputAttachmentIndex, 1); case ShaderParameterKind::TextureSampler: + { + ObjectLayoutInfo info; + info.layoutInfos.add(SimpleLayoutInfo(LayoutResourceKind::ShaderResource, 1)); + info.layoutInfos.add(SimpleLayoutInfo(LayoutResourceKind::SamplerState, 1)); + return info; + } case ShaderParameterKind::MutableTextureSampler: + { + ObjectLayoutInfo info; + info.layoutInfos.add(SimpleLayoutInfo(LayoutResourceKind::UnorderedAccess, 1)); + info.layoutInfos.add(SimpleLayoutInfo(LayoutResourceKind::SamplerState, 1)); + return info; + } case ShaderParameterKind::InputRenderTarget: // TODO: how to handle these? default: @@ -981,7 +993,7 @@ CUDALayoutRulesFamilyImpl kCUDALayoutRulesFamilyImpl; struct CPUObjectLayoutRulesImpl : ObjectLayoutRulesImpl { - virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& /* options */) override + virtual ObjectLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& /* options */) override { switch (kind) { @@ -1034,7 +1046,7 @@ struct CUDAObjectLayoutRulesImpl : CPUObjectLayoutRulesImpl // of opaque handle (as opposed to a pointer) such as CUsurfObject, CUtexObject typedef unsigned long long ObjectHandle; - virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options & /* options */) override + virtual ObjectLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options & /* options */) override { switch (kind) { @@ -1657,6 +1669,24 @@ static TypeLayoutResult createSimpleTypeLayout( return TypeLayoutResult(typeLayout, info); } +static TypeLayoutResult createSimpleTypeLayout( + const ObjectLayoutInfo& info, + Type* type, + LayoutRulesImpl* rules) +{ + RefPtr<TypeLayout> typeLayout = new TypeLayout(); + + typeLayout->type = type; + typeLayout->rules = rules; + + typeLayout->uniformAlignment = info.layoutInfos[0].alignment; + + for (auto entry : info.layoutInfos) + typeLayout->addResourceUsage(entry.kind, entry.size); + + return TypeLayoutResult(typeLayout, info.layoutInfos[0]); +} + static SimpleLayoutInfo _getParameterGroupLayoutInfo( TypeLayoutContext const& context, ParameterGroupType* type, @@ -1664,15 +1694,15 @@ static SimpleLayoutInfo _getParameterGroupLayoutInfo( { if( as<ConstantBufferType>(type) ) { - return rules->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context.objectLayoutOptions); + return rules->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context.objectLayoutOptions).getSimple(); } else if( as<TextureBufferType>(type) ) { - return rules->GetObjectLayout(ShaderParameterKind::TextureUniformBuffer, context.objectLayoutOptions); + return rules->GetObjectLayout(ShaderParameterKind::TextureUniformBuffer, context.objectLayoutOptions).getSimple(); } else if( as<GLSLShaderStorageBufferType>(type) ) { - return rules->GetObjectLayout(ShaderParameterKind::ShaderStorageBuffer, context.objectLayoutOptions); + return rules->GetObjectLayout(ShaderParameterKind::ShaderStorageBuffer, context.objectLayoutOptions).getSimple(); } else if (as<ParameterBlockType>(type)) { @@ -2364,7 +2394,8 @@ static RefPtr<TypeLayout> _createParameterGroupTypeLayout( // the overall layout, to account for it. // auto cbUsage = parameterGroupRules->GetObjectLayout(ShaderParameterKind::ConstantBuffer, context.objectLayoutOptions); - containerTypeLayout->addResourceUsage(cbUsage.kind, cbUsage.size); + for (auto layoutInfo : cbUsage.layoutInfos) + containerTypeLayout->addResourceUsage(layoutInfo.kind, layoutInfo.size); } // Similarly to how we only need a constant buffer to be allocated @@ -2870,7 +2901,7 @@ createStructuredBufferTypeLayout( RefPtr<TypeLayout> elementTypeLayout) { auto rules = context.rules; - auto info = rules->GetObjectLayout(kind, context.objectLayoutOptions); + auto info = rules->GetObjectLayout(kind, context.objectLayoutOptions).getSimple(); auto typeLayout = new StructuredBufferTypeLayout(); @@ -3801,7 +3832,7 @@ static TypeLayoutResult _createTypeLayout( else if (const auto samplerStateType = as<SamplerStateType>(type)) { return createSimpleTypeLayout( - rules->GetObjectLayout(ShaderParameterKind::SamplerState, context.objectLayoutOptions), + rules->GetObjectLayout(ShaderParameterKind::SamplerState, context.objectLayoutOptions).getSimple(), type, rules); } @@ -3825,7 +3856,7 @@ static TypeLayoutResult _createTypeLayout( } else { - switch( textureType->getAccess() ) + switch (textureType->getAccess()) { default: kind = ShaderParameterKind::MutableTexture; @@ -3836,9 +3867,9 @@ static TypeLayoutResult _createTypeLayout( break; } } - + auto objLayout = rules->GetObjectLayout(kind, context.objectLayoutOptions); return createSimpleTypeLayout( - rules->GetObjectLayout(kind, context.objectLayoutOptions), + objLayout, type, rules); } @@ -3883,7 +3914,7 @@ static TypeLayoutResult _createTypeLayout( // TODO: need a better way to handle this stuff... #define CASE(TYPE, KIND) \ else if(auto type_##TYPE = as<TYPE>(type)) do { \ - auto info = rules->GetObjectLayout(ShaderParameterKind::KIND, context.objectLayoutOptions); \ + auto info = rules->GetObjectLayout(ShaderParameterKind::KIND, context.objectLayoutOptions).getSimple(); \ auto typeLayout = createStructuredBufferTypeLayout( \ context, \ ShaderParameterKind::KIND, \ diff --git a/source/slang/slang-type-layout.h b/source/slang/slang-type-layout.h index a44efb085..acf6088eb 100644 --- a/source/slang/slang-type-layout.h +++ b/source/slang/slang-type-layout.h @@ -361,6 +361,21 @@ struct SimpleArrayLayoutInfo : SimpleLayoutInfo } }; +struct ObjectLayoutInfo +{ + ShortList<SimpleLayoutInfo, 2> layoutInfos; + ObjectLayoutInfo() = default; + ObjectLayoutInfo(SimpleLayoutInfo layoutInfo) + { + layoutInfos.add(layoutInfo); + } + SimpleLayoutInfo getSimple() + { + SLANG_ASSERT(layoutInfos.getCount() == 1); + return layoutInfos[0]; + } +}; + struct LayoutRulesImpl; class VarLayout; @@ -988,7 +1003,7 @@ struct ObjectLayoutRulesImpl }; // Compute layout info for an object type - virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& options) = 0; + virtual ObjectLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& options) = 0; }; struct LayoutRulesImpl @@ -1046,7 +1061,7 @@ struct LayoutRulesImpl // Forward `ObjectLayoutRulesImpl` interface - SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind, const ObjectLayoutRulesImpl::Options& options) + ObjectLayoutInfo GetObjectLayout(ShaderParameterKind kind, const ObjectLayoutRulesImpl::Options& options) { return objectRules->GetObjectLayout(kind, options); } |
