Add support for GL_EXT_samplerless_texture_functions

This commit is contained in:
Alex Smith 2018-06-23 09:34:24 +01:00 committed by Alex Smith
parent 0b964b3c35
commit e47bfaedf6
10 changed files with 229 additions and 20 deletions

View File

@ -0,0 +1,13 @@
samplerlessTextureFunctions.frag
ERROR: 0:9: 'texelFetch' : required extension not requested: GL_EXT_samplerless_texture_functions
ERROR: 0:10: 'texelFetch' : required extension not requested: GL_EXT_samplerless_texture_functions
ERROR: 0:16: 'texelFetchOffset' : required extension not requested: GL_EXT_samplerless_texture_functions
ERROR: 0:18: 'textureSize' : required extension not requested: GL_EXT_samplerless_texture_functions
ERROR: 0:19: 'textureSize' : required extension not requested: GL_EXT_samplerless_texture_functions
ERROR: 0:20: 'textureSize' : required extension not requested: GL_EXT_samplerless_texture_functions
ERROR: 0:22: 'textureQueryLevels' : required extension not requested: GL_EXT_samplerless_texture_functions
ERROR: 0:24: 'textureSamples' : required extension not requested: GL_EXT_samplerless_texture_functions
ERROR: 8 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link

View File

@ -0,0 +1,93 @@
spv.samplerlessTextureFunctions.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 51
Capability Shader
Capability SampledBuffer
Capability ImageQuery
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
SourceExtension "GL_EXT_samplerless_texture_functions"
Name 4 "main"
Name 9 "tex2DFetch"
Name 12 "tex2D"
Name 19 "texMSFetch"
Name 22 "texMS"
Name 25 "bufFetch"
Name 28 "buf"
Name 31 "tex2DFetchOffset"
Name 35 "tex2DSize"
Name 38 "texMSSize"
Name 42 "bufSize"
Name 45 "tex2DLevels"
Name 48 "texMSSamples"
Decorate 12(tex2D) DescriptorSet 0
Decorate 12(tex2D) Binding 1
Decorate 22(texMS) DescriptorSet 0
Decorate 22(texMS) Binding 1
Decorate 28(buf) DescriptorSet 0
Decorate 28(buf) Binding 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Function 7(fvec4)
10: TypeImage 6(float) 2D sampled format:Unknown
11: TypePointer UniformConstant 10
12(tex2D): 11(ptr) Variable UniformConstant
14: TypeInt 32 1
15: TypeVector 14(int) 2
16: 14(int) Constant 0
17: 15(ivec2) ConstantComposite 16 16
20: TypeImage 6(float) 2D multi-sampled sampled format:Unknown
21: TypePointer UniformConstant 20
22(texMS): 21(ptr) Variable UniformConstant
26: TypeImage 6(float) Buffer sampled format:Unknown
27: TypePointer UniformConstant 26
28(buf): 27(ptr) Variable UniformConstant
34: TypePointer Function 15(ivec2)
41: TypePointer Function 14(int)
4(main): 2 Function None 3
5: Label
9(tex2DFetch): 8(ptr) Variable Function
19(texMSFetch): 8(ptr) Variable Function
25(bufFetch): 8(ptr) Variable Function
31(tex2DFetchOffset): 8(ptr) Variable Function
35(tex2DSize): 34(ptr) Variable Function
38(texMSSize): 34(ptr) Variable Function
42(bufSize): 41(ptr) Variable Function
45(tex2DLevels): 41(ptr) Variable Function
48(texMSSamples): 41(ptr) Variable Function
13: 10 Load 12(tex2D)
18: 7(fvec4) ImageFetch 13 17 Lod 16
Store 9(tex2DFetch) 18
23: 20 Load 22(texMS)
24: 7(fvec4) ImageFetch 23 17 Sample 16
Store 19(texMSFetch) 24
29: 26 Load 28(buf)
30: 7(fvec4) ImageFetch 29 16
Store 25(bufFetch) 30
32: 10 Load 12(tex2D)
33: 7(fvec4) ImageFetch 32 17 Lod ConstOffset 16 17
Store 31(tex2DFetchOffset) 33
36: 10 Load 12(tex2D)
37: 15(ivec2) ImageQuerySizeLod 36 16
Store 35(tex2DSize) 37
39: 20 Load 22(texMS)
40: 15(ivec2) ImageQuerySize 39
Store 38(texMSSize) 40
43: 26 Load 28(buf)
44: 14(int) ImageQuerySize 43
Store 42(bufSize) 44
46: 10 Load 12(tex2D)
47: 14(int) ImageQueryLevels 46
Store 45(tex2DLevels) 47
49: 20 Load 22(texMS)
50: 14(int) ImageQuerySamples 49
Store 48(texMSSamples) 50
Return
FunctionEnd

View File

@ -11,7 +11,7 @@ spv.specConstant.vert
Source GLSL 400 Source GLSL 400
Name 4 "main" Name 4 "main"
Name 9 "arraySize" Name 9 "arraySize"
Name 14 "foo(vf4[s2468];" Name 14 "foo(vf4[s2543];"
Name 13 "p" Name 13 "p"
Name 17 "builtin_spec_constant(" Name 17 "builtin_spec_constant("
Name 20 "color" Name 20 "color"
@ -102,10 +102,10 @@ spv.specConstant.vert
Store 20(color) 46 Store 20(color) 46
48: 10 Load 22(ucol) 48: 10 Load 22(ucol)
Store 47(param) 48 Store 47(param) 48
49: 2 FunctionCall 14(foo(vf4[s2468];) 47(param) 49: 2 FunctionCall 14(foo(vf4[s2543];) 47(param)
Return Return
FunctionEnd FunctionEnd
14(foo(vf4[s2468];): 2 Function None 12 14(foo(vf4[s2543];): 2 Function None 12
13(p): 11(ptr) FunctionParameter 13(p): 11(ptr) FunctionParameter
15: Label 15: Label
54: 24(ptr) AccessChain 53(dupUcol) 23 54: 24(ptr) AccessChain 53(dupUcol) 23

View File

@ -0,0 +1,46 @@
#version 450 core
layout(binding = 1) uniform texture2D tex2D;
layout(binding = 1) uniform texture2DMS texMS;
layout(binding = 0) uniform textureBuffer buf;
void testBad()
{
vec4 tex2DFetch = texelFetch(tex2D, ivec2(0, 0), 0);
vec4 texMSFetch = texelFetch(texMS, ivec2(0, 0), 0);
// Allowed by KHR_vulkan_glsl without the extension. All others should
// error.
vec4 bufFetch = texelFetch(buf, 0);
vec4 tex2DFetchOffset = texelFetchOffset(tex2D, ivec2(0, 0), 0, ivec2(0, 0));
ivec2 tex2DSize = textureSize(tex2D, 0);
ivec2 texMSSize = textureSize(texMS);
int bufSize = textureSize(buf);
int tex2DLevels = textureQueryLevels(tex2D);
int texMSSamples = textureSamples(texMS);
}
#extension GL_EXT_samplerless_texture_functions : enable
void main()
{
// These should all succeed.
vec4 tex2DFetch = texelFetch(tex2D, ivec2(0, 0), 0);
vec4 texMSFetch = texelFetch(texMS, ivec2(0, 0), 0);
vec4 bufFetch = texelFetch(buf, 0);
vec4 tex2DFetchOffset = texelFetchOffset(tex2D, ivec2(0, 0), 0, ivec2(0, 0));
ivec2 tex2DSize = textureSize(tex2D, 0);
ivec2 texMSSize = textureSize(texMS);
int bufSize = textureSize(buf);
int tex2DLevels = textureQueryLevels(tex2D);
int texMSSamples = textureSamples(texMS);
}

View File

@ -0,0 +1,23 @@
#version 450 core
#extension GL_EXT_samplerless_texture_functions : enable
layout(binding = 1) uniform texture2D tex2D;
layout(binding = 1) uniform texture2DMS texMS;
layout(binding = 0) uniform textureBuffer buf;
void main()
{
vec4 tex2DFetch = texelFetch(tex2D, ivec2(0, 0), 0);
vec4 texMSFetch = texelFetch(texMS, ivec2(0, 0), 0);
vec4 bufFetch = texelFetch(buf, 0);
vec4 tex2DFetchOffset = texelFetchOffset(tex2D, ivec2(0, 0), 0, ivec2(0, 0));
ivec2 tex2DSize = textureSize(tex2D, 0);
ivec2 texMSSize = textureSize(texMS);
int bufSize = textureSize(buf);
int tex2DLevels = textureQueryLevels(tex2D);
int texMSSamples = textureSamples(texMS);
}

View File

@ -5914,15 +5914,19 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
addSamplingFunctions(sampler, typeName, version, profile); addSamplingFunctions(sampler, typeName, version, profile);
addGatherFunctions(sampler, typeName, version, profile); addGatherFunctions(sampler, typeName, version, profile);
if (spvVersion.vulkan > 0 && sampler.dim == EsdBuffer && sampler.isCombined()) { if (spvVersion.vulkan > 0 && sampler.isCombined() && !sampler.shadow) {
// Vulkan wants a textureBuffer to allow texelFetch() -- // Base Vulkan allows texelFetch() for
// a sampled image with no sampler. // textureBuffer (i.e. without sampler).
// So, add sampling functions for both the //
// samplerBuffer and textureBuffer types. // GL_EXT_samplerless_texture_functions
// allows texelFetch() and query functions
// (other than textureQueryLod()) for all
// texture types.
sampler.setTexture(sampler.type, sampler.dim, sampler.arrayed, sampler.shadow, sampler.setTexture(sampler.type, sampler.dim, sampler.arrayed, sampler.shadow,
sampler.ms); sampler.ms);
TString textureTypeName = sampler.getString(); TString textureTypeName = sampler.getString();
addSamplingFunctions(sampler, textureTypeName, version, profile); addSamplingFunctions(sampler, textureTypeName, version, profile);
addQueryFunctions(sampler, textureTypeName, version, profile);
} }
} }
} }
@ -5995,7 +5999,7 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int
// textureQueryLod(), fragment stage only // textureQueryLod(), fragment stage only
// //
if (profile != EEsProfile && version >= 400 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { if (profile != EEsProfile && version >= 400 && sampler.combined && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) {
#ifdef AMD_EXTENSIONS #ifdef AMD_EXTENSIONS
for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) { for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) {
if (f16TexAddr && sampler.type != EbtFloat16) if (f16TexAddr && sampler.type != EbtFloat16)
@ -6200,12 +6204,12 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
// //
for (int proj = 0; proj <= 1; ++proj) { // loop over "bool" projective or not for (int proj = 0; proj <= 1; ++proj) { // loop over "bool" projective or not
if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms)) if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms || !sampler.combined))
continue; continue;
for (int lod = 0; lod <= 1; ++lod) { for (int lod = 0; lod <= 1; ++lod) {
if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms)) if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms || !sampler.combined))
continue; continue;
if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow) if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow)
continue; continue;
@ -6214,7 +6218,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
for (int bias = 0; bias <= 1; ++bias) { for (int bias = 0; bias <= 1; ++bias) {
if (bias && (lod || sampler.ms)) if (bias && (lod || sampler.ms || !sampler.combined))
continue; continue;
if (bias && (sampler.dim == Esd2D || sampler.dim == EsdCube) && sampler.shadow && sampler.arrayed) if (bias && (sampler.dim == Esd2D || sampler.dim == EsdCube) && sampler.shadow && sampler.arrayed)
continue; continue;
@ -6236,12 +6240,12 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
continue; continue;
if (fetch && (sampler.shadow || sampler.dim == EsdCube)) if (fetch && (sampler.shadow || sampler.dim == EsdCube))
continue; continue;
if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer)) if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer || !sampler.combined))
continue; continue;
for (int grad = 0; grad <= 1; ++grad) { // loop over "bool" grad or not for (int grad = 0; grad <= 1; ++grad) { // loop over "bool" grad or not
if (grad && (lod || bias || sampler.ms)) if (grad && (lod || bias || sampler.ms || !sampler.combined))
continue; continue;
if (grad && sampler.dim == EsdBuffer) if (grad && sampler.dim == EsdBuffer)
continue; continue;
@ -6263,7 +6267,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
if (extraProj && ! proj) if (extraProj && ! proj)
continue; continue;
if (extraProj && (sampler.dim == Esd3D || sampler.shadow)) if (extraProj && (sampler.dim == Esd3D || sampler.shadow || !sampler.combined))
continue; continue;
#ifdef AMD_EXTENSIONS #ifdef AMD_EXTENSIONS
for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing

View File

@ -1705,6 +1705,31 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
break; break;
} }
// Texture operations on texture objects (aside from texelFetch on a
// textureBuffer) require EXT_samplerless_texture_functions.
switch (callNode.getOp()) {
case EOpTextureQuerySize:
case EOpTextureQueryLevels:
case EOpTextureQuerySamples:
case EOpTextureFetch:
case EOpTextureFetchOffset:
{
const TSampler& sampler = fnCandidate[0].type->getSampler();
const bool isTexture = sampler.isTexture() && !sampler.isCombined();
const bool isBuffer = sampler.dim == EsdBuffer;
const bool isFetch = callNode.getOp() == EOpTextureFetch || callNode.getOp() == EOpTextureFetchOffset;
if (isTexture && (!isBuffer || !isFetch))
requireExtensions(loc, 1, &E_GL_EXT_samplerless_texture_functions, fnCandidate.getName().c_str());
break;
}
default:
break;
}
if (callNode.getOp() > EOpSubgroupGuardStart && callNode.getOp() < EOpSubgroupGuardStop) { if (callNode.getOp() > EOpSubgroupGuardStart && callNode.getOp() < EOpSubgroupGuardStop) {
// these require SPIR-V 1.3 // these require SPIR-V 1.3
if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_3) if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_3)

View File

@ -200,6 +200,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable; extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable;
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable; extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable; extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
// #line and #include // #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable; extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
@ -362,6 +363,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_post_depth_coverage 1\n" "#define GL_EXT_post_depth_coverage 1\n"
"#define GL_EXT_control_flow_attributes 1\n" "#define GL_EXT_control_flow_attributes 1\n"
"#define GL_EXT_nonuniform_qualifier 1\n" "#define GL_EXT_nonuniform_qualifier 1\n"
"#define GL_EXT_samplerless_texture_functions 1\n"
// GL_KHR_shader_subgroup // GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n" "#define GL_KHR_shader_subgroup_basic 1\n"

View File

@ -153,11 +153,12 @@ const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_sha
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted"; const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
// EXT extensions // EXT extensions
const char* const E_GL_EXT_device_group = "GL_EXT_device_group"; const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
const char* const E_GL_EXT_multiview = "GL_EXT_multiview"; const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage"; const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage";
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes"; const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier"; const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
// Arrays of extensions for the above viewportEXTs duplications // Arrays of extensions for the above viewportEXTs duplications

View File

@ -344,6 +344,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.xfb.vert", "spv.xfb.vert",
"spv.xfb2.vert", "spv.xfb2.vert",
"spv.xfb3.vert", "spv.xfb3.vert",
"spv.samplerlessTextureFunctions.frag",
})), })),
FileNameAsCustomTestSuffix FileNameAsCustomTestSuffix
); );
@ -433,6 +434,7 @@ INSTANTIATE_TEST_CASE_P(
"vulkan.frag", "vulkan.frag",
"vulkan.vert", "vulkan.vert",
"vulkan.comp", "vulkan.comp",
"samplerlessTextureFunctions.frag",
})), })),
FileNameAsCustomTestSuffix FileNameAsCustomTestSuffix
); );