diff options
Diffstat (limited to 'source/slang/type-layout.h')
| -rw-r--r-- | source/slang/type-layout.h | 141 |
1 files changed, 128 insertions, 13 deletions
diff --git a/source/slang/type-layout.h b/source/slang/type-layout.h index cdeadbb16..5ac9229b4 100644 --- a/source/slang/type-layout.h +++ b/source/slang/type-layout.h @@ -328,23 +328,20 @@ public: // the space storing it in the above array UInt uniformAlignment = 1; - /// An item that is conceptually owned by this type, but is pending layout. + + /// The layout for data that is conceptually owned by this type, but which is pending layout. /// /// When a type contains interface/existential fields (recursively), the /// actual data referenced by these fields needs to get allocated somewhere, /// but it cannot go inline at the point where the interface/existential - /// type appears, or else + /// type appears, or else the layout of a composite object would change + /// when the concrete type(s) we plug in change. /// - struct PendingItem - { - RefPtr<TypeLayout> typeLayout; - - RefPtr<TypeLayout> getTypeLayout() const { return typeLayout; } - RefPtr<Type> getType() const { return typeLayout->type; } - }; - - /// The pending items owned by this type, but which are pending layout. - List<PendingItem> pendingItems; + /// We solve this problem by tracking this data that is "pending" layout, + /// and then "flushing" the pending data at appropriate places during + /// the layout process. + /// + RefPtr<TypeLayout> pendingDataTypeLayout; ResourceInfo* FindResourceInfo(LayoutResourceKind kind) { @@ -383,6 +380,8 @@ public: addResourceUsage(info); } + void addResourceUsageFrom(TypeLayout* otherTypeLayout); + /// "Unwrap" any layers of array-ness from this type layout. /// /// If this is an `ArrayTypeLayout`, returns the result of unwrapping the element type layout. @@ -475,6 +474,8 @@ public: return AddResourceInfo(kind); } + + RefPtr<VarLayout> pendingVarLayout; }; // type layout for a variable that has a constant-buffer type @@ -501,6 +502,16 @@ public: // so that any fields (if the element type is a `struct`) // will be offset by the resource usage of the container. RefPtr<TypeLayout> offsetElementTypeLayout; + + // If the element type layout had any "pending" data, then + // as much of that data as possible will be flushed to + // fit into the overall layout of the parameter group. + // + // This field stores the offset information for where + // the pending data got stored relative to the start of + // the group. + // +// RefPtr<VarLayout> flushedDataVarLayout; }; // type layout for a variable that has a constant-buffer type @@ -585,6 +596,12 @@ public: // in the array above, rather than to the actual pointer, // so that we Dictionary<Decl*, RefPtr<VarLayout>> mapVarToLayout; + + // As an accellerator for type layouts created at the + // IR layer, we include a second map that use IR "key" + // instructions to map to fields. + // + Dictionary<IRInst*, RefPtr<VarLayout>> mapKeyToLayout; }; class GenericParamTypeLayout : public TypeLayout @@ -924,6 +941,98 @@ struct TypeLayoutContext } }; +// + + /// A custom tuple to capture the outputs of type layout +struct TypeLayoutResult +{ + /// The actual heap-allocated layout object with all the details + RefPtr<TypeLayout> layout; + + /// A simplified representation of layout information. + /// + /// This information is suitable for the case where a type only + /// consumes a single resource. + /// + SimpleLayoutInfo info; + + /// Default constructor. + TypeLayoutResult() + {} + + /// Construct a result from the given layout object and simple layout info. + TypeLayoutResult(RefPtr<TypeLayout> inLayout, SimpleLayoutInfo const& inInfo) + : layout(inLayout) + , info(inInfo) + {} +}; + + /// Helper type for building `struct` type layouts +struct StructTypeLayoutBuilder +{ +public: + /// Begin the layout process for `type`, using `rules` + void beginLayout( + Type* type, + LayoutRulesImpl* rules); + + /// Begin the layout process for `type`, using `rules`, if it hasn't already been begun. + /// + /// This functions allows for a `StructTypeLayoutBuilder` to be use lazily, + /// only allocating a type layout object if it is actaully needed. + /// + void beginLayoutIfNeeded( + Type* type, + LayoutRulesImpl* rules); + + /// Add a field to the struct type layout. + /// + /// One of the `beginLayout*()` functions must have been called previously. + /// + RefPtr<VarLayout> addField( + DeclRef<VarDeclBase> field, + TypeLayoutResult fieldResult); + + /// Add a field to the struct type layout. + /// + /// One of the `beginLayout*()` functions must have been called previously. + /// + RefPtr<VarLayout> addField( + DeclRef<VarDeclBase> field, + RefPtr<TypeLayout> fieldTypeLayout); + + /// Complete layout. + /// + /// If layout was begun, ensures that the result of `getTypeLayout()` is usable. + /// If layout was never begin, does nothing. + /// + void endLayout(); + + /// Get the type layout. + /// + /// This can be called any time after `beginLayout*()`. + /// In particular, it can be called before `endLayout`. + /// + RefPtr<StructTypeLayout> getTypeLayout(); + + /// The the type layout result. + /// + /// This is primarily useful for implementation code in `_createTypeLayout`. + /// + TypeLayoutResult getTypeLayoutResult(); + +private: + /// The layout rules being used, if layout has begun. + LayoutRulesImpl* m_rules = nullptr; + + /// The type layout being computed, if layout has begun. + RefPtr<StructTypeLayout> m_typeLayout; + + /// Uniform offset/alignment statte used when computing offset for uniform fields. + UniformLayoutInfo m_info; +}; + +// // Get an appropriate set of layout rules (packaged up // as a `TypeLayoutContext`) to perform type layout @@ -963,7 +1072,7 @@ RefPtr<TypeLayout> createTypeLayout( // /// Create a layout for a parameter-group type (a `ConstantBuffer` or `ParameterBlock`). -RefPtr<ParameterGroupTypeLayout> createParameterGroupTypeLayout( +RefPtr<TypeLayout> createParameterGroupTypeLayout( TypeLayoutContext const& context, RefPtr<ParameterGroupType> parameterGroupType); @@ -993,6 +1102,12 @@ createStructuredBufferTypeLayout( int findGenericParam(List<RefPtr<GenericParamLayout>> & genericParameters, GlobalGenericParamDecl * decl); // +// Given an existing type layout `oldTypeLayout`, apply offsets +// to any contained fields based on the resource infos in `offsetVarLayout`. +RefPtr<TypeLayout> applyOffsetToTypeLayout( + RefPtr<TypeLayout> oldTypeLayout, + RefPtr<VarLayout> offsetVarLayout); + } #endif |
