diff --git a/SPIRV/GLSL.ext.KHR.h b/SPIRV/GLSL.ext.KHR.h index de8896d16d..482548f951 100644 --- a/SPIRV/GLSL.ext.KHR.h +++ b/SPIRV/GLSL.ext.KHR.h @@ -68,4 +68,6 @@ static const char* const E_SPV_NV_cooperative_vector = "SPV_NV_cooper static const char* const E_SPV_KHR_bfloat16 = "SPV_KHR_bfloat16"; static const char* const E_SPV_EXT_descriptor_heap = "SPV_EXT_descriptor_heap"; static const char* const E_SPV_KHR_untyped_pointers = "SPV_KHR_untyped_pointers"; +static const char* const E_SPV_KHR_abort = "SPV_KHR_abort"; +static const char* const E_SPV_KHR_constant_data = "SPV_KHR_constant_data"; #endif // #ifndef GLSLextKHR_H diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 06b33ff31c..9f5143c83f 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -246,6 +246,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { spv::Id translateForcedType(spv::Id object); spv::Id createCompositeConstruct(spv::Id typeId, std::vector constituents); void recordDescHeapAccessChainInfo(glslang::TIntermBinary* node); + void createAbortEXT(const glslang::TIntermSequence glslangOperands); glslang::SpvOptions& options; spv::Function* shaderEntry; @@ -3136,6 +3137,101 @@ spv::Id TGlslangToSpvTraverser::createCompositeConstruct(spv::Id resultTypeId, s return builder.createCompositeConstruct(resultTypeId, constituents); } +void TGlslangToSpvTraverser::createAbortEXT(const glslang::TIntermSequence glslangOperands) +{ + bool isEmptyMsg = glslangOperands.size() == 0; + // Add Capability and extensions. + builder.addCapability(spv::Capability::AbortKHR); + builder.addCapability(spv::Capability::ConstantDataKHR); + builder.addExtension(spv::E_SPV_KHR_constant_data); + builder.addExtension(spv::E_SPV_KHR_abort); + + typedef struct constStrInfo { + glslang::TString string; + int specifierIndex; // -1 if not a specifier. + constStrInfo(glslang::TString str, int spec) : string(str), specifierIndex(spec){}; + } strInfo; + + std::vector splitedStr, tempSplitedStr; + const uint32_t formatSpecifiersSize = 4; + const char* formatSpecifiers[formatSpecifiersSize] = {"%d", "%i", "%f", "%u"}; + // 1. Split original message string with format specifiers. + const glslang::TString* msg = !isEmptyMsg ? glslangOperands[0]->getAsConstantUnion()->getConstArray()[0].getSConst() + : new glslang::TString("\0"); + splitedStr.push_back(strInfo(*const_cast(msg), -1)); + for (uint32_t i = 0; i < formatSpecifiersSize; i++) { + for (uint32_t j = 0; j < splitedStr.size(); j++) { + auto str = splitedStr[j].string; + int specifierIndex = splitedStr[j].specifierIndex; + auto pos = str.find(formatSpecifiers[i]); + while (pos != std::string::npos) { + tempSplitedStr.push_back(strInfo(str.substr(0, pos), specifierIndex)); + tempSplitedStr.push_back(strInfo(glslang::TString(formatSpecifiers[i]), i)); + str = str.substr(pos + strlen(formatSpecifiers[i])); + pos = str.find(formatSpecifiers[i]); + } + if (str.size() > 0 || isEmptyMsg) + tempSplitedStr.push_back(strInfo(str, specifierIndex)); + } + splitedStr.clear(); + splitedStr = tempSplitedStr; + tempSplitedStr.clear(); + } + // 2. Prepare to construct message struct variable, record members' types, data and offsets. + std::vector structMemberOffsets; + std::vector structMemberType; + std::vector structLoadMemberType; + std::vector structMemberData; + structMemberOffsets.push_back(0); + auto charType = builder.makeIntType(8); + for (auto elem : splitedStr) { + // 2.1 get sub string's length (if specifier, be spec const). + unsigned int strElemLen = isEmptyMsg ? 1 : elem.string.size(); + spv::Id constLen = builder.makeUintConstant(strElemLen); + spv::Op constDataOp = spv::Op::OpConstantDataKHR; + if (elem.specifierIndex >= 0) { + constLen = builder.createSpecConst(spv::Op::OpSpecConstant, builder.makeUintType(32), strElemLen); + constDataOp = spv::Op::OpSpecConstantDataKHR; + } + // 2.2 get sub string's array type (if specifier, be spec const). + auto strElemArrType = builder.makeArrayType(charType, constLen, 1); + auto strElemLoadArrType = builder.makeArrayType(charType, constLen, 1); + // 2.3 add sub string constant data + auto strElemConstData = builder.createConstData(constDataOp, strElemArrType, {elem.string.c_str()}); + // 2.4 add decoration for those sub string. + builder.addDecoration(strElemArrType, spv::Decoration::UTFCodePointsKHR); + builder.addDecoration(strElemLoadArrType, spv::Decoration::UTFCodePointsKHR); + builder.addDecoration(strElemLoadArrType, spv::Decoration::ArrayStride, 1); + // 2.5 Collect data and type for construct an internal message structure member. + structMemberType.push_back(strElemArrType); + structLoadMemberType.push_back(strElemLoadArrType); + structMemberOffsets.push_back(structMemberOffsets.back() + strElemLen); + structMemberData.push_back(strElemConstData); + } + structMemberOffsets.pop_back(); + // 3. Add extra following arguments/variables' types in member structure. + for (unsigned int i = 1; i < glslangOperands.size(); i++) { + spv::Builder::AccessChain save = builder.getAccessChain(); + builder.clearAccessChain(); + auto width = GetNumBits(glslangOperands[i]->getAsTyped()->getBasicType()); + structMemberOffsets.push_back(structMemberOffsets.back() + width / 8); + glslangOperands[i]->traverse(this); + structMemberData.push_back(accessChainLoad(glslangOperands[i]->getAsTyped()->getType())); + spv::Id reservedOpType = builder.getTypeId(structMemberData.back()); + structMemberType.push_back(reservedOpType); + structLoadMemberType.push_back(reservedOpType); + + builder.setAccessChain(save); + } + // 4. Construct struct message variable, add abortExt instruction. + auto structLoadType = builder.makeStructType(structLoadMemberType, {}, "abortMessageLoadType"); + for (unsigned int i = 0; i < structMemberOffsets.size(); i++) + builder.addMemberDecoration(structLoadType, i, spv::Decoration::Offset, structMemberOffsets[i]); + auto structType = builder.makeStructType(structMemberType, {}, "abortMessage"); + auto messageVar = builder.createCompositeConstruct(structType, structMemberData); + builder.makeStatementTerminator(spv::Op::OpAbortKHR, {structLoadType, messageVar}, "post-abort"); +} + bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TIntermAggregate* node) { SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); @@ -3873,6 +3969,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt glslang::TIntermSequence& glslangOperands = node->getSequence(); std::vector operands; std::vector memoryAccessOperands; + if (node->getOp() == glslang::EOpAbortEXT) { + createAbortEXT(glslangOperands); + return false; + } for (int arg = 0; arg < (int)glslangOperands.size(); ++arg) { // special case l-value operands; there are just a few bool lvalue = false; @@ -4073,6 +4173,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt break; } builder.clearAccessChain(); + if (invertedType != spv::NoType && arg == 0) glslangOperands[0]->getAsBinaryNode()->getLeft()->traverse(this); else diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index b65ec30641..98e8aac0f2 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -1778,6 +1778,7 @@ bool Builder::isConstantOpCode(Op opcode) const case Op::OpConstantTrue: case Op::OpConstantFalse: case Op::OpConstant: + case Op::OpConstantDataKHR: case Op::OpConstantComposite: case Op::OpConstantCompositeReplicateEXT: case Op::OpConstantSampler: @@ -1785,6 +1786,7 @@ bool Builder::isConstantOpCode(Op opcode) const case Op::OpSpecConstantTrue: case Op::OpSpecConstantFalse: case Op::OpSpecConstant: + case Op::OpSpecConstantDataKHR: case Op::OpSpecConstantComposite: case Op::OpSpecConstantCompositeReplicateEXT: case Op::OpSpecConstantOp: @@ -1802,6 +1804,7 @@ bool Builder::isSpecConstantOpCode(Op opcode) const case Op::OpSpecConstantTrue: case Op::OpSpecConstantFalse: case Op::OpSpecConstant: + case Op::OpSpecConstantDataKHR: case Op::OpSpecConstantComposite: case Op::OpSpecConstantOp: case Op::OpSpecConstantCompositeReplicateEXT: @@ -3468,6 +3471,29 @@ Id Builder::createTriOp(Op opCode, Id typeId, Id op1, Id op2, Id op3) return op->getResultId(); } +Id Builder::createConstData(Op opCode, Id typeId, const std::vector operands) +{ + Instruction* op = new Instruction(getUniqueId(), typeId, opCode); + op->reserveOperands(operands.size()); + for (auto id : operands) + op->addStringOperand(id); + module.mapInstruction(op); + constantsTypesGlobals.push_back(std::unique_ptr(op)); + + return op->getResultId(); +} + +Id Builder::createSpecConst(Op opCode, Id typeId, const unsigned int literalOp) +{ + Instruction* op = new Instruction(getUniqueId(), typeId, opCode); + op->reserveOperands(1); + op->addImmediateOperand(literalOp); + module.mapInstruction(op); + constantsTypesGlobals.push_back(std::unique_ptr(op)); + + return op->getResultId(); +} + Id Builder::createOp(Op opCode, Id typeId, const std::vector& operands) { Instruction* op = new Instruction(getUniqueId(), typeId, opCode); diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index abfec52efc..e8e2fca99a 100644 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -592,6 +592,8 @@ class Builder { Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3); Id createOp(Op, Id typeId, const std::vector& operands); Id createOp(Op, Id typeId, const std::vector& operands); + Id createConstData(Op opCode, Id typeId, const std::vector operands); + Id createSpecConst(Op opCode, Id typeId, const unsigned int literalOp); Id createFunctionCall(spv::Function*, const std::vector&); Id createSpecConstantOp(Op, Id typeId, const std::vector& operands, const std::vector& literals); diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp index f81faefabd..2906063024 100644 --- a/SPIRV/doc.cpp +++ b/SPIRV/doc.cpp @@ -1108,6 +1108,9 @@ const char* CapabilityString(int info) case (int)Capability::ExpectAssumeKHR: return "ExpectAssumeKHR"; + case (int)Capability::AbortKHR: return "AbortKHR"; + case (int)Capability::ConstantDataKHR: return "ConstantDataKHR"; + case (int)Capability::AtomicFloat16AddEXT: return "AtomicFloat16AddEXT"; case (int)Capability::AtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; case (int)Capability::AtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; @@ -1545,6 +1548,10 @@ const char* OpcodeString(int op) case (int)Op::OpMemberDecorateIdEXT: return "OpMemberDecorateIdEXT"; case (int)Op::OpUntypedImageTexelPointerEXT: return "OpUntypedImageTexelPointerEXT"; + case (int)Op::OpAbortKHR: return "OpAbortKHR"; + case (int)Op::OpConstantDataKHR: return "OpConstantDataKHR"; + case (int)Op::OpSpecConstantDataKHR: return "OpSpecConstantDataKHR"; + case (int)Op::OpAtomicFAddEXT: return "OpAtomicFAddEXT"; case (int)Op::OpAtomicFMinEXT: return "OpAtomicFMinEXT"; case (int)Op::OpAtomicFMaxEXT: return "OpAtomicFMaxEXT"; @@ -3214,6 +3221,12 @@ void Parameterize() InstructionDesc[enumCast(Op::OpGroupNonUniformQuadAnyKHR)].operands.push(OperandId, "'Predicate'"); InstructionDesc[enumCast(Op::OpTypeAccelerationStructureKHR)].setResultAndType(true, false); + InstructionDesc[enumCast(Op::OpConstantDataKHR)].operands.push(OperandLiteralString, "'Data'"); + InstructionDesc[enumCast(Op::OpSpecConstantDataKHR)].operands.push(OperandLiteralString, "'Data'"); + InstructionDesc[enumCast(Op::OpAbortKHR)].operands.push(OperandId, "'Message Type'"); + InstructionDesc[enumCast(Op::OpAbortKHR)].operands.push(OperandId, "'Message'"); + InstructionDesc[enumCast(Op::OpAbortKHR)].setResultAndType(false, false); + InstructionDesc[enumCast(Op::OpTraceNV)].operands.push(OperandId, "'Acceleration Structure'"); InstructionDesc[enumCast(Op::OpTraceNV)].operands.push(OperandId, "'Ray Flags'"); InstructionDesc[enumCast(Op::OpTraceNV)].operands.push(OperandId, "'Cull Mask'"); diff --git a/SPIRV/spirv.hpp11 b/SPIRV/spirv.hpp11 index 36a82e7a39..51b522c358 100644 --- a/SPIRV/spirv.hpp11 +++ b/SPIRV/spirv.hpp11 @@ -566,6 +566,7 @@ enum class Decoration : unsigned { PayloadDispatchIndirectAMDX = 5105, ArrayStrideIdEXT = 5124, OffsetIdEXT = 5125, + UTFCodePointsKHR = 5145, OverrideCoverageNV = 5248, PassthroughNV = 5250, ViewportRelativeNV = 5252, @@ -1133,7 +1134,9 @@ enum class Capability : unsigned { BFloat16TypeKHR = 5116, BFloat16DotProductKHR = 5117, BFloat16CooperativeMatrixKHR = 5118, + AbortKHR = 5120, DescriptorHeapEXT = 5128, + ConstantDataKHR = 5146, SampleMaskOverrideCoverageNV = 5249, GeometryShaderPassthroughNV = 5251, ShaderViewportIndexLayerEXT = 5254, @@ -2042,9 +2045,12 @@ enum class Op : unsigned { OpGroupNonUniformQuadAnyKHR = 5111, OpTypeBufferEXT = 5115, OpBufferPointerEXT = 5119, + OpAbortKHR = 5121, OpUntypedImageTexelPointerEXT = 5126, OpMemberDecorateIdEXT = 5127, OpConstantSizeOfEXT = 5129, + OpConstantDataKHR = 5147, + OpSpecConstantDataKHR = 5148, OpHitObjectRecordHitMotionNV = 5249, OpHitObjectRecordHitWithIndexMotionNV = 5250, OpHitObjectRecordMissMotionNV = 5251, @@ -2898,6 +2904,9 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case Op::OpSpecConstantStringAMDX: *hasResult = true; *hasResultType = false; break; case Op::OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break; case Op::OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpAbortKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpConstantDataKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantDataKHR : *hasResult = true; *hasResultType = true; break; case Op::OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break; case Op::OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break; case Op::OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break; @@ -3745,6 +3754,7 @@ inline const char* DecorationToString(Decoration value) { case Decoration::PayloadNodeSparseArrayAMDX: return "PayloadNodeSparseArrayAMDX"; case Decoration::PayloadNodeArraySizeAMDX: return "PayloadNodeArraySizeAMDX"; case Decoration::PayloadDispatchIndirectAMDX: return "PayloadDispatchIndirectAMDX"; + case Decoration::UTFCodePointsKHR: return "UTFCodePointsKHR"; case Decoration::OverrideCoverageNV: return "OverrideCoverageNV"; case Decoration::PassthroughNV: return "PassthroughNV"; case Decoration::ViewportRelativeNV: return "ViewportRelativeNV"; @@ -4128,6 +4138,8 @@ inline const char* CapabilityToString(Capability value) { case Capability::BFloat16TypeKHR: return "BFloat16TypeKHR"; case Capability::BFloat16DotProductKHR: return "BFloat16DotProductKHR"; case Capability::BFloat16CooperativeMatrixKHR: return "BFloat16CooperativeMatrixKHR"; + case Capability::AbortKHR: return "AbortKHR"; + case Capability::ConstantDataKHR: return "ConstantDataKHR"; case Capability::SampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; case Capability::GeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; case Capability::ShaderViewportIndexLayerEXT: return "ShaderViewportIndexLayerEXT"; @@ -4894,6 +4906,9 @@ inline const char* OpToString(Op value) { case Op::OpSpecConstantStringAMDX: return "OpSpecConstantStringAMDX"; case Op::OpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR"; case Op::OpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR"; + case Op::OpAbortKHR: return "OpAbortKHR"; + case Op::OpConstantDataKHR: return "OpConstantDataKHR"; + case Op::OpSpecConstantDataKHR: return "OpSpecConstantDataKHR"; case Op::OpHitObjectRecordHitMotionNV: return "OpHitObjectRecordHitMotionNV"; case Op::OpHitObjectRecordHitWithIndexMotionNV: return "OpHitObjectRecordHitWithIndexMotionNV"; case Op::OpHitObjectRecordMissMotionNV: return "OpHitObjectRecordMissMotionNV"; diff --git a/SPIRV/spvIR.h b/SPIRV/spvIR.h index ce7afbcce5..e6a0ac1925 100644 --- a/SPIRV/spvIR.h +++ b/SPIRV/spvIR.h @@ -381,6 +381,7 @@ class Block { case Op::OpReturn: case Op::OpReturnValue: case Op::OpUnreachable: + case Op::OpAbortKHR: return true; default: return false; diff --git a/Test/baseResults/cppBad.vert.out b/Test/baseResults/cppBad.vert.out index c36ae4dfa6..4fc2bd5aeb 100644 --- a/Test/baseResults/cppBad.vert.out +++ b/Test/baseResults/cppBad.vert.out @@ -7,6 +7,7 @@ ERROR: 0:6: 'string' : End of line in string ERROR: 0:6: 'string literal' : required extension not requested: Possible extensions include: GL_EXT_debug_printf GL_EXT_spirv_intrinsics +GL_EXT_abort ERROR: 0:6: '' : syntax error, unexpected INT, expecting COMMA or SEMICOLON ERROR: 6 compilation errors. No code generated. diff --git a/Test/baseResults/cppSimple.vert.out b/Test/baseResults/cppSimple.vert.out index 26de231239..c543b57894 100644 --- a/Test/baseResults/cppSimple.vert.out +++ b/Test/baseResults/cppSimple.vert.out @@ -21,9 +21,11 @@ ERROR: 0:122: '#endif' : unexpected tokens following directive ERROR: 0:135: 'string literal' : required extension not requested: Possible extensions include: GL_EXT_debug_printf GL_EXT_spirv_intrinsics +GL_EXT_abort ERROR: 0:136: 'string literal' : required extension not requested: Possible extensions include: GL_EXT_debug_printf GL_EXT_spirv_intrinsics +GL_EXT_abort ERROR: 0:136: 'length' : no matching overloaded function found ERROR: 0:136: '=' : cannot convert from ' const float' to ' global int' ERROR: 0:138: ''' : character literals not supported diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index 9e520dee7a..3c98309c60 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -1000,6 +1000,9 @@ enum TOperator { EOpAssumeEXT, EOpExpectEXT, + // GL_EXT_abort + EOpAbortEXT, + // Shader Clock Ops EOpReadClockSubgroupKHR, EOpReadClockDeviceKHR, diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index d4f87a413f..d074561c42 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -4831,6 +4831,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void memoryBarrier(int, int, int);\n"); commonBuiltins.append("void debugPrintfEXT();\n"); + commonBuiltins.append("void abortEXT();\n"); if (profile != EEsProfile && version >= 450) { // coopMatStoreNV perhaps ought to have "out" on the buf parameter, but @@ -10015,6 +10016,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("controlBarrier", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setFunctionExtensions("debugPrintfEXT", 1, &E_GL_EXT_debug_printf); + symbolTable.setFunctionExtensions("abortEXT", 1, &E_GL_EXT_abort); // GL_ARB_shader_ballot if (profile != EEsProfile) { @@ -11060,6 +11062,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("debugPrintfEXT", EOpDebugPrintf); symbolTable.relateToOperator("assumeEXT", EOpAssumeEXT); symbolTable.relateToOperator("expectEXT", EOpExpectEXT); + symbolTable.relateToOperator("abortEXT", EOpAbortEXT); if (PureOperatorBuiltins) { diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 0fb0c6f466..fb102ea816 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -2349,6 +2349,7 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction numArgs = 1; break; case EOpDebugPrintf: + case EOpAbortEXT: case EOpCooperativeMatrixPerElementOpNV: case EOpCooperativeMatrixReduceNV: case EOpConstructSaturated: @@ -8230,6 +8231,13 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct return symbol->getAsFunction(); } + // abortEXT has usage (var args) as similar as debugPrintfEXT. + if (call.getName() == "abortEXT") { + TSymbol* symbol = symbolTable.find("abortEXT(", &builtIn); + if (symbol) + return symbol->getAsFunction(); + } + // coopMatPerElementNV is variadic. There is some function signature error // checking in handleCoopMat2FunctionCall. if (call.getName() == "coopMatPerElementNV") { diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index ce705a351c..87787df8c3 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -270,6 +270,8 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_control_flow_attributes2] = EBhDisable; extensionBehavior[E_GL_EXT_spec_constant_composites] = EBhDisable; + extensionBehavior[E_GL_EXT_abort] = EBhDisable; + extensionBehavior[E_GL_KHR_cooperative_matrix] = EBhDisable; extensionBehavior[E_GL_NV_cooperative_vector] = EBhDisable; @@ -553,6 +555,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_shared_memory_block 1\n" "#define GL_EXT_shader_integer_mix 1\n" "#define GL_EXT_spec_constant_composites 1\n" + "#define E_GL_EXT_abort 1\n" // GL_KHR_shader_subgroup "#define GL_KHR_shader_subgroup_basic 1\n" diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index bb17dc972d..7af268cae0 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -187,6 +187,8 @@ const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_lo const char* const E_GL_EXT_shader_16bit_storage = "GL_EXT_shader_16bit_storage"; const char* const E_GL_EXT_shader_8bit_storage = "GL_EXT_shader_8bit_storage"; +const char* const E_GL_EXT_abort = "GL_EXT_abort"; + // EXT extensions const char* const E_GL_EXT_device_group = "GL_EXT_device_group"; diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index 572652d995..7de6066d50 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -995,6 +995,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break; case EOpDebugPrintf: out.debug << "Debug printf"; break; + case EOpAbortEXT: out.debug << "Abort"; break; case EOpHitObjectTraceRayNV: out.debug << "HitObjectTraceRayNV"; break; case EOpHitObjectTraceRayMotionNV: out.debug << "HitObjectTraceRayMotionNV"; break; diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp index a252295631..e8d4daaf10 100644 --- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -1286,10 +1286,11 @@ int TPpContext::tokenize(TPpToken& ppToken) if (needStringSupport && parseContext.intermediate.getSource() != EShSourceHlsl) { // HLSL allows string literals. // GLSL allows string literals with GL_EXT_debug_printf. - const char* const string_literal_EXTs[] = { E_GL_EXT_debug_printf, E_GL_EXT_spirv_intrinsics }; - parseContext.requireExtensions(ppToken.loc, 2, string_literal_EXTs, "string literal"); + const char* const string_literal_EXTs[] = { E_GL_EXT_debug_printf, E_GL_EXT_spirv_intrinsics, E_GL_EXT_abort }; + parseContext.requireExtensions(ppToken.loc, 3, string_literal_EXTs, "string literal"); if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf) && - !parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) { + !parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && + !parseContext.extensionTurnedOn(E_GL_EXT_abort)) { continue; } }