Updated glslang.

This commit is contained in:
Branimir Karadžić 2017-07-21 19:49:23 -07:00
parent 38574b6b73
commit 0e1893f292
23 changed files with 421 additions and 60 deletions

View File

@ -2914,6 +2914,13 @@ bool TGlslangToSpvTraverser::isShaderEntryPoint(const glslang::TIntermAggregate*
// Make all the functions, skeletally, without actually visiting their bodies.
void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
{
const auto getParamDecorations = [](std::vector<spv::Decoration>& decorations, const glslang::TType& type) {
spv::Decoration paramPrecision = TranslatePrecisionDecoration(type);
if (paramPrecision != spv::NoPrecision)
decorations.push_back(paramPrecision);
TranslateMemoryDecoration(type.getQualifier(), decorations);
};
for (int f = 0; f < (int)glslFunctions.size(); ++f) {
glslang::TIntermAggregate* glslFunction = glslFunctions[f]->getAsAggregate();
if (! glslFunction || glslFunction->getOp() != glslang::EOpFunction || isShaderEntryPoint(glslFunction))
@ -2934,11 +2941,13 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
// GLSL has copy-in/copy-out semantics. They can be handled though with a pointer to a copy.
std::vector<spv::Id> paramTypes;
std::vector<spv::Decoration> paramPrecisions;
std::vector<std::vector<spv::Decoration>> paramDecorations; // list of decorations per parameter
glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence();
bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() == glslangIntermediate->implicitThisName;
bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() ==
glslangIntermediate->implicitThisName;
paramDecorations.resize(parameters.size());
for (int p = 0; p < (int)parameters.size(); ++p) {
const glslang::TType& paramType = parameters[p]->getAsTyped()->getType();
spv::Id typeId = convertGlslangToSpvType(paramType);
@ -2952,14 +2961,15 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
typeId = builder.makePointer(spv::StorageClassFunction, typeId);
else
rValueParameters.insert(parameters[p]->getAsSymbolNode()->getId());
paramPrecisions.push_back(TranslatePrecisionDecoration(paramType));
getParamDecorations(paramDecorations[p], paramType);
paramTypes.push_back(typeId);
}
spv::Block* functionBlock;
spv::Function *function = builder.makeFunctionEntry(TranslatePrecisionDecoration(glslFunction->getType()),
convertGlslangToSpvType(glslFunction->getType()),
glslFunction->getName().c_str(), paramTypes, paramPrecisions, &functionBlock);
glslFunction->getName().c_str(), paramTypes,
paramDecorations, &functionBlock);
if (implicitThis)
function->setImplicitThis();

View File

@ -983,16 +983,16 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
Block* entry;
std::vector<Id> params;
std::vector<Decoration> precisions;
std::vector<std::vector<Decoration>> decorations;
entryPointFunction = makeFunctionEntry(NoPrecision, makeVoidType(), entryPoint, params, precisions, &entry);
entryPointFunction = makeFunctionEntry(NoPrecision, makeVoidType(), entryPoint, params, decorations, &entry);
return entryPointFunction;
}
// Comments in header
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
const std::vector<Id>& paramTypes, const std::vector<Decoration>& precisions, Block **entry)
const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& decorations, Block **entry)
{
// Make the function and initial instructions in it
Id typeId = makeFunctionType(returnType, paramTypes);
@ -1001,8 +1001,10 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
// Set up the precisions
setPrecision(function->getId(), precision);
for (unsigned p = 0; p < (unsigned)precisions.size(); ++p)
setPrecision(firstParamId + p, precisions[p]);
for (unsigned p = 0; p < (unsigned)decorations.size(); ++p) {
for (int d = 0; d < (int)decorations[p].size(); ++d)
addDecoration(firstParamId + p, decorations[p][d]);
}
// CFG
if (entry) {

View File

@ -247,7 +247,7 @@ public:
// Return the function, pass back the entry.
// The returned pointer is only valid for the lifetime of this builder.
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector<Id>& paramTypes,
const std::vector<Decoration>& precisions, Block **entry = 0);
const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
// Create a return. An 'implicit' return is one not appearing in the source
// code. In the case of an implicit return, no post-return block is inserted.

View File

@ -289,31 +289,29 @@ void ProcessResourceSetBindingBase(int& argc, char**& argv, std::array<std::vect
usage();
if (!isdigit(argv[1][0])) {
if (argc < 5) // this form needs one more argument
if (argc < 3) // this form needs one more argument
usage();
// Parse form: --argname stage base
// Parse form: --argname stage [regname set base...], or:
// --argname stage set
const EShLanguage lang = FindLanguage(argv[1], false);
base[lang].push_back(argv[2]);
base[lang].push_back(argv[3]);
base[lang].push_back(argv[4]);
argc -= 4;
argv += 4;
while(argv[1] != NULL) {
if(argv[1][0] != '-') {
base[lang].push_back(argv[1]);
base[lang].push_back(argv[2]);
base[lang].push_back(argv[3]);
argc -= 3;
argv += 3;
}
else {
break;
}
argc--;
argv++;
while (argc > 1 && argv[1] != nullptr && argv[1][0] != '-') {
base[lang].push_back(argv[1]);
argc--;
argv++;
}
// Must have one arg, or a multiple of three (for [regname set binding] triples)
if (base[lang].size() != 1 && (base[lang].size() % 3) != 0)
usage();
} else {
// Parse form: --argname base
// Parse form: --argname set
for (int lang=0; lang<EShLangCount; ++lang)
base[lang].push_back(argv[1]);
@ -1187,7 +1185,10 @@ void usage()
" --ku synonym for --keep-uncalled\n"
" --no-storage-format use Unknown image format\n"
" --nsf synonym for --no-storage-format\n"
" --resource-set-binding [stage] num descriptor set and binding for resources\n"
" --resource-set-binding [stage] name set binding\n"
" Set descriptor set and binding for individual resources\n"
" --resource-set-binding [stage] set\n"
" Set descriptor set for all resources\n"
" --rsb [stage] type set binding synonym for --resource-set-binding\n"
" --shift-image-binding [stage] num base binding number for images (uav)\n"
" --sib [stage] num synonym for --shift-image-binding\n"

View File

@ -1,9 +1,10 @@
glspv.frag
ERROR: 0:4: '#error' : GL_SPIRV is set ( correct , not an error )
ERROR: 0:6: '#error' : GL_SPIR is 100
ERROR: 0:14: 'input_attachment_index' : only allowed when using GLSL for Vulkan
ERROR: 0:14: '' : syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON
ERROR: 4 compilation errors. No code generated.
ERROR: 0:14: 'f' : non-opaque uniform variables need a layout(location=L)
ERROR: 0:19: 'input_attachment_index' : only allowed when using GLSL for Vulkan
ERROR: 0:19: '' : syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON
ERROR: 5 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link

View File

@ -0,0 +1,66 @@
hlsl.explicitDescriptorSet.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 31
Capability Shader
Capability Sampled1D
Capability SampledBuffer
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 19
ExecutionMode 4 OriginUpperLeft
Source HLSL 500
Name 4 "main"
Name 9 "@main("
Name 13 "g_sSamp2_amb"
Name 19 "@entryPointOutput"
Name 21 "g_sSamp"
Name 24 "g_tTex1df4"
Name 25 "$Global"
MemberName 25($Global) 0 "floatval_amb"
Name 27 ""
Name 30 "floatbuff"
Decorate 13(g_sSamp2_amb) DescriptorSet 3
Decorate 13(g_sSamp2_amb) Binding 10
Decorate 19(@entryPointOutput) Location 0
Decorate 21(g_sSamp) DescriptorSet 3
Decorate 21(g_sSamp) Binding 11
Decorate 24(g_tTex1df4) DescriptorSet 3
Decorate 24(g_tTex1df4) Binding 20
MemberDecorate 25($Global) 0 Offset 0
Decorate 25($Global) Block
Decorate 27 DescriptorSet 3
Decorate 30(floatbuff) DescriptorSet 3
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypeFunction 7(fvec4)
11: TypeSampler
12: TypePointer UniformConstant 11
13(g_sSamp2_amb): 12(ptr) Variable UniformConstant
14: 6(float) Constant 0
15: 7(fvec4) ConstantComposite 14 14 14 14
18: TypePointer Output 7(fvec4)
19(@entryPointOutput): 18(ptr) Variable Output
21(g_sSamp): 12(ptr) Variable UniformConstant
22: TypeImage 6(float) 1D sampled format:Unknown
23: TypePointer UniformConstant 22
24(g_tTex1df4): 23(ptr) Variable UniformConstant
25($Global): TypeStruct 6(float)
26: TypePointer Uniform 25($Global)
27: 26(ptr) Variable Uniform
28: TypeImage 6(float) Buffer sampled format:R32f
29: TypePointer UniformConstant 28
30(floatbuff): 29(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
20: 7(fvec4) FunctionCall 9(@main()
Store 19(@entryPointOutput) 20
Return
FunctionEnd
9(@main(): 7(fvec4) Function None 8
10: Label
ReturnValue 15
FunctionEnd

View File

@ -0,0 +1,66 @@
hlsl.explicitDescriptorSet.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 31
Capability Shader
Capability Sampled1D
Capability SampledBuffer
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 19
ExecutionMode 4 OriginUpperLeft
Source HLSL 500
Name 4 "main"
Name 9 "@main("
Name 13 "g_sSamp2_amb"
Name 19 "@entryPointOutput"
Name 21 "g_sSamp"
Name 24 "g_tTex1df4"
Name 25 "$Global"
MemberName 25($Global) 0 "floatval_amb"
Name 27 ""
Name 30 "floatbuff"
Decorate 13(g_sSamp2_amb) DescriptorSet 4
Decorate 13(g_sSamp2_amb) Binding 10
Decorate 19(@entryPointOutput) Location 0
Decorate 21(g_sSamp) DescriptorSet 4
Decorate 21(g_sSamp) Binding 11
Decorate 24(g_tTex1df4) DescriptorSet 4
Decorate 24(g_tTex1df4) Binding 20
MemberDecorate 25($Global) 0 Offset 0
Decorate 25($Global) Block
Decorate 27 DescriptorSet 4
Decorate 30(floatbuff) DescriptorSet 4
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypeFunction 7(fvec4)
11: TypeSampler
12: TypePointer UniformConstant 11
13(g_sSamp2_amb): 12(ptr) Variable UniformConstant
14: 6(float) Constant 0
15: 7(fvec4) ConstantComposite 14 14 14 14
18: TypePointer Output 7(fvec4)
19(@entryPointOutput): 18(ptr) Variable Output
21(g_sSamp): 12(ptr) Variable UniformConstant
22: TypeImage 6(float) 1D sampled format:Unknown
23: TypePointer UniformConstant 22
24(g_tTex1df4): 23(ptr) Variable UniformConstant
25($Global): TypeStruct 6(float)
26: TypePointer Uniform 25($Global)
27: 26(ptr) Variable Uniform
28: TypeImage 6(float) Buffer sampled format:R32f
29: TypePointer UniformConstant 28
30(floatbuff): 29(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
20: 7(fvec4) FunctionCall 9(@main()
Store 19(@entryPointOutput) 20
Return
FunctionEnd
9(@main(): 7(fvec4) Function None 8
10: Label
ReturnValue 15
FunctionEnd

View File

@ -184,6 +184,7 @@ gl_FragCoord origin is upper left
MemberDecorate 9 0 NonWritable
MemberDecorate 9 0 Offset 0
Decorate 9 BufferBlock
Decorate 13(sb) NonWritable
Decorate 17 ArrayStride 16
MemberDecorate 18 0 Offset 0
Decorate 18 BufferBlock

View File

@ -166,6 +166,7 @@ local_size = (256, 1, 1)
MemberDecorate 9 0 NonWritable
MemberDecorate 9 0 Offset 0
Decorate 9 BufferBlock
Decorate 14(buffer) NonWritable
Decorate 44(g_input) DescriptorSet 0
Decorate 44(g_input) Binding 0
Decorate 50(g_output) DescriptorSet 0

View File

@ -0,0 +1,137 @@
spv.paramMemory.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 69
Capability Shader
Capability StorageImageReadWithoutFormat
Capability StorageImageWriteWithoutFormat
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 27 66
ExecutionMode 4 OriginUpperLeft
Source ESSL 310
Name 4 "main"
Name 16 "image_load(I21;vi2;"
Name 14 "image"
Name 15 "coords"
Name 23 "image_store(I21;vi2;vf4;"
Name 20 "image"
Name 21 "coords"
Name 22 "data"
Name 27 "in_coords"
Name 35 "read1"
Name 38 "image1"
Name 39 "param"
Name 42 "read2"
Name 45 "image2"
Name 46 "param"
Name 49 "image3"
Name 53 "param"
Name 55 "param"
Name 57 "image4"
Name 61 "param"
Name 63 "param"
Name 66 "out_color"
Decorate 14(image) Coherent
Decorate 14(image) NonWritable
Decorate 20(image) Coherent
Decorate 20(image) NonReadable
Decorate 27(in_coords) Flat
Decorate 27(in_coords) Location 0
Decorate 38(image1) DescriptorSet 0
Decorate 38(image1) Binding 0
Decorate 38(image1) Coherent
Decorate 38(image1) NonWritable
Decorate 45(image2) DescriptorSet 0
Decorate 45(image2) Binding 2
Decorate 45(image2) NonWritable
Decorate 49(image3) DescriptorSet 0
Decorate 49(image3) Binding 1
Decorate 49(image3) Coherent
Decorate 49(image3) NonReadable
Decorate 57(image4) DescriptorSet 0
Decorate 57(image4) Binding 3
Decorate 57(image4) NonReadable
Decorate 66(out_color) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeImage 6(float) 2D nonsampled format:Unknown
8: TypePointer UniformConstant 7
9: TypeInt 32 1
10: TypeVector 9(int) 2
11: TypePointer Function 10(ivec2)
12: TypeVector 6(float) 4
13: TypeFunction 12(fvec4) 8(ptr) 11(ptr)
18: TypePointer Function 12(fvec4)
19: TypeFunction 2 8(ptr) 11(ptr) 18(ptr)
26: TypePointer Input 10(ivec2)
27(in_coords): 26(ptr) Variable Input
36: TypeImage 6(float) 2D nonsampled format:Rgba32f
37: TypePointer UniformConstant 36
38(image1): 37(ptr) Variable UniformConstant
43: TypeImage 6(float) 2D nonsampled format:Rgba16f
44: TypePointer UniformConstant 43
45(image2): 44(ptr) Variable UniformConstant
49(image3): 37(ptr) Variable UniformConstant
51: 6(float) Constant 1056964608
57(image4): 44(ptr) Variable UniformConstant
59: 6(float) Constant 1073741824
65: TypePointer Output 12(fvec4)
66(out_color): 65(ptr) Variable Output
67: 6(float) Constant 0
68: 12(fvec4) ConstantComposite 67 67 67 67
4(main): 2 Function None 3
5: Label
35(read1): 18(ptr) Variable Function
39(param): 11(ptr) Variable Function
42(read2): 18(ptr) Variable Function
46(param): 11(ptr) Variable Function
53(param): 11(ptr) Variable Function
55(param): 18(ptr) Variable Function
61(param): 11(ptr) Variable Function
63(param): 18(ptr) Variable Function
40: 10(ivec2) Load 27(in_coords)
Store 39(param) 40
41: 12(fvec4) FunctionCall 16(image_load(I21;vi2;) 38(image1) 39(param)
Store 35(read1) 41
47: 10(ivec2) Load 27(in_coords)
Store 46(param) 47
48: 12(fvec4) FunctionCall 16(image_load(I21;vi2;) 45(image2) 46(param)
Store 42(read2) 48
50: 12(fvec4) Load 35(read1)
52: 12(fvec4) VectorTimesScalar 50 51
54: 10(ivec2) Load 27(in_coords)
Store 53(param) 54
Store 55(param) 52
56: 2 FunctionCall 23(image_store(I21;vi2;vf4;) 49(image3) 53(param) 55(param)
58: 12(fvec4) Load 42(read2)
60: 12(fvec4) VectorTimesScalar 58 59
62: 10(ivec2) Load 27(in_coords)
Store 61(param) 62
Store 63(param) 60
64: 2 FunctionCall 23(image_store(I21;vi2;vf4;) 57(image4) 61(param) 63(param)
Store 66(out_color) 68
Return
FunctionEnd
16(image_load(I21;vi2;): 12(fvec4) Function None 13
14(image): 8(ptr) FunctionParameter
15(coords): 11(ptr) FunctionParameter
17: Label
25: 7 Load 14(image)
28: 10(ivec2) Load 27(in_coords)
29: 12(fvec4) ImageRead 25 28
ReturnValue 29
FunctionEnd
23(image_store(I21;vi2;vf4;): 2 Function None 19
20(image): 8(ptr) FunctionParameter
21(coords): 11(ptr) FunctionParameter
22(data): 18(ptr) FunctionParameter
24: Label
32: 7 Load 20(image)
33: 10(ivec2) Load 27(in_coords)
34: 12(fvec4) Load 22(data)
ImageWrite 32 33 34
Return
FunctionEnd

View File

@ -1,4 +1,4 @@
#version 330
#version 450
#ifdef GL_SPIRV
#error GL_SPIRV is set ( correct, not an error )
@ -11,4 +11,9 @@ void main()
{
}
uniform float f; // ERROR, no location
layout(location = 2) uniform float g;
uniform sampler2D s1;
layout(location = 3) uniform sampler2D s2;
layout(input_attachment_index = 1) uniform subpassInput sub; // ERROR, no inputs

View File

@ -0,0 +1,15 @@
SamplerState g_sSamp : register(s1);
Texture1D <float4> g_tTex1df4 : register(t0);
SamplerState g_sSamp2_amb;
uniform float floatval_amb;
Buffer<float> floatbuff;
float4 main() : SV_Target0
{
g_sSamp2_amb;
return 0;
}

View File

@ -97,6 +97,12 @@ echo Configuring HLSL descriptor set and binding number manually
$EXE -V -D -e main -H hlsl.multiDescriptorSet.frag --rsb frag t0 0 0 t1 1 0 s0 0 1 s1 1 1 b0 2 0 b1 2 1 b2 2 2 > $TARGETDIR/hlsl.multiDescriptorSet.frag.out
diff -b $BASEDIR/hlsl.multiDescriptorSet.frag.out $TARGETDIR/hlsl.multiDescriptorSet.frag.out || HASERROR=1
$EXE -V -D -e main -H hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb 4 > $TARGETDIR/hlsl.explicitDescriptorSet.frag.out
diff -b $BASEDIR/hlsl.explicitDescriptorSet.frag.out $TARGETDIR/hlsl.explicitDescriptorSet.frag.out || HASERROR=1
$EXE -V -D -e main -H hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb frag 3 > $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out
diff -b $BASEDIR/hlsl.explicitDescriptorSet-2.frag.out $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out || HASERROR=1
#
# Testing location error
#

View File

@ -0,0 +1,30 @@
#version 310 es
readonly coherent uniform layout(set = 0, binding = 0, rgba32f) highp image2D image1;
readonly uniform layout(set = 0, binding = 2, rgba16f) highp image2D image2;
writeonly coherent uniform layout(set = 0, binding = 1, rgba32f) highp image2D image3;
writeonly uniform layout(set = 0, binding = 3, rgba16f) highp image2D image4;
flat in layout(location = 0) highp ivec2 in_coords;
out layout(location = 0) highp vec4 out_color;
highp vec4 image_load(readonly coherent highp image2D image, highp ivec2 coords)
{
return imageLoad(image, in_coords);
}
void image_store(writeonly coherent highp image2D image, highp ivec2 coords, highp vec4 data)
{
imageStore(image, in_coords, data);
}
void main()
{
highp vec4 read1 = image_load(image1, in_coords);
highp vec4 read2 = image_load(image2, in_coords);
image_store(image3, in_coords, read1*0.5);
image_store(image4, in_coords, read2*2.0);
out_color = vec4(0.0);
}

View File

@ -1,8 +1,9 @@
#version 450
layout(constant_id = 3) const int a = 2;
uniform float f;
layout(location = 2) uniform float f;
layout(location = 4) uniform sampler2D s1;
uniform sampler2D s2;
void main()
{

View File

@ -2472,16 +2472,22 @@ void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, co
error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
}
void TParseContext::transparentCheck(const TSourceLoc& loc, const TType& type, const TString& /*identifier*/)
void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
{
if (parsingBuiltins)
return;
// Vulkan doesn't allow transparent uniforms outside of blocks
if (spvVersion.vulkan == 0 || type.getQualifier().storage != EvqUniform)
if (type.getQualifier().storage != EvqUniform)
return;
if (type.containsNonOpaque())
vulkanRemoved(loc, "non-opaque uniforms outside a block");
if (type.containsNonOpaque()) {
// Vulkan doesn't allow transparent uniforms outside of blocks
if (spvVersion.vulkan > 0)
vulkanRemoved(loc, "non-opaque uniforms outside a block");
// OpenGL wants locations on these
if (spvVersion.openGl > 0 && !type.getQualifier().hasLocation())
error(loc, "non-opaque uniform variables need a layout(location=L)", identifier.c_str(), "");
}
}
//
@ -5107,7 +5113,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
samplerCheck(loc, type, identifier, initializer);
atomicUintCheck(loc, type, identifier);
transparentCheck(loc, type, identifier);
transparentOpaqueCheck(loc, type, identifier);
if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");

View File

@ -327,7 +327,7 @@ public:
void boolCheck(const TSourceLoc&, const TPublicType&);
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
void transparentCheck(const TSourceLoc&, const TType&, const TString& identifier);
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&);
void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);

View File

@ -1836,6 +1836,7 @@ const char* TProgram::getUniformName(int index) const { return reflection
const char* TProgram::getUniformBlockName(int index) const { return reflection->getUniformBlock(index).name.c_str(); }
int TProgram::getUniformBlockSize(int index) const { return reflection->getUniformBlock(index).size; }
int TProgram::getUniformIndex(const char* name) const { return reflection->getIndex(name); }
int TProgram::getUniformBinding(int index) const { return reflection->getUniform(index).getBinding(); }
int TProgram::getUniformBlockIndex(int index) const { return reflection->getUniform(index).index; }
int TProgram::getUniformBlockCounterIndex(int index) const { return reflection->getUniformBlock(index).counterIndex; }
int TProgram::getUniformType(int index) const { return reflection->getUniform(index).glDefineType; }

View File

@ -404,6 +404,11 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
{
if (type.getQualifier().hasSet())
return type.getQualifier().layoutSet;
// If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN)
if (baseResourceSetBinding.size() == 1)
return atoi(baseResourceSetBinding[0].c_str());
return 0;
}

View File

@ -59,7 +59,15 @@ public:
name(pName), offset(pOffset),
glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), type(pType.clone()) { }
void dump() const {
const TType* const getType() const { return type; }
int getBinding() const
{
if (type == nullptr || !type->getQualifier().hasBinding())
return -1;
return type->getQualifier().layoutBinding;
}
void dump() const
{
printf("%s: offset %d, type %x, size %d, index %d, binding %d",
name.c_str(), offset, glDefineType, size, index, getBinding() );
@ -68,8 +76,7 @@ public:
printf("\n");
}
const TType* const getType() const { return type; }
static TObjectReflection badReflection() { return TObjectReflection(); }
TString name;
int offset;
@ -78,15 +85,7 @@ public:
int index;
int counterIndex;
static TObjectReflection badReflection() { return TObjectReflection(); }
protected:
int getBinding() const {
if (type == nullptr || type->getQualifier().layoutBinding == TQualifier::layoutBindingEnd)
return -1;
return type->getQualifier().layoutBinding;
}
TObjectReflection() : offset(-1), glDefineType(-1), size(-1), index(-1), type(nullptr) { }
const TType* type;

View File

@ -619,6 +619,7 @@ public:
const char* getUniformBlockName(int blockIndex) const; // can be used for glGetActiveUniformBlockName()
int getUniformBlockSize(int blockIndex) const; // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE)
int getUniformIndex(const char* name) const; // can be used for glGetUniformIndices()
int getUniformBinding(int index) const; // returns the binding number
int getUniformBlockIndex(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX)
int getUniformBlockCounterIndex(int index) const; // returns block index of associated counter.
int getUniformType(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE)

View File

@ -275,6 +275,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.noWorkgroup.comp",
"spv.offsets.frag",
"spv.Operations.frag",
"spv.paramMemory.frag",
"spv.precision.frag",
"spv.prepost.frag",
"spv.qualifiers.vert",

View File

@ -5411,7 +5411,7 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi
}
// TODO: learn what all these really mean and how they interact with regNumber and subComponent
std::vector<std::string> resourceInfo = intermediate.getResourceSetBinding();
const std::vector<std::string>& resourceInfo = intermediate.getResourceSetBinding();
switch (std::tolower(desc[0])) {
case 'b':
case 't':
@ -5419,11 +5419,17 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi
case 's':
case 'u':
qualifier.layoutBinding = regNumber + subComponent;
for (auto it = resourceInfo.cbegin(); it != resourceInfo.cend(); it = it + 3) {
if (strcmp(desc.c_str(), it[0].c_str()) == 0) {
qualifier.layoutSet = atoi(it[1].c_str());
qualifier.layoutBinding = atoi(it[2].c_str()) + subComponent;
break;
// This handles per-register layout sets numbers. For the global mode which sets
// every symbol to the same value, see setLinkageLayoutSets().
if ((resourceInfo.size() % 3) == 0) {
// Apply per-symbol resource set and binding.
for (auto it = resourceInfo.cbegin(); it != resourceInfo.cend(); it = it + 3) {
if (strcmp(desc.c_str(), it[0].c_str()) == 0) {
qualifier.layoutSet = atoi(it[1].c_str());
qualifier.layoutBinding = atoi(it[2].c_str()) + subComponent;
break;
}
}
}
break;