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) {
|
type.getQualifier().storage == glslang::EvqUniform) {
|
||||||
if (type.isAtomic())
|
if (type.isAtomic())
|
||||||
return spv::StorageClassAtomicCounter;
|
return spv::StorageClassAtomicCounter;
|
||||||
if (type.containsOpaque())
|
if (type.containsOpaque() && !glslangIntermediate->getBindlessMode())
|
||||||
return spv::StorageClassUniformConstant;
|
return spv::StorageClassUniformConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5083,7 +5083,7 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
|
|||||||
return true;
|
return true;
|
||||||
if (glslangIntermediate->getSource() == glslang::EShSourceHlsl)
|
if (glslangIntermediate->getSource() == glslang::EShSourceHlsl)
|
||||||
return paramType.getBasicType() == glslang::EbtBlock;
|
return paramType.getBasicType() == glslang::EbtBlock;
|
||||||
return paramType.containsOpaque() || // sampler, etc.
|
return (paramType.containsOpaque() && !glslangIntermediate->getBindlessMode()) || // sampler, etc.
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
paramType.getQualifier().isSpirvByReference() || // spirv_by_reference
|
paramType.getQualifier().isSpirvByReference() || // spirv_by_reference
|
||||||
#endif
|
#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:8: 'binding' : sampler/texture/image requires layout(binding=X)
|
||||||
ERROR: 0:9: '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: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: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: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
|
ERROR: 0:17: 'sampler2D' : sampler-constructor second argument must be a scalar sampler or samplerShadow
|
||||||
|
@ -429,6 +429,12 @@ enum TLayoutFormat {
|
|||||||
ElfR16ui,
|
ElfR16ui,
|
||||||
ElfR8ui,
|
ElfR8ui,
|
||||||
ElfR64ui,
|
ElfR64ui,
|
||||||
|
ElfExtSizeGuard, // to help with comparisons
|
||||||
|
ElfSize1x8,
|
||||||
|
ElfSize1x16,
|
||||||
|
ElfSize1x32,
|
||||||
|
ElfSize2x32,
|
||||||
|
ElfSize4x32,
|
||||||
|
|
||||||
ElfCount
|
ElfCount
|
||||||
};
|
};
|
||||||
@ -898,6 +904,8 @@ public:
|
|||||||
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
|
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
|
||||||
layoutSecondaryViewportRelativeOffset = -2048;
|
layoutSecondaryViewportRelativeOffset = -2048;
|
||||||
layoutShaderRecord = false;
|
layoutShaderRecord = false;
|
||||||
|
layoutBindlessSampler = false;
|
||||||
|
layoutBindlessImage = false;
|
||||||
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
|
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
|
||||||
layoutFormat = ElfNone;
|
layoutFormat = ElfNone;
|
||||||
#endif
|
#endif
|
||||||
@ -1001,6 +1009,9 @@ public:
|
|||||||
// GL_EXT_spirv_intrinsics
|
// GL_EXT_spirv_intrinsics
|
||||||
int spirvStorageClass;
|
int spirvStorageClass;
|
||||||
TSpirvDecorate* spirvDecorate;
|
TSpirvDecorate* spirvDecorate;
|
||||||
|
|
||||||
|
bool layoutBindlessSampler;
|
||||||
|
bool layoutBindlessImage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool hasUniformLayout() const
|
bool hasUniformLayout() const
|
||||||
@ -1132,6 +1143,14 @@ public:
|
|||||||
{
|
{
|
||||||
return nonUniform;
|
return nonUniform;
|
||||||
}
|
}
|
||||||
|
bool isBindlessSampler() const
|
||||||
|
{
|
||||||
|
return layoutBindlessSampler;
|
||||||
|
}
|
||||||
|
bool isBindlessImage() const
|
||||||
|
{
|
||||||
|
return layoutBindlessImage;
|
||||||
|
}
|
||||||
|
|
||||||
// GL_EXT_spirv_intrinsics
|
// GL_EXT_spirv_intrinsics
|
||||||
bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
|
bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
|
||||||
@ -1241,6 +1260,11 @@ public:
|
|||||||
case ElfR8ui: return "r8ui";
|
case ElfR8ui: return "r8ui";
|
||||||
case ElfR64ui: return "r64ui";
|
case ElfR64ui: return "r64ui";
|
||||||
case ElfR64i: return "r64i";
|
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";
|
default: return "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1898,6 +1922,8 @@ public:
|
|||||||
virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); }
|
virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); }
|
||||||
virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); }
|
virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); }
|
||||||
virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); }
|
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:
|
// Check the block-name convention of creating a block without populating it's members:
|
||||||
virtual bool isUnusableName() const { return isStruct() && structure == nullptr; }
|
virtual bool isUnusableName() const { return isStruct() && structure == nullptr; }
|
||||||
virtual bool isParameterized() const { return typeParameters != nullptr; }
|
virtual bool isParameterized() const { return typeParameters != nullptr; }
|
||||||
@ -1954,6 +1980,11 @@ public:
|
|||||||
return contains([](const TType* t) { return t->isOpaque(); } );
|
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
|
// Recursively checks if the type contains a built-in variable
|
||||||
virtual bool containsBuiltIn() const
|
virtual bool containsBuiltIn() const
|
||||||
{
|
{
|
||||||
@ -2285,7 +2316,10 @@ public:
|
|||||||
}
|
}
|
||||||
if (qualifier.layoutShaderRecord)
|
if (qualifier.layoutShaderRecord)
|
||||||
appendStr(" shaderRecordNV");
|
appendStr(" shaderRecordNV");
|
||||||
|
if (qualifier.layoutBindlessSampler)
|
||||||
|
appendStr(" layoutBindlessSampler");
|
||||||
|
if (qualifier.layoutBindlessImage)
|
||||||
|
appendStr(" layoutBindlessImage");
|
||||||
appendStr(")");
|
appendStr(")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2544,6 +2578,7 @@ public:
|
|||||||
void setStruct(TTypeList* s) { assert(isStruct()); structure = s; }
|
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
|
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 setBasicType(const TBasicType& t) { basicType = t; }
|
||||||
|
void setVectorSize(int s) { vectorSize = s; }
|
||||||
|
|
||||||
int computeNumComponents() const
|
int computeNumComponents() const
|
||||||
{
|
{
|
||||||
|
@ -751,6 +751,11 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne
|
|||||||
case EbtInt64: newOp = EOpConvInt64ToUint; break;
|
case EbtInt64: newOp = EOpConvInt64ToUint; break;
|
||||||
case EbtUint64: newOp = EOpConvUint64ToUint; break;
|
case EbtUint64: newOp = EOpConvUint64ToUint; break;
|
||||||
#endif
|
#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:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,8 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
|||||||
//
|
//
|
||||||
switch (node->getBasicType()) {
|
switch (node->getBasicType()) {
|
||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
message = "can't modify a sampler";
|
if (extensionTurnedOn(E_GL_ARB_bindless_texture) == false)
|
||||||
|
message = "can't modify a sampler";
|
||||||
break;
|
break;
|
||||||
case EbtVoid:
|
case EbtVoid:
|
||||||
message = "can't modify void";
|
message = "can't modify void";
|
||||||
|
@ -1389,7 +1389,8 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
|
|||||||
#endif
|
#endif
|
||||||
const TType& argType = arg->getAsTyped()->getType();
|
const TType& argType = arg->getAsTyped()->getType();
|
||||||
const TQualifier& argQualifier = argType.getQualifier();
|
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";
|
const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
if (argQualifier.volatil && ! formalQualifier.volatil)
|
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", "");
|
error(loc, "type does not match, or is not convertible to, the function's return type", "return", "");
|
||||||
branch = intermediate.addBranch(EOpReturn, value, loc);
|
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 = intermediate.addBranch(EOpReturn, value, loc);
|
||||||
|
}
|
||||||
branch->updatePrecision(currentFunctionType->getQualifier().precision);
|
branch->updatePrecision(currentFunctionType->getQualifier().precision);
|
||||||
return branch;
|
return branch;
|
||||||
}
|
}
|
||||||
@ -1928,6 +1933,9 @@ TIntermTyped* TParseContext::addAssign(const TSourceLoc& loc, TOperator op, TInt
|
|||||||
if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference())
|
if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference())
|
||||||
requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "+= and -= on a buffer reference");
|
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);
|
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");
|
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);
|
TOperator op = intermediate.mapTypeToConstructorOp(type);
|
||||||
|
|
||||||
if (op == EOpNull) {
|
if (op == EOpNull) {
|
||||||
@ -3544,8 +3560,13 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) {
|
if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) {
|
||||||
error(loc, "cannot convert a sampler", constructorString.c_str(), "");
|
if (op == EOpConstructUVec2 && extensionTurnedOn(E_GL_ARB_bindless_texture)) {
|
||||||
return true;
|
intermediate.setBindlessTextureMode(currentCaller, AstRefTypeFunc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error(loc, "cannot convert a sampler", constructorString.c_str(), "");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (op != EOpConstructStruct && typed->isAtomic()) {
|
if (op != EOpConstructStruct && typed->isAtomic()) {
|
||||||
error(loc, "cannot convert an atomic_uint", constructorString.c_str(), "");
|
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
|
TString constructorName = function.getType().getBasicTypeString(); // TODO: performance: should not be making copy; interface needs to change
|
||||||
const char* token = constructorName.c_str();
|
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
|
// exactly two arguments needed
|
||||||
if (function.getParamCount() != 2) {
|
if (function.getParamCount() != 2) {
|
||||||
@ -3660,13 +3701,32 @@ void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const
|
|||||||
if (type.getQualifier().storage == EvqUniform)
|
if (type.getQualifier().storage == EvqUniform)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler))
|
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler)) {
|
||||||
error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str());
|
// 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) {
|
else if (type.getBasicType() == EbtSampler && type.getQualifier().storage != EvqUniform) {
|
||||||
// non-uniform sampler
|
// For bindless texture, sampler can be declared as an input/output/block member
|
||||||
// not yet: okay if it has an initializer
|
if (extensionTurnedOn(E_GL_ARB_bindless_texture)) {
|
||||||
// if (! initializer)
|
if (type.getSampler().isImage())
|
||||||
error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
|
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.
|
// 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;
|
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");
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -4172,7 +4237,7 @@ void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType ba
|
|||||||
|
|
||||||
void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier qualifier, const TType& type)
|
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(), "");
|
error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), "");
|
||||||
if (!parsingBuiltins && type.contains16BitFloat())
|
if (!parsingBuiltins && type.contains16BitFloat())
|
||||||
requireFloat16Arithmetic(loc, type.getBasicTypeString().c_str(), "float16 types can only be in uniform block or buffer storage");
|
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)
|
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, "");
|
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();
|
intermediate.setUsePhysicalStorageBuffer();
|
||||||
return;
|
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 (language == EShLangGeometry || language == EShLangTessEvaluation || language == EShLangMesh) {
|
||||||
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgTriangles;
|
publicType.shaderQualifiers.geometry = ElgTriangles;
|
||||||
@ -6137,6 +6224,10 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
|
|||||||
dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
|
dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
|
||||||
if (src.layoutShaderRecord)
|
if (src.layoutShaderRecord)
|
||||||
dst.layoutShaderRecord = true;
|
dst.layoutShaderRecord = true;
|
||||||
|
if (src.layoutBindlessSampler)
|
||||||
|
dst.layoutBindlessSampler = true;
|
||||||
|
if (src.layoutBindlessImage)
|
||||||
|
dst.layoutBindlessImage = true;
|
||||||
if (src.pervertexNV)
|
if (src.pervertexNV)
|
||||||
dst.pervertexNV = true;
|
dst.pervertexNV = true;
|
||||||
if (src.pervertexEXT)
|
if (src.pervertexEXT)
|
||||||
@ -6418,7 +6509,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
|||||||
|
|
||||||
// Image format
|
// Image format
|
||||||
if (qualifier.hasFormat()) {
|
if (qualifier.hasFormat()) {
|
||||||
if (! type.isImage())
|
if (! type.isImage() && !intermediate.getBindlessImageMode())
|
||||||
error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
|
error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.getFormat()), "");
|
||||||
else {
|
else {
|
||||||
if (type.getSampler().type == EbtFloat && qualifier.getFormat() > ElfFloatGuard)
|
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";
|
const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier";
|
||||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation);
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation);
|
||||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, 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
|
// Combined texture-sampler constructors are completely semantic checked
|
||||||
// in constructorTextureSamplerError()
|
// in constructorTextureSamplerError()
|
||||||
if (op == EOpConstructTextureSampler) {
|
if (op == EOpConstructTextureSampler) {
|
||||||
if (aggrNode->getSequence()[1]->getAsTyped()->getType().getSampler().shadow) {
|
if (aggrNode != nullptr) {
|
||||||
// Transfer depth into the texture (SPIR-V image) type, as a hint
|
if (aggrNode->getSequence()[1]->getAsTyped()->getType().getSampler().shadow) {
|
||||||
// for tools to know this texture/image is a depth image.
|
// Transfer depth into the texture (SPIR-V image) type, as a hint
|
||||||
aggrNode->getSequence()[0]->getAsTyped()->getWritableType().getSampler().shadow = true;
|
// 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;
|
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,
|
TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUvec2, true, node,
|
||||||
type);
|
type);
|
||||||
return newNode;
|
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 EOpConstructUVec3:
|
||||||
case EOpConstructUVec4:
|
case EOpConstructUVec4:
|
||||||
@ -7898,7 +8001,15 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
|
|||||||
case EOpConstructBool:
|
case EOpConstructBool:
|
||||||
basicOp = EOpConstructBool;
|
basicOp = EOpConstructBool;
|
||||||
break;
|
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
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
case EOpConstructDVec2:
|
case EOpConstructDVec2:
|
||||||
@ -8245,6 +8356,30 @@ void TParseContext::inheritMemoryQualifiers(const TQualifier& from, TQualifier&
|
|||||||
#endif
|
#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.
|
// Do everything needed to add an interface block.
|
||||||
//
|
//
|
||||||
@ -8297,8 +8432,13 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memberType.containsOpaque())
|
// For bindless texture, sampler can be declared as uniform/storage block member,
|
||||||
error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), "");
|
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())
|
if (memberType.containsCoopMat())
|
||||||
error(memberLoc, "member of block cannot be or contain a cooperative matrix type", typeList[member].type->getFieldName().c_str(), "");
|
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;
|
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
|
} // end namespace glslang
|
||||||
|
@ -393,7 +393,7 @@ public:
|
|||||||
void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
|
void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier);
|
||||||
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
void memberQualifierCheck(glslang::TPublicType&);
|
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&);
|
void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
|
||||||
bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
|
bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
|
||||||
void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force);
|
void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force);
|
||||||
@ -456,9 +456,11 @@ public:
|
|||||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
||||||
void invariantCheck(const TSourceLoc&, const TQualifier&);
|
void invariantCheck(const TSourceLoc&, const TQualifier&);
|
||||||
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
||||||
|
void updateBindlessQualifier(TType& memberType);
|
||||||
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||||
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
||||||
const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*);
|
const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*);
|
||||||
|
TLayoutFormat mapLegacyLayoutFormat(TLayoutFormat legacyLayoutFormat, TBasicType imageType);
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
TAttributeType attributeFromName(const TString& name) const;
|
TAttributeType attributeFromName(const TString& name) const;
|
||||||
|
@ -319,6 +319,7 @@ public:
|
|||||||
|
|
||||||
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
||||||
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
||||||
|
const TQualifier& getQualifier() const { return returnType.getQualifier(); }
|
||||||
|
|
||||||
#ifndef GLSLANG_WEB
|
#ifndef GLSLANG_WEB
|
||||||
virtual void setSpirvInstruction(const TSpirvInstruction& inst)
|
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_texture_query_lod] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable;
|
extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_draw_instanced] = EBhDisable;
|
extensionBehavior[E_GL_ARB_draw_instanced] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_bindless_texture] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_fragment_coord_conventions] = 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_subgroup_extended_types_float16] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_atomic_float2] = 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
|
#endif // GLSLANG_WEB
|
||||||
@ -437,7 +441,6 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
|
|
||||||
} else { // !isEsProfile()
|
} else { // !isEsProfile()
|
||||||
preamble =
|
preamble =
|
||||||
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
|
||||||
"#define GL_ARB_texture_rectangle 1\n"
|
"#define GL_ARB_texture_rectangle 1\n"
|
||||||
"#define GL_ARB_shading_language_420pack 1\n"
|
"#define GL_ARB_shading_language_420pack 1\n"
|
||||||
"#define GL_ARB_texture_gather 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_vertex_attrib_64bit 1\n"
|
||||||
"#define GL_ARB_draw_instanced 1\n"
|
"#define GL_ARB_draw_instanced 1\n"
|
||||||
"#define GL_ARB_fragment_coord_conventions 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_non_constant_global_initializers 1\n"
|
||||||
"#define GL_EXT_shader_image_load_formatted 1\n"
|
"#define GL_EXT_shader_image_load_formatted 1\n"
|
||||||
"#define GL_EXT_post_depth_coverage 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_null_initializer 1\n";
|
||||||
preamble += "#define GL_EXT_subgroup_uniform_control_flow 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
|
#endif // GLSLANG_WEB
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1099,6 +1107,13 @@ void TParseVersions::extensionRequires(const TSourceLoc &loc, const char * const
|
|||||||
minSpvVersion = iter->second;
|
minSpvVersion = iter->second;
|
||||||
requireSpv(loc, extension, minSpvVersion);
|
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.
|
// 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_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_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_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_basic = "GL_KHR_shader_subgroup_basic";
|
||||||
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
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);
|
parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier);
|
||||||
}
|
}
|
||||||
| type_qualifier type_specifier {
|
| 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);
|
parseContext.globalQualifierTypeCheck($1.loc, $1.qualifier, $2);
|
||||||
|
|
||||||
if ($2.arraySizes) {
|
if ($2.arraySizes) {
|
||||||
|
@ -1218,7 +1218,7 @@ fully_specified_type
|
|||||||
parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier);
|
parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier);
|
||||||
}
|
}
|
||||||
| type_qualifier type_specifier {
|
| 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);
|
parseContext.globalQualifierTypeCheck($1.loc, $1.qualifier, $2);
|
||||||
|
|
||||||
if ($2.arraySizes) {
|
if ($2.arraySizes) {
|
||||||
|
@ -6551,7 +6551,7 @@ yyreduce:
|
|||||||
case 136: /* fully_specified_type: type_qualifier type_specifier */
|
case 136: /* fully_specified_type: type_qualifier type_specifier */
|
||||||
#line 1220 "MachineIndependent/glslang.y"
|
#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));
|
parseContext.globalQualifierTypeCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, (yyvsp[0].interm.type));
|
||||||
|
|
||||||
if ((yyvsp[0].interm.type).arraySizes) {
|
if ((yyvsp[0].interm.type).arraySizes) {
|
||||||
|
@ -1517,7 +1517,10 @@ void TIntermediate::checkCallGraphBodies(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
if (! keepUncalled) {
|
if (! keepUncalled) {
|
||||||
for (int f = 0; f < (int)functionSequence.size(); ++f) {
|
for (int f = 0; f < (int)functionSequence.size(); ++f) {
|
||||||
if (! reachable[f])
|
if (! reachable[f])
|
||||||
|
{
|
||||||
|
resetTopLevelUncalledStatus(functionSequence[f]->getAsAggregate()->getName());
|
||||||
functionSequence[f] = nullptr;
|
functionSequence[f] = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
functionSequence.erase(std::remove(functionSequence.begin(), functionSequence.end(), nullptr), functionSequence.end());
|
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 EbtInt16:
|
||||||
case EbtUint16: size = 2; return 2;
|
case EbtUint16: size = 2; return 2;
|
||||||
case EbtReference: size = 8; return 8;
|
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;
|
default: size = 4; return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,16 @@ enum ComputeDerivativeMode {
|
|||||||
LayoutDerivativeGroupLinear, // derivative_group_linearNV
|
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 {
|
class TIdMaps {
|
||||||
public:
|
public:
|
||||||
TMap<TString, long long>& operator[](long long i) { return maps[i]; }
|
TMap<TString, long long>& operator[](long long i) { return maps[i]; }
|
||||||
@ -744,6 +754,65 @@ public:
|
|||||||
useVariablePointers = true;
|
useVariablePointers = true;
|
||||||
processes.addProcess("use-variable-pointers");
|
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; }
|
bool usingVariablePointers() const { return useVariablePointers; }
|
||||||
|
|
||||||
#ifdef ENABLE_HLSL
|
#ifdef ENABLE_HLSL
|
||||||
@ -1188,7 +1257,8 @@ protected:
|
|||||||
|
|
||||||
TSpirvRequirement* spirvRequirement;
|
TSpirvRequirement* spirvRequirement;
|
||||||
TSpirvExecutionMode* spirvExecutionMode;
|
TSpirvExecutionMode* spirvExecutionMode;
|
||||||
|
std::map<TString, AstRefType> bindlessTextureModeCaller;
|
||||||
|
std::map<TString, AstRefType> bindlessImageModeCaller;
|
||||||
std::unordered_map<std::string, int> uniformLocationOverrides;
|
std::unordered_map<std::string, int> uniformLocationOverrides;
|
||||||
int uniformLocationBase;
|
int uniformLocationBase;
|
||||||
TNumericFeatures numericFeatures;
|
TNumericFeatures numericFeatures;
|
||||||
|
@ -226,6 +226,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is
|
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
|
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
|
EShMessages messages; // errors/warnings/rule-sets
|
||||||
int numErrors; // number of compile-time errors encountered
|
int numErrors; // number of compile-time errors encountered
|
||||||
TInputScanner* currentScanner;
|
TInputScanner* currentScanner;
|
||||||
|
@ -291,6 +291,7 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
"GL_EXT_shader_integer_mix.vert",
|
"GL_EXT_shader_integer_mix.vert",
|
||||||
"GL_ARB_draw_instanced.vert",
|
"GL_ARB_draw_instanced.vert",
|
||||||
"GL_ARB_fragment_coord_conventions.vert",
|
"GL_ARB_fragment_coord_conventions.vert",
|
||||||
|
"GL_ARB_bindless_texture.frag",
|
||||||
"BestMatchFunction.vert",
|
"BestMatchFunction.vert",
|
||||||
"EndStreamPrimitive.geom",
|
"EndStreamPrimitive.geom",
|
||||||
"floatBitsToInt.vert",
|
"floatBitsToInt.vert",
|
||||||
|
Loading…
Reference in New Issue
Block a user