summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/reflection.cpp24
-rw-r--r--source/slang/type-layout.cpp52
-rw-r--r--source/slang/type-layout.h8
3 files changed, 83 insertions, 1 deletions
diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp
index 4ac48d2e7..4d13052f6 100644
--- a/source/slang/reflection.cpp
+++ b/source/slang/reflection.cpp
@@ -279,6 +279,10 @@ SLANG_API SlangTypeKind spReflectionType_GetKind(SlangReflectionType* inType)
return SLANG_TYPE_KIND_INTERFACE;
}
}
+ else if( auto specializedType = as<ExistentialSpecializedType>(type) )
+ {
+ return SLANG_TYPE_KIND_SPECIALIZED;
+ }
else if (auto errorType = as<ErrorType>(type))
{
// This means we saw a type we didn't understand in the user's code
@@ -746,6 +750,10 @@ SLANG_API SlangReflectionTypeLayout* spReflectionTypeLayout_GetElementTypeLayout
{
return convert(structuredBufferTypeLayout->elementTypeLayout.Ptr());
}
+ else if( auto specializedTypeLayout = as<ExistentialSpecializedTypeLayout>(typeLayout) )
+ {
+ return convert(specializedTypeLayout->baseTypeLayout.Ptr());
+ }
return nullptr;
}
@@ -878,6 +886,22 @@ SLANG_API SlangReflectionVariableLayout* spReflectionVariableLayout_getPendingDa
return convert(pendingDataLayout);
}
+SLANG_API SlangReflectionVariableLayout* spReflectionTypeLayout_getSpecializedTypePendingDataVarLayout(SlangReflectionTypeLayout* inTypeLayout)
+{
+ auto typeLayout = convert(inTypeLayout);
+ if(!typeLayout) return nullptr;
+
+ if( auto specializedTypeLayout = as<ExistentialSpecializedTypeLayout>(typeLayout) )
+ {
+ auto pendingDataVarLayout = specializedTypeLayout->pendingDataVarLayout.Ptr();
+ return convert(pendingDataVarLayout);
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
// Variable Reflection
diff --git a/source/slang/type-layout.cpp b/source/slang/type-layout.cpp
index e315c2fb6..ba6085e0a 100644
--- a/source/slang/type-layout.cpp
+++ b/source/slang/type-layout.cpp
@@ -2210,7 +2210,11 @@ RefPtr<VarLayout> StructTypeLayoutBuilder::addField(
fieldLayout->varDecl = field;
fieldLayout->typeLayout = fieldTypeLayout;
m_typeLayout->fields.add(fieldLayout);
- m_typeLayout->mapVarToLayout.Add(field.getDecl(), fieldLayout);
+
+ if( field )
+ {
+ m_typeLayout->mapVarToLayout.Add(field.getDecl(), fieldLayout);
+ }
// Set up uniform offset information, if there is any uniform data in the field
if( fieldTypeLayout->FindResourceInfo(LayoutResourceKind::Uniform) )
@@ -2948,6 +2952,52 @@ static TypeLayoutResult _createTypeLayout(
return TypeLayoutResult(taggedUnionLayout, info);
}
+ else if( auto existentialSpecializedType = as<ExistentialSpecializedType>(type) )
+ {
+ TypeLayoutContext subContext = context.withExistentialTypeArgs(
+ existentialSpecializedType->slots.args.getCount(),
+ existentialSpecializedType->slots.args.getBuffer());
+
+ auto baseTypeLayoutResult = _createTypeLayout(
+ subContext,
+ existentialSpecializedType->baseType);
+
+ UniformLayoutInfo info = rules->BeginStructLayout();
+ rules->AddStructField(&info, baseTypeLayoutResult.info.getUniformLayout());
+
+ RefPtr<ExistentialSpecializedTypeLayout> typeLayout = new ExistentialSpecializedTypeLayout();
+ typeLayout->type = type;
+ typeLayout->rules = rules;
+
+ RefPtr<VarLayout> pendingDataVarLayout = new VarLayout();
+ if(auto pendingDataTypeLayout = baseTypeLayoutResult.layout->pendingDataTypeLayout)
+ {
+ for( auto pendingResInfo : pendingDataTypeLayout->resourceInfos )
+ {
+ auto kind = pendingResInfo.kind;
+ UInt index = 0;
+ if( kind == LayoutResourceKind::Uniform )
+ {
+ LayoutSize uniformOffset = rules->AddStructField(
+ &info,
+ makeTypeLayoutResult(pendingDataTypeLayout).info.getUniformLayout());
+
+ index = uniformOffset.getFiniteValue();
+ }
+ else
+ {
+ if(auto primaryResInfo = baseTypeLayoutResult.layout->FindResourceInfo(kind))
+ index = primaryResInfo->count.getFiniteValue();
+ }
+ pendingDataVarLayout->AddResourceInfo(kind)->index = index;
+ }
+ }
+
+ typeLayout->baseTypeLayout = baseTypeLayoutResult.layout;
+ typeLayout->pendingDataVarLayout = pendingDataVarLayout;
+
+ return makeTypeLayoutResult(typeLayout);
+ }
// catch-all case in case nothing matched
SLANG_ASSERT(!"unimplemented case in type layout");
diff --git a/source/slang/type-layout.h b/source/slang/type-layout.h
index fcb2c3419..c58f92cfb 100644
--- a/source/slang/type-layout.h
+++ b/source/slang/type-layout.h
@@ -630,6 +630,14 @@ public:
LayoutSize tagOffset;
};
+ /// Layout information for a type with existential (sub-)field types specialized.
+class ExistentialSpecializedTypeLayout : public TypeLayout
+{
+public:
+ RefPtr<TypeLayout> baseTypeLayout;
+ RefPtr<VarLayout> pendingDataVarLayout;
+};
+
/// Layout for a scoped entity like a program, module, or entry point
class ScopeLayout : public Layout
{