summaryrefslogtreecommitdiff
path: root/source/slang/slang-emit-glsl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-emit-glsl.cpp')
-rw-r--r--source/slang/slang-emit-glsl.cpp38
1 files changed, 37 insertions, 1 deletions
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 32301c418..d768cff97 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -10,6 +10,7 @@
#include "slang-legalize-types.h"
#include "slang-ir-layout.h"
#include "slang/slang-ir.h"
+#include "slang-ir-call-graph.h"
#include <assert.h>
@@ -26,6 +27,11 @@ GLSLSourceEmitter::GLSLSourceEmitter(const Desc& desc) :
SLANG_ASSERT(m_glslExtensionTracker);
}
+void GLSLSourceEmitter::beforeComputeEmitActions(IRModule* module)
+{
+ buildEntryPointReferenceGraph(this->m_referencingEntryPoints, module);
+}
+
SlangResult GLSLSourceEmitter::init()
{
SLANG_RETURN_ON_FAIL(Super::init());
@@ -2171,7 +2177,7 @@ void GLSLSourceEmitter::handleRequiredCapabilitiesImpl(IRInst* inst)
}
}
- // The function may have IRRequireGLSLExtensionInst in its body. We also need to look for them.
+ // The function may have various requirment declaring functions its body. We also need to look for them.
auto func = as<IRFunc>(inst);
if (!func)
return;
@@ -2184,6 +2190,36 @@ void GLSLSourceEmitter::handleRequiredCapabilitiesImpl(IRInst* inst)
{
_requireGLSLExtension(requireGLSLExt->getExtensionName());
}
+ else if (auto requireComputeDerivative = as<IRRequireComputeDerivative>(childInst))
+ {
+ // only allowed 1 of derivative_group_quadsNV or derivative_group_linearNV
+ if (m_entryPointStage != Stage::Compute
+ || m_requiredPreludesRaw.contains("layout(derivative_group_quadsNV) in;")
+ || m_requiredPreludesRaw.contains("layout(derivative_group_linearNV) in;")
+ )
+ return;
+
+ _requireGLSLExtension(UnownedStringSlice("GL_NV_compute_shader_derivatives"));
+
+ // This will only run once per program.
+ HashSet<IRFunc*>* entryPointsUsingInst = getReferencingEntryPoints(m_referencingEntryPoints, func);
+
+ for (auto entryPoint : *entryPointsUsingInst)
+ {
+ bool isQuad = !entryPoint->findDecoration<IRDerivativeGroupLinearDecoration>();
+ auto numThreadsDecor = entryPoint->findDecoration<IRNumThreadsDecoration>();
+ if (isQuad)
+ {
+ verifyComputeDerivativeGroupModifiers(getSink(), inst->sourceLoc, true, false, numThreadsDecor);
+ m_requiredPreludesRaw.add("layout(derivative_group_quadsNV) in;");
+ }
+ else
+ {
+ verifyComputeDerivativeGroupModifiers(getSink(), inst->sourceLoc, false, true, numThreadsDecor);
+ m_requiredPreludesRaw.add("layout(derivative_group_linearNV) in;");
+ }
+ }
+ }
}
}