@@ -190,6 +190,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
190
190
bool originalParam (glslang::TStorageQualifier, const glslang::TType&, bool implicitThisParam);
191
191
void makeFunctions (const glslang::TIntermSequence&);
192
192
void makeGlobalInitializers (const glslang::TIntermSequence&);
193
+ void collectRayTracingLinkerObjects ();
193
194
void visitFunctions (const glslang::TIntermSequence&);
194
195
void handleFunctionEntry (const glslang::TIntermAggregate* node);
195
196
void translateArguments (const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments,
@@ -273,6 +274,9 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
273
274
// requiring local translation to and from SPIR-V type on every access.
274
275
// Maps <builtin-variable-id -> AST-required-type-id>
275
276
std::unordered_map<spv::Id, spv::Id> forceType;
277
+
278
+ // Used later for generating OpTraceKHR/OpExecuteCallableKHR
279
+ std::unordered_map<unsigned int , glslang::TIntermSymbol *> locationToSymbol[2 ];
276
280
};
277
281
278
282
//
@@ -1232,7 +1236,7 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang:
1232
1236
spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass (const glslang::TType& type)
1233
1237
{
1234
1238
if (type.getBasicType () == glslang::EbtRayQuery)
1235
- return spv::StorageClassFunction ;
1239
+ return spv::StorageClassPrivate ;
1236
1240
if (type.getQualifier ().isPipeInput ())
1237
1241
return spv::StorageClassInput;
1238
1242
if (type.getQualifier ().isPipeOutput ())
@@ -1501,7 +1505,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
1501
1505
}
1502
1506
1503
1507
if (glslangIntermediate->getLayoutPrimitiveCulling ()) {
1504
- builder.addCapability (spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR );
1508
+ builder.addCapability (spv::CapabilityRayTraversalPrimitiveCullingKHR );
1505
1509
}
1506
1510
1507
1511
unsigned int mode;
@@ -1668,7 +1672,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
1668
1672
{
1669
1673
auto & extensions = glslangIntermediate->getRequestedExtensions ();
1670
1674
if (extensions.find (" GL_NV_ray_tracing" ) == extensions.end ()) {
1671
- builder.addCapability (spv::CapabilityRayTracingProvisionalKHR );
1675
+ builder.addCapability (spv::CapabilityRayTracingKHR );
1672
1676
builder.addExtension (" SPV_KHR_ray_tracing" );
1673
1677
}
1674
1678
else {
@@ -2118,8 +2122,9 @@ std::pair<spv::Id, spv::Id> TGlslangToSpvTraverser::getForcedType(glslang::TBuil
2118
2122
// these require changing a 64-bit scaler -> a vector of 32-bit components
2119
2123
if (glslangType.isVector ())
2120
2124
break ;
2121
- std::pair<spv::Id, spv::Id> ret (builder.makeVectorType (builder.makeUintType (32 ), 4 ),
2122
- builder.makeUintType (64 ));
2125
+ spv::Id ivec4_type = builder.makeVectorType (builder.makeUintType (32 ), 4 );
2126
+ spv::Id uint64_type = builder.makeUintType (64 );
2127
+ std::pair<spv::Id, spv::Id> ret (ivec4_type, uint64_type);
2123
2128
return ret;
2124
2129
}
2125
2130
// There are no SPIR-V builtins defined for these and map onto original non-transposed
@@ -2490,6 +2495,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
2490
2495
// anything else gets there, so visit out of order, doing them all now.
2491
2496
makeGlobalInitializers (node->getAsAggregate ()->getSequence ());
2492
2497
2498
+ // Pre process linker objects for ray tracing stages
2499
+ if (glslangIntermediate->isRayTracingStage ())
2500
+ collectRayTracingLinkerObjects ();
2501
+
2493
2502
// Initializers are done, don't want to visit again, but functions and link objects need to be processed,
2494
2503
// so do them manually.
2495
2504
visitFunctions (node->getAsAggregate ()->getSequence ());
@@ -2799,10 +2808,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
2799
2808
binOp = node->getOp ();
2800
2809
break ;
2801
2810
2802
- case glslang::EOpIgnoreIntersection:
2803
- case glslang::EOpTerminateRay:
2804
- case glslang::EOpTrace:
2805
- case glslang::EOpExecuteCallable:
2811
+ case glslang::EOpIgnoreIntersectionNV:
2812
+ case glslang::EOpTerminateRayNV:
2813
+ case glslang::EOpTraceNV:
2814
+ case glslang::EOpTraceKHR:
2815
+ case glslang::EOpExecuteCallableNV:
2816
+ case glslang::EOpExecuteCallableKHR:
2806
2817
case glslang::EOpWritePackedPrimitiveIndices4x8NV:
2807
2818
noReturnValue = true ;
2808
2819
break ;
@@ -2811,7 +2822,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
2811
2822
case glslang::EOpRayQueryGenerateIntersection:
2812
2823
case glslang::EOpRayQueryConfirmIntersection:
2813
2824
builder.addExtension (" SPV_KHR_ray_query" );
2814
- builder.addCapability (spv::CapabilityRayQueryProvisionalKHR );
2825
+ builder.addCapability (spv::CapabilityRayQueryKHR );
2815
2826
noReturnValue = true ;
2816
2827
break ;
2817
2828
case glslang::EOpRayQueryProceed:
@@ -2834,7 +2845,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
2834
2845
case glslang::EOpRayQueryGetIntersectionObjectToWorld:
2835
2846
case glslang::EOpRayQueryGetIntersectionWorldToObject:
2836
2847
builder.addExtension (" SPV_KHR_ray_query" );
2837
- builder.addCapability (spv::CapabilityRayQueryProvisionalKHR );
2848
+ builder.addCapability (spv::CapabilityRayQueryKHR );
2838
2849
break ;
2839
2850
case glslang::EOpCooperativeMatrixLoad:
2840
2851
case glslang::EOpCooperativeMatrixStore:
@@ -3087,11 +3098,18 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
3087
3098
)) {
3088
3099
bool cond = glslangOperands[arg]->getAsConstantUnion ()->getConstArray ()[0 ].getBConst ();
3089
3100
operands.push_back (builder.makeIntConstant (cond ? 1 : 0 ));
3090
- }
3091
- else {
3101
+ } else if ((arg == 10 && glslangOp == glslang::EOpTraceKHR) ||
3102
+ (arg == 1 && glslangOp == glslang::EOpExecuteCallableKHR)) {
3103
+ const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : 1 ;
3104
+ const int set = glslangOp == glslang::EOpTraceKHR ? 0 : 1 ;
3105
+ const int location = glslangOperands[opdNum]->getAsConstantUnion ()->getConstArray ()[0 ].getUConst ();
3106
+ auto itNode = locationToSymbol[set].find (location);
3107
+ visitSymbol (itNode->second );
3108
+ spv::Id symId = getSymbolId (itNode->second );
3109
+ operands.push_back (symId);
3110
+ } else {
3092
3111
operands.push_back (accessChainLoad (glslangOperands[arg]->getAsTyped ()->getType ()));
3093
- }
3094
-
3112
+ }
3095
3113
}
3096
3114
}
3097
3115
@@ -3494,11 +3512,11 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
3494
3512
3495
3513
switch (node->getFlowOp ()) {
3496
3514
case glslang::EOpKill:
3497
- builder.makeDiscard ( );
3515
+ builder.makeStatementTerminator (spv::OpKill, " post-discard " );
3498
3516
break ;
3499
3517
case glslang::EOpTerminateInvocation:
3500
3518
builder.addExtension (spv::E_SPV_KHR_terminate_invocation);
3501
- builder.makeTerminateInvocation ( );
3519
+ builder.makeStatementTerminator (spv::OpTerminateInvocation, " post-terminate-invocation " );
3502
3520
break ;
3503
3521
case glslang::EOpBreak:
3504
3522
if (breakForLoop.top ())
@@ -3535,6 +3553,12 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
3535
3553
builder.addExtension (spv::E_SPV_EXT_demote_to_helper_invocation);
3536
3554
builder.addCapability (spv::CapabilityDemoteToHelperInvocationEXT);
3537
3555
break ;
3556
+ case glslang::EOpTerminateRayKHR:
3557
+ builder.makeStatementTerminator (spv::OpTerminateRayKHR, " post-terminateRayKHR" );
3558
+ break ;
3559
+ case glslang::EOpIgnoreIntersectionKHR:
3560
+ builder.makeStatementTerminator (spv::OpIgnoreIntersectionKHR, " post-ignoreIntersectionKHR" );
3561
+ break ;
3538
3562
#endif
3539
3563
3540
3564
default :
@@ -4629,7 +4653,39 @@ void TGlslangToSpvTraverser::makeGlobalInitializers(const glslang::TIntermSequen
4629
4653
}
4630
4654
}
4631
4655
}
4656
+ // Walk over all linker objects to create a map for payload and callable data linker objects
4657
+ // and their location to be used during codegen for OpTraceKHR and OpExecuteCallableKHR
4658
+ // This is done here since it is possible that these linker objects are not be referenced in the AST
4659
+ void TGlslangToSpvTraverser::collectRayTracingLinkerObjects ()
4660
+ {
4661
+ glslang::TIntermAggregate* linkerObjects = glslangIntermediate->findLinkerObjects ();
4662
+ for (auto & objSeq : linkerObjects->getSequence ()) {
4663
+ auto objNode = objSeq->getAsSymbolNode ();
4664
+ if (objNode != nullptr ) {
4665
+ if (objNode->getQualifier ().hasLocation ()) {
4666
+ unsigned int location = objNode->getQualifier ().layoutLocation ;
4667
+ auto st = objNode->getQualifier ().storage ;
4668
+ int set;
4669
+ switch (st)
4670
+ {
4671
+ case glslang::EvqPayload:
4672
+ case glslang::EvqPayloadIn:
4673
+ set = 0 ;
4674
+ break ;
4675
+ case glslang::EvqCallableData:
4676
+ case glslang::EvqCallableDataIn:
4677
+ set = 1 ;
4678
+ break ;
4632
4679
4680
+ default :
4681
+ set = -1 ;
4682
+ }
4683
+ if (set != -1 )
4684
+ locationToSymbol[set].insert (std::make_pair (location, objNode));
4685
+ }
4686
+ }
4687
+ }
4688
+ }
4633
4689
// Process all the functions, while skipping initializers.
4634
4690
void TGlslangToSpvTraverser::visitFunctions (const glslang::TIntermSequence& glslFunctions)
4635
4691
{
@@ -6254,6 +6310,11 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
6254
6310
case glslang::EOpConstructReference:
6255
6311
unaryOp = spv::OpBitcast;
6256
6312
break ;
6313
+
6314
+ case glslang::EOpConvUint64ToAccStruct:
6315
+ case glslang::EOpConvUvec2ToAccStruct:
6316
+ unaryOp = spv::OpConvertUToAccelerationStructureKHR;
6317
+ break ;
6257
6318
#endif
6258
6319
6259
6320
case glslang::EOpCopyObject:
@@ -7840,10 +7901,16 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
7840
7901
typeId = builder.makeBoolType ();
7841
7902
opCode = spv::OpReportIntersectionKHR;
7842
7903
break ;
7843
- case glslang::EOpTrace:
7904
+ case glslang::EOpTraceNV:
7905
+ builder.createNoResultOp (spv::OpTraceNV, operands);
7906
+ return 0 ;
7907
+ case glslang::EOpTraceKHR:
7844
7908
builder.createNoResultOp (spv::OpTraceRayKHR, operands);
7845
7909
return 0 ;
7846
- case glslang::EOpExecuteCallable:
7910
+ case glslang::EOpExecuteCallableNV:
7911
+ builder.createNoResultOp (spv::OpExecuteCallableNV, operands);
7912
+ return 0 ;
7913
+ case glslang::EOpExecuteCallableKHR:
7847
7914
builder.createNoResultOp (spv::OpExecuteCallableKHR, operands);
7848
7915
return 0 ;
7849
7916
@@ -8131,11 +8198,11 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv:
8131
8198
spv::Id id = builder.createBuiltinCall (typeId, getExtBuiltins (spv::E_SPV_AMD_gcn_shader), spv::TimeAMD, args);
8132
8199
return builder.setPrecision (id, precision);
8133
8200
}
8134
- case glslang::EOpIgnoreIntersection :
8135
- builder.createNoResultOp (spv::OpIgnoreIntersectionKHR );
8201
+ case glslang::EOpIgnoreIntersectionNV :
8202
+ builder.createNoResultOp (spv::OpIgnoreIntersectionNV );
8136
8203
return 0 ;
8137
- case glslang::EOpTerminateRay :
8138
- builder.createNoResultOp (spv::OpTerminateRayKHR );
8204
+ case glslang::EOpTerminateRayNV :
8205
+ builder.createNoResultOp (spv::OpTerminateRayNV );
8139
8206
return 0 ;
8140
8207
case glslang::EOpRayQueryInitialize:
8141
8208
builder.createNoResultOp (spv::OpRayQueryInitializeKHR);
@@ -8263,7 +8330,8 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
8263
8330
}
8264
8331
8265
8332
#ifndef GLSLANG_WEB
8266
- if (symbol->getType ().isImage ()) {
8333
+ // Subgroup builtins which have input storage class are volatile for ray tracing stages.
8334
+ if (symbol->getType ().isImage () || symbol->getQualifier ().isPipeInput ()) {
8267
8335
std::vector<spv::Decoration> memory;
8268
8336
TranslateMemoryDecoration (symbol->getType ().getQualifier (), memory,
8269
8337
glslangIntermediate->usingVulkanMemoryModel ());
0 commit comments