diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2021-01-05 09:00:00 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-05 09:00:00 -0800 |
| commit | b4f94629f225b837e7102acc337610c5d4d8a7c1 (patch) | |
| tree | cb75cc2059d517fa41dfe2954f2893e04fa6af3b /source/slang/slang-emit-c-like.cpp | |
| parent | f5fffa90e936ab462b3842f9b2cfa996ae870fe4 (diff) | |
Use "capability" system to select VKRT extension (#1647)
* Use "capability" system to select VKRT extension
Slang currently supports translation of ray tracing shader code to Vulkan GLSL code that uses the `GL_NV_ray_tracing` extension. A multi-vendor equivalent of that extension has been released as `GL_EXT_ray_tracing` and we want Slang to support that extension as well.
At the simplest, making the change from one extension to the other is just a matter of changing a few strings, since it does not appear that anything of significance was changed at the GLSL level (or even in SPIR-V). Where this gets trickier is when we have users who want us to support *both* extensions, and to be able to switch between them.
The solution we've implemented here more or less amounts to:
* If you don't tell the compiler which extension to use, it will default to `GL_EXT_ray_tracing` (the newer multi-vendor one).
* If you explicitly want the older extension, you can opt into it using the `-profile` option or via a new API for explicitly adding capabilities to your target.
Making that work required a few different kinds of changes:
* The options parsing and public API needed ways to add optional capabilities to a target.
* During GLSL code emit, we can check the capabilities that were added to the target to see if the `GL_NV_ray_tracing` extension was explicitly enabled and, if not, default to using the `GL_EXT_ray_tracing` names for things. This step is needed because some of the modifiers/attributes involved in the extension have to be handled explicitly in the code generator rather than implicitly as part of mapping intrinsic functions.
* We add two different translations to the relevant operatiosn in the stdlib, one marked with each of the extensions. If profile/capability-based overload resolution can be relied on to pick the right one, this should Just Work.
* Next, a bunch of work had to go into making capability-based overloading Just Work for the purposes of this change. There's been a nearly complete reworking of the implementation of `CapabilitySet` here to make it more suitable for our needs.
* The tests that were using ray tracing translation for Vulkan needed to be updated. For some of them I updated their baselines to use `GL_EXT_ray_tracing` so that they can test the new path. For others, I updated the command line for the test case so that it explicitly opts into using `GL_NV_ray_tracing`. The result is that we have some coverage of each extension. I would have liked to have each test run in both modes, but our pass-through glslang support doesn't support `-D` options, so I couldn't take that step easily.
This change does *not* add support for `GL_EXT_ray_query`, the extension that supports "DXR 1.1" style queries under Vulkan. Adding support for that extension should hopefully be a smaller step because it doesn't have the same multiple-extensions issue.
This change does *not* address a lot of possible avenues for improvement or cleanup around the capability system. It focuses only on those changes that are necessary to make the ray tracing feature work and leaves the rest for future work.
* fixup: infinite loop
* Comment-only change to retrigger TC build
Diffstat (limited to 'source/slang/slang-emit-c-like.cpp')
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 31 |
1 files changed, 6 insertions, 25 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 9d208b8a3..facb8a710 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -630,7 +630,7 @@ String CLikeSourceEmitter::generateName(IRInst* inst) // If the instruction names something // that should be emitted as a target intrinsic, // then use that name instead. - if(auto intrinsicDecoration = findBestTargetIntrinsicDecorationXXX(inst)) + if(auto intrinsicDecoration = findBestTargetIntrinsicDecoration(inst)) { return String(intrinsicDecoration->getDefinition()); } @@ -1092,7 +1092,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst) // This is significant, because we can within a target intrinsics definition multiple accesses to the same // parameter. This is not indicated into the call, and can lead to output code computes something multiple // times as it is folding into the expression of the the target intrinsic, which we don't want. - if (auto targetIntrinsicDecoration = findBestTargetIntrinsicDecorationXXX(funcValue)) + if (auto targetIntrinsicDecoration = findBestTargetIntrinsicDecoration(funcValue)) { // Find the index of the original instruction, to see if it's multiply used. IRUse* args = callInst->getArgs(); @@ -1300,7 +1300,7 @@ IRTargetSpecificDecoration* CLikeSourceEmitter::findBestTargetDecoration(IRInst* return Slang::findBestTargetDecoration(inInst, getTargetCaps()); } -IRTargetIntrinsicDecoration* CLikeSourceEmitter::findBestTargetIntrinsicDecorationXXX(IRInst* inInst) +IRTargetIntrinsicDecoration* CLikeSourceEmitter::findBestTargetIntrinsicDecoration(IRInst* inInst) { return as<IRTargetIntrinsicDecoration>(findBestTargetDecoration(inInst)); } @@ -1834,25 +1834,6 @@ void CLikeSourceEmitter::emitIntrinsicCallExprImpl( } break; - case 'T': - { - // The `$XT` case handles selecting between - // the `gl_HitTNV` and `gl_RayTmaxNV` builtins, - // based on what stage we are using: - switch( m_entryPointStage ) - { - default: - m_writer->emit("gl_RayTmaxNV"); - break; - - case Stage::AnyHit: - case Stage::ClosestHit: - m_writer->emit("gl_HitTNV"); - break; - } - } - break; - default: SLANG_RELEASE_ASSERT(false); break; @@ -1955,7 +1936,7 @@ void CLikeSourceEmitter::emitCallExpr(IRCall* inst, EmitOpInfo outerPrec) // We want to detect any call to an intrinsic operation, // that we can emit it directly without mangling, etc. - if(auto targetIntrinsic = findBestTargetIntrinsicDecorationXXX(funcValue)) + if(auto targetIntrinsic = findBestTargetIntrinsicDecoration(funcValue)) { emitIntrinsicCallExpr(inst, targetIntrinsic, outerPrec); } @@ -3334,7 +3315,7 @@ bool CLikeSourceEmitter::isTargetIntrinsic(IRFunc* func) // it has a suitable decoration marking it as a // target intrinsic for the current compilation target. // - return findBestTargetIntrinsicDecorationXXX(func) != nullptr; + return findBestTargetIntrinsicDecoration(func) != nullptr; } void CLikeSourceEmitter::emitFunc(IRFunc* func) @@ -3367,7 +3348,7 @@ void CLikeSourceEmitter::emitStruct(IRStructType* structType) { // If the selected `struct` type is actually an intrinsic // on our target, then we don't want to emit anything at all. - if(auto intrinsicDecoration = findBestTargetIntrinsicDecorationXXX(structType)) + if(auto intrinsicDecoration = findBestTargetIntrinsicDecoration(structType)) { return; } |
