From 366a947cdf2e3c6958b7a9e17d561ce76ab0f594 Mon Sep 17 00:00:00 2001 From: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Date: Thu, 25 Apr 2024 09:18:32 -0400 Subject: Support derivative functions in compute & capabilities adjustments (#4014) * Support derivative functions in compute & capabilities adjustments fixes #4000 PR implements derivative functions in compute shaders properly so we have the functionality for SPIR-V & GLSL. Tests reflect fragment and compute paths. PR also adjusts capabilities to correct wrong SPRI-V target capabilities for when using textures. Remarks: 1. __requireComputeDerivative(); is a intrinsic_op and not modifier since inlining will destroy the modifier. 2. Derivative mode is tied to an entry point decoration `[DerivativeGroupQuad]`/`[DerivativeGroupLinear]` or GLSL syntax ``derivative_group_linearNV`. Default is to set the mode to `[DerivativeGroupQuad]` * remove -emit-spirv-directly * fixes 1. fix minor issue fwidth change where I returned the wrong type 2. fix issue where glslang{glsl->spirv} is wrong, so we don't run that test and just run the glsl test & direct spir-v test for intrinsic-texture.slang * adjust as per review and refine code 1. add test to ensure multi-diverging-in-logic entry points work -- 2 functions which may cause computeDerivatives + 1 that uses, 1 that does not. 2. naming 3. use entry point ref graph for c-like-targets 4. reordered some code to util's and removed `static linline` since that was just for ease of coding on my end (should not have been pushed). * Grammer * split up source file + issolate GLSL emit path change. --------- Co-authored-by: Yong He --- source/slang/slang-emit-spirv.cpp | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'source/slang/slang-emit-spirv.cpp') diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 06e5f0766..106248ef8 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -4,6 +4,7 @@ #include "slang-emit-base.h" #include "slang-ir-util.h" +#include "slang-ir-call-graph.h" #include "slang-ir.h" #include "slang-ir-insts.h" #include "slang-ir-layout.h" @@ -437,6 +438,7 @@ constexpr bool isPlural = true; template constexpr bool isSingular = !isPlural; + // Now that we've defined the intermediate data structures we will // use to represent SPIR-V code during emission, we will move on // to defining the main context type that will drive SPIR-V @@ -1278,6 +1280,11 @@ struct SPIRVEmitContext return result; } + bool hasExtensionDeclaration(const UnownedStringSlice& name) + { + return m_extensionInsts.containsKey(name); + } + struct SpvTypeInstKey { List words; @@ -2730,6 +2737,43 @@ struct SPIRVEmitContext auto inner = ensureInst(location); registerInst(inst, inner); result = inner; + break; + } + case kIROp_RequireComputeDerivative: + { + auto parentFunc = getParentFunc(inst); + + HashSet* entryPointsUsingInst = getReferencingEntryPoints(m_referencingEntryPoints, parentFunc); + for (IRFunc* entryPoint : *entryPointsUsingInst) + { + bool isQuad = true; + IREntryPointDecoration* entryPointDecor = nullptr; + for(auto dec : entryPoint->getDecorations()) + { + if(auto maybeEntryPointDecor = as(dec)) + entryPointDecor = maybeEntryPointDecor; + if(as(dec)) + isQuad = false; + } + if (!entryPointDecor || entryPointDecor->getProfile().getStage() != Stage::Compute) + continue; + + ensureExtensionDeclaration(UnownedStringSlice("SPV_NV_compute_shader_derivatives")); + auto numThreadsDecor = entryPointDecor->findDecoration(); + if (isQuad) + { + verifyComputeDerivativeGroupModifiers(this->m_sink, inst->sourceLoc, true, false, numThreadsDecor); + emitOpExecutionMode(getSection(SpvLogicalSectionID::ExecutionModes), nullptr, entryPoint, SpvExecutionModeDerivativeGroupQuadsNV); + emitOpCapability(getSection(SpvLogicalSectionID::Capabilities), nullptr, SpvCapabilityComputeDerivativeGroupQuadsNV); + } + else + { + verifyComputeDerivativeGroupModifiers(this->m_sink, inst->sourceLoc, false, true, numThreadsDecor); + emitOpExecutionMode(getSection(SpvLogicalSectionID::ExecutionModes), nullptr, entryPoint, SpvExecutionModeDerivativeGroupLinearNV); + emitOpCapability(getSection(SpvLogicalSectionID::Capabilities), nullptr, SpvCapabilityComputeDerivativeGroupLinearNV); + } + } + break; } case kIROp_Return: -- cgit v1.2.3