diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2023-07-26 16:33:48 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-26 09:33:48 -0700 |
| commit | c61775e634a6a52772de60e68ba6d50751d8b790 (patch) | |
| tree | 17e645be935f26f15f4ddc114fbe025f958fbfb0 | |
| parent | d47d54928f46f1c869c8cca5cf67b310fd18cb1d (diff) | |
Add GatherCmp* for texture objects (#3024)
The translation to GLSL is incomplete as intrinsics only exist for some combination of comparison and channel (just channel 0)
Closes https://github.com/shader-slang/slang/issues/3021
| -rw-r--r-- | source/slang/core.meta.slang | 56 | ||||
| -rw-r--r-- | tests/cross-compile/glsl-texturegather.slang | 20 |
2 files changed, 65 insertions, 11 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index afb14dc4a..ddb81fd87 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -2176,50 +2176,83 @@ struct TextureTypeInfo { 2, "Blue" }, { 3, "Alpha" }, }; + enum Cmp + { NotCmp, + Cmp + }; + for(auto cmp : {NotCmp, Cmp}) for(auto kk : kGatherComponets) { + auto samplerOrComparisonSampler = cmp == Cmp ? "SamplerComparisonState s, " : samplerStateParam; + auto componentIndex = kk.componentIndex; auto componentName = kk.componentName; auto outputType = cc.outputType; + const auto cmpName = cmp == Cmp ? "Cmp" : ""; + const auto cmpValueParam = cmp == Cmp ? "float compareValue, " : ""; + const auto cmpValueParamEnd = cmp == Cmp ? ", float compareValue" : ""; + const auto supportsGLSL = componentIndex == 0 || cmp == NotCmp; + EMIT_LINE_DIRECTIVE(); - sb << "__target_intrinsic(glsl, \"textureGather($p, $2, " << componentIndex << ")\")\n"; - if (base.coordCount == 2) + if(supportsGLSL) + { + if(cmp == Cmp) + sb << "__target_intrinsic(glsl, \"textureGather($p, $2, $3)\")\n"; + else + sb << "__target_intrinsic(glsl, \"textureGather($p, $2, " << componentIndex << ")\")\n"; + } + if (base.coordCount == 2 && cmp == NotCmp) { - // Gather only works on 2D in CUDA + // Gather only works on 2D in CUDA without comparison // "It is based on the base type of DataType except when readMode is equal to cudaReadModeNormalizedFloat (see Texture Reference API), in which case it is always float4." sb << "__target_intrinsic(cuda, \"tex2Dgather<$T0>($0, ($2).x, ($2).y, " << componentIndex << ")\")\n"; } if (isReadOnly) sb << "[__readNone]\n"; - sb << outputType << " Gather" << componentName << "(" << samplerStateParam; - sb << "float" << base.coordCount + isArray << " location);\n"; + sb << outputType << " Gather" << cmpName << componentName << "(" << samplerOrComparisonSampler; + sb << "float" << base.coordCount + isArray << " location" << cmpValueParamEnd << ");\n"; if (isReadOnly) sb << "[__readNone]\n"; EMIT_LINE_DIRECTIVE(); - sb << "__target_intrinsic(glsl, \"textureGatherOffset($p, $2, $3, " << componentIndex << ")\")\n"; - sb << outputType << " Gather" << componentName << "(" << samplerStateParam; + if(supportsGLSL) + { + if(cmp == Cmp) + sb << "__target_intrinsic(glsl, \"textureGatherOffset($p, $2, $3, $4)\")\n"; + else + sb << "__target_intrinsic(glsl, \"textureGatherOffset($p, $2, $3, " << componentIndex << ")\")\n"; + } + sb << outputType << " Gather" << cmpName << componentName << "(" << samplerOrComparisonSampler; sb << "float" << base.coordCount + isArray << " location, "; + sb << cmpValueParam; sb << "constexpr int" << base.coordCount << " offset);\n"; if (isReadOnly) sb << "[__readNone]\n"; EMIT_LINE_DIRECTIVE(); - sb << outputType << " Gather" << componentName << "(" << samplerStateParam; + sb << outputType << " Gather" << cmpName << componentName << "(" << samplerOrComparisonSampler; sb << "float" << base.coordCount + isArray << " location, "; + sb << cmpValueParam; sb << "constexpr int" << base.coordCount << " offset, "; sb << "out uint status);\n"; if (isReadOnly) sb << "[__readNone]\n"; EMIT_LINE_DIRECTIVE(); - sb << "__target_intrinsic(glsl, \"textureGatherOffsets($p, $2, int" << base.coordCount << "[]($3, $4, $5, $6), " << componentIndex << ")\")\n"; - sb << outputType << " Gather" << componentName << "(" << samplerStateParam; + if(supportsGLSL) + { + if(cmp == Cmp) + sb << "__target_intrinsic(glsl, \"textureGatherOffsets($p, $2, $3, ivec" << base.coordCount << "[]($4, $5, $6, $7))\")\n"; + else + sb << "__target_intrinsic(glsl, \"textureGatherOffsets($p, $2, ivec" << base.coordCount << "[]($3, $4, $5, $6), " << componentIndex << ")\")\n"; + } + sb << outputType << " Gather" << cmpName << componentName << "(" << samplerOrComparisonSampler; sb << "float" << base.coordCount + isArray << " location, "; + sb << cmpValueParam; sb << "int" << base.coordCount << " offset1, "; sb << "int" << base.coordCount << " offset2, "; sb << "int" << base.coordCount << " offset3, "; @@ -2228,8 +2261,9 @@ struct TextureTypeInfo if (isReadOnly) sb << "[__readNone]\n"; EMIT_LINE_DIRECTIVE(); - sb << outputType << " Gather" << componentName << "(" << samplerStateParam; + sb << outputType << " Gather" << cmpName << componentName << "(" << samplerOrComparisonSampler; sb << "float" << base.coordCount + isArray << " location, "; + sb << cmpValueParam; sb << "int" << base.coordCount << " offset1, "; sb << "int" << base.coordCount << " offset2, "; sb << "int" << base.coordCount << " offset3, "; diff --git a/tests/cross-compile/glsl-texturegather.slang b/tests/cross-compile/glsl-texturegather.slang new file mode 100644 index 000000000..125cf6df1 --- /dev/null +++ b/tests/cross-compile/glsl-texturegather.slang @@ -0,0 +1,20 @@ +//TEST:CROSS_COMPILE(filecheck=CHECK): -profile ps_5_0 -entry main -target glsl + +// CHECK: textureGather(sampler2DShadow(t_0,sc_0), (loc_0), (3.0)) +// CHECK: textureGatherOffset(sampler2DShadow(t_0,sc_0), (loc_0), (3.0), (off_0)) +// CHECK: textureGatherOffsets(sampler2DShadow(t_0,sc_0), (loc_0), (3.0), ivec2[]((off_0), (off_0), (off_0), (off_0))) +// CHECK: textureGatherOffsets(sampler2DShadow(t_0,sc_0), (loc_0), (3.0), ivec2[]((ivec2(6, 6)), (ivec2(7, 7)), (ivec2(8, 8)), (ivec2(9, 9)))) + +Texture2D t; +SamplerState s; +SamplerComparisonState sc; +float4 main() +{ + const float2 loc = float2(1,2); + const float cmp = 3; + const int2 off = int2(4,5); + return t.GatherCmp(sc, loc, cmp) + + t.GatherCmp(sc, loc, cmp, off) + + t.GatherCmp(sc, loc, cmp, off, off, off, off) + + t.GatherCmpRed(sc, loc, cmp, int2(6,6), int2(7,7), int2(8,8), int2(9,9)); +} |
