summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-type-layout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-type-layout.cpp')
-rw-r--r--source/slang/slang-type-layout.cpp132
1 files changed, 85 insertions, 47 deletions
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index 807d0cab4..29ebe7de6 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -2,6 +2,7 @@
#include "slang-type-layout.h"
#include "slang-syntax.h"
+#include "slang-ir-insts.h"
#include <assert.h>
@@ -1356,73 +1357,110 @@ RefPtr<TypeLayout> applyOffsetToTypeLayout(
return newTypeLayout;
}
-RefPtr<VarLayout> applyOffsetToVarLayout(
- VarLayout* baseLayout,
- VarLayout* offsetLayout)
+IRTypeLayout* applyOffsetToTypeLayout(
+ IRBuilder* irBuilder,
+ IRTypeLayout* oldTypeLayout,
+ IRVarLayout* offsetVarLayout)
{
- RefPtr<VarLayout> adjustedLayout = new VarLayout();
- adjustedLayout->typeLayout = baseLayout->typeLayout;
- adjustedLayout->varDecl = baseLayout->varDecl;
- adjustedLayout->flags = baseLayout->flags;
- adjustedLayout->semanticName = baseLayout->semanticName;
- adjustedLayout->semanticIndex = baseLayout->semanticIndex;
- adjustedLayout->systemValueSemantic = baseLayout->systemValueSemantic;
- adjustedLayout->systemValueSemanticIndex = baseLayout->systemValueSemanticIndex;
- adjustedLayout->stage = baseLayout->stage;
+ // The body of this function is derived from the AST case defined above.
+ //
+ // TODO: We shouldn't need this function at all because "offset" type
+ // layouts were only introduced as a legacy workaround for some bad choices
+ // in the reflection API.
+ //
- if( auto basePendingLayout = baseLayout->pendingVarLayout )
+ // There is no need to apply offsets if the old type and the offset
+ // don't share any resource infos in common.
+ bool anyHit = false;
+ for (auto oldResInfo : oldTypeLayout->getSizeAttrs())
{
- if( auto offsetPendingLayout = offsetLayout->pendingVarLayout )
+ if (auto offsetResInfo = offsetVarLayout->findOffsetAttr(oldResInfo->getResourceKind()))
{
- adjustedLayout->pendingVarLayout = applyOffsetToVarLayout(
- basePendingLayout,
- offsetPendingLayout);
+ anyHit = true;
+ break;
}
}
- for( auto baseResInfo : baseLayout->resourceInfos )
+ if (!anyHit)
+ return oldTypeLayout;
+
+ if (auto oldStructTypeLayout = as<IRStructTypeLayout>(oldTypeLayout))
{
- auto adjustedResInfo = baseResInfo;
- if( auto offsetResInfo = offsetLayout->FindResourceInfo(baseResInfo.kind) )
+ IRStructTypeLayout::Builder newStructTypeLayoutBuilder(irBuilder);
+ newStructTypeLayoutBuilder.addResourceUsageFrom(oldTypeLayout);
+
+ for (auto oldFieldAttr : oldStructTypeLayout->getFieldLayoutAttrs())
{
- adjustedResInfo.index += offsetResInfo->index;
- adjustedResInfo.space += offsetResInfo->space;
- }
- adjustedLayout->resourceInfos.add(adjustedResInfo);
- }
+ auto fieldKey = oldFieldAttr->getFieldKey();
+ auto oldFieldLayout = oldFieldAttr->getLayout();
- return adjustedLayout;
-}
+ IRVarLayout::Builder newFieldBuilder(irBuilder, oldFieldLayout->getTypeLayout());
+ newFieldBuilder.cloneEverythingButOffsetsFrom(oldFieldLayout);
-EntryPointLayout* EntryPointLayout::getAbsoluteLayout(
- VarLayout* parentLayout)
-{
- SLANG_ASSERT(parentLayout);
+ for (auto oldResInfo : oldFieldLayout->getOffsetAttrs())
+ {
+ auto kind = oldResInfo->getResourceKind();
+ auto newResInfo = newFieldBuilder.findOrAddResourceInfo(kind);
+ newResInfo->offset = oldResInfo->getOffset();
+ newResInfo->space = oldResInfo->getSpace();
+ if (auto offsetResInfo = offsetVarLayout->findOffsetAttr(kind))
+ {
+ newResInfo->offset += offsetResInfo->getOffset();
+ }
+ }
- if(m_absoluteLayout)
- return m_absoluteLayout;
+ newStructTypeLayoutBuilder.addField(fieldKey, newFieldBuilder.build());
+ }
- RefPtr<EntryPointLayout> adjustedLayout = new EntryPointLayout();
- adjustedLayout->entryPoint = this->entryPoint;
- adjustedLayout->flags = this->flags;
- adjustedLayout->parametersLayout = this->parametersLayout->getAbsoluteLayout(parentLayout);
- adjustedLayout->profile = this->profile;
- if( auto baseResultLayout = this->resultLayout )
+ return newStructTypeLayoutBuilder.build();
+ }
+ else
{
- adjustedLayout->resultLayout = baseResultLayout->getAbsoluteLayout(parentLayout);
+ // We can only effectively apply this offsetting to basic struct types,
+ // and so we won't even attempt it for anything else. This matches the
+ // AST implementation of this function, and shouldn't matter in the long
+ // run since we will remove the concept of offset type layouts from
+ // the IR.
+ //
+ return oldTypeLayout;
}
-
- m_absoluteLayout = adjustedLayout;
- return adjustedLayout;
}
-VarLayout* VarLayout::getAbsoluteLayout(VarLayout* parentAbsoluteLayout)
+IRVarLayout* applyOffsetToVarLayout(
+ IRBuilder* irBuilder,
+ IRVarLayout* baseLayout,
+ IRVarLayout* offsetLayout)
{
- if( !m_absoluteLayout )
+ IRVarLayout::Builder adjustedLayoutBuilder(irBuilder, baseLayout->getTypeLayout());
+ adjustedLayoutBuilder.cloneEverythingButOffsetsFrom(baseLayout);
+
+ if( auto basePendingLayout = baseLayout->getPendingVarLayout() )
{
- m_absoluteLayout = applyOffsetToVarLayout(this, parentAbsoluteLayout);
+ if( auto offsetPendingLayout = offsetLayout->getPendingVarLayout() )
+ {
+ adjustedLayoutBuilder.setPendingVarLayout(
+ applyOffsetToVarLayout(
+ irBuilder,
+ basePendingLayout,
+ offsetPendingLayout));
+ }
+ }
+
+ for( auto baseResInfo : baseLayout->getOffsetAttrs() )
+ {
+ auto kind = baseResInfo->getResourceKind();
+ auto adjustedResInfo = adjustedLayoutBuilder.findOrAddResourceInfo(kind);
+ adjustedResInfo->offset = baseResInfo->getOffset();
+ adjustedResInfo->space = baseResInfo->getSpace();
+
+ if( auto offsetResInfo = offsetLayout->findOffsetAttr(baseResInfo->getResourceKind()) )
+ {
+ adjustedResInfo->offset += offsetResInfo->getOffset();
+ adjustedResInfo->space += offsetResInfo->getSpace();
+ }
}
- return m_absoluteLayout;
+
+ return adjustedLayoutBuilder.build();
}
static bool _usesResourceKind(RefPtr<TypeLayout> typeLayout, LayoutResourceKind kind)