summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-10-19 13:53:18 -0700
committerGitHub <noreply@github.com>2018-10-19 13:53:18 -0700
commit53731f674601a2eb81c5715957d2e0e65637aee3 (patch)
treedafd74a4e926676c55b93e06e8275a4844a862e8 /source
parent3a5214b65b2a5efdbcf9bf6fb4d7603e9ee63234 (diff)
Vulkan implicit sampler fixups (#686)
* Fix sampler-less texture functions (#685) * Fix sampler-less texeture functions I'm honestly not sure how the original work on this feature in #648 worked at all (probably insufficient testing). We have these front-end modifiers to indicate that a particular function definition requires a certain GLSL version, or a GLSL extension in order to be used, and they are supposed to be automatically employed by the logic in `emit.cpp` to output `#extension` lines in the output GLSL. However, it turns out that nothing is actually wired up right now, so that adding the modifiers to a declaration is a placebo. This change propagates the modifiers through as decorations, and then uses them during GLSL code emit, which allows the functions that require `EXT_samplerless_texture_functions` to work. * fixup: 32-bit warning * Add serialization support for GLSL extension/version decorations
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp31
-rw-r--r--source/slang/ir-insts.h14
-rw-r--r--source/slang/ir-serialize.cpp30
-rw-r--r--source/slang/ir.cpp16
-rw-r--r--source/slang/ir.h2
-rw-r--r--source/slang/lower-to-ir.cpp17
6 files changed, 109 insertions, 1 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 4961518f1..c9e19dffc 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -3466,9 +3466,38 @@ struct EmitVisitor
IREmitMode mode,
EOpInfo outerPrec)
{
+ auto funcValue = inst->getOperand(0);
+
+ // Does this function declare any requirements on GLSL version or
+ // extensions, which should affect our output?
+ if(getTarget(ctx) == CodeGenTarget::GLSL)
+ {
+ auto decoratedValue = funcValue;
+ while (auto specInst = as<IRSpecialize>(decoratedValue))
+ {
+ decoratedValue = getSpecializedValue(specInst);
+ }
+
+ for( auto decoration = decoratedValue->firstDecoration; decoration; decoration = decoration->next )
+ {
+ switch(decoration->op)
+ {
+ default:
+ break;
+
+ case kIRDecorationOp_RequireGLSLExtension:
+ requireGLSLExtension(String(((IRRequireGLSLExtensionDecoration*)decoration)->extensionName));
+ break;
+
+ case kIRDecorationOp_RequireGLSLVersion:
+ requireGLSLVersion(int(((IRRequireGLSLVersionDecoration*)decoration)->languageVersion));
+ break;
+ }
+ }
+ }
+
// We want to detect any call to an intrinsic operation,
// that we can emit it directly without mangling, etc.
- auto funcValue = inst->getOperand(0);
if(auto irFunc = asTargetIntrinsic(ctx, funcValue))
{
emitIntrinsicCallExpr(ctx, inst, irFunc, mode, outerPrec);
diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h
index 1bce75b88..8d1c4708a 100644
--- a/source/slang/ir-insts.h
+++ b/source/slang/ir-insts.h
@@ -133,6 +133,20 @@ struct IRVulkanHitAttributesDecoration : IRDecoration
enum { kDecorationOp = kIRDecorationOp_VulkanHitAttributes };
};
+struct IRRequireGLSLVersionDecoration : IRDecoration
+{
+ enum { kDecorationOp = kIRDecorationOp_RequireGLSLVersion };
+
+ Int languageVersion;
+};
+
+struct IRRequireGLSLExtensionDecoration : IRDecoration
+{
+ enum { kDecorationOp = kIRDecorationOp_RequireGLSLExtension };
+
+ StringRepresentation* extensionName;
+};
+
// An instruction that specializes another IR value
// (representing a generic) to a particular set of generic arguments
// (instructions representing types, witness tables, etc.)
diff --git a/source/slang/ir-serialize.cpp b/source/slang/ir-serialize.cpp
index 3b0e45e23..e204944a7 100644
--- a/source/slang/ir-serialize.cpp
+++ b/source/slang/ir-serialize.cpp
@@ -531,6 +531,22 @@ Result IRSerialWriter::write(IRModule* module, SourceManager* sourceManager, Opt
dstInst.m_payloadType = PayloadType::Empty;
break;
}
+ case kIRDecorationOp_RequireGLSLExtension:
+ {
+ auto extDecor = static_cast<IRRequireGLSLExtensionDecoration*>(srcDecor);
+
+ dstInst.m_payloadType = PayloadType::String_1;
+ dstInst.m_payload.m_stringIndices[0] = getStringIndex(extDecor->extensionName);
+ break;
+ }
+ case kIRDecorationOp_RequireGLSLVersion:
+ {
+ auto verDecor = static_cast<IRRequireGLSLVersionDecoration*>(srcDecor);
+
+ dstInst.m_payloadType = PayloadType::UInt32;
+ dstInst.m_payload.m_uint32 = uint32_t(verDecor->languageVersion);
+ break;
+ }
default:
{
SLANG_ASSERT(!"Unhandled decoration type");
@@ -1513,6 +1529,20 @@ IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst)
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::Empty);
return decor;
}
+ case kIRDecorationOp_RequireGLSLExtension:
+ {
+ auto decor = createEmptyDecoration<IRRequireGLSLExtensionDecoration>(m_module);
+ SLANG_ASSERT(srcInst.m_payloadType == PayloadType::String_1);
+ decor->extensionName = getStringRepresentation(srcInst.m_payload.m_stringIndices[0]);
+ return decor;
+ }
+ case kIRDecorationOp_RequireGLSLVersion:
+ {
+ auto decor = createEmptyDecoration<IRRequireGLSLVersionDecoration>(m_module);
+ SLANG_ASSERT(srcInst.m_payloadType == Ser::Inst::PayloadType::UInt32);
+ decor->languageVersion = Int(srcInst.m_payload.m_uint32);
+ return decor;
+ }
default:
{
SLANG_ASSERT(!"Unhandled decoration type");
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 3ba2aa0dd..f05aeabf6 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -5344,6 +5344,22 @@ namespace Slang
}
break;
+ case kIRDecorationOp_RequireGLSLExtension:
+ {
+ auto originalDecoration = (IRRequireGLSLExtensionDecoration*)dd;
+ auto newDecoration = context->builder->addDecoration<IRRequireGLSLExtensionDecoration>(clonedValue);
+ newDecoration->extensionName = originalDecoration->extensionName;
+ }
+ break;
+
+ case kIRDecorationOp_RequireGLSLVersion:
+ {
+ auto originalDecoration = (IRRequireGLSLVersionDecoration*)dd;
+ auto newDecoration = context->builder->addDecoration<IRRequireGLSLVersionDecoration>(clonedValue);
+ newDecoration->languageVersion = originalDecoration->languageVersion;
+ }
+ break;
+
default:
// Don't clone any decorations we don't understand.
break;
diff --git a/source/slang/ir.h b/source/slang/ir.h
index ef257a759..e54a32043 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -154,6 +154,8 @@ enum IRDecorationOp : uint16_t
kIRDecorationOp_Transitory,
kIRDecorationOp_VulkanRayPayload,
kIRDecorationOp_VulkanHitAttributes,
+ kIRDecorationOp_RequireGLSLVersion,
+ kIRDecorationOp_RequireGLSLExtension,
kIRDecorationOp_CountOf
};
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 7b63f510f..5f3b00b24 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -5112,6 +5112,23 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// for a particular target, then handle that here.
addTargetIntrinsicDecorations(irFunc, decl);
+ // If this declaration requires certain GLSL extension (or a particular GLSL version)
+ // for it to be usable, then declare that here.
+ //
+ // TODO: We should wrap this an `SpecializedForTargetModifier` together into a single
+ // case for enumerating the "capabilities" that a declaration requires.
+ //
+ for(auto extensionMod : decl->GetModifiersOfType<RequiredGLSLExtensionModifier>())
+ {
+ auto decoration = getBuilder()->addDecoration<IRRequireGLSLExtensionDecoration>(irFunc);
+ decoration->extensionName = getBuilder()->addStringToFree(extensionMod->extensionNameToken.Content);
+ }
+ for(auto versionMod : decl->GetModifiersOfType<RequiredGLSLVersionModifier>())
+ {
+ auto decoration = getBuilder()->addDecoration<IRRequireGLSLVersionDecoration>(irFunc);
+ decoration->languageVersion = Int(getIntegerLiteralValue(versionMod->versionNumberToken));
+ }
+
// For convenience, ensure that any additional global
// values that were emitted while outputting the function
// body appear before the function itself in the list