mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 11:30:06 +00:00
[glslang][EXT] Support extension ARB_bindless_texture.
Add missing callgraph clean for bindless status flag. Add test cases. Add support to check special extensions not be available for Vulkan when using GLSL.
This commit is contained in:
parent
2b2523fb95
commit
16526fd9d2
@ -1293,7 +1293,7 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
|
||||
type.getQualifier().storage == glslang::EvqUniform) {
|
||||
if (type.isAtomic())
|
||||
return spv::StorageClassAtomicCounter;
|
||||
if (type.containsOpaque())
|
||||
if (type.containsOpaque() && !glslangIntermediate->getBindlessMode())
|
||||
return spv::StorageClassUniformConstant;
|
||||
}
|
||||
|
||||
@ -5083,7 +5083,7 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
|
||||
return true;
|
||||
if (glslangIntermediate->getSource() == glslang::EShSourceHlsl)
|
||||
return paramType.getBasicType() == glslang::EbtBlock;
|
||||
return paramType.containsOpaque() || // sampler, etc.
|
||||
return (paramType.containsOpaque() && !glslangIntermediate->getBindlessMode()) || // sampler, etc.
|
||||
#ifndef GLSLANG_WEB
|
||||
paramType.getQualifier().isSpirvByReference() || // spirv_by_reference
|
||||
#endif
|
||||
|
50
Test/GL_ARB_bindless_texture.frag
Normal file
50
Test/GL_ARB_bindless_texture.frag
Normal file
@ -0,0 +1,50 @@
|
||||
#version 460 compatibility
|
||||
|
||||
#extension GL_ARB_bindless_texture: require
|
||||
|
||||
#if !defined GL_ARB_bindless_texture
|
||||
# error GL_ARB_bindless_texture is not defined
|
||||
#elif GL_ARB_bindless_texture != 1
|
||||
# error GL_ARB_bindless_texture is not equal to 1
|
||||
#endif
|
||||
|
||||
// Valid usage cases
|
||||
layout(bindless_sampler) uniform sampler2D s0; // case0: bindless layout
|
||||
in sampler2D s1; // case1: sampler as an input
|
||||
uniform uvec2 s2; // case2: uvec2 as sampler constructor
|
||||
uniform ivec2 s3; // case3: ivec2 as sampler constructor
|
||||
uniform int index;
|
||||
in sampler2D s4[2][3]; // case4: sampler arrays of arrays
|
||||
uniform BB {sampler2D s5;} bbs5[2]; // case5: uniform block member as a sampler
|
||||
in samplerBuffer s6; // case6: samplerBuffer input
|
||||
uniform UBO9 {samplerBuffer s7;}; // case7: samplerBuffer as an uniform block member
|
||||
buffer SSBO10 {samplerBuffer s8;}; // case8: samplerBuffer as an ssbo member
|
||||
layout(rgba8, bindless_image) in image2D i9; // case9: bindless image as an input
|
||||
|
||||
|
||||
uniform vec2 coord; // bindless coord 2-D
|
||||
uniform int icoord; // bindless coord 1-D
|
||||
out vec4 color0;
|
||||
out vec4 color1;
|
||||
out vec4 color2;
|
||||
out vec4 color3;
|
||||
out vec4 color4;
|
||||
out vec4 color5;
|
||||
out vec4 color6;
|
||||
out vec4 color7;
|
||||
out vec4 color8;
|
||||
out vec4 color9;
|
||||
|
||||
void main()
|
||||
{
|
||||
color0 = texture(s0, coord);
|
||||
color1 = texture(s1, coord);
|
||||
color2 = texture(sampler2D(s2), coord);
|
||||
color3 = texture(sampler2D(s3), coord);
|
||||
color4 = texture(s4[index][index], coord);
|
||||
color5 = texture(bbs5[index].s5, coord);
|
||||
color6 = texelFetch(s6, icoord);
|
||||
color7 = texelFetch(s7, icoord);
|
||||
color8 = texelFetch(s8, icoord);
|
||||
color9 = imageLoad(i9, ivec2(0,0));
|
||||
}
|
205
Test/baseResults/GL_ARB_bindless_texture.frag.out
Normal file
205
Test/baseResults/GL_ARB_bindless_texture.frag.out
Normal file
@ -0,0 +1,205 @@
|
||||
GL_ARB_bindless_texture.frag
|
||||
Shader version: 460
|
||||
Requested GL_ARB_bindless_texture
|
||||
0:? Sequence
|
||||
0:38 Function Definition: main( ( global void)
|
||||
0:38 Function Parameters:
|
||||
0:40 Sequence
|
||||
0:40 move second child to first child ( temp 4-component vector of float)
|
||||
0:40 'color0' ( out 4-component vector of float)
|
||||
0:40 texture ( global 4-component vector of float)
|
||||
0:40 's0' ( uniform sampler2D)
|
||||
0:40 'coord' ( uniform 2-component vector of float)
|
||||
0:41 move second child to first child ( temp 4-component vector of float)
|
||||
0:41 'color1' ( out 4-component vector of float)
|
||||
0:41 texture ( global 4-component vector of float)
|
||||
0:41 's1' ( smooth in sampler2D)
|
||||
0:41 'coord' ( uniform 2-component vector of float)
|
||||
0:42 move second child to first child ( temp 4-component vector of float)
|
||||
0:42 'color2' ( out 4-component vector of float)
|
||||
0:42 texture ( global 4-component vector of float)
|
||||
0:42 packUint2x32 ( temp sampler2D)
|
||||
0:42 's2' ( uniform 2-component vector of uint)
|
||||
0:42 'coord' ( uniform 2-component vector of float)
|
||||
0:43 move second child to first child ( temp 4-component vector of float)
|
||||
0:43 'color3' ( out 4-component vector of float)
|
||||
0:43 texture ( global 4-component vector of float)
|
||||
0:43 packUint2x32 ( temp sampler2D)
|
||||
0:43 's3' ( uniform 2-component vector of int)
|
||||
0:43 'coord' ( uniform 2-component vector of float)
|
||||
0:44 move second child to first child ( temp 4-component vector of float)
|
||||
0:44 'color4' ( out 4-component vector of float)
|
||||
0:44 texture ( global 4-component vector of float)
|
||||
0:44 indirect index ( smooth temp sampler2D)
|
||||
0:44 indirect index ( smooth temp 3-element array of sampler2D)
|
||||
0:44 's4' ( smooth in 2-element array of 3-element array of sampler2D)
|
||||
0:44 'index' ( uniform int)
|
||||
0:44 'index' ( uniform int)
|
||||
0:44 'coord' ( uniform 2-component vector of float)
|
||||
0:45 move second child to first child ( temp 4-component vector of float)
|
||||
0:45 'color5' ( out 4-component vector of float)
|
||||
0:45 texture ( global 4-component vector of float)
|
||||
0:45 s5: direct index for structure (layout( column_major shared layoutBindlessSampler) uniform sampler2D)
|
||||
0:45 indirect index (layout( column_major shared) temp block{layout( column_major shared layoutBindlessSampler) uniform sampler2D s5})
|
||||
0:45 'bbs5' (layout( column_major shared) uniform 2-element array of block{layout( column_major shared layoutBindlessSampler) uniform sampler2D s5})
|
||||
0:45 'index' ( uniform int)
|
||||
0:45 Constant:
|
||||
0:45 0 (const int)
|
||||
0:45 'coord' ( uniform 2-component vector of float)
|
||||
0:46 move second child to first child ( temp 4-component vector of float)
|
||||
0:46 'color6' ( out 4-component vector of float)
|
||||
0:46 textureFetch ( global 4-component vector of float)
|
||||
0:46 's6' ( smooth in samplerBuffer)
|
||||
0:46 'icoord' ( uniform int)
|
||||
0:47 move second child to first child ( temp 4-component vector of float)
|
||||
0:47 'color7' ( out 4-component vector of float)
|
||||
0:47 textureFetch ( global 4-component vector of float)
|
||||
0:47 s7: direct index for structure (layout( column_major shared layoutBindlessSampler) uniform samplerBuffer)
|
||||
0:47 'anon@0' (layout( column_major shared) uniform block{layout( column_major shared layoutBindlessSampler) uniform samplerBuffer s7})
|
||||
0:47 Constant:
|
||||
0:47 0 (const uint)
|
||||
0:47 'icoord' ( uniform int)
|
||||
0:48 move second child to first child ( temp 4-component vector of float)
|
||||
0:48 'color8' ( out 4-component vector of float)
|
||||
0:48 textureFetch ( global 4-component vector of float)
|
||||
0:48 s8: direct index for structure (layout( column_major shared layoutBindlessSampler) buffer samplerBuffer)
|
||||
0:48 'anon@1' (layout( column_major shared) buffer block{layout( column_major shared layoutBindlessSampler) buffer samplerBuffer s8})
|
||||
0:48 Constant:
|
||||
0:48 0 (const uint)
|
||||
0:48 'icoord' ( uniform int)
|
||||
0:49 move second child to first child ( temp 4-component vector of float)
|
||||
0:49 'color9' ( out 4-component vector of float)
|
||||
0:49 imageLoad ( global 4-component vector of float)
|
||||
0:49 'i9' (layout( rgba8 layoutBindlessImage) smooth in image2D)
|
||||
0:49 Constant:
|
||||
0:49 0 (const int)
|
||||
0:49 0 (const int)
|
||||
0:? Linker Objects
|
||||
0:? 's0' ( uniform sampler2D)
|
||||
0:? 's1' ( smooth in sampler2D)
|
||||
0:? 's2' ( uniform 2-component vector of uint)
|
||||
0:? 's3' ( uniform 2-component vector of int)
|
||||
0:? 'index' ( uniform int)
|
||||
0:? 's4' ( smooth in 2-element array of 3-element array of sampler2D)
|
||||
0:? 'bbs5' (layout( column_major shared) uniform 2-element array of block{layout( column_major shared layoutBindlessSampler) uniform sampler2D s5})
|
||||
0:? 's6' ( smooth in samplerBuffer)
|
||||
0:? 'anon@0' (layout( column_major shared) uniform block{layout( column_major shared layoutBindlessSampler) uniform samplerBuffer s7})
|
||||
0:? 'anon@1' (layout( column_major shared) buffer block{layout( column_major shared layoutBindlessSampler) buffer samplerBuffer s8})
|
||||
0:? 'i9' (layout( rgba8 layoutBindlessImage) smooth in image2D)
|
||||
0:? 'coord' ( uniform 2-component vector of float)
|
||||
0:? 'icoord' ( uniform int)
|
||||
0:? 'color0' ( out 4-component vector of float)
|
||||
0:? 'color1' ( out 4-component vector of float)
|
||||
0:? 'color2' ( out 4-component vector of float)
|
||||
0:? 'color3' ( out 4-component vector of float)
|
||||
0:? 'color4' ( out 4-component vector of float)
|
||||
0:? 'color5' ( out 4-component vector of float)
|
||||
0:? 'color6' ( out 4-component vector of float)
|
||||
0:? 'color7' ( out 4-component vector of float)
|
||||
0:? 'color8' ( out 4-component vector of float)
|
||||
0:? 'color9' ( out 4-component vector of float)
|
||||
|
||||
|
||||
Linked fragment stage:
|
||||
|
||||
|
||||
Shader version: 460
|
||||
Requested GL_ARB_bindless_texture
|
||||
0:? Sequence
|
||||
0:38 Function Definition: main( ( global void)
|
||||
0:38 Function Parameters:
|
||||
0:40 Sequence
|
||||
0:40 move second child to first child ( temp 4-component vector of float)
|
||||
0:40 'color0' ( out 4-component vector of float)
|
||||
0:40 texture ( global 4-component vector of float)
|
||||
0:40 's0' ( uniform sampler2D)
|
||||
0:40 'coord' ( uniform 2-component vector of float)
|
||||
0:41 move second child to first child ( temp 4-component vector of float)
|
||||
0:41 'color1' ( out 4-component vector of float)
|
||||
0:41 texture ( global 4-component vector of float)
|
||||
0:41 's1' ( smooth in sampler2D)
|
||||
0:41 'coord' ( uniform 2-component vector of float)
|
||||
0:42 move second child to first child ( temp 4-component vector of float)
|
||||
0:42 'color2' ( out 4-component vector of float)
|
||||
0:42 texture ( global 4-component vector of float)
|
||||
0:42 packUint2x32 ( temp sampler2D)
|
||||
0:42 's2' ( uniform 2-component vector of uint)
|
||||
0:42 'coord' ( uniform 2-component vector of float)
|
||||
0:43 move second child to first child ( temp 4-component vector of float)
|
||||
0:43 'color3' ( out 4-component vector of float)
|
||||
0:43 texture ( global 4-component vector of float)
|
||||
0:43 packUint2x32 ( temp sampler2D)
|
||||
0:43 's3' ( uniform 2-component vector of int)
|
||||
0:43 'coord' ( uniform 2-component vector of float)
|
||||
0:44 move second child to first child ( temp 4-component vector of float)
|
||||
0:44 'color4' ( out 4-component vector of float)
|
||||
0:44 texture ( global 4-component vector of float)
|
||||
0:44 indirect index ( smooth temp sampler2D)
|
||||
0:44 indirect index ( smooth temp 3-element array of sampler2D)
|
||||
0:44 's4' ( smooth in 2-element array of 3-element array of sampler2D)
|
||||
0:44 'index' ( uniform int)
|
||||
0:44 'index' ( uniform int)
|
||||
0:44 'coord' ( uniform 2-component vector of float)
|
||||
0:45 move second child to first child ( temp 4-component vector of float)
|
||||
0:45 'color5' ( out 4-component vector of float)
|
||||
0:45 texture ( global 4-component vector of float)
|
||||
0:45 s5: direct index for structure (layout( column_major shared layoutBindlessSampler) uniform sampler2D)
|
||||
0:45 indirect index (layout( column_major shared) temp block{layout( column_major shared layoutBindlessSampler) uniform sampler2D s5})
|
||||
0:45 'bbs5' (layout( column_major shared) uniform 2-element array of block{layout( column_major shared layoutBindlessSampler) uniform sampler2D s5})
|
||||
0:45 'index' ( uniform int)
|
||||
0:45 Constant:
|
||||
0:45 0 (const int)
|
||||
0:45 'coord' ( uniform 2-component vector of float)
|
||||
0:46 move second child to first child ( temp 4-component vector of float)
|
||||
0:46 'color6' ( out 4-component vector of float)
|
||||
0:46 textureFetch ( global 4-component vector of float)
|
||||
0:46 's6' ( smooth in samplerBuffer)
|
||||
0:46 'icoord' ( uniform int)
|
||||
0:47 move second child to first child ( temp 4-component vector of float)
|
||||
0:47 'color7' ( out 4-component vector of float)
|
||||
0:47 textureFetch ( global 4-component vector of float)
|
||||
0:47 s7: direct index for structure (layout( column_major shared layoutBindlessSampler) uniform samplerBuffer)
|
||||
0:47 'anon@0' (layout( column_major shared) uniform block{layout( column_major shared layoutBindlessSampler) uniform samplerBuffer s7})
|
||||
0:47 Constant:
|
||||
0:47 0 (const uint)
|
||||
0:47 'icoord' ( uniform int)
|
||||
0:48 move second child to first child ( temp 4-component vector of float)
|
||||
0:48 'color8' ( out 4-component vector of float)
|
||||
0:48 textureFetch ( global 4-component vector of float)
|
||||
0:48 s8: direct index for structure (layout( column_major shared layoutBindlessSampler) buffer samplerBuffer)
|
||||
0:48 'anon@1' (layout( column_major shared) buffer block{layout( column_major shared layoutBindlessSampler) buffer samplerBuffer s8})
|
||||
0:48 Constant:
|
||||
0:48 0 (const uint)
|
||||
0:48 'icoord' ( uniform int)
|
||||
0:49 move second child to first child ( temp 4-component vector of float)
|
||||
0:49 'color9' ( out 4-component vector of float)
|
||||
0:49 imageLoad ( global 4-component vector of float)
|
||||
0:49 'i9' (layout( rgba8 layoutBindlessImage) smooth in image2D)
|
||||
0:49 Constant:
|
||||
0:49 0 (const int)
|
||||
0:49 0 (const int)
|
||||
0:? Linker Objects
|
||||
0:? 's0' ( uniform sampler2D)
|
||||
0:? 's1' ( smooth in sampler2D)
|
||||
0:? 's2' ( uniform 2-component vector of uint)
|
||||
0:? 's3' ( uniform 2-component vector of int)
|
||||
0:? 'index' ( uniform int)
|
||||
0:? 's4' ( smooth in 2-element array of 3-element array of sampler2D)
|
||||
0:? 'bbs5' (layout( column_major shared) uniform 2-element array of block{layout( column_major shared layoutBindlessSampler) uniform sampler2D s5})
|
||||
0:? 's6' ( smooth in samplerBuffer)
|
||||
0:? 'anon@0' (layout( column_major shared) uniform block{layout( column_major shared layoutBindlessSampler) uniform samplerBuffer s7})
|
||||
0:? 'anon@1' (layout( column_major shared) buffer block{layout( column_major shared layoutBindlessSampler) buffer samplerBuffer s8})
|
||||
0:? 'i9' (layout( rgba8 layoutBindlessImage) smooth in image2D)
|
||||
0:? 'coord' ( uniform 2-component vector of float)
|
||||
0:? 'icoord' ( uniform int)
|
||||
0:? 'color0' ( out 4-component vector of float)
|
||||
0:? 'color1' ( out 4-component vector of float)
|
||||
0:? 'color2' ( out 4-component vector of float)
|
||||
0:? 'color3' ( out 4-component vector of float)
|
||||
0:? 'color4' ( out 4-component vector of float)
|
||||
0:? 'color5' ( out 4-component vector of float)
|
||||
0:? 'color6' ( out 4-component vector of float)
|
||||
0:? 'color7' ( out 4-component vector of float)
|
||||
0:? 'color8' ( out 4-component vector of float)
|
||||
0:? 'color9' ( out 4-component vector of float)
|
||||
|
@ -6,7 +6,7 @@ ERROR: 0:6: 'binding' : sampler/texture/image requires layout(binding=X)
|
||||
ERROR: 0:8: 'binding' : sampler/texture/image requires layout(binding=X)
|
||||
ERROR: 0:9: 'binding' : sampler/texture/image requires layout(binding=X)
|
||||
ERROR: 0:10: 'binding' : sampler/texture/image requires layout(binding=X)
|
||||
ERROR: 0:14: 'sampler2D' : sampler-constructor requires two arguments
|
||||
ERROR: 0:14: 'sampler2D' : sampler-constructor requires the extension GL_ARB_bindless_texture enabled
|
||||
ERROR: 0:15: 'sampler2D' : sampler-constructor first argument must be a scalar *texture* type
|
||||
ERROR: 0:16: 'sampler2D' : sampler-constructor first argument must be a scalar *texture* type
|
||||
ERROR: 0:17: 'sampler2D' : sampler-constructor second argument must be a scalar sampler or samplerShadow
|
||||
|
@ -429,6 +429,12 @@ enum TLayoutFormat {
|
||||
ElfR16ui,
|
||||
ElfR8ui,
|
||||
ElfR64ui,
|
||||
ElfExtSizeGuard, // to help with comparisons
|
||||
ElfSize1x8,
|
||||
ElfSize1x16,
|
||||
ElfSize1x32,
|
||||
ElfSize2x32,
|
||||
ElfSize4x32,
|
||||
|
||||
ElfCount
|
||||
};
|
||||
@ -898,6 +904,8 @@ public:
|
||||
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
|
||||
layoutSecondaryViewportRelativeOffset = -2048;
|
||||
layoutShaderRecord = false;
|
||||
layoutBindlessSampler = false;
|
||||
layoutBindlessImage = false;
|
||||
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
|
||||
layoutFormat = ElfNone;
|
||||
#endif
|
||||
@ -1001,6 +1009,9 @@ public:
|
||||
// GL_EXT_spirv_intrinsics
|
||||
int spirvStorageClass;
|
||||
TSpirvDecorate* spirvDecorate;
|
||||
|
||||
bool layoutBindlessSampler;
|
||||
bool layoutBindlessImage;
|
||||
#endif
|
||||
|
||||
bool hasUniformLayout() const
|
||||
@ -1132,6 +1143,14 @@ public:
|
||||
{
|
||||
return nonUniform;
|
||||
}
|
||||
bool isBindlessSampler() const
|
||||
{
|
||||
return layoutBindlessSampler;
|
||||
}
|
||||
bool isBindlessImage() const
|
||||
{
|
||||
return layoutBindlessImage;
|
||||
}
|
||||
|
||||
// GL_EXT_spirv_intrinsics
|
||||
bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
|
||||
@ -1241,6 +1260,11 @@ public:
|
||||
case ElfR8ui: return "r8ui";
|
||||
case ElfR64ui: return "r64ui";
|
||||
case ElfR64i: return "r64i";
|
||||
case ElfSize1x8: return "size1x8";
|
||||
case ElfSize1x16: return "size1x16";
|
||||
case ElfSize1x32: return "size1x32";
|
||||
case ElfSize2x32: return "size2x32";
|
||||
case ElfSize4x32: return "size4x32";
|
||||
default: return "none";
|
||||
}
|
||||
}
|
||||
@ -1898,6 +1922,8 @@ public:
|
||||
virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); }
|
||||
virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); }
|
||||
virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); }
|
||||
virtual bool isBindlessImage() const { return isImage() && qualifier.layoutBindlessImage; }
|
||||
virtual bool isBindlessTexture() const { return isTexture() && qualifier.layoutBindlessSampler; }
|
||||
// Check the block-name convention of creating a block without populating it's members:
|
||||
virtual bool isUnusableName() const { return isStruct() && structure == nullptr; }
|
||||
virtual bool isParameterized() const { return typeParameters != nullptr; }
|
||||
@ -1954,6 +1980,11 @@ public:
|
||||
return contains([](const TType* t) { return t->isOpaque(); } );
|
||||
}
|
||||
|
||||
virtual bool containsSampler() const
|
||||
{
|
||||
return contains([](const TType* t) { return t->isTexture() || t->isImage(); });
|
||||
}
|
||||
|
||||
// Recursively checks if the type contains a built-in variable
|
||||
virtual bool containsBuiltIn() const
|
||||
{
|
||||
@ -2285,7 +2316,10 @@ public:
|
||||
}
|
||||
if (qualifier.layoutShaderRecord)
|
||||
appendStr(" shaderRecordNV");
|
||||
|
||||
if (qualifier.layoutBindlessSampler)
|
||||
appendStr(" layoutBindlessSampler");
|
||||
if (qualifier.layoutBindlessImage)
|
||||
appendStr(" layoutBindlessImage");
|
||||
appendStr(")");
|
||||
}
|
||||
}
|
||||
@ -2544,6 +2578,7 @@ public:
|
||||
void setStruct(TTypeList* s) { assert(isStruct()); structure = s; }
|
||||
TTypeList* getWritableStruct() const { assert(isStruct()); return structure; } // This should only be used when known to not be sharing with other threads
|
||||
void setBasicType(const TBasicType& t) { basicType = t; }
|
||||
void setVectorSize(int s) { vectorSize = s; }
|
||||
|
||||
int computeNumComponents() const
|
||||
{
|
||||
|
@ -751,6 +751,11 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne
|
||||
case EbtInt64: newOp = EOpConvInt64ToUint; break;
|
||||
case EbtUint64: newOp = EOpConvUint64ToUint; break;
|
||||
#endif
|
||||
// For bindless texture type conversion, add a dummy convert op, just
|
||||
// to generate a new TIntermTyped
|
||||
// uvec2(any sampler type)
|
||||
// uvec2(any image type)
|
||||
case EbtSampler: newOp = EOpConvIntToUint; break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -159,7 +159,8 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
||||
//
|
||||
switch (node->getBasicType()) {
|
||||
case EbtSampler:
|
||||
message = "can't modify a sampler";
|
||||
if (extensionTurnedOn(E_GL_ARB_bindless_texture) == false)
|
||||
message = "can't modify a sampler";
|
||||
break;
|
||||
case EbtVoid:
|
||||
message = "can't modify void";
|
||||
|
@ -1389,7 +1389,8 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
|
||||
#endif
|
||||
const TType& argType = arg->getAsTyped()->getType();
|
||||
const TQualifier& argQualifier = argType.getQualifier();
|
||||
if (argQualifier.isMemory() && (argType.containsOpaque() || argType.isReference())) {
|
||||
bool containsBindlessSampler = intermediate.getBindlessMode() && argType.containsSampler();
|
||||
if (argQualifier.isMemory() && !containsBindlessSampler && (argType.containsOpaque() || argType.isReference())) {
|
||||
const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
|
||||
#ifndef GLSLANG_WEB
|
||||
if (argQualifier.volatil && ! formalQualifier.volatil)
|
||||
@ -1675,9 +1676,13 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType
|
||||
error(loc, "type does not match, or is not convertible to, the function's return type", "return", "");
|
||||
branch = intermediate.addBranch(EOpReturn, value, loc);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
if (value->getType().isTexture() || value->getType().isImage()) {
|
||||
if (!extensionTurnedOn(E_GL_ARB_bindless_texture))
|
||||
error(loc, "sampler or image can be used as return type only when the extension GL_ARB_bindless_texture enabled", "return", "");
|
||||
}
|
||||
branch = intermediate.addBranch(EOpReturn, value, loc);
|
||||
|
||||
}
|
||||
branch->updatePrecision(currentFunctionType->getQualifier().precision);
|
||||
return branch;
|
||||
}
|
||||
@ -1928,6 +1933,9 @@ TIntermTyped* TParseContext::addAssign(const TSourceLoc& loc, TOperator op, TInt
|
||||
if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference())
|
||||
requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "+= and -= on a buffer reference");
|
||||
|
||||
if (op == EOpAssign && left->getBasicType() == EbtSampler && right->getBasicType() == EbtSampler)
|
||||
requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "sampler assignment for bindless texture");
|
||||
|
||||
return intermediate.addAssign(op, left, right, loc);
|
||||
}
|
||||
|
||||
@ -2811,6 +2819,14 @@ TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPu
|
||||
profileRequires(loc, EEsProfile, 300, nullptr, "arrayed constructor");
|
||||
}
|
||||
|
||||
// Reuse EOpConstructTextureSampler for bindless image constructor
|
||||
// uvec2 imgHandle;
|
||||
// imageLoad(image1D(imgHandle), 0);
|
||||
if (type.isImage() && extensionTurnedOn(E_GL_ARB_bindless_texture))
|
||||
{
|
||||
intermediate.setBindlessImageMode(currentCaller, AstRefTypeFunc);
|
||||
}
|
||||
|
||||
TOperator op = intermediate.mapTypeToConstructorOp(type);
|
||||
|
||||
if (op == EOpNull) {
|
||||
@ -3544,8 +3560,13 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
||||
return true;
|
||||
}
|
||||
if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) {
|
||||
error(loc, "cannot convert a sampler", constructorString.c_str(), "");
|
||||
return true;
|
||||
if (op == EOpConstructUVec2 && extensionTurnedOn(E_GL_ARB_bindless_texture)) {
|
||||
intermediate.setBindlessTextureMode(currentCaller, AstRefTypeFunc);
|
||||
}
|
||||
else {
|
||||
error(loc, "cannot convert a sampler", constructorString.c_str(), "");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (op != EOpConstructStruct && typed->isAtomic()) {
|
||||
error(loc, "cannot convert an atomic_uint", constructorString.c_str(), "");
|
||||
@ -3565,6 +3586,26 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const
|
||||
{
|
||||
TString constructorName = function.getType().getBasicTypeString(); // TODO: performance: should not be making copy; interface needs to change
|
||||
const char* token = constructorName.c_str();
|
||||
// verify the constructor for bindless texture, the input must be ivec2 or uvec2
|
||||
if (function.getParamCount() == 1) {
|
||||
TType* pType = function[0].type;
|
||||
TBasicType basicType = pType->getBasicType();
|
||||
bool isIntegerVec2 = ((basicType == EbtUint || basicType == EbtInt) && pType->getVectorSize() == 2);
|
||||
bool bindlessMode = extensionTurnedOn(E_GL_ARB_bindless_texture);
|
||||
if (isIntegerVec2 && bindlessMode) {
|
||||
if (pType->getSampler().isImage())
|
||||
intermediate.setBindlessImageMode(currentCaller, AstRefTypeFunc);
|
||||
else
|
||||
intermediate.setBindlessTextureMode(currentCaller, AstRefTypeFunc);
|
||||
return false;
|
||||
} else {
|
||||
if (!bindlessMode)
|
||||
error(loc, "sampler-constructor requires the extension GL_ARB_bindless_texture enabled", token, "");
|
||||
else
|
||||
error(loc, "sampler-constructor requires the input to be ivec2 or uvec2", token, "");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// exactly two arguments needed
|
||||
if (function.getParamCount() != 2) {
|
||||
@ -3660,13 +3701,32 @@ void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const
|
||||
if (type.getQualifier().storage == EvqUniform)
|
||||
return;
|
||||
|
||||
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler))
|
||||
error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str());
|
||||
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler)) {
|
||||
// For bindless texture, sampler can be declared as an struct member
|
||||
if (extensionTurnedOn(E_GL_ARB_bindless_texture)) {
|
||||
if (type.getSampler().isImage())
|
||||
intermediate.setBindlessImageMode(currentCaller, AstRefTypeVar);
|
||||
else
|
||||
intermediate.setBindlessTextureMode(currentCaller, AstRefTypeVar);
|
||||
}
|
||||
else {
|
||||
error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str());
|
||||
}
|
||||
}
|
||||
else if (type.getBasicType() == EbtSampler && type.getQualifier().storage != EvqUniform) {
|
||||
// non-uniform sampler
|
||||
// not yet: okay if it has an initializer
|
||||
// if (! initializer)
|
||||
error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
|
||||
// For bindless texture, sampler can be declared as an input/output/block member
|
||||
if (extensionTurnedOn(E_GL_ARB_bindless_texture)) {
|
||||
if (type.getSampler().isImage())
|
||||
intermediate.setBindlessImageMode(currentCaller, AstRefTypeVar);
|
||||
else
|
||||
intermediate.setBindlessTextureMode(currentCaller, AstRefTypeVar);
|
||||
}
|
||||
else {
|
||||
// non-uniform sampler
|
||||
// not yet: okay if it has an initializer
|
||||
// if (! initializer)
|
||||
error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3732,7 +3792,7 @@ void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType)
|
||||
//
|
||||
// Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level.
|
||||
//
|
||||
void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier, bool isMemberCheck)
|
||||
void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier, bool isMemberCheck, const TPublicType* publicType)
|
||||
{
|
||||
bool nonuniformOkay = false;
|
||||
|
||||
@ -3768,6 +3828,11 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
|
||||
{
|
||||
requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "default std430 layout for uniform");
|
||||
}
|
||||
|
||||
if (publicType != nullptr && publicType->isImage() &&
|
||||
(qualifier.layoutFormat > ElfExtSizeGuard && qualifier.layoutFormat < ElfCount))
|
||||
qualifier.layoutFormat = mapLegacyLayoutFormat(qualifier.layoutFormat, publicType->sampler.getBasicType());
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -4172,7 +4237,7 @@ void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType ba
|
||||
|
||||
void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier qualifier, const TType& type)
|
||||
{
|
||||
if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque())
|
||||
if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque() && !intermediate.getBindlessMode())
|
||||
error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), "");
|
||||
if (!parsingBuiltins && type.contains16BitFloat())
|
||||
requireFloat16Arithmetic(loc, type.getBasicTypeString().c_str(), "float16 types can only be in uniform block or buffer storage");
|
||||
@ -5105,7 +5170,7 @@ void TParseContext::arrayObjectCheck(const TSourceLoc& loc, const TType& type, c
|
||||
|
||||
void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const char* op)
|
||||
{
|
||||
if (containsFieldWithBasicType(type, EbtSampler))
|
||||
if (containsFieldWithBasicType(type, EbtSampler) && !extensionTurnedOn(E_GL_ARB_bindless_texture))
|
||||
error(loc, "can't use with samplers or structs containing samplers", op, "");
|
||||
}
|
||||
|
||||
@ -5480,6 +5545,28 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
||||
intermediate.setUsePhysicalStorageBuffer();
|
||||
return;
|
||||
}
|
||||
if (id == "bindless_sampler") {
|
||||
requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "bindless_sampler");
|
||||
publicType.qualifier.layoutBindlessSampler = true;
|
||||
intermediate.setBindlessTextureMode(currentCaller, AstRefTypeLayout);
|
||||
return;
|
||||
}
|
||||
if (id == "bindless_image") {
|
||||
requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "bindless_image");
|
||||
publicType.qualifier.layoutBindlessImage = true;
|
||||
intermediate.setBindlessImageMode(currentCaller, AstRefTypeLayout);
|
||||
return;
|
||||
}
|
||||
if (id == "bound_sampler") {
|
||||
requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "bound_sampler");
|
||||
publicType.qualifier.layoutBindlessSampler = false;
|
||||
return;
|
||||
}
|
||||
if (id == "bound_image") {
|
||||
requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "bound_image");
|
||||
publicType.qualifier.layoutBindlessImage = false;
|
||||
return;
|
||||
}
|
||||
if (language == EShLangGeometry || language == EShLangTessEvaluation || language == EShLangMesh) {
|
||||
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
||||
publicType.shaderQualifiers.geometry = ElgTriangles;
|
||||
@ -6137,6 +6224,10 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
|
||||
dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
|
||||
if (src.layoutShaderRecord)
|
||||
dst.layoutShaderRecord = true;
|
||||
if (src.layoutBindlessSampler)
|
||||
dst.layoutBindlessSampler = true;
|
||||
if (src.layoutBindlessImage)
|
||||
dst.layoutBindlessImage = true;
|
||||
if (src.pervertexNV)
|
||||
dst.pervertexNV = true;
|
||||
if (src.pervertexEXT)
|
||||
@ -6418,7 +6509,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
||||
|
||||
// Image format
|
||||
if (qualifier.hasFormat()) {
|
||||
if (! type.isImage())
|
||||
if (! type.isImage() && !intermediate.getBindlessImageMode())
|
||||
error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
|
||||
else {
|
||||
if (type.getSampler().type == EbtFloat && qualifier.getFormat() > ElfFloatGuard)
|
||||
@ -6437,7 +6528,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (type.isImage() && ! qualifier.isWriteOnly()) {
|
||||
} else if (type.isImage() && ! qualifier.isWriteOnly() && !intermediate.getBindlessImageMode()) {
|
||||
const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier";
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation);
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation);
|
||||
@ -7745,12 +7836,14 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
|
||||
// Combined texture-sampler constructors are completely semantic checked
|
||||
// in constructorTextureSamplerError()
|
||||
if (op == EOpConstructTextureSampler) {
|
||||
if (aggrNode->getSequence()[1]->getAsTyped()->getType().getSampler().shadow) {
|
||||
// Transfer depth into the texture (SPIR-V image) type, as a hint
|
||||
// for tools to know this texture/image is a depth image.
|
||||
aggrNode->getSequence()[0]->getAsTyped()->getWritableType().getSampler().shadow = true;
|
||||
if (aggrNode != nullptr) {
|
||||
if (aggrNode->getSequence()[1]->getAsTyped()->getType().getSampler().shadow) {
|
||||
// Transfer depth into the texture (SPIR-V image) type, as a hint
|
||||
// for tools to know this texture/image is a depth image.
|
||||
aggrNode->getSequence()[0]->getAsTyped()->getWritableType().getSampler().shadow = true;
|
||||
}
|
||||
return intermediate.setAggregateOperator(aggrNode, op, type, loc);
|
||||
}
|
||||
return intermediate.setAggregateOperator(aggrNode, op, type, loc);
|
||||
}
|
||||
|
||||
TTypeList::const_iterator memberTypes;
|
||||
@ -7885,6 +7978,16 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
|
||||
TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUvec2, true, node,
|
||||
type);
|
||||
return newNode;
|
||||
} else if (node->getType().getBasicType() == EbtSampler) {
|
||||
requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "sampler conversion to uvec2");
|
||||
// force the basic type of the constructor param to uvec2, otherwise spv builder will
|
||||
// report some errors
|
||||
TIntermTyped* newSrcNode = intermediate.createConversion(EbtUint, node);
|
||||
newSrcNode->getAsTyped()->getWritableType().setVectorSize(2);
|
||||
|
||||
TIntermTyped* newNode =
|
||||
intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConstructUVec2, false, newSrcNode, type);
|
||||
return newNode;
|
||||
}
|
||||
case EOpConstructUVec3:
|
||||
case EOpConstructUVec4:
|
||||
@ -7898,7 +8001,15 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
|
||||
case EOpConstructBool:
|
||||
basicOp = EOpConstructBool;
|
||||
break;
|
||||
|
||||
case EOpConstructTextureSampler:
|
||||
if ((node->getType().getBasicType() == EbtUint || node->getType().getBasicType() == EbtInt) &&
|
||||
node->getType().getVectorSize() == 2) {
|
||||
requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "ivec2/uvec2 convert to texture handle");
|
||||
// No matter ivec2 or uvec2, Set EOpPackUint2x32 just to generate an opBitcast op code
|
||||
TIntermTyped* newNode =
|
||||
intermediate.addBuiltInFunctionCall(node->getLoc(), EOpPackUint2x32, true, node, type);
|
||||
return newNode;
|
||||
}
|
||||
#ifndef GLSLANG_WEB
|
||||
|
||||
case EOpConstructDVec2:
|
||||
@ -8245,6 +8356,30 @@ void TParseContext::inheritMemoryQualifiers(const TQualifier& from, TQualifier&
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Update qualifier layoutBindlessImage & layoutBindlessSampler on block member
|
||||
//
|
||||
void TParseContext::updateBindlessQualifier(TType& memberType)
|
||||
{
|
||||
if (memberType.containsSampler()) {
|
||||
if (memberType.isStruct()) {
|
||||
TTypeList* typeList = memberType.getWritableStruct();
|
||||
for (unsigned int member = 0; member < typeList->size(); ++member) {
|
||||
TType* subMemberType = (*typeList)[member].type;
|
||||
updateBindlessQualifier(*subMemberType);
|
||||
}
|
||||
}
|
||||
else if (memberType.getSampler().isImage()) {
|
||||
intermediate.setBindlessImageMode(currentCaller, AstRefTypeLayout);
|
||||
memberType.getQualifier().layoutBindlessImage = true;
|
||||
}
|
||||
else {
|
||||
intermediate.setBindlessTextureMode(currentCaller, AstRefTypeLayout);
|
||||
memberType.getQualifier().layoutBindlessSampler = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Do everything needed to add an interface block.
|
||||
//
|
||||
@ -8297,8 +8432,13 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
||||
}
|
||||
}
|
||||
|
||||
if (memberType.containsOpaque())
|
||||
error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), "");
|
||||
// For bindless texture, sampler can be declared as uniform/storage block member,
|
||||
if (memberType.containsOpaque()) {
|
||||
if (memberType.containsSampler() && extensionTurnedOn(E_GL_ARB_bindless_texture))
|
||||
updateBindlessQualifier(memberType);
|
||||
else
|
||||
error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), "");
|
||||
}
|
||||
|
||||
if (memberType.containsCoopMat())
|
||||
error(memberLoc, "member of block cannot be or contain a cooperative matrix type", typeList[member].type->getFieldName().c_str(), "");
|
||||
@ -9472,4 +9612,38 @@ const TTypeList* TParseContext::recordStructCopy(TStructRecord& record, const TT
|
||||
return originStruct;
|
||||
}
|
||||
|
||||
TLayoutFormat TParseContext::mapLegacyLayoutFormat(TLayoutFormat legacyLayoutFormat, TBasicType imageType)
|
||||
{
|
||||
TLayoutFormat layoutFormat = ElfNone;
|
||||
if (imageType == EbtFloat) {
|
||||
switch (legacyLayoutFormat) {
|
||||
case ElfSize1x16: layoutFormat = ElfR16f; break;
|
||||
case ElfSize1x32: layoutFormat = ElfR32f; break;
|
||||
case ElfSize2x32: layoutFormat = ElfRg32f; break;
|
||||
case ElfSize4x32: layoutFormat = ElfRgba32f; break;
|
||||
default: break;
|
||||
}
|
||||
} else if (imageType == EbtUint) {
|
||||
switch (legacyLayoutFormat) {
|
||||
case ElfSize1x8: layoutFormat = ElfR8ui; break;
|
||||
case ElfSize1x16: layoutFormat = ElfR16ui; break;
|
||||
case ElfSize1x32: layoutFormat = ElfR32ui; break;
|
||||
case ElfSize2x32: layoutFormat = ElfRg32ui; break;
|
||||
case ElfSize4x32: layoutFormat = ElfRgba32ui; break;
|
||||
default: break;
|
||||
}
|
||||
} else if (imageType == EbtInt) {
|
||||
switch (legacyLayoutFormat) {
|
||||
case ElfSize1x8: layoutFormat = ElfR8i; break;
|
||||
case ElfSize1x16: layoutFormat = ElfR16i; break;
|
||||
case ElfSize1x32: layoutFormat = ElfR32i; break;
|
||||
case ElfSize2x32: layoutFormat = ElfRg32i; break;
|
||||
case ElfSize4x32: layoutFormat = ElfRgba32i; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
return layoutFormat;
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
@ -393,7 +393,7 @@ public:
|
||||
void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
|
||||
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||
void memberQualifierCheck(glslang::TPublicType&);
|
||||
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&, bool isMemberCheck = false);
|
||||
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&, bool isMemberCheck = false, const TPublicType* publicType = nullptr);
|
||||
void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
|
||||
bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
|
||||
void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force);
|
||||
@ -456,9 +456,11 @@ public:
|
||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
||||
void invariantCheck(const TSourceLoc&, const TQualifier&);
|
||||
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
||||
void updateBindlessQualifier(TType& memberType);
|
||||
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
||||
const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*);
|
||||
TLayoutFormat mapLegacyLayoutFormat(TLayoutFormat legacyLayoutFormat, TBasicType imageType);
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
TAttributeType attributeFromName(const TString& name) const;
|
||||
|
@ -319,6 +319,7 @@ public:
|
||||
|
||||
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
||||
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
||||
const TQualifier& getQualifier() const { return returnType.getQualifier(); }
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
virtual void setSpirvInstruction(const TSpirvInstruction& inst)
|
||||
|
@ -227,6 +227,7 @@ void TParseVersions::initializeExtensionBehavior()
|
||||
extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_draw_instanced] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_bindless_texture] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_fragment_coord_conventions] = EBhDisable;
|
||||
|
||||
|
||||
@ -370,6 +371,9 @@ void TParseVersions::initializeExtensionBehavior()
|
||||
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shader_atomic_float2] = EBhDisable;
|
||||
|
||||
// Record extensions not for spv.
|
||||
spvUnsupportedExt.push_back(E_GL_ARB_bindless_texture);
|
||||
}
|
||||
|
||||
#endif // GLSLANG_WEB
|
||||
@ -437,7 +441,6 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||
|
||||
} else { // !isEsProfile()
|
||||
preamble =
|
||||
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
||||
"#define GL_ARB_texture_rectangle 1\n"
|
||||
"#define GL_ARB_shading_language_420pack 1\n"
|
||||
"#define GL_ARB_texture_gather 1\n"
|
||||
@ -477,6 +480,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||
"#define GL_ARB_vertex_attrib_64bit 1\n"
|
||||
"#define GL_ARB_draw_instanced 1\n"
|
||||
"#define GL_ARB_fragment_coord_conventions 1\n"
|
||||
"#define GL_ARB_bindless_texture 1\n"
|
||||
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||
"#define GL_EXT_shader_image_load_formatted 1\n"
|
||||
"#define GL_EXT_post_depth_coverage 1\n"
|
||||
@ -576,6 +580,10 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||
preamble += "#define GL_EXT_null_initializer 1\n";
|
||||
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
|
||||
}
|
||||
if (version >= 130) {
|
||||
preamble +="#define GL_FRAGMENT_PRECISION_HIGH 1\n";
|
||||
}
|
||||
|
||||
#endif // GLSLANG_WEB
|
||||
}
|
||||
|
||||
@ -1099,6 +1107,13 @@ void TParseVersions::extensionRequires(const TSourceLoc &loc, const char * const
|
||||
minSpvVersion = iter->second;
|
||||
requireSpv(loc, extension, minSpvVersion);
|
||||
}
|
||||
|
||||
if (spvVersion.spv != 0){
|
||||
for (auto ext : spvUnsupportedExt){
|
||||
if (strcmp(extension, ext.c_str()) == 0)
|
||||
error(loc, "not allowed when using generating SPIR-V codes", extension, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call for any operation needing full GLSL integer data-type support.
|
||||
|
@ -163,6 +163,7 @@ const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_
|
||||
const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit";
|
||||
const char* const E_GL_ARB_draw_instanced = "GL_ARB_draw_instanced";
|
||||
const char* const E_GL_ARB_fragment_coord_conventions = "GL_ARB_fragment_coord_conventions";
|
||||
const char* const E_GL_ARB_bindless_texture = "GL_ARB_bindless_texture";
|
||||
|
||||
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
|
||||
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
||||
|
@ -1218,7 +1218,7 @@ fully_specified_type
|
||||
parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier);
|
||||
}
|
||||
| type_qualifier type_specifier {
|
||||
parseContext.globalQualifierFixCheck($1.loc, $1.qualifier);
|
||||
parseContext.globalQualifierFixCheck($1.loc, $1.qualifier, false, &$2);
|
||||
parseContext.globalQualifierTypeCheck($1.loc, $1.qualifier, $2);
|
||||
|
||||
if ($2.arraySizes) {
|
||||
|
@ -1218,7 +1218,7 @@ fully_specified_type
|
||||
parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier);
|
||||
}
|
||||
| type_qualifier type_specifier {
|
||||
parseContext.globalQualifierFixCheck($1.loc, $1.qualifier);
|
||||
parseContext.globalQualifierFixCheck($1.loc, $1.qualifier, false, &$2);
|
||||
parseContext.globalQualifierTypeCheck($1.loc, $1.qualifier, $2);
|
||||
|
||||
if ($2.arraySizes) {
|
||||
|
@ -6551,7 +6551,7 @@ yyreduce:
|
||||
case 136: /* fully_specified_type: type_qualifier type_specifier */
|
||||
#line 1220 "MachineIndependent/glslang.y"
|
||||
{
|
||||
parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier);
|
||||
parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, false, &(yyvsp[0].interm.type));
|
||||
parseContext.globalQualifierTypeCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, (yyvsp[0].interm.type));
|
||||
|
||||
if ((yyvsp[0].interm.type).arraySizes) {
|
||||
|
@ -1517,7 +1517,10 @@ void TIntermediate::checkCallGraphBodies(TInfoSink& infoSink, bool keepUncalled)
|
||||
if (! keepUncalled) {
|
||||
for (int f = 0; f < (int)functionSequence.size(); ++f) {
|
||||
if (! reachable[f])
|
||||
{
|
||||
resetTopLevelUncalledStatus(functionSequence[f]->getAsAggregate()->getName());
|
||||
functionSequence[f] = nullptr;
|
||||
}
|
||||
}
|
||||
functionSequence.erase(std::remove(functionSequence.begin(), functionSequence.end(), nullptr), functionSequence.end());
|
||||
}
|
||||
@ -2012,6 +2015,15 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
||||
case EbtInt16:
|
||||
case EbtUint16: size = 2; return 2;
|
||||
case EbtReference: size = 8; return 8;
|
||||
case EbtSampler:
|
||||
{
|
||||
if (type.isBindlessImage() || type.isBindlessTexture()) {
|
||||
size = 8; return 8;
|
||||
}
|
||||
else {
|
||||
size = 4; return 4;
|
||||
}
|
||||
}
|
||||
default: size = 4; return 4;
|
||||
}
|
||||
}
|
||||
|
@ -225,6 +225,16 @@ enum ComputeDerivativeMode {
|
||||
LayoutDerivativeGroupLinear, // derivative_group_linearNV
|
||||
};
|
||||
|
||||
//
|
||||
// Status type on AST level. Some uncalled status or functions would be reset in call graph.
|
||||
// Currently we will keep status set by explicitly declared layout or variable decl.
|
||||
//
|
||||
enum AstRefType {
|
||||
AstRefTypeVar, // Status set by variable decl
|
||||
AstRefTypeFunc, // Status set by function decl
|
||||
AstRefTypeLayout, // Status set by layout decl
|
||||
};
|
||||
|
||||
class TIdMaps {
|
||||
public:
|
||||
TMap<TString, long long>& operator[](long long i) { return maps[i]; }
|
||||
@ -744,6 +754,65 @@ public:
|
||||
useVariablePointers = true;
|
||||
processes.addProcess("use-variable-pointers");
|
||||
}
|
||||
// Set the global flag for bindless texture
|
||||
void setBindlessTextureMode(const TString& currentCaller, AstRefType type)
|
||||
{
|
||||
// When type is not func, currentCaller should be "" (empty string)
|
||||
bindlessTextureModeCaller[currentCaller] = type;
|
||||
}
|
||||
|
||||
// Get the global flag for bindless texture
|
||||
bool getBindlessTextureMode() const
|
||||
{
|
||||
return (bindlessTextureModeCaller.size() > 0);
|
||||
}
|
||||
|
||||
// Set the global flag for bindless image
|
||||
void setBindlessImageMode(const TString& currentCaller, AstRefType type)
|
||||
{
|
||||
// When type is not func, currentCaller should be "" (empty string)
|
||||
bindlessImageModeCaller[currentCaller] = type;
|
||||
}
|
||||
|
||||
// Get the global flag for bindless image
|
||||
bool getBindlessImageMode() const
|
||||
{
|
||||
return (bindlessImageModeCaller.size() > 0);
|
||||
}
|
||||
|
||||
// Get the global flag for bindless texture
|
||||
bool resetTopLevelUncalledStatus(const TString& deadCaller)
|
||||
{
|
||||
// For reflection collection purpose, currently uniform layout setting and some
|
||||
// flags introduced by variables (IO, global, etc,.) won't be reset here.
|
||||
// Remove each global status (AST top level) introduced by uncalled functions.
|
||||
// If a status is set by several functions, keep those which in call graph.
|
||||
bool result = false;
|
||||
|
||||
// For two types of bindless mode flag, we would only reset which is set by an uncalled function.
|
||||
// If one status flag's key in caller vec is empty, it should be come from a non-function setting.
|
||||
if (!bindlessTextureModeCaller.empty()) {
|
||||
auto caller = bindlessTextureModeCaller.find(deadCaller);
|
||||
if (caller != bindlessTextureModeCaller.end() && bindlessTextureModeCaller[deadCaller] == AstRefTypeFunc) {
|
||||
bindlessTextureModeCaller.erase(caller);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
if (!bindlessImageModeCaller.empty()) {
|
||||
auto caller = bindlessImageModeCaller.find(deadCaller);
|
||||
if (caller != bindlessImageModeCaller.end() && bindlessImageModeCaller[deadCaller] == AstRefTypeFunc) {
|
||||
bindlessImageModeCaller.erase(caller);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool getBindlessMode() const
|
||||
{
|
||||
return getBindlessTextureMode() || getBindlessImageMode();
|
||||
}
|
||||
|
||||
bool usingVariablePointers() const { return useVariablePointers; }
|
||||
|
||||
#ifdef ENABLE_HLSL
|
||||
@ -1188,7 +1257,8 @@ protected:
|
||||
|
||||
TSpirvRequirement* spirvRequirement;
|
||||
TSpirvExecutionMode* spirvExecutionMode;
|
||||
|
||||
std::map<TString, AstRefType> bindlessTextureModeCaller;
|
||||
std::map<TString, AstRefType> bindlessImageModeCaller;
|
||||
std::unordered_map<std::string, int> uniformLocationOverrides;
|
||||
int uniformLocationBase;
|
||||
TNumericFeatures numericFeatures;
|
||||
|
@ -226,6 +226,7 @@ public:
|
||||
protected:
|
||||
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is
|
||||
TMap<TString, unsigned int> extensionMinSpv; // for each extension string, store minimum spirv required
|
||||
TVector<TString> spvUnsupportedExt; // for extensions reserved for spv usage.
|
||||
EShMessages messages; // errors/warnings/rule-sets
|
||||
int numErrors; // number of compile-time errors encountered
|
||||
TInputScanner* currentScanner;
|
||||
|
@ -291,6 +291,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
"GL_EXT_shader_integer_mix.vert",
|
||||
"GL_ARB_draw_instanced.vert",
|
||||
"GL_ARB_fragment_coord_conventions.vert",
|
||||
"GL_ARB_bindless_texture.frag",
|
||||
"BestMatchFunction.vert",
|
||||
"EndStreamPrimitive.geom",
|
||||
"floatBitsToInt.vert",
|
||||
|
Loading…
Reference in New Issue
Block a user