summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-05-21 16:38:33 -0700
committerGitHub <noreply@github.com>2021-05-21 16:38:33 -0700
commit7f8a9994d0bd99a171a1daa0bce46d92c02ccffd (patch)
tree0b187e63ab5b9ce6f5ab41266fedaec44091a217 /source
parent172538fdb418f7a2faab1f5a410f3b2cb8e18ba5 (diff)
[gfx] Support StructuredBuffer<IInterface>. (#1851)
Co-authored-by: T. Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'source')
-rwxr-xr-xsource/slang/slang-compiler.h28
-rw-r--r--source/slang/slang-emit-source-writer.cpp3
-rw-r--r--source/slang/slang-emit-source-writer.h4
-rw-r--r--source/slang/slang-emit.cpp6
-rw-r--r--source/slang/slang-reflection-api.cpp32
-rw-r--r--source/slang/slang.cpp85
6 files changed, 110 insertions, 48 deletions
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 54c61bd75..603ee0bb5 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1199,14 +1199,10 @@ namespace Slang
// TypeLayouts created on the fly by reflection API
Dictionary<Type*, RefPtr<TypeLayout>> typeLayouts;
- Dictionary<Type*, ParameterBlockType*> parameterBlockTypes;
-
Dictionary<Type*, RefPtr<TypeLayout>>& getTypeLayouts() { return typeLayouts; }
TypeLayout* getTypeLayout(Type* type);
- TypeLayout* getParameterBlockLayout(Type* type);
-
private:
Linkage* linkage = nullptr;
CodeGenTarget format = CodeGenTarget::Unknown;
@@ -1251,6 +1247,21 @@ namespace Slang
const char* getBuildTagString();
struct TypeCheckingCache;
+
+ struct ContainerTypeKey
+ {
+ slang::TypeReflection* elementType;
+ slang::ContainerType containerType;
+ bool operator==(ContainerTypeKey other)
+ {
+ return elementType == other.elementType && containerType == other.containerType;
+ }
+ Slang::HashCode getHashCode()
+ {
+ return Slang::combineHash(
+ Slang::getHashCode(elementType), Slang::getHashCode(containerType));
+ }
+ };
/// A context for loading and re-using code modules.
class Linkage : public RefObject, public slang::ISession
@@ -1279,11 +1290,11 @@ namespace Slang
SlangInt targetIndex = 0,
slang::LayoutRules rules = slang::LayoutRules::Default,
ISlangBlob** outDiagnostics = nullptr) override;
- SLANG_NO_THROW slang::TypeLayoutReflection* SLANG_MCALL getParameterBlockLayout(
+ SLANG_NO_THROW slang::TypeReflection* SLANG_MCALL getContainerType(
slang::TypeReflection* elementType,
- SlangInt targetIndex = 0,
- slang::LayoutRules rules = slang::LayoutRules::Default,
+ slang::ContainerType containerType,
ISlangBlob** outDiagnostics = nullptr) override;
+ SLANG_NO_THROW slang::TypeReflection* SLANG_MCALL getDynamicType() override;
SLANG_NO_THROW SlangResult SLANG_MCALL getTypeRTTIMangledName(
slang::TypeReflection* type,
ISlangBlob** outNameBlob) override;
@@ -1348,6 +1359,9 @@ namespace Slang
RefPtr<ASTBuilder> m_astBuilder;
+ // Cache for container types.
+ Dictionary<ContainerTypeKey, Type*> m_containerTypes;
+
// cache used by type checking, implemented in check.cpp
TypeCheckingCache* getTypeCheckingCache();
void destroyTypeCheckingCache();
diff --git a/source/slang/slang-emit-source-writer.cpp b/source/slang/slang-emit-source-writer.cpp
index 29a83a1fc..bed9a2dbc 100644
--- a/source/slang/slang-emit-source-writer.cpp
+++ b/source/slang/slang-emit-source-writer.cpp
@@ -330,6 +330,9 @@ void SourceWriter::_emitLineDirectiveAndUpdateSourceLocation(const HumaneSourceL
void SourceWriter::_emitLineDirectiveIfNeeded(const HumaneSourceLoc& sourceLocation)
{
+ if (m_supressLineDirective)
+ return;
+
// Don't do any of this work if the user has requested that we
// not emit line directives.
auto mode = getLineDirectiveMode();
diff --git a/source/slang/slang-emit-source-writer.h b/source/slang/slang-emit-source-writer.h
index 64dc59801..294cfec18 100644
--- a/source/slang/slang-emit-source-writer.h
+++ b/source/slang/slang-emit-source-writer.h
@@ -47,6 +47,8 @@ public:
void emitName(Name* name, const SourceLoc& loc);
void emitName(Name* name);
+ void supressLineDirective() { m_supressLineDirective = true; }
+ void resumeLineDirective() { m_supressLineDirective = false; }
/// Indent the text
void indent();
@@ -102,6 +104,8 @@ protected:
HumaneSourceLoc m_nextHumaneSourceLocation;
bool m_needToUpdateSourceLocation = false;
+
+ bool m_supressLineDirective = false;
// Are we at the start of a line, so that we should indent
// before writing any other text?
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index af870d02b..74b11079d 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -849,7 +849,13 @@ SlangResult emitEntryPointsSourceFromIR(
}
// There may be global-scope modifiers that we should emit now
+ // Supress emitting line directives when emitting preprocessor directives since
+ // these preprocessor directives may be required to appear in the first line
+ // of the output. An example is that the "#version" line in a GLSL source must
+ // appear before anything else.
+ sourceWriter.supressLineDirective();
sourceEmitter->emitPreprocessorDirectives();
+ sourceWriter.resumeLineDirective();
RefObject* extensionTracker = sourceEmitter->getExtensionTracker();
diff --git a/source/slang/slang-reflection-api.cpp b/source/slang/slang-reflection-api.cpp
index b74a019e3..22f34a41a 100644
--- a/source/slang/slang-reflection-api.cpp
+++ b/source/slang/slang-reflection-api.cpp
@@ -480,6 +480,10 @@ SLANG_API SlangReflectionType* spReflectionType_GetElementType(SlangReflectionTy
{
return convert(parameterGroupType->elementType);
}
+ else if (auto structuredBufferType = as<HLSLStructuredBufferTypeBase>(type))
+ {
+ return convert(structuredBufferType->elementType);
+ }
else if( auto vectorType = as<VectorExpressionType>(type))
{
return convert(vectorType->elementType);
@@ -1485,7 +1489,7 @@ namespace Slang
Index bindingRangeIndex = m_extendedInfo->m_bindingRanges.getCount();
SlangBindingType bindingType = SLANG_BINDING_TYPE_CONSTANT_BUFFER;
Index spaceOffset = -1;
- bool usesIndirectAllocation = false;
+ bool shouldAllocDescriptorSet = true;
LayoutResourceKind kind = LayoutResourceKind::None;
// TODO: It is unclear if this should be looking at the resource
@@ -1515,13 +1519,14 @@ namespace Slang
// Note: the only case where a parameter group should
// reflect as consuming `Uniform` storage is on CPU/CUDA,
// where that will be the only resource it contains.
+ case LayoutResourceKind::Uniform:
+ break;
//
// TODO: If we ever support targets that don't have
// constant buffers at all, this logic would be questionable.
//
case LayoutResourceKind::RegisterSpace:
- case LayoutResourceKind::Uniform:
- usesIndirectAllocation = true;
+ shouldAllocDescriptorSet = false;
break;
}
@@ -1591,7 +1596,7 @@ namespace Slang
// because the physical storage for `C.a` is provided by the
// memory allocation for `C` itself.
- if( !usesIndirectAllocation )
+ if (shouldAllocDescriptorSet)
{
// The logic here assumes that when a parameter group consumes
// resources that must "leak" into the outer scope (including
@@ -1737,8 +1742,8 @@ namespace Slang
else
{
// Here we have the catch-all case that handles "leaf" fields
- // that should never introduce a sub-object range, but might
- // need to introduce a binding range and descriptor ranges.
+ // that might need to introduce a binding range and descriptor
+ // ranges.
//
// First, we want to determine what type of binding this
// leaf field should map to, if any. We being by querying
@@ -1839,12 +1844,13 @@ namespace Slang
// TODO: Make some clear decisions about what should and should
// not appear here.
//
- case LayoutResourceKind::Uniform:
case LayoutResourceKind::RegisterSpace:
case LayoutResourceKind::VaryingInput:
case LayoutResourceKind::VaryingOutput:
case LayoutResourceKind::HitAttributes:
case LayoutResourceKind::RayPayload:
+ case LayoutResourceKind::ExistentialTypeParam:
+ case LayoutResourceKind::ExistentialObjectParam:
continue;
}
@@ -1888,7 +1894,19 @@ namespace Slang
bindingRange.descriptorRangeCount++;
}
+ auto bindingRangeIndex = m_extendedInfo->m_bindingRanges.getCount();
+
m_extendedInfo->m_bindingRanges.add(bindingRange);
+
+ // For `StructuredBuffer` fields, we also make sure to report it as a sub-object range.
+ if (auto structuredBufferTypeLayout = as<StructuredBufferTypeLayout>(typeLayout))
+ {
+ TypeLayout::ExtendedInfo::SubObjectRangeInfo subObjectRange;
+ subObjectRange.bindingRangeIndex = bindingRangeIndex;
+ subObjectRange.offsetVarLayout = createOffsetVarLayout(typeLayout, path);
+ subObjectRange.spaceOffset = 0;
+ m_extendedInfo->m_subObjectRanges.add(subObjectRange);
+ }
}
}
};
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 8479a0e99..9a109f9d7 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -896,35 +896,65 @@ SLANG_NO_THROW slang::TypeLayoutReflection* SLANG_MCALL Linkage::getTypeLayout(
return asExternal(typeLayout);
}
-SLANG_NO_THROW slang::TypeLayoutReflection* SLANG_MCALL Linkage::getParameterBlockLayout(
+SLANG_NO_THROW slang::TypeReflection* SLANG_MCALL Linkage::getContainerType(
slang::TypeReflection* inType,
- SlangInt targetIndex,
- slang::LayoutRules rules,
+ slang::ContainerType containerType,
ISlangBlob** outDiagnostics)
{
auto type = asInternal(inType);
- if (targetIndex < 0 || targetIndex >= targets.getCount())
- return nullptr;
-
- auto target = targets[targetIndex];
-
- // TODO: We need a way to pass through the layout rules
- // that the user requested (e.g., constant buffers vs.
- // structured buffer rules). Right now the API only
- // exposes a single case, so this isn't a big deal.
- //
- SLANG_UNUSED(rules);
-
- auto typeLayout = target->getParameterBlockLayout(type);
+ Type* containerTypeReflection = nullptr;
+ ContainerTypeKey key = {inType, containerType};
+ if (!m_containerTypes.TryGetValue(key, containerTypeReflection))
+ {
+ switch (containerType)
+ {
+ case slang::ContainerType::ConstantBuffer:
+ {
+ ConstantBufferType* cbType = getASTBuilder()->create<ConstantBufferType>();
+ cbType->elementType = type;
+ containerTypeReflection = cbType;
+ }
+ break;
+ case slang::ContainerType::ParameterBlock:
+ {
+ ParameterBlockType* pbType = getASTBuilder()->create<ParameterBlockType>();
+ pbType->elementType = type;
+ containerTypeReflection = pbType;
+ }
+ break;
+ case slang::ContainerType::StructuredBuffer:
+ {
+ HLSLStructuredBufferType* sbType =
+ getASTBuilder()->create<HLSLStructuredBufferType>();
+ sbType->elementType = type;
+ containerTypeReflection = sbType;
+ }
+ break;
+ case slang::ContainerType::UnsizedArray:
+ {
+ ArrayExpressionType* arrType = getASTBuilder()->create<ArrayExpressionType>();
+ arrType->baseType = type;
+ arrType->arrayLength = nullptr;
+ containerTypeReflection = arrType;
+ }
+ break;
+ default:
+ containerTypeReflection = type;
+ break;
+ }
+
+ m_containerTypes.Add(key, containerTypeReflection);
+ }
- // TODO: We currently don't have a path for capturing
- // errors that occur during layout (e.g., types that
- // are invalid because of target-specific layout constraints).
- //
SLANG_UNUSED(outDiagnostics);
- return asExternal(typeLayout);
+ return asExternal(containerTypeReflection);
+}
+
+SLANG_NO_THROW slang::TypeReflection* SLANG_MCALL Linkage::getDynamicType()
+{
+ return asExternal(getASTBuilder()->getSharedASTBuilder()->getDynamicType());
}
SLANG_NO_THROW SlangResult SLANG_MCALL Linkage::getTypeRTTIMangledName(
@@ -1132,19 +1162,6 @@ TypeLayout* TargetRequest::getTypeLayout(Type* type)
return result.Ptr();
}
-TypeLayout* TargetRequest::getParameterBlockLayout(Type* type)
-{
- ParameterBlockType* parameterBlockType = nullptr;
- if (!parameterBlockTypes.TryGetValue(type, parameterBlockType))
- {
- parameterBlockType = getLinkage()->getASTBuilder()->create<ParameterBlockType>();
- parameterBlockType->elementType = type;
- parameterBlockTypes.Add(type, parameterBlockType);
- }
- return getTypeLayout(parameterBlockType);
-}
-
-
//
// TranslationUnitRequest
//