summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2023-07-20 18:59:29 -0400
committerGitHub <noreply@github.com>2023-07-20 15:59:29 -0700
commitc7c493478e5fe88768de8c0e787e1ab993e693c7 (patch)
tree006d2ae71e36e159cf720632543347ac67e5d4c3 /source
parent76fe0a1dcc73af87846bf27932716188d68d37f0 (diff)
Fix for vk-shift-* GLSL emit issue (#3004)
* Handle different resource kinds that can appear via the vk-shift-* allowing some HLSL kinds in GLSL emit. * Determine the used kind for emit. * Added vk-shift-uniform-issue.slang * Use a better function name. Improve comments.
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-glsl.cpp58
1 files changed, 50 insertions, 8 deletions
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 853ef69ae..b378f69dc 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -145,6 +145,28 @@ void GLSLSourceEmitter::_requireGLSLVersion(int version)
}
}
+
+// This function was needed because the vk-shift-* change allows kinds which are "in effect" DescriptorSlots but appear as HLSL
+// kinds.
+//
+// This seems safe as a test, because in the description of `usesResourceKind`, it appears that VarLayout require offsets even if
+// it's zero.
+static LayoutResourceKind _findUsedDescriptorSlotLikeKind(IRVarLayout* layout, LayoutResourceKind kind)
+{
+ // DescriptorTableSlot is the most likely, so look for that first
+ if (layout->usesResourceKind(LayoutResourceKind::DescriptorTableSlot))
+ {
+ return LayoutResourceKind::DescriptorTableSlot;
+ }
+ else if (layout->usesResourceKind(kind))
+ {
+ // If we find the optional kind use that
+ return kind;
+ }
+ // We'll just assume descriptor slot then
+ return LayoutResourceKind::DescriptorTableSlot;
+}
+
void GLSLSourceEmitter::_emitGLSLStructuredBuffer(IRGlobalParam* varDecl, IRHLSLStructuredBufferTypeBase* structuredBufferType)
{
// Shader storage buffer is an OpenGL 430 feature
@@ -158,11 +180,11 @@ void GLSLSourceEmitter::_emitGLSLStructuredBuffer(IRGlobalParam* varDecl, IRHLSL
auto layout = getVarLayout(varDecl);
if (layout)
{
- LayoutResourceKind kind = LayoutResourceKind::DescriptorTableSlot;
+ const LayoutResourceKind usedKind = _findUsedDescriptorSlotLikeKind(layout, LayoutResourceKind::ShaderResource);
EmitVarChain chain(layout);
- const UInt index = getBindingOffset(&chain, kind);
- const UInt space = getBindingSpace(&chain, kind);
+ const UInt index = getBindingOffset(&chain, usedKind);
+ const UInt space = getBindingSpace(&chain, usedKind);
m_writer->emit(", binding = ");
m_writer->emit(index);
@@ -216,6 +238,7 @@ void GLSLSourceEmitter::_emitGLSLStructuredBuffer(IRGlobalParam* varDecl, IRHLSL
m_writer->emit(";\n");
}
+
void GLSLSourceEmitter::_emitGLSLByteAddressBuffer(IRGlobalParam* varDecl, IRByteAddressBufferTypeBase* byteAddressBufferType)
{
// TODO: A lot of this logic is copy-pasted from `emitIRStructuredBuffer_GLSL`.
@@ -233,11 +256,12 @@ void GLSLSourceEmitter::_emitGLSLByteAddressBuffer(IRGlobalParam* varDecl, IRByt
auto layout = getVarLayout(varDecl);
if (layout)
{
- LayoutResourceKind kind = LayoutResourceKind::DescriptorTableSlot;
+ const LayoutResourceKind usedKind = _findUsedDescriptorSlotLikeKind(layout, LayoutResourceKind::ShaderResource);
+
EmitVarChain chain(layout);
- const UInt index = getBindingOffset(&chain, kind);
- const UInt space = getBindingSpace(&chain, kind);
+ const UInt index = getBindingOffset(&chain, usedKind);
+ const UInt space = getBindingSpace(&chain, usedKind);
m_writer->emit(", binding = ");
m_writer->emit(index);
@@ -310,7 +334,16 @@ void GLSLSourceEmitter::_emitGLSLParameterGroup(IRGlobalParam* varDecl, IRUnifor
or IRGLSLShaderStorageBufferType which is read write.
*/
- _emitGLSLLayoutQualifier(LayoutResourceKind::DescriptorTableSlot, &containerChain);
+ {
+ // TODO(JS):
+ // The *assumption* here is that we only need to detect the LayoutResourceKind as used on the initial containerChain.varLayout
+ // rather than search up the chain.
+ //
+ // Perhaps there is still an issue here, because perhaps it's possible (?) to have a mixture of ConstantBuffer/DescriptorSlot
+ // and in that case the usedKind would just restrict to one and so produce the wrong answer.
+ const auto usedKind = _findUsedDescriptorSlotLikeKind(containerChain.varLayout, LayoutResourceKind::ConstantBuffer);
+ _emitGLSLLayoutQualifier(usedKind, &containerChain);
+ }
_emitGLSLLayoutQualifier(LayoutResourceKind::PushConstantBuffer, &containerChain);
bool isShaderRecord = _emitGLSLLayoutQualifier(LayoutResourceKind::ShaderRecord, &containerChain);
@@ -598,6 +631,7 @@ bool GLSLSourceEmitter::_emitGLSLLayoutQualifier(LayoutResourceKind kind, EmitVa
case LayoutResourceKind::ShaderResource:
case LayoutResourceKind::UnorderedAccess:
case LayoutResourceKind::SamplerState:
+
case LayoutResourceKind::DescriptorTableSlot:
m_writer->emit("layout(binding = ");
m_writer->emit(index);
@@ -1372,8 +1406,16 @@ void GLSLSourceEmitter::emitLayoutQualifiersImpl(IRVarLayout* layout)
{
switch (rr->getResourceKind())
{
- case LayoutResourceKind::Uniform:
+ // These can occur for vk-shift-* scenarios, and are in effect equivalent to DescriptorTableSlot
case LayoutResourceKind::ShaderResource:
+ case LayoutResourceKind::ConstantBuffer:
+ case LayoutResourceKind::SamplerState:
+ case LayoutResourceKind::UnorderedAccess:
+
+ //
+ case LayoutResourceKind::Uniform:
+
+ //
case LayoutResourceKind::DescriptorTableSlot:
m_writer->emit("uniform ");
break;