From f60f09534672f3e921856d74e108ec042126ca6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Sun, 5 May 2019 18:50:18 -0700 Subject: [PATCH] Updated glslang. --- 3rdparty/glslang/SPIRV/SpvPostProcess.cpp | 73 ++++++++++++++----- .../glslang/Test/baseResults/430.vert.out | 3 +- .../spv.float16convertonlyarith.comp.out | 39 ++++++++++ .../spv.float16convertonlystorage.comp.out | 39 ++++++++++ .../glslang/Test/baseResults/vulkan.vert.out | 21 +++++- .../Test/spv.float16convertonlyarith.comp | 11 +++ .../Test/spv.float16convertonlystorage.comp | 11 +++ 3rdparty/glslang/Test/vulkan.vert | 12 +++ 3rdparty/glslang/glslang/Include/revision.h | 2 +- .../MachineIndependent/Intermediate.cpp | 52 +++++++++++++ .../MachineIndependent/ParseHelper.cpp | 46 ++++++++++++ .../glslang/MachineIndependent/attribute.cpp | 3 + 3rdparty/glslang/gtests/Spv.FromFile.cpp | 2 + 3rdparty/glslang/hlsl/hlslParseHelper.cpp | 11 ++- 14 files changed, 302 insertions(+), 23 deletions(-) create mode 100644 3rdparty/glslang/Test/baseResults/spv.float16convertonlyarith.comp.out create mode 100644 3rdparty/glslang/Test/baseResults/spv.float16convertonlystorage.comp.out create mode 100644 3rdparty/glslang/Test/spv.float16convertonlyarith.comp create mode 100644 3rdparty/glslang/Test/spv.float16convertonlystorage.comp diff --git a/3rdparty/glslang/SPIRV/SpvPostProcess.cpp b/3rdparty/glslang/SPIRV/SpvPostProcess.cpp index 80471cae0..6e1f7cf61 100644 --- a/3rdparty/glslang/SPIRV/SpvPostProcess.cpp +++ b/3rdparty/glslang/SPIRV/SpvPostProcess.cpp @@ -118,9 +118,46 @@ void Builder::postProcessType(const Instruction& inst, Id typeId) case OpAccessChain: case OpPtrAccessChain: case OpCopyObject: + break; case OpFConvert: case OpSConvert: case OpUConvert: + // Look for any 8/16-bit storage capabilities. If there are none, assume that + // the convert instruction requires the Float16/Int8/16 capability. + if (containsType(typeId, OpTypeFloat, 16) || containsType(typeId, OpTypeInt, 16)) { + bool foundStorage = false; + for (auto it = capabilities.begin(); it != capabilities.end(); ++it) { + spv::Capability cap = *it; + if (cap == spv::CapabilityStorageInputOutput16 || + cap == spv::CapabilityStoragePushConstant16 || + cap == spv::CapabilityStorageUniformBufferBlock16 || + cap == spv::CapabilityStorageUniform16) { + foundStorage = true; + break; + } + } + if (!foundStorage) { + if (containsType(typeId, OpTypeFloat, 16)) + addCapability(CapabilityFloat16); + if (containsType(typeId, OpTypeInt, 16)) + addCapability(CapabilityInt16); + } + } + if (containsType(typeId, OpTypeInt, 8)) { + bool foundStorage = false; + for (auto it = capabilities.begin(); it != capabilities.end(); ++it) { + spv::Capability cap = *it; + if (cap == spv::CapabilityStoragePushConstant8 || + cap == spv::CapabilityUniformAndStorageBuffer8BitAccess || + cap == spv::CapabilityStorageBuffer8BitAccess) { + foundStorage = true; + break; + } + } + if (!foundStorage) { + addCapability(CapabilityInt8); + } + } break; case OpExtInst: #if AMD_EXTENSIONS @@ -327,6 +364,24 @@ void Builder::postProcess() // Add per-instruction capabilities, extensions, etc., + // Look for any 8/16 bit type in physical storage buffer class, and set the + // appropriate capability. This happens in createSpvVariable for other storage + // classes, but there isn't always a variable for physical storage buffer. + for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) { + Instruction* type = groupedTypes[OpTypePointer][t]; + if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) { + if (containsType(type->getIdOperand(1), OpTypeInt, 8)) { + addExtension(spv::E_SPV_KHR_8bit_storage); + addCapability(spv::CapabilityStorageBuffer8BitAccess); + } + if (containsType(type->getIdOperand(1), OpTypeInt, 16) || + containsType(type->getIdOperand(1), OpTypeFloat, 16)) { + addExtension(spv::E_SPV_KHR_16bit_storage); + addCapability(spv::CapabilityStorageBuffer16BitAccess); + } + } + } + // process all reachable instructions... for (auto bi = reachableBlocks.cbegin(); bi != reachableBlocks.cend(); ++bi) { const Block* block = *bi; @@ -366,24 +421,6 @@ void Builder::postProcess() } } } - - // Look for any 8/16 bit type in physical storage buffer class, and set the - // appropriate capability. This happens in createSpvVariable for other storage - // classes, but there isn't always a variable for physical storage buffer. - for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) { - Instruction* type = groupedTypes[OpTypePointer][t]; - if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) { - if (containsType(type->getIdOperand(1), OpTypeInt, 8)) { - addExtension(spv::E_SPV_KHR_8bit_storage); - addCapability(spv::CapabilityStorageBuffer8BitAccess); - } - if (containsType(type->getIdOperand(1), OpTypeInt, 16) || - containsType(type->getIdOperand(1), OpTypeFloat, 16)) { - addExtension(spv::E_SPV_KHR_16bit_storage); - addCapability(spv::CapabilityStorageBuffer16BitAccess); - } - } - } } }; // end spv namespace diff --git a/3rdparty/glslang/Test/baseResults/430.vert.out b/3rdparty/glslang/Test/baseResults/430.vert.out index f57a39c1f..d741d357a 100644 --- a/3rdparty/glslang/Test/baseResults/430.vert.out +++ b/3rdparty/glslang/Test/baseResults/430.vert.out @@ -17,6 +17,7 @@ ERROR: 0:47: 'gl_ClipDistance array size' : must be less than or equal to gl_Max ERROR: 0:51: 'start' : undeclared identifier ERROR: 0:51: '' : constant expression required ERROR: 0:51: 'layout-id value' : scalar integer expression required +ERROR: 0:51: 'location' : needs a literal integer ERROR: 0:53: 'input block' : not supported in this stage: vertex ERROR: 0:54: 'location on block member' : not supported for this version or the enabled extensions ERROR: 0:57: 'input block' : not supported in this stage: vertex @@ -63,7 +64,7 @@ ERROR: 0:221: 'textureQueryLevels' : no matching overloaded function found ERROR: 0:221: 'assign' : cannot convert from ' const float' to ' temp int' ERROR: 0:222: 'textureQueryLevels' : no matching overloaded function found ERROR: 0:222: 'assign' : cannot convert from ' const float' to ' temp int' -ERROR: 64 compilation errors. No code generated. +ERROR: 65 compilation errors. No code generated. Shader version: 430 diff --git a/3rdparty/glslang/Test/baseResults/spv.float16convertonlyarith.comp.out b/3rdparty/glslang/Test/baseResults/spv.float16convertonlyarith.comp.out new file mode 100644 index 000000000..6abf0d4a5 --- /dev/null +++ b/3rdparty/glslang/Test/baseResults/spv.float16convertonlyarith.comp.out @@ -0,0 +1,39 @@ +spv.float16convertonlyarith.comp +// Module Version 10000 +// Generated by (magic number): 80007 +// Id's are bound by 22 + + Capability Shader + Capability Float16 + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint GLCompute 4 "main" + ExecutionMode 4 LocalSize 16 16 1 + Source GLSL 450 + SourceExtension "GL_EXT_shader_explicit_arithmetic_types_float16" + Name 4 "main" + Name 9 "v" + Decorate 21 BuiltIn WorkgroupSize + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Function 7(fvec4) + 10: 6(float) Constant 0 + 11: 7(fvec4) ConstantComposite 10 10 10 10 + 13: TypeFloat 16 + 14: TypeVector 13(float16_t) 4 + 17: TypeInt 32 0 + 18: TypeVector 17(int) 3 + 19: 17(int) Constant 16 + 20: 17(int) Constant 1 + 21: 18(ivec3) ConstantComposite 19 19 20 + 4(main): 2 Function None 3 + 5: Label + 9(v): 8(ptr) Variable Function + Store 9(v) 11 + 12: 7(fvec4) Load 9(v) + 15: 14(f16vec4) FConvert 12 + 16: 7(fvec4) FConvert 15 + Return + FunctionEnd diff --git a/3rdparty/glslang/Test/baseResults/spv.float16convertonlystorage.comp.out b/3rdparty/glslang/Test/baseResults/spv.float16convertonlystorage.comp.out new file mode 100644 index 000000000..a2ff1d09c --- /dev/null +++ b/3rdparty/glslang/Test/baseResults/spv.float16convertonlystorage.comp.out @@ -0,0 +1,39 @@ +spv.float16convertonlystorage.comp +// Module Version 10000 +// Generated by (magic number): 80007 +// Id's are bound by 22 + + Capability Shader + Capability Float16 + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint GLCompute 4 "main" + ExecutionMode 4 LocalSize 16 16 1 + Source GLSL 450 + SourceExtension "GL_EXT_shader_16bit_storage" + Name 4 "main" + Name 9 "v" + Decorate 21 BuiltIn WorkgroupSize + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Function 7(fvec4) + 10: 6(float) Constant 0 + 11: 7(fvec4) ConstantComposite 10 10 10 10 + 13: TypeFloat 16 + 14: TypeVector 13(float16_t) 4 + 17: TypeInt 32 0 + 18: TypeVector 17(int) 3 + 19: 17(int) Constant 16 + 20: 17(int) Constant 1 + 21: 18(ivec3) ConstantComposite 19 19 20 + 4(main): 2 Function None 3 + 5: Label + 9(v): 8(ptr) Variable Function + Store 9(v) 11 + 12: 7(fvec4) Load 9(v) + 15: 14(f16vec4) FConvert 12 + 16: 7(fvec4) FConvert 15 + Return + FunctionEnd diff --git a/3rdparty/glslang/Test/baseResults/vulkan.vert.out b/3rdparty/glslang/Test/baseResults/vulkan.vert.out index 6bfa188aa..7ee611a08 100644 --- a/3rdparty/glslang/Test/baseResults/vulkan.vert.out +++ b/3rdparty/glslang/Test/baseResults/vulkan.vert.out @@ -34,7 +34,26 @@ ERROR: 0:54: '[]' : only outermost dimension of an array of arrays can be a spec ERROR: 0:54: 'location' : SPIR-V requires location for user input/output ERROR: 0:58: 'location' : SPIR-V requires location for user input/output ERROR: 0:65: 'location' : overlapping use of location 10 -ERROR: 35 compilation errors. No code generated. +ERROR: 0:68: 'location' : needs a literal integer +ERROR: 0:68: 'component' : needs a literal integer +ERROR: 0:69: 'binding' : needs a literal integer +ERROR: 0:69: 'set' : needs a literal integer +ERROR: 0:70: 'offset' : needs a literal integer +ERROR: 0:71: 'align' : must be a power of 2 +ERROR: 0:71: 'align' : needs a literal integer +ERROR: 0:72: 'xfb_offset' : needs a literal integer +ERROR: 0:73: 'xfb_buffer' : needs a literal integer +ERROR: 0:74: 'xfb_stride' : needs a literal integer +ERROR: 0:73: 'xfb_buffer' : member cannot contradict block (or what block inherited from global) +ERROR: 0:72: 'xfb layout qualifier' : can only be used on an output +ERROR: 0:73: 'xfb layout qualifier' : can only be used on an output +ERROR: 0:74: 'xfb layout qualifier' : can only be used on an output +ERROR: 0:76: 'input_attachment_index' : needs a literal integer +ERROR: 0:76: 'input_attachment_index' : can only be used with a subpass +ERROR: 0:77: 'constant_id' : needs a literal integer +ERROR: 0:77: 'constant_id' : can only be applied to 'const'-qualified scalar +ERROR: 0:77: 'constant_id' : can only be applied to a scalar +ERROR: 54 compilation errors. No code generated. SPIR-V is not generated for failed compile or link diff --git a/3rdparty/glslang/Test/spv.float16convertonlyarith.comp b/3rdparty/glslang/Test/spv.float16convertonlyarith.comp new file mode 100644 index 000000000..9a2e3310a --- /dev/null +++ b/3rdparty/glslang/Test/spv.float16convertonlyarith.comp @@ -0,0 +1,11 @@ +#version 450 core + +#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require + +layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; + +void main() +{ + vec4 v = vec4(0.0); + vec4(f16vec4(v)); +} \ No newline at end of file diff --git a/3rdparty/glslang/Test/spv.float16convertonlystorage.comp b/3rdparty/glslang/Test/spv.float16convertonlystorage.comp new file mode 100644 index 000000000..3f8e157e9 --- /dev/null +++ b/3rdparty/glslang/Test/spv.float16convertonlystorage.comp @@ -0,0 +1,11 @@ +#version 450 core + +#extension GL_EXT_shader_16bit_storage : require + +layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; + +void main() +{ + vec4 v = vec4(0.0); + vec4(f16vec4(v)); +} \ No newline at end of file diff --git a/3rdparty/glslang/Test/vulkan.vert b/3rdparty/glslang/Test/vulkan.vert index 0fad1de9d..99456b9f0 100644 --- a/3rdparty/glslang/Test/vulkan.vert +++ b/3rdparty/glslang/Test/vulkan.vert @@ -63,3 +63,15 @@ layout(binding = 3000) uniform sampler2D s3000; layout(binding = 3001) uniform b3001 { int a; }; layout(location = 10) in vec4 in1; layout(location = 10) in vec4 in2; // ERROR, no location aliasing + +layout(constant_id = 400) const int nonLit = 1; +layout(location = nonLit, component = nonLit) in vec4 nonLit1; // ERROR, non literal +layout(binding = nonLit, set = nonLit) uniform nonLitBN { // ERROR, non literal + layout(offset = nonLit) vec4 nonLit1; // ERROR, non literal + layout(align = nonLit) vec4 nonLit3; // ERROR, non literal + layout(xfb_offset = nonLit) vec4 nonLit4; // ERROR, non literal + layout(xfb_buffer = nonLit) vec4 nonLit5; // ERROR, non literal + layout(xfb_stride = nonLit) vec4 nonLit6; // ERROR, non literal +} nonLitBI; +layout(input_attachment_index = nonLit) vec4 nonLit3; // ERROR, non literal +layout(constant_id = nonLit) vec4 nonLit4; // ERROR, non literal diff --git a/3rdparty/glslang/glslang/Include/revision.h b/3rdparty/glslang/glslang/Include/revision.h index dad700931..68ce76689 100644 --- a/3rdparty/glslang/glslang/Include/revision.h +++ b/3rdparty/glslang/glslang/Include/revision.h @@ -1,3 +1,3 @@ // This header is generated by the make-revision script. -#define GLSLANG_PATCH_LEVEL 3204 +#define GLSLANG_PATCH_LEVEL 3205 diff --git a/3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp b/3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp index 4ec728d0f..348b27209 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp @@ -498,6 +498,58 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped TOperator newOp = EOpNull; + // Certain explicit conversions are allowed conditionally + bool arithemeticInt8Enabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8); +#ifdef AMD_EXTENSIONS + bool arithemeticInt16Enabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16) || + extensionRequested(E_GL_AMD_gpu_shader_int16); + + bool arithemeticFloat16Enabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16) || + extensionRequested(E_GL_AMD_gpu_shader_half_float); +#else + bool arithemeticInt16Enabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16); + + bool arithemeticFloat16Enabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16); +#endif + bool convertToIntTypes = (convertTo == EbtInt8 || convertTo == EbtUint8 || + convertTo == EbtInt16 || convertTo == EbtUint16 || + convertTo == EbtInt || convertTo == EbtUint || + convertTo == EbtInt64 || convertTo == EbtUint64); + + bool convertFromIntTypes = (node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8 || + node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16 || + node->getBasicType() == EbtInt || node->getBasicType() == EbtUint || + node->getBasicType() == EbtInt64 || node->getBasicType() == EbtUint64); + + bool convertToFloatTypes = (convertTo == EbtFloat16 || convertTo == EbtFloat || convertTo == EbtDouble); + + bool convertFromFloatTypes = (node->getBasicType() == EbtFloat16 || + node->getBasicType() == EbtFloat || + node->getBasicType() == EbtDouble); + + if (! arithemeticInt8Enabled) { + if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) || + ((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes)) + return nullptr; + } + + if (! arithemeticInt16Enabled) { + if (((convertTo == EbtInt16 || convertTo == EbtUint16) && ! convertFromIntTypes) || + ((node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16) && ! convertToIntTypes)) + return nullptr; + } + + if (! arithemeticFloat16Enabled) { + if ((convertTo == EbtFloat16 && ! convertFromFloatTypes) || + (node->getBasicType() == EbtFloat16 && ! convertToFloatTypes)) + return nullptr; + } + switch (convertTo) { case EbtDouble: switch (node->getBasicType()) { diff --git a/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp b/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp index 8f575fbbb..62aba52a6 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp @@ -5003,6 +5003,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi integerCheck(node, feature); const TIntermConstantUnion* constUnion = node->getAsConstantUnion(); int value; + bool nonLiteral = false; if (constUnion) { value = constUnion->getConstArray()[0].getIConst(); if (! constUnion->isLiteral()) { @@ -5012,6 +5013,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } else { // grammar should have give out the error message value = 0; + nonLiteral = true; } if (value < 0) { @@ -5033,6 +5035,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi profileRequires(loc, EEsProfile, 310, nullptr, feature); } publicType.qualifier.layoutOffset = value; + if (nonLiteral) + error(loc, "needs a literal integer", "offset", ""); return; } else if (id == "align") { const char* feature = "uniform buffer-member align"; @@ -5045,6 +5049,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "must be a power of 2", "align", ""); else publicType.qualifier.layoutAlign = value; + if (nonLiteral) + error(loc, "needs a literal integer", "align", ""); return; } else if (id == "location") { profileRequires(loc, EEsProfile, 300, nullptr, "location"); @@ -5054,6 +5060,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "location is too large", id.c_str(), ""); else publicType.qualifier.layoutLocation = value; + if (nonLiteral) + error(loc, "needs a literal integer", "location", ""); return; } else if (id == "set") { if ((unsigned int)value >= TQualifier::layoutSetEnd) @@ -5062,6 +5070,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.qualifier.layoutSet = value; if (value != 0) requireVulkan(loc, "descriptor set"); + if (nonLiteral) + error(loc, "needs a literal integer", "set", ""); return; } else if (id == "binding") { profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding"); @@ -5070,6 +5080,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "binding is too large", id.c_str(), ""); else publicType.qualifier.layoutBinding = value; + if (nonLiteral) + error(loc, "needs a literal integer", "binding", ""); return; } else if (id == "component") { requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component"); @@ -5078,6 +5090,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "component is too large", id.c_str(), ""); else publicType.qualifier.layoutComponent = value; + if (nonLiteral) + error(loc, "needs a literal integer", "component", ""); return; } else if (id.compare(0, 4, "xfb_") == 0) { // "Any shader making any static use (after preprocessing) of any of these @@ -5098,12 +5112,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1); else publicType.qualifier.layoutXfbBuffer = value; + if (nonLiteral) + error(loc, "needs a literal integer", "xfb_buffer", ""); return; } else if (id == "xfb_offset") { if (value >= (int)TQualifier::layoutXfbOffsetEnd) error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd-1); else publicType.qualifier.layoutXfbOffset = value; + if (nonLiteral) + error(loc, "needs a literal integer", "xfb_offset", ""); return; } else if (id == "xfb_stride") { // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the @@ -5116,6 +5134,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd-1); else publicType.qualifier.layoutXfbStride = value; + if (nonLiteral) + error(loc, "needs a literal integer", "xfb_stride", ""); return; } } @@ -5126,6 +5146,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "attachment index is too large", id.c_str(), ""); else publicType.qualifier.layoutAttachment = value; + if (nonLiteral) + error(loc, "needs a literal integer", "input_attachment_index", ""); return; } if (id == "constant_id") { @@ -5138,11 +5160,15 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi if (! intermediate.addUsedConstantId(value)) error(loc, "specialization-constant id already used", id.c_str(), ""); } + if (nonLiteral) + error(loc, "needs a literal integer", "constant_id", ""); return; } if (id == "num_views") { requireExtensions(loc, Num_OVR_multiview_EXTs, OVR_multiview_EXTs, "num_views"); publicType.shaderQualifiers.numViews = value; + if (nonLiteral) + error(loc, "needs a literal integer", "num_views", ""); return; } @@ -5154,6 +5180,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi if (id == "secondary_view_offset") { requireExtensions(loc, 1, &E_GL_NV_stereo_view_rendering, "stereo view rendering"); publicType.qualifier.layoutSecondaryViewportRelativeOffset = value; + if (nonLiteral) + error(loc, "needs a literal integer", "secondary_view_offset", ""); return; } } @@ -5165,6 +5193,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "must be a power of 2", "buffer_reference_align", ""); else publicType.qualifier.layoutBufferReferenceAlign = (unsigned int)std::log2(value); + if (nonLiteral) + error(loc, "needs a literal integer", "buffer_reference_align", ""); return; } @@ -5178,6 +5208,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "must be greater than 0", "vertices", ""); else publicType.shaderQualifiers.vertices = value; + if (nonLiteral) + error(loc, "needs a literal integer", "vertices", ""); return; } break; @@ -5192,12 +5224,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "must be at least 1", "invocations", ""); else publicType.shaderQualifiers.invocations = value; + if (nonLiteral) + error(loc, "needs a literal integer", "invocations", ""); return; } if (id == "max_vertices") { publicType.shaderQualifiers.vertices = value; if (value > resources.maxGeometryOutputVertices) error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", ""); + if (nonLiteral) + error(loc, "needs a literal integer", "max_vertices", ""); return; } if (id == "stream") { @@ -5205,6 +5241,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.qualifier.layoutStream = value; if (value > 0) intermediate.setMultiStream(); + if (nonLiteral) + error(loc, "needs a literal integer", "stream", ""); return; } break; @@ -5222,6 +5260,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } publicType.qualifier.layoutIndex = value; + if (nonLiteral) + error(loc, "needs a literal integer", "index", ""); return; } break; @@ -5233,6 +5273,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.shaderQualifiers.vertices = value; if (value > resources.maxMeshOutputVerticesNV) error(loc, "too large, must be less than gl_MaxMeshOutputVerticesNV", "max_vertices", ""); + if (nonLiteral) + error(loc, "needs a literal integer", "max_vertices", ""); return; } if (id == "max_primitives") { @@ -5240,6 +5282,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.shaderQualifiers.primitives = value; if (value > resources.maxMeshOutputPrimitivesNV) error(loc, "too large, must be less than gl_MaxMeshOutputPrimitivesNV", "max_primitives", ""); + if (nonLiteral) + error(loc, "needs a literal integer", "max_primitives", ""); return; } // Fall through @@ -5259,6 +5303,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize"); profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize"); } + if (nonLiteral) + error(loc, "needs a literal integer", "local_size", ""); if (id.size() == 12 && value == 0) { error(loc, "must be at least 1", id.c_str(), ""); return; diff --git a/3rdparty/glslang/glslang/MachineIndependent/attribute.cpp b/3rdparty/glslang/glslang/MachineIndependent/attribute.cpp index 73b665d80..bf960ffe6 100644 --- a/3rdparty/glslang/glslang/MachineIndependent/attribute.cpp +++ b/3rdparty/glslang/glslang/MachineIndependent/attribute.cpp @@ -85,6 +85,9 @@ const TConstUnion* TAttributeArgs::getConstUnion(TBasicType basicType, int argNu if (argNum >= (int)args->getSequence().size()) return nullptr; + if (args->getSequence()[argNum]->getAsConstantUnion() == nullptr) + return nullptr; + const TConstUnion* constVal = &args->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0]; if (constVal == nullptr || constVal->getType() != basicType) return nullptr; diff --git a/3rdparty/glslang/gtests/Spv.FromFile.cpp b/3rdparty/glslang/gtests/Spv.FromFile.cpp index 4663df63b..2928e005d 100644 --- a/3rdparty/glslang/gtests/Spv.FromFile.cpp +++ b/3rdparty/glslang/gtests/Spv.FromFile.cpp @@ -300,6 +300,8 @@ INSTANTIATE_TEST_CASE_P( "spv.earlyReturnDiscard.frag", "spv.extPostDepthCoverage.frag", "spv.extPostDepthCoverage_Error.frag", + "spv.float16convertonlyarith.comp", + "spv.float16convertonlystorage.comp", "spv.flowControl.frag", "spv.forLoop.frag", "spv.forwardFun.frag", diff --git a/3rdparty/glslang/hlsl/hlslParseHelper.cpp b/3rdparty/glslang/hlsl/hlslParseHelper.cpp index 213f236d0..567431049 100644 --- a/3rdparty/glslang/hlsl/hlslParseHelper.cpp +++ b/3rdparty/glslang/hlsl/hlslParseHelper.cpp @@ -1899,13 +1899,16 @@ void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttr // location if (it->getInt(value)) type.getQualifier().layoutLocation = value; + else + error(loc, "needs a literal integer", "location", ""); break; case EatBinding: // binding if (it->getInt(value)) { type.getQualifier().layoutBinding = value; type.getQualifier().layoutSet = 0; - } + } else + error(loc, "needs a literal integer", "binding", ""); // set if (it->getInt(value, 1)) type.getQualifier().layoutSet = value; @@ -1914,7 +1917,9 @@ void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttr // global cbuffer binding if (it->getInt(value)) globalUniformBinding = value; - // global cbuffer binding + else + error(loc, "needs a literal integer", "global binding", ""); + // global cbuffer set if (it->getInt(value, 1)) globalUniformSet = value; break; @@ -1922,6 +1927,8 @@ void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttr // input attachment if (it->getInt(value)) type.getQualifier().layoutAttachment = value; + else + error(loc, "needs a literal integer", "input attachment", ""); break; case EatBuiltIn: // PointSize built-in