Skip to content

Commit e47bfae

Browse files
Alex Smithaejsmith
authored andcommitted
Add support for GL_EXT_samplerless_texture_functions
1 parent 0b964b3 commit e47bfae

File tree

10 files changed

+229
-20
lines changed

10 files changed

+229
-20
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
samplerlessTextureFunctions.frag
2+
ERROR: 0:9: 'texelFetch' : required extension not requested: GL_EXT_samplerless_texture_functions
3+
ERROR: 0:10: 'texelFetch' : required extension not requested: GL_EXT_samplerless_texture_functions
4+
ERROR: 0:16: 'texelFetchOffset' : required extension not requested: GL_EXT_samplerless_texture_functions
5+
ERROR: 0:18: 'textureSize' : required extension not requested: GL_EXT_samplerless_texture_functions
6+
ERROR: 0:19: 'textureSize' : required extension not requested: GL_EXT_samplerless_texture_functions
7+
ERROR: 0:20: 'textureSize' : required extension not requested: GL_EXT_samplerless_texture_functions
8+
ERROR: 0:22: 'textureQueryLevels' : required extension not requested: GL_EXT_samplerless_texture_functions
9+
ERROR: 0:24: 'textureSamples' : required extension not requested: GL_EXT_samplerless_texture_functions
10+
ERROR: 8 compilation errors. No code generated.
11+
12+
13+
SPIR-V is not generated for failed compile or link
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
spv.samplerlessTextureFunctions.frag
2+
// Module Version 10000
3+
// Generated by (magic number): 80007
4+
// Id's are bound by 51
5+
6+
Capability Shader
7+
Capability SampledBuffer
8+
Capability ImageQuery
9+
1: ExtInstImport "GLSL.std.450"
10+
MemoryModel Logical GLSL450
11+
EntryPoint Fragment 4 "main"
12+
ExecutionMode 4 OriginUpperLeft
13+
Source GLSL 450
14+
SourceExtension "GL_EXT_samplerless_texture_functions"
15+
Name 4 "main"
16+
Name 9 "tex2DFetch"
17+
Name 12 "tex2D"
18+
Name 19 "texMSFetch"
19+
Name 22 "texMS"
20+
Name 25 "bufFetch"
21+
Name 28 "buf"
22+
Name 31 "tex2DFetchOffset"
23+
Name 35 "tex2DSize"
24+
Name 38 "texMSSize"
25+
Name 42 "bufSize"
26+
Name 45 "tex2DLevels"
27+
Name 48 "texMSSamples"
28+
Decorate 12(tex2D) DescriptorSet 0
29+
Decorate 12(tex2D) Binding 1
30+
Decorate 22(texMS) DescriptorSet 0
31+
Decorate 22(texMS) Binding 1
32+
Decorate 28(buf) DescriptorSet 0
33+
Decorate 28(buf) Binding 0
34+
2: TypeVoid
35+
3: TypeFunction 2
36+
6: TypeFloat 32
37+
7: TypeVector 6(float) 4
38+
8: TypePointer Function 7(fvec4)
39+
10: TypeImage 6(float) 2D sampled format:Unknown
40+
11: TypePointer UniformConstant 10
41+
12(tex2D): 11(ptr) Variable UniformConstant
42+
14: TypeInt 32 1
43+
15: TypeVector 14(int) 2
44+
16: 14(int) Constant 0
45+
17: 15(ivec2) ConstantComposite 16 16
46+
20: TypeImage 6(float) 2D multi-sampled sampled format:Unknown
47+
21: TypePointer UniformConstant 20
48+
22(texMS): 21(ptr) Variable UniformConstant
49+
26: TypeImage 6(float) Buffer sampled format:Unknown
50+
27: TypePointer UniformConstant 26
51+
28(buf): 27(ptr) Variable UniformConstant
52+
34: TypePointer Function 15(ivec2)
53+
41: TypePointer Function 14(int)
54+
4(main): 2 Function None 3
55+
5: Label
56+
9(tex2DFetch): 8(ptr) Variable Function
57+
19(texMSFetch): 8(ptr) Variable Function
58+
25(bufFetch): 8(ptr) Variable Function
59+
31(tex2DFetchOffset): 8(ptr) Variable Function
60+
35(tex2DSize): 34(ptr) Variable Function
61+
38(texMSSize): 34(ptr) Variable Function
62+
42(bufSize): 41(ptr) Variable Function
63+
45(tex2DLevels): 41(ptr) Variable Function
64+
48(texMSSamples): 41(ptr) Variable Function
65+
13: 10 Load 12(tex2D)
66+
18: 7(fvec4) ImageFetch 13 17 Lod 16
67+
Store 9(tex2DFetch) 18
68+
23: 20 Load 22(texMS)
69+
24: 7(fvec4) ImageFetch 23 17 Sample 16
70+
Store 19(texMSFetch) 24
71+
29: 26 Load 28(buf)
72+
30: 7(fvec4) ImageFetch 29 16
73+
Store 25(bufFetch) 30
74+
32: 10 Load 12(tex2D)
75+
33: 7(fvec4) ImageFetch 32 17 Lod ConstOffset 16 17
76+
Store 31(tex2DFetchOffset) 33
77+
36: 10 Load 12(tex2D)
78+
37: 15(ivec2) ImageQuerySizeLod 36 16
79+
Store 35(tex2DSize) 37
80+
39: 20 Load 22(texMS)
81+
40: 15(ivec2) ImageQuerySize 39
82+
Store 38(texMSSize) 40
83+
43: 26 Load 28(buf)
84+
44: 14(int) ImageQuerySize 43
85+
Store 42(bufSize) 44
86+
46: 10 Load 12(tex2D)
87+
47: 14(int) ImageQueryLevels 46
88+
Store 45(tex2DLevels) 47
89+
49: 20 Load 22(texMS)
90+
50: 14(int) ImageQuerySamples 49
91+
Store 48(texMSSamples) 50
92+
Return
93+
FunctionEnd

Test/baseResults/spv.specConstant.vert.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ spv.specConstant.vert
1111
Source GLSL 400
1212
Name 4 "main"
1313
Name 9 "arraySize"
14-
Name 14 "foo(vf4[s2468];"
14+
Name 14 "foo(vf4[s2543];"
1515
Name 13 "p"
1616
Name 17 "builtin_spec_constant("
1717
Name 20 "color"
@@ -102,10 +102,10 @@ spv.specConstant.vert
102102
Store 20(color) 46
103103
48: 10 Load 22(ucol)
104104
Store 47(param) 48
105-
49: 2 FunctionCall 14(foo(vf4[s2468];) 47(param)
105+
49: 2 FunctionCall 14(foo(vf4[s2543];) 47(param)
106106
Return
107107
FunctionEnd
108-
14(foo(vf4[s2468];): 2 Function None 12
108+
14(foo(vf4[s2543];): 2 Function None 12
109109
13(p): 11(ptr) FunctionParameter
110110
15: Label
111111
54: 24(ptr) AccessChain 53(dupUcol) 23
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#version 450 core
2+
3+
layout(binding = 1) uniform texture2D tex2D;
4+
layout(binding = 1) uniform texture2DMS texMS;
5+
layout(binding = 0) uniform textureBuffer buf;
6+
7+
void testBad()
8+
{
9+
vec4 tex2DFetch = texelFetch(tex2D, ivec2(0, 0), 0);
10+
vec4 texMSFetch = texelFetch(texMS, ivec2(0, 0), 0);
11+
12+
// Allowed by KHR_vulkan_glsl without the extension. All others should
13+
// error.
14+
vec4 bufFetch = texelFetch(buf, 0);
15+
16+
vec4 tex2DFetchOffset = texelFetchOffset(tex2D, ivec2(0, 0), 0, ivec2(0, 0));
17+
18+
ivec2 tex2DSize = textureSize(tex2D, 0);
19+
ivec2 texMSSize = textureSize(texMS);
20+
int bufSize = textureSize(buf);
21+
22+
int tex2DLevels = textureQueryLevels(tex2D);
23+
24+
int texMSSamples = textureSamples(texMS);
25+
}
26+
27+
#extension GL_EXT_samplerless_texture_functions : enable
28+
29+
void main()
30+
{
31+
// These should all succeed.
32+
33+
vec4 tex2DFetch = texelFetch(tex2D, ivec2(0, 0), 0);
34+
vec4 texMSFetch = texelFetch(texMS, ivec2(0, 0), 0);
35+
vec4 bufFetch = texelFetch(buf, 0);
36+
37+
vec4 tex2DFetchOffset = texelFetchOffset(tex2D, ivec2(0, 0), 0, ivec2(0, 0));
38+
39+
ivec2 tex2DSize = textureSize(tex2D, 0);
40+
ivec2 texMSSize = textureSize(texMS);
41+
int bufSize = textureSize(buf);
42+
43+
int tex2DLevels = textureQueryLevels(tex2D);
44+
45+
int texMSSamples = textureSamples(texMS);
46+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#version 450 core
2+
#extension GL_EXT_samplerless_texture_functions : enable
3+
4+
layout(binding = 1) uniform texture2D tex2D;
5+
layout(binding = 1) uniform texture2DMS texMS;
6+
layout(binding = 0) uniform textureBuffer buf;
7+
8+
void main()
9+
{
10+
vec4 tex2DFetch = texelFetch(tex2D, ivec2(0, 0), 0);
11+
vec4 texMSFetch = texelFetch(texMS, ivec2(0, 0), 0);
12+
vec4 bufFetch = texelFetch(buf, 0);
13+
14+
vec4 tex2DFetchOffset = texelFetchOffset(tex2D, ivec2(0, 0), 0, ivec2(0, 0));
15+
16+
ivec2 tex2DSize = textureSize(tex2D, 0);
17+
ivec2 texMSSize = textureSize(texMS);
18+
int bufSize = textureSize(buf);
19+
20+
int tex2DLevels = textureQueryLevels(tex2D);
21+
22+
int texMSSamples = textureSamples(texMS);
23+
}

glslang/MachineIndependent/Initialize.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5914,15 +5914,19 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
59145914
addSamplingFunctions(sampler, typeName, version, profile);
59155915
addGatherFunctions(sampler, typeName, version, profile);
59165916

5917-
if (spvVersion.vulkan > 0 && sampler.dim == EsdBuffer && sampler.isCombined()) {
5918-
// Vulkan wants a textureBuffer to allow texelFetch() --
5919-
// a sampled image with no sampler.
5920-
// So, add sampling functions for both the
5921-
// samplerBuffer and textureBuffer types.
5917+
if (spvVersion.vulkan > 0 && sampler.isCombined() && !sampler.shadow) {
5918+
// Base Vulkan allows texelFetch() for
5919+
// textureBuffer (i.e. without sampler).
5920+
//
5921+
// GL_EXT_samplerless_texture_functions
5922+
// allows texelFetch() and query functions
5923+
// (other than textureQueryLod()) for all
5924+
// texture types.
59225925
sampler.setTexture(sampler.type, sampler.dim, sampler.arrayed, sampler.shadow,
59235926
sampler.ms);
59245927
TString textureTypeName = sampler.getString();
59255928
addSamplingFunctions(sampler, textureTypeName, version, profile);
5929+
addQueryFunctions(sampler, textureTypeName, version, profile);
59265930
}
59275931
}
59285932
}
@@ -5995,7 +5999,7 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int
59955999
// textureQueryLod(), fragment stage only
59966000
//
59976001

5998-
if (profile != EEsProfile && version >= 400 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) {
6002+
if (profile != EEsProfile && version >= 400 && sampler.combined && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) {
59996003
#ifdef AMD_EXTENSIONS
60006004
for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) {
60016005
if (f16TexAddr && sampler.type != EbtFloat16)
@@ -6200,12 +6204,12 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
62006204
//
62016205
for (int proj = 0; proj <= 1; ++proj) { // loop over "bool" projective or not
62026206

6203-
if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms))
6207+
if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms || !sampler.combined))
62046208
continue;
62056209

62066210
for (int lod = 0; lod <= 1; ++lod) {
62076211

6208-
if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms))
6212+
if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms || !sampler.combined))
62096213
continue;
62106214
if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow)
62116215
continue;
@@ -6214,7 +6218,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
62146218

62156219
for (int bias = 0; bias <= 1; ++bias) {
62166220

6217-
if (bias && (lod || sampler.ms))
6221+
if (bias && (lod || sampler.ms || !sampler.combined))
62186222
continue;
62196223
if (bias && (sampler.dim == Esd2D || sampler.dim == EsdCube) && sampler.shadow && sampler.arrayed)
62206224
continue;
@@ -6236,12 +6240,12 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
62366240
continue;
62376241
if (fetch && (sampler.shadow || sampler.dim == EsdCube))
62386242
continue;
6239-
if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer))
6243+
if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer || !sampler.combined))
62406244
continue;
62416245

62426246
for (int grad = 0; grad <= 1; ++grad) { // loop over "bool" grad or not
62436247

6244-
if (grad && (lod || bias || sampler.ms))
6248+
if (grad && (lod || bias || sampler.ms || !sampler.combined))
62456249
continue;
62466250
if (grad && sampler.dim == EsdBuffer)
62476251
continue;
@@ -6263,7 +6267,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
62636267

62646268
if (extraProj && ! proj)
62656269
continue;
6266-
if (extraProj && (sampler.dim == Esd3D || sampler.shadow))
6270+
if (extraProj && (sampler.dim == Esd3D || sampler.shadow || !sampler.combined))
62676271
continue;
62686272
#ifdef AMD_EXTENSIONS
62696273
for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing

glslang/MachineIndependent/ParseHelper.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,31 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
17051705
break;
17061706
}
17071707

1708+
// Texture operations on texture objects (aside from texelFetch on a
1709+
// textureBuffer) require EXT_samplerless_texture_functions.
1710+
switch (callNode.getOp()) {
1711+
case EOpTextureQuerySize:
1712+
case EOpTextureQueryLevels:
1713+
case EOpTextureQuerySamples:
1714+
case EOpTextureFetch:
1715+
case EOpTextureFetchOffset:
1716+
{
1717+
const TSampler& sampler = fnCandidate[0].type->getSampler();
1718+
1719+
const bool isTexture = sampler.isTexture() && !sampler.isCombined();
1720+
const bool isBuffer = sampler.dim == EsdBuffer;
1721+
const bool isFetch = callNode.getOp() == EOpTextureFetch || callNode.getOp() == EOpTextureFetchOffset;
1722+
1723+
if (isTexture && (!isBuffer || !isFetch))
1724+
requireExtensions(loc, 1, &E_GL_EXT_samplerless_texture_functions, fnCandidate.getName().c_str());
1725+
1726+
break;
1727+
}
1728+
1729+
default:
1730+
break;
1731+
}
1732+
17081733
if (callNode.getOp() > EOpSubgroupGuardStart && callNode.getOp() < EOpSubgroupGuardStop) {
17091734
// these require SPIR-V 1.3
17101735
if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_3)

glslang/MachineIndependent/Versions.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ void TParseVersions::initializeExtensionBehavior()
200200
extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable;
201201
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
202202
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
203+
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
203204

204205
// #line and #include
205206
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
@@ -362,6 +363,7 @@ void TParseVersions::getPreamble(std::string& preamble)
362363
"#define GL_EXT_post_depth_coverage 1\n"
363364
"#define GL_EXT_control_flow_attributes 1\n"
364365
"#define GL_EXT_nonuniform_qualifier 1\n"
366+
"#define GL_EXT_samplerless_texture_functions 1\n"
365367

366368
// GL_KHR_shader_subgroup
367369
"#define GL_KHR_shader_subgroup_basic 1\n"

glslang/MachineIndependent/Versions.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,12 @@ const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_sha
153153
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
154154

155155
// EXT extensions
156-
const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
157-
const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
158-
const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage";
159-
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
160-
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
156+
const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
157+
const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
158+
const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage";
159+
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
160+
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
161+
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
161162

162163
// Arrays of extensions for the above viewportEXTs duplications
163164

gtests/Spv.FromFile.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ INSTANTIATE_TEST_CASE_P(
344344
"spv.xfb.vert",
345345
"spv.xfb2.vert",
346346
"spv.xfb3.vert",
347+
"spv.samplerlessTextureFunctions.frag",
347348
})),
348349
FileNameAsCustomTestSuffix
349350
);
@@ -433,6 +434,7 @@ INSTANTIATE_TEST_CASE_P(
433434
"vulkan.frag",
434435
"vulkan.vert",
435436
"vulkan.comp",
437+
"samplerlessTextureFunctions.frag",
436438
})),
437439
FileNameAsCustomTestSuffix
438440
);

0 commit comments

Comments
 (0)