Merge pull request #2098 from jeffbolznv/debugprintf

GL_EXT_debug_printf implementation
This commit is contained in:
John Kessenich 2020-03-06 00:12:27 -07:00 committed by GitHub
commit 6f230b9e0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 4030 additions and 3794 deletions

View File

@ -85,6 +85,7 @@ genrule(
"SPIRV/GLSL.ext.KHR.h", "SPIRV/GLSL.ext.KHR.h",
"SPIRV/GLSL.ext.NV.h", "SPIRV/GLSL.ext.NV.h",
"SPIRV/GLSL.std.450.h", "SPIRV/GLSL.std.450.h",
"SPIRV/NonSemanticDebugPrintf.h",
"SPIRV/spirv.hpp", "SPIRV/spirv.hpp",
], ],
outs = [ outs = [
@ -93,6 +94,7 @@ genrule(
"include/SPIRV/GLSL.ext.KHR.h", "include/SPIRV/GLSL.ext.KHR.h",
"include/SPIRV/GLSL.ext.NV.h", "include/SPIRV/GLSL.ext.NV.h",
"include/SPIRV/GLSL.std.450.h", "include/SPIRV/GLSL.std.450.h",
"include/SPIRV/NonSemanticDebugPrintf.h",
"include/SPIRV/spirv.hpp", "include/SPIRV/spirv.hpp",
], ],
cmd = "mkdir -p $(@D)/include/SPIRV && cp $(SRCS) $(@D)/include/SPIRV/", cmd = "mkdir -p $(@D)/include/SPIRV && cp $(SRCS) $(@D)/include/SPIRV/",

View File

@ -70,6 +70,7 @@ source_set("glslang_sources") {
"SPIRV/InReadableOrder.cpp", "SPIRV/InReadableOrder.cpp",
"SPIRV/Logger.cpp", "SPIRV/Logger.cpp",
"SPIRV/Logger.h", "SPIRV/Logger.h",
"SPIRV/NonSemanticDebugPrintf.h",
"SPIRV/SPVRemapper.cpp", "SPIRV/SPVRemapper.cpp",
"SPIRV/SPVRemapper.h", "SPIRV/SPVRemapper.h",
"SPIRV/SpvBuilder.cpp", "SPIRV/SpvBuilder.cpp",

3
SPIRV/CMakeLists.txt Executable file → Normal file
View File

@ -27,7 +27,8 @@ set(HEADERS
SpvTools.h SpvTools.h
disassemble.h disassemble.h
GLSL.ext.AMD.h GLSL.ext.AMD.h
GLSL.ext.NV.h) GLSL.ext.NV.h
NonSemanticDebugPrintf.h)
set(SPVREMAP_HEADERS set(SPVREMAP_HEADERS
SPVRemapper.h SPVRemapper.h

View File

@ -44,5 +44,6 @@ static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physi
static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer"; static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer";
static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock"; static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock";
static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock"; static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock";
static const char* const E_SPV_KHR_non_semantic_info = "SPV_KHR_non_semantic_info";
#endif // #ifndef GLSLextKHR_H #endif // #ifndef GLSLextKHR_H

21
SPIRV/GlslangToSpv.cpp Executable file → Normal file
View File

@ -48,6 +48,7 @@ namespace spv {
#include "GLSL.ext.EXT.h" #include "GLSL.ext.EXT.h"
#include "GLSL.ext.AMD.h" #include "GLSL.ext.AMD.h"
#include "GLSL.ext.NV.h" #include "GLSL.ext.NV.h"
#include "NonSemanticDebugPrintf.h"
} }
// Glslang includes // Glslang includes
@ -248,6 +249,7 @@ protected:
const glslang::TIntermediate* glslangIntermediate; const glslang::TIntermediate* glslangIntermediate;
bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp
spv::Id stdBuiltins; spv::Id stdBuiltins;
spv::Id nonSemanticDebugPrintf;
std::unordered_map<const char*, spv::Id> extBuiltinMap; std::unordered_map<const char*, spv::Id> extBuiltinMap;
std::unordered_map<int, spv::Id> symbolValues; std::unordered_map<int, spv::Id> symbolValues;
@ -1375,7 +1377,8 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger), builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger),
inEntryPoint(false), entryPointTerminated(false), linkageOnly(false), inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
glslangIntermediate(glslangIntermediate), glslangIntermediate(glslangIntermediate),
nanMinMaxClamp(glslangIntermediate->getNanMinMaxClamp()) nanMinMaxClamp(glslangIntermediate->getNanMinMaxClamp()),
nonSemanticDebugPrintf(0)
{ {
spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage()); spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage());
@ -2687,6 +2690,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
break; break;
#endif #endif
case glslang::EOpDebugPrintf:
noReturnValue = true;
break;
default: default:
break; break;
} }
@ -2920,6 +2927,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
// Handle all atomics // Handle all atomics
result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(),
lvalueCoherentFlags); lvalueCoherentFlags);
} else if (node->getOp() == glslang::EOpDebugPrintf) {
if (!nonSemanticDebugPrintf) {
nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf");
}
result = builder.createBuiltinCall(builder.makeVoidType(), nonSemanticDebugPrintf, spv::NonSemanticDebugPrintfDebugPrintf, operands);
builder.addExtension(spv::E_SPV_KHR_non_semantic_info);
} else { } else {
// Pass through to generic operations. // Pass through to generic operations.
switch (glslangOperands.size()) { switch (glslangOperands.size()) {
@ -3566,6 +3579,9 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier); spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier);
} }
break; break;
case glslang::EbtString:
// no type used for OpString
return 0;
default: default:
assert(0); assert(0);
break; break;
@ -8183,6 +8199,9 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
scalar = builder.createUnaryOp(spv::OpBitcast, typeId, scalar); scalar = builder.createUnaryOp(spv::OpBitcast, typeId, scalar);
break; break;
#endif #endif
case glslang::EbtString:
scalar = builder.getStringId(consts[nextConst].getSConst()->c_str());
break;
default: default:
assert(0); assert(0);
break; break;

View File

@ -0,0 +1,50 @@
// Copyright (c) 2020 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
// "Materials"), to deal in the Materials without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Materials, and to
// permit persons to whom the Materials are furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Materials.
//
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
// https://www.khronos.org/registry/
//
// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
//
#ifndef SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
#define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
#ifdef __cplusplus
extern "C" {
#endif
enum {
NonSemanticDebugPrintfRevision = 1,
NonSemanticDebugPrintfRevision_BitWidthPadding = 0x7fffffff
};
enum NonSemanticDebugPrintfInstructions {
NonSemanticDebugPrintfDebugPrintf = 1,
NonSemanticDebugPrintfInstructionsMax = 0x7fffffff
};
#ifdef __cplusplus
}
#endif
#endif // SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_

View File

@ -94,6 +94,7 @@ public:
const char* file_c_str = str.c_str(); const char* file_c_str = str.c_str();
fileString->addStringOperand(file_c_str); fileString->addStringOperand(file_c_str);
strings.push_back(std::unique_ptr<Instruction>(fileString)); strings.push_back(std::unique_ptr<Instruction>(fileString));
module.mapInstruction(fileString);
stringIds[file_c_str] = strId; stringIds[file_c_str] = strId;
return strId; return strId;
} }

View File

@ -75,6 +75,7 @@ enum ExtInstSet {
GLSLextAMDInst, GLSLextAMDInst,
GLSLextNVInst, GLSLextNVInst,
OpenCLExtInst, OpenCLExtInst,
NonSemanticDebugPrintfExtInst,
}; };
// Container class for a single instance of a SPIR-V stream, with methods for disassembly. // Container class for a single instance of a SPIR-V stream, with methods for disassembly.
@ -482,6 +483,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
const char* name = idDescriptor[stream[word - 2]].c_str(); const char* name = idDescriptor[stream[word - 2]].c_str();
if (0 == memcmp("OpenCL", name, 6)) { if (0 == memcmp("OpenCL", name, 6)) {
extInstSet = OpenCLExtInst; extInstSet = OpenCLExtInst;
} else if (0 == memcmp("NonSemantic.DebugPrintf", name, 23)) {
extInstSet = NonSemanticDebugPrintfExtInst;
} else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 || } else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 ||
strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 || strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 ||
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 || strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
@ -505,6 +508,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
} }
else if (extInstSet == GLSLextNVInst) { else if (extInstSet == GLSLextNVInst) {
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")"; out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
} else if (extInstSet == NonSemanticDebugPrintfExtInst) {
out << "(DebugPrintf)";
} }
} }
break; break;

View File

@ -3,7 +3,7 @@ WARNING: 0:1: '#define' : missing space after macro name
ERROR: 0:3: 'preprocessor evaluation' : bad expression ERROR: 0:3: 'preprocessor evaluation' : bad expression
ERROR: 0:3: '#if' : unexpected tokens following directive ERROR: 0:3: '#if' : unexpected tokens following directive
ERROR: 0:6: 'string' : End of line in string ERROR: 0:6: 'string' : End of line in string
ERROR: 0:6: '""' : string literals not supported ERROR: 0:6: 'string literal' : required extension not requested: GL_EXT_debug_printf
ERROR: 0:6: '' : syntax error, unexpected INT, expecting COMMA or SEMICOLON ERROR: 0:6: '' : syntax error, unexpected INT, expecting COMMA or SEMICOLON
ERROR: 5 compilation errors. No code generated. ERROR: 5 compilation errors. No code generated.

View File

@ -18,8 +18,8 @@ ERROR: 0:117: '#error' : bad5
ERROR: 0:120: '#if' : unexpected tokens following directive ERROR: 0:120: '#if' : unexpected tokens following directive
ERROR: 0:121: '#error' : bad6 ERROR: 0:121: '#error' : bad6
ERROR: 0:122: '#endif' : unexpected tokens following directive ERROR: 0:122: '#endif' : unexpected tokens following directive
ERROR: 0:135: '""' : string literals not supported ERROR: 0:135: 'string literal' : required extension not requested: GL_EXT_debug_printf
ERROR: 0:136: '""' : string literals not supported ERROR: 0:136: 'string literal' : required extension not requested: GL_EXT_debug_printf
ERROR: 0:136: 'length' : no matching overloaded function found ERROR: 0:136: 'length' : no matching overloaded function found
ERROR: 0:136: '=' : cannot convert from ' const float' to ' global int' ERROR: 0:136: '=' : cannot convert from ' const float' to ' global int'
ERROR: 0:138: ''' : character literals not supported ERROR: 0:138: ''' : character literals not supported

View File

@ -9,8 +9,8 @@ hlsl.pp.line4.frag
EntryPoint Fragment 5 "MainPs" 70 74 EntryPoint Fragment 5 "MainPs" 70 74
ExecutionMode 5 OriginUpperLeft ExecutionMode 5 OriginUpperLeft
1: String "hlsl.pp.line4.frag" 1: String "hlsl.pp.line4.frag"
17: String "C:\\Users\\Greg\\shaders\\line\\foo4.frag" 17: String "C:\Users\Greg\shaders\line\foo4.frag"
32: String "C:\\Users\\Greg\\shaders\\line\\u1.h" 32: String "C:\Users\Greg\shaders\line\u1.h"
Source HLSL 500 1 "// OpModuleProcessed auto-map-locations Source HLSL 500 1 "// OpModuleProcessed auto-map-locations
// OpModuleProcessed auto-map-bindings // OpModuleProcessed auto-map-bindings
// OpModuleProcessed entry-point MainPs // OpModuleProcessed entry-point MainPs

View File

@ -0,0 +1,27 @@
spv.debugPrintf.frag
// Module Version 10000
// Generated by (magic number): 80008
// Id's are bound by 13
Capability Shader
Extension "SPV_KHR_non_semantic_info"
1: ExtInstImport "GLSL.std.450"
11: ExtInstImport "NonSemantic.DebugPrintf"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
6: String "ASDF \ ? \ %d %d %d"
Source GLSL 450
SourceExtension "GL_EXT_debug_printf"
Name 4 "main"
2: TypeVoid
3: TypeFunction 2
7: TypeInt 32 1
8: 7(int) Constant 1
9: 7(int) Constant 2
10: 7(int) Constant 3
4(main): 2 Function None 3
5: Label
12: 2 ExtInst 11(NonSemantic.DebugPrintf) 1(DebugPrintf) 6 8 9 10
Return
FunctionEnd

View File

@ -11,7 +11,7 @@ spv.specConstant.vert
Source GLSL 400 Source GLSL 400
Name 4 "main" Name 4 "main"
Name 9 "arraySize" Name 9 "arraySize"
Name 14 "foo(vf4[s4529];" Name 14 "foo(vf4[s4530];"
Name 13 "p" Name 13 "p"
Name 17 "builtin_spec_constant(" Name 17 "builtin_spec_constant("
Name 20 "color" Name 20 "color"
@ -102,10 +102,10 @@ spv.specConstant.vert
Store 20(color) 46 Store 20(color) 46
48: 10 Load 22(ucol) 48: 10 Load 22(ucol)
Store 47(param) 48 Store 47(param) 48
49: 2 FunctionCall 14(foo(vf4[s4529];) 47(param) 49: 2 FunctionCall 14(foo(vf4[s4530];) 47(param)
Return Return
FunctionEnd FunctionEnd
14(foo(vf4[s4529];): 2 Function None 12 14(foo(vf4[s4530];): 2 Function None 12
13(p): 11(ptr) FunctionParameter 13(p): 11(ptr) FunctionParameter
15: Label 15: Label
54: 24(ptr) AccessChain 53(dupUcol) 23 54: 24(ptr) AccessChain 53(dupUcol) 23

View File

@ -0,0 +1,7 @@
#version 450
#extension GL_EXT_debug_printf : enable
void main()
{
debugPrintfEXT("ASDF \\ \? \x5C %d %d %d", 1, 2, 3);
}

View File

@ -621,6 +621,8 @@ enum TOperator {
EOpIsHelperInvocation, EOpIsHelperInvocation,
EOpDebugPrintf,
// //
// Branch // Branch
// //

View File

@ -4086,6 +4086,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
commonBuiltins.append("void controlBarrier(int, int, int, int);\n" commonBuiltins.append("void controlBarrier(int, int, int, int);\n"
"void memoryBarrier(int, int, int);\n"); "void memoryBarrier(int, int, int);\n");
commonBuiltins.append("void debugPrintfEXT();\n");
if (profile != EEsProfile && version >= 450) { if (profile != EEsProfile && version >= 450) {
// coopMatStoreNV perhaps ought to have "out" on the buf parameter, but // coopMatStoreNV perhaps ought to have "out" on the buf parameter, but
// adding it introduces undesirable tempArgs on the stack. What we want // adding it introduces undesirable tempArgs on the stack. What we want
@ -7903,6 +7905,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
} }
symbolTable.setFunctionExtensions("controlBarrier", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setFunctionExtensions("controlBarrier", 1, &E_GL_KHR_memory_scope_semantics);
symbolTable.setFunctionExtensions("debugPrintfEXT", 1, &E_GL_EXT_debug_printf);
// GL_ARB_shader_ballot // GL_ARB_shader_ballot
if (profile != EEsProfile) { if (profile != EEsProfile) {
@ -8451,6 +8454,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("average", EOpAverage); symbolTable.relateToOperator("average", EOpAverage);
symbolTable.relateToOperator("averageRounded", EOpAverageRounded); symbolTable.relateToOperator("averageRounded", EOpAverageRounded);
symbolTable.relateToOperator("multiply32x16", EOpMul32x16); symbolTable.relateToOperator("multiply32x16", EOpMul32x16);
symbolTable.relateToOperator("debugPrintfEXT", EOpDebugPrintf);
if (PureOperatorBuiltins) { if (PureOperatorBuiltins) {
symbolTable.relateToOperator("imageSize", EOpImageQuerySize); symbolTable.relateToOperator("imageSize", EOpImageQuerySize);

View File

@ -1353,6 +1353,9 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction
case EOpInterpolateAtSample: case EOpInterpolateAtSample:
numArgs = 1; numArgs = 1;
break; break;
case EOpDebugPrintf:
numArgs = 0;
break;
default: default:
break; break;
} }
@ -6082,6 +6085,15 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct
#endif #endif
const TFunction* function = nullptr; const TFunction* function = nullptr;
// debugPrintfEXT has var args and is in the symbol table as "debugPrintfEXT()",
// mangled to "debugPrintfEXT("
if (call.getName() == "debugPrintfEXT") {
TSymbol* symbol = symbolTable.find("debugPrintfEXT(", &builtIn);
if (symbol)
return symbol->getAsFunction();
}
bool explicitTypesEnabled = extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || bool explicitTypesEnabled = extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8) || extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8) ||
extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16) || extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16) ||

View File

@ -842,6 +842,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
parseContext.error(loc, "not supported", "::", ""); parseContext.error(loc, "not supported", "::", "");
break; break;
case PpAtomConstString: parserToken->sType.lex.string = NewPoolTString(tokenText); return STRING_LITERAL;
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;

View File

@ -221,6 +221,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_buffer_reference2] = EBhDisable; extensionBehavior[E_GL_EXT_buffer_reference2] = EBhDisable;
extensionBehavior[E_GL_EXT_buffer_reference_uvec2] = EBhDisable; extensionBehavior[E_GL_EXT_buffer_reference_uvec2] = EBhDisable;
extensionBehavior[E_GL_EXT_demote_to_helper_invocation] = EBhDisable; extensionBehavior[E_GL_EXT_demote_to_helper_invocation] = EBhDisable;
extensionBehavior[E_GL_EXT_debug_printf] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable; extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable; extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
@ -418,6 +419,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_buffer_reference2 1\n" "#define GL_EXT_buffer_reference2 1\n"
"#define GL_EXT_buffer_reference_uvec2 1\n" "#define GL_EXT_buffer_reference_uvec2 1\n"
"#define GL_EXT_demote_to_helper_invocation 1\n" "#define GL_EXT_demote_to_helper_invocation 1\n"
"#define GL_EXT_debug_printf 1\n"
// GL_KHR_shader_subgroup // GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n" "#define GL_KHR_shader_subgroup_basic 1\n"

View File

@ -185,6 +185,7 @@ const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_ref
const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2"; const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2";
const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation"; const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation";
const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock"; const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock";
const char* const E_GL_EXT_debug_printf = "GL_EXT_debug_printf";
// Arrays of extensions for the above viewportEXTs duplications // Arrays of extensions for the above viewportEXTs duplications

View File

@ -263,6 +263,7 @@ GLSLANG_WEB_EXCLUDE_OFF
%token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN %token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
%token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN %token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
%token <lex> SUB_ASSIGN %token <lex> SUB_ASSIGN
%token <lex> STRING_LITERAL
%token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT %token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT
%token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT %token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
@ -377,6 +378,9 @@ primary_expression
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
} }
GLSLANG_WEB_EXCLUDE_ON GLSLANG_WEB_EXCLUDE_ON
| STRING_LITERAL {
$$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true);
}
| INT32CONSTANT { | INT32CONSTANT {
parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); parseContext.explicitInt32Check($1.loc, "32-bit signed literal");
$$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);

View File

@ -263,6 +263,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN %token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
%token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN %token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
%token <lex> SUB_ASSIGN %token <lex> SUB_ASSIGN
%token <lex> STRING_LITERAL
%token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT %token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT
%token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT %token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
@ -377,6 +378,9 @@ primary_expression
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
} }
| STRING_LITERAL {
$$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true);
}
| INT32CONSTANT { | INT32CONSTANT {
parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); parseContext.explicitInt32Check($1.loc, "32-bit signed literal");
$$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);

File diff suppressed because it is too large Load Diff

View File

@ -356,103 +356,104 @@ extern int yydebug;
XOR_ASSIGN = 566, XOR_ASSIGN = 566,
OR_ASSIGN = 567, OR_ASSIGN = 567,
SUB_ASSIGN = 568, SUB_ASSIGN = 568,
LEFT_PAREN = 569, STRING_LITERAL = 569,
RIGHT_PAREN = 570, LEFT_PAREN = 570,
LEFT_BRACKET = 571, RIGHT_PAREN = 571,
RIGHT_BRACKET = 572, LEFT_BRACKET = 572,
LEFT_BRACE = 573, RIGHT_BRACKET = 573,
RIGHT_BRACE = 574, LEFT_BRACE = 574,
DOT = 575, RIGHT_BRACE = 575,
COMMA = 576, DOT = 576,
COLON = 577, COMMA = 577,
EQUAL = 578, COLON = 578,
SEMICOLON = 579, EQUAL = 579,
BANG = 580, SEMICOLON = 580,
DASH = 581, BANG = 581,
TILDE = 582, DASH = 582,
PLUS = 583, TILDE = 583,
STAR = 584, PLUS = 584,
SLASH = 585, STAR = 585,
PERCENT = 586, SLASH = 586,
LEFT_ANGLE = 587, PERCENT = 587,
RIGHT_ANGLE = 588, LEFT_ANGLE = 588,
VERTICAL_BAR = 589, RIGHT_ANGLE = 589,
CARET = 590, VERTICAL_BAR = 590,
AMPERSAND = 591, CARET = 591,
QUESTION = 592, AMPERSAND = 592,
INVARIANT = 593, QUESTION = 593,
HIGH_PRECISION = 594, INVARIANT = 594,
MEDIUM_PRECISION = 595, HIGH_PRECISION = 595,
LOW_PRECISION = 596, MEDIUM_PRECISION = 596,
PRECISION = 597, LOW_PRECISION = 597,
PACKED = 598, PRECISION = 598,
RESOURCE = 599, PACKED = 599,
SUPERP = 600, RESOURCE = 600,
FLOATCONSTANT = 601, SUPERP = 601,
INTCONSTANT = 602, FLOATCONSTANT = 602,
UINTCONSTANT = 603, INTCONSTANT = 603,
BOOLCONSTANT = 604, UINTCONSTANT = 604,
IDENTIFIER = 605, BOOLCONSTANT = 605,
TYPE_NAME = 606, IDENTIFIER = 606,
CENTROID = 607, TYPE_NAME = 607,
IN = 608, CENTROID = 608,
OUT = 609, IN = 609,
INOUT = 610, OUT = 610,
STRUCT = 611, INOUT = 611,
VOID = 612, STRUCT = 612,
WHILE = 613, VOID = 613,
BREAK = 614, WHILE = 614,
CONTINUE = 615, BREAK = 615,
DO = 616, CONTINUE = 616,
ELSE = 617, DO = 617,
FOR = 618, ELSE = 618,
IF = 619, FOR = 619,
DISCARD = 620, IF = 620,
RETURN = 621, DISCARD = 621,
SWITCH = 622, RETURN = 622,
CASE = 623, SWITCH = 623,
DEFAULT = 624, CASE = 624,
UNIFORM = 625, DEFAULT = 625,
SHARED = 626, UNIFORM = 626,
BUFFER = 627, SHARED = 627,
FLAT = 628, BUFFER = 628,
SMOOTH = 629, FLAT = 629,
LAYOUT = 630, SMOOTH = 630,
DOUBLECONSTANT = 631, LAYOUT = 631,
INT16CONSTANT = 632, DOUBLECONSTANT = 632,
UINT16CONSTANT = 633, INT16CONSTANT = 633,
FLOAT16CONSTANT = 634, UINT16CONSTANT = 634,
INT32CONSTANT = 635, FLOAT16CONSTANT = 635,
UINT32CONSTANT = 636, INT32CONSTANT = 636,
INT64CONSTANT = 637, UINT32CONSTANT = 637,
UINT64CONSTANT = 638, INT64CONSTANT = 638,
SUBROUTINE = 639, UINT64CONSTANT = 639,
DEMOTE = 640, SUBROUTINE = 640,
PAYLOADNV = 641, DEMOTE = 641,
PAYLOADINNV = 642, PAYLOADNV = 642,
HITATTRNV = 643, PAYLOADINNV = 643,
CALLDATANV = 644, HITATTRNV = 644,
CALLDATAINNV = 645, CALLDATANV = 645,
PATCH = 646, CALLDATAINNV = 646,
SAMPLE = 647, PATCH = 647,
NONUNIFORM = 648, SAMPLE = 648,
COHERENT = 649, NONUNIFORM = 649,
VOLATILE = 650, COHERENT = 650,
RESTRICT = 651, VOLATILE = 651,
READONLY = 652, RESTRICT = 652,
WRITEONLY = 653, READONLY = 653,
DEVICECOHERENT = 654, WRITEONLY = 654,
QUEUEFAMILYCOHERENT = 655, DEVICECOHERENT = 655,
WORKGROUPCOHERENT = 656, QUEUEFAMILYCOHERENT = 656,
SUBGROUPCOHERENT = 657, WORKGROUPCOHERENT = 657,
NONPRIVATE = 658, SUBGROUPCOHERENT = 658,
NOPERSPECTIVE = 659, NONPRIVATE = 659,
EXPLICITINTERPAMD = 660, NOPERSPECTIVE = 660,
PERVERTEXNV = 661, EXPLICITINTERPAMD = 661,
PERPRIMITIVENV = 662, PERVERTEXNV = 662,
PERVIEWNV = 663, PERPRIMITIVENV = 663,
PERTASKNV = 664, PERVIEWNV = 664,
PRECISE = 665 PERTASKNV = 665,
PRECISE = 666
}; };
#endif #endif
@ -497,7 +498,7 @@ union YYSTYPE
glslang::TArraySizes* typeParameters; glslang::TArraySizes* typeParameters;
} interm; } interm;
#line 501 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ #line 502 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
}; };
typedef union YYSTYPE YYSTYPE; typedef union YYSTYPE YYSTYPE;

View File

@ -1090,6 +1090,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break; case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break;
case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break; case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break;
case EOpDebugPrintf: out.debug << "Debug printf"; break;
default: out.debug.message(EPrefixError, "Bad aggregation op"); default: out.debug.message(EPrefixError, "Bad aggregation op");
} }

19
glslang/MachineIndependent/preprocessor/Pp.cpp Executable file → Normal file
View File

@ -621,14 +621,25 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
{ {
const TSourceLoc directiveLoc = ppToken->loc; const TSourceLoc directiveLoc = ppToken->loc;
bool startWithLocalSearch = true; // to additionally include the extra "" paths bool startWithLocalSearch = true; // to additionally include the extra "" paths
int token = scanToken(ppToken); int token;
// handle <header-name>-style #include // Find the first non-whitespace char after #include
if (token == '<') { int ch = getChar();
while (ch == ' ' || ch == '\t') {
ch = getChar();
}
if (ch == '<') {
// <header-name> style
startWithLocalSearch = false; startWithLocalSearch = false;
token = scanHeaderName(ppToken, '>'); token = scanHeaderName(ppToken, '>');
} else if (ch == '"') {
// "header-name" style
token = scanHeaderName(ppToken, '"');
} else {
// unexpected, get the full token to generate the error
ungetChar();
token = scanToken(ppToken);
} }
// otherwise ppToken already has the header name and it was "header-name" style
if (token != PpAtomConstString) { if (token != PpAtomConstString) {
parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", ""); parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", "");

76
glslang/MachineIndependent/preprocessor/PpScanner.cpp Executable file → Normal file
View File

@ -1026,12 +1026,74 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
case '\'': case '\'':
return pp->characterLiteral(ppToken); return pp->characterLiteral(ppToken);
case '"': case '"':
// TODO: If this gets enhanced to handle escape sequences, or // #include uses scanHeaderName() to ignore these escape sequences.
// anything that is different than what #include needs, then
// #include needs to use scanHeaderName() for this.
ch = getch(); ch = getch();
while (ch != '"' && ch != '\n' && ch != EndOfInput) { while (ch != '"' && ch != '\n' && ch != EndOfInput) {
if (len < MaxTokenLength) { if (len < MaxTokenLength) {
if (ch == '\\') {
int nextCh = getch();
switch (nextCh) {
case '\'': ch = 0x27; break;
case '"': ch = 0x22; break;
case '?': ch = 0x3f; break;
case '\\': ch = 0x5c; break;
case 'a': ch = 0x07; break;
case 'b': ch = 0x08; break;
case 'f': ch = 0x0c; break;
case 'n': ch = 0x0a; break;
case 'r': ch = 0x0d; break;
case 't': ch = 0x09; break;
case 'v': ch = 0x0b; break;
case 'x':
// two character hex value
nextCh = getch();
if (nextCh >= '0' && nextCh <= '9')
nextCh -= '0';
else if (nextCh >= 'A' && nextCh <= 'F')
nextCh -= 'A' - 10;
else if (nextCh >= 'a' && nextCh <= 'f')
nextCh -= 'a' - 10;
else
pp->parseContext.ppError(ppToken->loc, "Expected hex value in escape sequence", "string", "");
ch = nextCh * 0x10;
nextCh = getch();
if (nextCh >= '0' && nextCh <= '9')
nextCh -= '0';
else if (nextCh >= 'A' && nextCh <= 'F')
nextCh -= 'A' - 10;
else if (nextCh >= 'a' && nextCh <= 'f')
nextCh -= 'a' - 10;
else
pp->parseContext.ppError(ppToken->loc, "Expected hex value in escape sequence", "string", "");
ch += nextCh;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
// three character octal value
nextCh = getch() - '0';
if (nextCh > 3)
pp->parseContext.ppError(ppToken->loc, "Expected octal value in escape sequence", "string", "");
ch = nextCh * 8 * 8;
nextCh = getch() - '0';
if (nextCh > 7)
pp->parseContext.ppError(ppToken->loc, "Expected octal value in escape sequence", "string", "");
ch += nextCh * 8;
nextCh = getch() - '0';
if (nextCh > 7)
pp->parseContext.ppError(ppToken->loc, "Expected octal value in escape sequence", "string", "");
ch += nextCh;
break;
default:
pp->parseContext.ppError(ppToken->loc, "Invalid escape sequence", "string", "");
break;
}
}
ppToken->name[len] = (char)ch; ppToken->name[len] = (char)ch;
len++; len++;
ch = getch(); ch = getch();
@ -1120,10 +1182,12 @@ int TPpContext::tokenize(TPpToken& ppToken)
continue; continue;
break; break;
case PpAtomConstString: case PpAtomConstString:
// HLSL allows string literals.
// GLSL allows string literals with GL_EXT_debug_printf.
if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) { if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) {
// HLSL allows string literals. parseContext.requireExtensions(ppToken.loc, 1, &E_GL_EXT_debug_printf, "string literal");
parseContext.ppError(ppToken.loc, "string literals not supported", "\"\"", ""); if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf))
continue; continue;
} }
break; break;
case '\'': case '\'':

View File

@ -309,6 +309,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.dataOut.frag", "spv.dataOut.frag",
"spv.dataOutIndirect.frag", "spv.dataOutIndirect.frag",
"spv.dataOutIndirect.vert", "spv.dataOutIndirect.vert",
"spv.debugPrintf.frag",
"spv.demoteDisabled.frag", "spv.demoteDisabled.frag",
"spv.deepRvalue.frag", "spv.deepRvalue.frag",
"spv.depthOut.frag", "spv.depthOut.frag",