summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-04-17 22:14:34 -0700
committerGitHub <noreply@github.com>2024-04-17 22:14:34 -0700
commit5dd27a26da9b6b6191f3b1eba0f38f85714c1ae3 (patch)
tree2a596911523b003746e2cfda2847ffd02d332ef3 /source
parent355a8d8f923ef67f11092ae706b50d028b09f9ad (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.slang108
-rw-r--r--source/slang/hlsl.meta.slang219
-rw-r--r--source/slang/slang-emit.cpp6
-rw-r--r--source/slang/slang-ir-inst-defs.h2
-rw-r--r--source/slang/slang-ir-lower-combined-texture-sampler.cpp205
-rw-r--r--source/slang/slang-ir-lower-combined-texture-sampler.h15
-rw-r--r--source/slang/slang-ir.cpp2
-rw-r--r--source/slang/slang-parameter-binding.cpp6
-rw-r--r--source/slang/slang-type-layout.cpp63
-rw-r--r--source/slang/slang-type-layout.h19
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);
}