Skip to content

Commit f6e0fe8

Browse files
committed
HLSL: Add support for printf().
Translate printf() to what GL_EXT_debug_printf has done. HLSL could define non-constant string variable and we don't have such features in SPIR-V, so just support constant string variable.
1 parent 3b334b2 commit f6e0fe8

File tree

9 files changed

+216
-5
lines changed

9 files changed

+216
-5
lines changed

SPIRV/GlslangToSpv.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,12 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
17201720
if (symbol->getType().getQualifier().isSpecConstant())
17211721
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
17221722

1723+
#ifdef ENABLE_HLSL
1724+
// Skip symbol handling if it is string-typed
1725+
if (symbol->getBasicType() == glslang::EbtString)
1726+
return;
1727+
#endif
1728+
17231729
// getSymbolId() will set up all the IO decorations on the first call.
17241730
// Formal function parameters were mapped during makeFunctions().
17251731
spv::Id id = getSymbolId(symbol);

Test/baseResults/hlsl.printf.comp.out

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
hlsl.printf.comp
2+
Shader version: 500
3+
local_size = (1, 1, 1)
4+
0:? Sequence
5+
0:4 Function Definition: @main( ( temp void)
6+
0:4 Function Parameters:
7+
0:? Sequence
8+
0:5 Debug printf ( temp void)
9+
0:5 Constant:
10+
0:5 "first string"
11+
0:6 Debug printf ( temp void)
12+
0:6 Constant:
13+
0:6 "please print this message."
14+
0:7 Debug printf ( temp void)
15+
0:7 Constant:
16+
0:7 "Variables are: %d %d %.2f"
17+
0:7 Constant:
18+
0:7 1 (const uint)
19+
0:7 Constant:
20+
0:7 2 (const uint)
21+
0:7 Constant:
22+
0:7 1.500000
23+
0:8 Debug printf ( temp void)
24+
0:8 Constant:
25+
0:8 "Integers are: %d %d %d"
26+
0:8 Constant:
27+
0:8 1 (const int)
28+
0:8 Constant:
29+
0:8 2 (const int)
30+
0:8 Constant:
31+
0:8 3 (const int)
32+
0:9 Debug printf ( temp void)
33+
0:9 Constant:
34+
0:9 "More: %d %d %d %d %d %d %d %d %d %d"
35+
0:9 Constant:
36+
0:9 1 (const int)
37+
0:9 Constant:
38+
0:9 2 (const int)
39+
0:9 Constant:
40+
0:9 3 (const int)
41+
0:9 Constant:
42+
0:9 4 (const int)
43+
0:9 Constant:
44+
0:9 5 (const int)
45+
0:9 Constant:
46+
0:9 6 (const int)
47+
0:9 Constant:
48+
0:9 7 (const int)
49+
0:9 Constant:
50+
0:9 8 (const int)
51+
0:9 Constant:
52+
0:9 9 (const int)
53+
0:9 Constant:
54+
0:9 10 (const int)
55+
0:4 Function Definition: main( ( temp void)
56+
0:4 Function Parameters:
57+
0:? Sequence
58+
0:4 Function Call: @main( ( temp void)
59+
0:? Linker Objects
60+
0:? 'first' ( const string)
61+
0:? "first string"
62+
63+
64+
Linked compute stage:
65+
66+
67+
Shader version: 500
68+
local_size = (1, 1, 1)
69+
0:? Sequence
70+
0:4 Function Definition: @main( ( temp void)
71+
0:4 Function Parameters:
72+
0:? Sequence
73+
0:5 Debug printf ( temp void)
74+
0:5 Constant:
75+
0:5 "first string"
76+
0:6 Debug printf ( temp void)
77+
0:6 Constant:
78+
0:6 "please print this message."
79+
0:7 Debug printf ( temp void)
80+
0:7 Constant:
81+
0:7 "Variables are: %d %d %.2f"
82+
0:7 Constant:
83+
0:7 1 (const uint)
84+
0:7 Constant:
85+
0:7 2 (const uint)
86+
0:7 Constant:
87+
0:7 1.500000
88+
0:8 Debug printf ( temp void)
89+
0:8 Constant:
90+
0:8 "Integers are: %d %d %d"
91+
0:8 Constant:
92+
0:8 1 (const int)
93+
0:8 Constant:
94+
0:8 2 (const int)
95+
0:8 Constant:
96+
0:8 3 (const int)
97+
0:9 Debug printf ( temp void)
98+
0:9 Constant:
99+
0:9 "More: %d %d %d %d %d %d %d %d %d %d"
100+
0:9 Constant:
101+
0:9 1 (const int)
102+
0:9 Constant:
103+
0:9 2 (const int)
104+
0:9 Constant:
105+
0:9 3 (const int)
106+
0:9 Constant:
107+
0:9 4 (const int)
108+
0:9 Constant:
109+
0:9 5 (const int)
110+
0:9 Constant:
111+
0:9 6 (const int)
112+
0:9 Constant:
113+
0:9 7 (const int)
114+
0:9 Constant:
115+
0:9 8 (const int)
116+
0:9 Constant:
117+
0:9 9 (const int)
118+
0:9 Constant:
119+
0:9 10 (const int)
120+
0:4 Function Definition: main( ( temp void)
121+
0:4 Function Parameters:
122+
0:? Sequence
123+
0:4 Function Call: @main( ( temp void)
124+
0:? Linker Objects
125+
0:? 'first' ( const string)
126+
0:? "first string"
127+
128+
// Module Version 10000
129+
// Generated by (magic number): 8000a
130+
// Id's are bound by 36
131+
132+
Capability Shader
133+
Extension "SPV_KHR_non_semantic_info"
134+
1: ExtInstImport "GLSL.std.450"
135+
9: ExtInstImport "NonSemantic.DebugPrintf"
136+
MemoryModel Logical GLSL450
137+
EntryPoint GLCompute 4 "main"
138+
ExecutionMode 4 LocalSize 1 1 1
139+
8: String "first string"
140+
11: String "please print this message."
141+
13: String "Variables are: %d %d %.2f"
142+
20: String "Integers are: %d %d %d"
143+
26: String "More: %d %d %d %d %d %d %d %d %d %d"
144+
Source HLSL 500
145+
Name 4 "main"
146+
Name 6 "@main("
147+
2: TypeVoid
148+
3: TypeFunction 2
149+
14: TypeInt 32 0
150+
15: 14(int) Constant 1
151+
16: 14(int) Constant 2
152+
17: TypeFloat 32
153+
18: 17(float) Constant 1069547520
154+
21: TypeInt 32 1
155+
22: 21(int) Constant 1
156+
23: 21(int) Constant 2
157+
24: 21(int) Constant 3
158+
27: 21(int) Constant 4
159+
28: 21(int) Constant 5
160+
29: 21(int) Constant 6
161+
30: 21(int) Constant 7
162+
31: 21(int) Constant 8
163+
32: 21(int) Constant 9
164+
33: 21(int) Constant 10
165+
4(main): 2 Function None 3
166+
5: Label
167+
35: 2 FunctionCall 6(@main()
168+
Return
169+
FunctionEnd
170+
6(@main(): 2 Function None 3
171+
7: Label
172+
10: 2 ExtInst 9(NonSemantic.DebugPrintf) 1(DebugPrintf) 8
173+
12: 2 ExtInst 9(NonSemantic.DebugPrintf) 1(DebugPrintf) 11
174+
19: 2 ExtInst 9(NonSemantic.DebugPrintf) 1(DebugPrintf) 13 15 16 18
175+
25: 2 ExtInst 9(NonSemantic.DebugPrintf) 1(DebugPrintf) 20 22 23 24
176+
34: 2 ExtInst 9(NonSemantic.DebugPrintf) 1(DebugPrintf) 26 22 23 24 27 28 29 30 31 32 33
177+
Return
178+
FunctionEnd

Test/hlsl.printf.comp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const string first = "first string";
2+
3+
[numthreads(1,1,1)]
4+
void main() {
5+
printf(first);
6+
printf("please print this message.");
7+
printf("Variables are: %d %d %.2f", 1u, 2u, 1.5f);
8+
printf("Integers are: %d %d %d", 1, 2, 3);
9+
printf("More: %d %d %d %d %d %d %d %d %d %d", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
10+
}
11+

glslang/HLSL/hlslGrammar.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,9 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
480480
}
481481

482482
// TODO: things scoped within an annotation need their own name space;
483-
// TODO: strings are not yet handled.
484-
if (variableType.getBasicType() != EbtString && parseContext.getAnnotationNestingLevel() == 0) {
483+
// TODO: non-constant strings are not yet handled.
484+
if (!(variableType.getBasicType() == EbtString && !variableType.getQualifier().isConstant()) &&
485+
parseContext.getAnnotationNestingLevel() == 0) {
485486
if (typedefDecl)
486487
parseContext.declareTypedef(idToken.loc, *fullName, variableType);
487488
else if (variableType.getBasicType() == EbtBlock) {

glslang/HLSL/hlslParseHelper.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7628,7 +7628,17 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
76287628
bool tie = false;
76297629

76307630
// send to the generic selector
7631-
const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
7631+
const TFunction* bestMatch = nullptr;
7632+
7633+
// printf has var args and is in the symbol table as "printf()",
7634+
// mangled to "printf("
7635+
if (call.getName() == "printf") {
7636+
TSymbol* symbol = symbolTable.find("printf(", &builtIn);
7637+
if (symbol)
7638+
return symbol->getAsFunction();
7639+
}
7640+
7641+
bestMatch = selectFunction(candidateList, call, convertible, better, tie);
76327642

76337643
if (bestMatch == nullptr) {
76347644
// If there is nothing selected by allowing only up-conversions (to a larger linearize() value),

glslang/HLSL/hlslParseables.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
605605
{ "noise", "S", "F", "V", "F", EShLangPS, false },
606606
{ "normalize", nullptr, nullptr, "V", "F", EShLangAll, false },
607607
{ "pow", nullptr, nullptr, "SVM,", "F,", EShLangAll, false },
608-
// { "printf", "-", "-", "", "", EShLangAll, false }, TODO: varargs
608+
{ "printf", nullptr, nullptr, "-", "-", EShLangAll, false },
609609
{ "Process2DQuadTessFactorsAvg", "-", "-", "V4,V2,>V4,>V2,", "F,,,,", EShLangHS, false },
610610
{ "Process2DQuadTessFactorsMax", "-", "-", "V4,V2,>V4,>V2,", "F,,,,", EShLangHS, false },
611611
{ "Process2DQuadTessFactorsMin", "-", "-", "V4,V2,>V4,>V2,", "F,,,,", EShLangHS, false },
@@ -1107,7 +1107,7 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profil
11071107
// symbolTable.relateToOperator("noise", EOpNoise); // TODO: check return type
11081108
symbolTable.relateToOperator("normalize", EOpNormalize);
11091109
symbolTable.relateToOperator("pow", EOpPow);
1110-
// symbolTable.relateToOperator("printf", EOpPrintf);
1110+
symbolTable.relateToOperator("printf", EOpDebugPrintf);
11111111
// symbolTable.relateToOperator("Process2DQuadTessFactorsAvg");
11121112
// symbolTable.relateToOperator("Process2DQuadTessFactorsMax");
11131113
// symbolTable.relateToOperator("Process2DQuadTessFactorsMin");

glslang/Include/Types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,7 @@ class TType {
19861986
case EbtAccStruct: return "accelerationStructureNV";
19871987
case EbtRayQuery: return "rayQueryEXT";
19881988
case EbtReference: return "reference";
1989+
case EbtString: return "string";
19891990
#endif
19901991
default: return "unknown type";
19911992
}

glslang/MachineIndependent/intermOut.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,9 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
13211321
out.debug << buf << "\n";
13221322
}
13231323
break;
1324+
case EbtString:
1325+
out.debug << "\"" << constUnion[i].getSConst()->c_str() << "\"\n";
1326+
break;
13241327
default:
13251328
out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
13261329
break;

gtests/Hlsl.FromFile.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ INSTANTIATE_TEST_SUITE_P(
308308
{"hlsl.pp.vert", "main"},
309309
{"hlsl.pp.line.frag", "main"},
310310
{"hlsl.precise.frag", "main"},
311+
{"hlsl.printf.comp", "main"},
311312
{"hlsl.promote.atomic.frag", "main"},
312313
{"hlsl.promote.binary.frag", "main"},
313314
{"hlsl.promote.vec1.frag", "main"},

0 commit comments

Comments
 (0)