@@ -1442,48 +1442,34 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
1442
1442
// This will allow the entry-point name to be something like
1443
1443
// myNamespace::myEntrypointFunc.
1444
1444
std::string funcName = getFnName(decl);
1445
- std::string debugFuncName = funcName;
1446
-
1445
+ std::string srcFuncName = "src." + funcName;
1447
1446
SpirvFunction *func = declIdMapper.getOrRegisterFn(decl);
1447
+ SpirvFunction *srcFunc = nullptr;
1448
1448
1449
1449
auto loc = decl->getLocStart();
1450
1450
auto range = decl->getSourceRange();
1451
1451
RichDebugInfo *info = nullptr;
1452
1452
SpirvDebugFunction *debugFunction = nullptr;
1453
+ SpirvDebugFunction *srcDebugFunction = nullptr;
1453
1454
SpirvDebugInstruction *outer_scope = spvContext.getCurrentLexicalScope();
1454
- const auto &sm = astContext.getSourceManager();
1455
- if (spirvOptions.debugInfoRich && decl->hasBody()) {
1456
- const uint32_t line = sm.getPresumedLineNumber(loc);
1457
- const uint32_t column = sm.getPresumedColumnNumber(loc);
1458
- info = getOrCreateRichDebugInfo(loc);
1459
-
1460
- auto *source = info->source;
1461
- // Note that info->scopeStack.back() is a lexical scope of the function
1462
- // caller.
1463
- auto *parentScope = info->compilationUnit;
1464
- // TODO: figure out the proper flag based on the function decl.
1465
- // using FlagIsPublic for now.
1466
- uint32_t flags = 3u;
1467
- // The line number in the source program at which the function scope begins.
1468
- auto scopeLine = sm.getPresumedLineNumber(decl->getBody()->getLocStart());
1469
- debugFunction = spvBuilder.createDebugFunction(decl, debugFuncName, source,
1470
- line, column, parentScope,
1471
- "", flags, scopeLine, func);
1472
- func->setDebugScope(new (spvContext) SpirvDebugScope(debugFunction));
1473
-
1474
- spvContext.pushDebugLexicalScope(info, debugFunction);
1475
- }
1476
1455
1477
1456
bool isEntry = false;
1478
1457
const auto iter = functionInfoMap.find(decl);
1479
1458
if (iter != functionInfoMap.end()) {
1480
1459
const auto &entryInfo = iter->second;
1481
1460
if (entryInfo->isEntryFunction) {
1482
1461
isEntry = true;
1483
- funcName = "src." + funcName;
1484
1462
// Create wrapper for the entry function
1485
- if (!emitEntryFunctionWrapper(decl, func))
1463
+ srcFunc = func;
1464
+
1465
+ func = emitEntryFunctionWrapper(decl, &info, &debugFunction, srcFunc);
1466
+ if (func == nullptr)
1486
1467
return;
1468
+ if (spirvOptions.debugInfoRich && decl->hasBody()) {
1469
+ // use the HLSL name the debug user will expect to see
1470
+ srcDebugFunction = emitDebugFunction(decl, srcFunc, &info, funcName);
1471
+ }
1472
+
1487
1473
// Generate DebugEntryPoint if function definition
1488
1474
if (spirvOptions.debugInfoVulkan && debugFunction) {
1489
1475
auto *cu = dyn_cast<SpirvDebugCompilationUnit>(outer_scope);
@@ -1492,15 +1478,30 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
1492
1478
clang::getGitCommitHash(),
1493
1479
spirvOptions.clOptions);
1494
1480
}
1481
+ } else {
1482
+ if (spirvOptions.debugInfoRich && decl->hasBody()) {
1483
+ debugFunction = emitDebugFunction(decl, func, &info, funcName);
1484
+ }
1495
1485
}
1496
1486
}
1497
1487
1488
+ if (spirvOptions.debugInfoRich) {
1489
+ spvContext.pushDebugLexicalScope(info, debugFunction);
1490
+ }
1491
+
1498
1492
const QualType retType =
1499
1493
declIdMapper.getTypeAndCreateCounterForPotentialAliasVar(decl);
1500
1494
1501
- spvBuilder.beginFunction(retType, decl->getLocStart(), funcName,
1502
- decl->hasAttr<HLSLPreciseAttr>(),
1503
- decl->hasAttr<NoInlineAttr>(), func);
1495
+ if (srcFunc) {
1496
+ spvBuilder.beginFunction(retType, decl->getLocStart(), srcFuncName,
1497
+ decl->hasAttr<HLSLPreciseAttr>(),
1498
+ decl->hasAttr<NoInlineAttr>(), srcFunc);
1499
+
1500
+ } else {
1501
+ spvBuilder.beginFunction(retType, decl->getLocStart(), funcName,
1502
+ decl->hasAttr<HLSLPreciseAttr>(),
1503
+ decl->hasAttr<NoInlineAttr>(), func);
1504
+ }
1504
1505
1505
1506
bool isNonStaticMemberFn = false;
1506
1507
if (const auto *memberFn = dyn_cast<CXXMethodDecl>(decl)) {
@@ -1551,7 +1552,9 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
1551
1552
1552
1553
// Add DebugFunctionDefinition if we are emitting
1553
1554
// NonSemantic.Shader.DebugInfo.100 debug info
1554
- if (spirvOptions.debugInfoVulkan && debugFunction)
1555
+ if (spirvOptions.debugInfoVulkan && srcDebugFunction)
1556
+ spvBuilder.createDebugFunctionDef(srcDebugFunction, srcFunc);
1557
+ else if (spirvOptions.debugInfoVulkan && debugFunction)
1555
1558
spvBuilder.createDebugFunctionDef(debugFunction, func);
1556
1559
1557
1560
// Process all statments in the body.
@@ -13331,11 +13334,17 @@ bool SpirvEmitter::processTessellationShaderAttributes(
13331
13334
}
13332
13335
13333
13336
bool SpirvEmitter::emitEntryFunctionWrapperForRayTracing(
13334
- const FunctionDecl *decl, SpirvFunction *entryFuncInstr) {
13337
+ const FunctionDecl *decl, SpirvDebugFunction *debugFunction,
13338
+ SpirvFunction *entryFuncInstr) {
13335
13339
// The entry basic block.
13336
13340
auto *entryLabel = spvBuilder.createBasicBlock();
13337
13341
spvBuilder.setInsertPoint(entryLabel);
13338
13342
13343
+ // Add DebugFunctionDefinition if we are emitting
13344
+ // NonSemantic.Shader.DebugInfo.100 debug info.
13345
+ if (spirvOptions.debugInfoVulkan && debugFunction)
13346
+ spvBuilder.createDebugFunctionDef(debugFunction, entryFunction);
13347
+
13339
13348
// Initialize all global variables at the beginning of the wrapper
13340
13349
for (const VarDecl *varDecl : toInitGloalVars) {
13341
13350
const auto varInfo =
@@ -13598,8 +13607,36 @@ bool SpirvEmitter::processMeshOrAmplificationShaderAttributes(
13598
13607
return true;
13599
13608
}
13600
13609
13601
- bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13602
- SpirvFunction *entryFuncInstr) {
13610
+ SpirvDebugFunction *SpirvEmitter::emitDebugFunction(const FunctionDecl *decl,
13611
+ SpirvFunction *func,
13612
+ RichDebugInfo **info,
13613
+ std::string name) {
13614
+ auto loc = decl->getLocStart();
13615
+ const auto &sm = astContext.getSourceManager();
13616
+ const uint32_t line = sm.getPresumedLineNumber(loc);
13617
+ const uint32_t column = sm.getPresumedColumnNumber(loc);
13618
+ *info = getOrCreateRichDebugInfo(loc);
13619
+
13620
+ SpirvDebugSource *source = (*info)->source;
13621
+ // Note that info->scopeStack.back() is a lexical scope of the function
13622
+ // caller.
13623
+ SpirvDebugInstruction *parentScope = (*info)->compilationUnit;
13624
+ // TODO: figure out the proper flag based on the function decl.
13625
+ // using FlagIsPublic for now.
13626
+ uint32_t flags = 3u;
13627
+ // The line number in the source program at which the function scope begins.
13628
+ auto scopeLine = sm.getPresumedLineNumber(decl->getBody()->getLocStart());
13629
+ SpirvDebugFunction *debugFunction =
13630
+ spvBuilder.createDebugFunction(decl, name, source, line, column,
13631
+ parentScope, "", flags, scopeLine, func);
13632
+ func->setDebugScope(new (spvContext) SpirvDebugScope(debugFunction));
13633
+
13634
+ return debugFunction;
13635
+ }
13636
+
13637
+ SpirvFunction *SpirvEmitter::emitEntryFunctionWrapper(
13638
+ const FunctionDecl *decl, RichDebugInfo **info,
13639
+ SpirvDebugFunction **debugFunction, SpirvFunction *entryFuncInstr) {
13603
13640
// HS specific attributes
13604
13641
uint32_t numOutputControlPoints = 0;
13605
13642
SpirvInstruction *outputControlPointIdVal =
@@ -13620,6 +13657,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13620
13657
entryFunction = spvBuilder.beginFunction(
13621
13658
astContext.VoidTy, decl->getLocStart(), decl->getName());
13622
13659
13660
+ if (spirvOptions.debugInfoRich && decl->hasBody()) {
13661
+ *debugFunction = emitDebugFunction(decl, entryFunction, info, "wrapper");
13662
+ }
13663
+
13623
13664
// Specify that entryFunction is an entry function wrapper.
13624
13665
entryFunction->setEntryFunctionWrapper();
13625
13666
@@ -13634,7 +13675,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13634
13675
entryInfo->entryFunction = entryFunction;
13635
13676
13636
13677
if (spvContext.isRay()) {
13637
- return emitEntryFunctionWrapperForRayTracing(decl, entryFuncInstr);
13678
+ return emitEntryFunctionWrapperForRayTracing(decl, *debugFunction,
13679
+ entryFuncInstr)
13680
+ ? entryFunction
13681
+ : nullptr;
13638
13682
}
13639
13683
// Handle attributes specific to each shader stage
13640
13684
if (spvContext.isPS()) {
@@ -13643,7 +13687,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13643
13687
processComputeShaderAttributes(decl);
13644
13688
} else if (spvContext.isHS()) {
13645
13689
if (!processTessellationShaderAttributes(decl, &numOutputControlPoints))
13646
- return false ;
13690
+ return nullptr ;
13647
13691
13648
13692
// The input array size for HS is specified in the InputPatch parameter.
13649
13693
for (const auto *param : decl->params())
@@ -13655,7 +13699,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13655
13699
outputArraySize = numOutputControlPoints;
13656
13700
} else if (spvContext.isDS()) {
13657
13701
if (!processTessellationShaderAttributes(decl, &numOutputControlPoints))
13658
- return false ;
13702
+ return nullptr ;
13659
13703
13660
13704
// The input array size for HS is specified in the OutputPatch parameter.
13661
13705
for (const auto *param : decl->params())
@@ -13666,11 +13710,11 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13666
13710
// The per-vertex output of DS is not an array.
13667
13711
} else if (spvContext.isGS()) {
13668
13712
if (!processGeometryShaderAttributes(decl, &inputArraySize))
13669
- return false ;
13713
+ return nullptr ;
13670
13714
// The per-vertex output of GS is not an array.
13671
13715
} else if (spvContext.isMS() || spvContext.isAS()) {
13672
13716
if (!processMeshOrAmplificationShaderAttributes(decl, &outputArraySize))
13673
- return false ;
13717
+ return nullptr ;
13674
13718
}
13675
13719
13676
13720
// Go through all parameters and record the declaration of SV_ClipDistance
@@ -13686,14 +13730,14 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13686
13730
for (const auto *param : decl->params()) {
13687
13731
if (canActAsInParmVar(param))
13688
13732
if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(param, true))
13689
- return false ;
13733
+ return nullptr ;
13690
13734
if (canActAsOutParmVar(param))
13691
13735
if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(param, false))
13692
- return false ;
13736
+ return nullptr ;
13693
13737
}
13694
13738
// Also consider the SV_ClipDistance/SV_CullDistance in the return type
13695
13739
if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(decl, false))
13696
- return false ;
13740
+ return nullptr ;
13697
13741
13698
13742
// Calculate the total size of the ClipDistance/CullDistance array and the
13699
13743
// offset of SV_ClipDistance/SV_CullDistance variables within the array.
@@ -13715,6 +13759,11 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13715
13759
// after the basic block is created and insert point is set.
13716
13760
processInlineSpirvAttributes(decl);
13717
13761
13762
+ // Add DebugFunctionDefinition if we are emitting
13763
+ // NonSemantic.Shader.DebugInfo.100 debug info.
13764
+ if (spirvOptions.debugInfoVulkan && *debugFunction)
13765
+ spvBuilder.createDebugFunctionDef(*debugFunction, entryFunction);
13766
+
13718
13767
// Initialize all global variables at the beginning of the wrapper
13719
13768
for (const VarDecl *varDecl : toInitGloalVars) {
13720
13769
// SPIR-V does not have string variables
@@ -13766,7 +13815,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13766
13815
SpirvInstruction *loadedValue = nullptr;
13767
13816
13768
13817
if (!declIdMapper.createStageInputVar(param, &loadedValue, false))
13769
- return false ;
13818
+ return nullptr ;
13770
13819
13771
13820
// Only initialize the temporary variable if the parameter is indeed used,
13772
13821
// or if it is an inout parameter.
@@ -13805,15 +13854,15 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13805
13854
// Create stage output variables out of the return type.
13806
13855
if (!declIdMapper.createStageOutputVar(decl, numOutputControlPoints,
13807
13856
outputControlPointIdVal, retVal))
13808
- return false ;
13857
+ return nullptr ;
13809
13858
if (!processHSEntryPointOutputAndPCF(
13810
13859
decl, retType, retVal, numOutputControlPoints,
13811
13860
outputControlPointIdVal, primitiveIdVar, viewIdVar,
13812
13861
hullMainInputPatchParam))
13813
- return false ;
13862
+ return nullptr ;
13814
13863
} else {
13815
13864
if (!declIdMapper.createStageOutputVar(decl, retVal, /*forPCF*/ false))
13816
- return false ;
13865
+ return nullptr ;
13817
13866
}
13818
13867
13819
13868
// Create and write stage output variables for parameters marked as
@@ -13836,7 +13885,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13836
13885
param->getLocStart());
13837
13886
13838
13887
if (!declIdMapper.createStageOutputVar(param, loadedParam, false))
13839
- return false ;
13888
+ return nullptr ;
13840
13889
}
13841
13890
}
13842
13891
@@ -13851,7 +13900,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13851
13900
if (spvContext.isHS())
13852
13901
doDecl(patchConstFunc);
13853
13902
13854
- return true ;
13903
+ return entryFunction ;
13855
13904
}
13856
13905
13857
13906
bool SpirvEmitter::processHSEntryPointOutputAndPCF(
0 commit comments