summaryrefslogtreecommitdiffstats
path: root/source/slang/type-layout.h
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-05-31 17:20:37 -0400
committerGitHub <noreply@github.com>2019-05-31 17:20:37 -0400
commit6cbc3929a54d37bd23cb5efa8e3320ba02f78b2f (patch)
tree5a23cb47782e9e2a77762c90dd35da1005eba8d0 /source/slang/type-layout.h
parentb81ff3ef968d1cc4e954b31a1812b3c391d17b02 (diff)
Use slang- prefix on slang compiler and core source (#973)
* Prefixing source files in source/slang with slang- * Prefix source in source/slang with slang- prefix. * Rename core source files with slang- prefix. * Update project files. * Fix problems from automatic merge.
Diffstat (limited to 'source/slang/type-layout.h')
-rw-r--r--source/slang/type-layout.h1118
1 files changed, 0 insertions, 1118 deletions
diff --git a/source/slang/type-layout.h b/source/slang/type-layout.h
deleted file mode 100644
index c58f92cfb..000000000
--- a/source/slang/type-layout.h
+++ /dev/null
@@ -1,1118 +0,0 @@
-#ifndef SLANG_TYPE_LAYOUT_H
-#define SLANG_TYPE_LAYOUT_H
-
-#include "../core/basic.h"
-#include "compiler.h"
-#include "profile.h"
-#include "syntax.h"
-
-#include "../../slang.h"
-
-namespace Slang {
-
-// Forward declarations
-
-enum class BaseType;
-class Type;
-
-//
-
-enum class LayoutRule
-{
- Std140,
- Std430,
- HLSLConstantBuffer,
- HLSLStructuredBuffer,
-};
-
-#if 0
-enum class LayoutRulesFamily
-{
- HLSL,
- GLSL,
-};
-#endif
-
-// A "size" that can either be a simple finite size or
-// the special case of an infinite/unbounded size.
-//
-struct LayoutSize
-{
- typedef size_t RawValue;
-
- LayoutSize()
- : raw(0)
- {}
-
- LayoutSize(RawValue size)
- : raw(size)
- {
- SLANG_ASSERT(size != RawValue(-1));
- }
-
- static LayoutSize infinite()
- {
- LayoutSize result;
- result.raw = RawValue(-1);
- return result;
- }
-
- bool isInfinite() const { return raw == RawValue(-1); }
-
- bool isFinite() const { return raw != RawValue(-1); }
- RawValue getFiniteValue() const { SLANG_ASSERT(isFinite()); return raw; }
-
- bool operator==(LayoutSize that) const
- {
- return raw == that.raw;
- }
-
- bool operator!=(LayoutSize that) const
- {
- return raw != that.raw;
- }
-
- void operator+=(LayoutSize right)
- {
- if( isInfinite() ) {}
- else if( right.isInfinite() )
- {
- *this = LayoutSize::infinite();
- }
- else
- {
- *this = LayoutSize(raw + right.raw);
- }
- }
-
- void operator*=(LayoutSize right)
- {
- // Deal with zero first, so that anything (even the "infinite" value) times zero is zero.
- if( raw == 0 )
- {
- return;
- }
-
- if( right.raw == 0 )
- {
- raw = 0;
- return;
- }
-
- // Next we deal with infinite cases, so that infinite times anything non-zero is infinite
- if( isInfinite() )
- {
- return;
- }
-
- if( right.isInfinite() )
- {
- *this = LayoutSize::infinite();
- return;
- }
-
- // Finally deal with the case where both sides are finite
- *this = LayoutSize(raw * right.raw);
- }
-
- void operator-=(RawValue right)
- {
- if( isInfinite() ) {}
- else
- {
- *this = LayoutSize(raw - right);
- }
- }
-
- void operator/=(RawValue right)
- {
- if( isInfinite() ) {}
- else
- {
- *this = LayoutSize(raw / right);
- }
- }
- RawValue raw;
-};
-
-inline LayoutSize operator+(LayoutSize left, LayoutSize right)
-{
- LayoutSize result(left);
- result += right;
- return result;
-}
-
-inline LayoutSize operator*(LayoutSize left, LayoutSize right)
-{
- LayoutSize result(left);
- result *= right;
- return result;
-}
-
-inline LayoutSize operator-(LayoutSize left, LayoutSize::RawValue right)
-{
- LayoutSize result(left);
- result -= right;
- return result;
-}
-
-inline LayoutSize operator/(LayoutSize left, LayoutSize::RawValue right)
-{
- LayoutSize result(left);
- result /= right;
- return result;
-}
-
-inline LayoutSize maximum(LayoutSize left, LayoutSize right)
-{
- if(left.isInfinite() || right.isInfinite())
- return LayoutSize::infinite();
-
- return LayoutSize(Math::Max(
- left.getFiniteValue(),
- right.getFiniteValue()));
-}
-
-inline bool operator>(LayoutSize left, LayoutSize::RawValue right)
-{
- return left.isInfinite() || (left.getFiniteValue() > right);
-}
-
-inline bool operator<=(LayoutSize left, LayoutSize::RawValue right)
-{
- return left.isFinite() && (left.getFiniteValue() <= right);
-}
-
-// Layout appropriate to "just memory" scenarios,
-// such as laying out the members of a constant buffer.
-struct UniformLayoutInfo
-{
- LayoutSize size;
- size_t alignment;
-
- UniformLayoutInfo()
- : size(0)
- , alignment(1)
- {}
-
- UniformLayoutInfo(
- LayoutSize size,
- size_t alignment)
- : size(size)
- , alignment(alignment)
- {}
-};
-
-// Extended information required for an array of uniform data,
-// including the "stride" of the array (the space between
-// consecutive elements).
-struct UniformArrayLayoutInfo : UniformLayoutInfo
-{
- size_t elementStride;
-
- UniformArrayLayoutInfo()
- : elementStride(0)
- {}
-
- UniformArrayLayoutInfo(
- LayoutSize size,
- size_t alignment,
- size_t elementStride)
- : UniformLayoutInfo(size, alignment)
- , elementStride(elementStride)
- {}
-};
-
-typedef slang::ParameterCategory LayoutResourceKind;
-
-// Layout information for a value that only consumes
-// a single resource kind.
-struct SimpleLayoutInfo
-{
- // What kind of resource should we consume?
- LayoutResourceKind kind;
-
- // How many resources of that kind?
- LayoutSize size;
-
- // only useful in the uniform case
- size_t alignment;
-
- SimpleLayoutInfo()
- : kind(LayoutResourceKind::None)
- , size(0)
- , alignment(1)
- {}
-
- SimpleLayoutInfo(
- UniformLayoutInfo uniformInfo)
- : kind(LayoutResourceKind::Uniform)
- , size(uniformInfo.size)
- , alignment(uniformInfo.alignment)
- {}
-
- SimpleLayoutInfo(LayoutResourceKind kind, LayoutSize size, size_t alignment=1)
- : kind(kind)
- , size(size)
- , alignment(alignment)
- {}
-
- // Convert to layout for uniform data
- UniformLayoutInfo getUniformLayout()
- {
- if(kind == LayoutResourceKind::Uniform)
- {
- return UniformLayoutInfo(size, alignment);
- }
- else
- {
- return UniformLayoutInfo(0, 1);
- }
- }
-};
-
-// Only useful in the case of a homogeneous array
-struct SimpleArrayLayoutInfo : SimpleLayoutInfo
-{
- // This field is only useful in the uniform case
- size_t elementStride;
-
- // Convert to layout for uniform data
- UniformArrayLayoutInfo getUniformLayout()
- {
- if(kind == LayoutResourceKind::Uniform)
- {
- return UniformArrayLayoutInfo(size, alignment, elementStride);
- }
- else
- {
- return UniformArrayLayoutInfo(0, 1, 0);
- }
- }
-};
-
-struct LayoutRulesImpl;
-
-// Base class for things that store layout info
-class Layout : public RefObject
-{
-};
-
-// A reified representation of a particular laid-out type
-class TypeLayout : public Layout
-{
-public:
- // The type that was laid out
- RefPtr<Type> type;
- Type* getType() { return type.Ptr(); }
-
- // The layout rules that were used to produce this type
- LayoutRulesImpl* rules;
-
- struct ResourceInfo
- {
- // What kind of register was it?
- LayoutResourceKind kind = LayoutResourceKind::None;
-
- // How many registers of the above kind did we use?
- LayoutSize count;
- };
-
- List<ResourceInfo> resourceInfos;
-
- // For uniform data, alignment matters, but not for
- // any other resource category, so we don't waste
- // the space storing it in the above array
- UInt uniformAlignment = 1;
-
-
- /// 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 the layout of a composite object would change
- /// when the concrete type(s) we plug in change.
- ///
- /// 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)
- {
- for(auto& rr : resourceInfos)
- {
- if(rr.kind == kind)
- return &rr;
- }
- return nullptr;
- }
-
- ResourceInfo* findOrAddResourceInfo(LayoutResourceKind kind)
- {
- auto existing = FindResourceInfo(kind);
- if(existing) return existing;
-
- ResourceInfo info;
- info.kind = kind;
- info.count = 0;
- resourceInfos.add(info);
- return &resourceInfos.getLast();
- }
-
- void addResourceUsage(ResourceInfo info)
- {
- if(info.count == 0) return;
-
- findOrAddResourceInfo(info.kind)->count += info.count;
- }
-
- void addResourceUsage(LayoutResourceKind kind, LayoutSize count)
- {
- ResourceInfo info;
- info.kind = kind;
- info.count = count;
- 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.
- /// Otherwise, returns this type layout.
- ///
- RefPtr<TypeLayout> unwrapArray();
-};
-
-typedef unsigned int VarLayoutFlags;
-enum VarLayoutFlag : VarLayoutFlags
-{
- HasSemantic = 1 << 1
-};
-
-// A reified layout for a particular variable, field, etc.
-class VarLayout : public Layout
-{
-public:
- // The variable we are laying out
- DeclRef<VarDeclBase> varDecl;
- VarDeclBase* getVariable() { return varDecl.getDecl(); }
-
- Name* getName() { return getVariable()->getName(); }
-
- // The result of laying out the variable's type
- RefPtr<TypeLayout> typeLayout;
- TypeLayout* getTypeLayout() { return typeLayout.Ptr(); }
-
- // Additional flags
- VarLayoutFlags flags = 0;
-
- // System-value semantic (and index) if this is a system value
- String systemValueSemantic;
- int systemValueSemanticIndex;
-
- // General case semantic name and index
- // TODO: this and the system-value field are redundant
- // TODO: the `VarLayout` type is getting bloated; we need to not store this
- // information unless actually required.
- String semanticName;
- int semanticIndex;
-
- // The stage this variable belongs to, in case it is
- // stage-specific.
- // TODO: This is wasteful to be storing on every single
- // variable layout.
- Stage stage = Stage::Unknown;
-
- // The start register(s) for any resources
- struct ResourceInfo
- {
- // What kind of register was it?
- LayoutResourceKind kind = LayoutResourceKind::None;
-
- // What binding space (HLSL) or set (Vulkan) are we placed in?
- UInt space;
-
- // What is our starting register in that space?
- //
- // (In the case of uniform data, this is a byte offset)
- UInt index;
- };
- List<ResourceInfo> resourceInfos;
-
- ResourceInfo* FindResourceInfo(LayoutResourceKind kind)
- {
- for(auto& rr : resourceInfos)
- {
- if(rr.kind == kind)
- return &rr;
- }
- return nullptr;
- }
-
- ResourceInfo* AddResourceInfo(LayoutResourceKind kind)
- {
- ResourceInfo info;
- info.kind = kind;
- info.space = 0;
- info.index = 0;
-
- resourceInfos.add(info);
- return &resourceInfos.getLast();
- }
-
- ResourceInfo* findOrAddResourceInfo(LayoutResourceKind kind)
- {
- auto existing = FindResourceInfo(kind);
- if(existing) return existing;
-
- return AddResourceInfo(kind);
- }
-
- RefPtr<VarLayout> pendingVarLayout;
-};
-
-// type layout for a variable that has a constant-buffer type
-class ParameterGroupTypeLayout : public TypeLayout
-{
-public:
- // The layout of the "container" part itself.
- // E.g., for a constant buffer, this would reflect
- // the resource usage of the container, without
- // the element type factored in. All of the offsets
- // for this variable should be zero, but it is included
- // for completeness.
- RefPtr<VarLayout> containerVarLayout;
-
- // A variable layout for the element of the container.
- // The offsets of the variable layout will reflect
- // the offsets that need to applied to get past the
- // container types resource usage, while the actual
- // type layout won't have offsets applied (unlike
- // `offsetElementTypeLayout` below).
- RefPtr<VarLayout> elementVarLayout;
-
- // The layout of the element type, with offsets applied
- // 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
-class StructuredBufferTypeLayout : public TypeLayout
-{
-public:
- RefPtr<TypeLayout> elementTypeLayout;
-};
-
- /// Type layout for a logical sequence type
-class SequenceTypeLayout : public TypeLayout
-{
-public:
- /// The layout of the element type.
- ///
- /// This layout may include adjustments to make lookups in elements
- /// of the array Just Work, and may not be the same as the layout
- /// of the element type when used in a non-array context.
- ///
- RefPtr<TypeLayout> elementTypeLayout;
-
- /// The stride in bytes between elements.
- size_t uniformStride = 0;
-};
-
- /// Type layout for an array type
-class ArrayTypeLayout : public SequenceTypeLayout
-{
-public:
- /// The original layout of the element type.
- ///
- /// This layout does not include any adjustments that
- /// were made to the element type in order to make
- /// lookup into array elements Just Work.
- ///
- RefPtr<TypeLayout> originalElementTypeLayout;
-};
-
-// type layout for a variable with stream-output type
-class StreamOutputTypeLayout : public TypeLayout
-{
-public:
- RefPtr<TypeLayout> elementTypeLayout;
-};
-
-class VectorTypeLayout : public SequenceTypeLayout
-{
-public:
-};
-
-
-class MatrixTypeLayout : public SequenceTypeLayout
-{
-public:
- /// Is this matrix laid out as row-major or column-major?
- ///
- /// Note that this does *not* affect the interpretation
- /// of the `elementTypeLayout` field, which always represents
- /// the logical elements of the matrix type, which are its
- /// rows.
- ///
- MatrixLayoutMode mode;
-};
-
-// Specific case of type layout for a struct
-class StructTypeLayout : public TypeLayout
-{
-public:
- // An ordered list of layouts for the known fields
- List<RefPtr<VarLayout>> fields;
-
- // Map a variable to its layout directly.
- //
- // Note that in the general case, there may be entries
- // in the `fields` array that came from multiple
- // translation units, and in cases where there are
- // multiple declarations of the same parameter, only
- // one will appear in `fields`, while all of
- // them will be reflected in `mapVarToLayout`.
- //
- // TODO: This should map from a declaration to the *index*
- // 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
-{
-public:
- RefPtr<GlobalGenericParamDecl> getGlobalGenericParamDecl();
- int paramIndex = 0;
-};
-
- /// Layout information for a tagged union type.
-class TaggedUnionTypeLayout : public TypeLayout
-{
-public:
- /// The layouts of each of the case types.
- ///
- /// The order of entries in this array matches
- /// the order of case types on the original
- /// `TaggedUnionType`, and the index of a case
- /// type is also the tag value for that case.
- ///
- List<RefPtr<TypeLayout>> caseTypeLayouts;
-
- /// The byte offset for the tag field.
- ///
- /// The tag field will always be allocated as
- /// a `uint`, so we don't store a separate layout
- /// for it.
- ///
- 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
-{
-public:
- // The layout for the parameters of this entity.
- //
- RefPtr<VarLayout> parametersLayout;
-};
-
-StructTypeLayout* getScopeStructLayout(
- ScopeLayout* programLayout);
-
-// Layout information for a single shader entry point
-// within a program
-//
-// Treated as a subclass of `StructTypeLayout` because
-// it needs to include computed layout information
-// for the parameters of the entry point.
-//
-// TODO: where to store layout info for the return
-// type of the function?
-class EntryPointLayout : public ScopeLayout
-{
-public:
- // The corresponding function declaration
- RefPtr<FuncDecl> entryPoint;
-
- // The shader profile that was used to compile the entry point
- Profile profile;
-
- // Layout for any results of the entry point
- RefPtr<VarLayout> resultLayout;
-
- enum Flag : unsigned
- {
- usesAnySampleRateInput = 0x1,
- };
- unsigned flags = 0;
-
- /// Layouts for all tagged union types required by this entry point.
- ///
- /// These are any tagged union types used by the generic
- /// arguments that this entry point is being compiled with.
- List<RefPtr<TypeLayout>> taggedUnionTypeLayouts;
-};
-
-class GenericParamLayout : public Layout
-{
-public:
- RefPtr<GlobalGenericParamDecl> decl;
- int index;
-};
-
-// Layout information for the global scope of a program
-class ProgramLayout : public ScopeLayout
-{
-public:
- /*
- // We store a layout for the declarations at the global
- // scope. Note that this will *either* be a single
- // `StructTypeLayout` with the fields stored directly,
- // or it will be a single `ParameterGroupTypeLayout`,
- // where the global-scope fields are the members of
- // that constant buffer.
- //
- // The `struct` case will be used if there are no
- // "naked" global-scope uniform variables, and the
- // constant-buffer case will be used if there are
- // (since a constant buffer will have to be allocated
- // to store them).
- //
- RefPtr<VarLayout> globalScopeLayout;
- */
-
- /// The target and program for which layout was computed
- TargetProgram* targetProgram;
-
- TargetProgram* getTargetProgram() { return targetProgram; }
- TargetRequest* getTargetReq() { return targetProgram->getTargetReq(); }
- Program* getProgram() { return targetProgram->getProgram(); }
-
-
- // We catalog the requested entry points here,
- // and any entry-point-specific parameter data
- // will (eventually) belong there...
- List<RefPtr<EntryPointLayout>> entryPoints;
-
- List<RefPtr<GenericParamLayout>> globalGenericParams;
- Dictionary<String, GenericParamLayout*> globalGenericParamsMap;
-};
-
-StructTypeLayout* getGlobalStructLayout(
- ProgramLayout* programLayout);
-
-struct LayoutRulesFamilyImpl;
-
-// A delineation of shader parameter types into fine-grained
-// categories that can then be mapped down to actual resources
-// by a given set of rules.
-//
-// TODO(tfoley): `SlangParameterCategory` and `slang::ParameterCategory`
-// are badly named, and need to be revised so they can't be confused
-// with this concept.
-enum class ShaderParameterKind
-{
- ConstantBuffer,
- TextureUniformBuffer,
- ShaderStorageBuffer,
-
- StructuredBuffer,
- MutableStructuredBuffer,
-
- RawBuffer,
- MutableRawBuffer,
-
- Buffer,
- MutableBuffer,
-
- Texture,
- MutableTexture,
-
- TextureSampler,
- MutableTextureSampler,
-
- InputRenderTarget,
-
- SamplerState,
-
- Image,
- MutableImage,
-
- RegisterSpace,
-};
-
-struct SimpleLayoutRulesImpl
-{
- // Get size and alignment for a single value of base type.
- virtual SimpleLayoutInfo GetScalarLayout(BaseType baseType) = 0;
-
- // Get size and alignment for an array of elements
- virtual SimpleArrayLayoutInfo GetArrayLayout(SimpleLayoutInfo elementInfo, LayoutSize elementCount) = 0;
-
- // Get layout for a vector or matrix type
- virtual SimpleLayoutInfo GetVectorLayout(SimpleLayoutInfo elementInfo, size_t elementCount) = 0;
- virtual SimpleArrayLayoutInfo GetMatrixLayout(SimpleLayoutInfo elementInfo, size_t rowCount, size_t columnCount) = 0;
-
- // Begin doing layout on a `struct` type
- virtual UniformLayoutInfo BeginStructLayout() = 0;
-
- // Add a field to a `struct` type, and return the offset for the field
- virtual LayoutSize AddStructField(UniformLayoutInfo* ioStructInfo, UniformLayoutInfo fieldInfo) = 0;
-
- // End layout for a struct, and finalize its size/alignment.
- virtual void EndStructLayout(UniformLayoutInfo* ioStructInfo) = 0;
-};
-
-struct ObjectLayoutRulesImpl
-{
- // Compute layout info for an object type
- virtual SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind) = 0;
-};
-
-struct LayoutRulesImpl
-{
- LayoutRulesFamilyImpl* family;
- SimpleLayoutRulesImpl* simpleRules;
- ObjectLayoutRulesImpl* objectRules;
-
- // Forward `SimpleLayoutRulesImpl` interface
-
- SimpleLayoutInfo GetScalarLayout(BaseType baseType)
- {
- return simpleRules->GetScalarLayout(baseType);
- }
-
- SimpleArrayLayoutInfo GetArrayLayout(SimpleLayoutInfo elementInfo, LayoutSize elementCount)
- {
- return simpleRules->GetArrayLayout(elementInfo, elementCount);
- }
-
- SimpleLayoutInfo GetVectorLayout(SimpleLayoutInfo elementInfo, size_t elementCount)
- {
- return simpleRules->GetVectorLayout(elementInfo, elementCount);
- }
-
- SimpleArrayLayoutInfo GetMatrixLayout(SimpleLayoutInfo elementInfo, size_t rowCount, size_t columnCount)
- {
- return simpleRules->GetMatrixLayout(elementInfo, rowCount, columnCount);
- }
-
- UniformLayoutInfo BeginStructLayout()
- {
- return simpleRules->BeginStructLayout();
- }
-
- LayoutSize AddStructField(UniformLayoutInfo* ioStructInfo, UniformLayoutInfo fieldInfo)
- {
- return simpleRules->AddStructField(ioStructInfo, fieldInfo);
- }
-
- void EndStructLayout(UniformLayoutInfo* ioStructInfo)
- {
- return simpleRules->EndStructLayout(ioStructInfo);
- }
-
- // Forward `ObjectLayoutRulesImpl` interface
-
- SimpleLayoutInfo GetObjectLayout(ShaderParameterKind kind)
- {
- return objectRules->GetObjectLayout(kind);
- }
-
- //
-
- LayoutRulesFamilyImpl* getLayoutRulesFamily() { return family; }
-};
-
-struct LayoutRulesFamilyImpl
-{
- virtual LayoutRulesImpl* getConstantBufferRules() = 0;
- virtual LayoutRulesImpl* getPushConstantBufferRules() = 0;
- virtual LayoutRulesImpl* getTextureBufferRules() = 0;
- virtual LayoutRulesImpl* getVaryingInputRules() = 0;
- virtual LayoutRulesImpl* getVaryingOutputRules() = 0;
- virtual LayoutRulesImpl* getSpecializationConstantRules()= 0;
- virtual LayoutRulesImpl* getShaderStorageBufferRules() = 0;
- virtual LayoutRulesImpl* getParameterBlockRules() = 0;
-
- virtual LayoutRulesImpl* getRayPayloadParameterRules() = 0;
- virtual LayoutRulesImpl* getCallablePayloadParameterRules() = 0;
- virtual LayoutRulesImpl* getHitAttributesParameterRules()= 0;
-
- virtual LayoutRulesImpl* getShaderRecordConstantBufferRules() = 0;
-};
-
-typedef List<RefPtr<GenericParamLayout>> GenericParamLayouts;
-
-struct TypeLayoutContext
-{
- // The layout rules to use (e.g., we compute
- // layout differently in a `cbuffer` vs. the
- // parameter list of a fragment shader).
- LayoutRulesImpl* rules;
-
- // The target request that is triggering layout
- TargetRequest* targetReq;
-
- // A parent program layout that will establish the ordering
- // of all global generic type parameters.
- //
- ProgramLayout* programLayout;
-
- // Whether to lay out matrices column-major
- // or row-major.
- MatrixLayoutMode matrixLayoutMode;
-
- // The concrete types (if any) to plug into the currently in-scope
- // existential type slots.
- //
- Int existentialTypeArgCount = 0;
- ExistentialTypeSlots::Arg const* existentialTypeArgs = nullptr;
-
- LayoutRulesImpl* getRules() { return rules; }
- LayoutRulesFamilyImpl* getRulesFamily() const { return rules->getLayoutRulesFamily(); }
-
- TypeLayoutContext with(LayoutRulesImpl* inRules) const
- {
- TypeLayoutContext result = *this;
- result.rules = inRules;
- return result;
- }
-
- TypeLayoutContext with(MatrixLayoutMode inMatrixLayoutMode) const
- {
- TypeLayoutContext result = *this;
- result.matrixLayoutMode = inMatrixLayoutMode;
- return result;
- }
-
- TypeLayoutContext withExistentialTypeArgs(
- Int argCount,
- ExistentialTypeSlots::Arg const* args) const
- {
- TypeLayoutContext result = *this;
- result.existentialTypeArgCount = argCount;
- result.existentialTypeArgs = args;
- return result;
- }
-
- TypeLayoutContext withExistentialTypeSlotsOffsetBy(
- Int offset) const
- {
- TypeLayoutContext result = *this;
- if( existentialTypeArgCount > offset )
- {
- result.existentialTypeArgCount = existentialTypeArgCount - offset;
- result.existentialTypeArgs = existentialTypeArgs + offset;
- }
- else
- {
- result.existentialTypeArgCount = 0;
- result.existentialTypeArgs = nullptr;
- }
- return result;
-
- }
-};
-
-//
-
- /// 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
-// for the given target.
-//
-// The provided `programLayout` is used to establish
-// the ordering of all global generic type paramters.
-//
-TypeLayoutContext getInitialLayoutContextForTarget(
- TargetRequest* targetReq,
- ProgramLayout* programLayout);
-
- /// Direction(s) of a varying shader parameter
-typedef unsigned int EntryPointParameterDirectionMask;
-enum
-{
- kEntryPointParameterDirection_Input = 0x1,
- kEntryPointParameterDirection_Output = 0x2,
-};
-
-
- /// Get layout information for a simple varying parameter type.
- ///
- /// A simple varying parameter is a scalar, vector, or matrix.
- ///
-RefPtr<TypeLayout> getSimpleVaryingParameterTypeLayout(
- TypeLayoutContext const& context,
- Type* type,
- EntryPointParameterDirectionMask directionMask);
-
-// Create a full type-layout object for a type,
-// according to the layout rules in `context`.
-RefPtr<TypeLayout> createTypeLayout(
- TypeLayoutContext const& context,
- Type* type);
-
-//
-
- /// Create a layout for a parameter-group type (a `ConstantBuffer` or `ParameterBlock`).
-RefPtr<TypeLayout> createParameterGroupTypeLayout(
- TypeLayoutContext const& context,
- RefPtr<ParameterGroupType> parameterGroupType);
-
- /// Create a wrapper constant buffer type layout, if needed.
- ///
- /// When dealing with entry-point `uniform` and global-scope parameters,
- /// we want to create a wrapper constant buffer for all the parameters
- /// if and only if there exist some parameters that use "ordinary" data
- /// (`LayoutResourceKind::Uniform`).
- ///
- /// This function determines whether such a wrapper is needed, based
- /// on the `elementTypeLayout` given, and either creates and returns
- /// the layout for the wrapper, or the unmodified `elementTypeLayout`.
- ///
-RefPtr<TypeLayout> createConstantBufferTypeLayoutIfNeeded(
- TypeLayoutContext const& context,
- RefPtr<TypeLayout> elementTypeLayout);
-
-// Create a type layout for a structured buffer type.
-RefPtr<StructuredBufferTypeLayout>
-createStructuredBufferTypeLayout(
- TypeLayoutContext const& context,
- ShaderParameterKind kind,
- RefPtr<Type> structuredBufferType,
- RefPtr<Type> elementType);
-
-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