Skip to content

Commit ffccefd

Browse files
dgkochalelenvneslimsah
authored
Updates for final Vulkan ray tracing extensions (KhronosGroup#2466)
* Fix traceRay/executeCallable to have id instead of constant. Update to final (non-provisional) SPIR-V capabilities (includes review feedback) - Change visibilty of findLinkerObjects. See merge request GLSL/glslang!78 * Add support for OpConvertUToAccelerationStructureKHR. GLSL : https://gitlab.khronos.org/GLSL/GLSL/-/merge_requests/60 SPV : https://gitlab.khronos.org/spirv/spirv-extensions/-/merge_requests/182 See merge request GLSL/glslang!77 * Add volatile qualifier to certain builtins for ray tracing. See merge request GLSL/glslang!81 * make gl_RayTmaxEXT volatile in intersection shader Vulkan Issue KhronosGroup#2268 * Add testing for layouts on SBT vulkan/vulkan#2230 - no layout specified should be same as std430 - explicitly test std140, std430, scalar layouts See merge request GLSL/glslang!86 * Support for new opcodes OpIgnoreIntersectionKHR and OpTerminateRayKHR vulkan/vulkan#2374 Add support for ignoreIntersectionEXT and terminateRayEXT as block terminator statements. See merge request GLSL/glslang!87 * Fix code-generation issues with global ray query variables See merge request GLSL/glslang!88 * update dependencies for spirv-headers and tools And update mesh shader results * Fix indeterminate argument ordering Authored-by: David Neto <dneto@google.com> Co-authored-by: Ashwin Lele (NVIDIA Corporation) <alele@nvidia.com> Co-authored-by: Neslisah <Neslisah.Torosdagli@amd.com>
1 parent 7f6559d commit ffccefd

File tree

76 files changed

+5030
-3742
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+5030
-3742
lines changed

SPIRV/GlslangToSpv.cpp

Lines changed: 92 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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:
12321236
spv::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.
46344690
void 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());

SPIRV/SpvBuilder.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -621,13 +621,13 @@ Id Builder::makeAccelerationStructureType()
621621
Id Builder::makeRayQueryType()
622622
{
623623
Instruction *type;
624-
if (groupedTypes[OpTypeRayQueryProvisionalKHR].size() == 0) {
625-
type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryProvisionalKHR);
626-
groupedTypes[OpTypeRayQueryProvisionalKHR].push_back(type);
624+
if (groupedTypes[OpTypeRayQueryKHR].size() == 0) {
625+
type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryKHR);
626+
groupedTypes[OpTypeRayQueryKHR].push_back(type);
627627
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
628628
module.mapInstruction(type);
629629
} else {
630-
type = groupedTypes[OpTypeRayQueryProvisionalKHR].back();
630+
type = groupedTypes[OpTypeRayQueryKHR].back();
631631
}
632632

633633
return type->getResultId();
@@ -1447,17 +1447,10 @@ void Builder::leaveFunction()
14471447
}
14481448

14491449
// Comments in header
1450-
void Builder::makeDiscard()
1450+
void Builder::makeStatementTerminator(spv::Op opcode, const char *name)
14511451
{
1452-
buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(OpKill)));
1453-
createAndSetNoPredecessorBlock("post-discard");
1454-
}
1455-
1456-
// Comments in header
1457-
void Builder::makeTerminateInvocation()
1458-
{
1459-
buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(OpTerminateInvocation)));
1460-
createAndSetNoPredecessorBlock("post-terminate-invocation");
1452+
buildPoint->addInstruction(std::unique_ptr<Instruction>(new Instruction(opcode)));
1453+
createAndSetNoPredecessorBlock(name);
14611454
}
14621455

14631456
// Comments in header

SPIRV/SpvBuilder.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,9 @@ class Builder {
357357
// Generate all the code needed to finish up a function.
358358
void leaveFunction();
359359

360-
// Create a discard or terminate-invocation.
361-
void makeDiscard();
362-
void makeTerminateInvocation();
360+
// Create block terminator instruction for certain statements like
361+
// discard, terminate-invocation, terminateRayEXT, or ignoreIntersectionEXT
362+
void makeStatementTerminator(spv::Op opcode, const char *name);
363363

364364
// Create a global or function local or IO variable.
365365
Id createVariable(Decoration precision, StorageClass, Id type, const char* name = nullptr,

0 commit comments

Comments
 (0)