diff options
| author | ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> | 2024-04-25 09:18:32 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-25 09:18:32 -0400 |
| commit | 366a947cdf2e3c6958b7a9e17d561ce76ab0f594 (patch) | |
| tree | ca305c7315806b51c3922d334b10b5f203a0b219 /source/slang/slang-ir-call-graph.cpp | |
| parent | 52dcb5bd44aa15f07826062c53fae344d55959e9 (diff) | |
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 <yonghe@outlook.com>
Diffstat (limited to 'source/slang/slang-ir-call-graph.cpp')
| -rw-r--r-- | source/slang/slang-ir-call-graph.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
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<IRInst*, HashSet<IRFunc*>>& 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<WorkItem> workListSet; + List<WorkItem> 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<IRFunc*> newSet; + newSet.add(entryPoint); + referencingEntryPoints.add(inst, _Move(newSet)); + } + }; + auto visit = [&](IRFunc* entryPoint, IRInst* inst) + { + if (auto code = as<IRGlobalValueWithCode>(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<IRCall>(inst); + addToWorkList({ entryPoint, call->getCallee() }); + } + break; + case kIROp_SPIRVAsmOperandInst: + { + auto operand = as<IRSPIRVAsmOperandInst>(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<IREntryPointDecoration>()) + { + visit(as<IRFunc>(globalInst), globalInst); + } + } + for (Index i = 0; i < workList.getCount(); i++) + visit(workList[i].entryPoint, workList[i].inst); +} + +HashSet<IRFunc*>* getReferencingEntryPoints(Dictionary<IRInst*, HashSet<IRFunc*>>& m_referencingEntryPoints, IRInst* inst) +{ + auto* referencingEntryPoints = m_referencingEntryPoints.tryGetValue(inst); + if (!referencingEntryPoints) + return nullptr; + return referencingEntryPoints; +} + +} |
