@@ -190,6 +190,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
190190 bool originalParam (glslang::TStorageQualifier, const glslang::TType&, bool implicitThisParam);
191191 void makeFunctions (const glslang::TIntermSequence&);
192192 void makeGlobalInitializers (const glslang::TIntermSequence&);
193+ void collectRayTracingLinkerObjects ();
193194 void visitFunctions (const glslang::TIntermSequence&);
194195 void handleFunctionEntry (const glslang::TIntermAggregate* node);
195196 void translateArguments (const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments,
@@ -273,6 +274,9 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
273274 // requiring local translation to and from SPIR-V type on every access.
274275 // Maps <builtin-variable-id -> AST-required-type-id>
275276 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 ];
276280};
277281
278282//
@@ -1232,7 +1236,7 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang:
12321236spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass (const glslang::TType& type)
12331237{
12341238 if (type.getBasicType () == glslang::EbtRayQuery)
1235- return spv::StorageClassFunction ;
1239+ return spv::StorageClassPrivate ;
12361240 if (type.getQualifier ().isPipeInput ())
12371241 return spv::StorageClassInput;
12381242 if (type.getQualifier ().isPipeOutput ())
@@ -1501,7 +1505,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
15011505 }
15021506
15031507 if (glslangIntermediate->getLayoutPrimitiveCulling ()) {
1504- builder.addCapability (spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR );
1508+ builder.addCapability (spv::CapabilityRayTraversalPrimitiveCullingKHR );
15051509 }
15061510
15071511 unsigned int mode;
@@ -1668,7 +1672,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
16681672 {
16691673 auto & extensions = glslangIntermediate->getRequestedExtensions ();
16701674 if (extensions.find (" GL_NV_ray_tracing" ) == extensions.end ()) {
1671- builder.addCapability (spv::CapabilityRayTracingProvisionalKHR );
1675+ builder.addCapability (spv::CapabilityRayTracingKHR );
16721676 builder.addExtension (" SPV_KHR_ray_tracing" );
16731677 }
16741678 else {
@@ -2118,8 +2122,9 @@ std::pair<spv::Id, spv::Id> TGlslangToSpvTraverser::getForcedType(glslang::TBuil
21182122 // these require changing a 64-bit scaler -> a vector of 32-bit components
21192123 if (glslangType.isVector ())
21202124 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);
21232128 return ret;
21242129 }
21252130 // 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
24902495 // anything else gets there, so visit out of order, doing them all now.
24912496 makeGlobalInitializers (node->getAsAggregate ()->getSequence ());
24922497
2498+ // Pre process linker objects for ray tracing stages
2499+ if (glslangIntermediate->isRayTracingStage ())
2500+ collectRayTracingLinkerObjects ();
2501+
24932502 // Initializers are done, don't want to visit again, but functions and link objects need to be processed,
24942503 // so do them manually.
24952504 visitFunctions (node->getAsAggregate ()->getSequence ());
@@ -2799,10 +2808,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
27992808 binOp = node->getOp ();
28002809 break ;
28012810
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:
28062817 case glslang::EOpWritePackedPrimitiveIndices4x8NV:
28072818 noReturnValue = true ;
28082819 break ;
@@ -2811,7 +2822,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
28112822 case glslang::EOpRayQueryGenerateIntersection:
28122823 case glslang::EOpRayQueryConfirmIntersection:
28132824 builder.addExtension (" SPV_KHR_ray_query" );
2814- builder.addCapability (spv::CapabilityRayQueryProvisionalKHR );
2825+ builder.addCapability (spv::CapabilityRayQueryKHR );
28152826 noReturnValue = true ;
28162827 break ;
28172828 case glslang::EOpRayQueryProceed:
@@ -2834,7 +2845,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
28342845 case glslang::EOpRayQueryGetIntersectionObjectToWorld:
28352846 case glslang::EOpRayQueryGetIntersectionWorldToObject:
28362847 builder.addExtension (" SPV_KHR_ray_query" );
2837- builder.addCapability (spv::CapabilityRayQueryProvisionalKHR );
2848+ builder.addCapability (spv::CapabilityRayQueryKHR );
28382849 break ;
28392850 case glslang::EOpCooperativeMatrixLoad:
28402851 case glslang::EOpCooperativeMatrixStore:
@@ -3087,11 +3098,18 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
30873098 )) {
30883099 bool cond = glslangOperands[arg]->getAsConstantUnion ()->getConstArray ()[0 ].getBConst ();
30893100 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 {
30923111 operands.push_back (accessChainLoad (glslangOperands[arg]->getAsTyped ()->getType ()));
3093- }
3094-
3112+ }
30953113 }
30963114 }
30973115
@@ -3494,11 +3512,11 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
34943512
34953513 switch (node->getFlowOp ()) {
34963514 case glslang::EOpKill:
3497- builder.makeDiscard ( );
3515+ builder.makeStatementTerminator (spv::OpKill, " post-discard " );
34983516 break ;
34993517 case glslang::EOpTerminateInvocation:
35003518 builder.addExtension (spv::E_SPV_KHR_terminate_invocation);
3501- builder.makeTerminateInvocation ( );
3519+ builder.makeStatementTerminator (spv::OpTerminateInvocation, " post-terminate-invocation " );
35023520 break ;
35033521 case glslang::EOpBreak:
35043522 if (breakForLoop.top ())
@@ -3535,6 +3553,12 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
35353553 builder.addExtension (spv::E_SPV_EXT_demote_to_helper_invocation);
35363554 builder.addCapability (spv::CapabilityDemoteToHelperInvocationEXT);
35373555 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 ;
35383562#endif
35393563
35403564 default :
@@ -4629,7 +4653,39 @@ void TGlslangToSpvTraverser::makeGlobalInitializers(const glslang::TIntermSequen
46294653 }
46304654 }
46314655}
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 ;
46324679
4680+ default :
4681+ set = -1 ;
4682+ }
4683+ if (set != -1 )
4684+ locationToSymbol[set].insert (std::make_pair (location, objNode));
4685+ }
4686+ }
4687+ }
4688+ }
46334689// Process all the functions, while skipping initializers.
46344690void TGlslangToSpvTraverser::visitFunctions (const glslang::TIntermSequence& glslFunctions)
46354691{
@@ -6254,6 +6310,11 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
62546310 case glslang::EOpConstructReference:
62556311 unaryOp = spv::OpBitcast;
62566312 break ;
6313+
6314+ case glslang::EOpConvUint64ToAccStruct:
6315+ case glslang::EOpConvUvec2ToAccStruct:
6316+ unaryOp = spv::OpConvertUToAccelerationStructureKHR;
6317+ break ;
62576318#endif
62586319
62596320 case glslang::EOpCopyObject:
@@ -7840,10 +7901,16 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
78407901 typeId = builder.makeBoolType ();
78417902 opCode = spv::OpReportIntersectionKHR;
78427903 break ;
7843- case glslang::EOpTrace:
7904+ case glslang::EOpTraceNV:
7905+ builder.createNoResultOp (spv::OpTraceNV, operands);
7906+ return 0 ;
7907+ case glslang::EOpTraceKHR:
78447908 builder.createNoResultOp (spv::OpTraceRayKHR, operands);
78457909 return 0 ;
7846- case glslang::EOpExecuteCallable:
7910+ case glslang::EOpExecuteCallableNV:
7911+ builder.createNoResultOp (spv::OpExecuteCallableNV, operands);
7912+ return 0 ;
7913+ case glslang::EOpExecuteCallableKHR:
78477914 builder.createNoResultOp (spv::OpExecuteCallableKHR, operands);
78487915 return 0 ;
78497916
@@ -8131,11 +8198,11 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv:
81318198 spv::Id id = builder.createBuiltinCall (typeId, getExtBuiltins (spv::E_SPV_AMD_gcn_shader), spv::TimeAMD, args);
81328199 return builder.setPrecision (id, precision);
81338200 }
8134- case glslang::EOpIgnoreIntersection :
8135- builder.createNoResultOp (spv::OpIgnoreIntersectionKHR );
8201+ case glslang::EOpIgnoreIntersectionNV :
8202+ builder.createNoResultOp (spv::OpIgnoreIntersectionNV );
81368203 return 0 ;
8137- case glslang::EOpTerminateRay :
8138- builder.createNoResultOp (spv::OpTerminateRayKHR );
8204+ case glslang::EOpTerminateRayNV :
8205+ builder.createNoResultOp (spv::OpTerminateRayNV );
81398206 return 0 ;
81408207 case glslang::EOpRayQueryInitialize:
81418208 builder.createNoResultOp (spv::OpRayQueryInitializeKHR);
@@ -8263,7 +8330,8 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
82638330 }
82648331
82658332#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 ()) {
82678335 std::vector<spv::Decoration> memory;
82688336 TranslateMemoryDecoration (symbol->getType ().getQualifier (), memory,
82698337 glslangIntermediate->usingVulkanMemoryModel ());
0 commit comments