Skip to content

Commit

Permalink
Merge pull request KhronosGroup#3066 from ShchchowAMD/shaochi/bindless
Browse files Browse the repository at this point in the history
[glslang][extension] Add support for ARB_bindless_texture.
  • Loading branch information
greg-lunarg authored Dec 7, 2022
2 parents 77551c4 + 16526fd commit ed257e2
Show file tree
Hide file tree
Showing 19 changed files with 608 additions and 35 deletions.
4 changes: 2 additions & 2 deletions SPIRV/GlslangToSpv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,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;
}

Expand Down Expand Up @@ -5106,7 +5106,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
Expand Down
50 changes: 50 additions & 0 deletions Test/GL_ARB_bindless_texture.frag
Original file line number Diff line number Diff line change
@@ -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 changes: 205 additions & 0 deletions Test/baseResults/GL_ARB_bindless_texture.frag.out
Original file line number Diff line number Diff line change
@@ -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)

2 changes: 1 addition & 1 deletion Test/baseResults/vulkan.frag.out
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 36 additions & 1 deletion glslang/Include/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,12 @@ enum TLayoutFormat {
ElfR16ui,
ElfR8ui,
ElfR64ui,
ElfExtSizeGuard, // to help with comparisons
ElfSize1x8,
ElfSize1x16,
ElfSize1x32,
ElfSize2x32,
ElfSize4x32,

ElfCount
};
Expand Down Expand Up @@ -898,6 +904,8 @@ class TQualifier {
// -2048 as the default value indicating layoutSecondaryViewportRelative is not set
layoutSecondaryViewportRelativeOffset = -2048;
layoutShaderRecord = false;
layoutBindlessSampler = false;
layoutBindlessImage = false;
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
layoutFormat = ElfNone;
#endif
Expand Down Expand Up @@ -1001,6 +1009,9 @@ class TQualifier {
// GL_EXT_spirv_intrinsics
int spirvStorageClass;
TSpirvDecorate* spirvDecorate;

bool layoutBindlessSampler;
bool layoutBindlessImage;
#endif

bool hasUniformLayout() const
Expand Down Expand Up @@ -1132,6 +1143,14 @@ class TQualifier {
{
return nonUniform;
}
bool isBindlessSampler() const
{
return layoutBindlessSampler;
}
bool isBindlessImage() const
{
return layoutBindlessImage;
}

// GL_EXT_spirv_intrinsics
bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
Expand Down Expand Up @@ -1241,6 +1260,11 @@ class TQualifier {
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";
}
}
Expand Down Expand Up @@ -1898,6 +1922,8 @@ class TType {
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; }
Expand Down Expand Up @@ -1954,6 +1980,11 @@ class TType {
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
{
Expand Down Expand Up @@ -2285,7 +2316,10 @@ class TType {
}
if (qualifier.layoutShaderRecord)
appendStr(" shaderRecordNV");

if (qualifier.layoutBindlessSampler)
appendStr(" layoutBindlessSampler");
if (qualifier.layoutBindlessImage)
appendStr(" layoutBindlessImage");
appendStr(")");
}
}
Expand Down Expand Up @@ -2544,6 +2578,7 @@ class TType {
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
{
Expand Down
5 changes: 5 additions & 0 deletions glslang/MachineIndependent/Intermediate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading

0 comments on commit ed257e2

Please sign in to comment.