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-ir-call-graph.cpp | 112 +++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 source/slang/slang-ir-call-graph.cpp (limited to 'source/slang/slang-ir-call-graph.cpp') diff --git a/source/slang/slang-ir-call-graph.cpp b/source/slang/slang-ir-call-graph.cpp new file mode 100644 index 000000000..b3de60228 --- /dev/null +++ b/source/slang/slang-ir-call-graph.cpp @@ -0,0 +1,112 @@ +#include "slang-ir-call-graph.h" +#include "slang-ir-insts.h" +#include "slang-ir-clone.h" + +namespace Slang +{ + +void buildEntryPointReferenceGraph(Dictionary>& referencingEntryPoints, IRModule* module) +{ + struct WorkItem + { + IRFunc* entryPoint; IRInst* inst; + + HashCode getHashCode() const + { + return combineHash(Slang::getHashCode(entryPoint), Slang::getHashCode(inst)); + } + bool operator == (const WorkItem& other) const + { + return entryPoint == other.entryPoint && inst == other.inst; + } + }; + HashSet workListSet; + List workList; + auto addToWorkList = [&](WorkItem item) + { + if (workListSet.add(item)) + workList.add(item); + }; + + auto registerEntryPointReference = [&](IRFunc* entryPoint, IRInst* inst) + { + if (auto set = referencingEntryPoints.tryGetValue(inst)) + set->add(entryPoint); + else + { + HashSet newSet; + newSet.add(entryPoint); + referencingEntryPoints.add(inst, _Move(newSet)); + } + }; + auto visit = [&](IRFunc* entryPoint, IRInst* inst) + { + if (auto code = as(inst)) + { + registerEntryPointReference(entryPoint, inst); + for (auto child : code->getChildren()) + { + addToWorkList({ entryPoint, child }); + } + return; + } + switch (inst->getOp()) + { + case kIROp_GlobalParam: + case kIROp_SPIRVAsmOperandBuiltinVar: + registerEntryPointReference(entryPoint, inst); + break; + case kIROp_Block: + case kIROp_SPIRVAsm: + for (auto child : inst->getChildren()) + { + addToWorkList({ entryPoint, child }); + } + break; + case kIROp_Call: + { + auto call = as(inst); + addToWorkList({ entryPoint, call->getCallee() }); + } + break; + case kIROp_SPIRVAsmOperandInst: + { + auto operand = as(inst); + addToWorkList({ entryPoint, operand->getValue() }); + } + break; + } + for (UInt i = 0; i < inst->getOperandCount(); i++) + { + auto operand = inst->getOperand(i); + switch (operand->getOp()) + { + case kIROp_GlobalParam: + case kIROp_GlobalVar: + case kIROp_SPIRVAsmOperandBuiltinVar: + addToWorkList({ entryPoint, operand }); + break; + } + } + }; + + for (auto globalInst : module->getGlobalInsts()) + { + if (globalInst->getOp() == kIROp_Func && globalInst->findDecoration()) + { + visit(as(globalInst), globalInst); + } + } + for (Index i = 0; i < workList.getCount(); i++) + visit(workList[i].entryPoint, workList[i].inst); +} + +HashSet* getReferencingEntryPoints(Dictionary>& m_referencingEntryPoints, IRInst* inst) +{ + auto* referencingEntryPoints = m_referencingEntryPoints.tryGetValue(inst); + if (!referencingEntryPoints) + return nullptr; + return referencingEntryPoints; +} + +} -- cgit v1.2.3